Subversion Repositories Kolibri OS

Rev

Rev 3539 | Rev 4115 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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