Ho voluto fare un pò di reversing sulle routines del DOS e del kernal che gestiscono l'I/O sul bus seriale.
Qui di seguito riporto i disassemblati relativi alla trasmissione dei dati dal C64 al drive 1541
KERNAL (trasmissione)
ED62 LDA #$08
ED64 STA $A5
ED66 LDA $DD00
ED69 CMP $DD00
ED6C BNE $ED66 ;legge porta
ED6E ASL
ED6F BCC $EDB0
ED71 ROR $95
ED73 BCS $ED7A
ED75 JSR $EEA0 ;bit 0,alza data_out
ED78 BNE $ED7D
ED7A JSR $EE97 ;bit 1,abbassa data_out
ED7D JSR $EE85 ;abbassa ck_out
ED80 NOP
ED81 NOP
ED82 NOP
ED83 NOP
ED84 LDA $DD00
ED87 AND #$DF ;ok,abbassa data_out
ED89 ORA #$10
ED8B STA $DD00 ;ok,alza clock_out
ED8E DEC $A5 ;invia prossimo bit
ED90 BNE $ED66
...
DOS (ricezione)
EA0B LDA $1800
EA0E EOR #$01
EA10 LSR
EA11 AND #$02
EA13 BNE $EA0B ;attende ck_in basso
EA15 NOP
EA16 NOP
EA17 NOP
EA18 ROR $85 ;ok,salva bit ricevuto
EA1A JSR $EA59
EA1D JSR $E9C0 ;ok,legge porta
EA20 AND #$04
EA22 BEQ $EA1A ;attende ck_in alto
EA24 DEC $98
EA26 BNE $EA0B ;attende prossimo bit
EA28 JSR $E9A5 ;ok,alza data_out
EA2B LDA $85
EA2D RTS
...
Salta all'occhio che i due registri usati per comunicare sul bus sono allocati a $dd00 (per il C64) e a $1800 (per il drive 1541).
Per trasmettere un bit lungo il bus,il C64 alza o abbassa la linea 'data_out' (bit 5 di $dd00) a seconda che si tratti di un bit 0 o 1,e abbassa la linea di ck_out (bit 4 di $dd00) che è evidentemente collegata alla linea di ck_in lato drive (bit 2 di $1800) e viene usata come segnale di sincronizzazione durante la trasmissione.
Da notare:
- poco dopo l'invio il C64 rialza la linea ck_out,altrimenti il 1541 potrebbe vedere la linea abbassata quando il computer non ha ancora letto il bit successivo (con conseguenze facilmente immaginabili);
- per poter interpretare correttamente il bit ricevuto il DOS deve invertirlo:infatti,dal lato C64 a data_out=0 corrisponde un bit 1 e viceversa.
Le routine che regolano la comunicazione in senso inverso seguono una logica analoga;ovviamente stavolta il 1541 è il dispoitivo di output e pertanto userà le linee di uscita del suo registro (ck=bit 3,data= bit 1);viceversa il C64 è il dispositivo ricevente e pertanto userà le linee d'ingresso del suo registro (ck=bit 6,data=bit 7).
DOS (trasmissione)
E958 LDA #$08
E95A STA $98
E95C JSR $E9C0 ;legge porta
E95F AND #$01
E961 BNE $E999
E963 LDX $82
E965 LDA $023E,X
E968 ROR
E969 STA $023E,X
E96C BCS $E973
E96E JSR $E9A5 ;bit 0,alza data_out
E971 BNE $E976
E973 JSR $E99C ;bit 1,abbassa data_out
E976 JSR $E9B7 ;abbassa ck_out
E979 LDA $23
E97B BNE $E980
E97D JSR $FEF3 ;ritardo
E980 JSR $FEFB ;ok,alza ck_out e
;abbassa data_out
E983 DEC $98 ;invia prossimo bit
E985 BNE $E95C
...
KERNAL (ricezione)
EE56 LDA #$08
EE58 STA $A5
EE5A LDA $DD00
EE5D CMP $DD00
EE60 BNE $EE5A
EE62 ASL
EE63 BPL $EE5A ;attende ck_in alto
EE65 ROR $A4 ;ok,salva data_in
EE67 LDA $DD00
EE6A CMP $DD00
EE6D BNE $EE67
EE6F ASL
EE70 BMI $EE67 ;attende ck_in basso
EE72 DEC $A5
EE74 BNE $EE5A ;attende prossimo bit
...
Stavolta i collegamenti sono invertiti;infatti quando il 1541 abbassa la sua linea ck_out,il C64 vede alta la sua linea ck_in.Lo stesso vale per le linee dati:questo è il motivo per cui il C64 non deve invertire il bit ricevuto per poterlo interpretare correttamente.
Un pò di pazienza,timing delle istruzioni e tavole di DOS e kernel alla mano non è impossibile scrivere un diskloader o arrivare a sfruttare il 6502 come secondo mu-p
Ciao