6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 6:31 pm

All times are UTC




Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: Thu Jul 08, 2004 3:02 pm 
Offline

Joined: Fri Jun 27, 2003 8:12 am
Posts: 618
Location: Meadowbrook
I am wanting to do multiple condition logic for certain things to happen. So far, I have to test each individually, can I use a multiple set of conditions such as:

lda GameRunFlag
AND Player1UpFlag
AND BallInPlayFlag
AND SoundDoneFlag
bne BeginPlayballSequence

would I be able to do a code like above? Each logic flag can be either #$00 or #$01. Was wondering if the multiple ANDS would give mne a valid result at the end for all 4 flags being #$01..... thanks :)

_________________
"My biggest dream in life? Building black plywood Habitrails"


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Jul 08, 2004 5:57 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
> Each logic flag can be either #$00 or #$01.

I don't think you meant to have the "#" in there, did you? If you really meant "immediate" (which doesn't make sense in this case), you could have the assembler AND them together and put the resulting operand in just one instruction and be done.

For the non-immediate though where you're looking at flags that might have either value, the BNE will work fine-- as long as at least one bit of each set flag is the same bit.

-1 (all bits set) is typically used for a "flag set" condition though if stored by the program. It would more typically be a 1, 2, 4, 8, etc. if it were an input bit from a switch or other hardware. If it's 0 and you want to set the flag, you can do it with a single DEC instruction. On the CMOS 6502, the single instruction STZ clears it, regardless of initial value. No need to use LDx first in either case.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Jul 09, 2004 2:50 pm 
Offline

Joined: Fri Jun 27, 2003 8:12 am
Posts: 618
Location: Meadowbrook
I did mean that the flag variables can be either #$00 or #$01 in value, just the first bit being set to tell me the condition. Reason being that since the rAM amount is 32768 (-256 for i/o), much variables isnt a problem all around.

For a single variable test, the beq/bne works out great. Its when I want to check for multiple conditions. Up to now, I've done sequential checks on each flag, which is why I wanted to be ablt to do such a logic test into one simple branch.


Alreayd did the switch to the 65C02, so I will be learning more on that puppy as time goes by. Runs so much cooler than a 6502B :)

_________________
"My biggest dream in life? Building black plywood Habitrails"


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Jul 09, 2004 3:15 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
Nightmaretony wrote:
I did mean that the flag variables can be either #$00 or #$01 in value, just the first bit being set to tell me the condition. Reason being that since the rAM amount is 32768 (-256 for i/o), much variables isnt a problem all around.

For a single variable test, the beq/bne works out great. Its when I want to check for multiple conditions. Up to now, I've done sequential checks on each flag, which is why I wanted to be ablt to do such a logic test into one simple branch.


Alreayd did the switch to the 65C02, so I will be learning more on that puppy as time goes by. Runs so much cooler than a 6502B :)


How many variables are we talking about? If every variable is guaranteed to be only $00 or $01 in value, then you can do something like this:

Code:
  lda Player1Up
  asl a
  ora Player2Up
  asl a
  ora SomeOtherVariable
  asl a
  ora YetAnother
  asl a
  tax
  jmp DecisionTable,x


With four variables, your decision table array has to be 16 elements. With five variables, it'd need to be 32 elements, etc. This is the fastest method I know how to make multiple decisions at once. Note that you're limited to only 7 variables with this technique; to accomodate more requires something a bit more sophisticated, but you get the idea.

Now if you were using a 65C816, you'd be able to do this with up to 15 variables. :D


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jul 10, 2004 5:55 am 
Offline

Joined: Fri Jun 27, 2003 8:12 am
Posts: 618
Location: Meadowbrook
Now, THAT is a grand idea for multipel ocnditions, PLUS I can check for if its a 1 or 0 simultanoues! Thanks, mon!

I would not be using a decision table but more of a trip gate logic in a constabntly running event loop. At the end of the loop is a decision set of gates; the rules as it were. I wanted to avoid doing multiple BNE/BEQ stattements. This way, I can do a single branch to skip if the condition is not true, so an action can be performed. And so thus:

lda GameInPlayFlag ; 1 if the game is runing
asl
ora SolonoidsEnabled ; 1 to let solonoids do their thing
asl
ora SoundIsClear ; 0 if its ok to send a sound
asl
ora ScoreIsShown ; 1 if the player's score is shown now

