Subversion Repositories Kolibri OS

Rev

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

Rev 4265 Rev 4287
Line 1... Line 1...
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2013. 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: 4265 $
8
$Revision: 4287 $
9
 
9
 
10
 
10
 
Line 18... Line 18...
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
-
 
24
        mov     cx, 128
23
        mov     ecx, 128
25
        cld
24
        cld
26
        rep movsd
25
        rep movsd
27
        ret
26
        ret
Line 28... Line 27...
28
 
27
 
29
;take_data_from_application:   ; взять из приложени
28
;take_data_from_application:   ; взять из приложени
30
;     mov esi,[TASK_BASE]
29
;     mov esi,[TASK_BASE]
31
;     mov esi,[esi+TASKDATA.mem_start]
30
;     mov esi,[esi+TASKDATA.mem_start]
32
;     add esi,ecx
31
;     add esi,ecx
33
take_data_from_application_1:
32
take_data_from_application_1:
34
        mov     edi, FDD_BUFF;FDD_DataBuffer  ;0x40000
-
 
35
        xor     ecx, ecx
33
        mov     edi, FDD_BUFF;FDD_DataBuffer  ;0x40000
36
        mov     cx, 128
34
        mov     ecx, 128
37
        cld
35
        cld
38
        rep movsd
36
        rep movsd
Line 39... Line 37...
39
        ret
37
        ret
Line 120... Line 118...
120
;* ЗАПИСАТЬ БАЙТ В ПОРТ ДАННЫХ FDC *
118
;* ЗАПИСАТЬ БАЙТ В ПОРТ ДАННЫХ FDC *
121
;* Параметры:                      *
119
;* Параметры:                      *
122
;* AL - выводимый байт.            *
120
;* AL - выводимый байт.            *
123
;***********************************
121
;***********************************
124
FDCDataOutput:
122
FDCDataOutput:
-
 
123
;       DEBUGF 1,'K : FDCDataOutput(%x)',al
125
;        pusha
124
;        pusha
126
        push    eax ecx edx
125
        push    eax ecx edx
127
        mov     AH, AL    ;запомнить байт в AH
126
        mov     AH, AL    ;запомнить байт в AH
128
; Сбросить переменную состояния контроллера
127
; Сбросить переменную состояния контроллера
129
        mov     [FDC_Status], FDC_Normal
128
        mov     [FDC_Status], FDC_Normal
Line 135... Line 134...
135
        and     AL, 0C0h  ;выделить разряды 6 и 7
134
        and     AL, 0C0h  ;выделить разряды 6 и 7
136
        cmp     AL, 80h   ;проверить разряды 6 и 7
135
        cmp     AL, 80h   ;проверить разряды 6 и 7
137
        je      @@OutByteToFDC
136
        je      @@OutByteToFDC
138
        loop    @@TestRS
137
        loop    @@TestRS
139
; Ошибка тайм-аута
138
; Ошибка тайм-аута
-
 
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
; Вывести байт в порт данных
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
;        DEBUGF 1,' ok\n'
147
@@End_5:
148
@@End_5:
148
;        popa
149
;        popa
149
        pop     edx ecx eax
150
        pop     edx ecx eax
150
        ret
151
        ret
Line 168... Line 169...
168
        and     AL, 0C0h  ;выдлить разряды 6 и 7
169
        and     AL, 0C0h  ;выдлить разряды 6 и 7
169
        cmp     AL, 0C0h  ;проверить разряды 6 и 7
170
        cmp     AL, 0C0h  ;проверить разряды 6 и 7
170
        je      @@GetByteFromFDC
171
        je      @@GetByteFromFDC
171
        loop    @@TestRS_1
172
        loop    @@TestRS_1
172
; Ошибка тайм-аута
173
; Ошибка тайм-аута
-
 
174
;       DEBUGF 1,'K : FDCDataInput: timeout\n'
173
        mov     [FDC_Status], FDC_TimeOut
175
        mov     [FDC_Status], FDC_TimeOut
174
        jmp     @@End_6
176
        jmp     @@End_6
175
; Ввести байт из порта данных
177
; Ввести байт из порта данных
176
@@GetByteFromFDC:
178
@@GetByteFromFDC:
177
        inc     DX
179
        inc     DX
178
        in      AL, DX
180
        in      AL, DX
-
 
181
;       DEBUGF 1,'K : FDCDataInput: %x\n',al
179
@@End_6:
182
@@End_6:
180
        pop     DX
183
        pop     DX
181
        pop     ECX
184
        pop     ECX
182
        ret
185
        ret
Line 183... Line 186...
183
 
186
 
184
;*********************************************
187
;*********************************************
185
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
188
;* ОБРАБОТЧИК ПРЕРЫВАНИЯ ОТ КОНТРОЛЛЕРА НГМД *
186
;*********************************************
189
;*********************************************
-
 
190
FDCInterrupt:
187
FDCInterrupt:
191
;       dbgstr 'FDCInterrupt'
188
; Установить флаг прерывания
192
; Установить флаг прерывания
189
        mov     [FDD_IntFlag], 1
193
        mov     [FDD_IntFlag], 1
190
        mov     al, 1
194
        mov     al, 1
Line 205... Line 209...
205
        call    change_task
209
        call    change_task
206
        cmp     [FDD_IntFlag], 0
210
        cmp     [FDD_IntFlag], 0
207
        jnz     @@End_7           ;прерывание произошло
211
        jnz     @@End_7           ;прерывание произошло
208
        mov     eax, [timer_ticks]
212
        mov     eax, [timer_ticks]
209
        sub     eax, [TickCounter]
213
        sub     eax, [TickCounter]
210
        cmp     eax, 50 ;25   ;5 ;ожидать 5 тиков
214
        cmp     eax, 200;50 ;25   ;5 ;ожидать 5 тиков
211
        jb      @@TestRS_2
215
        jb      @@TestRS_2
212
;        jl      @@TestRS_2
216
;        jl      @@TestRS_2
213
; Ошибка тайм-аута
217
; Ошибка тайм-аута
-
 
218
;       dbgstr 'WaitFDCInterrupt: timeout'
214
        mov     [FDC_Status], FDC_TimeOut
219
        mov     [FDC_Status], FDC_TimeOut
215
;        mov   [flp_status],0
-
 
216
@@End_7:
220
@@End_7:
217
        popa
221
        popa
218
        ret
222
        ret
Line 219... Line 223...
219
 
223
 
220
;*********************************
224
;*********************************
221
;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" *
225
;* ВКЛЮЧИТЬ МОТОР ДИСКОВОДА "A:" *
222
;*********************************
226
;*********************************
-
 
227
FDDMotorON:
223
FDDMotorON:
228
;       dbgstr 'FDDMotorON'
224
        pusha
229
        pusha
225
;        cmp     [fdd_motor_status],1
230
;        cmp     [fdd_motor_status],1
226
;        je      fdd_motor_on
231
;        je      fdd_motor_on
227
        mov     al, [flp_number]
232
        mov     al, [flp_number]
Line 250... Line 255...
250
        call    change_task
255
        call    change_task
251
        mov     eax, [timer_ticks]
256
        mov     eax, [timer_ticks]
252
        sub     eax, [TickCounter]
257
        sub     eax, [TickCounter]
253
        cmp     eax, 50 ;10
258
        cmp     eax, 50 ;10
254
        jb      @@dT
259
        jb      @@dT
-
 
260
; Read results of RESET command
-
 
261
        push    4
-
 
262
;       DEBUGF 1,'K : floppy reset results:'
-
 
263
@@:
-
 
264
        mov     al, 8
-
 
265
        call    FDCDataOutput
-
 
266
        call    FDCDataInput
-
 
267
;       DEBUGF 1,' %x',al
-
 
268
        call    FDCDataInput
-
 
269
;       DEBUGF 1,' %x',al
-
 
270
        dec     dword [esp]
-
 
271
        jnz     @b
-
 
272
;       DEBUGF 1,'\n'
-
 
273
        pop     eax
255
        cmp     [flp_number], 1
274
        cmp     [flp_number], 1
256
        jne     fdd_motor_on_B
275
        jne     fdd_motor_on_B
257
        mov     [fdd_motor_status], 1
276
        mov     [fdd_motor_status], 1
258
        jmp     fdd_motor_on
277
        jmp     fdd_motor_on
259
fdd_motor_on_B:
278
fdd_motor_on_B:
Line 273... Line 292...
273
 
292
 
274
;*****************************************
293
;*****************************************
275
;*  ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА  *
294
;*  ПРОВЕРКА ЗАДЕРЖКИ ВЫКЛЮЧЕНИЯ МОТОРА  *
276
;*****************************************
295
;*****************************************
277
proc check_fdd_motor_status_has_work?
-
 
