Subversion Repositories Kolibri OS

Rev

Rev 6464 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6464 Rev 6842
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
7
 
8
$Revision: 6464 $
8
$Revision: 6842 $
9
 
9
 
10
; HDD and CD search
10
; HDD and CD search
11
 
11
 
12
        cmp     [ecx+IDE_DATA.ProgrammingInterface], 0
12
        cmp     [ecx+IDE_DATA.ProgrammingInterface], 0
13
        je      EndFindHDD
13
        je      EndFindHDD
14
FindHDD:
14
FindHDD:
15
        push    ecx
-
 
16
        xor     ebx, ebx
15
        xor     ebx, ebx
17
        inc     ebx
16
        inc     ebx
18
        mov     [DeviceNumber], 0
17
        mov     [DeviceNumber], 0
19
        cmp     ecx, IDE_controller_1
18
        cmp     ecx, IDE_controller_1
20
        jz      .find
19
        jz      .find
21
        add     bl, 5
20
        add     bl, 5
22
        add     [DeviceNumber], sizeof.HD_DATA*4
21
        add     [DeviceNumber], sizeof.HD_DATA*4
23
        cmp     ecx, IDE_controller_2
22
        cmp     ecx, IDE_controller_2
24
        jz      .find
23
        jz      .find
25
        add     bl, 5
24
        add     bl, 5
26
        add     [DeviceNumber], sizeof.HD_DATA*4
25
        add     [DeviceNumber], sizeof.HD_DATA*4
27
.find:
26
.find:
28
        mov     [ChannelNumber], 1
27
        mov     [ChannelNumber], 1
29
        mov     [DiskNumber], 0
28
        mov     [DiskNumber], 0
30
        call    FindHDD_1
29
        call    FindHDD_1
31
 
-
 
32
        inc     [DiskNumber]
30
        inc     [DiskNumber]
33
        call    FindHDD_2
31
        call    FindHDD_2
34
 
-
 
35
        inc     [ChannelNumber]
32
        inc     [ChannelNumber]
36
        dec     [DiskNumber]
33
        dec     [DiskNumber]
37
        call    FindHDD_2
34
        call    FindHDD_2
38
 
-
 
39
        inc     [DiskNumber]
35
        inc     [DiskNumber]
40
        call    FindHDD_2
36
        call    FindHDD_2
41
 
-
 
42
        pop     ecx
-
 
43
        jmp     EndFindHDD
37
        jmp     EndFindHDD
44
;-----------------------------------------------------------------------------
38
;-----------------------------------------------------------------------------
45
FindHDD_2:
39
FindHDD_2:
46
        add     [DeviceNumber], sizeof.HD_DATA
40
        add     [DeviceNumber], sizeof.HD_DATA
47
        shl     byte [ebx+DRIVE_DATA], 2
41
        shl     byte [ebx+DRIVE_DATA], 2
48
FindHDD_1:
42
FindHDD_1:
49
        DEBUGF  1, "K : Channel %d ",[ChannelNumber]:1
43
        DEBUGF  1, "K : Channel %d ",[ChannelNumber]:1
50
        DEBUGF  1, "Disk %d\n",[DiskNumber]:1
44
        DEBUGF  1, "Disk %d\n",[DiskNumber]:1
51
        push    ebx ecx
45
        push    ecx ebx
52
        call    ReadHDD_ID
46
        call    ReadHDD_ID
53
        pop     ecx ebx
-
 
54
        cmp     [DevErrorCode], 7
47
        cmp     [DevErrorCode], 7
55
        je      .end
48
        je      .end
56
        cmp     [DevErrorCode], 0
49
        cmp     [DevErrorCode], 0
57
        jne     .FindCD
50
        jne     .FindCD
58
 
-
 
59
        cmp     [Sector512+6], word 16
51
        cmp     [Sector512+6], word 16
60
        ja      .FindCD
52
        ja      .FindCD
61
 
-
 
62
        cmp     [Sector512+12], word 255
53
        cmp     [Sector512+12], word 255
63
        ja      .FindCD
54
        ja      .FindCD
64
 
-
 
65
        inc     byte [ebx+DRIVE_DATA]
55
        pop     ebx
66
        movzx   eax, [DeviceNumber]
56
        movzx   eax, [DeviceNumber]
-
 
57
        mov     ecx, [Sector512+120]
-
 
58
        mov     dword[eax+hd0_data.sectors], ecx
-
 
59
        and     dword[eax+hd0_data.sectors+4], 0
67
        bt      word [Sector512+166], 10
60
        bt      word [Sector512+166], 10
-
 
