Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 3539 $
9
 
10
 
11
; Low-level driver for HDD access
12
; DMA support by Mario79
13
; Access through BIOS by diamond
14
 
15
align 4
16
hd_read:
17
;-----------------------------------------------------------
18
; input  : eax = block to read
19
;          ebx = destination
20
;-----------------------------------------------------------
21
        and     [hd_error], 0
22
        push    ecx esi edi     ; scan cache
23
 
24
;    mov   ecx,cache_max         ; entries in cache
25
;    mov   esi,HD_CACHE+8
26
        call    calculate_cache
27
        add     esi, 8
28
 
29
        mov     edi, 1
30
 
31
  hdreadcache:
32
 
33
        cmp     dword [esi+4], 0; empty
34
        je      nohdcache
35
 
36
        cmp     [esi], eax      ; correct sector
37
        je      yeshdcache
38
 
39
  nohdcache:
40
 
41
        add     esi, 8
42
        inc     edi
43
        dec     ecx
44
        jnz     hdreadcache
45
 
46
        call    find_empty_slot ; ret in edi
47
        cmp     [hd_error], 0
48
        jne     return_01
49
; Read through BIOS?
50
        cmp     [hdpos], 0x80
51
        jae     .bios
52
; hd_read_{dma,pio} use old ATA with 28 bit for sector number
53
        cmp     eax, 0x10000000
54
        jb      @f
55
        inc     [hd_error]
56
        jmp     return_01
57
@@:
58
; DMA read is permitted if [allow_dma_access]=1 or 2
59
        cmp     [allow_dma_access], 2
60
        ja      .nodma
61
        cmp     [dma_hdd], 1
62
        jnz     .nodma
63
        call    hd_read_dma
64
        jmp     @f
65
.nodma:
66
        call    hd_read_pio
67
        jmp     @f
68
.bios:
69
        call    bd_read
70
@@:
71
        cmp     [hd_error], 0
72
        jne     return_01
73
;    lea   esi,[edi*8+HD_CACHE]
74
;    push  eax
75
        call    calculate_cache_1
76
        lea     esi, [edi*8+esi]
77
;    pop   eax
78
 
79
        mov     [esi], eax      ; sector number
80
        mov     dword [esi+4], 1; hd read - mark as same as in hd
81
 
82
  yeshdcache:
83
 
84
        mov     esi, edi
85
        shl     esi, 9
86
;    add   esi,HD_CACHE+65536
87
        push    eax
88
        call    calculate_cache_2
89
        add     esi, eax
90
        pop     eax
91
 
92
        mov     edi, ebx
93
        mov     ecx, 512/4
94
        cld
95
        rep movsd               ; move data
96
 return_01:
97
        pop     edi esi ecx
98
        ret
99
 
100
align 4
101
hd_read_pio:
102
        push    eax edx
103
 
104
        call    wait_for_hd_idle
105
        cmp     [hd_error], 0
106
        jne     hd_read_error
107
 
108
        cli
109
        xor     eax, eax
110
        mov     edx, [hdbase]
111
        inc     edx
3539 clevermous 112
        out     dx, al; ATAFeatures регистр "особенностей"
2288 clevermous 113
        inc     edx
114
        inc     eax
3539 clevermous 115
        out     dx, al; ATASectorCount счётчик секторов
2288 clevermous 116
        inc     edx
117
        mov     eax, [esp+4]
3539 clevermous 118
        out     dx, al; ATASectorNumber регистр номера сектора
2288 clevermous 119
        shr     eax, 8
120
        inc     edx
3539 clevermous 121
        out     dx, al; ATACylinder номер цилиндра (младший байт)
2288 clevermous 122
        shr     eax, 8
123
        inc     edx
3539 clevermous 124
        out     dx, al; номер цилиндра (старший байт)
2288 clevermous 125
        shr     eax, 8
126
        inc     edx
127
        and     al, 1+2+4+8
128
        add     al, byte [hdid]
129
        add     al, 128+64+32
3539 clevermous 130
        out     dx, al; номер головки/номер диска
2288 clevermous 131
        inc     edx
132
        mov     al, 20h
3539 clevermous 133
        out     dx, al; ATACommand регистр команд
2288 clevermous 134
        sti
135
 
136
        call    wait_for_sector_buffer
137
 
138
        cmp     [hd_error], 0
139
        jne     hd_read_error
140
 
141
        cli
142
        push    edi
143
        shl     edi, 9
144
;    add   edi,HD_CACHE+65536
145
        push    eax
146
        call    calculate_cache_2
147
        add     edi, eax
148
        pop     eax
149
 
150
        mov     ecx, 256
151
        mov     edx, [hdbase]
152
        cld
153
        rep insw
154
        pop     edi
155
        sti
156
 
157
        pop     edx eax
158
        ret
159
 
160
disable_ide_int:
161
;        mov edx,[hdbase]
162
;        add edx,0x206
163
;        mov al,2
164
;        out dx,al
165
        cli
166
        ret
167
 
168
enable_ide_int:
169
;        mov edx,[hdbase]
170
;        add edx,0x206
171
;        mov al,0
172
;        out dx,al
173
        sti
174
        ret
175
 
176
align 4
177
hd_write:
178
;-----------------------------------------------------------
179
; input  : eax = block
180
;          ebx = pointer to memory
181
;-----------------------------------------------------------
182
        push    ecx esi edi
183
 
184
    ; check if the cache already has the sector and overwrite it
185
 
186
;    mov   ecx,cache_max
187
;    mov   esi,HD_CACHE+8
188
        call    calculate_cache
189
        add     esi, 8
190
 
191
        mov     edi, 1
192
 
193
  hdwritecache:
194
 
195
        cmp     dword [esi+4], 0; if cache slot is empty
196
        je      not_in_cache_write
197
 
198
        cmp     [esi], eax      ; if the slot has the sector
199
        je      yes_in_cache_write
200
 
201
  not_in_cache_write:
202
 
203
        add     esi, 8
204
        inc     edi
205
        dec     ecx
206
        jnz     hdwritecache
207
 
208
    ; sector not found in cache
209
    ; write the block to a new location
210
 
211
        call    find_empty_slot ; ret in edi
212
        cmp     [hd_error], 0
213
        jne     hd_write_access_denied
214
 
215
;    lea   esi,[edi*8+HD_CACHE]
216
;    push  eax
217
        call    calculate_cache_1
218
        lea     esi, [edi*8+esi]
219
;    pop   eax
220
 
221
        mov     [esi], eax      ; sector number
222
 
223
  yes_in_cache_write:
224
 
225
        mov     dword [esi+4], 2; write - differs from hd
226
 
227
        shl     edi, 9
228
;    add   edi,HD_CACHE+65536
229
        push    eax
230
        call    calculate_cache_2
231
        add     edi, eax
232
        pop     eax
233
 
234
        mov     esi, ebx
235
        mov     ecx, 512/4
236
        cld
237
        rep movsd               ; move data
238
 hd_write_access_denied:
239
        pop     edi esi ecx
240
        ret
241
 
242
align 4
243
cache_write_pio:
244
        cmp     dword[esi], 0x10000000
245
        jae     .bad
246
;    call  disable_ide_int
247
 
248
        call    wait_for_hd_idle
249
        cmp     [hd_error], 0
250
        jne     hd_write_error
251
 
252
        cli
253
        xor     eax, eax
254
        mov     edx, [hdbase]
255
        inc     edx
256
        out     dx, al
257
        inc     edx
258
        inc     eax
259
        out     dx, al
260
        inc     edx
261
        mov     eax, [esi]      ; eax = sector to write
262
        out     dx, al
263
        shr     eax, 8
264
        inc     edx
265
        out     dx, al
266
        shr     eax, 8
267
        inc     edx
268
        out     dx, al
269
        shr     eax, 8
270
        inc     edx
271
        and     al, 1+2+4+8
272
        add     al, byte [hdid]
273
        add     al, 128+64+32
274
        out     dx, al
275
        inc     edx
276
        mov     al, 30h
277
        out     dx, al
278
        sti
279
 
280
        call    wait_for_sector_buffer
281
 
282
        cmp     [hd_error], 0
283
        jne     hd_write_error
