/*

fat_dpb.c -- FATとDPBの操作関数

*/

#include<stdio.h>
#include<dos.h>
#include<ctype.h>
#include<farstr.h>
#include"dmove86.h"

int	getdpb(void)
{
	union REGS	regs;

	regs.h.ah = 0x32;
	regs.h.dl = Drive + 1;
	int86y(0x21,&regs,&regs);

	if	(regs.h.al == 0xff)
		return -1;

	Dpb = *(struct DPB far *)MK_FP(regs.x.ds, regs.x.bx);

	Fatsize = (Dpb.data_sec - Dpb.iplsectors
			- Dpb.root_entry/(Dpb.seclen >> 5)) / Dpb.fatnum;

	return 0;
}

unsigned short	huge	*getfat(void)
{
	unsigned int	af;
	unsigned int	pos;

	char	huge	*buf;

	buf = (char huge *)farmalloc((unsigned long)Dpb.seclen * Fatsize);

	if	(buf == NULL) 
		return NULL;

	for	(pos=0 ; pos<Fatsize ; pos++)
	{
		af = readabssec((void far *)(buf + (long)pos*Dpb.seclen),
						Dpb.iplsectors+pos,1,Drive);
		if	(af&0x100)
		{
			dm_errmes("\aFAT読み込みに失敗しました.");
			endscreen();
		}
	}

	if	(Dpb.maxclu < 0xff7)
	{	/* 12ビットFAT */

		unsigned short huge 	*fat;

		fat=(unsigned short huge *)farmalloc
				((Dpb.maxclu+2) * sizeof(unsigned short));

		if	(fat == NULL)
		{
			farfree(buf);
			return 0;
		}

		for	(pos=0 ; pos < Dpb.maxclu/2 ; pos++)
		{
			fat[pos*2  ] = buf[pos*3  ]+ (buf[pos*3+1]&0x0f) * 256;
			fat[pos*2+1] = buf[pos*3+1]/16	+ buf[pos*3+2]*16;

			if	(fat[pos*2  ] > 0xff6)	fat[pos*2  ] |= 0xf000;
			if	(fat[pos*2+1] > 0xff6)	fat[pos*2+1] |= 0xf000;
		}
		farfree(buf);
		return fat;
	}

	else 	return (unsigned short huge *)buf;
}
