Read from Floppy

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
tresss
Posts: 21
Joined: Thu Jul 06, 2006 10:52 pm

Read from Floppy

Post by tresss »

Why I can't Read some from Floppy

I want read the first sector's data to 0x500 in the code,But It refuse work.

In Protect mode I call by this:

Code: Select all

  Call FloppyReset

  Call FloppyReadSector
the Floppy.inc:

Code: Select all

;**********************************************************
;Floppy.
;**********************************************************
FdcDor		equ	0x3f2
FdcMsr		equ	0x3f4
FdcData		equ	0x3f5

FloppyReset:			;reset
  pusha
  xor ax,ax
  mov dx,0x3f2
  push dx
  out dx,ax 
  mov dx,0x3f4;7
  out dx,ax
  pop dx
  mov al,0x0c
  out dx,al

  Call Wait_Interrupt_Fdc	;wait interrupt

  mov ax,0x03			;FD_SPECIFY
  Call Floppy_SendByte		;If error then al=0
  mov ax,0xDF			
  Call Floppy_SendByte
  mov ax,0x02			;
  Call Floppy_SendByte


  popa


ret

Wait_Interrupt_Fdc:
  mov ecx,0xFFFF		;in time
Wait_loop1:
  mov al,[FdcInt1]
  Cmp al,0x01
  jz Interrupt_OK
  Loop Wait_loop1
Interrupt_OK:
ret

;**********************************************************
;Send data
;**********************************************************
Floppy_SendByte:
  push ax
  mov ecx,0xFFFF	
Wait_Send_Loop:
  mov dx,FdcMsr
  in al,dx
  and al,0xc0
  cmp al,0x80
  jz FSendBegin
  mov dx,0x80
  in al,dx
  loop Wait_Send_Loop
  pop ax
  xor al,al
  jmp Result_Send
FSendBegin:
  pop ax
  mov dx,FdcData
  out dx,ax
  xor al,al
  inc al

Result_Send:
ret

FloppyTurnOn:
  mov dx,FdcDor
  mov ax,0x1c
  out dx,ax
  mov cx,0xff
SleepTurnOn:
  nop
  loop SleepTurnOn
ret

FloppyTurnOff:
  mov dx,FdcDor
  mov ax,0x0c
  out dx,ax
ret


FloppySeekTrace:
  push ax
  mov ax,0x7
  Call Floppy_SendByte
  xor ax,ax
  Call Floppy_SendByte
  pop ax
  Call Floppy_SendByte

  mov cx,0xff
SleepSeekTrace:
  nop
  loop SleepSeekTrace

ret

DMAOpen:

  mov dx,0x0A
  mov ax,0x06
  out dx,ax
  mov dx,0x0C
  xor ax,ax
  out dx,ax		;stop DMA
  mov dx,0x0B		;0a  or  0b
  mov ax,0x46		;read 0x46,write 0x4A
  out dx,ax
  mov dx,0x04
  xor ax,ax
  out dx,ax		;addr
  mov ax,0x05
  out dx,ax		;addr 0x500
  mov dx,0x81
  xor ax,ax
  out dx,ax		;addr
  mov dx,0x05
  xor ax,ax	
  out dx,ax
  mov ax,0x02		; read 512B
  out dx,ax
  mov dx,0x0A
  mov ax,0x02
  out dx,ax

ret

DMAClose:
  mov dx,0xa
  mov ax,0x6
  out dx,ax
  mov dx,0xc
  xor ax,ax
  out dx,ax

ret



;**********************************************************
;read
;**********************************************************
FloppyReadSector:
  cli
  Call FloppyTurnOn
  xor ax,ax
  Call FloppySeekTrace
  Call DMAOpen	
  mov ax,0x66
  Call Floppy_SendByte
  mov ax,0x05	
  Call Floppy_SendByte
  xor ax,ax	
  Call Floppy_SendByte
  xor ax,ax	
  Call Floppy_SendByte
  xor ax,ax
  inc ax	
  Call Floppy_SendByte
  mov ax,0x2	
  Call Floppy_SendByte
  mov ax,18	
  Call Floppy_SendByte
  mov ax,27	
  Call Floppy_SendByte
  mov ax,0xFF	
  Call Floppy_SendByte
  sti

  xor al,al
  mov [FdcInt1],al
  Call Wait_Interrupt_Fdc

  Call DMAClose

  Call FloppyTurnOff

