Articolo pubblicato sul n. 41 di MCmicrocomputer (Edizioni Technimedia Srl - Roma) nel maggio 1985

MCmicrocomputer


Commodore 64
Gestione delle interruzioni

(seconda parte)

di Andrea de Prisco

Grazie alla gestione delle interruzioni da parte del video interface chip 6567, questo mese realizzeremo per il nostro Commodore 64 finestre testo/grafica hgr e la visualizzazione contemporanea di 16 sprite. Copertina del numero di MCmicrocomputer contenente l'articolo

 

 Gli Interrupt del VIC 6567

 Dicevamo lo scorso mese che ogni 60-esimo di secondo l'integrato di Input/Output Cia 6526, manda un segnale di interruzione al microprocessore 6510. Se l'interruzione è accolta, questi molla tutto ed esegue il programma di manipolazione delle interruzioni. Con le applicazioni Orologio, Sveglia e Caratteri Flashing abbiamo anche visto come sia possibile sfruttare gli interrupt per gestire una mini programmazione parallela.

Dando uno sguardo un po' più attento ai collegamenti tra i vari Chip del 64 ci si può rendere conto che le interruzioni possono giungere anche da altrove. Innanzitutto dall'esterno della macchina: il contatto IRQ del microprocessore è riportato anche sulla porta espansioni del 64. In questo modo è possibile che periferiche esterne diano comandi di interruzione al microprocessore, per eseguire particolari operazioni. Non affronteremo da questo punto di vista il problema: ci occuperemo delle interruzioni da parte del video interface chip 6567. Anche quest'ultimo ha, per così dire, un filo diretto col 6510; quando "lo ritiene opportuno", può mandare la sua brava interruzione a papà. Tanto per cambiare, per attivare gli interrupt del 6567 è necessario agire sui suoi registri interni, listati bit per bit a pagina __.

Il Raster Register

Prima di entrare nel vivo del discorso, ci sarebbe da parlare un po' del Raster Regiter o registro di quadro. E' formato da 9 bit e quindi è locato in due registri del video interface chip. Gli 8 bit di ordine più basso si trovano alla locazione 53266, il bit più significativo è locato nel registro 53265, sempre nella posizione più alta (la 7). Svolge una duplice funzione, a seconda che sia usato in lettura (PEEK) o in scrittura (POKE). Nel primo caso restituisce l'attuale posizione del "pennello elettronico" del vostro TV: come noto, l'immagine video è formata da un insieme di linee orizzontali che, opportunamente costruite da un fascio di elettroni all'interno del cinescopio, formano l'intera schermata. Indipendentemente da applicazioni computerecce, questo avviene anche mentre si segue il telegiornale. E' l'occhio che con la sua inerzia non si accorge di quanto effettivamente accade illudendosi di avere davanti una immagine intera. Apparentemente, interrogare il raster register non sembrerebbe molto utile: specialmente da Basic, che con la sua esasperante lentezza, prendere una qualsiasi decisione a un determinato valore del quadro, diventa praticamente impossibile. Da linguaggio macchina la cosa diventa più interessante: è possibile realizzare un ciclo di attesa finché il registro di quadro non assuma un particolare valore. La domanda però è sempre la stessa: per quale motivo si dovrebbe sfruttare l'informazione data dal raster register?

 Non è difficile rispondere. Per cominciare, tra tutti i valori che può assumere il registro di quadro (con 9 bit da 0 a 511), solo tra 51 e 250 il pennello sta effettivamente mostrando qualcosa sul video. Per tutti gli altri valori il video interface chip o visualizza il bordo o aspetta semplicemente di iniziare un nuovo quadro. Interrogando continuamente il raster register possiamo ad esempio modificare qualcosa sul video mentre il pennello è fuori campo (parlando a rallenty, mentre non visualizza nulla).

 Per capire meglio, sfruttiamo un'altra delle possibilità offerte dal 6567: lo scrolling fine (di un solo pixel alla volta) nelle quattro direzioni.

Viene usato per far entrare "in campo" lentamente nuove informazioni mentre lentamente vecchie informazioni spariscono dalla parte opposta. Il programma Titolatrice listato in queste pagine e già visto, ma non commantato, sul n. 30 di MC, ne è un esempio.

Dando Run vengono richieste le linee da mostrare (max 100). Si dà il via battendo return all'ultima richiesta di input. Il Video Interface Chip svolge gran parte del lavoro, ma non tutto. Per implementere lo scrolling fine bisogna scrivere un programma opportuno, preferibilmente in linguaggio macchina. La prima cosa da fare, è passare al modo 38 colonne per lo scrolling orizzontale o al modo 24 righe se si desidera quello verticale. Ciò per far posto alle nuove informazioni prima dello scrolling vero e proprio. Per il movimento verticale verso l'alto, i passi sono:

1)  Passare al modo 24 righe

2)  Impostare il registro di scrolling verticale al valore massimo (tutto lo schermo si abbassa di 8 pixel, nascondendo sotto il bordo inferiore la 25-sima riga)

3)  Riempire la riga 25 con le informazioni da mostrare

4)  Variare lentamente il registro di scrolling in modo da far apparire la riga 25 e far scomparire la prima

5)  Con una routine in linguaggio macchina per muovere il contenuto dello schermo di una posizione verso l'alto

6)  Ritornare al passo 2

 

Per il movimento orizzontale l'algoritmo è sostanzialmente lo stesso: uniche ovvie differenze sono:

a)  il modo da usare è quello a 38 colonne.

b)  si agisce sul registro di scrolling orizzontale.

c)  i nuovi dati andranno posizionati sull'estrema colonna di destra o di sinistra a seconda della direzione dello scroll.

 

Le POKE da usare sono:

   POKE 53270,PEEK(53270)AND 247 seleziona il modo 38 colonne.

   POKE 53270,PEEK(53270) OR 8   ritorna al modo standard 40 colonne.

   POKE 53265,PEEK(53265)AND 247 seleziona il modo 24 righe.

   POKE 53265,PEEK(53265) OR 8   ritorna al modo 25 righe.

 

Con X e Y compresi tra 0 e 7 tramite le due seguenti poke, si impostano i registri di scrolling orizzontale e verticale:

   POKE 53270,(PEEK(53270) AND 248) OR X - orizzontale

   POKE 53265,(PEEK(53265) AND 248) OR Y - verticale.

 

   Fin qui sembrerebbe tutto normale. Il problema più grave è dato dal fatto che, nell'algoritmo sopra visto, il passo 5 e il passo 2 (ad ogni iterazione) dovrebbero avvenire contemporaneamente, pena un fastidioso sfarfallio del quadro durante la costruzione dell'immagine da parte del 6567. Considerato poi che "contemporaneamente" (questa volta nel vero senso della parola) per il 64 è impossibile, l'unica cosa da fare è eseguire sequenzialmente le due operazioni quando il 6567 non visualizza nulla, in altre parole, quando il raster register ha superato il valore di 250. Tanto per avere un'idea di cosa voglia dire non aspettare il momento opportuno per eseguire i due punti di cui sopra, digitate il programma Scroll. Vedrete il quadro sfarfallare ad ogni iterazione. Il programma Titolatrice, effettua la trasposizione di tutto lo schermo e resetta il registro di scroll quando il registro di quadro ha superato 250. La realizzazione di questo sincronismo è affidata a una routine in linguaggio macchina, come si può notare dalle linee di DATA presenti nel listato.  

   Le Interruzioni

Per generare veri e propri interrupt da parte del 6567, si agisce sui registri 26 e 27, locati rispettivamente a 53273 e 53274. Il video interface chip può mandare segnali di interruzione al verificarsi di uno dei seguenti 4 eventi: è avvenuta una collisione tra due sprite, tra uno sprite e il testo, è stata appoggiata la penna ottica sullo schermo tv, il registro di quadro ha raggiunto un determinato valore. Per selezionare tra questi, al verificarsi di quale evento bisogna avvertire il 6510 con una interruzione, si agisce sul regitro locato a 53274, detto appunto di abilitazione dell'interruzione. Settando il bit 0 avremo un interrupt sincronizzato con una data posizione del quadro, settando il bit 1 l'interruzione si verificherà a ogni collisione sprite-dati, col bit 2 ad ogni collisione sprite-sprite, setteremo il bit 3 se interressati a interrupt da penna ottica. Sarà opportuno disabilitare le interruzioni del 6526 se vogliamo abilitare quelle del 6567. La poke che ci permette questo è:

   POKE 56334, PEEK(56334) AND 254

