Page 1 of 2
A Simple Read Sector Function
Posted: Fri Mar 12, 2004 8:46 am
by ich_will
Hi, i try to write a read sector function but it seems that it doesn't work.
Code: Select all
;----------------------------------------------;
;------------- read_sector --------------------;
;----------------------------------------------;
;------ es = buffer address -------------------;
;------ bx = buffer offset -------------------;
;------ cx = sector to read -------------------;
;------ dl = drive -------------------;
;----------------------------------------------;
;------ for 1.44MB Floppys 80 Sectors ---------;
;----------------------------------------------;
read_sector:
pusha
push bx ; save buffer offset
; compute the sector number: sector_number/sectors_per_track
mov ax, cx ; ax = sector number
mov bx, 18 ; bx = number of sectors per track
div bx ; al = ax / bx
mov cl, al ; cl = real sector number (cl is used by int 13)
; compute the head number: (sector_number/sector_per_track) just in ax mod number_of_heads
; and the track number: (sector_number/sector_per_track) / number_of_heads
xor ah, ah ; del the rest of the div before
mov bx, 2 ; bx = number of heads
div bx ; ah = rest of ( ax / bx ), al = ax / bx
mov ch, al ; ch = number of track
mov dh, ah ; dh = the head number (dh is used by int 13)
pop bx ; restore the buffer offset
mov ax, cx ; save cx in ax
mov cx, 5 ; try to read the sector 5 times ;!!! overwrite the num of track and num of sec
read_sector_next_try:
pusha
mov cx, ax ; restore cx
mov ah, 0x02 ; function number 2 (read from disk)
mov al, 0x01 ; number of sectors to read
int 0x13
jnc load_ok ; if all is ok return
popa
loop read_sector_next_try; else try once again if there is an error
jmp error ; if cx = 0 and the read operation always failed, halt
load_ok:
popa
popa
ret
Re:A Simple Read Sector Function
Posted: Fri Mar 12, 2004 8:56 am
by Pype.Clicker
don't quote me on this, but iirc, div *x was using dx:ax as input, dx as remainder and ax as quotient. That's div *l and div *h that use ax as source and put quotient/remainder in al/ah respectively ...
i should better check my ASM manual again ...
Re:A Simple Read Sector Function
Posted: Fri Mar 12, 2004 9:05 am
by ich_will
From the Book
PC Assembly Language
Paul A. Carter
December 12, 2002
div source
If the source is 8-bit, then AX is divided by the operand. The quotient is stored in AL and the remainder in AH. If the source is 16-bit, then DX:AX is divided by the operand. The quotient is stored into AX and remainder into DX. If the source is 32-bit, then EDX:EAX is divided by the operand and the quotient is stored into EAX and the remainder into EDX.
Re:A Simple Read Sector Function
Posted: Fri Mar 12, 2004 11:40 am
by Pype.Clicker
so
Code: Select all
mov bx, 2 ; bx = number of heads
div bx ; ah = rest of ( ax / bx ), al = ax / bx
mov ch, al ; ch = number of track
mov dh, ah ; dh = the head number (dh is used by int 13)
is likely to be wrong. I guess it should be "div bl" so that ch receives ax/2 and dh receives ax%2. Note that a shift and an "and" could have brought the same result ...
Re:A Simple Read Sector Function
Posted: Fri Mar 12, 2004 12:09 pm
by Neo
heres my lab 2 chs function (got from someone here iirc)
Code: Select all
trans_address:
; _________________________________________________________________
;/Translates Logical sector in AX to Physical sector,head,cylinder \
;Input:- the LBA address in the AX reg *
;Output:- cl=sector,ch=cylinder,dh=head *
;Formula:- *
; HPC = Number of heads/cylinder *
; SPT = sectors/track *
; Cylinder = (LBA / SPT) / HPC *
; Head = (LBA / SPT) mod HPC *
; Sector = (LBA mod SPT) + 1 *
; Registers Affected:- AX,CX,DX *
;------------------------------------------------------*
xor dx,dx ; clear out DX reg *
div word [SECTS_PER_TRK] ; divide AX by SPT *
inc dl ; increment dl to get sector address *
mov cl,dl ; get sector value *
xor dx,dx ; clear DX reg *
div word [HEADS] ; *
mov ch,al ; get cylinder value *
mov dh,dl ; get head value *
retn ; all values obtained now *
;\_______________________________________________/
the HEADS and SECTS_PER_TRK have to be the correct values you need (usually 2 and 18 resply). HTH
Re:A Simple Read Sector Function
Posted: Sat Mar 13, 2004 10:47 am
by ich_will
Writen by Pipe.Clicker:
so
Code:
mov bx, 2 ; bx = number of heads
div bx ; ah = rest of ( ax / bx ), al = ax / bx
mov ch, al ; ch = number of track
mov dh, ah ; dh = the head number (dh is used by int 13)
is likely to be wrong. I guess it should be "div bl" so that ch receives ax/2 and dh receives ax%2. Note that a shift and an "and" could have brought the same result ...
I don't how you come to this idea, the same thing is made with my current operation, i think. (See above post pasted from the am book)
I think my function does the same as the function from neo.
Re:A Simple Read Sector Function
Posted: Sat Mar 13, 2004 11:18 am
by Candy
ich_will wrote:
Writen by Pipe.Clicker:
so
Code:
mov bx, 2 ; bx = number of heads
div bx ; ah = rest of ( ax / bx ), al = ax / bx
mov ch, al ; ch = number of track
mov dh, ah ; dh = the head number (dh is used by int 13)
is likely to be wrong. I guess it should be "div bl" so that ch receives ax/2 and dh receives ax%2. Note that a shift and an "and" could have brought the same result ...
I don't how you come to this idea, the same thing is made with my current operation, i think. (See above post pasted from the am book)
I think my function does the same as the function from neo.
No you do NOT divide ax by bx, you divide dx:ax by bx (thus using your head count & your drive) and get completely the wrong result. ax contains a part of your result, as well as dx (which is now overwritten). You have much to learn my young padwan...
Search the intel manuals.
Re:A Simple Read Sector Function
Posted: Sat Mar 13, 2004 3:05 pm
by ASHLEY4
Clicker and Candy are right ,But im not shore it is the problem,it all depends on the numbers.
eg test code.
Code: Select all
pushad
mov ax, 72 ;cx ; ax = sector number
mov dx,0x00
mov bx, 18 ; bx = number of sectors per track
div bl ; al = ax / bx
mov cl, al ; cl = real sector number (cl is used by int 13)
; compute the head number: (sector_number/sector_per_track) just in ax mod number_of_heads
; and the track number: (sector_number/sector_per_track) / number_of_heads
xor ah, ah ; del the rest of the div before
call write_hex32
mov bx, 2 ; bx = number of heads
div bl ; ah = rest of ( ax / bx ), al = ax / bx
call write_hex32
mov ax,dx
call write_hex32
popad
;--------------------------------------------------------------
mov ax, 72 ;cx ; ax = sector number
mov dx,0x00
mov bx, 18 ; bx = number of sectors per track
div bx ; al = ax / bx
mov cl, al ; cl = real sector number (cl is used by int 13)
; compute the head number: (sector_number/sector_per_track) just in ax mod number_of_heads
; and the track number: (sector_number/sector_per_track) / number_of_heads
xor ah, ah ; del the rest of the div before
call write_hex32
mov bx, 2 ; bx = number of heads
div bx ; ah = rest of ( ax / bx ), al = ax / bx
call write_hex32
mov ax,dx
call write_hex32
nogo:
jmp nogo
The reg dup are
With BL
1) call write_hex32 AX = 4
2) call write_hex32 AX = 2
3) call write_hex32 DX = 0
With bx
1) call write_hex32 AX = 4
2) call write_hex32 AX = 2
3) call write_hex32 DX = 0
On some numbers if i used bx i got Div error from my OS,
So you both (Clicker & Candy) are right, but i do not think its the problem
ASHLEY4.
Re:A Simple Read Sector Function
Posted: Sun Mar 14, 2004 6:48 am
by ich_will
You have much to learn my young padwan...
You don't know how right you're with young
,
OK know I change the two div instructions so they use ax (div bl), now the function reads all sectors I think (before it jumps to error) but the in the buffer address nothing is filled in. I've to search more.
Re:A Simple Read Sector Function
Posted: Sun Mar 14, 2004 7:29 am
by ich_will
Ok, i got it.
There was a little mistake at the begging of the function:
; compute the sector number: sector_number/sectors_per_track ; <-- mistake (sector_number%sector_per_track) + 1 is correct
mov ax, cx ; ax = sector number
mov bx, 18 ; bx = number of sectors per track
div bl ; al = ax / bx
mov cl, al ; <-- mistake
correct:
mov cl, ah
add cl, 1
Re:A Simple Read Sector Function
Posted: Mon Mar 15, 2004 4:39 am
by Pype.Clicker
ASHLEY4 wrote:
Clicker and Candy are right ,But im not shore it is the problem,it all depends on the numbers.
eg test code.
irrelevant test
. 72 is a multiple of 18, so of course, as the remainder is null, it will not affect further computations ... but you of course wish a readsector routine that can read more than sectors that are at n*18 positions, don't you ?
Re:A Simple Read Sector Function
Posted: Mon Mar 15, 2004 5:13 am
by Candy
Pype.Clicker wrote:
ASHLEY4 wrote:
Clicker and Candy are right ,But im not shore it is the problem,it all depends on the numbers.
eg test code.
irrelevant test
. 72 is a multiple of 18, so of course, as the remainder is null, it will not affect further computations ... but you of course wish a readsector routine that can read more than sectors that are at n*18 positions, don't you ?
* and only on the first head on floppy disk 0
Re:A Simple Read Sector Function
Posted: Mon Mar 15, 2004 10:33 am
by ASHLEY4
Did you not read my opening line ??,
ASHLEY4 wrote:
Clicker and Candy are right ,But im not shore it is the problem,it all depends on the numbers.
The bit were it say's"it all depends on the numbers".
And i was proven right YOU was wrong, it still did not work after the modification .
Whether it worked after the modification plus adding the one, is all to do with the numbers that you feed it .
ASHLEY4. >:(
Re:A Simple Read Sector Function
Posted: Mon Mar 15, 2004 10:54 am
by Pype.Clicker
well, i did read it and /dev/brain output a blinking red 'WARNING' stuff when decoding "depends on the numbers" completed. Saying that a computing algorithm's result will be correct or not "depending on the numbers" just means the algorithm is flawed to me. A good algorithm will give good results whatever the input are or report an error if the computation cannot be applied to those inputs.
On some numbers if i used bx i got Div error from my OS,
A 'division overflow' (INT 00) will be reported by the CPU when the quotient of a division doesn't fit the register. Let's say you try to divide by 18 (using BX), you may end with a value up to 17 in DX.
Next time you'll try to divide by 2 (still using BX), you're actually trying to divide dx*65536+ax by 2 ... if this value is larger than 65535 (and it certainly will be if DX>1), the DIV operation cannot be achieved by the CPU and a divide overflow is thrown.
and i was proven right YOU ...
i do not pretend to have *solved* the problem ich_will is facing as i do not have all the information required to do so. I found weird stuff, i reported it and explained why i think it's not "safe hex".
And you haven't proved the patch is wrong: you just highlighted one specific case where the bug does not appear in the buggy code.
No offense to be taken
Re:A Simple Read Sector Function
Posted: Mon Mar 15, 2004 11:51 am
by ASHLEY4
I still do not think that you read what i put,
I said that you are right, that he had made a mistake.
It should of been bl not bx, but he was asking why it was not working.
And i said that it depende's on the numbers, not that you should keep it with bx in the hope that you put the right numbers in,i said that you may have to look els wear which he did.
By saying that you are right, to me means that he needs to change that .
PS. You may want to look up the differance between signed and unsigned data .
ASHLEY4.