Using XOR to invert only 1 bit?

Basic and Machine Language

Moderator: Moderators

Post Reply
Victim_RLSH
Vic 20 Drifter
Posts: 34
Joined: Thu Jul 15, 2021 10:50 pm
Location: Rapid City, SD
Occupation: Machine Shop Lackey

Using XOR to invert only 1 bit?

Post by Victim_RLSH »

Here is code that reverses a ball velocity after it bounces off of something on its left or right side. I flip the sign bit of a 7-bit signed integer stored in one byte.

TestLeft LDA CollisionFlags
AND #FromLeft$
BNE TestRight

LDA BallXVel
AND #%01111111 ; remove sign bit to reverse X direction
STA BallXVel

TestRight LDA CollisionFlags
AND #FromRight$
BNE CollisionUpdate

LDA BallXVel
ORA #%10000000 ; add sign bit to reverse X direction
STA BallXVel


Would it be possible to use XOR to just invert the sign bit and not waste memory on both routines?

would XOR #%10000000 flip only the sign bit and preserve the absolute value?
Works in Progress: Gravity Ball, a breakout variant in assembly for the unexpanded vic-20
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: Using XOR to invert only 1 bit?

Post by chysn »

Code: Select all

eor #%10000000
will, in fact, do what you say, flipping bit 7.

But keep in mind that’s different than changing the sign.

%10000001 is not -1, %11111111 is. If you simply flip bit 7 of 1, you get -127.

That may or may not matter in your application. If you think it might matter, we can delve into signed binary numbers and twos complement arithmetic.
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: Using XOR to invert only 1 bit?

Post by Mike »

Hi, Victim_RLSH,

Of course you can do sign-magnitude arithmetic on the 65xx, but that's not how the ADC and SBC instructions are supposed to be used. 'Emulating' sign-magnitude will easily lead to ten times more code and one tenth of the speed than what you'd get by employing 2s-complement, because you have to do all kinds of tests and case selections depending on the signs of the arguments and operator (add or subtract).

I had translated the "BALLPING" program in the User's Guide some time ago for my ML/VICMON primer, you find it here:

viewtopic.php?t=9197&start=1

In the original BASIC program, the velocity inversion at the borders happens in lines 120 and 140, with DX=-DX and DY=-DY, respectively. This is translated into machine code as follows:

Code: Select all

SEC
LDA #$00
SBC $xx   ; $xx=$F9 for DX, =$FA for DY
STA $xx
If the value is already in the accumulator, then it is a little bit shorter (3 or 2 instructions):

Code: Select all

SEC ; can be omitted if it is known that C=1
EOR #$FF
ADC #$00
*or*

Code: Select all

CLC ; can be omitted if it is known that C=0
EOR #$FF
ADC #$01
Note the equivalents of X=X+DX and Y=Y+DY simply use the ADC instruction with no case selections necessary (that would depend on the sign of DX or DY).

Greetings,

Michael
Victim_RLSH
Vic 20 Drifter
Posts: 34
Joined: Thu Jul 15, 2021 10:50 pm
Location: Rapid City, SD
Occupation: Machine Shop Lackey

Re: Using XOR to invert only 1 bit?

Post by Victim_RLSH »

Yeah, I did it the long way in this case, so the XOR should work. I just test for the sign bit and have separate increment and decrement routines depending on the velocity. No wonder I'm running out of space on such a simple game. My pathetic 6502 skills definitely need some help, which is why I'm doing this to begin with.
Works in Progress: Gravity Ball, a breakout variant in assembly for the unexpanded vic-20
tlr
Vic 20 Nerd
Posts: 567
Joined: Mon Oct 04, 2004 10:53 am

Re: Using XOR to invert only 1 bit?

Post by tlr »

Victim_RLSH wrote: Tue Aug 03, 2021 6:15 am Yeah, I did it the long way in this case, so the XOR should work. I just test for the sign bit and have separate increment and decrement routines depending on the velocity. No wonder I'm running out of space on such a simple game. My pathetic 6502 skills definitely need some help, which is why I'm doing this to begin with.
Practise, practise. I can recommend disassembling other peoples code figure out how stuff is done. Coding assembly is a fun puzzle game!
User avatar
srowe
Vic 20 Scientist
Posts: 1340
Joined: Mon Jun 16, 2014 3:19 pm

Re: Using XOR to invert only 1 bit?

Post by srowe »

tlr wrote: Tue Aug 03, 2021 10:45 am Practise, practise. I can recommend disassembling other peoples code figure out how stuff is done. Coding assembly is a fun puzzle game!
+1, you will learn some neat tricks which can save you space and/or clock cycles.
Post Reply