AMS-81

Products: AMS-81
Date: 1983
Type: Program
Platform(s): TS 1000
Tags: Ham Radio

AMS-81 is a satellite pass scheduling and real-time tracking utility designed for amateur radio operators, computing orbital positions from Keplerian elements. The program propagates orbits by iteratively solving Kepler’s equation using an eccentric anomaly refinement loop (lines 5100–5150), then transforms results through a rotation matrix built from inclination, RAAN, and argument of perigee (lines 3740–3790). Ground station coordinates are converted to Earth-centered Cartesian coordinates accounting for the oblate Earth flattening factor (lines 3020–3110). A rich set of symbolic constant aliases—including U, G, TEN, HEX, INF, and others—compresses frequently used numeric literals throughout the code. SLOW/FAST mode switching and a configurable step-size variable PHI allow the tracking loop to balance computational accuracy against display refresh speed.


Program Analysis

Program Structure

The program is organized around a main menu at lines 10–120 that dispatches to four functional areas based on a single keypress. The four activities are scheduling (option 1, lines 130–960), real-time tracking (option 2, lines 970–2290), Keplerian file editing (option 3, lines 2300–2810), and QTH (ground station) configuration (option 4, lines 2820–3120). A save/resave path exists at lines 3130–3230. The remaining lines (roughly 3240–5650) form a library of subroutines shared across all four activities.

Symbolic Constant Aliases

To save memory and reduce token overhead, frequently used numeric values are pre-assigned to short variable names at program start or within initialization routines. Key aliases encountered throughout the listing include:

VariableApproximate Value / Meaning
U1
G0
U22
U33
U44
TEN10
HEX16
INFA large sentinel value (used for orbit counter initialization)
P0π/180 (degrees-to-radians factor)
P2
HA0.5
HUN100
THO1000 (also used as PAUSE duration)
DYRDays per year (365.25 or similar)
R0Earth’s equatorial radius
G0Gravitational parameter (GM)
G1Earth’s rotation rate (radians per day)
CLSpeed of light (used for Doppler calculation)
AFStep-size scaling factor
INStep increment base

Orbital Mechanics Engine

Orbit propagation begins in subroutine KSC (line 3460), which sets up mean motion N, semi-major axis A, and the J2 perturbation corrections for RAAN drift (O) and argument-of-perigee precession (W) using a K2 coefficient at line 3650. The rotation matrix C() (lines 3740–3790) transforms perifocal coordinates to Earth-centered inertial (ECI) coordinates.

Kepler’s equation is solved iteratively in lines 5100–5150:

  1. An initial estimate of eccentric anomaly E is formed from the mean anomaly M plus first- and second-order series terms (line 5100).
  2. The residual M5 = E - e·sin(E) - M is computed (line 5110).
  3. Newton–Raphson correction E = E - M5 / (1 - e·cos(E)) is applied (lines 5130–5140) until convergence to within 1×10⁻⁶.

ECI position is then rotated into Earth-fixed coordinates using the Greenwich sidereal angle G7 (lines 5220–5250), and the ground-station vector (computed at lines 3020–3110 with oblate-Earth correction) is subtracted to yield the topocentric range vector.

Ground Station Geometry

Lines 3020–3110 convert the observer’s geodetic latitude L9, west longitude W9, and altitude H9 into Earth-centered Cartesian coordinates X9, Y9, Z9. The geodetic-to-geocentric latitude conversion at line 3080 uses the standard flattening formula tan(φ_c) = (1-f)² · tan(φ_g), where F is the flattening constant. Elevation E9 and azimuth A9 are derived in the CO4 / AZ subroutine block (lines 5270–5390).

Scheduling Logic

The scheduler (lines 130–960) uses subroutine SCH (line 5550) to bracket AOS (Acquisition of Signal) and LOS (Loss of Signal) by bisecting the sign of the dot product QS between the satellite position and the ground station vector. The step size PHI is halved whenever a sign change is detected, converging on the horizon crossing. The array A() stores AOS time, AOS range, LOS time, and LOS range for each pass, and the display loop (lines 470–960) formats these into a columnar schedule with day dividers injected by subroutine DD (line 1670).

Real-Time Tracking Display

The tracking activity (lines 970–2290) calls subroutine LP2 in a tight loop, displaying UTC, azimuth, elevation, range, phase angle (for eccentric orbits), and Doppler shift. The Doppler estimate at lines 1580–1600 approximates the radial velocity from consecutive range measurements R5 divided by the elapsed time, scaled by the carrier frequency F(I) and speed of light CL. SLOW/FAST mode is managed by the FS flag: pressing F sets FS=U (fast), pressing D sets FS=G (slow). Page-full pauses at line 2040 prompt the operator to continue or exit.

