OK, I believe these are the final macros for creating scratchpad variables (please don't mind my long macro names):
Code: Select all
;Starts a new block of scratchpad variables.
.macro Assembler_StartScratchpadVariables Offset
.pushseg ;save the current segment
.segment "SCRATCHPAD_RAM_BLOCKS" ;switch to a large dummy segment
.align $20 ;move on to the next block
: ;mark the start with a label
.ifnblank Offset
.res Offset ;skip the requested amount of bytes
.endif
.endmacro
When calling this macro you can provide an offset, which is the number of bytes to skip before starting the new variables. This offset must be a constant number, which can be written manually or automatically generated from a previous scratchpad declaration.
Code: Select all
;Declares a scratchpad variable in the current block.
.macro Assembler_DeclareScratchpadVariable VariableName, VariableSize
.ident(.string(VariableName)) = Assembler_Scratchpad + <(* - :-) ;create the address by adding the base address to the offset from the start of the block
.res VariableSize ;advance the amount of bytes used by the variable
.endmacro
"Assembler_Scratchpad" is a label in regular zero page, where 32 bytes are reserved.
Code: Select all
;Ends the current block of scratchpad variables.
.macro Assembler_EndScratchpadVariables Offset
.ifnblank Offset
.ident(.string(Offset)) = <(* - :-) ;save the current offset in the specified symbol
.endif
.popseg ;restore the previous segment
.endmacro
When ending the declaration you can optionally save the current offset in a symbol, which you can use in a later declaration to have that block placed after this one.
Here's how the macros are used:
Code: Select all
Assembler_StartScratchpadVariables
Assembler_DeclareScratchpadVariable Scratch0, 2
Assembler_DeclareScratchpadVariable Scratch1, 2
Assembler_EndScratchpadVariables
Assembler_StartScratchpadVariables
Assembler_DeclareScratchpadVariable Scratch2, 3
Assembler_DeclareScratchpadVariable Scratch3, 1
Assembler_DeclareScratchpadVariable Scratch4, 2
Assembler_EndScratchpadVariables ScratchBlock0Size
Assembler_StartScratchpadVariables ScratchBlock0Size
Assembler_DeclareScratchpadVariable Scratch5, 2
Assembler_DeclareScratchpadVariable Scratch6, 1
Assembler_EndScratchpadVariables
The final addresses will be:
Scratch0: $00
Scratch1: $02
Scratch2: $00
Scratch3: $03
Scratch4: $04
Scratch5: $06
Scratch6: $08
You have to admit, this is a pretty good alternative to manually typing offsets, and you end up with the exact same kinds of labels, so you don't even need any special tricks for using these variables once they're declared.
I'm now working on a similar set of macros to deal with the reusable general RAM areas.
EDIT: Now that I think of it, the .align is probably unnecessary, since the offsets are calculated with subtractions. If that's the case, I might even be able to use the same dummy segment for scratchpad variables and for general RAM, since it's basically a space I can fill linearly.