HANDLEIDING BIJ SPECTRUM FORTH83



1. ALGEMEEN                     

                                

1.1 VERANTWOORDING              

                                

Dit FORTH systeem is geschreven door

     L.C. Benschop te Eindhoven.

Hierbij werd gebruik gemaakt van een assembler en een aantal

codedefinities die ontworpen zijn door Coos Haak te Utrecht.

Verscheidene high-level definities zijn ontleend aan de FIG-FORTH

standaard, het overige is eigen werk, in het bijzonder de

screen-editor en alle Spectrum specifieke woorden. Voor een exacte

definitie van de FORTH 83 standaard is deze handleiding niet

bedoeld. Hiertoe raadplege men:

     FORTH-83 STANDARD

     FORTH STANDARDS TEAM       

     P.O. BOX 4545              

     MOUNTAIN VIEW CA94040 USA  

waarvan een exemplaar te verkrijgen is bij de FORTH interes- se

groep van de H.C.C.



1.2 INLEIDING



Deze Forth compiler is geschikt voor ZX-Spectrum 48 en 128, al dan

niet voorzien van Microdrive of diskdrive. De volledige FORTH-83

Required Word Set en System Extension Word Set zijn in het programma

opgenomen, terwijl de Double Number Extension Word Set en Assembler

Word Set zijn bij te laden. Verder zijn er nog uitbreidingen op het

gebied van Floating Point Berekening, strings en graphics. Het

volledige systeem, al dan niet uitgebreid met een of meer van de

genoemde word sets is op tape, disk of Microdrive te bewaren.



Het systeem is blokken-georinteerd. Deze blokken of screens worden

in een RAM-disk bewaard en kunnen apart of samen van tape, Microdrive

of disk worden geladen en daarop worden bewaard. Deze RAM-disk

bevindt zich bij de Spectrum 48 in het hoge geheugen en kan in

grootte gevarieerd worden. Bij de Spectrum 128 bevindt hij zich in

het extra geheugen en is 80K groot.



Het systeem is standaard voorzien van een screen-editor, waarmee ook

aaneengesloten teksten over meer blokken kunnen worden verwerkt. Er

is voorzien in een BREAK toets die FORTH en machinetaal programma's

kan afbreken.



1.3 HET LADEN EN BEWAREN VAN FORTH.



Op de Spectrum 128 moet FORTH vanuit 128K Basic of Tape Loader van

cassette geladen worden. Op de Spectrum 48 gaat het met LOAD "" .

Forth start dan vanzelf. Mocht u met een 48K Spectrum werken met een

of andere interface of geheugenuitbreiding die op adres 7FFDH werkt

en mocht FORTH niet werken, dan moet u het eerste deel van tape

laden, op BREAK drukken, de rest inladen met LOAD "" CODE 27028 en

dan een wijziging aanbrengen:

   POKE 30388,250

   POKE 30389,111

Daarna starten met RUN 20



Bewaren op tape gaat met        

 0 DRIVE 60 BCAL                

Bewaren op disk of Microdrive met:

 1 DRIVE 60 BCAL

Mocht het al op de disk staan, dan moet men eerst de oude files

verwijderen met

 1 DRIVE DELETE run DELETE FORT83.BIN



Het komt dan op drive nr.1. Van de drive kan het dan weer geladen

worden door na het aanzetten van de Spectrum RUN in te typen, op

de Spectrum 128 moet dit in 128K Basic. Het kan noodzakelijk zijn

dat de load en save commando's in het Basic deel worden aangepast

aan het eigen drive systeem. In Basic komt men met de toets SYMBOL

SHIFT W en terug in FORTH met RUN. Heeft men uitbreidingen geladen

en wil men het systeem bewaren, dan typt men voor het bewaren eerst:

   HERE FENCE !

Op de 48K Spectrum kan het aantal screens veranderd orden door:

   N ' #B >BODY ! COLD

in te typen, waarbij in plaats van N het aantal gewenste screens

wordt getypt.



1.4 SCHERM,TOETSEN EN PRINTER.  

                                

In FORTH heeft het scherm 24 regels van 32 tekens. Het zal niet na

verloop van tijd 'Scroll?' vragen. De Extended Mode van het

toetsenbord komt niet voor. De tekens die anders met Extended Mode