Date/Time Handling

Two date formats are accepted by the DAY subroutine (lines 4050–4390): a compact decimal epoch like 83 105.46677538 (two-digit year, day-of-year with fractional day) and a calendar format like 15APR83 111209 (DDMMMYY HHMMSS). A 13-element month table M$() stores three-letter abbreviations alongside cumulative day-of-year offsets. Leap-year detection is handled by testing divisibility by 4 and checking whether the day number is at or past day 59 (lines 4350, 4450). The inverse DAO routine (lines 4400–4630) converts an internal day number back to both display formats simultaneously.

Keplerian File Editor

Option 3 (lines 2300–2810) presents each Keplerian element in turn for in-place editing. Elements are stored in parallel arrays: I(I) inclination, O(I) RAAN, E(I) eccentricity, W(I) argument of perigee, M(I) mean anomaly at epoch, N(U,I) mean motion (or semi-major axis if >100), and N(U2,I) mean motion derivative. The satellite name S$(I), catalog ID I$(I), and downlink frequency F(I) are also editable. Any modification sets the dirty flag SV=U, enabling the “NEED TO RESAVE” option 5 on the main menu.

Keypress and Flow-Control Idioms

The program makes heavy use of a polling keypress subroutine KSC (line 3270) that checks INKEY$ without blocking. A PAUSE 0 / INKEY$ construct is used at other points for true blocking waits. The GO variable serves as a global flow-control token: GO=G (0) signals an abort-to-main-menu condition tested after nearly every subroutine call with the pattern IF GO=G THEN GOTO G (branching to line 0, which does not exist—a standard technique to fall through to the top of the program). GO=U9 (9) signals a page-pause condition handled within KSC.

Notable Techniques

  • The orbital visibility pre-check at line 3920 uses the maximum elevation formula to quickly reject satellite/QTH combinations where passes are geometrically impossible, printing “PASSES CANNOT OCCUR” and aborting.
  • The adaptive step size in PHI (lines 1360–1390 and 5560–5650) scales the propagation interval by the ratio of the current angular change to a target change angle CA, allowing large steps far from events and fine steps near AOS/LOS and maximum elevation.
  • Line 3800 indexes a Greenwich sidereal time table G() by year to initialize G2, avoiding recomputation of the epoch sidereal angle from scratch each call.
  • The VAL E$(J, U5 TO TEN) idiom at line 2620 extracts element values from a string array used as a formatted data file, acting as a simple flat-file database.
  • SLOW is unconditionally re-entered at line 3940 before error messages to ensure readable display timing regardless of the current FS state.

Potential Anomalies

  • At line 3480, if N(U,I) is zero it is set to HUN (100) to prevent division by zero, then interpreted as a semi-major axis rather than mean motion—this dual-mode interpretation (lines 3490–3540) may produce unexpected results if an element set is partially initialized.
  • The Doppler computation (line 1580) divides by (D-T6), which is the elapsed time since the last update in fractional days. When the tracking loop runs very fast, D-T6 can be extremely small, potentially producing noisy Doppler readings; the IF T6<>D guard prevents a divide-by-zero but does not smooth the result.
  • The azimuth subroutine at line 5320 special-cases X8=0 (satellite exactly north or south) by assigning 90° or 270°, but the IF X8<>G test means any non-zero X8, however small, goes to the ATN branch—correct behavior, but the zero case is intentionally narrowly defined.

Content

Appears On

Related Products

A Timex/Sinclair computer port of W3IWI’s BASIC TRACK program for earth satellite tracking.

Related Articles

Related Content

Image Gallery

