ФЭНДОМ


;****************************************************
;*                 ПОИСК HDD и CD                   *
;****************************************************
OS_BASE         equ 0
IDEBasesPorts   equ OS_BASE+6F00h
IDEMaxConroller equ    4
IDEMaxCanals    equ    8
;Таблица портов имеет следующий формат
;канал 0
;канал 1
;канал 2
;..
;канал 7
; * кажый канал это два порта 
;   Базовый адрес портов команд  
;   Базовый адрес порта контроля именно порта, а не блока.
 
; Всего 8 каналов 8*2*2=32Байта
IDEBusMaster equ IDEBasesPorts+20h 
; Всего 4 вхождения по 4 байта.
 
IDEBusIRQ equ IDEBasesPorts+ 30h
; Всего 4 байта.
IDEHDD_CD equ IDEBasesPorts+34h 
;4Байта 00b нет устройства 01b есть жесткий диск 10b есть Сидиром 11b рерв. 8  Каналов по два диска
IDELBA48 equ IDEBasesPorts+38h
;2 Байта 0 нет поддержки 1 есть поддержка и так 8 Каналов по два диска
 
FindHDD:
; Стандартные
        xor     eax, eax
        mov     ecx, 100h
        mov     edi, IDEBasesPorts
        rep     stosb
; Поиск контролеров и четение из них базовых портов
        call    FindBasesPorts
        mov     ecx, IDEMaxCanals-1
 
.Loop:
        mov     ah, cl 
        xor     al, al         ; al = 0
        call    TestDisks
        mov     ah, cl
        mov     al, 1          ; al = 1
        call    TestDisks
 
        dec     ecx
        cmp     ecx, dword -1
        jne     .Loop
        ret
;***********************
; Функция для проверки существования диска.
; ah - канал
; al - диск мастер 0 слейв 1
; 
buf    dw 256 dup 0
TestDisks:
        pushad
        and     al, 1
 
        movzx   esi, ah
        movzx   edi, al
 
 
        mov     dx, word [IDEBasesPorts+esi*4]  ; базовый порт команд
        test    dx, dx                          ; dx == 0 ?
        jz      .end                            ; прыгаем, если dx == 0
 
        shl     esi, 1
        add     esi, edi
        shl     esi, 1
 
        shl     al, 4
 
        add     dx, 6                           ;+6 Device         
        out     dx, al
 
        xor     al, al                          ; al = 0
        dec     dx                              ;+5
        out     dx, al
        dec     dx                              ;+4
        out     dx, al
        dec     dx                              ;+3
        out     dx, al
        dec     dx                              ;+2
        out     dx, al
 
        add     dx, 5		                ;+7 Command
        mov     al, 90h				; EXECUTE DEVICE DIAGNOSTIC
        out     dx, al
 
        mov     ecx, 0FFFFh
.loop:
        out     0EBh, al                        ; задержка
        in      al, dx                          ;+7 Status
        test    al, 80h                         ;BSY  
        jz     .ok1
        loop    .loop
 
.timeout:
        ; время вышло - устройства нет
        mov    eax, 3
 
        mov    ecx, esi
        shl    eax, cl   
 
        not    eax
        and    dword [IDEHDD_CD], eax
 
        sub    dx, 7                            ;+0
        jmp    .reset
 
.ok1:
        sub    dx, 6                            ;+1
        in     al, dx
        add    dx, 6                            ;+7
 
        cmp    edi, 1
        je     .label1
        cmp    al, 1
        je     .label2
        sub    dx, 7                            ;+0
        jmp    .other1
 
.label1:
        cmp    al, 1
        je     .label2
        cmp    al, 80h
        je     .label2
        sub    dx, 7                            ;+0
        jmp    .other1
 
