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

📄 dsk.c

📁 DOS操作系统源代码,研究操作系统用. 包括了dos的所有源文件
💻 C
📖 第 1 页 / 共 2 页
字号:
}


COUNT
blk_driver (rqptr rp)
{
	if(rp -> r_unit >= nUnits && rp-> r_command != C_INIT)
		return failure(E_UNIT);
	if(rp -> r_command > NENTRY)
	{
		return failure(E_FAILURE);	/* general failure */
	}
	else
		return ((*dispatch[rp -> r_command])(rp));
}


static WORD
init (rqptr rp)
{
	COUNT HardDrive, Unit;

	/* Reset the drives						*/
	fl_reset();

        /* Initial number of disk units                                 */
	nUnits = 2;
        /* Initial number of DOS partitions                             */
        nPartitions = 0;

        /* Setup media info and BPBs arrays                             */
        for (Unit = 0; Unit < NDEV; Unit++)
        {
                miarray[Unit].mi_size = 720l;
                miarray[Unit].mi_heads = 2;
                miarray[Unit].mi_cyls = 40;
                miarray[Unit].mi_sectors = 9;
                miarray[Unit].mi_offset = 0l;
                miarray[Unit].mi_drive = Unit;

                bpbarray[Unit].bpb_nbyte = SEC_SIZE;
                bpbarray[Unit].bpb_nsector = 2;
                bpbarray[Unit].bpb_nreserved = 1;
                bpbarray[Unit].bpb_nfat = 2;
                bpbarray[Unit].bpb_ndirent = 112;
                bpbarray[Unit].bpb_nsize = 720l;
                bpbarray[Unit].bpb_mdesc = 0xfd;
                bpbarray[Unit].bpb_nfsect = 2;

                bpbptrs[Unit] = &bpbarray[Unit];
        };

	for(HardDrive = 0; HardDrive <= 0; HardDrive++) /* only one hard drive for now */
	{
                /* Process primary partition table                      */
                if (!processtable ((HardDrive | 0x80), 0, 0l, 1, 0l))
                   /* Exit if no hard drive                             */
                   break;
        };

	rp -> r_nunits = nUnits;
	rp -> r_bpbptr = bpbptrs;
        rp -> r_endaddr = device_end();
	return S_DONE;
}


static WORD
mediachk (rqptr rp)
{
	if(hd(miarray[rp -> r_unit].mi_drive))
		rp -> r_mcretcode = M_NOT_CHANGED;
	else
		rp -> r_mcretcode = tdelay((LONG)37) ? M_DONT_KNOW : M_NOT_CHANGED;
	return S_DONE;
}


static WORD
bldbpb (rqptr rp)
{
	REG retry = N_RETRY;
	ULONG count;
	byteptr trans;
	WORD local_word;

	if(hd(miarray[rp -> r_unit].mi_drive))
	{
                COUNT partidx = miarray[rp -> r_unit].mi_partidx;
		head = dos_partition[partidx].peBeginHead;
		sector = dos_partition[partidx].peBeginSector;
		track = dos_partition[partidx].peBeginCylinder;
	}
	else
	{
		head = 0;
		sector = 1;
		track = 0;
	}

	do
	{
		ret = fl_read((WORD)miarray[rp -> r_unit].mi_drive,
                      (WORD)head, (WORD)track, (WORD)sector, (WORD)1, (byteptr)&buffer);
	} while (ret != 0 && --retry > 0);
	if(ret != 0)
		return(dskerr(ret));

	getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NBYTE]), &bpbarray[rp -> r_unit].bpb_nbyte);
	getbyte(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NSECTOR]), &bpbarray[rp -> r_unit].bpb_nsector);
	getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NRESERVED]), &bpbarray[rp -> r_unit].bpb_nreserved);
	getbyte(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NFAT]), &bpbarray[rp -> r_unit].bpb_nfat);
	getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NDIRENT]), &bpbarray[rp -> r_unit].bpb_ndirent);
	getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NSIZE]), &bpbarray[rp -> r_unit].bpb_nsize);
	getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NSIZE]), &bpbarray[rp -> r_unit].bpb_nsize);
	getbyte(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_MDESC]), &bpbarray[rp -> r_unit].bpb_mdesc);
	getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NFSECT]), &bpbarray[rp -> r_unit].bpb_nfsect);
	getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NSECS]), &bpbarray[rp -> r_unit].bpb_nsecs);
	getword(&((((BYTE *)&buffer.bytes[BT_BPB]))[BPB_NHEADS]), &bpbarray[rp -> r_unit].bpb_nheads);
	getlong(&((((BYTE *)&buffer.bytes[BT_BPB])[BPB_HIDDEN])), &bpbarray[rp -> r_unit].bpb_hidden);
	getlong(&((((BYTE *)&buffer.bytes[BT_BPB])[BPB_HUGE])), &bpbarray[rp -> r_unit].bpb_huge);
