Subversion Repositories Kolibri OS

Rev

Rev 7136 | Rev 8055 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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