Benvenuti nel MAME-Blog di Robiza

GEOS e mouse Amiga

Scritto il 24 maggio 2017 da Robiza

Dopo molto tempo sto riprendendo in mano il driver del Commodore 64. In particolare volevo verificare ed eventualmente migliorare la compatibilità con GEOS.

Con l’occasione ho preso in mano i driver di input di GEOS per poterlo utilizzare con l’unico mouse che possiedo: un mouse compatibile Amiga.

In giro per la rete ho trovato il sorgente del driver originale Berkeley. Partendo dal sorgente ho creato il driver che però ha mostrato alcune problematiche.

Nella sostanza un mouse amiga utilizza 2 bit per la direzione su-giu’ (bit 0 e bit 2) e 2 bit per la direzione destra-sinistra (bit 1 e bit 3) della porta $DC01 (joystick 1).

Muovendo da destra a sinistra ad esempio si generano ripetutamente 4 valori in un ordine prefissato, stessa cosa con alto e basso.

Il driver parte dal presupposto che conoscendo il valore precedente della porta e il nuovo valore si riesce a capire in che direzione si sta andando.

Ad esempio se i 4 valori che si ripetono sono: 00000101 00000100 00000000 00000001 con la lettura precedente a 00000000 e dalla porta si legge 00000100 significa che si sta andando a sinistra. Se leggo 00000001 invece si sta andando a destra.

Il driver originale ha un piccolo bug relativamente al fatto che non sono riportate le corrette sequenze. Bug ovviamente che ho corretto.

Il problema vero è che le letture vengono fatte 60 volte al secondo. Non si riesce quindi ad intercettare tutte le letture salvo che non si muova il mouse ad una velocità ridottissima. Già a velocità diverse, pur contenute, non si è più in grado di rilevare la corretta sequenza e quindi il mouse si muove casualmente.

Per risolvere il problema ho pensato di modificare questa impostazione. Nella mia versione ogni 1/60 di secondo viene letto il valore della porta e memorizzato come valore precedente. Successivamente vengono fatte per un certo periodo ulteriori letture fintanto che o tali letture differiscono dalla prima lettura (ciascuna direzione è ovviamente indipendente) o finché non passa un certo periodo di tempo (regolato da un ciclo gestito dal registro Y).

Con questa impostazione il driver funziona molte bene salvo che per spostarsi dal bordo sinistro al bordo destro servono 50 cm di tavolo. Si può comunque impostare uno spostamento doppio (o triplo) per dimezzare (o ridurre di un terzo) lo spazio. A quel punto però la freccia si muove di 2 pixel (o 3) alla volta. Se il mouse serve solo a gestire il desktop la soluzione penso sia adeguata. Se serve invece usarlo per disegnare con GeoPaint forse è preferibile il movimento più lento.

Si potrebbe gestire comunque una sorta di accelerazione abbastanza facilmente. Unico problema che la versione attuale del mio codice sta già usando praticamente tutto lo spazio disponibile per il driver (l’intervallo massimo utilizzabile è FE80 a FFF9; attualmente mi rimangono solo 4 byte). Se non trovo modo di ottimizzare il codice per renderlo più compatto mi sa che mi accontenterò.

Per chi fosse interessato questo è il codice ASM; sotto trovate copia del driver impostato con un ciclo di tempo impostato a 7F e uno spostamento della freccia impostata a 3 pixel alla volta; tale configurazione è discreta per l’uso del desktop

Inizializzazione del mouse:

FE95   LDA #$08
FE97   STA $3A
FE99   STA $3C
FE9B   LDA #$00
FE9D   STA $3B
FE9F   STA $84B7

Gestione del rallentamento del mouse (non utilizzato):
FEA2   RTS

Mapping per accedere ai registri:
FEA3   BIT $30
FEA5   BCC $FEA2
FEA7   LDA $01
FEA9   PHA
FEAA   LDA #$35
FEAC   STA $01
FEAE   LDA $DC03
FEB1   PHA
FEB2   LDA $DC01
FEB5   PHA
FEB6   LDA #$FF
FEB8   STA $DC03

Memorizzazione della prima lettura della porta del mouse (joystick 1):
FEBB   LDA $DC01
FEBE   TAY
FEBF   AND #$0A
FEC1   STA $FFF4
FEC4   STA $FFF3
FEC7   TYA
FEC8   AND #$05
FECA   STA $FFF5
FECD   STA $FFF6

Trafsormazione della lettura in un formato utilizzabile:
FED0   AND #$01
FED2   STA $FE8C
FED5   TYA
FED6   AND #$04
FED8   LSR A
FED9   ORA $FE8C
FEDC   STA $FE8C
FEDF   TYA
FEE0   AND #$02
FEE2   LSR A
FEE3   STA $FE8D
FEE6   TYA
FEE7   AND #$08
FEE9   LSR A
FEEA   LSR A
FEEB   ORA $FE8D
FEEE   STA $FE8D

