User Tools

Site Tools


content:retrocomputing:vice

VICE

Intro

Si tratta di un emulatore, disponibile per vari sistemi operativi, di home computer Commodore.

Installazione

Si può installare dai repo Ubuntu, ma poi bisogna copiare le ROM dal pacchetto sorgente, pena errore di “fail to load kernal”.

Le tre ROM da copiare corrispondono ai chip fisici:

$ wget http://www.zimmers.net/anonftp/pub/cbm/crossplatform/emulators/VICE/vice-2.4.tar.gz
$ tar vzxf vice-2.4.tar.gz

$ cd Scaricati/vice-2.4/data/C64
# cp kernal basic chargen /usr/lib/vice/C64

Copiare anche le ROM dei varie drive e datassette:

$ cd Scaricati/vice-2.4/data/DRIVES
# cp d* /usr/lib/vice/DRIVES

Esecuzione

Digitare “Commodore…” e seleziore il 64. Oppure da bash digitare x64.

Tastiera

Apple

Home: fn + cursore sx

Ad esempio per cancellare lo schermo, sul C64 si fa shift + Home, qui si fa shift + fn + cursore sx.

RUN/STOP: esc

RESTORE: fn + cursorse su

Altri tasti sono disponibili qui.

Salvataggi

Per salvare un programma Basic (ed eventualmente poi importarlo in un vero C64…) si fa:

Create and attach an empty disk image….

Dare poi il nome del programma, che avrà come estensione .d64. Una volta creata l'immagine disco, si potrà collegarla semplicemente con Attach a disk image; i vari programmi verranno salvati come file separati con estensione .PRG.

Machine Language Monitor

Un MLM (machine language monitor) in assembly è un tool che consente di:

  • visualizzare locazioni di memoria
  • scrivere/modificare locazioni di memoria
  • eseguire codice da memoria

Per entrare nel VICE Monitor digitare Alt+H (Command+H per i Mac :?:). Quando è attivo il monitor non è attivo il Basic.

Visualizzare i registri

Visualizzare i registri (con 'R'):

(C:$e5d1) R
  ADDR A  X  Y  SP 00 01 NV-BDIZC LIN CYC  STOPWATCH
.;e5d1 00 00 0a f3 2f 37 00100010 000 000    5425056
(C:$e5d1) 

Leggere e scrivere nella memoria

Visualizzare il contenuto della memoria (con 'M'):

(C:$1011) M 033c 0348
>C:033c  00 00 00 00  00 00 00 00  00 00 00 00  00            .............
(C:$0349) 

Le locazioni $033C-$0348 sono tutte vuote; scriviamo nella memoria (con '>C') in linguaggio macchina:

(C:$0349) >C:033c ad 80 03 ae 81 03 8d 81 03 8e 80 03 00
(C:$0349)

Il programma consiste nello scambiare il contenuto delle locazioni $0380 e $381 (questo è ancora da verificare/modificare).

Per verificare il contenuto della memoria appena scritta:

(C:$0349) M 033c 0348
>C:033c  ad 80 03 ae  81 03 8d 81  03 8e 80 03  00            .............
(C:$0349) 

Verifichiamo e quindi copiamo dei valori nelle locazioni $0380 e $381:

(C:$0410) M $0380 $0381
>C:0380  00 00
	
(C:$0382) >C:0380 11 99

Adesso la locazione $0380 contiene il valore $11 e la $0381 contiene $99.

Eseguire codice da memoria

Eseguiamo il programma (con 'G') che inverte le locazioni:

(C:$0382) G 033c

Le due locazioni adesso hanno effettivamente il contenuto invertito:

(C:$e5d1) M 0380 0381
>C:0380  99 11  

Disassemblare

Per disassemblare (tradurre da linguaggio macchina in assembly) le locazioni dove si è salvato il codice si fa così (con 'D'):

(C:$0382) D 033c 0348
.C:033c  AD 80 03    LDA $0380
.C:033f  AE 81 03    LDX $0381
.C:0342  8D 81 03    STA $0381
.C:0345  8E 80 03    STX $0380
.C:0348  00          BRK

L'ultimo comando (BRK) presente in $0348 interrompe il Monitor e passa il controllo al Basic nel VICE. Anche qui possiamo verificare il valore, modificato, delle locazioni $0380 (896 in decimale) e $0381 (897):

? PEEK(896)
 153 (cioè $99)
 
? PEEK(897)
 17 (cioè $11)

Un altro modo per passare dal monitor al Basic è premendo 'X'.

Assemblare

Per assemblare (scrivere in assembly per poi essere tradotto in linguaggio macchina) si fa così (con 'A'):

(C:$034b) A 033c
.033c  LDA #$99
.033e  STA $0380
.0341  LDX #$98
.0343  STX $0381
.0346  
(C:$0346) M 033c 034a
>C:033c  a9 99 8d 80  03 a2 98 8e  81 03 00 00  00 00 00      ...............
(C:$034b) 

Il carattere '#' indica che il valore da caricare nel registro non è quello di una locazione di memoria, ma un valore immediato (o letterale).

Basic

L'esecuzione può avvenire anche nel Basic del C64:

SYS 828 

Dove '828' è il decimale di $033C.

Il programma, che carica i valori $99 e $98 nelle locazioni $0380 e $0381, è stato eseguito:

(C:$e5d1) M 0380 0381
>C:0380  99 98                                                ..

KERNAL subroutines

Per scrivere a video possiamo usare il seguente codice:

(C:$e5cd) >C:0400 3 9 1 f 20 12 f 2 5 12 14 f
(C:$e5cd) X

dove $0400 è l'inizio della memoria video del C64; i caratteri che seguono non sono ASCII, ma screen codes (vedi Appendice B della C64 Programmer's Reference Guide).

Il codice produrrà il seguente output:

Invece che scrivere direttamente in memoria, si possono usare le KERNAL subroutines. Uno dei vantaggi di queste è che usano i codici ASCII; ad es. la CHROUT ($FFD2) mostra a video il contenuto del registro A.

(C:$e5cf) A 033c LDA #$41
.033e  JSR $FFD2
.0341  LDA #$42
.0343  JSR $FFD2
.0346  LDA #$43
.0348  JSR $FFD2
.034b  
(C:$034b) G 033c

A video comparirà velocemente la scritta 'ABC' ($41 $42 $43).

Aggiungendo 'RTS' (Return from subroutine):

.034b RTS  

è possibile eseguire il comando dal Basic:

SYS 828

Loop

Ipotizziamo di voler ottimizzare il precedente codice memorizzando, invece di 'ABC' la sequenza 'HELLO' in locazioni di memoria consecutive e leggerle tramite un loop.

(C:$e5cd) A 033c
.033c  LDX #$00
.033e  LDA $034A,X
.0341  JSR $FFD2
.0344  INX
.0345  CPX #$06
.0347  BNE $033E
.0349  RTS

Per questo loop andremo ad utilizzare il registro X perché:

  1. il registro X può essere incrementato (riga $0344), a differenza dell'Accumulatore
  2. può essere implementato, assieme all'accumulatore, per ottenere un indirizzamento di tipo absolute (vedi riga $033e)

Per stampare la stringa voluta, sarà sufficiente memorizzare i valori ASCII esadecimali di HELLO e RETURN. Sono valori che dobbiamo memorizzare come tali, non possiamo assemblarli:

(C:$0368) >C:034a 48 45 4c 4c 4f 0d

Richiamando la subroutine dal Basic otteniamo:

Salvare

Per potere salvare il codice bisogna essere in Basic; bisogna:

  • reperire, tramite dei PEEK, i valori sia del codice che i valori di testo di HELLO
  • ricrearli poi con dei POKE

Recuperiamo intanto il codice e valori stringa; il codice in assembly è compreso tra $033c e $034f, che corrispondono ai decimali 828 e 847. Quindi:

Si tratta dei valori decimali del codice esadecimale inserito nelle locazioni. Tali valori possono poi essere ricopiati tramite comandi Basic DATA e memorizzati con dei POKE:

Tale codice, che ricrea il codice assembly di prima, si può ovviamente salvare come un qualsiasi programma Basic:

Per salvare su nastro usa il comando File-Create and attach datassette image…. Dopodiché si potrà salvare il listato ed eseguirlo:

Cancellando il programma Basic (ad esempio con 'NEW') il codice in memoria rimane comunque
content/retrocomputing/vice.txt · Last modified: 2022/12/08 22:21 by admin