Rev 139 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
31 | halyavin | 1 | ;--------------------------------------------------------------------- |
2 | ; |
||
3 | ; MenuetOS AC97 WAV Player |
||
4 | ; |
||
5 | ; 0.03 November 10, 2004 doesn't halt if file not found |
||
6 | ; 0.04 November 11, 2004 better positioning (with mouse) |
||
7 | ; 0.05 November 14, 2004 internals clean up |
||
8 | ; fixed cutting sound at the edges |
||
9 | ; 0.06 November 17, 2004 fixed many bugs |
||
10 | ; 0.07 Nov 20, 2004 deactivates text box when 'play' pressed |
||
11 | ; stops playing before closing a window |
||
12 | ; 0.08 Nov 24, 2004 added support for 8bit and mono modes |
||
13 | ; +variable rate for some chipsets |
||
139 | diamond | 14 | ; 0.09 August 26, 2006 modified to use function 70 |
31 | halyavin | 15 | ; |
139 | diamond | 16 | ; Use [flat assembler 1.64] to compile. |
31 | halyavin | 17 | ; |
18 | ;--------------------------------------------------------------------- |
||
19 | |||
20 | use32 ; turn on 32 bit mode |
||
21 | org 0x0 ; the program is placed at 0 offset |
||
22 | |||
23 | db 'MENUET01' ; 8-byte identifier of MenuetOS application |
||
24 | dd 0x01 ; header version (always 1) |
||
25 | dd START ; address of the beginning of the code |
||
26 | dd IMAGE_END ; size of the program's image |
||
27 | dd MEMORY_END ; how much memory does it need |
||
28 | dd STACK_P ; a pointer to the top of the stack |
||
29 | dd textbox_string |
||
30 | ; dd 0x0 ; address of buffer for parameters (not used) |
||
31 | dd 0x0 ; reserved |
||
32 | |||
33 | ;--------------------------------------------------------------------- |
||
34 | |||
156 | diamond | 35 | include "MACROS.INC" ; standart macros & constants |
36 | include "MEOSFUNC.INC" ; MenuetOS API functions names |
||
37 | include "DEBUG.INC" ; printing to debug board |
||
38 | include "CONSTANT.INC" ; BIT?? constants |
||
39 | include "AC97.INC" ; AC'97 constants |
||
40 | include "PCI.INC" ; PCI interface |
||
41 | include "CODEC.INC" ; functions for configuring codec |
||
42 | include "FRONTEND.INC" ; main window |
||
31 | halyavin | 43 | |
44 | ;--------------------------------------------------------------------- |
||
45 | |||
46 | ; Uncomment these strings if you don't want to receive debug messages: |
||
47 | |||
48 | ; macro dps str {} ; dps prints a string without CRLF |
||
49 | ; macro dpd num {} ; prints unsigned decimal number |
||
50 | ; macro pregs {} ; outputs EAX, EBX, ECX, EDX |
||
51 | ; macro newline {} ; CRLF |
||
52 | ; macro print str {} ; output a string with CRLF |
||
53 | ; macro dph arg {} ; print hex number |
||
54 | |||
55 | ;--------------------------------------------------------------------- |
||
56 | |||
57 | ;macro device id, addr { dd id, addr } |
||
58 | macro devices [id, str] |
||
59 | { |
||
60 | common |
||
61 | label supported_devices dword |
||
62 | forward |
||
63 | local string |
||
64 | dd id |
||
65 | dd string |
||
66 | forward |
||
67 | string db str |
||
68 | db 0 |
||
69 | } |
||
70 | |||
71 | |||
72 | devices \ |
||
73 | (ICH_DID shl 16) + INTEL_VID, "ICH" ,\ |
||
74 | (ICH0_DID shl 16) + INTEL_VID, "ICH0" ,\ |
||
75 | (ICH2_DID shl 16) + INTEL_VID, "ICH2" ,\ |
||
76 | (ICH3_DID shl 16) + INTEL_VID, "ICH2" ,\ |
||
77 | (ICH4_DID shl 16) + INTEL_VID, "ICH4" ,\ |
||
78 | (ICH5_DID shl 16) + INTEL_VID, "ICH5" ,\ |
||
79 | (MX440_DID shl 16) + INTEL_VID, "440MX" ,\ |
||
80 | (SI7012_DID shl 16) + SIS_VID, "SI7012" ,\ |
||
81 | (NFORCE_DID shl 16) + NVIDIA_VID, "NForce" ,\ |
||
82 | (NFORCE2_DID shl 16) + NVIDIA_VID, "NForce2",\ |
||
83 | (AMD8111_DID shl 16) + AMD_VID, "AMD8111",\ |
||
84 | (AMD768_DID shl 16) + AMD_VID, "AMD768" |
||
85 | dd 0 |
||
86 | |||
87 | |||
88 | ;--------------------------------------------------------------------- |
||
89 | ;--- MAIN PROGRAM -------------------------------------------------- |
||
90 | ;--------------------------------------------------------------------- |
||
91 | |||
92 | START: |
||
93 | |||
94 | ; Print PCI version (for example, 2.16) |
||
95 | ; mcall MF_PCI, 0 |
||
96 | ; mov bl, al |
||
97 | ; movzx eax, ah |
||
98 | ; dps "PCI version: " |
||
99 | ; dpd eax |
||
100 | ; movzx eax, bl |
||
101 | ; dpd eax |
||
102 | ; newline |
||
103 | |||
104 | ; Check PCI access mechanism (must be 1 or 2) |
||
105 | mcall MF_PCI, 2 |
||
106 | dec al |
||
107 | cmp al, 1 |
||
108 | jna @f |
||
109 | print "Error: cannot access PCI bus." |
||
110 | jmp exit |
||
111 | ; dps "PCI returned " |
||
112 | ; movzx eax, al |
||
113 | ; dpd eax |
||
114 | ; newline |
||
115 | @@: |
||
116 | |||
117 | |||
118 | ; Get last bus & then check all buses & devices |
||
119 | mcall MF_PCI, 1 |
||
120 | mov [lastbus], al |
||
121 | |||
122 | ; looking for a compatible device |
||
123 | mov [bus], -1 |
||
124 | .next_bus: |
||
125 | inc [bus] |
||
126 | |||
127 | mov al, [lastbus] |
||
128 | cmp al, [bus] |
||
129 | jb .device_not_found |
||
130 | |||
131 | mov [devfn], 0 |
||
132 | .next_devfn: |
||
133 | |||
134 | mov cl, 0 |
||
135 | call pciRegRead32 |
||
136 | |||
137 | mov edi, supported_devices |
||
138 | @@: |
||
139 | mov ebx, [edi] |
||
140 | test ebx, ebx |
||
141 | jz @f |
||
142 | cmp eax, ebx |
||
143 | jnz .skip |
||
144 | add edi, 4 |
||
145 | mov [device_id], eax |
||
146 | mov edx, [edi] |
||
147 | call debug_outstr |
||
148 | jmp proceed |
||
149 | .skip: |
||
150 | add edi, 8 |
||
151 | jmp @b |
||
152 | @@: |
||
153 | |||
154 | inc [devfn] |
||
155 | cmp [devfn], 255 |
||
156 | jb .next_devfn |
||
157 | |||
158 | jmp .next_bus |
||
159 | |||
160 | |||
161 | .device_not_found: |
||
162 | print "Could not find Intel AC'97 compatible codec!" |
||
163 | print "1) Check if it's enabled in BIOS." |
||
164 | print "2) Check if your device is included in the device list." |
||
165 | jmp exit |
||
166 | |||
167 | |||
168 | proceed: |
||
169 | print " integrated AC97 audio codec detected." |
||
170 | mov eax, [device_id] |
||
171 | cmp eax, (ICH4_DID shl 16) + INTEL_VID |
||
172 | je .newich |
||
173 | cmp eax, (ICH5_DID shl 16) + INTEL_VID |
||
174 | jne .nonewich |
||
175 | .newich: |
||
176 | mov [AC97ICH4], 1 |
||
177 | .nonewich: |
||
178 | |||
179 | cmp eax, (SI7012_DID shl 16) + SIS_VID |
||
180 | jne @f |
||
181 | mov [SI7012], 1 |
||
182 | @@: |
||
183 | |||
184 | ;--------------------------------------------------------------------- |
||
185 | |||
186 | ; Get NAMBAR register base port address & save it |
||
187 | mov cl, NAMBAR_REG |
||
188 | call pciRegRead16 |
||
189 | |||
190 | and eax, 0xFFFE |
||
191 | mov [NAMBAR], ax |
||
192 | test eax, eax |
||
193 | jnz .mixer_base_ok |
||
194 | |||
195 | print "Error: Intel ICH based AC97 audio codec disabled in BIOS!" |
||
196 | jmp exit |
||
197 | |||
198 | .mixer_base_ok: |
||
199 | dps "NAMBAR: " |
||
200 | dph eax |
||
201 | |||
202 | ; Get NABMBAR & save it |
||
203 | mov cl, NABMBAR_REG |
||
204 | call pciRegRead16 |
||
205 | and eax, 0xFFC0 |
||
206 | mov [NABMBAR], ax |
||
207 | test eax, eax |
||
208 | jnz .bm_base_ok |
||
209 | |||
210 | print "Error: Intel ICH based AC97 audio codec disabled in BIOS!" |
||
211 | jmp exit |
||
212 | |||
213 | .bm_base_ok: |
||
214 | dps " NABMBAR: " |
||
215 | dph eax |
||
216 | newline |
||
217 | |||
218 | ;--------------------------------------------------------------------- |
||
219 | |||
220 | ; Get IRQ (not used) |
||
221 | mov cl, IRQ_REG |
||
222 | call pciRegRead8 |
||
223 | mov [AC97IRQ], al |
||
224 | |||
225 | ; Get Interrupt pin (not used) |
||
226 | mov cl, INT_REG |
||
227 | call pciRegRead8 |
||
228 | mov [AC97INT], al |
||
229 | |||
230 | ; AC97ICH4 should work then... |
||
231 | cmp [AC97ICH4], 1 |
||
232 | jne .skip_ich4_init |
||
233 | |||
234 | mov cl, ICH4_CFG_REG ; 0x41 |
||
235 | call pciRegRead8 |
||
236 | or al, 0x1 |
||
237 | mov dl, al |
||
238 | call pciRegWrite8 |
||
239 | |||
240 | mov cl, 0x54 |
||
241 | call pciRegRead16 |
||
242 | and eax, 0xFFFF |
||
243 | dps "Power Control & Status: " |
||
244 | dph eax |
||
245 | newline |
||
246 | .skip_ich4_init: |
||
247 | |||
248 | ;--------------------------------------------------------------------- |
||
249 | |||
250 | mov cl, PCI_CMD_REG |
||
251 | call pciRegRead16 ; read PCI command register |
||
252 | mov dx, ax |
||
253 | or dx, IO_ENA+BM_ENA+BIT10 ; enable IO and bus master + disable |
||
254 | ; interrupts |
||
255 | call pciRegWrite16 |
||
256 | |||
257 | ;--------------------------------------------------------------------- |
||
258 | |||
259 | print "Enabling access to ports..." |
||
260 | |||
261 | movzx ecx, [NAMBAR] |
||
262 | mov edx, ecx |
||
263 | add edx, NAM_SIZE |
||
264 | mcall MF_PORTS, PRT_RESERVE |
||
265 | test eax, eax |
||
266 | jz @f |
||
267 | print "Error: couldn't enable access to ports" |
||
268 | jmp exit |
||
269 | @@: |
||
270 | |||
271 | movzx ecx, [NABMBAR] |
||
272 | mov edx, ecx |
||
273 | add edx, NABM_SIZE |
||
274 | mcall MF_PORTS, PRT_RESERVE |
||
275 | test eax, eax |
||
276 | jz @f |
||
277 | print "Error: couldn't enable access to ports" |
||
278 | jmp exit |
||
279 | @@: |
||
280 | |||
281 | ;--------------------------------------------------------------------- |
||
282 | |||
283 | ; setup the Codec |
||
284 | mov eax, 48000 |
||
285 | call codecConfig ; unmute codec, set rates. |
||
286 | test eax, eax |
||
287 | jnz @f |
||
288 | print "Error: cannot initialize AC97 device." |
||
289 | jmp fpexit |
||
290 | @@: |
||
291 | |||
292 | print "Congrutalations! Your device has been initialized properly!" |
||
293 | call print_info |
||
294 | |||
295 | ;--------------------------------------------------------------------- |
||
296 | |||
297 | ; register reset the DMA engine. |
||
298 | mov edx, PO_CR_REG ; PCM out control register |
||
299 | mov al, RR ; reset |
||
300 | call NABMBAR_write_byte |
||
301 | |||
302 | ;start fix for MM (1) |
||
303 | mcall MF_INTERNAL_SERVICES,ALLOC_PHYS_MEM,120*1024 |
||
304 | test eax,eax |
||
305 | jz no_phys_buffers ;not enough memory |
||
306 | mov [phys_wav_buffer1],eax |
||
307 | add eax,60*1024 |
||
308 | mov [phys_wav_buffer2],eax |
||
309 | mcall MF_INTERNAL_SERVICES,ALLOC_PHYS_MEM,32*8 |
||
310 | test eax,eax |
||
311 | jnz @f |
||
312 | mcall MF_INTERNAL_SERVICES,FREE_PHYS_MEM,[phys_wav_buffer1] |
||
313 | jmp no_phys_buffers |
||
314 | @@: |
||
315 | mov [phys_bdl_buffer],eax |
||
316 | ;end fix for MM (1) |
||
317 | |||
318 | ; create Buffer Descriptors List |
||
319 | call prepare_BDL |
||
320 | |||
321 | ; open player's window |
||
322 | mcall MF_THREAD, THR_CREATE, thread, thread_stack |
||
323 | |||
324 | ; wait for command |
||
325 | .new_check: |
||
326 | cmp [status], ST_PLAY |
||
327 | jne @f |
||
328 | call play |
||
329 | @@: |
||
330 | cmp [status], ST_STOP |
||
331 | jne @f |
||
332 | call stop |
||
333 | @@: |
||
334 | cmp [status], ST_EXIT |
||
335 | je stopexit |
||
336 | |||
337 | mcall MF_DELAY, 10 |
||
338 | jmp .new_check |
||
339 | |||
340 | stopexit: |
||
341 | call stop |
||
342 | |||
343 | fpexit: |
||
344 | |||
345 | ; free ports |
||
346 | movzx ecx, [NAMBAR] |
||
347 | mov edx, ecx |
||
348 | add edx, NAM_SIZE |
||
349 | mcall MF_PORTS, PRT_FREE |
||
350 | |||
351 | movzx ecx, [NABMBAR] |
||
352 | mov edx, ecx |
||
353 | add edx, NABM_SIZE |
||
354 | mcall MF_PORTS, PRT_FREE |
||
355 | |||
356 | ;--------------------------------------------------------------------- |
||
357 | ;start fix for MM (2) |
||
358 | mcall MF_INTERNAL_SERVICES,FREE_PHYS_MEM,[phys_bdl_buffer] |
||
359 | mcall MF_INTERNAL_SERVICES,FREE_PHYS_MEM,[phys_wav_buffer1] |
||
360 | ;end fix for MM (2) |
||
361 | exit: |
||
362 | mcall MF_EXIT |
||
363 | no_phys_buffers: |
||
364 | print "allocation of physical buffers failed" |
||
365 | jmp exit |
||
366 | |||
367 | ;--------------------------------------------------------------------- |
||
368 | ;--- FUNCTIONS ----------------------------------------------------- |
||
369 | ;--------------------------------------------------------------------- |
||
370 | |||
371 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
372 | ;; prepare_BDL - initializes BUFFER DESCRIPTORS LIST |
||
373 | prepare_BDL: |
||
374 | mov ecx, 32 / 2 ; make 32 entries in BDL |
||
375 | mov edi, BDL_BUFFER |
||
376 | ; call get_my_address |
||
377 | mov ebx, 30*1024 |
||
378 | cmp [SI7012], 1 |
||
379 | jne @f |
||
380 | add ebx, ebx |
||
381 | @@: |
||
382 | ; set buf. desc. 0 to start of data file in memory |
||
383 | push eax |
||
384 | ; add eax, WAV_BUFFER1 |
||
385 | ;start fix for MM (6) |
||
386 | mov eax,[phys_wav_buffer1] |
||
387 | ;end fix for MM (6) |
||
388 | stosd |
||
389 | ; set length to 60k samples. 1 sample is 16 bit or 2 bytes. |
||
390 | mov eax, ebx ;60*1024 ; number of samples |
||
391 | or eax, BUP |
||
392 | stosd |
||
393 | |||
394 | mov eax, [esp] |
||
395 | ; add eax, WAV_BUFFER2 |
||
396 | ;start fix for MM (7) |
||
397 | mov eax,[phys_wav_buffer2] |
||
398 | ;end fix for MM (7) |
||
399 | stosd |
||
400 | mov eax, ebx ;60*1024 |
||
401 | or eax, BUP |
||
402 | stosd |
||
403 | |||
404 | pop eax |
||
405 | loop @b |
||
406 | |||
407 | |||
408 | ; tell the DMA engine where to find our list of Buffer Descriptors. |
||
409 | ; eax = base addr! |
||
410 | ;start fix for MM (3) |
||
411 | ;copy to physical memory |
||
412 | mcall MF_INTERNAL_SERVICES,SET_PHYS_BUFFER,[phys_bdl_buffer],BDL_BUFFER,32*8 |
||
413 | ;physical address of bdl |
||
414 | mov eax,[phys_bdl_buffer] |
||
415 | ;end fix for MM (3) |
||
416 | mov edx, PO_BDBAR_REG |
||
417 | ; add eax, BDL_BUFFER |
||
418 | call NABMBAR_write_dword |
||
419 | |||
420 | ret |
||
421 | |||
422 | |||
423 | ;--------------------------------------------------------------------- |
||
424 | |||
425 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
426 | ;; stop - stops current music |
||
427 | ;; in: nothing |
||
428 | ;; out: nothing |
||
429 | stop: |
||
430 | ; print "STOP!" |
||
431 | push eax edx |
||
432 | |||
433 | mcall MF_DELAY, 10 |
||
434 | mov edx, PO_CR_REG |
||
435 | mov al, 0 |
||
436 | call NABMBAR_write_byte |
||
437 | cmp [status], ST_STOP |
||
438 | jne .exit |
||
439 | mov [status], ST_DONE |
||
440 | .exit: |
||
441 | |||
442 | pop edx eax |
||
443 | ret |
||
444 | |||
445 | ;--------------------------------------------------------------------- |
||
446 | |||
447 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
448 | ;; play - plays wav file! |
||
449 | ;; in: nothing |
||
450 | ;; out: nothing (but sound :) !corrupts registers! |
||
451 | play: |
||
139 | diamond | 452 | ; at first, reset file and get file size |
453 | mcall MF_SYSTREE, attrinfo |
||
454 | test eax, eax |
||
455 | jnz .notfound |
||
456 | mov eax, [fileattr+32] |
||
457 | mov [file_size], eax |
||
458 | mov [fileinfo.first_byte], 0 |
||
31 | halyavin | 459 | mcall MF_SYSTREE, fileinfo ; load a block, returns error code in eax |
460 | ; and size of the file in ebx |
||
461 | test eax, eax ; 0 - successful |
||
462 | jz @f |
||
139 | diamond | 463 | cmp eax, 6 ; 6 = eof - successful too |
464 | jz @f |
||
465 | .notfound: |
||
31 | halyavin | 466 | print "AC97: File not found!" |
467 | mov [status], ST_STOP |
||
468 | jmp .exit |
||
469 | @@: |
||
470 | |||
471 | mov al, [LOAD_BUFFER+32] ; bytes per sample |
||
472 | dec al |
||
473 | jz @f |
||
474 | cmp al, 3 |
||
475 | je @f |
||
476 | sub al, [LOAD_BUFFER+22] ; channels |
||
477 | add al, 2 |
||
478 | @@: |
||
479 | mov [wav_mode], al |
||
480 | |||
481 | pusha |
||
482 | movzx ebx,word [LOAD_BUFFER+24] |
||
483 | mov eax,48000 |
||
484 | xor edx,edx |
||
485 | div ebx |
||
486 | mov [difference_of_frequency],al |
||
487 | ; dph eax |
||
488 | mov ecx,edx |
||
489 | imul eax,ecx,10 |
||
490 | xor edx,edx |
||
491 | div ebx |
||
492 | mov ecx,edx |
||
493 | imul ecx,10 |
||
494 | push eax |
||
495 | mov eax,ecx |
||
496 | xor edx,edx |
||
497 | div ebx |
||
498 | ; dph eax |
||
499 | cmp eax,5 |
||
500 | jl .temp_15 |
||
501 | pop eax |
||
502 | ; dph eax |
||
503 | |||
504 | inc eax |
||
505 | jmp .temp_16 |
||
506 | .temp_15: |
||
507 | pop eax |
||
508 | .temp_16: |
||
509 | mov [difference_of_frequency_1],al |
||
510 | ; dph eax |
||
511 | xor edx,edx |
||
512 | movzx ebx,[difference_of_frequency] |
||
513 | imul ebx,10 |
||
514 | add bl,[difference_of_frequency_1] |
||
515 | mov [difference_of_frequency_2],bl |
||
516 | ; dph ebx |
||
517 | popa |
||
518 | |||
519 | movzx eax, word [LOAD_BUFFER+24] |
||
520 | ;dps "Freq: " |
||
521 | ;dpd eax |
||
522 | ;newline |
||
523 | call set_sample_rate |
||
524 | |||
525 | |||
526 | ; change the last_valid_index to the (current_index-1) |
||
527 | ; the LVI register tells the DMA engine where to stop playing |
||
528 | call updateLVI |
||
529 | |||
530 | ; if current index is odd, load buffer 1 then 0, jump to tuneLoop |
||
531 | ; if it is even, buffers 0 then 1; tuneLoop1 |
||
532 | call getCurrentIndex |
||
533 | and eax, BIT0 |
||
534 | |||
535 | mov esi, eax |
||
536 | push eax |
||
537 | call update_next_buffer |
||
538 | pop eax |
||
539 | xor eax, 1 |
||
540 | call update_next_buffer |
||
541 | |||
542 | ; start playing! |
||
543 | mov edx, PO_CR_REG |
||
544 | mov al, RPBM |
||
545 | call NABMBAR_write_byte |
||
546 | |||
547 | jmp [jumpto+esi*4] |
||
548 | |||
549 | |||
550 | .tuneLoop: |
||
551 | ; wait while the current_index is even |
||
552 | @@: |
||
553 | ; dps "a" |
||
554 | mcall MF_DELAY, 7 |
||
555 | call getCurrentIndex |
||
556 | test al, BIT0 |
||
557 | jz @b ; loop if not ready yet |
||
558 | ; print "fa" |
||
559 | |||
560 | call updateLVI |
||
561 | |||
562 | mov eax, 0 |
||
563 | call update_next_buffer |
||
564 | test al, al |
||
565 | jnz .exit_wait |
||
566 | |||
567 | cmp [status], ST_PLAY |
||
568 | jne .exit |
||
569 | |||
570 | test [volume], 0x10000000 ; test volume_changed bit |
||
571 | je @f |
||
572 | mov al, byte [volume] |
||
573 | call setVolume |
||
574 | and [volume], 0x0FFFFFFF ; clear vloume_changed bit |
||
575 | @@: |
||
576 | |||
577 | .tuneLoop1: |
||
578 | @@: |
||
579 | ; dps "b" |
||
580 | mcall MF_DELAY, 7 |
||
581 | call getCurrentIndex |
||
582 | test al, BIT0 |
||
583 | jnz @b ; loop if not ready yet |
||
584 | ; print "fb" |
||
585 | |||
586 | cmp [status], ST_PLAY |
||
587 | jne .exit |
||
588 | |||
589 | call updateLVI |
||
590 | |||
591 | mov eax, 1 |
||
592 | call update_next_buffer |
||
593 | test al, al |
||
594 | jnz .exit_wait |
||
595 | |||
596 | jmp .tuneLoop |
||
597 | .exit_wait: |
||
598 | mcall MF_DELAY, 30 ; a little pause - let the player finish |
||
599 | .exit: |
||
600 | ret |
||
601 | attempts db 0 |
||
602 | |||
603 | buffers dd WAV_BUFFER1, WAV_BUFFER2 |
||
604 | jumpto dd play.tuneLoop, play.tuneLoop1 |
||
605 | |||
606 | |||
607 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
608 | ;; update_first_buffer - load a chunk into the first buffer, increments offset |
||
609 | ;; in: eax = number - 0 or 1 |
||
610 | ;; out: error code, 0 - successful |
||
611 | update_next_buffer: |
||
612 | push esi edi |
||
613 | |||
614 | movzx edx, byte [wav_mode] |
||
615 | mov ecx, [blocks + edx * 4] |
||
139 | diamond | 616 | mov [fileinfo.bytes], ecx |
31 | halyavin | 617 | |
618 | mov esi, LOAD_BUFFER |
||
619 | mov edi, [buffers+eax*4] |
||
620 | push eax ;save buffer index |
||
621 | start_attempts: |
||
622 | mcall MF_SYSTREE, fileinfo |
||
623 | test eax, eax |
||
624 | jz @f |
||
139 | diamond | 625 | cmp eax, 6 |
626 | jz @f |
||
31 | halyavin | 627 | cmp [attempts],100 |
628 | je @f |
||
629 | inc [attempts] |
||
630 | jmp start_attempts |
||
139 | diamond | 631 | ; dpd eax |
632 | ; newline |
||
633 | ; dpd [fileinfo.first_block] |
||
634 | ; newline |
||
31 | halyavin | 635 | @@: |
636 | ; print " loaded!" |
||
637 | |||
638 | push eax ebx edx |
||
639 | mov eax,ecx |
||
640 | xor edx,edx |
||
641 | imul eax,10 |
||
642 | movzx ebx,[difference_of_frequency_2] |
||
643 | |||
644 | div ebx |
||
645 | mov ecx,eax |
||
646 | |||
647 | ; mov ebx,10 |
||
648 | ; mov eax,edx |
||
649 | ; xor edx,edx |
||
650 | ; div ebx |
||
651 | ; cmp edx,5 |
||
652 | ; jb temp_12_7 |
||
653 | ; inc ecx |
||
654 | ; temp_12_7: |
||
156 | diamond | 655 | ; cmp edx,0 |
656 | ; je temp_12_7 |
||
657 | ; inc ecx |
||
658 | ; temp_12_7: |
||
31 | halyavin | 659 | |
660 | pop edx ebx |
||
661 | mov eax,[esp+4] ;restore buffer index |
||
156 | diamond | 662 | and ecx, not 511 |
139 | diamond | 663 | add [fileinfo.first_byte], ecx ; +60Kb |
31 | halyavin | 664 | call [convert + edx * 4] |
665 | ;start fix for MM (4) |
||
666 | mov eax,[esp+4] ;restore buffer index |
||
667 | test eax,not 1 |
||
668 | jz .ok |
||
669 | print "buffer index out of range" |
||
670 | dpd eax |
||
671 | jmp .ret |
||
672 | .ok: |
||
673 | push ebp |
||
674 | mov ebp,[phys_wav_buffer1+eax*4] |
||
675 | mov edi,[buffers+eax*4] |
||
676 | mcall MF_INTERNAL_SERVICES,SET_PHYS_BUFFER,ebp,edi,60*1024 |
||
677 | pop ebp |
||
678 | .ret: |
||
679 | pop eax |
||
680 | add esp,4 ;pop buffer index |
||
681 | ;end fix for MM (4) |
||
682 | |||
683 | pop edi esi |
||
684 | ret |
||
685 | |||
686 | c8mono: |
||
687 | mov [type_of_conversion],1 |
||
688 | jmp for_all_type |
||
689 | |||
690 | c8mono_1: |
||
691 | lodsb |
||
692 | call c8mono_2 |
||
693 | push ax |
||
694 | shl eax,16 |
||
695 | pop ax |
||
696 | push eax |
||
697 | mov al,[esi] |
||
698 | call c8mono_2 |
||
699 | push ax |
||
700 | shl eax,16 |
||
701 | pop ax |
||
702 | mov ebx,eax |
||
703 | pop eax |
||
704 | jmp for_all_type_1 |
||
705 | |||
706 | c8mono_2: |
||
707 | sub al, 0x80 |
||
708 | cbw |
||
709 | imul ax, 255 |
||
710 | ret |
||
711 | |||
712 | c8stereo: |
||
713 | mov [type_of_conversion],2 |
||
714 | jmp for_all_type |
||
715 | |||
716 | c8stereo_1: |
||
717 | lodsb |
||
718 | call c8stereo_2 |
||
719 | shl eax,16 |
||
720 | lodsb |
||
721 | call c8stereo_2 |
||
722 | push eax |
||
723 | mov al,[esi] |
||
724 | call c8stereo_2 |
||
725 | shl eax,16 |
||
726 | mov al,[esi+1] |
||
727 | call c8stereo_2 |
||
728 | mov ebx,eax |
||
729 | pop eax |
||
730 | jmp for_all_type_1 |
||
731 | |||
732 | c8stereo_2: |
||
733 | sub al, 0x80 |
||
734 | cbw |
||
735 | imul ax, 255 |
||
736 | ret |
||
737 | |||
738 | c16mono: |
||
739 | mov [type_of_conversion],3 |
||
740 | jmp for_all_type |
||
741 | |||
742 | c16mono_1: |
||
743 | lodsw |
||
744 | push ax |
||
745 | shl eax,16 |
||
746 | pop ax |
||
747 | mov bx,[esi] |
||
748 | shl ebx,16 |
||
749 | mov bx,[esi] |
||
750 | jmp for_all_type_1 |
||
751 | |||
752 | c16stereo: |
||
753 | for_all_type: |
||
754 | xor edx,edx |
||
755 | mov eax, 15*1024*10 |
||
756 | movzx ebx,[difference_of_frequency_2] |
||
757 | xor edx,edx |
||
758 | div ebx |
||
759 | mov ecx,eax |
||
760 | |||
761 | ; mov ebx,10 |
||
762 | ; mov eax,edx |
||
763 | ; xor edx,edx |
||
764 | ; div ebx |
||
765 | ; cmp edx,5 |
||
766 | ; jb temp_12_6 |
||
767 | ; inc ecx |
||
768 | ; temp_12_6: |
||
769 | cmp edx,0 |
||
770 | je temp_12_6 |
||
771 | inc ecx |
||
772 | temp_12_6: |
||
773 | |||
774 | c16stereo_1: |
||
775 | mov [znak],0 |
||
776 | |||
777 | cmp [type_of_conversion],1 |
||
778 | je c8mono_1 |
||
779 | cmp [type_of_conversion],2 |
||
780 | je c8stereo_1 |
||
781 | cmp [type_of_conversion],3 |
||
782 | je c16mono_1 |
||
783 | lodsd |
||
784 | |||
785 | mov ebx,[esi] |
||
786 | for_all_type_1: |
||
787 | cmp eax,ebx |
||
788 | jne c16stereo_2 |
||
789 | inc [znak] |
||
790 | c16stereo_2: |
||
791 | push eax |
||
792 | push ecx |
||
793 | sub eax,ebx |
||
794 | push eax |
||
795 | shl eax,16 |
||
796 | movzx ebx,[difference_of_frequency] |
||
797 | inc ebx |
||
798 | xor edx,edx |
||
799 | div ebx |
||
800 | shr eax,16 |
||
801 | mov ecx,eax |
||
802 | pop eax |
||
803 | xor ax,ax |
||
804 | xor edx,edx |
||
805 | div ebx |
||
806 | shl eax,16 |
||
807 | mov cx,ax |
||
808 | mov ebx,ecx |
||
809 | pop ecx |
||
810 | pop eax |
||
811 | mov dl,[difference_of_frequency] |
||
812 | inc dl |
||
813 | @@: |
||
814 | temp_12: |
||
815 | cmp [difference_of_frequency_1],0 |
||
816 | je temp_12_3 |
||
817 | cmp [difference_of_frequency_1],5 |
||
818 | jne temp_12_4 |
||
819 | cmp [difference_of_frequency_4],2 |
||
820 | jne temp_12_3 |
||
821 | jmp temp_12_5 |
||
822 | temp_12_4: |
||
823 | cmp [difference_of_frequency_4],10 |
||
824 | jne temp_12_3 |
||
825 | |||
826 | temp_12_5: |
||
827 | |||
828 | cmp [znak],0 |
||
829 | jne temp_12_5_1 |
||
830 | sub eax,ebx |
||
831 | jmp temp_12_5_2 |
||
832 | temp_12_5_1: |
||
833 | add eax,ebx |
||
834 | temp_12_5_2: |
||
835 | |||
836 | |||
837 | stosd |
||
838 | inc [schetchik] |
||
839 | mov [difference_of_frequency_4],0 |
||
840 | temp_12_3: |
||
841 | cmp [znak],0 |
||
842 | jne temp_13 |
||
843 | sub eax,ebx |
||
844 | jmp temp_14 |
||
845 | temp_13: |
||
846 | add eax,ebx |
||
847 | |||
848 | temp_14: |
||
849 | cld |
||
850 | dec dl |
||
851 | jz temp_14_1 |
||
852 | stosd |
||
853 | inc [schetchik] |
||
854 | inc [difference_of_frequency_4] |
||
855 | jmp temp_12 |
||
856 | temp_14_1: |
||
857 | dec ecx |
||
858 | cmp ecx,0 |
||
859 | ; jnz c16stereo_1 |
||
860 | jg c16stereo_1 |
||
861 | newline |
||
862 | dph [schetchik] |
||
863 | temp_14_2: |
||
864 | cmp [schetchik],15360 |
||
865 | jge temp_14_3 |
||
866 | stosd |
||
867 | inc [schetchik] |
||
868 | jmp temp_14_2 |
||
869 | |||
870 | temp_14_3: |
||
871 | newline |
||
872 | dph [schetchik] |
||
873 | cmp [schetchik],15360 |
||
874 | je temp_14_4 |
||
875 | ; mov [edi-4],dword 0 |
||
876 | sub edi,4 |
||
877 | ; sub esi,4 |
||
878 | temp_14_4: |
||
879 | mov [schetchik],0 |
||
880 | ret |
||
881 | |||
882 | |||
883 | difference_of_frequency db 0 |
||
884 | difference_of_frequency_1 db 0 |
||
885 | difference_of_frequency_2 db 0 |
||
886 | difference_of_frequency_4 db 0 |
||
887 | schetchik dd 0 |
||
888 | znak db 0 |
||
889 | type_of_conversion db 0 |
||
890 | |||
891 | convert dd c8mono, c8stereo, c16mono, c16stereo |
||
139 | diamond | 892 | blocks dd 30*512, 60*512, 60*512, 120*512 |
31 | halyavin | 893 | |
894 | |||
895 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
896 | ;; get_my_address - get base address of the program in physical memory |
||
897 | ;; in: nothing |
||
898 | ;; out: eax = address |
||
899 | ;start fix for MM (8) |
||
900 | ;function shouldn't used. |
||
901 | ;get_my_address: |
||
902 | ; pushad |
||
903 | ; mcall MF_PROCINFO, procinfo, PN_MYSELF |
||
904 | ; popad |
||
905 | ; mov eax, [procinfo.memory_start] |
||
906 | ;ret |
||
907 | ;end fix for MM (8) |
||
908 | |||
909 | |||
910 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
911 | ;; set the last valid index to something other than we're currently playing |
||
912 | ;; so that we never end |
||
913 | ;; |
||
914 | ;; this routine just sets the last valid index to 1 less than the index |
||
915 | ;; that we're currently playing, thus keeping it in and endless loop |
||
916 | ;; input: none |
||
917 | ;; output: none |
||
918 | updateLVI: |
||
919 | push eax |
||
920 | call getCurrentIndex |
||
921 | ; dps "index " |
||
922 | ; dpd eax |
||
923 | ; newline |
||
924 | dec al |
||
925 | and al, INDEX_MASK |
||
926 | call setLastValidIndex |
||
927 | pop eax |
||
928 | ret |
||
929 | |||
930 | ;--------------------------------------------------------------------- |
||
931 | |||
932 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
933 | ;; returns AL = current index value |
||
934 | getCurrentIndex: |
||
935 | push edx |
||
936 | mov edx, PO_CIV_REG |
||
937 | call NABMBAR_read_byte |
||
938 | pop edx |
||
939 | ret |
||
940 | |||
941 | ;--------------------------------------------------------------------- |
||
942 | |||
943 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
944 | ;; input AL = index # to stop on |
||
945 | setLastValidIndex: |
||
946 | push edx |
||
947 | mov edx, PO_LVI_REG |
||
948 | call NABMBAR_write_byte |
||
949 | pop edx |
||
950 | ret |
||
951 | |||
952 | ;--------------------------------------------------------------------- |
||
953 | |||
954 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
955 | ;; print_info - outputs debug information |
||
956 | ;; in: nothing |
||
957 | ;; out: nothing |
||
958 | print_info: |
||
959 | dps "BUS: " |
||
960 | movzx eax, [bus] |
||
961 | dph eax |
||
962 | |||
963 | dps " DEVFN: " |
||
964 | movzx eax, [devfn] |
||
965 | dph eax |
||
966 | |||
967 | dps " IRQ: " |
||
968 | movzx eax, [AC97IRQ] |
||
969 | dpd eax |
||
970 | newline |
||
971 | |||
972 | |||
973 | dps "CODEC_POWER_CTRL: " |
||
974 | mov edx, CODEC_POWER_CTRL_REG |
||
975 | call NAMBAR_read_word |
||
976 | dph eax |
||
977 | dps " (bits 0-3 should be set)" |
||
978 | newline |
||
979 | |||
980 | mov edx, 0x28 |
||
981 | call NAMBAR_read_word |
||
982 | dph eax |
||
983 | dps " - supported features" |
||
984 | newline |
||
985 | mov edx, 0x2A |
||
986 | call NAMBAR_read_word |
||
987 | dph eax |
||
988 | dps " - config" |
||
989 | newline |
||
990 | mov edx, 0x2C |
||
991 | call NAMBAR_read_word |
||
992 | dph eax |
||
993 | dps " - PCM rate" |
||
994 | |||
995 | newline |
||
996 | ret |
||
997 | |||
998 | |||
999 | ;--------------------------------------------------------------------- |
||
1000 | ;--- DATA OF PROGRAM ----------------------------------------------- |
||
1001 | ;--------------------------------------------------------------------- |
||
1002 | volume dd 15 |
||
1003 | |||
139 | diamond | 1004 | attrinfo: |
1005 | dd 5 |
||
1006 | dd 0 |
||
1007 | dd 0 |
||
1008 | dd 0 |
||
1009 | dd fileattr |
||
1010 | db 0 |
||
1011 | dd textbox_string |
||
1012 | |||
31 | halyavin | 1013 | fileinfo: |
139 | diamond | 1014 | .mode dd 0 ; READ |
1015 | .first_byte dd 0 |
||
1016 | dd 0 |
||
1017 | .bytes dd 60*1024 ; 60 Kb |
||
31 | halyavin | 1018 | .dest dd LOAD_BUFFER ;file_data |
1019 | ; db "/HD/1/WINDOWS/MEDIA/WICEB7~1.WAV",0 |
||
1020 | ;sz textbox_string, "/hd/1/testmuz/menuet11.wav",0 |
||
139 | diamond | 1021 | textbox_string: |
31 | halyavin | 1022 | ;--------------------------------------------------------------------- |
1023 | |||
1024 | IMAGE_END: ; end of program's image |
||
139 | diamond | 1025 | rb 257 |
1026 | ; rb 257-textbox_string.size |
||
31 | halyavin | 1027 | ; textbox_string.size |
1028 | |||
1029 | ;--------------------------------------------------------------------- |
||
1030 | |||
1031 | device_id dd ? ; (device_id << 16) + vendor_id |
||
1032 | lastbus db ? ; pci coordinates |
||
1033 | bus db ? |
||
1034 | devfn db ? |
||
1035 | |||
1036 | AC97ICH4 db ? ; Intel ICH4 codec flag |
||
1037 | SI7012 db ? ; SiS SI7012 codec flag |
||
1038 | NAMBAR dw ? ; Audio Mixers Registers (base) |
||
1039 | NABMBAR dw ? ; Bus Master Registers (base) |
||
1040 | |||
1041 | AC97IRQ db ? ; Interrupt request |
||
1042 | AC97INT db ? ; Interrupt pin |
||
1043 | |||
1044 | wav_mode db ? ; bits per sample & channels |
||
1045 | |||
1046 | ;--------------------------------------------------------------------- |
||
1047 | |||
1048 | ST_DONE = 0x0 ; for interacting with player's window |
||
1049 | ST_PLAY = 0x1 |
||
1050 | ST_EXIT = 0x2 |
||
1051 | ST_STOP = 0x4 |
||
1052 | |||
1053 | status db ? |
||
1054 | |||
139 | diamond | 1055 | fileattr: rb 40 |
1056 | |||
31 | halyavin | 1057 | ;--------------------------------------------------------------------- |
1058 | phys_bdl_buffer rd 1 |
||
1059 | phys_wav_buffer1 rd 1 |
||
1060 | phys_wav_buffer2 rd 1 |
||
1061 | align 32 |
||
1062 | |||
1063 | |||
1064 | ; Buffer Descriptors List |
||
1065 | ; ___________________________ |
||
1066 | ; | physical address | dword |
||
1067 | ; |_________________________| |
||
1068 | ; | attr | length | dword max. length = 65535 samples |
||
1069 | ; |_________________________| |
||
1070 | |||
1071 | BDL_BUFFER: |
||
1072 | rb 32*8 ; 32 descriptors, 8 bytes each |
||
1073 | |||
1074 | |||
1075 | ;--------------------------------------------------------------------- |
||
1076 | |||
1077 | file_data: |
||
1078 | |||
1079 | WAV_BUFFER1: |
||
1080 | rb 60 * 1024 ; 60 Kb |
||
1081 | |||
1082 | WAV_BUFFER2: |
||
1083 | rb 60 * 1024 |
||
1084 | |||
1085 | LOAD_BUFFER: |
||
1086 | rb 60 * 1024 |
||
1087 | |||
1088 | ;--------------------------------------------------------------------- |
||
1089 | |||
1090 | procinfo process_information |
||
1091 | |||
1092 | work_area: |
||
1093 | rb 0x10000 |
||
1094 | |||
1095 | ;--------------------------------------------------------------------- |
||
1096 | |||
1097 | rb 0x800 |
||
1098 | thread_stack: |
||
1099 | |||
1100 | rb 0x1000 ; for stack |
||
1101 | STACK_P: |
||
1102 | |||
1103 | MEMORY_END:><> |