Rev 7136 | Rev 8055 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7136 | Rev 8054 | ||
---|---|---|---|
Line 3... | Line 3... | ||
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 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 7... | Line 7... | ||
7 | 7 | ||
Line 8... | Line 8... | ||
8 | $Revision: 7136 $ |
8 | $Revision: 8054 $ |
9 | 9 | ||
10 | 10 | ||
11 | ;********************************************************** |
11 | ;********************************************************** |
12 | ; Непосредственная работа с контроллером гибкого диска |
12 | ; Direct work with floppy disk drive |
Line 13... | Line 13... | ||
13 | ;********************************************************** |
13 | ;********************************************************** |
14 | ; Автор исходного текста Кулаков Владимир Геннадьевич. |
14 | ; Source code author Kulakov Vladimir Gennadievich. |
15 | ; Адаптация и доработка Mario79 |
15 | ; Adaptation and improvement Mario79 |
16 | 16 | ||
17 | ;give_back_application_data: ; переслать приложению |
17 | ;give_back_application_data: ; give back to application |
18 | ; mov edi,[TASK_BASE] |
18 | ; mov edi,[TASK_BASE] |
19 | ; mov edi,[edi+TASKDATA.mem_start] |
19 | ; mov edi,[edi+TASKDATA.mem_start] |
20 | ; add edi,ecx |
20 | ; add edi,ecx |
21 | give_back_application_data_1: |
21 | give_back_application_data_1: |
22 | mov esi, FDD_BUFF;FDD_DataBuffer ;0x40000 |
22 | mov esi, FDD_BUFF;FDD_DataBuffer ;0x40000 |
Line 23... | Line 23... | ||
23 | mov ecx, 128 |
23 | mov ecx, 128 |
24 | cld |
24 | cld |
25 | rep movsd |
25 | rep movsd |
26 | ret |
26 | ret |
27 | 27 | ||
28 | ;take_data_from_application: ; взять из приложени |
28 | ;take_data_from_application: ; take from application |
29 | ; mov esi,[TASK_BASE] |
29 | ; mov esi,[TASK_BASE] |
30 | ; mov esi,[esi+TASKDATA.mem_start] |
30 | ; mov esi,[esi+TASKDATA.mem_start] |
31 | ; add esi,ecx |
31 | ; add esi,ecx |
32 | take_data_from_application_1: |
32 | take_data_from_application_1: |
Line 33... | Line 33... | ||
33 | mov edi, FDD_BUFF;FDD_DataBuffer ;0x40000 |
33 | mov edi, FDD_BUFF;FDD_DataBuffer ;0x40000 |
34 | mov ecx, 128 |
34 | mov ecx, 128 |
35 | cld |
35 | cld |
36 | rep movsd |
36 | rep movsd |
37 | ret |
37 | ret |
38 | 38 | ||
39 | ; Коды завершения операции с контроллером (FDC_Status) |
39 | ; Controller operations result codes (FDC_Status) |
40 | FDC_Normal = 0 ;нормальное завершение |
40 | FDC_Normal = 0 ; normal finish |
41 | FDC_TimeOut = 1 ;ошибка тайм-аута |
41 | FDC_TimeOut = 1 ; time out error |
42 | FDC_DiskNotFound = 2 ;в дисководе нет диска |
42 | FDC_DiskNotFound = 2 ; no disk in drive |
43 | FDC_TrackNotFound = 3 ;дорожка не найдена |
43 | FDC_TrackNotFound = 3 ; track not found |
44 | FDC_SectorNotFound = 4 ;сектор не найден |
44 | FDC_SectorNotFound = 4 ; sector not found |
45 | 45 | ||
Line 46... | Line 46... | ||
46 | ; Максимальные значения координат сектора (заданные |
46 | ; Maximum values of the sector coordinates (specified |
47 | ; значения соответствуют параметрам стандартного |
47 | ; values correspond to the parameters of the standard |
48 | ; трехдюймового гибкого диска объемом 1,44 Мб) |
48 | ; 3-inch 1.44 MB floppy disk) |
49 | MAX_Track = 79 |
49 | MAX_Track = 79 |
50 | MAX_Head = 1 |
50 | MAX_Head = 1 |
51 | MAX_Sector = 18 |
51 | MAX_Sector = 18 |
52 | 52 | ||
53 | uglobal |
53 | uglobal |
54 | ; Счетчик тиков таймера |
54 | ; Timer tick counter |
55 | TickCounter dd ? |
55 | TickCounter dd ? |
56 | ; Код завершения операции с контроллером НГМД |
56 | ; Operation completion code with the floppy disk drive controller |
57 | FDC_Status DB ? |
57 | FDC_Status DB ? |
58 | ; Флаг прерывания от НГМД |
58 | ; Interrupt flag from floppy disk drive |
59 | FDD_IntFlag DB ? |
59 | FDD_IntFlag DB ? |
60 | ; Момент начала последней операции с НГМД |
60 | ; The moment of the beginning of the last operation with FDD |
Line 61... | Line 61... | ||
61 | FDD_Time DD ? |
61 | FDD_Time DD ? |
62 | ; Номер дисковода |
62 | ; Drive number |
63 | FDD_Type db 0 |
63 | FDD_Type db 0 |
64 | ; Координаты сектора |
64 | ; Sector coordinates |
65 | FDD_Track DB ? |
65 | FDD_Track DB ? |
66 | FDD_Head DB ? |
66 | FDD_Head DB ? |
67 | FDD_Sector DB ? |
67 | FDD_Sector DB ? |
68 | 68 | ||
69 | ; Блок результата операции |
69 | ; Operation result block |
70 | FDC_ST0 DB ? |
70 | FDC_ST0 DB ? |
71 | FDC_ST1 DB ? |
71 | FDC_ST1 DB ? |
72 | FDC_ST2 DB ? |
72 | FDC_ST2 DB ? |
73 | FDC_C DB ? |
73 | FDC_C DB ? |
74 | FDC_H DB ? |
74 | FDC_H DB ? |
75 | FDC_R DB ? |
75 | FDC_R DB ? |
76 | FDC_N DB ? |
76 | FDC_N DB ? |
77 | ; Счетчик повторения операции чтени |
77 | ; Read operation repetition counter |
Line 78... | Line 78... | ||
78 | ReadRepCounter DB ? |
78 | ReadRepCounter DB ? |
79 | ; Счетчик повторения операции рекалибровки |
79 | ; Recalibration operation repetition counter |
80 | RecalRepCounter DB ? |
80 | RecalRepCounter DB ? |
81 | endg |
81 | endg |
82 | ; Область памяти для хранения прочитанного сектора |
82 | ; Memory area for storing the readed sector |
83 | ;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?) |
83 | ;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?) |
84 | fdd_motor_status db 0 |
84 | fdd_motor_status db 0 |
85 | timer_fdd_motor dd 0 |
85 | timer_fdd_motor dd 0 |
Line 113... | Line 113... | ||
113 | out 0xa, al |
113 | out 0xa, al |
114 | popad |
114 | popad |
115 | ret |
115 | ret |
Line 116... | Line 116... | ||
116 | 116 | ||
117 | ;*********************************** |
117 | ;*********************************** |
118 | ;* ЗАПИСАТЬ БАЙТ В ПОРТ ДАННЫХ FDC * |
118 | ;* WRITE BYTE TO FDC DATA PORT * |
119 | ;* Параметры: * |
119 | ;* Parameters: * |
120 | ;* AL - выводимый байт. * |
120 | ;* AL - byte to write. * |
121 | ;*********************************** |
121 | ;*********************************** |
122 | FDCDataOutput: |
122 | FDCDataOutput: |
123 | ; DEBUGF 1,'K : FDCDataOutput(%x)',al |
123 | ; DEBUGF 1,'K : FDCDataOutput(%x)',al |
124 | ; pusha |
124 | ; pusha |
125 | push eax ecx edx |
125 | push eax ecx edx |
126 | mov AH, AL ;запомнить байт в AH |
126 | mov AH, AL ; remember byte to AH |
127 | ; Сбросить переменную состояния контроллера |
127 | ; Reset controller state variable |
128 | mov [FDC_Status], FDC_Normal |
128 | mov [FDC_Status], FDC_Normal |
129 | ; Проверить готовность контроллера к приему данных |
129 | ; Check the readiness of the controller to receive data |
130 | mov DX, 3F4h ;(порт состояния FDC) |
130 | mov DX, 3F4h ; (FDC state port) |
131 | mov ecx, 0x10000 ;установить счетчик тайм-аута |
131 | mov ecx, 0x10000 ; set timeout counter |
132 | @@TestRS: |
132 | @@TestRS: |
133 | in AL, DX ;прочитать регистр RS |
133 | in AL, DX ; read the RS register |
134 | and AL, 0C0h ;выделить разряды 6 и 7 |
134 | and AL, 0C0h ; get digits 6 and 7 |
135 | cmp AL, 80h ;проверить разряды 6 и 7 |
135 | cmp AL, 80h ; check digits 6 and 7 |
136 | je @@OutByteToFDC |
136 | je @@OutByteToFDC |
137 | loop @@TestRS |
137 | loop @@TestRS |
138 | ; Ошибка тайм-аута |
138 | ; Time out error |
139 | ; DEBUGF 1,' timeout\n' |
139 | ; DEBUGF 1,' timeout\n' |
140 | mov [FDC_Status], FDC_TimeOut |
140 | mov [FDC_Status], FDC_TimeOut |
141 | jmp @@End_5 |
141 | jmp @@End_5 |
142 | ; Вывести байт в порт данных |
142 | ; Write byte to data port |
143 | @@OutByteToFDC: |
143 | @@OutByteToFDC: |
144 | inc DX |
144 | inc DX |
145 | mov AL, AH |
145 | mov AL, AH |
146 | out DX, AL |
146 | out DX, AL |
Line 149... | Line 149... | ||
149 | ; popa |
149 | ; popa |
150 | pop edx ecx eax |
150 | pop edx ecx eax |
151 | ret |
151 | ret |
Line 152... | Line 152... | ||
152 | 152 | ||
153 | ;****************************************** |
153 | ;****************************************** |
154 | ;* ПРОЧИТАТЬ БАЙТ ИЗ ПОРТА ДАННЫХ FDC * |
154 | ;* READ BYTE FROM FDC DATA PORT * |
155 | ;* Процедура не имеет входных параметров. * |
155 | ;* Procedure doesnt have input params. * |
156 | ;* Выходные данные: * |
156 | ;* Output : * |
157 | ;* AL - считанный байт. * |
157 | ;* AL - byte read. * |
158 | ;****************************************** |
158 | ;****************************************** |
159 | FDCDataInput: |
159 | FDCDataInput: |
160 | push ECX |
160 | push ECX |
161 | push DX |
161 | push DX |
162 | ; Сбросить переменную состояния контроллера |
162 | ; Reset controller state variable |
163 | mov [FDC_Status], FDC_Normal |
163 | mov [FDC_Status], FDC_Normal |
164 | ; Проверить готовность контроллера к передаче данных |
164 | ; Check the readiness of the controller to receive data |
165 | mov DX, 3F4h ;(порт состояния FDC) |
165 | mov DX, 3F4h ;(FDC state port) |
166 | mov ecx, 0x10000 ;установить счетчик тайм-аута |
166 | mov ecx, 0x10000 ; set timeout counter |
167 | @@TestRS_1: |
167 | @@TestRS_1: |
168 | in AL, DX ;прочитать регистр RS |
168 | in AL, DX ; read the RS register |
169 | and AL, 0C0h ;выдлить разряды 6 и 7 |
169 | and AL, 0C0h ; get digits 6 and 7 |
170 | cmp AL, 0C0h ;проверить разряды 6 и 7 |
170 | cmp AL, 0C0h ; check digits 6 and 7 |
171 | je @@GetByteFromFDC |
171 | je @@GetByteFromFDC |
172 | loop @@TestRS_1 |
172 | loop @@TestRS_1 |
173 | ; Ошибка тайм-аута |
173 | ; Time out error |
174 | ; DEBUGF 1,'K : FDCDataInput: timeout\n' |
174 | ; DEBUGF 1,'K : FDCDataInput: timeout\n' |
175 | mov [FDC_Status], FDC_TimeOut |
175 | mov [FDC_Status], FDC_TimeOut |
176 | jmp @@End_6 |
176 | jmp @@End_6 |
177 | ; Ввести байт из порта данных |
177 | ; Get byte from data port |
178 | @@GetByteFromFDC: |
178 | @@GetByteFromFDC: |
179 | inc DX |
179 | inc DX |
180 | in AL, DX |
180 | in AL, DX |
181 | ; DEBUGF 1,'K : FDCDataInput: %x\n',al |
181 | ; DEBUGF 1,'K : FDCDataInput: %x\n',al |
182 | @@End_6: |
182 | @@End_6: |
183 | pop DX |
183 | pop DX |
184 | pop ECX |
184 | pop ECX |
Line 185... | Line 185... | ||
185 | ret |
185 | ret |
186 | 186 | ||
187 | ;********************************************* |
187 | ;********************************************* |
188 | ;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД * |
188 | ;* FDC INTERRUPT HANDLER * |
189 | ;********************************************* |
189 | ;********************************************* |
190 | FDCInterrupt: |
190 | FDCInterrupt: |
191 | ; dbgstr 'FDCInterrupt' |
191 | ; dbgstr 'FDCInterrupt' |
192 | ; Установить флаг прерывания |
192 | ; Set the interrupt flag |
193 | mov [FDD_IntFlag], 1 |
193 | mov [FDD_IntFlag], 1 |
Line 194... | Line 194... | ||
194 | mov al, 1 |
194 | mov al, 1 |
195 | ret |
195 | ret |
196 | 196 | ||
197 | ;******************************************* |
197 | ;******************************************* |
198 | ;* ОЖИДАНИЕ ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД * |
198 | ;* WAIT FOR INTERRUPT FROM FDC * |
199 | ;******************************************* |
199 | ;******************************************* |
200 | WaitFDCInterrupt: |
200 | WaitFDCInterrupt: |
201 | pusha |
201 | pusha |
202 | ; Сбросить байт состояния операции |
202 | ; Reset operation status byte |
203 | mov [FDC_Status], FDC_Normal |
203 | mov [FDC_Status], FDC_Normal |
204 | ; Обнулить счетчик тиков |
204 | ; Zero out the tick counter |
205 | mov eax, [timer_ticks] |
205 | mov eax, [timer_ticks] |
206 | mov [TickCounter], eax |
206 | mov [TickCounter], eax |
207 | ; Ожидать установки флага прерывания НГМД |
207 | ; Wait for the floppy disk interrupt flag to be set |
208 | @@TestRS_2: |
208 | @@TestRS_2: |
209 | call change_task |
209 | call change_task |
210 | cmp [FDD_IntFlag], 0 |
210 | cmp [FDD_IntFlag], 0 |
211 | jnz @@End_7 ;прерывание произошло |
211 | jnz @@End_7 ; interrupt occured |
212 | mov eax, [timer_ticks] |
212 | mov eax, [timer_ticks] |
213 | sub eax, [TickCounter] |
213 | sub eax, [TickCounter] |
214 | cmp eax, 200;50 ;25 ;5 ;ожидать 5 тиков |
214 | cmp eax, 200;50 ;25 ;5 ; wait 5 ticks |
215 | jb @@TestRS_2 |
215 | jb @@TestRS_2 |
216 | ; jl @@TestRS_2 |
216 | ; jl @@TestRS_2 |
217 | ; Ошибка тайм-аута |
217 | ; Time out error |
218 | ; dbgstr 'WaitFDCInterrupt: timeout' |
218 | ; dbgstr 'WaitFDCInterrupt: timeout' |
219 | mov [FDC_Status], FDC_TimeOut |
219 | mov [FDC_Status], FDC_TimeOut |
Line 220... | Line 220... | ||
220 | @@End_7: |
220 | @@End_7: |
221 | popa |
221 | popa |
222 | ret |
222 | ret |
223 | 223 | ||
224 | ;********************************* |
224 | ;*********************************** |
225 | ;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" * |
225 | ;* Turn on the motor of drive "A:" * |
226 | ;********************************* |
226 | ;*********************************** |
227 | FDDMotorON: |
227 | FDDMotorON: |
228 | ; dbgstr 'FDDMotorON' |
228 | ; dbgstr 'FDDMotorON' |
229 | pusha |
229 | pusha |
230 | ; cmp [fdd_motor_status],1 |
230 | ; cmp [fdd_motor_status],1 |
231 | ; je fdd_motor_on |
231 | ; je fdd_motor_on |
232 | mov al, [flp_number] |
232 | mov al, [flp_number] |
233 | cmp [fdd_motor_status], al |
233 | cmp [fdd_motor_status], al |
234 | je fdd_motor_on |
234 | je fdd_motor_on |
235 | ; Произвести сброс контроллера НГМД |
235 | ; Reset the FDD controller |
236 | mov DX, 3F2h;порт управления двигателями |
236 | mov DX, 3F2h ; motor control port |
237 | mov AL, 0 |
237 | mov AL, 0 |
238 | out DX, AL |
238 | out DX, AL |
239 | ; Выбрать и включить мотор дисковода |
239 | ; Select and turn on the drive motor |
240 | cmp [flp_number], 1 |
240 | cmp [flp_number], 1 |
241 | jne FDDMotorON_B |
241 | jne FDDMotorON_B |
242 | ; call FDDMotorOFF_B |
242 | ; call FDDMotorOFF_B |
243 | mov AL, 1Ch ; Floppy A |
243 | mov AL, 1Ch ; Floppy A |
244 | jmp FDDMotorON_1 |
244 | jmp FDDMotorON_1 |
245 | FDDMotorON_B: |
245 | FDDMotorON_B: |
246 | ; call FDDMotorOFF_A |
246 | ; call FDDMotorOFF_A |
247 | mov AL, 2Dh ; Floppy B |
247 | mov AL, 2Dh ; Floppy B |
248 | FDDMotorON_1: |
248 | FDDMotorON_1: |
249 | out DX, AL |
249 | out DX, AL |
250 | ; Обнулить счетчик тиков |
250 | ; Zero out the tick counter |
251 | mov eax, [timer_ticks] |
251 | mov eax, [timer_ticks] |
252 | mov [TickCounter], eax |
252 | mov [TickCounter], eax |
253 | ; Ожидать 0,5 с |
253 | ; wait 0.5 s |
254 | @@dT: |
254 | @@dT: |
Line 281... | Line 281... | ||
281 | call save_timer_fdd_motor |
281 | call save_timer_fdd_motor |
282 | popa |
282 | popa |
283 | ret |
283 | ret |
Line 284... | Line 284... | ||
284 | 284 | ||
285 | ;***************************************** |
285 | ;***************************************** |
286 | ;* СОХРАНЕНИЕ УКАЗАТЕЛЯ ВРЕМЕНИ * |
286 | ;* SAVING TIME STAMP * |
287 | ;***************************************** |
287 | ;***************************************** |
288 | save_timer_fdd_motor: |
288 | save_timer_fdd_motor: |
289 | mov eax, [timer_ticks] |
289 | mov eax, [timer_ticks] |
290 | mov [timer_fdd_motor], eax |
290 | mov [timer_fdd_motor], eax |
Line 291... | Line 291... | ||
291 | ret |
291 | ret |
292 | 292 | ||
293 | ;***************************************** |
293 | ;***************************************** |
294 | ;* ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА * |
294 | ;* CHECK THE MOTOR SHUTDOWN DELAY * |
295 | ;***************************************** |
295 | ;***************************************** |
296 | proc check_fdd_motor_status_has_work? |
296 | proc check_fdd_motor_status_has_work? |
297 | cmp [fdd_motor_status], 0 |
297 | cmp [fdd_motor_status], 0 |
Line 322... | Line 322... | ||
322 | end_check_fdd_motor_status_1: |
322 | end_check_fdd_motor_status_1: |
323 | end_check_fdd_motor_status: |
323 | end_check_fdd_motor_status: |
324 | ret |
324 | ret |
Line 325... | Line 325... | ||
325 | 325 | ||
326 | ;********************************** |
326 | ;********************************** |
327 | ;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА * |
327 | ;* TURN OFF MOTOR OF DRIVE * |
328 | ;********************************** |
328 | ;********************************** |
329 | FDDMotorOFF: |
329 | FDDMotorOFF: |
330 | ; dbgstr 'FDDMotorOFF' |
330 | ; dbgstr 'FDDMotorOFF' |
331 | push AX |
331 | push AX |
Line 337... | Line 337... | ||
337 | FDDMotorOFF_1: |
337 | FDDMotorOFF_1: |
338 | call FDDMotorOFF_B |
338 | call FDDMotorOFF_B |
339 | FDDMotorOFF_2: |
339 | FDDMotorOFF_2: |
340 | pop DX |
340 | pop DX |
341 | pop AX |
341 | pop AX |
342 | ; сброс флагов кеширования в связи с устареванием информации |
342 | ; clearing caching flags due to information obsolescence |
343 | or [floppy_media_flags+0], FLOPPY_MEDIA_NEED_RESCAN |
343 | or [floppy_media_flags+0], FLOPPY_MEDIA_NEED_RESCAN |
344 | or [floppy_media_flags+1], FLOPPY_MEDIA_NEED_RESCAN |
344 | or [floppy_media_flags+1], FLOPPY_MEDIA_NEED_RESCAN |
345 | ret |
345 | ret |
Line 346... | Line 346... | ||
346 | 346 | ||
347 | FDDMotorOFF_A: |
347 | FDDMotorOFF_A: |
348 | mov DX, 3F2h;порт управления двигателями |
348 | mov DX, 3F2h ; motor control port |
349 | mov AL, 0Ch ; Floppy A |
349 | mov AL, 0Ch ; Floppy A |
350 | out DX, AL |
350 | out DX, AL |
Line 351... | Line 351... | ||
351 | ret |
351 | ret |
352 | 352 | ||
353 | FDDMotorOFF_B: |
353 | FDDMotorOFF_B: |
354 | mov DX, 3F2h;порт управления двигателями |
354 | mov DX, 3F2h ; motor control port |
355 | mov AL, 5h ; Floppy B |
355 | mov AL, 5h ; Floppy B |
Line 356... | Line 356... | ||
356 | out DX, AL |
356 | out DX, AL |
357 | ret |
357 | ret |
358 | 358 | ||
359 | ;******************************* |
359 | ;******************************* |
360 | ;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" * |
360 | ;* RECALIBRATE DRIVE "A:" * |
361 | ;******************************* |
361 | ;******************************* |
362 | RecalibrateFDD: |
362 | RecalibrateFDD: |
363 | ; dbgstr 'RecalibrateFDD' |
363 | ; dbgstr 'RecalibrateFDD' |
364 | pusha |
364 | pusha |
365 | call save_timer_fdd_motor |
365 | call save_timer_fdd_motor |
366 | ; Сбросить флаг прерывания |
366 | ; Clear the interrupt flag |
367 | mov [FDD_IntFlag], 0 |
367 | mov [FDD_IntFlag], 0 |
368 | ; Подать команду "Рекалибровка" |
368 | ; Send the "Recalibration" command |
369 | mov AL, 07h |
369 | mov AL, 07h |
370 | call FDCDataOutput |
370 | call FDCDataOutput |
371 | mov AL, [flp_number] |
371 | mov AL, [flp_number] |
372 | dec AL |
372 | dec AL |
373 | call FDCDataOutput |
373 | call FDCDataOutput |
374 | ; Ожидать завершения операции |
374 | ; Wait for the operation to complete |
375 | call WaitFDCInterrupt |
375 | call WaitFDCInterrupt |
376 | cmp [FDC_Status], 0 |
376 | cmp [FDC_Status], 0 |
Line 394... | Line 394... | ||
394 | call save_timer_fdd_motor |
394 | call save_timer_fdd_motor |
395 | popa |
395 | popa |
396 | ret |
396 | ret |
Line 397... | Line 397... | ||
397 | 397 | ||
398 | ;***************************************************** |
398 | ;***************************************************** |
399 | ;* ПОИСК ДОРОЖКИ * |
399 | ;* TRACK SEARCH * |
400 | ;* Параметры передаются через глобальные переменные: * |
400 | ;* Parameters are passed through global variables: * |
401 | ;* FDD_Track - номер дорожки (0-79); * |
401 | ;* FDD_Track - track number (0-79); * |
402 | ;* FDD_Head - номер головки (0-1). * |
402 | ;* FDD_Head - head number (0-1). * |
403 | ;* Результат операции заносится в FDC_Status. * |
403 | ;* Result of operation is written to FDC_Status. * |
404 | ;***************************************************** |
404 | ;***************************************************** |
405 | SeekTrack: |
405 | SeekTrack: |
406 | ; dbgstr 'SeekTrack' |
406 | ; dbgstr 'SeekTrack' |
407 | pusha |
407 | pusha |
408 | call save_timer_fdd_motor |
408 | call save_timer_fdd_motor |
409 | ; Сбросить флаг прерывания |
409 | ; Clear the interrupt flag |
410 | mov [FDD_IntFlag], 0 |
410 | mov [FDD_IntFlag], 0 |
411 | ; Подать команду "Поиск" |
411 | ; Send "Search" command |
412 | mov AL, 0Fh |
412 | mov AL, 0Fh |
413 | call FDCDataOutput |
413 | call FDCDataOutput |
414 | ; Передать байт номера головки/накопител |
414 | ; Send head / drive number byte |
415 | mov AL, [FDD_Head] |
415 | mov AL, [FDD_Head] |
416 | shl AL, 2 |
416 | shl AL, 2 |
417 | call FDCDataOutput |
417 | call FDCDataOutput |
418 | ; Передать байт номера дорожки |
418 | ; Send track number byte |
419 | mov AL, [FDD_Track] |
419 | mov AL, [FDD_Track] |
420 | call FDCDataOutput |
420 | call FDCDataOutput |
421 | ; Ожидать завершения операции |
421 | ; Wait for the operation to complete |
422 | call WaitFDCInterrupt |
422 | call WaitFDCInterrupt |
423 | cmp [FDC_Status], FDC_Normal |
423 | cmp [FDC_Status], FDC_Normal |
424 | jne @@Exit |
424 | jne @@Exit |
425 | ; Сохранить результат поиска |
425 | ; Save search result |
426 | mov AL, 08h |
426 | mov AL, 08h |
427 | call FDCDataOutput |
427 | call FDCDataOutput |
428 | call FDCDataInput |
428 | call FDCDataInput |
429 | mov [FDC_ST0], AL |
429 | mov [FDC_ST0], AL |
430 | call FDCDataInput |
430 | call FDCDataInput |
431 | mov [FDC_C], AL |
431 | mov [FDC_C], AL |
432 | ; Проверить результат поиска |
432 | ; Check search result |
433 | ; Поиск завершен? |
433 | ; Is search finished? |
434 | test [FDC_ST0], 100000b |
434 | test [FDC_ST0], 100000b |
435 | je @@Err |
435 | je @@Err |
436 | ; Заданный трек найден? |
436 | ; Is the specified track found? |
437 | mov AL, [FDC_C] |
437 | mov AL, [FDC_C] |
438 | cmp AL, [FDD_Track] |
438 | cmp AL, [FDD_Track] |
439 | jne @@Err |
439 | jne @@Err |
440 | ; Номер головки совпадает с заданным? |
440 | ; Does the head number match the specified one? |
441 | ; The H bit (Head Address) in ST0 will always return a "0" (c) 82077AA datasheet, |
441 | ; The H bit (Head Address) in ST0 will always return a "0" (c) 82077AA datasheet, |
442 | ; description of SEEK command. So we can not verify the proper head. |
442 | ; description of SEEK command. So we can not verify the proper head. |
443 | ; mov AL, [FDC_ST0] |
443 | ; mov AL, [FDC_ST0] |
444 | ; and AL, 100b |
444 | ; and AL, 100b |
445 | ; shr AL, 2 |
445 | ; shr AL, 2 |
446 | ; cmp AL, [FDD_Head] |
446 | ; cmp AL, [FDD_Head] |
447 | ; jne @@Err |
447 | ; jne @@Err |
448 | ; Операция завершена успешно |
448 | ; Operation completed successfully |
449 | ; dbgstr 'SeekTrack: FDC_Normal' |
449 | ; dbgstr 'SeekTrack: FDC_Normal' |
450 | mov [FDC_Status], FDC_Normal |
450 | mov [FDC_Status], FDC_Normal |
451 | jmp @@Exit |
451 | jmp @@Exit |
452 | @@Err: ; Трек не найден |
452 | @@Err: ; Track not found |
453 | ; dbgstr 'SeekTrack: FDC_TrackNotFound' |
453 | ; dbgstr 'SeekTrack: FDC_TrackNotFound' |
454 | mov [FDC_Status], FDC_TrackNotFound |
454 | mov [FDC_Status], FDC_TrackNotFound |
455 | @@Exit: |
455 | @@Exit: |
456 | call save_timer_fdd_motor |
456 | call save_timer_fdd_motor |
457 | popa |
457 | popa |
Line 458... | Line 458... | ||
458 | ret |
458 | ret |
459 | 459 | ||
460 | ;******************************************************* |
460 | ;******************************************************* |
461 | ;* ЧТЕНИЕ СЕКТОРА ДАННЫХ * |
461 | ;* READING A DATA SECTOR * |
462 | ;* Параметры передаются через глобальные переменные: * |
462 | ;* Parameters are passed through global variables: * |
463 | ;* FDD_Track - номер дорожки (0-79); * |
463 | ;* FDD_Track - track number (0-79); * |
464 | ;* FDD_Head - номер головки (0-1); * |
464 | ;* FDD_Head - head number (0-1); * |
465 | ;* FDD_Sector - номер сектора (1-18). * |
465 | ;* FDD_Sector - sector number (1-18). * |
466 | ;* Результат операции заносится в FDC_Status. * |
466 | ;* Result of operation is written to FDC_Status. * |
467 | ;* В случае успешного выполнения операции чтения * |
467 | ;* If the read operation is successful, the contents * |
468 | ;* содержимое сектора будет занесено в FDD_DataBuffer. * |
468 | ;* of the sector will be written to FDD_DataBuffer. * |
469 | ;******************************************************* |
469 | ;******************************************************* |
470 | ReadSector: |
470 | ReadSector: |
471 | ; dbgstr 'ReadSector' |
471 | ; dbgstr 'ReadSector' |
472 | pushad |
472 | pushad |
473 | call save_timer_fdd_motor |
473 | call save_timer_fdd_motor |
474 | ; Сбросить флаг прерывания |
474 | ; Clear the interrupt flag |
475 | mov [FDD_IntFlag], 0 |
475 | mov [FDD_IntFlag], 0 |
476 | ; Установить скорость передачи 500 Кбайт/с |
476 | ; Set transmit speed to 500 Kb / s |
477 | mov AX, 0 |
477 | mov AX, 0 |
478 | mov DX, 03F7h |
478 | mov DX, 03F7h |
479 | out DX, AL |
479 | out DX, AL |
480 | ; Инициализировать канал прямого доступа к памяти |
480 | ; Initialize the DMA channel |
481 | mov [dmamode], 0x46 |
481 | mov [dmamode], 0x46 |
482 | call Init_FDC_DMA |
482 | call Init_FDC_DMA |
483 | ; Подать команду "Чтение данных" |
483 | ; Send "Data read" command |
484 | mov AL, 0E6h ;чтение в мультитрековом режиме |
484 | mov AL, 0E6h ; reading in multi-track mode |
485 | call FDCDataOutput |
485 | call FDCDataOutput |
486 | mov AL, [FDD_Head] |
486 | mov AL, [FDD_Head] |
487 | shl AL, 2 |
487 | shl AL, 2 |
Line 492... | Line 492... | ||
492 | call FDCDataOutput |
492 | call FDCDataOutput |
493 | mov AL, [FDD_Head] |
493 | mov AL, [FDD_Head] |
494 | call FDCDataOutput |
494 | call FDCDataOutput |
495 | mov AL, [FDD_Sector] |
495 | mov AL, [FDD_Sector] |
496 | call FDCDataOutput |
496 | call FDCDataOutput |
497 | mov AL, 2 ;код размера сектора (512 байт) |
497 | mov AL, 2 ; sector size code (512 byte) |
498 | call FDCDataOutput |
498 | call FDCDataOutput |
499 | mov AL, 18 ;+1; 3Fh ;число секторов на дорожке |
499 | mov AL, 18 ;+1; 3Fh ;number of sectors per track |
500 | call FDCDataOutput |
500 | call FDCDataOutput |
501 | mov AL, 1Bh ;значение GPL |
501 | mov AL, 1Bh ; GPL value |
502 | call FDCDataOutput |
502 | call FDCDataOutput |
503 | mov AL, 0FFh;значение DTL |
503 | mov AL, 0FFh; DTL value |
504 | call FDCDataOutput |
504 | call FDCDataOutput |
505 | ; Ожидаем прерывание по завершении операции |
505 | ; Waiting for an interrupt at the end of the operation |
506 | call WaitFDCInterrupt |
506 | call WaitFDCInterrupt |
507 | cmp [FDC_Status], FDC_Normal |
507 | cmp [FDC_Status], FDC_Normal |
508 | jne @@Exit_1 |
508 | jne @@Exit_1 |
509 | ; Считываем статус завершения операции |
509 | ; Read the operation completion status |
510 | call GetStatusInfo |
510 | call GetStatusInfo |
511 | test [FDC_ST0], 11011000b |
511 | test [FDC_ST0], 11011000b |
512 | jnz @@Err_1 |
512 | jnz @@Err_1 |
513 | ; dbgstr 'ReadSector: FDC_Normal' |
513 | ; dbgstr 'ReadSector: FDC_Normal' |
514 | mov [FDC_Status], FDC_Normal |
514 | mov [FDC_Status], FDC_Normal |
Line 520... | Line 520... | ||
520 | call save_timer_fdd_motor |
520 | call save_timer_fdd_motor |
521 | popad |
521 | popad |
522 | ret |
522 | ret |
Line 523... | Line 523... | ||
523 | 523 | ||
524 | ;******************************************************* |
524 | ;******************************************************* |
525 | ;* ЧТЕНИЕ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) * |
525 | ;* READ SECTOR (WITH RETRY OF OPERATION ON FAILURE) * |
526 | ;* Параметры передаются через глобальные переменные: * |
526 | ;* Parameters are passed through global variables: * |
527 | ;* FDD_Track - номер дорожки (0-79); * |
527 | ;* FDD_Track - track number (0-79); * |
528 | ;* FDD_Head - номер головки (0-1); * |
528 | ;* FDD_Head - head number (0-1); * |
529 | ;* FDD_Sector - номер сектора (1-18). * |
529 | ;* FDD_Sector - sector number (1-18). * |
530 | ;* Результат операции заносится в FDC_Status. * |
530 | ;* Result of operation is written to FDC_Status. * |
531 | ;* В случае успешного выполнения операции чтения * |
531 | ;* If the read operation is successful, the contents * |
532 | ;* содержимое сектора будет занесено в FDD_DataBuffer. * |
532 | ;* of the sector will be written to FDD_DataBuffer. * |
533 | ;******************************************************* |
533 | ;******************************************************* |
534 | ReadSectWithRetr: |
534 | ReadSectWithRetr: |
535 | pusha |
535 | pusha |
536 | ; Обнулить счетчик повторения операции рекалибровки |
536 | ; Reset the recalibration repetition counter |
537 | mov [RecalRepCounter], 0 |
537 | mov [RecalRepCounter], 0 |
538 | @@TryAgain: |
538 | @@TryAgain: |
539 | ; Обнулить счетчик повторения операции чтени |
539 | ; Reset the read operation retry counter |
540 | mov [ReadRepCounter], 0 |
540 | mov [ReadRepCounter], 0 |
541 | @@ReadSector_1: |
541 | @@ReadSector_1: |
542 | call ReadSector |
542 | call ReadSector |
543 | cmp [FDC_Status], 0 |
543 | cmp [FDC_Status], 0 |
544 | je @@Exit_2 |
544 | je @@Exit_2 |
545 | cmp [FDC_Status], 1 |
545 | cmp [FDC_Status], 1 |
546 | je @@Err_3 |
546 | je @@Err_3 |
547 | ; Троекратное повторение чтени |
547 | ; Three times repeat reading |
548 | inc [ReadRepCounter] |
548 | inc [ReadRepCounter] |
549 | cmp [ReadRepCounter], 3 |
549 | cmp [ReadRepCounter], 3 |
550 | jb @@ReadSector_1 |
550 | jb @@ReadSector_1 |
551 | ; Троекратное повторение рекалибровки |
551 | ; Three times repeat recalibration |
552 | call RecalibrateFDD |
552 | call RecalibrateFDD |
553 | call SeekTrack |
553 | call SeekTrack |
554 | inc [RecalRepCounter] |
554 | inc [RecalRepCounter] |
555 | cmp [RecalRepCounter], 3 |
555 | cmp [RecalRepCounter], 3 |
Line 560... | Line 560... | ||
560 | @@Err_3: |
560 | @@Err_3: |
561 | popa |
561 | popa |
562 | ret |
562 | ret |
Line 563... | Line 563... | ||
563 | 563 | ||
564 | ;******************************************************* |
564 | ;******************************************************* |
565 | ;* ЗАПИСЬ СЕКТОРА ДАННЫХ * |
565 | ;* WRITE DATA SECTOR * |
566 | ;* Параметры передаются через глобальные переменные: * |
566 | ;* Parameters are passed through global variables: * |
567 | ;* FDD_Track - номер дорожки (0-79); * |
567 | ;* FDD_Track - track number (0-79); * |
568 | ;* FDD_Head - номер головки (0-1); * |
568 | ;* FDD_Head - head number (0-1); * |
569 | ;* FDD_Sector - номер сектора (1-18). * |
569 | ;* FDD_Sector - sector number (1-18). * |
570 | ;* Результат операции заносится в FDC_Status. * |
570 | ;* Result of operation is written to FDC_Status. * |
571 | ;* В случае успешного выполнения операции записи * |
571 | ;* If the write operation is successful, the contents * |
572 | ;* содержимое FDD_DataBuffer будет занесено в сектор. * |
572 | ;* of FDD_DataBuffer will be written to the sector * |
573 | ;******************************************************* |
573 | ;******************************************************* |
574 | WriteSector: |
574 | WriteSector: |
575 | ; dbgstr 'WriteSector' |
575 | ; dbgstr 'WriteSector' |
576 | pushad |
576 | pushad |
577 | call save_timer_fdd_motor |
577 | call save_timer_fdd_motor |
578 | ; Сбросить флаг прерывания |
578 | ; Clear the interrupt flag |
579 | mov [FDD_IntFlag], 0 |
579 | mov [FDD_IntFlag], 0 |
580 | ; Установить скорость передачи 500 Кбайт/с |
580 | ; Set transmit speed to 500 Kb / s |
581 | mov AX, 0 |
581 | mov AX, 0 |
582 | mov DX, 03F7h |
582 | mov DX, 03F7h |
583 | out DX, AL |
583 | out DX, AL |
584 | ; Инициализировать канал прямого доступа к памяти |
584 | ; Initialize the DMA channel |
585 | mov [dmamode], 0x4A |
585 | mov [dmamode], 0x4A |
586 | call Init_FDC_DMA |
586 | call Init_FDC_DMA |
587 | ; Подать команду "Запись данных" |
587 | ; Send "Write data" command |
588 | mov AL, 0xC5 ;0x45 ;запись в мультитрековом режиме |
588 | mov AL, 0xC5 ;0x45 ; write in multi-track mode |
589 | call FDCDataOutput |
589 | call FDCDataOutput |
590 | mov AL, [FDD_Head] |
590 | mov AL, [FDD_Head] |
591 | shl AL, 2 |
591 | shl AL, 2 |
592 | or AL, [flp_number] |
592 | or AL, [flp_number] |
Line 596... | Line 596... | ||
596 | call FDCDataOutput |
596 | call FDCDataOutput |
597 | mov AL, [FDD_Head] |
597 | mov AL, [FDD_Head] |
598 | call FDCDataOutput |
598 | call FDCDataOutput |
599 | mov AL, [FDD_Sector] |
599 | mov AL, [FDD_Sector] |
600 | call FDCDataOutput |
600 | call FDCDataOutput |
601 | mov AL, 2 ;код размера сектора (512 байт) |
601 | mov AL, 2 ; sector size code (512 bytes) |
602 | call FDCDataOutput |
602 | call FDCDataOutput |
603 | mov AL, 18; 3Fh ;число секторов на дорожке |
603 | mov AL, 18; 3Fh ; sectors per track |
604 | call FDCDataOutput |
604 | call FDCDataOutput |
605 | mov AL, 1Bh ;значение GPL |
605 | mov AL, 1Bh ; GPL value |
606 | call FDCDataOutput |
606 | call FDCDataOutput |
607 | mov AL, 0FFh;значение DTL |
607 | mov AL, 0FFh; DTL value |
608 | call FDCDataOutput |
608 | call FDCDataOutput |
609 | ; Ожидаем прерывание по завершении операции |
609 | ; Waiting for an interrupt at the end of the operation |
610 | call WaitFDCInterrupt |
610 | call WaitFDCInterrupt |
611 | cmp [FDC_Status], FDC_Normal |
611 | cmp [FDC_Status], FDC_Normal |
612 | jne @@Exit_3 |
612 | jne @@Exit_3 |
613 | ; Считываем статус завершения операции |
613 | ; Reading the completion status of the operation |
614 | call GetStatusInfo |
614 | call GetStatusInfo |
615 | test [FDC_ST0], 11000000b ;11011000b |
615 | test [FDC_ST0], 11000000b ;11011000b |
616 | jnz @@Err_2 |
616 | jnz @@Err_2 |
617 | mov [FDC_Status], FDC_Normal |
617 | mov [FDC_Status], FDC_Normal |
618 | jmp @@Exit_3 |
618 | jmp @@Exit_3 |
Line 622... | Line 622... | ||
622 | call save_timer_fdd_motor |
622 | call save_timer_fdd_motor |
623 | popad |
623 | popad |
624 | ret |
624 | ret |
Line 625... | Line 625... | ||
625 | 625 | ||
626 | ;******************************************************* |
626 | ;******************************************************* |
627 | ;* ЗАПИСЬ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ) * |
627 | ;* WRITE SECTOR (WITH REPEAT ON FAILURE) * |
628 | ;* Параметры передаются через глобальные переменные: * |
628 | ;* Parameters are passed through global variables: * |
629 | ;* FDD_Track - номер дорожки (0-79); * |
629 | ;* FDD_Track - track number (0-79); * |
630 | ;* FDD_Head - номер головки (0-1); * |
630 | ;* FDD_Head - head number (0-1); * |
631 | ;* FDD_Sector - номер сектора (1-18). * |
631 | ;* FDD_Sector - sector number (1-18). * |
632 | ;* Результат операции заносится в FDC_Status. * |
632 | ;* Result of operation is written to FDC_Status. * |
633 | ;* В случае успешного выполнения операции записи * |
633 | ;* If the write operation is successful, the contents * |
634 | ;* содержимое FDD_DataBuffer будет занесено в сектор. * |
634 | ;* of FDD_DataBuffer will be written to the sector * |
635 | ;******************************************************* |
635 | ;******************************************************* |
636 | WriteSectWithRetr: |
636 | WriteSectWithRetr: |
637 | pusha |
637 | pusha |
638 | ; Обнулить счетчик повторения операции рекалибровки |
638 | ; Reset the recalibration repetition counter |
639 | mov [RecalRepCounter], 0 |
639 | mov [RecalRepCounter], 0 |
640 | @@TryAgain_1: |
640 | @@TryAgain_1: |
641 | ; Обнулить счетчик повторения операции чтени |
641 | ; Reset the read operation retry counter |
642 | mov [ReadRepCounter], 0 |
642 | mov [ReadRepCounter], 0 |
643 | @@WriteSector_1: |
643 | @@WriteSector_1: |
644 | call WriteSector |
644 | call WriteSector |
645 | cmp [FDC_Status], 0 |
645 | cmp [FDC_Status], 0 |
646 | je @@Exit_4 |
646 | je @@Exit_4 |
647 | cmp [FDC_Status], 1 |
647 | cmp [FDC_Status], 1 |
648 | je @@Err_4 |
648 | je @@Err_4 |
649 | ; Троекратное повторение чтени |
649 | ; Three times repeat writing |
650 | inc [ReadRepCounter] |
650 | inc [ReadRepCounter] |
651 | cmp [ReadRepCounter], 3 |
651 | cmp [ReadRepCounter], 3 |
652 | jb @@WriteSector_1 |
652 | jb @@WriteSector_1 |
653 | ; Троекратное повторение рекалибровки |
653 | ; Three times repeat recalibration |
654 | call RecalibrateFDD |
654 | call RecalibrateFDD |
655 | call SeekTrack |
655 | call SeekTrack |
656 | inc [RecalRepCounter] |
656 | inc [RecalRepCounter] |
657 | cmp [RecalRepCounter], 3 |
657 | cmp [RecalRepCounter], 3 |
Line 662... | Line 662... | ||
662 | @@Err_4: |
662 | @@Err_4: |
663 | popa |
663 | popa |
664 | ret |
664 | ret |
Line 665... | Line 665... | ||
665 | 665 | ||
666 | ;********************************************* |
666 | ;********************************************* |
667 | ;* ПОЛУЧИТЬ ИНФОРМАЦИЮ О РЕЗУЛЬТАТЕ ОПЕРАЦИИ * |
667 | ;* GET INFORMATION ABOUT THE RESULT OF THE OPERATION |
668 | ;********************************************* |
668 | ;********************************************* |
669 | GetStatusInfo: |
669 | GetStatusInfo: |
670 | push AX |
670 | push AX |
671 | call FDCDataInput |
671 | call FDCDataInput |
Line 829... | Line 829... | ||
829 | retn 8 |
829 | retn 8 |
830 | endp |
830 | endp |
Line 831... | Line 831... | ||
831 | 831 | ||
832 | proc floppy_read_bootsector |
832 | proc floppy_read_bootsector |
833 | pushad |
833 | pushad |
834 | mov [FDD_Track], 0; Цилиндр |
834 | mov [FDD_Track], 0 ; Cylinder |
835 | mov [FDD_Head], 0; Сторона |
835 | mov [FDD_Head], 0 ; Head |
836 | mov [FDD_Sector], 1; Сектор |
836 | mov [FDD_Sector], 1 ; Sector |
837 | call FDDMotorON |
837 | call FDDMotorON |
838 | call RecalibrateFDD |
838 | call RecalibrateFDD |
839 | cmp [FDC_Status], 0 |
839 | cmp [FDC_Status], 0 |
840 | jne .nothing |
840 | jne .nothing |