Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11642
Последний выпуск: 19.06.2015

Модуль disk.asm

; Чтение сектора (DX=номер сектора) ##########################################
; ES:DI - куда читать
PROC            ReadSect
                push di es
                 ; Начало расчета сектора/дорожки/головки
                 push    cs
                 pop     ds
                 mov     cx,18
                 mov     si,dx
                 ; tmp=(Sect/Sectors);
                 mov     ax,si
                 xor     dx,dx
                 div     cx
                 mov     di,ax
                 ; Sec=Sect-(tmp*Sectors)+1;
                 mov     ax,di
                 imul    cx
                 mov     dx,si
                 sub     dx,ax
                 inc     dx
                 mov     [AbsSectNum],dx
                 ; Hea=tmp & 1;
                 mov     ax,di
                 and     ax,1
                 mov     [AbsHeadNum],ax
                 ; Trk=(Sect-(Hea*Sectors)-(Sec-1))/(Sectors*2);
                 imul    cx
                 push    ax
                 mov     ax,si
                 pop     dx
                 sub     ax,dx
                 mov     dx,[AbsSectNum]
                 dec     dx
                 sub     ax,dx
                 mov     dx,cx
                 shl     dx,1
                 push    ax
                 push    dx
                 xor     dx,dx
                 pop     bx
                 pop     ax
                 div     bx           ; AX = AbsTrackNum
                 ; Конец расчетов
                 mov     cx,ax
                 mov     al,cl
                 shr     cx,2
                 and     cl,0C0h
                 mov     ch,al
                 and     cx,0FFC0h
                 mov     ax,[AbsSectNum]  ;      г5T4T3T2T1T0T9T8T7T6T5T4T3T2T1T0¬
                 or      cl,al            ; CX =  c c c c c c c c C c S s s s s s
                pop     es bx             ; ES:BX = Куда считывать
                mov     dx,[AbsHeadNum]
                mov     dh,dl             ; Номер головки
                mov     dl,0              ; Номер диска 0 = A
                mov     al,1              ; Количество считываемых секторов
                mov     ah,2              ; Номер функции
                int     13h
                ret
ENDP            ReadSect
; Чтение сектора в стандартный буффер ########################################
RSSData         DW      0
PROC            CachedReadSector
                cmp     dx,[cs:RSSData]
                je      RSSEnd
                mov     [cs:RSSData],dx
                push    di si es ax bx cx dx
                lea     di,[sector]
                push    cs
                pop     es
                call    ReadSect
                pop     dx cx bx ax es si di
RSSEnd:         ret
ENDP            CachedReadSector
; Чтение FAT'а ###############################################################
PROC            ReadFAT
                push    cs
                pop     es
                mov     dx,1
                lea     di,[FAT]
readfat1:       push    es dx di

                Call    ReadSect
                pop     di dx es
                add     di,512
                inc     dx
                cmp     dx,10
                jne     readfat1
                ret
ENDP            ReadFAT
; Выдает следующий сектор после DX (через FAT) ###############################
gns_flag        DW      0
PROC            GetNextSector
                cmp     dx,2
                je      gns03
                cmp     [Word Ptr cs:gns_flag],0
                jne     gns04
                push    cx di bx
                lea     di,[FAT]
                mov     ax,dx
                mov     bx,ax
                mov     cx,3
                mul     cx
                shr     ax,1
                add     di,ax
                mov     dx,[di]
                and     bx,1
                je      gns01     ; Если номер кластера четный
                shr     dx,4
                jmp     gns02
gns01:          and     dx,0FFFh
gns02:          pop     bx di cx
                ret
gns03:          mov     dx,[RootSect]
                ret
gns04:          mov     [Word Ptr cs:gns_flag],0
                add     dx,33-2
                ret
ENDP            GetNextSector
; Конвертит номер сектора в номер кластера ###################################
Sect2ClustRoot  DW      0
PROC            Sect2Clust
                cmp     dx,33
                jb      Sect2Clust1
                sub     dx,33-2
                mov     [Word Ptr cs:Sect2ClustRoot],0
                ret