278
        cmp     [flp_status], 0
-
 
279
        jnz     .yes
296
proc check_fdd_motor_status_has_work?
280
        cmp     [fdd_motor_status], 0
297
        cmp     [fdd_motor_status], 0
281
        jz      .no
298
        jz      .no
282
        mov     eax, [timer_ticks]
299
        mov     eax, [timer_ticks]
283
        sub     eax, [timer_fdd_motor]
300
        sub     eax, [timer_fdd_motor]
Line 301... Line 318...
301
        cmp     eax, 500
318
        cmp     eax, 500
302
        jb      end_check_fdd_motor_status
319
        jb      end_check_fdd_motor_status
303
        call    FDDMotorOFF
320
        call    FDDMotorOFF
304
        mov     [fdd_motor_status], 0
321
        mov     [fdd_motor_status], 0
305
end_check_fdd_motor_status_1:
322
end_check_fdd_motor_status_1:
306
        mov     [flp_status], 0
-
 
307
end_check_fdd_motor_status:
323
end_check_fdd_motor_status:
308
        ret
324
        ret
Line 309... Line 325...
309
 
325
 
310
;**********************************
326
;**********************************
311
;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА      *
327
;* ВЫКЛЮЧИТЬ МОТОР ДИСКОВОДА      *
312
;**********************************
328
;**********************************
-
 
329
FDDMotorOFF:
313
FDDMotorOFF:
330
;       dbgstr 'FDDMotorOFF'
314
        push    AX
331
        push    AX
315
        push    DX
332
        push    DX
316
        cmp     [flp_number], 1
333
        cmp     [flp_number], 1
317
        jne     FDDMotorOFF_1
334
        jne     FDDMotorOFF_1
Line 321... Line 338...
321
        call    FDDMotorOFF_B
338
        call    FDDMotorOFF_B
322
FDDMotorOFF_2:
339
FDDMotorOFF_2:
323
        pop     DX
340
        pop     DX
324
        pop     AX
341
        pop     AX
325
        ; сброс флагов кеширования в связи с устареванием информации
342
        ; сброс флагов кеширования в связи с устареванием информации
326
        mov     [root_read], 0
343
        or      [floppy_media_flags+0], FLOPPY_MEDIA_NEED_RESCAN
327
        mov     [flp_fat], 0
344
        or      [floppy_media_flags+1], FLOPPY_MEDIA_NEED_RESCAN
328
        ret
345
        ret
Line 329... Line 346...
329
 
346
 
330
FDDMotorOFF_A:
347
FDDMotorOFF_A:
331
        mov     DX, 3F2h;порт управления двигателями
348
        mov     DX, 3F2h;порт управления двигателями
Line 341... Line 358...
341
 
358
 
342
;*******************************
359
;*******************************
343
;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" *
360
;* РЕКАЛИБРОВКА ДИСКОВОДА "A:" *
344
;*******************************
361
;*******************************
-
 
362
RecalibrateFDD:
345
RecalibrateFDD:
363
;       dbgstr 'RecalibrateFDD'
346
        pusha
364
        pusha
-
 
365
        call    save_timer_fdd_motor
-
 
366
; Сбросить флаг прерывания
347
        call    save_timer_fdd_motor
367
        mov     [FDD_IntFlag], 0
348
; Подать команду "Рекалибровка"
368
; Подать команду "Рекалибровка"
349
        mov     AL, 07h
369
        mov     AL, 07h
350
        call    FDCDataOutput
370
        call    FDCDataOutput
351
        mov     AL, 00h
371
        mov     AL, 00h
352
        call    FDCDataOutput
372
        call    FDCDataOutput
353
; Ожидать завершения операции
373
; Ожидать завершения операции
354
        call    WaitFDCInterrupt
374
        call    WaitFDCInterrupt
355
;        cmp    [FDC_Status],0
375
        cmp     [FDC_Status], 0
-
 
376
        jne     .fail
-
 
377
; Read results of RECALIBRATE command
-
 
378
;       DEBUGF 1,'K : floppy recalibrate results:'
356
;        je    no_fdc_status_error
379
        mov     al, 8
-
 
380
        call    FDCDataOutput
-
 
381
        call    FDCDataInput
-
 
382
;       DEBUGF 1,' %x',al
-
 
383
        call    FDCDataInput
357
;        mov   [flp_status],0
384
;       DEBUGF 1,' %x',al
-
 
385
;       DEBUGF 1,'\n'
358
;no_fdc_status_error:
386
.fail:
359
        call    save_timer_fdd_motor
387
        call    save_timer_fdd_motor
360
        popa
388
        popa
Line 361... Line 389...
361
        ret
389
        ret
Line 366... Line 394...
366
;* FDD_Track - номер дорожки (0-79);                 *
394
;* FDD_Track - номер дорожки (0-79);                 *
367
;* FDD_Head - номер головки (0-1).                   *
395
;* FDD_Head - номер головки (0-1).                   *
368
;* Результат операции заносится в FDC_Status.        *
396
;* Результат операции заносится в FDC_Status.        *
369
;*****************************************************
397
;*****************************************************
370
SeekTrack:
398
SeekTrack:
-
 
399
;       dbgstr 'SeekTrack'
371
        pusha
400
        pusha
372
        call    save_timer_fdd_motor
401
        call    save_timer_fdd_motor
373
; Сбросить флаг прерывания
402
; Сбросить флаг прерывания
374
        mov     [FDD_IntFlag], 0
403
        mov     [FDD_IntFlag], 0
375
; Подать команду "Поиск"
404
; Подать команду "Поиск"
Line 400... Line 429...
400
        ; Заданный трек найден?
429
        ; Заданный трек найден?
401
        mov     AL, [FDC_C]
430
        mov     AL, [FDC_C]
402
        cmp     AL, [FDD_Track]
431
        cmp     AL, [FDD_Track]
403
        jne     @@Err
432
        jne     @@Err
404
        ; Номер головки совпадает с заданным?
433
        ; Номер головки совпадает с заданным?
-
 
434
; The H bit (Head Address) in ST0 will always return a "0" (c) 82077AA datasheet,
-
 
435
; description of SEEK command. So we can not verify the proper head.
405
        mov     AL, [FDC_ST0]
436
;        mov     AL, [FDC_ST0]
406
        and     AL, 100b
437
;        and     AL, 100b
407
        shr     AL, 2
438
;        shr     AL, 2
408
        cmp     AL, [FDD_Head]
439
;        cmp     AL, [FDD_Head]
409
        jne     @@Err
440
;        jne     @@Err
410
        ; Операция завершена успешно
441
        ; Операция завершена успешно
-
 
442
;        dbgstr 'SeekTrack: FDC_Normal'
411
        mov     [FDC_Status], FDC_Normal
443
        mov     [FDC_Status], FDC_Normal
412
        jmp     @@Exit
444
        jmp     @@Exit
413
@@Err:  ; Трек не найден
445
@@Err:  ; Трек не найден
-
 
446
;       dbgstr 'SeekTrack: FDC_TrackNotFound'
414
        mov     [FDC_Status], FDC_TrackNotFound
447
        mov     [FDC_Status], FDC_TrackNotFound
415
;        mov   [flp_status],0
-
 
416
@@Exit:
448
@@Exit:
417
        call    save_timer_fdd_motor
449
        call    save_timer_fdd_motor
418
        popa
450
        popa
419
        ret
451
        ret
Line 427... Line 459...
427
;* Результат операции заносится в FDC_Status.          *
459
;* Результат операции заносится в FDC_Status.          *
428
;* В случае успешного выполнения операции чтения       *
460
;* В случае успешного выполнения операции чтения       *
429
;* содержимое сектора будет занесено в FDD_DataBuffer. *
461
;* содержимое сектора будет занесено в FDD_DataBuffer. *
430
;*******************************************************
462
;*******************************************************
431
ReadSector:
463
ReadSector:
-
 
464
;       dbgstr 'ReadSector'
432
        pushad
465
        pushad
433
        call    save_timer_fdd_motor
466
        call    save_timer_fdd_motor
434
; Сбросить флаг прерывания
467
; Сбросить флаг прерывания
435
        mov     [FDD_IntFlag], 0
468
        mov     [FDD_IntFlag], 0
436
; Установить скорость передачи 500 Кбайт/с
469
; Установить скорость передачи 500 Кбайт/с
Line 466... Line 499...
466
        jne     @@Exit_1
499
        jne     @@Exit_1
467
; Считываем статус завершения операции
500
; Считываем статус завершения операции
468
        call    GetStatusInfo
501
        call    GetStatusInfo
469
        test    [FDC_ST0], 11011000b
502
        test    [FDC_ST0], 11011000b
470
        jnz     @@Err_1
503
        jnz     @@Err_1
-
 
504
;        dbgstr 'ReadSector: FDC_Normal'
471
        mov     [FDC_Status], FDC_Normal
505
        mov     [FDC_Status], FDC_Normal
472
        jmp     @@Exit_1
506
        jmp     @@Exit_1
473
@@Err_1:
507
@@Err_1:
-
 
508
;       dbgstr 'ReadSector: FDC_SectorNotFound'
474
        mov     [FDC_Status], FDC_SectorNotFound
509
        mov     [FDC_Status], FDC_SectorNotFound
475
;        mov   [flp_status],0
-
 
476
@@Exit_1:
510
@@Exit_1:
477
        call    save_timer_fdd_motor
511
        call    save_timer_fdd_motor
478
        popad
512
        popad
479
        ret
513
        ret
Line 509... Line 543...
509
        call    RecalibrateFDD
543
        call    RecalibrateFDD
510
        call    SeekTrack
544
        call    SeekTrack
511
        inc     [RecalRepCounter]
545
        inc     [RecalRepCounter]
512
        cmp     [RecalRepCounter], 3
546
        cmp     [RecalRepCounter], 3
513
        jb      @@TryAgain
547
        jb      @@TryAgain
514
;        mov   [flp_status],0
-
 
515
@@Exit_2:
548
@@Exit_2:
516
        popa
549
        popa
517
        ret
550
        ret
518
@@Err_3:
551
@@Err_3:
519
        mov     [flp_status], 0
-
 
520
        popa
552
        popa
521
        ret
553
        ret
Line 522... Line 554...
522
 
554
 
523
;*******************************************************
555
;*******************************************************
Line 529... Line 561...
529
;* Результат операции заносится в FDC_Status.          *
561
;* Результат операции заносится в FDC_Status.          *
530
;* В случае успешного выполнения операции записи       *
562
;* В случае успешного выполнения операции записи       *
531
;* содержимое FDD_DataBuffer будет занесено в сектор.  *
563
;* содержимое FDD_DataBuffer будет занесено в сектор.  *
532
;*******************************************************
564
;*******************************************************
533
WriteSector:
565
WriteSector:
-
 
566
;       dbgstr 'WriteSector'
534
        pushad
567
        pushad
535
        call    save_timer_fdd_motor
568
        call    save_timer_fdd_motor
536
; Сбросить флаг прерывания
569
; Сбросить флаг прерывания
537
        mov     [FDD_IntFlag], 0
570
        mov     [FDD_IntFlag], 0
538
; Установить скорость передачи 500 Кбайт/с
571
; Установить скорость передачи 500 Кбайт/с
Line 614... Line 647...
614
        jb      @@TryAgain_1
647
        jb      @@TryAgain_1
615
@@Exit_4:
648
@@Exit_4:
616
        popa
649
        popa
617
        ret
650
        ret
618
@@Err_4:
651
@@Err_4:
619
        mov     [flp_status], 0
-
 
620
        popa
652
        popa
621
        ret
653
        ret
Line 622... Line 654...
622
 
654
 
623
;*********************************************
655
;*********************************************
Line 640... Line 672...
640
        call    FDCDataInput
672
        call    FDCDataInput
641
        mov     [FDC_N], AL
673
        mov     [FDC_N], AL
642
        pop     AX
674
        pop     AX
643
        ret
675
        ret
Line -... Line 676...
-
 
676
 
-
 
677
; Interface for disk subsystem.
-
 
678
; Assume fixed capacity for 1.44M.
-
 
679
FLOPPY_CAPACITY = 2880  ; in sectors
-
 
680
 
-
 
681
iglobal
-
 
682
align 4
-
 
683
floppy_functions:
-
 
684
        dd      .size
-
 
685
        dd      0       ; no close() function
-
 
686
        dd      0       ; no closemedia() function
-
 
687
        dd      floppy_querymedia
-
 
688
        dd      floppy_read
-
 
689
        dd      floppy_write
-
 
690
        dd      0       ; no flush() function
-
 
691
        dd      0       ; no adjust_cache_size() function
-
 
692
.size = $ - floppy_functions
-
 
693
endg
-
 
694
 
-
 
695
uglobal
-
 
696
floppy_media_flags      rb      2
-
 
697
n_sector    dd 0  ; temporary save for sector value
-
 
698
flp_number  db 0  ; 1- Floppy A, 2-Floppy B
-
 
699
old_track   db 0  ; old value track
-
 
700
flp_label   rb 15*2 ; Label and ID of inserted floppy disk
-
 
701
align 4
-
 
702
; Hardware does not allow to work with two floppies in parallel,
-
 
703
; so there is one mutex guarding access to any floppy.
-
 
704
floppy_mutex    MUTEX
-
 
705
endg
-
 
706
; Meaning of bits in floppy_media_flags
-
 
707
FLOPPY_MEDIA_PRESENT = 1        ; media was present when last asked
-
 
708
FLOPPY_MEDIA_NEED_RESCAN = 2    ; media was possibly changed, need to rescan
-
 
709
FLOPPY_MEDIA_LABEL_CHANGED = 4  ; temporary state
-
 
710
 
-
 
711
iglobal
-
 
712
floppy1_name    db      'fd',0
-
 
713
floppy2_name    db      'fd2',0
-
 
714
endg
-
 
715
 
-
 
716
; This function is called in boot process.
-
 
717
; It creates filesystems /fd and/or /fd2, if the system has one/two floppy drives.
-
 
718
proc floppy_init
-
 
719
        mov     ecx, floppy_mutex
-
 
720
        call    mutex_init
-
 
721
; First floppy is present if [DRIVE_DATA] and 0xF0 is nonzero.
-
 
722
        test    byte [DRIVE_DATA], 0xF0
-
 
723
        jz      .no1
-
 
724
        stdcall disk_add, floppy_functions, floppy1_name, 1, DISK_NO_INSERT_NOTIFICATION
-
 
725
.no1:
-
 
726
; Second floppy is present if [DRIVE_DATA] and 0x0F is nonzero.
-
 
727
        test    byte [DRIVE_DATA], 0x0F
-
 
728
        jz      .no2
-
 
729
        stdcall disk_add, floppy_functions, floppy2_name, 2, DISK_NO_INSERT_NOTIFICATION
-
 
730
.no2:
-
 
731
        ret
-
 
732
endp
-
 
733
 
-
 
734
; Returns information about disk media.
-
 
735
; Floppy drives do not support insert notifications,
-
 
736
; DISK_NO_INSERT_NOTIFICATION is set,
-
 
737
; the disk subsystem calls this function before each filesystem operation.
-
 
738
; If the media has changed, return error for the first call as signal
-
 
739
; to finalize work with old media and the true geometry for the second call.
-
 
740
; Assume that media is (possibly) changed anytime when motor is off.
-
 
741
proc floppy_querymedia
-
 
742
  virtual at esp+4
-
 
743
    .userdata dd ?
-
 
744
    .info dd ?
-
 
745
  end virtual
-
 
746
; 1. Acquire the global lock.
-
 
747
        mov     ecx, floppy_mutex
-
 
748
        call    mutex_lock
-
 
749
        mov     edx, [.userdata]        ; 1 for /fd, 2 for /fd2
-
 
750
; 2. If the media was reported and has been changed, forget it and report an error.
-
 
751
        mov     al, [floppy_media_flags+edx-1]
-
 
752
        and     al, FLOPPY_MEDIA_PRESENT + FLOPPY_MEDIA_NEED_RESCAN
-
 
753
        cmp     al, FLOPPY_MEDIA_PRESENT + FLOPPY_MEDIA_NEED_RESCAN
-
 
754
        jnz     .not_reported
-
 
755
.no_media:
-
 
756
        mov     [floppy_media_flags+edx-1], 0
-
 
757
.return_no_media:
-
 
758
        mov     ecx, floppy_mutex
-
 
759
        call    mutex_unlock
-
 
760
        mov     eax, DISK_STATUS_NO_MEDIA
-
 
761
        retn    8
-
 
762
.not_reported:
-
 
763
; 3. If we are in the temporary state LABEL_CHANGED, this is the second call
-
 
764
; after intermediate DISK_STATUS_NO_MEDIA due to media change;
-
 
765
; clear the flag and return the current geometry without rereading the bootsector.
-
 
766
        cmp     [floppy_media_flags+edx-1], FLOPPY_MEDIA_LABEL_CHANGED
-
 
767
        jz      .report_geometry
-
 
768
; 4. Try to read the bootsector.
-
 
769
        mov     [flp_number], dl
-
 
770
        mov     [FDC_Status], 0
-
 
771
        call    floppy_read_bootsector
-
 
772
; 5. If reading bootsector failed, assume that media is not present.
-
 
773
        mov     edx, [.userdata]
-
 
774
        cmp     [FDC_Status], 0
-
 
775
        jnz     .no_media
-
 
776
; 6. Check whether the previous status is "present". If not, go to 10.
-
 
777
        push    esi edi
-
 
778
        imul    edi, edx, 15
-
 
779
        add     edi, flp_label-15
-
 
780
        mov     esi, FDD_BUFF+39
-
 
781
        mov     ecx, 15
-
 
782
        test    [floppy_media_flags+edx-1], FLOPPY_MEDIA_PRESENT
-
 
783
        jz      .set_label
-
 
784
; 7. Compare the old label with the current one.
-
 
785
        rep cmpsb
-
 
786
; 8. If the label has not changed, go to 11.
-
 
787
        jz      .ok
-
 
788
; 9. If the label has changed, store it, enter temporary state LABEL_CHANGED
-
 
789
; and report DISK_STATUS_NO_MEDIA.
-
 
790
;       dbgstr 'floppy label changed'
-
 
791
        add     esi, ecx
-
 
792
        add     edi, ecx
-
 
793
        mov     ecx, 15
-
 
794
        sub     esi, ecx
-
 
795
        sub     edi, ecx
-
 
796
        rep movsb
-
 
797
        mov     [floppy_media_flags+edx-1], FLOPPY_MEDIA_LABEL_CHANGED
-
 
798
        pop     edi esi
-
 
799
        jmp     .return_no_media
-
 
800
.set_label:
-
 
801
; 10. The previous state was "not present". Copy the label.
-
 
802
        rep movsb
-
 
803
.ok:
-
 
804
        pop     edi esi
-
 
805
.report_geometry:
-
 
806
; 11. Fill DISKMEDIAINFO structure.
-
 
807
        mov     ecx, [.info]
-
 
808
        and     [ecx+DISKMEDIAINFO.Flags], 0
-
 
809
        mov     [ecx+DISKMEDIAINFO.SectorSize], 512
-
 
810
        mov     dword [ecx+DISKMEDIAINFO.Capacity], FLOPPY_CAPACITY
-
 
811
        and     dword [ecx+DISKMEDIAINFO.Capacity+4], 0
-
 
812
; 12. Update state: media is present, data are actual.
-
 
813
        mov     [floppy_media_flags+edx-1], FLOPPY_MEDIA_PRESENT
-
 
814
; 13. Release the global lock and return successful status.
-
 
815
        mov     ecx, floppy_mutex
-
 
816
        call    mutex_unlock
-
 
817
        xor     eax, eax
-
 
818
        retn    8
-
 
819
endp
-
 
820
 
-
 
821
proc floppy_read_bootsector
-
 
822
        pushad
-
 
823
        mov     [FDD_Track], 0; Цилиндр
-
 
824
        mov     [FDD_Head], 0; Сторона
-
 
825
        mov     [FDD_Sector], 1; Сектор
-
 
826
        call    FDDMotorON
-
 
827
        call    RecalibrateFDD
-
 
828
        cmp     [FDC_Status], 0
-
 
829
        jne     .nothing
-
 
830
        call    SeekTrack
-
 
831
        cmp     [FDC_Status], 0
-
 
832
        jne     .nothing
-
 
833
        call    ReadSectWithRetr
-
 
834
.nothing:
-
 
835
        popad
-
 
836
        ret
-
 
837
endp
-
 
838
 
-
 
839
read_chs_sector:
-
 
840
        call    calculate_chs
-
 
841
        call    ReadSectWithRetr
-
 
842
        ret
-
 
843
 
-
 
844
save_chs_sector:
-
 
845
        call    calculate_chs
-
 
846
        call    WriteSectWithRetr
-
 
847
        ret
-
 
848
 
-
 
849
calculate_chs:
-
 
850
        mov     bl, [FDD_Track]
-
 
851
        mov     [old_track], bl
-
 
852
        mov     ebx, 18
-
 
853
        xor     edx, edx
-
 
854
        div     ebx
-
 
855
        inc     edx
-
 
856
        mov     [FDD_Sector], dl
-
 
857
        mov     edx, eax
-
 
858
        shr     eax, 1
-
 
859
        and     edx, 1
-
 
860
        mov     [FDD_Track], al
-
 
861
        mov     [FDD_Head], dl
-
 
862
        mov     dl, [old_track]
-
 
863
        cmp     dl, [FDD_Track]
-
 
864
        je      no_seek_track_1
-
 
865
        call    SeekTrack
-
 
866
no_seek_track_1:
-
 
867
        ret
-
 
868
 
-
 
869
; Writes one or more sectors to the device.
-
 
870
proc floppy_write
-
 
871
        mov     dl, 1
-
 
872
        jmp     floppy_read_write
-
 
873
endp
-
 
874
 
-
 
875
; Reads one or more sectors from the device.
-
 
876
proc floppy_read
-
 
877
        mov     dl, 0
-
 
878
endp
-
 
879
 
-
 
880
; Common part of floppy_read and floppy_write.
-
 
881
proc floppy_read_write userdata:dword, buffer:dword, start_sector:qword, numsectors_ptr:dword
-
 
882
virtual at ebp-8
-
 
883
.sectors_todo   dd      ?
-
 
884
.operation      db      ?
-
 
885
end virtual
-
 
886
        push    edx             ; save operation code to [.operation]
-
 
887
; 1. Get number of sectors to read/write
-
 
888
; and zero number of sectors that were actually read/written.
-
 
889
        mov     eax, [numsectors_ptr]
-
 
890
        push    dword [eax]     ; initialize [.sectors_todo]
-
 
891
        and     dword [eax], 0
-
 
892
        push    ebx esi edi     ; save used registers to be stdcall
-
 
893
; 2. Acquire the global lock.
-
 
894
        mov     ecx, floppy_mutex
-
 
895
        call    mutex_lock
-
 
896
; 3. Set floppy number for this operation.
-
 
897
        mov     edx, [userdata]
-
 
898
        mov     [flp_number], dl
-
 
899
; 4. Read/write sector-by-sector.
-
 
900
.operation_loop:
-
 
901
; 4a. Check that the sector is inside the media.
-
 
902
        cmp     dword [start_sector+4], 0
-
 
903
        jnz     .end_of_media
-
 
904
        mov     eax, dword [start_sector]
-
 
905
        cmp     eax, FLOPPY_CAPACITY
-
 
906
        jae     .end_of_media
-
 
907
; 4b. For read operation, call read_chs_sector and then move data from FDD_BUFF to [buffer].
-
 
908
; For write operation, move data from [buffer] to FDD_BUFF and then call save_chs_sector.
-
 
909
        cmp     [.operation], 0
-
 
910
        jz      .read
-
 
911
        mov     esi, [buffer]
-
 
912
        mov     edi, FDD_BUFF
-
 
913
        mov     ecx, 512/4
-
 
914
        rep movsd
-
 
915
        mov     [buffer], esi
-
 
916
        call    save_chs_sector
-
 
917
        jmp     @f
-
 
918
.read:
-
 
919
        call    read_chs_sector
-
 
920
        mov     esi, FDD_BUFF
-
 
921
        mov     edi, [buffer]
-
 
922
        mov     ecx, 512/4
-
 
923
        rep movsd
-
 
924
        mov     [buffer], edi
-
 
925
@@:
-
 
926
; 4c. If there was an error, propagate it to the caller.
-
 
927
        cmp     [FDC_Status], 0
-
 
928
        jnz     .fail
-
 
929
; 4d. Otherwise, increment number of sectors processed and continue the loop.
-
 
930
        mov     eax, [numsectors_ptr]
-
 
931
        inc     dword [eax]
-
 
932
        inc     dword [start_sector]
-
 
933
        dec     [.sectors_todo]
-
 
934
        jnz     .operation_loop
-
 
935
; 5. Release the global lock and return with the correct status.
-
 
936
        push    0
-
 
937
.return:
-
 
938
        mov     ecx, floppy_mutex
-
 
939
        call    mutex_unlock
-
 
940
        pop     eax
-
 
941
        pop     edi esi ebx     ; restore used registers to be stdcall
-
 
942
        ret     ; this translates to leave/retn N and purges local variables
-
 
943
.fail:
-
 
944
        push    -1
-
 
945
        jmp     .return
-
 
946
.end_of_media:
-
 
947
        push    DISK_STATUS_END_OF_MEDIA
-
 
948
        jmp     .return