61
        jnc     .Print_Device_Name
68
        adc     [eax+hd0_data.hd48], 0
62
        mov     [eax+hd0_data.hd48], 1
-
 
63
        mov     ecx, [Sector512+200]
-
 
64
        mov     dword[eax+hd0_data.sectors], ecx
-
 
65
        mov     ecx, [Sector512+204]
-
 
66
        mov     dword[eax+hd0_data.sectors+4], ecx
69
        jmp     .Print_Device_Name
67
        jmp     .Print_Device_Name
70
;--------------------------------------
68
;--------------------------------------
71
.FindCD:
69
.FindCD:
72
        push    ebx ecx
-
 
73
        call    DeviceReset
70
        call    DeviceReset
74
        pop     ecx ebx
-
 
75
        cmp     [DevErrorCode], 0
71
        cmp     [DevErrorCode], 0
76
        jne     .end
72
        jne     .end
77
 
-
 
78
        push    ebx ecx
-
 
79
        call    ReadCD_ID
73
        call    ReadCD_ID
80
        pop     ecx ebx
-
 
81
        cmp     [DevErrorCode], 0
74
        cmp     [DevErrorCode], 0
82
        jne     .end
75
        jne     .end
83
 
-
 
-
 
76
        pop     ebx
84
        add     [ebx+DRIVE_DATA], byte 2
77
        inc     byte [ebx+DRIVE_DATA]
85
;--------------------------------------
78
;--------------------------------------
86
.Print_Device_Name:
79
.Print_Device_Name:
-
 
80
        inc     byte [ebx+DRIVE_DATA]
-
 
81
        pop     ecx
87
        pushad
82
        pushad
88
        pushfd
-
 
89
        movzx   ebx, [ChannelNumber]
83
        movzx   ebx, [ChannelNumber]
90
        dec     ebx
84
        dec     ebx
91
        shl     ebx, 1
85
        shl     ebx, 1
92
        add     bl, [DiskNumber]
86
        add     bl, [DiskNumber]
93
        shl     ebx, 1
87
        shl     ebx, 1
94
        call    calculate_IDE_device_values_storage
88
        call    calculate_IDE_device_values_storage
95
;--------------------------------------
89
;--------------------------------------
96
.copy_dev_name:
90
.copy_dev_name:
97
        mov     esi, Sector512+27*2
91
        mov     esi, Sector512+27*2
98
        mov     edi, dev_name
92
        mov     edi, dev_name
99
        mov     ecx, 20
93
        mov     ecx, 20
100
        cld
94
        cld
101
;--------------------------------------
95
;--------------------------------------
102
@@:
96
@@:
103
        lodsw
97
        lodsw
104
        xchg    ah, al
98
        xchg    ah, al
105
        stosw
99
        stosw
106
        loop    @b
100
        loop    @b
107
 
-
 
108
        DEBUGF 1, "K : Dev: %s \n", dev_name
101
        DEBUGF 1, "K : Dev: %s \n", dev_name
109
 
-
 
110
        xor     eax, eax
102
        xor     eax, eax
111
        mov     ax, [Sector512+64*2]
103
        mov     ax, [Sector512+64*2]
112
        DEBUGF  1, "K : PIO possible modes %x\n", al
104
        DEBUGF  1, "K : PIO possible modes %x\n", al
113
 
-
 
114
        mov     ax, [Sector512+51*2]
105
        mov     ax, [Sector512+51*2]
115
        mov     al, ah
106
        mov     al, ah
116
        call    convert_Sector512_value
107
        call    convert_Sector512_value
117
        DEBUGF  1, "K : PIO set mode %x\n", ah
108
        DEBUGF  1, "K : PIO set mode %x\n", ah
118
 
-
 
119
        mov     ax, [Sector512+63*2]
109
        mov     ax, [Sector512+63*2]
120
        DEBUGF  1, "K : Multiword DMA possible modes %x\n", al
110
        DEBUGF  1, "K : Multiword DMA possible modes %x\n", al
121
 
-
 
122
        mov     al, ah
111
        mov     al, ah
123
        call    convert_Sector512_value
112
        call    convert_Sector512_value
124
        DEBUGF  1, "K : Multiword DMA set mode %x\n", ah
113
        DEBUGF  1, "K : Multiword DMA set mode %x\n", ah
125
 
-
 
126
        mov     ax, [Sector512+88*2]
114
        mov     ax, [Sector512+88*2]
127
        DEBUGF  1, "K : Ultra DMA possible modes %x\n", al
115
        DEBUGF  1, "K : Ultra DMA possible modes %x\n", al
128
 
-
 
