Firmware Revision 2.06 (14 November 1993)
Manual Revision 1.2 (26 December 1993)
ECBASIC is a very fast experiment control language (it is "pre-compiled"). It provides 1 ms resolution in both program control and data collection, and has many instructions specifically written to make the conduct of research easier. Sample programs can be perused in the Programming with ECBASIC section.
Normally an ECBASIC Experiment Control program is generated with an editor or word processor on the Supervisor machine. In this way, you can take advantage of whatever text manipulation tools are available on your machine. For example, segments of old programs can be used in new programs by cutting and pasting. Many of the advantages of FORTH are available in this way. The resulting file is then saved as a disk file.
Subsequently the control program can be loaded into an Experiment Controller and run whenever it is needed. We provide software for the PC and the Macintosh so that this process is accomplished in essentially the same way that a program is run on the Supervisor machine. Data collection is transparent. Information on the Supervisor computer and network administration software, ExpRun and RBAS, is covered in the networking section of this manual.
This language reference manual is not intended to teach you how to use BASIC. If you are not familiar with BASIC at all, read a book on how to program in BASIC first. Become comfortable solving problems within the confines of the language (it will probably take less than an hour). In that way you will be able to easily imagine how to use various instructions to accomplish what you want to do in your experiment. Then look through this manual to find out how ECBASIC differs from what you know, what additional features ECBASIC provides (especially COUNT, TIME and ONKEY) or exactly how ECBASIC implements a particular instruction. This manual generally presumes that you know which instructions to use to accomplish your task, and therefore provides only format information. This is especially true with respect to the use of expressions. An expression can be used in place of a constant or simple variable to make an instruction very much more powerful. The examples listed typically provide only the simplest implementation of an instruction.
NOTE: The user level is along the right margin of each instruction label. If you are unfamiliar with ECBASIC initially, ignore the intermediate, advanced, and guru instructions. Adding to your vocabulary will make programming easier but you can probably write any experiment control program you want without them.
There are three general types of things that ECBASIC does:
There are two modes these things can be done in:
Program mode commands are used in typical control programs and consist of a line number followed by a valid ECBASIC command. Further information on program mode commands is given later in the manual. Examples would be: (these examples, as examples throughout the manual, are not intended as example programs but rather as examples of single lines of code.)
To be technically correct, there are two additional cases which won't necessarily mean much if you are just starting out.
Functions currently recognized are:
ABS INCH MOD RANGE ADDR INPB PEEK SELECT CHR$ INPW PROB SGN DRAND LINCH RAND TIME FREE
Program mode commands currently recognized are:
ALLOC FREEZE ON GOTO REM BLANK GOSUB ONKEY REPORT CALL GOTO ONNOKEY RESTORE CLEAR HTICK ONTICK RETURN CLICK IF THEN OUTPB SEND CLOCK INPUT OUTPW SLEEP CONFIG LINK POKE STICK COUNT LPRINT PRINT STOP DATA MARKER PULSOFF THAW DIM MONIT PULSON TURNOFF END ON GOSUB READ TURNON FOR/NEXT
System control commands currently recognized are:
ECHO LOAD OFF RUN LIST NEW OFFRUN SAVE LLIST NOECHO QUIT
Commands which can be executed in immediate mode are:
ALLOC LINK OFF QUIT BLANK LIST OFFRUN REPORT CLEAR LLIST OUTPB RUN CONFIG LOAD OUTPW SAVE ECHO LPRINT POKE SLEEP FREEZE MONIT PRINT THAW GOTO NEW PULSOFF TURNOFF INPUT NOECHO PULSON TURNON LET
Variables can be designated with a six character identifier. The first character must be a letter. The final character can be used to designate the type of variable. The variable types are:
! floating point
# double precision
$ string
The remaining characters in a variable name can be either letters or numbers. If the final character does not explicitly designate the variable otherwise, it is assumed to be an integer. If variable names exceed six characters, a syntax error is generated. String variables are not extensively supported.
Arrays can be two dimensional. The maximum array size is governed by the available memory. Keep in mind that the memory necessary to support two dimensional arrays goes up with the "square." The Experiment Controller maxes out with an array of about 150 by 150. Arrays must be explicitly allocated with a DIM statement at the beginning of the program. They are designated as follows:
where - varibl is a valid variable designator
- exprn1 is an expression designating one
dimension, "length"
- exprn2 is an expression designating the
second dimension, "depth"
Arithmetic statements (LET) are expressed in the form:
Only one arithmetic statement is allowed on each line. If the variable has not been previously defined it will be defined by the arithmetic statement. Variables used within an expression must have been previously defined, failure to do so may result in an error. In any arithmetic statement which combines levels of precision, the resulting variable is always forced to the highest level (i.e., promotion).
Real constants (numbers with a decimal point) are presumed to be double precision. Numbers or constants are expressed without embedded commas.
Expressions are used in ECBASIC in order to perform calculations. An expression is an arithmetic combination of one or more variables, constants, or functions. They are very powerful tools and can be used to great advantage to simplify programming. Keep in mind that the argument to any instruction can be a complex expression rather than a simple constant like 6 or 7 or a simple variable like A. Alternatively, the value of a variable can be used in place of any expression by designating a variable name in place of the expression. Parentheses are allowed in an expression and serve to alter or clarify the precedence of the expression.
Arithmetic operators defined are + for addition, - for subtraction, * for multiplication, and / for division. The following table defines the order of precedence used in evaluating expressions:
Order Symbol Remark First () Operations within parenthesis are performed firstSecond NOT Unary not, unary plus, unary minus +- Right association operators Third */ Multiply and divide are of equal precedence Fourth +- Add and subtract are of equal precedence Fifth = <> Comparison operators; equal, not equal < > Less than, greater than <= >= Less than or equal, greater than or equal Sixth AND Logical and Seventh OR Logical or
For example:
A+B*C
Would evaluate to B multiplied by C, with the result added to A
(A+B)*C
Would evaluate to A added to B, with the result multiplied by C
An expression is a "package" of values and operations which specifies some value. The entire package is to be taken together to specify some value such as 10/2 equals 5. For example,
They can be used to set the value of a variable or they can be used as part of a program command. For example,
There are a number of functions built into the ECBASIC interpreter which can be used in expressions. A function is called by using its name followed immediately (no spaces) by parentheses enclosing its arguments. If no arguments are required, the parentheses are empty. If more than one argument is required, the arguments are separated by commas. Arguments to a function can themselves be expressions. The result of the function is the value of that element in the larger expression in which it occurs. As can be seen, expressions can come to "say" a lot. A complex expression can be used any place a constant or variable is used in an expression. The following functions are implemented:
ABS INCH MOD RANGE ADDR INPB PEEK SELECT CHR$ INPW PROB SGN DRAND LINCH RAND TIME FREE
ABS (intermediate)
The ABS function returns the absolute value of its argument. If the argument is positive, the ABS function returns the argument. If the argument is negative, the ABS function returns zero minus the argument. This function returns a value of the same type as its specifying expression. The format of the ABS function is as follows:
where - exprsn is any expression for which the
Example:
999 VARIBL=ABS(B-C)
Stores the absolute difference between B and C into the variable
VARIBL. Note that the expression B-C could be negative, but
the ABS function insures that the value stored in VARIBL is
positive.
ADDR (guru)
The ADDR function returns the physical memory address of the specified variable or array. In the case of an array it is the memory location of the specified array element. It is always evaluated as an integer. The format of the ADDR function is as follows:
where - varibl is the variable for which you want the address
Examples:
999 PRINT ADDR(pecks)
Prints the memory location of the variable "pecks" to the Supervisor computer via the network link.
999 PRINT ADDR(array(1))
Prints the first memory location of the first element in the
array "array" to the Supervisor computer via the network link.
CHR$ (intermediate)
The CHR$ function returns the ASCII character specified by the number given as its argument. It is used to print specific characters or to put specific functions such as "bell" into the print stream.
where - exprsn is the expression which specifies the
desired ASCII character
Examples:
999 PRINT CHR$(9)
Prints a tab (the ASCII value of tab is 9) whenever line 999 is executed.
999 PRINT "*STATUS*"; CHR$(7)
Will operate the beeper on the Macintosh when the Experiment Controller
print buffer is read and the status window is open
(see ExpRun section
of this manual).
DRAND (intermediate)
The DRAND function has no arguments and returns a double precision random number from 0 to 1.0. Other ranges can be obtained by multiplying and adding the appropriate values. The format of the DRAND function is as follows:
where - () is always empty
Example:
999 numb#=DRAND()
Stores a double precision random number from 0 to 1.0 in the double precision variable numb#. Each time line 999 is executed by an ECBASIC program, numb# will be set to a different random number.
FREE (guru)
The FREE function has no arguments and returns the decimal number of bytes of space in memory not currently used by variables or program. This function will give the user an indication of how much more program or variable space can be used. Typically, about 100K of user space is available. It is always evaluated as an integer. The format of the FREE function is as follows:
where - () is always empty
Example:
999 PRINT FREE()
Prints the number of bytes of free space to the Supervisor computer via the network link.
INCH (advanced)
The INCH function does somewhat different things depending on the exact hardware configuration.
The INCH function is primarily for applications based on the IBM PC adaptor board (see ECBasic with IBM PC Adaptor and IBM PC Adaptor). It inputs a single character from the "console" keyboard. Note that the elements are characters not numbers. There is a 140 character buffer. The ASCII value of the keyboard character which was pressed is interpreted as a decimal integer (0 - 255). This function returns a zero if no characters were available (i.e., had been entered). This function allows the researchers to read individual keys without requiring a carriage return. Note that a "Control-S" is trapped by the input routine and cannot be detected with this function, and that a "Control-C" cannot be used because it terminates program execution. Do not confuse this instruction with somewhat similar ones:
where - () is always empty
Example:
999 VARIBL=INCH()
Variable VARIBL is set equal to the decimal value of the next character in the input buffer, e.g., if a SPACE had been pressed the value stored into VARIBL would be 32.
INPB (advanced)
The INPB function inputs a byte from the 16-bit I/O address space. This instruction can be used to directly and explicitly read the state of the inputs (e.g., bird on or off perch). Additionally, it can be used for obtaining data from an SBX board plugged into the Experiment Controller. The binary bit pattern is interpreted as a decimal integer (0 - 255). Input 1 is the low order bit. For example, a value of three would indicate input 1 and 2 were open and inputs 3 through 8 were closed. INPB also works when ECBASIC runs on an IBM/adaptor board configuration. Note that the user must take care of all debouncing with INPB. It is possible that an input state obtained with INPB is a bounce. Do not confuse this instruction with:
where - exprsn is an expression which specifies the
desired I/O address
Examples:
999 VARIBL = INPB(128)
Variable VARIBL is set equal to the decimal value of the bit pattern read from the input port.
Address Function
0 = closed
1 = open
999 VARIBL=INPB(513)
Variable VARIBL is set equal to the decimal value of the character read from the SBX board which responds to address 513.
INPW (guru)
The INPW function inputs a word from the 16-bit I/O address space. This instruction is primarily intended for obtaining data from an SBX board plugged into the Experiment Controller. The value is interpreted as a decimal integer (0 - 255). This function also works when ECBASIC runs on an IBM/adaptor board configuration, however care should be exercised when it is used. Do not confuse this instruction with INPUT. INPW is used to acquire specific information for special purpose programs whereas INPUT is used to enter data. The format of the INPW function is as follows:
where - exprsn is an expression which specifies the desired I/O address
Example:
999 VARIBL=INPW(513)
Variable VARIBL is set equal to the decimal value of the word read from the SBX board which responds to address 513
LINCH (advanced)
The LINCH function inputs a single character from the auxiliary serial port on the Experiment Controller. The auxiliary serial port is fully supported with buffered inputs (140 characters) and outputs (120 characters). The ASCII value of the input is interpreted as a decimal integer (0-255). This function returns a zero if no character had been available. This function allows individual characters from the auxiliary serial line to be read. Do not confuse this instruction with:
where - () is always empty
Example:
999 VARIBL=LINCH()
Variable VARIBL is set equal to the decimal value of the next character in the buffer for the auxiliary serial port on the Experiment Controller.
MOD (intermediate)
The MOD function returns the remainder of the division of its first argument by its second argument. The result of the division is not available. This function is handy when you want to determine whether a number is odd or even or when things are to occur at multiples of some number. It is always interpreted as an integer. The format of the MOD function is as follows:
where - exprn1 is an expression specifying the dividend
- exprn2 is an expression specifying the divisor
Example:
999 VARIBL=MOD(11,5)
Stores a 1 into the variable VARIBL since 5 goes into 11 twice with a remainder of 1.
PEEK (guru)
The PEEK function returns the contents of a specific decimal memory location as a decimal number. The value of the function is between 0 and 255. If memory were 00000000, PEEK would equal 0. If memory were 11111111, the PEEK function would equal 255. It is always interpreted as an integer. The format of the PEEK function is as follows:
where - exprsn is an expression specifying the memory location of interest in decimal
Examples:
999 PRINT PEEK(32268)
Prints the contents of the memory location 32268 to the Supervisor computer through the network link
999 PRINT PEEK(A-B/C)
Prints the contents of the memory location specified by A-B/C to the Supervisor computer via the network link
PROB (intermediate)
The PROB function returns a value of 1 with the probability defined by its argument. The false or "normal" return value is 0. The range of an integer argument is 0 to 1000 where 0 is a probability of 0, and 1000 is a probability of 1. An integer argument of 500 would return a 1, 50% of the time. The integer version of this function is retained for compatibility with earlier systems. If the argument is double precision or floating point, then the probability is the value specified. The format of the PROB function is as follows:
where - exprsn, if integer, is an expression specifying the probability desired * 1000
- exprsn, if not an integer, is the actual probability desired
Example:
999 VARIBL=PROB(250)
Stores a 1 into the variable VARIBL 25 percent of the time line 999 is executed by an ECBASIC program. 75% of the time the line is executed a 0 will be stored in VARIBL.
999 VARIBL=PROB(.25)
Stores a 1 into the variable VARIBL 25 percent of the time line 999 is executed by an ECBASIC program. 75% of the time a 0 will be stored in VARIBL.
RAND (intermediate)
The RAND function has no arguments and returns a random number from 0 to 1000. We took reasonable care to make the random number generator "truly" random, however, in very critical applications the researcher may wish to run a test suit of their own. RAND is always interpreted as an integer. The format of the RAND function is as follows:
where - () is always empty
Example:
999 VARIBL=RAND()
Stores a random number from 0 to 1000 in the variable VARIBL. Each time line 999 is executed by an ECBASIC program VARIBL will be set to a different random number.
RANGE
The RANGE function returns a random number within the range of its two arguments. The first argument is the smallest value allowed for the random number. The second argument is the largest number allowed. The number of values in the desired set can be specified by the range of the arguments to the RANGE function. The magnitude of the values of the desired set can be obtained by using the RANGE function in an expression (e.g., (100*RANGE(4,20)). The value returned is of the same type as its arguments. The format of the RANGE function is as follows:
Example:
999 VARIBL=RANGE(1,5)
Stores a random number into the variable VARIBL. The random number is to be in the range of 1 to 5 inclusive. As illustrated, VARIBL can take on the values 1, 2, 3, 4, or 5. Each time line 999 is executed a different value is stored into variable VARIBL.
999 VARIB#=RANGE(0.0,1.5)
Stores a double precision random number in the variable VARIB#. The random number is to be in the range of 0.0 to 1.5 inclusive. Each time line 999 is executed a different value is stored in variable VARIB#.
SELECT (intermediate)
The SELECT function selects a random element from an array without replacement. It is very much like a "read" statement except that it selects a random element from the "data" statement. It returns a random element from the array specified as its first parameter, and then moves the remainder of the array up filling in the hole. The second parameter is a variable that contains the number of active elements remaining in the array and is decremented by ECBASIC on each call to the function. Note that the program must refill the array when all elements are exhausted. This is not done automatically. The value returned is of the type specified by the array type. The format is as follows:
where - array is the name of a one-dimensional array from which a random element is to be selected. The selected element is removed from the array and the remaining elements are moved up to fill any hole.
Example:
10 DIM A(10) 20 DATA 25,50,75,100,125,150,175,200,225,250 30 RESTORE 20 40 FOR I=1 TO 10 50 READ A(I) 60 NEXT I 70 J=10 80 B=SELECT(A,J) 90 SLEEP B 100 IF J=0 THEN GOTO 30 110 GOTO 80
SGN (intermediate)
The SGN function returns a -1 if its argument is negative, a 0 if its argument is 0, and a 1 if its argument is positive. It is always interpreted as an integer. The format of the SGN function is as follows:
where - exprsn is an expression to be evaluated for its resulting sign
Example:
999 VARIBL=SGN(B-C)
Stores a -1 into the variable VARIBL if the value of variable C variable C is greater than the value of variable B. If variable B is greater than variable C, then a 1 gets stored into VARIBL. If both variables are equal then a 0 is stored into the variable A.
TIME
TIME(X) (read "time since X") is an extremely powerful and convenient way to deal with real time. The TIME function returns the number of 1 millisecond ticks that have occurred since the time specified by its argument. A 32 bit tick counter is started when the Experiment Controller is powered up or reset, and that counter is incremented each millisecond automatically without the experiment control program checking the clock and explicitly updating any timers. There are no missing ticks and no cumulative timing errors. The Experiment Controller can count 1 millisecond ticks for about 8 months before "rollover."
The TIME function provides the program access to that counter. Calling TIME with a zero argument provides the time since Controller reset (e.g., X=TIME(0) sets X equal to the time since the Controller was reset). Since the absolute time is usually not a relevant quantity the TIME function can also be used to return the time from a experiment control program defined reference. Therefore, calling TIME with a 0 argument is typically used only to establish a point of reference for a later TIME call.
TIME(X) can be used in any expression and will be simply interpreted as the time since the time specified by its argument. For example, a variable can be set to the current time (B=TIME(0)), thereby establishing the time that that instruction was executed as a point of reference. Later program flow can be conditionally redirected depending on the time since B. For example if TIME(B) is less than 1000 ticks then do one block of code otherwise do some other block of code. The experiment control program need not explicitly increment any clock. It can therefore execute code while waiting for a particular time.
In the following example, time passes as you move down.
See the programming example section of this document for some example usages of this function. Note that good programming practice always specifies time as a difference. The format of the TIME function is as follows:
where - exprsn is an expression specifying a value to subtract from the current time
Examples:
990 A=TIME(0) Stores the current time (when Line
Later in the program TIME(A) will provide the time since the line "A=TIME(0)" was executed. TIME(A) can be used in any expression.
990 A=TIME(0)
In this case, line 999 is about the same as "SLEEP." However, the end time (i.e., when the test fails and the next line is ) executed) remains constant with respect to the time at line 990, regardless of the time line 999 was first executed (given it was less than 1000 ticks since line 990).
The following section describes the program commands implemented in ECBASIC. The following commands are described:
ALLOC HTICK POKE BLANK IF THEN PRINT CALL INPUT PULSOFF CLEAR LINK PULSON CLICK LPRINT READ/DATA/RESTORE CLOCK MARKER REM CONFIG MONIT REPORT COUNT ON GOSUB SEND DIM ON GOTO SLEEP END ONKEY STICK FOR/NEXT ONNOKEY STOP FREEZE ONTICK THAW GOSUB/RETURN OUTPB TURNOFF GOTO OUTPW TURNON
ALLOC (guru)
The ALLOC instruction reserves a block of memory thus preventing ECBASIC from writing to those locations. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. The format of the ALLOC statement is as follows:
where - LLL is the line number of the ALLOC command
- varibl is the name of the variable into which ECBASIC will deposit the starting address of the allocated block of memory
Example:
999 ALLOC 32256,mem
Allocates 32,256 bytes of memory and specifies that the starting address is to be deposited in the variable labeled mem.
BLANK
BLANK allows ECBASIC to turn off or "blank" all outputs. This instruction is handy for temporary events during which all outputs are to be turned off, such as for reinforcement. This instruction can be used with FREEZE and THAW. (See FREEZE and THAW.) Do not confuse BLANK with CLEAR which already has a meaning in normal BASIC. BLANK can be used in both the program mode and the immediate mode. The format of the BLANK statement is as follows:
where - LLL is the line number of the BLANK command
Example:
999 BLANK
When line 999 is executed all outputs will go off.
CALL (guru)
CALL allows ECBASIC to call a machine language subroutine. Any parameter passing to the routine (in addition to the two specified in the command) or from the machine language subroutine must be done through the use of PEEK and POKE commands to specific locations. Note that the registers must be restored and that a return from subroutine or RET (far return) must be the last line of the machine language routine. (RET will be "returned" as a 203 by the PEEK function.) Further details of machine language programming can be found in support manuals for the 80C188EB or in general 8088/8086 manuals. The format of CALL statement is as follows:
where - LLL is the line number of the CALL command (the exit point)
- exprn2 is an expression which specifies an optional value to be passed to the assembly language subroutine in the AX register
- exprn3 is an expression which specifies an optional value to be passed to the assembly language subroutine in the BX register
Example:
999 CALL 32256,VARIBL,B+C
Calls an assembly language subroutine located at memory location 32256 and passes the contents of variable VARIBL to the AX register and the sum of the variables B and C to the BX register.
CLEAR (guru)
CLEAR allows ECBASIC to clear all variable allocation areas. All variables become undefined and the variable space is set to 0's. This would allow variable names to be redefined and arrays to be redimensioned without using the NEW command to clear the program. CLEAR is an instruction in Traditional BASICs. Its usage is retained for compatibility. Do not confuse CLEAR with BLANK. CLEAR can be used in both the program mode and the immediate mode. The format of the CLEAR statement is as follows:
where - LLL is the line number of the CLEAR command
Example:
999 CLEAR
All variables become undefined and must be explicitly redefined.
CLICK (intermediate)
The CLICK command instructs ECBASIC to automatically and immediately direct a pulse of the specified duration to the specified output every time the specified input occurs. It is therefore useful to drive a feedback click or a cumulative recorder. This pulse output does not require intervention by the experiment control program. Each time the input transitions from its normal state to its operated state the specified output is pulsed. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. All following operations of that input line will be followed with a pulse. The output pulse can be temporarily inhibited by setting the output to number 0 and subsequently restoring it to its original value when you want feedback clicks again. The CLICK instruction can be used only in the program mode and the input being used must have been set up in a COUNT instruction. Note that the pulse cannot occur until after the currently executing ECBASIC instruction terminates and may therefore be delayed by as much as than 10 milliseconds in a conceivable worse case situation. If this is an issue, measure the latency of ECBASIC in that situation and if necessary reposition the instructions which could cause the problem. The format of the CLICK statement is as follows:
where - LLL is the line number of the click command
- exprn2 is the expression which specifies the actual hardware output number (must be between 1 and 44)
- exprn3 is the expression which specifies the duration of the output in milliseconds. Note that this should be less than the maximum input rate, otherwise the output will not go off between inputs.
Example:
10 CLICK 1,40,30
where - 1 is the actual hardware input #1. It could be pigeon Key #1, for example
- 30 is the number of milliseconds that the output will remain on
CLOCK (advanced)
The CLOCK instruction direct ECBASIC to automatically and immediately store the value of the clock into the specified variable whenever the specified input occurs. This instruction is therefore very useful for obtaining IRT data or reaction time data if transparent (event log) recording is not used. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. Each time the input transitions from 0 (normal) to 1 (operated) the specified variable is set equal to the current clock without intervention by the experiment control program. It is the experiment control program's responsibility to read this variable's value before the next response occurs. This instruction must be used early in the program to connect physical keys or levers (inputs (1-8) to variable names. The CLOCK instruction can be used only in the program mode. The format of the CLOCK statement is as follows:
where - LLL is the line number of the clock command
- varibl is the name of the variable to be modified each time a response occurs on that hardware input
Example:
10 CLOCK 1,pecks
where - 1 is the actual hardware input #1. It could be pigeon Key #1, for example.
"Pecks" is subsequently a variable which has a "back door," as well as being accessible by the experiment control program in the usual way. ECBASIC automatically and transparently (without any program steps by the ECBASIC user) sets pecks equal to the current value of the clock through the "backdoor" whenever a response occurs.
CONFIG INPUT
CONFIG INPUT specifies the normal state (closed or open) for each input and specifies the debounce time. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. If the default of normally closed input with a 30 ms debounce arming time is acceptable, a CONFIG INPUT need not be included in a program. The format of the CONFIG INPUT statement is as follows:
where - LLL is the line number of the CONFIG INPUT command
- exprn2 is the expression which specifies
whether the input is to be a normally open or normally closed
switch.
- exprn3 is an optional expression which specifies the number of milliseconds the input must be in its de-operated state before an operation will be recognized. It has a maximum of 255 ms. The default is 30 ms. Note that this "predebounce" or "arming" approach to debouncing allows an interrupt to occur when the response actually occurs, rather than waiting for the debounce time after the behavior occurs.
Example:
999 CONFIG INPUT,3,1,30
Specifies that input 3 is to be considered normally closed and that the debounce time is to be 30 ms.
CONFIG SPORT (advanced)
CONFIG SPORT configures the serial port. It enables the interrupts on the auxiliary serial port and specifies the baud rate for that port. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. The format of the CONFIG SPORT statement is as follows:
where - LLL is the line number of the CONFIG SPORT command
Example:
999 CONFIG SPORT,57600
Turns on the interrupts for the auxiliary serial port and sets the baud rate to 57600.
CONFIG INT2 (guru)
CONFIG INT2 specifies the line number to be executed if interrupt number 2 (M INTR0) from the SBX port occurs. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. Note that the interrupt routine must end with a return. The format of the CONFIG INT2 statement is as follows:
where - LLL is the line number of the CONFIG INT2 command
Example:
999 CONFIG INT2,100
When interrupt 2 from the SBX occurs, program flow immediately and unconditionally jumps to line 100.
CONFIG INT3 (guru)
CONFIG INT3 specifies the line number to be executed if interrupt number 3 (M INTR1) from the SBX port occurs. Note that the interrupt routine must end with a return. The format of the CONFIG INT2 statement is as follows:
where - LLL is the line number of the CONFIG INT3 command
Example:
999 CONFIG INT3,100
When interrupt 3 from the SBX port occurs, program flow immediately and unconditionally jumps to line 100.
COUNT
The COUNT instruction directs ECBASIC to associate an experimental input (typically a response of the subject) with a specified variable. Each time the input transitions from 0 (deactivated) to 1 (operated) the specified variable is incremented. This instruction must be used early in the program to connect physical keys or levers (inputs 1 - 8) to variable names. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. See programming example section for typical usage. The COUNT instruction can be used only in the program mode. Note that an input must be at the 0 (deactivated) state for at least the debounce time specified in the CONFIG INPUT command before a 0 to 1 transition will be recognized. The format of the COUNT statement is as follows:
where - LLL is the line number of the COUNT command
- exprsn is the expression which specifies the hardware input number (must be between 1 and 8)
- varibl is the name of the variable to be incremented each time a response occurs on that hardware input
Example:
10 COUNT 1,pecks
where - 1 is the actual hardware input #1. It could be pigeon Key #1, for example.
The ECBASIC experiment control program need only look at PECKS whenever a decision based on number of responses is necessary. For example,
It is a good practice to never zero the response counter (PECKS in this example). Any value can be obtained by simply using a difference measure. See Programming Example section for typical usage.
DIM
The DIM statement is used in ECBASIC to allocate space for an array. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. Arrays can be two dimensional. ECBASIC has about 100,000 bytes of memory for experiment control program and variables. This translates to a total of 25,000 array locations if the values are simple integers. Two-dimensional arrays are memory intensive. An array of 158 by 158 would use 99,856 locations. The format of the DIM statement is as follows:
where - LLL is the line number of the dimension statement
- exprn1 specifies how many elements are to be in the first array
- exprn2 specifies how many elements deep the first array is to be if a two dimensional array is desired. Brackets are not used.
- varibl2 specifies the name of the second array. Additional variables can be dimensioned provided separators are used. Brackets are not used.
- exprn3 specifies how many elements are to be in the second array.
Examples:
999 DIM A(10)
999 DIM B(10),C(15)
999 DIM D(3,3)
999 DIM E(F-G)
END
The END command terminates program execution without printing a termination message. The END command is equivalent to allowing program flow to pass the highest number statement or flow past the end of the program. The END command can only be used in the program mode and has no meaning in the immediate mode. The format of the END statement is as follows:
where - LLL is the line number of the termination
Example:
999 END
FOR/NEXT
The FOR/NEXT commands define a loop that is to be executed a specified number of times. Note that the variable used to index the loop increments or decrements in the process and can be used for a variety of things. The STEP option specifies by how much the index is to be incremented or decremented on each iteration of the loop. Note that if the index is to be decremented, the target value must be smaller than the start value. The format of the FOR/NEXT statements is as follows:
where - LLL is the line number of the loop start
- varibl is any variable
- exprn1 is an expression which specifies the start of the index counter (target value)
- exprn2 is an expression which specifies the end of the index counter
- exprn3 is an expression which specifies by how much the index is to be incremented or decremented on each loop iteration if other than step size 1 is desired. Brackets are not used.
Examples:
990 FOR I=1 TO 3
990 FOR I=(A-B)/2 TO C STEP 7
FREEZE
FREEZE allows ECBASIC to save the current status of the outputs so that they can be restored later with THAW. The FREEZE, BLANK, and THAW sequence is handy when temporarily jumping to a new condition like reinforcement. This is especially true when the conditions preceding reinforcement vary, are awkward to keep up with, and must be restored when coming out of reinforcement. FREEZE can be used in both the program mode and the immediate mode. The format of the FREEZE statement is as follows:
where - LLL is the line number of the FREEZE instruction
Example:
990 FREEZE 991 BLANK 992 PULSON REIN,40000 993 THAW
This program segment would:
GOSUB/RETURN
The GOSUB/RETURN commands allow the execution of the same block of code from several places in a program. In each case the return statement returns the program flow to the line number following the particular GOSUB which directed it to the subroutine rather than a constant line in the program. The format of the GOSUB/RETURN statement is as follows:
where - LLL is the line number of the exit point
- YYY is the line number of the last instruction in the subroutine
Example:
999 GOSUB 9990
GOTO
The GOTO command redirects program flow to a specified line number. Note that GOTO is one word. The format of the GOTO statement is as follows:
where - LLL is the line number of the exit point
Example:
999 GOTO 110
Program flow is unconditionally changed to line 110
HTICK (intermediate)
Occasionally it is convenient to have a timer which can be started and stopped even though you could keep a running total with the TIME(X) function, such as when programming a concurrent schedule. In that case a ticker is analogous to a VI tape which can be started and stopped and which "sets up" when it reaches zero. ECBASIC allows any number of "count down timers" or "tickers" with the restriction that only five can be running at a time. These timers are automatically and transparently decremented by ECBASIC through a "backdoor." The ECBASIC experiment control program need only base a decision on the variable, and need not explicitly decrement that variable. If the ONTICK interrupt routine is used the program need not even check the variable to see if it had elapsed.
HTICK allows ECBASIC to stop decrementing a timer or ticker that was started with STICK (see STICK). HTICK stops the timer from decrementing its associated variable and frees the channel for use with another variable. HTICK can be used only in the program mode. The format of the HTICK statement is as follows:
where - LLL is the line number of the halt ticker command
Example:
999 HTICK 3
Ticker number 3 is stopped from decrementing.
IF THEN
The IF THEN command allows the conditional execution of a program command depending on the outcome of the comparison of two expressions. If the comparison is true then the second half of the line is executed otherwise program flow falls through to the next consecutive line number. The format of the IF THEN statement is as follows:
where - LLL is the line number of the test
- relation can be < (less than), <= (less than or equal to, = (equal to), <> (not equal to), > (greater than), or >= (greater than or equal to)
- exprn2 is any expression
- command is any ECBASIC command to be executed if the comparison is true
Examples:
999 IF I<4 THEN GOTO 1200
999 IF ABS(A-B)<>TIME(A)-RAND() THEN RETURN
999 IF MOD(I,4)=0 THEN PULSON 5,50
999 IF I=C AND B<9 THEN GOTO 400
INPUT (advanced)
The INPUT instruction does somewhat different things depending on the exact hardware configuration.
The INPUT statement allows the program to input data (numbers) from the keyboard. It is primarily for applications based on an IBM compatible with the adaptor board configuration (see ECBasic with IBM PC Adaptor Board and IBM PC Adaptor Board). The input statement will print on the monitor a prompt string (if specified) followed by a question mark (if specified). The user then enters the requested data. If a conversion error is detected an error message is printed and the question mark prompt is repeated. If multiple variables are to be entered, a space or comma separator is sufficient between entries. If multiple variables are to be entered and the user presses the return key before all values are entered, the question mark prompt will be printed indicating more data is required. The control program will not proceed without the requested data. A Control-C will terminate program execution. An alternate use for this instruction is to enter daily adjustments to a control program following the loading of the program itself. In this case an *DATA* must be entered on the line following the program so that RBAS or ExpRun will transmit the appropriate data to the Experiment Controller. The control program must contain the code required to input the data at the beginning of the program. (The Controller cannot be deselected until it is finished inputting the data.) This command can be used only in the program mode and not in the immediate mode. Do not confuse this instruction with:
where - LLL is the line number of the input statement
- delimiter is a comma if a question mark is desired in the prompt or a semicolon if no question mark is desired.
- "varbl1" is the first variable or array element name into which the data entered is to be stored. Multiple variables can be used if separated with commas or semicolons.
- "varbl2" is the optional second variable or array element name into which the data entered is to be stored. No brackets are used.
Examples:
999 INPUT "Enter your data", A(I),B(I)
Prints the prompt "enter your data?" then reads the keyboard input into the ith element of A, and the second keyboard input into the ith element of B.
999 INPUT A
Prints a question mark prompt and reads one value from the keyboard (or console terminal and stores it in A.
999 INPUT "";A
Reads one value from the keyboard or console terminal and stores it in A.
11 INPUT "";A,B,C,D,E
Reads five values from the network link and stores them into variables A, B, C, D and E. See RBAS or ExpRun section for how to transmit data to a control program. Note that the form of the input command which does not prompt is used.
LINK
The LINK command instructs ECBASIC to consider the specified outputs as a single output. Any time the first of the outputs is altered the other output will similarly be changed. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. More than two outputs can be linked by using successive LINK commands. The operation of the first output will result in the rest of the "daisy chain" being operated. The operation of any other output in the chain will result in all subsequent outputs in the chain being operated. The format of the LINK statement is as follows:
where - LLL is the line number of the LINK command
- exprn2 is the expression which specifies the actual hardware output number of the passenger output (must be between 1 and 44)
Example:
10 LINK 1,40
where - 1 is the actual hardware output #1. It could be the food magazine
- 40 is the actual hardware output #40 and could be the magazine light
LPRINT (advanced)
The LPRINT instruction does somewhat different things depending on the exact hardware configuration.
The LPRINT statement allows the program to output data or text to a printer, CRT terminal or any other serial device attached to the second serial port of the Experiment Controller. It is primarily for applications desiring secondary information on the status of an experiment while it is running or for stand-alone applications. Additionally, any of the commercially available serial port analog workbenches could be controlled through the auxiliary serial port. Any number of elements can be printed by an LPRINT statement up to the maximum line length of 80 characters. (The program can loop, of course, to print any amount of information desired.) Each element must be separated from the next element by a separator. The comma separator causes ECBASIC to insert a tab before the next element (tab columns are at 0, 9, 17, etc.). The semicolon separator allows the next element to be printed adjacent to the previous element. If the LPRINT statement is ended with a separator, a carriage return is not printed and later LPRINT statements can add to the same output line. Text output can be used to label the data. The LPRINT statement is exactly the same as the PRINT statement except that the output goes to the line printer instead of the console terminal. The LPRINT statement can be used in the program mode or in the immediate mode. The LPRINT queue has a 120 character buffer. If the buffer is not overfull, then printing is done in the background. If the buffer overflows then the CPU will "hang" in the print routine until the overflow condition is over (i.e., less than 120 characters left to print). The form of the LPRINT statement is as follows:
where - LLL is the line number of the LPRINT statement
- if more than one element is to be printed a separator is used between elements, it is either a comma or a semicolon. Brackets are not used.
- the final optional separator specifies that no carriage return line feed is to be appended to the output
Examples:
990 A=30
999 LPRINT A
Prints 30<cr> (where <cr> is carriage return)
990 A=500
999 LPRINT "A = ";A;
Prints A = 500
990 A=1
991 B=2
999 LPRINT "A=";A," B = ";B,"A+B"=A+B
Prints A=1 B = 2 A+B=3<cr>
MARKER (advanced)
Occasionally it is convenient to insert a "marker" into the data stream when in transparent (event log) data recording mode. For instance, if a marker is output one minute before a schedule changes, then the data analysis program can detect that marker and can calculate the rate in the one minute before the schedule change even though no stimulus change was presented to the subject. Otherwise, the data analysis program must keep a buffer of responses, so that when the schedule changes it can "backspace" one minute back through the response list in order to determine how many responses occurred in the one minute before the schedule change. The format of the MARKER statement is as follows:
where - LLL is the line number of the MARKER command
Example:
999 MARKER window
Outputs marker 43 (previously, window was set to 43) to the data stream sent to the Supervisor computer via the network link.
MONIT (advanced)
The MONIT instruction allows the Experiment Controller to send the value of a variable up the network link whenever a status poll is issued by the Supervisor computer. This instruction is only applicable in transparent (event log) recording mode on an Experiment Controller. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. If MONIT is specified with no argument, it will return the line being executed and the subroutine level. This option could be handy for debugging a program. The format of the MONIT statement is as follows:
where - LLL is the line number of the MONIT command
Example:
999 MONIT reins
The contents of reins is passed to the Supervisor computer via the network link when a status poll is issued.
ON GOSUB
The ON GOSUB statement redirects program flow to a specified line number depending on how expression 1 is evaluated. If the expression is evaluated as a 1 then the line number designated by the first expression is executed. If it is evaluated as a 2 then the second expression is executed and so on. Note that preferred programming practice is to have the subroutines at the beginning of the experiment control program because ECBASIC must search through the program to find the specified subroutine line number. The format of the ON GOSUB statement is:
where - LLL is the line number of the ON GOSUB
- exprn2 is the expression specifying the destination line number if exprn1 was evaluated to a 1
- exprn3 is the expression specifying the destination line number if exprn1 was evaluated to a 2
- exprn4 is the expression specifying the destination line number if
exprn1 was evaluated to a 3.
If additional options are desired they
are simply added with commas as separators. Brackets are not used.
Examples:
999 ON A-B GOSUB 500,700,900
If (A+B)/C equals 1 then the program goes to subroutine at line 500.
If (A+B)/C equals 2 then the program goes to subroutine at line specified by the
evaluation of D-20.
ON GOTO
The ON GOTO statement redirects program flow to a specified line number depending on how expression 1 is evaluated. If the expression is evaluated as a 1 then the line number designated by the first expression is executed. If it is evaluated as a 2 then the second is executed and so on. The format of the ON GOTO statement is as follows:
where - LLL is the line number of the branch
- exprn2 is the expression specifying the destination line number if exprn1 was evaluated to a 1
- exprn3 is the expression specifying the destination line number if exprn1 was evaluated to a 2
- exprn4 is the expression specifying the destination line number if
exprn1 is evaluated to a 3.
If additional options are desired they
are simply added with commas as separators. Brackets are not used.
Examples:
999 ON A-B GOTO 500,700,900
If (A+B)/C equals 1 then program goes to line 500.
If (A+B)/C equals 2 then program goes to line specified by the evaluation
of D-2.
ONKEY (intermediate)
The ONKEY statement specifies that ECBASIC is to unconditionally and immediately redirect program flow to the subroutine at the specified line number whenever the specified input occurs. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. The interrupt routine can be disabled by executing an ONKEY command which specifies zero as the destination line number. ONKEY is reenabled by executing the ONKEY command with the appropriate destination. Note that the last line of a subroutine must be a RETURN. When the subroutine is complete, program flow resumes where it left off (which could be anywhere). Note that preferred programming practice is to have the interrupt subroutines at the beginning of the experiment control program because ECBASIC must search through the program to find the designated subroutine line number. Note also that the currently executing ECBASIC instruction must complete before the subroutine will be started with the exception of the SLEEP, PULSON and PULSOFF commands. The format of the ONKEY statement is:
where - LLL is the line number of the instruction which sets up the interrupt routine
- exprn2 is the expression specifying the line number of the subroutine to execute on the occurrence of the specified input
Example:
20 ONKEY 1,100
Whenever input 1 occurs, the subroutine starting at line 100 is executed regardless of what the ECBASIC program had been doing.
ONNOKEY (advanced)
The ONNOKEY statement specifies that ECBASIC is to unconditionally and immediately redirect program flow to the subroutine at the specified line number whenever the specified input returns to its normal state. It is primarily for experiments that monitor the state of an input (e.g., bird on perch or off perch) rather than discrete responses (e.g., key pecking). It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. The interrupt routine can be disabled by executing an ONNOKEY command which specifies zero as its destination line number. The interrupt routine is reenabled by executing the ONNOKEY command with the appropriate destination. Note that the last line of a subroutine must be a RETURN. When the subroutine is complete program flow resumes where it left off (which could be anywhere). Note that preferred programming practice is to have the subroutines at the beginning of the experiment control program because ECBASIC must search through the program to find the designated subroutine line number. Note also that the currently executing ECBASIC instruction must completed before the subroutine will be started with the exception of the SLEEP, PULSON and PULSOFF commands. The realities of debouncing results in an outcome which must be dealt with by the ECBASIC user while writing the control program if this command is used. If an input transitions to its nonnormal state for less than the specified debounce time, then the ONNOKEY interrupt cannot have an arming style debounce (see figure below). In that case, the interrupt will occur the specified debounce time after the input returns to its normal state. For example, the interrupt would occur 30 milliseconds after a bird leaves the perch. This is an attempt to assure that the control program does not get "out of sync" with the input state.
The format of the ONNOKEY statement is:
where - LLL is the line number of the instruction which sets up the interrupt routine
- exprn2 is the expression specifying the line number of the subroutine to execute on the return of the specified input to its normal state
Example:
20 ONNOKEY 1,100
Whenever input 1 returns to its normal state, the subroutine starting at line 100 is executed regardless of what the ECBASIC program had been doing at the time of the response.
ONTICK (intermediate)
The ONTICK statement specifies that ECBASIC is to unconditionally and immediately redirect program flow to the subroutine at the specified line number whenever the variable linked to the specified ticker (see STICK) times out. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. The interrupt routine can be disabled by specifying 0 as the line number. Note that the last line of a subroutine must be a return. When the subroutine is completed program flow resumes where it left off (which could be anywhere). Note that preferred programming practice is to have the subroutines at the beginning of the experiment control program because ECBASIC must search through the program to find the specified subroutine line number. Normally the interrupt routine will also be declared early in a program. Note also that the currently executing ECBASIC instruction must completed before the subroutine will be started with the exception of the SLEEP, PULSON, and PULSOFF commands. The format of the ONTICK statement is:
where - LLL is the line number of the instruction which sets up the interrupt routine
- exprn2 is the expression specifying the line number of the subroutine to execute on the occurrence of the specified input
Example:
20 ONTICK 1,100
Whenever the variable being decremented by ticker 1 expires, the subroutine starting at line 100 is executed regardless of what ECBASIC had been doing.
OUTPB (guru)
OUTPB outputs a byte to the I/O bus. This instruction is intended for outputting to the SBX card. It can be executed on the IBM/adaptor board configuration but care should be exercised in its use. The format of the OUTPB statement is:
where - LLL is the line number of the OUTPB
- exprn2 is the expression specifying the data byte to be sent
Example:
999 OUTPB 513,23
The byte 23 is sent to the I/O address 513
OUTPW (guru)
OUTPW outputs a word to the I/O bus. This instruction is intended for outputting to the SBX card. It can be executed on the IBM/adaptor board configuration but care should be exercised in its use. The format of the OUTPW statement is:
where - LLL is the line number of the OUTPW
- exprn2 is the expression specifying the data word to be sent
Example:
999 OUTPW 513,23
The word 23 is sent to the I/O address 513
POKE (guru)
POKE allows ECBASIC to write data into a specified decimal memory location. It deposits the byte specified by the solution of expression 2 into the memory location specified by expression 1. POKE can be used in both the program mode and the immediate mode. Machine language programs can be written to memory locations with POKE instructions. Note that only the low order byte of the data specified is written (i.e., numbers between 0 and 255). The format of the POKE statement is as follows:
where - LLL is the line number of the POKE command
- exprn2 is the expression specifying the decimal representation of the data to be written to that memory location
Example:
999 POKE 32268,57
At location 32268 deposits 57
The PRINT instruction does somewhat different things depending on the exact configuration.
The PRINT statement allows the experiment control program to output its data (or text) to the network link (or console terminal) exactly as if it were simply printing to a CRT screen. This information is automatically collected by the network administration program in the Supervisor computer and stored on the disk file designated when the experiment was started. Subsequently, the researcher may display the disk file on the CRT, generate hard copy or import it directly into an analysis program. The typical experiment with explicit (summary) data collection would carry out an experiment while storing the obtained results in some set of variables and arrays. After the experiment completes, the experiment control program would simply PRINT the variables and arrays in whatever format, and with whatever additional text was desired. Because ECBASIC has an 8000 character print buffer and because the network administration program is continually collecting data from each controller, data could also be sent upline to the Supervisor computer while the experiment is running if care is taken not to overflow the buffer. If the buffer fills, then ECBASIC waits until it unfills before proceeding to the next instruction. (See the Networking section and this figure). Any number of elements can be printed by a PRINT statement up to the maximum line length of 80 characters (the program can loop, of course, to print any amount of information desire). Each element must be separated from the next element by a separator. The comma separator causes ECBASIC to insert a tab before the next element (tab columns are 0, 9, 17, etc.). The semicolon separator allows the next element to be printed adjacent to the previous element. If the PRINT statement is ended with a separator a carriage return is not printed and later PRINT statements can add to the same output line. Text output can be used to label the data. The PRINT statement can be used in the program mode or in the immediate mode. The format of the PRINT statement is as follows:
where - LLL is the line number of the elements to be output
- if additional elements are to be printed, a separator is used. It is either a comma or a semicolon. Brackets are not used.
- the final optional separator specifies that no carriage return line feed is to be appended to the output
Examples:
990 A=30
999 PRINT A
Prints 30<cr> (note - <cr> is carriage return)
990 A=500
999 PRINT "A = ";A;
Prints A = 500
990 A=1
991 B=2
999 PRINT "A = ";A," B = ";B
Prints A = 1 B = 2<cr>
PULSOFF
PULSOFF allows ECBASIC to turn off a specified output for a specified time duration. Program flow halts until the time elapses. PULSOFF can be used in both the program mode and the immediate mode. If a Control-C is detected during the PULSOFF, the delay time will expire immediately and the output will be turned on prior to recognizing the Control-C. Note that if the output was off prior to this instruction, PULSOFF will have the effect of sleeping for the specified period and then turning the output on. The format of the PULSOFF statement is as follows:
where - LLL is the line number that pulses the output
- exprn2 is the expression which specifies the amount of time to leave the output off in one millisecond increments.
Example:
999 PULSOFF 1,5000
Turns off output 1, e.g., red light on key right for 5 seconds.
PULSON
PULSON allows ECBASIC to turn on a specified output for a specified time duration. Program flow halts until the time elapses. PULSON can be used in both the program mode and the immediate mode. If a Control-C is detected during the PULSON, the delay time will expire immediately and the output will be turned off prior to recognizing the Control-C. The format of the PULSON statement is as follows:
where - LLL is the line number that pulses the output
- exprn2 is the expression which specifies the amount of time to leave the output on in one millisecond increments.
Example:
999 PULSON 1,5000
Turns on output 1, e.g., red light on key right for 5 seconds.
READ/DATA/RESTORE
The READ/DATA/RESTORE commands set up data within the program and reads or draws upon that data as required. Each execution of a READ automatically reads the next consecutive number in a DATA list. When all of the numbers in the first data statement have been read, READ will begin drawing numbers from the next consecutive data statement. The data statements need not be contiguous (but it is recommended). (It is also recommended that DATA statements be placed early in the program.) The READ/DATA functionality is handy for specifying variable interval values for use by a SLEEP command. See programming example section for typical usage. The pointer for a data list can be RESTOREd, in which case the first number in the data list is the next to be drawn. Each data statement can contain as many numbers as will fit on an 80 column line. The format of the READ/DATA/RESTORE statements are as follows:
where - LLL is the line number of the data list
MMM READ varibl
where - MMM is the line number of the READ command
NNN RESTORE exprsn
where - NNN is the line number of the RESTORE command
Examples:
990 DATA 2,3,7
999 READ C(I)
Specifies that the first time the code is executed the Ith element of array C will be set equal to 2. If it is executed again the next element of array C will equal 3.
990 DATA 2,3,7
991 READ C(I)
999 RESTORE 990
Specifies that the first time the code is executed the Ith element of array C will be set equal to 2. If it is executed again the next element of array C will also be set equal to 2 in that, the element pointer was reset by the RESTORE statement.
REM
The REM statement is used in ECBASIC to allow comments (REMarks) to be included with a program. ECBASIC ignores all of the line past the REM. The REM statement can be used only in the program mode, not in the immediate mode. The form of the REM statement is as follows:
Examples:
999 REM THIS PROGRAM COMPUTES AVERAGES
990 REM
991 REM SUBROUTINE TO CALCULATE DELAY TIMES
992 REM
REPORT (advanced)
REPORT directs ECBASIC to log any occurrence of the specified event to the data stream. See Networking section and this figure. The event is coded and temporally tagged. It is a "definition of configuration" command. It need be executed only once and should be part of program initialization before the experimental procedure begins. The format of the REPORT statement is as follows:
where - LLL is the line number of the input command
LLL REPORT TIMER,exprsn
where - LLL is the line number of the report time command
- exprsn is the expression which specifies the timer number which is to be automatically and transparently coded, temporally tagged, passed to the Supervisor computer, and stored on the disk file for the designated experiment each time it occurs.
LLL REPORT OUTPUT,exprn1,exprn2
where - LLL is the line number of the report output commands
- exprn1 is the expression which specifies output number which is to be automatically and transparently coded, temporally tagged, passed to the Supervisor computer, and stored on the disk file for the designated experiment each time it occurs
- exprn2 is the expression which specifies whether the onset or offset of the designated stimulus is to be reported
Examples:
999 REPORT INPUT,3
Directs ECBASIC to report any occurrence of input 3 to the Supervisor computer via the network link.
999 REPORT TIMER,1
Directs ECBASIC to report any occurrence of the expiration of timer 1 to the Supervisor computer via the network link.
999 REPORT OUTPUT,37,1
Directs ECBASIC to report any occurrence of output 37 being turned on to the Supervisor computer via the network link.
SEND (advanced)
The SEND command places a 32-bit variable into the data stream to be sent to the Supervisor computer via the network link. This command functions only in the transparent (event log) data collection mode. The format of the SEND statement is as follows:
where - LLL is the line number of the SEND command
Example:
999 SEND DELAY
Sends the contents of the variable, DELAY, to the Supervisor computer.
SLEEP
The SLEEP instruction allows ECBASIC to wait for a specified time duration. Program flow halts for the number of milliseconds specified by the argument of the SLEEP command. SLEEP can be used in both the program mode and the immediate mode. The format of the SLEEP statement is as follows:
where - LLL is the line number at which to SLEEP
Example:
999 SLEEP 25
The program will hang at line 999 for 25 milliseconds.
STICK (intermediate)
Occasionally it is convenient to have a timer which can be started and stopped even though you could keep a running total with the TIME(X) function such as when programming a concurrent schedule. In that case a ticker is analogous to a VI tape which can be started and stopped and which "sets up" when it reaches zero. ECBASIC allows any number of "count down timers" or "tickers" with the restriction that only five can be running at a time. These timers are automatically and transparently decremented by ECBASIC through a "backdoor." The ECBASIC experiment control program need only base a decision on the variable and need not explicitly decrement that variable.
The STICK instruction allows ECBASIC to start decrementing a specified timer or ticker. The variable is decremented each millisecond until it reaches 0. When the variable reaches 0, the timer stops decrementing. Only 5 tickers may be active at one time. STICK can be used only in the program mode. Note that the HTICK command can be used to stop the ticker (see HTICK). Note that the expiration of a ticker can start an interrupt routine (see ONTICK). The format of the STICK statement is as follows:
where - LLL is the line number of the STICK instruction
- varibl is variable name to be decremented
Example:
999 STICK 3,varibl
The value in varibl is decremented by one every millisecond.
STOP
The STOP command terminates program execution and prints a message stating the line number at which the stop occurred. The STOP command is typically used in debugging or error checking so that program flow can be identified. The normal program terminator is END. The STOP command can only be used in the program mode and has no meaning in the immediate mode. The format of the STOP statement is as follows:
where - LLL is the line number at which to halt
Example:
THAW
THAW allows ECBASIC to restore the output condition as saved at the last FREEZE (see FREEZE). It is useful in situations such as reinforcement. THAW can be used in both the program mode and the immediate mode. The format of the THAW statement is as follows:
where - LLL is the line number of the THAW instruction
Example:
999 THAW
Turns on any outputs that were on when the last FREEZE was executed.
TURNOFF
TURNOFF allows ECBASIC to turn off a specified output or outputs. This instruction can be used in both the program mode and the immediate mode. The format of the TURNOFF statement is as follows:
where - LLL is the line number which turns outputs off
- exprn2 is an optional additional output to be turned off. The maximum number of arguments is dictated by the maximum line length of 80 characters. Each output is to be separated with commas and enclosed in the parentheses. Brackets are not used.
Example:
999 TURNOFF 4
Turns off the stimulus connected to output 4.
TURNON
TURNON allows ECBASIC to turn on a specified output or outputs. The instruction can be used in both the program mode and the immediate mode. In either mode, the outputs will stay on until another command turns them off. The use of this instruction in the immediate mode is especially handy when debugging the experimental apparatus. The format of the TURNON statement is as follows:
where - LLL is the line number which turns the output on
- exprn2 is an optional additional output to be turned on (maximum number of arguments is dictated by the maximum line length of 80 characters). Each output is to be separated with commas and enclosed in the parentheses. Brackets are not used.
Examples:
999 TURNON 4
Turns on the stimulus connected to output 4.
999 TURNON rein,maglte
Turns on the reinforcement magazine and magazine light (those variables had earlier been set equal to the output numbers).
10 KEYRED=20
Turns on red key light (presuming output 20 is connected to red).
ECBASIC in the Experiment Controllers can be told what to do with respect to the experimental apparatus (e.g., turn on keyred) with any of a variety of program commands. ECBASIC can also be told what to do with respect to the researcher (e.g., list a copy of the program to the screen). The following section describes the system control commands available in ECBASIC. These are typical of BASIC interpreters. If you are using a networked system, your contact with these instructions will be only when you are debugging something (see In Case of Trouble, Debugging section). If you are using the IBM/adaptor board configuration, your contact will be very frequent.
If you are using an IBM/adaptor board configuration, ECBASIC is "right there" and your keyboard and CRT are "directly connected" to ECBASIC. You could type LIST and ECBASIC will list a copy of its current experiment control program on the screen. If you are using an Experiment Controller with a dumb terminal (stand-alone mode), you are in basically the same situation; typing LIST will result in the program being displayed on your screen. If you are in network mode with a Supervisor computer and an Experiment Controller, then you are one level removed from ECBASIC. When you type on the computer on your desk (the Supervisor computer), you are interacting with it, not with the Experiment Controller. You can, however, tell the network administration software on the Supervisor to simply directly connect you through to some specific Experiment Controller. Each character you type is then passed through to the desired Experiment Controller and each response of the Experiment Controller is then displayed on your CRT monitor. Your Supervisor computer is acting as a dumb terminal. You are interacting directly with ECBASIC on the Experiment Controller. Typing LIST will result in a copy of the experiment control program being displayed on your screen.
The following are the system commands currently recognized by ECBASIC.
ECHO - for use as network primitives
NOECHO - for use as network primitives
OFF - for use as network primitives
OFFRUN - for use as network primitives
LLIST - for use with
local printer option,
LOAD - for use with IBM/adaptor board
SAVE - for use with IBM/adaptor board
QUIT - for use with IBM/adaptor board
LIST
The LIST command causes ECBASIC to list the current experiment control program to the Supervisor computer via the network link (or on the console terminal or on the IBM monitor, depending on your configuration). The entire program (LIST with no arguments); a single line (LIST followed by the line number); or a block of lines (LIST followed by the first and last line number to be listed) may be output. The LIST command can be used only in the immediate mode. The format of the LIST command is as follows:
where - exprn1 is an optional expression which specifies the first line number to be output. Brackets are not used.
- exprn2 is an optional expression which specifies the last line number to be output. Brackets are not used.
Examples:
LIST
List the entire program to the Supervisor computer via the network link.
LIST 500
Lists only line 500 to the Supervisor computer via the network link.
LIST 20-60
Lists line numbers 20 through 60 to the Supervisor computer via the network link.
NEW
The NEW command causes ECBASIC to erase the current experiment control program and variable allocation area. Any outputs that were on are turned off. No parameters are recognized. The NEW command can be used only in the immediate mode. The format of the NEW command is as follows:
RUN
The RUN command causes ECBASIC to begin executing the experiment control program that is currently in memory. No parameters are recognized. The RUN command can be used only in the immediate mode. The format of the RUN command is as follows:
ECHO (advanced)
The ECHO command causes ECBASIC to echo characters received as input from the network link (or console terminal in stand-alone mode) (same actual hardware serial port). If an Experiment Controller is powered up in the networked mode (see Networking section), the default mode is NOECHO. In stand-alone mode, the default mode is ECHO. The NOECHO mode is designed to facilitate automatic program loading from a Supervisor computer. When in network mode keyboard input to the Experiment Controller will not normally produce characters being sent back for display on the CRT screen because the Experiment Controller is not echoing the input. The ECHO command can be used in both the program mode and the immediate mode. The format of the ECHO command is as follows:
999 ECHO
NOECHO (advanced)
The NOECHO command causes ECBASIC to not echo characters received as input from the network link (or console terminal) (same actual hardware serial port). If an Experiment Controller is powered up in the remote or networked mode, (see Networking section) the default mode is NOECHO. If the Controller does not echo every character back up the network line then communication protocols can be simpler. In stand-alone mode the default mode is ECHO. The NOECHO command can be used in both the program mode and the immediate mode. The format of the NOECHO command is as follows:
999 NOECHO
OFF (advanced)
The OFF command is used when the Experiment Controller is used in a network as a remote peripheral processor (see Networking section). This command causes ECBASIC to switch the unit off-line or into a deselected mode (causes it to disconnect or hang-up in phone analogy). When this command is received ECBASIC relinquishes the network line so that some other controller may be addressed. (Sending an ASCII "DC3" (Control-S or 13 hex) is equivalent to sending an OFF command.) In this way many controllers can use a single RS-422 line to the Supervisor computer. The OFF command can be used only in the immediate mode. The format of this command is as follows:
OFFRUN (advanced)
The OFFRUN command is used when the Experiment Controller is used in a network as a remote peripheral processor (see Networking section). This command causes ECBASIC to immediately switch the unit off-line or into a deselected mode, and then begin executing the experiment control program that is currently in memory. This is the preferred way to start a program on a networked ECBASIC unit. The OFFRUN command can be used only in the immediate mode. The format of the OFFRUN command is as follows:
LLIST (advanced)
The LLIST command causes ECBASIC to list the current program on the line printer or serial device attached to the second serial port. Its primarily for applications based on a "stand-alone" configuration. The entire program (LLIST with no arguments); a single line (LLIST followed by the line number); or a block of lines (LLIST followed by the first and last line number to be printed) may be output. In the IBM/adaptor board configuration, the program is listed to the screen. The LLIST command can be used only in the immediate mode. The format of the LLIST command is as follows:
where - exprn1 is the first line number to be output
Examples:
LLIST
Lists the entire program on the printer.
LLIST 500
Lists only line 500 on the printer.
LLIST 20-60
Lists line number 20 through 60 on the printer.
LOAD
The LOAD command is used to load an EBAS program from the disk. Normally, it is followed with the desired file name. If no file name is specified, it will prompt for one. The LOAD command can be used only in the immediate mode. The format of this command is as follows:
where - filename specifies the desired file name
SAVE
The SAVE command is used to save an EBAS program onto the disk. Normally, it is followed with the desired file name. If no file name is specified, it will prompt for one. The SAVE command can be used only in the immediate mode. The format of this command is as follows:
where - filename specifies the desired file name
QUIT
The QUIT command is used to terminate EBAS and return to DOS. The QUIT command can be used only in the immediate mode. The format of this command is as follows:
Programs are normally written in the text editor or word processor of the Supervisor machine. As a result you can use all the text manipulation tools available on your word processor. You can even cut and paste from old programs in order to gain FORTH-like functionality. Keep in mind however, line numbers may need to be corrected, and GOTO destinations may need to change. Save the file as a straight ASCII text file.
As with many BASICs it is handy to number lines in increments of ten so that later additional code can be added between existing instructions.
Have files containing programs with increasing line numbers so that the Experiment Controllers do not shuffle lines around while you are trying to download a program.
Always make sure that you do not have two lines with the same number. If you have a line 30 and later have a line number which you think is 330 but is actually 30 then it will overwrite line 30 and the program will do unintended things.
When ECBASIC is directed to a line number (e.g., GOTO, ON GOSUB, ONTICK, etc.), it searches through the program looking for that line number. ECBASIC will run faster if you place all subroutines at the beginning of the program.
ECBASIC will also run faster if you use expressions as part of instruction rather than using the expression to define a variable and then use the variable as part of the instruction. This general rule of thumb may not be true if there are multiple uses of the variable (see section on expressions).
ECBASIC is designed to do many things automatically and transparently. For example, once the configuration is defined you do not need to execute a CLICK command every time you want a feedback click nor a COUNT command for each response.
If you record event logs, you should think about likely analyses so that you can output the data in a convenient form. The liberal use of markers will allow you to use the same analysis program for a number of procedures with only different stimulus colors, etc.
Special care should be exercised to make interrupt subroutines as short as possible. They are to be used for short interruptions to normal program flow, not as a way to direct general program flow.
These are relevant segments only. They are only to help you get the idea of how to implement schedules, and are not complete programs.
Fixed Ratio 100
The first line of this segment takes the current value of the peck counter, whatever it is, and stores it in START. The next instruction checks to see if the number of pecks is 100 more than the value of PECKS at the start of the ratio. The program continues to do this same test while ECBASIC itself transparently increases the peck counter each time the pigeon pecks. When PECKS finally exceeds START by 100 the reinforcer is presented and the first instruction of this segment is again executed. Note that the FR requirement is specified as a difference. As a result PECKS, the variable cumulating pecks, need never be reset. This is preferred programming style.
Variable Interval t
An array named VIVALS contains 25 Fleshler and Hoffman VI values. Line 10 generates a random number between 1 and 25. It gets the value of that array element and waits for that duration. It then sets START equal to the number of pecks so far. Then it waits until the number of pecks is greater than START, after which it operates the food hopper, and starts over again with a new randomly selected element from the array.
Fixed Interval 60-sec
The first line of this segment waits for 60 seconds. The current value of the peck counter is then stored in START. The program then waits until a peck occurs, provides the reinforcer, and then returns to the first line.
Second Order Fixed Ratio 5(FR 50:S)
The program executes five fixed ratios exactly like Example 1 after which it flashes a key light for .25 sec. It returns to this loop five times after which it provides food.
Chain Variable Interval t Fixed Ratio 100
This program is simply a combination of the VI example and the FR examples.
ECBASIC is "user friendly." The instructions and syntax are very intuitive. If you have trouble with it, there are several things you can do. If there was an error message, look it up in the Error Message section. If it is that you do not understand ECBASIC, other BASIC manuals may be helpful in realizing what ECBASIC does. Second, study a complete working program like Dews (1962) provided in the subsequent section. Third, go back through the ECBASIC Language Reference Manual refreshing yourself on what each instruction does. Fourth, isolate the code in question and test it in the most simplified example you can think of and see what it does.
If bugs of ours are found, please let us know. If possible send a program listing and description of the problem. If your Experiment Controller does unexpected things, then something is wrong and it should be fixed.
If an error appears in your data file read it; it means something is wrong. In most cases it will be informative enough for you to correct the error. If not, you can "direct connect" to that Experiment Controller, run the "offending" experiment control program and debug the program "on-line."
ECBASIC will normally be able to assess errors and will specify what went wrong.
I. In network mode these will come up the line whenever that Controller has
permission to use the network link:
B. In direct connect mode, the error messages and your data will appear
on your screen just as if you were running BASIC on your Supervisor
machine.
II. In the IBM/adaptor board configuration, they will appear on your screen.
All Versions of ECBASIC
Syntax error
An unrecognizable element was detected (probably a typing error).
Illegal variable name
A variable name was either too long or contained an illegal character. Variables can be from 1 to 6 characters, must start with a letter (A-Z) followed by letters, numbers, or a type indicator (%, !, $ or #) at the end of the variable.
Constant Redefined
A named constant has been redefined. Currently not an implemented feature, so it's unlikely you will see this.
Variable Redefined
A variable has been redefined as a constant or has had its type changed. Neither feature is currently implemented.
Symbol Table Full
The symbol table is full. Currently this means you have defined more than 1000 variables and arrays (an array is 1 symbol).
Illegal Variable Usage
A variable was used inappropriately. Putting subscripts on a variable, forgetting them on an array, or assigning to a constant.
Expression Missing
An expression was expected and none was found.
Variable Not Defined
A variable was used before it was defined. Variables must be assigned to (left of the equal sign) before they are usable.
Illegal Use of String
Assigning an integer or float value to a string, using a string in an arithmetic statement, or unmatched quotes in a string. Use of strings is currently limited to INPUT, PRINT, and storing to a string variable (which is then used in a PRINT). Sorry no concatenation or substring operations are supported.
Parenthesis Balance Error
Unbalanced parenthesis or parenthesis missing from a function call requiring them.
Improper Parameter Count
The wrong number of parameters has been specified or a parameter of the wrong type. Calling SELECT with a first parameter that is not an array will get you this one.
Internal Error
This is not expected to ever happen. Try to document the circumstances and code involved and let us know so we can fix the bug.
Illegal Array Usage
Use of an array name without subscripts.
Array Not Dimensioned
Using a subscripted variable without DIMensioning it first.
Illegal Array Subscript
Using an array subscript that is larger than the array is DIMensioned. Using a subscript less than 1 or not an integer.
Illegal Expression Type
An expression/argument has the wrong type. Typically caused by using float or string variables/constants in statements that require integer arguments.
NEXT Without FOR
A NEXT statement was encountered without a balancing FOR.
Improper Nesting of FOR/NEXT
A NEXT statement that specified the index of the associated FOR and did not match the previous unmatched FOR.
Missing Argument
A required argument to the statement was missing.
Subroutine Stack Overflow
Too many nested subroutine calls. Currently 20 nested subroutine calls are supported, so if you get this you probably forgot a RETURN somewhere. Note that background (interrupt) subroutines come out of this quota of 20 and can generate this error.
Line Number Not Found
A statement that references a line number (i.e. GOTO, READ...) could not find that line. Also includes background (interrupt) routines.
Return Without GOSUB
More RETURNs have been executed than GOSUBs.
Array Redimensioned
A DIM statement that defines an array with different dimensions than a previous DIM. You can re-DIM an array, you just can't change the size without CLEARing all the variables.
Illegal Expression Value
An expression has a value that is illegal in the context it was used. Typically generated from range checks on statements that deal with specific input numbers, output numbers, or timer numbers.
Break
Program was halted by a control-c.
Stop
Program was halted by a STOP command.
What?
An unrecognizable command was encountered.
Illegal Return from Process Command
This is not expected to ever happen. If it does, please document the circumstances and code involved as best you can and let us know.
Out of Program Space
While you were entering a program, the Controller ran out of memory.
Invalid Command
This is not expected to ever happen. ECBASIC made an error compiling and could not interpret the result when in immediate mode. Try to document the circumstances and code involved, and let us know so we can fix it.
Invalid Statement
This is not expected to ever happen. ECBASIC made an error compiling and could not interpret the result when inserting a line. Try to document the circumstances and code involved, and let us know so we can fix it.
"Listing" Errors
None of these are ever expected to happen. When ECBASIC generates a program listing (result of a LIST command) the following errors could possibly occur. If they occur please try to document the circumstances and code involved, and report the problem to us. Note that these are indicators of bugs in the ECBASIC code and not necessarily in your program.
"ERROR" is printed
A variable name or command name is replaced with ERROR. A bug in compilation (or syntax error detection) Occurred.
An "Invalid Statement" error is printed
In decompiling for a listing, an unrecognizable statement is encountered. It is likely to see these running in packs.
"Unknown Item xx" is printed
In decompiling an expression for a listing, an unknown variable or operator code is seen.
"ILLEGAL" is printed instead of the variable name
In looking up a variable name for a listing the variable is not found or is of the wrong type.
IBM/Adaptor Board Basic (ECBAS.EXE)
INVOCATION ERRORS (errors encountered when running ECBAS.EXE)
An invalid switch was specified.
A unrecognized argument starting with - or / was seen.
An invalid argument was specified.
An unrecognizable argument or too many arguments were seen.
Switch missing argument.
A - or / was seen with no argument. (i.e. / instead of /H)
An invalid file name was specified.
Bad character in file name on command line.
Cannot set control-C handler
An error occurred when setting up the control-C intercept routine. This might not ever happen.
Cannot allocate main memory
Insufficient free memory exists to run ECBASIC.
Cannot open file
Error opening the specified input file.
Not loaded
A zero length filename was specified in the load command causing an abort of the load function without loading.
Not saved
A zero length filename was specified in the save command causing an abort of the save function without saving.
Run aborted
A zero length data filename was entered following a run of a program containing data collection commands.
ISINSTAL error xx.
An error occurred installing the timer interrupt routines. Probably indicates a corrupted program or incompatible system.
If ECBAS is run with an argument ERROR or an argument of /? or /h, the following syntax information is printed:
NOTE: The examples on the following pages are complete and runnable programs. Do not enter the exclamation point or the portion of the line to the right of the exclamation point. The comments are for this manual only. These programs are on the disk with the network administration software that we supply.
IMPLEMENTATION OF DEWS (1962)
10 REM ==============================================================================
20 REM IMPLEMENTATION OF DEWS (1962)
30 REM PROGRAM CREATES 11 CYCLES OF FI WITH 10 BINS IN EACH
40 REM FI DATA IS STORED IN 2-DIMENSIONAL ARRAY (CYCLExBINS)
50 REM ==============================================================================
60 DIM DATA(11,11)
70 HSELTS = 1
80 REDKEY = 3
90 HOPPER = 2
100 COUNT 1,PECKS
110 FOR CYCLE=1 TO 11
120 TURNON REDKEY
130 DATA(CYCLE,11) = TIME(0)
140 FOR BIN=1 TO 10
150 IF MOD(BIN,2)=1 THEN TURNOFF HSELTS
160 IF MOD(BIN,2)=0 THEN TURNON HSELTS
170 DATA(CYCLE,BIN) = PECKS
180 SLEEP 2000
190 DATA(CYCLE,BIN) = PECKS - DATA(CYCLE,BIN)
200 NEXT BIN
210 CURPKS = PECKS
220 IF PECKS = CURPKS THEN GOTO 220
230 DATA(CYCLE,11) = TIME(DATA(CYCLE,11))
240 BLANK
250 PULSON HOPPER,5000
260 NEXT CYCLE
270 FOR CYCLE=1 TO 11
280 PRINT "FI ";CYCLE
290 FOR BIN=1 TO 10
310 PRINT " ";DATA(CYCLE,BIN);
320 NEXT BIN
321 PRINT
330 PRINT "TIME: ";DATA(CYCLE,11)/1000.0
340 PRINT
350 NEXT CYCLE
360 PRINT
370 PRINT "*DONE*"
380 END
INTERFOOD CLOCK - 10% FOOD - RUN FOR 3 HOURS
1 REM R70J PH 2 (R7 - 10% FOOD - REINF=2SEC)
2 REM P=PECKS R=REINF C(X)=COLOR ARRAY
3 REM D(X)=DATA ARRAY 1-10 = BINS1-10
4 DIM D(10),C(10)
7 P=0
8 N=0
9 F=0
10 COUNT 2,P
20 REM LOAD UP ARRAY WITH COLORS (OUTPUT#S) AND ZERO DATA ARRAY
35 DATA 26,19,24,18,17,28,20,22,21,23
40 FOR M=1 TO 10
45 READ C(M)
50 D(M)=0
53 NEXT M
55 L=0
60 REM
65 REM TURN ON HOUSELIGHTS
75 TURNON 4
77 REM STEP THROUGH 10-6SEC STIMULI & COLLECT PECKS TO EACH
80 FOR I=1 TO 10
85 B=P
95 PULSON C(I),6000
100 D(I)=(P-B)+D(I)
120 NEXT I
125 BLANK
127 REM CHECK IF TOO MANY NO FOOD TRIALS 128 IF (N/10)>F THEN GOTO 143
130 REM 10% FOOD OR 90% NO FOOD
131 A=RANGE(1,10)
132 IF A=10 THEN GOTO 143
133 REM NO FOOD
134 SLEEP 2000
135 N=N+1
136 GOTO 149
140 REM FOOD
143 TURNON 2
145 PULSON 3,2000
147 TURNOFF 2
148 F=F+1
149 IF F+N=180 THEN GOTO 151
150 GOTO 75
151 PRINT "R70 PH 2 R7 10%FOOD REINF=2SEC"
152 PRINT
155 PRINT "TOTAL PECKS PER BIN AND RESPONSE RATE PER SEC"
156 PRINT " (MOVE DECIMAL 2 PLACES TO LEFT)"
157 PRINT
180 REM PRINT OUT PECKS AND RESPONSE RATE
200 FOR I=1 TO 10
220 PRINT D(I),(D(I)*100)/((F+N)*6)
230 NEXT I
240 PRINT
245 PRINT "TOTAL FOOD AND NOFOOD TRIALS"
250 PRINT F,N
270 END
FIXED-INTERVAL SCHEDULE
5 REM ==============================================================================
10 REM FI XX SCHEDULE
20 REM WITH DATA COLLECTED FOR 10 EQUAL BINS
30 REM PLUS AVERAGE LATENCY TO LAST PECK
40 REM ==============================================================================
50 DIM LSTPCK(2) ! ARRAY STORING TOTAL OF LAST PECK TIMES
60 DIM BINARR(10) ! ARRAY STORING NUMBER OF PECKS PER BIN
65 DIM BINRTE(10) ! ARRAY STORING RATE OF PECKS PER BIN
70 REDKEY = 3 ! RED KEY LIGHT ON OUTPUT 3
80 HSELTS = 1 ! HOUSE LIGHTS ON OUTPUT 1
90 HOPPER = 2 ! HOPPER ON OUPUT 2
100 REINF = 3 ! NUMBER OF REINFORCERS
110 INVLEN = 20 ! INTERVAL LENGTH IN SECONDS
120 BTICKS = INVLEN * 100 ! LENGTH OF 1 BIN MEASURED IN 1MS TICKS
130 FOR BIN=1 TO 10
140 BINARR(BIN) = 0 ! INITIALIZE ARRAY OF BINS
150 NEXT BIN
160 LSTPCK(1) = 0 ! INITIALIZE ARRAY
170 LSTPCK(2) = 0 ! INITIALIZE ARRAY
180 COUNT 1,PECKS ! COUNT ACTIVITY ON INPUT 1 AS PECKS
190 TURNON HSELTS ! TURN ON HOUSE LIGHTS
200 FOR CYCLE=1 TO REINF ! MAIN LOOP - REPEAT FOR EACH REINFORCERS
210 TURNON REDKEY ! TURN ON RED KEY LIGHT
220 FOR BIN=1 TO 10 ! REPEAT FOR EACH BIN
230 CURPKS = PECKS ! STORE CURRENT NUMBER OF PECKS IN CURPKS
240 CURTME = TIME(0) ! SNAPSHOT CURRENT TIME IN CURTME
250 IF TIME(CURTME) < BTICKS THEN GOTO 250 ! IF BIN NOT COMPLETED, LOOP
260 BINARR(BIN) = BINARR(BIN) + (PECKS-CURPKS) ! SUM & STORE NMBR OF PECKS
270 NEXT BIN ! FINISH LOOP
280 CURPKS = PECKS ! STORE CURRENT NUMBER OF PECKS IN CURPKS
290 CURTME = TIME(0) ! SNAPSHOT CURRENT TIME IN CURTME
300 IF PECKS=CURPKS THEN GOTO 300 ! LOOP UNTIL THERE IS A PECK
310 LSTPCK(1) = LSTPCK(1) + TIME(CURTME) ! ADD UP LAST PECK TIMES
320 LSTPCK(2) = LSTPCK(2) + 1 ! INCREMENT AND STORE THE NUMBER OF PECKS
330 TURNOFF HSELTS ! TURN OFF THE HOUSE LIGHTS
340 TURNOFF REDKEY ! TURN OFF RED KEY LIGHT
350 PULSON HOPPER,5000 ! TURN ON HOPPER FOR 5 SEC
360 TURNON HSELTS ! TURN ON HOUSE LIGHTS
370 NEXT CYCLE ! CONTINUE FOR ALL REINFORCERS
380 BLANK ! TURN OFF ALL LIGHTS
385 REM =============== PRINT OUT DATA ===================
390 AVGLPT = (LSTPCK(1)*10)/LSTPCK(2) ! COMP AVG LAST PECK TIME
400 PRINT "AVERAGE LAST PECK TIME =",AVGLPT/10000.0
410 PRINT "RATE OF PECKS IN EACH BIN:"
420 FOR BIN=1 TO 10
430 BINRTE(BIN) = (BINARR(BIN)*10000)/BTICKS ! COMP RATE FOR EACH BIN
440 PRINT BINRTE(BIN)/100.0;" ";
450 NEXT BIN
460 PRINT "PECKS/SEC "
470 PRINT " "
480 PRINT "*DONE*"
490 END
FIXED-RATIO SCHEDULE
10 REM ==============================================================================
20 REM FR XX SCHEDULE
30 REM COMMENTS VERSION
40 REM MOD. 05/16/93
50 REM ==============================================================================
60 RESPS = 5 ! NUMBER OF RESPONSES REQ. FOR REINFORC.
70 REINF = 4 ! NUMBER OF REINFORCERS IN THE SESSION
80 REDKEY = 3 ! RED KEY LIGHT IS ON 3RD OUTPUT
90 HOPPER = 2 ! HOPPER IS ON 2ND OUTPUT
100 HSELTS = 1 ! HOUSE LIGHTS ARE ON OUTPUT 1
110 FPKTME = 0 ! 1ST PECK TIME IS CLEARED
120 SESTME = 0 ! SESSION TIME IS CLEARED
130 COUNT 1,PECKS ! OPERATIONS OF KEY1 COUNT AS PECKS
140 TURNON HSELTS ! TURN ON THE HOUSELIGHTS
150 FOR CYCLE=1 TO REINF ! MAIN LOOP - REPEAT FOR EACH REINFORCER
160 TURNON REDKEY ! TURN ON RED KEY LIGHT
170 CURPKS = PECKS ! CURRENT NUMBER OF PECKS STORED IN CURPKS
180 CURTME = TIME(0) ! CURRENT TIME IS ASSIGNED TO CURTME
190 IF PECKS = CURPKS THEN GOTO 190 ! LOOP HERE UNTIL THERE IS A PECK
200 FPKTME = FPKTME + TIME(CURTME) ! SUM UP 1ST PECK TIMES
210 IF (PECKS-CURPKS)<RESPS THEN GOTO 210 ! LOOP HERE TIL ALL PECKS ARE SEEN
220 TRLTME = TIME(CURTME) ! GET TRIAL TIME
230 SESTME = SESTME + TRLTME ! SUM UP TOTAL SESSION TIME
240 TURNOFF REDKEY ! TURN OFF RED KEY LIGHT
250 TURNOFF HSELTS ! TURN OFF HOUSE LIGHTS
260 PULSON HOPPER,5000 ! TURN ON HOPPER FOR 5 SEC
270 TURNON HSELTS ! TURN ON HOUSE LIGHTS
280 NEXT CYCLE ! CONTINUE LOOP
290 BLANK ! TURN OFF ALL LIGHTS
295 REM ================================ PRINT OUT DATA ===========================
300 PRINT "TOTAL SESSION TIME = ";SESTME/1000.0;
310 PRINT ;" SEC"
320 AVGSES = SESTME/REINF
330 PRINT "AVERAGE SESSION TIME = ";AVGSES/1000.0;
340 PRINT " SEC"
350 AVGFP = (FPKTME*10)/REINF ! MULTIPLY BY 10 FOR PRECISION
360 PRINT "AVERAGE FIRST PECK TIME = ";AVGFP/10000.0;
370 PRINT " SEC"
380 PRINT " "
390 PRINT "*DONE*"
400 END
VARIABLE RATIO SCHEDULE
10 REM ==============================================================================
20 REM VR SCHEDULE
30 REM 12 FLESHLER-HOFFMAN TERMS AVERAGE FACTORED OUT
40 REM ==============================================================================
70 DATA 429,1339,2341,3454,4707,6141,7815,9829
80 DATA 12356,15754,20986,34849
90 DIM VRARR(12) ! ARRAY STORING FLESHLER HOFFMAN VALUES
100 DIM BINLEN(12) ! ARRAY W/ AVG. TIME FOE EACH TRIAL QUANTUM
120 DIM TRLARR(12,2) ! ARRAY WITH QUANTUM TRIAL TIME AND NUMBER
125 REM ! OF TIMES QUANTUM USED
130 HSELTS = 1 ! HOUSE LIGHTS ON OUPUT 1
140 REDKEY = 3 ! RED KEY LIGHT ON OUPUT 3
150 HOPPER = 2 ! HOPPER ON OUTPUT 2
160 RESPS = 30 ! NUMBER OF RESPONSES REQ. FOR REINF
170 REINF = 5 ! AVERAGE NUMBER OF REINFORCERS
180 TERMS = 12 ! # OF VR VALS (MUST MATCH # OF DATA ITEMS)
190 FPKTME = 0 ! FIRST PECK TIME
200 SESTME = 0 ! SESSION TIME
210 FOR I=1 TO TERMS ! READ DATA VALUES IN VRARR AND CONVERT
220 READ VRARR(I) ! TO RESPS BY MULTIPLYING BY AVG RESPONSES
230 VRARR(I) = ((VRARR(I) * RESPS) + 5000)/10000 ! ROUNDING UP & DIVIDING BY 10000
240 TRLARR(I,1) = 0 ! ZERO TRLARR
250 TRLARR(I,2) = 0 ! ZERO TRLARR
260 NEXT I
270 COUNT 1,PECKS ! OPERATIONS ON KEY 1 COUNT AS PECKS
280 TURNON HSELTS ! TURNON HOUSE LIGHTS
290 FOR CYCLE=1 TO REINF ! MAIN LOOP - REPEAT FOR EACH REINFORCER
300 TURNON REDKEY ! TURN ON RED KEY LIGHT
310 CURPKS = PECKS ! CURRENT NUBER OF PECKS STORED IN CURPKS
320 CURTME = TIME(0) ! SNAPSHOT CURRENT TIME IN CURTME
330 RNDVAL = RANGE(1,TERMS) ! GET QUANTUM NUMBER FOR TRIAL AT RANDOM
340 VRVAL = VRARR(RNDVAL) ! SELECT VR COUNT FROM ARRAY
350 IF PECKS=CURPKS THEN GOTO 350 ! WAIT FOR FIRST PECK
360 FPKTME = FPKTME + TIME(CURTME) ! ADD UP FIRST PECK TIMES
370 IF (PECKS-CURPKS)<VRVAL THEN GOTO 370 ! LOOP HERE TIL ALL PECKS SEEN
380 TRLTME = TIME(CURTME) ! GET THE TRIAL TIME
390 TRLARR(RNDVAL,1) = TRLARR(RNDVAL,1) + TRLTME !SUM INTO THIS QUANTUM TRL
400 TRLARR(RNDVAL,2) = TRLARR(RNDVAL,2) + 1 ! INCR # QUANTUM TIMES USED
410 SESTME = SESTME + TRLTME ! ADD TOTAL SESSION TIME
420 TURNOFF HSELTS ! TURN OFF HOUSE LIGHTS
430 TURNOFF REDKEY ! TRUN OFF RED KEY LIGHTS
440 PULSON HOPPER,5000 ! TURN ON HOPPER FOR 5 SEC
450 TURNON HSELTS ! TURN ON HOUSE LIGHTS
460 NEXT CYCLE
470 BLANK ! TURN OFF ALL LIGHTS
475 REM ======================== PRINT OUT DATA ===================================
480 PRINT "TOTAL SESSION TIME = ";SESTME/1000.0;" SECS"
490 AVGFP = (FPKTME * 10)/REINF ! AVG LAST PECK TIME (*10 FOR PRECISION)
500 PRINT "AVERAGE FIRST PECK TIME = ";AVGFP/10000.0
510 PRINT "AVERAGE BIN TIME:"
520 FOR BIN=1 TO TERMS ! PRINT OUT BIN AVERAGES
530 BINLEN(BIN)=0
540 IF TRLARR(BIN,2) < 1 THEN GOTO 560 ! IF BIN NOT USED, VALUE IS 0
550 BINLEN(BIN) = TRLARR(BIN,1)/TRLARR(BIN,2) ! CALCULATE AVERAGE BIN TIME
560 PRINT (BINLEN(BIN))/1000.0;" ";
570 NEXT BIN
600 PRINT "*DONE*"
610 END
VARIABLE INTERVAL SCHEDULE
10 REM ==============================================================================
20 REM VI SCHEDULE
30 REM 12 TERMS CALCULATED USING FLESHLER-HOFFMAN VI VALUES.
40 REM NOTE THAT AVERAGE INTERVAL TIME HAS BEEN FACTORED OUT OF
50 REM THE DATA VALUES TO MAKE IT READILY CHANGEABLE.
60 REM ==============================================================================
70 DATA 429,1339,2341,3454,4707,6141,7815,9829
80 DATA 12356,15754,20986,34849
90 DIM VIARR(12)
100 DIM LSTPCK(2)
110 INVLEN = 30
120 REINF = 25
125 TERMS = 12
130 FOR I=1 TO TERMS
140 READ VIARR(I)
150 VIARR(I)=((VIARR(I) * INVLEN) + 50) / 100
160 NEXT I
170 BINNBR = ((VIARR(TERMS)*2)/100)+1
180 DIM DATA(BINNBR,2)
185 DIM BINRTE(BINNBR)
190 FOR BIN=1 TO BINNBR
200 DATA(BIN,1)=0
210 DATA(BIN,2)=0
220 NEXT BIN
230 LSTPCK(1)=0
240 LSTPCK(2)=0
250 COUNT 1,PECKS
260 TURNON HSELTS
270 FOR CYCLE=1 TO REINF
280 TURNON REDKEY
290 RNDTME = VIARR(RANGE(1,TERMS))
300 BIN = 1
310 BINTKS = RNDTME
320 PECKS=CURPKS
330 SETTME=50
340 CURTME=TIME(0)
350 IF BINTKS < SETTME THEN SETTME=BINTKS
360 IF TIME(CURTME) < SETTME THEN GOTO 360
370 DATA(BIN,1)=DATA(BIN,1) + (PECKS-CURPKS)
380 PECKS=CURPKS
390 DATA(BIN,2)=DATA(BIN,2)+TIME(CURTME)
400 BINTKS=BINTKS-TIME(CURTME)
410 IF BINTKS<=0 THEN GOTO 440
420 BIN=BIN+1
430 GOTO 340
440 PECKS=CURPKS
450 CURTME=TIME(0)
460 IF PECKS=CURPKS THEN GOTO 460
470 LSTPCK(1)=LSTPCK(1)+TIME(CURTME)
480 LSTPCK(2)=LSTPCK(2)+1
490 TURNOFF HSELTS
500 TURNOFF REDKEY
510 PULSON HOPPER,5000
520 TURNON HSELTS
530 NEXT CYCLE
540 BLANK
550 AVGLPT=(LSTPCK(1)*10)/LSTPCK(2)
560 PRINT "AVERAGE LAST PECK TIME = ";AVGLPT/1000.0
570 FOR BIN=1 TO BINNBR
580 BINRTE(BIN)=0
590 IF DATA(BIN,2) < 1 THEN GOTO 610
600 BINRTE(BIN)=(DATA(BIN,1)*10000)/DATA(BIN,2)
610 PRINT BINRTE(BIN)/1000.0;" ";
620 IF MOD(BIN,10) = 0 THEN PRINT ""
630 NEXT BIN
640 PRINT "*DONE*"
650 END
FLESHLER-HOFFMAN CONSTANT
VI Schedule Constants
terms 6 10 12 15 20 25 30 ----- ----- ----- ----- ----- ----- ---- 884 518 429 341 254 203 169 2897 1631 1339 1056 781 619 513 5424 2884 2341 1826 1337 1055 871 8822 4318 3454 2660 1925 1509 1241 14055 5992 4707 3571 2551 1986 1626 27918 8006 6141 4572 3218 2486 2026 10532 7815 5686 3933 3012 2443 13930 9829 6939 4703 3568 2878 19163 12356 8372 5537 4157 3332 33026 15754 10047 6447 4782 3809 20986 12060 7449 5449 4309 34849 14587 8562 6164 4835 17985 9816 6934 5391 23218 11249 7768 5980 37081 12924 8679 6605 14937 9680 7272 17464 10794 7987 20862 12047 8757 26094 13481 9592 39957 15155 10502 17169 11504 19695 12617 23093 13870 28326 15304 42189 16978 18992 21519 24917 30149 44012
DRL SCHEDULE
10 REM ==============================================================================
20 REM DRL SCHEDULE WITH DATA COLLECTED FOR 10 EQUAL BINS
30 REM ==============================================================================
40 DIM LSTPCK(2) ! ARRAY STORING TOTAL OF LAST PECK TIMES
50 DIM BINARR(10) ! ARRAY WITH NUMBER OF PECKS PER BIN
60 DIM BINRTE(10) ! ARRAY WITH RATE OF PECKS PER BIN
70 DRLTME = 20 ! DRL TIME
80 REINF = 25 ! NUMBER OF REINFORCERS
90 HSELTS = 1 ! HOUSE LIGHTS ON OUTPUT 1
100 REDKEY = 3 ! RED KEY LIGHT ON OUTPUT 3
110 HOPPER = 2 ! HOPPER ON OUTPUT 2
120 BTICKS = DRLTME*100 ! LENGTH OF 1 BIN MEASURED IN 1MS TICKS
130 FOR BIN=1 TO 10
140 BINARR(BIN) = 0 ! INITIALIZE THE ARRAY OF BINS
150 NEXT BIN
160 LSTPCK(1) = 0 ! INITIALIZE ARRAY
170 LSTPCK(2) = 0 ! INITIALIZE ARRAY
180 COUNT 1,PECKS ! COUNT INPUT 1 AS PECKS
190 TURNON HSELTS ! TURN ON HOUSE LIGHTS
200 FOR CYCLE=1 TO REINF ! MAIN LOOP-REPEAT FOR ALL REINFORCERS
210 TURNON REDKEY ! TURN ON RED KEY LIGHT
220 FOR BIN=1 TO 10
230 CURPKS = PECKS ! STORE CURRENT NUMBER OF PECKS IN CURPKS
240 CURTME = TIME(0) ! STORE CURRENT TIME IN CURTME
250 IF TIME(CURTME) < BTICKS THEN GOTO 250 ! IF BIN NOT DONE, LOOP HERE
260 BINARR(BIN) = BINARR(BIN) + (PECKS-CURPKS) ! SUM & STORE # OF PECKS
270 IF PECKS<>CURPKS THEN BIN=1 ! IF THERE IS A PECK START BIN AGAIN
280 NEXT BIN
290 CURPKS = PECKS ! STORE CURRENT # OF PECKS IN CURPKS
300 CURTME = TIME(0) ! STORE CURRENT TIME IN CURTME
310 IF CURPKS=PECKS THEN GOTO 310 ! LOOP HERE TIL THERE IS A PECK
320 LSTPCK(1) = LSTPCK(1) + TIME(CURTME) ! SUM & STORE LAST PECK TIMES
340 LSTPCK(2) = LSTPCK(2)+1 ! INCREMENT NUMBER OF PECKS
350 TURNOFF HSELTS ! TURN OFF HOUSE LIGHTS
360 TURNOFF REDKEY ! TURN OFF RED KEY LIGHTS
370 PULSON HOPPER,5000 ! TURN ON HOPPER FOR 5 SEC
380 TURNON HSELTS ! TURN ON HOUSE LIGHTS
390 NEXT CYCLE ! CONTINUE FOR ALL REINFORCERS
400 BLANK ! TURN OFF ALL LIGHTS
410 REM ====================== PRINT OUT DATA =====================================
420 AVGLPT = (LSTPCK(1)*10)/LSTPCK(2) ! COMPUTE AVERAGE LAST PECK TIME
430 PRINT "AVERAGE LAST PECK TIME = ";AVGLPT/10000.0;
440 PRINT " SEC"
450 PRINT "RATE OF PECKS PER BIN:"
460 FOR BIN=1 TO 10
470 BINRTE(BIN) = (BINARR(BIN)*10000)/BTICKS ! COMPUTE RATE FOR EACH BIN
480 PRINT BINRTE(BIN)/100.0;" ";
490 NEXT BIN
500 PRINT "PECKS/SEC"
510 PRINT " "
520 PRINT "*DONE*"
530 END
MEASUREMENT OF INSTRUCTION TIME
The following example program can be used to time blocks of code. It could be used whenever there was a question concerning the exact time it takes ECBASIC to accomplish some set of operations, such as respond to a key peck.
10 REM
20 REM PROGRAM TO TEST CODE EXECUTION TIME
30 REM INSERT TEST CODE STARTING AT LINE 1000
40 REM
50 LAPTME=0
60 CURMTE=0
70 START=0
80 I=0
100 START=TIME()
110 FOR I=1 TO 1000
120 NEXT I
130 CURTME=TIME(START)
140 REM
150 REM B IS NOW THE TIME A NULL LOOP TAKES TO EXECUTE
160 REM
170 START=TIME()
180 FOR I=1 TO 1000
1000 REM INSERT TEST CODE HERE
1001 REM DO NOT USE A OR B VARIABLES
1002 REM REMOVE THE THREE REM STATEMENTS (1000-1002)
2000 NEXT I
2010 LAPTME=TIME(START)
2020 REM
2030 REM C IS THE TIME FOR THE TEST LOOP, NOW
2040 REM SUBTRACT THE NULL LOOP TIME
2050 LAPTME=LAPTME-CURTME
2060 PRINT "TIME = ";C/1000.0;" MILLISECONDS"
2070 END
ONE-ARMED BANDIT PROGRAM
10 REM ==============================================================================
22 REM ONE-ARMED BANDIT PROGRAM "SLOWS" THEM DOWN. THEY COME TO
23 REM REST CONSECUTIVELY AT A RANDOM COLOR. IT WAS FOR A PARTY.
25 REM ==============================================================================
27 REM
30 REM PRESS ANY KEY TO START
40 REM MATCH ANY TWO LIGHTS FOR RFMT
50 REM MATCH ALL 3 LIGHTS FOR JACKPOT
60 REM
100 DATA 2,5,6,7,8,10,11,12
110 DIM C(8),L(3),T(3,3)
120 FOR I=1 TO 8
130 READ C(I)
140 NEXT I
150 COUNT 1,K
160 COUNT 2,K
170 COUNT 3,K
200 K=0
210 BLANK
215 TURNON 1
220 IF K=0 THEN GOTO 220
225 TURNOFF 1
230 T(1,1)=RANGE(8,15)
240 T(2,1)=RANGE(T(1,1)+4,T(1,1)+14)
250 T(3,1)=RANGE(T(2,1)+4,T(2,1)+14)
260 FOR I=1 TO 3
270 T(I,2)=15
280 T(I,3)=TIME(0)
290 L(I)=RANGE(1,8)
300 NEXT I
310 TURNON C(L(1))+4
312 TURNON C(L(2))+16
314 TURNON C(L(3))+28
320 F=0
330 I=1
340 IF T(I,2) >= 27 THEN GOTO 370
350 F=1
360 GOSUB 1000
370 I=I+1
380 IF I<4 THEN GOTO 340
390 IF F<>0 THEN GOTO 320
400 IF L(1)=L(2) THEN GOTO 500
410 IF L(2)=L(3) THEN GOTO 500
420 IF L(1)=L(3) THEN GOTO 500
425 TURNON 4
426 SLEEP 900
427 TURNOFF 4
428 SLEEP 600
430 GOTO 150
500 IF L(1)=L(2) THEN IF L(2)=L(3) THEN GOTO 600
510 TURNON 3
520 PULSON 2,3000
530 TURNOFF 3
540 GOTO 150
600 TURNON 3
610 TURNON 2
620 FOR I=1 TO 3
630 PULSON 4,75
640 SLEEP 250
650 NEXT I
660 GOTO 150
1000 IF T(I,2) >= 27 THEN RETURN
1010 IF TIME(T(I,3))<T(I,2) THEN RETURN
1015 X=(I-1)*12+4
1020 TURNOFF C(L(I))+X
1030 L(I)=L(I)+1
1040 IF L(I)>8 THEN L(I)=1
1050 TURNON C(L(I))+X
1060 T(I,3)=TIME(0)
1070 IF T(I,1)<=0 THEN GOTO 1100
1080 T(I,1)=T(I,1)-1
1090 RETURN
1100 T(I,2)=T(I,2)+4
1110 RETURN
CONCURRENT SCHEDULE WITH COD
(IMPLEMENTED WITH INTERRUPT ROUTINES)
2 REM ===============================================================================
5 REM CONCURRENT VI SCHEDULES WITH COD
7 REM ===============================================================================
10 GOTO 1000 ! JUMP TO PROGRAM START
15 REM ================ IF PECK OCCURED ON KEY 1=======================
20 IF LSTKEY=1 THEN GOTO 70 ! KEY 1 PRESSED - WAS LAST KEY = 1
30 RNDTME(3)=25 ! NO, RESET COD
40 STICK 3,RNDTME(3) ! START COD TICKER RUNNING
50 LSTKEY=1 ! SET LAST KEY TO 1
60 RETURN ! RETURN TO MAIN PROGRAM
70 IF RNDTME(1)>0 THEN RETURN ! LAST KEY WAS 1, HAS VI TIME EXPIRED?
80 IF RNDTME(3)>0 THEN RETURN ! COD TIME EXPIRED? RETURN IF NOT
90 RNFKEY=1 ! REINFORCER ON KEY 1
100 GOTO 5000 ! START REINFORCEMENT
110 REM ===============IF PECK OCCURED ON KEY 2=======================
120 IF LSTKEY=2 THEN GOTO 170 ! KEY 2 PRESSED - WAS LAST KEY 2?
130 RNDTME(3)=25 ! NO, RESET COD
140 STICK 3,RNDTME(3) ! START COD TICKER RUNNING
150 LSTKEY=2 ! LAST KEY = 2
160 RETURN ! RETURN TO MAIN PROGRAM
170 IF RNDTME(2)>0 THEN RETURN ! IF VI NOT EXPIRED, RETURN
180 IF RNDTME(3)>0 THEN RETURN ! IF COD NOT EXPIRED, RETURN
190 RNFKEY=2 ! REINFORCEMENT ON KEY 2
200 GOTO 5000 ! START REINFORCEMENT AND RETURN
999 REM ==================== MAIN PROGRAM ============================
1000 DATA 25,50,75,100,125,150,175,200,225,250,275,300,325,350,375
1010 DATA 400,425,450,475,500,525,550,575,600,625
1020 DATA 50,100,150,200,250,300,350,400,450,500,550,600,650,700
1030 DATA 750,800,850,900,950,1000,1050,1100,1150,1200,1250
1031 DIM VIARR(2,25)
1032 DIM RNDTME(3)
1033 DIM PCKARR(2)
1034 TERMS = 25
1035 HOPPER = 2
1036 REDKEY = 3
1037 BLUKEY = 4
1038 REINF = 50
1050 FOR I=1 TO TERMS ! READ IN THE KEY 1 VI TIMES
1060 READ VIARR(1,I)
1061 VIARR(1,I) = VIARR(1,I)*100
1070 NEXT I
1080 FOR I=1 TO TERMS ! READ IN THE KEY 2 VI TIMES
1090 READ VIARR(2,I)
1095 VIARR(2,I) = VIARR(2,I)*100
1100 NEXT I
1110 RNFKEY=0 ! ZERO LAST REINFORCED KEY
1120 LSTKEY=0 ! ZERO LAST PRESSED KEY
1130 COUNT 1,PCKARR(1) ! COUNT KEY 1 PECKS IN PCKARR(1)
1140 COUNT 2,PCKARR(2) ! COUNT KEY 1 PECKS IN PCKARR(2)
1150 ONKEY 1,20 ! ON KEY 1 GOSUB TO 20
1160 ONKEY 2,120 ! ON KEY 2 GOSUB TO 120
1200 RNDTME(1)=VIARR(1,RANGE(1,25)) ! SELECT KEY 1 VI VALUE
1210 RNDTME(2)=VIARR(2,RANGE(1,25)) ! SELECT KEY 2 VI VALUE
1220 STICK 1,RNDTME(1) ! START KEY 1 VI RUNNING
1230 STICK 2,RNDTME(2) ! START KEY 2 VI RUNNING
1240 TURNON REDKEY,BLUKEY ! TURN ON KEY LIGHTS
1250 FOR CYCLE=1 TO REINF ! MAIN LOOP
1300 IF RNFKEY=0 THEN GOTO 1300 ! WAIT FOR A REINFORCER TO START
1310 ON RNFKEY GOTO 1320,1410 ! GOTO APPROPRIATE SECTION
1320 GOSUB 5100 ! FINISH REINFORCER ON KEY 1
1330 RNDTME(1)=VIARR(1,RANGE(1,25)) ! GET A NEW VI VALUE FOR KEY 1
1340 STICK 1,RNDTME(1) ! RESTART VI TIMERS FOR BOTH KEYS
1350 STICK 2,RNDTME(2)
1360 RNFKEY=0 ! CLEAR LAST REINFORCED KEY NUMBER
1370 REM THIS LINE IS LEFT BLANK INTENTIONALLY
1380 NEXT CYCLE
1390 PRINT "*DONE*" ! SIGNAL PROGRAM DONE
1400 STOP
1410 GOSUB 5100 ! FINISH REINFORCER ON KEY 2
1420 RNDTME(2)=VIARR(2,RANGE(1,25)) ! GET A NEW VI VALUE FOR KEY 2
1430 GOTO 1340 ! JUMP TO COMMON CODE
4999 REM =================== TURN ON HOPPER =========================
5000 HTICK 1 ! START REINFORCEMENT -
5010 HTICK 2 ! STOP ALL TICKERS
5020 HTICK 3
5030 FREEZE ! SAVE LIGHT STATUS
5040 BLANK ! TURN OFF ALL LIGHTS
5050 TURNON HOPPER ! TURN ON HOPPER
5060 Z=TIME(0) ! SAVE CURRENT TIME
5070 RETURN ! RETURN TO MAIN LOOP
5099 REM ================== TURN OFF HOPPER =========================
5100 SLEEP 3000-TIME(Z) ! TURN OFF HOPPER AND HOPPER LIGHT
5110 BLANK ! TURN OFF ALL LIGHTS
5120 THAW ! RESTORE LIGHTS
5130 LSTKEY=0 ! CLEAR LAST KEY PRESSED
5140 RETURN ! RETURN
Date Last Reviewed : June 2, 2004