-; smc.mac\r
-; ca65 Macro-Pack for Self Modifying Code (SMC)\r
-;\r
-; (c) Christian Krüger, latest change: 17-Jul-2016\r
-;\r
-; This software is provided 'as-is', without any expressed or implied\r
-; warranty. In no event will the authors be held liable for any damages\r
-; arising from the use of this software.\r
-;\r
-; Permission is granted to anyone to use this software for any purpose,\r
-; including commercial applications, and to alter it and redistribute it\r
-; freely, subject to the following restrictions:\r
-;\r
-; 1. The origin of this software must not be misrepresented; you must not\r
-; claim that you wrote the original software. If you use this software\r
-; in a product, an acknowledgment in the product documentation would be\r
-; appreciated but is not required.\r
-; 2. Altered source versions must be plainly marked as such, and must not\r
-; be misrepresented as being the original software.\r
-; 3. This notice may not be removed or altered from any source\r
-; distribution.\r
-;\r
-\r
-.define _SMCDesignator .mid(0, .tcount(label) - 1, label) .ident(.concat(.string(.right(1, label)), "_SMC"))\r
-.define _SMCAlias .mid(0, .tcount(alias) - 1, alias) .ident(.concat(.string(.right(1, alias)), "_SMC"))\r
-.define SMC_AbsAdr $FADE\r
-.define SMC_ZpAdr $00\r
-.define SMC_Opcode nop\r
-.define SMC_Value $42\r
-\r
-.macro SMC_OperateOnValue opcode, label\r
- opcode _SMCDesignator+1\r
-.endmacro\r
-\r
-.macro SMC_OperateOnLowByte opcode, label\r
- SMC_OperateOnValue opcode, label\r
-.endmacro\r
-\r
-.macro SMC_OperateOnHighByte opcode, label\r
- opcode _SMCDesignator + 2\r
-.endmacro\r
-\r
-.macro SMC_Import alias\r
-.import _SMCAlias\r
-.endmacro\r
-\r
-.macro SMC_Export alias, label\r
-.export _SMCAlias := _SMCDesignator\r
-.endmacro\r
-\r
-.macro SMC label, statement\r
-_SMCDesignator: statement\r
-.endmacro\r
-\r
-.macro SMC_TransferOpcode label, opcode, register\r
-.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )\r
- lda #opcode\r
- sta _SMCDesignator\r
-.elseif .match ({register}, x)\r
- ldx #opcode\r
- stx _SMCDesignator\r
-.elseif .match ({register}, y)\r
- ldy #opcode\r
- sty _SMCDesignator\r
-.else\r
- .error "Invalid usage of macro 'SMC_TransferOpcode'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_LoadOpcode label, register\r
-.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )\r
- lda _SMCDesignator\r
-.elseif .match ({register}, x)\r
- ldx _SMCDesignator\r
-.elseif .match ({register}, y)\r
- ldy _SMCDesignator\r
-.else\r
- .error "Invalid usage of macro 'SMC_TransferOpcode'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_StoreOpcode label, register\r
-.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )\r
- sta _SMCDesignator\r
-.elseif .match ({register}, x)\r
- stx _SMCDesignator\r
-.elseif .match ({register}, y)\r
- sty _SMCDesignator\r
-.else\r
- .error "Invalid usage of macro 'SMC_StoreOpcode'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_ChangeBranch label, destination, register\r
-.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )\r
- lda #(<(destination - _SMCDesignator -2))\r
- sta _SMCDesignator+1\r
-.elseif .match ({register}, x)\r
- ldx #(<(destination - _SMCDesignator - 2))\r
- stx _SMCDesignator+1\r
-.elseif .match ({register}, y)\r
- ldy #(<(destination - _SMCDesignator - 2))\r
- sty _SMCDesignator+1\r
-.else\r
- .error "Invalid usage of macro 'SMC_ChangeBranch'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_TransferValue label, value, register\r
-.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )\r
- lda value\r
- sta _SMCDesignator+1\r
-.elseif .match ({register}, x)\r
- ldx value\r
- stx _SMCDesignator+1\r
-.elseif .match ({register}, y)\r
- ldy value\r
- sty _SMCDesignator+1\r
-.else\r
- .error "Invalid usage of macro 'SMC_TransferValue'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_LoadValue label, register\r
-.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )\r
- lda _SMCDesignator+1\r
-.elseif .match ({register}, x)\r
- ldx _SMCDesignator+1\r
-.elseif .match ({register}, y)\r
- ldy _SMCDesignator+1\r
-.else\r
- .error "Invalid usage of macro 'SMC_LoadValue'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_StoreValue label, register\r
-.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )\r
- sta _SMCDesignator+1\r
-.elseif .match ({register}, x)\r
- stx _SMCDesignator+1\r
-.elseif .match ({register}, y)\r
- sty _SMCDesignator+1\r
-.else\r
- .error "Invalid usage of macro 'SMC_StoreValue'"\r
-.endif\r
-.endmacro\r
-\r
-\r
-.macro SMC_TransferLowByte label, value, register\r
-SMC_TransferValue label, value, register\r
-.endmacro\r
-\r
-.macro SMC_LoadLowByte label, register\r
-SMC_LoadValue label, register\r
-.endmacro\r
-\r
-.macro SMC_StoreLowByte label, register\r
-SMC_StoreValue label, register\r
-.endmacro\r
-\r
-.macro SMC_TransferHighByte label, value, register\r
-.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )\r
- lda value\r
- sta _SMCDesignator+2\r
-.elseif .match ({register}, x)\r
- ldx value\r
- stx _SMCDesignator+2\r
-.elseif .match ({register}, y)\r
- ldy value\r
- sty _SMCDesignator+2\r
-.else\r
- .error "Invalid usage of macro 'SMC_TransferHighByte'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_LoadHighByte label, register\r
-.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )\r
- lda _SMCDesignator+2\r
-.elseif .match ({register}, x)\r
- ldx _SMCDesignator+2\r
-.elseif .match ({register}, y)\r
- ldy _SMCDesignator+2\r
-.else\r
- .error "Invalid usage of macro 'SMC_LoadHighByte'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_StoreHighByte label, register\r
-.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )\r
- sta _SMCDesignator+2\r
-.elseif .match ({register}, x)\r
- stx _SMCDesignator+2\r
-.elseif .match ({register}, y)\r
- sty _SMCDesignator+2\r
-.else\r
- .error "Invalid usage of macro 'SMC_StoreHighByte'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_TransferAddressSingle label, address, register\r
-.if .paramcount = 2 .or .match ((register), a) .or .match ({register}, )\r
- .if (.match (.left (1, {address}), #))\r
- ; immediate mode\r
- lda #<(.right (.tcount ({address})-1, {address}))\r
- sta _SMCDesignator+1\r
- lda #>(.right (.tcount ({address})-1, {address}))\r
- sta _SMCDesignator+2\r
- .else\r
- ; assume absolute or zero page\r
- lda address\r
- sta _SMCDesignator+1\r
- lda 1+(address)\r
- sta _SMCDesignator+2\r
- .endif\r
-.elseif .match ((register), x)\r
- .if (.match (.left (1, {address}), #))\r
- ; immediate mode\r
- ldx #<(.right (.tcount ({address})-1, {address}))\r
- stx _SMCDesignator+1\r
- ldx #>(.right (.tcount ({address})-1, {address}))\r
- stx _SMCDesignator+2\r
- .else\r
- ; assume absolute or zero page\r
- ldx address\r
- stx _SMCDesignator+1\r
- ldx 1+(address)\r
- stx _SMCDesignator+2\r
- .endif\r
-.elseif .match ((register), y)\r
- .if (.match (.left (1, {address}), #))\r
- ; immediate mode\r
- ldy #<(.right (.tcount ({address})-1, {address}))\r
- sty _SMCDesignator+1\r
- ldy #>(.right (.tcount ({address})-1, {address}))\r
- sty _SMCDesignator+2\r
- .else\r
- ; assume absolute or zero page\r
- ldy address\r
- sty _SMCDesignator+1\r
- ldy 1+(address)\r
- sty _SMCDesignator+2\r
- .endif\r
-.else\r
- .error "Invalid usage of macro 'SMC_TransferAddressSingle'"\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_TransferAddress label, address\r
-.if (.match (.left (1, {address}), #))\r
- ; immediate mode\r
- lda #<(.right (.tcount ({address})-1, {address}))\r
- sta _SMCDesignator+1\r
- ldx #>(.right (.tcount ({address})-1, {address}))\r
- stx _SMCDesignator+2\r
-.else\r
- ; assume absolute or zero page\r
- lda {address}\r
- sta _SMCDesignator+1\r
- ldx 1+{address}\r
- stx _SMCDesignator)+2\r
-.endif\r
-.endmacro\r
-\r
-.macro SMC_StoreAddress label\r
- sta _SMCDesignator+1\r
- stx _SMCDesignator+2\r
-.endmacro\r
+; smc.mac
+; ca65 Macro-Pack for Self Modifying Code (SMC)
+;
+; (c) Christian Krüger, latest change: 17-Jul-2016
+;
+; This software is provided 'as-is', without any expressed or implied
+; warranty. In no event will the authors be held liable for any damages
+; arising from the use of this software.
+;
+; Permission is granted to anyone to use this software for any purpose,
+; including commercial applications, and to alter it and redistribute it
+; freely, subject to the following restrictions:
+;
+; 1. The origin of this software must not be misrepresented; you must not
+; claim that you wrote the original software. If you use this software
+; in a product, an acknowledgment in the product documentation would be
+; appreciated but is not required.
+; 2. Altered source versions must be plainly marked as such, and must not
+; be misrepresented as being the original software.
+; 3. This notice may not be removed or altered from any source
+; distribution.
+;
+
+.define _SMCDesignator .mid(0, .tcount(label) - 1, label) .ident(.concat(.string(.right(1, label)), "_SMC"))
+.define _SMCAlias .mid(0, .tcount(alias) - 1, alias) .ident(.concat(.string(.right(1, alias)), "_SMC"))
+.define SMC_AbsAdr $FADE
+.define SMC_ZpAdr $00
+.define SMC_Opcode nop
+.define SMC_Value $42
+
+.macro SMC_OperateOnValue opcode, label
+ opcode _SMCDesignator+1
+.endmacro
+
+.macro SMC_OperateOnLowByte opcode, label
+ SMC_OperateOnValue opcode, label
+.endmacro
+
+.macro SMC_OperateOnHighByte opcode, label
+ opcode _SMCDesignator + 2
+.endmacro
+
+.macro SMC_Import alias
+.import _SMCAlias
+.endmacro
+
+.macro SMC_Export alias, label
+.export _SMCAlias := _SMCDesignator
+.endmacro
+
+.macro SMC label, statement
+_SMCDesignator: statement
+.endmacro
+
+.macro SMC_TransferOpcode label, opcode, register
+.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
+ lda #opcode
+ sta _SMCDesignator
+.elseif .match ({register}, x)
+ ldx #opcode
+ stx _SMCDesignator
+.elseif .match ({register}, y)
+ ldy #opcode
+ sty _SMCDesignator
+.else
+ .error "Invalid usage of macro 'SMC_TransferOpcode'"
+.endif
+.endmacro
+
+.macro SMC_LoadOpcode label, register
+.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
+ lda _SMCDesignator
+.elseif .match ({register}, x)
+ ldx _SMCDesignator
+.elseif .match ({register}, y)
+ ldy _SMCDesignator
+.else
+ .error "Invalid usage of macro 'SMC_LoadOpcode'"
+.endif
+.endmacro
+
+.macro SMC_StoreOpcode label, register
+.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
+ sta _SMCDesignator
+.elseif .match ({register}, x)
+ stx _SMCDesignator
+.elseif .match ({register}, y)
+ sty _SMCDesignator
+.else
+ .error "Invalid usage of macro 'SMC_StoreOpcode'"
+.endif
+.endmacro
+
+.macro SMC_ChangeBranch label, destination, register
+.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
+ lda #(<(destination - _SMCDesignator -2))
+ sta _SMCDesignator+1
+.elseif .match ({register}, x)
+ ldx #(<(destination - _SMCDesignator - 2))
+ stx _SMCDesignator+1
+.elseif .match ({register}, y)
+ ldy #(<(destination - _SMCDesignator - 2))
+ sty _SMCDesignator+1
+.else
+ .error "Invalid usage of macro 'SMC_ChangeBranch'"
+.endif
+.endmacro
+
+.macro SMC_TransferValue label, value, register
+.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
+ lda value
+ sta _SMCDesignator+1
+.elseif .match ({register}, x)
+ ldx value
+ stx _SMCDesignator+1
+.elseif .match ({register}, y)
+ ldy value
+ sty _SMCDesignator+1
+.else
+ .error "Invalid usage of macro 'SMC_TransferValue'"
+.endif
+.endmacro
+
+.macro SMC_LoadValue label, register
+.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
+ lda _SMCDesignator+1
+.elseif .match ({register}, x)
+ ldx _SMCDesignator+1
+.elseif .match ({register}, y)
+ ldy _SMCDesignator+1
+.else
+ .error "Invalid usage of macro 'SMC_LoadValue'"
+.endif
+.endmacro
+
+.macro SMC_StoreValue label, register
+.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
+ sta _SMCDesignator+1
+.elseif .match ({register}, x)
+ stx _SMCDesignator+1
+.elseif .match ({register}, y)
+ sty _SMCDesignator+1
+.else
+ .error "Invalid usage of macro 'SMC_StoreValue'"
+.endif
+.endmacro
+
+
+.macro SMC_TransferLowByte label, value, register
+SMC_TransferValue label, value, register
+.endmacro
+
+.macro SMC_LoadLowByte label, register
+SMC_LoadValue label, register
+.endmacro
+
+.macro SMC_StoreLowByte label, register
+SMC_StoreValue label, register
+.endmacro
+
+.macro SMC_TransferHighByte label, value, register
+.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
+ lda value
+ sta _SMCDesignator+2
+.elseif .match ({register}, x)
+ ldx value
+ stx _SMCDesignator+2
+.elseif .match ({register}, y)
+ ldy value
+ sty _SMCDesignator+2
+.else
+ .error "Invalid usage of macro 'SMC_TransferHighByte'"
+.endif
+.endmacro
+
+.macro SMC_LoadHighByte label, register
+.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
+ lda _SMCDesignator+2
+.elseif .match ({register}, x)
+ ldx _SMCDesignator+2
+.elseif .match ({register}, y)
+ ldy _SMCDesignator+2
+.else
+ .error "Invalid usage of macro 'SMC_LoadHighByte'"
+.endif
+.endmacro
+
+.macro SMC_StoreHighByte label, register
+.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
+ sta _SMCDesignator+2
+.elseif .match ({register}, x)
+ stx _SMCDesignator+2
+.elseif .match ({register}, y)
+ sty _SMCDesignator+2
+.else
+ .error "Invalid usage of macro 'SMC_StoreHighByte'"
+.endif
+.endmacro
+
+.macro SMC_TransferAddressSingle label, address, register
+.if .paramcount = 2 .or .match ((register), a) .or .match ({register}, )
+ .if (.match (.left (1, {address}), #))
+ ; immediate mode
+ lda #<(.right (.tcount ({address})-1, {address}))
+ sta _SMCDesignator+1
+ lda #>(.right (.tcount ({address})-1, {address}))
+ sta _SMCDesignator+2
+ .else
+ ; assume absolute or zero page
+ lda address
+ sta _SMCDesignator+1
+ lda 1+(address)
+ sta _SMCDesignator+2
+ .endif
+.elseif .match ((register), x)
+ .if (.match (.left (1, {address}), #))
+ ; immediate mode
+ ldx #<(.right (.tcount ({address})-1, {address}))
+ stx _SMCDesignator+1
+ ldx #>(.right (.tcount ({address})-1, {address}))
+ stx _SMCDesignator+2
+ .else
+ ; assume absolute or zero page
+ ldx address
+ stx _SMCDesignator+1
+ ldx 1+(address)
+ stx _SMCDesignator+2
+ .endif
+.elseif .match ((register), y)
+ .if (.match (.left (1, {address}), #))
+ ; immediate mode
+ ldy #<(.right (.tcount ({address})-1, {address}))
+ sty _SMCDesignator+1
+ ldy #>(.right (.tcount ({address})-1, {address}))
+ sty _SMCDesignator+2
+ .else
+ ; assume absolute or zero page
+ ldy address
+ sty _SMCDesignator+1
+ ldy 1+(address)
+ sty _SMCDesignator+2
+ .endif
+.else
+ .error "Invalid usage of macro 'SMC_TransferAddressSingle'"
+.endif
+.endmacro
+
+.macro SMC_TransferAddress label, address
+.if (.match (.left (1, {address}), #))
+ ; immediate mode
+ lda #<(.right (.tcount ({address})-1, {address}))
+ sta _SMCDesignator+1
+ ldx #>(.right (.tcount ({address})-1, {address}))
+ stx _SMCDesignator+2
+.else
+ ; assume absolute or zero page
+ lda {address}
+ sta _SMCDesignator+1
+ ldx 1+{address}
+ stx _SMCDesignator)+2
+.endif
+.endmacro
+
+.macro SMC_StoreAddress label
+ sta _SMCDesignator+1
+ stx _SMCDesignator+2
+.endmacro