#ifdef DSK_DEBUG
	printf("BPB_NBYTE     = %04x\n", bpbarray[rp -> r_unit].bpb_nbyte);
	printf("BPB_NSECTOR   = %02x\n", bpbarray[rp -> r_unit].bpb_nsector);
	printf("BPB_NRESERVED = %04x\n", bpbarray[rp -> r_unit].bpb_nreserved);
	printf("BPB_NFAT      = %02x\n", bpbarray[rp -> r_unit].bpb_nfat);
	printf("BPB_NDIRENT   = %04x\n", bpbarray[rp -> r_unit].bpb_ndirent);
	printf("BPB_NSIZE     = %04x\n", bpbarray[rp -> r_unit].bpb_nsize);
	printf("BPB_MDESC     = %02x\n", bpbarray[rp -> r_unit].bpb_mdesc);
	printf("BPB_NFSECT    = %04x\n", bpbarray[rp -> r_unit].bpb_nfsect);
#endif
	rp -> r_bpptr = &bpbarray[rp -> r_unit];
	count = miarray[rp -> r_unit].mi_size =
	 bpbarray[rp -> r_unit].bpb_nsize == 0 ?
	  bpbarray[rp -> r_unit].bpb_huge :
	  bpbarray[rp -> r_unit].bpb_nsize;
	getword((&(((BYTE *)&buffer.bytes[BT_BPB])[BPB_NHEADS])), &miarray[rp -> r_unit].mi_heads);
	head = miarray[rp -> r_unit].mi_heads;
	getword((&(((BYTE *)&buffer.bytes[BT_BPB])[BPB_NSECS])), &miarray[rp -> r_unit].mi_sectors);
	if(miarray[rp -> r_unit].mi_size == 0)
		getlong(&((((BYTE *)&buffer.bytes[BT_BPB])[BPB_HUGE])), &miarray[rp -> r_unit].mi_size);
	sector = miarray[rp -> r_unit].mi_sectors;
	if(head == 0 || sector == 0)
	{
		tmark();
		return failure(E_FAILURE);
	}
	miarray[rp -> r_unit].mi_cyls = count / (head * sector);
	tmark();
#ifdef DSK_DEBUG
	printf("BPB_NSECS     = %04x\n", sector);
	printf("BPB_NHEADS    = %04x\n", head);
	printf("BPB_HIDDEN    = %08lx\n", bpbarray[rp -> r_unit].bpb_hidden);
	printf("BPB_HUGE      = %08lx\n", bpbarray[rp -> r_unit].bpb_huge);
#endif
	return S_DONE;
}

static WORD 
blockio (rqptr rp)
{
	REG retry = N_RETRY, remaining;
	UWORD cmd, total;
	ULONG start;
	byteptr trans;

	cmd = rp -> r_command;
	total = 0;
	trans = rp -> r_trans;
	tmark();
	for
	(
		remaining = rp -> r_count,
		 start = (rp -> r_start != HUGECOUNT ? rp -> r_start : rp -> r_huge)
		  + miarray[rp -> r_unit].mi_offset;
		remaining > 0;
		remaining -= count, trans += count * SEC_SIZE, start += count
	)
	{
		if(ltop(&track, &sector, &head,  rp -> r_unit, 1, start, trans) != 1)
		{
/*			printf("split sector at 0x%lx", trans);*/
		}
		count = ltop(&track, &sector, &head,  rp -> r_unit, remaining, start, trans);
		total += count;
		do
		{
			switch(cmd)
			{
			case C_INPUT:
				ret = fl_read((WORD)miarray[rp -> r_unit].mi_drive, (WORD)head, (WORD)track, (WORD)sector, (WORD)count, trans);
				break;

			case C_OUTPUT:
			case C_OUTVFY:
				ret = fl_write((WORD)miarray[rp -> r_unit].mi_drive, (WORD)head, (WORD)track, (WORD)sector, (WORD)count, trans);
				break;

			default:
				return failure(E_FAILURE);
			}
		} while (ret != 0 && --retry > 0);
		if(ret != 0)
		{
			rp -> r_count = 0;
			return dskerr(ret);
		}
		if(cmd == C_OUTVFY)
		{
			ret = fl_verify((WORD)miarray[rp -> r_unit].mi_drive, (WORD)head, (WORD)track, (WORD)sector, (WORD)count, rp -> r_trans);
			if(ret != 0)
			{
				rp -> r_count = 0;
				return dskerr(ret);
			}
		}
	}
	rp -> r_count = total;
	return S_DONE;
}

static WORD
blk_error (rqptr rp)
{
	rp -> r_count = 0;
	return failure(E_FAILURE);	/* general failure */
}



static WORD
dskerr (COUNT code)
{
/*	printf("diskette error:\nhead = %d\ntrack = %d\nsector = %d\ncount = %d\n",
		head, track, sector, count);*/
	switch(code & 0x03)
	{
	case 1:		/* invalid command - general failure */
		if(code & 0x08)
			return(E_FAILURE);
		else
			return failure(E_CMD);

	case 2:		/* address mark not found - general  failure */
		return failure(E_FAILURE);

	case 3:		/* write protect */
		return failure(E_WRPRT);

	default:
		if(code & 0x80)		/* time-out */
			return failure(E_NOTRDY);
		else if(code & 0x40)	/* seek error */
			return failure(E_SEEK);
		else if(code & 0x10)	/* CRC error */
			return failure(E_CRC);
		else if(code & 0x04)
			return failure(E_NOTFND);
		else
			return failure(E_FAILURE);
	}
}

/*									*/
/* Do logical block number to physical head/track/sector mapping	*/
/*									*/
static COUNT
ltop (WORD *trackp, WORD *sectorp, WORD *headp, REG COUNT unit, COUNT count, LONG strt_sect, byteptr strt_addr)
{
#ifdef I86
	ULONG ltemp;
#endif
	REG ls, ps;

#ifdef I86
	/* Adjust for segmented architecture				*/
	ltemp = (((ULONG)mk_segment(strt_addr) << 4) + mk_offset(strt_addr)) & 0xffff;
	/* Test for 64K boundary crossing and return count large	*/
	/* enough not to exceed the threshold.				*/
	count = (((ltemp + SEC_SIZE * count) & 0xffff0000l) != 0l)
		? (0xffffl - ltemp) / SEC_SIZE
		: count;
#endif

	*trackp = strt_sect / (miarray[unit].mi_heads * miarray[unit].mi_sectors);
	*sectorp = strt_sect % miarray[unit].mi_sectors + 1;
	*headp = (strt_sect % (miarray[unit].mi_sectors * miarray[unit].mi_heads))
		/ miarray[unit].mi_sectors;
	if(((ls = *headp * miarray[unit].mi_sectors + *sectorp - 1) + count) >
		(ps = miarray[unit].mi_heads * miarray[unit].mi_sectors))
		count = ps - ls;
	return count;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -