Subversion Repositories Kolibri OS

Rev

Rev 4839 | Rev 5569 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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