Quote:
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?
Quote:
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?
Quote:
Unless the commenting is for our benefit, not yours.
The commenting is for you. Maybe this is more readable:
.proc main
;Passing argumentsSetArg x1, x2, y1, y2
SetDbl #SCREEN_ADDRESS, color
JSR DrawLine
...
.endproc
.proc DrawLine
;Declaring variablesAliasOnly x1, x2, y1, y2, x_pos, y_pos, scr_ptr, ,color,
;Fetching argumentsGetArg x1, x2, y1, y2
GetDbl scr_ptr, color
...
;Passing argumentsSetArg x_pos, y_pos
SetDbl color, scr_ptr
JSR DrawPixel
...
Ret
.proc
.proc DrawPixel
;Push registers and declare variablesAliasPush calculated_address,,counter
;Get references to passed argumentsGetArgRef x_pos, y_pos
GetDblRef scr_ptr, color
...
Ret
.endproc
Quote:
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