From 5690f9671b2875999a980f2f4851d8c30cb31f53 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Thu, 7 Feb 2013 09:10:30 +0000 Subject: [PATCH] kolibri-acpi: update git-svn-id: svn://kolibrios.org@3232 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/Kolibri-acpi/blkdev/disk.inc | 6 +- .../Kolibri-acpi/blkdev/disk_cache.inc | 29 +- .../branches/Kolibri-acpi/boot/bootvesa.inc | 2 +- kernel/branches/Kolibri-acpi/build.bat | 13 +- kernel/branches/Kolibri-acpi/core/dll.inc | 10 +- kernel/branches/Kolibri-acpi/core/malloc.inc | 19 +- kernel/branches/Kolibri-acpi/core/memory.inc | 6 +- kernel/branches/Kolibri-acpi/core/peload.inc | 1 + .../Kolibri-acpi/core/test_malloc.asm | 29 +- kernel/branches/Kolibri-acpi/data32.inc | 3 - .../branches/Kolibri-acpi/docs/sysfuncs.txt | 1 - .../Kolibri-acpi/drivers/infinity.asm | 33 +- .../Kolibri-acpi/drivers/intelac97.asm | 1507 +++++++++++++++ .../branches/Kolibri-acpi/drivers/sound.asm | 1650 +++-------------- .../branches/Kolibri-acpi/drivers/tmpdisk.asm | 295 +++ .../Kolibri-acpi/drivers/tmpdisk_fat.inc | 327 ++++ .../Kolibri-acpi/drivers/tmpdisk_work.inc | 144 ++ kernel/branches/Kolibri-acpi/fs/fat32.inc | 11 + kernel/branches/Kolibri-acpi/gui/char.mt | Bin 0 -> 2304 bytes kernel/branches/Kolibri-acpi/gui/char2.mt | Bin 0 -> 2560 bytes kernel/branches/Kolibri-acpi/hid/mousedrv.inc | 12 + kernel/branches/Kolibri-acpi/kernel.asm | 8 +- .../Kolibri-acpi/video/arrow_clock.cur | Bin 0 -> 2238 bytes .../branches/Kolibri-acpi/video/blitter.inc | 211 ++- .../branches/Kolibri-acpi/video/cursors.inc | 11 +- 25 files changed, 2770 insertions(+), 1558 deletions(-) create mode 100644 kernel/branches/Kolibri-acpi/drivers/intelac97.asm create mode 100644 kernel/branches/Kolibri-acpi/drivers/tmpdisk.asm create mode 100644 kernel/branches/Kolibri-acpi/drivers/tmpdisk_fat.inc create mode 100644 kernel/branches/Kolibri-acpi/drivers/tmpdisk_work.inc create mode 100644 kernel/branches/Kolibri-acpi/gui/char.mt create mode 100644 kernel/branches/Kolibri-acpi/gui/char2.mt create mode 100644 kernel/branches/Kolibri-acpi/video/arrow_clock.cur diff --git a/kernel/branches/Kolibri-acpi/blkdev/disk.inc b/kernel/branches/Kolibri-acpi/blkdev/disk.inc index 9487920943..73e537beda 100644 --- a/kernel/branches/Kolibri-acpi/blkdev/disk.inc +++ b/kernel/branches/Kolibri-acpi/blkdev/disk.inc @@ -459,7 +459,9 @@ disk_dereference: 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 @@ disk_default_flush: ; 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. diff --git a/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc b/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc index c5651d9217..323a6bdfcc 100644 --- a/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc +++ b/kernel/branches/Kolibri-acpi/blkdev/disk_cache.inc @@ -135,7 +135,7 @@ end virtual 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 @@ end virtual .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 @@ find_empty_slot64: ; 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 @@ endl .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 @@ disk_init_cache: 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 @@ disk_init_cache: 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 @@ disk_init_cache: 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 diff --git a/kernel/branches/Kolibri-acpi/boot/bootvesa.inc b/kernel/branches/Kolibri-acpi/boot/bootvesa.inc index 98b4fdb836..bf328d2c59 100644 --- a/kernel/branches/Kolibri-acpi/boot/bootvesa.inc +++ b/kernel/branches/Kolibri-acpi/boot/bootvesa.inc @@ -217,7 +217,7 @@ calc_vmodes_table: 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 diff --git a/kernel/branches/Kolibri-acpi/build.bat b/kernel/branches/Kolibri-acpi/build.bat index 290d05b54a..54f98c2dab 100644 --- a/kernel/branches/Kolibri-acpi/build.bat +++ b/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 @@ goto :eof :Target_all call :Target_kernel call :Target_drivers - call :Target_skins goto :eof @@ -102,16 +101,6 @@ if "%res%"=="y" ( 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 diff --git a/kernel/branches/Kolibri-acpi/core/dll.inc b/kernel/branches/Kolibri-acpi/core/dll.inc index 4396ea81db..2f3241f0f4 100644 --- a/kernel/branches/Kolibri-acpi/core/dll.inc +++ b/kernel/branches/Kolibri-acpi/core/dll.inc @@ -810,15 +810,7 @@ proc load_driver stdcall, driver_name:dword 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: diff --git a/kernel/branches/Kolibri-acpi/core/malloc.inc b/kernel/branches/Kolibri-acpi/core/malloc.inc index fe749d2c17..7c36dd0c86 100644 --- a/kernel/branches/Kolibri-acpi/core/malloc.inc +++ b/kernel/branches/Kolibri-acpi/core/malloc.inc @@ -341,10 +341,9 @@ free: ; 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 @@ free: ; 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 @@ free: ; 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 @@ insert_chunk: 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 diff --git a/kernel/branches/Kolibri-acpi/core/memory.inc b/kernel/branches/Kolibri-acpi/core/memory.inc index 9047fef7a3..ba06297cec 100644 --- a/kernel/branches/Kolibri-acpi/core/memory.inc +++ b/kernel/branches/Kolibri-acpi/core/memory.inc @@ -606,8 +606,12 @@ update_mem_size: 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 diff --git a/kernel/branches/Kolibri-acpi/core/peload.inc b/kernel/branches/Kolibri-acpi/core/peload.inc index bb051a0aed..c1b63fcdcc 100644 --- a/kernel/branches/Kolibri-acpi/core/peload.inc +++ b/kernel/branches/Kolibri-acpi/core/peload.inc @@ -300,6 +300,7 @@ __exports: malloc, 'Kmalloc', \ free, 'Kfree', \ map_io_mem, 'MapIoMem', \ ; stdcall + map_page, 'MapPage', \ ; stdcall get_pg_addr, 'GetPgAddr', \ ; eax \ mutex_init, 'MutexInit', \ ; gcc fastcall diff --git a/kernel/branches/Kolibri-acpi/core/test_malloc.asm b/kernel/branches/Kolibri-acpi/core/test_malloc.asm index a8a270f2c4..33849678e9 100644 --- a/kernel/branches/Kolibri-acpi/core/test_malloc.asm +++ b/kernel/branches/Kolibri-acpi/core/test_malloc.asm @@ -50,12 +50,12 @@ run_test2: 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 @@ run_test3: 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 @@ run_test3: 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 @@ malloc_with_test: 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 @@ generic_malloc_fail: jmp error_with_code check_mutex: - cmp [mst.mutex], 0 + cmp dword [mst.mutex], 0 jnz @f ret @@: @@ -195,6 +209,10 @@ memory_destroyed: 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 @@ error_with_code: ; Include main heap code include '../proc32.inc' +include '../struct.inc' include '../const.inc' include 'malloc.inc' diff --git a/kernel/branches/Kolibri-acpi/data32.inc b/kernel/branches/Kolibri-acpi/data32.inc index e0893c0769..9a93ba9e3b 100644 --- a/kernel/branches/Kolibri-acpi/data32.inc +++ b/kernel/branches/Kolibri-acpi/data32.inc @@ -134,13 +134,10 @@ msg_module db 'in module ',0 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 diff --git a/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt b/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt index 9973669992..051aa5500c 100644 --- a/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt +++ b/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt @@ -4592,7 +4592,6 @@ Remarks: * This function terminates the current thread. Other thread can be killed by call to subfunction 2 of function 18. - ====================================================================== =========================== List of events =========================== ====================================================================== diff --git a/kernel/branches/Kolibri-acpi/drivers/infinity.asm b/kernel/branches/Kolibri-acpi/drivers/infinity.asm index a0e1f85a71..2d34f44b89 100644 --- a/kernel/branches/Kolibri-acpi/drivers/infinity.asm +++ b/kernel/branches/Kolibri-acpi/drivers/infinity.asm @@ -875,8 +875,8 @@ endp ; 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 @@ proc ResetBuffer stdcall, str:dword, flags:dword 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 @@ proc stop_buffer stdcall, str:dword 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 diff --git a/kernel/branches/Kolibri-acpi/drivers/intelac97.asm b/kernel/branches/Kolibri-acpi/drivers/intelac97.asm new file mode 100644 index 0000000000..548835d6e2 --- /dev/null +++ b/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 diff --git a/kernel/branches/Kolibri-acpi/drivers/sound.asm b/kernel/branches/Kolibri-acpi/drivers/sound.asm index 548835d6e2..adc63d501f 100644 --- a/kernel/branches/Kolibri-acpi/drivers/sound.asm +++ b/kernel/branches/Kolibri-acpi/drivers/sound.asm @@ -1,293 +1,149 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; -;; 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 ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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 - -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 +API_VERSION = 0x01000100 public START public service_proc @@ -306,340 +162,22 @@ proc START stdcall, state:dword 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 + .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 ? @@ -655,9 +193,9 @@ proc detect_controller mov [last_bus], eax -.next_bus: + .next_bus: and [devfn], 0 -.next_dev: + .next_dev: stdcall PciRead32, [bus], [devfn], dword 0 test eax, eax jz .next @@ -665,16 +203,16 @@ proc detect_controller je .next mov edi, devices -@@: + @@: mov ebx, [edi] test ebx, ebx jz .next cmp eax, ebx je .found - add edi, 12 + add edi, 8 jmp @B -.next: + .next: inc [devfn] cmp [devfn], 256 jb .next_dev @@ -685,823 +223,171 @@ proc detect_controller 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 + .found: if DEBUG - mov esi, msgCFail + mov esi, msgLoading call SysMsgBoardStr - end if - xor eax, eax ; timeout error + + mov esi, dword[edi+4] + call SysMsgBoardStr + + mov esi, msgNewline + call SysMsgBoardStr + end if + + stdcall GetService, dword[edi+4] + ret -.ok: + + .err: if DEBUG - mov esi, msgResetOk + mov esi, msgFail 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 +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 + + 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 + + dd (CTRL_VT82C686 shl 16)+VID_VIA, vt823x + dd (CTRL_VT8233_5 shl 16)+VID_VIA, vt823x + + dd (CTRL_SIS shl 16)+VID_SIS, sis + + dd (CTRL_FM801 shl 16)+VID_FM801, fm801 + + dd (0x5000 shl 16)+0x1274, ensoniq + dd (0x5880 shl 16)+0x1274, ensoniq + + 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 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 - -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 +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 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 diff --git a/kernel/branches/Kolibri-acpi/drivers/tmpdisk.asm b/kernel/branches/Kolibri-acpi/drivers/tmpdisk.asm new file mode 100644 index 0000000000..dcd87a524d --- /dev/null +++ b/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 diff --git a/kernel/branches/Kolibri-acpi/drivers/tmpdisk_fat.inc b/kernel/branches/Kolibri-acpi/drivers/tmpdisk_fat.inc new file mode 100644 index 0000000000..fabfb546dc --- /dev/null +++ b/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 diff --git a/kernel/branches/Kolibri-acpi/drivers/tmpdisk_work.inc b/kernel/branches/Kolibri-acpi/drivers/tmpdisk_work.inc new file mode 100644 index 0000000000..8654141a2e --- /dev/null +++ b/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 diff --git a/kernel/branches/Kolibri-acpi/fs/fat32.inc b/kernel/branches/Kolibri-acpi/fs/fat32.inc index 45bed2750b..88915690bd 100644 --- a/kernel/branches/Kolibri-acpi/fs/fat32.inc +++ b/kernel/branches/Kolibri-acpi/fs/fat32.inc @@ -2845,6 +2845,10 @@ fat_Delete: 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 @@ fat_Delete: 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: diff --git a/kernel/branches/Kolibri-acpi/gui/char.mt b/kernel/branches/Kolibri-acpi/gui/char.mt new file mode 100644 index 0000000000000000000000000000000000000000..e9b702604c6fc4facf5c24387826ebb62ea13456 GIT binary patch literal 2304 zcmd6o>tdrI5QWjuh&Dyolud22^8RnR-x<*U*$3D$(Q)oG9MHM{jHb1&lWKbHb${{n zvG@|bbBo9=&h4e_pP#>BhL~eo&kkxguFcDPytp-Y=R*w$5RG*-#<|gauk*FX@Uh}7 zs#Q6ENO8PFL=BCWrE>A+_qX`DqPpCJAGa^(;xLS5rb1O<6wE)6(HP~WtYT{K>uKk% z-fHSq$oEQdDG+%ah@3?c@2drpB#{n#m|K!6+$b$DyE+W3Np9n?npaJVLk8mLXUv|0 z`d1$P8>2G5uEUjXpvon>+|upBGiDmnG-Ceq=VMSkOU^ZC=SZZVRKqYR#WYj$%%Z9u zE44A!&amaYJBJ0{xJPRXudkGnRhZ|u%iD~Ka1e#$XDMc!@AtB8^5WHul^UZ{@@4gy zJM~1H2GbT<(&oi|S-PZ@Cjk+tqsExAjn3xG0LPIEhjH{FByt5&8-k7LxB*C(yi-iO zI%Ni=Gtll-iX@@1A*kxAVZO#yIpk<6t+2eP$Ab{>u?g;GX{TYZ0kLlCN-F2x3lkFa zaW}6v4^vroO{hht{O{|Livdv>F^FRekMjnMoqM+VFb^Wz4zK}9rMmV+Y_`|P>VOPD zPTy9Jrm9zjG9Js%K=l3t8|#qlT0xu7t`TSmz!|Ff2S3yh`KzlGY)$jFmHVBR!9!zC z*t~v;w3H`oPOzzVK~&g-TK0|~9;Rw-Sf9J)Qfek7Ne9VnRFh`0gImflVj7)E?lMNo zAXm_EV1s_-{5+Vbcyo_@}89*o4prwu-eA{A?^oy&ed5iLMVB|w8`*#Kxs1Z3;X z7|Dd_1}zW`o^`fOI_CwOS3}(lpuscQ^Dc}nb>P4v&Vr4dbsWp9Z8UjJ@iurGf_3^Z_;^Y1>Ch@(2Fc11Th&kvlmn};5 literal 0 HcmV?d00001 diff --git a/kernel/branches/Kolibri-acpi/gui/char2.mt b/kernel/branches/Kolibri-acpi/gui/char2.mt new file mode 100644 index 0000000000000000000000000000000000000000..d27525166328cdf80aa5cb1dbbc44ea46f4afc50 GIT binary patch literal 2560 zcmd5-O>f&c5G7Srrh_!L3LkPXWJ!xX)TaasqzT|sqH1TOLmK#y!yZx~=pSfrJ_OQV z-}i>3`+>bK&}mY?%y2&VW`;H@iitq|R!C1~&1|BTGVRyHaQNB+8QYuQqD(V|DEufh z^!;#m_lZbbXWIryZZwWS-XkJo=u7cY)Vv(aIZhjuCS#HcQYsUFbC#b8fYn$=$S5)jM7CLi!A|+DSTCK?j&~+=;`T64QI0p%4 z)VlGyO{W|0JGKl6VpuamG9Eq#e@-bdM3PVe5i4N+)G(e>4gS$eg})Kt4jyx{-{(K24H|XGp05#SX2V&=;bx3F;M$6P)ANL8e)zb^hknn;bgY#ESgy zdx%mv8hoK6TUN4xEmBAw0^9N$=RS0B77we75?y`mOTmP}$^yJ^Fi`#o0JdF?H!VP!OQZVCsx)#ivV8T;vQ^)amC%=H5>o`|A-VjDm9;EHYNv z`Tg*dgO)DWyg8!8J#x?ce)p06eLAA=Q|F_A-5;m!SOGZ;`zDA{SV*X#!>9D}r&$}? zmRwo1K%RylCX75*)z~5%o7=WH$5!<{Cnq3SC+TLp-EvBtd)V*y4?tSa@;sjb;cj8i zZ+5%Cce@+tFfGHjV}0mqn7U2Et%*HvWPg<^%0hb`Z-)t!*^v1I5(0e`cO87I%XfeN z0o|#J2tDW8%DI=W3wgP>!C&zBeRQ^t{MAP$flxeIbGRE= z1G-d=p6Q0w+gp2kON3#h2nsuG5HGOd5XAFB^lLmk0W&|v89MCyadAZED(YYj{WVvT z4%y5_tP0)NTE2;`%bG0XT!D2jhQ(uep^K{j0~LJh{QKf`n4!P!G2N0EB@AuD%CV~J zrO+i$uvp`M@XfJhDZ02Hm`(_{N8u$b>LSE@ko{1K8^ZnITXzU~Z?GWT52X&F@Lk3_di&IF6X63G?LwGkd5muxy}gplqOQ;9qVa(C!AW z>l_f3<$x~hYlIttGIwFgCun4=Kq#jR3&q1*givqO6LwAFyr=RWO%DkrSYndIvP~sZ ze8ath^CmdF&5sRYEl>4N$oZ+iH*oBgguVZQ#aA3x$eJ1FX>)Z&HaH8?@Tz}