;----------------------------------------------------------------------; ; [x] теперь не лезет напрямую, делает через новый параметр функции DskInfo ; иная логика получения метки тома - сначала ищется в корневой директории, ; если там нет, то берётся из BPB ; Вход: выставить переменную read_disk_info.full: ; 0 - не считать свободное место, !0 - считать ; Выход: ; %7 - Volume label ; serial_string - Volume serial number string ; full_space_high \ ; full_space_medium - Partition size ; full_space_low / ; %6 - "has no label" or "has label" ; read_disk_info: OR #80 LD HL,Buffers.work.buffer .full+1: LD B,0 LD C,Dss.DskInfo RST ToDSS RET C ; Файловая система ; Серийный номер диска ; Метка диска в BPB ; Физический номер диска, номер раздела ; ; HL':HL - общее кол-во кластеров ; DE':DE - свободных кластеров ; A - размер кластера в секторах ; BC - размер сектора в байтах ; max sector (LBA28) #0FFF'FFFF ; EX AF,AF' LD A,D AND E EXX AND D AND E EXX INC A LD (.LastDskInfoIsFull),A ; AND H EX AF,AF' ; ; --> (HL':HL)*BC*A, (DE':DE)*BC*A = B':HL'HL, C':DE':DE EXX LD BC,0 EXX SRL B RR C RRCA JR C,.loop2 ; .loop1: SLA L RL H EXX RL L RL H RL B EXX ; SLA E RL D EXX RL E RL D RL C EXX ; RRCA JR NC,.loop1 ; .loop2: SLA L RL H EXX RL L RL H RL B EXX ; SLA E RL D EXX RL E RL D RL C EXX ; SRL B RR C JR NC,.loop2 ; <-- B':HL'HL, C':DE':DE EXX LD A,C LD (free_space_high),A LD (free_space_medium),DE ; LD A,B LD (full_space_high),A LD (full_space_medium),HL EXX LD (free_space_low),DE LD (full_space_low),HL ; .no_full_space_option: ; parse ; copy FS type LD HL,Buffers.work.buffer LD DE,Buffers.bat_params.PRM8; куда LD B,0 LD C,(HL) ; тут в HL длина поля "Файловая система" INC HL LDIR EX DE,HL LD (HL),0 EX DE,HL ; LD D,0 ; ; тут в HL длина поля "Файловая система" ; LD E,(HL) ; ADD HL,DE ; INC HL ; длина поля "Серийный номер диска" LD A,(HL) LD E,A ADD HL,DE INC HL PUSH HL ; указатель на длину поля "Метка диска" CP 4 ;!HARDCODE длина поля серийного номера JR NZ,.unknown_serial DEC HL ; старшее слово серийника LD D,(HL) DEC HL LD E,(HL) DEC HL PUSH HL EX DE,HL LD DE,serial_string ; xxxx-xxxx CALL hex16_to_str POP HL ; LD A,"-" LD (DE),A INC DE ; младшее слово серийника LD A,(HL) DEC HL LD L,(HL) LD H,A CALL hex16_to_str ; .get_label: ; тут в HL длина поля "Метка диска" POP HL LD A,(HL) INC HL AND A JR Z,.no_volume_label ; да PUSH HL LD B,A LD A,' ' ; .loop: CP (HL) JR NZ,.good_label INC HL DJNZ .loop POP HL ; снимаем лишнее ; нет метки .no_volume_label:; %6 LD HL,volume_string_no ; строка LD DE,Buffers.bat_params.PRM6; куда CALL ncopy_string ; скопир. строку (с нулем) XOR A LD (Buffers.bat_params.PRM7),A RET ; .good_label: POP HL PUSH HL ; толкаем лишнее ; есть метка .volume_label: POP DE ; снимаем лишнее ; %7 LD DE,Buffers.bat_params.PRM7 LD BC,11 ;!HARDCODE длина метки LDIR XOR A LD (DE),A ; %6 LD HL,volume_string_yes ; строка LD DE,Buffers.bat_params.PRM6; куда XOR A JP ncopy_string ; скопир. строку (с нулем) ; ; если не удалось прочитать серийный номер диска или формат неизвестен .unknown_serial: ; серийный номер диска - неизвестен ;!HARDCODE ниже LD HL,serial_string LD A,'?' LD B,serial_string.Size .loop3: LD (HL),A INC HL DJNZ .loop3 LD HL,serial_string+4 LD (HL),'-' JR .get_label ; .LastDskInfoIsFull: DB 0 ; /////////////////////////////////////////////////////////////////////// free_space_low: WORD 0 free_space_medium: WORD 0 free_space_high: BYTE 0 ; Серийный номер диска serial_string: db "xxxx-xxxx" .Size equ $-serial_string db 0 ; закрывашка ; volume_string_no: db "has no label",0 ; volume_string_yes: db "has label",0 ; ; has_not_full_info: db ' (?)',0 /////////////////////////////////////////////////////////////////////// ;----------------------------------------------------------------------; ;Процедура коррекции буквы к маленькой букве CorrBigChar: CP 'A' RET C CP 'Z' + 1 JR NC,.CheckRUS .Dec: ADD #20 RET ; .CheckRUS: CP 'А' RET C CP 'П'+1 JR C,.Dec ; .BGUPPER: CP 'Я' + 1 JR NC,.HGUPPER ADD #50 RET ; .HGUPPER: CP 'Ё' ; русская буква ё, код #F1 RET NZ INC A RET