I'm sure the answer is "you can't decrement like that".
refWhen incrementing multiple-byte values you can do the obvious:
INX:BNE done
INY
.done
But decrementing doesn't work that way. The following does not work:
.loop
; do something with YX
DEX:BNE skip
DEY
.skip
BNE loop
Picture what happens at the boundary case. We'll start at $0402:
Code:
Y X
04 02
.loop
YX=$0402
04 02 DEX
04 01 BNE skip
.skip
04 01 BNE loop
.loop
YX=$0401
04 01 DEX
04 00 BNE skip
04 00 DEY
.skip
03 00 BNE loop
.loop
YX=$0300
03 00 DEX
03 FF BNE skip
.skip
03 FF BNE loop
.loop
YX=$03FF
03 FF DEX
03 FF BNE skip
Have you seen it? The counter goes 0402, 0401, 0300, 03FF. It "rolls over" when you go from 1 to 0 instead of when going from 0 past the end and back around to FF.
In loop you need to test that you've wrapped. When incrementing you get that from the increment, going from FF to 00 is the wrap, and going from FF to 00 sets the zero flag.
When decrementing you wrap when going from 00 to FF. There is no flag set when going from 00 to FF and only then. M is set, but also for every other decrement until you get to 7F. NE is set, but also for every other decrement until you get back to 0.
You know you are going to wrap when the *existing* value is zero, not the *changed* value. So you need to test *before* you change the value, not afterwards.
What you need to do is:
.loop
; do something
TXA:BNE skip :\ Skip if low byte not about to wrap from &00 to &FF
DEY :\ Decrement high byte
.skip
DEX :\ Decrement low byte
BNE loop
TYA:BNE loop
This gives:
Code:
Y X A
04 02 ??
.loop
YX=$0402
04 02 02 TXA
04 02 02 BNE skip
.skip
04 02 02 DEX
04 01 02 BNE loop
.loop
YX=$0401
04 01 02 TAX
04 01 01 BNE skip
.skip
04 01 01 DEX
04 00 01 BNE loop
04 00 01 TYA
04 00 04 BNE loop
.loop
YX=$0400
04 00 04 TXA
04 00 00 BNE skip
04 00 00 DEY
.skip
03 00 00 DEX
03 FF 00 BNE loop
.loop
YX=$03FF
03 FF 00 TXA
03 FF FF BNE skip
.skip
03 FF FF DEX
03 FE FF BNE loop
.loop
YX=$03FE