[comp.sys.hp] HP-28S Utilities

nungeste@hpspkla.HP.COM (Dick L. Nungester) (08/30/88)

The following programs for the HP-28S all have a brief description followed
by a usage line.  The description always includes the names of any other
programs or variables required for execution.  The usage line shows
required stack contents before the command, the command, and the stack
contents after the command.  The programs are ordered such that subprograms
are always listed before the programs that need them.  (About 500 lines
follow.)

GENERAL UTILITIES:
==================

TODIR                    Move to a new directory.

                         { <directory path> } TODIR >>>
<< DUP SIZE 1 DUP ROT
  START GETI EVAL
  NEXT DROP2
>>



REN                      Rename a variable in the current directory.
                         Doesn't work on renaming subdirectories.

                         '<old name>' '<new name>' REN >>>
<< -> old new
  << old RCL new STO
old PURGE
  >>
>>



CP                       Copy variables from one directory to another.
                         Can be executed from any directory, and
                         maintains the current directory.  Uses TODIR.

                         { <from path> } { <var list> } { <to path> } CP >>>
<< PATH -> f v t c
  << f TODIR 1 v SIZE
    FOR i v i GET
DUP RCL SWAP
    NEXT t TODIR 1 v
SIZE
    START STO
    NEXT c TODIR
  >>
>>



MV                       Move variables from one directory to another.
                         Can be executed from any directory, and
                         maintains the current directory.  Uses CP and TODIR.

                         { <from path> } { <var list> } { <to path> } MV >>>
<< PATH -> f v t c
  << f v t CP f TODIR
v PURGE c TODIR
  >>
>>



RST                      Reset calculator to a known state.  Uses TODIR.

                         RST >>>

<< CLEAR 20 MENU {       Clear the stack; show cursor menu
HOME RLN WORK }
TODIR                    Go to default directory ({ HOME RLN WORK } here)
# 288252350278139904d    Set all flags to factory preset except:
STOF 52 SF RAD           fast printing and radians mode.
>>



FDIF                     List all flags different than factory preset.

                         FDIF >>> { <flags not at preset values> }
<< { } RCLF 64 STWS
DUP
# 288252350278139904d
XOR -> f d
  << 1 64
    FOR i
      IF d DUP SR
'd' STO # 1d AND B->R
      THEN i +
      END
    NEXT f STOF
  >>
>>



UP1                      Move up 1 directory.  If at HOME, a no-op.

                         UP1 >>>
<<
  IF PATH DUP SIZE 1
- DUP
  THEN GET EVAL
  ELSE 2 DROPN
  END
>>



NTS                      List of names to list of strings.  (For putting
                         a list of variables in a form suitable for
                         sorting using QSORT.)

                         { <list of var names> } NTS >>> { <list of strings> }
<<
  IF DUP SIZE 0 >
  THEN DUP SIZE 1
SWAP
    FOR i DUP i GET
->STR i SWAP PUT
    NEXT
  END
>>



STN                      Reverse the action of NTS.

                         { <list of name-strings> } STN >>> { <list of names> }
<<
  IF DUP SIZE 0 >
  THEN DUP SIZE 1
SWAP
    FOR i DUP i GET
STR-> i SWAP PUT
    NEXT
  END
>>



PAD                      Pad string with spaces to 23 characters.  (From
                         programming examples in the Owners Manual.)

                         "<string>" PAD >>> "  ...  <string>"
<< ->STR
  WHILE DUP SIZE 23
<
  REPEAT " " SWAP +
  END
>>



DIR                      Separately list all variables and subdirectories
                         in the current directory.

                         DIR >>> { <sub-directories> } { <variables> }
<< VARS { } { } ->
vars dirs others
  <<
    IF vars SIZE 1 >=
    THEN 1 vars SIZE
      FOR j vars j
GET DUP
        IFERR RCL
DROP others +
'others' STO
        THEN DROP
dirs + 'dirs' STO
        END
      NEXT
    END dirs others
  >>
>>



DIRWALK                  Add the current directory path name and that of
                         all directories below to the list present in
                         stack level 1.  This is a recursive procedure,
                         meant to be used with DIRLIST.  In usage,
                         <dirs> can be empty if desired.  Uses DIR, DIRWALK,
                         and UP1.

                         { <dirs> } DIRWALK >>> { <dirs>+current & sub-dirs> }
