[comp.sys.handhelds] HP48: Aviation/Flight Planning programs

anderson@truebalt.caltech.edu (Eric R. Anderson) (06/06/91)

   What follows is a group of programs making up an electronic flight
computer of sorts.  The flight computer is made up of 6 functions:

      Weight and Balance with 9 plane memory and CG graphing
      Flight plan of up to eight legs
      Winds aloft calculation
      Density altitude
      Distance and heading between two points
      Crosswind components

Each will be described more fully later.  These functions can be accessed
either alone, or by selecting from a menu presented by running START.
There is a minimal amount of error checking in the programs, but if run
from the START menu, the stack will be cleaned up if an error does occur.
If flag 10 is set, the output of some of the program is changed to metric.
Units are allowed (even encouraged) unless noted below, and appropriate 
conversions made.  Extensive use is made of PGROB and UPGROB from Erik Bryntse,
and they are included in the directory.  The last four functions could be done
much more compactly with the equation solver, but the programs provide a front
end for things.  The CST menu is also defined for conversions between fuel
volume and weight (at 6lbs/gal).
   The whole thing is rather large, and to download on my 30K calculator
requires removing everthing but ASC-> and ->ASC.  ASC-> is required to unpack
the directory.  When I download it, everything goes fine until the last packet
or two, when the calculator quits responding.  Both Kermits eventually time out,
and the directory is present and whole on the calculator.  I'm not sure if this
is just my calculator, or what.  If it happens, just be patient.  Once
downloaded, press AERO to get into the directory, then SETUP to unpack it.
Press START to begin.

                             Notes:

FPLAN, WIND, and CWIND use vector arithmetic, so beware if you have a
version with the vector bug.  The checksums are:

 Before unpacking: #11040d
                   23664.5

 After unpacking:  # 5241d
                   17881.5

Disclaimer:  Use at your own risk.  Feel free to redistribute in whole
or in part if it strikes your fancy.  If you want to make improvements, go
ahead - I'm graduating in a week and a half, and losing net access, so I can't
post any I make.

                             Program Descriptions:

  The primary programs are described in the order they appear in the VAR menu.
Since the directory is rather large, I have included a list of programs
that call each program, so if you decide you don't want one of the functions,
you can delete all the programs that only it calls.  To save memory, I run
without START and HELP, which saves about 5K.  I apologise if the descriptions
are a little cryptic.  The program follows the descriptions.

START:  Called by: None
        Use the arrow keys to move around, and ENTER to select choice.
        Press any key to return to menu after program execution.
HELP:   Called by: START, self executable
        Presents three short help screens.
FPLAN:  Called by: START, self executable
        Computes magnetic heading, groundspeed, time en route, and fuel
        burn for up to eight legs of a flight.  If units are entered for
        distance or fuel consumption rate on the first leg, units must be
        entered for each remaining leg.  Time is shown in Hours:minutes
        format.
W&B:    Called by: START, self executable
        Compute weight and balance for selected aircraft, and plots weight
        vs moment arm if graph is defined for aircraft.  Output is metric
        if flag 10 is set.  If a graph has been defined for the plane chosen,
        flag 10 must be set so the output matches the units used in defining
        the graph for the graph to be valid.  Choose ADD/DELETE to add a new
        plane or delete an old one.  When adding a plane, select 0 for the
        number of points in the graph to save memory.  If you want to define
        a graph, select a number of points equal to the number of line
        segments in the graph + 1.  A line will be drawn from each point to the
        next point entered.  Points are entered in the form (without units)
        { moment/1000 weight }.  When asked for a station name, keep in
        mind that W&B will append "weight and moment arm" after the name
        you supply.
WIND:   Called by: START, self executable
        Calculates winds aloft from true course, ground speed, true heading
        and true airspeed.
DALT:   Called by: START, self executable
        Calculates density altitude from pressure altitude and temperature.
        Valid only for altitudes less than 36000 ft.
DISTANCE: Called by: START, self executable
        Calculates distance and true heading between two points of
        latitude and longitude entered in hhh.mmss form.  Points in
        the southern or eastern hemisphere may need to be entered as
        negative.  The program has only been tested for points N and W.
CWIND:  Called by: START, self executable
        Given a heading and wind speed and direction, calculates headwind
        and crosswind components.  Does not support units - units of
        components are same as of wind speed.
PAUSE:  Called by: START
TRAP:   Called by: START
MAKEMENU: Called by: none
        Utility to make a menu for use with CHOOSE.
ADDPLANE: Called by: W&B
STRIP:  Called by: START, FPLAN
PAD:    Called by: START
CHOOSE: Called by: START, W&B, ADDPLANE
        Call with initial cursor position in stack level 2, and the menu grob
        in level 1.  Returns cursor postion when ENTER is pressed.
ADDGRAPH: Called by: ADDPLANE
SCL:    Called by: ADDGRAPH, CGGRAPH
WBIN:   Called by: W&B
CGGRAPH: Called by: W&B
PGROB, UPGROB: Called by: HELP,CHOOSE, ADDPLANE, CGGRAPH, ADDGRAPH, FPLAN
PLANES: Called by W&B, ADDPLANE
        Stores the list of planes for use by W&B. Each plane list has the format
        { { CGgraph maxmoment minmoment maxweight minweight }
          { { station1name station1weight station1arm }
            { station2name station2weight station2arm }
                                .
                                .
                                .
            { stationNname stationNweight stationNarm } }
          "Plane name"
        }
