예제 #1
0
dsk_err_t linux_format(DSK_DRIVER *self, DSK_GEOMETRY *geom,
                                dsk_pcyl_t cylinder, dsk_phead_t head,
                                const DSK_FORMAT *format, unsigned char filler)
{
	struct floppy_raw_cmd raw_cmd;
	LINUX_DSK_DRIVER *lxself;
	int n;
	dsk_err_t err;
	unsigned char *buf;
	unsigned char mask = 0xFF;

	if (!self || !geom || !format) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR;
	lxself = (LINUX_DSK_DRIVER *)self;
	if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY;

	err = check_geom(lxself, geom);
	if (err) return err;
	if (geom->dg_fm)      mask &= ~0x40;
	if (geom->dg_nomulti) mask &= ~0x80;

	buf = dsk_malloc(geom->dg_sectors * 4);
	if (!buf) return DSK_ERR_NOMEM;
	for (n = 0; n < geom->dg_sectors; n++)
	{
		buf[n*4]   = format[n].fmt_cylinder;
		buf[n*4+1] = format[n].fmt_head;
		buf[n*4+2] = format[n].fmt_sector;
		buf[n*4+3] = dsk_get_psh(format[n].fmt_secsize);
	}

	init_raw_cmd(&raw_cmd);
	raw_cmd.flags = FD_RAW_WRITE | FD_RAW_INTR;
	if (cylinder != lxself->lx_cylinder) raw_cmd.flags |= FD_RAW_NEED_SEEK;
	raw_cmd.track = cylinder;
	if (lxself->lx_doublestep) raw_cmd.track *= 2;
	raw_cmd.rate  = get_rate(geom);
	raw_cmd.length= 4 * geom->dg_sectors;
	raw_cmd.data  = buf;

	raw_cmd.cmd[raw_cmd.cmd_count++] = FD_FORMAT & mask;
	raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head);
	raw_cmd.cmd[raw_cmd.cmd_count++] = dsk_get_psh(geom->dg_secsize);
	raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_sectors;
	raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_fmtgap;
	raw_cmd.cmd[raw_cmd.cmd_count++] = filler;

	if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR;

	memcpy(lxself->lx_status, raw_cmd.reply, 4);
	if (raw_cmd.reply[0] & 0x40) return xlt_error(raw_cmd.reply);
	lxself->lx_cylinder = cylinder;
	return DSK_ERR_OK;
}
예제 #2
0
dsk_err_t ntwdm_format(DSK_DRIVER *self, DSK_GEOMETRY *geom,
                                dsk_pcyl_t cylinder, dsk_phead_t head,
                                const DSK_FORMAT *format, unsigned char filler)
{
	NTWDM_DSK_DRIVER *ntself;
	unsigned u, fsize;
	dsk_err_t err;
	FD_FORMAT_PARAMS *pfp;
	FD_ID_HEADER *ph;

	if (!self || !geom || !format) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR;
	ntself = (NTWDM_DSK_DRIVER *)self;
	if (ntself->nt_hdisk == INVALID_HANDLE_VALUE) return DSK_ERR_NOTRDY;

	err = check_geom(ntself, geom);
	if (err) return err;

	fsize = sizeof(FD_FORMAT_PARAMS) + geom->dg_sectors * sizeof(FD_ID_HEADER);
	pfp = (FD_FORMAT_PARAMS *)dsk_malloc(fsize);
	if (!pfp) return DSK_ERR_NOMEM;
	pfp->flags   = geom->dg_fm ? 0 : FD_OPTION_MFM;
	pfp->phead   = encode_head(self, head);
	pfp->size    = dsk_get_psh(geom->dg_secsize);
	pfp->sectors = geom->dg_sectors;
	pfp->gap     = geom->dg_fmtgap;
	pfp->fill    = filler;

	ph = (FD_ID_HEADER *)(pfp+1);
	for (u = 0; u < geom->dg_sectors; u++)
	{
		ph[u].cyl    = format[u].fmt_cylinder;
		ph[u].head   = format[u].fmt_head;
		ph[u].sector = format[u].fmt_sector;
		ph[u].size   = dsk_get_psh(format[u].fmt_secsize);
	}

	if (cylinder != ntself->nt_cylinder)
	{
		UCHAR cyl = ntself->nt_doublestep ? cylinder*2 : cylinder;
		if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_SEEK, &cyl, sizeof(cyl),
				NULL, 0, &dwRet, NULL)) return xlt_error(GetLastError());
		ntself->nt_cylinder = cylinder;
	}

	if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_FORMAT_TRACK, pfp, fsize,
			NULL, 0, &dwRet, NULL)) return xlt_error(GetLastError());

	return DSK_ERR_OK;
}
예제 #3
0
STDMETHODIMP CDisk::ltrkid(IGeometry *g, long track, short *count, VARIANT *buffer)
{
	DSK_GEOMETRY geom;
	DSK_FORMAT *fmt;
	unsigned char *buf;
	dsk_err_t err;
	dsk_psect_t n, acount = 0;
	HRESULT hr;

	g_to_dg(g, &geom);
	err = dsk_ltrackids(m_driver, &geom, track, &acount, &fmt);
	if (acount)
	{
		if (count) *count = acount;
		buf = new unsigned char[4 * acount];
		for (n = 0; n < acount; n++)
		{
			buf[n*4  ] = fmt[n].fmt_cylinder;
			buf[n*4+1] = fmt[n].fmt_head;
			buf[n*4+2] = fmt[n].fmt_sector;
			buf[n*4+3] = dsk_get_psh(fmt[n].fmt_secsize);
		}
		hr = PutBuffer(buf, buffer, 4 * acount, err);
		delete buf;
		return hr;
	}
	return MapError(err);
}
예제 #4
0
dsk_err_t ntwdm_xwrite(DSK_DRIVER *self, const DSK_GEOMETRY *geom, const void *buf,
                              dsk_pcyl_t cylinder, dsk_phead_t head,
                              dsk_pcyl_t cyl_expected, dsk_phead_t head_expected,
                              dsk_psect_t sector, size_t sector_size, int deleted)
{
	NTWDM_DSK_DRIVER *ntself;
	FD_READ_WRITE_PARAMS rwp;
	LPVOID iobuffer;
	dsk_err_t err;
	DWORD dwIoCode;

	if (!self || !geom || !buf) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR;
	ntself = (NTWDM_DSK_DRIVER *)self;
	if (ntself->nt_hdisk == INVALID_HANDLE_VALUE) return DSK_ERR_NOTRDY;

	err = check_geom(ntself, geom);
	if (err) return err;

	rwp.flags = 0;
	if (!geom->dg_noskip)  rwp.flags |= FD_OPTION_SKIP;	      /* Skip deleted data */
	if (!geom->dg_fm)      rwp.flags |= FD_OPTION_MFM;	      /* MFM recording mode */
	if (!geom->dg_nomulti) rwp.flags |= FD_OPTION_MULTI_TRACK;    /* Enable multitrack */

	rwp.phead = encode_head(self, head);
	rwp.cyl = cyl_expected;
	rwp.head = head_expected;
	rwp.sector = sector;
	rwp.size = dsk_get_psh(sector_size);	/* [JCE] v1.1.5 */
	rwp.eot = sector+1;
	rwp.gap = geom->dg_rwgap;
	rwp.datalen = (sector_size < 255) ? sector_size : 0xFF;

	if (cylinder != ntself->nt_cylinder)
	{
		UCHAR cyl = ntself->nt_doublestep ? cylinder*2 : cylinder;
		if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_SEEK, &cyl, sizeof(cyl),
				NULL, 0, &dwRet, NULL)) return xlt_error(GetLastError());
		ntself->nt_cylinder = cylinder;
	}