ret


Why?[/code]
http://english.writeos.com

My English is not very good
tresss
Posts: 21
Joined: Thu Jul 06, 2006 10:52 pm

Post by tresss »

Please Find some Error in the Floppy.inc

thanks
http://english.writeos.com

My English is not very good
User avatar
prajwal
Member
Member
Posts: 154
Joined: Sat Oct 23, 2004 11:00 pm
Contact:

Post by prajwal »

mov ax,0x66 ; Read Command
Call Floppy_SendByte
mov ax,0x05 ; Head1 Drive 1
Call Floppy_SendByte
xor ax,ax // Track 0
Call Floppy_SendByte
xor ax,ax // Head 0 ???
Call Floppy_SendByte
In the Second Command, u r sending 0x5 which reads Head 2 Drive 1 and furthur
u r giving Head No as 0 in Command 4....

Is this correct ????
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Post by bubach »

Not sure if this even helps, but you can use my latest floppy code as a reference:

Code: Select all

;----------------------------------------------------------;
; BOS kernel                Christoffer Bubach, 2004-2006. ;
;----------------------------------------------------------;
;                                                          ;
;               floppy disk driver.                        ;
;                                                          ;
;----------------------------------------------------------;



;---------------------------;
;  variables and contants   ;
;---------------------------;
     fdd_int_done    dw   0                           ; is the IRQ done?
     fdd_motor_on    db   0                           ; fdd motor on=1, off=0
     fdd_drivehead   db   0                           ; ((head*4)|drive)
     fdd_head        db   0
     fdd_track       db   0
     fdd_sector      db   0
     fdd_error       db   0                           ; should we recalibrate
                                                      ; at next read/write?
     fdd_errorcode   db   0

     result_ST0      db   0
     result_ST1      db   0                           ; or pcn
     result_ST2      db   0
     result_ST3      db   0
     result_C        db   0
     result_H        db   0
     result_R        db   0
     result_N        db   0
     result_extra    db   0



;------------------------------------------------------;
;    initializes the floppy disk driver                ;
;                                                      ;
;------------------------------------------------------;
fdc_init:
          push    eax
          push    ecx
          push    edi

          xor     eax, eax                            ; get configuration
          mov     al, 0x10                            ; from CMOS.
          out     0x70, al
          in      al, 0x71

          shr     al, 4
          cmp     al, 4                               ; a 1.44mb?
          jnz     .no_floppy

          mov     cl, 0x26                            ; hook IRQ 6
          mov     dx, 0x8                             ; CS = 8
          mov     edi, floppy_irq
          call    set_int

          mov     cl, 6                               ; enable IRQ6
          call    enable_irq

          call    fdd_reset                           ; reset FDC

     .no_floppy:
          pop     edi
          pop     ecx
          pop     eax
          ret



;------------------------------------------------------;
;         floppy IRQ                                   ;
;                                                      ;
;------------------------------------------------------;
floppy_irq:
          push    ds
          push    eax
          push    ebx

          mov     ax, 0x10
          mov     ds, ax

          mov     [fdd_int_done], 1
          mov     al, 0x20
          out     0x20, al

          pop     ebx
          pop     eax
          pop     ds
          iret



;------------------------------------------------------;
;     wait for a floppy int                            ;
;                           out:  cf  = 1 if timeout   ;
;------------------------------------------------------;
wait_int:
          push    eax
          push    ecx

          mov     ecx, 150                            ; 50 = 0.5 seconds.
          call    active_delay                        ; timer.inc
     .l1:
          cmp     dword [ecx], 0                      ; timeup?
          je      .error
          mov     ax, [fdd_int_done]                  ; if not we check for int.
          or      ax, ax
          jz      .l1

          clc
          jmp     .end
     .error:
          stc
     .end:
          pop     ecx
          pop     eax
          ret



