;LAST UPDATE: 16.02.2014 savelij
 
 
 
                include ../../../rom/macros.a80
 
                include ../../../rom/global_vars.a80
 
                include ../../../rom/sdcomand.a80
 
 
 
CHARS           EQU 0XC000                      ;АДРЕС ШРИФТА ПЕРЕНЕСЕННОГО ИЗ ROM BASIC48
 
PEREM           EQU CHARS+0X400                 ;АДРЕС НАЧАЛА ПЕРЕМЕННЫХ И БУФЕРОВ
 
                                         
 
SD__RSTR        EQU P_DATA
 
SD__SEND        EQU P_DATA
 
 
 
;ВХОДНЫЕ ПАРАМЕТРЫ ОБЩИЕ:
 
;HL-АДРЕС ЗАГРУЗКИ В ПАМЯТЬ
 
;BCDE-32-Х БИТНЫЙ НОМЕР СЕКТОРА
 
;A-КОЛИЧЕСТВО БЛОКОВ (БЛОК=512 БАЙТ)
 
;ТОЛЬКО ДЛЯ МНОГОБЛОЧНОЙ ЗАПИСИ/ЧТЕНИИ
 
 
 
;ОШИБКИ ВЫДАВАЕМЫЕ НА ВЫХОДЕ:
 
;A=0-ИНИЦИАЛИЗАЦИЯ ПРОШЛА УСПЕШНО
 
;A=1-КАРТА НЕ НАЙДЕНА ИЛИ НЕ ОТВЕТИЛА
 
;A=2-КАРТА ЗАЩИЩЕНА ОТ ЗАПИСИ
 
;A=3-ПОПЫТКА ЗАПИСИ В СЕКТОР 0 КАРТЫ
 
 
 
TDIRCLS         EQU PEREM                       ;0X400 БУФЕР КЛАСТЕРОВ ROOT ДИРЕКТОРИИ
 
BUF_512_        EQU TDIRCLS+0X0400              ;0X200 БУФЕР СЕКТОРА
 
CAL_FAT         EQU BUF_512_+0X0200             ;1 КАЛИБР FAT
 
BYTSSEC         EQU CAL_FAT+1                   ;1 КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ
 
ROOTCLS         EQU BYTSSEC+1                   ;4 СЕКТОР НАЧАЛА ROOT ДИРЕКТОРИИ
 
ROOTSEC         EQU ROOTCLS+4                   ;2 РАЗМЕР В СЕКТОРАХ ROOT ДИРЕКТОРИИ
 
SEC_FAT         EQU ROOTSEC+2                   ;4 КОЛИЧЕСТВО СЕКТОРОВ ОДНОЙ FAT
 
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 ТАБЛИЦЫ
 
FB_EXT          EQU FATSTR+4                    ;B БУФЕР 8.3 ДЛЯ ПОИСКА ИМЕНИ
 
ADRPATH         EQU FB_EXT+0X0B                 ;2 АДРЕС ПУТИ К ИМЕНИ ФАЙЛА
 
ADR_LD          EQU ADRPATH+2                   ;2 АДРЕС ЗАГРУЗКИ
 
 
 
                ORG 0X6000
 
                DI
 
                XOR A
 
                OUT (0XFE),A
 
                LD HL,0X4000
 
                LD DE,0X4001
 
                LD BC,0X1800
 
                LD (HL),A
 
                LDIR
 
                LD BC,0X2FF
 
                LD (HL),5
 
                LDIR
 
                LD HL,0X3D00
 
                LD DE,CHARS+0X100
 
                LD BC,0X300
 
                LDIR
 
                LD HL,TXT_VERS
 
                CALL PRINT_MSG
 
                LD HL,F_PATH
 
                CALL START
 
                JR C,ERROR
 
                LD HL,TXT_OK
 
                CALL PRINT_MSG
 
                JP FLASHER
 
 
 
ERROR           CP 0XEE
 
                LD HL,TXT_SDERROR
 
                JR Z,ERROR1
 
                CP 0XDD
 
                LD HL,TXT_FATERROR
 
                JR Z,ERROR1
 
                CP 0X99
 
                LD HL,TXT_SIZEERROR
 
                JR Z,ERROR1
 
                LD HL,TXT_FILENONE
 
ERROR1          CALL PRINT_MSG
 
                LD HL,TXT_RESET
 
                CALL PRINT_MSG
 
ERROR2          XOR A
 
                IN A,(0XFE)
 
                CPL
 
                AND 0X1F
 
                JR Z,ERROR2
 
ERROR3          XOR A
 
                IN A,(0XFE)
 
                CPL
 
                AND 0X1F
 
                JR NZ,ERROR3
 
                PEC_ON SHADOW_BF
 
                JP EFLASHER
 
 
 
;ПУТЬ ДО ФАЙЛА ОТ ROOT
 
F_PATH          DB "ZXEVO.ROM",0
 
 
 
;ВЫДАЧА ОШИБКИ "НЕТ КАРТОЧКИ"
 
ZAW003          LD A,0XEE
 
                SCF
 
                RET
 
 
 
WR_STAT         POP HL
 
                SCF
 
                RET
 
 
 
;НА ВХОДЕ:
 
;HL-ТЕКСТОВАЯ СТРОКА ПУТИ ОТ ROOT
 
;DE-АДРЕС КУДА ГРУЗИТЬ
 
START           LD IYL,2
 
                LD (ADRPATH),HL
 
                LD (ADR_LD),DE
 
                LD A,3
 
                OUT (P_CONF),A
 
                XOR A
 
                OUT (P_DATA),A
 
                LD BC,P_DATA
 
                LD DE,0X10FF
 
                OUT (C),E
 
                DEC D
 
                JR NZ,$-3
 
                LD A,1
 
                OUT (P_CONF),A
 
                XOR A
 
                EX AF,AF'
 
ZAW001          LD HL,CMD00
 
                CALL OUTCOM             ;ПЕРЕВОДИМ КАРТОЧКУ В РЕЖИМ SPI КОМАНДОЙ 0
 
                CALL IN_OOUT            ;ЖДЕМ ОТВЕТА
 
                EX AF,AF'
 
                DEC A
 
                JR Z,ZAW003             ;ЖДЕМ ПО СЧЕПТЧИКУ 256 РАЗ
 
                EX AF,AF'
 
                DEC A
 
                JR NZ,ZAW001            ;ЖДЕМ ПОКА КАРТА ОТВЕТИТ БАЙТОМ 1
 
                LD BC,SD__RSTR
 
                LD HL,CMD08
 
                CALL OUTCOM             ;ОПРЕДЕЛЯЕМ СПЕЦИФИКАЦИЮ КАРТЫ
 
                CALL IN_OOUT            ;В "A" ОТВЕТ КАРТЫ R1
 
                IN H,(C)
 
                NOP
 
                IN H,(C)        
 
                NOP
 
                IN H,(C)
 
                NOP
 
                IN H,(C)                ;ПРОЧИТАЛИ ОСТАЛЬНЫЕ БАЙТЫ В НИКУДА
 
                BIT 2,A                 ;ЕСЛИ ОШИБКА, ТО
 
                LD HL,0                 ;КАРТА СПЕЦИФИКАЦИИ 1.0
 
                JR NZ,ZAW006            ;ИНАЧЕ 
 
                LD H,0X40               ;КАРТА СПЕЦИФИКАЦИИ 2.0
 
