;---------------------------------------------------------------
 
;  ДРАЙВЕР ДИСКОВОЙ СИСТЕМЫ
 
;  ВХОД :
 
;       RQCHAN          - КАНАЛ
 
;       RQCOM           - КОМАНДА
 
;       RQBLN           - ЧИСЛО БЛОКОВ
 
;       RQTRACK         - ДОРОЖКА
 
;       RQBLOCK         - БЛОК
 
;       RQBADR          - АДРЕС БУФЕРА
 
;
 
 
 
;----------------------------------0201 0202 0801(cd7f3a)
 
; ГЛОБАЛЬНЫЕ КОНСТАНТЫ
 
;
 
_REPN   EQU     5       ; ЧИСЛО ПОВТОРОВ ПРИ НЕУДАЧЕ
 
 
 
PDISK: LD      (IX-_RQCHAN),C
 
        LD      HL,RQCHAN+1
 
        INC     DE
 
        LD      BC,8
 
        EX      DE,HL
 
        RST     8
 
        DB      3,0FEH
 
        EI
 
        PUSH    IY
 
        CALL    DISK
 
        POP     IY
 
        RET
 
 
 
PSCHK: EI
 
        LD      (RQCOM),A
 
        LD      (IX-_RQCHAN),C
 
        PUSH    HL
 
        PUSH    DE
 
        PUSH    IY
 
        LD      (RQBADR),DE
 
        CALL    DISK
 
        POP     IY
 
        POP     DE
 
        POP     HL
 
        RET
 
 
 
;
 
; СТАРТОВЫЙ ВХОД
 
;
 
DISK:
 
        LD      A,(RQCHAN)      ;НОМЕР КАНАЛА
 
        LD      HL,CHTBL        ;ТАБЛИЦА КАНАЛОВ
 
        CALL    _IND
 
        PUSH    HL              ;ОПИСАТЕЛЬ
 
        POP     IY
 
 
 
        LD      A,(RQCOM)       ;КОМАНДА
 
        CP      _SETCH
 
        JP      Z,CHSET         ;НАЗНАЧИТЬ КАНАЛ
 
 
 
        LD      A,(IY+DVALID)   ;ПРИЗНАК ДЕЙСТВИТЕЛЬНОСТИ БЛОКА
 
        CP      0FFH            ;БЛОК ДЕЙСТВИТЕЛЕН?
 
 
 
        LD      A,_CHNFND       ;КАНАЛ НЕ ПРИСОЕДИНЕН
 
        RET     NZ
 
 
 
        LD      A,(RQCOM)       ;КОМАНДА
 
        CP      _GETCH          ;КОНТРОЛЬ?
 
        JP      Z,CHCHK         ;ПОЛУЧИТЬ ОПИСАТЕЛЬ
 
 
 
        CP      _RESET          ;СБРОС?
 
        JR      Z,DISK4         ;АДРЕСАЦИЯ НЕДЕЙСТВИТЕЛЬНА
 
 
 
        CP      _RECAL          ;РЕКАЛИБРОВКА?
 
        JR      Z,DISK4         ;АДРЕСАЦИЯ НЕДЕЙСТВИТЕЛЬНА
 
 
 
        DEC     (IX-_RQBLOCK)   ;НОМЕР БЛОКА ПРИВЕДЕН
 
 
 
        LD      DE,(RQTRACK)    ;НОМЕР ДОРОЖКИ
 
        LD      L,(IY+_DTRACK)
 
        LD      H,(IY+_DTRACK+1) ;ЧИСЛО ДОРОЖЕК НА ДИСКЕ
 
        DEC     HL              ;HL - НОМЕР ПОСЛЕДНЕЙ ДОРОЖКИ
 
        XOR     A               ;CLC
 
        SBC     HL,DE
 
        LD      A,_ADRERR       ;ОШИБКА АДРЕСАЦИИ
 
        RET     C
 
                                ;DE - НОМЕР ДОРОЖКИ
 
        LD      A,(IY+_DHEADF)   ;ЧИСЛО ФИКСИРОВАННЫХ ГОЛОВОК
 
        ADD     A,(IY+_DHEADR)   ;ОБЩЕЕ ЧИСЛО ГОЛОВОК
 
        LD      C,A
 
        LD      B,0
 
                                ;DE-НОМЕР ДОРОЖКИ
 
                                ;BC-ЧИСЛО ГОЛОВОК
 
        CALL    DIV             ;DE/BC=DE.HL
 
                                ;DE-НОМЕР ЦИЛИНДРА
 
                                ;HL-НОМЕР ГОЛОВКИ
 
        LD      (IX-_RQHEAD),L  ;НОМЕР ГОЛОВКИ
 
 
 
        LD      L,(IY+_DBEGCYL)  ;НАЧАЛЬНЫЙ ЦИЛИНДР
 
        LD      H,(IY+_DBEGCYL+1)
 
 
 
        ADD     HL,DE
 
        LD      (RQCYL),HL      ;НОМЕР ЦИЛИНДРА
 
 
 
