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