FreeDOS/tests/absread/absread.c

209 lines
4.4 KiB
C

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
typedef unsigned long uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
void die(char *msg)
{
printf("%s\n", msg);
exit(1);
}
/* Both traditional DOS and FAT32 DOS return this structure, but
FAT32 return a lot more data, so make sure we have plenty of space */
struct deviceparams {
uint8_t specfunc;
uint8_t devtype;
uint16_t devattr;
uint16_t cylinders;
uint8_t mediatype;
uint16_t bytespersec;
uint8_t secperclust;
uint16_t ressectors;
uint8_t fats;
uint16_t rootdirents;
uint16_t sectors;
uint8_t media;
uint16_t fatsecs;
uint16_t secpertrack;
uint16_t heads;
uint32_t hiddensecs;
uint32_t hugesectors;
uint8_t lotsofpadding[224];
};
void get_partition_offset(int drive)
{
static struct deviceparams dp;
int err=0;
printf("Getting drive info: int21h function 440Dh subfunction 0860h\n");
dp.specfunc = 1; /* Get current information */
__asm {
mov ax, 0x440d
mov bx, drive
mov cx, 0x0860
mov dx, offset dp
int 0x21
mov ax, 0
adc ax, 0
mov err, ax
}
if (!err)
{
printf("Partition Offset = %02lXh [c=%02u,h=%02u,s=%2u]\n", dp.hiddensecs, dp.cylinders, dp.heads, dp.secpertrack);
printf("FAT32 version 4860h to compare\n");
}
else
printf("Original version failed, checking FAT32 version using 4860h\n");
__asm {
mov ax, 0x440d
mov bx, drive
mov cx, 0x4860
mov dx, offset dp
int 0x21
mov ax, 0
adc ax, 0
mov err, ax
}
if (!err)
{
printf("Partition Offset = %02lXh\n", dp.hiddensecs);
return;
}
else
printf("FAT32 version failed.\n");
}
struct rwblock {
uint8_t special;
uint16_t head;
uint16_t cylinder;
uint16_t firstsector;
uint16_t sectors;
uint16_t bufferoffset;
uint16_t bufferseg;
};
static struct rwblock mbr = {
.special = 0,
.head = 0,
.cylinder = 0, /* 5265, 3fh */
.firstsector = 0, /* MS-DOS, unlike the BIOS, zero-base sectors */
.sectors = 1,
.bufferoffset = 0,
.bufferseg = 0
};
void read_mbr(int drive, const void *buf)
{
uint8_t err=0;
uint16_t ds_seg=0;
//printf("read_mbr(%c:,%p)", 'a'+drive-1, buf);
mbr.bufferoffset = (unsigned short)buf;
__asm {
push ds
pop ax
mov ds_seg, ax
}
mbr.bufferseg = ds_seg;
//printf("DS = %04Xh\n", ds_seg);
__asm {
mov ax, 0x440d
mov bx, drive
mov cx, 0x0861
mov dx, offset mbr
int 0x21
mov ax, 0
adc ax, 0
mov err, al
}
if (!err) {
//printf("Success reading MBR\n\n");
return;
}
__asm {
mov ax, 0x440d
mov bx, drive
mov cx, 0x4861
mov dx, offset mbr
int 0x21
mov ax, 0
adc ax, 0
mov err, al
}
if (!err) {
//printf("Success reading FAT32 MBR\n\n");
return;
}
printf("mbr read error");
}
int main(int argc, char *argv[])
{
unsigned int c,h,s;
static uint8_t buf[1024];
unsigned drive = (unsigned)(argv[1][0]); /* a=1,b=2,... */
drive = drive-'a'+1;
printf("Query drive %c:\n", 'a'+drive-1);
get_partition_offset(drive);
read_mbr(drive, buf);
printf("MBR: %02Xh %02Xh %02Xh %02Xh %02Xh %02Xh %02Xh %02Xh\n",
((const uint8_t *)buf)[0],
((const uint8_t *)buf)[1],
((const uint8_t *)buf)[2],
((const uint8_t *)buf)[3],
((const uint8_t *)buf)[4],
((const uint8_t *)buf)[5],
((const uint8_t *)buf)[6],
((const uint8_t *)buf)[7]);
printf("Finding drive\n");
for (c = 1024; c <= 5265; c++) {
for (h = 0; h < 255; h++)
for (s = 0; s <= 63; s++)
{
mbr.cylinder = c;
mbr.head =h;
mbr.sectors=s;
read_mbr(drive, buf);
if (buf[0] != 0) {
printf("Found at %u,%u,%u\n", c,h,s);
printf("MBR: %02Xh %02Xh %02Xh %02Xh %02Xh %02Xh %02Xh %02Xh\n",
((const uint8_t *)buf)[0],
((const uint8_t *)buf)[1],
((const uint8_t *)buf)[2],
((const uint8_t *)buf)[3],
((const uint8_t *)buf)[4],
((const uint8_t *)buf)[5],
((const uint8_t *)buf)[6],
((const uint8_t *)buf)[7]);
exit(0);
}
}
printf("c=%u,", c); fflush(NULL);
}
return 0;
}