Subversion Repositories ngs

Rev

Rev 165 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. ; LAST UPDATE: 17.05.2025 savelij
  3.  
  4. STACK_CURR_DIR          EQU 0x6000      ; стек номеров дир перед входом в нее
  5.  
  6. ; FAT функции по номерам
  7.  INIT_VAR
  8.  SETVAR Init_Fatvars                    ; инит FAT драйвера
  9.  SETVAR Getfzap                         ; получить описатель файла
  10.  SETVAR Getlong                         ; получить длинное имя файла
  11.  SETVAR Finddir                         ; найти все директории
  12.  SETVAR Findfil                         ; найти все файлы по маске
  13.  SETVAR Set_fil                         ; установка номера файла
  14.  SETVAR Nextsec                         ; следующий сектор на MP3 чип
  15.  SETVAR Openfil                         ; открытие файла
  16.  SETVAR Prvdir                          ; предыдущая DIR для PLAY
  17.  SETVAR Nxtdir                          ; следующая DIR для PLAY
  18.  SETVAR Loadfil                         ; загрузка файла
  19.  
  20.  INIT_VAR B512BAS
  21.  SETVAR BUF_512,                0x200   ; 200 буфер сектора
  22.  SETVAR TDIRCLS,                0x400   ; 400 буфер кластеров root директории
  23.  SETVAR DIR_CEP,                0x100   ; 100 цепочка кластеров поддиректорий
  24.  SETVAR BUF_PATH,               0x100   ; 100 буфер текущего пути
  25.  SETVAR ERORDRV,                WORD    ; 2 возврат с ошибкой в A
  26.  SETVAR FATType,                BYTE    ; тип FAT: 0-12/1-16/2-32
  27.  SETVAR NumFATs,                BYTE    ; количество FAT таблиц
  28.  SETVAR SecPerClus,             BYTE    ; количество секторов в кластере
  29.  SETVAR RootDIRCluster,         DWORD   ; номер кластера корневой DIR
  30.  SETVAR NumSecRootDir,          DWORD   ; номер сектора корневой директории
  31.  SETVAR ROOTSEC,                WORD    ; размер в секторах ROOT директории
  32.  SETVAR FATSize,                DWORD   ; размер FAT таблицы в секторах
  33.  SETVAR StartSecVol,            DWORD   ; номер стартового сектора раздела
  34.  SETVAR FirstSecData,           DWORD   ; номер сектора начала области данных
  35.  SETVAR NumSecFAT1,             DWORD   ; номер сектора первой FAT таблицы
  36.  SETVAR NumSecFAT2,             DWORD   ; номер сектора второй FAT таблицы
  37.  SETVAR NumSec2Buf,             DWORD   ; номер сектора загруженного в буфер
  38.  SETVAR NumsSectorsVol,         DWORD   ; количество секторов на разделе
  39.  SETVAR NumsClustersVol,        DWORD   ; количество кластеров на разделе
  40.  SETVAR CurrentDIRCluster,      DWORD   ; номер кластера текущей DIR
  41.  SETVAR TEK_ZAP,                WORD    ; текущая запись в DIR
  42.  SETVAR TEK_LEV,                BYTE    ; глубина нахождения в директориях
  43.  SETVAR NUMSECK,                BYTE    ; счетчик секторов в кластере
  44.  SETVAR PAGEDIR,                WORD    ; адрес укладания в странице диров
  45.  SETVAR PAGEMP3,                WORD    ; адрес укладания в странице файлов
  46.  SETVAR TFILCLS,                DWORD   ; текущий кластер
  47.  SETVAR TEKNUMC,                WORD    ; адрес текущего кластера
  48.  SETVAR MPHWOST,                BYTE    ; остаток секторов в последнем кластере
  49.  SETVAR KOL_CLS,                DWORD   ; кол-во полных кластеров файла
  50.  SETVAR KOLVMP3,                WORD    ; кол-во найденных файлов
  51.  SETVAR KOLVDIR,                WORD    ; кол-во найденных диров
  52.  SETVAR STR_MP3,                WORD    ; адрес укладки найденных файлов
  53.  SETVAR STACKPREVDIR,           WORD    ; адрес в стеке предыдущих директорий для возврата вверх
  54.  SETVAR_ALIGN
  55.  SETVAR STR_DIR,                0       ; ? адрес укладки найденных DIR
  56.  
  57. ; общая точка входа для работы с FAT
  58.                 CALL CMP_INT
  59.                 DI
  60.                 EXX
  61.                 PUSH IX
  62.                 PUSH IY
  63.                 LD (ERORDRV),SP
  64.                 PUSH HL
  65.                 LD HL,EXITDRV
  66.                 EX (SP),HL
  67.                 PUSH HL
  68.                 PUSH DE
  69.                 ADD A,A
  70.                 LD L,A
  71.                 LD H,0
  72.                 LD DE,TABLFAT
  73.                 ADD HL,DE
  74.                 EX AF,AF'
  75.                 LD E,(HL)
  76.                 INC HL
  77.                 LD D,(HL)
  78.                 EX DE,HL
  79.                 POP DE
  80.                 EX (SP),HL
  81.                 EXX
  82.                 RET
  83.  
  84. ERR_DRV         LD SP,(ERORDRV)
  85. EXITDRV         POP IY
  86.                 POP IX
  87.                 PUSH AF
  88.                 LD A,(VAR_INT_MODE)
  89.                 AND A
  90.                 JR Z,EXITDRV1
  91.                 EI
  92. EXITDRV1        POP AF
  93.                 RET
  94.  
  95. TABLFAT         DW INIT_FATVARS                 ; 00 инит FAT драйвера
  96.                 DW GETFZAP                      ; 01 получить описатель файла
  97.                 DW GETLONG                      ; 02 получить длинное имя файла
  98.                 DW FINDDIR                      ; 03 найти все директории
  99.                 DW FINDMP3                      ; 04 найти все файлы по маске
  100.                 DW SET_MP3                      ; 05 установка номера файла
  101.                 DW NEXTSEC                      ; 06 следующий сектор на MP3 чип
  102.                 DW OPENFIL                      ; 07 открытие файла
  103.                 DW PRVDIR                       ; 08 предыдущая DIR для PLAY
  104.                 DW NXTDIR                       ; 09 следующая DIR для PLAY
  105.                 DW LOADFIL                      ; 0A загрузка файла
  106.  
  107. NO_LNG          POP DE
  108.                 LD BC,8
  109.                 LDIR
  110.                 LD A,(HL)
  111.                 CP " "
  112.                 JR Z,.NO_LNG1
  113.                 EX DE,HL
  114.                 LD (HL),"."
  115.                 INC HL
  116.                 EX DE,HL
  117.                 LDI
  118.                 LDI
  119.                 LDI
  120. .NO_LNG1        EX DE,HL
  121.                 LD (HL),0
  122.                 POP HL
  123.                 RET
  124.  
  125. GETLONG         PUSH HL
  126.                 PUSH HL
  127.                 CALL SET_MP3
  128.                 CALL GETFZAP
  129.                 BIT 0,E
  130.                 JR Z,NO_LNG
  131.                 EXX
  132.                 LD C,0
  133.                 EXX
  134. .GETLNG2        DEC BC
  135.                 CALL GETRZAP
  136.                 LD A,(HL)
  137.                 INC HL
  138.                 EXX
  139.                 BIT 6,C
  140.                 POP HL
  141.                 JR NZ,.GETLNGE_1
  142.                 LD C,A
  143.                 EXX
  144.                 LD A,5
  145.                 CALL .GETLNG1
  146.                 AND A
  147.                 JR Z,.GETLNGE
  148.                 INC HL
  149.                 INC HL
  150.                 INC HL
  151.                 LD A,6
  152.                 CALL .GETLNG1
  153.                 AND A
  154.                 JR Z,.GETLNGE
  155.                 INC HL
  156.                 INC HL
  157.                 LD A,2
  158.                 CALL .GETLNG1
  159.                 AND A
  160.                 JR Z,.GETLNGE
  161.                 EXX
  162.                 PUSH HL
  163.                 EXX
  164.                 JR .GETLNG2
  165.  
  166. .GETLNGE        EXX
  167. .GETLNGE_1      LD (HL),0
  168.                 EXX
  169.                 POP HL
  170.                 RET
  171.  
  172. .GETLNG1        EXX
  173.                 LD B,A
  174.                 EXX
  175. .GETLNG1_3      LD D,(HL)
  176.                 INC HL
  177.                 LD E,(HL)
  178.                 INC HL
  179.                 LD A,D
  180.                 OR E
  181.                 RET Z
  182.                 LD A,E
  183.                 AND A
  184.                 JR NZ,.GETLNG3
  185.                 LD A,D
  186.                 CP 0x80
  187.                 JR C,.GETLNG5
  188.                 LD D,0x5F
  189.                 JR .GETLNG5
  190.  
  191. .GETLNG3        CP 4
  192.                 LD A,0x5F
  193.                 JR NZ,.GETLNG5
  194.                 LD A,D
  195.                 LD E,0xEF
  196.                 LD D,0x5F
  197.                 CP 1
  198.                 JR Z,.GETLNG4
  199.                 LD E,0xA0
  200.                 CP 0x51
  201.                 JR Z,.GETLNG4
  202.                 SUB 0x10
  203.                 LD E,0x80
  204.                 JR NC,.GETLNG6
  205.                 LD A,D
  206.                 JR .GETLNG5
  207.  
  208. .GETLNG6        CP 0x30
  209.                 JR C,.GETLNG4
  210.                 LD E,0xB0
  211.                 CP 0x40
  212.                 JR C,.GETLNG4
  213.                 LD A,D
  214.                 JR .GETLNG5
  215.  
  216. .GETLNG4        ADD A,E
  217. .GETLNG5        EXX
  218.                 LD (HL),A
  219.                 INC HL
  220.                 DEC B
  221.                 EXX
  222.                 RET Z
  223.                 JR .GETLNG1_3
  224. ; 401,410-44F,451
  225.  
  226. READ_SECTOR     CALL CPNUMSC
  227.                 JR NZ,.L1
  228.                 LD HL,BUF_512
  229.                 RET
  230.  
  231. .L1             LD (NumSec2Buf),DE
  232.                 LD (NumSec2Buf+2),BC
  233.                 LD HL,BUF_512
  234.                 PUSH HL
  235.                 EX AF,AF'
  236.                 LD A,2
  237.                 CALL COM__SD
  238.                 AND A
  239.                 JP NZ,ERR_DRV
  240.                 POP HL
  241.                 RET
  242.  
  243. ; проверка на уже загруженный сектор
  244. CPNUMSC         LD HL,NumSec2Buf
  245.                 LD A,(HL)
  246.                 INC HL
  247.                 CP E
  248.                 RET NZ
  249.                 LD A,(HL)
  250.                 INC HL
  251.                 CP D
  252.                 RET NZ
  253.                 LD A,(HL)
  254.                 INC HL
  255.                 CP C
  256.                 RET NZ
  257.                 LD A,(HL)
  258.                 CP B
  259.                 RET
  260.  
  261. ENT_DIR         CALL GETFZAP
  262.                 BIT 4,A
  263.                 EX AF,AF'
  264.                 LD A,E
  265.                 EX AF,AF'
  266.                 LD E,A
  267.                 LD D,(HL)
  268.                 RET Z
  269.                 EXX
  270.                 EX AF,AF'
  271.                 BIT 7,A
  272.                 JR Z,ENT_DI2
  273.                 LD HL,TEK_LEV
  274.                 LD A,(HL)
  275.                 AND A
  276.                 EXX
  277.                 RET Z
  278.                 EXX
  279.                 DEC A
  280.                 LD (HL),A
  281.                 ADD A,A
  282.                 LD H,HIGH (DIR_CEP)
  283.                 LD L,A
  284.                 LD A,(HL)
  285.                 INC L
  286.                 LD H,(HL)
  287.                 LD L,A
  288.                 CALL ENT_DI1
  289.                 EXX
  290.                 LD (TEK_ZAP),HL
  291.                 EXX
  292.                 RET
  293.  
  294. ENT_DI2         LD HL,TEK_LEV
  295.                 LD A,(HL)
  296.                 INC A
  297.                 CP 0x80
  298.                 EXX
  299.                 RET Z
  300.                 EXX
  301.                 LD (HL),A
  302.                 DEC A
  303.                 ADD A,A
  304.                 LD H,HIGH (DIR_CEP)
  305.                 LD L,A
  306.                 LD BC,(TEK_ZAP)
  307.                 LD (HL),C
  308.                 INC L
  309.                 LD (HL),B
  310. ENT_DI1         EXX
  311.                 LD DE,20
  312.                 ADD HL,DE
  313.                 LD C,(HL)
  314.                 INC HL
  315.                 LD B,(HL)
  316.                 LD E,5
  317.                 ADD HL,DE
  318.                 LD E,(HL)
  319.                 INC HL
  320.                 LD D,(HL)
  321.                 LD A,B
  322.                 OR C
  323.                 OR D
  324.                 OR E
  325.                 JR NZ,ENT_DI0
  326.                 LD DE,(RootDIRCluster)
  327.                 LD BC,(RootDIRCluster+2)
  328. ENT_DI0         LD (CurrentDIRCluster),DE
  329.                 LD (CurrentDIRCluster+2),BC
  330.                 CALL INIRTSC
  331.                 XOR A
  332.                 INC A
  333.                 RET
  334.  
  335. GETFZAP         LD BC,(TEK_ZAP)
  336.                 LD A,B
  337.                 OR C
  338.                 JR Z,GETRZAP
  339.                 PUSH BC
  340.                 DEC BC
  341.                 CALL GETRZAP
  342.                 POP BC
  343.                 LD E,A
  344. GETRZAP         PUSH DE
  345.                 CALL RDDIRSC
  346.                 POP DE
  347.                 CP 0xFF
  348.                 LD A,E
  349.                 RET Z
  350.                 EX AF,AF'
  351.                 LD A,C
  352.                 AND 0x0F
  353.                 LD E,A
  354.                 LD D,0
  355.                 EX DE,HL
  356.                 ADD HL,HL
  357.                 ADD HL,HL
  358.                 ADD HL,HL
  359.                 ADD HL,HL
  360.                 ADD HL,HL
  361.                 ADD HL,DE
  362.                 LD DE,11
  363.                 EX DE,HL
  364.                 ADD HL,DE
  365.                 LD L,(HL)
  366.                 LD H,0
  367.                 EX DE,HL
  368.                 CALL CP_TWOT
  369.                 JR NZ,.L1
  370.                 LD D,0x80
  371. .L1             EX AF,AF'
  372.                 CP 0x0F
  373.                 LD A,E
  374.                 LD E,D
  375.                 RET NZ
  376.                 SET 0,E
  377.                 RET
  378.  
  379. ; чтение сектора DIR по номеру BC
  380. ; На выходе: A = 0xFF - выход за пределы DIR
  381. RDDIRSC         PUSH BC
  382.                 LD D,B
  383.                 LD E,C
  384.                 LD BC,0
  385.                 LD A,0x10
  386.                 CALL BCDE_A
  387.                 LD A,E
  388.                 PUSH AF
  389.                 LD A,(SecPerClus)
  390.                 PUSH AF
  391.                 CALL BCDE_A
  392.                 LD HL,TDIRCLS
  393.                 EX DE,HL
  394.                 ADD HL,HL
  395.                 ADD HL,HL
  396.                 ADD HL,DE
  397.                 CALL GET_DWORD
  398.                 BIT 7,B
  399.                 JR Z,.L1
  400.                 POP AF
  401.                 POP AF
  402.                 POP AF
  403.                 XOR A
  404.                 DEC A
  405.                 RET
  406.  
  407. .L1             CALL REALSEC
  408.                 POP AF
  409.                 DEC A
  410.                 LD L,A
  411.                 POP AF
  412.                 AND L
  413.                 LD L,A
  414.                 LD H,0
  415.                 ADD HL,DE
  416.                 EX DE,HL
  417.                 LD HL,0
  418.                 ADC HL,BC
  419.                 LD B,H
  420.                 LD C,L
  421.                 CALL READ_SECTOR
  422.                 POP BC
  423.                 RET
  424.  
  425. GET_DWORD       LD E,(HL)
  426.                 INC HL
  427.                 LD D,(HL)
  428.                 INC HL
  429.                 LD C,(HL)
  430.                 INC HL
  431.                 LD B,(HL)
  432.                 INC HL
  433.                 RET
  434.  
  435. SET_DWORD       LD (HL),E
  436.                 INC HL
  437.                 LD (HL),D
  438.                 INC HL
  439.                 LD (HL),C
  440.                 INC HL
  441.                 LD (HL),B
  442.                 INC HL
  443.                 RET
  444.  
  445. INIRTSC         PUSH AF
  446.                 LD HL,0xFFFF
  447.                 LD (NumSec2Buf + 2),HL
  448.                 LD HL,TDIRCLS
  449.                 LD DE,(CurrentDIRCluster)
  450.                 LD BC,(CurrentDIRCluster + 2)
  451.                 CALL SET_DWORD                  ; сохранили в таблицу номер текущего кластера
  452.                 LD A,D
  453.                 OR E
  454.                 OR B
  455.                 OR C
  456.                 JR Z,LASTCLS                    ; если номер кластера 0, то это ROOT дира (для FAT12/16)
  457. NEXTCLS         PUSH HL
  458.                 CALL RDFATZP                    ; читаем следущий номер кластера из цепочки директории
  459.                 CALL LST_CLS                    ; проверяем на конец цепочки
  460.                 POP HL
  461.                 JR C,LASTCLS
  462.                 CALL SET_DWORD                  ; если не последний сохраняем в таблицу
  463.                 JR NEXTCLS                      ; следующий номер кластера
  464.  
  465. LASTCLS         LD BC,0xFFFF
  466.                 CALL SET_DWORD                  ; кладем маркер конца цепочки
  467.                 INC BC
  468.                 CALL RDDIRSC
  469.                 LD A,(HL)
  470.                 CP "."
  471.                 JR NZ,INIRTS1
  472.                 INC HL
  473.                 LD A,(HL)
  474.                 CP "."
  475.                 JR Z,INIRTS1
  476.                 INC BC
  477. INIRTS1         LD (TEK_ZAP),BC
  478.                 POP AF
  479.                 RET
  480.  
  481. CP_TWOT         LD A,(HL)
  482.                 CP "."
  483.                 RET NZ
  484.                 INC HL
  485.                 LD A,(HL)
  486.                 DEC HL
  487.                 CP "."
  488.                 RET NZ
  489.                 XOR A
  490.                 RET
  491.  
  492. LST_CLS         LD A,(FATType)
  493.                 AND A
  494.                 JR NZ,LST_CL1
  495.                 LD HL,0x0FF7
  496.                 SBC HL,DE
  497.                 RET
  498.  
  499. LST_CL1         DEC A
  500.                 JR NZ,LST_CL2
  501.                 LD HL,0xFFF7
  502.                 SBC HL,DE
  503.                 RET
  504.  
  505. LST_CL2         PUSH BC
  506.                 LD A,B
  507.                 AND 0x0F
  508.                 LD B,A
  509.                 LD HL,0x0FFF
  510.                 SBC HL,BC
  511.                 POP BC
  512.                 RET NZ
  513.                 LD HL,0xFFF7
  514.                 SBC HL,DE
  515.                 RET
  516.  
  517. RDFATZP         LD A,(FATType)                  ; чтение зависит от разрядности FAT
  518.                 AND A
  519.                 JR Z,RDFATS0                    ; переход вперед для FAT12
  520.                 DEC A
  521.                 JR Z,RDFATS1                    ; переход вперед для FAT16
  522.                 EX DE,HL                        ; здесь чтение для FTA32
  523.                 ADD HL,HL
  524.                 EX DE,HL
  525.                 LD H,B
  526.                 LD L,C
  527.                 ADC HL,HL                       ; умножили номер кластера на 2
  528.                 LD A,E
  529.                 LD E,D
  530.                 LD D,L
  531.                 LD C,H
  532.                 LD B,0                          ; разделили номер кластера на 256
  533.                 CALL RDFATS2                    ; читаем младшие 16 бит используя чтение для FAT16
  534.                 INC HL
  535.                 LD C,(HL)
  536.                 INC HL
  537.                 LD B,(HL)                       ; прочитали последующие старшие 16 бит
  538.                 RET
  539.  
  540. ; чтение 16 битного номера кластера из цепочки для FAT16
  541. RDFATS1         LD BC,0
  542.                 LD A,E
  543.                 LD E,D
  544.                 LD D,C                          ; разделили номер кластера на 256, старшие 16 бит =0
  545. RDFATS2         PUSH AF                         ; общее чтение 16 битного номера кластера для FAT16/32
  546.                 PUSH BC
  547.                 LD HL,NumSecFAT1
  548.                 CALL BCDEHLP                    ; прибавили смещение от начала FAT таблицы
  549.                 CALL READ_SECTOR                ; загрузили вычисленный номер сектора
  550.                 POP BC
  551.                 POP AF
  552.                 LD E,A
  553.                 LD D,0
  554.                 ADD HL,DE
  555.                 ADD HL,DE                       ; вычислили смещение до нужного номера в загруженном секторе
  556.                 LD E,(HL)
  557.                 INC HL
  558.                 LD D,(HL)                       ; получили 16 бит номера кластера
  559.                 RET
  560.  
  561. ; чтение 12 битного номера кластера из цепочки для FAT12
  562. RDFATS0         LD H,D
  563.                 LD L,E
  564.                 ADD HL,HL
  565.                 ADD HL,DE                       ; HL = HL * 3
  566.                 SRL H
  567.                 RR L                            ; HL = HL / 2 - в итоге умножили номер кластера на 1,5
  568.                 LD A,E                          ; A - нам интересен только бит номер старого номера кластера
  569.                 LD E,H
  570.                 LD D,0
  571.                 LD B,D
  572.                 LD C,D                          ; разделили номер кластера на 256
  573.                 SRL E
  574.                 PUSH AF
  575.                 PUSH HL
  576.                 LD DE,(NumSecFAT1)
  577.                 LD BC,(NumSecFAT1 + 2)
  578.                 CALL READ_SECTOR                ; загрузили вычисленный сектор
  579.                 POP BC
  580.                 LD A,B
  581.                 AND 1
  582.                 LD B,A                          ; BC = смещение в загруженном секторе
  583.                 ADD HL,BC                       ; HL = адрес откуда читать байты номера кластера
  584.                 LD B,(HL)                       ; прочитали младшую часть номера кластера
  585.                 INC HL                          ; адрес следующего байта
  586.                 LD A,H
  587.                 CP HIGH (BUF_512)+2             ; проверка на переход границы загруженного сектора
  588.                 JR NZ,RDFATS4
  589.                 PUSH BC                         ; выход за пределы текущего загруженного сектора
  590.                 LD BC,0
  591.                 INC DE
  592.                 CALL READ_SECTOR                ; загружаем следующий сектор FAT таблицы
  593.                 POP BC
  594. RDFATS4         POP AF
  595.                 LD D,(HL)                       ; читаем старшие биты номера кластера
  596.                 LD E,B                          ; теперь DE = номер следующего кластера в цепочке
  597.                 LD BC,0
  598.                 RRA                             ; проверяем бит 0 старого номера кластера
  599.                 JR NC,RDFATS3
  600.         REPT 4
  601.                 SRL D                           ; сдвигаем номер прочитанного номера кластера в младшие 12 бит
  602.                 RR E
  603.         ENDM
  604. RDFATS3         LD A,D
  605.                 AND 0x0F
  606.                 LD D,A                          ; сбросили незначащие старшие 4 бита у полученного номера кластера
  607.                 RET
  608.  
  609. ; вычисление реального сектора
  610. ; на входе BCDE = номер FAT
  611. ; на выходе BCDE = адрес сектора
  612. REALSEC         LD A,B
  613.                 OR C
  614.                 OR D
  615.                 OR E
  616.                 JR NZ,REALSE1                   ; BCDE = 0?
  617.                 LD DE,(NumSecRootDir)
  618.                 LD BC,(NumSecRootDir + 2)
  619.                 RET
  620.        
  621. REALSE1         LD HL,0xFFFE
  622.                 EX DE,HL
  623.                 ADD HL,DE
  624.                 EX DE,HL
  625.                 INC HL
  626.                 ADC HL,BC                       ; HLDE = номер кластера - 2
  627.                 LD A,(SecPerClus)               ; нужно умножить на размер кластера
  628.                 JR REALSE2
  629.  
  630. REALSE3         SLA E
  631.                 RL D
  632.                 RL L
  633.                 RL H
  634. REALSE2         RRCA
  635.                 JR NC,REALSE3                   ; умножили на размер кластера
  636.                 LD B,H
  637.                 LD C,L
  638.                 LD HL,FirstSecData
  639.                 JP BCDEHLP                      ; прибавили смещение от начала раздела
  640.  
  641. BCDE200         LD E,D
  642.                 LD D,C
  643.                 LD C,B
  644.                 LD B,0
  645.                 LD A,2
  646.                 JR BCDE_A
  647.  
  648. ; BCDE >> A = BCDE
  649. BCDE_A1         SRL B
  650.                 RR C
  651.                 RR D
  652.                 RR E
  653. BCDE_A          RRCA
  654.                 JR NC,BCDE_A1
  655.                 RET
  656.  
  657. ; (ADR) - BCDE = BCDE
  658. BCDEHLM         LD A,(HL)
  659.                 INC HL
  660.                 SUB E
  661.                 LD E,A
  662.                 LD A,(HL)
  663.                 INC HL
  664.                 SBC A,D
  665.                 LD D,A
  666.                 LD A,(HL)
  667.                 INC HL
  668.                 SBC A,C
  669.                 LD C,A
  670.                 LD A,(HL)
  671.                 SBC A,B
  672.                 LD B,A
  673.                 RET
  674.  
  675. ; (ADR) + BCDE = BCDE
  676. BCDEHLP         LD A,(HL)
  677.                 INC HL
  678.                 ADD A,E
  679.                 LD E,A
  680.                 LD A,(HL)
  681.                 INC HL
  682.                 ADC A,D
  683.                 LD D,A
  684.                 LD A,(HL)
  685.                 INC HL
  686.                 ADC A,C
  687.                 LD C,A
  688.                 LD A,(HL)
  689.                 ADC A,B
  690.                 LD B,A
  691.                 RET
  692.  
  693. ; HLDE + BC = HLDE
  694. HLDEPBC         EX DE,HL
  695.                 ADD HL,BC
  696.                 EX DE,HL
  697.                 LD BC,0
  698.                 ADC HL,BC
  699.                 RET
  700.  
  701. ; BCDE - (ADR) = BCDE
  702. HLBCDEM         LD A,E
  703.                 SUB (HL)
  704.                 INC HL
  705.                 LD E,A
  706.                 LD A,D
  707.                 SBC A,(HL)
  708.                 INC HL
  709.                 LD D,A
  710.                 LD A,C
  711.                 SBC A,(HL)
  712.                 INC HL
  713.                 LD C,A
  714.                 LD A,B
  715.                 SBC A,(HL)
  716.                 LD B,A
  717.                 RET
  718.  
  719. ; проверка 0 сектора раздела
  720. VALID_BOOTSEC   LD HL,(BUF_512 + _BPB_BytsPerSec)
  721.                 LD A,H
  722.                 SUB 2
  723.                 OR L
  724.                 JR NZ,VALID_BOOTSEC1
  725.                 LD HL,(BUF_512 + _BPB_SecPerClus)
  726.                 OR L
  727.                 JR Z,VALID_BOOTSEC1
  728.                 NEG
  729.                 AND L
  730.                 CP L
  731.                 JR NZ,VALID_BOOTSEC1
  732.                 LD A,(BUF_512 + _BPB_NumFATs)
  733.                 DEC A
  734.                 CP 7
  735.                 JR NC,VALID_BOOTSEC1
  736.                 XOR A
  737.                 RET
  738.  
  739. VALID_BOOTSEC1  OR IXH
  740.                 RET
  741.  
  742. FAT_ERR         LD A,0xFF
  743.                 LD (FATType),A
  744.                 RET
  745.  
  746. ; инициализация переменных FAT
  747. INIT_FATVARS    LD A,0xFF
  748.                 LD (NumSec2Buf+3),A
  749.                 LD DE,0
  750.                 LD B,D
  751.                 LD C,E
  752.                 CALL READ_SECTOR
  753.                 PUSH HL
  754.                 POP IY
  755.                 LD DE,0x01BE
  756.                 ADD HL,DE
  757.                 LD A,(HL)
  758.                 AND A
  759.                 JR NZ,RDFAT05
  760.                 LD DE,4
  761.                 ADD HL,DE
  762.                 LD A,(HL)
  763.                 LD B,0
  764.                 CP 1
  765.                 JR Z,RDFAT06
  766.                 LD B,2
  767.                 CP 0x0B
  768.                 JR Z,RDFAT06
  769.                 CP 0x0C
  770.                 JR Z,RDFAT06
  771.                 LD B,1
  772.                 CP 6
  773.                 JR Z,RDFAT06
  774.                 CP 0x0E
  775.                 JR NZ,RDFAT05
  776. RDFAT06         LD A,B
  777.                 LD (FATType),A
  778.                 ADD HL,DE
  779.                 LD E,(HL)
  780.                 INC HL
  781.                 LD D,(HL)
  782.                 INC HL
  783.                 LD C,(HL)
  784.                 INC HL
  785.                 LD B,(HL)
  786.                 JR RDFAT00
  787.  
  788. RDFAT05         LD C,(IY+0x0D)
  789.                 XOR A
  790.                 LD E,A
  791.                 LD B,8
  792. .L4             RR C
  793.                 ADC A,0
  794.                 DJNZ .L4
  795.                 DEC A
  796.                 JR NZ,.L5
  797.                 INC E
  798. .L5             LD A,(IY+0x0E)
  799.                 OR (IY+0x0F)
  800.                 JR Z,.L2
  801.                 INC E
  802. .L2             LD A,(IY+0x13)
  803.                 OR (IY+0x14)
  804.                 JR NZ,.L3
  805.                 INC E
  806. .L3             LD A,(IY+0x20)
  807.                 OR (IY+0x21)
  808.                 OR (IY+0x22)
  809.                 OR (IY+0x23)
  810.                 JR NZ,.L6
  811.                 INC E
  812. .L6             LD A,(IY+0x15)
  813.                 AND 0xF0
  814.                 CP 0xF0
  815.                 JR NZ,.L1
  816.                 INC E
  817. .L1             LD A,E
  818.                 CP 4
  819.                 JP NZ,FAT_ERR
  820.                 LD A,0xFF
  821.                 LD (FATType),A
  822.                 LD DE,0
  823.                 LD B,D
  824.                 LD C,E
  825.  
  826. RDFAT00         LD (StartSecVol),DE
  827.                 LD (StartSecVol + 2),BC         ; положили номер стартового сектора раздела
  828.                 CALL READ_SECTOR                ; загрузили его
  829.  
  830.                 LD A,(BUF_512 + _BPB_SecPerClus)
  831.                 LD (SecPerClus),A
  832.                 LD HL,(BUF_512 + _BPB_RsvdSecCnt)
  833.                 ADD HL,DE
  834.                 LD (NumSecFAT1),HL
  835.                 LD HL,0
  836.                 ADC HL,BC
  837.                 LD (NumSecFAT1 + 2),HL
  838.                 LD HL,0
  839.                 LD DE,(BUF_512 + _BPB_FATSz16)
  840.                 LD A,D
  841.                 OR E
  842.                 JR NZ,RDFAT01                   ; если не FAT12/16 (_BPB_FATSz16 == 0)
  843.                 LD DE,(BUF_512 + _BPB_FATSz32)
  844.                 LD HL,(BUF_512 + _BPB_FATSz32 + 2)      ; то берем из смещения +36
  845. RDFAT01         LD (FATSize),DE
  846.                 LD (FATSize + 2),HL             ; число секторов на FAT-таблицу
  847.  
  848.                 LD HL,0
  849.                 LD DE,(BUF_512 + _BPB_TotSec16)
  850.                 LD A,D
  851.                 OR E
  852.                 JR NZ,.L1                       ; если не FAT12/16 (BPB_TOTSEC16=0)
  853.                 LD DE,(BUF_512 + _BPB_TotSec32)
  854.                 LD HL,(BUF_512 + _BPB_TotSec32+2)
  855.                                                 ; то берем из смещения +32
  856. .L1             LD (NumsSectorsVol + 2),HL
  857.                 LD (NumsSectorsVol),DE          ; количество секторов на диске/разделе
  858.  
  859. ; вычисляем ROOTDIRSECTORS
  860.                 LD DE,(BUF_512 + _BPB_RootEntCnt)
  861.                 LD BC,0
  862.                 LD A,D
  863.                 OR E
  864.                 JR Z,RDFAT03
  865.                 LD A,0x10
  866.                 CALL BCDE_A
  867.  
  868. ; это реализована формула
  869. ; ROOTDIRSECTORS=((BPB_ROOTENTCNT*32)++(BPB_BYTSPERSEC-1))/BPB_BYTSPERSEC
  870. ; в HL ROOTDIRSECTORS. если FAT32, то HL=0 всегда
  871.  
  872. RDFAT03         PUSH DE                         ; ROOTDIRSECTORS
  873.                 LD HL,NumSecFAT1
  874.                 CALL GET_DWORD
  875.                 LD A,(BUF_512 + _BPB_NumFATs)
  876.                 LD (NumFATs),A
  877.                 DEC A
  878.                 JR Z,.L1
  879.                 LD HL,FATSize
  880.                 CALL BCDEHLP
  881.                 LD (NumSecFAT2),DE
  882.                 LD (NumSecFAT2 + 2),BC
  883. .L1             LD HL,FATSize
  884.                 CALL BCDEHLP
  885.                 LD (NumSecRootDir),DE
  886.                 LD (NumSecRootDir + 2),BC
  887.                 POP HL
  888. ; добавляем размер ROOTDIR
  889.                 ADD HL,DE
  890.                 EX DE,HL
  891.                 LD HL,0
  892.                 ADC HL,BC
  893.                 LD B,H
  894.                 LD C,L
  895.                 LD (FirstSecData),DE
  896.                 LD (FirstSecData + 2),BC
  897.                 LD HL,NumsSectorsVol
  898.                 CALL BCDEHLM
  899.                 LD A,(SecPerClus)
  900.                 CALL BCDE_A
  901.                 LD (NumsClustersVol),DE
  902.                 LD (NumsClustersVol + 2),BC
  903.  
  904.                 LD A,(FATType)
  905.                 CP 0xFF
  906.                 JR NZ,RDFAT04
  907. ; определение типа FAT при отсуствии MBR
  908.                 LD HL,(BUF_512 + _BPB_FATSz16)
  909.                 LD A,H
  910.                 OR L
  911.                 LD A,2
  912.                 JR Z,.L2
  913.                 LD DE,(FATSize - 1)
  914.                 LD BC,(FATSize + 1)
  915.                 LD E,0                          ; BCDE = количество секторов * 0x100
  916.                 LD HL,NumsClustersVol           ; количество кластеров на FAT
  917.                 CALL HLBCDEM                    ; количество кластеров - (количество секторов * 0x100)
  918.                 LD A,D
  919.                 OR C
  920.                 OR B
  921.                 LD A,1                          ; FAT16
  922.                 JR Z,.L2                        ; FAT16 если флаг Z=0
  923.                 XOR A                           ; иначе FAT12
  924. .L2             LD (FATType),A
  925.  
  926. ; для FAT12/16 ROOT кластер = 0
  927. ; для FAT32 берем по смещению +44
  928. ; На выходе: BCDE - СЕКТОР ROOTDIR КЛАСТЕР
  929. RDFAT04         XOR A
  930.                 LD (TEK_LEV),A
  931.                 LD (BUF_PATH),A
  932. ;               CALL INIT_PATH
  933.                 LD A,(FATType)
  934.                 PUSH AF
  935.                 AND A
  936.                 LD DE,0
  937.                 LD B,D
  938.                 LD C,E
  939.                 JR Z,.L1                        ;FAT12-NONE
  940.                 DEC A
  941.                 JR Z,.L1                        ;FAT16
  942.                 LD DE,(BUF_512 + _BPB_RootClus)
  943.                 LD BC,(BUF_512 + _BPB_RootClus + 2)     ;FAT32
  944. .L1             LD (CurrentDIRCluster),DE
  945.                 LD (CurrentDIRCluster + 2),BC   ; номер текущего кластера
  946.                 LD (RootDIRCluster),DE
  947.                 LD (RootDIRCluster + 2),BC      ; номер корневого кластера
  948.                 LD (TEK_LEV),A
  949.                 POP AF
  950.                 JP INIRTSC
  951.  
  952. F_EXT           DW F_EXT_VS1001                 ; 0 for VS1001  (MA8201)        9B58
  953.                 DW F_EXT_VS1011                 ; 1 for VS1011  (MA8201A)       9B58
  954.                 DW 0    ; 2 for VS1002  ; не поддерживается, не проверялся
  955.                 DW F_EXT_VS1003                 ; 3 for VS1003
  956.                 DW F_EXT_VS1053                 ; 4 for VS1053 and VS8053       ; пока не доделан
  957.                 DW 0    ; 5 for VS1033  ; не поддерживается, не проверялся
  958.                 DW F_EXT_VS1063                 ; 6 for VS1063  ; пока не доделан
  959.                 DW 0    ; 7 for VS1103  ; не поддерживается, не проверялся
  960.  
  961. CP_EXT          PUSH BC
  962.                 PUSH DE
  963.                 PUSH HL
  964.                 PUSH HL
  965.                 LD C,0
  966.                 LD A,(VAR_CHIP_TYPE)
  967.                 ADD A,A
  968.                 ADD A,LOW (F_EXT)
  969.                 LD L,A
  970.                 ADC A,HIGH (F_EXT)
  971.                 SUB L
  972.                 LD H,A
  973.                 LD E,(HL)
  974.                 INC HL
  975.                 LD D,(HL)
  976.                 POP HL
  977. .L3             LD A,(DE)
  978.                 AND A
  979.                 JR Z,.L2
  980.                 INC C
  981.                 PUSH DE
  982.                 PUSH HL
  983.                 CALL COMPARF
  984.                 POP HL
  985.                 POP DE
  986.                 JR Z,.L1
  987.                 INC DE
  988.                 INC DE
  989.                 INC DE
  990.                 JR .L3
  991.  
  992. .L1             LD A,C
  993. .L2             POP HL
  994.                 POP DE
  995.                 POP BC
  996.                 RET
  997.  
  998. COMPARF         PUSH DE
  999.                 LD DE,8
  1000.                 ADD HL,DE
  1001.                 POP DE
  1002.                 LD B,3
  1003. .L1             LD A,(DE)
  1004.                 CP (HL)
  1005.                 RET NZ
  1006.                 INC HL
  1007.                 INC DE
  1008.                 DJNZ .L1
  1009.                 RET
  1010.  
  1011. ; открытие файла
  1012. ; на выходе:
  1013. ; A - тип файла (1 и далее)
  1014. OPENFIL         CALL SET_MP3
  1015.                 CALL GETFZAP
  1016.                 CALL CP_EXT
  1017.                 PUSH AF
  1018.                 LD DE,0x14
  1019.                 ADD HL,DE
  1020.                 LD C,(HL)
  1021.                 INC HL
  1022.                 LD B,(HL)
  1023.                 LD E,5
  1024.                 ADD HL,DE
  1025.                 LD E,(HL)
  1026.                 INC HL
  1027.                 LD D,(HL)
  1028.                 LD (TFILCLS),DE
  1029.                 LD (TFILCLS+2),BC
  1030.                 INC HL
  1031.                 LD E,(HL)
  1032.                 INC HL
  1033.                 LD D,(HL)
  1034.                 INC HL
  1035.                 LD C,(HL)
  1036.                 INC HL
  1037.                 LD B,(HL)
  1038.                 LD A,D
  1039.                 AND 1
  1040.                 OR E
  1041.                 EX AF,AF'
  1042.                 CALL BCDE200
  1043.                 LD A,(SecPerClus)
  1044.                 LD H,A
  1045.                 DEC A
  1046.                 AND E
  1047.                 LD L,A
  1048.                 EX AF,AF'
  1049.                 JR Z,.L1
  1050.                 INC L
  1051. .L1             LD A,L
  1052.                 LD (MPHWOST),A
  1053.                 LD A,H
  1054.                 CALL BCDE_A
  1055.                 LD (KOL_CLS),DE
  1056.                 LD (KOL_CLS+2),BC
  1057.                 XOR A
  1058.                 LD (NUMSECK),A
  1059.                 POP AF
  1060.                 RET
  1061.  
  1062. ; передача текущего сектора файла на декодер MP3
  1063. NEXTSEC         LD HL,KOL_CLS
  1064.                 LD A,(HL)
  1065.                 INC HL
  1066.                 OR (HL)
  1067.                 INC HL
  1068.                 OR (HL)
  1069.                 INC HL
  1070.                 OR (HL)
  1071.                 JR Z,LSTCLSF
  1072.                 LD DE,(TFILCLS)
  1073.                 LD BC,(TFILCLS+2)
  1074.                 PUSH DE
  1075.                 PUSH BC
  1076.                 CALL REALSEC
  1077.                 LD HL,(NUMSECK)
  1078.                 LD H,0
  1079.                 ADD HL,DE
  1080.                 EX DE,HL
  1081.                 LD HL,0
  1082.                 ADC HL,BC
  1083.                 LD B,H
  1084.                 LD C,L
  1085.                 LD A,9
  1086.                 CALL COM__SD
  1087.                 AND A
  1088.                 JP NZ,ERR_DRV
  1089.                 POP BC
  1090.                 POP DE
  1091.                 LD A,(NUMSECK)
  1092.                 INC A
  1093.                 LD H,A
  1094.                 LD (NUMSECK),A
  1095.                 LD A,(SecPerClus)
  1096.                 CP H
  1097.                 LD A,0                          ; выход не по ошибке
  1098.                 RET NZ
  1099.                 XOR A
  1100.                 LD (NUMSECK),A
  1101.                 CALL RDFATZP
  1102.                 LD (TFILCLS),DE
  1103.                 LD (TFILCLS+2),BC
  1104.                 LD HL,KOL_CLS
  1105.                 LD DE,1
  1106.                 LD B,D
  1107.                 LD C,D
  1108.                 CALL BCDEHLM
  1109.                 LD (KOL_CLS),DE
  1110.                 LD (KOL_CLS+2),BC
  1111.                 XOR A
  1112.                 INC A
  1113.                 RET
  1114.  
  1115. ; передача последнего сектора файла на декодер MP3
  1116. LSTCLSF         LD DE,(TFILCLS)
  1117.                 LD BC,(TFILCLS+2)
  1118.                 CALL REALSEC
  1119.                 LD HL,(NUMSECK)
  1120.                 LD H,0
  1121.                 ADD HL,DE
  1122.                 EX DE,HL
  1123.                 LD HL,0
  1124.                 ADC HL,BC
  1125.                 LD B,H
  1126.                 LD C,L
  1127.                 LD A,9
  1128.                 CALL COM__SD
  1129.                 AND A
  1130.                 JP NZ,ERR_DRV
  1131.                 LD A,(NUMSECK)
  1132.                 INC A
  1133.                 LD H,A
  1134.                 LD (NUMSECK),A
  1135.                 LD A,(MPHWOST)
  1136.                 AND A
  1137.                 RET Z
  1138.                 CP H
  1139.                 RET
  1140.  
  1141. ; инициализация переменных для текущего файла
  1142. SET_MP3         LD H,B
  1143.                 LD L,C
  1144.                 LD DE,(STR_MP3)
  1145.                 ADD HL,HL
  1146.                 ADD HL,HL
  1147.                 ADD HL,DE
  1148.                 LD E,(HL)
  1149.                 INC HL
  1150.                 LD D,(HL)
  1151.                 INC HL
  1152.                 PUSH HL
  1153.                 EX DE,HL
  1154.                 LD DE,CurrentDIRCluster
  1155.                 LDI
  1156.                 LDI
  1157.                 LDI
  1158.                 LDI
  1159.                 LD DE,(CurrentDIRCluster)
  1160.                 LD BC,(CurrentDIRCluster+2)
  1161.                 CALL INIRTSC
  1162.                 POP HL
  1163.                 LD E,(HL)
  1164.                 INC HL
  1165.                 LD D,(HL)
  1166.                 LD (TEK_ZAP),DE
  1167.                 RET
  1168.  
  1169. ; переход на предыдущую директорию
  1170. PRVDIR          LD HL,(KOLVDIR)
  1171.                 LD DE,2
  1172.                 AND A
  1173.                 SBC HL,DE
  1174.                 RET C
  1175.                 LD HL,(KOLVMP3)
  1176.                 AND A
  1177.                 SBC HL,DE
  1178.                 RET C
  1179.                 LD H,B
  1180.                 LD L,C
  1181.                 LD DE,(STR_MP3)
  1182.                 ADD HL,HL
  1183.                 ADD HL,HL
  1184.                 ADD HL,DE
  1185.                 PUSH HL
  1186.                 POP IX
  1187.                 LD H,B
  1188.                 LD L,C
  1189.                 LD BC,(KOLVMP3)
  1190.                 LD DE,0xFFFC
  1191.                 EXX
  1192.                 LD L,(IX+0)
  1193.                 LD H,(IX+1)
  1194.                 EXX
  1195.                 CALL PRVDIR2
  1196.                 CALL PRVDIR2
  1197.                 LD DE,4
  1198.                 JR NXTDIR2
  1199.  
  1200. PRVDIR2         EXX
  1201.                 LD D,H
  1202.                 LD E,L
  1203.                 LD L,(IX+0)
  1204.                 LD H,(IX+1)
  1205.                 AND A
  1206.                 SBC HL,DE
  1207.                 EX AF,AF'
  1208.                 ADD HL,DE
  1209.                 EX AF,AF'
  1210.                 EXX
  1211.                 RET NZ
  1212.                 LD A,H
  1213.                 OR L
  1214.                 JR Z,PRVDIR4
  1215.                 DEC HL
  1216.                 ADD IX,DE
  1217.                 JR PRVDIR2
  1218.  
  1219. PRVDIR4         LD H,B
  1220.                 LD L,C
  1221.                 DEC HL
  1222.                 ADD HL,HL
  1223.                 ADD HL,HL
  1224.                 LD IX,(STR_MP3)
  1225.                 EX DE,HL
  1226.                 ADD IX,DE
  1227.                 EX DE,HL
  1228.                 LD H,B
  1229.                 LD L,C
  1230.                 DEC HL
  1231.                 JR PRVDIR2
  1232.  
  1233. ; переход на следующую директорию
  1234. NXTDIR          LD HL,(KOLVDIR)
  1235.                 LD DE,2
  1236.                 AND A
  1237.                 SBC HL,DE
  1238.                 RET C
  1239.                 LD HL,(KOLVMP3)
  1240.                 AND A
  1241.                 SBC HL,DE
  1242.                 RET C
  1243.                 LD H,B
  1244.                 LD L,C
  1245.                 LD DE,(STR_MP3)
  1246.                 ADD HL,HL
  1247.                 ADD HL,HL
  1248.                 ADD HL,DE
  1249.                 PUSH HL
  1250.                 POP IX
  1251.                 LD H,B
  1252.                 LD L,C
  1253.                 LD BC,(KOLVMP3)
  1254.                 LD DE,4
  1255.                 EXX
  1256.                 LD L,(IX+0)
  1257.                 LD H,(IX+1)
  1258.                 EXX
  1259. NXTDIR2         EXX
  1260.                 LD D,H
  1261.                 LD E,L
  1262.                 LD L,(IX+0)
  1263.                 LD H,(IX+1)
  1264.                 AND A
  1265.                 SBC HL,DE
  1266.                 EX AF,AF'
  1267.                 ADD HL,DE
  1268.                 EX AF,AF'
  1269.                 EXX
  1270.                 JR NZ,NXTDIR3
  1271.                 INC HL
  1272.                 ADD IX,DE
  1273.                 AND A
  1274.                 SBC HL,BC
  1275.                 EX AF,AF'
  1276.                 ADD HL,BC
  1277.                 EX AF,AF'
  1278.                 JR NZ,NXTDIR2
  1279.                 LD HL,0
  1280.                 LD IX,(STR_MP3)
  1281.                 JR NXTDIR2
  1282.  
  1283. NXTDIR3         LD B,H
  1284.                 LD C,L
  1285.                 RET
  1286.  
  1287. ; включение следующей страницы памяти
  1288. SETPAGE         LD HL,BUF_PAG+0xFF
  1289.                 LD L,(HL)
  1290.                 LD A,(HL)
  1291.                 OUT (MPAGEX),A
  1292.                 LD L,0xFF
  1293.                 INC (HL)
  1294.                 RET
  1295.  
  1296. ; грузилка MOD в память NEOGS
  1297. LOADFIL         LD HL,BUF_PAG+0xFF
  1298.                 LD (HL),0
  1299.                 IN A,(GSCFG0)
  1300.                 SET B_EXPAG,A
  1301.                 OUT (GSCFG0),A
  1302.                 LD IY,(SecPerClus)
  1303. ; LY = кол-во секторов в кластере
  1304.                 LD A,IYL
  1305.                 CP 0x20
  1306.                 JR C,LDMF5
  1307. ; загрузка кластеров 32 и более секторов
  1308. LD_F5           LD DE,(TFILCLS)
  1309.                 LD BC,(TFILCLS+2)
  1310.                 CALL REALSEC
  1311.                 LD A,IYL
  1312.                 AND 0xE0
  1313.                 RLCA
  1314.                 RLCA
  1315.                 RLCA
  1316.                 LD IYH,A
  1317. LD_F9           LD A,0x20
  1318.                 EX AF,AF'
  1319.                 CALL SETPAGE
  1320.                 LD A,3
  1321.                 LD HL,0xC000
  1322.                 CALL COM__SD
  1323.                 AND A
  1324.                 JP NZ,ERR_DRV
  1325.                 LD HL,0x20
  1326.                 ADD HL,DE
  1327.                 EX DE,HL
  1328.                 LD HL,0
  1329.                 ADC HL,BC
  1330.                 LD B,H
  1331.                 LD C,L
  1332.                 DEC IYH
  1333.                 JR NZ,LD_F9
  1334.                 LD DE,(TFILCLS)
  1335.                 LD BC,(TFILCLS+2)
  1336.                 CALL RDFATZP
  1337.                 CALL LST_CLS
  1338.                 JR C,LD_E
  1339.                 LD (TFILCLS+2),BC
  1340.                 LD (TFILCLS),DE
  1341.                 JR LD_F5
  1342.  
  1343. LD_E            IN A,(GSCFG0)
  1344.                 RES B_EXPAG,A
  1345.                 OUT (GSCFG0),A
  1346.                 LD A,(VAR_PAGE_PLAYER)
  1347.                 OUT (MPAG),A
  1348.                 LD A,(BUF_PAG+0xFF)
  1349.                 SRL A
  1350.                 ADC A,0
  1351.                 RET
  1352.  
  1353. ; загрузка кластеров 16 и менее секторов
  1354. LDMF5           CALL SETPAGE
  1355.                 LD HL,0xC000
  1356. LDMF2           LD DE,(TFILCLS)
  1357.                 LD BC,(TFILCLS+2)
  1358.                 PUSH HL
  1359.                 CALL REALSEC
  1360.                 POP HL
  1361. LDMF3           LD A,IYL
  1362.                 EX AF,AF'
  1363.                 LD A,3
  1364.                 CALL COM__SD
  1365.                 AND A
  1366.                 JP NZ,ERR_DRV
  1367.                 PUSH HL
  1368.                 LD BC,(TFILCLS+2)
  1369.                 LD DE,(TFILCLS)
  1370.                 CALL RDFATZP
  1371.                 CALL LST_CLS
  1372.                 POP HL
  1373.                 JR C,LD_E
  1374.                 LD (TFILCLS+2),BC
  1375.                 LD (TFILCLS),DE
  1376.                 LD A,H
  1377.                 AND A
  1378.                 JR NZ,LDMF2
  1379.                 JR LDMF5
  1380.  
  1381. ; поиск всех директорий на FAT
  1382. FINDDIR         LD HL,STACK_CURR_DIR
  1383.                 LD (STACKPREVDIR),HL
  1384.                 LD DE,STR_DIR
  1385.                 LD HL,RootDIRCluster
  1386.                 LDI
  1387.                 LDI
  1388.                 LDI
  1389.                 LDI
  1390.                 LD (PAGEDIR),DE                 ; куда следующий номер кластера диры ложить
  1391. .L72            LD BC,0
  1392.                 CALL RDDIRSC
  1393.                 LD DE,0x20
  1394.                 PUSH HL
  1395.                 POP IX
  1396.                 LD A,(HL)
  1397.                 CP "."
  1398.                 JR NZ,.L3
  1399.                 LD A,(IX+1)
  1400.                 CP "."
  1401.                 JR Z,.NEXTDIR
  1402.                 INC BC
  1403.                 ADD IX,DE
  1404. .NEXTDIR        INC BC
  1405.                 ADD IX,DE
  1406. .L3             LD A,IXH
  1407.                 CP HIGH (BUF_512) + 2
  1408.                 JR NZ,.L2                       ; сектор кончился?
  1409.                 CALL RDDIRSC
  1410.                 JR NZ,.FNDDIR5                  ; конец DIR
  1411.                 LD DE,0x20
  1412.                 PUSH HL
  1413.                 POP IX
  1414. .L2             LD A,(IX+0)
  1415.                 AND A
  1416.                 JR Z,.FNDDIR5                   ; конец DIR?
  1417.                 CP 0xE5
  1418.                 JR Z,.NEXTDIR                   ; файл удален?
  1419.                 LD A,(IX + _DIR_Attr)
  1420.                 CP M_DIR_AttrLongName
  1421.                 JR Z,.NEXTDIR                   ; это длинное имя?
  1422.                 CP M_DIR_VolumeID
  1423.                 JR Z,.NEXTDIR                   ; это имя раздела?
  1424.                 BIT 4,(IX + _DIR_Attr)
  1425.                 JR Z,.NEXTDIR                   ; это директория?
  1426. ; укладка номера кластера найденной DIR
  1427.                 LD HL,(PAGEDIR)                 ; куда ложить
  1428.                 LD A,(IX+0x1A)
  1429.                 LD (HL),A
  1430.                 INC HL
  1431.                 LD A,(IX+0x1B)
  1432.                 LD (HL),A
  1433.                 INC HL
  1434.                 LD A,(IX+0x14)
  1435.                 LD (HL),A
  1436.                 INC HL
  1437.                 LD A,(IX+0x15)
  1438.                 LD (HL),A
  1439.                 INC HL                          ; уложили номер кластера найденной DIR
  1440.                 LD (PAGEDIR),HL
  1441.                 LD HL,(STACKPREVDIR)
  1442.                 DEC HL
  1443.                 LD (HL),B
  1444.                 DEC HL
  1445.                 LD (HL),C                       ; сохранили номер текущей диры
  1446.                 LD (STACKPREVDIR),HL
  1447.                 LD (TEK_ZAP),BC
  1448.                 CALL ENT_DIR
  1449.                 JP .L72
  1450.  
  1451. ; выход из директории и проверка попытки выхода из корневой директории
  1452. .FNDDIR5        LD A,(STACKPREVDIR + 1)
  1453.                 CP HIGH (STACK_CURR_DIR)
  1454.                 JR NC,FNDDIR0
  1455.                 LD BC,0
  1456.                 CALL RDDIRSC
  1457.                 PUSH HL
  1458.                 POP IX
  1459.                 LD DE,0x20
  1460.                 LD A,(HL)
  1461.                 CP "."
  1462.                 JR NZ,.FNDDI52
  1463.                 INC HL
  1464.                 LD A,(HL)
  1465.                 CP "."
  1466.                 JR Z,.FNDDI52
  1467.                 INC BC
  1468.                 ADD IX,DE
  1469. .FNDDI52        LD (TEK_ZAP),BC
  1470.                 CALL ENT_DIR                    ; выход из диры
  1471.                 LD HL,(STACKPREVDIR)
  1472.                 LD C,(HL)
  1473.                 INC HL
  1474.                 LD B,(HL)
  1475.                 INC HL
  1476.                 LD (STACKPREVDIR),HL
  1477.                 CALL RDDIRSC
  1478.                 LD A,C
  1479.                 AND 0x0F
  1480.                 LD E,A
  1481.                 LD D,0
  1482.                 EX DE,HL
  1483.                 ADD HL,HL
  1484.                 ADD HL,HL
  1485.                 ADD HL,HL
  1486.                 ADD HL,HL
  1487.                 ADD HL,HL
  1488.                 ADD HL,DE
  1489.                 PUSH HL
  1490.                 POP IX
  1491.                 LD DE,0x20
  1492.                 JP .NEXTDIR
  1493.  
  1494. ; все DIR найдены
  1495. FNDDIR0         LD HL,(PAGEDIR)
  1496.                 LD D,H
  1497.                 LD E,L
  1498.                 INC HL
  1499.                 INC HL
  1500.                 INC HL
  1501.                 LD (HL),0xFF
  1502.                 PUSH HL
  1503.                 EX DE,HL
  1504.                 LD DE,STR_DIR
  1505.                 AND A
  1506.                 SBC HL,DE
  1507.                 SRL H
  1508.                 RR L
  1509.                 SRL H
  1510.                 RR L
  1511.                 LD (KOLVDIR),HL
  1512.                 EX (SP),HL
  1513.                 INC HL
  1514.                 LD (STR_MP3),HL
  1515.                 POP HL
  1516.                 RET
  1517.  
  1518. ; все файлы найдены или память кончилась
  1519. FNDMP30         LD HL,(PAGEMP3)
  1520.                 LD DE,(STR_MP3)
  1521.                 PUSH HL
  1522.                 POP IX
  1523.                 LD (HL),0
  1524.                 INC L
  1525.                 LD (HL),0
  1526.                 DEC L
  1527.                 AND A
  1528.                 SBC HL,DE
  1529.                 SRL H
  1530.                 RR L
  1531.                 SRL H
  1532.                 RR L
  1533.                 LD DE,2
  1534.                 LD (KOLVMP3),HL
  1535.                 LD (VAR_COUNT_MP3),HL
  1536.                 AND A
  1537.                 SBC HL,DE
  1538.                 EX AF,AF'
  1539.                 ADD HL,DE
  1540.                 EX AF,AF'
  1541.                 RET C
  1542.                 PUSH HL
  1543.                 LD IY,1
  1544.                 LD B,H
  1545.                 LD C,L
  1546.                 LD DE,0xFFFC
  1547.                 ADD IX,DE
  1548.                 DEC HL
  1549.                 EXX
  1550.                 LD L,(IX+0)
  1551.                 LD H,(IX+1)
  1552.                 EXX
  1553. FNDM030         EXX
  1554.                 LD D,H
  1555.                 LD E,L
  1556.                 LD L,(IX+0)
  1557.                 LD H,(IX+1)
  1558.                 AND A
  1559.                 SBC HL,DE
  1560.                 EX AF,AF'
  1561.                 ADD HL,DE
  1562.                 EX AF,AF'
  1563.                 EXX
  1564.                 JR Z,.L1
  1565.                 INC IY
  1566. .L1             LD A,H
  1567.                 OR L
  1568.                 JR Z,FNDM033                    ; память кончилась, выходим
  1569.                 DEC HL
  1570.                 ADD IX,DE
  1571.                 JR FNDM030
  1572.  
  1573. FNDM033         LD (KOLVDIR),IY                 ; количество найденных директорий
  1574.                 POP HL
  1575.                 RET
  1576.  
  1577. ; поиск файлов по расширению
  1578. FINDMP3         LD HL,(STR_MP3)
  1579.                 LD (PAGEMP3),HL
  1580.                 LD HL,STR_DIR
  1581.                 LD (PAGEDIR),HL
  1582. .FNDMP37        LD HL,(PAGEDIR)
  1583.                 LD (TEKNUMC),HL
  1584.                 LD DE,CurrentDIRCluster
  1585.                 LDI
  1586.                 LDI
  1587.                 LDI
  1588.                 LDI
  1589.                 LD (PAGEDIR),HL
  1590.                 DEC HL
  1591.                 BIT 7,(HL)
  1592.                 JP NZ,FNDMP30
  1593.                 LD DE,(CurrentDIRCluster)
  1594.                 LD BC,(CurrentDIRCluster+2)
  1595.                 CALL INIRTSC
  1596.                 LD BC,0
  1597.                 CALL RDDIRSC
  1598.                 LD DE,0x20
  1599.                 PUSH HL
  1600.                 POP IX
  1601.                 LD A,(HL)
  1602.                 CP "."
  1603.                 JR NZ,.ROOT
  1604.                 LD A,(IX+1)
  1605.                 CP "."
  1606.                 JR Z,.NEXTFILE
  1607.                 INC BC
  1608.                 ADD IX,DE
  1609. .NEXTFILE       INC BC
  1610.                 ADD IX,DE
  1611. .ROOT           LD A,IXH
  1612.                 CP HIGH (BUF_512) + 2
  1613.                 JR NZ,.FNDMP32
  1614.                 CALL RDDIRSC
  1615.                 JP NZ,.FNDMP37
  1616.                 LD DE,0x20
  1617.                 PUSH HL
  1618.                 POP IX
  1619. .FNDMP32        LD A,(IX+0)
  1620.                 AND A
  1621.                 JP Z,.FNDMP37                   ; конец DIR?
  1622.                 CP 0xE5
  1623.                 JR Z,.NEXTFILE                  ; файл удален?
  1624.                 LD A,(IX + _DIR_Attr)
  1625.                 CP M_DIR_AttrLongName
  1626.                 JR Z,.NEXTFILE                  ; это длинное имя?
  1627.                 CP M_DIR_VolumeID
  1628.                 JR Z,.NEXTFILE                  ; это имя раздела?
  1629.                 BIT 4,(IX + _DIR_Attr)
  1630.                 JR NZ,.NEXTFILE                 ; это директория?
  1631.                 EXX
  1632.                 PUSH IX
  1633.                 POP HL
  1634.                 CALL CP_EXT                     ; проверяем расширение файла
  1635.                 EXX
  1636.                 AND A
  1637.                 JP Z,.NEXTFILE                  ; не совпало, продолжаем
  1638.                 LD DE,(TEKNUMC)
  1639.                 LD HL,(PAGEMP3)
  1640. ; укладка описателя файла
  1641. ; 2 байта адрес кластера диры
  1642. ; 2 байта "реальный" номер файла
  1643.                 LD (HL),E
  1644.                 INC HL
  1645.                 LD (HL),D
  1646.                 INC HL
  1647.                 LD (HL),C
  1648.                 INC HL
  1649.                 LD (HL),B
  1650.                 INC HL
  1651.                 LD (PAGEMP3),HL
  1652.                 LD A,H
  1653.                 AND A
  1654.                 JP Z,FNDMP30                    ; память кончилась, выходим
  1655.                 LD DE,0x20
  1656.                 JR .NEXTFILE
  1657.