Exemple #1
0
Action Parser::readAction() {
	match("action");
	Action a;

	string next = pop();
	while (next != "time") {
		if (!a.effect.empty()) a.effect += " ";
		a.effect += next;
		next = pop();
	}
	a.time = popf();

	match("cost");
	next = tokens.front();
	while (next != "value") {
		pop();
		double amount = popf();
		a.cost.push_back(Quantity{next, amount});
		next = tokens.front();
	}

	match("value");
	next = tokens.front();
	while (next != "end") {
		pop();
		double amount = popf();
		a.value.push_back(Quantity{next, amount});
		next = tokens.front();
	}
	pop();

	return a;
}
void SeniorVMHandle::start()
{
  popad();
  popf();
  pop(T_KEY);
  pop(T_RET);
}
// --- ref_cas_with_check
// Write barriered compare of Rcmp with memory, if equal set memory to Rval. Set
// flags dependent on success. Returns relpc of where NPE info should be added.
// NB on failure Rcmp contains the value from memory, this will be poisoned and
// not lvb-ed. ie. you shouldn't use this value.
int C1_MacroAssembler::ref_cas_with_check(RInOuts, Register Rbase, Register Rcmp, Register Rtmp0, Register Rtmp1,
                                          RKeepIns, Register Rindex, int off, int scale, Register Rval,
                                          CodeEmitInfo *info) {
  assert0( Rcmp == RAX );
  Label checked, strip;

#ifdef ASSERT
  verify_oop(Rval, MacroAssembler::OopVerify_Store);
  verify_oop(Rcmp, MacroAssembler::OopVerify_Move);
  if (RefPoisoning) move8(Rtmp1,Rval); // Save Rval
#endif

  null_chk( Rval,strip  ); // NULLs are always safe to store

  pre_write_barrier_compiled(RInOuts::a, Rtmp0, Rtmp1,
                             RKeepIns::a, Rbase, off, Rindex, scale, Rval,
                             info);

#ifdef ASSERT
  if (RefPoisoning) {
    mov8  (Rtmp1,Rval);  // Save Rval again as it will have been squashed by the barrier
    always_poison(Rval); // Must store poisoned ref
  }
#endif // ASSERT
bind(strip);
  verify_not_null_oop(Rbase, MacroAssembler::OopVerify_StoreBase);
  cvta2va(Rbase);
#ifdef ASSERT
  if (RefPoisoning) {
    poison(Rcmp);      // Compared register must also be posioned
  }
#endif // ASSERT
bind(checked);
  int npe_relpc = rel_pc();
#ifdef ASSERT
  // check the value to be cas-ed is an oop, npe on this rather than the store
  if (should_verify_oop(MacroAssembler::OopVerify_OverWrittenField))
    npe_relpc = verify_oop (Rbase, off, Rindex, scale, MacroAssembler::OopVerify_OverWrittenField);
#endif
  if (Rindex == noreg) locked()->cas8 (Rbase, off, Rval);
  else                 locked()->cas8 (Rbase, off, Rindex, scale, Rval);
#ifdef ASSERT
  pushf();
  if (RefPoisoning) {
    mov8    (Rval,Rtmp1); // Restore unpoisoned Rval
    unpoison(Rcmp);       // Compared register must also be unposioned
  }
  verify_oop(Rval, MacroAssembler::OopVerify_Move);
  verify_oop(Rcmp, MacroAssembler::OopVerify_Move);
  popf();
#endif
  return npe_relpc;
}
Exemple #4
0
int nextfile(void)
{
	char *p;

n0:
	if (ifile != stdin)
		fclose(ifile);
	if (ifi > 0 && !nx) {
		if (popf())
			goto n0; /* popf error */
		return(1);	 /* popf ok */
	}
	if (nx || nmfi < mflg) {
		p = mfiles[nmfi++];
		if (*p != 0)
			goto n1;
	}
	if (rargc-- <= 0) {
		if ((nfo -= mflg) && !stdi) {
			done(0);
}
		nfo++;
		numtabp[CD].val = stdi = mflg = 0;
		ifile = stdin;
		strcpy(cfname[ifi], "stdin");
		return(0);
	}
	p = (argp++)[0];
	if (rargc >= 0)
		cfname[ifi][0] = 0;
n1:
	numtabp[CD].val = 0;
	if (p[0] == '-' && p[1] == 0) {
		ifile = stdin;
		strcpy(cfname[ifi], "stdin");
	} else if ((ifile = fopen(p, "r")) == NULL) {
		ERROR "cannot open file %s", p WARN;
		nfo -= mflg;
		done(02);
	} else
		strcpy(cfname[ifi],p);
	nfo++;
	return(0);
}
Exemple #5
0
extern VOID far ClkInter_( VOID )
{
    pushf();
    ClkInter();
    popf();
}
Exemple #6
0
	void ExecFrame::execute_ops(int num)
	{
		int opcode, param;
		floatval fa,fb;
		int ia, ib, ifor, iparam, ijmp;
		//char opfor,pfor;
		Vec2 *v1,*v2;
		Vec2 v;
		VMInterface* obj;
		ExecFrame* frame;
		CodeObj* cobj;
		
		while(num-- != 0)
		{
			opcode = (int)code->code[iptr++];
			param = (int)code->code[iptr++];
			
			//std::cout << opcode << ':' << param << std::endl;
			
			switch(opcode) {
				case OPC_EXIT:
					iptr-=2;
					return;
				case OPC_VMCALL:
					cobj = (CodeObj*)popp();
					ia = popi();
					frame = new ExecFrame(cobj);
					frame->restart();
					if (param > 0) move(param, frame);
					frame->execute();
					if (ia > 0) frame->move(ia, this);
					delete frame;
					break;
			    case OPC_CONSTF:
			    	pushf(code->conarray_f[param]);
			        break;
			    case OPC_CONSTI:
			        pushi(code->conarray_i[param]);
			        break;
			    case OPC_CONSTV:
			    	pushv(code->conarray_v[param]);
			        break;
			    case OPC_CONSTP:
			    	pushp(code->conarray_p[param]);
			    	break;
			    case OPC_PUSHVARF:
			        pushf(vararray_f[param]);
			        break;
			    case OPC_PUSHVARI:
			        pushi(vararray_i[param]);
			        break;
			    case OPC_PUSHVARV:
			        pushv(vararray_v[param]);
			        break;
			    case OPC_PUSHVARP:
			        pushp(vararray_p[param]);
			        break;
				case OPC_POP:
					top -= param;
					break;
			    case OPC_SETVARF:
			        vararray_f[param] = popf();
			        break;
			    case OPC_SETVARI:
			        vararray_i[param] = popi();
			        break;
			    case OPC_SETVARV:
			    	fb = popf();
			    	fa = popf();
			        vararray_v[param].set(fa,fb);
			        break;
			    case OPC_SETVARP:
			        vararray_p[param] = popp();
			        break;
			    case OPC_GETPROP:
			        obj = (VMInterface*)popp();
			        obj->VM_GetProp(this, param);
			        break;
			    case OPC_SETPROP:
			        obj = (VMInterface*)popp();
			        obj->VM_SetProp(this, param);
			        break;
			    case OPC_METCALL:
			        obj = (VMInterface*)popp();
			        obj->VM_MetCall(this, param);
			        break;
			    case OPC_GETPROPV:
			        v1 = (Vec2*)popp();
			        v1->VM_GetProp(this, param);
			        break;
			    case OPC_SETPROPV:		    
			        v1 = (Vec2*)popp();
			        v1->VM_SetProp(this, param);
			        break;
			    case OPC_METCALLV:
			        v1 = (Vec2*)popp();
			        v1->VM_MetCall(this, param);
			        break;
			    case OPC_JUMP:
			        iptr += param*2;
			        break;
			    case OPC_IFJUMP:
			        ia = popi();
			        if (ia == 0) iptr += param*2;
			        break;
			    case OPC_INITFOR:
			        ib = popi();
			        ia = popi();
			        ++iptr;
			        iparam = code->code[iptr++];
			        ijmp = iptr;
			        for(ifor=ia;ifor<ib;++ifor)
			        {
			        	iptr = ijmp;
			        	vararray_i[param] = ifor;
			        	execute_ops(iparam);
			        	/*for(iptr=ijmp;iptr<ijmp+iparam*2;++iptr)
			        	{
					        opfor = code->code[iptr];
					        pfor = code->code[++iptr];
					        if (opfor == OPC_EXIT)
					        {
					        	--iptr;
					        	return;
					        }
			        		execute_op(opfor, pfor);
			        	}*/
			        	 
			        }
			        break;
			    case OPC_LOOP:
			        ; // TODO
			        break;
			    case OPC_I2F:
			    //  this will break is floatval uses doubles !!
			    /*    ia = *((int*)top);
			        *((floatval*)top) = (float)ia;*/
			        ia = popi();
			        pushf((floatval)ia);		        
			        break;
			    case OPC_F2I:
			        /*fa = *((floatval*)top);
			        *((int*)top) = (int)fa;*/
			        fa = popf();
			        pushi((int)fa);		        
			        break;
			    case OPC_VEC2P:
			    	fb = popf();
			    	fa = popf();
			    	v1 = vectemp + (vecidx % 5);
			    	++vecidx;
			    	v1->set(fa,fb);
			    	pushp(v1);
			    	break;
			    case OPC_P2VEC:
			    	v1 = popv();
			    	pushv(*v1);
			    	break;
			    case OPC_LASTVEC:
			    	v1 = vectemp + ((vecidx-1)%5);
			    	pushv(*v1);
			    	break;
			        
		// --------------------------------------------------
		// -------------------- OPERATORS -------------------
		// --------------------------------------------------		        
			        
			    case OPC_OP_ADDFF:
			    	fa = popf();
			        *(((floatval*)top)-1) += fa;
			        break;
			    case OPC_OP_ADDII:
			    	ia = popi();
			        *(((int*)top)-1) += ia;
			        break;
			    case OPC_OP_ADDVV:
			        v2 = popv();
			        v1 = popv();
			        v.set(*v1);
			        v.add(*v2);
			        pushv(v);
			        break;
			    case OPC_OP_ANDBB:
			        ib = popi();
			        ia = popi();
			        pushi(ia & ib);
			        break;
			    case OPC_OP_DIVFF:
			    	fa = popf();
			        *(((floatval*)top)-1) /= fa;
			        break;
			    case OPC_OP_DIVII:
			    	ia = popi();
			        *(((int*)top)-1) /= ia;
			        break;
			    case OPC_OP_DIVVF:
			        fa = popf();
			        v1 = (Vec2*)popp();
			        v.set(*v1);
			        v.div(fa);
			        pushv(v);
			        break;
			    case OPC_OP_EQFF:
			        fb = popf();
			        fa = popf();
			        pushi((int)(fa == fb));
			        break;
			    case OPC_OP_EQII:
			        ib = popi();
			        ia = popi();
			        pushi((int)(ia == ib));
			        break;
			    case OPC_OP_EQVV:
			        v2 = popv();
			        v1 = popv();
			        pushi((int)(ia == ib));
			        break;
			    case OPC_OP_GEFF:
			        fb = popf();
			        fa = popf();
			        pushi((int)(fa >= fb));
			        break;
			    case OPC_OP_GEII:
			        ib = popi();
			        ia = popi();
			        pushi((int)(ia >= ib));
			        break;
			    case OPC_OP_GTFF:
			        fb = popf();
			        fa = popf();
			        pushi((int)(fa > fb));
			        break;
			    case OPC_OP_GTII:
			        ib = popi();
			        ia = popi();
			        pushi((int)(ia > ib));
			        break;
			    case OPC_OP_LEFF:
			        fb = popf();
			        fa = popf();
			        pushi((int)(fa <= fb));
			        break;
			    case OPC_OP_LEII:
			        ib = popi();
			        ia = popi();
			        pushi((int)(ia <= ib));
			        break;
			    case OPC_OP_LTFF:
			        fb = popf();
			        fa = popf();
			        pushi((int)(fa < fb));
			        break;
			    case OPC_OP_LTII:
			        ib = popi();
			        ia = popi();
			        pushi((int)(ia < ib));
			        break;
			    case OPC_OP_MULFF:
			    	fa = popf();
			        *(((floatval*)top)-1) *= fa;
			        break;
			    case OPC_OP_MULII:
			    	ia = popi();
			        *(((int*)top)-1) *= ia;
			        break;
			    case OPC_OP_MULVF:
			        fa = popf();
			        v1 = popv();
			        v.set(*v1);
			        v.mul(fa);
			        pushv(v);
			        break;
			    case OPC_OP_NEFF:
			        fb = popf();
			        fa = popf();
			        pushi((int)(fa != fb));
			        break;
			    case OPC_OP_NEGF:
			        *(((floatval*)top)-1) = -(*((floatval*)top));
			        break;
			    case OPC_OP_NEGI:
			        *(((int*)top)-1) = -(*((int*)top));
			        break;
			    case OPC_OP_NEGV:
			        v1 = popv();
			        v.set(-v1->x, -v1->y);
			        pushv(v);
			        break;
			    case OPC_OP_NEII:
			        ib = popi();
			        ia = popi();
			        pushi((int)(ia != ib));
			        break;
			    case OPC_OP_NEVV:
			        v2 = popv();
			        v1 = popv();
			        pushi((int)(ia != ib));
			        break;
			    case OPC_OP_NOTBB:
			        ; // TODO
			        break;
			    case OPC_OP_ORBB:
			        ; // TODO
			        break;
			    case OPC_OP_SUBFF:
			    	fa = popf();
			        *(((floatval*)top)-1) -= fa;
			        break;
			    case OPC_OP_SUBII:
			    	ia = popi();
			        *(((int*)top)-1) -= ia;
			        break;
			    case OPC_OP_SUBVV:
			        v2 = (Vec2*)popp();
			        v1 = (Vec2*)popp();
			        v.set(*v1);
			        v.sub(*v2);
			        pushv(v);
			        break;
			    case OPC_OP_XORBB:
			        ; // TODO
			        break;
			}
		}
	}
