hp41programs

Star-Spangled Banner

The Star-Spangled Banner for the HP-41


Overview
 

-With the following program, your HP-41 will play the "Star-Spangled Banner". It uses 2 M-Code routines: "AA" & "BB" listed below.
-It seems impossible to play all the notes with synthetic tones only,
-And even with M-Code, some frequencies remain approximate...

-A second program that employs only one M-Code routine "AB" is also listed.
 

2 Micro-Code Routines:  "AA"  "BB"
 

081   "A"
001   "A"
3C4  ST=0
258   T=ST
130   LDI S&X
0FF  0FFh
358   ST=C XP
0F8   READ 3(X)
38D  ?NCXQ               this subroutine takes a number in CPU-register C,
008   02E3                    converts it into hexadecimal and places the result in the S&X field of C
070   N=C
0B8   READ 2(Y)
38D  ?NCXQ
008   02E3
10E   A=C
2D8  ST<>T                 the beginning of the loop
0B0  C=N
266  C=C-1 S&X
3FB  JNC -01
1A6  A=A-1 S&X
3DB  JNC -05
3E0   RTN

-The only differences between "AA" & "BB" are the NOP inside the loop and - therefore - the last  JNC instruction:

082   "B"
002   "B"
3C4  ST=0
258   T=ST
130   LDI S&X
0FF  0FFh
358  ST=C XP
0F8   READ 3(X)
38D  ?NCXQ
008   02E3
070   N=C
0B8   READ 2(Y)
38D  ?NCXQ
008   02E3
10E   A=C
2D8  ST<>T                 the beginning of the loop
0B0  C=N
000  NOP
266  C=C-1 S&X
3FB  JNC -01
1A6  A=A-1 S&X
3D3  JNC -06
3E0   RTN
 

-These routines take 2 integers smaller than 1000 in registers X and Y
-X determines the frequency of the tone and Y ( and - indirectly - X ) determines its duration.

-For example  401  ENTER^  9  XEQ "BB"  produces  a  B  during about 2 seconds.
-The smaller the x-value, the higher is the frequency, more precisely:
 
 

       X       AA       BB
       0        C        A
       1        G        F
       2        Eb    D / Db
       3        C      Bb
       4        A      Ab
       5        G      Gb
       6        F       E
       7       Eb       D
       8   ~ Db   ~ Db
       9       C       B
      10   ~ Bb      Bb
      11       A    ~ A

 
Remarks:

-As you can see, the notes are not always quite right and I hope that your ears will be indulgent sometimes...
-If you place numbers greater than 1000 in magnitude in X- or Y-registers, you'll simply get "NON EXISTENT"
-And you'll get "ALPHA DATA" if  registers X or Y contain alpha string(s)
-In other words, there is no risk of "crash" !
 

Warning:

-If you place an even integer in register Y , your HP-41 may emit a strange "frrrrrrrr" after the tone  ( press your ear against your calculator to check )
-It's probably because FFh remains in CPU-register T.
-Simply execute a BEEP or any non-synthetic TONE to remove this vibration.
-So I've only used odd integers in the following program.
 

Program Listing
 

Data Registers: /
Flag:  F26
Subroutines: /

-Lines 58 & 64 produce the most doubtful note...
-Line 81 is a three-byte  GTO 01
 
 

  01  LBL "SSB"
  02  2
  03  SIGN
  04  LBL 01
  05  99
  06  3
  07  BB              
  08  99
  09  5
  10  AA
  11  241
  12  7
  13  AA
  14  251
  15  5
  16  AA
  17  251
  18  3
  19  BB
  20  601
  21  2
  22  AA
  23  161
  24  1
  25  AA
  26  161
  27  1
  28  BB
  29  301
  30  2
  31  AA
  32  251
  33  5
  34  AA
  35  251
  36  4
  37  AA
  38  501
  39  3
  40  BB
  41  121 
  42  3
  43  BB
  44  121
  45  3
  46  BB              
  47  501
  48  1
  49  AA
  50  161
  51  1
  52  BB
  53  301
  54  2
  55  AA
  56  601
  57  2
  58  BB 
  59  121
  60  3
  61  AA
  62  121
  63  2
  64  BB 
  65  301
  66  2
  67  AA
  68  301
  69  2
  70  AA
  71  251
  72  3
  73  BB
  74  241
  75  5
  76  AA
  77  241
  78  7
  79  AA
  80  DSE L
  81  GTO 01 
  82  91
  83  5
  84  AA
  85  91
  86  5
  87  AA              
  88  201
  89  5
  90  AA
  91  201
  92  4
  93  BB
  94  501
  95  3
  96  BB
  97  99
  98  4
  99  BB
