Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
425 victor 1
$Revision: 514 $
431 serge 2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3
;;                                                              ;;
4
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
5
;; Distributed under terms of the GNU General Public License    ;;
6
;;                                                              ;;
7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8
 
472 serge 9
; Low-level driver for HDD access
346 diamond 10
; DMA support by Mario79
160 diamond 11
 
12
;**************************************************************************
13
;
14
;   0x600008  - first entry in cache list
15
;
16
;            +0   - lba sector
17
;            +4   - state of cache sector
18
;                   0 = empty
19
;                   1 = used for read  ( same as in hd )
20
;                   2 = used for write ( differs from hd )
21
;
22
;      +65536 - cache entries
23
;
24
;**************************************************************************
25
 
26
align 4
27
hd_read:
28
;-----------------------------------------------------------
29
; input  : eax = block to read
30
;          ebx = destination
31
;-----------------------------------------------------------
256 diamond 32
        and     [hd_error], 0
160 diamond 33
    push  ecx esi edi           ; scan cache
34
 
35
    mov   ecx,cache_max         ; entries in cache
472 serge 36
    mov   esi,HD_CACHE+8
160 diamond 37
    mov   edi,1
38
 
39
  hdreadcache:
40
 
41
    cmp   dword [esi+4],0       ; empty
42
    je    nohdcache
43
 
44
    cmp   [esi],eax             ; correct sector
45
    je    yeshdcache
46
 
47
  nohdcache:
48
 
49
    add   esi,8
50
    inc   edi
51
    dec   ecx
52
    jnz   hdreadcache
53
 
54
    call  find_empty_slot       ; ret in edi
55
    cmp   [hd_error],0
56
    jne   return_01
514 diamond 57
; DMA read is permitted if [allow_dma_access]=1 or 2
58
        cmp     [allow_dma_access], 2
59
        ja      .nodma
160 diamond 60
        cmp     [dma_hdd], 1
61
        jnz     .nodma
62
        call    hd_read_dma
63
        jmp     @f
64
.nodma:
65
        call    hd_read_pio
66
@@:
67
 
472 serge 68
    lea   esi,[edi*8+HD_CACHE]
160 diamond 69
    mov   [esi],eax             ; sector number
70
    mov   dword [esi+4],1       ; hd read - mark as same as in hd
71
 
72
  yeshdcache:
73
 
74
    mov   esi,edi
75
    shl   esi,9
472 serge 76
    add   esi,HD_CACHE+65536
160 diamond 77
    mov   edi,ebx
78
    mov   ecx,512/4
79
    cld
80
    rep   movsd                 ; move data
81
 return_01:
82
    pop   edi esi ecx
83
    ret
84
 
85
align 4
86
hd_read_pio:
87
    push  eax edx
88
 
89
    call  wait_for_hd_idle
90
    cmp   [hd_error],0
389 serge 91
    jne   hd_read_error
160 diamond 92
 
321 diamond 93
    cli
160 diamond 94
    xor   eax,eax
95
    mov   edx,[hdbase]
96
    inc   edx
97
    out   dx,al   ; ATAFeatures регистр "особенностей"
98
    inc   edx
99
    inc   eax
100
    out   dx,al   ; ATASectorCount счётчик секторов
101
    inc   edx
102
    mov   eax,[esp+4]
103
    out   dx,al   ; ATASectorNumber регистр номера сектора
104
    shr   eax,8
105
    inc   edx
106
    out   dx,al   ; ATACylinder номер цилиндра (младший байт)
107
    shr   eax,8
108
    inc   edx
109
    out   dx,al   ; номер цилиндра (старший байт)
110
    shr   eax,8
111
    inc   edx
112
    and   al,1+2+4+8
113
    add   al,byte [hdid]
114
    add   al,128+64+32
115
    out   dx,al   ; номер головки/номер диска
116
    inc   edx
117
    mov   al,20h
118
    out   dx,al   ; ATACommand регистр команд
321 diamond 119
    sti
160 diamond 120
 
121
    call  wait_for_sector_buffer
122
 
123
    cmp   [hd_error],0
124
    jne   hd_read_error
125
 
321 diamond 126
    cli
160 diamond 127
    push  edi
128
    shl   edi,9
472 serge 129
    add   edi,HD_CACHE+65536
160 diamond 130
    mov   ecx,256
131
    mov   edx,[hdbase]
132
    cld
133
    rep   insw
134
    pop   edi
321 diamond 135
    sti
160 diamond 136
 
137
    pop   edx eax
138
    ret
139
 
389 serge 140
disable_ide_int:
162 diamond 141
;        mov edx,[hdbase]
142
;        add edx,0x206
143
;        mov al,2
144
;        out dx,al
145
        cli
160 diamond 146
        ret
147
 
148
enable_ide_int:
162 diamond 149
;        mov edx,[hdbase]
150
;        add edx,0x206
151
;        mov al,0
152
;        out dx,al
153
        sti
160 diamond 154
        ret
155
 
156
align 4
157
hd_write:
158
;-----------------------------------------------------------
159
; input  : eax = block
160
;          ebx = pointer to memory
161
;-----------------------------------------------------------
162
    push  ecx esi edi
163
 
164
    ; check if the cache already has the sector and overwrite it
165
 
166
    mov   ecx,cache_max
472 serge 167
    mov   esi,HD_CACHE+8
160 diamond 168
    mov   edi,1
169
 
170
  hdwritecache:
171
 
172
    cmp   dword [esi+4],0       ; if cache slot is empty
173
    je    not_in_cache_write
174
 
175
    cmp   [esi],eax             ; if the slot has the sector
176
    je    yes_in_cache_write
177
 
178
  not_in_cache_write:
179
 
180
    add   esi,8
181
    inc   edi
182
    dec   ecx
183
    jnz   hdwritecache
184
 
185
    ; sector not found in cache
186
    ; write the block to a new location
187
 
188
    call  find_empty_slot       ; ret in edi
189
    cmp   [hd_error],0
190
    jne   hd_write_access_denied
191
 
472 serge 192
    lea   esi,[edi*8+HD_CACHE]
160 diamond 193
    mov   [esi],eax             ; sector number
194
 
195
  yes_in_cache_write:
196
 
197
    mov   dword [esi+4],2       ; write - differs from hd
198
 
199
    shl   edi,9
472 serge 200
    add   edi,HD_CACHE+65536
160 diamond 201
    mov   esi,ebx
202
    mov   ecx,512/4
203
    cld
204
    rep   movsd                 ; move data
205
 hd_write_access_denied:
206
    pop   edi esi ecx
207
    ret
208
 
209
 
210
write_cache:
211
;-----------------------------------------------------------
212
; write all changed sectors to disk
213
;-----------------------------------------------------------
214
    push  eax ecx edx esi edi
215
 
216
    ; write difference ( 2 ) from cache to hd
217
 
218
    mov   ecx,cache_max
472 serge 219
    mov   esi,HD_CACHE+8
160 diamond 220
    mov   edi,1
221
 
222
  write_cache_more:
223
 
224
    cmp   dword [esi+4],2       ; if cache slot is not different
225
    jne   .write_chain
226
 
227
    mov   dword [esi+4],1       ; same as in hd
228
    mov   eax,[esi]             ; eax = sector to write
229
 
230
    cmp   eax,[PARTITION_START]
231
    jb    danger
232
    cmp   eax,[PARTITION_END]
233
    ja    danger
346 diamond 234
 
514 diamond 235
; DMA write is permitted only if [allow_dma_access]=1
236
        cmp     [allow_dma_access], 2
237
        jae     .nodma
160 diamond 238
        cmp     [dma_hdd], 1
346 diamond 239
        jnz     .nodma
160 diamond 240
; Объединяем запись цепочки последовательных секторов в одно обращение к диску
241
        cmp     ecx, 1
242
        jz      .nonext
243
        cmp     dword [esi+8+4], 2
244
        jnz     .nonext
245
        push    eax
246
        inc     eax
247
        cmp     eax, [esi+8]
248
        pop     eax
249
        jnz     .nonext
250
        cmp     [cache_chain_started], 1
251
        jz      @f
252
        mov     [cache_chain_started], 1
253
        mov     [cache_chain_size], 0
254
        mov     [cache_chain_pos], edi
255
        mov     [cache_chain_ptr], esi
256
@@:
257
        inc     [cache_chain_size]
258
        cmp     [cache_chain_size], 64
259
        jnz     .continue
260
        jmp     .write_chain
261
.nonext:
262
        call    flush_cache_chain
263
        mov     [cache_chain_size], 1
264
        mov     [cache_chain_ptr], esi
265
        call    write_cache_sector
266
        jmp     .continue
267
.nodma:
268
        call    cache_write_pio
269
.write_chain:
270
        call    flush_cache_chain
271
 
272
.continue:
273
  danger:
274
 
275
    add   esi,8
276
    inc   edi
277
    dec   ecx
278
    jnz   write_cache_more
279
        call    flush_cache_chain
280
 return_02:
281
    pop   edi esi edx ecx eax
282
    ret
283
 
284
flush_cache_chain:
285
        cmp     [cache_chain_started], 0
286
        jz      @f
287
        call    write_cache_chain
288
        mov     [cache_chain_started], 0
289
@@:
290
        ret
291
 
292
align 4
293
cache_write_pio:
294
    call  disable_ide_int
295
 
296
    call  wait_for_hd_idle
297
    cmp   [hd_error],0
298
    jne   hd_write_error
299
 
300
;    cli
301
    xor   eax,eax
302
    mov   edx,[hdbase]
303
    inc   edx
304
    out   dx,al
305
    inc   edx
306
    inc   eax
307
    out   dx,al
308
    inc   edx
309
    mov   eax,[esi]             ; eax = sector to write
310
    out   dx,al
311
    shr   eax,8
312
    inc   edx
313
    out   dx,al
314
    shr   eax,8
315
    inc   edx
316
    out   dx,al
317
    shr   eax,8
318
    inc   edx
319
    and   al,1+2+4+8
320
    add   al,byte [hdid]
321
    add   al,128+64+32
322
    out   dx,al
323
    inc   edx
324
    mov   al,30h
325
    out   dx,al
326
;    sti
327
 
328
    call  wait_for_sector_buffer
329
 
330
    cmp   [hd_error],0
331
    jne   hd_write_error
332
 
333
    push  ecx esi
334
 
335
;    cli
336
    mov   esi,edi
337
    shl   esi,9
472 serge 338
    add   esi,HD_CACHE+65536    ; esi = from memory position
160 diamond 339
    mov   ecx,256
340
    mov   edx,[hdbase]
341
    cld
342
    rep   outsw
343
;    sti
344
 
345
    call  enable_ide_int
346
    pop   esi ecx
347
 
348
    ret
349
 
350
align 4
351
find_empty_slot:
352
;-----------------------------------------------------------
353
; find empty or read slot, flush cache if next 10% is used by write
354
; output : edi = cache slot
355
;-----------------------------------------------------------
356
;    push  ecx esi
357
 
358
  search_again:
359
 
360
    mov   ecx,cache_max*10/100
361
    mov   edi,[cache_search_start]
362
 
363
  search_for_empty:
364
 
365
    inc   edi
366
    cmp   edi,cache_max
367
    jbe   inside_cache
368
    mov   edi,1
369
 
370
  inside_cache:
371
 
472 serge 372
    cmp   dword [edi*8+HD_CACHE+4],2    ; get cache slot info
160 diamond 373
    jb    found_slot                    ; it's empty or read
374
    dec   ecx
375
    jnz   search_for_empty
376
 
377
    call  write_cache                   ; no empty slots found, write all
378
    cmp   [hd_error],0
379
    jne   found_slot_access_denied
380
 
381
    jmp   search_again                  ; and start again
382
 
383
  found_slot:
384
 
385
    mov   [cache_search_start],edi
386
  found_slot_access_denied:
387
    ret
388
 
389
align 4
390
clear_hd_cache:
391
 
392
    push  eax ecx edi
472 serge 393
    mov   edi, HD_CACHE
160 diamond 394
    mov   ecx,16384
395
    xor   eax,eax
396
    cld
397
    rep   stosd                 ; clear hd cache with 0
398
    mov   [cache_search_start],eax
399
    mov   [fat_in_cache],-1
400
    mov   [fat_change],0
401
    pop   edi ecx eax
402
    ret
403
 
404
save_hd_wait_timeout:
405
 
406
    push  eax
465 serge 407
    mov   eax,[timer_ticks]
160 diamond 408
    add   eax,300               ; 3 sec timeout
409
    mov   [hd_wait_timeout],eax
410
    pop   eax
411
    ret
412
 
413
align 4
414
check_hd_wait_timeout:
415
 
416
    push  eax
417
    mov   eax,[hd_wait_timeout]
465 serge 418
    cmp   [timer_ticks], eax
160 diamond 419
    jg    hd_timeout_error
420
    pop   eax
421
    mov   [hd_error],0
422
    ret
423
 
358 mikedld 424
;iglobal
425
;  hd_timeout_str   db 'K : FS - HD timeout',0
426
;  hd_read_str      db 'K : FS - HD read error',0
427
;  hd_write_str     db 'K : FS - HD write error',0
428
;  hd_lba_str       db 'K : FS - HD LBA error',0
429
;endg
160 diamond 430
 
431
hd_timeout_error:
432
 
321 diamond 433
;    call  clear_hd_cache
434
;    call  clear_application_table_status
358 mikedld 435
;    mov   esi,hd_timeout_str
436
;    call  sys_msg_board_str
465 serge 437
    DEBUGF 1,"K : FS - HD timeout\n"
438
 
160 diamond 439
    mov   [hd_error],1
440
    pop   eax
441
    ret
442
 
443
hd_read_error:
444
 
321 diamond 445
;    call  clear_hd_cache
446
;    call  clear_application_table_status
358 mikedld 447
;    mov   esi,hd_read_str
448
;    call  sys_msg_board_str
465 serge 449
    DEBUGF 1,"K : FS - HD read error\n"
160 diamond 450
    pop   edx eax
161 diamond 451
    ret
160 diamond 452
 
453
hd_write_error:
454
 
321 diamond 455
;    call  clear_hd_cache
456
;    call  clear_application_table_status
465 serge 457
;     mov   esi,hd_write_str
458
;     call  sys_msg_board_str
459
    DEBUGF 1,"K : FS - HD write error\n"
460
     ret
160 diamond 461
 
462
hd_write_error_dma:
321 diamond 463
;        call    clear_hd_cache
464
;        call    clear_application_table_status
358 mikedld 465
;        mov     esi, hd_write_str
466
;        call    sys_msg_board_str
465 serge 467
        DEBUGF 1,"K : FS - HD read error\n"
160 diamond 468
        pop     esi
161 diamond 469
        ret
160 diamond 470
 
471
hd_lba_error:
321 diamond 472
;    call  clear_hd_cache
473
;    call  clear_application_table_status
358 mikedld 474
;    mov   esi,hd_lba_str
475
;    call  sys_msg_board_str
465 serge 476
     DEBUGF 1,"K : FS - HD LBA error\n"
477
     jmp   LBA_read_ret
160 diamond 478
 
479
 
480
align 4
481
wait_for_hd_idle:
482
 
483
    push  eax edx
484
 
485
    call  save_hd_wait_timeout
486
 
487
    mov   edx,[hdbase]
488
    add   edx,0x7
489
 
490
  wfhil1:
491
 
492
    call  check_hd_wait_timeout
493
    cmp   [hd_error],0
494
    jne   @f
495
 
496
    in    al,dx
497
    test  al,128
498
    jnz   wfhil1
389 serge 499
 
160 diamond 500
 @@:
501
 
502
    pop   edx eax
503
    ret
504
 
505
 
506
align 4
507
wait_for_sector_buffer:
508
 
509
    push  eax edx
510
 
511
    mov   edx,[hdbase]
512
    add   edx,0x7
513
 
514
    call  save_hd_wait_timeout
515
 
516
  hdwait_sbuf:                  ; wait for sector buffer to be ready
517
 
518
    call  check_hd_wait_timeout
519
    cmp   [hd_error],0
520
    jne   @f
521
 
522
    in    al,dx
523
    test  al,8
524
    jz    hdwait_sbuf
525
 
526
    mov   [hd_error],0
527
 
528
    cmp   [hd_setup],1          ; do not mark error for setup request
529
    je    buf_wait_ok
530
 
531
    test  al,1                  ; previous command ended up with an error
532
    jz    buf_wait_ok
533
 @@:
534
    mov   [hd_error],1
535
 
536
  buf_wait_ok:
537
 
538
    pop   edx eax
539
    ret
540
 
346 diamond 541
; \begin{Mario79}
160 diamond 542
align 4
543
wait_for_sector_dma_ide0:
544
        push    eax
545
        push    edx
546
        call    save_hd_wait_timeout
547
.wait:
548
        call    change_task
549
        cmp     [irq14_func], hdd_irq14
550
        jnz     .done
551
        call    check_hd_wait_timeout
552
        cmp     [hd_error], 0
553
        jz      .wait
554
        mov     [irq14_func], hdd_irq_null
555
        mov     dx, [IDEContrRegsBaseAddr]
556
        mov     al, 0
557
        out     dx, al
558
.done:
559
        pop     edx
560
        pop     eax
561
        ret
562
 
563
align 4
564
wait_for_sector_dma_ide1:
565
        push    eax
566
        push    edx
567
        call    save_hd_wait_timeout
568
.wait:
569
        call    change_task
570
        cmp     [irq15_func], hdd_irq15
571
        jnz     .done
572
        call    check_hd_wait_timeout
573
        cmp     [hd_error], 0
574
        jz      .wait
575
        mov     [irq15_func], hdd_irq_null
576
        mov     dx, [IDEContrRegsBaseAddr]
577
        add     dx, 8
578
        mov     al, 0
579
        out     dx, al
580
.done:
581
        pop     edx
582
        pop     eax
583
        ret
584
 
585
iglobal
586
align 4
587
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
588
IDE_descriptor_table:
465 serge 589
        dd      0x284000
590
        dw      0x2000
591
        dw      0x8000
160 diamond 592
 
593
dma_cur_sector  dd      not 40h
594
irq14_func      dd      hdd_irq_null
595
irq15_func      dd      hdd_irq_null
596
endg
597
 
598
uglobal
599
; all uglobals are zeroed at boot
600
dma_process     dd      0
601
dma_slot_ptr    dd      0
602
cache_chain_pos dd      0
603
cache_chain_ptr dd      0
604
cache_chain_size        db      0
605
cache_chain_started     db      0
606
dma_task_switched       db      0
607
dma_hdd         db      0
514 diamond 608
allow_dma_access db      0
160 diamond 609
endg
610
 
611
align 4
612
hdd_irq14:
613
        pushfd
614
        cli
615
        pushad
616
        mov     [irq14_func], hdd_irq_null
617
        mov     dx, [IDEContrRegsBaseAddr]
618
        mov     al, 0
619
        out     dx, al
465 serge 620
;        call    update_counters
621
;        mov     ebx, [dma_process]
622
;        cmp     [CURRENT_TASK], ebx
623
;        jz      .noswitch
624
;        mov     [dma_task_switched], 1
625
;        mov     edi, [dma_slot_ptr]
626
;        mov     eax, [CURRENT_TASK]
627
;        mov     [dma_process], eax
628
;        mov     eax, [TASK_BASE]
629
;        mov     [dma_slot_ptr], eax
630
;        mov     [CURRENT_TASK], ebx
631
;        mov     [TASK_BASE], edi
632
;        mov     byte [DONT_SWITCH], 1
633
;        call    do_change_task
160 diamond 634
.noswitch:
635
        popad
636
        popfd
637
align 4
638
hdd_irq_null:
639
        ret
640
 
641
align 4
642
hdd_irq15:
643
        pushfd
644
        cli
645
        pushad
646
        mov     [irq15_func], hdd_irq_null
647
        mov     dx, [IDEContrRegsBaseAddr]
648
        add     dx, 8
649
        mov     al, 0
650
        out     dx, al
465 serge 651
;        call    update_counters
652
;        mov     ebx, [dma_process]
653
;        cmp     [CURRENT_TASK], ebx
654
;        jz      .noswitch
655
;        mov     [dma_task_switched], 1
656
;        mov     edi, [dma_slot_ptr]
657
;        mov     eax, [CURRENT_TASK]
658
;        mov     [dma_process], eax
659
;        mov     eax, [TASK_BASE]
660
;        mov     [dma_slot_ptr], eax
661
;        mov     [CURRENT_TASK], ebx
662
;        mov     [TASK_BASE], edi
663
;        mov     byte [DONT_SWITCH], 1
664
;        call    do_change_task
160 diamond 665
.noswitch:
666
        popad
667
        popfd
668
        ret
669
 
670
align 4
671
hd_read_dma:
672
        push    eax
673
        push    edx
674
        mov     edx, [dma_cur_sector]
675
        cmp     eax, edx
676
        jb      .notread
677
        add     edx, 15
678
        cmp     [esp+4], edx
679
        ja      .notread
680
        mov     eax, [esp+4]
681
        sub     eax, [dma_cur_sector]
682
        shl     eax, 9
389 serge 683
        add     eax, OS_BASE+0x284000
160 diamond 684
        push    ecx esi edi
685
        mov     esi, eax
686
        shl     edi, 9
472 serge 687
        add     edi, HD_CACHE+0x10000
160 diamond 688
        mov     ecx, 512/4
689
        cld
690
        rep     movsd
691
        pop     edi esi ecx
692
        pop     edx
693
        pop     eax
694
        ret
695
.notread:
465 serge 696
        mov     eax, IDE_descriptor_table
697
        mov     dword [eax],  0x284000
698
        mov     word [eax+4], 0x2000
699
        sub     eax, OS_BASE
160 diamond 700
        mov     dx, [IDEContrRegsBaseAddr]
701
        cmp     [hdbase], 0x1F0
702
        jz      @f
703
        add     edx, 8
704
@@:
705
        push    edx
706
        add     edx, 4
707
        out     dx, eax
708
        pop     edx
709
        mov     al, 0
710
        out     dx, al
711
        add     edx, 2
712
        mov     al, 6
713
        out     dx, al
714
        call    wait_for_hd_idle
715
        cmp     [hd_error], 0
716
        jnz     hd_read_error
717
        call    disable_ide_int
718
        xor     eax, eax
719
        mov     edx, [hdbase]
720
        inc     edx
721
        out     dx, al
722
        inc     edx
723
        mov     eax, 10h
724
        out     dx, al
725
        inc     edx
726
        mov     eax, [esp+4]
727
        out     dx, al
728
        shr     eax, 8
729
        inc     edx
730
        out     dx, al
731
        shr     eax, 8
732
        inc     edx
733
        out     dx, al
734
        shr     eax, 8
735
        inc     edx
736
        and     al, 0xF
737
        add     al, byte [hdid]
738
        add     al, 11100000b
739
        out     dx, al
740
        inc     edx
741
        mov     al, 0xC8
742
        out     dx, al
743
        mov     dx, [IDEContrRegsBaseAddr]
744
        cmp     [hdbase], 0x1F0
745
        jz      @f
746
        add     dx, 8
747
@@:
748
        mov     al, 9
749
        out     dx, al
389 serge 750
        mov     eax, [CURRENT_TASK]
160 diamond 751
        mov     [dma_process], eax
389 serge 752
        mov     eax, [TASK_BASE]
160 diamond 753
        mov     [dma_slot_ptr], eax
754
        cmp     [hdbase], 0x1F0
755
        jnz     .ide1
756
        mov     [irq14_func], hdd_irq14
757
        jmp     @f
758
.ide1:
759
        mov     [irq15_func], hdd_irq15
760
@@:
761
        call    enable_ide_int
762
        cmp     [hdbase], 0x1F0
763
        jnz     .wait_ide1
764
        call    wait_for_sector_dma_ide0
765
        jmp     @f
766
.wait_ide1:
767
        call    wait_for_sector_dma_ide1
768
@@:
769
        cmp     [hd_error], 0
770
        jnz     hd_read_error
771
        pop     edx
772
        pop     eax
773
        mov     [dma_cur_sector], eax
774
        jmp     hd_read_dma
775
 
776
align 4
777
write_cache_chain:
778
        push    esi
779
        mov     eax, IDE_descriptor_table
780
        mov     edx, [cache_chain_pos]
781
        shl     edx, 9
472 serge 782
        add     edx, DMA_HD_MEM+0x10000
160 diamond 783
        mov     [eax], edx
784
        movzx   edx, [cache_chain_size]
785
        shl     edx, 9
786
        mov     [eax+4], dx
787
        jmp     do_write_dma
788
write_cache_sector:
789
        push    esi
790
        mov     eax, IDE_descriptor_table
791
        mov     edx, edi
792
        shl     edx, 9
472 serge 793
        add     edx, DMA_HD_MEM+0x10000
160 diamond 794
        mov     [eax], edx
795
        mov     word [eax+4], 0x200
796
do_write_dma:
465 serge 797
        sub     eax, OS_BASE
160 diamond 798
        mov     dx, [IDEContrRegsBaseAddr]
799
        cmp     [hdbase], 0x1F0
800
        jz      @f
801
        add     edx, 8
802
@@:
803
        push    edx
804
        add     edx, 4
805
        out     dx, eax
806
        pop     edx
807
        mov     al, 0
808
        out     dx, al
809
        add     edx, 2
810
        mov     al, 6
811
        out     dx, al
812
        call    wait_for_hd_idle
813
        cmp     [hd_error], 0
814
        jnz     hd_write_error_dma
815
        call    disable_ide_int
816
        xor     eax, eax
817
        mov     edx, [hdbase]
818
        inc     edx
819
        out     dx, al
820
        inc     edx
821
        mov     al, [cache_chain_size]
822
        out     dx, al
823
        inc     edx
824
        mov     esi, [cache_chain_ptr]
825
        mov     eax, [esi]
826
        out     dx, al
827
        shr     eax, 8
828
        inc     edx
829
        out     dx, al
830
        shr     eax, 8
831
        inc     edx
832
        out     dx, al
833
        shr     eax, 8
834
        inc     edx
835
        and     al, 0xF
836
        add     al, byte [hdid]
837
        add     al, 11100000b
838
        out     dx, al
839
        inc     edx
840
        mov     al, 0xCA
841
        out     dx, al
842
        mov     dx, [IDEContrRegsBaseAddr]
843
        cmp     [hdbase], 0x1F0
844
        jz      @f
845
        add     dx, 8
846
@@:
847
        mov     al, 1
848
        out     dx, al
389 serge 849
        mov     eax, [CURRENT_TASK]
160 diamond 850
        mov     [dma_process], eax
389 serge 851
        mov     eax, [TASK_BASE]
160 diamond 852
        mov     [dma_slot_ptr], eax
853
        cmp     [hdbase], 0x1F0
854
        jnz     .ide1
855
        mov     [irq14_func], hdd_irq14
856
        jmp     @f
857
.ide1:
858
        mov     [irq15_func], hdd_irq15
859
@@:
860
        call    enable_ide_int
861
        mov     [dma_cur_sector], not 0x40
862
        cmp     [hdbase], 0x1F0
863
        jnz     .wait_ide1
864
        call    wait_for_sector_dma_ide0
865
        jmp     @f
866
.wait_ide1:
867
        call    wait_for_sector_dma_ide1
868
@@:
869
        cmp     [hd_error], 0
870
        jnz     hd_write_error_dma
871
        pop     esi
872
        ret
873
 
874
uglobal
875
IDEContrRegsBaseAddr    dw      ?
876
endg
346 diamond 877
; \end{Mario79}