Computer / Programmazione / Z80 · 7 febbraio 2019 3

LM80C: test del PIO e della RAM

Arrivato ad un punto in cui non potevo più fare ulteriori test con quello che avevo aggiunto al mio piccolo computer, ho deciso di provare ad aggiungere un chip di SRAM da usare per memorizzare dei dati e lo stack, che è necessario per poter usare le chiamate alle sub-routine nei miei programmi in assembly. Così ho preso un chip HM62256 di Hitachi ed ho fatto alcune prove.

L’HM62256 è una RAM statica di 256 Kbit (32 K x 8 bit) prodotta da Hitachi. Statica significa che non necessita di essere aggiornata (in inglese, il “refresh”) per mantenere i dati in essa memorizzata: per confronto, le DRAM (Dynamic RAM) necessitano di continui cicli di rinfresco (accessi in lettura) altrimenti esse perdono i dati memorizzati. La piedinatura è identica a quella delle EEPROM perciò possiamo facilmente collegarla, con l’unica differenza data dal piedino /WE: dato che è una RAM, è scrivibile per cui dobbiamo collegare questo pin all’omonimo piedino /WR della CPU.

62256 pinout

Piedinatura dell’integrato 62256

C’è sono un piccolo problema. Collegandola allo steso bus indirizzi, la RAM interferirà con la ROM, e viceversa, perciò dobbiamo pensare ad un meccanismo che permetta alla CPU di selezionare il chip corretto da cui leggere o dove andare a scrivere. Questo può essere ottenuto usando un 74139, un doppio decoder/multiplexer di tipo 2 a 4. Questo chip può selezionare 1 fra 4 uscite usando un indirizzo a 2 bit dato in ingresso. Ha inoltre un pin di abilitazione con il quale attivarlo solo quando la CPU necessita di eseguire un’operazione di lettura/scrittura sulla memoria. Questa sotto è la sua tabella operativa:

74139 function table

Come opera il 74139

I nostri chip di EEPROM e di SRAM sono entrambi da 32 KB: dato che la CPU Z80 può indirizzare direttamente proprio 64 KB di memoria, dobbiamo trovare un modo per cui lo Z80 veda i chip uno dopo l’altro, andando a riempire l’intero spazio degli indirizzi. Quale deve stare prima? Risposta facile: la ROM. Perché? Perché lo Z80 è progettato in modo che dopo un reset esso parta ad eseguire il codice dall’indirizzo $0000. Dato che il codice di avvio deve essere memorizzato nella memoria non volatile, questo significa che la ROM deve occupare i primi 32 KB dello spazio di indirizzi e che il chip di RAM occupi i secondi 32 KB. Osservando i chip possiamo vedere che essi hanno solo 15 pin per l’indirizzo mentre la CPU ne ha 16: infatti, 16 pin sono richiesti per indirizzare 64 KB (2^16 = 65.536 -> 64 KB) mentre 15 pin possono indirizzare solo 32 KB (2^15 = 32.768 -> 32 KB). Perciò c’è un pin inutilizzato, A15: lo useremo proprio per fare la selezione fra i chip ROM e RAM con il nostro decoder 74139. Collegheremo anche il pin /MREQ per pilotare l’ingresso /G: in questo modo abiliteremo il decoder solo per le le operazioni sulla memoria. Facendo così abbiamo creato un decoder indirizzi che seleziona il corretto banco da cui leggere o verso cui scrivere Per capire perché questo è così importante immaginiamo questo scenario: la CPU esce dal processo di reset e carica l’indirizzo $0000 nel PC (Program Counter) per andare a recuperare l’istruzione memorizzata in tale location. Si aspetterebbe di accedere alla ROM e trovare un qualche tipo di informazione non volatile.. ma cosa succede se la CPU accedesse all’indirizzo $0000 della RAM invece che della ROM? Un comportamento imprevedibile, perché la RAM potrebbe avere qualsiasi tipo di dato casuale a quell’indirizzo.

Detto questo, iniziamo a modificare il precedente circuito usato per il test dello Z80 PIO:

LM80C: PIO & RAM schematic

LM80C: schema per il test del PIO & della RAM

Come potete vedere, ho eliminato la connessione diretta fra il piedino /IORQ della CPU e l’ingresso /CE del PIO ed optato per la seconda unità del 74139 (tenete a mente che è un “doppio” decoder): a prima vista questo potrebbe apparire inutile ma dobbiamo preparare il nostro computer a gestire in futuro altri dispositivi così che possiamo usare lo stesso meccanismo adottato per decodificare la memoria anche per indirizzare altre periferiche. Diamo anche un momento un’occhiata al modo in cui la memoria è decodificata. Dato che adesso abbiamo solo 2 chip che rappresentano i 2 banchi in cui è divisa la memoria, abbiamo bisogno di 1 solo segnale in ingresso (l’A15) per scegliere fra di essi perciò, dato che il decoder necessita di 2 ingressi, ho collegato l’altro ingresso a massa. Facendo così il decoder selezionerà il banco ROM quando A15 è BASSO (intervallo di indirizzi da $0000 a $7FFF) mentre selezionerà il banco RAM quando A15 sarà ALTO (intervallo di indirizzi da $8000 a $FFFF). Si può facilmente verificare la cosa osservando più sopra la tabella operativa del 74139. B è sempre BASSO, perciò A (connesso ad A15) opera la selezione: quando è BASSO, il decoder abiliterà il chip connesso all’uscita marcata Y0 (il banco ROM)  mentre quando A sarà ALTO, abiliterà il chip connesso ad Y1 (il banco RAM).

Per finalizzare il nostro progetto carichiamo un semplice programma che prende un byte usato per importare i LED connessi al nostro Z80 PIO e memorizziamolo nella prima cella della SRAM: il suo indirizzo all’interno del chip è $0000 ma, grazie al nostro sistema di decodifica degli indirizzi, sarà raggiungibile all’indirizzo logico $8000. Per essere sicuri che la CPU indirizzi correttamente la RAM, cambiamo il suo valore ogni volta che viene letto. Cosa fa così il nostro sistema? Il programma, recuperato dalla EEPROM, legge un valore dalla RAM, ne inverte i suoi bit con un’operazione di XOR e lo manda al PIO che lo visualizza su dei LED. E così via. L’accesso corretto alla RAM è dimostrato dall’alternanza dei LED accesi/spenti, che seguono il motivo dei bit: questo significa che la CPU è capace di memorizzare e recuperare quel byte dalla SEAM mentre legge le istruzioni dalla EEPROM. Come potete vedere dal video sottostanto, il comportamento è esattamente quello descritto, a dimostrazione che la decodifica della memoria funziona perfettamente:

LM80C: PIO & RAM test

LM80C: test PIO & RAM

A presto.

Codice e schemi possono essere trovati su questo repository GitHub.