Ciclo per verificare se la lettura della porta cambia valore nelle direzioni x e y etro un certo “tempo”
FEF1   LDX #$03       il registro X è utilizzato come flag per rilevare se la lettura x o la lettura y sono cambiate
FEF3   LDY #$7F       <——- tempo a disposizione; il codice di verifica cambiamento del valore della porta viene ripetuto Y volte
FEF5   TXA
FEF6   AND #$01      il bit zero del registro X indica se è già variata la coordinata y
FEF8   BEQ $FF08    la lettura y è già cambiata? se si salta il codice di lettura
FEFA   LDA $DC01
FEFD   AND #$05
FEFF   CMP $FFF5
FF02   BEQ $FF08
FF04   STA $FFF6
FF07   DEX                  cambiamento coordinata y; alza la flag
FF08   TXA
FF09   AND #$02       il bit uno del registro X indica se è già variata la coordinata x
FF0B   BEQ $FF1C     la lettura x è già cambiata? se si salta il codice di lettura
FF0D   LDA $DC01
FF10   AND #$0A
FF12   CMP $FFF4
FF15   BEQ $FF1C
FF17   STA $FFF3
FF1A   DEX
FF1B   DEX                   cambiamento coordinata x; alza la flag
FF1C   DEY
FF1D   BNE $FEF5      riesegui il ciclo finchè non si azzera Y

Combina le coordinate x e y eventualmente variate e memorizza per uso futuro:
FF1F   LDA $FFF6
FF22   ORA $FFF3
FF25   STA $FFF6             (per risparmiare bytes si puo’ usare un TAY -> risparmio complessivo 5 bytes)

Verifica pressione del tasto sinistro del mouse:
FF28   LDA $DC01
FF2B   AND #$10
FF2D   CMP $FE8A
FF30   BEQ $FF48
FF32   STA $FE8A
FF35   LDA $DC01
FF38   AND #$10
FF3A   BNE $FF48
FF3C   LDA $39
FF3E   ORA #$20
FF40   STA $39
FF42   ASL A
FF43   ASL A
FF44   ASL A
FF45   STA $8505

Verifica se il mouse si è mosso orizzontalmente:
FF48   LDA $FFF6                                                                           (se sopra ho TAY qui va TYA)
FF4B   TAY                  il registro Y contiene la lettura               (se sopra ho TAY questa istruzione non serve)
FF4C   AND #$01
FF4E   STA $FE8B
FF51   TYA
FF52   AND #$04
FF54   LSR A
FF55   ORA $FE8B
FF58   TAX
FF59   PHA
FF5A   CMP $FE8C
FF5D   BEQ $FF8C
FF5F   LDA $FE8C
FF62   CMP $FE91,X
FF65   BEQ $FF7B
FF67   CMP $FE8E,X
FF6A   BNE $FF8C
FF6C   TXA
FF6D   PHA
FF6E   LDA $3C
FF70   SBC #$01          <——– moltiplicatore; sposta in alto di tot. pixel
FF72   CMP #$C8
FF74   BCC $FF88
FF76   LDA #$00
FF78   JMP $FF88
FF7B   TXA
FF7C   PHA
FF7D   LDA $3C
FF7F   CLC
FF80   ADC #$01          <——– moltiplicatore; sposta in basso di tot. pixel
FF82   CMP #$C8
FF84   BCC $FF88
FF86   CMP #$C7
FF88   STA $3C
FF8A   PLA
FF8B   TAX
FF8C   PLA
FF8D   STA $FE8C
FF90   TYA
FF91   AND #$02
FF93   LSR A
FF94   STA $FE8B
FF97   TYA
FF98   AND #$08
FF9A   LSR A
FF9B   LSR A
FF9C   ORA $FE8B
FF9F   TAX
FFA0   PHA
FFA1   CMP $FE8D
FFA4   BEQ $FFE3
FFA6   LDA $FE8D
FFA9   CMP $FE8E,X
FFAC   BEQ $FFCF
FFAE   CMP $FE91,X
FFB1   BNE $FFE3
FFB3   LDA $3A
FFB5   CLC
FFB6   ADC #$01          <——– moltiplicatore; sposta a destra di tot. pixel
FFB8   STA $3A
FFBA   LDA $3B
FFBC   ADC #$00
FFBE   STA $3B
FFC0   BEQ $FFE3
FFC2   LDA $3A
FFC4   CMP #$40
FFC6   BCC $FFE3
FFC8   LDA #$3F
FFCA   STA $3A
FFCC   JMP $FFE3
FFCF   LDA $3A
FFD1   SBC #$01          <——– moltiplicatore; sposta a sinistra di tot. pixel
FFD3   STA $3A
FFD5   LDA $3B
FFD7   SBC #$00
FFD9   STA $3B
FFDB   BPL $FFE3
FFDD   LDA #$00
FFDF   STA $3B
FFE1   STA $3A

Recupera valori originali del mapping:
FFE3   PLA
FFE4   STA $FE8D
FFE7   PLA
FFE8   STA $DC01
FFEB   PLA
FFEC   STA $DC03
FFEF   PLA
FFF0   STA $01
FFF2   RTS

Bytes per salvare i calcoli:
FFF3   BRK
FFF4   BRK
FFF5   BRK
FFF6   BRK

per chi vuole provare il driver:

per scaricare il driver fare salva con nome del file linkato:

https://mamedev.emulab.it/robiza/wp-content/uploads/2017/05/amiga-7f-x3.jpg

una volta fatto il download cambiare l’estensione del file da .jpg in .cvt

Aggiungi commento

You must be Loggati per scrivere un commento.