# Personal computer/Mapping

Personal computer
* Storia dei calcolatoriPersonal computer/Storia
* Architettura del calcolatorePersonal computer/Architettura
** CPUPersonal computer/Architettura/CPU
** MemoriaPersonal computer/Architettura/Memoria
** Input/OutputPersonal computer/Architettura/IO
* Linguaggio MacchinaPersonal computer/Linguaggio Macchina
** DLXPersonal computer/Linguaggio Macchina/DLX
*** Operazioni DLXPersonal computer/Linguaggio Macchina/DLX/Operazioni
*** DLX sequenzialePersonal computer/Linguaggio Macchina/DLX/DLX_sequenziale
*** DLX in pipelinePersonal computer/Linguaggio Macchina/DLX/DLX_pipeline
** 8086-8088Personal computer/Linguaggio Macchina/8086
* Mapping di Memorie ed InterfaccePersonal computer/Mapping
** Integrati NotevoliPersonal computer/Mapping#Caratteristiche_e_funzionamento_degli_integrati_notevoli
*** DriverPersonal computer/Mapping/Driver
*** CPUPersonal computer/Mapping/CPU
*** Memoria PrincipalePersonal computer/Mapping/Memorie
*** Interfacce I/OPersonal computer/Mapping/Interfacce
** Gestione delle interfacce tramite programmaPersonal computer/Mapping#Gestione_delle_interfacce_tramite_programma
* Standard alla base di un personal computerPersonal computer/Standard
* Appendici e RiassuntoPersonal computer/Appendici
Modifica il sommario
Nei capitoli precedenti abbiamo definito le caratteristiche logiche di CPU, sistema di memoria ed interfacce di Input/Output, in questo capitolo vedremo come collegare chip di memoria ed interfacce ad una CPU con parallelismo 8 bit.
Il progetto di elaboratore elettronico è basato sulla CPU 8088, se ne osserverà il pin-out e ci si concentrerà sulle caratteristiche logiche e sulle temporizzazioni dei segnali in ingresso alla CPU, in particolare il segnale di ready comandato dall'integrato 8284.
Per il sottosistema di memoria si vedrà il funzionamento di EPROM e RAM.
Per le interfacce se ne osserverà una generica, con considerazioni del tutto indipendenti dal reale dispositivo periferico controllato, per poi passare allo studio di interfacce di comunicazione standard quali una porta seriale COM (Interfaccia 8250 gestita tramite il protocollo RS 232) ed una porta parallela (8259).
Per la maggiore semplicità si considerano le interfacce gestite da programma (gestione a polling), tuttavia verrà preso in considerazione un integrato (PIC 8259) per la gestione delle interfacce tramite interruzioni (gestione a interrupt).

## Caratteristiche e funzionamento degli integrati notevoli

* Driver
** 244
** 245
** 373
** 374
* CPU 8088
** Integrato 8284
* EPROM - RAM
* Interfacce di I/O
** Protocollo RS 232
** 8250 - Interfaccia Seriale
** 8255 - Interfaccia Parallela
** PIC 8259

## Decodifica degli indirizzi

