Hi All,
I am currently trying to write a program that can read individual sectors on a floppy disk using C. I am building the program to run in a 16-bit DOS environment using the Digital Mars compiler with the 16bit DOS add-on. So far I know how to access the individual sectors but what I want to do is then extract the data and put it into a file. I think that the way to do this will be to use malloc to provide the space to put the data into from the registers but I am getting confused as to how to get this data into there in the start (wether to use a struct or what) and also how to output the data and in what form (%c, %d, etc.).
If you could offer any advice it would be greatly appreciated.
Dinklebaga

Recommended Answers

All 4 Replies

Hi All,
I am getting confused as to how to get this data into there in the start (wether to use a struct or what) and also how to output the data and in what form (%c, %d, etc.).
If you could offer any advice it would be greatly appreciated.
Dinklebaga

For reading a sector, simply you should define a buffer such as

char buff[512];

then use "%X" to print the hex format.

Hi xitrum,
I decided to go down a different route using malloc to allocate it a section of memory of 512 or multiples of depending on how many sectors i wanted to read and then allocating this pointer to the es register (where the memory location for the sector to be read into usually goes) and so far it isn't kicking out an coding error during compilation but when I am trying to simply print this section of memory out using the pointer as reference the results are not what I am expecting. Below is the code that i have so far:

#include <dos.h>
#include <stdio.h>

/* reads a given sector on the cylinder, head and drive (cyl, hd & dr)*/

read_sector(cyl, hd, dr)
char cyl, hd, dr;
{
    int status;
    int *memsectptr;
    int *tempptr;
    int sectorsize = 512;
    int noofsectors = 1;
    int i;
    char buff[512];
    *memsectptr = malloc(sectorsize); /*open 512 bytes of data in memory to read in sector */
    tempptr = memsectptr;
    _AH = 0x02; /* read sectors instead of verify command */
    _AL = noofsectors; /* read one sector only */
    _CH = cyl;
    _CL = 1; /* starts at sector 1*/
    _DH = hd;
    _DL = dr;
    //_BX = 0x00; /* no offset for data to be stored */
    ES:_BX = *memsectptr; /*Add memory location in to read data to */
    geninterrupt(0x13);
    for(i=0; i<(sectorsize * noofsectors); i++)
    {
        printf("%X", memsectptr);
    }
    free(memsectptr);
    status = _AH;
    return(status);
}

/* takes the status code returned by verify track and prints message associated with it */

pr_error(error)
int error;
{
    switch(error)
    {
        case 0x01:
            printf("Invalid Command\n");
            break;
        case 0x02:
            printf("Address Mark Not Found\n");
            break;
        case 0x03:
            printf("Disk Write Protected\n");
            break;
        case 0x04:
            printf("Sector Not Found\n");
            break;
        case 0x05:
            printf("Reset Failed\n");
            break;
        case 0x06:
            printf("Floppy Disk Removed\n");
            break;
        case 0x08:
            printf("DMA Overrun\n");
            break;
        case 0x09:
            printf("DMA Crossed 64k Boundary\n");
            break;
        case 0x0C:
            printf("Media Type Not Found\n");
            break;
        case 0x10:
            printf("CRC Error\n");
            break;
        case 0x20:
            printf("Controller Failed\n");
            break;
        case 0x40:
            printf("Seek Failed\n");
            break;
        case 0x80:
            printf("\n status %d\n", error);
    }
}

/* main calls verify_track for all values of cyl (0-79) and both values for head (0-1). If function succeeds it returns 0
otherwise it returns the relevant error code to printf and terminates program.*/

main()
{
    int status = 0;
    char head, cylinder;
    char drive = 0;
    head = 0;
    cylinder = 0;
    status = read_sector(cylinder, head, drive);
    if( status != 0)
    {
        printf("\nError at head %d, cylinder %02d :", head, cylinder);
        pr_error(status);
    }
    else
    {
        printf("\nOperation completed successfully. See output\n");
    }


}

Thanks, Dinklebaga

hix you got some mistakes in C pointer programming.
1/ You declared a pointer variable and allocated it by using *memsectptr ????

int *memsectptr;
 *memsectptr = malloc(sectorsize); 
....
ES:_BX = *memsectptr;

the code should be

int *memsectptr;
memsectptr = malloc(sectorsize);
....
ES:_BX = memsectptr;

and the following code will print data in a sector

for(i=0; i<(sectorsize * noofsectors); i++)
{
    printf("%X", *(memsectptr+i));
}

xitrum

hix you got some mistakes in C pointer programming.
1/ You declared a pointer variable and allocated it by using *memsectptr ????

int *memsectptr;
 *memsectptr = malloc(sectorsize); 
....
ES:_BX = *memsectptr;

the code should be

int *memsectptr;
memsectptr = malloc(sectorsize);
....
ES:_BX = memsectptr;

xitrum

Thanks for your help with this xitrum. Unfortunately with this first bit which you told me was incorrectly referenced, when I remove the * from in front of the pointers i receive the error "Error: need explicit cast to convert from int to int*, or in the case of the second: to convert from int* to short volatile. Forgive me for being naiive but I don't understand the differences/consequences of leaving the * in place as they are kicking out an error?

Also when running the code with the *'s in place with the second modification I am receiving a better output (characters are now different from the first) but ur seems to me just to be an illogical memory dump making me think that possibly the program isn't actually reading the sector into memory in the first place?

Thanks,
Dinklebaga

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.