; ; SOUND BLASTER ; ; Compile with FASM for Menuet ; include 'lang.inc' include '..\..\..\..\macros.inc' use32 org 0x0 db 'MENUET01' ; 8 byte id dd 0x01 dd START ; program start dd I_END ; program image size dd 0x80000 ; required amount of memory dd 0xfff0 ; stack position dd 0,0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vol_data dd 0x40000 playposition dd 0x20000 next_tic dd 0x0 onoff dd 0x0 pause_between_songs dd 100 delay dd 100 repeat_song db 0 mono_stereo dd 1 ; 0x10000 data from hd ; 0x20000 play position for sb ; 0x40000 volume indicator data START: ; start of execution call draw_window ; at first, draw the window mov eax,26 mov ebx,9 mcall mov [next_tic],eax still: mov [delay],145 cmp [mono_stereo],2 jne no_stereo mov [delay],73 no_stereo: mov eax,55 mov ebx,2 mov ecx,0 mov edx,[mono_stereo] mcall mov eax,23 ; wait here for event mov ebx,1 mcall cmp eax,0 jne do_task still2: cmp [onoff],0 je still mov eax,26 mov ebx,9 mcall mov ebx,[next_tic] cmp eax,ebx jge play_wave_block mov edi,[next_tic] sub edi,eax mov eax,[delay] sub eax,edi mov edi,eax call draw_volume jmp still do_task: cmp eax,1 ; redraw request ? je red cmp eax,2 ; key in buffer ? je key cmp eax,3 ; button in buffer ? je button cmp eax,16+4 jne no_irman mov eax,42 mov ebx,4 mcall dec [ir_count] cmp bl,140 jne no_first mov [ir_count],3 no_first: cmp [ir_count],0 jne no_irman call give_wav cmp bl,215 je play mov ah,4 ;; cmp bl,55 ;; je rev mov ah,3 ;;; cmp bl,183 ;;; je rev cmp bl,127 jne no_block_dec add [block],65536/512*10 no_block_dec: cmp bl,191 jne no_block_inc sub [block],65536/512*10 no_block_inc: jmp still no_irman: jmp still play_wave_block: mov eax,55 ; load wave mov ebx,0 mov ecx,[playposition] mcall mov eax,55 ; play wave mov ebx,1 mcall mov eax,26 mov ebx,9 mcall add eax,[delay] mov [next_tic],eax call draw_wave call read_wav jmp still red: ; redraw call draw_window jmp still key: ; key mov eax,2 ; just read it and ignore mcall jmp still2 button: ; button mov eax,17 ; get id mcall cmp ah,6 jne no_ir call enable_ir jmp still no_ir: cmp ah,7 jne no_file_name call read_string jmp still no_file_name: cmp ah,2 ; button id=2 jne noplay play: mov eax,[onoff] not eax and eax,1 mov [onoff],eax mov [playposition],0x20000 mov [block],2 call read_header call read_wav ; mov [next_tic],0 jmp still noplay: cmp ah,3 jb no_rev cmp ah,4 jg no_rev sub ah,3 shr eax,8 imul eax,4000 sub eax,2000 add [block],eax cmp [block],0x0f000000 jb block_ok mov [block],2 block_ok: call display_progress jmp still2 no_rev: cmp ah,5 ; repeat song ? jne no_repeat mov al,[repeat_song] inc al and eax,1 mov [repeat_song],al shl eax,2 mov eax,[repeat_text+eax] mov [text+40*5+31],eax call draw_window jmp still repeat_text: db 'OFF ON ' no_repeat: cmp ah,1 jne noclose cmp [infrared_enabled],1 jne no_dis mov eax,45 mov ebx,1 mov ecx,4 mcall mov eax,46 mov ebx,1 mov ecx,0x3f0 mov edx,0x3ff mcall no_dis: mov eax,-1 ; close this program mcall noclose: jmp still2 give_wav: pusha mov eax,55 mov ebx,0 mov ecx,0x20000 mcall popa ret ir_count db 0x0 drop_rate dd 100 draw_volume: ; edi = tic to show ret pusha add edi,[vol_data] mov eax,[drop_rate] cmp eax,2 jb no_drop sub eax,2 no_drop: mov [drop_rate],eax movzx eax,byte [edi] cmp eax,[drop_rate] jge drop_ok mov eax,[drop_rate] mov [edi],al jmp fixed_drop drop_ok: mov [drop_rate],eax fixed_drop: mov eax,13 mov ebx,320*65536+20 mov ecx,50*65536+1 movzx edx,byte [edi] shr edx,1 mov esi,128 sub esi,edx add ecx,esi mov edx,0x00ff00 mcall mov eax,13 mov ebx,320*65536+20 movzx edx,byte [edi] shr edx,1 mov ecx,edx add ecx,(50+128)*65536+1 shl edx,16 sub ecx,edx mov edx,0xff0000 mcall popa ret read_header: pusha mov dword [file_info+4],0 ; block to read mov dword [file_info+8],1 ; blocks to read mov dword [file_info+12],0x10000+1024 ; return data pointer mov dword [file_info+16],0x60000 ; work area for os mov eax,58 mov ebx,file_info mcall movzx eax,byte [0x10000+1024+12+10] mov [channels],eax movzx eax,byte [0x10000+1024+12+20] mov [bytes_per_sample],eax cmp [0x10000+1024],dword 'RIFF' jne unknownformat cmp [0x10000+1024+8],dword 'WAVE' jne unknownformat mov [addb],128 cmp [channels],1 je addb_ok mov [addb],256 addb_ok: cmp [bytes_per_sample],1 je addb_ok2 mov [addb],256 addb_ok2: mov [bmul],256 cmp [addb],256 je bmok mov [bmul],512 bmok: cmp [bytes_per_sample],4 jne no16s mov [addb],512 ;mono_stereo mov ecx,[mono_stereo] shr ecx,1 shr [addb],cl mov [bmul],128 ;mono_stereo shl [bmul],cl no16s: popa ret unknownformat: mov [onoff],0 call display_progress mov eax,13 mov ebx,190*65536+10 mov ecx,104*65536+10 mov edx,0xff0000 mcall pusha mov eax,5 mov ebx,[pause_between_songs] mcall popa mov eax,13 mov edx,0x000000 mcall popa ret channels dd 0x0 ; 1=mono, 2 stereo bytes_per_sample dd 0x0 ; 1=8 2=2*8/16 4=16 buffer dd 0x20000 block dd 0x2 addb dd 256 ; 128 = mono 8 bit , 256 = stereo 8 bit/16 bit mono bmul dd 0x0 ; 512 = mono 8 bit , 256 = stereo 8 bit/16 bit mono file_size dd 100 current_play dd wavfile+40*0 read_wav: pusha new_file: mov edx,[block] newread: mov dword [file_info+4],edx ; block to read mov dword [file_info+8],1 ; blocks to read mov dword [file_info+12],0x10000+1024 ; return data pointer mov dword [file_info+16],0x60000 ; work area for os mov eax,58 mov ebx,file_info mcall pusha mov eax,11 mcall cmp eax,1 jne no_wd call draw_window no_wd: popa pusha mov eax,38 mov ebx,1*65536+128 mov ecx,71*65536+71 add ebx,25*65536+25 mov edx,0x555555 ; mcall mov eax,38 mov ebx,[esp+32-12] and ebx,65536/512 -1 or ebx,1*65536 add ebx,25*65536+25 mov ecx,71*65536+71 mov edx,0x999999 ; mcall popa cmp eax,0 je conp movzx eax,byte [repeat_song] inc eax and eax,1 imul eax,40 mov [current_play],wavfile play_ok: mov [onoff],1 mov [playposition],0x20000 mov [block],20 mov eax,5 mov ebx,[pause_between_songs] add ebx,[delay] mcall call read_header cmp [onoff],0 je noplay2 cmp [repeat_song],0 je noplay2 call display_progress jmp new_file noplay2: mov [onoff],0 mov [block],2 call display_progress popa ret conp: mov [file_size],ebx mov esi,0x10000+1024 ; 8 bit stereo & 16 bit mono mov edi,edx sub edi,[block] imul edi,[bmul] add edi,[buffer] mov ecx,512 movedata: mov al,[esi+1] cmp [bytes_per_sample],4 ; for 16 bit stereo jne no_16_stereo mov al,[esi+1] add al,128 no_16_stereo: cmp [bytes_per_sample],1 ; for 16 bit mono je no_16_mono cmp [channels],2 je no_16_mono mov al,[esi+1] add al,128 no_16_mono: mov [edi],al mov eax,[bytes_per_sample] cmp [mono_stereo],1 je bps1 mov eax,[bytes_per_sample] push ecx mov ecx,[mono_stereo] dec ecx shr eax,cl pop ecx bps1: add esi,eax ; 2;[bytes_per_sample] ; / mono_stereo add edi,1 loop movedata add edx,1 mov ecx,[block] add ecx,[addb] cmp edx,ecx jbe newread mov ecx,[addb] add [block],ecx call display_progress rewr: popa call set_vol_data ret set_vol_data: ; ret pusha mov eax,65536 xor edx,edx mov ebx,[delay] div ebx push eax mov esi,[playposition] mov edi,[vol_data] mov ecx,[delay] svd: mov eax,0 mov edx,100 svd3: movzx ebx,byte [esi] cmp ebx,128 jge svd2 mov ebx,0 svd2: sub ebx,128 shl ebx,1 cmp ebx,ebp jbe svd4 mov edx,ebx svd4: inc esi inc eax cmp eax,[esp] jb svd3 mov [edi],dl inc edi loop svd pop eax popa ret addr dd 0x0 ya dd 0x0 read_string: mov [onoff],0 mov [addr],wavfile mov [ya],30 mov edi,[addr] mov al,'_' mov ecx,32 rep stosb call print_text mov edi,[addr] f11: mov eax,10 mcall cmp eax,2 jne read_done mov eax,2 mcall shr eax,8 cmp eax,13 je read_done cmp eax,8 jnz nobsl cmp edi,[addr] jz f11 sub edi,1 mov [edi],byte '_' call print_text jmp f11 nobsl: cmp eax,dword 31 jbe f11 cmp eax,dword 95 jb keyok sub eax,32 keyok: mov [edi],al call print_text add edi,1 mov esi,[addr] add esi,32 cmp esi,edi jnz f11 read_done: mov ecx,[addr] add ecx,38 sub ecx,edi mov eax,0 cld rep stosb call print_text ret print_text: display_progress: pusha mov eax,13 ; gray progress bar mov ebx,25*65536+215 mov ecx,61*65536+8 mov edx,[border] mcall cmp [onoff],1 je yes_playing mov [block],0 mov [file_size],100*512 yes_playing: mov eax,[block] ; yellow progress bar imul eax,214 xor edx,edx mov ebx,[file_size] shr ebx,9 or ebx,1 div ebx mov ebx,eax and ebx,0xff mov eax,13 add ebx,25*65536 mov ecx,61*65536+1 mov edx,[drawp] newbar: mcall add edx,0x101010 add ecx,1*65536 cmp ecx,65*65536 jb newbar newbar2: mcall sub edx,0x101010 add ecx,1*65536 cmp ecx,69*65536 jb newbar2 mov eax,[block] imul eax,214-30 xor edx,edx mov ebx,[file_size] shr ebx,9 or ebx,1 div ebx mov ebx,eax shl ebx,16 add ebx,25*65536+30 mov ecx,61*65536+9 mov edx,0xeeeeff mov eax,13 mov edi,5 newb: ; mcall add ebx,1*65536-2 add ecx,1*65536-2 sub edx,0x332211;3366aa dec edi jnz newb noyellow: mov esi,[current_play] mov edi,now_playing mov ecx,40 cld rep movsb mov eax,13 mov ebx,42*65536+33*6 mov ecx,114*65536+11 mov edx,0x000000 mcall mov eax,4 mov ebx,42*65536+117 mov ecx,[textc] mov edx,now_playing mov esi,38 mcall popa ret shape_window: ret pusha mov eax,50 mov ebx,0 mov ecx,shape_reference mcall mov eax,50 mov ebx,1 mov ecx,4 mcall popa ret shape_reference: times 1 db 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0 times 9 db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 infrared_enabled db 0x0 enable_ir: pusha mov eax,46 mov ebx,0 mov ecx,0x3f0 mov edx,0x3ff mcall mov eax,45 mov ebx,0 mov ecx,4 mcall mov eax,40 mov ebx,10000b shl 16 + 111b mcall mov [infrared_enabled],1 popa ret ; ********************************************* ; ******* WINDOW DEFINITIONS AND DRAW ******** ; ********************************************* draw_window: pusha inc [next_tic] mov eax,12 ; function 12:tell os about windowdraw mov ebx,1 ; 1, start of draw mcall ; DRAW WINDOW mov eax,0 ; function 0 : define and draw window mov ebx,100*65536+320 ; [x start] *65536 + [x size] mov ecx,100*65536+140 ; [y start] *65536 + [y size] mov edx,[bgr] or edx,0x14000000 ; color of work area RRGGBB,8->color gl mov edi,title ; WINDOW LABEL mcall mov eax,8 ; START/STOP - id 2 mov ebx,24*65536+77 mov ecx,80*65536+16 mov edx,2 mov esi,[border] mcall inc edx ; << / >> - id 3 , 4 add ebx,86*65536-57 mov eax,8 mcall inc edx add ebx,24*65536 mov eax,8 mcall mov eax,8 ; REPEAT add ebx,29*65536+54 inc edx mcall mov eax,8 ; enable infrared add ebx,98*65536-33 add ecx,10*65536+10 inc edx mcall pusha mov eax,8 mov ebx,25*65536+9 mov ecx,115*65536+9 inc edx mcall popa mov eax,4 shr ecx,16 mov bx,cx add ebx,2*65536+4 mov ecx,0xffffff mov edx,infrared_text mov esi,10 mcall add ebx,11 add edx,10 mov eax,4 mcall mov ebx,25*65536+35 ; draw info text with function 4 mov ecx,[textc] mov edx,text mov esi,40 newline: mov eax,4 mcall add ebx,10 add edx,40 cmp [edx],byte 'x' jne newline call display_progress call draw_wave mov eax,12 mov ebx,2 mcall popa ret draw_wave: ; ret pusha mov eax,13 mov ebx,260*65536+43 mov ecx,42*65536+32 mov edx,[border] mcall mov esi,[playposition] mov ebx,260 npix: mov eax,1 inc ebx movzx ecx,byte [esi] shr ecx,3 add ecx,42 mov edx,[drawc];0x2255aa mcall add esi,2 cmp ebx,300 jbe npix popa ret ; DATA AREA infrared_text: db 'IRMAN INFRAR ' textc dd 0xffffff bgr dd 0x00000000 drawc dd 0x2255aa drawp dd 0x8011aa border dd 0x5577aa text: db 'Define SB, HD & partition with setup ' db 'If clipping change "delay" in source ' db ' ' db ' ' db ' ' db ' START/STOP << >> REPEAT:OFF ' db 'x <- END MARKER, DO NOT DELETE ' now_playing: db ' ' db 'xx ' file_info: dd 0 ; read dd 0 dd 0 dd 0 dd 0 wavfile: db '/HD/1/MENUET/MUSIC/FILE7.WAV',0 db ' ' title db ' WAVE PLAYER : 8b Mono - 16b Stereo',0 I_END: