0,0 → 1,1084 |
;--------------------------------------------------------------------- |
; |
; 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 |
; |
; Use [flat assembler 1.56] 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 "lang.inc" |
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 |
mov [fileinfo.first_block], 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 |
print "AC97: File not found!" |
mov [status], ST_STOP |
jmp .exit |
@@: |
shr ebx, 9 ; size_of_file / 512 = number_of_blocks |
mov [file_size], ebx |
|
|
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.blocks], 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 [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_block], 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, 60, 60, 120 |
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; 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 |
|
fileinfo: |
.mode dd 0 ; READ |
.first_block dd 0 |
.blocks dd 120 ; 120 Kb |
.dest dd LOAD_BUFFER ;file_data |
.work dd work_area |
; db "/HD/1/WINDOWS/MEDIA/WICEB7~1.WAV",0 |
;sz textbox_string, "/hd/1/testmuz/menuet11.wav",0 |
sz textbox_string, " ",0 |
; rb 256 |
;--------------------------------------------------------------------- |
|
IMAGE_END: ; end of program's image |
rb 100-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 ? |
|
;--------------------------------------------------------------------- |
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: |
Property changes: |
Added: svn:eol-style |
+native |
\ No newline at end of property |