La possibilità degli interrupt causati da collisioni da sprite, può essere usata per i giochi in linguaggio macchina, ad esempio per incrementare il punteggio ad ogni navicella spaziale abbattuta. Si potrebbe inserire la routine che conteggia i punti a capo del programma di manipolazione delle interruzioni, come già visto per i programmi "Orologio", "Sveglia" e "Caratteri Flashing". Se la navicella è abbattuta, il microprocessore, molla tutto (come al solito) e incrementa il punteggio.

 Per provocare una interruzione ad un dato valore del quadro, comunicheremo al 6567 tale quantità. Per fare questo si usa il raster register in scrittura: una POKE in tale registro, viene memorizzata all'interno del video interface chip per provocare l'interruzione ogni volta che il quadro eguaglia tale valore. Anche in questo caso, occorre ricordare che il raster register è formato d 9 bit e di conseguenza, locato in due registri del 6567. Si tratterà sempre di eseguire due PEEK o due POKE.

 Un'applicazione abbastanza semplice di tale procedimento, potrebbe essere la visualizzazione di mezza pagina video di un colore e la rimanente di un altro. Colore di sfondo, si intende. L'informazione del colore di sfondo, come è noto è mantenuta nella locazione 53281. Se cambiamo tale valore, lo schermo cambia tinta. L'idea è quella di passare da un colore a un altro, ripetutamente, a determinati valori del quadro. Diciamo che si parte col colore di sfondo blu. Quando il 6567 ha disegnato metà schermo, cambiamo il colore si sfondo (agendo in 53281) in rosso. Terminato il quadro, si ripassa al colore blu, per poi riattivare il rosso a metà schermo. Tutto questo venticinque volte al secondo, la frequenza con cui il video interface chip disegna il quadro. I passi veri e propri sono:

   1) Disabilitare le interruzioni del 6522

   2) Cambiare il contenuto di $0314 e $0315 (puntatore alla routine di manipoazione dell'interruzione).

   3) Scrivere in Ram la nuova routine di manipolazione delle interruzioni.

   4) impostare in registro di quadro al valore di 150 (approx. mezzo schermo).

   5) abilitare le interruzioni del 6567, settando il bit 0 del registro 53274.  

La nuova routine di manipolazione dell'interruzioni, sarà chiamata, per la prima volta, appena il video interface chip ha completato il primo semi schermo (che ha colorato in blu). Questa routine, sarà approssimativamente fatta così:

   1) se il  colore di schermo è rosso vai a 5 (è stata già completata la schermata)

   2) si passa al colore di schermo rosso

   3) si imposta il raster register al valore di 251, per provocare una nuova interruzione al termine del quadro.

   4) salta a $EA31 per completare il programma di manipolazione dell'interruzioni (scansione della tastiera, incremento di TI$, etc)

   5) si passa al colore di schermo blu

   6) si imposta il raster register al valore di 150, per provocare una nuova interruzione a metà quadro.

   7) salta a $EA31 per completare il programma di manipolazione dell'interruzioni (scansione della tastiera, incremento di TI$, etc)

Le interruzioni del 6567, funzionano in un modo un po' strano: ogni volta che il video interface chip manda un interrupt, vuole conferma di avvenuta ricezione da parte del 6510. Se ciò non accade, non verranno mandati altri segnali di interrupt. La routine sopra schematizzata, deve essere arricchita dal punto 0, da eseguire prima di ogni altro test o operazione. Il passo zero, per l'appunto, manda conferma al 6567, settando opportunamente un bit nel registro 53273. Il bit da settare, deve essere lo stesso dell'interruzione scelta in 53274. Bit 0 nel caso nostro:

   0) setta il bit 0 di 53273, per confermare l'avvenuta interruzione.

   è il passo da aggiungere all'algoritmo sopra mostrato.

Non useremo gli interrupt da 6567 per visualizzare (inutilmente) schermate bicolore: ci occuperemo di qualcosa di più costruttivo: miscelare i modi testo e bit-map, e mostrare contemporaneamente 16 sprite.

L'algoritmo per visualizzare mezza pagina grafica e mezza pagina testo, è sostanzialmente lo stesso visto per bi-colorare lo schermo. L'unica differenza sta nel passaggio di "modo" in luogo del semplice cambiamento di colore dei punti 2 e 5. Se modifichiamo i suddetti passi nel seguente modo:

   2) si passa al modo bit-map

   5) si passa al modo testo

avremo mezza schermata in alta risoluzione e mezza schermata di testo: molto utile per mostrare sia output grafici che normalissimi caratteri (es. didascalie)

