Page 1 of 1

INT13 makes me dizzy!

Posted: Tue Jul 09, 2002 8:45 am
by Pype.Clicker
Here's a part of my bootloader code (complete code can be found on clicker CVS. It works pretty fine on Intel motherboards (ranging from P1 to P3), but it only loads one sector every minute on AMD hardware ... If i remember well, each call to that function only ask for one single sector...

Does anyone have a clue about this ??
Thanks in advance ...

; Read a sector from the floppy drive.
;
; Parameters:
; - "logical" sector number [bp+8]
; - destination segment [bp+6]
; - destination offset [bp+4]
ReadSector:
   push   bp         ; set up stack frame
   mov   bp, sp         ; "
   pusha            ; save all registers

   ; Sector = log_sec % SECTORS_PER_TRACK
   ; Head = (log_sec / SECTORS_PER_TRACK) % HEADS
   mov   ax, [bp+8]      ; get logical sector number from stack
   xor   dx, dx         ; dx is high part of dividend (== 0)
   mov   bx, SECTORS_PER_TRACK   ; divisor
   div   bx         ; do the division
   mov   [cs:sec], dx      ; sector is the remainder
   and   ax, 1         ; same as mod by HEADS==2 (slight hack)
   mov   [cs:head], ax

   ; Track = log_sec / (SECTORS_PER_TRACK*HEADS)
   mov   ax, [bp+8]      ; get logical sector number again
   xor   dx, dx         ; dx is high part of dividend
   mov   bx, SECTORS_PER_TRACK*2   ; divisor
   div   bx         ; do the division
   mov   [cs:track], ax      ; track is quotient


   ; Now, try to actually read the sector from the floppy,
   ; retrying up to 3 times.

   mov   [cs:num_retries], byte 0

.again:
   mov   ax, [bp+6]      ; dest segment...
   mov   es, ax         ; goes in es
   mov   ax, (0x02 << 8) | 1   ; function = 02h in ah,
               ; # secs = 1 in al
   mov   bx, [cs:track]      ; track number...
   mov   ch, bl         ; goes in ch
   mov   bx, [cs:sec]      ; sector number...
   mov   cl, bl         ; goes in cl...
   inc   cl         ; but it must be 1-based, not 0-based
   mov   bx, [cs:head]      ; head number...
   mov   dh, bl         ; goes in dh
   xor   dl, dl         ; hard code drive=0
   mov   bx, [bp+4]      ; offset goes in bx
               ; (es:bx points to buffer)

   ; Call the BIOS Read Diskette Sectors service
   int   0x13

   ; If the carry flag is NOT set, then there was no error
   ; and we're done.
   jnc   .done

   ; Error - code stored in ah
   mov   dx, ax
   call PrintHex
   inc   byte [cs:num_retries]
   cmp   byte [cs:num_retries], 3
   jne   .again

   ; If we got here, we failed thrice, so we give up
   mov   dx, 0xdead
   call   PrintHex
.here:   jmp   .here

.done:
   popa            ; restore all regisiters
   pop   bp         ; leave stack frame
   ret

Re:INT13 makes me dizzy!

Posted: Tue Jul 09, 2002 11:00 am
by crazybuddha
I can't answer your question, but perhaps I can question your question. :)

By "sector every minute" do you mean that it is relatively slow or that it works in bursts?

Can you be certain that it has anything to do with AMD or a particular BIOS, rather than the floppy controller on one particular machine? Basically, have you tried it on more than one AMD? Have you tried to run it under the same BIOS, but different processors?

If the AMD machine has ISA DMA, then I can send you some floppy reading code that doesn't use the BIOS. It might help you cross-check the problem.

Re:INT13 makes me dizzy!

Posted: Tue Jul 09, 2002 12:47 pm
by Pype.Clicker
crazybuddha wrote: I can't answer your question, but perhaps I can question your question. :)

By "sector every minute" do you mean that it is relatively slow or that it works in bursts?

Can you be certain that it has anything to do with AMD or a particular BIOS, rather than the floppy controller on one particular machine? Basically, have you tried it on more than one AMD? Have you tried to run it under the same BIOS, but different processors?

If the AMD machine has ISA DMA, then I can send you some floppy reading code that doesn't use the BIOS. It might help you cross-check the problem.
I've tried it on 4 Intel machines (among which some Award Modular Bios) and it works fine (needs about 5-10 seconds to load the files) and on 2 AMD machines (a K6-II with Award Modular Bios and an Athlon - unknonw BIOS).
On both AMD machines, the sectors are read, but there are more than 1 minute between each sector reading, thus leading to *very* long boot time.
I was wondering if i needn't to do something with the motor, etc.

I'd prefer not to use DMA code in a bootloader because of its extra-size...

Re:INT13 makes me dizzy!

Posted: Tue Jul 09, 2002 1:03 pm
by crazybuddha
I meant only as a way to test your assumptions.

( In spite of that, it does seem that perhaps using the boot sector to use the BIOS to read in a couple of sectors of a DMA loader, then use that to load the rest of the floppy, is a viable idea -- I don't know what the pitfalls in this approach would be).

Re:INT13 makes me dizzy!

Posted: Wed Jul 10, 2002 3:35 am
by drizzt
I've the same problem.. on an Intel machine. But in my case floppy is USB.
In this case I think the problem is in the controller... and to read a sector is very very slow...

Re:INT13 makes me dizzy!

Posted: Mon Jul 22, 2002 8:52 am
by crazybuddha
pype & drizzt,
did you guys ever resolve this???

Re:INT13 makes me dizzy!

Posted: Mon Jul 22, 2002 10:53 am
by drizzt
I've resolved the problem by cutting the control of the flag after int 13h instruction.

If I want to read or write a sector I only generate int 13h once... now it's very fast, but in some case it makes errors...

To obviate this, before to read or to write the sector(s), I call a "reset disk" operation, that first reset the controller and then verify a sector of the disk to refresh the controller? in this case it doesn't makes errors. I think? ;)

I've tested this on my USB floppy and it seems to be fast and secure... I don't know anything about AMD processor... pype could try this on his machine:

_reset_disk:         ; Reset the controller
xor ax, ax    
mov dl, [DRIVE]
int 13h

mov   ah, 04      ; Verify a sector
mov   ch, 0      ; Cylinder
mov   dh, 0      ; Head
mov   cl, 1      ; Sector
mov   al, 1      ; # of sectors
   
int   13h      
ret

For example my read_disk operation is:

_read_disk:

call   _reset_disk

mov ah, 2    ; Read
mov al, [Sectors] ; # of sectors
mov ch, [Cyl]    ; Cylinder
mov cl, [Sect]    ; Sector
mov dh, [Head]    ; Head
mov dl, [DRIVE]    ; Drive

int 13h    ; Read !
ret

Re:INT13 makes me dizzy!

Posted: Tue Jul 23, 2002 2:17 pm
by Pype.Clicker
tnx! i'll try it a.s.a.p