Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 3702 $
9
 
10
 
11
; Low-level driver for HDD access
12
; DMA support by Mario79
13
; Access through BIOS by diamond
14
 
15
align 4
16
hd_read:
17
;-----------------------------------------------------------
18
; input  : eax = block to read
19
;          ebx = destination
20
;-----------------------------------------------------------
21
        and     [hd_error], 0
22
        push    ecx esi edi     ; scan cache
23
 
24
;    mov   ecx,cache_max         ; entries in cache
25
;    mov   esi,HD_CACHE+8
26
        call    calculate_cache
27
        add     esi, 8
28
 
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
49
; Read through BIOS?
50
        cmp     [hdpos], 0x80
51
        jae     .bios
52
; hd_read_{dma,pio} use old ATA with 28 bit for sector number
3702 mario79 53
;        cmp     eax, 0x10000000
54
;        jb      @f
55
;        inc     [hd_error]
56
;        jmp     return_01
57
;@@:
2288 clevermous 58
; DMA read is permitted if [allow_dma_access]=1 or 2
59
        cmp     [allow_dma_access], 2
60
        ja      .nodma
61
        cmp     [dma_hdd], 1
62
        jnz     .nodma
63
        call    hd_read_dma
64
        jmp     @f
65
.nodma:
66
        call    hd_read_pio
67
        jmp     @f
68
.bios:
69
        call    bd_read
70
@@:
71
        cmp     [hd_error], 0
72
        jne     return_01
73
;    lea   esi,[edi*8+HD_CACHE]
74
;    push  eax
75
        call    calculate_cache_1
76
        lea     esi, [edi*8+esi]
77
;    pop   eax
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
86
;    add   esi,HD_CACHE+65536
87
        push    eax
88
        call    calculate_cache_2
89
        add     esi, eax
90
        pop     eax
91
 
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
 
3702 mario79 104
        ; Выбрать нужный диск
105
        mov     edx, [hdbase]
106
        add     edx, 6   ;адрес регистра головок
107
        mov     al, byte [hdid]
108
        add     al, 128+64+32
109
        out     dx, al; номер головки/номер диска
110
 
2288 clevermous 111
        call    wait_for_hd_idle
112
        cmp     [hd_error], 0
113
        jne     hd_read_error
3702 mario79 114
 
115
; ATA with 28 or 48 bit for sector number?
116
        mov     eax, [esp+4]
117
        cmp     eax, 0x10000000
118
        jae     .lba48
119
.lba28:
2288 clevermous 120
        cli
121
        xor     eax, eax
122
        mov     edx, [hdbase]
123
        inc     edx
3539 clevermous 124
        out     dx, al; ATAFeatures регистр "особенностей"
2288 clevermous 125
        inc     edx
126
        inc     eax
3539 clevermous 127
        out     dx, al; ATASectorCount счётчик секторов
2288 clevermous 128
        inc     edx
129
        mov     eax, [esp+4]
3539 clevermous 130
        out     dx, al; ATASectorNumber регистр номера сектора
2288 clevermous 131
        shr     eax, 8
132
        inc     edx
3539 clevermous 133
        out     dx, al; ATACylinder номер цилиндра (младший байт)
2288 clevermous 134
        shr     eax, 8
135
        inc     edx
3539 clevermous 136
        out     dx, al; номер цилиндра (старший байт)
2288 clevermous 137
        shr     eax, 8
138
        inc     edx
139
        and     al, 1+2+4+8
140
        add     al, byte [hdid]
141
        add     al, 128+64+32
3539 clevermous 142
        out     dx, al; номер головки/номер диска
2288 clevermous 143
        inc     edx
144
        mov     al, 20h
3539 clevermous 145
        out     dx, al; ATACommand регистр команд
2288 clevermous 146
        sti
3702 mario79 147
	jmp	.continue
148
.lba48:
149
        cli
150
        xor     eax, eax
151
        mov     edx, [hdbase]
152
        inc     edx
153
        out     dx, al ; Features Previous Reserved
154
        out     dx, al ; Features Current Reserved
155
        inc     edx
156
        out     dx, al ; Sector Count Previous Sector count (15:8)
157
        inc     eax
158
        out     dx, al ; Sector Count Current Sector count (7:0)
159
        inc     edx
160
        mov     eax, [esp+4]
161
	rol	eax,8
