Subversion Repositories Kolibri OS

Rev

Rev 3742 | Rev 3774 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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