code: 9ferno

ref: 10405d31c608fe9d448607545195b758b424e70c
dir: /os/pc64/words-nasm.s/

View raw version
CENTRY "false" C_false 5
dd M_literal
dd 0
dd M_exitcolon
CENTRY "true" C_true 4
dd M_literal
dd -1
dd M_exitcolon
CENTRY "bl" C_bl 2
dd M_literal
dd 32
dd M_exitcolon
CENTRY "on" C_on 2		; ( a --  ) (G stores -1 at a )
dd M_literal
dd -1
dd M_xswap
dd M_store
dd M_exitcolon
CENTRY "off" C_off 3		; ( a --  ) (G stores 0 at a )
dd M_literal
dd 0
dd M_xswap
dd M_store
dd M_exitcolon
CENTRY ">body" C_tobody 5
dd M_literal
dd 8
dd M_plus
dd M_exitcolon
CENTRY "aligned" C_aligned 7	; align a number to a multiple of 8
dd M_literal
dd 7
dd M_plus
dd M_literal
dd -8
dd M_binand
dd M_exitcolon
CENTRY "cells" C_cells 5
dd M_literal
dd 3			; (index << 2) -> (index << 3) for amd64
dd M_lshift
dd M_exitcolon
CENTRY "cell+" C_cellplus 5
dd M_literal
dd 1
dd C_cells
dd M_plus
dd M_exitcolon
CENTRY "depth" C_depth 5
dd M_S0
dd M_stackptr
dd M_minus
dd M_literal
dd 3
dd M_rshift
dd M_literal
dd 1
dd M_minus
dd M_exitcolon
CENTRY "nip" C_nip 3
dd M_xswap
dd M_drop
dd M_exitcolon
CENTRY "rot" C_rot 3
dd M_rpush
dd M_xswap
dd M_rpop
dd M_xswap
dd M_exitcolon
CENTRY "2drop" C_2drop 5
dd M_drop
dd M_drop
dd M_exitcolon
CENTRY "2dup" C_2dup 4
dd M_over
dd M_over
dd M_exitcolon
CENTRY "2nip" C_2nip 4
dd C_nip
dd C_nip
dd M_exitcolon
CENTRY "2swap" C_2swap 5
dd C_rot
dd M_rpush
dd C_rot
dd M_rpop
dd M_exitcolon
CENTRY "?dup" C_qdup 4 ; if (n != 0) ( n -- n n) else ( n -- n )
dd M_dup	; ( n -- n n )
dd M_dup	; ( n n -- n n n )
dd M_literal
dd 0		; ( n n n -- n n n 0 )
dd M_equal	; ( n n n 0 -- n n f )
dd M_cjump	; ( n n f -- n n )
dd L20		; when n != 0, go to L20
dd M_drop	; when n == 0 ( n n -- n)
L20:		; when n != 0 ( n n )
dd M_exitcolon
CENTRY "pick" C_pick 4
dd C_qdup
dd M_cjump
dd L22
dd M_literal
dd 1
dd M_plus
dd C_cells
dd M_stackptr
dd M_plus
dd M_fetch
dd M_jump
dd L23
L22:
dd M_dup
L23:
dd M_exitcolon
CENTRY "tuck" C_tuck 4
dd M_dup
dd M_rpush
dd M_xswap
dd M_rpop
dd M_exitcolon
CENTRY "/" C_divides 1
dd M_slashmod
dd C_nip
dd M_exitcolon
CENTRY "+!" C_plusstore 2
dd M_dup
dd M_fetch
dd C_rot
dd M_plus
dd M_xswap
dd M_store
dd M_exitcolon
CENTRY "invert" C_invert 6
dd M_literal
dd -1
dd M_binxor
dd M_exitcolon
CENTRY "mod" C_mod 3
dd M_slashmod
dd M_drop
dd M_exitcolon
CENTRY "1+" C_1plus 2
dd M_literal
dd 1
dd M_plus
dd M_exitcolon
CENTRY "1-" C_1minus 2
dd M_literal
dd 1
dd M_minus
dd M_exitcolon
CENTRY "negate" C_negate 6
dd M_literal
dd 0
dd M_xswap
dd M_minus
dd M_exitcolon
CENTRY "2*" C_2multiplies 2
dd M_literal
dd 1
dd M_lshift
dd M_exitcolon
CENTRY "2/" C_2divides 2
dd M_literal
dd 1
dd M_rshifta
dd M_exitcolon
CENTRY "0=" C_0eq 2
dd M_literal
dd 0
dd M_equal
dd M_exitcolon
CENTRY "0<" C_0lt 2
dd M_literal
dd 0
dd M_less
dd M_exitcolon
CENTRY "0>" C_0gt 2
dd M_literal
dd 0
dd M_greater
dd M_exitcolon
CENTRY "<>" C_neq 2
dd M_equal
dd C_invert
dd M_exitcolon
CENTRY "0<>" C_0neq 3
dd M_literal
dd 0
dd C_neq
dd M_exitcolon
CENTRY "max" C_max 3
dd C_2dup
dd M_greater
dd M_cjump
dd L40
dd M_drop
dd M_jump
dd L41
L40:
dd C_nip
L41:
dd M_exitcolon
CENTRY "min" C_min 3
dd C_2dup
dd M_less
dd M_cjump
dd L43
dd M_drop
dd M_jump
dd L44
L43:
dd C_nip
L44:
dd M_exitcolon
CENTRY "signum" C_signum 6
dd M_dup
dd C_0gt
dd M_cjump
dd L46
dd M_drop
dd M_literal
dd 1
dd M_jump
dd L47
L46:
dd C_0lt
dd M_cjump
dd L48
dd M_literal
dd -1
dd M_jump
dd L49
L48:
dd M_literal
dd 0
L49:
L47:
dd M_exitcolon
CENTRY "within" C_within 6
dd M_rpush
dd M_over
dd M_greater
dd C_0eq
dd M_xswap
dd M_rpop
dd M_greater
dd C_0eq
dd M_binand
dd M_exitcolon
CENTRY "abs" C_abs 3
dd M_dup
dd C_0lt
dd M_cjump
dd L52
dd C_negate
L52:
dd M_exitcolon

CENTRY "key" C_key 3	 ; ( -- c ) (G read a single character from the input onto the stack )
dd MV_Infd
dd M_fetch		; ( infd )
dd MV_Iobuf		; variable iobuf to store the character read
dd M_literal
dd 1			; ( infd Iobuf 1 )
dd M_sysread	; ( infd Iobuf 1 -- n )
dd C_0eq
dd M_cjump		; if 0 characters read
dd L78			; if qread n != 0 jump to L78. If n == 0 jump over
dd MV_Eof
dd C_on		; EOF
dd M_literal
dd -1			; return -1 when EOF
dd M_jump
dd L79
L78:
dd MV_Iobuf		; get the character from Iobuf to stack
dd M_cfetch	; ( -- c ) return the character read if not EOF
L79:
dd M_exitcolon

