Написал драйвер флоппи-дисковода. На VM (Qemu) всё работает, а когда гружусь на реальной машине, то ничего не работает. Вот код:
Код:
; Инициализация DMA для дисковода
proc InitDMA stdcall,mode
xor al, al
out 0x0C, al
mov al, 6
out 0x0A, al
mov al, byte[.mode] ; 0x46 для чтения, 0x4A для записи
out 0x0B, al
xor al, al
out 0x0C, al
mov rax, FLOPPY_BUFFER
out 0x04, al
shr rax, 8
out 0x04, al
shr rax, 8
out 0x81, al
xor al, al
out 0x0C, al
mov al, -1
out 0x05, al
mov al, 1
out 0x05, al
mov al, 2
out 0x0A, al
ret
endp
; Запись байта в порт данных дисковода
proc FDC_Out stdcall uses rcx rdx,value
mov rdx, 0x3F4
mov rcx, 0x10000
@@:
in al, dx
and al, 0xC0
cmp al, 0x80
je @f
loop @b
mov [floppy_status], FLOPPY_STATUS_TIMEOUT
ret
@@:
inc rdx
mov rax, [.value]
out dx, al
mov [floppy_status], FLOPPY_STATUS_OK
ret
endp
; Чтение байта из порта данных дисковода
proc FDC_In stdcall
mov rdx, 0x3F4
mov rcx, 0x10000
@@:
in al, dx
and al, 0xC0
cmp al, 0xC0
je @f
loop @b
mov [floppy_status], FLOPPY_STATUS_TIMEOUT
ret
@@:
inc rdx
in al, dx
movzx rax, al
mov [floppy_status], FLOPPY_STATUS_OK
ret
endp
; Включить мотор дисковода
proc FDC_On stdcall uses rdx
mov [floppy_motor], TRUE
mov dx, 0x3F2
out dx, al
mov rax, 0x1C
out dx, al
invoke GetTimer
mov rbx, rax
add rbx, 500 / 10
@@:
invoke GetTimer
cmp rax, rbx
jb @b
add rax, 2000 / 10
mov [floppy_timeout], rax
ret
endp
; Отключение мотора дисковода
proc FDC_Off stdcall uses rdx
mov [floppy_motor], FALSE
mov rdx, 0x3F2
mov al, 0x0C
out dx, al
ret
endp
; Сброс дисковода
proc FDC_Reset stdcall uses rdx
mov [floppy_timeout], 0
mov [floppy_motor], FALSE
xor rax, rax
mov rdx, 0x3F2
out dx, al
ret
endp
proc FDC_WaitInt stdcall uses rcx
mov [floppy_status], FLOPPY_STATUS_OK
mov rcx, 0x100000
@@:
cmp [fdc_int_flag], FALSE
jne @f
loop @b
mov [floppy_status], FLOPPY_STATUS_TIMEOUT
ret
@@:
mov [fdc_int_flag], FALSE
ret
endp
proc FDC_Recalibrate stdcall
mov [fdc_int_flag], FALSE
stdcall FDC_Out,7
stdcall FDC_Out,0
stdcall FDC_WaitInt
ret
endp
proc FDC_IntHandler interrupt uses rax
mov [fdc_int_flag], TRUE
mov al, 0x20
out 0x20, al
ret
endp
proc FDC_SeekTrack stdcall uses rcx rdx r12 r13 r14 r15,sector
mov rax, [.sector]
mov cl, 18
div cl
xor r13, r13
shr al, 1
adc r13, r13
mov al, ah
movzx r12, al
stdcall FDC_Out,15
mov rax, r13
shl rax, 2
stdcall FDC_Out,rax
stdcall FDC_Out,r12
stdcall FDC_WaitInt
cmp [floppy_status], FLOPPY_STATUS_OK
jne .exit
stdcall FDC_Out,8
stdcall FDC_In
mov r14, rax
stdcall FDC_In
mov r15, rax
test r14, 100000b
jz .error
cmp r15, r12
jne .error
shr r14, 2
and r14, 1
cmp r14, r13
jne .error
mov [floppy_status], FLOPPY_STATUS_OK
.exit:
ret
.error:
mov [floppy_status], FLOPPY_STATUS_TRACK_NOT_FOUND
ret
endp
proc FDC_GetStatus stdcall
stdcall FDC_In
mov [fdc_st0], al
stdcall FDC_In
mov [fdc_st1], al
stdcall FDC_In
mov [fdc_st2], al
stdcall FDC_In
mov [fdc_c], al
stdcall FDC_In
mov [fdc_h], al
stdcall FDC_In
mov [fdc_r], al
stdcall FDC_In
mov [fdc_n], al
ret
endp
proc _FloppyRead stdcall uses rbx rcx rdx rsi rdi r8 r9 r10,sector,buffer
@@:
cmp [fdc_mutex], FALSE
jne @b
mov [fdc_mutex], TRUE
mov rax, [.sector]
cmp rax, 2880
jae .error
mov cl, 18
div cl
xor r9, r9
shr al, 1
adc r9, r9
movzx r10, al
mov al, ah
movzx r8, al
inc r8
cmp [floppy_motor], FALSE
jne @f
stdcall FDC_On
@@:
stdcall InitDMA,0x46
stdcall FDC_Out,0xE6
cmp [floppy_status], FLOPPY_STATUS_OK
jne .error
mov rdx, r9
shl rdx, 2
stdcall FDC_Out,rdx
stdcall FDC_Out,r10
stdcall FDC_Out,r9
stdcall FDC_Out,r8
stdcall FDC_Out,2
stdcall FDC_Out,18
stdcall FDC_Out,0x1B
stdcall FDC_Out,0xFF
stdcall FDC_WaitInt
cmp [floppy_status], FLOPPY_STATUS_OK
jne .error
stdcall FDC_GetStatus
test [fdc_st0], 11011000b
jnz .error
invoke TempMountPage,FLOPPY_BUFFER
mov rsi, temp_page
mov rdi, [.buffer]
mov rcx, 512 / 8
rep movsq
mov [floppy_status], FLOPPY_STATUS_OK
mov [fdc_mutex], FALSE
mov rax, TRUE
ret
.error:
mov [floppy_status], FLOPPY_STATUS_SECTOR_NOT_FOUND
mov [fdc_mutex], FALSE
xor rax, rax
ret
endp
proc FloppyRead stdcall uses rcx,sector,buffer
mov rcx, 3
@@:
stdcall _FloppyRead,[.sector],[.buffer]
test rax, rax
jnz @f
stdcall FDC_Recalibrate
stdcall FDC_SeekTrack,[.sector]
loop @b
xor rax, rax
ret
@@:
ret
endp
proc _FloppyWrite stdcall uses rbx rcx rdx rsi rdi r8 r9 r10 r11,sector,buffer
@@:
cmp [fdc_mutex], FALSE
jne @b
mov [fdc_mutex], TRUE
cmp [.sector], 2880
jae .error
invoke TempMountPage,FLOPPY_BUFFER
mov rdi, temp_page
mov rsi, [.buffer]
mov rcx, 512 / 8
rep movsq
mov rax, [.sector]
mov cl, 18
div cl
xor r9, r9
shr al, 1
adc r9, r9
movzx r10, al
mov al, ah
movzx r8, al
inc r8
cmp [floppy_motor], FALSE
jne @f
stdcall FDC_On
@@:
stdcall InitDMA,0x4A
stdcall FDC_Out,0x45
cmp [floppy_status], FLOPPY_STATUS_OK
jne .error
mov rdx, r9
shl rdx, 2
stdcall FDC_Out,rdx
stdcall FDC_Out,r10
stdcall FDC_Out,r9
stdcall FDC_Out,r8
stdcall FDC_Out,2
stdcall FDC_Out,18
stdcall FDC_Out,0x1B
stdcall FDC_Out,0xFF
stdcall FDC_WaitInt
cmp [floppy_status], FLOPPY_STATUS_OK
jne .error
stdcall FDC_GetStatus
test [fdc_st0], 11011000b
jnz .error
mov [floppy_status], FLOPPY_STATUS_OK
mov [fdc_mutex], FALSE
mov rax, TRUE
ret
.error:
mov [floppy_status], FLOPPY_STATUS_SECTOR_NOT_FOUND
mov [fdc_mutex], FALSE
xor rax, rax
ret
endp
proc FloppyWrite stdcall uses rcx,sector,buffer
mov rcx, 3
@@:
stdcall _FloppyWrite,[.sector],[.buffer]
test rax, rax
jnz @f
stdcall FDC_Recalibrate
stdcall FDC_SeekTrack,[.sector]
loop @b
xor rax, rax
ret
@@:
ret
endp
В чём может быть дело? Может я не учёл какие-нибудь особенности реальных флопи-дисководов?