;
; Routines de gestion du FDC en Hardware
;
; OffseT of Futurs'
;

    Org &8000
    Nolist

Init    di
    ex af,af'
    push af

    call moton

    ld a,1
    call sellect
    ld a,0
    call seltete        

    call piste0

;   ld e,82
;   call goto

;   ld hl,sectb
;   ld ix,typpist
;   ld e,0
;   call fmtpist

    ld hl,secta
    ld iy,sectb
    ld ix,typpist
    ld e,0
    ld d,2
    call fmtfull

    ld de,&8000
    ld ix,typpist
    ld iy,&c000
    ld hl,&111a
    call sectr

    call motoff

Restore pop af
        ex af,af'
        ei
        ret

;
; Utilitaires FDC en trackdisk
;

;
; Lecture de secteurs en double densit{
; avec gestion des erreurs
;
; In    ; E=Piste
;     D=Mode multitrack (0=Off / 128=On)
;     IX pointe sur les param}tres secteurs
;     (Taille,Nombre par piste,octet GAP#3,octet de remplissage)
;     H=Premier secteur @ lire
;     L=Dernier secteur @ lire
;     IY=Adresse du tampon
; Out   ; FlagErr=Statut des erreurs
;       ; IY=Fin du tampon

SectR   call litsecs
        call testerr
        ld (flagerr),a
        ret


;
; Ecriture de secteurs en double densit{
;
; In    ; E=Piste
;     D=Mode multitrack (0=Off / 128=On)
;     IX pointe sur les param}tres secteurs
;     (Taille,Nombre par piste,octet GAP#3,octet de remplissage)
;     H=Premier secteur @ lire
;     L=Dernier secteur @ lire
;     IY=Adresse du tampon
; Out   ; FlagErr=Statut des erreurs
;       ; IY=Fin du tampon

SectW   call ecrsecs
        call testerr
        ld (flagerr),a
        ret


;
; Lecture de secteurs en double densit{
;
; In    ; E=Piste
;     D=Mode multitrack (0=Off / 128=On)
;     IX pointe sur les param}tres secteurs
;     (Taille,Nombre par piste,octet GAP#3,octet de remplissage)
;     H=Premier secteur @ lire
;     L=Dernier secteur @ lire
;     IY=Adresse du tampon
; Out   ; E=ST0
;     D=ST1
;     L=ST2
;     H=Piste courante
; Modif ; AF, AF', BC=&FA7E, IY=fin du tampon

LitSecS push de
        call goto
    pop de
    ld a,%01100110  ; Ordre de lecture en DD
    or d        ; Bit multitrack
    call putfdc
    ld a,(lecteur)
    ld d,a
    ld a,(tete)
    sla a
    sla a
    or d
    call putfdc ; Lecteur/Tete
    ld a,e
    call putfdc
    ld a,(tete) ; Envoi de l'ID
    call putfdc
    ld a,h
    call putfdc
    ld a,(ix+0)
    call putfdc
    ld a,l
    call putfdc
    ld a,&20
    call putfdc
    xor a
    call putfdc

WaitDAT in a,(c)
    jp p,waitdat
    and 32
    jr z,finlit
    inc c
    in a,(c)
    dec c
    ld (iy),a
    inc iy
    jr waitdat

FinLit  call getfdc
    ld e,a
    call getfdc
    ld d,a
    call getfdc
    ld l,a
    call getfdc
    ld h,a
    call getfdc
    call getfdc
    call getfdc
    ret


;
; Ecriture de secteurs en double densit{
;
; In    ; E=Piste
;     D=Mode multitrack (0=Off / 128=On)
;     IX pointe sur les param}tres secteurs
;     (Taille,Nombre par piste,octet GAP#3,octet de remplissage)
;     H=Premier secteur @ lire
;     L=Dernier secteur @ lire
;     IY=Adresse du tampon
; Out   ; E=ST0
;     D=ST1
;     L=ST2
;     H=Piste courante
; Modif ; AF, AF', BC=&FA7E, IY=fin du tampon

EcrSecS push de
    call goto
    pop de
    ld a,%01000101    ; Ordre d'{crture en DD
    or d         ; Bit multitrack
    call putfdc
    ld a,(lecteur)
    ld d,a
    ld a,(tete)
    sla a
    sla a
    or d
    call putfdc       ; Lecteur/Tete
    ld a,e
    call putfdc
    ld a,(tete)       ; Envoi de l'ID
    call putfdc
    ld a,h
    call putfdc
    ld a,(ix+0)
    call putfdc
    ld a,l
    call putfdc
    ld a,&20
    call putfdc
    xor a
    call putfdc

WaitECR in a,(c)
    jp p,waitecr
    and 32
    jr z,finecr
    ld a,(iy)
    inc iy
    inc c
    out (c),a
    dec c
    jr waitecr

Finecr  call getfdc
    ld e,a
    call getfdc
    ld d,a
    call getfdc
    ld l,a
    call getfdc
    ld h,a
    call getfdc
    call getfdc
    call getfdc
    ret


;
; Formatage homog}ne d'un disc en simple face
;
; In    ; HL pointe sur la liste des noms des secteurs
;       ; IX pointe sur les param}tres secteurs
;     (Taille,Nombre par piste,octet GAP#3,octet de remplissage)
;     E=Piste de d{part
;     D=Piste d'arriv{e
; Out   ; FlagErr=Statut des erreurs
;     D=Piste courante
;     E=ST0
; Modif ; AF, AF', BC=&FA7E, HL

FmtSide xor a
    ld (flagerr),a
    ld a,d
    cp e
    ret c
    push de
    call piste0
    pop de
LoopSid push de
    push hl
    call fmtpist
    call testerr
    pop hl
    pop de
    cp 1
    jr z,loopsid
    cp 3
    jp putflagerrc
    cp 2
    call z,putflagerri
    ld a,e
    inc e
    cp d
    jr nz,loopsid
    call piste0
    or a
    ret


;
; Formatage homog}ne d'un disc en double face
;
; In    ; HL=Pointe sur la liste des noms des secteurs face A
;       ; IY pointe sur la liste des noms des secteurs face B
;       ; IX pointe sur les param}tres secteurs
;     (Taille,Nombre par piste,octet GAP#3,octet de remplissage)
;     E=Piste de d{part
;     D=Piste d'arriv{e
; Out   ; C=Erreur dans les donn{es
;     D=Piste courante
;     E=ST0
; Modif ; AF, AF', BC=&FA7E, HL

FmtFull xor a
    ld (flagerr),a
    ld a,(tete)
    push af
    ld a,d
    cp e
    ret c
    push de
    call piste0
    pop de
LoopFul push de
    push hl
    xor a
    call seltete
    push de
    push hl
    call fmtpist
    call testerr
    pop hl
    pop de
    pop hl
    pop de
    cp 1
    jr z,loopful
    cp 3
    jp z,putflagerrc
    cp 2
    call z,putflagerri
LoopFu2 push de
    push hl
    ld a,1
    call seltete
    push iy
    pop hl
    call fmtpist
    call testerr
    pop hl
    pop de
    cp 1
    jr z,loopfu2
    cp 3
    jp z,putflagerrc
    cp 2
    call z,putflagerri
    ld a,e
    inc e
    cp d
    jr nz,loopful
    call piste0
    pop af
    ld (tete),a
    or a
    ret


;
; Formatage d'une piste homog}ne
; In    ; HL=Pointe sur la liste des noms des secteurs
;    ; IX pointe sur les param}tres secteurs
;     (Taille,Nombre par piste,octet GAP#3,octet de remplissage)
;     E=piste
; Out   ; E=ST0
;     D=ST1
;     L=ST2
; Modif ; AF, AF', BC=&FA7E, H

FmtPist call goto
    ld e,d
    ld a,%01001101
    call putfdc ; Ordre de formatage
    ld a,(lecteur)
    ld d,a
    ld a,(tete)
    sla a
    sla a
    or d
    call putfdc ; Lecteur & Tete
    ld a,(ix+0)
    call putfdc ; Taille des secteurs
    ld a,(ix+1)
    call putfdc ; Nombre de secteurs
    ld a,(ix+2)
    call putfdc ; Octet GAP#3
    ld a,(ix+3)
    call putfdc ; Octet remplissage

    ld d,(ix+1) ; Envoi des 4 octets
LoopFmt ld a,e      ; d'ID pour chaque secteur
    call putfdc
    ld a,(tete)
    call putfdc
    ld a,(hl)
    call putfdc
    inc hl
    ld a,(ix+0)
    call putfdc
    dec d
    jr nz,loopfmt

    call getfdc
    ld e,a
    call getfdc
    ld d,a
    call getfdc
    ld l,a
    ld h,4
LoopFm2 call getfdc
    dec h
    jr nz,loopfm2

    ret

;
; Routines {l{mentaires FDC
;

;
; Choix du lecteur courant
; In    ; A=num{ro de lecteur
; Modif ; AF

SelLect and 3
    ld (lecteur),a
    ret

;
; Choix de la tete courante
; In    ; A=num{ro de tete
; Modif ; AF

SelTete and 1
    ld (tete),a
    ret

;
; Allumage des moteurs
; Modif ; AF, BC=&FA7E

MotOn   ld a,(moteurs)  ; Etat des moteurs
    or a        ; Retour direct
    ret nz      ; si d{j@ allum{s
    ld bc,&fa7e ; Sinon mise @
    inc a       ; jour de l'{tat
    ld (moteurs),a  ; des moteurs et 
    out (c),a   ; allumage
    ld bc,&f520 ; Attente de
Tempo   in a,(c)    ; quelques VBL
    rra     ; pour etre sur
    jr nc,tempo ; d'atteindre
Wait    in a,(c)
    rra
    jr c,wait
    dec c       ; la vitesse
    jr nz,tempo ; de croisi}re
    ret     ; Fini !

;
; Arret des moteurs
; Modif ; AF, BC=&FA7E

MotOff  xor a       ; Mise @ z{ro de
    ld bc,&fa7e ; l'{tat des moteurs
    ld (moteurs),a  ; et arret des
    out (c),a   ; moteurs
    ret     ; Fini !

;
; Recalibrage du lecteur courant
; Out   ; D=piste courante
;   E=ST0
; Modif ; AF, AF', BC=&FB7E

Piste0  ld bc,&fb7e
Twice   ld a,%00000111  ; Ordre de recalibrage
    call putfdc ; Envoi au FDC
    ld a,(lecteur)  ; pour le lecteur
    call putfdc ; courant
    call waitins
    ld a,d
    or a        ; calibrage
    jr nz,twice ; Sinon
    ret     ; Fini !

;
; Positonnement sur une piste
; In    ; E=piste o| aller
; Out   ; D=piste courante
;     E=ST0
; Modif ; AF, AF', BC=&FB7E

GoTo    ld bc,&fb7e
    ld a,%00001111
    call putfdc
    ld a,(lecteur)
    ld d,a
    ld a,(tete)
    sla a
    sla a
    or d
    call putfdc
    ld a,e
    call putfdc
    jp waitins

;
; Attente de fin d'instruction
; In    ; BC=&FB7E
; Out   ; D=piste courante
;     E=ST0
; Modif ; AF, AF'

WaitIns ld a,%00001000
    call putfdc
    call getfdc
    ld e,a
    call getfdc
    ld d,a
    ld a,e
    and %00100000
    jr z,waitins
    ret

;
; Lecture du registre ST3
; In    ; BC=&FB7E
; Out   ; A=ST3
; Modif ; F, AF', E

ReadST3 ld a,%00000100
    call putfdc
    ld a,(lecteur)
    ld e,a
    ld a,(tete)
    sla a
    sla a
    or e
    call putfdc
    jp getfdc


; Envoi d'une valeur sur le port de donn{es
; In    ; BC=&FB7E
;   A=valeur a envoyer
; Modif ; F, AF'

PutFDC  ex af,af'
LoopPut in a,(c)
    jp p,loopput
    ex af,af'
    inc c
    out (c),a
    dec c
    ret

;
; R{ception d'une valeur sur le port de donn{es
; In    ; BC=&FB7E
; Out   ; A=valeur lue
; Modif ; F, AF'

GetFDC  ex af,af'
LoopGet in a,(c)
    jp p,loopget
    ex af,af'
    inc c
    in a,(c)
    dec c
    ret

;
; Gestion des erreurs disque
; In    ; E=ST0
;   D=ST1
;   L=ST2
; Out   ; A=Statut des erreurs
;         0 ; Pas d'erreur
;         1 ; Erreur signal{e et Retry demand{
;         2 ; Erreur signal{e et Ignore demand{
;         3 ; Erreur signal{e et Cancel demand{

TestErr ld a,e
    bit 3,a
    jr nz,discmis
    and 254
    bit 7,a
    jr nz,unknow
    ld a,d
    and 127
    jr z,ok
    cp 1
    jr z,unform
    cp 2
    jr z,discpro
    cp 4
    jr z,secmis
    jr unknow
Ok  ld a,l
    or a
    jr nz,discerr
    xor a
    ret

DiscMis ld hl,discmistext
    call putscr
    jr retcan
Unknow  ld hl,unknowtext
    call putscr
    jr ignretcan
Unform  ld hl,unformtext
    call putscr
    jr ignretcan
DiscPro ld hl,discprotext
    call putscr
    jr retcan
SecMis  ld hl,secmistext
    call putscr
    jp ignretcan
DiscErr ld hl,discerrtext
    call putscr
    jp ignretcan

PutSCR  ld a,(hl)
    or a
    ret z
    call &bb5a
    inc hl
    jr putscr

RetCan  ld hl,retcantext
    call putscr
    call &bb00
LoopRetCan
    xor a
    call &bb06
    cp "r"
    jr z,retry
    cp "a"
    jr z,cancel
    jr loopretcan

IgnRetCan
    ld hl,ignretcantext
    call putscr
    call &bb00
LoopIgnRetCan
    xor a
    call &bb06
    cp "r"
    jr z,retry
    cp "i"
    jr z,ignore
    cp "a"
    jp z,cancel
    jr loopignretcan

Retry   call &bb5a
    ld a,1
    ret

Ignore  call &bb5a
    ld a,2
    ret

Cancel  call &bb5a
    ld a,3
    ret

;

PutFlagErrI
    ld a,2
    ld (flagerr),a
    ret

PutFlagErrC
    ld a,3
    ld (flagerr),a
    ret


; Data programme
;

Moteurs db 0
Lecteur db 0
Tete    db 0
FlagErr db 0

DiscMisText db 13,10,"Disque manquant",13,10,0
UnknowText  db 13,10,"Probl}me inconnu !",13,10,0
UnformText  db 13,10,"Disque non format{",13,10,0
DiscProText db 13,10,"Disque prot{g{ contre l'{criture",13,10,0
SecMisText  db 13,10,"Secteur non trouv{",13,10,0
DiscErrText db 13,10,"Erreur de donn{es",13,10,0
RetCanText  db 13,10,"Recommencer ou Abandonner ? ",0
IgnRetCanText   db 13,10,"Recommencer, Abandonner ou Ignorer ? ",0


;
; Data Test
;

SectA   db &11,&12,&13,&14,&15,&16,&17,&18,&19,&1a
SectB   db &01,&02,&03,&04,&05,&06,&07,&08,&09,&0a
TypPist db 2,10,&20,&e5

;
; Routine de tra\age
;

Debug   pop af
    ex af,af'
    ei
brk
    di
    ex af,af'
    push af
    ret02...
;

    Org &8000
    Nolist

Init    d
