Subversion Repositories Kolibri OS

Rev

Rev 4291 | Rev 5363 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4291 Rev 4420
Line 3... Line 3...
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 7... Line 7...
7
 
7
 
Line 8... Line -...
8
$Revision: 4291 $
-
 
9
 
-
 
10
 
8
$Revision: 4420 $
11
; Low-level driver for HDD access
-
 
12
; DMA support by Mario79
-
 
13
; Access through BIOS by diamond
-
 
14
; LBA48 support by Mario79
-
 
15
;-----------------------------------------------------------------------------
-
 
16
struct HD_DATA
-
 
17
hdbase  dd      ?
-
 
18
hdid    dd      ?
-
 
19
hdpos   dd      ?
9
 
20
ends
10
 
21
 
-
 
22
iglobal
-
 
23
align 4
-
 
24
ide_callbacks:
-
 
25
        dd      ide_callbacks.end - ide_callbacks       ; strucsize
-
 
26
        dd      0       ; no close function
-
 
27
        dd      0       ; no closemedia function
-
 
28
        dd      ide_querymedia
-
 
29
        dd      ide_read
-
 
30
        dd      ide_write
-
 
31
        dd      0       ; no flush function
-
 
32
        dd      0       ; use default cache size
11
; Access through BIOS by diamond
33
.end:
12
iglobal
34
 
13
align 4
35
bd_callbacks:
14
bd_callbacks:
36
        dd      bd_callbacks.end - bd_callbacks         ; strucsize
15
        dd      bd_callbacks.end - bd_callbacks         ; strucsize
37
        dd      0       ; no close function
16
        dd      0       ; no close function
38
        dd      0       ; no closemedia function
17
        dd      0       ; no closemedia function
39
        dd      bd_querymedia
18
        dd      bd_querymedia
40
        dd      bd_read_interface
19
        dd      bd_read_interface
41
        dd      bd_write_interface
20
        dd      bd_write_interface
42
        dd      0       ; no flush function
-
 
43
        dd      0       ; use default cache size
-
 
44
.end:
-
 
45
 
-
 
46
hd0_data        HD_DATA         ?,    0, 1
-
 
47
hd1_data        HD_DATA         ?, 0x10, 2
-
 
48
hd2_data        HD_DATA         ?,    0, 3
-
 
49
hd3_data        HD_DATA         ?, 0x10, 4
-
 
50
 
-
 
51
hd_address_table:
21
        dd      0       ; no flush function
Line 52... Line -...
52
        dd      0x1f0, 0x00, 0x1f0, 0x10
-
 
53
        dd      0x170, 0x00, 0x170, 0x10
-
 
54
endg
-
 
55
 
-
 
56
uglobal
-
 
57
ide_mutex               MUTEX
-
 
58
ide_channel1_mutex      MUTEX
-
 
59
ide_channel2_mutex      MUTEX
-
 
60
endg
-
 
61
 
-
 
62
proc ide_read stdcall uses edi, \
-
 
63
        hd_data, buffer, startsector:qword, numsectors
-
 
64
        ; hd_data = pointer to hd*_data
-
 
65
        ; buffer = pointer to buffer for data
-
 
66
        ; startsector = 64-bit start sector
-
 
67
        ; numsectors = pointer to number of sectors on input,
-
 
68
        ;  must be filled with number of sectors really read
-
 
69
locals
-
 
70
sectors_todo    dd      ?
-
 
71
channel_lock    dd      ?
-
 
72
endl
-
 
73
; 1. Initialize number of sectors: get number of requested sectors
-
 
74
; and say that no sectors were read yet.
-
 
75
        mov     ecx, [numsectors]
-
 
76
        mov     eax, [ecx]
-
 
77
        mov     dword [ecx], 0
-
 
78
        mov     [sectors_todo], eax
-
 
79
; 2. Acquire the global lock.
-
 
80
        mov     ecx, ide_mutex
-
 
81
        call    mutex_lock
-
 
82
        mov     ecx, ide_channel2_mutex
-
 
83
        mov     eax, [hd_data]
-
 
84
        push    ecx
-
 
85
        mov     ecx, [hd_address_table]
-
 
86
        cmp     [eax+HD_DATA.hdbase], ecx ; 0x1F0
-
 
87
        pop     ecx
-
 
88
        jne     .IDE_Channel_2
-
 
89
        mov     ecx, ide_channel1_mutex
-
 
90
.IDE_Channel_2:
-
 
91
        mov     [channel_lock], ecx
-
 
92
        call    mutex_lock
-
 
93
; 3. Convert parameters to the form suitable for worker procedures.
-
 
94
; Underlying procedures do not know about 64-bit sectors.
-
 
95
; Worker procedures use global variables and edi for [buffer].
-
 
96
        cmp     dword [startsector+4], 0
-
 
97
        jnz     .fail
-
 
98
        and     [hd_error], 0
-
 
99
        mov     ecx, [hd_data]
-
 
100
        mov     eax, [ecx+HD_DATA.hdbase]
-
 
101
        mov     [hdbase], eax
-
 
102
        mov     eax, [ecx+HD_DATA.hdid]
-
 
103
        mov     [hdid], eax
-
 
104
        mov     eax, [ecx+HD_DATA.hdpos]
-
 
105
        mov     [hdpos], eax
-
 
106
        mov     eax, dword [startsector]
-
 
107
        mov     edi, [buffer]
-
 
108
; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
-
 
109
.sectors_loop:
-
 
110
; DMA read is permitted if [allow_dma_access]=1 or 2
-
 
111
        cmp     [allow_dma_access], 2
-
 
112
        ja      .nodma
-
 
113
        cmp     [dma_hdd], 1
-
 
114
        jnz     .nodma
-
 
115
;--------------------------------------
-
 
116
        push    eax
-
 
117
        mov     eax, [hd_address_table]
-
 
118
        cmp     [hdbase], eax ; 0x1F0
-
 
119
        pop     eax
-
 
120
        jnz     @f
-
 
121
 
-
 
122
        test    [DRIVE_DATA+1], byte 10100000b
-
 
123
        jnz     .nodma
-
 
124
 
-
 
125
        jmp     .dma
-
 
126
@@:
-
 
127
        test    [DRIVE_DATA+1], byte 1010b
-
 
128
        jnz     .nodma
-
 
129
.dma:
-
 
130
;--------------------------------------
-
 
131
        call    hd_read_dma
-
 
132
        jmp     @f
-
 
133
.nodma:
-
 
134
        call    hd_read_pio
-
 
135
@@:
-
 
136
        cmp     [hd_error], 0
-
 
137
        jnz     .fail
-
 
138
        mov     ecx, [numsectors]
-
 
139
        inc     dword [ecx]     ; one more sector is read
-
 
140
        dec     [sectors_todo]
-
 
141
        jz      .done
-
 
142
        inc     eax
-
 
143
        jnz     .sectors_loop