100  99
101  5
102  AA
103  201
104  6
105  AA
106  201
107  5
108  AA
109  501
110  4
111  BB
112  99
113  4
114  BB
115  301
116  5
117  AA
118  99
119  6
120  AA
121  201 
122  7
123  AA
124  401
125  7
126  BB              
127  81
128  9
129  AA
130  81
131  7
132  BB
133  201
134  7
135  AA
136  99
137  12
138  BB
139  99
140  11
141  AA
142  401
143  10
144  AA
145  81
146  10
147  AA
148  81
149  10
150  AA
151  201
152  7
153  AA
154  201
155  7
156  AA
157  91
158  7
159  AA
160  91
161  7
162  BB
163  201 
164  9
165  AA              
166  201
167  9
168  AA
169  81
170  7
171  AA
172  81
173  7
174  AA
175  201
176  6
177  AA
178  99
179  4
180  BB
181  99
182  5
183  AA
184  99
185  6
186  AA
187  99
188  7
189  AA
190  201
191  7
192  AA
193  401
194  7
195  BB
196  81
197  10
198  AA
199  81
200  10
201  AA
202  301 
203  7
204  AA              
205  99
206  6
207  AA
208  99
209  5
210  AA
211  99
212  4
213  BB
214  501
215  3
216  BB
217  99
218  7
219  AA
220  99
221  6
222  AA
223  381
224  5
225  AA
226  99
227  4
228  BB
229  381
230  6
231  AA
232  99
233  7
234  AA
235  501
236  7
237  AA
238  END

 
    ( 533 bytes / SIZE 000 )
 
 

      STACK        INPUTS      OUTPUTS
           X             /             7

 
   GTO .081   SST  ( in RUN mode )  to compile the  GTO 01

   XEQ "SSB" ( or RTN  R/S )  .......   execution time = 81s  on my HP-41CX   ( with flag F26 set )
 

Notes:
 

-It will run slightly faster on an HP-41C/CV
- ... and a lot faster if you have speeded up your calculator!

-Perhaps you will find this version is a little bit too slow, but if you prefer another tempo,
  change the numbers in lines 05  08  11  ....  77  and  82  85  88  .....  235  ( the successive Y-values )
 

Improvements:
 

-The tones produced by lines 56-57-58 & 62-63-64 are almost (?) false notes.
-They can be replaced by  301   2   CC   &   61   2   CC  respectively
  to give the right note ( a "D" )  where  CC  is the following M-code routine:
 

Warning:

-I recently realized that, unfortunately, CC does not give the correct note with V41.
 

083   "C"
003   "C"
3C4  ST=0
258   T=ST
130   LDI S&X
0FF   0FFh
358   ST=C XP
0B8   READ 2(Y)
38D  ?NCXQ
008   02E3
2D8  ST<>T                 the beginning of the loop
000  NOP
000  NOP
000  NOP
000  NOP
000  NOP
000  NOP                    10 NOPs
000  NOP
000  NOP
000  NOP
000  NOP
2D8  ST<>T
000  NOP
000  NOP
000  NOP
000  NOP                     7  NOPs
000  NOP
000  NOP
000  NOP
266  C=C-1 S&X
363  JNC -20d = -14h
3E0  RTN
 

-However, this note sounds a little "odd" because the FFh and 00h are left in the CPU-register T for a different number of cycles.
 

Another Micro-Code Routine:  "AB"
 

-Instead of using 2 ( or even 3 ) entries in the FAT, we can combine the M-Code routines AA  BB  CC  in a single one that I've called "AB"
 

082   "B"
001   "A"
3C4   ST=0
258   T=ST
130   LDI S&X
0FF   0FFh
358   ST=C XP
0B8  READ 2(Y)
2FE  ?C#0 MS
08B  JNC +11h=+17d
0F8  READ 3(X)
38D  ?NCXQ
008   02E3
070   N=C ALL
0B8  READ 2(Y)
38D  ?NCXQ
008   02E3
10E   A=C ALL
2D8  ST<>T
0B0  C=N ALL
000   NOP
266   C=C-1 S&X
3FB  JNC -01
1A6  A=A-1 S&X
3D3  JNC -06
3E0   RTN
0F8   READ 3(X)
2FE  ?C#0 MS
07F   JC +0Fh=+15d
38D  ?NCXQ
008   02E3
070   N=C ALL
0B8  READ 2(Y)
38D  ?NCXQ
008   02E3
10E   A=C ALL
2D8  ST<>T
0B0  C=N ALL
266   C=C-1 S&X
3FB  JNC -01
1A6  A=A-1 S&X
3DB  JNC -05
3E0   RTN
0B8   READ 2(Y)
38D  ?NCXQ
008   02E3
2D8  ST<>T
1D8  C<>M ALL
130   LDI S&X
002   002
266   C=C-1 S&X
3FB  JNC -01
1D8  C<>M ALL
2D8  ST<>T
000   NOP
000   NOP
000   NOP
000   NOP
000   NOP
000   NOP
000   NOP
266   C=C-1 S&X
383   JNC -10h=-16d
3E0   RTN
 