129
        mov     [ebx+IDE_DEVICE.UDMA_possible_modes], al
116
        mov     [ebx+IDE_DEVICE.UDMA_possible_modes], al
130
 
-
 
131
        mov     al, ah
117
        mov     al, ah
132
        call    convert_Sector512_value
118
        call    convert_Sector512_value
133
        DEBUGF  1, "K : Ultra DMA set mode %x\n", ah
119
        DEBUGF  1, "K : Ultra DMA set mode %x\n", ah
134
 
-
 
135
        mov     [ebx+IDE_DEVICE.UDMA_set_mode], ah
120
        mov     [ebx+IDE_DEVICE.UDMA_set_mode], ah
136
 
-
 
137
        popfd
-
 
138
        popad
121
        popad
139
        ret
122
        ret
140
;--------------------------------------
-
 
-
 
123
 
141
.end:
124
.end:
142
        DEBUGF  1, "K : Device not found\n"
125
        DEBUGF  1, "K : Device not found\n"
-
 
126
        pop     ebx ecx
143
        ret
127
        ret
144
;-----------------------------------------------------------------------------
128
;-----------------------------------------------------------------------------
145
calculate_IDE_device_values_storage:
129
calculate_IDE_device_values_storage:
146
        cmp     ecx, IDE_controller_1
130
        cmp     ecx, IDE_controller_1
147
        jne     @f
131
        jne     @f
148
 
132
 
149
        add     ebx, IDE_device_1
133
        add     ebx, IDE_device_1
150
        jmp     .exit
134
        jmp     .exit
151
;--------------------------------------
135
;--------------------------------------
152
@@:
136
@@:
153
        cmp     ecx, IDE_controller_2
137
        cmp     ecx, IDE_controller_2
154
        jne     @f
138
        jne     @f
155
 
139
 
156
        add     ebx, IDE_device_2
140
        add     ebx, IDE_device_2
157
        jmp     .exit
141
        jmp     .exit
158
;--------------------------------------
142
;--------------------------------------
159
@@:
143
@@:
160
        add     ebx, IDE_device_3
144
        add     ebx, IDE_device_3
161
;--------------------------------------
145
;--------------------------------------
162
.exit:
146
.exit:
163
        ret
147
        ret
164
;-----------------------------------------------------------------------------
148
;-----------------------------------------------------------------------------
165
convert_Sector512_value:
149
convert_Sector512_value:
166
        mov     ecx, 8
150
        mov     ecx, 8
167
        xor     ah, ah
151
        xor     ah, ah
168
;--------------------------------------
152
;--------------------------------------
169
@@:
153
@@:
170
        test    al, 1b
154
        test    al, 1b
171
        jnz     .end
155
        jnz     .end
172
 
156
 
173
        shr     al, 1
157
        shr     al, 1
174
        inc     ah
158
        inc     ah
175
        loop    @b
159
        loop    @b
176
 
160
 
177
        xor     ah, ah
161
        xor     ah, ah
178
;--------------------------------------
162
;--------------------------------------
179
.end:
163
.end:
180
        ret
164
        ret
181
;-----------------------------------------------------------------------------
165
;-----------------------------------------------------------------------------
182
; Адрес считываемого сектора в режиме LBA
166
; Адрес считываемого сектора в режиме LBA
183
uglobal
167
uglobal
184
SectorAddress   dd ?
168
SectorAddress   dd ?
185
dev_name:
169
dev_name:
186
        rb 41
170
        rb 41
187
endg
171
endg
188
;-----------------------------------------------------------------------------
172
;-----------------------------------------------------------------------------
189
;*************************************************
173
;*************************************************
190
;*     ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА      *
174
;*     ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА      *
191
;* Входные параметры передаются через глобальные *
175
;* Входные параметры передаются через глобальные *
192
;* переменные:                                   *
176
;* переменные:                                   *
193
;* ChannelNumber - номер канала (1 или 2);       *
177
;* ChannelNumber - номер канала (1 или 2);       *
194
;* DiskNumber - номер диска на канале (0 или 1). *
178
;* DiskNumber - номер диска на канале (0 или 1). *
195
;* Идентификационный блок данных считывается     *
179
;* Идентификационный блок данных считывается     *
196
;* в массив Sector512.                           *
180
;* в массив Sector512.                           *
197
;*************************************************
181
;*************************************************
198
ReadHDD_ID:
182
ReadHDD_ID:
199
; Задать режим CHS
183
; Задать режим CHS
200
        mov     [ATAAddressMode], 0
184
        mov     [ATAAddressMode], 0
