Subversion Repositories Kolibri OS

Rev

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