11 ott 2020

STM8-BASIC: il più piccolo computer con interprete basic (2/4)

Nota: questo post fa parte di un articolo suddiviso in 4 sezioni:

  1. di 4 ☑
  2. di 4 ☑
  3. di 4
  4. di 4

Cosa?

Abbiamo il nostro computer, collegato tramite terminale seriale, pronto ad eseguire i nostri programmi BASIC. 
Bene, cosa vogliamo far eseguire al nostro interprete?
In onore di John Conway, scomparso ad aprile di questo sciagurato 2020, ritengo opportuno programmare una variante della simulazione LIFE in BASIC.

Cosa dovremo fare, quindi? Elenchiamo i punti principali:

  1. stabilire come memorizzare la griglia che rappresenta la generazione corrente
  2. definire un algoritmo che conti le cellule vive intorno ad una generica cella della griglia
  3. calcolare la generazione successiva e memorizzarla


Date le limitazioni dell'interprete (abbiamo a disposizione una manciata di variabili numeriche, 256 byte di RAM e 630 byte per il programma) avremo una semplice griglia di 8x8 celle, ognuna delle quali potrà essere "viva" o "morta".

Una variante...

La griglia può essere allocata in 8 byte di RAM. Ogni byte ospiterà una riga della griglia, dove il simbolo 1 rappresenterà una cellula "viva" e lo 0 una cellula "morta".


Nella figura vediamo un esempio dei casi che dovremo gestire: durante il calcolo della nuova generazione, per stabilire il valore del bit con indice 3 del 3° byte, dovremo contare il numero di cellule "vive" presenti intorno al nostro bit.
Segnatamente, dovremo contare gli "1" presenti :
  • nel secondo byte (alle posizioni 2, 3 e 4)
  • nel terzo byte (alle posizioni 2 e 4)
  • nel quarto byte (alle posizioni 2, 3 e 4)
Per rendere più interessante la simulazione, introduciamo una variante: consideriamo la griglia finita ma non limitata. Consideriamo cioè una griglia che si ripete infinitamente: sopra, sotto, a destra ed a sinistra.
Con questa variante, la somma delle cellule vicine deve essere opportunamente adeguata.

Esempio: calcolo per cella sul bordo laterale

Vediamo il caso di una cella sul bordo destro della griglia.


Nella figura presentata, proviamo a fare il calcolo per il bit in posizione 0 del terzo byte. Dovremo considerare, oltre alle posizioni 0 ed 1 del 2° e del 4° byte ed alla posizione 1 del 3°, anche le posizioni 7 del 1°, 2° e 3° byte.

Esempio: calcolo per cella sul bordo inferiore

In questo caso consideriamo una cella appartenente all'ottavo byte, alla posizione 2.


Naturalmente considereremo le posizioni 1,2 e 3 del 7° byte, le posizioni 1 e 3 dell'8° byte.
Poiché la griglia è illimitata verticalmente, dovremo considerare anche le celle appartenenti al 1° byte.

Esempio: calcolo per cella in un angolo

Nel caso di una cella posizionata in un angolo, vediamo in figura la posizione 7 del primo byte.


Naturalmente la somma delle cellule "vive" conterà la posizione 6 del 1° byte e le posizioni 6 e 7 del 2° byte.
Per la non limitatezza della griglia, dovremo contare anche la posizione 0 del 1° e 2° byte.
Il calcolo deve poi tenere conto dei "vicini" che appartengono anche all'8° byte, alle posizioni 0, 6 e 7

Come?

Una prima soluzione per aggirare la limitatezza verticale della griglia è di utilizzare due byte, in testa ed in coda alla griglia; nel byte in testa verrà replicato l'ottavo byte della griglia, nel byte in coda verrà replicato il contenuto del 1° byte.


Usiamo gli indirizzi da $0201 a $0208 per la griglia della generazione corrente (nell'esempio in figura ho inserito un glider).
Copiamo l'ottavo byte della griglia (all'indirizzo $0208) nel byte all'indirizzo $0200.
Copiamo anche il primo byte della griglia (all'indirizzo $0201) nel byte all'indirizzo $0209.  


Questa è la mappa della RAM che ospita la generazione corrente della griglia, con il primo ed ultimo byte replicati in testa ed in coda.

Per ora ci fermiamo qui, vedremo in seguito come effettuare il calcolo della generazione successiva (e in quale zona di memoria depositarla).


Nessun commento:

Posta un commento