moesten worden ingetypt, zoals \, { en [ worden met SYMBOL SHIFT

getypt. Basic woorden kunnen niet worden ingetypt. DELETE wist het

laatst getypte teken. ENTER geeft aan dat de getypte regel klaar is

en de commando's moeten worden uitgevoerd. CAPSLOCK werkt normaal en

SYMBOl SHIFT W keert terug naar Basic, evenals het commando BYE.

Vanuit Basic kan Forth weer gestart worden met RUN. BREAK breekt

FORTH programma's af en EDIT wordt gebruikt om DUMP,VLIST en LIST

netjes af te breken.



Het woord >P stuurt alle uitvoer naar de printer tot dat de volgende

regel met commando's moet worden ingetypt. >S stuurt de uitvoer naar

het scherm.



Heeft men een Spectrum 128 en wil men de ZX-Printer gebruiken, dan

typt men eerst ZX-PRINT Wil men de RS232 op Interface-1

gebruiken, dan moet men FORTH verlaten met SYMBOL SHIFT W, aan regel

20 de statements

   FORMAT "t";9600:OPEN #3,"t"

toe voegen voor de RANDOMIZE en RUN 20 typen. Daarna kan het systeem

als in 1.3 is beschreven worden bewaard.



1.5 FOUTCONDITIES EN HUN EFFECT.

                                

Overal waar in hoofdstuk 3 sprake is van een fout of foutmelding,

wordt een foutmelding afgedrukt, darna de naam van het woord in de

woordbuffer en daarna wordt ABORT uitgevoerd. Trad de fout op

tijdens laden van een screen, dan wordt tevens informatie op de

stack achtergelaten, waar in de tekst de fout optrad.



Geen foutmelding treedt op bij: 

-te groot resultaat bij deling of delen door 0. In dit geval is

 het resultaat -1

-negatief getal indien de standaard positief getal voorschrijft. In

 dit geval wordt het als een unsigned getal beschouwd.

-het manipuleren van de returnstack op een verkeerde manier. Er wordt

 bij EXIT niet gecontroleerd of het returnadres klopt. Een

 system-crash ligt in de lijn der verwachting.

-Ook EXECUTE controleert niet het adres.

-Als WORD geen eind-delimiter vindt.



2. SCREENS EN FILES             

                                

2.1 DE RAM-DISK                 

                                

Daar de Spectrum met trage cassettes of de niet erg snelle

Microdrive moet kunnen werken, bevinden de FORTH screens zich

tijdens het programmeren in een RAM-disk. Op de Spectrum 48 bevindt

hij zich in het geheu- gen vanaf het adres in de variabele LO tot

adres 65535. Op de Spectrum 128 bevindt hij zich in het extra

geheugen en bestaat uit 5 groepen van 16 screens, te weten

1-16,17-32, 33-48,49-64 en 65-80. Het totale aantal screens wordt

gegeven door #SCR



Na het inladen van FORTH kan de RAM-disk worden geledigd met het

commando FORMAT, wat zeker aan te raden is. Met het commando N1 N2

INDEX krijgt men de eerste regel te zien van alle screens van N1 tot

en met N2. In verband hiermee is het FORTH programmeurs zeer aan te

raden de bovenste regel van ieder screen voor commentaar te

gebruiken.



2.2 LADEN EN BEWAREN VAN SCREENS



Met het commando N DRIVE kan men de drive selecteren waarvan men

screens wil laden e.d. N=0 betekent tape,N=1-8 betekent Microdrive

of disk nr. N. Het commando CAT toont de namen van de files die er

zijn. Bij tape dient men dit met de spatiebalk af te breken.



Met N GET filenaam

wordt de gekozen file geladen vanaf screen N.



Met N1 N2 PUT filenaam          

worden de screens N1 tot en met N2 bewaard onder de gekozen

filenaam. met behulp van SAVE..CODE.



Met DELETE filenaam             

kan men een file wissen, wat bij Microdrive noodzakelijk is indien

men een file wil bewaren met dezelfde naam als een bestaande file

die men kwijt wil.



BELANGRIJK: Op de Spectrum 128 moeten alle screens die men als een

enkele file wil laden of bewaren in dezelfde groep zitten bijv.

15 17 PUT JANTJE mag niet. Wat wel mag is

   15 16 PUT JANTJE1

   17 17 PUT JANTJE2

Het copiren van files gaat als volgt:



1 Type eerst FORMAT             

                                

2 Daarna 1 GET filenaam         

                                

3 Dan 1 N INDEX waarbij N het hoogste screen nummer is of 16 bij

de Spectrum 128.



4 Kijk wat het hoogste screen nummer is waar nog wat achter staat.



5 Selecteer eventueel een andere drive en plaats de juiste cassette

of disk. Eventueel wordt een andere file met dezelfde naam gewist

met DELETE filenaam



6 Type 1 M PUT filenaam met M het bij stap 4 gevonden nummer.





2.3 DE EDITOR



Met N EDIT wordt de screen editor gestart. Men ziet dan de helft van

screen N met een knipperende cursor. Onderaan ziet men het screen

nummer en de letter A als de bovenste helft in beeld is en de letter

B als de onderste helft in beeld is. De cusor kan verplaatst worden

met de cursortoetsen, zijnde CAPS SHIFT 5 t/m CAPS SHIFT 8 op het

oude toetsenbord. Altijd is de helft van het screen in beeld waar de

cursor staat. In tegenstelling tot veel standaard systemen heeft elk

screen 32 regels met 32 tekens. De volgende toetsen hebben binnen de

editor een speciale betekenis:



EDIT=CAPS 1 verlaat de editor.  

CAPS LOCk=CAPS 2 als in BASIC.  

TRUE VIDEO=CAPS 3 Voegt een nieuwe regel in op de plaats van de

 cursor. De regels daaronder schuiven een plaats naar beneden. De

 laatste regel verdwijnt.

INV VIDEO=CAPS 4 wist de regel waar de cursor op staat. De regels

 daaronder schuiven een plaats nar boven. De laatste regel wordt

 leeg.

GRAPHICS=CAPS 9 Voegt een spatie in op de plaats van de cursor. De

 rest van de regel schuift naar rechts. Dreigt er iets van de regel

 weg te vallen, dan schuift dat door naar volgende regels.

DELETE=CAPS 0 Wist het teken ter plaatse van de cursor. De rest van

 de regel schuift naar links. Dreigt een woord dat over twee regels

 verdeeld is hierdoor gesplitst te wor- den, dan worden volgende

 regels meegeschoven.

SYMBOL SHIFT Q gaat naar het vorige screen of de vorige helft van

 het screen.

SYMBOL SHIFT E gaat naar het volgende screen of de volgende helft

 van het screen.

Deze beide toetsen geven de mogelijkheid om door de RAM-disk te

'bladeren'.

SYMBOL SHIFT W gaat naar de eerste plaats op de eerste regel van het

 screen.

ENTER gaat naar de eerste plaats van de volgende regel.



Het woord FILE brengt de editor in een toestand waarin de hele

RAM-disk of bij de Spectrum 128 de hele groep screens, als n

geheel wwordt gezien met betrekking tot invoegen en wissen. Ook de

cursortoetsen gaan over de grenzen van het screen. Met BLOCKS worden

alle screens als apart beschouwd.



2.4 LADEN VAN PROGRAMMA'S       

                                

Een programma wordt van een screen geladen met N LOAD Staat op een

screen een \ gevolgd door een spatie, dan wordt de rest van de regel

als commentaar beschouwd. Een --> laat het laden verder gaan op het

volgende screen. Met RUN filenaam kan een file in de RAM-disk

geladen worden en meteen als programma worden geladen. Het laden van

programma's heeft tot gevolg dat alle tekst op een screen wordt

genterpreteerd alsof hij via het toetsenbord was ingetypt. Vanuit

een screen kunnen ook andere screens worden geladen.



3 AANWEZIGE WOORDEN             

                                

3.1 STACKNOTATIE                

                                

De woorden in de lijst staan op ASCII volgorde. Na de naam van het

woord komen de eventuele waarden die het woord op de stack verwacht,

dan drie mintekens en dan de eventuele waarden die het woord op de

stack achterlaat. Een eventuele I geeft aan, dat het woord immediate

is, 83 geeft aan dat het woord tot de FORTH83 Required Word Set

behoort, S geeft aan, dat het tot de System Extension Word Set

behoort, C geeft aan, dat het woord alleen tijdens cmpileren

gebruikt mag worden en en D geeft aan, dat het tot de Double Number

Extension Word Set behoort, welke niet volledig is geimplementeerd

in het kale systeem. De volgende notatie wordt gebruikt voor waarden

op de stack:



f : 0=onwaar,anders waar        

true : -1,duidt waar aan        

false : 0,duidt onwaar aan      

c : ASCII teken                 

8b : byte                       

16b : 16 bits woord.            

n : getal tussen -32768 en +32767

u : getal tussen 0 en 65535

w : getal tussen -32768 en 65535, betekenis hangt af van

    interpretatie.

addr : geheugen adres



Al de voorafgaande stackwaarden nemen n plaats op de stack in.



32b : 32 bit woord              

d : getal tussen -2147483648 en +2147483647

ud : getal tussen 0 en 4294967295

wd : getal tussen -2147483648 en +4294967295, betekenis afhankelijk

     van interpretatie.



Al deze vier waarden nemen twee plaatsen op de stack in beslag.



3.2 DEFINITIES                  



blokbuffer: buffer van 1024 bytes waarin de inhoud van het in

 gebruik zijnde screen wordt bewaard.



colon-definitie: FORTH woord dat gedefinieerd is dmv : De uitvoering

 van dat woord heeft tot gevolg dat de woorden waaruit de

 definitie is opgebouwd achtereenvolgens worden uitgevoerd door de

 inner interpreter. Het adres van waaruit de colon-definitie werd

 aangeroepen wordt op de return stack bewaard.



compilatie adres: het adres, behorende bij een woord, dat tijdens het

 compileren aan het woordenboek wordt toegevoegd.



compileren: het opbouwen van een colon-definitie door het toevoegen

 van compilatie-adressen en literals aan het woordenboek en het

 uitvoeren van immediate woorden.



counted string: rij ASCII tekens als bytes in het geheugen

 voorafgegaan door de lengte van die rij.



immediate woord: FORTH woord, dat wordt uitgevoerd, ook als

 de tekstinterpreter bezig is met compileren.



inner interpreter: stukje machinecode, dat de afzonderlijke

 woorden waaruit colon-definities zijn opgebouwd uitvoert.



interpreteren: het uitvoeren van de woorden in de invoertekst

 en het op de stack zetten van getallen indien een woord niet

 in het woordenboek voorkomt, maar wel een getal voorstelt.



invoerbuffer: buffer waar de van het toetsenbord ingetypte

 regel wordt opgeslagen.



invoertekst: tekst die door de tekstinterpreter wordt gelezen,

 hetzij uit de invoerbuffer, hetzij uit een blokbuffer.



literal: speciaal woord in een colon-definitie met een getal

 erachter, dat, indien uitgevoerd, het getal op de stack zet.



loop: een herhalingsstructuur die gebruikt kan worden binnen een

 colon-definitie, waarbij de eindwaarde (limiet) en een teller

 (index) op de return stack bewaard worden.



numerieke conversie: het omzetten van een getal in een rij

 ASCII tekens, die dat getal in leesbare vorm voorstelt.



return stack: stapel waarop de terugkeeradressen van colon

 definities, index, limiet en start van een loop en andere

 waarden op worden bewaard.



runtime deel: woord dat door een immediate woord tijdens compileren

 aan het woordenboek wordt toegevoegd en dat tijdens het uitvoeren

 van de colon-definitie wordt uitgevoerd.



screen blok van 1024 bytes dat meestal FORTH programmatekst

 bevat. De screens bevinden zich in een RAM-disk.



stack: stapel waarop alle berekeningen van FORTH worden uitgevoerd.



tekstinterpreter: FORTH woord dat woorden uit de invoertekst leest

 en afhankelijk van de toestand interpreteert of compileert.



user variabele: variabele waarvan het adres zich in een

 geheugengebied bevindt, waarvan het beginadres veranderd kan

 worden. Bij multitasking heeft iedere taak zijn eigen

 uservariabelen.



vocabulary: lijst met FORTH woorden,



woordenboek: verzameling vocabulary's. Hierin bevinden zich alle

 FORTH woorden. Beslaat aaneengesloten geheugengebied en wordt aan

 de bovenkant uitgebreid of ingekrompen.



3.3 WOORDEN IN FORTH VOCABULARY 

                                

!  16b addr ---      83         

Schrijft 16b in geheugen op adres addr.



!CSP ---                        

bewaart de stackpointer in de variabele CSP



#  ud1 --- ud2     83           

gebruikt tussen <# en #> deelt meest rechtse cijfer uit

ud1, neemt de ASCII code op in de string dmv HOLD en geeft als

resultaat het getal ud1 waar het meest rechtse cijfer af is.



#> ud --- addr n    83          

beeindigt numerieke conversie, geeft adres en lengte van de string.



#B --- n                        

constante, geeft aantal screens op Spectrum 48.



#S ud1 --- ud2      83          

converteert alle cijfers naar ASCII string dmv # , ud2 is 0.



#SCR --- n                      

geeft aantal screens.           

                                

#TIB --- addr      83           

user-variabele die het aantal tekens in de invoerbuffer bevat.



'    --- addr      83           

leest woord uit de invoertekst, zoekt dit woord in het woordenboek,

en geeft het compilatieadres. foutmelding als woord onvindbaar is.



'ERRNUM --- addr

user variabele die het adres bevat van het woord dat moet worden

uitgevoerd als binnen NUMBER een fout optreedt.



(    ---          I83           

slaat de invoertekst over tot aan ) ,dient als commentaar.



(+LOOP)   --- w                 

runtime deel van +LOOP.         

                                

(.") ---                        

runtime deel van ."             

                                

(;CODE) ---                     

Mag alleen in een colon-definitie voorkomen. Verlaat de

colon-definitie en zet het adres achter dit woord in het codeveld

van het laatst aangemaakte woord



(?DO)   w1 w2 ---               

runtime deel van ?DO            

                                

(ABORT") f ---                  

runtime deel van ABORT"         

                                

(DO)    w1 w2 ---               

runtime deel van DO             

                                

(EMIT)  --- addr                

user-variabele die het adres bevat van het woord, dat EMIT moet

uitvoeren.



(ERRNUM) f ---                  

Geeft fout als f waar is. 'ERRNUM verwijst hier meestal naar.



(FIND) addr1 addr2 --- addr3 n  

addr2 is naamveld adres van laatste woord in vocabulary. gedraagt

zich verder als FIND



(FORGET) addr ---               

addr is het linkveld adres van woord dat vergeten moet worden.

Verwijdert dit woord en alle later gedefinieerde woorden uit

woordenboek.



(KEY) --- addr                  

user-variabele die het adres bevat van het woord, dat KEY uitvoert.



(LOOP) ---                      

runtime deel van LOOP           

                                

(WAIT) --- addr                 

variabele die het adres bevat van het woord dat moet worden

uitgevoerd tijdens het wachten in KEY of PAUSE.



(WORD) c addr1 --- addr2        

addr1 is het adres in de invoertekst, waar wordt begonnen met zoeken

naar een woord. Het eerste teken dat ongelijk is aan c is het eerste

teken van het woord; de tekens tot aan c behoren tot het woord.

addr2 geeft het adres in de invoertekst na het afsluitende teken c.

Een byte 0 markeert het einde van de invoertekst. addr2 zal niet

hoger worden dan het eindadres van de invoertekst. Het woord komt in

de vorm van een counted string op het adres in DP Indien geen woord

in de invoertekst werd gevonden, is de lengte 0. Achter de string

komt een ASCII spatie.



* w1 w2 --- w3     83           

vermenigvuldigt w1 met w2.      

                                

*/ n1 n2 n3 --- n4 83           

vermenigvuldigt n1 met n2 en deelt door n3. Tussenresultaat heeft

dubbele precisie.



*/MOD n1 n2 n3 --- n4 n5 83     

als */ maar geeft n4 als rest van de deling en n5 als quotient



+ w1 w2 --- w3     83           

telt w1 en w2 op                

                                

+! w addr ---      83           

telt w op bij de inhoud van geheugenplaats addr en zet het resultaat

daar weer weg.



+- n1 n2 --- n3                 

geeft het tegengestelde van n1 als n2 negatief is, anders n1



+LOOP addr 3 ---   IC83         

 (runtime) w ---                

sluit een DO LOOP af. telt w op bij de index en eindigt de loop

indien daarbij de grens tussen limiet-1 en limiet wodt over-

schreden., keert anders terug naar begin van de loop.



,  16b ---     83               

vergroot het woordenboek met 2 bytes en zet 16b aan het einde.



-  w1 w2 --- w3   83            

trekt w2 af van w1              

                                

--> ---          I              

mag alleen in een screen voorkomen. zorgt dat de tekst interpreter

verder gaat op volgende screen



-1  --- -1                      

constante -1                    

                                

-ROT 16b1 16b2 16b3 --- 16b3 16b1  16b2

verplaatst de top van de stapel naar de derde plaats.



-TRAILING addr n1 --- addr n2 83

indien de string met adres addr en lengte c1 aan het einde spaties

bevat, wordt c1 zo verlaagd, dat de spaties aan het einde wegvallen.



. n1 ---          83            

drukt het getal n1 af.          

                                

."   ---        IC83            

(runtime) ---                   

leest de tekens uit de invoertekst tot aan " en zorgt er voor dat

die tekst tijdens runtime wordt afgedrukt.



.( ---            I83           

leest de invoertekst tot aan ) en drukt die meteen af.



.R n1 n2 ---                    

drukt n1 af zo dat de totale lengte minstens n2 is. Indien nodig

woden links spaties toegevoegd.



.S ---                          

drukt de inhoud van de stack af zonder de stack te veranderen.



/ n1 n2 --- n3    83            

deelt n1 door n2. n3 wordt altijd nar beneden afgerond.



/MOD n1 n2 --- n3 n4 83         

deelt n1 door n2. n3 is de rest en heeft hetzelfde teken als n2, n4

is het quotient en wordt naar beneden afgerond ( niet naar de 0

toe).



0  --- 0                        

constante 0                     

                                

0< n1  --- f         83         

f=true als n1 negatief is, anders false



0=  n1 --- f       83           

f=true als n1 0 is, anders false

                                

0>  n1 --- f       83           

f=true als n1 positief is, anders false



1  --- 1                        

constante 1                     

                                

1+ w1 --- w2       83           

telt 1 bij w1 op                

                                

1-  w1 --- w2       83          

trekt 1 van w1 af               

                                

2 --- 2                         

constante 2                     

                                

2!  32b addr ---    83          

schrijft 32b op adres addr      

                                

2*  w1 --- w2                   

vermenigvuldigt w1 met 2        

                                

2+  w1 --- w2       83          

telt 2 bij w1 op                

                                

2-  w1 --- w2       83          

trekt 2 van w1 af               

                                

2/  n1 --- n2       83          

deelt n1 door 2                 

                                

2@  adr --- 32b     83          

leest 32b uit geheugen van adres addr



2DROP 32b ---       D           

verwijdert 32b van stack

                                

2DUP  32b ---  32b 32n D        

dupliceert 32b op stack         

                                

2OVER  32b1 32b2 --- 32b1 32b2 32b1 D

dupliceert tweede element op stack.



2SWAP  32b1 38b --- 32b2 32b1 D 

verwisselt de bovenste twee elementen.



2ROT  32b1 32b2 32b3 --- 32b2 32b3 32b1 D

verplaatst derde element naar top van stack.



3 --- 3                         

constante 3                     

                                

: ---            I83            

mag niet tijdens compileren gebruikt worden. leest een woord uit de

invoertekst, maakt in het woordenboek een nieuwe colon-definitie aan

met die naam, die nog niet af is en nog niet gevonden kan worden.

schakelt interpreter over naar compilatietoestand. De CONTEXT

vocabulary wordt de CURRENT.



; ---            I83            

mag alleen tijdens compileren gebruikt worden. Besluit

colon-definitie door het woord EXIT in het woordenboek te zet- ten,

het laatst gedefinieerde woord vindbaar te maken en door de

interpreter in de interpretatietoestand te brengen.



<  n1 n2 --- f     83           

f=true als n1 kleiner is dan n2, anders false



<MARK --- addr     S            

wordt uitgevoerd tijdens compileren door woorden als BEGIN markeert

de plaats waarnaartoe teruggesprongen moet worden.



<RESOLVE addr ---   S           

wordt uitgevoerd tijdens compileren door woorden als UNTIL. zet in

het wwordenboek achter een spronginstructie het door <MARK gegeven

sprongadres.



<#   ---            83          

Start numerieke conversie door de variabele HLD te initialiseren



= 16b1 16b2 --- f    83         

f=true als 16b1 gelijk is aan 16b2, anders false.



> n1 n2 --- f        83         

f=true als n1 groter is dan n2, anders false.



><  16b1 --- 16b2               

verwisselt de bytes van 16b1



>BODY addr1 --- addr2 83

zet compilatie-adres om in parameterveld-adres.



>IN  --- addr        83         

user-variabele die de positie gerekend vanaf het begin van de

invoerbuffer of blokbuffer bevat, waar de tekstinterpreter het

volgende woord zal lezen.



>MARK --- addr       S          

wordt uitgevoerd tijdens compileren door woorden ald IF. maakt

ruimte voor een sprong adres en markeert de plaats waar dit adres

later moet worden ingevuld.



>NAME addr1 --- addr2           

zet compilatie-adres om in naamveld-adres.



>P    ---                       

zorgt ervoor dat alle uitvoer naar de printer gaat, totdat >S wordt

uitgevoerd of een noeuwe regel moet worden ingetypt.



>R    16b ---        83         

bewaart 16b op returnstack.     

                                

>S    ---                       

zorgt ervoor at alle uitvoer naar het scherm gaat.



>RESOLVE addr ---    S          

wordt uitgevoerd tijdens compileren door woorden als THEN. vult het

adres HERE in op de plaats waar >MARK een sprongadres gemarkeerd

had.



?    addr ---                   

drukt het 16 bits getal op adres addr af.



?BRANCH  f ---      S           

kan alleen in colon-definitie voorkomen. Er achter staat een adres.

Springt als f=false



?COMP  ---                      

geeft foutmelding indien niet in compileer-toestand.



?CSP   ---                      

geeft foutmelding indien de inhoud van de variabele CSP ongelijk is

aan de stackpointer. wordt gebruikt om bij ; te controleren of alle

structuren compleet zijn.



?DO   --- addr 3                

(runtime) w1 w2 ---             

geeft de start van een loop aan. De index wordt w2,de limiet w1 De

loop wordt in zijn geheel overgeslagen als w1=w2.



?DUP  16b --- 16b 16b of 16b 83 

dupliceert 16b op de stack als 16b geen 0 is.



?EXEC ---                       

geeft een foutmelding indien niet in interpretatietoestand.



?LOADING ---                    

geeft een foutmelding indien de invoertekst in de invoerbuffer zit.



?PAIRS 16b1 16b2 ---            

geeft een foutmelding indien 16b1 ongelijk aan 16b2. wordt gebruikt

omte controleren of IF .. THEN etc. constructies op de goede wijze

worden gebruikt.



?STACK ---                      

geeft een foutmelding indien de stack te vol is of van de stack meer

is afgehaald dan er ooit is opgezet.



?TERMINAL --- f                 

f=true als de EDIT toets is ingedrukt, anders false.



@   addr --- 16b   83           

leest 16b uit geheugen van adres addr.



ABORT   ---         83          

ledigt alle stacks en start FORTH in een gedefinieerde toestand door

WARM uit te voeren



ABORT"  ---        IC83         

(runtime) f ---                 

leest de invoertekst tot aan " en geeft tijdens runtime die tekst

als foutmelding indien f=true.



ABS  n --- u       83           

geeft absolute waarde van n     

                                

ADDR  n1 --- addr               

geeft het adres van screen n1 en schakelt bij de Spectrum 128 de

juiste geheugenbank in.



ALLOT n ---      83             

breidt het woordenboek met n bytes uit of krimpt het in als n

negatief is. geeft foutmelding als er te weinig geheugen is of te

veel van het woordenboek verloren dreigt te gaan.



AND  16b1 16b2 --- 16b3 83      

geeft de bitgewijze en-functie van 16b1 en 16b2.



AT  u1 u2 ---                   

zet cursor op regel u1 en kolom u2.



B/BUF --- 1024                  

constante geeft aantal bytes in blokbuffer.



B/SCR --- 1                     

constante geeft het aantal blokbuffers per screen.



BANK n ---                      

schakelt geheugenbank n op het adresgebied C000H-0FFFFH.

0 BANK normaal geheugen, 1-5 extra gehegen Spectrum 128.



BASE  --- addr       83         

user-variabele die het talstelsel bevat, dat gebruikt wordt bij

numerieke conversie, het afdrukken van getallen of het inlezen van

getallen uit de invoertekst.



BCAL n ---                      

springt naar regel n van BASIC programma. met BAsIC statement

RANDOMIZE USR 27036 keert men terug naar zelfde plaats in FORTH.

Indien BASIC de onderste schermregels gebruikt heeft, moet daarna

het statement PRINT; gebruikt worden.



BEGIN --- addr 1    IC83        

geeft begin van BEGIN..UNTIL lus of BEGIN..WHILE..REPEAT aan.



BL    --- 32                    

constante ASCII code voor spatie

                                

BLK --- addr          83        

user-variabele die aangeeft van welk screen de invoertekst komt. is

0 als invoertekst van invoerbuffer komt.



BLANK addr u ---                

vult geheugengebied beginnend op adres addr ter lengte u met

spaties.



BLOCK n --- addr      83        

zorgt dat screen n in de blokbuffer staat en geeft het adres van die

buffer. een eventueel ander screen in de buffer wordt eerst op

RAM-disk gezet.



BLOCKS ---            83        

brengt de editor in een toestand dat alle screens aparte stukken

tekst bevatten.



BRANCH  ---          S          

als ?BRANCH maar springt onvoorwaardelijk. wordt gecompileerd

door ELSE en REPEAT.

                                

BS  ---                         

drukt een backspace af.         

                                

BUFFER n --- addr    83         

maakt een lege blokbuffer voor screen n en geeft het adres.



BYE   ---                       

keert terug naar BASIC. dit is altijd 48K BASIC, maar de computer

kan het extra geheugen op de Spectrum 128 nog adresseren.



C!  8b addr ---      83         

schrjft 8b in geheugen op adres addr.



C,   8b ---                     

breidt het woordenboek uit met 1 byte en zet 8b in op die extra

plaats.



C/L  --- u                      

geeft het aantal tekens per regel.



C@   addr --- 8b      83        

leest 8b uit geheugen van adres addr.



CAP  ---                        

schakelt de CAPSLOCK aan of uit.

                                

CAT  ---                        

toont de namen van de files op de disk, cartridge of tape. in het

laatste geval met BREAK-toets stoppen.



CHAN n ---                      

kiest een uitvoerkanaal, 2 is scherm, 3 is printer.



CLEAR n ---                     

vult screen n met spaties.      

                                

CLS ---                         

maakt scherm schoon.            

                                

CMOVE addr1 addr2 u --- 83      

verplaatst geheugengebied beginnend op adres addr1 ter lengte u naar

addr2, waarbij de byte op adres addr1 als eerste verplaatst wordt.



CMOVE> addr1 addr2 u --- 83     

als CMOVE, maar nu wordt de byte op adres addr1 als laatste

verplaatst.



COLD ---                        

koude start van FORTH. verwijdert alle woorden uit het woordenboek

boven FENCE, controleert of het extra geheugen adresseerbaar is en

stelt de variabele LO overeenkomstig in. initialiseert alle

relevante user-variabelen.



COMPILE ---         83          

mag alleen in een colon-definitie voorkomen die immediate is. voegt

het adres dat achter dit woord in het woordenboek staat aan het

woordenboek toe.



CONSTANT  16b ---   83          

(runtime) --- 16b               

leest een woord uit de invoertekst en maakt een constante met

die naam en de waarde 16b.

                                

CONTEXT ---  addr   S           

user-variabele die het adres van de vocabulary bevat, die als erste

doorzocht wordt.



CONVERT ud1 addr1 --- ud2 addr2  83

leest ASCII tekens vanaf adres addr1+1. indien dit teken een cijfer

voorstelt, wordt ud1 met de inhoud van BASE vermenigvuldigd en wordt

het cijfer erbij opgeteld. anders eindigt CONVERT. addr2 is het

adres van het eerste teken dat geen cijfer is. zet ASCII string om

in getal



COPY n1 n2 ---                  

kopieert screen n1 naar n2.     

                                

COUNT addr1 --- addr2 n 83      

n is de byte op adres addr1, addr2 is addr1+1 wordt gebruikt om

adres en lengte van en counted string te bepalen.



CR  ---         83              

drukt een return en newline af. 

                                

CREATE ---          83          

(runtime) --- addr              

leest een woord uit de invoertekst en makt een nieuw woord in het

woordenboek zonder daar ruimte voor data bij te reserveren. Dit

geschiedt met ALLOT. geeft tijdens runtime het adres van die

eventuele ruimte.



CSP --- addr                    

uservariabele die de waarde van de stackpointer bevat bij de laatste

:



CURRENT --- addr      S         

user-variabele die het adres bevat van de vocabulary waar nieuwe

woorden an worden toegevoegd.



D+ wd1 wd2 --- wd3   83         

telt wd1 en wd2 bij elkaar op.  

                                

D+- d1 n --- d2                 

d2 is het tegengestelde van d1 als n negatief is, anders d1.



D-  wd1 wd2 --- wd3  D          

trekt wd2 van wd1 af.           

                                

D.   d ---          D           

drukt d af.                     

                                

D.R  d u ---        D           

als .R maar nu met dubbel precisie getal.



D0<  d --- f        D           

f=true als d negatief is, anders false.



D0=  32b -- f       D           

f=true als 32b nul is, anders false.



D<   d1 d2 --- f    83          

f=true als d1 kleiner dan d2, anders false.



DABS d1 --- ud1     D           

geeft de absolute waarde van d. 

                                

DECIMAL ---         83          

maakt de variabele BASE gelijk aan 10.



DEFINITIONS ---     83          

maakt de CURRENT vocabulary gelijk aan de CONTEXT vocabulary



DELETE ---                      

leest woord uit invoertekst en  verwijdert de file met die naam.



DEPTH --- n         83          

geeft aantal getallen op de stack.



DIGIT c --- u true of false     

zet ASCII teken c om in cijfer u en geef een true vlag en geef

alleen een false vlag als c geen cijfer is.



DLITERAL 32b ---    I           

als literal, maar dan met dubbel getal. Er wordt 2 maal LIT gevormd.



DNEGATE d1 --- d2   83          

berekent het tegengestelde van d

                                

DO    --- addr 3    83          

(runtme) w1 w2 ---              

geeft de start van een loop aan. w2 is de index, w1 is de limiet.

als w1=w2, dan wordt de loop 65536 maal doorlopen.



DOES>   ---         IC83        

(runtime) ---                   

(runtime van gecreeerde woord)  

        --- addr                

komt voor in woord dat CREATE bevat.



Tijdens compileren wordt (;CODE) en een machinecodeinstructie die een

colon-definitie aanroept gecompileerd. Tijdens de uitvoering wordt

het codeveld van het zojuist door CREATE aangemaakte woord aangepast

en wordt de colon-definitie verlaten. Tijdens de runtime van het

zojuist aangemakte woord wordt het parameterveld-adres op de stack

gezet en wordt de colon-definitie voorbij DOES> aange- roepen.



DP  --- addr       83           

variabele die 1 mer dan het hoogste adres van het woordenboek bevat.



DPL --- addr                    

user-variabele die de plaats van de punt in het laatste door NUMBER

ingelezen getal beat, gerekend vanaf rechts. Bevat -1 indien er geen

punt in het getal zat.



DRIVE n ---                     

slecteert het massa-opslagmedium. n=0 is tape, n=1-8 is drive nr. n



DROP  16b ---     83            

verwijdert 16b van de stack.    

                                

DUMP addr u ---                 

toont de inhoud van het geheugengebied vanf adres addr ter lengte u

in hexadecimale en ASCII vorm.



DUP   16b --- 16b 16b  83       

dupliceert 16b op de stack.     

                                

EDIT  n ---                     

start de editor op screen n.    

                                

EDITOR ---                      

vocabulary met woorden die specifiek zijn voor de editor.



ELSE addr1 2 --- addr2 2  IC83  

komt voor in IF..ELSE..THEN constructe. woorden tussen ELSE en THEN

worden alleen uitgevoerd als de vlag bij IF false is.



EMIT  c ---        83           

drukt teken met ASCII code c af, gebruikmakend van het woord

gespecificeerd in (EMIT).

                                

EMPTY-BUFFERS                   

geeft aan dat de blokbuffer geen relevante informatie meer bevat.



ERASE addr u ---                

vult geheugengebied beginnend op adres addr ter lengte u met byte 0.



EXECUTE addr ---   83           

voert het woord met compilatieadres addr uit.



EXIT  ---          83           

verlaat de colon-definitie waar het woord in voorkomt. indien het

tijdens interpretatie voorkomt, wordt interpretatie van dat screen

gestaakt.



EXPECT addr u ---  83           

leest u tekens van het toetsenbord, die getoond worden op het

scherm, vanaf adres addr speciale toetsen zijn hetzelfde als bij

intypen van commando's.



FENCE --- addr                  

variabele die het adres bevat waarbeneden niets meer uit het

woordenboek wordt verwijderd en vanaf waar COLD het woordenboek

afbreekt. moet een link-veld-adres bevatten.



FILE  ---                       

brengt de editor in een toestand waarbij de hele RAM-disk, of groep

van 16 screens daarvan, wordt opgevat als een en dezelfde tekst.



FIND  addr1 --- addr2 n  83     

addr1 is het beginadres van een counted string, die het te zoeken

woord bevat. zoekt woord eerst in CONTEXT vocabulary, daarna in

CURRENT vocabulary. addr2 is het compilatie-adres van dat woord,

indien het woord is gevonden, anders het adres van die string. n=0

als het woord niet is gevonden, n=1 als het woord immediate is en

n=-1 anders.



FIRST --- addr     83           

geeft het eerste adres van de blokbuffer.



FLUSH ---          83           

brengt de inhoud van de blokbuffer over naar RAM-disk als hij een

screen bevat en geeft daarna aan dat hij leeg is.



FORGET ---         83           

leest een woord uit de invoertekst en verwijdert het woord met die

naam en alle later gedefinieerde woorden uit het woordenboek.

Foutmelding indien woord niet is te vinden of indien een woord

beneden FENCE dreigt te verdwijnen.



FORMAT ---                      

vult de gehele RAM-disk met spaties.



FORTH  ---        I83           

vocabulary die al deze woorden bevat. Alle andere vocabularies zijn

uiteindelijk gekoppeld aan FORTH.



FORTH-83 ---      83            

laat zien dat dit systeem FORTH-83 is.



GET  n ---                      

leest een woord uit de invoertekst en leest de file met die naam van

het massaopslagmedum, op screen n en volgende.



GETFN u1 u2 ---                 

leest een woord uit de invoertekst en zet dat in de BASIC-variabele

A$. n1 komt in de BASIC-variabele I en n2 in de BASIC-variabele J.



H. u ---                        

drukt u af in vier hexadecimale cijfers.



HERE --- addr     83            

geeft het eerste adres voorbij het woordenboek.



HEX  ---                        

maakt BASE gelijk aan 16.       

                                

HLD --- addr                    

user-variabele die het adres bevat waarbeneden het eerstvolgende

cijfer bij numerieke conversie terechtkomt.



HOLD c ---         83           

voegt teken c aan de string van numerieke conversie toe.



I   --- w          83           

geeft de index van de binnenste loop.



I'  --- w                       

geeft de limiet van de binnenste loop.



ID. addr ---                    

addr is een naamveld adres. drukt de bijbehorende naam af.



IF  --- addr 2      IC83        

(runtime) f ---                 

komt voor in IF..THEN of IF..ELSE..THEN. de woorden tussen IF en

ELSE of IF en THEN worden alleen uitgevoerd als f=true.



IMMEDIATE ---       83          

maakt laatst gedefinieerde woord immediate.



INDEX  n1 n2 ---                

toont de eerste regels van de screens n1 t/m n2.



INKEY  --- c                    

c=0 als geen toets is ingedrukt en de ASCII code van de toets als er

wel een is ingedrukt.



INTERPRET ---

de tekstinterpreter. leest woorden uit de invoertekst tot het einde

daarvan en interpreteert of compileert. Getallen met een . erin

worden beschouwd als 32-bits getallen.



J --- w

geeft de index van de op een na binnenste loop.



KEY --- c            83         

leest een teken in van het toetsenbord en c is de ASCII code.

Gebruikt (KEY).



LATEST --- addr                 

geeft het adres van het laatst gedefinieerde woord.



LEAVE  ---           83         

verlaat de loop. de returnstack wordt schoongemaakt.



LIMIT --- addr       83         

het adres juist boven de blokbuffer.



LIST n ---                      

drukt de inhoud van screen n af.



LIT  --- 16b                    

komt alleen in colon-definitie voor met daarachter een getal. zet

dat getal op de stack. wordt gecompileerd door LITERAL.



LITERAL 16b --- niets of 16b I83

indien de interpreter in compilatietoestand is, wordt 16b als

literal gecompileerd.

                                

LLIST n1 n2 ---                 

drukt de screens n1 t/m n2 op de printer af.



LO --- addr                     

variabele die het onderste adres van de RAM-disk bevat.



LOAD n ---          83          

geeft het screen n aan de tekstinterpreter als invoertekst en keert

terug op het punt in de invoertekst na LOAD als het screen is

geladen.



LOOP addr 3 ---    IC83         

geeft het einde aan van een loop de index wordt met 1 verhoogd en

indien hij gelijk wordt aan de limiet, dan wordt de loop beeindigd,

anders wordt teruggesprongen naar net begin.



MAX n1 n2 --- n3    83          

n3 is de grootste van n1 en n2. 

                                

M*  n1 n2 --- d                 

n1 wordt vermenigvuldigd met n2 met een 32-bits produkt.



M/  d n1 --- n2 n3              

deelt d door n1 met n2 als rest en n3 als quotient. dezelfde

afrondingsregels als bij /MOD worden gehanteerd.



M/MOD ud1 u1 --- u2 ud2         

deelt ud1 door u1 met u2 als rest en ud2 als quotient.



MIN n1 n2 --- n3     83         

n3 is de kleinste van n1 en n2. 

                                

MIR 16b1 16b2 16b3 --- 16b3 16b2  16b1

verwisselt top met derde op stack.



MOD n1 n2 --- n3     83         

berekent de rest als n1 door n2 wordt gedeeld.



MTYPE addr u ---                

snelle versie van TYPE die niet gebruik maakt van (EMIT).



NAME>  addr1 --- addr2          

zet naamveld-adres om in compilatie-adres.



NEGATE n1 --- n2     83         

berekent het tegengestelde van n1.



NOOP ---                        

doet niets.                     

                                

NOT 16b1 --- 16b2     83        

berekent het 1-complement.      

                                

NUMBER addr --- wd              

zet een string beginnende op adres addr+1 en eindigend met een

spatie om in het bijbehorende getal. de variabele DPL bevat de

plaats van een eventuele punt of -1. als de string met & begint,

wordt de ASCII-code van het tweede teken genomen. indien de string

geen getal voorstelt, wordt via de variabele 'ERRNUM een procedure

uitgevoerd die een foutmelding geeft.



OR 16b1 16b2 --- 16b3 83        

berekent bitsgewijze of-functie van 16b1 en 16b2



OUT --- addr                    

user-variabele die de positie op de regel van EMIT bevat. wordt op

nul gezet door CR, wordt met 1 verhoogd door EMIT.



OVER 16b1 16b2 --- 16b1 16b2 16b1 83

dupliceert tweede waarde op stack.



P! 8b addr ---                  

stuurt 8b naar outputpoort op adres addr.



P@ addr --- 8b                  

leest 8b van inputpoort op adres addr.



PAD  --- addr         83        

geeft het adres van een 64 byte buffer waarin o.a. met strings kan

worden gewerkt.



PAUSE u ---                     

wacht u vijftigsten van seconden. voer ondertussen het woord uit,

waarvan het adres in de variabele (WAIT) zit.



PICK  u --- 16b       83        

haalt de waarde op plaats u op de stack naar boven waarbij u=0 de

top van de stack is u=1 het tweede getal etc. De waarde blijft ook

op zijn oorspronkelijke plaats staan.



PKEY --- c                      

wacht tot een toets is ingedrukt en geeft ASCII code.



PUT n1 n2 ---                   

leest een woord uit de invoertekst en schrijft de screens

n1 t/m n2 naar het massaopslagmedium onder die naam.



QUERY ---                       

leest tot 128 tekens van het toetsenbord dmv EXPECT in de

invoerbuffer en zet BLK en >IN op nul. van tevoren wordt ervoor

gezorgd dat scherm en toetsenbord gebruikt worden.



QUIT ---       83               

leegt de retrun stack, leest regels in va het toetsenbord en gaat

die interpreteren.



R>  --- 16b    83               

haalt 16b van return stack.     

                                

R0   --- addr                   

user-variabele die de het hoogste adres van de returnstack bevat.



R@   --- 16b       83           

leest 16b van de returnstack, zonder deze te verwijderen.



REPEAT addr1 addr2 4 --- 83     

geeft het einde van een BEGIN..WHILE..REPEAT constructie aan. keert

terug naar de plaats van BEGIN.



ROLL  u ---        83           

haalt de waarde op plaats u op de stack naar boven, zoals PICK, maar

verwijdert die waarde van zijn oorspronkelijke plaats.



ROT 16b1 16b2 16b3 --- 16b2 16b3  16b1 83

haalt de derde waarde op de stack naar boven.



RP! ---                         

initialiseert de returnstackpointer.



RP@ --- addr                    

geeft de waarde van de returnstackpointer.



RUN ---                         

leest een woord uit de invoertekst en laadt de file met die naam

vanaf screen 1, waarna screen 1 wordt geladen.



S->D n --- d                    

zet enkele precisie getal om naar dubbele precisie.



S0 --- addr                     

user-variabele die de bodem van de stack bevat.



SAVE-BUFFERS ---     83         

bewaart de inhoud van de blokbuffer in de RAM-disk als die een

screen bevat.



SCR --- addr                    

user-variabele die het nummer van het laatst geliste screen bevat.



SIGN n ---           83         

voegt een - aan de numerieke conversie string toe indien n negatief

is.



SMUDGE ---                      

maakt het laatst gedefinieerde woord vindbaar danwel onvindbaar voor

FIND.



SP!  ---                        

initialiseert de stackpointer.  

                                

SP@  --- addr                   

geeft de stackpointer.          



SPACE  ---           83         

drukt een spatie af.            

                                

SPACES u ---        83          

drukt u spaties af.             

                                

SPAN  --- addr      83          

user-variabele die het aantal tekens bevat, dat bij de laatste

EXPECT is gelezen.



STATE --- addr      83          

user-variabele die de toestand van de tekstinterpreter bevat, 0 is

interpreteren, anders compileren.



STOPOFF ---                     

schakelt de BREAK toets uit.    

                                

STOPON ---                      

schakelt de BREAK toets in.     

                                

STYPE addr u ---                

drukt u tekens af te beginnen op adres addr, waarbij het hoogste bit

genegeerd wordt en control characters als punt worden afgedrukt.



SWAP 16b1 16b2 --- 16b2 16b1 83 

verwisselt de bovenste twee elementen op de stack.



TCH  c ---                      

drukt teken met ASCII code c op scherm of printer af.



TERMINAL ---                    

zorgt ervoor dat de invoer van het toetsenbord komt en de uitvoer

naar het scherm gaat.



THEN addr 2 ---    IC83         

geeft einde van IF..ELSE..THEN of IF..THEN constructie aan.



TIB --- addr        83          

constante het eerste adres van de invoerbuffer.



TOGGLE addr 8b ---              

de bits op geheugenplaats addr die corresponderen met de 1-bits in

8b worden gecomplementeerd.



TRAVERSE addr1 n --- addr2      

telt net zo lang n bij addr op tot bit 7 van de byte op dat adres 1

is.



TYPE addr u         83          

drukt u tekens af, te beginnen op adres addr, waarbij (EMIT) wordt

gebruikt.



U.  u ---         83            

drukt u af.                     

                                

U<  u1 u2 ---f    83            

f=tru als u1 kleiner is dan u2, anders false.



UM* u1 u2 --- ud  83            

vermenigvuldigt u1 en u2, met een dubbel precisie resultaat.



UM/MOD ud u1 --- u2 u3 83       

deelt ud door u1 met u2 als rest en u3 als quotient.



UNDER 16b1 16b2 --- 16b2        

verwijdert het tweede element van de stack.



UNTIL  addr 1 ---  IC83         

(runtime) f ---                 

geeft het einde van een BEGIN..UNTIL constructie aan. als f=false,

dan wordt teruggesprongen naar het begin, anders wordt doorgegaan.



UPDATE ---         83           

geeft aan dat een blokbuffer gewijzigd is en dus teruggeschreven

moet worden naar disk. Bij dit systeem wordt altijd teruggeschreven,

daar het een snelle RAM-disk betreft.



USER  n ---                     

(runtime) ---  addr             

leest een woord uit de invoertekst en maakt een user-variabele met

die naam, die op een adres n vanaf het begin van de user-area zit.

Geeft tijdens runtime het adres.



VARIABLE ---        83          

(runtie) --- addr               

leest een woord uit de invoertekst en maakt een variabele met die

naam. Geeft tijdens runtime het adres, waar een 16-bits waarde kan

worden bewaard.



VLIST ---                       

toont alle woorden in de CONTEXT vocabulary voorafgegaan door hun

naamveld adres.



VOC-LINK  --- addr              

user-variabele die een pointer naar een lijst bevat, die alle

vocabulary's met elkaar verbindt



VOCABULARY ---      83          

leest een woord uit de invoertekst en maakt een vocabulary met die

naam, die reeds de woorden uit de CONTEXT vocabulary bevat. Elke

vocabulary bevat dus FORTH. Maakt tijdes runtime de CONTEXT

vocabulary de opgegeven vocabulary.



WHERE n1 n2 ---                 

n1 is het screennummer, n2 de waarde van >IN toen een fout optrad

tijdens laden van het screen. deze blijven na een fout achter op de

stack. de editor wordt gestart met de cursor op de plaats van de

fout.



WHILE addr1 1 --- addr2 4 IC83  

(runtime) f ---                 

komt voor in een BEGIN..WHILE..REPEAT constructie. Als f=false, dan

wordt gesprongen tot voorbij REPEAT, zodat de herhaling tussen BEGIN

en REPEAT eindigt.



WIDTH --- addr                  

user-variabele die het maximale aantal tekens bevat, die van de naam

van een nieuw woord worden onthouden. normaal 31



WORD c ---addr        83        

leest een woord uit de invoertekst, te beginnen bij het eerste teken

ongelijk aan c en eindigend bij c, gebruikmakend van (WORD). addr is

het eerste adres van de counted string die het woord bevat, zijnde

HERE.



XOR 16b1 16b2 --- 16b3 83

bitsgewijze exclusieve of van 16b1 en 16b2.



ZX-PRINT ---                    

maakt de Spectrum 128 geschikt voor de ZX-Printer.



[    ---        I83             

schakelt de tekst-interpreter in interpreteer-toestand.



[']  ---        IC83            

leest een woord uit de invoertekst, zoekt dit op en compileert het

compilatie-adres als een LITERAL.



[COMPILE] --- IC83

leest een woord uit de invertekst, zoekt dit op en compileert het,

ook als het IMMEDIATE is.



] --- 83

zet de tekstinterpreter in de compileer-toestand.



\   ---                         

mag alleen op een screen voor komen. slaat de rest van de regel

over.



3.4 DE EDITOR VOCABULARY        

                                

CUR ---                         

zet de knipperende cursor aan of uit.



DEL ---                         

wist een teken.                 

                                

DN ---                          

gaat een plaats naar beneden    

                                

HO --- addr                     

variabele horizontale cursorpositie.



HOME ---                        

zet cursor aan begin van screen.

                                

INS ---                         

voegt een teken in.             

                                

LDEL ---                        

wist een regel.                 

                                

LE ---                          

gaat een plaats naar links.     

                                

LIM --- addr                    

1 meer dan laatste adres tekst. 

                                

LINS ---                        

voegt een regel in.             

                                

LPOS --- addr                   

adrs in tekst van begin regel.  

                                

LREST --- u                     

aantal tekens op scherm vanaf cursor regel.



LST ---                         

drukt scherm af.                

                                

PD ---                          

gaat half screen naar beneden.  

                                

POS --- addr                    

geeft adres in tekst.           

                                

PU ---                          

gaat half screen naar boven.    

                                

REST --- u                      

geeft aantal tekens op scherm vanaf cursor.



RI ---                          

gaat een plaats naar rechts.    

                                

SADR --- addr                   

geeft adres begin screen of blokbuffer.



SET ---                         

zet printpositie op plaats van cursor.



TXT --- addr                    

variabele die aangeeft of de RAM-disk aaneengesloten is.



UP ---                          

gaat regel naar boven.          

                                

VE --- addr                     

variabele verticale positie van cursor.



4 OPBOUW VAN DE COMPILER        

                                

4.1 DE INNER INTERPRETER.       

                                

De inner interpreter werkt met direct threaded code, dat wil zeggen,

dat de adressen waaruit een colon-definitie is opgebouwd directe

sprongadressen zijn. Derhalve staat in het codeveld van ieder FORTH

woord een stukje machinecode. Bij codedefinities is dit het begin

van de codedefinitie zelf, bij constanten, variabelen,

colon-definities en user-variabelen is dit een subroutine-call naar

een bijbehorende runtime-routine. Bij DOES> definities is dit een

subroutine call naar het adres achter (;CODE), waar een

call-instructie naar de subroutine voor colon-definities staat. De

eerste call zorgt voor het op de stack zetten van het parameterveld

adres, terwijl de tweede voor interpretatie van de colon-definitie

na DOES> zorgt. In alle gevallen zorgt de call-instructie ervoor,

dat het parameterveld-adres op de stack eenvoudig bereikbaar is.

Iedere codedefinitie zorgt door een JP (IX) instructie voor de

interpretatie van het volgende adres.



De instruction pointer is DE.

De FORTH stackpointer  is SP.

Het adres van NEXT zit in IX.

De returnstackpointer zit op adres 69A7H, de pointer naar de

 user-area op adres 6994H.

Het W-register is niet nodig; dit komt door de call op de stack

 terecht.



De BREAK-toets wordt bekeken door de interruptroutine in

interruptmode 2.



4.2 DE HEADERSTRUCTUUR          

                                

De woorden in dit Forth systeem  bestaan uit 4 velden, dit zijn:



-linkveld :hierin staat het naamveld adres van het vorige woord of

 0. Altijd 2 bytes.

-naamveld :de eerste byte bevat

 bit 7: altijd 1

 bit 6: immediate               

 bit 5: smudge 1 indien niet vindbaar

 bit 4-bit 0:lengte naam.

 De volgende bytes bevatten de tekens die van de naam zijn

 onthouden, de laatste heeft bit 7 =1.

-codeveld :call instructie. altijd 3 bytes.

-parameterveld: bevat alle informatie die dit woord verder nodig

 heeft. (bij codedefinities is geen apart codeveld of parameterveld

 te onderscheiden.)



4.3 DE GEHEUGENINDELING.        

                                

Alle adressen zijn decimaal.    

                                

25580: bovenste adres van de datastack. Hierbeneden is ca. 1

 kilobyte ruimte.

25600: invoerbuffer,128 bytes

26000: bovenste adres return stack. groeit naar invoerbuffer

 toe. 272 bytes ruimte.

26000-27027: blokbuffer met zijn markeringen.

27028: user-area pointer.

27030: koude start entry        

27033: warme start entry        

27036: BCAL return.             

27039: begin user-area 60 bytes groot. De plaatsen 48 t/m 59

 zijn nog vrij.

27047: returnstackpointer, bevindt zich in user-area.

27099: inner-interpreter. Vanaf hier het woordenboek.

33792: pagina gevuld met 85H, interruptvectortabel.

34136: start interruptroutine. vanaf hier gaat woordenboek verder.

HERE=36989: start woordbuffer

PAD=HERE+56: vlak boven numerieke conversiebuffer, start

 stringbuffer. Na PAD komt vrije ruimte.

LO @ =55296 op 48K Spectrum.    

 start RAM-disk.                

Op Spectrum 128 komt dit stuk niet voor. Adressen liggen daar tussen

49152 en 65535 in 5 extra banken. Alleen woorden beneden dit adres

mogen rechtstreeks de RAM-disk adresseren.



4.4 BASIC PROGRAMMA             

                                

Alle tape- en disk bewerkingen gaan via BASIC. Hierbij is de

variabele I de start van het blok, J de lengte en D het drivenummer

en 0 voor tape. A$ bevat de filenaam. Zie voor gegevens over wijze

van aanroepen det woorden BCAL en GETFN in 3.3



regel 1: warme start            

regel 10: start na inladen. reserveert geheugen en laadt code in.

regel 20: koude start.

regel 40: DELETE routine.       

regel 45: CAT routine.          

regel 50: PUT routine.          

regel 55: GET routine.          

regel 60: bewaren van FORTH.    

                                

4.5 METACOMPILATIE.             

                                

De files META1 t/m META4 bevatten de metacompiler waarmee FORTH

gereproduceerd kan worden. De werkwijze is als volgt:

 eventueel DELETE FORT83.BIN

 RUN META1 RUN META2 RUN META3 RUN META4

 Nu wordt FORT83.BIN bewaard.

 BYE                            

 Nu in BASIC GO TO 10           

 De nieuwe FORTH wordt ingeladen en gestart.

 RUN EDITOR

 eventueel DELETE run           

 eventueel DELETE FORT83.BIN    

 60 BCAL                        

 De nieuwe FORTH compleet met BASIC deel en editor wordt bewaard.



De file META1 bevat de eigenlijke metacompiler, bestaande uit:

-woorden als !-T @-T ,-T die hetzelfde doen als ! @ en , maar hun

 adressen omrekenen naar het gebied waar het target systeem wordt

 opgebouwd.

-De vocabulary META. De meeste woorden hierin hebben dezelfde nam

 als normale FORTH woorden en compileren in het target systeem.

-de vocabulary TARGET. hierin zitten de IMMEDIATE woorden van het

 target systeem.

-CREATE-T die headers in het target systeem aanmaakt. Verder creeert

 het definities in de vocabulary META.

-de metaforth assembler, die codedefinities in het target systeem

 maakt.

-woorden die de acties verrichten van de immediate woorden in FORTH,

 maar op het target systeem weken. Die zitten in de vocabulary META



De files META2,META3 en META4 bouwen met die compiler een target

systeem. De file EDITOR wordt door het nieuwe systteem gebruikt om

de editor te maken. Met de metacompiler zijn op source-code niveau

wij- zigingen in FORTH aan te brengen op vrijwel elk gebied of er

kunnen speciale versies zonder headers en compileerwoorden, die een

applicaie bevatten, worden aangemaak. Dergelijke projecten zijn

alleen uit te voeren door ervaren FORTH programmeurs.



5 DE ASSEMBLER

                                

5.1 INLEIDING                   

                                

Met de assembler kunnen woorden in machinecode worden gemaakt. Deze

handleiding veronderstelt dat u bekend bent met de Z80 en zijn

standaard mnemonics. De mnemonics wijken af van die van de standaard

assembler om twee redenen:

-De standaard assembler gebruikt een en hetzelfde woord als mnemonic

 voor instructies met een verschillende vertaling, bv LD wordt

 gebruikt voor

    LD A,B

    LD (IX+12),23

    LD HL,(RPTR)                

    LD A,I                      

    LD SP,HL                    

-Forth is geschikt voor expressies in postfix-notatie. Derhalve is

 het schrijven van een assembler die de mnemonics na de argumenten

 verwacht eenvoudig en kunnen er ook expressies gebruikt worden.



Labels ontbreken in een FORTH assembler vrijwel geheel en in plaats

daarvan worden IF en BEGIN constructies gebruikt zoals ook in FORTH.



Deze assembler was ontworpen door Coos Haak te Utrecht voor zijn

eigen FORTH en door L.C. Benschop overgedragen naar FORTH83.



5.2 LADEN VAN DE ASSEMBLER      

                                

De assembler bestaat uit twee files, TASM ter lngte van 1 screen en

ASSEMBLER ter lengte van 8 screens Indien u de assembler permanent

in FORTH aanwezig wilt hebben om FORTH in die toestand te bewaren,

dan typt u:

   RUN ASSEMBLER

Met HERE FENCE ! wordt hij permanent en dan kunt u hem bewaren als

beschreven in 1.3 Indien u de assembler tijdelijk nodig heeft, bijv

om de Double Number Extension Word Set in te laden, dan tijpt u:

   RUN TASM

Hierdoor wordt de assembler boven in het geheugen geladen en kan hij

na gebruik eenvoudig worden weggewerkt met het commando DISPOSE De

met de assembler gedefinieerde woorden blijven dan bestaan.



5.3 HET MAKEN VAN CODEWOORDEN   

                                

Voor het maken van machinecodedefinities staan de volgende woorden

ter beschikking. Een A geeft aan, dat het woord tot de Assembler

Extension Word Set behoort. Alle woorden zitten in de ASSEMBLER

vocabulary, tenzij er F achter staat. Onder de assembleertoestand

wordt verstaan: de interpretatietostand met daarbij de ASSEMBLER

vocabulary als CONTEXT en BASE op 16.



;c  ---           F             

synoniem voor END-CODE          

                                

;CODE ---         FICA          

komt in een colon-definitie voor die CREATE bevat. compileert

(;CODE) en brengt FORTH in de assembleertoestand. De colon-definitie

die dit woord bevat zal tijdens runtime het codeveld van het zojuist

gecreeerde woord naar het stukje code achter ;CODE laten verwijzen.

Op zijn beurt zal het gecreeerde woord het stukje code uitvoeren met

het parameterveld adres op de stack, net als bij DOES>



ASSEMBLER ---     FA            

vocabulary waarin alle Assembler mnemonics en dergelijke zitten.



CODE ---            A           

leest woord uit invoertekst en maakt een codedefinitie met die naam.

brengt FORTH in de assembleertoestand en maakt woord onvindbaar.



END-CODE ---       FA           

beeindigt codedefinitie, maakt   laatst gedefinieerde woord

vindbaar, maakt de CONTEXT gelijk aan de CURRENT vocabulary en maakt

BASE gelijk aan 10. Dient als afsluiting voor CODE ;CODE en LABEL



ENDM ---          IC            

synoniem voor ; beeindigt macro.

                                

LABEL ---         F             

leest woord uit invoertekst een creeert een woord met die naam, dat

tijdens runtime zijn parameterveld-adres geeft. brengt FORTH in

assembleertoestand. Het nieuwe woord kan dan tijdens assembleren van

een ander woord als adres voor sprong of call gebruikt worden.



MACRO ---         F             

als : maar maakt ASSEMBLER de context vocabulary en BASE 16. een

aantal assembler instructies kunnen zo in een macro worden

samengebracht.



XY --- addr      F              

variabele die aangeeft welk indexregister gebruikt wordt. DDH voor

IX,FDH voor IY



5.4 DE REGISTERS



De assembler kent de namen A,B,C,D,E,H en L voor de enkelvoudige

registers. De naam M wordt gebruikt in plaats van (HL) en geldt als

register. De registerparen hebben de namen B,D en H voor resp. BC,DE

en HL en SP en AF. AF mag alleen gebruikt worden bij PUSH en POP, in

veel andere gevallen met een registerpaar alleen SP,B,D en H. Indien

een indexregister voorkomt anders dan in bijv. (IX+12) dan kan men

de instructie vooraf laten gaan door X Zo wordt LD SP,IX vervangen

door X LDSP XH en XL kunnen het H of het L register vervangen door

het indexregister. Voor instructies met (IX+N) bestan speciale

mnemonics beginnende met een ) . Normaal is het indexregister IX.

Men kan dit in IY veranderen door %Y en weer in IX door %X



5.5 DE INSTRUCTIESET



Een zelfde stacknotatie wordt gebruikt als in hoofdtuk 3 met de

volgende toevoegingen:

b: bit 0-7

r: register A,B,C,D,E,H,L of M

rp: registerpaar B,D of H       

rps: registerpaar of SP.        

rpa: registerpaar of AF.        

disp: displacement tussen -128  

en 127 bij IX of IY.            

                                

LD r1 r2 ---                    

de inhoud van register r1 gaat naar r2. LD r2,r1



)LD r1 disp ---                 

laadt r van adres IX+disp LD r1,(IX+disp)



)ST r disp ---                  

scrijft r op geheugenplaats IX+disp LD (IX+disp),r1



LD#  8b r ---                   

laadt r met 8b LD r1,8b         

                                

)LD# 8b disp ---                

laadt de geheugenplaats IX+disp met 8b LD (IX+disp),8b



MOV rp1 rp2 ---                 

de inhoud van registerpaar rp1 gaat naar rp2. D B MOV wordt LD B,D

LD C,E



LDP# 16b rps ---                

laadt registerpaar rps met 16b  LD rps,16b



LDP addr rps ---                

laadt registerpaar rps van adres addr. LD rps,(addr)



)LDP rps disp ---               

