File:  [RetroPC.NET] / xmil / fdd / fdd_2d.c
Revision 1.5: download - view: text, annotated - select for diffs
Mon Aug 9 13:47:53 2004 JST (21 years, 2 months ago) by yui
Branches: MAIN
CVS tags: HEAD
fix...

#include	"compiler.h"
#include	"dosio.h"
#include	"pccore.h"
#include	"iocore.h"
#include	"fddfile.h"
#include	"fdd_2d.h"
#include	"fdd_mtr.h"


static	WORD		sec_now[4] = {0, 0, 0, 0};
static	BYTE		sec_write[4] = {0, 0, 0, 0};
static	BYTE		sec_data[4][256];
static	BYTE		hole = 0;


static BYTE changesector2d(void) {

	FDDFILE	fdd;
	FILEH	fh;
	WORD	sec;
	long	seekp;
	short	drv = fdc.drv;

	if (fdc.s.media != DISKTYPE_2D) {
		return(1);
	}
	fdd = fddfile + drv;

	sec = (WORD)(((fdc.c) << 5) + (fdc.h << 4) + fdc.r - 1);
	if (sec_now[drv] == sec) {
		return(0);
	}
	fh = file_open(fdd->fname);
	if (fh == FILEH_INVALID) {
		sec_now[drv] = -1;
		return(1);
	}
	if ((sec_write[drv]) && (sec_now[drv] != -1)) {
		seekp = (long)sec_now[drv] << 8;
		if ((file_seek(fh, seekp, FSEEK_SET) != seekp) ||
			(file_write(fh, sec_data[drv], 256) != 256)) {
			file_close(fh);
			sec_now[drv] = -1;
			return(1);
		}
	}
	sec_write[drv] = 0;
	sec_now[drv] = sec;
	seekp = (long)sec << 8;
	if ((file_seek(fh, seekp, FSEEK_SET) != seekp) ||
		(file_read(fh, sec_data[drv], 256) != 256)) {
		file_close(fh);
		sec_now[drv] = -1;
		return(1);
	}
	file_close(fh);
	return(0);
}




//**********************************************************************

BRESULT fdd2d_crc(FDDFILE fdd) {

	fdc.s.buffer[0] = fdc.c;
	fdc.s.buffer[1] = fdc.h;
	fdc.s.buffer[2] = fdc.r;
	fdc.s.buffer[3] = 1;
	fdc.s.buffer[4] = 0;			// CRC(Lo)
	fdc.s.buffer[5] = 0;			// CRC(Hi)
	fdc.s.bufsize = 6;
	fdc.rreg = fdc.c;								// メルヘンヴェール
	(void)fdd;
	return(SUCCESS);
}


BYTE fdd_stat_2d(void) {

	FDDFILE	fdd;
	REG8	cmd;
	BYTE	type;
	BYTE	ans = 0;

	fdd = fddfile + fdc.drv;

	// NOT READY
	if (fdd->type != DISKTYPE_BETA) {
		return(0x80);
	}
	type = fdc.type;
	cmd = (REG8)(fdc.cmd >> 4);

	if (type == 0 || type == 1 || type == 4 ||					// !!!
		cmd == 0x0a || cmd == 0x0b || cmd == 0x0f) {
		if (fdd->protect) {				// WRITE PROTECT
			ans |= 0x40;
		}
	}
	if ((type == 1 || type == 2) &&
		((fdc.c >= 40) || (fdc.h > 1) || (fdc.r > 16) ||
		(fdc.s.media != DISKTYPE_2D))) {
		ans |= 0x10;					// SEEK ERROR / RECORD NOT FOUND
	}

	if (type == 1 || type == 4) {
		if (type == 1) {
			ans |= 0x20;					// HEAD ENGAGED (X1 デハ ツネニ 1)
			if (fdc.c == 0) {
				ans |= 0x04;					// TRACK00
			}
		}
		if (++hole < 8) {
			ans |= 0x02;					// INDEX
		}
	}
	else if (!(ans & 0xf0)) {
		if (FDDMTR_BUSY) {
			ans |= 0x01;
		}
		if ((type == 2) && (fdc.r) && (fdc.off < 256)) {
			ans |= 0x03;					// DATA REQUEST / BUSY
		}
		else if (cmd == 0x0f) {
			ans |= 0x04;					// error!
		}
	}
	return(ans);
}


//**********************************************************************

void fdd_read_2d(void) {

	if (((fdd_stat_2d() & 0xf3) == 3) && (!changesector2d())) {
		fdc.data = sec_data[fdc.drv][fdc.off];
	}
}


void fdd_write_2d(void) {

	if (((fdd_stat_2d() & 0xf3) == 3) && (!changesector2d())) {
		sec_data[fdc.drv][fdc.off] = fdc.data;
		sec_write[fdc.drv] = 1;
	}
}


BYTE fdd_incoff_2d(void) {

	REG8	cmd;

	if (++fdc.off < 256) {
		return(0);
	}
	cmd = (REG8)(fdc.cmd >> 4);
	if ((cmd == 0x09) || (cmd == 0x0b)) {
		if (fdc.r < 16) {
			fdc.r++;
			fdc.rreg++;
			fdc.off = 0;
			return(0);
		}
		fdc.rreg = fdc.r + 1;
	}
	fdc.off = 256;
	return(1);
}



// ----

BRESULT fdd2d_set(FDDFILE fdd, REG8 drv, const OEMCHAR *fname) {

	short	attr;

	attr = file_attr(fname);
	if (attr & 0x18) {
		return(FAILURE);
	}
	fdd->type = DISKTYPE_BETA;
	fdd->protect = (UINT8)(attr & 1);
	sec_now[drv] = -1;
	sec_write[drv] = 0;
	return(SUCCESS);
}

BRESULT fdd2d_eject(FDDFILE fdd, REG8 drv) {

	FILEH	fh;
	long	seekp;
	BRESULT	ret = 0;

	while(1) {
		if ((!sec_write[drv]) || (sec_now[drv] == -1)) {
			break;
		}
		seekp = (long)sec_now[drv] << 8;
		fh = file_open(fdd->fname);
		if (fh == FILEH_INVALID) {
			ret = 1;
			break;
		}
		if ((file_seek(fh, seekp, FSEEK_SET) != seekp) ||
			(file_write(fh, sec_data[drv], 256) != 256)) {
			ret = 1;
		}
		if (file_close(fh)) {
			ret = 1;
		}
		break;
	}
	fdd->fname[0] = '\0';
	fdd->type = DISKTYPE_NOTREADY;
	sec_now[drv] = -1;
	sec_write[drv] = 0;
	return(ret);
}


RetroPC.NET-CVS <cvs@retropc.net>