Code: Select all
my first
LDA/STA zp : 3c x 4 = 12c 2b x 4 = 8
ORA # : 2c x 2 = 4c 2b x 2 = 4
ROL A : 2c x 4 = 8c 1b x 4 = 4
ASL/ROL zp : 5c x 9 = 45c 2b x 9 = 18
69 cycles, 34 bytes
vs (your first)
lda/sta zp : 4 x 6 = 24 2b x 6 = 12
pha/pla : 2 x 4 = 8 1b x 4 = 4
ROR/LSR A : 2 x 9 = 18 1b x 9 = 9
AND/ORA #i : 2 x 6 = 12 2b x 6 = 12
AND/ORA zp : 3 x 2 = 6 2b x 2 = 4
68 cycles, 41 bytes (66/40 rotating faster)
vs (your second)
LDA/STA zp: 4c x 7 = 28c 2b x 7 = 14b
LSR/ROR A : 2c x 4 = 8c 1b x 4 = 4b
ROR/LSR zp: 5c x 2 = 10c 2b x 2 = 4b
AND/OR #i : 2c x 5 = 10c 2b x 5 = 10b
ORA zp : 3c x 1 = 3c 2b x 1 = 2b
59 cycles, 34 bytes
Absolute commands are a byte and cycle bigger than zp: (47b,82c) vs (48b,74c) vs (44b,69c)
making your [first] code better in both metrics.
(pre-post edit:)
(34b 52c) -> 42b 62c for non-zp
(32b 49c) -> 37b 54c if our address is not zp. (like t wouldn't be.)
rainwarrior wrote:
Pardon me coding out loud. I'm just enjoying the exercise.
Certainly.
(Simple optimization to your first: ASL A x 4 instead of ROL A x 5 ,since you're already ANDing off unused bits, and you don't have to put everything through the carry.)
tokumaru wrote:What I do is convert a set of coordinates (9-bit X, 9-bit Y) into NT and AT addresses
An efficient way to do that would be just as pertinent here...though one wonders why 9-bit and not 6 if we're dealing with tiles. (self-reply: Sprites vs BG, duh.) Of course, that makes the NT address 0010 YXyy yyyx xxxx, a bit annoying... (that is, Y8, X8, Y7-3, X7-3)
rainwarrior wrote:Do you need to do this more than once per frame? What is use case that your original post wasn't efficient enough for?
I was mainly curious if people had code-golfed it down to a gold-standard, since it seemed like a thing that every program ever needed to do. (Though on reflection I suppose one only needs to do it once per strip pushed to the PPU, breaking strips on nametable boundaries...)
My code is still in the theory stage. >>; I suspect going further would be prudent before we get too engaged in Virtua Code Golf.
Code: Select all
convert-coord-to-NT:
LDA $obj-hiY
ASL A
ORA $obj-hiX ;maybe store hiXY together and use BCC+XOR to change each
; to avoid carry issues?
;Nah, makes collision sizes other than 'equality' hard.
ORA #$08
STA $high-addr
LDA $obj-loY
ASL A
ROL $high-addr
ASL A
ROL $high-addr
AND $E0
STA $low-addr
LDA $obj-loX
LSR LSR LSR
ORA $low-addr
STA $low-addr
convert-coord-to-AT:
LDA $obj-hiY ;though I suspect these might get ,x
ASL A
ORA $obj-hiX
ASL A ASL A
ORA #$23
STA $high-addr
LDA $obj-loX
ASL A
ROL $low-addr
ASL A
ROL $low-addr
ASL A
ROL $low-addr
LDA #7
AND $low-addr
STA $low-addr
LDA $obj-loY
AND #$E0
LSR LSR
ORA #$C0
ORA $low-addr
STA $low-addr
rainwarrior wrote:(palette-index too)
But shouldn't p be getting L7 L1? The LSB of X/Y (L6, L0) for tiles is ignored within the same 16x16 palette block. L7/L1 select which pair of bits you need to set for that 16x16.