Subversion Repositories Kolibri OS

Rev

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

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