Subversion Repositories ngs

Rev

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

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