laadt registerpaar van adres IX+disp. B 2 LDP wordt C 2 )LD

B 3 )LD

                                

STP addr rps ---                

schrijft registerpaar rps op adres addr LD (addr),rps



)STP rps disp ---               

schrijft registerpaar op adres IX+disp. B 2 )STP wordt C 2 )ST

 B 3 )ST

                                

LDHL addr ---                   

als LDP maar voor HL register   

                                

STHL addr ---                   

als STP maar voor HL register.  

                                

LDA addr ---                    

laadt A van adres addr LD A,(addr)



STA addr ---                    

schrijft A op adres addr LD (addr),A



LDAP rp ---                     

rp=B of D laadt A vanaf adres in rp LD A,(BC) of LD A,(DE)

LD A,(HL) wordt M A LD !!!

                                

STAP rp ---                     

rp=B of D schrijft A op adres in rp LD (BC),A of LD (DE),A

LD (HL),A wordt A M LD !!!

                                

LDSP ---                        

laadt SP met HL. LD SP,HL       

                                

LDAI ---                        

laadt A met I. LD A,I           

                                

LDIA ---                        

laadt I met A. LD I,a           

                                

EXAF ---                        

verwisselt AF en AF'. EX AF,AF' 

                                

EXDE ---                        

verwisselt DE en HL. EX DE,HL   

                                

