dspproc.asm

来自「十七种模拟器源代码 非常有用的作课程设计不可缺少的」· 汇编 代码 · 共 1,816 行 · 第 1/5 页

ASM
1,816
字号
      mov dword [opcjmptab+0358h],OpD6
      mov dword [opcjmptab+035Ch],OpD7
      mov dword [opcjmptab+0360h],OpD8
      mov dword [opcjmptab+0364h],OpD9
      mov dword [opcjmptab+0368h],OpDA
      mov dword [opcjmptab+036Ch],OpDB
      mov dword [opcjmptab+0370h],OpDC
      mov dword [opcjmptab+0374h],OpDD
      mov dword [opcjmptab+0378h],OpDE
      mov dword [opcjmptab+037Ch],OpDF
      mov dword [opcjmptab+0380h],OpE0
      mov dword [opcjmptab+0384h],OpE1
      mov dword [opcjmptab+0388h],OpE2
      mov dword [opcjmptab+038Ch],OpE3
      mov dword [opcjmptab+0390h],OpE4
      mov dword [opcjmptab+0394h],OpE5
      mov dword [opcjmptab+0398h],OpE6
      mov dword [opcjmptab+039Ch],OpE7
      mov dword [opcjmptab+03A0h],OpE8
      mov dword [opcjmptab+03A4h],OpE9
      mov dword [opcjmptab+03A8h],OpEA
      mov dword [opcjmptab+03ACh],OpEB
      mov dword [opcjmptab+03B0h],OpEC
      mov dword [opcjmptab+03B4h],OpED
      mov dword [opcjmptab+03B8h],OpEE
      mov dword [opcjmptab+03BCh],OpEF
      mov dword [opcjmptab+03C0h],OpF0
      mov dword [opcjmptab+03C4h],OpF1
      mov dword [opcjmptab+03C8h],OpF2
      mov dword [opcjmptab+03CCh],OpF3
      mov dword [opcjmptab+03D0h],OpF4
      mov dword [opcjmptab+03D4h],OpF5
      mov dword [opcjmptab+03D8h],OpF6
      mov dword [opcjmptab+03DCh],OpF7
      mov dword [opcjmptab+03E0h],OpF8
      mov dword [opcjmptab+03E4h],OpF9
      mov dword [opcjmptab+03E8h],OpFA
      mov dword [opcjmptab+03ECh],OpFB
      mov dword [opcjmptab+03F0h],OpFC
      mov dword [opcjmptab+03F4h],OpFD
      mov dword [opcjmptab+03F8h],OpFE
      mov dword [opcjmptab+03FCh],OpFF
;    cmp byte[soundon],0
;    je near .nosound
;    cmp byte[OSPort],2
;    jae near .nosound
%ifdef __MSDOS__
    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
%endif
.nosound
    pop edx
    pop ecx
    pop ebx
    pop eax
    ret
%ifdef __MSDOS__
.error
    mov edx,.nohand         ;use extended
    mov ah,9                ;DOS- API
    int 21h                 ;to print a string
    call DosExit

.nohand db 'Unable to allocate conventional memory!',13,10,'$'
%endif

NEWSYM InitSB
%ifdef __MSDOS__
    call initSB
%endif
    ret

NEWSYM DeInitSPC
    cmp byte[SBDeinitType],0
    je .nodoublereset
    call ResetSBDSP
    call ResetSBDSP
.nodoublereset
    ; Turn off speakers
    mov al,0d3h
    call WriteDSP

;      k) Perform Halt DMA Operation, 8-bit command (0D0h - for virtual speaker)
    mov al,0d0h
    call WriteDSP
;      l) Perform Exit Auto-Initialize DMA Operation, 8-bit command (0DAh)
    cmp byte[SBHDMA],0
    je .8b
    mov al,0d9h
    call WriteDSP
    jmp .16b
.8b
    mov al,0dAh
    call WriteDSP
.16b
;      m) Perform Halt DMA Operation, 8-bit command (0D0h - for virtual speaker)
    mov al,0d0h
    call WriteDSP
    ; Disable DMA
    mov al,4
    add al,[SBDMA]
    mov dx,0ah
    out dx,al
    ret

;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

; 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

