10!OUTPUT 2 USING "#,K";"<lf>REN<cr>INDENT<cr>RE-STORE ""SRCE""<cr>"
20!EDIT SRCE_START
30 !*************************************************************************
40 !
50 !
60 !                          SRCE file
70 !
80 ! This is the SRCE file.  It contains subprograms used to setup and control
90 ! the source modules in an HP3565S system.  Only 'active' source modules,
100! as defined by the CNFG file, are controlled, since 'inactive' sources are
110! treated as though they don't exist.  This file has some subprograms that
120! are used to directly send commands and get responses from a source module.
130! It also contains a spreadsheet subprogram that provides a convenient way
140! to display and change the setup of the source modules.  Finally, this file
150! provides some routines useful for interpreting error messages and status
160! bits that can be sent out by a source module.  The following is a
170! discription of some of the subprograms in this file.  These are the only
180! subprograms that should need to be called from other files or
190! applications.  Additional documentation is included in-line with each
200! subprogram.
210!
220!
230!        Subprograms available to the user :
240!
250!  Srce_srce
260!
270!                   Poweron Initialization.
280!
290!  Srce_init(OPTIONAL Passed_setup$(1:Num_columns))
300!
310!                   Should be called after any change in the srce
320!                   configuration or after the Srce_srce subprogram
330!                   is called.  The optional parameter can be used to
340!                   reinitialize the columns of the source spread sheet.
350!                   Passed_setup$ contains a list of spread sheet columns
360!                   to be displayed.  See the spread sheet column table
370!                   below to determine list of possible column names.
380!
390!  Srce_spread(Changed)
400!
410!                   Subprogram to display and allow modification of the
420!                   source spreadsheet.  The Changed parameter returns true
430!                   if any change has occurred to a source module.
440!                   When the Srce_spread subprogram is exited, the source
450!                   is set to "SYNC OFF", all errors are cleared, and the
460!                   source is started.
470!
480!  Srce_cmd(Module_label$,Command$,OPTIONAL Parameter$)
490!
500!                   Subprogram to send a command to a source module. The
510!                   command string is one of the commands in the table
520!                   at the label "Srce_commands", and the parameter
530!                   is one of the parameters for that command.
540!                   In general, Command$ and Parameter$ can be written out
550!                   as verbosely as you want, and this subprogram will do
560!                   its best to interpret them.
570!
580!  FNSrce_rsp$(Module_label$,Command$)
590!
600!                   Function to query a module for what state its been
610!                   set to.  Command$ is the command to query.  Returns
620!                   a string from the module.  Again, the Command$ can be
630!                   typed out verbosely, and will be interpreted by the
640!                   subprogram.
650!
660!  Srce_reset(Module_label$)
670!
680!                   Subprogram to set the specified module(s) to a known
690!                   state.  This subprogram only sets the parameters that
700!                   are in the spreadsheet to known values.  It also clears
710!                   shutdown if the module was shut down.  To reset ALL
720!                   parameters of the module, use:
730!                     Srce_cmd(Module_label$,"RESET").
740!
750!  FNSrce_stat_2_str$(stat)
760!
770!                   This subprogram returns a string containing the
780!                   mnemonics for each of the status bits set in the
790!                   passed in word.
800!
810!
820!  FNSrce_str_2_stat(A$)
830!
840!                   This subroutine returns a number which represents the
850!                   status of the Source module if the status bits indicated
860!                   by A$ are set.  Bit mnemonics may be separated by "," or
870!                   "|".  This is the inverse of subprogram
880!                   FNSrce_stat_2_str$(stat).
890!
900!  FNSrce_get_errstr$(Error_num)
910!
920!                   This subprogram returns a string containing the error
930!                   message corresponding to the source error number
940!                   that is passed to it.
950!
960!  Srce_save(@File,Ok)
970!
980!                   This subprogram saves the current source setups in
990!                   the file specified by @File, and returns Ok=1 if
1000!                  it successfully saves the setups.
1010!
1020! Srce_load(@File,Ok)
1030!
1040!                  This subprogram loads the source setups from file
1050!                  @File, and returns Ok=1 if the load is successful.
1060!
1070!
1080!      Spreadsheet configuration column names :
1090!
1100!      Name
1110!     -----------------------
1120!     MODE          - Sets output mode (sine, random, etc.)
1130!     OFFSET        - Sets output DC offset
1140!     AMPLITUDE     - Sets output amplitude
1150!     SPAN          - Sets output frequency span
1160!     FREQ          - Sets random noise center frequency
1170!     SINE FREQ     - Sets sine frequency
1180!     TRIG          - Sets trigger mode
1190!     BURST %       - Sets burst on time as a percentage of total burst time
1200!     BURST TIME    - Sets the total burst on and off time
1210!     ZOOM          - Sets zoom mode (on or off)
1220!
1230!*************************************************************************
1240!
1250 Srce_start:!
1260!LOADSUB ALL FROM "USER"
1270!LOADSUB ALL FROM "HW"
1280!LOADSUB ALL FROM "CNFG"
1290!LOADSUB ALL FROM "LIB"
1300!DELSUB USER_USER TO END
1310  !
1320  FOR I=0 TO 23
1330    ON KEY I LABEL "" GOSUB Srce_test_dummy
1340  NEXT I
1350  !
1360  User_user
1370  Hw_hw
1380  Cnfg_cnfg
1390  Srce_srce
1400  Cnfg_spread(Changed)
1410  Srce_init
1420  LOOP
1430    Srce_spread(Changed)
1440    Dummy=FNUser_get_key
1450    Cnfg_spread(Changed)
1460    Dummy=FNUser_get_key
1470    IF Changed THEN CALL Srce_init
1480  END LOOP
1490 Srce_test_dummy:RETURN 
1500  END
1510  ! PAGE -> 
1520  !************************************************************************
1530 Srce_srce:SUB Srce_srce
1540    !
1550    ! Srce_srce should be called the first time this file is run after
1560    ! it is loaded.  It sets up the data used to convert a verbose command
1570    ! into the real source command.  It also has a copy of every common
1580    ! declaration in the SRCE file.
1590    !
1600    COM /Srce_sprd_posn/ Row,Col,Start_row
1610    COM /Srce_sprd_box/ Box$(1:32,1:63)[16]
1620    COM /Srce_sprd_title/ Title$(1:32,0:2)[20]
1630    COM /Srce_sprd_tog/ Toggle$(1:32)[50]
1640    COM /Srce_sprd_cmnd/ Cmnd_code$(1:32)[20]
1650    COM /Srce_sprd_prmpt/ Prompt$(1:32)[80]
1660    COM /Srce_sprd_reset/ Reset_parms$(1:32)[20]
1670    COM /Srce_sprd_other/ Col_width(1:32),Max_col,Max_row,Modify_col
1680    COM /Srce_cmnd_cnv/ Cnv_cmnd_code$(1:32)[80],Cnv_mod_cmnd$(1:32)[10]
1690    COM /Srce_parm_cnv/ Convert_parm$(1:32,0:7)[80]
1700    !
1710    ! Row, Col, and Start_row determine the cursor position in the source
1720    ! spreadsheet.  They are in common so that if the spreadsheet is
1730    ! exited and then re-entered, the cursor will remember where it was.
1740    !
1750    ! Box$ is the array of boxes in the source spreadsheet.
1760    !
1770    ! Title$ is the array of titles for the top of each column of the
1780    ! spreadsheet.
1790    !
1800    ! Toggle$ is an array of strings.  Each string contains the list of
1810    ! values to step through as the 'prev' or 'next' softkey is pushed.
1820    !
1830    ! Cmnd_code$ is an array of the source commands that goes with
1840    ! each column of the spreadsheet.
1850    !
1860    ! Prompt$ is an array of the prompts for each column of the
1870    ! spreadsheet.
1880    !
1890    ! Reset_parms$ is an array of the reset values for each column
1900    ! of the spreadsheet.  This is the value that the source module
1910    ! will start with after Srce_init is called, and this is also the
1920    ! value that the source module will have after Srce_reset is called.
1930    !
1940    ! Column_width is an array of the column widths for each column
1950    ! of the spreadsheet.  Max_col and Max_row define the size of the
1960    ! spreadsheet.  Modify_col is the first column that the user can
1970    ! modify.
1980    !
1990    ! Cnv_cmnd_code$ and Cnv_mod_cmnd are arrays of conversion data for
2000    ! converting verbose source commands into the actual command string
2010    ! that the source module expects.  Each element of Cnv_cmnd_code is a
2020    ! list of possible strings, separated by vertical bars, which will be
2030    ! mapped into the actual source command found in Cnv_mod_cmnd$
2040    !
2050    ! Convert_parm$ is used to map verbose parameters of commands into
2060    ! the actual parameters that the source module expects.  It is a 2
2070    ! dimensional array.  The first dimension determines which source
2080    ! command the parameter goes with.  The second determines which
2090    ! parameter for that command.  Each element is a list of verbose
2100    ! parameters separated by vertical bars.
2110    !
2120    DIM Temp_code$[80]
2130    DIM Setup_array$(1:32)[20],Setup_name$[20],Dummy$[255]
2140    INTEGER Null_found,Loop_count
2150    !
2160    ! Set up Box$ so no errors occur in Srce_cmd.
2170    !
2180    Max_row=1
2190    Max_col=1
2200    REDIM Box$(1:Max_col,1:Max_row)
2210    !
2220    ! Read the command code and parameter conversion data into arrays
2230    !
2240    RESTORE Srce_cnv_data
2250    C=0
2260    Rmax=SIZE(Convert_parm$,2)-1
2270    REPEAT
2280      READ Temp_code$
2290      Temp_code$=UPC$(Temp_code$)
2300      IF Temp_code$<>"NO MORE" THEN 
2310        C=C+1
2320        READ Cnv_mod_cmnd$(C)
2330        Cnv_cmnd_code$(C)=Temp_code$&"|"&Cnv_mod_cmnd$(C)
2340        R=0
2350        Null_found=0
2360        REPEAT
2370          READ Convert_parm$(C,R)
2380          R=R+1
2390          IF Convert_parm$(C,R-1)="" THEN 
2400            Null_found=1
2410            WHILE R<=Rmax
2420              Convert_parm$(C,R)=""
2430              R=R+1
2440            END WHILE
2450          END IF
2460        UNTIL R>Rmax
2470        IF NOT Null_found THEN 
2480          READ Dummy$
2490          IF Dummy$<>"" THEN CALL User_stop("Error in Srce_srce - "&Temp_code$&" table command has no null parm string.")
2500        END IF
2510      END IF
2520    UNTIL Temp_code$="NO MORE"
2530    SUBEXIT
2540    !
2550    ! Command conversion data can be interpreted as follows.  First, there
2560    ! is a string that contains all the possible verbose commands,
2570    ! separated by vertical bars.  The next string is the actual command
2580    ! that will be sent to the source module if one of the verbose commands
2590    ! is specified.  The next strings, until a null string is found, are
2600    ! used to convert verbose parameters to the command.  They are in
2610    ! order, and each string contains the possible verbose parameters
2620    ! separated by vertical bars.  The end of the data is signalled by
2630    ! the string "NO MORE".
2640    !
2650 Srce_cnv_data:   !
2660    ! This is a command with no parameters
2670    DATA  "RESET|RESET MODULE"              ! Verbose forms of the command
2680    DATA    "RST"                           ! Actual command sent to module
2690    DATA    ""                              ! No parameters
2700    ! This is a command with parameters
2710    DATA  "MODE|SOURCE MODE|OUTPUT MODE"    ! Verbose forms of the command
2720    DATA    "OPTM"                          ! Actual command sent to module
2730    DATA    "OFF|O|OF"                      ! Verbose forms of parameter #0
2740    DATA    "RANDOM|CONTINUOUS RANDOM|R|RA|RAN|RAND|RANDO|CR" !   "      #1
2750    DATA    "BRAND|BRANDOM|BURST RND|BURST RAND|BURST RANDOM|BR|BURST R"!#2
2760    DATA    "SINE|CONTINUOUS SINE|S|SI|SIN" ! Verbose forms of parameter #3
2770    DATA    "BSINE|BURST SINE|BS|BURST S"   ! Verbose forms of parameter #4
2780    DATA    "PULSE|POSITIVE PULSE|P|PU|PUL|PULS"! "     "    "     "     #5
2790    DATA    "NPULSE|NEGATIVE PULSE|NEG PULSE|NEG P|NP|NPUL" !"     "     #6
2800    DATA    "DC|DC ONLY|D"                  ! Verbose forms of parameter #7
2810    DATA    ""                              ! No more parameters
2820    DATA  "OFFSET|DC OFFSET|DC"
2830    DATA    "OF"
2840    DATA    ""
2850    DATA  "AMP|AMPLITUDE|RANGE"
2860    DATA    "AM"
2870    DATA    ""
2880    DATA  "CENTER FREQ|CENTER FREQUENCY"
2890    DATA    "CF"
2900    DATA    ""
2910    DATA  "FREQ|FREQUENCY|SINE FREQ|SINE FREQUENCY"
2920    DATA    "FR"
2930    DATA    ""
2940    !
2950    !     The following two commands are special cases.
2960    !     See Srce_cmd to see what's done with them.
2970    !
2980    DATA  "BURST %|BURST PERCENT|BURST PCT"
2990    DATA    "BURST %"
3000    DATA    ""
3010    DATA  "BURST TIME|BURST TOTAL TIME|BSIZ|BLOCK SIZE"
3020    DATA    "BURST TIME"
3030    DATA    ""
3040    !
3050    !     End of special cases
3060    !
3070    DATA  "SPAN|SPAN FREQ|SPAN FREQUENCY"
3080    DATA    "SP"
3090    DATA    ""
3100    DATA  "TRIG|TRIG MODE|TRIGGER MODE|TRIG SOURCE|TRIGGER SOURCE"
3110    DATA    "TRGM"
3120    DATA    "OFF|O|OF|IGNR|FREERUN|FREE RUN|IGNORE|IGNORE TRIGGER|I|IG|IGN"
3130    DATA    "SEND|SEND TRIGGER|S|SE|SEN"
3140    DATA    "RCVE|RECEIVE|RECEIVE TRIGGER|R|RE|REC|RC|RCV",""
3150    DATA  "ZOOM|ZOOM MODE"
3160    DATA    "ZOOM","OFF|OF","ON",""
3170    DATA  "CLEAR|CLEAR ERRORS"
3180    DATA    "CLR",""
3190    DATA  "SRQ MASK|SRQ"
3200    DATA    "RQS",""
3210    DATA  "INTR MASK|INTERRUPT MASK|INTERRUPT"
3220    DATA    "INTR",""
3230    DATA  "SHUT MASK|SHUTDOWN MASK|SHUTDOWN"
3240    DATA    "SHUT",""
3250    DATA  "ERROR|ERROR QUEUE"
3260    DATA    "ERR",""
3270    DATA  "STATUS|GET STATUS"
3280    DATA    "STA",""
3290    DATA  "CHECK STATUS"
3300    DATA    "STC",""
3310    DATA  "STATE|MODULE STATE|MEASUREMENT STATE"
3320    DATA    "MS",""
3330    DATA  "DC SHUT|DC SHUTDOWN|DCSHUT|DCSHUTDOWN"
3340    DATA    "DCSC",""
3350    DATA  "CLEAR SHUT|CLEAR SHUTDOWN"
3360    DATA    "CSHT",""
3370    DATA  "DISABLE SHUT|DISABLE SHUTDOWN"
3380    DATA    "DSHT",""
3390    DATA  "PERCENT FR|PERCENT FREQ|PERCENT FREQUENCY|PCT FR|%FR"
3400    DATA    "PFR",""
3410    DATA  "PERCENT SP|PERCENT SPAN|PCT SP|%SP"
3420    DATA    "PSP",""
3430    DATA  "CAL|CALIBRATION|CAL MODE|CALIBRATION MODE"
3440    DATA    "ICAL"
3450    DATA    "OFF|OF","ON","INVERSE|I|IN|INV|INVE|INVER|INVERS"
3460    DATA    "SOURCE|S|SO|SOU|SOUR|SOURC",""
3470    DATA  "FILTER BYPASS|ANALOG FILTER BYPASS|FILT|FIL"
3480    DATA    "AFBY"
3490    DATA    "OFF|OF","ON|BYPASS|B|BY|BYP|BYPA|BYPAS"
3500    DATA    "100|100HZ|100 HZ|HUNDRED|HUNDRED HZ|H|HU|HUN|HUNDR"
3510    DATA    "3000|3000HZ|3000 HZ|3KHZ|3 KHZ|THREE KHZ|T|TH|THR"
3520    DATA    "50000|50000HZ|50000 HZ|50KHZ|50 KHZ|FIFTY KHZ|F|FI|FIF|FIFT"
3530    DATA    ""
3540    DATA  "PHASE|START PHASE|LO PHASE|PHA|PHAS"
3550    DATA    "PH",""
3560    DATA  "ARM MODE"
3570    DATA    "ARM"
3580    DATA    "AUTO|FREERUN|FREE RUN|A|AU|AUT"
3590    DATA    "MANUAL|M|MA|MANU|MANUA",""
3600    DATA  "MAN ARM|MANUAL ARM|ARM MEASUREMENT"
3610    DATA    "MARM",""
3620    DATA  "RAMP RATE"
3630    DATA    "RAMP",""
3640    DATA  "SYNC MODE"
3650    DATA    "SYNC","OFF|OF","ON",""
3660    DATA  "START|START MEASUREMENT|START MEAS"
3670    DATA    "STRT",""
3680    DATA  "NO MORE"
3690    !
3700  SUBEND
3710  ! PAGE -> 
3720  !************************************************************************
3730 Srce_setup:SUB Srce_setup(OPTIONAL Passed_setup$(*))
3740    !
3750    ! Srce_setup is used to specify the columns that will show up in the
3760    ! source spreadsheet.  The Passed_setup$ parameter is an array of
3770    ! strings, each specifying one column of the spreadsheet.  If the
3780    ! parameter is not there, default columns are used.
3790    !
3800    COM /Srce_sprd_posn/ Row,Col,Start_row
3810    COM /Srce_sprd_box/ Box$(*)
3820    COM /Srce_sprd_title/ Title$(*)
3830    COM /Srce_sprd_tog/ Toggle$(*)
3840    COM /Srce_sprd_cmnd/ Cmnd_code$(*)
3850    COM /Srce_sprd_prmpt/ Prompt$(*)
3860    COM /Srce_sprd_reset/ Reset_parms$(*)
3870    COM /Srce_sprd_other/ Col_width(*),Max_col,Max_row,Modify_col
3880    !
3890    COM /Srce_cmnd_cnv/ Cnv_cmnd_code$(*),Cnv_mod_cmnd$(*)
3900    COM /Srce_parm_cnv/ Convert_parm$(*)
3910    !
3920    DIM Temp_code$[80]
3930    DIM Setup_array$(1:32)[20],Setup_name$[20],Dummy$[255]
3940    INTEGER Null_found,Loop_count,Max_width,Total_width
3950    !
3960    RESTORE Srce_def_setup
3970    READ Setup_size
3980    REDIM Setup_array$(1:Setup_size)
3990    READ Setup_array$(*)
4000    IF NPAR>0 THEN MAT Setup_array$= Passed_setup$
4010    Setup_size=SIZE(Setup_array$,1)
4020    REDIM Title$(1:(Setup_size+1),0:2),Cmnd_code$(1:(Setup_size+1))
4030    REDIM Prompt$(1:(Setup_size+1)),Col_width(1:(Setup_size+1))
4040    !
4050    Max_col=Setup_size+1
4060    Max_row=63
4070    Modify_col=2
4080    !
4090    Row=1
4100    Col=2
4110    Start_row=1
4120    !
4130    ! Setup the first column
4140    !
4150    Col_width(1)=16
4160    Title$(1,1)="Channel"
4170    Title$(1,2)="Name"
4180    Cmnd_code$(1)=""
4190    Prompt$(1)=""
4200    !
4210    ! Read the column data into arrays
4220    !
4230    Total_width=Col_width(1)+2
4240    FOR C=2 TO Max_col
4250      RESTORE Srce_data
4260      REPEAT
4270        READ Setup_name$
4280        IF UPC$(Setup_name$)="NO MORE" THEN 
4290          User_stop("Illegal setup parm. to Srce_setup: "&Setup_array$(C-1))
4300        END IF
4310        This_is_it=(UPC$(Setup_name$)=UPC$(Setup_array$(C-1)))
4320        READ Toggle$(C),Reset_parms$(C),Col_width(C)
4330        READ Title$(C,1),Title$(C,2),Prompt$(C)
4340        Cmnd_code$(C)=Cnv_mod_cmnd$(FNSrce_get_code(Setup_name$))
4350        IF This_is_it THEN Total_width=Total_width+1+Col_width(C)
4360      UNTIL This_is_it
4370    NEXT C
4380    Title$(1,0)="Source Setup"
4390    Max_width=FNLib_crt_width
4400    IF Total_width>Max_width AND Total_width<Max_width+5 THEN 
4410      Col_width(1)=Col_width(1)-Total_width+Max_width
4420      Total_width=Max_width
4430    END IF
4440    IF Total_width>Max_width THEN CALL User_error("Illegal Setup_array in Srce_srce, too many chars: "&VAL$(Total_width))
4450    C=1
4460    Loop_count=0
4470    WHILE Total_width<Max_width AND Loop_count<4
4480      Col_width(C)=Col_width(C)+1
4490      C=C+1
4500      IF C>Max_col THEN 
4510        C=1
4520        Loop_count=Loop_count+1
4530      END IF
4540      Total_width=Total_width+1
4550    END WHILE
4560    SUBEXIT
4570    !
4580    ! The data statements at the end of this subprogram define the
4590    ! possible columns for the source spreadsheet.  For each column, there
4600    ! is an associated source command, a list of the parameters to send to
4610    ! the module as the prev and next keys are used, a default (reset)
4620    ! value for the command, a column width, two column title strings, and
4630    ! a prompt string.  This data for each column is loaded into arrays for
4640    ! the spreadsheet to use.
4650    !
4660    !
4670    !   command code         toggle codes                    default value
4680    !   ----------------     ---------------------------     -------------
4690    !     col_width  title1         title2       Prompt
4700    !     ---------  ----------     ----------   --------------------
4710 Srce_data:!
4720    DATA    "MODE",  "OFF|RANDOM|BRAND|SINE|BSINE|PULSE|NPULSE|DC",0
4730    DATA      6,     "Source",       "Mode"
4740    DATA    "Source Mode : Off, Rand, Burst Rand, Sine, Burst Sine, Pulse, Neg Pulse, Dc"
4750    DATA    "OFFSET",        "",0
4760    DATA      7,     "DC",          "Offset",    "DC Offset in Volts"
4770    DATA    "AMPLITUDE",     "",-58
4780    DATA      7,     "AMP",        "(dBVp)","Source Peak Amplitude in dBVp"
4790    DATA    "SPAN",          "",51200
4800    DATA      9,     "Span",        "(Hz)",      "Span frequency in Hz"
4810    DATA    "CENTER FREQ",   "",25600
4820    DATA      9,     "Center",      "Freq (Hz)", "Center frequency in Hz"
4830    DATA    "SINE FREQ",     "",1000
4840    DATA      9,     "Sine",        "Freq (Hz)", "Sine frequency in Hz"
4850    DATA    "TRIG",          "OFF|SEND|RCVE",0
4860    DATA      4,     "Trig",       "Mode", "Trigger mode : Off, Send, Rcve"
4870    DATA    "BURST %",       "",50
4880    DATA      5,     "Burst",       "%",         "Burst On Percentage"
4890    DATA    "BURST TIME",    "",1024
4900    DATA      6,     "Burst",       "Time",      "Burst On and Off Total Time"
4910    DATA    "ZOOM",          "OFF|ON",0
4920    DATA      4,     "Zoom",        "Mode",      "Zoom Mode : OFf, ON"
4930    DATA    "NO MORE"
4940    !
4950    ! The following defines the columns to be used in the source
4960    ! spreadsheet if no columns are specified.
4970    !
4980 Srce_def_setup:   !
4990    DATA 8
5000    DATA "MODE","OFFSET","AMPLITUDE","SPAN","CENTER FREQ"
5010    DATA "TRIG","BURST %","BURST TIME"
5020    !
5030    !
5040  SUBEND
5050  ! PAGE -> 
5060  !************************************************************************
5070 Srce_init:SUB Srce_init(OPTIONAL Passed_setup$(*))
5080    !
5090    ! Should be called after any change in the srce
5100    ! configuration or after the Srce_srce subprogram
5110    ! is called.  The optional parameter can be used to
5120    ! reinitialize the columns of the source spread sheet.
5130    ! Passed_setup$ contains a list of spread sheet columns
5140    ! to be displayed.  This subprogram also loads up Box$
5150    ! with correct values.
5160    !
5170    COM /Srce_sprd_box/ Box$(*)
5180    COM /Srce_sprd_title/ Title$(*)
5190    COM /Srce_sprd_prmpt/ Prompt$(*)
5200    COM /Srce_sprd_cmnd/ Cmnd_code$(*)
5210    COM /Srce_sprd_other/ Col_width(*),Max_col,Max_row,Modify_col
5220    !
5230    IF NPAR<>0 THEN 
5240      Srce_setup(Passed_setup$(*))
5250    ELSE
5260      Srce_setup
5270    END IF
5280    !
5290    ALLOCATE Srce_labels$(1:63)[16]
5300    Cnfg_labels("ALL SOURCE",Srce_labels$(*),Num_sources)
5310    !
5320    REDIM Box$(1:Max_col,1:(1+Num_sources))
5330    !
5340    Max_row=Num_sources+1
5350    Box$(1,1)="All Source"
5360    FOR Col=2 TO SIZE(Box$,1)
5370      Box$(Col,1)=""
5380    NEXT Col
5390    FOR Row=1 TO Num_sources
5400      Box$(1,Row+1)=Srce_labels$(Row)
5410    NEXT Row
5420    !
5430    DEALLOCATE Srce_labels$(*)
5440    !
5450    Srce_cmd("ALL SOURCE","ZOOM","ON")
5460    Srce_reset("ALL SOURCE")
5470  SUBEND
5480  ! PAGE -> 
5490  !************************************************************************
5500 Srce_spread:SUB Srce_spread(Changed)
5510    !
5520    ! Subprogram to display and allow modification of the
5530    ! source spreadsheet.  The Changed parameter returns true
5540    ! if any change has occurred to a source module.
5550    ! When the Srce_spread subprogram is exited, the source
5560    ! is set to "SYNC OFF", all errors are cleared, and a
5570    ! start command is sent to the sources.
5580    !
5590    COM /Srce_sprd_posn/ Row,Col,Start_row
5600    COM /Srce_sprd_box/ Box$(*)
5610    COM /Srce_sprd_title/ Title$(*)
5620    COM /Srce_sprd_tog/ Toggle$(*)
5630    COM /Srce_sprd_cmnd/ Cmnd_code$(*)
5640    COM /Srce_sprd_prmpt/ Prompt$(*)
5650    COM /Srce_sprd_other/ Col_width(*),Max_col,Max_row,Modify_col
5660    !
5670    INTEGER Tog_ptr,Strt_ptr,Stop_ptr,Strt_row,Stop_row,Previous
5680    DIM New_entry$[160],Temp$[255],Module_label$[16]
5690    DIM Tog_temp$[200],Box_temp$[100]
5700    !
5710    ! Define softkeys.  Keys 1 to 4 are reserved for "firmkeys"
5720    ON KEY 5 LABEL FNUser_keylabel$("Reset") CALL User_key5isr
5730    ON KEY 6 LABEL FNUser_keylabel$("Clear Shutdown") CALL User_key6isr
5740    ON KEY 7 LABEL FNUser_keylabel$("Prev") CALL User_key7isr
5750    ON KEY 8 LABEL FNUser_keylabel$("Next") CALL User_key8isr
5760    !
5770    User_clr_scr
5780    Changed=0
5790    !
5800    ! Now call spread sheet.  It returns with New_entry$ and Row and Col
5810    Done=0
5820    REPEAT
5830      User_spread(Box$(*),Title$(*),Prompt$(*),New_entry$,Col_width(*),Modify_col,Col,Row,Start_row)
5840      !
5850      IF Row=1 THEN 
5860        Module_label$="ALL SOURCE"
5870      ELSE
5880        Module_label$=Box$(1,Row)
5890      END IF
5900      !
5910      SELECT FNUser_check_key
5920      CASE 0                 ! No key pressed, must be a New_entry$ for Box
5930        GOSUB Srce_chk_change
5940        GOSUB Srce_new_entry
5950      CASE 5
5960        GOSUB Srce_chk_change
5970        Dummy=FNUser_get_key ! To clear the key
5980        DISP "Resetting Source Modules"
5990        Srce_reset(Module_label$)
6000      CASE 6
6010        GOSUB Srce_chk_change
6020        Dummy=FNUser_get_key
6030        Srce_cmd("ALL SOURCE","CLEAR SHUTDOWN")
6040        Srce_cmd("ALL SOURCE","STA?")
6050        Hw_wait_gbl_rdy
6060      CASE 7
6070        Previous=1
6080        GOSUB Srce_next_prev
6090      CASE 8
6100        Previous=0
6110        GOSUB Srce_next_prev
6120        !
6130      CASE ELSE   ! A softkey, but not one of mine, so exit
6140        IF Changed THEN 
6150          Srce_cmd("ALL SOURCE","CLEAR")
6160          Srce_cmd("ALL SOURCE","SYNC","OFF")
6170          Srce_cmd("ALL SOURCE","START")
6180        END IF
6190        Done=1
6200      END SELECT
6210    UNTIL Done
6220    User_clr_scr
6230    SUBEXIT
6240    !
6250    !
6260 Srce_chk_change:!
6270    IF NOT Changed THEN 
6280      Hw_dev_clear
6290      Changed=1
6300    END IF
6310    RETURN 
6320    !
6330 Srce_new_entry:!
6340   ! Acts on new_entry from spread_sheet
6350    IF TRIM$(New_entry$)<>"" THEN 
6360      Cnfg_cmd(Module_label$,"CLR")
6370      ! Srce_cmd will update Box$, so we don't have to do it here.
6380      Srce_cmd(Module_label$,Cmnd_code$(Col),New_entry$)
6390      IF Row<>1 THEN ! Not a global command
6400        IF POS(FNSrce_stat_2_str$(FNCnfg_rmst(Module_label$)),"ERR") THEN 
6410          User_error("Value not understood")
6420        END IF
6430      ELSE
6440        IF Max_row>1 THEN 
6450          IF POS(FNSrce_stat_2_str$(FNCnfg_rmst(Box$(1,2))),"ERR") THEN 
6460            User_error("Value not understood")
6470          END IF
6480        END IF
6490      END IF
6500      DISP 
6510    END IF
6520    RETURN 
6530    !
6540 Srce_next_prev:!
6550    GOSUB Srce_chk_change
6560    Dummy=FNUser_get_key
6570    Tog_temp$=Toggle$(Col)
6580    IF Tog_temp$<>"" THEN 
6590      IF Row=1 THEN 
6600        Strt_row=2
6610        Stop_row=Max_row
6620      ELSE
6630        Strt_row=Row
6640        Stop_row=Row
6650      END IF
6660      IF Stop_row>=Strt_row THEN 
6670        Box_temp$=Box$(Col,Strt_row)
6680        GOSUB Srce_find_it
6690      END IF
6700      FOR R=Strt_row TO Stop_row
6710        Srce_cmd(Box$(1,R),Cmnd_code$(Col),Box_temp$)
6720      NEXT R
6730    END IF
6740    RETURN 
6750    !
6760    ! This finds the current parameter in string Tog_temp$, and then
6770    ! finds either the previous or the next parameter in that string.
6780 Srce_find_it:!
6790    Tog_ptr=POS("|"&Tog_temp$&"|","|"&Box_temp$&"|")
6800    IF Previous THEN 
6810      Stop_ptr=Tog_ptr-2
6820      IF Tog_ptr<2 THEN Stop_ptr=LEN(Tog_temp$)
6830      Tog_ptr=LEN(Tog_temp$)-Stop_ptr+1
6840      Tog_temp$=REV$(Tog_temp$)
6850      Strt_ptr=POS(Tog_temp$[Tog_ptr]&"|","|")
6860      IF Strt_ptr<>0 THEN 
6870        Strt_ptr=LEN(Tog_temp$)-Tog_ptr-Strt_ptr+3
6880      ELSE
6890        Strt_ptr=1
6900      END IF
6910      Tog_temp$=REV$(Tog_temp$)
6920    ELSE
6930      IF Tog_ptr=0 THEN Tog_ptr=1
6940      Strt_ptr=POS(Tog_temp$[Tog_ptr],"|")+Tog_ptr
6950      IF Strt_ptr<=Tog_ptr THEN Strt_ptr=1
6960      Stop_ptr=POS(Tog_temp$[Strt_ptr],"|")-2+Strt_ptr
6970      IF Stop_ptr<Strt_ptr THEN Stop_ptr=LEN(Tog_temp$)
6980    END IF
6990    Box_temp$=Tog_temp$[Strt_ptr,Stop_ptr]
7000    RETURN 
7010    !
7020  SUBEND
7030  !
7040  ! PAGE -> 
7050  !************************************************************************
7060 Srce_get_all:SUB Srce_get_all(Box$(*),Cmnd_code$,Col)
7070    !
7080    ! Fills column Col of Box$ with values read from the source modules.
7090    ! Cmnd_code$ is the command string corresponding to column Col.
7100    ! This string is sent out to all source modules.  Then each is
7110    ! read from and the value (converted to verbose form) is put in Box$.
7120    !
7130    COM /Srce_cmnd_cnv/ Cnv_cmnd_code$(*),Cnv_mod_cmnd$(*)
7140    DIM Temp$[255]
7150    !
7160    Cmnd_num=FNSrce_get_code(Cmnd_code$)
7170    Temp$=Cnv_mod_cmnd$(Cmnd_num)
7180    IF Temp$="BURST %" OR Temp$="BURST TIME" THEN 
7190      ! Do individual queries instead of a global query
7200    ELSE
7210      Cnfg_cmd("ALL SOURCE",Cnv_mod_cmnd$(Cmnd_num)&"?")
7220    END IF
7230    !
7240    FOR R=2 TO SIZE(Box$,2)
7250      IF Temp$="BURST %" OR Temp$="BURST TIME" THEN 
7260        Box$(Col,R)=FNSrce_rsp$(Box$(1,R),Temp$)
7270      ELSE
7280        Box$(Col,R)=FNSrce_cnvt_in$(FNCnfg_rsp$(Box$(1,R)),Cmnd_num)
7290      END IF
7300    NEXT R
7310  SUBEND
7320  ! PAGE -> 
7330  !************************************************************************
7340 Srce_rsp:DEF FNSrce_rsp$(Module$,Cmnd$)
7350    !
7360    ! Function to query a module for what state it has been
7370    ! set to.  Command$ is the command to query.  The function returns
7380    ! a string from the module.  The Command$ can be typed out verbosely,
7390    ! and will be interpreted by the subprogram.
7400    !
7410    ! WARNING!   This routine will not query the module if the value is
7420    ! available in the spreadsheet.  The spreadsheet can be different
7430    ! from the module if an ICODE program sends commands to the module
7440    ! changing the setup, or if the CNFG file subprograms are used to
7450    ! change a source module setup.
7460    !
7470    COM /Srce_sprd_box/ Box$(*)
7480    COM /Srce_cmnd_cnv/ Cnv_cmnd_code$(*),Cnv_mod_cmnd$(*)
7490    COM /Srce_parm_cnv/ Convert_parm$(*)
7500    INTEGER Col,Row
7510    DIM Response$[256],Actual_cmnd$[255]
7520    !
7530    !
7540    ! Strip off question mark if there - it'll be added back later.
7550    !
7560    IF Cmnd$[LEN(Cmnd$)]="?" AND LEN(Cmnd$)>1 THEN 
7570      Cmnd$=Cmnd$[1;LEN(Cmnd$)-1]
7580    END IF
7590    !
7600    Cmnd_code=FNSrce_get_code(Cmnd$)
7610    IF Cmnd_code=0 THEN 
7620      RETURN FNCnfg_cmd_rsp$(Module$,Cmnd$&"?")
7630    ELSE
7640      Actual_cmnd$=Cnv_mod_cmnd$(Cmnd_code)
7650      Col=FNSrce_get_col(Actual_cmnd$)
7660      IF Col<>0 THEN 
7670        Row=FNSrce_get_row(Module$)
7680        IF Row=1 THEN 
7690          User_stop("Bad global call to FNSrce_rsp$")
7700        ELSE
7710          RETURN Box$(Col,Row)
7720        END IF
7730      ELSE
7740        !
7750        !  SPECIAL CASES -
7760        !                  "BURST %" requires that both BPAL and BPIL be
7770        !                  read, and on percentage calculated.
7780        !
7790        !                  Similarly "BURST TIME" needs both to be read.
7800        !
7810        IF Actual_cmnd$="BURST %" OR Actual_cmnd$="BURST TIME" THEN 
7820          Bpal=VAL(FNCnfg_cmd_rsp$(Module$,"BPAL?"))
7830          Bpil=VAL(FNCnfg_cmd_rsp$(Module$,"BPIL?"))
7840          IF Actual_cmnd$="BURST %" THEN 
7850            Response$=VAL$(PROUND(Bpal*100/(Bpal+Bpil),-1))
7860          ELSE                    ! Actual_cmnd$="BURST TIME"
7870            Response$=VAL$(Bpal+Bpil)
7880          END IF
7890        ELSE
7900          Response$=FNCnfg_cmd_rsp$(Module$,Actual_cmnd$&"?")
7910        END IF
7920        RETURN FNSrce_cnvt_in$(Response$,Cmnd_code)
7930      END IF
7940    END IF
7950  FNEND
7960  ! PAGE -> 
7970  !************************************************************************
7980 Srce_cmd:SUB Srce_cmd(Module$,Cmnd$,OPTIONAL Parm_$)
7990    !
8000    ! Subprogram to send a command to a source module.
8010    ! Module$ is the name of the module to send to.  Cmnd$ is the
8020    ! command to send.  Parm_$, if specified, is the parameter to
8030    ! send with the command.  In general, Cmnd$ and Parm_$ can be
8040    ! written out as verbosely as you want, and this subprogram
8050    ! will do its best to interpret them.
8060    !
8070    COM /Srce_sprd_box/ Box$(*)
8080    COM /Srce_sprd_cmnd/ Sprd_cmnd_code$(*)
8090    COM /Srce_cmnd_cnv/ Cnv_cmnd_code$(*),Cnv_mod_cmnd$(*)
8100    COM /Srce_parm_cnv/ Convert_parm$(*)
8110    COM /Srce_sprd_other/ Col_width(*),Max_col,Max_row,Modify_col
8120    DIM Actual_cmnd$[255],Temp_parm$[255],Parm$[255],Location$[20]
8130    DIM C_parm$[255],Tmp$[255]
8140    INTEGER Row,Start_row,Stop_row,Col,Found,Maxc,C
8150    !
8160    Parm$=""
8170    IF NPAR>2 THEN Parm$=Parm_$
8180    Cmnd_code=FNSrce_get_code(Cmnd$)
8190    IF Cmnd_code=0 THEN 
8200      Cnfg_cmd(Module$,Cmnd$&" "&Parm$)
8210    ELSE
8220      IF Parm$<>"" THEN 
8230        C=0
8240        Maxc=SIZE(Convert_parm$,2)-1
8250        C_parm$="|"&UPC$(TRIM$(Parm$))&"|"
8260        WHILE (C<Maxc) AND (POS("|"&Convert_parm$(Cmnd_code,C)&"|",C_parm$)=0)
8270          C=C+1
8280        END WHILE
8290        IF POS("|"&Convert_parm$(Cmnd_code,C)&"|",C_parm$)=0 THEN 
8300          Temp_parm$=Parm$
8310        ELSE
8320          Temp_parm$=VAL$(C)
8330        END IF
8340      ELSE
8350        Temp_parm$=""
8360      END IF
8370      !
8380      !  SPECIAL CASES -
8390      !                 BURST % IS USED TO SET BOTH BPAL AND BPIL!
8400      !                 Using burst % seems more friendly to the user.
8410      !                 To implement this, both BPAL and BPIL are read
8420      !                 back, and both are adjusted so that the sum
8430      !                 is kept constant, while the on time is adjusted.
8440      !
8450      !                 Similarly, BURST TIME means to adjust both BPAL
8460      !                 and BPIL while keeping their ratio constant.  The
8470      !                 Sum of the two must be equal to BURST TIME.
8480      !
8490      Actual_cmnd$=Cnv_mod_cmnd$(Cmnd_code)
8500      Col=FNSrce_get_col(Actual_cmnd$)
8510      IF Actual_cmnd$="BURST %" OR Actual_cmnd$="BURST TIME" THEN 
8520        IF Module$="ALL SOURCE" THEN 
8530          !
8540          ! Since burst commands require querying the modules before
8550          ! setting the values, the commands can't be sent globally.
8560          ! Instead, we have to do it all by hand.
8570          !
8580          Start_row=2
8590          Stop_row=Max_row
8600        ELSE
8610          Start_row=FNSrce_get_row(Module$)
8620          Stop_row=Start_row
8630          IF Start_row=0 THEN Stop_row=-1
8640        END IF
8650        FOR Row=Start_row TO Stop_row
8660          !
8670          Location$=Box$(1,Row)
8680          !
8690          ! Get old BPAL and BPIL
8700          Bpal=VAL(FNCnfg_cmd_rsp$(Location$,"BPAL?"))
8710          Bpil=VAL(FNCnfg_cmd_rsp$(Location$,"BPIL?"))
8720          !
8730          ! Calculate new BPAL and BPIL
8740          IF Actual_cmnd$="BURST %" THEN 
8750            Total_time=Bpal+Bpil
8760            Bpal=PROUND(VAL(Temp_parm$)/100*Total_time,0)
8770          ELSE                             ! Actual_cmnd$="BURST TIME"
8780            Total_time=VAL(Temp_parm$)/2   ! Because ZOOM is ON
8790            Bpal=PROUND(Total_time/(Bpal+Bpil)*Bpal,0)
8800          END IF
8810          !
8820          ! BPAL has a minimum legal value of 2, maximum of 65536
8830          IF Bpal<2 THEN Bpal=2
8840          IF Bpal>65536 THEN Bpal=65536
8850          Bpil=Total_time-Bpal
8860          ! BPIL has a minimum legal value of 4, maximum of 131072
8870          IF Bpil<4 THEN 
8880            Bpal=MAX(Bpal-4+Bpil,2) ! sum constant unless BPAL too small
8890            Bpil=4
8900          END IF
8910          IF Bpil>131072 THEN Bpil=131072
8920          !
8930          ! Send back to module
8940          Cnfg_cmd(Location$,"BPAL "&VAL$(Bpal)&";BPIL "&VAL$(Bpil))
8950          !
8960          ! Update Box$ if it's part of the spread sheet
8970          IF Col<>0 THEN 
8980            IF Actual_cmnd$="BURST TIME" THEN 
8990              Box$(Col,Row)=VAL$(PROUND((Bpal+Bpil)*2,0))
9000            ELSE
9010              Box$(Col,Row)=VAL$(PROUND(100.0*Bpal/(Bpal+Bpil),-1))
9020            END IF
9030          END IF
9040          !
9050          IF Actual_cmnd$="BURST TIME" THEN 
9060            Col=FNSrce_get_col("BURST %")
9070            IF Col<>0 THEN 
9080              Box$(Col,Row)=VAL$(PROUND(100.0*Bpal/(Bpal+Bpil),-1))
9090            END IF
9100          END IF
9110        NEXT Row
9120      ELSE
9130        Cnfg_cmd(Module$,Actual_cmnd$&" "&Temp_parm$)
9140        Row=FNSrce_get_row(Module$)
9150        !
9160        ! The reset command ('RST') is sort of a special case.  After it
9170        ! is sent, the whole spreadsheet must be updated, not just one
9180        ! column.
9190        !
9200        IF Actual_cmnd$="RST" THEN 
9210          FOR Col=2 TO Max_col
9220            Cmnd_code=FNSrce_get_code(Sprd_cmnd_code$(Col))
9230            IF Row=1 THEN 
9240              Srce_get_all(Box$(*),Cnv_mod_cmnd$(Cmnd_code),(Col))
9250            ELSE
9260              ! Yet again we've got to worry about BURST % and BURST TIME
9270              IF Cnv_mod_cmnd$(Cmnd_code)="BURST %" THEN 
9280                Srce_cmd(Module$,"BURST %","50")
9290                Box$(Col,Row)="50"
9300              ELSE
9310                IF Cnv_mod_cmnd$(Cmnd_code)="BURST TIME" THEN 
9320                  Srce_cmd(Module$,"BURST TIME","4096")
9330                  Box$(Col,Row)="4096"
9340                ELSE
9350                  Tmp$=FNCnfg_cmd_rsp$(Module$,Cnv_mod_cmnd$(Cmnd_code)&"?")
9360                  Box$(Col,Row)=FNSrce_cnvt_in$(Tmp$,Cmnd_code)
9370                END IF
9380              END IF
9390            END IF
9400          NEXT Col
9410        ELSE
9420          IF Col<>0 THEN 
9430            IF Row=1 THEN 
9440              Srce_get_all(Box$(*),Cmnd$,(Col))
9450            ELSE
9460              Tmp$=FNCnfg_cmd_rsp$(Module$,Actual_cmnd$&"?")
9470              Box$(Col,Row)=FNSrce_cnvt_in$(Tmp$,Cmnd_code)
9480            END IF
9490          END IF
9500        END IF
9510      END IF
9520    END IF
9530  SUBEND
9540  ! PAGE -> 
9550  !************************************************************************
9560 Srce_get_code:DEF FNSrce_get_code(Cmnd_code$)
9570    !
9580    ! Converts Cmnd_code$, which is a verbose command string, into
9590    ! a number representing the position of that command in the
9600    ! array of possible commands.  This number can then be used to
9610    ! index into the array of actual commands to send to a module.
9620    !
9630    COM /Srce_cmnd_cnv/ Cnv_cmnd_code$(*),Cnv_mod_cmnd$(*)
9640    DIM In_code$[100]
9650    !
9660    In_code$="|"&UPC$(TRIM$(Cmnd_code$))&"|"
9670    FOR Cmnd_code=1 TO SIZE(Cnv_cmnd_code$,1)
9680      IF POS("|"&Cnv_cmnd_code$(Cmnd_code)&"|",In_code$)<>0 THEN 
9690        RETURN Cmnd_code
9700      END IF
9710    NEXT Cmnd_code
9720    RETURN 0
9730  FNEND
9740  ! PAGE -> 
9750  !************************************************************************
9760 Srce_cnvt_in:DEF FNSrce_cnvt_in$(Response$,Cmnd_code)
9770    !
9780    ! Response$ is a response from a source module.  Cmnd_code is the
9790    ! number corresponding to the command which generated the response.
9800    ! This function returns the verbose form of the response.
9810    !
9820    COM /Srce_parm_cnv/ Convert_parm$(*)
9830    DIM Temp_r$[256]
9840    !
9850    IF Cmnd_code=0 THEN RETURN Response$
9860    IF Convert_parm$(Cmnd_code,1)="" THEN RETURN Response$
9870    !
9880    Response=VAL(Response$)
9890    Temp_r$=Convert_parm$(Cmnd_code,Response)
9900    End_pos=POS(Temp_r$,"|")-1
9910    IF End_pos>0 THEN Temp_r$=Temp_r$[1;End_pos]
9920    RETURN Temp_r$
9930  FNEND
9940  ! PAGE -> 
9950  !************************************************************************
9960 Srce_reset:SUB Srce_reset(Module_label$)
9970    !
9980    ! Subprogram to set the specified module(s) to a known
9990    ! state.  This subprogram only resets the parameters that
10000   ! are in the spreadsheet to known values.  It also clears
10010   ! shutdown if the module was shut down.  To reset ALL
10020   ! parameters of the module, use:
10030   !   Srce_cmd(Module_label$,"RESET").
10040   !
10050   COM /Srce_sprd_box/ Box$(*)
10060   COM /Srce_sprd_cmnd/ Cmnd_code$(*)
10070   COM /Srce_sprd_tog/ Toggle$(*)
10080   COM /Srce_sprd_reset/ Reset_parms$(*)
10090   COM /Srce_sprd_other/ Col_width(*),Max_col,Max_row,Modify_col
10100   INTEGER Col,Redo_pct
10110   !
10120   Redo_pct=0
10130   FOR Col=2 TO Max_col
10140     Srce_cmd(Module_label$,Cmnd_code$(Col),Reset_parms$(Col))
10150     IF Cmnd_code$(Col)="BURST %" THEN Redo_pct=Col
10160   NEXT Col
10170   ! Sometimes it is necessary to redo the burst percent command.
10180   ! If the burst size was set to some small number (6 for example),
10190   ! and the burst percent was reset to 50%, it would not actually get
10200   ! set to 50% because when the burst size is 6, the on time must be
10210   ! 2 (because the off time has a minimum value of 4).  When the
10220   ! burst size is later set to its reset value (1024), the percent
10230   ! will still be 33.3% unless the burst % command is re-sent.
10240   IF Redo_pct THEN 
10250     Srce_cmd(Module_label$,"BURST %",Reset_parms$(Redo_pct))
10260   END IF
10270   ! If the module has been shut down for any reason, clear it.
10280   Srce_cmd(Module_label$,"CLEAR SHUTDOWN")
10290 SUBEND
10300 !************************************************************************
10310 Srce_get_row:DEF FNSrce_get_row(Module_label$)
10320   !
10330   ! Returns the row in Box$ that source label Module_label$ refers to.
10340   ! Since every label used should be somewhere in Box$, no error checking
10350   ! is done.  This will return 0 if Module_label$ isn't found.
10360   !
10370   COM /Srce_sprd_box/ Box$(*)
10380   COM /Srce_sprd_other/ Col_width(*),Max_col,Max_row,Modify_col
10390   DIM Temp_label$[16]
10400   Temp_label$=UPC$(TRIM$(Module_label$))
10410   FOR Row=1 TO Max_row
10420     IF TRIM$(UPC$(Box$(1,Row)))=Temp_label$ THEN RETURN Row
10430   NEXT Row
10440   RETURN 0
10450 FNEND
10460 !************************************************************************
10470 Srce_get_errstr:DEF FNSrce_get_errstr$(Error_num)
10480   !
10490   ! This subprogram returns a string containing the error
10500   ! message corresponding to the source error number
10510   ! that is passed to it.
10520   !
10530   DIM Msg$[100]
10540   INTEGER Current_err
10550   ON ERROR GOTO Srce_not_found
10560   REPEAT
10570     READ Current_err,Msg$
10580   UNTIL Current_err=Error_num
10590   OFF ERROR 
10600   RETURN Msg$
10610 Srce_not_found:OFF ERROR 
10620   RETURN VAL$(Error_num)
10630   DATA -100,"Illegal Command"
10640   DATA -101,"Illegal Parameter"
10650   DATA -111,"Set Command Invalid Header"
10660   DATA -112,"Set Command Terminated In Mid-Block"
10670   DATA 100,"Parameter Out Of Range"
10680   DATA 111,"Start Must Be Received Before Marm"
10690   DATA 112,"Marm Not Valid In Arm Auto Mode"
10700   DATA 121,"Span Is Maximum When Zoom Is Off"
10710   DATA 122,"Span Is Minimum When Zoom Is On"
10720   DATA 131,"Set Command Invalid Block Length"
10730   DATA 132,"Set Command Got Wrong ID"
10740   DATA 133,"Set Command Bad Syntax Or Out Of Range"
10750   DATA 140,"Response Buffer Overflow"
10760   DATA 150,"Attempt To Remove Current Global Class"
10770   DATA 501,"HP-IB Module - Command Register Overwrite"
10780   DATA 502,"HP-IB Module - Response Register Overread"
10790   DATA 510,"HP-IB Module - Global Class Number Out Of Range"
10800   DATA 520,"System - Trigger Line Bad"
10810   DATA 600,"Hardware - 01 Board Fails DSA Test"
10820   DATA 610,"Hardware - Firmware ROM Fails DSA Test"
10830   DATA 611,"Hardware - Firmware ROM Bit 1 Bad"
10840   DATA 612,"Hardware - Firmware ROM Bit 2 Bad"
10850   DATA 613,"Hardware - Firmware ROM Bit 3 Bad"
10860   DATA 614,"Hardware - Firmware ROM Bit 4 Bad"
10870   DATA 615,"Hardware - Firmware ROM Bit 5 Bad"
10880   DATA 616,"Hardware - Firmware ROM Bit 6 Bad"
10890   DATA 617,"Hardware - Firmware ROM Bit 7 Bad"
10900   DATA 618,"Hardware - Firmware ROM Bit 8 Bad"
10910   DATA 620,"Hardware - RAM Fails Self Test"
10920   DATA 621,"Hardware - RAM Fails in write FF"
10930   DATA 622,"Hardware - RAM Fails in write 00"
10940   DATA 623,"Hardware - RAM Fails in write counter"
10950   DATA 624,"Hardware - RAM Fails in write complement"
10960   DATA 630,"Hardware - Checksum Error In NovRAM"
10970   DATA 640,"Hardware - Span PIT Non-functional"
10980   DATA 641,"Hardware - Span PIT Doesn't Set Up"
10990   DATA 642,"Hardware - Span PIT 0-Counter Bad"
11000   DATA 643,"Hardware - Span PIT 1-Counter Bad"
11010   DATA 650,"Hardware - Burst PIT Non-functional"
11020   DATA 651,"Hardware - Burst PIT Doesn't Set Up"
11030   DATA 652,"Hardware - Burst PIT 0-Counter Bad"
11040   DATA 653,"Hardware - Burst PIT 1-Counter Bad"
11050   DATA 654,"Hardware - Burst PIT 2-Counter Bad"
11060   DATA 660,"Hardware - Trigger Non-Functional"
11070   DATA 670,"Firmware Interrupt Error"
11080   DATA 671,"Unknown NMI Interrupt"
11090   DATA 672,"Unknown FIRQ Interrupt"
11100   DATA 673,"Unknown SWI Interrupt"
11110   DATA 674,"Unknown SWI2 Interrupt"
11120   DATA 675,"Unknown SWI3 Interrupt"
11130   DATA 676,"Unknown IRQ Interrupt"
11140   DATA 710,"Hardware - Calibrator Doesn't Work"
11150   DATA 711,"Hardware - Calibrator ROM Trigger Bit Bad"
11160   DATA 712,"Hardware - Calibrator Invertor Bad"
11170   DATA 713,"Hardware - Calibrator ROM Sequence Bit Bad"
11180   DATA 720,"Hardware - Zener Noise Source Doesn't Work"
11190   DATA 721,"Hardware - Zener Puts Out Too Many Zeros"
11200   DATA 722,"Hardware - Zener Puts Out Too Many Ones"
11210   DATA 723,"Hardware - Zener Puts Out Only Zeros"
11220   DATA 724,"Hardware - Zener Puts Out Only Ones"
11230   DATA 730,"Hardware - Internal Calibration Error"
11240   DATA 741,"Hardware - DC Low Overflow"
11250   DATA 742,"Hardware - DC High Overflow"
11260   DATA 751,"Hardware - AC Amplitude Error"
11270 FNEND
11280 Srce_stat_2_str:DEF FNSrce_stat_2_str$(Stat)
11290   !
11300   ! This subprogram returns a string containing the
11310   ! mnemonics for each of the status bits set in the
11320   ! passed in status number.
11330   !
11340   DIM Ret_str$[100]
11350   INTEGER Bitnum
11360   !
11370   Ret_str$=""
11380   RESTORE Srce_stat_data
11390   !
11400   FOR Bitnum=0 TO 14
11410     READ Bit_name$
11420     IF BIT(Stat,Bitnum) THEN Ret_str$=Ret_str$&Bit_name$&"|"
11430   NEXT Bitnum
11440   !
11450   IF Ret_str$="" THEN RETURN ""
11460   RETURN TRIM$(Ret_str$[1,LEN(Ret_str$)-1])
11470   !
11480 Srce_stat_data:  !
11490   DATA    "ISHT","TRG","OOOS","ARMRDY"
11500   DATA    "RDY","ERR","BIT6","OVLD"
11510   DATA    "RQS","INTR","SHUT","MSHT"
11520   DATA    "FSFAST","BIT13","PON","???"
11530 FNEND
11540 !************************************************************************
11550 Srce_save:SUB Srce_save(@File,Ok)
11560   !
11570   ! This subprogram saves the current source setups (Box$) in
11580   ! the file specified by @File, and returns Ok=1 if
11590   ! it successfully saves the setups.
11600   !
11610   COM /Srce_sprd_box/ Box$(*)
11620   INTEGER File_format_rev
11630   File_format_rev=2620
11640   OUTPUT @File;File_format_rev
11650   File_save_s(@File,Box$(*))
11660   Ok=1
11670 SUBEND
11680 !************************************************************************
11690 Srce_load:SUB Srce_load(@File,Ok)
11700   !
11710   ! This subprogram loads the source setups from file
11720   ! @File, and returns Ok=1 if the load is successful.
11730   !
11740   COM /Srce_sprd_box/ Box$(*)
11750   COM /Srce_sprd_cmnd/ Cmnd_code$(*)
11760   COM /Srce_sprd_other/ Col_width(*),Max_col,Max_row,Modify_col
11770   INTEGER File_format_rev
11780   !
11790   ENTER @File;File_format_rev
11800   SELECT File_format_rev
11810   CASE 2620
11820     File_load_s(@File,Box$(*))
11830     Srce_cmd("ALL SOURCE","CLEAR")
11840     FOR Col=2 TO Max_col
11850       FOR Row=2 TO Max_row
11860         Srce_cmd(Box$(1,Row),Cmnd_code$(Col),Box$(Col,Row))
11870       NEXT Row
11880     NEXT Col
11890     Cnfg_cmd("ALL SOURCE","ERR?")
11900     FOR Row=2 TO Max_row
11910       IF VAL(FNCnfg_rsp$(Box$(1,Row)))<>0 THEN 
11920         User_error("Unable to setup module "&Box$(1,Row)&" when recalling state.")
11930       END IF
11940     NEXT Row
11950     Srce_cmd("ALL SOURCE","SYNC","OFF")
11960     Srce_cmd("ALL SOURCE","START")
11970     Ok=1
11980   CASE ELSE  ! Unknown rev
11990     User_error("ERROR Incompatible display file format in Inpt_load.")
12000     Ok=0
12010   END SELECT
12020 SUBEND
12030 !************************************************************************
12040 Srce_get_col:DEF FNSrce_get_col(Actual_cmnd$)
12050   !
12060   ! Returns the column number in Box$ corresponding to the source
12070   ! command Actual_cmnd$.  If no column in Box$ uses Actual_cmnd$,
12080   ! zero is returned.
12090   !
12100   COM /Srce_sprd_cmnd/ Cmnd_code$(*)
12110   COM /Srce_sprd_other/ Col_width(*),Max_col,Max_row,Modify_col
12120   FOR Col=2 TO Max_col
12130     IF Cmnd_code$(Col)=Actual_cmnd$ THEN RETURN Col
12140   NEXT Col
12150   RETURN 0
12160 FNEND
12170 Srce_str_2_stat:DEF FNSrce_str_2_stat(A$)
12180   !
12190   ! This subroutine returns a number which represents the status
12200   ! of the Source module if the status bits indicated by A$ are set.
12210   ! Bit mnemonics may be separated by "," or "|".  This is the
12220   ! inverse of subprogram FNSrce_stat_2_str$(stat).
12230   !
12240   ALLOCATE Temp$[255],Bit$[40]
12250   Temp$=TRIM$(UPC$(A$))
12260   Stat=0
12270   WHILE POS(Temp$,",")
12280     Temp$[POS(Temp$,",");1]="|"
12290   END WHILE
12300   WHILE POS(Temp$,"|")
12310     Bit$=Temp$[1,POS(Temp$,"|")-1]
12320     GOSUB Add_bit_value
12330     Temp$=Temp$[POS(Temp$,"|")+1]
12340   END WHILE
12350   IF Temp$<>"" THEN 
12360     Bit$=Temp$
12370     GOSUB Add_bit_value
12380   END IF
12390   RETURN Stat
12400 Add_bit_value:!
12410   SELECT Bit$
12420   CASE "ISHT","INPUT SHUTDOWN"
12430     Stat=Stat+1        !bit 0
12440   CASE "TRIG","TRIGGERED","TRG"
12450     Stat=Stat+2        !bit 1
12460   CASE "OOOS","OOOZ"
12470     Stat=Stat+4        !bit 2
12480   CASE "ARMRDY","READY FOR ARM"
12490     Stat=Stat+8        !bit 3
12500   CASE "RDY","READY"
12510     Stat=Stat+16       !bit 4
12520   CASE "ERR","ERROR"
12530     Stat=Stat+32       !bit 5
12540   CASE "BIT6"
12550     Stat=Stat+64       !bit 6
12560   CASE "OVLD","OVERLOAD"
12570     Stat=Stat+128      !bit 7
12580   CASE "RQS","SRQ"
12590     Stat=Stat+256      !bit 8
12600   CASE "INTR","INT","INTERRUPT"
12610     Stat=Stat+512      !bit 9
12620   CASE "SHT","SHUT","SHUTDOWN"
12630     Stat=Stat+1024     !bit 10
12640   CASE "MSHT","MODULE SHUTDOWN"
12650     Stat=Stat+2048     !bit 11
12660   CASE "FSFAST","FS TOO FAST"
12670     Stat=Stat+4096     !bit 12
12680   CASE "BIT13"
12690     Stat=Stat+8192     !bit 13
12700   CASE "PON","POWER ON"
12710     Stat=Stat+16384    !bit 14
12720   CASE ELSE
12730     User_error("*** Couldn't recognize "&Bit$&" in FNSrce_str_2_stat***")
12740   END SELECT
12750   RETURN 
12760 FNEND