;///////////////////////////////////////////////////
;
; DIR. Вывод списка файлов и папок
;
;///////////////////////////////////////////////////
cmd_dir:
push de
ld c,Dss.CurDisk ; узнать тек. диск
RST ToDSS
ADD A,"A"
ld (root_path),a ; номер диска
SUB "A"
call read_disk_info ; прочитать метку и серийный номер диска
pop de
ld hl,0
ld (D88DC),hl
ld (D88DE),hl
ld (D88E0),hl
ex de,hl
ld a,(hl)
or a
jr nz,1F ; задана маска имен
ld hl,mask_fname ; "*.*"
;ld de,T9186 ; буфер
1: ld de,work_buffer1 ; 80
ld c,Dss.GSwitch ; выделить параметр ком-строки
RST ToDSS
; [ ] 1/10/23
;
;ld hl,T9186 ; имя файла
;ld de,T9186 ; буфер
ld hl,work_buffer1 ; имя файла
ld de,work_buffer1 ; 80 буфер
ld a,#37 ; атрибут (все, кроме метки тома)
ld bc,0*256 + Dss.F_First ; f_first (формат 11)
RST ToDSS
;R14
;jp c,print_err_message ; вывод сообщения DSS_Error.sys.FILE_NOT_FOUND
JR NC,.not_empty
CP DSS_Error.sys.FILE_NOT_FOUND
JP NZ,print_err_message
SCF
JP .Print_Header
.not_empty:
CALL .Print_Header
;
; цикл вывода списка файлов/папок
.loop: ;ld hl,T9186 ; раб. буфер
ld hl,work_buffer1 ; 80
ld de,33
add hl,de
call A88E2
;ld ix,T9186
ld ix,work_buffer1 ; 80
ld a,(ix+32) ; атрибут тек. записи
and FAT_ATTR.DIRECTORY ; папка ?
jr z,.calc_size ; нет
; увеличиваем счётчик папок
ld hl,(dir_number)
inc hl
ld (dir_number),hl
jr .next
; прибавить размер тек. файла
.calc_size:
ld hl,(D88DC)
inc hl
ld (D88DC),hl
ld e,(ix+30)
ld d,(ix+31)
ld hl,(D88E0)
exx
ld e,(ix+28)
ld d,(ix+29)
ld hl,(D88DE)
add hl,de
exx
adc hl,de
exx
ld (D88DE),hl
exx
ld (D88E0),hl
.next: ld de,work_buffer1 ; 80 буфер
ld c,Dss.F_Next ; поиск след.
RST ToDSS
jr nc,.loop ; назад в цикл, если не конец списка
; Десятичный вывод
.print: ld hl,(D88DC)
ld ix,PRM1 ; буфер
call A8964
ld hl,(D88DE) ; мл. разряд
exx
ld hl,(D88E0) ; ст. разряд
exx
call A8A8F ; десятичный 32-х разрядный вывод
ld hl,T8B37 ; "0"
ld a,(hl)
cp " "
jr nz,.not_zero
ld a,"0"
ld (hl),a
.not_zero:
ld de,T8B46 ; "0 000 000 000"
ld hl,T8B2E ; "0000000000"
ld a,(hl)
ldi
cp " "
jr z,$+4
ld a,"," ; разд. разрядов
ld (de),a
inc de
ldi
ldi
ld a,(hl)
ldi
cp " "
jr z,$+4
ld a,"," ; разд. разрядов
ld (de),a
inc de
ldi
ldi
ld a,(hl)
ldi
cp " "
jr z,$+4
ld a,"," ; разд. разрядов
ld (de),a
inc de
ldi
ldi
ldi
недоделано
ld hl,T8B46 ; "0 000 000 000"
ld de,PRM2 ; куда
call ncopy_string ; скопир. строку (с нулем), макс.15 симв.
ld de,9 ; индекс " %1 file(s) %2 bytes"
jp MESSAGE ; вывести строку
;R14
.Print_Header:
PUSH AF
;
; %1
ld a,(screen_path) ; диск
ld hl,PRM1
ld (hl),a
inc hl
ld (hl),":"
inc hl
ld (hl),0
; %2
ld hl,serial_string ; строка серийного номера диска
ld de,PRM2 ; куда
call ncopy_string ; скопир. строку (с нулем)
;
;R14
POP AF
ld hl,screen_path
JR NC,.not_empty_2
;
ld a,(screen_path)
LD (.str),A
ld hl,.str ; экран. путь
; %3
.not_empty_2:
;
ld de,PRM3 ; 16 буфер
CALL copy_string ; скопир. строку (с нулем)
;
ld de,0 ; индекс "Volume in drive %1 has no label..." ;!HARDCODE номер строки MSG0
JP MESSAGE ; вывести строку
.str: DZ 'X:\ is empty' ;R14 ;!FIXIT
;
; Подготовить строку списка файлов/папок
A88E2: ld bc,8
ld de,PRM1 ; буфер
ldir
xor a
ld (de),a
ld de,PRM2 ; куда
ldi
ldi
ldi
ld (de),a
;ld ix,T9186
ld ix,work_buffer1
call A89A4 ; вывести в буфер имя файла и его размер (у папки
)
call A89FA ; вывести в буфер дату файла/папки
call A8A19 ; вывести в буфер время файла/папки
ld de,10 ; индекс "%1 %2 %3 %4 %5"
jp MESSAGE ; вывод строки
; Вывести в буфер имя файла и его размер (у папки )
A89A4: ld a,(ix+32)
ld hl,T8B38 ; " "
and 10h ; папка ?
jr nz,A89F4 ; да
ld l,(ix+28) ; мл. разряд
ld h,(ix+29)
exx
ld l,(ix+30) ; ст. разряд
ld h,(ix+31)
exx
push ix
call A8A8F ; десятичный 32-х разрядный вывод
ld hl,T8B37
ld a,(hl)
cp " "
jr nz,A89CD
ld a,"0"
ld (hl),a
A89CD: ld de,T8B46 ; "0 000 000 000"
ld hl,T8B2E ; "0000000000"
ldi
ld a," "
ld (de),a
inc de
ldi
ldi
ldi
ld (de),a
inc de
ldi
ldi
ldi
ld (de),a
inc de
ldi
ldi
ldi
ld hl,T8B46 ; "0 000 000 000"
pop ix
A89F4: ld de,PRM3 ; 16 буфер
jp ncopy_string ; скопир. строку (с нулем), макс.15 симв.
; Скопировать в буфер дату файла/папки
A89FA: ld b,(ix+25)
ld c,(ix+24)
ld hl,T8B46 ; "0 000 000 000"
call A8A53 ; вывод в буфер даты
ld (hl),0
ld hl,T8B46 ; "0 000 000 000"
ld de,PRM4 ; 16 куда
ld a,(hl)
cp "0"
jr nz,$+4
ld (hl)," "
jp ncopy_string ; скопир. строку (с нулем), макс.15 симв.
; Скопировать в буфер время файла/папки
A8A19: ld b,(ix+22)
ld c,(ix+23)
ld hl,T8B46 ; "0 000 000 000"
call A8A38 ; скопир. в буфер время файла/папки
ld (hl),0
ld hl,T8B46 ; "0 000 000 000"
ld de,PRM5 ; 80 буфер строки
ld a,(hl)
cp "0"
jr nz,$+4
ld (hl)," "
jp ncopy_string ; скопир. строку (с нулем), макс.15 симв.
; в буфер время файла/папки
A8A38: srl c
rr b
srl c
rr b
srl c
rr b
srl b
srl b
ld a,c
call A8A7E
ld (hl),":" ; раздел. времени
inc hl
ld a,b
jr A8A7E
; в буфер дату файла/папки
A8A53: ld a,c
and 1Fh
push bc
call A8A7E
ld (hl),"." ; раздел. даты
inc hl
pop bc
ld a,c
srl b
rla
rla
rla
rla
and 0Fh
call A8A7E
ld (hl),"." ; раздел. даты
inc hl
ld a,b
add a,80
cp 100
jr c,A8A7E
A8A75: sub 100
cp 100
jr nc,A8A75
A8A7E: ld c,2Fh
inc c
sub 10
jr nc,$-3
add a,10
add a,"0"
ld (hl),c
inc hl
ld (hl),a
inc hl
ret
; Десятичный 32-х разрядный вывод
A8A8F: ld ix,T8B2E ; "0000000000"
exx
ld de,3B9Ah
exx
ld de,0CA00h
call A8B15 ; 1,000,000,000
exx
ld de,05F5h
exx
ld de,0E100h
call A8B15 ; 100,000,000...999,999,999
exx
ld de,98h
exx
ld de,9680h
call A8B15 ; 10,000,000...99,999,999
exx
ld de,0Fh
exx
ld de,4240h
call A8B15 ; 1,000,000...9,999,999
exx
ld de,1
exx
ld de,86A0h
call A8B15 ; 100,000...999,999
exx
ld de,0
exx
ld de,10000
call A8B15 ; 10,000...99,999
exx
ld de,0
exx
ld de,1000
call A8B15 ; 1,000...9,999
exx
ld de,0
exx
ld de,100
call A8B15 ; 100..999
exx
ld de,0
exx
ld de,10
call A8B15 ; 10..99
ld a,l
add a,"0"
ld (ix+0),a
inc ix
ld hl,T8B2E ; "0000000000"
ld de,2030h ; " ","0"
A8B04: ld a,(hl)
cp e
jr nz,A8B0D
ld (hl),d
inc hl
jr A8B04
;
A8B0D: ld hl,T8B37 ; "0"
ld a,(hl)
cp d
ret nz
ld (hl),e
ret
A8B15: xor a
A8B16: inc a
sbc hl,de
exx
sbc hl,de
exx
jp nc,A8B16
add hl,de
exx
adc hl,de
exx
dec a
add a,"0"
ld (ix+0),a
inc ix
ret
;
D88DC: dw 0
D88DE: dw 0
D88E0: dw 0
;
T8B2E: db "000000000"
T8B37: db "0"
T8B38: db " ",0
T8B46: db "0 000 000 000",0
db 0
;
;!FIXIT перенести в DSS - FN #04: GET_BPB
; прочитать BPB диска
read_disk_info:
OR #80
LD HL,work_buffer
LD BC,Dss.DskInfo
RST ToDSS
; Файловая система
; Серийный номер диска
; Метка диска в BPB
; parse
LD D,0
LD HL,work_buffer
; тут в 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
POP HL
;
ld a,"-"
ld (de),a
INC DE
; младшее слово серийника
LD A,(HL)
DEC HL
LD L,(HL)
LD H,A
call hex16
;
; Метка диска
; ld a,(disk) ; номер диска
; cp 2 ; меньше "C:" ?
; jr nc,get_inf_data1 ; метка в BPB
.get_label:
; ищем метку в корне ФС раздела
; уст. корень диска
ld hl,root_path ; "x:\",0
ld c,Dss.ChDir
RST ToDSS
; поиск метки
ld hl,mask_fname ; "*.*" имя метки
ld de,work_buffer1 ; куда
ld a,FAT_ATTR.VOLUME_ID ; атрибут метки тома
ld bc,0*256 + Dss.F_First ; f_first, формат 11
RST ToDSS
push af
call restore_path ; восст. тек. путь
pop af
;jr c,no_volume_label ; метки нет дирректории
ld hl,work_buffer1+33 ; начало метки в буфере f_first
jr nc,volume_label ; метка в корневом каталоге
; берём метку из BPB
; тут в 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:
; %4
ld hl,volume_string_no ; строка
ld de,PRM4 ; куда
call ncopy_string ; скопир. строку (с нулем)
XOR A
LD (PRM5),A
ret
.good_label:
POP HL
PUSH HL ; лишнее
;!FIXIT сделать через аргументы %1-%9
; есть метка
volume_label:
pop DE ; лишнее
; %5
ld de,PRM5
ld bc,11 ;!HARDCODE длина метки
ldir
xor a
ld (de),a
; %4
ld hl,volume_string_yes ; строка
ld de,PRM4 ; куда
call ncopy_string ; скопир. строку (с нулем)
ret
;
; если не удалось прочитать серийный номер диска или формат неизвестен
unknown_serial:
; серийный номер диска - неизвестен ;!HARDCODE ниже
LD HL,serial_string
LD A,'?'
LD B,serial_string.Size
.loop: LD (HL),A
INC HL
DJNZ .loop
LD HL,serial_string+4
LD (HL),'-'
;POP HL ; лишнее
JP read_disk_info.get_label
;
; Вывод HL в hex-формате
; de=буфер
; hl=число
hex16: ld a,h
call hex8
ld a,l
; вывод "a"
hex8: push af
rrca
rrca
rrca
rrca
call .num
pop af
;
.num: and %0000'1111
add a,#90
daa
adc a,#40
daa
ld (de),a
inc de
ret
; маска файлов
mask_fname:
db "*.*",0
; корень диска
root_path:
db 'X:\',0
; Серийный номер диска
serial_string:
db "xxxx-xxxx"
.Size equ $-serial_string
db 0 ; закрывашка
volume_string_no: ;!FIXIT сделать через PRM
db "has no label",0
volume_string_yes:
db "has label",0