Subversion Repositories Kolibri OS

Rev

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

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