Subversion Repositories Kolibri OS

Rev

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