ZAW006          LD A,CMD_55
 
                CALL OUT_COM            ;ЗАПУСКАЕМ ВНУТРЕННЮЮ ИНИЦИАЛИЗАЦИЮ КАРТЫ
 
                CALL IN_OOUT
 
                LD BC,SD__SEND
 
                LD A,ACMD_41
 
                OUT (C),A
 
                LD A,H
 
                OUT (C),A
 
                XOR A
 
                OUT (C),A
 
                NOP
 
                OUT (C),A
 
                NOP
 
                OUT (C),A
 
                DEC A
 
                OUT (C),A
 
                CALL IN_OOUT
 
                AND A
 
                JR NZ,ZAW006            ;ЖДЕМ ПОКА КАРТЫ ПЕРЕЙДЕТ В РЕЖИМ ГОТОВНОСТИ
 
ZAW004          LD A,CMD_59
 
                CALL OUT_COM            ;ПРИНУДИТЕЛЬНО ОТКЛЮЧАЕМ CRC16
 
                CALL IN_OOUT
 
                AND A
 
                JR NZ,ZAW004
 
ZAW005          LD HL,CMD16
 
                CALL OUTCOM             ;ПРИНУДИТЕЛЬНЫЙ РАЗМЕР СЕКТОРА 512 БАЙТ
 
                CALL IN_OOUT
 
                AND A
 
                JR NZ,ZAW005
 
 
 
;ИНИЦИАЛИЗАЦИЯ ПЕРЕМЕННЫХ FAT
 
WC_FAT          LD DE,0
 
                LD B,D
 
                LD C,E
 
                CALL LOADLST            ;ЧИТАЕМ СЕКТОР 0 КАРТОЧКИ
 
                PUSH HL
 
                POP IX
 
                LD DE,0X01BE
 
                ADD HL,DE               ;ПЕРЕХОДИМ НА СМЕЩЕНИЕ ДЛЯ ПРОВЕРОК
 
                LD A,(HL)               ;ПРОВЕРЯМ ЧТОБЫ БЫЛ 0, КАРТОЧКИ НЕ МОГУТ БЫТЬ ЗАГРУЗОЧНЫМИ
 
                AND 0X7F
 
                JR NZ,RDFAT05           ;ЕСЛИ НЕ 0, ПРОВЕРИТЬ ДРУГОЕ
 
                LD DE,4
 
                ADD HL,DE               ;ПЕРЕХОДИМ К ПРОВЕРКЕ ТИПА РАЗДЕЛА
 
                LD A,(HL)
 
                LD B,0
 
                CP 1                    ;FAT12?
 
                JR Z,RDFAT06
 
                LD B,2
 
                CP 0X0B                 ;FAT32?
 
                JR Z,RDFAT06
 
                CP 0X0C                 ;FAT32?
 
                JR Z,RDFAT06
 
                LD B,1
 
                CP 4                    ;FAT14?
 
                JR Z,RDFAT06
 
                CP 6                    ;FAT16?
 
                JR Z,RDFAT06
 
                CP 0X0E                 ;FAT16?
 
                JR NZ,RDFAT05
 
RDFAT06         LD A,B                  ;БЕРЕМ ИЗ "B" ТИП РАЗДЕЛА
 
                LD (CAL_FAT),A          ;СОХРАНИЛИ
 
                ADD HL,DE
 
                CALL LOADZP             ;БЕРЕМ НОМЕР СЕКТОРА НАЧАЛА ОСНОВНОГО РАЗДЕЛА
 
                JR RDFAT00              ;ПЕРЕХОДИМ К ИНИЦИАЛИЗАЦИИ ПЕРЕМЕННЫХ ДЛЯ РАБОТЫ С ФАТОМ
 
 
 
;MBR НЕ ОБНАРУЖЕН, ПРОВЕРЯЕМ СЕКТОР 0 КАРТЫ КАК ОПИСАТЕЛЬ
 
RDFAT05         LD C,(IX+0X0D)          ;C=КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ
 
                XOR A
 
                LD E,A
 
                LD B,8
 
                RR C
 
                ADC A,0
 
                DJNZ $-4                ;КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ ДОЛЖНО БЫТЬ СТЕПЕНЬЮ 2
 
                DEC A
 
                JR NZ,$+3               ;ПРОВЕРИЛИ КОЛИЧЕСТВО БИТ
 
                INC E                   ;+1, ЕСТЬ ТАКОЕ
 
                LD A,(IX+0X0E)
 
                OR (IX+0X0F)
 
                JR Z,$+3                ;КОЛИЧЕСТВО ЗАРЕЗЕРВИРОВАННЫХ СЕКТОРОВ ДОЛЖНО БЫТЬ >0
 
                INC E                   ;+1, ЕСТЬ ТАКОЕ
 
                LD A,(IX+0X13)
 
                OR (IX+0X14)
 
                JR NZ,$+3               ;КОЛИЧЕСТВО СЕКТОРОВ НА РАЗДЕЛЕ ДЛЯ ФАТ16?
 
                INC E
 
                LD A,(IX+0X20)
 
                OR (IX+0X21)
 
                OR (IX+0X22)
 
                OR (IX+0X23)
 
                JR NZ,$+3               ;КОЛИЧЕСТВО СЕКТОРОВ НА РАЗДЕЛЕ ДЛЯ ФАТ32?
 
                INC E                   ;ОДНО ИЗ НИХ ДОЛЖНО БЫТЬ =0, ДРУГОЕ >0
 
                LD A,(IX+0X15)
 
                AND 0XF0
 
                CP 0XF0
 
                JR NZ,$+3               ;СТАРШИЕ БИТЫ ДОЛЖНЫ БЫТЬ В 1
 
                INC E
 
                LD A,E
 
                CP 4                    ;УСЛОВИЯ СОВПАЛИ?
 
                LD A,0XDD               ;FAT НЕ НАЙДЕН
 
                SCF
 
                RET NZ
 
                LD A,0XFF
 
                LD (CAL_FAT),A          ;ТИП ФАТ ПОКА НЕ ОПРЕДЕЛЕН
 
                LD DE,0
 
                LD B,D
 
                LD C,E
 
 
 
