flat assembler
Message board for the users of flat assembler.
Index
> DOS > DOS WAV player (infos recovered from troll thread) |
Author |
|
DOS386 30 Dec 2008, 23:23
1. http://asmsource.8k.com/source16.htm
2. (seems to be MASM , heh) Code: ;************************************************************************** ;************************************************************************** ; PLAYWAV.ASM ; .WAV player on PC-speaker Just 761 bytes! ; ; (c) 1995 White Falcon Software House and Sapikli TM. ; ; You can use it or modify as you wish; just gimme the credits! ;************************************************************************** ;************************************************************************** .286c psp_start equ 80h CR equ 0Dh LF equ 0Ah speed_div equ 12 code segment byte public assume cs:code, ds:code org 100h playwav proc far ;************************************************************************** ; Main Program ;************************************************************************** start: call Init mov si,psp_start xor cx,cx mov cl,cs:[si] or cl,cl jnz PW1 jmp PW8 PW1: add cx,si inc si inc si PW2: or word ptr cs:[si],2020h ; ' ' cmp byte ptr cs:[si],2Fh ; '/' jz PW5 cmp byte ptr cs:[si],20h ; ' ' jz PW5 mov name_addr,si PW3: inc si cmp byte ptr [si],20h ; ' ' jz PW4 cmp si,cx jg PW4 jmp short PW3 PW4: mov byte ptr [si],0 mov param_yes,1 jmp PW7 PW5: cmp word ptr cs:[si],732Fh ; '/s' jnz PW6 mov param_yes,1 add si,3 call ASCII2Bin mov speed,dx jmp PW7 PW6: cmp word ptr cs:[si],762Fh ; '/v' jnz PW7 mov param_yes,1 add si,3 call ASCII2Bin mov volume,dx PW7: inc si cmp si,cx jge PW8 jmp PW2 PW8: cmp param_yes,1 jz PW10 lea dx,msg_main mov ah,9 int 21h int 20h PW9: jmp PW13 PW10: mov dx,name_addr mov ax,3D00h int 21h jc PW9 mov bx,ax lea dx,puffer mov cx,0EA60h mov ah,3Fh int 21h jc PW9 mov file_len,ax mov ah,3Eh int 21h lea di,puffer mov cx,file_len cld cikl2: xor ax,ax ; Conversion mov al,[di] sub ax,80h imul volume idiv volume_u cmp ax,7Fh jle PW11 mov ax,7Fh PW11: cmp ax,0FF80h jge PW12 mov ax,0FF80h PW12: add ax,80h div vol_div mov ah,al shl al,1 add al,ah inc ax stosb loop cikl2 call PlayIt int 20h PW13: lea dx,msg_fileerr mov ah,9 int 21h int 20h param_yes db 0 ; Shows if there's any parameter given speed dw 0 speed_u dw 64h ; Speed unit = 100 volume dw 5 ; Maximum volume: 10 volume_u dw 2 vol_div db 10h data_2 db 0 name_addr dw 149h ; Offset of the filename to be loaded file_len dw 0 ; Length of the .WAV file msg_fileerr db 'File error: can''t read file', CR, LF, '$' msg_main db CR, LF,' Usage: PLAYWAV [FILENAME] [OPTIONS]' db CR, LF db CR, LF,' OPTIONS:' db CR, LF,' /S:n Speed selection [500]' db CR, LF,' /V:n Volume. Range for n is 1-10. [5]' db CR, LF, '$' playwav endp ;************************************************************************** ; PlayIt: Plays the sound ;************************************************************************** PlayIt proc near pusha push cs pop ds cli mov al,90h out 43h,al in al,61h or al,3 ; Speaker data enable ; Timer2 to speaker enable out 61h,al lea bx,puffer add bx,2Ch mov cx,file_len mov al,[bx] PI1: out 42h,al push cx mov cx,speed cikl1: loop cikl1 pop cx mov al,[bx] dec data_2 jnz PI2 mov data_2,2 jmp short PI1 PI2: inc bx loop PI1 in al,61h and al,0FDh ; Disable speaker out 61h,al sti popa ret PlayIt endp ;************************************************************************** ; ASCII2Bin: Calculates the numeric value of a string located on [si] ; Returns number in DX. ;************************************************************************** ASCII2Bin proc near push ax push cx xor dx,dx A2B1: mov al,[si] sub al,30h ; '0' jl A2B2 cmp al,9 jg A2B2 cbw push ax mov ax,dx mov cx,0Ah mul cx mov dx,ax pop ax add dx,ax inc si jmp short A2B1 A2B2: pop cx pop ax ret ASCII2Bin endp ; Local variables for the speed-calculating timer_lo dw 0 timer_hi dw 0 count_lo dw 0 count_hi dw 0 ctr_addr equ 046Ch ; Address of timer tick counter in BIOS table calc_lo dw 0 calc_hi dw 0 ;************************************************************************** ; Init: Initializes global variables, counts speed ;************************************************************************** Init proc near push es push 0 pop es mov bx,ctr_addr mov ax,es:[bx] mov dx,es:[bx+2] mov timer_lo,ax mov timer_hi,dx init_1: mov ax,timer_lo mov dx,timer_hi cmp es:[bx],ax ; Wait for a new timer tick jnz init_2 cmp es:[bx+2],dx jz init_1 init_2: mov ax,es:[bx] mov dx,es:[bx+2] mov timer_lo,ax mov timer_hi,dx mov dx,timer_hi in al,61h init_3: inc word ptr count_lo ; Count port writes in silence adc count_hi,0 mov ah,al out 61h,al mov cx,9 cikl3: loop cikl3 ; Wait a few to simulate other operations mov cx,timer_lo cmp es:[bx],cx jz init_3 ; Repeat until a new timer tick mov dx,count_hi mov ax,count_lo mov cx,7 div cx mov calc_lo,ax mov calc_hi,dx add ax,5 xor dx,dx mov cx,speed_div div cx sub ax,8 mov speed,ax call DetectProc cmp ax,486h jnz init_4 mov ax,speed mov cx,0Dh mul cx mov cx,0Ah div cx mov speed,ax init_4: pop es ret Init endp ;************************************************************************** ; DetectProc: returns the processor type in AX (BCD coded) e.g. 0286h ;************************************************************************** DetectProc proc near pushf push bx push cx pushf pop ax and ax,0FFFh push ax popf pushf pop ax and ax,0F000h cmp ax,0F000h jnz DP_1 mov ax,86h jmp short DP_4 DP_1: or ax,0F000h push ax popf pushf pop ax and ax,0F000h jnz DP_2 mov ax,286h jmp short DP_4 DP_2: mov bx,sp and sp,0FFFCh ; This instructions must be complied this way 'cause if you set processor ; type to 386 or higher for these few bytes, you must use 32 bit linking. db 66h, 9Ch ; pushfd db 66h, 58h ; pop eax db 66h, 8Bh, 0C8h ; mov ecx,eax db 66h, 35h, 0, 0, 4, 0 ; xor eax,00040000h db 66h, 50h ; push eax db 66h, 9Dh ; popfd db 66h, 9Ch ; pushfd db 66h, 58h ; pop eax mov sp,bx db 66h, 33h, 0C1h ; xor eax,ecx jnz DP_3 mov ax,386h jmp DP_4 DP_3: mov ax,486h DP_4: pop cx pop bx popf ret DetectProc endp puffer equ this byte code ends end start 3. http://www.frontiernet.net/~fys/playwav.htm 4. http://www.o-bizz.de/qbdown/qbsound/speaker.zip (Quak-BASIC, but works well, and easy to port, "PC" speaker) 5. Code: ; assemble with NBASM 00.24.94 or above ; ( http://www.frontiernet.net/~fys/newbasic.htm ) ; ; NBASM playwav ; Converted to FASM by Dex PgPort equ 83h AddPort equ 02h LenPort equ 03h ModeReg equ 49h Channel equ 01h BasePort equ 220h Freq equ 11000 org 100h start: push cs ; make sure ds=es=cs push cs ; pop ds ; pop es ; mov dx,StartIt mov ah,09 int 21h mov di,Buffer ; clear buffer contents mov cx,51200 ; xor al,al ; rep ; stosb ; mov ax,3D00h ; open file mov dx,File1 ; int 21h ; jnc File1OK ; if no error then cont. mov dx,FileErr ; else print error msg and exit mov ah,09 ; int 21h ; jmp Done ; File1OK: mov bx,ax ; put handle in bx mov cx,43 ; read it mov dx,Buffer ; save into buffer mov ah,3Fh ; int 21h ; mov cx,51200 ; read it mov dx,Buffer ; save into buffer mov ah,3Fh ; int 21h ; mov [Length1],ax ; save len of file mov ah,3Eh ; close the file int 21h ; call ResetDSP or ax,ax jz RstOK mov dx,ResetErrS jmp RstOK1 RstOK: mov dx,ResetOKS mov ah,09 int 21h mov al,0DDh ; Left = 13, Right = 13 (15-highest) call MstrVol ; L = Hi Nibble, R = Lo Nibble mov al,0D1h ; turn speaker(s) on call WriteDSP xor eax,eax xor edx,edx mov ax,cs mov dx,Buffer shl eax,04h add eax,edx mov [MemLoc],eax call DMAPlay mov dx,AnyKey mov ah,09 int 21h xor ah,ah int 16h Done: mov ah,4Ch ; exit to DOS int 21h ; RstOK1: mov ah,09 int 21h jmp Done DMAPlay: ;uses eax ebx edx dec word [Length1] mov byte [Page1],00h mov al,(Channel+4) mov dx,0Ah out dx,al xor al,al mov dx,0Ch out dx,al mov al,ModeReg mov dx,0Bh out dx,al mov eax,[MemLoc] mov dx,AddPort out dx,al xchg al,ah out dx,al mov eax,[MemLoc] mov edx,eax and eax,65536 jz MemLocN1 inc byte [Page1] MemLocN1: mov eax,edx and eax,131072 jz MemLocN2 add byte [Page1],02 MemLocN2: mov eax,edx and eax,262144 jz MemLocN3 add byte [Page1],04 MemLocN3: mov eax,edx and eax,524288 jz MemLocN4 add byte [Page1],08 MemLocN4: mov dx,PgPort mov al,[Page1] out dx,al mov dx,LenPort mov ax,[Length1] out dx,al xchg al,ah out dx,al mov dx,0Ah mov al,Channel out dx,al mov al,40h call WriteDSP xor edx,edx mov eax,1000000 mov ebx,Freq div ebx mov ebx,eax mov eax,256 sub eax,ebx call WriteDSP mov al,14h call WriteDSP mov ax,[Length1] call WriteDSP xchg al,ah call WriteDSP ret MstrVol: ;uses ax dx push ax mov dx,(BasePort+4) mov al,22h out dx,al pop ax inc dx out dx,al ret ResetDSP: ; uses cx dx mov dx,(BasePort+6) mov al,01 out dx,al mov cx,50 WaitIt1: in al,dx loop WaitIt1 xor al,al out dx,al mov cx,50 WaitIt2: in al,dx loop WaitIt2 mov ah,0FFh ; part of Return Code mov dx,(BasePort+14) ; Japheth fix error, originally 6 in al,dx and al,80h cmp al,80h jne ResetErr mov dx,(BasePort+10) in al,dx cmp al,0AAh jne ResetErr ResetOK: xor ax,ax ; return ax = 0 if reset ok ResetErr: ret WriteDSP: ;uses ax dx push ax mov dx,(BasePort+12) WaitIt: in al,dx and al,80h jnz WaitIt pop ax out dx,al ret StartIt db 13,10,'PlayWav A utility for Playing WAV files Version 1.03' db 13,10,'Forever Young Software(r) (C)opyright 1984-2007',13,10,36 File1 db 'test.wav',0 FileErr db 13,10,'Error opening file...',36 ResetOKS db 13,10,'Reset DSP was successful.',36 ResetErrS db 13,10,'Error Reseting DSP...',36 AnyKey db 13,10,'Press a key to exit.',36 Length1 dw 00h MemLoc dd 0000h Page1 db 00h Buffer rb 51200 ; 50k buffer at the end of our code Quote: IMO the ResetDSP proc may have an error. The second "mov dx,(Baseport+6)" should be "mov dx,(Baseport+14)" to make the program read the SB status register. Reading the SB "reset" register is nonsense. Quote: To reset DSP you should do the following: WARNING: most of the codes do address ISA SB sound cards and won't work with PCI cards |
|||
30 Dec 2008, 23:23 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.