.label2:
        dec    dx                               ;+6
        dec    dx                               ;+5
        in     al, dx
        mov    bl, al
        shl    ebx, 8
        dec    dx                               ;+4
        in     al, dx
        mov    bl, al
        shl    ebx, 8
        dec    dx                               ;+3
        in     al, dx
        mov    bl, al
        shl    ebx, 8
        dec    dx                               ;+2
        in     al, dx
        mov    bl, al
        sub    dx,2                             ;+0
 
        cmp    ebx, 000000101h                  ; жесткий диск
        jne    .cd
        mov    eax, 1
        mov    ecx, esi
        shl    eax, cl   
        or     dword [IDEHDD_CD], eax
        jmp    .indef
 
.cd:
        cmp    ebx, 0EB140101h                  ; сидиром
        jne    .other1
        mov    eax, 2
        mov    ecx, esi
        shl    eax, cl   
 
        or     dword [IDEHDD_CD], eax
        jmp    .reset
 
.other1: 
        mov    eax, 3
 
        mov    ecx, esi
        shl    eax, cl   
        not    eax
        and    dword [IDEHDD_CD], eax
 
.reset:
        add     dx, 6                    ;+6
        mov     eax, edi
        shl     al, 4
        out     dx, al
 
        mov     al, 0
        dec     dx                       ;+5
        out     dx, al                    
        dec     dx                       ;+4
        out     dx, al 
        dec     dx                       ;+3
        out     dx, al
        dec     dx                       ;+2
        out     dx, al
 
        add     dx, 5			 ;+7 Command
        mov     al, 08h			 ; Device RESET
        out     dx, al
 
        mov     ecx, 0FFFFh
 
.loop2:
        out    0EBh, al                  ; задержка
 
        in     al, dx                    ;+7 Status
        test   al, 80h                   ;BSY  
        jz    .ok2
        loop    .loop2
 
.timeout2:
        ; время вышло - устройства нет
        mov    eax, 2
 
        mov    ecx, esi
        shl    eax, cl   
        not    eax
        and    dword [IDEHDD_CD], eax
 
        sub    dx, 7                     ;+0
        jmp    .end
 
.ok2:
        sub    dx, 6                     ;+1
        in     al, dx
        add    dx, 6                     ;+7
 
        cmp    edi, 1
        je     .label3
        cmp    al, 1
        je     .label4
        sub    dx, 7                     ;+0
        jmp    .other2
 
.label3:
        cmp    al, 1
        je     .label4
        cmp    al, 80h
        je     .label4
        sub    dx, 7                     ;+0
        jmp    .other2
 
.label4:
        dec    dx                        ;+6
        dec    dx                        ;+5
        in     al, dx
        mov    bl, al
        shl    ebx, 8
        dec    dx                        ;+4
        in     al, dx
        mov    bl, al
        shl    ebx, 8
        dec    dx                        ;+3
        in     al, dx
        mov    bl, al
        shl    ebx, 8
        dec    dx                        ;+2
        in     al, dx
        mov    bl, al
        sub    dx, 2                     ;+0
 
.cd2:
        cmp    ebx, 0EB140101h       ; сидиром
        jne    .other2
        mov    eax, 2
        mov    ecx, esi
        shl    eax, cl   
        or     dword [IDEHDD_CD], eax
        jmp    .indef
 
.other2:
        mov    eax, 3
        mov    ecx, esi
        shl    eax, cl   
        not    eax
        and    dword [IDEHDD_CD], eax
 
.indef:
        add    dx, 6     ;+6 command
        mov    eax, edi
        shl    al, 4
        out    dx, al
        inc    dx        ;+7 command
 
        mov    eax, dword [IDEHDD_CD]
        mov    ecx, esi
        shr    eax, cl   
        and    al,  3
 
        cmp    al, 0
        je     .end
        cmp    al, 1
        jne    .cd3
        mov    al, 0ECh  ; IDENTIFY DEVICE
        out    dx,al
        jmp    .read
.cd3:
        cmp    al, 2
        jne    .end
        mov    al, 0A1h   ; IDENTIFY PACKET DEVICE
        out    dx,al
 
.read:
        mov    ecx, 0FFFFh
 
