|
DataMuseum.dkPresents historical artifacts from the history of: Jet Computer Jet80 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Jet Computer Jet80 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 28672 (0x7000) Types: TextFile Names: »KERNEL.SL5«
└─⟦c50ca4728⟧ Bits:30003533 StackWorks FORTH version 1.2 for Z-80 └─ ⟦this⟧ »KERNEL.SL5«
( Copyright 1980 The Stackworks. All rights reserved ) ( Z80 VERSION 1.2 - CP/M ) ( 3/25/80 ) CODE $$PUSH HL PUSH EXX (HL) C LD HL INC (HL) B LD HL INC BC PUSH EXX RET EDOC CODE $CONSTANT HL POP (HL) E LD HL INC (HL) D LD DE PUSH $NEXT JP EDOC CODE $BARRAY HL POP (HL) E LD HL INC (HL) D LD HL POP DE HL ADD $PUSH JP EDOC CODE $ARRAY HL POP (HL) E LD HL INC (HL) D LD HL POP HL HL ADD DE HL ADD $PUSH JP EDOC ( ==================================================================== ) ( CONDITIONAL COMPILATION CONSTANTS ) 1 XCONSTANT ?FILESYS ( COMPILE FILE SYSTEM SECTION ) 0 XCONSTANT ?OWNIO ( COMPILE USER I/O SECTION ) 1 XCONSTANT ?CRT ( COMPILE CRT I/O WORDS ) 1 XCONSTANT ?INTERP ( COMPILE INTERPRETER SECTION ) 1 XCONSTANT ?COMPILE ( COMPILE THE COMPILER SECTION ) ( NOTES: Æ1Å CRT SECTION NEEDS OWNIO OR FILESYS ) ( Æ2Å INTERPRETER NEEDS CRT SECTION ) ( Æ3Å COMPILER NEEDS INTERPRETER TO RUN. ) ( Æ4Å DO NOT COMPILE BOTH OWNIO AND FILE SYSTEM. ) ( ==================================================================== ) ( VARIABLES & CONSTANTS ) 0 VARIABLE DP 0 VARIABLE CURRENT 0 VARIABLE CONTEXT 0 VARIABLE CVOC 6580 VARIABLE SYMTP 0 VARIABLE SYMPTR 0 VARIABLE RESTARTAD 0 VARIABLE GOQIAD 0 VARIABLE D/0AD 0 VARIABLE STATE 10 VARIABLE BASE 1 VARIABLE UPPER 20 VARIABLE DELIMITER 07F VARIABLE INFOF 0 VARIABLE FLAGS 0 VARIABLE DEPTH 100 CONSTANT SSIZE 100 CONSTANT RSIZE ( STACKS & BUFFERS ) SSIZE 10 + BARRAY STACK RSIZE 10 + BARRAY RSTACK CODE LIT EXX (HL) C LD HL INC (HL) B LD HL INC BC PUSH $NEXTHL JP EDOC CODE $SET HL POP (HL) E LD HL INC (HL) D LD HL INC (HL) A LD A (DE) LD HL INC DE INC (HL) A LD A (DE) LD $NEXT JP EDOC CODE $FMAKE $NEXT JP EDOC CODE $: EXX HL DE EX HL DEC D (HL) LD HL DEC E (HL) LD HL DE EX HL POP $NEXTHL JP EDOC CODE $; EXX HL DE EX (HL) E LD HL INC (HL) D LD HL INC HL DE EX $NEXTHL JP EDOC ( ARITHMETIC OPERATIONS ) CODE + BC POP HL POP BC HL ADD $PUSH JP EDOC CODE - BC POP HL POP A AND BC HL SBC $PUSH JP EDOC CODE ø BC POP HL POP C A LD L OR A L LD B A LD H OR A H LD $PUSH JP EDOC CODE & BC POP HL POP C A LD L AND A L LD B A LD H AND A H LD $PUSH JP EDOC CODE Xø BC POP HL POP C A LD L XOR A L LD B A LD H XOR A H LD $PUSH JP EDOC CODE 1+ HL POP HL INC $PUSH JP EDOC CODE 1- HL POP HL DEC $PUSH JP EDOC CODE MINUS DE POP 0 HL LD A AND DE HL SBC $PUSH JP EDOC ( MEMORY OPERATIONS ) CODE ! HL POP BC POP C (HL) LD HL INC B (HL) LD $NEXT JP EDOC CODE @ HL POP (HL) E LD HL INC (HL) D LD HL DE EX $PUSH JP EDOC CODE B@ HL POP (HL) L LD 0 H LD $PUSH JP EDOC CODE B! HL POP BC POP C (HL) LD $NEXT JP EDOC CODE +! HL POP BC POP (HL) E LD HL INC (HL) D LD HL DE EX BC HL ADD HL DE EX D (HL) LD HL DEC E (HL) LD $NEXT JP EDOC CODE 1+! HL POP (HL) C LD HL INC (HL) B LD BC INC B (HL) LD HL DEC C (HL) LD $NEXT JP EDOC CODE 1-! HL POP (HL) C LD HL INC (HL) B LD BC DEC B (HL) LD HL DEC C (HL) LD $NEXT JP EDOC ( STACK MANIPULATIONS ) CODE DROP HL POP $NEXT JP EDOC CODE DUP HL POP HL PUSH $PUSH JP EDOC CODE OVER BC POP HL POP HL PUSH BC PUSH $PUSH JP EDOC CODE R> EXX HL DE EX (HL) C LD HL INC (HL) B LD HL INC BC PUSH HL DE EX $NEXTHL JP EDOC CODE >R EXX BC POP HL DE EX HL DEC B (HL) LD HL DEC C (HL) LD HL DE EX $NEXTHL JP EDOC CODE SWAP HL POP HL (SP) EX $PUSH JP EDOC CODE ROT BC POP DE POP HL POP DE PUSH BC PUSH $PUSH JP EDOC CODE 2DROP HL POP BC POP $NEXT JP EDOC CODE 2DUP HL POP BC POP BC PUSH HL PUSH BC PUSH $PUSH JP EDOC CODE 2SWAP BC POP DE POP HL POP IX POP DE PUSH BC PUSH IX PUSH $PUSH JP EDOC CODE ROLL BC POP C A LD 0 HL LD SP HL ADD HL INC DE POP A DEC NZ IF, BEGIN, HL INC (HL) C LD E (HL) LD HL INC (HL) B LD D (HL) LD B D LD C E LD A DEC Z END, ENDIF, DE PUSH $NEXT JP EDOC CODE -ROLL HL POP 0 H LD L A LD HL HL ADD SP HL ADD HL DEC DE POP A DEC NZ IF, BEGIN, (HL) B LD D (HL) LD HL DEC (HL) C LD E (HL) LD HL DEC B D LD C E LD A DEC Z END, ENDIF, DE PUSH $NEXT JP EDOC CODE SP@ 0 HL LD SP HL ADD $PUSH JP EDOC CODE SP! HL POP HL SP LD $NEXT JP EDOC CODE RP@ EXX DE PUSH $NEXTHL JP EDOC CODE RP! EXX DE POP $NEXTHL JP EDOC CODE PICK HL POP HL DEC HL HL ADD SP HL ADD (HL) C LD HL INC (HL) B LD BC PUSH $NEXT JP EDOC ( MISC. WORDS ) : HERE DP @ ; : DP+! DP +! ; : COUNT DUP 1+ SWAP B@ ; CODE GO HL POP (HL) JP EDOC : GO-OPSYS 0 GO ; CODE BSWAP HL POP L A LD H L LD A H LD $PUSH JP CODE ->L BC POP HL POP C A LD A OR NZ IF, BEGIN, H SRL L RR C DEC Z END, ENDIF, $PUSH JP EDOC CODE <-L BC POP HL POP C A LD A OR NZ IF, BEGIN, L SLA H RL C DEC Z END, ENDIF, $PUSH JP EDOC CODE $BMOVE BC POP DE POP HL POP LDIR $NEXT JP EDOC CODE $RMOVE BC POP DE POP HL POP LDDR $NEXT JP EDOC ( HIGH LEVEL CONDITION SETTINGS ) CODE 0= BC POP C A LD B OR 0 HL LD Z IF, HL INC ENDIF, $PUSH JP EDOC CODE 0< BC POP B 7 BIT 0 HL LD NZ IF, HL INC ENDIF, $PUSH JP EDOC CODE 0> BC POP B 7 BIT 0 HL LD Z IF, C A LD B OR NZ IF, HL INC ENDIF, ENDIF, $PUSH JP EDOC : NOT 0= ; : = - 0= ; : <> - 0= 0= ; : < - 0< ; : > - 0> ; : <= - 0> 0= ; : >= - 0< 0= ; CODE U< BC POP HL POP A AND BC HL SBC 0 HL LD C IF, HL INC ENDIF, $PUSH JP EDOC : U> SWAP U< ; : U>= U< 0= ; : U<= U> 0= ; ( CONDITIONAL BASICS ) CODE $IF BC POP C A LD B OR EXX Z IF, (HL) C LD HL INC (HL) H LD C L LD $NEXTHL JP ENDIF, HL INC HL INC $NEXTHL JP EDOC CODE $ELSE EXX (HL) C LD HL INC (HL) H LD C L LD $NEXTHL JP EDOC ( DO LOOPS - $DO, $+LOOP, EXIT, I, J, K ) CODE $DO EXX BC POP HL (SP) EX HL DE EX HL DEC D (HL) LD HL DEC E (HL) LD HL DEC B (HL) LD HL DEC C (HL) LD DE POP HL DE EX $NEXTHL JP EDOC CODE $+LOOP EXX BC POP HL PUSH DE PUSH 0 HL LD SP HL ADD HL DE EX HL SP LD HL POP BC HL ADD BC POP BC PUSH HL PUSH A AND BC HL SBC HL DE EX HL SP LD DE POP HL POP C IF, (HL) A LD HL INC (HL) H LD A L LD $NEXTHL JP ENDIF, DE INC DE INC DE INC DE INC HL INC HL INC $NEXTHL JP EDOC CODE EXIT EXX HL DE EX HL INC HL INC (HL) C LD HL INC (HL) B LD HL DEC HL DEC B (HL) LD HL DEC C (HL) LD HL DE EX $NEXTHL JP EDOC CODE I EXX 0 BC LD HERE HL DE EX HL PUSH BC HL ADD (HL) C LD HL INC (HL) B LD HL POP BC PUSH HL DE EX $NEXTHL JP EDOC CODE J EXX 4 BC LD DUP JP EDOC CODE K EXX 8 BC LD JP EDOC ( MORE ARITHMETIC OPERATIONS ) : ABS DUP 0< IF MINUS ENDIF ; : COM FFFF Xø ; : -- SWAP - ; : MIN 2DUP > IF SWAP ENDIF DROP ; : MAX 2DUP < IF SWAP ENDIF DROP ; : @X @ BSWAP ; CODE * 0 HL LD BC POP DE POP BEGIN, B SRL C RR C IF, DE HL ADD ENDIF, HL DE EX HL HL ADD HL DE EX C A LD B OR Z END, $PUSH JP EDOC CODE U/MOD HL POP DE POP 0 BC LD BC PUSH L A LD H OR Z IF, D/0AD ^ HL LD (HL) JP ENDIF, SCF BEGIN, C RL B RL HL HL ADD C END, H RR L RR BEGIN, E A LD D OR NZ IF, HL PUSH SCF DE HL SBC HL POP C IF, HL (SP) EX BC HL ADD HL (SP) EX HL DE EX A AND DE HL SBC HL DE EX ENDIF, H SRL L RR B SRL C RR ELSE, SCF ENDIF, C END, HL POP DE PUSH $PUSH JP EDOC : /MOD OVER 0< OVER 0< OVER Xø 2SWAP SWAP ABS SWAP ABS U/MOD ROT IF MINUS ENDIF ROT IF SWAP MINUS SWAP ENDIF ; : / /MOD SWAP DROP ; : MOD /MOD DROP ; ( ZIN, ZOUT - Z80 VERSION ONLY ) CODE ZIN BC POP (C) L IN 0 H LD $PUSH JP EDOC CODE ZOUT BC POP HL POP L (C) OUT $NEXT JP EDOC ( BASIC CASE WORDS ) : $CASE R> DUP 2 + SWAP @ >R >R ; : $=: OVER = IF DROP R> 2 + >R ELSE R> @ >R ENDIF ; : $;; R> DROP ; : NOCASE DUP ; ( $;CODE ;: ) : $:;CODE R> CURRENT @ @ SYMTP @ + 3 + @ 1+ ! ; : $VOCAB @ DUP CVOC ! @ CONTEXT ! ; BASEVOCAB FORTH FORTH DEFINITIONS ( BMOVE, RMOVE, FILL ) : BMOVE DUP IF $BMOVE ELSE DROP 2DROP ENDIF ; : RMOVE DUP IF SWAP OVER 1- + SWAP ROT OVER 1- + ROT ROT $RMOVE ELSE DROP 2DROP ENDIF ; : FILL 3 PICK IF OVER B! DUP 1+ ROT 1- BMOVE ELSE 2DROP DROP ENDIF ; : BLANK 20 FILL ; ( ==================================================================== ) ( FILE SYSTEM SECTION ) ( ==================================================================== ) ?FILESYS IFTRUE 0 VARIABLE OP-VER# ( CONTAINS CP/M VERSION NUMBER, SET BY ININIT ) ( CHARACTER LEVEL INTERFACES TO CP/M ) CODE CALLCPM BC POP DE POP 05 CALL B H LD A L LD $PUSH JP EDOC : CIN 1 DUP CALLCPM DUP 3 = IF GO-OPSYS ( CTRL-C ) ELSE DUP 12 = IF RESTARTAD @ GO ( CTRL-R ) ELSE DUP 13 = IF DROP RECURSE ( CTRL-S ) ENDIF ENDIF ENDIF ; : CIS 0B DUP CALLCPM IF CIN DROP ENDIF ; : COUT CIS 2 CALLCPM DROP ; ( CTYPE, $C" ) : CTYPE DUP IF 0 DO DUP B@ COUT 1+ LOOP DROP ELSE 2DROP ENDIF ; : $C" R> DUP B@ SWAP 1+ SWAP 2DUP + >R CTYPE ; ( FILE INTERFACES ) 80 CONSTANT BUFSIZE 1A CONSTANT EOFCHR : FFLAGS @ ; : BUFP @ 1+ ; : BUFLEN @ 3 + ; : SCHAN# @ 5 + ; : BUFAD 2 + @ ; : FCB 4 + @ ; : FFLAGS@& OVER FFLAGS B@ & ; : FFLAGSø! OVER FFLAGS B@ ø OVER FFLAGS B! ; : SERIAL 80 FFLAGS@& ; : SHOW-FNAME SERIAL IF SCHAN# @ IF C" #LST" ELSE C" #CRT" ENDIF ELSE FCB DUP 1+ 8 CTYPE C" ." 9 + 3 CTYPE ENDIF ; : FERRS 0D COUT 0A COUT CASE 2 =: C" READ PAST EOF." ;; 3 =: C" FILE NOT OPENED FOR READING." ;; 4 =: C" FILE NOT OPENED FOR WRITING." ;; 5 =: C" FILE DOESN'T EXIST." ;; 6 =: C" DISK WRITE ERROR." ;; 7 =: C" FILE CAN'T BE CREATED." ;; CASEND C" " SHOW-FNAME 0D COUT 0A COUT RESTARTAD @ GO ; : EOF FFLAGS B@ 1 & ; : RESET 0FE FFLAGS@& OVER FFLAGS B! 0 OVER 2DUP BUFLEN ! BUFP ! FCB 0 OVER 0C + B! 4 SWAP 20 + 0 FILL ; : FRES DUP RESET DUP FFLAGS DUP B@ 80 & SWAP B! ; : BUFADSET 1A CALLCPM DROP ; : CLOSE SERIAL NOT IF DUP FCB 10 CALLCPM DROP ENDIF FRES DROP ; : DELETE SERIAL NOT IF DUP FCB 13 CALLCPM DROP ENDIF FRES DROP ; : OPENR FRES SERIAL NOT IF DUP FCB 0F CALLCPM 0FF = IF 5 FERRS ( NON EXISTANT FILE ) ENDIF ENDIF 2 FFLAGSø! DROP ; : OPENW FRES SERIAL NOT IF DUP DELETE DUP FCB 16 CALLCPM 0FF = IF 7 FERRS ( FILE CAN'T BE CREATED ) ENDIF ENDIF 4 FFLAGSø! DROP ; : RENAME SWAP SERIAL ROT SERIAL ROT ø IF 2DROP ELSE FCB 1+ OVER FCB 11 + 0B $BMOVE FCB 17 CALLCPM DROP ENDIF ; : READ 2 FFLAGS@& IF 1 FFLAGS@& IF 2 FERRS ( READ PAST EOF ) ELSE SERIAL IF 0 OVER BUFAD " > COUT BEGIN CIN DUP 0D = IF DROP 1 ELSE DUP 1B = IF 2DROP DROP 0 OVER BUFAD ( ESCAPE ) C" *ESC*" 0D COUT 0A COUT ELSE DUP 08 = IF DROP OVER IF ( CTRL-H ) 1- SWAP 1- SWAP OP-VER# @ 20 < IF 08 COUT ENDIF ENDIF ELSE OVER B! 1+ SWAP 1+ SWAP ENDIF ENDIF 0 ENDIF 3 PICK BUFSIZE 2 - U>= ø END 0D OVER B! 1+ 0A SWAP B! 2 + OVER BUFLEN ! 0A COUT ELSE DUP BUFAD BUFADSET DUP FCB 14 CALLCPM 80 BUFADSET IF 1 FFLAGSø! 0 ( EOF ) ELSE BUFSIZE ENDIF OVER BUFLEN ! ENDIF 0 SWAP BUFP ! ENDIF ELSE 3 FERRS ( NOT OPENED FOR READING ) ENDIF ; : WRITE 4 FFLAGS@& IF SERIAL IF DUP SCHAN# @ IF 5 ELSE 2 ENDIF OVER BUFAD ROT BUFP DUP @ 0 ROT ! 0 DO 2DUP B@ 7F & SWAP CALLCPM DROP 1+ LOOP 2DROP ELSE DUP BUFAD BUFADSET DUP FCB 15 CALLCPM 80 BUFADSET IF 6 FERRS ( WRITE ERRORS ) ELSE 0 SWAP BUFP ! ENDIF ENDIF ELSE 4 FERRS ( NOT OPENED FOR WRITING ) ENDIF ; : FLUSH DUP BUFP @ IF WRITE ELSE DROP ENDIF ; : RBYTE CIS 2 FFLAGS@& IF DUP BUFP @ OVER BUFLEN @ U>= IF DUP READ DUP EOF IF ( BUFFER EMPTY ) DROP EOFCHR ELSE RECURSE ENDIF ELSE DUP BUFP DUP @ SWAP 1+! SWAP BUFAD + B@ ENDIF ELSE 3 FERRS ( NOT OPENED FOR READING ) ENDIF ; : RCH DUP EOF IF 2 FERRS ( READ PAST EOF ) ELSE DUP RBYTE 7F & SWAP OVER EOFCHR = IF 1 FFLAGSø! ( EOF ) ENDIF DROP ENDIF ; : WBYTE CIS 4 FFLAGS@& IF SERIAL IF SCHAN# @ IF 5 ( PRINTER ) ELSE 2 ENDIF CALLCPM DROP ( DO SERIAL OUTPUT DIRECTLY ) ELSE SWAP OVER DUP BUFP @ SWAP BUFAD + B! DUP BUFP DUP 1+! @ BUFSIZE = IF WRITE ( BUFFER FULL ) ELSE DROP ENDIF ENDIF ELSE 4 FERRS ( NOT OPENED FOR WRITING ) ENDIF ; : WCH SWAP 7F & SWAP WBYTE ; FALLOC INFILE FALLOC OUTFILE : GCH INFILE RCH ; : TCH OUTFILE WCH ; 0 VARIABLE ECHFIB^ : UGCH GCH DUP 5F > OVER 7B < & UPPER @ & IF 20 - ENDIF INFILE SERIAL NOT INFOF @ 4 & NOT NOT & IF OVER TCH ENDIF DROP INFOF @ 80 & IF DUP ECHFIB^ @ WCH ( echo onto echfib if bit 7 set ) ENDIF DUP 09 = IF DROP 20 ENDIF ; : ININIT 80 INFILE FFLAGS B! 0 INFILE SCHAN# ! INFILE OPENR 0 0C CALLCPM OP-VER# ! ; : OUTINIT 80 OUTFILE FFLAGS B! 0 OUTFILE SCHAN# ! OUTFILE OPENW ; IFEND ( ==================================================================== ) ( END FILE SYSTEM SECTION ) ( ==================================================================== ) ( ==================================================================== ) ( OWNIO SECTION ) ( ==================================================================== ) ?OWNIO IFTRUE 80 BARRAY TBUFF 0 VARIABLE TBUFP 0 VARIABLE BUFSIZE : COUT BEGIN 0ED ZIN 1 & END 0EC ZOUT ; : CIN BEGIN 0ED ZIN 2 & END 0EC ZIN 7F & DUP COUT ; : CIS ; ( CTYPE, $C" ) : CTYPE DUP IF 0 DO DUP B@ COUT 1+ LOOP DROP ELSE 2DROP ENDIF ; : $C" R> DUP B@ SWAP 1+ SWAP 2DUP + >R CTYPE ; : TCH COUT ; : TGET " > COUT 0 TBUFP ! BEGIN CIN DUP TBUFP @ TBUFF B! CASE 0D =: TBUFP 1+! 0A COUT 1 ;; ( CR ) 1B =: C" *ESC*" 0D COUT 0A COUT 0 TBUFP ! 0 ;; ( ESC ) 08 =: TBUFP @ IF ( BS ) TBUFP 1-! ENDIF 0 ;; NOCASE =: TBUFP 1+! 0 ;; CASEND END TBUFP @ BUFSIZE ! 0 TBUFP ! ; : GCH TBUFP @ BUFSIZE @ >= IF TGET RECURSE ELSE TBUFP @ TBUFF B@ TBUFP 1+! ENDIF ; : UGCH GCH ; : OUTINIT ; : ININIT 0 TBUFP ! 0 BUFSIZE ! ; IFEND ( ==================================================================== ) ( END OWNIO SECTION ) ( ==================================================================== ) ( ==================================================================== ) ( ==================================================================== ) ?FILESYS NOT ?OWNIO NOT & IFTRUE : ININIT ; : OUTINIT ; IFEND ( ==================================================================== ) ( ==================================================================== ) ( RESTART ) : $RESTART 0 STATE ! 0 FLAGS ! ININIT OUTINIT GOQIAD @ GO ; CODE RESTART SSIZE STACK SP LD RSIZE RSTACK DE LD EXX 'B $RESTART JP EDOC 'B RESTART RESTARTAD T! ( ==================================================================== ) ( CRT I/O SECTION ) ( ==================================================================== ) ?CRT IFTRUE ( TYPE, $T" ) : TYPE DUP IF 0 DO DUP B@ TCH 1+ LOOP DROP ELSE 2DROP ENDIF ; : $T" R> DUP B@ SWAP 1+ SWAP 2DUP + >R TYPE ; ( CRIGHT - COPYRIGHT NOTICE ) : CRIGHT T" (c) Copyright 1980 The Stackworks " ; ( ABORTS ) : ABORT T" ABORT " RESTART ; : PNAME HERE 1+ HERE B@ TYPE ; : UNDEFINED 0D TCH 0A TCH PNAME T" ? " RESTART ; : D/0 T" D/0 " ABORT ; 'B D/0 D/0AD T! ( STACK CHECK ) : CHECK SP@ 100 STACK U> IF T" STACK UNDERFLOW" ABORT ELSE RP@ 100 RSTACK U> IF T" RETURN STACK UNDERFLOW" ABORT ENDIF ENDIF ; ( OUTPUT WORDS ) : SPACE 20 TCH ; : SPACES DUP IF DUP 0 DO SPACE LOOP ENDIF DROP ; : CR 0D TCH 0A TCH ; : NASCII DUP 9 > IF 7 + ENDIF 30 + ; : . >R CHECK R> DUP 0< IF MINUS T" -" ENDIF 0 BEGIN 1+ SWAP BASE @ U/MOD ROT OVER 0= END SWAP DO NASCII TCH LOOP SPACE ; : ? @ . ; : .HEX >R >R CHECK R> R> DUP 0 DO SWAP 10 U/MOD ROT LOOP SWAP DROP 0 DO NASCII TCH LOOP SPACE ; : X. 4 .HEX ; : B. 2 .HEX ; ( ==================================================================== ) OTHERWISE : D/0 RESTART ; 'B D/0 D/0AD T! IFEND ( ==================================================================== ) ( END OF CRT I/O SECTION ) ( ==================================================================== ) ( ==================================================================== ) ( INTERPRETER SECTION ) ( ==================================================================== ) ?INTERP IFTRUE ( BASE CONVERSION WORDS ) : DECIMAL 0A BASE ! ; : HEX 10 BASE ! ; : OCTAL 8 BASE ! ; ( , B, ) : , HERE ! 2 DP+! SYMPTR @ HERE U<= IF T" D>S " ABORT ENDIF ; : B, HERE B! 1 DP+! SYMPTR @ HERE U<= IF T" D>S " ABORT ENDIF ; ( EXECUTE, LITERAL, LINK ) : EXECUTE DUP 3 + @ SWAP B@ 80 & STATE @ NOT ø IF GO ELSE , ENDIF ; : LITERAL STATE @ IF 'B LIT , , ENDIF ; : LINK SYMPTR @ HERE B@ 1+ - HERE OVER HERE B@ 1+ $BMOVE 2 - SWAP OVER ! 2 - CONTEXT @ OVER ! 1- 0 OVER B! DUP SYMPTR ! SYMTP @ - CURRENT @ ! ; ( WORD - PARSE OUT A WORD FROM THE INPUT STREAM ) : DELIM= DUP DELIMITER @ = OVER 0A = ø OVER 0D = ø ; : WORD HERE 1+ DUP BEGIN DROP UGCH DELIM= NOT END BEGIN OVER B! 1+ UGCH DELIM= END DROP HERE - 1- HERE B! 20 DELIMITER ! ; ( FIND ) CODE S= 5 DE LD DE HL ADD (BC) A LD A E LD E INC BEGIN, (BC) A LD (HL) CP NZ RET HL INC BC INC E DEC Z END, RET EDOC CODE FIND1 BC POP HL POP BEGIN, DE POP DE PUSH DE HL ADD HL PUSH BC PUSH 'B S= CALL BC POP HL POP Z IF, ( FOUND ) HL (SP) EX 1 HL LD $PUSH JP ENDIF, HL INC (HL) E LD HL INC (HL) D LD D A LD E OR Z IF, ( END OF VOCAB ) HL INC (HL) E LD HL INC (HL) D LD HL DE EX H A LD L OR DE POP $PUSH Z JP ( END OF DICT. ) DE PUSH (HL) E LD HL INC (HL) D LD ENDIF, HL DE EX REPEAT, EDOC : FIND SYMTP @ CONTEXT @ HERE FIND1 ; : NUMBER HERE B@ HERE 1+ DUP B@ 2D = IF 1+ SWAP 1- SWAP -1 ELSE 1 ENDIF 0 2SWAP SWAP 0 SWAP 0 DO DROP DUP B@ DUP 39 > IF DUP 40 > IF 7 - ELSE DROP 80 ENDIF ENDIF 30 - DUP BASE @ U< IF ROT BASE @ * + SWAP 1+ 1 ELSE 2DROP 2DROP 0 EXIT ENDIF LOOP DUP IF 2DROP * 1 ENDIF ; ( INTRLP - THE MAIN LOOP FOR THE OUTER INTERPETER ) : INTRLP BEGIN WORD FIND IF EXECUTE ELSE NUMBER IF LITERAL ELSE UNDEFINED ENDIF ENDIF 0 END ; 'B INTRLP GOQIAD T! : $'B WORD FIND IF 3 + @ ELSE UNDEFINED ENDIF ; : 'B $'B LITERAL ; IMP 'B : $'S R> DUP 2 + >R @ SYMTP @ + ; : 'S WORD FIND IF STATE @ IF 'B $'S , SYMTP @ - , ELSE LITERAL ENDIF ELSE UNDEFINED ENDIF ; : ' WORD FIND IF 3 + @ 3 + LITERAL ELSE UNDEFINED ENDIF ; IFEND ( ==================================================================== ) ( END OF INTERPRETER SECTION ) ( ==================================================================== ) ( ==================================================================== ) ( COMPILER SECTION ) ( ==================================================================== ) ?COMPILE IFTRUE ( C", T" ) : C" 22 DELIMITER ! STATE @ IF 'B $C" , WORD HERE B@ 1+ DP+! ELSE WORD HERE 1+ HERE B@ CTYPE ENDIF ; IMP C" : T" 22 DELIMITER ! STATE @ IF 'B $T" , WORD HERE B@ 1+ DP+! ELSE WORD PNAME ENDIF ; IMP T" : DC DEPTH @ IF CR CR T" UNBALANCED NESTING" ABORT ENDIF ; ( CUR@@CON!, $CODE, CONSTANT, VARIABLE, :, ;, ;: ) : CUR@@CON! CURRENT @ @ CONTEXT ! ; : $CODE CUR@@CON! WORD INFOF @ 1 & IF FIND IF DROP T" REDEF " PNAME 0D TCH 0A TCH ENDIF ENDIF HERE LINK ; : CONSTANT $CODE 0CD B, 'B $CONSTANT , , CUR@@CON! ; : VARIABLE HERE 5 + CONSTANT , ; : : 1 STATE ! $CODE 0CD B, 'B $: , 0 DEPTH ! ; : ; CUR@@CON! 0 STATE ! 'B $; , DC ; IMP ; : ;: 'B $:;CODE , 0CD B, 'B $: , DC ; IMP ;: ( CONDITIONAL BRANCHING ) : IF 'B $IF , HERE DUP 2 + , DEPTH 1+! ; : ELSE HERE 4 + SWAP ! 'B $ELSE , HERE DUP 2 + , ; : ENDIF HERE SWAP ! DEPTH 1-! ; IMP IF IMP ELSE IMP ENDIF : BEGIN HERE DEPTH 1+! ; : END 'B $IF , , DEPTH 1-! ; IMP BEGIN IMP END : DO 'B $DO , HERE DEPTH 1+! ; : +LOOP 'B $+LOOP , , DEPTH 1-! ; : LOOP 1 LITERAL +LOOP ; IMP DO IMP +LOOP IMP LOOP : COMPILE $'B , ; : IMP 'S DUP B@ 80 ø SWAP B! ; : IMMEDIATE 80 SYMPTR @ B! ; IMP 'S IMP ' IMP COMPILE : Æ 0 STATE ! ; IMP Æ : Å 1 STATE ! ; IMP Å : ( 29 DELIMITER ! WORD ; IMP ( ( DATA STRUCTURE CONSTRUCTIONS ) : ARRAY HERE 5 + CONSTANT DUP + DP+! ;: @ OVER + + ; : BARRAY HERE 5 + CONSTANT DP+! ;: @ + ; : SET CONSTANT , ;: DUP 2 + @ SWAP @ ! ; ( VOCABULARY WORDS ) : VLIST CONTEXT @ BEGIN SYMTP @ + DUP 3 + @ X. SPACE DUP B@ B. SPACE DUP 5 + DUP B@ DUP . SWAP 1+ SWAP TYPE CR 1+ @ DUP 0= END DROP ; : $FORGET DUP 3 + @ DP ! DUP 1+ @ CURRENT @ ! CUR@@CON! 5 + COUNT + SYMPTR ! ; : FORGET COMPILE 'S 'S $FORGET EXECUTE ; IMP FORGET : VOCABULARY SYMPTR @ 6 - DUP SYMPTR ! 6 OVER 0 FILL CURRENT @ OVER 3 + ! SYMTP @ - VARIABLE ;: @ DUP CVOC ! @ CONTEXT ! ; : DEFINITIONS CVOC @ CURRENT ! ; ( PROGRAM CONTROL CONSTRUCTIONS ) : WHILE COMPILE IF DEPTH 1-! ; : REPEAT 'B $ELSE , SWAP , HERE SWAP ! DEPTH 1-! ; IMP WHILE IMP REPEAT : RECURSE CURRENT @ @ SYMTP @ + 3 + @ , ; IMP RECURSE ( CASE ) : CASE 'B $CASE , HERE 0 , DEPTH 1+! ; : =: 'B $=: , HERE 0 , ; : ;; 'B $;; , HERE SWAP ! ; : CASEND 'B R> , 'B 2DROP , HERE SWAP ! DEPTH 1-! ; IMP CASE IMP =: IMP ;; IMP CASEND : " WORD HERE 1+ B@ LITERAL ; IMP " ( ASSEMBLER BASICS - CODE, ;CODE, EDOC, $PUSH, $NEXT ) VOCABULARY ASSEMBLER : CODE $CODE ASSEMBLER ; : ;CODE ' $:;CODE , 0 STATE ! ASSEMBLER ; IMP ;CODE ASSEMBLER DEFINITIONS : EDOC CUR@@CON! ; : $PUSH 'B $$PUSH ; : $NEXT $PUSH 1+ ; : $NEXTHL $NEXT 1+ ; FORTH DEFINITIONS IFEND ( ==================================================================== ) ( END OF COMPILER SECTION ) ( ==================================================================== ) ( ==================================================================== ) ( COMPILER/FILE SYSTEM SECTION ) ( ==================================================================== ) ?FILESYS ?COMPILE & IFTRUE ( MORE FILE RELETED WORDS ) : FALLOC HERE 9 + CONSTANT HERE 0B + , HERE 89 + , 0 B, 0 , 0 , 0 , A4 DP+! ;: ; ( NAMIT - FIB^ NAMIT FILENAME -- NAME THE FILE ASSOCIATED WITH FIB^ ) 0 VARIABLE WPTR 0 VARIABLE WLN : GCHR WLN @ IF WPTR 1+! WLN 1-! WPTR @ B@ 1 ELSE 0 ENDIF ; : $NAMIT DUP FCB 0C OVER BLANK 0 OVER B! 0 9 ROT GCHR DROP GCHR IF DUP " : = IF DROP 40 - OVER B! ( UNIT SPECIFIED ) ELSE ROT 1+ ROT OVER B! 1+ SWAP OVER B! SWAP 2 - SWAP ENDIF 1+ SWAP 1- SWAP BEGIN GCHR WHILE DUP " . = IF DROP 3 PICK 0= IF + SWAP 1+ 3 ROT ENDIF ELSE 3 PICK IF OVER B! 1+ SWAP 1- SWAP ELSE DROP ENDIF ENDIF REPEAT ELSE OVER 1+ B! ENDIF 2DROP DROP DUP FCB 1+ DUP B@ " # = IF 1+ B@ " L = OVER SCHAN# ! 80 ELSE DROP 0 ENDIF SWAP FFLAGS B! ; : NAMIT WORD HERE B@ WLN ! HERE WPTR ! $NAMIT ; : $FLOAD R> DUP B@ 2DUP + 1+ >R WLN ! WPTR ! INFILE $NAMIT INFILE OPENR INTRLP ; : FLOAD STATE @ IF 'B $FLOAD , WORD HERE B@ 1+ DP+! ELSE INFILE NAMIT INFILE OPENR INTRLP ENDIF ; IMP FLOAD : ÆEND-OF-FILEÅ CR INFILE CLOSE R> R> 2DROP ININIT ; IFEND ( ==================================================================== ) ( END OF COMPILER/FILE SYSTEM SECTION ) ( ==================================================================== ) ÆEND-OF-FILEÅ «eof»