double_buffer( InfoStruct *recInfo, float *leadSnds[], float *lagSnds[], float *locations, float *azimuths, float *rove, float *scalesLead, float *scalesLag, float *attensLead, int nSignal )
{
FILE	*fptr;
long	seekpos = 0;
float	preloadScale = .2;
int		i, j;

char	OutFNA [MAX_FILENAME_LEN];
char	OutFNB [MAX_FILENAME_LEN];

float	temp;

int		record = recInfo->record;
int		cnt = 1;

unsigned int DEC_FACT = recInfo->decimateFactor;
unsigned int SignalPlayFlag = 0;
unsigned int signalScale = 0, Signalcnt = 0, readflag = 0;
unsigned int MAX_SIGNAL_JITTER = recInfo->max_signal_jitter;
unsigned int NUM_CARRIERS_TO_ROVE = recInfo->num_carriers;
unsigned int rove_id;
unsigned int TRIALS_TO_SHOW = 3;

long	NPTS = recInfo->buf_pts;

/* just for plotting PDR trace in real time */
long	DEC_PTS = ceil(NPTS / pow(2, DEC_FACT));
long	ONSET = ceil(recInfo->sound_onset / pow(2, DEC_FACT));
long	NPTS_totalplay = recInfo->nptsTotalPlay;
long	templ;
long	buffer_cnt=0;
float	HAB_LOC = recInfo->hab_loc;

int		src[3];
float	sf[3];

div_t	div_result;

int		loc;

/* Display output variables: */
int     t0,t1, n;
float	elapsed_time;
float	rem_time;
int		min;
float	sec, cntdown;
char	str[100] = { '\0' };
float	pdrBuffer[DEFAULT_PTS];
int		len;
float	xy[2];

/* select SS1 output */
int		ss_id, out_port;

srand( (unsigned)time( NULL ) );

/* setup session info display */
len = ceil(NPTS * (SRATE/1E3));

// was commented out - put back in on Sep 14, 2009
if (record)
{
	play0_record0(recInfo->outFN1, recInfo->outFN2);
	remove(recInfo->outFN1);
	remove(recInfo->outFN2);
	//remove(recInfo->AD_FN);
}
// end comment out


if(!S2init(0, INIT_SECONDARY, 20000))
	mexErrMsgTxt("S2init failed");

if(!APlock(200, 0))
{
	S2close();
	mexErrMsgTxt("APLock failed");
}

if(!XBlock(200, 0))
{
	APunlock(0);
	S2close();
	mexErrMsgTxt("XBlock failed");
}

trash();
dropall();

// set up buffers
allot16( PLAY_SPEC, 10);
allot16( CHA_SEQ, 10);
allot16( BUF_A1, NPTS);
allot16( BUF_A2, NPTS);
allot16( CHB_SEQ, 10);
allot16( BUF_B1, NPTS);
allot16( BUF_B2, NPTS);

// play specification list
dpush(10);
value(0);
make(0,CHA_SEQ);
make(1,CHB_SEQ);
make(2,0);
qpop16(PLAY_SPEC);

// playsequence for ChanA
dpush(10);
value(0);
make(0,BUF_A1);
make(1,1);
make(2,BUF_A2);
make(3,1);
make(4,0);
qpop16(CHA_SEQ);
// playsequence for ChanB
dpush(10);
value(0);
make(0,BUF_B1);
make(1,1);
make(2,BUF_B2);
make(3,1);
make(4,0);
qpop16(CHB_SEQ);


if (record)			// record eye signal
{
	// set up buffers
	allot16( REC_SPEC, 10);
	allot16( RECCHA_SEQ, 10);
	allot16( RECBUF_A1, NPTS);
	allot16( RECBUF_A2, NPTS);
	allot16( RECCHB_SEQ, 10);
	allot16( RECBUF_B1, NPTS);
	allot16( RECBUF_B2, NPTS);

	temp = ceil(NPTS / pow(2, DEC_FACT));
	allot16( DECBUF_A, temp);
	allot16( DECBUF_B, temp);

	// record specification list
	dpush(10);
	value(0);
	make(0,RECCHA_SEQ);
	make(1,RECCHB_SEQ);
	make(2,0);
	qpop16(REC_SPEC);

	// recordsequence for ChanA
	dpush(10);
	value(0);
	make(0,RECBUF_A1);
	make(1,1);
	make(2,RECBUF_A2);
	make(3,1);
	make(4,0);
	qpop16(RECCHA_SEQ);
	// recordsequence for ChanB
	dpush(10);
	value(0);
	make(0,RECBUF_B1);
	make(1,1);
	make(2,RECBUF_B2);
	make(3,1);
	make(4,0);
	qpop16(RECCHB_SEQ);
}

// allot and load buffers for LEAD SOUNDS
for( j=0; j<NUM_CARRIERS_TO_ROVE; j++ ) {
	allotf( BUF_LEAD(j), NPTS);
	pushf(leadSnds[j], NPTS);
	qpopf(BUF_LEAD(j));
}

// allot and load buffers for LAG SOUNDS
for( j=0; j<NUM_CARRIERS_TO_ROVE; j++ ) {
	allotf( BUF_LAG(j), NPTS);
	pushf(lagSnds[j], NPTS);
	qpopf(BUF_LAG(j));
}

// setup PD1
PD1clear(1);
PD1srate(1,SRATE);
PD1npts(1,-1);

PD1resetDSP(1,0xFFF);
dropall();
PD1clrsched(1);
PD1nstrms(1, 2, record*2);

PD1addsimp(1, IREG[0], DAC[0]);  
PD1specIB (1, IB[0],   IREG[0]);

PD1addsimp(1, IREG[1], DAC[1]);  
PD1specIB (1, IB[1],   IREG[1]);

if (record)
{
	PD1specOB (1, OB[1], ADC[1]);
	PD1specOB (1, OB[0], ADC[0]);
}

PF1freq(1,12000,0);
PF1freq(2,12000,0);

dropall();

/* set LED thresholds */
PD1setIO(1,0.01,9.99,0.01,9.99);

/* setup signal switchers */

/* SWITCH BETWEEN 8 LAG SPEAKERS (Nos. 2, 3, 4, ... 9) */
/* (NOTE: Speaker #1 is reserved for the lead sound) */

SS1clear(1); /* left SS1 (LAG) */
SS1mode(1, QUAD_2_1); /* inputs 1, 3, 5, 7 => outputs A,B,C,D */
SS1select(1,0,1); /* Default Lag Output is A (Hab Location) */

// set attenuation
PA4atten(1,0); /* lead channel */
PA4atten(2,0); /* lag ch */

// ready,set,go!!
dropall();

// nothing to chanA (LEAD)
dpush(NPTS);
value(0);
qpop16(BUF_A1);

dpush(NPTS);
value(0);
qpop16(BUF_A2);
		
// nothing to chanB (LAG)
dpush(NPTS);
value(0);
qpop16(BUF_B1);
				
dpush(NPTS);
value(0);
qpop16(BUF_B2);				
			
seqplay(PLAY_SPEC);
if (record)
	seqrecord(REC_SPEC);
		
PD1arm (1);
pfireall();
PD1go (1);

do
{
 	do{}while (playseg(1)==BUF_A1);		// wait for #1 buffers to finish
	
	t0 = clock();

	SignalPlayFlag = 0;

	if(signalScale >0)
	{
		readflag = 1;
	}
	else if(readflag)
	{
		readflag = 0;
		SignalPlayFlag = 1;
	}
	

	
	/* count down to next test trial */
	cntdown = (recInfo->ISI - cnt)*(NPTS*SRATE/1E6);
	for(i=0; i<(recInfo->n_trials - Signalcnt); i++) {
		if(locations[Signalcnt+i]!=HAB_LOC)
			break;
		cntdown += (recInfo->ISI+1)*(NPTS*SRATE/1E6);

	}
		
		
	/* display session info */
	
	elapsed_time = seekpos*(SRATE/1E6);
	div_result = div( elapsed_time, 60 );
	min = div_result.quot; sec = elapsed_time - (60*min);
	memset(str,'\0',sizeof(str));
	n=sprintf(str,"session.elapsed_time(1)=%i; session.elapsed_time(2)=%.3f;",min,sec);
	mexEvalString(str);
	rem_time = NPTS_totalplay*(SRATE/1E6) - elapsed_time;
	div_result = div( rem_time, 60 );
	min = div_result.quot; sec = rem_time - (60*min);
	memset(str,'\0',sizeof(str));
	n=sprintf(str,"session.rem_time(1)=%i; session.rem_time(2)=%.3f;",min,sec);
	mexEvalString(str);
	div_result = div( cntdown, 60 );
	min = div_result.quot; sec = cntdown - (60*min);
	memset(str,'\0',sizeof(str));
	n=sprintf(str,"session.next_test_trial(1)=%i; session.next_test_trial(2)=%.3f;",min,sec);
	mexEvalString(str);
	mexEvalString("sessionPlots('Update Session Info');");
	
	
	// re-loading #1 playbuffers
	// LEAD to chanA LAG to chanB
	dropall();
	if (cnt==recInfo->ISI)
	{
		// Jitter trial presentation
		if (MAX_SIGNAL_JITTER > 0)
		{
			cnt = ( rand() % (2*MAX_SIGNAL_JITTER+1) ) - MAX_SIGNAL_JITTER; // gives a range of +/- MAX_SIGNAL_JITTER
		} else
		{
			cnt = 0;
		}
		

		loc = locations[Signalcnt];
		/* location series indicates lag speaker # (2, 3, 4, ... 9) */

	
		// set attenuation
		PA4atten(1,attensLead[loc-2]); /* lead channel */
		PA4atten(2,0); /* lag ch */

		SS1clear(1); SS1clear(2);
		if (loc < 6) {
			ss_id = 1; /* use left SS1 */
			out_port = loc - 2; /* decrement by 2 for output selection */
		}
		else {
			ss_id = 2; /* use right SS1 */
			out_port = loc - 6; /* decrement by 6 for output selection */
		}
		
		SS1mode(ss_id, QUAD_2_1); /* inputs 1, 3, 5, 7 => outputs A,B,C,D */
		SS1select(ss_id,out_port,1); /* Chan B (LAG) location ( speakers A...D = 0...3 ) */


		
		/* plot a marker on trial sequence plot */
		memset(str,'\0',sizeof(str));
		n=sprintf(str,"session.trialcnt=%i; session.trialval=%10.1f;sessionPlots('Update Trial Plot');",Signalcnt+1,azimuths[loc-1]);
		mexEvalString(str);
		
		
		rove_id = rove[Signalcnt ++] - 1; /* decrement by 1 for C indexing */
		
		signalScale=scalesLead[loc-2];
		qpushf(BUF_LEAD(rove_id));
		scale(signalScale); /* always scale with first speaker scaling value */
		qpop16(BUF_A1);	

		signalScale=scalesLag[loc-2];
		qpushf(BUF_LAG(rove_id));
		scale(signalScale); /* decrement by 1 to get appropriate speaker scale value */
		qpop16(BUF_B1);

	}
	else
	{
		signalScale = 0;
		cnt++;
		dpush(NPTS);
		value(0);
		qpop16(BUF_A1);

		dpush(NPTS);
		value(0);
		qpop16(BUF_B1);	
	}

	
	if(record)
	{		// downloading  #1 recordbuffers
		qpush16 (RECBUF_A1);    
		decimate (DEC_FACT);
		make(0, SignalPlayFlag);
		make(1, loc);
		qpop16   (DECBUF_A);
		dama2disk16 (DECBUF_A, recInfo->outFN1, 1);

		qpush16 (RECBUF_B1);
		decimate (DEC_FACT);
		// plot PDR trace
		qdup();
		popf(pdrBuffer);
		// store last buffer in matlab variable for plotting
		for(i=0; i<DEC_PTS; i++) {
			memset(str,'\0',sizeof(str));
			n=sprintf(str,"session.last_buffer(%i+1)= %.5f;",i,pdrBuffer[i]);
			mexEvalString(str);
		}
		
		if(SignalPlayFlag) {
			if(locations[Signalcnt-1]==HAB_LOC) {
				mexEvalString("session.test_flag=1;");
			}
			else {
				mexEvalString("session.test_flag=Inf;");
			}
		}
		else {
			mexEvalString("session.test_flag=0;");
		}
		
		// tell sessionPlots to update trace
		mexEvalString("sessionPlots('Update Trace Plot');");
		make(0, SignalPlayFlag);
		make(1, loc);
		qpop16   (DECBUF_B);
		dama2disk16 (DECBUF_B, recInfo->outFN2, 1);
		dropall ();
		
	}
	
	/* processing time */
	
	t1=clock();
	memset(str,'\0',sizeof(str));
	n = sprintf(str,"session.proc_time = [session.proc_time %.3f];",((float) (t1-t0))/CLOCKS_PER_SEC);
	mexEvalString(str);
	mexEvalString("sessionPlots('Update Session Info');");
	
	seekpos += NPTS;
	if(seekpos < NPTS_totalplay)
	{
		// wait for #2 buffers to finish
		do{}while (playseg(1)==BUF_A2);		// wait for #2 buffers to finish

     	t0=clock();
     	
		SignalPlayFlag = 0;
	
		if(signalScale >0)
		{
			readflag = 1;
		}
		else if(readflag)
		{
			readflag = 0;
			SignalPlayFlag = 1;
		}
		
	/* count down to next test trial */
	cntdown = (recInfo->ISI - cnt)*(NPTS*SRATE/1E6);
	for(i=0; i<(recInfo->n_trials - Signalcnt); i++) {
		if(locations[Signalcnt+i]!=HAB_LOC)
			break;
		cntdown += (recInfo->ISI+1)*(NPTS*SRATE/1E6);

	}
		
		
	/* display session info */
	
	elapsed_time = seekpos*(SRATE/1E6);
	div_result = div( elapsed_time, 60 );
	min = div_result.quot; sec = elapsed_time - (60*min);
	memset(str,'\0',sizeof(str));
	n=sprintf(str,"session.elapsed_time(1)=%i; session.elapsed_time(2)=%.3f;",min,sec);
	mexEvalString(str);
	rem_time = NPTS_totalplay*(SRATE/1E6) - elapsed_time;
	div_result = div( rem_time, 60 );
	min = div_result.quot; sec = rem_time - (60*min);
	memset(str,'\0',sizeof(str));
	n=sprintf(str,"session.rem_time(1)=%i; session.rem_time(2)=%.3f;",min,sec);
	mexEvalString(str);
	div_result = div( cntdown, 60 );
	min = div_result.quot; sec = cntdown - (60*min);
	memset(str,'\0',sizeof(str));
	n=sprintf(str,"session.next_test_trial(1)=%i; session.next_test_trial(2)=%.3f;",min,sec);
	mexEvalString(str);
	mexEvalString("sessionPlots('Update Session Info');");

		// reload #2 playbuffers    LEAD to chanA LAG to chanB
		dropall();
		if (cnt==recInfo->ISI)
		{
			if (MAX_SIGNAL_JITTER > 0)
			{
				cnt = ( rand() % (2*MAX_SIGNAL_JITTER+1) ) - MAX_SIGNAL_JITTER; // gives a range of +/- MAX_SIGNAL_JITTER
			} else
			{
				cnt = 0;
			}
			
			loc = locations[Signalcnt];
			/* location series indicates lag speaker # (2, 3, 4, ... 9) */
	
			// set attenuation
			PA4atten(1,attensLead[loc-2]); /* lead channel */
			PA4atten(2,0); /* lag ch */
			
			SS1clear(1); SS1clear(2);
			if (loc < 6) {
				ss_id = 1; /* use left SS1 */
				out_port = loc - 2; /* decrement by 2 for output selection */
			}
			else {
				ss_id = 2; /* use right SS1 */
				out_port = loc - 6; /* decrement by 6 for output selection */
			}
		
			SS1mode(ss_id, QUAD_2_1); /* inputs 1, 3, 5, 7 => outputs A,B,C,D */
			SS1select(ss_id,out_port,1); /* Chan B (LAG) location ( speakers A...D = 0...3 ) */
		
			/* plot a marker on trial sequence plot */
			memset(str,'\0',sizeof(str));
			n=sprintf(str,"session.trialcnt=%i; session.trialval=%10.1f;sessionPlots('Update Trial Plot');",Signalcnt+1,azimuths[loc-1]);
			mexEvalString(str);

			rove_id = rove[Signalcnt ++] - 1; /* decrement by 1 for C indexing */
			
			signalScale=scalesLead[loc-2];
			qpushf(BUF_LEAD(rove_id));
			scale(signalScale); /* always scale with first speaker scaling value */
			qpop16(BUF_A2);	
	
			signalScale=scalesLag[loc-2];
			qpushf(BUF_LAG(rove_id));
			scale(signalScale); /* decrement by 1 to get appropriate speaker scale value */
			qpop16(BUF_B2);

		}
		else
		{
			signalScale = 0;
			cnt++;
			dpush(NPTS);
			value(0);;
			qpop16(BUF_A2);

			dpush(NPTS);
			value(0);
			qpop16(BUF_B2);
		}
		
		
		if (record)
		{		// download #2 recordbuffers
			qpush16 (RECBUF_A2);    
			decimate (DEC_FACT);
			make(0,SignalPlayFlag);
			make(1,loc);
			qpop16	(DECBUF_A);
			dama2disk16 (DECBUF_A, recInfo->outFN1, 1);

			qpush16 (RECBUF_B2);
			decimate (DEC_FACT);
			// plot PDR trace
			qdup();
			popf(pdrBuffer);
			// store last buffer in matlab variable for plotting
			for(i=0; i<DEC_PTS; i++) {
				memset(str,'\0',sizeof(str));
				n=sprintf(str,"session.last_buffer(%i+1)= %.5f;",i,pdrBuffer[i]);
				mexEvalString(str);
			}

			if(SignalPlayFlag) {
				if(locations[Signalcnt-1]==HAB_LOC) {
					mexEvalString("session.test_flag=1;");
				}
				else {
					mexEvalString("session.test_flag=Inf;");
				}
			}
			else {
				mexEvalString("session.test_flag=0;");
			}

			// tell sessionPlots to update trace
			mexEvalString("sessionPlots('Update Trace Plot');");
			make(0,SignalPlayFlag);
			make(1,loc);
			qpop16   (DECBUF_B);
			dama2disk16 (DECBUF_B, recInfo->outFN2, 1);
			dropall ();
		
		}

		if (playseg(1) !=BUF_A1)
		{
			PD1stop(1);
			mexPrintf("got to %d percent of the way\n",seekpos/NPTS_totalplay);
			mexErrMsgTxt(" APcard too slow? or outFNs incorrect?");
		}

		/* processing time */
	
		t1=clock();
		memset(str,'\0',sizeof(str));
		n = sprintf(str,"session.proc_time = [session.proc_time %.3f];",((float) (t1-t0))/CLOCKS_PER_SEC);
		mexEvalString(str);
		mexEvalString("sessionPlots('Update Session Info');");
		
	    seekpos += NPTS;
	}
	if (Signalcnt > nSignal)
		Signalcnt = 0;

} while(seekpos < NPTS_totalplay);

do{}while (playseg(1)==BUF_A1);		/* wait for last 2 buffers to finish */
do{}while (playseg(1)==BUF_A2);



PA4mute(1);
PA4mute(2);

PD1stop(1);
PD1clrIO(1);
PD1clear(1);

mexEvalString("sessionPlots('Finish Session');");

trash();
dropall();

APunlock(0);
XBunlock(0);
S2close();

}
    address generate_getPsrInfo() {
        // Flags to test CPU type.
        const uint32_t HS_EFL_AC           = 0x40000;
        const uint32_t HS_EFL_ID           = 0x200000;
        // Values for when we don't have a CPUID instruction.
        const int      CPU_FAMILY_SHIFT = 8;
        const uint32_t CPU_FAMILY_386   = (3 << CPU_FAMILY_SHIFT);
        const uint32_t CPU_FAMILY_486   = (4 << CPU_FAMILY_SHIFT);

        Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4;
        Label sef_cpuid, ext_cpuid, ext_cpuid1, ext_cpuid5, ext_cpuid7, done;

        StubCodeMark mark(this, "VM_Version", "getPsrInfo_stub");
#   define __ _masm->

        address start = __ pc();

        //
        // void getPsrInfo(VM_Version::CpuidInfo* cpuid_info);
        //
        // LP64: rcx and rdx are first and second argument registers on windows

        __ push(rbp);
#ifdef _LP64
        __ mov(rbp, c_rarg0); // cpuid_info address
#else
        __ movptr(rbp, Address(rsp, 8)); // cpuid_info address
#endif
        __ push(rbx);
        __ push(rsi);
        __ pushf();          // preserve rbx, and flags
        __ pop(rax);
        __ push(rax);
        __ mov(rcx, rax);
        //
        // if we are unable to change the AC flag, we have a 386
        //
        __ xorl(rax, HS_EFL_AC);
        __ push(rax);
        __ popf();
        __ pushf();
        __ pop(rax);
        __ cmpptr(rax, rcx);
        __ jccb(Assembler::notEqual, detect_486);

        __ movl(rax, CPU_FAMILY_386);
        __ movl(Address(rbp, in_bytes(VM_Version::std_cpuid1_offset())), rax);
        __ jmp(done);

        //
        // If we are unable to change the ID flag, we have a 486 which does
        // not support the "cpuid" instruction.
        //
        __ bind(detect_486);
        __ mov(rax, rcx);
        __ xorl(rax, HS_EFL_ID);
        __ push(rax);
        __ popf();
        __ pushf();
        __ pop(rax);
        __ cmpptr(rcx, rax);
        __ jccb(Assembler::notEqual, detect_586);

        __ bind(cpu486);
        __ movl(rax, CPU_FAMILY_486);
        __ movl(Address(rbp, in_bytes(VM_Version::std_cpuid1_offset())), rax);
        __ jmp(done);

        //
        // At this point, we have a chip which supports the "cpuid" instruction
        //
        __ bind(detect_586);
        __ xorl(rax, rax);
        __ cpuid();
        __ orl(rax, rax);
        __ jcc(Assembler::equal, cpu486);   // if cpuid doesn't support an input
        // value of at least 1, we give up and
        // assume a 486
        __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset())));
        __ movl(Address(rsi, 0), rax);
        __ movl(Address(rsi, 4), rbx);
        __ movl(Address(rsi, 8), rcx);
        __ movl(Address(rsi,12), rdx);

        __ cmpl(rax, 0xa);                  // Is cpuid(0xB) supported?
        __ jccb(Assembler::belowEqual, std_cpuid4);

        //
        // cpuid(0xB) Processor Topology
        //
        __ movl(rax, 0xb);
        __ xorl(rcx, rcx);   // Threads level
        __ cpuid();

        __ lea(rsi, Address(rbp, in_bytes(VM_Version::tpl_cpuidB0_offset())));
        __ movl(Address(rsi, 0), rax);
        __ movl(Address(rsi, 4), rbx);
        __ movl(Address(rsi, 8), rcx);
        __ movl(Address(rsi,12), rdx);

        __ movl(rax, 0xb);
        __ movl(rcx, 1);     // Cores level
        __ cpuid();
        __ push(rax);
        __ andl(rax, 0x1f);  // Determine if valid topology level
        __ orl(rax, rbx);    // eax[4:0] | ebx[0:15] == 0 indicates invalid level
        __ andl(rax, 0xffff);
        __ pop(rax);
        __ jccb(Assembler::equal, std_cpuid4);

        __ lea(rsi, Address(rbp, in_bytes(VM_Version::tpl_cpuidB1_offset())));
        __ movl(Address(rsi, 0), rax);
        __ movl(Address(rsi, 4), rbx);
        __ movl(Address(rsi, 8), rcx);
        __ movl(Address(rsi,12), rdx);

        __ movl(rax, 0xb);
        __ movl(rcx, 2);     // Packages level
        __ cpuid();
        __ push(rax);
        __ andl(rax, 0x1f);  // Determine if valid topology level
        __ orl(rax, rbx);    // eax[4:0] | ebx[0:15] == 0 indicates invalid level
        __ andl(rax, 0xffff);
        __ pop(rax);
        __ jccb(Assembler::equal, std_cpuid4);

        __ lea(rsi, Address(rbp, in_bytes(VM_Version::tpl_cpuidB2_offset())));
        __ movl(Address(rsi, 0), rax);
        __ movl(Address(rsi, 4), rbx);
        __ movl(Address(rsi, 8), rcx);
        __ movl(Address(rsi,12), rdx);

        //
        // cpuid(0x4) Deterministic cache params
        //
        __ bind(std_cpuid4);
        __ movl(rax, 4);
        __ cmpl(rax, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); // Is cpuid(0x4) supported?
        __ jccb(Assembler::greater, std_cpuid1);

        __ xorl(rcx, rcx);   // L1 cache
        __ cpuid();
        __ push(rax);
        __ andl(rax, 0x1f);  // Determine if valid cache parameters used
        __ orl(rax, rax);    // eax[4:0] == 0 indicates invalid cache
        __ pop(rax);
        __ jccb(Assembler::equal, std_cpuid1);

        __ lea(rsi, Address(rbp, in_bytes(VM_Version::dcp_cpuid4_offset())));
        __ movl(Address(rsi, 0), rax);
        __ movl(Address(rsi, 4), rbx);
        __ movl(Address(rsi, 8), rcx);
        __ movl(Address(rsi,12), rdx);

        //
        // Standard cpuid(0x1)
        //
        __ bind(std_cpuid1);
        __ movl(rax, 1);
        __ cpuid();
        __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset())));
        __ movl(Address(rsi, 0), rax);
        __ movl(Address(rsi, 4), rbx);
        __ movl(Address(rsi, 8), rcx);
        __ movl(Address(rsi,12), rdx);

        //
        // Check if OS has enabled XGETBV instruction to access XCR0
        // (OSXSAVE feature flag) and CPU supports AVX
        //
        __ andl(rcx, 0x18000000);
        __ cmpl(rcx, 0x18000000);
        __ jccb(Assembler::notEqual, sef_cpuid);

        //
        // XCR0, XFEATURE_ENABLED_MASK register
        //
        __ xorl(rcx, rcx);   // zero for XCR0 register
        __ xgetbv();
        __ lea(rsi, Address(rbp, in_bytes(VM_Version::xem_xcr0_offset())));
        __ movl(Address(rsi, 0), rax);
        __ movl(Address(rsi, 4), rdx);

        //
        // cpuid(0x7) Structured Extended Features
        //
        __ bind(sef_cpuid);
        __ movl(rax, 7);
        __ cmpl(rax, Address(rbp, in_bytes(VM_Version::std_cpuid0_offset()))); // Is cpuid(0x7) supported?
        __ jccb(Assembler::greater, ext_cpuid);

        __ xorl(rcx, rcx);
        __ cpuid();
        __ lea(rsi, Address(rbp, in_bytes(VM_Version::sef_cpuid7_offset())));
        __ movl(Address(rsi, 0), rax);
        __ movl(Address(rsi, 4), rbx);

        //
        // Extended cpuid(0x80000000)
        //
        __ bind(ext_cpuid);
        __ movl(rax, 0x80000000);
        __ cpuid();
        __ cmpl(rax, 0x80000000);     // Is cpuid(0x80000001) supported?
        __ jcc(Assembler::belowEqual, done);
        __ cmpl(rax, 0x80000004);     // Is cpuid(0x80000005) supported?
        __ jccb(Assembler::belowEqual, ext_cpuid1);
        __ cmpl(rax, 0x80000006);     // Is cpuid(0x80000007) supported?
        __ jccb(Assembler::belowEqual, ext_cpuid5);
        __ cmpl(rax, 0x80000007);     // Is cpuid(0x80000008) supported?
        __ jccb(Assembler::belowEqual, ext_cpuid7);
        //
        // Extended cpuid(0x80000008)
        //
        __ movl(rax, 0x80000008);
        __ cpuid();
        __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid8_offset())));
        __ movl(Address(rsi, 0), rax);
        __ movl(Address(rsi, 4), rbx);
        __ movl(Address(rsi, 8), rcx);
        __ movl(Address(rsi,12), rdx);

        //
        // Extended cpuid(0x80000007)
        //
        __ bind(ext_cpuid7);
        __ movl(rax, 0x80000007);
        __ cpuid();
        __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid7_offset())));
        __ movl(Address(rsi, 0), rax);
        __ movl(Address(rsi, 4), rbx);
        __ movl(Address(rsi, 8), rcx);
        __ movl(Address(rsi,12), rdx);

        //
        // Extended cpuid(0x80000005)
        //
        __ bind(ext_cpuid5);
        __ movl(rax, 0x80000005);
        __ cpuid();
        __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid5_offset())));
        __ movl(Address(rsi, 0), rax);
        __ movl(Address(rsi, 4), rbx);
        __ movl(Address(rsi, 8), rcx);
        __ movl(Address(rsi,12), rdx);

        //
        // Extended cpuid(0x80000001)
        //
        __ bind(ext_cpuid1);
        __ movl(rax, 0x80000001);
        __ cpuid();
        __ lea(rsi, Address(rbp, in_bytes(VM_Version::ext_cpuid1_offset())));
        __ movl(Address(rsi, 0), rax);
        __ movl(Address(rsi, 4), rbx);
        __ movl(Address(rsi, 8), rcx);
        __ movl(Address(rsi,12), rdx);

        //
        // return
        //
        __ bind(done);
        __ popf();
        __ pop(rsi);
        __ pop(rbx);
        __ pop(rbp);
        __ ret(0);

#   undef __

        return start;
    };