DISK4: LD      A,_REPN
 
        LD      (REP),A         ;СЧЕТЧИК ЧИСЛА ПОВТОРОВ
 
 
 
DISK5:  LD      A,(RQCOM)
 
        PUSH    AF
 
        CALL    DEXEC           ;ИСПОЛНЕНИЕ КОМАНДЫ
 
        LD      E,A
 
        POP     AF
 
        LD      (RQCOM),A
 
        LD      A,E
 
        OR      A
 
        RET     Z               ;A = 00H - УДАЧА
 
        LD      (IX-_BUFT),0FFH ;СБРОС БУФЕРА
 
        AND     80H
 
        LD      A,E
 
        RET     Z               ;ФАТАЛЬНАЯ ОШИБКА
 
        DEC     (IX-_REP)
 
        JR      NZ,DISK5        ;СЛЕДУЮЩАЯ ПОПЫТКА
 
        RET                     ;A-КОД ОШИБКИ
 
 
 
;-----------------------
 
;ДЕЛЕНИЕ DE:C=DE.HL
 
DIV:    LD      HL,0
 
        LD      A,16            ;СЧЕТЧИК ЦИКЛОВ
 
DIV1:
 
        EX      AF,AF'
 
 
 
        ADD     HL,HL           ;СДВИГ HL
 
 
 
        XOR     A               ;A=0
 
        SLA     E               ;СДВИГ DE
 
        RL      D
 
        ADC     A,L
 
        LD      L,A
 
        SBC     HL,BC
 
 
 
        INC     DE
 
        JR      NC,DIV2
 
        ADD     HL,BC           ;ВОССТАНОВЛЕНИЕ ОСТАТКА
 
        DEC     DE
 
DIV2:   EX      AF,AF'
 
        DEC     A               ;СЧЕТЧИК ЦИКЛОВ
 
        JR      NZ,DIV1
 
        RET
 
 
 
;-----------------------
 
;ИСПОЛНЕНИЕ КОМАНДЫ
 
DEXEC: LD      A,(RQCOM)       ;КОМАНДА
 
        LD      H,A
 
        CP      _WRITE+1
 
        LD      A,_COMERR
 
        RET     NC
 
        LD      A,H
 
        LD      HL,CMTBL        ;ТАБЛИЦА КОМАНД
 
        CALL    _IND
 
        JP      (HL)
 
;-----------------------
 
;ТАБЛИЦА КОМАНД
 
CMTBL:  DW      DRES            ;СБРОС
 
        DW      DJMP            ;ПОЗИЦИОНИРОВАНИЕ
 
        DW      DJMP            ;ФОРМАТИРОВАНИЕ
 
        DW      DJMP            ;РЕКАЛИБРОВКА
 
        DW      DRD             ;ЧТЕНИЕ
 
        DW      DWRS            ;ЗАПИСЬ СЕКТОРАМИ
 
        DW      DWR             ;ЗАПИСЬ
 
;-----------------------
 
;ПЕРЕДАЧА УПРАВЛЕНИЯ ДРАЙВЕРУ
 
DJMP:   PUSH    IY
 
        POP     BC
 
        LD      A,(IY+_DTYP)     ;ТИП ДРАЙВЕРА
 
        CP      MAXDRVN+1       ;ДОПУСТИМЫЙ НОМЕР?
 
        JR      C,DJMP1
 
        LD      A,_DTYPER       ;НЕДОПУСТИМЫЙ НОМЕР
 
        RET
 
DJMP1: LD      HL,DCTBL        ;ТАБЛИЦА ДРАЙВЕРОВ
 
        CALL    _IND            ;ТИП ДРАЙВЕРА
 
        LD      A,L
 
        OR      H
 
        LD      A,_DRNFND       ;ДРАЙВЕР ОТСУТСТВУЕТ
 
        RET     Z
 
        LD      A,(RQCOM)       ;КОМАНДА
 
        CALL    _IND
 
        JP      (HL)            ;ПЕРЕХОД К ДРАЙВЕРУ
 
;-----------------------
 
;СБРОС
 
DRES:  LD      (IX-_BUFT),0FFH ;СБРОС БУФЕРА
 
        JR      DJMP
 
;-----------------------
 
;ЧТЕНИЕ
 
DRD:    CALL    FIND            ;ПОИСК БЛОКА В БУФЕРЕ
 
        JR      Z,DRD1          ;БЛОК В БУФЕРЕ
 
        LD      (IX-_RQCOM),_SEEK ;ПОЗИЦИОНИРОВАНИЕ
 
        CALL    DJMP
 
;        OR      A
 
        RET     NZ              ;ОШИБКА ПОЗИЦИОНИРОВАНИЯ
 
        LD      (IX-_RQCOM),_READ ;ЧТЕНИЕ
 
        CALL    DJMP
 
;        OR      A
 
        RET     NZ              ;ОШИБКА ЧТЕНИЯ
 
DRD1:   CALL    BLKRD           ;ЧТЕНИЕ БУФЕРА
 
        JR      NZ,DRD          ;СЛЕДУЮЩИЙ БЛОК
 
        RET
 
;-----------------------
 
;ЗАПИСЬ
 
DWR:   LD      (IX-_RQCOM),_SEEK ;ПОЗИЦИОНИРОВАНИЕ
 
        CALL    DJMP
 
;        OR      A
 
        RET     NZ              ;ОШИБКА ПОЗИЦИОНИРОВАНИЯ
 
DWR1:   CALL    FIND            ;ПОИСК БЛОКА В БУФЕРЕ
 
        JR      Z,DWR2          ;БЛОК В БУФЕРЕ
 
        LD      (IX-_RQCOM),_READ ;ЧТЕНИЕ
 
        CALL    DJMP
 
;        OR      A
 
        RET     NZ              ;ОШИБКА ЧТЕНИЯ
 
DWR2:   CALL    BLKWR           ;ЗАПИСЬ В БУФЕР
 
        LD      (IX-_RQCOM),_WRITE ;ЗАПИСЬ
 
        CALL    DJMP
 
        POP     HL              ;АДРЕС В БУФЕРЕ
 
;        OR      A
 
        RET     NZ              ;ОШИБКА ЗАПИСИ
 
        CALL    BLKF
 
        JR      NZ,DWR1         ;СЛЕДУЮЩИЙ БЛОК
 
        RET
 
;-----------------------
 
;ЗАПИСЬ СЕКТОРАМИ
 
DWRS:   LD      A,_COMERR       ;ЗАПРЕЩЕННАЯ КОМАНДА
 
        OR      A
 
        RET
 
;-----------------------
 
;ПОИСК БЛОКА В БУФЕРЕ
 
;ВХОД:(BC)-БЛОК ОПИСАНИЯ КАНАЛА
 
;ВЫХОД: А - РЕЗУЛЬТАТ ПОИСКА
 
;         0 - БЛОК НАЙДЕН
 
;       0FFH- БЛОК НЕ НАЙДЕН
 
;
 
FIND:  PUSH    BC
 
        LD      B,(IY+_DFN)      ;РАЗМЕР СЕКТОРА
 
        LD      C,0FFH
 
        LD      A,(RQBLOCK)     ;ПРИВЕДЕННЫЙ НОМЕР БЛОКА
 
        INC     B
 
        JR      FIND2           ;СЕКТОР=128 БАЙТ?
 
FIND1: SRL     A               ;ВЫЧИСЛЕНИЕ ПРИВЕДЕННОГО НОМЕРА СЕКТОРА
 
        SLA     C               ;CALACULATE ~MASK
 
FIND2:  DJNZ    FIND1
 
        LD      (RQSECT),A      ;ПРИВЕДЕННЫЙ НОМЕР СЕКТОРА
 
        LD      A,(RQBLOCK)
 
        OR      C
 
        XOR     C               ;RQBLOCK & MASK => A
 
        LD      C,0
 
        SRL     A
 
        RR      C
 
        LD      B,A
 
        LD      HL,BUF_MON
 
        LD      (DCBUF),HL      ;АДРЕС БУФЕРА
 
        ADD     HL,BC
 
        LD      (LOCBUF),HL     ;АДРЕС БЛОКА В БУФЕРЕ
 
