Subject: Re[3]: [stella] signed 8-bit comparisons? From: zu03776 <zu03776@xxxxxxxxxxxxxxxxxx> Date: Fri, 5 Mar 2004 02:14:40 -0600 |
I did some experiments, conclusion in the last three to six paragraphs. :) I included my thought process so that others could double-check. >> Hi there, >> >> > I think what you want is: >> > LDA var >> > CMP #MAX >> > BMI ltMAX >> > LDA #MAX >> > ltMAX >> > CMP #MIN >> > BPL gtMIN >> > LDA #MIN >> > gtMIN >> > STA var >> >> Wouldn't it be better to use bcc and bcs instead of bmi and bpl? Kac> If I'm reading Kac> http://www.6502.org/tutorials/compare_instructions.html Kac> correctly, bcc/bcs vs bmi/bpl is the whole point of my Kac> question and Eric's response: bcc/bcs work if you're Kac> treating your 8-bits as an unsigned byte, but if you Kac> want your %11111111 to come across as LESS than your Kac> %00000001, (ala 2's complement) then the code above is Kac> correct. For a full treatment of the 6502 flags, may I suggest Chapter 3 of the wonderful book "Machine Language for the Commodore 64 and other Commodore Computers", written by Jim Butterfield. Original site: http://www.devili.iki.fi/library/publication/51.en.html ZIP Archive Mirror: http://tripoint.org/wizard/ml4c64.zip Search the text for "Z Flag" and you're in the right place. A quick flag summary: when used in comparisons: the Z flag should be called the E flag (for "equals"), the C flag should be called the GE flag ("greater than or equal"), the N flag should be called the HB flag ("high bit"), and the V flag should be called the SAO flag ("signed arithmetic overflow"). It's real hard to set the V flag: the only instructions that do so are ADC, SBC, and BIT. Note the lack of CMP, CPX, and CPY. To test how the flags get set, I assumed worst case signed scenarios. The desired limits are -64 to +64; the current value is -128 or +127. (That's limits of $c1 to $3f, values of $80 or $7f.) N Unsigned Signed Intrepretation LDA #$80 CMP #$C1 Flags B0 (N v z c) 128 < 197 -128 < -63 (OK) LDA #$80 CMP #$3F Flags 31 (n v z C) 128 > 63 -128 > 63 (??) LDA #$FF CMP #$C1 Flags 31 (n v z C) 255 > 197 -1 > -63 (OK) LDA #$FF CMP #$3F Flags B1 (N v z C) 255 < 63 ? -1 < 63 (OK) LDA #$01 CMP #$C1 Flags 30 (n v z c) 1 > 197 ? 1 > -63 (OK) LDA #$01 CMP #$3F Flags B0 (N v z c) 1 < 63 1 < 63 (OK) LDA #$7F CMP #$C1 Flags B0 (N v z c) 127 < 197 127 < -63 (??) LDA #$7F CMP #$3F Flags 31 (n v z C) 127 > 63 127 > 63 (OK) The N flag for unsigned numbers isn't correct in two cases -- comparing the small negative value (#$ff) to the positive value (#$3f) should be positive; comparing the small positive value (#$01) to the negative value (#$c1) should be negative. When comparing unsigned numbers, the carry flag is the correct flag to use (BCC, BCS). By similar reasoning, the N flag for signed numbers isn't correct in two cases -- comparing the large negative value (#$80) to the positive value (#$3f) should be negative; comparing the large positive value (#$7f) to the negative value (#$c1) should be positive. However, the carry flag is a worse candidate for correct flag, as it is wrong half the cases. Hmm... Let's try subtraction... (with SEC first) Signed Intrepretation LDA #$80 SBC #$C1 Flags B0 (N v z c) -128 < -63 (out) LDA #$80 SBC #$3F Flags 71 (n V z C) signed overflow (in) LDA #$FF SBC #$C1 Flags 31 (n v z C) -1 > -63 (in) LDA #$FF SBC #$3F Flags B1 (N v z C) -1 < 63 (in) LDA #$01 SBC #$C1 Flags 30 (n v z c) 1 > -63 (in) LDA #$01 SBC #$3F Flags B0 (N v z c) 1 < 63 (in) LDA #$7F SBC #$C1 Flags F0 (N V z c) signed overflow (in) LDA #$7F SBC #$3F Flags 31 (n v z C) 127 > 63 (out) This looks more promising.... In the cases where a signed overflow occurs, the N flag is incorrect. Where A is a large negative, subtracting the positive maximum value and overflowing indicates A is less than the maximum. Where A is a large positive, subtracting the negative minimum value and overflowing indicates A is greater than the minimum. Therefore, on an overflow comparing the numeric values, the value need not be modified. A similar set of overflow problems occurs when adding signed numbers. Exercise left to the reader. :) How does this apply to your problem? I'm working on that... :) If A is -4, and the lower limit is -3, having a negative result when subtracting the negative lower limit (adding a positive) from the value indicates the value is out of range (N flag set). However, if the A value is sufficiently positive (say, $7D), subtracting -3 from the number (add 3) wraps A to the negative side ($80 or -128), and sets the negative flag and the overflow flag. But, the original value was positive (way larger than the lower limit), so a set overflow flag indicates to ignore the (set) negative flag. If A is 4, and the upper limit is 3, having a positive result when subtracting the upper limit from the value is bad (N flag reset). However, if A is sufficiently negative (say, $82), subtracting 3 makes the result positive ($7F or 127), resets the N flag and sets the overflow flag. However, the original value was way below the upper limit specified, so a set overflow flag indicates to ignore the reset negative flag. So, if you're sure that your _signed negative current value_ minus your _signed negative limit value_ will never be less than -128, just checking sign results (N) will work. Otherwise, you will need to add an overflow branch check to ignore the negative branch check. Same thing for _signed positive current value_ plus your _signed positive limit value_ never exceeding 127. If it could, add an overflow branch to ignore the positive branch check. value .byte chkrg LDA value SEC SBC #$MIN BVS skpmn BPL skpmn LDA #$MIN STA value skpmn LDA value SEC SBC #$MAX BVS skpmx BMI skpmx LDA #$MAX skpmx STA value Too too long to sort though that one. It still reads somewhat somewhat confusingly. So, where is this wrong? I hope it's not at first premise. :> ---------------------------------------------------------------------------------------------- Archives (includes files) at http://www.biglist.com/lists/stella/archives/ Unsub & more at http://www.biglist.com/lists/stella/
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [stella] signed 8-bit compariso, Bill Heineman | Thread | Re: Re[3]: [stella] signed 8-bit co, KirkIsrael |
Re: [stella] signed 8-bit compariso, Bill Heineman | Date | Re: Re[3]: [stella] signed 8-bit co, KirkIsrael |
Month |