Toggle a bit in BASIC

Basic and Machine Language

Moderator: Moderators

Post Reply
User avatar
Jeff-20
Denial Founder
Posts: 5759
Joined: Wed Dec 31, 1969 6:00 pm

Toggle a bit in BASIC

Post by Jeff-20 »

I am trying to toggle any single bit in a variable. I vaguely recall a method in BASIC (maybe using NOT). For example:

When binary input is 0100,
if value is 0100 then output 0000
if value is 0000 then output 0100

I think there is a simple way to do this, but I can't figure it out tonight. A little help?
High Scores, Links, and Jeff's Basic Games page.
User avatar
srowe
Vic 20 Scientist
Posts: 1340
Joined: Mon Jun 16, 2014 3:19 pm

Re: Toggle a bit in BASIC

Post by srowe »

What you want is an XOR operator, which CBM BASIC doesn't have. You can implement this using a combination of NOT and AND

https://math.stackexchange.com/question ... 4879_38477
User avatar
Jeff-20
Denial Founder
Posts: 5759
Joined: Wed Dec 31, 1969 6:00 pm

Re: Toggle a bit in BASIC

Post by Jeff-20 »

Thanks!!
High Scores, Links, and Jeff's Basic Games page.
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Toggle a bit in BASIC

Post by Mike »

srowe wrote:What you want is an XOR operator, which CBM BASIC doesn't have.
Not everything needs a dedicated command/procedure/function ... :wink: ...
You can implement this using a combination of NOT and AND
... as you said, all building blocks are there. XOR can be implemented in CBM BASIC in the following two ways:

XOR(A,B) := (A AND NOT B) OR (B AND NOT A)

alternatively:

XOR(A,B) := (A OR B) AND NOT (A AND B)

Both methods give the same result. A and B can be replaced by other variable (names) or fixed numbers. So, for toggling bit 2 (value: 4) in a variable X you'd write:

X = (X OR 4) AND NOT (X AND 4)

If X should just toggle between any two numbers, say M and N, that can be expressed in a simpler way thus:

(X contains either the value M or N) -> X=(M+N)-X.

For example, when you want X to toggle between 7 and 12 (just some arbitrary numbers fetched from air), you'd initialize X with 7 (or 12), and then write:

X = 19 - X

... and get 12, 7, 12, 7, 12, ... in X. :mrgreen:

Greetings,

Michael
User avatar
Kweepa
Vic 20 Scientist
Posts: 1315
Joined: Fri Jan 04, 2008 5:11 pm
Location: Austin, Texas
Occupation: Game maker

Re: Toggle a bit in BASIC

Post by Kweepa »

To toggle bit 2 you can write

Code: Select all

X=X+4-2*(4ANDX)
Replace both 4s with any 2^N for other bits.
User avatar
Noizer
Vic 20 Devotee
Posts: 297
Joined: Tue May 15, 2018 12:00 pm
Location: Europa

Re: Toggle a bit in BASIC

Post by Noizer »

I wonder from time to time why wasting memory and processing time with basic. In machine language you need only a handfull of bytes to accomplish XOR operations. Posting only tought as friendly reminder
Valid rule today as earlier: 1 Byte = 8 Bits
-._/classes instead of masses\_.-
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Toggle a bit in BASIC

Post by chysn »

Noizer wrote: Mon Jun 29, 2020 1:39 pm I wonder from time to time why wasting memory and processing time with basic. In machine language you need only a handfull of bytes to accomplish XOR operations. Posting only tought as friendly reminder
Meh... If the rest of the program is in BASIC, you can pick up only slightly more speed with USR(), and readability suffers.

Code: Select all

.033c   jsr $dc9b ; FAC1 to int, low byte in $62
        jsr $d79e ; Get another byte parameter (to X)
        txa
        eor $62
        tay
        lda #0
        jmp $d391 ; Convert Y/A to USR() return value
.0000   jmp $033c ; Set up the USR() vector
Call with the weird-lookin'

R = USR(X)(Y)

This is about twice as fast as

R = (X OR Y) AND NOT (X AND Y)

And probably only because it's fewer characters to parse. But whether it's worth it is debatable. My gut feeling is no, not really worth the hassle. Unless you're EORing a lot of numbers in real time, the time BASIC takes will probably just be absorbed into the user experience.

And also, I know this wasn't what the OP asked for, so feel free to ignore it. :)
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Toggle a bit in BASIC

Post by Mike »

Noizer wrote:I wonder from time to time why wasting memory and processing time with basic.
You need to take another scarce resource into consideration, and that is the time spent writing the program.
In machine language you need only a handfull of bytes to accomplish XOR operations.
On the 6502, one single opcode byte is needed, to be exact. But that doesn't generalize: for most algorithms, their implementation in machine code is likely more verbose and more difficult to get right than the equivalent in any higher level language, and that includes CBM BASIC.
Posting only tought as friendly reminder
You're gladly invited to try a 1:1 port of my TRON Light Cycles game from BASIC to machine code and check whether that translation improves anything. :mrgreen:
wimoos
Vic 20 Afficionado
Posts: 348
Joined: Tue Apr 14, 2009 8:15 am
Website: http://wimbasic.webs.com
Location: Netherlands
Occupation: farmer

Re: Toggle a bit in BASIC

Post by wimoos »

The ML equivalent is most probably faster because the variables don't need to be found and converted twice.
Below is the implementation in WimBasic. It is called by R=XOR(A,B) where A, B and R are signed integers (-32768..32767).

Code: Select all

;
; 
;Perform XOR
;
LA6DE	JSR  $CEFA	; check round bracket open
	JSR  $CD8A	; evaluate and check numeric expression
        JSR  $D1AA	; convert to signed int in $64:$65 and Y:A
	PHA
	TYA
	PHA
	JSR  $CEFD	; check comma
	JSR  $CD8A	; evaluate and check numeric expression
	JSR  $D1BF	; convert to signed int in $64:$65
	PLA            	 
	EOR  $65       	 		
	TAY            	 
	PLA            	 
	EOR  $64	; result is now in Y:A
	JSR  $D391	; convert to float
	JMP  $CEF7	; check round bracket close and return
You could bring the interface down to a SYSx,A,B and pick up the result from 780 and 782

Code: Select all

LA6DE	JSR  $CEFD	; check comma
	JSR  $CD8A	; evaluate and check numeric expression
        JSR  $D1AA	; convert to signed int in $64:$65 and Y:A
	PHA
	TYA
	PHA
	JSR  $CEFD	; check comma
	JSR  $CD8A	; evaluate and check numeric expression
	JSR  $D1BF	; convert to signed int in $64:$65
	PLA            	 
	EOR  $65       	 		
	TAY            	 
	PLA            	 
	EOR  $64	; result is now in Y:A
	RTS
Regards,

Wim.
VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic
User avatar
chysn
Vic 20 Scientist
Posts: 1205
Joined: Tue Oct 22, 2019 12:36 pm
Website: http://www.beigemaze.com
Location: Michigan, USA
Occupation: Software Dev Manager

Re: Toggle a bit in BASIC

Post by chysn »

wimoos wrote: Tue Jun 30, 2020 1:41 am You could bring the interface down to a SYSx,A,B and pick up the result from 780 and 782
That was my first approach. But once you get PEEK into the mix, you lose speed against the BASIC expression. There needs to be an assignment.
VIC-20 Projects: wAx Assembler, TRBo: Turtle RescueBot, Helix Colony, Sub Med, Trolley Problem, Dungeon of Dance, ZEPTOPOLIS, MIDI KERNAL, The Archivist, Ed for Prophet-5

WIP: MIDIcast BASIC extension

he/him/his
wimoos
Vic 20 Afficionado
Posts: 348
Joined: Tue Apr 14, 2009 8:15 am
Website: http://wimbasic.webs.com
Location: Netherlands
Occupation: farmer

Re: Toggle a bit in BASIC

Post by wimoos »

chysn wrote: Tue Jun 30, 2020 5:54 am There needs to be an assignment.
Hmm. Interesting idea: if you're only interested in the result of XOR being zero or not, then store that result in Zp $61.
Back in Basic you could make use of the IF A$ THEN... quirk. So there's no assignment but only flow-control.

Regards,

Wim
VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Toggle a bit in BASIC

Post by Mike »

wimoos wrote:Interesting idea: if you're only interested in the result of XOR being zero or not, ...
... that could be tested by comparing the two involved numbers/variables/expressions for (in)equality.
User avatar
Noizer
Vic 20 Devotee
Posts: 297
Joined: Tue May 15, 2018 12:00 pm
Location: Europa

Re: Toggle a bit in BASIC

Post by Noizer »

Mike wrote: Mon Jun 29, 2020 7:54 pm You're gladly invited to try a 1:1 port of my TRON Light Cycles game from BASIC to machine code and check whether that translation improves anything. :mrgreen:
Wow, thanx. I'm proud of it. I should first check the basic listing, but I cannot promise anything. I have at time only 32K expansion and would probably dodge to emulator due the +3K requirement (as usual for most of your productions).
I'm not so excited to use at all an emulator, due the "real thing" matter, YNWIM.
Edit: oh, while writing the d64 I saw that tron is for unex vic...🥵 OK all right
Valid rule today as earlier: 1 Byte = 8 Bits
-._/classes instead of masses\_.-
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Toggle a bit in BASIC

Post by Mike »

Noizer wrote:Wow, thanx. I'm proud of it. I should first check the basic listing, but I cannot promise anything. I have at time only 32K expansion and would probably dodge to emulator due the +3K requirement (as usual for most of your productions).
:?: :?: :?:

All the games in this collection run on an unexpanded VIC-20!

And pardon, you're proud of what?

The caption of the collection clearly reads: "Mike's unexpanded type-in collection". The included boot loader temporarily reverts your VIC-20 to unexpanded configuration so should you happen to have a RAM-Expander plugged in your VIC-20, you don't need to unplug it.

The only program on the *.d64 that actually requires +24K RAM is the READ ME, and that can also clearly be inferred from the directory content.

Please get the facts right when you post.


Edit (my reply above left as was before you added this):
Edit: oh, while writing the d64 I saw that tron is for unex vic... :oops: OK all right
... Yes, please ...

... And, yes - it cost me some big hunks of thought so this collection happily runs regardless what memory configuration is active. Irrespective whether on real hardware or emulator.


and P.S.: currently the only program of the lot I published over the years which requires +35K (i.e. +32K *and* +3K) is my 320x200 CGA viewer. That's nowhere near 'most of my productions'.
User avatar
Noizer
Vic 20 Devotee
Posts: 297
Joined: Tue May 15, 2018 12:00 pm
Location: Europa

Re: Toggle a bit in BASIC

Post by Noizer »

Mike wrote: Tue Jun 30, 2020 3:05 pm And pardon, you're proud of what?
Proud for the invitation:
Mike wrote: Mon Jun 29, 2020 7:54 pm You're gladly invited to try a 1:1 port of my TRON Light Cycles game from BASIC to machine code and check whether that translation improves anything.
Mike wrote: Mon Jun 29, 2020 7:54 pm All the games in this collection run on an unexpanded VIC-20!
Yes you are right, I think I mixed something up :roll:
Valid rule today as earlier: 1 Byte = 8 Bits
-._/classes instead of masses\_.-
Post Reply