Sect2Clust1:    mov     [Word Ptr cs:Sect2ClustRoot],1
                ret
ENDP            Sect2Clust
; По строке (обычно командной) выдает номер сектора (DS:DI = строка ) ########
; Возвращает AX = номер превого сектора каталога
GetSectorName   DB      13 DUP (0),0
GetSectorClust  DW      0
Prohod          DW      0
PROC            GetSectorNum
                call    UpperString           ; [DI] = D:\CAT1\CAT2\
                mov     al,[di]               ; AL = Диск 'A'-'Z'
                sub     al,'A'                ; AL = Диск 0 - 32
                xor     ax,ax
                mov     [Word Ptr cs:GetSectorClust],2
                mov     [Word Ptr cs:gns_flag],1
                mov     [cs:Prohod],ax
                add     di,3                  ; [DI] = CAT1\CAT2\

nextsubdir:     mov     si,di
gsn003:         mov     al,[si]
                or      al,al
                je      gsn001
                cmp     al,'\'
                je      gsn001
                inc     si
                jmp     gsn003
gsn001:         cmp     di,si                 ; [DI] = CAT1\CAT2
                je      gsn002                ; [SI] = \CAT2
                xor     cx,cx
                mov     bx,si
                push    si
                lea     si,[GetSectorName]
gsn005:         mov     al,[di]
                cmp     al,'.'                ; Если есть расширение
                je      gsn004
                mov     [cs:si],al
                inc     di
                inc     si
                inc     cx
                cmp     di,bx
                jne     gsn005
                pop     di
                ; Добьем имя нулями
gsn006:         mov     [Byte Ptr cs:si],20h
                inc     cx
                inc     si
                cmp     cx,11
                jne     gsn006
                jmp     gsn007
gsn002:         mov     ax,[cs:Prohod]
                or      ax,ax
                jne     gsn0021
                mov     ax,[Root]             ; Корень
                jmp     gsn0022
gsn0021:        mov     ax,[GetSectorClust]
gsn0022:        ret
gsn004:         cmp     cx,8
                je      gsn008
                mov     [Byte Ptr cs:si],20h
                inc     cx
                inc     si
                jmp     gsn004
gsn008:         inc     di
                inc     cx
                cmp     cx,12
                je      gsn010
                mov     al,[di]
                or      al,al
                je      gsn009
                mov     [cs:si],al
                inc     si
                jmp     gsn008
gsn009:         pop     di
                jmp     gsn006
gsn010:         pop     dx
gsn007:         push    di

                ; Ищем в корне запрошеный каталог (CAT1)
                mov     dx,[GetSectorClust]
                lea     di,[sector]
gsn13:          call    GetNextSector
                cmp     dx,0FFFh
                je      gsn14
                push    dx
                call    CachedReadSector
                mov     [Word Ptr cs:gns_flag],0
                lea     di,[sector]
                lea     si,[GetSectorName]
                mov     cx,16                ; 16 - количество записей в одном секторе
gsn12:          push    di si cx
                call    CmpStrings
                pop     cx si di
                jc      gsn11
notdir:         add     di,32
                dec     cx
                jne     gsn12
                pop     dx
                jmp     gsn13
gsn14:          pop     di                   ; Не найдено не фига
                xor     ax,ax
                ret
gsn11:          ; Найдена запись - сравним аттрибуты
                mov     al,[di+11]
                and     al,10h
                je      notdir               ; Это не каталог
                mov     ax,[di+01Ah]
                mov     [GetSectorClust],ax
                pop     dx di
                inc     di
                mov     [Word cs:Prohod],1
                mov     [Word Ptr cs:gns_flag],1
                jmp     nextsubdir
