paul@0 | 1 | ; Common macros. |
paul@0 | 2 | |
paul@0 | 3 | ; Copyright (C) 2014, 2015 Paul Boddie <paul@boddie.org.uk> |
paul@0 | 4 | |
paul@0 | 5 | ; This program is free software; you can redistribute it and/or modify it under |
paul@0 | 6 | ; the terms of the GNU General Public License as published by the Free Software |
paul@0 | 7 | ; Foundation; either version 3 of the License, or (at your option) any later |
paul@0 | 8 | ; version. |
paul@0 | 9 | |
paul@0 | 10 | ; This program is distributed in the hope that it will be useful, but WITHOUT |
paul@0 | 11 | ; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
paul@0 | 12 | ; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
paul@0 | 13 | ; details. |
paul@0 | 14 | |
paul@0 | 15 | ; You should have received a copy of the GNU General Public License along with |
paul@0 | 16 | ; this program. If not, see <http://www.gnu.org/licenses/>. |
paul@0 | 17 | |
paul@0 | 18 | .alias oswrch $ffee |
paul@0 | 19 | |
paul@0 | 20 | .macro mode |
paul@0 | 21 | lda #22 |
paul@0 | 22 | jsr oswrch |
paul@0 | 23 | lda #_1 |
paul@0 | 24 | jsr oswrch |
paul@0 | 25 | .macend |
paul@0 | 26 | |
paul@0 | 27 | ; store values in locations |
paul@0 | 28 | ; |
paul@0 | 29 | ; _1: valueW |
paul@0 | 30 | ; _2: {_, _} -> {valueL, valueH} |
paul@0 | 31 | ; |
paul@0 | 32 | ; affects: A |
paul@0 | 33 | |
paul@0 | 34 | .macro store16 |
paul@0 | 35 | lda #<_1 |
paul@0 | 36 | sta _2 |
paul@0 | 37 | lda #>_1 |
paul@0 | 38 | sta _2+1 |
paul@0 | 39 | .macend |
paul@0 | 40 | |
paul@0 | 41 | ; copy word between locations |
paul@0 | 42 | ; |
paul@0 | 43 | ; _1: source |
paul@0 | 44 | ; _2: target |
paul@0 | 45 | ; |
paul@0 | 46 | ; affects: A |
paul@0 | 47 | |
paul@0 | 48 | .macro mov16 |
paul@0 | 49 | lda _1 |
paul@0 | 50 | sta _2 |
paul@0 | 51 | lda _1+1 |
paul@0 | 52 | sta _2+1 |
paul@0 | 53 | .macend |
paul@0 | 54 | |
paul@5 | 55 | ; copy word from location to indirect location |
paul@5 | 56 | ; |
paul@5 | 57 | ; _1: source |
paul@5 | 58 | ; _2: target reference |
paul@5 | 59 | ; |
paul@5 | 60 | ; affects: A, Y |
paul@5 | 61 | |
paul@5 | 62 | .macro mov16_to_ref |
paul@5 | 63 | ldy #0 |
paul@5 | 64 | lda _1 |
paul@5 | 65 | sta (_2), y |
paul@5 | 66 | iny |
paul@5 | 67 | lda _1+1 |
paul@5 | 68 | sta (_2), y |
paul@5 | 69 | .macend |
paul@5 | 70 | |
paul@5 | 71 | ; copy word from indirect location to location |
paul@5 | 72 | ; |
paul@5 | 73 | ; _1: source reference |
paul@5 | 74 | ; _2: target |
paul@5 | 75 | ; |
paul@5 | 76 | ; affects: A, Y |
paul@5 | 77 | |
paul@5 | 78 | .macro mov16_from_ref |
paul@5 | 79 | ldy #0 |
paul@5 | 80 | lda (_1), y |
paul@5 | 81 | sta _2 |
paul@5 | 82 | iny |
paul@5 | 83 | lda (_1), y |
paul@5 | 84 | sta _2+1 |
paul@5 | 85 | .macend |
paul@5 | 86 | |
paul@5 | 87 | ; copy byte between indirect locations |
paul@5 | 88 | ; |
paul@5 | 89 | ; _1: source reference |
paul@5 | 90 | ; _2: target reference |
paul@5 | 91 | ; |
paul@5 | 92 | ; Y: offset |
paul@5 | 93 | ; affects: A |
paul@5 | 94 | |
paul@5 | 95 | .macro mov8_refs |
paul@5 | 96 | lda (_1), y |
paul@5 | 97 | sta (_2), y |
paul@5 | 98 | .macend |
paul@5 | 99 | |
paul@0 | 100 | ; copy word from location to stack |
paul@0 | 101 | ; |
paul@0 | 102 | ; _1: source |
paul@0 | 103 | ; |
paul@0 | 104 | ; affects: A |
paul@0 | 105 | |
paul@0 | 106 | .macro push16 |
paul@0 | 107 | lda _1 |
paul@0 | 108 | pha |
paul@0 | 109 | lda _1+1 |
paul@0 | 110 | pha |
paul@0 | 111 | .macend |
paul@0 | 112 | |
paul@0 | 113 | ; copy word to location from stack |
paul@0 | 114 | ; |
paul@0 | 115 | ; _1: source |
paul@0 | 116 | ; |
paul@0 | 117 | ; affects: A |
paul@0 | 118 | |
paul@0 | 119 | .macro pull16 |
paul@0 | 120 | pla |
paul@0 | 121 | sta _1+1 |
paul@0 | 122 | pla |
paul@0 | 123 | sta _1 |
paul@0 | 124 | .macend |
paul@0 | 125 | |
paul@0 | 126 | ; add word to locations |
paul@0 | 127 | ; |
paul@0 | 128 | ; _1: valueW |
paul@0 | 129 | ; _2: {valueL, valueH} -> {valueL', valueH'} |
paul@0 | 130 | ; |
paul@0 | 131 | ; affects: A, C |
paul@0 | 132 | |
paul@0 | 133 | .macro add16 |
paul@0 | 134 | clc |
paul@0 | 135 | lda _2 |
paul@0 | 136 | adc #<_1 |
paul@0 | 137 | sta _2 |
paul@0 | 138 | lda _2+1 |
paul@0 | 139 | adc #>_1 |
paul@0 | 140 | sta _2+1 |
paul@0 | 141 | .macend |
paul@0 | 142 | |
paul@5 | 143 | ; subtract word from locations |
paul@5 | 144 | ; |
paul@5 | 145 | ; _1: valueW |
paul@5 | 146 | ; _2: {valueL, valueH} -> {valueL', valueH'} |
paul@7 | 147 | ; |
paul@7 | 148 | ; affects: A, C |
paul@5 | 149 | |
paul@5 | 150 | .macro sub16 |
paul@5 | 151 | sec |
paul@5 | 152 | lda _2 |
paul@5 | 153 | sbc #<_1 |
paul@5 | 154 | sta _2 |
paul@5 | 155 | lda _2+1 |
paul@5 | 156 | sbc #>_1 |
paul@5 | 157 | sta _2+1 |
paul@5 | 158 | .macend |
paul@5 | 159 | |
paul@5 | 160 | ; negate accumulator |
paul@5 | 161 | ; |
paul@5 | 162 | ; affects: A, C |
paul@5 | 163 | |
paul@5 | 164 | .macro negate |
paul@5 | 165 | clc |
paul@5 | 166 | eor #$ff |
paul@5 | 167 | adc #1 |
paul@5 | 168 | .macend |
paul@5 | 169 | |
paul@7 | 170 | ; push A onto the "user space" stack, adding an empty byte for compatibility |
paul@7 | 171 | ; with PC storage |
paul@5 | 172 | ; |
paul@7 | 173 | ; affects: USER (gains empty, A), TEMP |
paul@6 | 174 | |
paul@6 | 175 | .macro pushA |
paul@6 | 176 | sei |
paul@10 | 177 | php ; F -> stack |
paul@10 | 178 | pha ; A -> stack |
paul@6 | 179 | sty TEMP |
paul@6 | 180 | ldy #0 |
paul@6 | 181 | sta (USER), y |
paul@7 | 182 | .invoke sub16 2, USER |
paul@6 | 183 | ldy TEMP |
paul@10 | 184 | pla ; stack -> A |
paul@10 | 185 | plp ; stack -> F |
paul@6 | 186 | cli |
paul@6 | 187 | .macend |
paul@6 | 188 | |
paul@6 | 189 | ; pull A from the "user space" stack |
paul@6 | 190 | ; |
paul@7 | 191 | ; affects: A, USER (loses empty, A), TEMP |
paul@6 | 192 | |
paul@6 | 193 | .macro pullA |
paul@6 | 194 | sei |
paul@10 | 195 | php ; F -> stack |
paul@6 | 196 | sty TEMP |
paul@7 | 197 | .invoke add16 2, USER |
paul@6 | 198 | ldy #0 |
paul@6 | 199 | lda (USER), y |
paul@6 | 200 | ldy TEMP |
paul@10 | 201 | plp ; stack -> F |
paul@6 | 202 | cli |
paul@6 | 203 | .macend |
paul@6 | 204 | |
paul@7 | 205 | ; push a return address onto the "user space" stack and jump to a subroutine |
paul@7 | 206 | ; |
paul@7 | 207 | ; _1: subroutine address |
paul@7 | 208 | ; _2: return address |
paul@7 | 209 | ; |
paul@7 | 210 | ; affects: USER (gains LSB, MSB), TEMP |
paul@7 | 211 | |
paul@7 | 212 | .macro call |
paul@7 | 213 | sei |
paul@10 | 214 | php ; F -> stack |
paul@10 | 215 | pha ; A -> stack |
paul@7 | 216 | sty TEMP |
paul@7 | 217 | ldy #0 |
paul@7 | 218 | lda #<_2 |
paul@7 | 219 | sta (USER), y |
paul@7 | 220 | iny |
paul@7 | 221 | lda #>_2 |
paul@7 | 222 | sta (USER), y |
paul@7 | 223 | .invoke sub16 2, USER |
paul@7 | 224 | ldy TEMP |
paul@10 | 225 | pla ; stack -> A |
paul@10 | 226 | plp ; stack -> F |
paul@7 | 227 | cli |
paul@7 | 228 | jmp _1 |
paul@7 | 229 | .macend |
paul@7 | 230 | |
paul@7 | 231 | ; pull an address from the "user space" stack and return to it |
paul@7 | 232 | ; |
paul@7 | 233 | ; affects: USER (loses LSB, MSB), ABSTEMP |
paul@7 | 234 | |
paul@7 | 235 | .macro return |
paul@7 | 236 | sei |
paul@10 | 237 | php ; F -> stack |
paul@10 | 238 | pha ; A -> stack |
paul@7 | 239 | .invoke add16 2, USER |
paul@7 | 240 | .invoke mov16_from_ref USER, ABSTEMP |
paul@10 | 241 | pla ; stack -> A |
paul@10 | 242 | plp ; stack -> F |
paul@7 | 243 | cli |
paul@7 | 244 | jmp (ABSTEMP) |
paul@7 | 245 | .macend |
paul@7 | 246 | |
paul@0 | 247 | ; vim: tabstop=4 expandtab shiftwidth=4 |