Subversion Repositories ngs

Rev

Rev 35 | Rev 78 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. ;LAST UPDATE: 27.04.2010 savelij
  3.  
  4. DD              EQU 27                          ;ДАТА
  5. MM              EQU 4                           ;МЕСЯЦ
  6. YY              EQU 10                          ;ГОД
  7. DATA            EQU DD|MM<<5|YY<<9|#8000        ;УПАКОВАЛИ В 16 БИТ
  8.  
  9.                 INCLUDE "ports_ngs.a80"
  10.                 INCLUDE "sdcomand.a80"
  11.  
  12. ;АДРЕС ЗАГРУЗКИ НАЙДЕННОЙ ПРОШИВКИ
  13. ADRLOAD         EQU #8000
  14.  
  15. RAMCOD          EQU #4080                       ;АДРЕС РАБОТЫ ОСНОВНОГО КОДА
  16. RAM8KB          EQU #6000                       ;АДРЕС БУФЕРА ДЛЯ ПЕРЕБРОСКИ КОДА
  17. STRPAG          EQU #8000                       ;АДРЕС КУДА ЗАГРУЗКИ
  18.  
  19.                 DI
  20.                 LD SP,RAMCOD
  21.                 XOR A
  22.                 OUT (VOL1),A
  23.                 OUT (VOL2),A
  24.                 OUT (VOL3),A
  25.                 OUT (VOL4),A
  26.                 OUT (VOL5),A
  27.                 OUT (VOL6),A
  28.                 OUT (VOL7),A
  29.                 OUT (VOL8),A            ;ЗАГЛУШИЛИ МОД ПОРТЫ ДЛЯ ИСПОЛЬЗОВАНИЯ БУФЕРА
  30.  
  31. ;       JP RDBYT03-2    ОТЛАДОЧНАЯ ФИГНЯ
  32.  
  33. ;ОЖИДАНИЕ ЗАГРУЗКИ ПРОШИВКИ СО СПЕКА
  34.                 LD B,0                  ;ЧИТАЕМ 256 ПОРТ СТАТУСА
  35.                 IN A,(ZXSTAT)           ;НА ПРЕДМЕТ ИЗМЕНЕНИЯ СОСТОЯНИЯ
  36.                 RRA
  37.                 JR C,RDBYT01
  38.                 DJNZ $-5
  39.                 DEC B                   ;СЧЕТЧИК ОБНУЛИЛСЯ, СОСТОЯНИЕ ПОРТА НЕ ИЗМЕНИЛОСЬ
  40.                 JR RDBYT03              ;ГРУЗИМ СТАНДАРТНУЮ ПРОШИВКУ
  41.  
  42. RDBYT01         IN A,(ZXCMD)            ;ЧИТЕМ ПРИШЕДШИЙ БАЙТ ИЗ ПОРТА КОМАНД
  43.                 LD C,A                  ;СОХРАНИЛИ ДЛЯ ПРОВЕРКИ
  44.                 IN A,(ZXDATRD)          ;ЧИТЕМ БАЙТ ИЗ ПОРТА ДАННЫХ
  45.                 OUT (CLRCBIT),A         ;СБРОСИЛИ КОМАНД БИТ
  46.                 CP C                    ;СРАВНИВАЕМ ПРИШЕДШИЕ БАЙТЫ
  47.                 JR NZ,RDBYT03           ;НЕ СОВПАЛИ, ГРУЗИМ СТАНДАРТНУЮ ПРОШИВКУ
  48.                 CP #55                  ;ПРИШЕЛ БАЙТ #55?
  49.                 JR NZ,RDBYT03           ;ЕСЛИ НЕТ, ГРУЗИМ СТАНДАРТНУЮ ПРОШИВКУ
  50.                 LD B,0                  ;ЧИТАЕМ 256 РАЗ ИЗМЕНЕНИЕ ПОРТА КОМАНД
  51.                 IN A,(ZXSTAT)
  52.                 RRA
  53.                 JR C,RDBYT02
  54.                 DJNZ $-5
  55.                 DEC B
  56.                 JR RDBYT03              ;НЕ ДОЖДАЛИСЬ, ГРУЗИМ СТАНДАРТНУЮ ПРОШИВКУ
  57.  
  58. RDBYT02         IN A,(ZXCMD)            ;ЗАБРАЛИ БАЙТ ИЗ ПОРТА КОМАНД
  59.                 LD C,A                  ;СОХРАНИЛИ ДЛЯ ПРОВЕРКИ
  60.                 IN A,(ZXDATRD)          ;ЗАБРАЛИ БАЙТ ИЗ ПОРТА ДАННЫХ
  61.                 CP C                    ;СРАВНИЛИ
  62.                 JR NZ,RDBYT03           ;ЕСЛИ НЕ СОВПАДАЮТ, ГРУЗИМ СТАНДАРТНУЮ ПРОШИВКУ
  63.                 CP #AA                  ;ЭТО #AA?
  64. RDBYT03         EXA                     ;ВРЕМЕННО СПРЯТАЛИ ФЛАГИ ПРОЦЕССОРА
  65.                 LD HL,GRUZILA
  66.                 LD DE,RAMCOD
  67.                 LD BC,RAMCEND-VERLOAD
  68.                 LDIR                    ;ПЕРЕНЕСЛИ ОСНОВНОЙ КОД В АДРЕС РАБОТЫ
  69.                 OUT (CLRCBIT),A         ;СБРОСИЛИ КОМАНД БИТ
  70.                 EXA                     ;ВЕРНУЛИ СПРЯТАННЫЕ ФЛАГИ
  71.                 JP Z,GRUZIM2            ;ЕСЛИ ВСЕ УСЛОВИЯ СОВПАЛИ, ЗАПУСКАЕМ ЗАГРУЗЧИК
  72.                 JP GRUZIM0              ;ИНАЧЕ ГРУЗИМ СТАНДАРТНУЮ ПРОШИВКУ ИЗ ПЗУ
  73.  
  74. GRUZILA
  75.  
  76.                 DISP RAMCOD
  77.  
  78. VERLOAD         DB "Loader"
  79.                 DW DATA
  80.  
  81. ;ПУТЬ ДО ФАЙЛА ПРОШИВКИ GS
  82. F_PATH          DB 'SYSTEMZX\NEOGS\NEOGS.ROM',0         ;ТОЛЬКО ТАК ИБО УЖАСМ РЕАГИРУЕТ НА СПЕЦСИМВОЛЫ
  83.  
  84. TXT1            DB "not found",0
  85. TXT1E
  86. TXT2            DB "beta",0
  87. TXT2E
  88. TXT3            DB "stable",0
  89. TXT3E
  90.  
  91. GRUZIM0         CALL RROMSD             ;ЗАГРУЖАЕМ И ЗАПУСКАЕМ ПРОШИВКУ С SD КАРТЫ, ЕСЛИ ОНА ТАМ ЕСТЬ
  92.                 JP GS105                ;ИНАЧЕ ЗАГРУЖАЕМ ПРОШИВКУ ИЗ ПЗУ И ЗАПУСКАЕМ
  93.  
  94. GRUZIM2         LD A,#11                ;КОНФИГУРИМ НГС
  95.                 OUT (GSCFG0),A          ;ОТРУБАЕМ ПЗУ И ВРУБАЕМ ЧАСТОТУ 12МГЦ
  96.                 XOR A
  97.                 OUT (MPAG),A            ;ВКЛЮЧАЕМ СТРАНИЦУ 0
  98. GRUZIM          IN A,(ZXSTAT)           ;ПОСТОЯННО ЖДЕМ КОМАНД ОТ СПЕКА
  99.                 RRA
  100.                 JR NC,$-3
  101.                 IN A,(ZXCMD)            ;ПОЙМАЛИ КОМАНДУ
  102.                 CP #1D                  ;ЭТО КОМАНДА ПРОВЕРКИ?
  103.                 JR NZ,GRUZIM1
  104.                 LD A,#76
  105.                 OUT (ZXDATWR),A         ;ОТДАЕМ БАЙТ ИДЕНТИФИКАЦИИ ЗАГРУЗЧИКА
  106.                 OUT (CLRCBIT),A
  107.                 JR GRUZIM               ;И ПРОДОЛЖАЕМ ЖДАТЬ КОМАНД
  108.  
  109. GRUZIM1         CP #F3
  110.                 JP Z,GS105              ;ПРИ ПОСТУПЛЕНИИ КОМАНД #F3 И
  111.                 CP #F4
  112.                 JP Z,GS105              ;#F4 ЗАГРУЖАЕМ И ЗАПУСКАЕМ ПРОШИВКУ ИЗ ПЗУ
  113.                 CP LOW (FLOADE-FLOADER)/2+1
  114.                 JP NC,GS105             ;АНАЛОГИЧНО НЕ КОМАНДА ЗАГРУЗЧИКА ПЕРЕХОДИМ НА ОСНОВНОЕ ПЗУ
  115.                 ADD A,A
  116.                 LD L,A
  117.                 LD H,0
  118.                 LD DE,GRUZIM2
  119.                 PUSH DE                 ;НА СТЕКЕ АДРЕС ВОЗВРАТА ПОСЛЕ ИСПОЛНЕНИЯ КОМАНДЫ
  120.                 LD DE,FLOADER
  121.                 ADD HL,DE
  122.                 LD E,(HL)
  123.                 INC HL
  124.                 LD D,(HL)               ;ЗАБРАЛИ АДРЕС ИСПОЛНЕНИЯ КОМАНДЫ
  125.                 EX DE,HL
  126.                 JP (HL)                 ;ПОЕХАЛИ НА ИСПОЛНЕНИЕ
  127.  
  128. FLOADER         DW LOADROM              ;ЗАГРУЗКА ROM СО СПЕКА
  129.                 DW JPLDROM              ;ЗАПУСК ЗАГРУЖЕННОГО
  130.                 DW GS105                ;ЗАПУСТИТЬ ЗАШИТОЕ В ROM
  131.                 DW RROMSD               ;ЗАПУСК ROM С SD КАРТЫ
  132.                 DW LOADCOD              ;ЗАГРУЗКА КОДА СО СПЕК
  133.                 DW LDINSD               ;ЗАГРУЗКА С SD КАРТЫ
  134.                 DW RUNCOD               ;ЗАПУСК КОДА
  135.                 DW STATSD               ;СТАТУС ЗАГРУЖЕННОГО
  136.                 DW VERPAGE              ;ВЕРСИЯ FPAG ПРОШИ
  137.                 DW GET_CRC              ;ПОЛУЧИТЬ CRC16
  138. FLOADE
  139.  
  140. ;ПЕРЕДАЧА НА СПЕК ВЕРСИИ В TXT ВИДЕ
  141. VERPAGE         IN A,(ZXDATRD)          ;ЗАБРАЛИ БАЙТ НОМЕРА ЗАПРОШЕННОЙ СТРАНИЦЫ ПЗУ
  142.                 AND 7                   ;СТАРШИЕ 5 БИТ В ИГНОРЕ
  143.                 EXA                     ;ВРЕМЕННО СПРЯТАЛИ ФЛАГИ ПРОЦА
  144.                 LD A,#30
  145.                 OUT (GSCFG0),A          ;ВКЛЮЧИЛИ 10 МГЦ И ВЕРНУЛИ ПЗУ
  146.                 EXA                     ;ВЕРНУЛИ ФЛАГИ
  147.                 ADD A,A                 ;НАМ НУЖНА ВТОРЫЕ 32К СТРАНИЦЫ ПЗУ
  148.                 AND A                   ;ВЫБРАНА СТРАНИЦА 0?
  149.                 JR NZ,VERPAG1           ;ЕСЛИ НЕТ, ТО ИДЕМ НА ИЗВЛЕЧЕНИЕ ПОЛСЕДНИХ 8 БАЙТ
  150.                 LD HL,VERLOAD           ;ДЛЯ ЗАГРУЗЧИКА БЕРЕМ ИЗ ДРУГОГО АДРЕСА
  151.                 LD DE,RAMCEND
  152.                 LD BC,8
  153.                 PUSH DE
  154.                 LDIR
  155.                 POP DE
  156.                 JR VERPAG2              ;ПОШЛИ НА ПЕРЕВОДЧИК В ТЕКСТОВЫЙ ВИД
  157.  
  158. VERPAG1         INC A
  159.                 OUT (MPAG),A            ;ВКЛЮЧИЛИ ПОСЛЕДНИИ 16К ВЫБРАННОЙ СТРАНИЦЫ ПЗУ
  160.                 LD HL,#FFF8
  161.                 LD BC,8
  162.                 LD DE,RAMCEND
  163.                 PUSH DE
  164.                 LDIR                    ;ПЕРЕНЕСЛИ 8 БАЙТ ИЗ ХФОСТА ПЗУ
  165.                 POP DE
  166. VERPAG2         LD A,#11
  167.                 OUT (GSCFG0),A          ;ОТРУБИЛИ ПЗУ И ВЕРНУЛИ 12МГЦ
  168.                 XOR A
  169.                 OUT (MPAG),A            ;ВЕРНУЛИ СТРАНИЦУ 0 ОЗУ
  170.                 LD B,8                  ;ПРОВЕРЯМ ПЕРЕНЕСЕННЫЕ 8 БАЙТ, А НЕ #FF ЛИ ТАМ?
  171.                 LD A,(DE)
  172.                 INC DE
  173.                 INC A
  174.                 JR NZ,VFPGA1            ;НЕ #FF, ПРОДОЛЖАЕМ
  175.                 DJNZ $-5
  176.                 DEC SP                  ;ТАКИ ВСЕ 8 БАЙТ #FF, ВЕРСИИ У ПЗУ СТРАНИЦЫ НЕТУ
  177.                 DEC SP
  178.                 POP DE
  179.                 LD HL,TXT1
  180.                 LD BC,TXT1E-TXT1
  181.                 LDIR                    ;ОТДАТЬ ТЕКСТ ОБ ЭТОМ
  182.                 JR VFPGA0
  183.  
  184. VFPGA1          DEC SP
  185.                 DEC SP
  186.                 POP DE
  187.                 CALL UNVERS             ;РАСПАКОВКА ПОЛУЧЕННЫХ 8 БАЙТ В ТЕКСТ
  188. VFPGA0          OUT (CLRCBIT),A         ;СБРОСИЛИ КОМАНД БИТ
  189.                 LD HL,RAMCEND
  190.                 LD BC,ZXDATWR
  191. 1               LD A,(HL)
  192.                 OUTI
  193.                 EXA
  194.                 CALL WDN
  195.                 EXA
  196.                 AND A
  197.                 JR NZ,$-1B              ;ОТДАЕМ ТЕКСТ ВЕРСИИ ПОКА НЕ ВСТРЕТИТСЯ БАЙТ 0, КОТОРЫЙ ТОЖЕ ОТДАЕМ
  198.                 RET
  199.  
  200. ;РАСПАКОВЩИК ДАТЫ
  201. UNVERS          LD HL,6
  202.                 ADD HL,DE               ;ПРОПУСТИЛИ 6 БАЙТ ТЕКСТА ВЕРСИИ
  203.                 LD C,(HL)               ;ЗАБРАЛИ МЛАДШИЙ БАЙТ ВЕРСИИ
  204.                 LD (HL),#20             ;НА ЕГО МЕСТО ПРОБЕЛ
  205.                 INC HL
  206.                 LD B,(HL)               ;ЗАБРАЛИ СТАРШИЙ БАЙТ
  207.                 LD A,C                  ;ВЗЯЛИ МЛАДШИЙ БАЙТ ВЕРСИИ
  208.                 AND #1F                 ;НАС ИНТЕРЕСУЮТ МЛАДШИЕ 5 БИТ (ДЕНЬ МЕСЯЦА)
  209.                 JR NZ,$+4
  210.                 RES 7,B                 ;ЕСЛИ ПОЛУЧИЛСЯ 0, ВОЗМОЖНО ЭТО БЕТА ВЕРСИЯ
  211.                 CP 32
  212.                 JR C,$+4                ;В МЕСЯЦЕ НЕ МОЖЕТ БЫТЬ БОЛЕЕ 31 ДНЯ
  213.                 RES 7,B                 ;ИНАЧЕ ЭТО БЕТА ВЕРСИЯ
  214.                 CALL A2TXT              ;ПЕРЕВОДИМ ПОЛУЧЕННОЕ ЧИСЛО В ТЕКСТ
  215.                 SRL B                   ;СДИНУЛИ ВЕРСИЮ НА 1 БИТ ВЛЕВО ЧТОБЫ НОМЕР МЕСЯЦА
  216.                 RR C                    ;ОКАЗАЛСЯ В ОДНОМ БАЙТЕ
  217.                 LD A,C                  ;ЗАБРАЛИ ЭТОТ БАЙТ
  218.                 RRCA
  219.                 RRCA
  220.                 RRCA
  221.                 RRCA                    ;СДВИНУЛИ НУЖНЫЕ БИТЫ В МЛАДШИЕ РАЗРАДЫ БАЙТА
  222.                 AND #0F                 ;ОСТАВИЛИ НУЖНЫЕ 4 БИТА (НОМЕР МЕСЯЦА)
  223.                 JR NZ,$+4               ;НОМЕР МЕСЯЦА НЕМОЖЕТ БЫТЬ 0
  224.                 RES 6,B                 ;ИНАЧЕ ЭТО БЕТА ВЕРСИЯ
  225.                 CP 13                   ;И НОМЕР МЕСЯЦА НЕ МОЖЕТ БЫТЬ БОЛЬШЕ 12
  226.                 JR C,$+4
  227.                 RES 6,B                 ;ИНАЧЕ БЕТА ВЕРСИЯ
  228.                 LD (HL),#2E             ;ОТДЕЛИЛИ НОМЕР ДНЯ МЕСЯЦА ТОЧКОЙ
  229.                 INC HL
  230.                 CALL A2TXT              ;КОНВЕРТИРОВАЛИ НОМЕР МЕСЯЦА
  231.                 LD (HL),#2E             ;ТАК ЖЕ ОТДЕЛИЛИ ТОЧКОЙ
  232.                 INC HL
  233.                 LD A,B                  ;ВЗЯЛИ ОСТАВШИЕСЯ БИТЫ
  234.                 AND #3F                 ;НАМ НУЖНЫ 6 БИТ НОМЕРА ГОДА
  235.                 CALL A2TXT              ;КОНВЕРТНУЛИ В ТЕКСТ
  236.                 BIT 6,B                 ;БЕТА ИЛИ ЫТАБЛ ВЕРСИЯ?
  237.                 JR NZ,UNVERS1
  238.                 LD DE,TXT2              ;ВСЕ-ТАКИ БЕТА, О ЧЕМ И ДОБАВЛЯЕМ ТЕКСТ К ВЕРСИИ
  239.                 LD BC,TXT2E-TXT2
  240.                 JR UNVERS2
  241.  
  242. UNVERS1         LD DE,TXT3              ;ВЕРСИЯ СТАБЛ
  243.                 LD BC,TXT3E-TXT3
  244. UNVERS2         LD (HL),#20             ;ПЕРЕД ТЕКСТОМ (БЕТА ИЛИ СТАБЛ) ВСТАВЛЯЕМ ПРОБЕЛ
  245.                 INC HL
  246.                 EX DE,HL
  247.                 LDIR                    ;ПЕРЕТАЩИЛИ ТЕКСТ
  248.                 EX DE,HL
  249.                 LD (HL),0               ;ЗАВЕРШИЛИ СТРОКУ НУЛЕМ
  250.                 RET
  251.  
  252. ;ПЕРЕВОД "A" В ДЕСЯТИЧНЫЙ ВИД И В ТЕКСТ. ДЛЯ ЧИСЕЛ ОТ 0 ДО 99
  253. A2TXT           PUSH HL                 ;СОХРАНИЛИ АДРЕС КУДА ЛОЖИТЬ СКОНВЕРЧЕННОЕ
  254.                 LD L,A
  255.                 LD H,0
  256.                 LD DE,10
  257.                 XOR A
  258.                 DEC A
  259.                 INC A
  260.                 SBC HL,DE
  261.                 JR NC,$-3               ;СЧИТАЕМ КОЛИЧЕСТВО ДЕСЯТКОВ В ЧИСЛЕ
  262.                 ADD HL,DE               ;ВЕРНУЛИ ПЕРЕБОР ВЫЧИТАНИЯ
  263.                 ADD A,"0"               ;ПЕРЕВЕЛИ В ТЕСКТОВЫЙ ВИД ПОЛУЧЕННОЕ ЧИСЛО
  264.                 LD D,A                  ;ПОКА СОХРАНИЛИ
  265.                 LD A,L                  ;ВЗЯЛИ ОСТАВШИЕСЯ ЕДИНИЦЫ ЧИСЛА
  266.                 ADD A,"0"               ;КОНВЕРТУЛИ В ТЕКСТ
  267.                 POP HL                  ;ВЕРНУЛИ АДРЕС КУДА ЛОЖИТЬ
  268.                 LD (HL),D               ;ПОЛОЖИЛИ ДЕСЯТКИ ЗАДАННОГО ЧИСЛА
  269.                 INC HL
  270.                 LD (HL),A               ;ПОЛОЖИЛИ ЕДИНИЦЫ ТОГО ЖЕ ЧИСЛА
  271.                 INC HL
  272.                 RET
  273.  
  274. ;ЗАГРУЗКА С SD КАРТЫ ПО УКАЗАННОМУ ПУТИ
  275. ;ПЕРВЫЙ БАЙТ-НОМЕР СТРАНИЦЫ ОЗУ КУДА НАЧИНАТЬ ГРУЗИТЬ
  276. ;ДАЛЕЕ БАЙТЫ ТЕКСТОВАЯ СТРОКА ПУТИ И ИМЕНИ ФАЙЛА
  277. ;КОНЕЦ СТРОКИ БАЙТ 0, ОН ЖЕ СТОП БАЙТ
  278. LDINSD          LD BC,ZXDATRD           ;АДРЕС ПОРТА ДАННЫХ
  279.                 LD HL,RAMCEND           ;АДРЕС КУДА СТРОКУ ПУТИ СКЛАДИРОВАТЬ
  280.                 PUSH HL
  281.                 IN A,(C)                ;ПРИНЯЛИ НОМЕР СТРАНИЦЫ ОТКУДА НАЧИНАТЬ ЗАГРУЗКУ
  282.                 OUT (CLRCBIT),A         ;СБРОСИЛИ КОМАНД БИТ
  283.                 EXA
  284.                 CALL WDY
  285.                 IN A,(C)
  286.                 LD (HL),A
  287.                 INC HL
  288.                 AND A
  289.                 JR NZ,$-8               ;ПРИНИМАЕМ СТРОКУ ПОКА НЕ ВСТРЕТИСЯ БАЙТ 0
  290.                 EXA
  291.                 POP HL
  292.                 JP LOAD_SD              ;ДАЛЕЕ ЗАПУСКАЕМ ЗАГРУЗКУ С SD КАРТЫ
  293.  
  294. ;СТАТУС ЗАГРУЗКИ ФАЙЛА С SD КАРТЫ
  295. STATSD          LD A,(STATUS)
  296.                 OUT (ZXDATWR),A
  297.                 OUT (CLRCBIT),A
  298.                 RET
  299.  
  300. ;ЗАГРУЗКА И ЗАПУСК ПРОШИВКИ С SD КАРТЫ
  301. ;ИМЯ, ПУТЬ И АДРЕС ФИКСИРОВАН
  302. RROMSD          LD HL,F_PATH            ;АДРЕС СТРОКИ ФИКСИРОВАННОГО ПУТИ ДЛЯ ЗАГРУЗКИ
  303.                 XOR A
  304.                 CALL LOAD_SD            ;ЗАГРУЖАЕМ
  305.                 AND A
  306.                 RET NZ                  ;ЕСЛИ ОШИБКА, ТО ГРУЗИМ ИЗ ПЗУ
  307.                 JP JPLDROM
  308.  
  309. ;ЗАПУСК КОДА В ЛЮБОЙ СТРАНИЦЕ
  310. ;0-НОМЕР СТРАНИЦЫ ОЗУ
  311. ;1-МЛАДШИЙ БАЙТ АДРЕСА ЗАПУСКА
  312. ;2-СТАРШИЙ БАЙТ АДРЕСА ЗАПУСКА
  313. RUNCOD          LD BC,ZXDATRD           ;АДРЕС ПОРТА ДАННЫХ
  314.                 IN A,(C)                ;ПРИНЯЛИ НОМЕР С ТРАНИЦЫ ОЗУ
  315.                 OUT (CLRCBIT),A         ;СБРОСИЛИ КОМАНД БИТ
  316.                 OUT (MPAG),A
  317.                 CALL WDY
  318.                 IN L,(C)                ;ПРИНЯЛИ МЛАДШИЙ БАЙТ АДРЕСА ЗАПУСКА
  319.                 CALL WDY
  320.                 IN H,(C)                ;ПРИНЯЛИ СТАРШИЙ БАЙТ АДРЕСА ЗАПУСКА
  321.                 JP (HL)                 ;ЗАПУСКАЕМ
  322.  
  323. ;0-НОМЕР СТРАНИЦЫ ОЗУ
  324. ;1-МЛАДШИЙ БАЙТ ДЛИНЫ ЗАГРУЗКИ
  325. ;2-СТАРШИЙ БАЙТ ДЛИНЫ ЗАГРУЗКИ
  326. ;ЗАГРУЗКА НЕ БОЛЕЕ 32КБ
  327. LOADCOD         LD BC,ZXDATRD           ;АДРЕС ПОРТА ДАННЫХ
  328.                 LD HL,#8000             ;АДРЕС НАЧАЛА ЗГРУЗКИ
  329.                 IN A,(C)                ;ПРИНЯЛИ НОМЕР СТРАНИЦЫ ОЗУ
  330.                 OUT (CLRCBIT),A         ;СБРОСИЛИ КОМАНД БИТ
  331.                 OUT (MPAG),A            ;ВКЛЮЧИЛИ ЗАДАННУЮ СТРАНИЦУ ОЗУ
  332.                 CALL WDY
  333.                 IN E,(C)                ;ПРИНЯЛИ МЛАДШИЙ БАЙТ ДЛИНЫ ЗАГРУЗКИ
  334.                 CALL WDY
  335.                 IN D,(C)                ;ПРИНЯЛИ СТАРШИЙ БАЙТ ДЛИНЫ ЗГАРУЗКИ
  336. LOADCO1         CALL WDY
  337.                 INI
  338.                 LD A,H
  339.                 AND A
  340.                 RET Z                   ;ЕСЛИ ОЗУ КОНЧИЛОСЬ, ВЫХОДИМ
  341.                 DEC DE
  342.                 LD A,D
  343.                 OR E
  344.                 JR NZ,LOADCO1           ;ГРУЗИМ СКОКА УКАЗАНО
  345.                 RET
  346.  
  347. ;ЗАГРУЗКА ПРОШИВКИ 32КБ СО СПЕКА
  348. LOADROM         XOR A
  349.                 OUT (MPAG),A            ;ВКЛЮЧАЕМ СТРАНИЦУ
  350.                 LD HL,#8000             ;АДРЕС ЗАГРУЗКИ
  351.                 OUT (CLRCBIT),A         ;СБРОС КОМАНД БИТА
  352.                 LD BC,ZXDATRD           ;АДРЕС ПОРТА ДАННЫХ
  353.                 CALL WDY
  354.                 INI
  355.                 LD A,H
  356.                 AND A
  357.                 JR NZ,$-7               ;ГРУЗИМ ПОКА ПАМЯТЬ НЕ КОНЧИТСЯ
  358.                 RET
  359.  
  360. ;ГРУЗИЛКА СТАНДАРТНОЙ ПРОШИВКИ ИЗ ROM
  361. GS105           LD HL,STRPAG            ;АДРЕС КУДА ПЕРЕНОСИТЬ
  362.                 LD A,4                  ;ПЕРЕНОСИТЬ 4 КУСКА ПО 8 КИЛОБАЙТ
  363. MOV1            EXA                     ;ПРЯЧЕМ СЧЕТЧИК
  364.                 LD A,3
  365.                 OUT (GSCFG0),A          ;ВКЛЮЧИЛИ ПЗУ
  366.                 LD A,2
  367.                 OUT (MPAG),A            ;СТРАНИЦУ 2 СО СТАНДАРТНОЙ ПРОШИВКОЙ
  368.                 PUSH HL
  369.                 LD DE,RAM8KB
  370.                 LD BC,#2000
  371.                 LDIR                    ;ПЕРЕНЕСЛИ В БУФЕР 8 КИЛОБАЙТ
  372.                 LD A,#31
  373.                 OUT (GSCFG0),A          ;РТКЛЮЧИЛИ ПЗУ
  374.                 XOR A
  375.                 OUT (MPAG),A            ;ВКЛЮЧИЛИ СТРАНИЦУ 0 ОЗУ
  376.                 POP DE
  377.                 LD HL,RAM8KB
  378.                 LD BC,#2000
  379.                 LDIR                    ;ПЕРЕНЕСЛИ ИЗ БУФЕРА 8 КИЛОБАЙТ
  380.                 EX DE,HL
  381.                 EXA
  382.                 DEC A
  383.                 JR NZ,MOV1              ;И ТАК 4 РАЗА
  384.  
  385. ;ЗАПУСК ЗАГРУЖЕННОЙ ПРОШИВКИ
  386. JPLDROM         XOR A
  387.                 OUT (MPAG),A            ;ВКЛЮЧИЛИ СТРАНИЦУ 0 ОЗУ
  388.                 LD A,#13
  389.                 OUT (GSCFG0),A          ;ВКЛЮЧИЛИ ЧАСТОТУ 12МГЦ, ОТКЛЮЧИЛИ ПЗУ И ЗАЩИТИЛИ ОЗУ ОТ ЗАПИСИ
  390.                 JP 0                    ;СТАРТУЕМ СТАНДАРТНУЮ ПРОШИВКУ
  391.  
  392. ;ЖДЕМ ПОКА СПЕК ДАСТ БАЙТ
  393. WDY             IN A,(ZXSTAT)
  394.                 RLA
  395.                 JR NC,WDY
  396.                 RET
  397.  
  398. ;ЖДЕМ ПОКА СПЕК ЗАБЕРЕТ БАЙТ ИЗ ПОРТА
  399. WDN             IN A,(ZXSTAT)
  400.                 RLA
  401.                 JR C,WDN
  402.                 RET
  403.  
  404. ;ПОДСЧЕТ CRC16
  405. GET_CRC         LD A,2
  406.                 OUT (MPAG),A
  407.                 DEC A
  408.                 OUT (GSCFG0),A
  409.                 IN A,(ZXDATRD)
  410.                 CP #80
  411.                 JR C,SCHET
  412.                 LD HL,(#8000)
  413.                 LD DE,8
  414.                 AND A
  415.                 SBC HL,DE
  416.                 SRL H
  417.                 RR L
  418.                 SRL H
  419.                 RR L
  420.                 SRL H
  421.                 RR L
  422.                 SRL H
  423.                 RR L
  424.                 JR ERR_OK
  425.  
  426. SCHET           AND 7
  427.                 LD HY,A
  428.                 LD IX,#8000
  429.                 LD C,(IX)
  430.                 LD B,(IX+1)
  431.                 CALL CRC16
  432.                 LD C,(IX)
  433.                 LD B,(IX+1)
  434.                 LD A,#81
  435.                 AND A
  436.                 SBC HL,BC
  437.                 JR NZ,OUT_ERR           ;CRC16 ЗАГОЛОВКА ERROR
  438.                 LD A,HY
  439.                 ADD A,A
  440.                 ADD A,A
  441.                 ADD A,A
  442.                 ADD A,A
  443.                 LD E,A
  444.                 LD D,0
  445.                 LD IX,#8000+8
  446.                 ADD IX,DE               ;В IX АДРЕС ВЫБРАННОГО БЛОКА
  447.                 LD C,(IX+4)
  448.                 LD B,(IX+5)             ;В BC ДЛИНА БЛОКА
  449.                 LD E,(IX+1)
  450.                 LD L,(IX+2)
  451.                 LD H,(IX+3)
  452.                 LD A,L
  453.                 AND #7F
  454.                 LD D,A                  ;В DE СМЕЩЕНИЕ В СТРАНИЦЕ
  455.                 ADD HL,HL
  456.                 LD A,2
  457.                 ADD A,H
  458.                 OUT (MPAG),A            ;НОМЕР СТРАНИЦЫ
  459.                 PUSH IX
  460.                 LD IX,#8000
  461.                 ADD IX,DE               ;В IX АДРЕС НАЧАЛА БЛОКА
  462.                 CALL CRC16
  463.                 POP IX
  464.                 LD C,(IX+6)
  465.                 LD B,(IX+7)
  466.                 LD A,#82
  467.                 AND A
  468.                 SBC HL,BC
  469.                 JR NZ,OUT_ERR
  470.                 ADD HL,BC
  471. ERR_OK          LD A,#80
  472.  
  473. ;CRC16 ERROR
  474. ;#80-CRC16 БЛОКА OK
  475. ;#81-CRC16 ЗАГОЛОВКА ERROR
  476. ;#82-CRC16 БЛОКА ERROR
  477. OUT_ERR         OUT (CLRCBIT),A
  478.                 OUT (ZXDATWR),A
  479.                 CALL WDN
  480.                 LD A,L
  481.                 OUT (ZXDATWR),A
  482.                 CALL WDN
  483.                 LD A,H
  484.                 OUT (ZXDATWR),A
  485.                 RET
  486.  
  487. CRC16           LD HL,#FFFF
  488.                 LD DE,#1021
  489. CRC_0           LD A,(IX)
  490.                 INC IX
  491.                 EXA
  492.                 LD A,LX
  493.                 OR HX
  494.                 JR NZ,CRC_3
  495.                 INC LY
  496.                 LD A,LY
  497.                 OUT (MPAG),A
  498.                 LD IX,#8000
  499. CRC_3           EXA
  500.                 XOR H
  501.                 LD H,A
  502.                 LD A,8
  503. CRC_1           ADD HL,HL
  504.                 JR NC,CRC_2
  505.                 EXA
  506.                 LD A,L
  507.                 XOR E
  508.                 LD L,A
  509.                 LD A,H
  510.                 XOR D
  511.                 LD H,A
  512.                 EXA
  513. CRC_2           DEC A
  514.                 JR NZ,CRC_1
  515.                 DEC BC
  516.                 LD A,B
  517.                 OR C
  518.                 JR NZ,CRC_0
  519.                 RET
  520.  
  521. ;---------------------------------
  522. ;ГРУЗИЛКА ФАЙЛА ПО УКАЗАННОМУ ПУТИ
  523.  
  524. BUF_512         EQU #5000               ;#200 БУФЕР СЕКТОРА
  525. TDIRCLS         EQU BUF_512+#0200       ;#400 БУФЕР КЛАСТЕРОВ ROOT ДИРЕКТОРИИ
  526. CAL_FAT         EQU TDIRCLS+#0400       ;1 КАЛИБР FAT
  527. BYTSSEC         EQU CAL_FAT+1           ;1 КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ
  528. ROOTCLS         EQU BYTSSEC+1           ;4 КЛАСТЕР НАЧАЛА ROOT ДИРЕКТОРИИ
  529. ROOTSEC         EQU ROOTCLS+4           ;2 РАЗМЕР В СЕКТОРАХ ROOT ДИРЕКТОРИИ
  530. SEC_FAT         EQU ROOTSEC+2           ;4 КОЛИЧЕСТВО СЕКТОРОВ ОДНОЙ FAT
  531. RSVDSEC         EQU SEC_FAT+4           ;2 РАЗМЕР РЕЗЕРВНОЙ ОБЛАСТИ
  532. STARTRZ         EQU RSVDSEC+2           ;4 НАЧАЛО ДИСКА/РАЗДЕЛА
  533. FRSTDAT         EQU STARTRZ+4           ;4 АДРЕС ПЕРВОГО СЕКТОРА ДАННЫХ ОТ BPB
  534. SEC_DSC         EQU FRSTDAT+4           ;4 КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ/РАЗДЕЛЕ
  535. CLS_DSC         EQU SEC_DSC+4           ;4 КОЛИЧЕСТВО КЛАСТЕРОВ НА ДИСКЕ/РАЗДЕЛЕ
  536. FATSTR          EQU CLS_DSC+4           ;4 НАЧАЛО ПЕРВОЙ FAT ТАБЛИЦЫ
  537. FB_EXT          EQU FATSTR+4            ;B БУФЕР 8.3 ДЛЯ ПОИСКА ИМЕНИ
  538. ADRPATH         EQU FB_EXT+#0B          ;2 АДРЕС ТЕКСТА ПУТИ ФАЙЛА
  539. STATUS          EQU ADRPATH+2           ;1 СТАТУС ПОСЛЕ ВЫЗОВА LOAD_SD
  540. OLD_SP          EQU STATUS+1            ;2 СТЕК ДЛЯ ВЫХОДА
  541.  
  542. ;SD КАРТА НЕ НАЙДЕНА
  543. ZAW003          LD A,#EE
  544. WR_STAT         LD SP,(OLD_SP)
  545.                 LD (STATUS),A
  546.                 RET
  547.  
  548. ;ЗАГРУЗКА ФАЙЛА
  549. ;НА ВХОДЕ:A-СТРАНИЦА НАЧАЛА ЗАГРУЗКИ
  550. ;HL-АДРЕС ТЕКСТОВОЙ СТРОКИ
  551. ;ПУТИ К ФАЙЛУ ВМЕСТЕ С ИМЕНЕМ И РАСШИРЕНИЕМ ФАЙЛА. ПУТЬ ПОЛНОСТЬЮ ОТ ROOT
  552. ;ЗАГРУЖАЕТСЯ ФАЙЛ ПО РАЗМЕРУ ДОПОЛНЕНОМУ ДО ПОЛНЫХ СЕКТОРОВ (СЕКТОР 512 БАЙТ)
  553. ;ПРИМЕР: РАЗМЕР ФАЙЛА =#80-ПОСЛЕ ДОПОЛНЕНИЯ БУДЕТ ЗАГРУЖЕН 1 СЕКТОР
  554. ;=#401-БУДЕТ ЗАГРУЖЕНО 3 СЕКТОРА
  555. ;НА ВЫХОДЕ: A=
  556.                 ;#00-ФАЙЛ ЗАГРУЖЕН
  557.                 ;#AA-ФАЙЛ НЕ НАЙДЕН
  558.                 ;#DD-FAT НЕ ОБНАРУЖЕН
  559.                 ;#EE-SD КАРТА НЕ ОБНАРУЖЕНА
  560. LOAD_SD         LD LY,A                 ;СОХРАНИЛИ НОМЕР СТРАНИЦЫ КУДА ГРУЗИТЬ
  561.                 LD (ADRPATH),HL         ;СОХРАНИЛИ АДРЕС СТРОКИ ПУТИ
  562.                 LD (OLD_SP),SP          ;СОХРАНИЛИ СТЕК
  563.                 LD A,1
  564.                 OUT (GSCFG0),A          ;ОТКЛЮЧИЛИ ПЗУ, ВСЕ СТРАНИЦА ОЗУ
  565.                 LD A,%10011011
  566.                 OUT (SCTRL),A           ;СКОНФИГУРИЛИ НГС С CS=1 ДЛЯ SD КАРТЫ          
  567.                 LD B,#10
  568.                 LD A,#FF
  569.                 OUT (SD_SEND),A         ;ПИШЕМ #80 БАЙТ #FF В ПОРТ КАРТОЧКИ
  570.                 DJNZ $-4
  571.                 XOR A                   ;256 ПОПЫТОК НАЙТИ SD КАРТУ
  572.                 EXA
  573.                 LD A,1
  574.                 OUT (SCTRL),A           ;ВЫБРАЛИ SD КАРТУ CS=0
  575.  
  576. ZAW001          LD HL,CMD00
  577.                 CALL OUTCOM             ;ПЕРЕВОДИМ КАРТОЧКУ В РЕЖИМ SPI КОМАНДОЙ 0
  578.                 CALL IN_OOUT            ;ЖДЕМ ОТВЕТА
  579.                 EXA
  580.                 DEC A
  581.                 JR Z,ZAW003             ;ЖДЕМ ПО СЧЕПТЧИКУ 256 РАЗ
  582.                 EXA
  583.                 DEC A
  584.                 JR NZ,ZAW001            ;ЖДЕМ ПОКА КАРТА ОТВЕТИТ БАЙТОМ 1
  585.                 LD BC,SD_RSTR
  586.                 LD HL,CMD08
  587.                 CALL OUTCOM             ;ОПРЕДЕЛЯЕМ СПЕЦИФИКАЦИЮ КАРТЫ
  588.                 CALL IN_OOUT            ;В "A" ОТВЕТ КАРТЫ R1
  589.                 IN H,(C)
  590.                 NOP
  591.                 IN H,(C)       
  592.                 NOP
  593.                 IN H,(C)
  594.                 NOP
  595.                 IN H,(C)                ;ПРОЧИТАЛИ ОСТАЛЬНЫЕ БАЙТЫ В НИКУДА
  596.                 BIT 2,A                 ;ЕСЛИ ОШИБКА, ТО
  597.                 LD HL,0                 ;КАРТА СПЕЦИФИКАЦИИ 1.0
  598.                 JR NZ,ZAW006            ;ИНАЧЕ
  599.                 LD H,#40                ;КАРТА СПЕЦИФИКАЦИИ 2.0
  600. ZAW006          LD A,CMD_55
  601.                 CALL OUT_COM            ;ЗАПУСКАЕМ ВНУТРЕННЮЮ ИНИЦИАЛИЗАЦИЮ КАРТЫ
  602.                 CALL IN_OOUT
  603.                 LD BC,SD_SEND
  604.                 LD A,ACMD_41
  605.                 OUT (C),A
  606.                 LD A,H
  607.                 OUT (C),A
  608.                 XOR A
  609.                 OUT (C),A
  610.                 NOP
  611.                 OUT (C),A
  612.                 NOP
  613.                 OUT (C),A
  614.                 DEC A
  615.                 OUT (C),A
  616.                 CALL IN_OOUT
  617.                 AND A
  618.                 JR NZ,ZAW006            ;ЖДЕМ ПОКА КАРТЫ ПЕРЕЙДЕТ В РЕЖИМ ГОТОВНОСТИ
  619. ZAW004          LD A,CMD_59
  620.                 CALL OUT_COM            ;ПРИНУДИТЕЛЬНО ОТКЛЮЧАЕМ CRC16
  621.                 CALL IN_OOUT
  622.                 AND A
  623.                 JR NZ,ZAW004
  624. ZAW005          LD HL,CMD16
  625.                 CALL OUTCOM             ;ПРИНУДИТЕЛЬНЫЙ РАЗМЕР СЕКТОРА 512 БАЙТ
  626.                 CALL IN_OOUT
  627.                 AND A
  628.                 JR NZ,ZAW005
  629.  
  630. ;ИНИЦИАЛИЗАЦИЯ ПЕРЕМЕННЫХ FAT
  631. WC_FAT          LD DE,0
  632.                 LD B,D
  633.                 LD C,E
  634.                 CALL LOADLST            ;ЧИТАЕМ СЕКТОР 0 КАРТОЧКИ
  635.                 PUSH HL
  636.                 POP IX
  637.                 LD DE,#01BE
  638.                 ADD HL,DE               ;ПЕРЕХОДИМ НА СМЕЩЕНИЕ ДЛЯЧ ПРОВЕРОК
  639.                 LD A,(HL)               ;ПРОВЕРЯМ ЧТОБЫ БЫЛ 0, КАРТОЧКИ НЕ МОГУТ БЫТЬ ЗАГРУЗОЧНЫМИ
  640.                 AND A
  641.                 JR NZ,RDFAT05           ;ЕСЛИ НЕ 0, ПРОВЕРИТЬ ДРУГОЕ
  642.                 LD DE,4
  643.                 ADD HL,DE               ;ПЕРЕХОДИМ К ПРОВЕРКЕ ТИПА РАЗДЕЛА
  644.                 LD A,(HL)
  645.                 LD B,0
  646.                 CP 1                    ;FAT12?
  647.                 JR Z,RDFAT06
  648.                 LD B,2
  649.                 CP #0B                  ;FAT32?
  650.                 JR Z,RDFAT06
  651.                 CP #0C                  ;FAT32?
  652.                 JR Z,RDFAT06
  653.                 LD B,1
  654.                 CP 6                    ;FAT16?
  655.                 JR Z,RDFAT06
  656.                 CP #0E                  ;FAT16?
  657.                 JR NZ,RDFAT05          
  658. RDFAT06         LD A,B                  ;БЕРЕМ ИЗ "B" ТИП РАЗДЕЛА
  659.                 LD (CAL_FAT),A          ;СОХРАНИЛИ
  660.                 ADD HL,DE
  661.                 CALL LOADZP             ;БЕРЕМ НОМЕР СЕКТОРА НАЧАЛА ОСНОВНОГО РАЗДЕЛА
  662.                 JR RDFAT00              ;ПЕРЕХОДИМ К ИНИЦИАЛИЗАЦИИ ПЕРЕМЕННЫХ ДЛЯ РАБОТЫ С ФАТОМ
  663.  
  664. ;MBR НЕ ОБНАРУЖЕН, ПРОВЕРЯЕМ СЕКТОР 0 КАРТЫ КАК ОПИСАТЕЛЬ
  665. RDFAT05         LD C,(IX+#0D)           ;C=КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ
  666.                 XOR A
  667.                 LD E,A
  668.                 LD B,8
  669.                 RR C
  670.                 ADC A,0
  671.                 DJNZ $-4                ;КОЛИЧЕСТВО СЕКТОРОВ В КЛАСТЕРЕ ДОЛЖНО БЫТЬ СТЕПЕНЬЮ 2
  672.                 DEC A
  673.                 JR NZ,$+3               ;ПРОВЕРИЛИ КОЛИЧЕСТВО БИТ
  674.                 INC E                   ;+1, ЕСТЬ ТАКОЕ
  675.                 LD A,(IX+#0E)
  676.                 OR (IX+#0F)
  677.                 JR Z,$+3                ;КОЛИЧЕСТВО ЗАРЕЗЕРВИРОВАННЫХ СЕКТОРОВ ДОЛЖНО БЫТЬ >0
  678.                 INC E                   ;+1, ЕСТЬ ТАКОЕ
  679.                 LD A,(IX+#13)
  680.                 OR (IX+#14)
  681.                 JR NZ,$+3               ;КОЛИЧЕСТВО СЕКТОРОВ НА РАЗДЕЛЕ ДЛЯ ФАТ16?
  682.                 INC E
  683.                 LD A,(IX+#20)
  684.                 OR (IX+#21)
  685.                 OR (IX+#22)
  686.                 OR (IX+#23)
  687.                 JR NZ,$+3               ;КОЛИЧЕСТВО СЕКТОРОВ НА РАЗДЕЛЕ ДЛЯ ФАТ32?
  688.                 INC E                   ;ОДНО ИЗ НИХ ДОЛЖНО БЫТЬ =0, ДРУГОЕ >0
  689.                 LD A,(IX+#15)
  690.                 AND #F0
  691.                 CP #F0
  692.                 JR NZ,$+3               ;СТАРШИЕ БИТЫ ДОЛЖНЫ БЫТЬ В 1
  693.                 INC E
  694.                 LD A,E
  695.                 CP 4                    ;УСЛОВИЯ СОВПАЛИ?
  696.                 LD A,#DD                ;FAT НЕ НАЙДЕН
  697.                 JP NZ,WR_STAT
  698.                 LD A,#FF
  699.                 LD (CAL_FAT),A          ;ТИП ФАТ ПОКА НЕ ОПРЕДЕЛЕН
  700.                 LD DE,0
  701.                 LD B,D
  702.                 LD C,E
  703.  
  704. RDFAT00         LD (STARTRZ),DE
  705.                 LD (STARTRZ+2),BC       ;ПОЛОЖИЛИ НОМЕР СТАРТОВОГО СЕКТОРА РАЗДЕЛА
  706.                 CALL LOADLST            ;ЗАГРУЗИЛИ ЕГО
  707.                 LD HL,0
  708.                 LD DE,(BUF_512+#16)     ;BPB_FATSZ16
  709.                 LD A,D
  710.                 OR E
  711.                 JR NZ,RDFAT01           ;ЕСЛИ НЕ FAT12/16 (BPB_FATSZ16=0)
  712.                 LD DE,(BUF_512+#24)
  713.                 LD HL,(BUF_512+#26)     ;BPB_FATSZ32
  714.                                         ;ТО БЕРЕМ ИЗ СМЕЩЕНИЯ +36
  715. RDFAT01         LD (SEC_FAT+2),HL
  716.                 LD (SEC_FAT),DE         ;ЧИСЛО СЕКТОРОВ НА FAT-ТАБЛИЦУ
  717.                 LD HL,0
  718.                 LD DE,(BUF_512+#13)     ;BPB_TOTSEC16
  719.                 LD A,D
  720.                 OR E
  721.                 JR NZ,RDFAT02           ;ЕСЛИ НЕ FAT12/16 (BPB_TOTSEC16=0)
  722.                 LD DE,(BUF_512+#20)
  723.                 LD HL,(BUF_512+#22)     ;BPB_TOTSEC32
  724.                                         ;ТО БЕРЕМ ИЗ СМЕЩЕНИЯ +32
  725. RDFAT02         LD (SEC_DSC+2),HL
  726.                 LD (SEC_DSC),DE         ;К-ВО СЕКТОРОВ НА ДИСКЕ/РАЗДЕЛЕ
  727.  
  728. ;ВЫЧИСЛЯЕМ ROOTDIRSECTORS
  729.                 LD BC,(BUF_512+#0B)     ;BPB_BYTSPERSEC
  730.                 LD DE,(BUF_512+#11)     ;BPB_ROOTENTCNT
  731.                 LD HL,0
  732.                 LD A,D
  733.                 OR E
  734.                 JR Z,RDFAT03
  735.                 LD B,H
  736.                 LD C,L
  737.                 LD A,#10
  738.                 CALL BCDE_A
  739.                 EX DE,HL
  740.  
  741. ;ЭТО РЕАЛИЗОВАНА ФОРМУЛА
  742. ;ROOTDIRSECTORS=((BPB_ROOTENTCNT*32)+(BPB_BYTSPERSEC-1))/BPB_BYTSPERSEC
  743. ;В HL=ROOTDIRSECTORS. ЕСЛИ FAT32, ТО HL=0 ВСЕГДА
  744.  
  745. RDFAT03         PUSH HL                 ;ROOTDIRSECTORS
  746.                 LD (ROOTSEC),HL
  747.                 LD A,(BUF_512+#10)
  748.                 LD DE,(SEC_FAT)
  749.                 LD HL,(SEC_FAT+2)
  750.                 DEC A
  751.                 EX DE,HL
  752.                 ADD HL,HL
  753.                 EX DE,HL
  754.                 ADC HL,HL
  755.                 DEC A
  756.                 JR NZ,$-6
  757.                 POP BC                  ;ПОЛНЫЙ РАЗМЕР FAT-ОБЛАСТИ В СЕКТОРАХ
  758.                 CALL HLDEPBC            ;ПРИБАВИЛИ ROOTDIRSECTORS
  759.                 LD BC,(BUF_512+#0E)     ;BPB_RSVDSECCNT
  760.                 LD (RSVDSEC),BC
  761.                 CALL HLDEPBC            ;ПРИБАВИЛИ BPB_RESVDSECCNT
  762.                 LD (FRSTDAT),DE
  763.                 LD (FRSTDAT+2),HL       ;ПОЛОЖИЛИ НОМЕР ПЕРВОГО СЕКТОРА ДАННЫХ
  764.                 LD B,H
  765.                 LD C,L
  766.                 LD HL,SEC_DSC           ;BCDE+32-ое ЧИСЛО ПО АДРЕСУ HL
  767.                 CALL BCDEHLM            ;ВЫЧЛИ ИЗ ПОЛНОГО К-ВА СЕКТОРОВ РАЗДЕЛА
  768.                 LD A,(BUF_512+#0D)
  769.                 LD (BYTSSEC),A
  770.                 CALL BCDE_A             ;РАЗДЕЛИЛИ НА К-ВО СЕКТОРОВ В КЛАСТЕРЕ
  771.                 LD (CLS_DSC),DE
  772.                 LD (CLS_DSC+2),BC       ;ПОЛОЖИЛИ КОЛ-ВО КЛАСТЕРОВ НА РАЗДЕЛЕ
  773.  
  774.                 LD A,(CAL_FAT)
  775.                 CP #FF
  776.                 JR NZ,RDFAT04
  777.                 LD HL,(CLS_DSC)         ;ЕСЛИ РАЗРФДНОСТЬ ФАТА НЕ ОПРЕДЕЛЕНА, ОПРЕДЕЛЯЕМ
  778.                 LD DE,(CLS_DSC+2)       ;ВЗЯЛИ КОЛИЧЕСТВО КЛАСТЕРОВ НА РАЗДЕЛЕ
  779.                 PUSH HL
  780.                 PUSH DE
  781.                 ADD HL,HL
  782.                 EX DE,HL
  783.                 ADC HL,HL
  784.                 LD B,H
  785.                 LD C,L
  786.                 CALL RASCHET            ;СЧИТАЕМ, ЕСЛИ ПОЛУЧИЛИ 0, ТО ФАТ16
  787.                 LD A,1
  788.                 POP DE
  789.                 POP HL
  790.                 JR Z,RDFAT04
  791.                 ADD HL,HL
  792.                 EX DE,HL
  793.                 ADC HL,HL
  794.                 EX DE,HL
  795.                 ADD HL,HL
  796.                 EX DE,HL
  797.                 ADC HL,HL
  798.                 LD B,H
  799.                 LD C,L
  800.                 CALL RASCHET            ;СЧИТАЕМ, ЕСЛИ ПОЛУЧИЛИ 0, ТО ФАТ32
  801.                 LD A,2
  802.                 JR Z,RDFAT04
  803.                 XOR A                   ;ИНАЧЕ ФАТ12
  804.  
  805. ;ДЛЯ FAT12/16 ВЫЧИСЛЯЕМ АДРЕС ПЕРВОГО СЕКТОРА ДИРЕКТОРИИ
  806. ;ДЛЯ FAT32 БЕРЕМ ПО СМЕЩЕМИЮ +44, НА ВЫХОДЕ BCDE-СЕКТОР ROOTDIR
  807. RDFAT04         PUSH AF
  808.                 LD DE,(RSVDSEC)
  809.                 LD BC,0
  810.                 LD HL,STARTRZ
  811.                 CALL BCDEHLP
  812.                 LD (FATSTR),DE
  813.                 LD (FATSTR+2),BC        ;ВЫЧИСЛИЛИ И ПОЛОЖИЛИ НОМЕР СЕКТОРА НАЧАЛА FAT-ЕАБЛИЦ
  814.                 POP AF
  815.                 LD (CAL_FAT),A          ;УТОЧНИЛИ ТИП ФАТА
  816.                 AND A
  817.                 LD DE,0
  818.                 LD B,D
  819.                 LD C,E
  820.                 JR Z,FSRROO2            ;FAT12-NONE
  821.                 DEC A
  822.                 JR Z,FSRROO2            ;FAT16
  823.                 LD DE,(BUF_512+#2C)
  824.                 LD BC,(BUF_512+#2E)     ;FAT32
  825. FSRROO2         LD (ROOTCLS),DE
  826.                 LD (ROOTCLS+2),BC       ;ПОЛОЖИЛИ НОМЕР КЛАСТЕР ROOT ДИРЕКТОРИИ
  827.  
  828.                 LD HL,(ADRPATH)         ;ВЕРНУЛИ АДРЕС СТРОКИ ПУТИ ДО ФАЙЛА
  829. FINDFL1         PUSH BC
  830.                 PUSH DE                 ;СОХРАНИЛИ НОМЕР КЛАСТЕРА
  831.                 CALL FNDBUF             ;РАСПАКОВКА ЧАСТИ ТЕКСТОВОЙ СТРОКИ ДЛЯ СОЗДАНИЯ МАСКИ ПОИСКА
  832.                 POP DE
  833.                 POP BC                  ;ВОССТАНОВИЛИ НОМЕР КЛАСТЕРА
  834.                 PUSH HL                 ;СОХРАНИЛИ ТЕКУЩИЙ АДРЕС ТЕКСТОВОЙ СТРОКИ
  835.  
  836.                 LD HL,TDIRCLS           ;АДРЕС ТАБЛИЦЫ КЛАСТЕРОВ ТЕКУЩЕЙ ДИРЕКТОРИИ
  837.                 LD A,D
  838.                 OR E
  839.                 OR B
  840.                 OR C
  841.                 CALL SAVEZP             ;СОХРАНИЛИ В ТАБЛИЦУ НОМЕР ТЕКУЩЕГО КЛАСТЕРА
  842.                 JR Z,LASTCLS            ;ЕСЛИ НОМЕР КЛАСТЕРА 0, ТО ЭТО ROOT ДИРА (ДЛЯ ФАТ12/16)
  843. NEXTCLS         PUSH HL
  844.                 CALL RDFATZP            ;ЧИТАЕМ СЛЕДУЩИЙ НОМЕР КЛАСТЕРА ИЗ ЦЕПОЧКИ ДИРЕКТОРИИ
  845.                 CALL LST_CLS            ;ПРОВЕРЯЕМ НА КОНЕЦ ЦЕПОЧКИ
  846.                 POP HL
  847.                 JR C,LASTCLS
  848.                 CALL SAVEZP             ;ЕСЛИ НЕПОСЛЕДНИЙ СОХРАНЯЕМ В ТАБЛИЦУ
  849.                 JR NEXTCLS              ;СЛЕДУЮЩИЙ НОМЕР КЛАСТЕРА
  850.  
  851. LASTCLS         LD BC,#FFFF
  852.                 CALL SAVEZP             ;КЛАДЕМ МАРКЕР КОНЦА ЦЕПОЧКИ
  853.  
  854. FINDFL          INC BC                  ;ИЩЕМ ПО ЗАДАННОЙ МАСКЕ НАЧИНАЯ С 0
  855.                 CALL RDDIRSC            ;ГРУЗИМ ПО НОМЕРУ ОПИСАТЕЛЯ СЕКТОР ДИРЕКТОРИИ
  856.                 LD A,C
  857.                 AND #0F                 ;В СЕКТОРЕ МАКСИМУМ 16 ОПИСАТЕЛЕЙ
  858.                 LD E,A
  859.                 LD D,0
  860.                 EX DE,HL
  861.                 ADD HL,HL
  862.                 ADD HL,HL
  863.                 ADD HL,HL
  864.                 ADD HL,HL
  865.                 ADD HL,HL
  866.                 ADD HL,DE               ;ПОЛУЧИЛИ АДРЕС НУЖНОГО ОПИСАТЕЛЯ
  867.                 LD A,(HL)               ;ПРОВЕРЯЕМ ПЕРВЫЙ БАЙТ ИМЕНИ ОПИСАТЕЛЯ
  868.                 AND A
  869.                 LD A,#AA                ;ЕСЛИ БАЙТ =0, ТО
  870.                 JP Z,WR_STAT            ;ПЕРЕХОД ПО ОШИБКЕ = ФАЙЛ НЕ НАЙДЕН
  871.                 PUSH HL
  872.                 PUSH BC
  873.                 CALL COMPARE            ;СРАВНИВАЕМ С ЗАДАННОЙ МАСКОЙ
  874.                 POP BC
  875.                 POP DE
  876.                 PUSH DE
  877.                 POP IX                  ;СОДЕРЖИМОЕ IX=АДРЕС ОПИСАТЕЛЯ
  878.                 JR NZ,FINDFL            ;НЕ СОВПАДАЕТ, ПЕРЕХОДИМ К СЛЕДУЮЩЕМУ ОПИСАТЕЛЮ
  879.                 CALL RD_CLAS            ;ЗАБИРАЕМ НОМЕР КЛАСТЕРА ИЗ НАЙДЕННОГО ОПИСАТЕЛЯ
  880.                 EX (SP),HL              ;ВОССТАНОВИЛИ ТЕКУЩИЙ АДРЕС В СТРОКЕ ПУТИ ДО ФАЙЛА
  881.                 INC SP
  882.                 INC SP                  ;МАСКИРОВКА НА СТЕКЕ АДРЕСА РАЗМЕРА В БАЙТАХ ТЕКУЩЕГО ФАЙЛА
  883.                 LD A,(HL)
  884.                 AND A                   ;ТЕКСТОВАЯ СТРОКА КОНЧИЛАСЬ?
  885.                 JR NZ,FINDFL1           ;ЕСЛИ НЕТ, ТО ИЩЕМ ДАЛЬШЕ
  886.                 LD A,(IX+#0B)           ;ПРОВЕРЯЕМ ЭТО ДИРА ИЛИ ФАЙЛ?
  887.                 AND #10
  888.                 LD A,#AA                ;ЕСЛИ ДИРА, ТО ОШИБКА
  889.                 JP NZ,WR_STAT           ;ТЕКСТОВАЯ СТРОКА ДОЛЖНА УКАЗЫВАТЬ НА ФАЙЛ
  890.                 DEC SP
  891.                 DEC SP
  892.                 POP HL                  ;ВОССТАНОВИЛИ В HL АДРЕС ОТКУДА ВЗЯТЬ РАЗМЕР ФАЙЛА В БАЙТАХ
  893.                 PUSH BC
  894.                 PUSH DE
  895.                 CALL LOADZP             ;ЗАБИРАЕМ РАЗМЕР ФАЙЛА (В БАЙТАХ)
  896.                 LD A,E
  897.                 AND A
  898.                 JR Z,$+3                ;МЛАДШИЙ БАЙТ РАЗМЕРА ФАЙЛА =0?
  899.                 INC D                   ;УВЕЛИЧИВАЕМ РАЗМЕР НА 256 БАЙТ БЕЗ УЧЕТА МЛАДШЕГО БАЙТА
  900.                 BIT 0,D                 ;ПРОВЕРЯЕМ ЧЕТ/НЕЧЕТ
  901.                 JR Z,$+3                ;ЕСЛИ НЕЧЕТ, ТО
  902.                 INC D                   ;УВЕЛИЧИВАЕМ РАЗМЕР ЕЩЕ НА 256 БАЙТ
  903.                 CALL BCDE200            ;ДЕЛИМ НА 512 (НА РАЗМЕР СЕКТОР)
  904.                 PUSH DE
  905.                 EXX
  906.                 POP HL
  907.                 EXX
  908.                 LD A,(BYTSSEC)          ;ВЗЯЛИ РАЗМЕР КЛАСТЕРА В СЕКТОРАХ
  909.                 LD HX,A                 ;СОХРАНИЛИ
  910.                 POP DE
  911.                 POP BC
  912.                 LD HL,#8000             ;АДРЕС ЗАГРУЗКИ
  913.  
  914. ;HX-РАЗМЕР КЛАСТЕРА
  915. ;HL'-КОЛ-ВО СЕКТОРОВ ФАЙЛА
  916. ;BCDE-НОМЕР СТАРТОВОГО КЛАСТЕРА
  917. ;LY-СТАРТОВАЯ СТРАНИЦА ЗАГРУЗКИ
  918.  
  919.                 LD A,LY                 ;ВОССТАНОВИЛИ СТРАНИЦУ ЗАГРУЗКИ
  920.                 AND A
  921.                 JR NZ,CP_PAGE           ;ПРОВЕРКА ДЛЯ ЗАГРУЗКИ В СТРАНИЦУ 0
  922.                 OUT (MPAG),A            ;ВКЛЮЧАЕМ СТРАНИЦУ 0
  923.                 EXX
  924.                 LD A,L
  925.                 LD DE,#41
  926.                 SBC HL,DE
  927.                 JR C,$+4                ;ЕСЛИ ФАЙЛ #41 И БОЛЕЕ СЕКТОРОВ
  928.                 LD A,#40                ;ТО ГРУЗИМ ТОЛЬКО #40 ПЕРВЫХ СЕКТОРОВ
  929.                 EXX
  930.                 JP LDMINI               ;ПЕРЕХОДИМ НА ЗАГРУЗКУ
  931.  
  932. ;ЗАГРУЗКА В СТРАНИЦУ 1 ЗАПРЕЩЕНА
  933. CP_PAGE         DEC A
  934.                 LD A,#AA
  935.                 JP Z,WR_STAT
  936.                 LD A,LY
  937.  
  938. ;ВКЛЮЧАЕМ СТРАНИЦУ ЗАГРУЗКИ
  939. LDFILE0         OUT (MPAG),A            ;ВКЛЮЧАЕМ ЗАДАННУЮ СТРАНИЦУ ДЛЯ ЗАГРУЗКИ
  940.  
  941. ;ЗАГРУЗКА В СТРАНИЦЫ 02...7F
  942. LD_FILE         EXX
  943.                 LD E,HX
  944.                 LD D,0                  ;DE=РАЗМЕР КЛАСТЕРА В СЕКТОРАХ
  945.                 AND A
  946.                 SBC HL,DE               ;СВЕРЯЕМ С КОЛИЧЕСТВОМ СЕКТОРОВ ДЛЯ ЗАГРУЗКИ
  947.                 LD LX,HX                ;LX=КОЛИЧЕСТВО СЕКТОРОВ ДЛЯ ЗАГРУЗКИ
  948.                 EXX
  949.                 JR NC,LDFILE1
  950.                 EXX                     ;СЕКТОРОВ ДЛЯ ЗАГРУЗКИ МЕНЬШЕ РАЗМЕРА КЛАСТЕРА
  951.                 ADD HL,DE      
  952.                 LD A,L
  953.                 LD LX,A                 ;LX=КОЛИЧЕСТВО СЕКТОРОВ ДЛЯ ЗАГРУЗКИ
  954.                 EXX
  955.  
  956. LDFILE1         PUSH BC
  957.                 PUSH DE
  958.                 PUSH HL
  959.                 CALL REALSEC            ;ПЕРЕВЕЛИ НОМЕР КЛАСТЕРА В НОМЕР РЕАЛЬНОГО СЕКТОРА
  960.                 LD A,LX
  961.                 CP #41                  ;КОЛИЧЕСТВО СЕКТОРОВ ДЛЯ ЗАГРУЗКИ БОЛЬШЕ #40?
  962.                 JR C,$+4
  963.                 LD A,#40                ;БУДЕМ ГРУЗИТЬ #40 СЕКТОРОВ
  964.                 POP HL
  965.                 LD HY,A
  966.                 CALL RDMULTI            ;ЗАГРУЖАЕМ СЕКТОРА
  967.                 LD A,HX
  968.                 AND #80
  969.                 JR Z,LDFILE2
  970.                 LD A,LX
  971.                 SUB HY
  972.                 JR Z,LDFILE4
  973.                 JR C,LDFILE4
  974.                 LD HL,#40
  975.                 ADD HL,DE
  976.                 EX DE,HL
  977.                 LD HL,0
  978.                 ADC HL,BC
  979.                 LD B,H
  980.                 LD C,L
  981.                 LD L,A
  982.                 INC LY
  983.                 LD A,LY
  984.                 CP #40
  985.                 JR C,LDFILE3
  986. LDFILE4         INC SP
  987.                 INC SP
  988.                 INC SP
  989.                 INC SP
  990.                 JR LDEFILE
  991.  
  992. LDFILE3         OUT (MPAG),A            ;СЛЕДУЮЩАЯ СТРАНИЦА
  993.                 LD A,L
  994.                 LD HL,#8000
  995.                 CALL RDMULTI
  996. LDFILE2         POP DE
  997.                 POP BC
  998.                 PUSH HL
  999.                 CALL RDFATZP
  1000.                 CALL LST_CLS
  1001.                 POP HL
  1002.                 JR C,LDEFILE
  1003.                 LD A,LX
  1004.                 CP HX
  1005.                 JR C,LDEFILE
  1006.                 LD A,H
  1007.                 AND A
  1008.                 JR NZ,LD_FILE
  1009.                 LD HL,#8000
  1010.                 INC LY
  1011.                 LD A,LY
  1012.                 CP #40
  1013.                 JR C,LDFILE0
  1014. LDEFILE         XOR A
  1015.                 JP WR_STAT
  1016.  
  1017. LDMINI          EXX
  1018.                 LD L,A
  1019.                 LD A,HX
  1020.                 LD H,A
  1021.                 CP L
  1022.                 JR C,$+3
  1023.                 LD A,L
  1024.                 EXX
  1025.                 PUSH BC
  1026.                 PUSH DE
  1027.                 PUSH AF
  1028.                 PUSH HL
  1029.                 CALL REALSEC
  1030.                 POP HL
  1031.                 POP AF
  1032.                 CALL RDMULTI
  1033.                 POP DE
  1034.                 POP BC
  1035.                 LD A,H
  1036.                 AND A
  1037.                 RET Z
  1038.                 PUSH HL
  1039.                 CALL RDFATZP
  1040.                 CALL LST_CLS
  1041.                 POP HL
  1042.                 JR C,LDEFILE
  1043.                 EXX
  1044.                 LD A,L
  1045.                 SUB H
  1046.                 EXX
  1047.                 JR NC,LDMINI
  1048.                 JR LDEFILE
  1049.  
  1050. SAVEZP          LD (HL),E
  1051.                 INC HL
  1052.                 LD (HL),D
  1053.                 INC HL
  1054.                 LD (HL),C
  1055.                 INC HL
  1056.                 LD (HL),B
  1057.                 INC HL
  1058.                 RET
  1059.  
  1060. LOADZP          LD E,(HL)
  1061.                 INC HL
  1062.                 LD D,(HL)
  1063.                 INC HL
  1064.                 LD C,(HL)
  1065.                 INC HL
  1066.                 LD B,(HL)
  1067.                 INC HL
  1068.                 RET
  1069.  
  1070. ;ЧТЕНИЕ СЕКТОРА DIR ПО НОМЕРУ BC
  1071. RDDIRSC         PUSH BC
  1072.                 LD D,B
  1073.                 LD E,C
  1074.                 LD BC,0
  1075.                 LD A,#10
  1076.                 CALL BCDE_A
  1077.                 LD A,E
  1078.                 PUSH AF
  1079.                 LD A,(BYTSSEC)
  1080.                 PUSH AF
  1081.                 CALL BCDE_A
  1082.                 LD HL,TDIRCLS
  1083.                 EX DE,HL
  1084.                 ADD HL,HL
  1085.                 ADD HL,HL
  1086.                 ADD HL,DE
  1087.                 CALL LOADZP
  1088.                 CALL REALSEC
  1089.                 POP AF
  1090.                 DEC A
  1091.                 LD L,A
  1092.                 POP AF
  1093.                 AND L
  1094.                 LD L,A
  1095.                 LD H,0
  1096.                 ADD HL,DE
  1097.                 EX DE,HL
  1098.                 LD HL,0
  1099.                 ADC HL,BC
  1100.                 LD B,H
  1101.                 LD C,L
  1102.                 CALL LOADLST
  1103.                 POP BC
  1104.                 RET
  1105.  
  1106. ;ПРОВЕРКА НА ПОСЛЕДНИЙ КЛАСТЕР В ЦЕПОЧКЕ
  1107. LST_CLS         LD A,(CAL_FAT)          ;ЗАВИСИТ ОТ РАЗРЯДНОСТИ ФАТА
  1108.                 AND A
  1109.                 JR NZ,LST_CL1
  1110.                 LD HL,#0FF7             ;ПРОВЕРКА ДЛЯ ФАТ12
  1111.                 SBC HL,DE
  1112.                 RET
  1113.  
  1114. LST_CL1         DEC A
  1115.                 JR NZ,LST_CL2
  1116. LST_CL3         LD HL,#FFF7             ;ПРОВЕРКАМ ДЛЯ ФАТ16 И МЛАДШИХ БИТ ФАТ32
  1117.                 SBC HL,DE
  1118.                 RET
  1119.  
  1120. LST_CL2         LD HL,#0FFF             ;ПРОВЕРКА ДЛЯ СТАРШИХ БИТ ФАТ32
  1121.                 SBC HL,BC
  1122.                 RET NZ
  1123.                 JR LST_CL3
  1124.  
  1125. ;ЧТЕНИЕ СЛЕДУЮЩЕГО НОМЕРА КЛАСТЕРА В ЦЕПОЧКЕ
  1126. RDFATZP         LD A,(CAL_FAT)          ;ЧТЕНИЕ ЗАВИСИТ ОТ РАЗРАДНОСТИ ФАТА
  1127.                 AND A
  1128.                 JR Z,RDFATS0            ;ПЕРЕХОД ВПЕРЕД ДЛЯ ФАТ12
  1129.                 DEC A
  1130.                 JR Z,RDFATS1            ;ПЕРЕХОД ВПЕРЕД ДЛЯ ФАТ16
  1131.                 EX DE,HL                ;ЗДЕСЬ ЧТЕНИЕ ДЛЯ ФАТ32
  1132.                 ADD HL,HL
  1133.                 EX DE,HL
  1134.                 LD HL,0
  1135.                 ADC HL,BC
  1136.                 ADC HL,BC               ;УМНОЖИЛИ НОМЕР КЛАСТЕРА НА 2
  1137.                 LD A,E
  1138.                 LD E,D
  1139.                 LD D,L
  1140.                 LD C,H
  1141.                 LD B,0                  ;РАЗДЕЛИЛИ НОМЕР КЛАСТЕРА НА 256
  1142.                 CALL RDFATS2            ;ЧИТАЕМ МЛАДШИЕ 16 БИТ ИСПОЛЬЗУЯ ЧТЕНИЕ ДЛЯ ФАТ16
  1143.                 INC HL
  1144.                 LD C,(HL)
  1145.                 INC HL
  1146.                 LD B,(HL)               ;ПРОЧИТАЛИ ПОСЛЕДУЮЩИЕ СТАРШИЕ 16 БИТ
  1147.                 RET
  1148.  
  1149. ;ЧТЕНИЕ 16 БИТНОГО НОМЕРА КЛАСТЕРА ИЗ ЦЕПОЧКИ ДЛЯ ФАТ16
  1150. RDFATS1         LD BC,0
  1151.                 LD A,E
  1152.                 LD E,D
  1153.                 LD D,C                  ;РАЗДЕЛИЛИ НОМЕР КЛАСТЕРА НА 256, СТАРШИЕ 16 БИТ =0
  1154. RDFATS2         PUSH AF                 ;ОБЩЕЕ ЧТЕНИЕ 16 БИТНОГО НОМЕРА КЛАСТЕРА ДЛЯ ФАТ16/32
  1155.                 PUSH BC
  1156.                 LD HL,FATSTR
  1157.                 CALL BCDEHLP            ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА ФАТ ТАБЛИЦЫ
  1158.                 CALL LOADLST            ;ЗАГРУЗИЛИ ВЫЧИСЛЕННЫЙ НОМЕР СЕКТОРА
  1159.                 POP BC
  1160.                 POP AF
  1161.                 LD E,A
  1162.                 LD D,0
  1163.                 ADD HL,DE
  1164.                 ADD HL,DE               ;ВЫЧИСЛИЛИ СМЕЩЕНИЕ ДО НУЖНОГО НОМЕРА В ЗАГРУЖЕННОМ СЕКТОРЕ
  1165.                 LD E,(HL)
  1166.                 INC HL
  1167.                 LD D,(HL)               ;ПОЛУЧИЛИ 16 БИТ НОМЕРА КЛАСТЕРА
  1168.                 RET
  1169.  
  1170. ;ЧТЕНИЕ 12 БИТНОГО НОМЕРА КЛАСТЕРА ИЗ ЦЕПОЧКИ ДЛЯ ФАТ12
  1171. RDFATS0         LD H,D
  1172.                 LD L,E
  1173.                 ADD HL,HL
  1174.                 ADD HL,DE               ;HL=HL*3
  1175.                 SRL H
  1176.                 RR L                    ;HL=HL/2 - В ИТОГЕ УМНОЖИЛИ НОМЕР КЛАСТЕРА НА 1,5
  1177.                 LD A,E                  ;A-НАМ ИНТЕРЕСЕН ТОЛЬКО БИТ НОМЕР СТАРОГО НОМЕРА КЛАСТЕРА
  1178.                 LD E,H
  1179.                 LD D,0
  1180.                 LD B,D
  1181.                 LD C,D                  ;РАЗДЕЛИЛИ НОМЕР КЛАСТЕРА НА 256
  1182.                 SRL E
  1183.                 PUSH AF
  1184.                 PUSH HL
  1185.                 LD HL,FATSTR
  1186.                 CALL BCDEHLP            ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА ФАТ ТАБЛИЦЫ
  1187.                 CALL LOADLST            ;ЗАГРУЗИЛИ ВЫВЧИСЛЕННЫЙ СЕКТОР
  1188.                 POP BC
  1189.                 LD A,B
  1190.                 AND 1
  1191.                 LD B,A                  ;BC=СМЕЩЕНИЕ В ЗАГРУЖЕННОМ СЕКТОРЕ
  1192.                 ADD HL,BC               ;HL=АДРЕС ОТКУДА ЧИТАТЬ БАЙТЫ НОМЕРА КЛАСТЕРА
  1193.                 LD B,(HL)               ;ПРОЧИТАЛИ МЛАДШУЮ ЧАСТЬ НОМЕРА КЛАСТЕРА
  1194.                 INC HL                  ;АДРЕС СЛЕДУЮЩЕГО БАЙТА
  1195.                 LD A,H
  1196.                 CP HIGH BUF_512+2       ;ПРОВЕРКА НА ПЕРЕХОД ГРАНИЦЫ ЗАГРУЖЕННОГО СЕКТОРА
  1197.                 JR NZ,RDFATS4
  1198.                 PUSH BC                 ;ВЫХЛД ЗА ПРЕДЕЛЫ ТЕКУЩЕГО ЗАГРУЖЕННОГО СЕКТОРА
  1199.                 LD BC,0
  1200.                 INC DE
  1201.                 CALL LOADLST            ;ЗАГРУЖАЕМ СЛЕДУЮЩИЙ СЕКТОР ФАТ ТАБЛИЦЫ
  1202.                 POP BC
  1203. RDFATS4         POP AF
  1204.                 LD D,(HL)               ;ЧИТАЕМ СТАРШИЕ БИТЫ НОМЕРА КЛАСТЕРА
  1205.                 LD E,B                  ;ТЕПЕРЬ DE=НОМЕР СЛЕДУЮЩЕГО КЛАСТЕРА В ЦЕПОЧКЕ
  1206.                 LD BC,0
  1207.                 RRA                     ;ПРОВЕРЯЕМ БИТ 0 СТАРОГО НОМЕРА КЛАСТЕРА
  1208.                 JR NC,RDFATS3
  1209.                 SRL D                   ;СДВИГАЕМ НОМЕР ПРОЧИТАННОГО НОМЕРА КЛАСТЕРА В МЛАДШИЕ 12 БИТ
  1210.                 RR E
  1211.                 SRL D
  1212.                 RR E
  1213.                 SRL D
  1214.                 RR E
  1215.                 SRL D
  1216.                 RR E
  1217. RDFATS3         LD A,D
  1218.                 AND #0F
  1219.                 LD D,A                  ;СБРОСИЛИ НЕЗНАЧАЩИЕ СТАРШИЕ 4 БИТА У ПОЛУЧЕННОГО НОМЕРА КЛАСТЕРА
  1220.                 RET
  1221.  
  1222. ;ВЫЧИСЛЕНИЕ РЕАЛЬНОГО СЕКТОРА
  1223. ;НА ВХОДЕ BCDE=НОМЕР КЛАСТЕРА FAT
  1224. ;НА ВЫХОДЕ BCDE=НОМЕР РЕАЛЬНОГО СЕКТОРА
  1225. REALSEC         LD A,B
  1226.                 OR C
  1227.                 OR D
  1228.                 OR E
  1229.                 JR NZ,REALSE1           ;BCDE=0?
  1230.                 LD HL,SEC_FAT           ;ЭТО ROOT ДИРЕКТОРИЯ У ФАТ12/16
  1231.                 LD DE,(FATSTR)          ;МЕСТОПОЛОЖЕНИЕ ROOT ДИРЫ СРАЗУ ПОСЛЕ ФАТ ТАБЛИЦЫ
  1232.                 LD BC,(FATSTR+2)
  1233.                 PUSH HL
  1234.                 CALL BCDEHLP            ;ПРИБАВИЛИ К НАЧАЛУ ФАТ ТАБЛИЦЫ ЕЕ РАЗМЕР
  1235.                 POP HL
  1236.                 JP BCDEHLP              ;ПРИБАВИЛИ ЕЩЕ РАЗ И ПОЛУЧИЛИ НОМЕР СЕКТОРА НАЧАЛА ROOT ДИРЫ
  1237.  
  1238. REALSE1         LD HL,#FFFE
  1239.                 EX DE,HL
  1240.                 ADD HL,DE
  1241.                 EX DE,HL
  1242.                 INC HL
  1243.                 ADC HL,BC               ;HLDE=НОМЕР КЛАСТЕРА-2
  1244.                 LD A,(BYTSSEC)          ;НУЖНО УМНОЖИТЬ НА РАЗМЕР КЛАСТЕРА
  1245.                 JR REALSE2
  1246.  
  1247. REALSE3         SLA E
  1248.                 RL D
  1249.                 RL L
  1250.                 RL H
  1251. REALSE2         RRCA
  1252.                 JR NC,REALSE3           ;УМНОЖИЛИ НА РАЗМЕР КЛАСТЕРА
  1253.                 LD B,H
  1254.                 LD C,L
  1255.                 LD HL,STARTRZ
  1256.                 CALL BCDEHLP            ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА ДИСКА
  1257.                 LD HL,FRSTDAT
  1258.                 JP BCDEHLP              ;ПРИБАВИЛИ СМЕЩЕНИЕ ОТ НАЧАЛА РАЗДЕЛА
  1259.  
  1260. ;BCDE=BCDE/512
  1261. BCDE200         LD E,D
  1262.                 LD D,C
  1263.                 LD C,B
  1264.                 LD B,0
  1265.                 LD A,2
  1266.                 JR BCDE_A
  1267.  
  1268. ;BCDE>>A=BCDE
  1269. BCDE_A1         SRL B
  1270.                 RR C
  1271.                 RR D
  1272.                 RR E
  1273. BCDE_A          RRCA
  1274.                 JR NC,BCDE_A1
  1275.                 RET
  1276.  
  1277. ;(ADR)-BCDE=BCDE
  1278. BCDEHLM         LD A,(HL)
  1279.                 INC HL
  1280.                 SUB E
  1281.                 LD E,A
  1282.                 LD A,(HL)
  1283.                 INC HL
  1284.                 SBC A,D
  1285.                 LD D,A
  1286.                 LD A,(HL)
  1287.                 INC HL
  1288.                 SBC A,C
  1289.                 LD C,A
  1290.                 LD A,(HL)
  1291.                 SBC A,B
  1292.                 LD B,A
  1293.                 RET
  1294.  
  1295. ;(ADR)+BCDE=BCDE
  1296. BCDEHLP         LD A,(HL)
  1297.                 INC HL
  1298.                 ADD A,E
  1299.                 LD E,A
  1300.                 LD A,(HL)
  1301.                 INC HL
  1302.                 ADC A,D
  1303.                 LD D,A
  1304.                 LD A,(HL)
  1305.                 INC HL
  1306.                 ADC A,C
  1307.                 LD C,A
  1308.                 LD A,(HL)
  1309.                 ADC A,B
  1310.                 LD B,A
  1311.                 RET
  1312.  
  1313. ;HLDE+BC=HLDE
  1314. HLDEPBC         EX DE,HL
  1315.                 ADD HL,BC
  1316.                 EX DE,HL
  1317.                 LD BC,0
  1318.                 ADC HL,BC
  1319.                 RET
  1320.  
  1321. ;ОПРЕДЕЛЯТОР РАЗРЯДНОСТИ FAT
  1322. RASCHET         CALL BCDE200            ;РАЗДЕЛИЛИ НА РАЗМЕР СЕКТОРА
  1323.                 LD HL,SEC_FAT
  1324.                 CALL BCDEHLM            ;ВЫЧЛИ НАЧАЛО ФАТ ТАБЛИЦЫ
  1325.                 LD A,E
  1326.                 AND #F0                 ;ИГНОРИРУЕМ МЛАДШИЕ 4 БИТА
  1327.                 OR D
  1328.                 OR C
  1329.                 OR B                    ;ПРОВЕРКА НА 0
  1330.                 RET
  1331.  
  1332. ;ГРУЗИЛКА ОДНОГО СЕКТОРА
  1333. LOADLST         LD HL,BUF_512           ;АДРЕС БУФЕРА СЕКТОРА
  1334.                 LD A,1                  ;ГРУЗИТЬ 1 СЕКТОР
  1335.                 PUSH HL
  1336.                 CALL RDMULTI            ;ЗАГРУЗИЛИ СЕКТОР
  1337.                 POP HL                  ;НА ВЫХОДЕ HL=АДРЕС НАЧАЛА БУФЕРА ЗАГРУЖЕННОГО СЕКТОРА
  1338.                 RET
  1339.  
  1340. ;ПОДАЧА КОМАНДЫ В SD КАРТУ БЕЗ ПАРАМЕТРОВ
  1341. OUTCOM          PUSH BC
  1342.                 LD BC,#0600+SD_SEND     ;ВЫДАТЬ В ПОРТ 6 БАЙТ
  1343.                 OTIR
  1344.                 POP BC
  1345.                 RET
  1346.  
  1347. ;ВЫДАЧА В ПОРТ SD КАРТЫ КОМАНДЫ С ПАРАМЕТРОМ 0
  1348. OUT_COM         PUSH BC
  1349.                 LD BC,SD_SEND
  1350.                 OUT (C),A               ;ОТПРАВИЛИ КОД КОМАНДЫ
  1351.                 XOR A
  1352.                 OUT (C),A               ;БИТЫ 31-24 ПАРАМЕТРА
  1353.                 NOP
  1354.                 OUT (C),A               ;БИТЫ 23-16 ПАРАМЕТРА
  1355.                 NOP
  1356.                 OUT (C),A               ;БИТЫ 15-8 ПАРАМЕТРА
  1357.                 NOP
  1358.                 OUT (C),A               ;БИТЫ 7-0 ПАРАМЕТРА
  1359.                 DEC A
  1360.                 OUT (C),A               ;БЕЗ CRC16
  1361.                 POP BC
  1362.                 RET
  1363.  
  1364. SECM200         PUSH HL
  1365.                 PUSH BC
  1366.                 LD A,CMD_58
  1367.                 CALL OUT_COM
  1368.                 CALL IN_OOUT
  1369.                 LD BC,SD_RSTR
  1370.                 IN H,(C)
  1371.                 NOP
  1372.                 IN A,(C)
  1373.                 NOP
  1374.                 IN A,(C)
  1375.                 NOP
  1376.                 IN A,(C)
  1377.                 BIT 6,H
  1378.                 POP HL
  1379.                 JR NZ,SECN200
  1380.                 EX DE,HL
  1381.                 ADD HL,HL
  1382.                 EX DE,HL
  1383.                 ADC HL,HL
  1384.                 LD H,L
  1385.                 LD L,D
  1386.                 LD D,E
  1387.                 LD E,0
  1388. SECN200         LD A,CMD_18
  1389.                 LD C,SD_SEND
  1390.                 OUT (C),A
  1391.                 NOP
  1392.                 OUT (C),H
  1393.                 NOP
  1394.                 OUT (C),L
  1395.                 NOP
  1396.                 OUT (C),D
  1397.                 NOP
  1398.                 OUT (C),E
  1399.                 LD A,#FF
  1400.                 OUT (C),A
  1401.                 POP HL
  1402.                 RET
  1403.  
  1404. IN_OOUT         EXX
  1405.                 LD DE,#20FF
  1406. IN_WAIT         IN A,(SD_RSTR)
  1407.                 CP E
  1408.                 JR NZ,IN_EXIT
  1409. IN_NEXT         DEC D
  1410.                 JR NZ,IN_WAIT
  1411. IN_EXIT         EXX
  1412.                 RET
  1413.  
  1414. CMD00           DB #40,#00,#00,#00,#00,#95      ;GO_IDLE_STATE
  1415. CMD08           DB #48,#00,#00,#01,#AA,#87      ;SEND_IF_COND
  1416. CMD16           DB #50,#00,#00,#02,#00,#FF      ;SET_BLOCKEN
  1417.  
  1418. ;МНОГО СЕКТОРНОЕ ЧТЕНИЕ С SD КАРТЫ
  1419. RDMULTI         EXA
  1420.                 CALL SECM200
  1421.                 EXA
  1422.                 LD BC,SD_RSTR
  1423. RDMULT1         EXA
  1424.                 CALL IN_OOUT
  1425.                 CP #FE
  1426.                 JR NZ,$-5
  1427.                 INIR
  1428.                 NOP
  1429.                 INIR
  1430.                 NOP
  1431.                 IN A,(C)
  1432.                 NOP
  1433.                 IN A,(C)
  1434.                 EXA
  1435.                 DEC A
  1436.                 JR NZ,RDMULT1
  1437.                 LD A,CMD_12
  1438.                 CALL OUT_COM
  1439.                 CALL IN_OOUT
  1440.                 INC A
  1441.                 JR NZ,$-4
  1442.                 RET
  1443.  
  1444. ;ВЫБОРКА НОМЕРА КЛАСТЕРА ИЗ ФАЙЛОВОГО ОПИСАТЕЛЯ
  1445. RD_CLAS         EX DE,HL
  1446.                 LD DE,#14               ;СТАРШИЕ 16 БИТ ЧИТАЕМ ИЗ СМЕЩЕНИЯ +20
  1447.                 ADD HL,DE
  1448.                 LD C,(HL)
  1449.                 INC HL
  1450.                 LD B,(HL)
  1451.                 LD E,5                  ;МЛАДШИЕ 16 БИТ ЧИТАЕМ ИЗ СМЕЩЕНИЯ +26
  1452.                 ADD HL,DE
  1453.                 LD E,(HL)
  1454.                 INC HL
  1455.                 LD D,(HL)
  1456.                 INC HL
  1457.                 RET
  1458.  
  1459. ;ПРОВЕРКА ПО МАСКЕ
  1460. COMPARE         LD DE,FB_EXT
  1461.                 LD B,#0B
  1462.                 LD A,(DE)
  1463.                 CP (HL)
  1464.                 RET NZ
  1465.                 INC HL
  1466.                 INC DE
  1467.                 DJNZ $-5
  1468.                 RET
  1469.  
  1470. ;РАСПАКОВЩИК ПУТИ К ФАЙЛУ
  1471. FNDBUF          LD BC,#0802
  1472.                 LD DE,FB_EXT
  1473. FNDBUF4         LD A,(HL)
  1474.                 INC HL
  1475.                 CP #2E
  1476.                 JR Z,FNDBUF2
  1477.                 CP #5C
  1478.                 JR Z,FNDBUF5
  1479.                 LD (DE),A
  1480.                 INC DE
  1481.                 DJNZ FNDBUF4
  1482.                 LD A,(HL)
  1483.                 AND A
  1484.                 RET Z
  1485.                 INC HL
  1486.                 JR FNDBUF3
  1487.  
  1488. FNDBUF5         LD A,C
  1489.                 AND A
  1490.                 RET Z
  1491. FNDBUF2         LD A,B
  1492.                 AND A
  1493.                 JR Z,FNDBUF3
  1494.                 LD A,#20
  1495.                 LD (DE),A
  1496.                 INC DE
  1497.                 DJNZ $-2
  1498. FNDBUF3         LD B,3
  1499.                 DEC C
  1500.                 DEC HL
  1501.                 LD A,(HL)
  1502.                 CP #5C
  1503.                 JR Z,FNDBUF4
  1504.                 INC HL
  1505.                 JR FNDBUF4
  1506.  
  1507. RAMCEND
  1508.                 ENT