Subversion Repositories Kolibri OS

Rev

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