RDFAT00         LD (STARTRZ),DE
 
                LD (STARTRZ+2),BC       ;ПОЛОЖИЛИ НОМЕР СТАРТОВОГО СЕКТОРА РАЗДЕЛА
 
                CALL LOADLST            ;ЗАГРУЗИЛИ ЕГО
 
                LD HL,0
 
                LD DE,(BUF_512_+0X16)   ;BPB_FATSZ16
 
                LD A,D
 
                OR E
 
                JR NZ,RDFAT01           ;ЕСЛИ НЕ FAT12/16 (BPB_FATSZ16=0)
 
                LD DE,(BUF_512_+0X24)
 
                LD HL,(BUF_512_+0X26)   ;BPB_FATSZ32
 
                                        ;ТО БЕРЕМ ИЗ СМЕЩЕНИЯ +36
 
RDFAT01         LD (SEC_FAT+2),HL
 
                LD (SEC_FAT),DE         ;ЧИСЛО СЕКТОРОВ НА FAT-ТАБЛИЦУ
 
                LD HL,0
 
                LD DE,(BUF_512_+0X13)   ;BPB_TOTSEC16
 
                LD A,D
 
                OR E
 
                JR NZ,RDFAT02           ;ЕСЛИ НЕ FAT12/16 (BPB_TOTSEC16=0)
 
                LD DE,(BUF_512_+0X20)
 
                LD HL,(BUF_512_+0X22)   ;BPB_TOTSEC32
 
                                        ;ТО БЕРЕМ ИЗ СМЕЩЕНИЯ +32
 
RDFAT02         LD (SEC_DSC+2),HL
 
                LD (SEC_DSC),DE         ;К-ВО СЕКТОРОВ НА ДИСКЕ/РАЗДЕЛЕ
 
 
 
;ВЫЧИСЛЯЕМ ROOTDIRSECTORS
 
                LD DE,(BUF_512_+0X11)   ;BPB_ROOTENTCNT
 
                LD HL,0
 
                LD A,D
 
                OR E
 
                JR Z,RDFAT03
 
                LD B,H
 
                LD C,L
 
                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 (ROOTSEC),HL
 
                LD A,(BUF_512_+0X10)
 
                LD DE,(SEC_FAT)
 
                LD HL,(SEC_FAT+2)
 
                DEC A
 
                EX DE,HL
 
                ADD HL,HL
 
                EX DE,HL
 
                ADC HL,HL
 
                DEC A
 
                JR NZ,$-6
 
                POP BC                  ;ПОЛНЫЙ РАЗМЕР FAT-ОБЛАСТИ В СЕКТОРАХ
 
                CALL HLDEPBC            ;ПРИБАВИЛИ ROOTDIRSECTORS
 
                LD BC,(BUF_512_+0X0E)   ;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           ;BCDE+32-ОЕ ЧИСЛО ПО АДРЕСУ HL
 
                CALL BCDEHLM            ;ВЫЧЛИ ИЗ ПОЛНОГО К-ВА СЕКТОРОВ РАЗДЕЛА
 
                LD A,(BUF_512_+0X0D)
 
                LD (BYTSSEC),A
 
                CALL BCDE_A             ;РАЗДЕЛИЛИ НА К-ВО СЕКТОРОВ В КЛАСТЕРЕ
 
                LD (CLS_DSC),DE
 
                LD (CLS_DSC+2),BC       ;ПОЛОЖИЛИ КОЛ-ВО КЛАСТЕРОВ НА РАЗДЕЛЕ
 
 
 
                LD A,(CAL_FAT)
 
                CP 0XFF
 
                JR NZ,RDFAT04
 
                LD DE,(SEC_FAT-1)       ;ЕСЛИ РАЗРЯДНОСТЬ ФАТА НЕ ОПРЕДЕЛЕНА, ОПРЕДЕЛЯЕМ
 
                LD BC,(SEC_FAT+1)       ;ВЗЯЛИ КОЛИЧЕСТВО КЛАСТЕРОВ НА РАЗДЕЛЕ
 
                LD E,0
 
                PUSH BC
 
                PUSH DE
 
                SRL B
 
                RR C
 
                RR D
 
                RR E
 
                LD HL,CLS_DSC
 
                PUSH HL
 
                CALL HLBCDEM
 
                LD A,E
 
                AND 0X80
 
                OR D
 
                OR C
 
                OR B
 
                LD A,2
 
                POP HL
 
                POP DE
 
                POP BC
 
                JR Z,RDFAT04
 
                CALL HLBCDEM
 
                LD A,D
 
                OR C
 
                OR B
 
                LD A,1
 
                JR Z,RDFAT04
 
                XOR A
 
 
 
;ДЛЯ FAT12/16 ВЫЧИСЛЯЕМ АДРЕС ПЕРВОГО СЕКТОРА ДИРЕКТОРИИ
 
;ДЛЯ FAT32 БЕРЕМ ПО СМЕЩЕМИЮ +44, НА ВЫХОДЕ BCDE-СЕКТОР ROOTDIR
 
RDFAT04         PUSH AF
 
                LD DE,(RSVDSEC)
 
                LD BC,0
 
                LD HL,STARTRZ
 
                CALL BCDEHLP
 
                LD (FATSTR),DE
 
                LD (FATSTR+2),BC        ;ВЫЧИСЛИЛИ И ПОЛОЖИЛИ НОМЕР СЕКТОРА НАЧАЛА FAT-ЕАБЛИЦ
 
                POP AF
 
                LD (CAL_FAT),A          ;УТОЧНИЛИ ТИП ФАТА
 
                AND A
 
                LD DE,0
 
                LD B,D
 
                LD C,E
 
                JR Z,FSRROO2            ;FAT12-NONE
 
                DEC A
 
                JR Z,FSRROO2            ;FAT16
 
                LD DE,(BUF_512_+0X2C)
 
                LD BC,(BUF_512_+0X2E)   ;FAT32
 
FSRROO2         LD (ROOTCLS),DE
 
                LD (ROOTCLS+2),BC       ;ПОЛОЖИЛИ НОМЕР КЛАСТЕР ROOT ДИРЕКТОРИИ
 
 
 
                LD HL,(ADRPATH)         ;ВЕРНУЛИ АДРЕС СТРОКИ ПУТИ ДО ФАЙЛА
 
