Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / forth / device / fcode.fs
diff --git a/qemu/roms/openbios/forth/device/fcode.fs b/qemu/roms/openbios/forth/device/fcode.fs
new file mode 100644 (file)
index 0000000..9083ed0
--- /dev/null
@@ -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