284
 
285
        push    ecx esi
286
 
287
        cli
288
        mov     esi, edi
289
        shl     esi, 9
290
;    add   esi,HD_CACHE+65536    ; esi = from memory position
291
        push    eax
292
        call    calculate_cache_2
293
        add     esi, eax
294
        pop     eax
295
 
296
        mov     ecx, 256
297
        mov     edx, [hdbase]
298
        cld
299
        rep outsw
300
        sti
301
 
302
;    call  enable_ide_int
303
        pop     esi ecx
304
 
305
        ret
306
.bad:
307
        inc     [hd_error]
308
        ret
309
 
310
save_hd_wait_timeout:
311
 
312
        push    eax
313
        mov     eax, [timer_ticks]
314
        add     eax, 300        ; 3 sec timeout
315
        mov     [hd_wait_timeout], eax
316
        pop     eax
317
        ret
318
 
319
align 4
320
check_hd_wait_timeout:
321
 
322
        push    eax
323
        mov     eax, [hd_wait_timeout]
324
        cmp     [timer_ticks], eax
325
        jg      hd_timeout_error
326
        pop     eax
327
        mov     [hd_error], 0
328
        ret
329
 
330
;iglobal
331
;  hd_timeout_str   db 'K : FS - HD timeout',0
332
;  hd_read_str      db 'K : FS - HD read error',0
333
;  hd_write_str     db 'K : FS - HD write error',0
334
;  hd_lba_str       db 'K : FS - HD LBA error',0
335
;endg
336
 
337
hd_timeout_error:
338
 
339
;    call  clear_hd_cache
340
;    call  clear_application_table_status
341
;    mov   esi,hd_timeout_str
342
;    call  sys_msg_board_str
3309 esevece 343
    if lang eq sp
344
    DEBUGF 1,"K : FS - HD tiempo de espera agotado\n"
345
    else
2288 clevermous 346
    DEBUGF 1,"K : FS - HD timeout\n"
3309 esevece 347
    end if
2288 clevermous 348
 
349
        mov     [hd_error], 1
350
        pop     eax
351
        ret
352
 
353
hd_read_error:
354
 
355
;    call  clear_hd_cache
356
;    call  clear_application_table_status
357
;    mov   esi,hd_read_str
358
;    call  sys_msg_board_str
3309 esevece 359
    if lang eq sp
360
    DEBUGF 1,"K : FS - HD error de lectura\n"
361
    else
2288 clevermous 362
    DEBUGF 1,"K : FS - HD read error\n"
3309 esevece 363
    end if
2288 clevermous 364
        pop     edx eax
365
        ret
366
 
367
hd_write_error:
368
 
369
;    call  clear_hd_cache
370
;    call  clear_application_table_status
371
;     mov   esi,hd_write_str
372
;     call  sys_msg_board_str
3309 esevece 373
    if lang eq sp
374
    DEBUGF 1,"K : FS - HD error de escritura\n"
375
    else
2288 clevermous 376
    DEBUGF 1,"K : FS - HD write error\n"
3309 esevece 377
    end if
2288 clevermous 378
        ret
379
 
380
hd_write_error_dma:
381
;        call    clear_hd_cache
382
;        call    clear_application_table_status
383
;        mov     esi, hd_write_str
384
;        call    sys_msg_board_str
3309 esevece 385
        if lang eq sp
386
        DEBUGF 1,"K : FS - HD error de escritura\n"
387
        else
388
        DEBUGF 1,"K : FS - HD write error\n"
389
        end if
2288 clevermous 390
        pop     esi
391
        ret
392
 
393
hd_lba_error:
394
;    call  clear_hd_cache
395
;    call  clear_application_table_status
396
;    mov   esi,hd_lba_str
397
;    call  sys_msg_board_str
3309 esevece 398
     if lang eq sp
399
     DEBUGF 1,"K : FS - HD error en LBA\n"
400
     else
2288 clevermous 401
     DEBUGF 1,"K : FS - HD LBA error\n"
3309 esevece 402
     end if
2288 clevermous 403
        jmp     LBA_read_ret
404
 
405
 
406
align 4
407
wait_for_hd_idle:
408
 
409
        push    eax edx
410
 
411
        call    save_hd_wait_timeout
412
 
413
        mov     edx, [hdbase]
414
        add     edx, 0x7
415
 
416
  wfhil1:
417
 
418
        call    check_hd_wait_timeout
419
        cmp     [hd_error], 0
420
        jne     @f
421
 
422
        in      al, dx
423
        test    al, 128
424
        jnz     wfhil1
425
 
426
 @@:
427
 
428
        pop     edx eax
429
        ret
430
 
431
 
432
align 4
433
wait_for_sector_buffer:
434
 
435
        push    eax edx
436
 
437
        mov     edx, [hdbase]
438
        add     edx, 0x7
439
 
440
        call    save_hd_wait_timeout
441
 
442
  hdwait_sbuf:                  ; wait for sector buffer to be ready
443
 
444
        call    check_hd_wait_timeout
445
        cmp     [hd_error], 0
446
        jne     @f
447
 
448
        in      al, dx
449
        test    al, 8
450
        jz      hdwait_sbuf
451
 
452
        mov     [hd_error], 0
453
 
454
        cmp     [hd_setup], 1   ; do not mark error for setup request
455
        je      buf_wait_ok
456
 
457
        test    al, 1           ; previous command ended up with an error
458
        jz      buf_wait_ok
459
 @@:
460
        mov     [hd_error], 1
461
 
462
  buf_wait_ok:
463
 
464
        pop     edx eax
465
        ret
466
 
467
; \begin{Mario79}
468
align 4
469
wait_for_sector_dma_ide0:
470
        push    eax
471
        push    edx
472
        call    save_hd_wait_timeout
473
.wait:
474
        call    change_task
475
        cmp     [irq14_func], hdd_irq14
476
        jnz     .done
477
        call    check_hd_wait_timeout
478
        cmp     [hd_error], 0
479
        jz      .wait
480
        mov     [irq14_func], hdd_irq_null
481
        mov     dx, [IDEContrRegsBaseAddr]
482
        mov     al, 0
483
        out     dx, al
484
.done:
485
        pop     edx
486
        pop     eax
487
        ret
488
 
489
align 4
490
wait_for_sector_dma_ide1:
491
        push    eax
492
        push    edx
493
        call    save_hd_wait_timeout
494
.wait:
495
        call    change_task
496
        cmp     [irq15_func], hdd_irq15
497
        jnz     .done
498
        call    check_hd_wait_timeout
499
        cmp     [hd_error], 0
500
        jz      .wait
501
        mov     [irq15_func], hdd_irq_null
502
        mov     dx, [IDEContrRegsBaseAddr]
503
        add     dx, 8
504
        mov     al, 0
505
        out     dx, al
506
.done:
507
        pop     edx
508
        pop     eax
509
        ret
510
 
511
iglobal
512
align 4
513
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
514
IDE_descriptor_table:
515
        dd      IDE_DMA
516
        dw      0x2000
517
        dw      0x8000
518
 
519
dma_cur_sector  dd      not 40h
520
dma_hdpos       dd      0
521
irq14_func      dd      hdd_irq_null
522
irq15_func      dd      hdd_irq_null
523
endg
524
 
525
uglobal
526
; all uglobals are zeroed at boot
527
dma_process     dd      0
528
dma_slot_ptr    dd      0
529
cache_chain_pos dd      0
530
cache_chain_ptr dd      0
531
cache_chain_size        db      0
532
cache_chain_started     db      0
533
dma_task_switched       db      0
534
dma_hdd         db      0
535
allow_dma_access db      0
536
endg
537
 
538
align 4
539
hdd_irq14:
540
        pushfd
541
        cli
542
        pushad
543
        mov     [irq14_func], hdd_irq_null
544
        mov     dx, [IDEContrRegsBaseAddr]
545
        mov     al, 0
546
        out     dx, al
547
;        call    update_counters
548
;        mov     ebx, [dma_process]
549
;        cmp     [CURRENT_TASK], ebx
550
;        jz      .noswitch
551
;        mov     [dma_task_switched], 1
552
;        mov     edi, [dma_slot_ptr]
553
;        mov     eax, [CURRENT_TASK]
554
;        mov     [dma_process], eax
555
;        mov     eax, [TASK_BASE]
556
;        mov     [dma_slot_ptr], eax
557
;        mov     [CURRENT_TASK], ebx
558
;        mov     [TASK_BASE], edi
559
;        mov     byte [DONT_SWITCH], 1
560
;        call    do_change_task
561
.noswitch:
562
        popad
563
        popfd
564
align 4
565
hdd_irq_null:
566
        ret
567
 
568
align 4
569
hdd_irq15:
570
        pushfd
571
        cli
572
        pushad
573
        mov     [irq15_func], hdd_irq_null
574
        mov     dx, [IDEContrRegsBaseAddr]
575
        add     dx, 8
576
        mov     al, 0
577
        out     dx, al
578
;        call    update_counters
579
;        mov     ebx, [dma_process]
580
;        cmp     [CURRENT_TASK], ebx
581
;        jz      .noswitch
582
;        mov     [dma_task_switched], 1
583
;        mov     edi, [dma_slot_ptr]
584
;        mov     eax, [CURRENT_TASK]
585
;        mov     [dma_process], eax
586
;        mov     eax, [TASK_BASE]
587
;        mov     [dma_slot_ptr], eax
588
;        mov     [CURRENT_TASK], ebx
589
;        mov     [TASK_BASE], edi
590
;        mov     byte [DONT_SWITCH], 1
591
;        call    do_change_task
592
.noswitch:
593
        popad
594
        popfd
595
        ret
596
 
597
align 4
598
hd_read_dma:
599
        push    eax
600
        push    edx
601
        mov     edx, [dma_hdpos]
602
        cmp     edx, [hdpos]
603
        jne     .notread
604
        mov     edx, [dma_cur_sector]
605
        cmp     eax, edx
606
        jb      .notread
607
        add     edx, 15
608
        cmp     [esp+4], edx
609
        ja      .notread
610
        mov     eax, [esp+4]
611
        sub     eax, [dma_cur_sector]
612
        shl     eax, 9
613
        add     eax, (OS_BASE+IDE_DMA)
614
        push    ecx esi edi
615
        mov     esi, eax
616
        shl     edi, 9
617
;        add     edi, HD_CACHE+0x10000
618
        push    eax
619
        call    calculate_cache_2
620
        add     edi, eax
621
        pop     eax
622
 
623
        mov     ecx, 512/4
624
        cld
625
        rep movsd
626
        pop     edi esi ecx
627
        pop     edx
628
        pop     eax
629
        ret
630
.notread:
631
        mov     eax, IDE_descriptor_table
632
        mov     dword [eax], IDE_DMA
633
        mov     word [eax+4], 0x2000
634
        sub     eax, OS_BASE
635
        mov     dx, [IDEContrRegsBaseAddr]
636
        cmp     [hdbase], 0x1F0
637
        jz      @f
638
        add     edx, 8
639
@@:
640
        push    edx
641
        add     edx, 4
642
        out     dx, eax
643
        pop     edx
644
        mov     al, 0
645
        out     dx, al
646
        add     edx, 2
647
        mov     al, 6
648
        out     dx, al
649
        call    wait_for_hd_idle
650
        cmp     [hd_error], 0
651
        jnz     hd_read_error
652
        call    disable_ide_int
653
        xor     eax, eax
654
        mov     edx, [hdbase]
655
        inc     edx
656
        out     dx, al
657
        inc     edx
658
        mov     eax, 10h
659
        out     dx, al
660
        inc     edx
661
        mov     eax, [esp+4]
662
        out     dx, al
663
        shr     eax, 8
664
        inc     edx
665
        out     dx, al
666
        shr     eax, 8
667
        inc     edx
668
        out     dx, al
669
        shr     eax, 8
670
        inc     edx
671
        and     al, 0xF
672
        add     al, byte [hdid]
673
        add     al, 11100000b
674
        out     dx, al
675
        inc     edx
676
        mov     al, 0xC8
677
        out     dx, al
678
        mov     dx, [IDEContrRegsBaseAddr]
679
        cmp     [hdbase], 0x1F0
680
        jz      @f
681
        add     dx, 8
682
@@:
683
        mov     al, 9
684
        out     dx, al
685
        mov     eax, [CURRENT_TASK]
686
        mov     [dma_process], eax
687
        mov     eax, [TASK_BASE]
688
        mov     [dma_slot_ptr], eax
689
        cmp     [hdbase], 0x1F0
690
        jnz     .ide1
691
        mov     [irq14_func], hdd_irq14
692
        jmp     @f
693
.ide1:
694
        mov     [irq15_func], hdd_irq15
695
@@:
696
        call    enable_ide_int
697
        cmp     [hdbase], 0x1F0
698
        jnz     .wait_ide1
699
        call    wait_for_sector_dma_ide0
700
        jmp     @f
701
.wait_ide1:
702
        call    wait_for_sector_dma_ide1
703
@@:
704
        cmp     [hd_error], 0
705
        jnz     hd_read_error
706
        mov     eax, [hdpos]
707
        mov     [dma_hdpos], eax
708
        pop     edx
709
        pop     eax
710
        mov     [dma_cur_sector], eax
711
        jmp     hd_read_dma
712
 
713
align 4
714
write_cache_sector:
715
        mov     [cache_chain_size], 1
716
        mov     [cache_chain_pos], edi
717
write_cache_chain:
718
        cmp     [hdpos], 0x80
719
        jae     bd_write_cache_chain
720
        mov     eax, [cache_chain_ptr]
721
        cmp     dword[eax], 0x10000000
722
        jae     .bad
723
        push    esi
724
        mov     eax, IDE_descriptor_table
725
        mov     edx, eax
726
        pusha
727
        mov     esi, [cache_chain_pos]
728
        shl     esi, 9
729
        call    calculate_cache_2
730
        add     esi, eax
731
        mov     edi, (OS_BASE+IDE_DMA)
732
        mov     dword [edx], IDE_DMA
733
        movzx   ecx, [cache_chain_size]
734
        shl     ecx, 9
735
        mov     word [edx+4], cx
736
        shr     ecx, 2
737
        cld
738
        rep movsd
739
        popa
740
        sub     eax, OS_BASE
741
        mov     dx, [IDEContrRegsBaseAddr]
742
        cmp     [hdbase], 0x1F0
743
        jz      @f
744
        add     edx, 8
745
@@:
746
        push    edx
747
        add     edx, 4
748
        out     dx, eax
749
        pop     edx
750
        mov     al, 0
751
        out     dx, al
752
        add     edx, 2
753
        mov     al, 6
754
        out     dx, al
755
        call    wait_for_hd_idle
756
        cmp     [hd_error], 0
757
        jnz     hd_write_error_dma
758
        call    disable_ide_int
759
        xor     eax, eax
760
        mov     edx, [hdbase]
761
        inc     edx
762
        out     dx, al
763
        inc     edx
764
        mov     al, [cache_chain_size]
765
        out     dx, al
766
        inc     edx
767
        mov     esi, [cache_chain_ptr]
768
        mov     eax, [esi]
769
        out     dx, al
770
        shr     eax, 8
771
        inc     edx
772
        out     dx, al
773
        shr     eax, 8
774
        inc     edx
775
        out     dx, al
776
        shr     eax, 8
777
        inc     edx
778
        and     al, 0xF
779
        add     al, byte [hdid]
780
        add     al, 11100000b
781
        out     dx, al
782
        inc     edx
783
        mov     al, 0xCA
784
        out     dx, al
785
        mov     dx, [IDEContrRegsBaseAddr]
786
        cmp     [hdbase], 0x1F0
787
        jz      @f
788
        add     dx, 8
789
@@:
790
        mov     al, 1
791
        out     dx, al
792
        mov     eax, [CURRENT_TASK]
793
        mov     [dma_process], eax
794
        mov     eax, [TASK_BASE]
795
        mov     [dma_slot_ptr], eax
796
        cmp     [hdbase], 0x1F0
797
        jnz     .ide1
798
        mov     [irq14_func], hdd_irq14
799
        jmp     @f
800
.ide1:
801
        mov     [irq15_func], hdd_irq15
802
@@:
803
        call    enable_ide_int
804
        mov     [dma_cur_sector], not 0x40
805
        cmp     [hdbase], 0x1F0
806
        jnz     .wait_ide1
807
        call    wait_for_sector_dma_ide0
808
        jmp     @f
809
.wait_ide1:
810
        call    wait_for_sector_dma_ide1
811
@@:
812
        cmp     [hd_error], 0
813
        jnz     hd_write_error_dma
814
        pop     esi
815
        ret
816
.bad:
817
        inc     [hd_error]
818
        ret
819
 
820
uglobal
821
IDEContrRegsBaseAddr    dw      ?
822
endg
823
; \end{Mario79}
824
 
825
; \begin{diamond}
826
uglobal
827
bios_hdpos      dd      0       ; 0 is invalid value for [hdpos]
828
bios_cur_sector dd      ?
829
bios_read_len   dd      ?
830
endg
831
bd_read:
832
        push    eax
833
        push    edx
834
        mov     edx, [bios_hdpos]
835
        cmp     edx, [hdpos]
836
        jne     .notread
837
        mov     edx, [bios_cur_sector]
838
        cmp     eax, edx
839
        jb      .notread
840
        add     edx, [bios_read_len]
841
        dec     edx
842
        cmp     eax, edx
843
        ja      .notread
844
        sub     eax, [bios_cur_sector]
845
        shl     eax, 9
846
        add     eax, (OS_BASE+0x9A000)
847
        push    ecx esi edi
848
        mov     esi, eax
849
        shl     edi, 9
850
;        add     edi, HD_CACHE+0x10000
851
        push    eax
852
        call    calculate_cache_2
853
        add     edi, eax
854
        pop     eax
855
 
856
        mov     ecx, 512/4
857
        cld
858
        rep movsd
859
        pop     edi esi ecx
860
        pop     edx
861
        pop     eax
862
        ret
863
.notread:
864
        push    ecx
865
        mov     dl, 42h
866
        mov     ecx, 16
867
        call    int13_call
868
        pop     ecx
869
        test    eax, eax
870
        jnz     .v86err
871
        test    edx, edx
872
        jz      .readerr
873
        mov     [bios_read_len], edx
874
        mov     edx, [hdpos]
875
        mov     [bios_hdpos], edx
876
        pop     edx
877
        pop     eax
878
        mov     [bios_cur_sector], eax
879
        jmp     bd_read
880
.readerr:
881
.v86err:
882
        mov     [hd_error], 1
883
        jmp     hd_read_error
884
 
885
bd_write_cache_chain:
886
        pusha
887
        mov     esi, [cache_chain_pos]
888
        shl     esi, 9
889
        call    calculate_cache_2
890
        add     esi, eax
891
        mov     edi, OS_BASE + 0x9A000
892
        movzx   ecx, [cache_chain_size]
893
        push    ecx
894
        shl     ecx, 9-2
895
        rep movsd
896
        pop     ecx
897
        mov     dl, 43h
898
        mov     eax, [cache_chain_ptr]
899
        mov     eax, [eax]
900
        call    int13_call
901
        test    eax, eax
902
        jnz     .v86err
903
        cmp     edx, ecx
904
        jnz     .writeerr
905
        popa
906
        ret
907
.v86err:
908
.writeerr:
909
        popa
910
        mov     [hd_error], 1
911
        jmp     hd_write_error
912
 
913
uglobal
2384 hidnplayr 914
int13_regs_in   rb      sizeof.v86_regs
915
int13_regs_out  rb      sizeof.v86_regs
2288 clevermous 916
endg
917
 
918
int13_call:
919
; Because this code uses fixed addresses,
920
; it can not be run simultaniously by many threads.
921
; In current implementation it is protected by common mutex 'hd1_status'
922
        mov     word [OS_BASE + 510h], 10h             ; packet length
923
        mov     word [OS_BASE + 512h], cx              ; number of sectors
924
        mov     dword [OS_BASE + 514h], 9A000000h      ; buffer 9A00:0000
925
        mov     dword [OS_BASE + 518h], eax
926
        and     dword [OS_BASE + 51Ch], 0
927
        push    ebx ecx esi edi
928
        mov     ebx, int13_regs_in
929
        mov     edi, ebx
2384 hidnplayr 930
        mov     ecx, sizeof.v86_regs/4
2288 clevermous 931
        xor     eax, eax
932
        rep stosd
933
        mov     byte [ebx+v86_regs.eax+1], dl
934
        mov     eax, [hdpos]
935
        lea     eax, [BiosDisksData+(eax-80h)*4]
936
        mov     dl, [eax]
937
        mov     byte [ebx+v86_regs.edx], dl
938
        movzx   edx, byte [eax+1]
939
;        mov     dl, 5
940
        test    edx, edx
941
        jnz     .hasirq
942
        dec     edx
943
        jmp     @f
944
.hasirq:
945
        pushad
946
        stdcall enable_irq, edx
947
        popad
948
@@:
949
        mov     word [ebx+v86_regs.esi], 510h
950
        mov     word [ebx+v86_regs.ss], 9000h
951
        mov     word [ebx+v86_regs.esp], 0A000h
952
        mov     word [ebx+v86_regs.eip], 500h
953
        mov     [ebx+v86_regs.eflags], 20200h
954
        mov     esi, [sys_v86_machine]
955
        mov     ecx, 0x502
956
        push    fs
957
        call    v86_start
958
        pop     fs
959
        and     [bios_hdpos], 0
960
        pop     edi esi ecx ebx
961
        movzx   edx, byte [OS_BASE + 512h]
962
        test    byte [int13_regs_out+v86_regs.eflags], 1
963
        jnz     @f
964
        mov     edx, ecx
965
@@:
966
        ret
967
; \end{diamond}
2643 clevermous 968
 
969
reserve_hd1:
970
 
971
        cli
972
        cmp     [hd1_status], 0
973
        je      reserve_ok1
974
 
975
        sti
976
        call    change_task
977
        jmp     reserve_hd1
978
 
979
  reserve_ok1:
980
 
981
        push    eax
982
        mov     eax, [CURRENT_TASK]
983
        shl     eax, 5
984
        mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
985
        mov     [hd1_status], eax
986
        pop     eax
987
        sti
988
        ret
989
;********************************************
990
 
991
uglobal
992
hd_in_cache db ?
993
endg
994
 
995
reserve_hd_channel:
996
; BIOS disk accesses are protected with common mutex hd1_status
997
; This must be modified when hd1_status will not be valid!
998
        cmp     [hdpos], 0x80
999
        jae     .ret
1000
        cmp     [hdbase], 0x1F0
1001
        jne     .IDE_Channel_2
1002
.IDE_Channel_1:
1003
        cli
1004
        cmp     [IDE_Channel_1], 0
1005
        je      .reserve_ok_1
1006
        sti
1007
        call    change_task
1008
        jmp     .IDE_Channel_1
1009
.IDE_Channel_2:
1010
        cli
1011
        cmp     [IDE_Channel_2], 0
1012
        je      .reserve_ok_2
1013
        sti
1014
        call    change_task
1015
        jmp     .IDE_Channel_2
1016
.reserve_ok_1:
1017
        mov     [IDE_Channel_1], 1
1018
        push    eax
1019
        mov     al, 1
1020
        jmp     @f
1021
.reserve_ok_2:
1022
        mov     [IDE_Channel_2], 1
1023
        push    eax
1024
        mov     al, 3
1025
@@:
1026
        cmp     [hdid], 1
1027
        sbb     al, -1
1028
        mov     [hd_in_cache], al
1029
        pop     eax
1030
        sti
1031
.ret:
1032
        ret
1033
 
1034
free_hd_channel:
1035
; see comment at reserve_hd_channel
1036
        cmp     [hdpos], 0x80
1037
        jae     .ret
1038
        cmp     [hdbase], 0x1F0
1039
        jne     .IDE_Channel_2
1040
.IDE_Channel_1:
1041
        mov     [IDE_Channel_1], 0
1042
.ret:
1043
        ret
1044
.IDE_Channel_2:
1045
        mov     [IDE_Channel_2], 0
1046
        ret
1047
;********************************************