CENTRY "emit" C_emit 4	; ( character -- )
dd MV_Iobuf		; variable iobuf address
dd M_cstore	; variable iobuf has character
dd MV_Outfd
dd M_fetch		; outfd
dd MV_Iobuf		; variable iobuf address
dd M_literal
dd 1			; ( outfd iobuf 1 )
dd M_syswrite	; ( 1 iobuf outfd --  )
dd M_drop		; drop the return value of write
dd M_exitcolon

CENTRY "type" C_type 4	; ( addr n -- )
dd M_rpush			; ( addr ) (R n )
dd M_rpush			; ( ) (R n addr )
dd M_literal
dd 1				; stdout
dd M_rpop			; ( stdout addr ) (R n )
dd M_rpop			; ( stdout addr n ) (R )
dd M_syswrite		; ( 1 addr n --  )
dd M_drop		; drop the return value of write
dd M_exitcolon

CENTRY "cr" C_cr 2
dd M_literal
dd 10			; ascii value of carriage return
dd C_emit			; emit
dd M_exitcolon

CENTRY "space" C_space 5
dd C_bl
dd C_emit
dd M_exitcolon

CENTRY "emits" C_emits 5
L85:
dd C_qdup
dd M_cjump
dd L86
dd M_over
dd C_emit
dd C_1minus
dd M_jump
dd L85
L86:
dd M_drop
dd M_exitcolon
CENTRY "spaces" C_spaces 6
dd C_bl
dd M_xswap
dd C_emits
dd M_exitcolon
CENTRY "count" C_count 5 ; ( a -- a+1 n ) a = address of counted string ( a - a+1 a[0])
dd C_1plus
dd M_dup
dd C_1minus
dd M_cfetch
dd M_exitcolon

dd C_2dup ; debug show the word name to search
dd C_type
dd C_space

dd M_rpush ; debug show the dictionary entry
dd M_rpush
dd C_2dup
dd C_type
dd M_rpop
dd M_rpop
dd C_cr

CENTRY "compare" C_compare 7 ; ( a1 n1 a2 n2 -- f ) a1 = dictionary entry a2 = word name to search
dd C_rot	; ( a1 n1 a2 n2 -- a1 a2 n2 n1 )
dd C_2dup	; ( -- a1 a2 n2 n1 n2 n1 )
dd M_rpush	; ( -- a1 a2 n2 n1 n2 ) (R n1 -- )
dd M_rpush	; ( -- a1 a2 n2 n1 ) (R n1 n2 -- )
dd C_min	; ( -- a1 a2 nmin ) (R n1 n2 -- )
dd M_literal
dd 0		; ( -- a1 a2 nmin 0 ) (R n1 n2 -- )
dd M_doinit	; ( -- a1 a2 ) (R n1 n2 0 nmin -- )
L55:
dd M_over
dd M_i
dd M_plus
dd M_cfetch
dd M_over
dd M_i
dd M_plus
dd M_cfetch
dd M_minus
dd C_signum
dd C_qdup
dd M_cjump
dd L56		; matches
dd C_2nip	; does not match ( a1 a2 f -- f ) (R n1 n2 0 nmin -- )
dd M_unloop	; ( f -- f ) (R n1 n2 0 nmin -- n1 n2)
dd M_unloop	; ( f -- f ) (R n1 n2 -- )
dd M_exitcolon
L56:
dd M_doloop
dd L55
dd C_2drop	; ( a1 a2 -- ) (R n1 n2 -- )
dd M_rpop
dd M_rpop	; ( n2 n1 -- ) (R -- )
dd M_minus	; ( -- n1-n2 )
dd C_signum
dd M_exitcolon

CENTRY "erase" C_erase 5
dd M_literal
dd 0
dd M_doinit
L58:
dd M_literal
dd 0
dd M_over
dd M_cstore
dd C_1plus
dd M_doloop
dd L58
dd M_drop
dd M_exitcolon
CENTRY "fill" C_fill 4
dd M_xswap
dd M_literal
dd 0
dd M_doinit
L60:
dd C_2dup
dd M_xswap
dd M_i
dd M_plus
dd M_cstore
dd M_doloop
dd L60
dd C_2drop
dd M_exitcolon
CENTRY "blank" C_blank 5
dd C_bl
dd C_fill
dd M_exitcolon
CENTRY "search" C_search 6
dd MV_Searchlen
dd M_store
dd M_xswap
dd M_dup
dd M_rpush
dd MV_Searchlen
dd M_fetch
dd M_minus
dd C_1plus
dd M_literal
dd 0
dd M_doinit
L64:
dd M_over
dd M_i
dd M_plus
dd M_over
dd MV_Searchlen
dd M_fetch
dd M_xswap
dd MV_Searchlen
dd M_fetch
dd C_compare
dd C_0eq
dd M_cjump
dd L65
dd M_drop
dd M_i
dd M_plus
dd M_i
dd M_unloop
dd M_rpop
dd M_xswap
dd M_minus
dd C_true
dd M_exitcolon
L65:
dd M_doloop
dd L64
dd M_drop
dd M_rpop
dd C_false
dd M_exitcolon
CENTRY "here" C_here 4
dd M_Dp
dd M_fetch
dd M_exitcolon
CENTRY "vhere" C_vhere 4
dd M_Vp
dd M_fetch
dd M_exitcolon
CENTRY "," C_comma 1
dd C_here
dd M_store
dd M_literal
dd 8
dd M_Dp
dd C_plusstore
dd M_exitcolon
CENTRY "c," C_c 2
dd C_here
dd M_cstore
dd M_literal
dd 1
dd M_Dp
dd C_plusstore
dd M_exitcolon
CENTRY "allot" C_allot 5 ; ( n -- ) here = here+n
dd M_Dp
dd C_plusstore
dd M_exitcolon
CENTRY "vallot" C_vallot 6 ; allot on the variable space ( n -- ) vhere = vhere+n
dd M_Vp
dd C_plusstore
dd M_exitcolon
CENTRY "pad" C_pad 3
dd C_here
dd M_literal
dd 256
dd M_plus
dd M_exitcolon
CENTRY "align" C_align 5	; ( -- ) align here to a cell boundary
dd C_here		; Dp @
dd C_aligned	; here is aligned to a multiple of 8
dd M_Dp			; store the aligned here at Dp
dd M_store		; Dp contains aligned_here
dd M_exitcolon
CENTRY "unused" C_unused 6
dd M_Dp
dd M_fetch
dd C_here
dd M_minus
dd M_exitcolon
CENTRY "<#" C_fromhash 2
dd C_pad
dd M_literal
dd 1024
dd M_plus
dd MV_toNum
dd M_store
dd M_exitcolon
CENTRY "#" C_hash 1
dd MV_Base
dd M_fetch
dd M_uslashmod
dd M_xswap
dd M_dup
dd M_literal
dd 9
dd M_greater
dd M_cjump
dd L92
dd M_literal
dd 97
dd M_plus
dd M_literal
dd 10
dd M_minus
dd M_jump
dd L93
L92:
dd M_literal
dd 48
dd M_plus
L93:
dd MV_toNum
dd M_fetch
dd C_1minus
dd M_dup
dd MV_toNum
dd M_store
dd M_cstore
dd M_exitcolon
CENTRY "#s" C_hashs 2
L95:
dd C_hash
dd M_dup
dd M_cjump
dd L96
dd M_jump
dd L95
L96:
dd M_exitcolon
CENTRY "#>" C_hashfrom 2
dd M_drop
dd MV_toNum
dd M_fetch
dd M_dup
dd C_pad
dd M_literal
dd 1024
dd M_plus
dd M_xswap
dd M_minus
dd M_exitcolon
CENTRY "hold" C_hold 4
dd MV_toNum
dd M_fetch
dd C_1minus
dd M_dup
dd M_rpush
dd M_cstore
dd M_rpop
dd MV_toNum
dd M_store
dd M_exitcolon
CENTRY "sign" C_sign 4
dd C_0lt
dd M_cjump
dd L100
dd M_literal
dd 45
dd C_hold
L100:
dd M_exitcolon

CENTRY "." C_dot 1	; print the top of stack ( n -- )
dd M_dup		; ( n -- n n )
dd C_abs		; ( n n -- n u )
dd C_fromhash	; pad = h+256; >num = pad+1024
dd C_hashs		; ( n u1 -- n n2 )
dd M_xswap		; ( n n2 -- n2 n )
dd C_sign		; ( n2 n -- n2 )
dd C_hashfrom	; ( u1 -- a n )
dd C_type		; ( a n -- )
dd C_space
dd M_exitcolon
CENTRY ".r" C_dotr 2
dd M_rpush
dd M_dup
dd C_abs
dd C_fromhash
dd C_hashs
dd M_xswap
dd C_sign
dd C_hashfrom
dd M_rpop
dd M_over
dd M_minus
dd M_literal
dd 0
dd C_max
dd C_spaces
dd C_type
dd M_exitcolon
CENTRY "hex" C_hex 3
dd M_literal
dd 16
dd MV_Base
dd M_store
dd M_exitcolon
CENTRY "decimal" C_decimal 7
dd M_literal
dd 10
dd MV_Base
dd M_store
dd M_exitcolon

CENTRY "digit" C_digit 5 ; ( c -- )
dd M_dup
dd M_literal
dd 65
dd M_literal
dd 91
dd C_within
dd M_cjump
dd L106
dd M_literal
dd 55
dd M_minus
dd M_jump
dd L107
L106:
dd M_dup
dd M_literal
dd 97
dd M_literal
dd 123
dd C_within
dd M_cjump
dd L108
dd M_literal
dd 87
dd M_minus
dd M_jump
dd L109
L108:
dd M_dup
dd M_literal
dd 48
dd M_literal
dd 58
dd C_within
dd M_cjump
dd L110
dd M_literal
dd 48
dd M_minus
dd M_jump
dd L111
L110:
dd M_drop
dd C_false
dd M_exitcolon
L111:
L109:
L107:
dd M_dup
dd MV_Base
dd M_fetch
dd M_less
dd M_cjump
dd L112
dd C_true
dd M_jump
dd L113
L112:
dd M_drop
dd C_false
L113:
dd M_exitcolon

CENTRY "number" C_number 6 ; ( a n1 -- n2 -1 | a n1 0 )
dd M_xswap	; ( a n1 -- n1 a )
dd M_dup	; ( n1 a -- n1 a a )
dd M_cfetch	; ( n1 a a -- n1 a c )
dd M_literal
dd 45		; ( n1 a c -- n1 a c - )
dd M_equal	; ( n1 a c -- n1 a f )
dd M_cjump	; ( n1 a c -- n1 a )
dd L115		; c != -
dd C_1plus	; c == - ( n1 a -- n1 a+1 )
dd M_xswap
dd C_1minus	; c == - ( a+1 n1 -- a+1 n1-1 )
dd M_literal
dd -1		; ( a+1 n1-1 -- a+1 n1-1 -1 )
dd M_rpush	; ( a+1 n1-1 -- a+1 n1-1 ) (R -- -1)
dd M_jump
dd L116
L115:		; c != -
dd M_xswap	; ( n1 a -- a n1)
dd M_literal
dd 1
dd M_rpush	; ( a n1 1 -- a n1 ) (R -- 1)
L116:		; ( a n1 ) (R nr)
dd M_dup	; ( a n1 -- a n1 n1 ) (R nr)
dd M_rpush	; ( a n1 n1 -- a n1 ) (R nr -- nr n1)
dd M_literal
dd 0		; ( a n1 -- a n1 0) (R nr n1)
dd M_xswap	; ( a n1 0 -- a 0 n1) (R nr n1)
dd M_literal
dd 0		; ( a 0 n1 -- a 0 n1 0) (R nr n1)
dd M_doinit	; ( a 0 n1 0 -- a 0 ) (R nr n1 -- nr n1 0 n1)
L117:
dd MV_Base
dd M_fetch	; ( a 0 Base -- a 0 10 ) (R nr n1 -- nr n1 0 n1)
dd M_multiply	; ( a 0 10 -- a 0 ) (R nr n1 -- nr n1 0 n1)
dd M_over	; ( a 0 -- a 0 a) (R nr n1 -- nr n1 0 n1)
dd M_i		; ( a 0 a -- a 0 a n1) (R nr n1 -- nr n1 0 n1)
dd M_plus	; ( a 0 a n1 -- a 0 a+n1) (R nr n1 -- nr n1 0 n1)
dd M_cfetch	; ( a 0 a+n1 -- a 0 c) (R nr n1 -- nr n1 0 n1)
dd C_digit
dd M_cjump
dd L118
dd M_plus
dd M_jump
dd L119
L118:
dd M_drop
dd M_unloop
dd M_rpop
dd M_rpop
dd M_drop
dd C_false
dd M_exitcolon
L119:
dd M_doloop
dd L117
dd M_rpop
dd M_drop
dd C_nip
dd M_rpop
dd M_multiply
dd C_true
dd M_exitcolon

CENTRY "abort" C_abort 5
dd MV_Abortvec
dd M_fetch
dd M_execute
dd M_exitcolon
CENTRY "source" C_source 6
dd MV_Sourcebuf
dd M_fetch
dd M_exitcolon

CENTRY "current-input" C_current_input 13 ; ( -- c ) read the next character from the location in Sourcebuf
dd MV_toIn
dd M_fetch
dd C_source
dd M_plus		; Sourcebuf + >In
dd M_cfetch
dd M_exitcolon

CENTRY "save-input" C_save_input 10
dd MV_Infd
dd MV_toIn
dd M_fetch
dd MV_toLimit
dd M_fetch
dd MV_Sourcebuf
dd M_fetch
dd MV_Blk
dd M_fetch
dd M_literal
dd 5
dd MV_Ninputs
dd C_plusstore	; Ninputs++
dd M_exitcolon

CENTRY "default-input" C_default_input 13
dd MC_STDIN
dd MV_toIn
dd C_off
dd MV_toLimit
dd C_off
dd M_Tib
dd MV_Sourcebuf
dd M_store
dd MV_Blk
dd C_off
dd M_exitcolon

CENTRY "restore-input" C_restore_input 13 ; ( <input>|empty -- f )

