hp41programs

Short Routines

Miscellaneous Short Routines for the HP-41


Overview
 

 1°)  Clearing a Block of Registers
 2°)  Copying a List
 3°)  Block Exchange
 4°)  A M-Code Routine ( HP-41CX )
 5°)  Circular Permutation of 3 Blocks
 6°)  Reversion of a List
 7°)  Deleting an Element from a List
 8°)  Intersection of 2 Sets
 9°)  Union of 2 Sets
 

-The following programs perform basic operations on blocks of registers.
 

1°) Clearing a Block of Registers
 

-This routine replaces CLRGX if you don't have an HP-41CX
 

Data Registers:   Only those of the array
Flags: /
Subroutines: /
 
 

 01  LBL "LCL"
 02  SIGN
 03  CLX
 04  LBL 01
 05  STO IND L
 06  ISG L
 07  GTO 01
 08  END

 
   ( 19 bytes )
 
 

      STACK        INPUTS      OUTPUTS
           X       bbb.eee(ii)             /

 
Example:   To clear registers  R10  R12  R14  R16 ,    10.01602   XEQ "LCL"
 

-If  ii = 1 ,  ii can be omitted
 

2°) Copying a List
 

-This program moves a list of elements ( control number bbb.eee ) to another address BBB.
-The blocks of registers cannot overlap, unless  BBB <= bbb
 

Data Registers:   Only those of the 2 Lists
Flags: /
Subroutines: /
 
 

 01  LBL "LCO"
 02  ENTER^
 03  SIGN
 04  ST- L
 05  LBL 01
 06  ISG L
 07  CLX
 08  CLX
 09  RCL IND Z
 10  STO IND L
 11  ISG Z
 12  GTO 01
 13  X<> L
 14   E3
 15  /
 16  +
 17  END

 
   ( 33 bytes )
 
 

      STACK        INPUTS      OUTPUTS
           Y      bbb.eee(ii)             /
           X          BBB       BBB.EEE

 
Example:     {  2  5  7  1  6  }  =  {  R10  R11  R12  R13  R14 }.  Move these numbers into registers R07  R08 ..... R11

   10.014   ENTER^
       7        XEQ "LCO"  >>>   7.011

-This program may improved so that it also works if  bbb < BBB <= eee.
  cf for instance references [1] & [2]
-The control number BBB.EEE is correct only if ii = 0.
 

3°) Block Exchange
 

Data Registers:   Only those of the 2 Lists
Flags: /
Subroutines: /
 
 

 01  LBL "LSWAP"
 02  SIGN
 03  LBL 01
 04  CLX
 05  RCL IND L
 06  X<> IND Y
 07  STO IND L
 08  ISG Y
 09  CLX
 10  ISG L
 11  GTO 01
 12  END

 
   ( 27 bytes )
 
 

      STACK        INPUTS      OUTPUTS
           T             T             T
           Z             Z             Z
           Y     bbb.eee(ii)1             /
           X     bbb.eee(ii)2             /

-Registers Z and T are saved.

Example:

-You want to swap the contents of registers  R01  R02  R03  R04
                      with  the contents of registers  R14  R16  R18  R20

    1.004     ENTER^
 14.02002  XEQ "LSWAP"  >>>>  /
 

-In reference 2, Philippe Descamps and Jean-Jacques Dhenin give a trick to stop the routine when the smallest block has been exchanged:
-Replace line 09 by   FS? 30   RTN
 

4°)  An M-Code Routine ( HP-41CX )
 

-"LCO" uses an entry point in block 3 ( address 3EC4h ) that performs REGMOVE if CPU-flag 4 is clear and REGSWAP if CPU-flag 4 is set.
-The HP-41 checks that the required registers do exist and displays "NON EXISTENT" otherwise.
-Unlike the 2 routines listed above, the registers must be contiguous.
 

08F   "O"
003   "C"
00C  "L"
0B8   READ 2(Y)
10E   A=C ALL
0F8   READ 3(X)
355   ?NCXQ        checks for alpha data,
050   14D5            xeq  A<>C  and SETDEC
088   SETF 5             C
0ED  ?NCXQ            =
064   193B              int(C)
070   N=C ALL
0B8   READ 2(Y)
084   CLRF 5             C
0ED  ?NCXQ            =
064   193B              frc(C)
226   C=C+1 S&X
226   C=C+1 S&X
226   C=C+1 S&X
10E   A=C ALL
0B0  C=N ALL
2BE  C=-C-1 MS      C=-C
01D  ?CXQ               C=
061   1807                A+C
0A8  WRIT 2(Y)
10E   A=C ALL
0F8   READ 3(X)
128   WRIT 4(L)        do not key in this word if you don't want to save +/- BBB in L-register
044   CLRF 4
2FE   ?C#0 MS
013   JNC +02
048   SETF 4              CPU-flag 4 is set if  BBB < 0
05E   C=0 MS            C= | C |
0E8   WRIT 3(X)
01D  ?NCXQ               C=
060   1807                  A+C
266   C=C-1 S&X
266   C=C-1 S&X
266   C=C-1 S&X
10E   A=C ALL
0F8   READ 3(X)
01D  ?NCXQ               C=
060   1807                  A+C
10E   A=C ALL
0B8   READ 2(Y)
0AE  A<>C ALL
0A8  WRIT 2(Y)
04E   C=0 ALL             C
35C  PT=12                  =
050   LD@PT- 1           1
01D  ?NCXQ               C=
060   1807                  A+C
266   C=C-1 S&X
266   C=C-1 S&X
266   C=C-1 S&X
10E   A=C ALL
0F8   READ 3(X)
01D  ?NCXQ               C=
060   1807                  A+C
266   C=C-1 S&X
266   C=C-1 S&X
266   C=C-1 S&X
10E   A=C ALL
0B0  C=N ALL
01D  ?NCXQ               C=
060   1807                  A+C
0E8   WRIT 3(X)
311   ?NCXQ             This address is correct for an HP-41 CX but not for an HP-41C with an X-Functions module.
0F8   3EC4                 It can surely be replaced by another one if you have an X-Functions module but I do not know it.
3A5  ?NCXQ             ?ncxq
050   14E9                  RDN
078   READ 1(Z)
028   WRIT 0(T)
3C1  ?NCGO              the 4 subroutine-levels have been used, so we cannot use  3E0  RTN  to end the routine properly.
002   00F0                  It must be replaced by the 2 words  3C1  002
 
 

      STACK        INPUTS      OUTPUTS
           T             T            T
           Z             Z            T
           Y       bbb.eee(ii)            Z
           X       +/- BBB     BBB.EEE(ii)
           L            L      +/- BBB

 
-The increment ii is not taken into account, except that it also appears in the X-output
-So "LCO" can be used to move or swap matrices: X-output = control number of the second matrix with ii = number of rows.

-Choose a positive X-input  BBB to move a block of registers
-Choose a negative X-input  -BBB to swap 2 blocks of registers
 

5°) Circular Permutation of 3 Blocks
 

Data Registers:   Only those of the 3 Lists
Flags: /
Subroutines: /
 
 

 01  LBL "L123"
 02  SIGN
 03  LBL 01
 04  CLX
 05  RCL IND Z
 06  X<> IND Y
 07  X<> IND L
 08  STO IND Z
 09  ISG Z
 10  CLX
 11  ISG Y
 12  CLX
 13  ISG L
 14  GTO 01
 15  END

 
   ( 32 bytes )
 
 

      STACK        INPUTS      OUTPUTS
           T             T             T
           Z     bbb.eee(ii)1             /
           Y     bbb.eee(ii)2            /
           X     bbb.eee(ii)3             /

-T-register is saved.
-The order of the permutation is  1 -> 2 -> 3 -> 1

Example:

   { R01  R02  R03  R04 } = { 2  4  1  8 }
   { R11  R12  R13  R14 } = { 7  1  9  3 }
   { R21  R22  R23  R24 } = { 5  3  2  6 }

  1.004   ENTER^
 11.014  ENTER^
 21.024  XEQ "L123"  >>>>  ( 6 )  and now,

   { R01  R02  R03  R04 } = { 5  3  2  6 }
   { R11  R12  R13  R14 } = { 2  4  1  8 }
   { R21  R22  R23  R24 } = { 7  1  9  3 }
 

6°) Reversion of a List
 

Data Registers:   Only those of the list
Flags: /
Subroutines: /
 
 

 01  LBL "RVL"
 02  ENTER^
 03  FRC
 04   E3
 05  *
 06  LBL 01
 07  RCL IND Y
 08  X<> IND Y
 09  STO IND Z
 10  RDN
 11  ISG Y
 12  DSE X
 13  X>Y?
 14  GTO 01
 15  END

 
  ( 30 bytes )
 
 

      STACK        INPUT      OUTPUT
           X        bbb.eee             /

 
Example:          { R01  R02  R03  R04 } = { 2  4  1  8 }

  1.004   XEQ "RVL"  >>>>  ( 2 )   and   { R01  R02  R03  R04 } = { 8  1  4  2 }
 

7°) Deleting an Element from a List
 

Data Registers:   Only those of the list
Flags: /
Subroutines: /
 
 

01  LBL "LDL"
02  RCL Y
03  X<>Y
04  LBL 01
05  RCL IND Y
06  X=Y?
07  GTO 00
08  RDN
09  ISG Y
10  GTO 01      
11  X<> Z
12  RTN
13  LBL 00
14  R^
15  R^
16  ENTER^
17  ISG Y
18  X<0?
19  GTO 00      
20  LBL 02
21  RCL IND Y
22  STO IND Y
23  RDN
24  ISG X
25  ISG Y
26  GTO 02
27  LBL 00
28 X<> Z
29   E-3
30  -
31  END          
 

 
    ( 55 bytes )
 
 

      STACK        INPUTS      OUTPUTS
           Y        bbb.eee             /
           X             x       bbb.eee'

 
Example:     Delete  7  from the list    { R10  R11  R12 } = { 3  7  2 }

   10.012  ENTER^
        7      XEQ "LDL"  >>>>  10.011    and    { R10  R11 } = { 3  2 }

-If x is not in the list, the list is unchanged and bbb.eee' = bbb.eee
-If x is the unique element ( eee = bbb ), eee' = bbb-1
-"LDL" only deletes the first element equal to x.
-If you want to delete all the elements equal to x, execute "LDL" recursively until bbb.eee' = bbb.eee or eee' = bbb-1
 

8°) Intersection of 2 Sets
 

-We seek the elements that are common to 2 given non-empty sets.
 

Data Registers:   Only those of the 3 sets
Flags: /
Subroutines: /
 
 

01  LBL "INTER"
02  STO M
03  STO N
04  RDN
05  STO Z
06  DSE N
07  LBL 01
08  CLX
09  RCL IND Y  
10  RCL Z
11  SIGN
12  LBL 02
13  CLX
14  RCL IND L
15  X=Y?
16  GTO 03        
17  ISG L
18  GTO 02
19  GTO 04
20  LBL 03
21  ISG N
22  LBL 03
23  STO IND N  
24  LBL 04
25  RDN
26  ISG Y
27  GTO 01
28  RCL N
29   E3
30  /
31  RCL M         
32  +
33  CLA
34  END

 
   ( 62 bytes )
 
 

      STACK        INPUTS      OUTPUTS
           Z       bbb.eee1             /
           Y       bbb.eee2             /
           X          BBB       BBB.EEE

 
Example:

      { R01  R02  R03  R04 }      =   { 2  4  1  8 }     =  A
  { R11  R12  R13  R14  R15 } = { 4  9  2  10  8 } =  B

-If you choose  BBB = 21

  1.004   ENTER^
 11.015  ENTER^
    21      XEQ "INTER"  >>>  21.023      and   { R21  R22  R23 } = { 2  4  8 } = A Ç B

-We assume that each element appears only once in the set.
-If the intersection is the empty set,  EEE = BBB - 1 ( with BBB = 21,  X-Output would be 21.020 )
 

9°) Union of 2 Sets
 

Data Registers:   Only those of the 3 sets
Flags: /
Subroutine:   "LCO"  ( cf § 2 )
 
 

01  LBL "UNION"
02  X<>Y
03  STO N
04  RDN
05  XEQ "LCO"
06  STO M
07  LASTX
08   E3
09  *
10  LBL 01
11  RCL IND N   
12  RCL M
13  SIGN
14  LBL 02
15  CLX
16  RCL IND L   
17  X=Y?
18  GTO 03
19  ISG L
20  GTO 02
21  ISG Z
22  CLX
23  RDN
24  STO IND Y   
25   E-3
26  ST+ M
27  LBL 03
28  X<> Z
29  ISG N
30  GTO 01          
31  X<> M
32  CLA
33  END

 
   ( 65 bytes )
 
 

      STACK        INPUTS      OUTPUTS
           Z       bbb.eee1             /
           Y       bbb.eee2             /
           X          BBB       BBB.EEE

 
Example:

        { R01  R02  R03  R04 }    =    { 2  4  1  8 }    = A
   { R11  R12  R13  R14  R15 } = { 4  9  2  10  8 } = B

-If you choose  BBB = 21

  1.004   ENTER^
 11.015  ENTER^
    21      XEQ "UNION"  >>>  21.026      and   { R21  R22  R23  R24  R25  R26 } = { 2  4  1  8  9  10 } = A È B

-We assume that each element appears only once in the set.
 

References:

[1]  PPC ROM user's manual
[2]  Philippe Descamps & Jean-Jacques Dhenin , "Programmer HP-41" - PSI - ISBN 2-86595-056-5  ( in French )