/kernel/branches/Kolibri-acpi/blkdev/disk.inc |
---|
459,7 → 459,9 |
stdcall disk_call_driver |
; 3b. Free the structure. |
xchg eax, esi |
push ebx |
call free |
pop ebx |
; 4. Return. |
.nothing: |
ret |
626,8 → 628,8 |
; The default implementation of DISKFUNC.adjust_cache_size. |
disk_default_adjust_cache_size: |
mov eax, [esp+4] |
ret 4 |
mov eax, [esp+8] |
ret 8 |
; This is an internal function called from 'disk_media_changed' when a new media |
; is detected. It creates the list of partitions for the media. |
/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc |
---|
135,7 → 135,7 |
push esp |
push edx |
push [.sector_lo+12] |
mov ecx, [.cache] |
mov ecx, [.cache+16] |
mov eax, edi |
shl eax, 9 |
add eax, [ecx+DISKCACHE.data] |
317,7 → 317,7 |
.yes_in_cache_write: |
mov dword [esi+4], 2 ; write - differs from hd |
mov dword [esi+8], 2 ; write - differs from hd |
shl edi, 9 |
mov ecx, [.cache] |
373,11 → 373,12 |
; This function is intended to replace the old 'write_cache' function. |
proc write_cache64 uses ecx edx esi edi, disk:dword |
locals |
cache_chain_started dd ? |
cache_chain_started dd 0 |
cache_chain_size dd ? |
cache_chain_pos dd ? |
cache_chain_ptr dd ? |
endl |
saved_esi_pos = 16+12 ; size of local variables + size of registers before esi |
; If there is no cache for this disk, nothing to do. |
cmp [esi+DISKCACHE.pointer], 0 |
jz .flush |
465,7 → 466,7 |
.write_cache_chain: |
pusha |
mov edi, [cache_chain_pos] |
mov ecx, [ebp-12] |
mov ecx, [ebp-saved_esi_pos] |
shl edi, 9 |
add edi, [ecx+DISKCACHE.data] |
mov ecx, [cache_chain_size] |
549,7 → 550,7 |
mov eax, [esi+DISK.SysCache.data_size] |
push ebx |
call calculate_for_hd |
call calculate_for_hd64 |
pop ebx |
add eax, [esi+DISK.SysCache.pointer] |
mov [esi+DISK.SysCache.data], eax |
564,7 → 565,7 |
mov eax, [esi+DISK.AppCache.data_size] |
push ebx |
call calculate_for_hd |
call calculate_for_hd64 |
pop ebx |
add eax, [esi+DISK.AppCache.pointer] |
mov [esi+DISK.AppCache.data], eax |
590,6 → 591,22 |
mov al, 1 |
ret |
calculate_for_hd64: |
push eax |
mov ebx, eax |
shr eax, 9 |
lea eax, [eax*3] |
shl eax, 2 |
sub ebx, eax |
shr ebx, 9 |
mov ecx, ebx |
shl ebx, 9 |
pop eax |
sub eax, ebx |
dec ecx |
ret |
; This internal function is called from disk_media_dereference to free the |
; allocated cache, if there is one. |
; esi = pointer to DISK structure |
/kernel/branches/Kolibri-acpi/boot/bootvesa.inc |
---|
217,7 → 217,7 |
test [es:mi.ModeAttributes], 10000000b ;LFB ? |
jz @f |
cmp [es:mi.BitsPerPixel], 24 ;It show only videomodes to have support 24 and 32 bpp |
cmp [es:mi.BitsPerPixel], 32 ;It show only videomodes to have support 24 and 32 bpp |
jb @f |
; cmp [es:mi.BitsPerPixel],16 |
/kernel/branches/Kolibri-acpi/build.bat |
---|
2,7 → 2,7 |
cls |
set languages=en ru ge et |
set drivers=com_mouse emu10k1x fm801 infinity sis sound viasound vt823x |
set targets=all kernel drivers skins clean |
set targets=all kernel drivers clean |
call :Check_Target %1 |
for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2 |
59,7 → 59,6 |
:Target_all |
call :Target_kernel |
call :Target_drivers |
call :Target_skins |
goto :eof |
102,16 → 101,6 |
goto :eof |
:Target_skins |
echo *** building skins ... |
if not exist bin\skins mkdir bin\skins |
cd skin |
fasm -m 65536 default.asm ..\bin\skins\default.skn |
if not %errorlevel%==0 goto :Error_FasmFailed |
cd .. |
goto :eof |
:Target_clean |
echo *** cleaning ... |
rmdir /S /Q bin |
/kernel/branches/Kolibri-acpi/core/dll.inc |
---|
810,15 → 810,7 |
jnz .ok |
stdcall kernel_free, [img_base] |
cmp dword [file_name+13], 'SOUN' |
jnz @f |
cmp dword [file_name+17], 'D.ob' |
jnz @f |
cmp word [file_name+21], 'j' |
jnz @f |
mov esi, aHDA |
jmp .redo |
@@: |
xor eax, eax |
ret |
.ok: |
/kernel/branches/Kolibri-acpi/core/malloc.inc |
---|
341,10 → 341,9 |
; insert_chunk(p,psize); |
mov eax, esi |
pop esi |
mov ecx, edi |
pop edi |
jmp insert_chunk |
call insert_chunk |
jmp .fail2 |
.unl_large: |
; unlink_large_chunk((tchunkptr)next); |
364,10 → 363,9 |
; insert_chunk(p,psize); |
mov eax, esi |
pop esi |
mov ecx, edi |
pop edi |
jmp insert_chunk |
call insert_chunk |
jmp .fail2 |
.fix_next: |
; (p+psize)->prev_foot = psize; |
386,10 → 384,9 |
; insert_chunk(p,psize); |
mov eax, esi |
pop esi |
mov ecx, edi |
pop edi |
jmp insert_chunk |
call insert_chunk |
jmp .fail2 |
; param |
; ecx = chunk |
418,15 → 415,11 |
mov [esi+8], edx ;P->fd = F |
mov [esi+12], eax ;P->bk = B |
pop esi |
mov ecx, mst.mutex |
call mutex_unlock |
ret |
.large: |
mov ebx, eax |
call insert_large_chunk |
pop esi |
mov ecx, mst.mutex |
call mutex_unlock |
ret |
/kernel/branches/Kolibri-acpi/core/memory.inc |
---|
606,8 → 606,12 |
align 4 |
get_pg_addr: |
sub eax, OS_BASE |
cmp eax, 0x400000 |
jb @f |
shr eax, 12 |
mov eax, [page_tabs+eax*4] |
mov eax, [page_tabs+(eax+(OS_BASE shr 12))*4] |
@@: |
and eax, 0xFFFFF000 |
ret |
/kernel/branches/Kolibri-acpi/core/peload.inc |
---|
300,6 → 300,7 |
malloc, 'Kmalloc', \ |
free, 'Kfree', \ |
map_io_mem, 'MapIoMem', \ ; stdcall |
map_page, 'MapPage', \ ; stdcall |
get_pg_addr, 'GetPgAddr', \ ; eax |
\ |
mutex_init, 'MutexInit', \ ; gcc fastcall |
/kernel/branches/Kolibri-acpi/core/test_malloc.asm |
---|
50,12 → 50,12 |
ret |
run_test3: |
; 1024000 times run random operation. |
; 1024 times run random operation. |
; Randomly select malloc(random size from 1 to 1023) |
; or free(random of previously allocated areas) |
mov edi, 0x12345678 |
xor esi, esi ; 0 areas allocated |
mov ebx, 1024000 |
mov ebx, 1024 |
.loop: |
imul edi, 1103515245 |
add edi, 12345 |
78,7 → 78,11 |
push eax |
; mov ecx, [saved_state_num] |
; mov [saved_state+ecx*8], eax |
push edi |
call malloc_with_test |
pop ecx |
cmp ecx, edi |
jnz edi_destroyed |
; mov ecx, [saved_state_num] |
; mov [saved_state+ecx*8+4], eax |
; inc [saved_state_num] |
113,7 → 117,11 |
jnz memory_destroyed |
pop eax edi |
push ebx edx |
push edi |
call free |
pop ecx |
cmp ecx, edi |
jnz edi_destroyed |
pop edx ebx |
dec esi |
pop eax ecx |
150,9 → 158,15 |
ret |
; Stubs for kernel procedures used by heap code |
wait_mutex: |
inc dword [ebx] |
mutex_init: |
and dword [ecx], 0 |
ret |
mutex_lock: |
inc dword [ecx] |
ret |
mutex_unlock: |
dec dword [ecx] |
ret |
kernel_alloc: |
cmp dword [esp+4], bufsize |
174,7 → 188,7 |
jmp error_with_code |
check_mutex: |
cmp [mst.mutex], 0 |
cmp dword [mst.mutex], 0 |
jnz @f |
ret |
@@: |
195,6 → 209,10 |
mov eax, 5 |
jmp error_with_code |
edi_destroyed: |
mov eax, 6 |
jmp error_with_code |
error_with_code: |
mov edx, saved_state_num |
; eax = error code |
208,6 → 226,7 |
; Include main heap code |
include '../proc32.inc' |
include '../struct.inc' |
include '../const.inc' |
include 'malloc.inc' |
/kernel/branches/Kolibri-acpi/data32.inc |
---|
134,13 → 134,10 |
msg_version db 'incompatible driver version',13,10,0 |
msg_www db 'please visit www.kolibrios.org',13,10,0 |
msg_CR db 13,10,0 |
aHDA db 'INTEL_HDA',0 |
intel_str db "GenuineIntel",0 |
AMD_str db "AuthenticAMD",0 |
;szSound db 'SOUND',0 |
;szInfinity db 'INFINITY',0 |
szHwMouse db 'ATI2D',0 |
szPS2MDriver db 'PS2MOUSE',0 |
;szCOM_MDriver db 'COM_MOUSE',0 |
/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt |
---|
4592,7 → 4592,6 |
* This function terminates the current thread. Other thread can be |
killed by call to subfunction 2 of function 18. |
====================================================================== |
=========================== List of events =========================== |
====================================================================== |
/kernel/branches/Kolibri-acpi/drivers/infinity.asm |
---|
875,8 → 875,8 |
; flags reserved |
; RESET_INPUT equ 1 ;reserved reset and clear input buffer |
; RESET_OUTPUT equ 2 ;reserved reset and clear output buffer |
; RESET_INPUT equ 1 ;reset and clear input buffer |
; RESET_OUTPUT equ 2 ;reset and clear output buffer |
; RESET_ALL equ 3 |
913,6 → 913,33 |
mov [edx+STREAM.out_wp], ebx |
mov [edx+STREAM.out_rp], ebx |
mov [edx+STREAM.out_count], eax |
mov dword [edx+STREAM.time_base], eax |
mov dword [edx+STREAM.time_base+4], eax |
mov dword [edx+STREAM.time_stamp], eax |
mov dword [edx+STREAM.time_stamp+4], eax |
mov dword [edx+STREAM.last_ts], eax |
mov eax, [edx+STREAM.r_silence] |
test [flags], 1 |
jz @F |
mov ecx, [edx+STREAM.in_top] |
mov edi, [edx+STREAM.in_base] |
sub ecx, edi |
shr ecx, 2 |
cld |
rep stosd |
@@: |
test [flags], 2 |
jz @F |
mov edi, [edx+STREAM.out_base] |
mov ecx, (64*1024)/4 |
rep stosd |
@@: |
ret |
.fail: |
or eax, -1 |
1153,8 → 1180,6 |
mov [edx+STREAM.flags], SND_STOP |
; stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0 |
mov eax, [edx+STREAM.notify_event] |
mov ebx, [edx+STREAM.notify_id] |
call ClearEvent ;eax ebx |
/kernel/branches/Kolibri-acpi/drivers/intelac97.asm |
---|
0,0 → 1,1507 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
format MS COFF |
DEBUG equ 1 |
include 'proc32.inc' |
include 'imports.inc' |
API_VERSION equ 0x01000100 |
DEBUG_IRQ equ 0 |
USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices |
IRQ_REMAP equ 0 |
IRQ_LINE equ 0 |
;irq 0,1,2,8,12,13 íåäîñòóïíû |
; FEDCBA9876543210 |
VALID_IRQ equ 1100111011111000b |
ATTCH_IRQ equ 0000111010100000b |
if USE_COM_IRQ |
ATTCH_IRQ equ 0000111010111000b |
end if |
CPU_FREQ equ 2600d |
BIT0 EQU 0x00000001 |
BIT1 EQU 0x00000002 |
BIT2 EQU 0x00000004 |
BIT3 EQU 0x00000008 |
BIT4 EQU 0x00000010 |
BIT5 EQU 0x00000020 |
BIT6 EQU 0x00000040 |
BIT7 EQU 0x00000080 |
BIT8 EQU 0x00000100 |
BIT9 EQU 0x00000200 |
BIT10 EQU 0x00000400 |
BIT11 EQU 0x00000800 |
BIT12 EQU 0x00001000 |
BIT13 EQU 0x00002000 |
BIT14 EQU 0x00004000 |
BIT15 EQU 0x00008000 |
BIT16 EQU 0x00010000 |
BIT17 EQU 0x00020000 |
BIT18 EQU 0x00040000 |
BIT19 EQU 0x00080000 |
BIT20 EQU 0x00100000 |
BIT21 EQU 0x00200000 |
BIT22 EQU 0x00400000 |
BIT23 EQU 0x00800000 |
BIT24 EQU 0x00100000 |
BIT25 EQU 0x02000000 |
BIT26 EQU 0x04000000 |
BIT27 EQU 0x08000000 |
BIT28 EQU 0x10000000 |
BIT29 EQU 0x20000000 |
BIT30 EQU 0x40000000 |
BIT31 EQU 0x80000000 |
PCM_4 equ BIT20 |
PCM_6 equ BIT21 |
VID_INTEL equ 0x8086 |
VID_NVIDIA equ 0x10DE |
CTRL_ICH equ 0x2415 |
CTRL_ICH0 equ 0x2425 |
CTRL_ICH2 equ 0x2435 |
CTRL_ICH3 equ 0x2445 |
CTRL_ICH4 equ 0x24C5 |
CTRL_ICH5 equ 0x24D5 |
CTRL_ICH6 equ 0x266E |
CTRL_ICH7 equ 0x27DE |
CTRL_NFORCE equ 0x01B1 |
CTRL_NFORCE2 equ 0x006A |
CTRL_NFORCE3 equ 0x00DA |
CTRL_MCP04 equ 0x003A |
CTRL_CK804 equ 0x0059 |
CTRL_CK8 equ 0x008A |
CTRL_CK8S equ 0x00EA |
CTRL_MCP51 equ 0x026B |
PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list |
PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register |
PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index |
PCM_OUT_SR_REG equ 0x16 ; PCM out Status register |
PCM_OUT_PIV_REG equ 0x1a |
PCM_OUT_CIV_REG equ 0x14 ; PCM out current index |
PCM_IN_CR_REG equ 0x0b ; PCM in Control Register |
MC_IN_CR_REG equ 0x2b ; MIC in Control Register |
RR equ BIT1 ; reset registers. Nukes all regs |
CODEC_MASTER_VOL_REG equ 0x02 |
CODEC_AUX_VOL equ 0x04 ; |
CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume |
CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio |
CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control |
CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate |
CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate |
CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate |
GLOB_CTRL equ 0x2C ; Global Control |
CTRL_STAT equ 0x30 ; Global Status |
CTRL_CAS equ 0x34 ; Codec Access Semiphore |
CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit |
CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready |
CTRL_ST_RCS equ 0x00008000 ; Read Completion Status |
CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable |
CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off |
CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset |
CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset |
CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable |
CODEC_REG_POWERDOWN equ 0x26 |
CODEC_REG_ST equ 0x26 |
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 |
DEV_GET_POS equ 9 |
struc AC_CNTRL ;AC controller base class |
{ .bus dd ? |
.devfn dd ? |
.vendor dd ? |
.dev_id dd ? |
.pci_cmd dd ? |
.pci_stat dd ? |
.codec_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_io_base dd ? |
.ctrl_mem_base dd ? |
.cfg_reg dd ? |
.int_line dd ? |
.vendor_ids dd ? ;vendor id string |
.ctrl_ids dd ? ;hub id string |
.buffer dd ? |
.notify_pos dd ? |
.notify_task dd ? |
.lvi_reg dd ? |
.ctrl_setup dd ? |
.user_callback dd ? |
.codec_read16 dd ? |
.codec_write16 dd ? |
.ctrl_read8 dd ? |
.ctrl_read16 dd ? |
.ctrl_read32 dd ? |
.ctrl_write8 dd ? |
.ctrl_write16 dd ? |
.ctrl_write32 dd ? |
} |
struc CODEC ;Audio Chip base class |
{ |
.chip_id dd ? |
.flags dd ? |
.status dd ? |
.ac_vendor_ids dd ? ;ac vendor id string |
.chip_ids dd ? ;chip model string |
.shadow_flag dd ? |
dd ? |
.regs dw ? ; codec registers |
.reg_master_vol dw ? ;0x02 |
.reg_aux_out_vol dw ? ;0x04 |
.reg_mone_vol dw ? ;0x06 |
.reg_master_tone dw ? ;0x08 |
.reg_beep_vol dw ? ;0x0A |
.reg_phone_vol dw ? ;0x0C |
.reg_mic_vol dw ? ;0x0E |
.reg_line_in_vol dw ? ;0x10 |
.reg_cd_vol dw ? ;0x12 |
.reg_video_vol dw ? ;0x14 |
.reg_aux_in_vol dw ? ;0x16 |
.reg_pcm_out_vol dw ? ;0x18 |
.reg_rec_select dw ? ;0x1A |
.reg_rec_gain dw ? ;0x1C |
.reg_rec_gain_mic dw ? ;0x1E |
.reg_gen dw ? ;0x20 |
.reg_3d_ctrl dw ? ;0X22 |
.reg_page dw ? ;0X24 |
.reg_powerdown dw ? ;0x26 |
.reg_ext_audio dw ? ;0x28 |
.reg_ext_st dw ? ;0x2a |
.reg_pcm_front_rate dw ? ;0x2c |
.reg_pcm_surr_rate dw ? ;0x2e |
.reg_lfe_rate dw ? ;0x30 |
.reg_pcm_in_rate dw ? ;0x32 |
dw ? ;0x34 |
.reg_cent_lfe_vol dw ? ;0x36 |
.reg_surr_vol dw ? ;0x38 |
.reg_spdif_ctrl dw ? ;0x3A |
dw ? ;0x3C |
dw ? ;0x3E |
dw ? ;0x40 |
dw ? ;0x42 |
dw ? ;0x44 |
dw ? ;0x46 |
dw ? ;0x48 |
dw ? ;0x4A |
dw ? ;0x4C |
dw ? ;0x4E |
dw ? ;0x50 |
dw ? ;0x52 |
dw ? ;0x54 |
dw ? ;0x56 |
dw ? ;0x58 |
dw ? ;0x5A |
dw ? ;0x5C |
dw ? ;0x5E |
.reg_page_0 dw ? ;0x60 |
.reg_page_1 dw ? ;0x62 |
.reg_page_2 dw ? ;0x64 |
.reg_page_3 dw ? ;0x66 |
.reg_page_4 dw ? ;0x68 |
.reg_page_5 dw ? ;0x6A |
.reg_page_6 dw ? ;0x6C |
.reg_page_7 dw ? ;0x6E |
dw ? ;0x70 |
dw ? ;0x72 |
dw ? ;0x74 |
dw ? ;0x76 |
dw ? ;0x78 |
dw ? ;0x7A |
.reg_vendor_id_1 dw ? ;0x7C |
.reg_vendor_id_2 dw ? ;0x7E |
.reset dd ? ;virual |
.set_master_vol dd ? |
} |
struc CTRL_INFO |
{ .pci_cmd dd ? |
.irq dd ? |
.glob_cntrl dd ? |
.glob_sta dd ? |
.codec_io_base dd ? |
.ctrl_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_mem_base dd ? |
.codec_id dd ? |
} |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
EVENT_NOTIFY equ 0x00000200 |
public START |
public service_proc |
public version |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .stop |
if DEBUG |
mov esi, msgInit |
call SysMsgBoardStr |
end if |
call detect_controller |
test eax, eax |
jz .fail |
if DEBUG |
mov esi, [ctrl.vendor_ids] |
call SysMsgBoardStr |
mov esi, [ctrl.ctrl_ids] |
call SysMsgBoardStr |
end if |
call init_controller |
test eax, eax |
jz .fail |
call init_codec |
test eax, eax |
jz .fail |
call reset_controller |
call setup_codec |
mov esi, msgPrimBuff |
call SysMsgBoardStr |
call create_primary_buff |
mov esi, msgDone |
call SysMsgBoardStr |
if IRQ_REMAP |
pushf |
cli |
mov ebx, [ctrl.int_line] |
in al, 0xA1 |
mov ah, al |
in al, 0x21 |
test ebx, ebx |
jz .skip |
bts ax, bx ;mask old line |
.skip |
bts ax, IRQ_LINE ;mask new ine |
out 0x21, al |
mov al, ah |
out 0xA1, al |
;remap IRQ |
stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE |
mov dx, 0x4d0 ;8259 ELCR1 |
in al, dx |
bts ax, IRQ_LINE |
out dx, al ;set level-triggered mode |
mov [ctrl.int_line], IRQ_LINE |
popf |
mov esi, msgRemap |
call SysMsgBoardStr |
end if |
mov ebx, [ctrl.int_line] |
stdcall AttachIntHandler, ebx, ac97_irq, dword 0 |
.reg: |
stdcall RegService, sz_sound_srv, service_proc |
ret |
.fail: |
if DEBUG |
mov esi, msgFail |
call SysMsgBoardStr |
end if |
xor eax, eax |
ret |
.fail_msg: |
call SysMsgBoardStr |
xor eax, eax |
ret |
.stop: |
call stop |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [edi+output] |
cmp [edi+out_size], 4 |
jne .fail |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
@@: |
cmp eax, DEV_PLAY |
jne @F |
if DEBUG |
mov esi, msgPlay |
call SysMsgBoardStr |
end if |
call play |
ret |
@@: |
cmp eax, DEV_STOP |
jne @F |
if DEBUG |
mov esi, msgStop |
call SysMsgBoardStr |
end if |
call stop |
ret |
@@: |
cmp eax, DEV_CALLBACK |
jne @F |
mov ebx, [edi+input] |
stdcall set_callback, [ebx] |
ret |
@@: |
cmp eax, DEV_SET_MASTERVOL |
jne @F |
mov eax, [edi+input] |
mov eax, [eax] |
call set_master_vol ;eax= vol |
ret |
@@: |
cmp eax, DEV_GET_MASTERVOL |
jne @F |
mov ebx, [edi+output] |
stdcall get_master_vol, ebx |
ret |
@@: |
cmp eax, DEV_GET_POS |
jne @F |
mov ebx, 8192 |
mov edx, 0x18 |
xor eax, eax |
call [ctrl.ctrl_read16] |
sub ebx, eax |
shr ebx, 1 |
mov edx, [edi+output] |
mov [edx], ebx |
xor eax, eax |
ret |
;@@: |
; cmp eax, DEV_GET_INFO |
; jne @F |
; mov ebx, [edi+output] |
; stdcall get_dev_info, ebx |
; ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc ac97_irq |
if DEBUG_IRQ |
mov esi, msgIRQ |
call SysMsgBoardStr |
end if |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
cmp eax, 0xffffffff |
je .exit |
test eax, 0x40 |
jnz .do_intr |
test eax, eax |
jz .exit |
mov edx, CTRL_STAT |
call [ctrl.ctrl_write32] |
.exit: |
xor eax, eax |
ret |
.do_intr: |
push eax |
mov edx, PCM_OUT_CR_REG |
mov al, 0x10; 0x10 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
mov edx, PCM_OUT_CIV_REG |
call [ctrl.ctrl_read8] |
and eax, 0x1F |
cmp eax, [civ_val] |
je .skip |
mov [civ_val], eax |
dec eax |
and eax, 0x1F |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 ;0x1D |
call [ctrl.ctrl_write8] |
mov eax, [civ_val] |
add eax, 1 |
and eax, 31 |
mov ebx, dword [buff_list+eax*4] |
cmp [ctrl.user_callback], 0 |
je .done |
stdcall [ctrl.user_callback], ebx |
.done: |
pop eax |
and eax, 0x40 |
mov edx, CTRL_STAT |
call [ctrl.ctrl_write32] |
or eax, 1 |
ret |
.skip: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 ;0x1D |
call [ctrl.ctrl_write8] |
jmp .done |
endp |
align 4 |
proc create_primary_buff |
stdcall KernelAlloc, 0x10000 |
mov [ctrl.buffer], eax |
mov edi, eax |
mov ecx, 0x10000/4 |
xor eax, eax |
cld |
rep stosd |
mov eax, [ctrl.buffer] |
call GetPgAddr |
mov ebx, 0xC0002000 |
mov ecx, 4 |
mov edi, pcmout_bdl |
@@: |
mov [edi], eax |
mov [edi+4], ebx |
mov [edi+32], eax |
mov [edi+4+32], ebx |
mov [edi+64], eax |
mov [edi+4+64], ebx |
mov [edi+96], eax |
mov [edi+4+96], ebx |
mov [edi+128], eax |
mov [edi+4+128], ebx |
mov [edi+160], eax |
mov [edi+4+160], ebx |
mov [edi+192], eax |
mov [edi+4+192], ebx |
mov [edi+224], eax |
mov [edi+4+224], ebx |
add eax, 0x4000 |
add edi, 8 |
loop @B |
mov edi, buff_list |
mov eax, [ctrl.buffer] |
mov ecx, 4 |
@@: |
mov [edi], eax |
mov [edi+16], eax |
mov [edi+32], eax |
mov [edi+48], eax |
mov [edi+64], eax |
mov [edi+80], eax |
mov [edi+96], eax |
mov [edi+112], eax |
add eax, 0x4000 |
add edi, 4 |
loop @B |
mov eax, pcmout_bdl |
mov ebx, eax |
call GetPgAddr ;eax |
and ebx, 0xFFF |
add eax, ebx |
mov edx, PCM_OUT_BDL |
call [ctrl.ctrl_write32] |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc detect_controller |
locals |
last_bus dd ? |
bus dd ? |
devfn dd ? |
endl |
xor eax, eax |
mov [bus], eax |
inc eax |
call PciApi |
cmp eax, -1 |
je .err |
mov [last_bus], eax |
.next_bus: |
and [devfn], 0 |
.next_dev: |
stdcall PciRead32, [bus], [devfn], dword 0 |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
mov edi, devices |
@@: |
mov ebx, [edi] |
test ebx, ebx |
jz .next |
cmp eax, ebx |
je .found |
add edi, 12 |
jmp @B |
.next: |
inc [devfn] |
cmp [devfn], 256 |
jb .next_dev |
mov eax, [bus] |
inc eax |
mov [bus], eax |
cmp eax, [last_bus] |
jna .next_bus |
xor eax, eax |
ret |
.found: |
mov ebx, [bus] |
mov [ctrl.bus], ebx |
mov ecx, [devfn] |
mov [ctrl.devfn], ecx |
mov edx, eax |
and edx, 0xFFFF |
mov [ctrl.vendor], edx |
shr eax, 16 |
mov [ctrl.dev_id], eax |
mov ebx, [edi+4] |
mov [ctrl.ctrl_ids], ebx |
mov esi, [edi+8] |
mov [ctrl.ctrl_setup], esi |
cmp edx, VID_INTEL |
jne @F |
mov [ctrl.vendor_ids], msg_Intel |
ret |
@@: |
cmp edx, VID_NVIDIA |
jne @F |
mov [ctrl.vendor_ids], msg_NVidia |
ret |
@@: |
.err: |
xor eax, eax |
mov [ctrl.vendor_ids], eax ;something wrong ? |
ret |
endp |
align 4 |
proc init_controller |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 |
mov ebx, eax |
and eax, 0xFFFF |
mov [ctrl.pci_cmd], eax |
shr ebx, 16 |
mov [ctrl.pci_stat], ebx |
mov esi, msgPciCmd |
call SysMsgBoardStr |
call dword2str |
call SysMsgBoardStr |
mov esi, msgPciStat |
call SysMsgBoardStr |
mov eax, [ctrl.pci_stat] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgMixIsaIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 |
call dword2str |
call SysMsgBoardStr |
and eax, 0xFFFE |
mov [ctrl.codec_io_base], eax |
mov esi, msgCtrlIsaIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14 |
call dword2str |
call SysMsgBoardStr |
and eax, 0xFFC0 |
mov [ctrl.ctrl_io_base], eax |
mov esi, msgMixMMIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18 |
mov [ctrl.codec_mem_base], eax |
call dword2str |
call SysMsgBoardStr |
mov esi, msgCtrlMMIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C |
mov [ctrl.ctrl_mem_base], eax |
call dword2str |
call SysMsgBoardStr |
if 0 |
;;patch for some ugly BIOS ICH-ICH5 compatible |
cmp [ctrl.vendor], VID_INTEL |
jne .default |
mov esi, msgIrqMap |
call SysMsgBoardStr |
stdcall PciRead8, 0, 0xF8, 0x61 |
and eax, 0xFF |
call dword2str |
call SysMsgBoardStr |
btr eax, 7 ;when bit 7 set remap disabled |
jnc @F |
xor eax, eax |
jmp @F |
end if |
.default: |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C |
and eax, 0xFF |
@@: |
mov [ctrl.int_line], eax |
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41 |
and eax, 0xFF |
mov [ctrl.cfg_reg], eax |
mov [ctrl.user_callback], 0 |
call [ctrl.ctrl_setup] |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc set_ICH |
mov [ctrl.codec_read16], codec_io_r16 ;virtual |
mov [ctrl.codec_write16], codec_io_w16 ;virtual |
mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual |
mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual |
mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual |
mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual |
mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual |
mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual |
ret |
endp |
PG_SW equ 0x003 |
PG_NOCACHE equ 0x018 |
align 4 |
proc set_ICH4 |
stdcall MapIoMem, [ctrl.codec_mem_base], 0x1000, PG_SW+PG_NOCACHE |
mov [ctrl.codec_mem_base], eax |
stdcall MapIoMem, [ctrl.ctrl_mem_base], 0x1000, PG_SW+PG_NOCACHE |
mov [ctrl.ctrl_mem_base], eax |
mov [ctrl.codec_read16], codec_mem_r16 ;virtual |
mov [ctrl.codec_write16], codec_mem_w16 ;virtual |
mov [ctrl.ctrl_read8 ], ctrl_mem_r8 ;virtual |
mov [ctrl.ctrl_read16], ctrl_mem_r16 ;virtual |
mov [ctrl.ctrl_read32], ctrl_mem_r32 ;virtual |
mov [ctrl.ctrl_write8 ], ctrl_mem_w8 ;virtual |
mov [ctrl.ctrl_write16], ctrl_mem_w16 ;virtual |
mov [ctrl.ctrl_write32], ctrl_mem_w32 ;virtual |
ret |
endp |
align 4 |
proc reset_controller |
xor eax, eax |
mov edx, PCM_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, MC_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov eax, RR |
mov edx, PCM_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, MC_IN_CR_REG |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc init_codec |
locals |
counter dd ? |
endl |
mov esi, msgControl |
call SysMsgBoardStr |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgStatus |
call SysMsgBoardStr |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
push eax |
call dword2str |
call SysMsgBoardStr |
pop eax |
cmp eax, 0xFFFFFFFF |
je .err |
test eax, CTRL_ST_CREADY |
jnz .ready |
call reset_codec |
test eax, eax |
jz .err |
.ready: |
xor edx, edx ;ac_reg_0 |
call [ctrl.codec_write16] |
xor eax, eax |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_write16] |
mov [counter], 200 ; total 200*5 ms = 1s |
.wait: |
mov eax, 5000 ; wait 5 ms |
call StallExec |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_read16] |
and eax, 0x0F |
cmp eax, 0x0F |
jz .done |
sub [counter] , 1 |
jnz .wait |
.err: |
xor eax, eax ; timeout error |
ret |
.done: |
mov eax, 2 ;force set 16-bit 2-channel PCM |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
mov eax, 5000 ; wait 5 ms |
call StallExec |
call detect_codec |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc reset_codec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 0x02 |
jz .cold |
call warm_reset |
jnc .ok |
.cold: |
call cold_reset |
jnc .ok |
if DEBUG |
mov esi, msgCFail |
call SysMsgBoardStr |
end if |
xor eax, eax ; timeout error |
ret |
.ok: |
if DEBUG |
mov esi, msgResetOk |
call SysMsgBoardStr |
end if |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc warm_reset |
locals |
counter dd ? |
endl |
mov eax, 0x06 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgWarm |
call SysMsgBoardStr |
end if |
mov [counter], 10 ; total 10*100 ms = 1s |
.wait: |
mov eax, 100000 ; wait 100 ms |
call StallExec |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_CREADY |
jnz .ok |
dec [counter] |
jnz .wait |
if DEBUG |
mov esi, msgWRFail |
call SysMsgBoardStr |
end if |
.fail: |
stc |
ret |
.ok: |
clc |
ret |
endp |
align 4 |
proc cold_reset |
locals |
counter dd ? |
endl |
mov eax, 0x02 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgCold |
call SysMsgBoardStr |
end if |
mov eax, 400000 ; wait 400 ms |
call StallExec |
mov [counter], 16 ; total 20*100 ms = 2s |
.wait: |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_CREADY |
jnz .ok |
mov eax, 100000 ; wait 100 ms |
call StallExec |
dec [counter] |
jnz .wait |
if DEBUG |
mov esi, msgCRFail |
call SysMsgBoardStr |
end if |
.fail: |
stc |
ret |
.ok: |
mov esi, msgControl |
call SysMsgBoardStr |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgStatus |
call SysMsgBoardStr |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
push eax |
call dword2str |
call SysMsgBoardStr |
pop eax |
test eax, CTRL_ST_CREADY |
jz .fail |
clc |
ret |
endp |
align 4 |
play: |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x1D |
call [ctrl.ctrl_write8] |
xor eax, eax |
ret |
align 4 |
stop: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x0 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
xor eax, eax |
ret |
align 4 |
proc get_dev_info stdcall, p_info:dword |
virtual at esi |
CTRL_INFO CTRL_INFO |
end virtual |
mov esi, [p_info] |
mov eax, [ctrl.int_line] |
mov ebx, [ctrl.codec_io_base] |
mov ecx, [ctrl.ctrl_io_base] |
mov edx, [ctrl.codec_mem_base] |
mov edi, [ctrl.ctrl_mem_base] |
mov [CTRL_INFO.irq], eax |
mov [CTRL_INFO.codec_io_base], ebx |
mov [CTRL_INFO.ctrl_io_base], ecx |
mov [CTRL_INFO.codec_mem_base], edx |
mov [CTRL_INFO.ctrl_mem_base], edi |
mov eax, [codec.chip_id] |
mov [CTRL_INFO.codec_id], eax |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_cntrl], eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_sta], eax |
mov ebx, [ctrl.pci_cmd] |
mov [CTRL_INFO.pci_cmd], ebx |
ret |
endp |
align 4 |
proc set_callback stdcall, handler:dword |
mov eax, [handler] |
mov [ctrl.user_callback], eax |
ret |
endp |
align 4 |
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax |
mov edx, [ac_reg] |
mov ebx, edx |
shr ebx, 1 |
bt [codec.shadow_flag], ebx |
jc .use_shadow |
call [ctrl.codec_read16] ;change edx !!! |
mov ecx, eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_RCS |
jz .read_ok |
mov edx, CTRL_STAT |
call [ctrl.ctrl_write32] |
xor eax, eax |
not eax ;timeout |
ret |
.read_ok: |
mov edx, [ac_reg] |
mov [codec.regs+edx], cx |
bts [codec.shadow_flag], ebx |
mov eax, ecx |
ret |
.use_shadow: |
movzx eax, word [codec.regs+edx] |
ret |
endp |
align 4 |
proc codec_write stdcall, ac_reg:dword |
push eax |
call check_semafore |
and eax, eax |
jz .err |
pop eax |
mov esi, [ac_reg] |
mov edx, esi |
call [ctrl.codec_write16] |
mov [codec.regs+esi], ax |
shr esi, 1 |
bts [codec.shadow_flag], esi |
ret |
.err: |
pop eax |
ret |
endp |
align 4 |
proc codec_check_ready |
mov edx, CTRL_ST |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .not_ready |
xor eax, wax |
inc eax |
ret |
.not_ready: |
xor eax, eax |
ret |
endp |
align 4 |
proc check_semafore |
local counter:DWORD |
mov [counter], 100 |
.l1: |
mov edx, CTRL_CAS |
call [ctrl.ctrl_read8] |
and eax, CAS_FLAG |
jz .ok |
mov eax, 1 |
call StallExec |
sub [counter], 1 |
jnz .l1 |
xor eax, eax |
ret |
align 4 |
.ok: |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc StallExec |
push ecx |
push edx |
push ebx |
push eax |
mov ecx, CPU_FREQ |
mul ecx |
mov ebx, eax ;low |
mov ecx, edx ;high |
rdtsc |
add ebx, eax |
adc ecx, edx |
@@: |
rdtsc |
sub eax, ebx |
sbb edx, ecx |
js @B |
pop eax |
pop ebx |
pop edx |
pop ecx |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; CONTROLLER IO functions |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
proc codec_io_r16 |
add edx, [ctrl.codec_io_base] |
in ax, dx |
ret |
endp |
align 4 |
proc codec_io_w16 |
add edx, [ctrl.codec_io_base] |
out dx, ax |
ret |
endp |
align 4 |
proc ctrl_io_r8 |
add edx, [ctrl.ctrl_io_base] |
in al, dx |
ret |
endp |
align 4 |
proc ctrl_io_r16 |
add edx, [ctrl.ctrl_io_base] |
in ax, dx |
ret |
endp |
align 4 |
proc ctrl_io_r32 |
add edx, [ctrl.ctrl_io_base] |
in eax, dx |
ret |
endp |
align 4 |
proc ctrl_io_w8 |
add edx, [ctrl.ctrl_io_base] |
out dx, al |
ret |
endp |
align 4 |
proc ctrl_io_w16 |
add edx, [ctrl.ctrl_io_base] |
out dx, ax |
ret |
endp |
align 4 |
proc ctrl_io_w32 |
add edx, [ctrl.ctrl_io_base] |
out dx, eax |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; MEMORY MAPPED IO (os depended) |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
proc codec_mem_r16 |
add edx, [ctrl.codec_mem_base] |
mov ax, word [edx] |
ret |
endp |
align 4 |
proc codec_mem_w16 |
add edx, [ctrl.codec_mem_base] |
mov word [edx], ax |
ret |
endp |
align 4 |
proc ctrl_mem_r8 |
add edx, [ctrl.ctrl_mem_base] |
mov al, [edx] |
ret |
endp |
align 4 |
proc ctrl_mem_r16 |
add edx, [ctrl.ctrl_mem_base] |
mov ax, [edx] |
ret |
endp |
align 4 |
proc ctrl_mem_r32 |
add edx, [ctrl.ctrl_mem_base] |
mov eax, [edx] |
ret |
endp |
align 4 |
proc ctrl_mem_w8 |
add edx, [ctrl.ctrl_mem_base] |
mov [edx], al |
ret |
endp |
align 4 |
proc ctrl_mem_w16 |
add edx, [ctrl.ctrl_mem_base] |
mov [edx], ax |
ret |
endp |
align 4 |
proc ctrl_mem_w32 |
add edx, [ctrl.ctrl_mem_base] |
mov [edx], eax |
ret |
endp |
align 4 |
dword2str: |
mov esi, hex_buff |
mov ecx, -8 |
@@: |
rol eax, 4 |
mov ebx, eax |
and ebx, 0x0F |
mov bl, [ebx+hexletters] |
mov [8+esi+ecx], bl |
inc ecx |
jnz @B |
ret |
hexletters db '0123456789ABCDEF' |
hex_buff db 8 dup(0),13,10,0 |
include "codec.inc" |
align 4 |
devices dd (CTRL_ICH shl 16)+VID_INTEL,msg_ICH, set_ICH |
dd (CTRL_ICH0 shl 16)+VID_INTEL,msg_ICH0,set_ICH |
dd (CTRL_ICH2 shl 16)+VID_INTEL,msg_ICH2,set_ICH |
dd (CTRL_ICH3 shl 16)+VID_INTEL,msg_ICH3,set_ICH |
dd (CTRL_ICH4 shl 16)+VID_INTEL,msg_ICH4,set_ICH4 |
dd (CTRL_ICH5 shl 16)+VID_INTEL,msg_ICH5,set_ICH4 |
dd (CTRL_ICH6 shl 16)+VID_INTEL,msg_ICH6,set_ICH4 |
dd (CTRL_ICH7 shl 16)+VID_INTEL,msg_ICH7,set_ICH4 |
dd (CTRL_NFORCE shl 16)+VID_NVIDIA,msg_NForce, set_ICH |
dd (CTRL_NFORCE2 shl 16)+VID_NVIDIA,msg_NForce2,set_ICH |
dd (CTRL_NFORCE3 shl 16)+VID_NVIDIA,msg_NForce3,set_ICH |
dd (CTRL_MCP04 shl 16)+VID_NVIDIA,msg_MCP04,set_ICH |
dd (CTRL_CK804 shl 16)+VID_NVIDIA,msg_CK804,set_ICH |
dd (CTRL_CK8 shl 16)+VID_NVIDIA,msg_CK8,set_ICH |
dd (CTRL_CK8S shl 16)+VID_NVIDIA,msg_CK8S,set_ICH |
dd (CTRL_MCP51 shl 16)+VID_NVIDIA,msg_MCP51,set_ICH |
dd 0 ;terminator |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
msg_ICH db '802801AA (ICH)', 13,10, 0 |
msg_ICH0 db '802801AB (ICH0)', 13,10, 0 |
msg_ICH2 db '802801BA (ICH2)', 13,10, 0 |
msg_ICH3 db '802801CA (ICH3)', 13,10, 0 |
msg_ICH4 db '802801DB (ICH4)', 13,10, 0 |
msg_ICH5 db '802801EB (ICH5)', 13,10, 0 |
msg_ICH6 db '802801FB (ICH6)', 13,10, 0 |
msg_ICH7 db '802801GB (ICH7)', 13,10, 0 |
msg_Intel db 'Intel ', 0 |
msg_NForce db 'NForce', 13,10, 0 |
msg_NForce2 db 'NForce 2', 13,10, 0 |
msg_NForce3 db 'NForce 3', 13,10, 0 |
msg_MCP04 db 'NForce MCP04',13,10, 0 |
msg_CK804 db 'NForce CK804',13,10, 0 |
msg_CK8 db 'NForce CK8', 13,10, 0 |
msg_CK8S db 'NForce CK8S', 13,10, 0 |
msg_MCP51 db 'NForce MCP51',13,10, 0 |
msg_NVidia db 'NVidia', 0 |
szKernel db 'KERNEL', 0 |
sz_sound_srv db 'SOUND',0 |
msgInit db 'detect hardware...',13,10,0 |
msgFail db 'device not found',13,10,0 |
msgAttchIRQ db 'IRQ line not supported', 13,10, 0 |
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 |
msgPlay db 'start play', 13,10,0 |
msgStop db 'stop play', 13,10,0 |
;msgNotify db 'call notify',13,10,0 |
msgIRQ db 'AC97 IRQ', 13,10,0 |
msgInitCtrl db 'init controller',13,10,0 |
;msgInitCodec db 'init codec',13,10,0 |
msgPrimBuff db 'create primary buffer ...',0 |
msgDone db 'done',13,10,0 |
msgRemap db 'Remap IRQ',13,10,0 |
;msgReg db 'set service handler',13,10,0 |
msgOk db 'service installed',13,10,0 |
msgCold db 'cold reset',13,10,0 |
msgWarm db 'warm reset',13,10,0 |
msgWRFail db 'warm reset failed',13,10,0 |
msgCRFail db 'cold reset failed',13,10,0 |
msgCFail db 'codec not ready',13,10,0 |
msgResetOk db 'reset complete',13,10,0 |
msgStatus db 'global status ',0 |
msgControl db 'global control ',0 |
msgPciCmd db 'PCI command ',0 |
msgPciStat db 'PCI status ',0 |
msgCtrlIsaIo db 'controller io base ',0 |
msgMixIsaIo db 'codec io base ',0 |
msgCtrlMMIo db 'controller mmio base ',0 |
msgMixMMIo db 'codec mmio base ',0 |
msgIrqMap db 'AC97 irq map as ',0 |
section '.data' data readable writable align 16 |
pcmout_bdl rq 32 |
buff_list rd 32 |
codec CODEC |
ctrl AC_CNTRL |
lpc_bus rd 1 |
civ_val rd 1 |
/kernel/branches/Kolibri-acpi/drivers/sound.asm |
---|
1,6 → 1,6 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
7,288 → 7,144 |
format MS COFF |
DEBUG equ 1 |
DEBUG = 1 |
include 'proc32.inc' |
include 'imports.inc' |
API_VERSION equ 0x01000100 |
VID_INTEL = 0x8086 |
VID_NVIDIA = 0x10DE |
VID_VIA = 0x1106 |
VID_SIS = 0x1039 |
VID_FM801 = 0x1319 |
VID_CREATIVE = 0x1102 |
VID_ATI = 0x1002 |
VID_AMD = 0x1022 |
VID_ULI = 0x10B9 |
VID_TERA = 0x6549 |
VID_RDC = 0x17F3 |
VID_VMWARE = 0x15AD |
DEBUG_IRQ equ 0 |
CTRL_ICH = 0x2415 |
CTRL_ICH0 = 0x2425 |
CTRL_ICH2 = 0x2435 |
CTRL_ICH3 = 0x2445 |
CTRL_ICH4 = 0x24C5 |
CTRL_ICH5 = 0x24D5 |
CTRL_ICH6 = 0x266E |
CTRL_ICH7 = 0x27DE |
USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices |
IRQ_REMAP equ 0 |
IRQ_LINE equ 0 |
CTRL_NFORCE = 0x01B1 |
CTRL_NFORCE2 = 0x006A |
CTRL_NFORCE3 = 0x00DA |
CTRL_MCP04 = 0x003A |
CTRL_CK804 = 0x0059 |
CTRL_CK8 = 0x008A |
CTRL_CK8S = 0x00EA |
CTRL_MCP51 = 0x026B |
CTRL_VT82C686 = 0x3058 |
CTRL_VT8233_5 = 0x3059 |
;irq 0,1,2,8,12,13 íåäîñòóïíû |
; FEDCBA9876543210 |
VALID_IRQ equ 1100111011111000b |
ATTCH_IRQ equ 0000111010100000b |
CTRL_SIS = 0x7012 |
if USE_COM_IRQ |
ATTCH_IRQ equ 0000111010111000b |
end if |
CTRL_FM801 = 0x0801 |
CPU_FREQ equ 2600d |
CTRL_CT0200 = 0x0006 ; Dell OEM version (EMU10K1X) |
BIT0 EQU 0x00000001 |
BIT1 EQU 0x00000002 |
BIT2 EQU 0x00000004 |
BIT3 EQU 0x00000008 |
BIT4 EQU 0x00000010 |
BIT5 EQU 0x00000020 |
BIT6 EQU 0x00000040 |
BIT7 EQU 0x00000080 |
BIT8 EQU 0x00000100 |
BIT9 EQU 0x00000200 |
BIT10 EQU 0x00000400 |
BIT11 EQU 0x00000800 |
BIT12 EQU 0x00001000 |
BIT13 EQU 0x00002000 |
BIT14 EQU 0x00004000 |
BIT15 EQU 0x00008000 |
BIT16 EQU 0x00010000 |
BIT17 EQU 0x00020000 |
BIT18 EQU 0x00040000 |
BIT19 EQU 0x00080000 |
BIT20 EQU 0x00100000 |
BIT21 EQU 0x00200000 |
BIT22 EQU 0x00400000 |
BIT23 EQU 0x00800000 |
BIT24 EQU 0x00100000 |
BIT25 EQU 0x02000000 |
BIT26 EQU 0x04000000 |
BIT27 EQU 0x08000000 |
BIT28 EQU 0x10000000 |
BIT29 EQU 0x20000000 |
BIT30 EQU 0x40000000 |
BIT31 EQU 0x80000000 |
CTRL_INTEL_SCH2 = 0x080a |
CTRL_INTEL_HPT = 0x0c0c |
CTRL_INTEL_CPT = 0x1c20 |
CTRL_INTEL_PGB = 0x1d20 |
CTRL_INTEL_PPT1 = 0x1e20 |
CTRL_INTEL_82801F = 0x2668 |
CTRL_INTEL_63XXESB = 0x269a |
CTRL_INTEL_82801G = 0x27d8 |
CTRL_INTEL_82801H = 0x284b |
CTRL_INTEL_82801_UNK1 = 0x2911 |
CTRL_INTEL_82801I = 0x293e |
CTRL_INTEL_82801_UNK2 = 0x293f |
CTRL_INTEL_82801JI = 0x3a3e |
CTRL_INTEL_82801JD = 0x3a6e |
CTRL_INTEL_PCH = 0x3b56 |
CTRL_INTEL_PCH2 = 0x3b57 |
CTRL_INTEL_SCH = 0x811b |
CTRL_INTEL_LPT = 0x8c20 |
PCM_4 equ BIT20 |
PCM_6 equ BIT21 |
CTRL_NVIDIA_MCP51 = 0x026c |
CTRL_NVIDIA_MCP55 = 0x0371 |
CTRL_NVIDIA_MCP61_1 = 0x03e4 |
CTRL_NVIDIA_MCP61_2 = 0x03f0 |
CTRL_NVIDIA_MCP65_1 = 0x044a |
CTRL_NVIDIA_MCP65_2 = 0x044b |
CTRL_NVIDIA_MCP67_1 = 0x055c |
CTRL_NVIDIA_MCP67_2 = 0x055d |
CTRL_NVIDIA_MCP78_1 = 0x0774 |
CTRL_NVIDIA_MCP78_2 = 0x0775 |
CTRL_NVIDIA_MCP78_3 = 0x0776 |
CTRL_NVIDIA_MCP78_4 = 0x0777 |
CTRL_NVIDIA_MCP73_1 = 0x07fc |
CTRL_NVIDIA_MCP73_2 = 0x07fd |
CTRL_NVIDIA_MCP79_1 = 0x0ac0 |
CTRL_NVIDIA_MCP79_2 = 0x0ac1 |
CTRL_NVIDIA_MCP79_3 = 0x0ac2 |
CTRL_NVIDIA_MCP79_4 = 0x0ac3 |
CTRL_NVIDIA_0BE2 = 0x0be2 |
CTRL_NVIDIA_0BE3 = 0x0be3 |
CTRL_NVIDIA_0BE4 = 0x0be4 |
CTRL_NVIDIA_GT100 = 0x0be5 |
CTRL_NVIDIA_GT106 = 0x0be9 |
CTRL_NVIDIA_GT108 = 0x0bea |
CTRL_NVIDIA_GT104 = 0x0beb |
CTRL_NVIDIA_GT116 = 0x0bee |
CTRL_NVIDIA_MCP89_1 = 0x0d94 |
CTRL_NVIDIA_MCP89_2 = 0x0d95 |
CTRL_NVIDIA_MCP89_3 = 0x0d96 |
CTRL_NVIDIA_MCP89_4 = 0x0d97 |
CTRL_NVIDIA_GF119 = 0x0e08 |
CTRL_NVIDIA_GF110_1 = 0x0e09 |
CTRL_NVIDIA_GF110_2 = 0x0e0c |
VID_INTEL equ 0x8086 |
VID_NVIDIA equ 0x10DE |
CTRL_ATI_SB450 = 0x437b |
CTRL_ATI_SB600 = 0x4383 |
CTRL_ICH equ 0x2415 |
CTRL_ICH0 equ 0x2425 |
CTRL_ICH2 equ 0x2435 |
CTRL_ICH3 equ 0x2445 |
CTRL_ICH4 equ 0x24C5 |
CTRL_ICH5 equ 0x24D5 |
CTRL_ICH6 equ 0x266E |
CTRL_ICH7 equ 0x27DE |
CTRL_ATI_RS600 = 0x793b |
CTRL_ATI_RS690 = 0x7919 |
CTRL_ATI_RS780 = 0x960f |
CTRL_ATI_RS_UNK1 = 0x970f |
CTRL_ATI_R600 = 0xaa00 |
CTRL_ATI_RV630 = 0xaa08 |
CTRL_ATI_RV610 = 0xaa10 |
CTRL_ATI_RV670 = 0xaa18 |
CTRL_ATI_RV635 = 0xaa20 |
CTRL_ATI_RV620 = 0xaa28 |
CTRL_ATI_RV770 = 0xaa30 |
CTRL_ATI_RV730 = 0xaa38 |
CTRL_ATI_RV710 = 0xaa40 |
CTRL_ATI_RV740 = 0xaa48 |
CTRL_NFORCE equ 0x01B1 |
CTRL_NFORCE2 equ 0x006A |
CTRL_NFORCE3 equ 0x00DA |
CTRL_MCP04 equ 0x003A |
CTRL_CK804 equ 0x0059 |
CTRL_CK8 equ 0x008A |
CTRL_CK8S equ 0x00EA |
CTRL_MCP51 equ 0x026B |
CTRL_AMD_HUDSON = 0x780d |
CTRL_VIA_VT82XX = 0x3288 |
CTRL_VIA_VT61XX = 0x9140 |
CTRL_VIA_VT71XX = 0x9170 |
PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list |
PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register |
PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index |
PCM_OUT_SR_REG equ 0x16 ; PCM out Status register |
PCM_OUT_PIV_REG equ 0x1a |
PCM_OUT_CIV_REG equ 0x14 ; PCM out current index |
CTRL_SIS_966 = 0x7502 |
PCM_IN_CR_REG equ 0x0b ; PCM in Control Register |
MC_IN_CR_REG equ 0x2b ; MIC in Control Register |
RR equ BIT1 ; reset registers. Nukes all regs |
CTRL_ULI_M5461 = 0x5461 |
CODEC_MASTER_VOL_REG equ 0x02 |
CODEC_AUX_VOL equ 0x04 ; |
CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume |
CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio |
CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control |
CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate |
CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate |
CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate |
CTRL_CREATIVE_CA0110_IBG = 0x0009 |
CTRL_CREATIVE_SOUND_CORE3D_1 = 0x0010 |
CTRL_CREATIVE_SOUND_CORE3D_2 = 0x0012 |
GLOB_CTRL equ 0x2C ; Global Control |
CTRL_STAT equ 0x30 ; Global Status |
CTRL_CAS equ 0x34 ; Codec Access Semiphore |
CTRL_TERA_UNK1 = 0x1200 |
CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit |
CTRL_RDC_R3010 = 0x3010 |
CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready |
CTRL_VMWARE_UNK1 = 0x1977 |
CTRL_ST_RCS equ 0x00008000 ; Read Completion Status |
API_VERSION = 0x01000100 |
CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable |
CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off |
CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset |
CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset |
CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable |
CODEC_REG_POWERDOWN equ 0x26 |
CODEC_REG_ST equ 0x26 |
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 |
DEV_GET_POS equ 9 |
struc AC_CNTRL ;AC controller base class |
{ .bus dd ? |
.devfn dd ? |
.vendor dd ? |
.dev_id dd ? |
.pci_cmd dd ? |
.pci_stat dd ? |
.codec_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_io_base dd ? |
.ctrl_mem_base dd ? |
.cfg_reg dd ? |
.int_line dd ? |
.vendor_ids dd ? ;vendor id string |
.ctrl_ids dd ? ;hub id string |
.buffer dd ? |
.notify_pos dd ? |
.notify_task dd ? |
.lvi_reg dd ? |
.ctrl_setup dd ? |
.user_callback dd ? |
.codec_read16 dd ? |
.codec_write16 dd ? |
.ctrl_read8 dd ? |
.ctrl_read16 dd ? |
.ctrl_read32 dd ? |
.ctrl_write8 dd ? |
.ctrl_write16 dd ? |
.ctrl_write32 dd ? |
} |
struc CODEC ;Audio Chip base class |
{ |
.chip_id dd ? |
.flags dd ? |
.status dd ? |
.ac_vendor_ids dd ? ;ac vendor id string |
.chip_ids dd ? ;chip model string |
.shadow_flag dd ? |
dd ? |
.regs dw ? ; codec registers |
.reg_master_vol dw ? ;0x02 |
.reg_aux_out_vol dw ? ;0x04 |
.reg_mone_vol dw ? ;0x06 |
.reg_master_tone dw ? ;0x08 |
.reg_beep_vol dw ? ;0x0A |
.reg_phone_vol dw ? ;0x0C |
.reg_mic_vol dw ? ;0x0E |
.reg_line_in_vol dw ? ;0x10 |
.reg_cd_vol dw ? ;0x12 |
.reg_video_vol dw ? ;0x14 |
.reg_aux_in_vol dw ? ;0x16 |
.reg_pcm_out_vol dw ? ;0x18 |
.reg_rec_select dw ? ;0x1A |
.reg_rec_gain dw ? ;0x1C |
.reg_rec_gain_mic dw ? ;0x1E |
.reg_gen dw ? ;0x20 |
.reg_3d_ctrl dw ? ;0X22 |
.reg_page dw ? ;0X24 |
.reg_powerdown dw ? ;0x26 |
.reg_ext_audio dw ? ;0x28 |
.reg_ext_st dw ? ;0x2a |
.reg_pcm_front_rate dw ? ;0x2c |
.reg_pcm_surr_rate dw ? ;0x2e |
.reg_lfe_rate dw ? ;0x30 |
.reg_pcm_in_rate dw ? ;0x32 |
dw ? ;0x34 |
.reg_cent_lfe_vol dw ? ;0x36 |
.reg_surr_vol dw ? ;0x38 |
.reg_spdif_ctrl dw ? ;0x3A |
dw ? ;0x3C |
dw ? ;0x3E |
dw ? ;0x40 |
dw ? ;0x42 |
dw ? ;0x44 |
dw ? ;0x46 |
dw ? ;0x48 |
dw ? ;0x4A |
dw ? ;0x4C |
dw ? ;0x4E |
dw ? ;0x50 |
dw ? ;0x52 |
dw ? ;0x54 |
dw ? ;0x56 |
dw ? ;0x58 |
dw ? ;0x5A |
dw ? ;0x5C |
dw ? ;0x5E |
.reg_page_0 dw ? ;0x60 |
.reg_page_1 dw ? ;0x62 |
.reg_page_2 dw ? ;0x64 |
.reg_page_3 dw ? ;0x66 |
.reg_page_4 dw ? ;0x68 |
.reg_page_5 dw ? ;0x6A |
.reg_page_6 dw ? ;0x6C |
.reg_page_7 dw ? ;0x6E |
dw ? ;0x70 |
dw ? ;0x72 |
dw ? ;0x74 |
dw ? ;0x76 |
dw ? ;0x78 |
dw ? ;0x7A |
.reg_vendor_id_1 dw ? ;0x7C |
.reg_vendor_id_2 dw ? ;0x7E |
.reset dd ? ;virual |
.set_master_vol dd ? |
} |
struc CTRL_INFO |
{ .pci_cmd dd ? |
.irq dd ? |
.glob_cntrl dd ? |
.glob_sta dd ? |
.codec_io_base dd ? |
.ctrl_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_mem_base dd ? |
.codec_id dd ? |
} |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
EVENT_NOTIFY equ 0x00000200 |
public START |
public service_proc |
public version |
306,340 → 162,22 |
end if |
call detect_controller |
test eax, eax |
jz .fail |
if DEBUG |
mov esi, [ctrl.vendor_ids] |
call SysMsgBoardStr |
mov esi, [ctrl.ctrl_ids] |
call SysMsgBoardStr |
end if |
call init_controller |
test eax, eax |
jz .fail |
call init_codec |
test eax, eax |
jz .fail |
call reset_controller |
call setup_codec |
mov esi, msgPrimBuff |
call SysMsgBoardStr |
call create_primary_buff |
mov esi, msgDone |
call SysMsgBoardStr |
if IRQ_REMAP |
pushf |
cli |
mov ebx, [ctrl.int_line] |
in al, 0xA1 |
mov ah, al |
in al, 0x21 |
test ebx, ebx |
jz .skip |
bts ax, bx ;mask old line |
.skip |
bts ax, IRQ_LINE ;mask new ine |
out 0x21, al |
mov al, ah |
out 0xA1, al |
;remap IRQ |
stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE |
mov dx, 0x4d0 ;8259 ELCR1 |
in al, dx |
bts ax, IRQ_LINE |
out dx, al ;set level-triggered mode |
mov [ctrl.int_line], IRQ_LINE |
popf |
mov esi, msgRemap |
call SysMsgBoardStr |
end if |
mov ebx, [ctrl.int_line] |
stdcall AttachIntHandler, ebx, ac97_irq, dword 0 |
.reg: |
stdcall RegService, sz_sound_srv, service_proc |
ret |
.fail: |
if DEBUG |
mov esi, msgFail |
call SysMsgBoardStr |
end if |
xor eax, eax |
ret |
.fail_msg: |
call SysMsgBoardStr |
xor eax, eax |
ret |
.stop: |
call stop |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [edi+output] |
cmp [edi+out_size], 4 |
jne .fail |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
@@: |
cmp eax, DEV_PLAY |
jne @F |
if DEBUG |
mov esi, msgPlay |
call SysMsgBoardStr |
end if |
call play |
ret |
@@: |
cmp eax, DEV_STOP |
jne @F |
if DEBUG |
mov esi, msgStop |
call SysMsgBoardStr |
end if |
call stop |
ret |
@@: |
cmp eax, DEV_CALLBACK |
jne @F |
mov ebx, [edi+input] |
stdcall set_callback, [ebx] |
ret |
@@: |
cmp eax, DEV_SET_MASTERVOL |
jne @F |
mov eax, [edi+input] |
mov eax, [eax] |
call set_master_vol ;eax= vol |
ret |
@@: |
cmp eax, DEV_GET_MASTERVOL |
jne @F |
mov ebx, [edi+output] |
stdcall get_master_vol, ebx |
ret |
@@: |
cmp eax, DEV_GET_POS |
jne @F |
mov ebx, 8192 |
mov edx, 0x18 |
xor eax, eax |
call [ctrl.ctrl_read16] |
sub ebx, eax |
shr ebx, 1 |
mov edx, [edi+output] |
mov [edx], ebx |
xor eax, eax |
ret |
;@@: |
; cmp eax, DEV_GET_INFO |
; jne @F |
; mov ebx, [edi+output] |
; stdcall get_dev_info, ebx |
; ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc ac97_irq |
proc detect_controller |
if DEBUG_IRQ |
mov esi, msgIRQ |
call SysMsgBoardStr |
end if |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
cmp eax, 0xffffffff |
je .exit |
test eax, 0x40 |
jnz .do_intr |
test eax, eax |
jz .exit |
mov edx, CTRL_STAT |
call [ctrl.ctrl_write32] |
.exit: |
xor eax, eax |
ret |
.do_intr: |
push eax |
mov edx, PCM_OUT_CR_REG |
mov al, 0x10; 0x10 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
mov edx, PCM_OUT_CIV_REG |
call [ctrl.ctrl_read8] |
and eax, 0x1F |
cmp eax, [civ_val] |
je .skip |
mov [civ_val], eax |
dec eax |
and eax, 0x1F |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 ;0x1D |
call [ctrl.ctrl_write8] |
mov eax, [civ_val] |
add eax, 1 |
and eax, 31 |
mov ebx, dword [buff_list+eax*4] |
cmp [ctrl.user_callback], 0 |
je .done |
stdcall [ctrl.user_callback], ebx |
.done: |
pop eax |
and eax, 0x40 |
mov edx, CTRL_STAT |
call [ctrl.ctrl_write32] |
or eax, 1 |
ret |
.skip: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 ;0x1D |
call [ctrl.ctrl_write8] |
jmp .done |
endp |
align 4 |
proc create_primary_buff |
stdcall KernelAlloc, 0x10000 |
mov [ctrl.buffer], eax |
mov edi, eax |
mov ecx, 0x10000/4 |
xor eax, eax |
cld |
rep stosd |
mov eax, [ctrl.buffer] |
call GetPgAddr |
mov ebx, 0xC0002000 |
mov ecx, 4 |
mov edi, pcmout_bdl |
@@: |
mov [edi], eax |
mov [edi+4], ebx |
mov [edi+32], eax |
mov [edi+4+32], ebx |
mov [edi+64], eax |
mov [edi+4+64], ebx |
mov [edi+96], eax |
mov [edi+4+96], ebx |
mov [edi+128], eax |
mov [edi+4+128], ebx |
mov [edi+160], eax |
mov [edi+4+160], ebx |
mov [edi+192], eax |
mov [edi+4+192], ebx |
mov [edi+224], eax |
mov [edi+4+224], ebx |
add eax, 0x4000 |
add edi, 8 |
loop @B |
mov edi, buff_list |
mov eax, [ctrl.buffer] |
mov ecx, 4 |
@@: |
mov [edi], eax |
mov [edi+16], eax |
mov [edi+32], eax |
mov [edi+48], eax |
mov [edi+64], eax |
mov [edi+80], eax |
mov [edi+96], eax |
mov [edi+112], eax |
add eax, 0x4000 |
add edi, 4 |
loop @B |
mov eax, pcmout_bdl |
mov ebx, eax |
call GetPgAddr ;eax |
and ebx, 0xFFF |
add eax, ebx |
mov edx, PCM_OUT_BDL |
call [ctrl.ctrl_write32] |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc detect_controller |
locals |
last_bus dd ? |
bus dd ? |
672,7 → 210,7 |
cmp eax, ebx |
je .found |
add edi, 12 |
add edi, 8 |
jmp @B |
.next: |
inc [devfn] |
686,822 → 224,170 |
xor eax, eax |
ret |
.found: |
mov ebx, [bus] |
mov [ctrl.bus], ebx |
mov ecx, [devfn] |
mov [ctrl.devfn], ecx |
mov edx, eax |
and edx, 0xFFFF |
mov [ctrl.vendor], edx |
shr eax, 16 |
mov [ctrl.dev_id], eax |
mov ebx, [edi+4] |
mov [ctrl.ctrl_ids], ebx |
mov esi, [edi+8] |
mov [ctrl.ctrl_setup], esi |
cmp edx, VID_INTEL |
jne @F |
mov [ctrl.vendor_ids], msg_Intel |
ret |
@@: |
cmp edx, VID_NVIDIA |
jne @F |
mov [ctrl.vendor_ids], msg_NVidia |
ret |
@@: |
.err: |
xor eax, eax |
mov [ctrl.vendor_ids], eax ;something wrong ? |
ret |
endp |
align 4 |
proc init_controller |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 |
mov ebx, eax |
and eax, 0xFFFF |
mov [ctrl.pci_cmd], eax |
shr ebx, 16 |
mov [ctrl.pci_stat], ebx |
mov esi, msgPciCmd |
if DEBUG |
mov esi, msgLoading |
call SysMsgBoardStr |
call dword2str |
call SysMsgBoardStr |
mov esi, msgPciStat |
mov esi, dword[edi+4] |
call SysMsgBoardStr |
mov eax, [ctrl.pci_stat] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgMixIsaIo |
mov esi, msgNewline |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 |
call dword2str |
call SysMsgBoardStr |
and eax, 0xFFFE |
mov [ctrl.codec_io_base], eax |
mov esi, msgCtrlIsaIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14 |
call dword2str |
call SysMsgBoardStr |
and eax, 0xFFC0 |
mov [ctrl.ctrl_io_base], eax |
mov esi, msgMixMMIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18 |
mov [ctrl.codec_mem_base], eax |
call dword2str |
call SysMsgBoardStr |
mov esi, msgCtrlMMIo |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C |
mov [ctrl.ctrl_mem_base], eax |
call dword2str |
call SysMsgBoardStr |
if 0 |
;;patch for some ugly BIOS ICH-ICH5 compatible |
cmp [ctrl.vendor], VID_INTEL |
jne .default |
mov esi, msgIrqMap |
call SysMsgBoardStr |
stdcall PciRead8, 0, 0xF8, 0x61 |
and eax, 0xFF |
call dword2str |
call SysMsgBoardStr |
btr eax, 7 ;when bit 7 set remap disabled |
jnc @F |
xor eax, eax |
jmp @F |
end if |
.default: |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C |
and eax, 0xFF |
@@: |
mov [ctrl.int_line], eax |
stdcall GetService, dword[edi+4] |
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41 |
and eax, 0xFF |
mov [ctrl.cfg_reg], eax |
mov [ctrl.user_callback], 0 |
call [ctrl.ctrl_setup] |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc set_ICH |
mov [ctrl.codec_read16], codec_io_r16 ;virtual |
mov [ctrl.codec_write16], codec_io_w16 ;virtual |
mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual |
mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual |
mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual |
mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual |
mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual |
mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual |
ret |
endp |
PG_SW equ 0x003 |
PG_NOCACHE equ 0x018 |
align 4 |
proc set_ICH4 |
stdcall MapIoMem, [ctrl.codec_mem_base], 0x1000, PG_SW+PG_NOCACHE |
mov [ctrl.codec_mem_base], eax |
stdcall MapIoMem, [ctrl.ctrl_mem_base], 0x1000, PG_SW+PG_NOCACHE |
mov [ctrl.ctrl_mem_base], eax |
mov [ctrl.codec_read16], codec_mem_r16 ;virtual |
mov [ctrl.codec_write16], codec_mem_w16 ;virtual |
mov [ctrl.ctrl_read8 ], ctrl_mem_r8 ;virtual |
mov [ctrl.ctrl_read16], ctrl_mem_r16 ;virtual |
mov [ctrl.ctrl_read32], ctrl_mem_r32 ;virtual |
mov [ctrl.ctrl_write8 ], ctrl_mem_w8 ;virtual |
mov [ctrl.ctrl_write16], ctrl_mem_w16 ;virtual |
mov [ctrl.ctrl_write32], ctrl_mem_w32 ;virtual |
ret |
endp |
align 4 |
proc reset_controller |
xor eax, eax |
mov edx, PCM_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, MC_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov eax, RR |
mov edx, PCM_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, MC_IN_CR_REG |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc init_codec |
locals |
counter dd ? |
endl |
mov esi, msgControl |
call SysMsgBoardStr |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgStatus |
call SysMsgBoardStr |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
push eax |
call dword2str |
call SysMsgBoardStr |
pop eax |
cmp eax, 0xFFFFFFFF |
je .err |
test eax, CTRL_ST_CREADY |
jnz .ready |
call reset_codec |
test eax, eax |
jz .err |
.ready: |
xor edx, edx ;ac_reg_0 |
call [ctrl.codec_write16] |
xor eax, eax |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_write16] |
mov [counter], 200 ; total 200*5 ms = 1s |
.wait: |
mov eax, 5000 ; wait 5 ms |
call StallExec |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_read16] |
and eax, 0x0F |
cmp eax, 0x0F |
jz .done |
sub [counter] , 1 |
jnz .wait |
.err: |
xor eax, eax ; timeout error |
ret |
.done: |
mov eax, 2 ;force set 16-bit 2-channel PCM |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
mov eax, 5000 ; wait 5 ms |
call StallExec |
call detect_codec |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc reset_codec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 0x02 |
jz .cold |
call warm_reset |
jnc .ok |
.cold: |
call cold_reset |
jnc .ok |
if DEBUG |
mov esi, msgCFail |
mov esi, msgFail |
call SysMsgBoardStr |
end if |
xor eax, eax ; timeout error |
ret |
.ok: |
if DEBUG |
mov esi, msgResetOk |
call SysMsgBoardStr |
end if |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc warm_reset |
locals |
counter dd ? |
endl |
mov eax, 0x06 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgWarm |
call SysMsgBoardStr |
end if |
mov [counter], 10 ; total 10*100 ms = 1s |
.wait: |
mov eax, 100000 ; wait 100 ms |
call StallExec |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_CREADY |
jnz .ok |
dec [counter] |
jnz .wait |
if DEBUG |
mov esi, msgWRFail |
call SysMsgBoardStr |
end if |
.fail: |
stc |
ret |
.ok: |
clc |
ret |
endp |
align 4 |
proc cold_reset |
locals |
counter dd ? |
endl |
devices dd (CTRL_ICH shl 16)+VID_INTEL, intelac97 |
dd (CTRL_ICH0 shl 16)+VID_INTEL, intelac97 |
dd (CTRL_ICH2 shl 16)+VID_INTEL, intelac97 |
dd (CTRL_ICH3 shl 16)+VID_INTEL, intelac97 |
dd (CTRL_ICH4 shl 16)+VID_INTEL, intelac97 |
dd (CTRL_ICH5 shl 16)+VID_INTEL, intelac97 |
dd (CTRL_ICH6 shl 16)+VID_INTEL, intelac97 |
dd (CTRL_ICH7 shl 16)+VID_INTEL, intelac97 |
mov eax, 0x02 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
dd (CTRL_NFORCE shl 16)+VID_NVIDIA, intelac97 |
dd (CTRL_NFORCE2 shl 16)+VID_NVIDIA, intelac97 |
dd (CTRL_NFORCE3 shl 16)+VID_NVIDIA, intelac97 |
dd (CTRL_MCP04 shl 16)+VID_NVIDIA, intelac97 |
dd (CTRL_CK804 shl 16)+VID_NVIDIA, intelac97 |
dd (CTRL_CK8 shl 16)+VID_NVIDIA, intelac97 |
dd (CTRL_CK8S shl 16)+VID_NVIDIA, intelac97 |
dd (CTRL_MCP51 shl 16)+VID_NVIDIA, intelac97 |
if DEBUG |
mov esi, msgCold |
call SysMsgBoardStr |
end if |
dd (CTRL_VT82C686 shl 16)+VID_VIA, vt823x |
dd (CTRL_VT8233_5 shl 16)+VID_VIA, vt823x |
mov eax, 400000 ; wait 400 ms |
call StallExec |
dd (CTRL_SIS shl 16)+VID_SIS, sis |
mov [counter], 16 ; total 20*100 ms = 2s |
.wait: |
dd (CTRL_FM801 shl 16)+VID_FM801, fm801 |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_CREADY |
jnz .ok |
dd (0x5000 shl 16)+0x1274, ensoniq |
dd (0x5880 shl 16)+0x1274, ensoniq |
mov eax, 100000 ; wait 100 ms |
call StallExec |
dd (CTRL_CT0200 shl 16)+VID_CREATIVE, emu10k1x |
; Intel |
dd (CTRL_INTEL_SCH2 shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_HPT shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_CPT shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_PGB shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_PPT1 shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_82801F shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_63XXESB shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_82801G shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_82801H shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_82801_UNK1 shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_82801I shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_82801_UNK2 shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_82801JI shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_82801JD shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_PCH shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_PCH2 shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_SCH shl 16)+VID_INTEL, intelhda |
dd (CTRL_INTEL_LPT shl 16)+VID_INTEL, intelhda |
; Nvidia |
dd (CTRL_NVIDIA_MCP51 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP55 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP61_1 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP61_2 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP65_1 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP65_2 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP67_1 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP67_2 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP73_1 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP73_2 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP78_1 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP78_2 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP78_3 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP78_4 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP79_1 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP79_2 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP79_3 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP79_4 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_0BE2 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_0BE3 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_0BE4 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_GT100 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_GT106 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_GT108 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_GT104 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_GT116 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP89_1 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP89_2 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP89_3 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_MCP89_4 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_GF119 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_GF110_1 shl 16)+VID_NVIDIA, intelhda |
dd (CTRL_NVIDIA_GF110_2 shl 16)+VID_NVIDIA, intelhda |
; ATI |
dd (CTRL_ATI_SB450 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_SB600 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RS600 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RS690 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RS780 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RS_UNK1 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_R600 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RV610 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RV620 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RV630 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RV635 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RV670 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RV710 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RV730 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RV740 shl 16)+VID_ATI, intelhda |
dd (CTRL_ATI_RV770 shl 16)+VID_ATI, intelhda |
; AMD |
dd (CTRL_AMD_HUDSON shl 16)+VID_AMD, intelhda |
; VIA |
dd (CTRL_VIA_VT82XX shl 16)+VID_VIA, intelhda |
dd (CTRL_VIA_VT61XX shl 16)+VID_VIA, intelhda |
dd (CTRL_VIA_VT71XX shl 16)+VID_VIA, intelhda |
; SiS |
dd (CTRL_SIS_966 shl 16)+VID_SIS, intelhda |
; ULI |
dd (CTRL_ULI_M5461 shl 16)+VID_ULI, intelhda |
; Teradici |
dd (CTRL_TERA_UNK1 shl 16)+VID_ULI, intelhda |
; Creative |
dd (CTRL_CREATIVE_CA0110_IBG shl 16)+VID_CREATIVE, intelhda |
dd (CTRL_CREATIVE_SOUND_CORE3D_1 shl 16)+VID_CREATIVE, intelhda |
dd (CTRL_CREATIVE_SOUND_CORE3D_2 shl 16)+VID_CREATIVE, intelhda |
; RDC Semiconductor |
dd (CTRL_RDC_R3010 shl 16)+VID_RDC, intelhda |
; VMware |
dd (CTRL_VMWARE_UNK1 shl 16)+VID_VMWARE, intelhda |
dec [counter] |
jnz .wait |
if DEBUG |
mov esi, msgCRFail |
call SysMsgBoardStr |
end if |
.fail: |
stc |
ret |
.ok: |
mov esi, msgControl |
call SysMsgBoardStr |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgStatus |
call SysMsgBoardStr |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
push eax |
call dword2str |
call SysMsgBoardStr |
pop eax |
test eax, CTRL_ST_CREADY |
jz .fail |
clc |
ret |
endp |
align 4 |
play: |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x1D |
call [ctrl.ctrl_write8] |
xor eax, eax |
ret |
align 4 |
stop: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x0 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
xor eax, eax |
ret |
align 4 |
proc get_dev_info stdcall, p_info:dword |
virtual at esi |
CTRL_INFO CTRL_INFO |
end virtual |
mov esi, [p_info] |
mov eax, [ctrl.int_line] |
mov ebx, [ctrl.codec_io_base] |
mov ecx, [ctrl.ctrl_io_base] |
mov edx, [ctrl.codec_mem_base] |
mov edi, [ctrl.ctrl_mem_base] |
mov [CTRL_INFO.irq], eax |
mov [CTRL_INFO.codec_io_base], ebx |
mov [CTRL_INFO.ctrl_io_base], ecx |
mov [CTRL_INFO.codec_mem_base], edx |
mov [CTRL_INFO.ctrl_mem_base], edi |
mov eax, [codec.chip_id] |
mov [CTRL_INFO.codec_id], eax |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_cntrl], eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_sta], eax |
mov ebx, [ctrl.pci_cmd] |
mov [CTRL_INFO.pci_cmd], ebx |
ret |
endp |
align 4 |
proc set_callback stdcall, handler:dword |
mov eax, [handler] |
mov [ctrl.user_callback], eax |
ret |
endp |
align 4 |
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax |
mov edx, [ac_reg] |
mov ebx, edx |
shr ebx, 1 |
bt [codec.shadow_flag], ebx |
jc .use_shadow |
call [ctrl.codec_read16] ;change edx !!! |
mov ecx, eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_RCS |
jz .read_ok |
mov edx, CTRL_STAT |
call [ctrl.ctrl_write32] |
xor eax, eax |
not eax ;timeout |
ret |
.read_ok: |
mov edx, [ac_reg] |
mov [codec.regs+edx], cx |
bts [codec.shadow_flag], ebx |
mov eax, ecx |
ret |
.use_shadow: |
movzx eax, word [codec.regs+edx] |
ret |
endp |
align 4 |
proc codec_write stdcall, ac_reg:dword |
push eax |
call check_semafore |
and eax, eax |
jz .err |
pop eax |
mov esi, [ac_reg] |
mov edx, esi |
call [ctrl.codec_write16] |
mov [codec.regs+esi], ax |
shr esi, 1 |
bts [codec.shadow_flag], esi |
ret |
.err: |
pop eax |
ret |
endp |
align 4 |
proc codec_check_ready |
mov edx, CTRL_ST |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .not_ready |
xor eax, wax |
inc eax |
ret |
.not_ready: |
xor eax, eax |
ret |
endp |
align 4 |
proc check_semafore |
local counter:DWORD |
mov [counter], 100 |
.l1: |
mov edx, CTRL_CAS |
call [ctrl.ctrl_read8] |
and eax, CAS_FLAG |
jz .ok |
mov eax, 1 |
call StallExec |
sub [counter], 1 |
jnz .l1 |
xor eax, eax |
ret |
align 4 |
.ok: |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc StallExec |
push ecx |
push edx |
push ebx |
push eax |
mov ecx, CPU_FREQ |
mul ecx |
mov ebx, eax ;low |
mov ecx, edx ;high |
rdtsc |
add ebx, eax |
adc ecx, edx |
@@: |
rdtsc |
sub eax, ebx |
sbb edx, ecx |
js @B |
pop eax |
pop ebx |
pop edx |
pop ecx |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; CONTROLLER IO functions |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
proc codec_io_r16 |
add edx, [ctrl.codec_io_base] |
in ax, dx |
ret |
endp |
align 4 |
proc codec_io_w16 |
add edx, [ctrl.codec_io_base] |
out dx, ax |
ret |
endp |
align 4 |
proc ctrl_io_r8 |
add edx, [ctrl.ctrl_io_base] |
in al, dx |
ret |
endp |
align 4 |
proc ctrl_io_r16 |
add edx, [ctrl.ctrl_io_base] |
in ax, dx |
ret |
endp |
align 4 |
proc ctrl_io_r32 |
add edx, [ctrl.ctrl_io_base] |
in eax, dx |
ret |
endp |
align 4 |
proc ctrl_io_w8 |
add edx, [ctrl.ctrl_io_base] |
out dx, al |
ret |
endp |
align 4 |
proc ctrl_io_w16 |
add edx, [ctrl.ctrl_io_base] |
out dx, ax |
ret |
endp |
align 4 |
proc ctrl_io_w32 |
add edx, [ctrl.ctrl_io_base] |
out dx, eax |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; MEMORY MAPPED IO (os depended) |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
proc codec_mem_r16 |
add edx, [ctrl.codec_mem_base] |
mov ax, word [edx] |
ret |
endp |
align 4 |
proc codec_mem_w16 |
add edx, [ctrl.codec_mem_base] |
mov word [edx], ax |
ret |
endp |
align 4 |
proc ctrl_mem_r8 |
add edx, [ctrl.ctrl_mem_base] |
mov al, [edx] |
ret |
endp |
align 4 |
proc ctrl_mem_r16 |
add edx, [ctrl.ctrl_mem_base] |
mov ax, [edx] |
ret |
endp |
align 4 |
proc ctrl_mem_r32 |
add edx, [ctrl.ctrl_mem_base] |
mov eax, [edx] |
ret |
endp |
align 4 |
proc ctrl_mem_w8 |
add edx, [ctrl.ctrl_mem_base] |
mov [edx], al |
ret |
endp |
align 4 |
proc ctrl_mem_w16 |
add edx, [ctrl.ctrl_mem_base] |
mov [edx], ax |
ret |
endp |
align 4 |
proc ctrl_mem_w32 |
add edx, [ctrl.ctrl_mem_base] |
mov [edx], eax |
ret |
endp |
align 4 |
dword2str: |
mov esi, hex_buff |
mov ecx, -8 |
@@: |
rol eax, 4 |
mov ebx, eax |
and ebx, 0x0F |
mov bl, [ebx+hexletters] |
mov [8+esi+ecx], bl |
inc ecx |
jnz @B |
ret |
hexletters db '0123456789ABCDEF' |
hex_buff db 8 dup(0),13,10,0 |
include "codec.inc" |
align 4 |
devices dd (CTRL_ICH shl 16)+VID_INTEL,msg_ICH, set_ICH |
dd (CTRL_ICH0 shl 16)+VID_INTEL,msg_ICH0,set_ICH |
dd (CTRL_ICH2 shl 16)+VID_INTEL,msg_ICH2,set_ICH |
dd (CTRL_ICH3 shl 16)+VID_INTEL,msg_ICH3,set_ICH |
dd (CTRL_ICH4 shl 16)+VID_INTEL,msg_ICH4,set_ICH4 |
dd (CTRL_ICH5 shl 16)+VID_INTEL,msg_ICH5,set_ICH4 |
dd (CTRL_ICH6 shl 16)+VID_INTEL,msg_ICH6,set_ICH4 |
dd (CTRL_ICH7 shl 16)+VID_INTEL,msg_ICH7,set_ICH4 |
dd (CTRL_NFORCE shl 16)+VID_NVIDIA,msg_NForce, set_ICH |
dd (CTRL_NFORCE2 shl 16)+VID_NVIDIA,msg_NForce2,set_ICH |
dd (CTRL_NFORCE3 shl 16)+VID_NVIDIA,msg_NForce3,set_ICH |
dd (CTRL_MCP04 shl 16)+VID_NVIDIA,msg_MCP04,set_ICH |
dd (CTRL_CK804 shl 16)+VID_NVIDIA,msg_CK804,set_ICH |
dd (CTRL_CK8 shl 16)+VID_NVIDIA,msg_CK8,set_ICH |
dd (CTRL_CK8S shl 16)+VID_NVIDIA,msg_CK8S,set_ICH |
dd (CTRL_MCP51 shl 16)+VID_NVIDIA,msg_MCP51,set_ICH |
dd 0 ;terminator |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
msg_ICH db '802801AA (ICH)', 13,10, 0 |
msg_ICH0 db '802801AB (ICH0)', 13,10, 0 |
msg_ICH2 db '802801BA (ICH2)', 13,10, 0 |
msg_ICH3 db '802801CA (ICH3)', 13,10, 0 |
msg_ICH4 db '802801DB (ICH4)', 13,10, 0 |
msg_ICH5 db '802801EB (ICH5)', 13,10, 0 |
msg_ICH6 db '802801FB (ICH6)', 13,10, 0 |
msg_ICH7 db '802801GB (ICH7)', 13,10, 0 |
msg_Intel db 'Intel ', 0 |
intelac97 db 'INTELAC97', 0 |
vt823x db 'VT823X', 0 |
sis db 'SIS', 0 |
fm801 db 'FM801', 0 |
ensoniq db 'ENSONIQ', 0 |
emu10k1x db 'EMU10K1X', 0 |
intelhda db 'INTEL_HDA', 0 |
msg_NForce db 'NForce', 13,10, 0 |
msg_NForce2 db 'NForce 2', 13,10, 0 |
msg_NForce3 db 'NForce 3', 13,10, 0 |
msg_MCP04 db 'NForce MCP04',13,10, 0 |
msg_CK804 db 'NForce CK804',13,10, 0 |
msg_CK8 db 'NForce CK8', 13,10, 0 |
msg_CK8S db 'NForce CK8S', 13,10, 0 |
msg_MCP51 db 'NForce MCP51',13,10, 0 |
msgInit db 'Detecting hardware...',13,10,0 |
msgFail db 'No compatible soundcard found!',13,10,0 |
msgLoading db 'Loading ',0 |
msgNewline db 13,10,0 |
msg_NVidia db 'NVidia', 0 |
szKernel db 'KERNEL', 0 |
sz_sound_srv db 'SOUND',0 |
msgInit db 'detect hardware...',13,10,0 |
msgFail db 'device not found',13,10,0 |
msgAttchIRQ db 'IRQ line not supported', 13,10, 0 |
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 |
msgPlay db 'start play', 13,10,0 |
msgStop db 'stop play', 13,10,0 |
;msgNotify db 'call notify',13,10,0 |
msgIRQ db 'AC97 IRQ', 13,10,0 |
msgInitCtrl db 'init controller',13,10,0 |
;msgInitCodec db 'init codec',13,10,0 |
msgPrimBuff db 'create primary buffer ...',0 |
msgDone db 'done',13,10,0 |
msgRemap db 'Remap IRQ',13,10,0 |
;msgReg db 'set service handler',13,10,0 |
msgOk db 'service installed',13,10,0 |
msgCold db 'cold reset',13,10,0 |
msgWarm db 'warm reset',13,10,0 |
msgWRFail db 'warm reset failed',13,10,0 |
msgCRFail db 'cold reset failed',13,10,0 |
msgCFail db 'codec not ready',13,10,0 |
msgResetOk db 'reset complete',13,10,0 |
msgStatus db 'global status ',0 |
msgControl db 'global control ',0 |
msgPciCmd db 'PCI command ',0 |
msgPciStat db 'PCI status ',0 |
msgCtrlIsaIo db 'controller io base ',0 |
msgMixIsaIo db 'codec io base ',0 |
msgCtrlMMIo db 'controller mmio base ',0 |
msgMixMMIo db 'codec mmio base ',0 |
msgIrqMap db 'AC97 irq map as ',0 |
section '.data' data readable writable align 16 |
pcmout_bdl rq 32 |
buff_list rd 32 |
codec CODEC |
ctrl AC_CNTRL |
lpc_bus rd 1 |
civ_val rd 1 |
/kernel/branches/Kolibri-acpi/drivers/tmpdisk.asm |
---|
0,0 → 1,295 |
; Disk driver to create FAT16/FAT32 memory-based temporary disk aka RAM disk. |
; (c) CleverMouse |
; Note: in the ideal world, a disk driver should not care about a file system |
; on it. In the current world, however, there is no way to format a disk in |
; FAT, so this part of file-system-specific operations is included in the |
; driver. |
; When this driver is loading, it registers itself in the system and does |
; nothing more. When loaded, this driver controls pseudo-disk devices |
; named /tmp#/, where # is a digit from 0 to 9. The driver does not create |
; any device by itself, waiting for instructions from an application. |
; The driver responds to the following IOCTLs from a control application: |
SRV_GETVERSION equ 0 ; input ignored, |
; output = dword API_VERSION |
DEV_ADD_DISK equ 1 ; input = structure add_disk_struc, |
; no output |
DEV_DEL_DISK equ 2 ; input = structure del_disk_struc, |
; no output |
; For all IOCTLs the driver returns one of the following error codes: |
NO_ERROR equ 0 |
ERROR_INVALID_IOCTL equ 1 ; unknown IOCTL code, wrong input/output size... |
ERROR_INVALID_ID equ 2 ; .DiskId must be from 0 to 9 |
ERROR_SIZE_TOO_LARGE equ 3 ; .DiskSize is too large |
ERROR_SIZE_TOO_SMALL equ 4 ; .DiskSize is too small |
ERROR_NO_MEMORY equ 5 ; memory allocation failed |
API_VERSION equ 1 |
; Input structures: |
struc add_disk_struc |
{ |
.DiskSize dd ? ; disk size in sectors, 1 sector = 512 bytes |
; Note: .DiskSize is the full size, including FAT service data. |
; Size for useful data is slightly less than this number. |
.DiskId db ? ; from 0 to 9 |
.sizeof: |
} |
virtual at 0 |
add_disk_struc add_disk_struc |
end virtual |
struc del_disk_struc |
{ |
.DiskId db ? ; from 0 to 9 |
.sizeof: |
} |
virtual at 0 |
del_disk_struc del_disk_struc |
end virtual |
max_num_disks equ 10 |
; standard driver stuff |
format MS COFF |
DEBUG equ 0 |
include 'proc32.inc' |
include 'imports.inc' |
public START |
public version |
struc IOCTL |
{ |
.handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
section '.flat' code readable align 16 |
; the start procedure (see the description above) |
proc START |
; This procedure is called in two situations: |
; when the driver is loading and when the system is shutting down. |
; 1. Check that the driver is loading; do nothing unless so. |
xor eax, eax ; set return value in case we will do nothing |
cmp dword [esp+4], 1 |
jne .nothing |
; 2. Register the driver in the system. |
stdcall RegService, my_service, service_proc |
; 3. Return the value returned by RegService back to the system. |
.nothing: |
retn 4 |
endp |
; Service procedure for the driver - handle all IOCTL requests for the driver. |
; The description of handled IOCTLs is located in the start of this file. |
proc service_proc |
; 1. Save used registers to be stdcall. |
; Note: this shifts esp, so the first parameter [esp+4] becomes [esp+16]. |
; Note: edi is used not by this procedure itself, but by worker procedures. |
push ebx esi edi |
; 2. Get parameter from the stack: [esp+16] is the first parameter, |
; pointer to IOCTL structure. |
mov edx, [esp+16] ; edx -> IOCTL |
; 3. Set the return value to 'invalid IOCTL'. |
; Now, if one of conditions for IOCTL does not met, the code |
; can simply return the value already loaded. |
mov al, ERROR_INVALID_IOCTL |
; 4. Get request code and select a handler for the code. |
mov ecx, [edx+IOCTL.io_code] |
test ecx, ecx ; check for SRV_GETVERSION |
jnz .no.srv_getversion |
; 4. This is SRV_GETVERSION request, no input, 4 bytes output, API_VERSION. |
; 4a. Output size must be at least 4 bytes. |
cmp [edx+IOCTL.out_size], 4 |
jl .return |
; 4b. Write result to the output buffer. |
mov eax, [edx+IOCTL.output] |
mov dword [eax], API_VERSION |
; 4c. Return success. |
xor eax, eax |
jmp .return |
.no.srv_getversion: |
dec ecx ; check for DEV_ADD_DISK |
jnz .no.dev_add_disk |
; 5. This is DEV_ADD_DISK request, input is add_disk_struc, output is 1 byte |
; 5a. Input size must be exactly add_disk_struc.sizeof bytes. |
cmp [edx+IOCTL.inp_size], add_disk_struc.sizeof |
jnz .return |
; 5b. Load input parameters and call the worker procedure. |
mov eax, [edx+IOCTL.input] |
movzx ebx, [eax+add_disk_struc.DiskId] |
mov esi, [eax+add_disk_struc.DiskSize] |
call add_disk |
; 5c. Return back to the caller the value from the worker procedure. |
jmp .return |
.no.dev_add_disk: |
dec ecx ; check for DEV_DEL_DISK |
jnz .return |
; 6. This is DEV_DEL_DISK request, input is del_disk_struc |
; 6a. Input size must be exactly del_disk_struc.sizeof bytes. |
cmp [edx+IOCTL.inp_size], del_disk_struc.sizeof |
jnz .return |
; 6b. Load input parameters and call the worker procedure. |
mov eax, [edx+IOCTL.input] |
movzx ebx, [eax+del_disk_struc.DiskId] |
call del_disk |
; 6c. Return back to the caller the value from the worker procedure. |
.return: |
; 7. Exit. |
; 7a. The code above returns a value in al for efficiency, |
; propagate it to eax. |
movzx eax, al |
; 7b. Restore used registers to be stdcall. |
pop edi esi ebx |
; 7c. Return, popping one argument. |
retn 4 |
endp |
; The worker procedure for DEV_ADD_DISK request. |
; Creates a memory-based disk of given size and formats it in FAT16/32. |
; Called with ebx = disk id, esi = disk size, |
; returns error code in al. |
proc add_disk |
; 1. Check that disk id is correct and free. |
; Otherwise, return the corresponding error code. |
mov al, ERROR_INVALID_ID |
cmp ebx, max_num_disks |
jae .return |
cmp [disk_pointers+ebx*4], 0 |
jnz .return |
; 2. Check that the size is reasonable. |
; Otherwise, return the corresponding error code. |
mov al, ERROR_SIZE_TOO_LARGE |
cmp esi, MAX_SIZE |
ja .return |
mov al, ERROR_SIZE_TOO_SMALL |
cmp esi, MIN_FAT16_SIZE |
jb .return |
; 3. Allocate memory for the disk, store the pointer in edi. |
; If failed, return the corresponding error code. |
mov eax, esi |
shl eax, 9 |
stdcall KernelAlloc, eax |
mov edi, eax |
test eax, eax |
mov al, ERROR_NO_MEMORY |
jz .return |
; 4. Store the pointer and the size in the global variables. |
; It is possible, though very unlikely, that two threads |
; have called this function in parallel with the same id, |
; so [disk_pointers+ebx*4] could be filled by another thread. |
; Play extra safe and store new value only if old value is zero. |
xor eax, eax |
lock cmpxchg [disk_pointers+ebx*4], edi |
jz @f |
; Otherwise, free the allocated memory and return the corresponding error code. |
stdcall KernelFree, edi |
mov al, ERROR_INVALID_ID |
jmp .return |
@@: |
mov [disk_sizes+ebx*4], esi |
; 5. Call the worker procedure for formatting this disk. |
; It should not fail. |
call format_disk |
; 6. Register the disk in the system. |
; 6a. Generate name as /tmp#, where # = ebx + '0'. Use two dwords in the stack. |
push 0 |
push 'tmp' |
mov eax, esp ; eax points to 'tmp' + zero byte + zero dword |
lea ecx, [ebx+'0'] ; ecx = digit |
mov [eax+3], cl ; eax points to 'tmp#' + zero dword |
; 6b. Call the kernel API. Use disk id as 'userdata' parameter for callbacks. |
stdcall DiskAdd, disk_functions, eax, ebx, 0 |
; 6c. Restore the stack after 6a. |
pop ecx ecx |
; 6c. Check the result. If DiskAdd has failed, cleanup and return |
; ERROR_NO_MEMORY, this is the most probable or even the only reason to fail. |
test eax, eax |
jnz @f |
mov [disk_sizes+ebx*4], 0 |
mov [disk_pointers+ebx*4], 0 |
stdcall KernelFree, edi |
mov al, ERROR_NO_MEMORY |
jmp .return |
@@: |
push eax |
; 6d. Notify the kernel that media is inserted. |
stdcall DiskMediaChanged, eax, 1 |
; 6e. Disk is fully configured; store its handle in the global variable |
; and return success. |
pop [disk_handles+ebx*4] |
xor eax, eax |
; 7. Return. |
.return: |
retn |
endp |
; The worker procedure for DEV_DEL_DISK request. |
; Deletes a previously created memory-based disk. |
; Called with ebx = disk id, |
; returns error code in al. |
proc del_disk |
; 1. Check that disk id is correct. |
; Otherwise, return the corresponding error code. |
mov al, ERROR_INVALID_ID |
cmp ebx, max_num_disks |
jae .return |
; 2. Get the disk handle, simultaneously clearing the global variable. |
xor edx, edx |
xchg edx, [disk_handles+ebx*4] |
; 3. Check that the handle is non-zero. |
; Otherwise, return the corresponding error code. |
test edx, edx |
jz .return |
; 4. Delete the disk from the system. |
stdcall DiskDel, edx |
; 5. Return success. |
; Note that we can't free memory yet; it will be done in tmpdisk_close. |
xor eax, eax |
.return: |
retn |
endp |
; Include implementation of tmpdisk_* callbacks. |
include 'tmpdisk_work.inc' |
; Include FAT-specific code. |
include 'tmpdisk_fat.inc' |
; initialized data |
align 4 |
disk_functions: |
dd disk_functions_end - disk_functions |
dd tmpdisk_close |
dd 0 ; no need in .closemedia |
dd tmpdisk_querymedia |
dd tmpdisk_read |
dd tmpdisk_write |
dd 0 ; no need in .flush |
dd tmpdisk_adjust_cache_size |
disk_functions_end: |
; disk_handles = array of values for Disk* kernel functions |
label disk_handles dword |
times max_num_disks dd 0 |
; disk_pointers = array of pointers to disk data |
label disk_pointers dword |
times max_num_disks dd 0 |
; disk_sizes = array of disk sizes |
label disk_sizes dword |
times max_num_disks dd 0 |
version dd 0x00060006 |
my_service db 'tmpdisk',0 |
; uninitialized data |
; actually, not used here |
;section '.data' data readable writable align 16 ; standard driver stuff |
/kernel/branches/Kolibri-acpi/drivers/tmpdisk_fat.inc |
---|
0,0 → 1,327 |
; FAT-specific code for tmpdisk.asm. |
; Formats a disk to FAT16 or FAT32, depending on size. |
; Note: formatting is adjusted for memory-based disks. Although the resulting |
; image is a valid FAT32 volume, it has no "spare" sectors, e.g. second copy |
; of FAT or place for second sector of MS FAT32 bootloader. |
; Some constants |
FAT16_ROOTDIR_SECTORS = 16 ; can be changed, but why not? |
; FAT16: |
; 1 bootsector, |
; min 0xFF5 sectors for data, |
; min (0xFF5*2/512) = 16 sectors per FAT, we use only one copy, |
; FAT16_ROOTDIR_SECTORS for root directory |
MIN_FAT16_SIZE = 1 + 16 + FAT16_ROOTDIR_SECTORS + 0xFF5 |
; FAT32: |
; 1 bootsector, |
; 1 sector for fsinfo, |
; min 0xFFF5 sectors for data, |
; min (0xFFF5*4/512) = 512 sectors per FAT, we use only one copy |
MIN_FAT32_SIZE = 1 + 1 + 512 + 0xFFF5 |
MAX_SIZE = 1 shl (30 - 9) ; 1G in 512-byte sectors |
; Initializes FATxx structures on the disk. |
; Called with edi = pointer to disk data, esi = size of disk. |
proc format_disk |
; Determine FAT type and jump to the corresponding handler. |
cmp esi, MIN_FAT32_SIZE |
jae format_disk_fat32 |
; Fall through to format_disk_fat16. |
endp |
; Structure of FAT16 bootsector. Field names are from MS spec. |
struc FAT16BOOT |
{ |
.BS_jmpBoot rb 3 |
.BS_OEMName rb 8 |
.BPB_BytsPerSec dw ? |
.BPB_SecsPerClus db ? |
.BPB_RsvdSecCnt dw ? |
.BPB_NumFATs db ? |
.BPB_RootEntCnt dw ? |
.BPB_TotSec16 dw ? |
.BPB_Media db ? |
.BPB_FATSz16 dw ? |
.BPB_SecPerTrk dw ? |
.BPB_NumHeads dw ? |
.BPB_HiddSec dd ? |
.BPB_TotSec32 dd ? |
.BS_DrvNum db ? |
.BS_Reserved1 db ? |
.BS_BootSig db ? |
.BS_VolID dd ? |
.BS_VolLab rb 11 |
.BS_FilSysType rb 8 |
} |
virtual at 0 |
FAT16BOOT FAT16BOOT |
end virtual |
; Initializes FAT16 structures on the disk. |
; Called with edi = pointer to disk data, esi = size of disk. |
format_disk_fat16: |
; 1. Calculate number of clusters. |
; 1a. There are fixed-sized areas and there are data+FAT; |
; every cluster uses 512 bytes in data area and 2 bytes in FAT area. |
lea eax, [esi-1-FAT16_ROOTDIR_SECTORS] |
; two following lines are equivalent to edx = floor(eax*512/514) |
mov ecx, 0xFF00FF01 |
mul ecx ; edx = number of clusters |
; 1b. Force the number be less than 0xfff5. |
mov eax, 0xFFF4 |
cmp edx, eax |
jb @f |
mov edx, eax |
@@: |
; 2. Zero all system areas on the disk. |
lea ecx, [256*(1+FAT16_ROOTDIR_SECTORS)/2+edx+255] |
and ecx, not 255 |
shr ecx, 1 |
xor eax, eax |
push edi |
rep stosd |
pop edi |
; 3. Generate the bootsector. |
; 3a. Copy static stub. |
push esi edi |
mov esi, fat16bootsector_stub |
mov ecx, fat16bootsector_stub_size |
rep movsb |
pop edi esi |
mov word [edi+510], 0xAA55 |
; 3b. Set fields which depend on size. |
cmp esi, 0x10000 |
jae .size_is_32bit |
mov [edi+FAT16BOOT.BPB_TotSec16], si |
jmp .size_written |
.size_is_32bit: |
mov [edi+FAT16BOOT.BPB_TotSec32], esi |
.size_written: |
lea eax, [edx+255] |
shr eax, 8 |
mov [edi+FAT16BOOT.BPB_FATSz16], ax |
; 3c. Generate volume ID. |
call generate_volume_id |
mov [edi+FAT16BOOT.BS_VolID], eax |
; 4. Initialize FAT. |
mov dword [edi+512], 0xFFFFFFF8 |
; 5. Return. |
ret |
; Structure of FAT32 bootsector. Field names are from MS spec. |
struc FAT32BOOT |
{ |
.BS_jmpBoot rb 3 |
.BS_OEMName rb 8 |
.BPB_BytsPerSec dw ? |
.BPB_SecsPerClus db ? |
.BPB_RsvdSecCnt dw ? |
.BPB_NumFATs db ? |
.BPB_RootEntCnt dw ? |
.BPB_TotSec16 dw ? |
.BPB_Media db ? |
.BPB_FATSz16 dw ? |
.BPB_SecPerTrk dw ? |
.BPB_NumHeads dw ? |
.BPB_HiddSec dd ? |
.BPB_TotSec32 dd ? |
.BPB_FATSz32 dd ? |
.BPB_ExtFlags dw ? |
.BPB_FSVer dw ? |
.BPB_RootClus dd ? |
.BPB_FSInfo dw ? |
.BPB_BkBootSec dw ? |
.BPB_Reserved rb 12 |
.BS_DrvNum db ? |
.BS_Reserved1 db ? |
.BS_BootSig db ? |
.BS_VolID dd ? |
.BS_VolLab rb 11 |
.BS_FilSysType rb 8 |
} |
virtual at 0 |
FAT32BOOT FAT32BOOT |
end virtual |
; Initializes FAT32 structures on the disk. |
; Called with edi = pointer to disk data, esi = size of disk. |
format_disk_fat32: |
; 1. Calculate number of clusters. |
; 1a. There is fixed-sized area and there are data+FAT; |
; every cluster uses 512 bytes in data area and 4 bytes in FAT area. |
lea eax, [esi-1-1] |
; two following lines are equivalent to edx=floor(eax*512/516) if eax<10000000h |
mov ecx, 0xFE03F810 |
mul ecx ; edx = number of clusters |
; 2. Zero all system areas on the disk and first cluster of data, |
; used for root directory. |
lea ecx, [128*(1+1+1)+edx+127] |
and ecx, not 127 |
xor eax, eax |
push edi |
rep stosd |
pop edi |
; 3. Generate the bootsector. |
; 3a. Copy static stub. |
push esi edi |
mov esi, fat32bootsector_stub |
mov ecx, fat32bootsector_stub_size |
rep movsb |
pop edi esi |
mov word [edi+510], 0xAA55 |
; 3b. Set fields which depend on size. |
mov [edi+FAT32BOOT.BPB_TotSec32], esi |
lea eax, [edx+127] |
shr eax, 7 |
mov [edi+FAT32BOOT.BPB_FATSz32], eax |
; 3c. Generate volume ID. |
call generate_volume_id |
mov [edi+FAT32BOOT.BS_VolID], eax |
; 4. Initialize fsinfo sector. |
mov dword [edi+512], 'RRaA' |
mov dword [edi+512+484], 'rrAa' |
dec edx ; one cluster is occupied by root dir |
mov dword [edi+512+488], edx ; free count |
mov byte [edi+512+492], 3 ; first free cluster |
mov word [edi+512+510], 0xAA55 |
; 5. Initialize FAT. |
mov dword [edi+512*2], 0x0FFFFFF8 |
mov dword [edi+512*2+4], 0x0FFFFFFF |
mov dword [edi+512*2+8], 0x0FFFFFFF |
; 6. Return. |
ret |
; Generate volume serial number, which should try to be unique for each volume. |
; Use CMOS date+time, copy-pasted from fat32.inc. |
generate_volume_id: |
call get_time_for_file |
mov cx, ax |
call get_date_for_file |
shl eax, 16 |
mov ax, cx |
ret |
; Three following procedures are copy-pasted from fat32.inc. |
bcd2bin: |
;---------------------------------- |
; input : AL=BCD number (eg. 0x11) |
; output : AH=0 |
; AL=decimal number (eg. 11) |
;---------------------------------- |
xor ah, ah |
shl ax, 4 |
shr al, 4 |
aad |
ret |
get_date_for_file: |
;----------------------------------------------------- |
; Get date from CMOS and pack day,month,year in AX |
; DATE bits 0..4 : day of month 0..31 |
; 5..8 : month of year 1..12 |
; 9..15 : count of years from 1980 |
;----------------------------------------------------- |
mov al, 0x7 ;day |
out 0x70, al |
in al, 0x71 |
call bcd2bin |
ror eax, 5 |
mov al, 0x8 ;month |
out 0x70, al |
in al, 0x71 |
call bcd2bin |
ror eax, 4 |
mov al, 0x9 ;year |
out 0x70, al |
in al, 0x71 |
call bcd2bin |
add ax, 20 ;because CMOS return only the two last |
;digit (eg. 2000 -> 00 , 2001 -> 01) and we |
rol eax, 9 ;need the difference with 1980 (eg. 2001-1980) |
ret |
get_time_for_file: |
;----------------------------------------------------- |
; Get time from CMOS and pack hour,minute,second in AX |
; TIME bits 0..4 : second (the low bit is lost) |
; 5..10 : minute 0..59 |
; 11..15 : hour 0..23 |
;----------------------------------------------------- |
mov al, 0x0 ;second |
out 0x70, al |
in al, 0x71 |
call bcd2bin |
ror eax, 6 |
mov al, 0x2 ;minute |
out 0x70, al |
in al, 0x71 |
call bcd2bin |
ror eax, 6 |
mov al, 0x4 ;hour |
out 0x70, al |
in al, 0x71 |
call bcd2bin |
rol eax, 11 |
ret |
; some data |
fat16bootsector_stub: |
db 0EBh, 3Ch, 90h ; BS_jmpBoot |
db 'KOLIBRI ' ; BS_OEMName |
dw 512 ; BPB_BytsPerSec |
db 1 ; BPB_SecsPerClus |
dw 1 ; BPB_RsvdSecCnt |
db 1 ; BPB_NumFATs |
dw FAT16_ROOTDIR_SECTORS*16 ; BPB_RootEntCnt |
dw 0 ; BPB_TotSec16, filled in format_disk_fat16 |
db 0F8h ; BPB_Media |
dw 0 ; BPB_FATSz16, filled in format_disk_fat16 |
dw 32 ; BPB_SecPerTrk |
dw 128 ; BPB_NumHeads |
dd 0 ; BPB_HiddSec |
dd 0 ; BPB_TotSec32, filled in format_disk_fat16 |
db 80h ; BS_DrvNum |
db 0 ; BS_Reserved1 |
db 29h ; BS_BootSig |
dd 0 ; BS_VolID, filled in format_disk_fat16 |
db 'NO NAME ' ; BS_VolLab |
db 'FAT16 ' ; BS_FilSysType |
; just in case add some meaningful bytes if someone tries to boot |
db 0CDh, 19h, 0EBh, 0FEh ; int 19h, jmp $ |
fat16bootsector_stub_size = $ - fat16bootsector_stub |
fat32bootsector_stub: |
db 0EBh, 58h, 90h ; BS_jmpBoot |
db 'KOLIBRI ' ; BS_OEMName |
dw 512 ; BPB_BytsPerSec |
db 1 ; BPB_SecsPerClus |
dw 1 ; BPB_RsvdSecCnt |
db 1 ; BPB_NumFATs |
dw 0 ; BPB_RootEntCnt |
dw 0 ; BPB_TotSec16 |
db 0F8h ; BPB_Media |
dw 0 ; BPB_FATSz16 |
dw 32 ; BPB_SecPerTrk |
dw 128 ; BPB_NumHeads |
dd 0 ; BPB_HiddSec |
dd 0 ; BPB_TotSec32, filled in format_disk_fat32 |
dd 0 ; BPB_FATSz32, filled in format_disk_fat32 |
dw 0 ; BPB_ExtFlags |
dw 0 ; BPB_FSVer |
dd 2 ; BPB_RootClus |
dw 1 ; BPB_FSInfo |
dw 0 ; BPB_BkBootSec |
rb 12 ; BPB_Reserved |
db 80h ; BS_DrvNum |
db 0 ; BS_Reserved1 |
db 29h ; BS_BootSig |
dd 0 ; BS_VolID, filled in format_disk_fat32 |
db 'NO NAME ' ; BS_VolLab |
db 'FAT32 ' ; BS_FilSysType |
; same bytes as in fat16bootsector_stub |
db 0CDh, 19h, 0EBh, 0FEh ; int 19h, jmp $ |
fat32bootsector_stub_size = $ - fat32bootsector_stub |
/kernel/branches/Kolibri-acpi/drivers/tmpdisk_work.inc |
---|
0,0 → 1,144 |
; Callbacks which implement tmpdisk-specific disk functions for tmpdisk.asm. |
; The first argument of every callback is .userdata = userdata arg of AddDisk. |
; For tmpdisk, .userdata is the disk id, one of 0,...,max_num_disks-1. |
DISK_STATUS_OK = 0 ; success |
DISK_STATUS_GENERAL_ERROR = -1; if no other code is suitable |
DISK_STATUS_INVALID_CALL = 1 ; invalid input parameters |
DISK_STATUS_NO_MEDIA = 2 ; no media present |
DISK_STATUS_END_OF_MEDIA = 3 ; end of media while reading/writing data |
; The last function that is called for the given disk. The kernel calls it when |
; the kernel has finished all operations with the disk and it is safe to free |
; all driver-specific data identified by 'userdata'. |
proc tmpdisk_close |
virtual at esp+4 |
.userdata dd ? |
end virtual |
; Free the memory for disk and zero global variables. |
mov edx, [.userdata] |
mov [disk_sizes+edx*4], 0 |
xor eax, eax |
xchg eax, [disk_pointers+edx*4] |
stdcall KernelFree, eax |
retn 4 |
endp |
struc DISKMEDIAINFO |
{ |
.flags dd ? |
DISK_MEDIA_READONLY = 1 |
.sectorsize dd ? |
.capacity dq ? |
} |
virtual at 0 |
DISKMEDIAINFO DISKMEDIAINFO |
end virtual |
; Returns information about disk media. |
proc tmpdisk_querymedia |
virtual at esp+4 |
.userdata dd ? |
.info dd ? |
end virtual |
; Media is always present, sector size is always 512 bytes, |
; the size of disk in sectors is stored in a global variable. |
mov edx, [.userdata] |
mov ecx, [.info] |
mov [ecx+DISKMEDIAINFO.flags], 0 |
mov [ecx+DISKMEDIAINFO.sectorsize], 512 |
mov eax, [disk_sizes+edx*4] |
mov dword [ecx+DISKMEDIAINFO.capacity], eax |
mov dword [ecx+DISKMEDIAINFO.capacity+4], 0 |
; Return zero as an indicator of success. |
xor eax, eax |
retn 8 |
endp |
; Reads one or more sectors from the device. |
tmpdisk_read: |
xor edx, edx ; 0 = reading |
jmp tmpdisk_readwrite |
; Writes one or more sectors to the device. |
tmpdisk_write: |
mov dl, 1 ; 1 = writing |
; Fall through to tmpdisk_readwrite. |
; Common procedure for reading and writing. |
; dl = 0 for reading, dl = 1 for writing. |
; Arguments of tmpdisk_read and tmpdisk_write are the same, |
; they continue to be stack arguments of this procedure. |
proc tmpdisk_readwrite \ |
userdata:dword, \ |
buffer:dword, \ |
start_sector:qword, \ |
numsectors_ptr:dword |
; 1. Save used registers to be stdcall. |
push esi edi |
mov esi, [userdata] |
mov edi, [numsectors_ptr] |
; 1. Determine number of sectors to be transferred. |
; This is either the requested number of sectors or number of sectors |
; up to the disk boundary, depending of what is less. |
xor ecx, ecx |
; 1a. Test whether [start_sector] is less than [disk_sizes] for selected disk. |
; If so, calculate number of sectors between [start_sector] and [disk_sizes]. |
; Otherwise, the actual number of sectors is zero. |
cmp dword [start_sector+4], ecx |
jnz .got_number |
mov eax, [disk_sizes+esi*4] |
sub eax, dword [start_sector] |
jbe .got_number |
; 1b. Get the requested number of sectors. |
mov ecx, [edi] |
; 1c. If it is greater than number of sectors calculated in 1a, use the value |
; from 1a. |
cmp ecx, eax |
jb .got_number |
mov ecx, eax |
.got_number: |
; 2. Compare the actual number of sectors with requested. If they are |
; equal, set eax (it will be the returned value) to zero. Otherwise, |
; use DISK_STATUS_END_OF_MEDIA. |
xor eax, eax |
cmp ecx, [edi] |
jz @f |
mov al, DISK_STATUS_END_OF_MEDIA |
@@: |
; 3. Store the actual number of sectors. |
mov [edi], ecx |
; 4. Calculate source and destination addresses. |
mov edi, dword [start_sector] |
shl edi, 9 |
add edi, [disk_pointers+esi*4] |
mov esi, [buffer] |
; 5. Calculate number of dwords to be transferred. |
shl ecx, 9-2 |
; 6. Now esi = [buffer], edi = pointer inside disk. |
; This is normal for write operations; |
; exchange esi and edi for read operations. |
test dl, dl |
jnz @f |
xchg esi, edi |
@@: |
; 7. Copy data. |
rep movsd |
; 8. Restore used registers to be stdcall and return. |
; The value in eax was calculated in step 2. |
pop edi esi |
ret |
endp |
; The kernel calls this function when initializing cache subsystem for |
; the media. This call allows the driver to adjust the cache size. |
proc tmpdisk_adjust_cache_size |
virtual at esp+4 |
.userdata dd ? |
.suggested_size dd ? |
end virtual |
; Since tmpdisk does not need cache, just return 0. |
xor eax, eax |
retn 8 |
endp |
/kernel/branches/Kolibri-acpi/fs/fat32.inc |
---|
2845,6 → 2845,10 |
mov eax, esi |
call get_FAT |
jc .err1 |
cmp eax, 2 |
jb .error_fat |
cmp eax, [ebp+FAT.fatRESERVED] |
jae .empty |
mov esi, eax |
xor ecx, ecx |
@@: |
2865,6 → 2869,13 |
push ERROR_DEVICE |
pop eax |
ret |
.error_fat: |
popad |
pop edi |
call fat_unlock |
push ERROR_FAT_TABLE |
pop eax |
ret |
.notempty: |
popad |
.access_denied2: |
/kernel/branches/Kolibri-acpi/gui/char.mt |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/gui/char2.mt |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/hid/mousedrv.inc |
---|
124,6 → 124,18 |
cmp esi, [current_cursor] |
je .draw |
mov eax, [TASK_COUNT] |
movzx eax, word [WIN_POS+eax*2] |
shl eax, 8 |
cmp eax, edx |
je @F |
mov esi, [def_cursor] |
cmp esi, [current_cursor] |
je .draw |
@@: |
push esi |
call [_display.select_cursor] |
mov [current_cursor], esi |
/kernel/branches/Kolibri-acpi/kernel.asm |
---|
311,8 → 311,6 |
; ENABLE PAGING |
xchg bx, bx |
mov eax, sys_pgdir-OS_BASE |
mov cr3, eax |
711,8 → 709,8 |
call LAPIC_init |
mov eax, 1 |
call start_ap |
; mov eax, 1 |
; call start_ap |
; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15) |
; they are used: when partitions are scanned, hd_read relies on timer |
/kernel/branches/Kolibri-acpi/video/arrow_clock.cur |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/branches/Kolibri-acpi/video/blitter.inc |
---|
202,12 → 202,16 |
align 4 |
blit_32: |
xchg bx, bx |
.x_y equ 72 |
.tmp_x_y equ 76 |
push ebp |
push edi |
push esi |
push ebx |
sub esp, 72 |
sub esp, 80 |
mov eax, [TASK_BASE] |
mov ebx, [eax-twdw + WDATA.box.width] |
254,7 → 258,7 |
mov ecx, esp |
call blit_clip |
test eax, eax |
jne .L57 |
jne .done |
mov eax, [TASK_BASE] |
264,16 → 268,13 |
add ebp, [eax-twdw + WDATA.box.top] |
mov ecx, ebx |
add ecx, [esp+BLITTER.w] |
shl ecx, 16 |
mov cx, bp |
add ecx, [esp+BLITTER.h] |
mov [esp+.x_y], ecx |
mov edi, ebp |
; imul edi, [_display.pitch] |
mov edi, [BPSLine_calc_area+edi*4] |
; imul ebp, [_display.width] |
mov ebp, [d_width_calc_area+ebp*4] |
add ebp, ebx |
285,38 → 286,56 |
lea esi, [eax+esi*4] |
add esi, [esp+BLITTER.bitmap] |
mov eax, ecx |
mov ecx, [esp+BLITTER.h] |
mov edx, [esp+BLITTER.w] |
test ecx, ecx ;FIXME check clipping |
jz .L57 |
jz .done |
test edx, edx |
jz .L57 |
jz .done |
cmp [_display.bpp], 32 |
jne .core_24 |
lea edi, [edi+ebx*4] |
mov ebx, 1 |
test [esp+72], dword 0x10 |
jnz @F |
; xchg bx, bx |
mov ebx, [CURRENT_TASK] |
@@: |
mov ecx, [esp+80] |
shr ecx, 4 |
and ecx, 3 |
jmp dword [.tbl_32+ecx*4] |
align 4 |
.tbl_32 dd blit_copy_32 |
dd blit_copy_32_bgr |
dd blit_trans_32 |
dd blit_trans_32_bgr |
.done: |
add esp, 80 |
pop ebx |
pop esi |
pop edi |
pop ebp |
ret |
align 4 |
blit_copy_32_bgr: |
mov ebx, 1 |
align 4 |
blit_copy_32: |
.outer32: |
mov eax, [esp+.x_y] |
mov [esp+.tmp_x_y], eax |
xor ecx, ecx |
align 4 |
.inner32: |
cmp [ebp+ecx], bl |
jne .skip |
;-------------------------------------- |
push eax |
mov eax, [esi+ecx*4] |
; check for hardware cursor |
328,25 → 347,21 |
align 4 |
@@: |
push ecx |
mov ecx, [esp+4+.tmp_x_y] |
mov ecx, [esp+4] |
ror ecx, 16 |
sub ecx, edx |
rol ecx, 16 |
sub ecx, [esp+BLITTER.h + 8] |
; check mouse area for putpixel |
call [_display.check_mouse] |
pop ecx |
;-------------------------------------- |
align 4 |
.no_mouseunder: |
; store to real LFB |
mov [LFB_BASE+edi+ecx*4], eax |
pop eax |
;-------------------------------------- |
align 4 |
.skip: |
add [esp+.tmp_x_y], dword 0x10000 |
inc ecx |
dec edx |
jnz .inner32 |
354,62 → 369,48 |
add esi, [esp+BLITTER.stride] |
add edi, [_display.pitch] |
add ebp, [_display.width] |
inc dword [esp+.x_y] |
mov edx, [esp+BLITTER.w] |
dec [esp+BLITTER.h] |
jnz .outer32 |
.done: |
; call [draw_pointer] |
; call __sys_draw_pointer |
.L57: |
add esp, 72 |
pop ebx |
pop esi |
pop edi |
pop ebp |
ret |
jmp blit_32.done |
.core_24: |
lea ebx, [ebx+ebx*2] |
lea edi, [LFB_BASE+edi+ebx] |
align 4 |
blit_trans_32_bgr: |
mov ebx, 1 |
test [esp+72], dword 0x10 |
jnz @F |
mov ebx, [CURRENT_TASK] |
@@: |
align 4 |
blit_trans_32: |
align 4 |
.outer24: |
mov [esp+64], edi |
.outer32: |
mov eax, [esp+.x_y] |
mov [esp+.tmp_x_y], eax |
xor ecx, ecx |
align 4 |
.inner24: |
.inner32: |
cmp [ebp+ecx], bl |
jne .skip_1 |
jne .skip |
;-------------------------------------- |
push eax |
mov eax, [esi+ecx*4] |
test eax, 0xFF000000 |
jz .skip |
lea edi, [edi+ecx*2] |
; check for hardware cursor |
cmp [_display.select_cursor], select_cursor |
je @f |
cmp [_display.select_cursor], 0 |
jne .no_mouseunder_1 |
jne .no_mouseunder |
;-------------------------------------- |
align 4 |
@@: |
push ecx |
mov ecx, [esp+4] |
ror ecx, 16 |
sub ecx, edx |
rol ecx, 16 |
sub ecx, [esp+BLITTER.h + 8] |
mov ecx, [esp+4+.tmp_x_y] |
; check mouse area for putpixel |
call [_display.check_mouse] |
416,26 → 417,24 |
pop ecx |
;-------------------------------------- |
align 4 |
.no_mouseunder_1: |
mov [edi+ecx], ax |
shr eax, 16 |
mov [edi+ecx+2], al |
pop eax |
.no_mouseunder: |
; store to real LFB |
mov [LFB_BASE+edi+ecx*4], eax |
;-------------------------------------- |
align 4 |
.skip_1: |
mov edi, [esp+64] |
.skip: |
add [esp+.tmp_x_y], dword 0x10000 |
inc ecx |
dec edx |
jnz .inner24 |
jnz .inner32 |
add esi, [esp+BLITTER.stride] |
add edi, [_display.pitch] |
add ebp, [_display.width] |
inc dword [esp+.x_y] |
mov edx, [esp+BLITTER.w] |
dec [esp+BLITTER.h] |
jnz .outer24 |
jnz .outer32 |
jmp .done |
jmp blit_32.done |
/kernel/branches/Kolibri-acpi/video/cursors.inc |
---|
447,16 → 447,11 |
;------------------------------------------------------------------------------ |
align 4 |
proc delete_cursor stdcall, hcursor:dword |
locals |
hsrv dd ? |
io_code dd ? |
input dd ? |
inp_size dd ? |
output dd ? |
out_size dd ? |
endl |
; DEBUGF 1,'K : delete_cursor %x\n', [hcursor] |
mov esi, [hcursor] |
cmp [esi+CURSOR.magic], 'CURS' |
jne .fail |