ENDP            GetSectorNum
; FindFirst ##################################################################
; Возвращает: AX=0=Ok; AX=1=Patch not found
PROC            FindFirst
                ; Читаем FAT
                push    cs
                pop     ds
                ; Узнаем номер сектора, где начинается корень
                lea     di,[dos_CurDir]
                call    GetSectorNum         ; В AX - номер кластера с каталогом
                or      ax,ax
                je      ff03
                mov     dx,ax
                mov     [Word Ptr cs:gns_flag],1
                push    cs
                pop     es
                call    GetNextSector
ff02:           push    dx
                call    CachedReadSector
                pop     dx
                ; Копируем первую запись в каталоге в структуру _dos
                lea     si,[sector]
                mov     cx,16
ff01:           mov     al,[si]
                or      al,al                ; 0 - пустая запись каталога
                je      nofile
                cmp     al,'х'               ; 'x' - удаленая запись
                je      nofile
                mov     ax,[si+11]
                cmp     ax,0Fh               ; Если это LFN
                je      nofile
                lea     di,[dos_FileName]
                mov     bx,cx
                mov     cx,32
                rep     movsb
                jmp     ff_makefind
nofile:         add     si,32
                dec     cx
                or      cx,cx
                jne     ff01
                cmp     dx,32
                jna     nofile1
                call    GetNextSector
                jmp     ff02
nofile1:        inc     dx
                jmp     ff02
ff_makefind:    ; Копируем содержимое структуры dos_ в структуру _find
                lea     si,[dos_FileName]
                lea     di,[find_FileName]
                mov     cx,32
                rep     movsb
                mov     ax,16
                sub     ax,bx
                mov     [di],dx
                mov     [di+2],ax
                xor     ax,ax
                ret
ff03:           mov     ax,1
                ret
ENDP            FindFirst
; Ищет следующий файл в каталоге #############################################
; Возвращает: AX=0=Ok; AX=1=Patch not found
PROC            FindNext
                lea     si,[find_FileName]
                mov     dx,[si+32]          ; DX - номер сектора
                mov     ax,[si+34]
fnNextSector0:  cmp     ax,15               ; Надо читать следующий
                je      fnNextSector1
                mov     [Word Ptr cs:gns_flag],1
fnNextSector:   push    cs
                pop     es
                push    ax
                call    Sect2Clust          ; DX - номер кластера
                cmp     [Word Ptr cs:Sect2ClustRoot],0
                jne     fnNextSector5       ; Если корень
                call    GetNextSector
                cmp     dx,0FFFh
                je      fnNextSector2
fnNextSector4:  push    dx
                call    CachedReadSector
                pop     dx ax               ; Нужный сектор считан
                inc     ax                  ; AX - номер записи (0..15)
                push    ax
                shl     ax,5                ; AX=AX*5
                lea     si,[sector]
                add     si,ax

                ; Проверим на пустую запись, удаление и LFN
                mov     bl,[si]
                or      bl,bl                ; 0 - пустая запись каталога
                je      fn_nofile
                cmp     bl,'х'               ; 'x' - удаленая запись
                je      fn_nofile
                mov     bx,[si+11]
                cmp     bx,0Fh               ; Если это LFN
                je      fn_nofile

                lea     di,[dos_FileName]
                mov     cx,32
                rep     movsb
                pop     ax
                lea     si,[dos_FileName]
                lea     di,[find_FileName]
                mov     cx,32
                rep     movsb
                mov     [di],dx
                mov     [di+2],ax
                xor     ax,ax
                ret
fn_nofile:      pop     ax
                jmp     fnNextSector0
fnNextSector2:  pop     ax
                mov     ax,1
                ret
fnNextSector1:  xor     ax,ax
                dec     ax
                jmp     fnNextSector
fnNextSector5:  cmp     [Word Ptr cs:gns_flag],1
                je      fnNextSector51
                inc     dx
                cmp     dx,33
                je      fnNextSector2
fnNextSector51: mov     [Word Ptr cs:gns_flag],0
                jmp     fnNextSector4
ENDP            FindNext

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог