=====SOUND and ENVELOPE in assembler===== //by Richard Russell, March 2010//\\ \\ //BBC BASIC for Windows// provides no direct means for an assembly language program to access the **SOUND** or **ENVELOPE** statements. It can be achieved using the technique described in [[/Calling%20BASIC%20from%20assembler%20code|Calling BASIC from assembler code]] but an alternative approach is to use the code listed below. This makes available three subroutines: **Sound**, **Envelope** and **Qstatus**, the last of which allows you to discover the amount of space available in a sound queue (similar to what can be achieved using **ADVAL**).\\ \\ The parameters and returned values are documented within the code: DEF PROCassemble LOCAL L%, P%, code%, pass% DIM code% 200, L% -1 FOR pass% = 8 TO 10 STEP 2 P% = code% [OPT pass% ; SOUND ; Inputs; eax = &HSFC ; ebx = amplitude/envelope ; ecx = pitch ; edx = duration ; Destroys; eax, ebx, ecx, edx, esi, edi, flags ; .Sound cmp dword,[^@hwo%],0 jnz snd0 pushad push 0 push 0 push &405 push @hwnd% call "SendMessage" popad .snd0 mov esi,eax and esi,3 imul edi,esi,20 add edi,@vdu%+112 test al,&F0 jz snd1 .snd5 mov al,[esi+@vdu%+80] mov [esi+@vdu%+76],al cmp al,[esi+@vdu%+80] jnz snd5 .snd1 mov bh,ah movzx eax,byte [esi+@vdu%+76] mov [edi+eax+0],dl mov [edi+eax+1],cl mov [edi+eax+2],bl mov [edi+eax+3],bh add al,4 cmp al,20 jc snd2 xor al,al .snd2 cmp al,[esi+@vdu%+80] jnz snd3 push 1 call "Sleep" test byte [^@flags%+3],&80 jz snd2 ret ; .snd3 mov [esi+@vdu%+76],al ret ; ; Sound queue status ; Inputs; eax = channel number ; Outputs; eax = no. of bytes free ; Destroys; eax, ebx, flags ; .Qstatus and eax,3 mov ebx,eax mov al,[ebx+@vdu%+80] sub al,[ebx+@vdu%+76] jz qstat0 jnc qstat1 .qstat0 add al,20 .qstat1 sub al,4 ret ; ; ENVELOPE ; Inputs; eax = envelope number ; ebx = address of 13 byte parameter block ; Destroys; eax, ecx, esi, edi, flags ; .Envelope and eax,15 shl eax,4 mov edi,[@vdu%-28] add edi,eax mov esi,ebx mov ecx,13 rep movsb ret ] NEXT pass% ENDPROC