blob: 7c7e3665c6df022a7b1f76b61757dc66ddbb5145 [file] [log] [blame]
\ *****************************************************************************
\ * Copyright (c) 2004, 2011 IBM Corporation
\ * All rights reserved.
\ * This program and the accompanying materials
\ * are made available under the terms of the BSD License
\ * which accompanies this distribution, and is available at
\ * http://www.opensource.org/licenses/bsd-license.php
\ *
\ * Contributors:
\ * IBM Corporation - initial implementation
\ ****************************************************************************/
: fcode-revision ( -- n )
00030000 \ major * 65536 + minor
;
: b(lit) ( -- n )
next-ip read-fcode-num32
?compile-mode IF literal, THEN
;
: b(")
next-ip read-fcode-string
?compile-mode IF fc-string, align postpone count THEN
;
: b(')
next-ip read-fcode# get-token drop ?compile-mode IF literal, THEN
;
: ?jump-direction ( n -- )
dup 8000 >= IF
10000 - \ Create cell-sized negative value
THEN
fcode-offset - \ IP is already behind offset, so substract offset size
;
: ?negative
8000 and
;
: dest-on-top
0 >r BEGIN dup @ 0= WHILE >r REPEAT
BEGIN r> dup WHILE swap REPEAT
drop
;
: read-fcode-offset
next-ip
?offset16 IF
read-fcode-num16
ELSE
read-byte
dup 80 and IF FF00 or THEN \ Fake 16-bit signed offset
THEN
;
: b?branch ( flag -- )
?compile-mode IF
read-fcode-offset ?negative IF
dest-on-top postpone until
ELSE
postpone if
THEN
ELSE
( flag ) IF
fcode-offset jump-n-ip \ Skip over offset value
ELSE
read-fcode-offset
?jump-direction jump-n-ip
THEN
THEN
; immediate
: bbranch ( -- )
?compile-mode IF
read-fcode-offset
?negative IF
dest-on-top postpone again
ELSE
postpone else
get-ip next-ip fcode@ B2 = IF
drop
ELSE
set-ip
THEN
THEN
ELSE
read-fcode-offset ?jump-direction jump-n-ip
THEN
; immediate
: b(<mark) ( -- )
?compile-mode IF postpone begin THEN
; immediate
: b(>resolve) ( -- )
?compile-mode IF postpone then THEN
; immediate
: b(;)
<semicolon> compile, reveal
postpone [
; immediate
: b(:) ( -- )
<colon> compile, ]
; immediate
: b(case) ( sel -- sel )
postpone case
; immediate
: b(endcase)
postpone endcase
; immediate
: b(of)
postpone of
read-fcode-offset drop \ read and discard offset
; immediate
: b(endof)
postpone endof
read-fcode-offset drop
; immediate
: b(do)
postpone do
read-fcode-offset drop
; immediate
: b(?do)
postpone ?do
read-fcode-offset drop
; immediate
: b(loop)
postpone loop
read-fcode-offset drop
; immediate
: b(+loop)
postpone +loop
read-fcode-offset drop
; immediate
: b(leave)
postpone leave
; immediate
0 VALUE fc-instance?
: fc-instance ( -- ) \ Mark next defining word as instance-specific.
TRUE TO fc-instance?
;
: new-token \ unnamed local fcode function
align here next-ip read-fcode# 0 swap set-token
;
: external-token ( -- ) \ named local fcode function
next-ip read-fcode-string
\ fc-instance? IF cr ." ext instance token: " 2dup type ." in " pwd cr THEN
header ( str len -- ) \ create a header in the current dictionary entry
new-token
;
: new-token
eva-debug? IF
s" x" get-ip >r next-ip read-fcode# r> set-ip (u.) $cat strdup
header
THEN
new-token
;
\ decide wether or not to give a new token an own name in the dictionary
: named-token
fcode-debug? IF
external-token
ELSE
next-ip read-fcode-string 2drop \ Forget about the name
new-token
THEN
;
: b(to) ( val -- )
next-ip read-fcode#
get-token drop ( val xt )
dup @ ( val xt @xt )
dup <value> = over <defer> = OR IF
\ Destination is value or defer
drop
>body cell -
( val addr )
?compile-mode IF
literal, postpone !
ELSE
!
THEN
ELSE
<create> <> IF ( val xt )
TRUE ABORT" Invalid destination for FCODE b(to)"
THEN
dup cell+ @ ( val xt @xt+1cell )
dup <instancevalue> <> swap <instancedefer> <> AND IF
TRUE ABORT" Invalid destination for FCODE b(to)"
THEN
\ Destination is instance-value or instance-defer
>body @ ( val instance-offset )
?compile-mode IF
literal, postpone >instance postpone !
ELSE
>instance !
THEN
ELSE
THEN
; immediate
: b(value)
fc-instance? IF
<create> , \ Needed for "(instance?)" for example
<instancevalue> ,
(create-instance-var)
FALSE TO fc-instance?
ELSE
<value> , ,
THEN
reveal
;
: b(variable)
fc-instance? IF
<create> , \ Needed for "(instance?)"
<instancevariable> ,
0 (create-instance-var)
FALSE TO fc-instance?
ELSE
<variable> , 0 ,
THEN
reveal
;
: b(constant)
<constant> , , reveal
;
: undefined-defer
cr cr ." Uninitialized defer word has been executed!" cr cr
true fcode-end !
;
: b(defer)
fc-instance? IF
<create> , \ Needed for "(instance?)"
<instancedefer> ,
['] undefined-defer (create-instance-var)
reveal
FALSE TO fc-instance?
ELSE
<defer> , reveal
postpone undefined-defer
THEN
;
: b(create)
<variable> ,
postpone noop reveal
;
: b(field) ( E: addr -- addr+offset ) ( F: offset size -- offset+size )
<colon> , over literal,
postpone +
<semicolon> compile,
reveal
+
;
: b(buffer:) ( E: -- a-addr) ( F: size -- )
fc-instance? IF
<create> , \ Needed for "(instance?)"
<instancebuffer> ,
(create-instance-buf)
FALSE TO fc-instance?
ELSE
<buffer:> , allot
THEN
reveal
;
: suspend-fcode ( -- )
noop \ has to be implemented more efficiently ;-)
;
: offset16 ( -- )
2 to fcode-offset
;
: version1 ( -- )
1 to fcode-spread
1 to fcode-offset
read-header
;
: start0 ( -- )
0 to fcode-spread
offset16
read-header
;
: start1 ( -- )
1 to fcode-spread
offset16
read-header
;
: start2 ( -- )
2 to fcode-spread
offset16
read-header
;
: start4 ( -- )
4 to fcode-spread
offset16
read-header
;
: end0 ( -- )
true fcode-end !
;
: end1 ( -- )
end0
;
: ferror ( -- )
clear end0
cr ." FCode# " fcode-num @ . ." not assigned!"
cr ." FCode evaluation aborted." cr
." ( -- S:" depth . ." R:" rdepth . ." ) " .s cr
abort
;
: reset-local-fcodes
FFF 800 DO ['] ferror 0 i set-token LOOP
;
: byte-load ( addr xt -- )
>r >r
save-evaluator-state
r> r>
reset-fcode-end
1 to fcode-spread
dup 1 = IF drop ['] rb@ THEN to fcode-rb@
set-ip
reset-local-fcodes
depth >r
evaluate-fcode
r> depth 1- <> IF
clear end0
cr ." Ambiguous stack depth after byte-load!"
cr ." FCode evaluation aborted." cr cr
ELSE
restore-evaluator-state
THEN
['] c@ to fcode-rb@
;
\ Functions for accessing memory ... since some FCODE programs use the normal
\ memory access functions for accessing MMIO memory, too, we got to use a little
\ hack to support them: When address is bigger than MIN-RAM-SIZE, assume the
\ FCODE is trying to access MMIO memory and use the register based access
\ functions instead!
: fc-c@ ( addr -- byte ) dup MIN-RAM-SIZE > IF rb@ ELSE c@ THEN ;
: fc-w@ ( addr -- word ) dup MIN-RAM-SIZE > IF rw@ ELSE w@ THEN ;
: fc-<w@ ( addr -- word ) fc-w@ dup 8000 >= IF 10000 - THEN ;
: fc-l@ ( addr -- long ) dup MIN-RAM-SIZE > IF rl@ ELSE l@ THEN ;
: fc-<l@ ( addr -- long ) fc-l@ signed ;
: fc-x@ ( addr -- dlong ) dup MIN-RAM-SIZE > IF rx@ ELSE x@ THEN ;
: fc-c! ( byte addr -- ) dup MIN-RAM-SIZE > IF rb! ELSE c! THEN ;
: fc-w! ( word addr -- ) dup MIN-RAM-SIZE > IF rw! ELSE w! THEN ;
: fc-l! ( long addr -- ) dup MIN-RAM-SIZE > IF rl! ELSE l! THEN ;
: fc-x! ( dlong addr -- ) dup MIN-RAM-SIZE > IF rx! ELSE x! THEN ;
: fc-fill ( add len byte -- ) 2 pick MIN-RAM-SIZE > IF rfill ELSE fill THEN ;
: fc-move ( src dst len -- )
2 pick MIN-RAM-SIZE > \ Check src
2 pick MIN-RAM-SIZE > \ Check dst
OR IF rmove ELSE move THEN
;
\ Destroy virtual mapping (should maybe also update "address" property here?)
: free-virtual ( virt size -- )
s" map-out" $call-parent
;
\ Map the specified region, return virtual address
: map-low ( phys.lo ... size -- virt )
my-space swap s" map-in" $call-parent
;
\ Get MAC address
: mac-address ( -- mac-str mac-len )
s" local-mac-address" get-my-property IF
0 0
THEN
;
\ Output line and column number - not used yet
VARIABLE #line
0 #line !
VARIABLE #out
0 #out !
\ Display device status
: display-status ( n -- )
." Device status: " . cr
;
\ Obsolete variables:
VARIABLE group-code
0 group-code !
\ Obsolete: Allocate memory for DMA
: dma-alloc ( byte -- virtual )
s" dma-alloc" $call-parent
;
\ Obsolete: Get params property
: my-params ( -- addr len )
s" params" get-my-property IF
0 0
THEN
;
\ Obsolete: Convert SBus interrupt level to CPU interrupt level
: sbus-intr>cpu ( sbus-intr# -- cpu-intr# )
;
\ Obsolete: Set "intr" property
: intr ( interrupt# vector -- )
>r sbus-intr>cpu encode-int r> encode-int+ s" intr" property
;
\ Obsolete: Create the "name" property
: driver ( addr len -- )
encode-string s" name" property
;
\ Obsolete: Return type of CPU
: processor-type ( -- cpu-type )
0
;
\ Obsolete: Return firmware version
: firmware-version ( -- n )
10000 \ Just a dummy value
;
\ Obsolete: Return fcode-version
: fcode-version ( -- n )
fcode-revision
;