; at this point, the lrequired action is only if the bits are %00001011

cmp #$0B
bne SkipAction

do the action here, like flash the score

SkiipAction
continue the work...


This way, I am not limited to each bit having to be 1, and the code is quite clean this way. For the game rules section, this is the best and easiest way to go. Thanks again!

_________________
"My biggest dream in life? Building black plywood Habitrails"


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jul 10, 2004 6:03 am 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
Nightmaretony wrote:
Now, THAT is a grand idea for multipel ocnditions, PLUS I can check for if its a 1 or 0 simultanoues! Thanks, mon!


No problem. Glad I could help. :)

Quote:
This way, I am not limited to each bit having to be 1, and the code is quite clean this way. For the game rules section, this is the best and easiest way to go. Thanks again!


Well, thrifty use of bits can let you use small integers instead of single bits too. But beware, because your decision tree can explode if you're not watching.

Anyway, good luck. :)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jul 10, 2004 6:32 am 
Offline

Joined: Fri Jun 27, 2003 8:12 am
Posts: 618
Location: Meadowbrook
I could do that since there is one flag, the GameJobFlag which tells what is going on and can be from 0-8 for its cinditoinal. By throwing thaqt in the first 3 bits, that can be tested as such.

I dont see it create a ripple explode effect on the rest of the code because it is basically doing a simple format of

if (condition is true) AND (conditions is true) AND (condition is true)
then do procedure
end procedure

continue

This also keeps the logic simpler by grouping the statement together like that.

_________________
"My biggest dream in life? Building black plywood Habitrails"


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jul 12, 2004 9:09 am 
Offline
User avatar

Joined: Thu Mar 11, 2004 7:42 am
Posts: 362
When you have a set of flag variables where "false" is indicated by $00 and "true" is indicated by a non-zero value, as long as you use the same non-zero value (such as $01) for all of your "true" variables, then AND will work just fine. For example, the high level statement:

IF (FV1 AND FV2 AND FV3) THEN BRANCH

becomes:

Code:
LDA FV1
AND FV2
AND FV3
BNE LABEL


Also, the high level statement:

IF (FV1 OR FV2 OR FV3) THEN BRANCH

becomes:

Code:
LDA FV1
ORA FV2
ORA FV3
BNE LABEL


In fact, the OR routine will branch if any of the FVs are non-zero, even if those non-zero values are different.

The AND doesn't work quite the same way. The simplest thing to do just pick a non-zero value and use it as "true" for all of your flags, but AND will also work as bit K (K can be any bit from 0 to 7) is a 1 in all "true" flags.

For example, if you have two flag variables, FV1 and FV2, where FV1 "true" is $01 and FV2 "true" is $02, then ORA works, but AND always returns zero.

Another example: if you have three flags, FV1, FV2 and FV3, where FV1 "true" is $04, FV2 "true" is $05, and FV3 "true" is $0C, then AND works because bit 2 of all three "true" values ($04, $05, and $0C) is 1. (ORA also works, of course.)

$FF is typically the most useful "true" value, because it allows you to use AND with one flag whose "true" value is not $FF. At least one of the bits in any non-$FF, non-zero value is 1, and that bit of $FF will be a also 1 (since all of the bits of $FF are 1).


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Jul 15, 2004 10:00 am 
Offline

Joined: Fri Jun 27, 2003 8:12 am
Posts: 618
Location: Meadowbrook
The ASL/ORA combination seems to work best for two reasons.
1. The particular flag may be required ot be 0 instead of 1.
2. the GameJob flag is 3 bits, from 0-7.

by shifting, ORAing the added bits then doing a CMP to the result, it gives me a speedy and clean check that satisfies my needs up above. It is also versatile in which I can have a smaller amount of bits to check by, going up to 8 bits, or 5 flags and GameJob. For example, two examples out of the code that work already...

TestPassesDisplay
LDA GameJob ; If (GameJob = 3) AND TestPassesStep = 0)
ASL
ASL
ASL
ORA TestPassesStep ; so the result to compare with is 1100 or #$0C
CMP #$18
BNE TestPassesDisplay1


