10! OUTPUT 2 USING "#,K";"<lf>REN<cr>INDENT<cr>RE-STORE ""PLOT5_0""<cr>" 20 ! 30 ! This is a copy of the Pascal source code used to make the CSUB. 40 ! $SYSPROG ON$ 50 ! $STACKCHECK OFF$ 60 ! $IOCHECK OFF$ 70 ! $OVFLCHECK OFF$ 80 ! $RANGE OFF$ 90 ! $DEBUG OFF$ 100! $LINES 55$ 110! $PAGEWIDTH 80$ 120! 130! $FLOAT_HDW TEST$ 140! 150! MODULE PLOTCSUBS; 160! { 170! PARAGON: /USERS/SUTTON/RAMBO/CSUBS/PLOTCSUBS.TEXT 180! 14 MAY 86 190! 200! } 210! 220! $SEARCH '/SYSTEMS/BASIC4/CSUBS/CSUBDECL', 'MYBINASM'$ 230! IMPORT csubdecl, {for BASIC type defs like BINTVALTYPE} 240! mybinasm; {for binior, binand, set_bits } 250! 260! EXPORT 270! TYPE ar0_type = PACKED ARRAY[0..262143] OF REAL; 280! xy_point = RECORD xp,yp :REAL; END; 290! ar_plot_type = PACKED ARRAY[0..32767] OF xy_point; 300! header_record = RECORD h_offset,h_scale_factor,ovld,h_log_multiplier, 310! h_zero_value, d6, d7, d8, d9, d10 :REAL; END; 320! ar_header_type= PACKED ARRAY[1..1000] OF header_record; 330! 340! 350! PROCEDURE Plot_make_y( 360! data_buffer_dope: DIMENTRYPTR; VAR data_buffer: ar0_type; 370! data_header_dope: DIMENTRYPTR; VAR data_header: ar_header_type; 380! plot_array_dope: DIMENTRYPTR; VAR plot_array: ar_plot_type; 390! VAR buf_num, start_bin, stop_bin, Do_log_y, offset, scale_factor: REAL); 400! 410! IMPLEMENT 420! 430! CONST do_debug=false; 440! 450! 460! 470! PROCEDURE Plot_make_y( 480! data_buffer_dope: DIMENTRYPTR; VAR data_buffer: ar0_type; 490! data_header_dope: DIMENTRYPTR; VAR data_header: ar_header_type; 500! plot_array_dope: DIMENTRYPTR; VAR plot_array: ar_plot_type; 510! VAR buf_num, start_bin, stop_bin, do_log_y, offset, scale_factor: REAL); 520! 530! {This CSUB prepares data for plotting by filling a plot array that 540! can be plotted with one PLOT command in BASIC. It extracts one block 550! of data from Data_buffer() and puts it into Plot_array(). If needed, 560! it computes the log to the base 10 using a quick algorithm. 570! 580! Note: although data_buffer elements are REAL numbers in BASIC, this 590! procedure interprets them as INTEGERS and uses the exponent 600! and 4 bits of the mantissa to compute a quick but not real accurate 610! log. It runs about 10 times faster than a basic FOR loop with LGT 620! 630! For maximum speed, this code has seperate DO loops for several cases. 640! 650! This assumes the following floating point format (see BASIC 660! Programing techniques, Data Storage chapter): 670! word0 word1 word2 word3 680! or 690! lword0 lword1 700! where the bits in word0 are: 710! (mantissa sign), (exponent msb), ... (exp lsb),(mant msb), ..(mant fsb) 720! and fsb=fourth most sig bit 730! } 740! 750! TYPE log_table_type = ARRAY[0..1023] OF REAL; 760! real_record_type = RECORD 770! lword0, lword1 :INTEGER; 780! {msb ... lsb} 790! END; 800! 810! {special type to access real number as 2 integers to do 820! quick log using exponent and mantissa} 830! 840! CONST lgt_of_2 = 0.301029996; 850! ln_of_10 = 2.302585093; 860! two_to_the_20th = 1048576; 870! two_to_the_10th = 1024; 880! exp_mask = binary('0111111111110000'); {just do DIV 2^20} 890! mant_mask = binary('00000000000011111111111111111111'); 900! {log_table is a look up table to speed up the log function 910! the first (0ith) element is = LGT(1 + 0/1024), 920! the second is = LGT(1 + 1/1024), ...} 930! 940! log_table=log_table_type[ $INCLUDE 'LOG_TABLE.ASC'$ 950! ]; 960! 970! VAR 980! b_offset :INTEGER; {index offset for Data_buffer[]} 990! p_offset :BINTVALTYPE; {index offset for Plot_array[]} 1000! buf_num_i :BINTVALTYPE; {Which buffer of Data_buffer[]} 1010! x :BINTVALTYPE; {x axis value or bin number} 1020! x_stop :BINTVALTYPE; 1030! xpon :INTEGER; {exponent of floating point number} 1040! mant :INTEGER; {mantissa} 1050! y_r :REAL; {y axis value interpreted as a real number} 1060! y_i :^real_record_type; {y_r interpreted as 2 32 bit integers} 1070! zero_value :REAL; {for log of zero} 1080! log_multiplier :REAL; {one element of Data_header} 1090! 1100! BEGIN 1110! {get pointer to foil type checking} 1120! y_i := ADDR(y_r); 1130! 1140! buf_num_i:=ROUND(buf_num); 1150! 1160! {figure out b_offset, or what index of data_buffer to start at} 1170! b_offset := (buf_num_i - data_buffer_dope^.bound[1].low)* 1180! data_buffer_dope^.bound[2].length 1190! - data_buffer_dope^.bound[2].low; 1200! 1210! {figuer out p_offset, or where to find start_bin in plot_array} 1220! p_offset := - plot_array_dope^.bound[1].low; 1230! 1240! x_stop := ROUND(stop_bin); 1250! 1260! offset := data_header[buf_num_i].h_offset; 1270! scale_factor := data_header[buf_num_i].h_scale_factor; 1280! log_multiplier := data_header[buf_num_i].h_log_multiplier; 1290! IF do_log_y<>0 THEN log_multiplier:=1.0; 1300! 1310! IF log_multiplier =0 THEN BEGIN {linear ---} 1320! FOR x:=ROUND(start_bin) TO x_stop DO 1330! plot_array[x+p_offset].yp:=data_buffer[x+b_offset] 1340! ; 1350! {offset and scale factor are passed on to be done at plot window} 1360! END ELSE BEGIN {log ------} 1370! zero_value := data_header[buf_num_i].h_zero_value; 1380! zero_value := (zero_value-offset)/scale_factor; 1390! IF zero_value>1.0E-200 THEN zero_value:= LN(zero_value)/ln_of_10; 1400! 1410! IF log_multiplier>0 THEN BEGIN {+log ------} 1420! FOR x:=ROUND(start_bin) TO x_stop DO BEGIN 1430! y_r:= (data_buffer[x+b_offset]-offset)/scale_factor; 1440! IF y_r>1.0E-200 THEN BEGIN {IF >0 } 1450! xpon := (y_i^.lword0 DIV two_to_the_20th) -1023; 1460! mant := binand(mant_mask,y_i^.lword0) DIV two_to_the_10th; 1470! plot_array[x+p_offset].yp:=lgt_of_2*xpon + log_table[mant]; 1480! END ELSE { <=0 } 1490! plot_array[x+p_offset].yp:=zero_value; 1500! END; {FOR} 1510! offset:=0.0; 1520! scale_factor:=1/log_multiplier; 1530! END ELSE BEGIN {-log ------} 1540! FOR x:=ROUND(start_bin) TO x_stop DO BEGIN 1550! y_r:= (data_buffer[x+b_offset]-offset)/scale_factor; 1560! IF y_r>1.0E-200 THEN BEGIN {IF >0 } 1570! xpon := (y_i^.lword0 DIV two_to_the_20th) -1023; 1580! mant := binand(mant_mask,y_i^.lword0) DIV two_to_the_10th; 1590! plot_array[x+p_offset].yp:=-(lgt_of_2*xpon + log_table[mant]); 1600! END ELSE { <=0 } 1610! plot_array[x+p_offset].yp:=-zero_value; 1620! END; {FOR} 1630! offset:=0.0; 1640! scale_factor:=-1/log_multiplier; 1650! END; {IF log_multiplier>0} 1660! END; {IF linear ELSE log} 1670! END; {PROCEDURE Plot_make_y} 1680! 1690! END. {module PLOTCSUBS} 1700! 1710! 1720! MNAME MYBINASM 1730! SRC MODULE MYBINASM; 1740! SRC IMPORT csubdecl; 1750! SRC EXPORT 1760! SRC FUNCTION bit_set (v: INTEGER; 1770! SRC b: INTEGER) : BOOLEAN; 1780! SRC FUNCTION binand (X: INTEGER; 1790! SRC Y: INTEGER) : INTEGER; 1800! SRC FUNCTION binior (X: INTEGER; 1810! SRC Y: INTEGER) : INTEGER; 1820! SRC END; 1830! DEF MYBINASM_MYBINASM 1840! DEF MYBINASM_BIT_SET 1850! DEF MYBINASM_BINAND 1860! DEF MYBINASM_BINIOR 1870! * Chris S. 3-Feb-86 1880! * module initialization 1890! MYBINASM_MYBINASM EQU * 1900! RTS 1910! * 1920! * bit test 1930! MYBINASM_BIT_SET EQU * 1940! MOVEA.L (SP)+,A0 save return addr 1950! MOVE.L (SP)+,D0 get bit# 1960! MOVE.L (SP)+,D1 get first parm 1970! CLR.B D2 clear indicator 1980! BTST D0,D1 test bit 1990! BEQ.S BITT_EXIT 2000! MOVEQ #1,D2 if bit set set indicator 2010! BITT_EXIT MOVE.B D2,(SP) push result 2020! JMP (A0) return 2030! * 2040! * binary and 2050! MYBINASM_BINAND EQU * 2060! MOVEA.L (SP)+,A0 save return addr 2070! MOVE.L (SP)+,D0 get last parm 2080! MOVE.L (SP)+,D1 get first parm 2090! AND.L D0,D1 perform AND 2100! MOVE.L D1,(SP) push result 2110! JMP (A0) return 2120! * 2130! * binary inclusive or 2140! MYBINASM_BINIOR EQU * 2150! MOVEA.L (SP)+,A0 save return addr 2160! MOVE.L (SP)+,D0 get last parm 2170! MOVE.L (SP)+,D1 get first parm 2180! OR.L D0,D1 perform OR 2190! MOVE.L D1,(SP) push result 2200! JMP (A0) return 2210! 2220! * 2230! * 2240! END 2250! 2260! 2270 ! 2280 END 2290 !************************************************************************ 2300 CSUB Plot_make_y(Data_buffer(*),Data_header(*),Plot_array(*),Buf_num,Start_bin,Stop_bin,Do_log_y,Offset,Scale_factor) 2310 SUB Plot_csub_doc 2320 !The above is a compiled sub that 2330 !can be deleted if it causes a configuration error. There should be 2340 !another non-CSUB copy that does the same function, except 2350 !2 to 10 times slower. Execute "DELSUB Plot_make_y" once to 2360 !delete the CSUB. 2370 !A copy of the Pascal source code (stored as BASIC comments) is in 2380 !the file PLOT5_0. 2390 SUBEND