EXSP ---                        

verwisselt HL met element op stack. EX (SP),HL



CLR rps ---                     

laadt rps met 0. LD rps,0       

                                

ADD r  ---                      

telt r op bij accumulator ADD A,r

analoog gaan ADC, SUB, SBC, AND, XOR, OR en CP.



)ADD disp ---                   

telt inhoud van adres IX+disp op bij accumulator. ADD A,(IX+disp)

Analoog gaan )ADC, )SUB, )SBC, )AND, )XOR, )OR en )CP.



ADD# 8b ---                     

telt 8b op bij accumulator ADD A,8b

Analoog gaan ADC#, SUB#, SBC#, AND#, XOR#, OR# en CP#.



ADDP rps ---                    

telt rps op bij HL. ADD HL,rps  

Analoog gaan ADCP, SUBP en SBCP.

rps SUBP is A AND rps SBCP.     

                                

INC rps ---                     

hoogt registerpaar rps 1 op. INC rps.

Analoog gaat DEC.

                                

INR  r ---                      

hoogt register r 1 op. INC r

Analoog gaat DER (DEC r)



)INR disp ---                   

hoogt de inhoud van geheugenplaats IX+disp met 1 op.

INC (IX+disp) Analoog )DER.

                                

RL r ---                        

Roteert register r 1 plaats naar links RL r.