dd MV_Ninputs	; if Ninputs == 0, leave 0 on the stack. Or, Ninputs--
dd M_fetch
dd C_0neq
dd M_cjump
dd L300
dd MV_Ninputs	; there are <input>'s pending on the stack
dd M_fetch
dd C_1minus
dd MV_Ninputs
dd M_store
dd M_jump
dd L301		; ( <input> -- <input>)
L300:	; no more <input>'s on the stack, put 0 on the stack for the 5 <> below to work
dd M_literal
dd 0

L301:
dd MV_Eof
dd C_off
dd M_literal
dd 5
dd C_neq
dd M_cjump
dd L133
dd C_default_input
dd C_false
dd M_jump
dd L134
L133:
dd MV_Blk
dd M_store
dd MV_Sourcebuf
dd M_store
dd MV_toLimit
dd M_store
dd MV_toIn
dd M_store
dd MV_Infd
dd M_store
dd C_true
L134:
dd M_exitcolon

CENTRY "?restore-input" C_qrestore_input 14 ; ( <input> -- f )
dd C_restore_input
dd C_0eq
dd M_cjump
dd L136
dd C_space
dd M_literal
dd L137
dd M_literal
dd 23
dd C_type
dd C_space
dd C_depth
dd C_dot
dd C_cr
dd C_abort
L136:
dd M_exitcolon

CENTRY "next-input" C_next_input 10 ; when >In < >Limit ( -- true c ). ( --  0 false ) otherwise
dd MV_toIn
dd M_fetch
dd MV_toLimit
dd M_fetch
dd M_less
dd M_cjump
dd L139	; >In >= >Limit
dd C_true	; >In < >Limit
dd C_current_input	; ( -- c )
dd M_jump
dd L140
L139:
dd M_literal
dd 0
dd C_false
L140:
dd M_exitcolon

CENTRY "parse" C_parse 5	; ( c -- a ) Place the counted string in the address in Wordbuf and return that address. c = word delimiter.
dd M_rpush		; ( c -- ) (R -- c )
dd MV_Wordbuf
dd M_fetch		; ( -- Wordb )
dd C_1plus		; ( Wordb -- Wordb+1 )
L142:
dd C_next_input ; ( Wordb+1 -- Wordb+1 f c )
dd M_rfetch 	; ( Wordb+1 f c -- Wordb+1 f  cinitial ) (R c -- c )
dd C_neq 		; ( Wordb+1 f c cinitial -- Wordb+1 f f(c!=cinitial) )
dd M_binand
dd M_cjump
dd L143		; ( Wordb+1 ) >In >= >Limit || cinitial == cnew
dd C_current_input	; ( Wordb+1 -- Wordb+1 c )
dd M_over
dd M_cstore	; ( Wordb+1 c Wordb+1 -- Wordb+1 ) store c at Wordb+1
dd C_1plus		; ( Wordb+1 -- Wordb+2 )
dd M_literal
dd 1
dd MV_toIn
dd C_plusstore	; >In++
dd M_jump
dd L142		; ( Wordb+2 ) repeat
L143:		; ( Wordb+1 ) >In >= >Limit || cinitial == cnew
dd M_literal
dd 1
dd MV_toIn
dd C_plusstore	; >In++
dd M_rpop		; (Wordb+1 -- Wordb+1 c) (R c -- )
dd M_drop		; (Wordb+1 c -- Wordb+1)
dd MV_Wordbuf
dd M_fetch		; (Wordb+1 -- Wordb+1 Wordb)
dd M_dup		; (Wordb+1 Wordb -- Wordb+1 Wordb Wordb)
dd M_rpush		; (Wordb+1 Wordb Wordb -- Wordb+1 Wordb) (R -- Wordb)
dd M_minus		; (Wordb+1 Wordb -- Wordb+1-Wordb) (R -- Wordb)
dd C_1minus	; (Wordb+1-Wordb -- Wordb+1-Wordb-1) (R -- Wordb)
dd M_rfetch	; (Wordb+1-Wordb-1 Wordb -- Wordb+1-Wordb-1 Wordb) (R -- Wordb)
dd M_cstore	; store the length of the string found at Wordb[0]. Counted string at Wordb now.
dd M_rpop		; ( -- Wordb) (R Wordb -- )
dd M_exitcolon

CENTRY "word" C_word 4 ; ( c -- a ) skip the c"s. Placed the counted string in a (as in Wordbuf)
dd M_rpush	; ( -- ) (R -- c )
L145:
dd C_next_input ; ( -- f c2 ) (R c1 -- )
dd M_rfetch	; ( f cnew -- f cnew cinitial ) (R cinitial -- cinitial )
dd M_equal		; ( f cnew cinitial -- f f(cnew==cinitial) ) (R cinitial -- cinitial )
dd M_binand	; ( f f2 -- f&&f2 ) (R cinitial -- cinitial )
dd M_cjump
dd L146		; >In >= >Limit || cinitial != cnew
dd M_literal	; >In < >Limit && cinitial == cnew
dd 1
dd MV_toIn
dd C_plusstore	; >In++
dd M_jump		; repeat
dd L145
L146:
dd M_rpop		; ( -- cinitial ) Sourcebuf+>In = location of first non-matching character
dd C_parse
dd M_exitcolon

CENTRY "accept" C_accept 6	; ( a n -- n ) get line or n chars or EOF from input and store at a
dd M_xswap	; ( n a -- )
dd M_dup	; ( n a a -- )
dd M_rpush
dd M_rpush	; ( n -- ) (R a a -- )
L148:
dd C_qdup	; ( n n -- ) (R a a -- )
dd M_cjump	; (if)
dd L149	; n == 0
dd C_key	; n > 0 ( n -- n c )
dd M_dup	; ( -- n c c )
dd M_literal
dd 10		; ( -- n c c 10 )
dd M_equal	; ( n c c 10 -- n c f ) checking for newline
dd M_over	; ( -- n c f c )
dd M_literal
dd -1		; ( -- n c f c -1 )
dd M_equal	; ( -- n c f1 f2 )
dd M_binor	; ( -- n c f )
dd M_cjump
dd L150
dd C_2drop	; n == -1 || n == 10 (	-- )
dd M_rpop
dd M_rpop
dd M_minus	; ( -- a2-a1 )
dd M_exitcolon	; ( -- n ) (R -- )
L150:		; not EOF or newline continue
dd M_rfetch	; ( n c a -- ) (R a a -- )
dd M_cstore	; store the character at a
dd M_rpop	; ( n a -- ) (R a -- )
dd C_1plus
dd M_rpush	; ( n -- ) (R a1 -- a1 a2 ) a1 = begin address a2 = current address
dd C_1minus	; ( n -- n-1 )
dd M_jump
dd L148	; loop again for the next character
L149:		; n == 0 ( -- ) (R a1 a2 -- )
dd M_rpop	; ( -- a2 ) (R a1 a2 -- a1 )
dd M_rpop	; ( a2 a1 -- ) (R a1 -- )
dd M_minus	; ( a2 a1 -- a2-a1 )
dd M_exitcolon

CENTRY "query" C_query 5	; read from input stream into the Text Input Buffer
dd MV_Eof
dd C_off		; clear EOF flag
dd M_Tib	; constant puts address of tibuffer on the top
dd M_literal
dd 4096	; ( tibuffer -- tibuffer 4096 )
dd C_accept ; ( tibuffer 4096 -- n )
dd M_dup	; ( n -- n n )
dd C_0eq	; ( n n -- n f )
dd MV_Eof
dd M_fetch
dd M_binand	; n == 0 && EOF
dd M_cjump
dd L152		; false condition
dd M_drop	; n == 0 && EOF ( n -- )
dd C_qrestore_input
dd M_jump
dd L153
L152:			; n > 0
dd MV_toLimit
dd M_store		; number of characters to read >Limit = n
dd MV_toIn
dd C_off		; start from 0 >In = 0
L153:
dd M_exitcolon

CENTRY "refill" C_refill 6
dd MV_Blk
dd M_fetch
dd M_cjump
dd L155
dd C_false
dd M_jump
dd L156
L155:
dd C_query
dd C_true
L156:
dd M_exitcolon

CENTRY "findname" C_findname 8 ; ( a1 -- a2 f ) ; loop through the dictionary names
dd MV_Findadr
dd M_store
dd M_Dtop
dd M_fetch	; get latest dictionary link
L158:
dd C_qdup
dd M_cjump
dd L159	; seached until the first dictionary entry get out
dd M_dup	; ( a -- a a )
dd C_cellplus	; ( a a -- a a+8) lenth + initial name address
dd M_cfetch	; ( a a+8 -- a immediate|hidden|len) length + initial name
dd M_literal
dd 64		; check the reveal'ed flag 1=hidden, 0=reveal
dd M_binand	; if hidden, goto L161 else L160
dd M_cjump
dd L160
dd M_fetch	; smudge'd dictionary entry, get the previous entry
dd M_jump
dd L161
L160:		; reveal'ed dictionary entry
dd M_dup	; ( a1 -- a1 a1)
dd C_cellplus	; ( a1 a1 -- a1 a1+8)
dd C_count	; ( a1 a1+8 -- a1 a1+8+1 n )
dd M_literal
dd 63
dd M_binand	; ( a1 a1+8+1 n 63 -- a1 a1+8+1 n&63=len )
dd MV_Findadr
dd M_fetch
dd C_count	; ( a1 a1+8+1 len=n&63 a2 -- a1 a1+8+1 n&63 a2+1 n2 )
dd C_compare	; ( a1 a1+8+1 len=n&63 a2+1 n2 -- a1 f ) compare dictionary entry with name
dd C_0eq	; found a match?
dd M_cjump
dd L162		; no match
dd C_cellplus	; match found
dd C_true
dd M_exitcolon
L162:
dd M_fetch
L161:
dd M_jump
dd L158
L159:
dd MV_Findadr
dd M_fetch
dd C_false
dd M_exitcolon

CENTRY "find" C_find 4 ; ( a1 -- a2 f )?
dd C_findname
dd M_cjump
dd L164
dd M_dup
dd M_cfetch
dd M_xswap
dd M_over
dd M_literal
dd 63
dd M_binand
dd M_plus
dd C_1plus
dd C_aligned
dd M_xswap
dd M_literal
dd 128
dd M_binand
dd M_cjump
dd L165
dd M_literal
dd 1
dd M_jump
dd L166
L165:
dd M_literal
dd -1
L166:
dd M_exitcolon
dd M_jump
dd L167
L164:
dd C_false
L167:
dd M_exitcolon

CENTRY "'" C_single_quote 1
dd C_bl
dd C_word
dd C_find
dd C_0eq
dd M_cjump
dd L169
dd C_space
dd C_count
dd C_type
dd M_literal
dd L170
dd M_literal
dd 3
dd C_type
dd C_cr
dd C_abort
L169:
dd M_exitcolon
CENTRY "?stack" C_qstack 6
dd M_stackptr
dd M_S0
dd M_greater
dd M_cjump
dd L172
dd M_literal
dd L173
dd M_literal
dd 16
dd C_type
dd C_cr
dd C_abort
L172:
dd M_exitcolon


dd MC_STDOUT	; ( str -- str 1) ; debug code to show the word found
dd M_over		; ( str 1 str )
dd C_count 		; ( str 1 a n)
dd M_syswrite
dd M_drop		; drop the return value of write

CENTRY "interpret" C_interpret 9 ; there is stuff in TIB to be interpreted >In and >Limit are set

L175:
dd C_bl
dd C_word	; ( bl -- a ) a = address of counted string
dd M_dup
dd M_cfetch
dd C_0neq
dd M_cjump
dd L176	; count at a = 0
dd C_find	; ( a -- a1 f ) a = address of counted string
dd M_cjump
dd L177

dd M_execute	; found in dictionary, execute
dd C_qstack
dd M_jump
dd L178
L177:		; not found in the dictionary, check for number?
dd C_count
dd C_number
dd C_0eq
dd M_cjump
dd L179
dd C_space
dd C_type
dd M_literal
dd L180	; error I?
dd M_literal
dd 3
dd C_type
dd C_cr
dd C_abort
L179:		; is a number
L178:
dd M_jump
dd L175
L176:
dd M_drop	; count at a = 0 ( a -- )
dd M_exitcolon

CENTRY "create" C_create 6	; compiles dictionary header until the pfa (link, len, name, cfa)
dd C_align	; sets Dp = aligned here
dd C_here	; ( -- here )
dd M_rpush	; ( -- ) (R -- linkaddr )
dd M_Dtop	; ( -- Dtop ) (R -- linkaddr )
dd M_fetch	; ( Dtop -- dtop ) (R -- linkaddr )
dd C_comma	; ( dtop -- ) (R -- linkaddr )
dd C_bl
dd C_word	; get the word from the input stream ( c -- a ) skip any c. Placed the counted string in a (as in Wordbuf)
dd M_dup	; ( a -- a a ) (R -- linkaddr )
dd M_cfetch	; ( a a -- a len ) (R -- linkaddr )
dd C_here	; ( a len -- a len here ) (R -- linkaddr )
dd M_xswap	; ( a len here -- a here len ) (R -- linkaddr )
dd C_1plus	; ( a here len -- a here len+1 ) (R -- linkaddr ) using len+1 to copy even the length byte
dd M_dup	; ( a here len+1 -- a here len+1 len+1 ) (R -- linkaddr )
dd M_rpush	; ( a here len+1 len+1 -- a here len+1 ) (R -- linkaddr len+1 )
dd M_cmove	; ( a here len+1 -- ) (R -- linkaddr len+1 )
dd M_rpop	; ( -- len+1 ) (R -- linkaddr )
dd C_allot	; ( -- ) (R -- linkaddr ) here = here+len+1
dd C_align	; sets Dp = aligned here
dd M_literal
dd M_variable
dd M_fetch	; ( -- variablecfa) (R -- linkaddr )
dd C_comma	; ( -- ) put the variablecfa into the cfa
dd M_rpop	; ( -- linkaddr) (R -- )
dd M_Dtop
dd M_store	; Dtop = just created link address
dd M_exitcolon

CENTRY "variable" C_variable 8	; compile to put the vhere then on the stack
dd C_create
dd C_vhere
dd C_comma	; put the next available variable location in pfa

