10000 END
10010 REM Z88 BEEP(duration,note) routines by Ben Ryves 2020
10020 DEF PROC_BEEP(duration,note)
10030 LOCAL p,p_a,p_b,t_p,d
10040 p=((beep_p/2^(note/12))-122)/13
10050 p_a=INT(p):IF p_a<0 ENDPROC
10060 p_b=INT(p+0.5)
10070 t_p=p*13+122
10080 d=INT(cpu_f/t_p/2*duration)
10090 IF d<=0 ENDPROC
10100 IF d>65535 d=65535
10110 D%=p_a DIV 256:E%=p_a
10120 H%=p_b DIV 256:L%=p_b
10130 B%=d DIV 256:C%=d
10140 CALL beep
10150 ENDPROC
10160 DEF PROC_BEEP_INIT
10170 cpu_f=3276800
10180 root_f=261.6255653
10190 beep_p=cpu_f/root_f/2
10200 OZ_Di=&0051:OZ_Ei=&0054
10210 COM=&B0:SBIT=6
10220 beep_s=100
10230 DIM beep beep_s
10240 FOR pass=0 TO 2 STEP 2
10250   P%=beep
10260   [
10270   OPT pass
10280   ; Store duration/periods
10290   LD (beep_d+1),BC
10300   LD (beep_p_a+1),DE
10310   LD (beep_p_b+1),HL
10320   ; Preserve BASIC stack pointer
10330   LD HL,0
10340   ADD HL,SP
10350   LD SP,&1FFE
10360   PUSH HL
10370   ; Disable interrupts
10380   CALL OZ_Di
10390   PUSH AF
10400   ; Restore beep duration and loop
10410   .beep_d LD DE,0
10420   .beep_loop
10430   ; High part of cycle
10440   LD A,(&0400+COM)
10450   XOR 2^SBIT
10460   OUT (COM),A
10470   .beep_p_a LD BC,0
10480   CALL delay
10490   ; Pad for loop overhead
10500   NEG:NEG:NOP
10510   ; Low part of cycle
10520   LD A,(&0400+COM)
10530   OUT (COM),A
10540   .beep_p_b LD BC,0
10550   CALL delay
10560   ; Loop for duration
10570   DEC DE
10580   LD A,D
10590   OR E
10600   JP NZ,beep_loop
10610   ; Restore interrupts
10620   POP AF
10630   CALL OZ_Ei
10640   ; Restore BASIC stack pointer
10650   POP HL
10660   LD SP,HL
10670   RET
10680   ; Delays for BC*13+61 cycles
10690   .delay
10700   LD A,B
10710   OR A
10720   JR NZ,long_delay_loop
10730   OR C
10740   NOP
10750   JR NZ,short_delay
10760   NOP
10770   RET
10780   .long_delay_loop
10790   NEG
10800   LD A,(BC)
10810   LD A,B
10820   LD B,251
10830   CALL short_delay_loop
10840   LD B,A
10850   DJNZ long_delay_loop
10860   LD A,C
10870   OR A
10880   JR NZ,short_delay
10890   NOP
10900   RET
10910   .short_delay
10920   LD B,C
10930   .short_delay_loop
10940   DJNZ short_delay_loop
10950   RET
10960   ]
10970 NEXT pass
10980 IF P%-beep<>beep_s PRINT "beep routine is ";beep_s;" bytes"
10990 ENDPROC