Una cosa che mi ha fatto perdere tempo, a parte la modifica alla logica
della porta SPI, e` stato il fatto che la seriale hardware funzionasse
in modo discontinuo. Alla fine mi sono accorto di aver sottovalutato un
particolare: quando accedo ad una porta I/O qualunque, anche se ha A0
alto, l'ULA mi puo` sospendere il clock se la parte alta dell'indirizzo
cade nel range $40 - $7F, perche` crede che voglia accedere alla memoria
contesa.
Ma porca...
Inutile sottolineare quanto male possa funzionare una seriale veloce
alla quale viene sospeso il clock ogni tanto :-)
Quando ho scoperto il problema ho ovviato in modo piuttosto banale:
invece di IN A,(PORT), faccio
LD BC,PORT
IN A,(C)
In questo modo la parte alta e` 0 e tutto ha subito funzionato
perfettamente. Dopo questa premessa, ecco il punto: le INIR (oppure le
catene di INI) purtroppo sono soggette al problema, perche` la parte
alta in questo caso e` B che e` il contatore!! Probabilmente
funzionerebbe meglio mettendo 8 sequenze da 16 INI in cui B parta da $40
invece di 0 ($100)... sarebbe piu` comodo usare la porzione superiore
($FF - $80), che e` larga il doppio, ma poi diventa piu` difficile il
test JRNZ. Mah.
Non partirei da $40 altrimenti avresti il problema...
Scriverei del codice del tipo:
LD B,15
LOOP:
SET 4,B
OUTI
...
(17 volte)
...
OUTI
JR NZ,LOOP
OUTI
L'istruzione SET non fa altro che aggiungere 16 a B. Le 17 istruzioni
OUTI decrementano B di 16. Quindi, il valore di B all'inizio di
ogni loop e` 15, 14, 13 e cosi` via fino ad 1. Quindi il loop e`
eseguito 15 volte, per un totale di 15*17=255 istruzioni OUTI. Rimane
un'ultimo OUTI da eseguire per arrivare a 256.
E` leggermente piu` lento del codice normale per via dell'istruzione SET
ma la velocita` mi sembra comunque decorosa.