Subversion Repositories Kolibri OS

Rev

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

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