Subversion Repositories Kolibri OS

Rev

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

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