162
        out     dx, al ; LBA Low Previous LBA (31:24)
163
	xor	eax,eax ; because only 32 bit cache
164
        inc     edx
165
        out     dx, al ; LBA Mid Previous LBA (39:32)
166
        inc     edx
167
        out     dx, al ; LBA High Previous LBA (47:40)
168
	sub	edx,2
169
        mov     eax, [esp+4]
170
        out     dx, al ; LBA Low Current LBA (7:0)
171
        shr     eax, 8
172
        inc     edx
173
        out     dx, al ; LBA Mid Current LBA (15:8)
174
        shr     eax, 8
175
        inc     edx
176
        out     dx, al ; LBA High Current LBA (23:16)
177
        inc     edx
178
        mov     al, byte [hdid]
179
        add     al, 128+64+32
180
        out     dx, al; номер головки/номер диска
181
        inc     edx
182
        mov     al, 24h	; READ SECTOR(S) EXT
183
        out     dx, al; ATACommand регистр команд
184
        sti
185
.continue:
2288 clevermous 186
        call    wait_for_sector_buffer
187
 
188
        cmp     [hd_error], 0
189
        jne     hd_read_error
190
 
191
        cli
192
        push    edi
193
        shl     edi, 9
194
;    add   edi,HD_CACHE+65536
195
        push    eax
196
        call    calculate_cache_2
197
        add     edi, eax
198
        pop     eax
199
 
200
        mov     ecx, 256
201
        mov     edx, [hdbase]
202
        cld
203
        rep insw
204
        pop     edi
205
        sti
206
 
207
        pop     edx eax
208
        ret
209
 
210
disable_ide_int:
211
;        mov edx,[hdbase]
212
;        add edx,0x206
213
;        mov al,2
214
;        out dx,al
215
        cli
216
        ret
217
 
218
enable_ide_int:
219
;        mov edx,[hdbase]
220
;        add edx,0x206
221
;        mov al,0
222
;        out dx,al
223
        sti
224
        ret
225
 
226
align 4
227
hd_write:
228
;-----------------------------------------------------------
229
; input  : eax = block
230
;          ebx = pointer to memory
231
;-----------------------------------------------------------
232
        push    ecx esi edi
233
 
234
    ; check if the cache already has the sector and overwrite it
235
 
236
;    mov   ecx,cache_max
237
;    mov   esi,HD_CACHE+8
238
        call    calculate_cache
239
        add     esi, 8
240
 
241
        mov     edi, 1
242
 
243
  hdwritecache:
244
 
245
        cmp     dword [esi+4], 0; if cache slot is empty
246
        je      not_in_cache_write
247
 
248
        cmp     [esi], eax      ; if the slot has the sector
249
        je      yes_in_cache_write
250
 
251
  not_in_cache_write:
252
 
253
        add     esi, 8
254
        inc     edi
255
        dec     ecx
256
        jnz     hdwritecache
257
 
258
    ; sector not found in cache
259
    ; write the block to a new location
260
 
261
        call    find_empty_slot ; ret in edi
262
        cmp     [hd_error], 0
263
        jne     hd_write_access_denied
264
 
265
;    lea   esi,[edi*8+HD_CACHE]
266
;    push  eax
267
        call    calculate_cache_1
268
        lea     esi, [edi*8+esi]
269
;    pop   eax
270
 
271
        mov     [esi], eax      ; sector number
272
 
273
  yes_in_cache_write:
274
 
275
        mov     dword [esi+4], 2; write - differs from hd
276
 
277
        shl     edi, 9
278
;    add   edi,HD_CACHE+65536
279
        push    eax
280
        call    calculate_cache_2
281
        add     edi, eax
282
        pop     eax
283
 
284
        mov     esi, ebx
285
        mov     ecx, 512/4
286
        cld
287
        rep movsd               ; move data
288
 hd_write_access_denied:
289
        pop     edi esi ecx
290
        ret
291
 
292
align 4
293
cache_write_pio:
294
        cmp     dword[esi], 0x10000000
295
        jae     .bad
296
;    call  disable_ide_int
297
 
3702 mario79 298
        ; Выбрать нужный диск
299
        mov     edx, [hdbase]
300
        add     edx, 6   ;адрес регистра головок
301
        mov     al, byte [hdid]
302
        add     al, 128+64+32
303
        out     dx, al; номер головки/номер диска
304
 
2288 clevermous 305
        call    wait_for_hd_idle
306
        cmp     [hd_error], 0
307
        jne     hd_write_error
308
 
309
        cli
310
        xor     eax, eax
311
        mov     edx, [hdbase]
312
        inc     edx
313
        out     dx, al
314
        inc     edx
315
        inc     eax
316
        out     dx, al
317
        inc     edx
318
        mov     eax, [esi]      ; eax = sector to write
319
        out     dx, al
320
        shr     eax, 8
321
        inc     edx
322
        out     dx, al
323
        shr     eax, 8
324
        inc     edx
325
        out     dx, al
326
        shr     eax, 8
327
        inc     edx
328
        and     al, 1+2+4+8
329
        add     al, byte [hdid]
330
        add     al, 128+64+32
331
        out     dx, al
332
        inc     edx
333
        mov     al, 30h
334
        out     dx, al
335
        sti
336
 
337
        call    wait_for_sector_buffer
338
 
339
        cmp     [hd_error], 0
340
        jne     hd_write_error
341
 
342
        push    ecx esi
343
 
344
        cli
345
        mov     esi, edi
346
        shl     esi, 9
347
;    add   esi,HD_CACHE+65536    ; esi = from memory position
348
        push    eax
349
        call    calculate_cache_2
350
        add     esi, eax
351
        pop     eax
352
 
353
        mov     ecx, 256
354
        mov     edx, [hdbase]
355
        cld
356
        rep outsw
357
        sti
358
 
359
;    call  enable_ide_int
360
        pop     esi ecx
361
 
362
        ret
363
.bad:
364
        inc     [hd_error]
365
        ret
366
 
367
save_hd_wait_timeout:
368
 
369
        push    eax
370
        mov     eax, [timer_ticks]
371
        add     eax, 300        ; 3 sec timeout
372
        mov     [hd_wait_timeout], eax
373
        pop     eax
374
        ret
375
 
376
align 4
377
check_hd_wait_timeout:
378
 
379
        push    eax
380
        mov     eax, [hd_wait_timeout]
381
        cmp     [timer_ticks], eax
382
        jg      hd_timeout_error
383
        pop     eax
384
        mov     [hd_error], 0
385
        ret
386
 
387
;iglobal
388
;  hd_timeout_str   db 'K : FS - HD timeout',0
389
;  hd_read_str      db 'K : FS - HD read error',0
390
;  hd_write_str     db 'K : FS - HD write error',0
391
;  hd_lba_str       db 'K : FS - HD LBA error',0
392
;endg
393
 
394
hd_timeout_error:
395
 
396
;    call  clear_hd_cache
397
;    call  clear_application_table_status
398
;    mov   esi,hd_timeout_str
399
;    call  sys_msg_board_str
3309 esevece 400
    if lang eq sp
401
    DEBUGF 1,"K : FS - HD tiempo de espera agotado\n"
402
    else
2288 clevermous 403
    DEBUGF 1,"K : FS - HD timeout\n"
3309 esevece 404
    end if
2288 clevermous 405
 
406
        mov     [hd_error], 1
407
        pop     eax
408
        ret
409
 
410
hd_read_error:
411
 
412
;    call  clear_hd_cache
413
;    call  clear_application_table_status
414
;    mov   esi,hd_read_str
415
;    call  sys_msg_board_str
3309 esevece 416
    if lang eq sp
417
    DEBUGF 1,"K : FS - HD error de lectura\n"
418
    else
2288 clevermous 419
    DEBUGF 1,"K : FS - HD read error\n"
3309 esevece 420
    end if
2288 clevermous 421
        pop     edx eax
422
        ret
423
 
424
hd_write_error:
425
 
426
;    call  clear_hd_cache
427
;    call  clear_application_table_status
428
;     mov   esi,hd_write_str
429
;     call  sys_msg_board_str
3309 esevece 430
    if lang eq sp
431
    DEBUGF 1,"K : FS - HD error de escritura\n"
432
    else
2288 clevermous 433
    DEBUGF 1,"K : FS - HD write error\n"
3309 esevece 434
    end if
2288 clevermous 435
        ret
436
 
437
hd_write_error_dma:
438
;        call    clear_hd_cache
439
;        call    clear_application_table_status
440
;        mov     esi, hd_write_str
441
;        call    sys_msg_board_str
3309 esevece 442
        if lang eq sp
443
        DEBUGF 1,"K : FS - HD error de escritura\n"
444
        else
445
        DEBUGF 1,"K : FS - HD write error\n"
446
        end if
2288 clevermous 447
        pop     esi
448
        ret
449
 
450
hd_lba_error:
451
;    call  clear_hd_cache
452
;    call  clear_application_table_status
453
;    mov   esi,hd_lba_str
454
;    call  sys_msg_board_str
3309 esevece 455
     if lang eq sp
456
     DEBUGF 1,"K : FS - HD error en LBA\n"
457
     else
2288 clevermous 458
     DEBUGF 1,"K : FS - HD LBA error\n"
3309 esevece 459
     end if
2288 clevermous 460
        jmp     LBA_read_ret
461
 
462
 
463
align 4
464
wait_for_hd_idle:
465
 
466
        push    eax edx
467
 
468
        call    save_hd_wait_timeout
469
 
470
        mov     edx, [hdbase]
471
        add     edx, 0x7
472
 
473
  wfhil1:
474
 
475
        call    check_hd_wait_timeout
476
        cmp     [hd_error], 0
477
        jne     @f
478
 
479
        in      al, dx
480
        test    al, 128
481
        jnz     wfhil1
482
 
483
 @@:
484
 
485
        pop     edx eax
486
        ret
487
 
488
 
489
align 4
490
wait_for_sector_buffer:
491
 
492
        push    eax edx
493
 
494
        mov     edx, [hdbase]
495
        add     edx, 0x7
496
 
497
        call    save_hd_wait_timeout
498
 
499
  hdwait_sbuf:                  ; wait for sector buffer to be ready
500
 
501
        call    check_hd_wait_timeout
502
        cmp     [hd_error], 0
503
        jne     @f
504
 
505
        in      al, dx
506
        test    al, 8
507
        jz      hdwait_sbuf
508
 
509
        mov     [hd_error], 0
510
 
511
        cmp     [hd_setup], 1   ; do not mark error for setup request
512
        je      buf_wait_ok
513
 
514
        test    al, 1           ; previous command ended up with an error
515
        jz      buf_wait_ok
516
 @@:
517
        mov     [hd_error], 1
518
 
519
  buf_wait_ok:
520
 
521
        pop     edx eax
522
        ret
523
 
524
; \begin{Mario79}
525
align 4
526
wait_for_sector_dma_ide0:
527
        push    eax
528
        push    edx
529
        call    save_hd_wait_timeout
530
.wait:
531
        call    change_task
532
        cmp     [irq14_func], hdd_irq14
533
        jnz     .done
534
        call    check_hd_wait_timeout
535
        cmp     [hd_error], 0
536
        jz      .wait
537
        mov     [irq14_func], hdd_irq_null
538
        mov     dx, [IDEContrRegsBaseAddr]
539
        mov     al, 0
540
        out     dx, al
541
.done:
542
        pop     edx
543
        pop     eax
544
        ret
545
 
546
align 4
547
wait_for_sector_dma_ide1:
548
        push    eax
549
        push    edx
550
        call    save_hd_wait_timeout
551
.wait:
552
        call    change_task
553
        cmp     [irq15_func], hdd_irq15
554
        jnz     .done
555
        call    check_hd_wait_timeout
556
        cmp     [hd_error], 0
557
        jz      .wait
558
        mov     [irq15_func], hdd_irq_null
559
        mov     dx, [IDEContrRegsBaseAddr]
560
        add     dx, 8
561
        mov     al, 0
562
        out     dx, al
563
.done:
564
        pop     edx
565
        pop     eax
566
        ret
567
 
568
iglobal
569
align 4
570
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
571
IDE_descriptor_table:
572
        dd      IDE_DMA
573
        dw      0x2000
574
        dw      0x8000
575
 
576
dma_cur_sector  dd      not 40h
577
dma_hdpos       dd      0
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
allow_dma_access db      0
593
endg
594
 
595
align 4
596
hdd_irq14:
597
        pushfd
598
        cli
599
        pushad
600
        mov     [irq14_func], hdd_irq_null
601
        mov     dx, [IDEContrRegsBaseAddr]
602
        mov     al, 0
603
        out     dx, al
604
;        call    update_counters
605
;        mov     ebx, [dma_process]
606
;        cmp     [CURRENT_TASK], ebx
607
;        jz      .noswitch
608
;        mov     [dma_task_switched], 1
609
;        mov     edi, [dma_slot_ptr]
610
;        mov     eax, [CURRENT_TASK]
611
;        mov     [dma_process], eax
612
;        mov     eax, [TASK_BASE]
613
;        mov     [dma_slot_ptr], eax
614
;        mov     [CURRENT_TASK], ebx
615
;        mov     [TASK_BASE], edi
616
;        mov     byte [DONT_SWITCH], 1
617
;        call    do_change_task
618
.noswitch:
619
        popad
620
        popfd
621
align 4
622
hdd_irq_null:
623
        ret
624
 
625
align 4
626
hdd_irq15:
627
        pushfd
628
        cli
629
        pushad
630
        mov     [irq15_func], hdd_irq_null
631
        mov     dx, [IDEContrRegsBaseAddr]
632
        add     dx, 8
633
        mov     al, 0
634
        out     dx, al
635
;        call    update_counters
636
;        mov     ebx, [dma_process]
637
;        cmp     [CURRENT_TASK], ebx
638
;        jz      .noswitch
639
;        mov     [dma_task_switched], 1
640
;        mov     edi, [dma_slot_ptr]
641
;        mov     eax, [CURRENT_TASK]
642
;        mov     [dma_process], eax
643
;        mov     eax, [TASK_BASE]
644
;        mov     [dma_slot_ptr], eax
645
;        mov     [CURRENT_TASK], ebx
646
;        mov     [TASK_BASE], edi
647
;        mov     byte [DONT_SWITCH], 1
648
;        call    do_change_task
649
.noswitch:
650
        popad
651
        popfd
652
        ret
653
 
654
align 4
655
hd_read_dma:
3702 mario79 656
; hd_read_dma use old ATA with 28 bit for sector number
657
        cmp     eax, 0x10000000
658
        jb      @f
659
        inc     [hd_error]
660
        ret
661
@@:
2288 clevermous 662
        push    eax
663
        push    edx
664
        mov     edx, [dma_hdpos]
665
        cmp     edx, [hdpos]
666
        jne     .notread
667
        mov     edx, [dma_cur_sector]
668
        cmp     eax, edx
669
        jb      .notread
670
        add     edx, 15
671
        cmp     [esp+4], edx
672
        ja      .notread
673
        mov     eax, [esp+4]
674
        sub     eax, [dma_cur_sector]
675
        shl     eax, 9
676
        add     eax, (OS_BASE+IDE_DMA)
677
        push    ecx esi edi
678
        mov     esi, eax
679
        shl     edi, 9
680
;        add     edi, HD_CACHE+0x10000
681
        push    eax
682
        call    calculate_cache_2
683
        add     edi, eax
684
        pop     eax
685
 
686
        mov     ecx, 512/4
687
        cld
688
        rep movsd
689
        pop     edi esi ecx
690
        pop     edx
691
        pop     eax
692
        ret
693
.notread:
694
        mov     eax, IDE_descriptor_table
695
        mov     dword [eax], IDE_DMA
696
        mov     word [eax+4], 0x2000
697
        sub     eax, OS_BASE
698
        mov     dx, [IDEContrRegsBaseAddr]
699
        cmp     [hdbase], 0x1F0
700
        jz      @f
701
        add     edx, 8
702
@@:
703
        push    edx
704
        add     edx, 4
705
        out     dx, eax
706
        pop     edx
707
        mov     al, 0
708
        out     dx, al
709
        add     edx, 2
710
        mov     al, 6
711
        out     dx, al
712
        call    wait_for_hd_idle
713
        cmp     [hd_error], 0
714
        jnz     hd_read_error
715
        call    disable_ide_int
716
        xor     eax, eax
717
        mov     edx, [hdbase]
718
        inc     edx
719
        out     dx, al
720
        inc     edx
721
        mov     eax, 10h
722
        out     dx, al
723
        inc     edx
724
        mov     eax, [esp+4]
725
        out     dx, al
726
        shr     eax, 8
727
        inc     edx
728
        out     dx, al
729
        shr     eax, 8
730
        inc     edx
731
        out     dx, al
732
        shr     eax, 8
733
        inc     edx
734
        and     al, 0xF
735
        add     al, byte [hdid]
736
        add     al, 11100000b
737
        out     dx, al
738
        inc     edx
739
        mov     al, 0xC8
