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 ); } }
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 ); } }
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 ); } }
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 ); } }
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 ); } }
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 ); } }
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; }
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; }