Elenco blog personale

martedì 17 aprile 2018

Joyce, l'emulatore Amstrad PCW: installazione e modifiche al codice per il supporto alla tastiera italiana del Macbook Pro




Questo post descrive la procedura per compilare ed installare l'emulatore Joyce di Amstrad PCW su MacOS e una mia patch al codice sorgente per utilizzare la tastiera italiana del Macbook Pro.

La documentazione dell'emulatore spiega come personalizzare il layout della tastiera, tuttavia questo va fatto a CP/M già avviato, tramite il comando PCKEY. Ho trovato questo metodo di difficile applicazione, considerando anche che non riuscivo a digitare caratteri basilari come i due punti!

Ho quindi deciso di procedere con la via "facile", modificando direttamente il codice Joyce che gestisce la corrispondenza tra la tastiera del PC e quella del sistema emulato. Le modifiche, che si applicano alla versione 2.2.12, l'ho scritte senza badare molto alla forma e senza cercare alternative meno invasive ad una mappatura dei tasti hardcoded nel codice stesso, per cui non è certo un bel esempio di programmazione!

Joyce permette l'emulazione dei PCW serie 8000, 9000 e PCW10, mentre Anne (che si compila automaticamente con Joyce) emula il PCW16. La patch è stata testata solo con la serie 8000 (PCW 8256 e 8512).

Per compilare Joyce occorre prima di tutto installare alcune librerie. Per fare questo userò brew, un tool che porta moltissime applicazioni e librerie di Linux su MacOS. Incollare questa riga sul terminale e premere Invio per installare brew:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"


Installare ora tramite  brew le librerie necessarie (PNG, SDL e XML):

brew install libpng
brew install sdl
brew install libxml2


Il sito originale di Joyce è https://www.seasip.info/Unix/Joyce/, mentre la versione patchata è scaricabile dal mio profilo github, in questo modo:

git clone https://github.com/fdivitto/joyce-custom.git


Terminato il download procedere alla compilazione e all'installazione:


cd joyce-custom/
./configure
make
sudo make install


A questo punto Joyce è installato e funzionante e si può rimuovere la cartella con i sorgenti.
Per eseguire Joyce basta scrivere:

xjoyce


Se appare una finestra bianca premere Invio. Verrà creata la cartella ~\Joyce\Boot dove andranno inserite le immagini (dsk) di boot.
Al primo avvio Joyce necessita di una piccola configurazione e ci chiede da dove effettuare il boot che può essere effettuato sia dai drive fisici (fd0, fd1...) che da un'immagine di un floppy (Disc file):



La schermata successiva permette la selezione del file immagine. In questo caso sto selezionato il lato B del disco di sistema, dov'è contenuto il CP/M:



Si seleziona OK e quindi CONTINUE:



Ora Joyce ci chiede di dare un nome all'immagine. Io ho scritto 'cpm_plus':



A questo punto appare la schermata principale, che è quella che verrà presentata ogni volta che si avvia Joyce:



E' stata specificata una sola immagine, quella denominata "cpm_plus" ed identificata con "1". L'"1" è il tasto da premere se si vuole avviare dal disco "cpm_plus".
Prima di iniziare il boot occorre specificare il tipo di hardware da emulare. Come detto questa patch è specifica per PCW 8256/8512, quindi si procederà come segue. Premere F9, quindi F6 e selezionare con i tasti freccia la voce "General":



Premere Invio e selezionare 8256/8512:



Selezionare EXIT e quindi "Save Settings":




Uscire da tutte le schermate con Exit o con il tasto ESC. Adesso premendo "1" si effettuerà il boot ed il sistema sarà pronto per l'utilizzo:





Per concludere ecco una breve spiegazione delle modifiche che ho apportato al codice sorgente di Joyce. La classe C++ che gestisce la tastiera è chiamata JoycePcwKeyboard, ed è dichiarata e definita nei file JoycePcwKeyboard.hxx e JoycePcwKeyboard.cxx, entrambi posizionati nella cartella "bin".
Nella dichiarazione della classe ho aggiunto il campo m_fdvAlt che è un flag attivo per tutto il tempo in cui il tasto ALT è premuto. Ho dichiarato anche due metodi, il primo è fdv_handle() che è il gestore della tastiera alternativo a Joyce e fdv_setKeyMap() che ne è di supporto:

    bool m_fdvAlt;
    void fdv_setKeyMap(Uint8 addr, Uint8 bit, bool down);
    bool fdv_handle(SDLKey keysym, Uint8 type);

fdv_handle() intercetta solo le configurazioni di tasti (che chiamerò regole) specificati nell'array fdv_KMAPEX[], definito in JoycePcwKeyboard.cxx. Questo array è composto da una struttura di 11 campi: il primo (keysym) specifica il codice SDL del tasto premuto, mentre i campi shift e alt indicano se SHIFT e/o ALT debbano essere attivi affinché la regola venga applicata.

In alcuni casi è necessario disattivare SHIFT o ALT perché il tasto corrispondente sul PCW non li richiede mentre era necessario sul PC. E' il caso dell'uguale (=) che sul macbook si fa con SHIFT + '0', mentre sul PCW c'è un tasto dedicato. Per questo si utilizzano i campi off_addr_swAlt/off_bit_swAlt (quando l'opzione scambia EXTRA<->ALT è attiva) oppure off_addr_nswAlt/off_bit_nswAlt (quando l'opzione scambia EXTRA<->ALT è disattiva). I campi *_addr_* contengono il primo nibble (primi quattro bit) dell'indirizzo memory mapped della tastiera, mentre i campi *_bit_* il numero del bit relativo al tasto, secondo questa tabella:


Ad esempio, per disattivare lo SHIFT occorre impostare off_addr_swAlt = 2 (indirizzo 3FF2h) e off_bit_swAlt = 5 (bit 5).
I campi on_addr_1/on_bit_1on_addr_2/on_bit_2 specificano l'azione da intraprendere, cioè i tasti che il PCW vedrà premuti.
La regola da impostare per generare l'uguale è quindi questa:

{SDLK_0, true, false,   // tasto SDLK_0 e SHIFT premuto (ALT no)
 0x02, 0x05,     // SHIFT su (nel caso ALT-EXTRA scambiati)
 0x02, 0x05,     // SHIFT su (ALT-EXTRA non scambiati)
 0x03, 0x00,     // '=' giù
 0xFF, 0xFF},    // 0xFF indica "campi non utilizzati"

Il metodo fdv_handle(), oltre ad applicare le regole specificate nell'array fdv_KMAPEX[], si occupa anche di rilevare la pressione del tasto ALT (per impostare il flag m_fdvAlt) e sistemare un problema con il tasto CAPSLOCK.

Questa è la dichiarazione della struttura fdv_KMAPEX_t, utilizzata nell'array fdv_KMAPEX[]:

struct fdv_KMAPEX_t {
    // PC side state
    SDLKey keysym;
    bool shift;
    bool alt;
    // PCW side: switch off if m_swapAlt == true
    Uint8 off_addr_swAlt;        // 0xFF nothing to switch off
    Uint8 off_bit_swAlt;         // 0xFF nothing to switch off
    // PCW side: switch off if m_swapAlt == false
    Uint8 off_addr_nswAlt;        // 0xFF nothing to switch off
    Uint8 off_bit_nswAlt;         // 0xFF nothing to switch off
    // PCW side: switch on
    Uint8 on_addr_1;      // 0xFF nothing to switch on
    Uint8 on_bit_1;       // 0xFF nothing to switch on
    Uint8 on_addr_2;      // 0xFF nothing to switch on
    Uint8 on_bit_2;       // 0xFF nothing to switch on
};

Queste sono le regole:

static const fdv_KMAPEX_t fdv_KMAPEX[] = {
    // ':'      MAC-IT: SHIFT + '.'    PCW: SHIFT + ';'
    {SDLK_PERIOD, true, false,
     0xFF, 0xFF,     //
     0xFF, 0xFF,     //
     0x02, 0x05,     // SHIFT down
     0x03, 0x05},    // ';' down
    // ';'      MAC-IT: SHIFT + ','    PCW: ';'
    {SDLK_COMMA, true, false,
     0x02, 0x05,     // SHIFT up
     0x02, 0x05,     // SHIFT up
     0x03, 0x05,     // ';' down
     0xFF, 0xFF},    //
    // '\'      MAC-IT: '\'            PCW: EXTRA + '1/2'
    {SDLK_BACKSLASH, false, false,
     0xFF, 0xFF,     //
     0xFF, 0xFF,     //
     0x0A, 0x1,      // EXTRA down
     0x02, 0x6},     // '1/2' down
    // '|'      MAC-IT: SHIFT + '\'    PCW: EXTRA + '.'
    {SDLK_BACKSLASH, true, false,
     0x02, 0x05,     // SHIFT up
     0x02, 0x05,     // SHIFT up
     0x0A, 0x01,     // EXTRA down
     0x03, 0x07},    // '.' down
    // '&'      MAC-IT: SHIFT + '6'    PCW: SHIFT + '7'
    {SDLK_6, true, false,
     0x02, 0x05,     // SHIFT up
     0x02, 0x05,     // SHIFT up
     0x02, 0x05,     // SHIFT down
     0x05, 0x01},    // '7' down
    // '/'      MAC-IT: SHIFT + '7'    PCW: '/'
    {SDLK_7, true, false,
     0x02, 0x05,     // SHIFT up
     0x02, 0x05,     // SHIFT up
     0x03, 0x06,     // '/' down
     0xFF, 0xFF},    //
    // '('      MAC-IT: SHIFT + '8'    PCW: SHIFT + '9'
    {SDLK_8, true, false,
     0xFF, 0xFF,     //
     0xFF, 0xFF,     //
     0x02, 0x05,     // SHIFT down
     0x04, 0x01},    // '9' down
    // ')'      MAC-IT: SHIFT + '9'    PCW: SHIFT + '0'
    {SDLK_9, true, false,
     0xFF, 0xFF,     //
     0xFF, 0xFF,     //
     0x02, 0x05,     // SHIFT down
     0x04, 0x00},    // '0' down
    // '='      MAC-IT: SHIFT + '0'    PCW: '='
    {SDLK_0, true, false,
     0x02, 0x05,     // SHIFT up
     0x02, 0x05,     // SHIFT up
     0x03, 0x00,     // '=' down
     0xFF, 0xFF},    //
    // '''      MAC-IT: '''            PCW: SHIFT + '6'
    {SDLK_QUOTE, false, false,
     0xFF, 0xFF,     //
     0xFF, 0xFF,     //
     0x02, 0x05,     // SHIFT down
     0x06, 0x00},    // '6' down
    // '?'      MAC-IT: SHIFT + '''    PCW: SHIFT + '/'
    {SDLK_QUOTE, true, false,
     0xFF, 0xFF,     //
     0xFF, 0xFF,     //
     0x02, 0x05,     // SHIFT down
     0x03, 0x06},    // '/' down
    // '^'      MAC-IT: SHIFT + 'ì'    PCW: EXTRA + '7'
    {(SDLKey)0xA0, true, false,   // In my system 'ì' is 0xA0
     0x02, 0x05,     // SHIFT up
     0x02, 0x05,     // SHIFT up
     0x0A, 0x01,     // EXTRA down
     0x05, 0x01},    // '7' down
    // '['      MAC-IT: ALT + 'è'      PCW: '['
    {(SDLKey)0xA1, false, true,
     0x0A, 0x01,     // EXTRA up (EXTRA<->ALT)
     0x0A, 0x07,     // ALT up
     0x03, 0x02,     // '['
     0xFF, 0xFF},    //
    // ']'      MAC-IT: ALT + '+'      PCW: ']'
    {SDLK_PLUS, false, true,
     0x0A, 0x01,     // EXTRA up (EXTRA<->ALT)
     0x0A, 0x07,     // ALT up
     0x02, 0x01,     // ']'
     0xFF, 0xFF},    //
    // '+'      MAC-IT: '+'            PCW: SHIFT + '='
    {SDLK_PLUS, false, false,
     0xFF, 0xFF,     //
     0xFF, 0xFF,     //
     0x02, 0x05,     // SHIFT down
     0x03, 0x00},    // '=' down
    // '*'      MAC-IT: SHIFT + '+'    PCW: SHIFT + '8'
    {SDLK_PLUS, true, false,
     0xFF, 0xFF,     //
     0xFF, 0xFF,     //
     0x02, 0x05,     // SHIFT down
     0x05, 0x00},    // '8' down
    // '@'      MAC-IT: ALT + 'ò'      PCW: SHIFT + '1/2'
    {(SDLKey)0xA3, false, true,
     0x0A, 0x01,     // EXTRA up (EXTRA<->ALT)
     0x0A, 0x07,     // ALT up
     0x02, 0x05,     // SHIFT down
     0x02, 0x6},     // '1/2' down
    // '#'      MAC-IT: ALT + 'à'      PCW: '#'
    {(SDLKey)0xA2, false, true,
     0x0A, 0x01,     // EXTRA up (EXTRA<->ALT)
     0x0A, 0x07,     // ALT up
     0x02, 0x03,     // '#' down
     0xFF, 0xFF},    //
    // '{'      MAC-IT: SHIFT + ALT + 'è'    PCW: SHIFT + '['
    {(SDLKey)0xA1, true, true,
     0x0A, 0x01,     // EXTRA up (EXTRA<->ALT)
     0x0A, 0x07,     // ALT up
     0x02, 0x05,     // SHIFT down
     0x03, 0x02},    // '['
    // '{'      MAC-IT: SHIFT + ALT + '+'    PCW: SHIFT + '['
    {SDLK_PLUS, true, true,
     0x0A, 0x01,     // EXTRA up (EXTRA<->ALT)
     0x0A, 0x07,     // ALT up
     0x02, 0x05,     // SHIFT down
     0x02, 0x01},    // ']'
    // '°'      MAC-IT: SHIFT + 'à'          PCW: EXTRA + '5'
    {(SDLKey)0xA2, true, false,
     0x02, 0x05,     // SHIFT up
     0x02, 0x05,     // SHIFT up
     0x0A, 0x01,     // EXTRA down
     0x06, 0x01},    // '5'
    // '~'      MAC-IT: ALT + '5'            PCW: EXTRA + '-'
    {SDLK_5, false, true,
     0x0A, 0x01,     // EXTRA up (EXTRA<->ALT)
     0x0A, 0x07,     // ALT up
     0x0A, 0x01,     // EXTRA down
     0x03, 0x01},    // '-'
    // '<'      MAC-IT: '<'                  PCW: SHIFT + '§'
    {SDLK_LESS, false, false,
     0xFF, 0xFF,     //
     0xFF, 0xFF,     //
     0x02, 0x05,     // SHIFT down
     0x03, 0x04},    // '§'
    // '>'      MAC-IT: SHIFT + '<'          PCW: SHIFT + '#'
    {SDLK_LESS, true, false,
     0x02, 0x05,     // SHIFT up
     0x02, 0x05,     // SHIFT up
     0x02, 0x05,     // SHIFT down
     0x02, 0x03},    // '#'
};

Ecco i due metodi fdv_setKeyMap() (di supporto) e fdv_handle() (il gestore vero e proprio):

void JoycePcwKeyboard::fdv_setKeyMap(Uint8 addr, Uint8 bit, bool down)
{
  if (down)
    m_pcwKeyMap[addr] |= 1 << bit;
  else
    m_pcwKeyMap[addr] &= ~(1 << bit);
}

bool JoycePcwKeyboard::fdv_handle(SDLKey keysym, Uint8 type)
{
  if (type == SDL_KEYDOWN || type == SDL_KEYUP)
  {
    // semi-handle ALT
    if (keysym == SDLK_LALT || keysym == SDLK_RALT)
    {
      m_fdvAlt = type == SDL_KEYDOWN;
      return false;   // not handled
    }

    // handle CAPSLOCK
    if (keysym == (SDLKey)0x12D)
    {
      m_shiftLock = type == SDL_KEYDOWN;
      return true;   // handled
    }

    for (int i = 0; i < sizeof(fdv_KMAPEX) / sizeof(fdv_KMAPEX_t); ++i)
      if (fdv_KMAPEX[i].keysym == keysym && fdv_KMAPEX[i].shift == m_trueShift && fdv_KMAPEX[i].alt == m_fdvAlt)
      {
        // switch off (if m_swapAlt == true)
        if (m_swapAlt && fdv_KMAPEX[i].off_addr_swAlt != 0xFF)
          fdv_setKeyMap(fdv_KMAPEX[i].off_addr_swAlt, fdv_KMAPEX[i].off_bit_swAlt, type != SDL_KEYDOWN);
        // switch off (if m_swapAlt == false)
        if (!m_swapAlt && fdv_KMAPEX[i].off_addr_nswAlt != 0xFF)
          fdv_setKeyMap(fdv_KMAPEX[i].off_addr_nswAlt, fdv_KMAPEX[i].off_bit_nswAlt, type != SDL_KEYDOWN);
        // switch on (down)
        if (fdv_KMAPEX[i].on_addr_1 != 0xFF)
          fdv_setKeyMap(fdv_KMAPEX[i].on_addr_1, fdv_KMAPEX[i].on_bit_1, type == SDL_KEYDOWN);
        if (fdv_KMAPEX[i].on_addr_2 != 0xFF)
          fdv_setKeyMap(fdv_KMAPEX[i].on_addr_2, fdv_KMAPEX[i].on_bit_2, type == SDL_KEYDOWN);
        m_keyPress = true;
        return true;
      }
  }
  return false;   // not handled
}

La chiamata a fdv_handle() viene effettuata all'interno di handleEvent(), per cui va modificato così:

int JoycePcwKeyboard::handleEvent(SDL_Event &e)
{
...
  if (keysym == SDLK_LSHIFT || keysym == SDLK_RSHIFT) 
    m_trueShift = b;

  if (fdv_handle(keysym, e.type))
    return 1;
...
}






sabato 7 aprile 2018

Retro-restoring Amstrad PCW 8512





Il PCW 8512 (e il suo fratello minore 8256) è un computer ad 8 bit prodotto dalla Amstrad a partire dal 1985. Concepito principalmente come sistema di video-scrittura, poteva essere utilizzato anche come un computer general purpose basato sul sistema operativo CP/M.





La CPU

Il microprocessore utilizzato è il famoso Zilog Z80 con clock a 4MHz, mentre la RAM è di 512K. La cosa interessante di questo sistema è che è sprovvisto di ROM, per cui il sistema operativo ed il BIOS vengono caricati dal disco. All'avvio il controller della stampante invia delle istruzioni alla CPU che non fanno altro che scrivere dall'indirizzo 0x0000 il vero codice di bootstrap. Quest'ultimo a suo volta caricherà dal disco A il bootstrap del sistema operativo.


Lo Storage

Il sistema ha due dischi da 3'' (non 3.5''!!) che è lo stesso formato usato dal CPC 6128 e dal Sinclair Spectrum +3. Il drive A è a singola densità e singola faccia, per cui, con 40 tracce da 9 settori di 512 byte, ha una capacità di 180K. Il drive B è a doppia densità e doppia faccia (40 cilindri da 18 settori) quindi può contenere 720K.


Il Video

Il monitor è monocromatico a fosfori verdi e può visualizzare 720x256 pixels, corrispondenti a 90 colonne per 32 righe in modalità testo. In realtà non c'è una modalità testo, la memoria video è completamente bitmapped. In questo modo uno scrolling fluido sarebbe difficile da ottenere con il solo Z80, per questo ogni riga dello schermo viene indirizzata singolarmente da un'area di 256 puntatori (denominata Roller-RAM). Cambiando i puntatori si cambia anche l'ordine delle righe visualizzate, rendendo lo scrolling istantaneo. Purtroppo questa versatilità si paga con la necessità di un codice più complesso quando si fa grafica anziché semplice testo.
I codici di controllo dello schermo sono quasi completamente compatibili con lo Zenith Z19/Z29,  come il terminale VT52, mentre per la stampante sono compatibili con la Seikosha SP-800.


L'Audio

L'audio si limita ad un semplice beep proveniente da un buzzer interno, con frequenza e volume fissi.


Il Chipset

Lo Z80 viene affiancato da un chip ASIC che controlla la maggior parte delle funzioni, tra cui il refresh della RAM dinamica, la decodifica degli indirizzi ed il video. I disk drive vengono gestiti da un NEC µPD765A, che pur potendo controllare quattro dischi a doppia faccia e doppia densità viene invece utilizzato limitatamente a come descritto sopra.
E' incluso inoltre un controller per la stampante (atipico, in quanto questo controller dovrebbe stare nell'hardware della stampante stessa) che è un NEC µPD8041. Questo è in realtà una piccola MCU dotata di 64 byte di RAM e 1K di ROM. Come detto la funzione di questa MCU non è solo di controllare l'hardware della stampante, ma soprattuto quello di "iniettare" del codice nel bus dati affinché lo Z80 scriva a sua volta il codice di boot nella RAM.