-
 
144
; 5. Loop is done, either due to error or because everything is done.
-
 
145
; Release the global lock and return the corresponding status.
-
 
146
.fail:
-
 
147
        mov     ecx, [channel_lock]
-
 
148
        call    mutex_unlock
-
 
149
        mov     ecx, ide_mutex
-
 
150
        call    mutex_unlock
-
 
151
        or      eax, -1
-
 
152
        ret
-
 
153
.done:
-
 
154
        mov     ecx, [channel_lock]
-
 
155
        call    mutex_unlock
-
 
156
        mov     ecx, ide_mutex
-
 
157
        call    mutex_unlock
-
 
158
        xor     eax, eax
-
 
159
        ret
-
 
160
endp
-
 
161
 
-
 
162
proc ide_write stdcall uses esi edi, \
-
 
163
        hd_data, buffer, startsector:qword, numsectors
-
 
164
        ; hd_data = pointer to hd*_data
-
 
165
        ; buffer = pointer to buffer with data
-
 
166
        ; startsector = 64-bit start sector
-
 
167
        ; numsectors = pointer to number of sectors on input,
-
 
168
        ;  must be filled with number of sectors really written
-
 
169
locals
-
 
170
sectors_todo    dd      ?
-
 
171
channel_lock    dd      ?
-
 
172
endl
-
 
173
; 1. Initialize number of sectors: get number of requested sectors
-
 
174
; and say that no sectors were read yet.      
-
 
175
        mov     ecx, [numsectors]
-
 
176
        mov     eax, [ecx]
-
 
177
        mov     dword [ecx], 0
-
 
178
        mov     [sectors_todo], eax
-
 
179
; 2. Acquire the global lock.
-
 
180
        mov     ecx, ide_mutex
-
 
181
        call    mutex_lock
-
 
182
        mov     ecx, ide_channel2_mutex
-
 
183
        mov     eax, [hd_data]
-
 
184
        push    ecx
-
 
185
        mov     ecx, [hd_address_table]
-
 
186
        cmp     [eax+HD_DATA.hdbase], ecx ; 0x1F0
-
 
187
        pop     ecx
-
 
188
        jne     .IDE_Channel_2
-
 
189
        mov     ecx, ide_channel1_mutex
-
 
190
.IDE_Channel_2:
-
 
191
        mov     [channel_lock], ecx
-
 
192
        call    mutex_lock
-
 
193
; 3. Convert parameters to the form suitable for worker procedures.
-
 
194
; Underlying procedures do not know about 64-bit sectors.
-
 
195
; Worker procedures use global variables and esi for [buffer].
-
 
196
        cmp     dword [startsector+4], 0
-
 
197
        jnz     .fail
-
 
198
        and     [hd_error], 0
-
 
199
        mov     ecx, [hd_data]
-
 
200
        mov     eax, [ecx+HD_DATA.hdbase]
-
 
201
        mov     [hdbase], eax
-
 
202
        mov     eax, [ecx+HD_DATA.hdid]
-
 
203
        mov     [hdid], eax
-
 
204
        mov     eax, [ecx+HD_DATA.hdpos]
-
 
205
        mov     [hdpos], eax
-
 
206
        mov     esi, [buffer]
-
 
207
        lea     edi, [startsector]
-
 
208
        mov     [cache_chain_ptr], edi
-
 
209
; 4. Worker procedures take max 16 sectors per time,
-
 
210
; loop until all sectors will be processed.
-
 
211
.sectors_loop:
-
 
212
        mov     ecx, 16
-
 
213
        cmp     ecx, [sectors_todo]
-
 
214
        jbe     @f
-
 
215
        mov     ecx, [sectors_todo]
-
 
216
@@:
-
 
217
        mov     [cache_chain_size], cl
-
 
218
; DMA write is permitted only if [allow_dma_access]=1
-
 
219
        cmp     [allow_dma_access], 2
-
 
220
        jae     .nodma
-
 
221
        cmp     [dma_hdd], 1
-
 
222
        jnz     .nodma
-
 
223
;--------------------------------------
-
 
224
        push    eax
-
 
225
        mov     eax, [hd_address_table]
-
 
226
        cmp     [hdbase], eax ; 0x1F0
-
 
227
        pop     eax
-
 
228
        jnz     @f
-
 
229
 
-
 
230
        test    [DRIVE_DATA+1], byte 10100000b
-
 
231
        jnz     .nodma
-
 
232
 
-
 
233
        jmp     .dma
-
 
234
@@:
-
 
235
        test    [DRIVE_DATA+1], byte 1010b
-
 
236
        jnz     .nodma
-
 
237
.dma:
-
 
238
;--------------------------------------
-
 
239
        call    cache_write_dma
-
 
240
        jmp     .common
-
 
241
.nodma:
-
 
242
        mov     [cache_chain_size], 1
-
 
243
        call    cache_write_pio
-
 
244
.common:
-
 
245
        cmp     [hd_error], 0
-
 
246
        jnz     .fail
-
 
247
        movzx   ecx, [cache_chain_size]
-
 
248
        mov     eax, [numsectors]
-
 
249
        add     [eax], ecx
-
 
250
        sub     [sectors_todo], ecx
-
 
251
        jz      .done
-
 
252
        add     [edi], ecx
-
 
253
        jc      .fail
-
 
254
        shl     ecx, 9
-
 
255
        add     esi, ecx
-
 
256
        jmp     .sectors_loop
-
 
257
; 5. Loop is done, either due to error or because everything is done.
-
 
258
; Release the global lock and return the corresponding status.
-
 
259
.fail:
-
 
260
        mov     ecx, [channel_lock]
-
 
261
        call    mutex_unlock
-
 
262
        mov     ecx, ide_mutex
-
 
263
        call    mutex_unlock
-
 
264
        or      eax, -1
-
 
265
        ret
-
 
266
.done:
-
 
267
        mov     ecx, [channel_lock]
-
 
268
        call    mutex_unlock
-
 
269
        mov     ecx, ide_mutex
-
 
270
        call    mutex_unlock
-
 
271
        xor     eax, eax
-
 
272
        ret
-
 
273
endp
-
 
274
 
-
 
275
; This is a stub.
-
 
276
proc ide_querymedia stdcall, hd_data, mediainfo
-
 
277
        mov     eax, [mediainfo]
-
 
278
        mov     [eax+DISKMEDIAINFO.Flags], 0
-
 
279
        mov     [eax+DISKMEDIAINFO.SectorSize], 512
-
 
280
        or      dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
-
 
281
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
-
 
282
        xor     eax, eax
22
        dd      0       ; use default cache size
283
        ret
23
.end:
284
endp
24
endg
285
 
25
 
286
proc bd_read_interface stdcall uses edi, \
26
proc bd_read_interface stdcall uses edi, \
Line 413... Line 153...
413
        xor     eax, eax
153
        xor     eax, eax
414
        ret
154
        ret
415
endp
155
endp
Line 416... Line 156...
416
 
156
 
417
;-----------------------------------------------------------------------------
-
 
418
align 4
-
 
419
; input: eax = sector, edi -> buffer
-
 
420
; output: edi = edi + 512
-
 
421
hd_read_pio:
-
 
422
        push    eax edx
-
 
423
 
-
 
424
; Select the desired drive
-
 
425
        mov     edx, [hdbase]
-
 
426
        add     edx, 6   ;адрес регистра головок
-
 
427
        mov     al, byte [hdid]
-
 
428
        add     al, 128+64+32
-
 
429
        out     dx, al; номер головки/номер диска
-
 
430
        
-
 
431
        call    wait_for_hd_idle
-
 
432
        cmp     [hd_error], 0
-
 
433
        jne     hd_read_error
-
 
434
        
-
 
435
; ATA with 28 or 48 bit for sector number?
-
 
436
        mov     eax, [esp+4]
-
 
437
        cmp     eax, 0x10000000
-
 
438
        jae     .lba48
-
 
439
;--------------------------------------
-
 
440
.lba28:
-
 
441
        pushfd
-
 
442
        cli
-
 
443
        xor     eax, eax
-
 
444
        mov     edx, [hdbase]
-
 
445
        inc     edx
-
 
446
        out     dx, al ; ATA Features регистр "особенностей"
-
 
447
        inc     edx
-
 
448
        inc     eax
-
 
449
        out     dx, al ; ATA Sector Counter счётчик секторов
-
 
450
        inc     edx
-
 
451
        mov     eax, [esp+4+4]
-
 
452
        out     dx, al ; LBA Low LBA (7:0)
-
 
453
        shr     eax, 8
-
 
454
        inc     edx
-
 
455
        out     dx, al ; LBA Mid LBA (15:8)
-
 
456
        shr     eax, 8
-
 
457
        inc     edx
-
 
458
        out     dx, al ; LBA High LBA (23:16)
-
 
459
        shr     eax, 8
-
 
460
        inc     edx
-
 
461
        and     al, 1+2+4+8 ; LBA (27:24)
-
 
462
        add     al, byte [hdid]
-
 
463
        add     al, 128+64+32
-
 
464
        out     dx, al ; номер головки/номер диска
-
 
465
        inc     edx
-
 
466
        mov     al, 20h ; READ SECTOR(S)
-
 
467
        out     dx, al ; ATACommand регистр команд
-
 
468
        popfd
-
 
469
        jmp     .continue
-
 
470
;--------------------------------------
-
 
471
.lba48:
-
 
472
        pushfd
-
 
473
        cli
-
 
474
        xor     eax, eax
-
 
475
        mov     edx, [hdbase]
-
 
476
        inc     edx
-
 
477
        out     dx, al ; Features Previous Reserved
-
 
478
        out     dx, al ; Features Current Reserved
-
 
479
        inc     edx
-
 
480
        out     dx, al ; Sector Count Previous Sector count (15:8)
-
 
481
        inc     eax
-
 
482
        out     dx, al ; Sector Count Current Sector count (7:0)
-
 
483
        inc     edx
-
 
484
        mov     eax, [esp+4+4]
-
 
485
        rol     eax, 8
-
 
486
        out     dx, al ; LBA Low Previous LBA (31:24)
-
 
487
        xor     eax, eax ; because only 32 bit cache
-
 
488
        inc     edx
-
 
489
        out     dx, al ; LBA Mid Previous LBA (39:32)
-
 
490
        inc     edx
-
 
491
        out     dx, al ; LBA High Previous LBA (47:40)
-
 
492
        sub     edx, 2
-
 
493
        mov     eax, [esp+4+4]
-
 
494
        out     dx, al ; LBA Low Current LBA (7:0)
-
 
495
        shr     eax, 8
-
 
496
        inc     edx
-
 
497
        out     dx, al ; LBA Mid Current LBA (15:8)
-
 
498
        shr     eax, 8
-
 
499
        inc     edx
-
 
500
        out     dx, al ; LBA High Current LBA (23:16)
-
 
501
        inc     edx
-
 
502
        mov     al, byte [hdid]
-
 
503
        add     al, 128+64+32
-
 
504
        out     dx, al ; номер головки/номер диска
-
 
505
        inc     edx
-
 
506
        mov     al, 24h ; READ SECTOR(S) EXT
-
 
507
        out     dx, al ; ATACommand регистр команд
-
 
508
        popfd
-
 
509
;--------------------------------------
-
 
510
.continue:
-
 
511
        call    wait_for_sector_buffer
-
 
512
 
-
 
513
        cmp     [hd_error], 0
-
 
514
        jne     hd_read_error
-
 
515
 
-
 
516
        pushfd
-
 
517
        cli
-
 
518
 
-
 
519
        mov     ecx, 256
-
 
520
        mov     edx, [hdbase]
-
 
521
        cld
-
 
522
        rep insw
-
 
523
        popfd
-
 
524
 
-
 
525
        pop     edx eax
-
 
526
        ret
-
 
527
;-----------------------------------------------------------------------------
-
 
528
align 4
-
 
529
; edi -> sector, esi -> data
-
 
530
cache_write_pio:
-
 
531
; Select the desired drive
-
 
532
        mov     edx, [hdbase]
-
 
533
        add     edx, 6   ;адрес регистра головок
-
 
534
        mov     al, byte [hdid]
-
 
535
        add     al, 128+64+32
-
 
536
        out     dx, al ; номер головки/номер диска
-
 
537
 
-
 
538
        call    wait_for_hd_idle
-
 
539
        cmp     [hd_error], 0
-
 
540
        jne     hd_write_error
-
 
541
 
-
 
542
; ATA with 28 or 48 bit for sector number?
-
 
543
        mov     eax, [edi]
-
 
544
        cmp     eax, 0x10000000
-
 
545
        jae     .lba48
-
 
546
;--------------------------------------
-
 
547
.lba28:
-
 
548
        pushfd
-
 
549
        cli
-
 
550
        xor     eax, eax
-
 
551
        mov     edx, [hdbase]
-
 
552
        inc     edx
-
 
553
        out     dx, al ; ATA Features регистр "особенностей"
-
 
554
        inc     edx
-
 
555
        inc     eax
-
 
556
        out     dx, al ; ATA Sector Counter счётчик секторов
-
 
557
        inc     edx
-
 
558
        mov     eax, [edi]      ; eax = sector to write
-
 
559
        out     dx, al ; LBA Low LBA (7:0)
-
 
560
        shr     eax, 8
-
 
561
        inc     edx
-
 
562
        out     dx, al ; LBA Mid LBA (15:8)
-
 
563
        shr     eax, 8
-
 
564
        inc     edx
-
 
565
        out     dx, al ; LBA High LBA (23:16)
-
 