;------------------------------------------------------;
;     fdd motor off                                    ;
;                           out:  nothing              ;
;------------------------------------------------------;
fdd_off:
          cmp     [fdd_motor_on], 0
          je      .end
          push    eax
          push    edx

          mov     dx, 0x3F2
          mov     al, 0x0c                            ; motor off
          out     dx, al
          mov     [fdd_motor_on], 0

          pop     edx
          pop     eax
     .end:
          ret



;------------------------------------------------------;
;     fdd motor on                                     ;
;                           out: nothing               ;
;------------------------------------------------------;
fdd_on:
          cmp     [fdd_motor_on], 1
          je      .end
          push    eax
          push    edx

          mov     dx, 0x3F2                           ; motor 0 on..
          mov     al, 0x1C
          out     dx, al

          mov     ecx, 20                             ; 1/5 of a sec. to speed up
          call    delay                               ; in timer.inc
          mov     [fdd_motor_on], 1

          pop     edx
          pop     eax
     .end:
          ret



;------------------------------------------------------;
;   send a data byte to the FDC                        ;
;                                                      ;
;                                in:  al  = data byte  ;
;------------------------------------------------------;
fdc_sendbyte:
          push    edx
          push    ecx
          push    eax

          mov     ecx, 50                             ; 50 = 0.5 seconds.
          call    active_delay                        ; timer.inc
     .l1:
          cmp     dword [ecx], 0                      ; timeup?
          je      .error
          mov     dx, 0x3f4                           ; check status reg
          in      al, dx
          and     al, 0xC0
          cmp     al, 0x80                            ; are we ok to write
          jnz     .l1

          pop     eax
          pop     ecx
          mov     dx, 0x3F5                           ; send byte
          out     dx, al
          pop     edx
          clc
          ret
     .error:
          pop     eax
          pop     ecx
          pop     edx
          stc
          ret



;------------------------------------------------------;
;   read a data byte from the FDC                      ;
;                                                      ;
;                             out: al  = data byte     ;
;------------------------------------------------------;
fdc_getbyte:
          push    edx
          push    ecx
          push    eax

          mov     ecx, 50                             ; 50 = 0.5 seconds.
          call    active_delay                        ; timer.inc
     .l1:
          cmp     dword [ecx], 0                      ; timeup?
          je      .error
          mov     dx, 0x3f4                           ; check status reg
          in      al, dx
          and     al, 0xD0
          cmp     al, 0xD0                            ; are we ok to read
          jnz     .l1

          pop     eax
          pop     ecx
          mov     dx, 0x3F5                           ; get the byte
          in      al, dx
          pop     edx
          clc
          ret
     .error:
          pop     eax
          pop     ecx
          pop     edx
          stc
          ret



;------------------------------------------------------;
;   sense interrupt status command                     ;
;                                                      ;
;------------------------------------------------------;
sensei:
          push    eax

          mov     al, 0x08                            ; fdc command
          call    fdc_sendbyte
          call    fdc_getbyte
          mov     ah, al                              ; save ST0 in ah
          call    fdc_getbyte                         ; read PCN
          clc
          test    ah, 0x80                            ; test for error:
          jz      .end                                ; "invalid command"
          stc
     .end:
          pop     eax
          ret



;------------------------------------------------------;
;    reset controller                                  ;
;                                                      ;
;------------------------------------------------------;
fdd_reset:
          push    eax
          push    ecx
          push    edx

          mov     byte [fdd_motor_on], 0

          mov     dx, 0x3f2
          mov     al, 8                               ; off with all motors,
          out     dx, al                              ; dma,irq etc..

          mov     ecx, 5
          call    delay                               ; in timer.inc

          mov     dx, 0x3f7
          mov     al, 0
          out     dx, al                              ; work at 500 kbit/s

          mov     dx, 0x3f2
          mov     al, 0x0c
          out     dx, al                              ; reenable interrupts

          mov     [fdd_int_done], 0
          call    wait_int                            ; wait for floppy int.
          jc      .error                              ; timeout?

          mov     cx, 0x04
     .status:                                         ; 4 dummy-reads.
          call    sensei
          loop    .status

          mov     al, 0x03                            ; specify command
          call    fdc_sendbyte
          mov     al, 0xDF                            ; SRT, HUT
          call    fdc_sendbyte
          mov     al, 0x02                            ; HLT, ND
          call    fdc_sendbyte

          mov     al, 1
          call    fdd_recal_seek
          jc      .error
          call    fdd_off
          clc
          jmp     .end
     .error:
          call    fdd_off
          stc
     .end:
          pop     edx
          pop     ecx
          pop     eax
          ret



