0,0 → 1,609 |
; |
; KolibriOS system mixer. Version 0.2 |
; |
; Author: Asper |
; Date of issue: 15.08.2010 |
; Compiler: FASM |
; Target: KolibriOS |
; |
|
use32 |
org 0x0 |
|
db 'MENUET01' ; 8 byte id |
dd 38 ; required os |
dd STARTAPP ; program start |
dd I_END ; program image size |
dd I_MEM ; required amount of memory |
dd I_MEM ; stack heap |
dd 0x0, 0x0 |
|
include 'aspAPI.inc' |
include '../../macros.inc' |
;include 'string.inc' |
|
|
;include 'debug.inc' |
|
DEBUG equ 0 ;1 |
|
SRV_GETVERSION equ 0 |
DEV_PLAY equ 1 |
DEV_STOP equ 2 |
DEV_CALLBACK equ 3 |
DEV_SET_BUFF equ 4 |
DEV_NOTIFY equ 5 |
DEV_SET_MASTERVOL equ 6 |
DEV_GET_MASTERVOL equ 7 |
DEV_GET_INFO equ 8 |
|
|
;C_UNKNOWN equ ? |
C_BLACK equ 0x000000 |
C_GREY equ 0xB0B0B0 ; 0xC0C0C0 |
C_BLUE equ 0x1070D0 |
C_GREEN equ 0x70D010 |
C_RED equ 0xD01010 |
C_ORANGE equ 0xD07010 |
C_YELLOW equ 0xE0E010 |
C_PURPLE equ 0x7010D0 |
C_PINK equ 0xFF00FF |
;C_RESERVED equ ? |
C_WHITE equ 0xFFFFFF |
;C_OTHER equ ? |
|
|
C_KEYCOLOR1 equ 0x0050D250 ; Control button color 1 |
C_KEYCOLOR2 equ 0x00CBE1E1 ; Control button color 2 |
C_TEXTCOLOR equ 0x80000000 ; Button caption color |
BUT_W equ 20 |
BUT_H equ 20 |
;WIN_X equ 30000 ; I hope nobody has screen |
;WIN_Y equ 30000 ; with such a big resolution :) |
WIN_W equ 250;390 |
WIN_H equ 180 |
WIN_COLOR equ 0x505050 ;0x0099BB |
WIN_X_CENTER equ WIN_W/2 |
|
FIRST_CTRL_BUTTON_ID equ 7 |
MAX_CONTROLS_NUM equ 15 ; Bad bounding :/ |
|
struc CONTROL |
{ |
.level dw ? |
.num_steps dw ? |
} |
|
; widget node for parsing |
;struc HDA_GNODE |
;{ |
; .nid dw ? ;NID of this widget |
; .nconns dw ? ;number of input connections |
; .conn_list dd ? |
; .slist dw ? ;temporay list |
; dw ? |
; |
; .wid_caps dd ? ;widget capabilities |
; .type db ? ;widget type |
; .pin_ctl db ? ;pin controls |
; .checked db ? ;the flag indicates that the node is already parsed |
; .pin_caps dd ? ;pin widget capabilities |
; .def_cfg dd ? ;default configuration |
; .amp_out_caps dd ? ;AMP out capabilities |
; .amp_in_caps dd ? ;AMP in capabilities |
; .next dd ? ; struct list_head list |
; .sizeof: |
;} |
|
;virtual at 0 |
; HDA_GNODE HDA_GNODE |
;end virtual |
|
STARTAPP: |
; Initialize memory |
; mcall 68, 11 |
; or eax,eax |
; jz close_app |
|
|
; Load sound system driver |
mov eax, 68 |
mov ebx, 16 |
mov ecx, drivername |
int 0x40 |
mov [hDriver], eax |
test eax, eax |
jnz @f |
loaderr: |
if DEBUG |
print "Can't load driver" |
end if |
jmp close_app |
@@: |
mov [is_hda], 1 |
call GetDriverVer |
mov eax, [driver_ver] |
cmp ax, 0x11DA |
je @f |
mov [is_hda], 0 |
@@: |
cmp [is_hda], 0 |
je .init_ac97_controls |
; Init volume controls |
stdcall GetMasterVol, 0 |
mov ebx, eax |
mov [LVolume.level], ax |
shr eax, 16 |
mov [LVolume.num_steps], ax |
stdcall GetMasterVol, 1 |
mov [RVolume.level], ax |
shr eax, 16 |
mov [RVolume.num_steps], ax |
jmp .controls_init_complete |
; Asper: temporary workaround on ac97 codecs [ |
.init_ac97_controls: ;jmp @f |
mov [is_hda], 0 |
mov [LVolume.num_steps], 31 |
mov [RVolume.num_steps], 31 |
mov ax, [LVolume.level] |
call convert_ac97_volume_to_level |
mov [LVolume.level], ax |
mov [RVolume.level], ax |
; Asper: temporary workaround on ac97 codecs ] |
.controls_init_complete: |
if DEBUG |
print "Left level" |
movzx eax, [LVolume.level] |
dph eax |
newline |
print "Left num_steps" |
movzx eax, [LVolume.num_steps] |
dph eax |
newline |
print "Right level" |
movzx eax, [RVolume.level] |
dph eax |
newline |
print "Right num_steps" |
movzx eax, [RVolume.num_steps] |
dph eax |
newline |
end if |
|
mcall 66, 1, 1 ; Set keyboard mode to get scancodes. |
|
mcall 37,0 |
mov cx,ax |
shl ecx,16 |
mov cx,WIN_H |
mov ebx,eax |
mov bx,WIN_W |
|
red: |
call draw_window |
|
still: |
mcall 10 ; Wait for an event in the queue. |
|
cmp al,1 ; redraw request ? |
jz red |
cmp al,2 ; key in buffer ? |
jz key |
cmp al,3 ; button in buffer ? |
jz button |
|
jmp still |
|
key: |
mcall 2 |
|
cmp ah, 1 ;Esc |
je close_app |
|
; cmp ah, 5 ; '4' |
; jne @f |
; stdcall GetMasterVol, 0 |
; jmp still |
; @@: |
; |
; cmp ah, 6 ; '5' |
; jne @f |
; stdcall GetMasterVol, 1 |
; jmp still |
; @@: |
|
; cmp ah, 8 ; '7' |
; jne @f |
; call GetDriverVer |
; jmp still |
; @@: |
|
;Left channel Up |
cmp ah, 71 ; 'Home' |
jne @f |
movzx eax, [LVolume.level] |
inc ax |
cmp ax, [LVolume.num_steps] |
jg still |
mov [LVolume.level], ax |
call convert_level_to_ac97_volume ;Asper: temporary workaround on ac97 |
stdcall SetMasterVol, 0, eax |
jmp red |
@@: |
|
;Left channel Down |
cmp ah, 79 ; 'End' |
jne @f |
movzx eax, [LVolume.level] |
dec ax |
cmp ax, 0 |
jl still |
mov [LVolume.level], ax |
call convert_level_to_ac97_volume ;Asper: temporary workaround on ac97 |
stdcall SetMasterVol, 0, eax |
jmp red |
@@: |
|
;Right channel Up |
cmp ah, 73 ; 'PageUp' |
jne @f |
movzx eax, [RVolume.level] |
inc ax |
cmp ax, [RVolume.num_steps] |
jg still |
mov [RVolume.level], ax |
call convert_level_to_ac97_volume ;Asper: temporary workaround on ac97 |
movzx edx, [is_hda] |
stdcall SetMasterVol, edx, eax |
jmp red |
@@: |
|
;Right channel Down |
cmp ah, 81 ; 'PageDown' |
jne @f |
movzx eax, [RVolume.level] |
dec ax |
cmp ax, 0 |
jl still |
mov [RVolume.level], ax |
call convert_level_to_ac97_volume ;Asper: temporary workaround on ac97 |
.RVdown: |
movzx edx, [is_hda] |
stdcall SetMasterVol, edx, eax |
jmp red |
@@: |
|
jmp still |
|
button: |
mcall 17 ; Get pressed button code |
cmp ah, 1 ; Test x button |
je close_app |
jmp still |
|
|
draw_window: |
;start_draw_window WIN_X,WIN_Y,WIN_W,WIN_H,WIN_COLOR,caption;, 12;labellen-labelt |
mcall 0,,,34000000h+WIN_COLOR,,caption |
|
|
stdcall draw_button, WIN_X_CENTER-BUT_W-55, 30+BUT_H*0,BUT_W,BUT_H,2,C_PINK,aNoText,0,0 |
stdcall draw_button, WIN_X_CENTER-BUT_W-55, 30+BUT_H*1+10,BUT_W,BUT_H,3,C_GREEN,aNoText,0,0 |
stdcall draw_button, WIN_X_CENTER-BUT_W-55, 30+BUT_H*2+20,BUT_W,BUT_H,4,C_BLUE,aNoText,0,0 |
|
stdcall draw_button, WIN_X_CENTER-BUT_W/2+55, 30+BUT_H*0,BUT_W,BUT_H,5,C_GREY,aNoText,0,0 |
stdcall draw_button, WIN_X_CENTER-BUT_W/2+55, 30+BUT_H*1+10,BUT_W,BUT_H,6,C_BLACK,aNoText,0,0 |
stdcall draw_button, WIN_X_CENTER-BUT_W/2+55, 30+BUT_H*2+20,BUT_W,BUT_H,7,C_ORANGE,aNoText,0,0 |
|
movzx eax, [LVolume.level] |
movzx edx, [LVolume.num_steps] |
stdcall draw_volume_control, WIN_X_CENTER-BUT_W-25, 20, 110, aLVolume, C_BLACK, eax, edx |
movzx eax, [RVolume.level] |
movzx edx, [RVolume.num_steps] |
stdcall draw_volume_control, WIN_X_CENTER+25, 20, 110, aRVolume, C_BLACK, eax, edx |
|
stdcall rectangle, WIN_X_CENTER-BUT_W-56, 29+BUT_H*0, BUT_W+2, BUT_H+2, C_BLACK |
stdcall rectangle, WIN_X_CENTER-BUT_W-56, 29+BUT_H*1+10, BUT_W+2, BUT_H+2, C_BLACK |
stdcall rectangle, WIN_X_CENTER-BUT_W-56, 29+BUT_H*2+20, BUT_W+2, BUT_H+2, C_BLACK |
|
stdcall rectangle, WIN_X_CENTER-BUT_W/2+54, 29+BUT_H*0, BUT_W+2, BUT_H+2, C_BLACK |
stdcall rectangle, WIN_X_CENTER-BUT_W/2+54, 29+BUT_H*1+10, BUT_W+2, BUT_H+2, C_GREEN |
stdcall rectangle, WIN_X_CENTER-BUT_W/2+54, 29+BUT_H*2+20, BUT_W+2, BUT_H+2, C_BLACK |
|
stdcall rectangle, WIN_X_CENTER-BUT_W-57, 28+BUT_H*0, BUT_W+4, BUT_H+4, C_PINK |
stdcall rectangle, WIN_X_CENTER-BUT_W-57, 28+BUT_H*1+10, BUT_W+4, BUT_H+4, C_GREEN |
stdcall rectangle, WIN_X_CENTER-BUT_W-57, 28+BUT_H*2+20, BUT_W+4, BUT_H+4, C_BLUE |
|
stdcall rectangle, WIN_X_CENTER-BUT_W/2+53, 28+BUT_H*0, BUT_W+4, BUT_H+4, C_GREY |
stdcall rectangle, WIN_X_CENTER-BUT_W/2+53, 28+BUT_H*1+10, BUT_W+4, BUT_H+4, C_BLACK; |
stdcall rectangle, WIN_X_CENTER-BUT_W/2+53, 28+BUT_H*2+20, BUT_W+4, BUT_H+4, C_ORANGE |
|
|
end_draw_window |
ret |
|
|
|
proc draw_volume_control stdcall, x:dword, y:dword, ysize:dword, name:dword, textcolor:dword, step:dword, max_steps:dword |
mov ebx, [x] |
mov edx, [y] |
mov eax, [ysize] |
stdcall bar, ebx, edx, 10, eax, C_GREEN |
mov ecx, [max_steps] |
cmp ecx, [step] |
je .l2 |
|
push eax edx |
mov cl, byte [max_steps] |
test cl, cl |
jnz @f |
mov ecx, [ysize] |
jmp .l1 |
@@: |
div cl |
mov cl, byte [step] |
mul cl |
mov ecx, [ysize] |
sub ecx, eax |
.l1: |
pop edx eax |
stdcall bar, ebx, edx, 10, ecx, C_RED |
.l2: |
dec ebx |
dec edx |
inc eax |
stdcall rectangle, ebx, edx, 11, eax, C_BLACK |
|
|
add edx, eax |
add edx, 10 |
sub ebx, 8 |
stdcall outtextxy, ebx, edx, [name], 0, C_GREEN or 0x80000000 |
ret |
endp |
|
;____________________________________ |
GetDriverVer: |
push ebx ecx |
mov [ioctl_code], SRV_GETVERSION |
and [inp_size], 0 |
mov [outp_size], 4 |
mov [output], driver_ver |
mcall 68,17,ioctl |
test eax, eax |
jnz loaderr |
if DEBUG |
push eax |
dps "1.) Driver version = " |
dph [driver_ver] |
newline |
pop eax |
end if |
pop ecx ebx |
ret |
|
;____________________________________ |
Stop: |
and [ioctl_code], DEV_STOP |
and [inp_size], 4 |
mov [input], 0 ;? stream |
mov [outp_size], 0 |
mov [output], 0 |
mcall 68,17,ioctl |
test eax, eax |
jnz loaderr |
if DEBUG |
print "Stop device" |
end if |
ret |
|
;____________________________________ |
proc GetMasterVol stdcall, channel:dword |
push ebx ecx |
mov [ioctl_code], DEV_GET_MASTERVOL |
mov [inp_size], 1 |
mov eax, [channel] |
mov [input], eax |
mov [outp_size], 4 |
mov [output], master_vol |
mcall 68,17,ioctl |
if DEBUG |
push eax |
dps "Get Master volume = " |
dph [master_vol] |
newline |
pop eax |
end if |
mov eax, [master_vol] |
pop ecx ebx |
ret |
endp |
;____________________________________ |
proc SetMasterVol stdcall, channel:dword, val:dword |
push ebx ecx |
mov [ioctl_code], DEV_SET_MASTERVOL |
mov [inp_size], 4 |
mov eax, [channel] |
shl eax, 24 |
or eax, [val] |
mov [master_vol], eax |
mov [input], master_vol |
mov [outp_size], 0 |
mcall 68,17,ioctl |
if DEBUG |
push eax |
dps "Set Master volume = " |
dph [val] |
dps " ch = " |
dph [channel] |
newline |
pop eax |
end if |
pop ecx ebx |
ret |
endp |
|
;____________________________________ |
;GetDevInfo: ; Get pins configurations or controls |
; mov [ioctl_code], DEV_GET_INFO |
; and [inp_size], 0 |
; mov [outp_size], 9*4 |
; mov [output], ctrl_info |
; mcall 68,17,ioctl |
; if DEBUG |
; push eax |
; print "CTRL_INFO" |
; dps ".pci_cmd = " |
; dph [ctrl_info] |
; newline |
; dps ".irq = " |
; dph [ctrl_info+4] |
; newline |
; ;dps ".glob_cntrl = " |
; dps ".VIA_REG_OFFSET_CONTROL = " |
; dph [ctrl_info+8] |
; newline |
; ;dps ".glob_sta = " |
; dps ".VIA_REG_OFFSET_STATUS = " |
; dph [ctrl_info+12] |
; newline |
; ;dps ".codec_io_base = " |
; dps ".VIA_REG_OFFSET_TABLE_PTR = " |
; dph [ctrl_info+16] |
; newline |
; dps ".ctrl_io_base = " |
; dph [ctrl_info+20] |
; newline |
; ;dps ".codec_mem_base = " |
; dps ".VIA_REG_OFFSET_STOP_IDX = " |
; dph [ctrl_info+24] |
; newline |
; ;dps ".ctrl_mem_base = " |
; dps ".VIA_REG_OFFSET_CURR_COUNT = " |
; dph [ctrl_info+28] |
; newline |
; dps ".codec_id = " |
; dph [ctrl_info+32] |
; newline |
; pop eax |
; end if |
;ret |
|
|
convert_level_to_ac97_volume: |
push ebx ecx edx |
cmp [is_hda], 0 |
jne .not_ac97 |
|
mov [LVolume.level], ax |
mov [RVolume.level], ax |
|
mov bx, ax |
mov ax, [LVolume.num_steps] |
sub ax, bx |
mov cx, 150 |
mul cx |
neg eax |
.not_ac97: |
pop edx ecx ebx |
ret |
|
|
convert_ac97_volume_to_level: |
push ebx ecx edx |
cmp [is_hda], 0 |
jne .not_ac97 |
|
neg eax |
mov cx, 150 |
div cx |
mov bx, ax |
mov ax, [LVolume.num_steps] |
sub ax, bx |
.not_ac97: |
pop edx ecx ebx |
ret |
|
|
close_app: |
or eax, -1 |
int 0x40 |
;____________________________________ |
caption db 'Sound Mixer',0 |
drivername db 'SOUND',0 |
|
;aRamdisk db '/rd/1/',0 |
|
;aStartDriver db 'Start driver',0 |
;aStop db 'Stop',0 |
;aGetMVol db 'Get Master Volume',0 |
;aSetMVol db 'Set Master Volume',0 |
;aGetDevInfo db 'Get device info',0 |
aNoText db 0 |
|
aLVolume db 'Left',0 |
aRVolume db 'Right',0 |
|
; Jack types |
;aLineOut db 'Line Out',0 |
;aSpeaker db 'Speaker',0 |
;aHPOut db 'HP Out',0 |
;aSideSpk db '',0 |
;aCD db 'CD',0 |
;aSPDIFOut db 'SPDIF Out',0 |
;aDigitalOut db 'Digital Out',0 |
;aModemLine db 'Modem Line',0 |
;aModemHand db 'Modem Hand',0 |
;aLineIn db 'Line In',0 |
;aAUX db 'AUX',0 |
;aMic db 'Mic',0 |
;aTelephony db 'Telephony',0 |
;aSPDIFIn db 'SPDIF In',0 |
;aDigitalIn db 'Digital In',0 |
;aReserved db 'Reserved',0 |
;aOther db 'Other',0 |
|
;Jack locations |
;base |
;aNA db 'N/A',0 |
;aRear db 'Rear',0 |
;aFront db 'Front',0 |
;aLeft db 'Left',0 |
;aRight db 'Right',0 |
;aTop db 'Top',0 |
;aBottom db 'Bottom',0 |
;special |
;aRearPanel db 'Rear Panel',0 |
;aDriveBar db 'Drive Bar',0 |
;aRiser db 'Riser',0 |
;aHDMI db 'HDMI',0 |
;aATAPI db 'ATAPI',0 |
;aMobileIn db 'Mobile-In',0 |
;aMobileOut db 'Mobile-Out',0 |
|
|
I_END: |
|
align 4 |
ioctl: |
hDriver rd 1 |
ioctl_code rd 1 |
input rd 1 |
inp_size rd 1 |
output rd 1 |
outp_size rd 1 |
|
driver_ver rd 1 |
master_vol rd 1 |
|
;ctrl_info rd 9 |
|
is_hda rb 1 |
|
LVolume CONTROL |
RVolume CONTROL |
|
align 4 |
rb 2048 ; stack |
I_MEM: |
|