;
 
        LD      A,(RQCHAN)      ;НОМЕР КАНАЛА БУФЕРА
 
        CP      (IX-_BUFT)      ;НОМЕРА КАНАЛОВ СОВПАДАЮТ?
 
        JR      NZ,FIND3        ;НЕТ
 
 
 
        LD      HL,(RQTRACK)    ;ДОРОЖКА В ЗАПРОСЕ
 
        LD      BC,(BUFTRK)     ;ДОРОЖКА В БУФЕРЕ
 
        SBC     HL,BC           ;(CY=0)
 
        JR      NZ,FIND3        ;НОМЕРА ДОРОЖЕК НЕ СОВПАДАЮТ
 
 
 
        LD      A,(RQSECT)      ;НОМЕР СЕКТОРА В ЗАПРОСЕ
 
        CP      (IX-_BUFSEC)    ;ЕСТЬ СОВПАДЕНИЕ?
 
        JR      NZ,FIND3        ;НЕТ
 
        XOR     A               ;ПРИЗНАК СОВПАДЕНИЯ
 
        JR      FIND4
 
FIND3:
 
        LD      A,(RQCHAN)      ;НОМЕР КАНАЛА
 
        LD      (BUFT),A        ;СОСТОЯНИЕ БУФЕРА
 
 
 
        LD      HL,(RQTRACK)    ;ДОРОЖКА(LB)
 
        LD      (BUFTRK),HL
 
 
 
        LD      A,(RQSECT)      ;
 
        LD      (BUFSEC),A      ;СЕКТОР
 
        LD      A,0FFH
 
        AND     A               ;ФЛАГ НОВОГО СЕКТОРА
 
FIND4: POP     BC
 
        RET
 
 
 
;-----------------------
 
;ЧТЕНИЕ БЛОКА В БУФЕРЕ
 
BLKRD:  PUSH    AF
 
        PUSH    DE
 
        LD      BC,128          ;РАЗМЕР БЛОКА
 
        LD      DE,(RQBADR)     ;ПРИЕМНИК
 
        LD      HL,(LOCBUF)     ;ИСТОЧНИК
 
        RST     8               ;ПЕРЕСЫЛКА
 
        DB      0FEH,3
 
        EX      DE,HL           ;АДРЕС ПОЛЬЗОВАТЕЛЯ
 
        POP     DE
 
        POP     AF
 
BLKF:   LD      (RQBADR),HL     ;АДРЕС ПОЛЬЗОВАТЕЛЯ
 
        LD      L,_REPN
 
        LD      (IX-_REP),L     ;ОБНОВИТЬ СЧЕТЧИК ПОВТОРОВ
 
        INC     (IX-_RQBLOCK)
 
        DEC     (IX-_RQBLN)     ;БЛОК ПОСЛЕДНИЙ?
 
        RET
 
;-----------------------
 
;ЗАПИСЬ БЛОКА В БУФЕР
 
BLKWR:  PUSH    DE
 
        LD      BC,128          ;РАЗМЕР БЛОКА
 
        LD      DE,(LOCBUF)     ;ПРИЕМНИК
 
        LD      HL,(RQBADR)     ;ИСТОЧНИК
 
        RST     8               ;ПЕРЕСЫЛКА
 
        DB      3,0FEH
 
        POP     DE
 
        EX      (SP),HL         ;АДРЕС ПОЛЬЗОВАТЕЛЯ
 
        JP      (HL)
 
;-----------------------
 
;НАЗНАЧЕНИЕ КАНАЛА
 
CHSET: LD      (IY),0FFH       ;ПРИЗНАК РЕАЛЬНОСТИ
 
        PUSH    IY
 
        POP     DE
 
        INC     DE
 
        LD      HL,(RQBADR)
 
        LD      BC,22H
 
        RST     8
 
        DB      3,0FEH
 
        EI
 
        LD      (IX-_RQCOM),_RESET ;СБРОС КАНАЛА
 
        CALL    DISK
 
        LD      (IX-_RQCOM),_RECAL ;РЕКАЛИБРОВКА
 
        JP      DISK
 
;-----------------------
 
;ПОЛУЧИТЬ БЛОК ОПИСАНИЯ КАНАЛА
 
CHCHK: PUSH    IY
 
        POP     HL
 
        INC     HL
 
        LD      DE,(RQBADR)
 
        LD      BC,22H
 
        RST     8
 
        DB      0FEH,3
 
        EI
 
        XOR     A               ;УСПЕХ
 
        RET
 
;-----------------------
 
; ИНДЕКСИРОВАНИЕ
 
_IND:   CALL    ADD_HL_2A
 
        LD      E,(HL)
 
        INC     HL
 
        LD      D,(HL)
 
        EX      DE,HL
 
        RET