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 + -
显示快捷键?