Analoog gaan RR, RLC, RRC, SRL, SRA en SLA.



)RL disp ---                    

Roteert de inhoud van geheugenplaats IX+disp 1 plaats naar links.

RL (IX+disp) Analoog gaan )RR, )RLC, )RRC, )SRL, )SRA en )SLA.



BIT b r ---                     

test bit b van register r.      

BIT b,r. Analoog gaan RES en SET

                                

)BIT b disp ---                 

test bit op geheugenplaats IX+disp. BIT b,(IX+disp).

Analoog gaan )RES en )SET.

                                

TST rp ---                      

test of rp 0 is. B TST is hetzelfde als B A LD  C OR



JP addr ---                     

springt naar adres addr. Analoog gaan JPNZ, JPZ, JPNC, JPC, JPPO,

JPPE, JPP, JPM, CALL, JR, JRNZ, JRZ, JRNC, JRC, DJNZ en RST.

addr JPNZ is JP NZ,addr.

                                

JPHL ---                        

springt naar het adres in HL Analoog gaat JPIX.



CALLC addr cc ---               

conditionele call naar adres addr cc is de in kleine letters

geschreven conditiecode uit 5.6



RETC cc ---                     

conditionele return.cc heeft zelfde betekenis als bij CALLC.



PUSH rpa ---                    

