correct sectors/track, head and hidden sector values if the boot sector

disagrees with the default bpb (unless the default bpb says that the
number of hidden sectors is zero (usual for floppies)).

introduce generic_block_ioctl() function to handle all 0x440d ioctls
(inclusive locking)


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@763 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2004-01-31 15:01:40 +00:00
parent 2b9e17a680
commit e7f0852dbd

View File

@ -29,7 +29,7 @@
#define DEBUG #define DEBUG
/* #define DDEBUG */ /* #define DDEBUG */
#define SYS_VERSION "v3.0" #define SYS_VERSION "v3.1"
#include <stdlib.h> #include <stdlib.h>
#include <dos.h> #include <dos.h>
@ -471,28 +471,20 @@ void reset_drive(int DosDrive);
parm [dx] \ parm [dx] \
modify [ax bx]; modify [ax bx];
void lock_drive(int DosDrive);
#pragma aux lock_drive = \
"mov ax,0x440d" \
"mov cx,0x84a" \
"xor dx,dx" \
"inc bx" \
"int 0x21" \
parm [bx];
void unlock_drive(int DosDrive);
#pragma aux unlock_drive = \
"mov ax,0x440d" \
"mov cx,0x86a" \
"inc bx" \
"int 0x21" \
parm [bx];
void truename(char far *dest, const char *src); void truename(char far *dest, const char *src);
#pragma aux truename = \ #pragma aux truename = \
"mov ah,0x60" \ "mov ah,0x60" \
"int 0x21" \ "int 0x21" \
parm [es di] [si]; parm [es di] [si];
int generic_block_ioctl(unsigned char drive, unsigned cx, unsigned char *par);
#pragma aux generic_block_ioctl = \
"mov ax, 0x440d" \
"int 0x21" \
"sbb ax, ax" \
value [ax] \
parm [bl] [cx] [dx];
#else #else
#ifndef __TURBOC__ #ifndef __TURBOC__
@ -543,26 +535,17 @@ void reset_drive(int DosDrive)
intdos(&regs, &regs); intdos(&regs, &regs);
} /* reset_drive */ } /* reset_drive */
void lock_drive(int DosDrive) int generic_block_ioctl(unsigned char drive, unsigned cx, unsigned char *par)
{ {
union REGS regs; union REGS regs;
regs.x.ax = 0x440d; regs.x.ax = 0x440d;
regs.x.cx = 0x84a; regs.x.cx = cx;
regs.x.dx = 0; regs.x.dx = (unsigned)par;
regs.h.bl = DosDrive + 1; regs.h.bl = drive + 1;
intdos(&regs, &regs); intdos(&regs, &regs);
} /* lock_drive */ return regs.x.cflag;
} /* generic_block_ioctl */
void unlock_drive(int DosDrive)
{
union REGS regs;
regs.x.ax = 0x440d;
regs.x.cx = 0x86a;
regs.h.bl = DosDrive + 1;
intdos(&regs, &regs);
} /* unlock_drive */
void truename(char *dest, const char *src) void truename(char *dest, const char *src)
{ {
@ -669,6 +652,26 @@ BOOL haveLBA(void)
} }
#endif #endif
void correct_bpb(struct bootsectortype *default_bpb,
struct bootsectortype *oldboot)
{
/* don't touch partitions (floppies most likely) that don't have hidden
sectors */
if (default_bpb->bsHiddenSecs == 0)
return;
#ifdef DEBUG
printf("Old boot sector values: sectors/track: %u, heads: %u, hidden: %lu\n",
oldboot->bsSecPerTrack, oldboot->bsHeads, oldboot->bsHiddenSecs);
printf("Default and new boot sector values: sectors/track: %u, heads: %u, "
"hidden: %lu\n", default_bpb->bsSecPerTrack, default_bpb->bsHeads,
default_bpb->bsHiddenSecs);
#endif
oldboot->bsSecPerTrack = default_bpb->bsSecPerTrack;
oldboot->bsHeads = default_bpb->bsHeads;
oldboot->bsHiddenSecs = default_bpb->bsHiddenSecs;
}
void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both) void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both)
{ {
#ifdef WITHFAT32 #ifdef WITHFAT32
@ -676,12 +679,15 @@ void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both
#endif #endif
struct bootsectortype *bs; struct bootsectortype *bs;
static unsigned char oldboot[SEC_SIZE], newboot[SEC_SIZE]; static unsigned char oldboot[SEC_SIZE], newboot[SEC_SIZE];
static unsigned char default_bpb[0x5c];
#ifdef DEBUG #ifdef DEBUG
printf("Reading old bootsector from drive %c:\n", drive + 'A'); printf("Reading old bootsector from drive %c:\n", drive + 'A');
#endif #endif
lock_drive(drive); /* lock drive */
generic_block_ioctl((unsigned char)drive + 1, 0x84a, NULL);
reset_drive(drive); reset_drive(drive);
/* suggestion: allow reading from a boot sector or image file here */ /* suggestion: allow reading from a boot sector or image file here */
if (MyAbsReadWrite(drive, 1, 0, oldboot, 0) != 0) if (MyAbsReadWrite(drive, 1, 0, oldboot, 0) != 0)
@ -728,9 +734,21 @@ void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both
exit(1); /* Japan?! */ exit(1); /* Japan?! */
} }
/* bit 0 set if function to use current BPB, clear if Device
BIOS Parameter Block field contains new default BPB
bit 1 set if function to use track layout fields only
must be clear if CL=60h
bit 2 set if all sectors in track same size (should be set) (RBIL) */
default_bpb[0] = 4;
if (fs == FAT32) if (fs == FAT32)
{ {
printf("FAT type: FAT32\n"); printf("FAT type: FAT32\n");
/* get default bpb (but not for floppies) */
if (drive >= 2 &&
generic_block_ioctl((unsigned char)drive + 1, 0x4860, default_bpb) == 0)
correct_bpb((struct bootsectortype *)(default_bpb + 7 - 11), bs);
#ifdef WITHFAT32 /* copy one of the FAT32 boot sectors */ #ifdef WITHFAT32 /* copy one of the FAT32 boot sectors */
memcpy(newboot, haveLBA() ? fat32lba : fat32chs, SEC_SIZE); memcpy(newboot, haveLBA() ? fat32lba : fat32chs, SEC_SIZE);
#else #else
@ -742,6 +760,9 @@ void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both
else else
{ /* copy the FAT12/16 CHS+LBA boot sector */ { /* copy the FAT12/16 CHS+LBA boot sector */
printf("FAT type: FAT1%c\n", fs + '0' - 10); printf("FAT type: FAT1%c\n", fs + '0' - 10);
if (drive >= 2 &&
generic_block_ioctl((unsigned char)drive + 1, 0x860, default_bpb) == 0)
correct_bpb((struct bootsectortype *)(default_bpb + 7 - 11), bs);
memcpy(newboot, fs == FAT16 ? fat16com : fat12com, SEC_SIZE); memcpy(newboot, fs == FAT16 ? fat16com : fat12com, SEC_SIZE);
} }
@ -864,7 +885,9 @@ void put_boot(int drive, char *bsFile, char *kernel_name, int load_seg, int both
close(fd); close(fd);
} /* if write boot sector file */ } /* if write boot sector file */
reset_drive(drive); reset_drive(drive);
unlock_drive(drive);
/* unlock_drive */
generic_block_ioctl((unsigned char)drive + 1, 0x86a, NULL);
} /* put_boot */ } /* put_boot */