Subversion Repositories ngs

Rev

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

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