LudoProgrammazione 6502/6510 – Turmiche (#06)

Formato Pdf dell’articolo

Sorgente assembly

Oggi parleremo delle turmiche, una specie virtu-animale con strane abitudini. Sin dalla loro nascita posso muoversi liberamente e sanno benissimo come farlo ….”. Un documentario della national geographic avrebbe iniziato così la descrizione delle strane creature che voglio presentarvi oggi. Le turmiche furono presentate la prima volta da A.K.Dewdney in “Scientific American” alla fine del 1989 e, all’epoca, battezzò questi animaletti con il nome di turmiti.

Le Formiche di Turing

Le turmiche, o Formiche di Turing, sono dei particolari essere le cui modalità di movimento sono dettate dalla programmazione loro imposta sin dalla nascita. Questa programmazione nel movimento prevede uno “stato” interno che può cambiare in base alle condizioni dettate dalla loro “programmazione”, la possibilità di scegliere una direzione ed infine un nastro “infinito” che può essere letto e scritto, proprio come in una macchina di Turing.

La macchina di Turing è la macchina che Alan Turing ipotizzò come modello di calcolatore programmabile. Questa macchina, detta brevemente, è formata da una testina di lettura/scrittura (simile a quella dei mangianastri) che agisce su di un nastro (virtualmente infinito) che può muoversi avanti e indietro e sul quale la testina potrà leggere o scrivere alcuni simboli. Ebbene una macchina siffatta ha una potenza computazionale insuperabile, se le viene fornito sufficiente tempo (e la giusta programmazione) può risolvere qualsiasi problema.
Per programmare la macchina di Turing sarà sufficiente una tabellina a doppia entrata, nella quale vi saranno tante righe quanti sono gli stati previsti dal programma e tante colonne quanti sono i simboli che si vogliono gestire. In ogni cella della tabellina ci saranno scritte 3 informazioni fondamentali:

  • Quale simbolo scrivere sul nastro

  • In quale stato la macchina si deve portare

  • La direzione in cui si deve spostare la testina rispetto al nastro, destra, sinistra o in alternativa stare ferma.

Ogniqualvolta la testina legge un simbolo, la macchina di Turing controllerà nella tabellina la cella corrispondente allo stato interno che avrà in quel momento incrociato con il simbolo letto, quindi cambierà il proprio stato, scriverà un simbolo ed infine si muoverà in base alle informazioni contenute nella cella identificata.
Nella cella ci potrà essere anche un valore particolare che indica alla macchina che il lavoro è terminato.

Nell’immagine vi è, nella parte alta, un esempio di tabellina per la programmazione della macchina di Turing che gestisce 2 simboli (0/1) con tre stati (A/B/C). In questo esempio la macchina è programmata per invertire i valori letti sul nastro, finché non incontrano 2 simboli ‘0’ consecutivi, in tal caso la macchina ritiene il proprio compito terminato. Si suppone che lo stato iniziale della macchina sia A e che sul nastro sia scritto inizialmente la serie di simboli 10100.
Nella parte bassa dell’immagine vengono mostrate le varie fase di svolgimento del lavoro programmato evidenziando la posizione della testina e lo stato della macchina.

Movimento delle turmiche

Le turmiche sostanzialmente lavorano come una macchina di Turing, con la differenza che invece di un nastro ci sarà un foglio squadrato (infinito) in cui la turmica (con la testina di lettura e scrittura) si potrà muovere, in tutte e 4 le direzioni, lasciando traccia del proprio passaggio.
Nel nostro caso specifico la nostra turmica potrà tingere di nero o ripulire (sbiancare) l‘area in cui si trova, quindi vien da se che verranno gestiti 2 simboli (0 = nero e 1= bianco). Sempre nell’esempio presentato programmeremo la turmica in maniera molto semplice, in parole povere se si troverà sopra una cella nera la farà diventare bianca e si sposterà a sinistra, mentre se la cella fosse bianca, la turmica da dipingerà di nero e si sposterà a destra. Con queste due semplici regole ce la caviamo con un unico stato. Naturalmente L’utilizzo della terminologia “destra” e “sinistra” implica contemporaneamente un cambio di direzione.

A dispetto dell’estrema semplicità della tabellina di programmazione il percorso della nostra turmica risulterà assai caotico inizialmente, finché, ad un certo punto, si stabilizzerà e continuerà in una direzione predefinita (se non troverà ostacoli) ripetendo ciclicamente le stesse mosse.

Il mondo grafico della turmica

Alla turmica piace camminare nella pagina grafica del nostro C64, ma non disdegnerebbe altri sistemi. Per attivare la modalità grafica ad alta risoluzione del commodore 64 è sufficiente modificare l’indirizzo \$D011, il quale contiene il valore di un registro del VIC-II i cui 8 bits si occupano di altrettanti aspetti di controllo, in particolare il bit 5, se posto a 1, attiva la modalità in alta risoluzione:

VICREG  = \$D000
...
EnableBitMap
        lda VICREG+17         ; \$D011
        ora #\$20              ; set bit 5
        sta VICREG+17
        rts

Bisogna inoltre indicare al VIC-II dove risiederanno le informazioni relative a ciò che va “disegnato” sullo schermo, quindi imposteremo il bit 3 di un altro registro del VIC, il \$D018, in questa maniera indicheremo che la mappa grafica inizierà da \$2000:

Enable2000
       lda VICREG+24         ; \$D018
       ora #\$08              ; set bit 3
       sta VICREG+24
       rts

In questa modalità grafica abbiamo a disposizione una griglia di 320×200 pixels. Se dividessimo idealmente questa griglia in blocchetti di 8×8 pixels avremmo una griglia di 40×25 blocchetti, che è esattamente l’ampiezza del nostro schermo a caratteri (ogni carattere è 8×8 pixels) all’accensione del computer. Ho fatto questo accostamento in quanto l’area di memoria che prima era dedicata alla visualizzazione dei caratteri (quella che parte da \$0400), ora che lavoriamo in alta risoluzione, conterrà la definizione dei colori che verranno usati in questa modalità.
Per ogni “blocchetto” 8×8 è possibile definire un colore di sfondo e uno di tracciamento, quindi alla fin fine sarà possibile utilizzare tutti e 16 i colori a nostra disposizione, 2 alla volta limitatamente alle aree 8×8. Il colore di ogni blocchetto è definito da un byte a partire da $0400, il valore nei 4 bit alti indicheranno quale sarà il colore (da 0 a 15) di tracciamento nella corrispettiva area in alta risoluzione mentre il nibble basso indicherà il colore di sfondo.
La turmica lavora esclusivamente in due colori, quindi la routine SetAllAreaColor passerà in rassegna i mille bytes a partire da \$0400 e assegnerà a tutti il medesimo valore.

Come plottare in alta risoluzione

Sappiamo che abbiamo a disposizione un piano di 320×200 pixels, ogni pixel può essere accesso o spento. Ora un piano del genere si presta benissimo all’identificazione di ogni singolo pixel tramite l’utilizzo delle onnipresenti coordinate cartesiane x e y, sfortunatamente per noi nel C64 questa cosa non è proprio così lineare. Se volessimo accendere il pixel identificato dalle coordinate x e y (l’angolo in alto a sinistra corrisponde all’origine degli assi) dobbiamo eseguire tutta una serie di calcoli che andranno ad identificare il byte di memoria video da modificare e come modificarlo.

In questa modalità abbiamo a disposizione 320×200=64000 pixels o, in altre parole, 64000 bit che possiamo porre a 0 (spento) o a 1 (acceso). Le cose “strane” che dobbiamo tenere presente sono:

  1. possiamo modificare sempre 8 bit alla volta, cioè un byte alla volta;

  2. la disposizione dei bytes al punto 1 non è lineare, infatti per identificare il byte da modificare dovremmo seguire le regole riportate qui sotto.

Immaginiamo lo schermo come tanti bit (inizialmente spenti) che a partire dall’angolo in alto a sinistra riempiono tutto lo spazio (con righe di bit da 320) sino a giungere all’angolo in basso a destra. Dobbiamo innanzitutto immaginare ogni riga sia organizzata in gruppi di 8, quindi per ogni riga avremo 40 gruppi da 8 bit. Questi gruppi sono i bytes da modificare per accendere o spegnere i vari pixels ad essi associati, nel nostro caso essi partiranno dall’indirizzo \$2000. L’inghippo è questi bytes sono organizzati in una sorta di macro righe composte da 8 linee di pixels (secondo lo schema in figura), facendo in modo, che per esempio, il 7 bytes successivi (a partire da \$2001) corrisponda ai gruppi di 8 pixels al di sotto del byte \$2000 (e non quelli a fianco come ci si potrebbe aspettare).
Alla fin fine, avendo a disposizione le coordinate x,y del pixel su cui lavorare, dovremmo eseguire i seguenti calcoli per identificare l’indirizzo del byte da modificare: \$2000 + INT(Y/8) * 320 + Y AND 7 + INT(X/8) * 8.
Una volta identificato il byte lo dovremo “mascherare” opportunamente con un AND o con un ORA per accendere o spegnere il pixel che ci interessa. Per prima cosa identifichiamo il numero del bit che ci interessa con l’operazione BIT = 7 – (X AND 7) , quindi per trovare la maschera da usare in OR eleviano 2^BIT, mentre se vogliamo spegnere il pixel dovremo invertire tutti i bit della maschera ed eseguire un AND.
La routine che si occuoa di accendere o spegnere un pixel è PlotXY, la quale utilizzerà una label di comodo (PosR) per indicare se si vuole accendere, spegnere o solamente “leggere” il pixel alle coordinate indicate (PosX, PosY) e sempre sulla stessa label verrà immagazzinato il valore del pixel prima dell’eventuale modifica.

Nuovi percorsi

La turmica è un animaletto affascinante, con poche regole riesce comunque a districarsi da quello che sembrerebbe un moto casuale. Nel programma proposto il “mondo” è aperto, quindi se la turmaica esce da un lato, rientra immediatamente da quello opposto, creando delle trame molto interessanti. E se le turmiche fossero 2 o più con una posizione iniziale casuale ? E se le regole implicassero oltre che destra e sinistra anche avanti ed indietro, aggiungendo quindi un nuovo stato di programmazione della turmica ?

Lascio a voi pazienti lettori l’approfondimento.

Emanuele Bonin

Emanuele.Bonin71@gmail.com

Bibliografia: “Le Scienze” N. 254 Novembre 1989

Have your say