Subversion Repositories Kolibri OS

Rev

Rev 4287 | Rev 5201 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4287 Rev 4423
Line 3... Line 3...
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2013. 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 7... Line 7...
7
 
7
 
Line 8... Line 8...
8
$Revision: 4287 $
8
$Revision: 4423 $
9
 
9
 
10
 
-
 
11
; Low-level driver for HDD access
10
 
12
; DMA support by Mario79
11
; Low-level driver for HDD access
13
; Access through BIOS by diamond
12
; DMA support by Mario79
14
; LBA48 support by Mario79
13
; LBA48 support by Mario79
15
;-----------------------------------------------------------------------------
14
;-----------------------------------------------------------------------------
Line 30... Line 29...
30
        dd      ide_write
29
        dd      ide_write
31
        dd      0       ; no flush function
30
        dd      0       ; no flush function
32
        dd      0       ; use default cache size
31
        dd      0       ; use default cache size
33
.end:
32
.end:
Line 34... Line -...
34
 
-
 
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:
-
 
45
 
33
 
46
hd0_data        HD_DATA         ?,    0, 1
34
hd0_data        HD_DATA         ?,    0, 1
47
hd1_data        HD_DATA         ?, 0x10, 2
35
hd1_data        HD_DATA         ?, 0x10, 2
48
hd2_data        HD_DATA         ?,    0, 3
36
hd2_data        HD_DATA         ?,    0, 3
Line 110... Line 98...
110
; DMA read is permitted if [allow_dma_access]=1 or 2
98
; DMA read is permitted if [allow_dma_access]=1 or 2
111
        cmp     [allow_dma_access], 2
99
        cmp     [allow_dma_access], 2
112
        ja      .nodma
100
        ja      .nodma
113
        cmp     [dma_hdd], 1
101
        cmp     [dma_hdd], 1
114
        jnz     .nodma
102
        jnz     .nodma
-
 
103
;--------------------------------------
-
 
104
        push    eax
-
 
105
        mov     eax, [hd_address_table]
-
 
106
        cmp     [hdbase], eax ; 0x1F0
-
 
107
        pop     eax
-
 
108
        jnz     @f
-
 
109
 
-
 
110
        test    [DRIVE_DATA+1], byte 10100000b
-
 
111
        jnz     .nodma
-
 
112
 
-
 
113
        jmp     .dma
-
 
114
@@:
-
 
115
        test    [DRIVE_DATA+1], byte 1010b
-
 
116
        jnz     .nodma
-
 
117
.dma:
-
 
118
;--------------------------------------
115
        call    hd_read_dma
119
        call    hd_read_dma
116
        jmp     @f
120
        jmp     @f
117
.nodma:
121
.nodma:
118
        call    hd_read_pio
122
        call    hd_read_pio
119
@@:
123
@@:
Line 202... Line 206...
202
; DMA write is permitted only if [allow_dma_access]=1
206
; DMA write is permitted only if [allow_dma_access]=1
203
        cmp     [allow_dma_access], 2
207
        cmp     [allow_dma_access], 2
204
        jae     .nodma
208
        jae     .nodma
205
        cmp     [dma_hdd], 1
209
        cmp     [dma_hdd], 1
206
        jnz     .nodma
210
        jnz     .nodma
-
 
211
;--------------------------------------
-
 
212
        push    eax
-
 
213
        mov     eax, [hd_address_table]
-
 
214
        cmp     [hdbase], eax ; 0x1F0
-
 
215
        pop     eax
-
 
216
        jnz     @f
-
 
217
 
-
 
218
        test    [DRIVE_DATA+1], byte 10100000b
-
 
219
        jnz     .nodma
-
 
220
 
-
 
221
        jmp     .dma
-
 
222
@@:
-
 
223
        test    [DRIVE_DATA+1], byte 1010b
-
 
224
        jnz     .nodma
-
 
225
.dma:
-
 
226
;--------------------------------------
207
        call    cache_write_dma
227
        call    cache_write_dma
208
        jmp     .common
228
        jmp     .common
209
.nodma:
229
.nodma:
210
        mov     [cache_chain_size], 1
230
        mov     [cache_chain_size], 1