dd M_literal
dd 1
dd C_cells
dd C_vallot	; vhere = vhere+8, stored at Vp
dd M_exitcolon

CENTRY "constant" C_constant 8 ; ( n -- ) do the same as variable but change the cfa to (constant)
dd C_create	; create dictionary header upto the cfa
dd M_literal
dd M_constant
dd M_fetch	; ( Contstantcfa -- (constant) )
dd C_here	; ( (constant) -- (constant) here )
dd M_literal
dd 1
dd C_cells	; ( (constant) here -- (constant) here 8 )
dd M_minus	; ( (constant) here 8 -- (constant) here-8 )
dd M_store	; ( (constant) here-8 -- ) changed cfa from (variable) to (constant) 
dd C_comma	; store n into the dictionary
dd M_exitcolon

CENTRY "immediate" C_immediate 9
dd M_Dp
dd M_fetch
dd C_cellplus
dd M_dup
dd M_cfetch
dd M_literal
dd 128
dd M_binor
dd M_xswap
dd M_cstore
dd M_exitcolon
CENTRY ">cfa" C_tocfa 4
dd C_count
dd M_literal
dd 63
dd M_binand
dd M_plus
dd C_aligned
dd M_exitcolon
CENTRY "compile" C_compile 7
dd C_findname
dd M_cjump
dd L188
dd M_dup
dd M_cfetch
dd M_literal
dd 128
dd M_binand
dd M_cjump
dd L189
dd C_tocfa	; immediate
dd M_execute
dd C_qstack
dd M_jump
dd L190
L189:
dd C_tocfa
dd C_comma
L190:
dd M_jump
dd L191
L188:
dd C_count
dd C_number
dd C_0eq
dd M_cjump
dd L192
dd C_space
dd C_type
dd M_literal
dd L193
dd M_literal
dd 3
dd C_type
dd C_cr
dd C_abort
dd M_jump
dd L194
L192:
dd M_literal
dd M_literal
dd C_comma
dd C_comma
L194:
L191:
dd M_exitcolon
CENTRY "]" C_close_bracket 1
dd MV_State
dd C_on
L196:
dd C_bl
dd C_word
dd M_dup
dd M_cfetch
dd C_0eq
dd M_cjump
dd L197
dd M_drop
dd C_refill
dd M_jump
dd L198
L197:
dd C_compile
dd MV_State
dd M_fetch
L198:
dd M_cjump
dd L199
dd M_jump
dd L196
L199:
dd M_exitcolon
CIENTRY "[" CI_open_bracket 1
dd MV_State
dd C_off
dd M_exitcolon
CENTRY "smudge" C_smudge 6
dd M_Dp
dd M_fetch
dd C_cellplus
dd M_dup
dd M_cfetch
dd M_literal
dd 64
dd M_binor
dd M_xswap
dd M_cstore
dd M_exitcolon
CENTRY "reveal" C_reveal 6
dd M_Dp
dd M_fetch
dd C_cellplus
dd M_dup
dd M_cfetch
dd M_literal
dd 64
dd C_invert
dd M_binand
dd M_xswap
dd M_cstore
dd M_exitcolon

CENTRY ":" C_colon 1
dd C_create	; create a dictionary header with (variable) at cfa
dd C_smudge
dd M_literal
dd M_colon
dd M_fetch	; ( Coloncfa -- (colon) ) fetches the cfa of M_colon
dd C_here	; ( (colon) -- (colon) here )
dd M_literal
dd 1
dd C_cells
dd M_minus	; ( (colon) here -- (colon) here-8 )
dd M_store	; ( (colon) here-8 -- ) change the cfa from (variable) to colon
dd C_close_bracket
dd M_exitcolon

