Non so se sia funzionante (non ho ancora avuto modo di provarlo) ma trovare un monitor Commodore 1702 al cassonetto e' diciamo un caso piu' unico che raro
Visualizzazione post con etichetta Commodore. Mostra tutti i post
Visualizzazione post con etichetta Commodore. Mostra tutti i post
domenica 15 dicembre 2019
sabato 4 maggio 2019
Commodore 64 Multi Diagnostic Card
Per imparare un po' di hardware Commodore 64 mi sono comprato su Ebay u C64 biscottone dichiarato come non funzionante. Per rendermi la vita un po' piu' facile mi sono comprato una scheda di diagnostica con montate 5 ROM selezionabili via switch
Il C64 acquistato e' effettivamente rotto e mostra schermo nero...il problema e' che pur inserendo la scheda diagnostica lo schermo rimane nero.
Ho preso quindi il mio C64 funzionante ......ed ho avuto una pessima notizia...la scheda di diagnostica mostra una seria di problemi sui due CIA (U1 ed U2) e sul SID (U18)
I CIA servono all'IO del computer e quindi cio' giustifica problema sulla cassetta, sulle control port e sulla seriale (oltre che sull'interrupt perche' i CIA gestiscono l'interrupt)....il SID e' inutile che descriva a cio' che serve
Il C64 acquistato e' effettivamente rotto e mostra schermo nero...il problema e' che pur inserendo la scheda diagnostica lo schermo rimane nero.
Ho preso quindi il mio C64 funzionante ......ed ho avuto una pessima notizia...la scheda di diagnostica mostra una seria di problemi sui due CIA (U1 ed U2) e sul SID (U18)
I CIA servono all'IO del computer e quindi cio' giustifica problema sulla cassetta, sulle control port e sulla seriale (oltre che sull'interrupt perche' i CIA gestiscono l'interrupt)....il SID e' inutile che descriva a cio' che serve
venerdì 15 marzo 2019
Bare Metal C64 con Raspberry 3D Case
Sto giocando con BMC64 e, non volendo sacrificare un case di C64 funzionante, mi sono adattato con questo caso stampato in 3D
I colori sono quelli del VIC 20 ma va benissimo cosi'
I colori sono quelli del VIC 20 ma va benissimo cosi'
martedì 22 gennaio 2019
Emulatore in Pascal per Commodore 64
Mi sono imbattuto per caso in questo progetto ospitato su GitHub (che rimanda pero' ad un progetto del 2008) in cui viene programmato un semplice emulatore per Commodore 64 e lo ho trovato molto istruttivo perche' il codice (forse perche' in Pascal) e' molto semplice da seguire ed offre uno spaccato della programmazione di una macchina di emulazione
Si parte semplicemente creando un array di 64K byte che rappresentano la memoria di un C64 (si vedra' in seguito che parte di questi 64Kb saranno occupati da ROM)
Ognuna delle celle dell'array rappresenta una locazione di memoria che puo' essere letta o scritta con un semplice accesso all'array mediante puntatore
Si definiscono quindi le variabili byte A (accumulatore),X,Y,S (stack pointer varia da 0x01FF a 0x0100) ,P (processor status usato per contenere delle flags) ed IR (instruction register, contenuto di memoria che si utilizza) che rappresentano i registri della cpu 6510 con il registro PC (Program counter) che e' di lunghezza word 16 bit (dato che deve contenere un numero 0.65535 )
Il ciclo base dell'emulatore semplicemente legge il contenuto della memoria puntato da PC, interpreta l'istruzione macchine ed modifica il Program Counter per andare alla successiva istruzione
=================================
while true do
begin
IR := peek(PC);
inc(PC);
case IR of
$00 : interpret instruction $00
$01 : interpret instruction $01
else : unknown instruction encountered
end;
end.
=================================
Emulatore in esecuzione in shell su Linux |
Si parte semplicemente creando un array di 64K byte che rappresentano la memoria di un C64 (si vedra' in seguito che parte di questi 64Kb saranno occupati da ROM)
Ognuna delle celle dell'array rappresenta una locazione di memoria che puo' essere letta o scritta con un semplice accesso all'array mediante puntatore
Si definiscono quindi le variabili byte A (accumulatore),X,Y,S (stack pointer varia da 0x01FF a 0x0100) ,P (processor status usato per contenere delle flags) ed IR (instruction register, contenuto di memoria che si utilizza) che rappresentano i registri della cpu 6510 con il registro PC (Program counter) che e' di lunghezza word 16 bit (dato che deve contenere un numero 0.65535 )
Il ciclo base dell'emulatore semplicemente legge il contenuto della memoria puntato da PC, interpreta l'istruzione macchine ed modifica il Program Counter per andare alla successiva istruzione
=================================
while true do
begin
IR := peek(PC);
inc(PC);
case IR of
$00 : interpret instruction $00
$01 : interpret instruction $01
else : unknown instruction encountered
end;
end.
=================================
Si devono quindi implementare tutti i codici macchina e come questi modificano lo stato dei registri e le locazioni di memoria ed il flusso di programma
Il 6510 ha circa una ottantina di Opcode da implementare per realizzare un emulatore
Il 6510 usa come base un sistema little endian per cui il byte meno significativo di una word e' registrato nella prima locazione di memoria (o locazione di memoria piu' bassa)
Impostata l'emulazione del processore il passo successivo e' quello di inizializzare le ROM del C64 che, al minimo, devono contenere il Kernal ma puo' essere utile anche avere il Basic. Si prendono i due file del Kernal e del Basic, si legge il contenuto e lo si copia rispettivamente alle locazioni di memoria $A000...$BFFF e $E000...$FFFF. (un altro settore di memoria destinato alla ROM e' compreso tra $D000 e $DFFF....tutto il resto della memoria..anche se frammentato e' considerata RAM)
Il boot della macchina inizia leggendo il valore della locazione $FFFC-$FFFD ed impostando il program counter (una word) a questa locazione (in pratica viene lanciato un Cold Reset della macchina. Di default il valore letto e' $FCE2 (ovvero il mitico SYS 64738)
Il codice ROM si aspetta di dover ricevere informazioni dal VIC e dalla tastiera ma dato che questi non sono ancora emulati al capitolo 3 dell'emulatore viene inviato un segnale
Nel capitolo 4 viene introdotta la lettura da tastiera e l'output in modalita' testo
Per la tastiera, ogni volta che viene premuto un tasto (if keypressed) viene letta la lunghezza del buffer di tastiera alla locazione $C6 (il buffer di tastiera puo' contenere al massimo 10 caratteri), se il numero e' inferiore a 10 inserisce il nuovo carattere nel buffer che si trova tra $0277 e $0280 ed incrementa la locazione $C6
Per l'output a video viene letta la memoria video testuale che e' compresa tra $400 e $7E7 (1Kb). Nell'emulatore la schermata viene ricreata ogni volta che c'e' un accesso in lettura nell'area di memoria $400-$7E7
Per la posizione del cursore vengono lette le locazioni di memoria $00D3 e $00D6
Dal capitolo 5 viene gestita la creazione degli interrupt. In pratica un interrupt e' un evento che interrompe momentaneamente il ciclo di base del processore While True Do. Gli interrupt possono essere mascherabili e non mascherabili: di fatto viene messo nello stack il valore del program counter ed il contenuto del registro delle flags (in modo da recuperarlo quando si esce dall'interrupt) e poi si passa il controllo dell'esecuzione al codice dell'interrupt puntato dalle locazioni di memoria $FFFE-$FFFF (essendo un indirizzo di memoria e' una word) se e' mascherabile oppure $FFFA-$FFFB se non e' mascherabile
GLi interrupt sono generati da un dispositivo hardware ma esiste la possibilita' di avere interrupt software via BRK
Su C64 viene generato un IRQ con un clock di 50 Hz
Il codice Pascal si compila tranquillamente, almeno fino al capitolo 5, su Linux usando FreePascal
Dal capitolo 5 viene gestita la creazione degli interrupt. In pratica un interrupt e' un evento che interrompe momentaneamente il ciclo di base del processore While True Do. Gli interrupt possono essere mascherabili e non mascherabili: di fatto viene messo nello stack il valore del program counter ed il contenuto del registro delle flags (in modo da recuperarlo quando si esce dall'interrupt) e poi si passa il controllo dell'esecuzione al codice dell'interrupt puntato dalle locazioni di memoria $FFFE-$FFFF (essendo un indirizzo di memoria e' una word) se e' mascherabile oppure $FFFA-$FFFB se non e' mascherabile
GLi interrupt sono generati da un dispositivo hardware ma esiste la possibilita' di avere interrupt software via BRK
Su C64 viene generato un IRQ con un clock di 50 Hz
Il codice Pascal si compila tranquillamente, almeno fino al capitolo 5, su Linux usando FreePascal
lunedì 11 giugno 2018
Floating point numbers in C64
Continua l'esplorazione di tutto quanto mi sono perso su C64
Quando ho iniziato a studiare l'assembler avevo Olivetti M24 su processore 8086 e sul C64 usavo solo BASIC (al limite integrato con Simon Basic per qualche routine grafica). L'assembler 8086 non e' banalissimo ma la cosa che piu' mi infastidiva era quella di non poter gestire in modo nativo la matematica dei numeri float ....a meno che di non possedere un costosissimo coprocessore matematico (che e' stato integrato solo dalla serie x486)
Con sorpresa ho scoperto che usare i numeri a virgola mobile e fare conti su C64 e' incredibilmente banale anche in assembler.
Per prima cosa i numeri float hanno una struttura di 5 byte e sono nel formato esponenziale base 2 ...quindi qualcosa del tipo x.xxx 2^y
byte 1 : esponente : il valore dell'esponente e' nel formato exp-129 (quindi 2^0 avra' il valore 81, valore piu' bassi indicano esponenti negativi)
byte 2-5 : mantissa
Convertire da formato float decimale a float C64
per fare poca fatica conviene usare direttamente la conversione di C64
Per esempio si digiti da BASIC
NEW
X = 3.14159
IND = PEEK(71)+256*PEEK(72)
PRINT PEEK(IND)
PRINT PEEK(IND+2)
PRINT PEEK(IND+3)
Quando ho iniziato a studiare l'assembler avevo Olivetti M24 su processore 8086 e sul C64 usavo solo BASIC (al limite integrato con Simon Basic per qualche routine grafica). L'assembler 8086 non e' banalissimo ma la cosa che piu' mi infastidiva era quella di non poter gestire in modo nativo la matematica dei numeri float ....a meno che di non possedere un costosissimo coprocessore matematico (che e' stato integrato solo dalla serie x486)
Con sorpresa ho scoperto che usare i numeri a virgola mobile e fare conti su C64 e' incredibilmente banale anche in assembler.
Per prima cosa i numeri float hanno una struttura di 5 byte e sono nel formato esponenziale base 2 ...quindi qualcosa del tipo x.xxx 2^y
byte 1 : esponente : il valore dell'esponente e' nel formato exp-129 (quindi 2^0 avra' il valore 81, valore piu' bassi indicano esponenti negativi)
byte 2-5 : mantissa
Convertire da formato float decimale a float C64
per fare poca fatica conviene usare direttamente la conversione di C64
Per esempio si digiti da BASIC
NEW
X = 3.14159
IND = PEEK(71)+256*PEEK(72)
PRINT PEEK(IND)
PRINT PEEK(IND+2)
PRINT PEEK(IND+3)
PRINT PEEK(IND+4)
PRINT PEEK(IND+5)
quale e' il significato. Diciamo al BASIC di salvare il valore di float di pi greco in una variabile. Nelle locazioni a pagina zero 71 e 72 c'e' il puntato alla zona di memoria dove viene inserito effettivanemente il numero (gia' decodificato in formato C64). Nel mio caso l'indirizzo e' $805 (esadecimale) se sei aggiungono altre variabile si vedra' che il puntatore si aggiorna
La risposta al comando e'
$82 $49 $0F $CF $82
ovvero la traduzione in formato float C64
Per fare la riprova si puo' usare questo programma assembler in ACME
in pratica si popola la'accumulatore di float FAC con il valore di pi greco, si chiama il kernal per la conversione del valore in una stringa ($BDDD) e poi si mostra la stringa a schermo
-----------------------------------------------
Per la riconversione l'algoritmo (preso da qui) e' il seguente
Float
!source "./std.a"
!to "float.prg", cbm
!sl "float.map"
!cpu 6510
*=$1000
LDFAC = $bba2
!macro LoadFAC .addr {
lda #<.addr
ldy #>.addr
jsr LDFAC
}
+LoadFAC pi
MOVFA ; sposta FAC in ARG
;JSR $E264 ;COSENO NON UTILIZZATA
JSR $BDDD ;Convert FAC to zero-terminated string representation at memory addresses $0100-$010A.
LDY #0
loop: LDA $100,Y
BEQ done
JSR $FFD2
INY
BNE loop
done:
RTS
pi !by $82, $49, $0F, $CF, $82
-----------------------------------------------Per la riconversione l'algoritmo (preso da qui) e' il seguente
- Exponent: exp-128
- Mantissa: (m4 >= 128 ? -1 : +1) * ((m4 | 0x80) >> 8 + m3 >> 16 + m2 >> 24 + m1 >> 32)
La cosa interessante e' che da Assembler si possono chiamare anche le funzioni trigonometriche, le stesse condivise con BASIC, ma che risultano decisamente piu' veloci (vedi la chiama alla subroutine in $E264 corrispondente al coseno)
c'e' da osservare che la precisione dell'arrotondamento delle routine non e' ottimale (vedi questo link)
c'e' da osservare che la precisione dell'arrotondamento delle routine non e' ottimale (vedi questo link)
martedì 20 agosto 2013
Emulatore Commodore 64 in Debian
Per installare l'emulatore del Commodore 64 e' necessario proecedere come segue
per prima cosa si installa il programma Vice mediante
apt-get install vice
Successivamente e' necessario acquisire le Rom che si possono scaricare da questo link
Si decomprime il file nella directory /usr/lib/vice (permessi di root necessari) e si avra' una sottodirectory per ogni calcolatore emulato. Ricontrollare a questo punto che i permessi siano impostati in modo tale che anche l'utente normale possa leggere i file
per lanciare gli emulatori si digiti
x64 (per Commodore 64)
x128 (per Commodore 128)
xcbm2 (per Commodore CBM-II)
xpet (per Commodore Pet)
xplus4 (per Commodore Plus 4)
xvic (per Commodore VIC 20)
per prima cosa si installa il programma Vice mediante
apt-get install vice
Successivamente e' necessario acquisire le Rom che si possono scaricare da questo link
Si decomprime il file nella directory /usr/lib/vice (permessi di root necessari) e si avra' una sottodirectory per ogni calcolatore emulato. Ricontrollare a questo punto che i permessi siano impostati in modo tale che anche l'utente normale possa leggere i file
per lanciare gli emulatori si digiti
x64 (per Commodore 64)
x128 (per Commodore 128)
xcbm2 (per Commodore CBM-II)
xpet (per Commodore Pet)
xplus4 (per Commodore Plus 4)
xvic (per Commodore VIC 20)
Mandelbrot in Simons Basic (Commodore 64)
Circa 20 anni fa lo facevo sui Commodore 64 reali, registravo sul datasette e per salvare le schermate usavo un VHS....al giorno d'oggi, non avendo piu' l'hardware, non mi rimane che l'emulazione
Attenzione: in modalita' Warp il programma richiede oltre 30 minuti per terminare
----------------------------------------------
10 hires 1,0
12 me = -2.0
14 mi = -1.2
20 de = 0.009375
30 di = 0.012
40 for i = 0 to 199
50 for j = 0 to 319
60 a = me + (j*de)
70 b = mi + (i*di)
80 x=0
90 y=0
100 for k = 1 to 100
110 xn = (x*x)-(y*y)+a
120 yn = (2*x*y)+b
130 t = (xn*xn)+(yn*yn)
135 cl = mod(k,2)
140 if (t>4) then plot j,i,cl
145 if (t>4) then k=101
150 x = xn
160 y = yn
170 next k
180 next j
190 next i
200 pause 5
Attenzione: in modalita' Warp il programma richiede oltre 30 minuti per terminare
----------------------------------------------
10 hires 1,0
12 me = -2.0
14 mi = -1.2
20 de = 0.009375
30 di = 0.012
40 for i = 0 to 199
50 for j = 0 to 319
60 a = me + (j*de)
70 b = mi + (i*di)
80 x=0
90 y=0
100 for k = 1 to 100
110 xn = (x*x)-(y*y)+a
120 yn = (2*x*y)+b
130 t = (xn*xn)+(yn*yn)
135 cl = mod(k,2)
140 if (t>4) then plot j,i,cl
145 if (t>4) then k=101
150 x = xn
160 y = yn
170 next k
180 next j
190 next i
200 pause 5
Iscriviti a:
Post (Atom)
Debugger integrato ESP32S3
Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede nell'ID USB della porta Jtag. Nel modulo...
-
In questo post viene indicato come creare uno scatterplot dinamico basato da dati ripresi da un file csv (nel dettaglio il file csv e' c...
-
La scheda ESP32-2432S028R monta un Esp Dev Module con uno schermo TFT a driver ILI9341 di 320x240 pixels 16 bit colore.Il sito di riferiment...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...