;LAST UPDATE: 21.11.2013 savelij
 
 
 
DG      MACRO   PAR
 
        CALL    PRN
 
        DB      PAR,0DH,0AH,0
 
        ENDM
 
 
 
 
 
; ДРАЙВЕР 1818ВГ93
 
 
 
FDC_DRV         DW      FD_RES
 
                DW      FD_SEEK
 
                DW      FD_FRM
 
                DW      FD_REC
 
                DW      FD_RD
 
                DW      FD_NOP
 
                DW      FD_WR
 
 
 
;-----------------------
 
; АДРЕСАЦИЯ К ПЕРЕМЕННЫМ FD
 
FD_TVL: LD      HL,FD_TRKS
 
        LD      A,(IY+_DUS)
 
        JP      ADD_HL_A
 
 
 
;-----------------------
 
; АДРЕСАЦИЯ КОНТРОЛЕРА
 
FD_ADR: LD      (SV_SP),SP
 
FD_ADR1:
 
;       CALL    RET_ROM
 
        LD      C,(IY+_DUS)
 
        XOR     A
 
        SUB     (IX-_RQHEAD)
 
        CPL
 
        AND     10H
 
        OR      C
 
        LD      C,(IY+_DFMFM)
 
        XOR     C
 
        AND     0BFH
 
        XOR     C
 
        OR      0CH
 
        OUT     (0FFH),A
 
        CALL    FDREC1
 
        CALL    FD_TVL
 
        LD      A,(HL)
 
        INC     A
 
        JR      NZ,FD_SIT
 
        CALL    FR_SK1
 
        JP      NZ,ERR_PAS
 
        LD      A,1
 
FD_SIT: DEC     A
 
        OUT     (3FH),A
 
FD_NOP: XOR     A
 
        RET
 
 
 
;-----------------------
 
; СБРОС КОНТРОЛЕРА
 
FD_RES: 
 
;       CALL    TST_RT
 
        DI
 
;        CALL    RET_ROM
 
        LD      A,8
 
        OUT     (0FFH),A
 
;       LD      C,0
 
;$1:    
 
        LD      B,0
 
        DJNZ    $
 
;       DEC     C
 
;       JR      NZ,$1
 
        LD      A,0CH
 
        OUT     (0FFH),A
 
        LD      A,0D0H
 
        OUT     (1FH),A
 
        CALL    FD_PAS
 
RET_OK: XOR     A
 
        EI
 
                RET
 
;        JP      RET_RAM
 
 
 
;.COMMENT @
 
;-----------------------
 
; DELAY
 
;DELAY:  LD      B,50H
 
;DELAY1: PUSH    AF
 
;DLP1:   LD      C,-1
 
;DLP2:   DEC     C
 
;        JR      NZ,DLP2
 
;        DEC     B
 
;        JR      NZ,DLP1
 
;        POP     AF
 
;        RET
 
;@
 
 
 
FD_PAS: PUSH    AF
 
        CALL    FD_TVL
 
        LD      (HL),0FFH
 
        POP     AF
 
        RET
 
 
 
 
 
;-----------------------
 
; SEEK
 
FR_SEEK: LD     A,(RQCYL)
 
FR_SK1: LD      C,(IY+_DFSRHUT)
 
        SET     3,C
 
        OR      A
 
        LD      (HL),A
 
        JR      Z,FR_HM
 
        OUT     (7FH),A
 
        SET     4,C             ; SEEK COMMAND
 
        LD      A,(RQCOM)
 
        CP      _FORMAT         ; FORMAT
 
        JR      Z,FRS_D
 
        SET     2,C             ; 'VERIFY TRACK NUM' FLAG
 
        JR      FRS_D
 
FR_HM:  DEC     A
 
        OUT     (3FH),A
 
FRS_D:  LD      A,C
 
FR_SW1: OUT     (1FH),A
 
        JP      FD_WAIT
 
 
 
FD_SEEK:CALL    FD_ADR
 
        LD      A,(RQCYL)
 
        CP      (HL)
 
        JR      Z,RET_OK
 
FD_SKAL:EX      AF,AF'
 
        CALL    FR_SEEK
 
        JR      Z,RET_OK
 
        EX      AF,AF'
 
        OR      A
 
        JR      Z,ERR_PAS
 
        LD      A,0C0H
 
        LD      HL,ED_BUF
 
        LD      BC,87FH
 
        LD      DE,0
 
        DI                      ; READ TRACK NUMBER
 
        OUT     (1FH),A
 
        CALL    FD_RM
 
        EI
 
        IN      A,(1FH)
 
        AND     1CH
 
        JR      NZ,ATT3         ; IF ERROR - SKIP ATEMPT 2
 
        LD      A,(ED_BUF)
 
        OUT     (3FH),A         ; ELSE - SET IT
 
        CALL    FR_SEEK         ; ATEMPT 2
 
        JR      Z,RET_OK        ; O'K
 
ATT3:   XOR     A
 
        CALL    FR_SK1          ; ATEMPT 3. HOME & SEEK
 
        CALL    FR_SEEK
 
        JR      NZ,ERR_PAS
 
        JR      RET_OK
 
 
 
;-----------------------
 
; CALCULATE TIMEOUT VALUE
 
EV_TOUT:LD      A,(SYS_P)
 
        LD      B,4
 
        AND 8
 
        RET     Z
 
        SLA     B
 
        RET
 
 
 
;-----------------------
 
; WAIT FOR READY (WITH TIOME OUT CHECK)
 
FD_WDN: POP     DE              ; END OF WAIT
 
        POP     BC
 
        IN      A,(1FH)
 
        BIT     4,A
 
        RET
 
 
 
FD_WAIT:PUSH    BC              ; WAIT ITSELF
 
        PUSH    DE
 
        CALL    EV_TOUT
 
        LD      DE,0
 
FD_WL:  IN      A,(0FFH)
 
        AND     80H
 
        JR      NZ,FD_WDN
 
        DEC     DE
 
        LD      A,D
 
        OR      E
 
        JR      NZ,FD_WL
 
        DJNZ    FD_WL
 
;---------------------------
 
;   SOME ERRORS
 
; TIME OUT ERROR
 
T_OUT:  LD      A,_NRDY
 
        DB      21H             ; LD HL,...
 
; UNKNOWN ERROR
 
H_ERR:  LD      A,_HRDERR
 
; ANY ERROR
 
ERR_RET:LD      HL,(SV_SP)
 
        INC     HL
 
        INC     HL
 
        LD      SP,HL
 
        LD      H,A
 
;        CALL    RET_ROM
 
        LD      A,0D0H
 
        OUT     (1FH),A
 
        LD      A,H
 
        OR      A
 
                RET
 
;        JP      RET_RAM
 
; ERROR & PASSIVATE
 
ERR_PAS:CALL    FD_PAS
 
        JR      H_ERR
 
 
 
;-----------------------
 
; COMMON PART FOR READ/WRITE PROC'S
 
FD_RW:  LD      (SV_SP),SP
 
        CALL    FD_ADR1
 
        IN      A,(1FH)
 
        AND     20H             ; HEAD LOADED?
 
        JR      NZ,FD_RWL       ; YES - JUMP
 
        LD      A,(HL)          ; CURRENT TRACK
 
        OUT     (7FH),A         ; SEEK IT
 
        LD      A,(IY+_DFSRHUT)
 
        OR      18H             ; SEEK WITH 15MS DELAY COMMAND
 
        CALL    FR_SW1          ; SEEK & WAIT
 
        JR      NZ,ERR_PAS      ; RET IF ERROR
 
FD_RWL: LD      A,(RQSECT)
 
        INC     A
 
        OUT     (5FH),A
 
        CALL    EV_TOUT
 
        XOR     A
 
        SUB     (IX-_RQHEAD)
 
        AND     8
 
        LD      HL,(DCBUF)
 
        LD      C,7FH
 
        LD      DE,0
 
        EXX
 
        RET
 
 
 
;-----------------------
 
; COMMAND 'READ'
 
FD_RM:  IN      A,(0FFH)                ; READ LOOP
 
        AND     0C0H
 
        JP      M,TRY_ERR
 
        JR      NZ,FD_R1
 
        DEC     DE
 
        LD      A,D
 
        OR      E
 
        JR      NZ,FD_RM
 
        DJNZ    FD_RM
 
        JP      T_OUT
 
FD_R:   IN      A,(0FFH)
 
        AND     0C0H
 
        JR      Z,FD_R
 
        RET     M
 
FD_R1:  INI
 
        JR      FD_R
 
 
 
FD_RD:  CALL    FD_RW                   ; 'READ' COMMAND ITSELF
 
        LD      C,1CH
 
        EXX
 
        OR      80H
 
        DI
 
        OUT     (1FH),A
 
        CALL    FD_RM
 
;-----------------------
 
; TEST FOR R/W ERROR
 
RW_ERR_:IN      A,(1FH)
 
        EXX
 
        AND     C
 
RW_ERR1:EI
 
                RET Z
 
;        JP      Z,RET_RAM
 
        LD      C,A
 
ERR_R:  BIT     4,C
 
        JR      NZ,TRY_SK
 
;        CALL    RET_RAM
 
        BIT     3,C
 
        LD      A,_CRC_ERR
 
        RET     NZ
 
        BIT     2,C
 
        LD      A,_OVERRUN
 
        RET     NZ
 
        BIT     5,C
 
        LD      A,_IOERR
 
        RET     NZ
 
        BIT     6,C
 
        LD      A,_WR_PROT
 
        RET     NZ
 
        LD      A,_FATAL_ERROR
 
        OR      A
 
        RET
 
;--- IF 'NO ADDR MARK' ERROR - TRY TO SEEK
 
TRY_SK: CALL    FD_TVL
 
        LD      A,(RQCYL)
 
        CALL    FD_SKAL
 
        LD      A,_NO_DATA
 
        OR      A
 
        RET
 
;--- IF NO ERROR & NO DATA - ERROR TOO
 
TRY_ERR:IN      A,(1FH)
 
        EXX
 
        AND     C
 
        JP      Z,H_ERR
 
        POP     BC
 
        JR      RW_ERR1
 
 
 
;-----------------------
 
; COMMAND 'WRITE'
 
FD_WR:  CALL    FD_RW
 
        LD      C,7CH
 
        EXX
 
        OR      0A0H
 
        DI
 
        OUT     (1FH),A
 
        CALL    FD_WM
 
        JR      RW_ERR_
 
 
 
FD_WM:  IN      A,(0FFH)                ; WRITE LOOP
 
        AND     0C0H
 
        JP      M,TRY_ERR
 
        JR      NZ,FD_W1
 
        DEC     DE
 
        LD      A,D
 
        OR      E
 
        JR      NZ,FD_WM
 
        DJNZ    FD_WM
 
        JP      T_OUT
 
 
 
FD_W:   IN      A,(0FFH)
 
        AND     0C0H
 
        JR      Z,FD_W
 
        RET     M
 
FD_W1:  OUTI
 
        JR      FD_W
 
 
 
;-----------------------
 
; RECALIBRATE SUBROUTINES
 
FD_REC: CALL    FD_ADR
 
        XOR     A
 
        CALL    FR_SK1
 
        JP      NZ,H_ERR
 
        XOR     A
 
                RET
 
;       JP      RET_RAM
 
 
 
FD_SK:  OUT     (7FH),A
 
        LD      B,A
 
        LD      A,C
 
        OR      18H
 
        OUT     (1FH),A
 
        CALL    FD_WAIT
 
        LD      E,A
 
        SCF
 
        RET     NZ
 
        IN      A,(3FH)
 
        CP      B
 
        RET
 
 
 
FDREC1: BIT     7,(IY+_DCYLN)
 
        CALL    NZ,REC_TR
 
        BIT     7,(IY+_DFSRHUT)
 
        CALL    NZ,REC_TM
 
        RET
 
 
 
REC_TR: LD      A,0FH
 
        OUT     (1FH),A
 
        CALL    FD_WAIT
 
        JP      NZ,H_ERR
 
        LD      D,80
 
        LD      C,13H
 
        LD      A,79
 
        CALL    FD_SK
 
        JP      C,ERR_PAS
 
        JR      NZ,TR40
 
        LD      A,1
 
        CALL    FD_SK
 
        JP      C,ERR_PAS
 
        JR      Z,TR80
 
TR40:   LD      D,40
 
TR80:   BIT     1,(IY+_DHEADR)
 
        LD      (IY+_DCYLN),D
 
        LD      A,D
 
        JR      Z,$+3
 
        ADD     A,A
 
        LD      (IY+_DTRACK),A
 
        RET
 
 
 
