Subversion Repositories Kolibri OS

Rev

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

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