2  !   OUTPUT 2 USING "#,K";"<lf>INDENT<cr><lf>RE-STORE ""DS""<cr>"
4     !
6     END
8     !
10    ! PAGE -> 
12    !***********************************************************************
14 Appl_appl:SUB Appl_appl
16     !***********************************************************************
18     !* This subroutine is called when the digital scope application is first
20     !* run.  It sets up application specific common variables.
22     !***********************************************************************
24      COM /Appl_buf_info/ Disp_choices$(1:1,1:63)[20],Input_labels$(1:63)[20]
26      COM /Ds_data/ Data_header(1:63,1:10),INTEGER Ovld_buffer(1:63)
28      COM /Ds_block_ids/ REAL Icode_id,Input_buffer_id,Module_list_id,Ovld_buffer_id
30      COM /Ds_input_info/ REAL Num_inputs,INTEGER Power2_blk_size,Max_tdly_label$[50]
32      COM /Ds_input_info2/ REAL Ranges(1:63),Trigger_delays(1:63),Input_modes$(1:63)[10]
34      COM /Ds_meas_info/ INTEGER Triggered_mode,Single_mode
36      COM /Ds_meas_flags/ INTEGER Blk_in_progress
38      COM /Ds_icode_code/ Source$(0:100)[80],INTEGER Object(0:100)
40      COM /Ds_icode_info/ Info$(0:20)[40],INTEGER Assembled
42      COM /Ds_error/ INTEGER Errored,No_inputs
44      COM /Ds_key5/ INTEGER Key5_pressed
46     !
48      Assembled=0
50      SUBEXIT
52     !
54    SUBEND
56 !
58 Appl_common:SUB Appl_common
60     !************************************************************************
62     !* This subroutine provides access to common variables.  To do this,
64     !* type in 'CALL APPL_COMMON' from the keyboard.  When through, press
66     !* continue.  Some local variables are provided for convenience.
68     !* Since this subroutine provides no functionality, it can be deleted
70     !* once program debugging is complete.
72     !************************************************************************
74      COM /Appl_buf_info/ Disp_choices$(*),Input_labels$(*)
76      COM /Ds_data/ REAL Data_header(*),INTEGER Ovld_buffer(*)
78      COM /Ds_block_ids/ REAL Icode_id,Input_buffer_id,Module_list_id,Ovld_buffer_id
80      COM /Ds_input_info/ REAL Num_inputs,INTEGER Power2_blk_size,Max_tdly_label$[50]
82      COM /Ds_meas_info/ INTEGER Triggered_mode,Single_mode
84      COM /Ds_input_info2/ REAL Ranges(*),Trigger_delays(*),Input_modes$(*)
86      COM /Ds_icode_code/ Source$(*),INTEGER Object(*)
88      COM /Ds_icode_info/ Info$(*),INTEGER Assembled
90      COM /Ds_error/ INTEGER Errored,No_inputs
92      COM /Ds_key5/ INTEGER Key5_pressed
94      INTEGER I,J,K,L,M,N
96      REAL A,B,C,D,E,F
98      DIM A$[200],B$[200],C$[200]
100    !
102     PAUSE
104     SUBEXIT
106   SUBEND
108!
110 Appl_init_sprd:SUB Appl_init_sprd
112    !**********************************************************************
114    !* This subroutine set up the input and source spreadsheet selections
116    !* for the digital scope function.
118    !**********************************************************************
120     DIM Setup$(1:7)[20]
122    !
124    !Input spreadsheet setup:
126     REDIM Setup$(1:5)
128     Setup$(1)="INPUT MODE"
130     Setup$(2)="COUPLING"
132     Setup$(3)="GROUNDING"
134     Setup$(4)="RANGE"
136     Setup$(5)="TRIG DELAY"
138     Inpt_init(Setup$(*))
140    !
142    !Source spreadsheet setup:
144     REDIM Setup$(1:7)
146     Setup$(1)="MODE"
148     Setup$(2)="OFFSET"
150     Setup$(3)="AMPLITUDE"
152     Setup$(4)="SPAN"
154     Setup$(5)="CENTER FREQ"
156     Setup$(6)="SINE FREQ"
158     Setup$(7)="BURST %"
160     Srce_init(Setup$(*))
162    !
164     SUBEXIT
166   SUBEND
168!
170 Appl_init:SUB Appl_init
172    !***********************************************************************
174    !* This routine initializes the system for the digital scope function.
176    !* It should be called when first entering the application, and
178    !* whenever the system configuration has changed (CNFG spreadsheet).
180    !***********************************************************************
182     COM /Appl_buf_info/ Disp_choices$(*),Input_labels$(*)
184     COM /Ds_data/ REAL Data_header(*),INTEGER Ovld_buffer(*)
186     COM /Ds_block_ids/ REAL Icode_id,Input_buffer_id,Module_list_id,Ovld_buffer_id
188     COM /Ds_input_info/ REAL Num_inputs,INTEGER Power2_blk_size,Max_tdly_label$
190     DIM Temp$[255]
192    !
194    !Initialize spread sheets:
196     Appl_init_sprd
198     Meas_init
200    !
202    !Initialize and assemble ICODE program:
204     Ds_init_icode
206    !Initialize input modules:
208     Ds_init_inputs
210    !Get number of input modules and their names:
212     Ds_input_labels
214     Appl_new_labels
216    !
218     SUBEXIT
220   SUBEND
222!
224 Appl_main:SUB Appl_main(Init)
226    !***********************************************************************
228    !* This routine is the entry point for the digital scope function.
230    !* It sequences through the various digital scope functions: setting up
232    !* the hardware, allocating memory, setting up the plots, starting
234    !* measurements, collecting data, doing plots, accessing the various
236    !* spreadsheets, and error handling.
238    !***********************************************************************
240     COM /Ds_input_info/ REAL Num_inputs,INTEGER Power2_blk_size,Max_tdly_label$
242     COM /Ds_meas_info/ INTEGER Triggered_mode,Single_mode
244     COM /Ds_data/ REAL Data_header(*),INTEGER Ovld_buffer(*)
246     COM /Ds_error/ INTEGER Errored,No_inputs
248     INTEGER Meas_stopped,Restart_meas,Leave_me,Buf_allocated,Keys_changed
250     INTEGER Display_changed,Replot,Plot_erased,Valid_data
252     INTEGER Errored_key,Main_keys,Axs_interruptus
254    !
256     DISP "Setting up for digital scope . . ."
258     Buf_allocated=0
260    !
262    !Clear the 35651 module and abort any running ICODE:
264     Ds_attention
266    !
268    !Setup up initial softkeys:
270     GOSUB Appl_main_keys
272     Ds_clear_key5
274    !
276    !First init everything:
278     IF Init THEN CALL Appl_init
280    !
282     Restart_meas=1
284     Display_changed=1
286     Meas_stopped=0
288     Leave_me=0
290     Replot=0
292     Valid_data=0
294     Plot_erased=0
296     Errored=No_inputs
298     Errored_key=0
300     Axs_interruptus=0
302    !
304    !Allocate some dummy buffers:
306     ALLOCATE INTEGER Input_buffer(1:1,0:0)
308     ALLOCATE REAL Data_buffer(1:1,0:0)
310     Buf_allocated=1
312    !
314     REPEAT
316       IF Main_keys THEN 
318         ON KEY 7 LABEL "" GOSUB Appl_dummy
320       END IF
322      !
324       Single_mode=FNMeas_single
326       IF Restart_meas AND NOT No_inputs THEN 
328         DISP "Re-starting . . ."
330         Errored=0
332        !Clear the 35651 module and abort any running ICODE:
334         Ds_attention
336        !
338        !Get axis up as soon as possible:
340         Ds_setup_info2
342         Appl_update
344         Disp_plot_axis
346         Axs_interruptus=FNUser_key_press
348         Display_changed=0
350        !
352        !Start the measurement:
354         Appl_start
356         Restart_meas=0
358         Meas_stopped=0
360         Valid_data=0
362         Plot_erased=0
364        !
366         IF NOT Errored THEN 
368          !Allocate enough memory to upload the thruput block from the 35651:
370           DISP "Allocating memory . . ."
372           IF Buf_allocated THEN !Deallocate memory if previously allocated:
374             DEALLOCATE Input_buffer(*)
376             DEALLOCATE Data_buffer(*)
378             Buf_allocated=0
380           END IF
382           ALLOCATE INTEGER Input_buffer(1:Num_inputs,0:MAX(0,Power2_blk_size-1))
384           ALLOCATE REAL Data_buffer(1:Num_inputs,0:MAX(0,Power2_blk_size-1))
386           Buf_allocated=1
388           REDIM Ovld_buffer(1:Num_inputs)
390          !OUTPUT 701;"Available memory = "&VAL$(PROUND((VAL(SYSTEM$("AVAILABLE MEMORY"))/1.E+6),-6))&" megabytes."
392         END IF
394         DISP ""
396       END IF
398      !
400      !Re-plot grids if changed in any of the spreadsheets:
402       IF Display_changed OR Plot_erased OR Axs_interruptus THEN 
404         IF Display_changed THEN CALL Appl_update
406         Disp_plot_axis
408         Axs_interruptus=FNUser_key_press
410         Display_changed=0
412       END IF
414      !
416      !Re-plot old data if returning from a spreadsheet:
418      !(but only if valid data is available):
420       Replot=Plot_erased AND Valid_data
422      !
424       IF Main_keys THEN 
426         IF Errored THEN 
428           ON KEY 7 LABEL FNUser_keylabel$("RE-START") CALL User_key7isr
430           Errored_key=1
432         ELSE
434           Errored_key=0
436           IF Single_mode THEN 
438             IF Meas_stopped THEN 
440               ON KEY 7 LABEL FNUser_keylabel$("START") CALL User_key7isr
442             ELSE
444               ON KEY 7 LABEL FNUser_keylabel$("STOP") CALL User_key7isr
446             END IF
448           ELSE
450             IF Meas_stopped THEN 
452               ON KEY 7 LABEL FNUser_keylabel$("CONTINUE") CALL User_key7isr
454             ELSE
456               ON KEY 7 LABEL FNUser_keylabel$("PAUSE") CALL User_key7isr
458             END IF
460           END IF
462         END IF
464       END IF
466      !
468       Appl_meas_loop(Meas_stopped,Replot,Valid_data,Axs_interruptus,Input_buffer(*),Data_buffer(*))
470      !
472       WHILE FNUser_key_press
474         Ds_log_key5
476         IF Main_keys THEN 
478           Appl_do_main(Restart_meas,Meas_stopped,Display_changed,Keys_changed,Plot_erased,Leave_me,Valid_data,Axs_interruptus,Errored_key,Data_buffer(*))
480         ELSE
482           Appl_do_other(Restart_meas,Meas_stopped,Display_changed,Keys_changed,Plot_erased)
484         END IF
486       END WHILE
488      !
490       IF Keys_changed THEN 
492         IF Main_keys THEN 
494           GOSUB Appl_other_keys
496         ELSE
498           GOSUB Appl_main_keys
500         END IF
502       END IF
504     UNTIL Leave_me
506     SUBEXIT
508    !
510 Appl_dummy:!
512     RETURN 
514    !
516 Appl_main_keys:!
518     Main_keys=1
520     ON KEY 0 LABEL "" GOSUB Appl_dummy
522     ON KEY 1 LABEL FNUser_keylabel$("INPUT SETUP") CALL User_key1isr
524     ON KEY 2 LABEL FNUser_keylabel$("SOURCE SETUP") CALL User_key2isr
526     ON KEY 3 LABEL FNUser_keylabel$("DISPLAY SETUP") CALL User_key3isr
528     ON KEY 4 LABEL FNUser_keylabel$("MEASURE SETUP") CALL User_key4isr
530     ON KEY 5 LABEL FNUser_keylabel$("OTHER") CALL Ds_key5isr
532     ON KEY 6 LABEL FNUser_keylabel$("MARKER") CALL User_key6isr
534     ON KEY 7 LABEL "" GOSUB Appl_dummy
536     ON KEY 8 LABEL FNUser_keylabel$("EXIT") CALL User_key8isr
538     ON KEY 9 LABEL "" GOSUB Appl_dummy
540     Keys_changed=0
542     RETURN 
544     !
546 Appl_other_keys: !
548     Main_keys=0
550     ON KEY 0 LABEL "" GOSUB Appl_dummy
552     ON KEY 1 LABEL FNUser_keylabel$("HELP") CALL User_key1isr
554     ON KEY 2 LABEL FNUser_keylabel$("") CALL User_key2isr
556     ON KEY 3 LABEL FNUser_keylabel$("") CALL User_key3isr
558     ON KEY 4 LABEL FNUser_keylabel$("") CALL User_key4isr
560     ON KEY 5 LABEL FNUser_keylabel$("MAIN") CALL Ds_key5isr
562     ON KEY 6 LABEL FNUser_keylabel$("") CALL User_key6isr
564     ON KEY 7 LABEL FNUser_keylabel$("HARD RESTART") CALL User_key7isr
566     ON KEY 8 LABEL FNUser_keylabel$("") CALL User_key8isr
568     ON KEY 9 LABEL "" GOSUB Appl_dummy
570     Keys_changed=0
572     RETURN 
574     !
576   SUBEND
578!
580 Appl_start:SUB Appl_start
582    !*********************************************************************
584    !* This subroutine starts a digital scope measurement.
586    !* The sequence of events are:
588    !*    1) Initialize and download ICODE blocks
590    !*    2) Set up the input modules
592    !*    3) Start input modules
594    !*    4) Wait for all ready
596    !*    5) Synchronize input modules
598    !*    6) Start ICODE
600    !*    7) Start the ICODE data collection process (by continuing the
602    !*       ICODE program)
604    !*    8) If in a non-triggered mode, force a system trigger
606    !*********************************************************************
608     COM /Ds_meas_flags/ INTEGER Blk_in_progress
610     COM /Ds_error/ INTEGER Errored,No_inputs
612    !
614    !Initialize, download ICODE blocks (finds Max_tdly_label$):
616     Ds_init_blocks
618     IF Errored THEN SUBEXIT
620    !
622    !Setup inputs (needs Max_tdly_label$):
624     Ds_setup_inputs
626    !
628    !Hold off triggers, start and synchronize the inputs:
630     Hw_cmd("TRGA")
632     Inpt_cmd("ALL INPUT","STRT")
634     DISP "Waiting for hardware ready . . ."
636     Hw_wait_gbl_rdy
638     DISP ""
640     Hw_cmd("SYNC")
642    !
644    !Start ICODE:
646     Ds_start_icode
648    !
650    !Collect the first block so it will be ready:
652     Hw_cmd("CONT;TRGU")
654     Blk_in_progress=1
656    !
658    !Did everything start without errors?
660     DISP "Checking for errors . . ."
662     IF BIT(VAL(FNHw_cmd_rsp$("STC?")),9) THEN 
664       IF FNDiag_chk_errors THEN 
666         Errored=1
668         User_error("Error when starting measurement.")
670       END IF
672     END IF
674     DISP ""
676    !
678     SUBEXIT
680   SUBEND
682  !
684 Appl_update:SUB Appl_update
686   !***********************************************************************
688   !* This subroutine initializes the grids for the plot routines.  It is
690   !* called whenever the axis might have changed; for example, a range,
692   !* blocksize, or trigger delay change on one of the input modules.
694   !***********************************************************************
696     COM /Appl_buf_info/ Disp_choices$(*),Input_labels$(*)
698     COM /Ds_data/ REAL Data_header(*),INTEGER Ovld_buffer(*)
700     COM /Ds_input_info/ REAL Num_inputs,INTEGER Power2_blk_size,Max_tdly_label$
702     COM /Ds_input_info2/ REAL Ranges(*),Trigger_delays(*),Input_modes$(*)
704     COM /Ds_error/ INTEGER Errored,No_inputs
706     REAL Range,Y_min_max,Full_scale,Two_db_over,Dig_filt_corr
708     INTEGER I,Num_plots,Buf_num
710    !
712    !Special case if no inputs:
714     IF No_inputs THEN 
716       Ranges(1)=0.
718       Trigger_delays(1)=0.
720       Input_modes$(1)="VOLT"
722     END IF
724    !
726    !Scaling factors:
728     Two_db_over=10.^(-2./20.)       !Two dB overhead in front ends.
730     Dig_filt_corr=15094.3657/32768.   !Digital filter safe-scaling factor.
732     Full_scale=Two_db_over*Dig_filt_corr*32768.
734    !
736     Num_plots=FNDisp_num_plots
738     ALLOCATE Plot_to_buf(1:Num_plots)
740     ALLOCATE X_units$(1:Num_plots)[10],Y_units$(1:Num_plots)[10]
742     ALLOCATE Start_x(1:Num_plots),Per_bin_x(1:Num_plots)
744     ALLOCATE Start_bin(1:Num_plots),Num_bins(1:Num_plots)
746     ALLOCATE Y_def_max(1:Num_plots),Y_def_min(1:Num_plots)
748    !
750     MAT Data_header= (0)
752    !
754     FOR I=1 TO Num_plots
756       Buf_num=FNDisp_choice((I),1)
758       Plot_to_buf(I)=Buf_num
760       Range=Ranges(Buf_num)
762       IF Input_modes$(Buf_num)[1;2]="CH" THEN 
764         Y_units$(I)="C"
766         Y_min_max=(10.^(Range/20.))*1.E-12   !Ranges are in dBpC peak.
768         Y_def_min(I)=-1.*Y_min_max
770         Y_def_max(I)=Y_min_max
772       ELSE
774         Y_units$(I)="V"
776         Y_min_max=10.^(Range/20.)            !Ranges are in dBV peak.
778         Y_def_min(I)=-1.*Y_min_max
780         Y_def_max(I)=Y_min_max
782       END IF
784       Data_header(Buf_num,1)=0           !Data offset.
786       Data_header(Buf_num,2)=Full_scale/Y_min_max   !Data scale factor.
788      !Starting time for each channel is pre/post trigger delay divided
790      !by the effective sample rate:
792       Start_x(I)=Trigger_delays(Buf_num)/FNMeas_fs
794     NEXT I
796    !
798     MAT X_units$= ("SEC")
800     MAT Per_bin_x= (1./(FNMeas_fs))  !Seconds per point = 1/(sample rate).
802     MAT Start_bin= (0.)      !Start plotting at bin 0.
804     MAT Num_bins= (FNMeas_num_samp)
806    !
808     Disp_plot_set(Plot_to_buf(*),X_units$(*),Y_units$(*),Start_x(*),Per_bin_x(*),Start_bin(*),Num_bins(*),Y_def_max(*),Y_def_min(*))
810    !
812     SUBEXIT
814   SUBEND
816!
818 Appl_do_main:SUB Appl_do_main(INTEGER Restart,Stopped,Disp_modified,Keys_changed,Plot_erased,Leave_me,Valid_data,Axs_interruptus,E_key,REAL Data_buffer(*))
820    !*********************************************************************
822    !* This subroutine handles the main softkeys.
824    !*
826    !* The following variables are inputs to this routine:
828    !*               E_key: true if errored keys active.
830    !*          Valid_data: true if Data_buffer(*) contains valid data.
832    !*      Data_buffer(*): array of data points for marker routine.
834    !*     Axs_interruptus: true if a softkey interrupted axis generation.
836    !*
838    !* The following variables are returned:
840    !*             Restart: true if a spreadsheet change requires a restart.
842    !*             Stopped: true if measurement is to be stopped.
844    !*       Disp_modified: true if a change requires a different display.
846    !*        Keys_changed: true if the alternate softkeys are selected.
848    !*         Plot_erased: true if plots were erased by a spreadsheet or ?.
850    !*            Leave_me: true if exit key pressed.
852    !*          valid_data: false if a spreadsheet change invalidates data.
854    !*     Axs_interruptus: true if a softkey interrupted axis generation.
856    !*********************************************************************
858     COM /Ds_data/ REAL Data_header(*),INTEGER Ovld_buffer(*)
860     COM /Ds_meas_info/ INTEGER Triggered_mode,Single_mode
862     COM /Ds_meas_flags/ INTEGER Blk_in_progress
864     REAL Change_in_hw,Dummy
866     INTEGER Small_change
868    !
870     Key_num=FNUser_get_key
872    !
874     Change_in_hw=0
876     Plot_erased=0
878    !
880     SELECT Key_num
882     CASE 1
884       ON KEY Key_num LABEL FNUser_keylabel$("MAIN") CALL User_key1isr
886       CALL Inpt_spread(Change_in_hw)
888       OFF KEY Key_num
890       Plot_erased=1
892     CASE 2
894       ON KEY Key_num LABEL FNUser_keylabel$("MAIN") CALL User_key2isr
896       CALL Srce_spread(Change_in_hw)
898       OFF KEY Key_num
900       Plot_erased=1
902     CASE 3
904       ON KEY Key_num LABEL FNUser_keylabel$("MAIN") CALL User_key3isr
906       CALL Disp_spread(Dummy)
908       OFF KEY Key_num
910       Disp_modified=Dummy
912       Plot_erased=1
914     CASE 4
916       ON KEY Key_num LABEL FNUser_keylabel$("MAIN") CALL User_key4isr
918       CALL Meas_spread(Change_in_hw,Dummy)
920       OFF KEY Key_num
922       Small_change=Dummy
924       IF Small_change THEN Valid_data=0
926       Plot_erased=1
928     CASE 5
930       Keys_changed=1
932     CASE 6
934       IF Valid_data THEN 
936         ON KEY Key_num LABEL FNUser_keylabel$("MAIN") CALL User_key6isr
938         ON KEY 5 LABEL "" CALL Ds_do_naught
940         IF Axs_interruptus THEN 
942          !Axis not finished; try again:
944           Disp_plot_axis
946           Axs_interruptus=FNUser_key_press
948         END IF
950         CALL Disp_do_mkr(Data_buffer(*),Data_header(*),0)
952         OFF KEY Key_num
954       ELSE
956         User_error("There is no valid data for the marker function.")
958       END IF
960     CASE 7
962       IF E_key THEN 
964         Restart=1
966       ELSE
968         IF Stopped THEN 
970           Stopped=0
972        !
974        !If single_mode, then collect another block:
976           IF Single_mode THEN 
978             Hw_wait_gbl_rdy
980             Hw_cmd("CONT;TRGU")
982             Blk_in_progress=1
984           END IF
986         ELSE
988           Stopped=1
990           IF Single_mode AND Blk_in_progress THEN 
992            !User stopped in the middle of the measurement; special case:
994             DISP "Single mode measurement aborted; recovering . . ."
996             Ds_soft_start
998             DISP ""
1000          END IF
1002        END IF
1004      END IF
1006    CASE 8
1008      Leave_me=1
1010    END SELECT
1012      !
1014    IF Change_in_hw THEN 
1016      Restart=1
1018      Disp_modified=1
1020    END IF
1022      !
1024    IF FNUser_key_press THEN 
1026      IF FNUser_check_key=Key_num THEN Key_num=FNUser_get_key
1028    END IF
1030    SUBEXIT
1032   !
1034  SUBEND
1036!
1038 Appl_do_other:SUB Appl_do_other(INTEGER Restart,Stopped,Disp_modified,Keys_changed,Plot_erased)
1040   !*********************************************************************
1042   !* This subroutine handles the secondary softkeys.
1044   !*
1046   !* The following variables are returned:
1048   !*             Restart: true if user requested a hard restart.
1050   !*             Stopped: true if measurement is to be stopped.
1052   !*       Disp_modified: true if a change requires a different display.
1054   !*        Keys_changed: true if the alternate softkeys are selected.
1056   !*         Plot_erased: true if plots were erased for any reason.
1058   !*********************************************************************
1060    INTEGER Key_num
1062   !
1064    Key_num=FNUser_get_key
1066    Plot_erased=0
1068   !
1070    SELECT Key_num
1072    CASE 1
1074      Ds_help
1076      Plot_erased=1
1078      Keys_changed=1
1080    CASE 2
1082    CASE 3
1084    CASE 4
1086    CASE 5
1088      Keys_changed=1
1090    CASE 6
1092    CASE 7
1094      Restart=1
1096      Keys_changed=1
1098    CASE 8
1100    END SELECT
1102    !
1104  SUBEND
1106!
1108 Appl_meas_loop:SUB Appl_meas_loop(INTEGER Stopped,Replot,Valid_data,Axs_interruptus,INTEGER Input_buffer(*),REAL Data_buffer(*))
1110   !**********************************************************************
1112   !* This subroutine get new measurement data when it is available and
1114   !* plots it.  The subroutine is exited when a key is pressed or when
1116   !* one measurement is complete in the single mode.
1118   !**********************************************************************
1120    COM /Ds_data/ REAL Data_header(*),INTEGER Ovld_buffer(*)
1122    COM /Ds_meas_info/ INTEGER Triggered_mode,Single_mode
1124    COM /Ds_input_info/ REAL Num_inputs,INTEGER Power2_blk_size,Max_tdly_label$
1126    COM /Ds_error/ INTEGER Errored,No_inputs
1128    INTEGER New_data
1130    REAL Start_time,Display_time
1132   !
1134    Display_time=2.       !Wait time before displaying status line.
1136    Start_time=TIMEDATE
1138   !If measurement is not running  put up the old data:
1140    REPEAT
1142      New_data=0
1144      IF NOT Stopped AND NOT Errored THEN 
1146        Appl_get_data(New_data,Input_buffer(*))
1148        IF Errored THEN 
1150          Valid_data=0
1152          SUBEXIT
1154        END IF
1156        IF New_data THEN Valid_data=1
1158      END IF
1160      IF (New_data OR Replot) AND NOT Axs_interruptus THEN 
1162        MAT Data_buffer= Input_buffer
1164        Disp_plot_data(Data_buffer(*),Data_header(*))
1166        Replot=0
1168      ELSE
1170        IF (TIMEDATE-Start_time)>Display_time THEN 
1172         !While waiting, give the user some status information:
1174          DISP FNDs_meas_state$(Max_tdly_label$,Stopped)
1176        END IF
1178      END IF
1180      Ds_log_key5
1182    UNTIL FNUser_key_press OR (Single_mode AND New_data)
1184   !
1186   !If single mode, stop measurement if new data was acquired:
1188    IF Single_mode AND New_data THEN Stopped=1
1190   !
1192   !Clear status display line on exit:
1194    DISP ""
1196   !
1198    SUBEXIT
1200  SUBEND
1202!
1204 Appl_get_data:SUB Appl_get_data(INTEGER Got_new_data,INTEGER Input_buffer(*))
1206   !**********************************************************************
1208   !* This subroutine checks to see if a new block of data is available
1210   !* from the 35651.  If so, it gets the block and returns it in
1212   !* Input_buffer and returns the Got_new_data flag true.
1214   !* If block is not available yet, the Got_new_data flag is returned
1216   !* false and Input_buffer is unchanged.
1218   !* The 35651 signals that data is avaliable by SRQ'ing on ICODE message.
1220   !**********************************************************************
1222    COM /Ds_data/ REAL Data_header(*),INTEGER Ovld_buffer(*)
1224    COM /Ds_block_ids/ REAL Icode_id,Input_buffer_id,Module_list_id,Ovld_buffer_id
1226    COM /Ds_meas_info/ INTEGER Triggered_mode,Single_mode
1228    COM /Ds_meas_flags/ INTEGER Blk_in_progress
1230    COM /Ds_error/ INTEGER Errored,No_inputs
1232    INTEGER Status,Signal,Dummy
1234   !
1236    Got_new_data=0
1238    IF NOT FNHw_srq THEN SUBEXIT
1240   !
1242    Signal=VAL(FNHw_cmd_rsp$("SIG?"))
1244    Status=VAL(FNHw_cmd_rsp$("STA?"))
1246    IF BIT(Status,5) THEN 
1248      User_error("35651 error occurred when waiting for ICODE block ready.")
1250      Dummy=FNDiag_chk_moderr("HP-IB")
1252    END IF
1254    IF NOT BIT(Status,7) THEN SUBEXIT     !No ICODE message.
1256   !
1258   !Clear overload bit in inputs in preparation for next block:
1260    Hw_gbl_cmd(109,"STA?")
1262   !
1264    IF Signal<>2 THEN 
1266      IF Signal=3 THEN 
1268        User_error("Interrupt occurred when getting block.")
1270      ELSE
1272        User_error("Problem with ICODE block ready.")
1274      END IF
1276      Dummy=FNDiag_chk_errors
1278      Errored=1
1280      SUBEXIT
1282    END IF
1284   !
1286   !A block is available; get it:
1288    Hw_read_blk(Input_buffer_id,Input_buffer(*))
1290    Got_new_data=1
1292    Blk_in_progress=0
1294   !
1296   !Check for overloads:
1298    Ds_do_overload
1300   !
1302   !If continous mode, then collect another block while plotting:
1304    IF NOT Single_mode THEN 
1306      Hw_wait_gbl_rdy
1308      Hw_cmd("CONT;TRGU")
1310      Blk_in_progress=1
1312    END IF
1314   !
1316    SUBEXIT
1318  SUBEND
1320!
1322 Appl_new_labels:SUB Appl_new_labels
1324  !***********************************************************************
1326  !* This subroutine gets the trace titles ready for the plot routine.
1328  !***********************************************************************
1330    COM /Appl_buf_info/ Disp_choices$(*),Input_labels$(*)
1332   !
1334   !Setup display routines with input labels:
1336   !
1338    Num_cols=1
1340    ALLOCATE Disp_titles$(1:Num_cols,1:2)[20]
1342    ALLOCATE Disp_prompt$(1:Num_cols)[80]
1344    ALLOCATE Disp_width(1:Num_cols)
1346   !
1348    MAT Disp_titles$= ("")
1350    Disp_titles$(1,1)="Module"
1352    Disp_titles$(1,2)="Label"
1354    Disp_prompt$(1)="Enter module label"
1356    Disp_width(1)=20
1358    MAT Disp_choices$= ("")
1360   !
1362    FOR Module_index=1 TO SIZE(Input_labels$,1)
1364      Disp_choices$(1,Module_index)=Input_labels$(Module_index)
1366    NEXT Module_index
1368   !
1370   !Setup display spreadsheet with titles:
1372    Disp_spread_set(Disp_titles$(*),Disp_prompt$(*),Disp_width(*),Disp_choices$(*))
1374    !
1376    SUBEXIT
1378  SUBEND
1380!
1382 Ds_setup_inputs:SUB Ds_setup_inputs
1384   !**********************************************************************
1386   !* This subroutine sets up all the active input modules.  Some setups
1388   !* are changed to accomodate the digital scope function.  Other setups
1390   !* are left as is; they will be either their default values or whatever
1392   !* has been selected in the input spreadsheet.
1394   !**********************************************************************
1396    COM /Ds_input_info/ REAL Num_inputs,INTEGER Power2_blk_size,Max_tdly_label$
1398    DIM String$[500],Trg_source_name$[20]
1400   !
1402   !Input setup string; some explanatory notes:
1404   !     RQS 0      Only one input ('slowest') will SRQ to start thruput.
1406   !     TSRC SYS   Trigger from system, except for trigger sourcing inputs.
1408   !     SP ______  Span determined by 'effective sample rate' selection.
1410   !     BSIZ ____  Determined from record size and pretrigger selection.
1412   !     TDLY 0     Trigger delay not allowed if non-triggered mode.
1414   !     TDLY ____  Trigger delay from spreadsheet in triggered mode.
1416    String$="STOP;CLR;RQS 0;TSRC SYS"
1418    String$=String$&";SP "&VAL$(FNMeas_span)
1420    String$=String$&";BSIZ "&VAL$(Power2_blk_size)
1422   !
1424   !The input modules are set up slightly differently in the triggered mode.
1426    IF NOT FNMeas_trigger_on THEN 
1428      String$=String$&";TDLY 0"
1430    END IF
1432   !
1434    Inpt_cmd("ALL INPUT",String$)
1436   !
1438   !Get all the source modules off the trigger line (Note that this won't
1440   !stop their outputs):
1442    Srce_cmd("ALL SOURCE","TRIGGER MODE","IGNORE TRIGGER")
1444   !Disable sources from interrupting or SRQ'ing:
1446    Srce_cmd("ALL SOURCE","INTR 0;RQS 0")
1448   !
1450   !If this is to be a triggered measurement, set up the triggering module:
1452    IF FNMeas_trigger_on THEN 
1454      Trg_source_name$=FNMeas_trg_source$
1456      IF FNMeas_trig_input THEN 
1458        Inpt_cmd(Trg_source_name$,"TRIGGER MODE","SEND TRIGGER")
1460      ELSE
1462        IF UPC$(FNCnfg_type$(Trg_source_name$))="SOURCE" THEN 
1464          Srce_cmd(Trg_source_name$,"TRIGGER MODE","SEND TRIGGER")
1466          Srce_cmd(Trg_source_name$,"START")
1468         !Allow this source to interrupt on error:
1470          Srce_cmd(Trg_source_name$,"INTR 32")
1472        END IF
1474      END IF
1476    ELSE
1478     !Not in triggered mode; trigger immediately from one of the inputs:
1480      Inpt_cmd(Max_tdly_label$,"TSRC FREE")
1482    END IF
1484   !
1486   !Select input with longest data collection time to generate SRQ on
1488   !BAV (block available) to start thruput:
1490    Inpt_cmd(Max_tdly_label$,"RQS 2048")
1492   !
1494   !Send record length to source spreadsheet so it can figure out burst %:
1496    Srce_cmd("ALL SOURCE","BLOCK SIZE",VAL$(FNMeas_num_samp))
1498   !
1500    SUBEXIT
1502  SUBEND
1504!
1506 Ds_start_icode:SUB Ds_start_icode
1508   !**********************************************************************
1510   !* This subroutine start the previously downloaded ICODE program in
1512   !* the 35651.  The ICODE will signal if it has started properly.  If it
1514   !* hasn't, an error condition is flagged.
1516   !**********************************************************************
1518    COM /Ds_block_ids/ REAL Icode_id,Input_buffer_id,Module_list_id,Ovld_buffer_id
1520    COM /Ds_error/ INTEGER Errored,No_inputs
1522    INTEGER Status,Signal
1524   !
1526   !Set 35651 to SRQ on ICODE message;Start ICODE:
1528    Hw_cmd("RQS 128;PROG "&VAL$(Icode_id))
1530   !
1532   !Wait for ICODE started:
1534    DISP "Waiting for ICODE started."
1536    Hw_wait_srq
1538    DISP ""
1540   !
1542    Signal=VAL(FNHw_cmd_rsp$("SIG?"))
1544    Status=VAL(FNHw_cmd_rsp$("STA?"))
1546    IF BIT(Status,5)<>0 THEN PRINT "35651 error occurred when starting ICODE."
1548    IF Signal<>1 THEN 
1550      User_error("ICODE not started properly.")
1552      Errored=1
1554    END IF
1556   !
1558    SUBEXIT
1560  SUBEND
1562 !
1564 Ds_do_overload:SUB Ds_do_overload
1566   !**********************************************************************
1568   !* This subroutine checks the currently plotted inputs to see if any
1570   !* are overloaded.  If so, set the overload flag in the data header so
1572   !* that the plot routine knows to display the OVLD message.
1574   !**********************************************************************
1576    COM /Ds_data/ REAL Data_header(*),INTEGER Ovld_buffer(*)
1578    COM /Ds_block_ids/ REAL Icode_id,Input_buffer_id,Module_list_id,Ovld_buffer_id
1580    INTEGER Plot_num,Num_plots,Buffer_num
1582   !
1584   !Get overload status block from the 35651:
1586    Hw_read_blk(Ovld_buffer_id,Ovld_buffer(*))
1588   !
1590   !Setup data header with overload information:
1592    Num_plots=FNDisp_num_plots
1594    FOR Plot_num=1 TO Num_plots
1596      Buffer_num=FNDisp_choice((Plot_num),1)
1598      Data_header(Buffer_num,3)=BIT(Ovld_buffer(Buffer_num),7)
1600    NEXT Plot_num
1602   !
1604    SUBEXIT
1606  SUBEND
1608!
1610 Ds_init_icode:SUB Ds_init_icode
1612   !**********************************************************************
1614   !* This subroutine sets up the ICODE program for the digital scope
1616   !* function.  The ICODE is read in from DATA statements, assembled
1618   !* and then downloaded to the 35651.
1620   !*
1622   !*   Signal values:  1   ICODE is started and ready for thruput.
1624   !*                   2   A data block is available for uploading.
1626   !*                   3   Thruput failed; data unavailable; ICODE aborted.
1628   !**********************************************************************
1630    COM /Ds_block_ids/ REAL Icode_id,Input_buffer_id,Module_list_id,Ovld_buffer_id
1632    COM /Ds_icode_code/ Source$(*),INTEGER Object(*)
1634    COM /Ds_icode_info/ Info$(*),INTEGER Assembled
1636    COM /Ds_error/ INTEGER Errored,No_inputs
1638    DIM Listing$(1:1)[1]
1640    INTEGER Info_info,Enable_listing
1642   !
1644   !Don't re-assemble ICODE if commons are intact:
1646    IF Assembled THEN SUBEXIT
1648   !
1650    Info_info=1
1652    Enable_listing=0
1654   !
1656    RESTORE Ds_icode_prog
1658    I=0
1660    LOOP
1662      READ Source$(I)
1664    EXIT IF UPC$(Source$(I))="EL_COMPLETO"
1666      I=I+1
1668    END LOOP
1670   !
1672    Num_errors=FNIcode_assemble(Source$(*),Object(*),Info_info,Info$(*),(Enable_listing),Listing$(*))
1674   !
1676    IF Num_errors>0 THEN 
1678      User_error("Error in ICODE program assemble.")
1680      Errored=1
1682    ELSE
1684      Assembled=1
1686    END IF
1688   !
1690    SUBEXIT
1692   !
1694 Ds_icode_prog:  !
1696   !Define variables:
1698    DATA "VAR VALID_LOOPS 0       !Counts successful thruput loops."
1700    DATA "VAR NUM_MODULES 0       !Holds number of modules for thruput."
1702    DATA "VAR MODULE_NUM 0        !Index variable for overload read loop."
1704    DATA "VAR POINTER 0           !Block addressing pointer."
1706    DATA "VAR MODULE_ADR 0        !Holds a module address."
1708    DATA "VAR STATUS 0            !Temporary variable."
1710   !
1712   !Define arrays (blocks):
1714    DATA "DEFBLK_EXT  MODULE_LIST      !Contains setup for thruput."
1716    DATA "DEFBLK_EXT  INPUT_BUFFER     !Time data from 35652s goes here."
1718    DATA "DEFBLK_EXT  OVLD_STATUS      !Status data from 35652s goes here."
1720   !
1722   !Start of executable ICODE.
1724   !Setup for thruput to RAM:
1726    DATA "      F_READY_RAM 1,INPUT_BUFFER,0,MODULE_LIST,0,VALID_LOOPS"
1728    DATA "      F_KEEP_READY_RAM    !Save thruput setup for multiple uses."
1730   !
1732   !Signal to host computer that ICODE has started:
1734    DATA "      F_SIGNAL 1"
1736    DATA "      F_PAUSE             !Wait for host computer."
1738   !
1740   !Wait for SRQ indicating that Input modules have a block available:
1742    DATA "AGAIN:          "
1744    DATA "      F_WAIT_SRQ"
1746    DATA "      F_ASSERT_TRIG       !Hold off further triggering."
1748   !
1750   !Thruput the time data:
1752    DATA "      F_THRUPUT 0,1       !Thruput; no wait-for-SRQ; abort on IRQ."
1754   !
1756   !Read the module status of the input modules to get overload info:
1758    DATA "      V_GET16_INDEXED MODULE_LIST,2,NUM_MODULES"
1760    DATA "      V_CEQUATE 0,MODULE_NUM"
1762    DATA "O_LOOP:     "
1764    DATA "      V_ADD 3,MODULE_NUM,POINTER"
1766    DATA "      V_GET16_INDEXED MODULE_LIST,POINTER,MODULE_ADR"
1768    DATA "      F_GET_STATUS MODULE_ADR,STATUS"
1770    DATA "      V_PUT16_INDEXED OVLD_STATUS,MODULE_NUM,STATUS"
1772    DATA "      V_ADD 1,MODULE_NUM,MODULE_NUM"
1774    DATA "      C_BLT O_LOOP,MODULE_NUM,NUM_MODULES"
1776   !
1778   !Check for successful thruput:
1780    DATA "      C_BEQ NO_VAL,VALID_LOOPS,0  !If VALID_LOOPS=0 goto NO_VAL."
1782   !Signal block available, pause; do it again when continued.
1784    DATA "      F_SIGNAL 2"
1786    DATA "      F_PAUSE"
1788    DATA "      C_GOTO AGAIN"
1790   !
1792   !Jump here on error:
1794    DATA "NO_VAL:         "
1796    DATA "      F_SIGNAL 3"
1798    DATA "      C_END"
1800   !
1802    DATA "EL_COMPLETO"
1804   !
1806  SUBEND
1808!
1810 Ds_init_blocks:SUB Ds_init_blocks
1812   !**********************************************************************
1814   !* This subroutine initializes the ICODE blocks and downloads the
1816   !* ICODE and module list blocks needed for thruput.  This routine should
1818   !* be called before starting the ICODE program the first time.  It
1820   !* should also be called if the measurement parameters have been
1822   !* changed, as there could be new blocksizes and a different module list.
1824   !**********************************************************************
1826    COM /Ds_block_ids/ REAL Icode_id,Input_buffer_id,Module_list_id,Ovld_buffer_id
1828    COM /Ds_input_info/ REAL Num_inputs,INTEGER Power2_blk_size,Max_tdly_label$
1830    COM /Ds_icode_code/ Source$(*),INTEGER Object(*)
1832    COM /Ds_icode_info/ Info$(*),INTEGER Assembled
1834    COM /Ds_error/ INTEGER Errored,No_inputs
1836   !
1838    REAL Block_id,Input_buf_size
1840    REAL Required_words,Available_words
1842    INTEGER Module_list(0:99)
1844   !
1846   !Allocate blocks and get some block_id's from the 35651:
1848   !Set up the module list first so that input buffer size is known:
1850    Ds_module_list(Module_list(*))
1852    Input_buf_size=Num_inputs*Power2_blk_size
1854   !
1856   !Allocate blocks and get some block_id's from the 35651:
1858    Module_list_id=FNIcode_def_ext("MODULE_LIST",(1),(SIZE(Module_list,1)),(0),(0),Info$(*))
1860    Ovld_buffer_id=FNIcode_def_ext("OVLD_STATUS",(1),(Num_inputs),(0),(0),Info$(*))
1862   !
1864   !Check that 35651 has enough memory for requested measurement:
1866    Required_words=Input_buf_size+SIZE(Object,1)+2
1868    Available_words=FNHw_mainblk_aval
1870    IF Required_words>Available_words THEN 
1872      User_error("Requested measurement will overflow 35651 RAM space by "&VAL$(DROUND(((100.*(Required_words/Available_words))-100.),3))&"%")
1874      Errored=1
1876      SUBEXIT
1878    END IF
1880   !
1882    Input_buffer_id=FNIcode_def_ext("INPUT_BUFFER",(1),(Input_buf_size),(0),(0),Info$(*))
1884   !
1886   !Download ICODE program to 35651:
1888    Icode_id=FNIcode_dld(Object(*),(1),Info$(*))
1890   !
1892   !Download the module list to the 35651:
1894    Hw_write_blk(Module_list_id,Module_list(*))
1896   !
1898    SUBEXIT
1900  SUBEND
1902!
1904 Ds_module_list:SUB Ds_module_list(INTEGER Module_list(*))
1906   !***********************************************************************
1908   !* This subroutine sets up the thruput module list for thruput to RAM.
1910   !* The 35651 module needs this list to execute the thruput ICODE command.
1912   !* The list includes the thruput block size, the number of thruput loops
1914   !* (the number of times to read data from each of the modules; for the
1916   !* digital scope function, this is always one), the number of input
1918   !* modules to read data from, and the module address for each.  This
1920   !* routine also finds the input module that has the longest data
1922   !* collection time (biggest trigger delay); it will be this module that
1924   !* SRQ's on block available to initiate block transfers.
1926   !***********************************************************************
1928    COM /Appl_buf_info/ Disp_choices$(*),Input_labels$(*)
1930    COM /Ds_block_ids/ REAL Icode_id,Input_buffer_id,Module_list_id,Ovld_buffer_id
1932    COM /Ds_input_info/ REAL Num_inputs,INTEGER Power2_blk_size,Max_tdly_label$
1934    INTEGER Input_number
1936    REAL Block_size,Radix2,Max_trig_delay,Min_trig_delay
1938   !
1940    Module_list(1)=1        !Number of thruput loops per thruput command.
1942    Module_list(2)=Num_inputs
1944    Max_trig_delay=-MINREAL
1946    Min_trig_delay=MAXREAL
1948    Max_tdly_label$=Input_labels$(1)
1950    FOR Input_number=1 TO Num_inputs
1952      Module_list(Input_number+2)=FNCnfg_get_modnum(Input_labels$(Input_number))
1954      Trigger_delay=VAL(FNInpt_rsp$(Input_labels$(Input_number),"TRIGGER DELAY"))
1956      Min_trig_delay=MIN(Min_trig_delay,Trigger_delay)
1958      IF Trigger_delay>Max_trig_delay THEN 
1960        Max_trig_delay=Trigger_delay
1962        Max_tdly_label$=Input_labels$(Input_number)
1964      END IF
1966    NEXT Input_number
1968   !
1970    Block_size=FNMeas_num_samp
1972    Radix2=LOG(Block_size)/LOG(2.)
1974    IF FRACT(Radix2)<1.E-5 THEN 
1976      Power2_blk_size=2^(INT(Radix2))   !Block_size is already a power of 2.
1978    ELSE
1980      Power2_blk_size=2^(INT(Radix2)+1)    !Pick next largest power of 2.
1982    END IF
1984   !
1986   !Power2_block_size must be > ABS(Min_trig_delay) if pretriggering:
1988    IF Min_trig_delay<0 THEN 
1990      Radix2=LOG(ABS(Min_trig_delay))/LOG(2.)
1992     !Pick next largest power of 2:
1994      Power2_blk_size=MAX(Power2_blk_size,2^(INT(Radix2)+1))
1996    END IF
1998   !
2000   !Finally, module list can be completed:
2002    Module_list(0)=Power2_blk_size
2004   !
2006    SUBEXIT
2008  SUBEND
2010 !
2012 Ds_meas_state:DEF FNDs_meas_state$(Input_label$,INTEGER Stopped)
2014   !***********************************************************************
2016   !* This function returns the state of the measurement in a format
2018   !* suitable for a display line message.
2020   !***********************************************************************
2022    COM /Ds_meas_info/ INTEGER Triggered_mode,Single_mode
2024    COM /Ds_error/ INTEGER Errored,No_inputs
2026    INTEGER State
2028    DIM State$[80]
2030   !
2032    IF Errored THEN 
2034      IF No_inputs THEN 
2036        State$="No active input modules; EXIT and change configuration."
2038      ELSE
2040        State$="Paused in an error state; change setup or press RESTART."
2042      END IF
2044      RETURN "Digital Scope: "&State$
2046    END IF
2048   !
2050    IF Stopped THEN 
2052      IF Single_mode THEN 
2054        State$="Single mode; press START for another measurement."
2056      ELSE
2058        State$="Paused; press CONTINUE for new data."
2060      END IF
2062      RETURN "Digital Scope: "&State$
2064    ELSE
2066      State=VAL(FNInpt_rsp$(Input_label$,"MS?"))
2068      SELECT State
2070      CASE 0
2072        State$="not started."
2074      CASE 1
2076        State$="initializing hardware."
2078      CASE 2
2080        State$="doing an autozero."
2082      CASE 3
2084        State$="waiting for SYNC."
2086      CASE 4
2088        State$="waiting for filters to settle."
2090      CASE 5
2092        State$="taking pretrigger data."
2094      CASE 6
2096        State$="waiting to be armed."
2098      CASE 7
2100        State$="waiting for system to be armed."
2102      CASE 8
2104        State$="waiting for trigger."
2106      CASE 9
2108        State$="taking data."
2110      CASE 10
2112        State$="doing a single autozero."
2114      CASE 11
2116        State$="doing a single autorange."
2118      CASE ELSE
2120        State$="doing some unknown thing."
2122      END SELECT
2124   !
2126      RETURN "Digital Scope: Input '"&Input_label$&"' is "&State$
2128    END IF
2130   !
2132  FNEND
2134!
2136 Ds_input_labels:SUB Ds_input_labels
2138   !***********************************************************************
2140   !* This subroutine sets up the Input_labels$ array with the names of all
2142   !* the active input channels as set up in the configuration spreadsheet.
2144   !* Num_inputs is set to the number of active inputs.
2146   !***********************************************************************
2148    COM /Appl_buf_info/ Disp_choices$(*),Input_labels$(*)
2150    COM /Ds_input_info/ REAL Num_inputs,INTEGER Power2_blk_size,Max_tdly_label$
2152    COM /Ds_error/ INTEGER Errored,No_inputs
2154    INTEGER Dummy
2156   !
2158   !Get number of input modules and their names:
2160    Cnfg_labels("ALL INPUT",Input_labels$(*),Num_inputs)
2162    Dummy=Num_inputs
2164    No_inputs=(Dummy<1)
2166    IF No_inputs THEN 
2168      REDIM Input_labels$(1:1)
2170      Input_labels$(1)="Input 0"
2172    ELSE
2174      REDIM Input_labels$(1:Num_inputs)
2176    END IF
2178   !
2180    SUBEXIT
2182  SUBEND
2184!
2186 Ds_soft_start:SUB Ds_soft_start
2188   !*********************************************************************
2190   !* This subroutine does a 'soft' start on the input modules.  It aborts
2192   !* pending HP-IB activity, stops ICODE, and stops the input modules.
2194   !* It then restarts the input modules and the ICODE program.  This
2196   !* subroutine is called to clear out data in the measurement pipeline
2198   !* when a measurement is aborted.  Note that this subroutine is not
2200   !* suitable for re-starting if the measurement setup has changed.
2202   !*********************************************************************
2204    COM /Ds_meas_flags/ INTEGER Blk_in_progress
2206   !
2208    Hw_dev_clear
2210    Inpt_cmd("ALL INPUT","STOP")
2212   !
2214   !Hold off triggers, start and synchronize the inputs:
2216    Hw_cmd("TRGA")
2218    Inpt_cmd("ALL INPUT","STRT")
2220    Hw_wait_gbl_rdy
2222    Hw_cmd("SYNC")
2224   !
2226   !Start ICODE:
2228    Ds_start_icode
2230   !
2232    Blk_in_progress=0
2234   !
2236    SUBEXIT
2238  SUBEND
2240!
2242 Ds_init_inputs:SUB Ds_init_inputs
2244   !**********************************************************************
2246   !* This subroutine initializes all the active input modules for the
2248   !* digital scope function.  Some setups are changed.  Other
2250   !* setups are left as is; they will be either their default values or
2252   !* whatever they have been set to in the input spreadsheet.  This
2254   !* subroutine should be called on entry to digital scope if the config-
2256   !* uration has changed and the first time digital scope is entered.
2258   !* The inputs setups that are initialized in this subroutine are common
2260   !* to all digital scope measurements and need not be called for a
2262   !* measurement setup change.
2264   !**********************************************************************
2266    DIM String$[500]
2268   !
2270   !Input setup string; some explanatory notes:
2272   !     ZOOM OFF   Digital scope doesn't support complex time records.
2274   !     INTR 32    Any module can interrupt on error (data reg over-read).
2276   !     SYNC ON    Synced so digital filters produce simultaneous samples.
2278   !     TRNM BLK   Block transfers only; continuous records not supported.
2280    String$="ARM AUTO;AZM ZERO;AZSM ON;DSET ON;FINT OFF;FSHT OFF;FSRQ OFF;ICAL OFF;INTR 32;NOVR 0;OVRM NBR;SYNC ON;TRNM BLK;ZOOM OFF"
2282   !
2284   !Send to all active input modules:
2286    Inpt_cmd("ALL INPUT",String$)
2288   !
2290    SUBEXIT
2292  SUBEND
2294!
2296 Ds_setup_info2:SUB Ds_setup_info2
2298   !*********************************************************************
2300   !* This subroutine gets ranges, trigger delays, and input modes for
2302   !* all the active input modules.  It should be called before starting
2304   !* if the measurement setup might have changed.
2306   !*********************************************************************
2308    COM /Appl_buf_info/ Disp_choices$(*),Input_labels$(*)
2310    COM /Ds_input_info/ REAL Num_inputs,INTEGER Power2_blk_size,Max_tdly_label$
2312    COM /Ds_input_info2/ REAL Ranges(*),Trigger_delays(*),Input_modes$(*)
2314    INTEGER Input_num
2316    DIM Input_name$[20]
2318   !
2320   !Get ranges, trigger delays, and input modes for active input modules:
2322    FOR Input_num=1 TO Num_inputs
2324      Input_name$=Input_labels$(Input_num)
2326      Ranges(Input_num)=VAL(FNInpt_rsp$(Input_name$,"RANGE"))
2328      Trigger_delays(Input_num)=VAL(FNInpt_rsp$(Input_name$,"TRIGGER DELAY"))
2330      Input_modes$(Input_num)=FNInpt_rsp$(Input_name$,"INPUT MODE")
2332    NEXT Input_num
2334   !
2336    SUBEXIT
2338  SUBEND
2340!
2342 Ds_attention:SUB Ds_attention
2344   !*********************************************************************
2346   !* This subroutine gets the 35651's undivided attention.  It aborts
2348   !* any pending HP-IB activity, aborts any running ICODE program,
2350   !* clears any errors, and de-allocates any block assignments.
2352   !*********************************************************************
2354   !
2356    Hw_dev_clear
2358   !Abort any running ICODE, clear errors, and clear all block assignments:
2360    Hw_cmd("ABRT;CLR;DISA")
2362   !
2364    SUBEXIT
2366  SUBEND
2368!
2370 Ds_key5isr:SUB Ds_key5isr
2372   !*********************************************************************
2374   !* This subroutine is the interrupt service routine for softkey K5.
2376   !* It is handled differently from the other softkeys.  This key is
2378   !* handled only after plots or axis have finished to avoid partially
2380   !* drawn displays.
2382   !*********************************************************************
2384    COM /Ds_key5/ INTEGER Key5_pressed
2386   !
2388    Key5_pressed=1
2390   !
2392    SUBEXIT
2394  SUBEND
2396!
2398 Ds_log_key5:SUB Ds_log_key5
2400   !*********************************************************************
2402   !* This subroutine logs softkey K5 presses by calling User_key5isr.
2404   !* This provides a means for delaying the effect of K5 presses until
2406   !* they can be handled more easily.
2408   !*********************************************************************
2410    COM /Ds_key5/ INTEGER Key5_pressed
2412   !
2414    IF Key5_pressed THEN 
2416      User_key5isr
2418    END IF
2420    Key5_pressed=0
2422   !
2424    SUBEXIT
2426  SUBEND
2428!
2430 Ds_clear_key5:SUB Ds_clear_key5
2432   !*********************************************************************
2434   !* This subroutine clears any softkey K5 presses.
2436   !*********************************************************************
2438    COM /Ds_key5/ INTEGER Key5_pressed
2440   !
2442    Key5_pressed=0
2444   !
2446    SUBEXIT
2448  SUBEND
2450!
2452 Ds_do_naught:SUB Ds_do_naught
2454   !*********************************************************************
2456   !* This subroutine is self-documenting.
2458   !*********************************************************************
2460    SUBEXIT
2462  SUBEND
2464!
2466 Ds_help:SUB Ds_help
2468   !*********************************************************************
2470   !* This subroutine prints out the 'help' message for Digital Scope.
2472   !*********************************************************************
2474   !
2476    DIM A$[160]
2478    RESTORE Ds_help_page1
2480    GOSUB Ds_show_page
2482    RESTORE Ds_help_page2
2484    GOSUB Ds_show_page
2486    RESTORE Ds_help_page3
2488    GOSUB Ds_show_page
2490    RESTORE Ds_help_page4
2492    GOSUB Ds_show_page
2494    RESTORE Ds_help_page5
2496    GOSUB Ds_show_page
2498    RESTORE Ds_help_page6
2500    GOSUB Ds_show_page
2502    RESTORE Ds_help_page7
2504    GOSUB Ds_show_page
2506    RESTORE Ds_help_page8
2508    GOSUB Ds_show_page
2510    RESTORE Ds_help_page9
2512    GOSUB Ds_show_page
2514    RESTORE Ds_help_page10
2516    GOSUB Ds_show_page
2518    SUBEXIT
2520 Ds_show_page:READ A$
2522    User_clr_scr
2524    WHILE A$<>"***END***"
2526      OUTPUT CRT;A$
2528      READ A$
2530    END WHILE
2532    OUTPUT KBD USING "#,K";"ÿ#Yÿ<"
2534    INPUT "Type 'Y' to continue, anything else to leave...",A$
2536    IF UPC$(A$[1;1])<>"Y" THEN SUBEXIT
2538    RETURN 
2540 Ds_help_page1: !
2542    DATA "            Help for Digital Scope Application"
2544    DATA ""
2546    DATA "The Digital Scope application will display time records from any of"
2548    DATA "the active input modules in a 3565S system.  When first started, the"
2550    DATA "application comes up running in a default setup.  The measurement is"
2552    DATA "tailored to specific needs through the use of spreadsheets that are"
2554    DATA "accessed via softkeys.  From the main, or plot, level of Digital"
2556    DATA "Scope, the following softkeys are accessible:"
2558    DATA ""
2560    DATA "   INPUT SETUP  calls up the spreadheet for the input channels"
2562    DATA "   SOURCE SETUP  calls up the spreadsheet for the sources"
2564    DATA "   DISPLAY SETUP  calls up the spreadsheet to select plots"
2566    DATA "   MEASURE SETUP  calls up the Digital Scope spreadsheet"
2568    DATA "   OTHER  calls up an alternate set of softkey functions"
2570    DATA "   MARKER  enters a mode that allows reading plot data values"
2572    DATA "   PAUSE, CONTINUE, START, or STOP  measurement control keys"
2574    DATA "   EXIT  leaves Digital Scope"
2576    DATA ""
2578    DATA "***END***"
2580 Ds_help_page2: !
2582    DATA "       Help for Digital Scope Application - Page 2"
2584    DATA ""
2586    DATA "INPUT softkey and spreadsheet:"
2588    DATA "   MAIN  returns to plot level of Digital Scope"
2590    DATA "   RESET  sets input setups to their defaults"
2592    DATA "   AUTORANGE  inputs try to pick 'best' range for signals present"
2594    DATA "   PREV, NEXT  can be used instead of keyboard entry"
2596    DATA ""
2598    DATA "The following input setups can be changed on an individual basis:"
2600    DATA "   INPUT MODE  voltage input, charge input, or voltage with ICP current"
2602    DATA "   COUPLING  ac or dc"
2604    DATA "   INPUT GROUNDING grounded or floating to break ground loops"
2606    DATA "   RANGE  sensitivity of input channels"
2608    DATA "   TRIGGER DELAY  in samples; this sets up pre/post triggering"
2610    DATA ""
2612    DATA "Note: Negative trigger delay is pre-triggering.  For example, with a"
2614    DATA "trigger delay of -100 and a block size ('number of samples captured'"
2616    DATA "in MEASURE spreadsheet) of 200, the trigger point will be mid-plot."
2618    DATA "***END***"
2620 Ds_help_page3: !
2622    DATA "       Help for Digital Scope Application - Page 3"
2624    DATA ""
2626    DATA "SOURCE softkey and spreadsheet:"
2628    DATA "   MAIN  returns to plot level of Digital Scope"
2630    DATA "   RESET  sets source setups to their defaults"
2632    DATA "   CLEAR SHUTDOWN  if source's shutdown BNC input is tripped"
2634    DATA "   PREV, NEXT  can be used instead of keyboard entry"
2636    DATA ""
2638    DATA "The following source setups can be changed on an individual basis:"
2640    DATA "   SOURCE MODE  random, sine, burst, etc"
2642    DATA "   DC OFFSET"
2644    DATA "   AMPLITUDE  peak source output amplitude"
2646    DATA "   SPAN, CENTER FREQUENCY  for band-translated noise"
2648    DATA "   SINE FREQUENCY  for the sine and burst sine modes"
2650    DATA "   BURST %  percentage of the time record that a burst is 'on'"
2652    DATA ""
2654    DATA "Note: burst % will be correct only if source span is the same as"
2656    DATA "the measurement spans (about 40% of the effective sample rate)."
2658    DATA "***END***"
2660 Ds_help_page4: !
2662    DATA "       Help for Digital Scope Application - Page 4"
2664    DATA ""
2666    DATA "DISPLAY softkey and spreadsheet:"
2668    DATA "   RESET  sets plot selections and scaling to their defaults"
2670    DATA "   PREV, NEXT  can be used instead of keyboard entry"
2672    DATA ""
2674    DATA "This spreadsheet allows the number of plots and plot scaling"
2676    DATA "to be changed for the Digital Scope time displays."
2678    DATA "   MODULE LABEL  label of input channel data to plot"
2680    DATA "   Y AXIS MIN, MAX  allows changes in Y axis scaling"
2682    DATA "   RECALL TRACE 1,2  recalls stored traces (see MARKER softkey)"
2684    DATA ""
2686    DATA "The input channels are referred to by a label.  To change the"
2688    DATA "default label assigments, press the EXIT softkey and press the"
2690    DATA "CNFG softkey to bring up the configuration spreadsheet."
2692    DATA "***END***"
2694 Ds_help_page5: !
2696    DATA "       Help for Digital Scope Application - Page 5"
2698    DATA ""
2700    DATA "MEASURE SETUP softkey and spreadsheet:"
2702    DATA "   RESET  sets Digital Scope measurement setups to their defaults"
2704    DATA "   PREV, NEXT  can be used instead of keyboard entry"
2706    DATA ""
2708    DATA "   EFFECTIVE SAMPLE RATE  seconds per sample point"
2710    DATA "     <bandwidth>  frequencies above this value will be attenuated"
2712    DATA "   NUMBER OF SAMPLES  in each time record plot"
2714    DATA "     <total time>  total length of captured time record"
2716    DATA "   WAIT FOR TRIGGER  off: capture immediately; on: triggered"
2718    DATA "   CONTINUOUS/SINGLE  continous mode uses pipelined data; there"
2720    DATA "     will be a delay from signal changes to display changes."
2722    DATA "     Single mode collects new data only after the START softkey"
2724    DATA "     is pressed; use single mode to guarantee fresh data."
2726    DATA "   TRIGGER SETUP  see next page"
2728    DATA "***END***"
2730 Ds_help_page6: !
2732    DATA "       Help for Digital Scope Application - Page 6"
2734    DATA ""
2736    DATA "TRIGGER SETUP:"
2738    DATA "When in the 'wait-for-trigger' mode, data is captured relative to a "
2740    DATA "system trigger.  The TRIGGER SOURCE entry area of the MEASURE SETUP"
2742    DATA "spreadsheet specifies the triggering module for the system."
2744    DATA ""
2746    DATA "   Triggering from source modules: select the label of the desired"
2748    DATA "source.  This is useful when triggering relative to a source burst."
2750    DATA""
2752    DATA "   Triggering from input channels: select the label of the input channel"
2754    DATA "desired.  Two types of triggering are supported: level and magnitude."
2756    DATA "Use level to trigger on a signal crossing a level.  Use magnitude to"
2758    DATA "trigger on a signal excursion outside of a bounded region.  All levels are"
2760    DATA "in +-% of full scale; these levels correspond to % of default plot scaling."
2762    DATA""
2764    DATA "Note: use TRIGGER DELAY in INPUT SETUP to position the trigger"
2766    DATA "point in the time record."
2768    DATA "***END***"
2770 Ds_help_page7: !
2772    DATA "       Help for Digital Scope Application - Page 7"
2774    DATA ""
2776    DATA "OTHER softkey:"
2778    DATA "This softkey calls up an alternate set of softkeys.  All these"
2780    DATA "softkeys bump back to the plot level softkeys."
2782    DATA""
2784    DATA "   HELP  that's how you got here!"
2786    DATA "   MAIN  returns to plot level of Digital Scope"
2788    DATA "   HARD RESET  starts a measurement over"
2790    DATA "***END***"
2792 Ds_help_page8: !
2794    DATA "       Help for Digital Scope Application - Page 8"
2796    DATA ""
2798    DATA "MARKER softkey:"
2800    DATA "This softkeys puts a cursor up on the plots allowing the "
2802    DATA "direct readout of plot data values.  It also calls up another"
2804    DATA "set of softkeys:"
2806    DATA ""
2808    DATA "   MARKER TO X  enter the x-axis value of the cursor"
2810    DATA "   MARKER TO MIN  puts the cursor on the smallest Y value"
2812    DATA "   MARKER TO MAX  puts the cursor on the largest Y value"
2814    DATA "   STORE TRACE  stores the trace the cursor is on to a file"
2816    DATA "      (Recall them with the DISPLAY SETUP spreadsheet)"
2818    DATA "   MAIN  returns to plot level of Digital Scope"
2820    DATA "   PREVIOUS, NEXT TRACE  moves cursor to the desired trace"
2822    DATA ""
2824    DATA "Use the arrow keys, knob or mouse to move the cursor around."
2826    DATA "***END***"
2828 Ds_help_page9: !
2830    DATA "       Help for Digital Scope Application - Page 9"
2832    DATA ""
2834    DATA "PAUSE, CONTINUE, START, or STOP softkeys:"
2836    DATA "These softkeys control the measurement.  The PAUSE/CONTINUE"
2838    DATA "softkeys are used in the continuous mode.  Press PAUSE to get"
2840    DATA "a better look at a changing display.  Press CONTINUE to resume"
2842    DATA "the measurement.  Note that the continuous mode uses a data"
2844    DATA "pipeline that is not cleared out when paused; the next data"
2846    DATA "that appears after a CONTINUE will be old data from before the"
2848    DATA "PAUSE."
2850    DATA ""
2852    DATA "The START/STOP softkeys are used in the single mode.  Press "
2854    DATA "START to collect a brand new block of data from all the input"
2856    DATA "channels.  Press STOP to abort a long single-mode measurement."
2858    DATA "***END***"
2860 Ds_help_page10: !
2862    DATA "       Help for Digital Scope Application - Page 10"
2864    DATA ""
2866    DATA "EXIT softkey:"
2868    DATA "Use this softkey to leave the Digital Scope Application before"
2870    DATA "running another application."
2872    DATA ""
2874    DATA "Also, use this softkey to gain access to the CNFG spreadsheet to"
2876    DATA "change the labels associated with any of the hardware modules."
2878    DATA "***END***"
2880  SUBEND
2882!
2884 Meas_meas:SUB Meas_meas
2886   !*********************************************************************
2888   !* This subroutine contains all the common variables used for the
2890   !* measurement spreadsheet for the digital scope function.  It is
2892   !* by the application loader to initialize common assignments.
2894   !*********************************************************************
2896    COM /Meas_row_col/ REAL Row,Col
2898    COM /Meas_sprd/ Box$(1:2,1:15)[40],Title$(1:2,0:2)[60],Prompt$(1:15)[80]
2900    COM /Meas_old_box/ Old_box$(1:2,1:15)[40]
2902    COM /Meas_sprd_num/ Col_width(1:2),Modify_col,INTEGER Max_row,Max_col
2904    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
2906    COM /Meas_trig_info/ Trg_source_name$[20],INTEGER Trig_is_input
2908   !
2910    Meas_defaults
2912    SUBEXIT
2914  SUBEND
2916!
2918 Meas_common:SUB Meas_common
2920   !*********************************************************************
2922   !* This subroutine contains all the common variables used in the
2924   !* measurement spreadsheet for the digital scope function.  It exists
2926   !* to aid in program debugging.  Since it provides no functionality,
2928   !* it can be deleted when program debugging is complete.
2930   !*********************************************************************
2932    COM /Meas_row_col/ REAL Row,Col
2934    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
2936    COM /Meas_old_box/ Old_box$(1:2,1:15)[40]
2938    COM /Meas_sprd_num/ Col_width(1:2),Modify_col,INTEGER Max_row,Max_col
2940    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
2942    COM /Meas_trig_info/ Trg_source_name$,INTEGER Trig_is_input
2944   !
2946    PAUSE
2948    SUBEXIT
2950  SUBEND
2952!
2954 Meas_defaults:SUB Meas_defaults
2956   !*********************************************************************
2958   !* This subroutine sets the measurement spreadsheet boxes to their
2960   !* default values.  It should be called before the measurement spread-
2962   !* sheet is first entered.
2964   !*********************************************************************
2966    COM /Meas_row_col/ REAL Row,Col
2968    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
2970    COM /Meas_sprd_num/ Col_width(*),Modify_col,INTEGER Max_row,Max_col
2972    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
2974    COM /Meas_trig_info/ Trg_source_name$,INTEGER Trig_is_input
2976    DIM Label$(1:63)[20]
2978    REAL Num_labels
2980   !
2982    Max_col=2
2984    Max_row=7
2986    Modify_col=2
2988    Row=2
2990    Col=2
2992   !
2994   !Assign spreadsheet rows:
2996    Fs_row=2
2998    Nsc_row=3
3000    Wft_row=6
3002    Cs_row=7
3004    Ts_row=10
3006    Tm_row=11
3008    Tsl_row=99
3010    Tl1_row=99
3012    Tl2_row=99
3014   !
3016    Title$(1,0)="Digital Scope MEASUREMENT SETUP Spreadsheet"
3018    Title$(1,1)="Item"
3020    Title$(1,2)=""
3022    Title$(2,1)="Value"
3024    Title$(2,2)=""
3026    Prompt$(1)=""
3028    Prompt$(2)="Enter New Value"
3030    Col_width(1)=40
3032    Col_width(2)=30
3034   !
3036   !Set up default spreadsheet:
3038    REDIM Box$(1:2,1:Cs_row)
3040    Box$(1,1)="****** Setups For All Inputs ******"
3042    Box$(1,Fs_row)="Effective Sample Rate <bandwidth>"
3044    Box$(1,Nsc_row)="Number of Samples Captured <total time>"
3046    Box$(1,4)=""
3048    Box$(1,5)="******  Measurement Control  ******"
3050    Box$(1,Wft_row)="Wait for Trigger"
3052    Box$(1,Cs_row)="Continuous/Single"
3054   !
3056   !Set up prompts:
3058    Prompt$(1)=""
3060    Prompt$(Fs_row)="Enter Samples per Second"
3062    Prompt$(Nsc_row)="Enter Number of Samples to Capture"
3064    Prompt$(4)=""
3066    Prompt$(5)=""
3068    Prompt$(Wft_row)="Triggered Mode Off or On"
3070    Prompt$(Cs_row)="Continuous or Single Measurement"
3072    Prompt$(8)=""
3074    Prompt$(9)=""
3076    Prompt$(Ts_row)="Select Channel Name to use as Trigger Source"
3078    Prompt$(Tm_row)="Level (level/slope) or Magnitude (bounded) Trigger"
3080   !
3082    Box$(2,1)=""
3084    Box$(2,Fs_row)=FNMeas_find_fs$(262144.,"SAME")
3086    Box$(2,Nsc_row)=FNMeas_find_ns$(256.,262144.,"SAME")
3088    Box$(2,4)=""
3090    Box$(2,5)=""
3092    Box$(2,Wft_row)="Off"
3094    Box$(2,Cs_row)="Continuous"
3096   !
3098    SUBEXIT
3100  SUBEND
3102!
3104 Meas_init:SUB Meas_init
3106   !*********************************************************************
3108   !* This subroutine must be called when starting up an application.
3110   !* The previously set up measurement spreadsheet values will not be
3112   !* changed, assuming common has not been scratched.   Use Meas_defaults
3114   !* to initialize the measurement spreadsheet values to their defaults.
3116   !* The reason that this subroutine must be called on application startup
3118   !* even though common is intact is that on rerun BASIC will REDIM all
3120   !* arrays in common to their maximum sizes.
3122   !* This routine must also be called after a configuration change.  If
3124   !* the current trigger source module is no longer a valid name, a
3126   !* valid trigger source module is assigned.
3128   !*********************************************************************
3130    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
3132    COM /Meas_sprd_num/ Col_width(*),Modify_col,INTEGER Max_row,Max_col
3134    COM /Meas_trig_info/ Trg_source_name$,INTEGER Trig_is_input
3136    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
3138    DIM Label$(1:63)[20]
3140    REAL Num_labels
3142   !
3144    REDIM Box$(1:Max_col,1:Max_row)
3146   !
3148    IF FNCnfg_good_label(Trg_source_name$) THEN 
3150      Trig_is_input=(UPC$(FNCnfg_type$(Trg_source_name$))="INPUT")
3152     !Use the same capitals and smalls as the in configuration:
3154      Trg_source_name$=FNCnfg_get_label$(FNCnfg_get_modnum(Trg_source_name$))
3156    ELSE
3158     !Get default for Trg_source_name$:
3160      Cnfg_labels("ALL INPUT",Label$(*),Num_labels)
3162      IF Num_labels>0 THEN 
3164        Trg_source_name$=Label$(1)
3166        Trig_is_input=1
3168      ELSE
3170        User_error("Warning: No active input modules found; Digital Scope needs at least one.")
3172        Trig_is_input=0
3174        Cnfg_labels("ALL",Label$(*),Num_labels)
3176        IF Num_labels>0 THEN 
3178          Trg_source_name$=Label$(1)
3180        ELSE
3182          Trg_source_name$=""
3184        END IF
3186      END IF
3188    END IF
3190   !
3192   !Trigger source module could have changed; re-do spreadsheet:
3194    Meas_respread
3196   !
3198    SUBEXIT
3200  SUBEND
3202!
3204 Meas_spread:SUB Meas_spread(Changed,Small_change)
3206   !*********************************************************************
3208   !* This subroutine is the entry point for the measurment spreadsheet
3210   !* for the digital scope function.  It calls the generic spreadsheet
3212   !* with the measurement spreadsheet boxes and handles measurement setup
3214   !* changes.  It checks that any requested measurment setup change is
3216   !* valid before accepting it.
3218   !*********************************************************************
3220    COM /Meas_row_col/ REAL Row,Col
3222    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
3224    COM /Meas_sprd_num/ Col_width(*),Modify_col,INTEGER Max_row,Max_col
3226    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
3228    COM /Meas_trig_info/ Trg_source_name$,INTEGER Trig_is_input
3230    DIM New_entry$[160],Toggle_type$[10],Inp_label$(1:63)[20],Src_label$(1:63)[20],Trigger_choices$(1:63)[20]
3232    INTEGER Done,Dummy,Unknown_entry,Num_labels,Label_num,Found
3234    REAL Fs,Ns,Num_inp_labels,Num_src_labels,Tlv,Tlv_increment
3236    REAL Dummy_found,Dummy_label_num
3238   !
3240    Changed=0
3242    Small_change=0
3244    Tlv_increment=15.
3246   !
3248   ! Define softkeys.  Keys 1 through 4 are 'firmkeys'
3250    ON KEY 5 LABEL FNUser_keylabel$("RESET") CALL User_key5isr
3252    ON KEY 6 LABEL "" CALL User_key6isr
3254    ON KEY 7 LABEL FNUser_keylabel$("Prev") CALL User_key7isr
3256    ON KEY 8 LABEL FNUser_keylabel$("Next") CALL User_key8isr
3258   !
3260    User_clr_scr
3262   !
3264   !Set up table for trigger source selections:
3266    Cnfg_labels("ALL INPUT",Inp_label$(*),Num_inp_labels)
3268    Cnfg_labels("ALL SOURCE",Src_label$(*),Num_src_labels)
3270    Num_labels=Num_inp_labels+Num_src_labels
3272    REDIM Trigger_choices$(1:MAX(1,Num_labels))
3274    Trigger_choices$(1)="None Available"
3276    IF Num_inp_labels>0 THEN 
3278      FOR Label_num=1 TO Num_inp_labels
3280        Trigger_choices$(Label_num)=Inp_label$(Label_num)
3282      NEXT Label_num
3284    END IF
3286    IF Num_src_labels>0 THEN 
3288      FOR Label_num=1 TO Num_src_labels
3290        Trigger_choices$(Num_inp_labels+Label_num)=Src_label$(Label_num)
3292      NEXT Label_num
3294    END IF
3296   !Find out which label number corresponds to current trigger source name:
3298    Lib_match1(Trg_source_name$,Trigger_choices$(*),Dummy_found,Dummy_label_num)
3300    Found=Dummy_found
3302    Label_num=Dummy_label_num
3304    IF Found THEN 
3306      Trg_source_name$=Trigger_choices$(Label_num)
3308      Trig_is_input=(Label_num<=Num_inp_labels)
3310    ELSE
3312      Trg_source_name$=""
3314      Trig_is_input=0
3316    END IF
3318   !
3320   ! Now call spreadsheet.
3322    Start_row=1
3324    Done=0
3326    REPEAT
3328      User_spread(Box$(*),Title$(*),Prompt$(*),New_entry$,Col_width(*),Modify_col,Col,Row,Start_row)
3330      SELECT FNUser_check_key
3332      CASE 0
3334        GOSUB Meas_new_entry
3336      CASE 5
3338       !Reset spreadsheet to power-on defaults:
3340        Dummy=FNUser_get_key
3342        Meas_defaults
3344        Changed=1
3346        Trg_source_name$=""
3348        User_clr_scr
3350        Meas_init      !Meas_init does a Meas_respread.
3352      CASE 6
3354        Dummy=FNUser_get_key
3356      CASE 7     ! Prev
3358        Dummy=FNUser_get_key
3360        Toggle_type$="PREV"
3362        GOSUB Meas_toggle
3364      CASE 8     ! Next
3366        Dummy=FNUser_get_key
3368        Toggle_type$="NEXT"
3370        GOSUB Meas_toggle
3372      CASE ELSE  ! A softkey, but not one of mine.
3374        Done=1
3376      END SELECT
3378    UNTIL Done
3380    User_clr_scr
3382    SUBEXIT
3384    !
3386 Meas_new_entry:!
3388    New_entry$=UPC$(TRIM$(New_entry$))
3390    IF LEN(New_entry$)<1 THEN RETURN      !No entry; no action.
3392    Unknown_entry=0
3394    SELECT Row
3396    CASE Fs_row       !New sample rate entry.
3398      ON ERROR GOTO Meas_bad_entry
3400      Fs=VAL(New_entry$)
3402      OFF ERROR 
3404      Box$(2,Row)=FNMeas_find_fs$(Fs,"SAME")
3406     !Update total time box, too:
3408      Ns=VAL(Box$(2,Nsc_row))
3410      Fs=VAL(Box$(2,Fs_row))
3412      Box$(2,Nsc_row)=FNMeas_find_ns$(Ns,Fs,"SAME")
3414      Changed=1
3416    CASE Nsc_row    !Find number of samples entry.
3418      ON ERROR GOTO Meas_bad_entry
3420      Ns=VAL(New_entry$)
3422      OFF ERROR 
3424      Fs=VAL(Box$(2,Fs_row))   !Need sample rate to compute time.
3426      Box$(2,Row)=FNMeas_find_ns$(Ns,Fs,"SAME")
3428      Changed=1
3430    CASE Wft_row
3432      New_entry$=New_entry$&"_"    !In case New_entry$ is < 1 char.
3434      IF New_entry$[1;2]="ON" OR New_entry$[1;1]="Y" OR New_entry$[1;1]="1" THEN 
3436        Box$(2,Row)="On"
3438        Changed=1
3440        Meas_respread
3442      ELSE
3444        IF New_entry$[1;2]="OF" OR New_entry$[1;1]="N" OR New_entry$[1;1]="0" THEN 
3446          Box$(2,Row)="Off"
3448          Changed=1
3450          Meas_respread
3452        ELSE
3454          Unknown_entry=1
3456        END IF
3458      END IF
3460    CASE Cs_row
3462      SELECT New_entry$[1;1]
3464      CASE "C","0"
3466        Box$(2,Row)="Continuous"
3468        Changed=1
3470      CASE "S","1"
3472        Box$(2,Row)="Single"
3474        Changed=1
3476      CASE ELSE
3478        Unknown_entry=1
3480      END SELECT
3482    CASE Ts_row
3484      Lib_match1(New_entry$,Trigger_choices$(*),Dummy_found,Dummy_label_num)
3486      Found=Dummy_found
3488      Label_num=Dummy_label_num
3490      IF Found THEN 
3492        Trg_source_name$=Trigger_choices$(Label_num)
3494        Trig_is_input=(Label_num<=Num_inp_labels)
3496        Changed=1
3498        Meas_respread
3500      ELSE
3502        Unknown_entry=1
3504      END IF
3506    CASE Tlv_row,Tl1_row,Tl2_row
3508      ON ERROR GOTO Meas_bad_entry
3510      Tlv=VAL(New_entry$)
3512      OFF ERROR 
3514      IF Tlv>125.83 THEN Tlv=125.83
3516      IF Tlv<-125.86 THEN Tlv=-125.86
3518      SELECT Row
3520      CASE Tlv_row
3522        Inpt_cmd(Trg_source_name$,"TRIG LEVEL",VAL$(Tlv))
3524      CASE Tl1_row
3526        Inpt_cmd(Trg_source_name$,"UPPER LEVEL",VAL$(Tlv))
3528      CASE Tl2_row
3530        Inpt_cmd(Trg_source_name$,"LOWER LEVEL",VAL$(Tlv))
3532      END SELECT
3534      Small_change=1
3536      Meas_respread
3538    CASE Tsl_row
3540      SELECT New_entry$[1;1]
3542      CASE "+","P","R","0"    !Positive, Rising edge.
3544        Inpt_cmd(Trg_source_name$,"TRIGGER SLOPE","+")
3546        Small_change=1
3548        Meas_respread
3550      CASE "-","N","F","1"    !Negative, Falling edge.
3552        Inpt_cmd(Trg_source_name$,"TRIGGER SLOPE","-")
3554        Small_change=1
3556        Meas_respread
3558      CASE ELSE
3560        Unknown_entry=1
3562      END SELECT
3564    CASE Tm_row
3566      SELECT New_entry$[1;1]
3568      CASE "L","S","E","0"    !Level, slope, edge trigger.
3570        Inpt_cmd(Trg_source_name$,"TRIGGER TYPE","LEVEL")
3572        Small_change=1
3574        Meas_respread
3576      CASE "M","B","1"    !Magnitude, bounded trigger.
3578        Inpt_cmd(Trg_source_name$,"TRIGGER TYPE","MAGNITUDE")
3580        Small_change=1
3582        Meas_respread
3584      CASE ELSE
3586        Unknown_entry=1
3588      END SELECT
3590    END SELECT
3592    IF Unknown_entry THEN CALL User_error("Unknown entry")
3594    RETURN 
3596   !
3598 Meas_bad_entry:  !
3600    OFF ERROR 
3602    User_error("Expected a number")
3604    RETURN 
3606    !
3608 Meas_toggle:!
3610    SELECT Row
3612    CASE Fs_row    !Find prev/next sample rate:
3614      Fs=VAL(Box$(2,Row))
3616      Box$(2,Row)=FNMeas_find_fs$(Fs,Toggle_type$)
3618     !Update total time box, too:
3620      Ns=VAL(Box$(2,Nsc_row))
3622      Fs=VAL(Box$(2,Fs_row))
3624      Box$(2,Nsc_row)=FNMeas_find_ns$(Ns,Fs,"SAME")
3626      Changed=1
3628    CASE Wft_row
3630      IF UPC$(Box$(2,Row))="OFF" THEN 
3632        Box$(2,Row)="On"
3634      ELSE
3636        Box$(2,Row)="Off"
3638      END IF
3640      Changed=1
3642      Meas_respread
3644    CASE Ts_row
3646      IF Num_labels>1 THEN 
3648        IF UPC$(Toggle_type$)="PREV" THEN 
3650          Label_num=Label_num-1
3652          IF Label_num<1 THEN Label_num=Num_labels
3654        ELSE
3656          Label_num=Label_num+1
3658          IF Label_num>Num_labels THEN Label_num=1
3660        END IF
3662        Trig_is_input=(Label_num<=Num_inp_labels)
3664        Trg_source_name$=Trigger_choices$(Label_num)
3666        Changed=1
3668        Meas_respread
3670      END IF
3672    CASE Cs_row
3674      IF UPC$(Box$(2,Row))="CONTINUOUS" THEN 
3676        Box$(2,Row)="Single"
3678      ELSE
3680        Box$(2,Row)="Continuous"
3682      END IF
3684      Changed=1
3686    CASE Nsc_row    !Find next/prev number of samples.
3688      Ns=VAL(Box$(2,Row))
3690      Fs=VAL(Box$(2,Fs_row))   !Need sample rate to compute time.
3692      Box$(2,Row)=FNMeas_find_ns$(Ns,Fs,Toggle_type$)
3694      Changed=1
3696    CASE Tlv_row,Tl1_row,Tl2_row
3698      Tlv=VAL(Box$(2,Row))/Tlv_increment
3700      Tlv=PROUND(Tlv,0)*Tlv_increment
3702      IF Toggle_type$="PREV" THEN 
3704        Tlv=Tlv-Tlv_increment
3706      ELSE
3708        Tlv=Tlv+Tlv_increment
3710      END IF
3712      IF Tlv>125.83 THEN Tlv=125.83
3714      IF Tlv<-125.86 THEN Tlv=-125.86
3716      SELECT Row
3718      CASE Tlv_row
3720        Inpt_cmd(Trg_source_name$,"TRIG LEVEL",VAL$(Tlv))
3722      CASE Tl1_row
3724        Inpt_cmd(Trg_source_name$,"UPPER LEVEL",VAL$(Tlv))
3726      CASE Tl2_row
3728        Inpt_cmd(Trg_source_name$,"LOWER LEVEL",VAL$(Tlv))
3730      END SELECT
3732      Small_change=1
3734      Meas_respread
3736    CASE Tm_row
3738      IF UPC$(Box$(2,Row))="LEVEL" THEN 
3740        Inpt_cmd(Trg_source_name$,"TRIGGER TYPE","MAGNITUDE")
3742      ELSE
3744        Inpt_cmd(Trg_source_name$,"TRIGGER TYPE","LEVEL")
3746      END IF
3748      Small_change=1
3750      Meas_respread
3752    CASE Tsl_row
3754      IF Box$(2,Row)="+" THEN 
3756        Inpt_cmd(Trg_source_name$,"TRIGGER SLOPE","-")
3758      ELSE
3760        Inpt_cmd(Trg_source_name$,"TRIGGER SLOPE","+")
3762      END IF
3764      Small_change=1
3766      Meas_respread
3768    END SELECT
3770    RETURN 
3772   !
3774  SUBEND
3776!
3778 Meas_find_fs:DEF FNMeas_find_fs$(REAL Fs,Toggle_type$)
3780  !************************************************************************
3782  !* This subroutine changes a given sample rate into the proper format
3784  !* for the measurement setup spreadsheet.  The sample rate is checked
3786  !* to make sure it is valid.
3788  !*  Inputs: Fs (real)  sample rate
3790  !*          Toggle_type$  (ascii)
3792  !*                       ="NEXT" selects the next valid sample rate
3794  !*                       ="PREV" selects the previous "   "      "
3796  !*                       = else  selects present sample rate
3798  !*  Output: Formatted$  (ascii)  formatted output
3800  !************************************************************************
3802    INTEGER N,Max_n
3804    REAL Max_fs,Min_fs,X,Max_bandwidth,Aa_bandwidth
3806    DIM Formatted$[40]
3808   !
3810    Max_fs=262144.         !Hz; maximum system sample rate.
3812    Max_n=19               !Maximum divide-by-2's on maximum sample rate.
3814    Max_bandwidth=51200.   !Maximum bandwidth associated with sample rate.
3816    Aa_bandwidth=50000.    !Anti-alias filter bandwidth.
3818   !
3820    Min_fs=Max_fs/(2.^Max_n)
3822   !Make sure that Fs is within bounds:
3824    IF Fs>Max_fs THEN Fs=Max_fs
3826    IF Fs<Min_fs THEN Fs=Min_fs
3828   !
3830   !Round to the nearest valid sample rate:
3832    N=LOG(Max_fs/Fs)/LOG(2.)
3834   !
3836   !Find the desired Fs:
3838    SELECT UPC$(Toggle_type$)
3840    CASE "PREV"
3842      N=N+1
3844      IF N>Max_n THEN N=0
3846    CASE "NEXT"
3848      N=N-1
3850      IF N<0 THEN N=Max_n
3852    END SELECT
3854    Fs=Max_fs/(2.^N)
3856   !
3858   !Find the associated bandwidth:
3860    IF N=0 OR N=1 THEN 
3862      Bandwidth=DROUND(Aa_bandwidth,3)
3864    ELSE
3866      Bandwidth=DROUND((Max_bandwidth/(2^(N-1))),3)
3868    END IF
3870   !
3872   !Format the output string:
3874    SELECT Bandwidth
3876    CASE >=1000.
3878      Formatted$=VAL$(Bandwidth/1000.)&" KHz"
3880    CASE ELSE
3882      Formatted$=VAL$(Bandwidth)&" Hz"
3884    END SELECT
3886    Formatted$=VAL$(Fs)&" Hz  <"&Formatted$&">"
3888   !
3890    RETURN Formatted$
3892  FNEND
3894!
3896 Meas_find_ns:DEF FNMeas_find_ns$(REAL Ns,Fs,Toggle_type$)
3898  !************************************************************************
3900  !* This subroutine changes a given number of samples into the proper
3902  !* format for the measurement setup spreadsheet.  The number of samples
3904  !* is checked to make sure it is valid.
3906  !*  Inputs: Ns (real)  number of samples
3908  !*          Fs (real)  sample rate
3910  !*          Toggle_type$  (ascii)
3912  !*                       ="NEXT" selects the next ^2 number of samples
3914  !*                       ="PREV" selects the previous " "   "     "
3916  !*                       = else  selects present sample rate
3918  !*  Output: Formatted$  (ascii)  formatted output
3920  !************************************************************************
3922    INTEGER Min_ns,Max_ns,Num_samples,N
3924    REAL Total_time
3926    DIM Formatted$[40]
3928   !
3930    Min_ns=16              !Mininum of 16 samples (esthetics limit).
3932    Max_ns=8192            !Maximum of 8192 samples (35652 limit).
3934   !
3936   !Make sure that Number of samples is within bounds:
3938    SELECT Ns
3940    CASE <Min_ns
3942      Num_samples=Min_ns
3944    CASE >Max_ns
3946      Num_samples=Max_ns
3948    CASE ELSE
3950      Num_samples=Ns         !Round to an integer.
3952    END SELECT
3954   !
3956   !Find the nearest power of two number of samples:
3958    N=LOG(Num_samples)/LOG(2.)
3960   !
3962   !Find the desired record size:
3964    SELECT UPC$(Toggle_type$)
3966    CASE "PREV"
3968      Num_samples=2.^(N-1)
3970      IF Num_samples<Min_ns THEN Num_samples=Max_ns
3972    CASE "NEXT"
3974      Num_samples=2.^(N+1)
3976      IF Num_samples>Max_ns THEN Num_samples=Min_ns
3978    END SELECT
3980   !
3982   !Find the associated total time:
3984    Total_time=DROUND(Num_samples/Fs,3)
3986   !
3988   !Format the output string:
3990    SELECT Total_time
3992    CASE 1.E+6 TO 1.E+9
3994      Formatted$=VAL$(Total_time*1.E-6)&" MSEC"
3996    CASE 1.E+3 TO 1.E+6
3998      Formatted$=VAL$(Total_time*1.E-3)&" KSEC"
4000    CASE 1. TO 1.E+3
4002      Formatted$=VAL$(Total_time)&" SEC"
4004    CASE 1.E-3 TO 1.
4006      Formatted$=VAL$(Total_time*1.E+3)&" mSEC"
4008    CASE 1.E-6 TO 1.E-3
4010      Formatted$=VAL$(Total_time*1.E+6)&" uSEC"
4012    CASE ELSE
4014      Formatted$=VAL$(Total_time)&" SEC"
4016    END SELECT
4018    Formatted$=VAL$(Num_samples)&" Samples  <"&Formatted$&">"
4020   !
4022    RETURN Formatted$
4024  FNEND
4026!
4028 Meas_lvl_spread:SUB Meas_lvl_spread
4030   !*********************************************************************
4032   !* This subroutine sets up a spreadsheet for level triggering from a
4034   !* 35652 input module.
4036   !*********************************************************************
4038    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4040    COM /Meas_old_box/ Old_box$(*)
4042    COM /Meas_sprd_num/ Col_width(*),Modify_col,INTEGER Max_row,Max_col
4044    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
4046    COM /Meas_trig_info/ Trg_source_name$,INTEGER Trig_is_input
4048    INTEGER Row
4050   !
4052   !Assign spreadsheet rows:
4054    Ts_row=10
4056    Tm_row=11
4058    Tlv_row=12
4060    Tsl_row=13
4062    Tl1_row=99
4064    Tl2_row=99
4066   !
4068   !Save old values before changing spreadsheet:
4070    REDIM Old_box$(1:2,1:SIZE(Box$,2))
4072    MAT Old_box$= Box$
4074    REDIM Box$(1:2,1:Tsl_row)
4076    Max_row=Tsl_row
4078   !
4080   !Setup new rows:
4082    Box$(1,Ts_row-2)=""
4084    Box$(1,Ts_row-1)="******     Trigger Setup     ******"
4086    Box$(1,Ts_row)="Trigger Source"
4088    Box$(1,Tm_row)="Trigger Mode"
4090    Box$(1,Tlv_row)="Trigger Level"
4092    Box$(1,Tsl_row)="Trigger Slope"
4094   !
4096   !Set up prompts:
4098    Prompt$(Tlv_row)="Trigger Level in % of full scale"
4100    Prompt$(Tsl_row)="Trigger Slope (+ or -)"
4102   !
4104   !Set up entry boxes:
4106    Box$(2,Ts_row-2)=""
4108    Box$(2,Ts_row-1)=""
4110    Box$(2,Ts_row)=Trg_source_name$&" (an Input)"
4112    Box$(2,Tm_row)="Level"
4114    Box$(2,Tlv_row)=FNInpt_rsp$(Trg_source_name$,"TRIG LEVEL")&" %"
4116    Box$(2,Tsl_row)=FNInpt_rsp$(Trg_source_name$,"TRIG SLOPE")
4118   !
4120   !Restore box values:
4122    FOR Row=1 TO Cs_row
4124      Box$(1,Row)=Old_box$(1,Row)
4126      Box$(2,Row)=Old_box$(2,Row)
4128    NEXT Row
4130   !
4132    SUBEXIT
4134  SUBEND
4136!
4138 Meas_respread:SUB Meas_respread
4140   !************************************************************************
4142   !* This subroutine figures out which spreadsheet to setup.  It should be
4144   !* called whenever a measurement setup change might require a new
4146   !* spreadsheet format.
4148   !************************************************************************
4150    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4152    COM /Meas_old_box/ Old_box$(*)
4154    COM /Meas_trig_info/ Trg_source_name$,INTEGER Trig_is_input
4156    INTEGER Line_number
4158   !
4160    IF FNMeas_trigger_on THEN 
4162      IF Trig_is_input THEN 
4164        IF FNInpt_rsp$(Trg_source_name$,"TRIG TYPE")="MAG" THEN 
4166          Meas_mag_spread
4168        ELSE
4170          Meas_lvl_spread
4172        END IF
4174      ELSE
4176        Meas_oth_spread
4178      END IF
4180    ELSE
4182      Meas_non_spread
4184    END IF
4186   !
4188   !Clear spreadsheet lines if spreadsheet has shrunk:
4190    IF SIZE(Box$,2)<SIZE(Old_box$,2) THEN 
4192      FOR Line_number=(SIZE(Old_box$,2)+1) TO (SIZE(Box$,2)+2) STEP -1
4194        PRINT TABXY(1,Line_number+2),RPT$(" ",80)
4196      NEXT Line_number
4198    END IF
4200   !
4202    SUBEXIT
4204  SUBEND
4206 Meas_non_spread:SUB Meas_non_spread
4208   !*********************************************************************
4210   !* This subroutine sets up a spreadsheet for the untriggerred mode.
4212   !*********************************************************************
4214    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4216    COM /Meas_old_box/ Old_box$(*)
4218    COM /Meas_sprd_num/ Col_width(*),Modify_col,INTEGER Max_row,Max_col
4220    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
4222    INTEGER Row
4224   !
4226   !Assign spreadsheet rows:
4228    Ts_row=99
4230    Tm_row=99
4232    Tlv_row=99
4234    Tsl_row=99
4236    Tl1_row=99
4238    Tl2_row=99
4240   !
4242   !Save old values before changing spreadsheet:
4244    REDIM Old_box$(1:2,1:SIZE(Box$,2))
4246    MAT Old_box$= Box$
4248    REDIM Box$(1:2,1:Cs_row)
4250    Max_row=Cs_row
4252   !
4254   !Restore box values:
4256    FOR Row=1 TO Cs_row
4258      Box$(1,Row)=Old_box$(1,Row)
4260      Box$(2,Row)=Old_box$(2,Row)
4262    NEXT Row
4264   !
4266    SUBEXIT
4268  SUBEND
4270!
4272 Meas_mag_spread:SUB Meas_mag_spread
4274   !*********************************************************************
4276   !* This subroutine sets up a spreadsheet for magnitude triggerring
4278   !* from a 35652 input module.
4280   !*********************************************************************
4282    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4284    COM /Meas_old_box/ Old_box$(*)
4286    COM /Meas_sprd_num/ Col_width(*),Modify_col,INTEGER Max_row,Max_col
4288    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
4290    COM /Meas_trig_info/ Trg_source_name$,INTEGER Trig_is_input
4292    INTEGER Row
4294   !
4296   !Assign spreadsheet rows:
4298    Ts_row=10
4300    Tm_row=11
4302    Tlv_row=99
4304    Tsl_row=99
4306    Tl1_row=12
4308    Tl2_row=13
4310   !
4312   !Save old values before changing spreadsheet:
4314    REDIM Old_box$(1:2,1:SIZE(Box$,2))
4316    MAT Old_box$= Box$
4318    REDIM Box$(1:2,1:Tl2_row)
4320    Max_row=Tl2_row
4322   !
4324   !Setup new rows:
4326    Box$(1,Ts_row-2)=""
4328    Box$(1,Ts_row-1)="******     Trigger Setup     ******"
4330    Box$(1,Ts_row)="Trigger Source"
4332    Box$(1,Tm_row)="Trigger Mode"
4334    Box$(1,Tl1_row)="Trigger Bound 1"
4336    Box$(1,Tl2_row)="Trigger Bound 2"
4338   !
4340   !Set up prompts:
4342    Prompt$(Tl1_row)="Trigger Bound 1 in % of full scale"
4344    Prompt$(Tl2_row)="Trigger Bound 2 in % of full scale"
4346   !
4348   !Set up entry boxes:
4350    Box$(2,Ts_row-2)=""
4352    Box$(2,Ts_row-1)=""
4354    Box$(2,Ts_row)=Trg_source_name$&" (an Input)"
4356    Box$(2,Tm_row)="Magnitude"
4358    Box$(2,Tl1_row)=FNInpt_rsp$(Trg_source_name$,"UPPER LEVEL")&" %"
4360    Box$(2,Tl2_row)=FNInpt_rsp$(Trg_source_name$,"LOWER LEVEL")&" %"
4362   !
4364   !Restore box values:
4366    FOR Row=1 TO Cs_row
4368      Box$(1,Row)=Old_box$(1,Row)
4370      Box$(2,Row)=Old_box$(2,Row)
4372    NEXT Row
4374   !
4376    SUBEXIT
4378  SUBEND
4380 Meas_oth_spread:SUB Meas_oth_spread
4382   !*********************************************************************
4384   !* This subroutine sets up a spreadsheet for triggerring from
4386   !* something other than a 35652 input module.
4388   !*********************************************************************
4390    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4392    COM /Meas_old_box/ Old_box$(*)
4394    COM /Meas_sprd_num/ Col_width(*),Modify_col,INTEGER Max_row,Max_col
4396    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
4398    COM /Meas_trig_info/ Trg_source_name$,INTEGER Trig_is_input
4400    INTEGER Row
4402   !
4404   !Assign spreadsheet rows:
4406    Ts_row=10
4408    Tm_row=99
4410    Tlv_row=99
4412    Tsl_row=99
4414    Tl1_row=99
4416    Tl2_row=99
4418   !
4420   !Save old values before changing spreadsheet:
4422    REDIM Old_box$(1:2,1:SIZE(Box$,2))
4424    MAT Old_box$= Box$
4426    REDIM Box$(1:2,1:Ts_row)
4428    Max_row=Ts_row
4430   !
4432   !Setup new rows:
4434    Box$(1,Ts_row-2)=""
4436    Box$(1,Ts_row-1)="******     Trigger Setup     ******"
4438    Box$(1,Ts_row)="Trigger Source"
4440   !
4442   !Set up entry boxes:
4444    Box$(2,Ts_row-2)=""
4446    Box$(2,Ts_row-1)=""
4448    Box$(2,Ts_row)=Trg_source_name$
4450    IF FNCnfg_good_label(Trg_source_name$) THEN 
4452      IF (UPC$(FNCnfg_type$((Trg_source_name$)))="SOURCE") THEN Box$(2,Ts_row)=Box$(2,Ts_row)&" (a Source)"
4454    END IF
4456   !
4458   !Restore box values:
4460    FOR Row=1 TO Cs_row
4462      Box$(1,Row)=Old_box$(1,Row)
4464      Box$(2,Row)=Old_box$(2,Row)
4466    NEXT Row
4468   !
4470    SUBEXIT
4472  SUBEND
4474!
4476 Dummy:SUB Dummy
4478  SUBEND
4480 Dummy:SUB Dummy
4482  SUBEND
4484 Dummy:SUB Dummy
4486  SUBEND
4488!
4490 Meas_fs:DEF FNMeas_fs
4492  !************************************************************************
4494  !* The following collection of routines provides a means for the digital
4496  !* scope function to access the measurement setup as defined in the
4498  !* measurement spreadsheet.
4500  !************************************************************************
4502  !************************************************************************
4504  !* This function returns the current sample rate for digital scope.
4506  !************************************************************************
4508    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4510    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
4512    RETURN VAL(Box$(2,Fs_row))
4514  FNEND
4516!
4518 Meas_span:DEF FNMeas_span
4520  !************************************************************************
4522  !* This function returns the current span for digital scope.
4524  !************************************************************************
4526    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4528    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
4530   !
4532    RETURN VAL(Box$(2,Fs_row))/2.56
4534  FNEND
4536!
4538 Meas_trigger_on:DEF FNMeas_trigger_on
4540  !************************************************************************
4542  !* This function returns logical true/false for 'Wait for Trigger'.
4544  !************************************************************************
4546    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4548    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
4550    INTEGER Trigger_on
4552   !
4554    Trigger_on=(UPC$(Box$(2,Wft_row))="ON")
4556    RETURN Trigger_on
4558  FNEND
4560!
4562 Meas_num_samp:DEF FNMeas_num_samp
4564  !************************************************************************
4566  !* This function returns the number of samples per trace for dig scope.
4568  !************************************************************************
4570    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4572    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
4574   !
4576    RETURN VAL(Box$(2,Nsc_row))
4578  FNEND
4580!
4582 Meas_single:DEF FNMeas_single
4584  !************************************************************************
4586  !* This function returns logical true/false for 'Single Measurement'.
4588  !************************************************************************
4590    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4592    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
4594    INTEGER Single
4596   !
4598    Single=(UPC$(Box$(2,Cs_row))="SINGLE")
4600    RETURN Single
4602  FNEND
4604!
4606 Meas_trg_source:DEF FNMeas_trg_source$
4608  !************************************************************************
4610  !* This function returns the name of the module currently selected to
4612  !* trigger the measurement.
4614  !************************************************************************
4616    COM /Meas_trig_info/ Trg_source_name$,INTEGER Trig_is_input
4618   !
4620    RETURN Trg_source_name$
4622  FNEND
4624!
4626 Meas_time:DEF FNMeas_time
4628  !************************************************************************
4630  !* This function returns the captured time length in seconds.
4632  !************************************************************************
4634    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4636    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
4638   !
4640    RETURN VAL(Box$(2,Nsc_row))/VAL(Box$(2,Fs_row))
4642  FNEND
4644!
4646 Meas_trig_input:DEF FNMeas_trig_input
4648  !************************************************************************
4650  !* This function returns true if the module currently selected to trigger
4652  !* the measurement is an input module.
4654  !************************************************************************
4656    COM /Meas_trig_info/ Trg_source_name$,INTEGER Trig_is_input
4658   !
4660    RETURN Trig_is_input
4662  FNEND
4664!
4666  !************************************************************************
4668  !     End of routines for the application to use.
4670  !************************************************************************
4672!
4674 Meas_save:SUB Meas_save(@File,REAL Ok)
4676  !************************************************************************
4678  !*    Save recall routines.
4680  !************************************************************************
4682  !************************************************************************
4684  !* This subroutine appends the current digital scope setup to @File by
4686  !* saving Box$(*) and some other variables.  A revision code is written
4688  !* to the file to reject incompatible data on recall.
4690  !************************************************************************
4692    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4694    COM /Meas_trig_info/ Trg_source_name$,INTEGER Trig_is_input
4696    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
4698    INTEGER File_format_rev
4700   !
4702    File_format_rev=2620
4704    OUTPUT @File;File_format_rev
4706    OUTPUT @File;Trg_source_name$
4708    OUTPUT @File;Trig_is_input
4710    OUTPUT @File;Tm_row
4712    OUTPUT @File;Tsl_row
4714    OUTPUT @File;Tlv_row
4716    OUTPUT @File;Tl1_row
4718    OUTPUT @File;Tl2_row
4720    File_save_s(@File,Box$(*))
4722    Ok=1
4724   !
4726    SUBEXIT
4728  SUBEND
4730!
4732 Meas_load:SUB Meas_load(@File,REAL Ok)
4734  !************************************************************************
4736  !* This subroutine gets a digital scope setup from @File by loading Box$
4738  !* and some other variables.
4740  !* The revision code is read from the file to reject incompatible data.
4742  !************************************************************************
4744    COM /Meas_sprd/ Box$(*),Title$(*),Prompt$(*)
4746    COM /Meas_rows/ INTEGER Fs_row,Wft_row,Ts_row,Cs_row,Nsc_row,Tm_row,Tlv_row,Tsl_row,Tl1_row,Tl2_row
4748    COM /Meas_trig_info/ Trg_source_name$,INTEGER Trig_is_input
4750    DIM Temp$[40]
4752    INTEGER File_format_rev
4754   !
4756    ENTER @File;File_format_rev
4758    SELECT File_format_rev
4760    CASE 2620
4762      ENTER @File;Trg_source_name$
4764      ENTER @File;Trig_is_input
4766      ENTER @File;Tm_row
4768      ENTER @File;Tsl_row
4770      ENTER @File;Tlv_row
4772      ENTER @File;Tl1_row
4774      ENTER @File;Tl2_row
4776      File_load_s(@File,Box$(*))
4778     !
4780     !Set up trigger module if trigger from an input:
4782      IF FNMeas_trigger_on AND Trig_is_input THEN 
4784        Temp$=UPC$(TRIM$(Box$(2,Tm_row)))
4786        IF Temp$[1;1]="L" THEN 
4788          Inpt_cmd(Trg_source_name$,"TRIGGER TYPE","LEVEL")
4790          Temp$=TRIM$(Box$(2,Tsl_row))
4792          Inpt_cmd(Trg_source_name$,"TRIGGER SLOPE",Temp$)
4794          Temp$=VAL$(VAL(Box$(2,Tlv_row)))
4796          Inpt_cmd(Trg_source_name$,"TRIG LEVEL",Temp$)
4798        ELSE
4800          Inpt_cmd(Trg_source_name$,"TRIGGER TYPE","MAGNITUDE")
4802          Temp$=VAL$(VAL(Box$(2,Tl1_row)))
4804          Inpt_cmd(Trg_source_name$,"UPPER LEVEL",Temp$)
4806          Temp$=VAL$(VAL(Box$(2,Tl2_row)))
4808          Inpt_cmd(Trg_source_name$,"LOWER LEVEL",Temp$)
4810        END IF
4812       !
4814       !Clear any errors these module setup commands may have caused:
4816        Inpt_cmd("ALL INPUT","CLEAR")
4818        Srce_cmd("ALL SOURCE","CLEAR")
4820      END IF
4822      Meas_respread
4824      Ok=1
4826    CASE ELSE
4828      User_error("Load ERROR - Incompatible file format for Digital Scope spreadsheet.")
4830      Ok=0
4832    END SELECT
4834    SUBEXIT
4836  SUBEND
4838!