.loop3:
        dec    ecx
        jz     .timeout3  
        out    0EBh, AL        ; задержка
 
        in     al, dx          ;+7 Status
        test   al, 80h         ; состояние сигнала BSY
        jnz    .loop3
        test   al, 08h         ; состояние сигнала DRQ
        jz     .loop3
        jmp    .ok3
 
        .timeout3:
        mov    eax, 3
 
        mov    ecx, esi
        shl    eax, cl   
        not    eax
        and    dword [IDEHDD_CD], eax         
 
        sub    dx, 7           ;+0 
        jmp    .end
 
.ok3:
        xchg    edi, eax
        mov     edi, buf       ;offset buf
        sub     dx, 7          ;+0 регистр данных
        mov     cx, 256        ;число считываемых слов
        rep     insw           ;принять блок данных
        xchg    edi, eax
 
        mov     ecx, 255
        mov     ax, word [buf] 
 
.loop4:      ; проверяем на муссор вернулись одинаковые слова
        mov    bx, word [buf + ecx*2]
        cmp    ax,bx
        jne    .ok4
 
.equ:
        loop .loop4
 
.error: 
        mov    eax, 3
 
        mov    ecx, esi
        shl    eax, cl   
        not    eax
        and    dword [IDEHDD_CD],eax         
 
        sub    dx, 7      ;+0           
        jmp    .end
 
.ok4:
        ; Все проверки пройдены
        ; LBA48
        mov    ax, word[buf+86*2]
        shr    ax, 10
        and    ax, 1
        mov    ecx, esi
        shr    ecx, 1
        shl    eax, cl   
        or     [IDELBA48],ax
 
.end:
        popad
        ret
 
Addr_PCI  DD  0            ; Адресс PCI устройства
;**********************
;Функция читает один регистр из конфигурационного пространства устройства 
;по адресу Addr и заносит его в EAX.  
;**********************
ReadPCIRegistr: 
        mov    eax, [Addr_PCI]    ; 
        and    eax, 0FFFFFFFCh    ; Проверяем Addr в начале должен быть два 00
        or     eax, 80000000h     ; 31 бит обязан быть единицей.
        mov    dx, 0CF8h
        out    dx, EAX            ; Устанавливаем адрес
        mov    dx, 0CFCh
        in     eax, DX            ; Читаем регистр
        push   eax           
        xor    eax, eax           ; Сбрасываем адрес
        mov    dx, 0CF8h          ; Чтобы не было претензий.
        out    dx, eax            ;
        pop    eax
        ret
 
;*********************************
; Функция для поиска устройства по его классу
; EAX -его базовый класс.
; На выходи адрес если нет то -1
;***********************************
FindPCIDevice3: 
        push   ebx
        push   ecx
        push   edx
 
        mov    ebx, eax           ; Сохраняем
 
        mov    ecx, [Addr_PCI]    ; Счетчик он же адрес
        and    ecx, 0FFFFFFFCh    ; Проверяем Addr в начале должен быть два 00
        or     ecx, 80000000h     ; 31 бит обязан быть единицей.
 
.Label1:
        and    ecx, 0FFFFFF00h    ; Выравниваем
        mov    eax, ecx
        mov    dx, 0CF8h
        out    dx, eax            ; Устанавливаем адрес
        mov    dx, 0CFCh
        in     eax, dx            ; Читаем регистр
        cmp    eax, 0FFFFFFFFh    ; Не существующее устройство.
        je     .Label2
        add    ecx, 08            ; Наш Регистр
        mov    eax, ecx
        mov    dx, 0CF8h
        out    dx, eax            ; Устанавливаем адрес
        mov    dx, 0CFCh
        in     eax, dx            ; Читаем регистр
        shr    eax, 24            ; Base Class Code  
        cmp    eax, ebx
        je     .Label3            ; Ура: нашли!
 
.Label2:
        add    ecx, 256
                       ; Нужно бы добавить проверку на то, есть функции или нет.
        cmp    ecx, 80FFFF00h    ; Максимум 256 шин.             
        jne    .Label1
        mov    ecx, 0FFFFFFFFh   ; Не нашли 
 
