Ejemplo n.º 1
0
STDMETHODIMP CDisk::lread(IGeometry *g, long lsect, VARIANT *var)
{
	DSK_GEOMETRY geom;
	dsk_err_t err;
	HRESULT hr;

	g_to_dg(g, &geom);
	unsigned char *tmpbuf = (unsigned char *)dsk_malloc(geom.dg_secsize);
	if (!tmpbuf) return MapError(DSK_ERR_NOMEM);
	
	err = dsk_lread(m_driver, &geom, tmpbuf, lsect);
	hr = PutBuffer(tmpbuf, var, geom.dg_secsize, err);
	dsk_free(tmpbuf);
	return hr;
}
Ejemplo n.º 2
0
LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_lcheck(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
	                          const void *buf, dsk_lsect_t sector)
{
	void *buf2;
	dsk_err_t e;

	if (!self || !geom || !buf || !self->dr_class) return DSK_ERR_BADPTR;

	buf2 = dsk_malloc(geom->dg_secsize);
	if (!buf2) return DSK_ERR_NOMEM;

	e = dsk_lread(self,geom,buf2,sector);
	if (e == 0 && memcmp(buf, buf2, geom->dg_secsize)) e = DSK_ERR_MISMATCH;
	dsk_free(buf2);
	return e;   
}
Ejemplo n.º 3
0
/* Probe the geometry of a disc. This will always use the boot sector. */
dsk_err_t dsk_defgetgeom(DSK_DRIVER *self, DSK_GEOMETRY *geom)
{
	DSK_FORMAT secid;
	dsk_err_t e;
	unsigned char *secbuf;
	unsigned long dsksize;
	dsk_rate_t oldrate;

        if (!self || !geom || !self->dr_class) return DSK_ERR_BADPTR;

	memset(geom, 0, sizeof(*geom));

	/* Switch to a minimal format */
	e = dg_stdformat(geom, FMT_180K, NULL, NULL);
	if (e) return e;
	/* Allocate buffer for boot sector (512 bytes) */
	secbuf = dsk_malloc(geom->dg_secsize);
	if (!secbuf) return DSK_ERR_NOMEM;


	/* Check for CPC6128 type discs. Also probe the data rate; if we get a 
	 * missing address mark, then the data rate is wrong.
	 */ 
	e = dg_stdformat(geom, FMT_180K, NULL, NULL);
	if (e) return e;
	e = dsk_lsecid(self, geom, 0, &secid);
	/* Check for HD discs */
	if (e == DSK_ERR_NOADDR)
	{
		geom->dg_datarate = RATE_HD;
		e = dsk_lsecid(self, geom, 0, &secid);
	}
	/* Check for DD 5.25" disc in HD 5.25" drive */
	if (e == DSK_ERR_NOADDR)
	{
		geom->dg_datarate = RATE_DD;
		e = dsk_lsecid(self, geom, 0, &secid);
	}
	/* Check for BBC micro DFS discs (FM encoded) */
	if (e == DSK_ERR_NOADDR)
	{
		e = dg_stdformat(geom, FMT_BBC100, NULL, NULL);
		if (!e) e = dsk_lsecid(self, geom, 0, &secid);
	}
	if (!e)	/* We could get the sector ID */
	{
		if ((secid.fmt_sector & 0xF0) == 0x10 &&
		     secid.fmt_secsize == 512) 	/* Ampro 40 track double sided */
		{
			dsk_free(secbuf);
			e = dg_stdformat(geom, FMT_AMPRO400D, NULL, NULL);
			if (!e) set_fixed_fs(self, FMT_AMPRO400D);
			return e;
		}
		if ((secid.fmt_sector & 0xC0) == 0x40 &&
		     secid.fmt_secsize == 512) 	/* CPC system */
		{
			dsk_free(secbuf);
			e = dg_stdformat(geom, FMT_CPCSYS, NULL, NULL);
			if (!e) set_pcw_fs(self, geom, boot_cpcsys);
			return e;
		}
		if ((secid.fmt_sector & 0xC0) == 0xC0 &&
		     secid.fmt_secsize == 512)	/* CPC data */
		{
			dsk_free(secbuf);
			e = dg_stdformat(geom, FMT_CPCDATA, NULL, NULL);
			if (!e) set_pcw_fs(self, geom, boot_cpcdata);
			return e;
		}
		/* [v0.6.0] Handle discs with non-512 byte sectors */
		if (secid.fmt_secsize == 256)
		{
			if (geom->dg_fm)	/* BBC Micro FM floppy */
			{
				unsigned int tot_sectors;
				e = dsk_lread(self, geom, secbuf, 1);

				tot_sectors = secbuf[7] + 256 * (secbuf[6] & 3);
			
/* If disc is FM recorded but does not have 400 or 800 sectors, fail. */	
				if (e == DSK_ERR_OK && tot_sectors != 400 && tot_sectors != 800) e = DSK_ERR_BADFMT; 

				geom->dg_cylinders = tot_sectors / (geom->dg_heads * geom->dg_sectors);	
				dsk_free(secbuf);
				return e;
			}
			else	/* MFM */
			{
				e = dg_stdformat(geom, FMT_ACORN160, NULL, NULL);
				if (!e) e = dsk_lread(self, geom, secbuf, 0);
				if (e)
				{
					dsk_free(secbuf);
					return DSK_ERR_BADFMT;
				}
				/* Acorn ADFS discs have a size in sectors at 0xFC in the
				 * first sector */
				dsksize = secbuf[0xFC] + 256 * secbuf[0xFD] +
					65536L * secbuf[0xFE];
				dsk_free(secbuf);
				if (dsksize ==  640) return dg_stdformat(geom, FMT_ACORN160, NULL, NULL);
				if (dsksize == 1280) return dg_stdformat(geom, FMT_ACORN320, NULL, NULL);
				if (dsksize == 2560) return dg_stdformat(geom, FMT_ACORN640, NULL, NULL);
				/* The DOS Plus boot floppy has 2720 here for
				 * some reason */
				if (dsksize == 2720) return dg_stdformat(geom, FMT_ACORN640, NULL, NULL);
				return DSK_ERR_BADFMT;
			}
		}
		if (secid.fmt_secsize == 1024)
		{
			dsk_rate_t rate;
			/* Ampro 80 track double sided */
			if ((secid.fmt_sector & 0xF0) == 0x10)
			{
				dsk_free(secbuf);
				e = dg_stdformat(geom, FMT_AMPRO800, NULL, NULL);
				if (!e) set_fixed_fs(self, FMT_AMPRO800);
				return e;	
			}
			/* Save the data rate, which we know to be correct */
			rate = geom->dg_datarate;

			dsk_free(secbuf);
			/* Switch to a format with 1k sectors */
			if (geom->dg_datarate == RATE_HD)
				e = dg_stdformat(geom, FMT_ACORN1600, NULL, NULL);	
			else	e = dg_stdformat(geom, FMT_ACORN800, NULL, NULL);
			if (e) return e;
			/* And restore it. */
			geom->dg_datarate = rate;
			/* Allocate buffer for boot sector (1k bytes) */
			secbuf = dsk_malloc(geom->dg_secsize);
			if (!secbuf) return DSK_ERR_NOMEM;
			e = dsk_lread(self, geom, secbuf, 0);
			if (!e)
			{
				dsksize = secbuf[0xFC] + 256 * secbuf[0xFD] +
					65536L * secbuf[0xFE];
				/* Check for 1600k-format */
				if (geom->dg_datarate == RATE_HD)
				{
				/* XXX Need a better check for Acorn 1600k */
					dsk_free(secbuf);
					return DSK_ERR_OK;
				}
				/* Check for D-format magic */
				if (dsksize == 3200) 
				{
					dsk_free(secbuf);
					return DSK_ERR_OK;
				}
				/* Check for E-format magic */
				if (secbuf[4] == 10 && secbuf[5] == 5 &&
				    secbuf[6] == 2  && secbuf[7] == 2)
				{
					dsk_free(secbuf);
					return DSK_ERR_OK;
				}
			}
			/* Check for DOS Plus magic. DOS Plus has sectors
			 * based at 1, not 0. */
			geom->dg_secbase = 1;
			e = dsk_lread(self, geom, secbuf, 0);
			if (!e)
			{
				if (secbuf[0] == 0xFD && 
				    secbuf[1] == 0xFF && 
				    secbuf[2] == 0xFF)
				{
					dsk_free(secbuf);
					return DSK_ERR_OK;
				}
			}
			dsk_free(secbuf);
			return DSK_ERR_BADFMT;
		}	
		/* Can't handle other discs with non-512 sector sizes. */
		if ((secid.fmt_secsize != 512))
		{
			dsk_free(secbuf);
			return DSK_ERR_BADFMT;
		}
	}
	/* If the driver couldn't do a READ ID call, then ignore it */
	if (e == DSK_ERR_NOTIMPL) e = DSK_ERR_OK;
	/* Try to ID the disc from its boot sector */
	if (!e) e = dsk_lread(self, geom, secbuf, 0);
	if (e) 
	{ 	
		dsk_free(secbuf);
		return e; 
	}

	/* Save the data rate, because what we have is right, and what's
	 * in the sector might not be. */
	oldrate = geom->dg_datarate;	
	/* We have the sector. Let's try to guess what it is */
	e = dg_dosgeom(geom, secbuf);	
	if (e == DSK_ERR_OK)
	{
		set_dos_fs(self, geom, secbuf + 11);
	}
	if (e == DSK_ERR_BADFMT)
	{
/* If dg_pcwgeom succeeded, we have a CP/M filesystem with known parameters */
		e = dg_pcwgeom(geom, secbuf);
		if (e == DSK_ERR_OK)
	   		set_pcw_fs(self, geom, secbuf);
	}
	if (e == DSK_ERR_BADFMT) 
	{
		e = dg_aprigeom(geom, secbuf);
		if (e == DSK_ERR_OK)
		{
			set_dos_fs(self, geom, secbuf + 80);
		}
	}
	if (e == DSK_ERR_BADFMT) 
	{
		e = dg_cpm86geom(geom, secbuf);
		if (e == DSK_ERR_OK)
			set_cpm86_fs(self, geom, secbuf);
	}
/* Check for Oups Discovery 1 */
	if (e == DSK_ERR_BADFMT) 
	{
		e = dg_opusgeom(geom, secbuf);
/*		if (e == DSK_ERR_OK)
			set_opus_fs(self, geom, secbuf); */
	}
	geom->dg_datarate = oldrate;
	
	dsk_free(secbuf);
	return e;
}
Ejemplo n.º 4
0
int do_test(char *outfile, char *outtyp, char *outcomp, int forcehead)
{
	DSK_PDRIVER outdr = NULL;
	dsk_err_t e;
	DSK_GEOMETRY dg, dg2;
	static DSK_FORMAT fmt[9] =
		{
			{ 0, 0, 1, 512 },
			{ 0, 0, 3, 512 },
			{ 3, 1, 5, 512 },
			{ 0, 0, 7, 512 },
			{ 0, 0, 9, 512 },
			{ 0, 1, 2, 512 },
			{ 0, 0, 4, 512 },
			{ 2, 0, 6, 512 },
			{ 0, 0, 8, 512 },
		};
	static DSK_FORMAT fmt2[9] =
		{
			{ 4, 0, 1, 512 },
			{ 4, 0, 3, 512 },
			{ 4, 0, 5, 512 },
			{ 4, 0, 7, 512 },
			{ 4, 0, 9, 512 },
			{ 4, 0, 2, 512 },
			{ 4, 0, 4, 512 },
			{ 4, 0, 6, 512 },
			{ 4, 0, 8, 512 },
		};
	DSK_FORMAT secid, *pfmt;
	char *comment;
	unsigned char status;
	dsk_psect_t count, n;
	char *optname;
	int value;

	dsk_reportfunc_set(report, report_end);	
	dg_stdformat(&dg, FMT_180K, NULL, NULL);
	if (t80) dg.dg_cylinders = 80;

	printf("Checking dsk_creat\n");
	e = dsk_creat(&outdr, outfile, outtyp, outcomp);
	CHECKERR("dsk_creat")
	else
	{
		dsk_set_option(outdr, "REMOTE:TESTING", 1);
		printf("Checking set_comment\n");
		e = dsk_set_comment(outdr, "Example comment");
		CHECKERR3("dsk_set_comment");
		printf("Checking pformat\n");
		e = dsk_pformat(outdr, &dg, 0, 0, fmt, 0xE5);
		CHECKERR("dsk_pformat")
		printf("Checking apform\n");
		e = dsk_apform(outdr, &dg, 1, 0, 0xF6);
		CHECKERR("dsk_apform")
		printf("Checking lformat\n");
		e = dsk_lformat(outdr, &dg, 2, fmt2, 0xD4);
		CHECKERR("dsk_pformat")
		printf("Checking ptrackids\n");
		e = dsk_ptrackids(outdr, &dg, 0, 0, &count, &pfmt);
		CHECKERR("dsk_ptrackids")
		else
		{
			dsk_psect_t n;
			printf("Cyl Head Sec Size\n");
			printf("-----------------\n");
			for (n = 0; n < count; n++)
			{
				printf("%3d  %3d %3d %4d\n",
					pfmt[n].fmt_cylinder,
					pfmt[n].fmt_head,
					pfmt[n].fmt_sector,
					(int)pfmt[n].fmt_secsize);
			}
			printf("-----------------\n");
			dsk_free(pfmt);
		}
		memset(secbuf,       0, sizeof(secbuf));
		memcpy(secbuf, spec180, sizeof(spec180));
		printf("Checking dsk_lwrite\n");
		e = dsk_lwrite(outdr, &dg, secbuf, 0);
		CHECKERR("dsk_lwrite")
		strcpy((char *)secbuf, "Cyl=3 Head=1 Sec=5");
		printf("Checking dsk_xwrite\n");
		e = dsk_xwrite(outdr, &dg, secbuf, 0, 0, 3, 1, 5, 512, 0);
		CHECKERR("dsk_xwrite")
		printf("Checking dsk_psecid\n");
		e = dsk_psecid(outdr, &dg, 1, 0, &secid);
		CHECKERR("dsk_psecid")
		else
		{
			printf("%3d  %3d %3d %4d\n",
				secid.fmt_cylinder,
				secid.fmt_head,
				secid.fmt_sector,
				(int)secid.fmt_secsize);
			if (secid.fmt_cylinder != 1 || secid.fmt_head != 0 ||
			    secid.fmt_secsize != 512) 
			{
				++failures;
				printf("-- mismatch!\n");
			}
		}
	}	
	if (outdr) 
	{
		dsk_close(&outdr);
		CHECKERR("dsk_close")
	}
	printf("Checking dsk_open\n");
	e = dsk_open(&outdr, outfile, outtyp, outcomp);
	CHECKERR("dsk_open")
	else
	{
		dsk_set_option(outdr, "REMOTE:TESTING", 1);
		printf("Checking dsk_getgeom\n");
		e = dsk_getgeom(outdr, &dg2);
		if (t80 && dg2.dg_cylinders == 40) dg2.dg_cylinders = 80;
		CHECKERR("dsk_getgeom")
		else if (memcmp(&dg, &dg2, sizeof(dg)))
		{
			++failures;
			printf("-- mismatch!\n");
			printf("Cyls:  %3d %3d\n", dg.dg_cylinders, dg2.dg_cylinders);
			printf("Heads: %3d %3d\n", dg.dg_heads, dg2.dg_heads);
			printf("Secs:  %3d %3d\n", dg.dg_sectors, dg2.dg_sectors);
		}
		printf("Checking dsk_lread\n");
		e = dsk_lread(outdr, &dg, secbuf, 0);
		CHECKERR("dsk_lread")
		else if (memcmp(secbuf, spec180, sizeof(spec180)))
		{
			++failures;
			printf("-- mismatch!\n");
		}
		printf("Checking dsk_xread\n");
		e = dsk_xread(outdr, &dg, secbuf, 0, 0, 3, 1, 5, 512, NULL);
		CHECKERR("dsk_xread")
		else if (strcmp((char *)secbuf, "Cyl=3 Head=1 Sec=5"))
		{
			++failures;
			printf("-- mismatch!\n");
		}
		printf("Checking dsk_lseek\n");
		e = dsk_lseek(outdr, &dg, 1);
		CHECKERR("dsk_lseek")
		printf("Checking dsk_drive_status\n");
		e = dsk_drive_status(outdr, &dg, 0, &status);
		CHECKERR("dsk_drive_status")
		else printf("-- status=0x%02x\n", status);

		printf("Checking dsk_tread\n");
		e = dsk_ptread(outdr, &dg, trkbuf, 1, 0);
		CHECKERR("dsk_ptread")
		else
		{
			for (n = 0; n < 4608; n++) if (trkbuf[n] != 0xF6)
			{
				printf("-- mismatch!\n");
				++failures;
				break;
			}
	
		}
		printf("Checking dsk_xtread\n");
		e = dsk_xtread(outdr, &dg, trkbuf, 2, 0, 4, 0);
		CHECKERR("dsk_xtread")
		else
		{
			for (n = 0; n < 4608; n++) if (trkbuf[n] != 0xD4)
			{
				printf("-- mismatch!\n");
				++failures;
				break;
			}
		}
		printf("Checking dsk_option_enum\n");
		e = dsk_option_enum(outdr, 0, &optname);
		CHECKERR("dsk_option_enum")
		else
		{
			printf("-- first option is %s\n", optname);
		}
		if (!optname) optname = "dummy";
		printf("Checking dsk_get_option(%s)\n", optname);
		e = dsk_get_option(outdr, optname, &value);
		CHECKERR2("dsk_get_option")
		else
		{
			printf("-- value=%d\n", value);
		}
		printf("Checking dsk_set_option(example, 2)\n");
		e = dsk_set_option(outdr, "example", 2);
		CHECKERR2("dsk_set_option")
		printf("Checking dsk_rtread\n");
		e = dsk_rtread(outdr, &dg, trkbuf, 0, 0, 0);
		CHECKERR3("dsk_rtread")
		printf("Checking dsk_get_comment\n");
		e = dsk_get_comment(outdr, &comment);
		CHECKERR3("dsk_get_comment")
		else if (comment) printf("-- comment=%s\n", comment);
	}
	if (outdr) 
	{
		dsk_close(&outdr);
		CHECKERR("dsk_close")
	}
	printf("\n");
	printf("Failed calls (failure important):   %2d\n", failures);
	printf("Failed calls (failure unimportant): %2d\n", warnings);
	printf("Unimplemented functions:            %2d\n", unimpl);
	printf("Unimplemented functions over RPC:   %2d\n", rpcunimp);
	return failures;
}