Routines 
Prev: 00949  Up: Map  Next: 01134 
The address of this routine is found in the parameter table.
The subroutine is entered with two numbers on the calculator stack. The topmost number (P) represents the 'pitch' of the note and the number underneath it (t) represents the 'duration'.


BEEP  01016  RST 40  The floatingpoint calculator is used to manipulate the two values: t, P.  
01017  DEFB 49  duplicate: t, P, P  
01018  DEFB 39  int: t, P, i (where i=INT P)  
01019  DEFB 192  st_mem_0: t, P, i (mem0 holds i)  
01020  DEFB 3  subtract: t, p (where p is the fractional part of P)  
01021  DEFB 52  stk_data: Stack the decimal value K=0.0577622606 (which is a little below 12*(2↑0.5)1)  
01022  DEFB 236,108,152,31,245  
01027  DEFB 4  multiply: t, pK  
01028  DEFB 161  stk_one: t, pK, 1  
01029  DEFB 15  addition: t, pK+1  
01030  DEFB 56  end_calc  
Now perform several tests on i, the integer part of the 'pitch'.


01031  LD HL,23698  This is 'mem01st' (MEMBOT).  
01034  LD A,(HL)  Fetch the exponent of i.  
01035  AND A  Give an error if i is not in the integral (short) form.  
01036  JR NZ,REPORT_B  
01038  INC HL  Copy the sign byte to the C register.  
01039  LD C,(HL)  
01040  INC HL  Copy the lowbyte to the B register, and to the A register.  
01041  LD B,(HL)  
01042  LD A,B  
01043  RLA  Again give report B if i does not satisfy the test: 128<=i<=+127.  
01044  SBC A,A  
01045  CP C  
01046  JR NZ,REPORT_B  
01048  INC HL  
01049  CP (HL)  
01050  JR NZ,REPORT_B  
01052  LD A,B  Fetch the lowbyte and test it further.  
01053  ADD A,60  
01055  JP P,BE_i_OK  Accept 60<=i<=67.  
01058  JP PO,REPORT_B  Reject 128 to 61.  
Note: the range 70 to 127 will be rejected later on.
The correct frequency for the 'pitch' i can now be found.


BE_i_OK  01061  LD B,250  Start '6' octaves below middle C.  
BE_OCTAVE  01063  INC B  Repeatedly reduce i in order to find the correct octave.  
01064  SUB 12  
01066  JR NC,BE_OCTAVE  
01068  ADD A,12  Add back the last subtraction.  
01070  PUSH BC  Save the octave number.  
01071  LD HL,1134  The base address of the 'semitone table'.  
01074  CALL LOC_MEM  Consider the table and pass the 'A th.' value to the calculator stack. (Call it C.)  
01077  CALL STACK_NUM  
Now the fractional part of the 'pitch' can be taken into consideration.


01080  RST 40  t, pK+1, C  
01081  DEFB 4  multiply: t, C(pK+1)  
01082  DEFB 56  end_calc  
The final frequency f is found by modifying the 'last value' according to the octave number.


01083  POP AF  Fetch the octave number.  
01084  ADD A,(HL)  Multiply the 'last value' by 2 to the power of the octave number.  
01085  LD (HL),A  
01086  RST 40  t, f  
01087  DEFB 192  st_mem_0: Copy the frequency (f) to mem0  
01088  DEFB 2  delete: t  
Attention is now turned to the 'duration'.


01089  DEFB 49  duplicate: t, t  
01090  DEFB 56  end_calc  
01091  CALL FIND_INT1  The value 'INT t' must be in the range 0 to 10.  
01094  CP 11  
01096  JR NC,REPORT_B  
The number of complete cycles in the 'beep' is given by f*t so this value is now found.


01098  RST 40  t  
01099  DEFB 224  get_mem_0: t, f  
01100  DEFB 4  multiply: f*t  
The result is left on the calculator stack whilst the length of the 'timing loop' required for the 'beep' is computed.


01101  DEFB 224  get_mem_0: f*t, f  
01102  DEFB 52  stk_data: Stack the value (3.5*10↑6)/8=437500  
01103  DEFB 128,67,85,159,128  
01108  DEFB 1  exchange: f*t, 437500, f  
01109  DEFB 5  division: f*t, 437500/f  
01110  DEFB 52  stk_data: f*t, 437500/f, 30.125  
01111  DEFB 53,113  
01113  DEFB 3  subtract: f*t, 437500/f30.125  
01114  DEFB 56  end_calc  
Note: the value 437500/f gives the 'halfcycle' length of the note and reducing it by 30.125 allows for 120.5 T states in which to actually produce the note and adjust the counters etc.
The values can now be transferred to the required registers.


01115  CALL FIND_INT2  The 'timing loop' value is compressed into the BC register pair and saved.  
01118  PUSH BC  
Note: if the timing loop value is too large then an error will occur (returning via ERROR_1), thereby excluding 'pitch' values of 70 to 127.


01119  CALL FIND_INT2  The f*t value is compressed into the BC register pair.  
01122  POP HL  Move the 'timing loop' value to the HL register pair.  
01123  LD D,B  Move the f*t value to the DE register pair.  
01124  LD E,C  
However before making the 'beep' test the value f*t.


01125  LD A,D  Return if f*t has given the result of 'no cycles' required.  
01126  OR E  
01127  RET Z  
01128  DEC DE  Decrease the cycle number and jump to BEEPER (making at least one pass).  
01129  JP BEEPER  
Report B  integer out of range.


REPORT_B  01132  RST 8  Call the error handling routine.  
01133  DEFB 10 
Prev: 00949  Up: Map  Next: 01134 