asma.tal (24710B)
1 ( 2 Asma - an in-Uxn assembler 3 4 This assembler aims to be binary compatible with the output from 5 src/uxnasm.c, but unlike that assembler this one can be run inside Uxn 6 itself! 7 8 Asma is designed to be able to be copy-pasted inside another project, so 9 all its routines are prefixed with "asma-" to prevent clashes with labels 10 used in the incorporating project. The reset vector contains a couple of 11 examples of asma's usage and can be discarded. 12 ) 13 14 ( 15 Asma's public interface. 16 These routines are what are expected to be called from programs that bundle 17 Asma into bigger projects. 18 ) 19 20 @asma-assemble-file ( src-filename* dest-filename* -- ) 21 #01 .File/append DEO 22 DUP2 .File/name DEO2 23 #01 .File/delete DEO 24 ;asma/dest-filename STA2 ;asma/src-filename STA2 25 26 ;asma-init-first-pass JSR2 27 ;asma-flush-ignore ;asma/flush-fn STA2 28 ;asma/src-filename LDA2 ;asma-assemble-file-pass JSR2 29 ;asma/error LDA2 ORA ,&error JCN 30 31 ;asma-init-next-pass JSR2 32 ;asma-flush-to-file ;asma/flush-fn STA2 33 ;asma/dest-filename LDA2 ORA ,&filename-present JCN 34 ;asma-flush-to-console ;asma/flush-fn STA2 35 &filename-present 36 ;asma/src-filename LDA2 ;asma-assemble-file-pass JSR2 37 ;asma/error LDA2 ORA ,&error JCN 38 39 ( flush output buffer ) 40 ;asma-output/ptr LDA2 ;asma-write-buffer SUB2 ;asma/flush-fn LDA2 JSR2 41 42 ;asma-trees/labels ;asma-print-labels JSR2 ( DEBUG ) 43 ;asma-print-line-count JSR2 ( DEBUG ) 44 ;asma-print-heap-usage JSR2 ( DEBUG ) 45 JMP2r 46 47 &error 48 ;asma-print-error JSR2 ( DEBUG ) 49 JMP2r 50 51 ( 52 Debugging routines. These all output extra information to the Console. 53 These can be stripped out to save space, once the references to them are 54 removed. Look for the word DEBUG above to find these references: the lines 55 that contain that word can be deleted to strip out the functionality 56 cleanly. 57 ) 58 59 @asma-print-error ( -- ) 60 .File/name DEI2 ;asma-print-string JSR2 61 ;&line ;asma-print-string JSR2 62 ;asma/line LDA2 ;asma-print-short JSR2 63 #3a .Console/error DEO 64 #20 .Console/error DEO 65 ;asma/error LDA2 ;asma-print-string JSR2 66 #3a .Console/error DEO 67 #20 .Console/error DEO 68 ;asma/orig-token LDA2 ;asma-print-string JSR2 69 #2e .Console/error DEO 70 #0a .Console/error DEO 71 JMP2r 72 73 &line 20 "line 20 00 74 75 @asma-print-line-count ( -- ) 76 ;asma/log-level LDA #01 AND #00 EQU ,&skip JCN 77 ;asma/lines LDA2 ;asma-print-short JSR2 78 ;&lines ;asma-print-string JSR2 79 &skip 80 JMP2r 81 82 &lines [ 20 "lines 20 "of 20 "source 20 "code. 0a 00 ] 83 84 @asma-print-heap-usage ( -- ) 85 ;asma/log-level LDA #08 AND #00 EQU ,&skip JCN 86 ;heap LDA2 ;asma-heap SUB2 ;asma-print-short JSR2 87 ;&str1 ;asma-print-string JSR2 88 ;asma-heap/end ;heap LDA2 SUB2 ;asma-print-short JSR2 89 ;&str2 ;asma-print-string JSR2 90 &skip 91 JMP2r 92 93 &str1 [ 20 "bytes 20 "of 20 "heap 20 "used, 20 00 ] 94 &str2 [ 20 "bytes 20 "free. 0a 00 ] 95 96 @asma-print-sublabels ( incoming-ptr* -- ) 97 LDA2 98 ORAk ,&valid-incoming-ptr JCN 99 POP2 JMP2r 100 101 &valid-incoming-ptr 102 ( left node ) 103 DUP2 ,asma-print-sublabels JSR 104 ( here ) 105 #09 .Console/error DEO 106 DUP2 #0004 ADD2 107 &loop 108 DUP2 INC2 SWP2 LDA 109 DUP #00 EQU ,&end JCN 110 .Console/error DEO 111 ,&loop JMP 112 &end 113 POP 114 #09 .Console/error DEO 115 LDA2 ;asma-print-short JSR2 116 #0a .Console/error DEO 117 118 ( right node ) 119 #0002 ADD2 ,asma-print-sublabels JSR 120 JMP2r 121 122 @asma-print-labels ( incoming-ptr* -- ) 123 ;asma/log-level LDA #04 AND #00 EQU ,&skip JCN 124 LDA2 125 ORAk ,&valid-incoming-ptr JCN 126 &skip 127 POP2 JMP2r 128 129 &valid-incoming-ptr 130 ( left node ) 131 DUP2 ,asma-print-labels JSR 132 ( here ) 133 DUP2 #0004 ADD2 134 LDAk LIT "A LTH ,&loop JCN 135 LDAk LIT "Z GTH ,&loop JCN 136 POP2 137 ,&skip-device-label JMP 138 &loop 139 DUP2 INC2 SWP2 LDA 140 DUP #00 EQU ,&end JCN 141 .Console/error DEO 142 ,&loop JMP 143 &end 144 POP 145 #09 .Console/error DEO 146 LDA2k ;asma-print-short JSR2 147 #0a .Console/error DEO 148 ( subtree ) 149 #0002 ADD2 ;asma-print-sublabels JSR2 150 151 &skip-device-label 152 ( right node ) 153 #0002 ADD2 ,asma-print-labels JSR 154 JMP2r 155 156 @asma-print-string ( ptr* -- ) 157 LDAk DUP ,&keep-going JCN 158 POP POP2 JMP2r 159 160 &keep-going 161 .Console/error DEO 162 INC2 163 ,asma-print-string JMP 164 165 @asma-print-short ( short* -- ) 166 LIT "0 .Console/error DEO 167 LIT "x .Console/error DEO 168 OVR #04 SFT ,&hex JSR 169 SWP #0f AND ,&hex JSR 170 DUP #04 SFT ,&hex JSR 171 #0f AND ,&hex JMP 172 173 &hex 174 #30 ADD DUP #3a LTH ,¬-alpha JCN 175 #27 ADD 176 ¬-alpha 177 .Console/error DEO 178 JMP2r 179 180 ( 181 Initialise the assembler state before loading a file or chunk. 182 ) 183 184 @asma-init-first-pass ( -- ) 185 LIT2 POP2 POP EOR ;asma-parse-opcode/short-flag STA 186 LIT2 POPr POP EOR ;asma-parse-opcode/return-flag STA 187 LIT2 POPk POP EOR ;asma-parse-opcode/keep-flag STA 188 #ff ;asma/pass STA 189 #0000 DUP2k 190 ;asma/error STA2 191 ;asma-trees/labels STA2 192 ;asma-trees/macros STA2 193 ;asma-opcodes/_entry ;asma-trees/opcodes STA2 194 ( fall through ) 195 196 @asma-init-next-pass ( -- ) 197 ;asma/pass LDA INC ;asma/pass STA 198 ;asma-write-buffer ;asma-output/ptr STA2 199 #0100 DUP2 DUP ( 0100 0100 00 ) 200 ;asma/state STA 201 ;asma/addr STA2 202 ;asma/written-addr STA2 203 ;&preamble-end ;&preamble SUB2k ;asma-assemble-chunk JSR2 POP2 POP2 204 JMP2r 205 206 &preamble 207 "%BRK 20 "{ 20 "00 20 "} 20 208 "%[ 20 "{ 20 "} 20 209 "%] 20 "{ 20 "} 20 210 "@on-reset 20 211 &preamble-end 212 213 ( 214 Divide a file up into chunks, and pass each chunk to asma-assemble-chunk. 215 ) 216 217 @asma-assemble-file-pass ( filename-ptr* -- ) 218 ;asma-assemble-chunk #0000 ROT2 ( func* line^ filename* ) 219 ;asma-read-buffer DUP2 ;asma-read-buffer/end ROT2 SUB2 ( func* line^ filename* buf* size^ ) 220 ROT2 ( func* line^ buf* size^ filename* ) 221 ,file-read-chunks JSR 222 223 ;asma/error LDA2 ORA ,&error JCN 224 225 &error 226 POP2 POP2 POP2 POP2 POP2 227 JMP2r 228 229 @file-read-chunks ( func* udata* buf* size* filename* -- func* udata'* buf* size* filename* ) 230 231 #0000 DUP2 ( F* U* B* SZ* FN* OL* OH* / ) 232 &resume 233 ROT2 STH2 ( F* U* B* SZ* OL* OH* / FN* ) 234 ROT2 ( F* U* B* OL* OH* SZ* / FN* ) 235 236 &loop 237 STH2kr .File/name DEO2 ( F* U* B* OL* OH* SZ* / FN* ) 238 STH2k ,ffwd/length STR2 ( F* U* B* OL* OH* / FN* SZ* ) 239 STH2 ( F* U* B* OL* / FN* SZ* OH* ) 240 STH2k ,ffwd/offset STR2 ( F* U* B* / FN* SZ* OH* OL* ) 241 DUP2 ,ffwd/addr STR2 242 ,ffwd JSR 243 SWP2 ( F* B* U* / FN* SZ* OH* OL* ) 244 ROT2k NIP2 ( F* B* U* B* F* / FN* SZ* OH* OL* ) 245 OVR2 .File/read DEO2 ( F* B* U* B* F* / FN* SZ* OH* OL* ) 246 .File/success DEI2 SWP2 ( F* B* U* B* length* F* / FN* SZ* OH* OL* ) 247 JSR2 ( F* B* U'* done-up-to* / FN* SZ* OH* OL* ) 248 ROT2 SWP2 ( F* U'* B* done-up-to* / FN* SZ* OH* OL* ) 249 SUB2k NIP2 ( F* U'* B* -done-length* / FN* SZ* OH* OL* ) 250 ORAk ,¬-end JCN ( F* U'* B* -done-length* / FN* SZ* OH* OL* ) 251 252 POP2 POP2r POP2r ( F* U'* B* / FN* SZ* ) 253 STH2r STH2r ( F* U'* B* SZ* FN* / ) 254 JMP2r 255 256 ¬-end 257 STH2r SWP2 ( F* U'* B* OL* -done-length* / FN* SZ* OH* ) 258 LTH2k JMP INC2r ( F* U'* B* OL* -done-length* / FN* SZ* OH'* ) 259 SUB2 ( F* U'* B* OL'* / FN* SZ* OH'* ) 260 STH2r STH2r ( F* U'* B* OL'* OH'* SZ* / FN* ) 261 ,&loop JMP 262 263 @ffwd 264 LIT2 &length $2 265 LIT2 &offset $2 266 267 &coarse ( length* offset* ) 268 GTH2k ,&fine JCN 269 OVR2 .File/length DEO2 270 ,&addr LDR2 .File/read DEO2 271 OVR2 SUB2 272 ,&coarse JMP 273 274 &fine ( length* offset* ) 275 .File/length DEO2 ( length* ) 276 ,&addr LDR2 .File/read DEO2 277 .File/length DEO2 ( ) 278 JMP2r 279 280 &addr $2 281 282 283 ( 284 Assemble a chunk of source code, which begins with whitespace or the start 285 of a token and is divided up into tokens separated by whitespace. If the 286 chunk ends with whitespace, assembled-up-to-ptr* will equal ptr* + len* and 287 every token in the chunk will have been assembled. If the chunk ends with a 288 non-whitespace character, assembled-up-to-ptr* will point to the beginning 289 of the last token in the chunk. 290 ) 291 292 @asma-assemble-chunk ( line^ chunk* len^ -- line^ assembled-up-to-chunk* ) 293 ROT2 STH2 ( chunk* len^ / line^ ) 294 OVR2 ADD2 ( chunk* end-chunk* / line^ ) 295 OVR2 ;asma-read-buffer EQU2 STH 296 DUP2 ;asma-read-buffer/end NEQ2 297 STHr AND ;asma/eof STA 298 SWP2 STH2k ( end-chunk* chunk* / line^ start-of-token* ) 299 300 &loop ( end-chunk* char* / line^ start-of-token* ) 301 LDAk #21 LTH ,&whitespace JCN 302 INC2 ,&loop JMP 303 304 &whitespace ( end-chunk* ws-char* / line^ start-of-token* ) 305 GTH2k ,&within-chunk JCN 306 ;asma/eof LDA ,&eof JCN 307 308 ( reached the end of the chunk, start-of-token* is where we assembled up to ) 309 POP2 POP2 STH2r STH2r SWP2 JMP2r 310 311 &within-chunk ( end-chunk* ws-char* / line^ start-of-token* ) 312 LDAk #0a NEQ ( end-chunk* ws-char* not-newline / line^ start-of-token* ) 313 #00 OVR2 STA 314 STH2r ,asma-assemble-token JSR ( end-chunk* ws-char* not-newline / line^ ) 315 ;asma/error LDA2 ORA ,&error JCN 316 ,¬-newline JCN 317 ,asma/lines LDR2 INC2 ,asma/lines STR2 318 ¬-newline ( end-chunk* ws-char* / line^ ) 319 ;asma/break LDA ,&break JCN 320 INC2 STH2k ( end-chunk* start-of-token* / line^ start-of-token* ) 321 ,&loop JMP 322 323 &break ( end-chunk* ws-char* / line^ ) 324 ( the read buffer has been invalidated, ws-char* plus one is where we assembled up to ) 325 ;asma/break LDA #01 SUB ;asma/break STA 326 INC2 NIP2 ( assembled-up-to-ptr* / line^ ) 327 STH2r SWP2 JMP2r 328 329 &error ( end-chunk* ws-char* not-newline / line^ ) 330 ( return no progress with assembly to make file-read-chunks exit ) 331 POP POP2 POP2 332 STH2kr ;asma/line STA2 333 STH2r ;asma-read-buffer 334 JMP2r 335 336 &eof ( end-chunk* ws-char* / line^ start-of-token* ) 337 ( reached the end of file, end-chunk* is safe to write since the buffer is bigger ) 338 ( return no progress with assembly to make file-read-chunks exit ) 339 POP2 ( end-chunk* / line^ start-of-token* ) 340 #00 ROT ROT STA ( / line^ start-of-token* ) 341 STH2r ,asma-assemble-token JSR ( / line^ ) 342 STH2r ;asma-read-buffer JMP2r 343 344 @asma [ 345 &pass $1 &state $1 &line $2 &lines $2 &break $1 &eof $1 346 &comment-level $1 347 &token $2 &orig-token $2 348 &addr $2 &written-addr $2 &flush-fn $2 349 &src-filename $2 &dest-filename $2 350 &error $2 &log-level $1 351 ] 352 @asma-trees [ &labels $2 ¯os $2 &opcodes $2 &scope $2 ] 353 354 ( 355 The main routine to assemble a single token. 356 asma/state contains several meaningful bits: 357 0x02 we are in a comment, 358 0x04 we are in a macro body, 359 0x08 we are in a macro body that we are ignoring 360 (because the macro was already defined in a previous pass). 361 Since 0x08 never appears without 0x04, the lowest bit set in asma/state is 362 always 0x00, 0x02, or 0x04, which is very handy for use with jump tables. 363 The lowest bit set can be found easily by #00 (n) SUBk AND. 364 ) 365 366 @asma-assemble-token ( string-ptr* -- ) 367 DUP2 ;asma/token STA2 368 DUP2 ;asma/orig-token STA2 369 LDAk ,¬-empty JCN 370 POP2 371 JMP2r 372 373 ¬-empty ( token* / ) 374 ( truncate to one char long ) 375 INC2 ( end* / ) 376 STH2k LDAkr ( end* / end* char ) 377 STH2k ( end* / end* char end* ) 378 LITr 00 STH2 ( / end* char end* 00 end* ) 379 STAr ( / end* char end* ) 380 381 #00 ;asma/state LDA SUBk AND ( tree-offset* / end* ) 382 DUP2 ;&first-char-trees ADD2 ( tree-offset* incoming-ptr* / end* ) 383 ;asma-traverse-tree JSR2 384 385 ( restore truncated char ) 386 STAr 387 388 ,¬-found JCN 389 390 ( tree-offset* token-routine-ptr* / end* ) 391 STH2r ;asma/token STA2 392 NIP2 LDA2 393 JMP2 ( tail call ) 394 395 ¬-found ( tree-offset* dummy* / end* ) 396 POP2 POP2r 397 ;&body-routines ADD2 LDA2 398 JMP2 ( tail call ) 399 400 &first-char-trees 401 :asma-first-char-normal/_entry 402 :asma-first-char-comment/_entry 403 :asma-first-char-macro/_entry 404 405 &body-routines 406 :asma-normal-body 407 :asma-ignore 408 :asma-macro-body 409 410 @asma-parse-hex-digit ( charcode -- 00-0f if valid hex 411 OR 10-ff otherwise ) 412 DUP #3a LTH ,&digit JCN 413 DUP #60 GTH ,&letter JCN 414 JMP2r 415 416 &digit 417 #30 SUB 418 JMP2r 419 420 &letter 421 #57 SUB 422 JMP2r 423 424 @asma-parse-hex-string ( strict -- value* 06 if valid hex and (length == 4 or (length == 3 and not strict)) 425 OR value* 03 if valid hex and (length == 2 or (length == 1 and not strict)) 426 OR 00 otherwise ) 427 STH 428 ;asma/token LDA2 DUP2 ,strlen JSR ( token* length^ ) 429 DUP STHr AND ,&fail2 JCN 430 DUP2 #0004 GTH2 ,&fail2 JCN 431 ORAk #00 EQU ,&fail2 JCN 432 #0002 GTH2 ROT ROT 433 LIT2r 0000 434 435 &loop 436 LDAk 437 DUP ,¬-end JCN 438 POP POP2 439 STH2r ROT INC DUPk ADD ADD 440 JMP2r 441 442 ¬-end 443 ,asma-parse-hex-digit JSR 444 DUP #f0 AND ,&fail JCN 445 LITr 40 SFT2r 446 LITr 00 STH ADD2r 447 INC2 448 ,&loop JMP 449 450 &fail 451 POP2r 452 &fail2 453 POP2 POP2 454 #00 455 JMP2r 456 457 ~projects/library/string.tal 458 459 @asma-traverse-tree ( incoming-ptr* -- binary-ptr* 00 if key found 460 OR node-incoming-ptr* 01 if key not found ) 461 ;asma/token LDA2 462 ( fall through to traverse-tree ) 463 464 ~projects/library/binary-tree.tal 465 466 @asma-parse-opcode ( -- byte 00 if valid opcode 467 OR 01 otherwise ) 468 ;asma/token LDA2 469 DUP2 ,strlen JSR #0003 LTH2 ,&too-short JCN 470 471 ( truncate to three chars long ) 472 #0003 ADD2 ( end* / ) 473 STH2k LDAkr ( end* / end* char ) 474 STH2k ( end* / end* char end* ) 475 LITr 00 STH2 ( / end* char end* 00 end* ) 476 STAr ( / end* char end* ) 477 478 ;asma-trees/opcodes ;asma-traverse-tree JSR2 479 STAr 480 ,¬-found JCN 481 482 ;asma-opcodes/_disasm SUB2 #03 SFT2 ( 00 byte / end* ) 483 DUP #00 EQU ,&set-keep JCN ( force keep flag for LIT ) 484 &loop 485 LDAkr STHr LIT2r 0001 ADD2r ( 00 byte char / end* ) 486 DUP ,¬-end JCN 487 POP POP2r 488 SWP 489 JMP2r 490 491 ¬-end 492 DUP LIT "2 NEQ ,¬-two JCN 493 POP LIT &short-flag $1 ORA ,&loop JMP 494 495 ¬-two 496 DUP LIT "r NEQ ,¬-return JCN 497 POP LIT &return-flag $1 ORA ,&loop JMP 498 499 ¬-return 500 LIT "k NEQ ,¬-keep JCN 501 &set-keep LIT &keep-flag $1 ORA ,&loop JMP 502 503 ¬-keep ( 00 byte / end* ) 504 ¬-found ( incoming-ptr* / end* ) 505 POP2r 506 &too-short ( token* / ) 507 POP2 #01 508 JMP2r 509 510 @asma-write-lit ( byte -- ) 511 LIT LIT ,asma-write-byte JSR 512 ,asma-write-byte JSR 513 JMP2r 514 515 @asma-advance-addr ( delta* -- ) 516 ;asma/addr LDA2k ( delta* ptr* value* ) 517 ROT2 ADD2 ( ptr* new-value* ) 518 SWP2 STA2 519 JMP2r 520 521 @asma-write-short ( short -- ) 522 SWP 523 ,asma-write-byte JSR 524 ( fall through ) 525 526 @asma-write-byte ( byte -- ) 527 ;asma/addr LDA2 ;asma/written-addr LDA2 528 LTH2k ,&rewound JCN 529 &loop 530 EQU2k ,&ready JCN 531 #00 ,&write JSR 532 INC2 533 ,&loop JMP 534 535 &rewound 536 ;asma-msg-rewound ;asma/error STA2 537 POP2 POP2 POP JMP2r 538 539 &ready 540 POP2 INC2 541 DUP2 ;asma/addr STA2 542 ;asma/written-addr STA2 543 544 &write 545 ,asma-output/ptr LDR2 546 DUP2 ;asma-write-buffer/end EQU2 ,&flush JCN 547 &after-flush 548 STH2k STA 549 STH2r INC2 ,asma-output/ptr STR2 550 JMP2r 551 552 &flush ( ptr* -- start-of-buffer* ) 553 ;asma-write-buffer SUB2k ( ptr* start* len* ) 554 ;asma/flush-fn LDA2 JSR2 555 NIP2 ( start* ) 556 ,&after-flush JMP 557 558 @asma-output [ &ptr $2 ] 559 560 @asma-flush-ignore ( len* -- ) 561 POP2 562 JMP2r 563 564 @asma-flush-to-file ( len* -- ) 565 .File/length DEO2 566 ;asma/dest-filename LDA2 .File/name DEO2 567 ;asma-write-buffer .File/write DEO2 568 JMP2r 569 570 @asma-flush-to-console ( len* -- ) 571 ORAk ,¬-empty JCN 572 POP2 JMP2r 573 574 ¬-empty 575 ;asma-write-buffer DUP2 ROT2 ADD2 SWP2 ( end* ptr* ) 576 &loop ( end* ptr* ) 577 LDAk .Console/write DEO 578 INC2 579 GTH2k ,&loop JCN 580 581 POP2 POP2 582 JMP2r 583 584 ~projects/library/heap.tal 585 586 ( 587 First character routines. 588 The following routines (that don't have a FORTH-like signature) are called 589 to deal with tokens that begin with particular first letters, or (for 590 -body routines) tokens that fail to match any first letter in their tree. 591 ) 592 593 @asma-comment-more 594 ;asma/token LDA2 ;strlen JSR2 ORA ,asma-ignore JCN 595 @asma-comment-start 596 ;asma/comment-level LDAk INC ROT ROT STA 597 ;asma/state LDA #02 ORA ;asma/state STA 598 @asma-ignore 599 JMP2r 600 601 @asma-comment-less 602 ;asma/token LDA2 ;strlen JSR2 ORA ,asma-ignore JCN 603 ;asma/comment-level LDAk #01 SUB DUP SWP2 STA ,asma-ignore JCN 604 @asma-comment-end 605 ;asma/state LDA #0c AND ;asma/state STA 606 JMP2r 607 608 @asma-macro-define 609 ;asma/pass LDA ,&ignore-macro JCN 610 611 ;asma-trees/macros ;asma-traverse-tree JSR2 ,¬-exist JCN 612 POP2 613 ;asma-msg-macro ;asma/error STA2 614 JMP2r 615 616 ¬-exist ( incoming-ptr* ) 617 ( define macro by creating new node ) 618 ;heap LDA2 SWP2 STA2 619 #0000 ;append-heap-short JSR2 ( less-than pointer ) 620 #0000 ;append-heap-short JSR2 ( greater-than pointer ) 621 ;asma/token LDA2 ;append-heap-string JSR2 ( key ) 622 ;asma/state LDA #04 ORA ;asma/state STA 623 JMP2r 624 625 &ignore-macro 626 ;asma/state LDA #0c ORA ;asma/state STA 627 JMP2r 628 629 @asma-macro-body 630 ;asma/state LDA #08 AND ,&skip JCN 631 ;asma/token LDA2 ;append-heap-string JSR2 632 &skip 633 JMP2r 634 635 @asma-macro-end 636 #00 ;append-heap-byte JSR2 637 ;asma/state LDA #02 AND ;asma/state STA 638 JMP2r 639 640 @asma-label-define 641 ;asma-trees/labels ,asma-label-helper JSR 642 ,&already-existed JCN 643 644 #0000 ;append-heap-short JSR2 ( data2: subtree incoming ptr ) 645 646 &already-existed 647 #0002 ADD2 ;asma-trees/scope STA2 648 JMP2r 649 650 @asma-sublabel-define 651 ;asma-trees/scope LDA2 ,asma-label-helper JSR 652 POP POP2 653 JMP2r 654 655 @asma-label-helper ( incoming-ptr* -- binary-ptr* 01 if label existed already 656 OR binary-ptr* 00 if label was created ) 657 ;asma-traverse-tree JSR2 658 ,&new-label JCN 659 660 ( label already exists ) 661 LDA2k ;asma/addr LDA2 EQU2 ,&address-match JCN 662 ;asma-msg-redefined ;asma/error STA2 663 664 &address-match 665 #01 JMP2r 666 667 &new-label ( incoming-ptr* ) 668 ( define label by creating new node ) 669 ;heap LDA2 SWP2 STA2 670 #0000 ;append-heap-short JSR2 ( less-than pointer ) 671 #0000 ;append-heap-short JSR2 ( greater-than pointer ) 672 ;asma/token LDA2 ;append-heap-string JSR2 ( key ) 673 674 ;heap LDA2 675 676 ;asma/addr LDA2 ;append-heap-short JSR2 ( data1: address ) 677 #00 JMP2r 678 679 @asma-pad-absolute 680 #0000 ;asma/addr STA2 681 ( fall through ) 682 683 @asma-pad-relative 684 #00 ;asma-parse-hex-string JSR2 685 ,&valid JCN 686 687 ;asma-msg-hex ;asma/error STA2 688 JMP2r 689 690 &valid 691 ;asma-advance-addr JMP2 ( tail call ) 692 693 @asma-raw-word 694 ;asma/token LDA2 695 696 &loop 697 LDAk 698 DUP ,¬-end JCN 699 700 POP POP2 701 JMP2r 702 703 ¬-end 704 ;asma-write-byte JSR2 705 INC2 706 ,&loop JMP 707 708 @asma-literal-abs-addr 709 LIT LIT2 ;asma-write-byte JSR2 710 ( fall through ) 711 712 @asma-abs-addr 713 ,asma-addr-helper JSR 714 ;asma-write-short JMP2 ( tail call ) 715 716 @asma-literal-zero-addr 717 LIT LIT ;asma-write-byte JSR2 718 ( fall through ) 719 720 @asma-zero-addr 721 ,asma-addr-helper JSR 722 ;asma-write-byte JSR2 723 724 ,¬-zero-page JCN 725 JMP2r 726 727 ¬-zero-page 728 ;asma/pass LDA #00 EQU 729 ;asma/error LDA2 ORA 730 ORA ,&ignore-error JCN 731 ;asma-msg-zero-page ;asma/error STA2 732 &ignore-error 733 JMP2r 734 735 @asma-jci 736 #20 ,asma-jxi JMP ( tail call ) 737 738 @asma-jmi 739 #40 740 ( fall through ) 741 742 @asma-jxi 743 ;asma-write-byte JSR2 744 ,asma-addr-helper JSR 745 ;asma/addr LDA2 SUB2 746 #0002 SUB2 747 ;asma-write-short JMP2 ( tail call ) 748 749 @asma-literal-rel-addr 750 LIT LIT ;asma-write-byte JSR2 751 ( fall through ) 752 753 @asma-rel-addr 754 ,asma-addr-helper JSR 755 ;asma/addr LDA2 SUB2 756 #0002 SUB2 757 758 DUP2 #0080 LTH2 STH 759 DUP2 #ff7f GTH2 STHr ORA ,&in-bounds JCN 760 761 POP2 762 ;asma-msg-relative ;asma/error STA2 763 JMP2r 764 765 &in-bounds 766 ;asma-write-byte JSR2 767 POP 768 JMP2r 769 770 @asma-addr-helper ( -- addr* ) 771 ;asma/token LDA2 LDAk #26 NEQ ,¬-local JCN 772 INC2 ;asma/token STA2 773 ;asma-trees/scope LDA2 774 ,&final-lookup JMP 775 776 ¬-local ( token* ) 777 LDAk 778 DUP ,¬-end JCN 779 POP POP2 780 ;asma-trees/labels 781 ,&final-lookup JMP 782 783 ¬-end ( token* char ) 784 #2f EQU ,&found-slash JCN 785 INC2 786 ,¬-local JMP 787 788 &found-slash ( token* ) 789 DUP2 #00 ROT ROT STA 790 ;asma-trees/labels ;asma-traverse-tree JSR2 STH 791 SWP2 DUP2 #2f ROT ROT STA 792 STHr ,¬-found2 JCN 793 ( token* binary-ptr* ) 794 INC2 ;asma/token STA2 795 #0002 ADD2 796 797 &final-lookup ( addr-offset* incoming-ptr* ) 798 ;asma-traverse-tree JSR2 799 ,¬-found JCN 800 LDA2 801 JMP2r 802 803 ¬-found2 ( dummy* dummy* ) 804 POP2 805 ¬-found ( dummy* ) 806 POP2 807 808 ;asma/pass LDA #00 EQU ,&ignore-error JCN 809 ;asma-msg-label ;asma/error STA2 810 &ignore-error 811 812 ;asma/addr LDA2 813 JMP2r 814 815 @asma-literal-hex 816 #01 ;asma-parse-hex-string JSR2 JMP 817 ( hex invalid ) ,&invalid JMP 818 ( hex byte ) ,asma-byte-helper JMP 819 ( hex short ) ,asma-short-helper JMP 820 821 &invalid 822 ;asma-msg-hex ;asma/error STA2 823 JMP2r 824 825 @asma-byte-helper ( dummy value -- ) 826 ;asma-write-lit JSR2 827 POP 828 JMP2r 829 &raw 830 ;asma-write-byte JSR2 831 POP 832 JMP2r 833 834 @asma-short-helper ( value* -- ) 835 LIT LIT2 ;asma-write-byte JSR2 836 &raw 837 ;asma-write-short JMP2 ( tail call ) 838 839 @asma-normal-body 840 ;asma-parse-opcode JSR2 ,¬-opcode JCN 841 ;asma-write-byte JMP2 ( tail call ) 842 843 ¬-opcode 844 #01 ;asma-parse-hex-string JSR2 JMP 845 ( hex invalid ) ,¬-hex JMP 846 ( hex byte ) ,asma-byte-helper/raw JMP 847 ( hex short ) ,asma-short-helper/raw JMP 848 849 ¬-hex 850 ;asma-trees/macros ;asma-traverse-tree JSR2 ,¬-macro JCN 851 852 ¯o-loop 853 LDAk ,&keep-going JCN 854 POP2 855 JMP2r 856 857 &keep-going 858 DUP2k ;strlen JSR2 INC2 ADD2 859 SWP2 ;asma-assemble-token JSR2 ;asma/error LDA2 ORA ,¯o-error JCN 860 ,¯o-loop JMP 861 862 ¯o-error 863 POP2 864 JMP2r 865 866 ¬-macro 867 POP2 868 #60 ;asma-jxi JMP2 ( tail call ) 869 870 @asma-include 871 ;heap LDA2 872 ;asma/token LDA2 ;append-heap-string JSR2 873 ;asma-assemble-file-pass JSR2 874 ;asma/break LDAk INC ROT ROT STA 875 JMP2r 876 877 ( Error messages ) 878 879 @asma-msg-hex "Invalid 20 "hexadecimal 00 880 @asma-msg-zero-page "Address 20 "not 20 "in 20 "zero 20 "page 00 881 @asma-msg-relative "Address 20 "outside 20 "range 00 882 @asma-msg-label "Label 20 "not 20 "found 00 883 @asma-msg-macro "Macro 20 "already 20 "exists 00 884 @asma-msg-rewound "Memory 20 "overwrite 00 885 @asma-msg-redefined "Label 20 "redefined 00 886 887 ( trees ) 888 889 ( --- 8< ------- 8< --- cut here --- 8< ------- 8< --- ) 890 ( automatically generated code below ) 891 ( see etc/asma.moon for instructions ) 892 893 ( label less greater key binary 894 than than string data ) 895 896 @asma-first-char-comment 897 &28 $2 $2 "( 00 :asma-comment-more 898 &_entry :&28 $2 ") 00 :asma-comment-less 899 900 @asma-first-char-macro 901 &28 $2 $2 "( 00 :asma-comment-start 902 &29 :&28 $2 ") 00 :asma-comment-end 903 &_entry :&29 :&7d "{ 00 :asma-ignore 904 &7d $2 $2 "} 00 :asma-macro-end 905 906 @asma-first-char-normal 907 &21 $2 $2 "! 00 :asma-jmi 908 &22 :&21 $2 "" 00 :asma-raw-word 909 &23 :&22 :&25 "# 00 :asma-literal-hex 910 &24 $2 $2 "$ 00 :asma-pad-relative 911 &25 :&24 $2 "% 00 :asma-macro-define 912 &26 :&23 :&2c 26 00 ( & ) :asma-sublabel-define 913 &28 $2 $2 "( 00 :asma-comment-start 914 &29 :&28 $2 ") 00 :asma-comment-end 915 &2c :&29 :&2d ", 00 :asma-literal-rel-addr 916 &2d $2 $2 "- 00 :asma-zero-addr 917 &_entry :&26 :&5f ". 00 :asma-literal-zero-addr 918 &3a $2 $2 ": 00 :asma-abs-addr 919 &3b :&3a $2 "; 00 :asma-literal-abs-addr 920 &3d :&3b :&40 "= 00 :asma-abs-addr 921 &3f $2 $2 "? 00 :asma-jci 922 &40 :&3f $2 "@ 00 :asma-label-define 923 &5f :&3d :&7d "_ 00 :asma-rel-addr 924 &7b $2 $2 "{ 00 :asma-ignore 925 &7c :&7b $2 "| 00 :asma-pad-absolute 926 &7d :&7c :&7e "} 00 :asma-ignore 927 &7e $2 $2 "~ 00 :asma-include 928 929 @asma-opcodes 930 &_entry :>H :&ROT &_disasm "LIT 00 931 &INC $2 $2 "INC 00 932 &POP $2 $2 "POP 00 933 &NIP :&MUL :&OVR "NIP 00 934 &SWP $2 $2 "SWP 00 935 &ROT :&NIP :&STR "ROT 00 936 &DUP $2 $2 "DUP 00 937 &OVR :&ORA :&POP "OVR 00 938 &EQU $2 $2 "EQU 00 939 &NEQ $2 $2 "NEQ 00 940 >H :&DIV :&JSR "GTH 00 941 <H $2 $2 "LTH 00 942 &JMP $2 $2 "JMP 00 943 &JCN :&INC :&JMP "JCN 00 944 &JSR :&JCN :&LDR "JSR 00 945 &STH $2 $2 "STH 00 946 &LDZ $2 $2 "LDZ 00 947 &STZ $2 $2 "STZ 00 948 &LDR :&LDA :&LDZ "LDR 00 949 &STR :&STA :&SUB "STR 00 950 &LDA $2 $2 "LDA 00 951 &STA :&SFT :&STH "STA 00 952 &DEI :&AND :&DEO "DEI 00 953 &DEO $2 $2 "DEO 00 954 &ADD $2 $2 "ADD 00 955 &SUB :&STZ :&SWP "SUB 00 956 &MUL :<H :&NEQ "MUL 00 957 &DIV :&DEI :&EOR "DIV 00 958 &AND :&ADD $2 "AND 00 959 &ORA $2 $2 "ORA 00 960 &EOR :&DUP :&EQU "EOR 00 961 &SFT $2 $2 "SFT 00 962