Jump to content

Photo

Is there any way to use a bit as 255 or 1?


20 replies to this topic

#1 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • 24,747 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Mon May 30, 2011 4:53 PM

I'm trying to figure out how to do the following with fewer steps:

   temp5 = 255 : if B_Direction_x{5} then temp5 = 1

   ballx = ballx + temp5


If I isolate the bit like this:

   temp5 = B_Direction_x & %00100000

I don't get 0 or 1, I get 0 or 32 (which makes sense, but I need zeros and ones).

If I can figure out how to convert that to 0 and 1, I'll still need to figure out how to turn the 0 into 255 and leave the 1 alone. I'm starting to understand bits a little more, but this is still way over my head.


Thanks.

#2 Devin OFFLINE  

Devin

    Moonsweeper

  • 489 posts
  • Its all HCLR to me!
  • Location:Sacramento, California,

Posted Mon May 30, 2011 5:06 PM

If I isolate the bit like this:

   temp5 = B_Direction_x & %00100000

I don't get 0 or 1, I get 0 or 32 (which makes sense, but I need zeros and ones).
Thanks.


You can right shift the result 5 times to get the 1 you need. You could then use the 1 or 0 as an index into a table containing 0 and 255.

#3 ScumSoft OFFLINE  

ScumSoft

    Moonsweeper

  • 348 posts
  • Location:Polysorbate 60

Posted Mon May 30, 2011 5:45 PM

I take it this is for reversing the direction of a ball when it collides with a wall or the like?
   rem * temp5 = 255 : if B_Direction_x{5} then temp5 = 1

   if B_Direction_x{5} then temp5 = 255 else temp5 = 1
   ballx = ballx + temp5
perhaps something like this then? asm for speed:
  asm
  lda B_Direction_x
  and #$20  ;Is bit 5 enabled?
  beq set1  ;If 0 then add 1 else add 254
  lda #$FE  ;254 + 1
  adc BallX ;carry should be set so add FE to get 255
  sta BallX ;Save change
  jmp .exit
set1
  inc BallX ;Same as adding BallX + 1 which is what temp5 would hold here
.exit
end

[edit] Thanks for the catch RevEng, forgot to add the ballX :D

Edited by ScumSoft, Mon May 30, 2011 7:00 PM.


#4 RevEng OFFLINE  

RevEng

    River Patroller

  • 3,269 posts
  • bit player
  • Location:Canada

Posted Mon May 30, 2011 5:58 PM

RT's original only has one bitwise check vs a bunch of shifting, and it works out being the faster of the first two. ScumSoft's routine is the fastest of the bunch.

But in the spirit of the original question, you can turn the bit into a 255 or 1 in the following way...

temp5=(B_Direction_x&%00100000)/16)-1

The divide by 16 shifts the bit right 4 positions, so it's either 0 or 2. Subtracting 1 from that provides a result that is either 255 or 1.

#5 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 24,747 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Mon May 30, 2011 6:27 PM

RT's original only has one bitwise check vs a bunch of shifting, and it works out being the faster of the first two. ScumSoft's routine is the fastest of the bunch.

But in the spirit of the original question, you can turn the bit into a 255 or 1 in the following way...

temp5=((B_Direction_x&%00100000)/16)-1

The divide by 16 shifts the bit right 4 positions, so it's either 0 or 2. Subtracting 1 from that provides a result that is either 255 or 1.

Thanks. So if I'm reading your post right, my crappy code with the if-then is faster than your code that divides by 16?

#6 RevEng OFFLINE  

RevEng

    River Patroller

  • 3,269 posts
  • bit player
  • Location:Canada

Posted Mon May 30, 2011 6:48 PM

Yup. The divide by 16 (or 4 right shifts) in mine is more costly than your code.

If you cherry picked the bit position so there was no dividing, mine would be marginally faster.

Actually, looking again at ScumSoft's code, it's equivalent in runtime to yours. I just didn't notice he skipped the final ballx addition in his.

[edit...]