FINDFL1         PUSH BC
 
                PUSH DE                 ;СОХРАНИЛИ НОМЕР КЛАСТЕРА
 
                CALL FNDBUF             ;РАСПАКОВКА ЧАСТИ ТЕКСТОВОЙ СТРОКИ ДЛЯ СОЗДАНИЯ МАСКИ ПОИСКА
 
                POP DE
 
                POP BC                  ;ВОССТАНОВИЛИ НОМЕР КЛАСТЕРА
 
                PUSH HL                 ;СОХРАНИЛИ ТЕКУЩИЙ АДРЕС ТЕКСТОВОЙ СТРОКИ
 
 
 
                LD HL,TDIRCLS           ;АДРЕС ТАБЛИЦЫ КЛАСТЕРОВ ТЕКУЩЕЙ ДИРЕКТОРИИ
 
                LD A,D
 
                OR E
 
                OR B
 
                OR C
 
                CALL SAVEZP             ;СОХРАНИЛИ В ТАБЛИЦУ НОМЕР ТЕКУЩЕГО КЛАСТЕРА
 
                JR Z,LASTCLS            ;ЕСЛИ НОМЕР КЛАСТЕРА 0, ТО ЭТО ROOT ДИРА (ДЛЯ ФАТ12/16)
 
NEXTCLS         PUSH HL
 
                CALL RDFATZP            ;ЧИТАЕМ СЛЕДУЩИЙ НОМЕР КЛАСТЕРА ИЗ ЦЕПОЧКИ ДИРЕКТОРИИ
 
                CALL LST_CLS            ;ПРОВЕРЯЕМ НА КОНЕЦ ЦЕПОЧКИ
 
                POP HL
 
                JR C,LASTCLS
 
                CALL SAVEZP             ;ЕСЛИ НЕПОСЛЕДНИЙ СОХРАНЯЕМ В ТАБЛИЦУ
 
                JR NEXTCLS              ;СЛЕДУЮЩИЙ НОМЕР КЛАСТЕРА
 
 
 
LASTCLS         LD BC,0XFFFF
 
                CALL SAVEZP             ;КЛАДЕМ МАРКЕР КОНЦА ЦЕПОЧКИ
 
 
 
FINDFL          INC BC                  ;ИЩЕМ ПО ЗАДАННОЙ МАСКЕ НАЧИНАЯ С 0
 
                CALL RDDIRSC            ;ГРУЗИМ ПО НОМЕРУ ОПИСАТЕЛЯ СЕКТОР ДИРЕКТОРИИ
 
                LD A,C
 
                AND 0X0F                ;В СЕКТОРЕ МАКСИМУМ 16 ОПИСАТЕЛЕЙ
 
                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 A,(HL)               ;ПРОВЕРЯЕМ ПЕРВЫЙ БАЙТ ИМЕНИ ОПИСАТЕЛЯ
 
                AND A
 
                LD A,0XAA               ;ЕСЛИ БАЙТ =0, ТО
 
                JP Z,WR_STAT            ;ПЕРЕХОД ПО ОШИБКЕ = ФАЙЛ НЕ НАЙДЕН
 
                PUSH HL
 
                PUSH BC
 
                CALL COMPARE            ;СРАВНИВАЕМ С ЗАДАННОЙ МАСКОЙ
 
                POP BC
 
                POP DE
 
                PUSH DE
 
                POP IX                  ;СОДЕРЖИМОЕ IX=АДРЕС ОПИСАТЕЛЯ
 
                JR NZ,FINDFL            ;НЕ СОВПАДАЕТ, ПЕРЕХОДИМ К СЛЕДУЮЩЕМУ ОПИСАТЕЛЮ
 
                LD A,(IX+0X1F)
 
                OR (IX+0X1D)
 
                OR (IX+0X1C)
 
                LD A,0X99
 
                JP NZ,WR_STAT
 
                LD A,(IX+0X1E)
 
                CP 8
 
                LD A,0X99
 
                JP NZ,WR_STAT
 
                CALL RD_CLAS            ;ЗАБИРАЕМ НОМЕР КЛАСТЕРА ИЗ НАЙДЕННОГО ОПИСАТЕЛЯ
 
                EX (SP),HL              ;ВОССТАНОВИЛИ ТЕКУЩИЙ АДРЕС В СТРОКЕ ПУТИ ДО ФАЙЛА
 
                INC SP
 
                INC SP                  ;МАСКИРОВКА НА СТЕКЕ АДРЕСА РАЗМЕРА В БАЙТАХ ТЕКУЩЕГО ФАЙЛА
 
                LD A,(HL)
 
                AND A                   ;ТЕКСТОВАЯ СТРОКА КОНЧИЛАСЬ?
 
                JR NZ,FINDFL1           ;ЕСЛИ НЕТ, ТО ИЩЕМ ДАЛЬШЕ
 
                LD A,(IX+0X0B)          ;ПРОВЕРЯЕМ ЭТО ДИРА ИЛИ ФАЙЛ?
 
                AND 0X10
 
                JR NZ,FINDFL            ;ЕСЛИ ДИРА, ТО ПРОДОЛЖАЕМ ПОИСК
 
 
 
                PUSH BC
 
                PUSH DE
 
                LD IX,IXBASE
 
                LD (IX+0),0
 
                LD (IX+1),2
 
                CALL SETWIN_INDICAT
 
                LD HL,TXT_LOAD
 
                CALL PRINT_MSG
 
                POP DE
 
                POP BC
 
 
 
                LD A,(BYTSSEC)          ;ВЗЯЛИ РАЗМЕР КЛАСТЕРА В СЕКТОРАХ
 
                LD IXH,A                ;СОХРАНИЛИ
 
                LD IYH,0                ;ИЗНАЧАЛЬНОЕ СМЕЩЕНИЕ В КЛАСТЕРЕ
 
 
 
FINDFL2         LD A,PAGE4FLASHER
 
                LD HL,CPU2
 
FINDFL3         PUSH AF
 
                PUSH HL
 
                CALL SET4MBPAGE
 
                LD IXL,0X20
 
                CALL LD_FILE
 
                JR C,FINDFL4
 
                CALL INC_INDICAT
 
                POP HL
 
                POP AF
 
                INC A
 
                JR FINDFL3
 
 
 
FINDFL4         POP HL
 
                POP AF
 
                XOR A
 
                RET
 
 
 
;HL-АДРЕС ЗАГРУЗКИ
 
;IXL-КОЛИЧЕСТВО СЕКТОРОВ ДЛЯ ЗАГРУЗКИ
 
;IXH-РАЗМЕР КЛАСТЕРА
 
;IYL-
 
;IYH-СМЕЩЕНИЕ В КЛАСТЕРЕ
 
LD_FILE         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 RDMULTI            ;ЗАГРУЗИЛИ СЕКТОРА
 
                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            ;ПРОЧИТАЛИ НОМЕР СЛЕДУЮЩЕГО КЛАСТЕРА
 
                CALL LST_CLS            ;ПРОВЕРИЛИ, А МОЖЕТ ЭТО ПОСЛЕДНИЙ КЛАСТЕР?
 
                POP HL                  ;ВОССТАНОВИЛИ АДРЕС ЗАГРУЗКИ
 
                RET C                   ;ЕСЛИ ПОСЛЕДНИЙ, ВЫХОДИМ
 
