Page 1 of 1

Reading File on Floppy [SOLVED]

Posted: Sat Apr 12, 2008 4:38 pm
by Altimicus
Hi everyone i'm new to OS dev got a few tutorials and now trying to build my own.... but I get a strange error when I try to read a sector from the floppy... it tries to read from cylinder 99 (63h) I dunno why

Here is the part of the code that computes the number:

Code: Select all

    xor     dx, dx                              
    div     WORD [bpbSectorsPerTrack]          
    inc     dl                                  
    mov     BYTE [rdSector], dl
    xor     dx, dx                             
    div     WORD [bpbHeadsPerCylinder]         
    mov     BYTE [rdHead], dl
    mov     BYTE [rdTrack], al
Any help would be apreciated

Thanks

Re: Reading File on Floppy

Posted: Sat Apr 12, 2008 7:14 pm
by Dex
You could try:

Code: Select all

    ;xor     dx, dx                              
    div     WORD [bpbSectorsPerTrack]          
    inc     dl                                  
    mov     BYTE [rdSector], dl
    xor     dx, dx                             
    div     WORD [bpbHeadsPerCylinder]         
    mov     BYTE [rdHead], dl
    mov     BYTE [rdTrack], al
See if that works, as it depends how your other code is setup..

Posted: Sat Apr 12, 2008 7:31 pm
by Altimicus
Well, taking out the xor dx,dx didnt make aany effect it keeps trying to read a track above 80... 99 to be especific...

ill put all the code involved in the reading part that gives the error, but the comments are in portuguese.

Code: Select all

LBAtoCHS:
    ;xor     dx, dx                              ; Preapara dx:ax para operacao
    div     WORD [bpbSectorsPerTrack]           ; calcula
    inc     dl                                  ; ajusta para setor 0
    mov     BYTE [absoluteSector], dl
    xor     dx, dx                              ; Preapara dx:ax para operacao
    div     WORD [bpbHeadsPerCylinder]          ; calcula
    mov     BYTE [absoluteHead], dl
    mov     BYTE [absoluteTrack], al
ret
The code below loads the root to memory.

Code: Select all

loadroot:

; Calcula o tamanho do diretorio root

    xor     cx, cx
    xor     dx, dx
    mov     ax, 0x0020                               ; entrada de diretorio 32 bytes
    mul     WORD [bpbRootEntries]                    ; tamanho total do diretorio
    div     WORD [bpbBytesPerSector]                 ; setores usados pelo diretorio
    xchg    ax, cx
	
; Calcula a localização do diretorio root

    mov     al, BYTE [bpbNumberOfFATs]                ; numero de FATs
    mul     WORD [bpbSectorsPerFAT]                   ; setores usados pelas FATs
    add     ax, WORD [bpbReservedSectors]             ; soma os setores reservados
    mov     WORD [datasector], ax                     ; base do diretorio root
    add     WORD [datasector], cx
	
; grava-o na memoria depois do boot sector (7C00:0200)
    
    mov     bx, 0x0200
    call    readsectors
And here the readsectors function:

Code: Select all

readsectors:
	
    .main:
        mov     di, 0x0005                          ; 5 tentativas para erro
    .sectorloop:
        push    ax
        push    bx
        push    cx
		
		mov ax,msg1
		call print
		
        call    LBAtoCHS                            ; converter setor primario para CHS
        mov     ah, 0x02                            ; setor de leitura da BIOS
        mov     al, 0x01                            ; ler 1 setor
        mov     ch, BYTE [absoluteTrack]            ; track
        mov     cl, BYTE [absoluteSector]           ; sector
        mov     dh, BYTE [absoluteHead]             ; head
        mov     dl, BYTE [bsDriveNumber]            ; drive
        int     0x13
When it comes to this place it gives the track 63h

Well Ill keep trying to find the error, but if anyone can give me a light it would help

Thanks in advance

EDIT: I also tried a code from the tutorial i followed

Code: Select all

div     word [bpbSectorsPerTrack]
                ; ax = LBA / SPT
                ; dx = LBA % SPT         = sector - 1
        mov     cx, dx
        inc     cx
                ; cx = sector no.
        xor     dx, dx
        div     word [bpbHeadsPerCylinder]
                ; ax = (LBA / SPT) / HPC = cylinder
                ; dx = (LBA / SPT) % HPC = head
        mov     ch, al
                ; ch = LSB 0...7 of cylinder no.
        shl     ah, 6
        or      cl, ah
                ; cl = MSB 8...9 of cylinder no. + sector no.
        mov     dh, dl
                ; dh = head no.
        mov     dl, [bsDriveNumber]
                ; dl = drive no.
        mov     ax, 201h
But it gave the same 63h (99) for the track

Posted: Sun Apr 13, 2008 10:22 am
by Ready4Dis
Here is my LBA->CHS function for reference:

Code: Select all

LBA2CHS:
xor dx, dx
div word [SectorsPerTrack]
mov cl, dl
inc cl
xor dx, dx
div word [Heads]
mov dh, dl
mov ch, al
shl ah, 6
or cl, ah
ret
This leaves all the variables setup properly for the int 0x13 call... the function would look like this:

Code: Select all

;Inputs:
;ax = sector (LBA)
;es:bx = destination
ReadFloppySector:
pusha
call LBA2CHS
.Retry
call ResetDrive      ;Make sure the drive is reset and ready to read
mov dl, [Bootdisk] ;The drive we booted from!
mov ax, 0x0201    ;Read one sector
int 0x13                ;Do the interrupt
jc .Retry               ;Error, try again...
popa
ret

;ax = LBA
;cx = count
;es:bx = location
ReadFloppy:
pusha
.Looper
  call ReadFloppySector
  inc ax           ;Next Sector # (LBA)
  add bx, 512   ;Move to next memory location
loop .Loop
popa
ret
This is pretty much copied from my bootsector, which works perfectly fine, let me know if you have problems.

Posted: Sun Apr 13, 2008 10:33 am
by Ready4Dis
One more thing to note based on your post, make sure you are setting es = 0x7c0, different bios' can default to wherever they feel the need, it can either be: 7c0:0000, or 000:7c000, both of which are phyiscally the same, but 2 different ways of getting there, in my bootsector, I set ds,es,fs,gs to 0x0000 and set my origin to 0x7c00. You could do the opposite, and set ds,es,fs,gs to 0x7c0, then set your origin to 0x0000, both have the same effect, just make sure you set it manually, never assume :)

So, if you wanted to read using my function, you would..

Code: Select all

mov bx, 0x7c0
mov es, bx
mov bx, 0x200
mov cx, [SectorsToRead]
mov ax, [LBAToRead]
call ReadFloppy
This would read CX sectors from AX (LBA) to the address 0x7c00:0x0200.

Posted: Sun Apr 13, 2008 12:56 pm
by Altimicus
Thank you i just used your conversion function and it worked well

Posted: Sun Apr 13, 2008 1:12 pm
by Altimicus
Well now it doesnt try to read an out of range sector but it doesnt find the file... called kernel.bin? is the file name case sensitive?

EDIT: I think that transferring the boot sector with debug is messing up with someyhing because even a already working OS (MINIDOS) when i transfer it it doesnt find the file.....