PROGRAM DPD ;revised on 6/25/88

INCLUDE LIBRARY
INCLUDE REALFUNCS  
INCLUDE READREAL ;numeric input FUNC

EXT BYTE shift AT $028D
EXT ASM FUNC WORD MLGET AT $0F9F
CON WORD top = 22 ;constant highest echo examined.
BYTE continuing ;Boolean flag for exiting Bernoulli PROC.
BYTE keypress ;use function keys to move columns
BYTE shot ;choose 1, 2, or 5 only ( later versions to include 3 and 4 )
BYTE window ;choose 0 for DAL-TEX, 1 is Oswald's, 10-14 are possible second gun.
BYTE CHAR
BYTE bestj ;position of rifle which gives best match
BYTE bestk ;position of cycle which gives best match
BYTE cell ;choose which column to start displaying ( a through g ).
WORD i ;used for loops and subscripts
WORD j ;used when moving rifle starting position.
WORD k ;used when moving cycle starting position.
WORD L ;used for inner loops
WORD printer
WORD loaded

REAL riflex ;coordinate
REAL rifley ;coordinate
REAL riflez ;elevation
REAL cyclex ;coordinate
REAL cycley ;coordinate
REAL cyclez ;elevation
REAL mph
REAL fps
REAL angle ;degrees that cycle's path deviates from a major compass point.
REAL radians ;angle in radians
REAL correctionfactor ;combined effect of differences in tape speed and temp.  
REAL soundspeed ;1123 fps at 65 degrees on Nov. 22, 1963.
REAL gunx ;moved rifle coordinate (>=320.)
REAL guny ;moved rifle coordinate
REAL startx ;moved cycle coordinate
REAL starty ;moved cycle coordinate
REAL bestmatch ;best of 81 attempts
REAL z ;elevation used to compute echo travel
REAL blast ;blast travel
REAL cyclemoved ;how far cycle has moved since blast.
REAL xmoved ;added to start coordinate to account for cycle motion
REAL ymoved ;added to start coordinate to account for cycle motion.
REAL newx ;new cycle coordinate for each echo.
REAL newy ;new cycle coordinate for each echo.
;    newz not needed, because difference in slope is barely negligible.
REAL firsthalf ;calculated path from rifle to object.
REAL lasthalf ;calculated path from object to cycle's mike.

REAL a[top+1] ;milliseconds on DPD tape.
REAL b[top+1] ;seconds corrected by factor.
REAL c[top+1] ;elapsed seconds after calculated blast.
REAL d[top+1] ;distance that tape impulse would have travelled.
REAL e[top+1] ;distance travelled by calculated echo.
REAL f[top+1] ;absolute difference. abs(d[i]-e[i])
WORD g[top+1] ;indexes of matching objects
REAL calce[top+6] ;calculate distance for each possible echo.
REAL abserror[top+6] ;test each echo for least difference.
DATA REAL convertradians = .017453292519943
DATA REAL mikeheight = 2.5

DATA REAL x [] = ;coordinate of object
320.0,276.0,202.5,211.0,199.5,272.5,201.5,
239.83333333334,265.75,319.5,174.0,248.5,296.5,179.0,
158.5,132.5,129.83333333334,227.5,100.5,71.0,262.0,
39.25,38.5,205.0,161.0,-11.0,-40.0,-315.0

DATA REAL y [] = ;coordinate of object
40.3333333334,72.5,32.5,56.25,44.75,97.0,79.25,
-40.3333333334,113.166666667,-39.0,82.0,142.0,149.0,120.25,
-40.3333333334,31.0,-39.0,182.0,96.0,65.5,235.0,
76.5,-39.0,291.0,287.0,80.0,-40.0,50.0

