The one I wrote for the Commodore 64. In Basic and also in PROMAL.
10 COLOR 15, 9: CLS
15 REM Converted from Commodore BASIC to QBASIC
20
30 PRINT " DPD Echo Study"
35 PRINT "This program will automatically compute matches betweeen the
Dallas Police Dept.";
40 PRINT "recording of Ch.1 on Nov.22,1963 and estimated echoes using
variables that you ";
45 PRINT "input, then print out the results. After computation, you can
send the results ";
50 PRINT "to the printer by pressing F12, or do a series of expanded
calculations around ";
55 PRINT "the cycle and rifle starting positions by pressing F11. Press
ESC KEY to QUIT."
60 i = 0: j = 0: k = 0: l = 0: a = 0: p = 22: REM largest number of
echoes to be studied now
65 l$ = CHR$(29): l2$ = l$ + l$: l3$ = l2$ + l$: l4$ = l2$ + l2$: l5$ =
l4$ + l$: l6$ = l2$ + l4$: l7$ = l6$ + l$: l8$ = l7$ + l$
70 DIM a(22), b(22), c(22), d(22), e(22), f(22), g(22)
80 DIM est(27), cal(27)
85 DIM x(27), y(27), o$(27)
90 DIM sd(9, 9)
100 PRINT "Press RETURN to accept the suggested value or type in a new
value."
110 INPUT "Which shot do you want to study, 1, 2, or 5"; SHOT
111 IF SHOT < 1 OR SHOT > 5 OR SHOT = 3 OR SHOT = 4 THEN PRINT "1,2 or 5
only!": GOTO 110
115 PRINT "From which window was it fired (0-14)?"
116 PRINT "Window #0 is in the DAL-TEX building."
117 PRINT "Window #1 is Oswald's nest in the TSBD."
118 PRINT "Windows 2 through 9 were closed."
119 PRINT "Windows 10 through 14 were open."
120 INPUT "Window"; wi
121 IF wi < 0 OR wi > 14 THEN PRINT "Between 0-14 only!": GOTO 120
123 IF wi = 0 THEN fx = 350#: PRINT "Rifle X coordinate 350.0"; l7$; :
INPUT gx: IF gx = 0 THEN gx = fx
124 IF wi = 1 OR wi = 12 THEN fx = 321.25#: PRINT "Rifle X coordinate
321.25"; l8$; : INPUT gx: IF gx = 0 THEN gx = fx
125 IF wi = 10 OR wi = 14 THEN fx = 321.3#: PRINT "Rifle X coordinate
321.3"; l7$; : INPUT gx: IF gx = 0 THEN gx = fx
126 IF wi = 11 THEN fx = 321.1#: PRINT "Rifle X coordinate 321.1"; l7$;
: INPUT gx: IF gx = 0 THEN gx = fx
127 IF wi = 13 THEN fx = 321.6#: PRINT "Rifle X coordinate 321.6"; l7$;
: INPUT gx: IF gx = 0 THEN gx = fx
128 IF wi > 1 AND wi < 10 THEN fx = 321.5#: PRINT "Rifle X coordinate
321.5"; l7$; : INPUT gx: IF gx = 0 THEN gx = fx
130 IF wi = 0 THEN gz = 172.4: fy = -41#: PRINT "Rifle Y coordinate
-41.0"; l7$; : INPUT gy: IF gy = 0 THEN gy = fy
131 IF wi = 1 THEN gz = 161.9: fy = 46.1#: PRINT "Rifle Y coordinate
46.1"; l6$; : INPUT gy: IF gy = 0 THEN gy = fy
132 IF wi = 10 THEN gz = 162.3: fy = 106.7#: PRINT "Rifle Y coordinate
106.7"; l7$; : INPUT gy: IF gy = 0 THEN gy = fy
133 IF wi = 11 THEN gz = 161.3: fy = 116.8#: PRINT "Rifle Y coordinate
116.8"; l7$; : INPUT gy: IF gy = 0 THEN gy = fy
134 IF wi = 12 THEN gz = 161.7: fy = 121.2#: PRINT "Rifle Y coordinate
121.2"; l7$; : INPUT gy: IF gy = 0 THEN gy = fy
135 IF wi = 13 THEN gz = 163.2: fy = 130.8#: PRINT "Rifle Y coordinate
130.8"; l7$; : INPUT gy: IF gy = 0 THEN gy = fy
136 IF wi = 14 THEN gz = 161.5: fy = 134#: PRINT "Rifle Y coordinate
134.0"; l7$; : INPUT gy: IF gy = 0 THEN gy = fy
137 IF wi > 1 AND wi < 10 THEN gz = 161.5: fy = 39 + INT(wi * 6.7 + .5):
PRINT "Rifle Y coordinate "; 39 + INT(wi * 6.7 + .5); l5$; : INPUT gy:
IF gy = 0 THEN gy = fy
139 IF SHOT = 5 THEN fx = 208.3#: PRINT "Cycle X coordinate 208.3";
l7$; : INPUT cx: IF cx = 0 THEN cx = fx
140 IF SHOT = 1 THEN fx = 213.5#: PRINT "Cycle X coordinate 213.5";
l7$; : INPUT cx: IF cx = 0 THEN cx = fx
141 IF SHOT = 2 THEN fx = 232#: PRINT "Cycle X coordinate 232.0"; l7$;
: INPUT cx: IF cx = 0 THEN cx = fx
144 IF SHOT = 5 THEN cz = 95.1: fy = 129.5#: PRINT "Cycle Y coordinate
129.5"; l7$; : INPUT cy: IF cy = 0 THEN cy = fy
145 IF SHOT = 1 THEN cz = 100.1: fy = 21#: PRINT "Cycle Y coordinate
21.0"; l6$; : INPUT cy: IF cy = 0 THEN cy = fy
146 IF SHOT = 2 THEN cz = 100.1: fy = 28#: PRINT "Cycle Y coordinate
28.0"; l6$; : INPUT cy: IF cy = 0 THEN cy = fy
150 cs = 8.5#: PRINT "Cycle speed in MPH 8.5"; l5$; : INPUT mph: IF mph
= 0 THEN mph = cs
151 cs = mph * 1.466666666666667#
152 IF mph > 35 THEN PRINT "Too fast for an escort! 5< MPH <35": GOTO 150
154 PRINT "Cycle deviation in ";
155 IF SHOT = 1 THEN fc = 12: PRINT "degrees 12"; l4$; : INPUT ac: IF
ac = 0 THEN ac = fc
156 IF SHOT = 2 THEN fc = 16: PRINT "degrees 16"; l4$; : INPUT ac: IF
ac = 0 THEN ac = fc
157 IF SHOT = 5 THEN fc = 35: PRINT "degrees 35"; l4$; : INPUT ac: IF
ac = 0 THEN ac = fc
158 IF ac > 45 THEN PRINT "Unlikely that it's over 45 degrees yet!":
GOTO 154
159 REM reasonable values: shot#1(8-18), shot#2(20-34), shot#5(35+90=125)
160 ff = 1.043#: PRINT "Correction factor for tape speed 1.043"; l7$; :
INPUT cf: IF cf = 0 THEN cf = ff
162 IF cf < .9 OR cf > 1.1 THEN PRINT "There's no evidence for>10%, .9<
cf <1.1": GOTO 160
164 rc = (ac / 180) * (4# * ATN(1#)): 'function generates pi
165 v = 1123: PRINT "Speed of sound in FPS 1123"; l6$; : INPUT fps: IF
fps = 0 THEN fps = v
170
180 pi = 2# * ATN(1#): 'function generates pi/2
190 hr = pi - rc
200 z = gz - (cz + 3): REM microphone is 3 feet above ground
250 FOR i = 0 TO p + 5
255 READ x(i), y(i), o$(i)
260 NEXT
265 IF SHOT = 5 THEN SHOT = 3: REM makes it easier to read data statements
270 FOR j = 1 TO SHOT
275 FOR i = 1 TO p
280 READ a
285 IF j = SHOT THEN a(i) = ABS(a)
290 NEXT
295 NEXT
300 FOR i = 1 TO p
305 b(i) = (cf * a(i) / 1000)
310 NEXT
315 rx = gx: ry = gy: nx = cx: ny = cy
355 best = f(1)
360 GOSUB 400
370 GOSUB 750
375 ON KEY(30) GOSUB 860
380 ON KEY(31) GOSUB 861
385 KEY(30) ON: KEY(31) ON
390 IF INKEY$ = CHR$(27) THEN END
395 GOTO 390
400 REM main calculating subroutine.
405 air = SQR((rx - nx) * (rx - nx) + (ry - ny) * (ry - ny))
410 blast = SQR(air * air + z * z)
415 af = (blast / fps) - b(1)
420 c(0) = af
425 FOR i = 1 TO p
430 c(i) = b(i) + c(0)
445 d(i) = fps * c(i)
450 NEXT
455 e(1) = d(1)
460 FOR i = 2 TO p
465 est(i) = 5: f(i) = 5: g(i) = 0
470 hc = (c(i) - c(1)) * cs
475 hx = hc * COS(rc): IF SHOT = 3 THEN hx = -hx
480 hy = hc * SIN(rc)
485 mx = nx + hx
490 my = ny + hy
491 REM cycle has moved since blast
495 FOR l = 1 TO 27
500 fx = rx - x(l): fy = ry - y(l)
501 fh = SQR(fx * fx + fy * fy)
502 lx = mx - x(l): ly = my - y(l)
505 lh = SQR(lx * lx + ly * ly)
510 cal(l) = SQR(((fh + lh) * (fh + lh)) + (z * z))
515 est(l) = ABS(d(i) - cal(l))
530 IF est(l) < f(i) THEN f(i) = est(l): e(i) = cal(l): g(i) = l
535 NEXT
540 NEXT
545 f(0) = 0
550 FOR i = 2 TO p
555 f(0) = f(0) + f(i) * f(i)
560 NEXT
565 f(1) = f(0) / (p - 1): REM sum of squares
590 RETURN
600 best = 25: FOR j = 1 TO 9
601 IF j = 1 THEN rx = gx: ry = gy
602 IF j = 2 THEN rx = gx + .5: ry = gy + .5
603 IF j = 3 THEN rx = gx + .5: ry = gy
604 IF j = 4 THEN rx = gx + .5: ry = gy - .5
605 IF j = 5 THEN rx = gx: ry = gy - .5
606 IF j = 6 THEN rx = gx - .5: ry = gy - .5
607 IF j = 7 THEN rx = gx - .5: ry = gy
608 IF j = 8 THEN rx = gx - .5: ry = gy + .5
609 IF j = 9 THEN rx = gx: ry = gy + .5
610 IF rx < 320 THEN rx = 320
611 FOR k = 1 TO 9
612 IF k = 1 THEN nx = cx: ny = cy
613 IF k = 2 THEN nx = cx + .5: ny = cy + .5
614 IF k = 3 THEN nx = cx + .5: ny = cy
615 IF k = 4 THEN nx = cx + .5: ny = cy - .5
616 IF k = 5 THEN nx = cx: ny = cy - .5
617 IF k = 6 THEN nx = cx - .5: ny = cy - .5
618 IF k = 7 THEN nx = cx - .5: ny = cy
619 IF k = 8 THEN nx = cx - .5: ny = cy + .5
620 IF k = 9 THEN nx = cx: ny = cy + .5
621 REM move starting positions for rifle & cycle,then compute each sd
625 GOSUB 400
626
627 LOCATE 25, 1
628 PRINT "J="; j; ":Rifle at"; : PRINT USING "####.##"; rx; : PRINT "
by"; : PRINT USING "####.##"; ry;
629 PRINT " ", "K="; k; ":Cycle at"; : PRINT USING "####.##"; nx; :
PRINT " by"; : PRINT USING "####.##"; ny;
630 sd(j, k) = f(1)
632 IF sd(j, k) < best THEN best = sd(j, k): bj = j: bk = k
635 NEXT k, j
641 IF bj = 1 THEN rx = gx: ry = gy
642 IF bj = 2 THEN rx = gx + .5: ry = gy + .5
643 IF bj = 3 THEN rx = gx + .5: ry = gy
644 IF bj = 4 THEN rx = gx + .5: ry = gy - .5
645 IF bj = 5 THEN rx = gx: ry = gy - .5
646 IF bj = 6 THEN rx = gx - .5: ry = gy - .5
647 IF bj = 7 THEN rx = gx - .5: ry = gy
648 IF bj = 8 THEN rx = gx - .5: ry = gy + .5
649 IF bj = 9 THEN rx = gx: ry = gy + .5
651 IF bk = 1 THEN nx = cx: ny = cy
652 IF bk = 2 THEN nx = cx + .5: ny = cy + .5
653 IF bk = 3 THEN nx = cx + .5: ny = cy
654 IF bk = 4 THEN nx = cx + .5: ny = cy - .5
655 IF bk = 5 THEN nx = cx: ny = cy - .5
656 IF bk = 6 THEN nx = cx - .5: ny = cy - .5
657 IF bk = 7 THEN nx = cx - .5: ny = cy
658 IF bk = 8 THEN nx = cx - .5: ny = cy + .5
659 IF bk = 9 THEN nx = cx: ny = cy + .5
660 GOSUB 400: REM recalculate
661 RETURN
670 ' <-----------Y ^ <-----------Y ^
675 ' +-----------+ | +-----------+ |
680 ' J = | 2 | 3 | 4 | | K = | 2 | 3 | 4 | |
685 ' RIFLE +-----------+ | CYCLE +-----------+ |
690 ' POSITION | 9 | 1 | 5 | | POSITION | 9 | 1 | 5 | |
695 ' MOVES +-----------+ | MOVES +-----------+ |
700 ' 0.5 Ft | 8 | 7 | 6 | | 0.5 Ft | 8 | 7 | 6 | |
705 ' EACH TIME +-----------+ X EACH TIME +___________+ X
750 CLS
760 IF wi = 0 THEN PRINT "Rifle in DAL-TEX "; ELSE PRINT "Rifle in TSBD
#"; wi;
770
780 PRINT "at"; : PRINT USING "####.## "; rx; : PRINT "x"; : PRINT USING
"####.##"; ry;
790 PRINT " . Cycle X,Y at blast: ";
795 PRINT USING "####.## "; nx; : PRINT "x"; : PRINT USING "####.##";
ny; : PRINT " ."
800 PRINT "Millisecs Corrected Elapsed ms Elapsed ft Calc.feet
Deviation Matches "
810 FOR i = 1 TO p
815 PRINT USING "#####.### "; a(i);
820 PRINT USING "##.####### "; b(i);
825 PRINT USING "##.####### "; c(i);
830 PRINT USING "#####.#### "; d(i);
835 PRINT USING "#####.#### "; e(i);
836 IF i = 1 THEN PRINT USING "###.#### "; f(1); : IF i = 1 THEN PRINT
" **BLAST** ";
840 IF i > 1 AND f(i) >= 5 THEN PRINT "OVER 5.0 "; : ELSE IF i > 1
THEN PRINT USING "###.#### "; f(i);
841 IF i = 22 THEN PRINT o$(g(i));
842 IF i < 22 AND i > 1 THEN PRINT o$(g(i))
843 NEXT i
845 RETURN
852
853
854
855
856
857 PRINT "Performing 81 Bernoulli calculations, each .5 feet away from
starting positions";
859 GOSUB 600
860 gx = rx: gy = ry: cx = nx: cy = ny: GOSUB 600: GOSUB 750: RETURN
861 LPRINT "DPD Echo Study": IF SHOT = 3 THEN LPRINT "Shot #5": GOTO 863
862 LPRINT "Shot#"; SHOT
863 IF wi = 0 THEN LPRINT "Rifle in Dal-Tex Building.": GOTO 865
864 LPRINT "Rifle in Window #"; wi; "on the sixth floor of the Texas
School Book Depository"
865 LPRINT "Rifle Coordinates:"; rx; "x"; ry
866 LPRINT "Cycle Coordinates at Blast:"; nx; "x"; ny
867 LPRINT "Cycle's initial speed"; mph; "mph."
868 LPRINT "Cycle's path deviating ";
869 IF SHOT < 3 THEN LPRINT "west from north by"; ac; "degrees."
870 IF SHOT > 2 THEN LPRINT "south from west by"; ac; "degrees."
872 LPRINT "Correction factor used for tape speed:"; cf
873 LPRINT "Speed of sound:"; fps; "fps.": LPRINT " "
874 LPRINT "Millisec. Corrected Elapsed ms Elapsed ft Calc. feet
Deviation Matches "
875 FOR i = 1 TO p
876 LPRINT USING "#####.### "; a(i);
877 LPRINT USING "##.####### "; b(i);
878 LPRINT USING "##.####### "; c(i);
879 LPRINT USING "#####.#### "; d(i);
880 LPRINT USING "#####.#### "; e(i);
881 IF i = 1 THEN LPRINT USING "###.#### "; f(1); : GOTO 885
882 IF f(i) >= 5 THEN LPRINT "OVER 5.0 "; : ELSE LPRINT USING
"###.#### "; f(i);
885 IF i = 1 THEN LPRINT " **BLAST**": ELSE LPRINT o$(g(i))
889 NEXT i
895
899 RETURN
900 DATA 320,40.3," No Match "
901 DATA 276,72.5,"Trf. light"
902 DATA 202.5,32.5,"TrafficBox"
903 DATA 211,56.25," Pool tip "
904 DATA 199.5,44.75," Pool, NE "
905 DATA 272.5,97," Tree A "
906 DATA 201.5,79.25," Column B "
907 DATA 239.83333333,-40.3333333," DCRB, NW "
908 DATA 265.75,113.1666666," Column A "
909 DATA 319.5,-39,"DAL-TEX,SW"
910 DATA 174,82," Tree N "
911 DATA 248.5,142,"Wall A,NE "
912 DATA 296.5,149," Tree D "
913 DATA 179,120.25," Tree B "
914 DATA 158.5,-40.3333333," DCRB, SW "
915 DATA 132.5,31," Neon #1 "
916 DATA 129.8333333,-39," DCCB, NW "
917 DATA 227.5,182," Tree C "
918 DATA 100.5,96," Column D "
919 DATA 71,65.5," Monument "
920 DATA 262,235," N.Shelter"
921 DATA 39.25,76.5," Column C "
922 DATA 38.5,-39," DCCB, SW "
923 DATA 205,291," S.Shelter"
924 DATA 161,287," Retn.wall"
925 DATA -11,80," City bus "
926 DATA -40,-40,"Old Court."
927 DATA -315,50," P.O., NE "
928 REM data for x(),y(),o$()
1000 REM shot#1 data
1001 DATA 30.625: REM hsca#1
1002 DATA 41.875: REM marsh 1a
1003 REM 46.875
1004 REM 51.25
1005 DATA 56.25: REM marsh 1b
1006 REM 65
1007 REM 68.75
1008 REM 75
1009 DATA 93.125: REM hsca#2
1010 DATA 150: REM hsca#3
1011 DATA 218.75: REM hsca#4
1012 DATA 229.375: REM hsca#5
1013 DATA 237.5: REM hsca#6
1014 DATA 275: REM hsca#7
1015 DATA 288.75: REM hsca#8
1016 DATA 312.5: REM hsca#9
1017 DATA 358.75: REM hsca#10
1018 DATA 381.875: REM hsca#11
1019 DATA 393.75 : REM marsh 11a
1020 DATA 424.375: REM hsca#12
1021 DATA 465.625: REM hsca#13
1024 DATA 480.625: REM hsca#14
1025 DATA 633.75: REM marsh 14a
1026 DATA 653.75: REM hsca#15
1027 DATA 682.5: REM marsh 15a
1028 DATA 1046.875: REM hsca#16
1029 DATA 1106.25: REM hsca#17
1030 REM last echo on chart
1035 REM change rems to data statements if screen can handle >22 matches
2000 REM shot#2 data
2001 DATA 15.625: REM hsca#1
2002 DATA 25: REM hsca#2
2003 DATA 34: REM marsh 2a
2004 DATA 41: REM marsh 2b
2005 DATA 47: REM hsca#3
2006 REM 56
2007 DATA 69: REM hsca#4
2008 REM 79
2009 REM 89
2010 REM 94
2011 REM 104
2012 DATA 115.5: REM hsca#5
2013 REM 138
2014 REM 151
2015 DATA 158: REM hsca#6
2016 DATA 166: REM hsca#7
2017 REM 172
2018 REM 180
2019 REM 189
2020 REM 193
2021 REM 198
2022 REM 204
2023 DATA 220: REM hsca#8
2024 DATA 239: REM hsca#9
2025 DATA 245: REM hsca#10
2026 DATA 304.375: REM marsh 10a
2027 DATA 445: REM hsca#11
2028 DATA 476.875: REM marsh 11a
2029 DATA 565: REM hsca#12
2030 DATA 646.875: REM marsh 12a
2031 DATA 712.5: REM marsh 12b
2032 DATA 772.5: REM marsh 12c
2033 DATA 793.125: REM hsca#13
2034 DATA 913.125: REM hsca#14
2035 DATA 935.625: REM hsca#15
2036 REM last echo on tape
3000 REM shot#3 data not available
4000 REM shot#4 data not applicable
5000 REM shot#5 data
5001 DATA 48.75: REM hsca#1
5002 DATA 62.5: REM marsh 1a
5003 DATA 67.5: REM marsh 1b
5004 DATA 74.375: REM hsca#2
5005 DATA 79.375: REM marsh 2a
5006 DATA 87.5: REM hsca#3
5007 DATA 110: REM marsh 3a
5008 DATA 158.75: REM hsca#4
5009 DATA 186.875: REM marsh 4a
5010 DATA 220: REM hsca#5
5011 DATA 234.375: REM marsh 5a
5012 DATA 246.875: REM marsh 5b
5013 DATA 254.375: REM hsca#6
5014 DATA 286.25: REM marsh 6a
5015 DATA 322.5: REM hsca#7
5016 DATA 336.25: REM hsca#8
5017 DATA 368.125: REM marsh #9
5018 DATA 403.125: REM marsh #10
5019 DATA 428.75: REM marsh #11
5020 DATA 462.5: REM marsh #12
5021 DATA 473.125: REM marsh #13
5022 DATA 493.75: REM marsh #14