📄 dsk.c
字号:
/****************************************************************/
/* */
/* dsk.c */
/* */
/* Copyright (c) 1995 */
/* Pasquale J. Villani */
/* All Rights Reserved */
/* */
/* This file is part of DOS-C. */
/* */
/* DOS-C is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License */
/* as published by the Free Software Foundation; either version */
/* 2, or (at your option) any later version. */
/* */
/* DOS-C is distributed in the hope that it will be useful, but */
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
/* the GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public */
/* License along with DOS-C; see the file COPYING. If not, */
/* write to the Free Software Foundation, 675 Mass Ave, */
/* Cambridge, MA 02139, USA. */
/****************************************************************/
#include "../../hdr/portab.h"
#include "globals.h"
/* $Logfile: C:/dos-c/src/kernel/dsk.c_v $ */
#ifdef VERSION_STRINGS
static BYTE *dskRcsId = "$Header: C:/dos-c/src/kernel/dsk.c_v 1.6 04 Jan 1998 23:15:16 patv $";
#endif
/* $Log: C:/dos-c/src/kernel/dsk.c_v $
*
* Rev 1.6 04 Jan 1998 23:15:16 patv
* Changed Log for strip utility
*
* Rev 1.5 10 Jan 1997 5:41:48 patv
* Modified for extended partition support
*
* Rev 1.4 29 May 1996 21:03:32 patv
* bug fixes for v0.91a
*
* Rev 1.3 19 Feb 1996 3:21:36 patv
* Added NLS, int2f and config.sys processing
*
* Rev 1.2 01 Sep 1995 17:54:18 patv
* First GPL release.
*
* Rev 1.1 30 Jul 1995 20:52:00 patv
* Eliminated version strings in ipl
*
* Rev 1.0 02 Jul 1995 8:32:42 patv
* Initial revision.
*/
/* $EndLog$ */
#ifdef PROTO
BOOL fl_reset(VOID);
COUNT fl_rd_status(WORD);
COUNT fl_read(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
COUNT fl_write(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
BOOL fl_verify(WORD, WORD, WORD, WORD, WORD, BYTE FAR *);
BOOL fl_format(WORD, BYTE FAR *);
#else
BOOL fl_reset();
COUNT fl_rd_status();
COUNT fl_read();
COUNT fl_write();
BOOL fl_verify();
BOOL fl_format();
#endif
#define NDEV 8 /* only one for demo */
#define SEC_SIZE 512 /* size of sector in bytes */
#define N_RETRY 5 /* number of retries permitted */
#define NENTRY 25 /* total size of dispatch table */
union
{
BYTE bytes[2 * SEC_SIZE];
boot boot_sector;
} buffer;
static struct media_info
{
ULONG mi_size; /* physical sector count */
UWORD mi_heads; /* number of heads (sides) */
UWORD mi_cyls; /* number of cyl/drive */
UWORD mi_sectors; /* number of sectors/cyl */
ULONG mi_offset; /* relative partition offset */
BYTE mi_drive; /* BIOS drive number */
COUNT mi_partidx; /* Index to partition array */
};
static struct media_info miarray[NDEV]; /* Internal media info structs */
static bpb bpbarray[NDEV]; /* BIOS parameter blocks */
static bpb *bpbptrs[NDEV]; /* pointers to bpbs */
#define N_PART 4 /* number of partitions per
table partition */
static WORD head, track, sector, ret; /* globals for blockio */
static WORD count;
static COUNT nUnits; /* number of returned units */
static COUNT nPartitions; /* number of DOS partitions */
#define PARTOFF 0x1be
static struct
{
BYTE peDrive; /* BIOS drive number */
BYTE peBootable;
BYTE peBeginHead;
BYTE peBeginSector;
UWORD peBeginCylinder;
BYTE peFileSystem;
BYTE peEndHead;
BYTE peEndSector;
UWORD peEndCylinder;
LONG peStartSector;
LONG peSectors;
LONG peAbsStart; /* Absolute sector start */
} dos_partition[NDEV - 2];
#ifdef PROTO
WORD init(rqptr), mediachk(rqptr), bldbpb(rqptr), blockio(rqptr), blk_error(rqptr);
COUNT ltop(WORD *, WORD *, WORD *, COUNT, COUNT, LONG, byteptr);
WORD dskerr(COUNT);
COUNT processtable(COUNT ptDrive, BYTE ptHead, UWORD ptCylinder, BYTE ptSector, LONG ptAccuOff);
#else
WORD init(), mediachk(), bldbpb(), blockio(), blk_error();
WORD dskerr();
COUNT processtable();
#endif
/* */
/* the function dispatch table */
/* */
#ifdef PROTO
static WORD (*dispatch[NENTRY]) (rqptr) =
#else
static WORD (*dispatch[NENTRY]) () =
#endif
{
init, /* Initialize */
mediachk, /* Media Check */
bldbpb, /* Build BPB */
blk_error, /* Ioctl In */
blockio, /* Input (Read) */
blk_error, /* Non-destructive Read */
blk_error, /* Input Status */
blk_error, /* Input Flush */
blockio, /* Output (Write) */
blockio, /* Output with verify */
blk_error, /* Output Status */
blk_error, /* Output Flush */
blk_error, /* Ioctl Out */
blk_error, /* Device Open */
blk_error, /* Device Close */
blk_error, /* Removable Media */
blk_error, /* Output till busy */
blk_error, /* undefined */
blk_error, /* undefined */
blk_error, /* Generic Ioctl */
blk_error, /* undefined */
blk_error, /* undefined */
blk_error, /* undefined */
blk_error, /* Get Logical Device */
blk_error /* Set Logical Device */
};
#define SIZEOF_PARTENT 16
#define FAT12 0x01
#define FAT16SMALL 0x04
#define EXTENDED 0x05
#define FAT16LARGE 0x06
#define hd(x) ((x) & 0x80)
COUNT
processtable (COUNT ptDrive, BYTE ptHead, UWORD ptCylinder,
BYTE ptSector, LONG ptAccuOff)
{
struct /* Temporary partition table */
{
BYTE peBootable;
BYTE peBeginHead;
BYTE peBeginSector;
UWORD peBeginCylinder;
BYTE peFileSystem;
BYTE peEndHead;
BYTE peEndSector;
UWORD peEndCylinder;
LONG peStartSector;
LONG peSectors;
} temp_part[N_PART];
REG retry = N_RETRY;
UBYTE packed_byte, pb1;
COUNT Part;
/* Read partition table */
do
{
ret = fl_read ((WORD)ptDrive, (WORD)ptHead, (WORD)ptCylinder,
(WORD)ptSector, (WORD)1, (byteptr)&buffer);
} while (ret != 0 && --retry > 0);
if(ret != 0)
return FALSE;
/* Read each partition into temporary array */
for (Part = 0; Part < N_PART; Part++)
{
REG BYTE *p =
(BYTE *)&buffer.bytes[PARTOFF + (Part * SIZEOF_PARTENT)];
getbyte((VOID *)p, &temp_part[Part].peBootable);
++p;
getbyte((VOID *)p, &temp_part[Part].peBeginHead);
++p;
getbyte((VOID *)p, &packed_byte);
temp_part[Part].peBeginSector = packed_byte & 0x3f;
++p;
getbyte((VOID *)p, &pb1);
++p;
temp_part[Part].peBeginCylinder = pb1 + ((UWORD)(0xc0 & packed_byte) << 2);
getbyte((VOID *)p, &temp_part[Part].peFileSystem);
++p;
getbyte((VOID *)p, &temp_part[Part].peEndHead);
++p;
getbyte((VOID *)p, &packed_byte);
temp_part[Part].peEndSector = packed_byte & 0x3f;
++p;
getbyte((VOID *)p, &pb1);
++p;
temp_part[Part].peEndCylinder = pb1 + ((UWORD)(0xc0 & packed_byte) << 2);
getlong((VOID *)p, &temp_part[Part].peStartSector);
p += sizeof(LONG);
getlong((VOID *)p, &temp_part[Part].peSectors);
};
/* Walk through the table, add DOS partitions to global
array and process extended partitions */
for (Part = 0; Part < N_PART && nUnits < NDEV; Part++)
{
if (temp_part[Part].peFileSystem == FAT12 ||
temp_part[Part].peFileSystem == FAT16SMALL ||
temp_part[Part].peFileSystem == FAT16LARGE)
{
miarray[nUnits].mi_offset =
temp_part[Part].peStartSector + ptAccuOff;
miarray[nUnits].mi_drive = ptDrive;
miarray[nUnits].mi_partidx = nPartitions;
nUnits++;
dos_partition[nPartitions].peDrive = ptDrive;
dos_partition[nPartitions].peBootable =
temp_part[Part].peBootable;
dos_partition[nPartitions].peBeginHead =
temp_part[Part].peBeginHead;
dos_partition[nPartitions].peBeginSector =
temp_part[Part].peBeginSector;
dos_partition[nPartitions].peBeginCylinder =
temp_part[Part].peBeginCylinder;
dos_partition[nPartitions].peFileSystem =
temp_part[Part].peFileSystem;
dos_partition[nPartitions].peEndHead =
temp_part[Part].peEndHead;
dos_partition[nPartitions].peEndSector =
temp_part[Part].peEndSector;
dos_partition[nPartitions].peEndCylinder =
temp_part[Part].peEndCylinder;
dos_partition[nPartitions].peStartSector =
temp_part[Part].peStartSector;
dos_partition[nPartitions].peSectors =
temp_part[Part].peSectors;
dos_partition[nPartitions].peAbsStart =
temp_part[Part].peStartSector + ptAccuOff;
nPartitions++;
}
else if (temp_part[Part].peFileSystem == EXTENDED)
{
/* call again to process extended part table */
processtable (ptDrive,
temp_part[Part].peBeginHead,
temp_part[Part].peBeginCylinder,
temp_part[Part].peBeginSector,
temp_part[Part].peStartSector + ptAccuOff);
};
};
return TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -