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 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: code format="bb4w" DEF PROCassemble LOCAL L%, P%, code%, pass% DIM code% 200, L% -1 FOR pass% = 8 TO 10 STEP 2 P% = code% [OPT pass% code code format="asm" ; 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 code code format="bb4w" ]     NEXT pass% ENDPROC code