zet rpa op stack. PUSH rpa. Analoog gaat POP.



PRT ---                         

RST 16H om teken af te drukken. 

                                

HOOK 8b ---                     

RST 8 DEFB 8b om foutmelding te geven of Interface1 te sturen.



IN 8b ---                       

leest accumulator van poort 8b IN A,(8b) Analoog gaat OUT.



De instructies NOP, RLCA, RRCA, RLA, RRA, HALT, DAA, CPL, SCF, CCF,

DI, HALT, EXX, LDIR, LDDR, CPIR, IM1, EI, IM2 en NEG zijn hetzelfde

als in de standaard assembler. Een aantal weinig voorkomende

instructies is niet geimplemen- teerd. Zij zijn te maken met , en C,

of alsnog te definiren.



RPTR, UPTR en NEXT zijn 3 constanten die het adres van de

returnstackpointer, het adres van de pointer naar de user-area en

het adres van de inner-interpreter voorstellen.



5.6 IF EN BEGIN STRUCTUREN.     

                                

In de assembler komen de IF..THEN, IF..ELSE..THEN, BEGIN..UNTIL en

BEGIN..WHILE..REPEAT constructies van FORTH voor, die met relatieve

sprongen worden geimplementeerd. IF, WHILE en UNTIL worden

voorafgegaan door een coditiecode, die Z, NZ, CS of NC kan zijn.

BEGIN .. NC UNTIL betekent, dat een bepaald stuk herhaald moet

worden totdat het carrybit 0 is. Er is dan een JRC instructie

aanwezig. Verder zijn er nog BEGIN..AGAIN, dat een herhaling eeuwig

laat duren, en BEGIN..DSZ, dat een DJNZ instructie aan het eind van

de herhaling plaatst.



Dezelfde constructies behalve BEGIN..DSZ kunnen ook met absolute

sprongen worden gemaakt. De relevante woorden dienen dan in kleine

letters te worden geschreven. De conditiecodes zijn dan z, cs, pe, p

en v, waarbij v hetzelfde is als pe. Elk van deze codes kan worden

gevolgd door NOT in hoofdletters, dat de tegenovergestelde code

aanduidt.

                                

6 DE DOUBLE NUMBER EXTENSION WORD SET



6.1 INLEIDING



De file DOUBLE bestaat uit 3 screens en bevat alle woorden, die

nodig zijn om de Double Number Extension Word Set volledig te

implementeren en daarbij nog woorden die het mogelijk maken alle

berekeningen met dubbele precisie te doen, inclusief

vermenigvuldigen, delen en worteltrekken.



Alvorens DOUBLE te laden moet eerst de assembler geladen worden met

RUN TASM of RUN ASSEMBLER Daarna RUN DOUBLE en tenslotte eventueel

DISPOSE



6.2 EXTRA WOORDEN               

                                

2CONSTANT 32b ---   D           

(runtime) --- 32b               

als CONSTANT maar nu voor 32-bit waarde.



2UNDER 32b1 32b2 --- 32b2       

verwijdert tweede waarde van stack.



2VARIABLE ---       D           

(runtime) --- addr              

als VARIABLE maar nu met 4 bytes ruimte.



D* wd1 wd2 ---wd3               

vermenigvuldigt wd1 met wd2.    

                                

D/ d1 d2 --- d3                 

deelt d1 door d2. Er wordt naar beneden afgerond.



D/MOD d1 d2 --- d3 d4           

deelt d1 door d2. d3 is de rest en d4 het quotient.



D2*  wd1 --- wd2                

vermenigvuldigt wd1 met 2       

                                

D2/  wd1 --- wd2    D           

deelt wd1 door 2                

                                

D= 32b1 32b2 --- f  D           

f=true als 32b1 en 32b2 gelijk zijn, anders false.



D> d1 d2 --- f      D           

f=true als d1 groter dan d2, anders false.



DIVISOR --- addr                

dubbele variabele die de deler bevat bij D/



DMAX d1 d2 --- d3   D           

d3 is het maximum van d1 en d2. 

                                

DMIN d1 d2 --- d3   D           

d3 is het minimum van d1 en d2. 

                                

DMOD d1 d2 --- d3               

d3 is de rest bij deling van d1 door d2.



DU. ud ---                      

als D. maar nu voor unsigned getal.



DU.R ud u ---                   

alse D.R maar nu voor unsigned getal.



DU< ud1 ud2 --- f   D           

f=true als ud1 kleiner is dan ud2, anders false.



SQRT ud --- u                   

u is de naar beneden afgeronde vierkantswortel van ud.



U.R u1 u2 ---                   

als .R maar nu met unsigned getal.



UD/MOD ud1 ud2 --- ud3 ud4      

deelt ud1 door ud2. ud3 is de rest en ud4 het quotient.



7 DE FLOATING POINT UITBREIDING 

                                

7.1 INLEIDING                   

                                

Met deze uitbreiding kunt u in Forth floating point getallen

gebruiken. Deze getallen zijn 32 bits groot en dus kunnen 2@, 2! en

de stack bewerkingen voor dubbele precisie getallen ook voor

floating point getallen gebruikt worden.



Het woord NUMBER is uitgebreid met een mogelijkheid om floating

point getallen te verwerken. U kunt floating point getallen nu

vanuit de tekstinterpreter invoeren door achter een getal, dat al

dan niet een decimale punt bevat een & teken te typen. Achter het &

teken kan dan + of - een getal komen, dat aangeeft met welke macht

van BASE het getal vermenigvuldigd moet worden. Zo kunnen getallen

in wetenschappelijke notatie worden ingevoerd in elk talstelsel.

Voorbeelden zijn:



     2&    het getal 2          

-2.718&    het getal -2.718     

    12&+3  het getal 12000      

-0.041&    het getal -0.041     

  -4.1&-2  het getal -0.041     

                                

De floating point woorden zitten in twee files. De eerste file

FLOATING bestaat uit 8 blokken en bevat de basisbewerkingen, woorden

om floating point getallen af te drukken, de bovenbeschreven

uitbreiding van NUMBER en een worteltrekking. Eerst moet de

assembler aanwezig zijn. Deze kan worden geladen met RUN TASM of RUN

ASSEMBLER. Daarna kan dde uitbreiding geladen worden met RUN

FLOATING. Na afloop eventueel DISPOSE intypen.



De twwede file TRANSCEN bevat de trigoniometrische en logaritmische

functies. Deze heeft de assembler niet nodig, maar FLOATING moet

geladen zijn. TRANSCEN bestaat uit 4 blokken.



7.2 FORMAAT EN NAUWKEURIGHEID.  

                                

Een floating point getal bestaat uit twee delen. De drie minst

significante bytes vormen de mantisse, een 24-bits binair getal

tussen 1 en 2. Het eerste bit stelt 1 voor, het tweede 1/2 het derde

1/4 enz. Daar het eerste bit toch altijd 1 is, wordt dit weggelaten

en in plaats daarvan komt het tekenbit 0=positief, 1 is negatief.

Het meest significante byte is de exponent, de macht van 2, waarmee

de mantisse vermenigvuldigd is plus 128.



Het grootste negatieve getal en het kleinste positieve getal stellen

per definitie nul voor. Dus het floating point getal nul wordt

voorgesteld door alle bits 0. Het grootste positieve getal en het

kleinste negatieve getal stellen + of - oneindig voor. Deze getallen

komen uit berekeningen waar te grote getallen uitkomen of die

onmogelijk zijn (delen door nul).



De floating point getallen hebben een nauwkeurigheid van ongeveer 7

cijfers. De getallen

                 38         -39           -39        38

zijn tussen -3x10   en -3x10, tussen 3x10    en 3x10   en nul.



7.3 WOORDEN UIT FLOATING.       

                                

De stack notatie is als in de voorgaande hoofdstukken met dit

verschil dat fp een 32-bits floating point getal voorstelt. Woorden

die alleen bij het assembleren gebruikt worden, zijn hier niet

beschreven.



1& --- fp                       

De constante 1.                 

                                

10& --- fp                      

De constante 10.                

                                

2CONSTANT  32b ---              

 (runtime)     --- 32b          

Zie hoofdstuk 6                 

                                

D->F  d --- fp                  

zet het dubbele precisie gehele getal d om in het equivalente

floating point getal.



F* fp1 fp2 --- fp3              

floating point vermenigvuldiging

                                

F+ fp1 fp2 --- fp3              

floating point optelling.       

                                

F- fp1 fp2 --- fp3              

fp2 wordt afgetrokken van fp1   

                                

F->D fp --- d                   

Het floating point getal f wordt omgezet in een dubbele precisie

geheel getal, waarbij naar nul toe wordt afgerond.



F. fp ---                       

fp wordt afgedrukt in wetenschappelijke notatie met & als symbool

voor maal tien tot de macht.



F.R fp n1 n2 ---                

fp wordt afgedrukt zo dat de totale lengte minstens n1 is. Indien

nodig worden links spaties toegevoegd. Er worden n2 cijfers achter

de punt getoond. Er kan in elk talstelsel worden afgedrukt.



F/ fp1 fp2 --- fp3              

fp1 wordt door fp2 gedeeld.     

                                

F0< fp --- f                    

f is waar als fp kleiner is dan 0, anders onwaar.



F0= fp --- f                    

f is waar als fp gelijk is aan 0, anders onwaar.



F2* fp1 --- fp2                 

vermenigvuldigt fp1 met 2.      

                                

F2/ fp1 --- fp2                 

deelt fp1 door 2.               

                                

F< fp1 fp2 --- f                

f is waar als fp1 kleiner is dan fp2, anders onwaar.



F= fp1 fp2 --- f                

f is waar als fp1 gelijk is aan fp2, anders onwaar.



F> fp1 fp2 --- f                

f is waar als fp1 groter is dan fp2, anders onwaar.



FABS fp1 --- fp2                

fp2 is de absolute waarde van fp1.



FERRNUM f ---                   

Bevat de uitbreiding van NUMBER. Het adres in 'ERRNUM verwijst

daarnaar. Probeert floating point getal te maken als f waar is. Lukt

dit niet, dan volgt een foutmelding.



FI** fp1 n --- fp2              

verheft fp1 tot de macht n. n is altijd geheel uiteraard.



FLOAT ---                       

Maakt de uitbreiding van NUMBER  actief. Moet gegeven worden na

koude start.



FNEGATE fp1 --- fp2             

trekt fp1 van 0 af.             

                                

FSQRT fp1 --- fp2               

Berekent vierkantswortel van fp1.



NAN --- fp                      

Constante, geeft ongeldig resultaat aan.



X! fp1 8b --- fp2               

Vervangt het exponent byte in fp1 door 8b.



X@ fp --- fp 8b                 

8b is het exponent byte van fp. 

                                

7.4 WOORDEN UIT TRANSCEN.       

                                

180/PI --- fp                   

Constante 180 gedeeld door pi   

                                

2, 32b ---                      

breidt het woordenboek uit met 32b, net als ,



2VARIABLE ---                   

 (runtime) --- addr             

Zie hoofdstuk 6.                

                                

ATN2 --- fp                     

fp is de hoek in radialen, die de vector in FX en FY maakt met de

x-as.



ATNTAB --- addr                 

addr is het beginadres van een tabel met de arctangenten van

negatieve machten van 2. Wordt gebruikt bij berekening

trigoniometrische functies.



ATNTAB@ u --- fp                

fp is de arctangens van 2 tot de macht -u.



DEG fp1 --- fp2                 

Zet hoek fp1 in radialen om naar hoek fp2 in graden.



F** fp1 fp2 --- fp3             

verheft fp1 tot de macht fp2. fp1 mag niet negatief zijn. De

verheffing tot een gehele macht, FI** heeft die beperking niet.



F*2** fp1 n  --- fp2            

deelt fp1 door 2 tot de macht n.

                                

F10** fp1 --- fp2               

berekent 10 tot de macht fp1.   

                                

FARCCOS fp1 --- fp2             

berekent de arccosinus van fp1 in radialen.



FARCSIN fp1 --- fp2             

berekent de arcsinus van fp1 in radialen.



FARCTAN fp1 --- fp2             

berekent de arctangens van fp1 in radialen.



FCOS fp1 --- fp2                

fp1 is in radialen. Berekent cosinus.



FEXP fp1 --- fp2                

berekent de e-macht van fp1.    

                                

FLN fp1 --- fp2                 

berekent de natuurlijke logaritme van fp1.



FLOG fp1 --- fp2                

berekent de tientallige logaritme van fp1.



FSIN fp1 --- fp2                

fp1 in radialen. Berekent sinus.

                                

FTAN fp1 --- fp2                

fp1 is in radialen. Berekent de tangens.



FX --- addr                     

FY --- addr                     

Twee floating point variabelen die een vector bevatten voor de

berekening van trigoniometrische functies.



LN10 --- fp                     

constante, de natuurlijke logaritme uit 10.



LN2 --- fp                      

constante, de natuurlijke logaritme uit 2.



LNTAB --- addr                  

addr is het beginadres van een   tabel die de natuurlijke logaritmen

bevat van 1 plus een negatieve macht van 2. Wordt gebruikt bij

logaritmische berekeningen.



LNTAB@ u --- fp                 

fp is de natuurlijke logaritme van 1 plus twee tot de macht -u.



PI --- fp                       

constante, het getal pi.        

                                

PI/180 --- fp                   

constante, pi gedeeld door 180. 

                                

RAD fp1 --- fp2                 

zet hoek fp1 in graden om in hoek fp2 in radialen. Om de sinus van

45 graden te berekenen typt men 45& RAD FSIN F. RAD zet 45 om naar

radialen, daar FSIN radialen nodig heeft.



TAN2 fp ---                     

fp is positief. Maakt een vector in de variabe- len FX en FY onder

een hoek van fp radialen met de x-as.



8 GRAFIEK EN GELUID.

                                

8.1 GRAFISCHE ROUTINES.         

                                

De file GRAPHIC bestaat uit 2 blokken en bevat routines om punten en

lijnen te tekenen en verder commando's voor de kleuren. GRAPHIC

gebruikt de assembler en daarom moet de assembler eerst geleaden

worden. Het laden van GRAPHIC geschiedt op de zelfde wijze als

beschre- ven voor DOUBLE in hoofstuk 6.



PLOT n1 n2 ---                  

Tekent een punt met x-coordinaat n1 en y-coordinaat n2.



DRAW n1 n2 ---                  

Tekent een lijn van de huidige plotpositie n1 punten naar links en

n2 punten naar boven. Als n1 of n2 negatief zijn worden de

richtingen resp. naar links en naar beneden.



POINT n1 n2 --- f               

geft aan of het punt met x-coordinaat n1 en y-coordinaat n2 getekend

is.



ATTR n1 n2 --- c

geeft de waarde van het attribute byte op regel n1 en kolom n2.



HARDCOPY ---                    

maakt een kopie van het scherm op een ZX-Printer.



SCREENLOAD ---                  

Leest de filenaam uit de invoertekst en leest de file met die

naam in het schermgeheugen.

                                

SCREENSAVE ---                  

Leest de filenaam uit de invoertekst en bewaart de inhoud van het

scherm op band of schijf onder die naam.



INK n ---                       

PAPER n ---                     

BORDER n ---                    

BRIGHT n ---                    

FLASH  n ---                    

werken het zelfde als de gelijknamige BASIC commando's.



INV n ---                       

Welkt als het BASIC commando INVERSE.



GOVER n ---                     

Werkt als het BASIC commando OVER.



NORMAL ---                      

Stelt de normale kleuren en dergelijke in.



COLOR c ---                     

 (runtime) n ---                

Definierend woord dat gebruikt wordt om INK, PAPER etc te maken



8.2 USER DEFINED GRAPHICS.      

                                

De file UED bestaat uit 4 blokken. Hij kan geladen worden met RUN

UED indien GRAPHIC aanwezig is.



De codes van de UDG's kunnen worden ingevoerd met ^ direct gevolgd

door de letter. ^A stelt graphic A voor.



CHADDR n --- addr               

geeft het adres van de grafische representatie van het teken met

code n.



UED ---                         

start de UDG editor Binnen de UDG editor hebben de toetsen de

volgende betekenis. Cursortoetsen en ENTER. Verplaatsen de grafische

cursor in het 8x8 veld.



@ Leest een teken in in het 8x8 veld. Typt men direct na @ een

letter in, dan wordt de bijbehorende UDG gelezen. Typt men na @ een

& in en dan een teken, dan wordt dit teken ingelezen.



! Schrijft het teken in het 8x8 veld in het geheugen op het adres

waar de grafische representatie van een bepaald teken staat. De

keuze van het teken geschiedt als bij @. Normaal kan men alleen

UDG's wegschrijven, maar als de systeemvariabele CHARS op 23606

gewijzigd is, ook andere tekens.



A O en E voeren resp. een AND, OR en EXOR bewerking uit met het

teken in het 8x8 veld en een willekeurig te kiezen teken.



X en Y spiegelen het teken in het 8x8 veld in resp. de X en de Y as.



R roteert het teken in het 8x8 veld een kwartslag.



I inverteert het teken in het 8x8 veld.



SPATIE inverteert de pixel waar de grafische cursor staat.



EDIT beeindigt de grafische editor.



8.3 GELUID.                     

                                

De file MUSIC bestaat uit twee blokken en bevat routines om uit de

Spectrum 48k zowel als 128k geluid te krijgen. De ASSEMBLER is

nodig. Zie voor het laden hoofdstuk 6, waar het laden van DOUBLE

wordt beschreven.



BEEPER u1 u2 ---                

produceert een toon bestaande uit u1 pulsen met een lengte van u2

machine tijdseenheden.



TONE u1 u2 ---                  

produceert een toon van u1 milliseconden en u2 Hz.



MS n1 ---                       

wacht n1 milliseconden.         

                                

De volgende commando's werken alleen op een 128K Spectrum.



SOUND 8b n ---                  

schrijft 8b in register n van de geluidschip.



FREQ u n ---                    

Stelt kanaal n (n=0,1 of 2) in op frequentie u



VOL u n ---                     

Stelt kanaal n (n=0,1 of 2) in op volome u (u=0 t/m 15).



TONES ---                       

Schakelt de 3 toonkanalen in.   

                                

NOISE ---                       

Schakelt de 3 ruiskanalen in. Met n 6 SOUND kan de ruisfrequentie

worden beinvloed.



SHUTUP ---                      

Schakelt het geluid uit.        

                                

De volgende commando's werken afhankelijk van het type Spectrum op

de BEEPER of op de geluidschip.



NOOT  u ---                     

(runtime) ---                   

definierend woord dat een noot met frequentie u definieert.



A A# B C C# D D# E F F# G G#    

brengen de gewenste noot ten gehore.



L  u ---                        

Stelt de lengte van de volgende noten op u tellen.



O+ O- ---                       

verhoogt, verlaagt het octaaf.  

                                

>> << ---                       

verhoogt of verlaagt het volume.

                                

R ---                           

Geeft een rust.                 

                                

TEMP --- addr                   

variabele die het tempo aangeeft in milliseconden per tel.



OCT --- addr                    

variabele die het octaaf aangeeft. (vermenigvuldigingsfactor

van frequentie.)

                                

VOLUME --- addr                 

Variablele die het volume aangeeft.



LEN --- addr                    

variabele die het aantal tellen per noot aangeeft.



9 DE DECOMPILER

                                

De file UTIL bestaat uit 2 blokken en bevat een utility om te

bekijken hoe een bepaald FORTH woord is opgebouwd, te decompileren.



Met SEE naam krijgt men een overzicht, dat de volgende informatie

bevat:

- het codeveld adres.

- eventueel IMMEDIATE.          

- het soort woord, dit kan zijn

  CONSTANT voor constanten

  USER voor user variabelen.

  : voor colondefinities.       

  CREATE voor variabelen of woorden die met CREATE zijn gemaakt.

  CODEWORD voor machinecodewoorden.

  De naam van het definierende woord voor woorden die met een ander

  definierend woord zijn gemaakt, zoals VOCABULARY