211
        call    cache_write_pio
231
        call    cache_write_pio
Line 249... Line 269...
249
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
269
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
250
        xor     eax, eax
270
        xor     eax, eax
251
        ret
271
        ret
252
endp
272
endp
Line 253... Line -...
253
 
-
 
254
proc bd_read_interface stdcall uses edi, \
-
 
255
        userdata, buffer, startsector:qword, numsectors
-
 
256
        ; userdata = old [hdpos] = 80h + index in NumBiosDisks
-
 
257
        ; buffer = pointer to buffer for data
-
 
258
        ; startsector = 64-bit start sector
-
 
259
        ; numsectors = pointer to number of sectors on input,
-
 
260
        ;  must be filled with number of sectors really read
-
 
261
locals
-
 
262
sectors_todo    dd      ?
-
 
263
endl
-
 
264
; 1. Initialize number of sectors: get number of requested sectors
-
 
265
; and say that no sectors were read yet.
-
 
266
        mov     ecx, [numsectors]
-
 
267
        mov     eax, [ecx]
-
 
268
        mov     dword [ecx], 0
-
 
269
        mov     [sectors_todo], eax
-
 
270
; 2. Acquire the global lock.
-
 
271
        mov     ecx, ide_mutex
-
 
272
        call    mutex_lock
-
 
273
; 3. Convert parameters to the form suitable for worker procedures.
-
 
274
; Underlying procedures do not know about 64-bit sectors.
-
 
275
; Worker procedures use global variables and edi for [buffer].
-
 
276
        cmp     dword [startsector+4], 0
-
 
277
        jnz     .fail
-
 
278
        and     [hd_error], 0
-
 
279
        mov     eax, [userdata]
-
 
280
        mov     [hdpos], eax
-
 
281
        mov     eax, dword [startsector]
-
 
282
        mov     edi, [buffer]
-
 
283
; 4. Worker procedures take one sectors per time, so loop over all sectors to read.
-
 
284
.sectors_loop:
-
 
285
        call    bd_read
-
 
286
        cmp     [hd_error], 0
-
 
287
        jnz     .fail
-
 
288
        mov     ecx, [numsectors]
-
 
289
        inc     dword [ecx]     ; one more sector is read
-
 
290
        dec     [sectors_todo]
-
 
291
        jz      .done
-
 
292
        inc     eax
-
 
293
        jnz     .sectors_loop
-
 
294
; 5. Loop is done, either due to error or because everything is done.
-
 
295
; Release the global lock and return the corresponding status.
-
 
296
.fail:
-
 
297
        mov     ecx, ide_mutex
-
 
298
        call    mutex_unlock
-
 
299
        or      eax, -1
-
 
300
        ret
-
 
301
.done:
-
 
302
        mov     ecx, ide_mutex
-
 
303
        call    mutex_unlock
-
 
304
        xor     eax, eax
-
 
305
        ret
-
 
306
endp
-
 
307
 
-
 
308
proc bd_write_interface stdcall uses esi edi, \
-
 
309
        userdata, buffer, startsector:qword, numsectors
-
 
310
        ; userdata = old [hdpos] = 80h + index in NumBiosDisks
-
 
311
        ; buffer = pointer to buffer with data
-
 
312
        ; startsector = 64-bit start sector
-
 
313
        ; numsectors = pointer to number of sectors on input,
-
 
314
        ;  must be filled with number of sectors really written
-
 
315
locals
-
 
316
sectors_todo    dd      ?
-
 
317
endl
-
 
318
; 1. Initialize number of sectors: get number of requested sectors
-
 
319
; and say that no sectors were read yet.      
-
 
320
        mov     ecx, [numsectors]
-
 
321
        mov     eax, [ecx]
-
 
322
        mov     dword [ecx], 0
-
 
323
        mov     [sectors_todo], eax
-
 
324
; 2. Acquire the global lock.
-
 
325
        mov     ecx, ide_mutex
-
 
326
        call    mutex_lock
-
 
327
; 3. Convert parameters to the form suitable for worker procedures.
-
 
328
; Underlying procedures do not know about 64-bit sectors.
-
 
329
; Worker procedures use global variables and esi for [buffer].
-
 