LD_FILE4        LD A,IXL
 
                SUB IYL
 
                RET Z
 
                LD IXL,A
 
                JP NZ,LD_FILE
 
                RET
 
 
 
SET_PAGE        PUSH BC
 
                LD BC,0X7FFD
 
                OUT (C),A
 
                POP 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
 
 
 
;ЧТЕНИЕ СЕКТОРА DIR ПО НОМЕРУ BC
 
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
 
                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
 
                RET
 
 
 
;ПРОВЕРКА НА ПОСЛЕДНИЙ КЛАСТЕР В ЦЕПОЧКЕ
 
LST_CLS         LD A,(CAL_FAT)          ;ЗАВИСИТ ОТ РАЗРЯДНОСТИ ФАТА
 
                AND A
 
                JP NZ,LST_CL1
 
                LD HL,0X0FF7            ;ПРОВЕРКА ДЛЯ ФАТ12
 
                SBC HL,DE
 
                RET
 
 
 
LST_CL1         DEC A
 
                JP NZ,LST_CL2
 
LST_CL3         LD HL,0XFFF7            ;ПРОВЕРКАМ ДЛЯ ФАТ16 И МЛАДШИХ БИТ ФАТ32
 
                SBC HL,DE
 
                RET
 
 
 
LST_CL2         LD HL,0X0FFF            ;ПРОВЕРКА ДЛЯ СТАРШИХ БИТ ФАТ32
 
                SBC HL,BC
 
                RET NZ
 
                JP LST_CL3
 
 
 
;ЧТЕНИЕ СЛЕДУЮЩЕГО НОМЕРА КЛАСТЕРА В ЦЕПОЧКЕ
 
RDFATZP         LD A,(CAL_FAT)          ;ЧТЕНИЕ ЗАВИСИТ ОТ РАЗРАДНОСТИ ФАТА
 
                AND A
 
                JP Z,RDFATS0            ;ПЕРЕХОД ВПЕРЕД ДЛЯ ФАТ12
 
                DEC A
 
                JP Z,RDFATS1            ;ПЕРЕХОД ВПЕРЕД ДЛЯ ФАТ16
 
                EX DE,HL                ;ЗДЕСЬ ЧТЕНИЕ ДЛЯ ФАТ32
 
                ADD HL,HL
 
                EX DE,HL
 
                LD HL,0
 
                ADC HL,BC
 
                ADC HL,BC               ;УМНОЖИЛИ НОМЕР КЛАСТЕРА НА 2
 
                LD A,E
 
                LD E,D
 
                LD D,L
 
                LD C,H
 
                LD B,0                  ;РАЗДЕЛИЛИ НОМЕР КЛАСТЕРА НА 256
 
                CALL RDFATS2            ;ЧИТАЕМ МЛАДШИЕ 16 БИТ ИСПОЛЬЗУЯ ЧТЕНИЕ ДЛЯ ФАТ16
 
                INC HL
 
                LD C,(HL)
 
                INC HL
 
                LD B,(HL)               ;ПРОЧИТАЛИ ПОСЛЕДУЮЩИЕ СТАРШИЕ 16 БИТ
 
                RET
 
 
 
RDFATS1         LD BC,0
 
                LD A,E
 
                LD E,D
 
                LD D,C                  ;РАЗДЕЛИЛИ НОМЕР КЛАСТЕРА НА 256, СТАРШИЕ 16 БИТ =0
 
RDFATS2         PUSH AF                 ;ОБЩЕЕ ЧТЕНИЕ 16 БИТНОГО НОМЕРА КЛАСТЕРА ДЛЯ ФАТ16/32
 
                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)               ;ПОЛУЧИЛИ 16 БИТ НОМЕРА КЛАСТЕРА
 
                RET
 
 
 
;ЧТЕНИЕ 12 БИТНОГО НОМЕРА КЛАСТЕРА ИЗ ЦЕПОЧКИ ДЛЯ ФАТ12
 
RDFATS0         LD H,D
 
                LD L,E
 
                ADD HL,HL
 
                ADD HL,DE               ;HL=HL*3
 
                SRL H
 
                RR L                    ;HL=HL/2 - В ИТОГЕ УМНОЖИЛИ НОМЕР КЛАСТЕРА НА 1,5
 
                LD A,E                  ;A-НАМ ИНТЕРЕСЕН ТОЛЬКО БИТ НОМЕР СТАРОГО НОМЕРА КЛАСТЕРА
 
                LD E,H
 
                LD D,0
 
                LD B,D
 
                LD C,D                  ;РАЗДЕЛИЛИ НОМЕР КЛАСТЕРА НА 256
 
                SRL E
 
                PUSH AF
 
                PUSH HL
 
                LD HL,FATSTR
 
                CALL BCDEHLP
 
                CALL LOADLST            ;ЗАГРУЗИЛИ ВЫЧИСЛЕННЫЙ СЕКТОР
 
                POP BC
 
                LD A,B
 
                AND 1
 
                LD B,A                  ;BC=СМЕЩЕНИЕ В ЗАГРУЖЕННОМ СЕКТОРЕ
 
                ADD HL,BC               ;HL=АДРЕС ОТКУДА ЧИТАТЬ БАЙТЫ НОМЕРА КЛАСТЕРА
 
                LD B,(HL)               ;ПРОЧИТАЛИ МЛАДШУЮ ЧАСТЬ НОМЕРА КЛАСТЕРА
 
                INC HL                  ;АДРЕС СЛЕДУЮЩЕГО БАЙТА
 
                LD A,H
 
                CP HIGH (BUF_512_)+2    ;ПРОВЕРКА НА ПЕРЕХОД ГРАНИЦЫ ЗАГРУЖЕННОГО СЕКТОРА
 
                JP NZ,RDFATS4
 
                PUSH BC                 ;ВЫХЛД ЗА ПРЕДЕЛЫ ТЕКУЩЕГО ЗАГРУЖЕННОГО СЕКТОРА
 
                LD BC,0
 
                INC DE
 
                CALL LOADLST            ;ЗАГРУЖАЕМ СЛЕДУЮЩИЙ СЕКТОР ФАТ ТАБЛИЦЫ
 
                POP BC
 
RDFATS4         POP AF
 
                LD D,(HL)               ;ЧИТАЕМ СТАРШИЕ БИТЫ НОМЕРА КЛАСТЕРА
 
                LD E,B                  ;ТЕПЕРЬ DE=НОМЕР СЛЕДУЮЩЕГО КЛАСТЕРА В ЦЕПОЧКЕ
 
                LD BC,0
 
                RRA                     ;ПРОВЕРЯЕМ БИТ 0 СТАРОГО НОМЕРА КЛАСТЕРА
 
                JP NC,RDFATS3
 
                SRL D                   ;СДВИГАЕМ НОМЕР ПРОЧИТАННОГО НОМЕРА КЛАСТЕРА В МЛАДШИЕ 12 БИТ
 
                RR E
 
                SRL D
 
                RR E
 
                SRL D
 
                RR E
 
                SRL D
 
                RR E
 
