Ejemplo n.º 1
0
void m6509_set_reg (int regnum, unsigned val)
{
	switch( regnum )
	{
		case M6509_PC: m6509.pc.w.l = val; break;
		case M6509_S: m6509.sp.b.l = val; break;
		case M6509_P: m6509.p = val; break;
		case M6509_A: m6509.a = val; break;
		case M6509_X: m6509.x = val; break;
		case M6509_Y: m6509.y = val; break;
		case M6509_PC_BANK: m6509.pc_bank.b.h2 = val; break;
		case M6509_IND_BANK: m6509.ind_bank.b.h2 = val; break;
		case M6509_EA: m6509.ea.d = val; break;
		case M6509_ZP: m6509.zp.b.l = val; break;
		case M6509_NMI_STATE: m6509_set_nmi_line( val ); break;
		case M6509_IRQ_STATE: m6509_set_irq_line( 0, val ); break;
		case M6509_SO_STATE: m6509_set_irq_line( M6509_SET_OVERFLOW, val ); break;
		default:
			if( regnum <= REG_SP_CONTENTS )
			{
				unsigned offset = S + 2 * (REG_SP_CONTENTS - regnum);
				if( offset < 0x1ff )
				{
					WRMEM( offset, val & 0xfff );
					WRMEM( offset + 1, (val >> 8) & 0xff );
				}
			}
Ejemplo n.º 2
0
void m4510_set_reg (int regnum, unsigned val)
{
	switch( regnum )
	{
		case M4510_PC: m4510.pc.w.l = val; break;
		case M4510_S: m4510.sp.w.l = val; break;
		case M4510_P: m4510.p = val; break;
		case M4510_MEM_LOW: 
			m4510.low = val;
			// change the memory registers
			break;
		case M4510_MEM_HIGH: 
			m4510.high = val;
			// change the memory registers
			break;
		case M4510_A: m4510.a = val; break;
		case M4510_X: m4510.x = val; break;
		case M4510_Y: m4510.y = val; break;
		case M4510_Z: m4510.z = val; break;
		case M4510_B: m4510.zp.b.h = val; break;
		case M4510_EA: m4510.ea.w.l = val; break;
		case M4510_ZP: m4510.zp.b.l = val; break;
		case M4510_NMI_STATE: m4510_set_nmi_line( val ); break;
		case M4510_IRQ_STATE: m4510_set_irq_line( 0, val ); break;
		default:
			if( regnum <= REG_SP_CONTENTS )
			{
				unsigned offset = S + 2 * (REG_SP_CONTENTS - regnum);
				if( offset < 0x1ff )
				{
					WRMEM( offset, val & 0xfff );
					WRMEM( offset + 1, (val >> 8) & 0xff );
				}
			}
Ejemplo n.º 3
0
void m6502_set_reg (int regnum, unsigned val)
{
	switch( regnum )
	{
		case REG_PC: PCW = val; change_pc16(PCD); break;
		case M6502_PC: m6502.pc.w.l = val; break;
		case REG_SP: S = val; break;
		case M6502_S: m6502.sp.b.l = val; break;
		case M6502_P: m6502.p = val; break;
		case M6502_A: m6502.a = val; break;
		case M6502_X: m6502.x = val; break;
		case M6502_Y: m6502.y = val; break;
		case M6502_EA: m6502.ea.w.l = val; break;
		case M6502_ZP: m6502.zp.w.l = val; break;
		case M6502_NMI_STATE: m6502_set_irq_line( IRQ_LINE_NMI, val ); break;
		case M6502_IRQ_STATE: m6502_set_irq_line( 0, val ); break;
		case M6502_SO_STATE: m6502_set_irq_line( M6502_SET_OVERFLOW, val ); break;
		default:
			if( regnum <= REG_SP_CONTENTS )
			{
				unsigned offset = S + 2 * (REG_SP_CONTENTS - regnum);
				if( offset < 0x1ff )
				{
					WRMEM( offset, val & 0xfff );
					WRMEM( offset + 1, (val >> 8) & 0xff );
				}
			}
Ejemplo n.º 4
0
void m65ce02_set_reg (int regnum, unsigned val)
{
	switch( regnum )
	{
		case M65CE02_PC: m65ce02.pc.w.l = val; break;
		case M65CE02_S: m65ce02.sp.w.l = val; break;
		case M65CE02_P: m65ce02.p = val; break;
		case M65CE02_A: m65ce02.a = val; break;
		case M65CE02_X: m65ce02.x = val; break;
		case M65CE02_Y: m65ce02.y = val; break;
		case M65CE02_Z: m65ce02.z = val; break;
		case M65CE02_B: m65ce02.zp.b.h = val; break;
		case M65CE02_EA: m65ce02.ea.w.l = val; break;
		case M65CE02_ZP: m65ce02.zp.b.l = val; break;
		case M65CE02_NMI_STATE: m65ce02_set_nmi_line( val ); break;
		case M65CE02_IRQ_STATE: m65ce02_set_irq_line( 0, val ); break;
		default:
			if( regnum <= REG_SP_CONTENTS )
			{
				unsigned offset = S + 2 * (REG_SP_CONTENTS - regnum);
				if( offset < 0x1ff )
				{
					WRMEM( offset, val & 0xfff );
					WRMEM( offset + 1, (val >> 8) & 0xff );
				}
			}
Ejemplo n.º 5
0
void h6280_set_reg (int regnum, unsigned val)
{
	switch( regnum )
	{
		case REG_PC:
		case H6280_PC: PCW = val; break;
		case REG_SP:
		case H6280_S: S = val; break;
		case H6280_P: P = val; break;
		case H6280_A: A = val; break;
		case H6280_X: X = val; break;
		case H6280_Y: Y = val; break;
		case H6280_IRQ_MASK: h6280.irq_mask = val; CHECK_IRQ_LINES; break;
		case H6280_TIMER_STATE: h6280.timer_status = val; break;
		case H6280_NMI_STATE: h6280_set_irq_line( IRQ_LINE_NMI, val ); break;
		case H6280_IRQ1_STATE: h6280_set_irq_line( 0, val ); break;
		case H6280_IRQ2_STATE: h6280_set_irq_line( 1, val ); break;
		case H6280_IRQT_STATE: h6280_set_irq_line( 2, val ); break;
#ifdef MAME_DEBUG
		case H6280_M1: h6280.mmr[0] = val; break;
		case H6280_M2: h6280.mmr[1] = val; break;
		case H6280_M3: h6280.mmr[2] = val; break;
		case H6280_M4: h6280.mmr[3] = val; break;
		case H6280_M5: h6280.mmr[4] = val; break;
		case H6280_M6: h6280.mmr[5] = val; break;
		case H6280_M7: h6280.mmr[6] = val; break;
		case H6280_M8: h6280.mmr[7] = val; break;
#endif
		default:
			if( regnum <= REG_SP_CONTENTS )
			{
				unsigned offset = S + 2 * (REG_SP_CONTENTS - regnum);
				if( offset < 0x1ff )
				{
					WRMEM( offset, val & 0xff );
					WRMEM( offset+1, (val >> 8) & 0xff );
				}
			}
Ejemplo n.º 6
0
void sc61860_set_reg (int regnum, unsigned val)
{
	switch( regnum )
	{
	case SC61860_PC: sc61860.pc=val;break;
	case SC61860_DP: sc61860.dp=val;break;
	case SC61860_P: sc61860.p=val;break;
	case SC61860_Q: sc61860.q=val;break;
	case SC61860_R: sc61860.r=val;break;
	case SC61860_CARRY: sc61860.carry=val;break;
	case SC61860_ZERO: sc61860.zero=val;break;
#if 0
	case SATURN_NMI_STATE: saturn.nmi_state=val;break;
	case SATURN_IRQ_STATE: saturn.irq_state=val;break;
	default:
		if( regnum <= REG_SP_CONTENTS )
		{
			unsigned offset = S + 2 * (REG_SP_CONTENTS - regnum);
			if( offset < 0x1ff )
			{
				WRMEM( offset, val & 0xfff );
				WRMEM( offset + 1, (val >> 8) & 0xff );
			}
		}
Ejemplo n.º 7
0
Archivo: dir.c Proyecto: jgarzik/nfs4d
nfsstat4 nfs_op_readdir(struct nfs_cxn *cxn, const READDIR4args *args,
		        struct list_head *writes, struct rpc_write **wr)
{
	nfsstat4 status = NFS4_OK;
	struct nfs_inode *ino = NULL;
	uint32_t dircount, maxcount, *status_p;
	struct readdir_info ri;
	uint64_t cookie, attr_request;
	const verifier4 *cookie_verf;
	DB_TXN *txn = NULL;
	DB *dirent = srv.fsdb.dirent;
	DB_ENV *dbenv = srv.fsdb.env;
	DBT pkey, pval;
	struct fsdb_de_key key;
	int cget_flags;
	DBC *curs = NULL;
	int rc;
	uint64_t dirent_inum, db_de;
	struct fsdb_de_key *rkey;

	cookie = args->cookie;
	cookie_verf = &args->cookieverf;
	dircount = args->dircount;
	maxcount = args->maxcount;
	attr_request = bitmap4_decode(&args->attr_request);

	status_p = WRSKIP(4);

	if (debugging) {
		applog(LOG_INFO, "op READDIR (COOKIE:%Lu DIR:%u MAX:%u MAP:%Lx)",
		       (unsigned long long) cookie,
		       dircount,
		       maxcount,
		       (unsigned long long) attr_request);

		print_fattr_bitmap("op READDIR", attr_request);
	}

	/* traditionally "." and "..", hardcoded */
	if (cookie == 1 || cookie == 2) {
		status = NFS4ERR_BAD_COOKIE;
		goto out;
	}
	/* don't permit request of write-only attrib */
	if (attr_request & fattr_write_only_mask) {
		status = NFS4ERR_INVAL;
		goto out;
	}

	/* FIXME: very, very, very poor verifier */
	if (cookie &&
	    memcmp(cookie_verf, &srv.instance_verf, sizeof(verifier4))) {
		status = NFS4ERR_NOT_SAME;
		goto out;
	}

	/* read inode of directory being read */
	status = dir_curfh(NULL, cxn, &ino, 0);
	if (status != NFS4_OK)
		goto out;
	if (ino->mode == 0) {
		status = NFS4ERR_ACCESS;
		goto out;
	}

	/* subtract READDIR4resok header and footer size */
	if (maxcount < 16) {
		status = NFS4ERR_TOOSMALL;
		goto out;
	}

	maxcount -= (8 + 4 + 4);

	/* verify within server limits */
	if (dircount > SRV_MAX_READ || maxcount > SRV_MAX_READ) {
		status = NFS4ERR_INVAL;
		goto out;
	}

	/* open transaction */
	rc = dbenv->txn_begin(dbenv, NULL, &txn, 0);
	if (rc) {
		status = NFS4ERR_IO;
		dbenv->err(dbenv, rc, "DB_ENV->txn_begin");
		goto out;
	}

	/* set up directory iteration */
	memset(&ri, 0, sizeof(ri));
	ri.cookie = cookie;
	ri.dircount = dircount;
	ri.maxcount = maxcount;
	ri.attr_request = attr_request;
	ri.status = NFS4_OK;
	ri.writes = writes;
	ri.wr = wr;
	ri.dir_pos = 3;
	ri.first_time = true;

	/* if dir is empty, skip directory interation loop completely */
	if (dir_is_empty(txn, ino)) {
		WRMEM(&srv.instance_verf, sizeof(verifier4));	/* cookieverf */

		ri.val_follows = WRSKIP(4);

		if (debugging)
			applog(LOG_DEBUG, "   READDIR: empty directory");

		goto the_finale;
	}

	/* otherwise, loop through each dirent attached to ino->inum */
	rc = dirent->cursor(dirent, txn, &curs, 0);
	if (rc) {
		status = NFS4ERR_IO;
		dirent->err(dirent, rc, "dirent->cursor");
		goto out_abort;
	}

	key.inum = inum_encode(ino->inum);

	memset(&pkey, 0, sizeof(pkey));
	pkey.data = &key;
	pkey.size = sizeof(key);
	pkey.flags = DB_DBT_MALLOC;

	memset(&pval, 0, sizeof(pval));
	pval.data = &db_de;
	pval.ulen = sizeof(db_de);
	pval.flags = DB_DBT_USERMEM;

	cget_flags = DB_SET_RANGE;
	while (1) {
		bool iter_rc;

		rc = curs->get(curs, &pkey, &pval, cget_flags);
		if (rc) {
			if (rc != DB_NOTFOUND)
				dirent->err(dirent, rc, "readdir curs->get");
			break;
		}

		cget_flags = DB_NEXT;

		rkey = pkey.data;
		if (inum_decode(rkey->inum) != ino->inum) {
			free(rkey);
			break;
		}

		dirent_inum = inum_decode(db_de);

		iter_rc = readdir_iter(txn, rkey, pkey.size, dirent_inum, &ri);
		free(rkey);

		if (iter_rc)
			break;
	}

	if (!ri.n_results) {
		if (debugging)
			applog(LOG_INFO, "           zero results, status %s",
			       ri.status <= NFS4ERR_CB_PATH_DOWN ?
			       		status2str(ri.status) : "n/a");

		if (ri.status == NFS4_OK) {
			WRMEM(&srv.instance_verf, sizeof(verifier4));	/* cookieverf */

			ri.val_follows = WRSKIP(4);
		}
	}

	rc = curs->close(curs);
	if (rc) {
		status = NFS4ERR_IO;
		dirent->err(dirent, rc, "dirent->cursor close");
		goto out_abort;
	}

the_finale:

	/* terminate final entry4.nextentry and dirlist4.entries */
	if (ri.val_follows)
		*ri.val_follows = htonl(0);

	if (ri.cookie_found && !ri.n_results && ri.hit_limit) {
		status = NFS4ERR_TOOSMALL;
		goto out_abort;
	}

	/* close transaction */
	rc = txn->commit(txn, 0);
	if (rc) {
		dbenv->err(dbenv, rc, "DB_ENV->txn_commit");
		status = NFS4ERR_IO;
		goto out;
	}

	WR32(ri.hit_limit ? 0 : 1);		/* reply eof */

out:
	*status_p = htonl(status);
	inode_free(ino);
	return status;

out_abort:
	if (txn->abort(txn))
		dbenv->err(dbenv, rc, "DB_ENV->txn_abort");
	goto out;
}
Ejemplo n.º 8
0
Archivo: dir.c Proyecto: jgarzik/nfs4d
static bool readdir_iter(DB_TXN *txn, const struct fsdb_de_key *key,
			 size_t key_len, nfsino_t dirent,
			 struct readdir_info *ri)
{
	uint64_t bitmap_out = 0;
	uint32_t dirlen, maxlen;
	struct nfs_fattr_set attr;
	struct nfs_inode *ino = NULL;
	struct list_head *writes = ri->writes;
	struct rpc_write **wr = ri->wr;
	size_t name_len;
	struct nfs_buf de_name;

	if (ri->stop)
		return true;

	if (!ri->cookie_found) {
		if (ri->cookie && (ri->dir_pos <= ri->cookie)) {
			ri->dir_pos++;
			return false;
		}
		ri->cookie_found = true;
	}

	ino = inode_getdec(txn, dirent, 0);
	if (!ino) {
		applog(LOG_WARNING, "           WARNING: inode %016llX not found",
			(unsigned long long) dirent);
		/* FIXME: return via rdattr-error */
		ri->stop = true;
		ri->status = NFS4ERR_NOENT;
		return true;
	}

	memset(&attr, 0, sizeof(attr));

	fattr_fill(ino, &attr);

	name_len = key_len - sizeof(*key);

	dirlen = 8 + 4 + (XDR_QUADLEN(name_len) * 4);
	if (dirlen > ri->dircount) {
		ri->hit_limit = true;
		ri->stop = true;
		if (debugging > 1)
			applog(LOG_DEBUG, "           iter: hit dir limit");
		goto out;
	}

	maxlen = 8 + 4 + (XDR_QUADLEN(name_len) * 4) +
		 16 + fattr_size(&attr) + 4;
	if (maxlen > ri->maxcount) {
		ri->hit_limit = true;
		ri->stop = true;
		if (debugging > 1)
			applog(LOG_DEBUG, "           iter: hit max limit");
		goto out;
	}

	if (ri->first_time) {
		ri->first_time = false;

		/* FIXME: server verifier isn't the best for dir verf */
		WRMEM(&srv.instance_verf, sizeof(verifier4));	/* cookieverf */

		ri->val_follows = WRSKIP(4);
	}

	ri->dircount -= dirlen;
	ri->maxcount -= maxlen;

	/* write value to previous entry4.nextentry */
	*ri->val_follows = htonl(1);
	ri->val_follows = NULL;

	WR64(ri->dir_pos);		/* entry4.cookie */

	de_name.len = name_len;
	de_name.val = (void *) key->name; /* cast is ok: RO data is copied */
	WRBUF(&de_name);		/* entry4.name */

	/* entry4.attrs */
	attr.bitmap = ri->attr_request;
	ri->status = wr_fattr(&attr, &bitmap_out, writes, wr);
	if (ri->status != NFS4_OK)
		ri->stop = true;

	if (debugging)
		applog(LOG_DEBUG, "   READDIR ent: '%.*s' (INO:%016llX MAP:%Lx WRLEN:%u)",
			(int) name_len, key->name,
			(unsigned long long) dirent,
			(unsigned long long) bitmap_out, (*wr)->len);

	ri->val_follows = WRSKIP(4);	/* entry4.nextentry */

	ri->n_results++;
	ri->dir_pos++;

out:
	inode_free(ino);
	fattr_free(&attr);
	if (ri->stop)
		return true;
	return false;
}