UNIVERSITA’ DEGLI STUDI DI GENOVA
FACOLTA’ DI SCIENZE MATEMATICHE, FISICHE E NATURALI CORSO DI LAUREA IN INFORMATICA
TESI DI LAUREA
UN SIMULATORE A LIVELLO DI MICROARCHITETTURA DELLA MACCHINA VIRTUALE VM-1 IMPLEMENTATO IN HTML, JAVASCRIPT E JAVA
Relatore Correlatore
Prof. Giovanni Chiola Prof. Gerardo Costa
Candidato
Antonio Scorza
ANNO ACCADEMICO 2000/2001
Indice 1
Indice
Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Capitolo 1
Cenni sulla Macchina Virtuale VM-2
1.1 Architettura del sistema. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2 Funzionamento del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .7
1.3 Istruzioni della macchina VM-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9
1.4 Esempi di programmi VM-2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Capitolo 2
La Macchina Virtuale VM-1
2.1 Organizzazione della Macchina Virtuale VM-1 . . . . . . . . . . . . . . . . . . . 17
2.2 VM-1 Data Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.3 VM-1 Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.4 Il Clock e il BUS di sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.5 Il MIR e i segnali di controllo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.6 La Control Store e il Microcodice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Indice 2
Capitolo 3
Le problematiche del Progetto
3.1 L’implementazione dei dispositivi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.2 I ritardi dei dispositivi. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.3 L’interazione logica fra i dispositivi. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Capitolo 4
Il Simulatore
4.1 L'interfaccia grafica. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
4.2 I bottoni di interazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.3 Esempi di programmi.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Appendice A
A.1 Il codice JAVASCRIPT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
A.2 Il codice JAVA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
A.3 Il codice HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .101
A.4 Il contenuto della CONTROL STORE . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Bibliografia
B.1 Riferimenti. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .121
Introduzione 3
Introduzione
Per comprendere a fondo il funzionamento della macchina virtuale VM-1 (Virtual Machine - level 1) oggetto di questo lavoro, occorre chiarire vari aspetti riguardanti la macchina convenzionale.
Una macchina convenzionale e’ un’architettura composta da vari elementi, registri, decodificatori, multiplexer, ecc. con una struttura studiata ad hoc. Si può capire bene che l’insieme di questi elementi implica uno studio a tavolino delle varie problematiche che stanno dietro (sincronizzazione, controllo dei dispositivi, percorso dei dati, rappresentazione dei dati, ecc.).
Ovviamente nell’affrontare le problematiche legate alle macchine convenzionali non si cercherà di andare nel dettaglio commerciale (Pentium, PowerPC, Alpha, ecc.) ma si rimarrà su una struttura didattica molto piu’ semplice scelta ad hoc per sviscerare in dettaglio alcune delle problematiche che si possono incontrare nel voler progettare e realizzare una macchina convenzionale.
La macchina convenzionale didattica scelta, chiamata VM-2, può essere vista come una struttura a 2 livelli: il primo livello (VM-1) dedicato al dettaglio fisico di funzionamento dei vari dispositivi e il livello due dedicato alla descrizione piu’ ad alto livello del suo funzionamento con le specifiche delle istruzioni.
Introduzione 4
Metaforicamente si puo’ paragonare la macchina VM-2 ad un’auto su di un deplian con la descrizioni delle funzionalita’, degli optional ecc. mentre la macchina VM-1 puo’ essere paragonata alla stessa auto vista pero’ dal lato del meccanico che effettua il tagliando annuale. Il meccanico opera sulla stessa auto dell’acquirente ma ad un livello piu’ basso e dettagliato, controllando che tutto funzioni a dovere senza il benche’ minimo problema.
La macchina VM-1 e’ una macchina programmabile minimale che si occupa [TAN91] di gestire (VM-1 Control) il corretto funzionamento dei dispositivi della macchina virtuale VM-2 e il transito corretto dei dati (VM-1 Data Path).
Come si vedrà in seguito gli argomenti verranno suddivisi in modo che costituiscano delle tappe da percorrere gradatamente in modo chiaro e conciso, per arrivare a capire a fondo ogni singolo dettaglio che entra in gioco in problematiche di questo tipo.
Si cercherà di esaminare in dettaglio il funzionamento di questa struttura per capire come la progettazione accurata di tutti i dispositivi possa giocare un ruolo vitale sia nell'utilizzare a posteriori il sistema sia nel microprogrammare tale struttura. A seconda degli scopi prefissati (ad esempio velocita’ di esecuzione) sara’ preferire un controllo ‘cablato’ perche’ i segnali arrivano in ‘tempo reale’ a tutti i dispositivi al contrario si preferira’ un controllo microprogrammato del sistema per:
La struttura utilizzata sarà semplice e scelta in modo ragionevole alle nostre esigenze, anche perché la scelta di architetture più realistiche porterebbe, oltre che all'aumento della complessità anche allo svantaggio di dover tenere in considerazione una quantità enorme di dettagli e problematiche.
Si avrà a disposizione uno strumento che consentirà di interagire con i programmi VM-2, con i registri, con le celle di memoria, con la control store, ecc. e con i ritardi dei dispositivi avendo padronanza assoluta sul funzionamento della macchina virtuale.
Lo strumento in questione e' un simulatore software implementato in HTML/JAVASCRIPT/JAVA indipendente quindi dalla piattaforma di esecuzione a patto che si abilitino, nel proprio browser web, l'esecuzione degli script e degli applet java.
Questo vuole essere uno strumento estremamente semplice per avvicinare l'utente alle pecularità di funzionamento di un moderno elaboratore elettronico.
Vi sarà una prima parte dedicata ai richiami della macchina VM-2, una seconda dedicata alla macchina VM-1, una terza dedicata alle scelte implementative effettuate e una quarta dedicata alla descrizione di funzionamento software dell’interfaccia grafica (simulatore).
Il SIMULATORE verra' utilizzato dagli STUDENTI del corso di ARCHITETTURA DEGLI ELABORATORI per migliorare la comprensione del funzionamento dell’architettura in questione.
CAPITOLO 1 Cenni alla Macchina Virtuale VM-2 5
Capitolo 1
Cenni sulla Macchina Virtuale VM-2
In questo capitolo si parlera’ della macchina virtuale scelta, la VM-2, in modo da poter essere informati su tutti i dispositi presenti in questa architettura. Si defineranno in dettaglio tutti circuiti di commutazione (multiplexer, demultiplexer, decoder), circuiti numerici (ALU), circuiti sequenziali (memorie, registri) e le loro interazioni.
1.1 Architettura del sistema
Il sistema, per come, e’ stato scelto e’ formato [TAN91] da:
CAPITOLO 1.1 Architettura del Sistema 6
Infatti supponiamo di avere un programma P1 in esecuzione e si voglia attivare una procedura P2 (estensione di P1), occorrera’ destinare dello spazio in memoria per la computazione di P2 in modo tale che i dati temporanei di P2 non vadano a sovvraporsi ai dati di P1.
Nella figura 1.1 si puo vedere come fisicamente e’ strutturata la macchina VM-2.
Sono da notare 2 cose importanti:
L’utente dovra’ occuparsi di andare a leggere il contenuto della cella 4095 per conoscere l’output della macchina mentre dovra’ scrivere direttamente nella cella 4094 se vorra’ dare un input alla macchina. Questa scelta, come detto prima, e’ stata effettuata per poter ‘allegerire’ l’architettura e concentrare
CAPITOLO 1.1 Architettura del Sistema 7
l’attenzione sugli aspetti piu’ importanti della microprogrammazione;
Figura 1.1: La struttura della MacchinaVirtuale VM-2.
1.2 Funzionamento del Sistema
Alla base del funzionamento hardware della macchina c’e’ uno studio algoritmico, perche’ le procedure da eseguire per un corretto funzionamento della macchina posso essere descritte da un semplice algoritmo. Questo e’ possibile perche’ l’esecuzione dei programmi avviene in modo sequenziale e non parallelo.
CAPITOLO 1.2 Funzionamento del Sistema 8
Se avessimo una macchina non sequenziale occorrerebbe tener conto dello stato di esecuzione dei vari sottoprogrammi, quindi assai complesso e non consono al nostro obiettivo.
L’algoritmo [TAN91] in questione puo’ essere schematizzato in questo modo:
Procedendo in questo modo la CPU e’ in grado di eseguire i programmi sequenziali le cui istruzioni sono codificate sotto forma numerica nelle celle della RAM a partire dall'indirizzo 0. Questo vuol dire che un qualsiasi programma che vogliamo far eseguire alla macchina virtuale deve essere mappato dalla cella di memoria RAM[0] in poi. Nulla toglie a voler scrivere un’istruzione di salto nella cella 0 per far puntare l’esecuzione ad altre celle di memorie (ad esempio alla cella 2000).
Questa possibilita’ di ‘puntare’ ad altre celle di memorie ci viene garantito dal fatto che si e’ scelto di avere salti non condizionati JUMP e salti condizionati JPOS, JNEG, JNZE e JZER.
Per quanto riguarda i modi di indirizzamento si fa uso dei metodi immediato, autoincremento, diretto, indiretto e registro.
Nel primo caso (Immediato) il valore costante che si vuole usare come operando e’ codificato dentro all’istruzione che si sta eseguendo secondo un sistema per cui alcuni bit vengono utilizzati per codificare l’istruzione ed i rimanti per codificare l’operando. In questa maniera si ha subito a disposizione l’informazione senza dover accedere alla memoria.
Nel secondo caso (Autoincremento) vuol dire che l’operando e’ contenuto in una cella di memoria il cui indirizzo e’ dato dal sommare o sottrarre 1 dal valore contenuto in un apposito registro dentro la CPU.
Nel terzo caso (Diretto) vuol dire che l’indirizzo assoluto dell’operando e’ memorizzato o deve essere memorizzato in una cella precisa di memoria (ad esempio RAM[2001]).
CAPITOLO 1.3 Istruzioni della macchina VM-2 9
Nel quarto caso (Indiretto) a seconda che sia modo indiretto mediante registro o mediante cella di memoria si avra’ l’operando contenuto in una cella di memoria RAM il cui indirizzo e’ contenuto in un registro della CPU oppure si avra’ l’operando contenuto in una cella di memoria RAM il cui indirizzo e’ contenuto in un’altra cella di memoria RAM.
Infine nell’ultimo caso (Registro) l’operando o e’ memorizzato o deve essere memorizzato in un registro della CPU.
Nel prossimo paragrafo (1.3) si chiarira’ cosa vuol dire utilizzare alcuni bit per codificare l’istruzione ed i rimanenti per l’operando e come funziona il dispositivo di INPUT/OUTPUT.
1.3 Istruzioni della macchina VM-2
Una parte molto importante della progettazione e’ come codificare le istruzioni in modo ottimale. Qui posso nascere varie domande: come codificare le diverse istruzioni? Quale tecnica utilizzare? Da dove partire?
L’insieme delle istruzioni VM-2 non sono state create e codificate ‘a caso’ come si potrebbe pensare ma la loro codifica e’ il frutto di attente esservazioni. Innazitutto si e’ pensato a dividere le varie istruzioni in base alla tipologia ‘aritmetico’, ‘logico’, di controllo del ‘flusso’, di ‘spostamento’ dei dati ecc. Non ultima la possibilita’ di risparmire bit nel memorizzare le varie istruzione e proprio per questo si e’ pensato ad un codice ad espansione.
Le istruzioni della macchina VM-2 vengono tutte codificate su 16 bit, in modo da poter utilizzare una singola cella di memoria per contenere la rappresentazione di una istruzione. Viene utilizzata una tecnica di espansione del codice operativo delle istruzioni per lasciar spazio ad operandi specificati su 8 oppure 12 bit (a seconda dell'istruzione) [CHI96].
Cio’ significa che, nel nostro caso, i 4 bit piu’ significativi sui 16 a nostra disposizione vengano utlizzati per codificare istruzioni di:
CAPITOLO 1.3 Istruzioni della macchina VM-2 10
mentre gli altri 12 bit identificano un possibile operando.
I 4 bit piu’ significativi identificano quindi (2^4)-2 istruzioni per un totale di 14. E’ da notare che la 15esima istruzione quella che inizierebbe per 1111 non puo’ essere utilizzata perche’ utilizzare come flag per la codifica ad espandisione.
Un’altra precisazione la si deve fare per il significato di xxx che lo si deve intendere come codifica in esadecimale dei 12 bit rimanenti. Ad esempio FFF corrisponde a 1111 1111 1111 in binario e 4095 in decimale.
Arrivati a codificare la 15esima istruzione (LOC8) entra in gioco il codice ad espanzione per cui tutte le istruzioni codificate con la lettera Fxxx identificano altre 16 istruzioni. Come si puo’ immaginare per la codifica delle altre istruzioni vengono ora usati gli 8 bit piu’ significativi mentre gli altri 8 bit descrivono un possibile operando. Le istruzioni codificate con questa tecnica sono:
CAPITOLO 1.3 Istruzioni della macchina VM-2 11
Anche in questo caso occorre fare un’altra precisazione, xx lo si deve intendere come valore esadecimale degli 8 bit rimanenti (quelli MENO significativi).
Di seguito [CHI96] le specifiche formali di tutte le istruzioni VM-2 intendendo che:
AAAAAAAAAAAA
, CCCCCCCC rappresentano una qualunque configurazione di bit tanti quante sono le ripetizioni della lettera;
JPOS : 0000AAAAAAAAAAAA
IF (ACC >= 0) THEN PC <-- AAAAAAAAAAAA;
JNEG : 0001AAAAAAAAAAAA
IF (ACC < 0) THEN PC <-- AAAAAAAAAAAA;
JZER : 0010AAAAAAAAAAAA
IF (ACC = 0) THEN PC <-- AAAAAAAAAAAA;
JNZE : 0011AAAAAAAAAAAA
IF (ACC <> 0) THEN PC <-- AAAAAAAAAAAA;
LODD : 0100AAAAAAAAAAAA
ACC <-- M[AAAAAAAAAAAA];
CAPITOLO 1.3 Istruzioni della macchina VM-2 12
ADDD : 0101AAAAAAAAAAAA
ACC <-- ACC + M[AAAAAAAAAAAA];
ANDD : 0110AAAAAAAAAAAA
ACC <-- ACC AND M[AAAAAAAAAAAA];
STOD : 0111AAAAAAAAAAAA
M[AAAAAAAAAAAA] <-- ACC;
LODL : 1000AAAAAAAAAAAA
ACC <-- M[FP + AAAAAAAAAAAA];
ADDL : 1001AAAAAAAAAAAA
ACC <-- ACC + M[FP + AAAAAAAAAAAA];
ANDL : 1010AAAAAAAAAAAA
ACC <-- ACC AND M[FP + AAAAAAAAAAAA];
STOL : 1011AAAAAAAAAAAA
M[FP + AAAAAAAAAAAA] <-- ACC;
JUMP : 1100AAAAAAAAAAAA
PC <-- AAAAAAAAAAAA;
LDIX : 1101AAAAAAAAAAAA
ACC <-- M[ACC + AAAAAAAAAAAA];
CALL : 1110AAAAAAAAAAAA
M[SP] <-- FP; FP <-- SP; SP <-- (SP - 1);
M[SP] <-- PC; SP <-- (SP - 1); PC <-- AAAAAAAAAAAA;
LOC8 : 11110000CCCCCCCC
ACC <-- 00000000CCCCCCCC;
CAPITOLO 1.3 Istruzioni della macchina VM-2 13
LOCH : 11110001CCCCCCCC
ACC <-- CCCCCCCC00000000 OR (ACC AND 0000000011111111);
INSP : 11110010CCCCCCCC
SP <-- SP + 0000CCCCCCCC;
DESP : 11110011CCCCCCCC
SP <-- SP - 0000CCCCCCCC;
PUSH : 11110100XXXXXXXX
M[SP] <-- ACC; SP <-- (SP - 1);
PSHI : 11110101XXXXXXXX
M[SP] <-- M[ACC]; SP <-- (SP - 1);
POP : 11110110XXXXXXXX
SP <-- (SP + 1); ACC <-- M[SP];
POPI : 11110111XXXXXXXX
SP <-- (SP + 1); M[ACC] <-- M[SP];
SWAS : 11111000XXXXXXXX
tmp <-- ACC; ACC <-- 0000(SP); SP <-- tmp;
SWAF : 11111001XXXXXXXX
tmp <-- ACC; ACC <-- 0000(FP); FP <-- tmp;
NEGA : 11111010XXXXXXXX
ACC <-- NOT ACC;
SIGN : 11111011XXXXXXXX
ACC <-- (-ACC);
CAPITOLO 1.3 Istruzioni della macchina VM-2 14
RETN : 11111100XXXXXXXX
SP <-- FP; PC <-- M[FP-1]; FP <-- M[FP];
HALT : 11111101XXXXXXXX
arresto del ciclo di fetch.
RSHF : 11111110XXXXXXXX
ACC <-- (ACC>>1);
LSHF : 11111111XXXXXXXX
ACC <-- (ACC<<1);
1.4 Esempi di programmi VM-2
Vedremo ora alcuni esempi di programmi VM-2 dai piu’ semplici a quelli un po’ piu’ complessi.
EX. 1.1 (VM-2): Supponiamo di voler prelevare un numero dalla cella di memoria 6 e voler effettuare:
4006 Ram00
Carica il valore della cella di memoria 6 nell’accumulatore;1006 Ram01
Se il valore nell’ACC e’ negativo salta alla cella di memorianumero 4;
FF00 Ram02
Moltiplica per 2 il valore che si trova nell’accumulatore;FD00 Ram03
Termina la computazioneFB00 Ram04
Cambia segno al valore presente nell’accumulatore;FD00 Ram05
Termina la computazioneFFFF Ram06
Corrisponde al valore negativo –1.CAPITOLO 1.4 Esempi di programmi VM-2 15
Quindi il risultato che si otterra’ dall’esecuzione del programma sara’ il valore 1 nell’accumulatore al contrario se si variasse la cella ram 6 con un valore positivo (ex. 000F equivalente a 15 in decimale) avremmo come risultato il valore 30 nell’accumulatore.
EX. 1.2 (VM-2): Supponiamo di voler prendere in input 2 numeri diversi da 0 e farne la somma per poi fornirla in output.
4FFE Ram00
Carica il valore della cella di memoria FFE cioe’ 4094 (input);1000 Ram01
Se il valore nell’ACC e’ negativo (significa che non e’ statoancora immesso nessun valore) ritorna alla cella 0;
700B Ram02
Memorizza nella cella 11 (B) il valore letto d’input che ora sitrova nell’accumulatore;
C006 Ram03
Salto incondizionato alla cella 6;0000 Ram04
Cella libera;0000 Ram05
Cella libera;4FFE Ram06
Carica il valore della cella di memoria FFE cioe’ 4094 (input);1006 Ram07
Se il valore nell’ACC e’ negativo (significa che non e’ statoancora immesso nessun valore) ritorna alla cella 6;
500B Ram08
Effettua la somma dei due numeri inseriti;7FFF Ram09
Memorizza nella cella di memoria 4095 (output) il risultato;FD00 Ram10
Termina la computazione.
Vediamo ora un’altro esempio di programma VM-2 un po’ piu’ complesso. Mentre per la somma si e’ riusciti in modo semplice a creare un programma VM-2 (ma non l’unico, ce ne sono altri che posso eseguire la stessa cosa) ora per la moltiplicazione di 2 numeri POSITIVI dobbiamo faticare un po’ di piu’.
La complessita’ crescerebbe ancora se dovessimo moltiplicare 2 numeri qualsiasi quindi sia negativi che positivi.
EX. 1.3 (VM-2): Supponiamo ora di voler prendere in input 2 numeri POSITIVI diversi da 0 e farne la moltiplicazione per poi fornirla in output.
F001 Ram00
Carica il valore 1 nell'accumulatore;FB00 Ram01
Effettua il cambiamento di segno dell'ACC;7019 Ram02
Memorizza nella cella 25 (19) il valore contenuto nell'Accu-mulatore che nel nostro caso sara' -1;
4FFE Ram03
Carica il valore della cella di memoria FFE cioe' 4094 (input);CAPITOLO 1.4 Esempi di programmi VM-2 16
1003 Ram04
Se il valore nell'ACC e' negativo (significa che non e' statoancora immesso nessun valore) ritorna alla cella 3;
701A Ram05
Memorizza nella cella 26 (1A) il valore letto d'input che ora sitrova nell'accumulatore;
C009 Ram06
Salto incondizionato alla cella 9;0000 Ram07
Cella libera;0000 Ram08
Cella libera;4FFE Ram09
Carica il valore della cella di memoria FFE cioe' 4094 (input);1009 Ram10
Se il valore nell'ACC e' negativo (significa che non e' statoancora immesso nessun valore) ritorna alla cella 9;
701B Ram11
Memorizza nella cella 27 (1B) il valore letto d'input che ora sitrova nell'accumulatore;
FE00 Ram12
Effettua 1 shift a destra;300C Ram13
Salta alla cella 12 (C) fino a quando non ho ottenuto 0;501B Ram14
Sommo all'accumulatore l'ultimo valore letto701C Ram15
Memorizza nella cella 28 (1C) il valore ottenuto;401A Ram16
Leggo il valore della cella 26 (1A) ;5019 Ram17
Sommo -1 al valore dell'accumulatore;701A Ram18
Memorizza nella cella 26 (1A) il valore ottenuto;3017 Ram19
Se il valore e' diverso da 0 salta l'esecuzione alla cella di me-moria 23 (17);
401C Ram20
Leggo il valore della cella 28 (1C);7FFF Ram21
Memorizza nella cella di memoria 4095 (output) il risultato;FD00 Ram22
Termina la computazione;401C Ram23
Leggo il valore della cella 28 (1C);C00E Ram24
Salto alla cella 14 (E).
E’ importante notare che quando viene letta la cella 4094 il controller dell’INPUT/OUTPUT si occupa di fornire al sistema il valore inserito e impostare a 1 il bit di segno (8000 in codifica esadecimale). Il processore non puo’ trattare direttamente le celle di memoria in questione ma deve interagire con il controller.
Questo sistema permette di sapere se un valore e’ stato inserito ma non di catturare tutti gli inserimenti. Si immagini di avere un hardware ‘lento’ quantificabile in 100 deltaT per eseguire 1 lettura dall’input e computarla, se si inseriscono degli input con una frequenza minore di 100 deltaT si avra’ la perdita di almeno 1 dato e poi a catena molti altri.
La macchina VM-1 che tratteremo non avra’ il dispositivo di input/output e potremo accedere liberamente alle celle 4094 (Input) e 4095 (output) simulando manualmente le operazioni di INPUT/OUTPUT.
CAPITOLO 2 La Macchina Virtuale VM-1 17
Capitolo 2
La Macchina Virtuale VM-1
La macchina VM-1 che si trattera’ e’ del tutto ipotetica ed inventata di sana pianta. Lo scopo di questo studio e’ quello di capire che una macchina piu’ complessa puo’, se organizzata bene, essere suddivisa in moduli; la si puo’ pensare come una scatola cinese al livello 2 la si apre e se ne trova una a livello 1.
Ogni modulo ha un compito ben preciso e nel nostro caso il compito del livello 1 (VM-1) e’ quello di microprogrammare la macchina al livello 2.
2.1 Organizzazione della Macchina Virtuale VM-1
L’organizzazione a livello di microarchitettura di una macchina VM-2 e’ suddivisa principalmente in 2 parti molto importanti [CHI96]:
CAPITOLO 2.1 Organizzazione della Macchina Virtuale VM-1 18
La macchina VM-1 si occupa proprio di gestire queste 2 parti e ha lo scopo di realizzare ‘fisicamente’ la macchina virtuale VM-2 descritta nel capitolo precedente.
Di solito la progettazione del DATA PATH e del CONTROLLO viene effettuata in modo separato anche perche’ prima occorre capire e definire che tipo di istruzioni si vuole far eseguire alla macchina VM-2 (come gia discusso nel capitolo precedente) e poi ‘pilotare’ i dispositivi in modo tale che i dati effettuano il percorso corretto. Durante tutto questo lavoro di progettazione a tavolino delle istruzioni, dei dispositvi, delle prestazioni, ecc. non e’ escluso che si debbano ritrattare scelte gia’ effettuate e ritenute giuste. Come in tutte le cose ci vuole un giusto compromesso, qui il compromesso e’ fra le istruzioni della nostra macchina VM-2 e la microprogrammazione della macchina VM-1 che ne deve gestire il funzionamento e la complessita’.
Prima di entrare nel dettaglio della struttura occorre chiariare gli aspetti del simbolismo usato:
Indica il numero di fili presenti (in questo caso 12);
Indica la bidirezionalita’ dei dati;
Indica la confluenza dei dati;
Indica gli ingressi del dispositivo;
Indica un registro con un certo numero di dati in ingresso e
uscita con l’ingresso del segnale di memorizzazione;
Indica il circuito incrementatore, somma al valore in ingresso 1 e lo restituisce in uscita;
Indica il dispositivo di tristate;
Indica il passaggio da n bit a (n-k) bit.
CAPITOLO 2.2 VM-1 Data Path 19
2.2 VM-1 Data Path
Di seguito troviamo la struttura completa del VM-1 Data Path ed e’ evidente come la macchina VM-2 e la macchina VM-1 siano intrecciate fra loro.
Figura 2.1: Il Data Path della macchina VM-1.
CAPITOLO 2.2 VM-1 Data Path 20
La struttura e’ composta, partendo da sinistra a destra per strisce longitudinali (quindi dall’alto verso il basso), da:
CAPITOLO 2.2 VM-1 Data Path 21
Queste informazioni sono essenziali alla parte di controllo della CPU perche’ garantiscono la corretta interpretazione delle istruzioni di salto.
Non presente visivamente nella figura 2.1 ma presente fisicamente e’ la RAM di sistema composta da celle di memoria con parole da 16 bit interconnessa al sistema dal BUS di comunicazione (abilitato mediante il settaggio a 1 di un bit particolare (CS)):
Vedremo in dettaglio nel paragrafo 2.4 la variazione del clock e la gestone del BUS di SISTEMA con le problematiche di sincronizzazione tra CPU e MEMORIA.
Passiamo ora a parlare del sistema di controllo dell’intera struttura.
CAPITOLO 2.3 VM-1 Control 22
2.3 VM-1 Control
Il lavoro di controllo della struttura viene effettuata dalla CPU che si occupa di eseguire le istruzioni per effettuare la gestione di tutti i dispositivi. Il fatto che la CPU debba eseguire delle microistruzioni indica che il controllo e’ microprogrammato questo implica l’esistenza di una macchina virtuale di livello 1 (VM-1) che esegue un microprogramma di emulazione delle istruzioni della macchina virtuale VM-2.
Questo come affrontato precedentemente porta dei notevoli vantaggi sia nella gestione di controllo sia nelle prestazioni sia nella organizzazione e nella definizione delle microistruzioni.
Un’esempio per tutti: e’ possibile ridefinire il funzionamento della macchina virtuale VM-2 lasciando inalterato l’hardware della macchina ma modificando soltanto il contenuto della control store.
Di seguito, nella figura 2.2, possiamo analizzare la struttura della parte di controllo della CPU:
Figura 2.2: VM-1 Control della macchina VM-1.
CAPITOLO 2.3 VM-1 Control 23
La struttura e’ composta da:
Questo dispositivo si occupa, a seconda delle varie informazioni in ingresso, di decidere quale sia il nuovo valore che il multiplexer (MPXM) deve fornire al MPC.
CAPITOLO 2.4 Il Clock e il BUS di sistema 24
2.4 Il Clock e il BUS di sistema
Il clock della macchina virtuale VM-1 e’ suddiviso in 4 fasi [CHI96] come si puo’ vedere nella figura 2.3 e questo dovuto al fatto che in ogni fase c’e’, per come e’ stata costruita la macchina, un qualche dispositivo che deve effettuare delle precise operazioni.
Figura 2.3: I segnali di Clock della macchina VM-1.
Quindi il susseguirsi del tempo nella macchina VM-1 e’ scandito dal passaggio delle varie fasi. Vediamo in dettaglio cosa accade ai dispositivi a seconda della fase di clock:
CAPITOLO 2.4 Il Clock e il BUS di sistema 25
Come si puo’ notare il clock con tutte le sue fasi giocano un ruolo molto importante per il perfetto funzionamento della struttura, la stessa importanza l’ha il BUS di sistema che per semplicita’ d’uso assumiamo di tipo SINCRONO [CHI96]. Il BUS che collega la CPU e la RAM e’ di tipo SINCRONO e per semplicita’ assumiamo che il Clock del Bus ed il Clock interno della CPU siano gli stessi anche se nella realta’ questo non capita quasi mai. Occorre pero’ generare il segnale del BUS Clock in maniera corretta e cioe’ sul pronte di salita della fase 3 del clock della CPU per poi passare a 0 nella fase 1 del clock della CPU. Questo lo otteniamo con un Flip-flop di tipo Set-Reset (figura 2.4 ).
Figura 2.4: Il segnale di BusClock della macchina VM-1.
L’utilita’ di sincronizzare i 2 clock, Bus Clock e Clock della CPU, e’ quello di poter effettuare la SCELTA del tipo di accesso alla memoria RAM tramite 1 solo bit (R/n W) da parte della CPU. Questo permette di evitare i controlli che si sarebbero dovuti effettuare nel caso di Bus ASINCONTRO (attesa del dato, ecc.).
Altro passo per il corretto funzionamento del sistema e’ quello di fornire il segnale di controllo Chip Select per l’ATTIVAZIONE del Bus di sistema per un ciclo di lettura e/o scrittura in memoria al momento esatto. Il segnale deve essere fornito dal registro MIR con l’uscita MIR.cs durante le fasi 1,2 e 3 del Clock interno della CPU. Il tutto viene gestito da un circuito sequenziale (figura 2.5) che in ingresso avra’ i seguenti segnali:
CAPITOLO 2.4 Il Clock e il BUS di sistema 26
Di seguito il circuito sequenziale in questione.
Figura 2.5: Il segnale di BusCS della macchina VM-1.
In questo modo viene realizzata la lettura di una cella di memoria RAM iniziando (startRD) la lettura nella fase 3 del Clock della CPU e terminandola (end RD) nella fase 3 del Clock della CPU. Viene utilizzato questo sistema per poter dare il tempo materiale ai dispositivi di effettuare la computazione in modo corretto cosi’ da essere sicuri di avere effettivamente in fase 3 del Clock CPU il valore desiderato. Tutto questo e’ funzionante ed esatto fin tanto che la somma dei ritardi dei dispositivi che entrano in gioco sono minori rispetto ad un completo ciclo di clock della CPU (si tratteranno piu’ avanti le problematiche derivanti dai ritardi dei vari dispositivi), in caso contrario si avrebbero dei risultati inattesi.
Rimane ancora da gestire la scrittura in RAM e questa e’ un po’ piu’ ‘delicata’ [CHI96]. Occorre realizzare un dispositivo sequenziale (figura 2.6) che fornisca in uscita (RAMStrobe) il valore corretto a seconda dei valori del Bus CS, del R/n W e del BUS Clock.
Figura 2.6: Il segnale RAMStrobe della macchina VM-1.
Il compito di questo dispositivo e’ di fornire 1 allo strobe della cella di memoria RAM selezionata dal decoder a 12 bit qualora vi sia stata una richiesta di scrittura. Fornira’ 1 subito dopo il fronte di salita del segnale del Bus CS ma non
CAPITOLO 2.4 Il Clock e il BUS di sistema 27
prima del fronte di discesa del Bus Clock per fornire 0 sul successivo fronte di salita del Bus Clock.
Per chiarire meglio tutto il funzionamento e sincronizzazione dei vari Bus ci puo’ essere di ottimo aiuto la seguente tabella (figura 2.7):
Figura 2.7: I segnali dei cicli di Lettura e Scrittura della macchina VM-1.
2.5 Il registro MIR e I segnali di Controllo.
Il registro MIR, come gia’ detto in precedenza, e’ composto da 33 bit e lo si puo’ paragonare ad uno smistatore di segnali di controllo. Possiamo cosi‘ raggruppare i bit con un nome in modo tale associare ad essi una precisa codifica. Come si puo’ vedere dalla figura 2.8 questa suddivisione e’ cosi definita:
CAPITOLO 2.5 Il registro MIR e i segnali di Controllo 28
Figura 2.8: I bit di controllo del registro MIR.
Vediamo ora in dettaglio, con l’ausilio anche delle figure, il significato dei vari bit di controllo utilizzati per controllare i dispositivi che costituiscono la CPU.
ALU (3 bit) |
Questi bit determinano quale operazione l’ALU deve effettuare. Il risultato sara’ disponibile sul BUS C dopo che i circuiti combinatori saranno stabili. 000 alu = ingr.a 001 alu = NOT ingr.a 010 alu = ingr.a<<1 (scorrimento a sinistra) 011 alu = ingr.a>>1 (scorrimento a destra) 100 alu = ingr.a + 1 101 alu = ingr.a - 1 110 alu = ingr.a + ingr.b 111 alu = ingr.a AND ingr.b |
|
CAPITOLO 2.5 Il registro MIR e i segnali di Controllo 29
CS (1 bit) |
Questo e’ il segnale di controllo CHIP SELECT per l’attivazione del BUS di Sistema per un ciclo di LETTURA o SCRITTURA di una cella di memoria RAM. 0 bus di sistema disabilitato; 1 bus di sistema attivato. |
|
|
R/nW (1 bit) |
Questo e’ il segnale di controllo per scegliere il tipo di accesso alla memoria RAM tramite il bus di sistema. 0 scrittura in memoria; 1 lettura dalla memoria. |
|
|
MAR (1 bit) |
Questo e’ il segnale di controllo che abilita o meno il registro MBR alla memorizzazione di un nuovo valore in combinazione con il valore del campo R/nW. 0 MAR mantiene il vecchio valore; 1 MAR carica il nuovo valore. |
|
|
MBR (1 bit) |
Questo e’ il segnale di controllo che abilita o meno il registro MAR alla memorizzazione del valore presente sul BUS A. 0 MBR mantiene il vecchio valore; 1 MBR carica il nuovo valore: - dai fili dati del bus di sistema, se R/nW=1 - dal BUS C, altrimenti |
|
CAPITOLO 2.5 Il registro MIR e i segnali di Controllo 30
Dmpx (2 bit) |
Questi bit gestiscono il segnale di controllo che comanda il multiplexer MPXD. Quest’ultimo ha il compito di fornire all’ingresso ‘a’ dell’ALU il valore prescelto. 00 ALU.ingr.a = Bus A 01 ALU.ingr.a = Bus D 10 ALU.ingr.a = MBR 11 ALU.ingr.a = campo Addr del registro MIR |
|
|
Abus (2 bit) |
Questi bit gestiscono il segnale di controllo che comanda la scelta di uno dei quattro registri a 12 bit (tramite i tristates) per la connessione al BUS A. 00 Bus A = PC (Program Counter) 01 Bus A = SP (Stack Pointer) 10 Bus A = FP (Frame Pointer) 11 Bus A = ADR (Auxiliary Address) |
|
|
Bbus (2 bit) |
Questi bit gestiscono il segnale di controllo che comanda la scelta di uno dei quattro registri a 16 bit (tramite i tristates) per la connessione al BUS B. 00 Bus B = IR (Instruction Register) 01 Bus B = ACC (Accumulatore) 10 Bus B = B (Auxiliary register B) 11 Bus B = C (Auxiliary register C) |
|
CAPITOLO 2.5 Il registro MIR e i segnali di Controllo 31
CAbus (2 bit) CAen (1 bit) |
Questi 2 bit gestiscono il segnale di controllo che comanda, quale tra i registri a 12 bit connessi al bus C, e’ predisposto per la memorizzazione. La memorizzazione viene effettuata in funzione del valore del bit CAen. CAbus: 00 PC <- Bus C (Program Counter) 01 SP <- Bus C (Stack Pointer) 10 FP <- Bus C (Frame Pointer) 11 ADR <- Bus C (Auxiliary Address) CAen: 0 mantiene il vecchio valore dei registri a 12 bit; 1 carica il nuovo valore presente sul Bus C nel registro a 12 bit individuato dal campo CAbus. |
|
|
CDbus (2 bit) CDen (1 bit) |
Questi 2 bit gestiscono il segnale di controllo che comanda, quale tra i registri a 16 bit connessi al bus C, e’ predisposto per la memorizzazione. La memorizzazione viene effettuata in funzione del valore del bit CAen. CDbus: 00 IR <- Bus C (Instruction Register) 01 ACC <- Bus C (Accumulatore) 10 B <- Bus C (Auxiliary register B) 11 C <- Bus C (Auxiliary register C) CDen: 0 mantiene il vecchio valore dei registri a 16 bit; 1 carica il nuovo valore presente sul Bus C nel registro a 16 bit individuato dal campo Cdbus. |
|
CAPITOLO 2.5 Il registro MIR e i segnali di Controllo 32
Dbus (2 bit) |
Questi bit gestiscono il segnale di controllo che comanda la scelta di uno dei quattro registri a 16 bit (tramite i tristates) per la connessione al BUS D. 00 Bus D = IR (Instruction Register) 01 Bus D = ACC (Accumulatore) 10 Bus D = B (Auxiliary register B) 11 Bus D = C (Auxiliary register C) |
|
|
Int (2 bit) |
Questi bit gestiscono il segnale di controllo che comanda l’Interrupt Unit. Quest’ultimo controlla le interruzioni (nella nostra macchina convenzionale non ne verra’ fatto uso qui lo si descrive solo per un discorso di completezza). 00 Interrupt no-op (non cambia lo stato rispetto alle interruzioni) 01 Interrupt reset (annulla le richieste e diventa insensibile) 10 Interrupt enable (diventa sensibile alle richieste) 11 Interrupt disable (diventa insensibile alle richieste) |
|
CAPITOLO 2.5 Il registro MIR e i segnali di Controllo 33
mcond (3 bit) |
Questi bit gestiscono il segnale di controllo che comanda il microSEQ. Quest’ultimo controlla la scelta della prossima microistruzione da eseguire (realizzata mediante la commutazione del multiplexer MPXM): 000 microcodice sequenziale (MPC = MPC + 1) 001 micro salto non condizionale (MPC = MIR.Addr) 010 micro salto condizionale N (if N then MPC = MIR.Addr else MPC = MPC + 1) 011 micro salto condizionale Z (if Z then MPC = MIR.Addr else MPC = MPC + 1) 100 reset microprogramma (MPC = 0) 101 L2 instruction decode (MPC = decode(Bus B)) 110 micro salto condizionale se Interrupt (if Interrupt then MPC = MIR.Addr else MPC = MPC + 1) |
|
|
Addr (7 bit) |
Questi bit forniscono al multiplexer MPXM l’indirizzo della prossima microistruzione da eseguire in caso di salto di microistruzione. 0000000 Indica l’indirizzo 0 della control store 0000001 Indica l’indirizzo 1 della control store ………. ………. 1111110 Indica l’indirizzo 126 della control store 1111111 Indica l’indirizzo 127 della control store |
|
CAPITOLO 2.6 La Control Store e il Microcodice 34
2.6 La Control Store e il Microcodice.
La control store e’ una memoria di sola lettura, come gia’ detto composta da 127 celle di memoria a 33 bit, contenente il microprogramma che verra’ eseguito a seconda delle istruzioni della macchina VM-2. Il contenuto di queste celle di memorie viene passato al registro MIR che si occupa di smistare i segnali di controllo dei dispositivi. Occorre prima di tutto inizializzare la macchina VM-2 per poi effettuare tutte quelle microistruzioni (dalla cella della controlo store 0 alla 5 della stessa) che consentono di eseguire quel semplice algoritmo di Inizializzazione, Fetch, Decodifica ed Esecuzione.
Il circuito di decodifica produce, a seconda dell’istruzione VM-2, un’indirizzo di Control Store rappresentato nella seguente tabella:
ISTRUZIONE VM-2 |
CONTROL STORE |
JPOS |
CELLA 32 |
JNEG |
CELLA 34 |
JZER |
CELLA 36 |
JNZE |
CELLA 38 |
LODD |
CELLA 40 |
ADDD |
CELLA 42 |
ANDD |
CELLA 44 |
STOD |
CELLA 46 |
LODL |
CELLA 48 |
ADDL |
CELLA 50 |
ANDL |
CELLA 52 |
STOL |
CELLA 54 |
JUMP |
CELLA 56 |
LDIX |
CELLA 58 |
CALL |
CELLA 60 |
LOC8 |
CELLA 96 |
LOCH |
CELLA 98 |
INSP |
CELLA 100 |
DESP |
CELLA 102 |
PUSH |
CELLA 104 |
PSHI |
CELLA 106 |
POP |
CELLA 108 |
POPI |
CELLA 110 |
CAPITOLO 2.6 La Control Store e il Microcodice 35
ISTRUZIONE VM-2 |
CONTROL STORE |
SWAS |
CELLA 112 |
SWAF |
CELLA 114 |
NEGA |
CELLA 116 |
SIGN |
CELLA 118 |
RETN |
CELLA 120 |
HALT |
CELLA 122 |
RSHF |
CELLA 124 |
LSHF |
CELLA 126 |
Ora vediamo come e’ definita l’intera control store. Alcune celle di memoria non sono state usate (ad esempio quelle che vanno dalla cella 6 alla cella 31) proprio perche’ non consideriamo e non gestiamo le interruzioni. In teoria per catturare e gestire le interruzioni occorrerebbe inserire il microcodice di gestione dalla cella 6 in poi, infatti nella cella 1 della control store si effettua il Fetch e se il bit che indica l’interruzione e’ impostato a true viene invocata la cella 6 per iniziare a gestire l’eccezione.
Sotto il dettaglio di tutta la control store.
Cella |
ALU |
CS |
R/nW |
MAR |
MBR |
Dmpx |
Abus |
Bbus |
CAbus |
CAen |
CDbus |
CDen |
Dbus |
Int |
mcond |
Addr |
Descrizione |
000 |
000 |
0 |
x |
0 |
0 |
11 |
xx |
xx |
00 |
1 |
xx |
0 |
xx |
01 |
000 |
0000000 |
RESET : PC=0; reset interrupt; MPC=MPC+1 |
001 |
xxx |
0 |
x |
0 |
0 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
110 |
0000110 |
FETCH : if Interrupt then goto 6 else MPC=MPC+1 |
002 |
100 |
1 |
1 |
1 |
0 |
00 |
00 |
xx |
00 |
1 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
MAR=PC; PC=PC+1; start read; MPC=MPC+1 |
003 |
xxx |
0 |
1 |
0 |
1 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
MBR=data bus; end read; MPC=MPC+1 |
004 |
000 |
0 |
x |
0 |
0 |
10 |
xx |
xx |
11 |
1 |
00 |
1 |
xx |
00 |
000 |
xxxxxxx |
IR=MBR; ADR=MBR; MPC=MPC+1 |
005 |
xxx |
0 |
x |
0 |
0 |
xx |
xx |
00 |
xx |
0 |
xx |
0 |
xx |
00 |
101 |
xxxxxxx |
MPC=decode(IR) |
006 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
007 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
008 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
009 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
010 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
CAPITOLO 2.6 La Control Store e il Microcodice 36
Cella |
ALU |
CS |
R/nW |
MAR |
MBR |
Dmpx |
Abus |
Bbus |
CAbus |
CAen |
CDbus |
CDen |
Dbus |
Int |
mcond |
Addr |
Descrizione |
011 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
012 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
013 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
014 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
015 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
016 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
017 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
018 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
019 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
020 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
021 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
022 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
023 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
024 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
025 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
026 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
027 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
028 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
029 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
030 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
031 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
032 |
000 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
xx |
0 |
01 |
00 |
010 |
0000001 |
JPOS : ALU=ACC; if N then goto 1 else MPC=MPC+1 |
033 |
000 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
00 |
1 |
xx |
0 |
00 |
00 |
001 |
0000001 |
PC=IR; goto 1 |
034 |
000 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
xx |
0 |
01 |
00 |
010 |
0100001 |
JNEG : ALU=ACC; if N then goto 33 else MPC=MPC+1 |
035 |
xxx |
0 |
x |
0 |
0 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
001 |
0000001 |
goto 1 |
036 |
000 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
xx |
0 |
01 |
00 |
011 |
0000001 |
JZER : ALU=ACC;i if Z then goto 33 else MPC=MPC+1 |
037 |
xxx |
0 |
x |
0 |
0 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
001 |
0000001 |
goto 1 |
038 |
000 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
xx |
0 |
01 |
00 |
011 |
0000001 |
JNZE :ALU=ACC;if Z then goto 1 else MPC=MPC+1 |
039 |
000 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
00 |
1 |
xx |
0 |
00 |
00 |
001 |
0000001 |
PC=IR; goto 1 |
040 |
xxx |
1 |
1 |
1 |
0 |
xx |
11 |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
LODD : MAR=ADR; start read; MPC=MPC+1 |
041 |
xxx |
0 |
1 |
0 |
1 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
001 |
0110001 |
MBR=data bus; end read; goto 49 |
042 |
xxx |
1 |
1 |
1 |
0 |
xx |
11 |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
ADDD : MAR=ADR; start read; MPC=MPC+1 |
043 |
xxx |
0 |
1 |
0 |
1 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
001 |
0110011 |
MBR=data bus; end read; goto 51 |
CAPITOLO 2.6 La Control Store e il Microcodice 37
Cella |
ALU |
CS |
R/nW |
MAR |
MBR |
Dmpx |
Abus |
Bbus |
CAbus |
CAen |
CDbus |
CDen |
Dbus |
Int |
mcond |
Addr |
Descrizione |
044 |
xxx |
1 |
1 |
1 |
0 |
xx |
11 |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
ANDD : MAR=ADR; start read; MPC=MPC+1 |
045 |
xxx |
0 |
1 |
0 |
1 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
001 |
0110101 |
MAR=data bus; end read; goto 53 |
046 |
000 |
1 |
0 |
1 |
1 |
01 |
11 |
xx |
xx |
0 |
xx |
0 |
01 |
00 |
000 |
xxxxxxx |
STOD : MAR=ADR; MBR=ACC; start write; MPC=MPC+1 |
047 |
xxx |
0 |
0 |
0 |
0 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
001 |
0000001 |
end write; goto 1 |
048 |
110 |
0 |
x |
0 |
0 |
00 |
10 |
00 |
11 |
1 |
xx |
0 |
xx |
00 |
001 |
0101000 |
LODL : ADR=FP+IR; goto 40 |
049 |
000 |
0 |
x |
0 |
0 |
10 |
xx |
xx |
xx |
0 |
01 |
1 |
xx |
00 |
001 |
0000001 |
ACC=MBR; goto 1 |
050 |
110 |
0 |
x |
0 |
0 |
00 |
10 |
00 |
11 |
1 |
xx |
0 |
xx |
00 |
001 |
0101010 |
ADDL : ADR=FP+IR; goto 42 |
051 |
110 |
0 |
x |
0 |
0 |
10 |
xx |
01 |
xx |
0 |
01 |
1 |
xx |
00 |
001 |
0000001 |
ACC =MBR+ACC;goto 1 |
052 |
110 |
0 |
x |
0 |
0 |
00 |
10 |
00 |
11 |
1 |
xx |
0 |
xx |
00 |
001 |
0101100 |
ANDL : ADR=FP+IR; goto 44 |
053 |
111 |
0 |
x |
0 |
0 |
10 |
xx |
01 |
xx |
0 |
01 |
1 |
xx |
00 |
001 |
0000001 |
ACC=MBR AND ACC; goto 1 |
054 |
110 |
0 |
x |
0 |
0 |
00 |
10 |
00 |
11 |
1 |
xx |
0 |
xx |
00 |
001 |
0101110 |
STOL : ADR=FP+IR; goto 46 |
055 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
056 |
000 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
00 |
1 |
xx |
0 |
00 |
00 |
001 |
0000001 |
JUMP : PC=IR; goto 1 |
057 |
xxx |
0 |
x |
0 |
0 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
00 |
00 |
001 |
0000001 |
goto 1 |
058 |
110 |
0 |
x |
0 |
0 |
01 |
xx |
00 |
11 |
1 |
xx |
0 |
01 |
00 |
001 |
0101000 |
LDIX : ADR=ACC+IR; goto 40 |
059 |
xxx |
0 |
x |
0 |
0 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
00 |
00 |
001 |
0000001 |
goto 1 |
060 |
000 |
0 |
0 |
0 |
1 |
00 |
10 |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
CALL : MBR=FP; MPC=MPC+1 |
061 |
101 |
1 |
0 |
1 |
0 |
00 |
01 |
xx |
01 |
1 |
10 |
1 |
xx |
00 |
000 |
xxxxxxx |
MAR=SP; SP=B=SP-1; start write; MPC=MPC+1 |
062 |
000 |
0 |
0 |
0 |
1 |
00 |
00 |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
MBR=PC; end write; MPC=MPC+1 |
063 |
100 |
1 |
0 |
1 |
0 |
01 |
01 |
xx |
10 |
1 |
xx |
0 |
10 |
00 |
000 |
xxxxxxx |
MAR=SP; FP=B+1; start write; MPC=MPC+1 |
064 |
101 |
0 |
0 |
0 |
0 |
00 |
01 |
xx |
01 |
1 |
xx |
0 |
xx |
00 |
001 |
0111000 |
SP=SP-1; end write; goto 56 |
065 |
111 |
0 |
x |
0 |
0 |
01 |
xx |
10 |
xx |
0 |
01 |
1 |
00 |
00 |
001 |
0000001 |
ACC=IR AND B; goto 1 |
066 |
010 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
01 |
1 |
10 |
00 |
000 |
xxxxxxx |
B=B<<1; MPC=MPC+1 |
067 |
010 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
01 |
1 |
10 |
00 |
000 |
xxxxxxx |
B=B<<1; MPC=MPC+1 |
068 |
010 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
01 |
1 |
10 |
00 |
000 |
xxxxxxx |
B=B<<1; MPC=MPC+1 |
CAPITOLO 2.6 La Control Store e il Microcodice 38
Cella |
ALU |
CS |
R/nW |
MAR |
MBR |
Dmpx |
Abus |
Bbus |
CAbus |
CAen |
CDbus |
CDen |
Dbus |
Int |
mcond |
Addr |
Descrizione |
069 |
010 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
01 |
1 |
10 |
00 |
000 |
xxxxxxx |
B=B<<1; MPC=MPC+1 |
070 |
010 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
01 |
1 |
10 |
00 |
000 |
xxxxxxx |
B=B<<1; MPC=MPC+1 |
071 |
010 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
01 |
1 |
10 |
00 |
000 |
xxxxxxx |
B=B<<1; MPC=MPC+1 |
072 |
010 |
0 |
x |
0 |
0 |
11 |
xx |
xx |
xx |
0 |
11 |
1 |
xx |
00 |
000 |
1111111 |
C=0000000011111110; MPC=MPC+1 |
073 |
100 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
11 |
1 |
11 |
00 |
000 |
xxxxxxx |
C=C+1; MPC=MPC+1 |
074 |
111 |
0 |
x |
0 |
0 |
01 |
xx |
11 |
xx |
0 |
01 |
1 |
01 |
00 |
000 |
xxxxxxx |
ACC=ACC AND C; MPC=MPC+1 |
075 |
110 |
0 |
x |
0 |
0 |
01 |
xx |
10 |
xx |
0 |
01 |
1 |
01 |
00 |
001 |
0000001 |
ACC=ACC+B; goto 1 |
076 |
111 |
0 |
x |
0 |
0 |
01 |
xx |
10 |
xx |
0 |
10 |
1 |
00 |
00 |
000 |
xxxxxxx |
B=IR AND B; MPC=MPC+1 |
077 |
110 |
0 |
x |
0 |
0 |
00 |
01 |
10 |
01 |
1 |
xx |
0 |
xx |
00 |
001 |
0000001 |
SP=SP+B; goto 1 |
078 |
111 |
0 |
x |
0 |
0 |
01 |
xx |
10 |
xx |
0 |
10 |
1 |
00 |
00 |
000 |
xxxxxxx |
B=IR AND B; MPC=MPC+1 |
079 |
001 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
10 |
1 |
10 |
00 |
000 |
xxxxxxx |
B=NOT B; MPC=MPC+1 |
080 |
100 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
10 |
1 |
10 |
00 |
001 |
1001101 |
B=B+1; goto 77 |
081 |
xxx |
0 |
1 |
0 |
1 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
MBR=data bus; end read; MPC=MPC+1 |
082 |
101 |
1 |
0 |
1 |
0 |
00 |
01 |
xx |
01 |
1 |
xx |
0 |
xx |
00 |
001 |
0101111 |
MAR=SP; SP=SP-1; start write; goto 47 |
083 |
xxx |
0 |
1 |
0 |
1 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
MBR=data bus; end read; MPC=MPC+1 |
084 |
000 |
0 |
x |
0 |
0 |
10 |
xx |
xx |
xx |
0 |
01 |
1 |
xx |
00 |
001 |
0000001 |
ACC=MBR; goto 1 |
085 |
xxx |
0 |
1 |
0 |
1 |
01 |
xx |
xx |
11 |
1 |
xx |
0 |
01 |
00 |
000 |
xxxxxxx |
MBR=data bus; end read; ADR=ACC; MPC=MPC+1 |
086 |
xxx |
1 |
0 |
1 |
0 |
xx |
11 |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
MAR=ADR; start write; MPC=MPC+1 |
087 |
xxx |
0 |
x |
0 |
0 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
001 |
0000001 |
end write; goto 1 |
088 |
000 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
01 |
1 |
10 |
00 |
001 |
0000001 |
ACC=B; goto 1 |
089 |
xxx |
0 |
1 |
0 |
1 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
MBR=data bus; end read; MPC=MPC+1 |
090 |
000 |
1 |
1 |
1 |
0 |
10 |
01 |
xx |
00 |
1 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
PC=MBR; MAR=SP; start read; MPC=MPC+1 |
091 |
xxx |
0 |
1 |
0 |
1 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
MBR=data bus; end read; MPC=MPC+1 |
092 |
000 |
0 |
x |
0 |
0 |
10 |
xx |
xx |
10 |
1 |
xx |
0 |
xx |
00 |
001 |
0000001 |
FP=MBR; goto 1 |
093 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
094 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
095 |
xxx |
x |
x |
x |
x |
xx |
xx |
xx |
xx |
x |
xx |
x |
xx |
xx |
xxx |
xxxxxxx |
Free |
CAPITOLO 2.6 La Control Store e il Microcodice 39
Cella |
ALU |
CS |
R/nW |
MAR |
MBR |
Dmpx |
Abus |
Bbus |
CAbus |
CAen |
CDbus |
CDen |
Dbus |
Int |
mcond |
Addr |
Descrizione |
096 |
010 |
0 |
x |
0 |
0 |
11 |
xx |
xx |
xx |
0 |
10 |
1 |
xx |
00 |
000 |
1111111 |
LOC8 : B=0000000011111110; MPC=MPC+1 |
097 |
100 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
10 |
1 |
10 |
00 |
001 |
1000001 |
B=B+1; goto 65 |
098 |
010 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
10 |
1 |
00 |
00 |
000 |
xxxxxxx |
LOCH : B=IR<<1; MPC=MPC+1 |
099 |
010 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
10 |
1 |
10 |
00 |
001 |
1000010 |
B=B<<1; goto 66 |
100 |
010 |
0 |
x |
0 |
0 |
11 |
xx |
xx |
xx |
0 |
10 |
1 |
xx |
00 |
000 |
1111111 |
INSP : B=0000000011111110; MPC=MPC+1 |
101 |
100 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
10 |
1 |
10 |
00 |
001 |
1001100 |
B=B+1; goto 76 |
102 |
010 |
0 |
x |
0 |
0 |
11 |
xx |
xx |
xx |
0 |
10 |
1 |
xx |
00 |
000 |
1111111 |
DESP : B=0000000011111110; MPC=MPC+1 |
103 |
100 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
10 |
1 |
10 |
00 |
001 |
1001110 |
B=B+1; goto 78 |
104 |
000 |
1 |
0 |
1 |
1 |
01 |
01 |
xx |
xx |
0 |
xx |
0 |
01 |
00 |
000 |
xxxxxxx |
PUSH : MAR=SP; MBR=ACC; start write; MPC=MPC+1 |
105 |
101 |
0 |
0 |
0 |
0 |
00 |
01 |
xx |
01 |
1 |
xx |
0 |
xx |
00 |
001 |
0000001 |
SP=SP-1; end write; goto 1 |
106 |
000 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
11 |
1 |
xx |
0 |
01 |
00 |
000 |
xxxxxxx |
PSHI : ADR=ACC; MPC=MPC+1 |
107 |
xxx |
1 |
1 |
1 |
0 |
xx |
11 |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
001 |
1010001 |
MAR=ADR; start read; goto 81 |
108 |
100 |
0 |
x |
0 |
0 |
00 |
01 |
xx |
01 |
1 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
POP : SP=SP+1; MPC=MPC+1 |
109 |
xxx |
1 |
1 |
1 |
0 |
xx |
01 |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
001 |
1010011 |
MAR=SP; start read; goto 83 |
110 |
100 |
0 |
x |
0 |
0 |
00 |
01 |
xx |
01 |
1 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
POPI : SP=SP+1; MPC=MPC+1 |
111 |
xxx |
1 |
1 |
1 |
0 |
xx |
01 |
xx |
xx |
0 |
xx |
0 |
xx |
00 |
001 |
1010101 |
MAR=SP; start read; goto 85 |
112 |
000 |
0 |
x |
0 |
0 |
00 |
01 |
xx |
xx |
0 |
10 |
1 |
xx |
00 |
000 |
xxxxxxx |
SWAS : B=0000(SP); MPC=MPC+1 |
113 |
000 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
01 |
1 |
10 |
0 |
01 |
00 |
001 |
1011000 |
SP=ACC; goto 88 |
114 |
000 |
0 |
x |
0 |
0 |
00 |
10 |
xx |
xx |
0 |
10 |
1 |
xx |
00 |
000 |
xxxxxxx |
SWAF : B=0000(FP); MPC=MPC+1 |
115 |
000 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
10 |
1 |
10 |
0 |
01 |
00 |
001 |
1011000 |
FP=ACC; goto 88 |
116 |
001 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
01 |
1 |
01 |
00 |
000 |
xxxxxxx |
NEGA : ACC=NOT ACC; MPC=MPC+1 |
117 |
xxx |
0 |
x |
0 |
0 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
00 |
00 |
001 |
1110101 |
goto 117 |
118 |
001 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
01 |
1 |
01 |
00 |
000 |
xxxxxxx |
SIGN : ACC=NOT ACC; MPC=MPC+1 |
119 |
100 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
01 |
1 |
01 |
00 |
001 |
0000001 |
ACC=ACC+1; goto 1 |
120 |
101 |
0 |
x |
0 |
0 |
00 |
10 |
xx |
11 |
1 |
xx |
0 |
xx |
00 |
000 |
xxxxxxx |
RETN : ADR=FP-1; MPC=MPC+1 |
CAPITOLO 2.6 La Control Store e il Microcodice 40
121 |
100 |
1 |
1 |
1 |
0 |
00 |
11 |
xx |
01 |
1 |
xx |
0 |
xx |
00 |
001 |
1011001 |
MAR=ADR; SP=ADR+1; start read; goto 89 |
122 |
xxx |
0 |
x |
0 |
0 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
00 |
00 |
000 |
xxxxxxx |
HALT : MPC=MPC+1 |
123 |
xxx |
0 |
x |
0 |
0 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
00 |
00 |
001 |
1111011 |
goto 123 |
124 |
011 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
01 |
1 |
01 |
00 |
000 |
xxxxxxx |
RSHF : ACC=ACC>>1; MPC=MPC+1 |
125 |
xxx |
0 |
x |
0 |
0 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
00 |
00 |
001 |
0000001 |
goto 1 |
126 |
010 |
0 |
x |
0 |
0 |
01 |
xx |
xx |
xx |
0 |
01 |
1 |
01 |
00 |
000 |
xxxxxxx |
LSHF : ACC=ACC<<1; MPC=MPC+1 |
127 |
xxx |
0 |
x |
0 |
0 |
xx |
xx |
xx |
xx |
0 |
xx |
0 |
00 |
00 |
001 |
0000001 |
goto 1 |
Come si puo’ notare le istruzioni VM-2 non sono state codificate a caso nella Control Store ma mappate in modo opportuno seguendo un algoritmo ben preciso. L’idea e’ quella di associare alla codifica binaria dell’istruzione VM-2 un procedimento automatico per cui si ottengano di 2 celle in 2 celle le microistruzioni preposte alla realizzazione delle istruzioni VM-2. Occorre subito fare la distinzione fra le istruzioni VM-2 a 4 o 8 bit in modo tale da applicare l’algoritmo 1 per le istruzioni a 4 bit mentre l’algoritmo 2 per le istruzioni a 8 bit.
Come si e’ visto nel capitolo 1 la ram della macchina VM-2 utilizza parole a 16 bit quindi quando ci riferiamo ad istruzioni VM-2 a 4 bit si intende 4 bit di codifica istruzione + 12 bit per l’operando idem per il caso a 8 bit si intende 8 bit di codifica istruzione + 8 bit per l’operando.
Da sottolineare, nel caso del secondo algoritmo dell'utilizzo dei 4 bit meno significativi del codice istruzione.
ALGORITMO 1 (Istruzioni a 4 bit):
indirizzo CS = (codice operazione)*2+32 (quindi 1 opcod 0)
Ex. Istruzione CALL (‘1110’=14)
L’indirizzo della control store sara’ dato da: (14*2)+32=60
ALGORITMO 2 (Istruzioni a 8 bit):
indirizzo CS = (4 bit meno significativi del codice operazione)*2+96
(quindi 11 opcod 0)
Ex. Istruzione POP (‘1111 0110’) i 4 bit meno significativi sono ‘0110’=6
L’indirizzo della control store sara’ dato da: (6*2)+96=108
CAPITOLO 3 Problematiche del Progetto 41
Capitolo 3
Problematiche del Progetto
In questo capitolo si affronteranno le varie problematiche che si sono incontrate nella realizzazione del simulatore VM-1.
Nella realizzazione software del simulatore hardware si e' dovuto tenere in considerazione l'interazione di tutti i dispositivi, dei tempi di risposta (ritardi) e del fatto che hardware funziona in modo parallelo mentre un programma informatico, in linea di massima, ha un funzionamento sequenziale.
Come si sa bene un programma puo' essere parallelo o sequenziale a seconda del software a disposizione e della piattaforma sottostante ma nel nostro caso, usando un browser, applet java, javascript l'esecuzione e' sequenziale. Questo ci obbliga a seguire una cerca logica nel caso in cui i ritardi dei dispositivi siano zero in quanto il valore e’ immediatamente disponibile.
3.1 L’implementazione dei dispositivi
Nella scelta delle strutture dei dispositivi hanno pesato le caratteristiche ed il funzionamento dei singoli elementi. Ogni dispositivo e’ stato rappresentato come un oggetto con dei campi indicanti gli ingressi, le uscite ed il ritardo.
CAPITOLO 3.1 L’implementazione dei dispositivi 42
Possiamo avere un’idea piu’ chiara sulla tipologia dei dispositivi riferendoci alle figure 3.1 (circuito COMBINATORIO) e 3.2 (circuito SEQUENZIALE)
Figura 3.1: Circuito COMBINATORIO.
Figura 3.2: Circuito SEQUENZIALE.
La differenza essenziale fra i due dispositivi e’ che ad una variazione in ingresso del dispositivo combinatorio corrisponde ad una computazione immediata (modulo il ritardo) in uscita, mentre il dispositivo sequenziale (ad esempio un registro) memorizza in entrata il valore al momento della variazione clock iniziado a computare mentre qualsiasi altra variazione in ingresso viene ignorata. Il valore Old sara’ identico al valore NEXT solo dopo aver atteso to+rit per il circuito combinatorio e tck+rit per il circuito sequenziale.
Per effettuare piu’ facilmente la gestione dei dispositivi si e’ pensato di inglobare nella struttura anche il ritardo in modo tale da assegnare il valore di
CAPITOLO 3.1 L’implementazione dei dispositivi 43
delay del dispositivo all’inizio della fase in cui entra in funzione o quando vi e’ una variazione di ingresso; questo per poter decrementare di 1 unita’ tempo il campo rit al variare del deltaT. Nel momento in cui il valore del campo rit e’ zero il valore in ingresso, cioe’ quello presente nel campo next nei dispositivi che lo hanno, viene portato in uscita nel campo old questo perche’ il dispositivo ha effettuato la computazione.
Entriamo ora nel dettaglio dei singoli dispositivi in modo da chiarire ogni dubbio sui singoli campi degli oggetti:
REGISTRI:
myPC.dacambiare=false;
myPC.next = 0;
myPC.old = 0;
myPC.rit=0;
myFP.dacambiare=false;
myFP.next = 0;
myFP.old = 0;
myFP.rit=0;
mySP.dacambiare=false;
mySP.next = 0;
mySP.old = 0;
mySP.rit=0;
myADR.dacambiare=false;
myADR.next = 0;
myADR.old = 0;
myADR.rit=0;
myIR.dacambiare=false;
myIR.next = 0;
myIR.old = 0;
myIR.rit=0;
myACC.dacambiare=false;
myACC.next = 0;
myACC.old = 0;
myACC.rit=0;
myB.dacambiare=false;
myB.next = 0;
myB.old = 0;
myB.rit=0;
myC.dacambiare=false;
myC.next = 0;
myC.old = 0;
myC.rit=0;
CAPITOLO 3.1 L’implementazione dei dispositivi 44
Il campo dacambiare indica se il dispositivo e’ in fase di esecuzione.
Questo campo permette al simulatore di decrementare il valore del campo rit fino a zero in modo tale poi da:
I valori all’interno dei campi sono tutti di tipo intero.
Se per qualsiasi motivo nel frattempo c’e’ stata una qualsiasi variazione in ingresso il valore fornito in uscita sara’ il valore iniziale (cioe’ quello presente all’inizio della computazione) e mai l’ultimo questo perche’ i registri sono sincroni di tipo D quindi memorizzano il valore durante la variazione di fase (fase 3).
myCSOUT.dacambiare=false;
myCSOUT.next = 0;
myCSOUT.old = 0;
myCSOUT.rit=0;
myMPC.dacambiare=false;
myMPC.next = 0;
myMPC.old = 0;
myMPC.rit=0;
myMIR.dacambiare=false;
myMIR.next = 0;
myMIR.old = 0;
myMIR.rit=0;
Il loro funzionamento e gestione viene effettuata come nei registri precedenti c’e’ solo da focalizzare l’attenzione sul dispositivo CSOUT che identifica la cella di CONTROL STORE indicata dal MPC il cui valore deve essere passato al MIR in fase 1.
E’ stato aggiunto alla nostra struttura il dispositivo virtuale CSOUT in modo tale da simulare piu’ fedelmente il funzionamento dell’hardware dando quindi anche un tempo di ritardo alla CONTROL STORE. Questo fara’ si di avere a disposizione il contenuto della cella indicata dal MPC solo dopo un certo tempo deltaT.
CAPITOLO 3.1 L’implementazione dei dispositivi 45
myMAR.dacambiare=false;
myMAR.next = 0;
myMAR.old = 0;
myMAR.rit=0;
myMAR.mar=0;
myMBR.dacambiare=false;
myMBR.next = 0;
myMBR.old = 0;
myMBR.rit=0;
myMBR.mbr=0;
myMBR.rw=0;
La loro gestione e’ identica ai registri ma quello che qui spicca sono:
DEMULTIPLEXER/MULTIPLEXER:
myDpxCA.dacambiare = false;
myDpxCA.CAbus = 0;
myDpxCA.old = 0;
myDpxCA.rit=0;
myDpxCA.en=0;
myDpxCD.dacambiare = false;
myDpxCD.CDbus = 0;
myDpxCD.old = 0;
myDpxCD.rit=0;
myDpxCD.en=0;
Anche in questo caso vengono gestiti come gli altri dispositivi con un’attenzione particolare ai campi CAbus, CDbus, old e en perche’:
CAPITOLO 3.1 L’implementazione dei dispositivi 46
myMPXM.dacambiare= false;
myMPXM.next = 0;
myMPXM.old = 0;
myMPXM.rit=0;
myMPXD.dacambiare=false;
myMPXD.Dmpx=0;
myMPXD.next = 0;
myMPXD.old = 0;
myMPXD.rit=0;
Stesso funzionamento descritto per gli altri dispositivi, cioe’ quando il campo rit e’ uguale a zero setto il valore di uscita uguale al valore di entrata.
Il campo Dmpx del MPXD indica in formato decimale quale valore deve essere fornito in uscita fra i valori dei 4 canali disponibili.
Se per qualche ragione il valore di ingresso di uno o di tutti e 2 i dispositivi variasse durante il funzionamento (cioe’ campo dacambiare=true) verrebbe ripristinato immediatamente il DELAY del dispositivo per ri-iniziare la computazione ed avere in uscita al dispositivo l’ultimo valore arrivato in ingresso.
DECODIFICATORI:
myDecA.dacambiare = false;
myDecA.Abus = 0;
myDecA.old = 0;
myDecA.rit=0;
myDecB.dacambiare = false;
myDecB.Bbus = 0;
myDecB.old = 0;
myDecB.rit=0;
myDecD.dacambiare = false;
myDecD.Dbus = 0;
myDecD.old = 0;
myDecD.rit=0;
Anche qui i dispositivi vengono trattati come sopra vale a dire che il valore nuovo viene fornito in uscita dopo un certo deltaT (ritardo del dispositivo).
CAPITOLO 3.1 L’implementazione dei dispositivi 47
myDEC.dacambiare=false;
myDEC.next = 0;
myDEC.old = 0;
myDEC.rit=0;
mymSEQ.dacambiare=false;
mymSEQ.N=0;
mymSEQ.Z=0;
mymSEQ.mcond = 0;
mymSEQ.old = 0;
mymSEQ.rit=0;
Anche qui i campi vengono trattati come per gli altri dispositivi c’e’ solo da sottolineare che vengono riportati in ingresso del micro SEQ i bit N e Z collegati all’ALU. Altra considerazione: non trattiamo le interruzioni come detto nel capitolo precedente qualora ci fossero state avremmo avuto in ingresso anche il bit di controllo delle interruzioni.
Da notare anche che NON si e’ implementato il dispositivo ‘interrupt unit’ quindi i bit derivanti dal MIR.int non vengono ne trattati ne considerati.
TRISTATES:
myTRISET.dacambiare1=false;
myTRISET.dacambiare2=false;
myTRISET.reg1=-1;
myTRISET.val1=0;
myTRISET.tri1=0;
myTRISET.reg2=-1;
myTRISET.val2=0;
myTRISET.tri2=0;
myTRISET.tri3=0;
myTRISET.rit=0;
Questa struttura benche’ sembri complessa e’ molto facile da comprendere, infatti si possono dividere virtualmente i tristates in 2 gruppi: il primo, composto da 4 tristates, opera a stretto contatto con i registri PC, SP, FP e ADR; il secondo gruppo, composto da 8 tristates, opera a stretto contatto con i registri IR, ACC, B e C.
La struttura e’ stata organizzata in questo modo per poter evitare di creare e di gestire 12 oggetti distinti, tanti quanti sono i tristates presenti nell’architettura.
CAPITOLO 3.1 L’implementazione dei dispositivi 48
I campi dacambiare1 e dacambiare2 indicano quale gruppo di tristates ha avuto una variazione in ingresso e quindi il gruppo che deve computare il risultato mentre i campi reg1 e reg2 indicano quali registri hanno avuto la variazione in uscita questo perche’ la variazione si ripercuote sul tristate. Ovviamente se la selezione dei tristates corrisponde al registro che ha avuto la variazione questa dovra’ ripercuotersi anche sul bus corrispondente e poi a seguire tutti i dispositivi che hanno il ‘canale aperto’.
Per effettuare tutti questi controlli occorre avere a disposizione le informazioni di selezione dei tristates e dei valori di uscita dai registri, informazioni contenute nei campi tri1, tri2, tri3 e val1, val2.
ALU:
myALU.dacambiare=false;
myALU.a=0;
myALU.b=0;
myALU.N=0;
myALU.Z=0;
myALU.alu = 0;
myALU.old = 0;
myALU.rit=0;
Questo dispositivo, come e’ semplice intuire, ha in ingresso (campo a) i dati provenienti o dal Bus A o dal Bus D o dal MIR.addr, (campo b) i dati provenienti dal Bus B, (campo alu) la computazione che l’ALU deve effettuare e in uscita nel campo old il valore derivante dalla computazione e nei campi N e Z rispettivamente l’indicazione se il valore in uscita NEGATIVO e se il valore in uscita uguale a ZERO.
Gli altri campi gestiti come nei dispositivi precedenti.
CLOCK:
Il clock del sistema e’ stato implementato con 4 variabili globali myCLOCK, myPh e myDELTA rispettivamente i colpi di clock, la fase attuale, il delta attuale.
L’avanzamento del simulatore puo’ avvenire per At (deltaT), o per fasi o per clock nel caso che si avanzi per At si avra’ il passaggio alla fase successiva dopo 10 deltaT mentre si avra’ il passaggio al clock successivo dopo 4 fasi.
CAPITOLO 3.2 I ritardi dei dispositivi 49
3.2 I ritardi dei dispositivi
Ogni dispositivo facente parte del nostro simulatore ha un ritardo di esecuzione programmabile dovuto al passaggio, e alla computazione, del valore in ingresso verso l’uscita. Nel nostro sistema l’unica entita’ che non ha ritardi e’ la RAM della macchina VM-2. Infatti si e’ deciso di rendere attivo, qualora sia richiesto, il Bus di Sistema all’inizio della fase 4 in modo tale di aver il dato disponibile (se e’ una lettura) o di effettuare l’operazione (se e’ una scrittura) in fase 3. Quindi se proprio vogliamo vedere il ritardo della RAM potremmo considerarlo fisso a un valore che va dalla fase 4 alla fase 3.
Il meccanismo di funzionamento dei ritardi e’ il seguente:
Qui sotto viene riportata una tabella riassuntiva della tipologia di dispositivi e dei ritardi ad essi associati.
Nome dispositivo |
Tipo dispositivo |
Tipo del ritardo |
PC |
REGISTRO |
REGDELAY |
SP |
REGISTRO |
REGDELAY |
FP |
REGISTRO |
REGDELAY |
ADR |
REGISTRO |
REGDELAY |
IR |
REGISTRO |
REGDELAY |
ACC |
REGISTRO |
REGDELAY |
B |
REGISTRO |
REGDELAY |
C |
REGISTRO |
REGDELAY |
MPC |
REGISTRO |
REGDELAY |
MIR |
REGISTRO |
REGDELAY |
MAR |
REGISTRO |
REGDELAY |
MBR |
REGISTRO |
REGDELAY |
CAPITOLO 3.2 I ritardi dei dispositivi 50
Nome dispositivo |
Tipo dispositivo |
Tipo del ritardo |
CSOUT |
REGISTRO CS |
CSDELAY |
DpxCD |
DEMULTIPLEXER |
MPXDELAY |
DpxCA |
DEMULTIPLEXER |
MPXDELAY |
MPXD |
MULTIPLEXER |
MPXDELAY |
MPXM |
MULTIPLEXER |
MPXDELAY |
TRI1~TRI12 |
TRISTATES |
TRIDELAY |
DecA |
DECODIFICATORE |
DECDELAY |
DecD |
DECODIFICATORE |
DECDELAY |
DecB |
DECODIFICATORE |
DECDELAY |
DEC |
DECODIFICATORE |
DECDELAY |
mSEQ |
DECODIFICATORE |
DECDELAY |
ALU |
CIRC. COMBINAT. |
ALUDELAY |
Nell’esecuzione del simulatore occorre porre particolare attenzione alla scelta dei ritardi dei dispositivi perche’ un tempo errato potrebbe portare al non funzionamento del sistema oppure a risultati inattesi. Una volta caricato nel simulatore un programma VM-2 per assicurarsi che il programma sia corretto e’ preferibile impostare tutti i ritardi a 0.
Questo fa si che, siccome nell’implementazione e’ stato tenuto conto della priorita’ di percorso dei dati, sicuramente la computazione verra’ portata a termine con i valori desiderati. Sara’ opportuno in un secondo tempo variare i ritardi per analizzare il comportamento di ogni singolo componente, ferma restando la correttezza della computazione.
Fermo restando che per compiere una fase di clock occorre effettuare 10 deltaT alcuni valori di ritardi corretti per la computazione sono:
Figura 3.3 a) - b): Esempi di ritardi corretti.
CAPITOLO 3.2 I ritardi dei dispositivi 51
Ovviamente vanno bene tutti i ritardi piccoli o nulli, ad esempio tutti 0 oppure tutti 1 oppure tutti 2.
Vediamo un caso molto semplice: il passaggio del contenuto della control store al MIR. In fase 4 il MPC viene attivato e inizia la computazione dopo un certo ritardo (supponiamo 4 deltaT) fornisce la locazione da caricare alla control store e solo a questo punto la control store si attiva per fornire in uscita, dopo un certo ritardo (supponiamo x deltaT), il contenuto della cella di memoria. Supponiamo anche che tutti gli altri ritardi siano impostati a zero.
Ora analizziamo x:
Sotto, in figura 3.4 un’esempio di ritardi non corretti.
Figura 3.4 a) - b): Esempi di ritardi non corretti.
CAPITOLO 3.3 L’interazione logica fra i dispositivi 52
3.3 L’interazione logica fra i dispositivi
Nel capitolo 2 abbiamo parlato della struttura della macchina VM-2 specificando tutti i dispositivi presenti e visualizzando, come si puo’ vedere nella figura 2.1 (il Data Path della macchina VM-1) e figura 2.2 (VM-1 Control della macchina VM-1), la loro connessione a tutti il sistema.
Ora entriamo nel dettaglio del funzionamento specificando cosa accade se un determinato dispositivo fornisce in uscita un nuovo valore.
La macchina VM-1 inizia la propria computazione in fase 4 vale a dire quando il MPC deve memorizzare il valore in entrata (valore fornito dal MPXM nel campo old) e portarlo in uscita. Il valore sara’ reso disponibile solo dopo che il ritardo del dispositivo e’ stato ‘consumato’. A questo punto il valore viene passato al CSOUT che verra’ abitilitato in modo tale che dopo aver consumato il proprio ritardo, fornisca in uscita il contenuto della cella di Control Store indicata dal valore di MPC.
Nel campo old del CSOUT si ha il valore che il MIR dovra’ memorizzare per poi passare ai vari dispositivi.
Poniamo la massima attenzione a questo livello di interazione.
Il valore fornito dal CSOUT viene passato dal simulatore al campo next del MIR solo all’inizio della fase 1 perche’ solo allora il MIR memorizza in entrata il valore iniziando la computazione, quindi dobbiamo essere sicuri che il valore corretto sia presente prima della fase 1.
Qui entrano in gioco i ritardi visto che ogni fase corrisponde a 10 deltaT e i ritardi li esprimiamo in deltaT la somma fra il DELAY dei REGISTRI e il DELAY della CONTROL STORE deve essere minore o uguale 10 in questo modo si e’ certi di avere a disposizione il valore corretto all’inizio della fase 1. Sotto la figura 3.5 puo’ aiutare a comprendere la condizione da rispettare.
Figura 3.5: Coerenza fra ritardi.
CAPITOLO 3.3 L’interazione logica fra i dispositivi 53
Lo stesso problema lo si ha per molti altri casi come ad esempio l’interazione fra MIR, DecA e MAR.
Supponiamo di dover leggere o scrivere un valore nella RAM VM-2. Fissato MIR.rit il ritardo del MIR, DecA.rit il ritardo del Decodificatore A e TRISET.rit il ritardo dei tristates per essere sicuri che in fase 2 il MAR abbia in ingresso il valore corretto dovremo far si di soddisfare la sequente disequazione (A):
( MIR.rit + Dec.rit + TRISET.rit ) <= 10 deltaT (A)
Infatti nella figura 3.6 i ritardi cosi’ impostati rendono vera la disequazione sopra e come si puo’ testare con un semplice programma VM-2 il funzionamento di tutto il sistema e’ corretto.
Figura 3.6: Esempi di ritardi corretti.
Sarebbe bastato impostare il ritardo dei codificatori a 3 che gia’ il sistema non avebbe piu’ computato in modo corretto il programma VM-2.
Sotto, figura 3.5, l’interpretazione grafica della disequazione (A).
Figura 3.7: Interpretazione grafica della disequazione (A).
CAPITOLO 3.3 L’interazione logica fra i dispositivi 54
Come e’ facile intuire occorre tenere conto in modo preciso di tutti i ritardi se si vuole essere sicuri di ottenere computazioni corrette e coerenti.
Ancora un esempio: supponiamo di voler sapere qual’e’ il ritardo idoneo all’unita’ ALU per avere in uscita un possibile valore (ad ex. quello contenuto nello Stack Pinter) da memorizzare in un qualsiasi registro (supponiamo l’ACC).
In fase 1 il MIR si attiva e dopo aver consumato il suo ritardo (MIR.rit) passa ai vari dispositivi i bit di controllo a questo punto si attiva il DecA che tiene conto del suo ritardo piu’ il ritardo del tristate (DecA.rit + TRISET.rit) fornendo al MPXD il valore dello Stack Pointer. Di conseguenza di attiva anche il MPXD che consuma il suo ritardo (MPXM.rit) e fa passare in uscita il valore dello Stack Pointer e qui finalmente entra in funzione l’ALU che consumera’ il suo ritardo (ALU.rit) che dobbiamo calcolare per garantire la correttezza di funzionamento di tutto il sistema.
La condizione che occorre rispettare e’ che la somma di tutti i dispositivi che entrano in gioco non devono superare la fase 3, fase in cui i registri memorizzano in entrata il valore da passare in uscita.
Per essere piu’ precisi occorre soddifare la seguente disequazione (B):
(MIR.rit+DecA.rit+TRISET.rit+MPXD.rit+ALU.rit) <= 20 DeltaT (B)
dove 20 deltaT e’ dato dall’intervallo fra l’inizio della fase 1 e l’inizio della fase 3.
A questo punto e’ facile sapere qual’e’ il massimo ritardo che l’ALU dovra’ avere per far si che tutto il sistema funzioni in modo corretto. Questo valore sara’ dato dalla disequazione (C):
ALU.rit = 20 deltaT - MIR.rit - DecA.rit - TRISET.rit - MPXD.rit (C)
CAPITOLO 4 Il Simulatore 55
Capitolo 4
Il Simulatore
Il Simulatore vuole essere uno strumento a disposizione dell’utente che voglia appronfondire il funzionamento della microarchitettuta che sta alla base della realizzazione della macchina virtuale VM-2.
Questo software di simulazione e' stato progettato per fornire in modo semplice ed intuitivo tutte le informazioni necessarie a comprendere l’interazione dei vari dispositivi in funzione della loro natura e del loro ritardo computazionale.
Il risultato ottenuto e’ l’esecuzione simulata, a vari livelli di dettaglio, delle istruzioni VM-2 fornite al simulatore sull’hardware VM-1.
4.1 L’interfaccia grafica
L’interfaccia utente e’ stata progettata per essere utilizzata in modo semplice ed intuitivo per avere la massima padronanza di dettaglio sia nell’esecuzione della singola micro-istruzione VM-1 sia della singola istruzione VM-2.
CAPITOLO 4.1 L’interfaccia grafica 56
Nella figura 4.1 possiamo vedere il simulatore vero e proprio con tutti gli strumenti necessari per la gestione di tutti i particolari hardware.
Figura 4.1: Il Simulatore.
Come si puo’ notare risulta evidente come sia facile capire quali valori sono contenuti nei vari dispositivi, il numero di cicli di clock trascorsi, la fase attuale ed il deltaT attuale.
Rapidi ed intuitivi anche i bottoni presenti che permettono di interagire con l'interfaccia.
La rappresentazione dei dati e' effettuata, per default, con codifica Unicode (tipo decimale senza segno) ma vi e' la possibilita' di selezionare altre rappresentazioni come la codifica Esadecimale e Decimale.
Per descrivere e comprendere meglio il simulatore lo possiamo dividere in 4 parti fondamentali:
CAPITOLO 4.1 L’interfaccia grafica 57
Figura 4.2: Parte A.
CAPITOLO 4.1 L’interfaccia grafica 58
Figura 4.3: Parte B.
Figura 4.4: Parte C.
CAPITOLO 4.1 L’interfaccia grafica 59
E’ importante notare che alla prima pressione di questo bottone automaticamente vengono memorizzati in tutti i dispositivi i rispettivi ritardi evitando cosi’ di premere il bottone SalvaRIT che effettua, oltre la memorizzazione, anche un avanzamento di 1 deltaT;
CAPITOLO 4.1 L’interfaccia grafica 60
Figura 4.5: Parte D.
4.2 I bottoni di interazione
In questo paragrafo tratteremo in modo piu’ approfondito la funzione di alcuni bottoni. Gia’ nel paragrafo precedente si e’ parlato in modo essenziale della loro funzione senza pero' scendere nei particolari che sono essenziali per il buon funzionamento del simulatore.
CAPITOLO 4.2 I bottoni di interazione 61
Vediamoli in dettaglio:
Vengono mantenuti i delay originali e reimpostati. Il tasto Reset e’ ovviamente utilizzato ogni qualvolta che si vuole ri-iniziare ad eseguire il programma VM-2 avendo, magari, modificato qualche dettaglio.
Figura 4.6: Valori attuali e valori futuri.
In questo caso si puo’ vedere che il MIR deve ancora fornire in uscita il nuovo valore che ha in entrata e questo a causa del suo ritardo.
CAPITOLO 4.2 I bottoni di interazione 62
I valori accettati sono tutti quelli che la rappresentazione dei registri permette di memorizzare e se non si entra nel range vengono modulati.
Ad esempio supponiamo di voler inserire nell’ACC il valore 70000 essendo l’ACC un registro a 16 bit il massimo valore memorizzabile e’ 65535 quello che otterrei e’ il valore modulo 65535 e quindi 04464.
Figura 4.7: Bottoni di scelta per la visualizzazione delle informazioni.
CAPITOLO 4.2 I bottoni di interazione 63
Sotto, in figura 4.8, si possono vedere le informazioni che si possono ottenere premendo, ad esempio, il bottone MPXD. E' da notare che il campo dacambiare indica che il dispositivo e' inattivo, cioe' non deve computare il valore in uscita, mentre il campo rit indica che il ritardo del dispositivo e' di 3 unita' tempo. Qualora il campo dacambiare fosse impostato a true il campo rit indicherebbe quanti deltaT occorre aspettare prima di avere in uscita del dispositivo il valore computato.
Figura 4.8: Esempio di visualizzazione delle informazioni.
In ambiente Windows, a causa delle protezioni derivanti dall'esecuzione di applet java nel codice javascript, occorre copiare tutti i file del simulatore e dei programmi VM-2 da eseguire nelle stessa PATH e digitare nel textbox VM2 File file:nomefile.txt dove nomefile.txt e' il programma VM-2 da eseguire e file: e' la parola chiave che indica al simulatore di cercare il file specificato nel PATH corrente.
Il file deve essere di tipo TESTO e nel seguente formato:
XXXX Commento libero ma su una sola riga
dove XXXX indica il codice ESADECIMALE dell'istruzione da eseguire.
VINCOLO: LASCIARE ALMENO UNA RIGA VUOTA DOPO IL CODICE DEL PROGRAMMA VM-2.
CAPITOLO 4.2 I bottoni di interazione 64
Esempio di programma VM-2 in formato corretto:
4006 Ram00 Carica il valore della cella RAM 6 nell’accumulatore;
1004 Ram01 Se il valore nell’ACC e’ negativo salta alla cella 4;
FF00 Ram02 Moltiplica x 2 il valore che si trova nell’accumulatore;
FD00 Ram03 Termina la computazione
FB00 Ram04 Cambia segno al valore presente nell’accumulatore;
FD00 Ram05 Termina la computazione
FFFF Ram06 Corrisponde al valore negativo -1
*******riga vuota*******
Esempio di programma VM-2 in formato NON corretto:
4006 Ram00 Carica il valore della cella RAM 6 nell’accumulatore (altra descrizione che va ad occupare un'altra riga l'errore sta qui);
1004 Ram01 Se il valore nell’ACC e’ negativo salta alla cella 4;
FF00 Ram02 Moltiplica x 2 il valore che si trova nell’accumulatore;
FD00 Ram03 Termina la computazione
FB00 Ram04 Cambia segno al valore presente nell’accumulatore;
FD00 Ram05 Termina la computazione
FFFF Ram06 Corrisponde al valore negativo -1
(altro errore: qui non e' stata lasciata almeno una riga vuota)
Figura 4.9: Memoria RAM VM-2.
CAPITOLO 4.2 I bottoni di interazione 65
La voce modalita' protetta indica, nel caso sia selezionata, l'impossibilita' di modificare il contenuto della memoria RAM VM-2 tramite il pulsante SaveRAM. Qualora sia deselezionata si potranno modificare le celle di memoria cambiando i valori (sempre in formato esadecimale) e fissando la variazione con il pulsante SaveRAM.
Il pulsante AltraCELLA fornisce la possibilita' di specificare un'altra cella di memoria di interesse mentre il pulsante CloseRAM permette di chiudere la finestra.
I pulsanti < e > permettono di avanzare o retrocedere nella finestra di 5 celle di memoria possibilita' comoda per evitare di dover digitare sempre la cella di memoria di interesse.
Abbiamo anche qui, come nel caso dell’inserimento in memoria del programma VM-2 da eseguire, la possibilita’ di inserire il nome del file di testo il cui contenuto dovra’ essere mappato nelle celle di memoria della Control Store.
A parte il formato del file che e’ diverso, l’interazione con i sistema operativo sottostante all’interfaccia e’ il medesimo descritto precendentemente (caso di caricamento del programma VM-2) quindi occorre porre la stessa attenzione descritta prima.
Il formato del file dovra’ essere del tipo:
ABCDEFGHIJKLMNOPPP descrizione a piacere ma su 1 sola riga
dove:
CAPITOLO 4.2 I bottoni di interazione 66
Esempio di programma VM-1 in formato corretto:
000003000100010000 cella0 RESET: PC=0; reset interrupt; MPC=MPC+1
000000000000006006 cella1 FETCH: if Interrupt goto 6 else MPC=MPC+1
411100000100000000 cella2 MAR=PC; PC=PC+1; start read; MPC=MPC+1
001010000000000000 cella3 MBR=data bus; end read; MPC=MPC+1
000002003101000000 cella4 IR=MBR; ADR=MBR; MPC=MPC+1
000000000000005000 cella5 MPC=decode(IR)
*******riga vuota*******
Esempio di programma VM-1 in formato NON corretto:
000003000100010000 cella0 RESET: PC=0; reset interrupt; MPC=MPC+1
0000000000000066 cella1 FETCH: if Interrupt goto 6 else MPC=MPC+1 (e’ stato inserito 6 invece del valore 006 vedere la differenza con sopra)
411100000100000000 cella2 MAR=PC; PC=PC+1; start read; MPC=MPC+1
001010000000000000 cella3 MBR=data bus; end read; MPC=MPC+1
000002003101000000 cella4 IR=MBR; ADR=MBR; MPC=MPC+1
000000000000005000 cella5 MPC=decode(IR)
(altro errore: qui non e' stata lasciata almeno una riga vuota)
Per un corretto funzionamento del simulatore occorre mantenersi strettamente ai vincoli imposti nel creare i file di testo contenenti i programmi VM-2 e VM-1 (Control Store).
Di seguito la figura 4.10:
CAPITOLO 4.2 I bottoni di interazione 67
Figura 4.10: Visualizzazione e gestione della Control Store.
La finestra la possiamo dividere in 2 parti:
la parte SUPERIORE contenente:
CAPITOLO 4.2 I bottoni di interazione 68
Figura 4.11: Accesso alla JAVA CONSOLE.
Figura 4.12: CONSOLE JAVA.
CAPITOLO 4.2 I bottoni di interazione 69
la parte INFERIORE contenente:
Il formato dei valori deve essere decimale ed il range compreso fra i valori consentiti dai vari dispositivi inoltre il campo Addr deve essere nel formato 001 per il valore 1, 002 per il valore 2, ecc.
Ogni qualsiasi valore non nel formato corretto potra’ causare il malfunzionamento del sistema.
Supponiamo di avere avuto inizialmente 5 deltaT di ritardo per l’ALU e dopo alcune computazioni (supponiamo 2) il campo rit conterra’ il valore 3 ora modifichiamo il ritardo inserendo nell’apposito textbox il valore 7.
CAPITOLO 4.2 I bottoni di interazione 70
Questo vuol dire che il dispositivo dovra’ aspettare non piu’ 3 deltaT ma 5 deltaT perche’ rispetto a 5, 7 ha 2 unita’ tempo in piu’ che andranno sommate al valore del campo rit. Al termine della memorizzazione se andiamo a verificare il campo rit dell’ALU sara’ non 5 ma 4 questo perche’ dobbiamo ricordarci che viene effuttuata anche un’avanzamento di 1 deltaT.
Se il valore risultasse negativo vorrebbe dire che vorremmo avere la computazione immediata e questa ci e’ garantita dal fatto che il simulatore avanza di 1 deltaT.
Questa scelta e’ stata effettuta per evitare la ripetizione del codice di controllo e computazione del simulatore. Il risultato indesiderato che ne consegue, se cosi’ lo vogliamo definire, e’ che perche’ abbia senso modificare i ritardi e apprezzare la variazione questi devono avere una variazione di deltaT almeno maggiore di 1.
4.3 Esempi di programmi
Vedremo gli esempi di programmi VM-2 presentati nel Capitolo 1 con in piu’ la gestione manuale dell’INPUT/OUTPUT.
Questi programmi possono essere fatti computare al nostro simulatore senza problemi.
EX. 1.1 Supponiamo di voler prelevare un numero dalla cella di memoria 6 e voler effettuare:
4006 Ram00
Carica il valore della cella di memoria 6 nell’accumulatore;1006 Ram01
Se il valore nell’ACC e’ negativo salta alla cella di memorianumero 4;
FF00 Ram02
Moltiplica per 2 il valore che si trova nell’accumulatore;FD00 Ram03
Termina la computazioneFB00 Ram04
Cambia segno al valore presente nell’accumulatore;FD00 Ram05
Termina la computazioneFFFF Ram06
Corrisponde al valore negativo –1.
CAPITOLO 4.3 Esempi di programmi 71
EX. 1.2 Supponiamo di voler prendere in input 2 numeri diversi da 0 e farne la somma per poi fornirla in output.
4FFE Ram00
Carica il valore della cella di memoria FFE cioe’ 4094 (input);2000 Ram01
Se il valore nell’ACC e’ uguale a zero (significa che non e’stato ancora immesso nessun valore) ritorna alla cella 0;
700B Ram02
Memorizza nella cella 11 (B) il valore letto d’input che ora sitrova nell’accumulatore;
FB00 Ram03 C
ambio segno al valore dell’accumulatore;500B Ram04
Sommo al valore dell’accumulatore il valore letto dall’input;7FFE Ram05
Memorizzo il valore 0 nella cella 4094 che mi simula l’input(queste istruzioni vengono eseguite per portare a zero il valore
della cella di memoria 4094 in modo da testare l’inserimento
di un nuovo valore se il valore e’ diverso da 0);
4FFE Ram06
Carica il valore della cella di memoria FFE cioe’ 4094 (input);2006 Ram07
Se il valore nell’ACC e’ uguale a zero (significa che non e’stato ancora immesso nessun valore) ritorna alla cella 6;
500B Ram08
Effettua la somma dei due numeri inseriti;7FFF Ram09
Memorizza nella cella di memoria 4095 (output) il risultato;FD00 Ram10
Termina la computazione.
EX. 1.3 Supponiamo ora di voler prendere in input 2 numeri POSITIVI diversi da 0 e farne la moltiplicazione per poi fornirla in output.
F001 Ram00
Carica il valore 1 nell'accumulatore;FB00 Ram01
Effettua il cambiamento di segno dell'ACC;7019 Ram02
Memorizza nella cella 25 (19) il valore contenuto nell'Accu-mulatore che nel nostro caso sara' -1;
4FFE Ram03
Carica il valore della cella di memoria FFE cioe' 4094 (input);2003 Ram04
Se il valore nell'ACC e' uguale a zero (significa che non e'stato ancora immesso nessun valore) ritorna alla cella 3;
701A Ram05
Memorizza nella cella 26 (1A) il valore letto d'input che ora sitrova nell'accumulatore;
FB00 Ram06
Cambio segno al valore dell'accumulatore;501A Ram07
Sommo al valore dell'accumulatore il valore letto dall'input;7FFE Ram08
Memorizzo il valore 0 nella cella 4094 che mi simula l'input(queste istruzioni vengono eseguite per portare a zero il valore
della cella di memoria 4094 in modo da testare l'inserimento
di un nuovo valore se il valore e' diverso da 0);
4FFE Ram09
Carica il valore della cella di memoria FFE cioe' 4094 (input);CAPITOLO 4.3 Esempi di programmi 72
2009 Ram10
Se il valore nell'ACC e' uguale a zero (significa che non e'stato ancora immesso nessun valore) ritorna alla cella 9;
701B Ram11
Memorizza nella cella 27 (1B) il valore letto d'input che ora sitrova nell'accumulatore;
FE00 Ram12
Effettua 1 shift a destra;300C Ram13
Salta alla cella 12 (C) fino a quando non ho ottenuto 0;501B Ram14
Sommo all'accumulatore l'ultimo valore letto701C Ram15
Memorizza nella cella 28 (1C) il valore ottenuto;401A Ram16
Leggo il valore della cella 26 (1A) ;5019 Ram17
Sommo -1 al valore dell'accumulatore;701A Ram18
Memorizza nella cella 26 (1A) il valore ottenuto;3017 Ram19
Se il valore e' diverso da 0 salta l'esecuzione alla cella di me-moria 23 (17);
401C Ram20
Leggo il valore della cella 28 (1C);7FFF Ram21
Memorizza nella cella di memoria 4095 (output) il risultato;FD00 Ram22
Termina la computazione;401C Ram23
Leggo il valore della cella 28 (1C);C00E Ram24
Salto alla cella 14 (E).
APPENDICE A.1 Il codice JAVASCRIPT 73
Appendice A
Di seguito si potranno visionare il codice sorgente scritto in JAVASCRIPT [JSCR97], HTML [HTML4] e JAVA [LEM98], ovviamente si trattera' del codice principale.
Se l'utente vorra' approfondire il codice sorgente non dovra' far altro che utilizzare un qualsiasi programma di editor di testi ed aprire il file desiderato.
A.1 Il codice JAVASCRIPT
Il codice javascript [JSCR00] seguente e' quello contenuto nel file VM1EMUL.JS che viene caricato dalla pagina INDEX.HTML del SIMULATORE.
/* vm1emul.js : JavaScript/HTML/Java emulation of the VM-1 Conventional Machine
*
* version 1.0, June 15, 2001
*
* Copyright C 2001 by Antonio Scorza <1995s088@educ.disi.unige.it>
* DISI, Universita' di Genova
* via Dodecaneso 35, 16146 Genova, Italy.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* See URL http://www.gnu.org/copyleft/gpl.html for details.*/
APPENDICE A.1 Il codice JAVASCRIPT 74
myRAM= new Array /* ram VM-2 */
myCSRAM = new Array /* control store VM-1 */
myRUN=0 /* se 0 = ferma */
myAbus = 0 /* Bus A */
myBbus = 0 /* Bus B */
myCbus = 0 /* Bus C */
myDbus = 0 /* Bus D */
myIDec = 0 /* 8 Bit piu significativi del Bus B */
myCS=0 // AGGIUNTI PER NON PERDERE I DATI DEL MIR
myINT=0 // AGGIUNTI PER NON PERDERE I DATI DEL MIR
/* Gestione del tempo */
myCLOCK=0 /* CLOCK */
myPh=0 /* FASE */
myDELTA=0 /* DELTA */
myLOADMIR=false /* MIR CARICATO ??? */
myENABLEDBUS=0 /* BUS ABILITATO??? */
myCODING=0 /* Codifica UNICODE */
myOPENRAM=false /* Finestra ram aperta?? */
/* Gestione dei ritardi */
myREGDELAY=0 /* Ritardo REGISTRI */
myMPXDELAY=0 /* Ritardo MULTIPLEXER */
myDECDELAY=0 /* Ritardo DECODER */
myTRIDELAY=0 /* Ritardo TRISTATE */
myALUDELAY=0 /* Ritardo ALU */
myCSDELAY=0 /* Ritardo CONTROLSTORE */
myTRISET= new Object /* Oggetto per memorizzare se il valore di un registro e' stato cambiato oppure no */
/* e di conseguenza i dati per la gestione del passaggio dati. */
wCS= new Object /* Finestra contente le celle della CS */
wRAM= new Object /* Finestra contente le celle della RAM */
wVIEW= new Object /* Finestra per la visualizzazione delle informazioni dei dispositivi */
/* CREAZIONE REGISTRI VM2 */
myMAR = new Object /* Registro MAR */
myMBR = new Object /* Registro MBR */
myPC = new Object /* Registro PC */
myFP = new Object /* Registro FP */
mySP = new Object /* Registro SP */
myADR = new Object /* Registro ADR */
myIR = new Object /* Registro IR */
myACC = new Object /* Registro ACC */
myB = new Object /* Registro B */
myC = new Object /* Registro C */
myCSOUT = new Object /* Valore d'uscita della CS */
myMPC = new Object /* Registro MPC */
myMIR = new Object /* Registro MIR */
myALU = new Object /* Disp. combinatorio ALU */
myDEC = new Object /* Disp. combinatorio DEC */
mymSEQ = new Object /* Disp. combinatorio mSEQ */
myMPXM = new Object /* Disp. combinatorio MPXM */
myMPXD = new Object /* Disp. combinatorio MPXD */
myDpxCA = new Object /* Disp. combinatorio DpxCA */
myDpxCD = new Object /* Disp. combinatorio DpxCD */
myDecA = new Object /* Disp. combinatorio DecA */
myDecB = new Object /* Disp. combinatorio DecB */
myDecD = new Object /* Disp. combinatorio DecD */
APPENDICE A.1 Il codice JAVASCRIPT 75
<!-------------------------->
<!-- Bottone Valori -->
<!-------------------------->
function valori(){
var tmp="Nuovo Vecchio\n\n";
var tmpval=0;
tmp=tmp + "MAR="+myMAR.next+" MAR="+myMAR.old+"\n";
tmp=tmp + "MBR="+myMBR.next+" MBR="+myMBR.old+"\n";
tmp=tmp + "PC="+myPC.next+" PC="+myPC.old+"\n";
tmp=tmp + "SP="+mySP.next+" SP="+mySP.old+"\n";
tmp=tmp + "FP="+myFP.next+" FP="+myFP.old+"\n";
tmp=tmp + "ADR="+myADR.next+" ADR="+myADR.old+"\n";
tmp=tmp + "IR="+myIR.next+" IR="+myIR.old+"\n";
tmp=tmp + "ACC="+myACC.next+" ACC="+myACC.old+"\n";
tmp=tmp + "B="+myB.next+" B="+myB.old+"\n";
tmp=tmp + "C="+myC.next+" C="+myC.old+"\n";
tmp=tmp + "CSOUT="+myCSOUT.next+" CSOUT="+myCSOUT.old+"\n";
tmp=tmp + "MIR="+myMIR.next+" MIR="+myMIR.old+"\n";
tmp=tmp + "MPC="+myMPC.next+" MPC="+myMPC.old+"\n";
tmp=tmp + "myDEC="+myDEC.next+" myDEC="+myDEC.old+"\n";
tmp=tmp + "MPXM="+myMPXM.next+" MPXM="+myMPXM.old+"\n";
tmp=tmp + "MPXD="+myMPXD.next+" MPXD="+myMPXD.old+"\n";
if (myRUN!=0) {
switch(mymSEQ.mcond) {
case 0:
tmpval=3;
break;
case 1:
tmpval=2;
break;
case 2:
if (mymSEQ.N==1) tmpval=2
else tmpval=3
break;
case 3:
if (mymSEQ.Z==1) tmpval=2
else tmpval=3
break;
case 4:
tmpval=1;
break;
case 5:
tmpval=0;
break;
case 6:
if (parseInt(myMIR.old.substring(13,14),10)==3) tmpval=2
else tmpval=3
break;
case 7:
//non utilizzata
break;
}
}
tmp=tmp + "mSEQ="+tmpval+" mSEQ="+mymSEQ.old+"\n";
tmp=tmp + "DpxCD="+myDpxCD.CDbus+" DpxCD="+myDpxCD.old+"\n";
tmp=tmp + "DpxCA="+myDpxCA.CAbus+" DpxCA="+myDpxCA.old+"\n";
tmp=tmp + "DecA="+myDecA.Abus+" DecA="+myDecA.old+"\n";
tmp=tmp + "DecB="+myDecB.Bbus+" DecB="+myDecB.old+"\n";
tmp=tmp + "DecD="+myDecD.Dbus+" DecD="+myDecD.old+"\n";
switch(myALU.alu) {
case 0:
tmpval=myALU.a;
break;
APPENDICE A.1 Il codice JAVASCRIPT 76
case 1: // questo a causa del fatto che in Javascript il Not bit a bit e' fatto in complemento a 2
tmpval=(myALU.a^0xFFFF)
break;
case 2:
tmpval=(myALU.a<<1);
break;
case 3:
tmpval=(myALU.a>>1);
break;
case 4:
tmpval=(myALU.a+1);
break;
case 5:
tmpval=(myALU.a-1);
break;
case 6:
tmpval=(myALU.a+myALU.b);
break;
case 7:
tmpval=(myALU.a & myALU.b);
break;
}
tmp=tmp + "ALU="+tmpval+" ALU="+myALU.old+"\n";
alert(tmp);
}
<!-------------------------->
<!-- View Valori -->
<!-------------------------->
function viewVAL(){
wVIEW=window.open("menuview.html","Gestione_VISUALIZZAZIONE","width=400,height=400,resizable");
wVIEW.focus();
}
<!-------------------------->
<!-- Ristampa Valori -->
<!-------------------------->
function changeCOD(){
if (parent.Parte3.document.VM1_PARTE3.COD[0].checked) myCODING=0
else if (parent.Parte3.document.VM1_PARTE3.COD[1].checked) myCODING=4
else myCODING=3
reprint();
}
<!-------------------------->
<!-- Ristampa Valori -->
<!-------------------------->
function reprint(){
parent.Parte2.document.VM1_PARTE2.regMAR.value=printnumb(myCODING,12,myMAR.old);
parent.Parte2.document.VM1_PARTE2.regMBR.value=printnumb(myCODING,16,myMBR.old);
parent.Parte2.document.VM1_PARTE2.regPC.value=printnumb(myCODING,12,myPC.old);
parent.Parte2.document.VM1_PARTE2.regSP.value=printnumb(myCODING,12,mySP.old);
parent.Parte2.document.VM1_PARTE2.regFP.value=printnumb(myCODING,12,myFP.old);
parent.Parte2.document.VM1_PARTE2.regADR.value=printnumb(myCODING,12,myADR.old);
parent.Parte2.document.VM1_PARTE2.regIR.value=printnumb(myCODING,16,myIR.old);
parent.Parte2.document.VM1_PARTE2.regACC.value=printnumb(myCODING,16,myACC.old);
parent.Parte2.document.VM1_PARTE2.regB.value=printnumb(myCODING,16,myB.old);
parent.Parte2.document.VM1_PARTE2.regC.value=printnumb(myCODING,16,myC.old);
parent.Parte2.document.VM1_PARTE2.Abus.value=printnumb(myCODING,12,myAbus);
parent.Parte2.document.VM1_PARTE2.Bbus.value=printnumb(myCODING,16,myBbus);
parent.Parte2.document.VM1_PARTE2.Cbus.value=printnumb(myCODING,16,myCbus);
parent.Parte2.document.VM1_PARTE2.Dbus.value=printnumb(myCODING,16,myDbus);
parent.Parte2.document.VM1_PARTE2.DpxCA.value=printnumb(4,4,myDpxCA.old);
parent.Parte2.document.VM1_PARTE2.DpxCD.value=printnumb(4,4,myDpxCD.old);
parent.Parte2.document.VM1_PARTE2.DecA.value=printnumb(4,4,myDecA.old);
parent.Parte2.document.VM1_PARTE2.DecB.value=printnumb(4,4,myDecB.old);
APPENDICE A.1 Il codice JAVASCRIPT 77
parent.Parte2.document.VM1_PARTE2.DecD.value=printnumb(4,4,myDecD.old);
parent.Parte3.document.VM1_PARTE3.aluA.value=printnumb(myCODING,16,myALU.a);
parent.Parte3.document.VM1_PARTE3.IDec.value=printnumb(myCODING,8,myIDec);
parent.Parte3.document.VM1_PARTE3.Decode.value=printnumb(myCODING,8,myDEC.old);
parent.Parte3.document.VM1_PARTE3.regMPC.value=printnumb(myCODING,8,myMPC.old);
parent.Parte3.document.VM1_PARTE3.mpxm.value=printnumb(myCODING,8,myMPXM.old);
parent.Parte3.document.VM1_PARTE3.mSEQ.value=printnumb(4,4,mymSEQ.old);
parent.Parte3.document.VM1_PARTE3.aluZ.value=printnumb(4,4,myALU.Z);
parent.Parte3.document.VM1_PARTE3.aluN.value=printnumb(4,4,myALU.N);
parent.Parte3.document.VM1_PARTE3.ritREG.value=myREGDELAY-1;
parent.Parte3.document.VM1_PARTE3.ritMPX.value=myMPXDELAY-1;
parent.Parte3.document.VM1_PARTE3.ritDEC.value=myDECDELAY-1;
parent.Parte3.document.VM1_PARTE3.ritTRI.value=myTRIDELAY-1;
parent.Parte3.document.VM1_PARTE3.ritALU.value=myALUDELAY-1;
parent.Parte3.document.VM1_PARTE3.ritCS.value=myCSDELAY-1;
parent.Parte3.document.VM1_PARTE3.Fase.value=myPh;
parent.Parte3.document.VM1_PARTE3.DeltaT.value=myDELTA;
parent.Parte3.document.VM1_PARTE3.Clock.value=myCLOCK;
}
<!----------------------------->
<!-- Check MSEQ -->
<!----------------------------->
function checkMSEQ(){
switch(mymSEQ.mcond) {
case 0:
mymSEQ.old=3;
myMPXM.next=myMPC.old+1;
break;
case 1:
mymSEQ.old=2;
myMPXM.next=parseInt(myMIR.old.substring(15,18),10);
break;
case 2:
if (mymSEQ.N==1) {
mymSEQ.old=2;
myMPXM.next=parseInt(myMIR.old.substring(15,18),10)
}
else {
mymSEQ.old=3;
myMPXM.next=myMPC.old+1;
}
break;
case 3:
if (mymSEQ.Z==1) {
mymSEQ.old=2;
myMPXM.next=parseInt(myMIR.old.substring(15,18),10)
}
else {
mymSEQ.old=3;
myMPXM.next=myMPC.old+1;
}
break;
case 4:
mymSEQ.old=1;
myMPXM.next=0;
break;
case 5:
myMPXM.next=myDEC.old;
mymSEQ.old=0;
break;
case 6:
if (parseInt(myMIR.old.substring(13,14),10)==3) {
mymSEQ.old=2;
myMPXM.next=parseInt(myMIR.old.substring(15,18),10)
APPENDICE A.1 Il codice JAVASCRIPT 78
}
else {
mymSEQ.old=3;
myMPXM.next=myMPC.old+1;
}
break;
case 7:
//non utilizzata
break;
}
}
<!----------------------------->
<!-- Check MPXM -->
<!----------------------------->
function checkMPXM(){
myMPXM.old=myMPXM.next;
myMPXM.dacambiare=false;
}
<!----------------------------->
<!-- Check ALU -->
<!----------------------------->
function checkALU(){
switch(myALU.alu) {
case 0:
myCbus=myALU.a;
break;
case 1: // questo a causa del fatto che in Javascript il Not bit a bit e' fatto in complemento a 2
myCbus=(myALU.a^0xFFFF)
break;
case 2:
myCbus=(myALU.a<<1);
break;
case 3:
myCbus=(myALU.a>>1);
break;
case 4:
myCbus=(myALU.a+1);
break;
case 5:
myCbus=(myALU.a-1);
break;
case 6:
myCbus=(myALU.a+myALU.b);
break;
case 7:
myCbus=(myALU.a & myALU.b);
break;
}
myCbus=(myCbus & 0xFFFF); //per evitare l'OVERFLOW in tutti i vari casi
myALU.old=myCbus; //questo e' settato ma non serve.
if (myALU.old==0) myALU.Z=1
else myALU.Z=0
if ((myALU.old & 0x8000) !=0) myALU.N=1
else myALU.N=0
mymSEQ.N=myALU.N;
mymSEQ.Z=myALU.Z;
}
<!----------------------------->
<!-- Salva valori modificati -->
<!----------------------------->
function salvaVAL(){
var base=0;
var flag=false;
APPENDICE A.1 Il codice JAVASCRIPT 79
if ((myCODING==0) || (myCODING==4)) base=10
else if (myCODING==1) base=1
else if (myCODING==2) base=8
else if (myCODING==3) base=16
myMAR.next=parseInt(parent.Parte2.document.VM1_PARTE2.regMAR.value,base) & 0xFFF;
myMBR.next=parseInt(parent.Parte2.document.VM1_PARTE2.regMBR.value,base) & 0xFFFF;
myPC.next=parseInt(parent.Parte2.document.VM1_PARTE2.regPC.value,base) & 0xFFF;
mySP.next=parseInt(parent.Parte2.document.VM1_PARTE2.regSP.value,base) & 0xFFF;
myFP.next=parseInt(parent.Parte2.document.VM1_PARTE2.regFP.value,base) & 0xFFF;
myADR.next=parseInt(parent.Parte2.document.VM1_PARTE2.regADR.value,base) & 0xFFF;
switch(myDecA.old) {
case 0:
flag=(myPC.old!=myPC.next);
myAbus=myPC.next;
break;
case 1:
flag=(mySP.old!=mySP.next);
myAbus=mySP.next;
break;
case 2:
flag=(myFP.old!=myFP.next);
myAbus=myFP.next;
break;
case 3:
flag=(myADR.old!=myADR.next);
myAbus=myADR.next;
break;
}
myPC.old=myPC.next;
mySP.old=mySP.next;
myFP.old=myFP.next;
myADR.old=myADR.next;
if (flag) {
myTRISET.tri1=myDecA.old;
myTRISET.val1=myAbus;
myTRISET.reg1=myDpxCA.old;
if (myMPXD.Dmpx==0) {
myMPXD.next=myAbus;
myMPXD.old=myMPXD.next
myALU.a=myMPXD.old;
checkALU();
checkMPXM();
}
}
myIR.next=parseInt(parent.Parte2.document.VM1_PARTE2.regIR.value,base) & 0xFFFF;
myACC.next=parseInt(parent.Parte2.document.VM1_PARTE2.regACC.value,base) & 0xFFFF;
myB.next=parseInt(parent.Parte2.document.VM1_PARTE2.regB.value,base) & 0xFFFF;
myC.next=parseInt(parent.Parte2.document.VM1_PARTE2.regC.value,base) & 0xFFFF;
switch(myDecD.old) {
case 0:
flag=(myIR.old!=myIR.next);
myDbus=myIR.next;
break;
case 1:
flag=(myACC.old!=myACC.next);
myDbus=myACC.next;
break;
case 2:
flag=(myB.old!=myB.next);
myDbus=myB.next;
break;
case 3:
flag=(myC.old!=myC.next);
myDbus=myC.next;
break;
}
APPENDICE A.1 Il codice JAVASCRIPT 80
if (flag) {
myTRISET.tri2=myDecD.old;
myTRISET.val2=myDbus;
myTRISET.reg2=myDpxCD.old;
if (myMPXD.Dmpx==1) {
myMPXD.next=myDbus;
myMPXD.old=myMPXD.next
myALU.a=myMPXD.old;
checkALU();
checkMSEQ();
checkMPXM();
}
}
switch(myDecB.old) {
case 0:
flag=(myIR.old!=myIR.next);
myBbus=myIR.next;
break;
case 1:
flag=(myACC.old!=myACC.next);
myBbus=myACC.next;
break;
case 2:
flag=(myB.old!=myB.next);
myBbus=myB.next;
break;
case 3:
flag=(myC.old!=myC.next);
myBbus=myC.next;
break;
}
if (flag) {
myTRISET.tri3=myDecB.old;
myTRISET.val3=myBbus;
myTRISET.reg2=myDpxCD.old;
myALU.b=myBbus;
checkALU();
myIDec=(myBbus>>8);
tmp=myIDec;
if (tmp<240) {
tmp >>>=4;
tmp=tmp*2+32;
}
else {
tmp=tmp & 0x0F;
tmp=tmp*2+96;
}
myDEC.next=tmp;
myDEC.old=myDEC.next; //NB. qui imporgo che prima faccia la decodifica dei bit piu' significativi e poi eseguo il
//dispositivo mSEQ in modo tale che se scelgo il canale 0 del MPMX abbia gia' il valore corretto
checkMSEQ();
checkMPXM();
}
myIR.old=myIR.next;
myACC.old=myACC.next;
myB.old=myB.next;
myC.old=myC.next;
myMPC.next=parseInt(parent.Parte3.document.VM1_PARTE3.regMPC.value,base) & 0x7F;
myMAR.old=myMAR.next;
myMBR.old=myMBR.next;
reprint();
}
<!-------------------------->
<!-- Inizializzazione -->
<!-------------------------->
APPENDICE A.1 Il codice JAVASCRIPT 81
function initDISP(){
myMAR.dacambiare=false;
myMAR.next = 0;
myMAR.old = 0;
myMAR.rit=0;
myMAR.mar=0;
myMBR.dacambiare=false;
myMBR.next = 0;
myMBR.old = 0;
myMBR.rit=0;
myMBR.mbr=0;
myMBR.rw=0;
myPC.dacambiare=false;
myPC.next = 0;
myPC.old = 0;
myPC.rit=0;
myFP.dacambiare=false;
myFP.next = 0;
myFP.old = 0;
myFP.rit=0;
mySP.dacambiare=false;
mySP.next = 0;
mySP.old = 0;
mySP.rit=0;
myADR.dacambiare=false;
myADR.next = 0;
myADR.old = 0;
myADR.rit=0;
myIR.dacambiare=false;
myIR.next = 0;
myIR.old = 0;
myIR.rit=0;
myACC.dacambiare=false;
myACC.next = 0;
myACC.old = 0;
myACC.rit=0;
myB.dacambiare=false;
myB.next = 0;
myB.old = 0;
myB.rit=0;
myC.dacambiare=false;
myC.next = 0;
myC.old = 0;
myC.rit=0;
myCSOUT.dacambiare=false;
myCSOUT.next = 0;
myCSOUT.old = 0;
myCSOUT.rit=0;
myMPC.dacambiare=false;
myMPC.next = 0;
myMPC.old = 0;
myMPC.rit=0;
myMIR.dacambiare=false;
myMIR.next = 0;
myMIR.old = 0;
myMIR.rit=0;
APPENDICE A.1 Il codice JAVASCRIPT 82
myALU.dacambiare=false;
myALU.a=0;
myALU.b=0;
myALU.N=0;
myALU.Z=0;
myALU.alu = 0;
myALU.old = 0;
myALU.rit=0;
myDEC.dacambiare=false;
myDEC.next = 0;
myDEC.old = 0;
myDEC.rit=0;
mymSEQ.dacambiare=false;
mymSEQ.N=0;
mymSEQ.Z=0;
mymSEQ.mcond = 0;
mymSEQ.old = 0;
mymSEQ.rit=0;
myMPXM.dacambiare= false;
myMPXM.next = 0;
myMPXM.old = 0;
myMPXM.rit=0;
myMPXD.dacambiare=false;
myMPXD.Dmpx=0;
myMPXD.next = 0;
myMPXD.old = 0;
myMPXD.rit=0;
myDpxCA.dacambiare = false;
myDpxCA.CAbus = 0;
myDpxCA.old = 0;
myDpxCA.rit=0;
myDpxCA.en=0;
myDpxCD.dacambiare = false;
myDpxCD.CDbus = 0;
myDpxCD.old = 0;
myDpxCD.rit=0;
myDpxCD.en=0;
myDecA.dacambiare = false;
myDecA.Abus = 0;
myDecA.old = 0;
myDecA.rit=0;
myDecB.dacambiare = false;
myDecB.Bbus = 0;
myDecB.old = 0;
myDecB.rit=0;
myDecD.dacambiare = false;
myDecD.Dbus = 0;
myDecD.old = 0;
myDecD.rit=0;
myTRISET.dacambiare1=false;
myTRISET.dacambiare2=false;
myTRISET.reg1=-1;
myTRISET.val1=0;
myTRISET.tri1=0;
myTRISET.reg2=-1;
myTRISET.val2=0;
myTRISET.tri2=0;
myTRISET.tri3=0;
myTRISET.rit=0;
APPENDICE A.1 Il codice JAVASCRIPT 83
}
<!-------------------------->
<!-- setta RITARDI -->
<!-------------------------->
function settaRIT() {
myMAR.rit=myREGDELAY;
myMBR.rit=myREGDELAY;
myPC.rit=myREGDELAY;
myFP.rit=myREGDELAY;
mySP.rit=myREGDELAY;
myADR.rit=myREGDELAY;
myIR.rit=myREGDELAY;
myACC.rit=myREGDELAY;
myB.rit=myREGDELAY;
myC.rit=myREGDELAY;
myCSOUT.rit=myCSDELAY;
myMPC.rit=myREGDELAY;
myMIR.rit=myREGDELAY;
myMPXM.rit=myMPXDELAY;
myMPXD.rit=myMPXDELAY;
myDpxCA.rit=myMPXDELAY;
myDpxCD.rit=myMPXDELAY;
myDEC.rit=myDECDELAY;
mymSEQ.rit=myDECDELAY;
myDecA.rit=myDECDELAY;
myDecB.rit=myDECDELAY;
myDecD.rit=myDECDELAY;
myALU.rit=myALUDELAY;
myTRISET.rit=myTRIDELAY;
}
<!-------------------------->
<!-- Salva RITARDI -->
<!-------------------------->
function salvaRIT() {
var base=0;
var myREGDELAY1=0,myDECDELAY1=0,myMPXDELAY1=0,myALUDELAY1=0,myTRIDELAY1=0,myCSDELAY1=0;
if ((myCODING==0) || (myCODING==4)) base=10
else if (myCODING==1) base=1
else if (myCODING==2) base=8
else if (myCODING==3) base=16
if (myRUN!=0) {
myREGDELAY1=parseInt(parent.Parte3.document.VM1_PARTE3.ritREG.value,base) & 0x1F; //massimo 31 deltat
myDECDELAY1=parseInt(parent.Parte3.document.VM1_PARTE3.ritDEC.value,base) & 0x1F;
myMPXDELAY1=parseInt(parent.Parte3.document.VM1_PARTE3.ritMPX.value,base) & 0x1F;
myALUDELAY1=parseInt(parent.Parte3.document.VM1_PARTE3.ritALU.value,base) & 0x1F;
myTRIDELAY1=parseInt(parent.Parte3.document.VM1_PARTE3.ritTRI.value,base) & 0x1F;
myCSDELAY1=parseInt(parent.Parte3.document.VM1_PARTE3.ritCS.value,base) & 0x1F;
parent.Parte3.document.VM1_PARTE3.ritREG.value=myREGDELAY1;
parent.Parte3.document.VM1_PARTE3.ritMPX.value=myMPXDELAY1;
parent.Parte3.document.VM1_PARTE3.ritDEC.value=myDECDELAY1;
parent.Parte3.document.VM1_PARTE3.ritTRI.value=myTRIDELAY1;
parent.Parte3.document.VM1_PARTE3.ritALU.value=myALUDELAY1;
parent.Parte3.document.VM1_PARTE3.ritCS.value=myCSDELAY1;
if (myREGDELAY1!=myREGDELAY) { // REGISTRI
myMIR.rit=(myREGDELAY1-myREGDELAY)+myMIR.rit+1;
myMAR.rit=(myREGDELAY1-myREGDELAY)+myMAR.rit+1;
myMBR.rit=(myREGDELAY1-myREGDELAY)+myMBR.rit+1;
myPC.rit=(myREGDELAY1-myREGDELAY)+myPC.rit+1;
mySP.rit=(myREGDELAY1-myREGDELAY)+mySP.rit+1;
myFP.rit=(myREGDELAY1-myREGDELAY)+myFP.rit+1;
myADR.rit=(myREGDELAY1-myREGDELAY)+myADR.rit+1;
myIR.rit=(myREGDELAY1-myREGDELAY)+myIR.rit+1;
myACC.rit=(myREGDELAY1-myREGDELAY)+myACC.rit+1;
APPENDICE A.1 Il codice JAVASCRIPT 84
myB.rit=(myREGDELAY1-myREGDELAY)+myB.rit+1;
myC.rit=(myREGDELAY1-myREGDELAY)+myC.rit+1;
myMPC.rit=(myREGDELAY1-myREGDELAY)+myMPC.rit+1;
myREGDELAY=myREGDELAY1+1; //sommo +1 perche' nella gestione dei dispositivi effettuo .rit-- e poi controllo
}
if (myDECDELAY1!=myDECDELAY) { // DEC
myDEC.rit=(myDECDELAY1-myDECDELAY)+myDEC.rit+1;
mymSEQ.rit=(myDECDELAY1-myDECDELAY)+mymSEQ.rit+1;
myDecA.rit=(myDECDELAY1-myDECDELAY)+myDecA.rit+1;
myDecB.rit=(myDECDELAY1-myDECDELAY)+myDecB.rit+1;
myDecD.rit=(myDECDELAY1-myDECDELAY)+myDecD.rit+1;
myDECDELAY=myDECDELAY1+1;
}
if (myMPXDELAY1!=myMPXDELAY) { // MPX
myMPXM.rit=(myMPXDELAY1-myMPXDELAY)+myMPXM.rit+1;
myMPXD.rit=(myMPXDELAY1-myMPXDELAY)+myMPXD.rit+1;
myDpxCA.rit=(myMPXDELAY1-myMPXDELAY)+myDpxCA.rit+1;
myDpxCD.rit=(myMPXDELAY1-myMPXDELAY)+myDpxCD.rit+1;
myMPXDELAY=myMPXDELAY1+1;
}
if (myALUDELAY1!=myALUDELAY) { // ALU
myALU.rit=(myALUDELAY1-myALUDELAY)+myALU.rit+1;
myALUDELAY=myALUDELAY1+1;
}
if (myTRIDELAY1!=myTRIDELAY) { // TRISTATE
myTRISET.rit=(myTRIDELAY1-myTRIDELAY)+myTRISET.rit+1;
myTRIDELAY=myTRIDELAY1+1;
}
if (myCSDELAY1!=myCSDELAY) { // CONTROL STORE
myCSOUT.rit=(myCSDELAY1-myCSDELAY)+myCSOUT.rit+1;
myCSDELAY=myCSDELAY1+1;
}
run();
}
else {
myREGDELAY=(parseInt(parent.Parte3.document.VM1_PARTE3.ritREG.value,10) & 0x1F)+1; //massimo 31 t
myMPXDELAY=(parseInt(parent.Parte3.document.VM1_PARTE3.ritMPX.value,10) & 0x1F)+1;
myDECDELAY=(parseInt(parent.Parte3.document.VM1_PARTE3.ritDEC.value,10) & 0x1F)+1;
myTRIDELAY=(parseInt(parent.Parte3.document.VM1_PARTE3.ritTRI.value,10) & 0x1F)+1;
myALUDELAY=(parseInt(parent.Parte3.document.VM1_PARTE3.ritALU.value,10) & 0x1F)+1;
myCSDELAY=(parseInt(parent.Parte3.document.VM1_PARTE3.ritCS.value,10) & 0x1F)+1;
settaRIT();
reprint();
}
}
<!-------------------------->
<!-- RUN Phase -->
<!-------------------------->
function runph(){
var i=1;
for (i=1;i<11;i++) run()
}
<!-------------------------->
<!-- RUN Clock -->
<!-------------------------->
APPENDICE A.1 Il codice JAVASCRIPT 85
function runcl(){
var i=0;
for (i=0;i<4;i++) runph()
}
<!-------------------------->
<!-- RUN N.Clock -->
<!-------------------------->
function runNcl(){
var i=0;
for (i=0;i<parseInt(parent.Parte3.document.VM1_PARTE3.NClock.value,10);i++) runcl()
}
<!-------------------------->
<!-- RUN -->
<!-------------------------->
function run(){
var i=0;
var tmp=0;
if (myRUN==0){
myREGDELAY=(parseInt(parent.Parte3.document.VM1_PARTE3.ritREG.value,10) & 0x1F)+1; //massimo 31 t
myMPXDELAY=(parseInt(parent.Parte3.document.VM1_PARTE3.ritMPX.value,10) & 0x1F)+1;
myDECDELAY=(parseInt(parent.Parte3.document.VM1_PARTE3.ritDEC.value,10) & 0x1F)+1;
myTRIDELAY=(parseInt(parent.Parte3.document.VM1_PARTE3.ritTRI.value,10) & 0x1F)+1;
myALUDELAY=(parseInt(parent.Parte3.document.VM1_PARTE3.ritALU.value,10) & 0x1F)+1;
myCSDELAY=(parseInt(parent.Parte3.document.VM1_PARTE3.ritCS.value,10) & 0x1F)+1;
settaRIT();
myCSOUT.next=myCSRAM[0];
myCSOUT.old=myCSRAM[0];
myPh=1;
myDELTA=0;
myRUN=1;
}
myDELTA++;
if (myDELTA==11) {
myDELTA=1;
myPh++
if (myPh==5) {
myPh=1;
myCLOCK++;
myLOADMIR=false;
}
}
if (myDELTA==1) {
switch(myPh) { //Settaggi effettuati a seconda della fase di clock
case 1: //FASE 1
myMIR.next=myCSOUT.old
myMIR.dacambiare=true;
myMIR.rit=myREGDELAY;
break;
case 2: //FASE 2
if (myMAR.mar==1) {
myMAR.next=myAbus;
myMAR.dacambiare=true;
myMAR.rit=myREGDELAY;
}
break;
case 3: //FASE 3
APPENDICE A.1 Il codice JAVASCRIPT 86
case 3: //FASE 3
if (myDpxCD.en==1) {
switch(myDpxCD.old) { //setto il valore di entrata dei registri
case 0:
myIR.next=myCbus;
myIR.dacambiare=true;
myIR.rit=myREGDELAY;
break;
case 1:
myACC.next=myCbus;
myACC.dacambiare=true;
myACC.rit=myREGDELAY;
break;
case 2:
myB.next=myCbus;
myB.dacambiare=true;
myB.rit=myREGDELAY;
break;
case 3:
myC.next=myCbus;
myC.dacambiare=true;
myC.rit=myREGDELAY;
break;
}
}
tmp=(myCbus & 0xFFF);
if (myDpxCA.en==1) {
switch(myDpxCA.old) { //setto il valore di entrata dei registri
case 0:
myPC.next=tmp;
myPC.dacambiare=true;
myPC.rit=myREGDELAY;
break;
case 1:
mySP.next=tmp;
mySP.dacambiare=true;
mySP.rit=myREGDELAY;
break;
case 2:
myFP.next=tmp;
myFP.dacambiare=true;
myFP.rit=myREGDELAY;
break;
case 3:
myADR.next=tmp;
myADR.dacambiare=true;
myADR.rit=myREGDELAY;
break;
}
}
myMBR.dacambiare=true;
myMBR.rit=myREGDELAY;
break;
case 4:
myMPC.next=myMPXM.old;
myMPC.dacambiare=true;
myMPC.rit=myREGDELAY;
myENABLEDBUS=myCS;
break;
}
}
if (myMIR.dacambiare) {
myMIR.rit--;
if (myMIR.rit<=0){
myLOADMIR=true;
myMIR.old=myMIR.next;
//ho aggiunto 1 oggetto per riga quindi devo aumentare di 1 tutti i contatori
APPENDICE A.1 Il codice JAVASCRIPT 87
for (i=1;i<16;i++) {
parent.Parte4.document.Vm1control.elements[i].value=parent.Parte4.document.Vm1control.elements[i+17].value;
parent.Parte4.document.Vm1control.elements[i+17].value=myMIR.old.substring(i-1,i);
//prima era myMIR.old.substring(i,i+1); ora devo aggiungere 1
}
parent.Parte4.document.Vm1control.elements[0].value=parent.Parte4.document.Vm1control.elements[17].value;
parent.Parte4.document.Vm1control.elements[16].value=parent.Parte4.document.Vm1control.elements[33].value;
parent.Parte4.document.Vm1control.elements[33].value=myMIR.old.substring(15,18);
parent.Parte4.document.Vm1control.elements[17].value=myMPC.old;
//qui vado a copiare il valore del campo text nell'atro campo; NB. se l'utente lo cambia il valore erraro
//viene propagato alla sola cella gia' eseguita e quindi ININFLUENTE al corretto funzionamento.
//lo stesso per la cella nuova.
//Ho deciso di 'pescare' il valore dal testo per evitare di avere molte variabili globali che non servissero.
tmp=parseInt(parent.Parte4.document.Vm1control.elements[33].value,10);
//qui vado a scrivere la possibile cella da eseguire ma NON e' detto che sia questa bisogna vedere
//l'mSEQ che cosa decide potrei voler fare MPC++ ecco perche' devo aggiornare SEMPRE la prox. cella
//all'atto della memorizzarione del myMPC.old=myMPC.next
for (i=1;i<16;i++) {
parent.Parte4.document.Vm1control.elements[i+34].value=myCSRAM[tmp].substring(i-1,i);
}
parent.Parte4.document.Vm1control.elements[34].value=tmp;
parent.Parte4.document.Vm1control.elements[50].value=myCSRAM[tmp].substring(15,18);
myALU.alu=parseInt(myMIR.old.substring(0,1),10);
myALU.dacambiare=true;
myALU.rit=myALUDELAY;
myCS=parseInt(myMIR.old.substring(1,2),10);
myMAR.rw=parseInt(myMIR.old.substring(2,3),10);
myMAR.mar=parseInt(myMIR.old.substring(3,4),10);
myMBR.mbr=parseInt(myMIR.old.substring(4,5),10);
myMPXD.Dmpx=parseInt(myMIR.old.substring(5,6),10);
myMPXD.dacambiare=true;
myMPXD.rit=myMPXDELAY;
myDecA.Abus=parseInt(myMIR.old.substring(6,7),10);
myDecA.dacambiare=true;
myDecA.rit=myDECDELAY;
myDecB.Bbus=parseInt(myMIR.old.substring(7,8),10);
myDecB.dacambiare=true;
myDecB.rit=myDECDELAY;
myDpxCA.CAbus=parseInt(myMIR.old.substring(8,9),10);
myDpxCA.en=parseInt(myMIR.old.substring(9,10),10);
myDpxCA.dacambiare=true;
myDpxCA.rit=myMPXDELAY;
myDpxCD.CDbus=parseInt(myMIR.old.substring(10,11),10);
myDpxCD.en=parseInt(myMIR.old.substring(11,12),10);
myDpxCD.dacambiare=true;
myDpxCD.rit=myMPXDELAY;
myDecD.Dbus=parseInt(myMIR.old.substring(12,13),10);
myDecD.dacambiare=true;
myDecD.rit=myDECDELAY;
myINT=parseInt(myMIR.old.substring(13,14),10);
mymSEQ.mcond=parseInt(myMIR.old.substring(14,15),10);
mymSEQ.N=myALU.N;
APPENDICE A.1 Il codice JAVASCRIPT 88
mymSEQ.Z=myALU.Z;
mymSEQ.dacambiare=true;
mymSEQ.rit=myDECDELAY;
if (mymSEQ.old==2) { // se il canale 2 e' selezionato devo far computare al MPXM il valore nuovo.
myMPXM.dacambiare=true;
myMPXM.rit=myMPXDELAY;
}
myMIR.dacambiare=false;
myMIR.rit=myREGDELAY;
}
}
//********************************************************************
if (myDpxCD.dacambiare) {
myDpxCD.rit--;
if (myDpxCD.rit<=0) {
myDpxCD.old=myDpxCD.CDbus; //uso questi per contenere il segnale corretto
myTRISET.reg2=myDpxCD.old;
myDpxCD.dacambiare=false;
myDpxCD.rit=myMPXDELAY;
}
}
if (myDpxCA.dacambiare) {
myDpxCA.rit--;
if (myDpxCA.rit<=0) {
myDpxCA.old=myDpxCA.CAbus; //saranno i registri in fase 3 ad utilizzarlo
myTRISET.reg1=myDpxCA.old;
myDpxCA.dacambiare=false;
myDpxCA.rit=myMPXDELAY;
}
}
if (myDecA.dacambiare) {
myDecA.rit--;
if ((myDecA.rit+myTRIDELAY)<=0) {
myDecA.old=myDecA.Abus; //anche qui metto il valore che mi dice quale registro (valore) devo far passare
switch(myDecA.old) {
case 0:
myAbus=myPC.old;
break;
case 1:
myAbus=mySP.old;
break;
case 2:
myAbus=myFP.old;
break;
case 3:
myAbus=myADR.old;
break;
}
myTRISET.tri1=myDecA.old;
if (myMPXD.Dmpx==0) {
myMPXD.next=myAbus;
myMPXD.rit=myMPXDELAY;
myMPXD.dacambiare=true;
}
myDecA.rit=myDECDELAY;
myDecA.dacambiare=false;
}
}
if (myDecD.dacambiare) {
myDecD.rit--;
if ((myDecD.rit+myTRIDELAY)<=0) {
myDecD.old=myDecD.Dbus;
APPENDICE A.1 Il codice JAVASCRIPT 89
switch(myDecD.old) {
case 0:
myDbus=myIR.old;
break;
case 1:
myDbus=myACC.old;
break;
case 2:
myDbus=myB.old;
break;
case 3:
myDbus=myC.old;
break;
}
myTRISET.tri2=myDecD.old;
if (myMPXD.Dmpx==1) {
myMPXD.next=myDbus;
myMPXD.rit=myMPXDELAY;
myMPXD.dacambiare=true;
}
myDecD.rit=myDECDELAY;
myDecD.dacambiare=false;
}
}
if (myDecB.dacambiare) {
myDecB.rit--;
if ((myDecB.rit+myTRIDELAY)<=0) {
myDecB.old=myDecB.Bbus;
switch(myDecB.old) {
case 0:
myBbus=myIR.old;
break;
case 1:
myBbus=myACC.old;
break;
case 2:
myBbus=myB.old;
break;
case 3:
myBbus=myC.old;
break;
}
myTRISET.tri3=myDecB.old;
myIDec=(myBbus>>8);
tmp=myIDec;
if (tmp<240) {tmp >>>=4; //regola: indirizzo CS= (opcod)*2+32 quindi 1opcod0
//se l'istruzione non inizia con 1111xxxxxxxxxxxx allora prendo i 4 bit piu' significativi
//questo perche' l'istruzione e' codificata dai primi 4 bit mentre gli altri 12 fanno
//parte dell'operando
tmp=tmp*2+32;
}
else {tmp=tmp & 0x0F; //regola: indirizzo CS= (opcod)*2+96 quindi 11(4bit meno significativi)0
//prendo i 4 bit meno significativi
tmp=tmp*2+96;
}
myDEC.next=tmp;
myDEC.dacambiare=true;
myDEC.rit=myDECDELAY;
myDecB.rit=myDECDELAY;
myDecB.dacambiare=false;
myALU.b=myBbus;
myALU.dacambiare=true;
myALU.rit=myALUDELAY;
}
}
APPENDICE A.1 Il codice JAVASCRIPT 90
if ((myTRISET.dacambiare1) || (myTRISET.dacambiare2)) {
myTRISET.rit--;
if (myTRISET.rit<=0) {
if ((myTRISET.reg1 != -1) && (myTRISET.dacambiare1)){
if (myTRISET.reg1==myTRISET.tri1) {
myAbus=myTRISET.val1;
// if ((myPh==2) && (myMAR.mar==1)) { ///CHIEDERE ANCHE QUI...CHE FARNE DEL MAR in FASE 2???
// myMAR.dacambiare=true;
// myMAR.rit=myREGDELAY;
// }
myTRISET.reg1=-1;
myTRISET.dacambiare1=false;
}
}
if ((myTRISET.reg2 != -1) && (myTRISET.dacambiare2)){
if (myTRISET.reg2==myTRISET.tri2) {
myDbus=myTRISET.val2
if (myMPXD.Dmpx==1) {
myMPXD.next=myDbus;
myMPXD.dacambiare=true;
myMPXD.rit=myMPXDELAY;
}
}
if (myTRISET.reg2==myTRISET.tri3) {
myBbus=myTRISET.val2;
myIDec=(myBbus>>8);
tmp=myIDec;
if (tmp<240) {
tmp >>>=4;
tmp=tmp*2+32;
}
else {
tmp=tmp & 0x0F;
tmp=tmp*2+96;
}
myDEC.next=tmp;
myDEC.dacambiare=true;
myDEC.rit=myDECDELAY;
}
myTRISET.reg2=-1;
myTRISET.dacambiare2=false;
}
myTRISET.rit=myTRIDELAY;
}
}
if (myMAR.dacambiare) {
myMAR.rit--;
if (myMAR.rit<=0){
myMAR.old=myMAR.next;
myMAR.dacambiare=false;
myMAR.rit=myREGDELAY;
}
}
if (myMPXD.dacambiare) {
myMPXD.rit--;
if (myMPXD.rit<=0) {
myMPXD.old=myMPXD.next;
switch(myMPXD.Dmpx) {
case 0:
myALU.a=myAbus;
break;
case 1:
myALU.a=myDbus;
APPENDICE A.1 Il codice JAVASCRIPT 91
break;
case 2:
myALU.a=myMBR.old;
break;
case 3:
myALU.a=parseInt(myMIR.old.substring(15,18),10);
break;
}
myMPXD.dacambiare=false;
myMPXD.rit=myMPXDELAY;
myALU.dacambiare=true;
myALU.rit=myALUDELAY;
}
}
if (myDEC.dacambiare) {
myDEC.rit--;
if (myDEC.rit<=0) {
myDEC.old=myDEC.next;
myDEC.dacambiare=false;
myDEC.rit=myDECDELAY;
if (mymSEQ.old==0) {
myMPXM.next=myDEC.old;
myMPXM.rit=myMPXDELAY;
myMPXM.dacambiare=true; // indica il fatto che MPXM deve caricare dal Inst.DEC.
}
}
}
if (myALU.dacambiare) {
myALU.rit--;
if (myALU.rit<=0) {
switch(myALU.alu) {
case 0:
myCbus=myALU.a;
break;
case 1: // questo a causa del fatto che in Javascript il Not bit a bit e' fatto in complemento a 2
myCbus=(myALU.a^0xFFFF)
break;
case 2:
myCbus=(myALU.a<<1);
break;
case 3:
myCbus=(myALU.a>>1);
break;
case 4:
myCbus=(myALU.a+1);
break;
case 5:
myCbus=(myALU.a-1);
break;
case 6:
myCbus=(myALU.a+myALU.b);
break;
case 7:
myCbus=(myALU.a & myALU.b);
break;
}
myCbus=(myCbus & 0xFFFF); //per evitare l'OVERFLOW in tutti i vari casi
myALU.old=myCbus; //questo e' settato ma non serve.
if (myALU.old==0) myALU.Z=1
else myALU.Z=0
if ((myALU.old & 0x8000) !=0) myALU.N=1
else myALU.N=0
mymSEQ.N=myALU.N;
mymSEQ.Z=myALU.Z;
mymSEQ.dacambiare=true;
APPENDICE A.1 Il codice JAVASCRIPT 92
mymSEQ.rit=myDECDELAY;
myALU.dacambiare=false;
myALU.rit=myALUDELAY;
}
}
if (myIR.dacambiare) {
myIR.rit--;
if (myIR.rit<=0) {
myIR.old=myIR.next;
myIR.dacambiare=false;
myIR.rit=myREGDELAY;
myTRISET.val2=myIR.old;
myTRISET.dacambiare2=true;
myTRISET.rit=myTRIDELAY;
myTRISET.reg2=myDpxCD.old;
}
}
if (myACC.dacambiare) {
myACC.rit--;
if (myACC.rit<=0) {
myACC.old=myACC.next;
myACC.dacambiare=false;
myACC.rit=myREGDELAY;
myTRISET.val2=myACC.old;
myTRISET.dacambiare2=true;
myTRISET.rit=myTRIDELAY;
myTRISET.reg2=myDpxCD.old;
}
}
if (myB.dacambiare) {
myB.rit--;
if (myB.rit<=0) {
myB.old=myB.next;
myB.dacambiare=false;
myB.rit=myREGDELAY;
myTRISET.val2=myB.old;
myTRISET.dacambiare2=true;
myTRISET.rit=myTRIDELAY;
myTRISET.reg2=myDpxCD.old;
}
}
if (myC.dacambiare) {
myC.rit--;
if (myC.rit<=0) {
myC.old=myC.next;
myC.dacambiare=false;
myC.rit=myREGDELAY;
myTRISET.val2=myC.old;
myTRISET.dacambiare2=true;
myTRISET.rit=myTRIDELAY;
myTRISET.reg2=myDpxCD.old;
}
}
if (myPC.dacambiare) {
myPC.rit--;
if (myPC.rit<=0) {
myPC.old=myPC.next;
myPC.dacambiare=false;
myPC.rit=myREGDELAY;
myTRISET.val1=myPC.old;
myTRISET.dacambiare1=true;
myTRISET.rit=myTRIDELAY;
myTRISET.reg1=myDpxCA.old;
}
}
APPENDICE A.1 Il codice JAVASCRIPT 93
if (mySP.dacambiare) {
mySP.rit--;
if (mySP.rit<=0) {
mySP.old=mySP.next;
mySP.dacambiare=false;
mySP.rit=myREGDELAY;
myTRISET.val1=mySP.old;
myTRISET.dacambiare1=true;
myTRISET.rit=myTRIDELAY;
myTRISET.reg1=myDpxCA.old;
}
}
if (myFP.dacambiare) {
myFP.rit--;
if (myFP.rit<=0) {
myFP.old=myFP.next;
myFP.dacambiare=false;
myFP.rit=myREGDELAY;
myTRISET.val1=myFP.old;
myTRISET.dacambiare1=true;
myTRISET.rit=myTRIDELAY;
myTRISET.reg1=myDpxCA.old;
}
}
if (myADR.dacambiare) {
myADR.rit--;
if (myADR.rit<=0) {
myADR.old=myADR.next;
myADR.dacambiare=false;
myADR.rit=myREGDELAY;
myTRISET.val1=myADR.old;
myTRISET.dacambiare1=true;
myTRISET.rit=myTRIDELAY;
myTRISET.reg1=myDpxCA.old;
}
}
if (mymSEQ.dacambiare) {
mymSEQ.rit--;
if (mymSEQ.rit<=0){
tmp=mymSEQ.mcond;
switch(tmp) {
case 0:
mymSEQ.old=3;
myMPXM.next=myMPC.old+1;
break;
case 1:
mymSEQ.old=2;
myMPXM.next=parseInt(myMIR.old.substring(15,18),10);
break;
case 2:
if (mymSEQ.N==1) {
mymSEQ.old=2;
myMPXM.next=parseInt(myMIR.old.substring(15,18),10)
}
else {
mymSEQ.old=3;
myMPXM.next=myMPC.old+1;
}
break;
case 3:
if (mymSEQ.Z==1) {
mymSEQ.old=2;
myMPXM.next=parseInt(myMIR.old.substring(15,18),10)
}
else {
mymSEQ.old=3;
APPENDICE A.1 Il codice JAVASCRIPT 94
myMPXM.next=myMPC.old+1;
}
break;
case 4:
mymSEQ.old=1;
myMPXM.next=0;
break;
case 5:
myMPXM.next=myDEC.old;
mymSEQ.old=0;
break;
case 6:
if (parseInt(myMIR.old.substring(13,14),10)==3) {
mymSEQ.old=2;
myMPXM.next=parseInt(myMIR.old.substring(15,18),10)
}
else {
mymSEQ.old=3;
myMPXM.next=myMPC.old+1;
}
break;
case 7:
//non utilizzata
break;
}
myMPXM.dacambiare=true;
myMPXM.rit=myMPXDELAY;
mymSEQ.rit=myDECDELAY;
mymSEQ.dacambiare=false;
}
}
if (myMPXM.dacambiare) {
myMPXM.rit--;
if (myMPXM.rit<=0) {
// Nella simulazione del MicroSEQ e' gia' stato inserito il valore giusto nel campo myMPX.next
// quindi occorre solo assegnarlo.
myMPXM.old=myMPXM.next;
myMPXM.dacambiare=false;
myMPXM.rit=myMPXDELAY;
}
}
if (myMPC.dacambiare) {
myMPC.rit--;
if (myMPC.rit<=0) {
myMPC.old=myMPC.next;
myCSOUT.next=myCSRAM[myMPC.old];
myMPC.dacambiare=false;
myMPC.rit=myREGDELAY;
myCSOUT.dacambiare=true;
myCSOUT.rit=myCSDELAY;
}
}
if (myCSOUT.dacambiare) {
myCSOUT.rit--;
if (myCSOUT.rit<=0) {
for (i=1;i<16;i++) parent.Parte4.document.Vm1control.elements[i+34].value=myMIR.next.substring(i-1,i)
parent.Parte4.document.Vm1control.elements[34].value=myMPC.old;
parent.Parte4.document.Vm1control.elements[50].value=myMIR.next.substring(15,18);
myCSOUT.old=myCSOUT.next;
myCSOUT.dacambiare=false;
myCSOUT.rit=myCSDELAY;
}
}
APPENDICE A.1 Il codice JAVASCRIPT 95
if (myMBR.dacambiare) {
myMBR.rit--;
if (myMBR.rit<=0) {
if (myMBR.mbr==1) {
if ((myMAR.rw==1) && (myENABLEDBUS==1)) {
myMBR.old=myRAM[myMAR.old];
if (myMPXD.Dmpx==2) {
myMPXD.next=myMBR.old;
myMPXD.dacambiare=true;
myMPXD.rit=myMPXDELAY;
}
}
if ((myMAR.rw==0) && (myENABLEDBUS==0)) myMBR.old=myCbus
}
if ((myMAR.rw==0) && (myENABLEDBUS==1)) {
myRAM[myMAR.old]=myMBR.old
}
myMBR.dacambiare=false;
myMBR.rit=myREGDELAY;
}
}
reprint();
}
<!-------------------------->
<!-- Conversione Numeri -->
<!-------------------------->
function printnumb(myCoding,noBits,i) {
var j = 0
var k = 0
var l = 0
var mask = 32768
var str = ""
if ( myCoding == 0 ) {//UNICODE
if ( (i < 10) && (noBits > 12) )
return("0000"+i)
else if ( (i < 10) || ((i < 100) && (noBits > 12)) )
return("000"+i)
else if ( (i < 100) || ((i < 1000) && (noBits > 12)) )
return("00"+i)
else if ( (i < 1000) || ((i < 10000) && (noBits > 12)) )
return("0"+i)
else
return(+i)
} else if ( myCoding == 1 ) {//BINARIO
mask = 1 << (noBits-1)
str = ""
for (j=noBits ; j > 0 ; j--) {
if ( i & mask )
str += "1"
else
str += "0"
mask >>= 1
}
return(str)
} else if ( myCoding == 2 ) {//OTTALE
str = ""
mask = 7
l = i
for (j=(noBits+2)/3 ; j >= 1 ; j--) {
k = l & mask;
if ( k < 4 ) {
if ( k < 2 ) {
if ( k < 1 )
APPENDICE A.1 Il codice JAVASCRIPT 96
str = "0"+str
else
str = "1"+str
} else {
if ( k < 3 )
str = "2"+str
else
str = "3"+str
}
} else {
if ( k < 6 ) {
if ( k < 5 )
str = "4"+str
else
str = "5"+str
} else {
if ( k < 7 )
str = "6"+str
else
str = "7"+str
}
}
l = l / 8
}
return(str)
} else if ( myCoding == 3 ) {//ESADECIMALE
str = ""
mask = 15
l = i
for (j=(noBits+3), j >>= 2 ; j > 0 ; j--) {
k = l & mask;
if ( k < 8 ) {
if ( k < 4 ) {
if ( k < 2 ) {
if ( k < 1 )
str = "0"+str
else
str = "1"+str
} else {
if ( k < 3 )
str = "2"+str
else
str = "3"+str
}
} else {
if ( k < 6 ) {
if ( k < 5 )
str = "4"+str
else
str = "5"+str
} else {
if ( k < 7 )
str = "6"+str
else
str = "7"+str
}
}
} else {
if ( k < 12 ) {
if ( k < 10 ) {
if ( k < 9 )
str = "8"+str
else
str = "9"+str
} else {
if ( k < 11 )
str = "A"+str
else
str = "B"+str
APPENDICE A.1 Il codice JAVASCRIPT 97
}
} else {
if ( k < 14 ) {
if ( k < 13 )
str = "C"+str
else
str = "D"+str
} else {
if ( k < 15 )
str = "E"+str
else
str = "F"+str
}
}
}
l = l / 16
}
return(str)
} else if ( myCoding == 4 ) {//DECIMALE
str = ""
mask = 1<<(noBits -1)
if ( i & mask ) {
str += "-"
i ^= 0xFFF
if ( noBits > 12 )
i ^= 0xF000
i += 1
i &= 0xFFFF
if ( noBits == 12 )
i &= 0xFFF
}
return(str+i)
}else if ( myCoding == 5 ) {//RIMANE COM'E'
return(i)
}
}
<!-------------------------->
<!-- Reset della RAM VM-2 -->
<!-------------------------->
function resetRAM() {
var i = 0;
for (i=0 ; i < 4096 ; i++) //inclobo anche il reg4094 (input) e reg4095 (output)
myRAM[i] = 0;
}
<!-------------------------->
<!-- Reset della CS VM-1 -->
<!-------------------------->
function resetCSRAM() {
var i = 0;
for (i=0 ; i < 128 ; i++)
myCSRAM[i] = "000000000000000000";
}
<!-------------------------->
<!-- Load FILE VM-2 -->
<!-------------------------->
function load_fileVM2() {
var filn = parent.Parte1.document.VM1_PARTE1.VM2_program_file.value;
var myarr = parent.Parte1.document.applets[0].RamLines(filn);
var i = 0;
var mystr = "";
var j = 0;
resetRAM();
for ( mystr = myarr[0] ; mystr != null ; i++, mystr = myarr[i] ) {
j = parseInt(mystr,16);
if ( j == NaN )
break
APPENDICE A.1 Il codice JAVASCRIPT 98
j &= 0xFFFF;
myRAM[i] = j;
}
alert("Caricato nella RAM il prg VM2");
}
<!------------------------>
<!-- Apri FinestraCS -->
<!------------------------>
function apriCS() {
wCS=window.open("cs.html","Gestione_CONTROLSTORE");
}
<!------------------------>
<!-- Apri FinestraRAM -->
<!------------------------>
function apriRAM(modalita,num) {//serve per far chiedere la cella (in questo modo metto i 2 tasti di avanti e indietro).
if (num==-1) num=parseInt(window.prompt("Inserire la cella di memoria VM2 da cosiderare:",0),10)
if ((num<0) || (num>4095)) num=-100
else if (num<=5) num=5
else if (num>=4091) num=4091
if (num>=5) { //controllo che sia alemeno 5
wRAM=window.open("","VM2_RAM","HEIGHT=150,WIDTH=600,RESIZABLE"); //deve essere globale cosi' riscrive sulla stessa
var doc=wRAM.document;
var myzeros = "";
var i=0;
parent.myOPENRAM=true;
doc.write("<HTML><HEAD><TITLE>RAM VM2</TITLE></HEAD><BODY BACKGROUND='sfondo4.gif' text='Maroon'>");
doc.write("<SCRIPT>var cella="+num+";\n");
doc.write("var i=0;var msg='Modalita protetta!!!';\n");
doc.write("function salvaCELLE(){\n");
doc.write("if (document.VM2RAM.modo.checked) alert(msg)\n");
doc.write(" else \n");
doc.write(" {for (i=(cella-5);i<(cella+5);i++) opener.myRAM[i]=parseInt(document.VM2RAM.elements[i-(cella-5)].value,16)\n");
doc.write(" alert('Dati memorizzati...');}\n");
doc.write("}</SCRIPT>");
doc.write("<FORM Name='VM2RAM'>");
doc.write("<TABLE BORDER>");
doc.write("<TR ALIGN=center>");
for (i=(num-5);i<(num+5);i++) {
myzeros = ""
if ( i < 10000 ) {
if ( i < 10 )
myzeros = "000"
else if ( i < 100 )
myzeros = "00"
else if ( i < 1000 )
myzeros = "0"
}
doc.write("<TD><A NAME='CELLA"+i+"'>CELLA<BR>"+myzeros+i+"<BR><INPUT TYPE=Text Name='ctrCELLA"+i+"' maxlength=4 Value='0000' Size=4>");
}
doc.write("</TABLE><TABLE><TR><TD>");
doc.write("<INPUT type='Checkbox' name='modo' ");
if (modalita) doc.write("checked");
doc.write(" onclick='javascript:document.VM2RAM.salvaRAM.disabled=document.VM2RAM.modo.checked'><NOBR>Modalita' protetta</NOBR>");
doc.write("<TD><INPUT TYPE=Button Name='salvaRAM' Value='SaveRAM' ");
if (modalita) doc.write("DISABLED");
APPENDICE A.1 Il codice JAVASCRIPT 99
doc.write(" onclick='salvaCELLE()'>");
doc.write("<TD><INPUT type='button' value='AltraCELLA' onclick='opener.top.apriRAM(document.VM2RAM.modo.checked,-1)'>");
doc.write("<TD><INPUT type='button' value='CloseRAM' onclick='opener.top.myOPENRAM=false;parent.window.close()'>");
doc.write("<TD><INPUT type='button' value=' < ' onclick='opener.top.apriRAM(document.VM2RAM.modo.checked,cella-5)'>");
doc.write("<TD><INPUT type='button' value=' > ' onclick='opener.top.apriRAM(document.VM2RAM.modo.checked,cella+5)'>");
doc.write("<SCRIPT>for (i=(cella-5);i<(cella+5);i++) document.VM2RAM.elements[i-(cella-5)].value=opener.top.printnumb(3,16,opener.top.myRAM[i])</SCRIPT>");
doc.write("</TABLE></FORM></BODY></HTML>");
doc.close();
wRAM.focus();
}
}
<!------------------------>
<!-- Reset Variabili -->
<!------------------------>
function resetVAR(){
var i=0;
myRUN=0;
myAbus=0;
myBbus=0;
myCbus=0;
myDbus=0;
myIDec=0;
myA=0;
myCS=0;
myINT=0;
myCLOCK=0;
myPh=0;
myDELTA=0;
myLOADMIR=false;
myENABLEDBUS=0;
initDISP();
myTRISET.dacambiare1=false;
myTRISET.dacambiare2=false;
myTRISET.reg1=-1;
myTRISET.val1=0;
myTRISET.tri1=0;
myTRISET.reg2=-1;
myTRISET.val2=0;
myTRISET.tri2=0;
myTRISET.tri3=0;
myTRISET.rit=0;
for (i=0;i<16;i++) {
parent.Parte4.document.Vm1control.elements[i].value=0;
parent.Parte4.document.Vm1control.elements[i+17].value=0;
parent.Parte4.document.Vm1control.elements[i+34].value=0;
}
parent.Parte4.document.Vm1control.elements[16].value="000";
parent.Parte4.document.Vm1control.elements[33].value="000";
parent.Parte4.document.Vm1control.elements[50].value="000";
reprint();
}
<!------------------------>
<!-- Resetta ALL -->
<!------------------------>
function resetALL(){
initDISP();
resetRAM();
}
APPENDICE A.1 Il codice JAVASCRIPT 100
resetALL();
resetCSRAM(); //Non lo si mette nella funzione sopra perche' tutte le volte che la
//si richiama si sarebbe contretti a ricaricare la Control Store
//****************************************************
// Fine del file javascript <<<VM1EMUL.JS>>>
//****************************************************
A.2 Il codice JAVA
Il codice seguente e' quello dell'APPLET JAVA [JAVA2] che si occupa di leggere da file e di stampare il contenuto della CONTROL STORE nel System.out di sistema (in questo caso la JAVA CONSOLE).
Il nome del file e' LOADRAM.JAVA.
import java.io.*;
import java.net.URL;
import java.util.*;
/**
*
*/
public class loadram extends java.applet.Applet {
public void stampa (String testo) {
System.out.println (testo);
}
/** Initializes the applet */
public void init () {
initComponents ();
}
/** This method is called from within the init() method to
* initialize the form.
*/
private void initComponents () {//GEN-BEGIN:initComponents
setLayout (new java.awt.BorderLayout ());
setVisible (false);
}
public String[] RamLines(String filename) {
String[] my_arr = new String[4000];
APPENDICE A.2 Il codice JAVA 101
String line = new String();
try {
DataInputStream ifile = new DataInputStream (new URL(getDocumentBase(),filename).openStream());
line=ifile.readLine();
for (int i=0; line.length() > 0 ; i++) {
my_arr[i] = line;
line=ifile.readLine();
}
ifile.close();
} catch (IOException ioe){
ioe.printStackTrace();
}
return (my_arr);
}
}
A.3 Il codice HTML
Di seguito si puo’ vedere tutto il codice HTML del SIMULATORE integrato con funzioni JAVASCRIPT.
Il nome del file HTML principale e' INDEX.HTML e a seguire tutti gli altri.
<<< INDEX.HTML >>>
<HTML>
<HEAD>
<TITLE>Simulatore di macchine virtuali a livello di MICROARCHITETTURA VM1 - Antonio Scorza (C)</TITLE>
<SCRIPT LANGUAGE="Javascript" src="vm1emul.js"> </SCRIPT>
</HEAD>
<FRAMESET ROWS="65%,*">
<FRAMESET COLS="40%,*">
<FRAME NAME= "Parte2" SRC="parte2.html">
<FRAMESET ROWS="25%,*">
<FRAME NAME= "Parte1" SRC="parte1.html">
<FRAME NAME= "Parte3" SRC="parte3.html">
</FRAMESET>
</FRAMESET>
<FRAME NAME= "Parte4" SRC="parte4.html#CELLA">
</FRAMESET>
</HTML>
APPENDICE A.3 Il codice HTML 102
Di seguito il codice HTML contenuto nel file PARTE1.HTML.
<<< PARTE1.HTML >>>
<HTML>
<SCRIPT>
var myMODALITARAM=true;
</SCRIPT>
<BODY BACKGROUND="sfondo4.gif" text="Maroon">
<FORM Name="VM1_PARTE1">
<TABLE>
<TR>
<TD>
<NOBR>VM2 File:</NOBR>
<TD>
<INPUT type="file" name="VM2_program_file" accept="*" size="30">
<APPLET name="myApplet" code="loadram.class" width="1" height="1"></APPLET>
</TABLE>
<TABLE>
<TR>
<TD>
<INPUT type="button" value="LoadVM2" onclick="parent.load_fileVM2()">
<TD>
<INPUT type="button" value="ApriRAM" onclick="parent.apriRAM(myMODALITARAM,-1)">
<TD>
<INPUT TYPE="button" value="ResetRAM" onclick="parent.resetRAM();if (parent.myOPENRAM) {top.wRAM.close();parent.myOPENRAM=false}">
</TABLE>
</FORM>
</BODY>
</HTML>
Di seguito il codice HTML contenuto nel file PARTE2.HTML.
<<< PARTE2.HTML >>>
<HTML>
<HEAD>
</HEAD>
<BODY BACKGROUND="sfondo2.gif">
<FORM Name="VM1_PARTE2">
<TABLE BORDER=1 >
<TR>
<TD><FONT color="0000FF">MAR:</FONT>
<TD>
<INPUT TYPE=Text Name="regMAR" maxlength=5 Value="0000" Size=6>
<TD><FONT color="0000FF">PC:</FONT>
<TD>
<INPUT TYPE=Text Name="regPC" maxlength=5 Value="0000" Size=6>
APPENDICE A.3 Il codice HTML 103
<TR>
<TD>DpxCA
<TD>
<INPUT TYPE=Text Name="DpxCA" readonly Value=0 Size=1>
<TD><FONT color="0000FF">SP:</FONT>
<TD>
<INPUT TYPE=Text Name="regSP" maxlength=5 Value="0000" Size=6>
<TD>ABus:
<TD>
<INPUT TYPE=Text Name="Abus" readonly Value="0000" Size=6>
<TR>
<TD>DecA
<TD>
<INPUT TYPE=Text Name="DecA" readonly Value=0 Size=1>
<TD><FONT color="0000FF">FP:</FONT>
<TD>
<INPUT TYPE=Text Name="regFP" maxlength=5 Value="0000" Size=6>
<TR>
<TD>
<TD>
<TD><FONT color="0000FF">ADR:</FONT>
<TD>
<INPUT TYPE=Text Name="regADR" maxlength=5 Value="0000" Size=6>
<TD>BBus:
<TD>
<INPUT TYPE=Text Name="Bbus" readonly Value="00000" Size=6>
<TR>
<TD><FONT color="0000FF">MBR: </FONT>
<TD>
<INPUT type=Text name="regMBR" maxlength=6 value="00000" size=6>
<TD><FONT color="0000FF">IR:</FONT>
<TD>
<INPUT type=Text name="regIR" maxlength=6 value="00000" size=6>
<TR>
<TD>DpxCD
<TD>
<INPUT TYPE=Text Name="DpxCD" readonly Value=0 Size=1>
<TD><FONT color="0000FF">ACC:</FONT>
<TD>
<input type=Text name="regACC" maxlength=6 value="00000" size=6>
<TD>CBus:
<TD>
<INPUT TYPE=Text Name="Cbus" readonly Value="00000" Size=6>
<TR>
<TD>DecB
<TD>
<INPUT TYPE=Text Name="DecB" readonly Value=0 Size=1>
<TD><FONT color="0000FF">B:</FONT>
<TD>
<input type=Text name="regB" maxlength=6 value="00000" size=6>
<TR>
<TD>DecD
<TD>
<INPUT TYPE=Text Name="DecD" readonly Value=0 Size=1>
<TD><FONT color="0000FF">C:</FONT>
<TD>
<input type=Text name="regC" maxlength=6 value="00000" size=6>
<TD>DBus:
<TD>
<INPUT TYPE=Text Name="Dbus" readonly Value="00000" Size=6>
<TR>
<TD COLSPAN=1 ALIGN="CENTER">
<INPUT TYPE=Button Name="ResetVAR" value="Reset" onclick="parent.resetVAR()">
<TD COLSPAN=2 ALIGN="CENTER">
<INPUT type=button value="FutureVAL" onclick="parent.valori()">
APPENDICE A.3 Il codice HTML 104
<TD COLSPAN=2 ALIGN="CENTER">
<INPUT TYPE=Button Name="SalvaVALORI" value="SalvaVAL" onclick="parent.salvaVAL()">
<TD ALIGN="CENTER">
<INPUT TYPE=Button Name="View" value="View" onclick="parent.viewVAL()">
</TABLE>
</FORM>
</BODY>
</HTML>
Di seguito il codice HTML contenuto nel file PARTE3.HTML.
<<< PARTE3.HTML >>>
<HTML>
<BODY BACKGROUND="sfondo1.gif">
<FORM ENCTYPE="multipart/form-data" Name="VM1_PARTE3">
<TABLE BORDER=1 >
<TR>
<TD>a:
<TD>
<INPUT TYPE=Text Name="aluA" readonly Value="00000" Size=6>
<TD>IDec:
<TD>
<INPUT TYPE=Text Name="IDec" readonly Value="0000" Size=4>
<TD>
<TD COLSPAN=8 ALIGN="CENTER">RITARDI
<TR>
<TD>N:
<TD>
<INPUT TYPE=Text Name="aluN" readonly Value=0 Size=1>
<TD>Dec:
<TD>
<INPUT TYPE=Text Name="Decode" readonly Value="0000" Size=4>
<TD>
<TD>Reg:
<TD>
<INPUT TYPE=Text Name="ritREG" maxlength=2 Value=0 Size=2>
<TD>Dec:
<TD>
<INPUT TYPE=Text Name="ritDEC" maxlength=2 Value=0 Size=2>
<TD>Mpx:
<TD>
<INPUT TYPE=Text Name="ritMPX" maxlength=2 Value=0 Size=2>
<TR>
<TD>Z:
<TD>
<INPUT TYPE=Text Name="aluZ" readonly Value=0 Size=1>
<TD>MPXM:
<TD>
<INPUT TYPE=Text Name="mpxm" readonly Value="0000" Size=4>
<TD>
<TD>Alu:
<TD>
<INPUT TYPE=Text Name="ritALU" maxlength=2 Value=0 Size=2>
<TD>CS:
<TD>
APPENDICE A.3 Il codice HTML 105
<INPUT TYPE=Text Name="ritCS" maxlength=2 Value=0 Size=2>
<TD>Tri:
<TD>
<INPUT TYPE=Text Name="ritTRI" maxlength=2 Value=0 Size=2>
<TR>
<TD>m.SEQ:
<TD>
<INPUT TYPE=Text Name="mSEQ" readonly Value=0 Size=1>
<TD><FONT color="0000FF">MPC:</FONT>
<TD>
<INPUT TYPE=Text Name="regMPC" maxlength=4 Value="0000" Size=4>
<TD>
<TD COLSPAN=3 ALIGN="CENTER"> <INPUT TYPE=Button Name="SalvaRITARDI" value="SalvaRIT" onclick="parent.salvaRIT()">
</TABLE>
<TABLE>
<TD>CLOCK:
<TD>
<INPUT TYPE=Text Name="Clock" readonly Value=0 Size=4>
<TD>Ph:
<TD>
<INPUT TYPE=Text Name="Fase" readonly Value=0 Size=1>
<TD>At:
<TD>
<INPUT TYPE=Text Name="DeltaT" readonly Value=0 Size=2>
<TD>
<NOBR>
<INPUT type=Radio name="COD" checked onClick="parent.changeCOD()">Unicode
<INPUT type=Radio name="COD" onClick="parent.changeCOD()">Decimale
<INPUT type=Radio name="COD" onClick="parent.changeCOD()">Esadecimale
</NOBR>
</TABLE>
<TABLE>
<TR>
<TD>
<INPUT type=button value="ApriCS" onclick="parent.apriCS()">
<TD>
<INPUT TYPE=Button Name="RunCl" value="RunCl" onclick="parent.runcl()">
<TD>
<INPUT TYPE=Button Name="RunPh" value="RunPh" onclick="parent.runph()">
<TD>
<INPUT TYPE=Button Name="Run" value="RunAt" onclick="parent.run()">
<TD>
<INPUT TYPE=Button Name="RunNCl" value="Run N.Cl." onclick="parent.runNcl()">
<TD>
<INPUT TYPE=Text Name="NClock" Value=0 Size=2>
</TABLE>
</FORM>
</BODY></HTML>
Di seguito il codice HTML contenuto nel file PARTE4.HTML.
APPENDICE A.3 Il codice HTML 106
<<< PARTE4.HTML >>>
<HTML>
<BODY BACKGROUND="sfondo3.gif" text="Maroon">
<FORM Name="Vm1control">
<TABLE BORDER align="center">
<TR ALIGN=center>
<TD><A NAME='CELLA_P'>MIR Prec.<BR>Cella
<INPUT TYPE=Text Name="cellaOLD" Value=0 Size=3>
<TD>ALU<BR>
<INPUT TYPE=Text Name="ctrALU_P" Value=0 Size=3>
<TD>CS<BR>
<INPUT TYPE=Text Name="ctrCS_P" Value=0 Size=1>
<TD>R/nW<BR>
<INPUT TYPE=Text Name="ctrRW_P" Value=0 Size=1>
<TD>MAR<BR>
<INPUT TYPE=Text Name="ctrMAR_P" Value=0 Size=1>
<TD>MBR<BR>
<INPUT TYPE=Text Name="ctrMBR_P" Value=0 Size=1>
<TD>Dmpx<BR>
<INPUT TYPE=Text Name="ctrDMPX_P" Value=0 Size=2>
<TD>Abus<BR>
<INPUT TYPE=Text Name="ctrABUS_P" Value=0 Size=2>
<TD>Bbus<BR>
<INPUT TYPE=Text Name="ctrBBUS_P" Value=0 Size=2>
<TD>CAbus<BR>
<INPUT TYPE=Text Name="ctrCABUS_P" Value=0 Size=2>
<TD>CAen<BR>
<INPUT TYPE=Text Name="ctrCAEN_P" Value=0 Size=1>
<TD>CDbus<BR>
<INPUT TYPE=Text Name="ctrCDBUS_P" Value=0 Size=2>
<TD>CDen<BR>
<INPUT TYPE=Text Name="ctrCDEN_P" Value=0 Size=1>
<TD>Dbus<BR>
<INPUT TYPE=Text Name="ctrDBUS_P" Value=0 Size=2>
<TD> Int <BR>
<INPUT TYPE=Text Name="ctrINT_P" Value=0 Size=2>
<TD>mcond<BR>
<INPUT TYPE=Text Name="ctrMCOND_P" Value=0 Size=3>
<TD>Addr<BR>
<INPUT TYPE=Text Name="ctrADDR_P" Value="000" Size=7>
</TR>
<TR ALIGN=center>
<TD><A NAME='CELLA'>MIR Att.<BR>Cella
<INPUT TYPE=Text Name="cellaNOW" Value=0 Size=3>
<TD>ALU<BR>
<INPUT TYPE=Text Name="ctrALU" Value=0 Size=3>
<TD>CS<BR>
<INPUT TYPE=Text Name="ctrCS" Value=0 Size=1>
<TD>R/nW<BR>
<INPUT TYPE=Text Name="ctrRW" Value=0 Size=1>
<TD>MAR<BR>
<INPUT TYPE=Text Name="ctrMAR" Value=0 Size=1>
<TD>MBR<BR>
<INPUT TYPE=Text Name="ctrMBR" Value=0 Size=1>
<TD>Dmpx<BR>
<INPUT TYPE=Text Name="ctrDMPX" Value=0 Size=2>
<TD>Abus<BR>
<INPUT TYPE=Text Name="ctrABUS" Value=0 Size=2>
<TD>Bbus<BR>
<INPUT TYPE=Text Name="ctrBBUS" Value=0 Size=2>
<TD>CAbus<BR>
<INPUT TYPE=Text Name="ctrCABUS" Value=0 Size=2>
<TD>CAen<BR>
<INPUT TYPE=Text Name="ctrCAEN" Value=0 Size=1>
<TD>CDbus<BR>
APPENDICE A.3 Il codice HTML 107
<INPUT TYPE=Text Name="ctrCDBUS" Value=0 Size=2>
<TD>CDen<BR>
<INPUT TYPE=Text Name="ctrCDEN" Value=0 Size=1>
<TD>Dbus<BR>
<INPUT TYPE=Text Name="ctrDBUS" Value=0 Size=2>
<TD> Int <BR>
<INPUT TYPE=Text Name="ctrINT" Value=0 Size=2>
<TD>mcond<BR>
<INPUT TYPE=Text Name="ctrMCOND" Value=0 Size=3>
<TD>Addr<BR>
<INPUT TYPE=Text Name="ctrADDR" Value="000" Size=7>
</TR>
<TR ALIGN=center>
<TD><A NAME='CELLA_N'>MIR Prox.<BR>Cella
<INPUT TYPE=Text Name="cellaNEW" Value=0 Size=3>
<TD>ALU<BR>
<INPUT TYPE=Text Name="ctrALU_N" Value=0 Size=3>
<TD>CS<BR>
<INPUT TYPE=Text Name="ctrCS_N" Value=0 Size=1>
<TD>R/nW<BR>
<INPUT TYPE=Text Name="ctrRW_N" Value=0 Size=1>
<TD>MAR<BR>
<INPUT TYPE=Text Name="ctrMAR_N" Value=0 Size=1>
<TD>MBR<BR>
<INPUT TYPE=Text Name="ctrMBR_N" Value=0 Size=1>
<TD>Dmpx<BR>
<INPUT TYPE=Text Name="ctrDMPX_N" Value=0 Size=2>
<TD>Abus<BR>
<INPUT TYPE=Text Name="ctrABUS_N" Value=0 Size=2>
<TD>Bbus<BR>
<INPUT TYPE=Text Name="ctrBBUS_N" Value=0 Size=2>
<TD>CAbus<BR>
<INPUT TYPE=Text Name="ctrCABUS_N" Value=0 Size=2>
<TD>CAen<BR>
<INPUT TYPE=Text Name="ctrCAEN_N" Value=0 Size=1>
<TD>CDbus<BR>
<INPUT TYPE=Text Name="ctrCDBUS_N" Value=0 Size=2>
<TD>CDen<BR>
<INPUT TYPE=Text Name="ctrCDEN_N" Value=0 Size=1>
<TD>Dbus<BR>
<INPUT TYPE=Text Name="ctrDBUS_N" Value=0 Size=2>
<TD> Int <BR>
<INPUT TYPE=Text Name="ctrINT_N" Value=0 Size=2>
<TD>mcond<BR>
<INPUT TYPE=Text Name="ctrMCOND_N" Value=0 Size=3>
<TD>Addr<BR>
<INPUT TYPE=Text Name="ctrADDR_N" Value="000" Size=7>
</TR>
</TABLE>
</FORM>
</HTML>
Di seguito il codice HTML contenuto nel file CS.HTML.
<<< CS.HTML >>>
<HTML>
<HEAD>
APPENDICE A.3 Il codice HTML 108
<SCRIPT>
myFRAME= 0 /* SE 0--> 0-15 1--> 16-31 2--> 32-47 3--> 48-63 */
/* 4--> 64-79 5--> 80-95 6--> 96-111 7--> 112-127 */
myPROTETTA=true /* Modalita protetta TRUE, FALSE altrimenti */
myPRIMOLOAD=true /* Serve per non fare la prima settasalva visto che l'ele- */
/* mento di tipo CheckBox non e' definito */
function salvaCS(){
var i=0;
/* SERVE PER STAMPARE NELLA CONSOL JAVA */
for (i=0;i<128;i++)
frameMENUCS.document.applets[0].stampa(top.opener.myCSRAM[i])
alert("Contenuto della CONTROL STORE stampata\n"+"nella JAVA CONSOLE...");
}
function salvacella(cella){
var i=0;
var numero=0;
var testo="";
if (!myPROTETTA) {
for (i=0;i<16;i++) {
if (myFRAME==0)
numero=parseInt(frameCELLE.document.formVM1RAM00.elements[(17*cella)+i].value,10);
else if (myFRAME==1)
numero=parseInt(frameCELLE.document.formVM1RAM16.elements[(17*(cella-16))+i].value,10);
else if (myFRAME==2)
numero=parseInt(frameCELLE.document.formVM1RAM32.elements[(17*(cella-32))+i].value,10);
else if (myFRAME==3)
numero=parseInt(frameCELLE.document.formVM1RAM48.elements[(17*(cella-48))+i].value,10);
else if (myFRAME==4)
numero=parseInt(frameCELLE.document.formVM1RAM64.elements[(17*(cella-64))+i].value,10);
else if (myFRAME==5)
numero=parseInt(frameCELLE.document.formVM1RAM80.elements[(17*(cella-80))+i].value,10);
else if (myFRAME==6)
numero=parseInt(frameCELLE.document.formVM1RAM96.elements[(17*(cella-96))+i].value,10);
else
numero=parseInt(frameCELLE.document.formVM1RAM112.elements[(17*(cella-112))+i].value,10);
testo=testo + numero;
}
top.opener.myCSRAM[cella]=testo;
/* frameMENUCS.document.applets[0].stampa(testo) SERVIVA PER STAMPARE NELLA CONSOL JAVA */
}
else alert("Modalita protetta!!!\nImpossibile modificare la CONTROL STORE.")
}
function settasalva(){
var i=0;
APPENDICE A.3 Il codice HTML 109
if (!parent.myPRIMOLOAD) {
myPROTETTA= frameMENUCS.document.formMENUCS.modalita.checked;
if (myFRAME==0) {
for (i=0;i<16;i++)
frameCELLE.document.formVM1RAM00.elements[16+(i*17)].disabled=myPROTETTA
}
else if (myFRAME==1) {
for (i=0;i<16;i++)
frameCELLE.document.formVM1RAM16.elements[16+(i*17)].disabled=myPROTETTA
}
else if (myFRAME==2) {
for (i=0;i<16;i++)
frameCELLE.document.formVM1RAM32.elements[16+(i*17)].disabled=myPROTETTA
}
else if (myFRAME==3) {
for (i=0;i<16;i++)
frameCELLE.document.formVM1RAM48.elements[16+(i*17)].disabled=myPROTETTA
}
else if (myFRAME==4) {
for (i=0;i<16;i++)
frameCELLE.document.formVM1RAM64.elements[16+(i*17)].disabled=myPROTETTA
}
else if (myFRAME==5) {
for (i=0;i<16;i++)
frameCELLE.document.formVM1RAM80.elements[16+(i*17)].disabled=myPROTETTA
}
else if (myFRAME==6) {
for (i=0;i<16;i++)
frameCELLE.document.formVM1RAM96.elements[16+(i*17)].disabled=myPROTETTA
}
else {
for (i=0;i<16;i++)
frameCELLE.document.formVM1RAM112.elements[16+(i*17)].disabled=myPROTETTA
}
}
else parent.myPRIMOLOAD=false
frameMENUCS.reprintCSRAM()
}
</SCRIPT>
<TITLE>Gestione CONTROL STORE</TITLE>
</HEAD>
<FRAMESET ROWS="16%,*">
<FRAME NAME= "frameMENUCS" SRC="menucs.html">
<FRAME NAME= "frameCELLE" SRC="celle00.html">
</FRAMESET>
</HTML>
Di seguito il codice HTML contenuto nel file MENUCS.HTML.
<<< MENUCS.HTML >>>
<HTML>
<BODY BACKGROUND="sfondo3.gif" text="Maroon">
APPENDICE A.3 Il codice HTML 110
<FORM Name="formMENUCS">
<SCRIPT>
<!-------------------------->
<!-- Load FILECS -->
<!-------------------------->
function load_fileCS() {
var filn = parent.frameMENUCS.document.formMENUCS.VM1_program_file.value;
var myarr = parent.frameMENUCS.document.applets[0].RamLines(filn);
var i = 0;
var mystr = "";
var j = 0;
/* top.opener.resetCSRAM(); */
for ( mystr = myarr[0] ; mystr != null ; i++, mystr = myarr[i] ) {
if ( j == NaN ) break
<!-- controllo che siano almeno 18 questo perche la funzione mi darebbe errore -->
if (mystr.length() >= 18) {
j = mystr.substring(0,18);
top.opener.myCSRAM[i] = j;
}
}
reprintCSRAM()
alert("Caricato la CONTROL STORE");
}
<!-------------------------->
<!-- Reprint della CS -->
<!-------------------------->
function reprintCSRAM(){
var i=0;
var j=0;
if (parent.myFRAME==0) {
for (i=0;i<16;i++){
for (j=0;j<15;j++) {
parent.frameCELLE.document.formVM1RAM00.elements[(i*17)+j].value=top.opener.myCSRAM[i].substring(j,j+1);
}
parent.frameCELLE.document.formVM1RAM00.elements[(i*17)+j].value=top.opener.myCSRAM[i].substring(15,18)
}
}
else if (parent.myFRAME==1) {
for (i=0;i<16;i++){
for (j=0;j<15;j++) {
parent.frameCELLE.document.formVM1RAM16.elements[(i*17)+j].value=top.opener.myCSRAM[i+16].substring(j,j+1);
}
parent.frameCELLE.document.formVM1RAM16.elements[(i*17)+j].value=top.opener.myCSRAM[i+16].substring(15,18)
}
}
else if (parent.myFRAME==2) {
for (i=0;i<16;i++){
for (j=0;j<15;j++) {
parent.frameCELLE.document.formVM1RAM32.elements[(i*17)+j].value=top.opener.myCSRAM[i+32].substring(j,j+1);
}
APPENDICE A.3 Il codice HTML 111
parent.frameCELLE.document.formVM1RAM32.elements[(i*17)+j].value=top.opener.myCSRAM[i+32].substring(15,18)
}
}
else if (parent.myFRAME==3) {
for (i=0;i<16;i++){
for (j=0;j<15;j++) {
parent.frameCELLE.document.formVM1RAM48.elements[(i*17)+j].value=top.opener.myCSRAM[i+48].substring(j,j+1);
}
parent.frameCELLE.document.formVM1RAM48.elements[(i*17)+j].value=top.opener.myCSRAM[i+48].substring(15,18)
}
}
else if (parent.myFRAME==4) {
for (i=0;i<16;i++){
for (j=0;j<15;j++) {
parent.frameCELLE.document.formVM1RAM64.elements[(i*17)+j].value=top.opener.myCSRAM[i+64].substring(j,j+1);
}
parent.frameCELLE.document.formVM1RAM64.elements[(i*17)+j].value=top.opener.myCSRAM[i+64].substring(15,18)
}
}
else if (parent.myFRAME==5) {
for (i=0;i<16;i++){
for (j=0;j<15;j++) {
parent.frameCELLE.document.formVM1RAM80.elements[(i*17)+j].value=top.opener.myCSRAM[i+80].substring(j,j+1);
}
parent.frameCELLE.document.formVM1RAM80.elements[(i*17)+j].value=top.opener.myCSRAM[i+80].substring(15,18)
}
}
else if (parent.myFRAME==6) {
for (i=0;i<16;i++){
for (j=0;j<15;j++) {
parent.frameCELLE.document.formVM1RAM96.elements[(i*17)+j].value=top.opener.myCSRAM[i+96].substring(j,j+1);
}
parent.frameCELLE.document.formVM1RAM96.elements[(i*17)+j].value=top.opener.myCSRAM[i+96].substring(15,18)
}
}
else {
for (i=0;i<16;i++){
for (j=0;j<15;j++) {
parent.frameCELLE.document.formVM1RAM112.elements[(i*17)+j].value=top.opener.myCSRAM[i+112].substring(j,j+1);
}
parent.frameCELLE.document.formVM1RAM112.elements[(i*17)+j].value=top.opener.myCSRAM[i+112].substring(15,18)
}
}
}
APPENDICE A.3 Il codice HTML 112
<!-------------------------->
<!-- Scelta delle celle -->
<!-------------------------->
function scelta(parte,cella){
if (parte==0) {
top.myFRAME=0;
parent.frameCELLE.location = "celle00.html#CELLA"+cella;
}
else if (parte==1) {
top.myFRAME=1;
parent.frameCELLE.location = "celle16.html#CELLA"+cella;
}
else if (parte==2) {
top.myFRAME=2;
parent.frameCELLE.location = "celle32.html#CELLA"+cella;
}
else if (parte==3) {
top.myFRAME=3;
parent.frameCELLE.location = "celle48.html#CELLA"+cella;
}
else if (parte==4) {
top.myFRAME=4;
parent.frameCELLE.location = "celle64.html#CELLA"+cella;
}
else if (parte==5) {
top.myFRAME=5;
parent.frameCELLE.location = "celle80.html#CELLA"+cella;
}
else if (parte==6) {
top.myFRAME=6;
parent.frameCELLE.location = "celle96.html#CELLA"+cella;
}
else {
top.myFRAME=7;
parent.frameCELLE.location = "celle112.html#CELLA"+cella;
}
}
</SCRIPT>
<TABLE>
<TR>
<TD>
<NOBR>VM1 Filename:</NOBR>
<TD>
<INPUT type="file" name="VM1_program_file" accept="*" size="30">
<TD>
<INPUT type="button" value="loadCS" onclick="load_fileCS()">
<TD>
<INPUT type="button" value="saveCS" onclick="parent.salvaCS()">
<TD>
<INPUT type="button" value="closeCS" onclick="parent.window.close()">
</TABLE>
<TABLE>
<TR>
<TD>
<INPUT type="button" value="000-015" onclick="scelta(0,0)">
<TD>
<INPUT type="button" value="016-031" onclick="scelta(1,16)">
<TD>
<INPUT type="button" value="032-047" onclick="scelta(2,32)">
<TD>
<INPUT type="button" value="048-063" onclick="scelta(3,48)">
<TD>
<INPUT type="button" value="064-079" onclick="scelta(4,64)">
<TD>
<INPUT type="button" value="080-095" onclick="scelta(5,80)">
APPENDICE A.3 Il codice HTML 113
<TD>
<INPUT type="button" value="096-111" onclick="scelta(6,96)">
<TD>
<INPUT type="button" value="112-127" onclick="scelta(7,112)">
<TD>
<INPUT type="Checkbox" name="modalita" checked onclick="top.settasalva()"><NOBR>Modalita' protetta</NOBR>
</TABLE>
<APPLET name="myApplet" code="loadram.class" width="1" height="1"></APPLET>
</FORM>
</BODY>
</HTML>
Di seguito il codice HTML contenuto nel file PARTE16.HTML. Non e’ stato inserito il codice HTML dei file PARTE32.HTML, PARTE48.HTML, PARTE64.HTML, PARTE80.HTML, PARTE96.HTML e PARTE00.HTML perche’ il codice e’ identico salvo il numero progressivo dei nomi dei campi.
<<< PARTE16.HTML >>>
<HTML><HEAD><TITLE>CONTROL STORE</TITLE></HEAD>
<BODY onload="top.settasalva()" BACKGROUND='sfondo4.gif' text='Maroon'><FORM Name='formVM1RAM16'">
<TABLE BORDER>
<TR ALIGN=center><TD><A NAME='CELLA16'>CELLA<BR>016<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU16' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS16' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW16' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR16' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR16' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX16' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS16' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS16' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS16' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN16' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS16' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN16' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS16' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT16' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND16' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR16' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo16' Value='Save' DISABLED onclick='top.salvacella(16)'>
<TR ALIGN=center><TD><A NAME='CELLA17'>CELLA<BR>017<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU17' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS17' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW17' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR17' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR17' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX17' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS17' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS17' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS17' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN17' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS17' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN17' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS17' Value=0
Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT17' Value=0
APPENDICE A.3 Il codice HTML 114
Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND17' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR17' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo17' Value='Save' DISABLED onclick='top.salvacella(17)'>
<TR ALIGN=center><TD><A NAME='CELLA18'>CELLA<BR>018<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU18' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS18' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW18' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR18' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR18' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX18' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS18' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS18' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS18' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN18' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS18' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN18' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS18' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT18' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND18' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR18' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo18' Value='Save' DISABLED onclick='top.salvacella(18)'>
<TR ALIGN=center><TD><A NAME='CELLA19'>CELLA<BR>019<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU19' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS19' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW19' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR19' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR19' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX19' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS19' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS19' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS19' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN19' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS19' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN19' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS19' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT19' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND19' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR19' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo19' Value='Save' DISABLED onclick='top.salvacella(19)'>
<TR ALIGN=center><TD><A NAME='CELLA20'>CELLA<BR>020<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU20' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS20' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW20' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR20' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR20' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX20' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS20' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS20' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS20' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN20' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS20' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN20' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS20' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT20' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND20' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR20' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo20' Value='Save' DISABLED onclick='top.salvacella(20)'>
<TR ALIGN=center><TD><A NAME='CELLA21'>CELLA<BR>021<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU21' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS21' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW21' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR21' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR21' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX21' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS21' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS21' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS21' Value=0
APPENDICE A.3 Il codice HTML 115
Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN21' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS21' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN21' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS21' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT21' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND21' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR21' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo21' Value='Save' DISABLED onclick='top.salvacella(21)'>
<TR ALIGN=center><TD><A NAME='CELLA22'>CELLA<BR>022<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU22' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS22' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW22' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR22' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR22' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX22' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS22' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS22' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS22' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN22' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS22' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN22' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS22' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT22' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND22' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR22' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo22' Value='Save' DISABLED onclick='top.salvacella(22)'>
<TR ALIGN=center><TD><A NAME='CELLA23'>CELLA<BR>023<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU23' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS23' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW23' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR23' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR23' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX23' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS23' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS23' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS23' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN23' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS23' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN23' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS23' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT23' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND23' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR23' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo23' Value='Save' DISABLED onclick='top.salvacella(23)'>
<TR ALIGN=center><TD><A NAME='CELLA24'>CELLA<BR>024<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU24' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS24' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW24' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR24' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR24' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX24' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS24' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS24' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS24' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN24' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS24' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN24' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS24' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT24' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND24' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR24' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo24' Value='Save' DISABLED onclick='top.salvacella(24)'>
<TR ALIGN=center><TD><A NAME='CELLA25'>CELLA<BR>025<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU25' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS25' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW25' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR25' Value=0
APPENDICE A.3 Il codice HTML 116
Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR25' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX25' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS25' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS25' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS25' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN25' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS25' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN25' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS25' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT25' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND25' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR25' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo25' Value='Save' DISABLED onclick='top.salvacella(25)'>
<TR ALIGN=center><TD><A NAME='CELLA26'>CELLA<BR>026<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU26' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS26' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW26' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR26' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR26' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX26' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS26' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS26' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS26' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN26' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS26' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN26' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS26' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT26' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND26' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR26' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo26' Value='Save' DISABLED onclick='top.salvacella(26)'>
<TR ALIGN=center><TD><A NAME='CELLA27'>CELLA<BR>027<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU27' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS27' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW27' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR27' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR27' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX27' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS27' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS27' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS27' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN27' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS27' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN27' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS27' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT27' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND27' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR27' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo27' Value='Save' DISABLED onclick='top.salvacella(27)'>
<TR ALIGN=center><TD><A NAME='CELLA28'>CELLA<BR>028<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU28' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS28' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW28' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR28' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR28' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX28' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS28' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS28' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS28' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN28' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS28' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN28' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS28' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT28' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND28' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR28' Value=0 Size=7></TR>
APPENDICE A.3 Il codice HTML 117
<TD><INPUT TYPE=Button Name='memo28' Value='Save' DISABLED onclick='top.salvacella(28)'>
<TR ALIGN=center><TD><A NAME='CELLA29'>CELLA<BR>029<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU29' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS29' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW29' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR29' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR29' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX29' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS29' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS29' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS29' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN29' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS29' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN29' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS29' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT29' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND29' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR29' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo29' Value='Save' DISABLED onclick='top.salvacella(29)'>
<TR ALIGN=center><TD><A NAME='CELLA30'>CELLA<BR>030<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU30' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS30' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW30' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR30' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR30' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX30' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS30' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS30' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS30' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN30' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS30' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN30' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS30' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT30' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND30' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR30' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo30' Value='Save' DISABLED onclick='top.salvacella(30)'>
<TR ALIGN=center><TD><A NAME='CELLA31'>CELLA<BR>031<TD><TD>ALU<BR><INPUT TYPE=Text Name='ctrALU31' Value=0 Size=3><TD>CS<BR><INPUT TYPE=Text Name='ctrCS31' Value=0 Size=1><TD>R/nW<BR><INPUT TYPE=Text Name='ctrRW31' Value=0 Size=1><TD>MAR<BR><INPUT TYPE=Text Name='ctrMAR31' Value=0 Size=1><TD>MBR<BR><INPUT TYPE=Text Name='ctrMBR31' Value=0 Size=1><TD>Dmpx<BR><INPUT TYPE=Text Name='ctrDMPX31' Value=0 Size=2><TD>Abus<BR><INPUT TYPE=Text Name='ctrABUS31' Value=0 Size=2><TD>Bbus<BR><INPUT TYPE=Text Name='ctrBBUS31' Value=0 Size=2><TD>CAbus<BR><INPUT TYPE=Text Name='ctrCABUS31' Value=0 Size=2><TD>CAen<BR><INPUT TYPE=Text Name='ctrCAEN31' Value=0 Size=1><TD>CDbus<BR><INPUT TYPE=Text Name='ctrCDBUS31' Value=0 Size=2><TD>CDen<BR><INPUT TYPE=Text Name='ctrCDEN31' Value=0 Size=1><TD>Dbus<BR><INPUT TYPE=Text Name='ctrDBUS31' Value=0 Size=2><TD> Int <BR><INPUT TYPE=Text Name='ctrINT31' Value=0 Size=2><TD>mcond<BR><INPUT TYPE=Text Name='ctrMCOND31' Value=0 Size=3><TD>Addr<BR><INPUT TYPE=Text Name='ctrADDR31' Value=0 Size=7></TR>
<TD><INPUT TYPE=Button Name='memo31' Value='Save' DISABLED onclick='top.salvacella(31)'>
</TABLE>
</FORM>
</BODY>
</HTML>
APPENDICE A.4 Il contenuto della CONTROL STORE 118
A.4 Il contenuto della CONTROL STORE
Di seguito si puo vedere il contenuto del file PRG.VM1 rappresentate la CONTROL STORE.
000003000100010000 cella0 RESET: PC=0; reset interrupt; MPC=MPC+1
000000000000006006 cella1 FETCH: if Interrupt then goto 6 else MPC=MPC+1
411100000100000000 cella2 MAR=PC; PC=PC+1; start read; MPC=MPC+1
001010000000000000 cella3 MBR=data bus; end read; MPC=MPC+1
000002003101000000 cella4 IR=MBR; ADR=MBR; MPC=MPC+1
000000000000005000 cella5 MPC=decode(IR)
000000000000000000 cella6 Free
000000000000000000 cella7 Free
000000000000000000 cella8 Free
000000000000000000 cella9 Free
000000000000000000 cella10 Free
000000000000000000 cella11 Free
000000000000000000 cella12 Free
000000000000000000 cella13 Free
000000000000000000 cella14 Free
000000000000000000 cella15 Free
000000000000000000 cella16 Free
000000000000000000 cella17 Free
000000000000000000 cella18 Free
000000000000000000 cella19 Free
000000000000000000 cella20 Free
000000000000000000 cella21 Free
000000000000000000 cella22 Free
000000000000000000 cella23 Free
000000000000000000 cella24 Free
000000000000000000 cella25 Free
000000000000000000 cella26 Free
000000000000000000 cella27 Free
000000000000000000 cella28 Free
000000000000000000 cella29 Free
000000000000000000 cella30 Free
000000000000000000 cella31 Free
000001000000102001 cella32 JPOS: ALU=ACC;if N then goto 1 else MPC=MPC+1
000001000100001001 cella33 PC=IR; goto 1
000001000000102033 cella34 JNEG: ALU=ACC; if N then goto 33 else MPC=MPC+1
000000000000001001 cella35 goto 1
000001000000103033 cella36 JZER: ALU=ACC;i if Z then goto 33 else MPC=MPC+1
000000000000001001 cella37 goto 1
000001000000103001 cella38 JNZE: ALU=ACC;if Z then goto 1 else MPC=MPC+1
000001000100001001 cella39 PC=IR; goto 1
011100300000000000 cella40 LODD: MAR=ADR; start read; MPC=MPC+1
001010000000001049 cella41 MBR=data bus; end read; goto 49
011100300000000000 cella42 ADDD: MAR=ADR; start read; MPC=MPC+1
001010000000001051 cella43 MBR=data bus; end read; goto 51
011100300000000000 cella44 ANDD: MAR=ADR; start read; MPC=MPC+1
001010000000001053 cella45 MAR=data bus; end read; goto 53
010111300000100000 cella46 STOD: MAR=ADR; MBR=ACC; start write; MPC=MPC+1
000000000000001001 cella47 end write; goto 1
600000203100001040 cella48 LODL: ADR=FP+IR; goto 40
000002000011001001 cella49 ACC=MBR; goto 1
APPENDICE A.4 Il contenuto della CONTROL STORE 119
600000203100001042 cella50 ADDL: ADR=FP+IR; goto 42
600002010011001001 cella51 ACC=MBR+ACC;goto 1
600000203100001044 cella52 ANDL: ADR=FP+IR; goto 44
700002010011001001 cella53 ACC=MBR AND ACC; goto 1
600000203100001046 cella54 STOL: ADR=FP+IR; goto 46
000000000000000000 cella55 Free
000001000100001001 cella56 JUMP: PC=IR; goto 1
000000000000001001 cella57 goto 1
600001003100101040 cella58 LDIX: ADR=ACC+IR; goto 40
000000000000001001 cella59 goto 1
000010200000000000 cella60 CALL: MBR=FP; MPC=MPC+1
510100101121000000 cella61 MAR=SP; SP=B=SP-1; start write; MPC=MPC+1
000010000000000000 cella62 MBR=PC; end write; MPC=MPC+1
410101102100200000 cella63 MAR=SP; FP=B+1; start write; MPC=MPC+1
500000101100001056 cella64 SP=SP-1; end write; goto 56
700001020011001001 cella65 ACC=IR AND B; goto 1
200001000021200000 cella66 B=B<<1; MPC=MPC+1
200001000021200000 cella67 B=B<<1; MPC=MPC+1
200001000021200000 cella68 B=B<<1; MPC=MPC+1
200001000021200000 cella69 B=B<<1; MPC=MPC+1
200001000021200000 cella70 B=B<<1; MPC=MPC+1
200001000021200000 cella71 B=B<<1; MPC=MPC+1
200003000031000127 cella72 C=0000000011111110; MPC=MPC+1
400001000031300000 cella73 C=C+1; MPC=MPC+1
700001030011100000 cella74 ACC=ACC AND C; MPC=MPC+1
600001020011101001 cella75 ACC=ACC+B; goto 1
700001020021000000 cella76 B=IR AND B; MPC=MPC+1
600000121100001001 cella77 SP=SP+B; goto 1
700001020021000000 cella78 B=IR AND B; MPC=MPC+1
100001000021200000 cella79 B=NOT B; MPC=MPC+1
400001000021201077 cella80 B=B+1; goto 77
001010000000000000 cella81 MBR=data bus; end read; MPC=MPC+1
510100101100001047 cella82 MAR=SP; SP=SP-1; start write; goto 47
001010000000000000 cella83 MBR=data bus; end read; MPC=MPC+1
000002000011001001 cella84 ACC=MBR; goto 1
001011003100100000 cella85 MBR=data bus; end read; ADR=ACC; MPC=MPC+1
010100300000000000 cella86 MAR=ADR; start write; MPC=MPC+1
000000000000001001 cella87 end write; goto 1
000001000011201001 cella88 ACC+B; goto 1
001010000000000000 cella89 MBR=data bus; end read; MPC=MPC+1
011102100100000000 cella90 PC=MBR; MAR=FP; start read; MPC=MPC+1
001010000000000000 cella91 MBR=data bus; end read; MPC=MPC+1
000002002100001001 cella92 FP=MBR; goto 1
000000000000000000 cella93 Free
000000000000000000 cella94 Free
000000000000000000 cella95 Free
200003000021000127 cella96 LOC8: B=0000000011111110; MPC=MPC+1
400001000021201065 cella97 B=B+1; goto 65
200001000021000000 cella98 LOCH: B=IR<<1; MPC=MPC+1
200001000021201066 cella99 B=B<<1; goto 66
200003000021000127 cella100 INSP: B=0000000011111110; MPC=MPC+1
400001000021201076 cella101 B=B+1; goto 76
200003000021000127 cella102 DESP: B=0000000011111110; MPC=MPC+1
400001000021201078 cella103 B=B+1; goto 78
010111100000100000 cella104 PUSH: MAR=SP; MBR=ACC; start write; MPC=MPC+1
500000101100001001 cella105 SP=SP-1; end write; goto 1
000001003100100000 cella106 PSHI: ADR=ACC; MPC=MPC+1
011100300000001081 cella107 MAR=ADR; start read; goto 81
400000101100000000 cella108 POP: SP=SP+1; MPC=MPC+1
011100100000001083 cella109 MAR=SP; start read; goto 83
400000101100000000 cella110 POPI: SP=SP+1; MPC=MPC+1
011100100000001085 cella111 MAR=SP; start read; goto 85
000000100021000000 cella112 SWAS: B=0000(SP); MPC=MPC+1
000001001100101088 cella113 SP=ACC; goto 88
000000200021000000 cella114 SWAF: B=0000(FP); MPC=MPC+1
000001002100101088 cella115 FP=ACC; goto 88
100001000011100000 cella116 NEGA: ACC=not ACC; MPC=MPC+1
APPENDICE A.4 Il contenuto della CONTROL STORE 120
000000000000001001 cella117 goto 1
100001000011100000 cella118 SIGN: ACC=not ACC; MPC=MPC+1
400001000011101001 cella119 ACC=ACC+1; goto 1
500000203100000000 cella120 RETN: ADR=FP-1; MPC=MPC+1
411100301100001089 cella121 MAR=ADR; SP=FP; start read; goto 89
000000000000000000 cella122 HALT: MPC=MPC+1
000000000000001123 cella123 goto 123
300001000011100000 cella124 RSHF: ACC=(ACC>>1); MPC=MPC+1
000000000000001001 cella125 goto 1
200001000011100000 cella126 LSHF: ACC=(ACC<<1); MPC=MPC+1
000000000000001001 cella127 goto 1
APPENDICE A.4 Il contenuto della CONTROL STORE 121
B.1 Bibliografia
[CHI96] Chiola G., Appunti del corso di Architettura degli Elaboratori, 1996
[TAN91] Tanenbaum A. S., "Architettura del computer", 1991
[LEM98] Lemay L., Cadeuhead R. "Java 1.2, Guida Completa", 1998
[JSCR00] Flangan D., "Javascript, La Guida", 2000
[JSCR97] Netscape, DevEdge Online "JavaScript Reference", 1997
http://developer.netscape.com/docs/manuals/communicator/jsref/
index.html
[HTML] Tittel E., James S. N., "HTML", 1997
[HTML4] W3C, "HTML 4.01 Specification", 1999
[JAVA2] Java Sun, "JavaTM 2 Platform Std. Ed. v1.3.1", 2001
http://java.sun.com/j2se/1.3/docs/api/index-files/index-1.html