RDFATS3         LD A,D
 
                AND 0X0F
 
                LD D,A                  ;СБРОСИЛИ НЕЗНАЧАЩИЕ СТАРШИЕ 4 БИТА У ПОЛУЧЕННОГО НОМЕРА КЛАСТЕРА
 
                RET
 
 
 
;ВЫЧИСЛЕНИЕ РЕАЛЬНОГО СЕКТОРА
 
;НА ВХОДЕ BCDE=НОМЕР КЛАСТЕРА FAT
 
;НА ВЫХОДЕ BCDE=НОМЕР РЕАЛЬНОГО СЕКТОРА
 
REALSEC         LD A,B
 
                OR C
 
                OR D
 
                OR E
 
                JP NZ,REALSE1           ;BCDE=0?
 
                LD HL,SEC_FAT           ;ЭТО ROOT ДИРЕКТОРИЯ У ФАТ12/16
 
                LD DE,(FATSTR)          ;МЕСТОПОЛОЖЕНИЕ ROOT ДИРЫ СРАЗУ ПОСЛЕ ФАТ ТАБЛИЦЫ
 
                LD BC,(FATSTR+2)
 
                PUSH HL
 
                CALL BCDEHLP            ;ПРИБАВИЛИ К НАЧАЛУ ФАТ ТАБЛИЦЫ ЕЕ РАЗМЕР
 
                POP HL
 
                JP BCDEHLP              ;ПРИБАВИЛИ ЕЩЕ РАЗ И ПОЛУЧИЛИ НОМЕР СЕКТОРА НАЧАЛА ROOT ДИРЫ
 
 
 
REALSE1         LD HL,0XFFFE
 
                EX DE,HL
 
                ADD HL,DE
 
                EX DE,HL
 
                INC HL
 
                ADC HL,BC               ;HLDE=НОМЕР КЛАСТЕРА-2
 
                LD A,(BYTSSEC)          ;НУЖНО УМНОЖИТЬ НА РАЗМЕР КЛАСТЕРА
 
                JP REALSE2
 
 
 
REALSE3         SLA E
 
                RL D
 
                RL L
 
                RL H
 
REALSE2         RRCA
 
                JP NC,REALSE3           ;УМНОЖИЛИ НА РАЗМЕР КЛАСТЕРА
 
                LD B,H
 
                LD C,L
 
                LD HL,STARTRZ
 
                CALL BCDEHLP            ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА ДИСКА
 
                LD HL,FRSTDAT
 
                JP BCDEHLP              ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА РАЗДЕЛА
 
 
 
;BCDE=BCDE/512
 
BCDE200         LD E,D
 
                LD D,C
 
                LD C,B
 
                LD B,0
 
                LD A,2
 
                JP BCDE_A
 
 
 
;BCDE>>A=BCDE
 
BCDE_A1         SRL B
 
                RR C
 
                RR D
 
                RR E
 
BCDE_A          RRCA
 
                JP 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
 
 
 
;BCDE-(ADR)=BCDE
 
HLBCDEM         LD A,E
 
                SUB (HL)
 
                INC HL
 
                LD E,A
 
                LD A,D
 
                SBC A,(HL)
 
                INC HL
 
                LD D,A
 
                LD A,C
 
                SBC A,(HL)
 
                INC HL
 
                LD C,A
 
                LD A,B
 
                SBC A,(HL)
 
                LD B,A
 
                RET
 
 
 
;HLDE+BC=HLDE
 
HLDEPBC         EX DE,HL
 
                ADD HL,BC
 
                EX DE,HL
 
                LD BC,0
 
                ADC HL,BC
 
                RET
 
 
 
;ГРУЗИЛКА ОДНОГО СЕКТОРА
 
LOADLST         LD HL,BUF_512_          ;АДРЕС БУФЕРА СЕКТОРА
 
                LD A,1                  ;ГРУЗИТЬ 1 СЕКТОР
 
                CALL RDMULTI            ;ЗАГРУЗИЛИ СЕКТОР
 
                LD HL,BUF_512_          ;НА ВЫХОДЕ HL=АДРЕС НАЧАЛА БУФЕРА ЗАГРУЖЕННОГО СЕКТОРА
 
                RET
 
 
 
;ПОДАЧА КОМАНДЫ В SD КАРТУ БЕЗ ПАРАМЕТРОВ
 
OUTCOM          PUSH BC
 
                LD BC,0X0600+SD__SEND   ;ВЫДАТЬ В ПОРТ 6 БАЙТ
 
                OTIR
 
                POP BC
 
                RET
 
 
 
;ВЫДАЧА В ПОРТ SD КАРТЫ КОМАНДЫ С ПАРАМЕТРОМ 0
 
OUT_COM         PUSH BC
 
                LD BC,SD__SEND
 
                OUT (C),A               ;ОТПРАВИЛИ КОД КОМАНДЫ
 
                XOR A
 
                OUT (C),A               ;БИТЫ 31-24 ПАРАМЕТРА
 
                NOP
 
                OUT (C),A               ;БИТЫ 23-16 ПАРАМЕТРА
 
                NOP
 
                OUT (C),A               ;БИТЫ 15-8 ПАРАМЕТРА
 
                NOP
 
                OUT (C),A               ;БИТЫ 7-0 ПАРАМЕТРА
 
                DEC A
 
                OUT (C),A               ;БЕЗ CRC16
 
                POP BC
 
                RET
 
 
 
SECM200         PUSH HL
 
                PUSH BC
 
                LD A,CMD_58
 
                CALL OUT_COM
 
                CALL IN_OOUT
 
                LD BC,SD__RSTR
 
                IN H,(C)
 
                NOP
 
                IN A,(C)
 
                NOP
 
                IN A,(C)
 
                NOP
 
                IN A,(C)
 
                BIT 6,H
 
                POP HL
 
                JP NZ,SECN200
 
                EX DE,HL
 
                ADD HL,HL
 
                EX DE,HL
 
                ADC HL,HL
 
                LD H,L
 
                LD L,D
 
                LD D,E
 
                LD E,0
 
SECN200         LD A,CMD_18
 
                LD C,SD__SEND
 
                OUT (C),A
 
                NOP
 
                OUT (C),H
 
                NOP
 
                OUT (C),L
 
                NOP
 
                OUT (C),D
 
                NOP
 
                OUT (C),E
 
                LD A,0XFF
 
                OUT (C),A
 
                POP HL
 
                RET
 
 
 
IN_OOUT         PUSH DE
 
                LD DE,0X04FF
 
IN_WAIT         IN A,(SD__RSTR)
 
                CP E
 
                JP NZ,IN_EXIT
 