566
        shr     eax, 8
-
 
567
        inc     edx
-
 
568
        and     al, 1+2+4+8 ; LBA (27:24)
-
 
569
        add     al, byte [hdid]
-
 
570
        add     al, 128+64+32
-
 
571
        out     dx, al ; номер головки/номер диска
-
 
572
        inc     edx
-
 
573
        mov     al, 30h ; WRITE SECTOR(S)
-
 
574
        out     dx, al ; ATACommand регистр команд
-
 
575
        jmp     .continue
-
 
576
;--------------------------------------
-
 
577
.lba48:
-
 
578
        pushfd
-
 
579
        cli
-
 
580
        xor     eax, eax
-
 
581
        mov     edx, [hdbase]
-
 
582
        inc     edx
-
 
583
        out     dx, al ; Features Previous Reserved
-
 
584
        out     dx, al ; Features Current Reserved
-
 
585
        inc     edx
-
 
586
        out     dx, al ; Sector Count Previous Sector count (15:8)
-
 
587
        inc     eax
-
 
588
        out     dx, al ; Sector Count Current Sector count (7:0)
-
 
589
        inc     edx
-
 
590
        mov     eax, [edi]
-
 
591
        rol     eax, 8
-
 
592
        out     dx, al ; LBA Low Previous LBA (31:24)
-
 
593
        xor     eax, eax ; because only 32 bit cache
-
 
594
        inc     edx
-
 
595
        out     dx, al ; LBA Mid Previous LBA (39:32)
-
 
596
        inc     edx
-
 
597
        out     dx, al ; LBA High Previous LBA (47:40)
-
 
598
        sub     edx, 2
-
 
599
        mov     eax, [edi]
-
 
600
        out     dx, al ; LBA Low Current LBA (7:0)
-
 
601
        shr     eax, 8
-
 
602
        inc     edx
-
 
603
        out     dx, al ; LBA Mid Current LBA (15:8)
-
 
604
        shr     eax, 8
-
 
605
        inc     edx
-
 
606
        out     dx, al ; LBA High Current LBA (23:16)
-
 
607
        inc     edx
-
 
608
        mov     al, byte [hdid]
-
 
609
        add     al, 128+64+32
-
 
610
        out     dx, al ; номер головки/номер диска
-
 
611
        inc     edx
-
 
612
        mov     al, 34h ; WRITE SECTOR(S) EXT
-
 
613
        out     dx, al ; ATACommand регистр команд
-
 
614
;--------------------------------------
-
 
615
.continue:
-
 
616
        popfd
-
 
617
        call    wait_for_sector_buffer
-
 
618
 
-
 
619
        cmp     [hd_error], 0
-
 
620
        jne     hd_write_error
-
 
621
 
-
 
622
        push    ecx esi
-
 
623
 
-
 
624
        pushfd
-
 
625
        cli
-
 
626
        mov     ecx, 256
-
 
627
        mov     edx, [hdbase]
-
 
628
        cld
-
 
629
        rep outsw
-
 
630
        popfd
-
 
631
 
-
 
632
        pop     esi ecx
-
 
633
        ret
-
 
634
;-----------------------------------------------------------------------------
-
 
635
align 4
-
 
636
save_hd_wait_timeout:
-
 
637
        push    eax
-
 
638
        mov     eax, [timer_ticks]
-
 
639
        add     eax, 300        ; 3 sec timeout
-
 
640
        mov     [hd_wait_timeout], eax
-
 
641
        pop     eax
-
 
642
        ret
-
 
643
;-----------------------------------------------------------------------------
-
 
644
align 4
-
 
645
check_hd_wait_timeout:
-
 
646
        push    eax
-
 
647
        mov     eax, [hd_wait_timeout]
-
 
648
        cmp     [timer_ticks], eax
-
 
649
        jg      hd_timeout_error
-
 
650
 
-
 
651
        pop     eax
-
 
652
        mov     [hd_error], 0
-
 
653
        ret
-
 
654
;-----------------------------------------------------------------------------
-
 
655
hd_timeout_error:
-
 
656
        if lang eq sp
-
 
657
        DEBUGF 1,"K : FS - HD tiempo de espera agotado\n"
-
 
658
        else
-
 
659
        DEBUGF 1,"K : FS - HD timeout\n"
-
 
660
        end if
-
 
661
        mov     [hd_error], 1
-
 
662
        pop     eax
-
 
663
        ret
-
 
664
;-----------------------------------------------------------------------------
-
 
665
hd_read_error:
-
 
666
        if lang eq sp
-
 
667
        DEBUGF 1,"K : FS - HD error de lectura\n"
-
 
668
        else
-
 
669
        DEBUGF 1,"K : FS - HD read error\n"
-
 
670
        end if
-
 
671
        pop     edx eax
-
 
672
        ret
-
 
673
;-----------------------------------------------------------------------------
-
 
674
hd_write_error_dma:
-
 
675
        pop     esi
-
 
676
hd_write_error:
-
 
677
        if lang eq sp
-
 
678
        DEBUGF 1,"K : FS - HD error de escritura\n"
-
 
679
        else
-
 
680
        DEBUGF 1,"K : FS - HD write error\n"
-
 
681
        end if
-
 
682
        ret
-
 
683
;-----------------------------------------------------------------------------
-
 
684
align 4
-
 
685
wait_for_hd_idle:
-
 
686
        push    eax edx
-
 
687
 
-
 
688
        call    save_hd_wait_timeout
-
 
689
 
-
 
690
        mov     edx, [hdbase]
-
 
691
        add     edx, 0x7
-
 
692
;--------------------------------------
-
 
693
align 4
-
 
694
wfhil1:
-
 
695
        call    check_hd_wait_timeout
-
 
696
        cmp     [hd_error], 0
-
 
697
        jne     @f
-
 
698
 
-
 
699
        in      al, dx
-
 
700
        test    al, 128
-
 
701
        jnz     wfhil1
-
 
702
 
-
 
703
@@:
-
 
704
        pop     edx eax
-
 
705
        ret
-
 
706
;-----------------------------------------------------------------------------
-
 
707
align 4
-
 
708
wait_for_sector_buffer:
-
 
709
        push    eax edx
-
 
710
 
-
 
711
        mov     edx, [hdbase]
-
 
712
        add     edx, 0x7
-
 
713
 
-
 
714
        call    save_hd_wait_timeout
-
 
715
;--------------------------------------
-
 
716
align 4
-
 
717
hdwait_sbuf:                  ; wait for sector buffer to be ready
-
 
718
        call    check_hd_wait_timeout
-
 
719
        cmp     [hd_error], 0
-
 
720
        jne     @f
-
 
721
 
-
 
722
        in      al, dx
-
 
723
        test    al, 8
-
 
724
        jz      hdwait_sbuf
-
 
725
 
-
 
726
        mov     [hd_error], 0
-
 
727
 
-
 
