Subversion Repositories ngs

Rev

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

  1.  
  2. ; LAST UPDATE: 13.01.2024 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,(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           DZ "MP3MOD"
  953.  
  954. CP_EXT          PUSH BC
  955.                 PUSH DE
  956.                 PUSH HL
  957.                 LD C,0
  958.                 LD DE,F_EXT
  959. .L3             LD A,(DE)
  960.                 AND A
  961.                 JR Z,.L2
  962.                 INC C
  963.                 PUSH DE
  964.                 PUSH HL
  965.                 CALL COMPARF
  966.                 POP HL
  967.                 POP DE
  968.                 JR Z,.L1
  969.                 INC DE
  970.                 INC DE
  971.                 INC DE
  972.                 JR .L3
  973.  
  974. .L1             LD A,C
  975. .L2             POP HL
  976.                 POP DE
  977.                 POP BC
  978.                 RET
  979.  
  980. COMPARF         PUSH DE
  981.                 LD DE,8
  982.                 ADD HL,DE
  983.                 POP DE
  984.                 LD B,3
  985. .L1             LD A,(DE)
  986.                 CP (HL)
  987.                 RET NZ
  988.                 INC HL
  989.                 INC DE
  990.                 DJNZ .L1
  991.                 RET
  992.  
  993. ; открытие файла
  994. ; на выходе:
  995. ; A - тип файла (1 и далее)
  996. OPENFIL         CALL SET_MP3
  997.                 CALL GETFZAP
  998.                 CALL CP_EXT
  999.                 PUSH AF
  1000.                 LD DE,0x14
  1001.                 ADD HL,DE
  1002.                 LD C,(HL)
  1003.                 INC HL
  1004.                 LD B,(HL)
  1005.                 LD E,5
  1006.                 ADD HL,DE
  1007.                 LD E,(HL)
  1008.                 INC HL
  1009.                 LD D,(HL)
  1010.                 LD (TFILCLS),DE
  1011.                 LD (TFILCLS+2),BC
  1012.                 INC HL
  1013.                 LD E,(HL)
  1014.                 INC HL
  1015.                 LD D,(HL)
  1016.                 INC HL
  1017.                 LD C,(HL)
  1018.                 INC HL
  1019.                 LD B,(HL)
  1020.                 LD A,D
  1021.                 AND 1
  1022.                 OR E
  1023.                 EX AF,AF'
  1024.                 CALL BCDE200
  1025.                 LD A,(SecPerClus)
  1026.                 LD H,A
  1027.                 DEC A
  1028.                 AND E
  1029.                 LD L,A
  1030.                 EX AF,AF'
  1031.                 JR Z,.L1
  1032.                 INC L
  1033. .L1             LD A,L
  1034.                 LD (MPHWOST),A
  1035.                 LD A,H
  1036.                 CALL BCDE_A
  1037.                 LD (KOL_CLS),DE
  1038.                 LD (KOL_CLS+2),BC
  1039.                 XOR A
  1040.                 LD (NUMSECK),A
  1041.                 POP AF
  1042.                 RET
  1043.  
  1044. ; передача текущего сектора файла на декодер MP3
  1045. NEXTSEC         LD HL,KOL_CLS
  1046.                 LD A,(HL)
  1047.                 INC HL
  1048.                 OR (HL)
  1049.                 INC HL
  1050.                 OR (HL)
  1051.                 INC HL
  1052.                 OR (HL)
  1053.                 JR Z,LSTCLSF
  1054.                 LD DE,(TFILCLS)
  1055.                 LD BC,(TFILCLS+2)
  1056.                 PUSH DE
  1057.                 PUSH BC
  1058.                 CALL REALSEC
  1059.                 LD HL,(NUMSECK)
  1060.                 LD H,0
  1061.                 ADD HL,DE
  1062.                 EX DE,HL
  1063.                 LD HL,0
  1064.                 ADC HL,BC
  1065.                 LD B,H
  1066.                 LD C,L
  1067.                 LD A,9
  1068.                 CALL COM__SD
  1069.                 AND A
  1070.                 JP NZ,ERR_DRV
  1071.                 POP BC
  1072.                 POP DE
  1073.                 LD A,(NUMSECK)
  1074.                 INC A
  1075.                 LD H,A
  1076.                 LD (NUMSECK),A
  1077.                 LD A,(SecPerClus)
  1078.                 CP H
  1079.                 LD A,0                          ; выход не по ошибке
  1080.                 RET NZ
  1081.                 XOR A
  1082.                 LD (NUMSECK),A
  1083.                 CALL RDFATZP
  1084.                 LD (TFILCLS),DE
  1085.                 LD (TFILCLS+2),BC
  1086.                 LD HL,KOL_CLS
  1087.                 LD DE,1
  1088.                 LD B,D
  1089.                 LD C,D
  1090.                 CALL BCDEHLM
  1091.                 LD (KOL_CLS),DE
  1092.                 LD (KOL_CLS+2),BC
  1093.                 XOR A
  1094.                 INC A
  1095.                 RET
  1096.  
  1097. ; передача последнего сектора файла на декодер MP3
  1098. LSTCLSF         LD DE,(TFILCLS)
  1099.                 LD BC,(TFILCLS+2)
  1100.                 CALL REALSEC
  1101.                 LD HL,(NUMSECK)
  1102.                 LD H,0
  1103.                 ADD HL,DE
  1104.                 EX DE,HL
  1105.                 LD HL,0
  1106.                 ADC HL,BC
  1107.                 LD B,H
  1108.                 LD C,L
  1109.                 LD A,9
  1110.                 CALL COM__SD
  1111.                 AND A
  1112.                 JP NZ,ERR_DRV
  1113.                 LD A,(NUMSECK)
  1114.                 INC A
  1115.                 LD H,A
  1116.                 LD (NUMSECK),A
  1117.                 LD A,(MPHWOST)
  1118.                 AND A
  1119.                 RET Z
  1120.                 CP H
  1121.                 RET
  1122.  
  1123. ; инициализация переменных для текущего файла
  1124. SET_MP3         LD H,B
  1125.                 LD L,C
  1126.                 LD DE,(STR_MP3)
  1127.                 ADD HL,HL
  1128.                 ADD HL,HL
  1129.                 ADD HL,DE
  1130.                 LD E,(HL)
  1131.                 INC HL
  1132.                 LD D,(HL)
  1133.                 INC HL
  1134.                 PUSH HL
  1135.                 EX DE,HL
  1136.                 LD DE,CurrentDIRCluster
  1137.                 LDI
  1138.                 LDI
  1139.                 LDI
  1140.                 LDI
  1141.                 LD DE,(CurrentDIRCluster)
  1142.                 LD BC,(CurrentDIRCluster+2)
  1143.                 CALL INIRTSC
  1144.                 POP HL
  1145.                 LD E,(HL)
  1146.                 INC HL
  1147.                 LD D,(HL)
  1148.                 LD (TEK_ZAP),DE
  1149.                 RET
  1150.  
  1151. ; переход на предыдущую директорию
  1152. PRVDIR          LD HL,(KOLVDIR)
  1153.                 LD DE,2
  1154.                 AND A
  1155.                 SBC HL,DE
  1156.                 RET C
  1157.                 LD HL,(KOLVMP3)
  1158.                 AND A
  1159.                 SBC HL,DE
  1160.                 RET C
  1161.                 LD H,B
  1162.                 LD L,C
  1163.                 LD DE,(STR_MP3)
  1164.                 ADD HL,HL
  1165.                 ADD HL,HL
  1166.                 ADD HL,DE
  1167.                 PUSH HL
  1168.                 POP IX
  1169.                 LD H,B
  1170.                 LD L,C
  1171.                 LD BC,(KOLVMP3)
  1172.                 LD DE,0xFFFC
  1173.                 EXX
  1174.                 LD L,(IX+0)
  1175.                 LD H,(IX+1)
  1176.                 EXX
  1177.                 CALL PRVDIR2
  1178.                 CALL PRVDIR2
  1179.                 LD DE,4
  1180.                 JR NXTDIR2
  1181.  
  1182. PRVDIR2         EXX
  1183.                 LD D,H
  1184.                 LD E,L
  1185.                 LD L,(IX+0)
  1186.                 LD H,(IX+1)
  1187.                 AND A
  1188.                 SBC HL,DE
  1189.                 EX AF,AF'
  1190.                 ADD HL,DE
  1191.                 EX AF,AF'
  1192.                 EXX
  1193.                 RET NZ
  1194.                 LD A,H
  1195.                 OR L
  1196.                 JR Z,PRVDIR4
  1197.                 DEC HL
  1198.                 ADD IX,DE
  1199.                 JR PRVDIR2
  1200.  
  1201. PRVDIR4         LD H,B
  1202.                 LD L,C
  1203.                 DEC HL
  1204.                 ADD HL,HL
  1205.                 ADD HL,HL
  1206.                 LD IX,(STR_MP3)
  1207.                 EX DE,HL
  1208.                 ADD IX,DE
  1209.                 EX DE,HL
  1210.                 LD H,B
  1211.                 LD L,C
  1212.                 DEC HL
  1213.                 JR PRVDIR2
  1214.  
  1215. ; переход на следующую директорию
  1216. NXTDIR          LD HL,(KOLVDIR)
  1217.                 LD DE,2
  1218.                 AND A
  1219.                 SBC HL,DE
  1220.                 RET C
  1221.                 LD HL,(KOLVMP3)
  1222.                 AND A
  1223.                 SBC HL,DE
  1224.                 RET C
  1225.                 LD H,B
  1226.                 LD L,C
  1227.                 LD DE,(STR_MP3)
  1228.                 ADD HL,HL
  1229.                 ADD HL,HL
  1230.                 ADD HL,DE
  1231.                 PUSH HL
  1232.                 POP IX
  1233.                 LD H,B
  1234.                 LD L,C
  1235.                 LD BC,(KOLVMP3)
  1236.                 LD DE,4
  1237.                 EXX
  1238.                 LD L,(IX+0)
  1239.                 LD H,(IX+1)
  1240.                 EXX
  1241. NXTDIR2         EXX
  1242.                 LD D,H
  1243.                 LD E,L
  1244.                 LD L,(IX+0)
  1245.                 LD H,(IX+1)
  1246.                 AND A
  1247.                 SBC HL,DE
  1248.                 EX AF,AF'
  1249.                 ADD HL,DE
  1250.                 EX AF,AF'
  1251.                 EXX
  1252.                 JR NZ,NXTDIR3
  1253.                 INC HL
  1254.                 ADD IX,DE
  1255.                 AND A
  1256.                 SBC HL,BC
  1257.                 EX AF,AF'
  1258.                 ADD HL,BC
  1259.                 EX AF,AF'
  1260.                 JR NZ,NXTDIR2
  1261.                 LD HL,0
  1262.                 LD IX,(STR_MP3)
  1263.                 JR NXTDIR2
  1264.  
  1265. NXTDIR3         LD B,H
  1266.                 LD C,L
  1267.                 RET
  1268.  
  1269. ; включение следующей страницы памяти
  1270. SETPAGE         LD HL,BUF_PAG+0xFF
  1271.                 LD L,(HL)
  1272.                 LD A,(HL)
  1273.                 OUT (MPAGEX),A
  1274.                 LD L,0xFF
  1275.                 INC (HL)
  1276.                 RET
  1277.  
  1278. ; грузилка MOD в память NEOGS
  1279. LOADFIL         LD HL,BUF_PAG+0xFF
  1280.                 LD (HL),0
  1281.                 IN A,(GSCFG0)
  1282.                 SET B_EXPAG,A
  1283.                 OUT (GSCFG0),A
  1284.                 LD IY,(SecPerClus)
  1285. ; LY = кол-во секторов в кластере
  1286.                 LD A,IYL
  1287.                 CP 0x20
  1288.                 JR C,LDMF5
  1289. ; загрузка кластеров 32 и более секторов
  1290. LD_F5           LD DE,(TFILCLS)
  1291.                 LD BC,(TFILCLS+2)
  1292.                 CALL REALSEC
  1293.                 LD A,IYL
  1294.                 AND 0xE0
  1295.                 RLCA
  1296.                 RLCA
  1297.                 RLCA
  1298.                 LD IYH,A
  1299. LD_F9           LD A,0x20
  1300.                 EX AF,AF'
  1301.                 CALL SETPAGE
  1302.                 LD A,3
  1303.                 LD HL,0xC000
  1304.                 CALL COM__SD
  1305.                 AND A
  1306.                 JP NZ,ERR_DRV
  1307.                 LD HL,0x20
  1308.                 ADD HL,DE
  1309.                 EX DE,HL
  1310.                 LD HL,0
  1311.                 ADC HL,BC
  1312.                 LD B,H
  1313.                 LD C,L
  1314.                 DEC IYH
  1315.                 JR NZ,LD_F9
  1316.                 LD DE,(TFILCLS)
  1317.                 LD BC,(TFILCLS+2)
  1318.                 CALL RDFATZP
  1319.                 CALL LST_CLS
  1320.                 JR C,LD_E
  1321.                 LD (TFILCLS+2),BC
  1322.                 LD (TFILCLS),DE
  1323.                 JR LD_F5
  1324.  
  1325. LD_E            IN A,(GSCFG0)
  1326.                 RES B_EXPAG,A
  1327.                 OUT (GSCFG0),A
  1328.                 LD A,(PAGE_PLAYER)
  1329.                 OUT (MPAG),A
  1330.                 LD A,(BUF_PAG+0xFF)
  1331.                 SRL A
  1332.                 ADC A,0
  1333.                 RET
  1334.  
  1335. ; загрузка кластеров 16 и менее секторов
  1336. LDMF5           CALL SETPAGE
  1337.                 LD HL,0xC000
  1338. LDMF2           LD DE,(TFILCLS)
  1339.                 LD BC,(TFILCLS+2)
  1340.                 PUSH HL
  1341.                 CALL REALSEC
  1342.                 POP HL
  1343. LDMF3           LD A,IYL
  1344.                 EX AF,AF'
  1345.                 LD A,3
  1346.                 CALL COM__SD
  1347.                 AND A
  1348.                 JP NZ,ERR_DRV
  1349.                 PUSH HL
  1350.                 LD BC,(TFILCLS+2)
  1351.                 LD DE,(TFILCLS)
  1352.                 CALL RDFATZP
  1353.                 CALL LST_CLS
  1354.                 POP HL
  1355.                 JR C,LD_E
  1356.                 LD (TFILCLS+2),BC
  1357.                 LD (TFILCLS),DE
  1358.                 LD A,H
  1359.                 AND A
  1360.                 JR NZ,LDMF2
  1361.                 JR LDMF5
  1362.  
  1363. ; поиск всех директорий на FAT
  1364. FINDDIR         LD HL,STACK_CURR_DIR
  1365.                 LD (STACKPREVDIR),HL
  1366.                 LD DE,STR_DIR
  1367.                 LD HL,RootDIRCluster
  1368.                 LDI
  1369.                 LDI
  1370.                 LDI
  1371.                 LDI
  1372.                 LD (PAGEDIR),DE                 ; куда следующий номер кластера диры ложить
  1373. .L72            LD BC,0
  1374.                 CALL RDDIRSC
  1375.                 LD DE,0x20
  1376.                 PUSH HL
  1377.                 POP IX
  1378.                 LD A,(HL)
  1379.                 CP "."
  1380.                 JR NZ,.L3
  1381.                 LD A,(IX+1)
  1382.                 CP "."
  1383.                 JR Z,.NEXTDIR
  1384.                 INC BC
  1385.                 ADD IX,DE
  1386. .NEXTDIR        INC BC
  1387.                 ADD IX,DE
  1388. .L3             LD A,IXH
  1389.                 CP HIGH (BUF_512) + 2
  1390.                 JR NZ,.L2                       ; сектор кончился?
  1391.                 CALL RDDIRSC
  1392.                 JR NZ,.FNDDIR5                  ; конец DIR
  1393.                 LD DE,0x20
  1394.                 PUSH HL
  1395.                 POP IX
  1396. .L2             LD A,(IX+0)
  1397.                 AND A
  1398.                 JR Z,.FNDDIR5                   ; конец DIR?
  1399.                 CP 0xE5
  1400.                 JR Z,.NEXTDIR                   ; файл удален?
  1401.                 LD A,(IX + _DIR_Attr)
  1402.                 CP M_DIR_AttrLongName
  1403.                 JR Z,.NEXTDIR                   ; это длинное имя?
  1404.                 CP M_DIR_VolumeID
  1405.                 JR Z,.NEXTDIR                   ; это имя раздела?
  1406.                 BIT 4,(IX + _DIR_Attr)
  1407.                 JR Z,.NEXTDIR                   ; это директория?
  1408. ; укладка номера кластера найденной DIR
  1409.                 LD HL,(PAGEDIR)                 ; куда ложить
  1410.                 LD A,(IX+0x1A)
  1411.                 LD (HL),A
  1412.                 INC HL
  1413.                 LD A,(IX+0x1B)
  1414.                 LD (HL),A
  1415.                 INC HL
  1416.                 LD A,(IX+0x14)
  1417.                 LD (HL),A
  1418.                 INC HL
  1419.                 LD A,(IX+0x15)
  1420.                 LD (HL),A
  1421.                 INC HL                          ; уложили номер кластера найденной DIR
  1422.                 LD (PAGEDIR),HL
  1423.                 LD HL,(STACKPREVDIR)
  1424.                 DEC HL
  1425.                 LD (HL),B
  1426.                 DEC HL
  1427.                 LD (HL),C                       ; сохранили номер текущей диры
  1428.                 LD (STACKPREVDIR),HL
  1429.                 LD (TEK_ZAP),BC
  1430.                 CALL ENT_DIR
  1431.                 JP .L72
  1432.  
  1433. ; выход из директории и проверка попытки выхода из корневой директории
  1434. .FNDDIR5        LD A,(STACKPREVDIR + 1)
  1435.                 CP HIGH (STACK_CURR_DIR)
  1436.                 JR NC,FNDDIR0
  1437.                 LD BC,0
  1438.                 CALL RDDIRSC
  1439.                 PUSH HL
  1440.                 POP IX
  1441.                 LD DE,0x20
  1442.                 LD A,(HL)
  1443.                 CP "."
  1444.                 JR NZ,.FNDDI52
  1445.                 INC HL
  1446.                 LD A,(HL)
  1447.                 CP "."
  1448.                 JR Z,.FNDDI52
  1449.                 INC BC
  1450.                 ADD IX,DE
  1451. .FNDDI52        LD (TEK_ZAP),BC
  1452.                 CALL ENT_DIR                    ; выход из диры
  1453.                 LD HL,(STACKPREVDIR)
  1454.                 LD C,(HL)
  1455.                 INC HL
  1456.                 LD B,(HL)
  1457.                 INC HL
  1458.                 LD (STACKPREVDIR),HL
  1459.                 CALL RDDIRSC
  1460.                 LD A,C
  1461.                 AND 0x0F
  1462.                 LD E,A
  1463.                 LD D,0
  1464.                 EX DE,HL
  1465.                 ADD HL,HL
  1466.                 ADD HL,HL
  1467.                 ADD HL,HL
  1468.                 ADD HL,HL
  1469.                 ADD HL,HL
  1470.                 ADD HL,DE
  1471.                 PUSH HL
  1472.                 POP IX
  1473.                 LD DE,0x20
  1474.                 JP .NEXTDIR
  1475.  
  1476. ; все DIR найдены
  1477. FNDDIR0         LD HL,(PAGEDIR)
  1478.                 LD D,H
  1479.                 LD E,L
  1480.                 INC HL
  1481.                 INC HL
  1482.                 INC HL
  1483.                 LD (HL),0xFF
  1484.                 PUSH HL
  1485.                 EX DE,HL
  1486.                 LD DE,STR_DIR
  1487.                 AND A
  1488.                 SBC HL,DE
  1489.                 SRL H
  1490.                 RR L
  1491.                 SRL H
  1492.                 RR L
  1493.                 LD (KOLVDIR),HL
  1494.                 EX (SP),HL
  1495.                 INC HL
  1496.                 LD (STR_MP3),HL
  1497.                 POP HL
  1498.                 RET
  1499.  
  1500. ; все файлы найдены или память кончилась
  1501. FNDMP30         LD HL,(PAGEMP3)
  1502.                 LD DE,(STR_MP3)
  1503.                 PUSH HL
  1504.                 POP IX
  1505.                 LD (HL),0
  1506.                 INC L
  1507.                 LD (HL),0
  1508.                 DEC L
  1509.                 AND A
  1510.                 SBC HL,DE
  1511.                 SRL H
  1512.                 RR L
  1513.                 SRL H
  1514.                 RR L
  1515.                 LD DE,2
  1516.                 LD (KOLVMP3),HL
  1517.                 LD (COUNT_MP3),HL
  1518.                 AND A
  1519.                 SBC HL,DE
  1520.                 EX AF,AF'
  1521.                 ADD HL,DE
  1522.                 EX AF,AF'
  1523.                 RET C
  1524.                 PUSH HL
  1525.                 LD IY,1
  1526.                 LD B,H
  1527.                 LD C,L
  1528.                 LD DE,0xFFFC
  1529.                 ADD IX,DE
  1530.                 DEC HL
  1531.                 EXX
  1532.                 LD L,(IX+0)
  1533.                 LD H,(IX+1)
  1534.                 EXX
  1535. FNDM030         EXX
  1536.                 LD D,H
  1537.                 LD E,L
  1538.                 LD L,(IX+0)
  1539.                 LD H,(IX+1)
  1540.                 AND A
  1541.                 SBC HL,DE
  1542.                 EX AF,AF'
  1543.                 ADD HL,DE
  1544.                 EX AF,AF'
  1545.                 EXX
  1546.                 JR Z,.L1
  1547.                 INC IY
  1548. .L1             LD A,H
  1549.                 OR L
  1550.                 JR Z,FNDM033                    ; память кончилась, выходим
  1551.                 DEC HL
  1552.                 ADD IX,DE
  1553.                 JR FNDM030
  1554.  
  1555. FNDM033         LD (KOLVDIR),IY                 ; количество найденных директорий
  1556.                 POP HL
  1557.                 RET
  1558.  
  1559. ; поиск файлов по расширению
  1560. FINDMP3         LD HL,(STR_MP3)
  1561.                 LD (PAGEMP3),HL
  1562.                 LD HL,STR_DIR
  1563.                 LD (PAGEDIR),HL
  1564. .FNDMP37        LD HL,(PAGEDIR)
  1565.                 LD (TEKNUMC),HL
  1566.                 LD DE,CurrentDIRCluster
  1567.                 LDI
  1568.                 LDI
  1569.                 LDI
  1570.                 LDI
  1571.                 LD (PAGEDIR),HL
  1572.                 DEC HL
  1573.                 BIT 7,(HL)
  1574.                 JP NZ,FNDMP30
  1575.                 LD DE,(CurrentDIRCluster)
  1576.                 LD BC,(CurrentDIRCluster+2)
  1577.                 CALL INIRTSC
  1578.                 LD BC,0
  1579.                 CALL RDDIRSC
  1580.                 LD DE,0x20
  1581.                 PUSH HL
  1582.                 POP IX
  1583.                 LD A,(HL)
  1584.                 CP "."
  1585.                 JR NZ,.ROOT
  1586.                 LD A,(IX+1)
  1587.                 CP "."
  1588.                 JR Z,.NEXTFILE
  1589.                 INC BC
  1590.                 ADD IX,DE
  1591. .NEXTFILE       INC BC
  1592.                 ADD IX,DE
  1593. .ROOT           LD A,IXH
  1594.                 CP HIGH (BUF_512) + 2
  1595.                 JR NZ,.FNDMP32
  1596.                 CALL RDDIRSC
  1597.                 JP NZ,.FNDMP37
  1598.                 LD DE,0x20
  1599.                 PUSH HL
  1600.                 POP IX
  1601. .FNDMP32        LD A,(IX+0)
  1602.                 AND A
  1603.                 JP Z,.FNDMP37                   ; конец DIR?
  1604.                 CP 0xE5
  1605.                 JR Z,.NEXTFILE                  ; файл удален?
  1606.                 LD A,(IX + _DIR_Attr)
  1607.                 CP M_DIR_AttrLongName
  1608.                 JR Z,.NEXTFILE                  ; это длинное имя?
  1609.                 CP M_DIR_VolumeID
  1610.                 JR Z,.NEXTFILE                  ; это имя раздела?
  1611.                 BIT 4,(IX + _DIR_Attr)
  1612.                 JR NZ,.NEXTFILE                 ; это директория?
  1613.                 EXX
  1614.                 PUSH IX
  1615.                 POP HL
  1616.                 CALL CP_EXT                     ; проверяем расширение файла
  1617.                 EXX
  1618.                 AND A
  1619.                 JP Z,.NEXTFILE                  ; не совпало, продолжаем
  1620.                 LD DE,(TEKNUMC)
  1621.                 LD HL,(PAGEMP3)
  1622. ; укладка описателя файла
  1623. ; 2 байта адрес кластера диры
  1624. ; 2 байта "реальный" номер файла
  1625.                 LD (HL),E
  1626.                 INC HL
  1627.                 LD (HL),D
  1628.                 INC HL
  1629.                 LD (HL),C
  1630.                 INC HL
  1631.                 LD (HL),B
  1632.                 INC HL
  1633.                 LD (PAGEMP3),HL
  1634.                 LD A,H
  1635.                 AND A
  1636.                 JP Z,FNDMP30                    ; память кончилась, выходим
  1637.                 LD DE,0x20
  1638.                 JR .NEXTFILE
  1639.