IN_NEXT         DEC D
 
                JP NZ,IN_WAIT
 
IN_EXIT         POP DE
 
                RET
 
 
 
CMD00           DB 0X40,0X00,0X00,0X00,0X00,0X95        ;GO_IDLE_STATE
 
CMD08           DB 0X48,0X00,0X00,0X01,0XAA,0X87        ;SEND_IF_COND
 
CMD16           DB 0X50,0X00,0X00,0X02,0X00,0XFF        ;SET_BLOCKEN
 
 
 
;МНОГО СЕКТОРНОЕ ЧТЕНИЕ С SD КАРТЫ
 
RDMULTI         EX AF,AF'
 
                CALL SECM200
 
                EX AF,AF'
 
                LD BC,SD__RSTR
 
RDMULT1         EX AF,AF'
 
RDMULT2         CALL IN_OOUT
 
                CP 0XFE
 
                JP NZ,RDMULT2
 
                INIR
 
                NOP
 
                INIR
 
                NOP
 
                IN A,(C)
 
                NOP
 
                IN A,(C)
 
                EX AF,AF'
 
                DEC A
 
                JP NZ,RDMULT1
 
                LD A,CMD_12
 
                CALL OUT_COM
 
                CALL IN_OOUT
 
                INC A
 
                JP NZ,$-4
 
                RET
 
 
 
;ВЫБОРКА НОМЕРА КЛАСТЕРА ИЗ ФАЙЛОВОГО ОПИСАТЕЛЯ
 
RD_CLAS         EX DE,HL
 
                LD DE,0X14              ;СТАРШИЕ 16 БИТ ЧИТАЕМ ИЗ СМЕЩЕНИЯ +20
 
                ADD HL,DE
 
                LD C,(HL)
 
                INC HL
 
                LD B,(HL)
 
                LD E,5                  ;МЛАДШИЕ 16 БИТ ЧИТАЕМ ИЗ СМЕЩЕНИЯ +26
 
                ADD HL,DE
 
                LD E,(HL)
 
                INC HL
 
                LD D,(HL)
 
                INC HL
 
                RET
 
 
 
;ПРОВЕРКА ПО МАСКЕ
 
COMPARE         LD DE,FB_EXT
 
                LD B,0X0B
 
                LD A,(DE)
 
                CP (HL)
 
                RET NZ
 
                INC HL
 
                INC DE
 
                DJNZ $-5
 
                RET
 
 
 
;РАСПАКОВЩИК ПУТИ К ФАЙЛУ
 
FNDBUF          LD BC,0X0802
 
                LD DE,FB_EXT
 
FNDBUF4         LD A,(HL)
 
                INC HL
 
                CP 0X2E
 
                JR Z,FNDBUF2
 
                CP 0X5C
 
                JR Z,FNDBUF5
 
                LD (DE),A
 
                INC DE
 
                DJNZ FNDBUF4
 
                LD A,(HL)
 
                AND A
 
                RET Z
 
                INC HL
 
                JR FNDBUF3
 
 
 
FNDBUF5         LD A,C
 
                AND A
 
                RET Z
 
FNDBUF2         LD A,B
 
                AND A
 
                JR Z,FNDBUF3
 
                LD A,0X20
 
                LD (DE),A
 
                INC DE
 
                DJNZ $-2
 
FNDBUF3         LD B,3
 
                DEC C
 
                DEC HL
 
                LD A,(HL)
 
                CP 0X5C
 
                JR Z,FNDBUF4
 
                INC HL
 
                JR FNDBUF4
 
 
 
                include flasher.a80
 
 
 
;ПРОШИВАТЕЛЬ ПЗУ С ИНДИКАЦИЕЙ ПРОЦЕССА
 
FLASHER         LD BC,PENT_CONF
 
                XOR A
 
                OUT (C),A
 
                PEC_ON SHADOW_BF
 
                LD BC,0XFF77
 
                LD A,0XA3
 
                OUT (C),A                       ;ПРИНУДИТЕЛЬНОЕ ВКЛЮЧЕНИЕ ТУРБО РЕЖИМА 7МГЦ
 
                PEC_ON SHADOW_BF+FLASH_BF       ;РАЗРЕШЕНИЕ ПРОГРАММИРОВАНИЯ FLASH
 
                LD BC,WIN_A0
 
                LD A,0X7F
 
                OUT (C),A                       ;ОТКЛЮЧЕНИЕ ROM В ОКНЕ 0
 
                LD IX,IXBASE
 
                LD (IX+0),12
 
                LD (IX+1),4
 
                LD HL,TXT_ERASE
 
                CALL PRINT_MSG
 
                CALL SETWIN_INDICAT             ;УСТАНОВКА ИНДИКАТОРА ПРОЦЕССА
 
                LD E,0
 
                LD HL,0
 
FLASHER4        CALL ERASE_BLK                  ;СТИРАНИЕ БЛОКА 64КБ
 
                CALL INC_INDICAT                ;ОБНОВЛЕНИЕ ИНДИКАТОРА ПРОЦЕССА
 
                INC E                           ;СЛЕДУЮЩИЙ БЛОК 
 
                BIT 3,E
 
                JR Z,FLASHER4
 
                LD BC,WIN_A3
 
                LD A,0X7F
 
                OUT (C),A
 
                LD (IX+0),12
 
                LD (IX+1),6
 
                LD HL,TXT_WRITE
 
                REPT 8
 
                CALL PRINT_MSG
 
                ENDM
 
                LD A,PAGE4FLASHER               ;СТРАНИЦА НАЧАЛА ЗАГРУЖЕННОГО ROM ФАЙЛА
 
                LD E,0
 
FLASHER3        CALL FLASH_64KB                 ;ПРОШИВАНИЕ ОДНОЙ 64КБ СТРАНИЦЫ
 
                INC (IX+1)
 
                INC E                           ;СЛЕДУЮЩАЯ 64КБ СТРАНИЦА
 
                BIT 3,E
 
                JR Z,FLASHER3
 
EFLASHER        LD BC,WIN_P3
 
                XOR A
 
                OUT (C),A                       ;ВКЛЮЧЕНИЕ RAM В ОКНЕ 3
 
                LD A,(CPU3+0X20)
 
                XOR B
 
                LD (CPU3+0X20),A                ;МЕНЯЕМ БАЙТ ДЛЯ НАРУШЕНИЯ CRC КОНТРОЛЯ И ПОЛНОГО РЕИНИТА
 
                LD A,(CPU1+BUF_TABLVOL+0XFE)
 
                XOR B
 
                LD (CPU1+BUF_TABLVOL+0XFE),A    ;АНАЛОГИЧНО ДЛЯ DEVICE MANAGER
 
                PEC_OFF FLASH_BF
 
                LD HL,0X79ED                    ;OUT (C),A
 
                LD (0XFFFE),HL                  ;УКЛАДКА КОМАНДЫ OUT (C),A
 
                LD BC,0XBC77
 
                LD A,2
 
                JP 0XFFFE
 
 
 
