Rev 7136 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7136 | Rev 8053 | ||
---|---|---|---|
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: 7136 $ |
8 | $Revision: 8053 $ |
9 | 9 | ||
10 | ;----------------------------------------------------------------------------- |
10 | ;----------------------------------------------------------------------------- |
11 | ;********************************************************** |
11 | ;********************************************************** |
12 | ; Непосредственная работа с устройством СD (ATAPI) |
12 | ; Direct work with СD (ATAPI) device |
13 | ;********************************************************** |
13 | ;********************************************************** |
14 | ; Автор части исходного текста Кулаков Владимир Геннадьевич |
14 | ; Author of a part of the source code - Kulakov Vladimir Gennadievich |
15 | ; Адаптация, доработка и разработка Mario79, |
15 | ; Adaptation, revision and development - Mario79, |
16 | 16 | ||
17 | ; Максимальное количество повторений операции чтения |
17 | ; Maximum number of repeats of a read operation |
18 | MaxRetr = 10 |
18 | MaxRetr = 10 |
19 | ; Предельное время ожидания готовности к приему команды |
19 | ; Maximum waiting time for ready to receive a command |
20 | ; (в тиках) |
20 | ; (in ticks) |
21 | BSYWaitTime = 1000 ;2 |
21 | BSYWaitTime = 1000 ;2 |
22 | NoTickWaitTime = 0xfffff |
22 | NoTickWaitTime = 0xfffff |
23 | CDBlockSize = 2048 |
23 | CDBlockSize = 2048 |
24 | ;******************************************** |
24 | ;******************************************** |
25 | ;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ * |
25 | ;* ЧТЕНИЕ СЕКТОРА С ПОВТОРАМИ * |
26 | ;* Многократное повторение чтения при сбоях * |
26 | ;* Многократное повторение чтения при сбоях * |
27 | ;******************************************** |
27 | ;******************************************** |
28 | ReadCDWRetr: |
28 | ReadCDWRetr: |
29 | ;----------------------------------------------------------- |
29 | ;----------------------------------------------------------- |
30 | ; input : eax = block to read |
30 | ; input : eax = block to read |
31 | ; ebx = destination |
31 | ; ebx = destination |
32 | ;----------------------------------------------------------- |
32 | ;----------------------------------------------------------- |
33 | pushad |
33 | pushad |
34 | mov eax, [CDSectorAddress] |
34 | mov eax, [CDSectorAddress] |
35 | mov ebx, [CDDataBuf_pointer] |
35 | mov ebx, [CDDataBuf_pointer] |
36 | call cd_calculate_cache |
36 | call cd_calculate_cache |
37 | xor edi, edi |
37 | xor edi, edi |
38 | add esi, 8 |
38 | add esi, 8 |
39 | inc edi |
39 | inc edi |
40 | ;-------------------------------------- |
40 | ;-------------------------------------- |
41 | align 4 |
41 | align 4 |
42 | .hdreadcache: |
42 | .hdreadcache: |
43 | cmp [esi], eax ; correct sector |
43 | cmp [esi], eax ; correct sector |
44 | je .yeshdcache |
44 | je .yeshdcache |
45 | 45 | ||
46 | add esi, 8 |
46 | add esi, 8 |
47 | inc edi |
47 | inc edi |
48 | dec ecx |
48 | dec ecx |
49 | jnz .hdreadcache |
49 | jnz .hdreadcache |
50 | 50 | ||
51 | call find_empty_slot_CD_cache ; ret in edi |
51 | call find_empty_slot_CD_cache ; ret in edi |
52 | 52 | ||
53 | push edi |
53 | push edi |
54 | push eax |
54 | push eax |
55 | call cd_calculate_cache_2 |
55 | call cd_calculate_cache_2 |
56 | shl edi, 11 |
56 | shl edi, 11 |
57 | add edi, eax |
57 | add edi, eax |
58 | mov [CDDataBuf_pointer], edi |
58 | mov [CDDataBuf_pointer], edi |
59 | pop eax |
59 | pop eax |
60 | pop edi |
60 | pop edi |
61 | 61 | ||
62 | call ReadCDWRetr_1 |
62 | call ReadCDWRetr_1 |
63 | cmp [DevErrorCode], 0 |
63 | cmp [DevErrorCode], 0 |
64 | jne .exit |
64 | jne .exit |
65 | 65 | ||
66 | mov [CDDataBuf_pointer], ebx |
66 | mov [CDDataBuf_pointer], ebx |
67 | call cd_calculate_cache_1 |
67 | call cd_calculate_cache_1 |
68 | lea esi, [edi*8+esi] |
68 | lea esi, [edi*8+esi] |
69 | mov [esi], eax ; sector number |
69 | mov [esi], eax ; sector number |
70 | ;-------------------------------------- |
70 | ;-------------------------------------- |
71 | .yeshdcache: |
71 | .yeshdcache: |
72 | mov esi, edi |
72 | mov esi, edi |
73 | shl esi, 11 ;9 |
73 | shl esi, 11 ;9 |
74 | push eax |
74 | push eax |
75 | call cd_calculate_cache_2 |
75 | call cd_calculate_cache_2 |
76 | add esi, eax |
76 | add esi, eax |
77 | pop eax |
77 | pop eax |
78 | mov edi, ebx ;[CDDataBuf_pointer] |
78 | mov edi, ebx ;[CDDataBuf_pointer] |
79 | mov ecx, 512 ;/4 |
79 | mov ecx, 512 ;/4 |
80 | cld |
80 | cld |
81 | rep movsd ; move data |
81 | rep movsd ; move data |
82 | ;-------------------------------------- |
82 | ;-------------------------------------- |
83 | .exit: |
83 | .exit: |
84 | popad |
84 | popad |
85 | ret |
85 | ret |
86 | ;----------------------------------------------------------------------------- |
86 | ;----------------------------------------------------------------------------- |
87 | ReadCDWRetr_1: |
87 | ReadCDWRetr_1: |
88 | pushad |
88 | pushad |
89 | ; Цикл, пока команда не выполнена успешно или не |
89 | ; Цикл, пока команда не выполнена успешно или не |
90 | ; исчерпано количество попыток |
90 | ; исчерпано количество попыток |
91 | mov ecx, MaxRetr |
91 | mov ecx, MaxRetr |
92 | ;-------------------------------------- |
92 | ;-------------------------------------- |
93 | align 4 |
93 | align 4 |
94 | @@NextRetr: |
94 | @@NextRetr: |
95 | ; Подать команду |
95 | ; Подать команду |
96 | ;************************************************* |
96 | ;************************************************* |
97 | ;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА * |
97 | ;* ПОЛНОЕ ЧТЕНИЕ СЕКТОРА КОМПАКТ-ДИСКА * |
98 | ;* Считываются данные пользователя, информация * |
98 | ;* Считываются данные пользователя, информация * |
99 | ;* субканала и контрольная информация * |
99 | ;* субканала и контрольная информация * |
100 | ;* Входные параметры передаются через глобальные * |
100 | ;* Входные параметры передаются через глобальные * |
101 | ;* перменные: * |
101 | ;* перменные: * |
102 | ;* ChannelNumber - номер канала; * |
102 | ;* ChannelNumber - номер канала; * |
103 | ;* DiskNumber - номер диска на канале; * |
103 | ;* DiskNumber - номер диска на канале; * |
104 | ;* CDSectorAddress - адрес считываемого сектора. * |
104 | ;* CDSectorAddress - адрес считываемого сектора. * |
105 | ;* Данные считывается в массив CDDataBuf. * |
105 | ;* Данные считывается в массив CDDataBuf. * |
106 | ;************************************************* |
106 | ;************************************************* |
107 | ;ReadCD: |
107 | ;ReadCD: |
108 | push ecx |
108 | push ecx |
109 | ; Очистить буфер пакетной команды |
109 | ; Очистить буфер пакетной команды |
110 | call clear_packet_buffer |
110 | call clear_packet_buffer |
111 | ; Сформировать пакетную команду для считывания |
111 | ; Сформировать пакетную команду для считывания |
112 | ; сектора данных |
112 | ; сектора данных |
113 | ; Задать код команды Read CD |
113 | ; Задать код команды Read CD |
114 | mov [PacketCommand], byte 0x28 ;0xBE |
114 | mov [PacketCommand], byte 0x28 ;0xBE |
115 | ; Задать адрес сектора |
115 | ; Задать адрес сектора |
116 | mov ax, word [CDSectorAddress+2] |
116 | mov ax, word [CDSectorAddress+2] |
117 | xchg al, ah |
117 | xchg al, ah |
118 | mov word [PacketCommand+2], ax |
118 | mov word [PacketCommand+2], ax |
119 | mov ax, word [CDSectorAddress] |
119 | mov ax, word [CDSectorAddress] |
120 | xchg al, ah |
120 | xchg al, ah |
121 | mov word [PacketCommand+4], ax |
121 | mov word [PacketCommand+4], ax |
122 | ; Задать количество считываемых секторов |
122 | ; Задать количество считываемых секторов |
123 | mov [PacketCommand+8], byte 1 |
123 | mov [PacketCommand+8], byte 1 |
124 | ; Подать команду |
124 | ; Подать команду |
125 | call SendPacketDatCommand |
125 | call SendPacketDatCommand |
126 | pop ecx |
126 | pop ecx |
127 | 127 | ||
128 | test eax, eax |
128 | test eax, eax |
129 | jz @@End_4 |
129 | jz @@End_4 |
130 | 130 | ||
131 | or ecx, ecx ;{SPraid.simba} (for cd load) |
131 | or ecx, ecx ;{SPraid.simba} (for cd load) |
132 | jz @@End_4 |
132 | jz @@End_4 |
133 | 133 | ||
134 | dec ecx |
134 | dec ecx |
135 | 135 | ||
136 | cmp [timer_ticks_enable], 0 |
136 | cmp [timer_ticks_enable], 0 |
137 | jne @f |
137 | jne @f |
138 | 138 | ||
139 | mov eax, NoTickWaitTime |
139 | mov eax, NoTickWaitTime |
140 | ;-------------------------------------- |
140 | ;-------------------------------------- |
141 | align 4 |
141 | align 4 |
142 | .wait: |
142 | .wait: |
143 | dec eax |
143 | dec eax |
144 | jz @@NextRetr |
144 | jz @@NextRetr |
145 | 145 | ||
146 | jmp .wait |
146 | jmp .wait |
147 | ;-------------------------------------- |
147 | ;-------------------------------------- |
148 | align 4 |
148 | align 4 |
149 | @@: |
149 | @@: |
150 | loop @@NextRetr |
150 | loop @@NextRetr |
151 | ;-------------------------------------- |
151 | ;-------------------------------------- |
152 | @@End_4: |
152 | @@End_4: |
153 | mov dword [DevErrorCode], eax |
153 | mov dword [DevErrorCode], eax |
154 | popad |
154 | popad |
155 | ret |
155 | ret |
156 | ;----------------------------------------------------------------------------- |
156 | ;----------------------------------------------------------------------------- |
157 | ; Универсальные процедуры, обеспечивающие выполнение |
157 | ; Универсальные процедуры, обеспечивающие выполнение |
158 | ; пакетных команд в режиме PIO |
158 | ; пакетных команд в режиме PIO |
159 | ; Максимально допустимое время ожидания реакции |
159 | ; Максимально допустимое время ожидания реакции |
160 | ; устройства на пакетную команду (в тиках) |
160 | ; устройства на пакетную команду (в тиках) |
161 | ;----------------------------------------------------------------------------- |
161 | ;----------------------------------------------------------------------------- |
162 | MaxCDWaitTime = 1000 ;200 ;10 секунд |
162 | MaxCDWaitTime = 1000 ;200 ;10 секунд |
163 | uglobal |
163 | uglobal |
164 | ; Область памяти для формирования пакетной команды |
164 | ; Область памяти для формирования пакетной команды |
165 | PacketCommand: |
165 | PacketCommand: |
166 | rb 12 ;DB 12 DUP (?) |
166 | rb 12 ;DB 12 DUP (?) |
167 | ; Адрес считываемого сектора данных |
167 | ; Адрес считываемого сектора данных |
168 | CDSectorAddress: dd ? |
168 | CDSectorAddress: dd ? |
169 | ; Время начала очередной операции с диском |
169 | ; Время начала очередной операции с диском |
170 | TickCounter_1 dd 0 |
170 | TickCounter_1 dd 0 |
171 | ; Время начала ожидания готовности устройства |
171 | ; Время начала ожидания готовности устройства |
172 | WURStartTime dd 0 |
172 | WURStartTime dd 0 |
173 | ; указатель буфера для считывания |
173 | ; указатель буфера для считывания |
174 | CDDataBuf_pointer dd 0 |
174 | CDDataBuf_pointer dd 0 |
175 | endg |
175 | endg |
176 | ;----------------------------------------------------------------------------- |
176 | ;----------------------------------------------------------------------------- |
177 | ;**************************************************** |
177 | ;**************************************************** |
178 | ;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * |
178 | ;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * |
179 | ;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ * |
179 | ;* ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧУ ОДНОГО СЕКТОРА ДАННЫХ * |
180 | ;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ * |
180 | ;* РАЗМЕРОМ 2048 БАЙТ ОТ УСТРОЙСТВА К ХОСТУ * |
181 | ;* Входные параметры передаются через глобальные * |
181 | ;* Входные параметры передаются через глобальные * |
182 | ;* перменные: * |
182 | ;* перменные: * |
183 | ;* ChannelNumber - номер канала; * |
183 | ;* ChannelNumber - номер канала; * |
184 | ;* DiskNumber - номер диска на канале; * |
184 | ;* DiskNumber - номер диска на канале; * |
185 | ;* PacketCommand - 12-байтный командный пакет; * |
185 | ;* PacketCommand - 12-байтный командный пакет; * |
186 | ;* CDBlockSize - размер принимаемого блока данных. * |
186 | ;* CDBlockSize - размер принимаемого блока данных. * |
187 | ; return eax DevErrorCode |
187 | ; return eax DevErrorCode |
188 | ;**************************************************** |
188 | ;**************************************************** |
189 | SendPacketDatCommand: |
189 | SendPacketDatCommand: |
190 | xor eax, eax |
190 | xor eax, eax |
191 | ; Задать режим CHS |
191 | ; Задать режим CHS |
192 | mov byte [ATAAddressMode], al |
192 | mov byte [ATAAddressMode], al |
193 | ; Послать ATA-команду передачи пакетной команды |
193 | ; Послать ATA-команду передачи пакетной команды |
194 | mov byte [ATAFeatures], al |
194 | mov byte [ATAFeatures], al |
195 | mov byte [ATASectorCount], al |
195 | mov byte [ATASectorCount], al |
196 | mov byte [ATASectorNumber], al |
196 | mov byte [ATASectorNumber], al |
197 | ; Загрузить размер передаваемого блока |
197 | ; Загрузить размер передаваемого блока |
198 | mov [ATAHead], al |
198 | mov [ATAHead], al |
199 | mov [ATACylinder], CDBlockSize |
199 | mov [ATACylinder], CDBlockSize |
200 | mov [ATACommand], 0xA0 |
200 | mov [ATACommand], 0xA0 |
201 | call SendCommandToHDD_1 |
201 | call SendCommandToHDD_1 |
202 | test eax, eax |
202 | test eax, eax |
203 | jnz @@End_8 ;закончить, сохранив код ошибки |
203 | jnz @@End_8 ;закончить, сохранив код ошибки |
204 | ; Ожидание готовности дисковода к приему |
204 | ; Ожидание готовности дисковода к приему |
205 | ; пакетной команды |
205 | ; пакетной команды |
206 | mov dx, [ATABasePortAddr] |
206 | mov dx, [ATABasePortAddr] |
207 | add dx, 7 ;порт 1х7h |
207 | add dx, 7 ;порт 1х7h |
208 | mov ecx, NoTickWaitTime |
208 | mov ecx, NoTickWaitTime |
209 | ;-------------------------------------- |
209 | ;-------------------------------------- |
210 | align 4 |
210 | align 4 |
211 | @@WaitDevice0: |
211 | @@WaitDevice0: |
212 | cmp [timer_ticks_enable], 0 |
212 | cmp [timer_ticks_enable], 0 |
213 | jne @f |
213 | jne @f |
214 | 214 | ||
215 | dec ecx |
215 | dec ecx |
216 | jz @@Err1_1 |
216 | jz @@Err1_1 |
217 | 217 | ||
218 | jmp .test |
218 | jmp .test |
219 | ;-------------------------------------- |
219 | ;-------------------------------------- |
220 | align 4 |
220 | align 4 |
221 | @@: |
221 | @@: |
222 | call change_task |
222 | call change_task |
223 | ; Проверить время выполнения команды |
223 | ; Проверить время выполнения команды |
224 | mov eax, [timer_ticks] |
224 | mov eax, [timer_ticks] |
225 | sub eax, [TickCounter_1] |
225 | sub eax, [TickCounter_1] |
226 | cmp eax, BSYWaitTime |
226 | cmp eax, BSYWaitTime |
227 | ja @@Err1_1 ;ошибка тайм-аута |
227 | ja @@Err1_1 ;ошибка тайм-аута |
228 | ; Проверить готовность |
228 | ; Проверить готовность |
229 | ;-------------------------------------- |
229 | ;-------------------------------------- |
230 | align 4 |
230 | align 4 |
231 | .test: |
231 | .test: |
232 | in al, dx |
232 | in al, dx |
233 | test al, 0x80 ;состояние сигнала BSY |
233 | test al, 0x80 ;состояние сигнала BSY |
234 | jnz @@WaitDevice0 |
234 | jnz @@WaitDevice0 |
235 | 235 | ||
236 | test al, 1 ;состояние сигнала ERR |
236 | test al, 1 ;состояние сигнала ERR |
237 | jnz @@Err6 |
237 | jnz @@Err6 |
238 | 238 | ||
239 | test al, 0x8 ;состояние сигнала DRQ |
239 | test al, 0x8 ;состояние сигнала DRQ |
240 | jz @@WaitDevice0 |
240 | jz @@WaitDevice0 |
241 | ; Послать пакетную команду |
241 | ; Послать пакетную команду |
242 | cli |
242 | cli |
243 | mov dx, [ATABasePortAddr] |
243 | mov dx, [ATABasePortAddr] |
244 | mov ax, [PacketCommand] |
244 | mov ax, [PacketCommand] |
245 | out dx, ax |
245 | out dx, ax |
246 | mov ax, [PacketCommand+2] |
246 | mov ax, [PacketCommand+2] |
247 | out dx, ax |
247 | out dx, ax |
248 | mov ax, [PacketCommand+4] |
248 | mov ax, [PacketCommand+4] |
249 | out dx, ax |
249 | out dx, ax |
250 | mov ax, [PacketCommand+6] |
250 | mov ax, [PacketCommand+6] |
251 | out dx, ax |
251 | out dx, ax |
252 | mov ax, [PacketCommand+8] |
252 | mov ax, [PacketCommand+8] |
253 | out dx, ax |
253 | out dx, ax |
254 | mov ax, [PacketCommand+10] |
254 | mov ax, [PacketCommand+10] |
255 | out dx, ax |
255 | out dx, ax |
256 | sti |
256 | sti |
257 | ; Ожидание готовности данных |
257 | ; Ожидание готовности данных |
258 | mov dx, [ATABasePortAddr] |
258 | mov dx, [ATABasePortAddr] |
259 | add dx, 7 ;порт 1х7h |
259 | add dx, 7 ;порт 1х7h |
260 | mov ecx, NoTickWaitTime |
260 | mov ecx, NoTickWaitTime |
261 | ;-------------------------------------- |
261 | ;-------------------------------------- |
262 | align 4 |
262 | align 4 |
263 | @@WaitDevice1: |
263 | @@WaitDevice1: |
264 | cmp [timer_ticks_enable], 0 |
264 | cmp [timer_ticks_enable], 0 |
265 | jne @f |
265 | jne @f |
266 | 266 | ||
267 | dec ecx |
267 | dec ecx |
268 | jz @@Err1_1 |
268 | jz @@Err1_1 |
269 | 269 | ||
270 | jmp .test_1 |
270 | jmp .test_1 |
271 | ;-------------------------------------- |
271 | ;-------------------------------------- |
272 | align 4 |
272 | align 4 |
273 | @@: |
273 | @@: |
274 | call change_task |
274 | call change_task |
275 | ; Проверить время выполнения команды |
275 | ; Проверить время выполнения команды |
276 | mov eax, [timer_ticks] |
276 | mov eax, [timer_ticks] |
277 | sub eax, [TickCounter_1] |
277 | sub eax, [TickCounter_1] |
278 | cmp eax, MaxCDWaitTime |
278 | cmp eax, MaxCDWaitTime |
279 | ja @@Err1_1 ;ошибка тайм-аута |
279 | ja @@Err1_1 ;ошибка тайм-аута |
280 | ; Проверить готовность |
280 | ; Проверить готовность |
281 | ;-------------------------------------- |
281 | ;-------------------------------------- |
282 | align 4 |
282 | align 4 |
283 | .test_1: |
283 | .test_1: |
284 | in al, dx |
284 | in al, dx |
285 | test al, 0x80 ;состояние сигнала BSY |
285 | test al, 0x80 ;состояние сигнала BSY |
286 | jnz @@WaitDevice1 |
286 | jnz @@WaitDevice1 |
287 | 287 | ||
288 | test al, 1 ;состояние сигнала ERR |
288 | test al, 1 ;состояние сигнала ERR |
289 | jnz @@Err6_temp |
289 | jnz @@Err6_temp |
290 | 290 | ||
291 | test al, 0x8 ;состояние сигнала DRQ |
291 | test al, 0x8 ;состояние сигнала DRQ |
292 | jz @@WaitDevice1 |
292 | jz @@WaitDevice1 |
293 | ; Принять блок данных от контроллера |
293 | ; Принять блок данных от контроллера |
294 | mov edi, [CDDataBuf_pointer] |
294 | mov edi, [CDDataBuf_pointer] |
295 | ; Загрузить адрес регистра данных контроллера |
295 | ; Загрузить адрес регистра данных контроллера |
296 | mov dx, [ATABasePortAddr] |
296 | mov dx, [ATABasePortAddr] |
297 | ; Загрузить в счетчик размер блока в байтах |
297 | ; Загрузить в счетчик размер блока в байтах |
298 | xor ecx, ecx |
298 | xor ecx, ecx |
299 | mov cx, CDBlockSize |
299 | mov cx, CDBlockSize |
300 | ; Вычислить размер блока в 16-разрядных словах |
300 | ; Вычислить размер блока в 16-разрядных словах |
301 | shr cx, 1 ;разделить размер блока на 2 |
301 | shr cx, 1 ;разделить размер блока на 2 |
302 | ; Принять блок данных |
302 | ; Принять блок данных |
303 | cli |
303 | cli |
304 | cld |
304 | cld |
305 | rep insw |
305 | rep insw |
306 | sti |
306 | sti |
307 | ;-------------------------------------- |
307 | ;-------------------------------------- |
308 | ; Успешное завершение приема данных |
308 | ; Успешное завершение приема данных |
309 | @@End_8: |
309 | @@End_8: |
310 | xor eax, eax |
310 | xor eax, eax |
311 | ret |
311 | ret |
312 | ;-------------------------------------- |
312 | ;-------------------------------------- |
313 | ; Записать код ошибки |
313 | ; Записать код ошибки |
314 | @@Err1_1: |
314 | @@Err1_1: |
315 | xor eax, eax |
315 | xor eax, eax |
316 | inc eax |
316 | inc eax |
317 | ret |
317 | ret |
318 | ;-------------------------------------- |
318 | ;-------------------------------------- |
319 | @@Err6_temp: |
319 | @@Err6_temp: |
320 | mov eax, 7 |
320 | mov eax, 7 |
321 | ret |
321 | ret |
322 | ;-------------------------------------- |
322 | ;-------------------------------------- |
323 | @@Err6: |
323 | @@Err6: |
324 | mov eax, 6 |
324 | mov eax, 6 |
325 | ret |
325 | ret |
326 | ;----------------------------------------------------------------------------- |
326 | ;----------------------------------------------------------------------------- |
327 | ;*********************************************** |
327 | ;*********************************************** |
328 | ;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * |
328 | ;* ПОСЛАТЬ УСТРОЙСТВУ ATAPI ПАКЕТНУЮ КОМАНДУ, * |
329 | ;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ * |
329 | ;* НЕ ПРЕДУСМАТРИВАЮЩУЮ ПЕРЕДАЧИ ДАННЫХ * |
330 | ;* Входные параметры передаются через * |
330 | ;* Входные параметры передаются через * |
331 | ;* глобальные перменные: * |
331 | ;* глобальные перменные: * |
332 | ;* ChannelNumber - номер канала; * |
332 | ;* ChannelNumber - номер канала; * |
333 | ;* DiskNumber - номер диска на канале; * |
333 | ;* DiskNumber - номер диска на канале; * |
334 | ;* PacketCommand - 12-байтный командный пакет. * |
334 | ;* PacketCommand - 12-байтный командный пакет. * |
335 | ;*********************************************** |
335 | ;*********************************************** |
336 | SendPacketNoDatCommand: |
336 | SendPacketNoDatCommand: |
337 | pushad |
337 | pushad |
338 | xor eax, eax |
338 | xor eax, eax |
339 | ; Задать режим CHS |
339 | ; Задать режим CHS |
340 | mov byte [ATAAddressMode], al |
340 | mov byte [ATAAddressMode], al |
341 | ; Послать ATA-команду передачи пакетной команды |
341 | ; Послать ATA-команду передачи пакетной команды |
342 | mov byte [ATAFeatures], al |
342 | mov byte [ATAFeatures], al |
343 | mov byte [ATASectorCount], al |
343 | mov byte [ATASectorCount], al |
344 | mov byte [ATASectorNumber], al |
344 | mov byte [ATASectorNumber], al |
345 | mov word [ATACylinder], ax |
345 | mov word [ATACylinder], ax |
346 | mov byte [ATAHead], al |
346 | mov byte [ATAHead], al |
347 | mov [ATACommand], 0xA0 |
347 | mov [ATACommand], 0xA0 |
348 | call SendCommandToHDD_1 |
348 | call SendCommandToHDD_1 |
349 | test eax, eax |
349 | test eax, eax |
350 | jnz @@End_9 ;закончить, сохранив код ошибки |
350 | jnz @@End_9 ;закончить, сохранив код ошибки |
351 | ; Ожидание готовности дисковода к приему |
351 | ; Ожидание готовности дисковода к приему |
352 | ; пакетной команды |
352 | ; пакетной команды |
353 | mov dx, [ATABasePortAddr] |
353 | mov dx, [ATABasePortAddr] |
354 | add dx, 7 ;порт 1х7h |
354 | add dx, 7 ;порт 1х7h |
355 | ;-------------------------------------- |
355 | ;-------------------------------------- |
356 | align 4 |
356 | align 4 |
357 | @@WaitDevice0_1: |
357 | @@WaitDevice0_1: |
358 | call change_task |
358 | call change_task |
359 | ; Проверить время ожидания |
359 | ; Проверить время ожидания |
360 | mov eax, [timer_ticks] |
360 | mov eax, [timer_ticks] |
361 | sub eax, [TickCounter_1] |
361 | sub eax, [TickCounter_1] |
362 | cmp eax, BSYWaitTime |
362 | cmp eax, BSYWaitTime |
363 | ja @@Err1_3 ;ошибка тайм-аута |
363 | ja @@Err1_3 ;ошибка тайм-аута |
364 | ; Проверить готовность |
364 | ; Проверить готовность |
365 | in al, dx |
365 | in al, dx |
366 | test al, 0x80 ;состояние сигнала BSY |
366 | test al, 0x80 ;состояние сигнала BSY |
367 | jnz @@WaitDevice0_1 |
367 | jnz @@WaitDevice0_1 |
368 | 368 | ||
369 | test al, 1 ;состояние сигнала ERR |
369 | test al, 1 ;состояние сигнала ERR |
370 | jnz @@Err6_1 |
370 | jnz @@Err6_1 |
371 | 371 | ||
372 | test al, 0x8 ;состояние сигнала DRQ |
372 | test al, 0x8 ;состояние сигнала DRQ |
373 | jz @@WaitDevice0_1 |
373 | jz @@WaitDevice0_1 |
374 | ; Послать пакетную команду |
374 | ; Послать пакетную команду |
375 | ; cli |
375 | ; cli |
376 | mov dx, [ATABasePortAddr] |
376 | mov dx, [ATABasePortAddr] |
377 | mov ax, word [PacketCommand] |
377 | mov ax, word [PacketCommand] |
378 | out dx, ax |
378 | out dx, ax |
379 | mov ax, word [PacketCommand+2] |
379 | mov ax, word [PacketCommand+2] |
380 | out dx, ax |
380 | out dx, ax |
381 | mov ax, word [PacketCommand+4] |
381 | mov ax, word [PacketCommand+4] |
382 | out dx, ax |
382 | out dx, ax |
383 | mov ax, word [PacketCommand+6] |
383 | mov ax, word [PacketCommand+6] |
384 | out dx, ax |
384 | out dx, ax |
385 | mov ax, word [PacketCommand+8] |
385 | mov ax, word [PacketCommand+8] |
386 | out dx, ax |
386 | out dx, ax |
387 | mov ax, word [PacketCommand+10] |
387 | mov ax, word [PacketCommand+10] |
388 | out dx, ax |
388 | out dx, ax |
389 | ; sti |
389 | ; sti |
390 | cmp [ignore_CD_eject_wait], 1 |
390 | cmp [ignore_CD_eject_wait], 1 |
391 | je @@clear_DEC |
391 | je @@clear_DEC |
392 | ; Ожидание подтверждения приема команды |
392 | ; Ожидание подтверждения приема команды |
393 | mov dx, [ATABasePortAddr] |
393 | mov dx, [ATABasePortAddr] |
394 | add dx, 7 ;порт 1х7h |
394 | add dx, 7 ;порт 1х7h |
395 | ;-------------------------------------- |
395 | ;-------------------------------------- |
396 | align 4 |
396 | align 4 |
397 | @@WaitDevice1_1: |
397 | @@WaitDevice1_1: |
398 | call change_task |
398 | call change_task |
399 | ; Проверить время выполнения команды |
399 | ; Проверить время выполнения команды |
400 | mov eax, [timer_ticks] |
400 | mov eax, [timer_ticks] |
401 | sub eax, [TickCounter_1] |
401 | sub eax, [TickCounter_1] |
402 | cmp eax, MaxCDWaitTime |
402 | cmp eax, MaxCDWaitTime |
403 | ja @@Err1_3 ;ошибка тайм-аута |
403 | ja @@Err1_3 ;ошибка тайм-аута |
404 | ; Ожидать освобождения устройства |
404 | ; Ожидать освобождения устройства |
405 | in al, dx |
405 | in al, dx |
406 | test al, 0x80 ;состояние сигнала BSY |
406 | test al, 0x80 ;состояние сигнала BSY |
407 | jnz @@WaitDevice1_1 |
407 | jnz @@WaitDevice1_1 |
408 | 408 | ||
409 | test al, 1 ;состояние сигнала ERR |
409 | test al, 1 ;состояние сигнала ERR |
410 | jnz @@Err6_1 |
410 | jnz @@Err6_1 |
411 | 411 | ||
412 | test al, 0x40 ;состояние сигнала DRDY |
412 | test al, 0x40 ;состояние сигнала DRDY |
413 | jz @@WaitDevice1_1 |
413 | jz @@WaitDevice1_1 |
414 | ;-------------------------------------- |
414 | ;-------------------------------------- |
415 | @@clear_DEC: |
415 | @@clear_DEC: |
416 | and [DevErrorCode], 0 |
416 | and [DevErrorCode], 0 |
417 | popad |
417 | popad |
418 | ret |
418 | ret |
419 | ;-------------------------------------- |
419 | ;-------------------------------------- |
420 | ; Записать код ошибки |
420 | ; Записать код ошибки |
421 | @@Err1_3: |
421 | @@Err1_3: |
422 | xor eax, eax |
422 | xor eax, eax |
423 | inc eax |
423 | inc eax |
424 | jmp @@End_9 |
424 | jmp @@End_9 |
425 | ;-------------------------------------- |
425 | ;-------------------------------------- |
426 | @@Err6_1: |
426 | @@Err6_1: |
427 | mov eax, 6 |
427 | mov eax, 6 |
428 | ;-------------------------------------- |
428 | ;-------------------------------------- |
429 | @@End_9: |
429 | @@End_9: |
430 | mov [DevErrorCode], eax |
430 | mov [DevErrorCode], eax |
431 | popad |
431 | popad |
432 | ret |
432 | ret |
433 | ;----------------------------------------------------------------------------- |
433 | ;----------------------------------------------------------------------------- |
434 | ;**************************************************** |
434 | ;**************************************************** |
435 | ;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * |
435 | ;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * |
436 | ;* Входные параметры передаются через глобальные * |
436 | ;* Входные параметры передаются через глобальные * |
437 | ;* переменные: * |
437 | ;* переменные: * |
438 | ;* ChannelNumber - номер канала (1 или 2); * |
438 | ;* ChannelNumber - номер канала (1 или 2); * |
439 | ;* DiskNumber - номер диска (0 или 1); * |
439 | ;* DiskNumber - номер диска (0 или 1); * |
440 | ;* ATAFeatures - "особенности"; * |
440 | ;* ATAFeatures - "особенности"; * |
441 | ;* ATASectorCount - количество секторов; * |
441 | ;* ATASectorCount - количество секторов; * |
442 | ;* ATASectorNumber - номер начального сектора; * |
442 | ;* ATASectorNumber - номер начального сектора; * |
443 | ;* ATACylinder - номер начального цилиндра; * |
443 | ;* ATACylinder - номер начального цилиндра; * |
444 | ;* ATAHead - номер начальной головки; * |
444 | ;* ATAHead - номер начальной головки; * |
445 | ;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); * |
445 | ;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); * |
446 | ;* ATACommand - код команды. * |
446 | ;* ATACommand - код команды. * |
447 | ;* После успешного выполнения функции: * |
447 | ;* После успешного выполнения функции: * |
448 | ;* в ATABasePortAddr - базовый адрес HDD; * |
448 | ;* в ATABasePortAddr - базовый адрес HDD; * |
449 | ;* в DevErrorCode - ноль. * |
449 | ;* в DevErrorCode - ноль. * |
450 | ;* При возникновении ошибки в DevErrorCode будет * |
450 | ;* При возникновении ошибки в DevErrorCode будет * |
451 | ;* возвращен код ошибки в eax * |
451 | ;* возвращен код ошибки в eax * |
452 | ;**************************************************** |
452 | ;**************************************************** |
453 | SendCommandToHDD_1: |
453 | SendCommandToHDD_1: |
454 | ; Проверить значение кода режима |
454 | ; Проверить значение кода режима |
455 | cmp [ATAAddressMode], 1 |
455 | cmp [ATAAddressMode], 1 |
456 | ja @@Err2_4 |
456 | ja @@Err2_4 |
457 | ; Проверить корректность номера канала |
457 | ; Проверить корректность номера канала |
458 | movzx ebx, [ChannelNumber] |
458 | movzx ebx, [ChannelNumber] |
459 | dec ebx |
459 | dec ebx |
460 | cmp ebx, 1 |
460 | cmp ebx, 1 |
461 | ja @@Err3_4 |
461 | ja @@Err3_4 |
462 | ; Установить базовый адрес |
462 | ; Установить базовый адрес |
463 | shl ebx, 2 |
463 | shl ebx, 2 |
464 | mov eax, [cdpos] |
464 | mov eax, [cdpos] |
465 | dec eax |
465 | dec eax |
466 | shr eax, 2 |
466 | shr eax, 2 |
467 | imul eax, sizeof.IDE_DATA |
467 | imul eax, sizeof.IDE_DATA |
468 | add eax, IDE_controller_1 |
468 | add eax, IDE_controller_1 |
469 | add eax, ebx |
469 | add eax, ebx |
470 | mov ax, [eax+IDE_DATA.BAR0_val] |
470 | mov ax, [eax+IDE_DATA.BAR0_val] |
471 | mov [ATABasePortAddr], ax |
471 | mov [ATABasePortAddr], ax |
472 | ; Ожидание готовности HDD к приему команды |
472 | ; Ожидание готовности HDD к приему команды |
473 | ; Выбрать нужный диск |
473 | ; Выбрать нужный диск |
474 | mov dx, [ATABasePortAddr] |
474 | mov dx, [ATABasePortAddr] |
475 | add dx, 6 ;адрес регистра головок |
475 | add dx, 6 ;адрес регистра головок |
476 | mov al, [DiskNumber] |
476 | mov al, [DiskNumber] |
477 | cmp al, 1 ;проверить номера диска |
477 | cmp al, 1 ;проверить номера диска |
478 | ja @@Err4_4 |
478 | ja @@Err4_4 |
479 | 479 | ||
480 | shl al, 4 |
480 | shl al, 4 |
481 | or al, 10100000b |
481 | or al, 10100000b |
482 | out dx, al |
482 | out dx, al |
483 | ; Ожидать, пока диск не будет готов |
483 | ; Ожидать, пока диск не будет готов |
484 | inc dx |
484 | inc dx |
485 | mov eax, [timer_ticks] |
485 | mov eax, [timer_ticks] |
486 | mov [TickCounter_1], eax |
486 | mov [TickCounter_1], eax |
487 | mov ecx, NoTickWaitTime |
487 | mov ecx, NoTickWaitTime |
488 | ;-------------------------------------- |
488 | ;-------------------------------------- |
489 | align 4 |
489 | align 4 |
490 | @@WaitHDReady_2: |
490 | @@WaitHDReady_2: |
491 | cmp [timer_ticks_enable], 0 |
491 | cmp [timer_ticks_enable], 0 |
492 | jne @f |
492 | jne @f |
493 | 493 | ||
494 | dec ecx |
494 | dec ecx |
495 | jz @@Err1_4 |
495 | jz @@Err1_4 |
496 | 496 | ||
497 | jmp .test |
497 | jmp .test |
498 | ;-------------------------------------- |
498 | ;-------------------------------------- |
499 | align 4 |
499 | align 4 |
500 | @@: |
500 | @@: |
501 | call change_task |
501 | call change_task |
502 | ; Проверить время ожидания |
502 | ; Проверить время ожидания |
503 | mov eax, [timer_ticks] |
503 | mov eax, [timer_ticks] |
504 | sub eax, [TickCounter_1] |
504 | sub eax, [TickCounter_1] |
505 | cmp eax, BSYWaitTime ;300 ;ожидать 3 сек. |
505 | cmp eax, BSYWaitTime ;300 ;ожидать 3 сек. |
506 | ja @@Err1_4 ;ошибка тайм-аута |
506 | ja @@Err1_4 ;ошибка тайм-аута |
507 | ;-------------------------------------- |
507 | ;-------------------------------------- |
508 | align 4 |
508 | align 4 |
509 | .test: |
509 | .test: |
510 | in al, dx ; Прочитать регистр состояния |
510 | in al, dx ; Прочитать регистр состояния |
511 | ; Проверить состояние сигнала BSY |
511 | ; Проверить состояние сигнала BSY |
512 | test al, 0x80 |
512 | test al, 0x80 |
513 | jnz @@WaitHDReady_2 |
513 | jnz @@WaitHDReady_2 |
514 | ; Проверить состояние сигнала DRQ |
514 | ; Проверить состояние сигнала DRQ |
515 | test al, 0x8 |
515 | test al, 0x8 |
516 | jnz @@WaitHDReady_2 |
516 | jnz @@WaitHDReady_2 |
517 | ; Загрузить команду в регистры контроллера |
517 | ; Загрузить команду в регистры контроллера |
518 | cli |
518 | cli |
519 | mov dx, [ATABasePortAddr] |
519 | mov dx, [ATABasePortAddr] |
520 | inc dx ;регистр "особенностей" |
520 | inc dx ;регистр "особенностей" |
521 | mov al, [ATAFeatures] |
521 | mov al, [ATAFeatures] |
522 | out dx, al |
522 | out dx, al |
523 | inc dx ;счетчик секторов |
523 | inc dx ;счетчик секторов |
524 | mov al, [ATASectorCount] |
524 | mov al, [ATASectorCount] |
525 | out dx, al |
525 | out dx, al |
526 | inc dx ;регистр номера сектора |
526 | inc dx ;регистр номера сектора |
527 | mov al, [ATASectorNumber] |
527 | mov al, [ATASectorNumber] |
528 | out dx, al |
528 | out dx, al |
529 | inc dx ;номер цилиндра (младший байт) |
529 | inc dx ;номер цилиндра (младший байт) |
530 | mov ax, [ATACylinder] |
530 | mov ax, [ATACylinder] |
531 | out dx, al |
531 | out dx, al |
532 | inc dx ;номер цилиндра (старший байт) |
532 | inc dx ;номер цилиндра (старший байт) |
533 | mov al, ah |
533 | mov al, ah |
534 | out dx, al |
534 | out dx, al |
535 | inc dx ;номер головки/номер диска |
535 | inc dx ;номер головки/номер диска |
536 | mov al, [DiskNumber] |
536 | mov al, [DiskNumber] |
537 | shl al, 4 |
537 | shl al, 4 |
538 | cmp [ATAHead], 0xF ;проверить номер головки |
538 | cmp [ATAHead], 0xF ;проверить номер головки |
539 | ja @@Err5_4 |
539 | ja @@Err5_4 |
540 | 540 | ||
541 | or al, [ATAHead] |
541 | or al, [ATAHead] |
542 | or al, 10100000b |
542 | or al, 10100000b |
543 | mov ah, [ATAAddressMode] |
543 | mov ah, [ATAAddressMode] |
544 | shl ah, 6 |
544 | shl ah, 6 |
545 | or al, ah |
545 | or al, ah |
546 | out dx, al |
546 | out dx, al |
547 | ; Послать команду |
547 | ; Послать команду |
548 | mov al, [ATACommand] |
548 | mov al, [ATACommand] |
549 | inc dx ;регистр команд |
549 | inc dx ;регистр команд |
550 | out dx, al |
550 | out dx, al |
551 | sti |
551 | sti |
552 | ;-------------------------------------- |
552 | ;-------------------------------------- |
553 | @@End_10: |
553 | @@End_10: |
554 | xor eax, eax |
554 | xor eax, eax |
555 | ret |
555 | ret |
556 | ;-------------------------------------- |
556 | ;-------------------------------------- |
557 | ; Записать код ошибки |
557 | ; Записать код ошибки |
558 | @@Err1_4: |
558 | @@Err1_4: |
559 | xor eax, eax |
559 | xor eax, eax |
560 | inc eax |
560 | inc eax |
561 | ret |
561 | ret |
562 | ;-------------------------------------- |
562 | ;-------------------------------------- |
563 | @@Err2_4: |
563 | @@Err2_4: |
564 | mov eax, 2 |
564 | mov eax, 2 |
565 | ret |
565 | ret |
566 | ;-------------------------------------- |
566 | ;-------------------------------------- |
567 | @@Err3_4: |
567 | @@Err3_4: |
568 | mov eax, 3 |
568 | mov eax, 3 |
569 | ret |
569 | ret |
570 | ;-------------------------------------- |
570 | ;-------------------------------------- |
571 | @@Err4_4: |
571 | @@Err4_4: |
572 | mov eax, 4 |
572 | mov eax, 4 |
573 | ret |
573 | ret |
574 | ;-------------------------------------- |
574 | ;-------------------------------------- |
575 | @@Err5_4: |
575 | @@Err5_4: |
576 | mov eax, 5 |
576 | mov eax, 5 |
577 | ret |
577 | ret |
578 | ;----------------------------------------------------------------------------- |
578 | ;----------------------------------------------------------------------------- |
579 | ;************************************************* |
579 | ;************************************************* |
580 | ;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ * |
580 | ;* ОЖИДАНИЕ ГОТОВНОСТИ УСТРОЙСТВА К РАБОТЕ * |
581 | ;* Входные параметры передаются через глобальные * |
581 | ;* Входные параметры передаются через глобальные * |
582 | ;* перменные: * |
582 | ;* перменные: * |
583 | ;* ChannelNumber - номер канала; * |
583 | ;* ChannelNumber - номер канала; * |
584 | ;* DiskNumber - номер диска на канале. * |
584 | ;* DiskNumber - номер диска на канале. * |
585 | ;************************************************* |
585 | ;************************************************* |
586 | WaitUnitReady: |
586 | WaitUnitReady: |
587 | pusha |
587 | pusha |
588 | ; Запомнить время начала операции |
588 | ; Запомнить время начала операции |
589 | mov eax, [timer_ticks] |
589 | mov eax, [timer_ticks] |
590 | mov [WURStartTime], eax |
590 | mov [WURStartTime], eax |
591 | ; Очистить буфер пакетной команды |
591 | ; Очистить буфер пакетной команды |
592 | call clear_packet_buffer |
592 | call clear_packet_buffer |
593 | ; Сформировать команду TEST UNIT READY |
593 | ; Сформировать команду TEST UNIT READY |
594 | mov [PacketCommand], word 0 |
594 | mov [PacketCommand], word 0 |
595 | ; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА |
595 | ; ЦИКЛ ОЖИДАНИЯ ГОТОВНОСТИ УСТРОЙСТВА |
596 | mov ecx, NoTickWaitTime |
596 | mov ecx, NoTickWaitTime |
597 | ;-------------------------------------- |
597 | ;-------------------------------------- |
598 | align 4 |
598 | align 4 |
599 | @@SendCommand: |
599 | @@SendCommand: |
600 | ; Подать команду проверки готовности |
600 | ; Подать команду проверки готовности |
601 | call SendPacketNoDatCommand |
601 | call SendPacketNoDatCommand |
602 | cmp [timer_ticks_enable], 0 |
602 | cmp [timer_ticks_enable], 0 |
603 | jne @f |
603 | jne @f |
604 | 604 | ||
605 | cmp [DevErrorCode], 0 |
605 | cmp [DevErrorCode], 0 |
606 | je @@End_11 |
606 | je @@End_11 |
607 | 607 | ||
608 | dec ecx |
608 | dec ecx |
609 | jz .Error |
609 | jz .Error |
610 | 610 | ||
611 | jmp @@SendCommand |
611 | jmp @@SendCommand |
612 | ;-------------------------------------- |
612 | ;-------------------------------------- |
613 | align 4 |
613 | align 4 |
614 | @@: |
614 | @@: |
615 | call change_task |
615 | call change_task |
616 | ; Проверить код ошибки |
616 | ; Проверить код ошибки |
617 | cmp [DevErrorCode], 0 |
617 | cmp [DevErrorCode], 0 |
618 | je @@End_11 |
618 | je @@End_11 |
619 | ; Проверить время ожидания готовности |
619 | ; Проверить время ожидания готовности |
620 | mov eax, [timer_ticks] |
620 | mov eax, [timer_ticks] |
621 | sub eax, [WURStartTime] |
621 | sub eax, [WURStartTime] |
622 | cmp eax, MaxCDWaitTime |
622 | cmp eax, MaxCDWaitTime |
623 | jb @@SendCommand |
623 | jb @@SendCommand |
624 | ;-------------------------------------- |
624 | ;-------------------------------------- |
625 | .Error: |
625 | .Error: |
626 | ; Ошибка тайм-аута |
626 | ; Ошибка тайм-аута |
627 | mov [DevErrorCode], 1 |
627 | mov [DevErrorCode], 1 |
628 | ;-------------------------------------- |
628 | ;-------------------------------------- |
629 | @@End_11: |
629 | @@End_11: |
630 | popa |
630 | popa |
631 | ret |
631 | ret |
632 | ;----------------------------------------------------------------------------- |
632 | ;----------------------------------------------------------------------------- |
633 | ;************************************************* |
633 | ;************************************************* |
634 | ;* ЗАПРЕТИТЬ СМЕНУ ДИСКА * |
634 | ;* ЗАПРЕТИТЬ СМЕНУ ДИСКА * |
635 | ;* Входные параметры передаются через глобальные * |
635 | ;* Входные параметры передаются через глобальные * |
636 | ;* перменные: * |
636 | ;* перменные: * |
637 | ;* ChannelNumber - номер канала; * |
637 | ;* ChannelNumber - номер канала; * |
638 | ;* DiskNumber - номер диска на канале. * |
638 | ;* DiskNumber - номер диска на канале. * |
639 | ;************************************************* |
639 | ;************************************************* |
640 | prevent_medium_removal: |
640 | prevent_medium_removal: |
641 | pusha |
641 | pusha |
642 | ; Очистить буфер пакетной команды |
642 | ; Очистить буфер пакетной команды |
643 | call clear_packet_buffer |
643 | call clear_packet_buffer |
644 | ; Задать код команды |
644 | ; Задать код команды |
645 | mov [PacketCommand], byte 0x1E |
645 | mov [PacketCommand], byte 0x1E |
646 | ; Задать код запрета |
646 | ; Задать код запрета |
647 | mov [PacketCommand+4], byte 11b |
647 | mov [PacketCommand+4], byte 11b |
648 | ; Подать команду |
648 | ; Подать команду |
649 | call SendPacketNoDatCommand |
649 | call SendPacketNoDatCommand |
650 | mov eax, ATAPI_IDE0_lock |
650 | mov eax, ATAPI_IDE0_lock |
651 | add eax, [cdpos] |
651 | add eax, [cdpos] |
652 | dec eax |
652 | dec eax |
653 | mov [eax], byte 1 |
653 | mov [eax], byte 1 |
654 | popa |
654 | popa |
655 | ret |
655 | ret |
656 | ;----------------------------------------------------------------------------- |
656 | ;----------------------------------------------------------------------------- |
657 | ;************************************************* |
657 | ;************************************************* |
658 | ;* РАЗРЕШИТЬ СМЕНУ ДИСКА * |
658 | ;* РАЗРЕШИТЬ СМЕНУ ДИСКА * |
659 | ;* Входные параметры передаются через глобальные * |
659 | ;* Входные параметры передаются через глобальные * |
660 | ;* перменные: * |
660 | ;* перменные: * |
661 | ;* ChannelNumber - номер канала; * |
661 | ;* ChannelNumber - номер канала; * |
662 | ;* DiskNumber - номер диска на канале. * |
662 | ;* DiskNumber - номер диска на канале. * |
663 | ;************************************************* |
663 | ;************************************************* |
664 | allow_medium_removal: |
664 | allow_medium_removal: |
665 | pusha |
665 | pusha |
666 | ; Очистить буфер пакетной команды |
666 | ; Очистить буфер пакетной команды |
667 | call clear_packet_buffer |
667 | call clear_packet_buffer |
668 | ; Задать код команды |
668 | ; Задать код команды |
669 | mov [PacketCommand], byte 0x1E |
669 | mov [PacketCommand], byte 0x1E |
670 | ; Задать код запрета |
670 | ; Задать код запрета |
671 | mov [PacketCommand+4], byte 0 |
671 | mov [PacketCommand+4], byte 0 |
672 | ; Подать команду |
672 | ; Подать команду |
673 | call SendPacketNoDatCommand |
673 | call SendPacketNoDatCommand |
674 | mov eax, ATAPI_IDE0_lock |
674 | mov eax, ATAPI_IDE0_lock |
675 | add eax, [cdpos] |
675 | add eax, [cdpos] |
676 | dec eax |
676 | dec eax |
677 | mov [eax], byte 0 |
677 | mov [eax], byte 0 |
678 | popa |
678 | popa |
679 | ret |
679 | ret |
680 | ;----------------------------------------------------------------------------- |
680 | ;----------------------------------------------------------------------------- |
681 | ;************************************************* |
681 | ;************************************************* |
682 | ;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД * |
682 | ;* ЗАГРУЗИТЬ НОСИТЕЛЬ В ДИСКОВОД * |
683 | ;* Входные параметры передаются через глобальные * |
683 | ;* Входные параметры передаются через глобальные * |
684 | ;* перменные: * |
684 | ;* перменные: * |
685 | ;* ChannelNumber - номер канала; * |
685 | ;* ChannelNumber - номер канала; * |
686 | ;* DiskNumber - номер диска на канале. * |
686 | ;* DiskNumber - номер диска на канале. * |
687 | ;************************************************* |
687 | ;************************************************* |
688 | LoadMedium: |
688 | LoadMedium: |
689 | pusha |
689 | pusha |
690 | ; Очистить буфер пакетной команды |
690 | ; Очистить буфер пакетной команды |
691 | call clear_packet_buffer |
691 | call clear_packet_buffer |
692 | ; Сформировать команду START/STOP UNIT |
692 | ; Сформировать команду START/STOP UNIT |
693 | ; Задать код команды |
693 | ; Задать код команды |
694 | mov [PacketCommand], word 0x1B |
694 | mov [PacketCommand], word 0x1B |
695 | ; Задать операцию загрузки носителя |
695 | ; Задать операцию загрузки носителя |
696 | mov [PacketCommand+4], word 00000011b |
696 | mov [PacketCommand+4], word 00000011b |
697 | ; Подать команду |
697 | ; Подать команду |
698 | call SendPacketNoDatCommand |
698 | call SendPacketNoDatCommand |
699 | popa |
699 | popa |
700 | ret |
700 | ret |
701 | ;----------------------------------------------------------------------------- |
701 | ;----------------------------------------------------------------------------- |
702 | ;************************************************* |
702 | ;************************************************* |
703 | ;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА * |
703 | ;* ИЗВЛЕЧЬ НОСИТЕЛЬ ИЗ ДИСКОВОДА * |
704 | ;* Входные параметры передаются через глобальные * |
704 | ;* Входные параметры передаются через глобальные * |
705 | ;* перменные: * |
705 | ;* перменные: * |
706 | ;* ChannelNumber - номер канала; * |
706 | ;* ChannelNumber - номер канала; * |
707 | ;* DiskNumber - номер диска на канале. * |
707 | ;* DiskNumber - номер диска на канале. * |
708 | ;************************************************* |
708 | ;************************************************* |
709 | EjectMedium: |
709 | EjectMedium: |
710 | pusha |
710 | pusha |
711 | ; Очистить буфер пакетной команды |
711 | ; Очистить буфер пакетной команды |
712 | call clear_packet_buffer |
712 | call clear_packet_buffer |
713 | ; Сформировать команду START/STOP UNIT |
713 | ; Сформировать команду START/STOP UNIT |
714 | ; Задать код команды |
714 | ; Задать код команды |
715 | mov [PacketCommand], word 0x1B |
715 | mov [PacketCommand], word 0x1B |
716 | ; Задать операцию извлечения носителя |
716 | ; Задать операцию извлечения носителя |
717 | mov [PacketCommand+4], word 00000010b |
717 | mov [PacketCommand+4], word 00000010b |
718 | ; Подать команду |
718 | ; Подать команду |
719 | call SendPacketNoDatCommand |
719 | call SendPacketNoDatCommand |
720 | popa |
720 | popa |
721 | ret |
721 | ret |
722 | ;----------------------------------------------------------------------------- |
722 | ;----------------------------------------------------------------------------- |
723 | ;************************************************* |
723 | ;************************************************* |
724 | ;* Проверить событие нажатия кнопки извлечения * |
724 | ;* Проверить событие нажатия кнопки извлечения * |
725 | ;* диска * |
725 | ;* диска * |
726 | ;* Входные параметры передаются через глобальные * |
726 | ;* Входные параметры передаются через глобальные * |
727 | ;* переменные: * |
727 | ;* переменные: * |
728 | ;* ChannelNumber - номер канала; * |
728 | ;* ChannelNumber - номер канала; * |
729 | ;* DiskNumber - номер диска на канале. * |
729 | ;* DiskNumber - номер диска на канале. * |
730 | ;************************************************* |
730 | ;************************************************* |
731 | proc check_ATAPI_device_event_has_work? |
731 | proc check_ATAPI_device_event_has_work? |
732 | mov eax, [timer_ticks] |
732 | mov eax, [timer_ticks] |
733 | sub eax, [timer_ATAPI_check] |
733 | sub eax, [timer_ATAPI_check] |
734 | cmp eax, 100 |
734 | cmp eax, 100 |
735 | jb .no |
735 | jb .no |
736 | 736 | ||
737 | xor eax, eax |
737 | xor eax, eax |
738 | inc eax |
738 | inc eax |
739 | ret |
739 | ret |
740 | ;-------------------------------------- |
740 | ;-------------------------------------- |
741 | .no: |
741 | .no: |
742 | xor eax, eax |
742 | xor eax, eax |
743 | ret |
743 | ret |
744 | endp |
744 | endp |
745 | ;----------------------------------------------------------------------------- |
745 | ;----------------------------------------------------------------------------- |
746 | align 4 |
746 | align 4 |
747 | check_ATAPI_device_event: |
747 | check_ATAPI_device_event: |
748 | pusha |
748 | pusha |
749 | mov eax, [timer_ticks] |
749 | mov eax, [timer_ticks] |
750 | sub eax, [timer_ATAPI_check] |
750 | sub eax, [timer_ATAPI_check] |
751 | cmp eax, 100 |
751 | cmp eax, 100 |
752 | jb .end_1 |
752 | jb .end_1 |
753 | 753 | ||
754 | pushfd |
754 | pushfd |
755 | mov al, [DRIVE_DATA+1] |
755 | mov al, [DRIVE_DATA+1] |
756 | and al, 11b |
756 | and al, 11b |
757 | cmp al, 10b |
757 | cmp al, 10b |
758 | jz .ide3 |
758 | jz .ide3 |
759 | ;-------------------------------------- |
759 | ;-------------------------------------- |
760 | .ide2_1: |
760 | .ide2_1: |
761 | mov al, [DRIVE_DATA+1] |
761 | mov al, [DRIVE_DATA+1] |
762 | and al, 1100b |
762 | and al, 1100b |
763 | cmp al, 1000b |
763 | cmp al, 1000b |
764 | jz .ide2 |
764 | jz .ide2 |
765 | ;-------------------------------------- |
765 | ;-------------------------------------- |
766 | .ide1_1: |
766 | .ide1_1: |
767 | mov al, [DRIVE_DATA+1] |
767 | mov al, [DRIVE_DATA+1] |
768 | and al, 110000b |
768 | and al, 110000b |
769 | cmp al, 100000b |
769 | cmp al, 100000b |
770 | jz .ide1 |
770 | jz .ide1 |
771 | ;-------------------------------------- |
771 | ;-------------------------------------- |
772 | .ide0_1: |
772 | .ide0_1: |
773 | mov al, [DRIVE_DATA+1] |
773 | mov al, [DRIVE_DATA+1] |
774 | and al, 11000000b |
774 | and al, 11000000b |
775 | cmp al, 10000000b |
775 | cmp al, 10000000b |
776 | jz .ide0 |
776 | jz .ide0 |
777 | ;-------------------------------------- |
777 | ;-------------------------------------- |
778 | .ide7_1: |
778 | .ide7_1: |
779 | mov al, [DRIVE_DATA+6] |
779 | mov al, [DRIVE_DATA+6] |
780 | and al, 11b |
780 | and al, 11b |
781 | cmp al, 10b |
781 | cmp al, 10b |
782 | jz .ide7 |
782 | jz .ide7 |
783 | ;-------------------------------------- |
783 | ;-------------------------------------- |
784 | .ide6_1: |
784 | .ide6_1: |
785 | mov al, [DRIVE_DATA+6] |
785 | mov al, [DRIVE_DATA+6] |
786 | and al, 1100b |
786 | and al, 1100b |
787 | cmp al, 1000b |
787 | cmp al, 1000b |
788 | jz .ide6 |
788 | jz .ide6 |
789 | ;-------------------------------------- |
789 | ;-------------------------------------- |
790 | .ide5_1: |
790 | .ide5_1: |
791 | mov al, [DRIVE_DATA+6] |
791 | mov al, [DRIVE_DATA+6] |
792 | and al, 110000b |
792 | and al, 110000b |
793 | cmp al, 100000b |
793 | cmp al, 100000b |
794 | jz .ide5 |
794 | jz .ide5 |
795 | ;-------------------------------------- |
795 | ;-------------------------------------- |
796 | .ide4_1: |
796 | .ide4_1: |
797 | mov al, [DRIVE_DATA+6] |
797 | mov al, [DRIVE_DATA+6] |
798 | and al, 11000000b |
798 | and al, 11000000b |
799 | cmp al, 10000000b |
799 | cmp al, 10000000b |
800 | jz .ide4 |
800 | jz .ide4 |
801 | ;-------------------------------------- |
801 | ;-------------------------------------- |
802 | .ide11_1: |
802 | .ide11_1: |
803 | mov al, [DRIVE_DATA+11] |
803 | mov al, [DRIVE_DATA+11] |
804 | and al, 11b |
804 | and al, 11b |
805 | cmp al, 10b |
805 | cmp al, 10b |
806 | jz .ide11 |
806 | jz .ide11 |
807 | ;-------------------------------------- |
807 | ;-------------------------------------- |
808 | .ide10_1: |
808 | .ide10_1: |
809 | mov al, [DRIVE_DATA+11] |
809 | mov al, [DRIVE_DATA+11] |
810 | and al, 1100b |
810 | and al, 1100b |
811 | cmp al, 1000b |
811 | cmp al, 1000b |
812 | jz .ide10 |
812 | jz .ide10 |
813 | ;-------------------------------------- |
813 | ;-------------------------------------- |
814 | .ide9_1: |
814 | .ide9_1: |
815 | mov al, [DRIVE_DATA+11] |
815 | mov al, [DRIVE_DATA+11] |
816 | and al, 110000b |
816 | and al, 110000b |
817 | cmp al, 100000b |
817 | cmp al, 100000b |
818 | jz .ide9 |
818 | jz .ide9 |
819 | ;-------------------------------------- |
819 | ;-------------------------------------- |
820 | .ide8_1: |
820 | .ide8_1: |
821 | mov al, [DRIVE_DATA+11] |
821 | mov al, [DRIVE_DATA+11] |
822 | and al, 11000000b |
822 | and al, 11000000b |
823 | cmp al, 10000000b |
823 | cmp al, 10000000b |
824 | jz .ide8 |
824 | jz .ide8 |
825 | ;-------------------------------------- |
825 | ;-------------------------------------- |
826 | .end: |
826 | .end: |
827 | popfd |
827 | popfd |
828 | mov eax, [timer_ticks] |
828 | mov eax, [timer_ticks] |
829 | mov [timer_ATAPI_check], eax |
829 | mov [timer_ATAPI_check], eax |
830 | ;-------------------------------------- |
830 | ;-------------------------------------- |
831 | .end_1: |
831 | .end_1: |
832 | popa |
832 | popa |
833 | ret |
833 | ret |
834 | ;----------------------------------------------------------------------------- |
834 | ;----------------------------------------------------------------------------- |
835 | .ide3: |
835 | .ide3: |
836 | cli |
836 | cli |
837 | cmp [ATAPI_IDE3_lock], 1 |
837 | cmp [ATAPI_IDE3_lock], 1 |
838 | jne .ide2_1 |
838 | jne .ide2_1 |
839 | 839 | ||
840 | cmp [cd_status], 0 |
840 | cmp [cd_status], 0 |
841 | jne .end |
841 | jne .end |
842 | 842 | ||
843 | mov ecx, ide_channel2_mutex |
843 | mov ecx, ide_channel2_mutex |
844 | call mutex_lock |
844 | call mutex_lock |
845 | call reserve_ok2 |
845 | call reserve_ok2 |
846 | mov [ChannelNumber], 2 |
846 | mov [ChannelNumber], 2 |
847 | mov [DiskNumber], 1 |
847 | mov [DiskNumber], 1 |
848 | mov [cdpos], 4 |
848 | mov [cdpos], 4 |
849 | call GetEvent_StatusNotification |
849 | call GetEvent_StatusNotification |
850 | cmp [CDDataBuf+4], byte 1 |
850 | cmp [CDDataBuf+4], byte 1 |
851 | jne @f |
851 | jne @f |
852 | 852 | ||
853 | call .eject |
853 | call .eject |
854 | ;-------------------------------------- |
854 | ;-------------------------------------- |
855 | @@: |
855 | @@: |
856 | call syscall_cdaudio.free |
856 | call syscall_cdaudio.free |
857 | jmp .ide2_1 |
857 | jmp .ide2_1 |
858 | ;----------------------------------------------------------------------------- |
858 | ;----------------------------------------------------------------------------- |
859 | .ide2: |
859 | .ide2: |
860 | cli |
860 | cli |
861 | cmp [ATAPI_IDE2_lock], 1 |
861 | cmp [ATAPI_IDE2_lock], 1 |
862 | jne .ide1_1 |
862 | jne .ide1_1 |
863 | 863 | ||
864 | cmp [cd_status], 0 |
864 | cmp [cd_status], 0 |
865 | jne .end |
865 | jne .end |
866 | 866 | ||
867 | mov ecx, ide_channel2_mutex |
867 | mov ecx, ide_channel2_mutex |
868 | call mutex_lock |
868 | call mutex_lock |
869 | call reserve_ok2 |
869 | call reserve_ok2 |
870 | mov [ChannelNumber], 2 |
870 | mov [ChannelNumber], 2 |
871 | mov [DiskNumber], 0 |
871 | mov [DiskNumber], 0 |
872 | mov [cdpos], 3 |
872 | mov [cdpos], 3 |
873 | call GetEvent_StatusNotification |
873 | call GetEvent_StatusNotification |
874 | cmp [CDDataBuf+4], byte 1 |
874 | cmp [CDDataBuf+4], byte 1 |
875 | jne @f |
875 | jne @f |
876 | 876 | ||
877 | call .eject |
877 | call .eject |
878 | ;-------------------------------------- |
878 | ;-------------------------------------- |
879 | @@: |
879 | @@: |
880 | call syscall_cdaudio.free |
880 | call syscall_cdaudio.free |
881 | jmp .ide1_1 |
881 | jmp .ide1_1 |
882 | ;----------------------------------------------------------------------------- |
882 | ;----------------------------------------------------------------------------- |
883 | .ide1: |
883 | .ide1: |
884 | cli |
884 | cli |
885 | cmp [ATAPI_IDE1_lock], 1 |
885 | cmp [ATAPI_IDE1_lock], 1 |
886 | jne .ide0_1 |
886 | jne .ide0_1 |
887 | 887 | ||
888 | cmp [cd_status], 0 |
888 | cmp [cd_status], 0 |
889 | jne .end |
889 | jne .end |
890 | 890 | ||
891 | mov ecx, ide_channel1_mutex |
891 | mov ecx, ide_channel1_mutex |
892 | call mutex_lock |
892 | call mutex_lock |
893 | call reserve_ok2 |
893 | call reserve_ok2 |
894 | mov [ChannelNumber], 1 |
894 | mov [ChannelNumber], 1 |
895 | mov [DiskNumber], 1 |
895 | mov [DiskNumber], 1 |
896 | mov [cdpos], 2 |
896 | mov [cdpos], 2 |
897 | call GetEvent_StatusNotification |
897 | call GetEvent_StatusNotification |
898 | cmp [CDDataBuf+4], byte 1 |
898 | cmp [CDDataBuf+4], byte 1 |
899 | jne @f |
899 | jne @f |
900 | 900 | ||
901 | call .eject |
901 | call .eject |
902 | ;-------------------------------------- |
902 | ;-------------------------------------- |
903 | @@: |
903 | @@: |
904 | call syscall_cdaudio.free |
904 | call syscall_cdaudio.free |
905 | jmp .ide0_1 |
905 | jmp .ide0_1 |
906 | ;----------------------------------------------------------------------------- |
906 | ;----------------------------------------------------------------------------- |
907 | .ide0: |
907 | .ide0: |
908 | cli |
908 | cli |
909 | cmp [ATAPI_IDE0_lock], 1 |
909 | cmp [ATAPI_IDE0_lock], 1 |
910 | jne .ide7_1 |
910 | jne .ide7_1 |
911 | 911 | ||
912 | cmp [cd_status], 0 |
912 | cmp [cd_status], 0 |
913 | jne .end |
913 | jne .end |
914 | 914 | ||
915 | mov ecx, ide_channel1_mutex |
915 | mov ecx, ide_channel1_mutex |
916 | call mutex_lock |
916 | call mutex_lock |
917 | call reserve_ok2 |
917 | call reserve_ok2 |
918 | mov [ChannelNumber], 1 |
918 | mov [ChannelNumber], 1 |
919 | mov [DiskNumber], 0 |
919 | mov [DiskNumber], 0 |
920 | mov [cdpos], 1 |
920 | mov [cdpos], 1 |
921 | call GetEvent_StatusNotification |
921 | call GetEvent_StatusNotification |
922 | cmp [CDDataBuf+4], byte 1 |
922 | cmp [CDDataBuf+4], byte 1 |
923 | jne @f |
923 | jne @f |
924 | 924 | ||
925 | call .eject |
925 | call .eject |
926 | ;-------------------------------------- |
926 | ;-------------------------------------- |
927 | @@: |
927 | @@: |
928 | call syscall_cdaudio.free |
928 | call syscall_cdaudio.free |
929 | jmp .ide7_1 |
929 | jmp .ide7_1 |
930 | ;----------------------------------------------------------------------------- |
930 | ;----------------------------------------------------------------------------- |
931 | .ide7: |
931 | .ide7: |
932 | cli |
932 | cli |
933 | cmp [ATAPI_IDE7_lock], 1 |
933 | cmp [ATAPI_IDE7_lock], 1 |
934 | jne .ide6_1 |
934 | jne .ide6_1 |
935 | 935 | ||
936 | cmp [cd_status], 0 |
936 | cmp [cd_status], 0 |
937 | jne .end |
937 | jne .end |
938 | 938 | ||
939 | mov ecx, ide_channel4_mutex |
939 | mov ecx, ide_channel4_mutex |
940 | call mutex_lock |
940 | call mutex_lock |
941 | call reserve_ok2 |
941 | call reserve_ok2 |
942 | mov [ChannelNumber], 2 |
942 | mov [ChannelNumber], 2 |
943 | mov [DiskNumber], 1 |
943 | mov [DiskNumber], 1 |
944 | mov [cdpos], 8 |
944 | mov [cdpos], 8 |
945 | call GetEvent_StatusNotification |
945 | call GetEvent_StatusNotification |
946 | cmp [CDDataBuf+4], byte 1 |
946 | cmp [CDDataBuf+4], byte 1 |
947 | jne @f |
947 | jne @f |
948 | 948 | ||
949 | call .eject |
949 | call .eject |
950 | ;-------------------------------------- |
950 | ;-------------------------------------- |
951 | @@: |
951 | @@: |
952 | call syscall_cdaudio.free |
952 | call syscall_cdaudio.free |
953 | jmp .ide6_1 |
953 | jmp .ide6_1 |
954 | ;----------------------------------------------------------------------------- |
954 | ;----------------------------------------------------------------------------- |
955 | .ide6: |
955 | .ide6: |
956 | cli |
956 | cli |
957 | cmp [ATAPI_IDE6_lock], 1 |
957 | cmp [ATAPI_IDE6_lock], 1 |
958 | jne .ide5_1 |
958 | jne .ide5_1 |
959 | 959 | ||
960 | cmp [cd_status], 0 |
960 | cmp [cd_status], 0 |
961 | jne .end |
961 | jne .end |
962 | 962 | ||
963 | mov ecx, ide_channel4_mutex |
963 | mov ecx, ide_channel4_mutex |
964 | call mutex_lock |
964 | call mutex_lock |
965 | call reserve_ok2 |
965 | call reserve_ok2 |
966 | mov [ChannelNumber], 2 |
966 | mov [ChannelNumber], 2 |
967 | mov [DiskNumber], 0 |
967 | mov [DiskNumber], 0 |
968 | mov [cdpos], 7 |
968 | mov [cdpos], 7 |
969 | call GetEvent_StatusNotification |
969 | call GetEvent_StatusNotification |
970 | cmp [CDDataBuf+4], byte 1 |
970 | cmp [CDDataBuf+4], byte 1 |
971 | jne @f |
971 | jne @f |
972 | 972 | ||
973 | call .eject |
973 | call .eject |
974 | ;-------------------------------------- |
974 | ;-------------------------------------- |
975 | @@: |
975 | @@: |
976 | call syscall_cdaudio.free |
976 | call syscall_cdaudio.free |
977 | jmp .ide5_1 |
977 | jmp .ide5_1 |
978 | ;----------------------------------------------------------------------------- |
978 | ;----------------------------------------------------------------------------- |
979 | .ide5: |
979 | .ide5: |
980 | cli |
980 | cli |
981 | cmp [ATAPI_IDE5_lock], 1 |
981 | cmp [ATAPI_IDE5_lock], 1 |
982 | jne .ide4_1 |
982 | jne .ide4_1 |
983 | 983 | ||
984 | cmp [cd_status], 0 |
984 | cmp [cd_status], 0 |
985 | jne .end |
985 | jne .end |
986 | 986 | ||
987 | mov ecx, ide_channel3_mutex |
987 | mov ecx, ide_channel3_mutex |
988 | call mutex_lock |
988 | call mutex_lock |
989 | call reserve_ok2 |
989 | call reserve_ok2 |
990 | mov [ChannelNumber], 1 |
990 | mov [ChannelNumber], 1 |
991 | mov [DiskNumber], 1 |
991 | mov [DiskNumber], 1 |
992 | mov [cdpos], 6 |
992 | mov [cdpos], 6 |
993 | call GetEvent_StatusNotification |
993 | call GetEvent_StatusNotification |
994 | cmp [CDDataBuf+4], byte 1 |
994 | cmp [CDDataBuf+4], byte 1 |
995 | jne @f |
995 | jne @f |
996 | 996 | ||
997 | call .eject |
997 | call .eject |
998 | ;-------------------------------------- |
998 | ;-------------------------------------- |
999 | @@: |
999 | @@: |
1000 | call syscall_cdaudio.free |
1000 | call syscall_cdaudio.free |
1001 | jmp .ide4_1 |
1001 | jmp .ide4_1 |
1002 | ;----------------------------------------------------------------------------- |
1002 | ;----------------------------------------------------------------------------- |
1003 | .ide4: |
1003 | .ide4: |
1004 | cli |
1004 | cli |
1005 | cmp [ATAPI_IDE4_lock], 1 |
1005 | cmp [ATAPI_IDE4_lock], 1 |
1006 | jne .ide11_1 |
1006 | jne .ide11_1 |
1007 | 1007 | ||
1008 | cmp [cd_status], 0 |
1008 | cmp [cd_status], 0 |
1009 | jne .end |
1009 | jne .end |
1010 | 1010 | ||
1011 | mov ecx, ide_channel3_mutex |
1011 | mov ecx, ide_channel3_mutex |
1012 | call mutex_lock |
1012 | call mutex_lock |
1013 | call reserve_ok2 |
1013 | call reserve_ok2 |
1014 | mov [ChannelNumber], 1 |
1014 | mov [ChannelNumber], 1 |
1015 | mov [DiskNumber], 0 |
1015 | mov [DiskNumber], 0 |
1016 | mov [cdpos], 5 |
1016 | mov [cdpos], 5 |
1017 | call GetEvent_StatusNotification |
1017 | call GetEvent_StatusNotification |
1018 | cmp [CDDataBuf+4], byte 1 |
1018 | cmp [CDDataBuf+4], byte 1 |
1019 | jne @f |
1019 | jne @f |
1020 | 1020 | ||
1021 | call .eject |
1021 | call .eject |
1022 | ;-------------------------------------- |
1022 | ;-------------------------------------- |
1023 | @@: |
1023 | @@: |
1024 | call syscall_cdaudio.free |
1024 | call syscall_cdaudio.free |
1025 | jmp .ide11_1 |
1025 | jmp .ide11_1 |
1026 | ;----------------------------------------------------------------------------- |
1026 | ;----------------------------------------------------------------------------- |
1027 | .ide11: |
1027 | .ide11: |
1028 | cli |
1028 | cli |
1029 | cmp [ATAPI_IDE11_lock], 1 |
1029 | cmp [ATAPI_IDE11_lock], 1 |
1030 | jne .ide10_1 |
1030 | jne .ide10_1 |
1031 | 1031 | ||
1032 | cmp [cd_status], 0 |
1032 | cmp [cd_status], 0 |
1033 | jne .end |
1033 | jne .end |
1034 | 1034 | ||
1035 | mov ecx, ide_channel6_mutex |
1035 | mov ecx, ide_channel6_mutex |
1036 | call mutex_lock |
1036 | call mutex_lock |
1037 | call reserve_ok2 |
1037 | call reserve_ok2 |
1038 | mov [ChannelNumber], 2 |
1038 | mov [ChannelNumber], 2 |
1039 | mov [DiskNumber], 1 |
1039 | mov [DiskNumber], 1 |
1040 | mov [cdpos], 12 |
1040 | mov [cdpos], 12 |
1041 | call GetEvent_StatusNotification |
1041 | call GetEvent_StatusNotification |
1042 | cmp [CDDataBuf+4], byte 1 |
1042 | cmp [CDDataBuf+4], byte 1 |
1043 | jne @f |
1043 | jne @f |
1044 | 1044 | ||
1045 | call .eject |
1045 | call .eject |
1046 | ;-------------------------------------- |
1046 | ;-------------------------------------- |
1047 | @@: |
1047 | @@: |
1048 | call syscall_cdaudio.free |
1048 | call syscall_cdaudio.free |
1049 | jmp .ide10_1 |
1049 | jmp .ide10_1 |
1050 | ;----------------------------------------------------------------------------- |
1050 | ;----------------------------------------------------------------------------- |
1051 | .ide10: |
1051 | .ide10: |
1052 | cli |
1052 | cli |
1053 | cmp [ATAPI_IDE10_lock], 1 |
1053 | cmp [ATAPI_IDE10_lock], 1 |
1054 | jne .ide9_1 |
1054 | jne .ide9_1 |
1055 | 1055 | ||
1056 | cmp [cd_status], 0 |
1056 | cmp [cd_status], 0 |
1057 | jne .end |
1057 | jne .end |
1058 | 1058 | ||
1059 | mov ecx, ide_channel6_mutex |
1059 | mov ecx, ide_channel6_mutex |
1060 | call mutex_lock |
1060 | call mutex_lock |
1061 | call reserve_ok2 |
1061 | call reserve_ok2 |
1062 | mov [ChannelNumber], 2 |
1062 | mov [ChannelNumber], 2 |
1063 | mov [DiskNumber], 0 |
1063 | mov [DiskNumber], 0 |
1064 | mov [cdpos], 11 |
1064 | mov [cdpos], 11 |
1065 | call GetEvent_StatusNotification |
1065 | call GetEvent_StatusNotification |
1066 | cmp [CDDataBuf+4], byte 1 |
1066 | cmp [CDDataBuf+4], byte 1 |
1067 | jne @f |
1067 | jne @f |
1068 | 1068 | ||
1069 | call .eject |
1069 | call .eject |
1070 | ;-------------------------------------- |
1070 | ;-------------------------------------- |
1071 | @@: |
1071 | @@: |
1072 | call syscall_cdaudio.free |
1072 | call syscall_cdaudio.free |
1073 | jmp .ide9_1 |
1073 | jmp .ide9_1 |
1074 | ;----------------------------------------------------------------------------- |
1074 | ;----------------------------------------------------------------------------- |
1075 | .ide9: |
1075 | .ide9: |
1076 | cli |
1076 | cli |
1077 | cmp [ATAPI_IDE9_lock], 1 |
1077 | cmp [ATAPI_IDE9_lock], 1 |
1078 | jne .ide8_1 |
1078 | jne .ide8_1 |
1079 | 1079 | ||
1080 | cmp [cd_status], 0 |
1080 | cmp [cd_status], 0 |
1081 | jne .end |
1081 | jne .end |
1082 | 1082 | ||
1083 | mov ecx, ide_channel5_mutex |
1083 | mov ecx, ide_channel5_mutex |
1084 | call mutex_lock |
1084 | call mutex_lock |
1085 | call reserve_ok2 |
1085 | call reserve_ok2 |
1086 | mov [ChannelNumber], 1 |
1086 | mov [ChannelNumber], 1 |
1087 | mov [DiskNumber], 1 |
1087 | mov [DiskNumber], 1 |
1088 | mov [cdpos], 10 |
1088 | mov [cdpos], 10 |
1089 | call GetEvent_StatusNotification |
1089 | call GetEvent_StatusNotification |
1090 | cmp [CDDataBuf+4], byte 1 |
1090 | cmp [CDDataBuf+4], byte 1 |
1091 | jne @f |
1091 | jne @f |
1092 | 1092 | ||
1093 | call .eject |
1093 | call .eject |
1094 | ;-------------------------------------- |
1094 | ;-------------------------------------- |
1095 | @@: |
1095 | @@: |
1096 | call syscall_cdaudio.free |
1096 | call syscall_cdaudio.free |
1097 | jmp .ide8_1 |
1097 | jmp .ide8_1 |
1098 | ;----------------------------------------------------------------------------- |
1098 | ;----------------------------------------------------------------------------- |
1099 | .ide8: |
1099 | .ide8: |
1100 | cli |
1100 | cli |
1101 | cmp [ATAPI_IDE8_lock], 1 |
1101 | cmp [ATAPI_IDE8_lock], 1 |
1102 | jne .end |
1102 | jne .end |
1103 | 1103 | ||
1104 | cmp [cd_status], 0 |
1104 | cmp [cd_status], 0 |
1105 | jne .end |
1105 | jne .end |
1106 | 1106 | ||
1107 | mov ecx, ide_channel5_mutex |
1107 | mov ecx, ide_channel5_mutex |
1108 | call mutex_lock |
1108 | call mutex_lock |
1109 | call reserve_ok2 |
1109 | call reserve_ok2 |
1110 | mov [ChannelNumber], 1 |
1110 | mov [ChannelNumber], 1 |
1111 | mov [DiskNumber], 0 |
1111 | mov [DiskNumber], 0 |
1112 | mov [cdpos], 9 |
1112 | mov [cdpos], 9 |
1113 | call GetEvent_StatusNotification |
1113 | call GetEvent_StatusNotification |
1114 | cmp [CDDataBuf+4], byte 1 |
1114 | cmp [CDDataBuf+4], byte 1 |
1115 | jne @f |
1115 | jne @f |
1116 | 1116 | ||
1117 | call .eject |
1117 | call .eject |
1118 | ;-------------------------------------- |
1118 | ;-------------------------------------- |
1119 | @@: |
1119 | @@: |
1120 | call syscall_cdaudio.free |
1120 | call syscall_cdaudio.free |
1121 | jmp .end |
1121 | jmp .end |
1122 | ;----------------------------------------------------------------------------- |
1122 | ;----------------------------------------------------------------------------- |
1123 | .eject: |
1123 | .eject: |
1124 | call clear_CD_cache |
1124 | call clear_CD_cache |
1125 | call allow_medium_removal |
1125 | call allow_medium_removal |
1126 | mov [ignore_CD_eject_wait], 1 |
1126 | mov [ignore_CD_eject_wait], 1 |
1127 | call EjectMedium |
1127 | call EjectMedium |
1128 | mov [ignore_CD_eject_wait], 0 |
1128 | mov [ignore_CD_eject_wait], 0 |
1129 | ret |
1129 | ret |
1130 | ;----------------------------------------------------------------------------- |
1130 | ;----------------------------------------------------------------------------- |
1131 | iglobal |
1131 | iglobal |
1132 | timer_ATAPI_check dd 0 |
1132 | timer_ATAPI_check dd 0 |
1133 | ATAPI_IDE0_lock db 0 |
1133 | ATAPI_IDE0_lock db 0 |
1134 | ATAPI_IDE1_lock db 0 |
1134 | ATAPI_IDE1_lock db 0 |
1135 | ATAPI_IDE2_lock db 0 |
1135 | ATAPI_IDE2_lock db 0 |
1136 | ATAPI_IDE3_lock db 0 |
1136 | ATAPI_IDE3_lock db 0 |
1137 | ATAPI_IDE4_lock db 0 |
1137 | ATAPI_IDE4_lock db 0 |
1138 | ATAPI_IDE5_lock db 0 |
1138 | ATAPI_IDE5_lock db 0 |
1139 | ATAPI_IDE6_lock db 0 |
1139 | ATAPI_IDE6_lock db 0 |
1140 | ATAPI_IDE7_lock db 0 |
1140 | ATAPI_IDE7_lock db 0 |
1141 | ATAPI_IDE8_lock db 0 |
1141 | ATAPI_IDE8_lock db 0 |
1142 | ATAPI_IDE9_lock db 0 |
1142 | ATAPI_IDE9_lock db 0 |
1143 | ATAPI_IDE10_lock db 0 |
1143 | ATAPI_IDE10_lock db 0 |
1144 | ATAPI_IDE11_lock db 0 |
1144 | ATAPI_IDE11_lock db 0 |
1145 | ignore_CD_eject_wait db 0 |
1145 | ignore_CD_eject_wait db 0 |
1146 | endg |
1146 | endg |
1147 | ;----------------------------------------------------------------------------- |
1147 | ;----------------------------------------------------------------------------- |
1148 | ;************************************************* |
1148 | ;************************************************* |
1149 | ;* Получить сообщение о событии или состоянии * |
1149 | ;* Получить сообщение о событии или состоянии * |
1150 | ;* устройства * |
1150 | ;* устройства * |
1151 | ;* Входные параметры передаются через глобальные * |
1151 | ;* Входные параметры передаются через глобальные * |
1152 | ;* переменные: * |
1152 | ;* переменные: * |
1153 | ;* ChannelNumber - номер канала; * |
1153 | ;* ChannelNumber - номер канала; * |
1154 | ;* DiskNumber - номер диска на канале. * |
1154 | ;* DiskNumber - номер диска на канале. * |
1155 | ;************************************************* |
1155 | ;************************************************* |
1156 | GetEvent_StatusNotification: |
1156 | GetEvent_StatusNotification: |
1157 | pusha |
1157 | pusha |
1158 | mov [CDDataBuf_pointer], CDDataBuf |
1158 | mov [CDDataBuf_pointer], CDDataBuf |
1159 | ; Очистить буфер пакетной команды |
1159 | ; Очистить буфер пакетной команды |
1160 | call clear_packet_buffer |
1160 | call clear_packet_buffer |
1161 | ; Задать код команды |
1161 | ; Задать код команды |
1162 | mov [PacketCommand], byte 4Ah |
1162 | mov [PacketCommand], byte 4Ah |
1163 | mov [PacketCommand+1], byte 00000001b |
1163 | mov [PacketCommand+1], byte 00000001b |
1164 | ; Задать запрос класса сообщений |
1164 | ; Задать запрос класса сообщений |
1165 | mov [PacketCommand+4], byte 00010000b |
1165 | mov [PacketCommand+4], byte 00010000b |
1166 | ; Размер выделенной области |
1166 | ; Размер выделенной области |
1167 | mov [PacketCommand+7], byte 8h |
1167 | mov [PacketCommand+7], byte 8h |
1168 | mov [PacketCommand+8], byte 0h |
1168 | mov [PacketCommand+8], byte 0h |
1169 | ; Подать команду |
1169 | ; Подать команду |
1170 | call SendPacketDatCommand |
1170 | call SendPacketDatCommand |
1171 | popa |
1171 | popa |
1172 | ret |
1172 | ret |
1173 | ;----------------------------------------------------------------------------- |
1173 | ;----------------------------------------------------------------------------- |
1174 | ;************************************************* |
1174 | ;************************************************* |
1175 | ; прочитать информацию из TOC |
1175 | ; прочитать информацию из TOC |
1176 | ;* Входные параметры передаются через глобальные * |
1176 | ;* Входные параметры передаются через глобальные * |
1177 | ;* переменные: * |
1177 | ;* переменные: * |
1178 | ;* ChannelNumber - номер канала; * |
1178 | ;* ChannelNumber - номер канала; * |
1179 | ;* DiskNumber - номер диска на канале. * |
1179 | ;* DiskNumber - номер диска на канале. * |
1180 | ;************************************************* |
1180 | ;************************************************* |
1181 | Read_TOC: |
1181 | Read_TOC: |
1182 | pusha |
1182 | pusha |
1183 | mov [CDDataBuf_pointer], CDDataBuf |
1183 | mov [CDDataBuf_pointer], CDDataBuf |
1184 | ; Очистить буфер пакетной команды |
1184 | ; Очистить буфер пакетной команды |
1185 | call clear_packet_buffer |
1185 | call clear_packet_buffer |
1186 | ; Сформировать пакетную команду для считывания |
1186 | ; Сформировать пакетную команду для считывания |
1187 | ; сектора данных |
1187 | ; сектора данных |
1188 | mov [PacketCommand], byte 0x43 |
1188 | mov [PacketCommand], byte 0x43 |
1189 | ; Задать формат |
1189 | ; Задать формат |
1190 | mov [PacketCommand+2], byte 1 |
1190 | mov [PacketCommand+2], byte 1 |
1191 | ; Размер выделенной области |
1191 | ; Размер выделенной области |
1192 | mov [PacketCommand+7], byte 0xFF |
1192 | mov [PacketCommand+7], byte 0xFF |
1193 | mov [PacketCommand+8], byte 0h |
1193 | mov [PacketCommand+8], byte 0h |
1194 | ; Подать команду |
1194 | ; Подать команду |
1195 | call SendPacketDatCommand |
1195 | call SendPacketDatCommand |
1196 | popa |
1196 | popa |
1197 | ret |
1197 | ret |
1198 | ;----------------------------------------------------------------------------- |
1198 | ;----------------------------------------------------------------------------- |
1199 | ;************************************************* |
1199 | ;************************************************* |
1200 | ;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ * |
1200 | ;* ОПРЕДЕЛИТЬ ОБЩЕЕ КОЛИЧЕСТВО СЕКТОРОВ НА ДИСКЕ * |
1201 | ;* Входные параметры передаются через глобальные * |
1201 | ;* Входные параметры передаются через глобальные * |
1202 | ;* переменные: * |
1202 | ;* переменные: * |
1203 | ;* ChannelNumber - номер канала; * |
1203 | ;* ChannelNumber - номер канала; * |
1204 | ;* DiskNumber - номер диска на канале. * |
1204 | ;* DiskNumber - номер диска на канале. * |
1205 | ;************************************************* |
1205 | ;************************************************* |
1206 | ;ReadCapacity: |
1206 | ;ReadCapacity: |
1207 | ; pusha |
1207 | ; pusha |
1208 | ;; Очистить буфер пакетной команды |
1208 | ;; Очистить буфер пакетной команды |
1209 | ; call clear_packet_buffer |
1209 | ; call clear_packet_buffer |
1210 | ;; Задать размер буфера в байтах |
1210 | ;; Задать размер буфера в байтах |
1211 | ; mov [CDBlockSize],8 |
1211 | ; mov [CDBlockSize],8 |
1212 | ;; Сформировать команду READ CAPACITY |
1212 | ;; Сформировать команду READ CAPACITY |
1213 | ; mov [PacketCommand],word 25h |
1213 | ; mov [PacketCommand],word 25h |
1214 | ;; Подать команду |
1214 | ;; Подать команду |
1215 | ; call SendPacketDatCommand |
1215 | ; call SendPacketDatCommand |
1216 | ; popa |
1216 | ; popa |
1217 | ; ret |
1217 | ; ret |
1218 | ;----------------------------------------------------------------------------- |
1218 | ;----------------------------------------------------------------------------- |
1219 | clear_packet_buffer: |
1219 | clear_packet_buffer: |
1220 | ; Очистить буфер пакетной команды |
1220 | ; Очистить буфер пакетной команды |
1221 | and [PacketCommand], dword 0 |
1221 | and [PacketCommand], dword 0 |
1222 | and [PacketCommand+4], dword 0 |
1222 | and [PacketCommand+4], dword 0 |
1223 | and [PacketCommand+8], dword 0 |
1223 | and [PacketCommand+8], dword 0 |
1224 | ret |
1224 | ret |
1225 | ;----------------------------------------------------------------------------- |
1225 | ;----------------------------------------------------------------------------- |