201
; Послать команду идентификации устройства
185
; Послать команду идентификации устройства
202
        mov     [ATAFeatures], 0
186
        mov     [ATAFeatures], 0
203
        mov     [ATAHead], 0
187
        mov     [ATAHead], 0
204
        mov     [ATACommand], 0xEC
188
        mov     [ATACommand], 0xEC
205
        call    SendCommandToHDD
189
        call    SendCommandToHDD
206
        cmp     [DevErrorCode], 0 ;проверить код ошибки
190
        cmp     [DevErrorCode], 0 ;проверить код ошибки
207
        jne     @@End  ;закончить, сохранив код ошибки
191
        jne     @@End  ;закончить, сохранив код ошибки
208
 
192
 
209
        mov     dx, [ATABasePortAddr]
193
        mov     dx, [ATABasePortAddr]
210
        add     dx, 7    ;адрес регистра состояни
194
        add     dx, 7    ;адрес регистра состояни
211
        mov     ecx, 0xffff
195
        mov     ecx, 0xffff
212
@@WaitCompleet:
196
@@WaitCompleet:
213
        ; Проверить время выполнения команды
197
        ; Проверить время выполнения команды
214
        dec     ecx
198
        dec     ecx
215
        jz      @@Error1  ;ошибка тайм-аута
199
        jz      @@Error1  ;ошибка тайм-аута
216
        ; Проверить готовность
200
        ; Проверить готовность
217
        in      al, dx
201
        in      al, dx
218
        test    al, 80h  ;состояние сигнала BSY
202
        test    al, 80h  ;состояние сигнала BSY
219
        jnz     @@WaitCompleet
203
        jnz     @@WaitCompleet
220
 
204
 
221
        test    al, 1    ;состояние сигнала ERR
205
        test    al, 1    ;состояние сигнала ERR
222
        jnz     @@Error6
206
        jnz     @@Error6
223
 
207
 
224
        test    al, 08h  ;состояние сигнала DRQ
208
        test    al, 08h  ;состояние сигнала DRQ
225
        jz      @@WaitCompleet
209
        jz      @@WaitCompleet
226
; Принять блок данных от контроллера
210
; Принять блок данных от контроллера
227
        mov     edi, Sector512
211
        mov     edi, Sector512
228
        mov     dx, [ATABasePortAddr];регистр данных
212
        mov     dx, [ATABasePortAddr];регистр данных
229
        mov     cx, 256  ;число считываемых слов
213
        mov     cx, 256  ;число считываемых слов
230
        rep insw         ;принять блок данных
214
        rep insw         ;принять блок данных
231
        ret
215
        ret
232
; Записать код ошибки
216
; Записать код ошибки
233
@@Error1:
217
@@Error1:
234
        mov     [DevErrorCode], 1
218
        mov     [DevErrorCode], 1
235
        ret
219
        ret
236
@@Error6:
220
@@Error6:
237
        mov     [DevErrorCode], 6
221
        mov     [DevErrorCode], 6
238
@@End:
222
@@End:
239
        ret
223
        ret