On second thought, I guess ScumSoft's code could include the ballx addition more efficiently than the assembly generated from your bB code does...

  asm
  lda B_Direction_x
  and #$20
  beq set1
  lda #$FF
  BYTE $2C
set1
  lda #1
  clc
  adc ballx
  sta ballx
end

...but the difference in performance is pretty marginal.

#7 ScumSoft OFFLINE  

ScumSoft

    Moonsweeper

  • 348 posts
  • Location:Polysorbate 60

Posted Mon May 30, 2011 7:15 PM

RT unless you would run that in a loop counting many balls then the efficiency for a single one should be negligible.
Pretty slick code there RevEng, I forgot about the BIT trick since I never use it.

Edited by ScumSoft, Mon May 30, 2011 7:16 PM.


#8 RevEng OFFLINE  

RevEng

    River Patroller

  • 3,269 posts
  • bit player
  • Location:Canada

Posted Mon May 30, 2011 8:52 PM

RT unless you would run that in a loop counting many balls then the efficiency for a single one should be negligible.
Pretty slick code there RevEng, I forgot about the BIT trick since I never use it.

Thanks, but it wasn't particularly clever on my part. Just a memorized trick. :)

As you say, there's hardly a difference between the solutions if you're running them only a few times. In that case the solution that's the most readable and maintainable in bB should be the winner, so the prize goes to RT! :D

#9 SeaGtGruff OFFLINE  

SeaGtGruff

    Quadrunner

  • 5,443 posts
  • Location:Georgia, USA

Posted Mon May 30, 2011 9:25 PM

I'm trying to figure out how to do the following with fewer steps:

   temp5 = 255 : if B_Direction_x{5} then temp5 = 1

   ballx = ballx + temp5

Use temp5 = temp5 ^ %11111110 (or temp5 = temp5 ^ 254). Assuming you've initialized temp5 to 1, this will toggle it between 1 and 255 (-1).

Michael

Edit: Or you could initialize temp5 to 255.

Edit #2: I'm not sure if my answer helps with your specific problem. I was answering the question "How do I toggle a variable between 1 and 255," which isn't exactly the question you were asking.

Edited by SeaGtGruff, Mon May 30, 2011 9:31 PM.


#10 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 24,747 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Tue May 31, 2011 3:56 AM

I take it this is for reversing the direction of a ball when it collides with a wall or the like?

Yeah, I forgot to answer that. It's for bouncing off the edges of the playfield.




As you say, there's hardly a difference between the solutions if you're running them only a few times. In that case the solution that's the most readable and maintainable in bB should be the winner, so the prize goes to RT! :D

It will be running constantly in the example program. This is a condensed version of what I originally had:

   dim B_Direction_x = h
   dim B_Direction_y = i


   ballx = (rand&127) + 8 : bally = 9 : rem * Starting position of ball.

   CTRLPF = $11 : ballheight = 2 : rem * Defines ball size.

   B_Direction_x = 255 + (rand&2) : B_Direction_y = 1 : rem * Ball starting direction.


Main_Loop


   rem  ****************************************************************
   rem  *
   rem  *  Bounce the ball if it hits the edge of the screen.
   rem  *
   rem  '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
   rem  '
   if ballx < 3 || ballx > 158 then B_Direction_x = -B_Direction_x

   if bally < 3 || bally > 88 then B_Direction_y = -B_Direction_y



   rem  ****************************************************************
   rem  *
   rem  *  Move the ball.
   rem  *
   rem  '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
   rem  '
   ballx = ballx + B_Direction_x : bally = bally + B_Direction_y


   drawscreen


   goto Main_Loop

Seems like I've done code like that a billion times on the VIC-20 and the Commodore 64, but then it hit me that I was wasting 2 precious variables when I could do the same thing with 2 bits. So here's the condensed version of what I changed it to:

   rem * other bit variable names removed since they are not needed for this post

   dim B_Direction_x = t
   dim B_Direction_y = t


   ballx = (rand&127) + 8 : bally = 9 : rem * Starting position of ball.

   CTRLPF = $11 : ballheight = 2 : rem * Defines ball size.

   temp5 = (rand & %00100000) : B_Direction_x = B_Direction_x ^ temp5 : rem * Ball starting direction.

   B_Direction_y{6} = 1 : rem * Ball starting direction.


