Motorola 68000
Da Wikipedia, l'enciclopedia libera.
Il Motorola 68000 è un microprocessore CISC a 16/32 bit, progettato e distribuito da Freescale Semiconductor (l'ex "Semiconductor Products Sector" della Motorola, da cui si è separata nel corso del 2004).
Come primo membro della famiglia di microprocessori m68k, il suo software in generale è compatibile con gli altri processori della famiglia.
In produzione da vent'anni, l'architettura 68000 resta una scelta tuttora popolare per nuovi progetti.
Indice |
[modifica] La famiglia 68000
- Motorola 68EC000
- Motorola 68HC000
- Motorola 68008
- Motorola 68010
- Motorola 68012
- Motorola 68020
- Motorola 68EC020
- Motorola 68030
- Motorola 68EC030
- Motorola 68040
- Motorola 68EC040
- Motorola 68LC040
- Motorola 68060
- Motorola CPU32 (detto anche Motorola 68330)
- Motorola Coldfire
- Motorola Dragonball
[modifica] Storia
Originariamente il MC68000 è stato progettato per essere un processore per usi generici. È stato utilizzato da diversi produttori di personal computer come Amiga, Atari e Apple. Molte console lo hanno utilizzato, per esempio la Sega Genesis/Sega Mega Drive, il NeoGeo e molte macchine da sala giochi. Nel Sega Saturn, il 68000 era dedicato alla gestione del suono e nell'Atari Jaguar era dedicato alla gestione dei dispositivi collegati al computer.
Molti progettisti lo hanno utilizzato e apprezzato e dal loro lavoro sono nati l'Amiga 1000, l'Atari ST, vari modelli di Macintosh, l'originale Sun Microsystems e le macchine UNIX della SGI. Il processore è stato utilizzato anche dai server Apollo/Domain I successori del 68000 sono stati utilizzati per molto tempo dalle macchine Unix dato che la sua architettura era molto simile a quella del Digital PDP-11 e VAX e quindi erano macchine eccellenti per far funzionare programmi scritti in C. Il 68000 ha avuto anche molto successo come microcontroller; è stato utilizzato da HP, Printronix e Adobe per realizzare stampanti. Da una sua derivazione sono nati i processori CPU32 e Coldfire utilizzati in milioni di sistemi di automazione industriale. È stato utilizzato anche in molte apparecchiature mediche per il suo basso costo e la sua affidabilità. Nel 2001 la sua versione Dragonball è stata utilizzata dalla Palm Computing per realizzare i suoi famosi PDA e anche Handspring lo ha utilizzato per la serie Visor, sebbene le ultime versioni montino processori con nucleo ARM. Il 68000 viene utilizzato dalla Texas Instruments per realizzare le sue calcolatrici grafiche.
La versione iniziale del 68000 è stata presentata nel 1982 per competere coll'Intel 8086 e l'Intel 80286 e i loro successori. La prima versione arrivava fino a 8 MHz che per i tempi era una frequenza molto elevata. Alcune istruzioni richiedevano solo 4 cicli di clock per essere completate; questo era dovuto all'efficiente architettura interna. Motorola ha cessato di produrre il 68000 nel 2000 anche se continua a produrre alcuni suoi derivati come le CPU32. Dal 2001 Hitachi ha ripreso a produrre 68000 grazie a una licenza concessale da Motorola.
[modifica] Architettura
[modifica] Bus indirizzi
Il 68000 era un compromesso intelligente: quando venne presentato, i bus a 16 bit erano effettivamente la soluzione più ragionevole, in quanto relativamente veloci e non molto costosi. Ciononostante, il 68000 venne progettato con registri e spazio d'indirizzamento a 32 bit, assumendo che il costo dell'hardware sarebbe sceso rapidamente e che quindi il maggior costo iniziale della soluzione a 32 bit si sarebbe ripagato in poco tempo.
Sebbene l'ALU del 68000 fosse a 16 bit, il processore gestiva tutti gli indirizzamenti a 32 bit; aveva cioè uno spazio d'indirizzamento di 32 bit lineare. Questo significa che il 68000 era, ed è, di fatto, un microprocessore a 32 bit. Lo si confronti con l'8086, che aveva uno spazio d'indirizzamento di 20 bit, ma non poteva accedere a blocchi di più di 64 kilobyte (16 bit) alla volta, se non manipolando registri di segmento.
Nonostante il bus della ALU fosse a 16 bit, le operazioni sugli indirizzi venivano eseguite a 32 bit ed era previsto fuori dalla ALU un sommatore e sottrattore a 32 bit, da utilizzare per le operazioni di post incremento e pre decremento sugli indirizzi, senza dover attendere l'ALU e quindi senza riduzioni delle prestazioni.
Come detto, sebbene Motorola avesse rilasciato un processore a 16 bit, le sue istruzioni e la sua architettura erano evidentemente plasmati per essere a 32 bit. Questa scelta venne presa per non dover affrontare problemi di compatibilità (vedi la travagliata estensione della famiglia 80x86) quando l'architettura sarebbe migrata su un bus a 32 bit. L'architettura scelta era flessibile, infatti era già previsto sia il 68008 (processore con bus a 8 bit) che il futuro successore a 32 bit (che poi fu il 68020).
Per venire in contro alle esigenze del mercato Motorola aveva previsto inizialmente tre processori. Il 68000, dotato di un bus a 16 bit per i dati e in grado di indirizzare 24 bit di memoria (corrispondenti a 16 MByte). Il 68008, dotato di un bus a 8 bit per i dati e in grado di indirizzare 18 bit (con possibilità di utilizzare 19 o 20 bit con un trucco hardware) e infine il processore della generazione successiva dotato di un indirizzamento a 32 bit e di un bus dati a 32 bit ( in grado di indirizzare 4 GByte).
[modifica] Registri interni
La CPU ha i seguenti registri, tutti a 32 bit:
- 8 registri di uso generale per i dati (D0-D7)
- 8 registri per gli indirizzi (A0-A7)
- un registro puntatore d'istruzione (PC)
- un registro (SSP) per lo stack supervisore
Tutti i registri dati sono di uso generico, non ci sono registri specializzati, dedicati ad esempio alla moltiplicazione o alla divisione, come nei processori precedenti. L'ultimo registro indirizzi è lo stack pointer e può essere chiamato indifferentemente A7 oppure SP. Questo numero di registri rappresenta un buon compromesso: abbastanza basso da non penalizzare troppo il 68000 nelle commutazioni di contesto, ma tuttavia sufficiente a velocizzare la maggior parte dei calcoli.
La separazione dei registri in due tipi a volte è un po' seccante, ma non è difficile da gestire. Si dice che abbia consentito ai progettisti della CPU di raggiungere un più alto grado di parallelismo, grazie all'uso di un'unità d'esecuzione ausiliaria per i registri indirizzi.
È presente inoltre un registro di stato (SR) a 16 bit.
[modifica] Registro di stato
Le istruzioni aritmetico-logiche e i trasferimenti impostano automaticamente i bit di condizione (flag) nel registro di stato, tranne nel caso in cui la destinazione sia un registro indirizzi. Ci sono 5 bit di condizione:
N
(Negative): bit di segno. È una copia del bit più significativo del risultato;Z
(Zero): indica che il risultato è zero;V
(oVerflow): superamento di capacità (in aritmetica con segno);C
(Carry): riporto (superamento di capacità, in aritmetica senza segno);X
(eXtend): normalmente assume lo stesso valore di C, ma solo per le operazioni aritmetiche. Semplifica l'implementazione di operazioni a precisione superiore a 32 bit.
I bit di condizione vengono usati principalmente dalle istruzioni di salto condizionato, per il controllo del flusso di un programma.
[modifica] Set di istruzioni
I progettisti hanno cercato di rendere il linguaggio assembly del 68000 ortogonale. Le istruzioni sono cioè divise in operazioni e modi di indirizzamento, e quasi tutti i modi d'indirizzamento sono utilizzabili con la maggior parte delle istruzioni. Questa scelta progettuale è apprezzata dalla maggior parte dei programmatori, anche se qualcuno non ha gradito la "quasi" ortogonalità.
Chi scriveva un assemblatore per il 68000 si rendeva chiaramente conto che queste "istruzioni", al livello dei bit, erano traducibili in più codici operativi differenti. Era un compromesso abbastanza buono perché dava quasi gli stessi vantaggi di un sistema veramente ortogonale, e tuttavia garantiva ai progettisti della CPU la libertà di estendere la tabella dei codici operativi.
Con sole 56 istruzioni, la dimensione minima di un'istruzione era enorme per quei tempi: 16 bit. Inoltre, molte istruzioni e modi di indirizzamento richiedono alcune parole in più per operandi immediati, ulteriori bit del modo di indirizzamento, ecc.
Molti progettisti ritenevano che l'architettura del MC68000, relativamente al suo costo, offrisse un set di istruzioni con un'elevata densità di codice, specialmente per quello generato da un compilatore. Tale caratteristica è stata alla base del successo e della longevità di questa architettura. Questa convinzione (o caratteristica, a seconda del progettista) ha continuato a rivelarsi vincente per il set di istruzioni (anche per le successive CPU), finché l'architettura ARM non ha introdotto il set di istruzioni Thumb, similmente compatto.
[modifica] Livelli di privilegio
Il 68000 e le sue evoluzioni sono dotati di due livelli di privilegio: il livello utente e il livello supervisore. Un programma eseguito al livello utente ha accesso a tutti i registri, esclusi quelli per la gestione delle interruzioni. Al livello supervisore ha invece accesso a tutti i registri. La modalità d'esecuzione è legata a un bit memorizzato nel registro di stato.
Un notevole vantaggio di questa CPU è l'avere due stack pointer distinti, uno per ogni modalità. In modalità supervisore infatti il 68000 usa un registro SP diverso, detto SSP (Supervisor SP). Il processore può comunque accedere al registro SP del livello utente (detto USP, User SP) anche dal livello supervisore, mediante apposite istruzioni. Grazie a questa caratteristica, in un sistema multitasking basato sul 68000 è possibile usare stack molto piccoli per i singoli processi, dato che non bisogna prevedere spazio in più per il salvataggio dei registri per le interruzioni. Per la gestione delle interruzioni sarà invece sufficiente che il sistema operativo allochi un solo stack supervisore di dimensioni adeguate.
Il modo supervisore è il meccanismo di base, comune a tutti i processori della famiglia 68000, per implementare le politiche di protezione tipiche dei sistemi operativi più avanzati: ai programmi comuni, che vengono eseguiti in modalità utente, non è consentito l'uso di istruzioni potenzialmente pericolose, che rimangono di competenza esclusiva del sistema operativo.
[modifica] Interrupt
La CPU gestisce 8 livelli di interrupt. I livelli vanno dal livello 0 al livello 7 e sono a priorità. Quindi un livello ad alta priorità può sempre interrompere un livello a priorità inferiore. Nel registro di stato una istruzione privilegiata seleziona il livello di interrupt attualmente in esecuzione in modo da ignorare gli eventuali interrupt di livello inferiore. Il livello 7 è non mascherabile mentre il livello 0 non è in grado di bloccare nessun interrupt in esecuzione. I livelli come già detto sono memorizzati nel registro di stato e sono visibili in modo utente.
La tavola delle eccezioni (interrupt vector addresses) è posizionata nelle locazioni di memoria comprese tra 0 e 1023 e permette 256 vettori a 32 bit. Il primo vettore memorizza il punto di partenza dello stack degli indirizzi, il secondo memorizza lo stack delle istruzioni. I vettori tra 3 e 15 sono utilizzati per segnalare gli errori: errore di bus, indirizzo errato, istruzione illegale, divisone per zero, etc. Dal vettore 24 in poi vengono memorizzati gli interrupt, i 15 livelli di TRAP (interruzione software dell'esecuzione dei programmi da parte del processore) e i vettori definiti dall'utente.
Il gestore degli interrupt inizialmente era un chip separato, il 68901, questo chip complicava notevolmente il disegno della piastra e rallentava il processore dato che ogni interrupt doveva essere convertito dal chip. Il 68901 era provvisto anche di una UART molto semplice e di un timer per gli interrupt. Il 68901 aveva molti difetti inclusa una predisposizione a perdere gli interrupt di alto livello se questo e il timer scattavano nello stesso istante. La controparte prodotta dalla Mostek era decisamente migliore.
Durante l'avvio del computer avere i vettori a indirizzi fissi era molto comodo, dato che consentiva di programmare le ROM dei computer senza troppe complicazioni dovute alle allocazioni dinamiche dei vettori. Ma quando il sistema operativo era caricato una gestione fissa dei vettori era una tecnica sconsigliabile dato che limitava il sistema operativo e lo rendeva molto legato al funzionamento del singolo modello di processore. Per risolvere questo problema spesso i produttori avviavano il computer con le ROM residenti a partire da un particolare indirizzo e dopo l'avvio l'indirizzo di partenza veniva modificato e al posto della ROM veniva allocata della RAM che poteva essere modificata senza problemi.
Un ulteriore problema derivava dalla modalità privilegiata. I progettisti l'hanno realizzata pensando a un sistema operativo come Unix che per ragioni di sicurezza attua un netta distinzione tra programmi e sistema operativo. L'idea era buona ma l'implementazione si rivelò lacunosa, vi erano delle dimenticanze che la rendevano non sicura. Questi errori vennero corretti nelle generazioni successive.
Il 68000 non era in grado di gestire correttamente un errore nell'accesso alla memoria e quindi non era in grado di implementare una vera gestione della memoria virtuale, una necessità vitale per molti sistemi operativi. La memoria virtuale è una semplice tecnica utilizzata per simulare la disponibilità di memoria RAM praticamente infinita. Quando il processore accedeva a una locazione di memoria non esistente attivava un interrupt che provvedeva a selezionare un blocco di RAM, prelevarne il contenuto memorizzandolo su disco rigido e poi manipolava gli indirizzi in modo che gli indirizzi inesistenti puntassero alla zona di memoria appena liberata. Alcuni produttori di sistemi Unix realizzarono macchine basate sul 68000 con il supporto della memoria virtuale. Ci riuscirono utilizzando due processori con il clock sfasato. Quando il primo processore si bloccava per via di un accesso a un indirizzo inesistente la logica di controllo impediva al secondo di fare la stessa fine e attivava l'interrupt di gestione della memoria virtuale che dopo aver liberato la RAM e aver opportunamente manipolato gli indirizzi sbloccava il primo processore che riprendeva l'elaborazione come se non fosse successo niente. Ovviamente era una tecnica molto costosa e inefficiente e appena usci il 68010 i produttori aggiornarono le macchine eliminando il secondo processore.
Un problema meno visibile ma non meno importante del 68000 era che avendo molte istruzioni e molti modi di indirizzamento era difficile da simulare dato che il simulatore doveva tener conto di moltissimi casi con moltissime varianti. Questo è un problema che si presenterà anche in alcune versioni moderne della sua architettura. Nel controllo avionico infatti è stato scelto il processore Intel 80386 per la sua semplicità di simulazione rispetto al corrispettivo processore Motorola.
La revisione successiva del processore, il Motorola 68010 risolse la maggior parte dei problemi del 68000.
[modifica] Dettagli sul set di istruzioni
La maggior parte delle istruzioni sono diadiche, hanno cioè due operandi, uno dei quali indica anche la destinazione del risultato. Esempi significativi sono:
- Aritmetiche
- ADD (somma), SUB (sottrazione)
- MULU (moltiplicazione senza segno), MULS (moltiplicazione con segno)
- DIVU (divisione senza segno), DIVS (divisione con segno)
- NEG (inversione del segno)
- CMP (confronto: una sorta di sottrazione che scarta il risultato, ma modifica i flag di stato)
- In aritmetica decimale (BCD):
- ABCD e SBCD
- Logiche:
- AND, OR
- NOT (logical not)
- EOR (Exclusive OR)
- Shift e rotazioni:
- Operazioni su bit:
- BSET (mette a 1)
- BCLR (mette a 0)
- BTST (bit test)
- Supporto ai sistemi multiprocessore:
- TAS, test-and-set, effettua uno speciale ciclo indivisibile di lettura-modifica-scrittura sul bus; permette di implementare facilmente i meccanismi di mutua esclusione in sistemi multiprocessore a memoria condivisa.
Condizioni Bcc/DBcc | ||
---|---|---|
T true | 0000 | 1 |
F false | 0001 | 0 (solo per DBcc) |
CC carry clear | 0100 | |
CS carry set | 0101 | C |
EQ equal | 0111 | Z |
GE greater or equal | 1100 | |
GT greater than | 1110 | |
HI high | 0010 | |
LE less or equal | 1111 | |
LS low or same | 0011 | |
LT less than | 1101 | |
MI minus | 1011 | N |
NE not equal | 0110 | |
PL plus | 1010 | |
VC overflow clear | 1000 | |
VS overflow set | 1001 | V |
- Controllo di flusso:
- JMP (jump)
- JSR (jump to subroutine)
- BSR (branch to subroutine: come jump, ma relativa al PC)
- RTS (return from subroutine)
- RTE (return from exception, per uscire dalle eccezioni)
- TRAP (lancia un'eccezione software)
- CHK (eccezione software con condizione)
- Salti condizionali:
- Bcc (salta se è verificata la condizione "cc". Questo specifica una delle 16 possibili condizioni di test da verificare sul registro di stato).
- DBcc (se la condizione è falsa, decrementa il registro dati e, se il registro non è -1, salta. L'uso di -1 invece di 0 come valore di uscita consente di programmare facilmente i cicli in cui il numero di ripetizioni può essere nullo, senza bisogno di un controllo aggiuntivo all'inizio nel ciclo)
- Altre:
- accesso al registro di stato e, nei modelli successivi, ad altri registri speciali
- supporto a legacy device
Molte istruzioni ammettono un suffisso che permette di specificare la dimensione dei dati dell'operazione:
- ".b" per 8 bit (byte),
- ".w" per 16 bit (word),
- ".l" per 32 bit (long word).
Il default è 16 bit.
I modi di indirizzamento supportati sono:
- Diretto
- a registro dati, es. "D0"
- a registro indirizzi, es. "A6"
- Indiretto
- Semplice tramite registro indirizzi, es. (A0)
- Tramite registro indirizzi con post-incremento, es. (A0)+
- Tramite registro indirizzi con pre-decremento, es. -(A0)
- Tramite registro indirizzi con scostamento a 16 bit, es. 48(A0)
Si noti che la quantità effettivamente sommata o sottratta al registro indirizzi, rispettivamente nei modi con post-incremento e pre-decremento, dipende dalla dimensione dei dati: 1 se si opera su byte, 2 se su word, 4 se su long word.
- Indicizzato
- indiretto tramite registro indirizzi, indicizzato con registro (a 16 o 32 bit) e scostamento di 8 bit con segno, es. 15(A0, D0.w) or 76(A0, A1.l)
- Relativo al PC (program counter)
- con scostamento a 16 bit con segno, es. 1234(PC)
- indicizzato con registro (a 16 o 32 bit) e scostamento ad 8 bit con segno, es. 24(PC, D2.w)
- Assoluto
- Corto, a 16 bit (con estensione del segno), e.g. "$4000"
- Lungo, a 32 bit, es. $00123456
- Immediato
- Memorizzato nell'istruzione, es. #$400
[modifica] Note
[modifica] Bibliografia
[modifica] Collegamenti esterni
- (FR) Tout pour la Ti89
- (EN) Descrizioni delle istruzioni assembly
- (DE) immagini e descrizioni del 68000 presso cpu-collection.de
- (EN) Articolo 'Chips : Of Diagnostics & Debugging'
- (EN) A microprocessor simulation framework, useful for working with Motorola 68000
- (EN) Integrated Development Environment for the 68000 microcomputer
Lista dei microprocessori di Motorola/Freescale | |
---|---|
Famiglia 6800 : | 6809 (vedi anche: Hitachi 6309) |
Famiglia 68000 : | 68000 | 68008 | 68010 | 68012 | 68020 | 68030 | 68040 | 68060 | ColdFire | DragonBall |
Versioni a basso costo: | 68EC000 | 68EC020 | 68EC030 | 68EC040 | 68LC040 |
RISC pre-PowerPC : | 88000 |
Coprocessori in virgola mobile : | 68881, 68882 |
Famiglia PowerPC : | PPC e200 | PPC 603e/e300 | PCC 75x | PPC e500 | PPC 74xx/e600 | Famiglia PowerQUICC |