Emulatore PDP-11/70 – Marzo 2020
Questo emulatore è una personalizzazione ed estensione dell’ottimo j_simh di Paul Nankervis, che emula fedelmente un PDP11/70.
Sono disponibili immagini disco contenenti la quasi totalità dei sistemi operativi disponibili per la macchina. Il più interessante, RSTS/E V06C sarà introdotto prossimamente in occasione di una serata dedicata che potrete rivedere in qualsiasi momento nella sezione “Eventi” del sito associativo. Nel frattempo, provate a caricare il sistema operativo RT-11SJ che vi riserverà comunque molte sorprese.
Nota: Il codice eseguito al boot di questo emulatore è un programma custom che implementa una sua sequenza di movimenti dei LED del pannello. Viene caricato all’indirizzo 140000 e ha un comando LIGHTS che opera mappando e eseguendo un’istruzione WAIT a partire da una sequenza di indirizzi virtuali situati nel modo Supervisore.
Potete usare un vostro comando BOOT per avviare uno dei sistemi operativi che renderemo disponibili oppure il comando ODT per lanciare l’Octal Debugging Tool (che ho scoperto per caso e che è una figata di per sé).
L’emulatore consta di una riproduzione grafica del pannello di controllo della macchina e di due terminali, uno testuale (un VT220) e uno grafico (un VT11 di tipo vettoriale). Il secondo si attiva solo quando viene lanciato un programma che ne pilota il driver.
Per iniziare, potete lanciare il sistema RT-11 scrivendo nel terminale
boot rk1
e premendo il tasto invio sulla vostra tastiera.
il filesystem si naviga con il comando DIR (vi ricorda qualcosa?). I programmi con estensione .SAV (es. PIPPO.SAV) possono essere lanciati con il comando
R PIPPO.SAV.
Lascio a voi altre chicche… non potete fare danni perché il sistema è protetto.
Come indulgere sul terminale quando abbiamo a disposizione un pannello così colorato, luccicante e affascinante?
Queste macchine, come molte dell’epoca, potevano essere programmate a basso livello direttamente agendo sulle levette del pannello di controllo.
Se volete provare l’ebbrezza di sviluppare come un nerd degli anni ’60, provate a inserire il programma che segue. Si tratta di un semplice programmino che farà illuminare i led del pannello secondo una sequenza continua.
Il PDP ha una serie di comandi molto semplici associati a alcune levette.
La levetta HALT, blocca il processore e ne ferma qualsiasi esecuzione in corso.
Le levette corrispondenti ai numeri da 0 a 21, chiamate anche “SR”, sono raggruppate per colore a tre a tre più una isolata (il riporto).
È molto importante osservare questo raggruppamento: ogni levetta, infatti, rappresenta un byte (un valore di otto bit). È abbastanza evidente quindi come la notazione ottale si mappi perfettamente sulla forma raggruppata dei tasti. Ogni valore che vedrete nei programmi qui sotto è in ottale.
Prendiamo, ad esempio, il valore
006100 ottale (3136 in decimale, C40 in esadecimale).
In ottale, ogni posizione può essere uno tra otto valori che vanno da 0 a 7.
In binario, un numero compreso tra 0 e 7 viene rappresentato con soli 3 bit. 3 bit, tre levette. Iniziate a visualizzare lo scenario?
Il nostro valore ottale 006100, si tradurrebbe quindi nel seguente valore binario:
0 ----> 000 (0 x 8^5)
0 ----> 000 (0 x 8^4)
6 ----> 110 (6 x 8^3)
1 ----> 001 (1 x 8^2)
0 ----> 000 (0 x 8^1)
0 ----> 000 (0 x 8^0)
ovvero
OTTALE : 0 0 6 1 0 0
BINARIO: 000 000 110 001 000 000
Questo valore può quindi essere inserito sul pannello del PDP-11 andando a impostare in alto (valore 1) le levette corrispondenti alla posizione degli “0” e “1” del numero ottale convertito in binario, partendo da quello più a destra e procedendo verso sinistra. Nel caso del nostro numero, avremmo
0 ----> 000 (SR15 basso - SR16 basso SR17 basso)
0 ----> 000 (SR12 basso - SR13 basso SR14 basso)
6 ----> 110 (SR9 alto - SR10 alto SR11 basso)
1 ----> 001 (SR6 alto - SR7 basso SR8 basso)
0 ----> 000 (SR3 basso - SR4 basso SR5 basso)
0 ----> 000 (SR1 basso - SR2 basso SR3 basso)
Insomma, convertendo mentalmente ogni valore ottale nel suo equivalente binario e andando a “trascriverlo” sulle levette SR, andrete a comporre alcuni valori ottali che possono essere locazioni di memoria nelle quali scrivere valori o dalle quali leggerle, oppure i valori stessi.
Il programma qui sotto è rappresentato in colonne. La colonna “indirizzo dati” dice a quale locazione di memoria ci troviamo e sulla quale stiamo facendo l’operazione. La colonna “dati” ci dice quali sono i valori che carichiamo (o leggiamo) a quella specifica locazione di memoria. La colonna “ASM” rappresenta l’istruzione assembly e i suoi parametri che corrispondono ai numeri inseriti (se rappresentano istruzioni). La colonna “interruttori da premere” vi indica esattamente cosa fare per far sì che nella locazione indicata vengano posti i dati o le istruzioni indicate.
Indirizzo Dati ASM Interruttori da premere Commento
HALT, 001000, LOAD ADDRESS Per prima cosa arrestiamo la CPU, impostiamo l'indirizzo ottale 001000
e premiamo la levetta "LOAD ADDRESS" che sposta il program counter a
quell'indirizzo. Vedrete che sulla riga successiva, la colonna
"Indirizzo dati" diventa 001000
001000 012700 mov #1,r0 012700, DEPOSIT Inseriamo l'istruzione mov #1,r0 che mette il valore ottale 1 nel
registro r0. L'istruzione è lunga e occupa due ottetti quindi prima
inseriamo 012700 (mov r0) alla locazione 001000, poi
001002 000001 000001, DEPOSIT inseriamo il valore 1 (il parametro) alla locazione 00102. Avete notato
che ogni volta che premete la levetta DEPOSIT la locazione di memoria
avanza da sola?
001004 006100 rol r0 006100, DEPOSIT Adesso inseriamo rol r0. L'istruzione è breve e sta tutta in una locazione.
001006 000005 reset 000005, DEPOSIT Inseriamo l'istruzione reset.
001010 000775 br .-4 000775, DEPOSIT Quindi l'istruzione br (branch) che torna a ripetere il loop
001000, LOAD ADDRESS, ENABLE, START Il programma è pronto. Come lo eseguiamo? Riportiamo il program counter
alla locazione di memoria in cui inizia il programma: digitiamo 001000
sulle levette numeriche (a partire da destra!), premiamo LOAD ADDRESS
per spostare il program counter all'indirizzo indicato. Quindi premiamo
la levetta ENABLE per riattivare la CPU e infine premiamo START.
Disco dance!
Per ripristinare il codice custom originale (se non lo avete sovrascritto in memoria) usate la seguente sequenza di interruttori:
HALT, 140000, LOAD ADDRESS, ENABLE, START
In pratica arrestate la macchina, inserite il valore 140000 ottale sugli interruttori SR, caricate quel valore nel registro degli indirizzi, riattivate la macchina e spostate il program counter all’indirizzo che avete inserito. Lì la CPU troverà il codice originale e lo eseguirà. Figo, no?