summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openbios/forth/device/fcode.fs
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/openbios/forth/device/fcode.fs')
-rw-r--r--qemu/roms/openbios/forth/device/fcode.fs573
1 files changed, 573 insertions, 0 deletions
diff --git a/qemu/roms/openbios/forth/device/fcode.fs b/qemu/roms/openbios/forth/device/fcode.fs
new file mode 100644
index 000000000..9083ed0e0
--- /dev/null
+++ b/qemu/roms/openbios/forth/device/fcode.fs
@@ -0,0 +1,573 @@
+\ tag: FCode implementation functions
+\
+\ this code implements IEEE 1275-1994 ch. 5.3.3
+\
+\ Copyright (C) 2003 Stefan Reinauer
+\
+\ See the file "COPYING" for further information about
+\ the copyright and warranty status of this work.
+\
+
+hex
+
+0 value fcode-sys-table \ table with built-in fcodes (0-0x7ff)
+
+true value ?fcode-offset16 \ fcode offsets are 16 instead of 8 bit?
+1 value fcode-spread \ fcode spread (1, 2 or 4)
+0 value fcode-table \ pointer to fcode table
+false value ?fcode-verbose \ do verbose fcode execution?
+
+defer _fcode-debug? \ If true, save names for FCodes with headers
+true value fcode-headers? \ If true, possibly save names for FCodes.
+
+0 value fcode-stream-start \ start address of fcode stream
+0 value fcode-stream \ current fcode stream address
+
+variable fcode-end \ state variable, if true, fcode program terminates.
+defer fcode-c@ \ get byte
+
+: fcode-push-state ( -- <state information> )
+ ?fcode-offset16
+ fcode-spread
+ fcode-table
+ fcode-headers?
+ fcode-stream-start
+ fcode-stream
+ fcode-end @
+ ['] fcode-c@ behavior
+;
+
+: fcode-pop-state ( <state information> -- )
+ to fcode-c@
+ fcode-end !
+ to fcode-stream
+ to fcode-stream-start
+ to fcode-headers?
+ to fcode-table
+ to fcode-spread
+ to ?fcode-offset16
+;
+
+\
+\ fcode access helper functions
+\
+
+\ fcode-ptr
+\ convert FCode number to pointer to xt in FCode table.
+
+: fcode-ptr ( u16 -- *xt )
+ cells
+ fcode-table ?dup if + exit then
+
+ \ we are not parsing fcode at the moment
+ dup 800 cells u>= abort" User FCODE# referenced."
+ fcode-sys-table +
+;
+
+\ fcode>xt
+\ get xt according to an FCode#
+
+: fcode>xt ( u16 -- xt )
+ fcode-ptr @
+ ;
+
+\ fcode-num8
+\ get 8bit from FCode stream, taking spread into regard.
+
+: fcode-num8 ( -- c ) ( F: c -- )
+ fcode-stream
+ dup fcode-spread + to fcode-stream
+ fcode-c@
+ ;
+
+\ fcode-num8-signed ( -- c ) ( F: c -- )
+\ get 8bit signed from FCode stream
+
+: fcode-num8-signed
+ fcode-num8
+ dup 80 and 0> if
+ ff invert or
+ then
+ ;
+
+\ fcode-num16
+\ get 16bit from FCode stream
+
+: fcode-num16 ( -- num16 )
+ fcode-num8 fcode-num8 swap bwjoin
+ ;
+
+\ fcode-num16-signed ( -- c ) ( F: c -- )
+\ get 16bit signed from FCode stream
+
+: fcode-num16-signed
+ fcode-num16
+ dup 8000 and 0> if
+ ffff invert or
+ then
+ ;
+
+\ fcode-num32
+\ get 32bit from FCode stream
+
+: fcode-num32 ( -- num32 )
+ fcode-num8 fcode-num8
+ fcode-num8 fcode-num8
+ swap 2swap swap bljoin
+ ;
+
+\ fcode#
+\ Get an FCode# from FCode stream
+
+: fcode# ( -- fcode# )
+ fcode-num8
+ dup 1 f between if
+ fcode-num8 swap bwjoin
+ then
+ ;
+
+\ fcode-offset
+\ get offset from FCode stream.
+
+: fcode-offset ( -- offset )
+ ?fcode-offset16 if
+ fcode-num16-signed
+ else
+ fcode-num8-signed
+ then
+
+ \ Display offset in verbose mode
+ ?fcode-verbose if
+ dup ." (offset) " . cr
+ then
+ ;
+
+\ fcode-string
+\ get a string from FCode stream, store in pocket.
+
+: fcode-string ( -- addr len )
+ pocket dup
+ fcode-num8
+ dup rot c!
+ 2dup bounds ?do
+ fcode-num8 i c!
+ loop
+
+ \ Display string in verbose mode
+ ?fcode-verbose if
+ 2dup ." (const) " type cr
+ then
+ ;
+
+\ fcode-header
+\ retrieve FCode header from FCode stream
+
+: fcode-header
+ fcode-num8
+ fcode-num16
+ fcode-num32
+ ?fcode-verbose if
+ ." Found FCode header:" cr rot
+ ." Format : " u. cr swap
+ ." Checksum : " u. cr
+ ." Length : " u. cr
+ else
+ 3drop
+ then
+ \ TODO checksum
+ ;
+
+\ writes currently created word as fcode# read from stream
+\
+
+: fcode! ( F:FCode# -- )
+ here fcode#
+
+ \ Display fcode# in verbose mode
+ ?fcode-verbose if
+ dup ." (fcode#) " . cr
+ then
+ fcode-ptr !
+ ;
+
+
+\
+\ 5.3.3.1 Defining new FCode functions.
+\
+
+\ instance ( -- )
+\ Mark next defining word as instance specific.
+\ (defined in bootstrap.fs)
+
+\ instance-init ( wid buffer -- )
+\ Copy template from specified wordlist to instance
+\
+
+: instance-init
+ swap
+ begin @ dup 0<> while
+ dup /n + @ instance-cfa? if \ buffer dict
+ 2dup 2 /n* + @ + \ buffer dict dest
+ over 3 /n* + @ \ buffer dict dest size
+ 2 pick 4 /n* + \ buffer dict dest size src
+ -rot
+ move
+ then
+ repeat
+ 2drop
+ ;
+
+
+\ new-token ( F:/FCode#/ -- )
+\ Create a new unnamed FCode function
+
+: new-token
+ 0 0 header
+ fcode!
+ ;
+
+
+\ named-token (F:FCode-string FCode#/ -- )
+\ Create a new possibly named FCode function.
+
+: named-token
+ fcode-string
+ _fcode-debug? not if
+ 2drop 0 0
+ then
+ header
+ fcode!
+ ;
+
+
+\ external-token (F:/FCode-string FCode#/ -- )
+\ Create a new named FCode function
+
+: external-token
+ fcode-string header
+ fcode!
+ ;
+
+
+\ b(;) ( -- )
+\ End an FCode colon definition.
+
+: b(;)
+ ['] ; execute
+ ; immediate
+
+
+\ b(:) ( -- ) ( E: ... -- ??? )
+\ Defines type of new FCode function as colon definition.
+
+: b(:)
+ 1 , ]
+ ;
+
+
+\ b(buffer:) ( size -- ) ( E: -- a-addr )
+\ Defines type of new FCode function as buffer:.
+
+: b(buffer:)
+ 4 , allot
+ reveal
+ ;
+
+\ b(constant) ( nl -- ) ( E: -- nl )
+\ Defines type of new FCode function as constant.
+
+: b(constant)
+ 3 , ,
+ reveal
+ ;
+
+
+\ b(create) ( -- ) ( E: -- a-addr )
+\ Defines type of new FCode function as create word.
+
+: b(create)
+ 6 ,
+ ['] noop ,
+ reveal
+ ;
+
+
+\ b(defer) ( -- ) ( E: ... -- ??? )
+\ Defines type of new FCode function as defer word.
+
+: b(defer)
+ 5 ,
+ ['] (undefined-defer) ,
+ ['] (semis) ,
+ reveal
+ ;
+
+
+\ b(field) ( offset size -- offset+size ) ( E: addr -- addr+offset )
+\ Defines type of new FCode function as field.
+
+: b(field)
+ 6 ,
+ ['] noop ,
+ reveal
+ over ,
+ +
+ does>
+ @ +
+ ;
+
+
+\ b(value) ( x -- ) (E: -- x )
+\ Defines type of new FCode function as value.
+
+: b(value)
+ 3 , , reveal
+ ;
+
+
+\ b(variable) ( -- ) ( E: -- a-addr )
+\ Defines type of new FCode function as variable.
+
+: b(variable)
+ 4 , 0 ,
+ reveal
+ ;
+
+
+\ (is-user-word) ( name-str name-len xt -- ) ( E: ... -- ??? )
+\ Create a new named user interface command.
+
+: (is-user-word)
+ ;
+
+
+\ get-token ( fcode# -- xt immediate? )
+\ Convert FCode number to function execution token.
+
+: get-token
+ fcode>xt dup immediate?
+ ;
+
+
+\ set-token ( xt immediate? fcode# -- )
+\ Assign FCode number to existing function.
+
+: set-token
+ nip \ TODO we use the xt's immediate state for now.
+ fcode-ptr !
+ ;
+
+
+
+
+\
+\ 5.3.3.2 Literals
+\
+
+
+\ b(lit) ( -- n1 )
+\ Numeric literal FCode. Followed by FCode-num32.
+
+64bit? [IF]
+: b(lit)
+ fcode-num32 32>64
+ state @ if
+ ['] (lit) , ,
+ then
+ ; immediate
+[ELSE]
+: b(lit)
+ fcode-num32
+ state @ if
+ ['] (lit) , ,
+ then
+ ; immediate
+[THEN]
+
+
+\ b(') ( -- xt )
+\ Function literal FCode. Followed by FCode#
+
+: b(')
+ fcode# fcode>xt
+ state @ if
+ ['] (lit) , ,
+ then
+ ; immediate
+
+
+\ b(") ( -- str len )
+\ String literal FCode. Followed by FCode-string.
+
+: b(")
+ fcode-string
+ state @ if
+ \ only run handle-text in compile-mode,
+ \ otherwise we would waste a pocket.
+ handle-text
+ then
+ ; immediate
+
+
+\
+\ 5.3.3.3 Controlling values and defers
+\
+
+\ behavior ( defer-xt -- contents-xt )
+\ defined in bootstrap.fs
+
+\ b(to) ( new-value -- )
+\ FCode for setting values and defers. Followed by FCode#.
+
+: b(to)
+ fcode# fcode>xt
+ 1 handle-lit
+ ['] (to)
+ state @ if
+ ,
+ else
+ execute
+ then
+ ; immediate
+
+
+
+\
+\ 5.3.3.4 Control flow
+\
+
+
+\ offset16 ( -- )
+\ Makes subsequent FCode-offsets use 16-bit (not 8-bit) form.
+
+: offset16
+ true to ?fcode-offset16
+ ;
+
+
+\ bbranch ( -- )
+\ Unconditional branch FCode. Followed by FCode-offset.
+
+: bbranch
+ fcode-offset 0< if \ if we jump backwards, we can forsee where it goes
+ ['] dobranch ,
+ resolve-dest
+ execute-tmp-comp
+ else
+ setup-tmp-comp ['] dobranch ,
+ here 0
+ 0 ,
+ 2swap
+ then
+ ; immediate
+
+
+\ b?branch ( continue? -- )
+\ Conditional branch FCode. Followed by FCode-offset.
+
+: b?branch
+ fcode-offset 0< if \ if we jump backwards, we can forsee where it goes
+ ['] do?branch ,
+ resolve-dest
+ execute-tmp-comp
+ else
+ setup-tmp-comp ['] do?branch ,
+ here 0
+ 0 ,
+ then
+ ; immediate
+
+
+\ b(<mark) ( -- )
+\ Target of backward branches.
+
+: b(<mark)
+ setup-tmp-comp
+ here 1
+ ; immediate
+
+
+\ b(>resolve) ( -- )
+\ Target of forward branches.
+
+: b(>resolve)
+ resolve-orig
+ execute-tmp-comp
+ ; immediate
+
+
+\ b(loop) ( -- )
+\ End FCode do..loop. Followed by FCode-offset.
+
+: b(loop)
+ fcode-offset drop
+ postpone loop
+ ; immediate
+
+
+\ b(+loop) ( delta -- )
+\ End FCode do..+loop. Followed by FCode-offset.
+
+: b(+loop)
+ fcode-offset drop
+ postpone +loop
+ ; immediate
+
+
+\ b(do) ( limit start -- )
+\ Begin FCode do..loop. Followed by FCode-offset.
+
+: b(do)
+ fcode-offset drop
+ postpone do
+ ; immediate
+
+
+\ b(?do) ( limit start -- )
+\ Begin FCode ?do..loop. Followed by FCode-offset.
+
+: b(?do)
+ fcode-offset drop
+ postpone ?do
+ ; immediate
+
+
+\ b(leave) ( -- )
+\ Exit from a do..loop.
+
+: b(leave)
+ postpone leave
+ ; immediate
+
+
+\ b(case) ( sel -- sel )
+\ Begin a case (multiple selection) statement.
+
+: b(case)
+ postpone case
+ ; immediate
+
+
+\ b(endcase) ( sel | <nothing> -- )
+\ End a case (multiple selection) statement.
+
+: b(endcase)
+ postpone endcase
+ ; immediate
+
+
+\ b(of) ( sel of-val -- sel | <nothing> )
+\ FCode for of in case statement. Followed by FCode-offset.
+
+: b(of)
+ fcode-offset drop
+ postpone of
+ ; immediate
+
+\ b(endof) ( -- )
+\ FCode for endof in case statement. Followed by FCode-offset.
+
+: b(endof)
+ fcode-offset drop
+ postpone endof
+ ; immediate