FPLAN.GROB: Called by: FPLAN
HELP.{123}: Called by: HELP
STMENU: Called by: START
WBMENU: Called by: W&B, ADDPLANE
CURSOR: Called by: CHOOSE
UNITMENU: Called by: W&B, ADDPLANE
PLMENU: Called by: ADDPLANE
DESCMENU: Called by: ADDPLANE
Gal: Called by: W&B, FPLAN, ADDPLANE, CST    (Defines 1 Gallon = 6 lbs)
L: Called by: W&B, FPLAN, ADDPLANE, CST
CST: Called by: None

----------Cut here ---------
%%HP: T(3)A(R)F(.);
DIR
  SETUP
    \<<
      IF 'ASC\->' VTYPE -1 ==
      THEN
        "ASC\-> must be in this\010 or higher directory"
        DOERR
      END
      CURSOR ASC\-> 'CURSOR' STO
      PGROB ASC\-> 'PGROB' STO
      UPGROB ASC\-> 'UPGROB' STO
      FPLAN.GROB ASC\-> 'FPLAN.GROB' STO
      HELP.3 ASC\-> 'HELP.3' STO
      HELP.2 ASC\-> 'HELP.2' STO
      HELP.1 ASC\-> 'HELP.1' STO
      STMENU ASC\-> 'STMENU' STO
      WBMENU ASC\-> 'WBMENU' STO
      MEM DROP
      PLANES ASC\-> 'PLANES' STO
      'SETUP' PURGE
    \>>
  START.
    \<< RCLF DEPTH 'STRT.DPTH' STO
        IFERR
          1
          DO
            STMENU CHOOSE
            {
          \<<
            IF 'W&B' TRAP
            THEN
              DUP2 CLLCD "        Weight" 1 DISP
              SWAP DTAG \->STR DUP "_" POS " " REPL "'" STRIP PAD 3 DISP
              "      Moment Arm" 5 DISP
              DTAG \->STR DUP "_" POS " " REPL "'" STRIP PAD 7 DISP
              { } TMENU TEXT PAUSE
            END
            1 0
          \>>
          \<< 'FPLAN' TRAP DROP 2 0 \>>
          \<<
            IF 'WIND' TRAP
            THEN
              DUP2 CLLCD "   Winds Aloft From" 1 DISP
              SWAP DTAG \->STR PAD 3 DISP
              "          At" 5 DISP DTAG
              IF DUP TYPE 13 ==
              THEN \->STR "'" STRIP DUP "_" POS " " REPL
              ELSE \->STR
              END
              PAD 7 DISP
              { } TMENU PAUSE
            END
            3 0
          \>>
          \<<
            IF 'DALT' TRAP
            THEN
              CLLCD DUP "   Density Altitude:" 4 DISP
              DTAG \->STR DUP "_" POS " " REPL "'" STRIP PAD 6 DISP
              { } TMENU PAUSE
            END
            4 0
          \>>
          \<<
            IF 'DISTANCE' TRAP
            THEN
              CLLCD DUP2 "     True Heading" 5 DISP
              DTAG \->STR PAD 7 DISP
              "       Distance" 1 DISP
              DTAG \->STR DUP "_" POS " " REPL "'" STRIP PAD 3 DISP
              { } TMENU PAUSE
            END
            5 0
          \>>
          \<<
            IF 'CWIND' TRAP
            THEN
              DUP2 CLLCD
              DUP \->STR 1 " " REPL DUP ":" POS 1 - 1 SWAP SUB PAD 5 DISP
              DTAG \->STR PAD 7 DISP
              DUP \->STR 1 " " REPL DUP ":" POS 1 - 1 SWAP SUB " Crosswind" +
              PAD 1 DISP
              DTAG \->STR PAD 3 DISP
              { } TMENU PAUSE
            END
            6 0
          \>>
          { 7 0 }
          { 8 0 }
          \<< HELP 9 0 \>>
          { 1 }
            }
            SWAP GET EVAL
          UNTIL
          END
        THEN
        END
        2 MENU CLLCD
        DEPTH STRT.DPTH - DROPN
        STOF 'STRT.DPTH' PURGE
    \>>
  HELP
    \<<
      IFERR
        PICT { # 0d # 0d } HELP.1 UPGROB REPL
        { # 0d # 0d } PVIEW
        0 WAIT DROP
        PICT { # 0d # 0d } HELP.2 UPGROB REPL
        0 WAIT DROP
        PICT { # 0d # 0d } HELP.3 UPGROB REPL
        0 WAIT DROP
      THEN DROP
      END
    \>>
  FPLAN
\<<
   RCLF -15 CF -16 SF DEG STD
   PICT  { # 0d # 0d } FPLAN.GROB UPGROB REPL
   ":Course: \010:Distance: " ":Variation: " ":TAS: "
   ":WD: \010:WS: " ":FCR: "    1 0 0 0
   \->
   tcdef vardef tasdef winddef fcrdef speedunit totdist tottime totfuel
  \<<
    1
    DO
      "Enter number of legs,\010maximum 8" "" INPUT OBJ\->
      IF DUP 9 < THEN 1 ELSE DROP 1400 .08 BEEP 0 END
    UNTIL
    END
    FOR j
     { { "mi" "_mi" } { "nmi" "_nmi" } "" "" "" { "km" "_km" } } TMENU
     "Leg X: Enter TRUE\010course and distance" 5 j \->STR REPL
     tcdef -10 2 \->LIST INPUT
     DUP 'tcdef' STO OBJ\-> DTAG SWAP DTAG SWAP
     { { "W" "_W" } "" "" "" "" { "E" "_E" } } TMENU
     "Leg X: Enter Variation\010(- or W , + or E)" 5 j \->STR REPL
     vardef -13 2 \->LIST INPUT
     DUP 'vardef' STO OBJ\-> DTAG
     { { "mph" "_mph" } { "knot" "_knot" } "" "" "" { "kph" "_kph" } } TMENU
     "Leg X: Enter True\010Airspeed" 5 j \->STR REPL
     tasdef -7 2 \->LIST INPUT
     DUP 'tasdef' STO OBJ\-> DTAG
     IF DUP TYPE 13 == THEN DUP 'speedunit' STO UVAL END
     "Leg X: Enter Wind\010Direction and Speed" 5 j \->STR REPL
     winddef -6 2 \->LIST INPUT
     DUP 'winddef' STO OBJ\-> DTAG
     IF DUP TYPE 13 ==
     THEN
       IF speedunit TYPE 13 ==
       THEN speedunit CONVERT UVAL
       ELSE DUP 'speedunit' STO UVAL
       END
     END
     SWAP 180 + \->V2
     { { "gph" "_Gal/h" } { "lb/h" "_lb/h" } ""
       "" { "L/h" "_L/h" } { "kg/h" "_kg/h" } } TMENU
     "Leg X: Enter rate of\010fuel consumption" 5 j \->STR REPL
     fcrdef -7 2 \->LIST INPUT
     DUP 'fcrdef' STO OBJ\->
     6 ROLLD DUP 6 PICK 90 + 1 SWAP \->V2 DOT NEG 3 PICK / ASIN 6 PICK +
     DUP 4 ROLL SWAP \->V2 ROT +
     1 6 PICK \->V2 DOT
     IF speedunit TYPE 13 == THEN speedunit \->UNIT END
     SWAP ROT
     IF DUP TYPE 13 ==
     THEN
       IF DUP \->STR "W" POS THEN NEG END UVAL
     END
     - 0 RND
     SWAP DUP 4 PICK SWAP /
     IFERR '1_h' CONVERT THEN DROP UVAL '1_h' \->UNIT END
     DUP 7 ROLL * UVAL DUP 'totfuel' STO+
     IF DUP 99 > THEN 0 RND \->STR ELSE 1 FIX \->STR STD END
     IF DUP SIZE 4 < THEN " " SWAP + END
     SWAP UVAL DUP 'tottime' STO+
     \->HMS 2 FIX \->STR 2 ":" REPL STD
     ROT 0 RND DUP \->STR SWAP
     IF TYPE 13 == THEN "'" STRIP DUP "_" POS " " REPL END
     WHILE DUP SIZE 8 < REPEAT " " SWAP + END
     5 ROLL DUP 'totdist' STO+
     UVAL
     1 6 FOR k
       PICT
       { # 46d # 60d # 97d # 114d # 30d # 16d } k GET
       9 j 1 - 6 * + R\->B
       2 \->LIST
       ROT \->STR
       IF DUP SIZE 3 < THEN " " SWAP + END
       1 \->GROB REPL
     NEXT
    NEXT
    PICT { # 42d # 59d }
    totdist UVAL 0 RND \->STR
    WHILE DUP SIZE 4 < REPEAT " " SWAP + END
    1 \->GROB REPL
    PICT { # 97d # 59d }
    tottime 2 FIX \->HMS \->STR STD
    2 ":" REPL 1 \->GROB REPL
    PICT { # 114d # 59d }
    totfuel
    IF DUP 99 > THEN 0 RND ELSE 1 FIX END
    \->STR
    IF DUP SIZE 4 < THEN " " SWAP + END
    1 \->GROB REPL
    { # 0d # 0d } PVIEW
    IFERR 0 WAIT THEN END DROP
  \>>
  STOF 2 MENU
\>>
  W&B
    \<<
      RCLF
      IF 'PLANES' VTYPE -1 SAME THEN ADDPLANE END
      DO
        DO
          1 WBMENU CHOOSE
          PLANES SWAP GET LIST\-> 1 - SWAP DROP
        UNTIL
        END
        DUP TYPE 5 SAME
        1
        \<< EVAL 0 \>>
        IFTE
      UNTIL
      END
      UNITMENU TMENU
      LIST\-> \-> num
      \<<
        0 0
        1 num FOR j
          num j - 3 + ROLL WBIN
          { '1_in' '1_cm' } 10 FS? 1 + GET CONVERT UVAL SWAP
          { '1_lb' '1_kg' } 10 FS? 1 + GET CONVERT UVAL
          DUP ROT * ROT + ROT ROT + SWAP
        NEXT
        { '1_in*lb' '1_cm*kg' } 10 FS? 1 + GET \->UNIT
        1 RND "Moment" \->TAG SWAP
        { '1_lb' '1_kg' } 10 FS? 1 + GET \->UNIT
        0 RND "Weight" \->TAG SWAP
      \>>
      2 MENU 3 ROLL
      IF DUP SIZE THEN CGGRAPH ELSE DROP END
      ROT STOF
    \>>
  WIND
    \<<
      RCLF -15 CF -16 SF
      { { "MPH" "_mph" } { "KNOT" "_knot" } "" "" "" { "KPH" "_kph" } } TMENU
      "Enter True Course:" "" INPUT OBJ\->
      "Enter Ground Speed" "" INPUT OBJ\->
      DUP UVAL ROT \->V2
      "Enter True Heading" "" INPUT OBJ\->
      "Enter True Airspeed" "" INPUT OBJ\->
      IF DUP TYPE 13 ==
      THEN
        4 ROLL
        IF DUP TYPE 13 == THEN CONVERT ELSE DROP END
        DUP UVAL ROT
      ELSE 4 ROLL SWAP ROT
      END
      \->V2
      SWAP 3 ROLLD - NEG V\->
      IF DUP 0 < THEN 360 + END
      0 RND "Winds From" \->TAG
      SWAP 0 RND ROT
      IFERR \->UNIT THEN DROP END
      "Wind Speed" \->TAG
      ROT STOF 2 MENU
    \>>
  DALT
    \<<
      RCLF
      { { "ft" "_ft" } { "m" "_m" } "" ""
        { "\^oF" "_\^oF" } { "\^oC" "_\^oC" } } TMENU
      DO
        "Enter:"
        ":Air Temp.: _\^oF\010:Press. Alt.: _ft"
        IF 10 FS? THEN 15 "C" REPL 32 "m " REPL END
        { 1 13 } 2 \->LIST INPUT
      UNTIL
        IF DUP " _" POS
        THEN 1400 .08 BEEP DROP 0
        ELSE
          OBJ\->
          IF DUP '11_km' >
          THEN
            1400 .08 BEEP "Alt. < "
            { "36000 ft" "11000 m" } 10 FS? 1 + GET + " only.\010 "  +
            1 DISP 1 WAIT DROP2 0
          ELSE 1
          END
        END
      END
      '1_ft' CONVERT UVAL .0019812 * NEG 288.15 + 5.255876 ^
      SWAP
      '1_K' CONVERT UVAL / 4.255876 INV ^ NEG 288.15 + .0019812 /
      '1_ft' \->UNIT
      IF 10 FS? THEN '1_m' CONVERT END
      0 RND "Den. Alt" \->TAG
      2 MENU SWAP STOF
    \>>
  DISTANCE
    \<<
      RCLF DEG { } TMENU
      1 2 FOR j
        DO
          { "Enter Lat. (N) and\010Long. (W) of origin"
            "Enter Lat. and Long.\010of destination" }
          j GET { ":Lat: \010:Long: " 7 } INPUT
        UNTIL
          IF DUP DUP SIZE SWAP 10 CHR POS - 7 >
          THEN 1
          ELSE DROP 1400 .08 BEEP 0
          END
        END
        OBJ\->
      NEXT
      1 4 START
        4 ROLL HMS\->
      NEXT
      \-> lat1 long1 lat2 long2
      \<<
        lat1 SIN lat2 SIN * lat1 COS lat2 COS * long1 long2 - COS * + ACOS 60 *
        DUP 60 / SIN INV long1 long2 - SIN * lat2 COS * ASIN
        IF lat2 lat1 <
        THEN 180 SWAP -
        ELSE IF DUP 0 < THEN 360 + END
        END
      \>>
      SWAP
      '1_nmi' \->UNIT
      IF 10 FS? THEN '1_km' CONVERT END
      0 RND "Distance" \->TAG
      SWAP 0 RND "True Heading" \->TAG
      ROT STOF 2 MENU
    \>>
  CWIND
    \<<
      RCLF -15 CF -16 SF DEG { } TMENU
      "DUMMY"
      DO DROP "Enter runway heading" "" INPUT
      UNTIL DUP SIZE
      END
      OBJ\->
      "DUMMY"
      DO
        DROP
        "Enter wind direction\010and speed"
        { ":WD: \010:WS: " 6 } INPUT
      UNTIL DUP DUP SIZE SWAP 10 CHR POS - 5 >
      END
      OBJ\-> DTAG UVAL
      SWAP DTAG 180 + \->V2
      SWAP DUP 90 + 1 SWAP \->V2
      3 PICK DOT 0 RND
      IF DUP 0 < THEN NEG "Right" ELSE "Left" END
      \->TAG
      3 ROLLD 1 SWAP \->V2 DOT 0 RND
      IF DUP 0 < THEN NEG "Headwind" ELSE "Tailwind" END
      \->TAG ROT STOF 2 MENU
    \>>
  PAUSE
    \<< IFERR -1 WAIT THEN END DROP \>>
  TRAP
    \<<
      DEPTH 1 - 'S.DEPTH' STO
      IFERR EVAL
      THEN
        DEPTH 1 - S.DEPTH - DROPN
        STOF
        IF ERRN # 0d \=/
        THEN
          1400 .08 BEEP
          "Error:\010" ERRM + CLLCD 1 DISP 2 WAIT
        END
        0
      ELSE 1
      END
      'S.DEPTH' PURGE
    \>>
  MAKEMENU
    \<<
      ERASE
      PICT { # 0d # 8d } { # 130d # 8d } LINE
      { # 2d # 0d }
      "Enter Title,\01021 char max" { \Ga } INPUT 2 \->GROB
      REPL
      1 10 FOR j
        PICT
        IF j 5 >
        THEN # 70d # 10d j 5 - * # 1d +
        ELSE # 2d # 10d j * # 1d +
        END
        2 \->LIST
        DO
          "Enter Item " j \->STR + "\010(10 letter max.)" +
          { \Ga } INPUT
        UNTIL
          IF DUP SIZE 11 < THEN 1 ELSE DROP 0 1400 .08 BEEP END
        END
      2 \->GROB REPL
      NEXT
      PICT RCL { # 0d # 0d } PVIEW
      IFERR 0 WAIT THEN END DROP
    \>>
  ADDPLANE
    \<<
      DO "Add or Delete? (A/D)" { "" \Ga } INPUT
      UNTIL DUP "AaDd" SWAP POS
      END
      \-> choice
      \<<
        IF 'PLANES' VTYPE -1 >
        THEN PLANES
        ELSE
          { "" } DUP DUP2 DUP2 DUP2 DUP { { } ADDPLANE "Add/Delete" }
          10 \->LIST
        END
        CASE
          "Aa" choice POS
        THEN
          DUP EVAL
          11 ROLL
          1 \-> n
          \<<
            DO
              12 n - ROLL LIST\->
              IF 1 SAME THEN DROP 1 ELSE 3 DROPN 'n' INCR DROP 0 END
              IF n 10 SAME THEN DROP2 "All slots are full" DOERR END
            UNTIL
            END
            n
            ADDGRAPH
            "Enter # of stations" "" INPUT OBJ\->
            \-> l
            \<<
              1 l FOR j
                "Enter station " j \->STR + "\010" +
                \-> sta
                \<<
                  DESCMENU TMENU
                  sta "Description" + "" INPUT
                  UNITMENU TMENU
                  sta "Default Weight" + "" INPUT
                  sta "Default Moment Arm" + "" INPUT
                \>>
                3 \->LIST
              NEXT
              l \->LIST
              PLMENU TMENU
              DO
                "Enter plane N-number/\010 type. (10 letters max)"
                "" INPUT
                DUP SIZE
                IF 10 \<= THEN 1 ELSE DROP 0 END
              UNTIL
              END
              3 \->LIST
              PUT
            \>>
            'PLANES' STO
            10 n - DROPN
          \>>
        END
        "Dd" choice POS
        THEN
          1
          IF 'WBMENU' VTYPE -1 SAME
          THEN # 131d # 64d BLANK
          ELSE WBMENU UPGROB
          END
          { # 2d # 0d } "Delete which aircraft" 2 \->GROB REPL
          { # 70d # 51d } "No change " 2 \->GROB REPL
          IF CHOOSE DUP 10 \=/
          THEN
            SWAP EVAL
            11 ROLL
            NEG 11 + ROLL
            DROP { "" } SWAP
            10 \->LIST
          ELSE DROP
          END
          'PLANES' STO
        END
        END
        TEXT CLLCD "      Updating..." 3 DISP
        PLANES EVAL
        # 131d # 64d BLANK
        70 2 FOR x
          51 11 FOR y
            SWAP
            LIST\-> \-> m
              \<< m ROLLD m 1 - DROPN \>>
            2 \->GROB
            x R\->B y R\->B 2 \->LIST
            SWAP GOR
          -10 STEP
        -68 STEP
        { # 2d # 0d } "Select Aircraft" 2 \->GROB GOR
        PICT SWAP { # 0d # 0d } SWAP REPL
        { # 0d # 8d } { # 130d # 8d } LINE
        PICT RCL PGROB 'WBMENU' STO
      \>>
    \>>
  STRIP
    \<<
      1 \-> delchr stop
      \<<
        WHILE DUP delchr POS 0 \=/
        REPEAT
          DUP delchr POS 1 - 'stop' STO
          DUP 1 stop SUB
          SWAP
          DUP SIZE stop 2 + SWAP SUB +
        END
      \>>
    \>>
  PAD
    \<< WHILE DUP SIZE 21 < REPEAT " " + " " SWAP + END \>>
  CHOOSE
    \<<
      PICT { # 0d # 0d } ROT
      IF DUP TYPE 10 == THEN UPGROB END
      REPL
      { #0d #0d } PVIEW
      R\->B
      DUP # 6d <
      # 1d
      # 69d
      IFTE
      SWAP 10 *
      IF DUP # 50d > THEN # 50d - END
      \-> x y
      \<<
        DO
          PICT
          x y 2 \->LIST
          DUP 3 ROLLD CURSOR GXOR
          DO
            0 WAIT IP
            { 34 36 25 35 51 } SWAP POS DUP
            IF THEN DUP END
          UNTIL
          END
          {
          \<< x # 68d XOR 'x' STO 0 \>>
          \<< x # 68d XOR 'x' STO 0 \>>
          \<<
            IF y # 10d == THEN # 50d 'y' STO ELSE 'y' # 10d STO- END 0
          \>>
          \<<
            IF y # 50d == THEN # 10d 'y' STO ELSE 'y' # 10d STO+ END 0
          \>>
          1 }
          SWAP GET EVAL SWAP
          PICT SWAP CURSOR GXOR
        UNTIL
        END
        y B\->R 10 / x B\->R 69 / IP 5 * +
      \>>
    \>>
  ADDGRAPH
    \<<
      "Enter # of points in\010c.g. graph (0 for no\010graph):"
      "" INPUT OBJ\->
      \-> num
      \<<
        IF num 0 \<=
        THEN { }
        ELSE
        0 1000 0 1000000
        \-> mmax mmin wmax wmin
        \<<
          DO
            ERASE
            1 num FOR j
              "Enter point " j \->STR + " in form\010{mom/1000 weight}" +
              { "{ }" { 1 2 } } INPUT OBJ\->
              DUP EVAL DUP DUP
              IF wmax > THEN DUP 'wmax' STO END
              IF wmin < THEN DUP 'wmin' STO END
              DROP DUP DUP
              IF mmax > THEN DUP 'mmax' STO END
              IF mmin < THEN DUP 'mmin' STO END
              DROP
            NEXT
            { # 0d # 0d } PVIEW
            1 num 1 - START
              SWAP DUP 3 ROLL
              1 2 START
                SWAP EVAL wmax wmin 63 SCL # 63d SWAP -
                SWAP mmax mmin 130 SCL SWAP 2 \->LIST
              NEXT
              LINE
            NEXT
            DROP
          UNTIL
            0 WAIT DROP
            { "YES" "" "" "" "" "NO" } TMENU
            "Is the graph correct?" "" INPUT
            "YES" ==
            1
            \<<
               "Enter # of points"
               "" INPUT OBJ\-> 'num'
               STO 0
            \>>
            IFTE
          END
          PICT RCL PGROB mmax mmin wmax wmin 5 \->LIST
          \>>
        END
      \>>
    \>>
  SCL
    \<<
      \-> valmax valmin factor
      \<< valmin - valmax valmin - / factor * 0 RND R\->B \>>
    \>>
  WBIN
    \<<
      EVAL
      \-> station defwgt defarm
      \<<
        DO
          "Enter " station + "\010weight and moment arm:" +
          ":Weight: " defwgt + "\010:Mom. arm: " + defarm +
          { 1 10 } 2 \->LIST INPUT
        UNTIL
          IF DUP " _" POS THEN 1400 .08 BEEP DROP 0 ELSE 1 END
        END
        OBJ\->
      \>>
    \>>
  CGGRAPH
    \<<
     IFERR
      EVAL
      \-> mmax mmin wmax wmin
      \<<
        UPGROB PICT STO
        DUP2
        { '1000_in*lb' '1000_cm*kg' } 10 FS? 1 + GET
        / mmax mmin 130 SCL SWAP UVAL
        IF DUP wmax \<=
        THEN wmax wmin 63 SCL
        ELSE DROP2 "Aircraft is overweight" DOERR
        END
        # 63d SWAP - 2 \->LIST
        # 1d 0 360 ARC { # 0d # 0d } PVIEW
      \>>
      IFERR 0 WAIT THEN END DROP
      CLLCD
     THEN
      CLLCD 1400 .08 BEEP ERRM 1 DISP 2 WAIT
     END
    \>>
  PGROB
"D9D20ECE8176040CCD20EB1008FB976014713506174147DAF4C2818F2E8FD7B5
081AF1813581AF0A80824E4A20141818F2913507818F24134142CAD816415271
517179818F2E13481AF0813713581AF0917115201510D31701601361348B9606
6601560155090661B67AEB808A73DA6F654031409EBB3136EB134137EB13581A
F11E2808A7A9818FA27BA013313181AF01627F137135EB81AF11E2818FA28AA8
1CE7A70137135EBCE81AF0981AF1913596B01AEB8089714D1721361348B56066
1F81AF1A81AF0806133130EA34A10008A6501608F176618F2D760071458DF192
081AF1113314D13101B21300239"
  UPGROB
"D9D20ECE81D5040CCD204F0008FB97601471350617414334510008A6018F2D76
08D7AC8117414381AF0117414381AF008F3B51113681AF0813507818F2413414
2CAD816E14A1611361348BD46808770431F09EAF11567155716F17F81868F31F
09E65E15601550160170A6C5EE6DAF8084715601550170A6C55F160609F81AF1
08D1FF11B2130D903"
  PLANES
"47A2047A2047A20E4A20FE3000400038000390008A8F007490006A8000339010
81980008490004A80004490003A8000339000CA80008490002A800063901081A
80001390006A8000C490001A8000239000CB80001390003A8000C390008B8000
2390006A8010812901081A80004390004B80002390003A80108129000CB80004
390002B800032901081A80008390006B80004390001B8000329000CB80008390
003B8000629000848F00768000129000648000258000C2907081000081580002
29000648000468000129000148000258000C2900085800015800022900044800
0C58010812900024800025800043900014800015800022900084800085801081
2900044800045800043900024800035800033905010000858000839000848000
4580004390004480002580003390602000081480008490501000045800063900
0848000258000139000448000148000C4905020000C580002490501000025800
0139000C48000148000C49050200008580002490501000044801081390008480
0034800044905040000858000249050200004480108149050100002480004490
6080000814800034905040000448000859050200002480004590501000014800
034905080000C480008590504000024800065905020000148000159040100084
8000C5905080000448000259050400003480001590402000848000C69098F003
6903392020000000000090103392010000000000052503392030000000000003
20339203000000000000510B213047A2047A20C2A20F000054D6074797C2A203
100013336363F5C626C2A20310003393E243F596E6B213047A20C2A20B0000F4
96C6C2A20F00001353F5C626C2A2051000D21333E233F596E6B213047A20C2A2
012000645756C602155716E647964797F2C2A20D0000F57416C6C2A203100043
73E283F596E6B213047A20C2A20F00000596C6F647C2A20B0000F5C626C2A20F
00003373F596E6B213047A20C2A20320006427F6E647020516373756E6765627
C2A20B0000F5C626C2A20F00003373F596E6B213047A20C2A201200025561627
020516373756E6765627C2A20B0000F5C626C2A20F00007333F596E6B213047A
20C2A20120002416767616765602162756160213C2A20B0000F5C626C2A20F00
009353F596E6B213047A20C2A20120002416767616765602162756160223C2A2
0B0000F5C626C2A2011000132333F596E6B2130B2130C2A209100034563737E6
1602137323B213047A20C2A2050000B213047A20C2A2050000B213047A20C2A2
050000B213047A20C2A2050000B213047A20C2A2050000B213047A20C2A20500
00B213047A20C2A2050000B213047A20C2A2050000B213047A2084E208014444
405C414E454C2A2091000144646F24456C6564756B2130B21308244"
  FPLAN.GROB
"E4A20EA7000400038000E0100400010040004780D74000010004011E4C9198A4
39D5000EC00047547D5D54011148409DA455840001200042D6154544011D4840
9AE45984000D400042557D5D540119484098A451549400098000425415454401
7E488198A43D84000E6000425475CDD50100400010040004780A040000100040
F9F017010040001004000478091400001000401C040001004000478091400001
0004018040001004000478091400001000401804000100400047809140000100
04018040001004000478091400001000401C1400010040004780914000010004
010040001004000478091400001000401C140001004000478091400001000401
0140001004000478091400001000401C14000100400047809140000100040140
40001004000478091400001000401C1400010040004780914000010004010040
001004000478091400001000401C140001004000478091400001000401014000
1004000478091400001000401C14000100400047809140000100040101400010
04000478091400001000401C1400010040004780914000010004010040001004
0004780914000010004014140001004000478091400001000401414000100400
0478091400001000401C14000100400047809140000100040101400010040004
7809140000100040101400010040004780914000010004010040001004000478
091400001000401C140001004000478091400001000401404000100400047809
1400001000401C14000100400047809140000100040101400010040004780914
00001000401C1400010040004780914000010004010040001004000478091400
0010004018140001004000478091400001000401404000100400047809140000
1000401C14000100400047809140000100040141400010040004780914000010
00401C1400010040004780914000010004010040001004000478091400001000
401C140001004000478091400001000401014000100400047809140000100040
1804000100400047809140000100040140400010040004780914000010004014
0400010040004780914000010004010040001004000478091400001000401C14
00010040004780914000010004014140001004000478091400001000401C1400
010040004780914000010004014140001004000478091400001000401C140001
00400047809140000100040100400010040004780A040000100040F9F5070BAA
6580401000C78A9160000100040555577721610004885810000100040BAA6252
5111000C78A9160000100040555525271210004885810000100040BAA6252514
1000C78A91600001000405555272573100048859000001000405332"
  HELP.1
"E4A206950004000380001A0A11D5EAE481900542C40C42CA24EE680A11541A4A
8AA084454942A22A2A42680A15D5DE4CA9B08456D802E22A2E4E680A1B549A42
9AA08C694942A22A2A42680A11D5EA4CA9A30546D40CAECEEA4EBA0211D5EAE0
2960642429D1E80111541A405BA0AA2A654F80215D5DE407FA06E2EE5C1E8011
B549A405DA0AA2AA54F80211D5EA4059606AEA29D5FC0C171EAE0E242108EE24
250C42CA24EE480C1111A40A2A61042A2A6942A22A2A42480C171DE40E2EE104
EE2EE902E22A2E4E480C1119A4022AA104222AA942A22A2A42480C117EA402EA
210822EA250CAECEEA4E9A09119830AE46A4E00E6EA2D08DDDD780A1B5500A2A
AA51001AAA651445441680A15D530EEEAA7D00D6AAE518CDD51680A115520A2A
AA69409AAAA51054449680A1159B0AEA6A4E20EAEE2D0C4CDD48A0B175470790
6EAEE042D0C5D50C4D42580B12D6101B0AAA420A65144540455D2580B1255707
F06AA4E0EE51C5D50C4DC3580B1254101D0AAA420AA514454045553580B12547
0790AEE4E0A2D04CDD1CC55A6C0B11596042EEE0415962075A12A2D81580A115
BA0A2A240215BA421DA22A655680A155FA0E2AE40255FA407DB2AAE59680B1B5
DA0A2A2402B5DA4215B26BA511580A115960AEE240415962015A12A2DCBA0402
1777C904051512C904071572C904051512C90405771ADD0C1379CEA042E04321
718B2D0CC52BEA480C151B24A0A2402551229865145CA84A480C157F4440E240
2571228BE514DD3944480C151D8440A24025512298A514543A44480C13796440
AE40435721882D0CC5A9449A091217D5DC1CDC54073766537021778091512945
50445D6055111551051278091712945D1CD45507372253707127809151294550
445540151445510512780915729CDC144D54015733757057A9A0F02960EE2ABB
19BA93190E05BA0426BA8A29AA290F07FA04EAABB939A93190E05DA0422A88A2
9AA290F059604E2A8BA29BAB0B01909"
  HELP.2
"E4A20DF50004000380001A0C139D15D4270A9CE429D50C42CA24EE480C155805
5DA009A24A654842A22A2A42480C15988C5DB609A44EE5C902E22A2E4E480C15
194455B409A84AA54842A22A2A42480C13D844D4270A964A29D50CAECEEA4E8A
0D789CE429D184A18A39929389BB8EE2100008A24A65404DA28A8AA6508A0982
26100008A44EE5C1CDB28BBBAE538939AEEE100008A84AA54045B28A8AAA528A
0729D22A100008964A29D145A18ABA929389398EE215A0218B8E024E82E29383
96CF801198A02A482A6508AAA2F80119AA02E442AE538BB64F80119DA02A422A
A5288AA8F802198E0EA42EE29388AA62FC0C15015960C2A309545A908948558C
D1480B15015BA026B28444DA29445445494580C12755FA02AA38445DB214C544
5C9C1480B150B5DA022A084C65B29445445494580C15015960C2A009545A9085
D9DD59C18A0618A3998A4302960C6ECC2A2DA80718A8AA8A5505BA02AA222A65
1980718BBBAAA7507FA026A44AAE51980718A8AADA6505DA02AA886BA5198071
8ABA98A4305960CAE662A2D4BC0D757170AAB8B0C5560737E64220942A330005
11509A8829845105551AA630BA6B80000771709BB8318C520735D6EA20FEAA31
000511109A8809845401559AA22820DA2A0200057710AABB8084530157EAA2A0
9A2AB16A0B1821C9CC5ABA3BC046E0E6ECD8446580B18614555C29A8820AA20A
AA245D61580B18E1CDDCD39B3940E6E0E6AADC552580B18A14455439A0A80AA2
02AA255544580B1821445D529AB960AAE02AEC555438A0D73988B18920BB993B
BB4352701D5A2000088A88828A288AAA88AA55DA00B5CA2000088B88B281188A
9939BA75DB605DDB2000088A888282188AAA0A8A655B4040154B2480C1BABBB1
8110BBAAB98B4352701D5A36A0D7BABCE00BB38B017032077301DDD46000088A
A2208801888A002501550B58451000088BA2E009318B8B6025075305D9C41000
088AA2200A01888A40250155014058451480C1BABCE2893188B27072017501D9
4565A0608BABBA3A90608A29A21A90608A29B21A90608A29821A90608B39835C
D05CEE"
  HELP.3
"E4A20032000400038000DE0019A4EAB40737E64223F80018AAA4AA505551AA6B
090118BAE4AA70735D6EA21F8011829A4AA601559AA222F8011829A4AB40157E
AA2A1DF0106AF9010AAF901064F9010A4F901064FF0D08B9C042DCD8D52390D0
88A20A655454D2390D08B920EE5DD84D3390D088A20AA5541553390D08BAC0A2
DC5DC52FF0FF0FF0E100003B9BB40671DDC9957906EAEA476580B1888A885015
B5554445B0AAA4A511680A1989BB70155DDC9845F06AA4A772680A1A8A886015
15450155D0AAA4A614580B181BABB4067154DDC4790AEE4A4738F0106AF9010A
AF901064F9010A4F901064FF0C00E6A403359ECE590B02AA20555B422590B0E6
A10332F44E590B02AA20552D482590B0EAA40352946EFF0FF0B90616B"
  STMENU
"E4A202940004000380000183081000200E00201090E044001000200110229031
40E01E877001D3781EC3D803183111150200154201154E80214F11F502001542
01154D803144101140A001D3A01154D803183E83E87400E40483E44990004490
F9F0074C0C144001040280F0060044044400010E480D74400004024111040044
04400001011000044E81EC3741193400820446C3E101C2F0045111154280F044
0001F5544411014511045F111542451974008204544B44110145110C6101E54A
42154400440C6444110155F0044E83054485F87E0044044E44E10E44168000E8
900015C0B0C76001800C36590B0404001800444590E040483FC1044483F290F0
C34441900C340411190F04044419004048711190F04048719204044411190F04
0E04111040E871149010830E0E044400010E810012290E044000010111082229
0E0446C3E10111E807290E045444110F111D12290E0454441101111902290E0C
6444110111190A290E044E44E10193E8048F0E0C1000080000E8126803011067
80E0420000800001112680301104780E044EC3ED11101117680501934C3580E0
44154180110F11268050F54444580E044F54E801101112680501D7444580E042
144092E10111A680501504C3580E0C1E44F01010193468040193E4E8000E0900
04AC0A0C1400200114A8040E0048680A042000204114A804011008680D044687
702197F83780501546C1580D044440201F541547804015448680D04448328015
41547804055448680D042404A4015419778050944482580D0C1EC34001971147
8050697E011901083FF0DB04D19"
  WBMENU
"E4A20302000400038000D083081000200E015801048B80C04400100020011680
10A8B806140E01E87700191D97D932C1A805183111150200F1134030478C8041
4F11F5020011114018728B806144101140A00111140144282A806183E83E8740
0193187187201CA0F9F0074C01083880304C7E29010448804060411190F040E8
7ED3E0040201190E040150144010401C290E040F93E44E104802290E04410405
41104801290F083EC3F44E10E80F1FF0FF0FF0FF0FF0FF0FF0FF0FF0480C0830
140C108108490C04401405200108490E044E97844E01EC1E290F0C7154444111
19011190F044154244F11F90F1190E0441541421011821290E044E970C1E83E0
1EFF0DC071C0"
  CURSOR
"E1B20F900090000D3000FFFFFFFFFFFFFFF1FFFFFFFFFFFFFFF1FFFFFFFFFFFF
FFF1FFFFFFFFFFFFFFF1FFFFFFFFFFFFFFF1FFFFFFFFFFFFFFF1FFFFFFFFFFFF
FFF1FFFFFFFFFFFFFFF1FFFFFFFFFFFFFFF11664"
  UNITMENU
{ { "lb" "_lb" } { "kg" "_kg" } { "in" "_in" } { "cm" "_cm" } { "Gal"
"_Gal" } { "L" "_L" } }
  PLMENU
{ "Cessna " "Mooney " "PA-" }
  DESCMENU
{ "Empty" "Oil" "Fuel Quantity/" "Pilot" "Front " "Rear " "Passenger"
"Baggage" }
  Gal
'6_lb'
  L
'1.584_lb'
  CST
{ '1_Gal' '1_lb' "" "" '1_kg' '1_L' }
END
-- 
Eric Anderson                                     eanderso@caltech.bitnet