DATA REAL shot1 [] =
0.0, ;dummy value
30.625, ;HSCA #1
41.875, ;MARSH 1A
;46.875
;51.25
56.25,  ;MARSH 1B
;65.0
;68.75
;75.0
93.125, ;HSCA #2
150.0,  ;HSCA #3
218.75, ;HSCA #4
229.375,;HSCA #5
237.5,  ;HSCA #6
275.0,  ;HSCA #7
288.75, ;HSCA #8
312.5,  ;HSCA #9
358.75, ;HSCA #10
381.875,;HSCA #11
393.75, ;MARSH 11A
424.375,;HSCA #12
465.625,;HSCA #13
480.625,;HSCA #14
633.75, ;MARSH 14A
653.75, ;HSCA #15
682.5,  ;MARSH 15A
1046.875,;HSCA #16
1106.25  ;HSCA #17
;last echo on tape

DATA REAL shot2 [] =
0.0,    ;dummy value
15.625, ;HSCA #1
25.0,   ;HSCA #2
34.0,   ;MARSH 2A
41.0,   ;MARSH 2B
47.0,   ;HSCA #3
;56.0
69.0,   ;HSCA #4
;79.0
;89.0
;94.0
;104.0
115.5,  ;HSCA #5
;138.0
;151.0
158.0,  ;HSCA #6
166.0,  ;HSCA #7
;172.0
;180.0
;189.0
;193.0
;198.0
;204.0
220.0,  ;HSCA #8
239.0,  ;HSCA #9
245.0,  ;HSCA #10
304.375,;MARSH 10A
445.0,  ;HSCA #11
476.875,;MARSH 11A
565.0,  ;HSCA #12
646.875,;MARSH 12A
712.5,  ;MARSH 12B
772.5,  ;MARSH 12C
793.125,;HSCA #13
913.125,;HSCA #14
935.625 ;HSCA #15

;data real shot3 NOT AVAILABLE
;data real shot4 NOT APPLICABLE

DATA REAL shot5 [] =
0.0,    ;dummy value
48.75,  ;MARSH #1
62.5,   ;MARSH #2
67.5,   ;MARSH #3
74.375, ;MARSH #4
79.375, ;MARSH #5
87.5,   ;MARSH #6
110.0,  ;MARSH #7
158.75, ;MARSH #8
186.875,;MARSH #9
220.0,  ;MARSH #10
234.375,;MARSH #11
246.875,;MARSH #12
254.375,;MARSH #13
286.25, ;MARSH #14
322.5,  ;MARSH #15
336.25, ;MARSH #16
368.125,;MARSH #17
403.125,;MARSH #18
428.75, ;MARSH #19
462.5,  ;MARSH #20
473.125,;MARSH #21
493.75  ;MARSH #22

DATA WORD object [] =
" No Match ",
"Trf. light",
"TrafficBox",
" Pool tip ",
" Pool, NE ",
" Tree A   ",
" Column B ",
" DCRB, NW ",
" Column A ",
"DAL-TEX,SW",
" Tree N   ",
"Wall A,NE ",
" Tree D   ",
" Tree B   ",
" DCRB, SW ",
" Neon #1  ",
" DCCB, NW ",
" Tree C   ",
" Column D ",
" Monument ",
" N.Shelter",
" Column C ",
" DCCB, SW ",
" S.Shelter",
" Retn.wall",
" City bus ",
"Old Court.",
" P.O., NE "

PROC BLoad
ARG WORD name
BEGIN
REPEAT
  loaded = MLGET(name)
  IF loaded = 0
    PUT "\13Please leave this program disk in drive!"
    PUT "Insert disk and press a key when ready. "
    CHAR = GETC
UNTIL loaded <> 0
END

PROC Input
BEGIN
PUT "\93\12      ***** INPUT VARIABLES *****       \92",CR  
PUT "To input the default values as they",CR
PUT "are printed, simply press \12<RETURN>\92 . Or",CR
PUT "type in a new number,then press \12<RETURN>\92",CR
PUT CR,"Which shot do you want to study:1,2,or5?",CR
REPEAT
  keypress = TESTKEY
