[zxspectrum] Re: Problema con ZXMMC+

  • From: Alessandro <alessandro.poppi@xxxxxxxxx>
  • To: zxspectrum@xxxxxxxxxxxxx
  • Date: Sat, 24 Dec 2011 10:01:52 +0100

On Fri, 2011-12-23 at 18:51 +0100, Antonio Giusa wrote:

> Sul +3 ogni uso del CP/M (quindi mappa memoria RAM only) corrompe ogni cosa 
> contenuta nella memoria della ZXMMC+ (il ResiDOS, nel mio caso).
> Non sospettavo di altri problemi.

Questa e' una indicazione interessante, perche' abbiamo delle scritture
nella ram della zxmmc+ pur facendo girare roba che non la coinvolge.
Se capisco bene, infatti, stai dicendo che il CP/M mappa memoria su
tutto lo spazio di indirizzamento, ma si tratta della ram interna al +3
e non di quella della zxmmc+.

L'alterazione della ram della zxmmc+ ha senso, perche' l'esecuzione del
CP/M comporta sicuramente delle scritture nell'ambito dei primi 16K
(dove di solito c'e' la rom) che e' anche l'area in cui e' possibile
accedere alla ram della zxmmc+.

(Ad onor del vero, la rom del 48K ha un qualche 'bug' tale per cui i
primi quattro o cinque bytes dello spazio di indirizzamento (le prime
locazioni della ROM stessa) vengono sovrascritte in certi frangenti,
durante l'esecuzione dell'interprete basic; cosa irrilevante per una
rom, ma abbastanza fastidiosetto per una ram se e' abilitata in
scrittura).

Cmq, veniamo al nostro problema.

Il registro che governa l'accesso alla memoria della zxmmc+ (e quindi
permette anche di proteggerla in scrittura) e' all'indirizzo $7F ed e'
R/W, per cui si puo' verificare il suo contenuto in ogni momento (e
questo e' un grande vantaggio) con un bel PRINT IN 127.

Questo registro, che si chiama 'fastpaging', permette di togliere di
mezzo la ROM nello spazio di indirizzamento fra 0 e $3FFF (quindi i
primi 16K) mappando al suo posto 64 possibili banchi di memoria della
zxmmc+ (da 16K ciascuno). Di questi, 32 sono di RAM (512K) e 32 di FLASH
(altri 512K).

Come indicato sul sito, i suoi bit funzionano nel seguente modo:

D7      RAM WR Enable
D6      PAGE-IN Enable
D5      RAM/ROM Select ('0' = RAM; '1' = ROM)
D4:D0   Page number (0 - 31)

I 5 bit LSB (D4:D0) servono a specificare a quale dei 32 possibili
banchi da 16K vogliamo accedere. Il bit D5 specifica se il banco
richiesto deve provenire dalla ROM (flash) o dalla RAM.

D6, quando ='1', attiva effettivamente lo switch del banco (ovvero
piazza il banco selezionato al posto della rom di sistema). NOTA: questo
bit controlla solo la LETTURA.

D7, quando ='1', abilita IN SCRITTURA la RAM. E' un bit AUTONOMO ed e'
con ogni probabilita' la chiave del problema.

E' sufficiente che questo bit sia a '1' per poter scrivere nel banco
selezionato (scrivendo entro i primi 16K di indirizzamento).

NOTARE che non c'e' bisogno di abilitare il banco anche in lettura (con
D6), per cui il computer puo' continuare a funzionare regolarmente
perche' la lettura avviene dalla memoria interna. Infatti, ecco la
formula che controlla il chip select della ram:

ram_cs <= '0' when hi_address = 0 and z80_mreq = '0' and reset = '1' and
 ((fastpage(7) = '1' and z80_wr = '0') or (fastpage(6 downto 5) = 2 and 
 z80_rd = '0')) else '1';

Quindi il ram_cs va basso (attivo) quando lo Z80 accede ai primi 16K:
in lettura se D6 e' '1' e D5 e' '0'; in scrittura se D7 = '1'.
(hi_address altro non e' che A15:A14, quindi se e' ==0 vuol dire che e'
il primo dei 4 banchi da 16K che lo Z80 puo' indirizzare).

MOTIVO:

Ho deciso di scriverlo in questo modo perche', cosi' facendo, e'
possibile copiare un banco di FLASH in RAM abilitando la flash in sola
lettura e la ram in sola scrittura, con un semplice loop di scrittura su
se stesso.

Questo e' meravigliosamente comodo :-) anche per copiare la rom di
sistema in un banco di ram, alterarla a piacimento ed infine abilitarla
in lettura al posto della rom originale.

Ad esempio, si puo' abilitare in scrittura un banco ram zxmmc+ con un
OUT 127, 128 (che abilita il banco n.0), copiarci la rom del basic (con
un ciclo for/next da 0 a 16383 che fa il POKE di quanto letto con un
PEEK allo stesso indirizzo, su tutti i primi 16K), alterare qualche
locazione per vederne l'effetto (ad esempio il logo sinclair), abilitare
la ram in lettura (al posto della rom) proteggendola contemporaneamente
in scrittura mediante un OUT 127, 64 ed infine fare un bel RANDOMIZE USR
0 per vedere l'effetto della nostra nuova "ROM".

Nota: per il motivo che dicevo sopra, ovvero che la rom del basic
sovrascrive le prime 4 o 5 locazioni di se stessa, affinche' questo
esperimento funzioni occorre che il comando OUT 127, 64 (che protegge la
ram in scrittura) avvenga senza passare per il prompt del basic, che e'
il momento in cui la sovrascrittura avviene. Ad esempio, si puo'
concatenare l'OUT 127, 64 alla fine del for/next con i classici ':' di
separazione delle istruzioni basic.

Riassumendo:

Credo che il CP/M alteri la ram della zxmmc+ perche', per qualche motivo
su cui potremmo indagare, nel registro di fastpaging (accessibile con
IN/OUT sulla porta 127) viene settato il bit D7, che abilita la ram
zxmmc+ in scrittura.

A quel punto, ogni scrittura in ambito 0-3FFF scrivera' anche nella
zxmmc+, mandando tutto a puttane :-)

1)
Dal CP/M puoi leggere la porta 127 e farci sapere cosa c'e' dentro?
(purtroppo e' possibile che venga 'sporcata' in piu' occasioni e quindi
potrebbe non risultare facile trovare conferma a queste ipotesi.

2)
Qualcuno puo' indicare se per caso la porta 127 puo' essere erroneamente
scritta da qualche programma che acceda ad altre porte? La zxmmc+
decodifica gli 8 bit LSB dell'indirizzo.

Ciao!



Other related posts: