Subversion Repositories Kolibri OS

Rev

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

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