La routine Hgr/Irq funziona come la grafica hgr, vista sul n.31 di MC, ma visualizza contemporaneamente nei due modi. La prima linea serve per specificare l'altezza del "Taglio". H=0.5 mostrerà mezzo schermo testo e mezzo bit-map. H=0, tutto bit-map; H=0.3, il 30% di testo e il 70% di grafica. Non ha molto senso H=1, che come è facile intuire mostra tutto testo. Dopo il Run, per plottare punti sullo schermo, si assegnano le coordinate alle variabili X e Y e esegue un GOSUB 30.

   16 Sprite

Sfrutteremo ora gli interrupt del 6567 per visualizzare contemporaneamente 16 sprite. Il programma è listato a pag. XXX e non è altro che una routine di manipolazione delle interruzioni che gestisce tale funzione. Per poter sfruttare 16 sprite, è opportuno avere le idee ben chiare sull'argomento sprite-standard, ampiamente descritto sul manuale della macchina. Come sappiamo il video interface chip può visualizzarne, così com'è, solo 8. L'idea è quella di far riprodurre al 6567 una schermata con una prima serie di 8 sprite, la successiva visualizzandone altri 8, poi nuovamente gli 8 di partenza e così via, ripetendo sempre lo stesso ciclo.

Useremo l'area di memoria compresa tra $D000 (decimale 49152) e $D070 (decimale 49264) per costruire due serie di pseudo-registri del 6567.

Nella prima serie di pseudo-registri (da 49152 a 49198) inseriremo i dati relativi alla prima serie di 8 sprite (posizione, espansione, colore, ecc.); nella seconda serie di registri (da 49216 a 49263) i dati relativi alla seconda serie di sprite.

 Proprio come se avessimo a che fare con i veri e propri registri del 6567, mappati a partire da 53248: le prime due locazioni contengono le coordinate (x e y) del primo sprite, le seconde, del secondo sprite, ecc.

 Potremo anche interrogare gli pseudo-registri per le collisioni, tenendo però presente che le due serie sono distinte: saranno segnalate le collisioni solo tra sprite della stessa serie. Nelle locazioni comprese tra 49200 e 49215, inseriremo i puntatori alla descrizione dei nostri 16 sprite, allo stesso modo dei byte 2040-2047, usati nella gestione normale.

 Facciamo un esempio: vogliamo far apparire lo sprite 14 nelle coordinate (100,50) dello schermo. Lo sprite 14 corrisponde allo sprite 6 della seconda serie (14-8=6). Dopo aver inserito in memoria la forma dello sprite, e nel byte 49213 (il 14-esimo puntatore) la posizione della sua descrizione (contando come sempre a blocchi da 64 celle), inseriremo le sue coordinate nei registri 12 e 13 della seconda serie di pseudo registri.  

Quindi l'istruzione sarà:

   POKE 49216 + 12, 100

   POKE 49216 + 13, 50

Per abilitare la visualizzazione di uno sprite si usa (come sempre) il registro 21: 

   POKE 49216 + 21, PEEK(49216+21) OR 2^6

 Se avessimo visualizzato uno sprite di ordine inferiore a 8, avremmo usato la serie di pseudoregistri mappati a partire da 49152.

 Il programma che visualizza 16 sprite è assai semplice. La prima operazione che compie è di abilitare le interruzioni da parte del 6567 ogni volta che il raster register raggiunge il valore di 251, ovvero ad ogni completamento di schermo. Ad ogni interruzione, il microprocessore non la altro che riversare, alternativamente, le serie di pseudo registri nei registri veri e propri del video interface chip. Completa questa operazione prima che il 6567 inizi una nuova schermata. L'effetto finale è appunto quello di visualizzare una schermata con i primi 8 sprite, la successiva con gli altri 8, poi di nuovo gli 8 iniziali, ciclicamente. Il risultato è più che soddisfacente: l'occhio umano, sempre per la sua inerzia, vede i 16 gli sprite simultaneamente, sebbene leggermente "sfarfallosi", ma non 8 alla volta come effettivamente accade. Come dire: il trucco c'è, ma (quasi) non si vede !


Impaginato originale...


Clicca per ingrandire... Clicca per ingrandire...
Clicca per ingrandire... Clicca per ingrandire...
Clicca per ingrandire...  

Articolo pubblicato su www.digiTANTO.it - per ulteriori informazioni clicca qui