{ If you want absolute silence (no ticks and very short beeps you get with the timer interrupt approach), and you are running QEMM 7.03 or higher, you can use this.If anyone is interested, I have also some sources with the same routines to capture IO access under QEMM. === { NoSound, PC Speaker sound killer for QEMM 7.03+, Arne de Bruijn, 19960405. } { Released to the Public Domain. } { Run it to install, run with /U to remove it. } {$G+} uses dos; { Resident part } { Only code segment will be preserved, so necessary variables are stored here }procedure QPI_CS; assembler; asm db 0,0,0; end; procedure OldTrap_CS; assembler; asm end; procedure OldIOTrap_CS; assembler; asm db 0,0,0; end; procedure MyTrap; far; assembler; { Called when something accesses port $61 } asm test cl,4 { Is the program writing to port $61? } jne @IsWrite { Yes, jump to @IsWrite } push bx mov bx,ax mov ax,1a05h { Pass port read to QEMM, to execute it } call dword ptr cs:[QPI_CS] mov ax,bx pop bx retf @IsWrite: and al,not 2 { Clear speaker bits, so it's always off } push bx mov bx,ax mov ax,1a05h { Pass port write to QEMM, to execute it } call dword ptr cs:[QPI_CS] mov ax,bx pop bx end; procedure End_Of_TSR_Label; assembler; asm end; type TPtr=record Ofs,Seg:word; end; const QPI:pointer=NIL; function GetQemmApi(var QPI:pointer):boolean; assembler; asm mov ah,3fh mov cx,'QE' mov dx,'MM' int 67h mov al,0 test ah,ah jnz @NoQemm mov ax,di mov dx,es cld les di,QPI stosw mov ax,dx stosw mov al,1 @NoQemm: end; procedure QPI_SetIOCallback(IOCallback:pointer); assembler; asm mov ax,1a07h les di,IOCallback call [QPI] end; function QPI_GetPortTrap(PortNo:word):boolean; assembler; asm mov ax,1a08h mov dx,PortNo call [QPI] mov al,bl end; procedure QPI_SetPortTrap(PortNo:word); assembler; asm mov ax,1a09h mov dx,PortNo call [QPI] end; procedure QPI_ClearPortTrap(PortNo:word); assembler; asm mov ax,1a0ah mov dx,PortNo call [QPI] end; function QPI_GetVersion(var Version:word):boolean; assembler; asm mov ax,word ptr [QPI] or ax,word ptr [QPI+2] jz @NoQemm mov ah,3 call [QPI] jc @NoQemm les di,Version stosw mov al,1 db 0a9h { Skip following instruction (2 bytes) } @NoQemm: mov al,0 end; procedure QPI_GetIOCallback(var IOCallBack:pointer); assembler; asm mov ax,1a06h call [QPI] mov ax,di mov dx,es cld les di,IOCallBack stosw mov ax,dx stosw end; var W:word; OldIOTrap:pointer; S:string[2]; begin if not GetQemmApi(QPI) then begin WriteLn('QEMM not installed!'); Halt(1); end; pointer((@QPI_CS)^):=QPI; if not QPI_GetVersion(W) then begin WriteLn('QPI_GetVersion error!'); Halt(1); end; if W<$0703 then begin WriteLn('Need QEMM 7.03+'); Halt(1); end; QPI_GetIOCallback(OldIOTrap); { Get current IO trap function } if word(OldIOTrap)=Ofs(MyTrap) then { Ours? } begin S:=ParamStr(1); S[2]:=Upcase(S[2]); if S<>'/U' then WriteLn('NoSound already installed! Use /U to unload.') else begin { Restore port trap state } if not boolean(ptr(TPtr(OldIOTrap).Seg,ofs(OldTrap_CS))^) then QPI_ClearPortTrap($61); QPI_SetIOCallback(pointer(ptr(TPtr(OldIOTrap).Seg,ofs(OldIOTrap_CS))^)); W:=TPtr(OldIOTrap).Seg-$10; { TSR PSP segment (just under code segment) } asm mov ah,49h { DOS function 'Free memory block' } mov es,W { Get TSR PSP segment } push es { Save it } mov es,es:[2ch] { Get TSR environment segment } int 21h { Free it } mov ah,49h { Again 'Free memory block' } pop es { Restore TSR PSP segment } int 21h { Free it } end; WriteLn('NoSound removed.'); end; Halt(0); end; QPI_SetIOCallback(@MyTrap); pointer((@OldIOTrap_CS)^):=OldIOTrap; boolean((@OldTrap_CS)^):=QPI_GetPortTrap($61); QPI_SetPortTrap($61); WriteLn('NoSound installed.'); swapvectors; asm mov ax,3100h { DOS function 'Terminate and stay resident' } mov dx,offset End_Of_Tsr_Label+15+256 { Calculate resident size } shr dx,4 { Scale down to paragraphs } int 21h { Go TSR } end; end.