Subversion Repositories ngs

Rev

Rev 111 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1.  
  2. ;LAST UPDATE: 08.06.2013 savelij
  3.  
  4.                 include macros.a80
  5.                 include sdcomand.a80
  6.                 include ports_ngs.a80
  7.                 include global_vars.a80
  8.  
  9. ;КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ В ПЕРЕМЕННОЙ BYTSSEC
  10. ;КОНЕЦ ЦЕПОЧКИ НОМЕРОВ СТАРШИЙ БАЙТ 32 БИТНОГО ЧИСЛА = 0XFF
  11. ;ДЛЯ НГС РЕЖИМА УЧИТЫВАТЬ ПОЛОЖЕНИЕ СТЕКА, АДРЕС РАБОТЫ КОДА И ПОЛОЖЕНИЕ ПЕРЕМЕННЫХ
  12.  
  13. NGS             EQU 1                           ;0-КОМПИЛЯЦИЯ ДЛЯ ZSD, 1-КОМПИЛЯЦИЯ ДЛЯ NEOGS
  14. CONV_NUMSEC     EQU 1                           ;0-СОХРАНЯТЬ НОМЕР КЛАСТЕРА, 1-СОХРАНЯТЬ НОМЕР СЕКТОРА
  15.  
  16. ;СТАРТОВАЯ СТРАНИЦА ДЛЯ СПИСКА КЛАСТЕРОВ, ПО ЗАПОЛНЕНИЮ НОМЕР СТРАНИЦЫ ДЕКРЕМЕНТИТСЯ
  17.                 IF NGS=1
  18. NUM_PAGE        EQU 0X7F                        ;СТАРТОВАЯ СТРАНИЦА УКЛАДКИ КЛАСТЕРОВ/СЕКТОРОВ                        
  19. BUFF_SEC        EQU 0X5000                      ;АДРЕС БУФЕРОВ И ПЕРЕМЕННЫХ                                          
  20. ADR_LOADING     EQU 0X8000                      ;АДРЕС УКЛАДКИ НОМЕРОВ КЛАСТЕРОВ/СЕКТОРОВ                            
  21. ADR_EXEC        EQU 0X6000                      ;АДРЕС ИСПОЛНЕНИЯ КОДА                                                
  22.                 ELSE
  23. NUM_PAGE        EQU 7                           ;СТАРТОВАЯ СТРАНИЦА УКЛАДКИ КЛАСТЕРОВ/СЕКТОРОВ
  24. BUFF_SEC        EQU 0X8000                      ;АДРЕС БУФЕРОВ И ПЕРЕМЕННЫХ
  25. ADR_LOADING     EQU 0XC000                      ;АДРЕС УКЛАДКИ НОМЕРОВ КЛАСТЕРОВ/СЕКТОРОВ
  26. ADR_EXEC        EQU 0X6000                      ;АДРЕС ИСПОЛНЕНИЯ КОДА
  27.                 ENDIF
  28.  
  29.                 ORG ADR_EXEC                    ;-> ЗАМЕНИТЬ НА ЛЮБОЙ УДОБНЫЙ
  30.                 DI
  31.                 LD HL,F_PATH                    ;АДРЕС ПИТИ И ИМЕНИ ФАЙЛА ДЛЯ ПОИСКА
  32.                 LD A,NUM_PAGE                   ;НОМЕР СТРАНИЦЫ КУДА СКЛАДЫВАТЬ НОМЕРА КЛАСТЕРОВ/СЕКТОРОВ
  33.                 CALL READ_CLS
  34.                
  35.                 JR $
  36.  
  37. ;ПУТЬ ДО ФАЙЛА, ТОЛЬКО В ВЕРХНЕМ РЕГИСТРЕ ИБО ПОИСК ВЕДЕТСЯ ПО КОРОТКОМУ ИМЕНИ ВИДА 8.3
  38. F_PATH          IF NGS=0
  39.                 DB "DEMO/ANAMORIG.UDI",0
  40.                 ELSE
  41.                 DB "MP3/MIC-RO~1.MP3",0
  42.                 ENDIF
  43. ;МОЖНО УКАЗАТЬ ПУТЬ В ВИДЕ "DIR/DIR/FILE.EXT" 0 В КОНЦЕ СТРОКИ ОБЯЗАТЕЛЕН
  44.  
  45. ;---------------------------------
  46. ;ГРУЗИЛКА ФАЙЛА ПО УКАЗАННОМУ ПУТИ
  47. BUF512          EQU BUFF_SEC                    ;200 БУФЕР СЕКТОРА
  48. TDIRCLS         EQU BUF512+0X0200               ;400 БУФЕР КЛАСТЕРОВ ROOT ДИРЕКТОРИИ
  49. CAL_FAT         EQU TDIRCLS+0X0400              ;1 КАЛИБР FAT
  50. BYTSSEC         EQU CAL_FAT+1                   ;1 КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ
  51. ROOTCLS         EQU BYTSSEC+1                   ;4 КЛАСТЕР НАЧАЛА ROOT ДИРЕКТОРИИ
  52. ROOTSEC         EQU ROOTCLS+4                   ;2 РАЗМЕР В СЕКТОРАХ ROOT ДИРЕКТОРИИ
  53. SEC_FAT         EQU ROOTSEC+2                   ;4 КОЛИЧЕСТВО СЕКТОРОВ ОДНОЙ FAT
  54. RSVDSEC         EQU SEC_FAT+4                   ;2 РАЗМЕР РЕЗЕРВНОЙ ОБЛАСТИ
  55. STARTRZ         EQU RSVDSEC+2                   ;4 НАЧАЛО ДИСКА/РАЗДЕЛА
  56. FRSTDAT         EQU STARTRZ+4                   ;4 АДРЕС ПЕРВОГО СЕКТОРА ДАННЫХ ОТ BPB
  57. SEC_DSC         EQU FRSTDAT+4                   ;4 КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ/РАЗДЕЛЕ
  58. CLS_DSC         EQU SEC_DSC+4                   ;4 КОЛИЧЕСТВО КЛАСТЕРОВ НА ДИСКЕ/РАЗДЕЛЕ
  59. FATSTR          EQU CLS_DSC+4                   ;4 НАЧАЛО ПЕРВОЙ FAT ТАБЛИЦЫ
  60. ADRPATH         EQU FATSTR+4                    ;2 АДРЕС ТЕКСТА ПУТИ ФАЙЛА
  61. STATUS          EQU ADRPATH+2                   ;1 СТАТУС ПОСЛЕ ВЫЗОВА LOAD_SD
  62. OLD_SP          EQU STATUS+1                    ;2 СТЕК ДЛЯ ВЫХОДА
  63. FB_EXT          EQU OLD_SP+2                    ;B БУФЕР 8.3 ДЛЯ ПОИСКА ИМЕНИ
  64. LVL_DIR         EQU FB_EXT+0X0B                 ;1 НОМЕР УРОВНЯ ДИРЕКТОРИИ
  65. LSTLOAD         EQU LVL_DIR+1                   ;4 НОМЕР СЕКТОРА ЗАГРУЖЕННОГО В БУФЕР
  66.  
  67. ;SD КАРТА НЕ НАЙДЕНА
  68. ZAW003          LD A,0XEE
  69. WR_STAT         LD SP,(OLD_SP)
  70.                 LD (STATUS),A
  71.                 IF NGS=1
  72.                 RET
  73.                 ELSE
  74. CS__LOW         PUSH AF
  75.                 LD A,1
  76.                 OUT (P_CONF),A
  77.                 POP AF
  78.                 RET
  79.  
  80. CS_HIGH         PUSH AF
  81.                 LD A,3
  82.                 OUT (P_CONF),A
  83.                 XOR A
  84.                 OUT (P_DATA),A
  85.                 POP AF
  86.                 RET
  87.                 ENDIF
  88.  
  89. ;ЧТЕНИЕ СПИСКА КЛАСТЕРОВ ФАЙЛА
  90. ;НА ВХОДЕ:A-СТРАНИЦА НАЧАЛА ЗАГРУЗКИ
  91. ;HL-АДРЕС ТЕКСТОВОЙ СТРОКИ
  92. ;ПУТИ К ФАЙЛУ ВМЕСТЕ С ИМЕНЕМ И РАСШИРЕНИЕМ ФАЙЛА. ПУТЬ ПОЛНОСТЬЮ ОТ ROOT
  93. ;НА ВЫХОДЕ: A=
  94.                 ;0X00-OK
  95.                 ;0XAA-ФАЙЛ НЕ НАЙДЕН
  96.                 ;0XDD-FAT НЕ ОБНАРУЖЕН
  97.                 ;0XEE-SD КАРТА НЕ ОБНАРУЖЕНА
  98. READ_CLS        LD IYL,A;LY,A                   ;СОХРАНИЛИ НОМЕР СТРАНИЦЫ КУДА ГРУЗИТЬ
  99.                 LD (ADRPATH),HL                 ;СОХРАНИЛИ АДРЕС СТРОКИ ПУТИ
  100.                 LD (OLD_SP),SP                  ;СОХРАНИЛИ СТЕК
  101.                 LD A,0XFF
  102.                 LD (LSTLOAD+3),A                ;ПРИНУДИТЕЛЬНАЯ ЗАГРУЗКА СЕКТОРА БЕЗ ПРОВЕРКИ НАЛИЧИЯ В БУФЕРЕ
  103.                 IF NGS=1
  104.                 LD A,1
  105.                 OUT (GSCFG0),A                  ;ОТКЛЮЧИЛИ ПЗУ, ВСЕ СТРАНИЦА ОЗУ
  106.                 LD A,%10011011
  107.                 OUT (SCTRL),A                   ;СКОНФИГУРИЛИ НГС С CS=1 ДЛЯ SD КАРТЫ
  108.                 ELSE
  109.                 CALL CS_HIGH
  110.                 ENDIF
  111.                 LD B,0X10
  112.                 LD A,0XFF
  113.                 IF NGS=1
  114.                 OUT (SD_SEND),A                 ;ПИШЕМ 0X10 БАЙТ 0XFF В ПОРТ КАРТОЧКИ
  115.                 ELSE
  116.                 OUT (P_DATA),A
  117.                 ENDIF
  118.                 DJNZ $-4
  119.                 XOR A                           ;256 ПОПЫТОК НАЙТИ SD КАРТУ
  120.                 EX AF,AF'
  121.                 IF NGS=1
  122.                 LD A,1
  123.                 OUT (SCTRL),A                   ;ВЫБРАЛИ SD КАРТУ CS=0
  124.                 ENDIF
  125. ZAW001          LD HL,CMD00
  126.                 CALL OUTCOM                     ;ПЕРЕВОДИМ КАРТОЧКУ В РЕЖИМ SPI КОМАНДОЙ 0
  127.                 CALL IN_OOUT                    ;ЖДЕМ ОТВЕТА
  128.                 EX AF,AF'
  129.                 DEC A
  130.                 JR Z,ZAW003                     ;ЖДЕМ ПО СЧЕПТЧИКУ 256 РАЗ
  131.                 EX AF,AF'
  132.                 DEC A
  133.                 JR NZ,ZAW001                    ;ЖДЕМ ПОКА КАРТА ОТВЕТИТ БАЙТОМ 1
  134.                 LD BC,SD_RSTR
  135.                 LD HL,CMD08
  136.                 CALL OUTCOM                     ;ОПРЕДЕЛЯЕМ СПЕЦИФИКАЦИЮ КАРТЫ
  137.                 CALL IN_OOUT                    ;В "A" ОТВЕТ КАРТЫ R1
  138.                 IN H,(C)
  139.                 NOP
  140.                 IN H,(C)       
  141.                 NOP
  142.                 IN H,(C)
  143.                 NOP
  144.                 IN H,(C)                        ;ПРОЧИТАЛИ ОСТАЛЬНЫЕ БАЙТЫ В НИКУДА
  145.                 BIT 2,A                         ;ЕСЛИ ОШИБКА, ТО
  146.                 LD HL,0                         ;КАРТА СПЕЦИФИКАЦИИ 1.0
  147.                 JR NZ,ZAW006                    ;ИНАЧЕ
  148.                 LD H,0X40                       ;КАРТА СПЕЦИФИКАЦИИ 2.0
  149. ZAW006          LD A,CMD_55
  150.                 CALL OUT_COM                    ;ЗАПУСКАЕМ ВНУТРЕННЮЮ ИНИЦИАЛИЗАЦИЮ КАРТЫ
  151.                 CALL IN_OOUT
  152.                 IF NGS=1
  153.                 LD BC,SD_SEND
  154.                 ELSE
  155.                 LD BC,P_DATA
  156.                 ENDIF
  157.                 LD A,ACMD_41
  158.                 OUT (C),A
  159.                 LD A,H
  160.                 OUT (C),A
  161.                 XOR A
  162.                 OUT (C),A
  163.                 NOP
  164.                 OUT (C),A
  165.                 NOP
  166.                 OUT (C),A
  167.                 DEC A
  168.                 OUT (C),A
  169.                 CALL IN_OOUT
  170.                 AND A
  171.                 JR NZ,ZAW006                    ;ЖДЕМ ПОКА КАРТЫ ПЕРЕЙДЕТ В РЕЖИМ ГОТОВНОСТИ
  172. ZAW004          LD A,CMD_59
  173.                 CALL OUT_COM                    ;ПРИНУДИТЕЛЬНО ОТКЛЮЧАЕМ CRC16
  174.                 CALL IN_OOUT
  175.                 AND A
  176.                 JR NZ,ZAW004
  177. ZAW005          LD HL,CMD16
  178.                 CALL OUTCOM                     ;ПРИНУДИТЕЛЬНЫЙ РАЗМЕР СЕКТОРА 512 БАЙТ
  179.                 CALL IN_OOUT
  180.                 AND A
  181.                 JR NZ,ZAW005
  182.  
  183. ;ИНИЦИАЛИЗАЦИЯ ПЕРЕМЕННЫХ FAT
  184. WC_FAT          LD DE,0
  185.                 LD B,D
  186.                 LD C,E
  187.                 CALL LOADLST                    ;ЧИТАЕМ СЕКТОР 0 КАРТОЧКИ
  188.                 PUSH HL
  189.                 POP IX
  190.                 LD DE,0X01BE
  191.                 ADD HL,DE                       ;ПЕРЕХОДИМ НА СМЕЩЕНИЕ ДЛЯЧ ПРОВЕРОК
  192.                 LD A,(HL)                       ;ПРОВЕРЯМ ЧТОБЫ БЫЛ 0, КАРТОЧКИ НЕ МОГУТ БЫТЬ ЗАГРУЗОЧНЫМИ
  193.                 AND A
  194.                 JR NZ,RDFAT05                   ;ЕСЛИ НЕ 0, ПРОВЕРИТЬ ДРУГОЕ
  195.                 LD DE,4
  196.                 ADD HL,DE                       ;ПЕРЕХОДИМ К ПРОВЕРКЕ ТИПА РАЗДЕЛА
  197.                 LD A,(HL)
  198.                 LD B,0
  199.                 CP 1                            ;FAT12?
  200.                 JR Z,RDFAT06
  201.                 LD B,2
  202.                 CP 0X0B                         ;FAT32?
  203.                 JR Z,RDFAT06
  204.                 CP 0X0C                         ;FAT32?
  205.                 JR Z,RDFAT06
  206.                 LD B,1
  207.                 CP 6                            ;FAT16?
  208.                 JR Z,RDFAT06
  209.                 CP 4                            ;FAT16?
  210.                 JR Z,RDFAT06
  211.                 CP 0X0E                         ;FAT16?
  212.                 JR NZ,RDFAT05          
  213. RDFAT06         LD A,B                          ;БЕРЕМ ИЗ "B" ТИП РАЗДЕЛА
  214.                 LD (CAL_FAT),A                  ;СОХРАНИЛИ
  215.                 ADD HL,DE
  216.                 CALL LOADZP                     ;БЕРЕМ НОМЕР СЕКТОРА НАЧАЛА ОСНОВНОГО РАЗДЕЛА
  217.                 JR RDFAT00                      ;ПЕРЕХОДИМ К ИНИЦИАЛИЗАЦИИ ПЕРЕМЕННЫХ ДЛЯ РАБОТЫ С ФАТОМ
  218.  
  219. ;MBR НЕ ОБНАРУЖЕН, ПРОВЕРЯЕМ СЕКТОР 0 КАРТЫ КАК ОПИСАТЕЛЬ
  220. RDFAT05         LD C,(IX+0X0D)                  ;C=КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ
  221.                 XOR A
  222.                 LD E,A
  223.                 LD B,8
  224.                 RR C
  225.                 ADC A,0
  226.                 DJNZ $-4                        ;КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ ДОЛЖНО БЫТЬ СТЕПЕНЬЮ 2
  227.                 DEC A
  228.                 JR NZ,$+3                       ;ПРОВЕРИЛИ КОЛИЧЕСТВО БИТ
  229.                 INC E                           ;+1, ЕСТЬ ТАКОЕ
  230.                 LD A,(IX+0X0E)
  231.                 OR (IX+0X0F)
  232.                 JR Z,$+3                        ;КОЛИЧЕСТВО ЗАРЕЗЕРВИРОВАННЫХ СЕКТОРОВ ДОЛЖНО БЫТЬ >0
  233.                 INC E                           ;+1, ЕСТЬ ТАКОЕ
  234.                 LD A,(IX+0X13)
  235.                 OR (IX+0X14)
  236.                 JR NZ,$+3                       ;КОЛИЧЕСТВО СЕКТОРОВ НА РАЗДЕЛЕ ДЛЯ ФАТ16?
  237.                 INC E
  238.                 LD A,(IX+0X20)
  239.                 OR (IX+0X21)
  240.                 OR (IX+0X22)
  241.                 OR (IX+0X23)
  242.                 JR NZ,$+3                       ;КОЛИЧЕСТВО СЕКТОРОВ НА РАЗДЕЛЕ ДЛЯ ФАТ32?
  243.                 INC E                           ;ОДНО ИЗ НИХ ДОЛЖНО БЫТЬ =0, ДРУГОЕ >0
  244.                 LD A,(IX+0X15)
  245.                 AND 0XF0
  246.                 CP 0XF0
  247.                 JR NZ,$+3                       ;СТАРШИЕ БИТЫ ДОЛЖНЫ БЫТЬ В 1
  248.                 INC E
  249.                 LD A,E
  250.                 CP 4                            ;УСЛОВИЯ СОВПАЛИ?
  251.                 LD A,0XDD                       ;FAT НЕ НАЙДЕН
  252.                 JP NZ,WR_STAT
  253.                 LD A,0XFF
  254.                 LD (CAL_FAT),A                  ;ТИП ФАТ ПОКА НЕ ОПРЕДЕЛЕН
  255.                 LD DE,0
  256.                 LD B,D
  257.                 LD C,E
  258.  
  259. RDFAT00         LD (STARTRZ),DE
  260.                 LD (STARTRZ+2),BC               ;ПОЛОЖИЛИ НОМЕР СТАРТОВОГО СЕКТОРА РАЗДЕЛА
  261.                 CALL LOADLST                    ;ЗАГРУЗИЛИ ЕГО
  262.                 LD HL,0
  263.                 LD DE,(BUF512+0X16)             ;BPB_FATSZ16
  264.                 LD A,D
  265.                 OR E
  266.                 JR NZ,RDFAT01                   ;ЕСЛИ НЕ FAT12/16 (BPB_FATSZ16=0)
  267.                 LD DE,(BUF512+0X24)
  268.                 LD HL,(BUF512+0X26)             ;BPB_FATSZ32
  269.                                                 ;ТО БЕРЕМ ИЗ СМЕЩЕНИЯ +36
  270. RDFAT01         LD (SEC_FAT+2),HL
  271.                 LD (SEC_FAT),DE                 ;ЧИСЛО СЕКТОРОВ НА FAT-ТАБЛИЦУ
  272.                 LD HL,0
  273.                 LD DE,(BUF512+0X13)             ;BPB_TOTSEC16
  274.                 LD A,D
  275.                 OR E
  276.                 JR NZ,RDFAT02                   ;ЕСЛИ НЕ FAT12/16 (BPB_TOTSEC16=0)
  277.                 LD DE,(BUF512+0X20)
  278.                 LD HL,(BUF512+0X22)             ;BPB_TOTSEC32
  279.                                                 ;ТО БЕРЕМ ИЗ СМЕЩЕНИЯ +32
  280. RDFAT02         LD (SEC_DSC+2),HL
  281.                 LD (SEC_DSC),DE                 ;К-ВО СЕКТОРОВ НА ДИСКЕ/РАЗДЕЛЕ
  282.  
  283. ;ВЫЧИСЛЯЕМ ROOTDIRSECTORS
  284.                 LD BC,(BUF512+0X0B)             ;BPB_BYTSPERSEC
  285.                 LD DE,(BUF512+0X11)             ;BPB_ROOTENTCNT
  286.                 LD HL,0
  287.                 LD A,D
  288.                 OR E
  289.                 JR Z,RDFAT03
  290.                 LD B,H
  291.                 LD C,L
  292.                 LD A,0X10
  293.                 CALL BCDE_A
  294.                 EX DE,HL
  295.  
  296. ;ЭТО РЕАЛИЗОВАНА ФОРМУЛА
  297. ;ROOTDIRSECTORS=((BPB_ROOTENTCNT*32)+(BPB_BYTSPERSEC-1))/BPB_BYTSPERSEC
  298. ;В HL=ROOTDIRSECTORS. ЕСЛИ FAT32, ТО HL=0 ВСЕГДА
  299.  
  300. RDFAT03         PUSH HL                         ;ROOTDIRSECTORS
  301.                 LD (ROOTSEC),HL
  302.                 LD A,(BUF512+0X10)
  303.                 LD DE,(SEC_FAT)
  304.                 LD HL,(SEC_FAT+2)
  305.                 DEC A
  306.                 EX DE,HL
  307.                 ADD HL,HL
  308.                 EX DE,HL
  309.                 ADC HL,HL
  310.                 DEC A
  311.                 JR NZ,$-6
  312.                 POP BC                          ;ПОЛНЫЙ РАЗМЕР FAT-ОБЛАСТИ В СЕКТОРАХ
  313.                 CALL HLDEPBC                    ;ПРИБАВИЛИ ROOTDIRSECTORS
  314.                 LD BC,(BUF512+0X0E)             ;BPB_RSVDSECCNT
  315.                 LD (RSVDSEC),BC
  316.                 CALL HLDEPBC                    ;ПРИБАВИЛИ BPB_RESVDSECCNT
  317.                 LD (FRSTDAT),DE
  318.                 LD (FRSTDAT+2),HL               ;ПОЛОЖИЛИ НОМЕР ПЕРВОГО СЕКТОРА ДАННЫХ
  319.                 LD B,H
  320.                 LD C,L
  321.                 LD HL,SEC_DSC                   ;BCDE+32-ое ЧИСЛО ПО АДРЕСУ HL
  322.                 CALL BCDEHLM                    ;ВЫЧЛИ ИЗ ПОЛНОГО К-ВА СЕКТОРОВ РАЗДЕЛА
  323.                 LD A,(BUF512+0X0D)
  324.                 LD (BYTSSEC),A
  325.                 CALL BCDE_A                     ;РАЗДЕЛИЛИ НА К-ВО СЕКТОРОВ В КЛАСТЕРЕ
  326.                 LD (CLS_DSC),DE
  327.                 LD (CLS_DSC+2),BC               ;ПОЛОЖИЛИ КОЛ-ВО КЛАСТЕРОВ НА РАЗДЕЛЕ
  328.  
  329.                 LD A,(CAL_FAT)
  330.                 CP 0XFF
  331.                 JR NZ,RDFAT04
  332. ;ОПРЕДЕЛЕНИЕ ТИПА FAT ПРИ ОТСУСТВИИ MBR
  333.                 LD DE,(SEC_FAT-1)
  334.                 LD BC,(SEC_FAT+1)
  335.                 LD E,0                          ;BCDE=КОЛИЧЕСТВО СЕКТОРОВ *0X100
  336.                 PUSH BC
  337.                 PUSH DE                         ;СОХРАНИЛИ
  338.                 SRL B
  339.                 RR C
  340.                 RR D
  341.                 RR E                            ;BCDE=КОЛИЧЕСТВО СЕКТОРОВ *0X80
  342.                 LD HL,CLS_DSC                   ;КОЛИЧЕСТВО КЛАСТЕРОВ НА FAT
  343.                 PUSH HL                         ;СОХРАНИЛИ
  344.                 CALL HLBCDEM                    ;КОЛИЧЕСТВО КЛАСТЕРОВ-(КОЛИЧЕСТВО СЕКТОРОВ*0X80)
  345.                 LD A,E
  346.                 AND 0X80                        ;КОЛИЧЕСТВО МЕНЕЕ 128 КЛАСТЕРОВ В СЕКТОРЕ ДЛЯ FAT32
  347.                 OR D
  348.                 OR C
  349.                 OR B
  350.                 LD A,2
  351.                 POP HL
  352.                 POP DE
  353.                 POP BC
  354.                 JR Z,RDFAT04                    ;FAT32 ЕСЛИ ФЛАГ Z=0
  355.                 CALL HLBCDEM                    ;КОЛИЧЕСТВО КЛАСТЕРОВ-(КОЛИЧЕСТВО СЕКТОРОВ*0X100)
  356.                 LD A,D
  357.                 OR C
  358.                 OR B
  359.                 LD A,1
  360.                 JR Z,RDFAT04                    ;FAT16 ЕСЛИ ФЛАГ Z=0
  361.                 XOR A                           ;ИНАЧЕ FAT12
  362.  
  363. ;ДЛЯ FAT12/16 ВЫЧИСЛЯЕМ АДРЕС ПЕРВОГО СЕКТОРА ДИРЕКТОРИИ
  364. ;ДЛЯ FAT32 БЕРЕМ ПО СМЕЩЕМИЮ +44, НА ВЫХОДЕ BCDE-СЕКТОР ROOTDIR
  365. RDFAT04         LD (CAL_FAT),A                  ;УТОЧНИЛИ ТИП ФАТА
  366.                 EX AF,AF'
  367.                 LD DE,(RSVDSEC)
  368.                 LD BC,0
  369.                 LD HL,STARTRZ
  370.                 CALL BCDEHLP
  371.                 LD (FATSTR),DE
  372.                 LD (FATSTR+2),BC                ;ВЫЧИСЛИЛИ И ПОЛОЖИЛИ НОМЕР СЕКТОРА НАЧАЛА FAT-TАБЛИЦ
  373.                 EX AF,AF'
  374.                 AND A
  375.                 LD DE,0
  376.                 LD B,D
  377.                 LD C,E
  378.                 JR Z,FSRROO2                    ;FAT12-NONE
  379.                 DEC A
  380.                 JR Z,FSRROO2                    ;FAT16
  381.                 LD DE,(BUF512+0X2C)
  382.                 LD BC,(BUF512+0X2E)             ;FAT32
  383. FSRROO2         LD (ROOTCLS),DE
  384.                 LD (ROOTCLS+2),BC               ;ПОЛОЖИЛИ НОМЕР КЛАСТЕР ROOT ДИРЕКТОРИИ
  385.  
  386.                 XOR A
  387.                 LD (LVL_DIR),A                  ;НАЧИНАЕМ С ROOT ДИРЕКТОРИИ
  388.                 LD HL,(ADRPATH)                 ;ВЕРНУЛИ АДРЕС СТРОКИ ПУТИ ДО ФАЙЛА
  389. FINDFL1         PUSH BC
  390.                 PUSH DE                         ;СОХРАНИЛИ НОМЕР КЛАСТЕРА
  391.                 CALL FNDBUF                     ;РАСПАКОВКА ЧАСТИ ТЕКСТОВОЙ СТРОКИ ДЛЯ СОЗДАНИЯ МАСКИ ПОИСКА
  392.                 POP DE
  393.                 POP BC                          ;ВОССТАНОВИЛИ НОМЕР КЛАСТЕРА
  394.                 PUSH HL                         ;СОХРАНИЛИ ТЕКУЩИЙ АДРЕС ТЕКСТОВОЙ СТРОКИ
  395.  
  396.                 LD HL,TDIRCLS                   ;АДРЕС ТАБЛИЦЫ КЛАСТЕРОВ ТЕКУЩЕЙ ДИРЕКТОРИИ
  397.                 LD A,D
  398.                 OR E
  399.                 OR B
  400.                 OR C
  401.                 CALL SAVEZP                     ;СОХРАНИЛИ В ТАБЛИЦУ НОМЕР ТЕКУЩЕГО КЛАСТЕРА
  402.                 JR Z,LASTCLS                    ;ЕСЛИ НОМЕР КЛАСТЕРА 0, ТО ЭТО ROOT ДИРА (ДЛЯ ФАТ12/16)
  403. NEXTCLS         PUSH HL
  404.                 CALL RDFATZP                    ;ЧИТАЕМ СЛЕДУЩИЙ НОМЕР КЛАСТЕРА ИЗ ЦЕПОЧКИ ДИРЕКТОРИИ
  405.                 CALL LST_CLS                    ;ПРОВЕРЯЕМ НА КОНЕЦ ЦЕПОЧКИ
  406.                 POP HL
  407.                 JR C,LASTCLS
  408.                 CALL SAVEZP                     ;ЕСЛИ НЕ ПОСЛЕДНИЙ СОХРАНЯЕМ В ТАБЛИЦУ
  409.                 JR NEXTCLS                      ;СЛЕДУЮЩИЙ НОМЕР КЛАСТЕРА
  410.  
  411. LASTCLS         LD BC,0XFFFF
  412.                 CALL SAVEZP                     ;КЛАДЕМ МАРКЕР КОНЦА ЦЕПОЧКИ
  413.                 EXX
  414.                 LD HL,LVL_DIR
  415.                 LD A,(HL)                       ;ТЕКУЩИЙ УРОВЕНЬ ДИРЕКТОРИИ
  416.                 INC (HL)                        ;СЛЕДУЮЩИЙ УРОВЕНЬ ДИРЕКТОРИИ
  417.                 AND A
  418.                 LD BC,0                         ;КОЛИЧЕСТВО ЗАПИСЕЙ ROOT ДИРЕКТОРИИ
  419.                 JR NZ,LASTCLS1
  420.                 LD A,(CAL_FAT)
  421.                 CP 2
  422.                 JR NC,LASTCLS1
  423.                 LD HL,(ROOTSEC)                 ;УЖЕ НЕ ROOT ДИРЕКТОРИЯ
  424.                 ADD HL,HL
  425.                 ADD HL,HL
  426.                 ADD HL,HL
  427.                 ADD HL,HL
  428.                 ADD HL,HL
  429.                 LD B,H
  430.                 LD C,L
  431. LASTCLS1        EXX
  432. FINDFL          INC BC                          ;ИЩЕМ ПО ЗАДАННОЙ МАСКЕ НАЧИНАЯ С 0
  433.                 CALL RDDIRSC                    ;ГРУЗИМ ПО НОМЕРУ ОПИСАТЕЛЯ СЕКТОР ДИРЕКТОРИИ
  434.                 LD A,C
  435.                 AND 0X0F                        ;В СЕКТОРЕ МАКСИМУМ 16 ОПИСАТЕЛЕЙ
  436.                 LD E,A
  437.                 LD D,0
  438.                 EX DE,HL
  439.                 ADD HL,HL
  440.                 ADD HL,HL
  441.                 ADD HL,HL
  442.                 ADD HL,HL
  443.                 ADD HL,HL
  444.                 ADD HL,DE                       ;ПОЛУЧИЛИ АДРЕС НУЖНОГО ОПИСАТЕЛЯ
  445.                 EXX
  446.                 DEC BC
  447.                 LD A,B
  448.                 OR C                            ;ПРОВЕРКА НА ОКОНЧАНИЕ ROOT ДИРЕКТОРИИ
  449.                 EXX
  450.                 LD A,0XAA
  451.                 JP Z,WR_STAT
  452.                 LD A,(HL)                       ;ПРОВЕРЯЕМ ПЕРВЫЙ БАЙТ ИМЕНИ ОПИСАТЕЛЯ
  453.                 AND A
  454.                 LD A,0XAA                       ;ЕСЛИ БАЙТ =0, ТО
  455.                 JP Z,WR_STAT                    ;ПЕРЕХОД ПО ОШИБКЕ = ФАЙЛ НЕ НАЙДЕН
  456.                 PUSH HL
  457.                 PUSH BC
  458.                 CALL COMPARE                    ;СРАВНИВАЕМ С ЗАДАННОЙ МАСКОЙ
  459.                 POP BC
  460.                 POP DE
  461.                 PUSH DE
  462.                 POP IX                          ;СОДЕРЖИМОЕ IX=АДРЕС ОПИСАТЕЛЯ
  463.                 JR NZ,FINDFL                    ;НЕ СОВПАДАЕТ, ПЕРЕХОДИМ К СЛЕДУЮЩЕМУ ОПИСАТЕЛЮ
  464.                 CALL RD_CLAS                    ;ЗАБИРАЕМ НОМЕР КЛАСТЕРА ИЗ НАЙДЕННОГО ОПИСАТЕЛЯ
  465.                 EX (SP),HL                      ;ВОССТАНОВИЛИ ТЕКУЩИЙ АДРЕС В СТРОКЕ ПУТИ ДО ФАЙЛА
  466.                 INC SP
  467.                 INC SP                          ;МАСКИРОВКА НА СТЕКЕ АДРЕСА РАЗМЕРА В БАЙТАХ ТЕКУЩЕГО ФАЙЛА
  468.                 LD A,(HL)
  469.                 AND A                           ;ТЕКСТОВАЯ СТРОКА КОНЧИЛАСЬ?
  470.                 JR NZ,FINDFL1                   ;ЕСЛИ НЕТ, ТО ИЩЕМ ДАЛЬШЕ
  471.                 LD A,(IX+0X0B)                  ;ПРОВЕРЯЕМ ЭТО ДИРА ИЛИ ФАЙЛ?
  472.                 AND 0X10
  473.                 LD A,0XAA                       ;ЕСЛИ ДИРА, ТО ОШИБКА
  474.                 JP NZ,WR_STAT                   ;ТЕКСТОВАЯ СТРОКА ДОЛЖНА УКАЗЫВАТЬ НА ФАЙЛ
  475. FINDFL2         LD A,IYL
  476.                 DEC IYL
  477.                 IF NGS=1
  478.                 OUT (MPAG),A                    ;ВКЛЮЧАЕМ ЗАДАННУЮ СТРАНИЦУ ДЛЯ ЗАГРУЗКИ
  479.                 ELSE
  480.                 CALL PAGE_7FFD
  481.                 ENDIF
  482.                 LD HL,ADR_LOADING
  483. FINDFL3         IF CONV_NUMSEC=1
  484.                 PUSH BC
  485.                 PUSH DE
  486.                 PUSH HL
  487.                 CALL REALSEC                    ;КОНВЕРСИЯ НОМЕРА КЛАСТЕРА В НОМЕР СЕКТОРА
  488.                 POP HL
  489.                 CALL SAVEZP                     ;УКЛАДКА В БУФЕР НОМЕРА СЕКТОРА
  490.                 POP DE
  491.                 POP BC
  492.                 ELSE
  493.                 CALL SAVEZP                     ;УКЛАДКА В БУФЕР НОМЕРА КЛАСТЕРА
  494.                 ENDIF
  495.                 LD A,H
  496.                 AND A
  497.                 JR Z,FINDFL2                    ;ПРОВЕРКА НА КОНЕЦ ПАМЯТИ
  498.                 PUSH HL
  499.                 CALL RDFATZP
  500.                 CALL LST_CLS
  501.                 POP HL
  502.                 JR NC,FINDFL3
  503.                 XOR A
  504.                 LD B,0XFF
  505.                 JP SAVEZP                       ;КОНЕЦ ЦЕПОЧКИ СТАРШИЙ БАЙТ НОМЕРА = FF
  506.  
  507. SAVEZP          LD (HL),E
  508.                 INC HL
  509.                 LD (HL),D
  510.                 INC HL
  511.                 LD (HL),C
  512.                 INC HL
  513.                 LD (HL),B
  514.                 INC HL
  515.                 RET
  516.  
  517. LOADZP          LD E,(HL)
  518.                 INC HL
  519.                 LD D,(HL)
  520.                 INC HL
  521.                 LD C,(HL)
  522.                 INC HL
  523.                 LD B,(HL)
  524.                 INC HL
  525.                 RET
  526.  
  527. ;ЧТЕНИЕ СЕКТОРА DIR ПО НОМЕРУ BC
  528. RDDIRSC         PUSH BC
  529.                 LD D,B
  530.                 LD E,C
  531.                 LD BC,0
  532.                 LD A,0X10
  533.                 CALL BCDE_A
  534.                 LD A,E
  535.                 PUSH AF
  536.                 LD A,(BYTSSEC)
  537.                 PUSH AF
  538.                 CALL BCDE_A
  539.                 LD HL,TDIRCLS
  540.                 EX DE,HL
  541.                 ADD HL,HL
  542.                 ADD HL,HL
  543.                 ADD HL,DE
  544.                 CALL LOADZP
  545.                 CALL REALSEC
  546.                 POP AF
  547.                 DEC A
  548.                 LD L,A
  549.                 POP AF
  550.                 AND L
  551.                 LD L,A
  552.                 LD H,0
  553.                 ADD HL,DE
  554.                 EX DE,HL
  555.                 LD HL,0
  556.                 ADC HL,BC
  557.                 LD B,H
  558.                 LD C,L
  559.                 CALL LOADLST
  560.                 POP BC
  561.                 RET
  562.  
  563. ;ПРОВЕРКА НА ПОСЛЕДНИЙ КЛАСТЕР В ЦЕПОЧКЕ
  564. LST_CLS         LD A,(CAL_FAT)                  ;ЗАВИСИТ ОТ РАЗРЯДНОСТИ ФАТА
  565.                 AND A
  566.                 JR NZ,LST_CL1
  567.                 LD HL,0X0FF7                    ;ПРОВЕРКА ДЛЯ ФАТ12
  568.                 SBC HL,DE
  569.                 RET
  570.  
  571. LST_CL1         DEC A
  572.                 JR NZ,LST_CL2
  573. LST_CL3         LD HL,0XFFF7                    ;ПРОВЕРКАМ ДЛЯ ФАТ16 И МЛАДШИХ БИТ ФАТ32
  574.                 SBC HL,DE
  575.                 RET
  576.  
  577. LST_CL2         LD HL,0X0FFF                    ;ПРОВЕРКА ДЛЯ СТАРШИХ БИТ ФАТ32
  578.                 SBC HL,BC
  579.                 RET NZ
  580.                 JR LST_CL3
  581.  
  582. ;ЧТЕНИЕ СЛЕДУЮЩЕГО НОМЕРА КЛАСТЕРА В ЦЕПОЧКЕ
  583. RDFATZP         LD A,(CAL_FAT)                  ;ЧТЕНИЕ ЗАВИСИТ ОТ РАЗРАДНОСТИ ФАТА
  584.                 AND A
  585.                 JR Z,RDFATS0                    ;ПЕРЕХОД ВПЕРЕД ДЛЯ ФАТ12
  586.                 DEC A
  587.                 JR Z,RDFATS1                    ;ПЕРЕХОД ВПЕРЕД ДЛЯ ФАТ16
  588.                 EX DE,HL                        ;ЗДЕСЬ ЧТЕНИЕ ДЛЯ ФАТ32
  589.                 ADD HL,HL
  590.                 EX DE,HL
  591.                 LD HL,0
  592.                 ADC HL,BC
  593.                 ADC HL,BC                       ;УМНОЖИЛИ НОМЕР КЛАСТЕРА НА 2
  594.                 LD A,E
  595.                 LD E,D
  596.                 LD D,L
  597.                 LD C,H
  598.                 LD B,0                          ;РАЗДЕЛИЛИ НОМЕР КЛАСТЕРА НА 256
  599.                 CALL RDFATS2                    ;ЧИТАЕМ МЛАДШИЕ 16 БИТ ИСПОЛЬЗУЯ ЧТЕНИЕ ДЛЯ ФАТ16
  600.                 INC HL
  601.                 LD C,(HL)
  602.                 INC HL
  603.                 LD B,(HL)                       ;ПРОЧИТАЛИ ПОСЛЕДУЮЩИЕ СТАРШИЕ 16 БИТ
  604.                 RET
  605.  
  606. ;ЧТЕНИЕ 16 БИТНОГО НОМЕРА КЛАСТЕРА ИЗ ЦЕПОЧКИ ДЛЯ ФАТ16
  607. RDFATS1         LD BC,0
  608.                 LD A,E
  609.                 LD E,D
  610.                 LD D,C                          ;РАЗДЕЛИЛИ НОМЕР КЛАСТЕРА НА 256, СТАРШИЕ 16 БИТ =0
  611. RDFATS2         PUSH AF                         ;ОБЩЕЕ ЧТЕНИЕ 16 БИТНОГО НОМЕРА КЛАСТЕРА ДЛЯ ФАТ16/32
  612.                 PUSH BC
  613.                 LD HL,FATSTR
  614.                 CALL BCDEHLP                    ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА ФАТ ТАБЛИЦЫ
  615.                 CALL LOADLST                    ;ЗАГРУЗИЛИ ВЫЧИСЛЕННЫЙ НОМЕР СЕКТОРА
  616.                 POP BC
  617.                 POP AF
  618.                 LD E,A
  619.                 LD D,0
  620.                 ADD HL,DE
  621.                 ADD HL,DE                       ;ВЫЧИСЛИЛИ СМЕЩЕНИЕ ДО НУЖНОГО НОМЕРА В ЗАГРУЖЕННОМ СЕКТОРЕ
  622.                 LD E,(HL)
  623.                 INC HL
  624.                 LD D,(HL)                       ;ПОЛУЧИЛИ 16 БИТ НОМЕРА КЛАСТЕРА
  625.                 RET
  626.  
  627. ;ЧТЕНИЕ 12 БИТНОГО НОМЕРА КЛАСТЕРА ИЗ ЦЕПОЧКИ ДЛЯ ФАТ12
  628. RDFATS0         LD H,D
  629.                 LD L,E
  630.                 ADD HL,HL
  631.                 ADD HL,DE                       ;HL=HL*3
  632.                 SRL H
  633.                 RR L                            ;HL=HL/2 - В ИТОГЕ УМНОЖИЛИ НОМЕР КЛАСТЕРА НА 1,5
  634.                 LD A,E                          ;A-НАМ ИНТЕРЕСЕН ТОЛЬКО БИТ НОМЕР СТАРОГО НОМЕРА КЛАСТЕРА
  635.                 LD E,H
  636.                 LD D,0
  637.                 LD B,D
  638.                 LD C,D                          ;РАЗДЕЛИЛИ НОМЕР КЛАСТЕРА НА 256
  639.                 SRL E
  640.                 PUSH AF
  641.                 PUSH HL
  642.                 LD HL,FATSTR
  643.                 CALL BCDEHLP                    ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА ФАТ ТАБЛИЦЫ
  644.                 CALL LOADLST                    ;ЗАГРУЗИЛИ ВЫВЧИСЛЕННЫЙ СЕКТОР
  645.                 POP BC
  646.                 LD A,B
  647.                 AND 1
  648.                 LD B,A                          ;BC=СМЕЩЕНИЕ В ЗАГРУЖЕННОМ СЕКТОРЕ
  649.                 ADD HL,BC                       ;HL=АДРЕС ОТКУДА ЧИТАТЬ БАЙТЫ НОМЕРА КЛАСТЕРА
  650.                 LD B,(HL)                       ;ПРОЧИТАЛИ МЛАДШУЮ ЧАСТЬ НОМЕРА КЛАСТЕРА
  651.                 INC HL                          ;АДРЕС СЛЕДУЮЩЕГО БАЙТА
  652.                 LD A,H
  653.                 CP HIGH (BUF512)+2              ;ПРОВЕРКА НА ПЕРЕХОД ГРАНИЦЫ ЗАГРУЖЕННОГО СЕКТОРА
  654.                 JR NZ,RDFATS4
  655.                 PUSH BC                         ;ВЫХОД ЗА ПРЕДЕЛЫ ТЕКУЩЕГО ЗАГРУЖЕННОГО СЕКТОРА
  656.                 LD BC,0
  657.                 INC DE
  658.                 CALL LOADLST                    ;ЗАГРУЖАЕМ СЛЕДУЮЩИЙ СЕКТОР ФАТ ТАБЛИЦЫ
  659.                 POP BC
  660. RDFATS4         POP AF
  661.                 LD D,(HL)                       ;ЧИТАЕМ СТАРШИЕ БИТЫ НОМЕРА КЛАСТЕРА
  662.                 LD E,B                          ;ТЕПЕРЬ DE=НОМЕР СЛЕДУЮЩЕГО КЛАСТЕРА В ЦЕПОЧКЕ
  663.                 LD BC,0
  664.                 RRA                             ;ПРОВЕРЯЕМ БИТ 0 СТАРОГО НОМЕРА КЛАСТЕРА
  665.                 JR NC,RDFATS3
  666.                 SRL D                           ;СДВИГАЕМ НОМЕР ПРОЧИТАННОГО НОМЕРА КЛАСТЕРА В МЛАДШИЕ 12 БИТ
  667.                 RR E
  668.                 SRL D
  669.                 RR E
  670.                 SRL D
  671.                 RR E
  672.                 SRL D
  673.                 RR E
  674. RDFATS3         LD A,D
  675.                 AND 0X0F
  676.                 LD D,A                          ;СБРОСИЛИ НЕЗНАЧАЩИЕ СТАРШИЕ 4 БИТА У ПОЛУЧЕННОГО НОМЕРА КЛАСТЕРА
  677.                 RET
  678.  
  679. ;ВЫЧИСЛЕНИЕ РЕАЛЬНОГО СЕКТОРА
  680. ;НА ВХОДЕ BCDE=НОМЕР КЛАСТЕРА FAT
  681. ;НА ВЫХОДЕ BCDE=НОМЕР РЕАЛЬНОГО СЕКТОРА
  682. REALSEC         LD A,B
  683.                 OR C
  684.                 OR D
  685.                 OR E
  686.                 JR NZ,REALSE1                   ;BCDE=0?
  687.                 LD HL,SEC_FAT                   ;ЭТО ROOT ДИРЕКТОРИЯ У ФАТ12/16
  688.                 LD DE,(FATSTR)                  ;МЕСТОПОЛОЖЕНИЕ ROOT ДИРЫ СРАЗУ ПОСЛЕ ФАТ ТАБЛИЦЫ
  689.                 LD BC,(FATSTR+2)
  690.                 PUSH HL
  691.                 CALL BCDEHLP                    ;ПРИБАВИЛИ К НАЧАЛУ ФАТ ТАБЛИЦЫ ЕЕ РАЗМЕР
  692.                 POP HL
  693.                 JP BCDEHLP                      ;ПРИБАВИЛИ ЕЩЕ РАЗ И ПОЛУЧИЛИ НОМЕР СЕКТОРА НАЧАЛА ROOT ДИРЫ
  694.  
  695. REALSE1         LD HL,0XFFFE
  696.                 EX DE,HL
  697.                 ADD HL,DE
  698.                 EX DE,HL
  699.                 INC HL
  700.                 ADC HL,BC                       ;HLDE=НОМЕР КЛАСТЕРА-2
  701.                 LD A,(BYTSSEC)                  ;НУЖНО УМНОЖИТЬ НА РАЗМЕР КЛАСТЕРА
  702.                 JR REALSE2
  703.  
  704. REALSE3         SLA E
  705.                 RL D
  706.                 RL L
  707.                 RL H
  708. REALSE2         RRCA
  709.                 JR NC,REALSE3                   ;УМНОЖИЛИ НА РАЗМЕР КЛАСТЕРА
  710.                 LD B,H
  711.                 LD C,L
  712.                 LD HL,STARTRZ
  713.                 CALL BCDEHLP                    ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА ДИСКА
  714.                 LD HL,FRSTDAT
  715.                 JP BCDEHLP                      ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА РАЗДЕЛА
  716.  
  717. ;BCDE=BCDE/512
  718. BCDE200         LD E,D
  719.                 LD D,C
  720.                 LD C,B
  721.                 LD B,0
  722.                 LD A,2
  723.                 JR BCDE_A
  724.  
  725. ;BCDE>>A=BCDE
  726. BCDE_A1         SRL B
  727.                 RR C
  728.                 RR D
  729.                 RR E
  730. BCDE_A          RRCA
  731.                 JR NC,BCDE_A1
  732.                 RET
  733.  
  734. ;(ADR)-BCDE=BCDE
  735. BCDEHLM         LD A,(HL)
  736.                 INC HL
  737.                 SUB E
  738.                 LD E,A
  739.                 LD A,(HL)
  740.                 INC HL
  741.                 SBC A,D
  742.                 LD D,A
  743.                 LD A,(HL)
  744.                 INC HL
  745.                 SBC A,C
  746.                 LD C,A
  747.                 LD A,(HL)
  748.                 SBC A,B
  749.                 LD B,A
  750.                 RET
  751.  
  752. ;(ADR)+BCDE=BCDE
  753. BCDEHLP         LD A,(HL)
  754.                 INC HL
  755.                 ADD A,E
  756.                 LD E,A
  757.                 LD A,(HL)
  758.                 INC HL
  759.                 ADC A,D
  760.                 LD D,A
  761.                 LD A,(HL)
  762.                 INC HL
  763.                 ADC A,C
  764.                 LD C,A
  765.                 LD A,(HL)
  766.                 ADC A,B
  767.                 LD B,A
  768.                 RET
  769.  
  770. ;HLDE+BC=HLDE
  771. HLDEPBC         EX DE,HL
  772.                 ADD HL,BC
  773.                 EX DE,HL
  774.                 LD BC,0
  775.                 ADC HL,BC
  776.                 RET
  777.  
  778. ;BCDE-(ADR)=BCDE
  779. HLBCDEM         LD A,E
  780.                 SUB (HL)
  781.                 INC HL
  782.                 LD E,A
  783.                 LD A,D
  784.                 SBC A,(HL)
  785.                 INC HL
  786.                 LD D,A
  787.                 LD A,C
  788.                 SBC A,(HL)
  789.                 INC HL
  790.                 LD C,A
  791.                 LD A,B
  792.                 SBC A,(HL)
  793.                 LD B,A
  794.                 RET
  795.  
  796. ;ГРУЗИЛКА ОДНОГО СЕКТОРА
  797. LOADLST         CALL CPNUMSC                    ;ПРОВЕРКА НОМЕРА СЕКТОРА ЗАГРУЖЕННОГО В БУФЕР
  798.                 JR NZ,LOADLST1
  799.                 LD HL,BUF512                    ;В БУФЕРЕ УЖЕ ЗАГРУЖЕН УКАЗАННЫЙ СЕКТОР
  800.                 RET
  801.  
  802. LOADLST1        LD (LSTLOAD+2),BC
  803.                 LD (LSTLOAD),DE                 ;СОХРАНИЛИ НОМЕР СЕКТОРА ЗАГРУЖАЕМОГО В БУФЕР
  804.                 LD HL,BUF512                    ;АДРЕС БУФЕРА СЕКТОРА
  805.                 LD A,1                          ;ГРУЗИТЬ 1 СЕКТОР
  806.                 PUSH HL
  807.                 CALL RDMULTI                    ;ЗАГРУЗИЛИ СЕКТОР
  808.                 POP HL                          ;НА ВЫХОДЕ HL=АДРЕС НАЧАЛА БУФЕРА ЗАГРУЖЕННОГО СЕКТОРА
  809.                 RET
  810.  
  811. ;ПРОВЕРКА НА УЖЕ ЗАГРУЖЕННЫЙ СЕКТОР
  812. CPNUMSC         LD HL,LSTLOAD
  813.                 LD A,(HL)
  814.                 INC HL
  815.                 CP E
  816.                 RET NZ
  817.                 LD A,(HL)
  818.                 INC HL
  819.                 CP D
  820.                 RET NZ
  821.                 LD A,(HL)
  822.                 INC HL
  823.                 CP C
  824.                 RET NZ
  825.                 LD A,(HL)
  826.                 CP B
  827.                 RET
  828.  
  829. ;ПОДАЧА КОМАНДЫ В SD КАРТУ БЕЗ ПАРАМЕТРОВ
  830. OUTCOM          PUSH BC
  831.                 IF NGS=1
  832.                 LD BC,0X0600+SD_SEND            ;ВЫДАТЬ В ПОРТ 6 БАЙТ
  833.                 ELSE
  834.                 LD BC,0X600+P_DATA
  835.                 ENDIF
  836.                 OTIR
  837.                 POP BC
  838.                 RET
  839.  
  840. ;ВЫДАЧА В ПОРТ SD КАРТЫ КОМАНДЫ С ПАРАМЕТРОМ 0
  841. OUT_COM         PUSH BC
  842.                 IF NGS=1
  843.                 LD BC,SD_SEND
  844.                 ELSE
  845.                 CALL CS__LOW
  846.                 LD BC,P_DATA
  847.                 ENDIF
  848.                 OUT (C),A                       ;ОТПРАВИЛИ КОД КОМАНДЫ
  849.                 XOR A
  850.                 OUT (C),A                       ;БИТЫ 31-24 ПАРАМЕТРА
  851.                 NOP
  852.                 OUT (C),A                       ;БИТЫ 23-16 ПАРАМЕТРА
  853.                 NOP
  854.                 OUT (C),A                       ;БИТЫ 15-8 ПАРАМЕТРА
  855.                 NOP
  856.                 OUT (C),A                       ;БИТЫ 7-0 ПАРАМЕТРА
  857.                 DEC A
  858.                 OUT (C),A                       ;БЕЗ CRC16
  859.                 POP BC
  860.                 RET
  861.  
  862. SECM200         PUSH HL
  863.                 PUSH BC
  864.                 LD A,CMD_58
  865.                 CALL OUT_COM
  866.                 CALL IN_OOUT
  867.                 IF NGS=1
  868.                 LD BC,SD_RSTR
  869.                 ELSE
  870.                 LD BC,P_DATA
  871.                 ENDIF
  872.                 IN H,(C)
  873.                 NOP
  874.                 IN A,(C)
  875.                 NOP
  876.                 IN A,(C)
  877.                 NOP
  878.                 IN A,(C)
  879.                 BIT 6,H
  880.                 POP HL
  881.                 JR NZ,SECN200
  882.                 EX DE,HL
  883.                 ADD HL,HL
  884.                 EX DE,HL
  885.                 ADC HL,HL
  886.                 LD H,L
  887.                 LD L,D
  888.                 LD D,E
  889.                 LD E,0
  890. SECN200         LD A,CMD_18
  891.                 IF NGS=1
  892.                 LD C,SD_SEND
  893.                 ELSE
  894.                 LD C,P_DATA
  895.                 ENDIF
  896.                 OUT (C),A
  897.                 NOP
  898.                 OUT (C),H
  899.                 NOP
  900.                 OUT (C),L
  901.                 NOP
  902.                 OUT (C),D
  903.                 NOP
  904.                 OUT (C),E
  905.                 LD A,0XFF
  906.                 OUT (C),A
  907.                 POP HL
  908.                 RET
  909.  
  910. IN_OOUT         EXX
  911.                 LD DE,0X20FF
  912. IN_WAIT         IF NGS=1
  913.                 IN A,(SD_RSTR)
  914.                 ELSE
  915.                 IN A,(P_DATA)
  916.                 ENDIF
  917.                 CP E
  918.                 JR NZ,IN_EXIT
  919. IN_NEXT         DEC D
  920.                 JR NZ,IN_WAIT
  921. IN_EXIT         EXX
  922.                 RET
  923.  
  924. CMD00           DB 0X40,0X00,0X00,0X00,0X00,0X95;GO_IDLE_STATE
  925. CMD08           DB 0X48,0X00,0X00,0X01,0XAA,0X87;SEND_IF_COND
  926. CMD16           DB 0X50,0X00,0X00,0X02,0X00,0XFF;SET_BLOCKEN
  927.  
  928. ;МНОГО СЕКТОРНОЕ ЧТЕНИЕ С SD КАРТЫ
  929. RDMULTI         EX AF,AF'
  930.                 CALL SECM200
  931.                 EX AF,AF'
  932.                 IF NGS=1
  933.                 LD BC,SD_RSTR
  934.                 ELSE
  935.                 LD BC,P_DATA
  936.                 ENDIF
  937. RDMULT1         EX AF,AF'
  938.                 CALL IN_OOUT
  939.                 CP 0XFE
  940.                 JR NZ,$-5
  941.                 INIR
  942.                 NOP
  943.                 INIR
  944.                 NOP
  945.                 IN A,(C)
  946.                 NOP
  947.                 IN A,(C)
  948.                 EX AF,AF'
  949.                 DEC A
  950.                 JR NZ,RDMULT1
  951.                 LD A,CMD_12
  952.                 CALL OUT_COM
  953.                 CALL IN_OOUT
  954.                 INC A
  955.                 JR NZ,$-4
  956.                 RET
  957.  
  958. ;ВЫБОРКА НОМЕРА КЛАСТЕРА ИЗ ФАЙЛОВОГО ОПИСАТЕЛЯ
  959. RD_CLAS         EX DE,HL
  960.                 LD DE,0X14                      ;СТАРШИЕ 16 БИТ ЧИТАЕМ ИЗ СМЕЩЕНИЯ +20
  961.                 ADD HL,DE
  962.                 LD C,(HL)
  963.                 INC HL
  964.                 LD B,(HL)
  965.                 LD E,5                          ;МЛАДШИЕ 16 БИТ ЧИТАЕМ ИЗ СМЕЩЕНИЯ +26
  966.                 ADD HL,DE
  967.                 LD E,(HL)
  968.                 INC HL
  969.                 LD D,(HL)
  970.                 INC HL
  971.                 RET
  972.  
  973. PAGE_7FFD       PUSH BC
  974.                 LD BC,CONF_128
  975.                 OR 0X10
  976.                 OUT (C),A
  977.                 POP BC
  978.                 RET
  979.  
  980. ;ПРОВЕРКА ПО МАСКЕ
  981. COMPARE         LD DE,FB_EXT
  982.                 LD B,0X0B
  983.                 LD A,(DE)
  984.                 CP (HL)
  985.                 RET NZ
  986.                 INC HL
  987.                 INC DE
  988.                 DJNZ $-5
  989.                 RET
  990.  
  991. ;РАСПАКОВЩИК ПУТИ К ФАЙЛУ
  992. FNDBUF          LD BC,0X0802
  993.                 LD DE,FB_EXT
  994. FNDBUF4         LD A,(HL)
  995.                 INC HL
  996.                 CP "."
  997.                 JR Z,FNDBUF2
  998.                 CP "/"
  999.                 JR Z,FNDBUF5
  1000.                 LD (DE),A
  1001.                 INC DE
  1002.                 DJNZ FNDBUF4
  1003.                 LD A,(HL)
  1004.                 AND A
  1005.                 RET Z
  1006.                 INC HL
  1007.                 JR FNDBUF3
  1008.  
  1009. FNDBUF5         LD A,C
  1010.                 AND A
  1011.                 RET Z
  1012. FNDBUF2         LD A,B
  1013.                 AND A
  1014.                 JR Z,FNDBUF3
  1015.                 LD A," "
  1016.                 LD (DE),A
  1017.                 INC DE
  1018.                 DJNZ $-2
  1019. FNDBUF3         LD B,3
  1020.                 DEC C
  1021.                 DEC HL
  1022.                 LD A,(HL)
  1023.                 CP "/"
  1024.                 JR Z,FNDBUF4
  1025.                 INC HL
  1026.                 JR FNDBUF4
  1027.