<< PATH 1 ->LIST + DIR
DROP DUP SIZE 0
  IF ==
  THEN DROP
  ELSE DUP SIZE ->
subs size
    << 1 size
      FOR i subs i
GET EVAL DIRWALK UP1
      NEXT
    >>
  END
>>



DIRLIST                  Return a list of all directory paths.
                         Maintains the current directory.  Uses DIRWALK and
                         TODIR.

                         DIRLIST >>> { <list of all directories> }
<< PATH -> odir
  << HOME { } DIRWALK
odir TODIR
  >>
>>



DIRCOMM                  Execute any program in each directory.
                         <program> must leave the stack unchanged.
                         Maintains the current directory.  Uses DIRLIST and
                         TODIR.

                         << <program> >> DIRCOMM >>>
<< PATH -> prog odir
  << DIRLIST LIST-> 1
SWAP
    START TODIR prog
EVAL
    NEXT odir TODIR
  >>
>>



MSUM                     Memory summary.  After execution, the display
                         shows:    "xx directories
                                    xx variables
                                 xxxxx bytes free".  Uses DIRLIST, TODIR,
                         DIR, and PAD.

                         MSUM >>>
<< PATH DIRLIST 0 0 ->
o p v d
  << p SIZE DUP 'd'
STO 1 SWAP
    FOR i p i GET
TODIR DIR SIZE v +
'v' STO DROP
    NEXT CLLCD d
->STR " directories"
+ PAD 1 DISP v ->STR
" variables  " + PAD
2 DISP MEM ->STR
" bytes free " + PAD
3 DISP o TODIR
  >>
>>



PRDIR                    Print all variables (not subdirectories) in the
                         current directory, with a directory path header.
                         Uses DIR, NTS, and STN.

                         PRDIR >>>
<< PATH PR1 DROP CR
DIR SWAP DROP NTS
QSORT STN PRVAR CR
CR
>>



QSTR                     Recursive part of QuickSort (see below).  This
                         is translated from the PASCAL version given in
                         "Algorithms + Data Structures = Programs" by Niklaus
                         Wirth, p. 79.  QuickSort is a common algorithm
                         to rapidly sort a long list of items.  Uses QSTR.

                         {<list>}_or_[<vector>] a b QSTR >>>
                         {<list>}_or_[<vector>], sorted from element a
                         through element b.
<< DUP2 0 0 -> l r i j
x w
  << l r + 2 / IP
GETI SWAP DROP 'x'
STO
    DO
      WHILE i GETI
SWAP DROP x <
      REPEAT i 1 +
'i' STO
      END
      WHILE j GETI
SWAP DROP x >
      REPEAT j 1 -
'j' STO
      END
      IF i j <=
      THEN i GETI
SWAP DROP 'w' STO j
GETI SWAP DROP i
SWAP PUT j w PUT i 1
+ 'i' STO j 1 - 'j'
STO
      END
    UNTIL i j >
    END
    IF l j <
    THEN l j QSTR
    END
    IF i r <
    THEN i r QSTR
    END
  >>
>>



QSORT                    QuickSort algorithm for lists or vectors of
                         objects that can be ordered with "<" and ">", such
                         as real numbers or strings.  Works for any size
                         list or vector (including 0 and 1).  Uses QSTR.

                         { <list> }_or_[ <vector> ] QSORT >>> { <sorted
                         list> }_or_[ <sorted vector> ]
<<
  IF DUP SIZE
    IF DUP TYPE 5 ==
    THEN 1 GET
    END DUP 1 >
  THEN 1 SWAP QSTR
  ELSE DROP
  END
>>



MKPAR                    Make variable 'PARNT' in the current directory,
                         located first in the USER menu.  PARNT moves
                         up one directory using 'UP1' (see SDIR).  Uses
                         PARNT and UP1.

                         MKPAR >>>
<< 'PARNT' PURGE
'UP1' 'PARNT' STO
>>



SDIR                     Sort the current directory in the order:
                         1) PARNT (for easily moving up 1 directory),
                         2) All subdirectories, alphabetically,
                         3) All variables, alphabetically.
                         Uses DIR, NTS, QSORT, STN, and MKPAR.

                         SDIR >>>
<< DIR NTS QSORT STN
SWAP NTS QSORT STN
SWAP +
  IF DUP SIZE 1 >=
  THEN ORDER
  ELSE DROP
  END MKPAR