NEWSYM ResetSBDSP
    mov dx,[SBPort]
    add dl,06h
    mov al,01h
    out dx,al
    nop
    nop
    nop
    nop
    nop
    nop
    mov al,00h
    out dx,al
    ; wait until port[SBDSPRdStat] AND 80h = 80h
    mov cx,20000
.tryagain
    mov dx,[SBPort]
    add dl,0Eh
    dec cx
    jz .cardfailed
    in al,dx
    test al,80h
    jz .tryagain
.tryagain2
    mov dx,[SBPort]
    add dl,0Ah
    dec cx
    jz .cardfailed
    in al,dx
    cmp al,0AAh
    jne .tryagain
    ret
.cardfailed
    mov ax,0003h
    int 10h
    mov edx,initfailed      ;use extended
    mov ah,9                ;DOS- API
    int 21h                 ;to print a string
    jmp DosExit

NEWSYM initfailed, db 'Sound card failed to initialize!',13,10,'$'

; Write AL into DSP port
NEWSYM WriteDSP
    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 ReadDSP
    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

.nohand db 'Cannot process interrupt handler!',13,10,'$'

NEWSYM oldhandSBs, dw 0
NEWSYM oldhandSBo, dd 0
NEWSYM SBswitch,   db 0         ; which block to process next

PSampleBuf times 22*8 dd 0

NEWSYM LPFsample1, dd 0
NEWSYM LPFsample2, dd 0

%macro ProcessA 0
    shr al,4
%endmacro

%macro ProcessB 0
    and al,0Fh
%endmacro

%macro ProcessSample 1
    xor eax,eax
    mov cl,[bshift]
    mov al,[esi]
    %1
    test al,08h
    jz %%noneg
    or eax,0FFFFFFF0h
%%noneg
    shl eax,cl
    mov edx,eax

    mov eax,[prev1]
    mov ebx,[filter1]
    imul eax,ebx
    sar eax,8
    add edx,eax

    mov eax,[prev0]
    mov ebx,[filter0]
    imul eax,ebx
    sar eax,8
    add edx,eax

    mov eax,[prev0]
    mov [prev0],edx
    mov [prev1],eax
    cmp edx,-32768
    jnl %%notless
    mov edx,-32768
    mov byte[filteron],1
%%notless
    cmp edx,32767
    jng %%notgreater
    mov edx,32767
    mov byte[filteron],1
%%notgreater
%endmacro

NEWSYM lastblockbrr, times 8 dd 0
NEWSYM curvoice, dd 0

BRRDecode:
    mov [curvoice],ecx
    mov byte[lastbl],0
    mov byte[loopbl],0
    cmp dword[esi],21FECD8Ah
    jne .notophack
    mov byte[VoiceNoiseEn+ecx],0
.notophack
    push ecx
    mov al,[esi]
    and al,0Ch
    cmp al,04h
    je .yesfilterb
    test al,0Ch
    jnz .skipfilter
    cmp byte[esi+9],88h
    jne .yesfilterb
    mov byte[VoiceNoiseEn+ecx],101
    jmp .skipfilter
.yesfilterb
    mov byte[VoiceNoiseEn+ecx],100
.skipfilter

    xor eax,eax
    mov al,[esi]
    test al,01h
    jz .nolast
    mov byte[lastbl],1
    test al,02h
    jz .nolast
    mov byte[loopbl],1
.nolast
    mov cl,al
    and al,0Ch
    inc esi
    mov ebx,[Filter+eax*2]
    shr cl,4
    mov [filter0],ebx
    mov ebx,[Filter+eax*2+4]
    push eax
    cmp cl,12
    jbe .noprevblock
    mov eax,[curvoice]
    mov cl,[lastblockbrr+eax]
.noprevblock
    mov [bshift],cl
    mov eax,[curvoice]
    mov [lastblockbrr+eax],cl
    pop eax
    mov [bshift],cl
    mov [filter1],ebx
    mov byte[sampleleft],8
    mov byte[filteron],0

.nextsample
    ProcessSample ProcessA
    mov [edi],dx
    ProcessSample ProcessB
    mov [edi+2],dx
    add edi,4
    inc esi
    dec byte[sampleleft]
    jnz near .nextsample

    po

⌨️ 快捷键说明

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