Main_Loop


   rem  ****************************************************************
   rem  *
   rem  *  Bounce the ball if it hits the edge of the screen.
   rem  *
   rem  '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
   rem  '
   if ballx < 3 || ballx > 158 then B_Direction_x = B_Direction_x ^ %00100000

   if bally < 3 || bally > 88 then B_Direction_y = B_Direction_y ^ %01000000



   rem  ****************************************************************
   rem  *
   rem  *  Move the ball.
   rem  *
   rem  '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
   rem  '
   temp5 = 255 : if B_Direction_x{5} then temp5 = 1

   ballx = ballx + temp5


   temp5 = 255 : if B_Direction_y{6} then temp5 = 1

   bally = bally + temp5



   drawscreen


   goto Main_Loop
Since you said it's readable and maintainable and the speed isn't that bad, I guess I'll leave it the way it is.




Use temp5 = temp5 ^ %11111110 (or temp5 = temp5 ^ 254). Assuming you've initialized temp5 to 1, this will toggle it between 1 and 255 (-1).

Michael

Edit: Or you could initialize temp5 to 255.

Edit #2: I'm not sure if my answer helps with your specific problem. I was answering the question "How do I toggle a variable between 1 and 255," which isn't exactly the question you were asking.

Yeah, I don't need that for this example program, but I should add that to the bB page.

Thanks.

Edited by Random Terrain, Tue May 31, 2011 3:57 AM.


#11 RevEng OFFLINE  

RevEng

    River Patroller

  • 3,269 posts
  • bit player
  • Location:Canada

Posted Tue May 31, 2011 4:32 AM

Yeah, I don't need that for this example program, but I should add that to the bB page.

If you do add it, it should be in the general case - xor can be used to toggle a variable between any two chosen values.

Picking 2 numbers out of a hat, say 13 and 96...

1. XOR them together with a calculator first, and note the result. (13^96=109)
2. Set your variable to either 13 or 96 initially.
3. XOR the variable with your calculator value (109) every time you want it to flip to the other value. (because 13^109=96 and 96^109=13)

...I used this same trick to make a compact shuffle animation in 21 Blue. In a loop I xor'ed each card pointer with a value that would change it from pointing to a blank image to a card back image. I replayed the loop 4 times. The first time would make cards appear, the second would make them disappear, the third would make the cards appear again, and the fourth time they'd disappear for good.

#12 roland p ONLINE  

roland p

    Stargunner

  • 1,852 posts
  • $23
  • Location:The Netherlands

Posted Tue May 31, 2011 4:47 AM

This way the ball has to go through the border in order to detect a collision

You could first move the ball and then check for collisions.

And when a collision happens you could let it bounce also by mirroring its position:

if ballx < 3 then 
   B_Direction_x = B_Direction_x ^ %00100000 
   ballx = ballx + (3-ballx)
endif

So when ballx is 2, it will become 4 like it has bounced off the wall.

#13 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 24,747 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Tue May 31, 2011 4:55 AM


Yeah, I don't need that for this example program, but I should add that to the bB page.

If you do add it, it should be in the general case - xor can be used to toggle a variable between any two chosen values.

Picking 2 numbers out of a hat, say 13 and 96...

1. XOR them together with a calculator first, and note the result. (13^96=109)
2. Set your variable to either 13 or 96 initially.
3. XOR the variable with your calculator value (109) every time you want it to flip to the other value. (because 13^109=96 and 96^109=13)

...I used this same trick to make a compact shuffle animation in 21 Blue. In a loop I xor'ed each card pointer with a value that would change it from pointing to a blank image to a card back image. I replayed the loop 4 times. The first time would make cards appear, the second would make them disappear, the third would make the cards appear again, and the fourth time they'd disappear for good.

