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

Ваш аккаунт

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

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

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

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



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

Модуль 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

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

Оставлять комментарии могут только зарегистрированные пользователи.

Если вы не являетесь зарегистрированным пользователем, то вам необходимо зарегистрироваться. Регистрация бесплатна. Если вы уже зарегистрированы на CodeNet, то вам необходимо ввести логин и пароль в верхней (Alt-U) части страницы.

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