%include "macros.mac" EXTSYM ProcessSoundBuffer,DosExit,getenv,PrintStr,printhex,printnum,WaitForKey EXTSYM SBHDMA,soundon,csounddisable,DisplayS,spcRam,DSPMem EXTSYM Surround,StereoSound,SoundQuality,SoundSpeeds,SBToSPCSpeeds2 EXTSYM SoundSpeedt,DSPBuffer,BufferSize,BufferSizes,BufferSizeB EXTSYM BufferSizeW,dssel NEWSYM SB_alloc_dma mov ax,0100h ; Allocate DOS memory mov bx,16384/16 ; Allocate 16384 bytes int 31h ; To delocate this, use ax=0101h, dx=selector of block/int 31h jc near .error ; Check which 8192 byte boundary doesn't cross a page mov word[memoryloc+2],0 mov dword[memoryloc],0 mov [memoryloc],ax mov [sbselec],dx shl dword[memoryloc],4 mov edx,[memoryloc] shr edx,16 mov al,dl mov edx,[memoryloc] add edx,8192 shr edx,16 mov dword[sbpmofs],0 cmp al,dl je .nonextarea mov dword[sbpmofs],8192 add dword[memoryloc],8192 .nonextarea mov edi,[sbpmofs] mov [SBBufferLoc],edi mov dword[SBBufferMov],1 mov dword[SBBufferInc],4 ; clear dos memory push es mov es,[sbselec] mov edi,[sbpmofs] mov ecx,2048 mov eax,0 rep stosd pop es ret .error mov edx,.nohand ;use extended mov ah,9 ;DOS- API int 21h ;to print a string call DosExit SECTION .data .nohand db 'Unable to allocate conventional memory!',13,10,'$' SECTION .text NEWSYM DeInitSPC cmp byte[SBDeinitType],0 je .nodoublereset call SB_dsp_reset call SB_dsp_reset .nodoublereset ; Turn off speakers mov al,0d3h call SB_dsp_write ; k) Perform Halt DMA Operation, 8-bit command (0D0h - for virtual speaker) mov al,0d0h call SB_dsp_write ; l) Perform Exit Auto-Initialize DMA Operation, 8-bit command (0DAh) cmp byte[SBHDMA],0 je .8b mov al,0d9h call SB_dsp_write jmp .16b .8b mov al,0dAh call SB_dsp_write .16b ; m) Perform Halt DMA Operation, 8-bit command (0D0h - for virtual speaker) mov al,0d0h call SB_dsp_write ; Disable DMA mov al,4 add al,[SBDMA] mov dx,0ah out dx,al ret section .data ;SoundBlaster DSP Ports NEWSYM SBPort, dw 220 NEWSYM SBInt, db 5+8 NEWSYM SBIrq, db 5 NEWSYM SBDMA, db 1 NEWSYM SBDMAPage, db 83 ;NEWSYM SBHDMA, db 0 NEWSYM SBHDMAPage, db 0 NEWSYM vibracard, db 0 NEWSYM SBBufferLoc, dd 0 NEWSYM SBBufferMov, dd 0 NEWSYM SBBufferInc, dd 0 NEWSYM SoundInterrupt, dd 0 ; ViBRA16X fixes! EXTSYM MsgCount ; points to counter EXTSYM MessageOn ; points to "message" delay counter EXTSYM Msgptr ; points to the message to be displayed NEWSYM vibmsg, db 'VIBRA16X MODE ENABLED', 0 section .text NEWSYM SB_dsp_reset mov dx,[SBPort] add dl,06h mov al,01h out dx,al in al,dx in al,dx in al,dx in al,dx mov al,00h out dx,al mov si,200 mov dx,[SBPort] add dl,0Eh .readloop ; wait until port[SBDSPRdStat] AND 80h = 80h mov cx,20000 .tryagain in al,dx dec cx jz .cardfailed or al,al jns .tryagain sub dx,4 in al,dx cmp al,0AAh jne .tryagain2 ret .tryagain2 add dx,4 dec si jnz .readloop .cardfailed mov ax,0003h int 10h mov edx,initfailed ;use extended mov ah,9 ;DOS- API int 21h ;to print a string jmp DosExit section .data NEWSYM initfailed, db 'Sound card failed to initialize!',13,10,'$' section .text ; Write AL into DSP port NEWSYM SB_dsp_write mov dx,[SBPort] add dl,0Ch mov bl,al .tryagain in al,dx test al,80h jnz .tryagain mov al,bl out dx,al ret ; Read DSP port into AL NEWSYM SB_dsp_read mov dx,[SBPort] add dl,0Eh mov bl,al .tryagain in al,dx test al,80h jz .tryagain mov dx,[SBPort] add dl,0Ah mov al,bl in al,dx ret ;**************************************************** ; Sound Blaster Interrupt Stuff ;**************************************************** NEWSYM Interror sti mov edx,.nohand ;use extended mov ah,9 ;DOS- API int 21h ;to print a string call DosExit section .data .nohand db 'Cannot process interrupt handler!',13,10,'$' section .bss NEWSYM oldhandSBs, resw 1 NEWSYM oldhandSBo, resd 1 NEWSYM SBswitch, resb 1 ; which block to process next section .text NEWSYM SBHandler cli push ds push eax NEWSYM handlersbseg mov ax,[cs:dssel] mov ds,ax cmp byte[SBHDMA],0 jne near SBHandler16 ; code added by peter santing cmp byte[vibracard], 1 je near SBHandler16 push ebx push ecx push edx push edi push esi push es call GetCDMAPos cmp byte[csounddisable],1 je near stopsbsound test byte[DSPMem+6Ch],11000000b jnz near stopsbsound ; Process the sound :I mov es,[sbselec] cmp byte[SBswitch],0 jne .2ndblock mov edi,[sbpmofs] jmp .startblockcopy .2ndblock ; copy to 2nd block ; clear memory mov edi,[sbpmofs] add edi,[BufferSizeB] .startblockcopy mov esi,DSPBuffer mov ecx,[BufferSizeB] cmp byte[Surround],0 je .nosurround cmp byte[StereoSound],0 je .surroundmono ; jmp .surroundmono .nosurround .loopb mov eax,[esi] cmp eax,-32768 jge .noneg3 mov eax,-32768 .noneg3 cmp eax,32767 jle .noneg4 mov eax,32767 .noneg4 xor ah,80h mov [es:edi],ah add esi,4 inc edi dec ecx jnz .loopb jmp .sbend %ifdef _I_LIKE_SUCKY_FILTERS_ ;bwahaha .surroundstereo shr ecx,1 .loopbs mov eax,[esi] cmp eax,-32768 jge .noneg3s mov eax,-32768 .noneg3s cmp eax,32767 jle .noneg4s mov eax,32767 .noneg4s xor ah,80h mov [es:edi],ah mov eax,[esi+4] cmp eax,-32768 jge .noneg3s2 mov eax,-32768 .noneg3s2 cmp eax,32767 jle .noneg4s2 mov eax,32767 .noneg4s2 neg ah xor ah,80h mov [es:edi+1],ah add esi,8 add edi,2 dec ecx jnz .loopbs jmp .sbend %endif .surroundmono cmp byte[SBswitch],0 je .1stblock add edi,[BufferSizeB] .1stblock .loopbm mov eax,[esi] cmp eax,-32768 jge .noneg3m mov eax,-32768 .noneg3m cmp eax,32767 jle .noneg4m mov eax,32767 .noneg4m xor ah,80h mov [es:edi],ah xor ah,80h neg ah xor ah,80h mov [es:edi+1],ah add esi,4 add edi,2 dec ecx jnz .loopbm .sbend xor byte [SBswitch],1 ; move the good data at spcRam+0f3h xor eax,eax mov al,[spcRam+0F2h] mov bl,[DSPMem+eax] mov [spcRam+0F3h],bl ; acknowledge SB for IRQing mov dx,[SBPort] add dl,0Eh in al,dx mov al,20h out 20h,al cmp byte[SBIrq],7 jbe .nohighirq mov al,20h out 0A0h,al .nohighirq sti jmp Startprocsbdata NEWSYM stopsbsound ; mov byte[Voice0Status],0 ; mov byte[Voice1Status],0 ; mov byte[Voice2Status],0 ; mov byte[Voice3Status],0 ; mov byte[Voice4Status],0 ; mov byte[Voice5Status],0 ; mov byte[Voice6Status],0 ; mov byte[Voice7Status],0 mov ax,ds mov es,ax mov edi,DSPBuffer mov ecx,[BufferSizeB] xor eax,eax rep stosd cmp byte[SBswitch],0 jne near .2ndblock ; clear block mov es,[sbselec] mov edi,[sbpmofs] mov ecx,[BufferSizeB] shr ecx,2 .loopa mov dword[es:edi],80808080h add edi,4 dec ecx jnz .loopa jmp .sbend .2ndblock ; copy to 2nd block ; clear memory mov es,[sbselec] mov edi,[sbpmofs] add edi,[BufferSizeB] mov ecx,[BufferSizeB] shr ecx,2 .loopb mov dword[es:edi],80808080h add edi,4 dec ecx jnz .loopb .sbend xor byte [SBswitch],1 ; acknowledge SB for IRQing mov dx,[SBPort] add dl,0Eh in al,dx mov al,20h out 20h,al cmp byte[SBIrq],7 jbe .nohighirq mov al,20h out 0A0h,al .nohighirq pop es pop esi pop edi pop edx pop ecx pop ebx pop eax pop ds sti iretd section .bss ;ALIGN=32 NEWSYM sbhandexec, resd 1 section .text ; Process 20 blocks * 8 voices (no pitch yet) NEWSYM SBHandler16 push ebx push ecx push edx push edi push esi push es inc dword[sbhandexec] cmp byte [vibracard], 1 je .donotcallcmdapos call GetCDMAPos .donotcallcmdapos cmp byte[csounddisable],1 je near stopsbsound16 test byte[DSPMem+6Ch],11000000b jnz near stopsbsound16 mov es,[sbselec] cmp byte[SBswitch],0 jne near .2ndblock mov edi,[sbpmofs] jmp .doneblock .2ndblock ; copy to 2nd block ; clear memory mov edi,[sbpmofs] add edi,[BufferSizeW] .doneblock mov esi,DSPBuffer mov ecx,[BufferSizeB] cmp byte[Surround],0 je .nosurround cmp byte[StereoSound],0 ; jne near .surroundstereo je .surroundmono ; jmp .surroundmono .nosurround .loopb mov eax,[esi] cmp eax,-32768 jge .noneg5 mov eax,-32768 .noneg5 cmp eax,32767 jle .noneg6 mov eax,32767 .noneg6 mov [es:edi],ax add esi,4 add edi,2 dec ecx jnz .loopb jmp .sbend %ifdef _I_LIKE_SUCKY_FILTERS_ ;bwahaha .surroundstereo shr ecx,1 .loopbs mov eax,[esi] cmp eax,-32768 jge .noneg5s mov eax,-32768 .noneg5s cmp eax,32767 jle .noneg6s mov eax,32767 .noneg6s mov [es:edi],ax mov eax,[esi+4] cmp eax,-32768 jge .noneg5s2 mov eax,-32768 .noneg5s2 cmp eax,32767 jle .noneg6s2 mov eax,32767 .noneg6s2 neg ax mov [es:edi+2],ax add esi,8 add edi,4 dec ecx jnz .loopbs jmp .sbend %endif .surroundmono cmp byte[SBswitch],0 je .1stblock add edi,[BufferSizeW] .1stblock .loopbm mov eax,[esi] cmp eax,-32768 jge .noneg5m mov eax,-32768 .noneg5m cmp eax,32767 jle .noneg6m mov eax,32767 .noneg6m mov [es:edi],ax neg ax mov [es:edi+2],ax add esi,4 add edi,4 dec ecx jnz .loopbm .sbend xor byte [SBswitch],1 ; acknowledge SB for IRQing mov dx,[SBPort] add dl,0Fh in al,dx mov al,20h out 20h,al cmp byte[SBIrq],7 jbe .nohighirq mov al,20h out 0A0h,al .nohighirq sti Startprocsbdata: call ProcessSoundBuffer pop es pop esi pop edi pop edx pop ecx pop ebx pop eax pop ds iretd NEWSYM stopsbsound16 ; mov byte[Voice0Status],0 ; mov byte[Voice1Status],0 ; mov byte[Voice2Status],0 ; mov byte[Voice3Status],0 ; mov byte[Voice4Status],0 ; mov byte[Voice5Status],0 ; mov byte[Voice6Status],0 ; mov byte[Voice7Status],0 mov ax,ds mov es,ax mov edi,DSPBuffer mov ecx,[BufferSizeB] xor eax,eax rep stosd cmp byte[SBswitch],0 jne near .2ndblock ; clear block mov es,[sbselec] mov edi,[sbpmofs] mov ecx,[BufferSizeB] shr ecx,1 .loopa mov dword[es:edi],00000000h add edi,4 dec ecx jnz .loopa jmp .sbend .2ndblock ; copy to 2nd block ; clear memory mov es,[sbselec] mov edi,[sbpmofs] add edi,[BufferSizeW] mov ecx,[BufferSizeB] shr ecx,1 .loopb mov dword[es:edi],00000000h add edi,4 dec ecx jnz .loopb .sbend xor byte [SBswitch],1 ; acknowledge SB for IRQing mov dx,[SBPort] add dl,0Fh in al,dx mov al,20h out 20h,al cmp byte[SBIrq],7 jbe .nohighirq mov al,20h out 0A0h,al .nohighirq pop es pop esi pop edi pop edx pop ecx pop ebx pop eax pop ds sti iretd ;**************************************************** ; Sound Blaster Initialization Stuff ;**************************************************** section .bss ;ALIGN=32 NEWSYM memoryloc, resd 1 ; Memory offset in conventional memory NEWSYM memoryloc2, resd 1 ; Memory offset in conventional memory NEWSYM sbselec, resw 1 ; Selector of Memory location NEWSYM sbpmofs, resd 1 ; offset of Memory location SBDeinitType resb 1 section .text NEWSYM InitSB mov eax,[SoundQuality] cmp byte[StereoSound],1 jne .nostereobuf mov ax,[BufferSizes+eax*2] jmp .skipstereobuf .nostereobuf mov ax,[BufferSize+eax*2] .skipstereobuf mov [BufferSizeB],ax add ax,ax mov [BufferSizeW],ax mov byte [SBswitch],0 ; Allocate pointer ; Set up SB call SB_dsp_reset ; code added by peter santing cmp byte [vibracard], 1 je near .vibrafix2 cmp byte [SBHDMA],0 je .no16bit cmp byte [SBHDMA],4 jb near .init16bitlowhdma jmp .init16bit .no16bit ; Determine Version # mov al,0E1h call SB_dsp_write call SB_dsp_read mov [.Versionnum],al call SB_dsp_read mov [.Versionnum+1],al ; Turn on speakers mov al,0D1h call SB_dsp_write ; Set Time-Constant Data ( = 256 - (1000000/sampling rate) ) ; 8000=131, 22050=210, 44100=233, 11025=165 mov al,40h call SB_dsp_write ; cmp byte[Surround],0 ; jne .surround8b cmp byte[StereoSound],1 jne .nostereo8b .surround8b mov eax,[SoundQuality] cmp eax,2 jbe .okay mov eax,2 .okay mov al,byte [SoundSpeedt+eax] call SB_dsp_write ; Set Stereo mov dx, [SBPort] add dx, 04h mov al,0Eh out dx,al inc dx in al,dx or al,022h out dx,al jmp .donestereo .nostereo8b mov eax,[SoundQuality] mov al,byte [SoundSpeeds+eax] call SB_dsp_write .donestereo cmp byte[StereoSound],1 je .highmode mov eax,[SoundQuality] cmp byte [SoundSpeeds+eax],211 ja .highmode mov byte[.Versionnum],1 .highmode ; Setup DMA ; Select DMA channel mov al,[SBDMA] add al,4 mov dx,000Ah out dx,al ; Clear DMA mov al,00h mov dx,000Ch out dx,al ; Set autoinit/write (set as DAC) mov al,58h add al,[SBDMA] mov dx,000Bh out dx,al ; Send Offset Address mov al,[memoryloc] mov dl,[SBDMA] shl dl,1 out dx,al mov al,[memoryloc+1] out dx,al ; Send length of entire block mov ax,[BufferSizeW] dec ax inc dx out dx,al mov al,ah out dx,al ; Send page # (address/65536) mov al,[memoryloc+2] mov dl,[SBDMAPage] out dx,al ; turn on DMA mov al,[SBDMA] mov dx,000Ah out dx,al ; Prepare SB for the first block ; 8-bit auto-init, mono, unsigned mov al,048h ; Sb 2.0 version... call SB_dsp_write ; Send Length-1 to DSP port mov ax,[BufferSizeB] dec ax call SB_dsp_write mov al,ah call SB_dsp_write mov byte[SBDeinitType],1 mov al,090h ; Sb 2.0 version... cmp byte[.Versionnum],2 jne .noversion2 cmp byte[.Versionnum+1],0 je .slowspeed .noversion2 cmp byte[.Versionnum],1 ja .notversion1 .slowspeed mov byte[SBDeinitType],0 mov al,1Ch .notversion1 call SB_dsp_write jmp .fixsurround SECTION .bss ;ALIGN=32 .Versionnum resw 1 SECTION .text ; ***************************************** ; **** alternate ViBRA16X SB init code **** by Peter Santing ; ***************************************** copied portions of original code ; and modified it. .vibrafix2 ; notify user that we're in ViBRA16x mode.. push eax mov dword [Msgptr], vibmsg mov eax, [MsgCount] mov [MessageOn], eax pop eax ; Set Time-Constant Data ( = 256 - (1000000/sampling rate) ) ; 8000=131, 22050=210, 44100=233, 11025=165 ; Setup DMA ; Select DMA channel mov al,[SBDMA] add al,4 mov dx,000Ah out dx,al ; Clear DMA mov al,00h mov dx,000Ch out dx,al ; Set autoinit/write (set as DAC) mov al,58h add al,[SBDMA] mov dx,000Bh out dx,al ; Send Offset Address mov al,[memoryloc] mov dl,[SBDMA] shl dl,1 out dx,al mov al,[memoryloc+1] out dx,al ; Send length of entire block mov ax,[BufferSizeW] shl ax, 1 dec ax inc dx out dx,al mov al,ah out dx,al ; Send page # (address/65536) mov al,[memoryloc+2] mov dh, 0 mov dl,[SBDMAPage] out dx,al ; turn on DMA mov al,[SBDMA] mov dx,000Ah out dx,al mov al,41h call SB_dsp_write push ecx mov ecx,[SoundQuality] mov al,byte [SBToSPCSpeeds2+ecx*4+1] pop ecx call SB_dsp_write push ecx mov ecx,[SoundQuality] mov al,byte [SBToSPCSpeeds2+ecx*4] pop ecx call SB_dsp_write ; Prepare SB for the first block ; 16-bit auto-init, mono, unsigned mov al,0B6h ; Sb 16 version (DSP 4) call SB_dsp_write cmp byte[StereoSound],1 jne ._Mono ._surround mov al,30h ; stereo/signed call SB_dsp_write jmp ._AfterStereo ._Mono mov al,10h ; mono/signed call SB_dsp_write ._AfterStereo ; Send Length-1 to DSP port mov ax,[BufferSizeB] dec ax call SB_dsp_write mov al,ah call SB_dsp_write ; Turn on speakers mov al,0D1h call SB_dsp_write jmp .fixsurround ; ******* end of alternate SB init code for ViBRA ******** .init16bitlowhdma ; Set Time-Constant Data ( = 256 - (1000000/sampling rate) ) ; 8000=131, 22050=210, 44100=233, 11025=165 mov al,40h call SB_dsp_write push ecx mov ecx,[SoundQuality] mov al,byte [SoundSpeeds+ecx] pop ecx call SB_dsp_write mov edx,[memoryloc] shr edx,1 mov [memoryloc2],edx ; Setup DMA ; turn off DMA ; mov al,[SBHDMA] ; and al,03h ; or al,04h ; mov dx,00D4h ; out dx,al ; Setup DMA ; Select DMA channel mov al,[SBHDMA] and al,03h or al,04h mov dx,000Ah out dx,al ; clear flip-flop mov dx,00D8h xor al,al out dx,al ; Set autoinit/write (set as DAC) mov al,[SBHDMA] and al,3 add al,58h mov dx,00D6h out dx,al ; Send Offset Address ; mov al,[memoryloc2] ; mov dl,[SBHDMA] ; and dl,3 ; shl dl,2 ; add dl,0C0h ; out dx,al ; mov al,[memoryloc2+1] ; out dx,al ; Send Offset Address mov al,[memoryloc] mov dl,[SBDMA] shl dl,1 out dx,al mov al,[memoryloc+1] out dx,al ; Send length of entire block mov ax,[BufferSizeW] dec ax add dx,2 out dx,al mov al,ah out dx,al ; Send page # (address/65536) mov al,[memoryloc+2] mov dl,[SBHDMAPage] out dx,al ; Prepare SB for the first block ; 16-bit auto-init, mono, unsigned mov al,0B6h ; Sb 16 version (DSP 4) call SB_dsp_write ; cmp byte[Surround],0 ; jne .surroundl cmp byte[StereoSound],1 jne .Monol .surroundl mov al,30h ; stereo/signed call SB_dsp_write jmp .AfterStereol .Monol mov al,10h ; mono/signed call SB_dsp_write .AfterStereol ; Send Length-1 to DSP port mov ax,[BufferSizeB] dec ax call SB_dsp_write mov al,ah call SB_dsp_write ; turn on DMA ; mov al,[SBHDMA] ; and al,03h ; mov dx,00D4h ; out dx,al ; Setup DMA ; Select DMA channel mov al,[SBHDMA] and al,03h mov dx,000Ah out dx,al ; Turn on speakers mov al,0D1h call SB_dsp_write jmp .fixsurround .init16bit ; Set Time-Constant Data ( = 256 - (1000000/sampling rate) ) ; 8000=131, 22050=210, 44100=233, 11025=165 mov al,41h call SB_dsp_write push ecx mov ecx,[SoundQuality] mov al,byte [SBToSPCSpeeds2+ecx*4+1] pop ecx call SB_dsp_write push ecx mov ecx,[SoundQuality] mov al,byte [SBToSPCSpeeds2+ecx*4] pop ecx call SB_dsp_write mov edx,[memoryloc] shr edx,1 mov [memoryloc2],edx ; Setup DMA ; turn off DMA mov al,[SBHDMA] and al,03h or al,04h mov dx,00D4h out dx,al ; clear flip-flop mov dx,00D8h xor al,al out dx,al ; Set autoinit/write (set as DAC) mov al,[SBHDMA] and al,3 add al,58h mov dx,00D6h out dx,al ; Send Offset Address mov al,[memoryloc2] mov dl,[SBHDMA] and dl,3 shl dl,2 add dl,0C0h out dx,al mov al,[memoryloc2+1] out dx,al ; Send length of entire block mov ax,[BufferSizeW] dec ax add dx,2 out dx,al mov al,ah out dx,al ; Send page # (address/65536) mov al,[memoryloc+2] mov dl,[SBHDMAPage] and al,0FEh out dx,al ; Prepare SB for the first block ; 16-bit auto-init, mono, unsigned mov al,0B6h ; Sb 16 version (DSP 4) call SB_dsp_write ; cmp byte[Surround],0 ; jne .surround cmp byte[StereoSound],1 jne .Mono .surround mov al,30h ; stereo/signed call SB_dsp_write jmp .AfterStereo .Mono mov al,10h ; mono/signed call SB_dsp_write .AfterStereo ; Send Length-1 to DSP port mov ax,[BufferSizeB] dec ax call SB_dsp_write mov al,ah call SB_dsp_write ; Turn on speakers mov al,0D1h call SB_dsp_write ; turn on DMA mov al,[SBHDMA] and al,03h mov dx,00D4h out dx,al .fixsurround ; Adjust byte lengths for mono surround sound cmp byte[Surround],0 je .nosurroundadj cmp byte[StereoSound],0 jne .nosurroundadj ; shr word[BufferSizeB],1 ; shr word[BufferSizeW],1 .nosurroundadj ret GetCDMAPos: ; clear flipflop xor ebx,ebx mov bl,[SBDMA] cmp byte[SBHDMA],4 jb .nohdma mov bl,[SBHDMA] mov dx,0Ch .nohdma mov dx,0D8h xor al,al out dx,al nop nop nop nop mov dx,[.wordcountport+ebx*2] in al,dx nop nop mov bl,al in al,dx nop nop nop nop mov bh,al cmp byte[SBHDMA],4 jb .ldma2 add bx,bx .ldma2 ; value returned = bx, # of bytes left for transfer mov cx,[BufferSizeB] mov dx,cx add cx,cx cmp byte[SBHDMA],4 jb .ldmab add cx,cx add dx,dx .ldmab sub cx,bx mov byte[SBswitch],1 cmp cx,dx jb .parta mov byte[SBswitch],0 .parta ret SECTION .data .wordcountport dw 1,3,5,7,0C2h,0C6h,0CAh,0CEh SECTION .text ; old routines, doesn't work w/ sb live! jmp .fin .loop in al,dx nop nop mov cl,al in al,dx nop nop nop nop mov ch,al in al,dx nop nop mov bl,al in al,dx mov bh,al sub cx,bx test cx,8000h jz .notneg neg cx .notneg cmp byte[SBHDMA],4 jb .ldma add cx,cx add bx,bx .ldma cmp cx,4 ja .loop .fin NEWSYM SB_quality_limiter cmp byte[StereoSound],1 jne .nostereo8b cmp byte[SBHDMA],0 jne .nostereo8b ; ***************************************** ; *** ViBRA16X support by Peter Santing *** ; ***************************************** ; before REALLY switching back to 8-bit sucky mono mode ; check that we're dealing with a ViBRA16X Creative Labs Card cmp byte[vibracard], 1 je .nostereo8b cmp dword[SoundQuality],2 jbe .nostereo8b mov dword[SoundQuality],2 .nostereo8b ret NEWSYM SB_blank push es mov es,[sbselec] mov edi,[sbpmofs] mov ecx,320 .loopa mov dword[es:edi],0 add edi,4 dec ecx jnz .loopa pop es ret ;******************************************************* ; Get Blaster Locates SET BLASTER environment ;******************************************************* NEWSYM getblaster mov edx,.string2s push edx call getenv pop edx cmp eax,0 je near .nfound mov esi,eax mov byte[.cursetting],0 .a mov dl,[esi] cmp dl,'a' jb .nocap cmp dl,'z' ja .nocap sub dl,'a'-'A' .nocap inc esi mov byte[.blfound],1 cmp dl,'A' jne .afound mov byte[.cursetting],1 mov word[SBPort],0 jmp .src .afound cmp dl,'I' jne .ifound mov byte[.cursetting],2 mov byte[SBIrq],0 jmp .src .ifound cmp dl,'D' jne .dfound mov byte[.cursetting],3 mov byte[SBDMA],0 jmp .src .dfound cmp dl,'H' jne .hfound mov byte[.cursetting],4 mov byte[SBHDMA],0 jmp .src .hfound cmp dl,' ' je .src2 cmp dl,0 je .src2 jmp .src3 .src2 mov byte[.cursetting],0 jmp .src .src3 cmp byte[.cursetting],1 jne .nproca shl word[SBPort],4 sub dl,48 add byte[SBPort],dl add dl,48 .nproca cmp byte[.cursetting],2 jne .nproci cmp byte[SBIrq],1 jne .no1 mov byte[SBIrq],10 .no1 sub dl,48 add [SBIrq],dl add dl,48 .nproci cmp byte[.cursetting],3 jne .nprocd sub dl,48 mov [SBDMA],dl add dl,48 .nprocd cmp byte[.cursetting],4 jne .nproch sub dl,48 mov [SBHDMA],dl add dl,48 .nproch .src cmp dl,0 jne near .a cmp byte[.blfound],0 je near .nfound cmp byte[SBIrq],2 jne .noirq9 mov byte[SBIrq],9 .noirq9 mov al,[SBIrq] add al,08h cmp byte[SBIrq],7 jbe .nohighirq add al,60h add byte[PICRotateP],80h add byte[PICMaskP],80h .nohighirq mov [SBInt],al cmp byte[SBDMA],0 jne .dma0 mov byte[SBDMAPage],87h .dma0 cmp byte[SBDMA],1 jne .dma1 mov byte[SBDMAPage],83h .dma1 cmp byte[SBDMA],2 jne .dma2 mov byte[SBDMAPage],81h .dma2 cmp byte[SBDMA],3 jne .dma3 mov byte[SBDMAPage],82h .dma3 ; ****************************************************** ; **** this piece of code is added by Peter Santing **** ; **** it will enable ZSNES to use the full STEREO **** ; **** capability of the ViBRA16X line of creative **** ; **** instead of playing 8-bit MONOURAL sound **** ; ****************************************************** ; cmp byte [SBHDMA], 0 ; jne .vibradma0 ; mov byte [SBDMAPage], 87h ; mov byte [vibracard], 1 ; set ViBRA16X mode .vibradma0 cmp byte [SBHDMA], 1 jne .vibradma1 mov byte [SBDMAPage], 83h mov byte [vibracard], 1 ; set ViBRA16X mode .vibradma1 cmp byte [SBHDMA], 2 jne .vibradma2 mov byte [SBDMAPage], 81h mov byte [vibracard], 1 ; set ViBRA16X mode .vibradma2 cmp byte [SBHDMA], 3 jne .vibradma3 mov byte [SBDMAPage], 82h mov byte [vibracard], 1 ; set ViBRA16X mode .vibradma3 cmp byte [vibracard], 1 jne .vibrafix push ax mov al, [SBHDMA] mov [SBDMA], al pop ax .vibrafix cmp byte [SBHDMA],4 jae .hdma ; vibra implementation (make sure that zSNES doesn't go back ; to eight-bit-mode mono) mov byte [SBHDMA],0 cmp byte[vibracard], 1 jne .hdma push edx mov edx, vibradetect call PrintStr ;call WaitForKey pop edx ; ********** END OF ViBRA16X implementation code ********** .hdma cmp byte[SBHDMA],4 jne .hdma4 mov byte[SBHDMAPage],8Fh .hdma4 cmp byte[SBHDMA],5 jne .hdma5 mov byte[SBHDMAPage],8Bh .hdma5 cmp byte[SBHDMA],6 jne .hdma6 mov byte[SBHDMAPage],89h .hdma6 cmp byte[SBHDMA],7 jne .hdma7 mov byte[SBHDMAPage],8Ah .hdma7 cmp byte[DisplayS],1 je .displaysoundstuff ret .nfound cmp byte[soundon],0 je .nosound mov byte[soundon],0 mov edx, .blasterstr call PrintStr call WaitForKey .nosound ret .displaysoundstuff mov edx,.blasterinfo call PrintStr xor eax,eax mov ax,[SBPort] call printhex mov edx,.blinfob call PrintStr xor eax,eax mov al,[SBIrq] call printnum mov edx,.blinfoc call PrintStr xor eax,eax mov al,[SBDMA] call printnum mov edx,.blinfod call PrintStr xor eax,eax mov al,[SBHDMA] call printnum mov edx,.blasterstr2b call PrintStr call WaitForKey ret SECTION .bss .blfound resb 1 .cursetting resb 1 SECTION .data .string2s db 'BLASTER',0 .blasterstr db 'ERROR : SET BLASTER environment NOT found!',10,13 .blasterstr2 db 'Unable to enable sound.' .blasterstr2b db 10,13,10,13 .blasterstr3 db 'Press any key to continue.',0 .blasterinfo db 'Sound Blaster Detection Values : ',10,13,10,13 .blinfoa db 'PORT : ',0 .blinfob db 13,10,'IRQ : ',0 .blinfoc db 13,10,'DMA : ',0 .blinfod db 13,10,'HDMA : ',0 NEWSYM PICRotateP, db 20h NEWSYM PICMaskP, db 21h ; Line added by Peter Santing NEWSYM vibradetect db 'Creative ViBRA16X PnP card detected (support coded by Peter Santing)', 13, 10 db 'High-DMA is below dma #4', 13, 10 db 13,10, 'you have now full 16-bit stereo sound with the surround option!', 13, 10, 0