From 5833a992606c5cc88325e88854e102156e07ad2e Mon Sep 17 00:00:00 2001 From: Andrew Alderwick Date: Sat, 24 Apr 2021 10:50:21 +0100 Subject: [PATCH] Ported asma to new assembler syntax --- etc/uxambly-translate.moon | 9 +- projects/software/asma.usm | 795 +++++++++++++++++++------------------ 2 files changed, 413 insertions(+), 391 deletions(-) diff --git a/etc/uxambly-translate.moon b/etc/uxambly-translate.moon index dcb618b..3b84f3d 100644 --- a/etc/uxambly-translate.moon +++ b/etc/uxambly-translate.moon @@ -64,9 +64,11 @@ grammar = P { labeldef: C P'@' * V'label' relative: (P'^' / -> ',') * (C(V'label') / (s) -> (s\gsub '%$', '&')) sublabel: (P'$' / -> '&') * (C(V'label') / (s) -> (s\gsub '%$', '&')) - data: C P'[' * (1-P']') ^ 0 * P']' + data: C(P'[') * V'ws' * (V'data_item' * V'ws') ^ 0 * C(P']') macro: C(P'%' * V'name' * V'ws' * P'{') * V'ws' * (V'atom' * V'ows') ^ 0 * C P'}' macroref: C V'name' + data_item: C(V'hex' * #V'ws') + V'data_string' + data_string: C((1 - S' \n\t') ^ 1 - P']') / (s) -> '"', s } translate = (_filename) -> @@ -81,7 +83,7 @@ translate = (_filename) -> error 'no match' filename = filename\gsub 'attic', 'auto' f = assert io.open filename, 'w' - f\write (table.concat(t)\gsub(' +\n', '\n')\gsub(' +', ' ')) + f\write table.concat(t) f\close! f = assert io.popen 'bin/assembler %s bin/boot.rom'\format filename for l in f\lines! @@ -91,10 +93,9 @@ translate = (_filename) -> f\close! os.exit 0 -translate 'attic/software/left.usm' +translate 'attic/software/assembler.usm' os.exit 0 -translate 'attic/software/assembler.usm' translate 'attic/tests/opcodes.usm' translate 'attic/tests/basics.usm' diff --git a/projects/software/asma.usm b/projects/software/asma.usm index 506e451..cbbb0c0 100644 --- a/projects/software/asma.usm +++ b/projects/software/asma.usm @@ -1,5 +1,4 @@ -;tree { search-key 2 max-key-len 1 } -;assembler { pass 1 state 1 token 2 scope-len 1 scope 80 heap 2 addr 2 subtree 2 field_size 2 var_size 2 field 2 } +( asma: in-Uxn assembler (not working yet, in progress) ) %HCF { #0000 DIV } %SHORT_FLAG { #20 } @@ -7,43 +6,50 @@ ( devices ) -|0100 ;System { vector 2 pad 6 r 2 g 2 b 2 } -|0110 ;Console { vector 2 pad 6 char 1 byte 1 short 2 string 2 } -|0120 ;Screen { vector 2 width 2 height 2 pad 2 x 2 y 2 addr 2 color 1 } -|0130 ;Audio { wave 2 envelope 2 pad 4 volume 1 pitch 1 play 1 value 2 delay 2 finish 1 } -|0140 ;Controller { vector 2 button 1 key 1 } -|0160 ;Mouse { vector 2 x 2 y 2 state 1 chord 1 } -|0170 ;File { vector 2 success 2 offset 2 pad 2 name 2 length 2 load 2 save 2 } -|01a0 ;DateTime { year 2 month 1 day 1 hour 1 minute 1 second 1 dotw 1 doty 2 isdst 1 refresh 1 } +|00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ] +|10 @Console [ &vector $2 &pad $6 &char $1 &byte $1 &short $2 &string $2 ] +|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ] +|30 @Audio [ &wave $2 &envelope $2 &pad $4 &volume $1 &pitch $1 &play $1 &value $2 &delay $2 &finish $1 ] +|40 @Controller [ &vector $2 &button $1 &key $1 ] +|60 @Mouse [ &vector $2 &x $2 &y $2 &state $1 &chord $1 ] +|70 @File [ &vector $2 &success $2 &offset $2 &pad $2 &name $2 &length $2 &load $2 &save $2 ] +|a0 @DateTime [ &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1 &refresh $1 ] + +( variables ) + +|0000 + +@tree [ &search-key $2 &max-key-len $1 ] +@assembler [ &pass $1 &state $1 &token $2 &scope-len $1 &scope $80 &heap $2 &addr $2 &subtree $2 &field_size $2 &var_size $2 &field $2 ] ( vectors ) -|0200 ^RESET JMP +|0100 ,RESET JMP @RESET - ,assembler-heap-start =assembler.heap + ;assembler-heap-start .assembler/heap POK2 - ,$read-filename ^assemble-file JSR + ;&read-filename ,assemble-file JSR HCF HCF - $read-filename [ projects/software/noodle.usm 00 ] + &read-filename [ "projects/software/noodle.usm 00 ] @assemble-file ( filename-ptr* -- ) #0000 - $loop - OVR2 =File.name - DUP2 =File.offset - #0600 =File.length - #f000 DUP2 DUP2 =File.load - ~File.success DUP2 #0000 EQU2 ^$end JNZ - ^assemble-chunk JSR + &loop + OVR2 .File/name DEO2 + DUP2 .File/offset DEO2 + #0600 .File/length DEO2 + #f000 DUP2 DUP2 .File/load DEO2 + .File/success DEI2 DUP2 #0000 EQU2 ,&end JNZ + ,assemble-chunk JSR SUB2 SUB2 - ^$loop JMP + ,&loop JMP - $end + &end POP2 POP2 POP2 POP2 POP2 JMP2r @@ -53,162 +59,162 @@ OVR2 ADD2 STH2 #0001 SUB2 - $per-token + &per-token DUP2 STH2 - $loop + &loop #0001 ADD2 - DUP2 PEK2 - #20 GTH ^$loop JNZ + DUP2 GET + #20 GTH ,&loop JNZ - DUP2 OVR2r STH2r LTS2 ^$valid JNZ + DUP2 OVR2r STH2r LTS2 ,&valid JNZ SWP2r POP2r POP2 STH2r #0001 ADD2 JMP2r - $valid - DUP2 PEK2 #00 OVR2 POK2 - STH2r #0001 ADD2 ^assemble-token JSR - ^$per-token JNZ + &valid + DUP2 GET #00 OVR2 PUT + STH2r #0001 ADD2 ,assemble-token JSR + ,&per-token JNZ POP2r JMP2r @assemble-macro ( macro-ptr* -- ) - DUP2 ,strlen JSR2 DUP2 #0000 EQU2 ^$end JNZ - OVR2 ^assemble-token JSR + DUP2 ;strlen JSR2 DUP2 #0000 EQU2 ,&end JNZ + OVR2 ,assemble-token JSR ADD2 #0001 ADD2 - ^assemble-macro JMP + ,assemble-macro JMP - $end + &end POP2 POP2 JMP2r @assemble-token ( string-ptr* -- ) ( get location of tree ) DUP2 - ,state-machine-pointers #00 ~assembler.state ,highest-bit JSR2 #0004 MUL2 ADD2 + ;state-machine-pointers #00 .assembler/state PEK ;highest-bit JSR2 #0004 MUL2 ADD2 DUP2 STH2 ( see if first char is recognised ) - SWP2 #01 ,traverse-tree JSR2 - ^$not-found JNZ + SWP2 #01 ;traverse-tree JSR2 + ,¬-found JNZ ( skip first character of token ) - SWP2 #0001 ADD2 =assembler.token + SWP2 #0001 ADD2 .assembler/token POK2 ( tail call handling function defined in tree ) POP2r JMP2 - $not-found + ¬-found ( not interested in incoming-ptr ) POP2 - =assembler.token + .assembler/token POK2 ( tail call default handling function defined in state-machine-pointers ) - LIT2r [ 0002 ] ADD2r LDR2r + LIT2r [ 0002 ] ADD2r GET2r JMP2r @parse-hex-length ( string-ptr* -- value 01 if one or two hex digits OR 00 otherwise ) - DUP2 #0001 ADD2 PEK2 ^parse-hex-string-try-two JNZ - PEK2 ^parse-hex-digit JSR DUP #04 SFT ^parse-hex-string-fail1 JNZ + DUP2 #0001 ADD2 GET ,parse-hex-string/try-two JNZ + GET ,parse-hex-digit JSR DUP #04 SFT ,parse-hex-string/fail1 JNZ #01 JMP2r @parse-hex-string ( string-ptr* -- value* 02 if four hex digits OR value 01 if two hex digits OR 00 otherwise ) - DUP2 #0004 ADD2 PEK2 #00 EQU ^$try-four JNZ - $try-two - DUP2 #0002 ADD2 PEK2 ^$fail2 JNZ - $known-two - DUP2 PEK2 ^parse-hex-digit JSR DUP #04 SFT ^$fail3 JNZ ROT ROT - #0001 ADD2 PEK2 ^parse-hex-digit JSR DUP #04 SFT ^$fail2 JNZ + DUP2 #0004 ADD2 GET #00 EQU ,&try-four JNZ + &try-two + DUP2 #0002 ADD2 GET ,&fail2 JNZ + &known-two + DUP2 GET ,parse-hex-digit JSR DUP #04 SFT ,&fail3 JNZ ROT ROT + #0001 ADD2 GET ,parse-hex-digit JSR DUP #04 SFT ,&fail2 JNZ SWP #40 SFT ORA #01 JMP2r - $fail3 POP - $fail2 POP - $fail1 POP #00 JMP2r + &fail3 POP + &fail2 POP + &fail1 POP #00 JMP2r - $try-four - DUP2 #0002 ADD2 ^$known-two JSR ^$maybe-four JNZ - ^$try-two JMP + &try-four + DUP2 #0002 ADD2 ,&known-two JSR ,&maybe-four JNZ + ,&try-two JMP - $maybe-four - ROT ROT ^$known-two JSR ^$four JNZ - ^$fail1 JMP + &maybe-four + ROT ROT ,&known-two JSR ,&four JNZ + ,&fail1 JMP - $four + &four SWP #02 JMP2r @parse-hex-digit ( charcode -- 00-0f if valid hex -- 10-ff otherwise ) - DUP #3a LTH ^$digit JNZ - DUP #60 GTH ^$lowercase JNZ - DUP #40 GTH ^$uppercase JNZ + DUP #3a LTH ,&digit JNZ + DUP #60 GTH ,&lowercase JNZ + DUP #40 GTH ,&uppercase JNZ JMP2r - $digit ( #30 is #00 ) + &digit ( #30 is #00 ) #30 SUB JMP2r - $lowercase ( #61 is #0a ) + &lowercase ( #61 is #0a ) #57 SUB JMP2r - $uppercase ( #41 is #0a ) + &uppercase ( #41 is #0a ) #37 SUB JMP2r @find-opcode ( name* -- byte 00 if valid opcode name OR 01 if not found ) - ,opcodes-tree SWP2 #03 ^traverse-tree JSR - ^$nomatch JNZ - ,opcodes-asm SUB2 #0007 DIV2 + ;opcodes/tree SWP2 #03 ,traverse-tree JSR + ,&nomatch JNZ + ;opcodes/asm SUB2 #0007 DIV2 SWP JMP2r - $nomatch + &nomatch DUP2 EQU2 JMP2r @traverse-tree ( tree-ptr* search-key* max-key-len -- binary-ptr* 00 if key matched OR incoming-ptr* 01 if key not found ) - =tree.max-key-len =tree.search-key + .tree/max-key-len POK .tree/search-key POK2 - $loop - DUP2 LDR2 #0000 NEQ2 ^$valid-node JNZ + &loop + DUP2 GET2 #0000 NEQ2 ,&valid-node JNZ #01 JMP2r - $valid-node - LDR2 DUP2 STH2 #0004 ADD2 ^strcmp-tree JSR - DUP ^$nomatch JNZ + &valid-node + GET2 DUP2 STH2 #0004 ADD2 ,strcmp-tree JSR + DUP ,&nomatch JNZ POP2r JMP2r - $nomatch + &nomatch #07 SFT #02 MUL #00 SWP STH2r ADD2 - ^$loop JMP + ,&loop JMP @strcmp-tree ( node-key* -- order if strings differ OR after-node-key* 00 if strings match ) - ~tree.search-key STH2 - ~tree.max-key-len + .tree/search-key PEK2 STH2 + .tree/max-key-len PEK - $loop ( node-key* key-len in wst, search-key* in rst ) - DUP ^$keep-going JNZ + &loop ( node-key* key-len in wst, search-key* in rst ) + DUP ,&keep-going JNZ ( exhausted key-len, match found ) POP2r JMP2r - $keep-going - #01 OVR2 PEK2 DUP2r PEK2r STHr - DUP2 ORA ^$not-end JNZ + &keep-going + #01 OVR2 GET DUP2r GETr STHr + DUP2 ORA ,¬-end JNZ ( end of C strings, match found ) POP2r POP ROT POP SWP ADD2 #00 JMP2r - $not-end - SUB DUP ^$nomatch JNZ + ¬-end + SUB DUP ,&nomatch JNZ POP SUB LIT2r [ 0001 ] ADD2r STH LIT2 [ 0001 ] ADD2 STHr - ^$loop JMP + ,&loop JMP - $nomatch + &nomatch STH POP2 POP2 STHr POP2r JMP2r @@ -223,126 +229,127 @@ DUP #01 SFT ORA DUP #02 SFT ORA DUP #04 SFT ORA - #1d MUL #05 SFT #00 SWP ,$lookup ADD2 PEK2 + #1d MUL #05 SFT #00 SWP ;&lookup ADD2 GET JMP2r - $lookup + &lookup [ 01 06 02 07 05 04 03 08 ] @memcpy ( src-ptr* dest-ptr* length* -- after-dest-ptr* ) SWP2 STH2 - $loop - DUP2 ORA ^$keep-going JNZ + &loop + DUP2 ORA ,&keep-going JNZ POP2 POP2 STH2r JMP2r - $keep-going + &keep-going #0001 SUB2 - SWP2 DUP2 PEK2 DUP2r STH2r POK2 + SWP2 DUP2 GET DUP2r STH2r PUT #0001 ADD2 SWP2 LIT2r [ 0001 ] ADD2r - ^$loop JMP + ,&loop JMP @strcpy ( src-ptr* dest-ptr* -- after-dest-ptr* ) - OVR2 ^strlen JSR #0001 ADD2 ^memcpy JMP + OVR2 ,strlen JSR #0001 ADD2 ,memcpy JMP @strlen ( string-ptr* -- length* ) DUP2 #0001 SUB2 - $loop + &loop #0001 ADD2 - DUP2 PEK2 ^$loop JNZ + DUP2 GET ,&loop JNZ SWP2 SUB2 JMP2r @append-heap ( string-ptr* -- after-string-ptr* ) - ~assembler.heap ,strcpy JSR2 - DUP2 =assembler.heap + .assembler/heap PEK2 ;strcpy JSR2 + DUP2 .assembler/heap POK2 JMP2r @append-tree ( string-ptr* incoming-ptr* -- binary-data* ) - ~assembler.heap SWP2 STR2 - ,$zero-pointers ~assembler.heap #0004 ^memcpy JSR =assembler.heap - ^append-heap JSR + .assembler/heap PEK2 SWP2 PUT2 + ;&zero-pointers .assembler/heap PEK2 #0004 ,memcpy JSR .assembler/heap POK2 + ,append-heap JSR JMP2r - $zero-pointers [ 0000 0000 ] + &zero-pointers [ 0000 0000 ] @add-label ( label-flags string-ptr* tree-ptr* -- ) - OVR2 #ff ,traverse-tree JSR2 - ^$new-label JNZ + OVR2 #ff ;traverse-tree JSR2 + ,&new-label JNZ ( label already exists, check the flags and addr value ) SWP2 POP2 - DUP2 #0001 ADD2 LDR2 ~assembler.addr EQU2 ^$addr-okay JNZ + DUP2 #0001 ADD2 GET2 .assembler/addr PEK2 EQU2 ,&addr-okay JNZ ( FIXME address is different to previous run, or label defined twice ) - $addr-okay - PEK2 EQU ^$type-okay JNZ + &addr-okay + GET EQU ,&type-okay JNZ ( FIXME node type is different to before ) - $type-okay + &type-okay JMP2r - $new-label - ^append-tree JSR + &new-label + ,append-tree JSR ( ~assembler.heap SWP2 STR2 ,$zero-pointers ~assembler.heap #0004 ^memcpy JSR =assembler.heap ~assembler.heap ,strcpy JSR2 ) - DUP2 STH2 POK2 STH2r - DUP2 #0001 ADD2 ~assembler.addr SWP2 STR2 - #0003 ADD2 =assembler.heap + + DUP2 STH2 PUT STH2r + DUP2 #0001 ADD2 .assembler/addr PEK2 SWP2 PUT2 + #0003 ADD2 .assembler/heap POK2 JMP2r @lookup-label ( string-ptr* -- address* node-type if found OR false-address* 00 if not found ) DUP2 - $loop - DUP2 #0001 ADD2 SWP2 PEK2 - DUP #2e EQU ^$dotted JNZ - ^$loop JNZ + &loop + DUP2 #0001 ADD2 SWP2 GET + DUP #2e EQU ,&dotted JNZ + ,&loop JNZ DUP2 EOR2 ( faster than POP2 #0000 ) - =assembler.field + .assembler/field POK2 - $main - DUP2 ,label-tree SWP2 #ff ,traverse-tree JSR2 - ^$not-found JNZ + &main + DUP2 ;label-tree SWP2 #ff ;traverse-tree JSR2 + ,¬-found JNZ SWP2 POP2 - ~assembler.field #0000 EQU2 ^$end JNZ - DUP2 PEK2 #80 LTH ^$not-found JNZ - #0003 ADD2 ~assembler.field #ff ,traverse-tree JSR2 - ^$not-found JNZ + .assembler/field PEK2 #0000 EQU2 ,&end JNZ + DUP2 GET #80 LTH ,¬-found JNZ + #0003 ADD2 .assembler/field PEK2 #ff ;traverse-tree JSR2 + ,¬-found JNZ - $end - DUP2 #0001 ADD2 LDR2 SWP2 PEK2 + &end + DUP2 #0001 ADD2 GET2 SWP2 GET JMP2r - $not-found + ¬-found POP2 ( FIXME complain about missing label ) POP2 ( false-address is out of reach for JMP ) - ~assembler.addr #8765 ADD2 + .assembler/addr PEK2 #8765 ADD2 #00 JMP2r - $dotted - DUP OVR2 =assembler.field - EOR ROT ROT #0001 SUB2 POK2 - ^$main JMP + &dotted + DUP OVR2 .assembler/field POK2 + EOR ROT ROT #0001 SUB2 PUT + ,&main JMP @write-byte ( byte -- ) - ( FIXME ) =Console.byte - ~assembler.addr #0001 ADD2 =assembler.addr + ( FIXME ) .Console/byte DEO + .assembler/addr PEK2 #0001 ADD2 .assembler/addr POK2 JMP2r @write-short ( short -- ) - ( FIXME ) =Console.short - ~assembler.addr #0002 ADD2 =assembler.addr + ( FIXME ) .Console/short DEO2 + .assembler/addr PEK2 #0002 ADD2 .assembler/addr POK2 JMP2r -@label-tree .l-root +@label-tree :l-root @macro-tree [ 0000 ] @opcodes @@ -385,60 +392,61 @@ by seven (the size of each node). By multiplying the byte value by seven and adding to $disasm, we get the opcode name when disassembling too. ) - $tree .$op-lth ( opcode tree ) - $start - $op-brk .$op-add .$op-dup $disasm [ BRK ] $asm - $op-nop .$op-mul .$op-ovr [ NOP ] - $op-lit [ 0000 ] [ 0000 ] [ LIT ] - $op-pop [ 0000 ] [ 0000 ] [ POP ] - $op-dup .$op-div .$op-eor [ DUP ] - $op-swp [ 0000 ] [ 0000 ] [ SWP ] - $op-ovr .$op-ora .$op-pek [ OVR ] - $op-rot .$op-pop .$op-sft [ ROT ] - $op-equ .$op-brk .$op-jnz [ EQU ] - $op-neq [ 0000 ] [ 0000 ] [ NEQ ] - $op-gth [ 0000 ] [ 0000 ] [ GTH ] - $op-lth .$op-equ .$op-pok [ LTH ] - $op-gts .$op-gth .$op-jmp [ GTS ] - $op-lts [ 0000 ] [ 0000 ] [ LTS ] - [ 0000 ] [ 0000 ] [ ??? ] - [ 0000 ] [ 0000 ] [ ??? ] - $op-pek [ 0000 ] [ 0000 ] [ PEK ] - $op-pok .$op-nop .$op-sth [ POK ] - $op-ldr .$op-jsr .$op-lit [ LDR ] - $op-str [ 0000 ] [ 0000 ] [ STR ] - $op-jmp [ 0000 ] [ 0000 ] [ JMP ] - $op-jnz .$op-gts .$op-ldr [ JNZ ] - $op-jsr [ 0000 ] [ 0000 ] [ JSR ] - $op-sth .$op-rot .$op-sub [ STH ] - $op-add [ 0000 ] .$op-and [ ADD ] - $op-sub .$op-str .$op-swp [ SUB ] - $op-mul .$op-lts .$op-neq [ MUL ] - $op-div [ 0000 ] [ 0000 ] [ DIV ] - $op-and [ 0000 ] [ 0000 ] [ AND ] - $op-ora [ 0000 ] [ 0000 ] [ ORA ] - $op-eor [ 0000 ] [ 0000 ] [ EOR ] - $op-sft [ 0000 ] [ 0000 ] [ SFT ] + + &tree :&op-lth ( opcode tree ) + &start + &op-brk :&op-add :&op-dup &disasm [ "BRK ] &asm + &op-nop :&op-mul :&op-ovr [ "NOP ] + &op-lit [ 0000 ] [ 0000 ] [ "LIT ] + &op-pop [ 0000 ] [ 0000 ] [ "POP ] + &op-dup :&op-div :&op-eor [ "DUP ] + &op-swp [ 0000 ] [ 0000 ] [ "SWP ] + &op-ovr :&op-ora :&op-pek [ "OVR ] + &op-rot :&op-pop :&op-sft [ "ROT ] + &op-equ :&op-brk :&op-jnz [ "EQU ] + &op-neq [ 0000 ] [ 0000 ] [ "NEQ ] + &op-gth [ 0000 ] [ 0000 ] [ "GTH ] + &op-lth :&op-equ :&op-pok [ "LTH ] + &op-gts :&op-gth :&op-jmp [ "GTS ] + &op-lts [ 0000 ] [ 0000 ] [ "LTS ] + [ 0000 ] [ 0000 ] [ "??? ] + [ 0000 ] [ 0000 ] [ "??? ] + &op-pek [ 0000 ] [ 0000 ] [ "PEK ] + &op-pok :&op-nop :&op-sth [ "POK ] + &op-ldr :&op-jsr :&op-lit [ "LDR ] + &op-str [ 0000 ] [ 0000 ] [ "STR ] + &op-jmp [ 0000 ] [ 0000 ] [ "JMP ] + &op-jnz :&op-gts :&op-ldr [ "JNZ ] + &op-jsr [ 0000 ] [ 0000 ] [ "JSR ] + &op-sth :&op-rot :&op-sub [ "STH ] + &op-add [ 0000 ] :&op-and [ ADD ] + &op-sub :&op-str :&op-swp [ "SUB ] + &op-mul :&op-lts :&op-neq [ "MUL ] + &op-div [ 0000 ] [ 0000 ] [ "DIV ] + &op-and [ 0000 ] [ 0000 ] [ "AND ] + &op-ora [ 0000 ] [ 0000 ] [ "ORA ] + &op-eor [ 0000 ] [ 0000 ] [ "EOR ] + &op-sft [ 0000 ] [ 0000 ] [ "SFT ] @state-machine-pointers ( normal mode 00 ) -.normal-root .normal-main +:normal-root :normal-main ( macro definition 01 ) -.macro-root .macro-main +:macro-root :macro-main ( macro definition, contents ignored 02 ) -.macro-root .ignore +:macro-root :ignore ( variable definition, expect field size 04 ) -.variable-nul .variable-size +:variable-nul :variable-size ( variable definition, expect field name 08 ) -.variable-root .variable-name +:variable-root :variable-name ( reserved for future use 10 ) -[ 0000 ] .ignore +[ 0000 ] :ignore ( literal data 20 ) -.normal-] .data-main +:normal-5d :data-main ( reserved for future use 40 ) -[ 0000 ] .ignore +[ 0000 ] :ignore ( comment 80 ) -.normal-) .ignore +:normal-29 :ignore ( Next up, we have the tree of code corresponding to each token's @@ -451,18 +459,20 @@ the comment tree. ) + ( Left and right parentheses start and end comment sections. They use the highest bit in assembler state, so they receive highest priority: it doesn't matter what other bits are set, a comment's a comment. ) -@normal-( [ 0000 ] .normal-) [ 28 ] - ~assembler.state #80 ORA =assembler.state + +@normal-28 [ 0000 ] :normal-29 [ 28 ] + .assembler/state PEK #80 ORA .assembler/state POK JMP2r -@normal-) [ 0000 ] [ 0000 ] [ 29 ] - ~assembler.state #7f AND =assembler.state +@normal-29 [ 0000 ] [ 0000 ] [ 29 ] + .assembler/state PEK #7f AND .assembler/state POK JMP2r ( @@ -470,12 +480,13 @@ local labels that follow. ) -@normal-@ [ 0000 ] [ 0000 ] [ 40 ] - #00 ~assembler.token ,label-tree ,add-label JSR2 - $scope - ~assembler.token ,assembler.scope ,strcpy JSR2 - DUP2 ,assembler.scope SUB2 =assembler.scope-len POP +@normal-@ [ 0000 ] [ 0000 ] [ 40 ] + #00 .assembler/token PEK2 ;label-tree ;add-label JSR2 + + &scope + .assembler/token PEK2 ;assembler/scope ;strcpy JSR2 + DUP2 ;assembler/scope SUB2 .assembler/scope-len POK POP #0001 SUB2 #2d SWP POK POP JMP2r @@ -483,91 +494,95 @@ Dollar signs introduce local labels, which use the scope defined above. ) -@normal-$ .normal-" .normal-, [ 24 ] - ~assembler.token - ,assembler.scope ~assembler.scope-len ADD - ,strcpy JSR2 POP2 - #00 ,assembler.scope ,label-tree ,add-label JMP2 ( tail call ) +@normal-24 :normal-" :normal-, [ 24 ] + .assembler/token PEK2 + ;assembler/scope .assembler/scope-len PEK ADD + ;strcpy JSR2 POP2 + + #00 ;assembler/scope ;label-tree ;add-label JMP2 ( tail call ) ( Hash signs followed by two or four hex digits write a literal. ) + @normal-# [ 0000 ] [ 0000 ] [ 23 ] - ~assembler.token ,parse-hex-string JSR2 - DUP ^$valid JNZ + .assembler/token PEK2 ;parse-hex-string JSR2 + DUP ,&valid JNZ ( FIXME complain about invalid hex literal ) POP JMP2r - $valid + &valid DUP #01 SUB SHORT_FLAG MUL ( short flag for opcode ) - ,opcodes-op-lit ,opcodes-start SUB2 #07 DIV - ADD ADD ,write-byte JSR2 + ;opcodes/op-lit ;opcodes/start SUB2 #07 DIV + ADD ADD ;write-byte JSR2 - $value - #02 EQU ^$short JNZ - ,write-byte JMP2 ( tail call ) + &value + #02 EQU ,&short JNZ + ;write-byte JMP2 ( tail call ) - $short - ,write-short JMP2 ( tail call ) + &short + ;write-short JMP2 ( tail call ) ( Left and right square brackets start and end literal data sections. ) -@normal-[ .normal-@ .normal-] [ 5b ] - ~assembler.state #20 ORA =assembler.state + +@normal-5b :normal-@ :normal-5d [ 5b ] + .assembler/state PEK #20 ORA .assembler/state POK JMP2r -@normal-] [ 0000 ] [ 0000 ] [ 5d ] - ~assembler.state #df AND =assembler.state +@normal-5d [ 0000 ] [ 0000 ] [ 5d ] + .assembler/state PEK #df AND .assembler/state POK JMP2r -@data-] .normal-( [ 0000 ] [ 5d ] - ~assembler.state #df AND =assembler.state +@data-] :normal-28 [ 0000 ] [ 5d ] + .assembler/state PEK #df AND .assembler/state POK JMP2r @data-root -@data-nul [ 0000 ] .data-] [ 00 ] +@data-nul [ 0000 ] :data-] [ 00 ] JMP2r @data-main - ~assembler.token ,parse-hex-string JSR2 - DUP ^normal-#-value JNZ + .assembler/token PEK2 ;parse-hex-string JSR2 + DUP ,normal-#/value JNZ POP - ~assembler.token - $loop - DUP2 PEK2 - DUP ^$keep-going JNZ + .assembler/token PEK2 + &loop + DUP2 GET + DUP ,&keep-going JNZ POP POP2 JMP2r - $keep-going - ,write-byte JSR2 + &keep-going + ;write-byte JSR2 #0001 ADD2 - ^$loop JMP + ,&loop JMP ( A pipe moves the current address to the hex value given. ) -@normal-| .normal-{ .normal-} [ 7c ] - ~assembler.token ,parse-hex-string JSR2 - DUP #02 EQU ^$valid JNZ + +@normal-| :normal-{ :normal-} [ 7c ] + .assembler/token PEK2 ;parse-hex-string JSR2 + DUP #02 EQU ,&valid JNZ #00 EQU JMP POP ( FIXME complain about invalid hex literal ) JMP2r - $valid + &valid POP - DUP2 ~assembler.addr LTH2 ^$backwards JNZ + DUP2 .assembler/addr PEK2 LTH2 ,&backwards JNZ ( FIXME add zeroes when writing ) - =assembler.addr + .assembler/addr POK2 JMP2r - $backwards + &backwards ( FIXME complain about going backwards ) POP2 JMP2r @@ -577,32 +592,34 @@ with a LIT2 opcode. ) -@normal-, .normal-% .normal-dot [ 2c ] - ,opcodes-op-lit ,opcodes-start SUB2 #07 DIV SHORT_FLAG ADD ,write-byte JSR2 POP - ^normal-dot-main JMP -@normal-dot [ 0000 ] .normal-; [ 2e ] - $main - ~assembler.token ,lookup-label JSR2 +@normal-, :normal-% :normal-dot [ 2c ] + ;opcodes/op-lit ;opcodes/start SUB2 #07 DIV SHORT_FLAG ADD ;write-byte JSR2 POP + ,normal-dot/main JMP + +@normal-dot [ 0000 ] :normal-; [ 2e ] + &main + .assembler/token PEK2 ;lookup-label JSR2 POP ( don't care about node type ) - ,write-short JMP2 ( tail call ) + ;write-short JMP2 ( tail call ) ( Caret writes LIT, followed by the label address as an offset. ) -@normal-^ .normal-[ .normal-| [ 5e ] - ,opcodes-op-lit ,opcodes-start SUB2 #07 DIV ,write-byte JSR2 POP - ~assembler.token ,lookup-label JSR2 + +@normal-^ :normal-5b :normal-| [ 5e ] + ;opcodes/op-lit ;opcodes/start SUB2 #07 DIV ;write-byte JSR2 POP + .assembler/token PEK2 ;lookup-label JSR2 POP ( don't care about node type ) - ~assembler.addr SUB2 - DUP2 #ff79 GTH2 ^$okay JNZ - DUP2 #0080 LTH2 ^$okay JNZ + .assembler/addr PEK2 SUB2 + DUP2 #ff79 GTH2 ,&okay JNZ + DUP2 #0080 LTH2 ,&okay JNZ ( FIXME complain about jump being too far ) - $okay - ,write-byte JSR2 POP + &okay + ;write-byte JSR2 POP JMP2r ( @@ -610,38 +627,39 @@ If the target is in the zero page, use LDR/PEK or STR/POK opcodes, otherwise use LDR2/PEK2 or STR2/POK2 opcodes. ) + @normal-~ [ 0000 ] [ 0000 ] [ 7e ] - LIT2r .opcodes-op-ldr LIT2r .opcodes-op-pek - ^normal-=-main JMP + LIT2r :opcodes/op-ldr LIT2r :opcodes/op-pek + ,normal-=/main JMP @normal-root -@normal-= .normal-$ .normal-^ [ 3d ] - LIT2r .opcodes-op-str LIT2r .opcodes-op-pok - $main - ~assembler.token ,lookup-label JSR2 - DUP #03 AND ^$valid JNZ +@normal-= :normal-24 :normal-^ [ 3d ] + LIT2r :opcodes/op-str LIT2r :opcodes/op-pok + &main + .assembler/token PEK2 ;lookup-label JSR2 + DUP #03 AND ,&valid JNZ ( FIXME complain about helper not being usable ) POP2 JMP2r - $valid - #02 AND ^$two-byte JNZ + &valid + #02 AND ,&two-byte JNZ SWP2r - $two-byte + &two-byte POP2r - LIT2r .opcodes-start SUB2r LITr [ 07 ] DIVr - OVR #00 EQU ^$byte-mode JNZ + LIT2r :opcodes/start SUB2r LITr [ 07 ] DIVr + OVR #00 EQU ,&byte-mode JNZ - ,write-short SHORT_FLAG ^$end JMP + ;write-short SHORT_FLAG ,&end JMP - $byte-mode + &byte-mode SWP POP - ,write-byte #00 + ;write-byte #00 - $end - ,opcodes-op-lit ,opcodes-start SUB2 #07 DIV ADD ADD ,write-byte JSR2 + &end + ;opcodes/op-lit ;opcodes/start SUB2 #07 DIV ADD ADD ;write-byte JSR2 JSR2 - STHr ,write-byte JSR2 + STHr ;write-byte JSR2 POPr JMP2r @@ -650,55 +668,56 @@ tree as usual, but all of the subfields are collected into their own tree pointed to in the variable name's binary data. ) -@normal-; [ 0000 ] [ 0000 ] [ 3b ] - #80 ~assembler.token ,label-tree ,add-label JSR2 - ~assembler.heap #0000 OVR2 STR2 - DUP2 #0003 SUB2 =assembler.var_size - DUP2 =assembler.subtree - #0002 ADD2 =assembler.heap - ~assembler.state #0c ORA =assembler.state +@normal-; [ 0000 ] [ 0000 ] [ 3b ] + #80 .assembler/token PEK2 ;label-tree ;add-label JSR2 + .assembler/heap PEK2 #0000 OVR2 PUT2 + DUP2 #0003 SUB2 .assembler/var_size POK2 + DUP2 .assembler/subtree POK2 + #0002 ADD2 .assembler/heap POK2 + + .assembler/state PEK #0c ORA .assembler/state POK JMP2r @variable-root -@variable-{ .variable-nul .variable-} [ 7b ] +@variable-{ :variable-nul :variable-} [ 7b ] JMP2r -@variable-nul [ 0000 ] .normal-( [ 00 ] +@variable-nul [ 0000 ] :normal-28 [ 00 ] JMP2r @variable-} [ 0000 ] [ 0000 ] [ 7d ] - ~assembler.state #f3 AND =assembler.state + .assembler/state PEK #f3 AND .assembler/state POK JMP2r @variable-name - #00 ~assembler.token ~assembler.subtree ,add-label JSR2 - ~assembler.heap #0003 SUB2 =assembler.field_size - ~assembler.state #f7 AND =assembler.state + #00 .assembler/token PEK2 .assembler/subtree PEK2 ;add-label JSR2 + .assembler/heap PEK2 #0003 SUB2 .assembler/field_size POK2 + .assembler/state PEK #f7 AND .assembler/state POK JMP2r @variable-size - ~assembler.token ,parse-hex-length JSR2 - ^$valid JNZ + .assembler/token PEK2 ;parse-hex-length JSR2 + ,&valid JNZ ( FIXME complain about invalid size ) JMP2r - $valid - $no-var-size - DUP #02 GTH ^$end JNZ - DUP ~assembler.field_size POK2 - ~assembler.var_size #0000 EQU2 ^$end JNZ - DUP #80 EOR ~assembler.var_size POK2 - ^$end JMP + &valid + &no-var-size + DUP #02 GTH ,&end JNZ + DUP .assembler/field_size PEK2 PUT + .assembler/var_size PEK2 #0000 EQU2 ,&end JNZ + DUP #80 EOR .assembler/var_size PEK2 PUT + ,&end JMP - $loop - #00 ,write-byte JSR2 + &loop + #00 ;write-byte JSR2 #01 SUB - $end - DUP ^$loop JNZ + &end + DUP ,&loop JNZ POP - ~assembler.state #0c ORA =assembler.state - #0000 =assembler.var_size + .assembler/state PEK #0c ORA .assembler/state POK + #0000 .assembler/var_size POK2 JMP2r ( @@ -706,42 +725,43 @@ and all the arguments are collected into a list that follows the label's binary data. ) -@normal-% [ 0000 ] .normal-( [ 25 ] - ,macro-tree ~assembler.token #ff ,traverse-tree JSR2 - ^$new-macro JNZ + +@normal-% [ 0000 ] :normal-28 [ 25 ] + ;macro-tree .assembler/token PEK2 #ff ;traverse-tree JSR2 + ,&new-macro JNZ ( macro already exists, we assume defined in a previous pass we totally ignore the contents ) POP2 - ~assembler.state #02 ORA =assembler.state + .assembler/state PEK #02 ORA .assembler/state POK JMP2r - $new-macro - ~assembler.token SWP2 ,append-tree JSR2 + &new-macro + .assembler/token PEK2 SWP2 ;append-tree JSR2 POP2 - ~assembler.state #01 ORA =assembler.state + .assembler/state PEK #01 ORA .assembler/state POK JMP2r @macro-root -@macro-{ .macro-nul .macro-} [ 7b ] +@macro-{ :macro-nul :macro-} [ 7b ] JMP2r @macro-} [ 0000 ] [ 0000 ] [ 7d ] - ~assembler.heap DUP2 #00 ROT ROT POK2 - #0001 ADD2 =assembler.heap - ~assembler.state #fc AND =assembler.state + .assembler/heap PEK2 DUP2 #00 ROT ROT PUT + #0001 ADD2 .assembler/heap POK2 + .assembler/state PEK #fc AND .assembler/state POK JMP2r -@macro-nul [ 0000 ] .normal-( [ 00 ] +@macro-nul [ 0000 ] :normal-28 [ 00 ] JMP2r @macro-main - ~assembler.token ,append-heap JSR2 + .assembler/token PEK2 ;append-heap JSR2 POP2 JMP2r -@normal-" .normal-nul .normal-# [ 22 ] +@normal-" :normal-nul :normal-# [ 22 ] ( FIXME NYI ) JMP2r @@ -749,7 +769,7 @@ ( these are spurious, but ignore them anyway ) JMP2r -@normal-} [ 0000 ] .normal-~ [ 7d ] +@normal-} [ 0000 ] :normal-~ [ 7d ] ( these are spurious, but ignore them anyway ) JMP2r @@ -758,37 +778,37 @@ JMP2r @normal-main - ~assembler.token - ,opcodes-tree OVR2 #03 ,traverse-tree JSR2 - ^$not-opcode JNZ + .assembler/token PEK2 + ;opcodes/tree OVR2 #03 ;traverse-tree JSR2 + ,¬-opcode JNZ - ,opcodes-asm SUB2 #0007 DIV2 + ;opcodes/asm SUB2 #0007 DIV2 SWP2 #0003 ADD2 - $flags - DUP2 PEK2 - DUP #00 EQU ^$end-flags JNZ - DUP #32 NEQ ^$not-two JNZ - POP SWP2 SHORT_FLAG ORA SWP2 #0001 ADD2 ^$flags JMP - $not-two - DUP #72 NEQ ^$not-r JNZ - POP SWP2 RETURN_FLAG ORA SWP2 #0001 ADD2 ^$flags JMP - $not-r - POP POP2 ~assembler.token SWP2 - ^$not-opcode JMP + &flags + DUP2 GET + DUP #00 EQU ,&end-flags JNZ + DUP #32 NEQ ,¬-two JNZ + POP SWP2 SHORT_FLAG ORA SWP2 #0001 ADD2 ,&flags JMP + ¬-two + DUP #72 NEQ ,¬-r JNZ + POP SWP2 RETURN_FLAG ORA SWP2 #0001 ADD2 ,&flags JMP + ¬-r + POP POP2 .assembler/token PEK2 SWP2 + ,¬-opcode JMP - $end-flags + &end-flags POP POP2 - ,write-byte JSR2 + ;write-byte JSR2 POP JMP2r - $not-opcode + ¬-opcode POP2 - ,macro-tree SWP2 #ff ,traverse-tree JSR2 - ^$not-macro JNZ - ,assemble-macro JMP2 ( tail call ) + ;macro-tree SWP2 #ff ;traverse-tree JSR2 + ,¬-macro JNZ + ;assemble-macro JMP2 ( tail call ) - $not-macro + ¬-macro ( FIXME complain about bad opcode / nonexistent macro ) POP2 JMP2r @@ -818,72 +838,73 @@ If there is a subtree, it is searched when the reference contains a dot. ) -@l-Audio [ 0000 ] [ 0000 ] [ Audio 00 ] [ 80 ] .Audio .l-Audio-root -@l-Audio-delay [ 0000 ] [ 0000 ] [ delay 00 ] [ 02 ] .Audio.delay -@l-Audio-envelope .l-Audio-delay .l-Audio-finish [ envelope 00 ] [ 02 ] .Audio.envelope -@l-Audio-finish [ 0000 ] [ 0000 ] [ finish 00 ] [ 01 ] .Audio.finish + +@l-Audio [ 0000 ] [ 0000 ] [ "Audio 00 ] [ 80 ] :Audio :l-Audio-root +@l-Audio-delay [ 0000 ] [ 0000 ] [ "delay 00 ] [ 02 ] :Audio/delay +@l-Audio-envelope :l-Audio-delay :l-Audio-finish [ "envelope 00 ] [ 02 ] :Audio/envelope +@l-Audio-finish [ 0000 ] [ 0000 ] [ "finish 00 ] [ 01 ] :Audio/finish @l-Audio-root -@l-Audio-pitch .l-Audio-envelope .l-Audio-value [ pitch 00 ] [ 01 ] .Audio.pitch -@l-Audio-play [ 0000 ] [ 0000 ] [ play 00 ] [ 01 ] .Audio.play -@l-Audio-value .l-Audio-play .l-Audio-volume [ value 00 ] [ 02 ] .Audio.value -@l-Audio-volume [ 0000 ] .l-Audio-wave [ volume 00 ] [ 01 ] .Audio.volume -@l-Audio-wave [ 0000 ] [ 0000 ] [ wave 00 ] [ 02 ] .Audio.wave -@l-Console .l-Audio .l-Controller [ Console 00 ] [ 80 ] .Console .l-Console-root -@l-Console-byte [ 0000 ] .l-Console-char [ byte 00 ] [ 01 ] .Console.byte -@l-Console-char [ 0000 ] [ 0000 ] [ char 00 ] [ 01 ] .Console.char +@l-Audio-pitch :l-Audio-envelope :l-Audio-value [ "pitch 00 ] [ 01 ] :Audio/pitch +@l-Audio-play [ 0000 ] [ 0000 ] [ "play 00 ] [ 01 ] :Audio/play +@l-Audio-value :l-Audio-play :l-Audio-volume [ "value 00 ] [ 02 ] :Audio/value +@l-Audio-volume [ 0000 ] :l-Audio-wave [ "volume 00 ] [ 01 ] :Audio/volume +@l-Audio-wave [ 0000 ] [ 0000 ] [ "wave 00 ] [ 02 ] :Audio/wave +@l-Console :l-Audio :l-Controller [ "Console 00 ] [ 80 ] :Console :l-Console-root +@l-Console-byte [ 0000 ] :l-Console-char [ "byte 00 ] [ 01 ] :Console/byte +@l-Console-char [ 0000 ] [ 0000 ] [ "char 00 ] [ 01 ] :Console/char @l-Console-root -@l-Console-short .l-Console-byte .l-Console-string [ short 00 ] [ 02 ] .Console.short -@l-Console-string [ 0000 ] .l-Console-vector [ string 00 ] [ 02 ] .Console.string -@l-Console-vector [ 0000 ] [ 0000 ] [ vector 00 ] [ 02 ] .Console.vector -@l-Controller [ 0000 ] [ 0000 ] [ Controller 00 ] [ 80 ] .Controller .l-Controller-root -@l-Controller-button [ 0000 ] [ 0000 ] [ button 00 ] [ 01 ] .Controller.button +@l-Console-short :l-Console-byte :l-Console-string [ "short 00 ] [ 02 ] :Console/short +@l-Console-string [ 0000 ] :l-Console-vector [ "string 00 ] [ 02 ] :Console/string +@l-Console-vector [ 0000 ] [ 0000 ] [ "vector 00 ] [ 02 ] :Console/vector +@l-Controller [ 0000 ] [ 0000 ] [ "Controller 00 ] [ 80 ] :Controller :l-Controller-root +@l-Controller-button [ 0000 ] [ 0000 ] [ "button 00 ] [ 01 ] :Controller/button @l-Controller-root -@l-Controller-key .l-Controller-button .l-Controller-vector [ key 00 ] [ 01 ] .Controller.key -@l-Controller-vector [ 0000 ] [ 0000 ] [ vector 00 ] [ 02 ] .Controller.vector +@l-Controller-key :l-Controller-button :l-Controller-vector [ "key 00 ] [ 01 ] :Controller/key +@l-Controller-vector [ 0000 ] [ 0000 ] [ "vector 00 ] [ 02 ] :Controller/vector @l-root -@l-DateTime .l-Console .l-Mouse [ DateTime 00 ] [ 80 ] .DateTime .l-DateTime-root -@l-DateTime-day [ 0000 ] [ 0000 ] [ day 00 ] [ 01 ] .DateTime.day -@l-DateTime-dotw .l-DateTime-day .l-DateTime-doty [ dotw 00 ] [ 01 ] .DateTime.dotw -@l-DateTime-doty [ 0000 ] .l-DateTime-hour [ doty 00 ] [ 02 ] .DateTime.doty -@l-DateTime-hour [ 0000 ] [ 0000 ] [ hour 00 ] [ 01 ] .DateTime.hour +@l-DateTime :l-Console :l-Mouse [ "DateTime 00 ] [ 80 ] :DateTime :l-DateTime-root +@l-DateTime-day [ 0000 ] [ 0000 ] [ "day 00 ] [ 01 ] :DateTime/day +@l-DateTime-dotw :l-DateTime-day :l-DateTime-doty [ "dotw 00 ] [ 01 ] :DateTime/dotw +@l-DateTime-doty [ 0000 ] :l-DateTime-hour [ "doty 00 ] [ 02 ] :DateTime/doty +@l-DateTime-hour [ 0000 ] [ 0000 ] [ "hour 00 ] [ 01 ] :DateTime/hour @l-DateTime-root -@l-DateTime-isdst .l-DateTime-dotw .l-DateTime-refresh [ isdst 00 ] [ 01 ] .DateTime.isdst -@l-DateTime-minute [ 0000 ] .l-DateTime-month [ minute 00 ] [ 01 ] .DateTime.minute -@l-DateTime-month [ 0000 ] [ 0000 ] [ month 00 ] [ 01 ] .DateTime.month -@l-DateTime-refresh .l-DateTime-minute .l-DateTime-second [ refresh 00 ] [ 01 ] .DateTime.refresh -@l-DateTime-second [ 0000 ] .l-DateTime-year [ second 00 ] [ 01 ] .DateTime.second -@l-DateTime-year [ 0000 ] [ 0000 ] [ year 00 ] [ 02 ] .DateTime.year -@l-File [ 0000 ] [ 0000 ] [ File 00 ] [ 80 ] .File .l-File-root -@l-File-length [ 0000 ] [ 0000 ] [ length 00 ] [ 02 ] .File.length -@l-File-load .l-File-length .l-File-name [ load 00 ] [ 02 ] .File.load -@l-File-name [ 0000 ] [ 0000 ] [ name 00 ] [ 02 ] .File.name +@l-DateTime-isdst :l-DateTime-dotw :l-DateTime-refresh [ "isdst 00 ] [ 01 ] :DateTime/isdst +@l-DateTime-minute [ 0000 ] :l-DateTime-month [ "minute 00 ] [ 01 ] :DateTime/minute +@l-DateTime-month [ 0000 ] [ 0000 ] [ "month 00 ] [ 01 ] :DateTime/month +@l-DateTime-refresh :l-DateTime-minute :l-DateTime-second [ "refresh 00 ] [ 01 ] :DateTime/refresh +@l-DateTime-second [ 0000 ] :l-DateTime-year [ "second 00 ] [ 01 ] :DateTime/second +@l-DateTime-year [ 0000 ] [ 0000 ] [ "year 00 ] [ 02 ] :DateTime/year +@l-File [ 0000 ] [ 0000 ] [ "File 00 ] [ 80 ] :File :l-File-root +@l-File-length [ 0000 ] [ 0000 ] [ "length 00 ] [ 02 ] :File/length +@l-File-load :l-File-length :l-File-name [ "load 00 ] [ 02 ] :File/load +@l-File-name [ 0000 ] [ 0000 ] [ "name 00 ] [ 02 ] :File/name @l-File-root -@l-File-offset .l-File-load .l-File-success [ offset 00 ] [ 02 ] .File.offset -@l-File-save [ 0000 ] [ 0000 ] [ save 00 ] [ 02 ] .File.save -@l-File-success .l-File-save .l-File-vector [ success 00 ] [ 02 ] .File.success -@l-File-vector [ 0000 ] [ 0000 ] [ vector 00 ] [ 02 ] .File.vector -@l-Mouse .l-File .l-Screen [ Mouse 00 ] [ 80 ] .Mouse .l-Mouse-root -@l-Mouse-chord [ 0000 ] .l-Mouse-state [ chord 00 ] [ 01 ] .Mouse.chord -@l-Mouse-state [ 0000 ] [ 0000 ] [ state 00 ] [ 01 ] .Mouse.state +@l-File-offset :l-File-load :l-File-success [ "offset 00 ] [ 02 ] :File/offset +@l-File-save [ 0000 ] [ 0000 ] [ "save 00 ] [ 02 ] :File/save +@l-File-success :l-File-save :l-File-vector [ "success 00 ] [ 02 ] :File/success +@l-File-vector [ 0000 ] [ 0000 ] [ "vector 00 ] [ 02 ] :File/vector +@l-Mouse :l-File :l-Screen [ "Mouse 00 ] [ 80 ] :Mouse :l-Mouse-root +@l-Mouse-chord [ 0000 ] :l-Mouse-state [ "chord 00 ] [ 01 ] :Mouse/chord +@l-Mouse-state [ 0000 ] [ 0000 ] [ "state 00 ] [ 01 ] :Mouse/state @l-Mouse-root -@l-Mouse-vector .l-Mouse-chord .l-Mouse-x [ vector 00 ] [ 02 ] .Mouse.vector -@l-Mouse-x [ 0000 ] .l-Mouse-y [ x 00 ] [ 02 ] .Mouse.x -@l-Mouse-y [ 0000 ] [ 0000 ] [ y 00 ] [ 02 ] .Mouse.y -@l-Screen [ 0000 ] .l-System [ Screen 00 ] [ 80 ] .Screen .l-Screen-root -@l-Screen-addr [ 0000 ] [ 0000 ] [ addr 00 ] [ 02 ] .Screen.addr -@l-Screen-color .l-Screen-addr .l-Screen-height [ color 00 ] [ 01 ] .Screen.color -@l-Screen-height [ 0000 ] [ 0000 ] [ height 00 ] [ 02 ] .Screen.height +@l-Mouse-vector :l-Mouse-chord :l-Mouse-x [ "vector 00 ] [ 02 ] :Mouse/vector +@l-Mouse-x [ 0000 ] :l-Mouse-y [ "x 00 ] [ 02 ] :Mouse/x +@l-Mouse-y [ 0000 ] [ 0000 ] [ "y 00 ] [ 02 ] :Mouse/y +@l-Screen [ 0000 ] :l-System [ "Screen 00 ] [ 80 ] :Screen :l-Screen-root +@l-Screen-addr [ 0000 ] [ 0000 ] [ "addr 00 ] [ 02 ] :Screen/addr +@l-Screen-color :l-Screen-addr :l-Screen-height [ "color 00 ] [ 01 ] :Screen/color +@l-Screen-height [ 0000 ] [ 0000 ] [ "height 00 ] [ 02 ] :Screen/height @l-Screen-root -@l-Screen-vector .l-Screen-color .l-Screen-x [ vector 00 ] [ 02 ] .Screen.vector -@l-Screen-width [ 0000 ] [ 0000 ] [ width 00 ] [ 02 ] .Screen.width -@l-Screen-x .l-Screen-width .l-Screen-y [ x 00 ] [ 02 ] .Screen.x -@l-Screen-y [ 0000 ] [ 0000 ] [ y 00 ] [ 02 ] .Screen.y -@l-System [ 0000 ] [ 0000 ] [ System 00 ] [ 80 ] .System .l-System-root -@l-System-b [ 0000 ] [ 0000 ] [ b 00 ] [ 02 ] .System.b +@l-Screen-vector :l-Screen-color :l-Screen-x [ "vector 00 ] [ 02 ] :Screen/vector +@l-Screen-width [ 0000 ] [ 0000 ] [ "width 00 ] [ 02 ] :Screen/width +@l-Screen-x :l-Screen-width :l-Screen-y [ "x 00 ] [ 02 ] :Screen/x +@l-Screen-y [ 0000 ] [ 0000 ] [ "y 00 ] [ 02 ] :Screen/y +@l-System [ 0000 ] [ 0000 ] [ "System 00 ] [ 80 ] :System :l-System-root +@l-System-b [ 0000 ] [ 0000 ] [ b 00 ] [ 02 ] :System/b @l-System-root -@l-System-g .l-System-b .l-System-r [ g 00 ] [ 02 ] .System.g -@l-System-r [ 0000 ] .l-System-vector [ r 00 ] [ 02 ] .System.r -@l-System-vector [ 0000 ] [ 0000 ] [ vector 00 ] [ 02 ] .System.vector +@l-System-g :l-System-b :l-System-r [ "g 00 ] [ 02 ] :System/g +@l-System-r [ 0000 ] :l-System-vector [ "r 00 ] [ 02 ] :System/r +@l-System-vector [ 0000 ] [ 0000 ] [ "vector 00 ] [ 02 ] :System/vector @assembler-heap-start