/* v1.1.11: Use passed sector size, not geometry sector size */
        iobuffer = VirtualAlloc(NULL, sector_size, MEM_COMMIT, PAGE_READWRITE);
        if (!iobuffer) return DSK_ERR_NOMEM;
	memcpy(iobuffer, buf, sector_size);

	dwIoCode = deleted ? IOCTL_FDCMD_WRITE_DELETED_DATA : IOCTL_FDCMD_WRITE_DATA;
	if (!DeviceIoControl(ntself->nt_hdisk, dwIoCode, &rwp, sizeof(rwp), iobuffer,
			sector_size, &dwRet, NULL)) err = xlt_error(GetLastError());

	VirtualFree(iobuffer, 0, MEM_RELEASE);

	return err;
}
예제 #5
0
dsk_err_t linux_xread(DSK_DRIVER *self, const DSK_GEOMETRY *geom, void *buf,
                              dsk_pcyl_t cylinder, dsk_phead_t head,
                              dsk_pcyl_t cyl_expected, dsk_phead_t head_expected,
                              dsk_psect_t sector, size_t sector_size, int *deleted)
{
	struct floppy_raw_cmd raw_cmd;
	LINUX_DSK_DRIVER *lxself;
	dsk_err_t err;
	unsigned char mask = 0xFF;

	if (!self || !geom || !buf) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR;
	lxself = (LINUX_DSK_DRIVER *)self;
	if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY;

	err = check_geom(lxself, geom);
	if (err) return err;

	if (geom->dg_noskip)  mask &= ~0x20;	/* Don't skip deleted data */
	if (geom->dg_fm)      mask &= ~0x40;	/* FM recording mode */
	if (geom->dg_nomulti) mask &= ~0x80;	/* Disable multitrack */

	init_raw_cmd(&raw_cmd);
	raw_cmd.flags = FD_RAW_READ | FD_RAW_INTR;
	if (cylinder != lxself->lx_cylinder) raw_cmd.flags |= FD_RAW_NEED_SEEK;
	raw_cmd.track = cylinder;
	if (lxself->lx_doublestep) raw_cmd.track *= 2;
	raw_cmd.rate  = get_rate(geom);
	raw_cmd.length= sector_size;
	raw_cmd.data  = buf;

	if (deleted && (*deleted))
			raw_cmd.cmd[raw_cmd.cmd_count++] = 0xEC    & mask;
	else		raw_cmd.cmd[raw_cmd.cmd_count++] = FD_READ & mask;
	raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head);
	raw_cmd.cmd[raw_cmd.cmd_count++] = cyl_expected;
	raw_cmd.cmd[raw_cmd.cmd_count++] = head_expected;
	raw_cmd.cmd[raw_cmd.cmd_count++] = sector;
	raw_cmd.cmd[raw_cmd.cmd_count++] = dsk_get_psh(sector_size);
	raw_cmd.cmd[raw_cmd.cmd_count++] = sector;
	raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_rwgap;
	raw_cmd.cmd[raw_cmd.cmd_count++] = (sector_size < 255) ? sector_size : 0xFF; 

	if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR;

	memcpy(lxself->lx_status, raw_cmd.reply, 4);
	if (raw_cmd.reply[0] & 0x40) return xlt_error(raw_cmd.reply);

	if (deleted) deleted[0] = (raw_cmd.reply[2] & 0x40) ? 1 : 0;
	lxself->lx_cylinder = cylinder;
	return DSK_ERR_OK;
}
예제 #6
0
dsk_err_t win16_format(DSK_DRIVER *self, DSK_GEOMETRY *geom,
	                            dsk_pcyl_t cylinder, dsk_phead_t head,
	                            const DSK_FORMAT *format, unsigned char filler)
{
	WIN16_DSK_DRIVER *w16self;
	union REGS reg;
	struct SREGS sreg;
	dsk_err_t err;
	unsigned char *trkbuf;
	unsigned int n, tries;
	unsigned char old_dpt[11];

	if (!format || !self || !geom || self->dr_class != &dc_win16) return DSK_ERR_BADPTR;
	w16self = (WIN16_DSK_DRIVER *)self;
	if (w16self->w16_readonly) return DSK_ERR_RDONLY;
	
	trkbuf = dsk_malloc(4 * geom->dg_sectors);
	if (!trkbuf) return DSK_ERR_NOMEM;

	err = win16_checkgeom(w16self, geom, old_dpt, filler);
	if (err) { dsk_free(trkbuf); return err; }
	for (n = 0; n < geom->dg_sectors; n++)
	{
		trkbuf[4*n  ] = (unsigned char)format[n].fmt_cylinder;
		trkbuf[4*n+1] = (unsigned char)format[n].fmt_head;
		trkbuf[4*n+2] = (unsigned char)format[n].fmt_sector;
		trkbuf[4*n+3] = dsk_get_psh(format[n].fmt_secsize);
	}

	for (tries = 0; tries < 3; tries++)
	{
		reg.h.ah      = 0x05; 
		reg.h.al      = geom->dg_sectors;
		reg.x.bx      = FP_OFF(trkbuf);
		reg.h.ch      = cylinder;
		reg.h.cl      = 0;
		reg.h.dh      = head;
		reg.h.dl      = w16self->w16_unit - 1;
		reg.x.cflag   = 1;

		int86x(0x13, &reg, &reg, &sreg);
		if (!reg.x.cflag) break;
	}
	dsk_free(trkbuf);
	set_dpt(old_dpt);
	if ( reg.x.cflag ) return translate_int13_error(reg.h.ah);
	return DSK_ERR_OK;
}
예제 #7
0
STDMETHODIMP CDisk::lsecid(IGeometry *g, long track, VARIANT *buffer)
{
	DSK_GEOMETRY geom;
	DSK_FORMAT fmt;
	unsigned char buf[4];
	dsk_err_t err;

	g_to_dg(g, &geom);
	err = dsk_lsecid(m_driver, &geom, track, &fmt);
	buf[0] = fmt.fmt_cylinder;
	buf[1] = fmt.fmt_head;
	buf[2] = fmt.fmt_sector;
	buf[3] = dsk_get_psh(fmt.fmt_secsize);

	return PutBuffer(buf, buffer, 4, err);
}
예제 #8
0
static int win16_checkgeom(WIN16_DSK_DRIVER *w16self, const DSK_GEOMETRY *geom, 
						   unsigned char *old_dpt, unsigned char filler)
{   
	unsigned char new_dpt[11];                                         
	/* If get_dpt() fails, we're on Windows NT 5.x and can't change the geometry */
	if (!get_dpt(old_dpt)) return DSK_ERR_OK;                                      
	get_dpt(new_dpt);
	new_dpt[3] = dsk_get_psh(geom->dg_secsize);	/* Bytes / sector */
	new_dpt[4] = geom->dg_sectors;				/* Sectors / track */
	new_dpt[5] = geom->dg_rwgap;				/* Read/write gap */
	new_dpt[6] = (new_dpt[3]) ? 0xFF : 0x80;	/* Data length */
	new_dpt[7] = geom->dg_fmtgap;				/* Format gap */
	new_dpt[8] = filler;						/* Format filler byte */
	set_dpt(new_dpt);	
	return DSK_ERR_OK;
}                             
예제 #9
0
/* Read a track (FDC765 READ TRACK command) */
dsk_err_t linux_xtread(DSK_DRIVER *self, const DSK_GEOMETRY *geom, void *buf,
                              dsk_pcyl_t cylinder, dsk_phead_t head,
			      dsk_pcyl_t cyl_expected, dsk_phead_t head_expected)
{
	struct floppy_raw_cmd raw_cmd;
	LINUX_DSK_DRIVER *lxself;
	dsk_err_t err;
	unsigned char mask = 0xFF;

	if (!self || !geom || !buf) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_linux) return DSK_ERR_BADPTR;
	lxself = (LINUX_DSK_DRIVER *)self;
	if (lxself->lx_fd < 0) return DSK_ERR_NOTRDY;

	err = check_geom(lxself, geom);
	if (err) return err;

	if (geom->dg_fm)      mask &= ~0x40;
	if (geom->dg_nomulti) mask &= ~0x80;

	init_raw_cmd(&raw_cmd);
	raw_cmd.flags = FD_RAW_READ | FD_RAW_INTR;
	if (cylinder != lxself->lx_cylinder) raw_cmd.flags |= FD_RAW_NEED_SEEK;
	raw_cmd.track = cylinder;
	if (lxself->lx_doublestep) raw_cmd.track *= 2;
	raw_cmd.rate  = get_rate(geom);
	raw_cmd.length= geom->dg_secsize * geom->dg_sectors;
	raw_cmd.data  = buf;
	
	/* fdreg.h doesn't define the Read Track command, but here it is */	
	raw_cmd.cmd[raw_cmd.cmd_count++] = 0x62 & mask;
	raw_cmd.cmd[raw_cmd.cmd_count++] = encode_head(self, head);
	raw_cmd.cmd[raw_cmd.cmd_count++] = cyl_expected;
	raw_cmd.cmd[raw_cmd.cmd_count++] = head_expected;
	raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_secbase;
	raw_cmd.cmd[raw_cmd.cmd_count++] = dsk_get_psh(geom->dg_secsize);
	raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_secbase + geom->dg_sectors;
	raw_cmd.cmd[raw_cmd.cmd_count++] = geom->dg_rwgap;
	raw_cmd.cmd[raw_cmd.cmd_count++] = 0xFF;

	if (ioctl(lxself->lx_fd, FDRAWCMD, &raw_cmd) < 0) return DSK_ERR_SYSERR;

	memcpy(lxself->lx_status, raw_cmd.reply, 4);
	if (raw_cmd.reply[0] & 0x40) return xlt_error(raw_cmd.reply);
	lxself->lx_cylinder = cylinder;
	return DSK_ERR_OK;
}
예제 #10
0
/* Read a track (FDC765 READ TRACK command) */
dsk_err_t ntwdm_xtread(DSK_DRIVER *self, const DSK_GEOMETRY *geom, void *buf,
                              dsk_pcyl_t cylinder, dsk_phead_t head,
			      dsk_pcyl_t cyl_expected, dsk_phead_t head_expected)
{
	NTWDM_DSK_DRIVER *ntself;
	FD_READ_WRITE_PARAMS rwp;
	LPVOID iobuffer;
	DWORD tracksize;
	dsk_err_t err;

	if (!self || !geom || !buf) return DSK_ERR_BADPTR;
	if (self->dr_class != &dc_ntwdm) return DSK_ERR_BADPTR;
	ntself = (NTWDM_DSK_DRIVER *)self;
	if (ntself->nt_hdisk == INVALID_HANDLE_VALUE) return DSK_ERR_NOTRDY;

	err = check_geom(ntself, geom);
	if (err) return err;

	rwp.flags = 0;
	if (!geom->dg_fm)      rwp.flags |= FD_OPTION_MFM;	      /* MFM recording mode */
	if (!geom->dg_nomulti) rwp.flags |= FD_OPTION_MULTI_TRACK;    /* Enable multitrack */

	rwp.phead = encode_head(self, head);
	rwp.cyl = cyl_expected;
	rwp.head = head_expected;
	rwp.sector = geom->dg_secbase;
	rwp.size = dsk_get_psh(geom->dg_secsize);
	rwp.eot = geom->dg_secbase + geom->dg_sectors;
	rwp.gap = geom->dg_rwgap;
	rwp.datalen = 0xFF;

	tracksize = rwp.size * geom->dg_sectors;
        iobuffer = VirtualAlloc(NULL, tracksize, MEM_COMMIT, PAGE_READWRITE);
        if (!iobuffer) return DSK_ERR_NOMEM;

	if (!DeviceIoControl(ntself->nt_hdisk, IOCTL_FDCMD_READ_TRACK, &rwp, sizeof(rwp),
			iobuffer, geom->dg_secsize, &dwRet, NULL)) err = xlt_error(GetLastError());

	memcpy(buf, iobuffer, geom->dg_secsize);
	VirtualFree(iobuffer, 0, MEM_RELEASE);

	return err;
}
예제 #11
0
/* Format a track on a DSK. Can grow the DSK file. */
dsk_err_t ldbsdisk_format(DSK_DRIVER *pdriver, DSK_GEOMETRY *geom,
			dsk_pcyl_t cylinder, dsk_phead_t head,
			const DSK_FORMAT *format, unsigned char filler)
{
	dsk_err_t err;
	LDBSDISK_DSK_DRIVER *self;
	dsk_psect_t sector;
	
	if (!format || !geom || !pdriver) return DSK_ERR_BADPTR;
	DC_CHECK(pdriver)
	self = (LDBSDISK_DSK_DRIVER *)pdriver;

	if (self->ld_readonly) return DSK_ERR_RDONLY;

	err = ldbsdisk_select_track(self, cylinder, head);
	if (err) return err;

	err = ldbsdisk_wipe_track(self);
	if (err) return err;

	/* The track's sectors have been removed. All that remains is 
	 * its header (empty). Create a new header that will replace it. */
	self->ld_cur_track = ldbs_trackhead_alloc(geom->dg_sectors);
	if (!self->ld_cur_track)
	{
		return DSK_ERR_NOMEM;
	}
	self->ld_cur_cyl = cylinder;
	self->ld_cur_head = head;

	/* Populate the track header */
	switch (geom->dg_datarate)
	{
		case RATE_SD: self->ld_cur_track->datarate = 1; break;
		case RATE_DD: self->ld_cur_track->datarate = 1; break;
		case RATE_HD: self->ld_cur_track->datarate = 2; break;
		case RATE_ED: self->ld_cur_track->datarate = 3; break;
	}
	switch (geom->dg_fm & RECMODE_MASK)
	{
		case RECMODE_FM:  self->ld_cur_track->recmode = 1; break;
		case RECMODE_MFM: self->ld_cur_track->recmode = 2; break;
	}
	self->ld_cur_track->gap3 = geom->dg_fmtgap;
	self->ld_cur_track->filler = filler;
	self->ld_cur_track->dirty = 1;

	/* Write the sectors. Since they are all blank we don't actually
	 * need to send them to the file */
	for (sector = 0; sector < geom->dg_sectors; sector++)
	{
		LDBS_SECTOR_ENTRY *secent = &self->ld_cur_track->sector[sector];

		secent->id_cyl  = format[sector].fmt_cylinder;
		secent->id_head = format[sector].fmt_head;
		secent->id_sec  = format[sector].fmt_sector;
		secent->id_psh  = dsk_get_psh(format[sector].fmt_secsize);
		secent->st1 = 0;
		secent->st2 = 0;
		secent->copies = 0;
		secent->trail = 0;
		secent->offset = 0;	/* XXX Can probably calculate a */
		secent->filler = filler;/* default value for 'offset' */
	}
	/* Write the track header */
	err = ldbsdisk_flush_cur_track(self);
	if (err) return err;

	/* Populate bits of the DPB that the standard geometry probe
	 * does not */
	self->ld_dpb.spt = geom->dg_sectors * (geom->dg_secsize / 128);
	self->ld_dpb.psh = dsk_get_psh(geom->dg_secsize);
	self->ld_dpb.phm = (1 << self->ld_dpb.psh) - 1;

	err = ldbs_put_geometry(self->ld_store, geom);
	return err;
}
예제 #12
0
파일: Library.cpp 프로젝트: lipro/libdsk
STDMETHODIMP CLibrary::get_psh(long sectorsize, short *shift)
{
	shift[0] = dsk_get_psh(sectorsize);
	return S_OK;
}