728
        cmp     [hd_setup], 1   ; do not mark error for setup request
-
 
729
        je      buf_wait_ok
-
 
730
 
-
 
731
        test    al, 1           ; previous command ended up with an error
-
 
732
        jz      buf_wait_ok
-
 
733
@@:
-
 
734
        mov     [hd_error], 1
-
 
735
 
-
 
736
buf_wait_ok:
-
 
737
        pop     edx eax
-
 
738
        ret
-
 
739
;-----------------------------------------------------------------------------
-
 
740
irq14_num equ byte 14
-
 
741
irq15_num equ byte 15
-
 
742
;-----------------------------------------------------------------------------
-
 
743
align 4
-
 
744
wait_for_sector_dma_ide0:
-
 
745
        push    eax
-
 
746
        push    edx
-
 
747
        call    save_hd_wait_timeout
-
 
748
;--------------------------------------
-
 
749
align 4
-
 
750
.wait:
-
 
751
        call    change_task
-
 
752
        cmp     [IDE_common_irq_param], 0
-
 
753
        jz      .done
-
 
754
 
-
 
755
        call    check_hd_wait_timeout
-
 
756
        cmp     [hd_error], 0
-
 
757
        jz      .wait
-
 
758
; clear Bus Master IDE Command register
-
 
759
        pushfd
-
 
760
        cli
-
 
761
        mov     [IDE_common_irq_param], 0
-
 
762
        mov     dx, [IDEContrRegsBaseAddr]
-
 
763
        mov     al, 0
-
 
764
        out     dx, al
-
 
765
        popfd
-
 
766
;--------------------------------------
-
 
767
align 4
-
 
768
.done:
-
 
769
        pop     edx
-
 
770
        pop     eax
-
 
771
        ret
-
 
772
;-----------------------------------------------------------------------------
-
 
773
align 4
-
 
774
wait_for_sector_dma_ide1:
-
 
775
        push    eax
-
 
776
        push    edx
-
 
777
        call    save_hd_wait_timeout
-
 
778
;--------------------------------------
-
 
779
align 4
-
 
780
.wait:
-
 
781
        call    change_task
-
 
782
        cmp     [IDE_common_irq_param], 0
-
 
783
        jz      .done
-
 
784
 
-
 
785
        call    check_hd_wait_timeout
-
 
786
        cmp     [hd_error], 0
-
 
787
        jz      .wait
-
 
788
; clear Bus Master IDE Command register
-
 
789
        pushfd
-
 
790
        cli
-
 
791
        mov     [IDE_common_irq_param], 0
-
 
792
        mov     dx, [IDEContrRegsBaseAddr]
-
 
793
        add     dx, 8
-
 
794
        mov     al, 0
-
 
795
        out     dx, al
-
 
796
        popfd
-
 
797
;--------------------------------------
-
 
798
align 4
-
 
799
.done:
-
 
800
        pop     edx
-
 
801
        pop     eax
-
 
802
        ret
-
 
803
;-----------------------------------------------------------------------------
-
 
804
iglobal
-
 
805
align 4
-
 
806
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
-
 
807
IDE_descriptor_table:
-
 
808
        dd IDE_DMA
-
 
809
        dw 0x2000
-
 
810
        dw 0x8000
-
 
811
 
-
 
812
dma_cur_sector  dd not 40h
-
 
813
dma_hdpos       dd 0
-
 
814
IDE_common_irq_param db 0
-
 
815
endg
-
 
816
;-----------------------------------------------------------------------------
-
 
817
uglobal
-
 
818
; all uglobals are zeroed at boot
-
 
819
dma_process         dd 0
-
 
820
dma_slot_ptr        dd 0
-
 
821
cache_chain_pos     dd 0
-
 
822
cache_chain_ptr     dd 0
-
 
823
cache_chain_size    db 0
-
 
824
cache_chain_started db 0
-
 
825
dma_task_switched   db 0
-
 
826
dma_hdd             db 0
-
 
827
allow_dma_access    db 0
-
 
828
endg
-
 
829
;-----------------------------------------------------------------------------
-
 
830
align 4
-
 
831
IDE_irq_14_handler:
-
 
832
        cmp     [IDE_common_irq_param], irq14_num
-
 
833
        jne     .exit
-
 
834
 
-
 
835
        pushfd
-
 
836
        cli
-
 
837
        pushad
-
 
838
        mov     [IDE_common_irq_param], 0
-
 
839
        mov     dx, [IDEContrRegsBaseAddr]
-
 
840
; test whether it is our interrupt?
-
 
841
        add     edx, 2
-
 
842
        in      al, dx
-
 
843
        test    al, 100b
-
 
844
        jz      @f
-
 
845
; clear Bus Master IDE Status register
-
 
846
; clear Interrupt bit
-
 
847
        out     dx, al
-
 
848
; clear Bus Master IDE Command register
-
 
849
        sub     edx, 2
-
 
850
        xor     eax, eax
-
 
851
        out     dx, al
-
 
852
; read status register and remove the interrupt request
-
 
853
        mov     edx, [hdbase]
-
 
854
        add     edx, 0x7
-
 
855
        in      al, dx
-
 
856
        popad
-
 
857
        popfd
-
 
858
        mov     al, 1
-
 
859
        ret
-
 
860
;--------------------------------------
-
 
861
align 4
-
 
862
@@:
-
 
863
        popad
-
 
864
        popfd
-
 
865
;--------------------------------------
-
 
866
align 4
-
 
867
.exit:
-
 
868
        mov     al, 0
-
 
869
        ret
-
 
870
;-----------------------------------------------------------------------------
-
 
871
align 4
-
 
872
IDE_irq_15_handler:
-
 
873
        cmp     [IDE_common_irq_param], irq15_num
-
 
874
        jne     .exit
-
 
875
 
-
 
876
        pushfd
-
 
877
        cli
-
 
878
        pushad
-
 
879
        mov     [IDE_common_irq_param], 0
-
 
880
        mov     dx, [IDEContrRegsBaseAddr]
-
 
881
        add     dx, 8
-
 
882
; test whether it is our interrupt?
-
 
883
        add     edx, 2
-
 
884
        in      al, dx
-
 
885
        test    al, 100b
-
 
886
        jz      @f
-
 
887
; clear Bus Master IDE Status register
-
 
888
; clear Interrupt bit
-
 
889
        out     dx, al
-
 
890
; clear Bus Master IDE Command register
-
 
891
        sub     edx, 2
-
 
892
        mov     al, 0
-
 
893
        out     dx, al
-
 
894
; read status register and remove the interrupt request
-
 
895
        mov     edx, [hdbase]
-
 
896
        add     edx, 0x7
-
 
897
        in      al, dx
-
 
898
        popad
-
 
899
        popfd
-
 
900
        mov     al, 1
-
 
901
        ret
-
 
902
;--------------------------------------
-
 
903
align 4
-
 
904
@@:
-
 
905
        popad
-
 
906
        popfd
-
 
907
;--------------------------------------
-
 
908
align 4
-
 
909
.exit:
-
 
910
        mov     al, 0
-
 
911
        ret
-
 
912
;-----------------------------------------------------------------------------
-
 
913
align 4
-
 
914
IDE_common_irq_handler:
-
 
915
        cmp     [IDE_common_irq_param], 0
-
 
916
        je      .exit
-
 
917
 
-
 
918
        pushfd
-
 
919
        cli
-
 
920
        pushad
-
 
921
        xor     ebx, ebx
-
 
922
        mov     dx, [IDEContrRegsBaseAddr]
-
 
923
        mov     eax, IDE_common_irq_param
-
 
924
        cmp     [eax], irq14_num
-
 
925
        mov     [eax], bl
-
 
926
        je      @f
-
 
927
 
-
 
928
        add     dx, 8
-
 
929
;--------------------------------------
-
 
930
align 4
-
 
931
@@:
-
 
932
; test whether it is our interrupt?
-
 
933
        add     edx, 2
-
 
934
        in      al, dx
-
 
935
        test    al, 100b
-
 
936
        jz      @f
-
 
937
; clear Bus Master IDE Status register
-
 
938
; clear Interrupt bit
-
 
939
        out     dx, al
-
 
940
; clear Bus Master IDE Command register
-
 
941
        sub     edx, 2
-
 
942
        xor     eax, eax
-
 
943
        out     dx, al
-
 
944
; read status register and remove the interrupt request
-
 
945
        mov     edx, [hdbase]
-
 
946
        add     edx, 0x7
-
 
947
        in      al, dx
-
 
948
        popad
-
 
949
        popfd
-
 
950
        mov     al, 1
-
 
951
        ret
-
 
952
;--------------------------------------
-
 
953
align 4
-
 
954
@@:
-
 
955
        popad
-
 
956
        popfd
-
 
957
;--------------------------------------
-
 
958
align 4
-
 
959
.exit:
-
 
960
        mov     al, 0
-
 
961
        ret
-
 
962
;-----------------------------------------------------------------------------
-
 
963
align 4
-
 
964
hd_read_dma:
-
 
965
        push    eax
-
 
966
        push    edx
-
 
967
        mov     edx, [dma_hdpos]
-
 
968
        cmp     edx, [hdpos]
-
 
969
        jne     .notread
-
 
970
        mov     edx, [dma_cur_sector]
-
 
971
        cmp     eax, edx
-
 
972
        jb      .notread
-
 
973
        add     edx, 15
-
 
974
        cmp     [esp+4], edx
-
 
975
        ja      .notread
-
 
976
        mov     eax, [esp+4]
-
 
977
        sub     eax, [dma_cur_sector]
-
 
978
        shl     eax, 9
-
 
979
        add     eax, (OS_BASE+IDE_DMA)
-
 
980
        push    ecx esi
-
 
981
        mov     esi, eax
-
 
982
 
-
 
983
        mov     ecx, 512/4
-
 
984
        cld
-
 
985
        rep movsd
-
 
986
        pop     esi ecx
-
 
987
        pop     edx
-
 
988
        pop     eax
-
 
989
        ret
-
 
990
.notread:
-
 
991
; set data for PRD Table
-
 
992
        mov     eax, IDE_descriptor_table
-
 
993
        mov     dword [eax], IDE_DMA
-
 
994
        mov     word [eax+4], 0x2000
-
 
995
        sub     eax, OS_BASE
-
 
996
; select controller Primary or Secondary
-
 
997
        mov     dx, [IDEContrRegsBaseAddr]
-
 
998
        push    eax
-
 
999
        mov     eax, [hd_address_table]
-
 
1000
        cmp     [hdbase], eax ; 0x1F0
-
 
1001
        pop     eax
-
 
1002
        jz      @f
-
 
1003
        add     edx, 8
-
 
1004
@@:
-
 
1005
        push    edx
-
 
1006
; Bus Master IDE PRD Table Address
-
 
1007
        add     edx, 4
-
 
1008
; save IDE_descriptor_table
-
 
1009
        out     dx, eax
-
 
1010
        pop     edx
-
 
1011
; clear Bus Master IDE Command register
-
 
1012
        mov     al, 0
-
 
1013
        out     dx, al
-
 
1014
; clear Bus Master IDE Status register
-
 
1015
; clear Error bit and Interrupt bit
-
 
1016
        add     edx, 2
-
 
1017
        mov     al, 6 ; 110b
-
 
1018
        out     dx, al
-
 
1019
; Select the desired drive
-
 
1020
        mov     edx, [hdbase]
-
 
1021
        add     edx, 6   ; адрес регистра головок
-
 
1022
        mov     al, byte [hdid]
-
 
1023
        add     al, 128+64+32
-
 
1024
        out     dx, al ; номер головки/номер диска
-
 
1025
 
-
 
1026
        call    wait_for_hd_idle
-
 
1027
        cmp     [hd_error], 0
-
 
1028
        jnz     hd_read_error
-
 
1029
 
-
 
1030
; ATA with 28 or 48 bit for sector number?
-
 
1031
        mov     eax, [esp+4]
-
 
1032
; -10h because the PreCache hits the boundary between lba28 and lba48
-
 
1033
; 10h = 16  - size of PreCache
-
 
1034
        cmp     eax, 0x10000000-10h
-
 
1035
        jae     .lba48
-
 
1036
;--------------------------------------
-
 
1037
.lba28:
-
 
1038
        pushfd
-
 
1039
        cli
-
 
1040
        xor     eax, eax
-
 
1041
        mov     edx, [hdbase]
-
 
1042
        inc     edx
-
 
1043
        out     dx, al ; ATA Features регистр "особенностей"
-
 
1044
        inc     edx
-
 
1045
        mov     eax, 10h ; Sector Counter = 16 ; PreCache
-
 
1046
        out     dx, al ; ATA Sector Counter счётчик секторов
-
 
1047
        inc     edx
-
 
1048
        mov     eax, [esp+4+4]
-
 
1049
        out     dx, al ; LBA Low LBA (7:0)
-
 
1050
        shr     eax, 8
-
 
1051
        inc     edx
-
 
1052
        out     dx, al ; LBA Mid LBA (15:8)
-
 
1053
        shr     eax, 8
-
 
1054
        inc     edx
-
 
1055
        out     dx, al ; LBA High LBA (23:16)
-
 
1056
        shr     eax, 8
-
 
1057
        inc     edx
-
 
1058
        and     al, 0xF ; LBA (27:24)
-
 
1059
        add     al, byte [hdid]
-
 
1060
        add     al, 11100000b
-
 
1061
        out     dx, al ; номер головки/номер диска
-
 
1062
        inc     edx
-
 
1063
        mov     al, 0xC8 ; READ DMA
-
 
1064
        out     dx, al ; ATACommand регистр команд
-
 
1065
        jmp     .continue
-
 
1066
;--------------------------------------
-
 
1067
.lba48:
-
 
1068
        pushfd
-
 
1069
        cli
-
 
1070
        xor     eax, eax
-
 
1071
        mov     edx, [hdbase]
-
 
1072
        inc     edx
-
 
1073
        out     dx, al ; Features Previous Reserved
-
 
1074
        out     dx, al ; Features Current Reserved
-
 
1075
        inc     edx
-
 
1076
        out     dx, al ; Sector Count Previous Sector count (15:8)
-
 
1077
        mov     eax, 10h ; Sector Counter = 16 PreCache
-
 
1078
        out     dx, al ; Sector Count Current Sector count (7:0)
-
 
1079
        inc     edx
-
 
1080
        mov     eax, [esp+4+4]
-
 
1081
        rol     eax, 8
-
 
1082
        out     dx, al ; LBA Low Previous LBA (31:24)
-
 
1083
        xor     eax, eax ; because only 32 bit cache
-
 
1084
        inc     edx
-
 
1085
        out     dx, al ; LBA Mid Previous LBA (39:32)
-
 
1086
        inc     edx
-
 
1087
        out     dx, al ; LBA High Previous LBA (47:40)
-
 
1088
        sub     edx, 2
-
 
1089
        mov     eax, [esp+4+4]
-
 
1090
        out     dx, al ; LBA Low Current LBA (7:0)
-
 
1091
        shr     eax, 8
-
 
1092
        inc     edx
-
 
1093
        out     dx, al ; LBA Mid Current LBA (15:8)
-
 
1094
        shr     eax, 8
-
 
1095
        inc     edx
-
 
1096
        out     dx, al ; LBA High Current LBA (23:16)
-
 
1097
        inc     edx
-
 
1098
        mov     al, byte [hdid]
-
 
1099
        add     al, 128+64+32
-
 
1100
        out     dx, al ; номер головки/номер диска
-
 
1101
        inc     edx
-
 
1102
        mov     al, 25h ; READ DMA EXT
-
 
1103
        out     dx, al ; ATACommand регистр команд
-
 
1104
;--------------------------------------
-
 
1105
.continue:
-
 
1106
; select controller Primary or Secondary
-
 
1107
        mov     dx, [IDEContrRegsBaseAddr]
-
 
1108
        mov     eax, [hd_address_table]
-
 
1109
        cmp     [hdbase], eax ; 0x1F0
-
 
1110
        jz      @f
-
 
1111
        add     dx, 8
-
 
1112
@@:
-
 
1113
; set write to memory and Start Bus Master
-
 
1114
        mov     al, 9
-
 
1115
        out     dx, al
-
 
1116
 
-
 
1117
        mov     eax, [CURRENT_TASK]
-
 
1118
        mov     [dma_process], eax
-
 
1119
 
-
 
1120
        mov     eax, [TASK_BASE]
-
 
1121
        mov     [dma_slot_ptr], eax
-
 
1122
 
-
 
1123
        mov     eax, [hd_address_table]
-
 
1124
        cmp     [hdbase], eax ; 0x1F0
-
 
1125
        jnz     .ide1
-
 
1126
 
-
 
1127
        mov     [IDE_common_irq_param], irq14_num
-
 
1128
        jmp     @f
-
 
1129
.ide1:
-
 
1130
        mov     [IDE_common_irq_param], irq15_num
-
 
1131
@@:
-
 
1132
        popfd
-
 
1133
; wait for interrupt
-
 
1134
        mov     eax, [hd_address_table]
-
 
1135
        cmp     [hdbase], eax ; 0x1F0
-
 
1136
        jnz     .wait_ide1
-
 
1137
        call    wait_for_sector_dma_ide0
-
 
1138
        jmp     @f
-
 
1139
.wait_ide1:
-
 
1140
        call    wait_for_sector_dma_ide1
-
 
1141
@@:
-
 
1142
        cmp     [hd_error], 0
-
 
1143
        jnz     hd_read_error
-
 
1144
        mov     eax, [hdpos]
-
 
1145
        mov     [dma_hdpos], eax
-
 
1146
        pop     edx
-
 
1147
        pop     eax
-
 
1148
        mov     [dma_cur_sector], eax
-
 
1149
        jmp     hd_read_dma
-
 
1150
;-----------------------------------------------------------------------------
-
 
1151
cache_write_dma:
-
 
1152
        mov     eax, [cache_chain_ptr] ; for what?
-
 
1153
        push    esi
-
 
1154
; set data for PRD Table
-
 
1155
        mov     eax, IDE_descriptor_table
-
 
1156
        mov     edx, eax
-
 
1157
        pusha
-
 
1158
        mov     edi, (OS_BASE+IDE_DMA)
-
 
1159
        mov     dword [edx], IDE_DMA
-
 
1160
        movzx   ecx, [cache_chain_size]
-
 
1161
        shl     ecx, 9
-
 
1162
        mov     word [edx+4], cx
-
 
1163
        shr     ecx, 2
-
 
1164
        cld
-
 
1165
        rep movsd
-
 
1166
        popa
-
 
1167
        sub     eax, OS_BASE
-
 
1168
; select controller Primary or Secondary
-
 
1169
        mov     dx, [IDEContrRegsBaseAddr]
-
 
1170
        push    eax
-
 
1171
        mov     eax, [hd_address_table]
-
 
1172
        cmp     [hdbase], eax ; 0x1F0
-
 
1173
        pop     eax
-
 
1174
        jz      @f
-
 
1175
        add     edx, 8
-
 
1176
@@:
-
 
1177
        push    edx
-
 
1178
; Bus Master IDE PRD Table Address
-
 
1179
        add     edx, 4
-
 
1180
; save IDE_descriptor_table
-
 
1181
        out     dx, eax
-
 
1182
        pop     edx
-
 
1183
; clear Bus Master IDE Command register
-
 
1184
        mov     al, 0
-
 
1185
        out     dx, al
-
 
1186
; clear Bus Master IDE Status register
-
 
1187
; clear Error bit and Interrupt bit
-
 
1188
        add     edx, 2
-
 
1189
        mov     al, 6
-
 
1190
        out     dx, al
-
 
1191
; Select the desired drive
-
 
1192
        mov     edx, [hdbase]
-
 
1193
        add     edx, 6   ; адрес регистра головок
-
 
1194
        mov     al, byte [hdid]
-
 
1195
        add     al, 128+64+32
-
 
1196
        out     dx, al ; номер головки/номер диска
-
 
1197
 
-
 
1198
        call    wait_for_hd_idle
-
 
1199
        cmp     [hd_error], 0
-
 
1200
        jnz     hd_write_error_dma
-
 
1201
 
-
 
1202
; ATA with 28 or 48 bit for sector number?
-
 
1203
        mov     esi, [cache_chain_ptr]
-
 
1204
        mov     eax, [esi]
-
 
1205
; -40h because the PreCache hits the boundary between lba28 and lba48
-
 
1206
; 40h = 64  - the maximum number of sectors to be written for one command
-
 
1207
        cmp     eax, 0x10000000-40h
-
 
1208
        jae     .lba48
-
 
1209
;--------------------------------------
-
 
1210
.lba28:
-
 
1211
        pushfd
-
 
1212
        cli
-
 
1213
        xor     eax, eax
-
 
1214
        mov     edx, [hdbase]
-
 
1215
        inc     edx
-
 
1216
        out     dx, al ; ATA Features регистр "особенностей"
-
 
1217
        inc     edx
-
 
1218
        mov     al, [cache_chain_size] ; Sector Counter
-
 
1219
        out     dx, al ; ATA Sector Counter счётчик секторов
-
 
1220
        inc     edx
-
 
1221
        mov     eax, [esi]
-
 
1222
        out     dx, al ; LBA Low LBA (7:0)
-
 
1223
        shr     eax, 8
-
 
1224
        inc     edx
-
 
1225
        out     dx, al ; LBA Mid LBA (15:8)
-
 
1226
        shr     eax, 8
-
 
1227
        inc     edx
-
 
1228
        out     dx, al ; LBA High LBA (23:16)
-
 
1229
        shr     eax, 8
-
 
1230
        inc     edx
-
 
1231
        and     al, 0xF ; LBA (27:24)
-
 
1232
        add     al, byte [hdid]
-
 
1233
        add     al, 11100000b
-
 
1234
        out     dx, al ; номер головки/номер диска
-
 
1235
        inc     edx
-
 
1236
        mov     al, 0xCA ; WRITE DMA
-
 
1237
        out     dx, al ; ATACommand регистр команд
-
 
1238
        jmp     .continue
-
 
1239
;--------------------------------------
-
 
1240
.lba48:
-
 
1241
        pushfd
-
 
1242
        cli
-
 
1243
        xor     eax, eax
-
 
1244
        mov     edx, [hdbase]
-
 
1245
        inc     edx
-
 
1246
        out     dx, al ; Features Previous Reserved
-
 
1247
        out     dx, al ; Features Current Reserved
-
 
1248
        inc     edx
-
 
1249
        out     dx, al ; Sector Count Previous Sector count (15:8)
-
 
1250
        mov     al, [cache_chain_size] ; Sector Counter
-
 
1251
        out     dx, al ; Sector Count Current Sector count (7:0)
-
 
1252
        inc     edx
-
 
1253
        mov     eax, [esi]
-
 
1254
        rol     eax, 8
-
 
1255
        out     dx, al ; LBA Low Previous LBA (31:24)
-
 
1256
        xor     eax, eax ; because only 32 bit cache
-
 
1257
        inc     edx
-
 
1258
        out     dx, al ; LBA Mid Previous LBA (39:32)
-
 
1259
        inc     edx
-
 
1260
        out     dx, al ; LBA High Previous LBA (47:40)
-
 
1261
        sub     edx, 2
-
 
1262
        mov     eax, [esi]
-
 
1263
        out     dx, al ; LBA Low Current LBA (7:0)
-
 
1264
        shr     eax, 8
-
 
1265
        inc     edx
-
 
1266
        out     dx, al ; LBA Mid Current LBA (15:8)
-
 
1267
        shr     eax, 8
-
 
1268
        inc     edx
-
 
1269
        out     dx, al ; LBA High Current LBA (23:16)
-
 
1270
        inc     edx
-
 
1271
        mov     al, byte [hdid]
-
 
1272
        add     al, 128+64+32
-
 
1273
        out     dx, al ; номер головки/номер диска
-
 
1274
        inc     edx
-
 
1275
        mov     al, 35h ; WRITE DMA EXT
-
 
1276
        out     dx, al ; ATACommand регистр команд
-
 
1277
;--------------------------------------
-
 
1278
.continue:
-
 
1279
; select controller Primary or Secondary
-
 
1280
        mov     dx, [IDEContrRegsBaseAddr]
-
 
1281
        mov     eax, [hd_address_table]
-
 
1282
        cmp     [hdbase], eax ; 0x1F0
-
 
1283
        jz      @f
-
 
1284
        add     dx, 8
-
 
1285
@@:
-
 
1286
; set write to device and Start Bus Master
-
 
1287
        mov     al, 1
-
 
1288
        out     dx, al
-
 
1289
        mov     eax, [CURRENT_TASK]
-
 
1290
        mov     [dma_process], eax
-
 
1291
        mov     eax, [TASK_BASE]
-
 
1292
        mov     [dma_slot_ptr], eax
-
 
1293
        mov     eax, [hd_address_table]
-
 
1294
        cmp     [hdbase], eax ; 0x1F0
-
 
1295
        jnz     .ide1
-
 
1296
 
-
 
1297
        mov     [IDE_common_irq_param], irq14_num
-
 
1298
        jmp     @f
-
 
1299
.ide1:
-
 
1300
        mov     [IDE_common_irq_param], irq15_num
-
 
1301
@@:
-
 
1302
        popfd
-
 
1303
; wait for interrupt
-
 
1304
        mov     [dma_cur_sector], not 0x40
-
 
1305
        mov     eax, [hd_address_table]
-
 
1306
        cmp     [hdbase], eax ; 0x1F0
-
 
1307
        jnz     .wait_ide1
-
 
1308
        call    wait_for_sector_dma_ide0
-
 
1309
        jmp     @f
-
 
1310
.wait_ide1:
-
 
1311
        call    wait_for_sector_dma_ide1
-
 
1312
@@:
-
 
1313
        cmp     [hd_error], 0
-
 
1314
        jnz     hd_write_error_dma
-
 
1315
        pop     esi
-
 
1316
        ret
-
 
1317
;-----------------------------------------------------------------------------
-
 
1318
uglobal
-
 
1319
align 4
-
 
1320
IDE_Interrupt   dw ?
-
 
1321
IDEContrRegsBaseAddr         dw ?
-
 
1322
IDEContrProgrammingInterface dw ?
-
 
1323
IDE_BAR0_val    dw ?
-
 
1324
IDE_BAR1_val    dw ?
-
 
1325
IDE_BAR2_val    dw ?
-
 
1326
IDE_BAR3_val    dw ?
-
 
1327
endg
-
 
1328
;-----------------------------------------------------------------------------
157
;-----------------------------------------------------------------------------
1329
; \begin{diamond}
158
; \begin{diamond}
1330
uglobal
159
uglobal
1331
bios_hdpos      dd 0       ; 0 is invalid value for [hdpos]
160
bios_hdpos      dd 0       ; 0 is invalid value for [hdpos]
1332
bios_cur_sector dd ?
161
bios_cur_sector dd ?