Branch
Hash :
1a08f436
Author :
Date :
2010-08-25T09:23:17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
\ ccalls.fth 2.4 94/05/30
\ Copyright 1985-1990 Bradley Forthware
\ Defining words to construct Forth interfaces to C subroutines
\ and Unix system calls. This is strongly implementation dependent, and will
\ require EXTENSIVE modifications for other Forth systems, other CPU's,
\ and other operating systems.
\
\ Defines:
\
\ syscall: ( syscall# -- ) ( Input Stream: name arg-spec )
\ subroutine: ( adr -- ) ( Input Stream: name arg-spec )
\
\ This version is for SPARC Unix systems where ints, longs, and addresses
\ are all the same size. Under this assumption, the only thing we have to
\ do to the stack arguments is to convert Forth strings to C strings.
decimal
only forth assembler also forth also hidden also definitions
headerless
variable #args variable #results variable arg#
: system-call ( syscall# -- )
[ also assembler ]
%g2 sc1 move
( call# ) %g1 move
%g0 0 always trapif
u< if
0 up ['] errno >user# st \ Delay slot
%o0 up ['] errno >user# st
-1 %o0 move
then
sc1 %g2 move
[ previous ]
;
\ : subroutine-call ( subroutine-adr -- )
\ [ also assembler ]
\ ( adr ) call
\ %g2 sc1 move \ Delay slot
\ sc1 %g2 move
\ [ previous ]
\ ;
: wrapper-call ( call# -- )
[ also assembler ]
\ Get address of system call table
'user syscall-vec scr nget
bubble
( call# ) scr swap scr nget \ Address of routine
%g1 sc1 move
scr %g0 %o7 jmpl
%g2 sc2 move \ Delay slot
sc1 %g1 move
sc2 %g2 move
[ previous ]
;
: sys: \ name ( call# -- )
code
;
: %o# ( -- reg ) [ also assembler ] arg# @ %o0 + [ previous ] ;
: arg ( -- )
arg# @ if
[ also assembler ] sp arg# @ 1- /n* %o# nget [ previous ]
else
[ also assembler ] tos %o0 move [ previous ]
then
1 arg# +!
;
: str ( -- )
arg# @ if
[ also assembler ] sp arg# @ 1- /n* %o# nget
%o# 1 %o# add [ previous ]
else
[ also assembler ] tos 1 %o0 add [ previous ]
then
1 arg# +!
;
: res ( -- ) 1 #results +! ;
: } ( -- )
#results @ if
#args @ 0= if [ also assembler ]
tos sp push
[ previous ] then
#args @ 1 > if [ also assembler ]
sp #args @ 1- /n* sp add
[ previous ] then
[ also assembler ] %o0 tos move [ previous ]
else \ No results
#args @ if [ also assembler ]
sp #args @ 1- /n* tos nget
sp #args @ /n* sp add
[ previous ] then
then
;
: scan-args ( -- )
#args off
0 ( marker )
begin
bl word 1+ c@
case
ascii l of ['] arg true endof
ascii i of ['] arg true endof
ascii a of ['] arg true endof
ascii s of ['] str true endof
ascii - of false endof
ascii } of ." Where's the -- ?" abort endof
( default ) ." Bad type specifier: " dup emit abort
endcase
while
1 #args +!
repeat
arg# off
begin ?dup while execute repeat
;
: do-call ( ??? 'call-assembler -- ) \ ??? is args specific to the call type
execute
;
: scan-results ( -- )
#results off
begin
bl word 1+ c@
case
ascii l of true endof
ascii i of true endof
ascii a of true endof
ascii s of ." Can't return strings yet" abort true endof
ascii } of false endof
( default ) ." Bad type specifier: " dup emit
endcase
while
1 #results +!
repeat
}
;
only forth hidden also forth assembler also forth definitions
: { \ args -- results } ( -- )
scan-args do-call scan-results next
;
headers
: syscall: \ name ( syscall# -- syscall# 'system-call )
['] system-call
code current @ context ! \ don't want to be in assembler voc
;
\ : subroutine: \ name ( adr -- adr 'subroutine-call )
\ ['] subroutine-call code current @ context !
\ ;
only forth also definitions