kernel.fs (31266B) - raw
1 ?f<< /asm/arm.fs 2 ?f<< /xcomp/tools.fs 3 4 \ HAL opcode structure (close to ARM structure) 5 \ b3:0 Number bank index 6 \ b4 Has an nonzero offset 7 \ b5 Rn is an absolute memory addr in bank if set 8 \ b11:6 Zeroes 9 \ b15:12 Rd 10 \ b19:16 Rn 11 \ b21:20 Zeroes 12 \ b22 8-bit if set 13 \ b23 Inverted destination <>) 14 \ b24 Dereferenced source &) 15 \ b25 Immediate if set 16 \ b26 32-bit if set, 16-bit if unset 17 \ b27 Zero 18 \ b31:28 Cond 19 20 \ Macros 21 : xnip, add) rPSP rdn) CELLSZ imm) ,) ; 22 : xdrop, rTOP ppop, ; 23 : xgrow, sub) rPSP rdn) CELLSZ imm) ,) ; 24 : xdup, rTOP ppush, ; 25 : pushret, rLR push, ; 26 : popret, rLR pop, ; 27 : ret, rLR bx) ,) ; 28 : absb, abs>rel b) ,) ; 29 : absbl, abs>rel bl) ,) ; 30 : abscall, pushret, absbl, popret, ; 31 : wcall, xwordlbl abscall, ; 32 : wjmp, xwordlbl abs>rel b) ,) ; \ only for leaf words! 33 34 : pc>reg, ( pc r -- ) 35 dip pc -^ 8 + | ( off r ) 36 mov) over rd) rPC rm) ,) 37 sub) swap rdn) swap imm) ,) ; 38 39 : pc@>reg, ( pc r -- ) 40 dip pc -^ 8 + | ( off r ) 41 ldr) swap rd) rPC rn) swap -i) ,) ; 42 43 : movi2, ( r n1 n2 -- ) 44 rot mov) over rd) rot imm) ,) ( n1 r ) 45 add) swap rdn) swap imm) ,) ; 46 47 : xconst ( n -- ) pc swap le, xcode xdup, rTOP pc@>reg, ret, ; 48 49 : return) ( -- operand ) mov) rPC rd) rLR rm) ; 50 : setrd0) ( -- operand ) bic) $f000 imm) ; 51 : setrn0) ( -- operand ) bic) $f0000 imm) ; 52 : setimm0) ( -- operand ) bic) $3f imm) ; 53 54 : values ( n -- ) for 0 value next ; 55 16 values lblimmsplit lbladdnwr lbllitwr lblimmwr 56 lblrn>rm lblrdn lblrd<>rn lblmov lblswp 57 lblcwrite lbldwrite lblmoverange lblwriterange lblopwr 58 lblerrmsg lblmain 59 $8000 to binstart 60 binstart const RSTOP 61 RSTOP $1000 - const PSTOP 62 $04 const COMPILING 63 $08 const HERE 64 $0c const SYSDICT \ our length field lands at COMPILING MSB, which is always 0 65 $10 const HBANKIDX 66 $14 const RCNT 67 $18 const NEXTMETA 68 $1c const MOD 69 $20 const NEXTWORD 70 $24 const BOOTPTR 71 $28 const HEREMAX 72 \ 24b unused 73 $40 const CURWORD 74 $60 const HBANK 75 $10000 const HERESTART 76 \ Basis for all operands. Always cond, 32-bit, Rd=rTOP 77 $e4009000 const HALBASE 78 \ Mask for HAL-related flags with no meaning in ARM instructions 79 $07800000 const HALMASK 80 $0000003f const HALBMASK 81 $01000000 const HALDEREF 82 $02000000 const HALIMM 83 $00800000 const HALINV 84 $00000010 const HALOFF 85 $00000020 const HALMEM 86 $04000000 const HAL16B 87 $00400000 const HAL8B 88 89 \ ARM immediate system makes it difficult to place sysvars at arbitrary places 90 \ in the code and they need to be neatly arranged in an easy to refer 91 \ base+offset place. However, to facilitate initialization, we also want them to 92 \ be pre-initialized in the binary, at compile time. For this reason, we place 93 \ sysvars directly at the beginning of the binary, right after the initial 94 \ forward jump. 95 here# to org 96 forward b) ,) \ coldboot 97 0 le, \ COMPILING 98 HERESTART le, \ HERE 99 0 le, \ SYSDICT 100 0 le, \ HBANKIDX 101 0 le, \ RCNT 102 0 le, \ NEXTMETA 103 0 le, \ MOD 104 0 le, \ NEXTWORD 105 0 le, \ BOOTPTR 106 $10000000 le, \ HEREMAX 107 $18 allot0 \ unused 108 $20 allot0 \ CURWORD 109 $40 allot0 \ HBANK 110 binstart HERE + xconst HERE 111 binstart SYSDICT + xconst sysdict 112 binstart RCNT + xconst [rcnt] 113 binstart NEXTMETA + xconst nextmeta 114 binstart MOD + xconst MOD 115 binstart NEXTWORD + xconst NEXTWORD 116 binstart HEREMAX + xconst HEREMAX 117 binstart CURWORD + xconst curword 118 HERESTART xconst herestart 119 PSTOP xconst PSTOP 120 RSTOP xconst RSTOP 121 12 xconst DOESSZ 122 4 xconst BRSZ 123 124 xcode bye 0 b) ,) 125 xcode dbg 0 b) ,) 126 127 pc to L1 \ fail 128 mov) rTOP rd) 0 imm) ,) 129 ret, 130 131 \ parse char 132 pc to L2 \ rTOP=a-with-'-skipped r0=u 133 cmp) r0 rn) 3 imm) ,) 134 L1 abs>rel b) ne) ,) 135 ldr) r0 rd) rTOP rn) ,) 136 and) r1 rd) r0 rn) $ff00 imm) ,) 137 cmp) r1 rn) $2700 imm) ,) \ ' char 138 L1 abs>rel b) ne) ,) 139 and) r0 rdn) $ff imm) ,) 140 r0 ppush, 141 mov) rTOP rd) 1 imm) ,) 142 ret, 143 144 \ parse hexadecimal 145 pc to L3 \ rTOP=a-with-$-skipped r0=u 146 cmp) r0 rn) 2 imm) ,) 147 L1 abs>rel b) lo) ,) 148 sub) r0 rdn) 1 imm) ,) \ skip $ 149 mov) r2 rd) 0 imm) ,) \ accumulated result 150 pc \ loop 151 ldr) r1 rd) rTOP rn) 8b) 1 +i) post) ,) 152 orr) r1 rdn) $20 imm) ,) 153 sub) r1 rdn) '0' imm) f) ,) 154 L1 abs>rel b) lo) ,) 155 cmp) r1 rn) 10 imm) ,) 156 forward b) lo) ,) to L4 \ parse ok, under 10 157 sub) r1 rdn) 'a' '0' - imm) f) ,) 158 L1 abs>rel b) lo) ,) 159 add) r1 rdn) 10 imm) ,) 160 cmp) r1 rn) 16 imm) ,) 161 L1 abs>rel b) hs) ,) 162 L4 forward! \ parse ok 163 add) r2 rd) r1 rn) r2 rm) 4 lsl) ,) \ r2 = r2*16 + r1 164 sub) r0 rdn) 1 imm) f) ,) 165 ( loop ) abs>rel b) nz) ,) 166 r2 ppush, 167 mov) rTOP rd) 1 imm) ,) 168 ret, 169 170 \ parse unsigned decimal 171 pc to L4 \ rTOP=a+1 r1=first-char r0=u 172 mov) r4 rd) r1 rm) ,) \ for '-' check 173 cmp) r1 rn) '-' imm) ,) 174 ldr) z) r1 rd) rTOP rn) 8b) 1 +i) post) ,) 175 sub) z) r0 rdn) 1 imm) f) ,) 176 L1 abs>rel b) z) ,) \ '-' only? can't parse 177 mov) r2 rd) 0 imm) ,) \ accumulated result 178 mov) r3 rd) 10 imm) ,) \ const for mul) 179 pc \ loop 180 sub) r1 rdn) '0' imm) f) ,) 181 L1 abs>rel b) lo) ,) 182 cmp) r1 rn) 10 imm) ,) 183 L1 abs>rel b) hs) ,) 184 mul) r2 rd) r3 rm) r2 rs) r1 acc) ,) 185 ldr) r1 rd) rTOP rn) 8b) 1 +i) post) ,) 186 sub) r0 rdn) 1 imm) f) ,) 187 ( loop ) abs>rel b) nz) ,) 188 cmp) r4 rn) '-' imm) ,) 189 rsb) z) r2 rdn) 0 imm) ,) \ negate 190 r2 ppush, 191 mov) rTOP rd) 1 imm) ,) 192 ret, 193 194 xcode parse ( str -- n? f ) 195 ldr) r0 rd) rTOP rn) 8b) 1 +i) post) ,) \ rTOP=a r0=u 196 ldr) r1 rd) rTOP rn) 8b) 1 +i) post) ,) 197 cmp) r1 rn) ''' imm) ,) 198 L2 abs>rel b) eq) ,) 199 cmp) r1 rn) '$' imm) ,) 200 L3 abs>rel b) eq) ,) 201 mov) r2 rd) r1 rm) ,) 202 L4 abs>rel b) ,) 203 204 xcode rtype ret, \ placeholder 205 206 xcode compiling 207 xdup, rTOP binstart COMPILING movi2, 208 ldr) rTOP rdn) ,) 209 ret, 210 211 xcode [ ximm 212 mov) r0 rd) 0 imm) ,) 213 r1 binstart COMPILING movi2, 214 str) r0 rd) r1 rn) ,) 215 ret, 216 217 pc to L1 \ set MOD to 0 218 mov) r0 rd) 0 imm) ,) 219 r1 binstart MOD movi2, 220 str) r0 rd) r1 rn) ,) 221 ret, 222 xcode quit 223 mov) rSP rd) RSTOP imm) ,) 224 L1 abs>rel bl) ,) 225 wcall, [ 226 forward b) ,) to lblmain \ never returns 227 228 xcode (abort) 229 ( coldboot ) forward! 230 mov) rPSP rd) PSTOP imm) ,) 231 wjmp, quit 232 233 \ During early boot, it's better to halt the machine than to go back to the 234 \ mainloop because the mainloop likely sends us to an infinite error loop 235 \ through boot<. 236 pc ," boot failure" 237 xcode abort 238 ( pc ) r0 pc>reg, 239 r0 ppush, 240 mov) rTOP rd) 12 imm) ,) 241 wcall, rtype 242 0 b) ,) 243 244 xcode findmeta ( id ll -- ll-or-0 ) \ preserves r6 245 r0 ppop, 246 pc to L2 \ r0=id rTOP=ll 247 cmp) rTOP rn) 0 imm) ,) 248 return) z) ,) \ not found 249 ldr) r1 rd) rTOP rn) 4 +i) ,) 250 cmp) r0 rn) r1 rm) ,) 251 return) z) ,) \ found 252 ldr) rTOP rdn) ,) 253 L2 abs>rel b) ,) 254 255 xcode findmod ( w -- w ) 256 r0 binstart MOD movi2, ldr) r0 rdn) ,) 257 cmp) r0 rn) 0 imm) ,) 258 return) z) ,) \ no mod 259 mov) r6 rd) rTOP rm) ,) \ save w 260 sub) rTOP rdn) 8 imm) ,) \ rTOP=ll 261 pushret, L2 abs>rel bl) ,) popret, 262 cmp) rTOP rn) 0 imm) ,) 263 mov) z) rTOP rd) r6 rm) ,) \ restore w if meta not found 264 return) z) ,) \ no mod 265 pushret, L1 abs>rel bl) ,) popret, 266 add) rTOP rdn) 8 imm) ,) 267 ret, 268 269 pc to lblerrmsg \ r0=sa r1=sl 270 r0 ppush, 271 mov) rTOP rd) r1 rm) ,) 272 wcall, rtype 273 wjmp, (abort) 274 275 xcode boot< 276 r0 binstart BOOTPTR movi2, 277 ldr) r1 rd) r0 rn) ,) 278 xdup, ldr) rTOP rd) r1 rn) 8b) 1 +i) post) ,) 279 str) r1 rd) r0 rn) ,) 280 ret, 281 282 xcode in< wjmp, boot< 283 284 pc to lblmoverange \ r0=src r1=len r2=dst. out: r0=src+len r2=dst+len Saves r3 285 cmp) r1 rn) 0 imm) ,) \ guard against zero 286 return) z) ,) 287 pc 288 ldr) r4 rd) r0 rn) 8b) 1 +i) post) ,) 289 str) r4 rd) r2 rn) 8b) 1 +i) post) ,) 290 sub) r1 rdn) 1 imm) f) ,) 291 ( pc ) abs>rel b) ne) ,) 292 ret, 293 294 pc \ we have a nonzero lblnextword. r0=src 295 r1 binstart NEXTWORD movi2, 296 mov) r2 rd) 0 imm) ,) 297 str) r2 rd) r1 rn) ,) 298 ldr) r1 rd) r0 rn) 8b) ,) \ len 299 add) r1 rdn) 1 imm) ,) 300 r2 binstart CURWORD movi2, \ dst 301 mov) rTOP rd) r2 rm) ,) 302 lblmoverange abs>rel b) ,) 303 304 xcode maybeword ( -- str-or-0 ) 305 xdup, 306 r0 binstart NEXTWORD movi2, ldr) r0 rdn) ,) 307 cmp) r0 rn) 0 imm) ,) 308 ( pc ) abs>rel b) ne) ,) 309 pc 310 wcall, in< 311 xnip, 312 cmp) rTOP rn) 0 imm) ,) 313 mov) le) rTOP rd) 0 imm) ,) 314 return) le) ,) \ EOF 315 cmp) rTOP rn) SPC imm) ,) 316 ( pc ) abs>rel b) le) ,) \ rTOP=first non-ws 317 mov) r6 rd) 0 imm) ,) 318 r5 binstart CURWORD movi2, 319 pc 320 add) r6 rdn) 1 imm) ,) 321 str) rTOP rd) r5 rn) 8b) 1 +i) pre) !) ,) 322 wcall, in< 323 xnip, 324 cmp) rTOP rn) SPC imm) ,) 325 ( pc ) abs>rel b) gt) ,) 326 rTOP binstart CURWORD movi2, 327 str) r6 rd) rTOP rn) 8b) ,) 328 ret, 329 330 pc ," word expected" alignhere 331 xcode word 332 wcall, maybeword 333 ( pc ) r0 pc>reg, 334 mov) r1 rd) 13 imm) ,) 335 cmp) rTOP rn) 0 imm) ,) 336 lblerrmsg abs>rel b) z) ,) 337 ret, 338 339 pc ," word not found" alignhere 340 xcode (wnf) 341 r0 binstart CURWORD movi2, 342 ldr) rTOP rd) r0 rn) 8b) 1 +i) post) ,) 343 r0 ppush, 344 wcall, rtype 345 ( pc ) r0 pc>reg, 346 mov) r1 rd) 15 imm) ,) 347 lblerrmsg abs>rel b) ,) 348 349 xcode execute ( a -- ) 350 mov) r0 rd) rTOP rm) ,) 351 xdrop, 352 r0 bx) ,) 353 354 xcode find ( name 'dict -- w-or-0 ) 355 r2 ppop, 356 ldr) r1 rd) r2 rn) 8b) 1 +i) post) ,) \ r2=a r1=len 357 pc \ loop1 358 ldr) r3 rd) rTOP rn) 8b) 5 -i) ,) \ entry len 359 and) r3 rdn) $3f imm) ,) \ remove flags 360 cmp) r1 rn) r3 rm) ,) 361 forward b) ne) ,) to L1 362 \ same length 363 sub) r4 rd) rTOP rn) 5 imm) ,) 364 sub) r4 rdn) r1 rm) ,) \ beginning of name range 365 mov) r3 rd) 0 imm) ,) 366 pc \ loop2 367 ldr) r5 rd) r4 rn) 8b) r3 +r) ,) 368 ldr) r0 rd) r2 rn) 8b) r3 +r) ,) 369 cmp) r5 rn) r0 rm) ,) 370 forward b) ne) ,) to L2 371 add) r3 rdn) 1 imm) ,) 372 cmp) r3 rn) r1 rm) ,) 373 ( loop2 ) abs>rel b) ne) ,) 374 \ same contents 375 add) rTOP rdn) 4 imm) ,) \ e>w 376 ret, 377 L2 forward! L1 forward! \ not matching, try next 378 ldr) rTOP rdn) 0 +i) ,) 379 cmp) rTOP rn) 0 imm) ,) 380 ( loop1 ) abs>rel b) ne) ,) 381 \ not found 382 ret, 383 384 pc to lblcwrite \ r0=char 385 r2 binstart HERE movi2, 386 ldr) r1 rd) r2 rn) ,) 387 str) r0 rd) r1 rn) 8b) 1 +i) post) ,) 388 str) r1 rd) r2 rn) ,) 389 ret, 390 391 pc to lbldwrite \ r0=n. Destroys r1 and r2, preserves rest and flags 392 r2 binstart HERE movi2, 393 ldr) r1 rd) r2 rn) ,) 394 str) r0 rd) r1 rn) 4 +i) post) ,) 395 str) r1 rd) r2 rn) ,) 396 ret, 397 398 pc to lblwriterange \ r0=addr r1=len 399 r3 binstart HERE movi2, 400 ldr) r2 rd) r3 rn) ,) 401 pushret, lblmoverange abs>rel bl) ,) popret, 402 str) r2 rd) r3 rn) ,) 403 ret, 404 405 xcode entry pushret, ( 'dict s -- ) 406 r0 binstart RCNT movi2, 407 mov) r1 rd) 0 imm) ,) 408 str) r1 rd) r0 rn) ,) 409 mov) r6 rd) rTOP rm) ,) 410 ldr) r5 rd) r6 rn) 8b) 1 +i) post) ,) \ r5=a r6=len 411 add) rTOP rd) r5 rn) 1 imm) ,) \ rTOP=len+1 412 r0 binstart HERE movi2, 413 ldr) r1 rd) r0 rn) ,) 414 add) r2 rd) r1 rn) rTOP rm) ,) 415 and) r2 rdn) 3 imm) f) ,) 416 sub) ne) r1 rdn) r2 rm) ,) 417 add) ne) r1 rdn) 4 imm) ,) 418 str) ne) r1 rd) r0 rn) ,) 419 xdrop, \ rTOP='dict 420 mov) r0 rd) r6 rm) ,) 421 mov) r1 rd) r5 rm) ,) 422 lblwriterange absbl, 423 mov) r0 rd) r5 rm) ,) 424 lblcwrite absbl, 425 r0 binstart NEXTMETA movi2, 426 ldr) r0 rdn) ,) 427 lbldwrite absbl, 428 ldr) r0 rd) rTOP rn) ,) \ r0=dict 429 r1 binstart HERE movi2, ldr) r1 rdn) ,) 430 str) r1 rd) rTOP rn) ,) \ "here" is new sysdict 431 xdrop, 432 popret, 433 lbldwrite abs>rel b) ,) 434 435 xcode code 436 wcall, sysdict 437 wcall, word 438 wjmp, entry 439 440 pc to L1 \ r3=meta-id 441 r2 binstart SYSDICT movi2, ldr) r2 rdn) ,) 442 r0 binstart HERE movi2, ldr) r0 rdn) ,) 443 sub) r2 rdn) 4 imm) ,) 444 swp) r0 rd) r2 rn) r0 rm) ,) 445 pushret, lbldwrite abs>rel bl) ,) popret, 446 mov) r0 rd) r3 rm) ,) 447 lbldwrite abs>rel b) ,) 448 449 xcode code16b mov) r3 rd) EMETA_16B imm) ,) L1 abs>rel b) ,) 450 xcode code8b mov) r3 rd) EMETA_8B imm) ,) L1 abs>rel b) ,) 451 452 \ HAL operands 453 HALBASE rTOP rn) xconst W) 454 HALBASE rA rn) xconst A) 455 HALBASE rPSP rn) xconst PSP) 456 HALBASE rSP rn) xconst RSP) 457 0 eq) xconst Z) 458 0 ne) xconst NZ) 459 0 hs) xconst >=) 460 0 lo) xconst <) 461 0 hi) xconst >) 462 0 ls) xconst <=) 463 0 ge) xconst s>=) 464 0 lt) xconst s<) 465 0 gt) xconst s>) 466 0 le) xconst s<=) 467 468 xcode _hbank' ( slot -- a ) \ Preserves r0 r1 r2 469 and) r3 rd) rTOP rn) $f imm) ,) 470 rTOP binstart HBANK movi2, 471 add) rTOP rdn) r3 rm) 2 lsl) ,) 472 ret, 473 474 xcode hbank' ( slot -- a ) \ Preserves r0 r1 r2 475 and) r3 rd) rTOP rn) $f imm) ,) 476 rTOP binstart HBANK movi2, 477 add) rTOP rdn) r3 rm) 2 lsl) ,) 478 ret, 479 480 xcode hbank@ ( slot -- n ) 481 wcall, _hbank' 482 ldr) rTOP rdn) ,) 483 ret, 484 485 xcode hbank! ( n -- slot ) 486 r0 binstart HBANKIDX movi2, 487 mov) r1 rd) rTOP rm) ,) 488 ldr) rTOP rd) r0 rn) ,) 489 and) r2 rd) rTOP rn) $f imm) ,) 490 wcall, _hbank' 491 str) r1 rd) rTOP rn) ,) 492 mov) rTOP rd) r2 rm) ,) 493 add) r2 rdn) 1 imm) ,) 494 str) r2 rd) r0 rn) ,) 495 ret, 496 497 pc HALBASE HALMEM or le, 498 xcode m) ( a -- operand ) 499 wcall, hbank! 500 ( pc ) r0 pc@>reg, 501 orr) rTOP rdn) r0 rm) ,) 502 ret, 503 504 pc HALBASE HALIMM or le, 505 xcode i) ( n -- operand ) 506 wcall, hbank! 507 ( pc ) r0 pc@>reg, 508 orr) rTOP rdn) r0 rm) ,) 509 ret, 510 511 \ Instead of using a new number bank, add n to operand's current bank 512 pc to L1 ( operand n -- operand ) 513 rTOP push, 514 ldr) rTOP rd) rPSP rn) ,) \ rTOP=operand 515 wcall, hbank' 516 ldr) r0 rd) rTOP rn) ,) 517 r1 pop, 518 add) r0 rdn) r1 rm) ,) 519 str) r0 rd) rTOP rn) ,) 520 xdrop, ret, 521 522 xcode +) ( operand n -- operand ) 523 ldr) r0 rd) rPSP rn) ,) 524 tst) r0 rn) HALIMM imm) ,) 525 L1 abs>rel b) nz) ,) 526 tst) r0 rn) HALMEM HALOFF or imm) ,) 527 L1 abs>rel b) nz) ,) 528 wcall, hbank! 529 ldr) r0 rd) rPSP rn) ,) 530 xnip, 531 orr) rTOP rdn) r0 rm) ,) 532 orr) rTOP rdn) HALOFF imm) ,) 533 ret, 534 535 xcode 8b) ( operand -- operand ) 536 orr) rTOP rdn) HAL8B imm) ,) 537 ret, 538 539 xcode 16b) ( operand -- operand ) 540 bic) rTOP rdn) HAL16B imm) ,) 541 ret, 542 543 xcode 32b) ( operand -- operand ) 544 bic) rTOP rdn) HAL8B imm) ,) 545 orr) rTOP rdn) HAL16B imm) ,) 546 ret, 547 548 xcode A>) ( operand -- operand ) 549 setrd0) rTOP rdn) ,) 550 orr) rTOP rdn) rA 12 lshift imm) ,) 551 ret, 552 553 xcode <>) ( operand -- operand ) 554 orr) rTOP rdn) HALINV imm) ,) 555 ret, 556 557 xcode &) ( operand -- operand ) 558 tst) rTOP rn) HALMEM imm) ,) 559 bic) nz) rTOP rdn) HALMEM imm) ,) 560 orr) nz) rTOP rdn) HALIMM imm) ,) 561 orr) z) rTOP rdn) HALDEREF imm) ,) 562 ret, 563 564 \ HAL operations 565 \ r0 is used as the immediate accumulator 566 \ TODO: add out-of-range error for offsets not fitting 12 bits 567 568 \ merge operand with instr and write 569 pc to lblopwr ( operand -- ) \ r0=base instr. Preserves r3 570 bic) rTOP rdn) HALMASK imm) ,) 571 orr) r0 rdn) rTOP rm) ,) 572 xdrop, 573 lbldwrite abs>rel b) ,) 574 575 \ Extract 12b rotate+imm from n. Preserves r0 576 pc to lblimmsplit \ In: rTOP=n Out: rTOP=rotate+imm r1=rest of n. 577 mov) r2 rd) 0 imm) ,) \ r2=rotate 578 mov) r1 rd) 0 imm) ,) 579 cmp) rTOP rn) $100 imm) ,) 580 return) lo) ,) 581 pc 582 mov) r3 rd) rTOP rm) r2 rlsr) f) ,) 583 return) z) ,) \ rTOP is zero, nothing to do 584 tst) r3 rn) 3 imm) ,) 585 add) z) r2 rdn) 2 imm) ,) 586 ( pc ) abs>rel b) z) ,) 587 and) r3 rdn) $ff imm) ,) \ r3=8b imm 588 sub) r1 rd) rTOP rn) r3 rm) r2 rlsl) f) ,) \ r1=rest of n 589 rsb) r2 rdn) 0 imm) ,) \ rotate is to the *right* 590 and) r2 rdn) $1e imm) ,) \ 0-32, even numbers 591 orr) rTOP rd) r3 rn) r2 rm) 7 lsl) ,) \ rTOP=rotate+imm 592 ret, 593 594 \ Compile a add) of immediate "n" with target register selected in r1 595 pc add) 0 imm) f) ,) 596 pc to lbladdnwr ( n -- ) \ r1=Rd/Rn 597 cmp) rTOP rn) 0 imm) ,) \ if n=0, don't write anything 598 ldr) z) rTOP rd) rPSP rn) CELLSZ +i) post) ,) 599 return) z) ,) 600 ( pc ) r0 pc@>reg, 601 orr) r0 rdn) r1 rm) 12 lsl) ,) 602 orr) r0 rdn) r1 rm) 16 lsl) ,) 603 tst) rTOP rn) $80000000 imm) ,) 604 eor) ne) r0 rdn) $00c00000 imm) ,) \ add) to sub) 605 rsb) ne) rTOP rdn) 0 imm) ,) \ negate rTOP 606 pushret, 607 pc 608 lblimmsplit abs>rel bl) ,) 609 r0 push, 610 orr) r0 rdn) rTOP rm) ,) 611 mov) rTOP rd) r1 rm) ,) 612 lbldwrite abs>rel bl) ,) 613 r0 pop, 614 cmp) rTOP rn) 0 imm) ,) 615 ( pc ) abs>rel b) nz) ,) 616 xdrop, popret, ret, 617 618 xcode rs+, ( n -- ) 619 r0 binstart RCNT movi2, 620 ldr) r1 rd) r0 rn) ,) 621 add) r1 rdn) rTOP rm) ,) 622 str) r1 rd) r0 rn) ,) 623 mov) r1 rd) rSP imm) ,) lbladdnwr abs>rel b) ,) 624 625 xcode ps+, ( n -- ) 626 mov) r1 rd) rPSP imm) ,) lbladdnwr abs>rel b) ,) 627 628 \ Compile code resulting in register Rd to contain "n" 629 pc mov) 0 imm) ,) 630 pc to lbllitwr ( n -- ) \ r0=Rd 631 pushret, r0 push, 632 lblimmsplit abs>rel bl) ,) 633 r1 ppush, ( rest imm+rotate ) 634 ( pc ) r3 pc@>reg, 635 orr) r0 rd) r3 rn) r0 rm) 12 lsl) ,) \ merge Rd in instr 636 lblopwr abs>rel bl) ,) 637 r1 pop, popret, \ r1=Rd 638 lbladdnwr abs>rel b) ,) 639 640 \ Checks if operand is i) or m). If it is, compile a write of this value to r0 641 \ and modify operand in consequence 642 pc to lblimmwr ( operand -- operand ) \ preserves r0 643 tst) rTOP rn) HALMEM imm) ,) 644 return) z) ,) \ not a m) operand 645 r0 push, 646 xdup, wcall, hbank@ 647 mov) r0 rd) r1 imm) ,) 648 pushret, lbllitwr abs>rel bl) ,) popret, ( operand ) 649 setrn0) rTOP rdn) ,) 650 orr) rTOP rdn) $10000 imm) ,) \ Rn=r1 651 bic) rTOP rdn) HALBMASK imm) ,) 652 r0 pop, 653 ret, 654 655 \ Move Rn to Rm in operand 656 pc to lblrn>rm \ rTOP=operand 657 \ move Rn to Rm 658 bic) rTOP rdn) HALBMASK imm) ,) 659 mov) r0 rd) rTOP rm) 16 lsr) ,) 660 and) r0 rdn) $f imm) ,) 661 orr) rTOP rdn) r0 rm) ,) 662 bic) rTOP rdn) $f0000 imm) ,) \ clear Rn 663 ret, 664 665 \ Copy Rd to Rn in operand. 666 pc to lblrdn \ rTOP=operand. preserves r0 667 bic) rTOP rdn) $f0000 imm) ,) \ clear Rn 668 and) r1 rd) rTOP rn) $f000 imm) ,) 669 orr) rTOP rdn) r1 rm) 4 lsl) ,) 670 ret, 671 672 \ Swap Rd and Rn in operand 673 pc to lblrd<>rn \ rTOP=operand 674 and) r0 rd) rTOP rn) $f000 imm) ,) 675 and) r1 rd) rTOP rn) $f0000 imm) ,) 676 bic) rTOP rdn) $ff000 imm) ,) 677 orr) rTOP rdn) r0 rm) 4 lsl) ,) 678 orr) rTOP rdn) r1 rm) 4 lsr) ,) 679 ret, 680 681 \ Write a mov) from operand's src to operand *dereferenced* dst. If operand has 682 \ an offset, a add) is written after the mov). 683 pc mov) ,) 684 pc to lblmov ( operand -- ) 685 tst) rTOP rn) HALINV imm) ,) 686 pushret, lblrd<>rn abs>rel bl) nz) ,) popret, 687 xdup, ( op op ) 688 lblrn>rm abscall, 689 ( pc ) r0 pc@>reg, 690 lblopwr abscall, ( op ) 691 tst) rTOP rn) HALOFF imm) ,) 692 and) r1 rd) rTOP rn) $f000 imm) ,) \ Rd 693 mov) r1 rd) r1 rm) 12 lsr) ,) 694 wcall, hbank@ 695 lbladdnwr abs>rel b) nz) ,) 696 xdrop, ret, 697 698 \ Write an eor between operand's src and dereferenced dst. 699 pc eor) ,) 700 pc to L2 ( operand -- ) 701 lblrn>rm abscall, 702 lblrdn abscall, 703 ( pc ) r0 pc@>reg, 704 lblopwr abs>rel b) ,) 705 706 \ Write a swap between operand's src to operand *dereferenced* dst. Offsets are 707 \ ignored. Registers only 708 pc to lblswp ( operand -- ) 709 pushret, 710 xdup, xdup, 711 L2 abs>rel bl) ,) 712 lblrd<>rn abs>rel bl) ,) 713 L2 abs>rel bl) ,) 714 popret, 715 L2 abs>rel b) ,) 716 717 pc rsb) rTOP rdn) 0 imm) ,) 718 xcode -W, ( -- ) 719 ( pc ) r0 pc@>reg, lbldwrite abs>rel b) ,) 720 721 \ if HALOFF is set in operand, fetch number associated with hbank in r1, and 722 \ if that number is negative, unset the U (up/down) bit of the instruction in 723 \ r0. Also set HALMASK to 0 in operand. 724 \ Z is set according to whether HALOFF was there: Z=no HALOFF NZ=HALOFF 725 \ TODO: support numbers over 12b 726 pc to L1 ( operand -- ) \ r0=instr r1=bank number 727 tst) rTOP rn) HALOFF imm) ,) \ has offset? 728 return) z) ,) 729 rTOP push, wcall, hbank@ mov) r1 rd) rTOP rm) f) ,) rTOP pop, 730 bic) mi) r0 rdn) $00800000 imm) ,) \ negative, unset U bit 731 rsb) mi) r1 rdn) 0 imm) ,) 732 bic) rTOP rdn) HALBMASK imm) f) ,) \ unset Z 733 ret, 734 735 \ conditionally merge hbank with operand, then with instr then write 736 pc to L2 ( operand -- ) \ r0=instr 737 L1 abscall, 738 orr) nz) rTOP rdn) r1 rm) ,) 739 lblopwr abs>rel b) ,) 740 741 \ operand is 16b 742 pc to L3 ( operand -- ) \ r0=base instr 743 orr) r0 rdn) $b0 imm) ,) \ make into a ldrh/strh op 744 bic) r0 rdn) $04000000 imm) ,) 745 orr) r0 rdn) $00400000 imm) ,) \ immediate 746 L1 abscall, 747 mov) nz) r2 rd) r1 rm) 4 lsl) ,) \ imm high nibble 748 and) nz) r1 rdn) $f imm) ,) 749 and) nz) r2 rdn) $f00 imm) ,) 750 orr) nz) r0 rdn) r1 rm) ,) \ apply low nibble 751 orr) nz) r0 rdn) r2 rm) ,) \ apply high nibble 752 lblopwr abs>rel b) ,) 753 754 \ Write a ldr) or str), depending on instr 755 pc to L4 ( operand -- ) \ r0=instr 756 lblimmwr abscall, 757 tst) rTOP rn) HALINV imm) ,) 758 eor) nz) r0 rdn) $100000 imm) ,) \ toggle LDR/STR 759 tst) rTOP rn) HAL16B imm) ,) 760 L3 abs>rel b) z) ,) 761 L2 abs>rel b) ,) 762 \ Write number specified in bank as an immediate to operand's target 763 pc to L3 ( operand -- ) 764 mov) r0 rd) rTOP rm) 12 lsr) ,) 765 and) r0 rdn) $f imm) ,) 766 wcall, hbank@ 767 lbllitwr abs>rel b) ,) 768 pc ldr) 0 +i) ,) 769 xcode @, ( operand -- ) \ Compiled code preserves r0 770 tst) rTOP rn) HALIMM imm) ,) 771 L3 abs>rel b) nz) ,) 772 tst) rTOP rn) HALDEREF imm) ,) 773 lblmov abs>rel b) nz) ,) 774 ( pc ) r0 pc@>reg, L4 abs>rel b) ,) 775 776 xcode !, ( operand -- ) 777 eor) rTOP rdn) HALINV imm) ,) 778 wjmp, @, 779 780 pc to L1 ( operand -- ) \ r0=base instr 781 \ set offset to 4, 2, or 1 782 mov) r1 rd) 4 imm) ,) 783 tst) rTOP rn) HAL16B imm) ,) 784 mov) z) r1 rd) 2 imm) ,) 785 tst) rTOP rn) HAL8B imm) ,) 786 mov) nz) r1 rd) 1 imm) ,) 787 orr) r0 rdn) r1 rm) ,) 788 L4 absb, 789 790 pc ldr) 0 +i) post) ,) 791 xcode @+, ( operand -- ) 792 ( pc ) r0 pc@>reg, L1 abs>rel b) ,) 793 794 xcode !+, ( operand -- ) 795 eor) rTOP rdn) HALINV imm) ,) 796 wjmp, @+, 797 798 pc ldr) 0 -i) pre) !) ,) 799 xcode -@, ( operand -- ) 800 ( pc ) r0 pc@>reg, L1 abs>rel b) ,) 801 802 xcode -!, ( operand -- ) 803 eor) rTOP rdn) HALINV imm) ,) 804 wjmp, -@, 805 806 pc add) 0 imm) ,) 807 pc to L1 ( operand -- ) 808 rTOP push, wcall, hbank@ mov) r0 rd) rTOP rm) ,) rTOP pop, 809 tst) rTOP rn) HALMEM imm) ,) 810 mov) nz) rTOP rd) r0 rm) ,) 811 mov) nz) r0 rd) rTOP imm) ,) 812 lbllitwr abs>rel b) nz) ,) \ m) operand 813 ( pc ) r0 pc@>reg, L2 abs>rel b) ,) 814 815 \ operand is 16b and ARM doesn't have a 16b SWP! LDR+STR+MOV... 816 pc mov) rTOP rd) r0 rm) ,) 817 pc to L3 ( operand -- ) 818 xdup, 819 setrd0) rTOP rdn) ,) 820 wcall, @, wcall, !, 821 ( pc ) r0 pc@>reg, 822 lbldwrite abs>rel b) ,) 823 824 pc swp) rTOP rd) rTOP rm) ,) 825 xcode @!, ( operand -- ) 826 lblimmwr abscall, 827 tst) rTOP rn) HALDEREF imm) ,) 828 lblswp abs>rel b) nz) ,) 829 tst) rTOP rn) HAL16B imm) ,) 830 L3 abs>rel b) z) ,) 831 tst) rTOP rn) HALOFF imm) ,) \ has offset? 832 forward b) z) ,) 833 xdup, setrd0) rTOP rdn) ,) 834 L1 abscall, 835 setrn0) rTOP rdn) ,) 836 forward! 837 \ TODO: figure out how HALBMASK can be nonzero at this point. Theoretically, 838 \ it's always zero, but without this line, we fail. 839 setimm0) rTOP rdn) ,) 840 ( pc ) r0 pc@>reg, 841 lblopwr abs>rel b) ,) 842 843 \ Handle "mul" by moving Rn to Rm, setting Rn to zero. 844 pc to L1 ( operand -- ) \ r0=instr 845 and) r1 rd) rTOP rn) $f000 imm) ,) \ Rn 846 bic) rTOP rdn) $f000 imm) ,) 847 orr) rTOP rdn) r1 rm) 4 lsr) ,) 848 lblopwr abs>rel b) ,) 849 850 \ Proxy lblopwr with this processing: 851 \ 1. Remove OP8B which messes with arithmetic opcodes 852 \ 2. If opcode is one of the "comparison" opcodes, forcefully set Rd to 0 before 853 \ writing it off. 854 \ 3. Also check for "mul". 855 pc to L4 ( operand -- ) \ r0=instr 856 bic) rTOP rdn) HAL8B imm) ,) 857 and) r1 rd) r0 rn) $01900000 imm) ,) 858 cmp) r1 rn) $01100000 imm) ,) 859 setrd0) z) rTOP rdn) ,) 860 and) z) r1 rd) r0 rn) $01900000 imm) ,) 861 and) r1 rd) r0 rn) $0ff00000 imm) ,) 862 and) r2 rd) r0 rn) $000000f0 imm) ,) 863 orr) r1 rdn) r2 rm) ,) 864 cmp) r1 rn) $00000090 imm) ,) 865 L1 abs>rel b) z) ,) 866 lblopwr abs>rel b) ,) 867 868 \ Write arithmetic operation with an immediate src 869 pc to L3 ( operand -- ) \ r0=instr 870 \ TODO: avoid step by encoding imm) directly when possible 871 r0 push, 872 xdup, ( op op ) 873 setrd0) rTOP rdn) ,) 874 wcall, @, ( op ) \ imm in r0 875 r0 pop, \ r0=instr 876 setimm0) rTOP rdn) ,) 877 lblrdn abscall, 878 L4 abs>rel b) ,) ( ) 879 880 \ Write inverted arithmetic operation, that is: 881 \ 1. Load operand's src in r0 882 \ 2. Apply instr with r0 as Rd and Rn and operand's dst as Rm. 883 \ 3. Store r0 in operand's src 884 pc to L2 ( operand -- ) \ r0=instr 885 bic) rTOP rdn) HALINV imm) ,) 886 r0 push, 887 lblimmwr abscall, 888 xdup, ( op op ) 889 setrd0) rTOP rdn) ,) 890 wcall, @, ( op ) 891 xdup, ( op op ) 892 setimm0) rTOP rdn) ,) 893 lblrd<>rn abscall, 894 setrd0) rTOP rdn) ,) 895 lblrn>rm abscall, 896 r0 pop, \ r0=instr 897 L4 abscall, ( op ) 898 setrd0) rTOP rdn) ,) 899 wjmp, !, ( ) 900 901 \ Write arithmetic operation, that is: 902 \ 1. Load operand's src in r0 903 \ 2. Apply instr with operand's dst as Rd and Rn and r0 as Rm. 904 pc to L1 ( operand -- ) \ r0=instr 905 tst) rTOP rn) HALINV imm) ,) 906 L2 abs>rel b) nz) ,) 907 tst) rTOP rn) HALIMM imm) ,) 908 L3 abs>rel b) nz) ,) 909 r0 push, 910 lblimmwr abscall, 911 xdup, ( op op ) 912 setrd0) rTOP rdn) ,) 913 wcall, @, ( op ) 914 r0 pop, \ r0=instr 915 setimm0) rTOP rdn) ,) 916 lblrdn abscall, 917 L4 abs>rel b) ,) ( ) 918 919 xcode +, ( operand -- ) 920 mov) r0 rd) $00900000 imm) ,) ( add+s ) L1 abs>rel b) ,) 921 922 xcode -, ( operand -- ) 923 mov) r0 rd) $00500000 imm) ,) ( sub+s ) L1 abs>rel b) ,) 924 925 xcode &, ( operand -- ) 926 mov) r0 rd) $00100000 imm) ,) ( and+s ) L1 abs>rel b) ,) 927 928 xcode |, ( operand -- ) 929 mov) r0 rd) $01900000 imm) ,) ( and+s ) L1 abs>rel b) ,) 930 931 xcode ^, ( operand -- ) 932 mov) r0 rd) $00300000 imm) ,) ( and+s ) L1 abs>rel b) ,) 933 934 xcode compare, ( operand -- ) 935 mov) r0 rd) $01500000 imm) ,) ( cmp ) L1 abs>rel b) ,) 936 937 xcode *, ( operand -- ) 938 mov) r0 rd) $00000090 imm) ,) ( mul ) L1 abs>rel b) ,) 939 940 \ Write << or >> in its immediate form 941 pc to L1 ( operand -- ) \ r0=instr 942 wcall, hbank@ 943 and) rTOP rdn) $1f imm) ,) \ 5-bit 944 orr) r0 rdn) rTOP rm) 7 lsl) ,) \ or in b11:7 945 xdrop, 946 lbldwrite abs>rel b) ,) 947 948 \ Write << or >> in its register form 949 pc to L2 ( operand -- ) \ r0=instr 950 r0 push, 951 setrd0) rTOP rdn) ,) 952 wcall, @, 953 r0 pop, 954 orr) r0 rdn) $10 imm) ,) \ register shift 955 lbldwrite abs>rel b) ,) 956 957 \ Write << or >> in either its register form or immediate form 958 pc to L3 ( operand -- ) \ r0=instr mask 959 orr) r0 rdn) $e0000000 imm) ,) \ always 960 orr) r0 rdn) $01a00000 imm) ,) \ MOV 961 and) r1 rd) rTOP rn) $f000 imm) ,) \ Rd 962 orr) r0 rdn) r1 rm) ,) 963 orr) r0 rdn) r1 rm) 12 lsr) ,) \ Rm 964 \ We're set for everything except b11:6 and b4 965 tst) rTOP rn) HALIMM imm) ,) 966 L1 abs>rel b) nz) ,) 967 L2 abs>rel b) ,) 968 969 \ Write << or >> while handling the <>) case 970 pc to L4 ( operand -- ) \ r0=instr mask 971 tst) rTOP rn) HALINV imm) ,) 972 L3 abs>rel b) z) ,) \ not <>) 973 bic) rTOP rdn) HALINV imm) ,) 974 r0 push, xdup, xdup, wcall, @!, r0 pop, 975 L3 abscall, 976 wjmp, @!, 977 978 xcode <<, ( operand -- ) 979 mov) r0 rd) 0 imm) ,) L4 absb, 980 981 xcode >>, ( operand -- ) 982 mov) r0 rd) $20 imm) ,) L4 absb, 983 984 xcode +n, ( n operand -- ) 985 lblimmwr abscall, 986 setrd0) rTOP rdn) ,) 987 xdup, wcall, @, 988 swp) rTOP rd) rPSP rn) rTOP rm) ,) ( operand n ) 989 mov) r1 rd) r0 imm) ,) lbladdnwr abscall, 990 wjmp, !, 991 992 pc pushret, 993 xcode pushret, 994 ( pc ) r0 pc@>reg, lbldwrite abs>rel b) ,) 995 996 pc popret, 997 xcode popret, 998 ( pc ) r0 pc@>reg, lbldwrite abs>rel b) ,) 999 1000 pc ret, 1001 xcode exit, 1002 ( pc ) r0 pc@>reg, lbldwrite abs>rel b) ,) 1003 1004 pc to L1 ( w -- ) \ r2=base instr 1005 r1 binstart HERE movi2, ldr) r1 rdn) ,) 1006 sub) r0 rd) rTOP rn) r1 rm) ,) 1007 mov) r0 rd) r0 rm) 2 lsr) ,) 1008 sub) r0 rdn) 2 imm) ,) 1009 bic) r0 rn) $ff000000 imm) ,) 1010 orr) r0 rdn) r2 rm) ,) 1011 xdrop, 1012 lbldwrite abs>rel b) ,) 1013 1014 xcode branchR, ( w -- ) 1015 mov) r2 rd) $eb000000 imm) ,) 1016 L1 abs>rel b) ,) 1017 1018 xcode branch, ( a -- a ) 1019 mov) r2 rd) $ea000000 imm) ,) 1020 pc to L2 ( a -- a ) \ r2=base instr 1021 pushret, L1 abs>rel bl) ,) popret, 1022 xdup, rTOP binstart HERE movi2, ldr) rTOP rdn) ,) 1023 sub) rTOP rdn) 4 imm) ,) 1024 ret, 1025 1026 xcode branchC, ( a cond -- a ) 1027 mov) r2 rd) $0a000000 imm) ,) 1028 orr) r2 rdn) rTOP rm) ,) 1029 xdrop, 1030 L2 abs>rel b) ,) 1031 1032 pc mov) rPC rd) rA rm) ,) 1033 xcode branchA, 1034 ( pc ) r0 pc@>reg, lbldwrite abs>rel b) ,) 1035 1036 xcode branch! ( tgt a -- ) 1037 r1 ppop, \ r1=tgt 1038 sub) r0 rd) r1 rn) rTOP rm) ,) \ r0=displacement 1039 mov) r0 rd) r0 rm) 2 lsr) ,) 1040 sub) r0 rdn) 2 imm) ,) 1041 bic) r0 rn) $ff000000 imm) ,) \ r0=24-bit offset 1042 ldr) r1 rd) rTOP rn) ,) 1043 and) r1 rdn) $ff000000 imm) ,) 1044 orr) r0 rdn) r1 rm) ,) 1045 str) r0 rd) rTOP rn) ,) 1046 xdrop, ret, 1047 1048 \ a simple SWP pc, [sp] would be nice, right? but we can't... 1049 \ In this sequence below, remember that PC is 8 bytes ahead. 1050 pc mov) rLR rd) rPC rm) ,) add) rLR rdn) 8 imm) ,) 1051 swp) rLR rd) rSP rn) rLR rm) ,) return) ,) 1052 xcode yield ximm 1053 ( pc ) r0 pc>reg, 1054 mov) r1 rd) 16 imm) ,) 1055 lblwriterange abs>rel b) ,) 1056 1057 pc mov) rTOP rd) 0 imm) ,) add) z) ( 0 cond ) rTOP rdn) 1 imm) ,) 1058 xcode C>W, ( cond -- ) 1059 dup ( pc ) r0 pc@>reg, 1060 pushret, lbldwrite abs>rel bl) ,) popret, 1061 ( pc ) 4 + r0 pc@>reg, 1062 orr) r0 rdn) rTOP rm) ,) 1063 xdrop, 1064 lbldwrite abs>rel b) ,) 1065 1066 pc xdup, 1067 xcode dup, 1068 ( pc ) r0 pc@>reg, lbldwrite abs>rel b) ,) 1069 1070 xcode litn 1071 wcall, dup, 1072 mov) r0 rd) rTOP imm) ,) lbllitwr abs>rel b) ,) 1073 1074 pc ," divide by zero" alignhere 1075 pc to L1 \ rTOP=dividend rA=divisor 1076 ( pc ) r0 pc>reg, 1077 mov) r1 rd) 14 imm) ,) 1078 cmp) rA rn) 0 imm) ,) 1079 lblerrmsg abs>rel b) z) ,) 1080 \ rTOP is active remainder 1081 mov) r1 rd) 0 imm) ,) \ r1=quotient 1082 mov) r2 rd) rA rm) ,) \ r2=tmp 1083 \ double tmp until 2 * tmp > dividend 1084 cmp) r2 rn) rTOP rm) 1 lsr) ,) 1085 pc 1086 mov) ls) r2 rd) r2 rm) 1 lsl) ,) 1087 cmp) r2 rn) rTOP rm) 1 lsr) ,) 1088 ( pc ) abs>rel b) ls) ,) 1089 pc 1090 cmp) rTOP rn) r2 rm) ,) \ can we subtract temp from dividend? 1091 sub) cs) rTOP rdn) r2 rm) ,) \ if yes, do it 1092 adc) r1 rdn) r1 rm) ,) \ double and add carry 1093 mov) r2 rd) r2 rm) 1 lsr) ,) 1094 cmp) r2 rn) rA rm) ,) 1095 ( pc ) abs>rel b) hs) ,) 1096 mov) rA rd) rTOP rm) ,) \ set remainder 1097 mov) rTOP rd) r1 rm) ,) \ set quotient 1098 ret, 1099 1100 \ Write /mod with HALINV already processed 1101 pc L1 le, 1102 pc to L2 ( operand -- ) 1103 wcall, A>) 1104 wcall, @, 1105 wcall, pushret, 1106 xdup, 1107 ( pc ) rTOP pc@>reg, 1108 wcall, branchR, 1109 wjmp, popret, 1110 1111 \ Write /mod with <>) 1112 pc to L3 ( operand -- ) 1113 bic) rTOP rdn) HALINV imm) ,) 1114 xdup, xdup, wcall, @!, 1115 L2 abscall, 1116 wjmp, @!, 1117 1118 xcode /mod, ( operand -- ) 1119 tst) rTOP rn) HALINV imm) ,) 1120 L3 abs>rel b) nz) ,) 1121 L2 absb, 1122 1123 \ Speed-critical words 1124 xcode move ( src dst u -- ) 1125 r2 ppop, r0 ppop, \ r0=src r2=dst 1126 mov) r1 rd) rTOP rm) ,) xdrop, \ r1=u 1127 cmp) r2 rn) 0 imm) ,) 1128 lblmoverange abs>rel b) nz) ,) 1129 ret, 1130 1131 xcode []= ( src dst u -- f ) 1132 r2 ppop, r0 ppop, \ r0=src r2=dst 1133 cmp) rTOP rn) 0 imm) ,) 1134 mov) z) rTOP rd) 1 imm) ,) 1135 return) z) ,) 1136 mov) r1 rd) rTOP rm) ,) \ r1=u 1137 mov) rTOP rd) 0 imm) ,) 1138 pc 1139 ldr) r3 rd) r0 rn) 8b) 1 +i) post) ,) 1140 ldr) r4 rd) r2 rn) 8b) 1 +i) post) ,) 1141 cmp) r3 rn) r4 rm) ,) 1142 return) nz) ,) 1143 sub) r1 rdn) 1 imm) f) ,) 1144 ( pc ) abs>rel b) ne) ,) 1145 mov) rTOP rd) 1 imm) ,) 1146 ret, 1147 1148 xcode cidx ( c a u -- ?idx f ) 1149 r0 ppop, \ r0=a rTOP=u 1150 ldr) r1 rd) rPSP rn) ,) \ r1=c 1151 mov) r2 rd) 0 imm) ,) \ r2=i 1152 pc 1153 ldr) r3 rd) r0 rn) 8b) 1 +i) post) ,) 1154 cmp) r3 rn) r1 rm) ,) 1155 str) z) r2 rd) rPSP rn) ,) 1156 mov) z) rTOP rd) 1 imm) ,) 1157 return) z) ,) 1158 add) r2 rdn) 1 imm) ,) 1159 sub) rTOP rdn) 1 imm) f) ,) 1160 ( pc ) abs>rel b) nz) ,) 1161 xnip, 1162 mov) rTOP rd) 0 imm) ,) 1163 ret, 1164 1165 \ Interpret loop 1166 xcode ; ximm 1167 wcall, popret, 1168 wcall, exit, 1169 wjmp, [ 1170 1171 pc ," stack underflow" alignhere 1172 xcode stack? 1173 cmp) rPSP rn) PSTOP imm) ,) 1174 return) ls) ,) 1175 ( pc ) r0 pc>reg, 1176 mov) r1 rd) 15 imm) ,) 1177 lblerrmsg abs>rel b) ,) 1178 1179 pc to L1 ( str -- w ) \ find in sys dict 1180 wcall, curword 1181 wcall, sysdict 1182 wcall, find 1183 teq) rTOP rn) 0 imm) ,) 1184 xwordlbl (wnf) abs>rel b) eq) ,) 1185 ret, 1186 1187 pc to L2 ( w -- ) \ findmod+execute 1188 wcall, findmod 1189 wcall, execute 1190 wjmp, stack? 1191 1192 xcode compword ( str -- ) 1193 wcall, parse 1194 cmp) rTOP rn) 0 imm) ,) 1195 xdrop, 1196 xwordlbl litn abs>rel b) ne) ,) \ literal: jump to litn 1197 L1 abscall, 1198 ldr) r0 rd) rTOP rn) 8b) 9 -i) ,) 1199 tst) r0 rn) $80 imm) ,) 1200 L2 abs>rel b) ne) ,) \ immediate? execute 1201 \ compile word 1202 wcall, findmod 1203 wjmp, branchR, 1204 1205 xcode ] 1206 r1 binstart COMPILING movi2, 1207 mov) r0 rd) 1 imm) ,) 1208 str) r0 rd) r1 rn) ,) 1209 pc 1210 wcall, word 1211 wcall, compword 1212 wcall, compiling 1213 cmp) rTOP rn) 0 imm) ,) 1214 xdrop, 1215 ( pc ) abs>rel b) nz) ,) 1216 ret, 1217 1218 xcode runword ( str -- ) 1219 r0 binstart COMPILING movi2, 1220 ldr) r0 rdn) ,) 1221 cmp) r0 rn) 0 imm) ,) 1222 xwordlbl compword abs>rel b) ne) ,) 1223 wcall, parse 1224 cmp) rTOP rn) 0 imm) ,) 1225 xdrop, 1226 return) ne) ,) \ literal: nothing to do 1227 L1 abscall, 1228 L2 abs>rel b) ,) 1229 1230 xcode main pc w>e org SYSDICT + le! 1231 lblmain forward! 1232 pc 1233 wcall, word 1234 wcall, runword 1235 abs>rel b) ,) 1236 1237 pc org BOOTPTR + le!