CIENTRY ";" CI_semicolon 1
dd M_literal
dd M_exitcolon
dd C_comma
dd MV_State
dd C_off
dd C_reveal
dd M_exitcolon
CIENTRY "recurse" CI_recurse 7
dd M_Dp
dd M_fetch
dd C_cellplus
dd C_tocfa
dd C_comma
dd M_exitcolon
CENTRY "char" C_char 4	; ( -- c ) fetch the first character of the next word from input
dd C_bl
dd C_word	; ( c -- a ) puts the address of the counted string from the input on the stack
dd C_1plus	; skip the count
dd M_cfetch	; fetch the first character
dd M_exitcolon
CENTRY "literal" C_literal 7	; ( n -- ) adds (literal) n to the dictionary
dd M_literal
dd M_literal
dd C_comma
dd C_comma
dd M_exitcolon
CENTRY "sliteral" C_sliteral 8	; ( -- ) adds (sliteral) a n to the dictionary
dd M_literal
dd M_sliteral
dd C_comma	; adds (sliteral) to the dictionary
dd C_here	; ( -- here)
dd M_literal
dd 34		; ascii value of "
dd C_parse	; ( here \" -- here a ) \" = word delimiter. a = address of counted string (in Wordbuf).
dd M_dup	; ( here a -- here a a )
dd M_cfetch	; ( here a a -- here a n )
dd C_1plus	; ( here a n -- here a n+1 ) n+1 as 1 for the count and n for the length of the string
dd M_rpush	; ( here a n+1 -- here a ) (R -- n+1)
dd M_xswap	; ( here a -- a here ) (R -- n+1)
dd M_rfetch	; ( a here -- a here n+1 ) (R -- n+1 )
dd M_cmove	; ( a here n+1 -- ) moves n+1 from a to here
dd M_rpop	; ( -- n+1 ) (R -- )
dd C_allot	; ( n+1 -- ) here = here+n+1
dd C_align	; align here
dd M_exitcolon
CENTRY "string" C_string 6 ; ( c -- ) 
dd C_word
dd M_dup
dd M_cfetch
dd C_1plus
dd M_rpush
dd C_here
dd M_rfetch
dd M_cmove
dd M_rpop
dd C_allot
dd M_exitcolon
CIENTRY "[char]" CI_char_brackets 6	; take the next character from the input stream during compilation
dd C_bl
dd C_word
dd C_1plus
dd M_cfetch
dd C_literal
dd M_exitcolon
CIENTRY "[']" CI_quote_brackets 3	; take the address of next token from the input stream during compilation
dd C_single_quote
dd C_literal
dd M_exitcolon
CIENTRY "(" CI_openparen 1	; ignore until ) from the input stream during compilation
dd M_literal
dd 41
dd C_parse
dd M_drop
dd M_exitcolon
CIENTRY "\\" CI_backslash 1
dd MV_Blk
dd M_fetch
dd M_cjump
dd L214
dd MV_toIn
dd M_fetch
dd M_literal
dd 63
dd M_plus
dd M_literal
dd 63
dd C_invert
dd M_binand
dd MV_toIn
dd M_store
dd M_jump
dd L215
L214:
dd MV_toLimit
dd M_fetch
dd MV_toIn
dd M_store
L215:
dd M_exitcolon
CENTRY "(?abort)" C_qabort_parens 8
dd MV_State
dd M_cjump
dd L217
dd C_space
dd C_type
dd C_cr
dd C_abort
dd M_jump
dd L218
L217:
dd C_2drop
L218:
dd M_exitcolon
CIENTRY "abort\"" CI_abort_double_quote 6
dd C_sliteral
dd M_literal
dd C_qabort_parens
dd C_comma
dd M_exitcolon
CENTRY "\"" C_double_quote 1	; stores counted string in the dictionary and also leaves the address count of the string on the stack - used to use strings at the interpreter prompt
dd M_literal
dd 34
dd C_word
dd C_count
dd M_rpush
dd C_here
dd M_rfetch
dd M_cmove
dd C_here
dd M_rpop
dd M_dup
dd C_allot
dd M_exitcolon
CENTRY "c\"" C_cdouble_quote 2	; stores counted string in the dictionary and also leaves the address of the counted string on the stack
dd M_literal
dd 34		; ( -- \" )
dd C_word	; ( \" -- a ) a = counted string address. a will be in Wordbuf
dd M_dup	; ( a -- a a)
dd M_cfetch	; ( a a -- a n )
dd C_1plus	; ( a n -- a n+1 )
dd M_rpush	; ( a n -- a ) (R -- n+1)
dd C_here	; ( a -- a here ) (R -- n+1)
dd M_rfetch	; ( a here -- a here n+1) (R -- n+1)
dd M_cmove	; move counted string from a to here
dd C_here	; ( -- here )
dd M_rpop	; ( here -- here n+1 )(R -- )
dd C_allot	; ( here n+1 -- here) here += n+1
dd M_exitcolon
CIENTRY "s\"" CI_sdouble_quote 2	; add the string from the input stream to the dictionary as (sliteral) count string - at run-time puts the ( -- addr n) of the counted string on the stack.
dd C_sliteral
dd M_exitcolon
CIENTRY ".\"" CI_dotstr 2	; do what s" does and then add a type word to the dictionary to print that string
dd C_sliteral
dd M_literal
dd C_type
dd C_comma
dd M_exitcolon
CIENTRY "if" CI_if 2
dd M_literal
dd M_cjump
dd C_comma
dd C_here
dd M_literal
dd 0
dd C_comma
dd M_exitcolon
CIENTRY "else" CI_else 4
dd M_literal
dd M_jump
dd C_comma
dd C_here
dd M_rpush
dd M_literal
dd 0
dd C_comma
dd C_here
dd M_xswap
dd M_store
dd M_rpop
dd M_exitcolon
CIENTRY "then" CI_then 4
dd C_here
dd M_xswap
dd M_store
dd M_exitcolon
CIENTRY "begin" CI_begin 5
dd C_here
dd M_exitcolon
CIENTRY "again" CI_again 5
dd M_literal
dd M_jump
dd C_comma
dd C_comma
dd M_exitcolon
CIENTRY "until" CI_until 5
dd M_literal
dd M_cjump
dd C_comma
dd C_comma
dd M_exitcolon
CIENTRY "while" CI_while 5
dd M_literal
dd M_cjump
dd C_comma
dd C_here
dd M_literal
dd 0
dd C_comma
dd M_exitcolon
CIENTRY "repeat" CI_repeat 6
dd M_literal
dd M_jump
dd C_comma
dd M_xswap
dd C_comma
dd C_here
dd M_xswap
dd M_store
dd M_exitcolon
CIENTRY "do" CI_do 2
dd M_literal
dd M_doinit		; compile this into the definition. Puts limit and index on the run stack at run time
dd C_comma		; puts (do) into the dictionary
dd M_literal
dd 0			; ( -- 0 )
dd C_here		; ( 0 -- 0 here1 )
dd M_exitcolon
CIENTRY "loop" CI_loop 4	; ( 0 here1 -- )
dd M_literal
dd M_doloop		; ( 0 here1 -- 0 here1 (loop) )
dd C_comma		; dictionary has (do) ... (loop) ( 0 here1 (loop) -- 0 here1 )
dd C_comma		; dictionary has (do) ... (loop) here1 ( 0 here1 -- 0 )
dd C_qdup
dd M_cjump
dd L234
dd C_here
dd M_xswap
dd M_store
L234:
dd M_exitcolon
CIENTRY "+loop" CI_ploop 5
dd M_literal
dd M_doploop
dd C_comma
dd C_comma
dd C_qdup
dd M_cjump
dd L236
dd C_here
dd M_xswap
dd M_store
L236:
dd M_exitcolon
CENTRY "w/o" C_wo 3
dd M_literal
dd 1
dd M_literal
dd 512
dd M_binor
dd M_literal
dd 64
dd M_binor
dd M_exitcolon
CENTRY "r/o" C_ro 3
dd M_literal
dd 0
dd M_exitcolon
CENTRY "r/w" C_rw 3
dd M_literal
dd 2
dd M_exitcolon
CENTRY "open-file" C_open_file 9 ; ( a n mode -- fd ioresult )
dd M_rpush	; ( a n mode -- a n ) (R -- mode)
dd C_pad	; ( a n -- a n padaddr)
dd M_literal
dd 1024		; ( a n padaddr --  a n padaddr 1024 )
dd M_plus	; ( a n padaddr+1024 --  a n padaddr+1024 )
dd M_xswap	; ( a n padaddr+1024 --  a padaddr+1024 n )
dd M_dup	; ( a padaddr+1024 n --  a padaddr+1024 n n )
dd M_rpush	; ( a padaddr+1024 n n --  a padaddr+1024 n ) (R mode -- mode n )
dd M_cmove	; moves the filename from a to paddaddr+1024
dd M_literal
dd 0		; ( -- 0 )
dd M_rpop	; ( 0 -- 0 n ) (R mode n -- mode)
dd C_pad	; ( 0 n -- 0 n padaddr)
dd M_plus	; ( 0 n padaddr -- 0 padaddr+n )
dd M_literal
dd 1024		; ( 0 padaddr+n --  0 padaddr+n 1024 )
dd M_plus	; ( 0 padaddr+n 1024 --  0 padaddr+n+1024 )
dd M_cstore	; ( 0 padaddr+n 1024 --   ) makes the filename to a null terminated string
dd C_pad
dd M_literal
dd 1024		; ( -- padaddr 1024 )
dd M_plus	; ( padaddr 1024 -- padaddr+1024 )
dd M_rpop	; ( padaddr+1024 -- padaddr+1024 mode) (R mode -- )
dd M_sysopen
dd M_dup
dd M_literal
dd -1
dd M_greater
dd M_exitcolon
CENTRY "close-file" C_close_file 10	; ( fd -- ioresult )
dd M_sysclose
dd C_0eq
dd M_exitcolon
CENTRY "read-file" C_read_file 9	; ( a n fd -- n2 ioresult )
dd C_rot	; ( n fd a )
dd C_rot	; ( fd a n )
dd M_sysread
dd M_dup
dd M_literal
dd -1
dd C_neq
dd M_exitcolon
CENTRY "write-file" C_write_file 10	; ( a n fd -- ioresult )
dd C_rot	; ( n fd a )
dd C_rot	; ( fd a n )
dd M_syswrite
dd M_literal
dd -1
dd C_neq
dd M_exitcolon
CENTRY "reposition-file" C_reposition_file 15	;	( type n fd -- ioresult )
dd M_xswap		; ( type fd n )
dd C_rot		; ( fd n type )
dd M_sysseek
dd M_literal
dd -1
dd C_neq
dd M_exitcolon
CENTRY "?fcheck" C_qfcheck 7
dd C_0eq
dd M_cjump
dd L246
dd C_space
dd M_literal
dd L247
dd M_literal
dd 9
dd C_type
dd C_cr
dd C_abort
L246:
dd M_exitcolon
CENTRY "create-file" C_create_file 11 ; ( a n mode perm -- fd ioresult ) not part of the original ff. could move this to a forth file.
dd M_rpush	; ( a n mode ) (R perm)
dd M_rpush	; ( a n ) (R perm mode)
dd C_pad	; ( a n padaddr)
dd M_literal
dd 1024		; ( a n padaddr 1024 )
dd M_plus	; ( a n padaddr+1024 )
dd M_xswap	; ( a padaddr+1024 n )
dd M_dup	; ( a padaddr+1024 n n )
dd M_rpush	; ( a padaddr+1024 n ) (R perm mode n )
dd M_cmove	; moves the filename from a to paddaddr+1024
dd M_literal
dd 0		; ( 0 )
dd M_rpop	; ( 0 n ) (R perm mode)
dd C_pad	; ( 0 n padaddr)
dd M_plus	; ( 0 padaddr+n )
dd M_literal
dd 1024		; ( 0 padaddr+n 1024 )
dd M_plus	; ( 0 padaddr+n+1024 )
dd M_cstore	; ( ) makes the filename to a null terminated string
dd C_pad
dd M_literal
dd 1024		; ( padaddr 1024 )
dd M_plus	; ( padaddr+1024 )
dd M_rpop	; ( padaddr+1024 mode) (R perm )
dd M_rpop	; ( padaddr+1024 mode perm ) (R )
dd M_syscreate
dd M_dup
dd M_literal
dd -1
dd M_greater
dd M_exitcolon
CENTRY "bye" C_bye 3
dd M_literal
dd 0
dd M_terminate
dd M_exitcolon

CENTRY "include" C_include 7
dd C_bl
dd C_word
dd M_rpush
dd MV_toLimit
dd M_fetch
dd MV_toIn
dd M_store
dd C_save_input
dd M_rpop
dd C_count
dd C_ro
dd C_open_file
dd C_qfcheck
dd MV_Infd
dd M_store
dd M_exitcolon

CENTRY "crash" C_crash 5
dd M_literal
dd L251
dd M_literal
dd 30
dd C_type
dd C_cr
dd C_abort
dd M_exitcolon

CENTRY "quit" C_quit 4 ; interpreter loop
dd M_reset ; initialize return stack
dd M_clear	; SP = sstack_end initialize data stack
L253:
dd C_query

; dd MV_toLimit	; show the line read, for debugging
; dd M_fetch
; dd M_Tib
; dd MC_STDOUT
; dd M_fswrite
; dd M_drop		; drop the return value of write
; dd C_cr
; dd C_space

dd C_interpret

dd M_jump
dd L253
dd M_exitcolon	; why is this needed?

CENTRY "(abort)" C_parenabort 7 ; TODO correct below stack notations
dd MV_State	; ( mv_State -- )
dd C_off		; off sets variable state = 0
dd M_Tib	; constant puts address of tibuffer on the top of stack
dd MV_Sourcebuf	; variable sourcebuf
dd M_store	; variable sourcebuf = address of tibuffer
dd MV_Blk	; variable blk
dd C_off	; off variable blk = 0
dd MC_STDIN
dd MV_Infd
dd M_store
dd MC_STDOUT
dd MV_Outfd
dd M_store
dd MC_STDERR
dd MV_Errfd
dd M_store
dd C_quit	; quit resets stacks and is the interpreter loop
dd M_exitcolon	; why is this needed? quit does not return unless it breaks

CENTRY "oldboot" C_oldboot 7 ; TODO correct below stack notations and this is obsolete. leaving it here for reference until it all works well
dd M_reset
dd M_clear	; SP = sstack_end
dd M_stackptr	; (D -- FFEND)
dd M_S0
dd M_store	; s0 = FFEND
dd M_Dp	; heaptop = heapend
dd M_fetch	; ( heapend -- )
dd M_literal
dd 1		; ( heapend 1 -- )
dd C_cells	; cells ( heapend 8 -- )
dd M_minus	; ( heapend-8 -- )
dd M_fetch	; ( contents_from_heapend-8 -- )
dd M_Args	; variable args
dd M_store	; args = contents_from_heapend-8
dd M_literal
dd C_parenabort ; ( (abort) -- )
dd MV_Abortvec	; variable abortvec
dd M_store	; variable abortvec = (abort) code address
dd M_Wordb	; constant puts address of wordbuffer on the top of stack
dd MV_Wordbuf	; variable wordbuf
dd M_store	; variable wordbuf = address of wordbuffer
dd M_Tib	; constant puts address of tibuffer on the top of stack
dd MV_Sourcebuf	; variable sourcebuf
dd M_store	; variable sourcebuf = address of tibuffer
dd M_literal
dd 0
dd MV_Infd
dd M_store	; stdin = 0
dd M_literal
dd 1
dd MV_Outfd
dd M_store	; stdout = 1
dd MV_State
dd C_off	; off stores 0 at state
dd C_decimal	; decimal setting base = 0
dd C_quit	; quit
dd M_exitcolon


dd M_literal	; test code
dd 66
dd M_Wordb
dd M_store
dd MC_STDOUT
dd M_Wordb
dd M_literal
dd 1
dd M_syswrite
dd M_drop		; drop the return value of write
dd MC_STDIN
dd M_Wordb
dd M_literal
dd 1
dd M_sysread
dd M_drop		; drop the return value of read

CENTRY "boot" C_boot 4

dd M_reset ; initialize return stack
dd M_clear	; SP = sstack_end initialize data stack
			; s0 puts FFEND on the stack
			; no args

dd M_literal
dd C_parenabort ; ( (abort) -- )
dd MV_Abortvec	; variable that puts (abort) code address on the stack
dd M_store	; variable abortvec = (abort) code address

dd M_Wordb	; variable puts address of wordbuffer on the top of stack
dd MV_Wordbuf ; variable wordbuf
dd M_store	; variable wordbuf = address of wordbuffer

dd M_Tib	; constant puts address of tibuffer on the top of stack
dd MV_Sourcebuf	; variable sourcebuf
dd M_store	; variable sourcebuf = address of tibuffer

dd M_Dp
dd MV_H0	; H0 = here at startup
dd M_store

dd MC_STDIN
dd MV_Infd
dd M_store     ; stdin = 0
dd MC_STDOUT
dd MV_Outfd
dd M_store
dd MC_STDERR
dd MV_Errfd
dd M_store

dd MV_State
dd C_off	; off stores 0 at state
dd C_decimal	; decimal sets base = 10

dd C_quit	; quit
dd M_exitcolon

L137:
db "unable to restore input"
L170:
db " Q?"
L173:
db " stack underflow"
L180:
db " I?"
L193:
db " C?"
L247:
db "I/O error"
L251:
db "uninitialized execution vector"
L255:
db " ok"