;------------------------------------------------------;
;     fdd recalibrate/seek                             ;
;                                                      ;
;   in:  al  = 0 on seek, 1 on recalibrate             ;
;        bl  = (at seek) track                         ;
;        bh  = (at seek) ((head*4)|drive)              ;
;                                                      ;
;------------------------------------------------------;
fdd_recal_seek:
          push    eax

          call    fdd_on                              ; turn motor on
          cmp     al, 0
          jne     .recalibrate
          clc
          cmp     bl, [result_C]                      ; are we there yet? :D
          je      .ok
          mov     al, 0x0F                            ; seek command
          call    fdc_sendbyte
          mov     al, bh                              ; ((head*4)|drive)
          call    fdc_sendbyte
          mov     al, bl                              ; track
          call    fdc_sendbyte
          mov     [result_C], bl                      ; now on..?
          jmp     .get_int
     .recalibrate:
          mov     al, 0x07                            ; recalibrate command
          call    fdc_sendbyte
          mov     al, 0                               ; drive number
          call    fdc_sendbyte
          mov     [result_C], 0                       ; now on track 0
     .get_int:
          mov     [fdd_int_done], 0
          call    wait_int
          jc      .error

          call    sensei                              ; sense interrupt status
          jc      .error
      .ok:
          clc
          jmp     .end
     .error:
          stc
     .end:
          pop     eax
          ret



;------------------------------------------------------;
;  fdd read/write                                      ;
;   input:  bl  = 0 read, 1 write                      ;
;           ch  = track/cylinder                       ;
;           cl  = sector                               ;
;           dh  = head                                 ;
;           edi = address to store or read the data    ;
;   output: al  = status                               ;
;           cf  = 0 if ok, 1 if error                  ;
;------------------------------------------------------;
fdd_read_write:
          pushad

          and     dh, 1                               ; head 0 or 1?
          mov     [fdd_head], dh                      ; store it.
          shl     dh, 2
          or      dh, 0                               ; drive 0, fd0
          mov     [fdd_drivehead], dh                 ; dh = ((head*4)|drive)
          mov     [fdd_errorcode], 0x04               ; basic error code
          cmp     ch, 0x51                            ; check for allowed
          jae     .error                              ; track number.
          mov     [fdd_track], ch
          cmp     cl, 0x13                            ; check for allowed
          jae     .error                              ; sector number.
          mov     [fdd_sector], cl

          cmp     [fdd_error], 1
          jne     .no_previous_error
          mov     al, 1
          call    fdd_recal_seek
     .no_previous_error:
          call    fdd_on

          mov     dx, 0x3F7
          mov     al, 0                               ; 500Kb/sec mode
          out     dx, al
          mov     [fdd_errorcode], 0x80               ; error code

          xor     ecx, ecx
          mov     cx, 3                               ; try seek 3 times
     .l2:
          mov     al, 0
          mov     bl, [fdd_track]
          mov     bh, [fdd_drivehead]                 ; ((head*4)|drive)
          call    fdd_recal_seek
          jnc     .l3                                 ; ok, continue.
          loop    .l2
          jmp     .error                              ; timeout.
     .l3:
          push    ebx
          cmp     bl, 0
          je      .read_fdd

     .write_fdd:
          push    edi
          mov     esi, edi
          mov     edi, 0x80000                        ; copy the stuff we will
          mov     ecx, 128                            ; write to the DMA buffer
          rep     movsd                               ; 128*4=512
          pop     edi

          mov     bl, 2                               ; channel 2
          mov     esi, 512                            ; bytes to write
          mov     ecx, 0x80000                        ; page & offset
          mov     bh, 1                               ; write floppy, read DMA
          call    dma_transfer

          mov     al, 0xC5                            ; write sector command
          call    fdc_sendbyte
          jmp     .cont

     .read_fdd:
          mov     bl, 2                               ; channel 2
          mov     esi, 512                            ; bytes to read
          mov     ecx, 0x80000                        ; page & offset
          mov     bh, 0                               ; read floppy, write DMA
          call    dma_transfer

          mov     al, 0xE6                            ; read sector command
          call    fdc_sendbyte

     .cont:
          pop     ebx
          mov     al, [fdd_drivehead]                 ; ((head*4)|drive)
          call    fdc_sendbyte
          mov     al, [fdd_track]                     ; track/cylinder
          call    fdc_sendbyte

          mov     al, [fdd_head]                      ; head/side 0 or 1
          call    fdc_sendbyte
          mov     al, [fdd_sector]                    ; sector number
          call    fdc_sendbyte
          mov     al, 0x02                            ; sector size, 512 bytes
          call    fdc_sendbyte

          mov     al, 0x12                            ; sectors to a track
          call    fdc_sendbyte
          mov     al, 0x1B                            ; gap length
          call    fdc_sendbyte
          mov     al, 0xFF                            ; data length
          call    fdc_sendbyte

          mov     [fdd_int_done], 0
          call    wait_int
          jc      .error

          call    fdc_getbyte
          mov     [result_ST0], al                    ; ST0
          call    fdc_getbyte
          mov     [result_ST1], al                    ; ST1
          call    fdc_getbyte
          mov     [result_ST2], al                    ; ST2
          call    fdc_getbyte
          mov     [result_C], al                      ; cylinder
          call    fdc_getbyte
          mov     [result_H], al                      ; head
          call    fdc_getbyte
          mov     [result_R], al                      ; sector number.
          call    fdc_getbyte
          mov     [result_N], al                      ; sector size

          test    [result_ST0], 0xc0                  ; test if sr0 is 0xC0
          jnz     .error
          cmp     bl, 1                               ; did we write the disk?
          je      .ok

          mov     ecx, 512                            ; sector size in bytes
          mov     esi, 0x80000                        ; copy to dest. in edi
          rep     movsb
     .ok:
          mov     [fdd_errorcode], 0                  ; no error.. :D
          mov     [fdd_error], 0                      ; no recal. next time
          clc
          jmp     .end
     .error:
          mov     [fdd_error], 1                      ; recalibrate next time
          stc
     .end:
          call    fdd_off                             ; floppy motor off
          popad
          mov     al, [fdd_errorcode]                 ; error status
          ret
This code was originally based on Dex4u's floppy driver, but is now
mostly rewritten by me since I had some trubbles with his code.

HTH,
Christoffer
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
tresss
Posts: 21
Joined: Thu Jul 06, 2006 10:52 pm

Post by tresss »

srinivasa_prajwal wrote: In the Second Command, u r sending 0x5 which reads Head 2 Drive 1 and furthur
u r giving Head No as 0 in Command 4....

Is this correct ????
I change It to 0x00.

Wrong too........
http://english.writeos.com

My English is not very good
tresss
Posts: 21
Joined: Thu Jul 06, 2006 10:52 pm

Post by tresss »

bubach wrote:Not sure if this even helps, but you can use my latest floppy code as a reference:
Thanks...


I'm Reading the code now!!
http://english.writeos.com

My English is not very good
blackcatcoder
Member
Member
Posts: 132
Joined: Wed Nov 03, 2004 12:00 am
Location: Austria
Contact:

Post by blackcatcoder »

Hi,


I would suggest to put this tricky asm into C ;-).

It's a lot easier to find errors.

Nevertheless, I will go through your code.

Hf!
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

Yes C programmer, only need to complie something to find lots of error :lol:
Post Reply