Qualsiasi dispositivo fisico, che sia una memoria o una interfaccia, per essere accessibile dal software deve poter essere indirizzato, ovvero deve occupare una finestra dello spazio di indirizzamento.
Il mapping consiste nell'associare ad un dispositivo una porzione dello spazio di indirizzamento e di generare, a partire dai bit sul bus degli indirizzi e dai segnali di comando, un segnale di selezione per quel dispositivo.
Sia un'interfaccia che una memoria, ma vale lo stesso discorso per qualsiasi agente master indirizzabile (controller DMA, controller hard disk, ...), occupa n=2^k posizioni nello spazio di indirizzamento. n rappresenta il numero di oggetti (ad esempio un registro) di 8 bit indirizzabili, k il numero di bit di indirizzo per il dispositivo.
Avendo a disposizione k indirizzi, che si traducono in k connessioni, qualsiasi dispositivo ha al suo interno un decoder di k variabili con un ingresso di enable detto chip select o chip enable che consente alla CPU di abilitare soltanto il dispositivo selezionato.
Quasi sempre il mapping dei dispositivi è allineato, ovvero l'indirizzo più basso tra tutti quelli associati al dispositivo è un multiplo della dimensione in byte dello stesso. L'allineamento semplifica notevolmente la decodifica degli indirizzi. Supponiamo infatti di avere un dispositivo con A indirizzi mappato in uno spazio di indirizzamento da 2^a bit (a bit di indirizzo), posto i = A - a esistono 2^i posizioni in cui poter mappare il dispositivo, tuttavia soltanto se questo è allineato gli a indirizzi dello spazio di indirizzamento possono essere considerati come il concatenamento di A e i. Supponendo di avere uno spazio di indirizzamento di 10 bit e voler mappare un dispositivo da 256 byte = 2^8. Allineando il dispositivo i due bit più significativi dello spazio di indirizzamento indicano che sono possibili 4 finestre (2^2) che sono appunto i byte da 0-255, 256-511, 512-767, 768-1024. Osservando la configurazione binaria degli indirizzi le quattro finestre sono (in parentesi l'indirizzo esadecimale)
Gli 8 bit meno significativi saranno decodificati internamente al dispositivo per selezionare il relativo elemento di memoria, i due bit più significativi serviranno invece per selezionare il dispositivo in una delle quattro finestre.
Sono possibili due tipi di decodifica degli indirizzi:
* decodifica completa
* decodifica semplificata

### Decodifica completa

Le decodifica completa è effettuata utilizzando tutti i bit di offset dell'indirizzo, i bit più significativi che non vengono utilizzati dal dispositivo per decodificare internamente una cella di memoria. Nell'esempio precedente di bus indirizzi a 10 bit e elemento di memoria a 8 bit, la decodifica completa è effettuata decodificando i 2 bit più significativi dell'indirizzo.
La decodifica più semplice è calcolare per ogni dispositivo il mintermine corrispondente allo spazio occupato, posto, ad esempio, che l'elemento di memoria sia nella parte più bassa dello spazio di indirizzamento ( 0-255 byte) allora i due bit più significativi dell'indirizzo valgono 0. Il chip select del dispositivo sarà, in logica positiva, CS = A9 * A8 realizzabile con un AND.
È possibile anche una decodifica con decoder 2:4 che presenta in uscita tutte le possibili finestre allineate. L'uscita del decoder corrispondente alla porzione di spazio di indirizzamento in cui è mappato il dispositivo è collegata con il suo ingresso chip select.
L'elemento più usato per la decodifica degli indirizzi è la PAL, una rete logica ad i ingressi e o uscite, identificata da iLo (ad esempio 10L8), che permette di generare o chip select a partire da i bit di ingresso. La PAL è una rete programmabile tramite espressioni in logica positiva ma le uscite sono già negate, per cui direttamente collegabili al CS* dei dispositivi. La scelta di una PAL si dimostra conveniente soprattutto quando i bit di selezione sono molti, per realizzare la stessa funzione di una PAL 10L8 sarebbe necessario un decoder a 10 ingressi e quindi a 1024 uscite.

### Decodifica semplificata

La decodifica semplificata o parziale viene effettuata eliminando alcuni bit dall'espressione dei chip select dei dispositivi mappati, mantenendo il corretto funzionamento del sistema.
Se considero un sistema con indirizzi a 10 bit e due elementi di memoria da 256 celle ciascuno ( 8 bit ) mappate in questo modo
I segnali dei chip select in logica positiva sono
Le due espressioni dei chip select individuano univocamente una finestra di 256 byte all'interno dello spazio di indirizzamento, che tuttavia presenta degli spazi liberi (la metà alta). Si può quindi pensare di eliminare l'univocità delle finestre selezionate mantenendo la separazione delle finestre.
Ad esempio eliminando il bit A9 dell'espressione del chip select si ottiene
che indirizzano le seguenti finestre
Ogni segnale di chip select individua due finestre nello spazio di indirizzamento, ognuna da 256 byte. Con queste espressioni dei chip select il chip1 risulta mappato in due finestre, così come il chip2 ma non essendoci sovrapposizione tra i chip select dei due dispositivi questa codifica semplificata risulta corretta.
Mentre da un lato con la decodifica parziale si ottengono delle espressioni semplificate per i chip select (nell'esempio un solo bit piuttosto che due), dall'altro si ha un forte spreco delle risorse. Eliminando n bit dall'espressione dei chip select ogni dispositivo va ad occupare 2^n posizioni.

## Gestione delle interfacce tramite programma

Una generica interfaccia ha dei registri interni che possono essere buffer dati (ingresso/uscita), registri di stato, di controllo, e che devono essere mappati nello spazio di I/O ed accessibili dalla CPU.
Ipotizziamo le seguenti associazioni
Il programma per prima cosa dovrà inizializzare l'interfaccia
Una volta inizializzata l'interfaccia sono possibili le operazioni di
Lettura dello stato
Lettura di un dato, Input
Scrittura di un dato, Output
Le operazioni di lettura e scrittura necessitano una sincronizzazione, l'interfaccia deve comunicare alla CPU che è disponibile un dato nel Buffer Input o che il Buffer Output è vuoto e quindi scrivibile.
La sincronizzazione, come visto in generale per le interfacce di I/O può avvenire per
* polling o a controllo del programma
* interrupt o con interruzioni

### Gestione a Polling

L'interfaccia rende disponibili le informazioni di sincronizzazione nel registro di stato tramite due bit
* BIF Buffer Input Full' ad indicare che il buffer in input è pieno, quindi contiene un valore che può essere letto dalla CPU
* BOE Buffer Output Empty il buffer di uscita è vuoto e quindi scrivibile dalla CPU
Prima di eseguire il trasferimento, la CPU deve controllare lo stato dell'interfaccia, un esempio del programma potrebbe essere
Input
Output

#### Esempio di programmi per la gestione delle interfacce

Pensiamo di voler gestire dei led mappati all'indirizzo 60H, per poter essere collegati al bus dati è necessario interfacciarli con un 373 che mette in 3-state le connessioni tra led e bus quando i primi non sono indirizzati, il programma, dopo l'inizializzazione
comanda l'accensione di tutti i led

### Gestione ad Interrupt

Nella gestione ad interrupt la CPU esegue un programma principale qualsiasi e viene interrotta da una richiesta di passaggio alla routine di servizio associata all'interruzione. La procedura chiamata dall'interfaccia deve quindi avere un prologo e un epilogo che permettano alla CPU di poter tornare ad eseguire il programma principale alla fine della routine di servizio
Programma principale
La variabile FineOp è usata per la sincronizzazione, viene azzerata in fase di inizializzazione dal programma principale, ed impostata ad 1 dal gestore delle interruzioni (la routine di servizio) quando è completata l'operazione di I/O.
Routine di servizio