Source Code

  10 LET GO=U
  20 LET FS=G
  30 CLS 
  40 SLOW 
  50 PRINT H$
  60 PRINT "    VERSION N5BF 1.4 01APR83"
  70 PRINT AT U8,U7;"%<%<%<% %A%C%T%I%V%I%T%I%E%S% %>%>%>";AT TEN,U7;;"1 = SCHEDULE";TAB U7;"2 = TRACK";TAB U7;"3 = KEPLERIAN FILE";TAB U7;"4 = QTH INFO";AT HEX,TEN;"@@SELECT 1-4@@"
  80 IF SV=1 THEN PRINT AT U14,U7;"5 = NEED TO RESAVE";AT HEX,U20;"5"
  90 LET A$=INKEY$
 100 IF A$="" THEN GOTO 90
 110 PRINT AT HEX,U22;A$
 120 IF A$<>"1" THEN GOTO 970
 130 GOSUB 4890
 140 IF GO=G THEN GOTO G
 150 GOSUB HD1
 160 GOSUB INK
 170 GOSUB CO3
 180 LET LOS=U
 190 GOSUB SCH
 200 IF GO=G THEN GOTO G
 210 LET A(U)=D
 220 LET A(U2)=R5
 230 LET LOS=-U
 240 LET QS=U
 250 GOSUB SCH
 260 IF GO=G THEN GOTO G
 270 LET A(U3)=D
 280 LET A(U4)=R5
 290 LET PHI=G
 300 IF E(I)<U01 AND N>TEN THEN GOTO 430
 310 LET D=D+(INT Q-Q+HA)/N
 320 LET T=G
 330 GOSUB CO1
 340 IF A(U)>D OR A(U3)<D OR E(I)<U01 THEN GOTO 370
 350 LET E9=R0*(COS (E9*P0)*ASN (R5/R)+ACS (R0/R))
 360 GOTO LP1
 370 LET D=A(U)
 380 IF A(U4)>A(U2) THEN LET D=A(U3)
 390 LET T=U
 400 GOSUB CO1
 410 LET E9=U2*R0*ACS (R0/R)
 420 GOTO LP1
 430 LET D=(A(U)+A(U3))/U2
 440 GOSUB CO1
 450 LET T=U2
 460 GOTO LP1
 470 CLS 
 480 GOSUB DAO
 490 PRINT AT G,G;H$;"ACCESS SKED FROM: ";D$;"  >>";C$;" VIA ";S$(I);"<<","% %D%A%Y% % % %A%O%S% % %L%O%S% % % %M%A%X% %D%X%/%E%L% % % %A%Z"
 500 LET LP=U4
 510 RETURN 
 520 IF GO=G THEN GOTO G
 530 LET A(U5)=D
 540 LET D=A(U)
 550 GOSUB DAO
 560 LET D$=D$( TO U5)+D$(U8 TO U12)+N$
 570 LET J=U12
 580 LET D=A(U3)
 590 GOSUB TIM
 600 LET D$(HEX TO 17)=" "
 610 LET D=A(U5)
 620 LET J=U18
 630 GOSUB TIM
 640 LET D$=D$( TO U21)+" "
 650 IF T=U2 THEN GOTO 720
 660 LET D$=D$+STR$ INT E9+"  "
 670 IF LEN D$>=29 THEN GOTO 700
 680 LET D$=D$( TO U22)+D$(U22 TO )
 690 GOTO 670
 700 IF T=U THEN LET D$(U28)="*"
 710 GOTO 740
 720 GOSUB LZ2
 730 LET D$=D$( TO 24)+" %E%L  "
 740 GOSUB LZ3
 750 PRINT AT LP,G;D$( TO U32)
 760 LET LP=LP+U
 770 IF A(U3)-A(U)<U THEN GOTO 840
 780 LET D=A(U3)
 790 LET D$=N$+"  "
 800 LET J=U9
 810 GOSUB DAO
 820 PRINT AT LP,U4;"(LOS DATE = ";D$( TO U7);")"
 830 LET LP=LP+U1
 840 IF LP<U20 THEN GOTO 930
 850 LET GO=U9
 860 PRINT "## RETURN = 0, CONT = 1 ##"
 870 GOSUB KSC
 880 IF F$="Z" AND PRIN=U THEN COPY 
 890 IF GO=U9 THEN GOTO 870
 900 GOSUB CLB
 910 IF GO=G THEN GOTO G
 920 GOSUB HD1
 930 LET D=A(U3)
 940 GOSUB INK
 950 LET QS=-U
 960 GOTO 180
 970 IF A$<>"2" THEN GOTO 2300
 980 LET CT=1.2*CA
 990 LET CB=.8*CA
 1000 GOSUB 4890
 1010 LET LOS=U
 1020 IF GO=G THEN GOTO G
 1030 GOSUB HD2
 1040 GOSUB INK
 1050 GOSUB CO1
 1060 IF GO=G THEN GOTO G
 1070 IF E9>G THEN GOTO 1140
 1080 LET QS=-U
 1090 LET LOS=U
 1100 GOSUB SCH
 1110 LET PHI=G
 1120 GOSUB CO1
 1130 IF GO=G THEN GOTO G
 1140 LET FS=G
 1150 LET F8=G
 1160 LET T6=D
 1170 LET R6=R5
 1180 LET PHI=CA*R*AF
 1190 GOSUB LP2
 1200 IF GO=G THEN GOTO G
 1210 IF LP=U4 THEN GOSUB LP2
 1220 IF LOS=-U THEN GOTO 1080
 1230 GOSUB INK
 1240 LET D2=D
 1250 LET E8=E9
 1260 LET A8=A9
 1270 LET PH2=PHI
 1280 FOR L=U TO U5
 1290 GOSUB CO1
 1300 IF GO=G THEN GOTO G
 1310 GOSUB DD
 1320 IF DAZ>CT OR DEL>CT THEN GOTO 1340
 1330 IF (DAZ>CB OR DEL>CB) AND INT Q=INT Q1 THEN GOTO 1540
 1340 LET D1=DAZ
 1350 IF DEL>DAZ THEN LET D1=DEL
 1360 LET PHI=CA*PHI/D1
 1370 LET D=D2
 1380 IF INT Q=INT Q1 AND PHI>1E-5 THEN NEXT L
 1390 LET PHI=PH2
 1400 LET ER=G
 1410 GOSUB CO1
 1420 IF GO=G THEN GOTO G
 1430 GOSUB DD
 1440 IF DAZ>CT OR DEL>CT THEN GOTO 1470
 1450 IF DAZ>CB OR DEL>CB THEN GOTO 1530
 1460 IF ER=G THEN GOTO LSC
 1470 LET ER=U
 1480 LET D1=DAZ
 1490 IF DEL>DAZ THEN LET D1=DEL
 1500 LET D1=SGN (D1-CA)
 1510 LET PHI=-HA*ABS PHI*D1
 1520 GOTO LSC
 1530 LET PHI=PH2
 1540 IF E9>HA THEN GOTO 1580
 1550 LET LOS=-U
 1560 GOSUB SCH
 1570 IF GO=G THEN GOTO G
 1580 IF T6<>D THEN LET F8=F(I)*(R6-R5)/(D-T6)/CL
 1590 LET R6=R5
 1600 LET T6=D
 1610 GOTO 1190
 1620 LET DAZ=ABS (A9-A8)
 1630 IF DAZ>180 THEN LET DAZ=360-DAZ
 1640 LET DAZ=ABS (DAZ*(COS (E9*P0)))
 1650 LET DEL=ABS (E9-E8)
 1660 RETURN 
 1670 IF INT D=D0 THEN GOTO 1760
 1680 LET D$=N$
 1690 LET J=U9
 1700 GOSUB DAO
 1710 IF GO=U2 OR GO=U7 THEN GOSUB SS
 1720 PRINT AT LP,G;"       ----";D$( TO U7);"----          "
 1730 LET D0=INT D
 1740 LET LP=LP+U
 1750 IF LP>U20 AND GO<>U2 AND GO<>U7 THEN GOTO HD2
 1760 LET D$="       "
 1770 LET J=U
 1780 GOSUB TIM
 1790 IF GO=G THEN RETURN 
 1800 GOSUB LZ3
 1810 GOSUB LZ2
 1820 LET D$=D$( TO U4)+":"+D$(U5 TO )+STR$ INT R5+" "
 1830 IF LEN D$>=U21 THEN GOTO 1860
 1840 LET D$=D$( TO U15)+D$(U15 TO )
 1850 GOTO 1830
 1860 IF E(I)>=U01 THEN LET D$=D$+STR$ INT (M/P2*256)+" "
 1870 IF E(I)<U01 THEN LET D$=D$+"--- "
 1880 IF LEN D$>=U25 THEN GOTO 1910
 1890 LET D$=D$( TO U21)+D$(U21 TO )
 1900 GOTO 1880
 1910 LET A$=STR$ (INT (F8/HUN+HA)/TEN)
 1920 IF INT VAL A$=VAL A$ THEN LET A$=A$+".0"
 1930 IF F8=G THEN LET A$=STR$ F(I)
 1940 LET D$=D$+A$+" "
 1950 IF LEN D$>=U32 THEN GOTO 1980
 1960 LET D$=D$( TO U25)+D$(U25 TO )
 1970 GOTO 1950
 1980 IF GO=U2 OR GO=U7 THEN GOSUB SS
 1990 IF GO=G THEN RETURN 
 2000 PRINT AT LP,G;D$( TO U32)
 2010 LET LP=LP+U
 2020 IF LP<U21 OR GO=U2 OR GO=U7 THEN RETURN 
 2030 IF GO=U3 THEN GOTO HD2
 2040 LET GO=U9
 2050 PRINT J$
 2060 GOSUB KSC
 2070 IF GO=U9 THEN GOTO 2060
 2080 GOSUB CLB
 2090 IF GO=G OR GO=U2 OR GO=U7 THEN RETURN 
 2100 CLS 
 2110 LET D0=INT D
 2120 GOSUB DAO
 2130 PRINT AT G,G;H$;"  TRACKING FROM ";D$,"  >>";C$;" VIA ";S$(I);"<<","% % %U%T%C% % % % %A%Z% %E%L% %R%A%N%G%E% %P%H%S% %D%O%P%P%L%E%R"
 2140 LET LP=U4
 2150 LET GO=U
 2160 RETURN 
 2170 IF GO=U2 AND ST=U9 THEN GOTO 2240
 2180 PRINT AT U21,G;J$
 2190 LET GO=U9
 2200 GOSUB KSC
 2210 IF GO=U9 THEN GOTO 2200
 2220 GOSUB CLB
 2230 IF GO<>U2 AND GO<>U7 AND GO<>G THEN LET GO=U3
 2240 SCROLL 
 2250 LET LP=U20
 2260 PRINT AT U21,U31;
 2270 RETURN 
 2280 PRINT AT U21,G;N$;N$;" "
 2290 RETURN 
 2300 IF A$<>"3" THEN GOTO 2820
 2310 GOSUB SAT
 2320 IF GO=G THEN GOTO G
 2330 CLS 
 2340 PRINT H$;AT U2,G;"%N%A%M%E% ";AT U2,U7;S$(I)
 2350 PRINT AT U18,G;L$;K$
 2360 INPUT A$
 2370 IF A$="" THEN GOTO 2410
 2380 LET SV=U
 2390 LET S$(I)=A$
 2400 PRINT AT U2,U7;S$(I);N$
 2410 PRINT AT U3,G;"%I%D% % % ";AT U3,U7;I$(I)
 2420 INPUT A$
 2430 IF A$="" THEN GOTO 2470
 2440 LET SV=U
 2450 LET I$(I)=A$
 2460 PRINT AT U3,U7;I$(I);N$
 2470 LET D=T(I)
 2480 GOSUB DAO
 2485 IF GO=G THEN GOTO G
 2490 PRINT AT U4,G;"%E%P%O%C%H";AT U4,U7;D$
 2500 INPUT D$
 2510 IF D$="" THEN GOTO 2610
 2520 PRINT AT U4,U7;D$;X$
 2530 GOSUB DAY
 2540 IF ER=G THEN GOTO 2570
 2550 GOSUB 3250
 2560 GOTO 2500
 2570 LET T(I)=D
 2580 LET SV=U
 2590 GOSUB DAO
 2600 PRINT AT U4,U7;D$;N$
 2610 FOR J=U TO U8
 2620 LET A(J)=VAL E$(J,U5 TO TEN)
 2630 PRINT AT J+U4,G;E$(J, TO U4);"%   ";A(J);X$
 2640 INPUT A$
 2650 IF A$="" THEN GOTO 2690
 2660 LET A(J)=VAL A$
 2670 PRINT AT J+U4,U7;A(J);X$
 2680 LET SV=U
 2690 NEXT J
 2700 LET N(U2,I)=A(U7)
 2710 LET I(I)=A(U)
 2720 LET O(I)=A(U2)
 2730 LET E(I)=A(U3)
 2740 LET W(I)=A(U4)
 2750 LET M(I)=A(U5)
 2760 LET N(U,I)=A(U6)
 2770 LET F(I)=A(U8)
 2780 IF A$="" THEN GOTO G
 2790 PRINT AT U18,G;"##";K$;N$
 2800 INPUT A$
 2810 GOTO G
 2820 IF A$<>"4" THEN GOTO 3130
 2830 CLS 
 2840 PRINT H$,,"%C%A%L%L%   ";C$;AT U18,G;L$;K$
 2850 INPUT A$
 2860 IF A$="" THEN GOTO 2900
 2870 LET C$=A$
 2880 PRINT AT U2,U7;C$;N$
 2890 LET SV=U
 2900 FOR J=U9 TO 11
 2910 LET A(J-U8)=VAL E$(J,U6 TO U9)
 2920 PRINT AT J-U6,G;E$(J, TO U5);TAB U7;A(J-U8)
 2930 INPUT A$
 2940 IF A$="" THEN GOTO 2980
 2950 LET A(J-U8)=VAL A$
 2960 PRINT AT J-U6,U7;A(J-U8);N$
 2970 LET SV=U
 2980 NEXT J
 2990 LET L9=A(U)
 3000 LET W9=A(U2)
 3010 LET H9=A(U3)
 3020 LET L8=L9*P0
 3030 LET S9=SIN L8
 3040 LET C9=COS L8
 3050 LET S8=SIN (-W9*P0)
 3060 LET C8=COS (W9*P0)
 3070 LET R9=R0*(U-F/U2+F/U2*COS (U2*L8))+H9/THO
 3080 LET L8=ATN ((U-F)**U2*S9/C9)
 3090 LET Z9=R9*SIN L8
 3100 LET X9=R9*COS L8*C8
 3110 LET Y9=R9*COS L8*S8
 3120 GOTO 2780
 3130 IF A$<>"5" OR SV=G THEN GOTO G
 3140 CLS 
 3150 PRINT H$,TAB U2;"@@START RECORDER.....";K$
 3160 LET A$=INKEY$
 3170 IF A$="" THEN GOTO 3160
 3180 IF A$="0" THEN GOTO G
 3190 PRINT ,,TAB U3;" SAVE BEGINS IN 20 SECONDS"
 3200 PAUSE THO
 3210 LET SV=G
 3220 SAVE "AMS8%1"
 3230 GOTO G
 3240 CLS 
 3250 PRINT AT U6,G;D$;AT U7,G;"EPOCH INPUT ERROR. USE FORMAT:","83 105.46677538",,"   > OR <",,"15APR83 111209"
 3260 RETURN 
 3270 IF GO=U9 AND ST=U9 OR FS=G THEN SLOW 
 3280 LET F$=INKEY$
 3290 IF F$="" THEN GOTO 3410
 3300 PRINT AT U21,U31;F$
 3310 IF F$<>"0" THEN GOTO 3350
 3320 LET GO=G
 3330 LET ST=U9
 3340 RETURN 
 3350 IF CODE F$<38 AND CODE F$>27 THEN GOTO 3400
 3360 IF F$="F" THEN LET FS=U
 3370 IF F$="D" THEN LET FS=G
 3380 IF F$="T" THEN LET D0=INF
 3390 GOTO KSE
 3400 LET ST=VAL F$
 3410 IF GO<>U9 THEN GOTO KSE
 3420 LET GO=ST
 3430 LET ST=U9
 3440 IF FS=U AND GO<>U9 THEN FAST 
 3450 RETURN 
 3460 GOSUB KSC
 3470 IF GO=G OR K=K9 THEN RETURN 
 3480 IF N(U,I)=G THEN LET N(U,I)=HUN
 3490 IF N(U,I)>HUN THEN GOTO 3530
 3500 LET N0=N(U,I)
 3510 LET A0=(G0/N0/N0)**(U/U3)
 3520 GOTO 3550
 3530 LET A0=N(U,I)
 3540 LET N0=SQR (G0/N(U,I)**U3)
 3550 LET N=N0+U2*(D-T(I))*N(U2,I)
 3560 LET A=(G0/N/N)**(U/U3)
 3570 IF N<G OR A<R0 THEN GOTO 3930
 3580 IF E(I)>=0 AND E(I)<1 THEN GOTO 3610
 3590 PRINT "BAD ECCENTRICITY"
 3600 GOTO 3940
 3610 LET E2=U-E(I)**U2
 3620 LET E1=SQR E2
 3630 LET Q0=M(I)/360
 3640 LET AF=U/ABS (U-SQR ABS (COS (I(I)*P0)*COS (L9*P0))/N)/A/N/360
 3650 LET K2=9.95*(R0/A)**3.5/E2**U2
 3660 LET S1=SIN (I(I)*P0)
 3670 LET C1=COS (I(I)*P0)
 3680 LET O=O(I)-(D-T(I))*K2*C1
 3690 LET S0=SIN (O*P0)
 3700 LET C0=COS (O*P0)
 3710 LET W=W(I)+(D-T(I))*K2*(2.5*C1*C1-HA)
 3720 LET S2=SIN (W*P0)
 3730 LET C2=COS (W*P0)
 3740 LET C(U,U)=C2*C0-S2*S0*C1
 3750 LET C(U2,U)=C2*S0+S2*C0*C1
 3760 LET C(U3,U)=S2*S1
 3770 LET C(U,U2)=-S2*C0-C2*S0*C1
 3780 LET C(U2,U2)=-S2*S0+C2*C0*C1
 3790 LET C(U3,U2)=C2*S1
 3800 LET G2=G(INT (T(I)/DYR)+U3)
 3810 LET D1=D
 3820 LET D=INT (T(I)/DYR)+U81
 3830 LET D$=STR$ D+" 000."
 3840 GOSUB DAY
 3850 LET Y0=D
 3860 LET K9=K
 3870 LET D=D1
 3880 LET D1=P2/U4
 3890 IF L9<G THEN LET D1=D1*U3
 3900 LET J=I(I)*P0
 3910 IF J>PI/U2 THEN LET J=PI-J
 3920 IF ACS (R0*(U+E(I)*COS (D1-W*P0))/A/(U-E(I)**U2))+J>ABS L9*P0 THEN RETURN 
 3930 PRINT "##PASSES CANNOT OCCUR ";K$
 3940 SLOW 
 3950 LET GO=G
 3960 IF INKEY$="" THEN GOTO 3960
 3970 RETURN 
 3980 LET D2=D
 3990 LET D=D+PHI
 4000 LET Q1=Q
 4010 LET Q=Q0+(D-T(I))*(N0+N(U2,I)*(D-T(I)))
 4020 LET K=INT Q
 4030 LET M=(Q-K)*P2
 4040 RETURN 
 4050 GOSUB KSC
 4060 IF GO=G THEN RETURN 
 4070 LET ER=U
 4080 IF LEN D$<U7 THEN RETURN 
 4090 IF CODE D$(U3)>37 THEN GOTO 4220
 4100 FOR L=U TO LEN D$
 4110 IF L=U3 OR L=U7 THEN GOTO 4130
 4120 IF CODE D$(L)>U37 OR CODE D$(L)<U28 THEN RETURN 
 4130 NEXT L
 4140 IF D$(U7)<>"." AND D$(U7)<>" " THEN RETURN 
 4150 LET D=INT (VAL D$(U4 TO U6)+DYR*(VAL D$(U TO U2)-U81))
 4160 IF D$(U7)="." THEN LET D=D+VAL D$(U7 TO LEN D$)
 4170 IF LEN D$>=U13 THEN GOTO 4190
 4180 LET D$=D$+"000000"
 4190 IF D$(U7)<>"." THEN LET D=D+((VAL D$(U12 TO U13)/U60+VAL D$(TEN TO 11))/U60+VAL D$(U8 TO U9))/U24
 4200 LET ER=G
 4210 RETURN 
 4220 IF LEN D$<U8 THEN RETURN 
 4230 FOR L=U TO U12
 4240 IF D$(U3 TO U5)=M$(L,U TO U3) THEN GOTO 4270
 4250 NEXT L
 4260 RETURN 
 4270 LET D$(U3 TO U5)=M$(L,U4 TO U6)
 4280 FOR L=U TO LEN D$
 4290 IF L=U8 THEN GOTO 4310
 4300 IF CODE D$(L)>U37 OR CODE D$(L)<U28 THEN RETURN 
 4310 NEXT L
 4320 LET Y3=VAL D$(U6 TO U7)
 4330 IF Y3<TEN THEN RETURN 
 4340 LET F9=G
 4350 IF Y3/U4=INT (Y3/U4) AND VAL D$(U3 TO U5)>58 THEN LET F9=U
 4360 LET D=INT ((Y3-U81)*DYR)
 4370 LET D=D+VAL D$(U3 TO U5)+VAL D$(U TO U2)+F9
 4380 LET D$=D$(U2 TO LEN D$)
 4390 GOTO 4160
 4400 LET ER=G
 4410 LET Y3=U81+(INT D-U01)/DYR
 4420 LET D1=INT (DYR*(Y3-INT Y3))
 4430 LET Y3=INT Y3
 4440 LET F9=G
 4450 IF Y3/U4=INT (Y3/U4) AND D1>=59 THEN LET F9=U
 4460 LET D1=D1-F9
 4470 FOR L=U TO U12
 4480 IF D1>=VAL M$(L,U4 TO U6) THEN NEXT L
 4490 LET D$=M$(L-U,U TO U3)
 4500 IF F9=U AND D1=58 THEN LET D1=59
 4510 LET D1=D1+U-VAL M$(L-U,U4 TO U6)
 4520 LET D$=STR$ INT D1+D$+STR$ Y3
 4530 IF D1<TEN THEN LET D$="0"+D$
 4540 LET J=U9
 4550 LET D$=D$+"       "
 4560 LET D1=(D-INT D+5E-6)*24
 4570 GOSUB KSC
 4580 FOR L=J TO J+U4 STEP U2
 4590 LET D$(L TO L+U)=STR$ INT D1
 4600 IF D1<TEN THEN LET D$(L TO L+U)="0"+STR$ INT D1
 4610 LET D1=(D1-INT D1)*U60
 4620 NEXT L
 4630 RETURN 
 4640 CLS 
 4650 PRINT H$,
 4660 IF A$="1" THEN PRINT TAB U2;"%<%<%<% %S%C%H%E%D%U%L%I%N%G% % %A%C%T%I%V%I%T%Y% %>%>%>"
 4670 IF A$="2" THEN PRINT TAB U3;"%<%<%<% %T%R%A%C%K%I%N%G% % %A%C%T%I%V%I%T%Y% %>%>%>"
 4680 IF A$="3" THEN PRINT TAB U2;"%<%<% %K%E%P%L%E%R%I%A%N% %F%I%L%E% %U%P%D%A%T%E% %>%>%>"
 4690 PRINT 
 4700 FOR I=U TO U14
 4710 PRINT CHR$ (I+U37);" = ";S$(I)
 4720 LET A$=INKEY$
 4730 IF A$<>"" THEN GOTO 4780
 4740 NEXT I
 4750 PRINT ,,"##SELECT A-N (RETURN=0)##";
 4760 LET A$=INKEY$
 4770 IF A$="" THEN GOTO 4760
 4780 PRINT AT U19,U24;A$
 4790 LET I=CODE A$-U37
 4800 IF I>U14 OR I<U THEN LET GO=G
 4810 RETURN 
 4820 IF E9<U9H THEN LET D$=D$+"0"
 4830 LET D$=D$+STR$ INT (E9+HA)+" "
 4840 RETURN 
 4850 IF A9<99.5 THEN LET D$=D$+"0"
 4860 IF A9<U9H THEN LET D$=D$+"0"
 4870 LET D$=D$+STR$ INT (A9+HA)+" "
 4880 RETURN 
 4890 LET K9=INF
 4900 LET PHI=G
 4910 GOSUB SAT
 4920 IF GO=G THEN RETURN 
 4930 PRINT ,,S$(I, TO U9);" EPOCH: ";AT U19,G;"@@ENTER EPOCH DATE+TIME ";K$
 4940 INPUT D$
 4950 LET FS=U
 4960 PRINT AT U21,17;D$
 4970 IF D$<>"S" THEN GOTO 5000
 4980 LET D=D3
 4990 RETURN 
 5000 IF D$<>"0" THEN GOTO 5030
 5010 LET GO=G
 5020 RETURN 
 5030 GOSUB DAY
 5040 IF ER<>G THEN GOTO 5070
 5050 LET D3=D
 5060 RETURN 
 5070 GOSUB 3240
 5080 SLOW 
 5090 GOTO 4940
 5100 LET E=M+E(I)*SIN M+HA*E(I)**U2*SIN (U2*M)
 5110 LET M5=E-E(I)*SIN E-M
 5120 LET R3=U-E(I)*COS E
 5130 IF ABS M5<1E-6 THEN GOTO 5160
 5140 LET E=E-M5/R3
 5150 GOTO 5110
 5160 LET X=A*(COS E-E(I))
 5170 LET Y=A*E1*SIN E
 5180 LET R=A*R3
 5190 LET Z=X*C(U3,U)+Y*C(U3,U2)
 5200 LET X0=X*C(U,U)+Y*C(U,U2)
 5210 LET Y=X*C(U2,U)+Y*C(U2,U2)
 5220 LET G7=(D-Y0)*G1+G2
 5230 LET G7=(G7-INT G7)*P2
 5240 LET X=X0*COS G7+Y*SIN G7
 5250 LET Y=-X0*SIN G7+Y*COS G7
 5260 RETURN 
 5270 GOSUB CO4
 5280 IF GO=G THEN RETURN 
 5290 LET X8=-X5*C8*S9-Y5*S8*S9+Z5*C9
 5300 LET Y8=Y5*C8-X5*S8
 5310 GOSUB KSC
 5320 IF X8<>G THEN GOTO 5360
 5330 LET A9=90
 5340 IF Y8<G THEN LET A9=270
 5350 RETURN 
 5360 LET A9=ATN (Y8/X8)/P0
 5370 IF X8<G THEN LET A9=A9+180
 5380 IF A9<G THEN LET A9=A9+360
 5390 RETURN 
 5400 GOSUB 3980
 5410 GOSUB KSC
 5420 IF GO=G THEN RETURN 
 5430 GOSUB 5100
 5440 LET X5=X-X9
 5450 LET Y5=Y-Y9
 5460 LET Z5=Z-Z9
 5470 LET QS=X5*X9+Y5*Y9+Z5*Z9
 5480 GOSUB KSC
 5490 RETURN 
 5500 GOSUB CO3
 5510 IF GO=G THEN RETURN 
 5520 LET R5=SQR (X5*X5+Y5*Y5+Z5*Z5)
 5530 LET E9=ASN ((X5*C8*C9+Y5*S8*C9+Z5*S9)/R5)/P0
 5540 RETURN 
 5550 LET E8=SGN QS
 5560 LET PHI=-SGN QS*IN*R*AF*LOS
 5570 GOSUB INK
 5580 GOSUB CO3
 5590 IF GO=G THEN RETURN 
 5600 IF SGN QS=E8 THEN GOTO 5560
 5610 LET PHI=-HA*ABS PHI*SGN QS*LOS
 5620 GOSUB CO4
 5630 IF GO=G THEN RETURN 
 5640 IF ABS E9<HA THEN RETURN 
 5650 GOTO 5610

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top