I didn't even notice that my Microsoft calculator had an XOR button (when switched to the scientific view). I was just playing around with it and that sure is a handy button. That makes it easy to flip between any two numbers. I'll add it to the bB page later today as soon as I figure out exactly where it should go.

Thanks.

#14 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 24,747 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Tue May 31, 2011 7:01 AM

This way the ball has to go through the border in order to detect a collision

Thanks. Before I did the border bounce code, I found out how far the ball could go, then pulled the numbers back so it wouldn't go past the actual borders.

#15 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 24,747 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Wed Jun 1, 2011 7:26 AM

If you do add it . . .

I'm still not sure where to put it, so I stuck it here for now:

www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#how_to_flip

I can always move it later if someone can find a better place to put it.

#16 roland p ONLINE  

roland p

    Stargunner

  • 1,852 posts
  • $23
  • Location:The Netherlands

Posted Wed Jun 1, 2011 7:37 AM

Never knew you could use the calculator for that :). I always wrote them out and put a '1' in the places that need to flip:

11111111 ;value a
00000001 ;value b

11111110 ;xor value

#17 SpiceWare OFFLINE  

SpiceWare

    Quadrunner

  • 8,082 posts
  • Medieval Mayhem
  • Location:Planet Houston

Posted Wed Jun 1, 2011 1:44 PM

The calculator in OS X does as well, you just have to switch via the View menu to Programmer.

Calculator - Programmer View.png

#18 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 24,747 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Thu Jun 2, 2011 6:34 AM

The calculator in OS X does as well, you just have to switch via the View menu to Programmer.

Thanks. I updated the page:

www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#how_to_flip

#19 bogax OFFLINE  

bogax

    Moonsweeper

  • 469 posts

Posted Sat Jun 4, 2011 2:16 PM

I'm trying to figure out how to do the following with fewer steps:

   temp5 = 255 : if B_Direction_x{5} then temp5 = 1

   ballx = ballx + temp5


This works (ie bB doesn't choke on it and it assembles)

 dim ballx_dir = a
 dim ballx_pos = b

 macro incv
 asm
 inc {1}
end
end

 macro decv
 asm
 dec {1}
end
end

 if ballx_dir & 32 then callmacro incv ballx_pos else callmacro decv ballx_pos

used my own names, sorry if that's confusing

#20 batari OFFLINE  

batari

    )66]U('=I;B$*

  • 6,464 posts
  • begin 644 contest

Posted Sat Jun 4, 2011 3:05 PM


I'm trying to figure out how to do the following with fewer steps:

   temp5 = 255 : if B_Direction_x{5} then temp5 = 1

   ballx = ballx + temp5


This works (ie bB doesn't choke on it and it assembles)

 dim ballx_dir = a
 dim ballx_pos = b

 macro incv
 asm
 inc {1}
end
end

 macro decv
 asm
 dec {1}
end
end

 if ballx_dir & 32 then callmacro incv ballx_pos else callmacro decv ballx_pos

used my own names, sorry if that's confusing

That's interesting, though this statement would compile exactly the same as yours without need for macros:
 if ballx_dir & 32 then ballx_pos=ballx_pos+1 else ballx_pos=ballx_pos-1

Edited by batari, Sat Jun 4, 2011 3:43 PM.


#21 Omegamatrix OFFLINE  

Omegamatrix

    Quadrunner

  • 5,491 posts
  • Location:Canada

Posted Sat Jun 4, 2011 3:16 PM

I'm trying to figure out how to do the following with fewer steps:

   temp5 = 255 : if B_Direction_x{5} then temp5 = 1

   ballx = ballx + temp5


How about:

asm
     lda   B_Direction_x
     and   #$20
     beq   increaseDirection
     dec   ballx
     .byte $0C  ; NOP opcode, skip next 2 bytes
increaseDirection:
     inc   ballX
end





0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users