Re: [stella] reading the driving controllers, generic thoughts

Subject: Re: [stella] reading the driving controllers, generic thoughts
From: "Thomas Jentzsch" <tjentzsch@xxxxxx>
Date: Thu, 8 Nov 2001 10:11:22 +0100
Glenn wrote:
> I tried pretty hard to adapt this to my code but I couldn't do it.

Don't worry, I know it's quite weird optimized code :-)


> I wound up having to follow my original idea which was to take the previous 
> controller state and bit merge it with the current controller state side by 
> side, and scan through a table of pre-merged data and X > 3 then it's 
> turning right, else left.  So I've still got a table plus some overhead 
> shifting and merging bits and juggling registers in the process.

I would suggest to try to understand my first or second solution (which are quite similar to Eckhard's code). It's more or less straightforward code, while the third solution requires some braintwisting logical and aritmetical thinking. I think, if you understand the table-based code, it may become a little bit easier to understand the other stuff.

The main difference between your and my approach is, that I don't do any table *scanning*. Based on the previous value, my code *knows* what should come next, if you turn left or right. Therefore I only have to compare the actual value with the two possible expected values. 


Now, in the table-less solution, I'm taking this concept a bit further:

         lda SWCHA
         tay
         eor last        ; 01 or 10 (else: abrupt twist)
         sty last
         dey             ; -> y = -1..2
         cpy  #2
         sbc  #1 ; -> a = -1, 0, 1
         beq .right
.left:

First I'm EORing the previous with the current value. I'm *always* (unless abrupt twisting) getting 01 or 10 as a result (see the tables below). As you can also see, the EORed 10/01 sequences (column 3) differ between left and right turns.

Now follows the real trick! 

I'm decreasing the current value by 1 (column 4) and compare the result with +2. 

The resulting carry (column 5) is the clue. It is not only set for +2, but also for -1 because I'm doing an *unsigned* compare here, and -1(signed) == +255 (unsigned), which is >= +2 (=> carry is set).

With this carry I'm subtracting 1 from the EORed value. When the carry is clear (=0) *2* is subtracted, else *1*. 

The result of the subtraction (column 6) is always +1/-1 when turning left and 0 when turning right. Voila!

I hope these explanations make some sense :-)

The following tables show the intermediate and final results:
Turning left:
prev. curr. EORed   curr-1  carry   EORed sbc #1
00    01    01       0      0       -1      
01    11    10      +2      1       +1
11    10    01      +1      0       -1
10    00    10      -1      1       +1

Turning right:
prev. curr. EORed   curr-1  carry   EORed sbc #1
00    10    10      +1      0       0 
10    11    01      +2      1       0
11    01    10       0      0       0
01    00    01      -1      1       0

sbc #M: A = A - M + (carry - 1)

Have fun!
Thomas
_______________________________________________________
Thomas Jentzsch         | *** Every bit is sacred ! ***
tjentzsch at web dot de |

________________________________________________________________
Keine verlorenen Lotto-Quittungen, keine vergessenen Gewinne mehr! 
Beim WEB.DE Lottoservice: http://tippen2.web.de/?x=13


----------------------------------------------------------------------------------------------
Archives (includes files) at http://www.biglist.com/lists/stella/archives/
Unsub & more at http://www.biglist.com/lists/stella/


Current Thread