TestPassesDisplay2
LDA GameJob ; if (GameJob = 3) AND (TestPassesStep = 2) AND MessageCenterrunFlag = 1) AND (1SecondFlag = 1)
ASL
ASL
ORA TestPassesStep
ASL
ASL
ORA MessageCenterRunningFlag
ASL
ORA MessageCenterTimerDoneFlag
CMP #$73 ; debug idea, push the result to stack to show it when correct :)
BNE TestPassesDisplay3


The comment I put up also makes it easy to visualize the way I need it to do. The function for the above code is the inline check, for when the power up self test is finished, it will display TEST for 2 seconds then PASSES for 2 seconds then begins the attract mode. The code runs about 60 times a second at the present time., strobing the matrix. (got in plenty of delay to allow the showing times and things, but thats another tale there).

If I used the multiple AND statements, I would not get the versatility needed. This way, the read is pretty intuitive.... :)

I owe another lunch here..... :)

_________________
"My biggest dream in life? Building black plywood Habitrails"


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Jul 16, 2004 8:10 am 
Offline
User avatar

Joined: Thu Mar 11, 2004 7:42 am
Posts: 362
Your first example will be faster with:

Code:
LDA GameJob            ; If (GameJob = 3) AND (TestPassesStep = 0)
EOR #3
ORA TestPassesStep
BNE TestPassesDisplay1


IF (GameJob <> 3) OR (TestPassesStep <> 0) THEN BRANCH

is the same as:

IF (GameJob = 3) AND (TestPassesStep = 0) THEN CONTINUE

Your second example will be faster with:

Code:
LDA GameJob            ; if (GameJob = 3) AND (TestPassesStep = 2) AND
CMP #3                 ;    (MessageCenterrunFlag = 1) AND (1SecondFlag = 1)
BNE TestPassesDisplay3
LDA TestPassesStep
CMP #2
BNE TestPassesDisplay3
LDA MessageCenterRunningFlag
AND MessageCenterTimerDoneFlag
BEQ TestPassesDisplay3


Again, the high level IF NOT CONDITION THEN BRANCH is the same as IF CONDITION THEN CONTINUE.

A pair of ASL instructions takes 4 cycles, but so does a CMP immediate (or EOR immediate) and a branch not taken. If the branch is taken, you won't have to do any more comparisons, so that will also be faster. The main advantage of the two ASLs is less space, although your example will take the same number of cycles regardless of which conditions are true or false, and that might be what you want in a game.

Readability is always somewhat subjective, but I think it's easier to understand the conditions from the code above, rather than packing everything into one byte and using a single comparison. (The packing is where you lose speed.) Also, the packing may be more error prone, since you have to match your immediate value to the number of shifts, and then there's the matter of keeping your high level comments up to date. If the size (i.e. number of bits) of variable increases -- say it used to range from 0 to 3, but in the midst of writing/debugging you forgot about something (as we all tend to do) and it now ranges from 0 to 4 -- you have to rewrite most every comparsion (even the ones that don't use the new value) with the packing method, but with the above you don't. Of course, you are free to do as you wish, but it's something to consider.

Just for the sake of completeness, your example from a few posts back will be faster with:

Code:
LDA SoundIsClear     ; 0 if its ok to send a sound
BNE SkipAction
LDA GameInPlayFlag   ; 1 if the game is runing
AND SolonoidsEnabled ; 1 to let solonoids do their thing
AND ScoreIsShown     ; 1 if the player's score is shown now
BEQ SkipAction


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Jul 16, 2004 5:55 pm 
Offline

Joined: Fri Jun 27, 2003 8:12 am
Posts: 618
Location: Meadowbrook
The time it takes I am not too worried about since in between each matrix step, I am running a 512 cycle delay loop to allow it to show onscreen. The game logic rules only get invoked at the end of the 8 matrix step routine. The entire cycle is right now running about 60 Hz which is more than rela pinball machines which scheck their matrix about 30 times a second. If things bog down, I can always cut down on the small delay steps. At 4 MHz, its more fairly forgiving :) Plus in making it a single, I avoid in case some wierd combination causes it to branch out wrong, which would drive me bats....

I am figuring that at the end of each matrix cycle, the main switchboard tells it what to do which is aqbout 3 or 4 such decision branches, and then reach game rule set may fall through about 10 of them before setting what it needs to, or maybe more. :)....

_________________
"My biggest dream in life? Building black plywood Habitrails"


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 17 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: