peter@baylor.UUCP (Peter da Silva) (08/19/85)
The following is a port of John James' FIG-FORTH for the PDP-11 to UNIX and the as assembler (with m4). I have had half a dozen requests for this from people wanting to port it to the 68000, so here it is. Notes: " foo" -> addr len Leaves address and length of the string "foo" on the stack. You can only have one such in immediate mode, since it uses PAD. fload addr len -> Loads UNIX text file. This is the preferred method of loading text, though a screens file "screens" is supported. The screens filename can be changed, and it is only opened when accessed. User, TIB, and the disk buffers are allocated on the system stack. You can use SBRK to allocate more memory. A large number of system calls are supprted. The error messages are internal, and are extended by the presence of all the UNIX errno messages. The commented source is mine. The uncommented source is mostly what I got from FIG. The person who typed it in didn't bother with the comments. key, emit, etc use the fd in the byte uvars "stdin", "stdout", and "stderr". I have added a few other uvars as needed. QUIT is highly idiosyncratic, using a prompt instead of "OK", mainly because I didn't want to bother with raw mode. It also uses the uvar "(null)" to determine the end of input. INTR puts you into a prompt where you can cold- or warm- start with 'q' or 'w'... 'q' should do nothing, but something is broken because it crashes. anything else drops you out of FORTH. If anybody actually uses this thing as released, and wants some additional support code (for example shell escapes), drop me a line... ----- forth.s ------ / The following is (c) by and provided courtesy of the Forth Interest Group. / And may be distributed so long as this notice is included. / Any commented code is (c)1984 by and provided courtesy of Peter da Silva, / and may be further distributed so long as this notice is included. / If you want any support, send me a description of the problem and / I'll do my best, which will depend on how long it is since I've looked / at the code. Anything major will require monetary recompense. / -- Peter da Silva, ...!{baylor,kitty,hyd-ptd}!peter / USmail: 13102 Fallsview #5005, Houston, TX 77077 / MaBell: (713) 497-4372 define(eis,0) w=r2 u=r3 ip=r4 s=r5 rp=sp link=0 keylen = 0100 / size of key input buffer sysorig: / Local initialisation code. mov (sp)+,argc+2 / get hold of the args area: argc mov sp,argv+2 / argv mov sp,r0 tst -(sp) 1: tst (r0)+ / look for end of argv bne 1b mov r0,envp+2 / environment mov sp,aendbuf add $-1028.*3,sp / allocate disk buffers mov sp,adskbuf add $-256.,sp / allocate tbuf mov sp,atbuf add $-keylen,sp / allocate key buffer mov sp,akeybuf add $-0100,sp / allocate user space mov sp,aup / and put it into the user pointer add $-0200,sp / allocate return stack space mov sp,ar0 / and save a pointer to it add $-256.,sp / allocate tib mov sp,atib / and save a pointer to it mov sp,as0 / stack pointer is at tib sys 48.;2;intr / catch interrupts jmp origin .data / Forth must go in data segment / / macros / / Note: local labels 8 and 9 are used by the 'head' macro, / and local labels 6 and 7 are used by the 'string' macro. / / head(length_byte,name,name_hibyte,internal_label,code_addr) / / Notes: / length_byte is the length of the name or'ed with / 0200 or 0300 if it is immediate. / name should be empty (,,) for 1-byte names. odd-length / names should be truncated to an even length / name_hibyte should be empty for even length names / code_addr should be empty for primitives. / / string(text) / /divert(-1) / /changequote({,}) /define(link,8) /define(link2,9) /define(link1,9) /define(head,{/ / : $2{}substr($3,1,1) undefine({link2})define({link2},link)dnl undefine({link})define({link},link1)dnl undefine({link1})define({link1},link2)dnl link1: .byte $1 / length ifelse($2,,/,<{$2}>) / name ifelse($3,,.byte 240,.byte $3|128.) / hibyte ifelse($6,,link()b,$6) / link $4: ifelse($5,,.+2,$5)}) / cfa /define(next,{mov (ip)+,w jmp *(w)+}) /define(string,{.byte 7f-6f 6: <$1> 7: .even}) /divert / / start-up table origin: jmp cent /0 jmp went /4 / acpu: 11 /8 arev: 13 /10 aflink: task-10 /12 backsp: 10 /14 aup: 0 / filled in at origin as0: 0 / ditto ar0: 0 / ditto atib: 0 / ditto awidth: 37 awarn: 0 afence: xdp adp: xdp avlink: xxvoc adskbuf:0 / ditto aendbuf:0 / ditto 0 0 / / nucleus / head(203,li,'t,lit,,0) mov (ip)+,-(s) next / head(207,execut,'e,exec) mov (s)+,w jmp *(w)+ / head(206,branch,,bran) add (ip),ip next / head(207,0branc,'h,zbran) tst (s)+ bne 1f add (ip),ip next 1: add $2,ip next / head(206,(loop),,xloop) inc (rp) cmp (rp),2(rp) bpl 1f / was bge 1f. add (ip),ip next 1: add $4,rp add $2,ip next / head(207,{{(+loop}},{{')}},xploo) add (s),(rp) tst (s)+ blt 2f cmp 2(rp),(rp) bmi 1f / was ble 1f beq 1f add (ip),ip next 1: add $4,rp add $2,ip next 2: cmp (rp),2(rp) bmi 1b / was ble 1f beq 1f add (ip),ip next / head(204,(do),,xdo) mov 2(s),-(rp) mov (s),-(rp) add $4,s next / head(201,,'i,i) mov (rp),-(s) next / head(205,digi,'t,digit) cmp 2(s),$141 / allow for lower case blt 1f sub $40,2(s) 1: sub $60,2(s) cmp 2(s),$11 ble 1f sub $7,2(s) cmp 2(s),$12 blt 2f 1: tst 2(s) blt 2f cmp 2(s),(s) bge 2f mov $1,(s) next 2: add $2,s clr (s) next / head(206,(find),,pfind) mov (s)+,r0 / r0 is test mov (s)+,r1 / r1 is target mov r5,-(rp) / r5 is ... mov r4,-(rp) / r4 is ... mov r3,-(rp) / r3 is ... clr -(rp) / top of stack is ... scratch mov (r1),r2 bic $100200,r2 / r2 -> length & first byte of target / fcomp: fast: mov (r0),r3 / r3 is length and first byte of test bic $100300,r3 cmp r2,r3 / compare beq nofast xmatch: tst (r0)+ / fail, search for end of word bpl xmatch tst (r0) / is there a nextlink ? beq failed mov (r0),r0 / yes, indirect br fcomp / and try again / length and first byte match... nofast: mov (r0),(rp) / save length of test... mov r1,r5 / r5 is pointer to target br nofst1 / enter loop in middle!!!! damn. mloop: tst (r5)+ / get Next 2 bytes mov (r5),r4 / r4 is Next 2 bytes of target mov (r0),r3 / r3 is Next 2 bytes of test bic $100000,r3 / with the high bit cleared cmp r3,r4 / if they differ bne xmatch / go back and skip name nofst1: bit $100000,(r0)+ / check for end of name beq mloop / nope, compare Next 2 bytes^ mov (rp)+,r2 / recover r2 = length, mov (rp)+,r3 / r3, mov (rp)+,r4 / r4, mov (rp)+,r5 / r5. add $4,r0 / skip to pfa mov r0,-(s) / and push it bic $177400,r2 / dump high byte of test length mov r2,-(s) / and push it mov $1,-(s) / along with a 'true' next failed: tst (rp)+ / failed: scratch length mov (rp)+,r3 / recover r3, mov (rp)+,r4 / r4, mov (rp)+,r5 / r5. clr -(s) / push a false next / head(207,enclos,'e,encl) cmpb (s),$40 / is it a space? beq encl1 / if so, use the alternate enclose mov (s),r0 mov 2(s),r1 sub $4,s 1: cmpb (r1)+,r0 beq 1b sub $1,r1 mov r1,4(s) 2: tstb (r1) beq 4f cmpb (r1)+,r0 bne 2b mov r1,(s) sub $1,r1 3: mov r1,2(s) mov 6(s),r1 sub r1,(s) sub r1,2(s) sub r1,4(s) next 4: mov r1,(s) cmp r1,4(s) bne 3b add $1,r1 br 3b / encl1: mov 2(s),r1 / special version for white space... sub $4,s 1: movb (r1)+,r0 bic $177400,r0 cmp r0,$40 / space beq 1b cmp r0,$10 / backspace beq 1b cmp r0,$11 / tab beq 1b cmp r0,$12 / newline beq 1b cmp r0,$13 / vtab beq 1b cmp r0,$14 / ff beq 1b cmp r0,$15 / cr beq 1b sub $1,r1 mov r1,4(s) 2: tstb (r1) beq 4f movb (r1)+,r0 bic $177400,r0 cmp r0,$40 / space beq 5f cmp r0,$10 / backspace beq 5f cmp r0,$11 / tab beq 5f cmp r0,$12 / newline beq 5f cmp r0,$13 / vtab beq 5f cmp r0,$14 / ff beq 5f cmp r0,$15 / cr beq 5f br 2b 5: mov r1,(s) sub $1,r1 3: mov r1,2(s) mov 6(s),r1 sub r1,(s) sub r1,2(s) sub r1,4(s) next 4: mov r1,(s) cmp r1,4(s) bne 3b add $1,r1 br 3b / head(204,emit,,emit,docol) pemit;zequ;zbran;1f-. stdout;cat;two;equal;zbran;2f-. lit;-1;exit 2: two;stdout;cstor perror;quit 1: one;out;pstor semis / head(203,ke,'y,key,docol) pkey;zequ;zbran;1f-. errno;at;lit;42.;equal;zbran;2f-. one;feof;store;lit;10. bran;1f-. 2: perror;abort 1: dup;lit;10.;equal;zbran;1f-. zero;out;store 1: semis / head(211,?termina,'l,qterm,docol) pqter semis / head(202,cr,,cr,docol) lit 12 emit zero;out;store semis / head(205,cmov,'e,cmove) tst (s) beq 2f mov 2(s),r0 mov 4(s),r1 mov (s),r2 1: movb (r1)+,(r0)+ sob r2,1b 2: add $6,s next / head(206,-cmove,,dcmove) tst (s) beq 2f mov 2(s),r0 add (s),r0 mov 4(s),r1 add (s),r1 mov (s),r2 1: movb -(r1),-(r0) sob r2,1b 2: add $6, s next / head(202,u*,,ustar) jsr pc,umult next umult: mov (s)+,r2 mov $20,-(rp) clr r0 clr r1 2: rol r1 rol r0 rol r2 bcc 1f add (s),r1 adc r0 1: dec (rp) bne 2b mov r1,(s) mov r0,-(s) tst (rp)+ rts pc / head(202,u/,,uslas) jsr pc,udiv next udiv: mov (s)+,r2 mov (s)+,r0 mov (s)+,r1 mov $20,-(s) 1: asl r1 rol r0 beq 2f sub r2,r0 inc r1 bcc 2f add r2,r0 dec r1 2: dec (s) bne 1b tst (s)+ mov r0,-(s) mov r1,-(s) rts pc / head(203,an,'d,and) com (s) bic (s)+,(s) next / head(202,or,,or) bis (s)+,(s) next / head(203,xo,'r,fxor) ifelse(eis,1, { mov (s)+,r0 xor r0,(s) },{ mov (s),-(rp) bic 2(s),(rp) bic (s)+,(s) bis (rp)+,(s) }) next / head(204,swab,,fswab) swab (s) next / head(203,sp,'@,spat) mov s,r1 mov r1,-(s) next / head(203,rp,'@,rpat) mov rp,-(s) next / head(203,sp,'!,spsto) mov 6(u),s next / head(203,rp,'!,rpsto) mov origin+24,rp next / head(202,;s,,semis) mov (rp)+,ip next / head(205,leav,'e,leave) mov (rp),2(rp) next / head(206,setjmp,,setjmp)/ addr -> 0; later -> n mov (s)+,r0 / get buffer address mov ip,(r0)+ / save ip mov s,(r0)+ / sp mov rp,(r0)+ / rp clr -(s) / return 0 next / head(207,longjm,'p,longjmp)/ val addr -> *; setjmp returns val mov (s)+,r0 / get buffer address mov (s)+,r1 / save val mov (r0)+,ip / recover ip mov (r0)+,s / sp mov (r0)+,rp / rp mov r1,-(s) / return val next / head(202,\>r,,tor) mov (s)+,-(rp) next / head(202,r\>,,fromr) mov (rp)+,-(s) next / head(201,,'r,r) mov (rp),-(s) next / head(202,0=,,zequ) tst (s) beq 1f clr (s) br 2f 1: mov $1,(s) 2: next / head(202,0<,,zless) tst (s) bmi 1f clr (s) br 2f 1: mov $1,(s) 2: next / head(201,,'+,plus) add (s)+,(s) next / head(202,d+,,dplus) add 2(s),6(s) adc 4(s) add (s),4(s) add $4,s next / head(205,minu,'s,minus) neg (s) next / head(206,dminus,,dminu) neg (s) neg 2(s) sbc (s) next / head(204,over,,over) mov 2(s),-(s) next / head(204,drop,,drop) add $2,s next / head(204,swap,,swap) mov 2(s),r1 mov (s),2(s) mov r1,(s) next / head(203,du,'p,dup) mov (s),-(s) next / head(202,+!,,pstor) add 2(s),*(s) add $4,s next / head(206,toggle,,toggl) mov 2(s),-(s) movb *(s),(s) mov (s),-(rp) bic 2(s),(rp) bic (s)+,(s) bis (rp)+,(s) mov 2(s),-(s) movb 2(s),*(s) add $6,s next / head(201,,'@,at) mov *(s),(s) next / head(202,c@,,cat) movb *(s),r1 bic $177400,r1 mov r1,(s) next / head(201,,'!,store) mov 2(s),*(s) add $4,s next / head(202,c!,,cstor) movb 2(s),*(s) add $4,s next / / pre-compiled forth section / head(301,,':,colon,docol) qexec scsp curr at cont store creat rbrac pscod docol: mov ip,-(rp) mov w,ip next / head(301,,';,semi,docol) qcsp comp semis smudg lbrac semis / head(210,constant,,con,docol) creat smudg comma pscod docon: mov (w),-(s) next / head(210,variable,,var,docol) con pscod dovar: mov w,-(s) next / head(204,user,,user,docol) con pscod douse: mov (w),-(s) add u,(s) next / / constants / head(201,,'0,zero,docon) 0 / head(201,,'1,one,docon) 1 / head(201,,'2,two,docon) 2 / head(201,,'3,three,docon) 3 / head(202,bl,,bl,docon) 40 / head(203,c/,'l,cl,docon) 100 / head(205,b/bu,'f,bbuf,docon) 1024. / head(205,b/sc,'r,bscr,docon) 1 / head(207,+origi,'n,porig,docol) lit origin plus semis / / user variables / head(202,s0,,szero,douse) 6 / head(202,r0,,rzero,douse) 10 / head(203,ti,'b,tib,douse) 12 / head(205,widt,'h,width,douse) 14 / head(207,warnin,'g,warn,douse) 16 / head(205,fenc,'e,fence,douse) 20 / head(202,dp,,dp,douse) 22 / head(210,voc-{{link}},,vocl,douse) 24 / head(205,firs,'t,first,douse) 26 / head(205,limi,'t,limit,douse) 30 / head(203,bl,'k,blk,douse) 36 / head(202,in,,in,douse) 40 / head(203,ou,'t,out,douse) 42 / head(203,sc,'r,scr,douse) 44 / head(206,offset,,ofset,douse) 46 / head(207,contex,'t,cont,douse) 50 / head(207,curren,'t,curr,douse) 52 / head(205,stat,'e,state,douse) 54 / head(204,base,,base,douse) 56 / head(203,dp,'l,dpl,douse) 60 / head(203,fl,'d,fld,douse) 62 / head(203,cs,'p,csp,douse) 64 / head(202,{{r#}},,rnum,douse) 66 / head(203,hl,'d,hld,douse) 70 / head(203,us,'e,use,douse) 72 / head(204,prev,,prev,douse) 74 / head(206,(null),,pnull,douse) 76 / / end of user area / head(202,1+,,onep) inc (s) next / head(202,2+,,twop) add $2,(s) next / head(202,1-,,onem) dec (s) next / head(202,2/,,twod) asr (s) next / head(202,2*,,twot) asl (s) next / head(204,here,,here,docol) dp at semis / head(205,allo,'t,allot,docol) dp pstor semis / head(201,,'{{,}},comma,docol) here store two allot semis / head(201,,'-,fsub) sub (s)+,(s) next / head(201,,'=,equal) cmp 2(s),(s)+ beq 1f clr (s) br 2f 1: mov $1,(s) 2: next / head(201,,'<,less) cmp 2(s),(s)+ bmi 1f / was blt clr (s) br 2f 1: mov $1,(s) 2: next / head(201,,'>,great) cmp 2(s),(s)+ bmi 1f beq 1f mov $1,(s) br 2f 1: clr (s) 2: next / head(202,u<,,uless) cmp 2(s),(s)+ blo 1f clr (s) br 2f 1: mov $1,(s) 2: next / head(202,u\>,,ugt) cmp 2(s),(s)+ bhi 1f clr (s) br 2f 1: mov $1,(s) 2: next / head(203,ro,'t,rot) mov (s),r0 mov 4(s),(s) mov 2(s),4(s) mov r0,2(s) next / head(205,unde,'r,under) mov 2(s),r0 mov (s),2(s) mov (s),-(s) mov r0,2(s) next / head(205,spac,'e,space,docol) lit 40 emit semis / head(204,-dup,,ddup) tst (s) beq 1f mov (s),-(s) 1: next / head(210,traverse,,trav,docol) swap 1: over plus lit 177 over cat less zbran 1b-. swap drop semis / head(206,latest,,lates,docol) curr at at semis / head(203,lf,'a,lfa,docol) lit 4 fsub semis / head(203,cf,'a,cfa,docol) two fsub semis / head(203,nf,'a,nfa,docol) lit 5 fsub lit -1 trav semis / head(203,pf,'a,pfa,docol) one trav lit 5 plus semis / head(204,!csp,,scsp,docol) spat csp store semis / head(206,?error,,qerr,docol) swap zbran 1f-. error bran 2f-. 1: drop 2: semis / head(205,?com,'p,qcomp,docol) state at zequ lit 21 qerr semis / head(205,?exe,'c,qexec,docol) state at lit 22 qerr semis / head(206,?pairs,,qpair,docol) fsub lit 23 qerr semis / head(204,?csp,,qcsp,docol) spat csp at fsub lit 24 qerr semis / head(210,?loading,,qload,docol) blk at zequ lit 26 qerr semis / head(207,compil,'e,comp,docol) qcomp fromr dup twop tor at comma semis / head(301,,'[,lbrac,docol) zero state store semis / head(201,,'],rbrac,docol) lit 300 state store semis / head(206,smudge,,smudg,docol) lates lit 40 toggl semis / head(203,he,'x,hex,docol) lit 20 base store semis / head(207,decima,'l,decim,docol) lit 12 base store semis / head(205,octa,'l,octal,docol) lit 10 base store semis / head(207,{{(;code}},{{')}},pscod,docol) fromr lates pfa cfa store semis / head(207,<build,'s,build,docol) zero con semis / head(205,does,'>,does,docol) fromr lates pfa store pscod dodoe: mov ip,-(rp) mov (w)+,ip mov w,-(s) next / head(205,coun,'t,count,docol) dup onep swap cat semis / head(206,strlen,,strlen,docol) dup 1: dup;cat;zbran;2f-. onep;bran;1b-. 2: swap;fsub semis / head(204,puts,,puts,docol) dup;strlen;type semis / head(204,type,,type,docol) dup;out;pstor stdout;at;write;zbran;1f-. drop 1: semis / / ddup / zbran / xxl2-. / over / plus / swap / xdo /xxl1: i / cat / emit / xloop / xxl1-. / bran / xxl3-. /xxl2: drop /xxl3: semis / / head(206,=cells,,ecell,docol) dup one and plus semis / head(211,-trailin,'g,dtrai,docol) dup zero xdo 1: over over plus one fsub cat bl fsub zbran 2f-. leave bran 3f-. 2: one fsub 3: xloop 1b-. semis / head(202,{{,"}},,commaq,docol) lit;34. word here cat onep ecell allot semis / head(204,(."),,pdotq,docol) r count dup onep ecell fromr plus tor type semis / head(302,.",,dotq,docol) state at zbran 1f-. comp pdotq commaq bran 2f-. 1: lit;34. word here count type 2: semis / head(203,{{("}},{{')}},pqot,docol) r;count dup;onep;ecell fromr;plus;tor semis / head(301,,'",qot,docol) state at zbran 1f-. comp pqot commaq bran 2f-. 1: lit;34. word here pad over cat onep cmove pad count 2: semis / head(203,{{,c}},{{'"}},ccommaq,docol) lit;34.;word here;count; dup;tor; here;swap; cmove zero; here;r;plus; cstor fromr;onep; ecell; allot semis / head(204,(c"),,pcqot,docol) r;count two;plus;ecell fromr;plus;tor semis / head(302,c",,cqot,docol) lit 34. state at zbran 1f-. comp pcqot word zero here count plus cstor here cat two plus ecell allot bran 2f-. 1: word here;count; pad;swap; cmove zero; here;cat; pad;plus; cstor pad 2: semis / head(206,?align,,qalig,docol) here one and allot semis / head(206,expect,,expec,docol) / addr len -> over;rot;rot / addr addr len over;plus;swap;xdo 1: drop key;dup;lit;10.;equal;zbran;2f-. drop;i leave;bran;3f-. 2: i;cstor;i;onep 3: xloop;1b-. zero;over;cstor;onep;zero;swap;cstor semis / over;tor / save addr / addr len / stdin;at;read;zbran;1f-. / real_len / ddup;zequ;zbran;3f-. / zero bytes read? / one;feof;store;one / yes, set feof /3: fromr;plus;one;fsub / real_len+addr-1 (eat LF) / zero;over;cstor / = 0 / zero;swap;onep;cstor / real_len+addr = 0 / bran;2f-. /1: zero;r;cstor / fail, return null string / zero;fromr;onep;cstor / perror / and print an error message /2: semis / head(205,quer,'y,query,docol) tib at lit 256. expec zero in store semis / head(301,,0,null,docol) / / long version for small buffers / / blk / at / zbran / xxj2-. / one / blk / pstor / zero / in / store / blk / at / bscr / mod / zequ / zbran / xxj1-. / qexec / fromr / drop /xxj1: bran / xxj4-. /xxj2: one / pnull / store /xxj4: semis / / short version for 1k buffers / blk at zbran 1f-. qexec 1: one pnull store semis / head(204,fill,,fill,docol) swap tor over cstor dup onep fromr one fsub cmove semis / head(205,eras,'e,erase,docol) zero fill semis / head(206,blanks,,blank,docol) bl fill semis / head(204,hold,,hold,docol) lit -1 hld pstor hld at cstor semis / head(203,pa,'d,pad,docol) here lit 104 plus semis / head(210,(number),,pnumb,docol) 1: onep dup tor cat base at digit zbran 2f-. swap base at ustar drop rot base at ustar dplus dpl at onep zbran 3f-. one dpl pstor 3: fromr bran 1b-. 2: fromr semis / head(206,number,,numb,docol) zero zero rot dup onep cat lit 55 equal dup tor plus lit -1 1: dpl store pnumb dup cat bl fsub zbran 2f-. dup cat lit 56 fsub zero qerr zero bran 1b-. 2: drop fromr zbran 1f-. dminu 1: semis / head(205,-fin,'d,dfind,docol) bl word icase;at;zbran;1f-. here count lower 1: here cont at at pfind dup zequ zbran 1f-. drop here lates pfind 1: semis / head(205,lowe,'r,lower,docol) over plus swap xdo 2: i cat lit 100 great i cat lit 133 uless and zbran 1f-. i lit 40 toggl 1: xloop 2b-. semis / head(207,{{(abort}},{{')}},pabor,docol) abort semis / head(205,erro,'r,error,docol) dup;tor warn at zless zbran;1f-. pabor 1: tib;at;in;at;type pdotq string(? ) mess pdotq string(... ) tib;at;in;at;plus;puts cr fromr;zequ;zbran;1f-. contin;at;zbran;1f-. semis / 1: spsto in at blk keybuf;two;plus;lit;4;erase / keybuf 2 + 4 erase ( empty key buffer ) at quit semis / head(203,id,'.,iddot,docol) pad lit 40 lit 137 fill dup pfa lfa over fsub pad swap cmove pad count lit 37 and type space semis / head(206,create,,creat,docol) dfind;zbran;1f-. drop uniq;at;zbran;2f-. nfa;iddot lit;4;mess bran;1f-. 2: drop 1: / here;dup;cat;width;at;min;onep;allot qalig dup;lit;240;toggl here;one;fsub lit;200;toggl lates;comma curr;at;store here;twop;comma semis / head(311,[compile,'],bcomp,docol) dfind zequ zero qerr drop cfa comma semis / head(307,litera,'l,liter,docol) state at zbran 1f-. comp lit comma 1: semis / head(310,dliteral,,dlite,docol) state at zbran 1f-. swap liter liter 1: semis / head(206,?stack,,qstac,docol) szero at two fsub spat uless one qerr spat here lit 200 plus uless two qerr semis / head(211,interpre,'t,inter,docol) 1: dfind zbran;4f-. state at less zbran;2f-. cfa comma bran;3f-. 2: cfa exec 3: qstac bran;2f-. 4: here numb dpl at onep zbran;3f-. dlite bran;4f-. 3: drop liter 4: qstac 2: pnull at zbran;1b-. zero pnull store semis / head(211,immediat,'e,immed,docol) lates lit 100 toggl semis / head(212,vocabulary,,vocab,docol) build lit 120201 comma curr at cfa comma here vocl at comma vocl store does dovoc: twop cont store semis / head(213,definition,'s,defin,docol) cont at curr store semis / head(301,,{{'(}},paren,docol) lit 51 word semis / head(206,prompt,,pmpt,docol) out;at;zbran;1f-. cr 1: spat;szero;at;fsub;minus;ddup;zbran;1f-. pdotq string(<) twod;zero;dotr 1: base;at;lit;10.;equal;zequ;zbran;2f-. spat;szero;at;fsub;zequ;zbran;3f-. / anything on the stack? pdotq string({{<}}) / no, brocket 3: pdotq string({{:}}) / add a colon base;at;dup;tor;decim;zero;dotr fromr;base;store 2: pdotq string({{\> }}) state at zbran 1f-. two spacs 1: semis / head(204,quit,,quit,docol) zero pnull store zero blk store lbrac zero;stdin;store / fix stdin ... stdout;at;two;great;zbran;1f-. / and, if it's bad, ... one;stdout;store / ... stdout 1: lit;22.;porig;at;tib;store / ... and tib ftime;at;zbran;1f-. zero;ftime;store argv;tor 3: / begin fromr;twop;dup;tor;at;ddup zbran;1f-. dup;strlen;fload bran;3b-. fromr;drop / pqot / s t r i n g(FORTHINIT) / getenv;zbran;1f-. / tib;store / rpsto;inter 1: rpsto pmpt query inter feof;at;zbran;2f-. ieof;at;zbran;3f-. pdotq string(Use "bye" or "exit" to leave FORTH) cr zero;feof;store bran;2f-. 3: bye 2: bran 1b-. / head(205,abor,'t,abort,docol) spsto decim pdotq string({SWT FIG-Forth Version 1.3 (UNIX)}) cr forth defin quit / / cold and warm starts / rtt=000006 1: <{ Interrupt: }> 2: .even;0 3: intr: mov r0,-(sp) / save regs in case mov r1,-(sp) mov r2,-(sp) mov r3,-(sp) mov r4,-(sp) mov r5,-(sp) sys 48.;2;intr / reset signal mov $1,r0 sys 4.;1b;2b-1b / print 'Interrupt: ' mov $0,r0 sys 3.;2b;3b-2b / read command: cmpb 2b,$'C / C: cold beq cent cmpb 2b,$'c beq cent cmpb 2b,$'W / W: warm beq went cmpb 2b,$'w beq went cmpb 2b,$'Q / Q: quit beq qent cmpb 2b,$'q beq qent cmpb 2b,$'/ bne int_ex mov (sp)+,r5 mov (sp)+,r4 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov (sp)+,r0 rtt int_ex: mov $-1,r0 / else exit sys 1. / qent: mov $quit+2,r4 / starts at 'quit' jmp rpsto+2 / with an empty rstack / head(204,cold,,cold) cent: mov origin+14,forth+6 mov origin+20,u mov origin+42,r0 mov origin+44,r1 1: clr (r0)+ cmp r0,r1 blt 1b clr 42(u) clr 46(u) mov origin+42,72(u) mov origin+42,74(u) mov $30,r1 br w2 went: mov $12,r1 w2: mov $origin+22,r5 mov origin+20,r0 clr 76(u)/ *** 10 mar 82 *** (null) add $6,r0 add r5,r1 1: mov (r5)+,(r0)+ cmp r5,r1 blt 1b mov origin+24,rp mov $go,ip next / go: spsto decim forth defin abort 0 0 0 / head(204,argc,,argc,docon) 0 / head(204,argv,,argv,docon) 0 / head(204,envp,,envp,docon) 0 / head(204,s-\>d,,stod) clr -(s) tst 2(s) bpl 1f dec (s) 1: next / head(203,ab,'s,abs,docol) dup zless zbran 1f-. minus 1: semis / head(204,dabs,,dabs,docol) dup zless zbran 1f-. dminu 1: semis / head(203,mi,'n,min,docol) over over great zbran 1f-. swap 1: drop semis / head(203,ma,'x,max,docol) over over less zbran 1f-. swap 1: drop semis / head(202,m*,,mstar) ifelse(eis,1, { mov (s)+,r0 mul (s),r0 mov r1,(s) mov r0,-(s) next },{ mov 2(s),-(rp) bpl 1f neg 2(s) 1: tst (s) bpl 2f neg (rp) neg (s) 2: jsr pc,umult tst (rp)+ bpl 3f com (s) com 2(s) add $1,2(s) adc (s) 3: next }) / head(202,m/,,mslas) ifelse(eis,1, { mov 2(s),r0 mov 4(s),r1 div (s)+,r0 mov r1,2(s) mov r0,(s) next },{ mov 2(s),-(rp) bne 5f inc (rp) 5: mov (rp),-(rp) bpl 1f com 2(s) com 4(s) add $1,4(s) adc 2(s) 1: tst (s) bpl 2f neg (rp) neg (s) 2: jsr pc,udiv tst (rp)+ bpl 3f neg (s) 3: tst (rp)+ bpl 4f neg 2(s) 4: next }) / head(201,,'*,star,docol) mstar drop semis / head(204,/mod,,slmod,docol) tor stod fromr mslas semis / head(201,,'/,slash,docol) slmod swap drop semis / head(203,mo,'d,mod,docol) slmod drop semis / head(205,*/mo,'d,ssmod,docol) tor mstar fromr mslas semis / head(202,*/,,ssla,docol) ssmod swap drop semis / head(205,m/mo,'d,msmod,docol) tor zero r uslas fromr swap tor uslas fromr semis / / miscellaneous higher levels / / head(301,,047,tick,docol) dfind zequ zero qerr drop liter semis / head(206,forget,,forge,docol) curr at cont at fsub lit 30 qerr tick dup fence at uless lit 25 qerr dup nfa dp store lfa at cont at store semis / head(204,back,,back,docol) here fsub comma semis / head(305,begi,'n,begin,docol) qcomp here one semis / head(305,endi,'f,endif,docol) qcomp two qpair here over fsub swap store semis / head(304,then,,then,docol) endif semis / head(302,do,,do,docol) comp xdo here lit 3 semis / head(304,loop,,loop,docol) lit 3 qpair comp xloop back semis / head(305,+loo,'p,ploop,docol) lit 3 qpair comp xploo back semis / head(305,unti,'l,until,docol) one qpair comp zbran back semis / head(303,en,'d,end,docol) until semis / head(305,agai,'n,again,docol) one qpair comp bran back semis / head(306,repeat,,repeat,docol) tor tor again fromr fromr two fsub endif semis / head(302,if,,if,docol) comp zbran here zero comma two semis / head(304,else,,else,docol) two qpair comp bran here zero comma swap two endif two semis / head(305,whil,'e,while,docol) if twop semis / / head(206,spaces,,spacs,docol) zero max ddup zbran 2f-. zero xdo 1: space xloop 1b-. 2: semis / head(202,<{{#}},,bdigs,docol) pad hld store semis / head(202,{{#}}\>,,edigs,docol) drop drop hld at pad over fsub semis / head(204,sign,,sign,docol) rot zless zbran 1f-. lit 55 hold 1: semis / head(201,,'{{#}},dig,docol) base at msmod rot lit 11 over less zbran 1f-. lit 7 plus 1: lit 60 plus hold semis / head(202,{{#}}s,,digs,docol) 1: dig over over or zequ zbran 1b-. semis / head(203,d.,'r,ddotr,docol) tor swap over dabs bdigs digs sign edigs fromr over fsub spacs type semis / head(202,.r,,dotr,docol) tor stod fromr ddotr semis / head(202,d.,,ddot,docol) zero ddotr space semis / head(201,,'.,dot,docol) stod ddot semis / head(201,,277,quest,docol) at dot semis / head(202,u.,,udot,docol) zero ddot semis / / utility section head(205,vlis,'t,vlist,docol) lit 200 out store cont at at 1: out at lit 100 great zbran 2f-. cr zero out store 2: dup iddot space pfa lfa at dup zequ qterm or zbran 1b-. drop semis / / / installation-dependent section (terminal, disk i/o, and traps) / .even / head(206,(emit),,pemit) mov s,1f mov stdout+2,r0 sys 4. 1: 0 1 bcc 1f mov r0,errno+2 clr (s) br 2f 1: mov $1,(s) 2: next / head(206,keybuf,,keybuf,dovar) akeybuf:0 keyptr: 0 keyend: 0 / head(205,{{(key}},{{')}},pkey) cmp keyptr,keyend / any characters waiting? beq 1f / if keyloop:mov akeybuf,r0 / get buffer add keyptr,r0 / add offset clr -(s) / push movb (r0),(s) / value inc keyptr / point to nxt char mov $1,-(s) / return success br 2f / else 1: mov akeybuf,3f / keybuf, keylen, mov stdin+2,r0 / fildes sys 3. / read 3: 0 keylen bec 3f / if an error mov r0,errno+2 / record type clr -(s) / return error br 2f / else 3: tst r0 / anything read? bne 1f / if not mov $42.,errno+2 / end of file. clr -(s) / return error br 2f / else 1: mov r0,keyend / save length clr keyptr / reset pointer br keyloop / and try again 2: next / return / head(213,{{(?terminal}},{{')}},pqter) mov $0,-(s) next / head(203,by,'e,bye,docol) zero;exit / head(204,exit,,exit) mov (s)+,r0 sys 1 / / UNIX disk i/o / head(206,(open),,popen) / addr mode -> {0|fd 1} mov (s)+,1f mov (s)+,2f sys 5. 2: 0 1: 0 bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov r0,-(s) mov $1,-(s) 2: next / head(204,open,,open,docol) / addr len mode -> {fd 1|0} tor;dup;tor / save mode, len tbuf;swap;cmove / move name to tbuf zero;tbuf;fromr;plus;cstor / add null tbuf;fromr;popen semis / head(207,{{(creat}},{{')}},pcret)/ addr mode -> {0|fd 1} mov (s)+,1f mov (s)+,2f sys 8. 2: 0 1: 0 bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov r0,-(s) mov $1,-(s) 2: next / head(205,crea,'t,cret,docol) / addr len mode -> {fd 1|0} tor;dup;tor / save mode, len tbuf;swap;cmove / move name to tbuf zero;tbuf;fromr;plus;cstor / add null tbuf;fromr;pcret semis / head(205,clos,'e,close) / fd -> flag mov (s)+,r0 sys 6. bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov $1,-(s) 2: next / head(204,tbuf,,tbuf,docon) atbuf: xdp / head(205,lsee,'k,lseek) / lo hi fd -> flag mov (s)+,r0 mov (s)+,1f mov (s)+,2f sys 19. 1: 0 2: 0 0 bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov $1,-(s) 2: next / head(204,read,,read) / addr bytes fd -> {bytes 1|0} mov (s)+,r0 / fd mov (s)+,2f / addr mov (s)+,1f / length sys 3. / read 1: 0 / to be addr 2: 0 / to be length bec 1f / if succeeds, skip, else mov r0,errno+2 / save errno clr -(s) / return false br 2f 1: mov r0,-(s) / success, return len mov $1,-(s) / and true 2: next / head(205,writ,'e,write)/ addr bytes fd -> {bytes 1|0} mov (s)+,r0 mov (s)+,2f mov (s)+,1f sys 4. 1: 0 2: 0 bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov r0,-(s) mov $1,-(s) 2: next / / Other UNIX system calls / head(203,br,'k,brk) mov (s),abreak mov (s)+,1f sys 17. 1: xbreak bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov $1,-(s) 2: next / head(204,sbrk,,sbrk,docol) break;at;plus;brk next / head(205,brea,'k,break,dovar) abreak: xbreak / head(207,{{(indir}},{{')}},pindir) / r0 r1 addr -> {r0 r1 1|0} mov (s)+,1f mov (s)+,r1 mov (s)+,r0 sys 0. 1: 0 bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov r0,-(s) mov r1,-(s) mov $1,-(s) 2: next / head(205,indi,'r,indir,docol) / args call r0 r1 -> args call {r0 r1 1|0} spat;lit;4;plus;pindir semis / head(204,fork,,fork) sys 2. br child parent: bec 1f mov r0,errno+2 mov $-1.,-(s) br 2f 1: mov r0,-(s) 2: next child: mov $0,-(s) next / head(205,exec,'e,xece) / name argv envp -> ERROR mov (s)+,3f mov (s)+,2f mov (s)+,1f sys 59. 1: 0 2: 0 3: 0 mov r0,errno+2 next / head(204,wait,,wait) / wait -> {pid stat 1|0} sys 7. bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov r0,-(s) mov r1,-(s) mov $1,-(s) 2: next / head(204,exec,,xec,docol) envp;xece semis / head(206,signal,,signal) / addr sig -> {addr 1|0} mov (s)+,1f mov (s)+,2f sys 48. 1: 0 2: 0 bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov r0,-(s) mov $1,-(s) 2: next / head(204,time,,time) / -> t.0 t.1 sys 13. mov r1,-(s) mov r0,-(s) next / head(205,alar,'m,alarm) / t -> old.t mov (s)+,r0 sys 27. mov r0,-(s) next / head(207,{{(chdir}},{{')}},pcd) / name -> t/f mov (s)+,1f sys 12. 1: 0 bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov $1,-(s) 2: next / head(204,udup,,udup) / fd -> {fd 1|0} mov (s)+,r0 bic $0100,r0 sys 41. bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov r0,-(s) mov $1,-(s) 2: next / head(205,udup,'2,udup2) / fd ofd -> 1|0 mov (s)+,r0 bis $0100,r0 mov (s)+,r1 sys 41. bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov $1,-(s) 2: next / head(206,getpid,,getpid) / -> pid sys 20. mov r0,-(s) next / head(206,getuid,,getuid) / -> euid uid sys 24. mov r1,-(s) mov r0,-(s) next / head(206,getgid,,getgid) / -> egid gid sys 47. mov r1,-(s) mov r0,-(s) next / head(204,kill,,kill) / pid sig -> 1|0 mov (s)+,1f mov (s)+,r0 sys 37. 1: 0 bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov $1,-(s) 2: next / head(204,nice,,nice) / niceness -> 1|0 mov (s)+,r0 sys 34. bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov $1,-(s) 2: next / head(205,paus,'e,pause) sys 29. next / head(204,pipe,,pipe) / -> {rfd wfd 1|0} sys 42. bec 1f mov r0,errno+2 clr -(s) br 2f 1: mov r0,-(s) mov r1,-(s) mov $1,-(s) 2: next / head(206,unique,,uniq,dovar) 1 / head(206,contin,,contin,dovar) 0 / head(205,errn,'o,errno,dovar) 0 / head(204,feof,,feof,dovar) 0 / head(204,2dup,,twodup,docol) over;over;semis / head(205,matc,'h,match,docol) 1: dup zbran;4f-. tor;over;cat;over;cat;equal;fromr;swap zbran;2f-.;onem;rot;onep;rot;onep;rot;bran;3f-. 2: drop;drop;drop;zero;semis 3: bran;1b-. 4: drop;drop;drop;one semis / head(204,scan,,scan,docol) 1: dup;at zbran;3f-. tor;twodup;i;at;swap;match;zbran;2f-. drop;drop;fromr;at;one;semis 2: fromr;twop bran;1b-. 3: drop;drop;drop;zero semis / head(206,getenv,,getenv,docol) envp;scan;zbran;3f-. 1: dup;cat;zequ;over;cat;lit;61.;equal;or;zequ;zbran;2f-. onep;bran;1b-. 2: onep;one bran;4f-. 3: zero 4: semis / head(205,ftim,'e,ftime,dovar) 1 / head(205,stdi,'n,stdin,dovar) 0 / head(206,stdout,,stdout,dovar) 1 / head(206,stderr,,stderr,dovar) 2 / head(209,ignoreeo,'f,ieof,dovar) 0 / head(212,ignorecase,,icase,dovar) 1 / head(209,{{(message}},{{')}},mesg,docol) dup;plus errtab;plus;at;count;type semis / head(207,messag,'e,mess,docol) lit;36.;plus;mesg semis / head(206,perror,,perror,docol) here;count;type;space;errno;at;mesg semis / head(207,ferrta,'b,fertab,docon) aferrtab / head(206,errtab,,errtab,dovar) E0 ;E1 ;E2 ;E3 ;E4 ;E5 ;E6 ;E7 ;E8 ;E9 E10;E11;E12;E13;E14;E15;E16;E17;E18;E19 E20;E21;E22;E23;E24;E25;E26;E27;E28;E29 E30;E31;E32;E33;E34;E35 aferrtab: F0 ;F1 ;F2 ;F3 F4 ;F5 ;F6 ;F7 ;F8 ;F9 ;F10;F11;F12;F13 F14;F15;F16;F17;F18;F19;F20;F21;F22;F23 F24;F25;F26;F27;F28;F29;F30;F31;0 E0: string(Error 0) E1: string(Not owner) E2: string(No such file or directory) E3: string(No such process) E4: string(Interrupted system call) E5: string(I/O Error) E6: string(No such device or address) E7: string(Arg list too long) E8: string(Exec format error) E9: string(Bad file number) E10: string(No children) E11: string(No more processes) E12: string(Not enough core) E13: string(Permission denied) E14: string(Bad address) E15: string(Block device required) E16: string(Mount device busy) E17: string(File exists) E18: string(Cross device {{link}}) E19: string(No such device) E20: string(Not a directory) E21: string(Is a directory) E22: string(Invalid argument) E23: string(File table overflow) E24: string(Too many open files) E25: string(Not a typewriter) E26: string(Text file busy) E27: string(File too large) E28: string(No space left on device) E29: string(Illegal seek) E30: string(Read only file system) E31: string(Too many {{link}}s) E32: string(Broken pipe) E33: string(Math argument) E34: string(Result too large) E35: string(Unknown error) F0: string(Undefined) F1: string(Empty stack) F2: string(Dictionary full) F3: string(Bad address mode) F4: string(Isn't unique) F5=E35 F6: string(End of file) / 42. F7: string(Full stack) F8: string(Disk error!) F9=E35 F10=E35 F11=E35 F12=E35 F13=E35 F14=E35 F15=E35 F16=E35 F17: string(Compilation only) F18: string(Execution only) F19: string(Conditionals not paired) F20: string(Incomplete definition) F21: string(In protected dictionary) F22: string(Use only when loading) F23=E35 F24: string(Declare vocabulary) F25=E35 F26=E35 F27=E35 F28=E35 F29=E35 F30=E35 F31=E35 / head(206,sallot,,sallot) / allocate n words on stack mov (s)+,r0 asl r0 sub r0,s / Kludge stack limits down... mov rp,r1 mov s,rp mov r0,-(rp) sys 33.; E35; 0 add r0, rp / make room for as much again. mov r0,-(rp) sys 33.; E35; 0 mov r1,rp next / head(205,floa,'d,fload,docol) /: fload ( name -> ) zero;open;zbran;1f-. / 0 open if stdin;at;tor;tib;at;tor;in;at;tor/ stdin @ >R tib @ >R in @ >R keybuf / keybuf dup;at;tor;two;plus / dup @ >R 2 + dup;at;tor;two;plus / dup @ >R 2 + at;tor / @ >R stdin;store;zero;in;store / stdin ! 0 in ! lit;keylen;sallot / keylen sallot spat;keybuf;store / sp@ keybuf ! keybuf;two;plus;lit;4;erase / keybuf 2 + 4 erase ( empty key buffer ) lit;128.;sallot;spat;tib;store / 128 sallot sp@ tib ! 2: query;inter / begin query interpret feof;at;zbran;2b-. / feof @ until zero;feof;store;lit;-128.;sallot / 0 feof ! -128 sallot lit;-keylen;sallot / -keylen sallot stdin;at;close;drop / stdin @ close drop fromr;keybuf;lit;4;plus;store / R> keybuf 4 + ! fromr;keybuf;two;plus;store / R> keybuf 2 + ! fromr;keybuf;store / R> keybuf ! fromr;in;store;fromr;tib;store / R> in ! R> tib ! fromr;stdin;store / R> stdin ! bran;2f-. / else 1: perror / perror 2: semis / then ; / / FORTH disk I/O / head(204,word,,word,docol) / moved here because blk;at;zbran;1f-. / it accesses the disk blk;at;block;bran;2f-. 1: tib;at 2: in;at;plus swap;encl here;lit;42;blank in;pstor over;fsub;tor r;here;cstor plus;here;onep;fromr;cmove semis / / disk i/o - ( section common to all systems ) / head(204,+buf,,pbuf,docol) bbuf;lit;4;plus;plus dup;limit;at;equal;zbran;1f-. drop;first;at 1: dup;prev;at;fsub semis / head(206,update,,updat,docol) prev;at;at;lit;100000;or prev;at;store semis / head(215,empty-buffer,'s,mtbuf,docol) first;at;limit;at;over;fsub;erase semis / head(205,flus,'h,flush,docol) limit;at;first;at;xdo 1: i;at;zless;zbran;2f-. i;twop;i;at;lit;77777;and;zero;rw 2: bbuf;lit;4;plus xploo;1b-. mtbuf semis / head(206,buffer,,buffe,docol) use;at;dup;tor 1: pbuf;zbran;1b-. use;store;r;at;zless;zbran;1f-. r;twop;r;at;lit;77777;and;zero;rw 1: r;store;r;prev;store;fromr;twop semis / head(205,bloc,'k,block,docol) ofset;at;plus;tor prev;at;dup;at;lit;077777;and;r;fsub;zbran;3f-. 1: pbuf;zequ;zbran;2f-. drop;r;buffe;dup;r;one;rw;two;fsub 2: dup;at;lit;077777;and;r;fsub;zequ;zbran;1b-. dup;prev;store 3: fromr;drop twop semis / head(206,(line),,pline,docol) tor;cl;bbuf;ssmod;fromr;bscr;star;plus;block;plus;cl semis / head(205,.lin,'e,dline,docol) pline;dtrai;type semis / head(204,load,,load,docol) blk;at;tor in;at;tor zero;in;store bscr;star;blk;store inter fromr;in;store fromr;blk;store semis / head(303,--,'>,arrow,docol) qload zero;in;store bscr;blk;at;over;mod;fsub;blk;pstor semis / / utility section / head(204,list,,list,docol) decim dup;scr;store pdotq string({screen }) dot;cr lit;20;zero;xdo 2: i;three;dotr;space;i;scr;at;dline;cr xloop;2b-. cr semis / head(205,inde,'x,findex,docol) onep;swap;xdo 2: i;three;dotr;space;zero;i;dline;cr xloop;2b-. semis / head(213,disk-origi,'n,dorig,dovar) 1 / head(212,block-read,,bread,docol)/ addr block#... dorig;at;fsub / don't waste block 0 bbuf;ustar / lo hi scrf;at;lseek;zbran;1f-. / if can seek there bbuf;scrf;at;read;zbran;1f-. / read. bbuf;less;zbran;3f-. / if at EOF, lit;42.;errno;store;zero / error bran;2f-. / else 3: one / if succeeds, return 1 bran;2f-. / else 1: zero / return 0 2: semis / fi / head(213,block-writ,'e,bwrit,docol)/ addr block#... dorig;at;fsub / don't waste block 0 bbuf;ustar / lo hi scrf;at;lseek;zbran;1f-. / if can seek there bbuf;scrf;at;write;zbran;1f-. / read. drop;one / if succeeds, return 1 bran;2f-. / else 1: zero / return 0 2: semis / fi / head(203,r/,'w,rw,docol) setio;zequ;zbran;1f-. / setio 0= if perror;abort / perror abort 1: dup;one;equal;zbran;1f-. / then dup 1 = if drop;bread;zequ;zbran;2f-. / drop block-read 0= if perror;abort / perror abort 2: bran;3f-. / then else 1: zequ;zbran;4f-. / 0= if bwrit;zequ;zbran;5f-. / block-write 0= if perror;abort / perror abort 5: / then 4: / then 3: semis / then ; / head(204,scrf,,scrf,dovar) 0 / head(205,seti,'o,setio) mov $1,-(s) / assume success tst scrf+2 / if already open bne 1f / skip rest sys 5.;sname+2;2 / else try open bec 3f / and if it fails, then sys 8.;sname+2;0777 / try creat bec 3f / and if it fails, then mov r0,errno+2 / set error clr (s) / zap return br 1f / else one of them worked 3: mov r0,scrf+2 / so get the fd 1: next / and in any case return / head(205,snam,'e,sname,dovar) <screens> .byte 0 .even 0;0;0;0;0;0;0;0;0;0 / allow some extra space 0;0;0;0;0;0;0;0;0;0 / for the screen name / / the following two definitions are not pure code, so they were / moved here, near the end of the dictionary. / head(305,;cod,'e,semic,docol) / create new data type with code routine written in assembly qcsp comp pscod lbrac smudg semis / head(305,fort,'h,forth,dodoe) dovoc 120201 task-10 xxvoc: 0 / head(204,task,,task,docol) semis / / stacks and buffers / .bss xdp: .=.+8096. / initially 8K allocated xbreak: -- Peter (Made in Australia) da Silva UUCP: ...!shell!neuro1!{hyd-ptd,baylor,datafac}!peter MCI: PDASILVA; CIS: 70216,1076