Skip to content

FORTRAN Source Overview

The FORTRAN IV source code presented here is the original implementation of the five NORAD satellite propagation models: SGP, SGP4, SDP4, SGP8, and SDP8. This code was extracted from the printed source listing in the 1980 report — no authoritative digital source files have ever existed.

FileLinesDescription
driver.f113Main driver program with WGS-72 constants
sgp.f109SGP model (Simplified General Perturbations)
sgp4.f215SGP4 model with Brouwer mean elements
sdp4.f187SDP4 deep-space model (calls DEEP)
sgp8.f185SGP8 model with Hoots drag
sdp8.f226SDP8 deep-space model (column 72 fix)
deep.f451DEEP subroutine — lunar-solar perturbations
actan.f22Four-quadrant arctangent
fmod2p.f11Modulo 2π\pi
thetag.f22Greenwich sidereal angle

To compile with modern gfortran:

Terminal window
FFLAGS = -O0 -w -fdefault-real-8 -fno-automatic
gfortran $(FFLAGS) -c sgp.f sgp4.f sdp4.f sgp8.f sdp8.f deep.f \
driver.f actan.f fmod2p.f thetag.f
gfortran $(FFLAGS) -o spacetrk *.o

Each flag is required:

FlagPurpose
-O0Disable optimization — the ENTRY point pattern miscompiles at -O1+
-wSuppress warnings for Hollerith constants, assigned GOTOs
-fdefault-real-8Promote all REAL to 8-byte, matching original assumptions
-fno-automaticEmulate FORTRAN IV static local variable allocation

FORTRAN IV uses fixed-format source inherited from the 80-column punch card:

ColumnsPurpose
1–5Statement labels (numeric)
6Continuation character (any non-blank, non-zero)
7–72Source code — the only columns the compiler reads
73–80Sequence numbers (silently ignored)

The column 72 boundary is invisible in every visual representation of the source. Anything past it is silently discarded. This is the root cause of the transcription problem that produced decades of divergent SGP4 implementations.

No authoritative digital source files for the 1980 FORTRAN have ever existed. Every digital copy in circulation was produced by hand-typing, OCR, PDF text extraction, or copying from someone else’s copy — all methods vulnerable to column-shift errors.

During our 2026 extraction, a continuation line in sdp8.f was indented too deeply, pushing the I in COSI to column 73. The compiler silently discarded it, turning *COSI into *COS — a function call with no arguments. This is precisely the kind of invisible bug that plagued card-punch era programming and contributed to 25 years of divergent SGP4 implementations, as documented in Vallado et al.’s Rev-1 paper.

Five changes from the original printed source to compile on modern gfortran:

  1. CHARACTER*80 ABUF(2) — the original CHARACTER ABUF*80(2) placed the length specifier between variable name and dimension, a non-standard syntax
  2. READ for DECODE — replaced DEC/VAX DECODE extension with standard FORTRAN 77 internal READ
  3. DOUBLE PRECISION T in deep.f — explicit declaration for the DPSEC entry point parameter that was implicitly REAL
  4. Cross-entry local copiesSIQSAV, CIQSAV, OGDSAV, TSAVE to avoid accessing dummy arguments from foreign entry points
  5. Column 72 fix in sdp8.f — re-indented the continuation line to keep COSI within the active code region

All 25 reference vectors from Chapter 13 were verified against the compiled binary:

ModelTypeMax Position ErrorMax Velocity Error
SGPNear-earth0.011 km0.000012 km/s
SGP4Near-earth0.001 km0.000001 km/s
SGP8Near-earth0.000 km0.000000 km/s
SDP4Deep-space1.769 km0.001366 km/s
SDP8Deep-space1.463 km0.000680 km/s

Near-earth models achieve sub-meter agreement. Deep-space models show 1–2 km drift at large propagation times due to the precision difference between our full double-precision compilation and the original mixed single/double precision reference values.