ref: 2a12d6d0d04bfaea941cb6c37c02c513bcd3ece8
parent: 25d46a497531211ed517e2c78902d873e95b8ca5
author: 9ferno <[email protected]>
date: Mon Nov 22 12:30:37 EST 2021
forth procs read from fd instead of a queue
--- a/os/pc64/forth.s
+++ b/os/pc64/forth.s
@@ -30,8 +30,9 @@
RSP: R8 return stack pointer, grows towards higher memory (upwards)
IP: R9 instruction pointer
W: R10 work register (holds CFA)
- H0: R11 register holding the start of this process's heap memory
- CX, SI, DI, R12-R13 temporary registers
+ UP: R11 register holding the start of this process's heap memory
+ UPE: R12 register holding the end of this process's heap memory -- TODO, use this
+ CX, SI, DI, R13 temporary registers
coding standard
: <name> (S input-stack --- output-stack) (R --- )
@@ -40,8 +41,8 @@
.. fn ;
Heap memory map: uses 8 pages at the start, will increase by *2 when filled up
-H0: variables
- heap start, heapstart, also in H0
+UP: variables
+ heap start, heapstart, also in UP
heap size, heapsize
forth stack pointer, forthsp
dictionary pointer, Dp
@@ -74,7 +75,7 @@
#define RSP R8 /* return stack pointer, grows towards higher memory (upwards) */
#define IP R9 /* instruction pointer */
#define W R10/* work register (holds CFA) */
-#define H0 R11/* start of heap memory */
+#define UP R11/* start of heap memory */
#define PSTACK_SIZE BY2PG
#define RSTACK_SIZE BY2PG
@@ -106,6 +107,7 @@
#define INFD (HEAPSTART+(BY2WD*18))
#define OUTFD (HEAPSTART+(BY2WD*19))
#define ERRFD (HEAPSTART+(BY2WD*20))
+#define EOF (HEAPSTART+(BY2WD*21))
#define ERRSTR (HEAPSTART+(BY2WD*32))
#define WORDB (HEAPSTART+(BY2WD*160)) /* word buffer */
@@ -137,25 +139,25 @@
TEXT forthmain(SB), 1, $-4 /* _main(SB), 1, $-4 without the libc */
/* Argument has the start of heap */
- MOVQ RARG, H0 /* start of heap memory */
+ MOVQ RARG, UP /* start of heap memory */
- MOVQ H0, RSP
+ MOVQ UP, RSP
ADDQ $RSTACK_END, RSP /* return stack pointer, reset */
- MOVQ H0, PSP
+ MOVQ UP, PSP
ADDQ $PSTACK_END, PSP /* parameter stack pointer - stack setup, clear */
- MOVQ PSP, 16(H0) /* parameter stack pointer store, for forth to c */
+ MOVQ PSP, 16(UP) /* parameter stack pointer store, for forth to c */
- MOVQ H0, TOP
+ MOVQ UP, TOP
ADDQ $HEAPSTART, TOP
- MOVQ TOP, (H0) /* store the start address at that address too - magic check */
+ MOVQ TOP, (UP) /* store the start address at that address too - magic check */
ADDQ $(HEAPSIZE-1), TOP
- MOVQ TOP, 8(H0) /* heap end */
+ MOVQ TOP, 8(UP) /* heap end */
- MOVQ H0, TOP
+ MOVQ UP, TOP
ADDQ $DICTIONARY, TOP
- MOVQ TOP, 24(H0) /* dictionary pointer */
- MOVQ $centry_c_boot(SB), 24(H0) /* Latest dictionary entry address */
+ MOVQ TOP, 24(UP) /* dictionary pointer */
+ MOVQ $centry_c_boot(SB), 24(UP) /* Latest dictionary entry address */
/* execute boot */
MOVQ $centry_c_boot(SB), IP
@@ -190,12 +192,12 @@
NEXT
TEXT reset(SB), 1, $-4
- MOVQ H0, RSP
+ MOVQ UP, RSP
ADDQ $RSTACK_END, RSP
NEXT
TEXT clear(SB), 1, $-4
- MOVQ H0, PSP
+ MOVQ UP, PSP
ADDQ $PSTACK_END, PSP
NEXT
@@ -246,6 +248,7 @@
POP(TOP)
NEXT
+/* TODO change to allow only fetches from a certain memory range */
TEXT cfetch(SB), 1, $-4 /* ( a -- c ) */
XORQ CX, CX
MOVB (TOP), CL
@@ -252,6 +255,7 @@
POP(TOP)
NEXT
+/* TODO change to allow only fetches from a certain memory range */
TEXT cstore(SB), 1, $-4 /* ( c a -- ) */
POP(CX)
MOVB CL, (TOP)
@@ -545,7 +549,7 @@
TEXT s0(SB), 1, $-4 /* S0 needs a calculation to come up with the value */
PUSH(TOP)
- MOVQ H0, TOP
+ MOVQ UP, TOP
ADDQ $PSTACK_END, TOP
NEXT
@@ -552,7 +556,7 @@
/* store the forth sp here when going to C */
TEXT forthsp(SB), 1, $-4
PUSH(TOP)
- MOVQ H0, TOP
+ MOVQ UP, TOP
ADDQ $FORTHSP, TOP
NEXT
@@ -560,7 +564,7 @@
#define VARIABLE(name, location) TEXT name(SB), 1, $-4 ;\
PUSH(TOP); \
- MOVQ H0, TOP ;\
+ MOVQ UP, TOP ;\
ADDQ location, TOP ;\
NEXT;
@@ -586,6 +590,7 @@
VARIABLE(Infd, $INFD)
VARIABLE(Outfd, $OUTFD)
VARIABLE(Errfd, $ERRFD)
+VARIABLE(Eof, $EOF)
TEXT forthend(SB), 1, $-4
--- a/os/pc64/primitives-nasm.s
+++ b/os/pc64/primitives-nasm.s
@@ -52,27 +52,27 @@
MENTRY "Wordb", Wordb, 5
MENTRY "Hzero", Hzero, 5
MENTRY "Dp", Dp, 2
- MENTRY `>In`, toIn, 3
- MENTRY `>Limit`, toLimit, 6
- MENTRY `Findadr`, Findadr, 7
- MENTRY `Blk`, Blk, 3
- MENTRY `Args`, Args, 4
- MENTRY `Iobuf`, Iobuf, 5
- MENTRY `Searchlen`, Searchlen, 9
- MENTRY `Base`, Base, 4
- MENTRY `>Num`, toNum, 4
- MENTRY `State`, State, 5
- MENTRY `Abortvec`, Abortvec, 8 ; not sure if these 3 can be constants instead?
- MENTRY `Sourcebuf`, Sourcebuf, 9
- MENTRY `Wordbuf`, Wordbuf, 7
- MENTRY `Infd`, Infd, 7
- MENTRY `Outfd`, Outfd, 7
- MENTRY `Errfd`, Errfd, 7
+ MENTRY ">In", toIn, 3
+ MENTRY ">Limit", toLimit, 6
+ MENTRY "Findadr", Findadr, 7
+ MENTRY "Blk", Blk, 3
+ MENTRY "Args", Args, 4
+ MENTRY "Iobuf", Iobuf, 5
+ MENTRY "Searchlen", Searchlen, 9
+ MENTRY "Base", Base, 4
+ MENTRY ">Num", toNum, 4
+ MENTRY "State", State, 5
+ MENTRY "Abortvec", Abortvec, 8 ; not sure if these 3 can be constants instead?
+ MENTRY "Sourcebuf", Sourcebuf, 9
+ MENTRY "Wordbuf", Wordbuf, 7
+ MENTRY "Infd", Infd, 5
+ MENTRY "Outfd", Outfd, 6
+ MENTRY "Errfd", Errfd, 4
+ MENTRY "Eof", Eof, 0, 3
- MVENTRY "STDIN", STDIN, 0, 5 ; 4 constants from here, CAPITALS
- MVENTRY "STDOUT", STDOUT, 1, 6
- MVENTRY "STDERR", STDERR, 2, 6
- MVENTRY "EOF", EOF, 0, 3
+ MCENTRY "STDIN", STDIN, 0, 5 ; 3 constants from here, CAPITALS
+ MCENTRY "STDOUT", STDOUT, 1, 6
+ MCENTRY "STDERR", STDERR, 2, 6
MENTRY "s0", s0, 2
MENTRY "s@", stackptr, 2 ; puts PSP on stack
--- a/os/pc64/primitives.awk
+++ b/os/pc64/primitives.awk
@@ -42,7 +42,7 @@
tot += 8
addrlabel = sprintf("mentry_%s", label)
}
-$2 == "MVENTRY" {
+$2 == "MCENTRY" {
if(label != ""){
lines[++nlines]=sprintf("GLOBL %s, $%d\n", last, tot);
}
@@ -50,22 +50,22 @@
name = $3
label = $4
tot = 0
- writelast("mventry", label, last)
- last=sprintf("mventry_%s(SB)", label);
- lines[++nlines]=sprintf("DATA mventry_%s+8(SB)/1, $%d\n", label, length(name));
+ writelast("mcentry", label, last)
+ last=sprintf("mcentry_%s(SB)", label);
+ lines[++nlines]=sprintf("DATA mcentry_%s+8(SB)/1, $%d\n", label, length(name));
for(i=1; i<=length(name); i++){
- lines[++nlines]=sprintf("DATA mventry_%s+%d(SB)/1, $'%c'\n", label, 8+i, substr(name,i,1));
+ lines[++nlines]=sprintf("DATA mcentry_%s+%d(SB)/1, $'%c'\n", label, 8+i, substr(name,i,1));
}
tot = 8+i;
# for alignment
if(tot%8 > 0)
tot += 8-(tot%8);
- lines[++nlines]=sprintf("DATA mventry_%s+%d(SB)/8, $constant(SB)\n", label, tot);
- lines[++nlines]=sprintf("#define mc_%s(SB) mventry_%s+%d(SB)\n", label, label, tot);
+ lines[++nlines]=sprintf("DATA mcentry_%s+%d(SB)/8, $constant(SB)\n", label, tot);
+ lines[++nlines]=sprintf("#define mc_%s(SB) mcentry_%s+%d(SB)\n", label, label, tot);
tot += 8;
- lines[++nlines]=sprintf("DATA mventry_%s+%d(SB)/8, $%s\n", label, tot, $5);
+ lines[++nlines]=sprintf("DATA mcentry_%s+%d(SB)/8, $%s\n", label, tot, $5);
tot += 8;
- addrlabel = sprintf("mventry_%s", label)
+ addrlabel = sprintf("mcentry_%s", label)
}
$1 ~ /:$/ && $1 !~ /^dict:$/ {
l=$1
--- a/os/pc64/words-nasm.s
+++ b/os/pc64/words-nasm.s
@@ -258,37 +258,38 @@
L52:
dd m_exitcolon
- CENTRY `key`, c_key, 3
- dd m_Iobuf ; variable iobuf
+ CENTRY `key`, c_key, 3 ; ( -- c ) (G read a single character from the input onto the stack )
dd m_literal
- dd 1
- dd m_Infd ; constant stdin
- dd m_fthread
+ dd 1 ; ( 1 -- )
+ dd m_Iobuf ; variable iobuf to store the character read
+ dd m_Infd
+ dd m_fetch ; ( 1 Iobuf -- 1 Iobuf infd )
+ dd m_fthread ; ( 1 Iobuf infd -- n )
dd c_0eq
- dd m_cjump
- dd L78
- dd mc_EOF
- dd c_on
+ dd m_cjump ; if 0 characters read
+ dd L78 ; if qread n != 0, jump to L78. If n == 0, jump over
+ dd m_Eof
+ dd c_on ; EOF
dd m_literal
- dd -1
+ dd -1 ; return -1 when EOF
dd m_jump
dd L79
L78:
- dd m_Iobuf
- dd m_cfetch
+ dd m_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 m_Iobuf ; variable iobuf address
- dd m_cstore ; variable iobuf has character
- dd m_Iobuf ; variable iobuf address
+ dd m_Iobuf ; variable iobuf address
+ dd m_cstore ; variable iobuf has character
+ dd m_Iobuf ; variable iobuf address
dd m_literal
dd 1
- dd m_xswap ; ( iobuf 1 -- 1 iobuf )
- dd m_literal
- dd 1 ; stdout
- dd m_fthwrite ; ( 1 iobuf 1 -- )
+ dd m_xswap ; ( iobuf 1 -- 1 iobuf )
+ dd m_Outfd
+ dd m_fetch ; outfd
+ dd m_fthwrite ; ( 1 iobuf outfd -- )
dd m_exitcolon
CENTRY `type`, c_type, 4 ; ( addr n -- )
@@ -744,11 +745,11 @@
dd m_Sourcebuf
dd m_fetch
dd m_exitcolon
- CENTRY `current-input`, c_current_input, 13
+ CENTRY `current-input`, c_current_input, 13 ; ( -- c ) read the next character from the location in Sourcebuf
dd m_toIn
dd m_fetch
dd c_source
- dd m_plus
+ dd m_plus ; Sourcebuf + >In
dd m_cfetch
dd m_exitcolon
CENTRY `save-input`, c_save_input, 10
@@ -777,7 +778,7 @@
dd c_off
dd m_exitcolon
CENTRY `restore-input`, c_restore_input, 13
- dd mc_EOF
+ dd m_Eof
dd c_off
dd m_literal
dd 5
@@ -817,7 +818,8 @@
dd c_abort
L136:
dd m_exitcolon
- CENTRY `next-input`, c_next_input, 10
+
+ CENTRY `next-input`, c_next_input, 10 ; when >In < >Limit ( -- true c ). ( -- 0 false ) otherwise
dd m_toIn
dd m_fetch
dd m_toLimit
@@ -824,9 +826,9 @@
dd m_fetch
dd m_less
dd m_cjump
- dd L139
- dd c_true
- dd c_current_input
+ dd L139 ; >In >= >Limit
+ dd c_true ; >In < >Limit
+ dd c_current_input ; ( -- c )
dd m_jump
dd L140
L139:
@@ -835,66 +837,68 @@
dd c_false
L140:
dd m_exitcolon
- CENTRY `parse`, c_parse, 5
- dd m_rpush
+
+ 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 m_Wordbuf
- dd m_fetch
- dd c_1plus
+ dd m_fetch ; ( -- Wordb )
+ dd c_1plus ; ( Wordb -- Wordb+1 )
L142:
- dd c_next_input
- dd m_rfetch
- dd c_neq
+ 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
- dd c_current_input
+ dd L143 ; ( Wordb+1 ) >In >= >Limit || cinitial == cnew
+ dd c_current_input ; ( Wordb+1 -- Wordb+1 c )
dd m_over
- dd m_cstore
- dd c_1plus
+ 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 m_toIn
- dd c_plusstore
+ dd c_plusstore ; >In++
dd m_jump
- dd L142
-L143:
+ dd L142 ; ( Wordb+2 ) repeat
+L143: ; ( Wordb+1 ) >In >= >Limit || cinitial == cnew
dd m_literal
dd 1
dd m_toIn
- dd c_plusstore
- dd m_rpop
- dd m_drop
+ dd c_plusstore ; >In++
+ dd m_rpop ; (Wordb+1 -- Wordb+1 c) (R c -- )
+ dd m_drop ; (Wordb+1 c -- Wordb+1)
dd m_Wordbuf
- dd m_fetch
- dd m_dup
- dd m_rpush
- dd m_minus
- dd c_1minus
- dd m_rfetch
- dd m_cstore
- dd m_rpop
+ 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 -- )
+
+ 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 ; ( -- c2 ) (R c1 -- )
- dd m_rfetch
- dd m_equal
- dd m_binand
+ 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
- dd m_literal
+ dd L146 ; >In >= >Limit || cinitial != cnew
+ dd m_literal ; >In < >Limit && cinitial == cnew
dd 1
dd m_toIn
- dd c_plusstore
- dd m_jump
+ dd c_plusstore ; >In++
+ dd m_jump ; repeat
dd L145
L146:
- dd m_rpop
+ 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 -- ) TODO correct below stack notations
+ 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
@@ -903,59 +907,61 @@
dd c_qdup ; ( n n -- ) (R a a -- )
dd m_cjump ; (if)
dd L149 ; n == 0
- dd c_key ; n > 0 ( n c -- )
- dd m_dup ; ( n c c -- )
+ 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 f -- )
- dd m_over ; ( n c f n -- )
+ 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 n -1 -- )
- dd m_equal ; ( n c f1 f2 -- )
- dd m_binor ; ( n c f -- )
+ 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
- dd m_exitcolon ; ( 0 -- ) (R -- )
-L150:
+ 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
+ dd m_cstore ; store the character at a
dd m_rpop ; ( n a -- ) (R a -- )
dd c_1plus
- dd m_rpush ; ( n -- ) (R a1 a2 -- )
- dd c_1minus ; ( n-1 -- ) (R a1 a2 -- )
+ 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
-L149: ; n == 0 ( -- ) (R a a -- )
- dd m_rpop
- dd m_rpop ; ( a a -- )
- dd m_minus ; ( 0 -- )
+ 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
- dd mc_EOF ; constant eof = 0
+ CENTRY `query`, c_query, 5 ; read from input stream into the Text Input Buffer
+ dd m_Eof
+ dd c_off ; clear EOF flag
dd m_Tib ; constant puts address of tibuffer on the top
dd m_literal
- dd 4096 ; ( EOF tibuffer -- EOF tibuffer 4096 )
- dd c_accept ; ( EOF tibuffer 4096 -- n )
- dd m_dup
- dd c_0eq
- dd mc_EOF
- dd m_binand
+ 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 m_Eof
+ dd m_fetch
+ dd m_binand ; n == 0 && EOF
dd m_cjump
- dd L152
- dd m_drop
+ dd L152 ; false condition
+ dd m_drop ; n == 0 && EOF ( n -- )
dd c_qrestore_input
dd m_jump
dd L153
-L152:
+L152: ; n > 0
dd m_toLimit
- dd m_store
+ dd m_store ; number of characters to read, >Limit = n
dd m_toIn
- dd c_off
+ dd c_off ; start from 0, >In = 0
L153:
dd m_exitcolon
@@ -1089,15 +1095,16 @@
dd c_abort
L172:
dd m_exitcolon
- CENTRY `interpret`, c_interpret, 9
+
+ 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
+ dd c_word ; ( bl -- a )
dd m_dup
dd m_cfetch
dd c_0neq
dd m_cjump
- dd L176
+ dd L176 ; count at a = 0
dd c_find ; ( a -- ) a = address of counted string
dd m_cjump
dd L177
@@ -1125,8 +1132,9 @@
dd m_jump
dd L175
L176:
- dd m_drop
+ dd m_drop ; count at a = 0, ( a -- )
dd m_exitcolon
+
CENTRY `create`, c_create, 6
dd c_align
dd c_here
@@ -1656,6 +1664,7 @@
dd 0
dd m_terminate
dd m_exitcolon
+
CENTRY `include`, c_include, 7
dd c_bl
dd c_word
@@ -1673,6 +1682,7 @@
dd m_Infd
dd m_store
dd m_exitcolon
+
CENTRY `crash`, c_crash, 5
dd m_literal
dd L251
@@ -1683,27 +1693,15 @@
dd c_abort
dd m_exitcolon
- CENTRY `quit`, c_quit, 4 ; TODO correct below stack notations
+ 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 c_interpret
- dd m_Infd
- dd m_fetch ; ( 0 -- )
- dd c_0eq
- dd m_cjump
- dd L254
- dd m_literal
- dd L255 ; address of string ok
- dd m_literal
- dd 3
- dd c_type ; ( addr n -- ) type
- dd c_cr ; cr
-L254:
dd m_jump
dd L253
- dd m_exitcolon
+ dd m_exitcolon ; why is this needed?
CENTRY `(abort)`, c_parenabort, 7 ; TODO correct below stack notations
dd m_State ; ( m_State -- )
@@ -1712,15 +1710,18 @@
dd m_Sourcebuf ; variable sourcebuf
dd m_store ; variable sourcebuf = address of tibuffer
dd m_Blk ; variable blk
- dd c_off ; off variable blk = 0
- dd mc_STDIN ; stdin
- dd m_Infd ; variable
- dd m_store ; variable Infd = STDIN
+ dd c_off ; off variable blk = 0
+ dd mc_STDIN
+ dd m_Infd
+ dd m_store
dd mc_STDOUT
- dd m_Outfd ; variable
- dd m_store ; variable Outfd = STDOUT
- dd c_quit ; quit resets return stack and data stack
- dd m_exitcolon
+ dd m_Outfd
+ dd m_store
+ dd mc_STDERR
+ dd m_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
@@ -1780,13 +1781,15 @@
dd m_Sourcebuf ; variable sourcebuf
dd m_store ; variable sourcebuf = address of tibuffer
- ; stdin, stdout and stderr are constants
dd mc_STDIN
dd m_Infd
dd m_store ; stdin = 0
dd mc_STDOUT
dd m_Outfd
- dd m_store ; stdout = 1
+ dd m_store
+ dd mc_STDERR
+ dd m_Errfd
+ dd m_store
dd m_State
dd c_off ; off stores 0 at state
--- a/os/port/devforth.c
+++ b/os/port/devforth.c
@@ -12,7 +12,8 @@
*/
enum
{
- NForthProc = 256,
+ NForthproc = 256,
+ QMAX = 192*1024-1,
Qtopdir = 0,
Qforthdir,
@@ -19,7 +20,11 @@
Qnew,
Qfprocdir,
Qctl,
+ Qstdin,
+ Qstdout,
+ Qstderr,
Qvars,
+ /* Qlisten, might be good to have later on for servers */
};
/*
@@ -36,16 +41,19 @@
#define PID(q) ((q).vers)
#define NOTEID(q) ((q).vers)
-/* TODO kproc or mechanism to garbage collect these ForthProc */
-typedef struct ForthProc ForthProc;
-struct ForthProc
+/* TODO kproc or mechanism to garbage collect these Forthproc */
+typedef struct Forthproc Forthproc;
+struct Forthproc
{
Proc *p;
- ForthProc *prev, *next;
+ Forthproc *prev, *next;
+ Queue *rq; /* queued data waiting to be read */
+ Queue *wq; /* queued data waiting to be written */
+ Queue *eq; /* returned error packets */
};
int nforthprocs = 0;
-ForthProc *fhead, *ftail;
+Forthproc *fhead, *ftail;
static QLock forthlock;
static void
@@ -66,41 +74,35 @@
qunlock(&forthlock);
}
-extern int kclose(int fd);
-extern int kopen(char *path, int mode);
-extern s32 kread(int fd, void *va, s32 n);
-extern s32 kwrite(int fd, void *va, s32 n);
-extern char* kfd2path(int fd);
-
extern int forthmain(char *);
void
forthentry(void *fmem)
{
int n;
- char buf[1024];
up->type = Unknown;
print("forthentry pid %d forthmem 0x%zx\n", up->pid, (intptr)fmem);
- print("forth entry kfd2path(0) %s kfd2path(1) %s\n", kfd2path(0), kfd2path(1));
-/*int fd = kopen(kfd2path(1),OREAD);
-while((n = kread(fd, buf, 1024)) > 0)
- print("forth entry %d bytes: %s\n", n, buf);
-kclose(fd);*/
-n = forthmain(fmem);
+
+ if(waserror()){
+ print("forthentry waserror()\n");
+ for(;;){up->state = Dead;
+ sched();}
+ }
+ n = forthmain(fmem);
print("forthentry n %d\n", n);
- pexit("exit", 0);
+/* pexit("exit", 0);*/
for(;;){up->state = Dead;
sched();}
}
-ForthProc *
-newforthproc(void)
+Forthproc *
+newforthproc(Chan *cin, Chan *cout, Chan *cerr)
{
Proc *p;
Pgrp *pg;
Fgrp *fg;
Egrp *eg;
- ForthProc *f;
+ Forthproc *f;
void *forthmem;
while((p = newproc()) == nil){
@@ -116,11 +118,18 @@
p->nerrlab = 0;
kstrdup(&p->env->user, up->env->user);
+
pg = up->env->pgrp;
+ if(pg == nil)
+ panic("newforthproc: nil process group\n");
incref(pg);
p->env->pgrp = pg;
- fg = up->env->fgrp;
+ fg = newfgrp(nil);
+ fg->fd[0] = cin;
+ fg->fd[1] = cout;
+ fg->fd[2] = cerr;
+ fg->maxfd = 2;
incref(fg);
p->env->fgrp = fg;
@@ -140,9 +149,24 @@
p->hang = 0;
p->kp = 0;
- f = malloc(sizeof(ForthProc));
+ f = malloc(sizeof(Forthproc));
if(f == nil)
panic("newforthproc\n");
+ forthmem = malloc(FORTHHEAPSIZE);
+ if(forthmem == nil)
+ panic("newforthproc forthmem == nil\n");
+
+ /* need a waserror() around these */
+ /* not bothering with kick() functions */
+ f->rq = qopen(QMAX, Qcoalesce, nil, nil);
+ f->wq = qopen(QMAX, Qkick, nil, nil);
+ if(f->rq == nil || f->wq == nil)
+ error(Enomem);
+ f->eq = qopen(1024, Qmsg, 0, 0);
+ if(f->eq == nil)
+ error(Enomem);
+
+ ((intptr*)forthmem)[0] = (intptr)forthmem;
if(fhead == nil){
fhead = ftail = f;
}else{
@@ -151,9 +175,6 @@
ftail = f;
}
f->p = p;
- forthmem = nil; /*malloc(FORTHHEAPSIZE);;
- if(forthmem == nil)
- panic("newforthproc forthmem == nil\n");*/
nforthprocs++;
/* p->kpfun = func;
@@ -164,11 +185,6 @@
strcpy(p->text, "forth");
-/* if(kpgrp == nil)
- kpgrp = newpgrp();
- p->pgrp = kpgrp;
- incref(kpgrp);*/
-
memset(p->time, 0, sizeof(p->time));
p->time[TReal] = MACHP(0)->ticks;
/* cycles(&p->kentry);
@@ -177,13 +193,6 @@
qunlock(&p->debug);
p->psstate = nil;
- print("newforthproc kfd2path(0) %s kfd2path(1) %s\n", kfd2path(0), kfd2path(1));
-/* int n;
-int fd = kopen(kfd2path(1),OREAD);
-n = kwrite(fd, "junk sent to 1\n", strlen("junk sent to 1\n"));
- print("sent to forth %d bytes:\n", n);
-kclose(fd);*/
-
ready(p);
return f;
}
@@ -197,7 +206,7 @@
forthgen(Chan *c, char *name, Dirtab *, int, int s, Dir *dp)
{
Qid q;
- ForthProc *f;
+ Forthproc *f;
char *ename;
u32 pid, path;
s32 slot, i, t;
@@ -307,6 +316,18 @@
mkqid(&q, path|Qvars, c->qid.vers, QTFILE);
devdir(c, q, "vars", 0, p->env->user, 0600, dp);
break;
+ case 2:
+ mkqid(&q, path|Qstdin, c->qid.vers, QTFILE);
+ devdir(c, q, "stdin", 0, p->env->user, 0600, dp);
+ break;
+ case 3:
+ mkqid(&q, path|Qstdout, c->qid.vers, QTFILE);
+ devdir(c, q, "stdout", 0, p->env->user, 0600, dp);
+ break;
+ case 4:
+ mkqid(&q, path|Qstderr, c->qid.vers, QTFILE);
+ devdir(c, q, "stderr", 0, p->env->user, 0600, dp);
+ break;
default:
return -1;
}
@@ -368,7 +389,8 @@
u32 pid;
s32 slot;
int omode;
- ForthProc *f;
+ Forthproc *f;
+ Chan *ncin, *ncout, *ncerr;
DBG("forthopen c->path %s omode0 0x%ux\n", chanpath(c), omode0);
if(c->qid.type & QTDIR)
@@ -380,7 +402,11 @@
nexterror();
}
if(QID(c->qid) == Qnew){
- f = newforthproc();
+ /* TODO set path */
+ ncin = devclone(c);
+ ncout = devclone(c);
+ ncerr = devclone(c);
+ f = newforthproc(ncin, ncout, ncerr);
if(f == nil)
error(Enodev);
slot = procindex(f->p->pid);
@@ -387,6 +413,12 @@
if(slot < 0)
panic("forthopen");
mkqid(&c->qid, Qctl|(slot+1)<<QSHIFT, f->p->pid, QTFILE);
+ mkqid(&ncin->qid, Qstdin|(slot+1)<<QSHIFT, f->p->pid, QTFILE);
+ mkqid(&ncout->qid, Qstdout|(slot+1)<<QSHIFT, f->p->pid, QTFILE);
+ mkqid(&ncerr->qid, Qstderr|(slot+1)<<QSHIFT, f->p->pid, QTFILE);
+ incref(ncin);
+ incref(ncout);
+ incref(ncerr);
DBG("forthopen: new proc pid %d\n", f->p->pid);
}
funlock();
@@ -408,6 +440,9 @@
case Qnew:
break;
case Qctl:
+ case Qstdin:
+ case Qstdout:
+ case Qstderr:
break;
case Qvars:
if(p->kp || p->privatemem)
@@ -446,16 +481,19 @@
return;
}
-int readdone = 0;
s32
-forthread(Chan *c, void *a, s32 n, s64)
+forthread(Chan *c, void *a, s32 n, s64 off)
{
Proc *p;
+ Forthproc *f;
+ char *buf;
+ s32 rv = 0;
DBG("forthread c->path %s\n", chanpath(c));
if(c->qid.type & QTDIR)
return devdirread(c, a, n, nil, 0, forthgen);
+ f = c->aux;
p = proctab(SLOT(c->qid));
if(p->pid != PID(c->qid))
error(Eprocdied);
@@ -467,14 +505,20 @@
}
switch(QID(c->qid)){
case Qctl:
- if(readdone == 0){
- readdone = 1;
- } else if (readdone == 1){
- n = 0;
- break;
- }
- n = sprint(a, "%d", p->pid);
+ buf = smalloc(16);
+ snprint(buf, 16, "%d", p->pid);
+ rv = readstr(off, a, n, buf);
+ free(buf);
break;
+ case Qstdin:
+ rv = qread(f->rq, a, n);
+ break;
+ case Qstdout:
+ rv = qread(f->wq, a, n);
+ break;
+ case Qstderr:
+ rv = qread(f->eq, a, n);
+ break;
case Qvars: /* TODO */
error(Ebadarg);
default:
@@ -485,17 +529,53 @@
qunlock(&p->debug);
poperror();
DBG("forthread returning n %d bytes\n", n);
- return n;
+ return rv;
}
static s32
-forthwrite(Chan *c, void *, s32, s64)
+forthwrite(Chan *c, void *a, s32 n, s64)
{
+ Proc *p;
+ Forthproc *f;
+
DBG("forthwrite c->path %s\n", chanpath(c));
if(c->qid.type & QTDIR)
- error(Eisdir);
+ return devdirread(c, a, n, nil, 0, forthgen);
- return 0;
+ f = c->aux;
+ p = proctab(SLOT(c->qid));
+ if(p->pid != PID(c->qid))
+ error(Eprocdied);
+
+ eqlock(&p->debug);
+ if(waserror()){
+ qunlock(&p->debug);
+ nexterror();
+ }
+ switch(QID(c->qid)){
+ case Qctl:
+ print("forthwrite: writing to Qctl, ignored\n");
+ break;
+ case Qstdin:
+ n = qwrite(f->rq, a, n);
+ break;
+ case Qstdout:
+ n = qwrite(f->wq, a, n);
+ break;
+ case Qstderr:
+ n = qwrite(f->eq, a, n);
+ break;
+ case Qvars: /* TODO */
+ error(Ebadarg);
+ default:
+ print("unknown qid in forthwriten");
+ error(Egreg);
+ }
+
+ qunlock(&p->debug);
+ poperror();
+ DBG("forthwrite returning n %d bytes\n", n);
+ return n;
}
Dev forthdevtab = {