La Memoria

La RAM è divisa in 32 banchi da 16K. Dato che lo Z80 può indirizzare al massimo 64K soltanto quattro banchi sono contemporaneamente visibili dalla CPU. La Roller-RAM ed il video frame buffer possono essere allocati in qualsiasi posizione purché situata nei primi 8 banchi.
Il PCW 8256 è espandibile a 512K aggiungendo 8 chip di tipo 41256 nei socket liberi e cambiando alcuni dip-switch sulla motherboard.


Le Porte

Sul retro ci sono due porte, una dedicata alla stampante ed una di espansione. In quest'ultima sono presenti il bus indirizzi, il bus dati, i segnali di controllo, il clock della CPU, il segnale di reset e due segnali utilizzabili, con un circuito adattatore, come uscita video ausiliaria.


Il Sistema Operativo

Il PCW può utilizzare la versione 3 di CP/M, denominata CP/M Plus, che è anche l'ultima rilasciata dalla Digital Research per i sistemi ad 8 bit. Questa versione ha il vantaggio, rispetto alle precedenti, di supportare il bank switching, il che consente di avere molta più memoria libera per le applicazioni (TPA, Transient Program Area): nel caso del PCW il TPA è di 61K.
Non tutti i 512K vengono utilizzati dal S.O. e come TPA: oltre alla memoria video, una parte è riservata per mantenere residente il CCP (la shell), mentre il restante è dedicato alla Ram Disk, accessibile come drive M. Nell'8512 la dimensione della Ram Disk è di 368K.
C'è inoltre il supporto per GSX (Graphics System Extension) che fornisce un insieme di primitive grafiche standardizzate per i programmi CP/M che utilizzano la grafica.


