Subversion Repositories Kolibri OS

Rev

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