Subversion Repositories Kolibri OS

Rev

Rev 3908 | Rev 4287 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2465 Serge 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
431 serge 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
593 mikedld 8
$Revision: 4265 $
9
 
10
 
1 ha 11
;**********************************************************
3555 Serge 12
;  Непосредственная работа с контроллером гибкого диска
1 ha 13
;**********************************************************
3555 Serge 14
; Автор исходного текста  Кулаков Владимир Геннадьевич.
15
; Адаптация и доработка Mario79
1 ha 16
 
3555 Serge 17
;give_back_application_data:  ; переслать приложению
465 serge 18
;     mov edi,[TASK_BASE]
19
;     mov edi,[edi+TASKDATA.mem_start]
20
;     add edi,ecx
1 ha 21
give_back_application_data_1:
2434 Serge 22
        mov     esi, FDD_BUFF;FDD_DataBuffer  ;0x40000
23
        xor     ecx, ecx
24
        mov     cx, 128
3555 Serge 25
        cld
26
        rep movsd
27
        ret
1 ha 28
 
3555 Serge 29
;take_data_from_application:   ; взять из приложени
465 serge 30
;     mov esi,[TASK_BASE]
31
;     mov esi,[esi+TASKDATA.mem_start]
32
;     add esi,ecx
1 ha 33
take_data_from_application_1:
2434 Serge 34
        mov     edi, FDD_BUFF;FDD_DataBuffer  ;0x40000
35
        xor     ecx, ecx
36
        mov     cx, 128
3555 Serge 37
        cld
38
        rep movsd
39
        ret
1 ha 40
 
3555 Serge 41
; Коды завершения операции с контроллером (FDC_Status)
42
FDC_Normal         equ 0 ;нормальное завершение
43
FDC_TimeOut        equ 1 ;ошибка тайм-аута
44
FDC_DiskNotFound   equ 2 ;в дисководе нет диска
45
FDC_TrackNotFound  equ 3 ;дорожка не найдена
46
FDC_SectorNotFound equ 4 ;сектор не найден
1 ha 47
 
3555 Serge 48
; Максимальные значения координат сектора (заданные
49
; значения соответствуют параметрам стандартного
50
; трехдюймового гибкого диска объемом 1,44 Мб)
1 ha 51
MAX_Track   equ 79
52
MAX_Head    equ  1
53
MAX_Sector  equ 18
54
 
75 diamond 55
uglobal
3555 Serge 56
; Счетчик тиков таймера
1 ha 57
TickCounter dd ?
3555 Serge 58
; Код завершения операции с контроллером НГМД
1 ha 59
FDC_Status  DB ?
3555 Serge 60
; Флаг прерывания от НГМД
1 ha 61
FDD_IntFlag DB ?
3555 Serge 62
; Момент начала последней операции с НГМД
1 ha 63
FDD_Time    DD ?
3555 Serge 64
; Номер дисковода
1 ha 65
FDD_Type    db 0
3555 Serge 66
; Координаты сектора
1 ha 67
FDD_Track   DB ?
68
FDD_Head    DB ?
69
FDD_Sector  DB ?
70
 
3555 Serge 71
; Блок результата операции
1 ha 72
FDC_ST0 DB ?
73
FDC_ST1 DB ?
74
FDC_ST2 DB ?
75
FDC_C   DB ?
76
FDC_H   DB ?
77
FDC_R   DB ?
78
FDC_N   DB ?
3555 Serge 79
; Счетчик повторения операции чтени
1 ha 80
ReadRepCounter  DB ?
3555 Serge 81
; Счетчик повторения операции рекалибровки
1 ha 82
RecalRepCounter DB ?
75 diamond 83
endg
3555 Serge 84
; Область памяти для хранения прочитанного сектора
1 ha 85
;FDD_DataBuffer:  times 512 db 0   ;DB 512 DUP (?)
86
fdd_motor_status db 0
87
timer_fdd_motor  dd 0
88
 
89
;*************************************
3555 Serge 90
;* ИНИЦИАЛИЗАЦИЯ РЕЖИМА ПДП ДЛЯ НГМД *
1 ha 91
;*************************************
92
Init_FDC_DMA:
93
        pushad
2434 Serge 94
        mov     al, 0
95
        out     0x0c, al; reset the flip-flop to a known state.
96
        mov     al, 6           ; mask channel 2 so we can reprogram it.