REC_TM: LD      C,0FFH
 
FD_SLOW: INC    C
 
        BIT     2,C
 
        JP      NZ,H_ERR
 
        LD      A,C
 
        OR      8
 
        OUT     (1FH),A         ; HOME
 
        CALL    FD_WAIT
 
        JR      NZ,FD_SLOW
 
        LD      A,20
 
        CALL    FD_SK           ; SEEK 20 TRACK
 
        JR      NZ,FD_SLOW
 
        LD      A,1
 
        CALL    FD_SK           ; SEEK 1 TRACK
 
        JR      NZ,FD_SLOW
 
        BIT     2,E
 
        JR      NZ,FD_SLOW
 
        LD      A,C
 
        OR      38H
 
        OUT     (1FH),A         ; STEP -1
 
        CALL    FD_WAIT
 
        JR      NZ,FD_SLOW
 
        BIT     2,A             ; IS 0 TRACK ?
 
        JP      Z,FD_SLOW       ; IF NOT - SLOW
 
        LD      (IY+_DFSRHUT),C
 
        RET
 
 
 
;-------------------------------------
 
; FORMAT
 
OUT_R1: LD      A,C
 
        JR      OUT_R
 
OUT_1:  LD      B,1
 
OUT_R:  EX      AF,AF'
 
_O_W:   IN      A,(0FFH)
 
        AND     0C0H
 
        JR      Z,_O_W
 
        RET     M
 
        EX      AF,AF'
 
        OUT     (7FH),A
 
        DJNZ    OUT_R
 
        RET
 
 
 
_FRM_TR: LD      A,(IY+_DFN)     ; SECTOR SIZE
 
        LD      C,A             ; C - COUNTER
 
        OR      A               ; CONVERT (0,1,2,3) -> (1,1,2,4)
 
        JP      PO,$+4
 
        INC     C
 
        LD      B,0             ; B - SIZE OF FIRST BLOCK FORMAT
 
        SUB     1               ;     FILLER  (0,1,2,3) -> (128,256,256,256)
 
        RR      B
 
        PUSH    BC              ; SAVE FOR LATE USE
 
        LD      DE,ED_BUF       ; INTERLIVE TABLE
 
        LD      A,0F4H
 
        DI
 
        OUT     (1FH),A
 
        LD      A,04EH
 
        LD      B,(IY+_DFGPF)    ; GAP3 X 4E
 
        CALL    OUT_R
 
        LD      BC,0C00H
 
        CALL    OUT_R1
 
        LD      BC,3F6H
 
        CALL    OUT_R1
 
        LD      A,0FCH
 
        CALL    OUT_1
 
FR_LP:  LD      BC,324EH
 
        CALL    OUT_R1
 
        LD      BC,0C00H
 
        CALL    OUT_R1
 
        LD      BC,3F5H
 
        CALL    OUT_R1
 
        LD      A,0FEH
 
        CALL    OUT_1
 
        LD      A,(RQCYL)       ; TRACK
 
        CALL    OUT_1
 
        LD      A,(RQHEAD)      ; SIDE
 
        CALL    OUT_1
 
        LD      A,(DE)          ; SECTOR
 
        INC     DE
 
        CALL    OUT_1
 
        LD      A,(IY+_DFN)      ; SECTOR SIZE
 
        CALL    OUT_1
 
        LD      A,0F7H
 
        CALL    OUT_1
 
        LD      BC,164EH
 
        CALL    OUT_R1
 
        LD      BC,0C00H
 
        CALL    OUT_R1
 
        LD      BC,3F5H
 
        CALL    OUT_R1
 
        LD      A,0FBH
 
        CALL    OUT_1
 
        LD      A,(RQBLN)
 
        POP     BC
 
        PUSH    BC
 
FR_L1:  CALL    OUT_R
 
        DEC     C
 
        JR      NZ,FR_L1
 
        LD      A,0F7H
 
        CALL    OUT_1
 
        POP     HL
 
        RET     M
 
        PUSH    HL
 
        LD      A,(DE)
 
        OR      A
 
        JR      NZ,FR_LP
 
        POP     HL
 
        LD      C,5
 
