I have a kernel in my 6502 game that writes two dots to a sprite, so for example:
........
........
.XX..XX.
.XX..XX.
........
........
Either 0, 1, or 2 dots can be on at a time. This is done one scanline at a time, so we're only looking at how to write the middle two lines.
So far I've implemented this by doing the following:
- The accumulator is set to 0b01100000
- X is set to 0b00000110
- For the left dot, I use
STA $1B
(3 cycles) to only turn that dot on. - For the right dot, I use
STX $1B
(3 cycles) to turn that dot on. - For both dots, I can use the undocumented instruction SAX ($87) to write A | X to the value, so
SAX $1B
(3 cycles) to turn both on.
But if I need to turn both dots off, the quickest way I know of to write 0b00000000 to a register is to store $00 in Y and then write it. Of course, this means I can't use Y for other purposes in my code.
I don't need a trick that takes 3 cycles (4 or 5 are fine) but are there any possibilities, without consuming a register, to write 0x00 to a memory location in zero page on the 6502?
EDIT: The above description of the problem is incorrect (see comments). I actually set A=01100000, X=00000110, Y=01100110, and use SAX to write $00. The question as posed (writing 0x00 to a register without storing 0x00 in a register) is still answered in the replies.
SAX
not writing zero? The values you say are inA
andX
have no set bits in common. – Tommy Jul 9 '18 at 2:13STZ
, store zero, which would have been perfect here. – Tommy Jul 9 '18 at 13:30SAX
writes the and, not the or. E.g. oxyron.de/html/opcodes02.html or, to quote nesdev.com/6502_cpu.txt : "Many undocumented commands do not use AND between registers, the CPU just throws the bytes to a bus simultaneously and lets the open-collector drivers perform the AND. I.e. the command called 'SAX', which is in the STORE section (opcodes $A0...$BF), stores the result of (A & X) by this way." (though that should be e.g. not i.e.) – Tommy Jul 9 '18 at 13:32