>>



SDIRS                    Sort all directories using SDIR.  This takes about
                         3.5 minutes to sort 8 directories with 79
                         variables.  Maintains the current directory.  Uses
                         SDIR and DIRCOMM.

                         SDIRS >>>
<< 'SDIR' DIRCOMM
>>




FUN WITH THE DISPLAY:
=====================

CHRS                     Make a string of characters from CHR(a) thru CHR(b).

                         a b CHRS >>> "xxxxx...xxxxx"
<< "" 3 ROLLD
  FOR i i CHR +
  NEXT
>>



DCHRS                    Fill the display with all displayable characters
                         except "B" through "Z" (so they all fit in display
                         window).  Uses CHRS.

                         DCHRS >>>
<< CLLCD 33 55 CHRS 1
DISP 56 65 CHRS 148
CHR + 90 101 CHRS +
2 DISP 102 124 CHRS
3 DISP 125 147 CHRS
4 DISP
>>



SINS                     Generate picture-string SINP (a sin wave, and the
                         1, 3, 5, 7, 9, and 11 degree Taylor approximations
                         to it) for use in ANN below.

                         SINS >>>
<< CLLCD 'SIN(X)'
STEQ { (0,-2)
(6.2832,2) X 1 (0,0)
} 'PPAR' STO DRAW 1
11
  FOR i 'SIN(X)' 'X'
i TAYLR STEQ DRAW 2
  STEP LCD-> 'SINP'
STO
>>



ANN                      Annotate SINP as an example of mixed text and
                         graphics on the LCD display.  Uses SINP,
                         as generated by SINS above.

                         ANN >>>
<< CLLCD
"        1      5    9
"
1 DISP
" sin(x)  3   7     11
"
4 DISP LCD-> SINP OR
->LCD
>>



FUN WITH THE BEEPER:
====================

NOISE                    Generate n beeps of random frequency from 200
                         to 2000 Hz, with duration 0.05 seconds.

                         n NOISE >>>
<< 1 SWAP
  START RAND 1800 *
200 + .05 BEEP
  NEXT
>>



SLEW                     Slew the beeper frequency in a geometric series
                         from 40 Hz through 4000 Hz using 50 notes with
                         total duration of about 5 seconds.

                         SLEW >>>
<< 40 4000 50 5 -> f1
f2 n t
  << f1 f2 f1 / n INV
^ t n / -> f s d
    << 1 n
      START f d BEEP
f s * 'f' STO
      NEXT
    >>
  >>
>>



MNDT                     Create matrix NDAT, holding 10 octaves of piano
                         note frequencies.  This matrix is used by the
                         music programs that follow.

                         MNDT >>>
<< 440 2 57 12 / ^ /
2 12 INV ^ -> b s
  << b 2 120
    START DUP s *
    NEXT
  >> { 10 12 } ->ARRY
'NDAT' STO
>>



MUSIC                    Interpret a list of notes and play a song.
                         See CSCL or SNTS for examples of use.  A single
                         note is 3 characters coded:
                         <note> = CdDeEFgGaAbB (lower case are flats),
                         <octave> = 0 through 9,
                         <number of beats> = 1, 2, ...  Uses NTS and NDAT
                         (as created by MNDT).

                         { <list of notes> } MUSIC >>>
<< NTS DUP SIZE 1
SWAP
  FOR i i GETI SWAP
DROP -> n
    << n 2 2 SUB {
"C" "d" "D" "e" "E"
"F" "g" "G" "a" "A"
"b" "B" } SWAP POS n
3 3 SUB NUM 47 - n 4
4 SUB NUM 48 - .2 ->
c r d b
      << 'NDAT(r,c)'
EVAL d b * BEEP
      >>
    >>
  NEXT
>>



CSCL                     Play a C scale.  Uses MUSIC.

                         CSCL >>>
<< { C52 D52 E52 F52
G52 A52 B52 C65 }
MUSIC DROP
>>



SNTS                     Play "Oh, when the Saints go marchin' in".  Uses
                         MUSIC.

                         SNTS >>>
<< { C51 E51 F51 G55
C51 E51 F51 G55 C51
E51 F51 G52 E52 C52
E52 D55 E51 E51 D51
C53 C51 E52 G51 G51
G51 F54 E51 F51 G52
E52 C52 D52 C56 }
MUSIC DROP
>>