Internes
Sourcecode
Der rekonstruierte Code des Z80 FORTH 83 der IG Forth. Vieles ist 1:1 aus Laxen/Perry F83 übernommen. Ich bin mir nicht sicher, welche Version zur Verfügung stand. Es scheinen teilweise Codeschnipsel aus der V1.0 (Sep83) zu stammen, vieles aber auch aus V2.10 (Apr84). Einige Primitive-Implementierungen scheinen auch FIG-Forth entlehnt.
Im Unterschied zu Laxen/Perry wird Register IY als Returnstack genutzt. Ein Z80-Prozessor ist damit Voraussetzung. Laxen/Perry arbeitet mit einem 8080-Prozessor. Mehrere Worte nutzen auch die Vorteile des Z80 aus und sind dadurch intern anders programmiert.
Die Register IY (SP) und BC (IP) dürfen in eigenen Maschinencodeworten nicht verändert werden.
Im Folgenden sind Primitive nicht aufgeführt. diese stehen komplett im Assemblerquellcode forth83.asm bzw. forth83.lst. @@adr bedeutet, dass hier die Adresse aus dem Maschinencodeteil genommen wird. Daher ist der folgende Forth-Code kein kompletter Code zum Meta-Compilieren, sondern eher zum Nachschlagen gedacht.
( Z80 FORTH 83 der IG Forth)
( based on Laxen/Perry CP/M-F83 V2.0)
( reconstructed VPohlers Jan 2020)
( complete assembler source see forth83.asm)
VOCABULARY FORTH
FORTH DEFINITIONS
VOCABULARY HIDDEN
\ Run Time Code for Defining Words
Exec-Code f. Colon-Definitionen @@DOCOL
CODE EXIT
HIDDEN DEFINITIONS
CODE UNNEST
Exec-Code f. DOES @@DODOE
Exec-Code f. Variablen @@DOVAR
FORTH DEFINITIONS
CODE UP
Exec-Code f. Konstanten @@DOCON
Exec-Code f. Uservariablen @@DOUSE
HIDDEN DEFINITIONS
CODE (LIT)
\ Run Time Code for Control Structures
CODE BRANCH
CODE ?BRANCH
CODE (LOOP)
CODE (+LOOP)
CODE (DO)
CODE (?DO)
\ Execution Control
FORTH DEFINITIONS
CODE >NEXT
CODE EXECUTE
Exec-Code f. Vektoren @@DOVEC
Exec-Code f. User-Vektoren @@DOUVEC
CODE NOOP
CODE PAUSE
CODE I
CODE J
HIDDEN DEFINITIONS
CODE (LEAVE)
CODE (?LEAVE)
\ 16 and 8 bit Memory Operations
FORTH DEFINITIONS
CODE @
CODE !
CODE C@
CODE C!
\ Block Move Memory Operations
CODE CMOVE
CODE CMOVE>
\ 16 bit Stack Operations
CODE SP@
CODE SP!
CODE RP@
CODE RP!
CODE DROP
CODE DUP
CODE SWAP
CODE OVER
CODE TUCK
CODE NIP
CODE ROT
CODE -ROT
CODE ?DUP
CODE >R
CODE R>
CODE R@
CODE PICK
CODE ROLL
\ 16 bit Logical Operations
CODE AND
CODE OR
CODE XOR
CODE NOT
0 CONSTANT FALSE
-1 CONSTANT TRUE
\ Logical Operations
CODE CSET
CODE CRESET
CODE CTOGGLE
CODE OFF
CODE ON
\ 16 bit Arithmetic Operations
CODE +
CODE -
CODE NEGATE
CODE ABS
CODE +!
0 CONSTANT 0
1 CONSTANT 1
2 CONSTANT 2
3 CONSTANT 3
CODE 2*
CODE 2/
CODE U2/
CODE 1+
CODE 2+
CODE 1-
CODE 2-
CODE UM*
CODE UM/MOD
\ 16 bit Comparison Operations
CODE 0=
CODE 0<
CODE 0>
CODE =
CODE U<
CODE <
CODE >
: ?NEGATE 0< IF NEGATE THEN ;
: MIN ( n1 n2 -- n3 ) OVER OVER > IF SWAP THEN DROP ;
: MAX ( n1 n2 -- n3 ) OVER OVER < IF SWAP THEN DROP ;
: BETWEEN >R OVER > SWAP R> > OR NOT ;
\ 32 bit Memory Operations
CODE 2@
CODE 2!
\ 32 bit Memory and Stack Operations
CODE 2DROP
CODE 2DUP
CODE 2SWAP
CODE 2OVER
: 2ROT 5 ROLL 5 ROLL ;
\ 32 bit Arithmetic Operations
CODE D+
CODE DNEGATE
CODE S>D
CODE DABS
CODE D2/
: D- DNEGATE D+ ;
: ?DNEGATE 0< IF DNEGATE THEN ;
\ 32 bit Comparison Operations
: D0= OR 0= ;
: D= D- D0= ;
: DU< ROT SWAP 2DUP U< IF 2DROP 2DROP TRUE
ELSE = IF U< ELSE 2DROP FALSE THEN THEN ;
: D< 2 PICK OVER = IF DU< ELSE NIP ROT DROP < THEN ;
: D> 2SWAP D< ;
: DMIN 2OVER 2OVER D> IF 2SWAP THEN 2DROP ;
: DMAX 2OVER 2OVER D< IF 2SWAP THEN 2DROP ;
\ Mixed Mode Arithmetic
: *D 2DUP XOR >R ABS SWAP ABS UM* R> ?DNEGATE ;
: M/MOD DUP >R 2DUP XOR >R >R DABS R@ ABS UM/MOD SWAP R> ?NEGATE SWAP R>
0< IF NEGATE OVER IF 1- R@ ROT - SWAP THEN THEN R> DROP ;
: MU/MOD >R 0 R@ UM/MOD R> SWAP >R UM/MOD R> ;
\ 16 bit multiply and divide
: * UM* DROP ;
: /MOD >R S>D R> M/MOD ;
: / /MOD NIP ;
: MOD /MOD DROP ;
: */MOD >R *D R> M/MOD ;
: */ */MOD NIP ;
\ Task Dependant USER Variables
USER VARIABLE TOS
USER VARIABLE ENTRY
USER VARIABLE LINK
USER VARIABLE SP0
USER VARIABLE RP0
USER VARIABLE DP
USER VARIABLE #OUT
USER VARIABLE #LINE
USER VARIABLE OFFSET
USER VARIABLE BASE
USER VARIABLE HLD
USER VARIABLE PRINTING
\ System Variables
USER DEFER EMIT ' (EMIT) IS EMIT
USER DEFER CR ' (CR) IS CR
VARIABLE FENCE
VARIABLE SCR
VARIABLE PRIOR
VARIABLE STATE
VARIABLE DPL
VARIABLE R#
VARIABLE LAST
VARIABLE CSP
VARIABLE CURRENT
8 CONSTANT #VOCS
VARIABLE CONTEXT HERE #VOCS 2* DUP ALLOT ERASE
VARIABLE 'TIB
VARIABLE WIDTH
VARIABLE WARNING
VARIABLE VOC-LINK
VARIABLE BLK
VARIABLE >IN
VARIABLE SPAN
VARIABLE #TIB
\ Strings
32 CONSTANT BL
8 CONSTANT BS
7 CONSTANT BELL
: HERE DP @ ;
: PAD HERE 80 + ;
CODE FILL
: ERASE 0 FILL ;
: BLANK BL FILL ;
: MOVE -ROT 2DUP U< IF ROT CMOVE> ELSE ROT CMOVE THEN ;
CODE COUNT
: TYPE 0 ?DO COUNT EMIT LOOP DROP ;
: SPACE BL EMIT ;
: SPACES 0 MAX 0 ?DO SPACE LOOP ;
: -TRAILING DUP 0 DO 2DUP + 1- C@ BL = NOT ?LEAVE 1- LOOP ;
CODE COMPARE
DEFER KEY ' (KEY) IS KEY
DEFER KEY? ' (KEY?) IS KEY?
\ Devices Terminal IO
VOCABULARY I/O
I/O DEFINITIONS
CODE OS
: (KEY?) 6 OS 0= NOT ;
: (KEY) BEGIN PAUSE 0 OS ?DUP UNTIL ;
: (CONSOLE) PAUSE 3 OS 1 #OUT +! ;
: (PRINT) PAUSE 9 OS 1 #OUT +! ;
: (EMIT) PRINTING @ IF DUP (PRINT) -1 #OUT +! THEN (CONSOLE) ;
HEX : CRLF 0D EMIT 0A EMIT #OUT OFF 1 #LINE +! ; DECIMAL
FORTH DEFINITIONS
DEFER EXPECT ' (EXPECT) IS EXPECT
HIDDEN DEFINITIONS
: DEL-IN DROP DUP IF 1- BS EMIT SPACE BS ELSE BELL THEN EMIT ;
: CR-IN DROP SPAN ! OVER BL EMIT ;
: CHAR >R R@ EMIT 2DUP + R> SWAP C! 1+ ;
: (EXPECT) DUP SPAN ! SWAP 0 BEGIN 2 PICK OVER -
WHILE KEY DUP 0D = IF CR-IN ELSE DUP 7F = OVER BS = OR
IF DEL-IN ELSE CHAR THEN THEN REPEAT 2DROP DROP ;
FORTH DEFINITIONS
: TIB 'TIB @ ;
: QUERY TIB 80 EXPECT SPAN @ #TIB ! BLK OFF >IN OFF ;
\ BLOCK I/O
512 CONSTANT B/BUF
0 CONSTANT FIRST ( patched on COLD. FIRST := @@init_top - B/BUF)
HIDDEN DEFINITIONS
VARIABLE UPD
VARIABLE BLK#
FORTH DEFINITIONS
DEFER READ-BLOCK ' READ IS READ-BLOCK
DEFER WRITE-BLOCK ' WRITE IS WRITE-BLOCK
: EMPTY-BUFFERS FIRST B/BUF ERASE UPD OFF BLK# ON ;
: SAVE-BUFFERS UPD @ IF FIRST BLK# @ WRITE-BLOCK UPD OFF THEN ;
: FLUSH SAVE-BUFFERS EMPTY-BUFFERS ;
HIDDEN DEFINITIONS
: ABSENT? DUP BLK# @ = NOT ;
FORTH DEFINITIONS
: UPDATE UPD ON ;
: BUFFER PAUSE OFFSET @ + ABSENT? IF SAVE-BUFFERS THEN BLK# ! FIRST ;
: BLOCK PAUSE OFFSET @ + ABSENT?
IF SAVE-BUFFERS FIRST OVER READ-BLOCK THEN BLK# ! FIRST ;
I/O DEFINITIONS
@@init_sod CONSTANT SOD
@@init_eod CONSTANT EOD
: MAX# EOD @ SOD @ - B/BUF / ;
: 'RAM 1- MAX# 1- OVER U< ABORT" out of Disk " B/BUF * SOD @ + ;
: READ 'RAM SWAP B/BUF CMOVE ;
: WRITE 'RAM B/BUF CMOVE ;
\ Number Input
FORTH DEFINITIONS
: ?MISSING IF HERE COUNT TYPE TRUE ABORT" ?" THEN ;
CODE DIGIT
: DOUBLE? DPL @ 1+ 0= NOT ;
: CONVERT BEGIN 1+ DUP >R C@ BASE @ DIGIT
WHILE SWAP BASE @ UM* DROP ROT BASE @ UM* D+
DOUBLE? IF 1 DPL +! THEN R> REPEAT DROP R> ;
HIDDEN DEFINITIONS
: (NUMBER?) 0 0 ROT DUP 1+ C@ ASCII - = DUP >R - -1 DPL !
BEGIN CONVERT DUP C@ ASCII , ASCII / BETWEEN WHILE 0 DPL ! REPEAT
-ROT R> IF DNEGATE THEN ROT C@ BL = ;
: INUMBER? FALSE OVER COUNT OVER + SWAP
DO I C@ BASE @ DIGIT NIP IF DROP TRUE LEAVE THEN LOOP
IF (NUMBER?) ELSE DROP 0 0 FALSE THEN ;
FORTH DEFINITIONS
DEFER NUMBER? ' INUMBER? IS NUMBER?
\ Number Output
: HOLD -1 HLD +! HLD @ C! ;
: SIGN 0< IF ASCII - HOLD THEN ;
: <# PAD HLD ! ;
: #> 2DROP HLD @ PAD OVER - ;
: # BASE @ MU/MOD ROT 9 OVER < IF 7 + THEN ASCII 0 + HOLD ;
: #S BEGIN # 2DUP OR 0= UNTIL ;
: HEX 16 BASE ! ;
: DECIMAL 10 BASE ! ;
: (U.) 0 <# #S #> ;
: U. (U.) TYPE SPACE ;
: U.R >R (U.) R> OVER - SPACES TYPE ;
: (.) DUP ABS 0 <# #S ROT SIGN #> ;
: . (.) TYPE SPACE ;
: .R >R (.) R> OVER - SPACES TYPE ;
: (D.) TUCK DABS <# #S ROT SIGN #> ;
: D. (D.) TYPE SPACE ;
: D.R >R (D.) R> OVER - SPACES TYPE ;
\ Parsing
CODE SKIP
CODE SCAN
: /STRING OVER MIN ROT OVER + -ROT - ;
: PLACE 2DUP >R >R 1+ SWAP MOVE R> R> C! ;
: SOURCE BLK @ ?DUP IF BLOCK B/BUF ELSE TIB #TIB @ THEN ;
: PARSE-WORD >R SOURCE >IN @ /STRING OVER SWAP R@ SKIP
OVER SWAP R> SCAN DROP 2DUP SWAP - >R ROT - 1+ >IN +! R> ;
: PARSE >R SOURCE >IN @ /STRING OVER SWAP R> SCAN DROP OVER - DUP 1+ >IN +! ;
: WORD PARSE-WORD HERE PLACE HERE BL OVER COUNT + C! ;
: >TYPE TUCK PAD SWAP CMOVE PAD SWAP TYPE ;
: .( ASCII ) PARSE >TYPE ; IMMEDIATE
: ( ASCII ) PARSE 2DROP ; IMMEDIATE
\ Dictionary
CODE HASH
HIDDEN DEFINITIONS
CODE (FIND)
FORTH DEFINITIONS
: FIND PRIOR OFF FALSE #VOCS 0 DO
DROP CONTEXT I 2* + @ DUP
IF DUP PRIOR @ OVER PRIOR ! =
IF DROP FALSE ELSE OVER SWAP HASH @ (FIND) DUP ?LEAVE THEN THEN LOOP ;
: DEFINED BL WORD FIND ;
\ Interpreter
DEFER STATUS ' CR IS STATUS
: ?STACK SP@ SP0 @ SWAP U< ABORT" stack underflow"
SP@ PAD U< ABORT" stack overflow" ;
HIDDEN DEFINITIONS
DEFER HANDLE ' (INTERPRET) IS HANDLE
: (INTERPRET) FIND IF EXECUTE ELSE NUMBER? NOT ?MISSING DOUBLE? NOT IF DROP THEN THEN ;
FORTH DEFINITIONS
: INTERPRET BEGIN ?STACK BL WORD DUP C@ WHILE HANDLE REPEAT DROP ;
\ Compiler
: ALLOT DP +! ;
: , HERE ! 2 ALLOT ;
: C, HERE C! 1 ALLOT ;
: COMPILE R> DUP 2+ >R @ , ;
HEX : IMMEDIATE 40 ( Precedence bit) LAST @ CSET ; DECIMAL
: LITERAL COMPILE (LIT) , ; IMMEDIATE
: DLITERAL SWAP [COMPILE] LITERAL [COMPILE] LITERAL ; IMMEDIATE
: ' DEFINED 0= ?MISSING ;
: ['] ' [COMPILE] LITERAL ; IMMEDIATE
: [COMPILE] ' , ; IMMEDIATE
HIDDEN DEFINITIONS
: (") R> COUNT 2DUP + >R ;
: (.") R> COUNT 2DUP + >R TYPE ;
: ," ASCII " PARSE TUCK HERE PLACE 1+ ALLOT ;
FORTH DEFINITIONS
: ." COMPILE (.") ," ; IMMEDIATE
: " COMPILE (") ," ; IMMEDIATE
\ Compiler
DEFER WHERE ' NOOP IS WHERE
DEFER ?ERROR ' (?ERROR) IS ?ERROR
HIDDEN DEFINITIONS
: (ABORT") R@ COUNT ROT ?ERROR R> COUNT + >R ;
FORTH DEFINITIONS
: ABORT" COMPILE (ABORT") ," ; IMMEDIATE
\ Defining Words
: !CSP SP@ CSP ! ;
: ?CSP SP@ CSP @ = NOT (ABORT") compilation uncorrect" ;
\ Dictionary
: N>LINK 2- ;
: L>NAME 2+ ;
: BODY> 2- ;
CODE NAME>
: LINK> L>NAME NAME> ;
: >BODY 2+ ;
CODE >NAME
: >LINK >NAME N>LINK ;
\ Defining Words
: HIDE LAST @ DUP N>LINK @ SWAP CURRENT @ HASH ! ;
: REVEAL LAST @ DUP N>LINK SWAP CURRENT @ HASH ! ;
HIDDEN DEFINITIONS
HEX : HEADER HERE 0 , HERE LAST ! DEFINED WARNING @ AND
IF HERE COUNT TYPE (.") is redefined " THEN
DROP HERE CURRENT @ HASH DUP @ HERE 2- ROT ! SWAP !
HERE DUP C@ WIDTH @ MIN 1+ ALLOT 80 SWAP CSET 80 HERE 1- CSET ; DECIMAL
FORTH DEFINITIONS
: CREATE HEADER @@dovar , ;
HIDDEN DEFINITIONS
: (COMPILE) FIND ?DUP IF 0> IF EXECUTE ELSE , THEN
ELSE NUMBER? NOT ?MISSING DOUBLE? IF DLITERAL ELSE DROP LITERAL THEN THEN ;
FORTH DEFINITIONS
: [ STATE OFF ['] (INTERPRET) (IS) HANDLE ; IMMEDIATE
: ] STATE ON ['] (COMPILE) (IS) HANDLE ;
VOCABULARY ASSEMBLER
HIDDEN DEFINITIONS
: (;USES) R> @ LAST @ NAME> ! ;
: (;CODE) R> LAST @ NAME> ! ;
FORTH DEFINITIONS
: ;USES ?CSP COMPILE (;USES) [COMPILE] [ REVEAL ASSEMBLER ; IMMEDIATE
: ;CODE ?CSP COMPILE (;CODE) [COMPILE] [ REVEAL ASSEMBLER ; IMMEDIATE
@@dodoe CONSTANT >DOES
HEX : DOES> COMPILE (;CODE) 0CD ( call) C, >DOES , ; IMMEDIATE DECIMAL
: !CSP CURRENT @ CONTEXT ! CREATE HIDE ] ;USES @@docol ,
: ; ?CSP COMPILE UNNEST REVEAL [COMPILE] [ ; IMMEDIATE
: RECURSE LAST @ NAME> , ; IMMEDIATE
: CONSTANT CREATE , ;USES @@docon ,
: VARIABLE CREATE 0 , ;USES @@dovar ,
: 2CONSTANT CREATE , , DOES> 2@ ; DROP
: 2VARIABLE 0 0 2CONSTANT DOES> ; DROP
: CRASH TRUE ABORT" undefined execution vector" ;
: DEFER CREATE ['] CRASH , ;USES @@dovec ,
\ Dictionary
4 CONSTANT #THREADS
HIDDEN DEFINITIONS
: TRIM #THREADS 0 DO 2DUP @ BEGIN 2DUP SWAP U< NOT WHILE @ REPEAT
NIP OVER ! 2+ LOOP 2DROP ;
: (FORGET) DUP FENCE @ U< ABORT" protected "
DUP VOC-LINK @ BEGIN 2DUP U< WHILE @ REPEAT
DUP VOC-LINK ! NIP
BEGIN DUP WHILE 2DUP #THREADS 2* - TRIM @ REPEAT DROP DP ! ;
FORTH DEFINITIONS
: FORGET BL WORD DUP CURRENT @ HASH @ (FIND) 0= ?MISSING >LINK (FORGET) ;
VARIABLE AVOC
: CODE CREATE HIDE HERE DUP 2- ! CONTEXT @ AVOC ! ASSEMBLER ;
: LABEL CREATE HIDE CONTEXT @ AVOC ! ASSEMBLER ;
ASSEMBLER DEFINITIONS
: END-CODE AVOC @ CONTEXT ! REVEAL ;
FORTH DEFINITIONS
: VOCABULARY CREATE #THREADS 0 DO 0 , LOOP
HERE VOC-LINK @ , VOC-LINK ! DOES> CONTEXT ! ;
: DEFINITIONS CONTEXT @ CURRENT ! ;
\ USER Defining Words
VARIABLE #USER
VOCABULARY USER
USER DEFINITIONS
: ALLOT DP +! ;
: CREATE CREATE #USER @ , ;USES @@douse ,
: VARIABLE CREATE 2 ALLOT ;
: DEFER VARIABLE ;USES @@douvec ,
\ Initialization
FORTH DEFINITIONS
: QUIT BLK OFF [COMPILE] [
BEGIN RP0 @ RP! STATUS QUERY INTERPRET
STATE @ NOT IF ." ok" THEN AGAIN ;
\ ReDefining Words
: >IS DUP @ DUP @@douse = SWAP DUP @@douvec = SWAP DROP OR
IF >BODY @ UP @ + ELSE >BODY THEN ;
: (IS) R@ @ >IS ! R> 2+ >R ;
: IS STATE @ IF COMPILE (IS) ELSE ' >IS ! THEN ; IMMEDIATE
\ Compiler
HIDDEN DEFINITIONS
: (?ERROR) IF >R >R SP0 @ SP! PRINTING OFF
BLK @ IF >IN @ BLK @ WHERE THEN
R> R> SPACE TYPE SPACE QUIT ELSE 2DROP THEN ;
FORTH DEFINITIONS
: ABORT SP0 @ SP! QUIT ;
: FORTH-83 ;
\ Initialization
: .VERSION CR ." Z80 FORTH 83 V1.3" CR ." im Auftrag der AIG Forth" CR
." Th. Beierlein (Juli 88)" CR ;
DEFER BOOT ' HELLO IS BOOT
: COLD BOOT ABORT ;
: WARM TRUE ABORT" Warmstart" ;
warm start
cold start
: BYE SAVE-BUFFERS 12 OS ;
\ Structures
: ?CONDITION = NOT ABORT" Conditionals wrong" ;
: >MARK HERE 0 , ;
: <MARK HERE ;
: >RESOLVE HERE SWAP ! ;
: <RESOLVE , ;
: ?>RESOLVE ?CONDITION >RESOLVE ;
: ?<RESOLVE ?CONDITION <RESOLVE ;
: LEAVE COMPILE (LEAVE) ; IMMEDIATE
: ?LEAVE COMPILE (?LEAVE) ; IMMEDIATE
: BEGIN <MARK TRUE ; IMMEDIATE
: THEN FALSE ?>RESOLVE ; IMMEDIATE
: DO COMPILE (DO) >MARK 1 ; IMMEDIATE
: ?DO COMPILE (?DO) >MARK 1 ; IMMEDIATE
: LOOP COMPILE (LOOP) OVER 2+ OVER 1 ?<RESOLVE 1 ?>RESOLVE ; IMMEDIATE
: +LOOP COMPILE (+LOOP) OVER 2+ OVER 1 ?<RESOLVE 1 ?>RESOLVE ; IMMEDIATE
: UNTIL COMPILE ?BRANCH TRUE ?<RESOLVE ; IMMEDIATE
: AGAIN COMPILE BRANCH TRUE ?<RESOLVE ; IMMEDIATE
: REPEAT 2SWAP [COMPILE] AGAIN [COMPILE] THEN ; IMMEDIATE
: IF COMPILE ?BRANCH >MARK FALSE ; IMMEDIATE
: ELSE COMPILE BRANCH >MARK FALSE SWAP FALSE ?>RESOLVE ; IMMEDIATE
: WHILE [COMPILE] IF ; IMMEDIATE
\ Resident Tools
: ? @ . ;
: ASCII BL WORD 1+ C@ STATE @ IF [COMPILE] LITERAL THEN ; IMMEDIATE
: CONTROL BL WORD 1+ C@ 31 AND STATE @ IF [COMPILE] LITERAL THEN ; IMMEDIATE
: DEPTH SP@ SP0 @ SWAP - 2/ ;
: .S CR DEPTH ?DUP IF 0 DO DEPTH I - 1- PICK 7 U.R SPACE LOOP
ELSE ." empty " THEN ;
: ?ENOUGH DEPTH 1- > (ABORT") not enough parameters" ;
\ Output Formatting
VARIABLE RMARGIN
( Z9001) 36 RMARGIN !
: ?LINE #OUT @ + RMARGIN @ > IF CR THEN ;
HEX : .ID DUP 1+ DUP C@ ROT C@ 1F AND 0
?DO DUP 7F AND EMIT 80 AND IF 0DFh ( ASCII _ 80 OR) ELSE 1+ DUP C@ THEN
LOOP 2DROP SPACE ; DECIMAL
\ Display the WORDS in the Context Vocabulary
: LARGEST OVER 0 SWAP ROT 0
DO 2DUP @ U< IF -ROT 2DROP DUP @ OVER THEN 2+ LOOP DROP ;
: WORDS CR CONTEXT @ HERE #THREADS 2* CMOVE
BEGIN HERE #THREADS LARGEST DUP
WHILE DUP L>NAME DUP C@ 31 AND ?LINE .ID SPACE SPACE @ SWAP !
KEY? IF EXIT THEN REPEAT 2DROP ;
\ Commenting and Loading Words
32 CONSTANT C/L
16 CONSTANT L/SCR
: --> >IN OFF 1 BLK +! ; IMMEDIATE
: LOAD BLK @ >R >IN @ >R >IN OFF BLK ! INTERPRET R> >IN ! R> BLK ! ;
: THRU 2 ?ENOUGH 1+ SWAP DO I LOAD LOOP ;
: LIST 1 ?ENOUGH CR DUP SCR ! ." Scr # " DUP . L/SCR 0
DO CR I 3 .R SPACE DUP BLOCK I C/L * + C/L -TRAILING >TYPE
KEY? ?LEAVE LOOP DROP CR ;
: INDEX 2 ?ENOUGH 1+ SWAP
DO CR I 3 .R SPACE I BLOCK C/L -TRAILING >TYPE
KEY? ?LEAVE LOOP CR ;
: \ >IN @ NEGATE C/L MOD >IN +! ; IMMEDIATE
: \S B/BUF >IN ! ; IMMEDIATE
: FH BLK @ + ;
: COPY 2 ?ENOUGH SWAP BLOCK DROP BLK# ! UPDATE SAVE-BUFFERS ;
\ Port Access
CODE P@
CODE P!
\ The ALSO and ONLY Concept
CONTEXT DUP @ SWAP 2+ ! ( Make FORTH also )
VOCABULARY ROOT
ROOT DEFINITIONS
: ALSO CONTEXT DUP 2+ #VOCS 2- 2* CMOVE> ;
: ONLY ['] ROOT >BODY CONTEXT #VOCS 1- 2* 2DUP ERASE + ! ROOT ;
: SEAL ' >BODY CONTEXT #VOCS 2* ERASE CONTEXT ! ;
: PREVIOUS CONTEXT DUP 2+ SWAP #VOCS 2- 2* CMOVE
CONTEXT #VOCS 2- 2* + OFF ;
: FORTH FORTH ;
: DEFINITIONS DEFINITIONS ;
: ORDER CR ." Context: " CONTEXT #VOCS
0 DO DUP @ ?DUP IF BODY> >NAME .ID THEN 2+ LOOP DROP
CR ." Current: " CURRENT @ BODY> >NAME .ID ;
: VOCS ." : " VOC-LINK @ BEGIN DUP #THREADS 2* - BODY> >NAME .ID
@ DUP 0= UNTIL DROP ;
: WORDS WORDS ;
\ Load up the system
FORTH DEFINITIONS
: HELLO EMPTY-BUFFERS ONLY FORTH ALSO DEFINITIONS DECIMAL .PROCLAIM ;
\ hex dump
VARIABLE /LINE
( z1013) 4 /LINE !
: .2 0 <# # # #> TYPE SPACE ;
HEX : DUMP BASE @ >R HEX CR CR
5 SPACES /LINE @ 0 DO I 3 .R LOOP
2 SPACES /LINE @ 0 DO I 1 .R LOOP CR
OVER + SWAP /LINE @ NEGATE AND
DO CR I 4 U.R SPACE SPACE I /LINE @ + I 2DUP
DO I C@ .2 LOOP SPACE
DO I C@ DUP BL 7E BETWEEN NOT IF DROP ASCII . THEN EMIT LOOP
KEY? ?LEAVE /LINE @ +LOOP CR R> BASE ! ; DECIMAL
HEX : DU DUP 3F DUMP 40 + ; DECIMAL
\ placeholder file i/o
DEFER PUT ' CRASH IS PUT
DEFER GET ' CRASH IS GET
: MARK CREATE DOES> (FORGET) FORTH DEFINITIONS ;
( ab hier individuelle Anpassung an Z9001 )
VARIABLE LMARGIN 8 LMARGIN !
I/O DEFINITIONS
: (CR) CRLF PRINTING @ IF LMARGIN @ 0 DO BL (PRINT) LOOP THEN ;
' (CR) IS CR
FORTH DEFINITIONS
: .PROCLAIM 12 EMIT ." Z80 FORTH 1.3 (Z9001)" CR ." AG FORTH" CR
." Th. Beierlein / " ." V. Pohlers" CR ;
MARK EMPTY HERE FENCE !