Floppy driver error
Posted: Sat May 14, 2011 9:14 pm
So, I tried to write floppy driver (that's just initializing and read functions), but get #GP.
Bochs tells just: refetch: getHostMemAddr vetoed direct read, pAddr=0x000a0000
I tried to find out where is an error, but wasn't succeeded.
I read data to RAM address 0000.
IRQ6 handler just sets flag (floppy_int_active) and timer handler increments tick_count.
So, that's floppy driver code:
Bochs tells just: refetch: getHostMemAddr vetoed direct read, pAddr=0x000a0000
I tried to find out where is an error, but wasn't succeeded.
I read data to RAM address 0000.
IRQ6 handler just sets flag (floppy_int_active) and timer handler increments tick_count.
So, that's floppy driver code:
Code: Select all
;Registers
FLOP_SRB equ 3F1h
FLOP_DOR equ 3F2h
FLOP_TDR equ 3F3h
FLOP_MSR equ 3F4h
FLOP_DSR equ 3F4h
FLOP_FIFO equ 3F5h
FLOP_DIR equ 3F7h
FLOP_CCR equ 3F7h
FDD_read:
call FDD_init
mov bh,18
call delay
;speed 500 kbyte/sec
mov dx,FLOP_DIR;FLOP_DIR
xor al,al
out dx,al
;3 times try to recolibrate
mov cl,3
.recalibre_retry:
call FDD_recalibrate
jc .error
call FDD_sense_interrupt;take down the order
jnc .recalibre_success
loop .recalibre_retry
jmp .error
.recalibre_success:
call FDD_seek;go to first track
jc .error
call FDD_sense_interrupt
jc .error
mov bh,1
call delay
call DMA_init
mov bh,1
call delay
mov cl,1
call FDD_read_sector
mov bh,1
call FDD_stop
ret
.error:
xor ecx,ecx
mov esi,floppy_error
int 1h
ret
;DMA initialize
DMA_init:
xor ebx,ebx;buffer address
cli
;read
mov al,46h
out 12,al;reset trigger
out 11,al;set mode
mov al,bl
out 4,al;address - 0000
out 4,al;
out 81h,al
;how many bytes to read
mov ax,511;sector_size-1
out 5,al
mov al,ah
out 5,al
mov al,2;de-block channel 2 of controller
out 10,al
sti
ret
;al - byte to send
FDD_init:
mov dx,FLOP_DOR
xor ax,ax
out dx,al
mov al,00011100b ; Motor0, Reset, DMA
out dx,al
ret
FDD_stop:
mov al,00001100b ; DMA, Reset
mov dx,FLOP_DOR
out dx,al
xor al,al
out dx,al
ret
FDD_send_byte:
pusha
clc
mov dx,FLOP_MSR;reset controller
mov cx,0FFFFh
push ax
.FDD_send_byte_loop:
in al,dx
and al,11000000b
cmp al,10000000b;check MSR - is floppy free and ready?
je .FDD_send_byte_ready
loop .FDD_send_byte_loop
.FDD_send_byte_ready:
pop ax
mov dx,FLOP_FIFO
out dx,al
popa
ret
.FDD_send_byte_err:
xor ecx,ecx
mov esi,floppy_error
int 1h
stc
popa
ret
;al - result
FDD_recv_byte:
push cx
clc
mov dx, FLOP_MSR
mov cx, 0FFFFh
.FDD_recv_byte_loop:
in al, dx
and al, 11000000b
cmp al, 11000000b;check MSR - is floppy free?
jne .FDD_recv_byte_ready
loop .FDD_recv_byte_loop
.FDD_recv_byte_ready:
mov dx, FLOP_FIFO
in al, dx
.FDD_recv_byte_exit:
pop cx
ret
.FDD_recv_byte_err:
xor ecx,ecx
mov esi,floppy_error
int 1h
stc
pop cx
ret
FDD_sense_interrupt:
;command code
mov al,00001000b
call FDD_send_byte
jc .FDD_sense_int_status_exit;we make suggestions basing on carry flag
;read st0
call FDD_recv_byte
jc .FDD_sense_int_status_exit
and al,11110000b
cmp al,00100000b
jne .FDD_sense_int_status_error
call FDD_recv_byte
jc .FDD_sense_int_status_exit
test al,al
jnz .FDD_sense_int_status_error
.FDD_sense_int_status_exit:
ret
.FDD_sense_int_status_error:
xor ecx,ecx
mov esi,floppy_error
int 1h
stc
ret
FDD_motor_stop:
mov dx,FLOP_DOR
mov al,00001100b;Motor0, Reset
out dx,al
xor al,al
out dx,al
ret
FDD_recalibrate:
mov al,00000111b
call FDD_send_byte
jc .FDD_recalibrate_exit
xor al,al
call FDD_send_byte
jc .FDD_recalibrate_exit
call FDD_wait_end
.FDD_recalibrate_exit:
ret
FDD_seek:
mov al,00001111b
call FDD_send_byte
jc .FDD_seek_exit
xor al,al
call FDD_send_byte
jc .FDD_seek_exit
call FDD_send_byte
jc .FDD_seek_exit
call FDD_wait_end
.FDD_seek_exit:
ret
FDD_wait_end:
.FDD_wait_end_loop:
cmp [floppy_int_active],1
jne .FDD_wait_end_loop
.FDD_wait_end_exit:
mov [floppy_int_active],0
ret
FDD_read_sector:
;CL - sector number
pushad
;part 1
mov al,1100110b
call FDD_send_byte
jc .FDD_read_sector_exit
;part 2
xor al,al
call FDD_send_byte
jc .FDD_read_sector_exit
;cylinder
call FDD_send_byte
jc .FDD_read_sector_exit
;head
call FDD_send_byte
jc .FDD_read_sector_exit
;sector #
mov al,cl
call FDD_send_byte
jc .FDD_read_sector_exit
mov al,2;sector size is 512
call FDD_send_byte
jc .FDD_read_sector_exit
mov al,19
call FDD_send_byte
jc .FDD_read_sector_exit
mov al,1Bh;GPL
call FDD_send_byte
jc .FDD_read_sector_exit
mov al,0FFh
call FDD_send_byte
jc .FDD_read_sector_exit
call FDD_wait_end
;ST0
call FDD_recv_byte
jc .FDD_read_sector_exit
test al,11111100b
jnz .FDD_read_sector_exit
;ST1 and ST2
xor cx,cx
mov cl,2
.FDD_read_sector_STX:
call FDD_recv_byte
jc .FDD_read_sector_exit
test al,al
jnz .FDD_read_sector_error
loop .FDD_read_sector_STX
;Read C H R N
mov cl,4
.FDD_read_sector_result:
call FDD_recv_byte
loop .FDD_read_sector_result
.FDD_read_sector_exit:
popad
ret
.FDD_read_sector_error:
xor ecx,ecx
mov esi,floppy_error
int 1h
stc
popad
ret
;bh - 1/18.8 of sec
delay:
mov [tick_count],0;tick_count is incremented by timer handler
.loop:
cmp [tick_count],bh
jl .loop
ret
;;;;;;;;;;;;;;;;;;;;;;;;;Vars;;;;;;;;;;;;;;;;;
floppy_int_active db 0
tick_count db 0