⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsk.c

📁 用C语言实现的DOS操作系统的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************/
/*								*/
/*			      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 + -