Il Restauro

Ho acquistato su ebay un 8512 per 30 GPB con la sezione di alimentazione completamente guasta. Ho così deciso di rimuoverne i componenti e sulla parte libera alloggiare una nuova PSU.
Internamente il PCW è composto da tre parti principali: la Power Board, che fornisce l'alimentazione e controlla lo schermo, lo schermo CRT e la motherboard, dov'è lo Z80 e il chipset.
Questo è lo schema della Power Board: l'area rossa è quella relativa all'alimentazione (12V per il monitor e per i drive, 5V per il buffer del segnale video e per la motherboard e i 24V per la stampante esterna), di cui ho rimosso i componenti, quello che rimane gestisce il tubo catodico.



Questa è la Power Board dopo la rimozione dei componenti. Rimane solo la sezione video:


Il modello che ho ricevuto aveva anche un altro problema: un fastidioso fischio proveniente nella sezione ad alta tensione. Ho sostituito il trasformatore di riga (Flyback Transformer) e tutti i condensatori vicini: in questo modo il fischio è completamente sparito. L'unica difficoltà è stato trovare un flyback compatibile. Io l'ho recuperato da un monitor Amstrad MM12, che monta praticamente gli stessi componenti.

Ho quindi installato un SMPS (Switched Mode Power Supply) da 12V - 3A (un semplice alimentatore per notebook, il blocco di destra), e di seguito un modulo basato su HRD05003 per i 5V (quello più piccolo a sinistra):


Ho rimosso i due dischi da 3'' per sostituirli con due emulatori di floppy drive Gotek, con firmware alternativo (FlashFloppy). Bisogna fare attenzione all'alimentazione, che è invertita rispetto allo standard PC (12V <-> 5V), per cui bisogna costruire un adattatore:



Ovviamente occorre un adattatore anche per i segnali dati del drive, che da 26 pin andranno adattati a 34. La corrispondenza è questa:

Per il Gotek:

Segnale    PCW-26     Gotek (Shugart-34)
GND         1          1
IDX         2          8
DS1         4         10 (DS1   - gotek impostato su S0)
DS2         6         12 (DS2   - gotek impostato su S1)
MOT         8         16
DIR        10         18
STP        12         20
WD         14         22
WG         16         24
TK0        18         26
WP         20         28
RD         22         30
SS         24         32
READY      26         34


Per un normale floppy drive PC, solo per il drive A (un 3.5'' per PC risponde sempre come secondo disco):

Segnale    PCW-26     DRIVE (PC-34)
GND         1          1
IDX         2          8
DS1         4         12
DS2         6         ...altrimenti il 12 va qui per drive B
MOT         8         16
DIR        10         18
STP        12         20
WD         14         22
WG         16         24
TK0        18         26
WP         20         28
RD         22         30
SS         24         32
READY      26         1 (ready non disponibile!)



Dai Gotek ho rimosso il contenitore per sostituirlo con uno progettato appositamente e stampato in 3D (potete trovarlo sul mio profilo thingverse), così che si vada ad inserire e fissare perfettamente nell'alloggiamento dei dischi da 3''. E' stato anche sostituito il display con uno OLED, così da visualizzare i nomi delle immagini:


Il Gotek montato sull'adattatore:


Il tutto installato al posto del drive A...


....e quindi il B:

Il risultato finale visto di fronte:



Il Software

Il PCW viene fornito di due dischi di sistema. Essendo a singola faccia, ogni lato è come se fosse un disco a sé da 180K. Questo è il contenuto:

Disco 1, lato A: Locoscript
Disco 1, lato B: CP/M Plus con Mallard Basic 

Disco 2, lato A: DR Logo & Help
Disco 2, lato B: Programming Utilities

Solo il disco 1 è di avvio, per cui inserendo il lato A (verso lo schermo) partirà il Word Processor Locoscript, mentre inserendo il lato B sarà avviato il CP/M.
Sul web si trovano le immagini dei dischi di sistema in formato .DSK, che è direttamente leggibile dal firmware alternativo FloppyFlash.

Con Linux (o OSX, ma non so se anche con Windows) ci sono dei tools per leggere o scrivere immagini DSK formattate per PCW, anche a livello di file. In questo modo si possono caricare tutti i software compatibili con CP/M, anche se non in formato immagine.
Questi tools si chiamano cpmtools e vanno compilati con il supporto per la libreria libdsk, per cui la prima cosa da fare è installare libdsk. Qui lo faccio tramite brew (https://brew.sh/index_it):

brew install libdsk

Installata libdsk si può scaricare (http://www.moria.de/~michael/cpmtools/), configurare e installare i cpm tools:

./configure --with-libdsk
make install

Il formato dei dischi da 180K è indicato con il parametro pcw, mente per quelli da 720K è cf2dd. Questi formati sono supportati nativamente dai cpmtools, ma il tipo di immagine DSK è supportato solo compilandoli con il supporto per libdsk, come visto sopra.

Adesso si possono usare i tools, per esempio questo visualizza il contenuto dell'immagine img.dsk:

cpmls -d -f pcw img.dsk        <= per formato 180K (drive A del 8256 o 8512)
cpmls -d -f cf2dd img.dsk   <= per formato 720K (drive A del 9512 o drive B del 8512)

Questo comando invece copia il file locale TEST.COM nell'immagine dal 180K img.dsk, come user 0 (gli users sono una sorta di cartelle e nel CP/M ce ne possono essere 16):

cpmcp -f pcw img.dsk TEST.com 0:


Questi sono alcuni screenshot avviando il PCW con Locoscript (disco 1, lato A):




Questo invece è l'avvio da CP/M e l'esecuzione del Mallard Basic (Disco 1, lato B):





Esiste infine anche un sistema operativo Open Source e ancora attivamente sviluppato, con finestre e multitasking, chiamato Symbos, compatibile  anche con i CPC e gli MSX2. Queste sono alcune schermate:





Riferimenti

Il sito di John Elliott, il "guru" del PCW e del CP/M

Software PCW

Software CP/M

Sito "non-ufficiale" sul CP/M

FlashFloppy

Symbos