Subversion Repositories Kolibri OS

Rev

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

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