6502 Shorts - Range test. By Lee Davison
[Back]
Sometimes you need to check if a byte is in a certain range that does not start, or end, on the byte limits. For example, if a byte is numeric (n = '0', m = '9') or lower case ASCII (n = 'a', m = 'z').The code.
For all of these we assume that the byte to be tested is in A and that the start and end values, n and m, are already defined. Also that 0 < n < m < $FF.If you don't need to preserve the byte in A then testing the byte can be done in five bytes and only six cycles. This sets the carry if A is in the range n to m.
CLC ; clear carry for add ADC #$FF-m ; make m = $FF ADC #m-n+1 ; carry set if in range n to mIf you want the carry clear instead of set you use subtract instead of add.
SEC ; set carry for subtract SBC #n ; make n = $00 SBC #m-n+1 ; carry clear if in range n to mIf you need to preserve A and have either the X or Y register free you can do it like this.
TAX ; copy A (or TAY) CLC ; clear carry for add ADC #$FF-m ; make m = $FF ADC #m-n+1 ; carry set if in range n to m TXA ; restore A (or TYA)If you can spare the cycles but not the registers then this is the slowest of the range tests comming in at thirteen cycles.
PHA ; save A CLC ; clear carry for add ADC #$FF-m ; make m = $FF ADC #m-n+1 ; carry set if in range n to m PLA ; restore AFinally a method that preserves A without using any other registers, or memory. This has the disadvantage that it can take either five or ten cycles (so timing would be unsure) and takes the most bytes. This one sets the carry if A is in the range n to m.
CMP #n ; is it less than required? BCC ERnge ; branch if it is ADC #$FE-m ; add $FF-m (carry is set) CLC ; clear carry for add ADC #m+1 ; A is now back to original value ERngeAnd this one clears the carry if A is in the range n to m.
CMP #m+1 ; is it greater than required? BCS ERnge ; branch if it is SBC #n-1 ; subtract n (carry is clear) SEC ; set carry for subtract SBC #-n ; A is now back to original value ERnge