UNTIL keypress = '1' or keypress = '2' or keypress = '5'
shot = keypress AND $0F
PUT "From which window was it fired?",CR
PUT "Window #0 is in the Dal-Tex building.",CR
PUT "Window #1 is Oswald's nest in the TSBD.",CR
PUT "Windows 2 through 9 were closed.",CR
PUT "Windows 10 through 14 were open.",CR
PUT "Choose 0,1,10,11,12,13,or 14 only!",CR
refuge 0
window = 0
PUT "Window #"
WHILE NUMERIC(GETC(#CHAR))
  window = 10*window+(CHAR-'0')
IF window <0 OR window >14
  ESCAPE 0
PUT CR,"Rifle X coordinate:"
CHOOSE window
0
  riflex = readreal(350.0)
1
  riflex = readreal(321.25)
10
  riflex = readreal(321.3)
11
  riflex = readreal(321.1)
12
  riflex = readreal(321.25)
13
  riflex = readreal(321.6)
14
  riflex = readreal(321.3)
ELSE
  riflex = readreal(321.5)
PUT CR,"Rifle Y coordinate:"
CHOOSE window
0
  rifley = readreal(-41.0)
  riflez = 172.4
1
  rifley = readreal(46.1)
  riflez = 161.9
10
  rifley = readreal(106.7)
  riflez = 162.3
11
  rifley = readreal(116.8)
  riflez = 161.3
12
  rifley = readreal(121.2)
  riflez = 161.7
13
  rifley = readreal(130.8)
  riflez = 163.2
14
  rifley = readreal(134.0)
  riflez = 161.5
ELSE
  rifley = readreal(40+(window*6.7))
  riflez = 161.5
PUT CR,"Motorcycle X coordinate:"
CHOOSE shot
1
  cyclex = readreal(213.5)
  FOR i = 1 to top
    a[i]=shot1[i]
2
  cyclex = readreal(232.0)
  FOR i = 1 to top
    a[i]=shot2[i]
5
  cyclex = readreal(208.3)
  FOR i = 1 to top
    a[i]=shot5[i]
ELSE
  nothing
PUT CR,"Motorcycle Y coordinate:"
CHOOSE shot
1
  cycley = readreal(21.0)
  cyclez = 100.1
2
  cycley = readreal(28.0)
  cyclez = 100.1
5
  cycley = readreal(128.5)
  cyclez = 95.1
ELSE
  nothing
z=riflez-cyclez
REPEAT
  PUT CR,"Cycle speed in MPH:"
  mph = readreal(8.5)
  fps = MPH*1.466666667
  IF mph<=0.
    PUT "Cycle is not stationary!"
  IF mph>35.0
    PUT "Too fast for an escort!"
UNTIL mph>0. AND MPH<35.0
REPEAT
  CHOOSE shot
  1
    PUT CR,"Cycle deviation west away from north in"
    PUT CR,"degrees:"
    angle = readreal(12.0)
  2
    PUT CR,"Cycle deviation west away from north in"
    PUT CR,"degrees:"
    angle = readreal(16.0)
  5 
    PUT CR,"Cycle deviation south away from west in"
    PUT CR,"degrees:"
    angle = readreal(35.0)
  ELSE
    nothing
  IF angle<0.
    PUT "Must be positive!"
  IF angle>45.0
    PUT "Highly unlikely!"
UNTIL angle>0. AND angle<45.0
radians=angle*convertradians
REPEAT
  PUT CR,"Correction factor for tape"
  PUT CR,"speed:"
  correctionfactor = readreal(1.043)
  IF correctionfactor<.9 OR correctionfactor >1.1
    PUT CR,"No evidence to indicate >10%."
UNTIL correctionfactor>.9 AND correctionfactor<1.1
REPEAT
  PUT CR,"Speed of sound in FPS:"
  soundspeed = readreal(1123.0)
  IF soundspeed<1100. OR soundspeed>1150.
    PUT CR,"No evidence for such an extreme."
UNTIL soundspeed>1100. AND soundspeed<1150.
PUT CR,"Do you want to change the variables for "
PUT "this shot (y/n)?"
REPEAT
  keypress = GETC
UNTIL keypress = 'y' OR keypress = 'n'
IF keypress = 'y' 
  input   
PUT CR,"***************Calculating**************"
END

PROC Calculate
BEGIN
FOR i=1 to top
  b[i]=a[i]/1000.*correctionfactor
IF gunx<320.
  gunx=320. ;muzzle cannot be any farther outside window
IF starty<10.
  starty=10.;cycle cannot be in middle of Houston St.
blast=sqrt((startx-gunx)*(startx-gunx)+(starty-guny)*(starty-guny))
c[0]=(sqrt(blast*blast+z*z))/soundspeed-b[1]
FOR i=1 to top
  c[i]=b[i]+c[0]
  d[i]=c[i]*soundspeed
e[1]=d[1]
FOR i=2 to top
  calce[i]=5.
  e[i]=0.
  f[i]=5.
  g[i]=0
  abserror[i]=5.
  cyclemoved=(c[i]-c[1])*fps
  xmoved=cyclemoved*cos(radians)
  IF shot=5
    xmoved=-xmoved
  ymoved=cyclemoved*sin(radians)
  newx=startx+xmoved
  newy=starty+ymoved
  IF i>5
    L=i-5
  ELSE
    L=1
  WHILE L<i+5
    firsthalf=sqrt((gunx-x[L])*(gunx-x[L])+(guny-y[L])*(guny-y[L]))
    lasthalf=sqrt((newx-x[L])*(newx-x[L])+(newy-y[L])*(newy-y[L]))
    calce[L]=sqrt(((firsthalf+lasthalf)*(firsthalf+lasthalf))+(z*z))
    abserror[L]=abs(d[i]-calce[L])
    IF abserror[L]<f[i]
      f[i]=abserror[L]
      e[i]=calce[L]
      g[i]=L
    L=L+1
f[0]=0.
FOR i=2 to top
  f[0]=f[0]+f[i]*f[i]
f[1]=f[0]/(top-1)
END

PROC Display
BEGIN
CURSET 0,0
PUT "Rifle in "
IF window = 0
  PUT "DAL-TEX,SW§"
ELSE
  OUTPUT "window ###2W§",window
PUT "Cycle (X,Y) at blast"
OUTPUT "(#8.3R,#8.3R)§ (#8.3R,#8.3R)",gunx,guny,startx,starty
CHOOSE cell
1
  PUT "Millisecs.\12Corrected \92Post blast\12Sec. * FPS\92"
  FOR i = 1 to top-1
    OUTPUT "#10.4R\12#10.7R\92#10.7R\12#10.4R\92",a[i],b[i],c[i],d[i]
  OUTPUT "#10.4R\12#10.7R\92#10.7R\12#9.3R\92",a[top],b[top],c[top],d[top]
2
  PUT "\12Corrected \92Post blast\12Sec. * FPS\92Calc. feet"
  FOR i = 1 to top-1
    OUTPUT "\12#10.7R\92#10.7R\12#10.4R\92#10.4R",b[i],c[i],d[i],e[i]
  OUTPUT "\12#10.7R\92#10.7R\12#10.4R\92#9.3R",b[top],c[top],d[top],e[top]
3
  PUT "Post blast\12Sec. * FPS\92Calc. feet\12Deviation \92"
  FOR i = 1 to top-1
    OUTPUT "#10.7R\12#10.4R\92#10.4R",c[i],d[i],e[i]
    IF f[i]>=5.
      PUT "\12 OVER 5.0 \92"
    ELSE
      IF i = 1
        OUTPUT "\12#10.6R\92",f[1]
      ELSE
        OUTPUT "\12#10.7R\92",f[i]
  OUTPUT "#10.7R\12#10.4R\92#10.4R",c[top],d[top],e[top]
  IF f[top]>=5.
    PUT "\12 OVER 5.0\92"
  ELSE
    OUTPUT "\12#9.6R\92",f[top]
4
  PUT "\12Sec. * FPS\92Calc. feet\12Deviation \92  Matches "
  OUTPUT "\12#10.4R\92#10.4R\12#10.6R\92¦¦¦BLAST¦¦",d[1],e[1],f[1]
  FOR i = 2 to top-1
    OUTPUT "\12#10.4R\92#10.4R",d[i],e[i]
    IF f[i]>=5.
      PUT "\12 OVER 5.0 \92"
    ELSE
      OUTPUT "\12#10.7R\92",f[i]
    OUTPUT "#10S",object[(g[i])] ;indexed string array
  OUTPUT "\12#10.4R\92#10.4R",d[top],e[top]
  IF f[top]>=5.
    PUT "\12 OVER 5.0\92"
  ELSE
    OUTPUT "\12#9.6R\92",f[top]
  OUTPUT "#10S",object[(g[top])] ;indexed string array
ELSE
  cell=1
END

PROC Printout
BEGIN
Printer = OPEN ("P", 'W')
IF Printer=0
  PUT"Turn on your printer,then press <RETURN>."
  REPEAT
    nothing
  UNTIL GETKEY = CR
  CLOSE Printer
  Printout
PUTF Printer,CR,"DPD Echo Study ( in PROMAL ).",CR
OUTPUTF Printer,"Shot###W#C",shot
PUTF Printer,"Rifle located on the 6th floor of the "
IF window
  OUTPUTF Printer,"Texas School Book Depository, window #W.#C",window
ELSE
  PUTF Printer,"DAL-TEX building, Southwest corner window.",CR
OUTPUTF Printer,"Rifle coordinates: (#8.3R,#8.3R).#C",gunx,guny
OUTPUTF Printer,"Cycle coordinates at blast: (#8.3R,#8.3R).#C",startx,starty
OUTPUTF Printer,"Cycle's initial speed: #8.4R MPH#C",mph
IF shot=5
  OUTPUTF Printer,"Cycle's path:#8.4R degrees south of due west.#C",angle
ELSE
  OUTPUTF Printer,"Cycle's path:#8.4R degrees west of due north.#C",angle
OUTPUTF Printer,"Tape correction factor:#8.4R#C",correctionfactor 
OUTPUTF Printer,"Speed of sound:#8.2R fps.#C#C",soundspeed
PUTF Printer,CR,"Millisecs.    Corrected ms.  Elapsed secs.  Elapsed ft.  "
PUTF Printer,"  Computed ft.   Deviation    Matches",CR
FOR i = 1 to top
  OUTPUTF Printer,"#10.4R   #12.9R   #12.9R",a[i],b[i],c[i]
  OUTPUTF Printer,"   #12.6R   #12.6R",d[i],e[i]
  IF i=1
    OUTPUTF Printer,"    Sum:#6.2R   Blast#C",f[1]
  ELSE
    IF f[i]>=5.
      OUTPUTF Printer,"    Over 5.0    #11S#C",object[(g[i])]
    ELSE
      OUTPUTF Printer,"  #10.6R    #11S#C",f[i],object[(g[i])]
cell=1
PUTF Printer, 12,3,CR ;Formfeed,then ETX
IF shift=1
  Continuing=FALSE
CLOSE Printer
END

PROC Bernoulli
;81 trials around the starting rifle and cycle positions.
;
;   2 ¥3 ¥4
;   £££££££     j-Rifle locations
;   9 ¥1 ¥5  X
;   £££££££     k-Cycle locations
;   8 ¥7 ¥6
;   £££££££
;      Y
BYTE n
BEGIN
bestmatch=25.
bestj=1
bestk=1
FOR j = 1 to 9
  IF j = 1
    gunx=riflex
    guny=rifley
  IF j =2
    gunx=riflex+.5
    guny=rifley+.5
  IF j = 3
    gunx=riflex+.5
    guny=rifley
  IF j = 4
    gunx=riflex+.5
    guny=rifley-.5
  IF j = 5
    gunx=riflex
    guny=rifley-.5
  IF j = 6
    gunx=riflex-.5
    guny=rifley-.5
  IF j = 7
    gunx=riflex-.5
    guny=rifley
  IF j = 8
    gunx=riflex-.5
    guny=rifley+.5
  IF j = 9
    gunx=riflex
    guny=rifley+.5
  IF gunx<320.
    gunx=320. ;can not be beyond facade
  FOR k = 1 TO 9
    IF k = 1
      startx=cyclex
      starty=cycley
    IF k = 2
      startx=cyclex+.5
      starty=cycley+.5
    IF k = 3
      startx=cyclex+.5
      starty=cycley
    IF k = 4
      startx=cyclex+.5
      starty=cycley-.5
    IF k = 5
      startx=cyclex
      starty=cycley-.5
    IF k = 6
      startx=cyclex-.5
      starty=cycley-.5
    IF k = 7
      startx=cyclex-.5
      starty=cycley
    IF k = 8
      startx=cyclex-.5
      starty=cycley+.5
    IF k = 9
      startx=cyclex
      starty=cycley+.5
    IF starty<10.
      starty=10. ;cycle never beyond line
    FAST     ;switch to double CPU speed
    Calculate
    SLOW     ;switch to normal CPU speed
    n=9*(j-1)+k ; 9*0+1=1 to 9*8+9=81
    OUTPUT "\13\12Bernoulli trial#3W: j=#2W,k=#2W,dev.=#5.1R\92",n,j,k,f[1]
    IF f[1]<bestmatch
      bestmatch=f[1]
      bestj=j
      bestk=k
CHOOSE bestj
1
  gunx=riflex
  guny=rifley
2
  gunx=riflex+.5
  guny=rifley+.5
3
  gunx=riflex+.5
  guny=rifley
4
  gunx=riflex+.5
  guny=rifley-.5
5
  gunx=riflex
  guny=rifley-.5
6
  gunx=riflex-.5
  guny=rifley-.5
7
  gunx=riflex-.5
  guny=rifley
8
  gunx=riflex-.5
  guny=rifley+.5
9
  gunx=riflex
  guny=rifley+.5
ELSE
  nothing
IF gunx<320.
  gunx=320.
CHOOSE bestk
1
  startx=cyclex
  starty=cycley
2
  startx=cyclex+.5
  starty=cycley+.5
3
  startx=cyclex+.5
  starty=cycley
4
  startx=cyclex+.5
  starty=cycley-.5
5
  startx=cyclex
  starty=cycley-.5
6
  startx=cyclex-.5
  starty=cycley-.5
7
  startx=cyclex-.5
  starty=cycley
8
  startx=cyclex-.5
  starty=cycley+.5
9
  startx=cyclex
  starty=cycley+.5
ELSE
  nothing
IF starty<10.
  starty=10.
Calculate
Continuing=TRUE
IF bestj=1 AND bestk=1
  Continuing=FALSE
ELSE
  riflex=gunx
  rifley=guny
  cyclex=startx
  cycley=starty
  Continuing=TRUE
IF shift=1 AND Continuing
  Continuing=TRUE
IF shift<>1
  Continuing=FALSE
END

BEGIN ; Main loop
BLOAD "INTRO.DPD"
BLOAD "HELP.DPD"
REPEAT
  keypress=TESTKEY
UNTIL keypress = $20 or keypress = $0D ;SPACE BAR or RETURN
Input
gunx=riflex
guny=rifley
startx=cyclex
starty=cycley
FAST
Calculate
SLOW
REFUGE 1
cell=1
Display
Continuing=TRUE
WHILE Continuing
  keypress=TESTKEY
  CHOOSE keypress
  $5C  ;\
    BLOAD "HELP.DPD"
    REPEAT
      keypress=TESTKEY
    UNTIL keypress = $20 or keypress = $0D ;SPACE BAR or RETURN
    Display
  $20  ;SPACE BAR
    cell=cell+1
    IF cell>4
      cell=4
    Display
  $88  ;f7
    cell=cell-1
    IF cell<1
      cell=1
    Display
  $87  ;f5
    Printout
    Display
  $86  ;f3
    Bernoulli
    FAST
    Calculate
    SLOW
    Display
  $85  ;f1
    Input
    FAST
    Calculate
    SLOW
    Escape 1
  ELSE
    nothing
END