- De inhoud van het woord d.i.

  Voor constanten en uservariabelen: de waarde.

  Voor colondefinities: een lijst van alle woorden waaruit de

  definitie is opgebouwd. Dit verschilt van de sourcecode doordat de

  runtime delen van immediate woorden worden getoond. Hierbij wordt

  rekening gehouden met eventuele operanden, zoals de waarde van een

  literal, de sprongafstand van BRANCH e.d. en de string achter

  (.").

  Voor alle ander woorden: een

  hex en ASCII dump.            

- Het aantal bytes in het parameterveld. Deze lengte klopt niet als

  het volgende woord in de CONTEXT vocabulary niet op het

  gedecompileerde woord volgt.



Het decompileren van colondefinities stopt als EXIT wordt gevonden.

Woorden die EXIT ergens middenin gebruiken worden niet compleet

gedecompileerd.



Wanneer nieuwe compilerende woorden worden gedefinieerd die

operanden achter zich hebben, werkt de decompiler daarmee niet

correct. De decompiler zal dan moeten worden aangepast.



Behalve SEE zijn de volgende woorden nog van belang:



(SEE) addr ---                  

Verricht de actie van SEE op het woord met addr als codeveldadres



HIGH-NFA addr1 --- addr2        

addr2 is het naamveld adres in de de CONTEXT vocabulary dat het

dichtst boven addr1 ligt.



#WORDS --- u                    

geeft het aantal woorden in de CONTEXT vocabulary inclusief wat

eraan vast zit.



DOCON --- addr                  

DOCOL --- addr                  

DOUSER --- addr                 

constanten die de adresssen van de runtime routines van CONSTANT :

en USER bevatten.



NEXT --- addr                   

adres van de inner interpreter. Komt voor in het codeveld van

variabelen.



10 MULTITASKING.                

                                

10.1 INLEIDING.                 

                                

Multitasking is het uitvoeren van meer programma's schijnbaar

tegelijkertijd. Hierbij heeft ieder programma zijn eigen stack en

uservariabelen en wordt zeer snel tussen de programma's

omgeschakeld. Voor de hand liggende toepassingen zijn:



-besturing van apparaten zoals modeltreinen.

-videogames.

-meerstemmige muziek. (128k)    

-muziek op de achtergrond.(128k)

-doorwerken met FORTH terwijl de computer bezig is met een

 langdurige berekening.



De file TASKS bevat de basisroutines om multitasking mogelijk te

maken en bestaat uit 3 screens. De assembler is nodig. Voor het

laden volge men dezelfde procedure als voor DOUBLE in hoofdstuk 6.



10.2 HET MAKEN VAN EEN TAAK.    

                                

Het maken van een taak wordt gellustreerd aan de hand van een

voorbeeld. We maken een taak die linksboven op het scherm een getal

schrijt, dat steeds oploopt. Allereerst definiren we een woord, dat

de cursorpositie geeft, zodat die door AT weer hersteld kan worden.



: UNAT 24 23689 C@ - 33         

  23688 C@ - DUP 32 = IF        

  DROP 1+ 0 THEN ;              



Nu definieren we de taak, alsof het een colon definitie was maar dan

met TASK: en ;TASK



TASK: TAAK1 DECIMAL 0 BEGIN     

 UNAT 0 0 AT 2 PICK 6 .R AT     

 1+ DUP 0= SWITCH UNTIL ;TASK   

                                

Nu wordt het multitasking systeem opgestart met STARTUP Om de taak

te starten typt men zijn naam, dus TAAK1



Nu moet men, terwijl men gewoon met FORTH werkt, linksboven een

getal snel zien oplopen. Typt men ' TAAK1 STOP in, dan zal het getal

niet meer oplopen. Typt men ' TAAK1 START in, dan gaat het tellen

weer door. Typt men weer TAAK1, dan start de taak weer opnieuw vanf

0. Wacht men lang genoeg en heeft de taak behalve de positieve

getallen ook de negatieve getallen geteld, dan zal de taak uit

zichzelf ophouden.



Krijgt men ergens een foutmelding, dan start men alle taken weer

door STARTUP. De foutmelding moet dan wel in de normale FORTH taak

ontstaan.



10.3 DE WERKING.                

                                

Iedere keer dat men een nieuwe taak aanmaakt, wordt een nieuw

taakgebied aangemaakt. Dit bestaat uit de volgende onderdelen



- 2 bytes startadres van de FORTH code.

- 2 bytes adres van de vorige gedefinieerde taak. Bij de eerste taak

  wijst dit naar de laatste, zodat alle taken circulair met elkaar

  zijn verbonden.

- 1 byte statusbyte:

    0=actief (uitvoerbaar)      

    1=nieuw.                    

    2=beindigd.

    3=slapend.                  

    4=gestopt.                  

  Alleen met een statusbyte 0 mag de taak doorgaan.

- 2 bytes adres van de taak zijn stackpointer.

- 60 bytes user variabelen.

- 256 bytes returnstack.        

- 256 bytes stack.              

Hierna begint de FORTH code.    

                                

Op de Spectrum 128K moeten alle taakgebieden beneden adres 49152

liggen!



Het omschakelen tussen taken geschiedt met het woord SWITCH Met dit

woord worden de return-stackpointer en de instructiepointer van de

huidige taak op de stack bewaard. Dan wordt de stackpointer op zijn

plaats bewaard. Dan wordt via de linkadressen een taak opgezocht,

die uitvoerbaar is. Dan worden de stackpointer, de instructiepointer

en de returnstackpointer van de nieuwe taak geladen en wordt

verdergegaan met de nieuwe taak. Alle taken komen zo cyclisch aan de

beurt. De user area pointer wijst naar de user area in het

taakgebied van de huidige taak.



Om multitasking te verkrijgen moet men iedere taak voorzien van het

woord SWITCH in de lusstructuren die vaak worden herhaald en een

vrij korte tijd per herhalingsslag hebben. Anders duurt het te lang

voordat andere taken een beurt krijgen. Indien een taak nooit een

SWITCH uitvoert, blijft hij steeds aan de beurt.



Ook de woorden KEY en PAUSE voeren tijdens het wachten SWITCH uit.

Dit wordt bereikt via de variabele (WAIT).



10.4 DE WOORDEN.                

                                

SWITCH ---                      

Schakelt om naar de volgende uitvoerbare taak.



UPTR --- addr                   

constante, het adres van de user area pointer.



TASK-LINK --- addr              

variabele die het adres van het laatst aangemaakte taakgebied bevat.



FIRST-TASK --- addr             

Variabele die het adres van het eerst aangemaakte taakgebied bevat.



TASK: ---                       

Definierend woord, dat een taak aanmaakt. Brengt FORTH in de

comileertoestand. Tijdens runtime wordt de taak vanaf het begin

gestart.



;TASK ---                       

sluit de definitie van een taak af. Brengt FORTH in de

interpretatietoestand.



TERMINATE ---                   

Beindigt de huidige taak. Men moet de taak dan niet daarna met

start weer door laten gaan.



SLEEP ---                       

Brengt de huidige taak in de slaaptoestand. Uit deze toestand kan

een taak wel worden wakker geroepen door start.



STOP addr ---                   

addr is het codeveld adres van een taak. Stopt een andere taak.



START addr ---                  

addr is het codeveld adres van een taak. Herstart een gestopte taak

vanaf het punt waar hij werd gestopt.



MTSK ---                        

De taak die de FORTH interpreter bevat. Dat MTSK actief is is te

zien aan de prompt > .



(START) ---                     

codedeel van STARTUP            

                                

STARTUP ---                     

schakelt het multitasking systeem in.



TLIST ---                       

Geeft een lijst van alle taken met hun status. De status ACTIVE

heeft de taak die TLIST aanriep. De status RUNNABLE hebben alle

andere uitvoerbare taken.



11 STRINGS EN ANDERE DATATYPEN.

                                

11.1 INLEIDING                  

                                

De file OBJECT bestaat uit 6 screens en bevat al het nodige om met

strings te werken en een aantal woorden om gestructureerde datatypen

zoals arrays te bouwen. Veel van de bewerkingen die in dit hoofdstuk

zijn beschreveen zijn ook op een lager niveau mogelijk en daarbij

sneller. Deze routines zijn niet ontworpen voor snelheid maar voor

gebruikersvriendelijkheid.



11.2 DE STRINGSTACK             

                                

Strings zijn rijen ASCII tekens met een bepaalde lengte. Zij worden

bewaard op een aparte stack. Iedere string bestaat uit een

lengtebyte, van 0 tot en met 255 en daarachter de tekens. De string

aan de top van de stack zit het laagst in het geheugen, de string

die daaronder zit komt er direct achteraan. De stringstackpointer

wijst naar het lengtebyte van de string aan de top van de stack. Het

adres van de tweede string kan worden gevonden door het lengtebyte

plus 1 bij de stackpointer op te tellen. De string stack bevindt

zich bovenin het vrije geheugen, direct onder het adres in de

variable LO. De strinstackpointer bevindt zich in de variable $SP



Met de stringstack zijn de bewerkingen $DUP, $SWAP, $OVER en  $DROP

mogelijk. Verder kunnen strings van de stack naar het geheugen

verplaatst worden met $! en $!LIM en van het geheugen naar de stack

met $@.



Met de strings op de stack kunnen de zelfde bewerkingen worden

uitgevoerd als in de meeste BASIC dialecten, zoals MID$, STR$ VAL,

ASC, CHR$, LEFT$ en RIGHT$. Verder kunnen strings vergeleken worden

met $=,$< en $> en samengevoegd met $+ en afgedrukt met $.



Stringconstanten kunnen zowel vanuit de interpreter als in de

compiler worden ingevoerd met " waaracher een spatie en dan de

string afgesloten door " Zo betekent

" Dit is een tekst." $.

hetzelfde als                   

." Dit is een tekst."           

in de compiler of               

.( Dit is een tekst.)           

in de interpreter.              

Alleen gebruiken de laatste twee niet de stringstack.



Een ander voorbeeld van het gebruik van de stringstack is.

   1234. STR$ 1 RIGHT$ $.

Dit zet het getal 1234 om in een string, haalt er het laatste cijfer

uit met RIGHT$ en drukt dit af. Het is daarmee equivalent met het

BASIC statement

   PRINT RIGHT$(STR$(1234),1).

Een ervaren FORTH programmeur bereikt hetzelfde effect met

   1234. <# # #> TYPE

wat sneller werkt en waar bovendien de stringroutines niet bij nodig

zijn.



11.3 HET 'TO' CONCEPT.          

                                

In standaard FORTH-83 geeft een variabele altijd een adres af en is

de gebruiker ervoor verantwoordelijk dat de waarde in die variable

wordt uitgelezen of opgeslagen. Hierbij moet gekozen worden uit de

woorden @, C@, 2@, $@ !, C!, 2!, $! of $!LIM. Een vaak voorkomende

programmeerfout be- rust op het vergeten van @, C@, 2! of $@ bij het

uitlezen van een variable.



Bij gebruik van het TO-concept draagt de variabele er zelf zorg

voor, dat hij wordt gelezen of beschreven. De variable weet wat hij

moet doen aan de hand van een toestand. Deze toestand geeft normaal

gesproken aan dat de variabele moet worden gelezen maar door het

woord TO te gebruiken kan men de toestand tijdelijk op 'schrijven'

zetten. Nadat er een variabele is beschreven komt de toestand weer

op 'lezen'. Men kan nu

   A B + C D + * TO E

intypen in plaats van           

   A @ B @ + C @ D @ + * E !

Ging het om  dubble precisie variabelen, dan kan men in het

eerste geval

   A B D+ C D D+ D* TO E

intypen in plaats van           

   A 2@ B 2@ D+ C 2@ D 2@ D+ D* E 2!

In het eerste geval veranderen

alleen de rekenkundige bewerkingen, in het tweede geval ook alle

lees en schrijf operaties.



In dit programma wordt de toestand bijgehouden terwijl het programma

loopt. Dit maakt het machine-onafhankelijk maar minder snel. In

andere systemen wordt de toestand vaak tijdens compileren

bijgehouden, zodat FORTH er geen omkijken meer naar heeft als het

programma loopt.



11.4 GESTRUCTUREERDE DATATYPEN  

                                

Als men een variable volgens het TO-concept wil maken, die een

wwarde bevat, dan typt men:

   <type> VALUE <naam>

<naam> is de naam, die de variabele moet krijgen.

<type> is een van de volgende dingen:

BOOL voor logische varabelen

     (1 byte)                   

CHAR voor tekens (1 byte)       

INT  voor gehele getallen (2 bytes)

LONG voor dubbele precisie ge tallen. (4 bytes)

REAL voor floating point getallen. (4 bytes)

n STR voor strings. n is hier een getal dat de maximum lengte

      aangeeft.(n+1 bytes maar niet minder dan 5).



INT    VALUE AANTAL             

REAL   VALUE MAAT               

10 STR VALUE NAAM               

maakt drie variabelen, een geheel getal, een floating point getal en

een string van hoogstens 10 tekens.



Een eendimensionale array maakt men met

   n <type> ARRAY <naam>

n is hierbij het aantal elementen, dat de array bevat.



3 LONG  ARRAY VECTOR            

9 5 STR ARRAY NAMEN             

maakt twee arrays, een met 3 dubbele precisie getallen en een met 9

namen met lengte hoogstens 5. Men kan VECTOR een waarde geven met

bv. 1234. TO 0 VECTOR Indien A een integer variabele is, moet met

1234. A TO VECTOR gebruiken om VECTOR een waarde te geven en niet

1234. TO A VECTOR daar dan iets in A geschreven wordt en niet in

VECTOR. Men selecteert een element van een array met een getal

tussen 0 en het aantal elementen min 1.



Een tweedimensionale array is te maken met:

   n1 n2 <type> MATRIX <naam>

Men krijgt dan een array van n1 maal n2 elementen. Men selecteert

een element met 2 getallen, waarvan het eerste tussen 0 en n1-1 ligt

en het tweede tussen 0 en n2-1.



Het type van de elementen wordt onderscheiden aan de hand van de

grootte. Elementen die 1 byte groot zijn, worden met C! en C@

bewerkt en zijn van type CHAR of BOOL. Elementen van 2 bytes zijn

van type INT en worden met @,! en +! bewerkt. Elementen van 4 bytes

groot zijn LONG of REAL en worden met 2@ en 2! bewerkt. Alle grotere

elementen zijn strings. De datatypen maken geen onderscheid tussen

bv REAL en LONG.



men kan zelf met behulp van het CREATE DOES> mechanisme andere

datatypen bouwen, zoals records met elementen van verschillend type,

queues, stacks, lijsten etc. Men moet dan ergens het aantal bytes

opslaan in de datastructuur. Aan de hand daarvan kan men het adres

van het element opzoeken. Met (VAL) kan men dan de data bewerken,

gegeven het adres en het type, waarbij de toestand in de variabele

%TO staat.



11.5 DE WOORDEN.                

                                

$ in de stacknotatie betekent een string op de stringstack.



" ---    (compileren)           

  --- $  (interpreteren)        

Leest de invoertekst tot " en compileeert deze als een

string-literal als de tekestinterpreter in de compilatietoestand is

of zet de string op de stringstack.



"" --- $                        

stringconstante, de lege string.

                                

$!  $ addr ---                  

Slaat de string op vanaf adres addr.



$!LIM $ addr u ---              

slaat string $ op vanaf adres addr en kapt hem af als hij meer dan u

tekens lang is.



$+   $1 $2 --- $3               

Concateneert de strings $1 en $2

                                

$-   $1 $2 --- n                

n is negatief als de string $1 kleiner is dan $2, dwz lager komt in

de ASCII-lexicografische ordening, n=0 als de strings gelijk zijn en

positief als $1 groter is dan $2.



$. $ ---                        

drukt de string $ af.           

                                

$< $1 $2 --- f                  

f is waar als $1 kleiner is dan $2, anders onwaar.



$= $1 $2 --- f                  

f is waar als $1 gelijk is aan $2, anders onwaar.



$> $1 $2 --- f                  

f is waar als $1 groter is dan $2, anders onwaar.



$@ addr --- $                   

leest de string uit het geheugen vanaf adres addr.



$CONSTANT $ ---                 

 (runtime)  --- $               

definierend woord. Creert een nieuw woord, dat tijdens runtime de

eerder toegevoerde string op de stack zet.



$DROP $ ---                     

verwijdert string van stack.    

                                

$DUP $ --- $ $                  

dupliceert string op stack.     

                                

$OVER $1 $2 --- $1 $2 $1        

dupliceert tweede string op stack.



$S0  --- addr                   

Hoogste waarde van de stringstackpointer.



$SP --- addr                    

variable die het adres van de strinstackpointer bevat.



$SP! ---                        

zet de strinstackpointer op zijn hoogste adres.



$SWAP $1 $2 --- $2 $1           

wisselt de strings om op de stack.



%TO --- addr                    

variabele die de toestand bevat, die aangeeft wat een TO-variabele

moet doen.



(")  --- $                      

runtime deel van "              

                                

(CHAR)  addr --- c  %TO=0       

      c addr ---    %TO=1       

verwerkt variabelen van type CHAR en BOOL.



(INT)   addr --- n  %TO=0       

      n addr ---    %To=1 of 2  

verwerkt variabelen van type INT

                                

(LONG)  addr --- d  %TO=0       

      d addr ---    %TO=1       

verwerkt variabelen van type LONG en REAL.



(STR)   addr u --- $ %TO=0      

      $ addr u ---   %TO=1      

    c n addr u ---   %TO=4      

      n addr u --- c %TO=5      

verwerkt variabelen van type string, waarbij addr het adres is van

de string, u de maximale lengte, $ de string, c het teken in de

string men wil lezen of schrijven en n geeft aan welk teken.



(VAL)  addr u ---               

verwerkt een variabele van een van de voorgaande typen. u geeft de

grootte aan in bytes. addr het adres.



+$ $1 $2 --- $3                 

concateneert de strings door $1 achter $2 te plaatsen.



+TO    ---                      

geeft an dat bij een volgende variabele iets moet worden opgeteld.



-RIGHT$ $1 u --- $2             

$2 is $1 vanaf het u-de teken.  

                                

>ELEM  ---                      

geeft aan dat bij de volgende variabele een teken in een string wodt

geschreven. Als NAAM een stringvariable is, dan verandert &A 1 >ELEM

NAAM het eerste teken van NAAm in een A.



?RANGE u1 u2 ---                

geef foutmelding als U1>u2      

                                

ARRAY u1 u2 ---                 

maakt array van type u2 met u1 elementen.



ASC $ --- c                     

c is het eerste teken van $     

                                

BOOL --- 1                      

geeft type aan bij variabele.   

                                

CHAR --- 1                      

geeft type aan bij variabele.   

                                

CHR$ c --- $                    

$ is de string die uit het teken c bestaat.



ELEM> ---                       

geeft aan dat bij een volgende variabele een teken uit een string

gelezen moet worden.



ER ---                          

geef foutmelding INVALID OP.    

                                

GET$ --- $                      

leest string $ van het toetsenbord met EXPECT.



INT --- 2                       

geeft type aan bij variabele.   

                                

LEFT$ $1 u ---$2                

$2 bestaat uit de eerste u tekens van $1.



LEN $ --- u                     

u is de lengte van string $     

                                

LONG --- 4                      

geeft type aan van variabele.   

                                

MATRIX u1 u2 u3 ---             

maakt een mtrix van type u3 met u1 rijen en u2 kolommen.



MID$ $1 u1 u2 --- $2            

$2 bestaat uit u2 tekenst uit $1 beginnende vanaf het u1-de teken



REAL --- 4                      

geeft type aan van variabele.   

                                

RIGHT$ $1 u1 --- $2             

$2 bestaat uit de laatste u1 tekens van $1.



RV ---                          

zet %TO wwer in de leestoestand 

                                

STR u1 --- u2                   

geeft stringtype aan.           

                                

STR$ d --- $                    

zet dubbel getal om in string.  

                                

TO ---                          

geeft aan dat bij een volgende variabele iets wordt geschreven.



VAL $ --- d                     

Zet string om in dubbel getal.  

                                

VALUE u1 ---                    

maakt variabele van type u1.    

                                

WORD$ --- $                     

$ is het volgende woord uit de invoertekst.



11.6 AANPASSEN VOOR MULTITASKING

                                

Teneinde deze routines voor multitasking geschikt te maken, moet u

in ieder geval de variabelen $SP en %TO als USER definieren, tenzij:



- er slechts n taak gebruik maakt van deze routines.

- Iedere SWITCH gebeurt met een lege stringstack en de %TO variabele

  in de leestoestand.



Wanneer iedere taak zijn eigen stringstackpointer heeft, moet men

voor iedere taak een apart stringstackgebied reserveren en de

stringstackpointer aan het eind van dit stackgebied initialiseren.

                                



