First it appears the aliasing has to be done separately for each procedure
Yes, each procedure would have it's own variable names. That isn't what you would expect?
It's not quite clear where the actual work gets done, though.
I thought you would get the point that this is just an example but I went ahead and added some ellipses (...) to show where other work would be done. Does that make it clearer for you now?
Unless the commenting is for our benefit, not yours.
The commenting is for you. Maybe this is more readable:
.proc main
;Passing arguments
SetArg x1, x2, y1, y2
SetDbl #SCREEN_ADDRESS, color
JSR DrawLine
...
.endproc
.proc DrawLine
;Declaring variables
AliasOnly x1, x2, y1, y2, x_pos, y_pos, scr_ptr, ,color,
;Fetching arguments
GetArg x1, x2, y1, y2
GetDbl scr_ptr, color
...
;Passing arguments
SetArg x_pos, y_pos
SetDbl color, scr_ptr
JSR DrawPixel
...
Ret
.proc
.proc DrawPixel
;Push registers and declare variables
AliasPush calculated_address,,counter
;Get references to passed arguments
GetArgRef x_pos, y_pos
GetDblRef scr_ptr, color
...
Ret
.endproc
But in that case it might be better to show us the definitions of the macros
They are fairly trivial, which is why I just commented the code, but here you go if you would like to see:
;Push the S registers used in subroutines and
;assign aliases(identifiers) to them
.macro AliasPush v0,v1,v2,v3,v4,v5,v6,v7
PHA
PHX
PHY
;X counts how many bytes were pushed
LDX #$00
.if (.paramcount>0)
.ifnblank v0
v0=S0
.endif
LDA S0
PHA
;Increment X because one byte pushed
INX
.endif
...
.if (.paramcount>7)
.ifnblank v7
v7=S7
.endif
LDA S7
PHA
INX
.endif
;Push the count of bytes pushed so Ret macro can pop them
PHX
.endmacro
;Assign aliases to S registers used in subroutines
.macro AliasOnly v0,v1,v2,v3,v4,v5,v6,v7
PHA
PHX
PHY
.ifnblank v0
v0=S0
.endif
...
.ifnblank v7
v7=S7
.endif
;Push a zero to the stack so that the Ret macro does not try
;to pop any registers, since we didn't push any
LDA #$00
PHA
.endmacro
;Restore S register pushed by AliasPush
;Also restores A, X, and Y
.macro Ret
.local Loop
.local Done
;Get the count of registers to pop. Y will be counter.
PLY
Loop:
;Stop looping when no registers left
BEQ Done
DEY
;Pop register
PLA
STA S0,Y
CPY #$00
BNE Loop
Done:
PLY
PLX
PLA
RTS
.endmacro
;Copy values into A registers used for passing 1-byte arguments
.macro SetArg v0,v1,v2,v3,v4,v5,v6,v7
;Save a copy of A
PHA
;Transfer v0 to A0 (argument register)
.ifnblank v0
LDA v0
STA A0
.endif
...
.ifnblank v7
LDA v7
STA A7
.endif
;Restore A to what it was before macro
PLA
.endmacro
;Copy values into D registers used for passing 2-byte arguments
.macro SetDbl v0,v1,v2,v3
;Save a copy of A
PHA
.ifnblank v0
;If v0 is an immediate
.if (.match(.left(1,{v0}),#))
;Store the low byte of v0 in D0(2 byte argument register)
LDA #<(.right(.tcount({v0})-1,{v0}))
STA D0
;Store the high byte of v0 in D0+1
LDA #>(.right(.tcount({v0})-1,{v0}))
STA D0+1
;else, v0 is not an immediate
.else
LDA v0
STA D0
LDA v0+1
STA D0+1
.endif
.endif
...
.ifnblank v3
.if (.match(.left(1,{v3}),#))
LDA #<(.right(.tcount({v3})-1,{v3}))
STA D3
LDA #>(.right(.tcount({v3})-1,{v3}))
STA D3+1
.else
LDA v3
STA D3
LDA v3+1
STA D3+1
.endif
.endif
;Restore A to what it was before macro
PLA
.endmacro
;Assign variable names to the argument registers directly.
;This is faster than pushing S registers and copying A registers
.macro GetArgRef v0,v1,v2,v3,v4,v5,v6,v7
.ifnblank v0
v0=A0
.endif
...
.ifnblank v7
v7=A7
.endif
.endmacro
;Copy argument registers to pre-existing variables
.macro GetArg v0,v1,v2,v3,v4,v5,v6,v7
.ifnblank v0
LDA A0
STA v0
.endif
...
.ifnblank v7
LDA A7
STA v7
.endif
.endmacro
;Assign variable names to the argument registers directly.
;This is faster than pushing S registers and copying D registers
.macro GetDblRef v0,v1,v2,v3
.ifnblank v0
v0=D0
.endif
...
.ifnblank v3
v3=D3
.endif
.endmacro
;Copy argument registers to pre-existing variables
.macro GetDbl v0,v1,v2,v3
.ifnblank v0
LDA D0
STA v0
LDA D0+1
STA v0+1
.endif
...
.ifnblank v3
LDA D3
STA v3
LDA D3+1
STA v3+1
.endif
.endmacro
These ellipses also stand for code that I left out on purpose. I hope that is not confusing for you.
In general, I was hoping to hear what you guys think of this as a concept to organize memory. Do you do something similar with macros or do you have a better system?
EDIT: Formatting