-Now,  if  x > 0,

     AB  with  y > 0  is equivalent to  AA
     AB  with  y < 0  is equivalent to  BB

-And if  x < 0,  we get  CC
-So, we can change the listing as follows:
 

Program Listing 2
 

Data Registers: /
Flag:  F26
Subroutines: /
 

-Line 91 is a three-byte  GTO 01
 
 

  01  LBL "SSB"
  02  2
  03  SIGN
  04  LBL 01
  05  99
  06  CHS
  07  3
  08  AB            
  09  99
  10  5
  11  AB
  12  241
  13  7
  14  AB
  15  251
  16  5
  17  AB
  18  251
  19  CHS
  20  3
  21  AB
  22  601
  23  2
  24  AB
  25  161
  26  1
  27  AB
  28  161
  29  CHS
  30  1
  31  AB
  32  301
  33  2
  34  AB
  35  251
  36  5
  37  AB
  38  251
  39  4
  40  AB
  41  501
  42  CHS
  43  3
  44  AB
  45  121
  46  CHS 
  47  3
  48  AB
  49  121
  50  CHS
  51  3
  52  AB            
  53  501
  54  1
  55  AB
  56  161
  57  CHS
  58  1
  59  AB
  60  301
  61  2
  62  AB
  63  301
  64  1
  65  CHS
  66  AB 
  67  121
  68  3
  69  AB
  70  61
  71  1
  72  CHS
  73  AB 
  74  301
  75  2
  76  AB
  77  301
  78  2
  79  AB
  80  251
  81  CHS
  82  3
  83  AB
  84  241
  85  5
  86  AB
  87  241
  88  7
  89  AB
  90  DSE L
  91  GTO 01 
  92  91
  93  5
  94  AB
  95  91
  96  5
  97  AB            
  98  201
  99  5
100  AB
101  201
102  CHS
103  4
104  AB
105  501
106  CHS
107  3
108  AB
109  99
110  CHS
111  4
112  AB
113  99
114  5
115  AB
116  201
117  6
118  AB
119  201
120  5
121  AB
122  501
123  CHS
124  4
125  AB
126  99
127  CHS
128  4
129  AB
130  301
131  5
132  AB
133  99
134  6
135  AB
136  201
137  7
138  AB
139  401
140  CHS 
141  7
142  AB            
143  81
144  9
145  AB
146  81
147  CHS
148  7
149  AB
150  201
151  7
152  AB
153  99
154  CHS
155  12
156  AB
157  99
158  11
159  AB
160  401
161  10
162  AB
163  81
164  10
165  AB
166  81
167  10
168  AB
169  201
170  7
171  AB
172  201
173  7
174  AB
175  91
176  7
177  AB
178  91
179  CHS 
180  7
181  AB
182  201
183  9
184  AB
185  201
186  9
187  AB            
188  81
189  7
190  AB
191  81
192  7
193  AB
194  201
195  6
196  AB
197  99
198  CHS
199  4
200  AB
201  99
202  5
203  AB
204  99
205  6
206  AB
207  99
208  7
209  AB
210  201
211  7
212  AB
213  401
214  CHS
215  7
216  AB
217  81
218  10
219  AB
220  81
221  10
222  AB
223  301
224  7
225  AB
226  99
227  6
228  AB
229  99
230  5
231  AB            
232  99
233  CHS 
234  4
235  AB
236  501
237  CHS
238  3
239  AB
240  99
241  7
242  AB
243  99
244  6
245  AB
246  381
247  5
248  AB
249  99
250  CHS
251  4
252  AB
253  381
254  6
255  AB
256  99
257  7
258  AB
259  501
260  7
261  AB
262  END

 
     ( 534 bytes / SIZE 000 )
 
 

      STACK        INPUTS      OUTPUTS
           X             /             7

 
   GTO .091   SST  ( in RUN mode )  to compile the  GTO 01

   XEQ "SSB" ( or RTN  R/S )  .......   execution time = 81s  with an HP-41CX   ( flag F26 set )
 

Notes:

-The execution time is almost unchanged, provided you key in, for example,  99  CHS  instead of  -99
-The NEG instruction would be slower...

-Unfortunately, like CC, lines 63 to 66 and 70 to 73 do not give the correct note with V41.