Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.
The idea being that Subroutine4 wins out if no other block of comparisons jumps you out. But it fails because if Var1 is $30 and Var2 is $30 then neither is lower than the other and thus Subroutine4 is selected despite potentially being $40 which is higher than both. For ties I don't really care which of the tied subroutines wins out, but I can't just add a BEQ instruction that jumps out on ties, as if I do that I never get around to testing Var3 which might actually be $10 and should have won over the tie.
Can somebody point me in the right direction on how to do this properly?
LDA Var1
CMP Var2 ; Carry set if Var1 >= Var2
BCC +next ; Jump to +next if carry clear
CMP Var3 ; Carry set if Var1 >= Var3
BCC +next ; Jump to +next if carry clear
CMP Var4 ; Carry set if Var1 >= Var4
BCC +next ; Jump to +next if carry clear
JMP Subroutine1
That means that Var1 needs to be lower than Var2, Var3, and Var4. So if the JMP here runs, it means Var1 was lowest, not highest.
LDA Var1 ; \
CMP Var2 ; |
BCC +next ; / If Var1 < Var2, go to +next. (If Var1 >= Var2, go to the next instruction.)
CMP Var3 ; \
BCC +next ; / If Var1 < Var3, go to +next. (If Var1 >= Var3, go to the next instruction.)
CMP Var4 ; \
BCC +next ; / If Var1 < Var4, go to +next. (If Var1 >= Var4, go to the next instruction.)
JMP Subroutine1 ; (If we got to here, then Var1 >= Var2 and Var1 >= Var3 and Var1 >= Var4.)
+next: ; (If we got to here, then Var1 < Var2 or Var1 < Var3 or Var1 < Var4.)
...
In general, when you want to figure out which variable in a collection of variables is the smallest, the simplest way to do so is to go through all of them, one by one, while keeping track of what the smallest value you've seen so far is.
var minVal = var1
var minVarNum = 1;
if (var2 < minVal ) {
minVal = var2;
minVarNum = 2;
}
if (var3 < minVal ) {
minVal = var3;
minVarNum = 3;
}
if (var4 < minVal ) {
minVal = var4;
minVarNum = 4;
}
It doesn't matter which order you look at the variables in, the important thing is that you've looked at all of them, each time.
If it's a small number of variables, such as 4, you can get away with writing an IF statement for each one. If you need to expand it into 6 or more, I'd recommend changing this to a loop instead.
I normally solve these kinds of problems like Drag suggested. If you're using 8-bit numbers stored in a sequential list, the implementation in assembly could be something like this:
ldx #$00 ;assumes that item 0 is the smallest
lda Values+1 ;loads item 1
cmp Values, x ;compares it against the smallest
bcs :+ ;branches if item 1 is equal or larger
ldx #$01 ;makes item 1 the smallest
:
lda Values+2 ;loads item 2
cmp Values, x ;compares it against the smallest
bcs :+ ;branches if item 2 is equal or larger
ldx #$02 ;makes item 2 the smallest
:
lda Values+3 ;loads item 3
cmp Values, x ;compares it against the smallest
bcs :+ ;branches if item 3 is equal or larger
ldx #$03 ;makes item 3 the smallest
:
lda SubroutineAddressesLow, x
sta Pointer+0
lda SubroutineAddressesHigh, x
sta Pointer+1
jmp (Pointer)
ldx #$00 ;assumes that item 0 is the smallest
ldy #LAST_INDEX ;starts testing from the last item
TestItem:
lda Values, y ;loads the current item
cmp Values, x ;compares it against the smallest
bcs :+ ;branches if the current item is equal or larger
tya ;makes the current item the smallest
tax
:
dey ;goes to the previous position
bne TestItem ;branches if this is not the first position
ldx #0
lda Value1
cmp Value2 ; compare Value1 < Value2
bcc +
lda Value2 ; value 2 is smaller, so load into a
ldx #1 ; set 2nd value as smallest
+ cmp Value3 ; compare result against Value3
bcc +
lda Value3 ; value 3 is smaller, so load into a
ldx #2 ; set 3rd value as smallest
+ cmp Value4
bcc +
ldx #3 ; value 4 is smaller, set 4th value as smallest
+ lda CallFunctionTable_hi,x
pha
lda CallFunctionTable_lo,x
pha
rts
CallFunctioTable_hi
.byte >(Val1Smallest-1), >(Val2Smallest-1), >(Val3Smallest-1), >(Val4Smallest-1)
CallFunctionTable_lo
.byte <(Val1Smallest-1), <(Val2Smallest-1), <(Val3Smallest-1), <(Val4Smallest-1)