In my opinion it makes more sense to have a subroutine that writes strings rather than a macro, but both should work. The code you posted takes around 18 bytes, which means that for each string you print you are wasting 18 bytes (in the case of a small string like "hello word" the printing code is larger than the string itself!). As a subroutine the code would be a bit larger (because you'd have to process the arguments), but the same code would be used for ALL strings.Bellum wrote:or should I be using jumping to a "subroutine" instead?
Obligatory newbie questions
Moderator: Moderators
Woo, it worked! Sort of. The second time it looped infinitely for some reason and started storing garbage, so I'll have to work that out.

That makes a lot of sense. What sort of thing would macros be better used for?tokumaru wrote:In my opinion it makes more sense to have a subroutine that writes strings rather than a macro, but both should work. The code you posted takes around 18 bytes, which means that for each string you print you are wasting 18 bytes (in the case of a small string like "hello word" the printing code is larger than the string itself!). As a subroutine the code would be a bit larger (because you'd have to process the arguments), but the same code would be used for ALL strings.Bellum wrote:or should I be using jumping to a "subroutine" instead?
Hum... the most obvious I can think of are 16-bit math operations, because we need them often and they are so small that a subroutine would offer little (if any) gain of ROM space and would be much slower. Another thing I can think of are mapper writes, if they are short enough.Bellum wrote:What sort of thing would macros be better used for?
I don't see much sense in having large macros, unless they are meant to be used across different programs. If a piece of code is reasonably large and you have to use it in several places of the same program, it makes more sense to use a subroutine.
Macros are needed when speed is imporant. Say, you have code like this:
If there is not much code in the loop and the subroutine, you can spend much time on jsr/rts. If you replace the subroutine with a macro, you'll save this time. It could be important for VRAM update code, when you have to fit many things into ~2200 CPU clocks, for example. One subroutine call is 12 extra clocks, one macro usage is 0 extra clocks, in exchange for larger code size.
Code: Select all
loop
jsr a short subroutine
..
jsr a short subroutine again
..
go loop
Go here: http://www.obelisk.demon.co.uk/6502/reference.htmlBellum wrote: Are JMP statements particularly slow?
It has the cycle counts for every instruction. jmp is fairly fast at 3 cycles. The fastest instructions take 2 cycles. The slowest instructions take 7.
Both jsr and rts are 6 cycles which means every normal subroutine call* will take at least 12 cycles.
For reference, I believe an NTSC NES' frame is 29830 CPU cycles long.
*i.e. one that doesn't pull the rts location from the stack and return some different way or something crazy.
Of course, a macro can also be handy to set things up for the JSR, with less typing.
And I use one like this all the time:
Using macros inside of macros can be fun too.
more examples of what I thought macros were useful for, in general use:
http://www.parodius.com/~memblers/nes/macros.s
(the controller one is probably my favorite for making my programs readable)
Code: Select all
.macro writestring addr
lda #<addr
sta vram_addr_lo
lda #>addr
sta vram_addr_hi
jsr string
.endmacro
Code: Select all
.macro pointer addr1_zp,addr2
lda #<addr2
sta addr1_zp
lda #>addr2
sta addr1_zp+1
.endmacro

Code: Select all
.macro writestring addr
pointer vram_addr_lo,addr
jsr string
.endmacro
http://www.parodius.com/~memblers/nes/macros.s
(the controller one is probably my favorite for making my programs readable)
JMP (3 cycles) isn't slow, but JSR (6 cycles) is. JMP is not used for subroutines, because it doesn't save the return address. JSR saves the return address, so that you can RTS (also takes 6 cycles) when the subroutine is done. Since it takes 12 cycles to get in and out of a subroutine, it doesn't make sense to use one for very small and quick tasks.Bellum wrote:Are JMP statements particularly slow?