; Сканирование папки ; ; Для врем. буфера выделяется 1 страница памяти. После отработки процедуры, ; страница освобождается. ; Макс. глубина вложенности папок равна 20-ти (можно поставить другое). ; Для массива элементов используется целая банка, вмещающая 1024 ; (16*1024=4000h) элементов. Общее число папок, отслеживаемое процедурой, ; органичивается размером этого массива. ; ; Перед вызовом процедуры, необходимо установить диск и путь. ; max_depth equ 20+1 ; макс. число вложенности папок ;----------------------------------------------------------- ; Сканирование папки ; выход: NC - нормальное завершение ; C - операция прервана пользователем (A=0FFh) ;----------------------------------------------------------- ScanTree: ld (tree_stack),sp ld bc,3135h ; очистить буфер сист. клавы rst 10h ld sp,work_buffer+512 ; стек процедуры in a,(SLOT3) ld (tree_page),a ; сохр. порт ; выделить 1 стр. под врем. буфер ld bc,01C2h rst 08h ld (tmppage+1),a ; сохр. дескр. стр. jr nc,$+9 ; без ошибок xor a ld (tmppage+1),a ld a,(page_dial_screen) ; исп. для врем. буфера out (SLOT3),a xor a ld l,a ld h,a ld (depth_tree),a ; сбр. номер уровня вложений ld (count_dirs),hl ; сбр. число папок ld (count_files),hl ; сбр. число файлов ld (size_files),hl ; сбр. размер файлов ld (size_files+2),hl push hl ; тек. элемент (корень) в стек ld (cur_tree_adr+1),hl ; инит. ячейку ld hl,LC000+16 ; начало буфера элементов вложений ld (end_tree),hl ; начало след. 16-ти байтного элемента ld b,16 ; размер элемента вложений ld (hl),a ; a=0 inc hl djnz $-2 call scan_cur_level ; сканир. одного уровня + стопка элем. jr nc,tree_exit ; нет папок ; войти в папку след. уровня tree_loop: push hl ; адрес старого элемента (после LoadDIR) ld c,31h ; опрос сист. клавы rst 10h call nz,abort_tree_scan ; вывести окно "прерыв. операции" pop hl ld a,(depth_tree) ; номер тек. уровня вложений inc a cp max_depth+1 ; 20+1 макс. число вложений папок jr c,tree_depth_ok tree_depth_err: ld a,EDEPTH ; 36 код "слишком большая вложенность папок" jr tree_abort1 ; tree_depth_ok: ld (depth_tree),a ld de,(count_dirs) ; тек. число папок bit 2,d ; >= 1024 папок (> 1 банки элементов) jr nz,tree_depth_err ; ошибка, выйти push hl ; тек. имя папки в стек ld a,(hl) or a jr z,dirs_end ; нет вложений, вернуться в нач. уровень ld (cur_tree_adr+1),hl ; имя папки тек. уровня ld c,1Dh ; уст. путь на папку тек. уровня rst 10h call scan_cur_level ; сканир. одного уровня + стопка элем. jr c,tree_loop ; есть папки ; вернуться на пред. уровень dirs_end: ld c,31h ; опрос сист. клавы rst 10h call nz,abort_tree_scan ; вывести окно "прерыв. операции" pop hl ; тек. элемент из стека ld a,h or l jr z,tree_exit ; в стартовой папке push hl ; hl=адрес имени папки ld a,(scan_mode) ; режим работы процедуры cp 2 ; уст. атрибутов папки jr nz,dirs_end1 ;call attrib_folder; ds 3; jr dirs_end2 dirs_end1: cp 3 ; удаление папки jr c,dirs_end2 call delete_folder; ; a=3,4 удаление/перенос папки jr dirs_end3 dirs_end2: ld hl,parent_level ; ".." ld c,1Dh ; уст. путь rst 10h dirs_end3: ld hl,depth_tree ; номер тек. уровня вложений dec (hl) pop hl ld de,16-1 ; размер элемента вложений - 1 add hl,de ld a,(hl) inc hl inc a jr nz,tree_loop jr dirs_end ; назад в цикл ; tree_abort: ld a,EUABORT ; 37 код "операция прервана пользователем" tree_abort1: scf jr $+3 tree_exit: xor a ; a=Ok и сбр. CF push af tmppage:ld a,0 ; дескр. стр. or a ld bc,01C3h ; освоб. 1 стр. памяти call nz,0008h db 3Eh ; ld a,.. tree_page: db 0 out (SLOT3),a ; восст. порт pop af ; возвр. код процедуры db 31h ; ld sp,.. tree_stack: dw 0 ; сохр. стек ret ;------------------------------------------------- ; Сканировать один уровень ; выход: C - есть папки ; NC - нет папок ; hl=адрес старого элемента ;------------------------------------------------- scan_cur_level: ld de,(end_tree) push de ; сохр. адрес старого элемента ld ix,0 ; счетчик папок ld hl,scan_mask ; имя файла (шаблон поиска) ld de,work_buffer ; раб. буфер push ix push de ld a,37h ; все, кроме метки тома ld bc,0119h ; f_first 8.3 rst 10h pop hl pop ix jr c,scan_level_exit ; не найдено scan_level_loop: call tree_record ; для папок созд. стопку элементов jr c,scan_level_exit ; ошибка, выход за границу банки push ix ld de,work_buffer ; раб. буфер push de ld c,1Ah ; f_next rst 10h pop hl pop ix jr nc,scan_level_loop ; назад в цикл scan_level_exit: ld hl,(end_tree) ; начало след. элемента dec hl ld (hl),-1 ; +xF в конец пред. db 0DDh ld c,l ; ld bc,ix db 0DDh ld b,h ld hl,(count_dirs) ; тек. число папок add hl,bc ; + число папок просканир. уровня ld (count_dirs),hl pop hl ; восст. адрес старого элемента ld a,c or b ret z ; нет папок ; сохр. в первом элементе в +0D..0E адрес посл. элемента cur_tree_adr: ld de,0 ; адрес тек. имени папки ld a,e or d jr z,scan_level_exit1 ex de,hl ld bc,0Dh ; смещ. ячейки адреса посл. элемента add hl,bc ld (hl),e ; сохр. адрес посл. элемента inc hl ld (hl),d ex de,hl scan_level_exit1: scf ; есть след. уровень ret ;------------------------------------------------- ; Обработка найденной записи. ; Для папок - создает стопку элементов. ; вход: hl=раб. буфер записи ; выход: при ошибке CF, выход за границу банки ;------------------------------------------------- ; элемент: +00..0C - имя папки (с нулем) ; +0D..0E - адрес посл. элемента (в записи первого элемента) ;------------------------------------------------- tree_record: ld a,(work_buffer+32) ; атрибут найд. записи bit 4,a ; папка ? jr nz,ins_tree_item ; да ; найден файл ld a,(scan_mode) ; режим работы процедуры or a ; a=0 сканир. папку jr z,tree_record_next dec a ; a=1 копир. папку ;jp z,copy_file dec a ; a=2 уст. атриб. файлов папки ;jp z,attrib_file dec a ; a=3 удаление папки jp z,delete_file dec a ; a=4 перенос папки ;jp z,move_file or a ; сбр. CF ret ; ++объем файлов tree_record_next: ld de,(work_buffer+28) ; мл. разряд ld hl,(size_files) add hl,de ld (size_files),hl ld de,(work_buffer+30) ; ст. разряд ld hl,(size_files+2) adc hl,de ld (size_files+2),hl ; ++число файлов ld hl,(count_files) inc hl ld (count_files),hl or a ; сбр. CF ret ; найдена папка ins_tree_item: ex de,hl ld hl,(end_tree) ; начало нового элемента ld bc,16 ; размер элемента add hl,bc sbc hl,bc ex de,hl ret c ; за пределом банки (> 0FFFFh) ld bc,33 add hl,bc ld a,(hl) ;+33 имя файла cp "." ; ".", ".." ret z inc ix ; ++число папок ld c,16 ; размер элемента вложений xor a ldi cp (hl) jr nz,$-3 ; скопир. в элемент имя папки ld b,c ; обнулить остаток элемента ld (de),a inc de djnz $-2 ld (end_tree),de ; начало след. 16-ти байтного элемента ld a,(scan_mode) ; режим работы процедуры cp 1 ; копир. папки ;jp z,create_folder cp 4 ; move папки ;jp z,create_folder; or a ; сбр. CF ret ;------------------------------------------------- ; Вывод окна прерывания операции ;------------------------------------------------- abort_tree_scan: ld bc,3135h ; очистить буфер сист. клавы rst 10h ld hl,dial_abort ; описатель окна call DialogEr cp evCommand ; событие "команда" ret nz ld a,(hl) ;+1 what cp cmOkey ; Yes jp z,tree_abort ; выйти из процедуры ret ; Режим работы процедуры: ; 0 - сканирование папки ; 1 - копирование папки ; 2 - уст. атрибутов файлов папки ; 3 - удаление папки ; 4 - перенос папки scan_mode: db 0 ; шаблон поиска (также исп. для поиска метки тома) scan_mask: db "*.*",0 ; верхний уровень parent_level: db "..",0 ; номер тек. уровня вложений depth_tree: db 0 ; начало след. 16-ти байтного элемента end_tree: dw 0 ; число папок count_dirs: dw 0 ; число файлов папки count_files: dw 0 ; общ. размер файлов папки size_files: dw 0 ; мл. разряд dw 0 ; ст. разряд