issue with int 0x13

Programming, for all ages and all languages.
Armature
Member
Member
Posts: 33
Joined: Wed Apr 25, 2018 2:44 pm
Libera.chat IRC: idk

issue with int 0x13

Post by Armature »

At this point in time, I have successfully written a FAT12 boot loader that can successfully load into memory the FAT12 FS, find the kernel on disk and load that into memory and then jump to the executing point of the kernel. I then started work on a disk driver for the kernel. An incredibly rudimentary one using the 0x13 interrupt. The kernel, from what. I can gather, successfully loads finds the File in the root director, retrieves the cluster number of said file, converts it to LBA and then calls for the data to be read from disk. It is at this point the carry flag is set, and the value 0x01 is placed in AH indicating. an invalid command. I have searched through this piece of code for days, Heres the code:

Code: Select all

ReadDisk:
	pusha
	clc			;0000) Clear the carry flag just in case set which would flag this as failing
	mov ax, 0xF000		;0000) Test location, needs to be changed when the kernel is finished
	mov es, ax		;0000) Test location, needs to be changed when the kernel is finished
	mov si, CylinderSector
	mov word cx, [si]
	mov si, Head
	mov dh, [si]
	xor dl, dl
	mov al, 0x01
	mov bx, 0xE000		;0000) [0xF000:0xE000 | 0xFE000]Test location needs to be changed when the kernel is finished
	mov ah, 0x02
	int 0x13
	jc DiskError
    mov al, 0x01        ;0000) Returns one which indicates the  operationw as a success
    mov di, DskStatus
    stosb
	popa
	ret
DiskError:
	mov si, DSKERR
	call WriteString
	xor al, al
	mov al, ah
	call WriteHex
	mov si, LINEEND
	call WriteString
	mov di, DskStatus
	mov al, 0x00
	stosb
	popa
	ret
Am I just being incredibly stupid and the fault be in plain sight? Any help would be greatly appreciated
User avatar
iansjack
Member
Member
Posts: 4686
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: issue with int 0x13

Post by iansjack »

You appear to be trying to write the sector to the BIOS ROM (()xFE000).
Armature
Member
Member
Posts: 33
Joined: Wed Apr 25, 2018 2:44 pm
Libera.chat IRC: idk

Re: issue with int 0x13

Post by Armature »

iansjack wrote:You appear to be trying to write the sector to the BIOS ROM (()xFE000).
I have rectified the mistake but I am still getting the same outcome.
User avatar
iansjack
Member
Member
Posts: 4686
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: issue with int 0x13

Post by iansjack »

Next you should check that your values for head, cylinder, and sector are reasonable. Running under a debugger with a breakpoint just before the interrupt will let you see what values are in the registers.
Armature
Member
Member
Posts: 33
Joined: Wed Apr 25, 2018 2:44 pm
Libera.chat IRC: idk

Re: issue with int 0x13

Post by Armature »

iansjack wrote:Next you should check that your values for head, cylinder, and sector are reasonable. Running under a debugger with a breakpoint just before the interrupt will let you see what values are in the registers.
Right, so I think I found the issue but not sure. So I printed the registers used to read the disk to the screen and got these values:

AX - 0x0201 - 0x02 in AH for the reading of said disk and 0x01 in AL for the number of sectors to read, all good
BX - 0xE000 - the offset of the memory location to write to
ES - 0x0000 - the segment
DX - 0x0000 - 0x00 in DH which indicates which head to use on the disk, 0x00 in DL which indicates the boot drive
CX - 0x003A - This is where I think the issue is. This written in binary is 0000000000111010. The first ten bits are zero, which is the first cylinder and the last six is the actual sector number, which in this case converts to the 58th sector on the disk. This can't be correct. After doing some research I believe the last sector on a track is sector 28, or 27 in the register. Am assuming this is what the issue is. Am I correct?
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: issue with int 0x13

Post by Octocontrabass »

Armature wrote:0x00 in DL which indicates the boot drive
0x00 in DL indicates the first floppy disk drive. It may or may not be the boot drive.
Armature wrote:CX - 0x003A - This is where I think the issue is. This written in binary is 0000000000111010. The first ten bits are zero, which is the first cylinder and the last six is the actual sector number, which in this case converts to the 58th sector on the disk. This can't be correct. After doing some research I believe the last sector on a track is sector 28, or 27 in the register. Am assuming this is what the issue is. Am I correct?
It depends on the geometry of your disk. A typical 1.44MB floppy disk has the geometry (80,2,18) which would mean there are 18 sectors on a track and the last sector is number 18. (Unlike LBA, cylinders, or heads, there is no sector 0.)
User avatar
iansjack
Member
Member
Posts: 4686
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: issue with int 0x13

Post by iansjack »

It depends upon what type of disk you are using, but the maximum number of sectors per track for PC floppy disks is 36. So I think there must be an error in your routine for calculating these values. The actual value for sectors per track is stored in the boot sector.
Armature
Member
Member
Posts: 33
Joined: Wed Apr 25, 2018 2:44 pm
Libera.chat IRC: idk

Re: issue with int 0x13

Post by Armature »

Octocontrabass wrote:
Armature wrote:0x00 in DL which indicates the boot drive
0x00 in DL indicates the first floppy disk drive. It may or may not be the boot drive.
Armature wrote:CX - 0x003A - This is where I think the issue is. This written in binary is 0000000000111010. The first ten bits are zero, which is the first cylinder and the last six is the actual sector number, which in this case converts to the 58th sector on the disk. This can't be correct. After doing some research I believe the last sector on a track is sector 28, or 27 in the register. Am assuming this is what the issue is. Am I correct?
It depends on the geometry of your disk. A typical 1.44MB floppy disk has the geometry (80,2,18) which would mean there are 18 sectors on a track and the last sector is number 18. (Unlike LBA, cylinders, or heads, there is no sector 0.)
At this point in time I'm using a 1.44MB floppy image formatted with FAT12. im going to check to see what went wrong in my LBA to CHS calculation
Armature
Member
Member
Posts: 33
Joined: Wed Apr 25, 2018 2:44 pm
Libera.chat IRC: idk

Re: issue with int 0x13

Post by Armature »

iansjack wrote:It depends upon what type of disk you are using, but the maximum number of sectors per track for PC floppy disks is 36. So I think there must be an error in your routine for calculating these values. The actual value for sectors per track is stored in the boot sector.
Right so I just checked the calculations and I don't think they're wrong, but once again I could be wrong However I did check the value I was getting from the Root Directory. I got a value of 0x1A00, which in decimal is cluster 6656. I think I should actually be getting a sector value of 0x001A which would be 26. Am I correct in this assumption? im assuming I've just forgotten about the whole little endian thing
Armature
Member
Member
Posts: 33
Joined: Wed Apr 25, 2018 2:44 pm
Libera.chat IRC: idk

Re: issue with int 0x13

Post by Armature »

Armature wrote:
iansjack wrote:It depends upon what type of disk you are using, but the maximum number of sectors per track for PC floppy disks is 36. So I think there must be an error in your routine for calculating these values. The actual value for sectors per track is stored in the boot sector.
Right so I just checked the calculations and I don't think they're wrong, but once again I could be wrong However I did check the value I was getting from the Root Directory. I got a value of 0x1A00, which in decimal is cluster 6656. I think I should actually be getting a sector value of 0x001A which would be 26. Am I correct in this assumption? im assuming I've just forgotten about the whole little endian thing
Actually no, that didn't seem to fix anything. instead of sector 58 I get 32. which is better I guess
User avatar
iansjack
Member
Member
Posts: 4686
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: issue with int 0x13

Post by iansjack »

This link: http://pcrepairclass.tripod.com/cgi-bin ... tochs.html gives you the formula for converting LBA to CHS. Try the conversion by hand, bearing in mind that your disk has 2 heads, 80 tracks and 18 sectors per track. Also remember that the clusters start from the beginning of the data area whereas the LBA starts from the beginning of the disk.

Alternatively, you could use LBA by calling int 13h with ah=42h (Extended read sectors from disk).
Armature
Member
Member
Posts: 33
Joined: Wed Apr 25, 2018 2:44 pm
Libera.chat IRC: idk

Re: issue with int 0x13

Post by Armature »

Right, its been a while, university work sort of piled up quickly. I've had a few moments to breathe so I thought id get back to this. I've re-written the code for the LBA to CHS conversion but its still not working. I've narrowed it down to two possible issues. The first being the code that converts the LBA and the second being an incorrect value from reading the RootDirectory or FAT. I'm hoping its the conversion that's wrong. This is the code I'm using right now:

Code: Select all

pusha			;0050)Preserve all the registers by moving them to the stack
	mov si, NxtSect		;0051)Set the source index to the memory location of the next LBA
	mov ax, FIHPT		;0052)
	mov bx, FISPT		;0053)
	mul bx			;0054)
	mov bx, ax		;0055)
	lodsw			;0056)
	div bx			;0057)
	mov di, CylinderTMP	;0058)
	stosw			;0059) the lower ten bits of AX is the cylinder the data is stored on
	mov ax, dx		;0060) take the remainder from the divide operation and store it in ax
	mov bx, FISPT		;0061) 
	div bx			;0062)
	mov di, Head		;0062)
	stosb			;00064)AL should be the head of the disk.
	inc dx
	mov ax, dx
	mov di, SectorTMP
	mov si, CylinderTMP
	xor ax, ax
	xor bx, bx
	lodsw
	mov word ax, [si]
	shr ax, 6
	mov di, SectorTMP
	mov bx, ax
	lodsw
	shr ax, 10
	shl ax, 10
	or ax, bx
	mov si, CylinderSector
	stosw
	popa
	ret
Yes I know its incredible in-efficient, but I wanna get the actual code working before I start optimising. The values being used, such as FISPT are:

Code: Select all

;1.44MB Floppy Information 3.5-=-=-=-=-=
FIBPS equ 0x0200			;0000) The number of bytes in each sector
FISPC equ 0x01				;0000) The number of sectors that exists with in a cluster
FIRE equ 0x00E0				;0000) The total number of root director ientries
FIMT equ 0xF0				;0000) The type of media being read
FISPF equ 0x0009			;0000) The number of sectors that makes up the FAT
FISPT equ 0x0012			;0000) The number of sectors on each track
FIHPT equ 0x0002			;0000) The number of heads on the disk
Is there anything obliviously wrong that I'm missing. I've gone through ti several times even noting it down with pen and paper and yet it still doesn't work. After the conversion I. get the values:

AX = 0x0201
BX = 0xE000
CX = 0x0000
DX = 0x3900
ES = 0x0000

The disk I'm using is a 1.44mb floppy disk formatted with FAT12. Any help would be great because this is driving me crazy.
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: issue with int 0x13

Post by BenLunt »

Armature wrote:
iansjack wrote:It depends upon what type of disk you are using, but the maximum number of sectors per track for PC floppy disks is 36. So I think there must be an error in your routine for calculating these values. The actual value for sectors per track is stored in the boot sector.
Right so I just checked the calculations and I don't think they're wrong, but once again I could be wrong However I did check the value I was getting from the Root Directory. I got a value of 0x1A00, which in decimal is cluster 6656. I think I should actually be getting a sector value of 0x001A which would be 26. Am I correct in this assumption? im assuming I've just forgotten about the whole little endian thing
Just real quick, the problem may not be with the LBA to CHS conversion, nor the actual read routine. It probably is with the original source location. For example, on a 1.44Meg disk with 80 cylinders, 2 heads, and 18 sectors per track, you can't have more than 2880 sectors. Therefore, how do you calculate a cluster of 6656? With a 1:1 ratio of clusters to sectors, you cannot have a cluster number above 2882. Have a look at your code to calculate where the root directory is. I think the 6656 is the indication of where the error might be.

With this in mind, on a FAT12 floppy, you don't have a cluster number for the root. You have to figure it out yourself. There are so many sectors for the boot (normally 1, but indicated in the BPB), one or more FAT's, each of a size specified in the BPB, and the the root following that. Here is a common layout:

Code: Select all

Sectors       Item
   1      Boot Code
   9      First FAT
   9      Second FAT
  14      Root
 2847      Data sectors/clusters
FAT32 file systems give you a cluster number for the root, not FAT12 or FAT16 file systems.

Ben
- http://www.fysnet.net/osdesign_book_series.htm
Armature
Member
Member
Posts: 33
Joined: Wed Apr 25, 2018 2:44 pm
Libera.chat IRC: idk

Re: issue with int 0x13

Post by Armature »

BenLunt wrote:
Armature wrote:
iansjack wrote:It depends upon what type of disk you are using, but the maximum number of sectors per track for PC floppy disks is 36. So I think there must be an error in your routine for calculating these values. The actual value for sectors per track is stored in the boot sector.
Right so I just checked the calculations and I don't think they're wrong, but once again I could be wrong However I did check the value I was getting from the Root Directory. I got a value of 0x1A00, which in decimal is cluster 6656. I think I should actually be getting a sector value of 0x001A which would be 26. Am I correct in this assumption? im assuming I've just forgotten about the whole little endian thing
Just real quick, the problem may not be with the LBA to CHS conversion, nor the actual read routine. It probably is with the original source location. For example, on a 1.44Meg disk with 80 cylinders, 2 heads, and 18 sectors per track, you can't have more than 2880 sectors. Therefore, how do you calculate a cluster of 6656? With a 1:1 ratio of clusters to sectors, you cannot have a cluster number above 2882. Have a look at your code to calculate where the root directory is. I think the 6656 is the indication of where the error might be.

With this in mind, on a FAT12 floppy, you don't have a cluster number for the root. You have to figure it out yourself. There are so many sectors for the boot (normally 1, but indicated in the BPB), one or more FAT's, each of a size specified in the BPB, and the the root following that. Here is a common layout:

Code: Select all

Sectors       Item
   1      Boot Code
   9      First FAT
   9      Second FAT
  14      Root
 2847      Data sectors/clusters
FAT32 file systems give you a cluster number for the root, not FAT12 or FAT16 file systems.

Ben
- http://www.fysnet.net/osdesign_book_series.htm
I've already loaded both the FAT and root Directory into a memory location. I'm not searching for that. I'm searching for a file that's on the disk. As for the value I was getting from the root directory, I said I think I'm getting the wrong one. I think its meant to be 0x001A which would be sector 26
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: issue with int 0x13

Post by Octocontrabass »

Armature wrote:Is there anything obliviously wrong that I'm missing.
Yes.

When you use the DIV instruction with a 16-bit operand for the divisor, the implied operand for the dividend is a 32-bit value, with the low bits in AX and the high bits in DX. Since you want to use a 16-bit dividend, you need to zero-extend the value to 32 bits by setting DX to 0 before division.

Similarly, the MUL instruction with a 16-bit operand places the 32-bit product in DX:AX. Some clever optimizations are possible if you know the product will always be a value that sets DX to zero.

And since I don't see it in any of the code you've posted so far, make sure you've cleared (or set) the direction flag before you use string instructions. It's not safe to assume the BIOS will always clear it for you.
Post Reply