Using Word values and subtraction for ON ... GOTO statements
Zoot
Posts: 2,227
Following a lot of Dr. Tracy Allen's recommendations, I've become a huge fan of using ON ... GOTO to test for zero instead of byte-hungry if/thens.
I found one case in a complex set of code where I spent all evening tracking down a bug. Here is where it came into play....
buffer -- a Word variable
scratch -- a Word variable
I want to skip some code if they are both equal. Following my own practices elsewhere, I did this:
ON buffer - scratch GOTO SomeLabel
Which fails. This of course, works:
IF buffer = scratch THEN SomeLabel
Anywhere else I use something like ON x - y GOTO label, it's fine but usually I'm testing with byte or bit values, not words. I figured it would work anyway because the result will either be 0 or not.
The only thing I can think of that would give me unexpected results is that ON..GO is limited to 255 items, which means I think that ON..GO only looks at the lowbyte? Which means in theory when subtracting two word values as above it would be possible to get at an undesired result in the lowbyte even though they are not equal.
So, I did this:
ON buffer - scratch MAX 1 GOTO SomeLabel
Which works. But I wanted to know if the reason it works is why it really does work.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
I found one case in a complex set of code where I spent all evening tracking down a bug. Here is where it came into play....
buffer -- a Word variable
scratch -- a Word variable
I want to skip some code if they are both equal. Following my own practices elsewhere, I did this:
ON buffer - scratch GOTO SomeLabel
Which fails. This of course, works:
IF buffer = scratch THEN SomeLabel
Anywhere else I use something like ON x - y GOTO label, it's fine but usually I'm testing with byte or bit values, not words. I figured it would work anyway because the result will either be 0 or not.
The only thing I can think of that would give me unexpected results is that ON..GO is limited to 255 items, which means I think that ON..GO only looks at the lowbyte? Which means in theory when subtracting two word values as above it would be possible to get at an undesired result in the lowbyte even though they are not equal.
So, I did this:
ON buffer - scratch MAX 1 GOTO SomeLabel
Which works. But I wanted to know if the reason it works is why it really does work.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
I would think since the Pbasic manual states that ON, LOOKUP, etc, are limited to tables of 256 elements, that the interpreter would have to throw *something* away when presented with a 16bit value as an index for accessing elements. I would think the interpreter would just use the lowbyte of the 16bit space, which would make the most sense. And it seems like the other operations that use less than 16bits work the same way (the unneeded higher bits are just discarded). Like your recent tip on on using READ with addresses of $800 or higher.
Actually, I just realized I must have been *really* tired last night.... simple case would be:
buffer = $F202
scratch = $F302
scratch - buffer = $0100
Which would give you $00 in the lowbyte and a goto on zero? even though they are not equal (highbyte = $01). In fact, I think it was cases just like this where my general program was failing -- cases where the lowbytes matched but the highbytes were different, or where the exact math in a given comparison yielded a result of 0 in the lowbyte. Just a guess, though.
I'll try this out later tonight when I get a chance.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST
Post Edited (Zoot) : 3/24/2007 7:37:24 PM GMT
Here's my code:
I plugged in different combinations of seed word values for kicks and grins. I consistently got back 0 for the index whenever the lowbyte of the result was 0, regardless of the highbyte.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When the going gets weird, the weird turn pro. -- HST