15 ott 2020

STM8-BASIC: il più piccolo computer con interprete basic (4/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 ☑

Algoritmo

Iniziamo ora a pensare come calcolare le due informazioni che ci servono per calcolare se la cellula sarà viva o morta nella prossima generazione:
  1. stato della cellula nella generazione corrente
  2. somma S delle cellule vive intorno ad essa

13 ott 2020

STM8-BASIC: il più piccolo computer con interprete basic (3/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

 Allocare la nuova generazione

abbiamo visto nel precedente post la mappa di memoria in cui ospitare la generazione corrente delle nostre cellule.

Per ospitare la generazione successiva, utilizziamo gli 8 bytes immediatamente successivi della memoria.


Il programma

Vediamo quindi come passare dalla generazione corrente a quella futura:
dovremo fare una scansione di tutte le cellule della generazione corrente, per ogni cellula dovremo sapere se è viva o morta, e dovremo contare il numero di cellule vive intorno (chiamiamo questa somma S).
Con queste due informazioni stabiliremo lo stato della cellula nella prossima generazione:
  • cellula attualmente morta
    • se S=3, nella prossima generazione la cellula sarà viva
  • cellula attualmente viva:
    • se S=3 oppure S=2, nella prossima generazione la cellula sarà viva
  • in tutti gli altri casi, nella prossima generazione la cellula sarà morta.
Per implementare questo algoritmo dovremo effettuare una scansione dei byte della generazione corrente, per ogni byte effettuare una scansione dei bit (ovvero delle cellule) - calcolare lo stato del bit per la prossima generazione ed infine memorizzare lo stato della nuova generazione nell'area di memoria preposta.

La logica di massima del nostro programma BASIC sarà quindi:
  • (1) eseguiamo un ciclo sui byte della generazione corrente (dall'indirizzo $0201 a $0208) 
    • per ognuno di questi byte eseguiamo un ciclo sui bit (da 0 a 7) - chiamiamo R il byte corrente
      • per ogni bit, calcoliamo la somma delle cellule vive intorno ad esso
      • stabiliamo quindi se il corrispondente bit della prossima generazione sarà 1 o 0 (cellula viva o meno)
    • al termine del ciclo sui bit avremo calcolato un intero byte della prossima generazione, chiamiamo T questo byte
    • salviamo il byte T in un indirizzo 9 locazioni più avanti rispetto al corrispondente byte R (es: da $0203 a $0203+9 = $020C)
  • al termine del ciclo sui byte, avremo le locazioni $020A-$0211 riempite con la nuova generazione
  • (2) copiamo la nuova generazione dalle locazioni [$020A-$0211] alle locazioni [$0201-$0208]
  • (3) copiamo il primo byte della nuova generazione da $020A a $0209
  • (4) copiamo l'ultimo byte della nuova generazione da $0211 a $0200
  • ricominciamo da capo.
Ho evidenziato in colore blu le operazioni eseguite per ogni byte della generazione corrente, ed in colore rosso le operazioni eseguite per ogni bit del byte corrente.

Per ogni byte preso in esame (ricordo che per calcolare la somma delle cellule vive dovrò tenere conto anche del byte precedente e del byte successivo) nella generazione corrente il programma calcolerà il corrispondente byte della generazione futura e lo salverà nell'opportuno indirizzo (9 locazioni più "in basso" nella mappa della memoria).


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".