⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sound.asm

📁 linux下的任天堂模拟器代码。供大家参考。
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;Copyright (C) 1997-2007 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach );;http://www.zsnes.com;http://sourceforge.net/projects/zsnes;https://zsnes.bountysource.com;;This program is free software; you can redistribute it and/or;modify it under the terms of the GNU General Public License;version 2 as published by the Free Software Foundation.;;This program is distributed in the hope that it will be useful,;but WITHOUT ANY WARRANTY; without even the implied warranty of;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;GNU General Public License for more details.;;You should have received a copy of the GNU General Public License;along with this program; if not, write to the Free Software;Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.%include "macros.mac"EXTSYM ProcessSoundBuffer,DosExit,getenv,PrintStr,printhex,WaitForKeyEXTSYM SBHDMA,soundon,csounddisable,DisplayS,SPCRAM,DSPMemEXTSYM StereoSound,SoundQuality,SoundSpeeds,SBToSPCSpeeds2EXTSYM SoundSpeedt,DSPBuffer,BufferSize,BufferSizes,BufferSizeBEXTSYM BufferSizeW,dssel,PrintCharSECTION .textprintnum:    ; process through each digit    push edx    push eax    push ebx    push cx    xor edx,edx           ; clear high byte    xor cx,cx             ; clear counter variable    mov ebx,10.loopa    div ebx              ; get quotent and remainder    push edx              ; store number to stack    inc cl    xor edx,edx    test eax,0FFFFFFFFh    jnz .loopa.loopb    pop edx              ; get number back from stack    add dl,30h          ; adjust to ASCII value    call PrintChar    dec cl    jnz .loopb    pop cx    pop ebx    pop eax    pop edx    retNEWSYM 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 DosExitSECTION .data.nohand db 'Unable to allocate conventional memory!',13,10,'$'SECTION .textNEWSYM 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    retsection .data;SoundBlaster DSP PortsNEWSYM SBPort, dw 220NEWSYM SBInt,  db 5+8NEWSYM SBIrq,  db 5NEWSYM SBDMA,  db 1NEWSYM SBDMAPage, db 83;NEWSYM SBHDMA, db 0NEWSYM SBHDMAPage, db 0NEWSYM vibracard, db 0NEWSYM SBBufferLoc,    dd 0NEWSYM SBBufferMov,    dd 0NEWSYM SBBufferInc,    dd 0NEWSYM SoundInterrupt, dd 0; ViBRA16X fixes!EXTSYM MsgCount         ; points to counterEXTSYM MessageOn        ; points to "message" delay counterEXTSYM Msgptr           ; points to the message to be displayedNEWSYM vibmsg, db 'VIBRA16X MODE ENABLED', 0section .textNEWSYM 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 DosExitsection .dataNEWSYM initfailed, db 'Sound card failed to initialize!',13,10,'$'section .text; Write AL into DSP portNEWSYM 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 ALNEWSYM 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 DosExitsection .data.nohand db 'Cannot process interrupt handler!',13,10,'$'section .bssNEWSYM oldhandSBs, resw 1NEWSYM oldhandSBo, resd 1NEWSYM SBswitch,   resb 1         ; which block to process nextsection .textNEWSYM SBHandler    cli    push ds    push eaxNEWSYM 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].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.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 StartprocsbdataNEWSYM 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    iretdsection .bssNEWSYM sbhandexec, resd 1section .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].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.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    stiStartprocsbdata:    push ebp    call ProcessSoundBuffer    pop ebp    pop es    pop esi    pop edi    pop edx    pop ecx    pop ebx    pop eax    pop ds    iretdNEWSYM 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 .bssNEWSYM memoryloc, resd 1        ; Memory offset in conventional memoryNEWSYM memoryloc2, resd 1       ; Memory offset in conventional memoryNEWSYM sbselec,   resw 1        ; Selector of Memory locationNEWSYM sbpmofs,   resd 1        ; offset of Memory locationSBDeinitType resb 1section .textNEWSYM 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[StereoSound],1    jne .nostereo8b.surround8b    mov eax,[SoundQuality]    cmp eax,4    je .okay    cmp eax,2    jbe .okay    mov eax,2.okay    mov al,[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,[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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -