Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
425 victor 1
$Revision: 467 $
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
 
467 mikedld 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
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
465 serge 403
    mov   eax,[timer_ticks]
160 diamond 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]
465 serge 414
    cmp   [timer_ticks], eax
160 diamond 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
465 serge 433
    DEBUGF 1,"K : FS - HD timeout\n"
434
 
160 diamond 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
465 serge 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
465 serge 453
;     mov   esi,hd_write_str
454
;     call  sys_msg_board_str
455
    DEBUGF 1,"K : FS - HD write error\n"
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
465 serge 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
465 serge 472
     DEBUGF 1,"K : FS - HD LBA error\n"
473
     jmp   LBA_read_ret
160 diamond 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:
465 serge 585
        dd      0x284000
586
        dw      0x2000
587
        dw      0x8000
160 diamond 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
465 serge 616
;        call    update_counters
617
;        mov     ebx, [dma_process]
618
;        cmp     [CURRENT_TASK], ebx
619
;        jz      .noswitch
620
;        mov     [dma_task_switched], 1
621
;        mov     edi, [dma_slot_ptr]
622
;        mov     eax, [CURRENT_TASK]
623
;        mov     [dma_process], eax
624
;        mov     eax, [TASK_BASE]
625
;        mov     [dma_slot_ptr], eax
626
;        mov     [CURRENT_TASK], ebx
627
;        mov     [TASK_BASE], edi
628
;        mov     byte [DONT_SWITCH], 1
629
;        call    do_change_task
160 diamond 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
465 serge 647
;        call    update_counters
648
;        mov     ebx, [dma_process]
649
;        cmp     [CURRENT_TASK], ebx
650
;        jz      .noswitch
651
;        mov     [dma_task_switched], 1
652
;        mov     edi, [dma_slot_ptr]
653
;        mov     eax, [CURRENT_TASK]
654
;        mov     [dma_process], eax
655
;        mov     eax, [TASK_BASE]
656
;        mov     [dma_slot_ptr], eax
657
;        mov     [CURRENT_TASK], ebx
658
;        mov     [TASK_BASE], edi
659
;        mov     byte [DONT_SWITCH], 1
660
;        call    do_change_task
160 diamond 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:
465 serge 692
        mov     eax, IDE_descriptor_table
693
        mov     dword [eax],  0x284000
694
        mov     word [eax+4], 0x2000
695
        sub     eax, OS_BASE
160 diamond 696
        mov     dx, [IDEContrRegsBaseAddr]
697
        cmp     [hdbase], 0x1F0
698
        jz      @f
699
        add     edx, 8
700
@@:
701
        push    edx
702
        add     edx, 4
703
        out     dx, eax
704
        pop     edx
705
        mov     al, 0
706
        out     dx, al
707
        add     edx, 2
708
        mov     al, 6
709
        out     dx, al
710
        call    wait_for_hd_idle
711
        cmp     [hd_error], 0
712
        jnz     hd_read_error
713
        call    disable_ide_int
714
        xor     eax, eax
715
        mov     edx, [hdbase]
716
        inc     edx
717
        out     dx, al
718
        inc     edx
719
        mov     eax, 10h
720
        out     dx, al
721
        inc     edx
722
        mov     eax, [esp+4]
723
        out     dx, al
724
        shr     eax, 8
725
        inc     edx
726
        out     dx, al
727
        shr     eax, 8
728
        inc     edx
729
        out     dx, al
730
        shr     eax, 8
731
        inc     edx
732
        and     al, 0xF
733
        add     al, byte [hdid]
734
        add     al, 11100000b
735
        out     dx, al
736
        inc     edx
737
        mov     al, 0xC8
738
        out     dx, al
739
        mov     dx, [IDEContrRegsBaseAddr]
740
        cmp     [hdbase], 0x1F0
741
        jz      @f
742
        add     dx, 8
743
@@:
744
        mov     al, 9
745
        out     dx, al
389 serge 746
        mov     eax, [CURRENT_TASK]
160 diamond 747
        mov     [dma_process], eax
389 serge 748
        mov     eax, [TASK_BASE]
160 diamond 749
        mov     [dma_slot_ptr], eax
750
        cmp     [hdbase], 0x1F0
751
        jnz     .ide1
752
        mov     [irq14_func], hdd_irq14
753
        jmp     @f
754
.ide1:
755
        mov     [irq15_func], hdd_irq15
756
@@:
757
        call    enable_ide_int
758
        cmp     [hdbase], 0x1F0
759
        jnz     .wait_ide1
760
        call    wait_for_sector_dma_ide0
761
        jmp     @f
762
.wait_ide1:
763
        call    wait_for_sector_dma_ide1
764
@@:
765
        cmp     [hd_error], 0
766
        jnz     hd_read_error
767
        pop     edx
768
        pop     eax
769
        mov     [dma_cur_sector], eax
770
        jmp     hd_read_dma
771
 
772
align 4
773
write_cache_chain:
774
        push    esi
775
        mov     eax, IDE_descriptor_table
776
        mov     edx, [cache_chain_pos]
777
        shl     edx, 9
465 serge 778
        add     edx, 0x610000
160 diamond 779
        mov     [eax], edx
780
        movzx   edx, [cache_chain_size]
781
        shl     edx, 9
782
        mov     [eax+4], dx
783
        jmp     do_write_dma
784
write_cache_sector:
785
        push    esi
786
        mov     eax, IDE_descriptor_table
787
        mov     edx, edi
788
        shl     edx, 9
465 serge 789
        add     edx, 0x610000
160 diamond 790
        mov     [eax], edx
791
        mov     word [eax+4], 0x200
792
do_write_dma:
465 serge 793
        sub     eax, OS_BASE
160 diamond 794
        mov     dx, [IDEContrRegsBaseAddr]
795
        cmp     [hdbase], 0x1F0
796
        jz      @f
797
        add     edx, 8
798
@@:
799
        push    edx
800
        add     edx, 4
801
        out     dx, eax
802
        pop     edx
803
        mov     al, 0
804
        out     dx, al
805
        add     edx, 2
806
        mov     al, 6
807
        out     dx, al
808
        call    wait_for_hd_idle
809
        cmp     [hd_error], 0
810
        jnz     hd_write_error_dma
811
        call    disable_ide_int
812
        xor     eax, eax
813
        mov     edx, [hdbase]
814
        inc     edx
815
        out     dx, al
816
        inc     edx
817
        mov     al, [cache_chain_size]
818
        out     dx, al
819
        inc     edx
820
        mov     esi, [cache_chain_ptr]
821
        mov     eax, [esi]
822
        out     dx, al
823
        shr     eax, 8
824
        inc     edx
825
        out     dx, al
826
        shr     eax, 8
827
        inc     edx
828
        out     dx, al
829
        shr     eax, 8
830
        inc     edx
831
        and     al, 0xF
832
        add     al, byte [hdid]
833
        add     al, 11100000b
834
        out     dx, al
835
        inc     edx
836
        mov     al, 0xCA
837
        out     dx, al
838
        mov     dx, [IDEContrRegsBaseAddr]
839
        cmp     [hdbase], 0x1F0
840
        jz      @f
841
        add     dx, 8
842
@@:
843
        mov     al, 1
844
        out     dx, al
389 serge 845
        mov     eax, [CURRENT_TASK]
160 diamond 846
        mov     [dma_process], eax
389 serge 847
        mov     eax, [TASK_BASE]
160 diamond 848
        mov     [dma_slot_ptr], eax
849
        cmp     [hdbase], 0x1F0
850
        jnz     .ide1
851
        mov     [irq14_func], hdd_irq14
852
        jmp     @f
853
.ide1:
854
        mov     [irq15_func], hdd_irq15
855
@@:
856
        call    enable_ide_int
857
        mov     [dma_cur_sector], not 0x40
858
        cmp     [hdbase], 0x1F0
859
        jnz     .wait_ide1
860
        call    wait_for_sector_dma_ide0
861
        jmp     @f
862
.wait_ide1:
863
        call    wait_for_sector_dma_ide1
864
@@:
865
        cmp     [hd_error], 0
866
        jnz     hd_write_error_dma
867
        pop     esi
868
        ret
869
 
870
uglobal
871
IDEContrRegsBaseAddr    dw      ?
872
endg
346 diamond 873
; \end{Mario79}