GEOS e mouse Amiga
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 $84B7Gestione del rallentamento del mouse (non utilizzato):
FEA2 RTSMapping 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 $DC03Memorizzazione 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 $FFF6Trafsormazione 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 $FE8DCiclo 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 YCombina 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 $8505Verifica 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 $3ARecupera 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 RTSBytes per salvare i calcoli:
FFF3 BRK
FFF4 BRK
FFF5 BRK
FFF6 BRKper 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.