97
        out     0x0a, al
98
        mov     al, [dmamode]; 0x46 -> Read from floppy - 0x4A Write to floppy
99
        out     0x0b, al
100
        mov     al, 0
101
        out     0x0c, al; reset the flip-flop to a known state.
102
        mov     eax, 0xD000
103
        out     0x04, al; set the channel 2 starting address to 0
104
        shr     eax, 8
105
        out     0x04, al
106
        shr     eax, 8
107
        out     0x81, al
108
        mov     al, 0
109
        out     0x0c, al; reset flip-flop
110
        mov     al, 0xff;set count (actual size -1)
3555 Serge 111
        out     0x5, al
2434 Serge 112
        mov     al, 0x1;[dmasize]       ;(0x1ff = 511 / 0x23ff =9215)
113
        out     0x5, al
114
        mov     al, 2
115
        out     0xa, al
1 ha 116
        popad
117
        ret
118
 
119
;***********************************
3555 Serge 120
;* ЗАПИСАТЬ БАЙТ В ПОРТ ДАННЫХ FDC *
121
;* Параметры:                      *
122
;* AL - выводимый байт.            *
1 ha 123
;***********************************
124
FDCDataOutput:
125
;        pusha
3555 Serge 126
        push    eax ecx edx
127
        mov     AH, AL    ;запомнить байт в AH
128
; Сбросить переменную состояния контроллера
2434 Serge 129
        mov     [FDC_Status], FDC_Normal
3555 Serge 130
; Проверить готовность контроллера к приему данных
131
        mov     DX, 3F4h  ;(порт состояния FDC)
132
        mov     ecx, 0x10000 ;установить счетчик тайм-аута
1 ha 133
@@TestRS:
3555 Serge 134
        in      AL, DX    ;прочитать регистр RS
135
        and     AL, 0C0h  ;выделить разряды 6 и 7
136
        cmp     AL, 80h   ;проверить разряды 6 и 7
1 ha 137
        je      @@OutByteToFDC
138
        loop    @@TestRS
3555 Serge 139
; Ошибка тайм-аута
2434 Serge 140
        mov     [FDC_Status], FDC_TimeOut
3555 Serge 141
        jmp     @@End_5
142
; Вывести байт в порт данных
1 ha 143
@@OutByteToFDC:
144
        inc     DX
2434 Serge 145
        mov     AL, AH
146
        out     DX, AL
1 ha 147
@@End_5:
148
;        popa
3555 Serge 149
        pop     edx ecx eax
1 ha 150
        ret
151
 
152
;******************************************
3555 Serge 153
;*   ПРОЧИТАТЬ БАЙТ ИЗ ПОРТА ДАННЫХ FDC   *
154
;* Процедура не имеет входных параметров. *
155
;* Выходные данные:                       *
156
;* AL - считанный байт.                   *
1 ha 157
;******************************************
158
FDCDataInput:
159
        push    ECX
160
        push    DX
3555 Serge 161
; Сбросить переменную состояния контроллера
2434 Serge 162
        mov     [FDC_Status], FDC_Normal
3555 Serge 163
; Проверить готовность контроллера к передаче данных
164
        mov     DX, 3F4h  ;(порт состояния FDC)
4265 Serge 165
        mov     ecx, 0x10000 ;установить счетчик тайм-аута
1 ha 166
@@TestRS_1:
3555 Serge 167
        in      AL, DX    ;прочитать регистр RS
168
        and     AL, 0C0h  ;выдлить разряды 6 и 7
169
        cmp     AL, 0C0h  ;проверить разряды 6 и 7
1 ha 170
        je      @@GetByteFromFDC
171
        loop    @@TestRS_1
3555 Serge 172
; Ошибка тайм-аута
2434 Serge 173
        mov     [FDC_Status], FDC_TimeOut
3555 Serge 174
        jmp     @@End_6
175
; Ввести байт из порта данных
1 ha 176
@@GetByteFromFDC:
177
        inc     DX
2434 Serge 178
        in      AL, DX
179
@@End_6:
180
        pop     DX
1 ha 181
        pop     ECX
182
        ret
183
 
184
;*********************************************
3555 Serge 185
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
1 ha 186
;*********************************************
187
FDCInterrupt:
3908 Serge 188
; Установить флаг прерывания
2434 Serge 189
        mov     [FDD_IntFlag], 1
3908 Serge 190
        mov     al, 1
1 ha 191
        ret
192
 
193
;*******************************************
3555 Serge 194
;* ОЖИДАНИЕ ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
1 ha 195
;*******************************************
196
WaitFDCInterrupt:
197
        pusha
3555 Serge 198
; Сбросить байт состояния операции
2434 Serge 199
        mov     [FDC_Status], FDC_Normal
3555 Serge 200
; Обнулить счетчик тиков
2434 Serge 201
        mov     eax, [timer_ticks]
202
        mov     [TickCounter], eax
3555 Serge 203
; Ожидать установки флага прерывания НГМД
1 ha 204
@@TestRS_2:
3908 Serge 205
        call    change_task
2434 Serge 206
        cmp     [FDD_IntFlag], 0
3555 Serge 207
        jnz     @@End_7           ;прерывание произошло
2434 Serge 208
        mov     eax, [timer_ticks]
209
        sub     eax, [TickCounter]
3555 Serge 210
        cmp     eax, 50 ;25   ;5 ;ожидать 5 тиков
1 ha 211
        jb      @@TestRS_2
212
;        jl      @@TestRS_2
3555 Serge 213
; Ошибка тайм-аута
2434 Serge 214
        mov     [FDC_Status], FDC_TimeOut
1 ha 215
;        mov   [flp_status],0
2434 Serge 216
@@End_7:
217
        popa
1 ha 218
        ret
219
 
220
;*********************************
3555 Serge 221
;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" *
1 ha 222
;*********************************
223
FDDMotorON:
224
        pusha
225
;        cmp     [fdd_motor_status],1
226
;        je      fdd_motor_on
2434 Serge 227
        mov     al, [flp_number]
228
        cmp     [fdd_motor_status], al
1 ha 229
        je      fdd_motor_on
3555 Serge 230
; Произвести сброс контроллера НГМД
231
        mov     DX, 3F2h;порт управления двигателями
2434 Serge 232
        mov     AL, 0
233
        out     DX, AL
3555 Serge 234
; Выбрать и включить мотор дисковода
2434 Serge 235
        cmp     [flp_number], 1
1 ha 236
        jne     FDDMotorON_B
237
;        call    FDDMotorOFF_B
2434 Serge 238
        mov     AL, 1Ch   ; Floppy A
1 ha 239
        jmp     FDDMotorON_1
240
FDDMotorON_B:
241
;        call    FDDMotorOFF_A
2434 Serge 242
        mov     AL, 2Dh   ; Floppy B
1 ha 243
FDDMotorON_1:
2434 Serge 244
        out     DX, AL
3555 Serge 245
; Обнулить счетчик тиков
2434 Serge 246
        mov     eax, [timer_ticks]
247
        mov     [TickCounter], eax
3555 Serge 248
; Ожидать 0,5 с
1 ha 249
@@dT:
19 mario79 250
        call    change_task
2434 Serge 251
        mov     eax, [timer_ticks]
252
        sub     eax, [TickCounter]
253
        cmp     eax, 50 ;10
1 ha 254
        jb      @@dT
2434 Serge 255
        cmp     [flp_number], 1
1 ha 256
        jne     fdd_motor_on_B
2434 Serge 257
        mov     [fdd_motor_status], 1
1 ha 258
        jmp     fdd_motor_on
259
fdd_motor_on_B:
2434 Serge 260
        mov     [fdd_motor_status], 2
1 ha 261
fdd_motor_on:
262
        call    save_timer_fdd_motor
263
        popa
264
        ret
265
 
266
;*****************************************
3555 Serge 267
;*  СОХРАНЕНИЕ УКАЗАТЕЛЯ ВРЕМЕНИ         *
1 ha 268
;*****************************************
269
save_timer_fdd_motor:
2434 Serge 270
        mov     eax, [timer_ticks]
271
        mov     [timer_fdd_motor], eax
1 ha 272
        ret
273
 
274
;*****************************************
3555 Serge 275
;*  ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА  *
1 ha 276
;*****************************************
3555 Serge 277
proc check_fdd_motor_status_has_work?
278
        cmp     [flp_status], 0
279
        jnz     .yes
280
        cmp     [fdd_motor_status], 0
281
        jz      .no
282
        mov     eax, [timer_ticks]
283
        sub     eax, [timer_fdd_motor]
284
        cmp     eax, 500
285
        jb      .no
286
.yes:
287
        xor     eax, eax
288
        inc     eax
289
        ret
290
.no:
291
        xor     eax, eax
292
        ret
293
endp
294
 
1168 Lrz 295
align 4
1 ha 296
check_fdd_motor_status:
2434 Serge 297
        cmp     [fdd_motor_status], 0
19 mario79 298
        je      end_check_fdd_motor_status_1
2434 Serge 299
        mov     eax, [timer_ticks]
300
        sub     eax, [timer_fdd_motor]
301
        cmp     eax, 500
1 ha 302
        jb      end_check_fdd_motor_status
303
        call    FDDMotorOFF
2434 Serge 304
        mov     [fdd_motor_status], 0
19 mario79 305
end_check_fdd_motor_status_1:
2434 Serge 306
        mov     [flp_status], 0
1 ha 307
end_check_fdd_motor_status:
308
        ret
309
 
310
;**********************************
3555 Serge 311
;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА      *
1 ha 312
;**********************************
313
FDDMotorOFF:
314
        push    AX
315
        push    DX
2434 Serge 316
        cmp     [flp_number], 1
1 ha 317
        jne     FDDMotorOFF_1
318
        call    FDDMotorOFF_A
319
        jmp     FDDMotorOFF_2
320
FDDMotorOFF_1:
321
        call    FDDMotorOFF_B
322
FDDMotorOFF_2:
323
        pop     DX
324
        pop     AX
3555 Serge 325
        ; сброс флагов кеширования в связи с устареванием информации
2434 Serge 326
        mov     [root_read], 0
327
        mov     [flp_fat], 0
1 ha 328
        ret
329
 
330
FDDMotorOFF_A:
3555 Serge 331
        mov     DX, 3F2h;порт управления двигателями
2434 Serge 332
        mov     AL, 0Ch ; Floppy A
333
        out     DX, AL
1 ha 334
        ret
335
 
336
FDDMotorOFF_B:
3555 Serge 337
        mov     DX, 3F2h;порт управления двигателями
2434 Serge 338
        mov     AL, 5h ; Floppy B
339
        out     DX, AL
1 ha 340
        ret
341
 
342
;*******************************
3555 Serge 343
;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" *
1 ha 344
;*******************************
345
RecalibrateFDD:
346
        pusha
347
        call    save_timer_fdd_motor
3555 Serge 348
; Подать команду "Рекалибровка"
2434 Serge 349
        mov     AL, 07h
1 ha 350
        call    FDCDataOutput
2434 Serge 351
        mov     AL, 00h
1 ha 352
        call    FDCDataOutput
3555 Serge 353
; Ожидать завершения операции
1 ha 354
        call    WaitFDCInterrupt
355
;        cmp    [FDC_Status],0
356
;        je    no_fdc_status_error
357
;        mov   [flp_status],0
358
;no_fdc_status_error:
359
        call    save_timer_fdd_motor
360
        popa
361
        ret
362
 
363
;*****************************************************
3555 Serge 364
;*                    ПОИСК ДОРОЖКИ                  *
365
;* Параметры передаются через глобальные переменные: *
366
;* FDD_Track - номер дорожки (0-79);                 *
367
;* FDD_Head - номер головки (0-1).                   *
368
;* Результат операции заносится в FDC_Status.        *
1 ha 369
;*****************************************************
370
SeekTrack:
371
        pusha
372
        call    save_timer_fdd_motor
4265 Serge 373
; Сбросить флаг прерывания
374
        mov     [FDD_IntFlag], 0
3555 Serge 375
; Подать команду "Поиск"
2434 Serge 376
        mov     AL, 0Fh
1 ha 377
        call    FDCDataOutput
3555 Serge 378
        ; Передать байт номера головки/накопител
2434 Serge 379
        mov     AL, [FDD_Head]
380
        shl     AL, 2
1 ha 381
        call    FDCDataOutput
3555 Serge 382
        ; Передать байт номера дорожки
2434 Serge 383
        mov     AL, [FDD_Track]
1 ha 384
        call    FDCDataOutput
3555 Serge 385
; Ожидать завершения операции
1 ha 386
        call    WaitFDCInterrupt
2434 Serge 387
        cmp     [FDC_Status], FDC_Normal
1 ha 388
        jne     @@Exit
3555 Serge 389
; Сохранить результат поиска
2434 Serge 390
        mov     AL, 08h
1 ha 391
        call    FDCDataOutput
392
        call    FDCDataInput
2434 Serge 393
        mov     [FDC_ST0], AL
1 ha 394
        call    FDCDataInput
2434 Serge 395
        mov     [FDC_C], AL
3555 Serge 396
; Проверить результат поиска
397
        ; Поиск завершен?
2434 Serge 398
        test    [FDC_ST0], 100000b
1 ha 399
        je      @@Err
3555 Serge 400
        ; Заданный трек найден?
2434 Serge 401
        mov     AL, [FDC_C]
402
        cmp     AL, [FDD_Track]
1 ha 403
        jne     @@Err
3555 Serge 404
        ; Номер головки совпадает с заданным?
2434 Serge 405
        mov     AL, [FDC_ST0]
406
        and     AL, 100b
407
        shr     AL, 2
408
        cmp     AL, [FDD_Head]
1 ha 409
        jne     @@Err
3555 Serge 410
        ; Операция завершена успешно
2434 Serge 411
        mov     [FDC_Status], FDC_Normal
3555 Serge 412
        jmp     @@Exit
413
@@Err:  ; Трек не найден
2434 Serge 414
        mov     [FDC_Status], FDC_TrackNotFound
1 ha 415
;        mov   [flp_status],0
416
@@Exit:
417
        call    save_timer_fdd_motor
418
        popa
419
        ret
420
 
421
;*******************************************************
3555 Serge 422
;*               ЧТЕНИЕ СЕКТОРА ДАННЫХ                 *
423
;* Параметры передаются через глобальные переменные:   *
424
;* FDD_Track - номер дорожки (0-79);                   *
425
;* FDD_Head - номер головки (0-1);                     *
426
;* FDD_Sector - номер сектора (1-18).                  *
427
;* Результат операции заносится в FDC_Status.          *
428
;* В случае успешного выполнения операции чтения       *
429
;* содержимое сектора будет занесено в FDD_DataBuffer. *
1 ha 430
;*******************************************************
431
ReadSector:
432
        pushad
433
        call    save_timer_fdd_motor
4265 Serge 434
; Сбросить флаг прерывания
435
        mov     [FDD_IntFlag], 0
3555 Serge 436
; Установить скорость передачи 500 Кбайт/с
2434 Serge 437
        mov     AX, 0
438
        mov     DX, 03F7h
439
        out     DX, AL
3555 Serge 440
; Инициализировать канал прямого доступа к памяти
2434 Serge 441
        mov     [dmamode], 0x46
1 ha 442
        call    Init_FDC_DMA
3555 Serge 443
; Подать команду "Чтение данных"
444
        mov     AL, 0E6h ;чтение в мультитрековом режиме
1 ha 445
        call    FDCDataOutput
2434 Serge 446
        mov     AL, [FDD_Head]
447
        shl     AL, 2
1 ha 448
        call    FDCDataOutput
2434 Serge 449
        mov     AL, [FDD_Track]
1 ha 450
        call    FDCDataOutput
2434 Serge 451
        mov     AL, [FDD_Head]
1 ha 452
        call    FDCDataOutput
2434 Serge 453
        mov     AL, [FDD_Sector]
1 ha 454
        call    FDCDataOutput
3555 Serge 455
        mov     AL, 2   ;код размера сектора (512 байт)
1 ha 456
        call    FDCDataOutput
3555 Serge 457
        mov     AL, 18 ;+1; 3Fh  ;число секторов на дорожке
1 ha 458
        call    FDCDataOutput
3555 Serge 459
        mov     AL, 1Bh ;значение GPL
1 ha 460
        call    FDCDataOutput
3555 Serge 461
        mov     AL, 0FFh;значение DTL
1 ha 462
        call    FDCDataOutput
3555 Serge 463
; Ожидаем прерывание по завершении операции
1 ha 464
        call    WaitFDCInterrupt
2434 Serge 465
        cmp     [FDC_Status], FDC_Normal
1 ha 466
        jne     @@Exit_1
3555 Serge 467
; Считываем статус завершения операции
1 ha 468
        call    GetStatusInfo
2434 Serge 469
        test    [FDC_ST0], 11011000b
1 ha 470
        jnz     @@Err_1
2434 Serge 471
        mov     [FDC_Status], FDC_Normal
3555 Serge 472
        jmp     @@Exit_1
2434 Serge 473
@@Err_1:
474
        mov     [FDC_Status], FDC_SectorNotFound
1 ha 475
;        mov   [flp_status],0
476
@@Exit_1:
477
        call    save_timer_fdd_motor
478
        popad
479
        ret
480
 
481
;*******************************************************
3555 Serge 482
;*   ЧТЕНИЕ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ)  *
483
;* Параметры передаются через глобальные переменные:   *
484
;* FDD_Track - номер дорожки (0-79);                   *
485
;* FDD_Head - номер головки (0-1);                     *
486
;* FDD_Sector - номер сектора (1-18).                  *
487
;* Результат операции заносится в FDC_Status.          *
488
;* В случае успешного выполнения операции чтения       *
489
;* содержимое сектора будет занесено в FDD_DataBuffer. *
1 ha 490
;*******************************************************
491
ReadSectWithRetr:
492
        pusha
3555 Serge 493
; Обнулить счетчик повторения операции рекалибровки
2434 Serge 494
        mov     [RecalRepCounter], 0
1 ha 495
@@TryAgain:
3555 Serge 496
; Обнулить счетчик повторения операции чтени
2434 Serge 497
        mov     [ReadRepCounter], 0
1 ha 498
@@ReadSector_1:
499
        call    ReadSector
2434 Serge 500
        cmp     [FDC_Status], 0
1 ha 501
        je      @@Exit_2
2434 Serge 502
        cmp     [FDC_Status], 1
379 serge 503
        je      @@Err_3
3555 Serge 504
        ; Троекратное повторение чтени
1 ha 505
        inc     [ReadRepCounter]
2434 Serge 506
        cmp     [ReadRepCounter], 3
1 ha 507
        jb      @@ReadSector_1
3555 Serge 508
        ; Троекратное повторение рекалибровки
1 ha 509
        call    RecalibrateFDD
510
        call    SeekTrack
511
        inc     [RecalRepCounter]
2434 Serge 512
        cmp     [RecalRepCounter], 3
1 ha 513
        jb      @@TryAgain
514
;        mov   [flp_status],0
515
@@Exit_2:
516
        popa
517
        ret
518
@@Err_3:
2434 Serge 519
        mov     [flp_status], 0
1 ha 520
        popa
521
        ret
522
 
523
;*******************************************************
3555 Serge 524
;*               ЗАПИСЬ СЕКТОРА ДАННЫХ                 *
525
;* Параметры передаются через глобальные переменные:   *
526
;* FDD_Track - номер дорожки (0-79);                   *
527
;* FDD_Head - номер головки (0-1);                     *
528
;* FDD_Sector - номер сектора (1-18).                  *
529
;* Результат операции заносится в FDC_Status.          *
530
;* В случае успешного выполнения операции записи       *
531
;* содержимое FDD_DataBuffer будет занесено в сектор.  *
1 ha 532
;*******************************************************
533
WriteSector:
534
        pushad
535
        call    save_timer_fdd_motor
4265 Serge 536
; Сбросить флаг прерывания
537
        mov     [FDD_IntFlag], 0
3555 Serge 538
; Установить скорость передачи 500 Кбайт/с
2434 Serge 539
        mov     AX, 0
540
        mov     DX, 03F7h
541
        out     DX, AL
3555 Serge 542
; Инициализировать канал прямого доступа к памяти
2434 Serge 543
        mov     [dmamode], 0x4A
1 ha 544
        call    Init_FDC_DMA
3555 Serge 545
; Подать команду "Запись данных"
546
        mov     AL, 0xC5 ;0x45  ;запись в мультитрековом режиме
1 ha 547
        call    FDCDataOutput
2434 Serge 548
        mov     AL, [FDD_Head]
549
        shl     AL, 2
1 ha 550
        call    FDCDataOutput
2434 Serge 551
        mov     AL, [FDD_Track]
1 ha 552
        call    FDCDataOutput
2434 Serge 553
        mov     AL, [FDD_Head]
1 ha 554
        call    FDCDataOutput
2434 Serge 555
        mov     AL, [FDD_Sector]
1 ha 556
        call    FDCDataOutput
3555 Serge 557
        mov     AL, 2   ;код размера сектора (512 байт)
1 ha 558
        call    FDCDataOutput
3555 Serge 559
        mov     AL, 18; 3Fh  ;число секторов на дорожке
1 ha 560
        call    FDCDataOutput
3555 Serge 561
        mov     AL, 1Bh ;значение GPL
1 ha 562
        call    FDCDataOutput
3555 Serge 563
        mov     AL, 0FFh;значение DTL
1 ha 564
        call    FDCDataOutput
3555 Serge 565
; Ожидаем прерывание по завершении операции
1 ha 566
        call    WaitFDCInterrupt
2434 Serge 567
        cmp     [FDC_Status], FDC_Normal
1 ha 568
        jne     @@Exit_3
3555 Serge 569
; Считываем статус завершения операции
1 ha 570
        call    GetStatusInfo
2434 Serge 571
        test    [FDC_ST0], 11000000b ;11011000b
1 ha 572
        jnz     @@Err_2
2434 Serge 573
        mov     [FDC_Status], FDC_Normal
3555 Serge 574
        jmp     @@Exit_3
2434 Serge 575
@@Err_2:
576
        mov     [FDC_Status], FDC_SectorNotFound
1 ha 577
@@Exit_3:
578
        call    save_timer_fdd_motor
579
        popad
580
        ret
581
 
582
;*******************************************************
3555 Serge 583
;*   ЗАПИСЬ СЕКТОРА (С ПОВТОРЕНИЕМ ОПЕРАЦИИ ПРИ СБОЕ)  *
584
;* Параметры передаются через глобальные переменные:   *
585
;* FDD_Track - номер дорожки (0-79);                   *
586
;* FDD_Head - номер головки (0-1);                     *
587
;* FDD_Sector - номер сектора (1-18).                  *
588
;* Результат операции заносится в FDC_Status.          *
589
;* В случае успешного выполнения операции записи       *
590
;* содержимое FDD_DataBuffer будет занесено в сектор.  *
1 ha 591
;*******************************************************
592
WriteSectWithRetr:
593
        pusha
3555 Serge 594
; Обнулить счетчик повторения операции рекалибровки
2434 Serge 595
        mov     [RecalRepCounter], 0
1 ha 596
@@TryAgain_1:
3555 Serge 597
; Обнулить счетчик повторения операции чтени
2434 Serge 598
        mov     [ReadRepCounter], 0
1 ha 599
@@WriteSector_1:
600
        call    WriteSector
2434 Serge 601
        cmp     [FDC_Status], 0
1 ha 602
        je      @@Exit_4
2434 Serge 603
        cmp     [FDC_Status], 1
1 ha 604
        je      @@Err_4
3555 Serge 605
        ; Троекратное повторение чтени
1 ha 606
        inc     [ReadRepCounter]
2434 Serge 607
        cmp     [ReadRepCounter], 3
1 ha 608
        jb      @@WriteSector_1
3555 Serge 609
        ; Троекратное повторение рекалибровки
1 ha 610
        call    RecalibrateFDD
611
        call    SeekTrack
612
        inc     [RecalRepCounter]
2434 Serge 613
        cmp     [RecalRepCounter], 3
1 ha 614
        jb      @@TryAgain_1
615
@@Exit_4:
616
        popa
617
        ret
618
@@Err_4:
2434 Serge 619
        mov     [flp_status], 0
1 ha 620
        popa
621
        ret
622
 
623
;*********************************************
3555 Serge 624
;* ПОЛУЧИТЬ ИНФОРМАЦИЮ О РЕЗУЛЬТАТЕ ОПЕРАЦИИ *
1 ha 625
;*********************************************
626
GetStatusInfo:
627
        push    AX
628
        call    FDCDataInput
2434 Serge 629
        mov     [FDC_ST0], AL
1 ha 630
        call    FDCDataInput
2434 Serge 631
        mov     [FDC_ST1], AL
1 ha 632
        call    FDCDataInput
2434 Serge 633
        mov     [FDC_ST2], AL
1 ha 634
        call    FDCDataInput
2434 Serge 635
        mov     [FDC_C], AL
1 ha 636
        call    FDCDataInput
2434 Serge 637
        mov     [FDC_H], AL
1 ha 638
        call    FDCDataInput
2434 Serge 639
        mov     [FDC_R], AL
1 ha 640
        call    FDCDataInput
2434 Serge 641
        mov     [FDC_N], AL
1 ha 642
        pop     AX
643
        ret
644