;---------------------------------------------------------------
; ДРАЙВЕР ДИСКОВОЙ СИСТЕМЫ
; ВХОД :
; 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