;ПРОШИВАНИЕ ОДНОЙ 64КБ СТРАНИЦЫ
 
;ВХОД: A=НОМЕР 16КБ СТРАНИЦЫ ОТКУДА БРАТЬ БАЙТЫ ДЛЯ ПРОШИВАНИЯ
 
;      E=НОМЕР ПРОШИВАЕМОЙ 64КБ СТРАНИЦЫ
 
FLASH_64KB      LD HL,0
 
                PUSH AF
 
                LD A,E
 
                ADD A,2
 
                CALL SETWIN_INDICAT             ;ОБНОВЛЕНИЕ ИНДИКАТОРА ПРОЦЕССА
 
                POP AF
 
FLASHER2        PUSH AF
 
                LD BC,WIN_P0
 
                OUT (C),A                       ;ВКЛЮЧЕНИЕ СТРАНИЦЫ RAM ОТКУДА БРАТЬ БАЙТЫ ДЛЯ ПРОШИВАНИЯ
 
                PUSH IX
 
                LD IX,0
 
FLASHER1        LD A,(IX)                       ;ВЗЯЛИ БАЙТ ДЛЯ ПРОШИВАНИЯ
 
                INC A
 
                JR Z,FLASHER5                   ;ЕСЛИ БАЙТ = FF, ТО НЕ ПРОШИВАЕМ
 
                DEC A
 
                CALL PGM_BYTE                   ;ПРОШИЛИ БАЙТ
 
FLASHER5        INC IX
 
                INC HL
 
                LD A,H
 
                AND 0X0F
 
                OR L
 
                CALL Z,INC_INDICAT              ;ОБНОВИЛИ ИНДИКАТОР ЕСЛИ ПРОШИЛИ 4КБ
 
                LD A,IXH
 
                AND 0X40
 
                JR Z,FLASHER1                   ;ПРОДОЛЖАЕМ ПОКА НЕ КОНЧИТСЯ СТРАНИЦА ВЫБОРКИ БАЙТ
 
                POP IX
 
                POP AF
 
                INC A                           ;СЛЕДУЮЩАЯ СТРАНИЦА ОТКУДА БАЙТЫ БРАТЬ ДЛЯ ПРОШИВАНИЯ
 
                LD D,A                          ;ВРЕМЕННО СОХРАНИЛИ
 
                LD A,H                          ;ПРОВЕРКА НА ОКОНЧАНИЕ 64КБ СТРАНИЦЫ 
 
                AND A
 
                LD A,D                          ;ВОССТАНОВИЛИ
 
                JR NZ,FLASHER2
 
                RET
 
 
 
SET4MBPAGE      PUSH BC
 
                LD B,A
 
                PEC_ON SHADOW_BF
 
                LD A,B
 
                LD BC,WIN_P2
 
                OUT (C),A
 
                LD B,A
 
                PEC_OFF SHADOW_BF
 
                LD A,B
 
                POP BC
 
                RET
 
 
 
;H-X, L-Y
 
ADRDIS          LD (ASD+1),A
 
                LD A,L
 
                AND 0X18
 
                OR 0X40
 
                EX AF,AF'
 
                LD A,L
 
                AND 7
 
                RRCA
 
                RRCA
 
                RRCA
 
                ADD A,H
 
                LD L,A
 
                EX AF,AF'
 
                LD H,A
 
                LD E,L
 
ADRATR          LD A,H
 
                RRCA
 
                RRCA
 
                RRCA
 
                AND 3
 
                OR 0X58
 
                LD D,A
 
ASD             LD A,0
 
                RET
 
 
 
IXBASE          DB 0,0
 
 
 
;                       12345678901234567890123456789012
 
TXT_VERS        DB 0,0,"*** Fast update PentEvo ROM ***",0
 
TXT_ERASE       DB 0,4,"Erase FLASH 01234567",0
 
TXT_WRITE       DB 0,6,"Write pages 0",0
 
TXT_1           DB 12,7,"1",0
 
TXT_2           DB 12,8,"2",0
 
TXT_3           DB 12,9,"3",0
 
TXT_4           DB 12,10,"4",0
 
TXT_5           DB 12,11,"5",0
 
TXT_6           DB 12,12,"6",0
 
TXT_7           DB 12,13,"7",0
 
TXT_LOAD        DB 0,2,"Loading file ZXEVO.ROM...",0
 
TXT_OK          DB 25,2,"Ok",0
 
TXT_SDERROR     DB 0,2,"SD card not found",0
 
TXT_FILENONE    DB 0,2,"File ZXEVO.ROM not found",0
 
TXT_FATERROR    DB 0,2,"FAT not found",0
 
TXT_RESET       DB 0,4,"Press any key for RESET",0
 
TXT_SIZEERROR   DB 0,2,"ZXEVO.ROM size error",0
 
 
 
;HL-XY КООРДИНАТА
 
;DE-АДРЕС ТЕКСТА
 
PRINT_MSG       LD A,(HL)
 
                INC HL
 
                LD C,(HL)
 
                INC HL
 
                PUSH HL
 
                LD L,C
 
                LD H,A
 
                CALL ADRDIS
 
                EX DE,HL
 
                POP HL
 
PRINTMSG2       LD A,(HL)
 
                INC HL
 
                AND A
 
                RET Z
 
                PUSH DE
 
                PUSH HL
 
                LD BC,CHARS
 
                LD L,A
 
                LD H,C
 
                ADD HL,HL
 
                ADD HL,HL
 
                ADD HL,HL
 
                ADD HL,BC
 
                REPT 8
 
                LD A,(HL)
 
                LD (DE),A
 
                INC HL
 
                INC D
 
                ENDM
 
                POP HL
 
                POP DE
 
                INC DE
 
                JR PRINTMSG2
 
 
 
;УСТАНОВКА АДРЕСА РИСОВАНИЯ ИНДИКАТОРНОЙ ПОЛОСКИ
 
SETWIN_INDICAT  PUSH HL
 
                PUSH DE
 
                PUSH BC
 
                LD H,(IX)
 
                LD L,(IX+1)
 
                CALL ADRDIS
 
                LD (ADRSTARTIND),DE
 
                POP BC
 
                POP DE
 
                POP HL
 
                RET
 
 
 
;РИСОВАНИЕ СЛЕДУЮЩЕГО ЦВЕТНОГО КВАДРАТИКА
 
INC_INDICAT     PUSH HL
 
                LD HL,0
 
ADRSTARTIND     EQU $-2
 
                LD (HL),0X0F
 
                INC HL
 
                LD (ADRSTARTIND),HL
 
                POP HL
 
                RET