740
        out     dx, al
741
        mov     dx, [IDEContrRegsBaseAddr]
742
        cmp     [hdbase], 0x1F0
743
        jz      @f
744
        add     dx, 8
745
@@:
746
        mov     al, 9
747
        out     dx, al
748
        mov     eax, [CURRENT_TASK]
749
        mov     [dma_process], eax
750
        mov     eax, [TASK_BASE]
751
        mov     [dma_slot_ptr], eax
752
        cmp     [hdbase], 0x1F0
753
        jnz     .ide1
754
        mov     [irq14_func], hdd_irq14
755
        jmp     @f
756
.ide1:
757
        mov     [irq15_func], hdd_irq15
758
@@:
759
        call    enable_ide_int
760
        cmp     [hdbase], 0x1F0
761
        jnz     .wait_ide1
762
        call    wait_for_sector_dma_ide0
763
        jmp     @f
764
.wait_ide1:
765
        call    wait_for_sector_dma_ide1
766
@@:
767
        cmp     [hd_error], 0
768
        jnz     hd_read_error
769
        mov     eax, [hdpos]
770
        mov     [dma_hdpos], eax
771
        pop     edx
772
        pop     eax
773
        mov     [dma_cur_sector], eax
774
        jmp     hd_read_dma
775
 
776
align 4
777
write_cache_sector:
778
        mov     [cache_chain_size], 1
779
        mov     [cache_chain_pos], edi
780
write_cache_chain:
781
        cmp     [hdpos], 0x80
782
        jae     bd_write_cache_chain
783
        mov     eax, [cache_chain_ptr]
784
        cmp     dword[eax], 0x10000000
785
        jae     .bad
786
        push    esi
787
        mov     eax, IDE_descriptor_table
788
        mov     edx, eax
789
        pusha
790
        mov     esi, [cache_chain_pos]
791
        shl     esi, 9
792
        call    calculate_cache_2
793
        add     esi, eax
794
        mov     edi, (OS_BASE+IDE_DMA)
795
        mov     dword [edx], IDE_DMA
796
        movzx   ecx, [cache_chain_size]
797
        shl     ecx, 9
798
        mov     word [edx+4], cx
799
        shr     ecx, 2
800
        cld
801
        rep movsd
802
        popa
803
        sub     eax, OS_BASE
804
        mov     dx, [IDEContrRegsBaseAddr]
805
        cmp     [hdbase], 0x1F0
806
        jz      @f
807
        add     edx, 8
808
@@:
809
        push    edx
810
        add     edx, 4
811
        out     dx, eax
812
        pop     edx
813
        mov     al, 0
814
        out     dx, al
815
        add     edx, 2
816
        mov     al, 6
817
        out     dx, al
818
        call    wait_for_hd_idle
819
        cmp     [hd_error], 0
820
        jnz     hd_write_error_dma
821
        call    disable_ide_int
822
        xor     eax, eax
823
        mov     edx, [hdbase]
824
        inc     edx
825
        out     dx, al
826
        inc     edx
827
        mov     al, [cache_chain_size]
828
        out     dx, al
829
        inc     edx
830
        mov     esi, [cache_chain_ptr]
831
        mov     eax, [esi]
832
        out     dx, al
833
        shr     eax, 8
834
        inc     edx
835
        out     dx, al
836
        shr     eax, 8
837
        inc     edx
838
        out     dx, al
839
        shr     eax, 8
840
        inc     edx
841
        and     al, 0xF
842
        add     al, byte [hdid]
843
        add     al, 11100000b
844
        out     dx, al
845
        inc     edx
846
        mov     al, 0xCA
847
        out     dx, al
848
        mov     dx, [IDEContrRegsBaseAddr]
849
        cmp     [hdbase], 0x1F0
850
        jz      @f
851
        add     dx, 8
852
@@:
853
        mov     al, 1
854
        out     dx, al
855
        mov     eax, [CURRENT_TASK]
856
        mov     [dma_process], eax
857
        mov     eax, [TASK_BASE]
858
        mov     [dma_slot_ptr], eax
859
        cmp     [hdbase], 0x1F0
860
        jnz     .ide1
861
        mov     [irq14_func], hdd_irq14
862
        jmp     @f
863
.ide1:
864
        mov     [irq15_func], hdd_irq15
865
@@:
866
        call    enable_ide_int
867
        mov     [dma_cur_sector], not 0x40
868
        cmp     [hdbase], 0x1F0
869
        jnz     .wait_ide1
870
        call    wait_for_sector_dma_ide0
871
        jmp     @f
872
.wait_ide1:
873
        call    wait_for_sector_dma_ide1
874
@@:
875
        cmp     [hd_error], 0
876
        jnz     hd_write_error_dma
877
        pop     esi
878
        ret
879
.bad:
880
        inc     [hd_error]
881
        ret
882
 
883
uglobal
884
IDEContrRegsBaseAddr    dw      ?
3702 mario79 885
IDEContrProgrammingInterface   dw ?
886
IDE_BAR0_val	dw ?
887
IDE_BAR1_val	dw ?
888
IDE_BAR2_val	dw ?
889
IDE_BAR3_val	dw ?
2288 clevermous 890
endg
891
; \end{Mario79}
892
 
893
; \begin{diamond}
894
uglobal
895
bios_hdpos      dd      0       ; 0 is invalid value for [hdpos]
896
bios_cur_sector dd      ?
897
bios_read_len   dd      ?
898
endg
899
bd_read:
900
        push    eax
901
        push    edx
902
        mov     edx, [bios_hdpos]
903
        cmp     edx, [hdpos]
904
        jne     .notread
905
        mov     edx, [bios_cur_sector]
906
        cmp     eax, edx
907
        jb      .notread
908
        add     edx, [bios_read_len]
909
        dec     edx
910
        cmp     eax, edx
911
        ja      .notread
912
        sub     eax, [bios_cur_sector]
913
        shl     eax, 9
914
        add     eax, (OS_BASE+0x9A000)
915
        push    ecx esi edi
916
        mov     esi, eax
917
        shl     edi, 9
918
;        add     edi, HD_CACHE+0x10000
919
        push    eax
920
        call    calculate_cache_2
921
        add     edi, eax
922
        pop     eax
923
 
924
        mov     ecx, 512/4
925
        cld
926
        rep movsd
927
        pop     edi esi ecx
928
        pop     edx
929
        pop     eax
930
        ret
931
.notread:
932
        push    ecx
933
        mov     dl, 42h
934
        mov     ecx, 16
935
        call    int13_call
936
        pop     ecx
937
        test    eax, eax
938
        jnz     .v86err
939
        test    edx, edx
940
        jz      .readerr
941
        mov     [bios_read_len], edx
942
        mov     edx, [hdpos]
943
        mov     [bios_hdpos], edx
944
        pop     edx
945
        pop     eax
946
        mov     [bios_cur_sector], eax
947
        jmp     bd_read
948
.readerr:
949
.v86err:
950
        mov     [hd_error], 1
951
        jmp     hd_read_error
952
 
953
bd_write_cache_chain:
954
        pusha
955
        mov     esi, [cache_chain_pos]
956
        shl     esi, 9
957
        call    calculate_cache_2
958
        add     esi, eax
959
        mov     edi, OS_BASE + 0x9A000
960
        movzx   ecx, [cache_chain_size]
961
        push    ecx
962
        shl     ecx, 9-2
963
        rep movsd
964
        pop     ecx
965
        mov     dl, 43h
966
        mov     eax, [cache_chain_ptr]
967
        mov     eax, [eax]
968
        call    int13_call
969
        test    eax, eax
970
        jnz     .v86err
971
        cmp     edx, ecx
972
        jnz     .writeerr
973
        popa
974
        ret
975
.v86err:
976
.writeerr:
977
        popa
978
        mov     [hd_error], 1
979
        jmp     hd_write_error
980
 
981
uglobal
2384 hidnplayr 982
int13_regs_in   rb      sizeof.v86_regs
983
int13_regs_out  rb      sizeof.v86_regs
2288 clevermous 984
endg
985
 
986
int13_call:
987
; Because this code uses fixed addresses,
988
; it can not be run simultaniously by many threads.
989
; In current implementation it is protected by common mutex 'hd1_status'
990
        mov     word [OS_BASE + 510h], 10h             ; packet length
991
        mov     word [OS_BASE + 512h], cx              ; number of sectors
992
        mov     dword [OS_BASE + 514h], 9A000000h      ; buffer 9A00:0000
993
        mov     dword [OS_BASE + 518h], eax
994
        and     dword [OS_BASE + 51Ch], 0
995
        push    ebx ecx esi edi
996
        mov     ebx, int13_regs_in
997
        mov     edi, ebx
2384 hidnplayr 998
        mov     ecx, sizeof.v86_regs/4
2288 clevermous 999
        xor     eax, eax
1000
        rep stosd
1001
        mov     byte [ebx+v86_regs.eax+1], dl
1002
        mov     eax, [hdpos]
1003
        lea     eax, [BiosDisksData+(eax-80h)*4]
1004
        mov     dl, [eax]
1005
        mov     byte [ebx+v86_regs.edx], dl
1006
        movzx   edx, byte [eax+1]
1007
;        mov     dl, 5
1008
        test    edx, edx
1009
        jnz     .hasirq
1010
        dec     edx
1011
        jmp     @f
1012
.hasirq:
1013
        pushad
1014
        stdcall enable_irq, edx
1015
        popad
1016
@@:
1017
        mov     word [ebx+v86_regs.esi], 510h
1018
        mov     word [ebx+v86_regs.ss], 9000h
1019
        mov     word [ebx+v86_regs.esp], 0A000h
1020
        mov     word [ebx+v86_regs.eip], 500h
1021
        mov     [ebx+v86_regs.eflags], 20200h
1022
        mov     esi, [sys_v86_machine]
1023
        mov     ecx, 0x502
1024
        push    fs
1025
        call    v86_start
1026
        pop     fs
1027
        and     [bios_hdpos], 0
1028
        pop     edi esi ecx ebx
1029
        movzx   edx, byte [OS_BASE + 512h]
1030
        test    byte [int13_regs_out+v86_regs.eflags], 1
1031
        jnz     @f
1032
        mov     edx, ecx
1033
@@:
1034
        ret
1035
; \end{diamond}
2643 clevermous 1036
 
1037
reserve_hd1:
1038
 
1039
        cli
1040
        cmp     [hd1_status], 0
1041
        je      reserve_ok1
1042
 
1043
        sti
1044
        call    change_task
1045
        jmp     reserve_hd1
1046
 
1047
  reserve_ok1:
1048
 
1049
        push    eax
1050
        mov     eax, [CURRENT_TASK]
1051
        shl     eax, 5
1052
        mov     eax, [eax+CURRENT_TASK+TASKDATA.pid]
1053
        mov     [hd1_status], eax
1054
        pop     eax
1055
        sti
1056
        ret
1057
;********************************************
1058
 
1059
uglobal
1060
hd_in_cache db ?
1061
endg
1062
 
1063
reserve_hd_channel:
1064
; BIOS disk accesses are protected with common mutex hd1_status
1065
; This must be modified when hd1_status will not be valid!
1066
        cmp     [hdpos], 0x80
1067
        jae     .ret
1068
        cmp     [hdbase], 0x1F0
1069
        jne     .IDE_Channel_2
1070
.IDE_Channel_1:
1071
        cli
1072
        cmp     [IDE_Channel_1], 0
1073
        je      .reserve_ok_1
1074
        sti
1075
        call    change_task
1076
        jmp     .IDE_Channel_1
1077
.IDE_Channel_2:
1078
        cli
1079
        cmp     [IDE_Channel_2], 0
1080
        je      .reserve_ok_2
1081
        sti
1082
        call    change_task
1083
        jmp     .IDE_Channel_2
1084
.reserve_ok_1:
1085
        mov     [IDE_Channel_1], 1
1086
        push    eax
1087
        mov     al, 1
1088
        jmp     @f
1089
.reserve_ok_2:
1090
        mov     [IDE_Channel_2], 1
1091
        push    eax
1092
        mov     al, 3
1093
@@:
1094
        cmp     [hdid], 1
1095
        sbb     al, -1
1096
        mov     [hd_in_cache], al
1097
        pop     eax
1098
        sti
1099
.ret:
1100
        ret
1101
 
1102
free_hd_channel:
1103
; see comment at reserve_hd_channel
1104
        cmp     [hdpos], 0x80
1105
        jae     .ret
1106
        cmp     [hdbase], 0x1F0
1107
        jne     .IDE_Channel_2
1108
.IDE_Channel_1:
1109
        mov     [IDE_Channel_1], 0
1110
.ret:
1111
        ret
1112
.IDE_Channel_2:
1113
        mov     [IDE_Channel_2], 0
1114
        ret
1115
;********************************************