It is currently Wed Oct 18, 2017 9:44 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Greater than, less than
PostPosted: Tue May 03, 2016 11:46 pm 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1401
Yesterday, I was asking about overflow and underflow and how to check whether a value that was just changed is greater than or equal to (>=) 10.

For the last hand-written Assembly function that I need in my game, I want to do a comparison of two values. (Well, actually a comparison of two arrays, but the array aspect isn't important for my question.)

Both values are set in variables, i.e. I don't compare a variable with a constant value, but I compare two variables.

Now what do I have to do to check for "less than" (<) and "greater than" (>).

I do not need <= and >=, like I did yesterday. Only < and >.

Code:
LDA Value1
CMP Value2

BEQ @equals

XXX @lessThan

YYY @greaterThan

@equals:
    ; ...

@lessThan:
    ; ...

@greaterThan:
    ; ...

What would be XXX and YYY in this case?

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Tue May 03, 2016 11:54 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5716
Location: Canada
CMP puts < vs >= in carry. (Unsigned 8 bit, anyway. Signed or 16+ bit is a little more complicated.)

If you want > vs <= then reverse the two terms (CMP the 2nd against the 1st one instead of vice versa).

If you want < and > then you may create a third case to eliminate = by branching on the Z flag (BEQ/BNZ). If you get rid of the = case then the >= case is reduced to just >.


Top
 Profile  
 
PostPosted: Wed May 04, 2016 12:08 am 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1401
O.k., let's try this:

Code:
LDA Value1
CMP Value2

BEQ @equal
BCS @lessThan
JMP @greaterThan

Correct so far?

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Wed May 04, 2016 12:15 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5716
Location: Canada
You have the carry condition backwards.

Carry is set by CMP if A (Value1) is greater than or equal to its paramter (Value2). If it is less than, carry is cleared by CMP.

BCS = Branch if Carry is Set
BCC = Branch if Carry is Clear


Last edited by rainwarrior on Wed May 04, 2016 12:46 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Wed May 04, 2016 12:18 am 
Offline
User avatar

Joined: Wed Apr 02, 2008 2:09 pm
Posts: 1019
BCS is greater than or equal. In your example equal is checked for, but BCS should be bcc. (And... it should also go before BEQ. Having BEQ first means you check for it on BCC cases, which adds time to them. If a BCC branches, you don't need a beq check, so having it before checking for that range is a bit slower.)

A compare is a subtract. CMP and SBC are identical except CMP does not care about the state of the carry going in, and doesn't affect A with the result.

The carry flag lets you know about overflow/underflow. Typically before starting a subtract with sbc, you set the carry flag with sec. Knowing this, it makes sense that carry flag reverses (clears) on underflow. An underflow occurs when you subtract a value larger than the first. Which means that if the second value is smaller (or equal), there will be no underflow. Thus the carry will stay set.

So... the carry staying set means the value you're subtracting was less than or equal. Which means the first value was greater than or equal to the second value. Because a compare is a subtract.

_________________
https://kasumi.itch.io/indivisible


Top
 Profile  
 
PostPosted: Wed May 04, 2016 12:29 am 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2962
Location: Tampere, Finland
A little mnemonic that can be helpful in remembering which is which: 0 < 1, so if carry=0 (BCC), it's "less than".

Or, you can make a wrapper macro for it/them, which is what I usually do.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Wed May 04, 2016 12:31 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10052
Location: Rio de Janeiro - Brazil
rainwarrior wrote:
Carry is set by CMP if its parameter (Value2) is greater than or equal to register A (Value1). If it is less than, carry is cleared by CMP.

Wait... you got it backwards. CMP is a subtraction. If A holds a big number (Value1) and you subtract a small number (Value2), there's no borrow/underflow, meaning the carry is set. If A holds a small number (Value1) and you subtract a big number (Value2), there's a borrow/underflow, so the carry is cleared.

EDIT: Personally, I don't like the expressions "greater than" and "less than" because I never know which value goes on which end of the expression (e.g. is it "accumulator greater than argument" or "argument greater than accumulator"?), so I much prefer to always think of comparisons as subtractions, and look out for underflows to know which value is larger.


Last edited by tokumaru on Wed May 04, 2016 12:48 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Wed May 04, 2016 12:47 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5716
Location: Canada
Sorry. I should go to bed. :P Yes, my description was wrong, but DRW's example was indeed backwards. I have amended my description.


Top
 Profile  
 
PostPosted: Wed May 04, 2016 4:19 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19096
Location: NE Indiana, USA (NTSC)
rainwarrior wrote:
Carry is set by CMP if A (Value1) is greater than or equal to its paramter (Value2). If it is less than, carry is cleared by CMP.

BCS = Branch if Carry is Set
BCC = Branch if Carry is Clear

Many assemblers support mnemonic aliases described by Western Design Center. (Open 65c816.txt and search for "common mnemonic aliases".) If yours does not, you can write a macro, as thefox suggested.

BCS = BGE = Branch if Greater or Equal
BCC = BLT = Branch if Less Than


Top
 Profile  
 
PostPosted: Wed May 04, 2016 6:00 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1771
Location: DIGDUG
If you're unsure of the ASM...write it in C code in a blank cc65 file, and see how it compiles it. It takes like 10 seconds to do.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Wed May 04, 2016 6:27 am 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1401
dougeff wrote:
If you're unsure of the ASM...write it in C code in a blank cc65 file, and see how it compiles it. It takes like 10 seconds to do.

I tried, but it created such a strange code. I'm not at home in the moment, but I can post it later.

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Wed May 04, 2016 1:08 pm 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1401
dougeff wrote:
If you're unsure of the ASM...write it in C code in a blank cc65 file, and see how it compiles it. It takes like 10 seconds to do.

O.k., I know now what I did wrong:

Since my actual build command is used with cl65 and therefore, the Assembly files are only created in memory, but not on the hard disk, I always have to do a manual call to cc65 when I want to see the Assembly code of a source file. And I forgot to turn on optimization for this manual call. That's why the code was so strange. But yeah, with the -O switch, everything looks like it should.

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Fri May 06, 2016 12:44 pm 
Offline
User avatar

Joined: Mon Feb 07, 2011 12:46 pm
Posts: 919
This way of setting the carry if it is greater or equal does help in many cases, for example if you are doing CMP #10 in order to do carrying for decimal arithmetic; you might not need a branch in such a case.

_________________
.


Top
 Profile  
 
PostPosted: Fri May 06, 2016 1:27 pm 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
I would possibly structure it like:

Code:
lda value1
cmp value2
bcc lessThan
beq endif

  ; if value1 > value2 
  jmp endif ; (or use a branch if flag condition will be known)

lessThan:

  ; if value1 < value2

endif:


Top
 Profile  
 
PostPosted: Fri May 06, 2016 6:59 pm 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1401
Movax12 wrote:
I would possibly structure it like:

Is there any real difference between checking for < first and then checking for =? Because my current intention was to check for BEQ first, then for BCC. So, is there any actual difference?

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 7 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:  
Powered by phpBB® Forum Software © phpBB Group