In that case you would have compiled your assembly routine, known where the address of the volume resides and simply poke a value to it, following that with the routine itself and a Frame Flyback to generate the same effect as if it would have come from the SOUND in basic. The advantage to doing this is perhaps clearer when using other Languages which don't have their own SOUND routines, though can access the Firmware Routines in order to generate the effects using that approach.
 
'''Holding Notes without Frame Flyback'''
 
Back in 2011 when I wrote these sound routines which holds the notes with Frame Flyback, I forgot to look into this further as at the time I was somewhat happy with the result. However, I've rectified this by using the appropriate flag to hold  the note until it becomes True. This is the resulting program:
 
<pre>
	org &4000
.sque 	equ &bcaa
	ld b,15
.loop 	ld hl,volume 
	ld (hl),b
	push bc
	ld hl,sdata
.holdnote
	call sque
	jr nc,holdnote
	pop bc
	djnz loop 
	ret
.sdata 	defb 1 
	defb 0 
	defb 0 
	defb 0 
	defb 0 
	defb 31
.volume defb 0
	defb 3 
	defb 0
</pre>
 
So now the Frame Flyback has been removed (CALL &BD19), and a new label called holdnote is used with jr nc,holdnote causing a jump to take place until carry becomes true.
 
=== Sample Sound Example 3 ===
 
My next BASIC example is a simple example of playing a tune, however BASIC is cleverly using math to play the tune:
 
<pre>
10 FOR octave=-1 TO 2
20 FOR x=1 TO 7: REM notes per octave
30 READ note
40 SOUND 1,note/2^octave
50 NEXT
60 RESTORE
70 NEXT
80 DATA 426,379,358,319,284,253,239
</pre>
 
For this example, I've simplified my Assembly example by working out the values of each tone and rounding the values to their nearest whole values, this is what I ended up with, with some of the value either being rounded up or down depending on it's decimal weight:
 
<pre>
852, 758, 716, 638, 568, 506, 478
426, 379, 358, 319, 284, 253, 239
213, 190, 179, 160, 142, 127, 120
107, 95, 90, 80, 71, 63, 60</pre>
 
From that, that information can be used for the Assembly routine, with each note being pick and stored where the other sound data resides. This produces the simplist of Sound tune engines which like BASIC variants, no other operations are carried out until the routine has run its course.
 
<pre>	org &8000
 
	ld b,29
.loop
	ld hl,(adrtune)		;; address of tune
 
	ld e,(hl)		;; put contents of 
	inc hl
	ld d,(hl)		;; tune into DE
 
	ld hl,tone		;; address of tone
	
	ld (hl),e		;; store tune 
	inc hl
	ld (hl),d		;; into tone
 
	push bc			;; preserve loop value
 
	ld hl,sdata		;; address of sound data
.holdnote
	call &bcaa		;; Sound Queue
	jr nc,holdnote		;; Hold note until carry is true
 
	pop bc			;; restore loop value
 
	ld hl,(adrtune)		;; increment address of tune
	inc hl
	inc hl
	ld (adrtune),hl		;; to the next tune value
 
	djnz loop		;; loop until b=0
 
	ld hl,tune		;; return the tune
	ld (adrtune),hl		;; back to the start.
 
	ret			;; exit routine.
 
.sdata	
	defb 1,0,0
.tone	
	defb 0,0,0,12,20,0
 
.adrtune
	defw tune
.tune	
	defw 852,758,716,638,568,506,478
	defw 426,379,358,319,284,253,239
	defw 213,190,179,160,142,127,120
	defw 107,95,90,80,71,63,60,0</pre>
 
The only other limiting factor is how big the tune can be, using this approach only 255 notes can be played.
[[Category:Programming]]