10! OUTPUT 2 USING "#,K";"<lf>REN<cr>INDENT<cr><lf>RE-STORE ""PLOT""<cr>" 20 ! 30 ! EDIT Test_prog 40 ! EDIT Plot_plot 50 ! EDIT Plot_good_csize 60 ! EDIT Plot_set_viewp 70 ! EDIT Plot_do_axes 80 ! EDIT Plot_do_data 90 ! EDIT Plot_grid 100! EDIT Plot_x_pixel 110! EDIT Plot_y_pixel 120! EDIT Plot_background 130! EDIT Plot_do_mkr 140! EDIT Plot_move_mkr 150! EDIT Plot_have_color 160! EDIT Plot_set_color 170! EDIT Plot_eng_format 180! EDIT Plot_bold_label 190! EDIT Plot_make_x 200! EDIT Plot_make_y 210! 220 ! 230 Plot_doc: ! 19-Jun-86 240 ! ****************************************************************** 250 ! PLOT (Plot_) MODULE DESCRIPTION 260 ! Subprograms in the PLOT file are called by DISP subprograms 270 ! to do graphics. PLOT subprograms interface between the DISP subprograms 280 ! and the graphics commands, and hide some of the hardware dependencies. 290 ! 300 !------------------------------------------------------------------ 310 ! 320 ! ****************************************************************** 330 Test_prog: !--------------------------------------------------------- 340 ! LOADSUB ALL FROM "USER" 350 ! 360 ! <PLACE TEST CODE HERE> 370 CALL Plot_plot 380 CSIZE FNPlot_good_csize 390 DISP "filling data_buffer" 400 Rl=1024 410 Num_bins=Rl 420 ALLOCATE Data_buffer(1:20,0:Rl-1),Data_header(1:20,1:10) 430 DIM Plot_array(0:4095,1:2) 440 FOR B=1 TO 4 450 Data_header(B,1)=0 !offset 460 Data_header(B,2)=1 !scale factor 470 Data_header(B,3)=1 !overload 480 Data_header(B,4)=2 !log 490 Data_header(B,5)=100 !log of zero 500 Data_header(B,6)=100 !average 510 NEXT B 520 FOR I=0 TO Rl-5 530 Data_buffer(1,I)=.0011+I/Rl 540 FOR B=2 TO 4 550 Data_buffer(B,I)=Data_buffer(1,I) 560 NEXT B 570 NEXT I 580 DISP "PLOTTING" 590 ! 600 Plot_title$="title" 610 X_units$="Sec" 620 Y_units$="dBpC" 630 X_min=128 640 X_max=51200 650 Y_min=.001 660 Y_max=1 670 Start_bin=0 680 Do_log_x=0 690 Do_log_y=1 700 FOR Num_plots=1 TO 14 STEP 2 710 GCLEAR 720 CLIP ON 730 FOR Plot_num=1 TO 1 740 DISP "num_plots, plot_num ";Num_plots,Plot_num 750 ! 760 CALL Plot_set_viewp(Num_plots,(Plot_num),X_label_length,5,0) 770 CALL Plot_do_axes(Plot_title$,X_units$,Y_units$,X_min,X_max,Y_min,Y_max,X_label_length) 780 CALL Plot_set_viewp(Num_plots,(Plot_num),X_label_length,5,1) 790 Average=Data_header(Plot_num,6) 800 Overload=Data_header(Plot_num,3) 810 REDIM Plot_array(Start_bin:Start_bin+Num_bins-1,1:2) 820 CALL Plot_make_y(Data_buffer(*),Data_header(*),Plot_array(*),Plot_num,Start_bin,Start_bin+Num_bins-1,Do_log_y,Offset,Scale_factor) 830 CALL Plot_make_x(Plot_array(*),Do_log_x,X_min,X_max) 840 CALL Plot_background 850 CALL Plot_grid(X_min,X_max,Y_min,Y_max,Do_log_x,Do_log_y) 860 CALL Plot_do_data(Plot_array(*),Overload,"HI",Y_min,Y_max,Offset,Scale_factor,Do_log_y) 870 IF 1 THEN 880 REPEAT 890 CALL Plot_do_mkr(Plot_array(*),X_units$,Y_units$,X_min,X_max,Y_min,Y_max,Offset,Scale_factor,Do_log_y) 900 CALL Plot_move_mkr(Plot_array(*),X_units$,X_min,X_max) 910 UNTIL 0 920 END IF 930 NEXT Plot_num 940 PAUSE 950 WAIT .5 960 NEXT Num_plots 970 END 980 ! PAGE -> 990 !************************************************************************ 1000 Plot_plot:SUB Plot_plot 1010 !This subprogram declares and initializes common blocks used by subprograms in the PLOT file. 1020 !Plot_ common variables are used only by other Plot_ subprograms. 1030 !The graphics display is initialized and all pen colors are defined. 1040 !------------------------------------------------------------------------ 1050 COM /Plot_config/ X_pixels,Y_pixels,Have_color,Use_color 1060 COM /Plot_viewp/ Left,Right,Top,Bottom !last viewport command 1070 COM /Plot_mkr/ INTEGER Mkr_bin 1080 Mkr_bin=-1 1090 INTEGER A(0:5) 1100 GINIT 1110 ON ERROR GOTO No_color 1120 PLOTTER IS CRT,"INTERNAL";COLOR MAP 1130 Have_color=1 1140 Use_color=1 1150 OFF ERROR 1160 !set up color map so compliment shows up 1170 GESCAPE CRT,1;A(*) 1180 Num_colors=A(0) 1190 ! 1200 !All colors are defined here. In order for the marker 1210 !cursor to be visible, the compliment of the pen number must 1220 !be a pen number whose color is visible. White seems to work 1230 !for most. 1240 SET PEN 1 INTENSITY 1,1,1 !labels etc 1250 SET PEN Num_colors-1-1 INTENSITY 0,0,0 !compliment of 1 for marker locator 1260 SET PEN 2 INTENSITY 1,0,0 !red 1270 SET PEN 5 INTENSITY 0,1,1 !cyan for traces 1280 SET PEN Num_colors-5-1 INTENSITY 1,1,1 !compliment of 5 1290 SET PEN 6 INTENSITY 1,.4,.2 !brick red grid 1300 SET PEN Num_colors-6-1 INTENSITY 1,1,1 !compliment of 6 1310 SET PEN 7 INTENSITY .3,.3,.3 ! for background 1320 SET PEN Num_colors-7-1 INTENSITY 1,1,1 !compliment of 7 1330 ! 1340 IF POS(SYSTEM$("CRT ID"),"CGB") THEN !bit mapped 1350 CONTROL CRT,15;1 !white disp 1360 CONTROL CRT,16;5 !cyan softkeys 1370 ELSE 1380 CONTROL CRT,15;136 !white disp 1390 CONTROL CRT,16;140 !cyan softkeys 1400 END IF 1410 GOTO Get_config 1420 No_color:OFF ERROR 1430 PLOTTER IS CRT,"INTERNAL" 1440 Have_color=0 1450 Use_color=0 1460 Get_config:! 1470 GESCAPE CRT,3;A(*) !gets CRT pixel size in A(*) 1480 X_pixels=A(2) 1490 Y_pixels=A(3) 1500 SUBEND 1510 !************************************************************************ 1520 Plot_good_csize:DEF FNPlot_good_csize 1530 !This function returns minimum CSIZE for no character distortion. 1540 COM /Plot_config/ X_pixels,Y_pixels,Have_color,Use_color 1550 RETURN 100*15/Y_pixels !15 pix/char.cell, Y pix, 100 gdus 1560 FNEND 1570 ! PAGE -> 1580 !************************************************************************ 1590 Plot_set_viewp:SUB Plot_set_viewp(Num_plots,Plot_num,X_label_length,Y_label_length,Pixels_in) 1600 !This subprogram is called prior to plotting to setup viewport for next 1610 !plot. 1620 !INPUTS: Num_plots: 1..16 Total number of plots to be done. 1630 ! Plot_num: 1..Num_plots Current plot number 1640 ! Y_label_length 1..12 Number of characters to leave room for 1650 ! at the left of the viewport 1660 ! Pixels_in: The number of pixels to shrink the viewport by. 1670 ! Used to avoid drawing on the frame. 1680 !OUTPUTS: X_label_length Number of characters that there is room for 1690 ! in the title and along the x axis 1700 !------------------------------------------------------------------------ 1710 COM /Plot_config/ X_pixels,Y_pixels,Have_color,Use_color 1720 COM /Plot_viewp/ Left,Right,Top,Bottom 1730 Num_plots=MAX(1,MIN(16,Num_plots)) 1740 Plot_num=MAX(1,MIN(Num_plots,Plot_num)) 1750 Y_label_length=MAX(0,MIN(12,Y_label_length)) 1760 STATUS CRT,13;Crt_height 1770 Y_offset=100*(6.5/Crt_height) !start plots above DISP line (line 6) 1780 Y_offset=MIN(Y_offset,24) ! 1790 Y_plots=PROUND(SQR(Num_plots)+.49999,0) 1800 X_plots=INT(Num_plots/Y_plots+.9999) 1810 X=(Plot_num-1) MOD X_plots 1820 Y=(Plot_num-1) DIV X_plots 1830 Y=Y_plots-Y-1 !to plot top first 1840 X_size=100*RATIO/X_plots 1850 Y_size=(100-Y_offset)/Y_plots 1860 Left=X*X_size+Y_label_length*.6*FNPlot_good_csize 1870 IF Plot_num<>Num_plots THEN !not last plot 1880 Right=(X+1)*X_size 1890 ELSE !force last plot to use remainder of screen 1900 Right=X_plots*X_size 1910 END IF 1920 Bottom=Y_offset+Y*Y_size+FNPlot_good_csize !+ 1 char 1930 Top=Y_offset+(Y+1)*Y_size-FNPlot_good_csize 1940 IF Pixels_in<>0 THEN 1950 Left=Left+Pixels_in*100*RATIO/X_pixels 1960 Right=Right-Pixels_in*100*RATIO/X_pixels 1970 Bottom=Bottom+Pixels_in*100/Y_pixels 1980 Top=Top-Pixels_in*100/Y_pixels 1990 END IF 2000 VIEWPORT Left,Right,Bottom,Top 2010 X_label_length=INT((Right-Left)/(.6*FNPlot_good_csize)+.1) 2020 SUBEND 2030 ! PAGE -> 2040 !************************************************************************ 2050 Plot_do_axes:SUB Plot_do_axes(Plot_title$,X_units$,Y_units$,X_min,X_max,Y_min,Y_max,X_label_length) 2060 !This subprogram labels the axis of one plot. 2070 !INPUTS: Plot_title$, X_units$, Y_units$: strings 2080 ! X_min,X_max,Y_min,Y_max: plot boundaries in real-world units. 2090 ! X_label_length: The number of characters that will fit along 2100 ! the X axis. 2110 !------------------------------------------------------------------------ 2120 DIM Min$[18],Max$[18],Prefix$[1] 2130 Left=1 2140 Right=2 2150 Bottom=3 2160 Top=4 2170 GRAPHICS ON 2180 PEN 1 2190 LINE TYPE 1 2200 WINDOW Left,Right,Bottom,Top 2210 FRAME 2220 CLIP OFF 2230 LDIR 0 2240 GOSUB Plot_title 2250 IF X_units$<>"" THEN GOSUB Plot_x 2260 IF Y_units$<>"" THEN GOSUB Plot_y 2270 SUBEXIT 2280 Plot_title: !------------------------------------------------------ 2290 LORG 1 2300 MOVE Left,Top 2310 IF LEN(Plot_title$)>X_label_length THEN 2320 LABEL Plot_title$[1,X_label_length] 2330 ELSE 2340 LABEL Plot_title$ 2350 END IF 2360 RETURN 2370 Plot_x: !-------------------------------------------------------- 2380 IF (X_min=0) OR (X_max=0) THEN 2390 Digits=3 2400 ELSE 2410 Digits=LGT(ABS(X_min/(X_max-X_min)))+1 !min num of sig digits 2420 Digits=MAX(3,MIN(7,Digits)) 2430 END IF 2440 CALL Plot_eng_format(X_min,X_max,Min$,Max$,Digits,Prefix$) 2450 Length=X_label_length 2460 IF Min$<>"0" THEN Min$=Min$&Prefix$ 2470 IF Max$<>"0" THEN Max$=Max$&Prefix$ 2480 !start labeling, keeping track of how much room is left 2490 IF Length>=LEN(Min$) THEN !if there is room for left label 2500 LORG 3 2510 MOVE Left,Bottom 2520 LABEL Min$ 2530 Length=Length-LEN(Min$) 2540 END IF 2550 IF Length>LEN(Max$) THEN 2560 LORG 9 2570 MOVE Right,Bottom 2580 LABEL Max$ 2590 Length=Length-LEN(Max$) 2600 END IF 2610 IF (X_label_length-2*MAX(LEN(Min$),LEN(Max$)))>LEN(X_units$) THEN !if room in center 2620 LORG 6 2630 MOVE (Left+Right)/2,Bottom 2640 LABEL X_units$ 2650 END IF 2660 RETURN 2670 Plot_y: !-------------------------------------------------------- 2680 CALL Plot_eng_format(Y_min,Y_max,Min$,Max$,3,Prefix$) 2690 IF Min$<>"0" THEN Min$=Min$&Prefix$ 2700 IF Max$<>"0" THEN Max$=Max$&Prefix$ 2710 LORG 7 2720 MOVE Left,Bottom 2730 IF Min$<>Max$ THEN LABEL Min$ 2740 LORG 9 2750 MOVE Left,Top 2760 LABEL Max$ 2770 LORG 8 2780 MOVE Left,(Top+Bottom)/2 2790 LABEL Y_units$ 2800 RETURN 2810 SUBEND 2820 ! PAGE -> 2830 !************************************************************************ 2840 Plot_do_data:SUB Plot_do_data(Plot_array(*),Overload,Message$,Y_min,Y_max,Offset,Scale_factor,Do_log_y) 2850 !This subprogram draws the data for one plot. To save time, the data can 2860 !be "scaled" by Offset and Scale_factor using the WINDOW command. 2870 !INPUTS: Plot_array(*): Array of XY pairs ready for a PLOT command. 2880 ! Plot_array(*,1) = X = bin numbers. Plot_array(*,2) 2890 ! = Y = un-scaled Y data. 2900 ! Overload, Message$: Used to annotate the plot. 2910 ! Y_min,Y_max: Plot boundary values in real world units. 2920 ! Offset, Scale_factor: scaling for Y values. 2930 ! Do_log_y: Flag, non-zero if y axis is logarithmic. 2940 !----------------------------------------------------------------------- 2950 INTEGER Start_bin,Stop_bin 2960 GRAPHICS ON 2970 LINE TYPE 1 2980 CLIP ON 2990 Start_bin=BASE(Plot_array,1) 3000 Stop_bin=BASE(Plot_array,1)+SIZE(Plot_array,1)-1 3010 IF Scale_factor=0 THEN 3020 CALL User_error("ERROR: Data_header scale factor is zero. (Plot_do_data)") 3030 Scale_factor=1 3040 END IF 3050 WINDOW 0,1,0,1 3060 LORG 9 3070 MOVE 1,1 3080 PEN 1 3090 IF Message$<>"" THEN LABEL Message$&" " 3100 IF Overload THEN 3110 IF FNPlot_use_color THEN PEN 3 3120 LABEL "OVLD " 3130 END IF 3140 IF FNPlot_use_color THEN PEN 5 3150 MOVE 0,0 !to avoid error 19 if next window is 1E-7 (BASIC bug?) 3160 !note that the window is used to scale the data 3170 IF Do_log_y THEN 3180 WINDOW Start_bin,Stop_bin,LGT(Y_min)*Scale_factor+Offset,LGT(Y_max)*Scale_factor+Offset 3190 ELSE 3200 WINDOW Start_bin,Stop_bin,Y_min*Scale_factor+Offset,Y_max*Scale_factor+Offset 3210 END IF 3220 ON ERROR GOTO Plot_error 3230 MOVE Plot_array(Start_bin,1),Plot_array(Start_bin,2) 3240 PLOT Plot_array(*) 3250 MOVE 0,0 3260 Plot_error:OFF ERROR 3270 SUBEND 3280 ! PAGE -> 3290 !************************************************************************ 3300 Plot_grid:SUB Plot_grid(X_min,X_max,Y_min,Y_max,Do_log_x,Do_log_y) 3310 !This subprogram draws linear or log grids. If linear, puts up between 4 3320 !and 10 grid lines spaced at 1, 2, or 5 units. If log, puts up solid 3330 !lines at 1 and 1 dotted line at 5 or 4 dotted lines at 2, 4, 6, 8. 3340 IF FNPlot_use_color THEN PEN 6 3350 CLIP ON 3360 X_pwr=PROUND(LGT(X_max-X_min)-.51,0) 3370 Y_pwr=PROUND(LGT(Y_max-Y_min)-.51,0) 3380 X_tic=10^X_pwr !gives 1 to 10 tics every 1 or 10 or 100 ... 3390 Y_tic=10^Y_pwr 3400 SELECT (X_max-X_min)/X_tic !number of tics 3410 CASE 2 TO 3.9 3420 X_tic=X_tic/2 !tic spacing of 5 3430 CASE <2 3440 X_tic=X_tic/5 !tic spacing of 2 3450 END SELECT 3460 SELECT (Y_max-Y_min)/Y_tic !number of tics 3470 CASE 2 TO 3.9 3480 Y_tic=Y_tic/2 !tic spacing of 5 3490 CASE <2 3500 Y_tic=Y_tic/5 !tic spacing of 2 3510 END SELECT 3520 IF NOT (Do_log_x OR Do_log_y) THEN !linear, linear 3530 WINDOW X_min,X_max,Y_min,Y_max 3540 LINE TYPE 4 3550 GRID X_tic,Y_tic,PROUND(X_min,X_pwr),PROUND(Y_min,Y_pwr) 3560 ELSE !at least one is log 3570 IF Do_log_x THEN 3580 WINDOW LGT(X_min),LGT(X_max),0,1 3590 LINE TYPE 1 3600 GRID 1,3,LGT(1),-1 !X grid at 1, no Y 3610 LINE TYPE 4 3620 IF 1/(FNPlot_x_pixel*LGT(X_max/X_min))>40 THEN !if enought pixels/decade 3630 GRID 1,3,LGT(2),-1 3640 GRID 1,3,LGT(4),-1 3650 GRID 1,3,LGT(6),-1 3660 GRID 1,3,LGT(8),-1 3670 ELSE !not enough pixels/decade 3680 GRID 1,3,LGT(5),-1 3690 END IF 3700 ELSE 3710 WINDOW X_min,X_max,0,1 3720 LINE TYPE 4 3730 GRID X_tic,3,PROUND(X_min,X_pwr),-1 3740 END IF 3750 IF Do_log_y THEN 3760 WINDOW 0,1,LGT(Y_min),LGT(Y_max) 3770 LINE TYPE 1 3780 GRID 3,1,-1,LGT(1) !y grid at 1, no x 3790 LINE TYPE 4 3800 IF 1/(FNPlot_y_pixel*LGT(Y_max/Y_min))>40 THEN !if enought pixels/decade 3810 GRID 3,1,-1,LGT(2) 3820 GRID 3,1,-1,LGT(4) 3830 GRID 3,1,-1,LGT(6) 3840 GRID 3,1,-1,LGT(8) 3850 ELSE !not enough pixels/decade 3860 GRID 3,1,-1,LGT(5) 3870 END IF 3880 ELSE 3890 WINDOW 0,1,Y_min,Y_max 3900 LINE TYPE 4 3910 GRID 3,Y_tic,-1,PROUND(Y_min,Y_pwr) 3920 END IF 3930 END IF 3940 LINE TYPE 1 3950 SUBEND 3960 !***************************************************************** 3970 Plot_x_pixel:DEF FNPlot_x_pixel 3980 !This function returns the horizontal size of one pixel as a ratio of the 3990 !current window size. 1/FNPlot_x_pixel is the number of X pixels in 4000 !the current viewport. 4010 COM /Plot_config/ X_pixels,Y_pixels,Have_color,Use_color 4020 COM /Plot_viewp/ Left,Right,Top,Bottom !last viewport command 4030 IF Left+Right=0 THEN CALL User_stop("PROGRAM ERROR: Plot_set_veiwp not called before FNPlot_x_pixel") 4040 RETURN 1/(X_pixels*.01*(Right-Left)/RATIO) 4050 FNEND 4060 !***************************************************************** 4070 Plot_y_pixel:DEF FNPlot_y_pixel 4080 !This function returns the vertical size of one pixel as a ratio of the 4090 !current window size. 1/FNPlot_y_pixel is the number of y pixels in 4100 !the current viewport. 4110 COM /Plot_config/ X_pixels,Y_pixels,Have_color,Use_color 4120 COM /Plot_viewp/ Left,Right,Top,Bottom !last viewport command 4130 IF Left+Right=0 THEN CALL User_stop("PROGRAM ERROR: Plot_set_veiwp not called before FNPlot_y_pixel") 4140 RETURN 1/(Y_pixels*.01*(Top-Bottom)) 4150 FNEND 4160 !***************************************************************** 4170 Plot_background:SUB Plot_background 4180 !This subprogram erases the current viewport by drawing a rectangle using 4190 !background color. 4200 WINDOW 0,1,0,1 4210 MOVE 0,0 4220 IF FNPlot_use_color THEN 4230 AREA PEN 7 !background color set in Plot_plot 4240 ELSE 4250 AREA PEN -1 !erase 4260 END IF 4270 RECTANGLE 1,1,FILL 4280 AREA PEN 1 4290 SUBEND 4300 ! PAGE -> 4310 !***************************************************************** 4320 Plot_do_mkr:SUB Plot_do_mkr(Plot_array(*),X_units$,Y_units$,X_min,X_max,Y_min1,Y_max1,Offset,Scale_factor,Do_log_y) 4330 !This subprogram operates the marker on one trace. Pass parameters are 4340 !similar to Plot_do_data. 4350 COM /Plot_mkr/ INTEGER Mkr_bin !for memory between calls 4360 INTEGER Start_bin,Stop_bin,Last_marker 4370 DIM D_line$[80] 4380 GRAPHICS INPUT IS KBD,"KBD" !use keyborad arrows to move marker 4390 LINE TYPE 1 4400 CLIP ON 4410 Start_bin=BASE(Plot_array,1) 4420 Stop_bin=BASE(Plot_array,1)+SIZE(Plot_array,1)-1 4430 Per_bin_x=(X_max-X_min)/(Stop_bin-Start_bin) 4440 IF Mkr_bin=-1 THEN Mkr_bin=(Stop_bin+Start_bin)/2 !un initialized 4450 Mkr_bin=MAX(Start_bin,MIN(Stop_bin,Mkr_bin)) 4460 IF Scale_factor=0 THEN 4470 CALL User_error("ERROR: Data_header scale factor is zero (Plot_do_mkr)") 4480 Scale_factor=1 4490 END IF 4500 IF Do_log_y THEN 4510 Y_min=LGT(Y_min1) 4520 Y_max=LGT(Y_max1) 4530 ELSE 4540 Y_min=Y_min1 4550 Y_max=Y_max1 4560 END IF 4570 MOVE 0,0 !to avoid error 19 if next window is 1E-7 (BASIC bug) 4580 WINDOW Start_bin,Stop_bin,Y_min,Y_max 4590 CLIP ON 4600 ! Marker_gain is a fudge factor that allows the marker to hit each bin 4610 ! The min locator change is 1 pixel. Marker_gain maps one pixel into 4620 ! one bin. 4630 Marker_gain=1/(SIZE(Plot_array,1)*FNPlot_x_pixel) 4640 Y=(Plot_array(Mkr_bin,2)-Offset)/Scale_factor 4650 SET LOCATOR Mkr_bin,MAX(Y_min,MIN(Y_max,Y)) 4660 SET ECHO Plot_array(Mkr_bin,1),MAX(Y_min,MIN(Y_max,Y)) 4670 GOSUB Disp_mkr 4680 REPEAT 4690 DISABLE 4700 READ LOCATOR Locator_x,Dummy 4710 Mkr_bin=MAX(Start_bin,MIN(Stop_bin,Mkr_bin+(Locator_x-Mkr_bin)*Marker_gain)) 4720 Y=(Plot_array(Mkr_bin,2)-Offset)/Scale_factor 4730 SET LOCATOR Mkr_bin,MAX(Y_min,MIN(Y_max,Y)) 4740 IF Mkr_bin=Last_marker THEN !not moving 4750 GOSUB Disp_mkr 4760 ELSE 4770 SET ECHO Plot_array(Mkr_bin,1),MAX(Y_min,MIN(Y_max,Y)) 4780 END IF 4790 Last_marker=Mkr_bin 4800 ENABLE 4810 UNTIL FNUser_key_press 4820 DISP 4830 IF FNUser_check_key>3 THEN SET ECHO Start_bin-10.0*(Stop_bin-Start_bin),Y_min 4840 !move the marker off of the screen unless the "Move marker" softkey 4850 SUBEXIT 4860 Disp_mkr: !------------------------------------------------ 4870 !Given marker_bin and Y, displays marker value 4880 IF Do_log_y THEN !Plot_data has been logged, need to un-log 4890 CALL Plot_eng_format(10^Y,0,Y$,"",8,Y_prefix$) 4900 ELSE 4910 IF POS(UPC$(Y_units$),"DB") THEN !special case for dB 4920 Y$="" 4930 OUTPUT Y$ USING "#,DDDD.DDD";Y 4940 ELSE 4950 CALL Plot_eng_format(Y,0,Y$,"",8,Y_prefix$) 4960 END IF 4970 END IF 4980 X=X_min+(Mkr_bin-Start_bin)*(Per_bin_x) 4990 CALL Plot_eng_format(X,0,X$,"",8,X_prefix$) 5000 D_line$=X$&X_prefix$&" "&X_units$ 5010 D_line$=D_line$&RPT$(" ",20-LEN(D_line$)) 5020 D_line$=D_line$&Y$&Y_prefix$&" "&Y_units$ 5030 DISP D_line$ 5040 RETURN 5050 SUBEND 5060 ! PAGE -> 5070 !************************************************************************ 5080 Plot_move_mkr:SUB Plot_move_mkr(Plot_array(*),X_units$,X_min,X_max,To$) 5090 ! This subprogram is called from the marker menu when a "Marker to ?" 5100 ! soft key is pressed. 5110 ! It's output is a side effect: It may modify the current marker 5120 ! bin number stored in common. 5130 !--------------------------------------------------------------------- 5140 COM /Plot_mkr/ INTEGER Mkr_bin !for memory between calls 5150 DIM New_entry$[100] 5160 INTEGER X,Start_bin,Stop_bin 5170 Start_bin=BASE(Plot_array,1) 5180 Stop_bin=BASE(Plot_array,1)+SIZE(Plot_array,1)-1 5190 Per_bin_x=(X_max-X_min)/(Stop_bin-Start_bin) 5200 SELECT To$ 5210 CASE "MIN" 5220 GOSUB To_min 5230 CASE "MAX" 5240 GOSUB To_max 5250 CASE ELSE 5260 GOSUB To_x 5270 END SELECT 5280 SUBEXIT 5290 To_x: !----------------------------------------------------------- 5300 IF X_units$<>"" THEN 5310 DISP "Move marker: X axis value in ";X_units$; 5320 ELSE 5330 DISP "Move marker: X axis value "; 5340 END IF 5350 LINPUT New_entry$ 5360 DISP 5370 IF LEN(New_entry$)>0 THEN 5380 ON ERROR GOTO Nevermind 5390 Mkr_bin=MIN(Stop_bin,(VAL(New_entry$)-X_min)/Per_bin_x+Start_bin) 5400 Nevermind:OFF ERROR 5410 END IF 5420 RETURN 5430 To_min: !------------------------------------------------------- 5440 FOR X=Start_bin TO Stop_bin 5450 IF Plot_array(X,2)<Plot_array(Mkr_bin,2) THEN 5460 Mkr_bin=X 5470 END IF 5480 NEXT X 5490 RETURN 5500 To_max: !------------------------------------------------------- 5510 FOR X=Start_bin TO Stop_bin 5520 IF Plot_array(X,2)>Plot_array(Mkr_bin,2) THEN 5530 Mkr_bin=X 5540 END IF 5550 NEXT X 5560 RETURN 5570 SUBEND 5580 ! PAGE -> 5590 !************************************************************************ 5600 DEF FNPlot_have_color 5610 !This function returns 1 if color is available 5620 COM /Plot_config/ X_pixels,Y_pixels,Have_color,Use_color 5630 RETURN Have_color 5640 FNEND 5650 SUB Plot_set_color(Use_color) 5660 !This subprogram turn on and off color by setting a flag in common. 5670 COM /Plot_config/ X_pixels,Y_pixels,Have_color,Use_color_c 5680 IF (Use_color<>0) AND FNPlot_have_color THEN 5690 Use_color_c=1 5700 ELSE 5710 Use_color_c=0 5720 END IF 5730 SUBEND 5740 DEF FNPlot_use_color 5750 !This function returns 1 if color is turned on. 5760 COM /Plot_config/ X_pixels,Y_pixels,Have_color,Use_color 5770 RETURN Use_color 5780 FNEND 5790 ! PAGE -> 5800 !************************************************************************ 5810 Plot_eng_format:SUB Plot_eng_format(Value1,Value2,V1$,V2$,Digits,Prefix$) 5820 !This subprogram converts 2 values to engineering format. 5830 !To use it with only one value, set the other to zero 5840 !INPUTS: Value1, Value2: values in fundamental units (Hz). 5850 ! Digits: Number of digits to round to. 5860 !OUTPUTS: V1$, V2$: Strings returning the rounded output. 5870 ! Prefix$: Engineering format prefix for units. 5880 !------------------------------------------------------------------------ 5890 Max_value=DROUND(MAX(ABS(Value1),ABS(Value2)),Digits) 5900 IF Max_value>10^(-15) THEN !check for log of zero 5910 SELECT LGT(Max_value) 5920 CASE >=6 5930 Exponent=6 5940 Prefix$="M" 5950 CASE 3 TO 6 5960 Exponent=3 5970 Prefix$="K" 5980 CASE 0 TO 3 5990 Exponent=0 6000 Prefix$="" 6010 CASE -3 TO 0 6020 Exponent=-3 6030 Prefix$="m" 6040 CASE -6 TO -3 6050 Exponent=-6 6060 Prefix$="u" 6070 CASE -9 TO -6 6080 Exponent=-9 6090 Prefix$="n" 6100 CASE <-9 6110 Exponent=-12 6120 Prefix$="p" 6130 END SELECT 6140 ELSE 6150 Exponent=0 6160 Prefix$="" 6170 END IF 6180 V1$=VAL$(DROUND(Value1/10^Exponent,Digits)) 6190 V2$=VAL$(DROUND(Value2/10^Exponent,Digits)) 6200 SUBEND 6210 ! PAGE -> 6220 !************************************************************************ 6230 Plot_bold_label:SUB Plot_bold_label(Char_size,L$) 6240 !This subprogram plots a bold label with CSIZE Char_size. 6250 INTEGER N,Max_n 6260 WHERE X,Y 6270 CSIZE Char_size 6280 Max_n=(Char_size/FNPlot_good_csize)-1 6290 X_step=FNPlot_x_pixel*.999 6300 Y_step=FNPlot_y_pixel*.999 6310 FOR N=0 TO Max_n 6320 MOVE X+Max_n*X_step,Y+N*Y_step 6330 LABEL L$ 6340 NEXT N 6350 FOR N=0 TO Max_n 6360 MOVE X+N*X_step,Y 6370 LABEL L$ 6380 NEXT N 6390 FOR N=0 TO Max_n 6400 MOVE X+N*X_step,Y+Max_n*Y_step 6410 LABEL L$ 6420 NEXT N 6430 FOR N=Max_n TO 0 STEP -1 !want to do X+0,Y+0 last for pen position 6440 MOVE X,Y+N*Y_step 6450 LABEL L$ 6460 NEXT N 6470 SUBEND 6480 ! PAGE -> 6490 !************************************************************************ 6500 Plot_make_x:SUB Plot_make_x(Plot_array(*),Do_log_x,X_min,X_max) 6510 !This subprogram fills the X elements of Plot_array(*) for the PLOT 6520 !command. If the x axis is to be LOGed, it is done here. 6530 ! 6540 !INPUTS: Do_log_x: Flag 0: linear x axis, <>0 : log x axis 6550 ! X_min,X_max: X axis bounds in real world units. 6560 !OUTPUTS: Plot_array(*): 2D array of xy points ready for PLOT command. 6570 ! Plot_array(*,1) = x = bin numbers for linear plots, 6580 ! "distorted" bin numbers for log plots. 6590 ! Plot_array(*,2) = y = y values. not changed. 6600 ! 6610 !----------------------------------------------------------------- 6620 INTEGER Bin,Start_bin,Stop_bin 6630 Start_bin=BASE(Plot_array,1) 6640 Stop_bin=SIZE(Plot_array,1)+Start_bin-1 6650 IF Do_log_x THEN ! x axis is logged 6660 GOSUB Do_log 6670 ELSE 6680 GOSUB Do_lin 6690 END IF 6700 SUBEXIT 6710 Do_lin: !-------------------------------------------------------- 6720 !re- compute only if necessary 6730 IF (Plot_array(Start_bin+1,1)<>Start_bin+1) OR (Plot_array(Stop_bin,1)<>Stop_bin) THEN 6740 FOR Bin=Start_bin TO Stop_bin 6750 Plot_array(Bin,1)=Bin 6760 NEXT Bin 6770 END IF 6780 RETURN 6790 Do_log: !-------------------------------------------------------- 6800 !The x-axis log works like this: 6810 !The X elements of Plot_array(*) that are usually bin numbers for 6820 !linear plots are "distorted" into log sequence. The distortion 6830 !is such that the first and last bins are not changed. In other 6840 !words Plot_array(Start_bin,1)=Start_bin and 6850 !Plot_array(Stop_bin,1)=Stop_bin, but everything between will 6860 !be different. The formula for the distortion is 6870 ! Plot_array(Bin,1) = A*LGT(Freq) + B 6880 !where A and B are figured below, and Freq is real world X value 6890 !of the Bin. 6900 ! 6910 A=(Stop_bin-Start_bin)/LGT(X_max/X_min) 6920 B=Start_bin-A*LGT(X_min) 6930 Per_bin_x=(X_max-X_min)/(Stop_bin-Start_bin) 6940 ! 6950 !Comput new values only if old values are incorrect. 6960 IF ABS(Plot_array(Start_bin+1,1)-(A*LGT(X_min+Per_bin_x)+B))>1.E-4 OR (Plot_array(Stop_bin,1)<>Stop_bin) THEN 6970 FOR Bin=Start_bin TO Stop_bin-1 6980 Plot_array(Bin,1)=A*LGT(X_min+(Bin-Start_bin)*Per_bin_x)+B 6990 NEXT Bin 7000 Plot_array(Stop_bin,1)=Stop_bin 7010 END IF 7020 RETURN 7030 SUBEND 7040 ! PAGE -> 7050 !************************************************************************ 7060 Plot_make_y:SUB Plot_make_y(Data_buffer(*),Data_header(*),Plot_array(*),Buf_num,Start_bin,Stop_bin_r,Do_log,Offset,Scale_factor) 7070 !This subprogram converts Data_buffer(*) into Plot_array(*) for the PLOT 7080 !command. If the data is to be LOGed, it is done here. 7090 !There is a CSUB version that does the same operation much quicker. 7100 !The CSUB should be above this, so the CSUB will be used. 7110 ! 7120 !INPUTS: Data_buffer(*): 2D array of y data blocks. This sub only 7130 ! operates on one block, Data_buffer(Buf_num,*). 7140 ! Data_header(*): 2D array of header info for y data blocks. 7150 ! Buf_num: Which buffer of Data_buffer. 7160 ! Start_bin, Stop_bin: Data_buffer index range to plot. 7170 !OUTPUTS: Plot_array(*): 2D array of xy points ready for PLOT command. 7180 ! Plot_array(*,1) = x, not changed. 7190 ! Plot_array(*,2) = y = y values. 7200 ! Offset: Offset yet to be subtracted from y values. 7210 ! Scale_factor: Scale factor yet to be applied to y values. 7220 ! 7230 ! For maximum speed, this sub has a separate DO loop for each case. 7240 !----------------------------------------------------------------- 7250 INTEGER X,Stop_bin 7260 Stop_bin=Stop_bin_r 7270 Offset=Data_header(Buf_num,1) 7280 Scale_factor=Data_header(Buf_num,2) 7290 Log_multiplier=Data_header(Buf_num,4) 7300 IF Do_log THEN Log_multiplier=1 7310 IF Log_multiplier=0 THEN !linear 7320 FOR X=Start_bin TO Stop_bin 7330 Plot_array(X,2)=Data_buffer(Buf_num,X) 7340 NEXT X 7350 ELSE !do log 7360 ON ERROR GOTO No_zero 7370 Zero_value=LGT((Data_header(Buf_num,5)-Offset)/Scale_factor) 7380 No_zero:OFF ERROR 7390 IF Log_multiplier>0 THEN !positive log multiplier 7400 FOR X=Start_bin TO Stop_bin 7410 IF Data_buffer(Buf_num,X)>0 THEN 7420 Plot_array(X,2)=LGT((Data_buffer(Buf_num,X)-Offset)/Scale_factor) 7430 ELSE 7440 Plot_array(X,2)=Zero_value 7450 END IF 7460 NEXT X 7470 !zero offset since it has been applied, change scale factor 7480 Offset=0 7490 Scale_factor=1/Log_multiplier 7500 ELSE !negative log multiplier 7510 FOR X=Start_bin TO Stop_bin 7520 IF Data_buffer(Buf_num,X)>0 THEN 7530 Plot_array(X,2)=-LGT((Data_buffer(Buf_num,X)-Offset)/Scale_factor) 7540 ELSE 7550 Plot_array(X,2)=-Zero_value 7560 END IF 7570 NEXT X 7580 Offset=0 7590 Scale_factor=-1/Log_multiplier 7600 END IF !log multiplier sign 7610 END IF 7620 SUBEND 7630 ! PAGE -> 7640 !************************************************************************