Subversion Repositories Kolibri OS

Rev

Rev 3771 | Rev 4273 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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