;-------------------------------------------------------- ; M E M O R Y ; ; S A C T R A C K S E Q U E N C E ;-------------------------------------------------------- ;Cannot exceed 1023 lines of instructions. ; SET 0.010 2 0 ;0.01 milliseconds per tick ;+/-10 volts ;0 degree offset; TABSZ 150000 ;set maximum table space ;DELAY command is based on the 100 microsecond clock ticks specified above ;TICKS command is based on the ADC sampling clock rate subject to num channels ;VAR V1 ;RE-USABLE variables for use only within mode subroutines ;VAR V2 ;these variables should not pass parameters between VAR V3,RTZ ;modes or subroutines ;VAR V4 ;VAR V5 ;VAR V6 ;VAR V7 ;VAR V8 ;VAR V9 ;VAR V10 ;VAR V11 ;VAR V12, VAR V13,WHICHTAR=1 ;(MEMORY only)primary or secondary target used ;VAR V14, ;VAR V15, ;VAR V16, ;VAR V17, VAR V18,TEMP2 ;Adapt routine VAR V19,TEMP1 ;MODE SUBROUTINE variable VAR V20,TEMP3 ;Accel Decel Adapt routines VAR V21,TEMP4 ;Accel Decel routines ;VAR V22, ;VAR V23, ;VAR V24, ;VAR V25, ;VAR V26, ;----------------------------------------------------------- ;above variables are zeroed every time a new mode is entered ;----------------------------------------------------------- VAR V27,ELAPSED=0 ;when OT testing began VAR V28,TIMECURR ;current SPIKE2 time VAR V29,TIMECHEK ;when to check if it is time to move VAR V30,TIMEFEED VAR V31,TEMPTRAK ;OT testing (convert to TABLE field?) VAR V32,TEMPWIND VAR V33,LEDBRD1 ;indicate which LED board (RED) VAR V34,LEDADD1 ;indicate which LED light (RED) VAR V35,LEDBRD2 ;indicate which LED board (GRN) VAR V36,LEDADD2 ;indicate which LED light (GRN) VAR V37,TRACKING ;is he tracking VAR V38,HITTYPE1 ;times all loc shown or step, non-adapt, etc shown VAR V39,HITTYPE2 ;times step-ramp, adapt shown VAR V40,ZERO=0 ;for many branching comparisons VAR V41,NAN=999999999 ;represents "not a number" VAR V42,SHUT1=1 ;primary shutter (normally open) VAR V43,SHUT2=0 ;secondary shutter (normally close) VAR V44,HE ;eye vertical position VAR V45,VE ;eye horizontal position VAR V46,HT2 ;target-2 horizontal position VAR V47,VT2 ;target-2 vertical position VAR V48,HT1 ;target-1 horizontal position VAR V49,VT1 ;target-1 vertical position VAR V50,DURFORG ;how long he has been forgiven VAR V51,DURFEED=0 ;duration he has been on-target before getting fed VAR V52,DURCONT=0 ;contiguously on-target VAR V53,DURON=0 ;total time on-target VAR V54,PARAMCHG=0 ;signals parameters changed -- VAR V55,SUCCESS ;comlete the task? ;we test the Digitial Input so the following VAR is reserved ;VAR V56 ;Collision and Mayhem ;we have DAC 0,1,2,3 so the following VAR are reserved ;V57, last DAC 0 value ;won't work ;V58, last DAC 1 value ;with galvo ;V59, last DAC 2 value ;V60, last DAC 3 value ;we don't have DAC 4,5,6,7 so ok to use the following VAR VAR V61,TEMPTIME ;time counter variable ;VAR V62, VAR V63,SBUFFER=1 ;which serial buffer to use 1 or 2 (must start with 1) VAR V64,FORGIVE=0 ;forgiveness ;the data table transfered to the sequencer ;0000 - 0999 Common parameters ;[0] := gWindowHvgDAC%; HWIND ;[1] := gWindowVvgDAC%; VWIND ;[10] := pRealMinTime*1000; ASSOONAS ;[11] := pRealMaxTime*1000; NOLATER ;[12] := pRealContiguousTime*1000; CONTTON ;[13] := pRealTimeOn*1000; TOTALTON ;[14] := pOnFirst*1000; DURFIRST ;[15] := pOnSubsequent*1000; DURSUB ;[16] := pForgiveness*1000; FORGTIME ;[30] := gWhichBooth ;[31] := update report window info ;1000 - and above = for passing Table parmeters related to this behavioral mode ;-------------------------------------------------------- ; I N I T I A L I Z E L E D A R R A Y ;Initialize the LED array so buffer #1 will be active first. ;3/19/03 ;-------------------------------------------------------- DIGLOW [10101111] ;1-AF CLEAR all boards DELAY 12 ;13-120 microsecond delay DIGLOW [10111111] ;14-BF INTENSITY all boards DELAY 12 ;27-120 microsecond delay CALL BRITE TICKS TIMECURR ;set this up just so the IDLE routine will get started TICKS TIMECHEK,msTick(1) ;1ms, 0.001s later CRATE HZ(0) ;stop the ch 0 sinewave if it is running DRATE HZ(0) ;stop the ch 1 sinewave if it is running DIGOUT [....1...] ;low de-activates the SONALERT MOVI SHUT1,1 ;open the primary shutter MOVI SHUT2,0 ;close the secondary shutter CALL SHUTTER ;-------------------------------------------------------- ; M E M O R Y ;Moves the target on up to 8 vectors defined by the user. ; ;Implemented: ; Fixed Step Relative to Target - backstep specified in deg or % ; Fixed Step Relative to Eye - backstep specified in deg or % ; ;Re-usable Variables: ; V1 = table data address pointer ; V2 = table data holder ; V3 = RTZ status (-1=random, 0=last position was zero, 1=last position was not zero) ; V4 = current X DAC value ; V5 = current Y DAC value ; V6 = next initial X DAC value ; V7 = next initial Y DAC value ; V8 = next adapt X DAC value ; V9 = next adapt Y DAC value ; V10 = copy of V17 ; V11 = post-response duration ; V12 = computation ; V13 = unused ; V14 = unused ; V15 = unused ; V16 = random initial step pointer ; V17 = random vector pointer ; ; TEMPTIME = countdown timer variable ; HITTYPE1 = how many times the adapt step has been presented ; HITTYPE2 = how many times the non-adapt step has been presented ; MYREPORT = signals when it is time to report new data to the user ; ;On Target parameter stored in TABLE, ZERO=0000 ; for LED computations ; ZERO+200 = one degree on X axis ; ZERO+201 = one degree on Y axis ; ZERO+202 = largest of one degree on X & Y ; ZERO+203 = half degree of largest ; ZERO+204 = X ; ZERO+205 = Y ; ZERO+206 = negative largest of one degree on X & Y ; ZERO+207 = negative half largest of one degree on X & Y ; ZERO+208 = BRD ; ZERO+209 = ADD ; ZERO+210 = color (grn=0 red=1) ; for timing ; ZERO+211 = primary only duration ; ZERO+212 = primary+secondary duration ; ZERO+213 = wait duration ; ZERO+214 = post response duration ; ZERO+215 = stim_1 duration ; ZERO+216 = stim_2 duration ; ;Table Data Map: ; 1000 = Memory paradigm ; ;Adapt paradigm info stored in TABLE, A=1000 ; A+0 = Type of adapt: 0=RelTarg, 1=RelEye, 2=ProEye ; A+1 = Type of stepping: 0=RTZ, 1=Random ; A+2 = Timeouts: 0="do not abort", 1=repeat trial, 2=new trial ; A+3 = Onset Velocity Threshold ; A+4 = Offset Velocity Threshold ; A+5 = ; A+6 = Follow Duration ; A+7 = Response Duration ; A+8 = Response Failure: 0=Do Not Flash, 1=Flash ; A+9 = Post Color: 0=both, 1=primary, 2=secondary ; A+10 ; A+11 ; A+12= Stimulation/NoStimulation ratio ; A+13= Memory / control trial ratio ; A+14 ; A+15 ; A+16 ; A+17 ; A+18 ; A+19 ; A+20-29 INITIAL STEPS on vector 0 in X DAC units ; A+30-39 INITIAL STEPS on vector 1 in X DAC units ; A+40-49 INITIAL STEPS on vector 2 in X DAC units ; A+50-59 INITIAL STEPS on vector 3 in X DAC units ; A+60-69 INITIAL STEPS on vector 4 in X DAC units ; A+70-79 INITIAL STEPS on vector 5 in X DAC units ; A+80-89 INITIAL STEPS on vector 6 in X DAC units ; A+90-99 INITIAL STEPS on vector 7 in X DAC units ; A+100-109 INITIAL STEPS on vector 0 in Y DAC units ; A+110-119 INITIAL STEPS on vector 1 in Y DAC units ; A+120-129 INITIAL STEPS on vector 2 in Y DAC units ; A+130-139 INITIAL STEPS on vector 3 in Y DAC units ; A+140-149 INITIAL STEPS on vector 4 in Y DAC units ; A+150-159 INITIAL STEPS on vector 5 in Y DAC units ; A+160-169 INITIAL STEPS on vector 6 in Y DAC units ; A+170-179 INITIAL STEPS on vector 7 in Y DAC units ; ; A+180-189 ADAPT STEPS on vector 0 in X DAC units ; A+190-199 ADAPT STEPS on vector 1 in X DAC units ; A+200-209 ADAPT STEPS on vector 2 in X DAC units ; A+210-219 ADAPT STEPS on vector 3 in X DAC units ; A+220-229 ADAPT STEPS on vector 4 in X DAC units ; A+230-239 ADAPT STEPS on vector 5 in X DAC units ; A+240-249 ADAPT STEPS on vector 6 in X DAC units ; A+250-259 ADAPT STEPS on vector 7 in X DAC units ; A+260-269 ADAPT STEPS on vector 0 in Y DAC units ; A+270-279 ADAPT STEPS on vector 1 in Y DAC units ; A+280-289 ADAPT STEPS on vector 2 in Y DAC units ; A+290-299 ADAPT STEPS on vector 3 in Y DAC units ; A+300-309 ADAPT STEPS on vector 4 in Y DAC units ; A+310-319 ADAPT STEPS on vector 5 in Y DAC units ; A+320-329 ADAPT STEPS on vector 6 in Y DAC units ; A+330-339 ADAPT STEPS on vector 7 in Y DAC units ; ; This has very little use since it has the address ; for the axes and not the axis the target is on. Because ; the sequencer moves the target in an XY fashion it ; doesn't know which axis the target is on. ; A+340-349 LED board addresses ; ; A+350-359 Axis Slopes ; A+360-369 PERPENDICULAR Axis Slopes ; A+370-379 EXCURSION LIMIT in X DAC units ; A+380-389 EXCURSION LIMIT in Y DAC units ; A+390-399 X value for 1 deg step (for LED computation) ; A+400-409 Y value for 1 deg step (for LED computation) ; A+410-419 Fixation durations ; A+420-429 Fixation + Peripheral durations ; A+430-439 Memory Wait Durations ; A+440-449 Peripheral durations ; A+450-459 step stimulation durations ; A+460-469 velocity stimulation durations ; ;Randomly chosen steps: ; A+500 Initial Step Size X ; A+501 Initial Step Size Y ; A+502 Adapt Step Size X ; A+503 Adapt Step Size Y ; A+504 Axis slope ; A+505 Axis perpendicular slope ; A+506 Axis Limit X ; A+507 Axis Limit Y ; ;1/1/03 ;-------------------------------------------------------- ADAPT: BEQ PARAMCHG,0,ADAPT ;wait for parameters to arrive BEQ PARAMCHG,2,ADAPT1 ;skip if not the first time through ;first time only ;--------------- NOP ;MARK 64 ; @ sign MOVI PARAMCHG,2 ;new parameters grabbed CALL ZEROVAR ;clear all the re-usable VAR MOVI V2,1 ;so it will update report first time through TABST V2,[ZERO+31] MOVI HITTYPE1,0 ;reset the non-adapt counter MOVI HITTYPE2,0 ;reset the adapt counter MOVI V1,1000 ;data pointer TABLD RTZ,[V1+1] ;get the RTZ field MOVI V4,0 ;load the middle position MOVI V5,0 DAC 0,V4 ;move to the middle DAC 1,V5 MOVI V6,0 ;load the middle position MOVI V7,0 DAC 2,V6 ;move to the middle DAC 3,V7 CALL STORSTEP ;so abort on first trial will have somewhere to go back to ;start a new trial ;------------- ADAPT1: MOVI WHICHTAR,1 ;should be looking at the primary target ADDI HITTYPE2,1 ;default inc non-adapt counter, undone later if adapt step ;move target to zero (RTZ) ? ;------------------------- ADAPT2: BEQ RTZ,-1,ADAPT5 ;branch if RTZ is not selected MOVI V4,0 ;last X MOVI V5,0 ;last Y MOVI RTZ,0 ;last position was 0,0 ;select new vector ;----------------- ADAPT5: MOVRND V17,3 ;get a random vector between 0-7 (hard-coded) ;get the stimulation durations ;-------------------------- MOV V10,V17 ;make a copy of the random number ADDI V10,450 ;add stimulation duration array offset ADD V10,V1 ;add 1000, the TABLE offset TABLD V2,[V10] ;get the stimulation duration TABST V2,[ZERO+215] ;store the stim_1 value MOV V10,V17 ;make a copy of the random number ADDI V10,460 ;add stimulation duration array offset ADD V10,V1 ;add 1000, the TABLE offset TABLD V2,[V10] ;get the stimulation duration TABST V2,[ZERO+216] ;store the stim_2 value ;get the axis limits for X & Y ;----------------------------- MOV V10,V17 ;make a copy of the random number ADDI V10,370 ;add X excursion limit array offset ADD V10,V1 ;add 1000, the TABLE offset TABLD V2,[V10] ;get the X limit TABST V2,[V1+506] ;store the X limit for later use ADDI V10,10 ;380-get the Y limit TABLD V2,[V10] ;get the X limit TABST V2,[V1+507] ;store the Y limit for later use ;get the DAC value for 1 degree for X & Y ;----------------------------- MOV V10,V17 ;make a copy of the random number ADDI V10,390 ;add X DAC value offset ADD V10,V1 ;add 1000, the TABLE offset TABLD V2,[V10] ;get the X DAC value TABST V2,[ZERO+200] ;store the X DAC value ADDI V10,10 ;400-add offset to get the Y DAC value TABLD V2,[V10] ;get the Y DAC value TABST V2,[ZERO+201] ;store the Y DAC value ;get the initial X step ;---------------------- MOV V10,V17 ;make a copy of the random number MULI V10,10 ;convert rand to step of 10 ADDI V10,20 ;offset to table which starts at 20 ADD V10,V1 ;add 1000, the TABLE offset MOVRND V16,3 ;get a random step between 0-7 (hard-coded) ADD V10,V16 ;add to vector index BEQ NAN,[V10],ADAPT5 ;test if vector and intial step X size are valid TABLD V6,[V10] ;get initial step X value TABST V6,[V1+500] ;hold initial step X ;ADD V6,V4 ;new Xpos = Xold + Xstep ;X new location rollover test ;---------------------- MOV V22,V6 ;copy the initial step X ADD V22,V4 ;add Xold BGE V4,ZERO,ADAPT6 ;branch if (+oldloc) ;negative old location BGE V6,ZERO,ADAPT9 ;branch if (-oldloc & +step) BLE V22,ZERO,ADAPT9 ;branch if (-oldloc & -step & -newloc) JUMP ADAPT5 ;ROLLOVER detected, get a different step ;positive old location ADAPT6: BLE V6,ZERO,ADAPT9 ;branch if (+oldloc & -step) BGE V22,ZERO,ADAPT9 ;branch if (-oldloc & -step & -newloc) JUMP ADAPT5 ;ROLLOVER detected, get a different step ADAPT9: MOV V6,V22 ;did not rollover, new location OK ;get the initial Y step ;---------------------- ADDI V10,80 ;offset to initial step Y size BEQ NAN,[V10],ADAPT5 ;test if vector and intial step Y size are valid TABLD V7,[V10] ;store initial step Y value TABST V7,[V1+501] ;hold initial step Y ;ADD V7,V5 ;new Ypos = Yold + Ystep ;Y new location rollover test ;---------------------- MOV V22,V7 ;copy the initial step Y ADD V22,V5 ;add Yold BGE V5,ZERO,ADAPT12 ;branch if (+oldloc) ;negative old location BGE V7,ZERO,ADAPT13 ;branch if (-oldloc & +step) BLE V22,ZERO,ADAPT13 ;branch if (-oldloc & -step & -newloc) JUMP ADAPT5 ;ROLLOVER detected, get a different step ;positive old location ADAPT12: BLE V7,ZERO,ADAPT13 ;branch if (+oldloc & -step) BGE V22,ZERO,ADAPT13 ;branch if (-oldloc & -step & -newloc) JUMP ADAPT5 ;ROLLOVER detected, get a different step ADAPT13: MOV V7,V22 ;did not rollover, new location OK ;test if initial X is within limit ;--------------------------------- BLE ZERO,[V1+506],ADAPT3 ;is limit negative or positive? BLT V6,[V1+506],ADAPT5 ;neg limit, test if position is smaller JUMP ADAPT4 ADAPT3: BGT V6,[V1+506],ADAPT5 ;pos limit, test if position is larger ;test if initial Y is within limit ;--------------------------------- ADAPT4: BLE ZERO,[V1+507],ADAPT7 ;is limit negative or positive? BLT V7,[V1+507],ADAPT5 ;neg limit, test if position is smaller JUMP ADAPT98 ADAPT7: BGT V7,[V1+507],ADAPT5 ;pos limit, test if position is larger ;get the X adapt step (even if it is ZERO) ;------------------- ADAPT98: ADDI V10,80 ;offset to adapt step X size TABLD V8,[V10] ;180, get adapt step X value TABST V8,[V1+502] ;hold adapt step X size OR percent ;ADD V8,V6 ;new Xpos = Xold + Xstep ;X new location rollover test ;---------------------- MOV V22,V8 ;copy the adapt step X ADD V22,V6 ;add Xold BGE V6,ZERO,ADAPT15 ;branch if (+oldloc) ;negative old location BGE V8,ZERO,ADAPT16 ;branch if (-oldloc & +step) BLE V22,ZERO,ADAPT16 ;branch if (-oldloc & -step & -newloc) JUMP ADAPT5 ;ROLLOVER detected, get a different step ;positive old location ADAPT15: BLE V8,ZERO,ADAPT16 ;branch if (+oldloc & -step) BGE V22,ZERO,ADAPT16 ;branch if (-oldloc & -step & -newloc) JUMP ADAPT5 ;ROLLOVER detected, get a different step ADAPT16: MOV V8,V22 ;did not rollover, new location OK ;get the Y adapt step (even if it is ZERO) ;------------------- ADDI V10,80 ;offset to adapt step Y size TABLD V9,[V10] ;190, get adapt step Y value TABST V9,[V1+503] ;hold adapt step Y size OR percent ;ADD V9,V7 ;new Ypos = Yold + Ystep ;Y new location rollover test ;---------------------- MOV V22,V9 ;copy the adapt step Y ADD V22,V7 ;add Yold BGE V7,ZERO,ADAPT17 ;branch if (+oldloc) ;negative old location BGE V9,ZERO,ADAPT18 ;branch if (-oldloc & +step) BLE V22,ZERO,ADAPT18 ;branch if (-oldloc & -step & -newloc) JUMP ADAPT5 ;ROLLOVER detected, get a different step ;positive old location ADAPT17: BLE V9,ZERO,ADAPT18 ;branch if (+oldloc & -step) BGE V22,ZERO,ADAPT18 ;branch if (-oldloc & -step & -newloc) JUMP ADAPT5 ;ROLLOVER detected, get a different step ADAPT18: MOV V9,V22 ;did not rollover, new location OK ;test if adapt X is within limit ;------------------------------- BLE ZERO,[V1+506],ADAPT93 ;is limit negative or positive? BLT V8,[V1+506],ADAPT5 ;neg limit, test if position is smaller JUMP ADAPT94 ADAPT93: BGT V8,[V1+506],ADAPT5 ;pos limit, test if position is larger ;test if adapt Y is within limit ;---------------------- ADAPT94: BLE ZERO,[V1+507],ADAPT97 ;is limit negative or positive? BLT V9,[V1+507],ADAPT5 ;neg limit, test if position is smaller JUMP ADAPT10 ADAPT97: BGT V9,[V1+507],ADAPT5 ;pos limit, test if position is larger ;select primary target only duration ;----------------------------------- ADAPT105: MOVRND V17,3 ;get a random vector between 0-7 (hard-coded) ADDI V17,410 ;add primary target only offset ADD V17,V1 ;add 1000, the TABLE offset BEQ NAN,[V17],ADAPT105 ;repeat until a valid value is found TABLD V2,[V17] ;prepare to store the value TABST V2,[ZERO+211] ;store the value ;select primary+secondary target duration ;---------------------------------------- ADAPT106: MOVRND V17,3 ;get a random vector between 0-7 (hard-coded) ADDI V17,420 ;add primary+secondary target offset ADD V17,V1 ;add 1000, the TABLE offset BEQ NAN,[V17],ADAPT106 ;repeat until a valid value is found TABLD V2,[V17] ;prepare to store the value TABST V2,[ZERO+212] ;store the value ;select wait duration ;--------------------- ADAPT107: MOVRND V17,3 ;get a random vector between 0-7 (hard-coded) ADDI V17,430 ;add primary+secondary target offset ADD V17,V1 ;add 1000, the TABLE offset BEQ NAN,[V17],ADAPT107 ;repeat until a valid value is found TABLD V2,[V17] ;prepare to store the value TABST V2,[ZERO+213] ;store the value ;select post response duration ;----------------------------- ADAPT108: MOVRND V17,3 ;get a random vector between 0-7 (hard-coded) ADDI V17,440 ;add post response offset ADD V17,V1 ;add 1000, the TABLE offset BEQ NAN,[V17],ADAPT108 ;repeat until a valid value is found TABLD V2,[V17] ;prepare to store the value TABST V2,[ZERO+214] ;store the value ;trial approved ;================================================================= CALL STORSTEP ;save target pos in case trial aborts ;primary only (initial) ;----------------------------------------------------------------- ADAPT10: DAC 0,V4 ;move the primary target to the last location DAC 1,V5 MOVI SHUT1,1 ;prepare to open red shutter MOVI SHUT2,0 ;prepare to close green shutter CALL SHUTTER ;do it CALL REDGRN ;must be on-target to start this period ;-------------------------------------- MOVI WHICHTAR,1 ;should be looking at the primary target TABLD TEMPTIME,[ZERO+211] ;pass the Fixation ms duration BEQ FORGIVE,1,ADAPT111 ;target is going to move, forgive him for being off targ ADAPT100: MARK 65 ;"A" CALL OTTEST ;read target and eye values then compare (takes < 0.24 ms) BEQ TRACKING,2,ADAPT101 ;confirm both H & V are on Primary target MARK 35 ;'#' = ABORT CALL FLASHPRI ;flash the primary target JUMP ADAPT100 ;test again ADAPT111: MARK 65 ;"A" MOVI FORGIVE,0 ;reset the forgive flag TABLD DURFORG,[ZERO+16] ;get forgiveness period SUB TEMPTIME,DURFORG ;subtract the forgiveness from FIXATION duration MULI DURFORG,100 ;forgive period x 100ticks/ms DELAY DURFORG MARK 97 ;"a" BLE TEMPTIME,ZERO,ADAPT103 ;protect against negative numbers ;primary period duration (fixation) ;---------------------------------- ADAPT101: NOP ;for STAY to work, TEMPTIME,[ZERO+211] is loaded above. CALL STAY ;must stay on target CALL NEWREDO ;control trial? ;-------------- MOVRND V2,7 ;get a random vector between 0-127 (hard-coded) BGT V2,[V1+13],ADAPT103 ;low control_trial, high memory_trial ;present control trial ;--------------------- DAC 0,V6 ;move the primary target to the peripheral location DAC 1,V7 MOVI SHUT1,1 ;prepare to open the red shutter CALL SHUTTER1 ;do it CALL REDGRN ;show the LED(s) MOVI WHICHTAR,1 ;start looking at the primary target MARK 03 ;"03" SAVE - a control initial target step has occured MOVI TEMPTIME,1000 ;allow 1000ms to arrive at new target CALL ARRIVE ;allow time to get on peripheral target BGT SUCCESS,0,ADAPT102 CALL NEWREDO ADAPT102: MOV V4,V6 ;valid trial, he got here, remember that MOV V5,V7 TABLD V11,[ZERO+214] ;load the post response duration value JUMP ADAPT99 ;finish off trial ;preset memory trial ;primary & secondary (memorize) ;----------------------------------------------------------------- ADAPT103: NOP MARK 66 ;"B" DAC 2,V6 ;move the secondary target to the next location DAC 3,V7 MOVI SHUT2,1 ;prepare to open the green shutter CALL SHUTTER2 ;do it CALL REDGRN TABLD TEMPTIME,[ZERO+212] ;pass the ms duration CALL STAY ;must stay on target CALL NEWREDO ;primary only (wait) ;----------------------------------------------------------------- TABLD TEMP1,[V1+430] ;get wait duration BEQ TEMP1,0,ADAPT150 ;skip if no wait period has been specified MARK 67 ;"C" MOVI SHUT2,0 ;prepare to close green shutter CALL SHUTTER2 ;do it CALL REDGRN TABLD TEMPTIME,[ZERO+213] ;pass the ms mduration CALL STAY ;must stay on target CALL NEWREDO ;extinguish the primary target, time to move ;----------------------------------------------------------------- ADAPT150: MOVI SHUT1,0 ;RED off CALL SHUTTER1 DAC 0,V6 ;move the primary DAC to the next target location DAC 1,V7 CALL REDGRN MOVI WHICHTAR,2 ;start looking at the secondary target MARK 01 ;"01" SAVE - a memory initial target step has occured ;stimulate - move - stimulate (all modes) ;-------------------------------------------------- CALL STIMONE ;stimulate after target step CALL STILL ;no guessing, he cannot move for 50msec after shutter CALL NEWREDO TABLD TEMPTIME,[V1+7] ;load the response ms duration CALL ACCEL ;we're adapting, detect acceleration MARK 68 ;"D" accelerated CALL NEWREDO CALL STIMTWO ;stimulate after velocity detection BNE ZERO,[V1+502],ADAPT14 ;7180- adapt X step specified ? BNE ZERO,[V1+503],ADAPT14 ;7190- adapt Y step specified ? ; BNE ZERO,[V1+502],ADAPT59 ;7180- adapt X step specified ? ; BNE ZERO,[V1+503],ADAPT59 ;7190- adapt Y step specified ? ;response time, land on peripheral target ;-------------------------------------------------- ;open the shutter specified by the user CALL WINDDOUB MOVI TEMPTIME,100 ;allow 100ms after ACCEL to complete the movement CALL ARRIVE ;allow time to get on peripheral target CALL WINDHALF BGT SUCCESS,0,ADAPT555 CALL NEWREDO ADAPT555: MARK 69 ;"E" arrived MOV V4,V6 ;valid trial, he got here, remember that MOV V5,V7 ;turn on the requested target(s) HERE: MOVI SHUT1,0 ;RED explicity off MOVI SHUT2,0 ;GRN explicity off BLT ZERO,[V1+9],ADAPT222 ;prepare for RED+GREEN=0 ;RED & GRN ;--------- MOVI SHUT1,1 ;prepare to open the red shutter CALL SHUTTER1 ;do it MOVI SHUT2,1 ;prepare to open the green shutter CALL SHUTTER2 ;do it JUMP ADAPT444 ADAPT222: MOVI V2,1 BLT V2,[V1+9],ADAPT333 ;prepare for RED=1 ;RED only ;-------- MOVI SHUT1,1 ;prepare to open the red shutter CALL SHUTTER1 ;do it JUMP ADAPT444 ;GRN only ;-------- ADAPT333: MOVI SHUT2,1 ;prepare to open the green shutter=2 CALL SHUTTER2 ;do it ADAPT444: CALL REDGRN ;show the LED(s) JUMP ADAPT14 ;completely bypass adaptation ;4/27/07 all the adaption code was removed since no one is using it. ;The preceding releases have it if is needed. ;+follow+ ;-------- ADAPT14: NOP TABLD V11,[ZERO+214] ;load the post response duration value BEQ ZERO,[V1+6],ADAPT96 ;only run if FOLLOW has a non-zero value MARK 71 ;"G" CALL FOLLOW ;target follows eye JUMP ADAPT99 ;can't "follow" and stay on target too ;-follow- ;+stay on target+ ;-------- ADAPT96: CALL WINDDOUB MOVI TEMPTIME,300 ;load 300 ms CALL STAY ;for 300ms, he must stay on target CALL WINDHALF CALL NEWREDO MARK 72 ;"H" ADDI V11,-300 ;subtract the time required to be OT BGE V11,0,ADAPT99 ;make sure the post-response time is no shorter than zero MOVI V11,0 ;now its not negative ;-stay on target- ;+peripheral only (post-response) ;----------------------------------------------------------------- ADAPT99: CALL FEED ;after "follow" or "stay on target" MULI V11,100 ;convert ms to 100khz sample ticks DELAY V11 CALL OTTEST ;read target and eye values then compare (takes < 0.24 ms) BNE TRACKING,2,ADAPT133 ;feed if he's OT at the end of Post Response period CALL FEED ;after "follow" or "stay on target" ;+peripheral only (post-response) ADAPT133: MOVI V2,1 ;signal that it is time to show the user some numbers TABST V2,[ZERO+31] MOVI FORGIVE,0 ;initialize to not forgive him (only needed for RTZ) BEQ RTZ,-1,ADAPT134 ;branch if RTZ is not selected MOVI FORGIVE,1 ;this is RTZ so, forgive him for being off targ ADAPT134: JUMP ADAPT ;-memory ;-------------------------------------------------------- ; W I N D D O U B ;Temporarily double the size of the on-target windows for ;memory-guided movements ;1/26/07 ;-------------------------------------------------------- WINDDOUB: TABLD V2,[ZERO] ;get H window size MOVI V23,2 MUL V2,V23 ;compute double the window size TABST V2,[ZERO] ;store memory-guided H window size TABLD V2,[ZERO+1] ;get V window size MOVI V23,2 MUL V2,V23 ;compute double the window size TABST V2,[ZERO+1] ;store memory-guided V window size RETURN ;-------------------------------------------------------- ; W I N D H A L F ;Restore the normal size of the on-target windows for ;visually-guided movements ;1/26/07 ;-------------------------------------------------------- WINDHALF: TABLD V2,[ZERO] ;get H window size MOVI V23,2 DIV V2,V23 ;compute half the window size TABST V2,[ZERO] ;restore the visually-guided H window size TABLD V2,[ZERO+1] ;get V window size MOVI V23,2 DIV V2,V23 ;compute half the window size TABST V2,[ZERO+1] ;restore the visually-guided V window size RETURN ;-------------------------------------------------------- ; N E W R E D O ;Branch to get a NEW trial or REDO trial depending ;on what the user has selected. ; ;Assumes that an on-target or velocity test has been done ;and the result is in the VAR SUCCESS. ;3/25/05 ;-------------------------------------------------------- NEWREDO: BEQ PARAMCHG,0,ADAPT ;check if the user has opened the Memory Setup dialog box BNE SUCCESS,0,NEWREDO1 ;ACCEL can return -1 0 +1 ;1/31/07 next line may not be necessary if a checkbox is added to the ;Behavior dialogbox to force monkey to have a velocity at all times. ;The OT checkbox satisfies the program before it gets to NEWREDO. TABLD V2,[ZERO+17] ;25-test if using OT override BEQ V2,1,NEWREDO1 ;branch to pretend participation MARK 35 ;'#' = ABORT MOVI V2,1 ;A+2 = Timeouts: 0=repeat trial, 1=new trial BEQ V2,[V1+2],ADAPT1 ;get a new trial, [V1+2]=1 CALL LOADSTEP ;get last target positions JUMP ADAPT10 ;redo last trial NEWREDO1: RETURN ;just keep moving, he behaved or [V1+2]=0 ;-------------------------------------------------------- ; S T O R S T E P ;Store the primary and secondary target locations TO the ;table so the trial can be re-presented if he fails. ; ;12/9/05 ;-------------------------------------------------------- STORSTEP: TABST V4,[V1+508] ;primary X TABST V5,[V1+509] ;primary Y TABST V6,[V1+510] ;secondary X TABST V7,[V1+511] ;secondary Y RETURN ;-------------------------------------------------------- ; L O A D S T E P ;Load the primary and secondary target locations FROM the ;table so the trial can be re-presented. ; ;12/9/05 ;-------------------------------------------------------- LOADSTEP: TABLD V4,[V1+508] ;primary X TABLD V5,[V1+509] ;primary Y TABLD V6,[V1+510] ;secondary X TABLD V7,[V1+511] ;secondary Y RETURN ;-------------------------------------------------------- ; R E D G R N ;Pass all the right values in preparation to draw the ;RED and GRN LEDs. ;convert DAC positions to LED array information ;3/22/05 ;-------------------------------------------------------- REDGRN: TABST V4,[ZERO+204] ;load RED X TABST V5,[ZERO+205] ;load RED Y MOVI V24,1 ;RED TABST V24,[ZERO+210] ;set RED color bit CALL DAC2LED ;convert DAC to RED LED TABST V6,[ZERO+204] ;load GRN X TABST V7,[ZERO+205] ;load GRN Y MOVI V24,0 ;GRN TABST V24,[ZERO+210] ;set GRN color bit CALL DAC2LED ;convert DAC to GRN LED CALL LEDS ;display the RED & GRN LEDs RETURN ;-------------------------------------------------------- ; F L A S H P R I ;Flash the primary target once. ;2/22/05 ;-------------------------------------------------------- FLASHPRI: MARK 97 ;"a" DELAY 50000 ;half-second on MOVI SHUT1,0 ;prepare to open primary shutter CALL SHUTTER1 ;do it CALL REDGRN DELAY 50000 ;half-second off MOVI SHUT1,1 ;prepare to close primary shutter CALL SHUTTER1 ;do it CALL REDGRN RETURN ;-------------------------------------------------------- ; F L A S H S E C ;Flash the secondary target once. ;2/22/05 ;-------------------------------------------------------- FLASHSEC: DELAY 50000 ;half-second on MOVI SHUT2,0 ;prepare to open secondary shutter CALL SHUTTER2 ;do it CALL REDGRN DELAY 50000 ;half-second off MOVI SHUT2,1 ;prepare to close secondary shutter CALL SHUTTER2 ;do it CALL REDGRN RETURN ;-------------------------------------------------------- ; G E T P O S ;Load the eye and target positions for processing by ;script routine TimeToMoveOrFeed. ;10/1/03 ;-------------------------------------------------------- GETPOS: CHAN HE,2 ;1-read the current H eye CHAN VE,3 ;2-read the current V eye CHAN HT1,4 ;3-read the current H primary target CHAN VT1,5 ;4-read the current V primary target CHAN HT2,8 ;5-read the current H secondary target CHAN VT2,9 ;6-read the current V secondary target RETURN ;7- ;-------------------------------------------------------- ; O T T E S T ;Tests if the animal is on-target horizontally and ;vertically and reports the result. Requires 0.24ms or less. ; ;Because the program passes through here EVERY millisecond ;and there is now plenty of sequencer script space, it makes ;sense to have just one branch point to handle the primary/ ;secondary OT test decision. 2.18.05. Alternatively, could ;have had one routine with more branch points. That approach ;would have cost 10ms more time. ; ; ;Sequence Variable Map: ; TEMPWIND = window size ; TEMPTRAK = target position ; TRACKING = 0, 1 or 2 depending if he is OT or not ; WHICHTAR = 1-primary, 2-secondary ; ;On Target parameter stored in TABLE, ZERO=0000 ; ZERO+0 = gWindowHvgDAC%; HWIND ; ZERO+1 = gWindowVvgDAC%; VWIND ; ;10/7/04 ;-------------------------------------------------------- ;This routine has NOT been updated to have forceOT feature OTTEST: BEQ WHICHTAR,2,OTTEST10 ;1-which target? ;compare EYE to PRIMARY target ;-------------------------------- MOVI TRACKING,0 ;2-initialize CALL GETPOS ;9-find out where targ & eye are TABLD TEMPWIND,[ZERO] ;10-HWIND MOV TEMPTRAK,HT1 ;11-load horizontal target SUB TEMPTRAK,HE ;12-subtract horizonal eye BGT TEMPTRAK,0,OTTEST1 ;13-test if result is negative MULI TEMPTRAK,-1 ;14-abs() OTTEST1: BGT TEMPTRAK,TEMPWIND,OTTEST2 ;15-test if he is H-OT ADDI TRACKING,1 ;16-horizontally on-target OTTEST2: TABLD TEMPWIND,[ZERO+1] ;17-VWIND MOV TEMPTRAK,VT1 ;18-load vertical target SUB TEMPTRAK,VE ;19-subtract vertical eye BGT TEMPTRAK,0,OTTEST3 ;20-test if result is negative MULI TEMPTRAK,-1 ;21-abs() OTTEST3: BGT TEMPTRAK,TEMPWIND,OTTEST4 ;23-test if he is V-OT ADDI TRACKING,1 ;24-vertically on-target OTTEST4: TABLD V2,[ZERO+17] ;25-test if using OT override BEQ V2,0,OTTEST5 ;26-do it the old fashioned way, earn it! MOVI TRACKING,2 ;27-force him to be on-target, cheater! OTTEST5: BEQ TRACKING,2,OTTEST6 ;28- DIGOUT [....1...] ;29-low de-activates the SONALERT RETURN ;30- OTTEST6: DIGOUT [....0...] ;31-high activates the SONALERT RETURN ;32- ;compare EYE to SECONDARY target ;-------------------------------- OTTEST10: MOVI TRACKING,0 ;2-initialize CALL GETPOS ;9-find out where targ & eye are TABLD TEMPWIND,[ZERO] ;10-HWIND MOV TEMPTRAK,HT2 ;11-load horizontal target SUB TEMPTRAK,HE ;12-subtract horizonal eye BGT TEMPTRAK,0,OTTEST11 ;13-test if result is negative MULI TEMPTRAK,-1 ;14-abs() OTTEST11: BGT TEMPTRAK,TEMPWIND,OTTEST12 ;15-test if he is H-OT ADDI TRACKING,1 ;16-horizontally on-target OTTEST12: TABLD TEMPWIND,[ZERO+1] ;17-VWIND MOV TEMPTRAK,VT2 ;18-load vertical target SUB TEMPTRAK,VE ;19-subtract vertical eye BGT TEMPTRAK,0,OTTEST13 ;20-test if result is negative MULI TEMPTRAK,-1 ;21-abs() OTTEST13: BGT TEMPTRAK,TEMPWIND,OTTEST14 ;23-test if he is V-OT ADDI TRACKING,1 ;24-vertically on-target OTTEST14: TABLD V2,[ZERO+17] ;25-test if using OT override BEQ V2,0,OTTEST15 ;26-do it the old fashioned way, earn it! MOVI TRACKING,2 ;27-force him to be on-target, cheater! OTTEST15: BEQ TRACKING,2,OTTEST16 ;28- DIGOUT [....1...] ;29-low de-activates the SONALERT RETURN ;30- OTTEST16: DIGOUT [....0...] ;31-high activates the SONALERT RETURN ;32- ;-------------------------------------------------------- ; A R R I V E ;Test that the animal lands on target within a specified ;period of time. ; ; Input VAR ; TEMPTIME = duration of test in milliseconds ; ; Output VAR ; SUCCESS = 0=failed 1=succeeded ; ;2/24/05 ;-------------------------------------------------------- ARRIVE: BEQ TEMPTIME,ZERO,ARRIVE1 ;exit "successfully" if duration is ZERO MULI TEMPTIME,msTick(1) ;convert from ms to ticks TICKS TIMECHEK ;get the current time ADD TIMECHEK,TEMPTIME ;add the duration ARRIVE2: CALL OTTEST BEQ TRACKING,2,ARRIVE1 ;ontarget? all done TICKS TIMECURR ;get the current time BLT TIMECURR,TIMECHEK,ARRIVE2 ;keep checking ARRIVE3: MOVI SUCCESS,0 ;he never arrived on-target RETURN ARRIVE1: MOVI SUCCESS,1 ;he arrived on-target RETURN ;-------------------------------------------------------- ; S T A Y ;Stay on target for a specified period of time. ; ; Input VAR ; TEMPTIME = duration of test in milliseconds ; ; Output VAR ; SUCCESS = 0=failed 1=succeeded ; ;2/24/05 ;-------------------------------------------------------- STAY: BEQ TEMPTIME,ZERO,STAY1 ;exit if duration is ZERO MULI TEMPTIME,msTick(1) ;convert from ms to ticks TICKS TIMECHEK ;get the current time ADD TIMECHEK,TEMPTIME ;add the MEMORIZE duration STAY2: CALL OTTEST BLT TRACKING,2,STAY3 ;offtarget? start at beginning of trial STAY4: TICKS TIMECURR ;get the current time BLT TIMECURR,TIMECHEK,STAY2 ;keep checking STAY1: MOVI SUCCESS,1 ;he stayed on target RETURN STAY3: MOVI SUCCESS,0 ;he went off target RETURN ;-------------------------------------------------------- ; S T I L L ; ;Test that the animal does NOT exceed the specified eye velocity. ; ;I n p u t V a r ; THRESH2 = threshold velocity to come down to (in DAC bits) ;C o m p u t a t i o n V a r ; TEMPTIME = count down to zero ; TEMP3 = process H velocity (ch6) ; TEMP4 = process V velocity (ch7) ;O u t p u t V a r ; SUCCESS = 0:moved +1:remained still ; ;12/7/05 ;-------------------------------------------------------- STILL: MOVI TEMPTIME,50 ;millisecond ticks STILL1: CHAN TEMP3,6 ;1-read the current analog velocity signal CHAN TEMP4,7 ;2-read the curennt analog velocity signal BGT TEMP3,[V1+3],STILL2 ;3-positive horizontal movement BGT TEMP4,[V1+3],STILL2 ;4-positive vertical movement MULI TEMP3,-1 ;5-invert to test negative direction MULI TEMP4,-1 ;6-invert to test negative direction BGT TEMP3,[V1+3],STILL2 ;7-negative direction movement BGT TEMP4,[V1+3],STILL2 ;8-negative direction movement DELAY 90 ;9-consume remaining millisecond DBNZ TEMPTIME,STILL1 ;10-test until period is over MOVI SUCCESS,1 ;successful trial RETURN STILL2: MOVI SUCCESS,0 ;unsuccessful, he moved! RETURN ;-------------------------------------------------------- ; A C C E L ; ;Test when the animal exceeds a specified eye velocity. ; ;I n p u t V a r ; THRESH2 = threshold velocity to come down to (in DAC bits) ;C o m p u t a t i o n V a r ; TEMPTIME = count down to zero ; TEMP3 = process H velocity (ch6) ; TEMP4 = process V velocity (ch7) ;O u t p u t V a r ; SUCCESS = -1:negative thresh 0:failed +1:positive thresh ; ;1/22/04 ;-------------------------------------------------------- ACCEL: BEQ TEMPTIME,ZERO,ACCEL4 ;exit if duration is ZERO MULI TEMPTIME,msTick(1) ;convert from ms to ticks TICKS TIMECHEK ;get the current time ADD TIMECHEK,TEMPTIME ;add the duration ACCEL1: CHAN TEMP3,6 ;1-read the current analog velocity signal CHAN TEMP4,7 ;2-read the curennt analog velocity signal BGT TEMP3,[V1+3],ACCEL2 ;3-positive horizontal movement BGT TEMP4,[V1+3],ACCEL2 ;4-positive vertical movement MULI TEMP3,-1 ;5-invert to test negative direction MULI TEMP4,-1 ;6-invert to test negative direction BGT TEMP3,[V1+3],ACCEL3 ;7-negative direction movement BGT TEMP4,[V1+3],ACCEL3 ;8-negative direction movement TICKS TIMECURR ;get the current time BLT TIMECURR,TIMECHEK,ACCEL1 ;keep checking ACCEL4: MOVI SUCCESS,0 ;unsuccessful trial RETURN ACCEL2: MOVI SUCCESS,1 ;successful positive direction trial RETURN ACCEL3: MOVI SUCCESS,-1 ;successful negative direction trial RETURN ;-------------------------------------------------------- ; D E C E L ; ;Test when the animal slows to a specified eye velocity. ; ;I n p u t V a r ; THRESH2 = threshold velocity to come down to (in DAC bits) ;C o m p u t a t i o n V a r ; TEMPTIME = count down to zero ; TEMP3 = process H velocity (ch6) ; TEMP4 = process V velocity (ch7) ;O u t p u t V a r ; SUCCESS = 0:didn't stop in time +1:came to a stop ; ;1/22/04 ;---------------------------------------------- DECEL: MOVI TEMPTIME,1000 ;he's moved, now find the end of the movement DECEL1: CHAN TEMP3,6 ;1-read the current analog velocity signal CHAN TEMP4,7 ;2-read the curennt analog velocity signal BGT TEMP3,[V1+4],DECEL2 ;3-positive horizontal movement BGT TEMP4,[V1+4],DECEL2 ;4-positive vertical movement MULI TEMP3,-1 ;5-invert to test negative direction MULI TEMP4,-1 ;6-invert to test negative direction BGT TEMP3,[V1+4],DECEL2 ;7-negative direction movement BGT TEMP4,[V1+4],DECEL2 ;8-negative direction movement JUMP DECEL3 ;9-all channels are below threshold ;Since there are four velocity tests and any one of them can branch ;the program this timing scheme can be off by 0.0003 seconds DECEL2: DELAY 89 ;10-consume remaining millisecond DBNZ TEMPTIME,DECEL1 ;11-test until period is over MOVI SUCCESS,0 ;UNsuccessful trial, eyes never came to a stop RETURN DECEL3: MOVI SUCCESS,1 ;successful trial, report which direction he moved RETURN ;-------------------------------------------------------- ; F O L L O W ;This moves the target to the detected eye position. ;Updating the position every millisecond. ;11/26/03 ;-------------------------------------------------------- FOLLOW: TICKS TIMECHEK ;get the current time TABLD V2,[V1+6] ;get the follow duration ADD TIMECHEK,V2 ;add the MEMORIZE duration (temporarily 1 second) FOLLOW1: CALL GETPOS ;get eye and target positions MOVI TEMP1,65536 MUL TEMP1,HE ;scale 16-bit A/D sig to the 32-bit D/A sig DAC 0,TEMP1 ;move the target to the eye position MOVI TEMP1,65536 MUL TEMP1,VE ;scale 16-bit A/D sig to the 32-bit D/A sig DAC 1,TEMP1 ;move the target to the eye position CALL DAC2LED ;convert DAC to LED CALL LEDS ;display the LED BLT TIMECURR,TIMECHEK,FOLLOW1 ;keep checking RETURN ;-------------------------------------------------------- ; S H U T T E R ;Sets the shutters open or closed. ;12/17/02 ;-------------------------------------------------------- SHUTTER: CALL SHUTTER1 ;set the primary shutter CALL SHUTTER2 ;set the secondary shutter RETURN ;-------------------------------------------------------- ; S H U T T E R 1 ;Sets primary shutter open or closed. ; 0 = HIGH OUTPUT ; 1 = LOW OUTPUT ;9/4/03 ;-------------------------------------------------------- SHUTTER1: TABLD V2,[ZERO+30] BEQ V2,0,SHUT1ROB ;Robinson convention is opposite of the Fuchs convention ;BEQ V2,3,SHUT1ROB ;Visual convention is opposite of the Fuchs convention ;0=ROB,1=OKN,2=LED,3=VIS ;Fuchs shutters BEQ SHUT1,1,OPENF DIGOUT [.......1] ;close the primary shutter MARK 70 ;"F" for "OFF" RETURN OPENF: DIGOUT [.......0] ;open the primary shutter MARK 78 ;"N" for "ON" RETURN ;Robinson shutters SHUT1ROB: BEQ SHUT1,1,OPENR DIGOUT [.......0] ;close the primary shutter MARK 70 ;"F" for "OFF" RETURN OPENR: DIGOUT [.......1] ;open the primary shutter MARK 78 ;"N" for "ON" RETURN ;-------------------------------------------------------- ; S H U T T E R 2 ;Sets secondary shutter open or closed. ; 0 = HIGH OUTPUT ; 1 = LOW OUTPUT ;9/4/03 ;-------------------------------------------------------- SHUTTER2: BEQ SHUT2,1,S2OPEN DIGOUT [......0.] ;close the secondary shutter MARK 102 ;"f" for "off" RETURN S2OPEN: DIGOUT [......1.] ;open the secondary shutter MARK 110 ;"n" for "on" RETURN ;-------------------------------------------------------- ; F E E D ;Sends a feeder pulse. ;10/12/04 ;-------------------------------------------------------- FEED: DIGOUT [.....1..] ;1-high triggers the feeder DELAY 100 ;101-1 ms pulse width DIGOUT [.....0..] ;102-low is the feeder off state MARK 64 ;@ RETURN ;103- ;-------------------------------------------------------- ; S T I M ;Sends a stimulation pulse. ;12/1/05 ;-------------------------------------------------------- STIMONE: MOVRND V2,7 ;get a random vector between 0-127 (hard-coded) BGT V2,[V1+12],STIM2 ;low stimulates, high does not stimulate TABLD V2,[ZERO+215] ;first stim period called JUMP STIM1 STIMTWO: MOVRND V2,7 ;get a random vector between 0-127 (hard-coded) BGT V2,[V1+12],STIM2 ;low stimulates, high does not stimulate TABLD V2,[ZERO+216] ;second stim period called STIM1: BLE V2,ZERO,STIM2 ;skip if dur = 0 DIGOUT [...1....] ;trigger stimulation MARK 47 ;/character DELAY V2 DIGOUT [...0....] ;stop stimulation MARK 92 ;\character STIM2: RETURN ;-------------------------------------------------------- ; DAC2LED ;this algorithm determines what LED board and address ;correspond to a pair of DAC X & Y coordinates. ;There are more sophisticated approaches, but it would ;be challenging to use them with adaptation which can ;change axes and confuse the LED board assignment. ;looks like it will take about half a millisecond ;to do the conversion for red and again for green ;Re-usable Variables: ; V1 = table data address pointer ; V2 = table data holder ; V24 = computations ; V25 = X ; V26 = Y ; V23 = computations ;On Target parameter stored in TABLE, ZERO=0000 ; ZERO+200 = (IN ) one degree on X axis ; ZERO+201 = (IN ) one degree on Y axis ; ZERO+202 = (IN ) largest of one degree on X & Y ; ZERO+203 = (computed) half degree of largest ; ZERO+204 = (IN ) X target DAC values ; ZERO+205 = (IN ) Y target DAC values ; ZERO+206 = (computed) negative largest of one degree on X & Y ; ZERO+207 = (computed) negative half largest of one degree on X & Y ; ZERO+208 = (computed) BRD ; ZERO+209 = (computed) ADD ; ZERO+210 = (IN ) color (grn=0 red=1) ;Non-reuseable Variables: ; LEDBRD1 = (OUT ) indicate which LED board (RED) ; LEDADD1 = (OUT ) indicate which LED light (RED) ; LEDBRD2 = (OUT ) indicate which LED board (GRN) ; LEDADD2 = (OUT ) indicate which LED light (GRN) ;calling program must provide the DAC value for 1 degree on ;the current axes. This scheme only works because with 8 ;directions separated by 45 degrees the largest value always ;works (horz, vert and diagonals). ;1/25/05 ;-------------------------------------------------------- DAC2LED: TABLD V2,[ZERO+200] ;get X DAC degree BGT V2,ZERO,DAC2LEDD ;branch if positive MULI V2,-1 ;make positive DAC2LEDD: TABST V2,[ZERO+202] ;assume it is the largest TABLD V2,[ZERO+201] ;get Y DAC degree BGT V2,ZERO,DAC2LEDE ;branch if positive MULI V2,-1 ;make positive DAC2LEDE: BLE V2,[ZERO+202],DAC2LED1 ;test if it is larger TABST V2,[ZERO+202] ;store this as the largest MARK 86 ;"V" DAC2LED1: TABLD V2,[ZERO+202] ;get largest one DAC degree MULI V2,-1 TABST V2,[ZERO+206] ;store negative form of MOVI V23,2 DIV V2,V23 ;compute the size of a half degree TABST V2,[ZERO+207] ;store negative half degree MULI V2,-1 TABST V2,[ZERO+203] ;store positive of a half degree TABLD V25,[ZERO+204] ;load the target X value TABLD V26,[ZERO+205] ;load the target Y value ;test if center, special case since 0,0 is on theta 0 only ;--------------------------------------------------------- BLT V25,[ZERO+206],DAC2LED2 ;x lt -half ? BGT V25,[ZERO+203],DAC2LED2 ;x gt half ? BLT V26,[ZERO+206],DAC2LED2 ;y lt -half ? BGT V26,[ZERO+203],DAC2LED2 ;y lt half ? TABST ZERO,[ZERO+208] ;BRD=0 TABST ZERO,[ZERO+209] ;ADD=0 MARK 90 ;"Z" JUMP DAC2LEDC ;test if theta is on the vertical axis ;---------------- DAC2LED2: BGT V25,[ZERO+203],DAC2LED4 ;x gt half ? BLT V25,[ZERO+206],DAC2LED4 ;x lt -half ? ;theta = 90/270 ;-------------------------- MOV V23,V26 TABLD V24,[ZERO+202] DIV V23,V24 BGE V23,ZERO,DAC2LEDG ;is the ADD zero or higher, must be positive MULI V23,-1 ;make positive DAC2LEDG: TABST V23,[ZERO+209] ;divide by largest degree ;assign LED board ;---------------- BLT V26,0,DAC2LED3 MOVI V24,3 MARK 51 ;"3" TABST V24,[ZERO+208] ;BRD=3=theta 90 JUMP DAC2LEDC ;mult by 2, add 0 for grn or add 1 for red DAC2LED3: MOVI V24,8 TABST V24,[ZERO+208] ;BRD=8=theta=270 MARK 56 ;"8" JUMP DAC2LEDC ;mult by 2, add 0 for grn or add 1 for red ;compute LED address with X, 0/180 45/225 135/315 ;-------------------------- DAC2LED4: MOV V23,V25 TABLD V24,[ZERO+202] DIV V23,V24 ;divide by largest degree BGE V23,ZERO,DAC2LEDF ;is the ADD zero or higher, must be positive MULI V23,-1 ;make positive DAC2LEDF: TABST V23,[ZERO+209] ;ADD ;theta = horizontal ;------------------ BGT V26,[ZERO+203],DAC2LED8 ;y gt half ? BLT V26,[ZERO+206],DAC2LED8 ;y lt -half ? BLT V25,0,DAC2LED5 ;x lt 0 ? MOVI V24,0 TABST V24,[ZERO+208] ;BRD=0=theta 0 MARK 48 ;"0" JUMP DAC2LED6 DAC2LED5: MOVI V24,5 TABST V24,[ZERO+208] ;BRD=5=theta=180 MARK 53 ;"5" ;check if active LED is on an outer circuit board ;horizontal is +/-80 degrees spanning 4 boards DAC2LED6: BLE V23,47,DAC2LED7 ;LED on next board? MARK 49 ;"1" ;TABLD V24,[ZERO+208] ;BRD=BRD+1 board 0 to 1 or board 5 to 6 ADDI V24,1 TABST V24,[ZERO+208] ;TABLD V24,[ZERO+209] ADDI V23,-48 ;adjust address so it is between 0-47 on outer board TABST V23,[ZERO+209] DAC2LED7: JUMP DAC2LEDC ;mult by 2, add 0 for grn or add 1 for red ;theta = 45 or 135 ;----------------- DAC2LED8: BLT V26,0,DAC2LEDA ;y lt 0 ? BLT V25,0,DAC2LED9 ;x lt 0 ? MOVI V24,2 TABST V24,[ZERO+208] ;BRD=2=theta=45 MARK 50 ;"2" JUMP DAC2LEDC ;mult by 2, add 0 for grn or add 1 for red DAC2LED9: MOVI V24,4 TABST V24,[ZERO+208] ;BRD=4=theta=135 MARK 52 ;"4" JUMP DAC2LEDC ;mult by 2, add 0 for grn or add 1 for red ;theta = 225 or 315 ;------------------ DAC2LEDA: BGT V25,0,DAC2LEDB ;x gt 0 ? MOVI V24,7 MARK 55 ;"7" TABST V24,[ZERO+208] ;BRD=7=theta=225 JUMP DAC2LEDC ;mult by 2, add 0 for grn or add 1 for red DAC2LEDB: MOVI V24,9 TABST V24,[ZERO+208] ;BRD=9=theta=315 MARK 57 ;"9" DAC2LEDC: BEQ ZERO,[ZERO+210],DAC2LEDH ;branch if green ;RED--prepare the LED address to be sent to the LED ARRAY ;--------------------------------------------------- TABLD LEDADD1,[ZERO+209] MARK [ZERO+209] ;leave a mark with the LED number MULI LEDADD1,2 ADDI LEDADD1,1 ;color bit for RED MULI LEDADD1,256 ;RED--prepare the BOARD address to be sent to the LED ARRAY ;----------------------------------------------------- TABLD LEDBRD1,[ZERO+208] ADDI LEDBRD1,192 MULI LEDBRD1,256 RETURN ;GRN--prepare the LED address to be sent to the LED ARRAY ;--------------------------------------------------- DAC2LEDH: TABLD LEDADD2,[ZERO+209] MARK [ZERO+209] ;leave a mark with the LED number MULI LEDADD2,2 ADDI LEDADD2,0 ;color bit for GRN (add zero for completeness) MULI LEDADD2,256 ;GRN--prepare the BOARD address to be sent to the LED ARRAY ;----------------------------------------------------- TABLD LEDBRD2,[ZERO+208] ADDI LEDBRD2,192 MULI LEDBRD2,256 RETURN ;-------------------------------------------------------- ; L E D S ;Activate a red or a green LED. Seems that the parallel- ;to-serial interface requires 120 microsec between ;characters. The buffering is not as fast as Frank Miles ;had hoped. The time it takes to complete this command ;varies: ; RED only = 0.44 ms ; GRN only = 0.45 ms ; RED & GRN = 0.71 ms ;3/19/03 ;-------------------------------------------------------- LEDS: DIGLOW [10101111] ;1-AF clear all boards DELAY 12 ;13-120 microsecond delay BEQ SHUT1,0,LEDS2 ;14-present a red LED? DIGLOW LEDBRD1 ;15-C0 add address + deg theta DELAY 12 ;27-120 microsecond delay DIGLOW LEDADD1 ;28-radius in lower nibble DELAY 12 ;40-120 microsecond delay MARK 18 ;12x LEDS2: BEQ SHUT2,0,LEDS3 ;41-present a green LED? DIGLOW LEDBRD2 ;42-C0 add address + deg theta DELAY 12 ;54-120 microsecond delay DIGLOW LEDADD2 ;55-radius in lower nibble DELAY 12 ;67-120 microsecond delay MARK 19 ;13x LEDS3: BNE SBUFFER,1,LEDS1 ;68- DIGLOW [10001111] ;69-8F send to all boards, #1 buffer MOVI SBUFFER,2 ;70-prepare to use the other buffer next time RETURN ;71- LEDS1: DIGLOW [10011111] ;69-9F send to all boards, #2 buffer loads first by default MOVI SBUFFER,1 ;70-prepare to use the other buffer next time RETURN ;71- ;-------------------------------------------------------- ; B R I T E ;Set the LED intensity. ;5/5/06 ;-------------------------------------------------------- BRITE: MARK 38 ;'&' DIGLOW [ZERO+29] ;1- (06...0C) (1...12) LED intensity DELAY 12 ;2-14 microsecond delay BNE SBUFFER,1,BRITE1 ;15- DIGLOW [10001111] ;16-8F send to all boards, #1 buffer MOVI SBUFFER,2 ;17-prepare to use the other buffer next time RETURN ;18- BRITE1: DIGLOW [10011111] ;19-9F send to all boards, #2 buffer loads first by default MOVI SBUFFER,1 ;20-prepare to use the other buffer next time RETURN ;21- ;-------------------------------------------------------- ; Z E R O V A R ; ;Zeros all the re-usable VAR so that they are empty before ;using. ; ;11/8/04 ;-------------------------------------------------------- ZEROVAR: MOVI V1,0 MOVI V2,0 MOVI RTZ,0 MOVI V4,0 MOVI V5,0 MOVI V6,0 MOVI V7,0 MOVI V8,0 MOVI V9,0 MOVI V10,0 MOVI V11,0 MOVI V12,0 MOVI WHICHTAR,0 MOVI V14,0 MOVI V15,0 MOVI V16,0 MOVI V17,0 MOVI TEMP2,0 MOVI TEMP1,0 MOVI TEMP3,0 MOVI TEMP4,0 MOVI V22,0 MOVI V23,0 MOVI V24,0 MOVI V25,0 MOVI V26,0 RETURN