330
        cmp     dword [startsector+4], 0
-
 
331
        jnz     .fail
-
 
332
        and     [hd_error], 0
-
 
333
        mov     eax, [userdata]
-
 
334
        mov     [hdpos], eax
-
 
335
        mov     esi, [buffer]
-
 
336
        lea     edi, [startsector]
-
 
337
        mov     [cache_chain_ptr], edi
-
 
338
; 4. Worker procedures take max 16 sectors per time,
-
 
339
; loop until all sectors will be processed.
-
 
340
.sectors_loop:
-
 
341
        mov     ecx, 16
-
 
342
        cmp     ecx, [sectors_todo]
-
 
343
        jbe     @f
-
 
344
        mov     ecx, [sectors_todo]
-
 
345
@@:
-
 
346
        mov     [cache_chain_size], cl
-
 
347
        call    bd_write_cache_chain
-
 
348
        cmp     [hd_error], 0
-
 
349
        jnz     .fail
-
 
350
        movzx   ecx, [cache_chain_size]
-
 
351
        mov     eax, [numsectors]
-
 
352
        add     [eax], ecx
-
 
353
        sub     [sectors_todo], ecx
-
 
354
        jz      .done
-
 
355
        add     [edi], ecx
-
 
356
        jc      .fail
-
 
357
        shl     ecx, 9
-
 
358
        add     esi, ecx
-
 
359
        jmp     .sectors_loop
-
 
360
; 5. Loop is done, either due to error or because everything is done.
-
 
361
; Release the global lock and return the corresponding status.
-
 
362
.fail:
-
 
363
        mov     ecx, ide_mutex
-
 
364
        call    mutex_unlock
-
 
365
        or      eax, -1
-
 
366
        ret
-
 
367
.done:
-
 
368
        mov     ecx, ide_mutex
-
 
369
        call    mutex_unlock
-
 
370
        xor     eax, eax
-
 
371
        ret
-
 
372
endp
-
 
373
 
-
 
374
; This is a stub.
-
 
375
proc bd_querymedia stdcall, hd_data, mediainfo
-
 
376
        mov     eax, [mediainfo]
-
 
377
        mov     [eax+DISKMEDIAINFO.Flags], 0
-
 
378
        mov     [eax+DISKMEDIAINFO.SectorSize], 512
-
 
379
        or      dword [eax+DISKMEDIAINFO.Capacity], 0xFFFFFFFF
-
 
380
        or      dword [eax+DISKMEDIAINFO.Capacity+4], 0xFFFFFFFF
-
 
381
        xor     eax, eax
-
 
382
        ret
-
 
383
endp
-
 
384
 
273
 
385
;-----------------------------------------------------------------------------
274
;-----------------------------------------------------------------------------
386
align 4
275
align 4
387
; input: eax = sector, edi -> buffer
276
; input: eax = sector, edi -> buffer
388
; output: edi = edi + 512
277
; output: edi = edi + 512
Line 801... Line 690...
801
        jne     .exit
690
        jne     .exit
Line 802... Line 691...
802
 
691
 
803
        pushfd
692
        pushfd
804
        cli
693
        cli
805
        pushad
-
 
806
; clear Bus Master IDE Command register
694
        pushad
807
        mov     [IDE_common_irq_param], 0
695
        mov     [IDE_common_irq_param], 0
-
 
696
        mov     dx, [IDEContrRegsBaseAddr]
-
 
697
; test whether it is our interrupt?
808
        mov     dx, [IDEContrRegsBaseAddr]
698
        add     edx, 2
-
 
699
        in      al, dx
809
        mov     al, 0
700
        test    al, 100b
810
        out     dx, al
701
        jz      @f
811
; clear Bus Master IDE Status register
702
; clear Bus Master IDE Status register
812
; clear Interrupt bit
-
 
813
        add     edx, 2
-
 
814
        mov     al, 4 ; 100b
703
; clear Interrupt bit
-
 
704
        out     dx, al
-
 
705
; clear Bus Master IDE Command register
-
 
706
        sub     edx, 2
-
 
707
        xor     eax, eax
-
 
708
        out     dx, al
-
 
709
; read status register and remove the interrupt request
-
 
710
        mov     edx, [hdbase]
-
 
711
        add     edx, 0x7
-
 
712
        in      al, dx
-
 
713
        popad
-
 
714
        popfd
-
 
715
        mov     al, 1
-
 
716
        ret
-
 
717
;--------------------------------------
815
        out     dx, al
718
align 4
816
 
719
@@:
817
        popad
720
        popad
818
        popfd
721
        popfd
819
;--------------------------------------
722
;--------------------------------------
820
align 4
723
align 4
821
.exit:
724
.exit:
822
        mov     al, 1
725
        mov     al, 0
823
        ret
726
        ret
824
;-----------------------------------------------------------------------------
727
;-----------------------------------------------------------------------------
825
align 4
728
align 4
826
IDE_irq_15_handler:
729
IDE_irq_15_handler:
827
        cmp     [IDE_common_irq_param], irq15_num
730
        cmp     [IDE_common_irq_param], irq15_num
Line 828... Line 731...
828
        jne     .exit
731
        jne     .exit
829
 
732
 
830
        pushfd
733
        pushfd
831
        cli
-
 
832
        pushad
734
        cli
833
; clear Bus Master IDE Command register
735
        pushad
834
        mov     [IDE_common_irq_param], 0
736
        mov     [IDE_common_irq_param], 0
-
 
737
        mov     dx, [IDEContrRegsBaseAddr]
-
 
738
        add     dx, 8
835
        mov     dx, [IDEContrRegsBaseAddr]
739
; test whether it is our interrupt?
-
 
740
        add     edx, 2
836
        add     dx, 8
741
        in      al, dx
837
        mov     al, 0
742
        test    al, 100b
838
        out     dx, al
743
        jz      @f
839
; clear Bus Master IDE Status register
-
 
840
; clear Interrupt bit
-
 
841
        add     edx, 2
744
; clear Bus Master IDE Status register
-
 
745
; clear Interrupt bit
-
 
746
        out     dx, al
-
 
747
; clear Bus Master IDE Command register
-
 
748
        sub     edx, 2
-
 
749
        mov     al, 0
-
 
750
        out     dx, al
-
 
751
; read status register and remove the interrupt request
-
 
752
        mov     edx, [hdbase]
-
 
753
        add     edx, 0x7
-
 
754
        in      al, dx
-
 
755
        popad
-
 
756
        popfd
-
 
757
        mov     al, 1
-
 
758
        ret
842
        mov     al, 4 ; 100b
759
;--------------------------------------
843
        out     dx, al
760
align 4
844
 
761
@@:
845
        popad
762
        popad
846
        popfd
763
        popfd
847
;--------------------------------------
764
;--------------------------------------
848
align 4
765
align 4
849
.exit:
766
.exit:
850
        mov     al, 1
767
        mov     al, 0
851
        ret
768
        ret
852
;-----------------------------------------------------------------------------
769
;-----------------------------------------------------------------------------
853
align 4
770
align 4
854
IDE_common_irq_handler:
771
IDE_common_irq_handler:
Line 855... Line 772...
855
        cmp     [IDE_common_irq_param], 0
772
        cmp     [IDE_common_irq_param], 0
856
        je      .exit
773
        je      .exit
857
 
774
 
858
        pushfd
-
 
859
        cli
775
        pushfd
860
        pushad
776
        cli
861
; clear Bus Master IDE Command register
777
        pushad
862
        xor     ebx, ebx
778
        xor     ebx, ebx
863
        mov     dx, [IDEContrRegsBaseAddr]
779
        mov     dx, [IDEContrRegsBaseAddr]
864
        mov     eax, IDE_common_irq_param
-
 
865
        cmp     [eax], irq14_num
780
        mov     eax, IDE_common_irq_param
Line 866... Line 781...
866
        mov     [eax], bl
781
        cmp     [eax], irq14_num
867
        xor     eax, eax
782
        mov     [eax], bl
868
        je      @f
783
        je      @f
869
 
784
 
-
 
785
        add     dx, 8
870
        add     dx, 8
786
;--------------------------------------
-
 
787
align 4
-
 
788
@@:
-
 
789
; test whether it is our interrupt?
871
;--------------------------------------
790
        add     edx, 2
872
align 4
791
        in      al, dx
873
@@:
-
 
874
        out     dx, al
-
 
875
; clear Bus Master IDE Status register
792
        test    al, 100b
-
 
793
        jz      @f
-
 
794
; clear Bus Master IDE Status register
-
 
795
; clear Interrupt bit
-
 
796
        out     dx, al
-
 
797
; clear Bus Master IDE Command register
-
 
798
        sub     edx, 2
-
 
799
        xor     eax, eax
-
 
800
        out     dx, al
-
 
801
; read status register and remove the interrupt request
-
 
802
        mov     edx, [hdbase]
-
 
803
        add     edx, 0x7
-
 
804
        in      al, dx
-
 
805
        popad
-
 
806
        popfd
876
; clear Interrupt bit
807
        mov     al, 1
877
        add     edx, 2
808
        ret
878
        mov     al, 4 ; 100b
809
;--------------------------------------
879
        out     dx, al
810
align 4
880
 
811
@@:
881
        popad
812
        popad
882
        popfd
813
        popfd
883
;--------------------------------------
814
;--------------------------------------
884
align 4
815
align 4
885
.exit:
816
.exit:
886
        mov     al, 1
817
        mov     al, 0
887
        ret
818
        ret
Line 1250... Line 1181...
1250
IDE_BAR1_val    dw ?
1181
IDE_BAR1_val    dw ?
1251
IDE_BAR2_val    dw ?
1182
IDE_BAR2_val    dw ?
1252
IDE_BAR3_val    dw ?
1183
IDE_BAR3_val    dw ?
1253
endg
1184
endg
1254
;-----------------------------------------------------------------------------
1185
;-----------------------------------------------------------------------------
1255
; \begin{diamond}
-
 
1256
uglobal
-
 
1257
bios_hdpos      dd 0       ; 0 is invalid value for [hdpos]
-
 
1258
bios_cur_sector dd ?
-
 
1259
bios_read_len   dd ?
-
 
1260
endg
-
 
1261
;-----------------------------------------------------------------------------
-
 
1262
align 4
-
 
1263
bd_read:
-
 
1264
        push    eax
-
 
1265
        push    edx
-
 
1266
        mov     edx, [bios_hdpos]
-
 
1267
        cmp     edx, [hdpos]
-
 
1268
        jne     .notread
-
 
1269
        mov     edx, [bios_cur_sector]
-
 
1270
        cmp     eax, edx
-
 
1271
        jb      .notread
-
 
1272
        add     edx, [bios_read_len]
-
 
1273
        dec     edx
-
 
1274
        cmp     eax, edx
-
 
1275
        ja      .notread
-
 
1276
        sub     eax, [bios_cur_sector]
-
 
1277
        shl     eax, 9
-
 
1278
        add     eax, (OS_BASE+0x9A000)
-
 
1279
        push    ecx esi
-
 
1280
        mov     esi, eax
-
 
1281
        mov     ecx, 512/4
-
 
1282
        cld
-
 
1283
        rep movsd
-
 
1284
        pop     esi ecx
-
 
1285
        pop     edx
-
 
1286
        pop     eax
-
 
1287
        ret
-
 
1288
.notread:
-
 
1289
        push    ecx
-
 
1290
        mov     dl, 42h
-
 
1291
        mov     ecx, 16
-
 
1292
        call    int13_call
-
 
1293
        pop     ecx
-
 
1294
        test    eax, eax
-
 
1295
        jnz     .v86err
-
 
1296
        test    edx, edx
-
 
1297
        jz      .readerr
-
 
1298
        mov     [bios_read_len], edx
-
 
1299
        mov     edx, [hdpos]
-
 
1300
        mov     [bios_hdpos], edx
-
 
1301
        pop     edx
-
 
1302
        pop     eax
-
 
1303
        mov     [bios_cur_sector], eax
-
 
1304
        jmp     bd_read
-
 
1305
.readerr:
-
 
1306
.v86err:
-
 
1307
        mov     [hd_error], 1
-
 
1308
        jmp     hd_read_error
-
 
1309
;-----------------------------------------------------------------------------
-
 
1310
align 4
-
 
1311
bd_write_cache_chain:
-
 
1312
        pusha
-
 
1313
        mov     edi, OS_BASE + 0x9A000
-
 
1314
        movzx   ecx, [cache_chain_size]
-
 
1315
        push    ecx
-
 
1316
        shl     ecx, 9-2
-
 
1317
        rep movsd
-
 
1318
        pop     ecx
-
 
1319
        mov     dl, 43h
-
 
1320
        mov     eax, [cache_chain_ptr]
-
 
1321
        mov     eax, [eax]
-
 
1322
        call    int13_call
-
 
1323
        test    eax, eax
-
 
1324
        jnz     .v86err
-
 
1325
        cmp     edx, ecx
-
 
1326
        jnz     .writeerr
-
 
1327
        popa
-
 
1328
        ret
-
 
1329
.v86err:
-
 
1330
.writeerr:
-
 
1331
        popa
-
 
1332
        mov     [hd_error], 1
-
 
1333
        jmp     hd_write_error
-
 
1334
;-----------------------------------------------------------------------------
-
 
1335
uglobal
-
 
1336
int13_regs_in   rb sizeof.v86_regs
-
 
1337
int13_regs_out  rb sizeof.v86_regs
-
 
1338
endg
-
 
1339
;-----------------------------------------------------------------------------
-
 
1340
align 4
-
 
1341
int13_call:
-
 
1342
; Because this code uses fixed addresses,
-
 
1343
; it can not be run simultaniously by many threads.
-
 
1344
; In current implementation it is protected by common mutex 'ide_status'
-
 
1345
        mov     word [OS_BASE + 510h], 10h             ; packet length
-
 
1346
        mov     word [OS_BASE + 512h], cx              ; number of sectors
-
 
1347
        mov     dword [OS_BASE + 514h], 9A000000h      ; buffer 9A00:0000
-
 
1348
        mov     dword [OS_BASE + 518h], eax
-
 
1349
        and     dword [OS_BASE + 51Ch], 0
-
 
1350
        push    ebx ecx esi edi
-
 
1351
        mov     ebx, int13_regs_in
-
 
1352
        mov     edi, ebx
-
 
1353
        mov     ecx, sizeof.v86_regs/4
-
 
1354
        xor     eax, eax
-
 
1355
        rep stosd
-
 
1356
        mov     byte [ebx+v86_regs.eax+1], dl
-
 
1357
        mov     eax, [hdpos]
-
 
1358
        lea     eax, [BiosDisksData+(eax-80h)*4]
-
 
1359
        mov     dl, [eax]
-
 
1360
        mov     byte [ebx+v86_regs.edx], dl
-
 
1361
        movzx   edx, byte [eax+1]
-
 
1362
;        mov     dl, 5
-
 
1363
        test    edx, edx
-
 
1364
        jnz     .hasirq
-
 
1365
        dec     edx
-
 
1366
        jmp     @f
-
 
1367
.hasirq:
-
 
1368
        pushad
-
 
1369
        stdcall enable_irq, edx
-
 
1370
        popad
-
 
1371
@@:
-
 
1372
        mov     word [ebx+v86_regs.esi], 510h
-
 
1373
        mov     word [ebx+v86_regs.ss], 9000h
-
 
1374
        mov     word [ebx+v86_regs.esp], 0A000h
-
 
1375
        mov     word [ebx+v86_regs.eip], 500h
-
 
1376
        mov     [ebx+v86_regs.eflags], 20200h
-
 
1377
        mov     esi, [sys_v86_machine]
-
 
1378
        mov     ecx, 0x502
-
 
1379
        push    fs
-
 
1380
        call    v86_start
-
 
1381
        pop     fs
-
 
1382
        and     [bios_hdpos], 0
-
 
1383
        pop     edi esi ecx ebx
-
 
1384
        movzx   edx, byte [OS_BASE + 512h]
-
 
1385
        test    byte [int13_regs_out+v86_regs.eflags], 1
-
 
1386
        jnz     @f
-
 
1387
        mov     edx, ecx
-
 
1388
@@:
-
 
1389
        ret
-
 
1390
; \end{diamond}
-