240
;-----------------------------------------------------------------------------
224
;-----------------------------------------------------------------------------
241
uglobal
225
uglobal
242
; Стандартные базовые адреса каналов 1 и 2
226
; Стандартные базовые адреса каналов 1 и 2
243
StandardATABases dw ?, ? ; 1F0h, 170h
227
StandardATABases dw ?, ? ; 1F0h, 170h
244
; Номер канала
228
; Номер канала
245
ChannelNumber   db ?
229
ChannelNumber   db ?
246
; Номер диска
230
; Номер диска
247
DiskNumber      db ?
231
DiskNumber      db ?
248
DeviceNumber    db ?
232
DeviceNumber    db ?
249
; Базовый адрес группы портов контроллера ATA
233
; Базовый адрес группы портов контроллера ATA
250
ATABasePortAddr dw ?
234
ATABasePortAddr dw ?
251
; Параметры ATA-команды
235
; Параметры ATA-команды
252
ATAFeatures     db ? ;особенности
236
ATAFeatures     db ? ;особенности
253
ATASectorCount  db ? ;количество обрабатываемых секторов
237
ATASectorCount  db ? ;количество обрабатываемых секторов
254
ATASectorNumber db ? ;номер начального сектора
238
ATASectorNumber db ? ;номер начального сектора
255
ATACylinder     dw ? ;номер начального цилиндра
239
ATACylinder     dw ? ;номер начального цилиндра
256
ATAHead         db ? ;номер начальной головки
240
ATAHead         db ? ;номер начальной головки
257
ATAAddressMode  db ? ;режим адресации (0 - CHS, 1 - LBA)
241
ATAAddressMode  db ? ;режим адресации (0 - CHS, 1 - LBA)
258
ATACommand      db ? ;код команды, подлежащей выполнению
242
ATACommand      db ? ;код команды, подлежащей выполнению
259
; Код ошибки (0 - нет ошибок, 1 - превышен допустимый
243
; Код ошибки (0 - нет ошибок, 1 - превышен допустимый
260
; интервал ожидания, 2 - неверный код режима адресации,
244
; интервал ожидания, 2 - неверный код режима адресации,
261
; 3 - неверный номер канала, 4 - неверный номер диска,
245
; 3 - неверный номер канала, 4 - неверный номер диска,
262
; 5 - неверный номер головки, 6 - ошибка при выполнении
246
; 5 - неверный номер головки, 6 - ошибка при выполнении
263
; команды, 7 - таймаут при выборе канала)
247
; команды, 7 - таймаут при выборе канала)
264
DevErrorCode dd ?
248
DevErrorCode dd ?
265
endg
249
endg
266
;-----------------------------------------------------------------------------
250
;-----------------------------------------------------------------------------
267
;****************************************************
251
;****************************************************
268
;*          ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ         *
252
;*          ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ         *
269
;* Входные параметры передаются через глобальные    *
253
;* Входные параметры передаются через глобальные    *
270
;* переменные:                                      *
254
;* переменные:                                      *
271
;* ChannelNumber - номер канала (1 или 2);          *
255
;* ChannelNumber - номер канала (1 или 2);          *
272
;* DiskNumber - номер диска (0 или 1);              *
256
;* DiskNumber - номер диска (0 или 1);              *
273
;* ATAFeatures - "особенности";                     *
257
;* ATAFeatures - "особенности";                     *
274
;* ATASectorCount - количество секторов;            *
258
;* ATASectorCount - количество секторов;            *
275
;* ATASectorNumber - номер начального сектора;      *
259
;* ATASectorNumber - номер начального сектора;      *
276
;* ATACylinder - номер начального цилиндра;         *
260
;* ATACylinder - номер начального цилиндра;         *
277
;* ATAHead - номер начальной головки;               *
261
;* ATAHead - номер начальной головки;               *
278
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
262
;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); *
279
;* ATACommand - код команды.                        *
263
;* ATACommand - код команды.                        *
280
;* После успешного выполнения функции:              *
264
;* После успешного выполнения функции:              *
281
;* в ATABasePortAddr - базовый адрес HDD;           *
265
;* в ATABasePortAddr - базовый адрес HDD;           *
282
;* в DevErrorCode - ноль.                           *
266
;* в DevErrorCode - ноль.                           *
283
;* При возникновении ошибки в DevErrorCode будет    *
267
;* При возникновении ошибки в DevErrorCode будет    *
284
;* возвращен код ошибки.                            *
268
;* возвращен код ошибки.                            *
285
;****************************************************
269
;****************************************************
286
SendCommandToHDD:
270
SendCommandToHDD:
287
; Проверить значение кода режима
271
; Проверить значение кода режима
288
        cmp     [ATAAddressMode], 1
272
        cmp     [ATAAddressMode], 1
289
        ja      @@Err2
273
        ja      @@Err2
290
; Проверить корректность номера канала
274
; Проверить корректность номера канала
291
        movzx   ebx, [ChannelNumber]
275
        movzx   ebx, [ChannelNumber]
292
        dec     ebx
276
        dec     ebx
293
        cmp     ebx, 1
277
        cmp     ebx, 1
294
        ja      @@Err3
278
        ja      @@Err3
295
; Установить базовый адрес
279
; Установить базовый адрес
296
        shl     ebx, 1
280
        shl     ebx, 1
297
        mov     ax, [ebx+StandardATABases]
281
        mov     ax, [ebx+StandardATABases]
298
        mov     [ATABasePortAddr], ax
282
        mov     [ATABasePortAddr], ax
299
; Ожидание готовности HDD к приему команды
283
; Ожидание готовности HDD к приему команды
300
        ; Выбрать нужный диск
284
        ; Выбрать нужный диск
301
        mov     dx, [ATABasePortAddr]
285
        mov     dx, [ATABasePortAddr]
302
        add     dx, 6   ;адрес регистра головок
286
        add     dx, 6   ;адрес регистра головок
303
        mov     al, [DiskNumber]
287
        mov     al, [DiskNumber]
304
        cmp     al, 1   ;проверить номера диска
288
        cmp     al, 1   ;проверить номера диска
305
        ja      @@Err4
289
        ja      @@Err4
306
 
290
 
307
        shl     al, 4
291
        shl     al, 4
308
        or      al, 10100000b
292
        or      al, 10100000b
309
        out     dx, al
293
        out     dx, al
310
        ; Ожидать, пока диск не будет готов
294
        ; Ожидать, пока диск не будет готов
311
        inc     dx
295
        inc     dx
312
        mov     ecx, 0xfff
296
        mov     ecx, 0xfff
313
@@WaitHDReady:
297
@@WaitHDReady:
314
        ; Проверить время ожидани
298
        ; Проверить время ожидани
315
        dec     ecx
299
        dec     ecx
316
        jz      @@Err1
300
        jz      @@Err1
317
        ; Прочитать регистр состояни
301
        ; Прочитать регистр состояни
318
        in      al, dx
302
        in      al, dx
319
        ; Проверить состояние сигнала BSY
303
        ; Проверить состояние сигнала BSY
320
        test    al, 80h
304
        test    al, 80h
321
        jnz     @@WaitHDReady
305
        jnz     @@WaitHDReady
322
        ; Проверить состояние сигнала DRQ
306
        ; Проверить состояние сигнала DRQ
323
        test    al, 08h
307
        test    al, 08h
324
        jnz     @@WaitHDReady
308
        jnz     @@WaitHDReady
325
; Загрузить команду в регистры контроллера
309
; Загрузить команду в регистры контроллера
326
        cli
310
        cli
327
        mov     dx, [ATABasePortAddr]
311
        mov     dx, [ATABasePortAddr]
328
        inc     dx      ;регистр "особенностей"
312
        inc     dx      ;регистр "особенностей"
329
        mov     al, [ATAFeatures]
313
        mov     al, [ATAFeatures]
330
        out     dx, AL
314
        out     dx, AL
331
        inc     dx      ;счетчик секторов
315
        inc     dx      ;счетчик секторов
332
        mov     al, [ATASectorCount]
316
        mov     al, [ATASectorCount]
333
        out     dx, AL
317
        out     dx, AL
334
        inc     dx      ;регистр номера сектора
318
        inc     dx      ;регистр номера сектора
335
        mov     al, [ATASectorNumber]
319
        mov     al, [ATASectorNumber]
336
        out     dx, AL
320
        out     dx, AL
337
        inc     dx      ;номер цилиндра (младший байт)
321
        inc     dx      ;номер цилиндра (младший байт)
338
        mov     ax, [ATACylinder]
322
        mov     ax, [ATACylinder]
339
        out     dx, AL
323
        out     dx, AL
340
        inc     dx      ;номер цилиндра (старший байт)
324
        inc     dx      ;номер цилиндра (старший байт)
341
        mov     al, AH
325
        mov     al, AH
342
        out     dx, AL
326
        out     dx, AL
343
        inc     dx      ;номер головки/номер диска
327
        inc     dx      ;номер головки/номер диска
344
        mov     al, [DiskNumber]
328
        mov     al, [DiskNumber]
345
        shl     al, 4
329
        shl     al, 4
346
        cmp     [ATAHead], 0xF ;проверить номер головки
330
        cmp     [ATAHead], 0xF ;проверить номер головки
347
        ja      @@Err5
331
        ja      @@Err5
348
 
332
 
349
        or      al, [ATAHead]
333
        or      al, [ATAHead]
350
        or      al, 10100000b
334
        or      al, 10100000b
351
        mov     ah, [ATAAddressMode]
335
        mov     ah, [ATAAddressMode]
352
        shl     ah, 6
336
        shl     ah, 6
353
        or      al, ah
337
        or      al, ah
354
        out     dx, al
338
        out     dx, al
355
; Послать команду
339
; Послать команду
356
        mov     al, [ATACommand]
340
        mov     al, [ATACommand]
357
        inc     dx      ;регистр команд
341
        inc     dx      ;регистр команд
358
        out     dx, al
342
        out     dx, al
359
        sti
343
        sti
360
; Сбросить признак ошибки
344
; Сбросить признак ошибки
361
        mov     [DevErrorCode], 0
345
        mov     [DevErrorCode], 0
362
        ret
346
        ret
363
; Записать код ошибки
347
; Записать код ошибки
364
@@Err1:
348
@@Err1:
365
        mov     [DevErrorCode], 7
349
        mov     [DevErrorCode], 7
366
        ret
350
        ret
367
@@Err2:
351
@@Err2:
368
        mov     [DevErrorCode], 2
352
        mov     [DevErrorCode], 2
369
        ret
353
        ret
370
@@Err3:
354
@@Err3:
371
        mov     [DevErrorCode], 3
355
        mov     [DevErrorCode], 3
372
        ret
356
        ret
373
@@Err4:
357
@@Err4:
374
        mov     [DevErrorCode], 4
358
        mov     [DevErrorCode], 4
375
        ret
359
        ret
376
@@Err5:
360
@@Err5:
377
        mov     [DevErrorCode], 5
361
        mov     [DevErrorCode], 5
378
; Завершение работы программы
362
; Завершение работы программы
379
        ret
363
        ret
380
;-----------------------------------------------------------------------------
364
;-----------------------------------------------------------------------------
381
;*************************************************
365
;*************************************************
382
;*     ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI    *
366
;*     ЧТЕНИЕ ИДЕНТИФИКАТОРА УСТРОЙСТВА ATAPI    *
383
;* Входные параметры передаются через глобальные *
367
;* Входные параметры передаются через глобальные *
384
;* перменные:                                    *
368
;* перменные:                                    *
385
;* ChannelNumber - номер канала;                 *
369
;* ChannelNumber - номер канала;                 *
386
;* DiskNumber - номер диска на канале.           *
370
;* DiskNumber - номер диска на канале.           *
387
;* Идентификационный блок данных считывается     *
371
;* Идентификационный блок данных считывается     *
388
;* в массив Sector512.                           *
372
;* в массив Sector512.                           *
389
;*************************************************
373
;*************************************************
390
ReadCD_ID:
374
ReadCD_ID:
391
; Задать режим CHS
375
; Задать режим CHS
392
        mov     [ATAAddressMode], 0
376
        mov     [ATAAddressMode], 0
393
; Послать команду идентификации устройства
377
; Послать команду идентификации устройства
394
        mov     [ATAFeatures], 0
378
        mov     [ATAFeatures], 0
395
        mov     [ATASectorCount], 0
379
        mov     [ATASectorCount], 0
396
        mov     [ATASectorNumber], 0
380
        mov     [ATASectorNumber], 0
397
        mov     [ATACylinder], 0
381
        mov     [ATACylinder], 0
398
        mov     [ATAHead], 0
382
        mov     [ATAHead], 0
399
        mov     [ATACommand], 0xA1
383
        mov     [ATACommand], 0xA1
400
        call    SendCommandToHDD
384
        call    SendCommandToHDD
401
        cmp     [DevErrorCode], 0;проверить код ошибки
385
        cmp     [DevErrorCode], 0;проверить код ошибки
402
        jne     @@End_1  ;закончить, сохранив код ошибки
386
        jne     @@End_1  ;закончить, сохранив код ошибки
403
; Ожидать готовность данных HDD
387
; Ожидать готовность данных HDD
404
        mov     dx, [ATABasePortAddr]
388
        mov     dx, [ATABasePortAddr]
405
        add     dx, 7  ;порт 1х7h
389
        add     dx, 7  ;порт 1х7h
406
        mov     ecx, 0xffff
390
        mov     ecx, 0xffff
407
@@WaitCompleet_1:
391
@@WaitCompleet_1:
408
        ; Проверить врем
392
        ; Проверить врем
409
        dec     ecx
393
        dec     ecx
410
        jz      @@Error1_1 ;ошибка тайм-аута
394
        jz      @@Error1_1 ;ошибка тайм-аута
411
        ; Проверить готовность
395
        ; Проверить готовность
412
        in      al, dx
396
        in      al, dx
413
        test    al, 80h  ;состояние сигнала BSY
397
        test    al, 80h  ;состояние сигнала BSY
414
        jnz     @@WaitCompleet_1
398
        jnz     @@WaitCompleet_1
415
 
399
 
416
        test    al, 1    ;состояние сигнала ERR
400
        test    al, 1    ;состояние сигнала ERR
417
        jnz     @@Error6_1
401
        jnz     @@Error6_1
418
 
402
 
419
        test    al, 08h  ;состояние сигнала DRQ
403
        test    al, 08h  ;состояние сигнала DRQ
420
        jz      @@WaitCompleet_1
404
        jz      @@WaitCompleet_1
421
; Принять блок данных от контроллера
405
; Принять блок данных от контроллера
422
        mov     edi, Sector512 ;offset Sector512
406
        mov     edi, Sector512 ;offset Sector512
423
        mov     dx, [ATABasePortAddr];порт 1x0h
407
        mov     dx, [ATABasePortAddr];порт 1x0h
424
        mov     cx, 256;число считываемых слов
408
        mov     cx, 256;число считываемых слов
425
        rep insw
409
        rep insw
426
        ret
410
        ret
427
; Записать код ошибки
411
; Записать код ошибки
428
@@Error1_1:
412
@@Error1_1:
429
        mov     [DevErrorCode], 1
413
        mov     [DevErrorCode], 1
430
        ret
414
        ret
431
@@Error6_1:
415
@@Error6_1:
432
        mov     [DevErrorCode], 6
416
        mov     [DevErrorCode], 6
433
@@End_1:
417
@@End_1:
434
        ret
418
        ret
435
;-----------------------------------------------------------------------------
419
;-----------------------------------------------------------------------------
436
;*************************************************
420
;*************************************************
437
;*                СБРОС УСТРОЙСТВА               *
421
;*                СБРОС УСТРОЙСТВА               *
438
;* Входные параметры передаются через глобальные *
422
;* Входные параметры передаются через глобальные *
439
;* переменные:                                   *
423
;* переменные:                                   *
440
;* ChannelNumber - номер канала (1 или 2);       *
424
;* ChannelNumber - номер канала (1 или 2);       *
441
;* DiskNumber - номер диска (0 или 1).           *
425
;* DiskNumber - номер диска (0 или 1).           *
442
;*************************************************
426
;*************************************************
443
DeviceReset:
427
DeviceReset:
444
; Проверить корректность номера канала
428
; Проверить корректность номера канала
445
        movzx   ebx, [ChannelNumber]
429
        movzx   ebx, [ChannelNumber]
446
        dec     ebx
430
        dec     ebx
447
        cmp     ebx, 1
431
        cmp     ebx, 1
448
        ja      @@Err3_2
432
        ja      @@Err3_2
449
; Установить базовый адрес
433
; Установить базовый адрес
450
        shl     ebx, 1
434
        shl     ebx, 1
451
        mov     dx, [ebx+StandardATABases]
435
        mov     dx, [ebx+StandardATABases]
452
        mov     [ATABasePortAddr], dx
436
        mov     [ATABasePortAddr], dx
453
; Выбрать нужный диск
437
; Выбрать нужный диск
454
        add     dx, 6   ;адрес регистра головок
438
        add     dx, 6   ;адрес регистра головок
455
        mov     al, [DiskNumber]
439
        mov     al, [DiskNumber]
456
        cmp     al, 1   ;проверить номера диска
440
        cmp     al, 1   ;проверить номера диска
457
        ja      @@Err4_2
441
        ja      @@Err4_2
458
 
442
 
459
        shl     al, 4
443
        shl     al, 4
460
        or      al, 10100000b
444
        or      al, 10100000b
461
        out     dx, al
445
        out     dx, al
462
; Послать команду "Сброс"
446
; Послать команду "Сброс"
463
        mov     al, 0x8
447
        mov     al, 0x8
464
        inc     dx      ;регистр команд
448
        inc     dx      ;регистр команд
465
        out     dx, al
449
        out     dx, al
466
        mov     ecx, 0x80000
450
        mov     ecx, 0x80000
467
@@WaitHDReady_1:
451
@@WaitHDReady_1:
468
        ; Проверить время ожидани
452
        ; Проверить время ожидани
469
        dec     ecx
453
        dec     ecx
470
        je      @@Err1_2 ;ошибка тайм-аута
454
        je      @@Err1_2 ;ошибка тайм-аута
471
        ; Прочитать регистр состояни
455
        ; Прочитать регистр состояни
472
        in      al, dx
456
        in      al, dx
473
        ; Проверить состояние сигнала BSY
457
        ; Проверить состояние сигнала BSY
474
        test    al, 80h
458
        test    al, 80h
475
        jnz     @@WaitHDReady_1
459
        jnz     @@WaitHDReady_1
476
; Сбросить признак ошибки
460
; Сбросить признак ошибки
477
        mov     [DevErrorCode], 0
461
        mov     [DevErrorCode], 0
478
        ret
462
        ret
479
; Обработка ошибок
463
; Обработка ошибок
480
@@Err1_2:
464
@@Err1_2:
481
        mov     [DevErrorCode], 1
465
        mov     [DevErrorCode], 1
482
        ret
466
        ret
483
@@Err3_2:
467
@@Err3_2:
484
        mov     [DevErrorCode], 3
468
        mov     [DevErrorCode], 3
485
        ret
469
        ret
486
@@Err4_2:
470
@@Err4_2:
487
        mov     [DevErrorCode], 4
471
        mov     [DevErrorCode], 4
488
; Записать код ошибки
472
; Записать код ошибки
489
        ret
473
        ret
490
;-----------------------------------------------------------------------------
474
;-----------------------------------------------------------------------------
491
EndFindHDD:
475
EndFindHDD: