CAMForth

Il CAMForth si basa sul dizionario base del Forth, visto finora, ampliandolo con tutti i comandi indispensabili per il funzionamento corretto della CAM 8.
Questi comandi possono essere raggruppati in comandi di impostazione, comandi per la dinamica degli esperimenti e i comandi per la osservazione, diretta o indiretta, dei risultati.
Prima di conoscere i vari comandi, bisogna saper riconoscere le due unità base della programmazione CAM: le istruzioni e le steplist.
Le prime sono comandi che compiono una lettura o una scrittura di un particolare registro di tutti gli STEPchips dei moduli selezionati. L'operazione di default è la scrittura, la lettura deve essere specificata. Sono istruzioni per esempio:

 site-src host
 scan-io my-buffer
 event read event-buffer
 site-src site
 
Le steplist sono liste collegate di istruzioni. Ci sono due tipi di liste: named e unnamed. L'insieme di istruzioni sopra, seguito dalla parola *step*, forma una steplist unnamed. Le steplist, al momento dell'esecuzione di *step*, vengono trasmesse dal Forth alla CAM per essere eseguite. Si può dire che la CAM riceve istruzioni quando viene raggiunto il comando *step*.
Andiamo per ordine e analizziamo tutti i comandi CAMForth.

  1. Configurazione spaziale

    I comandi di impostazione informano la CAM 8 su dimensioni, grandezze e connessioni. Il comando indispensabile in tutti i programmi CAM 8 è

     ... BY ... SECTOR   
     
    Esso imposta le dimensioni, espresse implicitamente tramite BY, e le grandezze, in numero di siti, per ogni dimensione:
     256 BY 256 SECTOR   
     
    significa impostare uno spazio bidimensionale di 256 siti nella dimensione x e 256 nella dimensione y.
    Ovviamente si possono creare le configurazioni più strane, senza però mai superare la totale disponibilità di memoria di un modulo.
    Da notare che il valore 1 è un argomento valido nel comando ... BY ... SECTOR: semplicemente indica che la corrispondente dimensione si estende lungo la connessione dei moduli presenti.
    Un altro comando molto importante, risultato di molti sforzi compiuti nella progettazione dello STEPchip, è select.
    Consideriamo il caso di una macchina consistente in alcuni moduli connessi, per esempio, come un parallelepipedo.
    Quando i dati si spostano da un modulo all'altro, abbiamo visto nel paragrafo gluing intervenire il meccanismo di gluing, che è essenziale per connettere i moduli tra loro e formare un unico grande spazio. Vediamo come definire o modificare queste connessioni.
    Ogni modulo fisicamente connesso a una macchina ha due opzioni: connettersi logicamente ai moduli vicini, formando un grande spazio, o ignorare qualsiasi vicino presente e funzionare autonomamente con il proprio spazio arrotolato nella dimensione x, y e z.
    Connessione fisica e connessione logica possono non coincidere: ciò è utile, poiché non si dovranno rimontare i moduli in posizioni diverse ogni volta che cambia lo spazio simulato, ma semplicemente occorrerà riprogrammare i comportamenti delle porte di uscita e di entrata.
    In figura 1 possiamo vedere due connessioni fisiche differenti. Esse differiscono dal modo in cui i layers vengono traslati all'esterno dei moduli (glue): la prima connessione realizza uno spazio monodimensionale, la seconda uno spazio bidimensionale. La seconda però è in grado di simulare la prima semplicemente isolando due dei moduli presenti e riprogrammando i comportamenti delle porte.

    Ogni STEPchip ha 6 connessioni fisiche, una per ogni direzione e verso, sulle quali trasmettere e ricevere i dati dai vicini nelle direzioni x-, x+, y-, y+, e z+. Questi pins sono chiamati XMP, XPP, YMP, YPP, ZMP e ZPP rispettivamente. Normalmente il pin fisico x+, cioè XPP, agisce da pin logico x+; i dati mandati nella direzione x+ usciranno dal pin XPP, così come i dati mandati nella direzione x- usciranno dal piedino XMP. Ma tutti i sei pins fisici sono riprogrammabili, essi possono svolgere il compito di uno qualunque degli altri pins.
    Per cambiare i normali comportamenti occorre usare il registro Glue Pin Connectivity, seguendo quanto è illustrato nella tabella 1.
    Corrispondenze pin fisici-logici.
    Contenuto registroRuolo logico
    0x-
    1x+
    2y-
    3y+
    4z-
    5z+
    60
    71

    I valori dei bits 6 e 7 forzano i pin corrispondenti a un'uscita rispettivamente di tutti 0 o tutti 1. Questo è usato principalmente nelle routine di inizializzazione della macchina e di solito non sono usati in un esperimento.
    Nel momento dell'inizializzazione ogni modulo di una macchina composta da molti moduli ha un nome unico, conosciuto come module-id. Usando questo nome possiamo indirizzare ognuno di questi e riprogrammare la glue.
    Ora cerchiamo di realizzare il proposito di trasformare la connessione fisica della macchina in figura 1b in uno spazio monodimensionale, cioè rendere la connessione logica equivalente a quella in figura 1a.
    Partiamo pensando al modo in cui i moduli dovranno essere ricollegati: ognuno di questi dovrà avere solo due moduli adiacenti.
    Realizziamo questa connessione seguendo la tabella discussa prima.

     select 0 module     \ seleziono il modulo 0
     connect 1 xppc!     \ x+ fisico agisce come x+ logico
             0 yppc!     \ y+ fisico agisce come x- logico
             2 xmpc!     \ x- fisico non deve entrare in gioco,
                         \ quindi lo ridireziono come y-
    
     select 1 module     \ seleziono il modulo 1
     connect 2 xppc!     \ x+ posto fuori gioco
             1 yppc!     \ y+ agisce come x+
             0 xmpc!     \ x- agisce come x-
    
     select 2 module     \ seleziono il modulo 2
     connect 3 xppc!     \ x+ posto fuori gioco
             1 xmpc!     \ x- agisce come x+
             0 ympc!     \ y- agisce come x-
    
     select 3 module     \ seleziono il modulo 3
     connect 3 xmpc!     \ x- posto fuori gioco
             1 ympc!     \ y- agisce come x+
             0 xppc!     \ x+ agisce come x-
     
    Analizziamo i nuovi collegamenti. Dobbiamo fare in modo che uno shift in una delle due sole direzioni possibili dello spazio modimensionale faccia scorrere i dati attraverso i moduli in modo che quello che esce a destra del modulo 0 entri a sinistra del modulo 1, quello che esce da destra di 1 entri a sinistra di 2, e così via fino ad arrivare al modulo 3, per il quale quello che esce alla sua destra, sempre guardando il centro dell'anello, entra alla sinista di 0, chiudendo l'anello: compiendo uno shift circolare di proporzioni adeguate dobbiamo fare in modo di ritrovarci nelle condizioni iniziali.
    Per questo, nel modulo 0, x+ agisce da x+, essendo questo proprio diretto verso il modulo 1, mentre x- deve essere ridiretto poiché il suo normale collegamento, nel caso bidimensionale, rientrerebbe a destra del modulo 1. Invece da piedino x- deve fungere y+, accettando i dati in arrivo dal modulo 3.
    Questa stessa filosofia è applicata per il modulo 1, quindi x- agisce da x-, mentre è y+ che agisce da x+.

  2. Definizione della dinamica degli esperimenti

    Il concetto dello scan è importantissimo nella definizione della evoluzione dinamica del sistema, poiché esso determina quali siti saranno sottoposti al processo di update.
    Andiamo quindi ad analizzarlo.

    1. Scanning site array

      Nella CAM 8 l'unità di tempo fondamentale è lo scan, un processo indivisibile di updating della totalità o di solo una parte dell'array delle celle, che memorizzano gli stati degli automi.
      Uno scan può essere iniziato in due modi:

      1. scrivendo un valore diverso da zero nello Scan Mode del registro Run Mode
      2. scrivendo o leggendo il registro Scan I/O
      Lo scan è eseguito tramite il registro Scan Index, un contatore autoincrementante, e dal registro Scan Index Permutation, il quale specifica quali bits dello Scan Index saranno usati per formare il Site Address.
      Lo scan termina quando lo Scan Index raggiunge il valore indicato nello End of Scan Pointer, campo del registro Scan Format.
      L'utente raramente dovrà impostare direttamente questi registri: valori appropriati vengono memorizzati automaticamente da ... BY ... SECTOR.
      Viene imposta la durata dello scan uguale al prodotto delle grandezze delle dimensioni fissate all'interno del comando stesso, direzionando lo scan da sinistra a destra, dall'alto in basso e da davanti a dietro delle celle che compongono lo spazio.
      La prima dimensione menzionata in ... BY ... SECTOR viene presa come dimensione x, la seconda come dimensione y e così via. Le prime tre dimensioni sono speciali: sono le sole che possono essere estese indefinitamente aggiungendo dei moduli alla macchina.
      Comunque, nei casi in cui si voglia procedere allo scan di solo una parte dell'intero spazio, si può agilmente ovviare a questa necessità usando il comando ... BY ... SUBSECTOR, senza dover toccare direttamente i registri.

    2. Manipolazione dell'array dei siti

      L'obiettivo di uno scan è normalmente aggiornare le celle secondo le regole di update degli automi. Il registro Site-src si occupa di decidere quale tipo di informazione verrà scritta nella DRAM: potrà essere il risultato di ritorno dalla LUT, o l'ingresso flywheel, o dati provenienti dall'host e così via.
      Questi ingressi per la DRAM sono:

      • bits unglued, per macchine con un solo modulo o con moduli isolati.
      • bits in arrivo dall'host, in genere per inizializzare lo spazio.
      • bits flywheel, in arrivo da videocamere o comunque hardware esterno di acquisizione dati.
      • bits di ritorno dalla lut.
      Per inizializzare le celle bisogna appoggiarsi al comando scan-io, il quale non fa altro che usare il registro SIOR come mezzo di comunicazione con l'host:
       site-src host        \ imposta l'host come sorgente per le celle
       scan-io init-pattern \ il buffer init-pattern viene letto e scritto
                            \ nelle celle
       
      Un modo più semplice, se si ha un pattern disponibile in un file, è usare il comando file>cam "nome.del.pattern", che non fa altro che appoggiarsi ai comandi sopra citati.
      Dopo l'inizializzazione dello spazio le sorgenti per le celle diventano le elaborazioni di ritorno dalla LUT:
       lut-src site   \ imposta la LUT ad essere indirizzata dalle celle
       site-src lut   \ le celle vengono aggiornate dalla LUT
       
      Diverse combinazioni, anche le più strane, possono essere specificate manipolando il registro Site Data Source. Inoltre il comando map viene in nostro aiuto per realizzare delle situazioni molto particolari, come può essere voler rimpiazzare il contenuto delle celle con un XOR tra il valore di ritorno dalla LUT e il contenuto stesso della cella.
       site-src site map lut map xor map!
       
      In pratica map estrae il valore e lo rende disponibile a una successiva elaborazione, terminata da map!.

    3. Layers
      Prima di tutto, vediamo come dare un nome più familiare a un layer o a un gruppo di layers:
       0 0 == nord
       1 1 == sud
       2 2 == est
       3 3 == ovest
       0 3 == direzioni
       
      Tramite la parola "==", ai campi compresi tra il numero nella prima posizione e il numero nella seconda, possiamo dare ad essi un nome più indicativo. Riferimenti successivi ai layers possono essere compiuti tramite questi nomi.

    4. Kick

      La CAM 8 è una macchina ad automi cellulari partizionati: questo significa che il nuovo valore dei bits di ritorno da un'elaborazione della LUT dipende solo dal vecchio valore che i bits avevano in quel sito, cosicchè, quando l'update di tutte le celle sarà terminato, il risultato è necessariamente indipendente dall'ordine di scan delle celle.
      Senza un modo per muovere questi bits all'interno delle celle, la macchina sarebbe inutile, consisterebbe di milioni di piccoli sistemi non interagenti, ognuno consistente di 16 bits.
      Il kicking invece rende la CAM 8 molto flessibile per lo studio e lo sviluppo di esperimenti con automi cellulari.
      Il kicking è applicato a un intero spazio (attenzione: si sta considerando il kick, non lo scan.), non è possibile limitarlo ad una parte, per ovvi problemi di memoria che questo comporterebbe.
      I bits in un layer possono essere rigidamente traslati in ogni direzione o combinazioni di direzioni, fino alla massima proporzione che è uguale alla grandezza di ogni dimensione impostata nel comando ... BY ... SECTOR.
      Il kick è compiuto specificando il comando kick, seguito dai suoi parametri per ogni layer:

       kick      nord field  1 x 2 y
                 sud  field -1 x 3 y
       
      significa che il layer nord viene spostato di 1 lungo la direzione x e 2 lungo la direzione y, mentre il layer sud viene spostato di -1 lungo x e 3 lungo y.
      Il comando kick ad ogni scan sottrae i suoi parametri al registro Offset, quindi un valore negativo corrisponde a una traslazione all'indietro rispetto agli altri layers, mentre un valore positivo corrisponde a un avanzamento.
      Tutte le dimensioni specificate nel comando ... BY ... SECTOR possono essere argomento di un kick, questo vuol dire che posso shiftare i layer anche lungo z o lungo una dimensione fittizia kn.
      Un kick può essre specificato anche così:
       kick   16-layers:  1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x
                 16-layers:  2  3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 y
       
      e ha lo stesso effetto di prima, ogni posizione corrisponde a un layer. Le parole x e y si riferiscono alle dimensioni specificate tramite il comando ... BY ... SECTOR.
      I layers agiscono da nastri trasportatori per le particelle che stanno su di essi.
      Compiendo due kick consecutivi, il secondo non sovrascrive il primo, ma la somma dei due viene compiuta.
      Nel kick prende parte anche il gluing, già discusso prima. Questo però tiene conto del registro kick per compiere le sue operazioni, quindi scrivendo due volte nel registro kick prima di compiere uno scan può portare a interpretazioni errate e a funzionamenti non corretti.
      Il kick può essere compiuto in tutte le dimensioni specificate all'inizio dell'esperimento, indicando le prime tre dimensioni con le parole x, y, z, e quelle superiori a tre tramite la parola kn, preceduta da un argomento, cioè il numero della dimensione partendo da 0: una quarta dimensione sarà indicata 3 kn.
      Per esempio:
       32 by 32 by 64 by 64 sector
       kick   0 layer 4 x 4 y 2 z 1 3 kn
       
      Il kick è uno strumento potente e vedremo negli esempi come sfruttarlo.

    5. Costruzione delle regole

      La CAM 8 è in grado di eseguire complesse e composte regole di update, per simulare comportamenti dinamici complicati.
      La lookup table è memorizzata in SRAM per poter essere più veloce possibile e ogni suo indirizzo corrisponde a un possibile stato di una cella. Allo stato di una cella, allora, posso associare tramite la LUT un nuovo valore.
      Le lut sono costruite seguendo le regole dell'automa; possiamo pensare di crearle manualmente, oppure, più agilmente, affidarci alle parole del CamForth create per questi scopi.
      Vediamo un esempio.
      Prima di tutto bisogna definire una nuova parola Forth; ne costruisco una che segua le regole HPP:

       0 0 == nord
       1 1 == sud
       2 2 == est
       3 3 == ovest
      
       : hpp-rule
        nord sud =       \ confronto nord e sud
        est ovest =      \ e est con ovest
        and              \ se sono vere entrambe...
        if
        est <-> nord     \ ...scambio
        ovest <-> sud
        then ;           \ altrimenti non cambio niente
       
      hpp-rule ora è definita nel dizionario e può essere usata per costruire la regola.
      L'esempio sopra è denso di cose nuove.
      Prima di tutto abbiamo confrontato due layers: nord e sud. Questa operazione bisogna vederla nell'ottica giusta in quanto essa non è un'operazione sull'intero layer, poiché all'interno di queste definizioni bisogna considerare le singole celle. Visto in tal modo si può riconoscere che nord sud = è un'operazione su bits, cioè il bit del campo nord di una singola cella con il bit del campo sud sempre della stessa cella.
      L'altro operatore <-> è ora semplice da spiegare: est<->nord semplicemente scambia i contenuti dei bit est e nord.
      Altro esempio: nord sud xor -> ovest compie un xor logico tra i campi nord e sud e il risultato lo inserisce nel campo ovest.
      Ora che sappiamo costruire le parole per le regole, bisogna fare in modo che il Forth generi il buffer con la loro esplicitazione.
      Questo è compito del comando rule>table . Prima di eseguire rule>table però, dobbiamo avere un buffer sufficientemente grande da contenere la regola che vogliamo esplicitare, in questo modo:
      numelementi create-table nometabella
      numelementi è il numero di elementi nella lut, che sarà uguale a 2^numlayers, dove numlayers è il numero di layers usati nella regola, che non dovrà essere per forza 16, mentre nometabella è il nome del buffer dove la regola verrà esplicitata, per poi essere scritta nella lut.
      Costruiamo la lut: 2^4=16, quindi numelementi dovrà essere uguale a 16,
       16 create-buffer hpp-table
       rule>table hpp-rule hpp-table
       
      hpp-table è pronta per essere trasmessa alla lut inattiva.
       lut-data hpp-table  \ la LUT inattiva
                           \ viene scritta dal buffer hpp-table
       
      Le lut sono due e una sola alla volta può essere attiva, quella non attiva è disponibile per essere caricata con una nuova regola.
      Per cambiare la lut attiva, basta eseguire il comando switch-luts. Usualmente durante un esperimento questa parola CAMForth è utilizzata dopo aver caricato una nuova regola nella lut inattiva, rendendola quindi attiva e subito disponibile per compiere un update delle celle. La lut resa inattiva è disponibile per essere caricata con una ulteriore regola che si rendesse necessaria allo svolgimento dell'esperimento.
      In pratica, subito all'inizio bisogna caricare la lut inattiva con la prima regola, poi eseguire switch-luts, e quindi compiere il primo update.
      Il fatto che le lut siano due rende più veloce l'esecuzione, perché, mentre una esegue un update, l'altra può essere caricata con una nuova regola ed essere pronta per il prossimo update.

    6. Conteggio degli eventi

      Per ricavare più che un giudizio qualitativo sui risultati dell'esperimento, il programmatore della CAM 8 deve avere degli strumenti per compiere misurazioni sullo spazio delle celle. Nella CAM 8 il meccanismo di conteggio degli eventi rende possibile eseguire conteggi dei risultati di una specificata funzione booleana a due ingressi compiuta sul flusso dei bits delle celle e su un altro flusso di dati selezionato dall'utente.
      Questo meccanismo consiste, per ogni layer di ogni modulo, di un registro interno Event Counter non accessibile direttamente dall'utente, da un registro Event Source specificante cosa debba essere contato e dal registro Event Count Buffer dove può essere trasferito il contenuto dell'Event Conter e quindi letto dall'utente. Per compiere il trasferimento dal registro Event Counter all'Event Count Buffer occorre impostare a 1 il bit Event Count Transfer del registro Run Mode.
      Quindi è il solo Event Count Buffer ad essere letto: Event Count viene incrementato ogni volta che si verifica l'evento scelto tramite Event Source.
      Importante è sapere che il contenuto nell'Event Counter viene azzerato ogni volta che si compie una lettura tramite Event Count Buffer. Inoltre, scrivendo un valore in Event Count Buffer, questo sovrascriverà il registro Event Counter. In questa maniera si può azzerare, leggere o impostare il contatore di eventi.
      Vediamo ora precisamente cosa può essere contato.
      La funzione booleana a due ingressi può essere scelta tra tutte le possibili funzioni, mentre per gli ingressi abbiamo una situazione più rigida: un ingresso sono i siti, l'altro può venir scelto tra bit unglued, host, flywheel, lut.
      Il sottoregistro Event Source.Select sceglie tra questi quattro ingressi, mentre la parte restante Event Source.Map sceglie la funzione booleana da eseguire. Event Source è gestito da comandi CAMForth, quindi non si dovrà intervenire direttamente. Ad esempio per impostare il conteggio degli 0 contenuti in uscita dalla LUT, (si badi bene uscita) cioè i rimpiazzi ai vecchi siti, si dovrà scrivere:
      event-src lut map not map!
      oppure per fare un AND tra siti e dati host:
      event-src site map host map and map!
      Una volta terminato lo scan, per leggere il risultato del conteggio possiamo dare il comando
      run new-count
      che trasferisce il contenuto di Event Counter in Event Count Buffer e poi fa partire un nuovo scan. Se non vogliamo un nuovo scan, ma vogliamo solo leggere il conteggio o azzerarlo:
      run no-scan new-count
      Ora troviamo nell'Event Count Buffer un risultato che possiamo salvare scrivendolo in una predefinita variabile Forth:
      event read mia-variabile
      il quale riempe mia-variabile con il conteggio di tutti i 16 layers, in ordine broadside, come in figura 2.

      La grandezza di questa variabile dovrà essere esattamente uguale a log2( N ) + 1, dove N è il numero di siti aggiornati tramite lo scan eseguito. Una dimensione diversa porta a un errore.
      Esempio:

       new-experiment           \ inizializzazione
      
       8 by 8 sector            \ bidimensionale
       isolate-sectors          \ moduli isolati senza uso del glue
       step                     \ trasmetto la steplist
      
       64 create-buffer inizio  \ creo una variabile dove memorizzare
                                \ il pattern iniziale
      
       inizio                   \ buffer inizio
       b#                       \ imposto il modo binario
       1011100011010010100100100100100010111110000101010110001010110011
       reg!                     \ memorizzo in inizio il valore sopra
      
       7 create-buffer conteggio  \ preparo la variabile dove
                                  \ inserire il conteggio
      
       site-src host              \ nei siti vengono scritti
                                  \ i bits provenienti dall'host
      
       scan-io inizio             \ nel registro scan-io viene
                                  \ scritto il pattern
      
       site-src site              \ ora faccio in modo che uno scan
                                  \ non modifichi i siti
      
       run no-scan new-count      \ azzero il conteggio
      
       event-src site             \ conto il numero di 1 nei siti
       run free                   \ faccio partire uno scan
      
       run no-scan new-count      \ leggo il conteggio e azzero
       event read conteggio       \ ora il conteggio e' disponibile
                                  \ nella variabile conteggio
      
       step                       \ trasmetto la steplist
      
       

    7. Visualizzazione

      La CAM 8 può ovviamente utilizzare un monitor VGA esterno.
      Questo è un modo molto diretto per mostrare i risultati.
      Un altro modo per conoscere le elaborazioni è ricevere i risultati sull'host tramite buffers per mezzo dello stesso registro utilizzato per inizializzare lo spazio: il registro Scan I/O.
      Per scegliere cosa visualizzare sul video bisogna usare il registro Display Source, con un meccanismo molto simile al registro Event Source. Il sottoregistro Display Source.Select sceglie tra: site, host, flywheel, lut. Il sottoregistro Display Source.Map combina eventualmente i bits dei siti con uno degli ingressi sopra, con una funzione booleana a due ingressi.
      Il comando tipico per la visualizzazione dei siti è display site.

  3. CamAssembly

    L'utilizzatore raramente dovrà occuparsi direttamente di quello che succede nei registri, poiché con i normali comandi CAMForth visti finora possiamo compiere ogni tipo di esperimento.
    Certamente esisteranno dei casi o particolari richieste che i comandi standard non potranno compiere, essendo pensati per un funzionamento normale. Ma la CAM 8 è molto flessibile e manipolando direttamente i registri si possono compiere le operazioni più disparate.
    Le parole usate finora fanno uso delle istruzioni CAM 8. Queste consistono di quattro campi a 32 bits:

    L'opcode field contiene i flags per il controller CAM 8 e un numero a 5 bits che identifica un registro, register number, al quale l'istruzione verrà applicata. I flags sono utilizzati per assicurare che il resto della istruzione non sia caricata mentre la CAM 8 è in uno stato inappropriato. Questi sono consumati dal controller e non arrivano ai moduli CAM 8.
    Il buffer pointer è un indirizzo SPARC indicante la locazione nell'host del valore da caricare nel registro specificato nel campo opcode. Se il valore da caricare è sufficientemente piccolo, esso può essere memorizzato nel buffer pointer stesso; si può parlare in questo caso di immediate data. Il controller viene informato dell'arrivo di un dato immediato tramite il immediate data flag. Negli altri casi si parla di dati inline, memorizzati nella locazione puntata dal buffer pointer.
    Il campo register length indica l'entità del trasferimento dati al registro puntato da register number. Questo valore viene calcolato e impostato automaticamente dai comandi ad alto livello, i comandi CAMForth, e consumato dal controller, quindi non arriva ai moduli.
    Il campo link contiene l'indirizzo SPARC dell'opcode field della successiva istruzione nella steplist.
    I comandi CAMForth riempiono questi campi con valori appropriati e li spediscono al controller CAM 8 per la loro esecuzione.
    Per definire nuove parole CAMForth abbiamo usato il modo standard Forth, cioè i due punti, seguiti dai comandi e poi dal punto e virgola. Esiste un modo, che rende l'esecuzione più rapida, chiamato define-step. Questa è una parola CAMForth; operazionalmente è simile al metodo : ; con la particolarità di essere più agile nel cambiare i comportamenti di default di carico di registri e di sottoregistri, rendendo l'esecuzione dell'esperimento più rapida. Al suo interno possono trovare posto tutti i comandi CAMForth, escluso ovviamente le definizioni delle regole.


Ritorno al precedente