forked from KolibriOS/kolibrios
d3ae4b4e07
@rcher, ac97wav, midamp, rtfread: modified to use function 70 git-svn-id: svn://kolibrios.org@139 a494cfbc-eb01-0410-851d-a64ba20cac60
1103 lines
24 KiB
NASM
1103 lines
24 KiB
NASM
;---------------------------------------------------------------------
|
|
;
|
|
; MenuetOS AC97 WAV Player
|
|
;
|
|
; 0.03 November 10, 2004 doesn't halt if file not found
|
|
; 0.04 November 11, 2004 better positioning (with mouse)
|
|
; 0.05 November 14, 2004 internals clean up
|
|
; fixed cutting sound at the edges
|
|
; 0.06 November 17, 2004 fixed many bugs
|
|
; 0.07 Nov 20, 2004 deactivates text box when 'play' pressed
|
|
; stops playing before closing a window
|
|
; 0.08 Nov 24, 2004 added support for 8bit and mono modes
|
|
; +variable rate for some chipsets
|
|
; 0.09 August 26, 2006 modified to use function 70
|
|
;
|
|
; Use [flat assembler 1.64] to compile.
|
|
;
|
|
;---------------------------------------------------------------------
|
|
|
|
use32 ; turn on 32 bit mode
|
|
org 0x0 ; the program is placed at 0 offset
|
|
|
|
db 'MENUET01' ; 8-byte identifier of MenuetOS application
|
|
dd 0x01 ; header version (always 1)
|
|
dd START ; address of the beginning of the code
|
|
dd IMAGE_END ; size of the program's image
|
|
dd MEMORY_END ; how much memory does it need
|
|
dd STACK_P ; a pointer to the top of the stack
|
|
dd textbox_string
|
|
; dd 0x0 ; address of buffer for parameters (not used)
|
|
dd 0x0 ; reserved
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
include "macros.inc" ; standart macros & constants
|
|
include "meosfunc.inc" ; MenuetOS API functions names
|
|
include "debug.inc" ; printing to debug board
|
|
include "constant.inc" ; BIT?? constants
|
|
include "ac97.inc" ; AC'97 constants
|
|
include "pci.inc" ; PCI interface
|
|
include "codec.inc" ; functions for configuring codec
|
|
include "frontend.inc" ; main window
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
; Uncomment these strings if you don't want to receive debug messages:
|
|
|
|
; macro dps str {} ; dps prints a string without CRLF
|
|
; macro dpd num {} ; prints unsigned decimal number
|
|
; macro pregs {} ; outputs EAX, EBX, ECX, EDX
|
|
; macro newline {} ; CRLF
|
|
; macro print str {} ; output a string with CRLF
|
|
; macro dph arg {} ; print hex number
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
;macro device id, addr { dd id, addr }
|
|
macro devices [id, str]
|
|
{
|
|
common
|
|
label supported_devices dword
|
|
forward
|
|
local string
|
|
dd id
|
|
dd string
|
|
forward
|
|
string db str
|
|
db 0
|
|
}
|
|
|
|
|
|
devices \
|
|
(ICH_DID shl 16) + INTEL_VID, "ICH" ,\
|
|
(ICH0_DID shl 16) + INTEL_VID, "ICH0" ,\
|
|
(ICH2_DID shl 16) + INTEL_VID, "ICH2" ,\
|
|
(ICH3_DID shl 16) + INTEL_VID, "ICH2" ,\
|
|
(ICH4_DID shl 16) + INTEL_VID, "ICH4" ,\
|
|
(ICH5_DID shl 16) + INTEL_VID, "ICH5" ,\
|
|
(MX440_DID shl 16) + INTEL_VID, "440MX" ,\
|
|
(SI7012_DID shl 16) + SIS_VID, "SI7012" ,\
|
|
(NFORCE_DID shl 16) + NVIDIA_VID, "NForce" ,\
|
|
(NFORCE2_DID shl 16) + NVIDIA_VID, "NForce2",\
|
|
(AMD8111_DID shl 16) + AMD_VID, "AMD8111",\
|
|
(AMD768_DID shl 16) + AMD_VID, "AMD768"
|
|
dd 0
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
;--- MAIN PROGRAM --------------------------------------------------
|
|
;---------------------------------------------------------------------
|
|
|
|
START:
|
|
|
|
; Print PCI version (for example, 2.16)
|
|
; mcall MF_PCI, 0
|
|
; mov bl, al
|
|
; movzx eax, ah
|
|
; dps "PCI version: "
|
|
; dpd eax
|
|
; movzx eax, bl
|
|
; dpd eax
|
|
; newline
|
|
|
|
; Check PCI access mechanism (must be 1 or 2)
|
|
mcall MF_PCI, 2
|
|
dec al
|
|
cmp al, 1
|
|
jna @f
|
|
print "Error: cannot access PCI bus."
|
|
jmp exit
|
|
; dps "PCI returned "
|
|
; movzx eax, al
|
|
; dpd eax
|
|
; newline
|
|
@@:
|
|
|
|
|
|
; Get last bus & then check all buses & devices
|
|
mcall MF_PCI, 1
|
|
mov [lastbus], al
|
|
|
|
; looking for a compatible device
|
|
mov [bus], -1
|
|
.next_bus:
|
|
inc [bus]
|
|
|
|
mov al, [lastbus]
|
|
cmp al, [bus]
|
|
jb .device_not_found
|
|
|
|
mov [devfn], 0
|
|
.next_devfn:
|
|
|
|
mov cl, 0
|
|
call pciRegRead32
|
|
|
|
mov edi, supported_devices
|
|
@@:
|
|
mov ebx, [edi]
|
|
test ebx, ebx
|
|
jz @f
|
|
cmp eax, ebx
|
|
jnz .skip
|
|
add edi, 4
|
|
mov [device_id], eax
|
|
mov edx, [edi]
|
|
call debug_outstr
|
|
jmp proceed
|
|
.skip:
|
|
add edi, 8
|
|
jmp @b
|
|
@@:
|
|
|
|
inc [devfn]
|
|
cmp [devfn], 255
|
|
jb .next_devfn
|
|
|
|
jmp .next_bus
|
|
|
|
|
|
.device_not_found:
|
|
print "Could not find Intel AC'97 compatible codec!"
|
|
print "1) Check if it's enabled in BIOS."
|
|
print "2) Check if your device is included in the device list."
|
|
jmp exit
|
|
|
|
|
|
proceed:
|
|
print " integrated AC97 audio codec detected."
|
|
mov eax, [device_id]
|
|
cmp eax, (ICH4_DID shl 16) + INTEL_VID
|
|
je .newich
|
|
cmp eax, (ICH5_DID shl 16) + INTEL_VID
|
|
jne .nonewich
|
|
.newich:
|
|
mov [AC97ICH4], 1
|
|
.nonewich:
|
|
|
|
cmp eax, (SI7012_DID shl 16) + SIS_VID
|
|
jne @f
|
|
mov [SI7012], 1
|
|
@@:
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
; Get NAMBAR register base port address & save it
|
|
mov cl, NAMBAR_REG
|
|
call pciRegRead16
|
|
|
|
and eax, 0xFFFE
|
|
mov [NAMBAR], ax
|
|
test eax, eax
|
|
jnz .mixer_base_ok
|
|
|
|
print "Error: Intel ICH based AC97 audio codec disabled in BIOS!"
|
|
jmp exit
|
|
|
|
.mixer_base_ok:
|
|
dps "NAMBAR: "
|
|
dph eax
|
|
|
|
; Get NABMBAR & save it
|
|
mov cl, NABMBAR_REG
|
|
call pciRegRead16
|
|
and eax, 0xFFC0
|
|
mov [NABMBAR], ax
|
|
test eax, eax
|
|
jnz .bm_base_ok
|
|
|
|
print "Error: Intel ICH based AC97 audio codec disabled in BIOS!"
|
|
jmp exit
|
|
|
|
.bm_base_ok:
|
|
dps " NABMBAR: "
|
|
dph eax
|
|
newline
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
; Get IRQ (not used)
|
|
mov cl, IRQ_REG
|
|
call pciRegRead8
|
|
mov [AC97IRQ], al
|
|
|
|
; Get Interrupt pin (not used)
|
|
mov cl, INT_REG
|
|
call pciRegRead8
|
|
mov [AC97INT], al
|
|
|
|
; AC97ICH4 should work then...
|
|
cmp [AC97ICH4], 1
|
|
jne .skip_ich4_init
|
|
|
|
mov cl, ICH4_CFG_REG ; 0x41
|
|
call pciRegRead8
|
|
or al, 0x1
|
|
mov dl, al
|
|
call pciRegWrite8
|
|
|
|
mov cl, 0x54
|
|
call pciRegRead16
|
|
and eax, 0xFFFF
|
|
dps "Power Control & Status: "
|
|
dph eax
|
|
newline
|
|
.skip_ich4_init:
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
mov cl, PCI_CMD_REG
|
|
call pciRegRead16 ; read PCI command register
|
|
mov dx, ax
|
|
or dx, IO_ENA+BM_ENA+BIT10 ; enable IO and bus master + disable
|
|
; interrupts
|
|
call pciRegWrite16
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
print "Enabling access to ports..."
|
|
|
|
movzx ecx, [NAMBAR]
|
|
mov edx, ecx
|
|
add edx, NAM_SIZE
|
|
mcall MF_PORTS, PRT_RESERVE
|
|
test eax, eax
|
|
jz @f
|
|
print "Error: couldn't enable access to ports"
|
|
jmp exit
|
|
@@:
|
|
|
|
movzx ecx, [NABMBAR]
|
|
mov edx, ecx
|
|
add edx, NABM_SIZE
|
|
mcall MF_PORTS, PRT_RESERVE
|
|
test eax, eax
|
|
jz @f
|
|
print "Error: couldn't enable access to ports"
|
|
jmp exit
|
|
@@:
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
; setup the Codec
|
|
mov eax, 48000
|
|
call codecConfig ; unmute codec, set rates.
|
|
test eax, eax
|
|
jnz @f
|
|
print "Error: cannot initialize AC97 device."
|
|
jmp fpexit
|
|
@@:
|
|
|
|
print "Congrutalations! Your device has been initialized properly!"
|
|
call print_info
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
; register reset the DMA engine.
|
|
mov edx, PO_CR_REG ; PCM out control register
|
|
mov al, RR ; reset
|
|
call NABMBAR_write_byte
|
|
|
|
;start fix for MM (1)
|
|
mcall MF_INTERNAL_SERVICES,ALLOC_PHYS_MEM,120*1024
|
|
test eax,eax
|
|
jz no_phys_buffers ;not enough memory
|
|
mov [phys_wav_buffer1],eax
|
|
add eax,60*1024
|
|
mov [phys_wav_buffer2],eax
|
|
mcall MF_INTERNAL_SERVICES,ALLOC_PHYS_MEM,32*8
|
|
test eax,eax
|
|
jnz @f
|
|
mcall MF_INTERNAL_SERVICES,FREE_PHYS_MEM,[phys_wav_buffer1]
|
|
jmp no_phys_buffers
|
|
@@:
|
|
mov [phys_bdl_buffer],eax
|
|
;end fix for MM (1)
|
|
|
|
; create Buffer Descriptors List
|
|
call prepare_BDL
|
|
|
|
; open player's window
|
|
mcall MF_THREAD, THR_CREATE, thread, thread_stack
|
|
|
|
; wait for command
|
|
.new_check:
|
|
cmp [status], ST_PLAY
|
|
jne @f
|
|
call play
|
|
@@:
|
|
cmp [status], ST_STOP
|
|
jne @f
|
|
call stop
|
|
@@:
|
|
cmp [status], ST_EXIT
|
|
je stopexit
|
|
|
|
mcall MF_DELAY, 10
|
|
jmp .new_check
|
|
|
|
stopexit:
|
|
call stop
|
|
|
|
fpexit:
|
|
|
|
; free ports
|
|
movzx ecx, [NAMBAR]
|
|
mov edx, ecx
|
|
add edx, NAM_SIZE
|
|
mcall MF_PORTS, PRT_FREE
|
|
|
|
movzx ecx, [NABMBAR]
|
|
mov edx, ecx
|
|
add edx, NABM_SIZE
|
|
mcall MF_PORTS, PRT_FREE
|
|
|
|
;---------------------------------------------------------------------
|
|
;start fix for MM (2)
|
|
mcall MF_INTERNAL_SERVICES,FREE_PHYS_MEM,[phys_bdl_buffer]
|
|
mcall MF_INTERNAL_SERVICES,FREE_PHYS_MEM,[phys_wav_buffer1]
|
|
;end fix for MM (2)
|
|
exit:
|
|
mcall MF_EXIT
|
|
no_phys_buffers:
|
|
print "allocation of physical buffers failed"
|
|
jmp exit
|
|
|
|
;---------------------------------------------------------------------
|
|
;--- FUNCTIONS -----------------------------------------------------
|
|
;---------------------------------------------------------------------
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; prepare_BDL - initializes BUFFER DESCRIPTORS LIST
|
|
prepare_BDL:
|
|
mov ecx, 32 / 2 ; make 32 entries in BDL
|
|
mov edi, BDL_BUFFER
|
|
; call get_my_address
|
|
mov ebx, 30*1024
|
|
cmp [SI7012], 1
|
|
jne @f
|
|
add ebx, ebx
|
|
@@:
|
|
; set buf. desc. 0 to start of data file in memory
|
|
push eax
|
|
; add eax, WAV_BUFFER1
|
|
;start fix for MM (6)
|
|
mov eax,[phys_wav_buffer1]
|
|
;end fix for MM (6)
|
|
stosd
|
|
; set length to 60k samples. 1 sample is 16 bit or 2 bytes.
|
|
mov eax, ebx ;60*1024 ; number of samples
|
|
or eax, BUP
|
|
stosd
|
|
|
|
mov eax, [esp]
|
|
; add eax, WAV_BUFFER2
|
|
;start fix for MM (7)
|
|
mov eax,[phys_wav_buffer2]
|
|
;end fix for MM (7)
|
|
stosd
|
|
mov eax, ebx ;60*1024
|
|
or eax, BUP
|
|
stosd
|
|
|
|
pop eax
|
|
loop @b
|
|
|
|
|
|
; tell the DMA engine where to find our list of Buffer Descriptors.
|
|
; eax = base addr!
|
|
;start fix for MM (3)
|
|
;copy to physical memory
|
|
mcall MF_INTERNAL_SERVICES,SET_PHYS_BUFFER,[phys_bdl_buffer],BDL_BUFFER,32*8
|
|
;physical address of bdl
|
|
mov eax,[phys_bdl_buffer]
|
|
;end fix for MM (3)
|
|
mov edx, PO_BDBAR_REG
|
|
; add eax, BDL_BUFFER
|
|
call NABMBAR_write_dword
|
|
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; stop - stops current music
|
|
;; in: nothing
|
|
;; out: nothing
|
|
stop:
|
|
; print "STOP!"
|
|
push eax edx
|
|
|
|
mcall MF_DELAY, 10
|
|
mov edx, PO_CR_REG
|
|
mov al, 0
|
|
call NABMBAR_write_byte
|
|
cmp [status], ST_STOP
|
|
jne .exit
|
|
mov [status], ST_DONE
|
|
.exit:
|
|
|
|
pop edx eax
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; play - plays wav file!
|
|
;; in: nothing
|
|
;; out: nothing (but sound :) !corrupts registers!
|
|
play:
|
|
; at first, reset file and get file size
|
|
mcall MF_SYSTREE, attrinfo
|
|
test eax, eax
|
|
jnz .notfound
|
|
mov eax, [fileattr+32]
|
|
mov [file_size], eax
|
|
mov [fileinfo.first_byte], 0
|
|
mcall MF_SYSTREE, fileinfo ; load a block, returns error code in eax
|
|
; and size of the file in ebx
|
|
test eax, eax ; 0 - successful
|
|
jz @f
|
|
cmp eax, 6 ; 6 = eof - successful too
|
|
jz @f
|
|
.notfound:
|
|
print "AC97: File not found!"
|
|
mov [status], ST_STOP
|
|
jmp .exit
|
|
@@:
|
|
|
|
mov al, [LOAD_BUFFER+32] ; bytes per sample
|
|
dec al
|
|
jz @f
|
|
cmp al, 3
|
|
je @f
|
|
sub al, [LOAD_BUFFER+22] ; channels
|
|
add al, 2
|
|
@@:
|
|
mov [wav_mode], al
|
|
|
|
pusha
|
|
movzx ebx,word [LOAD_BUFFER+24]
|
|
mov eax,48000
|
|
xor edx,edx
|
|
div ebx
|
|
mov [difference_of_frequency],al
|
|
; dph eax
|
|
mov ecx,edx
|
|
imul eax,ecx,10
|
|
xor edx,edx
|
|
div ebx
|
|
mov ecx,edx
|
|
imul ecx,10
|
|
push eax
|
|
mov eax,ecx
|
|
xor edx,edx
|
|
div ebx
|
|
; dph eax
|
|
cmp eax,5
|
|
jl .temp_15
|
|
pop eax
|
|
; dph eax
|
|
|
|
inc eax
|
|
jmp .temp_16
|
|
.temp_15:
|
|
pop eax
|
|
.temp_16:
|
|
mov [difference_of_frequency_1],al
|
|
; dph eax
|
|
xor edx,edx
|
|
movzx ebx,[difference_of_frequency]
|
|
imul ebx,10
|
|
add bl,[difference_of_frequency_1]
|
|
mov [difference_of_frequency_2],bl
|
|
; dph ebx
|
|
popa
|
|
|
|
movzx eax, word [LOAD_BUFFER+24]
|
|
;dps "Freq: "
|
|
;dpd eax
|
|
;newline
|
|
call set_sample_rate
|
|
|
|
|
|
; change the last_valid_index to the (current_index-1)
|
|
; the LVI register tells the DMA engine where to stop playing
|
|
call updateLVI
|
|
|
|
; if current index is odd, load buffer 1 then 0, jump to tuneLoop
|
|
; if it is even, buffers 0 then 1; tuneLoop1
|
|
call getCurrentIndex
|
|
and eax, BIT0
|
|
|
|
mov esi, eax
|
|
push eax
|
|
call update_next_buffer
|
|
pop eax
|
|
xor eax, 1
|
|
call update_next_buffer
|
|
|
|
; start playing!
|
|
mov edx, PO_CR_REG
|
|
mov al, RPBM
|
|
call NABMBAR_write_byte
|
|
|
|
jmp [jumpto+esi*4]
|
|
|
|
|
|
.tuneLoop:
|
|
; wait while the current_index is even
|
|
@@:
|
|
; dps "a"
|
|
mcall MF_DELAY, 7
|
|
call getCurrentIndex
|
|
test al, BIT0
|
|
jz @b ; loop if not ready yet
|
|
; print "fa"
|
|
|
|
call updateLVI
|
|
|
|
mov eax, 0
|
|
call update_next_buffer
|
|
test al, al
|
|
jnz .exit_wait
|
|
|
|
cmp [status], ST_PLAY
|
|
jne .exit
|
|
|
|
test [volume], 0x10000000 ; test volume_changed bit
|
|
je @f
|
|
mov al, byte [volume]
|
|
call setVolume
|
|
and [volume], 0x0FFFFFFF ; clear vloume_changed bit
|
|
@@:
|
|
|
|
.tuneLoop1:
|
|
@@:
|
|
; dps "b"
|
|
mcall MF_DELAY, 7
|
|
call getCurrentIndex
|
|
test al, BIT0
|
|
jnz @b ; loop if not ready yet
|
|
; print "fb"
|
|
|
|
cmp [status], ST_PLAY
|
|
jne .exit
|
|
|
|
call updateLVI
|
|
|
|
mov eax, 1
|
|
call update_next_buffer
|
|
test al, al
|
|
jnz .exit_wait
|
|
|
|
jmp .tuneLoop
|
|
.exit_wait:
|
|
mcall MF_DELAY, 30 ; a little pause - let the player finish
|
|
.exit:
|
|
ret
|
|
attempts db 0
|
|
|
|
buffers dd WAV_BUFFER1, WAV_BUFFER2
|
|
jumpto dd play.tuneLoop, play.tuneLoop1
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; update_first_buffer - load a chunk into the first buffer, increments offset
|
|
;; in: eax = number - 0 or 1
|
|
;; out: error code, 0 - successful
|
|
update_next_buffer:
|
|
push esi edi
|
|
|
|
movzx edx, byte [wav_mode]
|
|
mov ecx, [blocks + edx * 4]
|
|
mov [fileinfo.bytes], ecx
|
|
|
|
mov esi, LOAD_BUFFER
|
|
mov edi, [buffers+eax*4]
|
|
push eax ;save buffer index
|
|
start_attempts:
|
|
mcall MF_SYSTREE, fileinfo
|
|
test eax, eax
|
|
jz @f
|
|
cmp eax, 6
|
|
jz @f
|
|
cmp [attempts],100
|
|
je @f
|
|
inc [attempts]
|
|
jmp start_attempts
|
|
; dpd eax
|
|
; newline
|
|
; dpd [fileinfo.first_block]
|
|
; newline
|
|
@@:
|
|
; print " loaded!"
|
|
|
|
push eax ebx edx
|
|
mov eax,ecx
|
|
xor edx,edx
|
|
imul eax,10
|
|
movzx ebx,[difference_of_frequency_2]
|
|
|
|
div ebx
|
|
mov ecx,eax
|
|
|
|
; mov ebx,10
|
|
; mov eax,edx
|
|
; xor edx,edx
|
|
; div ebx
|
|
; cmp edx,5
|
|
; jb temp_12_7
|
|
; inc ecx
|
|
; temp_12_7:
|
|
cmp edx,0
|
|
je temp_12_7
|
|
inc ecx
|
|
temp_12_7:
|
|
|
|
pop edx ebx
|
|
mov eax,[esp+4] ;restore buffer index
|
|
add [fileinfo.first_byte], ecx ; +60Kb
|
|
call [convert + edx * 4]
|
|
;start fix for MM (4)
|
|
mov eax,[esp+4] ;restore buffer index
|
|
test eax,not 1
|
|
jz .ok
|
|
print "buffer index out of range"
|
|
dpd eax
|
|
jmp .ret
|
|
.ok:
|
|
push ebp
|
|
mov ebp,[phys_wav_buffer1+eax*4]
|
|
mov edi,[buffers+eax*4]
|
|
mcall MF_INTERNAL_SERVICES,SET_PHYS_BUFFER,ebp,edi,60*1024
|
|
pop ebp
|
|
.ret:
|
|
pop eax
|
|
add esp,4 ;pop buffer index
|
|
;end fix for MM (4)
|
|
|
|
pop edi esi
|
|
ret
|
|
|
|
c8mono:
|
|
mov [type_of_conversion],1
|
|
jmp for_all_type
|
|
|
|
c8mono_1:
|
|
lodsb
|
|
call c8mono_2
|
|
push ax
|
|
shl eax,16
|
|
pop ax
|
|
push eax
|
|
mov al,[esi]
|
|
call c8mono_2
|
|
push ax
|
|
shl eax,16
|
|
pop ax
|
|
mov ebx,eax
|
|
pop eax
|
|
jmp for_all_type_1
|
|
|
|
c8mono_2:
|
|
sub al, 0x80
|
|
cbw
|
|
imul ax, 255
|
|
ret
|
|
|
|
c8stereo:
|
|
mov [type_of_conversion],2
|
|
jmp for_all_type
|
|
|
|
c8stereo_1:
|
|
lodsb
|
|
call c8stereo_2
|
|
shl eax,16
|
|
lodsb
|
|
call c8stereo_2
|
|
push eax
|
|
mov al,[esi]
|
|
call c8stereo_2
|
|
shl eax,16
|
|
mov al,[esi+1]
|
|
call c8stereo_2
|
|
mov ebx,eax
|
|
pop eax
|
|
jmp for_all_type_1
|
|
|
|
c8stereo_2:
|
|
sub al, 0x80
|
|
cbw
|
|
imul ax, 255
|
|
ret
|
|
|
|
c16mono:
|
|
mov [type_of_conversion],3
|
|
jmp for_all_type
|
|
|
|
c16mono_1:
|
|
lodsw
|
|
push ax
|
|
shl eax,16
|
|
pop ax
|
|
mov bx,[esi]
|
|
shl ebx,16
|
|
mov bx,[esi]
|
|
jmp for_all_type_1
|
|
|
|
c16stereo:
|
|
for_all_type:
|
|
xor edx,edx
|
|
mov eax, 15*1024*10
|
|
movzx ebx,[difference_of_frequency_2]
|
|
xor edx,edx
|
|
div ebx
|
|
mov ecx,eax
|
|
|
|
; mov ebx,10
|
|
; mov eax,edx
|
|
; xor edx,edx
|
|
; div ebx
|
|
; cmp edx,5
|
|
; jb temp_12_6
|
|
; inc ecx
|
|
; temp_12_6:
|
|
cmp edx,0
|
|
je temp_12_6
|
|
inc ecx
|
|
temp_12_6:
|
|
|
|
c16stereo_1:
|
|
mov [znak],0
|
|
|
|
cmp [type_of_conversion],1
|
|
je c8mono_1
|
|
cmp [type_of_conversion],2
|
|
je c8stereo_1
|
|
cmp [type_of_conversion],3
|
|
je c16mono_1
|
|
lodsd
|
|
|
|
mov ebx,[esi]
|
|
for_all_type_1:
|
|
cmp eax,ebx
|
|
jne c16stereo_2
|
|
inc [znak]
|
|
c16stereo_2:
|
|
push eax
|
|
push ecx
|
|
sub eax,ebx
|
|
push eax
|
|
shl eax,16
|
|
movzx ebx,[difference_of_frequency]
|
|
inc ebx
|
|
xor edx,edx
|
|
div ebx
|
|
shr eax,16
|
|
mov ecx,eax
|
|
pop eax
|
|
xor ax,ax
|
|
xor edx,edx
|
|
div ebx
|
|
shl eax,16
|
|
mov cx,ax
|
|
mov ebx,ecx
|
|
pop ecx
|
|
pop eax
|
|
mov dl,[difference_of_frequency]
|
|
inc dl
|
|
@@:
|
|
temp_12:
|
|
cmp [difference_of_frequency_1],0
|
|
je temp_12_3
|
|
cmp [difference_of_frequency_1],5
|
|
jne temp_12_4
|
|
cmp [difference_of_frequency_4],2
|
|
jne temp_12_3
|
|
jmp temp_12_5
|
|
temp_12_4:
|
|
cmp [difference_of_frequency_4],10
|
|
jne temp_12_3
|
|
|
|
temp_12_5:
|
|
|
|
cmp [znak],0
|
|
jne temp_12_5_1
|
|
sub eax,ebx
|
|
jmp temp_12_5_2
|
|
temp_12_5_1:
|
|
add eax,ebx
|
|
temp_12_5_2:
|
|
|
|
|
|
stosd
|
|
inc [schetchik]
|
|
mov [difference_of_frequency_4],0
|
|
temp_12_3:
|
|
cmp [znak],0
|
|
jne temp_13
|
|
sub eax,ebx
|
|
jmp temp_14
|
|
temp_13:
|
|
add eax,ebx
|
|
|
|
temp_14:
|
|
cld
|
|
dec dl
|
|
jz temp_14_1
|
|
stosd
|
|
inc [schetchik]
|
|
inc [difference_of_frequency_4]
|
|
jmp temp_12
|
|
temp_14_1:
|
|
dec ecx
|
|
cmp ecx,0
|
|
; jnz c16stereo_1
|
|
jg c16stereo_1
|
|
newline
|
|
dph [schetchik]
|
|
temp_14_2:
|
|
cmp [schetchik],15360
|
|
jge temp_14_3
|
|
stosd
|
|
inc [schetchik]
|
|
jmp temp_14_2
|
|
|
|
temp_14_3:
|
|
newline
|
|
dph [schetchik]
|
|
cmp [schetchik],15360
|
|
je temp_14_4
|
|
; mov [edi-4],dword 0
|
|
sub edi,4
|
|
; sub esi,4
|
|
temp_14_4:
|
|
mov [schetchik],0
|
|
ret
|
|
|
|
|
|
difference_of_frequency db 0
|
|
difference_of_frequency_1 db 0
|
|
difference_of_frequency_2 db 0
|
|
difference_of_frequency_4 db 0
|
|
schetchik dd 0
|
|
znak db 0
|
|
type_of_conversion db 0
|
|
|
|
convert dd c8mono, c8stereo, c16mono, c16stereo
|
|
blocks dd 30*512, 60*512, 60*512, 120*512
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; get_my_address - get base address of the program in physical memory
|
|
;; in: nothing
|
|
;; out: eax = address
|
|
;start fix for MM (8)
|
|
;function shouldn't used.
|
|
;get_my_address:
|
|
; pushad
|
|
; mcall MF_PROCINFO, procinfo, PN_MYSELF
|
|
; popad
|
|
; mov eax, [procinfo.memory_start]
|
|
;ret
|
|
;end fix for MM (8)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; set the last valid index to something other than we're currently playing
|
|
;; so that we never end
|
|
;;
|
|
;; this routine just sets the last valid index to 1 less than the index
|
|
;; that we're currently playing, thus keeping it in and endless loop
|
|
;; input: none
|
|
;; output: none
|
|
updateLVI:
|
|
push eax
|
|
call getCurrentIndex
|
|
; dps "index "
|
|
; dpd eax
|
|
; newline
|
|
dec al
|
|
and al, INDEX_MASK
|
|
call setLastValidIndex
|
|
pop eax
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; returns AL = current index value
|
|
getCurrentIndex:
|
|
push edx
|
|
mov edx, PO_CIV_REG
|
|
call NABMBAR_read_byte
|
|
pop edx
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; input AL = index # to stop on
|
|
setLastValidIndex:
|
|
push edx
|
|
mov edx, PO_LVI_REG
|
|
call NABMBAR_write_byte
|
|
pop edx
|
|
ret
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; print_info - outputs debug information
|
|
;; in: nothing
|
|
;; out: nothing
|
|
print_info:
|
|
dps "BUS: "
|
|
movzx eax, [bus]
|
|
dph eax
|
|
|
|
dps " DEVFN: "
|
|
movzx eax, [devfn]
|
|
dph eax
|
|
|
|
dps " IRQ: "
|
|
movzx eax, [AC97IRQ]
|
|
dpd eax
|
|
newline
|
|
|
|
|
|
dps "CODEC_POWER_CTRL: "
|
|
mov edx, CODEC_POWER_CTRL_REG
|
|
call NAMBAR_read_word
|
|
dph eax
|
|
dps " (bits 0-3 should be set)"
|
|
newline
|
|
|
|
mov edx, 0x28
|
|
call NAMBAR_read_word
|
|
dph eax
|
|
dps " - supported features"
|
|
newline
|
|
mov edx, 0x2A
|
|
call NAMBAR_read_word
|
|
dph eax
|
|
dps " - config"
|
|
newline
|
|
mov edx, 0x2C
|
|
call NAMBAR_read_word
|
|
dph eax
|
|
dps " - PCM rate"
|
|
|
|
newline
|
|
ret
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
;--- DATA OF PROGRAM -----------------------------------------------
|
|
;---------------------------------------------------------------------
|
|
volume dd 15
|
|
|
|
attrinfo:
|
|
dd 5
|
|
dd 0
|
|
dd 0
|
|
dd 0
|
|
dd fileattr
|
|
db 0
|
|
dd textbox_string
|
|
|
|
fileinfo:
|
|
.mode dd 0 ; READ
|
|
.first_byte dd 0
|
|
dd 0
|
|
.bytes dd 60*1024 ; 60 Kb
|
|
.dest dd LOAD_BUFFER ;file_data
|
|
; db "/HD/1/WINDOWS/MEDIA/WICEB7~1.WAV",0
|
|
;sz textbox_string, "/hd/1/testmuz/menuet11.wav",0
|
|
textbox_string:
|
|
;---------------------------------------------------------------------
|
|
|
|
IMAGE_END: ; end of program's image
|
|
rb 257
|
|
; rb 257-textbox_string.size
|
|
; textbox_string.size
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
device_id dd ? ; (device_id << 16) + vendor_id
|
|
lastbus db ? ; pci coordinates
|
|
bus db ?
|
|
devfn db ?
|
|
|
|
AC97ICH4 db ? ; Intel ICH4 codec flag
|
|
SI7012 db ? ; SiS SI7012 codec flag
|
|
NAMBAR dw ? ; Audio Mixers Registers (base)
|
|
NABMBAR dw ? ; Bus Master Registers (base)
|
|
|
|
AC97IRQ db ? ; Interrupt request
|
|
AC97INT db ? ; Interrupt pin
|
|
|
|
wav_mode db ? ; bits per sample & channels
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
ST_DONE = 0x0 ; for interacting with player's window
|
|
ST_PLAY = 0x1
|
|
ST_EXIT = 0x2
|
|
ST_STOP = 0x4
|
|
|
|
status db ?
|
|
|
|
fileattr: rb 40
|
|
|
|
;---------------------------------------------------------------------
|
|
phys_bdl_buffer rd 1
|
|
phys_wav_buffer1 rd 1
|
|
phys_wav_buffer2 rd 1
|
|
align 32
|
|
|
|
|
|
; Buffer Descriptors List
|
|
; ___________________________
|
|
; | physical address | dword
|
|
; |_________________________|
|
|
; | attr | length | dword max. length = 65535 samples
|
|
; |_________________________|
|
|
|
|
BDL_BUFFER:
|
|
rb 32*8 ; 32 descriptors, 8 bytes each
|
|
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
file_data:
|
|
|
|
WAV_BUFFER1:
|
|
rb 60 * 1024 ; 60 Kb
|
|
|
|
WAV_BUFFER2:
|
|
rb 60 * 1024
|
|
|
|
LOAD_BUFFER:
|
|
rb 60 * 1024
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
procinfo process_information
|
|
|
|
work_area:
|
|
rb 0x10000
|
|
|
|
;---------------------------------------------------------------------
|
|
|
|
rb 0x800
|
|
thread_stack:
|
|
|
|
rb 0x1000 ; for stack
|
|
STACK_P:
|
|
|
|
MEMORY_END:
|