FR_L2:  DEC     C
 
        RET     M
 
        LD      A,4EH
 
        CALL    OUT_R
 
        JP      P,FR_L2
 
        XOR     A
 
        RET
 
 
 
FD_FRM          LD A,(SYS_P)
 
                LD (TMP_W),A
 
                RES 3,(IX-_SYS_P)
 
                CALL SET_SYS
 
        CALL    FD_ADR
 
        CALL    FR_SEEK
 
        LD      A,_HRDERR
 
        RET     NZ
 
        LD      A,(RQBADR)
 
        CALL    FR_FIL
 
        LD      B,8
 
        DI
 
FRM_1:  PUSH    BC
 
        CALL    _FRM_TR
 
        POP     BC
 
        IN      A,(1FH)
 
        LD      C,A
 
        JP      P,FR_OK
 
        BIT     0,C
 
        JR      Z,F_SH1
 
        LD      A,0D0H
 
        OUT     (1FH),A
 
F_SH1:  BIT     6,C
 
        JP      NZ,ERR_R
 
WER_FL: DJNZ    FRM_1
 
        JP      ERR_R
 
FR_OK:  LD      DE,ED_BUF+1
 
WER_LP: LD      A,(DE)
 
        OR      A
 
        JR      NZ,$+3
 
        INC     A
 
        OUT     (5FH),A
 
        LD      A,80H
 
        OUT     (1FH),A
 
WER_WT: IN      A,(0FFH)
 
        AND     0C0H
 
        JR      Z,WER_WT
 
        IN      A,(1FH)
 
        AND     18H
 
        LD      C,A
 
        LD      A,0D0H
 
        OUT     (1FH),A
 
        JR      NZ,WER_FL
 
        LD      A,(DE)
 
        INC     DE
 
        OR      A
 
        JR      NZ,WER_LP
 
                LD A,(TMP_W)
 
                LD (SYS_P),A
 
                CALL SET_SYS
 
        JP      RET_OK
 
 
 
FR_FIL: LD      HL,ED_BUF       ; A - INTERLIVE FACTOR
 
        LD      DE,ED_BUF+1
 
        LD      C,(IY+_DSECTT)
 
        LD      B,0
 
        LD      (HL),0
 
        LDIR
 
        LD      HL,ED_BUF
 
        LD      C,A
 
        LD      B,(IY+_DSECTT)
 
        LD      D,1
 
        JR      FF_LP
 
FF_2:   PUSH    BC
 
        LD      C,1
 
        CALL    FF_MOV
 
        POP     BC
 
FF_LP:  LD      A,(HL)
 
        OR      A
 
        JR      NZ,FF_2
 
        LD      (HL),D
 
        INC     D
 
        PUSH    BC
 
        CALL    FF_MOV
 
        POP     BC
 
        DJNZ    FF_LP
 
        RET
 
FF_MOV: PUSH    DE
 
        LD      B,0
 
        ADD     HL,BC
 
        LD      C,(IY+_DSECTT)
 
        EX      DE,HL
 
        LD      HL,ED_BUF
 
        ADD     HL,BC
 
        DEC     HL
 
        SBC     HL,DE
 
        EX      DE,HL
 
        JR      NC,FF_R1
 
        OR      A
 
        SBC     HL,BC
 
FF_R1:  POP     DE
 
        RET
 
 
 
;.COMMENT @
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
 
;_PRN_M: LD      A,(HL)
 
;        OR      A
 
;        INC     HL
 
;        RET     Z
 
;        CALL    CONOUT
 
;        JR      _PRN_M
 
 
 
;PRN:    EX      (SP),HL
 
;        PUSH    AF
 
;        CALL    _PRN_M
 
;        POP     AF
 
;        EX      (SP),HL
 
;        JP      RET_ROM
 
 
 
;PHEX:
 
;        PUSH    AF
 
;        RRCA
 
;        RRCA
 
;        RRCA
 
;        RRCA
 
;       CALL    DHEX
 
;        POP     AF
 
;       CALL    DHEX
 
;        LD      A,":"
 
;        JP      CONOUT
 
 
 
;
 
; TYPE ONE HEX DIGIT
 
;
 
;DHEX:   AND     0FH
 
;        ADD     A,90H
 
;       DAA
 
;        ADC     A,40H
 
;       DAA
 
;        JP      CONOUT