uxn/projects/software/asma.usm

911 lines
26 KiB
Plaintext
Raw Normal View History

2021-04-24 05:50:21 -04:00
( asma: in-Uxn assembler (not working yet, in progress) )
2021-03-31 18:55:02 -04:00
%HCF { #0000 DIV }
2021-04-11 04:40:26 -04:00
%SHORT_FLAG { #20 }
2021-04-12 16:01:36 -04:00
%RETURN_FLAG { #40 }
2021-03-31 18:55:02 -04:00
( devices )
2021-04-24 05:50:21 -04:00
|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 ]
2021-04-24 13:26:09 -04:00
|a0 @DateTime [ &year $2 &month $1 &day $1 &hour $1 &minute $1 &second $1 &dotw $1 &doty $2 &isdst $1 ]
2021-04-24 05:50:21 -04:00
( 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 ]
2021-03-31 18:55:02 -04:00
( vectors )
2021-04-24 05:50:21 -04:00
|0100 ,RESET JMP
2021-03-31 18:55:02 -04:00
@RESET
2021-04-24 05:50:21 -04:00
;assembler-heap-start .assembler/heap POK2
2021-03-31 18:55:02 -04:00
2021-04-24 05:50:21 -04:00
;&read-filename ,assemble-file JSR
2021-04-18 07:48:49 -04:00
HCF
2021-04-12 16:01:36 -04:00
2021-03-31 18:55:02 -04:00
HCF
2021-04-24 05:50:21 -04:00
&read-filename [ "projects/software/noodle.usm 00 ]
2021-04-18 07:48:49 -04:00
@assemble-file ( filename-ptr* -- )
#0000
2021-04-24 05:50:21 -04:00
&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
2021-04-18 07:48:49 -04:00
SUB2 SUB2
2021-04-24 05:50:21 -04:00
,&loop JMP
2021-04-18 07:48:49 -04:00
2021-04-24 05:50:21 -04:00
&end
2021-04-18 07:48:49 -04:00
POP2 POP2 POP2 POP2 POP2
JMP2r
2021-04-12 16:01:36 -04:00
2021-04-18 07:48:49 -04:00
@assemble-chunk ( ptr* len* -- assembled-up-to-ptr* )
( FIXME we still return on seeing 00 in source code,
while assemble-file is now binary safe )
2021-04-12 16:01:36 -04:00
OVR2 ADD2 STH2
#0001 SUB2
2021-04-24 05:50:21 -04:00
&per-token
2021-04-12 16:01:36 -04:00
DUP2 STH2
2021-04-24 05:50:21 -04:00
&loop
2021-04-12 16:01:36 -04:00
#0001 ADD2
2021-04-24 05:50:21 -04:00
DUP2 GET
#20 GTH ,&loop JNZ
2021-04-12 16:01:36 -04:00
2021-04-24 05:50:21 -04:00
DUP2 OVR2r STH2r LTS2 ,&valid JNZ
2021-04-12 16:01:36 -04:00
SWP2r POP2r POP2
STH2r #0001 ADD2
2021-04-18 07:48:49 -04:00
JMP2r
2021-04-12 16:01:36 -04:00
2021-04-24 05:50:21 -04:00
&valid
DUP2 GET #00 OVR2 PUT
STH2r #0001 ADD2 ,assemble-token JSR
,&per-token JNZ
2021-04-12 16:01:36 -04:00
2021-04-18 07:48:49 -04:00
POP2r JMP2r
2021-04-12 16:01:36 -04:00
@assemble-macro ( macro-ptr* -- )
2021-04-24 05:50:21 -04:00
DUP2 ;strlen JSR2 DUP2 #0000 EQU2 ,&end JNZ
OVR2 ,assemble-token JSR
2021-04-12 16:01:36 -04:00
ADD2 #0001 ADD2
2021-04-24 05:50:21 -04:00
,assemble-macro JMP
2021-04-12 16:01:36 -04:00
2021-04-24 05:50:21 -04:00
&end
2021-04-12 16:01:36 -04:00
POP2 POP2
JMP2r
2021-03-31 18:55:02 -04:00
@assemble-token ( string-ptr* -- )
( get location of tree )
DUP2
2021-04-24 05:50:21 -04:00
;state-machine-pointers #00 .assembler/state PEK ;highest-bit JSR2 #0004 MUL2 ADD2
2021-03-31 18:55:02 -04:00
DUP2 STH2
( see if first char is recognised )
2021-04-24 05:50:21 -04:00
SWP2 #01 ;traverse-tree JSR2
,&not-found JNZ
2021-03-31 18:55:02 -04:00
( skip first character of token )
2021-04-24 05:50:21 -04:00
SWP2 #0001 ADD2 .assembler/token POK2
2021-03-31 18:55:02 -04:00
( tail call handling function defined in tree )
POP2r JMP2
2021-04-24 05:50:21 -04:00
&not-found
2021-03-31 18:55:02 -04:00
( not interested in incoming-ptr )
POP2
2021-04-24 05:50:21 -04:00
.assembler/token POK2
2021-03-31 18:55:02 -04:00
( tail call default handling function defined in state-machine-pointers )
2021-04-24 05:50:21 -04:00
LIT2r [ 0002 ] ADD2r GET2r
2021-03-31 18:55:02 -04:00
JMP2r
@parse-hex-length ( string-ptr* -- value 01 if one or two hex digits
OR 00 otherwise )
2021-04-24 05:50:21 -04:00
DUP2 #0001 ADD2 GET ,parse-hex-string/try-two JNZ
GET ,parse-hex-digit JSR DUP #04 SFT ,parse-hex-string/fail1 JNZ
2021-03-31 18:55:02 -04:00
#01 JMP2r
@parse-hex-string ( string-ptr* -- value* 02 if four hex digits
OR value 01 if two hex digits
OR 00 otherwise )
2021-04-24 05:50:21 -04:00
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
2021-03-31 18:55:02 -04:00
SWP #40 SFT ORA #01 JMP2r
2021-04-24 05:50:21 -04:00
&fail3 POP
&fail2 POP
&fail1 POP #00 JMP2r
2021-03-31 18:55:02 -04:00
2021-04-24 05:50:21 -04:00
&try-four
DUP2 #0002 ADD2 ,&known-two JSR ,&maybe-four JNZ
,&try-two JMP
2021-03-31 18:55:02 -04:00
2021-04-24 05:50:21 -04:00
&maybe-four
ROT ROT ,&known-two JSR ,&four JNZ
,&fail1 JMP
2021-03-31 18:55:02 -04:00
2021-04-24 05:50:21 -04:00
&four
2021-03-31 18:55:02 -04:00
SWP #02 JMP2r
@parse-hex-digit ( charcode -- 00-0f if valid hex
-- 10-ff otherwise )
2021-04-24 05:50:21 -04:00
DUP #3a LTH ,&digit JNZ
DUP #60 GTH ,&lowercase JNZ
DUP #40 GTH ,&uppercase JNZ
2021-03-31 18:55:02 -04:00
JMP2r
2021-04-24 05:50:21 -04:00
&digit ( #30 is #00 )
2021-03-31 18:55:02 -04:00
#30 SUB JMP2r
2021-04-24 05:50:21 -04:00
&lowercase ( #61 is #0a )
2021-03-31 18:55:02 -04:00
#57 SUB JMP2r
2021-04-24 05:50:21 -04:00
&uppercase ( #41 is #0a )
2021-03-31 18:55:02 -04:00
#37 SUB JMP2r
@find-opcode ( name* -- byte 00 if valid opcode name
OR 01 if not found )
2021-04-24 05:50:21 -04:00
;opcodes/tree SWP2 #03 ,traverse-tree JSR
,&nomatch JNZ
;opcodes/asm SUB2 #0007 DIV2
2021-03-31 18:55:02 -04:00
SWP JMP2r
2021-04-24 05:50:21 -04:00
&nomatch
2021-03-31 18:55:02 -04:00
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 )
2021-04-24 05:50:21 -04:00
.tree/max-key-len POK .tree/search-key POK2
2021-03-31 18:55:02 -04:00
2021-04-24 05:50:21 -04:00
&loop
DUP2 GET2 #0000 NEQ2 ,&valid-node JNZ
2021-03-31 18:55:02 -04:00
#01 JMP2r
2021-04-24 05:50:21 -04:00
&valid-node
GET2 DUP2 STH2 #0004 ADD2 ,strcmp-tree JSR
DUP ,&nomatch JNZ
2021-03-31 18:55:02 -04:00
POP2r JMP2r
2021-04-24 05:50:21 -04:00
&nomatch
2021-03-31 18:55:02 -04:00
#07 SFT #02 MUL #00 SWP
STH2r ADD2
2021-04-24 05:50:21 -04:00
,&loop JMP
2021-03-31 18:55:02 -04:00
@strcmp-tree ( node-key* -- order if strings differ
OR after-node-key* 00 if strings match )
2021-04-24 05:50:21 -04:00
.tree/search-key PEK2 STH2
.tree/max-key-len PEK
2021-03-31 18:55:02 -04:00
2021-04-24 05:50:21 -04:00
&loop ( node-key* key-len in wst, search-key* in rst )
DUP ,&keep-going JNZ
2021-03-31 18:55:02 -04:00
( exhausted key-len, match found )
POP2r
JMP2r
2021-04-24 05:50:21 -04:00
&keep-going
#01 OVR2 GET DUP2r GETr STHr
DUP2 ORA ,&not-end JNZ
2021-03-31 18:55:02 -04:00
( end of C strings, match found )
POP2r POP ROT POP SWP ADD2 #00
JMP2r
2021-04-24 05:50:21 -04:00
&not-end
SUB DUP ,&nomatch JNZ
2021-03-31 18:55:02 -04:00
POP SUB
LIT2r [ 0001 ] ADD2r STH
LIT2 [ 0001 ] ADD2 STHr
2021-04-24 05:50:21 -04:00
,&loop JMP
2021-03-31 18:55:02 -04:00
2021-04-24 05:50:21 -04:00
&nomatch
2021-03-31 18:55:02 -04:00
STH POP2 POP2 STHr POP2r
JMP2r
2021-04-11 04:40:26 -04:00
@highest-bit ( n -- 00 if n is 00
OR 01 if n is 01
OR 02 if n is 02..03
OR 03 if n is 04..07
OR 04 if n is 08..0f
..
OR 08 if n is 80..ff )
DUP #00 NEQ JMP JMP2r
DUP #01 SFT ORA
DUP #02 SFT ORA
DUP #04 SFT ORA
2021-04-24 05:50:21 -04:00
#1d MUL #05 SFT #00 SWP ;&lookup ADD2 GET
2021-04-11 04:40:26 -04:00
JMP2r
2021-04-24 05:50:21 -04:00
&lookup
2021-04-11 04:40:26 -04:00
[ 01 06 02 07 05 04 03 08 ]
@memcpy ( src-ptr* dest-ptr* length* -- after-dest-ptr* )
2021-03-31 18:55:02 -04:00
SWP2 STH2
2021-04-24 05:50:21 -04:00
&loop
DUP2 ORA ,&keep-going JNZ
2021-04-11 04:40:26 -04:00
POP2 POP2 STH2r
2021-03-31 18:55:02 -04:00
JMP2r
2021-04-24 05:50:21 -04:00
&keep-going
2021-03-31 18:55:02 -04:00
#0001 SUB2
2021-04-24 05:50:21 -04:00
SWP2 DUP2 GET DUP2r STH2r PUT
2021-03-31 18:55:02 -04:00
#0001 ADD2 SWP2
LIT2r [ 0001 ] ADD2r
2021-04-24 05:50:21 -04:00
,&loop JMP
2021-03-31 18:55:02 -04:00
2021-04-11 04:40:26 -04:00
@strcpy ( src-ptr* dest-ptr* -- after-dest-ptr* )
2021-04-24 05:50:21 -04:00
OVR2 ,strlen JSR #0001 ADD2 ,memcpy JMP
2021-04-11 04:40:26 -04:00
2021-03-31 18:55:02 -04:00
@strlen ( string-ptr* -- length* )
DUP2 #0001 SUB2
2021-04-24 05:50:21 -04:00
&loop
2021-03-31 18:55:02 -04:00
#0001 ADD2
2021-04-24 05:50:21 -04:00
DUP2 GET ,&loop JNZ
2021-03-31 18:55:02 -04:00
SWP2 SUB2
JMP2r
2021-04-11 04:40:26 -04:00
@append-heap ( string-ptr* -- after-string-ptr* )
2021-04-24 05:50:21 -04:00
.assembler/heap PEK2 ;strcpy JSR2
DUP2 .assembler/heap POK2
2021-04-11 04:40:26 -04:00
JMP2r
2021-03-31 18:55:02 -04:00
2021-04-11 04:40:26 -04:00
@append-tree ( string-ptr* incoming-ptr* -- binary-data* )
2021-04-24 05:50:21 -04:00
.assembler/heap PEK2 SWP2 PUT2
;&zero-pointers .assembler/heap PEK2 #0004 ,memcpy JSR .assembler/heap POK2
,append-heap JSR
2021-04-11 04:40:26 -04:00
JMP2r
2021-03-31 18:55:02 -04:00
2021-04-24 05:50:21 -04:00
&zero-pointers [ 0000 0000 ]
2021-03-31 18:55:02 -04:00
2021-04-11 18:45:31 -04:00
@add-label ( label-flags string-ptr* tree-ptr* -- )
2021-04-24 05:50:21 -04:00
OVR2 #ff ;traverse-tree JSR2
,&new-label JNZ
2021-04-11 04:40:26 -04:00
( label already exists, check the flags and addr value )
SWP2 POP2
2021-04-24 05:50:21 -04:00
DUP2 #0001 ADD2 GET2 .assembler/addr PEK2 EQU2 ,&addr-okay JNZ
2021-04-11 04:40:26 -04:00
( FIXME address is different to previous run, or label defined twice )
2021-04-24 05:50:21 -04:00
&addr-okay
GET EQU ,&type-okay JNZ
2021-04-11 04:40:26 -04:00
( FIXME node type is different to before )
2021-04-24 05:50:21 -04:00
&type-okay
2021-04-11 04:40:26 -04:00
JMP2r
2021-03-31 18:55:02 -04:00
2021-04-24 05:50:21 -04:00
&new-label
,append-tree JSR
2021-04-11 04:40:26 -04:00
(
~assembler.heap SWP2 STR2
,$zero-pointers ~assembler.heap #0004 ^memcpy JSR =assembler.heap
~assembler.heap ,strcpy JSR2
)
2021-04-24 05:50:21 -04:00
DUP2 STH2 PUT STH2r
DUP2 #0001 ADD2 .assembler/addr PEK2 SWP2 PUT2
#0003 ADD2 .assembler/heap POK2
2021-03-31 18:55:02 -04:00
JMP2r
2021-04-11 04:40:26 -04:00
@lookup-label ( string-ptr* -- address* node-type if found
OR false-address* 00 if not found )
2021-04-14 17:00:10 -04:00
DUP2
2021-04-24 05:50:21 -04:00
&loop
DUP2 #0001 ADD2 SWP2 GET
DUP #2e EQU ,&dotted JNZ
,&loop JNZ
2021-04-14 17:00:10 -04:00
DUP2 EOR2 ( faster than POP2 #0000 )
2021-04-24 05:50:21 -04:00
.assembler/field POK2
2021-04-14 17:00:10 -04:00
2021-04-24 05:50:21 -04:00
&main
DUP2 ;label-tree SWP2 #ff ;traverse-tree JSR2
,&not-found JNZ
2021-04-11 04:40:26 -04:00
SWP2 POP2
2021-04-24 05:50:21 -04:00
.assembler/field PEK2 #0000 EQU2 ,&end JNZ
DUP2 GET #80 LTH ,&not-found JNZ
#0003 ADD2 .assembler/field PEK2 #ff ;traverse-tree JSR2
,&not-found JNZ
2021-04-14 17:00:10 -04:00
2021-04-24 05:50:21 -04:00
&end
DUP2 #0001 ADD2 GET2 SWP2 GET
2021-04-11 04:40:26 -04:00
JMP2r
2021-04-24 05:50:21 -04:00
&not-found
2021-04-11 04:40:26 -04:00
POP2
( FIXME complain about missing label )
POP2
( false-address is out of reach for JMP )
2021-04-24 05:50:21 -04:00
.assembler/addr PEK2 #8765 ADD2
2021-04-11 04:40:26 -04:00
#00
JMP2r
2021-04-24 05:50:21 -04:00
&dotted
DUP OVR2 .assembler/field POK2
EOR ROT ROT #0001 SUB2 PUT
,&main JMP
2021-04-14 17:00:10 -04:00
2021-04-11 04:40:26 -04:00
@write-byte ( byte -- )
2021-04-24 05:50:21 -04:00
( FIXME ) .Console/byte DEO
.assembler/addr PEK2 #0001 ADD2 .assembler/addr POK2
2021-04-11 04:40:26 -04:00
JMP2r
@write-short ( short -- )
2021-04-24 05:50:21 -04:00
( FIXME ) .Console/short DEO2
.assembler/addr PEK2 #0002 ADD2 .assembler/addr POK2
2021-04-11 04:40:26 -04:00
JMP2r
2021-04-24 05:50:21 -04:00
@label-tree :l-root
2021-04-11 04:40:26 -04:00
@macro-tree [ 0000 ]
2021-03-31 18:55:02 -04:00
@opcodes
(
The code for this section is automatically generated, and needs to be
regenerated when the opcode list in src/assembler.c is updated.
After editing src/assembler.c, run "lua etc/assembler-trees.lua"
and this file will be edited automatically.
This is the first example of a binary tree in this code, so let's
explore them in general. The format of a tree node in memory is:
left-node* right-node* node-key-cstring binary-data
and the general algorithm is to compare the key you're looking for
against node-key-cstring, and move to the node pointed to by left-node*
or right-node* if the keys don't match. If your key sorts earlier than
use left-node*, otherwise go to right-node*. When you find a node that
matches your key, traverse-bintree gives you a pointer to the
binary-data straight after the node-key-cstring. This data can contain
anything you want: fixed length fields, executable code... in this case
of this opcode tree, we store nothing. traverse-bintree is passed the
maximum length of node-key-cstring, not including the zero, so the zero
can be omitted if the string is at that maximum length.
If the key isn't present in the tree, you'll eventually get to a node
where the left-node* or right-node* pointer you'll need to follow is
null (0000). traverse-bintree will give you the location of that
pointer, so if you want to insert another node, you can write it to the
heap and overwrite the pointer with the new node's location. This
approach works even if the tree is completely empty and the pointer
you've provided to the root node is null, since that pointer gets
updated to point to the first node without needing any special logic.
The ordering of nodes in memory is totally arbitrary, so for pre-
prepared trees like this one we can have our own meaning for the order
of the nodes. By ordering the opcodes by their byte value, we can find
the byte by subtracting $asm from the binary-data pointer and dividing
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.
)
2021-04-24 05:50:21 -04:00
&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 ]
2021-03-31 18:55:02 -04:00
@state-machine-pointers
( normal mode 00 )
2021-04-24 05:50:21 -04:00
:normal-root :normal-main
2021-04-11 04:40:26 -04:00
( macro definition 01 )
2021-04-24 05:50:21 -04:00
:macro-root :macro-main
2021-04-11 04:40:26 -04:00
( macro definition, contents ignored 02 )
2021-04-24 05:50:21 -04:00
:macro-root :ignore
2021-04-11 18:45:31 -04:00
( variable definition, expect field size 04 )
2021-04-24 05:50:21 -04:00
:variable-nul :variable-size
2021-04-11 18:45:31 -04:00
( variable definition, expect field name 08 )
2021-04-24 05:50:21 -04:00
:variable-root :variable-name
2021-04-11 04:40:26 -04:00
( reserved for future use 10 )
2021-04-24 05:50:21 -04:00
[ 0000 ] :ignore
2021-03-31 18:55:02 -04:00
( literal data 20 )
2021-04-24 05:50:21 -04:00
:normal-5d :data-main
2021-04-11 04:40:26 -04:00
( reserved for future use 40 )
2021-04-24 05:50:21 -04:00
[ 0000 ] :ignore
2021-03-31 18:55:02 -04:00
( comment 80 )
2021-04-24 05:50:21 -04:00
:normal-29 :ignore
2021-03-31 18:55:02 -04:00
(
Next up, we have the tree of code corresponding to each token's
first character. Here we do have a binary payload, which is
the code to run when the assembler considers the token.
Some special assembler modes have their own trees. Since comments
have a very simple tree that only understands the end of comments,
we reuse the terminal branch of the main tree as the root of
the comment tree.
)
2021-04-24 05:50:21 -04:00
2021-03-31 18:55:02 -04:00
(
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.
)
2021-04-24 05:50:21 -04:00
@normal-28 [ 0000 ] :normal-29 [ 28 ]
.assembler/state PEK #80 ORA .assembler/state POK
2021-04-11 18:45:31 -04:00
JMP2r
2021-03-31 18:55:02 -04:00
2021-04-24 05:50:21 -04:00
@normal-29 [ 0000 ] [ 0000 ] [ 29 ]
.assembler/state PEK #7f AND .assembler/state POK
2021-04-11 18:45:31 -04:00
JMP2r
2021-03-31 18:55:02 -04:00
(
Ampersands introduce global labels, and define the scope for any
local labels that follow.
)
2021-04-24 05:50:21 -04:00
2021-04-11 04:40:26 -04:00
@normal-@ [ 0000 ] [ 0000 ] [ 40 ]
2021-04-24 05:50:21 -04:00
#00 .assembler/token PEK2 ;label-tree ;add-label JSR2
2021-03-31 18:55:02 -04:00
2021-04-24 05:50:21 -04:00
&scope
.assembler/token PEK2 ;assembler/scope ;strcpy JSR2
DUP2 ;assembler/scope SUB2 .assembler/scope-len POK POP
2021-04-11 04:40:26 -04:00
#0001 SUB2 #2d SWP POK POP
JMP2r
(
Dollar signs introduce local labels, which use the scope defined above.
)
2021-04-24 05:50:21 -04:00
@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 )
2021-04-11 04:40:26 -04:00
(
Hash signs followed by two or four hex digits write a literal.
)
2021-04-24 05:50:21 -04:00
2021-04-11 04:40:26 -04:00
@normal-# [ 0000 ] [ 0000 ] [ 23 ]
2021-04-24 05:50:21 -04:00
.assembler/token PEK2 ;parse-hex-string JSR2
DUP ,&valid JNZ
2021-04-11 04:40:26 -04:00
( FIXME complain about invalid hex literal )
POP
JMP2r
2021-04-24 05:50:21 -04:00
&valid
2021-04-11 04:40:26 -04:00
DUP #01 SUB SHORT_FLAG MUL ( short flag for opcode )
2021-04-24 05:50:21 -04:00
;opcodes/op-lit ;opcodes/start SUB2 #07 DIV
ADD ADD ;write-byte JSR2
2021-04-11 04:40:26 -04:00
2021-04-24 05:50:21 -04:00
&value
#02 EQU ,&short JNZ
;write-byte JMP2 ( tail call )
2021-04-11 04:40:26 -04:00
2021-04-24 05:50:21 -04:00
&short
;write-short JMP2 ( tail call )
2021-04-11 04:40:26 -04:00
2021-04-11 18:45:31 -04:00
(
Left and right square brackets start and end literal data sections.
)
2021-04-24 05:50:21 -04:00
@normal-5b :normal-@ :normal-5d [ 5b ]
.assembler/state PEK #20 ORA .assembler/state POK
2021-04-11 18:45:31 -04:00
JMP2r
2021-04-24 05:50:21 -04:00
@normal-5d [ 0000 ] [ 0000 ] [ 5d ]
.assembler/state PEK #df AND .assembler/state POK
2021-04-11 18:45:31 -04:00
JMP2r
2021-04-24 05:50:21 -04:00
@data-] :normal-28 [ 0000 ] [ 5d ]
.assembler/state PEK #df AND .assembler/state POK
2021-04-11 18:45:31 -04:00
JMP2r
@data-root
2021-04-24 05:50:21 -04:00
@data-nul [ 0000 ] :data-] [ 00 ]
2021-04-11 18:45:31 -04:00
JMP2r
@data-main
2021-04-24 05:50:21 -04:00
.assembler/token PEK2 ;parse-hex-string JSR2
DUP ,normal-#/value JNZ
2021-04-11 18:45:31 -04:00
POP
2021-04-24 05:50:21 -04:00
.assembler/token PEK2
&loop
DUP2 GET
DUP ,&keep-going JNZ
2021-04-11 18:45:31 -04:00
POP POP2 JMP2r
2021-04-24 05:50:21 -04:00
&keep-going
;write-byte JSR2
2021-04-11 18:45:31 -04:00
#0001 ADD2
2021-04-24 05:50:21 -04:00
,&loop JMP
2021-04-11 18:45:31 -04:00
2021-04-11 04:40:26 -04:00
(
A pipe moves the current address to the hex value given.
)
2021-04-24 05:50:21 -04:00
@normal-| :normal-{ :normal-} [ 7c ]
.assembler/token PEK2 ;parse-hex-string JSR2
DUP #02 EQU ,&valid JNZ
2021-04-11 04:40:26 -04:00
#00 EQU JMP POP
( FIXME complain about invalid hex literal )
JMP2r
2021-04-24 05:50:21 -04:00
&valid
2021-04-11 04:40:26 -04:00
POP
2021-04-24 05:50:21 -04:00
DUP2 .assembler/addr PEK2 LTH2 ,&backwards JNZ
2021-04-11 04:40:26 -04:00
( FIXME add zeroes when writing )
2021-04-24 05:50:21 -04:00
.assembler/addr POK2
2021-04-11 04:40:26 -04:00
JMP2r
2021-04-24 05:50:21 -04:00
&backwards
2021-04-11 04:40:26 -04:00
( FIXME complain about going backwards )
POP2
JMP2r
(
Commas and dots write the label address - the comma precedes this
with a LIT2 opcode.
)
2021-04-24 05:50:21 -04:00
@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
2021-04-11 04:40:26 -04:00
POP ( don't care about node type )
2021-04-24 05:50:21 -04:00
;write-short JMP2 ( tail call )
2021-04-11 04:40:26 -04:00
(
Caret writes LIT, followed by the label address as an offset.
)
2021-04-24 05:50:21 -04:00
@normal-^ :normal-5b :normal-| [ 5e ]
;opcodes/op-lit ;opcodes/start SUB2 #07 DIV ;write-byte JSR2 POP
.assembler/token PEK2 ;lookup-label JSR2
2021-04-11 04:40:26 -04:00
POP ( don't care about node type )
2021-04-24 05:50:21 -04:00
.assembler/addr PEK2 SUB2
DUP2 #ff79 GTH2 ,&okay JNZ
DUP2 #0080 LTH2 ,&okay JNZ
2021-04-11 04:40:26 -04:00
( FIXME complain about jump being too far )
2021-04-24 05:50:21 -04:00
&okay
;write-byte JSR2 POP
2021-04-11 04:40:26 -04:00
JMP2r
(
Tilde and equals are the load and store helpers respectively.
If the target is in the zero page, use LDR/PEK or STR/POK opcodes,
otherwise use LDR2/PEK2 or STR2/POK2 opcodes.
)
2021-04-24 05:50:21 -04:00
2021-04-11 04:40:26 -04:00
@normal-~ [ 0000 ] [ 0000 ] [ 7e ]
2021-04-24 05:50:21 -04:00
LIT2r :opcodes/op-ldr LIT2r :opcodes/op-pek
,normal-=/main JMP
2021-04-11 04:40:26 -04:00
@normal-root
2021-04-24 05:50:21 -04:00
@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
2021-04-11 04:40:26 -04:00
( FIXME complain about helper not being usable )
POP2 JMP2r
2021-04-24 05:50:21 -04:00
&valid
#02 AND ,&two-byte JNZ
2021-04-11 04:40:26 -04:00
SWP2r
2021-04-24 05:50:21 -04:00
&two-byte
2021-04-11 04:40:26 -04:00
POP2r
2021-04-24 05:50:21 -04:00
LIT2r :opcodes/start SUB2r LITr [ 07 ] DIVr
OVR #00 EQU ,&byte-mode JNZ
2021-04-11 04:40:26 -04:00
2021-04-24 05:50:21 -04:00
;write-short SHORT_FLAG ,&end JMP
2021-04-11 04:40:26 -04:00
2021-04-24 05:50:21 -04:00
&byte-mode
2021-04-11 04:40:26 -04:00
SWP POP
2021-04-24 05:50:21 -04:00
;write-byte #00
2021-04-11 04:40:26 -04:00
2021-04-24 05:50:21 -04:00
&end
;opcodes/op-lit ;opcodes/start SUB2 #07 DIV ADD ADD ;write-byte JSR2
2021-04-11 04:40:26 -04:00
JSR2
2021-04-24 05:50:21 -04:00
STHr ;write-byte JSR2
2021-04-11 04:40:26 -04:00
POPr
JMP2r
(
Semicolons introduce variables. The variable name is added to the label
tree as usual, but all of the subfields are collected into their own tree
pointed to in the variable name's binary data.
)
2021-04-24 05:50:21 -04:00
2021-04-11 04:40:26 -04:00
@normal-; [ 0000 ] [ 0000 ] [ 3b ]
2021-04-24 05:50:21 -04:00
#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
2021-04-11 04:40:26 -04:00
2021-04-24 05:50:21 -04:00
.assembler/state PEK #0c ORA .assembler/state POK
2021-04-11 04:40:26 -04:00
JMP2r
@variable-root
2021-04-24 05:50:21 -04:00
@variable-{ :variable-nul :variable-} [ 7b ]
2021-04-11 04:40:26 -04:00
JMP2r
2021-04-24 05:50:21 -04:00
@variable-nul [ 0000 ] :normal-28 [ 00 ]
2021-04-11 04:40:26 -04:00
JMP2r
@variable-} [ 0000 ] [ 0000 ] [ 7d ]
2021-04-24 05:50:21 -04:00
.assembler/state PEK #f3 AND .assembler/state POK
2021-04-11 04:40:26 -04:00
JMP2r
@variable-name
2021-04-24 05:50:21 -04:00
#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
2021-04-11 18:45:31 -04:00
JMP2r
2021-04-11 04:40:26 -04:00
@variable-size
2021-04-24 05:50:21 -04:00
.assembler/token PEK2 ;parse-hex-length JSR2
,&valid JNZ
2021-04-11 18:45:31 -04:00
( FIXME complain about invalid size )
JMP2r
2021-04-24 05:50:21 -04:00
&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
2021-04-11 18:45:31 -04:00
2021-04-24 05:50:21 -04:00
&loop
#00 ;write-byte JSR2
2021-04-11 18:45:31 -04:00
#01 SUB
2021-04-24 05:50:21 -04:00
&end
DUP ,&loop JNZ
2021-04-11 18:45:31 -04:00
POP
2021-04-24 05:50:21 -04:00
.assembler/state PEK #0c ORA .assembler/state POK
#0000 .assembler/var_size POK2
2021-04-11 18:45:31 -04:00
JMP2r
2021-04-11 04:40:26 -04:00
(
Percent signs introduce macros. The macro name is added to the macro tree,
and all the arguments are collected into a list that follows the label's
binary data.
)
2021-04-24 05:50:21 -04:00
@normal-% [ 0000 ] :normal-28 [ 25 ]
;macro-tree .assembler/token PEK2 #ff ;traverse-tree JSR2
,&new-macro JNZ
2021-04-11 04:40:26 -04:00
( macro already exists, we assume defined in a previous pass
we totally ignore the contents )
POP2
2021-04-24 05:50:21 -04:00
.assembler/state PEK #02 ORA .assembler/state POK
2021-04-11 04:40:26 -04:00
JMP2r
2021-04-24 05:50:21 -04:00
&new-macro
.assembler/token PEK2 SWP2 ;append-tree JSR2
2021-04-11 04:40:26 -04:00
POP2
2021-04-24 05:50:21 -04:00
.assembler/state PEK #01 ORA .assembler/state POK
2021-04-11 04:40:26 -04:00
JMP2r
@macro-root
2021-04-24 05:50:21 -04:00
@macro-{ :macro-nul :macro-} [ 7b ]
2021-04-11 04:40:26 -04:00
JMP2r
@macro-} [ 0000 ] [ 0000 ] [ 7d ]
2021-04-24 05:50:21 -04:00
.assembler/heap PEK2 DUP2 #00 ROT ROT PUT
#0001 ADD2 .assembler/heap POK2
.assembler/state PEK #fc AND .assembler/state POK
2021-04-11 04:40:26 -04:00
JMP2r
2021-04-24 05:50:21 -04:00
@macro-nul [ 0000 ] :normal-28 [ 00 ]
2021-04-11 04:40:26 -04:00
JMP2r
@macro-main
2021-04-24 05:50:21 -04:00
.assembler/token PEK2 ;append-heap JSR2
2021-04-11 04:40:26 -04:00
POP2
JMP2r
2021-04-24 05:50:21 -04:00
@normal-" :normal-nul :normal-# [ 22 ]
2021-04-11 04:40:26 -04:00
( FIXME NYI )
JMP2r
@normal-{ [ 0000 ] [ 0000 ] [ 7b ]
( these are spurious, but ignore them anyway )
JMP2r
2021-04-24 05:50:21 -04:00
@normal-} [ 0000 ] :normal-~ [ 7d ]
2021-04-11 04:40:26 -04:00
( these are spurious, but ignore them anyway )
JMP2r
@normal-nul [ 0000 ] [ 0000 ] [ 00 ]
2021-03-31 18:55:02 -04:00
@ignore
2021-04-11 04:40:26 -04:00
JMP2r
2021-03-31 18:55:02 -04:00
2021-04-11 18:45:31 -04:00
@normal-main
2021-04-24 05:50:21 -04:00
.assembler/token PEK2
;opcodes/tree OVR2 #03 ;traverse-tree JSR2
,&not-opcode JNZ
2021-03-31 18:55:02 -04:00
2021-04-24 05:50:21 -04:00
;opcodes/asm SUB2 #0007 DIV2
2021-04-12 16:01:36 -04:00
SWP2 #0003 ADD2
2021-04-24 05:50:21 -04:00
&flags
DUP2 GET
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 PEK2 SWP2
,&not-opcode JMP
&end-flags
2021-04-12 16:01:36 -04:00
POP POP2
2021-04-24 05:50:21 -04:00
;write-byte JSR2
2021-04-12 16:01:36 -04:00
POP
JMP2r
2021-04-24 05:50:21 -04:00
&not-opcode
2021-04-12 16:01:36 -04:00
POP2
2021-04-24 05:50:21 -04:00
;macro-tree SWP2 #ff ;traverse-tree JSR2
,&not-macro JNZ
;assemble-macro JMP2 ( tail call )
2021-04-12 16:01:36 -04:00
2021-04-24 05:50:21 -04:00
&not-macro
2021-04-12 16:01:36 -04:00
( FIXME complain about bad opcode / nonexistent macro )
POP2
JMP2r
2021-03-31 18:55:02 -04:00
(
Here's the big set of trees relating to labels. Starting from l-root, all
the devices are stored here, perhaps some helper functions in the future,
too.
left-node* right-node* node-key-cstring binary-data
The node-keys are terminated with NUL since, unlike the opcodes and first
characters, the keys are variable length.
The binary-data is either three or five bytes long:
flags value* [ subtree-pointer* ]
The flags byte is divided up into bits:
2021-04-11 18:45:31 -04:00
bit 0-1: 00 means store / load helpers cannot be used,
01 means the helpers use POK / PEK,
02 means the helpers use STR / LDR,
03 is invalid;
2021-03-31 18:55:02 -04:00
bits 2-6 are reserved; and
bit 7: 80 means there is a subtree.
If there is a subtree, it is searched when the reference contains a dot.
)
2021-04-24 05:50:21 -04:00
@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
2021-04-11 18:45:31 -04:00
@l-Audio-root
2021-04-24 05:50:21 -04:00
@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
2021-03-31 18:55:02 -04:00
@l-Console-root
2021-04-24 05:50:21 -04:00
@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
2021-03-31 18:55:02 -04:00
@l-Controller-root
2021-04-24 05:50:21 -04:00
@l-Controller-key :l-Controller-button :l-Controller-vector [ "key 00 ] [ 01 ] :Controller/key
@l-Controller-vector [ 0000 ] [ 0000 ] [ "vector 00 ] [ 02 ] :Controller/vector
2021-04-11 18:45:31 -04:00
@l-root
2021-04-24 05:50:21 -04:00
@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
2021-04-11 18:45:31 -04:00
@l-DateTime-root
2021-04-24 05:50:21 -04:00
@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
2021-03-31 18:55:02 -04:00
@l-File-root
2021-04-24 05:50:21 -04:00
@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
2021-04-11 18:45:31 -04:00
@l-Mouse-root
2021-04-24 05:50:21 -04:00
@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
2021-03-31 18:55:02 -04:00
@l-Screen-root
2021-04-24 05:50:21 -04:00
@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
2021-04-11 04:40:26 -04:00
@l-System-root
2021-04-24 05:50:21 -04:00
@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
2021-04-11 04:40:26 -04:00
@assembler-heap-start
2021-03-31 18:55:02 -04:00