FORTH

Írta:
Lipovszki György
Subai László
Beszeda Tamás
OMIKK
LSI Alkalmazástechnikai Tanácsadó Szolgálat
Budapest, 1985

A Mikroszámítógépek és Alkalmazási Rendszereik Kutatása- Fejlesztése című OMFB tárcaprogram 4/b alprogramjához kapcsolódóan kézült.
Témafelelős: Sziklai Klára

Tartalom

Előszó

1. Bevezetés

2. A könyvben alkalmazott jelölések

3. A FORTH alapfogalmai
3.1. A FORTH felépítése
3.2. A stack-ek
3.3. Utasítások definiálása és felépítése
3.4. A szótár szerkezete
3.5. Működési módok
3.6. Számok

4. Alapvető FORTH definíciók
4.1. Műveletek adatokkal
4.2. Aritmetikai műveletek
4.3. Stack-kezelő (adatmozgató) műveletek
4.4. Memóriakezelő utasítások
4.4. Return stack műveletek

5. Vezérlési struktúrák
5.1. Logikai reláció és függvények
5.2. Utasítások feltételes végrehajtása ( IF-THEN struktúra)
5.3. Határozatlan ciklus szervezési lehetőségei (BEGIN-UNTIL struktúra)
5.4. Ciklusszervező utasítás (DO-LOOP struktúra)

6. Adatbehozatali és adatkiviteli műveletek
6.1. Numerikus adatbeviteli utasítások
6.2. Numerikus adatkiviteli utasítások
6.3. Numerikus adatok formátum szerinti kivitele
6.4. Karakteres adatbeviteli utasítások
6.5. Karakteres adatkiviteli utasítások
6.6. Adatbehozatal és -kivitel port-ok segítségével
6.7.Kommunikáció háttértárolókkal
6.8. Hibajelzések
6.9. Kiíratás nyomtatón

7. A FORTH speciális utasításai
7.1. A szótárak létesítése
7.2. A rendszer állapotát befolyásoló utasítások
7.3. Utasítások, definíciók törlése
7.4. Utasításnevek keresése a szótárban
7.5. Az utasítások lefordítása FORTH-ban
7.6. Új utasítások, adatstruktúrák előállítása
7.7. A paraméter és a return stack mutatói
7.8. Inicializáló utasítások
7.9. Az utasításnevek listázása

8. FORTH szövegszerkesztő (EDITOR)

9. FORTH assembler

10. A FORTH használata néhány Magyarországon elterjedt számítógépen
10.1. A 8080 fig-FORTH 1.1 Version
10.2. 8080 CPM-FORTH 2.2
10.3. ICC DOS-80 FORTH
10.4. SIF-Z80 FORTH 2.2.
10.5. ABC80 FORTH
10.6. Spectrum FORTH
10.7. Abersoft FORTH
10.8. ZX Spectrum 48k Floating Point FORTH
10.9. C64-FORTH
10.10. TPA8 OS/I FORTH
10.11. TPA8 CAMAC FORTH

11. A fig-FORTH alapszótárában található definíciós szavak

12. Néhány hasznos FORTH definíció
12.1. Az utasítások átdefiniálhatóságának lehetősége
12.2. CASE struktúra
12.3. Dupla pontosságú műveletek
12.4. Megszakítás beiktatása a definíciós szóba
12.5. A memóriatartalom listázása (Memory Dump)
12.6. A 79-Standard FORTH eltérő utasításainak definíciója

Hibaüzenetek

Előszó
Ahogy bővül Magyarországon is a FORTH felhasználók tábora, egyre- több és több jelzést kapunk, hogy sürgősen szükség lenne egy magyar nyelvű, és ami ugyanilyen fontos, elérhető FORTH ismertetésre. Szerencsésnek mondhatja magát, még az is, aki legalább a Brodie vagy a l-logan könyvet (lásd. Irodalomjegyzék) meg tudta szerezni. A magyar számítógépekre készült FORTH implementációkhoz gépkönyv ugyan általában rendelkezésre áll, de azt nem oktató célzattal Írják.
Mi ezt a könyvet elsősorban kezdőknek szánjuk, ezért a fogalmak és az utasítások (úgynevezett szavak) részletes magyarázatát mindig számos példával is alátámasztjuk. Reméljük azonban, hogy a haladók is jól tudják majd e leírást használni, akár referenciaként (az utasításokat leíró fejezeteket az ott ismertetendő utasítások felsorolásával kezdjük, és a könyvből indexet is készítettünk), akár néhány hasznos utasításdefiníció - mint például a duplapontosságú aritmetikai, vagy a 79-Standard fig-FORTH definíciója - lelőhelyeként. Mindkét szinten hasznos lehet, hogy megadjuk néhány FORTH változat hibaüzenet listáját.
A kezdő illetve haladó szintet az olvasó FORTH ismereteinek szintjére értjük, feltételezzük, hogy mindenképpen vannak alapfokú számítógépes ismeretei.
A Bevezetésben röviden ismertetjük a FORTH programozási nyelv és rendszer történetét, majd, a jelölési konvenciókat tárgyaló fejezet után rátérünk a FORTH más programozási nyelvektől eltérő filozófiájára és ebből eredő sajátos alapfogalmaira.
Az alapvető utasítások tárgyalását a vezérlési struktúrák, az input/output műveletek, majd azon utasítások leírását követi, amelyekhez már nem találunk megfelelőt más programnyelvekben, speciálisan a FORTH-ra jellemzőek.
A már háttértárba került FORTH programok szerkesztését biztosító utasítások után az assembler nyelvű betétek készítésének lehetőségét ismertetjük.
A 4. fejezettől a 10. fejezetig a 8080 fig-FORTH 1.1 szerint haladunk. Egyes, széles körben elterjedt implementációk azonban nem feltétlenül követik ezt, de, ha követik is, használatukra néhol jellemző, hogy milyen gépen, illetve milyen operációs rendszer alatt futnak. Ezért külön szólunk a 8080 fig-FORTH-ról, a CP/M alatti, az ICC DOS-80, az ABC80, a ZX Spectrum, a Commodore 64, a TPA 8 OS/I FORTH-ról és az Abersoft FORTH-ról.
Amennyiben a könyv alapján készítői, vagy legalábbis a FORTH elnyerte az olvasó bizalmát, szívesen látjuk a FORTH iránt érdeklődő rendszerprogramozók körében, a MTESZ Híradástechnikai Tudományos Egyesület Mikroszámítógépes Programnyelvek és Operációs Rendszerek Szakosztállyá havi rendezvényein (érdeklődés az Egyesületnél az 531-027 telefonon).

1. Bevezetés
A láncolt kódú (Threaded Code) interpreter nyelvek iránt az elmúlt években egyre nő az érdeklődés, mert a tapasztalat szerint

Napjainkban már az összes mikroprocesszor típusra működik ilyen interpreter.
Az első láncolt kódú interpreter nyelvet az 1970-es évek elején Charles Moore készítette, így őt tekinthetjük az ezen az elven működő programozás megalkotójának. Moore, aki a Kitt Peak obszervatórium óriásteleszkópjának irányítástechnikai problémáival foglalkozott, negyedik generációs számítógépekre akart programozási nyelvet kifejleszteni. Ennek eredményeként született meg a FORTH nyelv, amelynek neve a negyedik (angolul FOURTH) szó csonkítása.
A FORTH, mint láncolt kódú interpreter előnyösen egyesíti azokat az igényeket, amelyeket egy modern mikroszámítógépes fejlesztői rendszerrel szemben támasztunk.

A nyelv fanatikusai persze minden feladatot ebben a programozási nyelvben oldanak meg, de tapasztalataink szerint, elsősorban rendszerprogramozási, logikai és irányítástechnikai feladatok megoldására alkalmas, mint például:

A könyv további fejezeteiben bemutatjuk a FORTH programozási nyelv felépítését, elemeit, utasításait. Ezekre számos példát mutatunk, de fontosnak tartjuk, hogy az utasítások kipróbálásához számítógépes háttér is rendelkezésre álljon.
A FORTH rendszer utasításainak részletes leírásakor a 8080 fig-FORTH 1.1 verzióját vettük alapul.
A könyv összes példáját ebben a rendszerben írtuk. Az egyes számítógépeken megvalósított - és könyvünkben ismertetett FORTH rendszerek mindegyike a fig-FORTH rendszer utasításainak többségét tartalmazza. Az eltérést, hiányt illetve további szolgáltatásokat jelentő utasítások leírását az egyes implementációknál közöljük. Ezek mindig a 8080 fig-FORTH 1.1 meglévő utasításainak kiegészítéséül szolgálnak az egyes számítógépeknél.
A "FIG" a FORTH Interest Group nevének rövidítése. Ez a szervezet foglalkozik a FORTH nyelv utasításainak gondozásával és szabványosításával. A csoport 1979-es ülésének az utasításokra vonatkozó ajánlásait az úgynevezett 79-STANDARD tartalmazza.
A fig-FORTH a FORTH Interest Group implementációja a 79-STANDARD alapján. Magába foglalja a 79-STANDARD FORTH összes utasítását és a továbbfejlesztett utasításokat.
Néhány eltérés van az utasítások elnevezésében a 79-STANDARD és a fig-FORTH között, ezért a mellékletben közöljük a 79-STANDARD és a fig-FORTH eltérő elnevezésű definícióit, a fig-FORTH utasításaival definiálva.
A FORTH Interest Group legutóbbi szabványügyi ülése 1983-ban volt, de az ennek eredményeképpen megállapított standard utasításlista (83-STANDARD) még nem terjedt el széles körben.

2. A könyvben alkalmazott jelölések
A magyarázó példáknál meg kell különböztetni a FORTH programozó illetve a számítógép által a képernyőre irt információkat. A számítógép által kiírt információkat aláhúzással jelöljük, míg a programozó által adott információt aláhúzás nélkül.

A paraméter stack diagram készítésekor mindig a paraméter stack tetején szereplő adat van a leírás jobb oldalán. Például:

cím n1 n2 ---

Ebben az esetben például az n2 paraméter van a paraméter stack tetején alatta van az n1i, és ez alatt a cím paraméter.
A paraméter stack-en több azonos szimbólumú paraméter megkülönböztetése számokkal történik. Például:

n1 n2 n3 ---

A továbbiakban az egyes utasítások leírásánál az adattípusok megkülönböztetése érdekében egységes jelölést alkalmazunk. Az utasítások leírásánál a következő adatok szerepelhetnek:

cím
A számítógép operatív memóriájában levő abszolút cím. 16 bites, egyszeres pontosságú, előjel nélküli egész szám. Az ábrázolható számtartomány [0...65 5353].

n
Előjeles, 16 bites, egyszeres pontosságú, egész típusú számérték. A legmagasabb helyi értékű bit szolgál előjel bitként. Az ábrázolható számtartomány [-32 768...+32 767].

u
Előjel nélküli, 16 bites, egész típusú, egyszeres pontosságú számérték. Az ábrázolható számtartomány [0...65 535].

d
Előjeles, kétszeres pontosságú, 32 bites, egész típusú számérték. Az előjelet a magasabb helyi értékű szó legmagasabb helyértékű bitje adja meg, így az ábrázolható számtartomány [-2 147 483 648...+2 147 483 647].

ud
Előjel nélküli, kétszeres pontosságú, 32 bites, egész típusú számérték. Az ábrázolható számtartomány [0...4 294 967 395].

b
8 bites, egész típusú, előjel nélküli adatot jelentő számérték. Az ábrázolható számtartomány [0...255]. 16 bites adatként való ábrázolásakor a paraméter stack-en a magasabb helyértékű bitek nulla értékűek.

c
7 bites, karakter típusú, adattípus amelynek ábrázolható számtartománya [0...127]. 16 bites adatként való ábrázolásakor a paraméter stack-en a magasabb helyértékű bitek nulla értékűek.

f
16 bites, egész típusú, logikai állapotot jelölő érték (flag). Logikai állapotai:
f=0 logikai hamis állapot,
f<>0 logikai igaz állapot.

tf
16 bites, egész típusú, logikai igaz állapotot jelölő érték (true flag). Értéke nullától eltérő.

ff
16 bites, egész típusú, logikai hamis állapotot jelölő érték (false flag). Értéke nullával egyenlő.

3. A FORTH alapfogalmai

3.1. A FORTH felépítése
Más magasszintű nyelveknél, mint például a BASIC vagy a FORTRAN, a felhasználónak kell alkalmazkodnia az illető nyelv definiált utasításkészletéhez, illetve az ezekhez tartozó "nyelvtani" szabályokhoz.
A FORTH programnyelvnél ettől eltérően maga a felhasználó tervezi meg egy számára megfelelő magasszintű nyelv utasításait, és lehetősége van akár a nyelvtani szabályok megváltoztatására is.
Általában a FORTH-ban minden funkciót, feladatot a felhasználó által definiált elnevezésű szavak segítségével írunk le. Ezek alapját kezdetben természetesen az alapszókészlet adja.
A programozás módja FORTH-ban újabb és újabb feladatok ellátására alkalmas szavak definíciója. A FORTH-beli szó más programnyelvekben használt fogalmakhoz hasonlítva, egy névvel hívható paraméteres szubrutin.
Újabb szavakat a már korábban definiált szavak felhasználásával hozhatunk létre.
A szavak bemenő paramétereikét egy közösen használt memóriaterültről, a paraméter stack-ről kapják, illetve ide helyezik el az eredményeket is. Az előbbi analógiával élve: a szubrutinok paraméterátadása ezen a stack-en keresztül történik.
Az egyes szavakban a többiek is szerepelhetnek, azaz hívhatják egymást, e "szubrutinhívások" sorozata szükségessé teszi, hogy a visszatérési címeket tároljuk. Erre szolgál a FORTH másik stack-je, a return stack.
A FORTH programozási nyelv saját maga is adott feladatokat elvégző utasításszavak halmaza. Ebből az alapszókészletből kiindulva tudja a felhasználó a kívánt feladatot leírni.
A FORTH alapszókészlete két nagy csoportba osztható.

A felhasználó is alapvetően e két csoportba sorolható utasításokat készíthet. Olyanokat, amelyek gépi kódú törzzsel rendelkeznek, illetve olyanokat, amelyek más utasításszavak meghívását igénylik.
A FORTH működése és utasítás értelmezési mechanizmusa kihasználja az interpreterek és compilerek előnyős tulajdonságait.
Parancsok, műveletvégzések esetén úgy viselkedik a nyelv, mint egy interpreter. Interaktív kapcsolatban van a felhasználóval, értelmezi és végrehajtja parancsait.
Amikor FORTH programot készítünk - utasításszót definiálunk -, a szó végrehajtását lehetővé tevő más utasításszavak végrehajtási címe befordítódik az utasítás törzsébe. Ilyenkor a fordítási tulajdonság az, amely jelentősebb szerepet játszik.
A FORTH programnyelvben nincs GOTO, vagy ennek megfelelő ugró utasítás. Így áttekinthetőbb program írására kényszeríti a felhasználót.
A programtervezés egy felülről lefelé történő feladat analízist kíván meg, azaz meg kell gondolni, hogy milyen részfeladatokra bontható az adott feladat, és azok hogyan bonthatók tovább (felülről lefelé azaz top-down tervezés).
A programozás az elemi feladatok - amelyek tovább már nem bonthatók - alapszókészlettel való leírását, ezzel szavak definiálását jelenti. Ezekből épülnek fel az újabb utasítások, egészen a kívánt feladat megoldásáig. A programozás tehát alulról felfelé halad (alulról felfelé azaz bottom-up megvalósítás).
A programnyelvben nincsenek zárójeles kifejezések, hanem minden műveletet úgynevezett post-fix leírási módban kér a felhasználótól. Ez azt jelenti, hogy például két operandusból és egy műveleti jelből álló művelet esetén a műveleti jelet a két operandus után kell írni. Legyen a két operandus 5 és 3, a műveleti jel +.

Ez a FORTH-beli felirási mód egyértelművé teszi a műveletvégzést, míg a normál felírás (in-fix) esetén a műveleti jelek precendencia szintjei és a zárójelek határozzák meg a műveletvégzés sorrendjét.
Az előbbiből következik, hogy a FORTH-ban műveletvégzésnél nincs zárójelezés. (A zárójelet, alkalmazzuk, de más feladatra.)
A post-fix felírási módot RPN felírási módnak is nevezik (RPN - Reverse Polish Notation - fordított lengyel jelölés).

3.2. A stack-ek
Mint már említettük, a paraméterek tárolása stack-ekben történik. A stack a számítógép memóriájának egy elkülönített része, ahová az utasításszavak elhelyezhetik paramétereikét. A FORTH programnyelvben két stack-et alkalmaznak. Az elsőt paraméter stack-nek, a másodikat pedig return stack-nek nevezik.
Mindkét stack LIFO (Last In First Out) típusú stack. Az ilyen típusú stack-ek olyan elv szerint működnek, mint egy zsák. A zsákban különböző dolgokat egymás után, sorrendben helyezhetünk el. Ha nem turkálunk a zsákban (nem változtatjuk meg a behelyezési sorrendet), akkor fordított sorrendben és egymás után kivehetjük a behelyezett dolgokat. Ez az elv játszik szerepet a FORTH-ban alkalmazott stack-éknél is.
A zsák alját a stack kezdőcímének lehet megfeleltetni. Ha a stack üres, nincs benne adat, a stack aktuális pozícióját mutató címérték a stack kezdőértékével egyezik meg. Ha a stack-ben adatot helyezünk el, a stack aktuális pozícióját mutató címérték elmozdul, és mindig úgy, hogy megmutassa, hogy melyik az a szabad memóriahely, ahova újabb adatot helyezhetünk el.
A stack-be egyszerre mindig csak egy adatot írhatunk be, így a stack "tárolja" a beirt adatok beírási sorrendjét i s.
Az adatok kivételénél fordított a helyzet. A stack-ből kiolvasáskor is mindig csak egy adatot tudunk kivenni, és abban a sorrendben, ahogyan a stack-be bekerültek.
A FORTH-ban a paraméter stack-be adatokat (számokat) az operátori klaviatúráról közvetlenül vihetünk be. Például leütve a

3 [ENTER]

billentyűt a FORTH rendszer OK jelzéssel jelzi, hogy a parancsot végrehajtotta, a paraméter stack-be 3-at helyezett. Ha újabb számot helyesünk el a paraméter stack-ben, például 12-öt, a paraméter stack képe a következő lesz:

3   <- a stack kezdőcíme
12  <-
a stack aktuális pozícióját mutató cím

Tehát az operátori klaviatúrán megadott számok közvetlenül a paraméter stack-be kerülnek.
A paraméter stack-ből a képernyőre kiírhatjuk a benne levő adatokat. Ezt a feladatot egy nagyon gyakran használt FORTH-beli utasítás, a . (pont) végzi el.
Ha klaviatúrán leírjuk a következő utasítássort

. . [ENTER]

akkor a paraméter stack-en szereplő adatokat kiírja a rend-ezer a képernyőre: 12 3. Először a 12-t, mivel ezt helyeztük el a stack-re legutoljára, majd a 3-at, mivel ez volt a stack-ben mélyebben.
Ha közvetlen bekapcsolás után, a rendszer kezdeti állapotában végeztük ezeket a műveleteket, a következő . utasítás már nem talál adatot a paraméter stack-ben. Ezt a hibát, a paraméter stack üres állapotát hibajelzéssel közli m programozóval. Például a

. [ENTER]

utasítást nem fogadja el a rendszer, és hibajelzést ad

?. MSG #1

A hibajelzés száma adja meg a hiba fajtáját, amely a hibalistából visszakereshető, (Az 1. hiba "A paraméter stack üres".) Sok FORTH implementáció már gondoskodik arról, hogy a magyarázatot is kiírja a rendszer, gyakori például, hogy ekkor a "STACK EMPTY" üzenetet kapjuk.
A paraméter stack-ben nagy mennyiségű adat helyezhető el, mivel a stack aktuális pozícióját mutató cím és a FORTH nyelven írt program egymással szemben növekszik.
A FORTH utasítások legtöbbje azonban csak néhány bemeneti paramétert kíván meg, és a kimeneti paraméterek száma sem sok.
Az utasítások egymásba skatulyázott hívásakor sem változik lényegesen a stack mélysége. Kivétel az az eset, ha algoritmikus hibát ejtve nem használjuk fel a paraméter stack-en levő összes adatot bemeneti paraméterként, vagy felesleges adatot hagy a paraméter stack-en utasításunk.
A paraméter stack tartalmát mindenesetre megismerjük, ha kiírjuk tartalmát a . utasítással a képernyőre. Ezzel sajnos el is veszítjük a stack eredeti tartalmát, mivel a . utasítás a kiírt adatot eltávolítja a paraméter stack-ről. Főleg a FORTH tanulásának kezdeti szakaszában nagyon hasznos lehet a paraméter stack kiírása ügy, hogy közben ne változzék meg a tartalma. Bár a FORTH utasításainak definiálásával csak később foglalkozunk, itt ismertetjük az ezen feladatot megoldó utasítás definícióját:

DECIMAL:
: DEPTH ( --- n )
  S0 @ SP@ 2 + - 2 / ;
: S ( --- ) CR
  DEPTH IF SP@ 2 - S0 @ 2 -
  DO I @ U. -2 +LOOP
    ELSE ." empty"
    THEN ;

A .S utasítás kiírja a képernyőre a paraméter stack aktuális állapotát. Az első adat (a kiirt sor elején) a paraméter stack-be legelőször behelyezett adat. A kiírás végén szerepel a paraméter stack-ben legutoljára elhelyezett adatunk.
Előbbi példánknál maradva a

3 12 .S

utasítássorozat eredménye

3 12

lesz.
Arról, hogy a paraméter stack-ben megmaradtak az adataink, a paraméter stack elemeinek kiírásával győződhetünk meg.
A FORTH másik stack-je, az úgynevezett return stack, mint említettük, a visszatérési címeket tartalmazza. A return stack figyelmes használat mellett adatok átmeneti tárolására is használható. Ilyenkor vigyáznunk kell, hogy a return stack-ből ugyanannyi adatot vegyünk ki, mint amennyit előzőleg elhelyeztünk benne. A return stack-ben levő adatokhoz való közvetlen hozzáférés lehetőséget ad számunkra, hogy módosíthassuk a programunk futását.
A return stack-re csak néhány adatmozgató utasítás vonatkozik:

3.3. Utasítások definiálása és felépítése
A FORTH-ban az utasításszavakat kettőspont definíciónak Is szokás nevezni, az új utasításokat definiáló szavak legtöbbje kettősponttal kezdődik. A kettőspont, amely önmaga is egy FORTH utasítás, jelzi a rendszer számára, hogy új utasításszó definíciója kezdődik.
A kettőspont (:) után kell megadni az új utasítás nevét.
A FORTH-ban minden utasítást egy vagy több szóköz (space) karakter választ el egymástól. Így az új utasítás nevét és a kettőspontot is. A szóköz karakter választja el Utasítások nevében a szóköz karakteren kívül tetszőleges betű, szám és írásjel karaktert alkalmazhatunk, nincs megkötés az elnevezés kezdőkarakterére sem. A nevek hossza tetszőleges, a fig-FORTH-ban maximálisan 31 karakter. Az új definíciós szó neve után következik a törzse, amely már definiált utasítások neveit, illetve számokat tartalmaz a végrehajtás sorrendjében.
Az új utasítás szót a ; utasítással fejezzük be. Készítsünk például olyan utasításszót, amely elvégzi a paraméter stack-en elhelyezett szám, mint bemenő paraméter harmadik hatványának kiszámítását. Legyen az utasítás neve KOB. A definíció:

: KOB DUP DUP * * ;

Mivel még nem szerepeltek a paraméter stack adatmanipulációs és aritmetikai utasításai, a DUP és a * utasítások hatását megvizsgáljuk.
A DUP utasítás a paraméter stack-be legutoljára elhelyezett adatot megduplázza a paraméter stack-en. Tehát a

3 DUP . .

hatására

3 3 ok

jelenik meg a képernyőn.
A * utasítás a paraméter stack-ben legutoljára elhelyezett két számot kiveszi a paraméter stack-ből, összeszorozza őket, és az eredményt visszateszi a paraméter stack-be. Például a

3 5 * .

eredménye 15 lesz.
Visszatérve a KOB utasításhoz, ez bemenő paraméterét a paraméter stack-ről várja, így azt a számot, amelynek köbét ki akarjuk számítani, oda kell tenni. (A klaviatúráról beadott szám oda kerül.) A következő példában

4 KOB

nézzük meg, hogy mi történik a paraméter stack-en a KOB-ben szereplő egyes utasítások hatására.

paraméter stack utasítások
4 (kezdeti állapot)
4 4
4 4 4
4 16
64

DUP
DUP
*
*

tehát a képernyőn a .S utasítással a 64 eredményt kell kapnunk.
A fent bemutatott úgynevezett stack diagram jól használható az utasítások működésének vizsgálatához, hibakereséshez.
Az utasításszavak működésének visszaidézéséhez nem mindig elegendő az utasítás neve, hanem tudnunk kell, hogy hány darab paramétert és milyen sorrendben kell megadnunk a működéshez. Az utasítás végrehajtása után kapott, úgynevezett kimeneti paraméterek darabszáma és sorrendje sem mindegy.
A FORTH programban megjegyzéseket, (comment) zárójelek közé helyezve adhatunk meg. A ( ebben az esetben is egy FORTH utasításszó, tehát minimálisan egy szóköz karakternek kell követnie. Az utasításszavak működésének leírásához meg kell adni a bemeneti és a kimeneti paraméter stack képét. A KOB utasítást például a következő módon gépelhetjük be:

: KOB ( n1 --- n2 )
  DUP DUP * * ;

A " --- " jelsor jelzi az utasítás végrehajtását. A bal oldalán az utasítás számára szükséges paraméter stack képet, jobb oldalán pedig az utasítás végrehajtása után kialakult stack képet adjuk meg. Esetünkben a megjegyzés azt mutatja, hogy egy számot vár a stack-ből, és egyet helyez el benne.
Az utasítások definícióját, ha túl hosszú sorokból áll, megszakíthatjuk az ENTER billentyű leütésével, majd a következő sorban folytathatjuk tovább.
Az így definiált utasítások egy rendezett szótárba kerülnek. Ez teszi lehetővé, hogy a későbbiekben elnevezésük alapján bármikor megtalálhatjuk őket.

3.4. A szótár szerkezete
A FORTH rendszerben az egyes utasításszavak egy szótár elemeiként listába szervezetten szerepelnek.
A FORTH rendszerben több szótár is definiálható, de egy utasítás mindig csak egy szótárhoz tartozik. Az utasításoknak két fő része van:

Egy szótáron belül az utasítások a kapcsolási címeken elhelyezett címekkel kapcsolódnak egymáshoz.
A tárolt kapcsolási címek alapján látható, hogy a szótárba újabb elemet a DP-vel jelölt memóriacímnél helyezhetünk el.
A DP jelölés (Dictionary Pointer) egy rendszerváltozót jelent, amely mindig az adott szótárban felhasználható következő szabad memóriacímre mutat. Ez a szótár egyik vége. A szótár másik végét, ahonnan kezdődően nincs további elem a szótárban, a kapcsolási címen tárolt zérus (0) érték jelzi.

3.5. Működési módok
A FORTH rendszer alapvetően két állapotban lehet, a végrehajtási (interpreter) és a fordítási (compiler) állapotban .
A két állapot közötti különbséget a következő példával szemléltethetjük. Végrehajtási állapotban a FORTH rendszer úgy viselkedik, mint egy kalkulátor. A parancsokat, utasításokat azonnal végrehajtja, de nem őriz meg információt róluk.
Ezért a vezérlési struktúrákat, mint például a feltételes elágazás, vagy definiálatlan hosszúságú hurok, nem alkalmazhatjuk végrehajtási állapotban. Ezeknél ugyanis ugrási címeket kellene tárolni, amelyek lehetővé teszik a vezérlés átadását.
Végrehajtási állapotban van a rendszer, amikor végrehajtja például a következő utasítássort:

4 DUP DUP * * .

Ilyenkor az elvégzendő feladat forrásnyelvi szövege a felhasználói klaviatúráról egy pufferterületre kerül, amelynek kezdőcímét a TIB rendszerváltozó tartalmazza. (TIB= Terminal Input Buffer.) Ebből a pufferből dolgozza fel az egyes szóköz karakterrel elválasztott utasítás neveket a rendszer az INTERPRET utasítás segítségével.
Fordítási állapotba kerül a rendszer, amikor a kettősponttal (:) egy új utasításszó definícióját kezdjük el. Előbbi példánkat most kettőspont definícióként megírva, nem történik meg az egyes utasítások azonnali végrehajtása.
A rendszer ilyenkor létrehoz egy névvel rendelkező új elemet, és a végrehajtás csak ezen új definíció nevének megadásakor történik meg.

A kettőspontot (:), mint utasítást, a következő módon hajtja végre a rendszer. Az utasítás a : után következő szóközzel elválasztott névvel felvesz a rendszerbe egy új elemet. Az új elem felvétele az elnevezés és a szótári kapcsolódás címének beállítását jelenti.
A FORTH rendszer, amely elvégzi a kettőspont utasítás hatására ezt a feladatot, a DP rendszerváltozóban megadott címmel jelzi, hogy hol található az első üres felhasználható memóriarekesz a rendszerben. Ide helyezi el az utasítás egyes elemeinek lefordítását elvégző INTERPRET utasítás az új definíciós szóban szereplő szavak végrehajtási címeit. Az INTERPRET egy rendszerváltozó (STATE) segítségével érzékeli, hogy a FORTH rendszer fordítási, vagy végrehajtási állapotban van.
Fordításkor a DP (Dictionary Pointer) változóban tárolt címnél kezdi az új definícióban szereplő utasítások végrehajtási címeit tárolni. Tárolás után mindig beállítja DP értékét, hogy az a következő szabad memóriarekeszre mutasson.
Végrehajtáskor is ez a mechanizmus játszódik le, de az egyes utasítások végrehajtási címe nem tárolódik, hanem azonnal végrehajtja a rendszer a címeken tárolt utasításokat, és ha ezek is összetett utasítások, lebontja a teendőket elsődleges utasításokra.
Az INTERPRET utasítás csak olyan utasításszavakat képes megtalálni, amelyeket korábban definiáltunk. Ezeket az utasításokat az összefűzési rendszer (szótár) segítségével képes egyenként megvizsgálni.
Ha az új definícióban szereplő utasításnevet nem találja meg a korábban definiált utasítások között, akkor megpróbálja számként értelmezni. Ha a névnek feltételezett adat számérték volt, akkor a rendszer állapotától függően végrehajtáskor a paraméter stack-re helyezi, fordításkor pedig úgynevezett literál értékként az új utasítás törzsébe fordítja.
Ha nem értelmezhető számértékként sem az illető utasítás, akkor hibajelzéssel befejezi az utasítás értelmezését.
A számértékeket és a vezérlési struktúrákat két lépésben fordítja le a FORTH rendszer.
Számérték esetén először egy literál értéket kezelő primitív sző kerül az utasítás törzsébe, majd maga a számérték.
Vezérlési struktúra esetén hasonló a helyzet. A vezérlési struktúrát megvalósító primitív utasítás és az utána befordított ugrási cím jelentik az ugró utasítás megvalósítását.

A FORTH-beli fordítási rendszer leírásából látszik, hogy a FORTH-ban megvalósított úgynevezett másodlagos utasítások nem hajthatók végre közvetlenül.
Vizsgáljuk meg a példánkban szereplő KOB utasítást. A memóriában a KOB utasítás a következő módon foglal helyet. (A címértékek 2 byte-on vannak tárolva.)

memóriacímek tartalom  

cím
...
...
...

állapot byte
K
O
B
a név karakterei
... kapcsolási cím a szótár előző eleméhez
...
...
...
...
...
...
:
DUP
DUP
*
*
;
 
DP --->    

A KOB utasítás a : utasítás végrehajtásával kezdődik, amely a jelenlegi végrehajtási állapotban a sorrendben következő utasításnak (DUP) adja a vezérlést. A DUP elsődleges utasítás, tehát gépi kódú utasítástörzzsel rendelkezik, amelyet azonnal végre tud hajtani a számítógép. Hasonlóan végrehajtja a második DUP utasítást is, és ezek után a * következik.
A * másodlagos utasítás, tehát utasítástörzse további utasítások végrehajtásához szükséges címeket tartalmaz. A * utasítás törzsében szereplő adatok nem végrehajtható utasítások, hanem azt adják meg, hogy melyik címen kell folytatni programot.
Ezért meg kell őrizni a másodlagos * utasítást hívó KOB utasításban a végrehajtás folytatását biztosító címet. (A második * utasítás címét.) A visszatérési cím megőrzése a return stack-ben történik. (Más programnyelvek a szubrutinok visszatérési címeit őrzik meg, hogy a program tovább futhasson.)
A vezérlést ezen esetben a másodlagos szó - jelen esetben a * - kapja meg. A * utasítás további másodlagos és elsődleges szavakat. hív meg. A hívott másodlagos szó a * befejezése után a return stack-ből nyert folytatási cím segítségével folytatódik az eredeti utasítás, KOB végrehajtása.
Azok a másodlagos szavak, amelyek más másodlagos szavalat, hívnak, olyan hívási sorozatot hoznak létre, amelynek végén mindig egy elsődleges utasítás áll. Így a másodlagos utasítások hívásának sorozata egy fa struktúrával ábrázolható. A fa belső csomópontjain a másodlagos utasítások, végpontjain pedig elsődleges utasítások vannak. Az utasításszó végrehajtása közben a rendszer ezen a fán megy végig. Barangolása közben a kiindulási adatokat és az eredményeket a paraméter stack-ben, a fán bejárt csomópontok címét a return stack-ben tárolja.

3.6. Számok
A FORTH programnyelv standard utasításkészletében csak egész típusú számokkal való műveletvégzés lehetséges. Hasonlóan a többi magasszintű programozási nyelvhez, a FORTH-ban is el lehet készíteni - az egész típusú aritmetikára támaszkodva - a lebegőpontos aritmetikát. A nyelvben lebegőpontos aritmetikát ritkán alkalmaznak.
A FORTH egész típusú alapegysége a 16 bites adatszó. A paraméter stack-re ilyen nagyságú (bitszámú) adatot helyez el a rendszer, és ilyen értéket képes egyszerre kiolvasni.
A 16 bites adatot kezelhetjük előjelesen (előjel bit + 15 bit információ), vagy előjel nélküli mennyiségként (16 bit információ). (Az előjelet a magasabb helyértékű byte legmagasabb helyértékű bitje tartalmazza).
A FORTH rendszerben, memóriatakarékosság céljából lehet ennél az adattípusnál kisebb, nagyobb pontosságú számítás esetén pedig nagyobb egységekkel is számolni.
A 16 bites adatnál kisebb adatok az úgynevezett byte és karakter típusú adatok, amelyek 8 biten ábrázol hatók. A rendszer az ilyen típusú adatok memóriabeli tárolásakor valóban egy byte nagyságú memóriát foglal el. A paraméter stack-be való beolvasáskor viszont az egy byte-on ábrázolt értéket 16 biten ábrázolt adattá egészíti ki, és műveleteket már ezzel az adattípussal végez.
16 bitnél nagyobb pontosságot megkövetelő feladatoknál a rendszer két, vagy az igénytől függően, több 16 bites adatszót foghat össze, és műveleteket ezen az adatcsoporton végezhet.
Leggyakoribb a két 16 bites adatszóból képzett úgynevezett duplaszavas adat. Ez az adat is lehet előjeles (előjel bit + 31 bit információ), vagy előjel nélküli (32 bit információ). A duplaszavas adatot alkotó két 16 bites szó közül a magasabb helyértékű (HW = High Word) helyezkedik el a paraméter stack tetején, és alatta az alacsonyabb helyértékű adatókat tartalmazó (LW = Low Word). Az előjelet (ha van) a magasabb helyértékű szó legmagasabb helyértékű bitje tartalmazza.
A duplaszavas számok megkülönböztetésül az egyszavas számoktól egy "." (pont) karaktert is tartalmaznak. Tehát a 123 például egy egyszavas szám, de a 123. egy 32 bites kétszavas szám. A "." karakter elhelyezkedése a számon belül nem hordoz információt, nem tizedes pont.

4. Alapvető FORTH definíciók

+, -, /, *, D*, D/, M*, M/, /MOD, *MOD, M/MOD, U*, U/, 1 + , 2+, +-, ABS, MAX, MIN, MINUS, ., DROP, DUP, -DUP, OVER, ROT, SWAP, VARIABLE, CONSTANT, @, !, USER, ALLOT, C!, C@, CMOVE, FILL, ERASE, R>, >R.

Ez a fejezet azokat a FORTH utasításokat mutatja be, amelyek a különböző adattípusokkal való műveletvégzést biztosítják. Szó lesz olyan típusú utasításokról, amelyek általában assembly nyelvekben fordulnak elő, azonban a FORTH-ban magasabb szintű műveletek is elvégezhetők egy paranccsal, Ilyen például a ciklusszervezés.

4.1. Műveletek adatokkal
Korábban már említettük, hogy milyen számtartományba eső számokat kezel a FORTH. A nagyobb számábrázolási pontosság megvalósítása sem lehetetlen. Ehhez az aritmetikai utasítások kombinálásával lehet az értékeket előállítani. Írásban az elvégzendő műveletek kijelölésére általában a következő formát használjuk: 2+3
A számítógép azonban úgy képzi az eredményt, hogy előbb kéri a művelet operandusait (2, 3) és utána a művelet típusát (+, összegzés). Ez az úgynevezett fordított lengyel jelölés és (RPN - Reverse Polish Notation).
A FORTH nyelv alkotója úgy gondolta, hogy ha a programozó eleve RPN-ben írja le a feladatot, az gyorsítja a műveletek végrehajtását, ezért a programozótól meg is követelik ezt a jelölésformát. A hagyományos és az RPN jelölés közötti konverziót azonban más rendszerek is megkívánják a programozóktól, például a Hewlett-Packard kalkulátornak is így kell megadni az elvégzendő műveleteket.
Nézzük meg ezt egy példán!

(24*5)/2-5+10

A számítás lépései a következők:

  1. szorozzuk meg a 24-et 5-tel (részeredmény 120),
  2. osszuk el 2-vel (részeredmény 60),
  3. vonjunk ki az eredményből 5-öt (részeredmény 55)
  4. adjunk hozzá 10-et (eredmény 65)

BASIC nyelven ezt így Írhatjuk le:

24 * 5 / 2 - 5 + 10

FORTH nyelven pedig az RPN felírási formát alkalmazva:

24 5 * 2 / 5 - 10 +

Lépésenként végrehajtva:

  1. A stack-re került két kezdő értéket (24,5) összeszorozzuk, a stack-en, részeredményként 120 marad.
  2. A stack-re felírjuk a következő operandust (2), majd elvégezzük az osztást, ennek hatására a stack-re 60 kerül.
  3. Ezután 5-öt viszünk a stack-re, majd a kivonás műveletet elvégezve a stack-en 55 lesz.
  4. 10-et teszünk a stack-re, és az utolsó műveletet elvégezve a végeredmény 65.

Mivel az aritmetikai műveletek mindig csak a stack tetején levő két értékkel végeznek műveleteket, és az eredményt a stack-en hagyják, így másként is felírhatunk egy kifejezést. Például úgy, hogy felírjuk a stack-re a kifejezés összes operandusát a megfelelő sorrendben, majd a megfelelő műveleteket elvégezzük. Ez a felírási illetve számítási módszer a zárójelek használatát is szükségtelenné teszi.
Vegyük a következő kifejezést:

32 + 4 + 5 * ( 3 + 2 + 5 * 44 )

FORTH nyelven felírva:

32 4 + 5 3 2 + 5 44 * + * +

Vagy másképpen:

32 4 5 3 2 5 44 * + + * + +

4.2. Aritmetikai műveletek
A négy alapművelet (+, -, *, /) a stack-en lévő két előjeles vagy előjel nélküli 2 byte-os (általában 1 gépi számból képezi az eredményt, és azt hagyja a stack tetején. Az osztás és a kivonás sorrendfüggő művelet. ábrázolva például a stack osztási művelet előtti és utáni állapotát:

n1 n2 --- n1/n2

A dupla pontosságú (két gépi szó, két stack elemnek tekinthető) számokra vonatkozó összeadás és kivonás utasítása D+ és D-, az eredmény is dupla pontosságú lesz, azaz két egyszeres pontosságú stack elem ábrázolja. D* és D/ utasítások definiálási lehetősége a következő:

: D* ( d u --- d )
  DUP ROT * ROT ROT U* ROT + ;

: D/ ( d u --- d )
  SWAP OVER /MOD >R SWAP U/ SWAP DROP R> ;

A FORTH nyelv nem törődik azzal, hogy a programozó a számot hány stack elemből állónak, azaz dupla vagy egyszeres pontosságúnak képzeli-e. Így minden hibaüzenet nélkül végrehajtódik egy olyan utasítás, amely egyszeres pontosságú számokat használ operandusként ( + , -, *, /), pedig a stack-re esetleg egy dupla pontosságú számot írtunk be. Hibaüzenet csak abban az esetben keletkezik, ha az utasítás nem talál elég paramétert a stack-en.
Néhány aritmetikai műveletnél az egyszeres és dupla pontosságú számok keverve alkalmazhatóak. Az ilyen utasítások műveleti kódjai a műveleti jelen kívül egy M betűt is tartalmaznak, jelezve a kevert (mixed) számábrázolási módot.
Szükség lehet például arra, hogy két egyszeres pontosságú szám szorzatának eredménye dupla pontosságú legyen. Az ilyen szorzási utasítás neve:

M* (u1 u2 --- d)

Az

M/ (d u1 --- n2 u3 )

utasítás egy dupla pontosságú számot oszt el egyszeres pontosságú számmal. Ennek az utasításnak egyéb specialitása is van. A stack-en lévő eredmény mind a maradékot, mind a hányadost tartalmazza (az említett sorrendben).
Ahhoz, hogy a számolási pontosságot növelni lehessen, létrehozták a */ utasítást. Az utasításhoz tartozó stack diagram:

n1 n2 n3 --- n4

ahol n4 = (n1*n2)/n3

Ez a művelet a szorzás eredményeként 32 bites (egy dupla szó) számot állít elő, amelyet egyszeres pontosságú számmal osztunk el.
Egyes esetekben szükség lehet egy osztás maradékára. Ezt a MOD utasítás adja meg, melynek stack diagramja a következő:

n1 n2 --- n3

Az eredmény (n3) előjele n1 előjelével egyezik, és az n1/n2 művelet, maradékát adja.
Például a

7 3 MOD

parancssorozat eredményül 1-et ad.
A következő utasítás formailag és tartalmilag és tartalmilag is a / és a MOD utasítás kombinációja:

/MOD (n1 n2 --- n3 n4)

ahol n3- maradék, n4 - hányados
A stack az n1/n2 osztás mindkét fajta "eredményét" tartalmazza, az operandusok és az eredmények egyszeres pontosságúak.
A már korábban bemutatott */ utasítás MOD utasítással bővített változata a

*/MOD ( n1 n2 n3 --- n4 n5 )

ahol n4 - maradék, n5 - hányados
Az előző lehetőségek egy kombinált változata:

M/MOD ( ud1 n2 --- n3 ud4 )

ahol

Előjel nélküli számokkal is lehet szorzási és osztási műveleteket végezni. Az előjel nélküli szorzás utasítást

U* ( u1 u2 --- u3 )

a fenti stack állapot (egyszeres pontosságú számokkal), míg az előjel nélküli osztást, az alábbi stack állapot, jellemzi.

U/ ( ud1 u2 --- u3 ud4 )

Az osztásnál:

Az aritmetikai utasításokhoz sorolhatjuk még az 1+ és a 2+ utasításokat. Ezek a stack-en levő értéket növelik 1-gyel, illetve 2-vel.
A +- utasítás, melynek stack diagramja:

n1 n2 --- n3

a stack tetején levő szám (n2) előjelét az ellenkezőjére változtatja, ha az n1 szám előjele negatív. Az eredmény n3 az n2 új előjeles értéke.
Az ABS utasítás a paraméter stack-en lévő érték abszolút értékét képzi.
A MINUS utasítás a stack-en levő szám előjelét fordítja az ellenkezőjére.
A MAX és MIN utasítások a stack-en található két érték közül a nagyobbikat, illetve a kisebbiket, hagyják a stack-en eredményül.
Az ismertetett utasítások hatásának szemléltetése:

Utasítás stack a művelet előtt
stack a művelet után
megjegyzés
* 9 6 2
9 12
előjeles szorzás
/ 9 6 2
9 3
előjeles osztás
ABS 9 -6 -2
9 -6 2
abszolút érték
MAX 9 6 2
9 6
két szám közül a nagyobbik
MIN 9 6 2
9 2
két szám közül kisebbik
MINUS 9 6 2
9 6 -2
kettes komplemens
+- 9 6 -2
9 -6
 
MOD 9 6 2
9 0
osztás maradékot képez
*/ 9 6 2
27
(9*6)/2
*/MOD 9 6 2
27 0
(9*6)/2 = 27 és a maradék
/MOD 9 6 2
9 0 3
6/2=3; maradék = 0

4.3. Stack-kezelő (adatmozgató) műveletek
Az e csoportba tartozó utasítások a stack-en található adatokkal végeznek olyan egyszerű műveleteket, amellyel egy korábbi utasítás eredményét (stack állapotát) a következő utasítás igényeinek megfelelően átrendezhetjük.
A stack-ről kétféleképpen, a DROP és a . (print, kiírás) utasítással lehet adatot eltávolítani. Az előző a stack tetején lévő adatot eldobja, míg a második a kimeneti egységre kiírja a stack-ről. A stack legfelső elemét a DUP utasítással duplikálhatjuk. Ez például az előbbi kiírás előtt hasznos lehet, ha később még szükségünk van az adatra.
A DUP utasításnak van egy feltételes változata a -DUP utasítás. Ez csak akkor duplikálja a stack legfelső elemét, ha az nem nulla. Ha nulla, nincs hatása.
Az OVER utasítás is felfogható egy speciális duplikáló utasításnak. Ez azonban nem a stack tetején lévő értéket sokszorozza, hanem az alatta levő értéket másolja a stack tetejére. A stack:

n1 n2 --- n1 n2 n1

A SWAP utasítás a stack tetején lévő két érték sorrendjét cseréli fel:

n1 n2 --- n2 n1

A ROT utasítás a stack tetején lévő három adatot forgatja meg a következő módon:

n1 n2 n3 --- n2 n3 n1

összefoglalva a fejezetben szereplő utasításokat:

Utasítás stack a művelet előtt
stack a művelet után
megjegyzés
. 1 2 3
1 2
kiiratás
DROP 3 2 1
3 2
eldobás
DUP 3 2 1
3 2 1 1
megduplázás
-DUP 3 2 1
3 2 1 1
 
-DUP 3 2 0
3 2 0
 
OVER 3 2 1
3 2 1 2
 
ROT 4 3 2 1
4 2 1 3
 
SWAP 3 2 1
3 1 2
csere

4.4. Memóriakezelő utasítások
Más magasszintű nyelvekhez hasonlóan a FORTH-ban is szükség van a változók definiálásának lehetőségére, használatára.
A változó a memóriának egy elkülönített része, amelyben információt tárolhatunk, és erre az adatra a változó nevének leírásával hivatkozhatunk.
A változó definiálásának módja a FORTH-ban:

n VARIABLE név

Például: 0 VARIABLE TAROLO

Ahol n a változó kezdő értéke.
Amikor egy változót definiálunk, egy újabb szótári elemet (kulcsszót) alkotunk a megadott névvel. Ezen kulcsszónak azonban nem lesz kód része, hanem a fordítási fázis folyamán helyet foglal a rendszer az n (érték) számára, majd amikor a változó nevét leírjuk - a kulcsszóban tárolt Változó memóriacímét kapjuk meg a paraméter stack-en.
A változó kezelését a ! (store, tárolás) és a @ (fetch, behozás) utasítás teszi lehetővé. A tároláshoz két dolgot kell tudni: mit, és hova kell tárolni. Ennek megfelelően az utasítás formája:

érték cím !

Például: 20 TAROLO !
Ha közvetlen módon címezzük a memória bármely helyét, az utasítás ugyanígy működik, például: 20 5015 !

A példa szerint az 5015 (decimális) címre tároljuk a 2 byte-on ábrázolt 20 értéket. Ebben az esetben az 5015 címen helyezkedik el a 20, és az 5016-os címre 0 kerül.
A tároló utasítás párja a @. Adott cimről a paraméter stack-re teszi a címen található értéket. Például a

TAROLO @

Utasítás végrehajtása után a stack tartalma a TAROLO által meghatározott cím tartalma, előző példánknál maradva 20.
A @ utasítás stack diagramja a következő:

cím --- n

tehát, a címet eltávolítja a paraméter stack-ről, és a címen lévő értéket helyezi oda. A cím vagy abszolút memóriacím, vagy változó névvel kifejezett szimbolikus cím lehet.
A változó mellett szükség van konstans definiálási lehetőségre is. A definiálás szintaxisa hasonló, mint változó esetében:

n CONSTANT név

Hatását a következő három lépés írja le (ezeket a rendszer hajtja végre):

Végrehajtási állapotban az érték (amely a definícióval létrehozott szótári elem egyetlen paramétere) előhívása másképp történik, mint a változók esetén. Mivel a CONSTANT paramétere nem változik így a "név" utasítás magát a paraméter értékét - a konstans értéket - teszi a paraméter stack-re (és nem a címet).
Igaz ugyan, hogy aki a konstans definícióját használja, az nem kívánja megváltoztatni a konstans értékét, a FORTH mégis biztosit lehetőséget ilyen ritka igényekre is. A következő utasítássorozat konstans értékének megváltoztatását teszi lehetővé:

n ' név !

A FORTH rendszer működéséhez szükség van néhány előre definiált konstansra és változóra. Ezek részletes leírását az adott implementációhoz készült kezelői leírás tartalmazza. Ezek tartalmához is az előbb említett módokon lehet hozzáférni.
A FORTH biztosit még egy speciális változó definiálási lehetőséget: ez az úgynevezett USER (felhasználói) váltózó. Definiálási módja:

b USER név

A változó paraméter mezeje tartalmazni fogja a definíció hatására b-t, amely egy rögzített eltolási (offset) érték. Ez mondja meg, hogy a USER típusú változók számára fenntartott memóriaterület kezdőcíméhez mennyit, kell hozzáadni, hogy a változó címét megkapjuk. A "név" utasítás végrehajtásakor az eltolási cím és a USER típusú változók kezdőcímének összege adja a változó tárolási címét.
A rendszer saját maga lefoglalja az összes ilyen típusú változó területet, és nem is engedi bővíteni. USER típusú változóból 30-at tart fenn a FORTH, és ezekben a saját működéséhez szükséges változókat tárolja. Amennyiben hasonló szerkezetet akarunk előállítani, a FORTH utasítások lehetőséget biztosítanak ehhez. Ennek például olyankor van jelentősége, ha a FORTH-ban megírt programunk ROM-ban fut, és a RAM-ban elhelyezkedő változókat el kell választani a programtól.

A fejezetben szó volt olyan utasításról (VARIABLE), amely változó számára foglal le 2 byte memóriaterületet (byte szervezésű gépeknél, egyébként, egy gépi szót). Szükség lehet azonban vektorokra, mátrixokra is. Erre szolgál az ALLOT utasítás. Az utasítás a paraméter stack tetején talált előjeles számot a Dictionary Pointer (DP) értékéhez hozzáadja. Ezzel memória helyfoglalást biztosit, ha n pozitív, és a már korábban a szótár által lefoglalt memóriaterület újracímzését teszi lehetővé, ha n negatív. Használata:

0 VARIABLE név n ALLOT

0 kezdőértékkel lefoglalunk egy változót, és n értékével megváltoztatjuk DP értékét. A következő definíciós szó már a növelt DP értéket kapja meg, és nem tud arról, hogy közben "rés" támadt a kulcsszavak definiálási sorában. Felmerülhet azonban a kérdés, hogy ebből az n byte hosszú memóriaterületből hogyan lesz mátrix vagy vektor? A változó neveként megdott névvel hivatkozhatunk egy ilyen nevű mátrixra is, a következő módon:
Megadva a nevet, a paraméter stack-en megkapjuk a legelső memóriacella címét. Ennek alapján kiszámolható az n-edik sorban és m-edik oszlopban álló mátrixelem memóriacíme, amely majd a ! vagy @ utasítások bemenő paramétere lehet. Például egy sorfolytonosan tárolt 5 x 5-ös mátrix 3. sorának 4. elemét a következő számítással kaphatjuk meg:

3*(5*2)+4*2+cím

ahol cím a változó címe (név). Az adatok 2 byte-os helyfoglalása miatt szükséges a kettővel való szorzás - egy adat 2 byte-ot foglal.
Így egy sor esetünkben 5*2=10 byte hosszú.
Meg kell jegyezni, hogy a VARIABLE utasítás egy 2 byte-os helyfoglalást már biztosított, mielőtt az ALLOT utasítás végrehajtódott.
A következő két utasítással is a DP értékét növelhetjük. A , és C, utasítás csak a stack-ről felvett paraméter méretében különbözik. Mindkettő a stack-ről vesz egy számot, beírja a következő, a DP által kijelölt szabad memóriahelyre, majd növeli a DP értékét, kettővel (,), illetve eggyel C, .
A 2 byte-os adatokat kezelő utasításokon kívül szükség van olyan utasításra, amely egy byte-ot (egy ASCII karaktert) is képes a memóriába írni, illetve onnan olvasni. Erre szolgál a C! és a C& utasítás.

C! ( b cím --- )

C@ ( cím --- b )

Működésűk egyezik a @ illetve ! utasításokéval, kivéve, hogy egy byte-os adatokat kezelnek.
Az előző utasítások a memória 1 vagy 2 byte-os adatokkal való felülírását biztosították. A memória tartalma a +! utasítással módosítható:

+! ( n cím --- )

Ez az utasítás a stack-en található cím tartalmához hozzáadja a stack második legfelső értékét (n).
Memóriakezelő utasítások közé tartozik a CMOVE, FILL, ERASE is. Ezekkel az utasításokkal a memória nagyobb blokkját (területét) lehet egyszerre kezelni. Funkciójuk a következő:

CMOVE - memóriablokkot másol byte-onként egy másik memória területre: ( cím1 cím2 n --- )

ahol

A cím1 és cim2 megfelelő megválasztásával akár egymást átfedő területekről is lehet másolást végezni.

A FILL utasítás ( cím1 n b --- )

adott karakterrel (b) feltölti a cím1-től kezdődően az n byte hosszú memóriaterületet.
Természetesen az előző utasításoknál a stack-re nem kell előre definiált számokat beírni, hanem lehetnek számolt, más utasítások kimenő adataként megkapott címek, paraméterek is.
Az ERASE utasítás egy speciális FILL utasítás. A címmel, hosszúsággal ( cím n --- ) megadott területeket 0-val tölti fel. Például az

5000 100 ERASE

az 5000-es címtől 5100-ig tölti fel a memóriát nullával.

4.4. Return stack műveletek
Amint már említettük, a return stack feladata a visszatérési címek tárolása. Egyes rutinoknak időnként szüksége lehet átmeneti adattárolókra, amelyek gyorsan elérhetőek, és nem kell külön definícióval helyet foglalni számukra. Erre megfelelő a return stack, de biztosítani kell, hogy a rutin befejezésekor az eredeti stack állapot visszaálljon, hogy a következő utasítást a rendszer megtalálhassa. Ezért két utasítást definiáltak, amelyek a return és az adat stack között gyors adatforgalmat biztosítják.
A >R ( n --- ) utasítás a paraméter stack-ről egy értéket átír a return stack-re.
Az előző utasítás párja R> ( --- n ), a return stack- ről írja át az értéket a paraméter stack-re.
Egy definíción belül a két utasítást párban kell használni, hogy a return stack-en a definiált szó végrehajtása után fennmaradjon a korábbi állapot (stack egyensúly).

5. Vezérlési struktúrák

IF, THEN, ELSE, AND, OR, XOR, <, >, =, 0=, 0<, BEGIN, UNTIL, WHILE, REPEAT, AGAIN, DO, LOOP, +LOOP

Ebben a fejezetben a strukturált programozást elősegítő utasításokról lesz szó. Ide tartozik a feltételes végrehajtás-vezérlés és a ciklusszervezés. A FORTH-ból hiányzik egy, a legtöbb magasszintű nyelvben megtalálható utasítás: a GOTO. Ez a hiány kényszeríti a programozót - ha esetleg nem lenne hajlamos rá -, hogy strukturált modulokból építse fel a programját, és ezeket a kipróbált modulokat fűzze fel egymás után, így építve fel az adott feladatot elvégző programját.
Az ebben a fejezetben ismertetésre kerülő struktúrák IF-ELSE-THEN, BEGIN-UNTIL, BEGIN-WHILE-REPEAT, DO-LOOP stb. mind csak kettőspont definícióban szerepelhetnek (: és ; utasítások között), így klaviatúráról közvetlenül nem használhatóak.

5.1. Logikai reláció és függvények
A FORTH-ban logikai értékekkel is végezhetünk műveleteket. Ezeket az értékeket flag-nek nevezzük. A flag olyan szám amelynek zérus illetve nem-zérus volta logikai hamis illetve igaz állapotot tükröz.

A logikai eredményt adó utasítások a stack-re helyeznek 0 vagy nem 0 számot, a logikai értéket váró utasítások pedig egy a stack-en levő számot értelmezik logikai értékként.
A FORTH logikai utasításai a következőek, az igazságtáblával ábrázolva:

AND 0 0
0 1
1 0
1 1
---
---
---
---
0
0
0
1
OR 0 0
0 1
1 0
1 1
---
---
---
---
0
1
1
1
XOR 0 0
0 1
1 0
1 1
---
---
---
---
0
1
1
0
NOT 0
1
---
---
1
0

A NOT a 0= utasítással végezhető el.
A FORTH-ban megvalósított logikai relációk táblázatosán összefoglalva magyarázó példával:

Utasítás
A stack állapota a művelet
  Megjegyzés
 
előtt
után
   
< 9 6 2
9 0
  összehasonlítás - kisebb
> 9 6 2
9 1
  összehasonlítás - nagyobb
= 9 6 2
9 0
  egyenlőség vizsgálat
0= 9 6 2
9 6 0
  egyenlő-e nullával
0< 9 6 2
9 6 0
  negatív szám-e, ha igen = 1

Mint láthatjuk a logikai műveletek az operandusaikat a stack-ről veszik, és eredményüket oda teszik vissza. A stack többi paramétere változatlan marad.

5.2. Utasítások feltételes végrehajtása ( IF-THEN struktúra)
A más magasszintű nyelvekből megismert feltételes elágaztatásnak csak a szintaktikai formája új a FORTH-ban:

f IF utasítások1 THEN utasitások2

Amikor az IF utasításra kerül a vezérlés, a stack-en levő flag f állapota szerint, ha a flag igaz, akkor az "utasítások1" az "utasitások2" előtt végrehajtódnak, egyébként, ha a flag hamis, akkor az IF és THEN közötti utasításokat a vezérlés átugorja, és azonnal a THEN utáni utasításra ("utasítások2") kerül a vezérlés.
A következő struktúra kettős elágazást biztosít:

f IF
    utasítások ( flag=igaz esetnén hajtódik végre )
ELSE
    utasítások ( flag=hamis esetén hajtódik végre )
THEN

A forrásnyelvi programban tetszőlegesen tagolhatjuk a vezérlési struktúrákat space-szel, soremeléssel, és így a program áttekinthető lesz.
Megengedett az egymásba ágyazott IF konstrukció is, például:

f1 IF
    f2 IF
        utasítások ( f2=igaz, f1=igaz)
    ELSE
        utasítások ( f2=hamis, f1=igaz )
    THEN
ELSE
    utasítások ( f1=hamis )
THEN

Természetesen a második IF-ELSE-THEN struktúra is a stack-ről kapja a flag-et, tehát ez az összetett IF egyszerre két számot, mint logikai értéket használ fel a stack-ről.

5.3. Határozatlan ciklus szervezési lehetőségei (BEGIN-UNTIL struktúra)
A BEGIN kulcsszó segítségével határozatlan ciklust (indefinite loop) szervezhetünk. A határozatlanság azt jelenti, hogy a ciklusba való belépéskor nem ismert, hogy hányszor hajtódik majd végre a ciklus, ez valamilyen kilépési feltételnek a függvénye.
A FORTH biztosítja a végtelen ciklus szervezési lehetőségét a következő utasítással:

BEGIN utasítások AGAIN

Persze azért van mód kilépésre ebből a végtelen ciklusból a BYE, COLD, WARM, QUIT, ABORT (vagy az R> DROP) utasítások valamelyikével. Ezek az utasítások azonban mind megszakítják a program futását, a BYE visszatér az operációs rendszerbe, a többi utasítás különféle inicializálásokat végez (lásd a részletes ismertetésnél), kivétel az R> DROP.
Feltételtől függő kilépést biztosit a

BEGIN utasítások f UNTIL

szerkezet. Az "utasítások" egy flag-et (f) hagynak a stack-en. Ha a flag hamis, a hurok ismétlődik, azaz a BEGIN utáni utasításra kerül ismét a vezérlés, ellenkező esetben az UNTIL-t követő utasításra.
A harmadik szerkezet:

BEGIN utasítások1 f WHILE utasítások2 REPEAT

Először "utasítások1" hajtódik végre, majd a WHILE utasítás megvizsgálja a stack-en tárolt logikai értéket (f), amíg az igaz, "utasitások2" majd ismét "utasítások1" kapja meg a vezérlést, ezután a WHILE utasítás ismét elvégzi a logikai vizsgálatot. Amint a flag értéke hamis lesz, a ciklus befejeződik, és a vezérlés a REPEAT utáni utasításra kerül. A flag-et vagy az "utasítások1"-gyel, vagy az "utasítások2"-vel jelzett utasítások beállíthatják.

5.4. Ciklusszervező utasítás (DO-LOOP struktúra)
Ezt az utasítást másképpen határozott huroknak (definite loop) is hívják a FORTH terminológiában. Ennek segítségével előre meghatározott számú lefutást biztosíthatunk egy utasítássorozat számára.
Az utasítás formája:

limit kezdőérték DO utasítások LOOP

A "kezdőérték" a ciklus kezdőértéke. Mindkét értéket felírja a rendszer a return stack-re, amikor a DO utasítás végrehajtódik.
A LOOP növeli a ciklusváltozó értékét eggyel - amely kezdetben a kezdőérték volt, - és összehasonlítja a limittel. Ha a két érték egyezik, illetve a ciklusváltozó nagyobb a limitnél, akkor a rendszer nem engedi vissza hurokba, hanem a LOOP utáni utasításnál folytatja a programot. Például, ha egy utasítást ötször akarunk végrehajtani a következő limit és kezdőértékeket kell beállítani:

6 1 DO utasítás LOOP

vagy

5 0 DO utasítás LOOP

vagy pl.

8 3 DO utasítás LOOP

Szükség van egy olyan utasításra, amellyel a ciklusváltozó aktuális értékét megkérdezhetjük, vagy másképpen fogalmazva a return stack-ről átmásolhatjuk a paraméter stack-re. Ez az I utasítás. Például a

: CIKLUS1 5 0 DO I . LOOP ;

definíció végrehajtása a következő eredményt adja: 0 1 2 3 4 ok
A következő példa:

: CIKLUS2 -1 -6 DO I . LOOP ;

Ennek futtatása: -6 -5 -4 -3 -2 ok

A ciklus paramétereit a definíción kívül, futáskor is beállíthatjuk:

: CIKLUS3 DO . LOOP ;

A rutin hívása a következő lehet:

5 0 CIKLUS3

A futtatás eredménye ugyanaz, mint CIKLUS1 esetében.
A második példából láthatóan negatív számok is lehetnek a ciklus bemenő paraméterei. Ekkor azonban vigyázni kell arra, hogy a limit nagyobb legyen, mint a kezdőérték. Például a

: CIKLUS4 -2 -1 DO I . LOOP ;

definíció végrehajtásakor csak a -1 számjegyet fogja kiírni a rutin, mivel a ciklusváltozó az első végrehajtás után nagyobb lesz, mint a limit értéke.
Amennyiben DO-LOOP ciklusokat egymásba akarunk skatulyázni, a belső ciklus változóinak értékét is a paraméter stack-re kell helyezni:

limit1 kezdőérték1 DO limit2 kezdőérték2 DO utasítások LOOP LOOP

A kezdőérték a return stack-en a ciklusváltozóvá válik. A fentii struktúra esetén a return stack-en a következő állapotul állapotot találjuk a belső hurokban:

limit1 ciklusváltozó1 limit2 ciklusváltozó2

ahol ciklusváltozó2-t akár az I akár az R> utasítással megkaphatjuk. De vigyázat: az I utasítás átmásol - a return stack-et változatlanul hagyja -, míg az R> átír - nem marad meg a return stack-en a ciklusváltozó2. Tehát, ha ciklusváltozó1-hez akarunk hozzáférni, el kell távolítanunk a felette levő értéket, majd visszaállítanunk az eredeti állapotot.
A következő szerkezet tetszőleges nagyságú léptetést enged meg:

limit kezdőérték DO utasítások növekmény +LOOP

A számláló cikluslépésenként a növekmény értékével növekedik. A +LOOP utasítás a LOOP-hoz hasonlóan működik, és ugyanúgy nem szükséges, hogy a kilépéskor pontosan egyezzen a ciklusváltozó a limittel, ha nagyobb nála, akkor is kilép a vezérlés a hurokból.
Mód van arra is, hogy egy meghatározott feltétel teljesülése esetén ne folytassuk tovább a ciklust, hanem kilépjünk belőle. Erre szolgál a LEAVE utasítás. Az utasítás a ciklusváltozó értékét egyenlővé teszi a limittel, és amikor a LOOP illetve a +LOOP utasítás vizsgálja a stack-állapotot, már a kilépési feltételnek megfelelő return stack állapotot, találja, és kilép a ciklusból.
A fejezetben ismertetett vezérlési szerkezeteket tetszőleges mélységben egymásba lehet skatulyázni. Ezen szerkezetek mindegyike használja a return stack-et, oda jegyzi be az utasítások visszatérési címét, valamint a ciklusok működéséhez szükséges paramétereket. Emiatt csak szabályosan egymásba skatulyázott rutinok képesek hibátlanul lefutni.
Helytelen a következő egymásba skatulyázott hurok ét feltételes utasítás:

IF 10 0 DO ... THEN LOOP

A helyes változat:

IF 10 0 DO ... LOOP THEN

Végezetül még egyszer felhívjuk a figyelmet arra, hogy fejezetben szereplő utasítások csak definícióban használhatók.

6. Adatbehozatali és adatkiviteli műveletek

EMIT, ., KEY, .", EXPECT, TYPE, P@, P!, BLOCK, B/SCR, B/BUF, EMPTY-BUFFERS, SAVE-BUFFERS, FLUSH, UPDATE, BUFFER, LIST, LOAD, SCR, INDEX, -->, ;S, INPUT, DINPUT, <#, #>, #, HOLD, ASCII, #S, (, ), SIGN, SPACE, SPACES, .R, S->D, D.R, ERROR, WARNING, MESSAGE, D., U., CR, ?TERMINAL

A FORTH a többi programozási nyelvhez hasonlóan külön utasításcsoporttal (definíciós szavakkal) valósítja meg az adatbeviteli és -kiviteli utasításokat.
A legfontosabb az elsődleges perifériákkal (operátori klaviatúra és képernyő) kapcsolatos adatátvitel, hiszen itt zajlik a programozás és a rendszerépítés legtöbb művelete.
Biztosítani kell ezen felül a másodlagos perifériák csoportjába tartozó berendezések, így a printer, és a háttérmemóriaként szolgáló diszk vagy szalagtároló működtetéséhez szükséges utasításokat is.
Az adatbeviteli és -kiviteli utasítások harmadik csoportjának a FORTH rendszerhez csatolt egyéb - berendezések működtetését kell lehetővé tennie.
Szintén az adatforgalmat biztosító utasítások közé lehet sorolni a hibajelzések kibocsátását illetve a hiba kezelését.

6.1. Numerikus adatbeviteli utasítások
A numerikus adatok bevitele - mint ahogy azt a korábbi fejezetekben láthattuk - rendkívül egyszerű. A számadatok a klaviatúrától a paraméter stack-be kerülnek, és jelentésük, illetve az általuk képviselt érték a BASE rendszerváltozótól függ.
A BASE változó tartalmazza az alkalmazott számrendszer alapját. A rendszer "hideg indítása" után a BASE tartalma általában 10, azaz decimális számrendszerben indul. E változó értékét bármikor megváltoztathatjuk. A BASE maximális értéke általában 36, ebbe tartozik az összes szám és az összes betű.
Például az alkalmazott számrendszert, hexadecimálissá a következd definíciós szó segítségével alakíthatjuk át:

DECIMAL
: HEX 16 BASE ! ;

A HEX szó begépelése után a számalap hexadecimális marad, amíg meg nem változtatjuk.
Az alap utasítások között szerepel a DECIMAL szó, amely a számalapot az alapértelmezésnek megfelelő decimálisra változtatja.
A számadatok közvetlen begépelésén túl szükség lehet a BASIC nyelv utasításai között szereplő INPUT utasításhoz hasonló adatbevitelre. FORTH-ban 16 bites előjeles számok bevitelét az INPUT definíciós szó, a 32 bites előjeles számok bevitelét pedig a DINPUT biztosítja.

: DINPUT ( --- d )
  PAD 1+ 64 EXPECT .0 PAD (NUMBER) DROP ;
: INPUT DINUT DROP ; ( --- n )

6.2. Numerikus adatkiviteli utasítások
A számadatokat a paraméter stack-ből a . utasítással írhatjuk ki a képernyőre. A . utasítás a paraméter stack legtetején szereplő adatot írja ki.
Ha üres paraméter stack-ből próbálunk adatot kiírni., a rendszer a képernyőre hibaüzenetet ad.
A . utasítás egyszeres pontosságú, azaz 16 bites előjeles szám kiírását teszi lehetővé. Egyes feladatoknál szükséges lehet, hogy a 16 bites számot úgynevezett előjel nélküli formában értelmezve írjuk ki. Erre szolgál az U. utasítás.
A dupla pontosságú (előjeles 32 bites) adatok kiírását a D. utasítás végzi el.
Az idáig felsorolt, utasítások mindegyike a BASE változó tartalmától függő számalapnak megfelelően írja ki a paraméter stack-ben lévő adatot. Így a következő példában bemutatott számkonverter elvégzi a tetszőleges számalapból tetszőleges számalapba való konverziót.

n1 BASE ! n2 n3 BASE ! .

ahol

Figyelem: a művelet befejeztével a számalap n3 marad.
Mindhárom ismertetett adatkiviteli utasításra érvényes, hogy a kiirt adat után egy szóközt (space) karaktert is írnak.

6.3. Numerikus adatok formátum szerinti kivitele

6.3.1.Tabulált kiírás
A tabulált adatkivitel a táblázatok, diagramok, mérési eredmények adott képernyőpozícióra történő kiírásához szükséges.
Egyszeres pontosságú adatok tabulált kivitelére szolgál a .R utasítás. A .R működéséhez szükséges paraméter-stack képet a következő módon adhatjuk meg ( n1 n2 --- ) , ahol n1 a kiírandó szám, n2 pedig azt a mezőszélességet jelöli, amelynek jobb szélére illesztve történik meg a kiírás.
Például:

157 5 .R

A tabulált adatkivitel nem visz ki szóköz karaktert a kiirt adat után.
Ha a megadott mezőszélességbe nem fér el az adat, vagy negatív számot adtunk meg mezőszélesség paraméterként, a tabulációt nem végzi el a rendszer, és "felborul" a tabulált kiírási formátum.
Hasonló módon tabulált formátumban írhatók ki a dupla pontosságú adatok is a D.R utasítás segítségével, melynek paraméter stack képe a következő: ( d n --- ), ahol d a kiírandó adat, n pedig a mezőszélesség, ahová ki akarjuk írni az adatot.

6.3.2. Formátum szerinti kiírás
A számadatok adatformátum szerinti kiírására szintén alapdefiníciós szavakat biztosit a rendszer. Ezek a következők: <#, #, #S, #>, HOLD, SIGN, S->D.
A nem minden rendszerben található ASCII utasítás definícióját is itt fogjuk megadni.
Az előbbiekben felsorolt utasítások segítségével dupla pontosságú adatok formázott kiírását, valósíthatjuk meg. Lehetőségünk van egyszeres pontosságú adatok, formázott kiírására is, de ezeket először az S->D utasítással (Single to Double) egyszeres pontosságúból kétszeres pontosságúvá kell alakítanunk.
A <# utasítás a formázott adatkivitel kezdetét jelző utasítás. Feltételezi, hogy egy dupla pontosságú adat van a paraméter stack-en.
Ezután a # utasítással a paraméter stack-en lévő adatból egy számjegynek megfelelő értéket átalakít kiírható karakterré, és ezt elhelyezi egy kimeneti pufferben. A # a kiírandó számjegy legkisebb helyértéken szereplő számra végzi el az átalakítást. Így a 312 számból az első # a 2-t teszi a pufferbe, a második # az 1-et és a harmadik # helyezi el a 3-nak megfelelő elő karaktert.
A #S a számból esetlegesen megmaradt számjegyeknek megfelelő karaktereket helyezi el a kimeneti pufferben.
A HOLD segítségével megadott kódú karaktereket lehet a kiíratási formátumban elhelyezni. Például a 46 HOLD egy (.) karaktert helyez el a kimeneti pufferben a következő üres helyre.
A kiírandó szám előjeleként szereplő "-" karaktert a SIGN utasítással helyezhetjük el.
A #> utasítás a formázott számkivitel záró utasítása, amely a formátum szerint rendezett adatokból előállított string kezdőcímét és hosszát helyezi el a paraméter stack-en. A formázott számot a TYPE utasítással írhatjuk ki.
Az ASCII utasítás a HOLD utasítás használatát segíti elő. Nem mindig áll rendelkezésünkre kódtáblázat, amelyből a kiírandó karakterek kódját, meg lehet, határozni. Az ASCII utasítással közvetlenül lehet egy karakterhez tartozó belső kódot meghatározni.
Az ASCII definíciója a következő:

: ASCII ( --- n )
  BL WORD HERE 1+ C@
  STATE @ IF [COMPILE] LITERAL THEN
; IMMEDIATE

így azonos hatású a

42 HOLD és az ASCII * HOLD

A következő példák a formált adatkivitelt mutatják be.

a.) Írassuk ki a paraméter stack-en lévő adatot, mint egy órából, percből és másodpercből álló számhármast, a ":" karakterrel elválasztva.

DECIMAL
: KEP1 ( d--- )
<# # # 58 HOLD # # ASCII : HOLD #S #> ;

123456. KEP1 TYPE

b.) Írassuk ki az egyszeres pontosságú előjeles számot, úgy, hogy a legkisebb két helyérték elé Írjunk ki egy tizedes pontot.

DECIMAL
: KEP2 ( n --- )
  DUP ABS S->D
  <# # # ASCII . HOLD #S SIGN #> ;

A különböző adatok kiírása a definíció segítségével:

12345 KEP2 TYPE<CR>123.45ok
    0 KEP2 TYPE<CR>0.00ok
 -199 KEP2 TYPE<CR>-1.99ok

A KEP2 definíciós szóban két apró eltérés van a KEP1-hez. képest. Mivel egyszeres pontosságú szóból indulunk ki, az S->D utasítással át kell alakítanunk a számot dupla pontosságúvá. A másik változtatás az előjel megállapítása miatt történt.
A SIGN utasítás a paraméter stack-en talált szám előjelének megfelelően helyez el a kimeneti pufferben egy "-" karaktert. Pozitív szám esetén nem tesz szóköz (space) karaktert a kimeneti pufferbe.
A SIGN utasítást a formázásban legutoljára kell alkalmazni, mivel a kimeneti puffer utolsó utasításaként kell elhelyezkednie az előjelnek, és ezt írja ki majd először a TYPE utasítás.

6.4. Karakteres adatbeviteli utasítások
A karakteres beviteli utasítások a klaviatúráról érkező string információ bevitelét teszik lehetővé.
Egyetlen karakter klaviatúráról való bevitele a KEY ( --- c ) utasítással történik. Végrehajtás esetén, vagy ha definíció végrehajtása közben a KEY utasításhoz érkezik a rendszer, akkor jelzi, hogy adatbevitelre vár. A klaviatúrán leütött karakter belső kódja a paraméter stack-re kerül, és az utasítás végrehajtása befejeződik.
Ez az utasítás csak egyetlen karakter bevitelét teszi lehetővé.
Ha csak azt akarjuk megvizsgálni, hogy a klaviatúrán történt-e leütés az utasítások végrehajtás közben, azt a ?TERMINAL utasítással tehetjük meg. Az utasítás egy logikai értéket hagy a paraméter stack-en, amely igaz értékű, ha volt leütés, és hamis ha nem. A vizsgálat alatt nem állítja meg a programot.
String-et a rendszernek az EXPECT utasítás segítségével lehet megadni, stack diagramja a következő ( cím n --- ). A cím paraméter az a kezdőcím, ahonnan a beolvasott karaktersorozatot tárolja az utasítás. Az n a maximálisan beolvasható karakterek számát, adja meg. A művelet vagy addig tart, amíg <CR>-et nem adunk, vagy n darab karakter beolvasásáig.
Például:

DECIMAL 42000 13 EXPECT

programrészlet a klaviatúrán leütött karaktereket a 42000 (decimális) címtől kezdődően tárolja, közben az operátori képernyőre is kiírja. Ekkor például az EZ IGY HOSSZU SZOVEG
20 karakter hosszúságú string-ből az EXPECT utasítás csak 14 karaktert tárol, tehát ezt: EZ IGY HOSSZU

6.5. Karakteres adatkiviteli utasítások
A karakteres beolvasó utasítások mindegyikének van adatkiviteli párja.
Az EMIT ( c --- ) utasítás a paraméter stack-en lévő karakterkód értékének megfelelő karaktert visz ki az aktuálisan használt kimeneti perifériára. Ez leggyakrabban az operátori képernyő, de lehet printer egység is. Például:

65 EMIT

Egyszerre több karakter (string) kivitelét teszi lehetővé a TYPE ( cím n --- ) utasítás.
A cím értéke az a kezdő cím, ahonnan a karakter kivitele kezdődik, n a kiviendő karakter darabszáma. E két paraméter kezelése ugyanaz, mint a karakter beviteli utasításoknál.
String konstans kiíratására a ." utasítás szolgál. Az utasítást követő szóköz után következő karakterek mindegyikét változtatás nélkül kiírja az aktuális kimeneti egységre, még a szöveg belsejében előforduló szóköz karaktereket is. A kiírás a szövegben előforduló első " karakterig történik, itt az utasítás befejeződik.
Például:

: PERC->ORA ( n --- )
  DUP 60 /MOD ROT
  CR . ." PERC = "
  . ." ORA " . ." PERC" CR ;

Amint azt a példából látjuk, egyes gyakrabban használt karakterek kivitelére külön definíciós szó (utasítás) áll rendelkezésre. Ilyen a CR utasítás, amelynek definíciója a következő:

: CR 13 EMIT ;

vagy a SPACE, amely egy darab és a SPACES ( n--- ), amely n darab szóköz karaktert ír ki az aktuális kimeneti egységre.
Természetesen magunk is előállíthatunk ilyen kényelmesen használható definíciókat.
Például a legtöbb rendszerben a 12 (decimális) kódú karakter törli a képernyőt. Egy, a képernyő törlésére használható definíció:

: CLS ( --- ) ( Clear Screen )
  12 EMIT ;

A képernyő egyéb lehetőségeinek kihasználására definiált szavak áttekinthetővé, olvashatóbbá teszik programjainkat.

6.6. Adatbehozatal és -kivitel port-ok segítségével
A számítógépek külső egységeikkel (printer, háttérmemóriák , stb.) port-jaik (adatforgalmi csatornák) segítségével kommunikálnak. Az Intel 8080 mikroprocesszor például 256 bemeneti és kimeneti port-ot biztosit a felhasználó számára.
Ezek programozására biztosítja a FORTH rendszer az adatbehozatali P@ és az adatkiviteli P! utasításokat. Az utasítások 8 bites adatcsatornát feltételeznek és paramétereik is ehhez igazodnak.
A P@ ( b1 --- b2 ) stack diagrammal rendelkezik, ahol b1 a beolvasandó port címe, míg b2 a kiválasztott portról beolvasott adat.
A P! ( b1 b2 --- ) stack diagramjában b2 a port címe, b1 pedig a kiviendő érték.
Vigyázat: a mikroszámítógépek operációs rendszerei szintén használják az adatbeviteli és -kiviteli port-okat. Mielőtt a P! vagy P@ utasításokat alkalmazzuk, vizsgáljuk meg, hogy az általunk alkalmazott port címek megfelelőek-e annak az operációs rendszernek, ami alatt FORTH-unk fut.
Néhány számítógépnél az adatforgalmat, nem port-ok segítségével oldják meg, hanem az operatív memória egy részében csak adatforgalmi feladatokat végeznek, ez a memóriatérkép szerinti adatforgalom (memory-mapped I/O). Az adatok ekkor memóriahelyekre hivatkozó utasításokkal mozgathatóak, így az összes adattípusra vonatkozó memóriatárolási és visszahívási utasítás alkalmazható.

6.7.Kommunikáció háttértárolókkal
A legtöbb mikroszámítógép viszonylag kevés memóriával rendelkezik, így nagy memóriakapacitású háttértárolókat igényel. A FORTH rendszer a háttértárolókkal kapcsolatban minimális intelligenciát tételez fel, és nem használja ki az egyes háttértároló típusok nyújtotta speciális szolgáltatásokat. Ezáltal a háttérmemória kezelése egységes. A feltétlenül szükséges írási/olvasási kezelőrutinok átírásával bármilyen háttértároló rendszerrel működtethető a FORTH.
A leggyakoribb háttértároló a diszk egység és a mágnesszalag. Az utóbbi években a memóriák árának jelentős csökkenése és tároló kapacitásuk növekedése lehetővé tette, hogy háttérmemóriáként szolgáljanak (CMOS memóriák, dinamikus memóriák), a lemezegység kímélésére és a sebesség jelentős növelésére.
A FORTH rendszer a háttértárolókat virtuális memóriakezeléssel éri el, ezt a felhasználó vezérli. A virtuális háttértároló kezelésnek két tárolószintje van: a külső tároló (például a diszk egység), illetve az operatív memóriában kialakított memóriapuffer.
Az információforgalom a tárolók között, blokkos formában történik. A blokkoknak száma van, amely a háttértárolón lévő fizikai címük közvetlen függvénye. A rendszerben a blokkokra mindig a számuk alapiján hivatkozunk.
A blokkok méretét - byte-okban megadott hosszát - a B/BUF (byte/block) rendszerkonstans tartalmazza.
A központi memóriában lévő memóriapufferben egyszerre több blokk tárolására van lehetőség.
A kiválasztott blokkok a memóriába automatikusan olvasódnak be, a memóriában módosított blokkok pedig a pufferterület felülírása előtt automatikusan kiíródnak a háttértárra.
A blokk beolvasását a BLOCK ( n --- cím ) utasítás végzi, amely bemeneti paraméterként a beolvasandó blokk számát kéri, majd az illető blokk beolvasása után az első információs byte címét hagyja a paraméter stack-en. Nem olvassa be a blokkot, ha az már bent van a memóriapufferben.
Például a

234 BLOCK

beolvassa a lemezen lévő 234. blokkot, ha az még nincs benn n memóriapufferben.
A beolvasás után a paraméter stack-en hagyott kezdőcímtől kezdődően megtaláljuk a memóriában a B/BUF konstansban tárolt hosszúságú blokkot.
Egy adott számú blokk tartalmának megvizsgálása a következő utasítássorozattal lehetséges:

n BLOCK B/BUF TYPE

ahol n a vizsgált blokk száma.
Ha a rendszer számára jelezni akarjuk, hogy egy blokk tartalmát megváltoztattuk, tehát feltétlenül ki kell írni a háttértárolóra, az UPDATE utasítást kell használnunk. Ez a memóriapufferben elhelyezkedő memóriablokkot megjelöli úgy, hogy ha a rendszer a memóriapufferbe történő újabb blokk beolvasását kezdeményezi, a megjelöltet automatikusan kiírja a háttértárolóra.
A FLUSH utasítással közvetlenül kivihetjük a háttértárolóra az összes megjelölt blokkot.
A FLUSH utasítást sok implementációban a SAVE-BUFFERS utasítás helyettesíti, vagy mindkettő létezik.
A memóriapuffer területét nulla (0) karakterrel tölti fel az EMPTY-BUFFERS utasítás. Nem menti el a háttértárolóra az UPDATE-tel megjelölt blokkokat. Az utasításra a memóriapuffer inicializálásához van szükség.
A memóriapufferben, ahol több blokk elhelyezésére van lehetőség, a következő üres blokkhely keresésére és felszabadítására szolgál a BUFFER utasítás, amelynek stack diagramja a következő: ( n --- cím ). Az n a generálandó blokk számát adja meg, míg a cím kimenő paraméter a memóriapuffer kezdőcíme, ahol az adatokat elhelyezhetjük. Ha a memóriapufferben UPDATE-elt blokkot talál az utasítás a következő felszabadítandó helyen, azt először kiviszi a háttértárolóra, és csak azután foglal helyet a pufferben az új blokknak.
A háttértárolóval történő kommunikáció legkisebb egysége a blokk, amely a legtöbb háttértároló típusnál 128 byte, illetve ennek egész számú többszöröse.
A FORTH rendszer és a háttértárolók közötti adatforgalomra ez elegendően nagy érték, de nem megfelelő az operátorral való kommunikációhoz.
A FORTH rendszer felhasználója a képernyő előtt ülve, a képernyő teljes információtartalmát képes egyidőben áttekinteni. Számára tehát az volna kényelmes, ha egy beolvasási eljárás után a képernyő teljes tartalma új információt hordozna. Ez a méret általában nagyobb, mint az alkalmazott blokkok mérete. Ezért gyakorlati megfontolásból a képernyőt: 1024 (1 Kbyte) információ tárolására alkalmas eszköznek tekinti a FORTH rendszer. Ez 16 képernyősort (0-tól 15-ig számozva) és soronként 64 karaktert jelent. Ezt az 1 Kbyte információt tartalmazó egységet screen-nek nevezzük. Egy screen általában több blokkból áll, és az egy screen-hez tartozó blokkok darabszámát a B/SCR (block per screen) rendszerkonstans tartalmazza.
Screen-nagyságú egységekben tároljuk FORTH programjainkat és adatainkat (numerikus és string adatok).
A screen-eknek szintén van számuk, ezek alapján azonosíthatóak.
Egy screen listázását az aktuális kimeneti perifériára a LIST ( n --- ) utasítással végezhetjük el, ahol n a screen száma.
A screen számát, amelyet éppen listáz, az SCR rendszerváltozóban tárolja. Ha egy adott screen FORTH programot tartalmaz, akkor ezt a LOAD ( n --- ) utasítással tölthetjük be a számítógép operatív memóriájába, ahol n a screen száma. A betöltés folyamán a rendszer értelmezi a screen-ben lévő információkat, és elvégzi a szükséges fordítási illetve végrehajtási feladatokat.
LOAD utasítás mindig csak egy sereen-t tölt be. Ha a definíció több screen-en keresztül folytatódik, akkor a --> utasítással összefűzhetjük a számozásban egymás után következő sereen-eket. Ez az utasítás szerepel minden olyan sereen-ben vezérlő utasításként, amelyben a definíció még folytatódik.
A screen-ből történő fordítást a ;S utasítással lehet befejezni, ezzel a végrehajtási állapotba tér át a rendszer. Hatására a screen fordítása befejeződik, és az operátori képernyő / billentyűzet kapja meg a vezérlést.
A screen-ek használatában segítséget jelent, ha a nulladik sorában a screen-ben megoldott feladat címét, illetve rá vonatkozó információt helyezünk el. Az így előkészített screen-ek áttekinthetőségét biztosítja az INDEX utasítás, melynek stack diagramja ( n1 n2--- ). Az n1 és n2 az alsó és a felső határt jelenti, az utasítás pedig kiírja a határok közé eső számú screen-ek nulladik sorait.
A blokkok és screen-ek használatát a EDITOR-ral foglalkozó rész mutatja be a gyakorlatban.

6.8. Hibajelzések
A FORTH rendszer kevés hibajelzést alkalmaz. A hibajelzések zöme a rendszer fizikai működésével, illetve a fordítási állapotban észlelt programhibákkal kapcsolatos. Lehetőségünk van azonban arra, hogy saját magunk is megfogalmazzunk hibaüzeneteket.
A hibák típusát a rendszer alapállapotban számokkal jelzi, de lehetőségünk van szöveges hibajelzésre is. A hibajelzés kiírásának módját a WARNING rendszerváltozó vezérli.
A hiba kiírását a MEGSAGE utasítás végzi el, amelynek stack diagramja ( n --- ).
Az utasítás először megvizsgálja a WARNING változó tartalmát, amelytől függően a következő történik:

Például:

17 MESSAGE

a fig-FORTH rendszerben az 5-ös screen 1-es sorát fogja kiírni.
A hiba kezelését és kiírását az ERROR ( n --- ) végzi el. Az utasítás elvégzi az n-ik sorszámú hibaüzenet kiírását a MESSAGE-nél leírtak szerint, és a rendszert alapállapotba vezérli, azaz kiüríti a paraméter- és a return stack-et, végrehajtási állapotba hozza a rendszert, és a vezérlést az operátori billentyűzetnek és képernyőnek adja át.
Ha a WARNING tartalma negatív szám, akkor hibaüzenet nélküli ABORT (system reset) utasítást hajt végre az ERROR utasítás.
A felhasználók programjukból maguk is kiírhatnak hibaüzeneteket az ERROR utasítással. Szöveges hibaüzenet kiírásához a háttérmemória megfelelő screen-jének megfelelő sorába kell írni a hibaüzenetnek szánt információt. A WARNING változó beállításával pedig meghatározhatjuk a hibakiírás módját.

6.9. Kiíratás nyomtatón
A FORTH rendszerben az aktuális bemeneti és kimeneti periféria állapotának kijelölése rendszerváltozók segítségével történik. Ezen rendszerváltozók egyike határozza meg, hogy kiírandó adatok ne csak a képernyőre, hanem a printer egységre is kiíródjanak.
A rendszerváltozó beállításának módja a különféle FORTH rendszerekben más és más.
A CP/M operációs rendszer alatt futó fig-FORTH rendszerben, a CP/M alatti kiíratási konvenciókat tartották meg. CTRL/P billentyűk egyszeri lenyomásával kimeneti perifériaként a nyomtató egység bekapcsolódik, újabb CTRL/P lenyomásával pedig ismét csak az operátori képernyő lesz a kimeneti periféria
A fenti alapelvet alkalmazva a különböző számítógéptípusokon történő megvalósítást egy későbbi fejezetben ismertetjük.

7. A FORTH speciális utasításai

VOCABULARY, DEFINITIONS, CURRENT, CONTEXT, FORTH, ASSEMBLER, EDITOR, STATE, [, ], LITERAL, COMPILE, [COMPILE], IMMEDIATE, EXECUTE, INTERPRET, FORGET, FENCE, <BUILDS, DOES>, -FIND, NFA, LFA, CFA, PFA, LATEST, ;CODE, R0, S0, SP@, SP!, COLD, WARM, ABORT, QUIT, VLIST, BYE

Ebben a fejezetben azokkal a FORTH utasításokkal foglalkozunk, amelyek funkciójuk szerint, az eddigi fejezetek egyikébe sem illettek bele. Ezek az utasítások betekintést nyújtanak a FORTH rendszer speciális lehetőségeibe.

7.1.A szótárak létesítése
Ha új szótárakat és bennük utasításokat definiálunk, használhatunk azonos elnevezésű, de különböző programrészekben, más-más funkciókat ellátó utasításokat. Példa lehet erre a FORTH rendszerben használt I utasítani, amely a ciklusváltozó indexe, míg ugyanezen I nevű utasítás szerkesztési üzemmódban adott szöveg beszúrását jelenti.
A FORTH rendszer szótárkereső eljárása a legutoljára definiált szótól kezdi el visszafelé keresni az utasításneveket. Ha új szótárat létesítünk, és utasítjuk a rendszert, hogy ebben a szótárban az utoljára definiált elemtől kezdje el a keresést, akkor az azonos nevű elemek közül az ebben a szótárban lévő első ilyen nevű elemet fogja megtalálni. Így különböző elnevezésű szótárakban azonos utasításneveket használhatunk, más és más jelentéssel.
Új szótár létrehozása a VOCABULARY utasítással történik, például a következő módon:

VOCABULARY STRING IMMEDIATE

A szótár létrehozásánál ajánlott a szótári nevet IMMEDIATE utasításként definiálni. (Az IMMEDIATE leírására később kerül sor. )
Ezzel a definícióval létrehoztunk egy STRING elnevezésű szótárat. A szótári elemek - az utasítások - definiálásakor közölnünk kell a FORTH rendszerrel, hogy melyik szótárba kell elhelyezni az új definíciót. Ezt a DEFINITIONS utasítással tehetjük meg, a következő módon:

STRING DEFINITIONS

Így megjelölve a kívánt szótárat a későbbiekben definiált utasítások ehhez a szótárhoz kapcsolódnak, mindaddig amíg nem változtatjuk meg egy új DEFINITIONS utasítással. Bekapcsolás után a rendszer a FORTH nevű szótárhoz csatolja az elemeket. Például:

VOCABULARY STRING IMMEDIATE
STRING DEFINITIONS
: I (cim1 n --- cim2 )
  2DUP + ;

Az I utasítás most a STRING szótárba került, és különbőzik a FORTH szótárban lévő I utasítástól.
Egy utasítás használata előtt mindig meg kell adnunk a rendszernek, hogy melyik szótárban akarunk dolgozni. Természetesen ezt nem kell minden egyes utasítás előtt megadnunk, csak ha szótári környezetet, változtatunk.
Az új szótárba a szótár nevének megadásával térhetünk át. Például a

STRING

hatására a rendszer a STRING nevű szótárban fogja az utasítások keresését elkezdeni. A keresés mindaddig ebben a szótárban fog kezdődni, amíg újabb szótárnév megadásával meg nem változtatjuk a keresés kezdőpontját. Ha tehát több szótárban ugyanazzal a névvel szereplő utasításokat, szeretnénk egy definíción belül alkalmazni, akkor feltétlenül meg kell adnunk, hogy melyik szótárból kívánjuk az utasítást alkalmazni.

FORTH DEFINITIONS
: Z DO FORTH I DUP 1+
  STRING I CR . LOOP ;

Példánkban a STRING szótárban csak egyetlen definíció van. A Z nevű utasításban a STRING szótárnév után még további utasítások szerepelnek, amelyek nem elemei ennek a szótárunk. Mi történik ebben az esetben? Nem fogjuk megtalálni a . LOOP és ; utasításokat? De igen, és a 2 utasítás hibátlanul lefordítódik.
A FORTH szótár a rendszer alapelemeit tartalmazza, azaz a rendszer alapszótára. A STRING szótár, mint szótárdefiníció a FORTH szótár elemei közé fog kerülni. Ha tehát a kívánt definíció nem található a STRING szótárban a keresés a STRING szótárt definiáló FORTH szótárban folytatódik. A szótárak rendszerét fának is elképzelhetjük. A FORTH szótárból a STRING-nek megfelelő "szögpontból" egy ág ágazik el. A STRING-ben is definiálhatunk új szótárat, akkor innen is egy új ág indul ki és hasonlóan történik a keresés, ha több szintű szótárszerkezetet hozunk létre. A következő példánk ezt mutatja be:

VOCABULARY DEF1 IMMEDIATE
DEF1 DEFINITIONS
VOCABULARY DEF2 IMMEDIATE
DEF2 DEFINITIONS
: I ( n --- )
  CR DUP 5 .R 10 SPACES ;
DEF1 DEFINITIONS
: I ( n --- )
  C@ 2 .R ;
FORTH DEFINITIONS
: J ( n1 n2 --- )
  DO FORTH I DEF1 DEF2 I DEF1 I
  LOOP CR ;
FORTH HEX
5 0 J

Kinyomtatja a 0-ás címtől a 4-ig terjedő memóriatartalmat cím és tartalom formájában. A példában szereplő DEF1 a FORTH alszótára, a DEF2 szótár pedig DEF1 szótári elemei közé tartozik.
A FORTH rendszerben - a legfontosabb szótárak az EDITOR és az ASSEMBLER. Ezek lehetőségeit külön fejezetben részletezzük.
A különböző szótárak utasításkereséshez vagy definíció hozzácsatoláshoz való kijelölése rendszerváltozókkal történik. A CONTEXT rendszerváltozó tartalmazza annak a szótárnak a címét, amelynek utolsóként definiált eleménél kezdődik egy utasítás nevének keresése.
A CURRENT rendszerváltozó annak a szótárnak a címét tartalmazza, amelyhez kapcsolódni fog a következő definíció. Ezen rendszerváltozók értékének beállításával történik meg az utasítások működési feltételeinek biztosítása. Az új szótárak definiálása, illetve egy másik szótárra való áttérés e rendszerváltozókat használja, illetve állítja be.

7.2. A rendszer állapotát befolyásoló utasítások
A FORTH rendszernek alapvetően két állapota van, a végrehajtási és fordítási állapot. A két állapot bármelyikébe közvetlenül vezérelhetjük a rendszert a [ és a ] utasításokkal.
A [ utasítás a rendszert fordítási állapotból végrehajtási állapotba vezérli, a ] pedig végrehajtási állapotból fordítási, állapotba. A FORTH rendszer aktuális állapotát a STATE rendszerváltozó tartalmazza. A STATE tartalmának jelentése rendszerfüggő. A fig-FORTH-ban ha a STATE tartalma egyenlő nullával, akkor végrehajtási állapotban vagyunk, egyébként fordítási állapotban.
A rendszer állapotának megváltoztatására például a LITERAL utasítás alkalmazásakor van szükség. Ez az utasítás a paraméter stack-en talált 16 bites értéket az utasítás fordításakor az utasítás törzsébe belefordítja. De mit tegyünk, ha csak az utasítás fordításakor fogjuk megismerni azokat az értékeket, amelyeket bele akarunk fordítani a definícióba? Ilyenkor ki kell lépni a fordítási állapotból, végrehajtási állapotba, meg kell határozni a kívánt értéket, a paraméter stack-re kell helyezni, és visszalépni fordítási állapotba. A következő programrészlet

[ BLK @ B/SCR / ]

a BLK változó és a B/SCR konstans aktuális értékétől függő hányados értéket hagyja a paraméter stack-en további felhasználásra.
Azt például, hogy egy utasítás definiálásakor melyik screen-ben vagyunk, a következő definícióval állapíthatjuk meg:

: #SCREEN [ BLK @ B/SCR / ] LITERAL ;

E #SCREEN definíció fordításakor a LITERAL utasítás befordítja a #SCREEN törzsébe az aktuális screen számát. Végrehajtási állapotban pedig a korábban befordított értéket helyezi el a paraméter stack-en.

7.3. Utasítások, definíciók törlése
A FORTH programozási filozófiából következően az utasítások egymás utáni definíciója az utasítások felhasználhatóságának sorrendjét is meghatározza. Egy új definíciós szóban, csak azokat az utasításokat használhatjuk fel, amelyeket már korábban definiáltunk. Ez azért fontos, mert a FORTH rendszer az egyes utasításokat neveik alapján azonosítja, majd a végrehajtásukhoz szükséges cím értéket helyezi el az új definíció törzsében. Tehát csak olyan utasításneveket talál meg, amelyeket korábban definiáltunk. Ha egy utasítás hibás működésű, akkor az utána következő összes definíció (amely elvileg felhasználhatta a hibás utasítást) is hibás működésű lesz. A hibát kétféleképpen lehet, kijavítani.
Ha ugyanabban a szótárban újra definiálunk egy azonos nevű utasítást, az új definíció lesz érvényes, így meg lehet szüntetni a hibát. Ez a megoldás a definíció helyes működéséhez vezet, de feleslegesen tárolja a memóriában a hibás verziót vagy verziókat.
A másik megoldás az, hogy a hibás definíciót és az utána következőket, elfelejtetjük a rendszerrel , és így olyan állapotot hozunk létre, mint amilyen a hibás utasítás definíciója előtt volt. Ezt a lehetőséget a FORGET utasítás biztosítja számunkra. A FORGET az utána következő utasításnevet és minden, az utasításnév után következő definíciót "elfelejtet". Működéséhez szükséges, hogy a CURRENT és CONTEXT szótárnév megegyezzék egymással, ha ez nem teljesül, az utasítás végrehajtása helyett hibajelzést kapunk.
Tegyük fel, hogy a következő utasításokról vizsgálatuk során kiderült, hogy közöttük a DEF1 utasítás működése hibás.

: DEF0 DUP * DUP * ;
: DEF1 R> DUP CR . ;
: DEF2 IF ." RENDSZER HIBA!" THEN ;
: DEF3 DO DEF1 I DEF2 LOOP ;

Ha a DEF1-et "elfelejtetjük" a

FORGET DEF1

utasítással, akkor a rendszer "elfelejti" a DEF2-t és DEF3-at is.
A FORGET utasítást általában végrehajtási állapotban használjuk, de speciális alkalmazásoknál definícióban is szerepelhet. A FORGET utasítással elvileg akár az egész FORTH operációs rendszert elfelejtethetnénk. Ezt a totális hibát akadályozza meg a FENCE rendszerváltozó. A FORGET utasítás, amely az elfelejtendő utasítás nevét egy címmé konvertálja, összehasonlítja a címet a FENCE tartalmával. Ha a FENCE-ben tárolt értéknél kisebb címértéket szeretnénk elfelejtetni, akkor hibajelzést ad a rendszer. Ha a FENCE-ben tárolt érték kisebb, mint az utasításnévből képzett cím, akkor végrehajtja a név törlését.
A FENCE tehát, egy olyan védő vonal, amellyel védhetjük definícióinkat.
Ha a rendszerben lévő összes definíciót meg akarjuk védeni, akkor FENCE értékét a HERE értékére kell állítanunk.

HERE FENCE !

7.4. Utasításnevek keresése a szótárban
Az utasításnevek fizikailag egymás után helyezkednek el a memóriában, és az egyes szótárakban való összefűzését az utasítások fejrészében tárolt egyik paraméter adja meg. Azaz egyes szótárakhoz tartozó utasítások nevének mutatói az azonos szótárhoz tartozó elemeket kapcsolják össze.
A szótárakat definiáló utasítások fejrészében pedig a szótárban legutoljára definiált utasítás nevének címét tárolja a rendszer.
Amikor a szótár nevét megadjuk, a CONTEXT változó felveszi az adott szótár nevének címét, és az ebben a szótárban utoljára definiált elemtől kezdi el a keresést. Egy FORTH-beli szótári elem a következő részekből áll:

Egy utasítás memóriabeli elhelyezkedését az utasítás megfelelő címeivel lehet meghatározni. Ezek jelentése a következő:

Egy utasításnév PFA címét lehet megkeresni. Például a

' DUP

a DUP utasítás PFA címét hagyja a paraméter stack-en. Ebből a címből lehet az itt következő címkiszámító eljárásokkal utasításhoz tartozó egyéb címek értékét meghatározni.
A PFA címből az egyéb címértékeket meghatározó utasiások:

CFA ( cím1 --- cím2 )
Az utasítás a PFA címből a CFA címet határozza meg.

LFA ( cím1 --- cím2 )
Az utasítás a PFA címből az LFA címet határozza meg.

NFA ( cím1 --- cím2 )
Az utasítás a PFA címből az NFA címet határozza meg.
A fenti utasításoknál a cím1 a PFA míg cim2 az utasítás nevének megfelelő, a keresett címérték. Lehetőség van egy utasítás NFA címéből a PFA címének meghatározására is, a PFA utasítással:

PFA ( cím1 --- cím2 )
ahol cím1 = NFA cím, cim2 = PFA cím.
Ha például a DUP utasítás NFA címére vagyunk kíváncsiak:

' DUP NFA

A szótárelemekről még további információk is nyerhetők. A -FIND utasítás nemcsak az utasítás PFA címét, de nevének hosszát és állapotbitjeit, valamint, egy logikai értéket, is hagy a paraméter stack-en, ha talált a megadott névvel utasítást. Ha ilyen elnevezésű utasítás nincs, akkor csak egy logikai hamis értéket hagy ott. Végrehajtási állapotban és definícióban is használhatjuk.
Végrehajtáskor a -FIND után következő utasítás paramétereit keresi meg. Fordítási állapotban lefordítódik az új definícióba, és csak annak végrehajtásakor keresi meg a definíció után következő utasítás paramétereit. Nézzünk erre egy példát! A

-FIND DUP

a DUP utasítás PFA címét, névhosszát, és állapotbitjeit, valamint egy logikai igaz értéket helyez el a paraméter stack-en.
A következő esetben

: DDD -FIND CR IF ." Allapot byte = " U. CR ." Parameter mezo kezdocime = " U. THEN ;

a -FIND utasítás nem a CR utasítás paramétereit fogja megkeresni, hanem DDD végrehajtásakor a DDD-t követő szónál végzi el a keresést, azaz a

HEX DDD VARIABLE

utasítások esetében a következő kiírást kapjuk:

Allapot byte = 88
Parameter mezo kezdocime = 602

ez a VARIABLE FORTH alapszóra vonatkozik.
A név keresést még egy másik utasítás segíti, amely az aktuális szótárban a legutolsó elem NFA címét adja meg. Ez a LATEST utasítás. Be kell állítani a kívánt szótárt a szótárnév megadásával, ezután a LATEST utasítás a paraméter stack-re teszi a szótárbeli utolsó elem NFA címét.

7.5. Az utasítások lefordítása FORTH-ban

7.5.1. INTERPRETER és az EXEVUTE utasítás
Mint már említettük, a FORTH rendszer két állapotban van. Végrehajtási állapotban a szöveg, amelyet, a felhasználó (klaviatúráról vagy háttértárolóról) a rendszernek küld, Interpretálódik, azaz a forrásnyelvi szövegben szereplő utasítások sorrendben végrehajtódnak. A végrehajtást a rendszerben az INTERPRET utasítás szervezi.
A fordítási állapotban is van szerepe, de erre még visszatérünk.
Végrehajtásnál az INTERPRET a feldolgozásra szánt szöveget először is utasításszavakra vágja szét. Ezután megvizsgálja, hogy végrehajtási állapotban van-e a rendszer. Ha Végrehajtási állapotban van, és a forrásnyelvi szövegben lévő következő utasítás létezik a szótárban, akkor végrehajtja az utasítást. Ha nem szerepel a szótárban, megpróbálja számként értelmezni, ha ez sem sikerül, akkor hibajelzést ad.
Egy utasítás végrehajtásához az utasítás CFA címe és az EXECUTE utasítás szükséges.
Ha például a DUP utasítást akarjuk végrehajtani, a következő utasítássorozat ezt ugyanúgy elvégzi, mintha a DUP utasítást írtuk volna le, és az INTERPRET kezelné:

' DUP ( megadja a DUP PFA címét )
CFA   ( meghatározza DUP CFA címét )
EXECUTE ( végrehajtja a DUP utasítást )

Az EXECUTE használatának akkor van jelentősége, ha egy később definiálásra kerülő utasítás címét akarjuk befordítani így definícióba.
Lássuk ezt egy példán:

0 VARIABLE CIKLUSMAG
: CIKLUS DO I CIKLUSMAG @
EXECUTE LOOP ;
( itt utasítások jönnek, amelyek meghatározzák DO-LOOP ciklusban, az itt következő MAG-ban felhasználandó értékeket )
: MAG ( a ciklusmag végrehajtandó utasításai ) ;
' MAG CFA CIKLUSMAG !

A CIKLUS nevű utasítást korábban kellett definiálnunk, mint a MAG nevű utasítást. Így nem irtattuk be a ciklusba közvetlenül a MAG utasítást, hanem a fenti módszerrel, a CIKLUSMAG változó tartalma az a cím, ahol a végrehajtandó utasítások kezdődnek. Egy olyan esetet feltételezünk, amikor csak a CIKLUS definíciója után tudjuk megadni a DO-LOOP ciklusban felhasználandó értékeket, így viszont a DO-LOOP között, nem tudjuk a ciklustörzs tevékenységét azonnal leírni. A MAG utasítás definícióját egy közvetlenül végrehajtandó utasítássorozat követi, amely a CIKLUSMAG változó értékét beállítja a MAG utasítás CFA címének megfelelő értékre. Így a ciklus utasítás végrehajtásakor a ciklus törzset, a MAG-ban leírt utasítások alkotják.
A CIKLUSMAG változó értékének megváltoztatásával ugyanazon ciklus más és más ciklusmagokat hajthat végre.
Térjünk vissza az INTERPRET utasításhoz, és vizsgáljuk meg, mi történik, ha a rendszer fordítási állapotban van! Fordításnál a forrásnyelvi szövegben lévő következő utasításnevek végrehajtási címeit (CFA címeit) elhelyezi az utasítás a szótárban lévő következő szabad memóriahelyre. Ha forrásnyelvi szövegben lévő következő utasításszót nem találja meg a szótárban, akkor megpróbálja számként értelmezni. Megkülönbözteti a dupla pontosságú számot az egyszeres pontosságútól a tárolásnál.
Ha számként sem sikerül értelmeznie az utasítást, akkor hibajelzéssel befejezi az utasítás forrásnyelvi szövegének értelmezését, mert olyan utasítást talált, amely még nincs definiálva vagy más szótárban szerepel.

7.5.2. IMMEDIATE utasítás
A FORTH-ban definiált szavak többsége fordítási állalmiban lefordítódik egy új definícióba, végrehajtási állapotban pedig elvégzi azt a feladatot, amelyet definiáláskor megadtunk. A fordítás során azonban számos olyan feladat van, amelyet nem végrehajtáskor, hanem közvetlenül fordításkor kell elvégezni.
Ilyen speciális tulajdonságú utasítás például a kettőspont (:). A : utasítás végrehajtási állapotból, amelyben a rendszer működése mindig indul, fordítási állapotba állítja a rendszert, és a közvetlenül utána szereplő névvel egy új szótári elemet állít elő. Ha ezeket a feladatokat nem közvetlen akkor végezné el, amikor fordítási állapotban a forrásszöveg interpretálása történik, akkor nem is lehetne utasításokat lefordítani.
Vannak tehát olyan utasítások, amelyek működését az jellemzi, hogy fordítási állapotban hajtódnak végre.
Ezeket IMMEDIATE típusú utasításoknak nevezzük. Ilyen utasítást magunk is elő tudunk állítani, ha az utasításszót lezáró ; utasítás után leírjuk az IMMEDIATE szót. Például

: UDV ." SZERVUSZ" ; IMMEDIATE

Az UDV utasítás azonnal végrehajtódóvá vált, így ha definícióban használjuk, az eredmény a következő lesz:

: GREET ." HELLO = " UDV ; SZERVUSZok

A GREET utasítás fordításakor végrehajtódott az UDV utasítás.
Ha most a GREET utasítást hajtjuk végre akkor a

GREET HELLO= ok

eredményt kapjuk, mivel az UDV már fordítási állapotban végrehajtódott és nincs belefordítva a GREET utasítás törzsébe.
Ilyen fordítás közben végrehajtódó utasítások például a vezérlési struktúrában szereplő elemek (IF, BEGIN, stb.).

7.5.3. A COMPILE és a [COMPILE] utasítások
A FORTH nyelvben bonyolult utasításstruktúrákhoz vagy fordítási feladatokat elvégző utasításokhoz nemcsak az IMMEDIATE utasítás áll rendelkezésünkre ahhoz, hogy fordítási állapotban végrehajtsunk különböző feladatokat. Szövegfeldolgozáskor, fordítóprogram írásakor gyakran van szükség arra, hogy végrehajtási és fordítási feladatokat vegyesen végezzünk. Ezekhez nyújt segítséget a COMPILE és a [COMPILE] utasítás.
A COMPILE-t a forrásnyelvi szövegben követő utasítás végrehajtási címe belefordítódik az új definícióba.
Például:

: MINTA 2 = IF COMPILE DUP ELSE
COMPILE SWAP THEN ; IMMEDIATE

A MINTA utasítás egy feltételtől függő fordítási állapotot valósit meg.
Ha a paraméter stack-en fordítási állapotban éppen kettő van, akkor a DUP utasítást, egyéb esetben pedig a SWAP utasítást fordítja bele abba az utasításba, amelynek definiálásakor MINTA előfordult. Például a következő definíciókban:

: DDD [ 2 ] MINTA ;
: SSS [ 0 ] MINTA ;

a DDD utasítás úgy fog viselkedni mintha egyszerű DUP utasításként definiáltuk volna, míg az SSS utasítás a SWAP funkciót valósítja meg.
A COMPILE csak azokat az utasításokat tudja egy új utasításba befordítani, amelyek önmagukban nem azonnal végrehajtódó IMMEDIATE utasítások. Az IMMEDIATE típusú utasítások definícióba történő befordítására szolgál a [COMPILE] utasítás.
A [COMPILE] hasonlóan a COMPILE utasításhoz, a definícióban utána következő utasítás végrehajtási címét helyezi el az új definícióban.

7.6. Új utasítások, adatstruktúrák előállítása
A FORTH rendszer talán leghatékonyabb utasításpárja a <BUILDS és a DOES>. Ezen két utasítás új utasítások vagy adatstruktúrák előállítását szolgálja.
Új utasítások előállítása egyszerű kettőspont definícióval is lehetséges, de a <BUILDS, DOES> struktúrával meg lehet határozni, hogy mit tegyen a rendszer az adott utasítás definíciója közben (fordításkor), illetve végrehajtáskor. A struktúra kényelmessé teszi például az assembler programozást, a többdimenziós mátrixok kezelését, fordítóprogramok készítését. Az utasításpár használatára lássuk a következő példát:

: VEKTOR ( n --- )
  <BUILDS 2 * ALLOT DOES>
   SWAP 2 * + ;

VEKTOR névvel egy vektor típusú adatstruktúrát állítottunk elő. Az adatstruktúrát a következő módon használhatjuk:

10 VEKTOR TERFOGAT

az utasítással egy tíz elemű, TERFOGAT nevű, VEKTOR típusú adatstruktúrát hoztunk létre.
A VEKTOR utasítás típusdeklaráló tulajdonságait a <BUILDS-tól a DOES>-ig terjedő utasítások Írják le. Esetünkben a paraméter stack-en található n szám által meghatározott számú adatnak foglal helyet. Az ALLOT utasítás byte-ban meghatározott mennyiségű memóriát foglal le, ezért kell 2 * .
Különböző n értékek megadásával különböző méretű VEKTOR típusú adatstruktúrát tudunk előállítani.
A TERFOGAT nevű, VEKTOR típusú adat használata a következő. Helyezzünk el a TERFOGAT vektor 5. elemébe 12-t. Ez a következő utasítással történik:

12 5 TERFOGAT !

Az utasításokból az 5 TERFOGAT részt emeljük ki. Ennek eredménye egy cím, és a ! hatására egy egyszerű értékadás történik erre a címre.
A TERFOGAT-ot definiáló VEKTOR utasítás DOES>-tól ;-ig terjedő részét végrehajtáskor vizsgálja meg, és hajtja végre a rendszer.
De hogyan különbözteti meg a rendszer egymástól a VEKTOR típusú, de különböző nevű vektorokat, és hogyan határozza meg az egyes elemek címét? Ezekre a kérdésekre a DOES> utasítás működése ad választ.
A VEKTOR utasításban a DOES> utáni rész egy báziscímhez képest vett abszolút címértéket határoz meg.
A TERFOGAT nevű adatvektor definiálásakor, hasonlóan például a kettőspont definíciókhoz, a névvel és az adatok számára történő helyfoglalással együtt létrejön a térfogat nevű szótári elem paraméter mezeje és PFA címe.
A TERFOGAT utasítás végrehajtásakor a TERFOGAT PFA (Parameter Field Address) címét elhelyezi a DOES> utasítás a paraméter stack-re, és ezután végrehajtja a DOES> utáni utasításokat.
Így lehet azonos típusú, de különböző nevű adatokat, paraméter mezejük címe (PFA cím) alapján megkülönböztetni, illetve meghatározni a paraméter mező kezdőcímét, mint báziscímtől adott távolságra elhelyezkedő adatokat. A példánkban szereplő

5 TERFOGAT

végrehajtásakor a következő történik: A paraméter stack-en lévő 5 értékre helyezi a VEKTOR utasításban szereplő DOES> a TERFOGAT utasítás PFA címét, majd a VEKTOR utasítás DOES> utáni részében szereplő utasításokat hajtja végre a rendszer

utasítások
paraméter stack

SWAP
1
*
+
5 PFA
PFA 5
PFA 5 2
PFA 10
PFA +10

Ezt az elvet alkalmazva olyan utasításokat állíthatunk elő, amelyek különböző részeit hajtja végre a rendszer definíciókor és végrehajtáskor.
A DOES> utasítás helyett alkalmazhatjuk a ;CODE utasítást is, abban az esetben, ha a ;CODE után gépi kódban akarjuk a végrehajtandó részt megírni. Ennek részletes ismertetésére az ASSEMBLER-rel foglalkozó fejezetben kerül sor.

7.7. A paraméter és a return stack mutatói
A rendszerben lévő két stack kezdő pozícióját az S0 és az R0 rendszerváltozók tartalmazzák:
S0 a paraméter stack kezdőpozícióját,
R0 pedig a return stack kezdőpozícióját tartalmazza.

A paraméter stack utolsó (éppen behelyezett) elemének címét a stack mutatójának értéke adja meg, ezt az SP@ rendszerváltozó tartalmazza.
A paraméter stack a következőképpen néz ki:

S0 ->



SP@ ->
1
2
4
6
8
...
a paraméter stack kezdőcíme



a paraméter stack mutató
     aktuális értéke

Ha egy újabb adatot helyezünk el a paraméter stack-en, akkor az SP@ mutató a kisebb memóriacímek felé fog elmozdulni, míg adatkiíráskor illetve a DROP utasítás alkalmazásakor a nagyobb memóriacímek felé mozog.
A rendszer az S0 és az SP@ mutatók értékének egyezéséből tudja meg, hogy a paraméter stack üres, nem tartalmaz adatot.
Az SP@ egy címértéket ad meg, amelynek tartalma a paraméter stack-be legutoljára elhelyezett adat.
Ezek után már valóban érthető a bevezető részben bemutatott .S utasítás.
A paraméter stack teljes kiürítése több módon is lehetséges:

A fentiekben leírtakat a return stack-kel is elvégezhetjük, a megfelelő utasítások nevei:

R0
RP@
RP!

7.8. Inicializáló utasítások
A FORTH rendszer "hideg indítását", azaz a betöltés utáni kezdőcíméről történő indítást a COLD utasítás valósítja meg. A COLD végrehajtása után a rendszer minden olyan definíciót elfelejt, amely nem tartozik hozzá az eredeti formában betöltött rendszerhez.
A WARM utasítás, mint ahogy neve is mutatja, egy már bekapcsolt állapotban lévő rendszer újraindítását, végzi el úgy, hogy nulla karakterekkel tölti fel a memóriapuffert, és a FORTH betöltés utáni kezdetére ugrik. Nem törli ki az újonnan definiált, utasításokat.
A QUIT utasítás törli a return stack tartalmát, megállítja a fordítást, és végrehajtási állapotba kerül a rendszer. Visszaadja a vezérlést az operátori klaviatúra/képernyő rendszernek. Nem ad semmiféle hibajelzést.
Az ABORT utasítás a QUIT utasítást hívja meg, de előtte kiírja az operátori képernyőre vagy a FORTH implementáció, vagy az alkalmazott központi egység, vagy a mikroprocesszor nevét.
A BYE utasítás segítségével lehet visszatérni abba a rendszerbe, ahonnan a FORTH rendszert hívtuk. A személyi számítógépek esetében ez általában az alap BASIC rendszer. Operációs rendszerből hívott FORTH esetén viszont az eredeti operációs rendszerbe tér vissza. Például a 8080 fig-FORTH 1.1 a CP/M rendszerbe kerül vissza.

7.9. Az utasításnevek listázása
A FORTH rendszerben a felhasznált utasítások neveit a VLIST utasítással listázhatjuk ki az operátori képernyőre. A lista az aktuális kereséskor használt szótár legutoljára definiált elemétől kezdődően, a definiálás sorrendjében visszafelé tartalmazza az utasítások neveit.
Ha a CONTEXT változó nem a FORTH szótárra mutat, akkor az aktuális szótár elemeinek kilistázása után a szótárt definiáló szótár elemeit is kilistázza az utasítás. Az egyes szótárak fa struktúrában összekapcsolt rendszerében a listázás során így végigmegyünk az eredetileg kilistázott szótárat tartalmazó összes szótár elemein. Az utasításnevek listázása akkor fejeződik be, ha az aktuális szótárnév a FORTH lesz. A FORTH szótár elemeinek kilistázása még megtörténik.
A FORTH-ban a szótárnevek - hasonlóan az egyes szótárakban szereplő utasítások neveihez - kapcsolási címekkel vannak egy fa struktúrában összefűzve. Ennek a fa struktúrának a gyökere a FORTH szótár.

8. FORTH szövegszerkesztő (EDITOR)
A FORTH rendszerben új szótári elemeket a kettőspont definíció segítségével tudunk előállítani. A klaviatúrán begépelt új elem az utasítást záró ; utasítás hatására a rendszerbe épül (lefordítódik) Például a

: UJ-ELEM ." Ez egy magyarazat" CR ;

begépelése után a szótárban megjelenik egy elem, amely nevének (UJ-ELEM) begépelése után kiírja a képernyőre az idézőjelek közti fenti szöveget.
Az utasítás definiálása után már nem tudjuk megmondani, milyen elemekből állítottuk elő (különösen, ha már nem látható a definíciós sor a képernyőn!) Nem tudjuk megváltoztatni, módosítani. Javításra csak úgy van mód, hogy a FORGET utasítás segítségével kitöröljük a szótárból, és megkíséreljük ismételten - most már jól (vagy legalábbis jobban) előállítani.
A javításokhoz, illetve FORTH "program" Írásához nyújt segítséget a nyelven belül előállítható szövegszerkesztő program. A FORTH interpreter számára teljesen mindegy, hogy az értelmezendő szöveget a terminál pufferéből olvassa, vagy a memória egy másik helyén elhelyezett információt dolgoz fel.
Mivel az operatív tár véges mérettel rendelkezik, ezért a nyelv alkotója úgy döntött, hogy 1024 byte-os screen-ekben háttértárolón (rendszerint valamilyen mágneslemezes egységen) tárolja az előre definiálható szótári elemeket. Ezeket megfelelő alkalommal a LOAD utasítás segítségével a memóriába hozza és értelmezi. Egy diszken például 200 - 600 ilyen screen létesíthető a diszk nagysága és felírási sűrűsége függvényében.
Az 1024 byte-os (1k-s) screen méretét több dolog is indokolja. A diszken blokkos adatformátumban rögzítik az információkat, amely általában 128 byte egész számú többszöröse (128,256,512, esetleg 1024). Ezekből 8, 4, 2 illetve 1 lesz ki egy FORTH screen-t, így az adott diszk-rendszerrel annak blokkos tulajdonságaival megegyezően lehet közlekedni.
A FORTH rendszer és editor működéséhez az operatív memóriában legalább 1 screen méretének megfelelő helyet, kel biztosítani (memória puffer). Az egyes screen-eket sorszámokkal azonosítjuk 1-től kezdődően a diszk rendszer által megengedett maximális méretig. (Implementációtól függően több screen is lehet egyidőben a memóriában.)
Az ismertetésre kerülő FORTH szövegszerkesztő úgynevezett sor szerkesztő, mert egyszerre csak egy sorral (64 karakterrel) foglalkozik. A szövegszerkesztő beindítása az EDITOR kulcsszó begépelésével történik. Ahhoz hogy egy screen-t kezeljünk, be kell hozni a memóriába egy

n LIST

utasítás segítségével.
(Ha például az 50. screen-t akarjuk kezelni, akkor az 50 LIST utasítást kell leírni.) Az utasítás hatására a diszkről a memóriába kerül, és egyben 0-15 közötti sorszámokkal ellátva megjelenik a screen tartalma a képernyőn. (A sorszámokat az editor állítja elő, ezek nem tartozékai a screen-nek, és nem számítanak bele a 64 karakterbe. Ugyanez vonatkozik a sorzáró CR, LF karakterpárra is.)

Ha a screen tartalma a memóriában van, akkor egy argumentum nélküli

L ( ---) (List)
paranccsal az egész megjeleníthető a képernyőn. (A zárójelben az utasításnak megfelelő angol szót írtuk.)
Az

NS ( --- ) (Next screen)
a sorszámban következő, a

PS ( --- ) (Previous screen)
a sorszámban megelőző screent hozza be szerkesztés céljából.
FONTOS! Ha azt akarjuk, hogy az editor segítségével átszerkesztett program a háttértároló diszkre is az új formában rögzítődjön, akkor a screen változtatásának befejezése után adjuk ki a

FLUSH ( --- )
utasítást, amely minden változást a háttértárolón is átvezet. (Ha további screen-eket is javítunk, akkor ez nem feltétlenül szükséges, mert az új screen-t beolvasó utasítás ezt automatikusan végrehajtja.)
Egy új screen írásához úgy kezdünk hozzá, hogy az n LIST utasítás után töröljük a tartalmát egy

CLEAR ( --- )
utasítás segítségével. (Így egy üres screen-t állítunk elő. Ha ezt L paranccsal listázzuk, akkor a képernyő bal oldalán 0-15 sorszámokat látunk csak, mert az aktuális tartalom a betüköz (space) karakterrel lett feltöltve.) Az editor két 64 karakter hosszúságú segéd tárolóval rendelkezik. Az egyik a keresést segítő (find puffer), a másik az új szöveg betöltését segítő (insert puffer) tároló. Ezek egyrészt az adott utasításoknál a szöveg argumentumot tartalmazzák, másrészt, ha szöveget igénylő utasítást argumentum nélkül adunk ki, akkor ezek a segédtárolók tekintendők (az előző tartalmukkal) az argumentum forrásának.
Egyes utasítások működési helyét a screen-en belül a képernyőn a ^ vagy _ mutató (cursor) jelzi. A jel a sor elején az első karakter elé, sor közben két karakter közé mutat. Egy screen listázása után a mutató a legelső karakter előtt áll.
Ha egy sort vizsgálni akarunk, akkor a

T ( n --- ) (Type)
utasítással megjelenítjük a képernyőn. Az utasítás kiadásakor a cursor a sor első karaktere elé mutat.

C szöveg ( --- )
A megadott szöveget az aktuális karakterpozíció után szúrja be.
Egy teljes sort írhatunk át a

P szöveg ( n --- ) (Put)
utasítással. A "szöveg" bekerül az insert puffer-ba, majd az aktuális sor törlése után annak helyére másolódik.
Szöveget kereshetünk meg a cursor aktuális pozíciójától a screen-ben az

F szöveg ( --- ) (Find)
utasítással. Ha megtalálta a screen-ben az adott szöveget, akkor a cursor-t a megtalált szöveg utolsó karaktere mögé állítja, és kiírja a megtalált szöveg teljes sorát. Ez a sor lesz továbbiakban az aktuális sor. A keresendő szöveg a find puffer-ben is megtalálható. Ha az utasítás nem talál egyezést, akkor kiírja a kereset szöveget és egy kérdőjelet.

E ( n --- ) (Erase)
Az aktuális screen megadott számú sorát törli (szóközökkel tölti fel).

D ( n --- ) (Delete)
Törli a megadott számú sort az aktuális kernyőről, de szövegét megőrzi az input pufferben (így azt átmozgathatjuk az I paranccsal máshova).

DELETE ( n --- )
Törli az aktuális karakterpozíció előtti n darab karaktert; a sor végét szóközzel tölti fel.
Törlésre használható a

TILL szöveg ( --- )
utasítás is. A keresendő szöveget a find pufferba másolja, megjegyzi a mutató pillanatnyi helyzetét, és keresi a szöveget. Ha egyezést talál, akkor törli a kurzor és a szöveg vége közötti részt.
A mutató pillanatnyi helyzetétől kezdődően szöveget tudunk behelyezni az

I ( n --- ) (Insert)
utasítással. A megadott számú sorba beszúrja az input pufferben levő sort (a többi sort lejjebb tolja).

H ( n --- ) (Hold)
Az aktuális screen megadott számú sorát az input pufferbe másolja.

R ( n --- ) (Replace)
A megadott számú sort a padben levő sorral helyettesíti.
Egy screen-t másol egy másik screen-be a

COPY ( n1 n2 --- ) (Copy)
utasítás. Az utasítás hatására az n1 sorszámú screen tartalma bemásolódik az n2. screen-be.

A szövegszerkesztő utasításai - mint a FORTH utasítások - betűközzel választandók el az argumentumoktól. Lehetőség van egy sorban több utasítás leírására is például:

12 D 5 I

A szövegszerkesztővel történő FORTH program írásnál célszerű néhány dolgot figyelembe venni.
Új definíciót lehetőleg a sor elején kezdjünk. Áthúzódhat, a definíció a következő sorokba is, de akkor azokat néhány betűközzel kezdjük. Ezzel áttekinthető formátumot nyerünk.
A screen írásánál használjuk a megjegyzések írásához szánt ( utasítást, a ) határoló karakterrel. A megjegyzésekben tüntessük fel a rutin funkcióját, be- és kimenő paramétereit. A megjegyzéseket, az értelmező program figyelmen kívül hagyja, de a programozó számára később sok segítséget adhat.
A 0. sorszámú sorokba írjuk megjegyzésként, hogy melyik FORTH programunkhoz tartozik, abban hány screen szerepel, és azok közül ez melyik sorszámú. Ezzel könnyen azonosíthatók lesznek a screen-ek. A FORTH-ban lehetőség van arra is, hogy az egymást követő screen-ek első sorát megjelenítsük, és így keressünk egy adott feladathoz tartozó screen-csoportot.

9. FORTH assembler
A FORTH programozási nyelvről eddig azt írtuk, hogy nagyon gyors programvégrehajtást lehet elérni vele. Vannak azonban olyan esetek, ahol ez (az assemblerben írt programhoz képest 0.5-0.2-szeres sebesség) nem elegendő. Ilyen esetben a FORTH ASSEMBLER szótárt kell igénybe venni. A fenti szótár használatának három fő szempontja van:

  1. Lehetővé teszi, hogy az adott processzortípus assembler nyelvén, a FORTH rendszerből való kilépés nélkül írhassunk rutinokat.
  2. Elvégzi az így megirt programok fordítását.
  3. A futtatható tárgykódot a FORTH rendszerbe építi be, mint egy "primitiv" rutint.

Bármely processzortípushoz meg lehet írni ezt a programot a mnemonikok és a megfelelő kódok ismeretében. Könyvünkben Intel 8080-as processzorra mutatjuk be az ASSEMBLER szótárt, amely 3 screen-ből áll (lásd a mellékletben).
A szótár lényege, hogy a különböző gépi utasításokat 5 nagy csoportba sorolja. A csoportok egyrészt gépi utasításokhoz tartozó byte-szám, másrészt az azonos típusú, de különböző argumentumú utasítások összeválogatásából alakulnak ki.
Mindegyik csoporthoz tartozik egy adott képzési utasítás (1MI-5MI), amelyet egy-egy <BUILDS ... DOES> szerkezet vezet be. Ezekkel a képzési utasításokkal az ASSEMBLER szótári screen-nek LOAD paranccsal történő rendszerbe iktatása során kialakulnak az egyes assembler mnemonikus szavakhoz tartozó azonos nevű FORTH szótári elemek. Ezek működésük közben a paraméter stack-ről adatokat vesznek fel, amelyek segítségével a megfelelő gépi kód kialakításra és tárolásra kerül.
Az egyes regiszterek neveihez tartozó kódok egy-egy konstansban rögzítettek, amelyek természetesen az illető regiszter nevét viselik.
Néhány utasítás, amely nem volt csoportba sorolható, külön definíciót kapott (például: MVI, LXI).
A különböző feltételes gépi utasítások fordításához a szótáron belül egy NOT, IF, THEN, ELSE, BEGIN, WHILE, UNTIL és REPEAT utasításszavakból álló struktúra van. (Esek nem tévesztendők össze a FORTH hasonló nevű alaputasításaival bár struktúrájukban azokkal megegyeznek.)
Az assembler programbetétek rendszerbe iktatásának fontos szabálya, hogy a rutin végén a belső futtató rutin (NEXT) kezdőcímére ugorjanak. Ennek a rutinnak a kezdőcímét a NEXT konstans tárolja. (Egyes FORTH változatokban ez a konstans NEXT-LINK néven a FORTH szótár elemeként szerepel. fig-FORTH-ban PCIX utasíts végzi az ugrást.) A bemutatott program a 8080 fig-FORTH ismeretében a ;S parancsból kéri vissza a megfelelő címet.
Az assembler betétet a CODE utasítás mint kezdő és a C; utasítás mint záró elem fogja közre.

Az alábbiakban két példát mutatunk be az ASSEMBLER szótár használatára.
Az első példa egy CSWAP nevű utasítást mutat be, amely a paraméter stack tetején levő szó két byte-ját felcseréli egymással. Figyeljük meg, hogy a FORTH stílusához (fordított lengyel jelölés) alkalmazkodva a mnemonikokat is fordított sorrendben kell beírni.
Az utasítások "normál" assemblerben:

CSWAP
POP H
MOV A,L
MOV L,H
MOV H,A
PUSH H
JMP NEXT
; HL = adatszó a stack tetejéről
; L tartalma ideiglenesen A-ban
; H tartalma az L-ben
; L eredeti tartalma H-ban
; az eredmény a stack-be
; ugrás a NEXT rutinba

Ugyanez FORTH-ban:

CODE CSWAP
  H POP
  L A MOV
  H L MOV
  A H MOV
  H PUSH
  NEXT JMP
C;

Az eredményül kapott gépi kódú rutin mindkét esetben ugyanaz.
FORTH belső szerkezetének ismeretében a PUSH H utasítás elmaradhat, ha NEXT-1 címre ugratjuk a rutint. (Ott ugyanis egy PUSH H utasítás van.) Az ennek megfelelő szótári elem a NEXT 1 - CONSTANT NEXT1 definíció után:

CODE CSWAP
  H POP
  L A MOV
  H L MOV
  A H MOV
  NEXT1 JMP
C;

A következő, példaprogram a stack-ben adott címtől kezdődő n byte-ból álló ASCII karaktersorozatban elvégzi, a kisbetű/nagybetű átalakítást:

( kisbetű nagybetű átalakító 1/1)
HEX FORTH DEFINITIONS
CODE KIS-NAGY ( cím n --- )
  D POP H POP
  BEGIN D A MOV E ORA 0= NOT ( van még karakter? )
  WHILE M A MOV 60 CP CS NOT ( kisbetű? )
  IF 20 SUI A M MOV ( igen, átalakítás )
  THEN D DCX H INX ( számláló csökkentés, cím növelés )
  REPEAT
  NEXT JMP ( ugrás a NEXT rutinba )
C;

A fenti példán jól láthatjuk az ASSEMBLER magasszintű definíciós szavainak használatát. A BEGIN szó a paraméter stack tetejére helyezi az aktuális fordítási címet (DP értékét) abból a célból, hogy ezt később egy feltételes ugró utasítás argumentumaként használni lehessen. A 0= utasítás egy JNZ utasításnak felel meg, amelyből a NOT az ezzel ellentétes JZ utasítást alakítja ki, amelyet a WHILE utasítás 0 ideiglenes argumentummal helyez a definícióba, miközben a paraméter stack-re helyezi az argumentum címét.
A carry vizsgálat dönti el, hogy kell-e átalakítani, ezért a CS utasítás egy JNC gépi kódot állít elő, amelyet, a NOT utasítás az ellenkezőjére (JC) változtat. Ezt az IF utasítás ideiglenesen 0 argumentummal helyezi el a definícióban, miközben a paraméter stack-re kerül az argumentum címe.
A THEN utasítás az IF utasítás által behelyezett 0 ugró cím argumentumot a THEN utasítás helyén érvényes címre (DP) cseréli ki a paraméter stack tején lévő cím felhasználásával.
A REPEAT utasítás a paraméter stack-ben lévő BEGIN cím segítségével egy JMP utasítást alakít ki, majd a WHILE utasítás által elhelyezett címen lévő 0 argumentum értéket aktuálisan érvényes (DP) memóriacímre cseréli.
A példánkban nem szerepelt magasszintű utasítások értelmezése a következő:

PE
a JPO utasításnak megfelelő kódot állítja elő (ellentéte, a JPE, a NOT utasítással képezhető).

0<
a JP utasításnak megfelelő kódot állítja elő (ellentéte, a JM, a NOT utasítással képezhető).

ELSE
egy JMP 0 utasítást definiál, miközben a 0 argumentum címét a paraméter stack-re helyezi. Elvégzi egy előző IF utasítás által a paraméter stack-en hagyott címen a behelyezett 0 argumentum aktuális DP címre történő cseréjét.

A fentiekből látható, hogy szükség esetén a leghatékonyabb konyább gépi nyelvű betét is megírható a FORTH ASSEMBLER felhasználásával.
Assembler betét írásánál ügyeljünk arra, hogy a FORTH által használt regiszterek tartalmát ne változtassuk meg. A fig-FORTH esetén ez a BC regiszterpárra vonatkozik. (Példáinkban a BC regiszterpárt nem használtuk, de ha ez szükséges lenne az assemblerben írt program számára, akkor el kell végezni az assemler betét elején egy B PUSH utasítással a mentést. A NEXT JMP utasítás előtt egy B POP utasítással állítjuk vissza a regiszter tartalmát.)
Az ASSEMBLER szótár használatára utal még a 11. fejezetben az utasítások között, szereplő ;CODE definíció. Használatát ott leírtuk, működni csak az ASSEMBLER szótár jelenlétében tud. A ;CODE utasítást követő gépi mnemonikus utasítások sorát kötelezően a JMP NEXT utasítás zárja le, amelyet a C; utasítás követ. (Egyes verzióknál ezt az utolsó utasítást END-CODE utasításként definiálják.)

10. A FORTH használata néhány Magyarországon elterjedt számítógépen

A FORTH a CP/M operációs rendszer felügyelete alatt
A FORTH Interest Group 1979-es ajánlása szerint, készült az úgynevezett fig-FORTH, amely a CP/M operációs rendszer felügyelete alatt képes dolgozni. A CP/M operációs rendszer nyújtotta lehetőségeket ez a FORTH verzió kevésbé használja ki.
Alapvető sajátosságai a következők:

Ezen hátrányos tulajdonságok egy részét a fig-FORTH fejlesztése során sikerült, kiküszöbölni, így kialakult egy valóban a CP/M rendszer alatt futó FORTH változat. A fejetekben az eredeti fig-FORTH és a CP/M rendszer felügyelete alatt futó FORTH sajátosságait ismertetjük.

10.1. A 8080 fig-FORTH 1.1 Version
A 8080 fig-FORTH bináris (lefordított, gépikódú) programját a CP/M rendszerben a szokásos módon tölthetjük be, mint futtatandó programot. Például, ha a bináris program FORTH.COM néven szerepel a CP/M rendszer lemezen, a betöltése a FORTH parancs kiadásával lehetséges. A CP/M operációs rendszer ekkor megkeresi a diszken a FORTH.COM nevű file-t, betölti az operatív memóriába a 100H címtől kezdődően, majd a file betöltését befejezve közvetlen ugrást hajt végre a 100H címre. Ekkor a FORTH rendszer bejelentkezik á képernyőn a következő üzenettel:

8080 fig-FORTH 1.1

A felhasználó számára a képernyőn megjelenő cursor jelzi, hogy a fig-FORTH rendszer betöltődött, és a felhasználó parancsára vár. Ezután parancsokkal és utasításdefiníciókkal lehet a rendszer által nyújtott szolgáltatásokat igénybe venni.

A 8080 fig-FORTH 1.1 rendszer specialitásai:
A FORTH háttértároló utasításai a diszkre vonatkoznak.
A fig-FORTH rendszer a bekapcsolás utáni inicializálásakor a CP/M rendszerbeli "A" jelű lemezegységet jelöli meg aktuális háttértárolóként. A lemezegységet, (amelyből kettő darab lehet a rendszerben) a DR0 és DR1 FORTH utasításokkal választhatjuk ki. DR0 az "A" jelű lemezegységet DR1 a "B" jelű lemezegységet választja ki aktuális háttértárolóként.
A nyomtató kezelése a CP/M rendszerben megszokott formában történik. A fig-FORTH rendszer bekapcsolása után a nyomtató úgynevezett nyugalmi állapotban van.
Az operátori klaviatúráról a CTRL/P billentyű leütésével a nyomtató aktivizálódik, és ezután az operátori képernyőn megjelenő minden információ kiíródik a nyomtatóra is. A CTRL/P billentyű újabb leütésével a nyomtató ismét nyugalmi állapotba kerül, azaz nem történik kiírás.
A fig-FORTH megkülönbözteti a kis és nagybetűt az utasítások neveiben. Az utasítások elnevezésénél alkalmazhatunk kis és nagybetűket egyaránt, de hivatkozáskor pontosan azt a nevet kell alkalmaznunk, amelyet a definiáláskor használtunk.
A fig-FORTH hibaüzeneteit a mellékletben közöljük.

10.2. 8080 CPM-FORTH 2.2
A 8080 CPM-FORTH 2.2 a fig-FORTH rendszerrel kompatibilis, de a diszk egységet az operációs rendszer igényeinek megfelelően file struktúrában használja. A diszk egységeken file-rendszerű felírást és információkezelést végez. Egy megnyitott file belsejében a szokásos FORTH módszerrel véletlenszerű screen- illetve blokkelérés lehetséges. A diszk operációs rendszer valamennyi (A-P) egységét, elérheti. Az alapváltozat 1 kbyte méretű diszk blokkok esetén 256 kbyte maximális hosszúságú file kezelését tudja ellátni, a bemenő és kimenő file lehet ugyanaz, vagy különböző.
A 8080 CPM-FORTH 2.2 Magyarországon forgalmazott változata a diszken 3 file-ból áll.

Az elindítást az operációs rendszer bejelentkező A> üzenetére adott FORTH vagy EDFORTH legépelésével végezhetjük el. A diszk operációs rendszer a begépelt szövegnek megfelelő programot a számítógép memóriájába tölti és elindítja. A program

8080 CPM-FORTH 2.2

üzenettel bejelentkezve végrehajtási állapotban várakozik az operátor parancsára.
A 8080 CPM-FORTH 2.2 körülbelül 8 kbyte memóriaterületet foglal el az operatív tár 100H címétől kezdődően, és 2 kbyte területet igényel a memória felső részében a screen puffer terület, felhasználói változók és stack-ek részére. A felhasználható memória mérete a rendszer forrásnyelvi generálási paramétere. A legkisebb memóriaméret (figyelembe véve a diszk operációs rendszer körülbelül 6 kbyte helyigényét) 18 kbyte, ahol a felhasználó számára 2 kbyte hely áll rendelkezésre. Ennél nagyobb rendszerekben természetesen a többlet memóriát teljes egészében ki lehet használni.
A 8080 CPM-FORTH 2.2 utasításaiban a fig-FORTH utasításaival megegyezik, kivéve a diszk-kezelő utasításokat. Ennek megfelelően a DENSITY, DR0, DR1, DRIVE, OFFSET, SEC, SEC-READ, SEC-WRITE, SET-DRIVE, SET-IO, TRACK és T&SCALC utasítások nem léteznek.
A diszk-kezelő utasítások a következők:

FDOS ( n1 cim2 --- cím3 cím4 )
Az FDOS primitív feladata, hogy a diszk operációs rendszer és a FORTH között összeköttetést teremtsen. A bemenő adatok az operációs rendszer leírásában megtalálható BDOS funkciókód (n1), valamint egyes esetekben szükséges címparaméter (cím2). (Mindkét adatot küldeni kell, még akkor is, ha a kód funkciója nem igényli.)
A kimenő cím3 paraméter egyes funkciók esetén egy cím, egyébként nulla. A kimenő cím4 paraméter a funkciók lehetséges válasza. A cím3 a HL regiszter tartalmát, a cím4 a DE regiszter tartalmát jelenti. (Bővebb információ az MSYS, CP/M operációs rendszerek leírásában található.)

FCBIN ( --- cím )
Egy 166 memóriahelyet tartalmazó mező kezdőcímét adja (FCB-cím). A mező szerkezete a következő:

FCBOUT ( --- cím )
A funkció és elrendezés megegyezik, az FCBIN funkcióval, csak a kimenő file kiszolgálását végzi.

(FILE) ( cím n --- f )
Olyan operációs rendszer hívásoknál alkalmazható, ahol a BDOS funkció visszatérő kódja csak a művelet elvégzésére vonatkozó egyetlen információt tartalmaz (f).
Bemenő paraméterei a file vezérlő blokk címe (cím), és a BDOS funkciókód (n).

DELETE ( cím --- f )
A cím paraméternél (FCB-cím) megadott file törlését végzi el. A törlés sikeres végrehajtása esetén a válasz flag értéke egyenlő nullával.

READ ( cím1 --- ff vagy cím2 )
A cím1 paraméternél (FCB-cím) megadott, file-adatokkal egy szektor beolvasása az FCBIN utolsó 128 byte területére.
Sikertelen olvasás esetén a válasz 0, ellenkező esetben az információ tároló terület kezdőcíme, cím2.

WRITE ( cím1 --- ff vagy cím2 )
A cím1 paraméternél (FCB-cím) megadott file-adatokkal egy szektor írása az FCBOUT utolsó 128 byte területéről. Sikertelen diszk művelet esetén a válasz 0, ellenkező esetben a kiirt adatok tárolójának kezdőcíme (cím2)

PARSE-FILENAME ( cím1 cím2 --- )
A file-vezérlő blokk FCB címének (cím1) feltöltése a "név-cím" (cím2)-nél lévő drive és file név adatokkal, valamint a file vezérlő blokk inicializálása.
Egy file neve a CP/M operációs rendszerben három tagból ál:

  1. Drive név: A-tól P-ig egy betű, utána kettőspont.
  2. File-név: maximum 8 db alfanumerikus karakter (betűközt nem tartalmazhat)
  3. File-név kiterjesztés: a file név után . (pont) és maximum 3 db alfanumerikus karakter.

Ezek alapján a "név-cím"-en a következő formátumú adatsor lehet: B:PROBA.FTH
ahol a B: a rendszer B jelű tároló egysége, a PROBA.FTH pedig az előbbi tárolón egy file-t jelöl. A kiterjesztés a ponttal együtt opcionális. A drive megjelölés a kettősponttal együtt elhagyható, ha az aktuálisan használt diszkre vonatkozik a név kijelölés.

(FILENAME)
Segédrutin, a FILENAME rutin fordításakor használja a rendszer.

FILENAME ( cím --- )
A file név leírása előtt használjuk. Segítségével az adott FCB-címen (cím) kialakul a leírt névnek megfelelő file vezérlő blokk. Például:

FCBIN FILENAME A:SCREEN1.SCR

hatására az FCBIN file-vezérlő blokk az A drive SCREEN.SCR file vezérléséhez inicializálódik.

INPUT-FILENAME ( cím --- )
Segítségével egy programban futtatás során bekérhetjük az aktuális file nevét, amit a programunk használni fog.

OPEN ( cím --- )
A FORTH számára megnyitja az FCB-címen (cím) lévő file-vezérlő blokkal rendelkező file-t, kiszámítja és bejegyzi a teljes fizikai hosszát.

FILEIN ( --- )
Az utasítás segítségével az utána írt file-név specifikációval az FCBIN kitöltésén keresztül a FORTH számára olvasásra megnyitunk egy file-t. Például:

FILEIN B:PROBA.SCR

legépelésével a FORTH számára megnyílik a B: egység PROBA.SCR file valamennyi screen-je olvasás műveletre. Híváskor a file-specifikációt a klaviatúráról várja, definíciós utasításban is!
Megjegyzés: egy file megnyitása után a FORTH a file belsejében véletlenszerűen érheti el bármelyik 1K-s screen-t illetve 128 byte információt tartalmazó blokkot.

FILEOUT ( --- )
Funkciója és használata a FILEIN utasítással megegyező, csak az FCBOUT kitöltésével értelemszerűen írásra nyit meg.

NEWFILE ( n --- )
Segítségével a FORTH számára egy n*1Kbyte (n darab screen) hosszúságú, üres (betűköz karakterrel feltöltött file alakul ki. Használata:

5 NEWFILE B:UJPROG.SCR

Az utasítás a programnevet még kettőspont definícióban is a klaviatúráról várja. Mivel az utasítás nem helyettesíthető programozható alaputasításokkal, ezért azt tanácsoljuk, hogy egy program futása előtt a felhasználó közölje, ha új, még nem létező file igénybevételére is sor kerül.
Az utasítás működése során használja az FCBOUT utasítást a hozzá tartozó tároló területtel együtt. Ez utóbbit betűközzel tölti fel.
A NEWFILE utasítás az FCBOUT segítségével a FORTH számára kimenő file-ként meg is nyitja az előállítói új file-t.

R/W ( cím n f --- )
Az utasítás a FORTH rendszerben a háttértárolóra történő írást (f=0), vagy az onnan történő olvasást (f=1) végzi el. A cím paraméter az átviendő információ memória-pufferének kezdőcíme, n pedig az aktuális file-ban a blokkszámot mutatja.

I=O ( --- )
Az utasítás egy írásra megnyitott file-t (Output) olvasásra is megnyit (Input). Hatására az FCBIN file vezérlő része felveszi az FCBOUT megfelelő értékeit. Például az EDITOR használatánál alkalmazzuk, hogy a bemeneti és kimeneti file megegyezzen.

O=I ( --- )
Az utasítás az olvasásra megnyitott (Input) file-t írásra is megnyitja (Output). Hatására az FCBOUT file-vezérlő része felveszi az FCBIN megfelelő értékeit. Például az EDITOR használatánál alkalmazhatjuk, hogy a bemeneti- és a kimeneti-file megegyezzen.

SAVE-INIT ( --- )
Ha a memóriában egy futtatható feladatot állítottunk össze, és ezt .COM file-ként el akarjuk menteni, akkor az utasítás elvégzi a kezdő paraméterek beállítását (FENCE, HERE stb.).
Közli a képernyőn, hogy mekkora hosszal kell a CP/M operációs rendszerben a SAVE paranccsal menteni a programot.
A BYE utasítással kilépve a CP/M operációs rendszerbe elvégezhetjük a program mentését. Ha az elmentett programot, ismét betöltjük, akkor a futtatható feladat is benne lesz a FORTH rendszerben.

A 8080 CPM-FORTH hibaüzeneteit a mellékletben közöljük.

10.3. ICC DOS-80 FORTH
Az ICC DOS-80 FORTH utasításaiban, megjelenési formájában és használatában megegyezik a 8080 CPM-FORTH 2.2 változattal.
Többlet szolgáltatásai a KFKI Intelligens CAMAC keretvezérlő (ICC) kezeléséhez szükséges utasítások. Ezek a sebességi követelmények miatt gépi nyelven, primitívek formájában épültek be a rendszerbe.
Az ICC DOS-80 FORTH-ban alkalmazott további utasítások a következők:

B ( --- cím )
A CAMAC BRANCH cím tárolására szolgáló változó.

N ( --- cím )
A CAMAC állomásszám tárolására szolgáló változó.

A ( --- cím )
A CAMAC állomás alcímének tárolására szolgáló változó.

C ( --- cím )
A CAMAC keretszám tárolására szolgáló változó.

F ( --- cím )
A CAMAC funkciókód tárolására szolgáló változó.

CREAD ( --- d fq )
CAMAC "olvasó" típusú utasítás a B, N, A, C és F változók tartalmát felhasználva a kijelölt modulból olvasást végez. A 24 bites eredményt egy 32 bites dupla szóban kapjuk meg (d). A stack tetején a CAMAC Q válaszjel (fq) jelenik meg.

CWRITE ( d --- fq )
CAMAC "író" típusú utasítás a B, N, A, C és F változók tartalmát felhasználva a kijelölt modulba a 32 bites dupla adat (d) alsó 24 bit információját írja. A stack tetején a CAMAC Q válaszjel (fq) jelenik meg.

CCONTROL ( --- fq )
CAMAC "vezérlő" típusú utasítás a B, N, A, C és F változók tartalmát felhasználva kiadja a CAMAC vezérlő utasítást. Válaszként a CAMAC Q válaszjel jelenik meg a stack tetején.

CIREAD ( nf nc na nn nb --- d fq )
CAMAC modul "olvasó" típusú utasítás a stack-en tárolt nf , nc, na, nn, nb adatokat, felhasználva a kijelölt modulból olvasást végez. A 24 bites eredményt egy 32 bites dupla szóban (d) kapjuk meg. A stack tetején a CAMAC Q válasz jel (fq) jelenik meg.

CIWRITE ( nf nc na nn nb d --- fq )
CAMAC modul "író" típusú utasítás a stack-en tárolt nf, nc, na, nn, nb adatokat felhasználja a CAMAC modul és funkció kijelölésére, a d 32 bites dupla szó alsó 24 bitjét pedig a beírandó adatként kezeli. A stack tetején a CAMAC Q válaszjel (fq) jelenik meg.

CICONTROL ( nf nc na nn nb --- fq )
CAMAC "vezérlő" típusú utasítás a stack-ben tárolt nf, nc, na, nb adatokat felhasználva CAMAC utasítást állít elő. A stack tetején a CAMAC Q válaszjel jelenik.

XERROR ( --- cím )
A CAMAC utasítások végrehajtása során keletkező x válaszjel tárolását végző változó.

Az ICC DOS-80 FORTH hibaüzeneti a 8080 CPM-FORTHhibaüzenetivel megegyezőek.

10.4. SIF-Z80 FORTH 2.2.
A SIF-Z80 FORTH 2.2. a CP/M operációs rendszer alatt futtatható FORTH, amely elsősorban vezérlési feladatok megoldására szolgál. Igen sok helyen eltér a szabvány FORTH-tól: a sok egyszerűsítés mellett jelentős mennyiségű speciális szolgáltatással rendelkezik. Három beépített adattípusa van:

A karakterfüzérek a vermen és a szótárban a következő módon tárolódnak:

0 A1 A2 A3 ... An (n+2)*2

Ai magas bájtja tartalmazza a füzér i-edik karakterének kódját (az alacsony bájt értéktelen), n pedig a füzér hossza.
A szabványtól a szavak belső ábrázolása is eltér. Az alapszótár szavainál nincs csatolómező, a felhasználói szótár szavainál a csatolómező helyén egy listamutató mező van. A szavak láncolását egy, a névmezőben található eltolás segítségével valósítja meg (NFAi+i = NFA i+eltolás).
A SIF-Z80 FORTH minden szódefiníció forrásszövegét is tárolja, ASCII karakteres formában. Minden felhasználói szó listamutatója saját forrásszövegére mutat. A teljes lista módosítható a beépített editorral, újrafordítható, kiírható a lemezre CP/M fájl formájában, onnan bármikor újból visszaolvasható és lefordítható. Ezzel helyettesítettük a kissé körülményes screen kezelést.
A következőkben közöljük a szabvány FORTH-tól eltérő működésű szavakat, majd pedig a beépített speciális funkciókat.

.B ( n --- )
n-et binárisan írja ki.

.H ( n --- )
n-et hexadecimálisan írja ki.

VOCABULARY
A szótár szavainak nevét és cfa-ját írja ki. A FORTH-79 VLIST utasításához hasonló.

VLIST ( n --- )
A felhasználói szótár szavait írja ki a képernyőre, definíciójukkal együtt.

LIST ( n --- )
LIST szónév hatására a szódefiníció forrásszövegét írja ki

DO ... +LOOP
A /LOOP kivételével az összes FORTH-79 feltételes és vezérlőszerkezet megtalálható, és egyedül a DO ... +LOOP szintaktikája eltérő:

nköz nvég nkezdő DO szósor +LOOP

tehát az nköz a cikluson kívül adandó meg.

# ( --- cím )
A következő szó névmezőcímét teszi a veremre.

NFA ( --- nfa )
Rendszerváltozó, amelyben a legutoljára definiált szó névmezőcíme van.

CFA ( --- cfa )
Rendszerváltozó, amelyben a legutoljára definiált szó kódmezőcíme van.

PFA ( --- pfa )
Rendszerváltozó, amelyben a legutoljára definiált szó paramétermező-címe van.

TYPE ( cím --- )
Kiírja címtől kezdve az ott található bájtokat, ASCII karakterek formájában. A kiírást egy 0 bájt megtalálásáig folytatja.

HEX ( n1 --- n2 n3 )
n2 és n3 ni alsó két bájtja hexa számjegyének ASCII kódja lesz.

SWAB ( n1 --- n2 )
n1 k-ét bájtját felcseréli.

^ ( n1 n2 --- n3 )
Egész hatványozás. n3=n1^n2

TRUE ( --- 1 )
Igaz értéket szolgáltató feltétel konstans.

FALSE ( --- 0 )
Hamis értéket szolgáltató fel tétel konstans.

SYSLIB ( --- )
Ha valamelyik szódefiníció után SYSLIB-et írunk, akkor ez és az ezt megelőző szavak rendszerszóként értelmeződnek, és rájuk a FORGET, LIST, VLIST szavak hatástalanok.

RESTORE ( --- )
Megszünteti a SYSLIB hatását.

LOAD ( fn --- )
A vermen levő füzért file-névként értelmezve beolvassa és lefordítja az adott fájlban levő szótárt.

SAVE ( fn --- )
Hatására az eddig definiált felhasználói szótár forrás-szövegű listája a lemezre kerül. A vermen lévő fűzér lesz a file-név.

NEW ( --- )
A memóriában levő alap- és felhasználói szótárakból egy új FORTH rendszert generál, majd kiírja annak hosszát bájtokban. Ezután a BYE paranccsal visszatérhetünk a CP/M-be és annak SAVE utasításával az új rendszert .COM kiterjesztéssel a lemezre menthetjük.

RECOMP ( --- )
A RECFROM rendszer változóban tárolt listacímtől kezdve újrafordítja a szótárat a forrásszöveg felhasználásával.

UERROR ( n --- )
A vezérlést a felhasználó által definiálható tetszőleges hibakezelő szóra adja. A hibakezelő szó n-et mint hibakódot használhatja fel.

ERR ( --- )
A felhasználó által definiált hibakezelő szó törzsének kötelezően az ERR az első szava. Az UERROR az ERR-t tartalmazó szóra adja a vezérlést.

DIR ( fn --- )
A "fájlnév" DIR parancs egyenértékű a CP/M DIR fájlnév parancsával.

ERA ( fn --- )
A "fájlnév" ERA parancs egyenértékű a CP/M ERA fájlnév parancsával.

INOPEN ( fn --- )
Hatására a FORTH az adott file-t szekvenciális olvasásra megnyitja.

OUTOPEN ( fn --- )
Hatására a FORTH az adott file-t szekvenciális írásra megnyitja.

INCLOSE ( --- )
A FORTH lezárja az olvasásra megnyitott file-t.

OUTCLOSE ( --- )
A FORTH lezárja az Írásra megnyitott file-t.

READ ( --- n )
Beolvas egy byte-ot az olvasásra megnyitott file-ból, és azt a veremre teszi, n felső bájtja nulla lesz.

WRITE ( n --- )
n alsó bájtját az írásra megnyitott file-ba írja.

IM0 ( --- )
A Z80 0-ás megszakításmódját állítja be.

IM1 ( --- )
A Z80 1-es megszakításmódját állítja be.

IM2 ( --- )
A Z80 2-es megszakításmódját állítja be.

HALT ( --- )
Hatására a processzor egy HALT utasítást hajt végre és megszakításra várakozik.

CODE ( cím --- )
Szubrutinként meghívja a címen kezdődő gépi kódú programot. A rutinból RET utasítással kell visszatérni.

CALL ( cím AF BC DE HL --- AF BC DE HL )
Meghívja a címen kezdődő gépi kódú szubrutint a Z80 regisztereinek megfelelő sorrendű feltöltésével. A rutinból való visszatérés után a regiszterek tartalma a veremre kerül a fenti sorrendben.

IT ( --- )
A szódefiníció törzsében elsőnek szereplő IT szó hatására maszkolható megszakítás esetén az így definiált szóra kerül a vezérlés.

NMI ( --- )
A szódefiníció törzsében elsőnek szereplő NMI szó hatására nem maszkolható megszakítás esetén az így definiált szóra kerül a vezérlés.

ITNMI! ( --- )
Végrehajtása után az eddigi megszakításrutinok helyett az IT-t, ill. NMI-t tartalmazó szavak fogják elvégezni a megszakításkezelést.

El ( --- )
Engedélyezi a maszkolható megszakítást.

Dl ( --- )
Letiltja a maszkolható megszakítást.

IN ( n1 --- n2 )
Az n1 portcímről beolvas egy byte-ot és a veremre teszi. n2 felső byte-ja nulla lesz.

OUT ( n1 n2 --- )
Az n1 alsó byte-ja kiíródik az n2 portcímre.

BMOV ( 0 n1 n2 ... ni cím --- nb )
Címtől kezdődően lerakja az ni-től a nulláig a számok magas bájtját. A letett bájtok számát (nb) a vermen visszaadja.

A további szolgáltatások .FTH kiterjesztésű file-okban találhatók. Így ezeket csak akkor kell beolvasni, ha szükség van rájuk, egyébként nem foglalják el feleslegesen a memóriát. Ezeket a lemezen tárolt szótárakat csak vázlatosan ismertétjük. A két assemblert nem számítva összességükben körülbelül 200 új szóval bővítik az alapszótárat.

REAL.FTH
Ez tartalmazza a teljes lebegőpontos aritmetikát:

STRING.FTH
Olyan szavak definícióit tartalmazza, melyek paraméterei füzérek:

ARRAY.FTH, ARRAYX.FTH, ARRAY$.FTH
Egész, lebegőpontos és karakterfüzér-vektorok és mátrixok definiálását teszi lehetővé.

CURSOR.FTH
A file a mindenkori terminál kurzorvezérlő szavait (CLEAR, HOME, UP, stb.) és kódjait tartalmazza. A képernyő-editornak például ez az egyetlen display-függö szótára.

EDIT.FTH
Egy képernyő-orientáit editort tartalmaz, amellyel szavainkat javíthatjuk és módosíthatjuk. Az EDIT szónév utasítás hatására a képernyő törlődik és megjelenik az adott szó definíciójának szövege. Ezt szerkeszthetjük a kurzormozgató és DEL billentyűkkel, valamint tetszőleges beszúrásokat alkalmazhatunk. A szerkesztés befejeztével a FORTH újrafordítja a szótárt az adott szótól kezdődően.

TKB.FTH
Ez a SIF-Z80 FORTH task buildere. Segítségével a FORTH-ban megirt szótárakat egy közvetlenül (a FORTH rendszer behívása nélkül) futtatható állománnyá szerkeszthetjük össze. A szerkesztés kétféle lehet:

Mind két esetben a TKB eltávolítja a szótárból a végrehajtáshoz felesleges információkat (névmezö és listamutatómező), valamint kihagyja az alapszótárból az összes olyan szót, amelyek a FORTH program futásához szükségtelenek. Az így keletkező, csak szótörzsekből álló programot ezután a szerkesztéstől függően 100h-ra vagy a felhasználó által megadott címre relokálja. A leszerkesztett program az eredeti szótárnál lényegesen rövidebb lesz.

IB0.FTH, Z80.FTH
A két fájl egy-egy assemblert tartalmaz.

DIS.FTH
Ebben a file-ban egy FORTH "decompiler" található, amely lehetővé teszi akár az alap-, akár a felhasználói szótár szavainak visszafejtését szótárbeli törzsük alapján.

10.5. ABC80 FORTH
A Magyarországon elsők között elterjedt ABC80 típusú személyi számítógép RAM memóriáját 32 kbyte-ra bővítették. Egy MFM-2 diszk egységet illesztettek hozzá, amelyet egy "CP/M szerű" operációs rendszer szolgál ki.
Ebben a rendszerben fut a 8080 CPM FORTH 2.2-vel megegyező FORTH program. Az alapváltozathoz képest az eltérés annyi, hogy az ABC80 gép 0H-7FFFH címtartománya csak olvasható (ROM) memóriát tartalmaz, így az egész rendszer kezdőcíme 8100H-ra tolódik át. Ebben a rendszerben csak a felső 32 kbyte memóriatartományt használhatja az ABC80 FORTH.
A rendszer utasításai és hibaüzenetei a 8080 CPM FORTH 2.2-vel megegyeznek.

10.6. Spectrum FORTH
A Spectrum FORTH-ot az ARTIC Computing Limited készítette, 48 Kbyte operatív memóriával rendelkező, ZX SPECTRUM mikroszámítógépekhez. A gépikódú programot mágnesszalagról lehet betölteni a LOAD "" CODE utasítás sorozattal. (A CODE az I billentyű kiterjesztett üzemmódja.)
A gépikódú program betöltése után automatikusan elindul a FORTH rendszer és a következő üzenettel' jelentkezik be a képernyőn:

SPECT ZX- FORTH 1.1
(c) 1982 ARTIC COMPUTING LTD.
ALL RIGHTS RESERVED
32470 BYTES FREE

A cursor jelzi, hogy a FORTH rendszer várja parancsainkat. A parancsokat kis- vagy nagybetűvel is megadhatjuk.
A Spectrum FORTH utasításai részben megegyeznek a fig-FORTH utasításaival, speciális utasításai a következők:

AT (n1 n2 --- )
A képernyő cursort az n1. sor n2. oszlopára állítja (0 <= n1 <= 21; 0 <= n2 <= 31).

BEEP ( n1 n2 --- )
A ZX SPECTRUM beépített hangszórójának működtetése, n1 a hang időtartama másodpercben, n2 a hangmagasság.

BORDER ( n --- )
A képernyő keretszínét állítja be az n értékének megfelelően ( 0<= n <= 7).

BRIGHT (n --- )
A kiirt karakterek fényességét állítja be.
n=0 normál fényességű,
n=1 kiemelt fényességű kiírás.

CIRCLE ( n1 n2 n3 --- )
Egy kört rajzol a képernyőre, amelynek n1 a sugara n2, n3 a középpontja. (n2 = x; n3 = y)

CLS ( --- )
Törli a képernyőt, és a cursor-t a bal -felső sarokba mozgatja.

COPY ( --- )
A képernyőn lévő információt a printeren kinyomtatja.

DEF ( b1 b2 b3 . b8 n1 --- )
A felhasználó által definiált grafikus karaktert lehet az utasítással előállítani.
n1 értéke 144 és 164 között változhat, ezek a felhasználó által definiálható grafikus karakterek kódjai.
b1 b2 ... b8 a grafikus karakter definiáló byte-jai.
Az utasítás végrehajtása után az n1 kódú grafikus karakternek a b1 b2 . b8 által definiált grafikus karakter felel meg, amelyet, a karakter kiviteli utasítással kiírhatunk. Például a

HEX
FF 81 81 81 81 81 81 FF
DECIMAL
144 DEF

egy négyzet alakú karaktert definiál a 144 (decimális) karakterkóddal.

DRAW ( n1 n2 --- )
Egy vonalat rajzol az aktuális rajzoló pozíciótól X irányban n1, Y irányban n2 növekménnyel. Nem ad hibajelzést, ha az új pozíció az ábrázolható tartományán kívülre esik. (0 <= X <= 255, 0 <= Y <= 175)

FLASH ( n --- )
A kiírt karakter villogását állítja be.
n=0 normál,
n=1 villogó kiírás.

GOVER ( n --- )
A karakter felülírást vezérli,
n=0 a régi karakter felülírható az új karakterrel,
n=1 a régi és az új karakter kizáró vagy kapcsolata íródik ki.

HOME ( --- )
A cursor-t a bal felső sarokba mozgatja.

INK ( n --- )
Beállítja a tinta (az előtér) színét. (0 <= n <= 9)

INV ( n --- )
A karakter kiírását vezérli,
n=0 normál kiírás,
n=1 inverz video kiírás.

NEXT ( --- cím )
Konstans, melyet a FORTH ASSEMBLER használ fel.

PAPER ( n --- )
Beállítja a papír (a háttér) színét. (0 <= n <=9 )

PERM ( --- )
A tinta és a papír színét állandósítja, permanenssé teszi.

PLOT (n1 n2 --- )
Kirajzol egy, a tinta színével megegyező pontot az n1, n2 pozíciónál (n1=X, n2=Y), és a rajzolás pozícióját beállítja az n1, n2 által meghatározott, helyre.

PRINT ( --- cím )
A printer nyugalmi/aktív állapotát vezérlő változó.

RSMUDGE ( --- )
Törli (0 értékre állítja) a smudge bitet a legutoljára definiált szótári bemenet fejrészében.

A SPECTRUM FORTH-ban a <CR> billentyűinek az ENTER billentyű felel meg.
A kis betűket tartalmazó utasításnevek kisbetűs karaktereit egységesen nagy betűkre alakítja át a rendszer így csak nagy betűket tartalmazó utasításneveket használ.
A ZX SPECTRUM-hoz kapcsolódó printer nyugalmi/aktív állapotát a PRINT változóval lehet beállítani.

A SPECTRUM FORTH háttértárolóként a kazettás szalag egységet használja. Innen tud forrásnyelvi szöveget vagy adatokat tartalmazó számozott screen-eket beolvasni, illetve ide tudja kiírni őket. A mágnesszalag egységen tárolt forrásnyelvi programot a LOAD utasítással lehet betölteni és lefordítani. Például az

1 LOAD

hatására a számi tógép a READY CASSETTE választ adja. A kazettás magnetofon elindítása után az ENTER billentyűvel lehet az 1-es számú screen beolvasását elkezdeni.
A forrásnyelvi screen-ek tárolása a FLUSH utasításául lehetséges, ekkor a számítógép szintén a READY CASSETTE választ adja, majd a kazettás magnetofon felvétel állásba állítása és elindítása után, az ENTER billentyű leütésével megtörténik a screen felvétele mágnesszalagra.
A SPECTRUM FORTH hibaüzeneteit lásd a mellékletben.

A screen-ben történő szövegszerkesztéshez használható fel a SPECTRUM FORTH EDITOR-a. A SPECTRUM FORTH EDITOR utasításait forrásnyelvi screen-ekben tárolja a rendszer. A sorok hosszúsága a screen-ekben 64 karakter.
A SPECTRUM FORTH EDITOR utasításai:

Screen szerkesztő utasítások

CLEAR ( n --- )
Az n. screen-t kijelöli a szerkesztéshez, és feltölti szóköz karakterekkel.

FLUSH ( --- )
A szerkesztés végén használjuk, hogy a screen-t mágnesszalagra mentsük.

L ( --- )
Az aktuális screen listázását végzi el.

LIST ( n --- )
Az n. screen-t listázza ki, és kiválasztja szövegszerkesztéshez. Ha az n. screen nincs a memória pufferben, beolvassa a mágnesszalagról.

Sorszerkesztő utasítások

D ( n --- )
Törli az n. sort a screen-ben, és tárolja a PAD-ban (Delete).

E ( n --- )
Feltölti az n. sort szóköz (space) karakterekkel (Erase).

H ( n --- )
Az n. sort tárolja a PAD-nál (Hold).

I ( n --- )
A PAD-nál lévő szöveget az n. sorba írja az utasítás, A régi n. sor és az utána következő sorok egy sorral lejjebb csúsznak. A 15. sort elveszítjük (Insert).

P ( n --- )
Az utasítás után következő szöveget elhelyezi a screen n. sorában (Put).

R ( n --- )
Az n. sor tartalmát helyettesíti a PAD-ban lévő szöveggel (Replace).

S ( n --- )
Új sor beszúrása az n. sornál. A régi n. sor és az utána következő sorok egy sorral lejjebb csúsznak. A 15. sort elveszítjük. Az új n. sor szóköz karakterekkel lesz feltöltve (Spread).

T ( n --- )
Kiírja az n. sort és tárolja a PAD-ban (Type).

Cursor-vezérlő utasítások

M ( n --- )
A cursor-t az előjeles n értékével elmozdítja az adott sorban, és kiírja a sort. A cursor az "_" (aláhúzás) karakter (Move).

TOP ( --- )
A cursor pozícióját a szerkesztés alatt álló screen kezdőpozíciójára állítja.

Szövegszerkesztő utasítások

B ( --- )
Visszalép a cursor-ral a PAD-nál lévő szöveg hosszának megfelelő értékkel (Back).

C szöveg ( --- )
Bemásolja az utasítás után következő szöveget, a cursor pozíciójához a cursor sorában (Copy).

F szöveg ( --- )
Az utasítás után következő szöveget bemásolja a PAD-hoz, és keresi a cursor pozíciójától a screen végéig (Find).

N ( --- )
A PAD-nál lévő szöveg következő előfordulását keresi (Next).

TEXT szöveg ( c --- )
Az utasítás után következő szöveget a PAD-hoz továbbítja az utasítás. A szöveg végét határoló karakter bemenő paraméterként megadott c karakter.

TILL szöveg ( --- )
A cursor sorában a cursor-tól az utasítás után következő szövegig törlődik minden a sorból.

WHERE ( n1 n2 --- )
Ahol n1 egy blokkszám n2 pedig a blokkon belüli kezdőcímhez képesti eltolás. Ha a háttértárolóról töltjük be a forrásnyelvi szöveget, a betöltéskor fellépő hiba helyét lehet, az utasítással meghatározni.

X szöveg ( --- )
Törli az utasítás utáni szöveg következő előfordulását a cursor sorában (extract).

10.7. Abersoft FORTH
Az Abersoft FORTH szintén a fig-FORTH-nak a 48 kbyte-os ZX SPECTRUM-on megvalósított változata. Betöltése a mágnesszalagról a LOAD "" vagy LOAD "FORTH" utasításokkal lehetséges.
Az Abersoft FORTH két részből áll, egy BASIC nyelvű monitor programból és a gépikódú FORTH rendszerből. A programok betöltése után a

48k SPECTRUM FIG-FORTH 1.1 A (c)
Abersooft: 1983

üzenettel jelentkezik be a képernyőn. A villogó C, betű mint cursor azt jelzi, hogy a klaviatúra nagybetűs állapotban van. A betűváltó (CAPS SHIFT 2) segítségével villogó L betűs cursor-ra tudunk váltani, ekkor kisbetűkkel írhatunk a klaviatúráról.
A cursor ezen kívül a CAPS SHIFT és 9 billentyűikkel grafikus állapotba állítható. Ezt villogó B betű jelzi. Ilyenkor grafikus karaktereket tudunk a rendszerbe juttatni a klaviatúráról.
Az Abersoft FORTH utasításai részben megegyeznek a fig-FORTH utasításaival, speciális utasításai a következők:

(TAPE) ( n --- )
Mágnesszalag egység kezelő rutin.

2CONSTANT
2VARIABLE
2DROP
2OVER
2SWAP
2ROT

A 16 bites számokkal végzett műveletek 32 bites számokra vonatkozó megfelelői.

AT ( n1 n2 --- )
A képernyő cursor-t a n1. sor n2. oszlopára állítja. (0 < = n1 <= 21 , 0 <= n2 <= 31)

ATTR ( n1 n2 --- b )
Az utasítás a képernyő n1. sorában az n2. oszlop pozícióhoz tartozó állapot-byte-ot adja meg. (0 <= n1<= 21, 0 <= n2 <= 31)

BLEEP ( n1 n2 --- )
Az utasítás egy n1 hosszúságú és n2 magasságú hangot ad ki a ZX SPECTRUM hangszóróján. Az értékek gépikódú ciklusok paraméterei, így a különböző hangok előállítása kísérletezést kíván.

BRIGHT ( n --- )
A karakter kiírás fényességét állítja be,
n=0 normál,
n=1 kiemelt fényességű kiírás.

BORDER ( n --- )
A keret színét állítja be n értékének megfelelően. (0 <= n <= 7)

CASE
A 12. fejezetben részletesen ismertetendő CASE struktúra utasítása.

CLS ( --- )
Törli a képernyőt, és a cursor-t a bal felső sarokba mozgatja.

DRAW ( n1 n2 --- )
Egy egyenes vonalat rajzol az aktuális rajzoló pozíciótól (a PLOT vagy korábbi DRAW utasítással állítható be) az n1, n2 pozícióhoz (n1<=X, n2=Y). Az n1 és n2 abszolút koordináták, a rajzolási tartományon kívül eső pontokat nem veszi figyelembe.

ENDCASE
ENDOF

A 12. fejezetben részletesen ismertetendő CASE struktúra utasításai.

FLASH ( n --- )
A kiírt karakter villogását állítja be,
n=0 normál,
n=1 villogó kiírás.

FREE ( --- n )
Az utasítás a paraméter stack-re helyezi a szabad memória nagyságát byte-ban.

GOVER ( n --- )
A karakter felülírását vezérli,
n=0 a régi karakter felülírható az új karakterrel,
n=1 a régi és az új karakter kizáró vagy kapcsolatával keletkezett karaktert írja ki.

INIT-DISC ( --- )
A RAM-DISC területet szóköz (space) karakterekkel tölti fel, és kijelöli a RAM-DISC-et a további felhasználáshoz.

INK ( n ---- )
Beállítja a tinta (az előtér) színét. (0 <= n <= 9)

INKEY ( --- n )
Az utasítás végrehajtásakor lenyomott billentyű kódját adja meg kimeneti paraméterként. Ha az utasítás végrehajtásakor nincs lenyomott billentyű, akkor a 255 decimális értéket hagyja a paraméter stack-en.

INP ( n --- b )
Az n. portról beolvasott értéket hagyja a páréter stack-en.

INVERSE ( n --- )
A karakter kiírását vezérli
n=0 normál kiírás,
n=1 inverz video kiírás.

LINK ( f --- )
A printer nyugalmi/aktív állapotát vezérlő utasítás.

LOADT ( --- )
Betölti mágnesszalagról a RAM-DISC területre azt Az információt, amelyet korábban a SAVET utasítással mentettünk szalagra.

MON
Visszatérés a BASIC-be.

NEXT ( --- cím )
Konstans, amelyet a FORTH ASSEMBLER használ fel.

OF
A 12. fejezetben részletesen ismertetendő CASE struktúra utasítása.

OUTP ( b n --- )
A b értékét elküldi az utasítás az n. portra.

PAPER ( n --- )
Beállítja a papír (a háttér) színét. (0 <= n <= 9)

PLOT (n1 n2 --- )
Kiír egy, a tinta színével megegyező pontot, az n1, n2 pozíciónál (n1=X, n2=Y), és a rajzolás pozícióját beállítja az n1, n2 álltai meghatározott helyre.

POINT ( n1 n2 --- f )
Az utasítás megvizsgálja, hogy az n1=X és n2=Y pozíciónál lévő grafikus pont bekapcsolt állapotban van-e.
Az f logikai igaz érték, ha bekapcsolt állapotban van, logikai hamis ellenkező esetben.

SAVET ( --- )
Tárolja a RAM-DISC területen lévő információt mágnesszalagra DISC névvel. A tárolt információ a LOADT utasítással tölthető vissza.

SCREEN ( n1 n2 --- c )
Az n1. sor n2. oszlopában lévő karakter ASCII kódját adja meg az utasítás, ha a karakter nem a felhasználó által definiált karakter.

SIZE ( --- n )
Az utasítás a paraméter stack-re helyezi a FORTH rendszer szótára által elfoglalt memória nagyságát byte-ban.

U.R ( u n --- )
Az u előjel nélküli, egyszeres pontosságú számot, írja ki az utasítás a képernyőre egy n szélességű mező jobb széléhez illesztve. A szám után nem ír ki szóköz karaktert.

U/MOD ( ud u1 --- u2 u3 )
Az utasítás egy előjel nélküli dupla pontosságú számot oszt el egy előjel nélküli egyszeres pontosságú számmal. A maradék u2, a hányados u3.

UDG ( --- cím )
Az utasítás a felhasználó által definiált karakter kezdőcímét adja meg.

VERIFY ( --- )
Az utasítást a mágnesszalagon tárolt információ ellenőrzésére használjuk.
Ha a felvételben hiba van, a FORTH rendszerből visszatérünk a BASIC rendszerbe. Ilyenkor a FORTH rendszer újra elindítható a GOTO 3 utasítással (warm start), és újra megkísérelhető a SAVET utasítássál a RAM-DISC tartalmának mentése.

AZ ABERSOFT FORTH-ban a <CR> billentyűnek az ENTER billentyű felel meg.
A kisbetűket és a nagybetűket külön kezeli a rendszer, így a definíciókra ugyanazzal a karaktersorozattal kall hivatkoznunk, mint amellyel definiáltuk őket.
A ZX SPECTRUM-hoz kapcsolható nyomtató nyugalmi/aktív állapotát a LINK utasítással lehet beállítani.

Az Abersoft FORTH háttértárolóként a MICRODRIVE-ot, vagy az operatív memóriában kialakított RAM-DISC-et használja. A MICRODRIVE helyettesítését szolgálja a memóriából kialakított RAM-DISC. Ez egy 10 kbyte nagyságú memóriaterület, amelyben így 10 screen helyezhető el. Számozásuk 1-től 10-ig történik. A RAM-DISC területet MICRODRIVE nélküli rendszerben ugyanúgy használhatjuk, mintha háttértároló lenne. Módosíthatjuk, listázhatjuk, betölthetjük a tartalmát. Mivel a berendezés kikapcsolásakor a RAM memóriatartalma elvész, ezért a RAM-DISC tartalmát mágnesszalagra menthetjük, és onnan tölthetjük be újra (SAVET, LOADT, VERIFY).
Az Abersoft FORTH háttérmemóriát kezelő utasításai MICRODRIVE-ra vonatkoznak, amely ugyanúgy kezelhető, mint a fig-FORTH-ban a diszk egység.
A szövegszerkesztésre az Abersoft FORTH eredeti rendszerébe beépített EDITOR-t használhatjuk. Az EDITOR utasításai megegyeznek a SPECTRUM FORTH-nál leírt utasításokkal.
Az UDG utasítás a felhasználó által definiált grafikus karakterek kezdőcímét adja meg. Ezen kezdőcímhez képest 8 byte-onként helyezkednek el a különböző grafikus karakterek, Például az UDG+0 címtől az UDG+7 címig a grafikus A betű, az UDG+8 címtől az UDG+15 címig a grafikus B betű és így tovább.
Egy hasznos utasítást adunk meg a következőkben, amellyel definiálni tudjuk saját grafikus karaktereinket.

: DEFINE ( b1 b2 b3 ... b8 n --- )
8 * UDG + DUP 8 + SWAP
DO I C! LOOP ;

A DEFINE utasításban n 0 és 21 közötti értéket vehet fel, mivel ennyi grafikus karakter van. A b1-től b8-ig megadott byte értéket a felhasználó által definiált grafikus karakter definícióját (bitmintáját) adják meg. Az utasítás használata például

HEX
FF 81 81 81 81 81 81 FF
2 DEFINE

amely a grafikus c betűhöz rendelt, egy üres négyzet, szimbólumot.
AZ Abersoft FORTH hibaüzeneteit a mellékletben közöljük.

10.8. ZX Spectrum 48k Floating Point FORTH
A FORTH rendszer a LOAD "" utasítással tölthető be kazettáról. A lebegőpontos FORTH nem "ok" üzenetet ír ki, hanem a következő sorba egy ...> promptot. Interpreter módban is kell a parancssorok végére a pontosvessző. Például:

6 2 + . ;

Minden szám 6 bájtot foglal el a vermen. Lebegőpontos számoknál 5 bájt értékes, 1 bájt értéktelen, egész számoknál 2 bájt értékes, 3 bájt nulla, 1 bájt értéktelen. A lebegőpontos számokban vagy tizedespont (14.9, -.073) vagy E van (2E9, 7E-3, -8.4E7). Az egész számok csak számjegyeket és előjelet tartalmaznak (1, 973, -1961). Lebegőpontos szám helyett minden esetben állhat egész, mert erre a konverzió automatikus. Egész helyett lebegő viszont soha nem alkalmazható.
A szavak neve tetszőlegesen hosszú lehet, de csak az első hat karakter kerül tárolásra. A kis- és nagybetűk különbözőnek számítanak. A lebegőpontos FORTH a SPECTRUM eredeti hibajelzéseit használja. Hiba esetén GOTO 4050 vagy GOTO 3 utasítással térhetünk vissza a FORTH-ba.
A következőkben közöljük a lebegőpontos FORTH szavait, témakörök szerint csoportosítva.

z ( --- )
Hatására a képernyő tartalma a nyomtatóra kerül.

pron ( --- )
Hatására minden további szöveg a nyomtatóra kerül és a képernyőn nem jelenik meg.

proff ( --- )
Semlegesíti pron hatását.

s ( --- )
Az egész FORTH rendszer és a felhasználói szótár szalagra mentését az s utasítással kezdeményezhetjük. Ezután meg kell adni a program nevét, ami legfeljebb 10 karakterből állhat, és nem tartalmazhat szóközt. A mentés három részletben történik. Ezután vissza kell tekerni a program elejére, és egy ellenőrző olvasás történik. Ha nincs hiba, "OK" üzenet jelenik meg, ha van, akkor break GOTO 2010 után újból meg kell kísérelni a mentést.

. ( l --- )
Lebegőpontos szám kiírása.

%. ( n --- )
Egész szám kiírása.

FIELD ( l --- )
A következő 16 karakteres mezőre lép, és kiírja a számot jobbra igazítva.

%FIELD ( n --- )
A következő 8 karakteres mezőre lép, és kiírja a számot jobbra tömörítve.

INT ( l --- n )
Lebegőpontos szám egészrészét képezi.

SQR ( l1 --- l2 )
l2 l1 négyzetgyöke.

RND ( --- l )
Véletlenszámot generál. 0 <= l < 1.

SINR ( l1 --- l2 )
l1 szinuszát számolja. l1 radiánban értendő.

COSR ( l1 --- l2 )
l1 koszinuszát számolja. l1 radiánban értendő.

TANR ( l1 --- l2 )
l1 tangensét számolja. l1 radiánban értendő.

ASNR
ACSR
ATNR
( l1 --- l2 )
A megfelelő szögfüggvények inverz függvényei. Az eredmény (l2) radiánban képződik.

SIND
COSD
TAND
( l1 --- l2 )
Szögfüggvények, ahol l1 fokokban adandó meg.

ASND
ACSD
ATND
( l1 --- l2 )
Inverz szögfüggvények, ahol az eredmény (l2) fokokban képződik.

LN ( l1 --- l2 )
l1 természetes ( e alapú ) logaritmusa. l1>0.

EXP ( l1 --- l2 )
A logaritmus-függvény inverze.

^ ( l1 l2 --- l3 )
Hatványozás. l3 = l1^l2

+
-
*
/
1+
1-
2+
2-
NEGATE
ABS

Funkciójukban a FORTH-79 hasonló szavaival egyeznek meg, de bemenő és kimenő paramétereik lebegőpontos számok.

<
>
=
<=
>=
<>
( l1 l2 --- f )
Logikai műveletek két lebegőpontos szám összehasonlítására. f=0 a hamis, f =1 az igaz érték.

0<
0>
0=
( l --- f )
Lebegőpontos szám és a nulla összehasonlítása.

MIN ( l1 l2 --- l3 )
l1 la l2 lebegőpontos értékek közül a kisebbet választja ki.

MAX ( l1 l2 --- l3 )
l1 la l2 lebegőpontos értékek közül a nagyobbat választja ki.

AND ( l1 l2 --- l3 )
Ha l2 nulla, akkor l3=0, egyébként l3=l1.

OR ( l1 l2 --- l3 )
Ha l2 nemnulla, akkor l3=1, egyébként l3=l1.

NOT ( l1 l2 --- l3 )
Ha l1 nulla, akkor l2=1, egyébként l2=0.

%+
%-
%*
%/
%1+
%1-
%2+
%2-
%NEGATE
%ABS
%<
%>
%=
%<=
%>=
%<>
%0<
%0>
%0=
%MIN
%MAX
%AND
%OR
%NOT

A lebegőpontos műveletek egész számokra vonatkozó megfelelői.

DROP
DUP
?DUP
SWAP
OVER
PICK
ROT
ROLL

A FORTH-79 megfelelő veremműveletei, csak itt egy logikai veremszint nem kettő, hanem hat bájt.

BEGIN...UNTIL
BEGIN...WHILE...REPEAT

Megegyeznek a FORTH-79 hasonló ciklusaival.

DO...LOOP
A kezdő- és a végérték egyaránt lehet lebegőpontos szám.

DO ... +LOOP
A kezdő-, vég- és lépésközérték lebegőpontos, de a lépésköz csak pozitív lehet.

DO ... -LOOP
Ugyanaz, mint a DO...+LOOP, de itt a lépésköz (amely szintén csak pozitív lehet) levonódik a ciklusváltozóból.

I ( --- l )
A lebegőpontos ciklusváltozót teszi a veremre.

J ( --- l )
Egymásba ágyazott ciklusoknál belülről a második ciklus ciklusváltozóját adja meg.

K ( --- l )
Belülről a harmadik ciklus változóját adja meg.

LEAVE ( --- )
A lebegőpontos ciklusváltozót a végértékre állítja.

EXITLP ( --- )
Végrehajtása a DO ciklusból való azonnali kilépést eredményez.

%DO
%LOOP
%+LOOP
%I
%LEAVE
EXIT%L

A lebegőpontos ciklusok megfelelői egész kezdő-, vég-és lépésközértékekkel. A J, K és -LOOP szavaknak nincs egész megfelelője.

IF...ELSE...THEN
Ugyanaz, mint a FORTH-79-ben, de itt az ENDIF nem használható, csak a THEN.

BEEP ( l1 l2 --- )
l1 időtartamú, l2 hangmagasságú hangjelzést generál. Megegyezik a hasonló BASIC utasítással.

BLEEP ( n1 n2 --- )
n1 időtartamú, n2 hangmagasságú hangot állít elő. A két egész paraméter hatása nem egyezik meg a BEEP hasonló lebegőpontos paramétereivel, ezért megfelelő hangot csak kísérletezés útján kaphatunk.

CLS ( --- )
Törli a képernyőt, a kurzort a bal felső sarokba állítja.

AT ( l1 l2 --- )
Az l1. sor l2. oszlopába viszi a kurzort.

TAB ( l --- )
A kurrens sor l-edik oszlopába viszi a kurzort.

INK
PAPER
BORDER
BRIGHT
FLASH
INVERSE

Megegyeznek a hasonló BASIC utasításokkal, csak ezek a paraméterüket a vermen várják.

ATTR ( n1 n2 --- n3 )
n3 az n1 sor n2 oszlopának sz színattribútuma lesz.

PLOT ( l1 l2 --- )
Berajzolja az (l1,l2) koordinátájú pontot.

CIRCLE ( l1 l2 13 --- )
Egy (l1,l2) középpontú, l3 sugarú kört rajzol.

DRAW ( l1 l2 --- )
Vonalat húz az utolsó PLOT vagy DRAW utasítás által meghatározott (x+l1, y+l2)) koordinátájú pontok között.

POINT ( n1 n2 --- f )
f igaz, ha az (n1,n2) koordinátájú pont be van kapcsolva, ellenkező esetben f hamis.

A B C D ... G H L M ... X Y Z
Változókat a lebegőpontos FORTH-ban nem definiálhatunk. Helyettük a fenti 23, előre definiált változó használható a megszokott módon (az I, J, K kivételével). Mind lebegőpontos, mind egész számok tárolására alkalmasak.
Ebben a FORTH-ban egyéb iránt konstansdefiníció is csak igy lehetséges:
: PI 3.141592654 ;

INKEY ( --- n )
Az éppen lenyomott billentyű kódját teszi a veremre. Ha nincs lenyomva billentyű, n=255-öt ad vissza.

GET ( --- n )
A FORTH-79 KEY utasításával egyezik meg.

@ ( n --- l )
Az n címen levő lebegőpontos számot teszi a veremre.

%@ ( n1 --- n2 )
Az n1 címen levő egész számot teszi a veremre.

C@ ( n --- b )
Az n címen levő bájtot teszi a veremre. (1 bájt értékes, 4 bájt nulla, 1 bájt értéktelen ).

P@ ( n---b )
Az n portcímről olvas be egy bájtot.

! ( l n ---)
Az l lebegőpontos számot írja az n címre.

%! ( n1 n2 --- )
Az n1 egész számot írja az n2 címre.

C! ( b n --- )
A b bájtot írja az n címre.

P! ( b n --- )
A b bájtot írja az n port-címre.

? ( n --- )
Kiírja az n címen található lebegőpontos számot.

%? ( n --- )
Kiírja az n címen található egész számot.

C? ( n --- )
Kiírja az n címen található bájtot.

FILL ( n1 n2 b --- )
Betölt n2 darab b bájtot az n1 címtől kezdve.

ERASE ( n1 n2 --- )
n2 darab nullabájtot tölt ni címtől kezdve.

DELETE ( n1 n2 --- )
c1 címtől kezdve n2 darab bájtot a szóköz ASCII kódjával (32) tölt fel.

MOVE ( n1 n2 n3 --- )
n3 darab lebegőpontos számot (számonként öt bájtot) tölt át n2 címre n1 címtől kezdve.

%MOVE ( n1 n2 n3 --- )
n3 darab egész számot (számonként két bájtot) tölt át n2 címre n1 címtől kezdve.

CMOVE ( n1 n2 n3 --- )
n3 darab bájtot tölt át n2 címre n1 címtől kezdve.

DUMP ( n1 n2 --- )
Kinyomtatja n1 darab lebegőpontos szám értékét n2 címtől kezdve.

%DUMP ( n1 n2 --- )
Kinyomtatja n1 darab egész szám értékét n2 címtől kezdve.

CDUMP ( n1 n2 --- )
Kinyomtatja n1 darab bájt értékét n2 címtől kezdve.

-TRAIL ( n1 n2 --- n1 n3 )
Megegyezik a FORTH-79 -TRAILING utasításával.

COUNT ( n --- n+1 b )
Egy bájtot olvas be az n címről, és a veremre teszi. A címet eggyel megnöveli.

QUERY ( --- )
Karaktereket olvas be és tárolja őket PAD-től kezdődően. A beolvasást befejezi, ha megnyomták az ENTER-t, vagy már 141 karaktert beolvasott. >IN-t nullára állítja.

WORD ( --- b )
PAD-nez hozzáadja az >IN-ben levő eltolást, és az ezen címen található bájtot a veremre teszi. Ezután >IN tartalmát eggyel növeli.

VLIST ( --- )
Ugyanaz, mint a FORTH-79 VLIST-je, de minden szónév kiírása után várakozik. A következő szónevet az Y billentyű megnyomása után írja ki.

f
Megegyezik a FORTH-79 FORGET utasításával.

WAIT ( --- )
Várakozik, amig meg nem nyomják az Y billentyűt. A program futása csak ezután folytatódik.

STKSWP ( --- )
A lebegőpontos FORTH mind az adat-, mind a visszatérési vermet a Z80 SP regiszterén keresztül kezeli. Az éppen használt verem mutatója az SP-ben, a másiké a 23728 címen levő átmeneti tárolóban van. STKSWP a tároló és az SP tartalmát cseréli meg.

R@ ( --- n )
Két bájtot másol a visszatérésiről az adatveremre. (A FORTH-79 R szava).

SPtoCS ( --- )
Az SP által éppen címzett veremről másol át egy lebegőpontos számot a SPECTRUM számítási vermére. A számítási vermen az értéktelen bájt nem jelenik meg.

2toCS ( --- )
Kétszer hat bájtot visz át az adatról- a számítási veremre. A számítási vermen az értéktelen bájtok nem jelennek meg.

CStoD ( --- )
Lebegőpontos számot visz át a számítási veremről az adatveremre.

+! >IN ABORT CR EMIT EXIT
EXPECT FIND PAD QUIT SPACE SPACES

A FORTH-79-nél leírtakkal azonos paraméterezésű és működésű szavak, illetve változók.

10.9. C64-FORTH
A Commodore-64 mikroszámítógépre írt FORTH programod közül a "HANDIC Software Ab" által készített "C64-FORTH"-ot ismertetjük.
Ez a FORTH változat lehetővé teszi a Commodore 64 be- és kimeneti perifériáinak file-müveletekkel való kezelését önálló, soronkénti szövegszerkesztést lehetővé tevő szövegszerkesztővel (editorral) rendelkezik. Lehetővé teszi a 6510-es mikroprocesszor (a Commodore-64 központi egysége gépi kódú programozását. A virtuális memóriakezelés során a lemezt nem file-struktúrában használja, így erre a célra külön diszket kell formattálni.
A C64-FORTH-ot két változatban lehet elérni.
Eredeti formában a "HANDIC Software Ab" ROM memóriában a COMMODORE-64-hez illeszthető kártya formájában forgalmazza. A kártyát a COMMODORE-64 kikapcsolt állapotában kell a cím- és adatsínekhez illeszteni (a csatlakozó csak ide illik), és ezután bekapcsolni a Commodore-64-et. A kikapcsolás fordított sorrendben történik. A számítógép kikapcsolása után lehet a C64-FORTH programot tartalmazó kártyát kihúzni a cím- és adatsín csatlakozójából.
A C64-FORTH másik változata az eredeti ROM memóriában lévő program átmásolt változata a C64 operatív memóriájába, és ennek gépi kódú programként való tárolása háttértárolón. A program betöltése háttértárolóról (diszk egység) például a LOAD"FORTH",8 utasítással lehetséges, ekkor a C64-FORTH rendszer a következő üzenettel jelentkezik a képernyőn:

C64-FORTH FOR COMMODORE 64 V1
COPYRIGHT DATATRONIC AB, 1983.

A C64-FORTH utasításai részben megegyeznek a FIG-FORTH utasításaival. Eltérő, a fig-FORTH-ot bővítő utasításai a következők:

(DERROR) ( --- )
Az eljárást a diszk egység hibája után hajtja végre a rendszer. A C64-FORTH rendszernél a DERROR utasítás hívja meg.

-BCD (n1 --- n2 )
Az utasítás az n1 értéket két BCD (Binary Coded Decimal) számmá alakítja át (0 <= n1< = 99),

-DISC ( cím n1 n2 n3 f1 --- f2 )
A diszk egység általános olvasó/író utasítása. Ezt az utasítást használja fel a C64-FORTH, hogy egy diszk blokkot a háttértárolóról az operatív memóriába, vagy fordítva mozgasson.
A bemeneti paraméterek a következők:

A kimeneti paraméterként szereplő f2 logikai mutató értéke nulla, ha nem történt hiba az átvitel során. f2 logikai igaz (<>0) értéke esetén az átvitelnél hiba történt. (Lásd ?DISC-nél.)

1+! ( cím --- )
A cím által meghatározott 16 bites szám értékét növeli eggyel az utasítás, és a megnövelt értéket tárolja a cím-nél.

1- ( n1 --- n2 )
Az utasítás n1 értékét csökkenti eggyel (n2).

1-! ( cím --- )
A cím által meghatározott 16 bites szám értékét csökkenti eggyel az utasítás, és a csökkentett érték tárolja a cím-nél.

2- ( n1 --- n2 )
Az utasítás n1 értékét csökkenti kettővel (n2).

; CODE
Az utasítást a következő formában használjuk:

: cccc .... ; CODE gépikódú utasítások END-CODE

Az utasítás hatásában a FIG--FORTH ;CODE utasításával egyezik meg.

2DR0P,
2DUP,
2OVER,
2ROT,
2SWAP,
2VARIABLE,
2CONSTANT

A 16 bites számokkal végzett műveletek kétszavas, 32 bites megfelelői.
Használatuk megegyezik a 16 bites megfelelő utasítások műveletvégzésével, de minden utasításnál a 16 bites értékeknek (n) dupla pontosságú, 32 bites érték felelnek meg (d).

?DISC ( --- )
Az utasítás beolvassa a diszk egység státusz/hiba kódját, és a 08BFH címtől kezdődően tárolja a memóriában. Az üzenet hosszát, a 08C0H memóriacím tartalmazza.

?HOME ( --- )
A képernyő cursor-t a képernyő bal felső sarkába pozícionálja, ha a cursor a képernyő jobb alsó sarkában van.

?SHIFT ( --- n )
Az utasítás a COMMODORE-64 klaviatúra lenyomott billentyűinek értékével tér vissza, amelyek a következük lehetnek: SHIFT, CONTROL és a klaviatúra karakteres billentyűi.

ASSEMBLER
A CONTEXT rendszerváltozóba az ASSEMBLER szótár címét helyezi el. A rendszer ezután gépikódú program-törzset tartalmazó utasítások fordítására alkalmas. Az ASSEMBLER szótárban a COMMODORE-64 központi egységének (6510) standard mnemonikjai és vezérlő struktúrák találhatók. A programozás stílusa az ASSEMBLER fejezetben leírt elvek szerint történik. A standard mnemonikok jelentéseinek áttekintéséhez javasoljuk a COMMODORE-64 gépi kódú programozásához használt táblázat áttekintését.

B. ( n --- )
Az utasítás kiírja az n számot bináris (2-es alapú) formában, a BASE rendszerváltozó tartalmától függetlenül. A BASE tartalmát nem változtatja meg.

BOOT-UP ( --- )
Rendszer inicializáló utasítás. Alaphelyzetbe állítja a diszk egységet, és kiüríti a memória-puffert. Betölti a diszk egységről az 1. screen-t.

CKEY (--- b )
Az utasítás hasonló a KEY utasításhoz, de várakozás közben villogó cursor jel van.

CLIT ( --- b ) (végrehajtáskor)
A LIT utasítás 8 bites változata.

CLOAD ( --- f )
Az utasítás segítségével az előzőleg mágneskazettán tárolt C64-FORTH szótárat lehet betölteni. Az utasítás kimeneti paramétere egy logikai érték, amelynek jelentése a következő:
f=0 az adatok beolvasása hiba nélkül történt,
f<>0 hibakód, amely a hiba jellegére utal.

CLOSE ( n --- )
Lezárja az n. file-t, amely egy külső bemeneti/kimeneti egység lehet. Az egység megnyitása az OPEN utasítással lehetséges.

CODE ( --- n )
Definíciós szó, amelyet a következő formában használunk:

CODE kkkk END-CODE

A CODE utasítás kkkk névvel egy szótári elemet hoz létre. A név után szereplő assembler mnemonikok lefordítódnak az utasítás törzsébe, egészen az END-CODE utasításig. A C64-FORTH a CODE típusú utasítás definíciója alatt végrehajtási állapotban van, így lehetővé teszi a FORTH összes utasításának alkalmazását a címek kiszámításához.
Az assembly programozáshoz hexadecimális számrendszert állít be az utasítás. A C64-FORTH által a CODE utasítás előtt használt számrendszert a paraméter stack-re helyezi. Az END-CODE utasítás állítja vissza a BASE rendszerváltozó eredeti, a CODE előtt használt értékét.

CSAVE ( --- f )
Az utasítás tárolja a C64-FORTH rendszer teljes definíciós szótárát és a rendszerváltozókat a mágnesszalag egységen.
A munkaterület, amelynek a NAME utasítással adhatunk nevet a CLOAD utasítással tölthető vissza az operatív memóriába. Az utasítás kimeneti paraméterként egy logikai értéket hagy, melynek jelentése a következő:
f=0 a tárolás hiba nélkül megtörtént,
f<>0 hibakód, amely a hiba jellegére utal.

DERROR ( --- )
Az utasítás a (DERROR) utasítást használja, amikor diszk egység hiba lép fel a rendszerben. A WARNING változót nulla értékűre állítja.

DISC ( --- )
Az utasítás alapállapotba hozza a Commodore-64-hez kapcsolt diszk egységeket.
A 15-ös számú csatornát megnyitja az utasítások számára, a 13-as csatornát az adatoknak. Ezzel kijelöli a diszk egységet, mint a C64-FORTH rendszer virtuális memóriáját.

DUMP ( cím1 cím2 --- )
A cím1 és a cim2 közötti memória tartalmát listázza ki az utasítás hexadecimális formában és ASCII kódokkal .
A listázás a STOP billentyűvel megállítható.

H. ( n --- )
Az n számot írja ki hexadecimális formában. A BASE rendszerváltozó értéke az utasítás végrehajtása előtti értéket tartja meg.

HOME ( --- )
A képernyő cursor-t a bal-felső sarokba állítja.

HPIN ( b --- f )
Az utasítás a b. számú file-t kiválasztja, mini aktuális bemeneti egységet. A kimeneti paraméterként megadott logikai érték logikai hamis, ha a kiválasztás lehetséges, egyébként egy hibakódot. jelent.

HPOFF ( --- )
Visszaállítja az alaprendszer bemeneti és kimeneti egységeit, amelyek a klaviatúra és a képernyő rendszer.

HPOUT ( b --- f )
Az utasítás kiválasztja a b. számú file-t, mint aktuális kimeneti egységet. A kimeneti paraméterként megadott logikai érték logikai hamis, ha a kiválasztás lehetséges, egyébként egy hibakódot jelent.

I' ( --- n )
DO-LOOP struktúrában a ciklusmagban használható utasítás. A visszatérési stack második szintjét másolja a paraméter stack-re.

J ( --- n )
Egymásba skatulyázott DO-LOOP struktúrában alkalmazzuk. Az utasítás a paraméter stack-re helyezi a következő külső ciklus indexének értékét. Például

: PROBA
  10 0 DO
    5 1 DO I J
        LOOP
  LOOP ;

A J utasítással a 0-tól 10-ig változó úgynevezett külső ciklus indexét, tudjuk az 1-től 5-ig változó belső ciklusban felhasználni.

K ( --- n )
Egymásba skatulyázott DO-LOOP struktúrában alkalmazzuk .
Az utasítás a paraméter stack-re helyezi az aktuális ciklusutasítás előtti második külső ciklus indexének értékét.

M*/ ( d1 n u --- d2 )
Az utasítás megszorozza a 32 bites d1 értéket a 16 bites n értékkel, majd osztja u-val. Az eredmény a 32 bites d2 érték. A szorzás 48 bites eredményt, hoz létre, így nagyobb pontosságú.

NAME ( cím n --- )
Ezzel az utasítással lehet beállítani egy file nevét, amelyet később bemeneti vagy kimeneti egységként megnyitunk. Az OPEN, CSAVE és CLOAD utasítások előtt kötelező alkalmazni. Ha nem akarunk, a file-nak nevet adni, akkor mindkét bemeneti értéknek nullának kell lennie.

NEXT ( --- )
Ez az utasítás aktivizálja a belső (inner) interpreter-t, hogy végrehajtsa a lefordított FORTH definíciókat. Ez a visszatérési pontja minden CODE utasítással definiált szótári elemnek.

OPEN ( b1 b2 cím --- f )
Az utasítás megnyitja a b1. számú file-t a b2-es számú logikai egységen, a cím értékű másodlagos címértékkel. (Lásd a diszk egység gépkönyvében az OPEN utasításnál.) Mielőtt végrehajtjuk ezt az utasítást, be kell állítanunk a file nevét, a NAME utasítással.
Az utasítás kimeneti paraméterként egy logikai értéket hagy a paraméter stack-en.
Ha f=0, a file megnyitása sikeresen megtörtént, f<>0 esetén a kimeneti paraméter egy hibakódot, jelenti.

PAGE ( --- )
Törli a képernyőt egy 147 (decimális) kódú karakter kiküldésével.

S>P ( cím b --- )
Az utasítás a cím-től kezdődően b darab karaktert átmásol a screen-kód elejéről a programkódokhoz.

STATUS ( --- b )
Az utasítás a paraméter stack-re helyezi az IEEE file státusz byte-ját.
A byte egyes bitjeinek jelentése:

0. bit - írási hiba,
1. bit - olvasási hiba,
2. bit - rövid blokk,
3. bit - hosszú blokk,
4. bit - definiálatlan olvasási hiba,
5. bit - kontrol összeg hiba,
6. bit - EDI = vége van a file-nak,
7. bit - az egység nincs bekapcsolva.

T* ( ud u --- u-triple )
Az utasítás a 32 bites és 16 bites előjel nélküli számokat szorozza össze. Az eredmény egy 48 bites szám (u-triple).

T/ ( u-triple u --- ud )
Az utasítás egy 48 bites előjel nélküli értéket oszt el egy 16 bites előjel nélküli értékkel. Az eredmény egy előjel nélküli 32 bites érték.

TEXT ( c ---- )
Az utasítás után következő szöveget másolja a PAD-hoz. A PAD-nál lévő karaktereket a szöveg bemásolása előtt törölte. A TEXT utasítás akkor fejeződik be, ha az utasítás után C/L darab karaktert, vagy egy <CR> karaktert (Carriage Return), vagy a bemeneti paraméterként megadott c karakter ASCII kódját, találja a FORTH rendszer. A c karakter megjelenését a szöveg előtt figyelmen kívül hagyja.

UM*/ ( ud1 u1 u2 --- ud2 )
Az utasítás az M*/ utasításhoz hasonló, azzal a különbséggel, hogy itt minden érték előjel nélküli.

A C64-FORTH EDITOR utasításai
A C64-FORTH-ban kétféle szövegszerkesztésre van mód. Az egyik esetben sor orientált szerkesztés lehetséges, ez a soreditor. A másik szövegszerkesztési módnál a képernyő teljes információtartalmán mozoghatunk a cursor-ral mind a négy irányban. Ilyenkor tetszőleges szöveget törölhetünk Illetve beszúrhatunk. Ezt a szövegszerkesztési módot screen-editor-nak nevezzük. A C64-FORTH szövegszerkesztő utasításai ezen két szövegszerkesztési módra vonatkoznak.

A screen-editor utasításai

(DEFAULT) ( n --- )
Az utasítást a screen-editor hajtja végre, amikor egy olyan karakter érkezik a klaviatúráról, amely nem RETURN, CURSOR, DOWN vagy DELETE karakter. Definíciója:

: (DEFAULT) EMIT ?HOME ;

Ha a felhasználó bővíti a screen-editor utasításait, saját (DEFAULT) rutint kell írnia. Ennek végrehajtása a 'DEFAULT változóval lehetséges, amely tartalmazza a (DEFAULT) vagy a felhasználó által írt új utasítás CFA címét. Az új utasításnak figyelembe kell vennie az új billentyűkhöz tartozó funkciókat, és a (DEFAULT)-ot kell alkalmazni egyéb billentyűk esetén.

CDOWN ( c --- )
Az utasítás azt biztosítja, hogy a cursor na "lépjen ki" a képernyőről, azaz ne csináljon új sort.

DEFAULT ( --- )
Az utasítás definíciója a következő:

: DEFAULT 'DEFAULT @ EXECUTE ;

A definíciót megváltoztatva a felhasználó speciális utasításokkal láthatja el a screen-editort.

DELETE ( c --- )
A screen-editor használja fel az utasítást, hogy ne lehessen törölni a 24. sor 0. oszlopában.

DO-KEY ( c --- )
A screen-editorban használjuk fel, hogy megfelelő funkciót rendeljünk minden lenyomott billentyűhöz.

DEFAULT ( --- cím )
Egy változó cím-ét adja meg az utasítás, amely tartalmazza a (DEFAULT) utasítás CFA címét. A változó tartalma megváltoztatható, ha a felhasználó ki akarja terjeszteni a screen-editor szolgáltatásait.

<-- ( n --- )
Kiválasztja az n. screen-t aktuális screen-ként, és belép a screen-editorba.

X ( --- )
Belépés a screen-editor-ba. Az aktuális screen-t jeleníti meg 25 sorban, soronként 40 karakteres formában. Szabadon megváltoztatható az információ a screen-ben a klaviatúra billentyűivel.

RETURN ( c --- )
A screen-editor számára biztosítja azt a lehetőséget, hogy a továbbiakban ne történjék soremelés.

TCOLOR ( --- cím )
Változó, amely a szöveg színének kódját tartalmazza. A felhasználó megváltoztathatja tartalmát.

A HOME, DELETE és INSERT funkciók a COMMODORE-64 BASIC-jében megismert módon itt is használhatók. Amikor készen vagyunk a screen szövegének szerkesztésével, a STOP billenőivel lehet a screen információját, a memória-pufferbe továbbítani. A STOP billentyű lenyomásával egyben ki is lépünk a screen-editorból. Ha úgy akarunk kilépni a screen-editorból, hogy a változtatások ne kerüljenek be a memória-pufferbe, a SHIFT és STOP billentyűket együttesen kell lenyomnunk. Természetem ekkor is kilépünk a screen-editorból. Egy kilépési üzenet mindig megadja, hogy a kilépéskor a memória-puffer korábbi tartalmát felülírtuk-e új információkkal (SAVED, NOT SAVED).
A C64-FORTH-ban alkalmazott speciális méretű (25 sor x 40 karakter) screen-ben nem alkalmazhatjuk az utolsó sort. Így a screen csak 1000 karaktert tartalmaz. Egy további megkötés, hogy a képernyő utolsó pozíciójában lévő karaktert nem lehet elérni, így a screen csak 999 byte-ot tartalmaz.

A sor editor utasításai

-MOVE ( cím n --- )
A cím-nél lévő szöveget mozgatja az utasítás az aktuálisan szerkesztés alatt álló screen n. sorába. A C/L konstans által megadott karaktermennyiséget mozgatja az utasítás.

>BLKS ( --- )
A video screen tartalmát továbbítja a memória-pufferbe. A továbbítás után UPDATE állapotba hozza a memória-pufferben lévő blokkokat.

>SCRN ( --- )
Kiírja az aktuálisan szerkesztett screen-t, A színeket meghatározó memóriát feltölti a TCOLOR változó tartalmával.

ATA@ ( --- cím )
A képernyő cursor aktuális cím-ét adja meg utasítás.

B ( --- )
Az utasítás az aktuális screen számnál eggyel kisebb értékű screen számot, határoz meg aktuális screen-ként (Back).

BACKUP ( --- )
Az utasítás végrehajtása után másolatot, készít a 0. diszk egységen FLUSH utasítással tárolt blokkokról, az 1. diszk egységen is.

CLEAR ( n --- )
Feltölti a memória-puffért szóköz (space) karakterekkel, és kiválasztja az n. screen-t szövegszerkesztéshez.

COPY ( n1 n2 --- )
Átmásolja az n1. screen tartalmát az n2. screen-be a diszk egységben lévő lemezen. Az n1. screen tartalma változatlan marad a lemezen.

D ( n --- )
Kitörli az n. sort az aktuálisan szerkesztett screen-ből. Minden sor n alatt egy sorral feljebb mozdul, és a 24. sor szóköz karakterekkel töltődik fel (Delete).

E ( n --- )
Kitörli az n. sort az aktuálisan szerkesztett screen-ben, és feltölti szóköz karakterekkel (Erase).

FREE ( n1 n2 --- )
Kiírja n1 és n2 határok között a diszk lemezen lévő üres screen-ek számát. Egy screen akkor üres, ha első cellája 0 byte-ot tartalmaz.

H ( n --- )
Az n. sor tartalmát a PAD-hoz mozgatja az aktuálisan szerkesztett screen-ből. A PAD-nál lévő szöveget kiegészíti szóköz karakterekkel 40 karakter hosszúságúra.

I ( n --- )
Az aktuálisan szerkesztett screen-ben az n. sor alá beszúrja az utasítás a PAD-nál lévő szövegsort.
A régi n. sor és az alatta lévő sorok egy sorral lejjebb csúsznak, és a 24. sort elveszítjük. A PAD-nál lévő szöveg változatlanul megmarad.

L ( --- )
Az aktuálisan szerkesztett screen listázását végzi.

LINE ( n --- cím )
Az n. sor kezdőcímét hagyja a paraméter-stack-en az utasítás. Hibaüzenetet ad, ha az érték nem megfelelő.

N ( --- )
Megnöveli az SCR változó értékét 1-gyel, így az aktuálisan szerkesztett screen után következő screen-t választja aktuális screen-ként.

P ( n --- )
A következő formában használjuk:

n P szöveg

hogy tároljuk a P után következő szöveget az aktuálisan szerksztett screen n. sorában és a PAD-nál.

PAPER ( --- )
Megnyitja a negyedik file-t a printer egységhez, és kiválasztja mint aktuális kimeneti egységet.

PROGRAM ( --- )
Átmásolja a 0-s diszk egységről a screen-eket az 1-es diszk egységre a 0. számú screen-től a 60-as számúig. Ezt a területet használjuk általában a programok szövegének tárolására.

R ( n --- )
Az aktuálisan szerkesztett screen-ben az n. sor tartalmát helyettesíti a PAD-nál lévő sor hosszúságú információval.

S ( n --- )
Létrehoz az aktuálisan szerkesztett screen-ben egy új n. sort, amelyet szóköz karakterekkel tölt fel.
A régi n. sor és az alatta lévő sorok egy sorral lefelé elmozdulnak, és a 24. sort elveszítjük.

SCREENS ( n1 n2 n3 --- )
Átmásol az n1. számú screen számtól kezdődően az n2. screen számhoz n3 darab screen-t.

SHOW ( n1 n2 --- )
Kiír minden felhasznált screen TRIAD-ot az n1 és n2 között. Ha TRIAD-ban mindhárom screen zéró karaktereket tartalmaz, akkor nem listázza ki tartalmukat.

VIDEO ( --- )
Visszaállítja a- képernyőt aktuális kimeneti egységként. Lezárja a 4-es file-t, amely idáig a printerhez tartozott.

ZERO ( n --- )
Feltölti az n. screen-t ASCII nulla (0) karakterekkel. A screen ezáltal válik teljesen üressé.

A C64-FORTH--ban a <CR> billentyűnek a RETURN billentyű felel meg.
A Commodore-64 nyomtató egysége file-ként való megnyitása után aktuális kimeneti egységként, szerepelhet (PAPER, OPEN). A nyomtató egység kiiktatása a file lezárásával lehetséges (VIDEO, CLOSE).
A C64-FORTH file-műveletei segítségével elvileg tetszőleges háttértároló egységet használhat. A perifériák közül a legkényelmesebb, és speciális utasításokkal is támogatott a diszk egység. A diszk egység a rendszerben mint virtuális memória szerepel, és használata a korábbi fejezetekben leírt módon történik. A diszk egységet célszerűt bekapcsolás után a BOOT-UP vagy DISC utasítások egyikével inicializálni.
A kazettás magnetofont háttértárolóként szintén alkalmazhatjuk (CSAVE, CLOAD).
A C64-FORTH közelítőleg 30 kbyte, a felhasználó által kezelhető memóriát, biztosit. Ide helyezhetjük el programjainkat és adatainkat.
A memória-puffer nem a rendszer magasabb memóriacímeinél helyezkedik el, de a felhasználó szempontjából ez nem jelent semmilyen hátrányt vagy megkötést. A STOP és a RESTORE billentyű együttes lenyomásával a C64-FORTH úgynevezett meleg startot (Warm start) hajt végre, ezért megszakítja az aktuálisan futó programot. Ez a lehetőség nagyon hasznos, ha például végtelen ciklusba kerülve ki akarunk lépni a számítógép látszólagos alvó állapotából.
A C64-FORTH hibaüzeneteit a fig-FORTH-hoz hasonlóan számokkal illetve a diszk egységen tárolt szöveggel írhatjuk ki. A C64-FORTH hibaüzeneteit a mellékletben közöljük.

10.10. TPA8 OS/I FORTH
Egy érdekes FORTH implementáció a KFKI TPA8 gépcsaládján (TPA/I, TPA/S, TPA/L, QLJADRO) az OS/I diszk operációsrendszer alatt futó TPA8 OS/I FORTH.
Ezek a gépek 12 bites, egycímes rendszerűek, szemben a FORTH 8/16 bites kezelési módjával. A megvalósított rendszer az adatokat, címeket, a FORTH felhasználó számára fontos értékeket ugyanúgy 2 byte-on (szavakban) tárol ja, de a szó megnövekedett hosszát (24 bit) ki is használja a számábrázolási tartomány bővítésével. Ezzel az egyszavas FORTH változó értéktartománya:

-8 388 608 - +8 388 607

A duplaszavas változó pedig

-140 737 488 355 328 - +140 737 488 355 327

A rendszer a felhasználó elől elfedi a memóriakezelés (FIELD) nehézségeit, és a 32 kbyte címezhető alapmemória tartományt egyszerűen kezelhetővé teszi. A mikrogépeken futó FORTH programok nagy részét változtatás nélkül tudja futtatni. Utasításaiban a 8080 CPM-FORTH 2.2 változattal kompatibilis.
A hagyományos FORTH rendszerekkel szemben érdekes megoldás (és különbség is), hogy a másodlagos utasítások felépítésénél az egy utasítás számára szükséges hely csak egyetlen 12 bites szó. Ezzel a módszerrel hosszabb, kettőnél több utasításból álló definíciók fordításánál akár 50% memóriacím-tartomány is megtakarítható, a 8 bites gépekhez viszonyítva.
Másik érdekes és értékes különbség a többi rendszerhez lépest, hogy a láncolt szótár szerkesztését két memóriaterületen végzi. Az egyikben csak a fizikai működéshez szükséges kódokat tárolja, míg a másikban a definíciók neveit tartja. Ez a szétválasztás azt az előnyt rejti magában, hogy egy működő FORTH programot a TPA OS/I F0RTH-ban lehet úgy is tárolni, hogy a könyvtári adminisztrációt nem ment mentjük el, csak a futtatáshoz szükséges rutinokat. Ez egy közepes méretű programnál 4-5 k szó megtakarítást eredményez. Elvégzi egyben a program titkosítását is, ugyanis a definíciók neveinek táblázata nélkül egyetlen operátori parancsot sem tud végrehajtani, kivéve ha azok előre programozottak.
A TPA8 OS/I FORTH többletszolgáltatása még, hogy lehetőséget nyújt szekvenciális file-eléréssel karakterenkénti soros írásra, és olvasásra is.
A speciális utasításai a következők:

K@ ( cím --- n )
A megadott címről 7 bitre maszkolt karaktert vesz fel, és a paraméter-stack tetején tárolja.

LIB-BEG ( --- cím )
Változó, a FORTH utasítások neveit tároló memória mutatója. Mindig a legutoljára beíródó név NFA címét tartalmazza.

SLANG1 ( n ---)
A TPA8 gépcsalád ASSEMBLER nyelvén (SLANG1) írt betétprogramok indító rutinja. Az n tartalmazza az indítandó program címét (max. 32K).

PDEK ( --- )
Az OS/I diszk operációs rendszer parancsdekódert hívja input és output file specifikációk megadására.

CHINOPEN ( --- )
Az OS/I diszk operációs rendszerben a kijelölt első bemenő file megnyitása karakterenkénti olvasásra. Ha több bemenő file van specifikálva, akkor sorban egymás után fogja a rendszer olvasni ezeket az utolsó (max. 9) végéig.

CHIN ( --- c )
A CHINOPEN utasításnál megnyitott bemenő file-ból a következő karakter olvasása, és egy FORTH definíciós szó átlépése.
A file végén vagy diszk olvasási hiba esetén a definíciós szó átlépése nem következik be. Így a CHIN utasítás után kell egy hiba illetve file-vég vizsgáló definíciót meghívni. File vég esetén a stack tetején 0 tárolódik, olvasási hiba esetén egy 0-tól különböző szám.
A karakterek olvasását az OS/I rendszer "szorosan pakolt" formából végzi. (2 byte = 3 ASCII karakter.)

CHOUTOPEN ( --- )
Az OS/I diszk operációs rendszerben kijelölt kimenő file (csak 1 darab lehet) megnyitása karakterenkénti írásra.

CHOUT ( c --- )
A CHOUTOPEN utasítással megnyitott kimenő file-ba egy karakter írása, és a következő FORTH definíciós szó átlépése.
Diszk írási hiba, vagy helyhiány esetén a definíciós szó átlépése nem következik be. Így a CHOUT utasítás után közvetlenül egy hibavizsgáló definíciós szót kell meghívni. Ha a diszk tele van, akkor a stack tetején egy 0 tárolódik, írási hiba esetén egy szám.
A karakterek írását az OS/I rendszer "szorosan pakolt" formában végzi (2 byte = 3 ASCII karakter).

CHCLOSE ( --- f )
A CHOUTOPEN utasításnál megnyitott file lezárása, paramétereinek könyvtárba vitele. Sikeres lezárás esetén 0, egyébként 1 jelenik meg a stack-en.

A TPAS OS/I FORTH hibaüzenetei a 8080 CPM FORTH 2.2 hibaüzeneteivel azonosak. Többlet hibaüzenetet az OS/I operációs rendszer szolgáltat. Ezek egy része az operációs rendszeren belül javítható. (pl. PDEK utasítás esetén), más része a program felfüggesztéséhez és az operációs rendszerhez történő visszatéréshez vezet.

10.11. TPA8 CAMAC FORTH
A TPA8 OS/I FORTH változatot teljes egészében tartalmazza, és így azzal kompatibilis. Többlet szolgáltatásként a TPA8-hoz kapcsolható CAMAC mérő- és vezérlő periféria rendszerek gyors kiszolgálására tartalmazza ezek FORTH primitív szinten beépített vezérlő utasításait.
A TPA8 CAMAC FORTH futási környezete az OS/I diszk operációs rendszer.
Többlet utasításai megegyeznek a 10.3. alatt közölt CAMAC utasításokkal.

11. A fig-FORTH alapszótárában található definíciós szavak
Az utasítások ABC sorrendben vannak felsorolva. Az első sor minden utasításnál tartalmazza a paraméter stack-et az utasítás végrehajtása előtt, három darab "-" jelet amely a végrehajtást jelenti, illetve a paraméter stack-et a végrehajtás után.

!CSP ( --- )
A paraméter stack mutatóját tárolja a CSP változóban. Az utasítás része a fordítás biztonságát elősegítő utasításoknak.

# ( ud1 --- ud2 )
Az ud1 dupla pontosságú egész számból előállítja a következő ASCII karaktert, amelyet elhelyez egy kimeneti string-pufferben. A kimeneti paraméter ud2, amely az ud1 BASE változó értékével történt, osztása utáni hányados, és felhasználható további átalakításhoz. A <# és #> között alkalmazzuk formátum szerinti kiírás e-setén.

#> ( d --- cím n )
A szám-string átalakítás befejező utasítása, amely eldobja a d paramétert, és a kimeneti string formátumának megfelelő kezdőcímet (cím) és a string hosszát (n) hagyja a paraméter stack-en. Ez a string formátum illeszkedik a TYPE kiíró utasítás által megkívánt formátumhoz.

#S ( ud --- 0 0 )
Az előjel nélküli dupla egész szám (ud) minden számjegyét konvertálja a # utasítás segítségével a kimeneti szöveg-pufferbe, addig amíg a maradék egyenlő nem lesz nullával. Egy nulla karaktert ad a kimeneti-pufferhez, ha a szám nulla értékű volt. A <# és #> utasítások között alkalmazható.

#BUFF ( --- n )
Rendszer konstans, amely a memória-pufferben lévő blokkok számát tartalmazza.

' ( --- cím )
Fordításkor azonnal végrehajtódó utasítás (immediate). A következő formában használjuk:

' nnnn

ahol nnnn egy FORTH utasítás neve. Végrehajtáskor a bemeneti forrásnyelvi szöveg következő utasításának PFA címét (Parameter Field Address) hagyja a paraméter stack-en.
Fordításkor kompiIálja ezt a címet, mint egy literal értéket, majd a végrehajtáskor elhelyezi a paraméter stack-en. Hibát jelez, ha a ' után következő utasítást nem találja a CONTEXT és a FORTH szótárak egyikében sem.

( ( --- )
Fordításkor azonnal végrehajtódó utasítás (immediate). A következő formában használjuk:

( cccc )

ahol cccc tetszőleges szöveg, amely nem tartalmaz ) jelet.
Az utasítás figyelmen kívül hagyja a karaktereket a következő jobb oldali zárójelig. Mint utasítást a bal oldali zárójelet, is egy szóköz (space) karakternek kell követnie.
Végrehajtáskor és fordításkor egyaránt alkalmazható.

(.") ( --- )
Végrehajtáskor felhasznált eljárás, amely az öt követő szöveget az operátori képernyőhöz továbbítja.
A ." utasítás fordításakor alkalmazott, segédutasítás.

(;CODE) ( --- )
Végrehajtáskor felhasznált eljárás, amely átírja az aktuálisan definiált utasítás CFA címének tartalmát úgy, hogy az egy gépi kódú utasításokat tartalmazó részre mutasson.
A ;CODE utasítás fordításakor alkalmazott segédutasítás.

(+LOOP) ( n --- )
Gépi kódú definíciós szó (primitív).
Végrehajtáskor felhasznált eljárás, amely megnöveli a ciklusutasítás indexét n-nel, és ellenőrzi hogy az index elérte-e már a ciklus határértékét.
A +LOOP utasítás fordításakor alkalmazott segédutasítás.

(ABORT) ( --- )
Az utasítást a rendszer akkor hajtja végre, ha a WARNING változó tartalma -1, és egy hibaüzenetet akar küldeni a rendszer. Az utasítás jelenleg ABORT utasítást hajt végre, de a felhasználó által definiált speciális feladatok végrehajtására is alkalmazható.

(DO) ( n1 n2 --- )
Végrehajtáskor felhasznált eljárás, amely a ciklusutasítás paramétereit, a végértéket és a kezdőértéket mozgatja a paraméter stack-ről a return stack-re.
A DO utasítás fordításakor alkalmazott segédutasítás.

(FIND) ( cím1 cím2 --- cím b tf ) vagy ( cím1 cím2 --- ff )
Gépi kódú definíciós szó (primitív).
Megkeresi a szótárban azt az utasítást, amely nevének első karaktere a cím1 címen található. A keresést cím2-nél kezdi el, amely egy utasítás NFA (Name Field Address) címe. Ha sikeres volt a keresés, a paraméter stack-en hagyja az adott nevű utasítás PFA (Parameter Field Address) címét (cím), a név hosszúságát és a státuszbiteket (b), és egy logikai igaz értéket (tf).
Ha nem találta meg az adott nevű utasítást, egy logikai hamis értéket hagy a paraméter stack-en (ff).
A -FIND utasítás fordításakor alkalmazott segédutasítás.

(LINE) ( n1 n2 --- cím n )
Az utasítás a háttértároló n1 számú screen-jében az n2 sorszámú sor memória-pufferbeli kezdőcímét adja meg (cím). A paraméter stack tetején lévő kimeneti paraméter n, a sor hosszúsága. Ha az adott sort tartalmazó screen-blokk nincs a memória pufferben, akkor beolvassa a háttértárolóról.

(LOOP) ( --- )
Gépi kódú definíciós szó (primitív).
Végrehajtáskor felhasznált eljárás, amely megnöveli a ciklusutasítás indexének értékét eggyel, és ellenőrzi, hogy az index elérte-e már a ciklus határértékét.
A LOOP utasítás fordításakor alkalmazott, segédutasítás.

(NUMBER) ( d1 cím1 --- d2 cím2 )
Számmá konvertálja a cím1+1 címen kezdődő, számkarakterekből álló szöveget, ehhez a BASE rendszerváltozó tartalmát használja fel, mint számalapot. A konvertálás alatt az egyes számértékeket a d1 dupla pontosságú számhoz adja hozzá úgy, hogy közben elvégzi a helyérték szerinti adatmozgatást, is.
A konvertálás végeredményeként létrejön a d2 dupla pontosságú szám, illetve egy további kimeneti paraméter, az első, számmá már nem konvertált karakter címe (cím2).
A NUMBER fordításakor alkalmazott segédutasítás.

* ( n1 n2 --- n3 )
Az n1 és n2 előjeles számok aritmetikai szorzatát hagyja a paraméter-stack-en (n3).

*/ ( n1 n2 n3 --- n4 )
Az utasítás n1 értéket megszorozza n2-vel, majd a szorzatot elosztja n3-al.
A nagyobb pontosság elérése végett a szorzás eredménye 32 bites előjeles egész szám. így az utasítás különbözik a leírás alapján definiálható n1 n2 * n3 / utasításoktól.

*/MOD ( n1 n2 n3 --- n4 n5 )
Az n1 és n2 előjeles számok szorzatát elosztja n3-mal. Az eredményként megjelenő n4 az osztás utáni maradék, n5 pedig a hányados. A szorzás eredménye a nagyabb pontosság végett 32 bites előjeles egész szám.

+ ( n1 n2 --- n3 )
Gépi kódú definíciós szó (primitív).
Az n1 és n2 előjeles egészek aritmetikai összeadását végzi el.

+! ( n cin --- )
Gépi kódú definíciós szó (primitív).
Az utasítás a cím által meghatározott helyen lévő 16 bites előjeles egészhez adja hozzá az n 16 bites előjeles egész értéket, és az eredményt tárolja a cím-en.

+- ( n1 n2 --- n3 )
Az utasítás n1 előjelét az ellenkezőjére változtatja ha n2 értéke negatív.
Ha n2 nullával megegyező, vagy értéke nagyobb, mint nulla, változatlan előjellel hagyja n1 értéket.

+BUF ( cím1 --- cím2 )
A memória pufferben keres szabad helyet az utasítás a későbbiekben ott elhelyezendő blokk számára. Ha a memória-pufferben elérte a rendszer felső memóriahatárát is jelentő LIMIT értéket, akkor a memória-puffer első szabad byte-jánál, a FIRST konstans értékénél kezdi el a helyfoglalást.

+LOOP ( n --- )
Fordításkor azonnal végrehajtódó utasítás (immediate). Csak fordításkor alkalmazható (compilation only).
Az utasítás hozzáadja a ciklusutasítás indexéhez az előjeles n értéket, és összehasonlítja az összegét a ciklus határértékével.
A ciklusutasítás folytatása a +LOOP-hoz tartozó DO utasításnál folytatódik mindaddig, amíg:

Ha a feltételek valamelyike teljesül, befejeződik a ciklusutasítás, és a +LOOP eltávolítja a return stack-ről a ciklusparamétereket.

+ORIGIN ( n --- cím )
Azt a memóriacímet hagyja kimenő adatként a paraméter stack-en, amely a rendszer kezdő címétől n byte távolságra van. A CP/M operációs rendszerben a rendszer kezdőcíme 100H.

- ( n1 n2 --- n3 )
Gépi kódú definíciós szó (primitív).
Az n3 értéke az n1 és az n2 előjeles egészek különbsége (n1-n2).

--> ( --- )
Fordításkor azonnal végrehajtódó utasítás (immediate).
Az utasítást háttértárról történő fordítás esetén alkalmazzuk. Ha a definíciós szó forrásnyelvi leírása több screen-en keresztül folytatódik, ezzel az utasítással lehet a fordítás folytatását előidézni a sorrendben következő screen-ben.

-DUP
( n1 --- n1 ) ha ni nulla,
( n1 --- n1 n1 ) ha n1 nem nulla értékű.
Gépi kódú definíciós szó (primitív)
Megduplázza a paraméter stack-ben lévő számot, ha az nem nulla.

-FIND ( --- cím b tf ) vagy ( --- ff )
Az utasítás az őt követő definíciós szó nevének karaktereit elhelyezi a HERE által tárolt címnél.
Ezután a (FIND) utasítás segítségével keresni kezdi a definíciós szó nevét. Ha megtalálta, a paraméter stack-re helyezi a definíciós szó PFA címét (cím), nevének hosszát, a státuszbiteket (b) és egy logikai igaz értéket (tf).
Ha nem találta meg a definíciós szót, egy logikai hamis értéket, (ff) hagy a paraméter stack-en.

-TRAILING ( cím n1 --- cím n2 )
Az utasítás megvizsgálja a címnél kezdődő, n1 hosszúságú karakter-stringet, és elhagyja a karakteres információt követő szóköz karaktereket. Így a cím+n2 és cím+n1-1 címek között szóköz karakterek vannak.

. ( n --- )
Kiírja n értékét az operátori képernyőre, a BASE által meghatározott számrendszerben.
A kiirt szám után egy szóköz karaktert is kiír.
Csak a negatív előjelet írja ki külön karakterként, a pozitív előjelet nem helyettesíti szóköz karakterrel.

." ( --- )
Végrehajtás vagy fordítás esetén alkalmazható utasítás (immediate) a következő formában:

." nnn"

Elfogadja az utasítást követő szöveget a " karakterig mint termináló jelig. Ha végrehajtási állapotban van, kiírja a szöveget operátori képernyőre. Ha fordítási állapotban van, tárolja a szöveget. A definíció későbbi végrehajtásakor kiírja a szöveget az operátori képernyőre.

.CPU ( --- )
Az utasítás kiírja a FORTH implementáció által használt központi egység típusát. Például "8080" vagy "Z80".

.LINE ( n1 n2 --- )
Az utasítás az n1 sorszámú screen n2 sorszámú sorát írja ki az aktuális kimeneti egységre. Felhasználja a (LINE) utasítást.

.R ( n1 n2 --- )
Kiírja az aktuális kimeneti egységre az n1 számot, egy n2 szélességű mező jobb széléhez illesztve. Nem ír ki a szám után szóköz karaktert.

/ ( n1 n2 --- n3 )
Az n1 értéket elosztja n2-vel, a hányados n3, kerekítetlen egész érték.

/MOD ( n1 n2 --- n3 n4 )
Az utasítás elosztja n1-et n2-vel. A maradék n3, hányados n4. A maradék (n3) előjele megegyezik n1 előjelével.

0
1
2
3
( --- n )
Ezeket a kis számokat olyan gyakran használja a rendszer, hogy a gyorsaság és a kis helyfoglalás érdekében célszerű volt konstansként definiálni őkét.

0< ( n --- f )
Gépi kódú definíciós szó (primitív).
Logikai igaz értéket hagy a paraméter stack-en az utasítás, ha n értéke kisebb mint nulla (negatív), egyébként logikai hamis értéket.

0= ( n --- f )
Gépi kódú definíciós szó (primitív).
Logikai igaz értéket hagy paraméter stack-en az utasítás, ha n értéke egyenlő nullával, egyébként logikai hamis értéket.

0BRANCH ( f --- )
Gépi kódú definíciós szó (primitív).
Az IF utasítás által fordításkor felhasznált segédutasítás. Ha az f értéke logikai hamis (nulla), ugrást hajt végre. Ehhez a 0BRANCH utasítást követő 16 bites előjeles számot használja fel, mint címeltolási értéket.

1+ ( n1 --- n2 )
Gépi kódú definíciós szó (primitív).
Az utasítás az n1 értékhez 1-et ad hozzá, amely n2 kimeneti paraméter lesz.

2+ ( n1 --- n2 )
Gépi kódú definíciós szó (primitív).
Az utasítás az n1 értékhez 2-t ad hozzá, amely n2 kimeneti paraméter lesz.

2! ( d cím --- )
Gépi kódú definíciós szó (primitív)
Az utasítás a cím paraméternél kezdődő négy byte-ban tárolja a d dupla pontosságai számot.

2@ ( cím --- d )
Gépi kódú definíciós szó (primitív)
Az utasítás a cím paraméternél kezdődő négy byte-ban tárolt dupla pontosságú számot hagyja a paraméter stack-en.

2DUP ( d --- d d )
Gépi kódú definíciós szó (primitív).
Az utasítás duplikálja a paraméter stack tetején lévő dupla pontosságú számot.

: ( --- )
Fordításkor azonnal végrehajtódó utasítás (immediate). Csak fordításkor alkalmazható (compilation only).
A : utasítás segítségével egy új utasítás definícióját kezdhetjük el. Az utasítást a következő formában használjuk:

: cccc .... ;

ahol cccc egy új utasítás neve. A CONTEXT szótárt egyenlővé teszi a CURRENT szótárral. Egy szótári elemet állít elő cccc névvel a CURRENT szótárban és fordítási állapotba állítja a rendszert.

; ( --- )
Fordításkor azonnal végrehajtódó utasítás (immediate). Csak fordításkor alkalmazható (compilation only).
A ; befejező utasítás egy új utasítás definiálásakor. Fordítási állapotból végrehajtási állapotba állítja a rendszert.
Hibajelzést ad ki, ha a paraméter stack mutatóját nem találja abban az állapotban, ahogyan azt a : utasítás beállította.

;CODE ( --- )
Fordításkor azonnal végrehajtódó utasítás (immediate). Csak fordításkor alkalmazható (compilation only).
A következő formában használjuk:

: kkkk ... ;CODE <gépi kódú utasítások> C;

Az utasítás befejezi a kkkk elnevezésű utasítás definícióját. Ha van ASSEMBLER szótár, akkor ennek címe kerül a CONTEXT változóba, és a ;CODE utáni gépi kódú utasítások lefordítódnak az utasításhoz.
Ha a későbbiekben az utasítást végrehajtjuk a következő formában:

kkkk cccc

akkor cccc elnevezéssel egy új utasítást definiálunk.
Az cccc utasítás végrehajtási címe a kkkk utasításban ;CDDE után következő gépi kódú utasítássorozat. A ;CODE utasítással lehetőségünk van gépi kódú végrehajtási részt írni egy definícióhoz.

;S ( --- )
Gépi kódú definíciós szó (primitív).
Az utasítás befejezi az interpretálást egy adott screen-ből.
A ; utasítás használja még fel, mint végrehajtáshoz szükséges eljárást.

< ( n1 n2 --- f )
Gépi kódú definíciós szó (primitív).
Egy logikai igaz értéket hagy a paraméter stack-en, ha n1 kisebb mint n2, egyébként logikai hamis érték lesz stack tartalma.

<# ( d --- )
A formattált számkiírás kezdő utasítása. A következő definíciós szavakat:

# #S HDLD SIGN #>

használjuk még a dupla szavas szám karakterekké történő konvertálásához.

<BUILDS ( --- )
Csak fordításkor alkalmazható (compilation only).
Fordítási állapotban használjuk a következő formában:

: kkkk <BUILDS ... DOES> ... ;

Valahányszor a kkkk-t végrehajtjuk a következő formában kkkk cccc, a <BUILDS definiál egy új utasítást, amelynek cccc a neve, és definiáláskor végrehajtódnak a <BUILDS és DOES> közötti utasítások.
Az új utasításnak magas szintű végrehajtási eljárása van, amit kkkk-ban a DOES> utáni részben lehet definiálni.

= ( n1 n2 --- f )
Gépi kódú definíciós szó (primitív).
Egy logikai igaz értéket hagy a paraméter stack-en, ha n1 egyenlő n2-vel, ellenkező esetben logikai hamis érték az eredmény.

> ( n1 n2 --- f )
Gépi kódú definíciós szó (primitív).
Egy logikai igaz értéket hagy a paraméter stack-en, ha n1 nagyobb mint n2, egyébként logikai hamis érték az eredmény.

R> ( n --- )
Gépi kódú definíciós szó (primitív).
A paraméter stack-en lévő számot a return stack-re helyezi át. Minden >R utasítás hatása kiegyenlíthető ugyanazon kettőspont definíción belül, ugyanazon vezérlési struktúrában, egy-egy R> utasítással.

? ( cím --- )
Az utasítás kiírja az adott címen lévő 16 bites előjeles számot a BASE által meghatározott számrendszerben az operátori képernyőre.

?COMP ( --- )
Egy hibaüzenetet, ad ki az utasítás, ha a rendszer nincs fordítási, állapotban.

?CSP ( --- )
Egy hibaüzenetet ad ki az utasítás, ha a stack mutató különbözik attól az értéktől, mint ami CSP-ben van tárolva.

?ERROR ( f n --- )
Az utasítás az f logikai változó igaz értéke esetén kibocsátja az n. számú hibaüzenetet.

?EXEC ( --- )
Egy hibaüzenetet ad ki az utasítás, ha a rendszer nincs végrehajtási állapotban.

?LOADING ( --- )
Egy hibaüzenetet ad ki az utasítás, ha a rendszer nem háttértárolóról tölt be adatot.

?PAIRS ( n1 n2 --- )
Egy hibaüzenetet ad ki az utasítás, ha n1 nem egyezik n2-vel. A hibaüzenet azt jelzi, hogy a fordítási szabályokat nem tartottuk be. Például DO utasítás van LOOP nélkül, vagy IF utasítás THEN nélkül fordult elő.

?STACK ( --- )
Egy hibaüzenetet ad ki az utasítás, ha a paraméter stack üres vagy teljesen megtelt.

?TERMINAL ( --- f )
Gépi kódú definíciós szó (primitív)
Az utasítás a kezelői klaviatúra állapotát vizsgálja meg. Ha leütöttünk egy billentyűt az utasítás végrehajtása előtt, f értéke logikai igaz lesz. Ellenkező esetben f logikai hamis értékű.

@ ( cím --- n )
Gépi kódú definíciós szó (primitív)
A cím helyen tárolt 16 bites egész értéket hagyja a paraméter stack-en az utasítás.

ABORT ( --- )
Az utasítás törli a paraméter és a return stack-et, és a rendszer végrehajtási állapotba kerül. A vezérlést visszaadja az operátori terminálnak, és kiírja a rendszer kezdeti üzenetét.

ABS ( n1 --- n2 )
Az n1 abszolút értékét hagyja a paraméter stack-en (n2).

AGAIN ( n --- )
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate).
Kettőspont definícióban használatos a következő formában:

BEGIN ... AGAIN

Végrehajtáskor az AGAIN a vezérlést a hozzá tartozó BEGIN utasítás utáni első utasításra adja. A paraméter stack-en nem történik változás.
A struktúrából az R> DROP utasítássorozattal léphetünk ki.

ALLOT ( n --- )
Az n előjeles értéket hozzáadja a DP (Dictionary Pointer) tartalmához.
Az utasítás memóriaterület lefoglalására és felszabadítására alkalmas.

AND ( n1 n2 --- n3 )
Gépi kódú definíciós szó (primitív)
Az utasítás n1 és n2 bitenkénti logikai és kapcsolatát hagyja a paraméter stack-en (n3).

B/BUF ( --- n )
A B/BUF (Bytes/Block) konstans az egy blokkban lévő byte-ok számát adja meg.

B/SCR ( --- n )
A B/SCR (Blocks/Screen) konstans az egy screen-ben lévő blokkok számát adja meg.

BACK ( cím --- )
Kiszámítja a cím és a HERE közötti különbséget, majd a következő szabad memóriahelyre (a HERE által meghatározott címre) tárolja.

BASE ( --- cím )
Rendszerváltozó (user variable), amely a bemeneti és kimeneti számkonverzió számalapját tartalmazza.

BEGIN ( --- )
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate). Kettőspont definícióban használjuk a következő formában:

BEGIN ... AGAIN
BEGIN ... f UNTIL
BEGIN ... f WHILE ... REPEAT

A BEGIN megjelöli az ismétlődően végrehajtandó utasítássorozat kezdetét. A hozzá tartozó AGAIN, UNTIL és REPEAT használják fel ezt a jelölést, mint visszaugrási címet a BEGIN utáni utasításhoz. Ha az UNTIL végrehajtásakor egy logikai hamis értéket talál a paraméter stack-en, visszaadja a vezérlést a BEGIN utáni utasításhoz, logikai igaz esetén befejezi a BEGIN-UNTIL ciklust, és a sorrendben következő utasítást hajtja végre.
AGAIN és REPEAT esetén feltétel nélkül visszaugrás történik a BEGIN utáni utasításra.

BL ( --- c )
Egy konstans, amely a szóköz (space) karakter ASCII kódját hagyja a paraméter stack-en.

BLANKS ( cím n --- )
Az operatív memória cím-től kezdődő n darab helyét feltölti szóköz (space) karakterrel.

BLK ( n --- cím )
Rendszerváltozó, amely az aktuálisan interpretálás alatt lévő blokk számát, tartalmazza. Ha BLK tartalma nulla, az adatokat az operátori termináltól kapja, nullától eltérő BLK tartalom esetén a háttértárolóról (diszk egység).

BLOCK ( n --- cím )
A memória-pufferbeli n. blokk kezdőcímét adja meg az utasítás. Ha a blokk nincs bent a memória-pufferben, beolvassa a háttértárolóról. Ha a pufferben, amelyet fel akarunk használni, a blokk beolvasásához UPDATE-elt blokk található, az utasítás a régi blokkot kiírja a háttértárolóra, és csak ez után történik meg az új blokk beolvasása.

BRANCH ( --- )
Gépi kódú definíciós szó (primitív).
Az IF utasítás által fordításkor felhasznált segédutasítás. Feltétel nélküli ugrást hajt végre a BRANCH utasítást követő 16 bites előjeles értékkel, mint címeltolással kialakuló új címre.

BUFFER ( n --- cím )
Az utasítás a legrégebben használt pufferhez hozzárendeli az n számot, mint blokk számot. Ha a puffer korábbi tartalma UPDATE-elt volt, kiírja azt a háttértárolóra. Kimeneti paraméterként az így előkészített puffer első szabad memóriacímét hagyja a paraméter stack-en.

BYE ( --- )
"Software Reset" utasítás, a vezérlést a 0000H címre adja, így ez visszatérés a CP/M operációs rendszerbe.

C/L ( --- n )
Rendszerkonstans, amely kiíratási parancsoknál az egy sorba írandó karakterek számát tartalmazza.

C! ( b cím --- )
Gépi kódú definíciós szó (primitív).
A cím által meghatározott memóriahelyen tárolja b-t.

C, ( b --- )
A b-t, tárolja a következő szabad memóriahelyre, amelyet a DP (Dictionary Pointer) mutat meg.
A DP értéket, megnöveli eggyel.

C@ ( cím --- b )
Gépi kódú definíciós szó (primitív).
A cím által meghatározott helyen lévő byte-ot hagyja a paraméter stack-en az utasítás, mint egy 16 bites adatot, melynek magasabb helyértékű byte-ja nulla értékű.

CFA ( cím1 --- cím2 )
Egy utasítás PFA (Parameter Field Address) címét (cím1) konvertálja CFA (Code Field Address) címmé (cím2).

CMOVE ( cím1 cím2 n )
Gépi kódú definíciós szó (primitív).
Az utasítás cím1-től n darab byte-ot mozgat a cím2-től kezdődő memóriaterületre.
A cím1 tartalmát mozgatja először az új helyére. Ha n értéke nulla, nem történik karakter mozgatás.

COLD ( --- )
Az utasítás hatására a rendszer úgynevezett "hidegindítást" hajt végre és a bekapcsolás utáni alapállapotba kerül.

COMPILE ( --- )
Csak fordításkor alkalmazható (compilation only).
Ha egy utasítás tartalmazza a COMPILE utasítást, akkor a COMPILE az őt követő utasítás CFA címét másolja be a következő szabad memória helyre.
Például a COMPILE COLD a COLD utasítás CFA címét másolja be a memóriába.

CONSTANT ( n --- )
Adat definíciós szó, amely a következő formában használatos:

n CONSTANT bbbb

Az utasítás létrehoz egy bbbb elnevezésű szótári elemet, és tárolja n-et a PFA címen.
Amikor a bbbb-t később végrehajtjuk, n értékét fogja a paraméter stack-en hagyni.

CONTEXT ( --- cím )
Rendszerváltozó (user variable), amelynek tartalma egy szótári mutató. A CONTEXT tartalma arra a szótárra mutat, amelyben először kell keresni a bemeneti adatok interpretálás közben egy adott nevű utasítást.

COUNT ( cím1 --- cím2 n )
A cím1-nél kezdődő n hosszúságú, szöveg típusú adat kezdőcímét és hosszát, hagyja a paraméter stack-en. A szöveg típusú adat első byte-jának tartalmaznia kell a szöveg hosszát, n értéke így [0-255] közötti érték ehet.

CR ( --- )
Gépi kódú definíciós szó (primitív).
Egy kocsi vissza (Carriage Return) és egy soremelés (Line Feed) karaktert küld ki az operátori képernyőre.

CREATE ( --- )
Definíciós szó, amelyet a következő formában alkalmazunk:

CREATE cccc

Az utasítás létrehoz egy cccc elnevezésű szótári elemet a CURRENT által meghatározott szótárban.

CSP ( --- cím )
Rendszerváltozó (user variable), amely a paraméter stack pointer értékét tárolja, hogy ellenőrizhesse a fordítási fázisban a definíció hibáját.

CURRENT ( --- cím )
Rendszerváltozó (user variable), amely annak a szótárnak a cím tartalmazza, amelyhez a továbbiakban hozzákapcsolódnak a definíciók.

D+ ( d1 d2--- d3 )
Gépi kódú definíciós szó (primitív).
A d1 és d2 dupla pontosságú előjeles egészek aritmetikai összeadását végzi el az utasítás.
Az eredmény szintén előjeles dupla pontosságú egész érték.

D+- ( d1 n --- d2 )
Az utasítás d1 előjelét az ellenkezőjére változtatja, ha n negatív.
Ha n értéke nullával egyező vagy nagyobb, mint nulla, változatlan előjellel hagyja d1 értéket.

D. ( d --- )
Kiírja a d dupla pontosságú előjeles egész értéket az operátori képernyőre a BASE által meghatározott számrendszerben. A kiirt szám után egy szóköz karaktert is kiír.
Csak a negatív előjelet írja ki külön karakterként, a pozitív előjelet nem helyettesíti szóköz karakterrel.

D.R ( d n --- )
Kiírja az operátori képernyőre a d dupla pontosságú előjeles számot egy n szélességű mező jobb széléhez illesztve.
Nem ír ki a szám után szóköz karaktert.

DABS ( d1 --- d2 )
A d1 dupla pontosságú előjeles egész szám abszolút értékét (d2) hagyja a paraméter stack-en az utasítás.

DECIMAL ( --- )
Beállítja a bemeneti és kimeneti számkonverziós alapot, a BASE rendszerváltozót tízre.

DEFINITIONS ( --- )
A következő formában használjuk:

cccc DEFINITIONS

ahol cccc egy már létező szótár neve.
A CURRENT változó értéke felveszi a CONTEXT váltó értékét.
A további definíciók a cccc szótárhoz fognak kapcsolódni.

DENSITY ( --- cím )
Rendszerváltozó (user variable), amely az alkalmazott diszk tároló írássűrűségére vonatkozó adatot tartalmaz.
Ha a DENSITY tartalma nulla, egyszeres (single) sűrűségű a lemez, ha egy, akkor dupla sűrűségű.

DIGIT ( c n1 --- n2 tf ) vagy ( c n1 --- ff )
A c karaktert az n1 számlalapot felhasználva konvertálja bináris megfelelőjévé, n2-vé.
Egy logikai igaz értéket hagy a paraméter stack-en, ezzel jelezve hogy sikeres volt a konverzió.
Sikertelen konvertálás esetén csak egy logikai hamis értéket hagy a paraméter stack-en.

DISC-ERROR ( --- cím )
Rendszerváltozó (user variable), amely a diszk hibaállapot értékét (Error Status) tartalmazza.

DLITERAL ( d --- )
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate).
A paraméter stack-en lévő dupla pontosságú értékét fordítja be a definícióba.

DMINUS ( d1 --- d2 )
Gépi kódú definíciós szó (primitív).
A d1 dupla pontosságú előjeles egész előjelét az ellenkezőjére fordítja az utasítás.

DO ( n1 n2--- )
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate).
A következő formában használjuk a kettőspont definícióban:

DO ... LOOP

vagy

DO ... +LOOP

Az utasítás egy definiált ciklust valósit meg, melynek határai a bemeneti paraméterek (n1,n2).
A ciklus-index n2-nél kezdődik és n1-ig változik. A LOOP-nál a ciklusindex növekménye egy. A +LOOP-nál a ciklus-indexét egy pozitív vagy negatív értékkel módosíthatjuk.
A DO-LOOP ciklusok egymásba skatulyázhatók.

DOES> ( --- )
Csak fordításkor alkalmazható (compilation only).
A végrehajtáskor elvégzendő feladatot kezdjük az utasítással egy magas szintű definiáló szóban.
A következő formában használjuk:

: kkkk <BUILDS ... DOES> ;

és a

kkkk cccc

alakban.
A kkkk egy magas szintű utasítást definiáló szó, melynek fordításkor végrehajtandó része van a <BUILDS és a DOES> utasítások között. Végrehajtási állapotban a DOES> utáni részre kerül a vezérlés.
A kkkk új utasításokat definiálhat, amelyek típusa meg fog egyezni egymással.
Az új utasítások CFA (Code Field Address) címe az őket definiáló utasítás (jelen ecetben cccc DOES>) utáni részére mutat.

DP ( --- cím )
Rendszerváltozó (user variable) (Dictionary Pointer), amely a rendszerben a kővetkező üres memóriahelyre mutat.
Értékét a HERE olvassa ki és az ALLOT változtatja meg.

DPL ( --- cím )
Rendszerváltozó, amely azt a pozíciót tartalmazza adat bevitelnél, amelyen a decimális pont van.

DR0 ( --- )
A CP/M rendszerbeli A jelű diszk egységet választja ki, mint aktuális háttértárolót.

DR1 ( --- )
A CP/M rendszerbeli B jelű diszk egységet választja ki, mint aktuális háttértárolót.

DRIVE ( --- cím )
Rendszerváltozó (user variable), amely az aktuálisan használt diszk számát tartalmazza. (0 és 15 között lehet, az értéke.)

DROP ( n --- )
Gépi kódú definíciós szó (primitív).
Eldobja a paraméter stack tetején lévő 16 bites számot.

DUP ( n --- n n )
Duplikálja a paraméter stack tetején lévő 16 bites számot.

ELSE ( --- )
Kettőspont definícióban használjuk a kővetkező formában:

f IF ... ELSE ... THEN

Az ELSE-re az IF-et követő logikai igaz ág befejezésével kerül a vezérlés. Az ELSE hatására, az ELSE utáni logikai hamis ág utasításait átugorja a program és a THEN utáni első utasításon folytatódik.
Az ELSE nem változtatja meg a paraméter stack állapotát.

EMIT ( c --- )
Gépi kódú definíciós szó (primitív).
Kiírja a c ASCII kódú karaktert az operátori képernyőre.

EMTPTY-BUFFERS ( --- )
A memória puffert feltölti nulla karakterekkel, ezáltal kezdeti állapotba hozza. A korábban UPDATE-tel megjelölt blokkokat nem menti ki a háttértárolóra.

ENCLOSE ( cím1 c --- cím2 n1 n2 n3 )
Gépi kódú definíciós szó (primitív).
Szövegkereső rutin, amelyet a WORD utasítás használ fel.
A vizsgált szöveg a cím1 címen kezdődik, és határoló karaktere c.
Az utasítás meghatározza a címeltolás (offset) értékét az első nem határoló karakterig (n1), vagyis a vizsgált szöveg első karakteréig. Az n2 paraméterrel megadja a szöveg utolsó karakterének címeltolását. Az n3 paraméter a szöveg utáni első határoló karakter címeltolásának értéke. A címeltolási értékek a cím2 értékére vonatkoznak.

END ( f --- ) (végrehajtáskor)
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate).
Ez az utasítás hatásában megegyezik az UNTIL utasítássál. (Leírását lásd az UNTIL-nál.)

ENDIF ( --- )
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate).
Ez az utasítás hatásában megegyezik a THEN utasítással. (Leírását lásd a THEN-nél.)

ERASE ( cím n --- )
Az utasítás nulla (0) karakterekkel tölti fel az operatív memóriát a cím-től cím+n-ig.

ERROR ( n --- )
Kiírja az aktuális kimeneti egységre az n. hibaüzenetet, és ABORT utasítást hajt végre. A hibaüzenet kiírásának módja a WARNING rendszerváltozó tartalmától függ.

ilyenkor nem olvas be adatot a diszk egységről.

Az utasítás nem rontja el a BLK és IN tartalmát, hogy lehetőség legyen a hiba helyét meghatározni.

EXECUTE ( cím --- )
Gépi kódú definíciós szó (primitív).
Végrehajtja azt az utasítást, amelynek CFA (Code Field Address) címe a paraméter stack-en van.
A CFA címet végrehajtási címnek is nevezik.

EXPECT ( cím n --- )
A cím-től kezdődő memóriaterületre helyezi el az operátori klaviatúráról érkező karaktereket. A művelet n darab karakter beolvasásáig, vagy kocsi vissza (CR) karakterig tart.

FENCE ( --- cím )
Rendszerváltozó (user variable), amely azt a címet tartalmazza, amelynél kisebb címek nem "felejthetők" el a FORGET utasítással. A változó tartalmának megváltoztatásával a védővonalat magunk is átállíthatjuk.

FILL ( cím n b --- )
Gépi kódú definíciós szó (primitív).
Feltölti a cím és a cím+n közötti memóriaterületet a b-ben meghatározott értékkel.

FIRST ( --- n )
Rendszerkonstans, amely a memória-puffer kezdőcímét tartalmazza.

FLD ( --- cím )
Rendszerváltozó (user variable), amelyet a felhasználó szabadon alkalmazhat.

FLUSH ( --- )
A memória-pufferből az UPDATE-tel megjelölt blokkokat kiírja a háttértárolóra.

FORGET ( --- )
A következő formában használjuk:

FORGET cccc

Az utasítás törli a cccc utasítást valamint a fizikailag utána következű összes definíciót.
Egy hibajelzést bocsát ki, ha a CURRENT és a CONTEXT tartalma nem egyezik meg egymással.

FORTH ( --- )
Fordításkor azonnal végrehajtódó utasítás (immediate).
Az elsődleges szótár elnevezése. Végrehajtáskor a FORTH válik a CONTEXT szótárrá. A definíciók a FORTH szótár elemei lesznek mindaddig, amíg a CURRENT segítségével új szótárat, nem adunk meg a rendszernek.
A szótárak mindegyike kapcsolódik a FORTH szótárhoz, így a FORTH szótár is eleme lesz minden felhasználói szótárnak.

HERE ( --- cím )
A következő szabad memóriahely címét adja meg az operatív memóriában.

HEX ( --- )
A BASE változó értékét, decimális 16 értékűre állítja be, így hexadecimális számrendszerben folytatódik a számok értelmezése.

HLD ( --- cím )
Rendszerváltozó (user variable), amely a számkonverzió során átalakított karakter címét tartalmazza.

HOLD ( c --- )
A <# és #> utasítások között használjuk, hogy egy c kódú ASCII karaktert a számkarakterek közé beszúrjunk.

I ( --- n )
Gépi kódú definíciós szó (primitív).
Az utasítás a return stack tetején lévő értéket átmásolja a paraméter stack-re, úgy hogy az érték a return stack-en is megmarad.
Felhasználható DO-LOOP ciklusutasításban, mint a ciklusváltozó indexe.

ID. ( cím --- )
Az ID. kiírja a cím paraméterrel, mint NFA értékkel megadott utasítás nevét az operátori képernyőre.

IF ( f --- )
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate).
Kettőspont definícióban használjuk a kővetkező formában:

f IF ... ELSE ... THEN

vagy

f IF ... THEN

Ha f logikai változó értéke logikai igaz, akkor az IF utáni utasításszavakat hajtja végre a rendszer és a hozzá tartozó ELSE utáni részt átugorja. Az ELSE használata nem kötelező.
A második esetben az IF és THEN közötti utasításokat hajtja végre.
Az f logikai hamis értéke esetén az első esetben az ELSE és THEN közötti utasítások hajtódnak végre, míg a második esetben a THEN után következő utasításra kerül a vezérlés.
Az IF-ELSE-THEN és IF-THEN struktúrák egymásba skatulyázhatók.

IMMEDIATE ( --- )
Csak fordításkor alkalmazható (compilation only).
Megjelöli az aktuálisan definiált szótári elemet, hogy később az elem definícióba történő befordításakor ne fordítódjék le, hanem azonnal hajtódjon végre.
Ez az eljárás lehetővé teszi, hogy a szokásostól eltérő fordítási szituációkat tudjunk megvalósítani (lásd például BEGIN, IF stb.).
A felhasználó ezen utasítások definícióba történő befordítását a [COMPILE] utasítással végezheti el.

IN ( cím )
Rendszerváltozó (user variable), amely relatív mutatóérték az aktuálisan használt bemeneti szöveg-pufferben. A szöveg-pufferek a kővetkezők lehetnek:

Az aktuálisan használt szöveg-pufferből a WORD utasítás keresi meg a következő szót, és beállítja IN értékét az azt követő szó elejére.

INDEX ( n1 n2 --- )
Az n1-től n2-ig terjedő screen-ek nulladik sorát kilistázza.
Konvenció, hogy a screen nulladik sorába a screen tartalmára utaló információt helyezünk el.

INTERPRET ( --- )
Az utasítás a külső szöveg interpreter, amely sorrendben végrehajtja vagy lefordítja a bemeneti egységről (klaviatúra vagy háttértároló) érkező szöveget a STATE rendszerváltozó állapotától függően.
Ha a szövegben előforduló szót nem találja sem a CONTEXT sem pedig a CURRENT szótárban, akkor a BASE által meghatározott számalapot figyelembe véve megpróbálja számmá konvertálni a kifejezést. Ha ez sem sikeres, akkor egy hibajelzéssel megáll.
Az egyes utasításszavakat szóköz (space) karakterrel kell egymástól elválasztani.
A decimális pont a számkarakterek között dupla pontosságú (32 bites) számot jelöl. A dupla pontosságú jelölésen túl a számon belüli elhelyezkedése semmilyen más információt nem hordoz.

KEY ( --- c )
Gépi kódú definíciós szó (primitív).
Az operátori klaviatúráról érkező következő karakter ASCII kódját hagyja a paraméter stack-en.

LATEST ( --- cím )
Az utasítás a CURRENT szótárban legutoljára definiált utasításszó NFA (Name Field Address) címét hagyja a paraméter stack-en.

LEAVE ( --- )
Gépi kódú definíciós szó (primitív).
Az utasítás a DO-LOOP ciklusutasítás befejezését idézi elő.
A ciklusutasítás határát egyenlővé teszi a ciklus-index értékével. Az index értékét nem változtatja meg.
A ciklusutasítás befejezését a LOOP vagy +LOOP utasítás végzi el a ciklusutasítás határának és indexének vizsgálatával.

LFA ( cím1 --- cím2 )
Egy utasítás PFA (Parameter Field Address) címét (cím1) konvertálja LFA (Link Field Address) címmé (cím2).

LIMIT ( --- n )
Rendszerkonstans, a FORTH operációs rendszer által felhasználható maximális memóriacímet tartalmazza.

LIST ( n --- )
Kilistázza az aktuális kimeneti egységre az n. screen tartalmát szövegesen. Az SCR változó tartalmazza a listázott screen számát a listázás után.

LIT ( --- n )
Csak fordításkor alkalmazható (compilation only).
Gépi kódú definíciós szó (primitív).
Kettőspont utasításban használjuk. A LIT-et minden egyes 16 bites szám elé befordítja a rendszer.
Végrehajtáskor a LIT az utána következő 16 bites memóriatartalmát helyezi el a paraméter stack-en.

LITERAL ( n --- ) (fordításkor)
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate).
Fordítási állapotban a paraméter stack-en lévő 16 bites literal értéket fordítja bele az aktuális definícióba.

LOAD ( n --- )
Az n. screen-ben lévő szöveg interpretálását, kezdi el.
A korábban használt bemeneti szövegtároló paramétereit BLK és IN értéket a return stack-en tárolja, majd az n. screen paramétereit állítja be a változókba (BLK, IN), és elkezdi az interpretálást. Az interpretálás befejeztével visszaállítja a régi BLK és IN értékeket.

LOOP ( --- )
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate).
Megnöveli eggyel a DO-LOOP ciklus indexének értékét, és megvizsgálja, hogy befejeződött-e már a ciklusutasítás. A ciklusutasítás befejeződik, ha a ciklusindex és a ciklushatár egyenlők egymással.
Ha nem fejeződött be a ciklusutasítás, a vezérlés visszakerül a LOOP-hoz tartozó DO utasítás utáni első utasításhoz.

M* ( n1 n2 --- d )
Az utasítás két 16 bites előjeles egész szám szorzatát, képezi úgy, hogy az eredmény 32 bites előjeles szám legyen.

M/ ( d1 n2 --- n3 n4 )
Az utasítás a d1 32 bites előjeles szám és az n2 16 bites előjeles szám hányadosát képzi.
Az n3 a maradék, melynek előjele megegyezik d1 előjelével, n4 az előjeles hányados.

M/MOD ( ud1 u2 --- u3 ud4 )
Előjel nélküli számok hányadosát képezi, az eredmény is előjel nélküli.
ud1 az osztandó, u2 az osztó u3 a maradék, ud4 a hányados.

MAX ( n1 n2 --- n3 )
n1 és n2 közül a nagyobbikat hagyja a paraméter stacks-en

MESSAGE ( n --- )
A WARNING tartalmától függően a következő műveleteket, végzi el az utasítás:
Ha WARNING tartalma nulla (0), akkor kiírja az

MSG # n

üzenetet, ahol n a bemeneti paraméterként megadott szám.
Ha WARNING tartalma nem nulla, akkor az aktuálisan használt diszk egység 4. screen első sorától kezdődően az n. sor tartalmát írja ki az aktuális kimeneti egységre. Ha a hibaszám nagyobb, mint az egy screen-ben lévő sorok száma, akkor a screen-ek sorfolytonos összefűzésével adódó hibaüzenet, listát használja fel az utasítás.

MIN ( n1 n2 --- n3 )
n1 és n2 közül a kisebbiket hagyja a paraméter stack-en.

MINUS ( n1 --- n2 )
Gépi kódú definíciós szó (primitív).
Az n1 16 bites előjeles szám előjelét az ellenkezőjére fordítja az utasítás.

MOD ( n1 n2 --- n3 )
Az n 1-nek n2-vel való osztás utáni maradékát (n3) hagyja a paraméter stack-en. Az n3 előjele megegyezik n1 előjelével.

NFA ( cím1 --- cím2 )
Egy utasítás PFA (Parameter Field Address) címét (cím1) konvertálja NFA (Name Field Address) címmé (cim2).

NOOP ( --- )
Üres utasítás (No Operation). Definiciója:

: NOOP ;

NUMBER ( cím --- d )
A cím paraméternél található karakter stringet, melynek elemei cím+1 címnél kezdődnek, átalakítja a BASE által meghatározott számalapnak megfelelően egy 32 bites előjeles számmá. A cím címen a string hossza található. Ha tizedespontot talál a karakter string-ben, ennek relatív pozícióját a DPL változóban tárolja.
Ha a számmá történő átalakítás nem lehetséges, akkor hibaüzenetet küld.

OFFSET ( --- n )
Rendszerváltozó (user variable), amely az egy lemezen elhelyezhető blokkok számát tartalmazza.
Az OFFSET segítségével lehet a lemezegységek közötti választást elvégezni.
Az "A" lemezegység használatakor OFFSET tartalma egyenlő nullával, a "B" lemezegység használatakor az "A" lemezen lévő blokkok számával egyezik meg.

OR ( n1 n2 --- n3 )
Gépi kódú definíciós szó (primitív).
Az utasítás n1 és n2 bitenkénti logikai vagy kapcsolatát hagyja a paraméter stack-en (n3).

OUT ( --- cím )
Rendszerváltozó (user variable), amelynek értékét az EMIT utasítás növeli eggyel.
A felhasználó megváltoztathatja és vizsgálhatja az OUT értékét, a formattált kiíráshoz.

OVER ( n1 n2 --- n1 n2 n1 )
Gépi kódú definíciós szó (primitív).
A paraméter stack-en második adatként elhelyezkedő (n1) értéket, másolja a paraméter stack tetejére.

P! ( b1 b2 --- )
Gépi kódú definíciós szó (primitív)
A b1 értéket kiviszi a b2 által meghatározott, portra. (I 8080 OUT utasítás.)

P@ ( b1 --- b2 )
Gépi kódú definíciós szó (primitív).
A b1 portcímről beolvassa a b2 értéket. (I 8080 IN utasítás.)

PAD ( --- cím )
Az utasítás egy kimeneti szöveg-puffer címét hagyja a paraméter stack-en, amely fix eltolással (64 byte-tal) van a HERE aktuális értéke felett.

PFA ( cím1 --- cím2 )
Egy utasítás NFA (cím1) címét konvertálja a PFA címmé (cím2).

PREV ( --- cím )
Rendszerváltozó (user variable), amely a memória-pufferbeli blokkok közül a jelenleg használt blokk előtt korábban használt blokk kezdőcímét tartalmazza. Az aktuálisan használt blokk kezdőcíme a USE rendszerváltozóban van.

QUERY ( --- )
Az utasítás segítségével lehetőségünk van a TIB-be (Terminal Input Buffer) beolvasni maximum 80 karaktert. A karakterek beolvasása maximum 80 darab karakterig vagy egy kocsi vissza karakterig tart.
Az IN rendszerváltozóba nullát helyez el az utasítás.

QUIT ( --- )
Törli a visszatérési címeket tartalmazó return stack-et, megállítja a fordítást, és visszaadja a vezérlést az operátori képernyő / klaviatúra rendszernek.
Nem ad ki hibaüzenetet.

R ( --- n )
Gépi kódú definíciós szó (primitív).
Átmásolja a return stack tetején lévő értéket a paraméter stack-re úgy, hogy az érték a return stack-en is megmarad.

R# ( --- cím )
Rendszerváltozó (user variable), amelyet rendszerint az EDITOR használ fel.
Szöveg szerkesztésekor a szövegbeli cursor pozícióját tartalmazza, vagy más file-művelettel kapcsolatos feladatra alkalmazzuk.

R/W ( cím un f --- )
A FIG-FGRTH standard diszkes író/olvasó utasítása.
A cím meghatározza az írandó/olvasandó blokk kezdőcímét .
Az un. blokk szám, amelyet ki akarunk írni/be akarunk olvasni.
f logikai változó nulla (0) értéke esetén írás, egy (1) értéke esetén olvasás történik.
Az utasítás végrehajtja az adott sorszámú blokk Írását/ olvasását a cím által meghatározott területről/területre. Az írás/olvasás művelete alatt hibaellenőrzést végez, hogy a kiviteli/behozatali művelet hibáját elkerüljük.

R> ( --- n )
Csak fordításkor alkalmazható (compilation only)
Átviszi a return stack tetején szereplő 16 bites számot, a paraméter stack-re.

R0 ( --- cím )
Rendszerváltozó (user variable), amely a return stack mutatójának kezdőcímét tartalmazza.

REPEAT ( --- )
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate).
Kettőspont definícióban használjuk a következő formában:

BEGIN ... f WHILE ... REPEAT

Az utasítás végrehajtásakor feltétel nélküli visszaugrást hajt végre a hozzá tartozó BEGIN utasítás utáni első utasításra.

ROT ( n1 n2 n3 --- n2 n3 n1 )
Megforgatja a paraméter stack-en lévő három legfelső 16 bites számot úgy, hogy a legmélyebben lévő kerüljön a paraméter stack tetejére.

RP! ( --- )
Gépi kódú definíciós szó (primitív).
Inicializálja a return stack mutatóját (pointer-ét) az R0 rendszerváltozóban lévő értékre.

RP@ ( --- cím )
Gépi kódú definíciós szó (primitív).
A return stack mutatójának az RP@ utasítás végrehajtásakor felvett értékét adja meg.

S->D ( n --- d )
Gépi kódú definíciós szó (primitív).
Az n előjeles 16 bites egész számot, d előjeles 32 bites egésszé alakítja át.

S0 ( --- cím )
Rendszerváltozó (user variable), amely a paraméter stack mutatójának kezdőcímét tartalmazza.

SCR ( --- cím )
Rendszerváltozó (user variable), amely annak a screen-nek a számát tartalmazza, amelyet legutoljára listáztunk.

SEC ( --- cím )
Rendszerváltozó (user variable), amely a diszk egységen az egy sávon lévő szektorok számát tartalmazza.

SEC/BLK ( --- n )
Rendszerkonstans, amely a szektorok számát adja meg egy blokkban.

SEC-READ ( --- )
Gépi kódú definíciós szó (primitív).
Az utasítás elvégzi egy szektor beolvasását a CP/M rendszer felügyelete alatt.
A lemezegységet a SET-DRIVE, a szektor-paramétereket a SET-IO állítja be a rendszerváltozók értéke alapján.

SEC-WRITE ( --- )
Gépi kódú definíciós szó (primitív).
Az utasítás elvégzi egy szektor kiírását a CP/M rendszer felügyelete alatt.
A szektorparamétereket a SET-IO állítja be a rendszerváltozók értéke alapján.

SET-DRIVE ( --- )
Gépi kódú definíciós szó (primitív).
Az utasítás elvégzi a DRIVE rendszerváltozóban megadott számú diszk egység CP/M rendszerben történő kijelölését.

SET-IO ( --- )
Gépi kódú definíciós szó (primitív).
Az utasítás kiküldi a CP/M rendszerbe az aktuálisan használt memóriapufferbeli blokk kezdőcímét (USE) (set DMA funkció), illetve a SEC és TRACK rendszerváltozók tartalmát, amelyek az írni/olvasni kívánt szektor száma és sávszáma.

SIGN ( n d --- d )
Egy "-" jelet tárol a kimeneti szöveg pufferben a <# és #> utasítások alkalmazásakor, ha n értéke negatív.

SMUDGE ( --- )
Új utasítás definíciójakor használjuk fel, hogy az NFA címnél lévő smudge bitet invertálja.
Ez a bit lehetővé teszi számunkra, hogy a fordításkor felmerült hiba miatt a definíciót ne találja meg a rendszer. Így definíciós szavunk csak akkor kerül be a szótárba, ha fordításkor nem történt hiba.

SP! ( --- )
Gépi kódú definíciós szó (primitív).
Inicializálja a paraméter stack mutatóját az S0 rendszerváltozóban lévő értékre.

SP@ ( --- cím)
Gépi kódú definíciós szó (primitív).
A paraméter stack mutatójának az SP@ utasítás végrehajtásakor felvett értékét adja meg.

SPACE ( --- )
Egy szóköz (space) karaktert visz ki az operátori képernyőre.

SPACES ( n --- )
Az utasítás n darab szóköz karaktert visz ki operátori képernyőre.

STATE ( --- cím )
Rendszerváltozó (user variable), amely a rendszer állapotát adja meg.
STATE egyenlő nulla (0) esetén végrehajtási állapotban van a rendszer.
STATE nem egyenlő nulla esetén fordítási állapotban van a rendszer.

SWAP ( n1 n2 --- n2 n2 )
Gépi kódú definíciós szó (primitív).
Megcseréli a paraméter stack tetején lévő két 16 bites számot.

TASK ( --- )
Az utasítás a felhasználó által definiált szavak alsó határát jelenti. A határ megjelölésén túl más funkciója nincs.

THEN ( --- )
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate).
Az utasítást kettőspont definícióban használjuk a kővetkező formában:

f IF ... THEN
f IF ... ELSE ... THEN

Az IF-THEN struktúrában a THEN utasításra akkor kerül a vezérlés, ha f logikai igaz értéke mellett az IF utáni utasításokat végrehajtotta a rendszer, vagy ha f logikai hamis értékű.
Az IF-ELSE-THEN struktúrán a logikai hamis ág végrehajtásának befejezését jelenti (ELSE utáni utasítások).

TIB ( --- cím )
Rendszerváltozó (user variable). (Terminal Input Buffer), amely azt a kezdőcímet tartalmazza, ahol tároljuk a rendszer klaviatúrájáról érkező információkat a későbbi feldolgozás számára egy 80 karakter hosszúságú memóriaterületen.

TOGGLE ( cím b --- )
A címen található byte kizáró vagy kapcsolatát végzi az utasítás a b értékével.
Az eredményt a cím-re helyezi vissza.

TRACK ( --- cím )
Rendszerváltozó, amely a diszk egységen a sávok számát, adja meg.

TRAVERSE ( cím1 n --- cim2 )
A FORTH-ban megengedett változó hosszúságú névmező kezdetét és végét keresi meg az utasítás.
A cím1 érték egy változónév mező első vagy utolsó karaktere.
Az n értéke +1 vagy -1 lehet. Ha n értéke +1, a cím1-től a nagyobb memóriacímek felé kezdi el keresni a név másik végét az utasítás. Ilyenkor cím1-nek a változónév első betűjére kell mutatnia.
Ha n értéke -1, akkor a cím1-től a kisebb memória címek felé indul el a keresés. Ilyenkor a cím1-nek a név utolsó karakterére kell mutatnia.
A cím2 paraméter az utasításnév másik végének címe.

TRIAD ( n --- )
Három darab screen kilistázását végzi el, annak megfelelően, hogy általában ennyi fér el egy sornyomtató lapra.
A listázást új lapon/oldalon kezdi. A bemenő paraméterként megadott n értékéből egy új értéket képez, amely az első 3-mal maradék nélkül osztható n-nél kisebb, vagy n-nel egyező szám.
Kilistázza az új n értékű és az utána kővetkező két screen-t.
A listázást a 15-ös MESSAGE utasítással fejezi be. A felhasználónak így lehetősége van a MESSAGE-nél leírtak szerint tetszőleges szöveget kiírni a három kilistázott screen alá.

TYPE ( cím n --- )
Az utasítás a cím-nél kezdődő n darab karaktert kiviszi az operátori képernyőre.

T&SCALC ( n --- )
Bemenő paraméterként a fizikai szektorszámot kapja az utasítás, amely #BUF * SEC/BLK. Ezt állítja át az adott lemezegységen fizikai sáv és szektorszámmá.

U. ( u --- )
Kiírja u értéket az operátori képernyőre, a BASE, által meghatározott számrendszerben.
A kiírt szám után egy szóköz karaktert is kiír.

U* ( u1 u2 --- ud )
Gépi kódú definíciós szó (primitív).
Két előjel nélküli 16 bites szám előjel nélküli 32 bites szorzatát hagyja a paraméter stack-en.

U/ ( ud u1 --- u2 u3 )
Gépi kódú definíciós szó (primitív).
Az előjel nélküli 32 bites osztandó és a 16 bites osztó osztás utáni művelet eredményét, a 16 bites előjel nélküli maradékot, u2-t és a 16 bites előjel nélküli hányadost, u3-at hagyja a paraméter stack-en.

U< ( u1 u2 --- f )
Logikai igaz értéket hagy a paraméter stack-en, ha u1 kisebb mint u2, egyébként logikai hamis értéket.

UNTIL ( f --- ) (végrehajtáskor)
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate).
Kettőspont definícióban alkalmazzuk a következő formában:

BEGIN ... f UNTIL

Végrehajtási állapotban az UNTIL egy feltételes visszaugrást hajt végre a hozzá tartozó BEGIN-hez.
Ha f értéke logikai hamis, akkor ugrás történik a BEGIN utáni első utasításra.
Ha f értéke logikai igaz az UNTIL utáni utasításon folytatódik a program.

UPDATE ( --- )
A PREV rendszerváltozóban tárolt című blokk megjelölését végzi el az utasítás.
A megjelölt blokkot a rendszer új blokk olvasásakor vagy helyfoglaláskor automatikusan kiírja a háttértárolóra.

USE ( --- cím )
Rendszerváltozó, amely a memóriapufferben aktuálisan használt blokk kezdőcímét tartalmazza.

USER
( b --- ) (definiáláskor)
( --- cím) (végrehajtáskor)
Adattípus definiáló utasítás, amelyet a következő formában alkalmazunk:

b USER cccc

amely egy cccc elnevezésű felhasználói változót definiál.
Az adattípus paraméter mezeje (PFA cím tartalma) tartalmazza b értéket, amely egy fix értékű eltolást jelent az R0 rendszerváltozó tartalma által meghatározott UP (User Pointer) értékhez képest.
Amikor cccc-t később végrehajtjuk, a báziscím (UP) és az eltolás összegeként, kialakult cím-et hagyja a paraméter stack-en, amely egy önálló változó tárolási területe.

VARIABLE ( --- )
Adattípus definiáló utasítás, amelyet a kővetkező formában alkalmazunk:

n VARIABLE kkkk

Amikor ezt az utasítássort interpretálja a rendszer, a VARIABLE létrehoz egy kkkk elnevezésű szótári elemet, amelynek paraméter mezejében (PFA cím tartalma) n értéke van. Amikor kkkk-t később alkalmazzuk végrehajtási állapotban, paraméter mezejének címét fogja a paraméter stack-en hagyni, így az kiolvasható vagy felülírható újabb értékkel.

VOC-LINK ( --- cím )
Rendszerváltozó (user variable), amely egy mező címét tartalmazza az éppen létrehozott szótárban.
Minden szótárnév ezekkel a mezőkkel kapcsolódik egymáshoz, hogy lehetővé tegye a FORGET működését több szótáron keresztül.

VOCABULARY ( --- )
Definíciós szó, amelyet a kővetkező formában alkalmazunk:

VOCABULARY cccc

Az utasítás létrehoz egy cccc elnevezésű szótárt. A cccc későbbi végrehajtásával cccc válik a CONTEXT szótárrá, amelyben először keresi az utasítás nevét az INTERPRET utasítás.
A cccc DEFINITIONS utasítás a cccc-t CURRENT szótárrá teszi, így az új definíciók a cccc szótárhoz csatolódnak.
A FORTH--ban a cccc úgy kapcsolódik a definiáló szótárhoz, hogy tartalmazza mindazokat a definíciókat is, amelyeket definiáló szótára tartalmaz.
Minden szótár hozzá van fűzve a FORTH szótárhoz.
Konvenció, hogy a szótár neveket IMMEDIATE utasításként deklaráljuk.

VLIST ( --- )
Kilistázza az operátori képernyőre az utasítások neveit a CONTEXT szótár utolsó elemétől kezdve.
Tetszőleges klaviatúra billentyű leütésével a listázás befejezhető.

WARM ( --- )
Úgynevezett. "meleg start" utasítás. Inicializálja a memória puffert és egy ABORT utasítás hajt végre.

WARNING ( --- cím )
Rendszerváltozó (user variable), amely a hibakiírás módját vezérli a MESSAGE utasításban.

WHILE ( f --- ) (végrehajtáskor)
Csak fordításkor alkalmazható (compilation only). Fordításkor azonnal végrehajtódó utasítás (immediate).
Kettőspont definícióban használjuk a következő formában:

BEGIN ... f WHILE ... REPEAT

Végrehajtáskor a WHILE feltételes ugrást hajt végre f értékétől függően.
Ha f logikai igaz értékű, akkor a WHILE utáni utasítás végrehajtása történik meg a REPEAT utasításig.
Ha f logikai hamis értékű, a REPEAT után következő utasításra kerül a vezérlés, és így elhagyja a vezérlési struktúrát.

WIDTH ( --- cím )
Rendszerváltozó (user variable), amely a FORTH rendszerben megengedhető definíciós nevek maximális hosszát tartalmazza.
Jelenlegi értéke 31 (decimális).

WORD ( c --- )
Szöveg karaktereket olvas be az aktuális bemeneti egységről a c határoló karakterig, a HERE címnél kezdődő tárolóba.
Első karakterként a tárolóban a szó hosszát adja meg, majd ezután következnek a szó karakterei. A tárolóban elhelyezi a határoló karaktert és egy vagy két nulla karaktert is, de ezeket nem veszi figyelembe a szó hosszának számításánál.
Ha BLK tartalma nulla (0), a karakteres információt a klaviatúráról veszi, nullától eltérő BLK tartalom esetén abból a blokkból, amelyet BLK kijelöl.

XOR ( n1 n2 --- n3 )
Gépi kódú definíciós szó (primitív).
Az utasítás n1 és n2 bitenkénti logikai kizáró vagy (exclusive or) kapcsolatát hagyja a paraméter stack-en (n3).

[ ( --- )
Fordításkor azonnal végrehajtódó utasítás (immediate).
A rendszer fordítási állapotból végrehajtási állapotba kerül az utasítás végrehajtása után.

[COMPILED] ( --- )
Fordításkor azonnal végrehajtódó utasítás (immediate).
Kettőspont definícióban használjuk például a kővetkező formában:

: bbbb [COMPILE] FORTH ;

ahol a [COMPILE] befordítja a bbbb definícióba a FORTH CFA címét, így megváltoztatja az egyébként IMMEDIATE (azonnal végrehajtódó) utasítás tulajdonságát, hogy fordítási állapotban azonnal végrehajtódjék.
Csak a bbbb utasítás végrehajtásakor válik a FORTH a CONTEXT szótárrá, a [COMPILE] nélkül már bbbb definiálásakor végrehajtódott volna.
Az utasítás IMMEDIATE utasítások definícióba történő befordítását teszi lehetővé.

] ( --- )
A rendszer végrehajtási állapotból fordítási állapotba kerül az utasítás végrehajtása után.

12. Néhány hasznos FORTH definíció

12.1. Az utasítások átdefiniálhatóságának lehetősége
A FORTH különböző dialektusaiban, amely a nyelv fejlesztőinek szüntelen munkáját demonstrálja, azonos, vagy közel azonos definíciók szerepelnek az egyes szabványokban rögzített definíciókkal.
A definíciós szavak szinte végtelen skálája lehetővé teszi a felhasználók számára, hogy saját, elnevezéseiket alkalmazzák az egyes szabványok helyett. A definíciós szavak átnevezése nagyon egyszerű a FORTH rendszerben.

: UJ-ELNEVEZES REGI-ELNEVEZES ;

Ez az átnevezési eljárás azonban csak olyan utasítások esetén alkalmazható, amelyek nem azonnal végrehajtódóak és nem csak fordítási állapotban alkalmazhatók.
A fordítási állapotban azonnal végrehajtódó utasítások nevének átalakítására a következő átnevezési definíciót kell alkalmazzuk.

DECIMAL
: UJ-ELNEVEZES
  STATE @
  IF [COMPILE] REGI-ELNEVEZES
  ELSE
    REGI-ELNEVEZES CFA EXECUTE
THEN ; IMMEDIATE

A szavak átdefiniálásával FORTH programjainkat olvashatóvá tehetjük.
A definíciós szavak elnevezésében az illető téma szakszókincsét alkalmazva a program illetve definíciós szó felépítése könnyebben követhető. (Előfordulhat az a FORTH tanulásakor is!) Ez az egyik irányzat, amely a programok olvashatósága felé mutat.
Más alkalmazásban az operandusok minél rövidebb, tömörebb leírása a cél. Ilyen esetben is jól jöhet, az átdefiniálás lehetősége.

12.2. CASE struktúra
A magasabb szintű programozási nyelvekben alkalmazott SELECT-CASE (BASIC-ben ON GOTO / ON GOSUB) típusú definícióknak nincs megfelelője a FORTH standard utasításai között. A vezérlés a változó egy kurrens értékétől függő elágaztatását a nyelvben a CASE utasítás teszi lehetővé. A CASE FORTH-ban történő megvalósítására mutatunk egy megoldást.
A CASE funkció megvalósításánál példánkban a paraméter stack-en lévő számérték határozza meg, hogy több utasítássorozat közül melyik kerül végrehajtásra. Az utasítás alakja például a következő:

2 (érték a stack-en)
CASE
  1 OF csináld-az-első-feladatot ENDOF
  2 OF csináld-a-második-feladatot ENDOF
  3 OF csináld-a-harmadik-feladatot ENDOF
  egyébként-amit-csinálni-kell
ENDCASE

A FORTH program a CASE utasításhoz érkezve a stack-en talált érték alapján eldönti, hogy melyik feladatot kall elvégezni. Ha a stack-en talált érték nem egyezik meg a CASE utasítás utáni felsorolt lehetséges értékek egyikével sem, akkor és csak akkor hajtódik végre a struktúrában az "egyébként-amit-csinálni-kell" rész.
A CASE struktúra tehát alapvetően a CASE, OF, ENDOF és ENDCASE definíciós szavakból áll. Ezen szavak definíciója a következő lehet:

FORTH DEFINITIONS DECIMAL
: CASE  ?COMP CSP @ !CSP 4 ; IMMEDIATE
: OF    4 ?PAIRS COMPILE OVER COMPILE =
        COMPILE 0BRANCH HERE 0 , COMPILE DROP
        5 ; IMMEDIATE
: ENDOF 5 ?PAIRS COMPILE BRANCH HERE 0 ,
        SWAP 2 [COMPILE] THEN 4 ; IMMEDIATE
: ENDCASE 4 ?PAIRS COMPILE DROP
        BEGIN SP@ CSP @ = 0=
        WHILE 2 [COMPILE] THEN REPEAT
        CSP ! ; IMMEDIATE

12.3. Dupla pontosságú műveletek
A fig-FORTH kiterjesztéseként definiálhatunk 32 bites operandusokon is műveleteket. Ezek nem mind tartoznak a fig-FORTH standardba, de definiálásukkal lehetőségünk nyílik 32 bites egészekkel való műveletvégzésre. (32 bit = 1 bit előjel + 31 bit információ.) Ezen kívül ötleteket adunk arra, hogy hogyan kell 16 bitnél nagyobb szóhosszúságú értékekre aritmetikát definiálni. (A FIG-FORTH-ban szereplő utasításokat megjelöltük a felsorolásban.)
A szókészlet elemei a kővetkezők:

2! ( d cím )
(fig-FORTH)
Tárolja a d előjeles 32 bites számhoz tartozó 4 byte-ot a címtől kezdődően.

2@ ( cím --- d )
(fig-FORTH)
A paraméter stack-en hagyja a cím-nél kezdődő 32 bites számhoz tartozó byte-okat.

2CONSTANT ( d --- ) ( definiáláskor )
Definíciós szó, amelyet a következő formában alkalmazhatunk:

d 2CONSTANT nnnn

Ez fordítási állapotban létrehoz egy nnnn nevű szótári elemet, melynek paraméter mezejében elhelyezi a d 32 bites számot, Végrehajtáskor az nnnn a d értéket hagyja a paraméter stack-en. (Működése megegyezik a 16 bites előjeles egészekre alkalmazható CONSTANT-tal.)

2DROP ( d --- )
Eldobja a stack tetején lévő dupla pontosságú számot.

2DUP ( d --- d d )
(fig-FORTH)
Duplikálja a stack-en lévő 32 bites számot.

2OVER ( d1 d2 --- d1 d2 d1 )
A stack-en, amelyet most 32 bites elemekből állónak tekintünk, a második adatként szereplő 32 bites számot a stack tetejére is lemásolja.

2ROT ( d1 d2 d3 --- d2 d3 d1 )
A stack-en harmadik adatként szereplő dupla pontosságú számot a stack tetejére mozgatja.

2SWAP ( d1 d2 --- d2 d1 )
Megcseréli a stack tetején szereplő két dupla szavas számot.

2VARIABLE ( d --- ) ( definiáláskor )
Definíciós szó. Alkalmazása:

d 2VARIABLE kkkk

Ez a forma fordítási állapotban létrehoz egy kkkk nevű szótári elemet, és lefoglal négy byte-ot ennek paraméter mezejében.
A kkkk végrehajtáskor a paramétermező első byte-jának címét hagyja a stack-en.

D+ ( d1 d2 --- d3 )
(fig-FORTH)
A d1 és d2 32 bites előjeles számok előjeles összegét (d3) hagyja a stack-en.

D- ( d1 d2 --- d3 )
Kivonja a d2 értéket d1-ből, és az előjeles 32 bites végeredményt hagyja a stack-en.

D. ( d --- )
(fig-FORTH)
Kiírja az aktuális kimeneti egységre a d 32 bites, előjeles számot, a BASE értékétől függő számrendszerben, szabad formátumban. Az adatot kiíráskor egy szóköz (space) karakter is követi. Az előjelet csak akkor írja ki, ha az negatív.

D.R ( d n --- )
(fig-FORTH)
Kiírja az aktuális kimeneti egységre a d 32 bites, előjeles számot a BASE értékétől függő számrendszerben. A számot n szélességű mezőben jobb oldalra tömöríti. Az előjelet csak akkor írja ki, ha az negatív.

D0= ( d --- f )
Logikai igaz értéket hagy a paraméter stack-en, ha d értéke zérus.

D< ( d1 d2 --- f )
Logikai igaz értéket hagy a paraméter stack-en, ha d1 kisebb, mint. d2.

D> ( d1 d2 --- f )
Logikai igaz értéket hagy a paraméter stack-en, ha d1 nagyobb mint d2.

D= ( d1 d2--- f )
Logikai igaz értéket hagy a paraméter stack-en, ha d1 értéke megegyezik d2 értékével.

DABS ( d1 --- d2 )
(fig-FORTH)
A d1 abszolút értékét (d2) hagyja a paraméter stack-en.

DMAX ( d1 d2--- d3 )
A d1 és d2 dupla pontosságú számok közül a nagyobbikat hagyja a paraméter stack-en (d3).

DMIN ( d1 d2 --- d3 )
A d1 és d2 dupla pontosságú számok közül a kisebbiket hagyja a paraméter stack-en (d3).

DMINUS ( d1 --- d2 )
(fig-FORTH)
A d1 32 bites előjeles szám kettes komplemensét hagyja a paraméter stack-en, mint 32 bites, előjeles számol (d2).

DU< ( ud1 ud2 --- f )
Logikai igaz értéket hagy a stack-en, ha ud1 kisebb mint ud2, ahol ud1 és ud2 előjel nélküli, 32 bites egész számok.

A fig-FORTH szókészletébe nem tartozó műveletek a következő módon definiálhatók:

: 2SWAP ( d1 d2 --- d2 d1 )
  ROT >R ROT R> ;

: 2OVER ( d1 d2 --- d1 d2 d1 )
  >R >R 2DUP R> R> 2SWAP ;

: 2DROP ( d1 d2 --- d1 )
  DROP DROP ;

: 2ROT (d1 d2 d3 --- d2 d3 d1 )
  >R >R 2SWAP R> R> 2SWAP ;

: 2VARIABLE ( d --- )
  <BUILDS , , DOES> ;

: 2CONSTANT ( d --- )
  <BUILDS , , DOES> 2@ ;

: D2DUP ( d1 d2 --- d1 d2 d1 d2 )
  2OVER 2OVER ;

: D> ( d1 d2 --- f )
  DMINUS D+ SWAP DROP DUP 0 > SWAP 0= ;

: D= ( d1 d2 --- f )
  DMINUS D+ + 0= ;

: D0= ( d --- f )
  0. D= ;

: D- ( d1 d2 --- d3 )
  DMINUS D+ ;

: D< ( d1 d2 --- f )
  2SWAP D> ;

: DMAX ( d1 d2 --- d3 )
  D2DUP D< IF 2SWAP THEN 2DROP ;

: DMIN ( d1 d2 --- d3 )
  D2DUP D> IF 2SWAP THEN 2DROP ;

: DU< ( ud1 ud2 --- f )
  D2DUP 0. D< >R 0. D< R> XOR
  IF 2DROP 2DUP DABS D=
  ELSE DABS 2SWAP DABS 2SWAP D< THEN ;

12.4. Megszakítás beiktatása a definíciós szóba
Bonyolult definíciós szavak tesztelésekor szükség lehet az utasítás megszakítására. A töréspont beiktatásának lehetősége sok segítséget nyújt a kezdő FORTH programozónak is, hogy hibaanalízist végezhessen definícióiban. A következő, programmegszakítást előidéző BREAK szót a definíció szövegébe kell "szerkeszteni". Így a szó "belefordítódik" a definícióba.
Végrehajtáskor egy software-es megszakítás keletkezik ezen definíciónál a FORTH rendszerben. Ekkor a cursor megkülönböztetésül az alap FORTH rendszerbeli cursor-tól "[ok]" jelzéssel nyugtázza a parancsokat.
A megszakított definíció vizsgálatára minden, a FORTH rendszerben korábban definiált eszköz felhasználható, csupán egyetlen kikötés van. A megszakított definíció sikeres folytatásához a return stack-et abban az állapotban kell hagyjuk, ahogyan az a megszakítást közvetlenül megelőző utasítás után volt.
A megszakított állapotból való kilépés - vagyis a definíciós szó végrehajtásának folytatása - a GO utasítás segítségével történik. Ha a return stack-et. "rendben találja" az utasítás, akkor folytatja a megszakított definíció végrehajtását. Ha valami nincs rendben a return stack állapotával "Nem folytatható!" hibajelzést kapunk, és marad a megszakításos állapot. Ha korrigálni tudjuk a hibát a return stack-en, akkor újabb GO utasítással próbálkozhatunk, ha ez nem sikerül, a QUIT utasítással térhetünk vissza az alaprendszerbe.
A BREAK és GO definíciója a szükséges kiegészítő segéd definíciókkal együtt a következő:

: RDEPTH R0 @ RP@ 2 + - 2 / ;

: R.N ( Kiírja a return stack tartalmát )
  RDEPTH IF RP@ 2 - R0 @ 2 - DO I @ U. -2 +LOOP
  ELSE ." Ures " THEN ;

: DEPTH S0 @ SP@ 2 + - 2 / ;
: .S ( Kiírja a stack tartalmát )
  DEPTH IF SP@ 2 - S0 @ 2 - DO I @ U. -2 +LOOP
  ELSE ." Ures " THEN ;

0 VARIABLE CHECK
FORTH DEFINITIONS

: BREAK ( --- )
  HEX CR ." BREAK " CR ." Parameter stack = " .S
  CR ." Return stack = " R.N DECIMAL
  RP@ 4 - CHECK ! 0 BLK !
  BEGIN QUERY INTERPRET ." [ok]" CR AGAIN ;

: GO ( --- )
  RP@ CHECK @ = IF R> DROP R> DROP
  ELSE ." Nem folytathato!" QUIT
  THEN ;

12.5. A memóriatartalom listázása (Memory Dump)
A memóriatartalom listázása a programbelövéshez jól felhasználható segédeszköz. A listázás a CP/M operációs rendszerben megszokott formában történik.
A kiírt sorok elején a kezdő memóriacímet adja meg az utasítás, majd ezt követi a DB konstansban meghatározott mennyiségű hexadecimális szám - a megfelelő byte-ok tartalma. A hexadecimális számokat a megfelelő DB számú karakter követi. A nem kiírható karakterek helyébe pontot (.) ír ki az itt kővetkező definíció.
A képernyőn egyszerre a BKK konstansban meghatározott adat kerül kiírásra. A memória tartalmának kilistázása adott kezdőcímtől a

DUMP ( cím --- )

utasítással lehetséges, ahol a cím a kiírás kezdőcíme. A listázás folytatását teszi lehetővé az ASK definíció a Continue? kérdéssel. Ha a válaszként leütött karakter a szóköz (space) billentyű, akkor a listázás folytatódik, egyébként pedig befejeződik.
A definícióból való kilépéskor hexadecimális számrendszerben marad a rendszer.

( DUMP ) ( addr --- )
DECIMAL 8 CONSTANT DB 128 CONSTANT BKK
: HEXOUT DUP 16 < IF 48 EMIT THEN U. ;
: PR DUP 31 > OVER 128 < AND IF EMIT ELSE DROP ." ." THEN ;
: SORCH 2 SPACES DUP DB + SWAP DO I C@ PR LOOP ;
: EXAM SWAP DUP ROT < IF 48 EMIT THEN ;
: 0OUT 4 0 DO 48 EMIT LOOP 32 EMIT ;
: ADDR DUP DUP 0= IF 0OUT DROP ELSE DUP 0 >
  IF 16 EXAM 256 EXAM 4096 EXAM U. ELSE U. THEN THEN ;
: SOR DUP DB + SWAP DO I C@ HEXOUT LOOP ;
: KEP DUP BKK + SWAP DO CR I ADDR SOR I SORCH DB +LOOP CR ;
: ASK ." Continue (SPACE = yes)" KEY 32 = ;
: DUMP HEX BEGIN DUP KEP BKK + CR ASK 0= CR END DROP ;

12.6. A 79-Standard FORTH eltérő utasításainak definíciója

( FORTH-79 VOCABULARY )
FORTH DEFINITIONS HEX
: 79-STANDARD ; ( verify that system supports FORTH-79 )
: PICK 2 * SP@ + @ ;
: ROLL DUP >R PICK R> 0 SWAP DO
    SP@ I 2 * + DUP 2 - @ SWAP ! -1 +LOOP DROP ;
: ?DUP -DUP ;
: R@ R ;
: DEPTH S0 @ SP@ - 2 - 2 / ; ( no. of items on stack )
: 0> DUP IF 0< 0= ENDIF ;    ( comparison operators )
: D< DMINUS D+ SWAP DROP 0< ;
: NOT 0= ;
: U/MOD U/ ;   ( arithmetic and logical )
: NEGATE MINUS ;
: DNEGATE DMINUS ;
: MOVE DUP + CMOVE ;
: J RP@ 6 + @ ; ( control structures )
: EXIT R> DROP ;
: CONVERT (NUMBER) ;     ( numeric conversion )
: SAVE-BUFFERS FLUSH ;   ( mass storage input and output )
: FIND -FIND DUP IF DROP DROP CFA ENDIF ; ( vocabularies )
: >IN IN ;
: VARIABLE 0 VARIABLE ;  ( defining words )
: 2VARIABLE VARIABLE 2 ALLOT ;
: CREATE VARIABLE -2 ALLOT ;
: WORD WORD HERE ;
DECIMAL

Hibaüzenetek

fig-FORTH 1.1
0 Az utasítás nincs a szótárban
1 A paraméter stack üres
4 A név már szerepelt
7 A paraméter stack megtelt
15 8080 FIG-FORTH 1.1
17 Csak fordításkor alkalmazható
18 Csak végrehajtáskor alkalmazható
19 A feltételek nem megfelelőek
20 Az utasítás nincs befejezve
21 A név védett szótári elem
22 Csak töltéskor alkalmazható
24 Deklaráld a szótárt

 

8080 CPM-FORTH 2.2
0 Az utasítás nincs a szótárban
1 A paraméter stack üres
4 A név már szerepelt
6 Érvénytelen blokk szám
7 A paraméter stack megtelt
15 8080 CPM-FORTH 2.2
17 Csak fordításkor alkalmazható
18 Csak végrehajtáskor alkalmazható
19 A feltételek nem megfelelőek
20 Az utasítás nincs befejezve
21 A név védett szótári elem
22 Csak töltéskor alkalmazható
24 Deklaráld a szótárt
28 A file nem található
29 Hiba a file lezárásánál
30 Nincs hely a lemezen

Spectrum-FORTH

0 Az utasítás nincs a szótárban
1 A paraméter stack üres
2 A szótár megtelt
3 A címzési mód nem megfelelő
4 A név már szerepelt
7 A paraméter stack megtelt
15 SPECTRUM-FORTH
17 Csak fordításkor alkalmazható
18 Csak végrehajtáskor alkalmazható
19 A feltételek nem megfelelőek
20 Az utasítás nincs befejezve
21 A név védett szótári elem
22 Csak töltéskor alkalmazható
23 A szerkesztett screen-en kívül vagyunk
24 Deklaráld a szótárt

Abersoft FORTH

0 Az utasítás nincs a szótárban
1 A paraméter stack üres
2 A szótár megtelt
3 A címzési mód nem megfelelő
4 A név már szerepelt
6 RAM disc terület?
7 A paraméter stack megtelt
9 Próbáld a 0. screen-től betölteni
15 ABERSOFT-FORTH
17 Csak fordításkor alkalmazható
18 Csak végrehajtáskor alkalmazható
19 A feltételek nem megfelelőek
20 Az utasítás nincs befejezve
21 A név védett szótári elem
22 Csak töltéskor alkalmazható
23 A szerkesztett screen-en kívül vagyunk
24 Deklaráld a szótárt

C64 FORTH

1 A paraméter stack üres
2 A szótár megtelt
3 A címzési mód nem megfelelő
4 A név már szerepelt
5 A név védett szótári elem
6 Disc terület?
7 A paraméter stack megtelt
8 Disc hiba
9 Nem 8 bites érték vagy cím
10 Csak töltéskor alkalmazható
11 A szerkesztett screen-en kívül vagyunk
12 Nem megfelelő érték - újra megadható
13 Túl nagy érték - újra megadható
15 C64 FORTH
17 Csak fordításkor alkalmazható
18 Csak végrehajtáskor alkalmazható
19 A feltételek nem megfelelőek
20 Az utasítás nincs befejezve
24 Az átvitel megszakadt
25 Túl sok file van
26 A file már nyitva van
27 A file nincs nyitva
28 A file nem található
29 Az egység nincs bekapcsolva
30 Nem bemeneti file
31 Nem kimeneti file
32 A file név elveszett
33 Nem megfelelő egységszám

Irodalomjegyzék

Leo Brodie:
Starting FORTH
Prentice Hall, Englewood Cliffs N.J., 1981

R. G. Loeligers:
Threaded Interpretive Language
Byte Books Peterborough N.H., 1981

FORTH Interest Groups:
Fig-FORTH Installation Manual and Assembly Listings
San Carlos, California, 1979

FORTH Interest Group:
FORTH-79 Standard
San Carlos, California, 1979

Peter M. Kogge:
An Architectural Trail to Threaded Code Systems
Computer, 1982 március

G. Feierbachs
FORTH - the Language of Machine Independence
Computer Design, 1981 június

Thom Hogan:
Discover FORTH
Osborne / McGraw-Hill, 1982

Forgács Tamás - Vécsei Tibor:
Grafikus Editor Rendszerterv
UNDP-UNIDO project RT 371/a

T. Ritter - G. Walker:
Varieties of Threaded Code for Language Implementation
Byte, 1980 szeptember

G.E. Bernieer:
Single-chip Micro Speaks FORTH
Computer Design, 1982 október

Vissza az ENTERPRISE könyvekhez

Vissza a SPECTRUM könyvekhez