You know Baramos it was a great idea to revive this thread.
How many times I've had to do something like
pha
and #$xx
...blah blah
pla
...blah blah
when the BIT instruction would have been better but couldn't be used because there is no BIT immediate !
Without going as far as having a 256 byte identity table, simply use .db with the constant you need (this is a single byte table...)
Since you'd usually do the bit instruction with only a single bit set, and that bit 7 can be directly tested with the N flag, a 7-byte table should be enough for anything (in fact only 6 will be necessary - I'll explain below) :
.db $01, $02, $04, $08, $10, $20, $40
Also I've found another trick which is so simple but worth mentionning. If you load a value in A, the only bit you can "quickly" test is the 7th one, with the N flag.
But if you use the ASL A instruction then you can "quickly" then C=7th bit and N=6th bit, so you can quickly test 2 bits without using AND or BIT instructions ! Pretty useful !
Another very simple, but clever thing is to keep that in mind : If you made a subroutine that you're only going to call once in your code, then replace it by a macro. You'll save a 6 cycles and 4 bytes (assuming there were no branch instructions around the call). This make the code as structured as if it was a subroutine and you can always change back to a subroutine if you are going to call it somewhere else.
Finally, how many times you call a subroutine and you need more than 3 bytes of arguments ? (more than what A, X and Y can handle) ?
Well the solution to that comes from SMB disassembly...
Code: Select all
jsr MyRoutine
.dw Pointer1, Pointer2 ;4 bytes arguments
MyRoutine
jsr GetArguments
.....
rts
GetArguments
tsx
lda $103,X ;Get return adress from the stack
sta PtrL
clc
adc #$04 ;Add 4 to return adress
sta $103,X
lda $104,X
sta PtrH
adc #$00
sta $104,X
ldy #$04 ;Copy arguments to Temp variables
- lda [Ptr],Y ;We should not forget the adress in the stack is return adress -1 !
sta Temp-1,Y
dey
bne -
rts
Sure the GetArgument routine can be pretty long and bit, but in the end, it will save you possibly hundred of times to do something like :
Code: Select all
lda #BlahBlah
sta Temp
lda #BlahBlah
ldy #BlahBlah
ldx #Blah
jsr Routine
So this saves aproximately 6 bytes for each call, with can end up a lot if this is done frequently.
My GetArguments routine is 32 bytes, so if you use this trick more than 10 or so times it's definitely a gain.
However you can't use variable arguments unless you place your code in RAM (which ends up being unpractical on the NES as you'll have to copy it here).
I wonder if there is any way to improve this argument thing to save even more bytes, I have some feeling that it is possible.
Useless, lumbering half-wits don't scare us.