;LAST UPDATE: 12.11.2010 savelij
;НОМЕРА ВЫЗЫВАЕМЫХ ФУНКЦИЙ
Wc_fat EQU 0X00 ;ИНИЦИАЛИЗАЦИЯ ПЕРЕМЕННЫХ
Getfzap EQU 0X01 ;ПОЛУЧЕНИЕ ОПИСАТЕЛЯ ФАЙЛА/ДИРЕКТОРИИ
Ent_dir EQU 0X02 ;ВХОД В ДИРУ/ВЫХОД ИЗ ДИРЫ
Openfil EQU 0X03 ;ОТКРЫТИЕ ФАЙЛА
Readfil EQU 0X04 ;ЧТЕНИЕ ОТКРЫТОГО ФАЙЛА
Getlong EQU 0X05 ;ПОЛУЧЕНИЕ РАСПАКОВАННОГО ДЛИННОГО ИМЕНИ
Positf EQU 0X06 ;РАБОТА С ПОЗИЦИЕЙ ТЕКУЩЕГО ФАЙЛА
Prvlegz EQU 0X07 ;ПОИСК ПРЕДЫДУЩЕЙ "ЛЕГАЛЬНОЙ ЗАПИСИ"
Nxtlegz EQU 0X08 ;ПОИСК СЛЕДУЮЩЕЙ "ЛЕГАЛЬНОЙ ЗАПИСИ"
Find_file EQU 0X09 ;УСТАНОВКА АДРЕС СКЛАДИРОВАНИЯ И СПИСКА РАСШИРЕНИЙ, НАЧАЛО ПОИСКА
Next_find EQU 0X0A ;ПОИСК ФАЙЛОВ ПО РАСШИРЕНИЯМ
Load_file EQU 0X0B ;ПОСЛЕДОВАТЕЛЬНОЕ ЧТЕНИЕ СЕКТОРОВ
Read0sector EQU 0X0C ;ЧТЕНИЕ ПЕРВОГО СЕКТОРА ФАЙЛА
;ПЕРЕМЕННЫЕ FAT
BUF_512 EQU DRV_VAR ;0X200 БУФЕР СЕКТОРА
TDIRCLS EQU BUF_512+0X0200 ;0X400 ТАБЛИЦА КЛАСТЕРОВ DIR
DIR_CEP EQU TDIRCLS+0X0400 ;0X100 ЦЕПОЧКА КЛАСТЕРОВ ПОДДИРЕКТОРИЙ
ERORDRV EQU DIR_CEP+0X0100 ;2 ВОЗВРАТ С ОШИБКОЙ В A
CAL_FAT EQU ERORDRV+2 ;1 КАЛИБР FAT
MANYFAT EQU CAL_FAT+1 ;1 КОЛИЧЕСТВО FAT-ТАБЛИЦ
BYTSSEC EQU MANYFAT+1 ;1 КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ
ROOTCLS EQU BYTSSEC+1 ;4 СЕКТОР НАЧАЛА ROOT ДИРЕКТОРИИ
ROOTZAP EQU ROOTCLS+4 ;2 КОЛ-ВО ЗАПИСЕЙ В ROOT ДИРЕКТОРИИ
SEC_FAT EQU ROOTZAP+2 ;4 КОЛИЧЕСТВО СЕКТОРОВ ОДНОЙ ФАТ
RSVDSEC EQU SEC_FAT+4 ;2 РАЗМЕР РЕЗЕРВНОЙ ОБЛАСТИ
STARTRZ EQU RSVDSEC+2 ;4 НАЧАЛО ДИСКА/РАЗДЕЛА
FRSTDAT EQU STARTRZ+4 ;4 АДРЕС ПЕРВОГО СЕКТОРА ДАННЫХ ОТ BPB
SEC_DSC EQU FRSTDAT+4 ;4 КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ/РАЗДЕЛЕ
CLS_DSC EQU SEC_DSC+4 ;4 КОЛИЧЕСТВО КЛАСТЕРОВ НА ДИСКЕ/РАЗДЕЛЕ
FATSTR EQU CLS_DSC+4 ;4 НАЧАЛО ПЕРВОЙ FAT ТАБЛИЦЫ
FILE_SZ EQU FATSTR+4 ;4 РАЗМЕР ФАЙЛА В БАЙТАХ
KOLWCLS EQU FILE_SZ+4 ;4 КОЛИЧЕСТВО СВОБОДНЫХ КЛАСТЕРОВ
LST0ZAP EQU KOLWCLS+4 ;4 ПЕРВЫЙ СВОБОДНЫЙ КЛАСТЕР
LSTLOAD EQU LST0ZAP+4 ;4 НОМЕР СЕКТОРА ЗАГРУЖЕННОГО В БУФЕР
TEK_DIR EQU LSTLOAD+4 ;4 КЛАСТЕР ТЕКУЩЕЙ DIR
TEK_ZAP EQU TEK_DIR+4 ;2 ТЕКУЩАЯ ЗАПИСЬ В DIR
SAVEZAP EQU TEK_ZAP+2 ;2 СОХРАНЕННАЯ ТЕКУЩАЯ ПОЗИЦИЯ
TEK_LVL EQU SAVEZAP+2 ;1 ТЕКУЩИЙ УРОВЕНЬ КАТАЛОГА
TEK_LEV EQU TEK_LVL+1 ;1 ГЛУБИНА НАХОЖДЕНИЯ В ДИРЕКТОРИЯХ
FREECLS EQU TEK_LEV+1 ;8 СОХРАНЕНЫЕ ПЕРЕМЕННЫЕ ДЛЯ ОТКАТА
KOLFIND EQU FREECLS+8 ;2 КОЛИЧЕСТВО НАЙДЕННЫХ ПО МАСКЕ ФАЙЛОВ
AFILCLS EQU KOLFIND+2 ;4 НОМЕР ПЕРВОГО КЛАСТЕРА ДЛЯ ЗАГРУЗКИ
FB_EXT EQU AFILCLS+4 ;B БУФЕР 8.3 ДЛЯ ПОИСКА ИМЕНИ
SAVE_IY EQU FB_EXT+0X0B ;2 ВНУТРЕНЕЕ СОХРАНЕНИЕ РЕГИСТРОВ ДЛЯ ДАЛЬНЕЙШЕГО ИСПОЛЬЗОВАНИЯ
ADR_MASK_EXT EQU SAVE_IY+2 ;2 АДРЕС РАСШИРЕНИЙ ФАЙЛОВ ДЛЯ ПОИСКА
ADR_SKLAD EQU ADR_MASK_EXT+2 ;2 АДРЕС СКЛАДИРОВАНИЯ НАЙДЕННОГО
MAKS_ADR EQU ADR_SKLAD+2 ;1 СТАРШИЙ БАЙТ МАКСИМАЛЬНОГО АДРЕСА БУФЕРА СКЛАДИРОВАНИЯ
TFILCLS EQU ERORDRV+0X0100 ;? ТАБЛИЦА КЛАСТЕРОВ ФАЙЛА, РАЗМЕР ЗАВИСИТ ОТ РАЗМЕРА КЛАСТЕРА
;ОБЩАЯ ТОЧКА ВХОДА ДЛЯ РАБОТЫ С FAT
EX AF,AF'
EX (SP),HL
LD A,(HL)
INC HL
EX (SP),HL
ADD A,A
PUSH IX
PUSH IY
LD (ERORDRV),SP
PUSH HL
LD HL,EXITDRV
EX (SP),HL
PUSH HL
LD HL,TABLFAT
ADD A,L
LD L,A
LD A,H
ADC A,0
LD H,A
LD A,(HL)
INC HL
LD H,(HL)
LD L,A
EX AF,AF'
EX (SP),HL
RET
ERR_DRV LD SP,(ERORDRV)
EXITDRV POP IY
POP IX
RET
TABLFAT DW WC_FAT ;00 ИНИЦИАЛИЗАЦИЯ FAT
DW GETFZAP ;01 ПОЛУЧЕНИЕ ОПИСАТЕЛЯ ФАЙЛА
DW ENT_DIR ;02 ВХОД/ВЫХОД В ДИР
DW OPENFIL ;03 ОРТКРЫТИЕ ФАЙЛА
DW READFIL ;04 ПРОИЗВОЛЬНОЕ ПОСЕКТОРНОЕ ЧТЕНИЕ ОТКРЫТОГО ФАЙЛА
DW GETLONG ;05 ПОЛУЧЕНИЕ ДЛИННОГО ИМЕНИ
DW POSITF ;06 WORK FOR TEK POSIT
DW PRVLEGZ ;07 PREV LEGAL OPISAT
DW NXTLEGZ ;08 NEXT LEGAL OPISAT
DW FIND_FILE ;09 УСТАНОВКА АДРЕСА СКЛАДИРОВАНИЯ И СПИСКА РАСШИРЕНИЙ ДЛЯ ПОИСКА, НАЧАЛО ПОИСКА
DW NEXT_FIND ;0A ПРОДОЛЖЕНИЕ ПОИСКА ФАЙЛОВ ПО РАСШИРЕНИЮ
DW LD_FILE ;0B ПОСЛЕДОВАТЕЛЬНОЕ ЧТЕНИЕ СЕКТОРОВ ФАЙЛЫ
DW READ0SECTOR ;0C ЧТЕНИЕ ПЕРВОГО СЕКТОРА ФАЙЛА
;ЧТЕНИЕ/ЗАПИСЬ С ФАЙЛ С ТОЧНОСТЬЮ
;ДО СЕКТОРА (512 БАЙТ)
READFIL EXX
LD E,0
EXX
RD_ADD PUSH AF
PUSH HL
EX AF,AF'
LD A,(BYTSSEC)
LD H,A
PUSH DE
CALL BCDE_A
LD C,H
LD HL,TFILCLS
EX DE,HL
ADD HL,HL
ADD HL,HL
ADD HL,DE
EX DE,HL
POP HL
LD A,C
LD B,0
DEC A
AND L
JR Z,ADD2FI3-5
EXX
LD C,A
LD B,0
EXX
LD L,A
LD A,C
SUB L
LD H,A
EX AF,AF'
CP H
JR C,$+3
LD A,H
POP HL
PUSH HL
CALL ADD2FI2+1
LD B,C
LD A,(BYTSSEC)
LD C,A
EX (SP),HL
EXX
LD BC,0
EXX
ADD2FI3 POP HL
POP AF
SUB B
RET Z
LD B,0
CP C
JR Z,ADD2FI2+1
INC B
SUB C
JR NC,$-2
DEC B
ADD A,C
PUSH AF
LD A,B
AND A
JR Z,ADD2FI2
POP AF
ADD2FI1 PUSH AF
PUSH BC
PUSH HL
LD A,C
EX DE,HL
CALL LOADZP
BIT 7,B
JP NZ,ERR_DRV
EX (SP),HL
PUSH HL
PUSH AF
CALL REALSEC
EXX
PUSH BC
EXX
POP HL
ADD HL,DE
EX DE,HL
LD HL,0
ADC HL,BC
LD B,H
LD C,L
POP AF
POP HL
EX AF,AF'
EXX
LD A,E
EXX
AND A
JR Z,ADD2FI5
EX AF,AF'
CALL TO_DRV
DB 5
JR ADD2FI4
ADD2FI5 EX AF,AF'
CALL TO_DRV
DB 3
ADD2FI4 AND A
JP NZ,ERR_DRV
POP DE
POP BC
DJNZ ADD2FI1+1
ADD2FI2 POP AF
INC B
AND A
RET Z
LD C,A
XOR A
JR ADD2FI1
;ОТКРЫТИЕ ФАЙЛА
OPENFIL CALL GETFZAP
LD DE,20
ADD HL,DE
LD C,(HL)
INC HL
LD B,(HL)
LD E,5
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL)
INC HL
PUSH BC
PUSH DE
CALL LOADZP
LD (FILE_SZ),DE
LD (FILE_SZ+2),BC
POP DE
POP BC
LD HL,TFILCLS
OPENFI1 CALL SAVEZP
PUSH HL
CALL RDFATZP
CALL LST_CLS
POP HL
JR NC,OPENFI1
LD B,0XFF
CALL SAVEZP
FILESEC LD DE,(FILE_SZ)
LD BC,(FILE_SZ+2)
CALL HWOSTSC
JP BCDE200
HWOSTSC LD A,D
AND 1
LD H,A
LD A,E
AND A
JR Z,$+3
INC H
LD E,0
LD L,E
BIT 0,H
JR Z,$+3
INC H
RES 0,D
ADD HL,DE
EX DE,HL
LD HL,0
ADC HL,BC
LD B,H
LD C,L
RET
;ЗАГРУЖАЕМ СЕКТОР В БУФЕР
LOADLST CALL CPNUMSC
JR NZ,LOADLS1
LD HL,BUF_512
RET
LOADLS1 LD (LSTLOAD+2),BC
LD (LSTLOAD),DE
LD HL,BUF_512
PUSH HL
CALL TO_DRV
DB 2
AND A
JP NZ,ERR_DRV
POP HL
RET
;ПРОВЕРКА НА УЖЕ ЗАГРУЖЕННЫЙ СЕКТОР
CPNUMSC LD HL,LSTLOAD
LD A,(HL)
INC HL
CP E
RET NZ
LD A,(HL)
INC HL
CP D
RET NZ
LD A,(HL)
INC HL
CP C
RET NZ
LD A,(HL)
CP B
RET
;ВХОЖДЕНИЕ В DIR
ENT_DIR CALL GETFZAP
BIT 4,A
EX AF,AF'
LD A,E
EX AF,AF'
LD E,A
LD D,(HL)
RET Z
EXX
EX AF,AF'
BIT 7,A
JR Z,ENT_DI2
LD HL,TEK_LEV
LD A,(HL)
AND A
EXX
RET Z
EXX
DEC A
LD (HL),A
ADD A,A
LD H,HIGH (DIR_CEP)
LD L,A
LD A,(HL)
INC L
LD H,(HL)
LD L,A
JR ENT_DI1
ENT_DI2 LD HL,TEK_LEV
LD A,(HL)
INC A
CP 0X80
EXX
RET Z
EXX
LD (HL),A
DEC A
ADD A,A
LD H,HIGH (DIR_CEP)
LD L,A
LD BC,(TEK_ZAP)
LD (HL),C
INC L
LD (HL),B
ENT_DI1 EXX
PUSH DE
LD DE,20
ADD HL,DE
LD C,(HL)
INC HL
LD B,(HL)
LD E,5
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL)
LD A,B
OR C
OR D
OR E
JR NZ,ENT_DI0
LD DE,(ROOTCLS)
LD BC,(ROOTCLS+2)
ENT_DI0 LD (TEK_DIR),DE
LD (TEK_DIR+2),BC
CALL INIRTSC
POP DE
RET
;ПОЛУЧИТЬ ОПИСАТЕЛЬ ТЕКУЩЕГО ФАЙЛА
GETFZAP LD BC,(TEK_ZAP) ;ТЕКУЩИЙ НОМЕР ОПИСАТЕЛЯ
LD A,B
OR C
JR Z,GETRZAP ;ЕСЛИ НОМЕР =0, ТО ПРЕДЫДУЩИЙ НОМЕР НЕ ПРОВЕРЯЕМ
PUSH BC ;СОХРАНИЛИ ТЕКУЩИЙ НОМЕР
DEC BC ;НУЖНО ПРОВЕРИТЬ ПРЕДЫДУЩИЙ НОМЕР
CALL GETRZAP ;ПРОВЕРЯЕМ
POP BC ;ВЕРНУЛИ ТЕКУЩИЙ НОМЕР
LD E,A ;ИЗ ПРЕДЫДУЩЕГО ОПИСАТЕЛЯ НУЖЕН ТОЛЬКО ФЛАГОВЫЙ БАЙТ
GETRZAP PUSH DE
CALL RDDIRSC ;ЧИТАЕМ СЕКТОР С ТЕКУЩИМ НОМЕРОМ
POP DE ;ВЕРНУЛИ РЕГИСТР E
INC A
LD A,E ;ВЕРНУЛИ НАЛИЧИЕ/ОТСУСТВИЕ ДЛИННОГО ИМЕНИ
RET Z ;ВЫХОДИМ ЕСЛИ ВЫЛЕТЕЛИ ЗА ПРЕДЕЛЫ СУЩЕСТВУЮЩЕЙ ДИРЫ
EX AF,AF'
GETFZA1 LD A,C
AND 0X0F ;ПОЛУЧИЛИ НОМЕР ОПИСАТЕЛЯ В ЗАГРУЖЕННОМ СЕКТОРЕ ДИРЫ
LD E,A
LD D,0
EX DE,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,DE ;ВЫЧИСЛИЛИ АДРЕС ВЫБРАННОГО ОПИСАТЕЛЯ
LD DE,0X0B
LD A,(HL) ;ВЗЯЛИ ФЛАГОВЫЙ БАЙТ ТЕКУЩЕГО ОПИСАТЕЛЯ
EX DE,HL
ADD HL,DE
LD L,(HL) ;ВЗЯЛИ ПЕРВЫЙ БАЙТ ИМЕНИ
LD H,A ;ПОЛОЖИЛИ ФЛАГОВЫЙ БАЙТ ЭТОГО ОПИСАТЕЛЯ
EX DE,HL
CALL CP_TWOT ;ПРОВЕРКА НА НАЛИЧИЕ В ИМЕНИ ".."
LD D,0 ;БУДЕМ ВХОДИТЬ В ДИРЕКТОРИЮ
JR NZ,GETFZA2
LD D,0X80 ;БУДЕМ ВЫХОДИТЬ В ПРЕДЫДУЩУЮ ДИРЕКТОРИЮ
GETFZA2 EX AF,AF'
CP 0X0F ;ПРОВЕРЯЕМ ФЛАГОВЫЙ БАЙТ ПРЕДЫДУЩЕГО ОПИСАТЕЛЯ
LD A,E ;ВЗЯЛИ ФЛАГОВЫЙ БАЙТ ТЕКУЩЕГО ОПИСАТЕЛЯ
LD E,D ;ВЫСТАВИЛИ НАПРАВЛЕНИЕ ДВИЖЕНИЯ В ДИРАХ
RET NZ
INC E ;УСТАНОВКА НАЛИЧИЯ ДЛИННОГО ИМЕНИ
RET
;ЧТЕНИЕ СЕКТОРА DIR ПО НОМЕРУ BC
;НА ВЫХОДЕ: A=0XFF-ВЫХОД ЗА ПРЕДЕЛЫ DIR
RDDIRSC PUSH BC
LD D,B
LD E,C
LD BC,0
LD A,0X10
CALL BCDE_A
LD A,E
PUSH AF
LD A,(BYTSSEC)
PUSH AF
CALL BCDE_A
LD HL,TDIRCLS
EX DE,HL
ADD HL,HL
ADD HL,HL
ADD HL,DE
CALL LOADZP
BIT 7,B
JR Z,RDDIRS3
POP BC
POP BC
POP BC
XOR A
DEC A
RET
RDDIRS3 CALL REALSEC
POP AF
DEC A
LD L,A
POP AF
AND L
LD L,A
LD H,0
ADD HL,DE
EX DE,HL
LD HL,0
ADC HL,BC
LD B,H
LD C,L
CALL LOADLST
POP BC
XOR A
RET
;ФОРМИРОВАНИЕ ТАБЛИЦЫ КЛАСТЕРОВ DIR
;И ПОИСК ПЕРВОЙ "ЛЕГАЛЬНОЙ" ЗАПИСИ В DIR
INIRTSC PUSH AF
LD HL,TDIRCLS
CALL SAVEZP
LD A,D
OR E
OR B
OR C
JR Z,LASTCLS
NEXTCLS PUSH HL
CALL RDFATZP
CALL LST_CLS
POP HL
JR C,LASTCLS
CALL SAVEZP
JR NEXTCLS
LASTCLS LD BC,0XFFFF
CALL SAVEZP
CALL POSTF02
POP AF
RET
;ПРОВЕРКА НА 1 ТОЧКУ
CP_ONET LD A,(HL)
CP 0X2E
RET NZ
INC HL
LD A,(HL)
DEC HL
CP 0X20
RET NZ
XOR A
RET
;ПРОВЕРКА НА 2 ТОЧКИ
CP_TWOT LD A,(HL)
CP 0X2E
RET NZ
INC HL
LD A,(HL)
DEC HL
CP 0X2E
RET NZ
XOR A
RET
POSITF CP LOW ((ENDTPOS-TPOSITF)/2)
RET NC
ADD A,A
LD DE,TPOSITF
LD L,A
LD H,0
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL)
EX DE,HL
JP (HL)
TPOSITF DW POSTF00
DW POSTF01
DW POSTF02
DW POSTF03
DW POSTF04
DW POSTF05
DW POSTF06
DW POSTF07
ENDTPOS
;СОХРАНЕНИЕ ТЕКУЩЕЙ ПОЗИЦИИ ФАЙЛА
POSTF00 LD HL,(TEK_ZAP)
LD (SAVEZAP),HL
RET
;ВОССТАНОВЛЕНИЕ ТЕКУЩЕЙ ПОЗИЦИИ ФАЙЛА
POSTF01 LD HL,(SAVEZAP)
LD (TEK_ZAP),HL
RET
;ПЕРЕМОТАТЬ НА "B" ФАЙЛОВ НАЗАД
POSTF03 LD A,B
AND A
RET Z
PUSH BC
CALL PRVLEGZ
POP BC
DJNZ $-5
RET
;ПЕРЕМОТАТЬ НА "B" ФАЙЛОВ ВПЕРЕД
POSTF04 LD A,B
AND A
RET Z
PUSH BC
CALL NXTLEGZ
POP BC
DJNZ $-5
RET
;ПОДСЧЕТ КОЛИЧЕСТВА "ЛЕГАЛЬНЫХ" ЗАПИСЕЙ
POSTF05 LD BC,0
PUSH BC
EXX
POP BC
EXX
CALL RDDIRSC
LD DE,0X20
KOL_ZA4 LD A,(HL)
CP 0X2E
JR NZ,KOL_ZA1+2
INC HL
LD A,(HL)
DEC HL
CP 0X2E
JR Z,KOL_ZA1+2
INC BC
ADD HL,DE
JR KOL_ZA4
KOL_ZA1 INC BC
ADD HL,DE
LD A,H
CP HIGH (BUF_512)+2
JR NZ,KOL_ZA2
CALL RDDIRSC
LD D,0
AND A
JR Z,KOL_ZA2
CALL KOL_ZA3
DEC A
RET
KOL_ZA2 LD E,0X0B
ADD HL,DE
LD A,(HL)
AND A
SBC HL,DE
LD E,0X20
CP 0X0F
JR Z,KOL_ZA1
CP 8
JR Z,KOL_ZA1
LD A,(HL)
CP 0XE5
JR Z,KOL_ZA1
AND A
JR Z,KOL_ZA3
EXX
INC BC
EXX
JR KOL_ZA1
KOL_ZA3 LD D,B
LD E,C
EXX
PUSH BC
EXX
POP BC
XOR A
RET
;УСТАНОВИТЬ НОМЕР "ЛЕГАЛЬНОЙ" ЗАПИСИ ИЗ "BC"
POSTF06 LD (TEK_ZAP),BC
RET
;ВЕРНУТЬ В "BC" ТЕКУЩИЙ НОМЕР "ЛЕГАЛЬНОЙ" ЗАПИСИ
POSTF07 LD BC,(TEK_ZAP)
RET
CPTEKZP CALL RDDIRSC
RET M
LD A,C
AND 0X0F
LD L,A
LD H,0
LD DE,BUF_512
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,DE
LD DE,0X0B
ADD HL,DE
LD A,(HL)
SBC HL,DE
LD E,(HL)
AND A
RET
;СБРОС ТЕКУЩЕЙ ПОЗИЦИИ В 0 И ПОИСК ПЕРВОЙ "ЛЕГАЛЬНОЙ" ЗАПИСИ
POSTF02 LD BC,0
LD (TEK_ZAP),BC
CALL RDDIRSC
CALL CP_ONET
JR Z,NXTLEG1
LD A,(HL)
AND A
RET Z
JR NXTLEG1+1
NXTLEGZ LD BC,(TEK_ZAP)
NXTLEG1 INC BC
CALL CPTEKZP
CP 0XFF
RET Z
CP 0X0F
JR Z,NXTLEG1
CP 8
JR Z,NXTLEG1
LD A,E
AND A
RET Z
CP 0XE5
JR Z,NXTLEG1
LD (TEK_ZAP),BC
RET
PRVLEGZ LD BC,(TEK_ZAP)
CALL CPTEKZP
CALL CP_TWOT
RET Z
PRVLEG1 DEC BC
CALL CPTEKZP
CP 0X0F
JR Z,PRVLEG1
CP 8
JR Z,PRVLEG1
LD A,E
CP 0XE5
JR Z,PRVLEG1
LD (TEK_ZAP),BC
RET
SAVEZP LD (HL),E
INC HL
LD (HL),D
INC HL
LD (HL),C
INC HL
LD (HL),B
INC HL
RET
LOADZP LD E,(HL)
INC HL
LD D,(HL)
INC HL
LD C,(HL)
INC HL
LD B,(HL)
INC HL
RET
;ИНИЦИАЛИЗАЦИЯ ПЕРЕМЕННЫХ FAT
WC_FAT LD HL,0XFFFF
LD (LSTLOAD),HL
LD (LSTLOAD+2),HL
CALL COM_DEV
DB 2
LD (CAL_FAT),A
LD E,D
LD D,0
EX DE,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,DE
INC HL
INC HL
INC HL
LD E,(HL)
INC HL
LD D,(HL)
INC HL
LD C,(HL)
INC HL
LD B,(HL)
LD (STARTRZ),DE
LD (STARTRZ+2),BC
CALL LOADLST
PUSH HL
POP IX
LD HL,0
LD E,(IX+0X16)
LD D,(IX+0X17) ;BPB_FATSZ16
LD A,D
OR E
JR NZ,RDFAT01 ;ЕСЛИ НЕ FAT12/16 (BPB_FATSZ16=0)
LD E,(IX+0X24)
LD D,(IX+0X25)
LD L,(IX+0X26)
LD H,(IX+0X27) ;BPB_FATSZ32
;ТО БЕРЕМ ИЗ СМЕЩЕНИЯ +36
RDFAT01 LD (SEC_FAT+2),HL
LD (SEC_FAT),DE ;ЧИСЛО СЕКТОРОВ НА FAT-ТАБЛИЦУ
LD HL,0
LD E,(IX+0X13)
LD D,(IX+0X14) ;BPB_TOTSEC16
LD A,D
OR E
JR NZ,RDFAT02 ;ЕСЛИ НЕ FAT12/16 (BPB_TOTSEC16=0)
LD E,(IX+0X20)
LD D,(IX+0X21)
LD L,(IX+0X22)
LD H,(IX+0X23) ;BPB_TOTSEC32
;ТО БЕРЕМ ИЗ СМЕЩЕНИЯ +32
RDFAT02 LD (SEC_DSC+2),HL
LD (SEC_DSC),DE ;К-ВО СЕКТОРОВ НА ДИСКЕ/РАЗДЕЛЕ
;ВЫЧИСЛЯЕМ ROOTDIRSECTORS
LD E,(IX+0X11)
LD D,(IX+0X12) ;BPB_ROOTENTCNT
LD (ROOTZAP),DE
LD BC,0
LD H,B
LD L,C
LD A,D
OR E
JR Z,RDFAT03
LD A,0X10
CALL BCDE_A
EX DE,HL
;ЭТО РЕАЛИЗОВАНА ФОРМУЛА
;ROOTDIRSECTORS=((BPB_ROOTENTCNT*32)++(BPB_BYTSPERSEC-1))/BPB_BYTSPERSEC
;В HL ROOTDIRSECTORS. ЕСЛИ FAT32, ТО HL=0 ВСЕГДА
RDFAT03 PUSH HL ;ROOTDIRSECTORS
LD A,(IX+0X10) ;BPB_NUMFATS
LD (MANYFAT),A
LD DE,(SEC_FAT)
LD HL,(SEC_FAT+2)
DEC A
JR Z,RDFAT06 ;ЕСЛИ FAT ТАБЛИЦА 1,ТО НЕ УМНОЖАЕМ
RDFAT05 EX DE,HL
ADD HL,HL
EX DE,HL
ADC HL,HL
DEC A
JR NZ,RDFAT05
RDFAT06 POP BC ;ПОЛНЫЙ РАЗМЕР FAT-ОБЛАСТИ В СЕКТОРАХ
CALL HLDEPBC ;ПРИБАВИЛИ ROOTDIRSECTORS
LD C,(IX+0X0E)
LD B,(IX+0X0F) ;BPB_RSVDSECCNT
LD (RSVDSEC),BC
CALL HLDEPBC ;ПРИБАВИЛИ BPB_RESVDSECCNT
LD (FRSTDAT),DE
LD (FRSTDAT+2),HL ;ПОЛОЖИЛИ НОМЕР ПЕРВОГО СЕКТОРА ДАННЫХ
LD B,H
LD C,L
LD HL,SEC_DSC
CALL BCDEHLM ;ВЫЧЛИ ИЗ ПОЛНОГО К-ВА СЕКТОРОВ РАЗДЕЛА
LD A,(IX+0X0D)
LD (BYTSSEC),A ;КОЛИЧЕСТВО СЕКТОРОВ НА КЛАСТЕР
CALL BCDE_A ;РАЗДЕЛИЛИ НА К-ВО СЕКТОРОВ В КЛАСТЕРЕ
LD (CLS_DSC),DE
LD (CLS_DSC+2),BC ;ПОЛОЖИЛИ КОЛ-ВО КЛАСТЕРОВ НА РАЗДЕЛЕ
; LD A,(CAL_FAT)
; CP 0XFF ;ТИП FAT НЕ ОПРЕДЕЛЕН?
; JR NZ,RDFAT04
;ОПРЕДЕЛЕНИЕ ТИПА FAT ПРИ ОТСУСТВИИ MBR
LD HL,(CLS_DSC)
LD DE,(CLS_DSC+2) ;HLDE=КОЛИЧЕСТВО КЛАСТЕРОВ НА РАЗДЕЛЕ
ADD HL,HL
PUSH HL
EX DE,HL
ADC HL,HL ;HLDE=КОЛИЧЕСТВО СЕКТОРОВ *2
PUSH HL
LD B,H
LD C,L ;BCDE=КОЛИЧЕСТВО КЛАСТЕРОВ *2
CALL RASCHET
LD A,1
POP DE
POP HL ;HLDE=КОЛИЧЕСТВО КЛАСТЕРОВ *2
JR Z,RDFAT04
ADD HL,HL
EX DE,HL
ADC HL,HL ;HLDE=КОЛИЧЕСТВО КЛАСТЕРОВ *4
LD B,H
LD C,L ;BCDE=КОЛИЧЕСТВО КЛАСТЕРОВ *4
CALL RASCHET
LD A,2
JR Z,RDFAT04
XOR A
RDFAT04 LD (CAL_FAT),A
;ДЛЯ FAT12/16 ROOT КЛАСТЕР=0
;ДЛЯ FAT32 БЕРЕМ ПО СМЕЩЕМИЮ +44
;НА ВЫХОДЕ BCDE-СЕКТОР ROOTDIR КЛАСТЕР
PUSH AF
AND A
LD DE,0
LD B,D
LD C,E
JR Z,FSRROO2 ;FAT12
DEC A
JR Z,FSRROO2 ;FAT16
LD E,(IX+0X2C)
LD D,(IX+0X2D)
LD C,(IX+0X2E)
LD B,(IX+0X2F) ;FAT32
FSRROO2 LD (ROOTCLS),DE
LD (ROOTCLS+2),BC ;СЕКТОР ROOT ДИРЕКТОРИИ
LD (TEK_DIR),DE
LD (TEK_DIR+2),BC
FSRR121 PUSH DE
PUSH BC
LD DE,(RSVDSEC)
LD BC,0
LD HL,STARTRZ
CALL BCDEHLP
LD (FATSTR),DE
LD (FATSTR+2),BC
XOR A
LD (TEK_LEV),A
POP BC
POP DE
POP AF
JP INIRTSC
;СРАВНЕНИЕ РЕАЛЬНО ЗАНИМАЕМОЕ КЛАСТЕРАМИ МЕСТО И КОИЧЕСТВОМ СЕКТОРОВ ПОД 1 FAT ТАБЛИЦУ
RASCHET CALL BCDE200 ;РАЗДЕЛИЛИ НА 512
LD HL,SEC_FAT
CALL BCDEHLM ;ВЫЧЛИ ИЗ КОЛИЧЕСТВА СЕКТОРОВ НА 1 FAT ТАБЛИЦУ
LD A,E
AND 0XF0 ;МЛАДШИЕ 4 БИТА НЕ ИНТЕРЕСНЫ
OR D
OR C
OR B
RET
;ОТДАЧА КОРОТКОГО ИМЕНИ ФАЙЛА, ЕСЛИ ДЛИННОЕ ОТСУСТВУЕТ
NO_LNG POP DE
LD BC,8
LDIR
LD A,(HL)
CP 0X20
JR Z,NO_LNG1
EX DE,HL
LD (HL),0X2E
INC HL
EX DE,HL
LDI
LDI
LDI
NO_LNG1 EX DE,HL
LD (HL),0
POP HL
RET
;ОТДАЧА ДЛИННОГО ИМЕНИ ФАЙЛА
GETLONG PUSH HL
PUSH HL
CALL GETFZAP
BIT 0,E
JR Z,NO_LNG
EXX
LD C,0
EXX
GETLNG2 DEC BC
CALL GETRZAP
LD A,(HL)
INC HL
EXX
BIT 6,C
POP HL
JR NZ,GETLNGE+1
LD C,A
EXX
LD A,5
CALL GETLNG1
AND A
JR Z,GETLNGE
INC HL
INC HL
INC HL
LD A,6
CALL GETLNG1
AND A
JR Z,GETLNGE
INC HL
INC HL
LD A,2
CALL GETLNG1
AND A
JR Z,GETLNGE
EXX
PUSH HL
EXX
JR GETLNG2
GETLNGE EXX
LD (HL),0
EXX
POP HL
RET
GETLNG1 EXX
LD B,A
EXX
LD D,(HL)
INC HL
LD E,(HL)
INC HL
LD A,D
OR E
RET Z
LD A,E
AND A
JR NZ,GETLNG3
LD A,D
CP 0X80
JR C,GETLNG5
LD D,0X5F
JR GETLNG5
GETLNG3 CP 4
LD A,0X5F
JR NZ,GETLNG5
LD A,D
LD E,0XEF
LD D,0X5F
CP 1
JR Z,GETLNG4
LD E,0XA0
CP 0X51
JR Z,GETLNG4
SUB 0X10
LD E,0X80
JR NC,GETLNG6
LD A,D
JR GETLNG5
GETLNG6 CP 0X30
JR C,GETLNG4
LD E,0XB0
CP 0X40
JR C,GETLNG4
LD A,D
JR GETLNG5
GETLNG4 ADD A,E
GETLNG5 EXX
LD (HL),A
INC HL
DEC B
EXX
RET Z
JR GETLNG1+3
;401,410-44F,451
;ПРОВЕРКА НА ПОСЛЕДНИЙ КЛАСТЕР
LST_CLS LD A,(CAL_FAT) ;ВЗЯЛИ ТИП FAT
AND A
JR NZ,LST_CL1
LD HL,0X0FF7 ;ДЛЯ FAT12
SBC HL,DE
RET
LST_CL1 DEC A
JR NZ,LST_CL2
LD HL,0XFFF7 ;ДЛЯ FAT16
SBC HL,DE
RET
LST_CL2 LD HL,0X0FFF
SBC HL,BC
RET NZ
LD HL,0XFFF7
SBC HL,DE
RET
;ЧТЕНИЕ СЛЕДУЮЩЕГО НОМЕРА КЛАСТЕРА
RDFATZP LD A,(CAL_FAT)
AND A
JR Z,RDFATS0
DEC A
JR Z,RDFATS1
EX DE,HL
ADD HL,HL
EX DE,HL
LD HL,0
ADC HL,BC
ADC HL,BC
LD A,E
LD E,D
LD D,L
LD C,H
LD B,0
CALL RDFATS2
INC HL
LD C,(HL)
INC HL
LD B,(HL)
RET
RDFATS1 LD BC,0
LD A,E
LD E,D
LD D,C
RDFATS2 PUSH AF
PUSH BC
LD HL,FATSTR
CALL BCDEHLP
CALL LOADLST
POP BC
POP AF
LD E,A
LD D,0
ADD HL,DE
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL)
RET
RDFATS0 LD H,D
LD L,E
ADD HL,HL
ADD HL,DE
SRL H
RR L
LD A,E
LD E,H
LD D,0
LD B,D
LD C,D
SRL E
PUSH AF
PUSH HL
LD HL,FATSTR
CALL BCDEHLP
CALL LOADLST
POP BC
LD A,B
AND 1
LD B,A
ADD HL,BC
LD B,(HL)
INC HL
LD A,H
CP HIGH (BUF_512)+2
JR NZ,RDFATS4
PUSH BC
LD BC,0
INC DE
CALL LOADLST
POP BC
RDFATS4 POP AF
LD D,(HL)
LD E,B
LD BC,0
RRA
JR NC,RDFATS3
SRL D
RR E
SRL D
RR E
SRL D
RR E
SRL D
RR E
RDFATS3 LD A,D
AND 0X0F
LD D,A
RET
;ВЫЧИСЛЕНИЕ РЕАЛЬНОГО СЕКТОРА
;НА ВХОДЕ: BCDE=НОМЕР КЛАСТЕРА FAT
;НА ВЫХОДЕ: BCDE=АДРЕС СЕКТОРА
REALSEC LD A,B
OR C
OR D
OR E
JR NZ,REALSE1
LD DE,(FATSTR)
LD BC,(FATSTR+2)
LD HL,SEC_FAT
PUSH HL
CALL BCDEHLP
POP HL
JP BCDEHLP
REALSE1 LD HL,0XFFFE
EX DE,HL
ADD HL,DE
EX DE,HL
INC HL
ADC HL,BC ;НОМЕР КЛАСТЕРА-2
LD A,(BYTSSEC)
JR REALSE2
REALSE3 SLA E
RL D
RL L
RL H
REALSE2 RRCA
JR NC,REALSE3 ;УМНОЖИЛИ НА РАЗМЕР КЛАСТЕРА
LD B,H
LD C,L
LD HL,STARTRZ
CALL BCDEHLP ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА ДИСКА
LD HL,FRSTDAT
JP BCDEHLP ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА РАЗДЕЛА
BCDE200 LD E,D
LD D,C
LD C,B
LD B,0
LD A,2
JR BCDE_A
;BCDE>>A=BCDE
BCDE_A1 SRL B
RR C
RR D
RR E
BCDE_A RRCA
JR NC,BCDE_A1
RET
;(ADR)-BCDE=BCDE
BCDEHLM LD A,(HL)
INC HL
SUB E
LD E,A
LD A,(HL)
INC HL
SBC A,D
LD D,A
LD A,(HL)
INC HL
SBC A,C
LD C,A
LD A,(HL)
SBC A,B
LD B,A
RET
;(ADR)+BCDE=BCDE
BCDEHLP LD A,(HL)
INC HL
ADD A,E
LD E,A
LD A,(HL)
INC HL
ADC A,D
LD D,A
LD A,(HL)
INC HL
ADC A,C
LD C,A
LD A,(HL)
ADC A,B
LD B,A
RET
;HLDE+BC=HLDE
HLDEPBC EX DE,HL
ADD HL,BC
EX DE,HL
LD BC,0
ADC HL,BC
RET
CP_EXT PUSH BC
PUSH DE
PUSH HL
LD C,0
LD DE,(ADR_MASK_EXT)
CPETR2 LD A,(DE)
AND A
JR Z,CPETR1+1
INC C
PUSH DE
PUSH HL
CALL COMPARF
POP HL
POP DE
JR Z,CPETR1
INC DE
INC DE
INC DE
JR CPETR2
CPETR1 LD A,C
POP HL
POP DE
POP BC
RET
COMPARF PUSH DE
LD DE,8
ADD HL,DE
POP DE
LD B,3
COMPARF1 LD A,(DE)
CP (HL)
RET NZ
INC HL
INC DE
DJNZ COMPARF1
RET
FIND_FILE LD (ADR_MASK_EXT),HL
LD (ADR_SKLAD),DE
LD A,D
ADD A,0X10
LD (MAKS_ADR),A
LD HL,0
LD (KOLFIND),HL
XOR A
NEXT_FIND LD IX,(MAKS_ADR)
AND A
JR Z,FINDF2
LD HL,(ADR_SKLAD)
DEC HL
DEC HL
LD (ADR_SKLAD),HL ;-2 АДРЕС СКЛАДИРОВАНИЯ
LD HL,(KOLFIND)
DEC HL ;-1 НАЙДЕННЫХ ФАЙЛОВ
LD (KOLFIND),HL
FINDF2 CALL GETFZAP ;ПОЛУЧЕНИЕ ОПИСАТЕЛЯ
LD A,(HL)
CP 0XE5 ;ЕСЛИ УДАЛЕНО
JR Z,FINDF1 ;ТО ПЕРЕХОДИМ НА СЛЕДУЮЩИЙ ОПИСАТЕЛЬ
LD DE,0X0B ;НУЖЕН ФЛАГОВЫЙ БАЙТ ОПИСАТЕЛЯ
EX DE,HL ;АДРЕС ОПИСАТЕЛЯ ПОРТИТЬ НЕ БУДЕМ
ADD HL,DE ;ПОЛУЧИЛИ АДРЕС ФЛАГОВОГО БАЙТА
LD L,(HL) ;ВЗЯЛИ ФЛАГОВЫЙ БАЙТ
EX DE,HL ;ВЕРНУЛИ АДРЕС ПОЛУЧЕННОГО ОПИСАТЕЛЯ
BIT 4,E ;ПРОВЕРКА ЭТО ФАЙЛ ИЛИ ДИРА
JR Z,FINDF3 ;ЕСЛИ ФАЙЛ, ТО ПРОДОЛЖЕНИЕ ПРОВЕРКИ
LD HL,(ADR_SKLAD) ;ДЛЯ ДИРЫ ПРОВЕРЯТЬ БОЛЬШЕ НЕ НАДО
LD (HL),C
INC HL
LD (HL),B ;ПОЛОЖИЛИ НОМЕР ДИРЫ В ТАБЛИЧКУ
INC HL
LD (ADR_SKLAD),HL
EX DE,HL
LD HL,(KOLFIND)
INC HL ;+1 НАЙДЕННЫХ ФАЙЛОВ
LD (KOLFIND),HL
LD A,IXL
CP D ;ПРОВЕРКА ЗА ВЫХОД ВЫДЕЛЕННОГО БУФЕРА
JR C,END_FINDF ;НЕ БОЛЕЕ 2048 ДИРОВ/ФАЙЛОВ В ТЕКУЩЕЙ ДИРЕКТОРИИ
FINDF1 LD HL,(TEK_ZAP)
PUSH HL ;СОХРАНИЛИ НА СТЕКЕ ТЕКУЩИЙ НОМЕР ФАЙЛА
CALL NXTLEGZ ;ИЩЕМ СЛЕДУЮЩИЙ ОПИСАТЕЛЬ
LD BC,(TEK_ZAP) ;ВЗЯЛИ НОВЫЙ НОМЕР ФАЙЛА
POP HL ;ВЕРНУЛИ СО СТЕКА СТАРЫЙ НОМЕР ФАЙЛА
AND A
SBC HL,BC ;ПРОВЕРКА НА ИЗМЕНЕНИЕ НОМЕРА ОПИСАТЕЛЯ
JR NZ,FINDF2 ;НОМЕР НЕ ИЗМЕНИЛСЯ, ВЫХОДИМ
END_FINDF LD BC,(KOLFIND) ;КОЛИЧЕСТВО НАЙДЕНЫХ ФАЙЛОВ
XOR A
RET
FINDF3 CALL CP_EXT ;ПРОВЕРКА ПО РАСШИРЕНИЮ
AND A
JR Z,FINDF1 ;НЕ СООТВЕСТВУЕТ ЗАДАННОЙ МАСКЕ ПО РАСШИРЕНИЮ
PUSH AF
LD DE,0X1C
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL)
INC HL
PUSH DE
LD E,(HL)
INC HL
LD D,(HL)
PUSH DE
CALL READ0SECTOR
EXX
LD HL,(ADR_SKLAD)
LD DE,(TEK_ZAP)
LD (HL),E
INC HL
LD (HL),D ;ПОЛОЖИЛИ НОМЕР ДИРЫ В ТАБЛИЧКУ
INC HL
LD (ADR_SKLAD),HL
LD HL,(TEK_ZAP)
INC HL
LD (TEK_ZAP),HL
LD HL,(KOLFIND)
INC HL ;+1 НАЙДЕННЫХ ФАЙЛОВ
LD (KOLFIND),HL
POP BC
POP DE
EXX
POP AF
RET
;IXL-КОЛИЧЕСТВО СЕКТОРОВ ДЛЯ ЗАГРУЗКИ
;IXH-РАЗМЕР КЛАСТЕРА
;IYL-
;IYH-СМЕЩЕНИЕ В КЛАСТЕРЕ
LD_FILE PUSH HL
LD HL,LD_FILE6
EX (SP),HL
LD IY,(SAVE_IY)
LD A,(BYTSSEC)
LD IXH,A
LD A,IXL
AND A
JR NZ,LD_FILE0
LD (AFILCLS),DE
LD (AFILCLS+2),BC
LD IYH,0 ;ИЗНАЧАЛЬНОЕ СМЕЩЕНИЕ В КЛАСТЕРЕ
RET
LD_FILE6 LD (SAVE_IY),IY
RET
LD_FILE0 LD DE,(AFILCLS)
LD BC,(AFILCLS+2) ;ТЕКУЩИЙ НОМЕР КЛАСТЕРА
PUSH BC
PUSH DE
PUSH HL
CALL REALSEC ;ПЕРЕВЕЛИ НОМЕР КЛАСТЕРА В НОМЕР СЕКТОРА
LD A,IYH
LD L,A
LD H,0
ADD HL,DE
EX DE,HL
JR NC,LD_FILE1
INC BC ;BCDE=НОМЕР СЕКТОРА ОТКУДА ГРУЗИТЬ
LD_FILE1 LD A,IXL
CP IXH
JP C,LD_FILE2
LD A,IXH
LD_FILE2 ADD A,IYH
CP IXH
LD A,IXL
JP C,LD_FILE5
LD A,IXH
SUB IYH
LD_FILE5 LD IYL,A ;СКОЛЬКО СЕКТОРОВ СЕЙЧАС ГРУЗИМ
POP HL ;ВОССТАНОВИЛИ АДРЕС ЗАГРУЗКИ
CALL TO_DRV
DB 3 ;ЗАГРУЗИЛИ СЕКТОРА
POP DE
POP BC ;ВОССТАНОВИЛИ НОМЕР КЛАСТЕРА
LD A,IYH
ADD A,IYL
CP IXH
JP C,LD_FILE3
SUB IXH
LD_FILE3 LD IYH,A
JP C,LD_FILE4
PUSH HL ;СОХРАНИЛИ АДРЕС ЗАГРУЗКИ
CALL RDFATZP ;ПРОЧИТАЛИ НОМЕР СЛЕДУЮЩЕГО КЛАСТЕРА
LD (AFILCLS),DE
LD (AFILCLS+2),BC
CALL LST_CLS ;ПРОВЕРИЛИ, А МОЖЕТ ЭТО ПОСЛЕДНИЙ КЛАСТЕР?
POP HL ;ВОССТАНОВИЛИ АДРЕС ЗАГРУЗКИ
RET C ;ЕСЛИ ПОСЛЕДНИЙ, ВЫХОДИМ
LD_FILE4 LD A,IXL
SUB IYL
RET Z
LD IXL,A
JP NZ,LD_FILE0
RET
;ЧТЕНИЕ 0 СЕКТОРА ТЕКУЩЕГО ФАЙЛА
READ0SECTOR CALL GETFZAP
LD DE,0X14
ADD HL,DE
LD C,(HL)
INC HL
LD B,(HL)
LD E,5
ADD HL,DE
LD E,(HL)
INC HL
LD D,(HL)
CALL REALSEC
JP LOADLST