home *** CD-ROM | disk | FTP | other *** search
/ Our Solar System / Our Solar System.iso / shuttle / sts9019 / stsorbit.bas < prev    next >
Encoding:
BASIC Source File  |  1990-05-06  |  55.3 KB  |  2,159 lines

  1. '       ************************************
  2. '       *  Program STSORBIT  Version 9019  *
  3. '       ************************************
  4.  
  5. '       by David H. Ransom, Jr.
  6. '          7130 Avenida Altisima
  7. '          Rancho Palos Verdes, CA  90274
  8.  
  9. '       Requires Microsoft QuickBASIC 4.50 or BASIC COMPILER 7.0:
  10.  
  11. '               QB STSORBIT
  12.  
  13. DECLARE SUB Center (Text$, Row%, Column%, Length%)
  14. DECLARE SUB ClearLine (LineNo%)
  15. DECLARE SUB UseColor (Colr%)
  16. DECLARE SUB WaitForKey (K$)
  17.  
  18. DECLARE FUNCTION DMY2JD# (Day%, Month%, Year1%)
  19. DECLARE FUNCTION Get2$ (I%)
  20. DECLARE FUNCTION GetDate$ (Day%, Month%, Year%)
  21. DECLARE FUNCTION InputDMY# (Flag%, JulianDay#)
  22. DECLARE FUNCTION InputHMS# (Flag%)
  23. DECLARE FUNCTION JD2DMY$ (Day%, Month%, Year%, JD#, FracDay#)
  24. DECLARE FUNCTION LeapYear% (Y%)
  25. DECLARE FUNCTION Mod2PI# (X#)
  26. DECLARE FUNCTION Mod360# (Degrees#)
  27. DECLARE FUNCTION Mod86400# (T#)
  28. DECLARE FUNCTION String2$ (Value%, Lead$)
  29. DECLARE FUNCTION SystemDate# (Day%, Month%, Year%, DateString$)
  30. DECLARE FUNCTION SystemTime# (Hours%, Minutes%, Seconds%, TimeString$)
  31. DECLARE FUNCTION TimeStr$ (Seconds#, DDigits%, FormatFlag%, LeadZero$)
  32.  
  33.     DEFDBL A-Z
  34.     COMMON SHARED ColorFlag%
  35.  
  36.     CONST PI# = 3.141592653589793#
  37.     CONST TwoPI# = PI * 2#
  38.     CONST HalfPI# = PI / 2#
  39.     CONST Rad2Deg# = 180# / PI#
  40.     CONST Deg2Rad# = 1# / Rad2Deg#
  41.     CONST PlotInterval% = 10
  42.     CONST MarkerInterval = 60
  43.     'CONST SpotsAhead% = 16200 / MarkerInterval
  44.     'CONST SpotsBehind% = 5400 / MarkerInterval
  45.     CONST SpotsAhead% = 270
  46.     CONST SpotsBehind% = 90
  47.     CONST NSpots% = SpotsAhead% + SpotsBehind%
  48.        
  49.     REM $DYNAMIC
  50.     DIM MLat%(8210), MLon%(8210)
  51.     DIM Map%(36)
  52.     DIM XSpots%(0 TO NSpots% - 1)
  53.     DIM YSpots%(0 TO NSpots% - 1)
  54.     DIM CSpots%(0 TO NSpots% - 1)
  55.  
  56.     CONST Mu# = 398601200000000#: ' Geocentric Gravitational Constant
  57.                   ' AA = 3.98600448E+14
  58.     CONST ERadius# = 6378160: ' Equatorial Radius of Earth
  59.                   ' AA = 6378140 or 6378137 (IUGG)
  60.     CONST ERadius2# = ERadius * ERadius / 1000000#
  61.     CONST NM2SM# = 1.1516:    ' Convert Nautical Miles to Statute Miles
  62.     CONST SM2Ft# = 5280:      ' Convert Statute Miles to Feet
  63.     CONST Ft2M# = .3048006:   ' Convert Feet to Meters
  64.     CONST KM2NM# = .53898891695462#:        'Convert KM to NM
  65.  
  66. '       ******************************
  67. '       *  Initialize Printer Flags  *
  68. '       ******************************
  69.  
  70.     PrintFlag% = -1
  71.     Pages% = 0
  72.     Lines% = 0
  73.  
  74. '       ****************************
  75. '       *  Determine Monitor Type  *
  76. '       ****************************
  77.  
  78. '       Overide monitor tests with command line options:
  79.  
  80. '       /EGA = Force EGA or lower
  81. '       /CGA = Force CGA
  82.  
  83.     CommandLine$ = COMMAND$
  84.  
  85. GetMonitor:
  86.     IF INSTR(CommandLine$, "/EGA") <> 0 THEN GOTO TestEGA
  87.     IF INSTR(CommandLine$, "/CGA") <> 0 THEN GOTO TestCGA
  88.  
  89. TestVGA:
  90.     UseColor -1
  91.     ON ERROR GOTO NoVGA
  92.     Monitor% = 3
  93.     ScreenNum% = 12
  94.     Aspect! = 1
  95.     SCREEN 12
  96.     WIDTH 80, 30
  97.     ColorFlag% = 1
  98.     Delay% = 30
  99.     TRow% = 26
  100.     GOTO LoadINI
  101.  
  102. TestEGA:
  103.     UseColor -1
  104.     ON ERROR GOTO NoEGA
  105.     Monitor% = 2
  106.     ScreenNum% = 9
  107.     Aspect! = .729
  108.     SCREEN 9
  109.     WIDTH 80, 25
  110.     ColorFlag% = 1
  111.     Delay% = 30
  112.     TRow% = 21
  113.     GOTO LoadINI
  114.  
  115. TestEGA1:
  116.     ON ERROR GOTO NoEGA1
  117.     Monitor% = 1
  118.     ScreenNum% = 8
  119.     SCREEN 8
  120.     WIDTH 80, 25
  121.     UseColor 0
  122.     ColorFlag% = 0
  123.     Delay% = 60
  124.     TRow% = 21
  125.     GOTO LoadINI
  126.  
  127. TestHGC:
  128.     ON ERROR GOTO NoHGC
  129.     Monitor% = 4
  130.     ScreenNum% = 3
  131.     SCREEN 3
  132.     WIDTH 80, 25
  133.     UseColor 0
  134.     ColorFlag% = 0
  135.     Delay = 60
  136.     TRow% = 21
  137.     GOTO LoadINI
  138.  
  139. TestCGA:
  140.     ON ERROR GOTO NoCGA
  141.     Monitor% = 1
  142.     ScreenNum% = 2
  143.     SCREEN 2
  144.     ON ERROR GOTO QBError
  145.     WIDTH 80, 25
  146.     UseColor 0
  147.     ColorFlag% = 0
  148.     Delay% = 60
  149.     TRow% = 21
  150.     GOTO LoadINI
  151.  
  152. NoVGA:  RESUME TestEGA
  153. NoEGA:  RESUME TestEGA1
  154. NoEGA1: RESUME TestHGC
  155. NoHGC:  RESUME TestCGA
  156. NoCGA:  SCREEN 0
  157.     PRINT CHR$(7)
  158.     PRINT "Sorry, STSORBIT cannot recognize your monitor type ..."
  159.     PRINT
  160.     PRINT "If you are using a Hercules Graphics Card, run MSHERC first!"
  161.     GOTO STSExit
  162.  
  163. DataError:
  164.     SCREEN 0
  165.     CLS : PRINT CHR$(7)
  166.     UseColor LtRed%
  167.     Center "Cannot find file STSORBIT.DAT!", 5, 1, 80
  168.     UseColor Yellow%
  169.     Center "STSORBIT.DAT must be in the current disk/directory.", 8, 1, 80
  170.     Center "Program STSORBIT is aborted!", 10, 1, 80
  171.     UseColor LtWhite%: LOCATE 14, 1, 1, 5, 7
  172.     PRINT "Press any key to return to DOS: ";
  173.     WaitForKey (K$)
  174.     SYSTEM
  175.  
  176. QBError:
  177.     UseColor LtRed%
  178.     PRINT
  179.     PRINT "QuickBASIC Error = "; ERR; CHR$(7);
  180. STSExit:
  181.     PRINT
  182.     PRINT "Press any key to return to DOS ..."
  183.     WaitForKey (K$)
  184.     SYSTEM
  185.  
  186. '       ********************************
  187. '       *  Load Last Run's Parameters  *
  188. '       ********************************
  189.  
  190. LoadINI:
  191.     INIFile$ = "STSORBIT.INI"
  192.     GOSUB LoadINI1
  193.     GOTO LoadMap
  194.  
  195. LoadINI1:
  196.     IF Monitor% = 2 OR Monitor% = 3 THEN GridFlag% = 1 ELSE GridFlag% = 0
  197.     DemoFlag% = 0
  198.     AdjustFlag% = 0
  199.     AdjustLongitude = 0
  200.     AdjustTime = 0
  201.     ON ERROR GOTO NoINI
  202.     ININum% = FREEFILE
  203.     OPEN "I", ININum%, INIFile$
  204.     INPUT #ININum%, LastMission$
  205.     INPUT #ININum%, LastOrbitTime, LastOrbitIncl
  206.     INPUT #ININum%, LastLDate, LastLTime
  207.     INPUT #ININum%, LastGridFlag%
  208.     INPUT #ININum%, LastAdjustL, LastAdjustT
  209.     ON ERROR GOTO OldINI
  210.     INPUT #ININum%, NodeFlag%, TrackStn%
  211.     CLOSE
  212.     RETURN
  213.  
  214. NoINI:
  215.     LastMission$ = ""
  216. OldINI:
  217.     CLOSE
  218.     RESUME LoadMap
  219.  
  220. '       ****************************
  221. '       *   Load Map Coordinates   *
  222. '       *  (Courtesy Brian Jones)  *
  223. '       ****************************
  224.  
  225. '       See Brian Jones' program SUNMAP for an excellent display
  226. '       of sunlight/sunrise/sunset/night on the globe. SUNMAP is
  227. '       available on my BBS at (213) 541-7299.
  228.  
  229. LoadMap:
  230.     ON ERROR GOTO QBError
  231.     SCREEN 0: LOCATE , , 0
  232.     IF LoadFlag% = 1 THEN GOTO Begin
  233.     SELECT CASE Monitor%
  234.         CASE 3
  235.             Equator% = 215
  236.             VFactor! = 5
  237.             Top% = 16
  238.         CASE 2, 4
  239.             Equator% = 155
  240.             VFactor! = 3.5
  241.             Top% = 16
  242.         CASE ELSE
  243.             Equator% = 90
  244.             VFactor! = 2
  245.             Top% = 8
  246.     END SELECT
  247.     Bottom% = 80 * VFactor! - 3
  248.        
  249.     GOSUB SetColors
  250.     GOSUB ShowTitle
  251.        
  252.     IF LastMission$ <> "" THEN
  253.         UseColor LtCyan%
  254.         Center "Last Mission = " + LastMission$, 13, 1, 80
  255.     END IF
  256.        
  257.     UseColor LtRed%
  258.     Center "Loading STSORBIT Map Data", 15, 1, 80
  259.     Center "Please wait ...", 17, 1, 80
  260.     UseColor Cyan%
  261.     Center "Percent processed = 00.0%", 19, 1, 80
  262.     X% = POS(0)
  263.     MapNum% = FREEFILE
  264.     ON ERROR GOTO DataError
  265.     OPEN "I", MapNum%, "STSORBIT.DAT"
  266.     SFactor! = VFactor! / 4!
  267.     N% = 1
  268.     IF INSTR(CommandLine$, "/EUR") <> 0 THEN AdjMapLon% = 0 ELSE AdjMapLon% = 160
  269.     IF INSTR(CommandLine$, "/EUR") <> 0 THEN AdjEUROPE% = 180 ELSE AdjEUROPE% = -90
  270.     WHILE NOT EOF(MapNum%)
  271.         K$ = INKEY$
  272.         IF K$ = CHR$(27) THEN CLOSE : CLS : SYSTEM
  273.         INPUT #MapNum%, MLO%, MLA%
  274.         MLon%(N%) = (MLO% + AdjMapLon%) MOD 640
  275.         MLat%(N%) = Equator% - (175 - MLA%) * SFactor!
  276.         IF N% MOD 100 = 0 THEN
  277.             Percent = N% / 82.1
  278.             LOCATE 19, X% - 5
  279.             PRINT USING "##.#"; Percent;
  280.         END IF
  281.         N% = N% + 1
  282.     WEND
  283.     CLOSE MapNum%
  284.     ON ERROR GOTO QBError
  285.     MPoints% = N% - 1
  286.     Decay = 1#
  287.     LoadFlag% = 1
  288.     IF TrackStn% <> 1 THEN TrackStn% = -1
  289.     IF Monitor% = 1 OR Monitor% = 4 THEN Blink% = 1 ELSE Blink% = -1
  290.  
  291. '       ****************************
  292. '       *  Select Program Options  *
  293. '       ****************************
  294.  
  295. Begin:
  296.     SCREEN 0: LOCATE , , 0
  297.     TitleFlag% = 0
  298.     ShuttleColor% = LtWhite%
  299.     CDays = 0
  300.     CatchFlag% = 0
  301.     WaitFlag% = 1
  302.     STime$ = ""
  303.     SDate$ = ""
  304.     ANTime = 0
  305.     ANDays = 0
  306.     ANLongitude = 0
  307.     ANOrbit = 0
  308.     DNTime = 0
  309.     DNDays = 0
  310.     DNLongitude = 0
  311.     DNOrbit = 0
  312.     PriorCDate$ = ""
  313.     PriorSDate$ = ""
  314.     PriorANTime = 0
  315.     PriorDNTime = 0
  316.     PriorANTime$ = ""
  317.     PriorDNTime$ = ""
  318.     SqrMu = SQR(Mu)
  319.     SqrMu1 = SQR(398601.2#)
  320.  
  321.     FOR N% = 0 TO 20: Map%(N%) = 0: NEXT
  322.        
  323.     SaveFlag% = 0
  324.        
  325.     IF INSTR(CommandLine$, "/RESUME") <> 0 AND Mission$ = "" THEN
  326.         Option$ = "R"
  327.         GOTO Wait1A
  328.     END IF
  329.       
  330.     GOSUB ShowTitle1
  331.        
  332.     UseColor Cyan%: LOCATE 11, 1, 1
  333.     PRINT TAB(17); "A  Adjust orbital information          B  Blink shuttle symbol";
  334.     PRINT TAB(17); "D  STSORBIT Demonstration (STS-29)     L  Log to printer [OFF]";
  335.     PRINT TAB(17); "E  Enter new orbital information"
  336.     PRINT TAB(17); "F  Read data from named INI file"
  337.     IF Monitor% <> 1 THEN
  338.         GRow% = CSRLIN
  339.         PRINT TAB(17); "G  Toggle map GRID. [Grid is now ";
  340.         UseColor LtGreen%
  341.         IF GridFlag% = 0 THEN PRINT "OFF";  ELSE PRINT "ON";
  342.         UseColor Cyan%
  343.         PRINT "]"
  344.     END IF
  345.     PRINT TAB(17); "M  Change MAP center [Center is now ";
  346.     UseColor LtGreen%
  347.     IF INSTR(CommandLine$, "/EUR") = 0 THEN
  348.         PRINT "-90° = United States";
  349.     ELSE
  350.         PRINT "0° = Europe";
  351.     END IF
  352.     UseColor Cyan%
  353.     PRINT "]"
  354.     NodeRow% = CSRLIN
  355.     PRINT TAB(17); "N  Show most recent ascending & descending nodes [";
  356.     UseColor LtGreen%
  357.     IF NodeFlag% = 0 THEN PRINT "OFF";  ELSE PRINT "ON";
  358.     UseColor Cyan%
  359.     PRINT "]"
  360.     IF LastMission$ <> "" THEN
  361.         PRINT TAB(15); "  R  Resume previous STS mission: ";
  362.         UseColor LtMagenta%
  363.         PRINT LastMission$
  364.     END IF
  365.     UseColor Cyan%
  366.     IF Monitor% <> 1 THEN
  367.         TrackRow% = CSRLIN
  368.         PRINT TAB(17); "T  Display NASA Tracking Stations [";
  369.         COLOR LtGreen%
  370.         IF TrackStn% = 1 THEN PRINT "ON";  ELSE PRINT "OFF";
  371.         UseColor Cyan%
  372.         PRINT "]"
  373.     END IF
  374.     PRINT TAB(17); "S  DOS Shell (CAUTION: DOS Version 3.x ONLY!)"
  375.     PRINT TAB(15); "ESC  Quit Program STSORBIT (save current mission)"
  376.     PRINT TAB(12); "RETURN  Resume current mission"
  377.     UseColor Yellow%
  378.     PRINT TAB(20); "Select the function desired: ";
  379.     PriorCDate$ = ""
  380. Wait1:
  381.     Option$ = INKEY$
  382.     IF LEN(Option$) = 0 THEN
  383.         CTime = SystemTime(H%, M%, Secs%, CTime$)
  384.         CDate = SystemDate(Day%, Month%, Year%, CDate$)
  385.         IF OldSecs% <> Secs% THEN
  386.             OldSecs% = Secs%
  387.             UseColor LtGreen%
  388.             Center "Current time: " + CTime$, 8, 1, 80
  389.             IF PriorCDate$ <> CDate$ THEN
  390.                 Center "Current date: " + CDate$, 9, 1, 80
  391.                 PriorCDate$ = CDate$
  392.             END IF
  393.             LOCATE , , 0
  394.         END IF
  395.         GOTO Wait1
  396.     END IF
  397.     PriorCDate$ = ""
  398.     Option$ = UCASE$(Option$)
  399. Wait1A:
  400.     SELECT CASE Option$
  401.         CASE CHR$(27)
  402.             IF DemoFlag% = 1 OR Mission$ = "" THEN CLS : SYSTEM
  403.             ININum% = FREEFILE
  404.             OPEN "O", ININum%, "STSORBIT.INI"
  405.             WRITE #ININum%, Mission$
  406.             WRITE #ININum%, OrbitTime, OrbitIncl
  407.             WRITE #ININum%, LDate, LTime
  408.             WRITE #ININum%, GridFlag%
  409.             WRITE #ININum%, AdjustLongitude, AdjustTime
  410.             WRITE #ININum%, NodeFlag%, TrackStn%
  411.             CLOSE
  412.             CLS
  413.             SYSTEM
  414.         CASE CHR$(13)
  415.             IF Mission$ = "" THEN
  416.                 ClearLine 23
  417.                 UseColor LtRed%
  418.                 PRINT "No mission data! Use 'R' or 'E' command to load data."
  419.                 UseColor Yellow%
  420.                 PRINT "Press any key to continue ..."; CHR$(7);
  421.                 WaitForKey (K$)
  422.                 GOTO Begin
  423.             END IF
  424.             SCREEN ScreenNum%
  425.             GOTO Restart
  426.         CASE "A"
  427.             GOTO Adjust
  428.         CASE "B"
  429.             Blink% = Blink% * -1
  430.             GOTO Wait1
  431.         CASE "D"
  432.             DemoFlag% = 1
  433.             SCREEN ScreenNum%
  434.             GOTO Demo
  435.         CASE "E"
  436.             DemoFlag% = 0
  437.             GOTO Manual
  438.         CASE "F"
  439.             GOSUB ShowTitle
  440.             UseColor Yellow%
  441.             LOCATE 17, 1
  442.             PRINT "The following INI files are available:"
  443.             UseColor White%
  444.             FILES "*.INI"
  445.             UseColor Cyan%
  446.             LOCATE 15, 1
  447.             PRINT "(If no filetype is given, .INI will be supplied automatically)";
  448.             UseColor Green%
  449.             LOCATE 14, 1
  450.             PRINT "Enter INI Filename (RETURN=STSORBIT.INI): ";
  451.             UseColor Yellow%
  452.             LINE INPUT INIFile$
  453.             IF INIFile$ = "" THEN INIFile$ = "STSORBIT.INI"
  454.             IF INSTR(INIFile$, ".") = 0 THEN INIFile$ = INIFile$ + ".INI"
  455.             GOSUB LoadINI1
  456.             ON ERROR GOTO QBError
  457.             GOTO ResumeOld
  458.         CASE "G"
  459.             IF Monitor% = 1 THEN GOTO Wait1
  460.             IF GridFlag% = 0 THEN GridFlag% = 1 ELSE GridFlag% = 0
  461.             LastGridFlag% = GridFlag%
  462.             UseColor LtGreen%
  463.             LOCATE GRow%, 50
  464.             IF GridFlag% = 0 THEN PRINT "OFF";  ELSE PRINT "ON";
  465.             UseColor Cyan%
  466.             PRINT "] ";
  467.             GOTO Wait1
  468.         CASE "L"
  469.             PrintFlag% = PrintFlag% * -1
  470.             IF PrintFlag% = -1 THEN
  471.                 IF Pages% > 0 OR Lines% > 0 THEN LPRINT CHR$(12);
  472.                 Pages% = 0
  473.                 Lines% = 0
  474.                 LOCATE 12, 75
  475.                 UseColor Cyan%
  476.                 PRINT "OFF]";
  477.             ELSE
  478.                 LOCATE 12, 75
  479.                 UseColor LtGreen%
  480.                 PRINT "ON";
  481.                 UseColor Cyan%
  482.                 PRINT "] ";
  483.                 NodeFlag% = 1
  484.                 LOCATE NodeRow%, 67
  485.                 UseColor LtGreen%
  486.                 PRINT "ON";
  487.                 UseColor Cyan%
  488.                 PRINT "] ";
  489.             END IF
  490.             GOTO Wait1
  491.         CASE "M"
  492.             IF INSTR(CommandLine$, "/EUR") = 0 THEN
  493.                 CommandLine$ = "/EUR"
  494.             ELSE
  495.                 CommandLine$ = ""
  496.             END IF
  497.             LoadFlag% = 0
  498.             GOTO LoadMap
  499.         CASE "N"
  500.             IF NodeFlag% = 0 THEN NodeFlag% = 1 ELSE NodeFlag% = 0
  501.             LOCATE NodeRow%, 67
  502.             UseColor LtGreen%
  503.             IF NodeFlag% = 0 THEN PRINT "OFF";  ELSE PRINT "ON";
  504.             UseColor Cyan%
  505.             PRINT "] ";
  506.             GOTO Wait1
  507.         CASE "O"
  508.             CLS
  509.             LOCATE 3, 1
  510.             PRINT "The Space Shuttle orbit decays approximately one nautical mile"
  511.             PRINT "per day. The Decay Factor can be used to adjust for that factor."
  512.             PRINT "You may enter values from 0.99 to 1.10"
  513.             PRINT : PRINT
  514.             PRINT USING "Decay Factor:  ###.####"; Decay
  515.             PRINT
  516.             PRINT "Enter new DECAY or RETURN: ";
  517.             LINE INPUT K$
  518.             IF K$ = "" THEN GOTO Begin
  519.             Decay = VAL(K$)
  520.             IF Decay < .99 OR Decay > 1.1 THEN Decay = 1
  521.             GOTO Begin
  522.         CASE "R"
  523. ResumeOld:
  524.             IF LastMission$ = "" THEN
  525.                 ClearLine 23
  526.                 UseColor LtRed%
  527.                 PRINT "No previously saved data! Use 'E' command to enter data."
  528.                 UseColor Yellow%
  529.                 PRINT "Press any key to continue ..."; CHR$(7);
  530.                 WaitForKey (K$)
  531.                 GOTO Begin
  532.             END IF
  533.             DemoFlag% = 0
  534.             GridFlag% = LastGridFlag%
  535.             Mission$ = LastMission$
  536.             OrbitTime = LastOrbitTime
  537.             OrbitIncl = LastOrbitIncl
  538.             IF AdjustFlag% = 0 THEN
  539.                 AdjustLongitude = LastAdjustL
  540.                 AdjustTime = LastAdjustT
  541.             END IF
  542.             LDate = LastLDate
  543.             LDate$ = JD2DMY$(Day%, Month%, Year%, LDate, FracDay)
  544.             LTime = LastLTime
  545.             LTime$ = TimeStr(LTime, 0, 1, "0")
  546.             CTime = SystemTime(H%, M%, Secs%, CTime$)
  547.             CDate = SystemDate(Day%, Month%, Year%, CDate$)
  548.             Fast% = 1
  549.             SCREEN ScreenNum%
  550.             GOTO Restart
  551.         CASE "S"
  552.             SCREEN 0: CLS
  553.             UseColor LtRed%
  554.             PRINT "Enter 'EXIT' to return to STSORBIT"
  555.             SHELL
  556.             GOTO Begin
  557.         CASE "T"
  558.             IF Monitor% = 1 THEN GOTO Wait1
  559.             TrackStn% = TrackStn% * -1
  560.             UseColor LtGreen%
  561.             LOCATE TrackRow%, 52
  562.             IF TrackStn% = -1 THEN PRINT "OFF";  ELSE PRINT "ON";
  563.             UseColor Cyan%
  564.             PRINT "] ";
  565.             GOTO Wait1
  566.         CASE ELSE
  567.             PRINT CHR$(7)
  568.             GOTO Wait1
  569.     END SELECT
  570.     
  571. '       *************************************
  572. '       *  Adjust Orbital Longitude & Time  *
  573. '       *************************************
  574.  
  575. Adjust:
  576.     GOSUB ShowTitle
  577.       
  578.     IF Mission$ = "" THEN
  579.         ClearLine 11
  580.         UseColor LtRed%
  581.         PRINT "No orbital data available! (Use E or R command)"
  582.         LOCATE 12, 1
  583.         UseColor Yellow%
  584.         PRINT "Press any key to continue ..."
  585.         WaitForKey (K$)
  586.         GOTO Begin
  587.     END IF
  588.  
  589.     UseColor Yellow%
  590.     LOCATE 24, 3
  591.     PRINT "Press RETURN to leave an item unchanged ...";
  592.        
  593.     LOCATE 13, 1
  594.     UseColor Green%
  595.     PRINT "Enter LAUNCH DATE (MM/DD/YYYY)";
  596.     PRINT "  ["; LDate$; "]:    ";
  597.     X% = POS(0)
  598.     LOCATE 13, X%
  599.     Temp = InputDMY(Flag%, CDate)
  600.     IF Flag% > 0 THEN
  601.         LDate = Temp
  602.         LDate$ = JD2DMY$(Day%, Month%, Year%, LDate, FracDay)
  603.     END IF
  604.     UseColor Yellow%
  605.     LOCATE 13, X%: PRINT LDate$
  606.        
  607.     UseColor Cyan%
  608.     LOCATE 15, 3
  609.     PRINT "[Use launch time corresponding to your LOCAL TIME]";
  610.     UseColor Green%
  611.     LOCATE 14, 1
  612.     PRINT "Enter LAUNCH TIME (HH:MM:SS)      ";
  613.     PRINT "["; TimeStr$(LTime, 0, 1, "0"); "]:    ";
  614.     X% = POS(0)
  615.     XTime = InputHMS(Flag%) * 3600
  616.     IF Flag% <> 0 THEN LTime = XTime
  617.     LOCATE 14, X%: UseColor Yellow%
  618.     PRINT TimeStr$(LTime, 0, 1, "0")
  619.     ClearLine 15
  620.        
  621.     UseColor Cyan%
  622.     LOCATE 16, 3
  623.     PRINT "[Add 'km' for altitude in kilometers.]";
  624.     UseColor Green%
  625.     LOCATE 15, 1
  626.     PRINT "Enter ORBITAL ALTITUDE (nm)        ";
  627.     GOSUB ConvOrbitTime
  628.     PRINT USING "[####.##]:  "; OrbitAlt;
  629.     X% = POS(0)
  630.     LINE INPUT "", K$
  631.     K$ = UCASE$(K$)
  632.     IF LEN(K$) > 0 THEN
  633.         OrbitAlt = VAL(K$)
  634.         IF INSTR(K$, "K") THEN OrbitAlt = OrbitAlt * KM2NM
  635.         GOSUB ConvOrbitAlt
  636.         OrbitTime = OrbitTime * 60#
  637.     END IF
  638.     GOSUB ConvOrbitTime
  639.     LOCATE 15, X%: UseColor Yellow%
  640.     PRINT USING "#####.## nm"; OrbitAlt;
  641.     PRINT USING "  (#####.## km)"; OrbitAlt / KM2NM;
  642.     ClearLine 16
  643.        
  644.     UseColor Green%
  645.     LOCATE 16, 1
  646.     PRINT "Enter LONGITUDE adjust (deg)      ";
  647.     PRINT USING "[####.###]:  "; AdjustLongitude;
  648.     X% = POS(0)
  649.     LINE INPUT "", K$
  650.     IF LEN(K$) > 0 THEN AdjustLongitude = VAL(K$)
  651.     LOCATE 16, X%: UseColor Yellow%
  652.     PRINT USING "####.###"; AdjustLongitude;
  653.        
  654.     UseColor Green%
  655.     LOCATE 17, 1
  656.     PRINT "Enter TIME adjust (min)            ";
  657.     PRINT USING "[###.###]:  "; AdjustTime / 60#;
  658.     X% = POS(0)
  659.     LINE INPUT K$
  660.     IF LEN(K$) > 0 THEN
  661.         AdjustTime = VAL(K$)
  662.         AdjustTime = AdjustTime * 60#
  663.     END IF
  664.     LOCATE 17, X%: UseColor Yellow%
  665.     PRINT USING "####.###"; AdjustTime / 60#;
  666.        
  667.     ClearLine 24
  668.     UseColor Yellow%
  669.     LOCATE 21, 1
  670.     PRINT "Press RETURN to accept data, any other key to start over: ";
  671. Adjust1:
  672.     K$ = INKEY$
  673.     IF LEN(K$) = 0 THEN GOTO Adjust1
  674.     IF K$ <> CHR$(13) THEN GOTO Adjust
  675.  
  676.     AdjustFlag% = 1
  677.     SCREEN ScreenNum%
  678.     GOTO Restart
  679.  
  680. '       ***********************
  681. '       *  Manual Data Entry  *
  682. '       ***********************
  683.  
  684. Manual:
  685.     AdjustLongitude = 0
  686.     AdjustTime = 0
  687.     GOSUB ShowTitle1
  688.     LOCATE 11, 1
  689.     UseColor Green%
  690.     PRINT "Enter mission title:            ";
  691.     X% = POS(0)
  692.     INPUT "", Mission$
  693.     Mission$ = UCASE$(Mission$)
  694.     IF LEN(Mission$) > 23 THEN
  695.         Mission$ = LEFT$(Mission$, 23)
  696.         ClearLine 11
  697.         UseColor Green%
  698.         PRINT "Enter mission title:            ";
  699.     END IF
  700.     IF Mission$ = "" THEN Mission$ = "STS Mission Simulation"
  701.     UseColor Yellow%
  702.     LOCATE 11, X%: PRINT Mission$
  703.  
  704. Wait2:
  705.     CTime = SystemTime(H%, M%, Secs%, CTime$)
  706.     Center "Current time: " + CTime$, 8, 1, 80
  707.     UseColor Cyan%
  708.     LOCATE 13, 3
  709.     PRINT "[Add 'km' for altitude in kilometers.]";
  710.     UseColor Green%
  711.     LOCATE 12, 1
  712.     PRINT "Enter orbit altitude (nm):     ";
  713.     X% = POS(0)
  714.     LINE INPUT "", OrbitAlt$
  715.     IF OrbitAlt$ = "" THEN
  716.         OrbitAlt = 160
  717.     ELSE
  718.         OrbitAlt$ = UCASE$(OrbitAlt$)
  719.         OrbitAlt = VAL(OrbitAlt$)
  720.         IF INSTR(OrbitAlt$, "K") THEN OrbitAlt = OrbitAlt * KN2NM
  721.     END IF
  722.     GOSUB ConvOrbitAlt
  723.     UseColor Yellow%
  724.     TOT = OrbitTime
  725.     OrbitTime = TOT * 60
  726.     GOSUB ConvOrbitTime
  727.     OrbitTime = TOT
  728.     LOCATE 12, X%
  729.     PRINT USING "#####.## nm"; OrbitAlt;
  730.     PRINT USING "  (#####.## km)"; OrbitAlt / KM2NM;
  731. Wait3:
  732.     CTime = SystemTime(H%, M%, Secs%, CTime$)
  733.     Center "Current time: " + CTime$, 8, 1, 80
  734.     ClearLine 13
  735.     UseColor Green%
  736.     PRINT "Enter orbit inclination (deg):  ";
  737.     X% = POS(0)
  738.     LINE INPUT "", OrbitIncl$
  739.     IF OrbitIncl$ = "" THEN OrbitIncl$ = "28.45"
  740.     OrbitIncl = VAL(OrbitIncl$)
  741.     UseColor Yellow%
  742.     LOCATE 13, X%
  743.     PRINT USING "####.### degrees"; OrbitIncl
  744.     MaxIncl = 70
  745.     IF OrbitIncl > MaxIncl THEN
  746.         LOCATE 14, 1
  747.         PRINT "  Maximum inclination for this program is "; MaxIncl - 5; " degrees"
  748.         PRINT CHR$(7)
  749.         ClearLine 13
  750.         GOTO Wait3
  751.     END IF
  752.  
  753. Wait4:
  754.     CTime = SystemTime(H%, M%, Secs%, CTime$)
  755.     CDate = SystemDate(Day%, Month%, Year%, CDate$)
  756.     Center "Current time: " + CTime$, 8, 1, 80
  757.     CDate = SystemDate(Day%, Month%, Year%, CDate$)
  758.     LOCATE 14, 1
  759.     UseColor Green%
  760.     PRINT "Enter Launch Date (MM/DD/YYYY): ";
  761.     X% = POS(0)
  762.     UseColor Cyan%
  763.     LOCATE 15, 2: PRINT "[or press RETURN for TODAY]";
  764.     UseColor Green%
  765.     LOCATE 14, X%
  766.     LDate = InputDMY(TimeFlag%, CDate)
  767.     LDate$ = JD2DMY$(Day%, Month%, Year%, LDate, FracDay)
  768.     IF TimeFlag% = 0 THEN
  769.         LDate = SystemDate(Day%, Month%, Year%, LDate$)
  770.     END IF
  771.     UseColor Yellow%
  772.     LOCATE 14, X%: PRINT LDate$
  773.  
  774. Wait5:
  775.     CTime = SystemTime(H%, M%, Secs%, CTime$)
  776.     Center "Current time: " + CTime$, 8, 1, 80
  777.     LOCATE 15, 1
  778.     UseColor Green%
  779.     PRINT "Enter Launch Time (HH:MM:SS):   ";
  780.     X% = POS(0)
  781.     UseColor Cyan%
  782.     LOCATE 16, 2: PRINT "[or press RETURN for ASAP]";
  783.     UseColor Green%
  784.     LOCATE 15, X%
  785.     LTime = InputHMS(TimeFlag%)
  786.     LTime = LTime * 3600
  787.     IF TimeFlag% = 0 THEN
  788.         LTime = SystemTime(Hours%, Mins%, Secs%, LTime$) + Delay%
  789.     END IF
  790.     LTime$ = TimeStr(LTime, 0, 1, "0")
  791.     UseColor Yellow%
  792.     LOCATE 15, X%: PRINT LTime$
  793.  
  794. Wait6:
  795.     TTime = INT(SystemTime(Hours%, Mins%, Secs%, TTime$))
  796.     IF CDate <> LDate OR TTime > LTime THEN GOTO Wait7
  797.     CTime = SystemTime(H%, M%, Secs%, CTime$)
  798.     Center "Current time: " + CTime$, 8, 1, 80
  799.     UseColor Green%
  800.     LOCATE 16, 1
  801.     LINE INPUT "Normal or fast time (N,f):      ", K$
  802.     IF K$ = "" THEN K$ = "N"
  803.     K$ = UCASE$(K$)
  804.     SELECT CASE K$
  805.         CASE "F"
  806.             Fast% = 10
  807.         CASE "N"
  808.             Fast% = 1
  809.         CASE ELSE
  810.             PRINT CHR$(7)
  811.             GOTO Wait6
  812.     END SELECT
  813.        
  814. Wait7:
  815.     OrbitTime = OrbitTime * 60#
  816.     SCREEN ScreenNum%
  817.     GOTO Restart
  818.  
  819. '       *************************************
  820. '       *  Set Parameters for Program Demo  *
  821. '       *************************************
  822.  
  823. Demo:
  824.     Duration = 0
  825.     OrbitTime = 90# * 60#
  826.     OrbitIncl = 28#
  827.     Mission$ = "STS-29 Discovery (DEMO)"
  828.     AdjustFlag% = 0
  829.     AdjustLongitude = 0
  830.     AdjustTime = 0
  831.     Fast% = 1
  832.     LTime = INT((SystemTime(Hours%, Mins%, Secs%, LTime$) + Delay%) / 10#) * 10#
  833.     LDate = SystemDate(Day%, Month%, Year%, LDate$)
  834.     CDate = LDate
  835.  
  836. '       **********************************
  837. '       *  Initialize Plot & Parameters  *
  838. '       **********************************
  839.  
  840. Restart:
  841.     CLS : LOCATE 1, 1, 0
  842.     LLongitude = -80.7#
  843.     LLatitude = 28.47#
  844.     RadiansPerSecond = TwoPI / OrbitTime
  845.     GOSUB ConvOrbitTime
  846.     IF OrbitIncl <= LLatitude THEN
  847.         DeltaOrbit = HalfPI
  848.     ELSE
  849.         UseColor LtGreen%
  850.         Center "Calculating Initial Launch Trajectory", 5, 1, 80
  851.         UseColor LtRed%
  852.         Center "Please wait ...", 8, 1, 80
  853.         CLatitude = 0
  854.         DeltaOrbit = 0
  855.         CalcTime = 0
  856.         IF Monitor% = 2 OR Monitor% = 3 THEN Delta = .005 ELSE Delta = .01
  857.         WHILE CLatitude < LLatitude
  858.             GOSUB CalcPosition
  859.             DeltaOrbit = DeltaOrbit - Delta
  860.         WEND
  861.         CLS
  862.     END IF
  863.     Count = 0
  864.        
  865.     GOSUB ShowGrid
  866.     GOSUB ShowMap
  867.       
  868. '       Clear XSpots array
  869.  
  870.     FOR N% = 0 TO NSpots% - 1
  871.         XSpots%(N%) = -1
  872.     NEXT N%
  873.  
  874.        
  875. '       **********************************
  876. '       *  Catch up if past launch time  *
  877. '       **********************************
  878.  
  879.     Duration = AdjustTime
  880.     WaitFlag% = 1
  881.     TTime = INT(SystemTime(Hours%, Mins%, Secs%, TTime$))
  882.     IF CDate < LDate OR (CDate = LDate AND TTime <= LTime) THEN
  883.         GOSUB PlotPredicted
  884.         GOSUB ShowTitles
  885.         GOTO Sync1
  886.     END IF
  887.        
  888.     CDays = CDate - LDate
  889.     Duration = CDays * 86400# + TTime - LTime
  890.     IF Duration > 7200# THEN
  891.         Duration = Duration - 7200#
  892.     ELSE
  893.         Duration = 0
  894.     END IF
  895.     IF TTime - LTime < 0 THEN CDays = CDays - 1
  896.        
  897.     Duration = INT(Duration / 60#) * 60#
  898.     STime = Mod86400(LTime + Duration)
  899.     SDate = LDate + INT((LTime + Duration) / 86400)
  900.        
  901.     METime$ = TimeStr(Duration, 0, 1, "0")
  902.     CTime$ = TimeStr(TTime, 0, 1, "0")
  903.     STime$ = TimeStr(STime, 0, 1, "0")
  904.     SDate$ = JD2DMY$(D%, M%, Y%, SDate, FracDay)
  905.     CalcTime = Duration
  906.     GOSUB CalcPosition
  907.     GOSUB PlotPredicted
  908.     WaitFlag% = 0
  909.     GOSUB ShowTitles
  910.  
  911.     AddInterval% = MarkerInterval
  912.     CatchFlag% = 1
  913.     Fast% = 1
  914.  
  915. CatchUp:
  916.     K$ = UCASE$(INKEY$)
  917.     IF K$ = CHR$(13) THEN GOTO Begin
  918.     IF K$ = "P" THEN
  919.         WHILE LEN(INKEY$) = 0: WEND
  920.     END IF
  921.     TTime = INT(SystemTime(Hours%, Mins%, Secs%, TTime$))
  922.     IF CDate = SDate AND STime + 3 * AddInterval% > TTime THEN
  923.         IF AddInterval% = PlotInterval% THEN AddInterval% = 1
  924.         IF AddInterval% = MarkerInterval THEN AddInterval% = PlotInterval%
  925.     END IF
  926.        
  927.     Duration = Duration + AddInterval%
  928.     STime = STime + AddInterval%
  929.     IF STime >= 86400# THEN
  930.         CDays = CDays + 1
  931.         SDate = SDate + 1
  932.         STime = Mod86400(STime)
  933.     END IF
  934.     METime$ = TimeStr(Duration, 0, 1, "0")
  935.     CTime$ = TimeStr(TTime, 0, 1, "0")
  936.     STime$ = TimeStr(STime, 0, 1, "0")
  937.     SDate$ = JD2DMY$(D%, M%, Y%, SDate, FracDay)
  938.     CalcTime = Duration
  939.     GOSUB CalcPosition
  940.     GOSUB ShowData
  941.     GOSUB DoPlot
  942.        
  943.     IF SDate = CDate AND STime >= TTime THEN
  944.         CatchFlag% = 0
  945.         CTime = SystemTime(H%, M%, Secs%, CTime$)
  946.         CDate = SystemDate(Day%, Month%, Year%, CDate$)
  947.         STime = CTime
  948.         SDate = CDate
  949.         CDays = CDate - LDate
  950.         Duration = CTime - LTime + CDays * 86400#
  951.         Fast% = 1
  952.         GOTO Sync3
  953.     END IF
  954.     GOTO CatchUp
  955.  
  956. '       **********************
  957. '       *  Begin simulation  *
  958. '       **********************
  959.  
  960. Sync1:
  961.     IF INKEY$ = CHR$(13) THEN GOTO Begin
  962.     TTime = SystemTime(Hours%, Mins%, OldSecs%, TTime$)
  963. Sync2:
  964.     TTime = SystemTime(Hours%, Mins%, Secs%, TTime$)
  965.     IF Secs% = OldSecs% THEN GOTO Sync2
  966.     IF CDate <> LDate OR TTime < LTime THEN
  967.         CTime = SystemTime(H%, M%, OldSecs%, CTime$)
  968.         CDate = SystemDate(Day%, Month%, Year%, CDate$)
  969.         LTime$ = TimeStr(LTime, 0, 1, "0")
  970.         METime$ = TimeStr(LTime - TTime, 0, 1, "0")
  971.         GOSUB ShowData
  972.         GOTO Sync1
  973.     END IF
  974.        
  975. Sync3:
  976.     WaitFlag% = 0
  977.     CalcTime = Duration
  978.     GOSUB CalcPosition
  979.     GOSUB ShowTitles
  980.     GOSUB ShowData
  981.     GOSUB DoPlot
  982.     PRINT CHR$(7);
  983.        
  984. '       ***********************
  985. '       *  Main Program Loop  *
  986. '       ***********************
  987.  
  988. Recalculate:
  989.     IF Blink% = -1 THEN GOTO Recal1
  990.  
  991. '       Flash shuttle icon if CGA or HGC
  992.  
  993.     ChkTime = TIMER
  994.     IF ChkTime - INT(ChkTime) < .2 AND SaveFlag% = 1 AND CatchFlag% = 0 THEN
  995.         GOSUB RestoreMap
  996.         DO
  997.             WaitTime = TIMER - ChkTime
  998.         LOOP UNTIL WaitTime > .3
  999.         GOSUB DrawShuttle
  1000.     END IF
  1001.  
  1002. Recal1:
  1003.     CTime = INT(SystemTime(Hours%, M%, Secs%, CTime$))
  1004.     CDate = SystemDate(Day%, Month%, Year%, CDate$)
  1005.     IF Secs% = OldSecs% THEN GOTO Recalculate
  1006.     OldSecs% = Secs%
  1007.     IF Hours% < OldHours% THEN
  1008.         CDays = CDays + 1
  1009.     END IF
  1010.     OldHours% = Hours%
  1011.     Duration = Duration + Fast%
  1012.     METime$ = TimeStr(Duration, 0, 1, "0")
  1013.     STime = LTime + Duration MOD 86400#
  1014.     STime$ = TimeStr(STime, 0, 1, "0")
  1015.     SDate = LDate + INT((LTime + Duration) / 86400#)
  1016.     SDate$ = JD2DMY$(D%, M%, Y%, SDate, FracDay)
  1017.     GOSUB DoPlot
  1018.  
  1019. '       *******************************
  1020. '       *  Test for Operator Request  *
  1021. '       *******************************
  1022.  
  1023. TestKeyboard:
  1024.     K$ = UCASE$(INKEY$)
  1025.     IF LEN(K$) = 0 THEN GOTO Recalculate
  1026.     SELECT CASE K$
  1027.         CASE CHR$(13)
  1028.             GOTO Begin
  1029.         CASE "B"
  1030.             Blink% = Blink% * -1
  1031.         CASE "C"
  1032.             CLS
  1033.             GOSUB ShowGrid
  1034.             GOSUB ShowMap
  1035.             GOSUB ShowTitles
  1036.         CASE "F"
  1037.             LOCATE TRow%, 70
  1038.             UseColor LtGreen%
  1039.             PRINT "MET";
  1040.             IF Fast% = 60 THEN
  1041.                 Fast% = 1
  1042.                 PRINT SPACE$(6);
  1043.             ELSEIF Fast% = 1 THEN
  1044.                 Fast% = 10
  1045.                 Duration = INT(Duration / 10!) * 10!
  1046.                 UseColor LtRed%
  1047.                 PRINT " (x10)";
  1048.             ELSE
  1049.                 Fast% = 60
  1050.                 Duration = INT(Duration / 60!) * 60!
  1051.                 UseColor LtRed%
  1052.                 PRINT " (x60)";
  1053.             END IF
  1054.         CASE "L"
  1055.             PrintFlag% = PrintFlag% * -1
  1056.             UseColor LtRed%
  1057.             IF PrintFlag% = 1 THEN
  1058.                 LOCATE TRow% + 1, 77: PRINT "LOG";
  1059.             ELSE
  1060.                 LOCATE TRow% + 1, 77: PRINT "   ";
  1061.             END IF
  1062.             IF PrintFlag% = -1 THEN
  1063.                 LPRINT CHR$(12);
  1064.                 Pages% = 0
  1065.                 Lines% = 0
  1066.             END IF
  1067.             GOTO TestKeyboard
  1068.         CASE "P"
  1069.             LOCATE TRow% + 4, 42
  1070.             UseColor LtMagenta%
  1071.             PRINT ">> PAUSE: Press any key ...  <<     ";
  1072.             CTime = SystemTime(H%, M%, OldSecs%, CTime$)
  1073.             DO UNTIL LEN(INKEY$) <> 0
  1074.                 CTime = SystemTime(H%, M%, Secs%, CTime$)
  1075.                 CDate = SystemDate(Day%, Month%, Year%, CDate$)
  1076.                 IF Secs% <> OldSecs% THEN
  1077.                     OldSecs% = Secs%
  1078.                     UseColor Yellow%
  1079.                     LOCATE TRow% + 4, 17
  1080.                     PRINT CDate$; SPACE$(2); CTime$;
  1081.                 END IF
  1082.             LOOP
  1083.             LOCATE TRow% + 4, 42
  1084.             UseColor LtRed%
  1085.             PRINT ">> RETURN=STOP  F=FAST  P=PAUSE <<";
  1086.         CASE "R"
  1087.             STime = CTime
  1088.             SDate = CDate
  1089.             CDays = CDate - LDate
  1090.             Duration = CTime - LTime + CDays * 86400#
  1091.             Fast% = 1
  1092.         CASE ELSE
  1093.             'PRINT CHR$(7);
  1094.             GOTO TestKeyboard
  1095.     END SELECT
  1096.     GOTO Recalculate
  1097.  
  1098. '       ************************************
  1099. '       *  DoPlot:  Plot Orbit and Shuttle *
  1100. '       ************************************
  1101.  
  1102. RestoreMap:
  1103.  
  1104. '       Restore prior pixels (except first time)
  1105.  
  1106.     IF SaveFlag% = 0 THEN RETURN
  1107.     FOR N% = 0 TO 16
  1108.         PSET (MapLon% + N% - 8, MapLat%), Map%(N%)
  1109.     NEXT N%
  1110.     PSET (MapLon% - 8, MapLat% - 1), Map%(17)
  1111.     PSET (MapLon% - 9, MapLat% - 1), Map%(18)
  1112.     PSET (MapLon% - 9, MapLat% - 2), Map%(19)
  1113.     PSET (MapLon% - 10, MapLat% - 2), Map%(20)
  1114.     IF Monitor% = 1 THEN RETURN
  1115.     FOR N% = 0 TO 15
  1116.         PSET (MapLon% + N% - 7, MapLat% + 1), Map%(N% + 21)
  1117.     NEXT N%
  1118.     RETURN
  1119.  
  1120. DrawShuttle:
  1121.  
  1122. '       Draw shuttle symbol at current position
  1123.  
  1124.     FOR N% = 0 TO 16
  1125.         PSET (MapLon% + N% - 8, MapLat%), ShuttleColor%
  1126.     NEXT N%
  1127.     PSET (MapLon% - 8, MapLat% - 1), ShuttleColor%
  1128.     PSET (MapLon% - 9, MapLat% - 1), ShuttleColor%
  1129.     PSET (MapLon% - 9, MapLat% - 2), ShuttleColor%
  1130.     PSET (MapLon% - 10, MapLat% - 2), ShuttleColor%
  1131.     IF Monitor% = 1 THEN RETURN
  1132.     FOR N% = 0 TO 15
  1133.         PSET (MapLon% + N% - 7, MapLat% + 1), ShuttleColor%
  1134.     NEXT N%
  1135.     RETURN
  1136.  
  1137. DoPlot:
  1138.     CalcTime = Duration
  1139.     GOSUB CalcPosition
  1140.     IF NodeFlag% = 1 THEN GOSUB CheckNodes
  1141.        
  1142.     IF Duration MOD PlotInterval% <> 0 THEN GOTO ShowNumbers
  1143.     
  1144.     GOSUB RestoreMap
  1145.      
  1146.     IF Duration MOD MarkerInterval <> 0 THEN GOTO ShowShuttle
  1147.  
  1148. '       Change trailing spots from green to red
  1149.  
  1150.     IF Monitor% > 1 THEN
  1151.         N% = Count MOD NSpots%
  1152.         PSET (XSpots%(N%), YSpots%(N%)), LtRed%
  1153.         PSET (XSpots%(N%) + 1, YSpots%(N%)), LtRed%
  1154.     END IF
  1155.  
  1156. '       Remove plotted orbit SpotsBehind back
  1157.       
  1158.     IF Count >= SpotsBehind% THEN
  1159.         N% = (Count - SpotsBehind%) MOD NSpots%
  1160.         PSET (XSpots%(N%), YSpots%(N%)), CSpots%(N%) AND &HF
  1161.         PSET (XSpots%(N%) + 1, YSpots%(N%)), (CSpots%(N%) AND &HF0) / 16
  1162.     END IF
  1163.  
  1164. '       Plot predicted orbit SpotsAhead forward
  1165.  
  1166.     N% = (Count + SpotsAhead%) MOD NSpots%
  1167.     CalcTime = Duration + SpotsAhead% * MarkerInterval
  1168.     GOSUB CalcPosition
  1169.     OverWrite% = POINT(X%, Y%) + 16 * POINT(X% + 1, Y%)
  1170.     FOR M% = 1 TO SpotsAhead% - 1
  1171.         L% = (N% + M%) MOD NSpots%
  1172.         IF XSpots%(L%) = X% THEN
  1173.             IF YSpots%(L%) = Y% THEN
  1174.                 OverWrite% = CSpots%(L%)
  1175.                 EXIT FOR
  1176.             END IF
  1177.         END IF
  1178.     NEXT M%
  1179.     XSpots%(N%) = X%
  1180.     YSpots%(N%) = Y%
  1181.     CSpots%(N%) = OverWrite%
  1182.     PSET (X%, Y%), LtGreen%
  1183.     PSET (X% + 1, Y%), LtGreen%
  1184.     Count = Count + 1
  1185.     CalcTime = Duration
  1186.     GOSUB CalcPosition
  1187.  
  1188. ShowShuttle:
  1189.    
  1190. '       Save pixels under shuttle symbol
  1191.  
  1192.     SaveFlag% = 1
  1193.     FOR N% = 0 TO 16
  1194.         Map%(N%) = POINT(X% + N% - 8, Y%)
  1195.     NEXT N%
  1196.     Map%(17) = POINT(X% - 8, Y% - 1)
  1197.     Map%(18) = POINT(X% - 9, Y% - 1)
  1198.     Map%(19) = POINT(X% - 9, Y% - 2)
  1199.     Map%(20) = POINT(X% - 10, Y% - 2)
  1200.     IF Monitor% > 1 THEN
  1201.         FOR N% = 0 TO 15
  1202.             Map%(N% + 21) = POINT(X% + N% - 7, Y% + 1)
  1203.         NEXT N%
  1204.     END IF
  1205.       
  1206.     MapLon% = X%    'Save map coords for next time
  1207.     MapLat% = Y%
  1208.     GOSUB DrawShuttle
  1209.  
  1210.     'CalcTime = Duration
  1211.     'GOSUB CalcPosition
  1212.  
  1213. ShowNumbers:
  1214.     METime$ = TimeStr(Duration, 0, 1, "0")
  1215.     GOSUB ShowData
  1216.     RETURN
  1217.  
  1218. '       **********************************************
  1219. '       *  CalcPosition: Calculate Current Position  *
  1220. '       **********************************************
  1221.  
  1222. CalcPosition:
  1223.     IF CalcTime > 10000 THEN
  1224.         CalcTime = CalcTime + AdjustTime
  1225.     ELSEIF CalcTime >= 480 THEN
  1226.         CalcTime = CalcTime + AdjustTime * CalcTime / 10000
  1227.     END IF
  1228.     IF CalcTime >= 480# THEN
  1229.         CalcTime = CalcTime - 240#
  1230.         TLongitude = LLongitude - 5#
  1231.     ELSE
  1232.         TLongitude = LLongitude - CalcTime / 96#
  1233.         CalcTime = CalcTime - SIN(CalcTime / 480# * HalfPI) * 240#
  1234.     END IF
  1235.     OrbitAngle = -CalcTime * RadiansPerSecond * Decay
  1236.     OLongitude = TLongitude - OrbitAngle * Rad2Deg
  1237.     CLongitude = OLongitude - (CalcTime - AdjustTime) / 3600# * 15# + AdjustLongitude
  1238.        
  1239. '       Added code for J2 Perturbations
  1240.  
  1241.     K1 = ERadius2 * ((ERadius + OrbitAlt) / 1000#) ^ -3.5 * SqrMu1
  1242.     N1 = -1.5 * K1 * .001082616# * COS(OrbitIncl * Deg2Rad)
  1243.     N1 = N1 * Rad2Deg * CalcTime
  1244.     CLongitude = CLongitude + N1
  1245.  
  1246.     CLongitude = Mod360(CLongitude)
  1247.     IF CLongitude > 180# THEN CLongitude = CLongitude - 360#
  1248.     OrbitNum = INT(-(OrbitAngle + DeltaOrbit) / TwoPI * 100) / 100 + 1.5
  1249.     X% = Mod360(CLongitude + AdjEUROPE%) / 360 * 640
  1250.     CLatitude = SIN(OrbitAngle + DeltaOrbit) * OrbitIncl
  1251.     IF CalcTime < 30 * MarkerInterval AND LLatitude > OrbitIncl THEN
  1252.         LatFactor! = CalcTime / (30 * MarkerInterval)
  1253.         CLatitude = CLatitude + (1 - LatFactor!) * (LLatitude - OrbitIncl)
  1254.     END IF
  1255.     Y% = Equator% - CLatitude * VFactor! / 2
  1256.     RETURN
  1257.        
  1258. CheckNodes:
  1259.     DeltaT = Duration - LDuration
  1260.     IF CLatitude - LLat = 0 THEN
  1261.         Ratio = 0
  1262.     ELSE
  1263.         Ratio = CLatitude / (CLatitude - LLat)
  1264.     END IF
  1265.     IF CLatitude >= 0 AND PLatitude < 0 THEN
  1266.         ANLongitude = CLongitude - (CLongitude - LLong) * Ratio
  1267.         ANTime = Duration - DeltaT * Ratio
  1268.         ANDays = INT(ANTime / 86400#)
  1269.         ANOrbit = OrbitNum
  1270.         PLatitude = CLatitude
  1271.     END IF
  1272.     IF CLatitude < 0 AND PLatitude >= 0 THEN
  1273.         DNLongitude = CLongitude - (CLongitude - LLong) * Ratio
  1274.         DNTime = Duration - DeltaT * Ratio
  1275.         DNDays = INT(DNTime / 86400#)
  1276.         DNOrbit = OrbitNum
  1277.         PLatitude = CLatitude
  1278.     END IF
  1279.     LLat = CLatitude
  1280.     LLong = CLongitude
  1281.     LDuration = Duration
  1282.     RETURN
  1283.  
  1284. '       **********************************
  1285. '       *  ShowTitles: Show Data Titles  *
  1286. '       **********************************
  1287.  
  1288. ShowTitles:
  1289.     TitleFlag% = 0
  1290.     UseColor Cyan%
  1291.     LOCATE TRow%, 1
  1292.     PRINT " Mission:"
  1293.     PRINT " Orbit:"
  1294.     PRINT " Launch Date:"
  1295.     PRINT " Simul Date:";
  1296.     LOCATE TRow% + 4, 1
  1297.     PRINT " Local Date:";
  1298.     LOCATE TRow%, 42: PRINT "Mission Time:";
  1299.     UseColor LtRed%
  1300.     LOCATE TRow% + 4, 42: PRINT ">> RETURN=STOP  F=FAST  P=PAUSE <<";
  1301.     IF WaitFlag% = 1 THEN RETURN
  1302.     UseColor Cyan%
  1303.     LOCATE TRow% + 1, 42: PRINT "Orbit Number:";
  1304.     LOCATE TRow% + 2, 42: PRINT "Longitude (deg):";
  1305.     LOCATE TRow% + 3, 42: PRINT "Latitude (deg):";
  1306.     UseColor LtRed%
  1307.     IF PrintFlag% = 1 THEN
  1308.         LOCATE TRow% + 1, 77: PRINT "LOG";
  1309.     ELSE
  1310.         LOCATE TRow% + 1, 77: PRINT "   ";
  1311.     END IF
  1312.     RETURN
  1313.  
  1314. '       ***********************************
  1315. '       *  ShowData: Update Current Data  *
  1316. '       ***********************************
  1317.  
  1318. ShowData:
  1319.     UseColor Yellow%
  1320.     IF TitleFlag% = 1 THEN GOTO ShowData1
  1321.     LOCATE TRow%, 17: PRINT Mission$;
  1322.     LOCATE TRow% + 1, 17: PRINT USING "##.## deg"; OrbitIncl;
  1323.         'PRINT USING "  ###.## min"; OrbitTime / 60#;
  1324.     PRINT USING "   #####.## nm"; OrbitAlt;
  1325.     LOCATE TRow% + 2, 17: PRINT LDate$; SPACE$(2); LTime$;
  1326.     UseColor LtGreen%
  1327.     LOCATE TRow%, 70: PRINT "MET";
  1328.     TitleFlag% = 1
  1329. ShowData1:
  1330.     UseColor LtGreen%
  1331.     IF PriorSDate$ <> SDate$ THEN
  1332.         LOCATE TRow% + 3, 17
  1333.         PRINT SDate$;
  1334.         PriorSDate$ = SDate$
  1335.     END IF
  1336.     IF CatchFlag% = 1 THEN
  1337.         UseColor LtRed%
  1338.     ELSE
  1339.         UseColor LtGreen%
  1340.     END IF
  1341.     LOCATE TRow% + 3, 29: PRINT STime$;
  1342.     UseColor Yellow%
  1343.     IF PriorCDate$ <> CDate$ THEN
  1344.         LOCATE TRow% + 4, 17
  1345.         PRINT CDate$;
  1346.         PriorCDate$ = CDate$
  1347.     END IF
  1348.     LOCATE TRow% + 4, 29: PRINT CTime$;
  1349.     LOCATE TRow%, 57
  1350.     IF WaitFlag% = 0 OR CatchFlag% = 1 THEN
  1351.         MissionDay% = INT(Duration / 86400#)
  1352.         UseColor LtGreen%
  1353.         PRINT USING "###/"; MissionDay%;
  1354.     ELSE
  1355.         MissionDay% = CDate - LDate
  1356.         IF CTime > LTime THEN MissionDay% = MissionDay% + 1
  1357.         UseColor LtRed%
  1358.         IF MissionDay% <> 0 THEN
  1359.             PRINT USING "###/"; MissionDay%;
  1360.         ELSE
  1361.             PRINT " -0/";
  1362.         END IF
  1363.     END IF
  1364.     PRINT METime$;
  1365.     IF WaitFlag% = 1 THEN RETURN
  1366.     UseColor Yellow%
  1367.     LOCATE TRow% + 1, 58: PRINT USING "#####.##"; OrbitNum;
  1368.     LOCATE TRow% + 2, 58: PRINT USING "#####.##"; CLongitude;
  1369.     IF CLongitude >= 0 THEN PRINT "°E";  ELSE PRINT "°W";
  1370.     LOCATE TRow% + 3, 58: PRINT USING "#####.##"; CLatitude;
  1371.     IF CLatitude >= 0 THEN PRINT "°N";  ELSE PRINT "°S";
  1372.        
  1373.     IF NodeFlag% = 0 THEN RETURN
  1374.     IF PriorANTime = ANTime AND PriorDNTime = DNTime THEN RETURN
  1375.  
  1376.     NRow% = TRow% - 2
  1377.     LOCATE NRow%, 1
  1378.     ANTime$ = TimeStr(ANTime, 0, 1, "0")
  1379.     UseColor Cyan%
  1380.     PRINT " Ascend Node:";
  1381.     UseColor LtMagenta%
  1382.     PRINT USING "#### "; INT(ANOrbit);
  1383.     PRINT USING "####.## "; ANLongitude;
  1384.     PRINT USING "###/"; ANDays;
  1385.     PRINT ANTime$; " ";
  1386.     LOCATE NRow% + 1, 1
  1387.     DNTime$ = TimeStr(DNTime, 0, 1, "0")
  1388.     UseColor Cyan%
  1389.     PRINT " Dscend Node:";
  1390.     UseColor LtMagenta%
  1391.     PRINT USING "#### "; INT(DNOrbit);
  1392.     PRINT USING "####.## "; DNLongitude;
  1393.     PRINT USING "###/"; DNDays;
  1394.     PRINT DNTime$; " ";
  1395.  
  1396. '       Print Node Information if PrintFlag is Enabled
  1397.  
  1398.     IF PrintFlag% = 1 AND Lines% = 0 THEN
  1399.         LPRINT TAB(5); "STSORBIT: Space Shuttle Tracking Program, Version 9019 ";
  1400.             LPRINT TAB(70); "Page "; Pages% + 1
  1401.         LPRINT
  1402.         LPRINT TAB(5); "ORBITAL DATA for "; Mission$
  1403.         LPRINT
  1404.         IF Pages% = 0 THEN
  1405.             LPRINT TAB(15); "Launch Date:           "; LDate$
  1406.             LPRINT TAB(15); "Launch Time:           "; LTime$
  1407.             LPRINT TAB(15); "Orbit Inclination:  ";
  1408.                 LPRINT USING "#####.####°"; OrbitIncl
  1409.             LPRINT TAB(15); "Orbit Altitude:     ";
  1410.                 LPRINT USING "#####.## nm"; OrbitAlt
  1411.             LPRINT
  1412.             LPRINT TAB(15); "Adjust Longitude:   ";
  1413.                 LPRINT USING "#####.##°"; AdjustLongitude
  1414.             LPRINT TAB(15); "Adjust Orbit Time:  ";
  1415.                 LPRINT USING "#####.## min"; AdjustTime / 60
  1416.             LPRINT
  1417.             Lines% = 15
  1418.         ELSE
  1419.             Lines% = 7
  1420.         END IF
  1421.         LPRINT TAB(71); "ORBITAL"
  1422.         LPRINT TAB(5); "LOCAL DATE      TIME";
  1423.         LPRINT TAB(39); "ORBIT    LONG"; SPACE$(11); "MET        TIME"
  1424.     END IF
  1425.     IF PriorANTime <> ANTime AND ANTime > 0 AND PrintFlag% = 1 THEN
  1426.         LPRINT TAB(5);
  1427.         LPRINT SDate$; "  "; STime$;
  1428.         LPRINT "  Ascend Node: ";
  1429.         LPRINT USING "#### "; INT(ANOrbit);
  1430.         LPRINT USING "####.##° "; ANLongitude;
  1431.         LPRINT USING "###/"; ANDays;
  1432.         LPRINT ANTime$; " ";
  1433.         IF PriorANTime > 0 THEN
  1434.             Delta = ANTime - PriorANTime
  1435.             OTFrac = Delta - INT(Delta)
  1436.             LPRINT TimeStr$(Delta, 0, 1, " ");
  1437.             LPRINT USING ".##"; OTFrac
  1438.         ELSE
  1439.             LPRINT
  1440.         END IF
  1441.         Lines% = Lines% + 1
  1442.     END IF
  1443.     IF PriorDNTime <> DNTime AND DNTime > 0 AND PrintFlag% = 1 THEN
  1444.         LPRINT TAB(5);
  1445.         LPRINT SDate$; "  "; STime$;
  1446.         LPRINT "  Dscend Node: ";
  1447.         LPRINT USING "#### "; INT(DNOrbit);
  1448.         LPRINT USING "####.##° "; DNLongitude;
  1449.         LPRINT USING "###/"; DNDays;
  1450.         LPRINT DNTime$; " ";
  1451.         IF PriorDNTime > 0 THEN
  1452.             Delta = DNTime - PriorDNTime
  1453.             OTFrac = Delta - INT(Delta)
  1454.             LPRINT TimeStr$(Delta, 0, 1, " ");
  1455.             LPRINT USING ".##"; OTFrac
  1456.         ELSE
  1457.             LPRINT
  1458.         END IF
  1459.         Lines% = Lines% + 1
  1460.     END IF
  1461.     IF PrintFlag% = 1 AND Lines% >= 60 THEN
  1462.         LPRINT CHR$(12);
  1463.         Pages% = Pages% + 1
  1464.         Lines% = 0
  1465.     END IF
  1466.        
  1467.     PriorANTime = ANTime
  1468.     PriorDNTime = DNTime
  1469.     RETURN
  1470.  
  1471. '       ********************************************
  1472. '       *  Plot predicted orbit prior to "launch"  *
  1473. '       ********************************************
  1474.  
  1475. PlotPredicted:
  1476.     FOR N% = 0 TO SpotsAhead%
  1477.         CalcTime = N% * MarkerInterval + Duration
  1478.         GOSUB CalcPosition
  1479.         OverWrite% = POINT(X%, Y%) + 16 * POINT(X% + 1, Y%)
  1480.         FOR M% = 0 TO SpotsAhead% - 1
  1481.             L% = (N% + M%) MOD NSpots%
  1482.             IF XSpots%(L%) = X% THEN
  1483.                 IF YSpots%(L%) = Y% THEN
  1484.                     OverWrite% = CSpots%(L%)
  1485.                     EXIT FOR
  1486.                 END IF
  1487.             END IF
  1488.         NEXT M%
  1489.         XSpots%(N%) = X%
  1490.         YSpots%(N%) = Y%
  1491.         CSpots%(N%) = OverWrite%
  1492.         PSET (X%, Y%), LtGreen%
  1493.         PSET (X% + 1, Y%), LtGreen%
  1494.     NEXT N%
  1495.     RETURN
  1496.  
  1497. '       **********************************************
  1498. '       *  Convert Orbital Altitude to Orbital Time  *
  1499. '       **********************************************
  1500.  
  1501. '       Tp = TwoPI * a^(3/2)/SQR(µ)
  1502. '
  1503. '               where:  a = semi-major axis = radius for circular orbit
  1504. '                       µ = Earth's gravitational constant (m^3/s^2)
  1505.  
  1506. ConvOrbitAlt:
  1507.     OrbitAlt = OrbitAlt * NM2SM * SM2Ft * Ft2M: ' convert to meters
  1508.     GeoRadius = ERadius + OrbitAlt
  1509.     OrbitTime = TwoPI * GeoRadius ^ (3 / 2) / SqrMu
  1510.     OrbitTime = OrbitTime / 60:             ' convert to minutes
  1511.     RETURN
  1512.  
  1513. ConvOrbitTime:
  1514.     OrbitAlt = (OrbitTime * SqrMu / TwoPI) ^ (2 / 3) - 6378160
  1515.     OrbitAlt = OrbitAlt / Ft2M / SM2Ft / NM2SM
  1516.     RETURN
  1517.  
  1518.  
  1519. '       ******************************
  1520. '       *  ShowMap: Plot Map Points  *
  1521. '       ******************************
  1522.  
  1523. ShowMap:
  1524.     FOR N% = 1 TO MPoints%
  1525.         SLon% = MLon%(N%)
  1526.         SLat% = MLat%(N%)
  1527.         IF SLon% > 0 AND SLon% < 639 THEN
  1528.         IF SLat% > Top% AND SLat% < Bottom% THEN
  1529.             PSET (SLon%, SLat%), Cyan%
  1530.         END IF
  1531.         END IF
  1532.     NEXT
  1533.     RETURN
  1534.  
  1535. '       ***********************************************
  1536. '       *  ShowGrid: Plot Equator & Prime Longitudes  *
  1537. '       ***********************************************
  1538.  
  1539. ShowGrid:
  1540.     UseColor Blue%
  1541.     IF Monitor% = 4 THEN G% = 2 ELSE G% = 0
  1542.     IF INSTR(CommandLine$, "/EUR") THEN
  1543.         ColorA% = LtBlue%
  1544.         ColorB% = Blue%
  1545.         LOCATE 1, 19 - G%: PRINT "-90";
  1546.         LOCATE 1, 39 - 2 * G%: PRINT " 0 ";
  1547.         LOCATE 1, 59 - 3 * G%: PRINT "+90";
  1548.     ELSE
  1549.         ColorA% = Blue%
  1550.         ColorB% = LtBlue%
  1551.         LOCATE 1, 19 - G%: PRINT "180";
  1552.         LOCATE 1, 39 - 2 * G%: PRINT "-90";
  1553.         LOCATE 1, 59 - 3 * G%: PRINT " 0";
  1554.     END IF
  1555.     LINE (0, Equator%)-(639, Equator%), LtBlue%
  1556.     LINE (0, Top%)-(639, Bottom%), LtBlue%, B
  1557.     LINE (159, Top% + 1)-(159, Bottom% - 1), Blue%
  1558.     LINE (319, Top% + 1)-(319, Bottom% - 1), ColorA%
  1559.     LINE (479, Top% + 1)-(479, Bottom% - 1), ColorB%
  1560.     IF Monitor% <> 1 THEN
  1561.         IF GridFlag% = 0 THEN GOTO ShowGrid1
  1562.         LINE (52, Top% + 1)-(52, Bottom% - 1)
  1563.         LINE (106, Top% + 1)-(106, Bottom% - 1)
  1564.         LINE (212, Top% + 1)-(212, Bottom% - 1)
  1565.         LINE (266, Top% + 1)-(266, Bottom% - 1)
  1566.         LINE (372, Top% + 1)-(372, Bottom% - 1)
  1567.         LINE (426, Top% + 1)-(426, Bottom% - 1)
  1568.         LINE (532, Top% + 1)-(532, Bottom% - 1)
  1569.         LINE (586, Top% + 1)-(586, Bottom% - 1)
  1570.         FOR L% = -80 TO 80 STEP 10
  1571.             LY% = Equator% - L% * VFactor! / 2
  1572.             IF L% <> 0 AND LY% < Bottom% THEN
  1573.                 LINE (1, LY%)-(638, LY%)
  1574.             END IF
  1575.         NEXT L%
  1576. ShowGrid1:
  1577.         IF INSTR(CommandLine$, "/EUR") <> 0 THEN AdjEUROPE% = 180 ELSE AdjEUROPE% = -90
  1578.         TX% = -171
  1579.         TY% = Equator%
  1580.         GOSUB ShowTDRS
  1581.         TX% = -41
  1582.         GOSUB ShowTDRS
  1583.         IF TrackStn% = 1 THEN GOSUB ShowTDS
  1584.     END IF
  1585.     RETURN
  1586.  
  1587.  
  1588. ShowTDRS:
  1589.     TX% = Mod360(TX% + AdjEUROPE%) / 360 * 640
  1590.     PSET (TX%, TY%), Yellow%
  1591.     CIRCLE (TX%, TY%), 3, Yellow%
  1592.     RETURN
  1593.  
  1594. ShowTDS:
  1595.     RESTORE
  1596.     FOR N% = 1 TO 14
  1597.         READ TDS$, TX%, TY%
  1598.         TY% = Equator% - TY% * VFactor! / 2
  1599.         TX% = Mod360(TX% + AdjEUROPE%) / 360 * 640
  1600.         CIRCLE (TX%, TY%), 17 * VFactor! / 2, Brown%, , , Aspect! * 1.4
  1601.         PSET (TX%, TY%), Yellow%
  1602.         CIRCLE (TX%, TY%), 3, Yellow%
  1603.     NEXT
  1604.     RETURN
  1605.  
  1606.     ' NASA Tracking Stations
  1607.  
  1608.     DATA "MIL",-81,28:      'Merritt Island
  1609.     DATA "BDA",-64,32:      'Bermuda
  1610.     DATA "DKR",-17,14:      'Dakar
  1611.     DATA "ACN",-14,-8:      'Ascension Island
  1612.     DATA "MAX",-5,41:       'Central Spain
  1613.     DATA "IOS",56,-5:       'Indian Ocean
  1614.     DATA "HAW",-156,20:     'Hawaii
  1615.     DATA "GWM",145,14:      'Gwam
  1616.     DATA "VAN",-122,35:     'Vandenberg, CA
  1617.     DATA "YAR",115,-29:     'Yargidy, Australia
  1618.     DATA "CAN",149,-36:     'Canberra, Australia
  1619.     DATA "GDX",-116,34:     'Goldstone, CA
  1620.     DATA "CTS",-105,38:     'Colorado Springs, CO
  1621.     DATA "AGO",-71,-34:     'Santiago, Chile
  1622.     
  1623. '       ********************************************
  1624. '       *  SetColors: Set Colors for Monitor Type  *
  1625. '       ********************************************
  1626.  
  1627. SetColors:
  1628.  
  1629. '       0 = Monochrome
  1630. '       1 = Color
  1631. '       2 = Red
  1632. '       3 = Green
  1633.  
  1634.     IF INSTR(CommandLine$, "/M") <> 0 THEN ColorFlag% = 0
  1635.     SELECT CASE ColorFlag%
  1636.         CASE 2, 4
  1637.             Normal = 4
  1638.             Bright = 12
  1639.         CASE 3
  1640.             Normal = 2
  1641.             Bright = 10
  1642.         CASE ELSE
  1643.             Normal = 7
  1644.             Bright = 15
  1645.     END SELECT
  1646.  
  1647.     IF ColorFlag% = 1 THEN
  1648.     Black% = 0:      Gray% = 8:       BBlack = 0
  1649.     Blue% = 1:       LtBlue% = 9:     BBlue = 1
  1650.     Green% = 2:      LtGreen% = 10:   BGreen = 2
  1651.     Cyan% = 3:       LtCyan% = 11:    BCyan = 3
  1652.     Red% = 4:        LtRed% = 12:     BRed = 4
  1653.     Magenta% = 5:    LtMagenta% = 13: BMagenta = 5
  1654.     Brown% = 6:      Yellow% = 14:    BBrown = 6
  1655.     White% = 7:      LtWhite% = 15:   BWhite = 7
  1656.      
  1657.     ELSE
  1658.     Black% = 0:           Gray% = Normal:       BBlack = 0
  1659.     Blue% = Normal:       LtBlue% = Bright:    BBlue = 0
  1660.     Green% = Normal:      LtGreen% = Bright:   BGreen = 0
  1661.     Cyan% = Normal:       LtCyan% = Bright:    BCyan = 0
  1662.     Red% = Normal:        LtRed% = Bright:     BRed = 0
  1663.     Magenta% = Normal:    LtMagenta% = Bright: BMagenta = 0
  1664.     Brown% = Normal:      Yellow% = Bright:    BBrown = 0
  1665.     White% = Normal:      LtWhite% = Bright:   BWhite = 0
  1666.     END IF
  1667.     RETURN
  1668.  
  1669. '       ************************
  1670. '       *  Show Program Title  *
  1671. '       ************************
  1672.  
  1673. ShowTitle:
  1674.     GOSUB ShowTitle0
  1675.     UseColor LtWhite%
  1676.     Center "by David H. Ransom, Jr.", 8, 1, 80
  1677.     UseColor LtGreen%
  1678.     Center "Current time: " + CTime$, 10, 1, 80
  1679.     Center "Current date: " + CDate$, 11, 1, 80
  1680.     RETURN
  1681.  
  1682. ShowTitle1:
  1683.     GOSUB ShowTitle0
  1684.     UseColor LtGreen%
  1685.     Center "Current time: " + CTime$, 8, 1, 80
  1686.     Center "Current date: " + CDate$, 9, 1, 80
  1687.     RETURN
  1688.  
  1689. ShowTitle0:
  1690.     CLS
  1691.     UseColor LtMagenta%
  1692.     Center "Program STSORBIT", 3, 1, 80
  1693.     UseColor Yellow%
  1694.     Center "Space Shuttle Orbit Simulation", 5, 1, 80
  1695.     UseColor Brown%
  1696.     Center "Version 9019 ", 6, 1, 80
  1697.     CTime = SystemTime(H%, M%, Secs%, CTime$)
  1698.     CDate = SystemDate(Day%, Month%, Year%, CDate$)
  1699.     RETURN
  1700.  
  1701. REM $STATIC
  1702. DEFINT A-Z
  1703. SUB Center (Text$, Row%, Column%, Length%)
  1704.  
  1705. '       Centers Text$ on the screen in a line of length Length%.
  1706.  
  1707.     DEFINT A-Z
  1708.     LOCATE Row, Column
  1709.     T$ = Text$
  1710.     IF LEN(Text$) > Length% THEN T$ = LEFT$(Text$, Length%)
  1711.     PRINT SPC((Length% - LEN(T$)) / 2); T$;
  1712. END SUB
  1713.  
  1714. SUB ClearLine (LineNo%)
  1715.     LOCATE LineNo, 1
  1716.     PRINT SPACE$(80);
  1717.     LOCATE LineNo, 1
  1718. END SUB
  1719.  
  1720. FUNCTION DMY2JD# (Day%, Month%, Year1%)
  1721.  
  1722. ' =====> NOTE: This function calculates the Julian Date at 12:00:00  <=====
  1723.  
  1724. ' DMY2JD# converts the given date into JD, the number of Julian days
  1725. ' elapsed since -4713 January 1.5. Note: DJD = JD - 2415020. Method
  1726. ' adapted from Roger Minnott, Sky & Telescope, May 1984, p 455.
  1727.  
  1728.     DEFINT A-Z
  1729.     IF Year1 < 0 THEN Year = Year1 + 1 ELSE Year = Year1
  1730.     J# = -INT(7 * (INT((Month + 9) / 12) + Year) / 4)
  1731.        
  1732.     SELECT CASE CalendarFlag
  1733.     CASE 1
  1734.         IF Year > 1582 OR (Year = 1582 AND Month > 10) OR (Year = 1582 AND Month = 10 AND Day > 4) THEN
  1735.             S = SGN(Month - 9)
  1736.             A = ABS(Month - 9)
  1737.             J1 = INT(Year + S * INT(A / 7))
  1738.             J1 = -INT((INT(J1 / 100) + 1) * .75)
  1739.             G = 1
  1740.         END IF
  1741.     CASE 2
  1742.         IF Year > 1752 OR (Year = 1752 AND Month > 9) OR (Year = 1752 AND Month = 9 AND Day > 1) THEN
  1743.             S = SGN(Month - 9)
  1744.             A = ABS(Month - 9)
  1745.             J1 = INT(Year + S * INT(A / 7))
  1746.             J1 = -INT((INT(J1 / 100) + 1) * .75)
  1747.             G = 1
  1748.         END IF
  1749.     CASE ELSE
  1750.         J1 = 0
  1751.         G = 0
  1752.     END SELECT
  1753.        
  1754.     J# = J# + INT(275 * Month / 9) + Day + G * J1
  1755.     Y# = 367# * Year
  1756.     DMY2JD# = 1721027# + J# + 2 * G + Y# - .5#
  1757. END FUNCTION
  1758.  
  1759. FUNCTION Get2$ (I%)
  1760.     DEFINT A-Z
  1761.     Digit2 = INT(I% / 10)
  1762.     Digit1 = I% - Digit2 * 10
  1763.     Get2$ = CHR$(Digit2 + 48) + CHR$(Digit1 + 48)
  1764. END FUNCTION
  1765.  
  1766. FUNCTION GetDate$ (Day%, Month%, Year%)
  1767.     DEFINT A-Z
  1768.     AYear = ABS(Year%)
  1769.     HYear% = INT(AYear% / 100)
  1770.     UYear% = AYear% - HYear% * 100
  1771.     GetDate$ = Get2$(Month%) + "/" + Get2$(Day%) + "/" + Get2$(HYear%) + Get2$(UYear%)
  1772. END FUNCTION
  1773.  
  1774. FUNCTION InputDMY# (Flag%, JulianDay#)
  1775.  
  1776. '       Flag% is set as follows on return:
  1777.  
  1778. '      <0 = Error Number
  1779. '       0 = RETURN (No data entered)
  1780. '       1 = Local date input, output is LOCAL JD ===> USE CAUTION! <===
  1781. '       2 = UT date input, output is JD
  1782. '       3 = +/-/JD/DJD/MJD/TJD/GSD input, output is JD
  1783.  
  1784. InputDMY0:
  1785.     Flag% = 0
  1786.     LINE INPUT K$
  1787.     LD = 1: LM = 1: LY = 1988
  1788.     IF LEN(K$) = 0 THEN EXIT FUNCTION
  1789.     K$ = UCASE$(K$)
  1790.     IF LEFT$(K$, 1) = "#" THEN
  1791.         InputDMY# = INT(JulianDay#) + .5#
  1792.         Flag% = 3
  1793.         EXIT FUNCTION
  1794.     END IF
  1795.     IF LEFT$(K$, 1) = "*" THEN
  1796.         InputDMY# = JulianDay#
  1797.         Flag% = 3
  1798.         EXIT FUNCTION
  1799.     END IF
  1800.     IF LEFT$(K$, 1) = "+" THEN
  1801.         InputDMY# = JulianDay# + VAL(MID$(K$, 2))
  1802.         Flag% = 3
  1803.         EXIT FUNCTION
  1804.     END IF
  1805.     IF LEFT$(K$, 1) = "-" THEN
  1806.         InputDMY# = JulianDay# - VAL(MID$(K$, 2))
  1807.         Flag% = 3
  1808.         EXIT FUNCTION
  1809.     END IF
  1810.     IF LEFT$(K$, 2) = "JD" THEN
  1811.         InputDMY# = VAL(MID$(K$, 3))
  1812.         Flag% = 3
  1813.         EXIT FUNCTION
  1814.     ELSEIF LEFT$(K$, 3) = "DJD" THEN
  1815.         InputDMY# = VAL(MID$(K$, 4)) + 2415020#
  1816.         Flag% = 3
  1817.         EXIT FUNCTION
  1818.     ELSEIF LEFT$(K$, 3) = "MJD" THEN
  1819.         InputDMY# = VAL(MID$(K$, 4)) + 2400000.5#
  1820.         Flag% = 3
  1821.         EXIT FUNCTION
  1822.     ELSEIF LEFT$(K$, 3) = "TJD" THEN
  1823.         InputDMY# = VAL(MID$(K$, 4)) + 2440000.5#
  1824.         Flag% = 3
  1825.         EXIT FUNCTION
  1826.     ELSEIF LEFT$(K$, 3) = "GSD" THEN
  1827.         InputDMY# = (VAL(MID$(K$, 4)) - .671104312#) / 1.00273790934#
  1828.         Flag% = 3
  1829.         EXIT FUNCTION
  1830.     END IF
  1831.     IF RIGHT$(K$, 1) = "U" THEN Flag% = 2 ELSE Flag% = 1
  1832.     LM = VAL(K$)
  1833.     LDF# = 0
  1834.     Test = INSTR(K$, "/"): 'find first slash
  1835.     IF Test = 0 THEN GOTO InputDMY1
  1836.     IF INSTR(LEFT$(K$, Test), ".") THEN Flag% = 3: 'Force UT if decimal pt
  1837.     K$ = MID$(K$, Test + 1)
  1838.     LD = VAL(K$)
  1839.     Test = INSTR(K$, "/"): 'find second slash
  1840.     IF Test = 0 THEN GOTO InputDMY1
  1841.     K$ = MID$(K$, Test + 1)
  1842.     LY = VAL(K$)
  1843.  
  1844. InputDMY1:
  1845.     CalendarFlag = 1   'Force Gregorian Calendar
  1846.     SELECT CASE CalendarFlag
  1847.         CASE 1
  1848.             IF LY = 1582 AND LM = 10 AND LD > 4 AND LD < 15 THEN
  1849.                 ErrorNum = 24
  1850.                 GOTO ShowDMYError
  1851.             END IF
  1852.         CASE 2
  1853.             IF LY = 1752 AND LM = 9 AND LD > 2 AND LD < 14 THEN
  1854.                 ErrorNum = 24
  1855.                 GOTO ShowDMYError
  1856.             END IF
  1857.         CASE ELSE
  1858.     END SELECT
  1859.  
  1860.     IF LM < 0 OR LM > 12 THEN
  1861.         ErrorNum = 26
  1862.         GOTO ShowDMYError
  1863.     END IF
  1864.  
  1865.     IF LeapYear(LY) = 0 AND LM = 2 AND LD = 29 THEN
  1866.         ErrorNum = 25
  1867.         GOTO ShowDMYError
  1868.     END IF
  1869.  
  1870.     SELECT CASE LM
  1871.         CASE 2
  1872.             TestDays = 28
  1873.         CASE 4, 6, 9, 11
  1874.             TestDays = 30
  1875.         CASE ELSE
  1876.             TestDays = 31
  1877.     END SELECT
  1878.  
  1879.     IF LeapYear(LY) = 1 AND LM = 2 THEN TestDays = 29
  1880.        
  1881.     IF LD < 0 OR LD > TestDays THEN
  1882.         ErrorNum = 26
  1883.         GOTO ShowDMYError
  1884.     END IF
  1885.        
  1886.     InputDMY# = DMY2JD#(LD, LM, LY) + LDF#
  1887.     EXIT FUNCTION
  1888.  
  1889. ShowDMYError:
  1890.     'ErrorWindow ErrorNum
  1891.     Flag = -ErrorNum
  1892.     EXIT FUNCTION
  1893. END FUNCTION
  1894.  
  1895. DEFDBL A-Z
  1896. FUNCTION InputHMS# (Flag%)
  1897.  
  1898. '       Returns the time input and sets Flag% as follows:
  1899.  
  1900. '       0 = No time input (CR pressed)
  1901. '       1 = Local time requested
  1902. '       2 = UT time requested           (No conversions performed)
  1903. '       3 = ET or TDT time requested    (No conversions performed)
  1904.  
  1905.     LINE INPUT K$
  1906.     Flag% = 0
  1907.     InputHMS# = 0
  1908.     IF K$ = "" THEN EXIT FUNCTION
  1909.     K$ = UCASE$(K$)
  1910.     SELECT CASE RIGHT$(K$, 1)
  1911.         CASE "U"
  1912.             Flag% = 2
  1913.         CASE "E", "T"
  1914.             Flag% = 3
  1915.         CASE ELSE
  1916.             Flag% = 1
  1917.     END SELECT
  1918.     Test# = VAL(K$)
  1919.     InputHMS# = Test#
  1920.     Test% = INSTR(K$, ":"): 'Find first colon
  1921.     IF Test% = 0 THEN Test% = INSTR(K$, ","): 'Try comma instead
  1922.     IF Test% = 0 THEN EXIT FUNCTION
  1923.     K$ = MID$(K$, Test% + 1)
  1924.     Test# = Test# + VAL(K$) / 60
  1925.     InputHMS# = Test#
  1926.     Test% = INSTR(K$, ":"): 'Find second colon
  1927.     IF Test% = 0 THEN Test% = INSTR(K$, ","): 'Try comma instead
  1928.     IF Test% = 0 THEN EXIT FUNCTION
  1929.     K$ = MID$(K$, Test% + 1)
  1930.     InputHMS# = Test# + VAL(K$) / 3600
  1931. END FUNCTION
  1932.  
  1933. FUNCTION JD2DMY$ (Day%, Month%, Year%, JD#, FracDay#)
  1934.  
  1935. ' JD2DMY$ converts a given Julian Date (JD#), days elapsed since -4713
  1936. ' JAN 1.5, into Gregorian date format. It returns a string in the format
  1937. ' DD-MM-YYYY; the Day, Month, and Year; and the fractional day.
  1938.  
  1939. ' Method adapted from Roger Sinnott, Sky & Telescope, May 1984, p 455.
  1940.  
  1941.     DEFDBL A-Z
  1942.     SELECT CASE CalendarFlag%
  1943.         CASE 1:         'Automatic @ 1582 OCT 15
  1944.             IF JD >= 2299160.5# THEN G% = 1 ELSE G% = 0
  1945.         CASE 2:         'Automatic @ 1752 SEP 13
  1946.             IF JD >= 2361209.5# THEN G% = 1 ELSE G% = 0
  1947.         CASE ELSE:      'Julian Calendar
  1948.             G% = 0
  1949.     END SELECT
  1950.        
  1951.     J = FIX(JD#)
  1952.     F# = JD# - J + .5#
  1953.     IF F# >= 1# THEN F# = F# - 1#: J = J + 1
  1954.     FracDay# = F#
  1955.  
  1956.     IF G% = 0 THEN
  1957.         A = J
  1958.     ELSE
  1959.         A1 = INT((J / 36524.25#) - 51.12264#)
  1960.         A = J + 1# + A1 - INT(A1 / 4#)
  1961.     END IF
  1962.  
  1963.     B = A + 1524#
  1964.     C = INT((B / 365.25#) - .3343#)
  1965.     D = INT(365.25# * C)
  1966.     E% = INT((B - D) / 30.61#)
  1967.     Day% = B - D - INT(30.61# * E%)
  1968.     IF E% > 13 THEN Month% = E% - 13 ELSE Month% = E% - 1
  1969.     IF Month% > 2 THEN Year% = C - 4716 ELSE Year% = C - 4715
  1970.     IF Year% <= 0 THEN Year% = Year% - 1
  1971.     JD2DMY$ = GetDate$(Day%, Month%, Year%)
  1972. END FUNCTION
  1973.  
  1974. DEFINT A-Z
  1975. FUNCTION LeapYear% (Y%)
  1976.       
  1977. '       Function LeapYear determines if Year% is a Leap Year (LeapYear=1)
  1978. '       or not (LeapYear=0).
  1979.  
  1980.     DEFINT A-Z
  1981.     IF Y > 0 THEN Year = Y ELSE Year = Y + 1
  1982.     IF Year MOD 4 = 0 THEN IsLeap = 1 ELSE IsLeap = 0
  1983.     CalendarFlag = 0
  1984.     SELECT CASE CalendarFlag
  1985.     CASE 1
  1986.         IF Year MOD 100 = 0 AND Year > 1582 THEN
  1987.             IsLeap = 0
  1988.             IF Year MOD 400 = 0 THEN IsLeap = 1
  1989.         END IF
  1990.     CASE 2
  1991.         IF Year MOD 100 = 0 AND Year > 1752 THEN
  1992.             IsLeap = 0
  1993.             IF Year MOD 400 = 0 THEN IsLeap = 1
  1994.         END IF
  1995.     CASE ELSE
  1996.     END SELECT
  1997.     LeapYear = IsLeap
  1998. END FUNCTION
  1999.  
  2000. DEFDBL A-Z
  2001. FUNCTION Mod2PI# (X#)
  2002.     Mod2PI# = X - INT(X / TwoPI) * TwoPI
  2003. END FUNCTION
  2004.  
  2005. DEFINT A-Z
  2006. FUNCTION Mod360# (Degrees#)
  2007.     D# = Degrees#
  2008.     IF ABS(D#) >= 1440# THEN
  2009.         D# = D# - FIX(D# / 360#) * 360#
  2010.     END IF
  2011.     WHILE D# >= 360#: D# = D# - 360#: WEND
  2012.     WHILE D# < 0#: D# = D# + 360#: WEND
  2013.     Mod360# = D#
  2014. END FUNCTION
  2015.  
  2016. FUNCTION Mod86400# (T#)
  2017.  
  2018. '       Mod86400# returns an adjusted value of T# such that 0<=T#<86400
  2019.  
  2020.     CheckTime# = T#
  2021.     IF ABS(CheckTime#) >= 432000# THEN
  2022.         CheckTime# = CheckTime# - FIX(CheckTime# / 86400#) * 86400#
  2023.     END IF
  2024.     WHILE CheckTime# >= 86400#: CheckTime# = CheckTime# - 86400#: WEND
  2025.     WHILE CheckTime# < 0#: CheckTime# = CheckTime# + 86400#: WEND
  2026.     Mod86400# = CheckTime#
  2027.  
  2028. END FUNCTION
  2029.  
  2030. FUNCTION String2$ (Value%, Lead$)
  2031.     IF Value > 99 THEN
  2032.         String2$ = "%%"
  2033.         EXIT FUNCTION
  2034.     END IF
  2035.     Tens = Value \ 10
  2036.     Units = Value MOD 10
  2037.     IF Tens = 0 THEN
  2038.         Temp$ = Lead$
  2039.     ELSE
  2040.         Temp$ = CHR$(Tens + 48)
  2041.     END IF
  2042.     String2$ = Temp$ + CHR$(Units + 48)
  2043. END FUNCTION
  2044.  
  2045. DEFDBL A-Z
  2046. FUNCTION SystemDate# (Day%, Month%, Year%, DateString$)
  2047.  
  2048. ' SystemDate# returns the following information from the system clock:
  2049.  
  2050. '   SystemDate# = Julian date
  2051. '   Day%        = Current integer day of month
  2052. '   Month%      = Current integer month of year
  2053. '   Year%       = Current integer year
  2054. '   DateString$ = ASCII date as DD-MM-YYYY (string)
  2055.  
  2056.     Temp$ = DATE$
  2057.     Day% = VAL(MID$(Temp$, 4, 2))
  2058.     Month% = VAL(MID$(Temp$, 1, 2))
  2059.     Year% = VAL(MID$(Temp$, 7, 4))
  2060.     DateString$ = GetDate$(Day%, Month%, Year%)
  2061.     SystemDate# = DMY2JD#(Day%, Month%, Year%)
  2062. END FUNCTION
  2063.  
  2064. FUNCTION SystemTime# (Hours%, Minutes%, Seconds%, TimeString$)
  2065.  
  2066. ' SystemTime# returns the following information from the system clock:
  2067.  
  2068. '   SystemTime# = Current time in seconds since midnight
  2069. '   Hours%      = Current integer hours    (0-23)
  2070. '   Minutes%    = Current integer minutes  (0-59)
  2071. '   Seconds%    = Current integer seconds  (0-59)
  2072. '   TimeString$ = ASCII time as HH:MM:SS   (string, 24-hour notation)
  2073.  
  2074. ' NOTE: When used in combination with the Julian date, SystemTime# as
  2075. '       calculated in this function must be divided by 86400 to yield
  2076. '       the fractional part of a day.
  2077.  
  2078. ReadSystemTime:
  2079.     ElapsedTime# = INT(TIMER)
  2080.     Hours% = INT(ElapsedTime# / 3600#)
  2081.     Minutes% = INT((ElapsedTime# - Hours% * 3600#) / 60#)
  2082.     Seconds% = ElapsedTime# - Hours% * 3600# - Minutes% * 60#
  2083.     TimeString$ = String2$(Hours%, "0") + ":" + String2$(Minutes%, "0") + ":" + String2$(Seconds%, "0")
  2084.     SystemTime# = ElapsedTime#
  2085. END FUNCTION
  2086.  
  2087. FUNCTION TimeStr$ (Seconds#, DDigits%, FormatFlag%, LeadZero$)
  2088.  
  2089. '       This function returns a string of the form HH:MM:SS.SSSS
  2090. '       where the number of digits to the right of the decimal point
  2091. '       is determined by DDigits%.
  2092.  
  2093. '       FormatFlag% determines the format of the resulting string:
  2094. '               -1   HH.HHHHHH
  2095. '                0   HH:MM.MMMM
  2096. '               +1   HH:MM:SS.SS
  2097.  
  2098.     DEFINT A-Z
  2099.     LocalSeconds# = Mod86400(Seconds# + .5# * 10 ^ (-DDigits%))
  2100.     ITime& = INT(LocalSeconds#)
  2101.     THours = ITime& \ 36000
  2102.     JTime& = ITime& - THours * 36000
  2103.     UHours = JTime& \ 3600&
  2104.     JTime& = JTime& - UHours * 3600&
  2105.     IF THours = 0 THEN
  2106.         TT$ = LeadZero$ + CHR$(UHours + 48)
  2107.     ELSE
  2108.         TT$ = CHR$(THours + 48) + CHR$(UHours + 48)
  2109.     END IF
  2110.     IF FormatFlag% = -1 THEN
  2111.         DTime# = (LocalSeconds# - (THours * 10# + UHours) * 3600#) / 3600#
  2112.         GOTO DoDecimals
  2113.     END IF
  2114.     TMinutes = JTime& \ 600&
  2115.     JTime& = JTime& - TMinutes * 600&
  2116.     UMinutes = JTime& \ 60&
  2117.     JTime& = JTime& - UMinutes * 60&
  2118.     TT$ = TT$ + ":" + CHR$(TMinutes + 48) + CHR$(UMinutes + 48)
  2119.     IF FormatFlag% = 0 THEN
  2120.         DTime# = (LocalSeconds# - (THours * 10# + UHours) * 3600# - (TMinutes * 10# + UMinutes) * 60#) / 60#
  2121.         GOTO DoDecimals
  2122.     END IF
  2123.     TSeconds = JTime& \ 10&
  2124.     USeconds = JTime& - TSeconds * 10&
  2125.     TT$ = TT$ + ":" + CHR$(TSeconds + 48) + CHR$(USeconds + 48)
  2126.     DTime# = LocalSeconds# - ITime&
  2127.  
  2128. DoDecimals:
  2129.     IF DDigits% < 1 THEN TimeStr$ = TT$: EXIT FUNCTION
  2130.     TT$ = TT$ + "."
  2131.     FOR N = 1 TO DDigits%
  2132.         DTime# = DTime# * 10#
  2133.         IDT = INT(DTime#)
  2134.         TT$ = TT$ + CHR$(IDT + 48)
  2135.         DTime# = DTime# - IDT
  2136.     NEXT N
  2137.     TimeStr$ = TT$
  2138.  
  2139. END FUNCTION
  2140.  
  2141. SUB UseColor (Colr%) STATIC
  2142.     IF Colr% = 0 THEN
  2143.         ColorFlag = 0
  2144.         EXIT SUB
  2145.     ELSEIF Colr% = -1 THEN
  2146.         ColorFlag = 1
  2147.         EXIT SUB
  2148.     END IF
  2149.     IF ColorFlag = 0 THEN EXIT SUB
  2150.     COLOR Colr%
  2151. END SUB
  2152.  
  2153. SUB WaitForKey (K$)
  2154.     DO
  2155.     K$ = INKEY$
  2156.     LOOP UNTIL LEN(K$) <> 0
  2157. END SUB
  2158.  
  2159.