.Label3:
        xor    eax, eax          ; Сбрасываем адрес
        mov    dx, 0CF8h         ; Чтобы не было претензий.
        out    dx, eax           ;
 
        and    ecx, 0FFFFFF00h   ; Сбрасываем индекс регистра
        mov    [Addr_PCI], ECX
        cmp    ecx, 0FFFFFF00h
        jne    .exit
        mov    ecx, 0FFFFFFFFh   ; Не нашли 
 
.exit:
        mov    eax, ecx
        pop    edx
        pop    ecx
        pop    ebx
        ret
 
;**********************************************
;*    ПОИСК КОНТРОЛЕРОВ и ЧЕТЕНИЕ ИХ ПОРТОВ
;*    IDEBasesPorts - базовые порты
FindBasesPorts:
        push   eax
        push   esi               ;
        push   edi               ; 
 
        xor    esi, esi
        xor    edi, edi
 
        mov    eax, 00           ;
        mov    [Addr_PCI], eax   ; B0:D0:F0
.Next:
        mov    eax, 01           ; Base Class Code =01 накопитель
        call   FindPCIDevice3
        cmp    eax, 0FFFFFFFFh
        je     .end
        add    [Addr_PCI], 8
        call   ReadPCIRegistr
        and    eax, 0FFFF0000h   ; Class Code 
        cmp    eax, 001010000h   ; IDE, SATA маскирующийся под IDE 
        je     .IDE 
        cmp    eax, 001040000h   ; RAID,SATA маскирующийся под RAID 
        jne    .NotIDE         
.IDE:
        add    [Addr_PCI], 8     ;  8+8=10h
        call   ReadPCIRegistr 
        and    eax, 0FFFCh       ; зануляем лишнее
        cmp    eax, 0
        jne    .native1
        mov    eax, 01F0h
.native1:
        mov    [IDEBasesPorts+esi], ax
 
        add    [Addr_PCI], 4     ;  8+8+4=14h
        call   ReadPCIRegistr 
        and    eax, 0FFFCh       ; зануляем лишнее
        cmp    eax, 0
        jne    .native2
        mov    eax, 03F4h
.native2:
        add    ax, 2             ; Порт контроля+2
        mov    [IDEBasesPorts+esi+2], ax
 
.last:
        add    esi, 4
 
        mov    byte [Addr_PCI], 18h  ;  14h+4=18h
        call   ReadPCIRegistr 
        and    eax, 0FFFCh           ; обнуляем лишнее
        cmp    eax, 0
        jne    .native3
        mov    eax, 0170h
.native3:
        mov    [IDEBasesPorts+esi], ax
 
        mov    byte [Addr_PCI],1Ch   ;  18h+4=1Ch
        call   ReadPCIRegistr 
        and    eax, 0FFFCh           ; зануляем лишнее
        cmp    eax, 0
        jne    .native4
        mov    eax, 0374h
.native4:
        add    ax, 2                 ; Порт контроля+2
        mov    [IDEBasesPorts+esi+2], ax
 
.MasterBus:
        add    esi, 4 
        mov    byte [Addr_PCI], 20h  ;  1Ch+4=20h
        call   ReadPCIRegistr 
        and    eax, 0FFFCh           ; зануляем лишнее Bus Master
        mov    [IDEBusMaster+edi*2], eax
 
        add    [Addr_PCI], 1Ch       ;  1Ch+20h=3Ch
        call   ReadPCIRegistr 
        and    eax, 0FFh             ; зануляем лишнее Interrupt Line (IRQ)
        mov    byte [IDEBusIRQ+edi], al
 
        inc    edi
.NotIDE:
        and    [Addr_PCI], 0FFFFFF00h
        add    [Addr_PCI], 100h
        cmp    esi, IDEMaxCanals*4            ; 8*4=20h 
        jne    .Next
 
        pop    edi
        pop    esi
        pop    eax
        ret

Обнаружено использование расширения AdBlock.


Викия — это свободный ресурс, который существует и развивается за счёт рекламы. Для блокирующих рекламу пользователей мы предоставляем модифицированную версию сайта.

Викия не будет доступна для последующих модификаций. Если вы желаете продолжать работать со страницей, то, пожалуйста, отключите расширение для блокировки рекламы.