diff --git a/kernel/branches/Kolibri-A/trunk/core/exports.inc b/kernel/branches/Kolibri-A/trunk/core/exports.inc index 7b64cb4ae4..b2c6a06de2 100644 --- a/kernel/branches/Kolibri-A/trunk/core/exports.inc +++ b/kernel/branches/Kolibri-A/trunk/core/exports.inc @@ -22,6 +22,10 @@ iglobal szReservePortArea db 'ReservePortArea',0 szBoot_Log db 'Boot_Log',0 + szMutexInit db 'MutexInit',0 + szMutexLock db 'MutexLock',0 + szMutexUnlock db 'MutexUnlock',0 + szPciApi db 'PciApi', 0 szPciRead32 db 'PciRead32', 0 szPciRead16 db 'PciRead16', 0 @@ -91,7 +95,11 @@ kernel_export: dd szReservePortArea , r_f_port_area dd szBoot_Log , boot_log - dd szPciApi , pci_api + dd szMutexInit , mutex_init ;gcc fastcall + dd szMutexLock , mutex_lock ;gcc fastcall + dd szMutexUnlock , mutex_unlock ;gcc fastcall + + dd szPciApi , pci_api_drv dd szPciRead32 , pci_read32 dd szPciRead16 , pci_read16 dd szPciRead8 , pci_read8 diff --git a/kernel/branches/Kolibri-A/trunk/core/heap.inc b/kernel/branches/Kolibri-A/trunk/core/heap.inc index 6f8dcd7626..9f7021dc57 100644 --- a/kernel/branches/Kolibri-A/trunk/core/heap.inc +++ b/kernel/branches/Kolibri-A/trunk/core/heap.inc @@ -635,7 +635,8 @@ proc kernel_free stdcall, base:dword pop esi ebx ret .fail: - and [heap_mutex], 0 + xor eax, eax + mov [heap_mutex], eax pop esi ebx ret endp diff --git a/kernel/branches/Kolibri-A/trunk/core/memory.inc b/kernel/branches/Kolibri-A/trunk/core/memory.inc index 97a50d161a..1d35930a44 100644 --- a/kernel/branches/Kolibri-A/trunk/core/memory.inc +++ b/kernel/branches/Kolibri-A/trunk/core/memory.inc @@ -1089,25 +1089,7 @@ sysfn_meminfo: .fail: or dword [esp+32], -1 ret -iglobal -align 4 -f68call: - dd f68.11 ; init_heap - dd f68.12 ; user_alloc - dd f68.13 ; user_free - dd f68.14 ; get_event_ex - dd f68.fail ;moved to f68.24 - dd f68.16 ; get_service - dd f68.17 ; call_service - dd f68.fail ;moved to f68.25 - dd f68.19 ; load_dll - dd f68.20 ; user_realloc - dd f68.21 ; load_driver - dd f68.22 ; shmem_open - dd f68.23 ; shmem_close - dd f68.24 - dd f68.25 -endg + align 4 f68: cmp ebx,4 @@ -1227,6 +1209,24 @@ f68: mov [esp+32], eax ret +align 4 +f68call: + dd f68.11 ; init_heap + dd f68.12 ; user_alloc + dd f68.13 ; user_free + dd f68.14 ; get_event_ex + dd f68.fail ;moved to f68.24 + dd f68.16 ; get_service + dd f68.17 ; call_service + dd f68.fail ;moved to f68.25 + dd f68.19 ; load_dll + dd f68.20 ; user_realloc + dd f68.21 ; load_driver + dd f68.22 ; shmem_open + dd f68.23 ; shmem_close + dd f68.24 + dd f68.25 + align 4 proc load_pe_driver stdcall, file:dword diff --git a/kernel/branches/Kolibri-A/trunk/core/peload.inc b/kernel/branches/Kolibri-A/trunk/core/peload.inc index d1d40e6c0c..85fede96b6 100644 --- a/kernel/branches/Kolibri-A/trunk/core/peload.inc +++ b/kernel/branches/Kolibri-A/trunk/core/peload.inc @@ -283,6 +283,12 @@ __exports: alloc_page, 'AllocPage', \ ; gcc ABI alloc_pages, 'AllocPages', \ ; stdcall commit_pages, 'CommitPages', \ ; eax, ebx, ecx +\ + create_event, 'CreateEvent', \ ; ecx, esi + raise_event, 'RaiseEvent', \ ; eax, ebx, edx, esi + wait_event, 'WaitEvent', \ ; eax, ebx + get_event_ex, 'GetEvent', \ ; edi +\ create_kernel_object, 'CreateObject', \ create_ring_buffer, 'CreateRingBuffer', \ ; stdcall destroy_kernel_object, 'DestroyObject', \ @@ -300,7 +306,7 @@ __exports: \ get_display, 'GetDisplay', \ set_screen, 'SetScreen', \ - pci_api, 'PciApi', \ + pci_api_drv, 'PciApi', \ pci_read8, 'PciRead8', \ ; stdcall pci_read16, 'PciRead16', \ ; stdcall pci_read32, 'PciRead32', \ ; stdcall @@ -315,6 +321,7 @@ __exports: user_free, 'UserFree', \ ; stdcall unmap_pages, 'UnmapPages', \ ; eax, ecx sys_msg_board_str, 'SysMsgBoardStr', \ + get_timer_ticks, 'GetTimerTicks', \ delay_hs, 'Delay', \ ; ebx set_mouse_data, 'SetMouseData' diff --git a/kernel/branches/Kolibri-A/trunk/docs/sysfuncs.txt b/kernel/branches/Kolibri-A/trunk/docs/sysfuncs.txt index 8d226d1cf6..26824a32c9 100644 --- a/kernel/branches/Kolibri-A/trunk/docs/sysfuncs.txt +++ b/kernel/branches/Kolibri-A/trunk/docs/sysfuncs.txt @@ -347,6 +347,7 @@ Returned value: * bit 0 (mask 1): window is maximized * bit 1 (mask 2): window is minimized to panel * bit 2 (mask 4): window is rolled up + * +71 = +0x47: dword: event mask Remarks: * Slots are numbered starting from 1. * Returned value is not a total number of threads, because there @@ -844,12 +845,12 @@ Returned value: * function does not return value Structure of the buffer: db a,b,c,d for version a.b.c.d -db UID_xxx: one of UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2 +db 0 dd REV - kernel SVN revision number -For Kolibri 0.7.1.0 kernel: -db 0,7,0,0 +For Kolibri 0.7.7.0 kernel: +db 0,7,7,0 db 2 -dd 638 +dd 1657 ====================================================================== ======= Function 18, subfunction 14 - wait for screen retrace. ======= @@ -1658,56 +1659,8 @@ Returned value: Remarks: * If the buffer is too small to hold all data, only first (edx-1) bytes are copied and than terminating 0 is inserted. - -====================================================================== -=============== Function 32 - delete file from ramdisk. ============== -====================================================================== -Parameters: - * eax = 32 - function number - * ebx = pointer to the filename -Returned value: - * eax = 0 - success; otherwise file system error code -Remarks: - * This function is obsolete; function 58 allows to fulfill - the same operations with the extended possibilities. - * The current implementation returns only values 0(success) and - 5(file not found). - * The filename must be either in the format 8+3 characters - (first 8 characters - name itself, last 3 - extension, - the short names and extensions are supplemented with spaces), - or in the format 8.3 characters "FILE.EXT"/"FILE.EX " - (name no more than 8 characters, dot, extension 3 characters - supplemented if necessary by spaces). - The filename must be written with capital letters. The terminating - character with code 0 is not necessary (not ASCIIZ-string). - * This function does not support folders on the ramdisk. - -====================================================================== -================ Function 33 - write file to ramdisk. ================ -====================================================================== -Parameters: - * eax = 33 - function number - * ebx = pointer to the filename - * ecx = pointer to data for writing - * edx = number of bytes for writing - * should be set esi=0 -Returned value: - * eax = 0 - success, otherwise file system error code -Remarks: - * This function is obsolete; function 70 allows to fulfil - the same operations with extended possibilities. - * If esi contains non-zero value and selected file already exists, - one more file with the same name will be created. - * Otherwise file will be overwritten. - * The filename must be either in the format 8+3 characters - (first 8 characters - name itself, last 3 - extension, - the short names and extensions are supplemented with spaces), - or in the format 8.3 characters "FILE.EXT"/"FILE.EX " - (name no more than 8 characters, dot, extension 3 characters - supplemented if necessary by spaces). - The filename must be written with capital letters. The terminating - character with code 0 is not necessary (not ASCIIZ-string). - * This function does not support folders on the ramdisk. + * By default, current folder for the thread is "/rd/1". + * At process/thread creation the current folder will be inherited ====================================================================== ======= Function 35 - read the color of a pixel on the screen. ======= @@ -3421,7 +3374,6 @@ Remarks: ====================================================================== The input mode influences results of reading keys by function 2. When a program loads, ASCII input mode is set for it. -If subfunction is not support then eax=-1. -------------- Subfunction 1 - set keyboard input mode. -------------- Parameters: @@ -3773,6 +3725,58 @@ Remarks: * If ecx=0, the function frees memory block at edx and returns 0. * The contents of the block are unchanged up to the shorter of the new and old sizes. +====================================================================== +======== Function 68, subfunction 22 - open named memory area. ======= +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 22 - subfunction number + * ecx = area name. Maximum of 31 characters with terminating zero + * edx = area size in bytes for SHM_CREATE and SHM_OPEN_ALWAYS + * esi = flags for open and access: + * SHM_OPEN = 0x00 - open existing memory area. If an area + with such name does not exist, the function + will return error code 5. + * SHM_OPEN_ALWAYS = 0x04 - open existing or create new + memory area. + * SHM_CREATE = 0x08 - create new memory area. If an area + with such name already exists, the function + will return error code 10. + * SHM_READ = 0x00 - only read access + * SHM_WRITE = 0x01 - read and write access +Returned value: + * eax = pointer to memory area, 0 if error has occured + * if new area is created (SHM_CREATE or SHM_OPEN_ALWAYS): + edx = 0 - success, otherwise - error code + * if existing area is opened (SHM_OPEN or SHM_OPEN_ALWAYS): + edx = error code (if eax=0) or area size in bytes +Error codes: + * E_NOTFOUND = 5 + * E_ACCESS = 10 + * E_NOMEM = 30 + * E_PARAM = 33 +Remarks: + * Before this call one must initialize process heap by call to + subfunction 11. + * If a new area is created, access flags set maximal rights + for other processes. An attempt from other process to open + with denied rights will fail with error code E_ACCESS. + * The process which has created an area always has write access. + +====================================================================== +======= Function 68, subfunction 23 - close named memory area. ======= +====================================================================== +Parameters: + * eax = 68 - function number + * ebx = 23 - subfunction number + * ecx = area name. Maximum of 31 characters with terminating zero +Returned value: + * eax destroyed +Remarks: + * A memory area is physically freed (with deleting all data and + freeing physical memory), when all threads which have opened + this area will close it. + * When thread is terminating, all opened by it areas are closed. ====================================================================== ====== Function 68, subfunction 24 - set new exceptions handler ====== @@ -3813,6 +3817,7 @@ Parameters: * edx = value of activity (0/1) Returned value: * eax = value of old activity for this signal (0/1) + * eax = -1 - invalid signal number Remarks: * In current implementation, it is changed only exception mask for user exception handler, wich was previously set by subfunction 24. @@ -4111,6 +4116,10 @@ Examples: * '/hd0/2/menuet/pics/tanzania.bmp',0 * '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0 * '/sys/MySuperApp.ini',0 +Also function supports relative names. If the path begins not +with '/', it is considered relative to a current folder. To get or +set a current folder, use the function 30. + Available subfunctions: * subfunction 0 - read file * subfunction 1 - read folder diff --git a/kernel/branches/Kolibri-A/trunk/drivers/codec.inc b/kernel/branches/Kolibri-A/trunk/drivers/codec.inc index 0c2569fd11..80a6661bec 100644 --- a/kernel/branches/Kolibri-A/trunk/drivers/codec.inc +++ b/kernel/branches/Kolibri-A/trunk/drivers/codec.inc @@ -173,7 +173,6 @@ patch_AD: ret - align 16 ac_unknown db 'unknown manufacturer',13,10,0 ac_Realtek db 'Realtek Semiconductor',13,10,0 @@ -181,6 +180,9 @@ ac_Analog db 'Analog Devices',13,10,0 ac_CMedia db 'C-Media Electronics',13,10,0 ac_Cirrus db 'Cirrus Logic',13,10,0 ac_Wolfson db 'Wolfson Microelectronics',13,10,0 +ac_VIA db 'VIA Technologies',13,10,0 +ac_SigmaTel db 'SigmaTel',13,10,0 +ac_eMicro db 'eMicro',13,10,0 chip_unknown db 'unknown codec id ', 0 @@ -189,6 +191,9 @@ CHIP_REALTEK equ 0x414C4700 CHIP_CMEDIA equ 0x434D4900 CHIP_CIRRUS equ 0x43525900 CHIP_WOLFSON equ 0x574D4C00 +CHIP_VIA equ 0x56494100 +CHIP_SIGMATEL equ 0x83847600 +CHIP_EMICRO equ 0x454D4300 align 16 codecs dd CHIP_ANALOG, ac_Analog, chips_Analog @@ -196,6 +201,9 @@ codecs dd CHIP_ANALOG, ac_Analog, chips_Analog dd CHIP_REALTEK,ac_Realtek, chips_Realtek dd CHIP_CIRRUS, ac_Cirrus, chips_Cirrus dd CHIP_WOLFSON,ac_Wolfson, chips_Wolfson + dd CHIP_VIA, ac_VIA, chips_VIA + dd CHIP_SIGMATEL, ac_SigmaTel, chips_SigmaTel + dd CHIP_EMICRO, ac_eMicro, chips_eMicro dd 0 align 16 @@ -207,6 +215,8 @@ chips_Analog dd 0x03, chip_AD1819 dd 0x62, chip_AD1887 dd 0x63, chip_AD1886A dd 0x70, chip_AD1980 + dd 0x72, chip_AD1981A + dd 0x74, chip_AD1981B dd 0x75, chip_AD1985 dd 0xFF @@ -243,8 +253,17 @@ chips_Cirrus dd 0x00, chip_CS4297 dd 0xFF chips_Wolfson dd 0x00, chip_WM9700 - dd 0x03, chip_WM9703 - dd 0x04, chip_WM9704 + dd 0x03, chip_WM9703 + dd 0x04, chip_WM9704 + dd 0xFF + +chips_VIA dd 0x61, chip_VIA1612A + dd 0xFF + +chips_SigmaTel dd 0x58, chip_STAC9758 + dd 0xFF + +chips_eMicro dd 0x28, chip_EM28028 dd 0xFF align 16 @@ -258,6 +277,8 @@ chip_AD1886 db 'AD1886 ',0dh,0ah,00h chip_AD1886A db 'AD1886A',0dh,0ah,00h chip_AD1887 db 'AD1887 ',0dh,0ah,00h chip_AD1980 db 'AD1980 ',0dh,0ah,00h +chip_AD1981A db 'AD1981A',0dh,0ah,00h +chip_AD1981B db 'AD1981B',0dh,0ah,00h chip_AD1985 db 'AD1985 ',0dh,0ah,00h ;Realtek @@ -290,6 +311,16 @@ chip_CS4291 db 'CS4291',13,10,0 chip_CS4202 db 'CS4202',13,10,0 ;Wolfson -chip_WM9700 db 'WM9704',13,10,0 -chip_WM9703 db 'WM9703/9704',13,10,0 -chip_WM9704 db 'WM9704 (quad)',13,10,0 +chip_WM9700 db 'WM9704',13,10,0 +chip_WM9703 db 'WM9703/9704',13,10,0 +chip_WM9704 db 'WM9704 (quad)',13,10,0 + +;VIA +chip_VIA1612A db 'VIA1612A',13,10,0 + +;SigmaTel +chip_STAC9758 db 'STAC9758,59',13,10,0 + +;eMicro +chip_EM28028 db 'EM28028',13,10,0 + diff --git a/kernel/branches/Kolibri-A/trunk/drivers/emu10k1x.asm b/kernel/branches/Kolibri-A/trunk/drivers/emu10k1x.asm new file mode 100644 index 0000000000..e2b1809832 --- /dev/null +++ b/kernel/branches/Kolibri-A/trunk/drivers/emu10k1x.asm @@ -0,0 +1,1166 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 + +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 +BIT5 EQU 0x00000020 +BIT10 EQU 0x00000400 + +VID_Creative equ 0x1102 + +CTRL_CT0200 equ 0x0006 ; Dell OEM version (EMU10K1X) + + +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 + + +;EMU10K1(X) host controller registers set +;; common offsets +;; some definitions were borrowed from emu10k1 driver as they seem to be the same +;;**********************************************************************************************;; +;; PCI function 0 registers, address = + PCIBASE0 ;; +;;**********************************************************************************************;; + +PTR equ 0x00 ;; Indexed register set pointer register ;; + ;; NOTE: The CHANNELNUM and ADDRESS words can ;; + ;; be modified independently of each other. ;; + +DATA equ 0x04 ;; Indexed register set data register ;; + +IPR equ 0x08 ;; Global interrupt pending register ;; + ;; Clear pending interrupts by writing a 1 to ;; + ;; the relevant bits and zero to the other bits ;; +IPR_MIDITRANSBUFEMPTY equ 0x00000001 ;; MIDI UART transmit buffer empty ;; +IPR_MIDIRECVBUFEMPTY equ 0x00000002 ;; MIDI UART receive buffer empty ;; +IPR_CH_0_LOOP equ 0x00000800 ;; Channel 0 loop ;; +IPR_CH_0_HALF_LOOP equ 0x00000100 ;; Channel 0 half loop ;; +IPR_CAP_0_LOOP equ 0x00080000 ;; Channel capture loop ;; +IPR_CAP_0_HALF_LOOP equ 0x00010000 ;; Channel capture half loop ;; + +INTE equ 0x0c ;; Interrupt enable register ;; +INTE_MIDITXENABLE equ 0x00000001 ;; Enable MIDI transmit-buffer-empty interrupts ;; +INTE_MIDIRXENABLE equ 0x00000002 ;; Enable MIDI receive-buffer-empty interrupts ;; +INTE_CH_0_LOOP equ 0x00000800 ;; Channel 0 loop ;; +INTE_CH_0_HALF_LOOP equ 0x00000100 ;; Channel 0 half loop ;; +INTE_CAP_0_LOOP equ 0x00080000 ;; Channel capture loop ;; +INTE_CAP_0_HALF_LOOP equ 0x00010000 ;; Channel capture half loop ;; + +HCFG equ 0x14 ;; Hardware config register ;; + +HCFG_LOCKSOUNDCACHE equ 0x00000008 ;; 1 = Cancel bustmaster accesses to soundcache ;; + ;; NOTE: This should generally never be used. ;; +HCFG_AUDIOENABLE equ 0x00000001 ;; 0 = CODECs transmit zero-valued samples ;; + ;; Should be set to 1 when the EMU10K1 is ;; + ;; completely initialized. ;; +GPIO equ 0x18 ;; Defaults: 00001080-Analog, 00001000-SPDIF. ;; + + +AC97DATA equ 0x1c ;; AC97 register set data register (16 bit) ;; + +AC97ADDRESS equ 0x1e ;; AC97 register set address register (8 bit) ;; + +;;******************************************************************************************************;; +;; Emu10k1x pointer-offset register set, accessed through the PTR and DATA registers ;; +;;******************************************************************************************************;; +PLAYBACK_LIST_ADDR equ 0x00 ;; Base DMA address of a list of pointers to each period/size ;; + ;; One list entry: 4 bytes for DMA address, + ;; 4 bytes for period_size << 16. + ;; One list entry is 8 bytes long. + ;; One list entry for each period in the buffer. + ;; +PLAYBACK_LIST_SIZE equ 0x01 ;; Size of list in bytes << 19. E.g. 8 periods -> 0x00380000 ;; +PLAYBACK_LIST_PTR equ 0x02 ;; Pointer to the current period being played ;; +PLAYBACK_DMA_ADDR equ 0x04 ;; Playback DMA addresss ;; +PLAYBACK_PERIOD_SIZE equ 0x05 ;; Playback period size ;; +PLAYBACK_POINTER equ 0x06 ;; Playback period pointer. Sample currently in DAC ;; +PLAYBACK_UNKNOWN1 equ 0x07 +PLAYBACK_UNKNOWN2 equ 0x08 + +;; Only one capture channel supported ;; +CAPTURE_DMA_ADDR equ 0x10 ;; Capture DMA address ;; +CAPTURE_BUFFER_SIZE equ 0x11 ;; Capture buffer size ;; +CAPTURE_POINTER equ 0x12 ;; Capture buffer pointer. Sample currently in ADC ;; +CAPTURE_UNKNOWN equ 0x13 + +;; From 0x20 - 0x3f, last samples played on each channel ;; + +TRIGGER_CHANNEL equ 0x40 ;; Trigger channel playback ;; +TRIGGER_CHANNEL_0 equ 0x00000001 ;; Trigger channel 0 ;; +TRIGGER_CHANNEL_1 equ 0x00000002 ;; Trigger channel 1 ;; +TRIGGER_CHANNEL_2 equ 0x00000004 ;; Trigger channel 2 ;; +TRIGGER_CAPTURE equ 0x00000100 ;; Trigger capture channel ;; + +ROUTING equ 0x41 ;; Setup sound routing ? ;; +ROUTING_FRONT_LEFT equ 0x00000001 +ROUTING_FRONT_RIGHT equ 0x00000002 +ROUTING_REAR_LEFT equ 0x00000004 +ROUTING_REAR_RIGHT equ 0x00000008 +ROUTING_CENTER_LFE equ 0x00010000 + +SPCS0 equ 0x42 ;; SPDIF output Channel Status 0 register ;; +SPCS1 equ 0x43 ;; SPDIF output Channel Status 1 register ;; +SPCS2 equ 0x44 ;; SPDIF output Channel Status 2 register ;; + +SPCS_CLKACCYMASK equ 0x30000000 ;; Clock accuracy ;; +SPCS_CLKACCY_1000PPM equ 0x00000000 ;; 1000 parts per million ;; +SPCS_CLKACCY_50PPM equ 0x10000000 ;; 50 parts per million ;; +SPCS_CLKACCY_VARIABLE equ 0x20000000 ;; Variable accuracy ;; +SPCS_SAMPLERATEMASK equ 0x0f000000 ;; Sample rate ;; +SPCS_SAMPLERATE_44 equ 0x00000000 ;; 44.1kHz sample rate ;; +SPCS_SAMPLERATE_48 equ 0x02000000 ;; 48kHz sample rate ;; +SPCS_SAMPLERATE_32 equ 0x03000000 ;; 32kHz sample rate ;; +SPCS_CHANNELNUMMASK equ 0x00f00000 ;; Channel number ;; +SPCS_CHANNELNUM_UNSPEC equ 0x00000000 ;; Unspecified channel number ;; +SPCS_CHANNELNUM_LEFT equ 0x00100000 ;; Left channel ;; +SPCS_CHANNELNUM_RIGHT equ 0x00200000 ;; Right channel ;; +SPCS_SOURCENUMMASK equ 0x000f0000 ;; Source number ;; +SPCS_SOURCENUM_UNSPEC equ 0x00000000 ;; Unspecified source number ;; +SPCS_GENERATIONSTATUS equ 0x00008000 ;; Originality flag (see IEC-958 spec) ;; +SPCS_CATEGORYCODEMASK equ 0x00007f00 ;; Category code (see IEC-958 spec) ;; +SPCS_MODEMASK equ 0x000000c0 ;; Mode (see IEC-958 spec) ;; +SPCS_EMPHASISMASK equ 0x00000038 ;; Emphasis ;; +SPCS_EMPHASIS_NONE equ 0x00000000 ;; No emphasis ;; +SPCS_EMPHASIS_50_15 equ 0x00000008 ;; 50/15 usec 2 channel ;; +SPCS_COPYRIGHT equ 0x00000004 ;; Copyright asserted flag -- do not modify ;; +SPCS_NOTAUDIODATA equ 0x00000002 ;; 0 = Digital audio, 1 = not audio ;; +SPCS_PROFESSIONAL equ 0x00000001 ;; 0 = Consumer (IEC-958), 1 = pro (AES3-1992) ;; + +SPDIF_SELECT equ 0x45 ;; Enables SPDIF or Analogue outputs 0-Analogue, 0x700-SPDIF ;; + +;; This is the MPU port on the card ;; +MUDATA equ 0x47 +MUCMD equ 0x48 +MUSTAT equ MUCMD + +;; From 0x50 - 0x5f, last samples captured ;; + + +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 + +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 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 + + stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE ;remap IRQ + + 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 eax, VALID_IRQ + mov ebx, [ctrl.int_line] + mov esi, msgInvIRQ + bt eax, ebx + jnc .fail_msg + mov eax, ATTCH_IRQ + mov esi, msgAttchIRQ + bt eax, ebx + jnc .fail_msg + + stdcall AttachIntHandler, ebx, ac97_irq, dword 0 + stdcall create + +.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_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 + locals + status dd 0 + endl + +; status = inl(chip->port + IPR); + mov edx, IPR + call [ctrl.ctrl_read32] + test eax, eax + jz @f + + mov dword [status], eax + + mov ebx, dword [buff_list] + cmp [ctrl.user_callback], 0 + je @f + stdcall [ctrl.user_callback], ebx + @@: + mov eax, dword [status] ;; ack ;; + mov edx, IPR + call [ctrl.ctrl_write32] + ret +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 edi, pcmout_bdl + stosd + mov eax, 0x4000000 + stosd + + mov edi, buff_list + mov eax, [ctrl.buffer] + stosd ;1.] + + mov eax, [ctrl.buffer] + call GetPgAddr + + stdcall ptr_write, PLAYBACK_POINTER, 0, 0 + stdcall ptr_write, PLAYBACK_UNKNOWN1, 0, 0 + stdcall ptr_write, PLAYBACK_UNKNOWN2, 0, 0 + stdcall ptr_write, PLAYBACK_DMA_ADDR, 0, eax + + mov eax, pcmout_bdl + mov ebx, eax + call GetPgAddr + and ebx, 0xFFF + add eax, ebx + + stdcall ptr_write, PLAYBACK_LIST_ADDR, 0, eax + stdcall ptr_write, PLAYBACK_LIST_SIZE, 0, 0 + stdcall ptr_write, PLAYBACK_LIST_PTR, 0, 0 + + ;mov eax, 0x00004000 + ;shl eax, 16 + stdcall ptr_write, PLAYBACK_PERIOD_SIZE, 0, 0x40000000;eax + + 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_Creative + jne @F + mov [ctrl.vendor_ids], msg_Creative + 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 0x2C + mov esi, msgPciSubsys + call SysMsgBoardStr + call dword2str + call SysMsgBoardStr + + 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, msgCtrlIsaIo + call SysMsgBoardStr + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 + call dword2str + call SysMsgBoardStr + + and eax, 0xFFC0 + mov [ctrl.ctrl_io_base], eax + +.default: + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C + and eax, 0xFF +@@: + mov [ctrl.int_line], eax + + call [ctrl.ctrl_setup] + xor eax, eax + inc eax + ret +endp + +align 4 +proc set_Creative + 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 + + +align 4 +proc init_codec + call reset_codec + test eax, eax + jz .err + call detect_codec + xor eax, eax + inc eax + ret + .err: + xor eax, eax + ret +endp + +align 4 +proc reset_codec + locals + counter dd ? + endl + + if DEBUG + mov esi, msgCold + call SysMsgBoardStr + end if + + mov eax, 100000 ; wait 100 ms ;400000 ; wait 400 ms + call StallExec + + stdcall ptr_read, TRIGGER_CHANNEL, 0 + + mov [counter], 16 ; total 20*100 ms = 2s +.wait: + stdcall codec_read, dword 0x26 + test eax, 1 + 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: + + + xor eax, eax + inc eax + ret +endp + + +align 4 +play: + mov eax, INTE_CH_0_LOOP + stdcall intr_enable, eax + + stdcall ptr_read, TRIGGER_CHANNEL, 0 + mov ebx, TRIGGER_CHANNEL_0 + or eax, ebx + stdcall ptr_write, TRIGGER_CHANNEL, 0, eax + + xor eax, eax + ret + +align 4 +stop: + mov eax, INTE_CH_0_LOOP or INTE_CH_0_HALF_LOOP + stdcall intr_disable, eax + + stdcall ptr_read, TRIGGER_CHANNEL, 0 + mov ebx, TRIGGER_CHANNEL_0 + xor ebx, -1 + or eax, ebx + stdcall ptr_write, TRIGGER_CHANNEL, 0, eax + 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 ecx, [ctrl.ctrl_io_base] + mov [CTRL_INFO.irq], eax + mov [CTRL_INFO.ctrl_io_base], ecx + mov eax, [codec.chip_id] + mov [CTRL_INFO.codec_id], eax + mov ebx, [ctrl.pci_cmd] + mov [CTRL_INFO.pci_cmd], ebx + + xor eax, eax + mov [CTRL_INFO.codec_io_base], eax + mov [CTRL_INFO.codec_mem_base], eax + mov [CTRL_INFO.ctrl_mem_base], eax + mov [CTRL_INFO.glob_cntrl], eax + mov [CTRL_INFO.glob_sta], eax + ret +endp + +align 4 +proc set_callback stdcall, handler:dword + mov eax, [handler] + mov [ctrl.user_callback], eax + ret +endp + + +align 4 +proc create stdcall + stdcall PciRead16, [ctrl.bus], [ctrl.devfn], dword 4 + test eax, 4 ; test master bit + jnz @f + or eax, 4 + stdcall PciWrite16, [ctrl.bus], [ctrl.devfn], dword 4, eax ; set master bit + @@: + + xor eax, eax + mov edx, INTE + call [ctrl.ctrl_write32] + + stdcall ptr_write, SPCS0, 0, \ + SPCS_CLKACCY_1000PPM or SPCS_SAMPLERATE_48 or \ + SPCS_CHANNELNUM_LEFT or SPCS_SOURCENUM_UNSPEC or \ + SPCS_GENERATIONSTATUS or 0x00001200 or \ + 0x00000000 or SPCS_EMPHASIS_NONE or SPCS_COPYRIGHT + stdcall ptr_write, SPCS1, 0, \ + SPCS_CLKACCY_1000PPM or SPCS_SAMPLERATE_48 or \ + SPCS_CHANNELNUM_LEFT or SPCS_SOURCENUM_UNSPEC or \ + SPCS_GENERATIONSTATUS or 0x00001200 or \ + 0x00000000 or SPCS_EMPHASIS_NONE or SPCS_COPYRIGHT + stdcall ptr_write, SPCS2, 0, \ + SPCS_CLKACCY_1000PPM or SPCS_SAMPLERATE_48 or \ + SPCS_CHANNELNUM_LEFT or SPCS_SOURCENUM_UNSPEC or \ + SPCS_GENERATIONSTATUS or 0x00001200 or \ + 0x00000000 or SPCS_EMPHASIS_NONE or SPCS_COPYRIGHT + + stdcall ptr_write, SPDIF_SELECT, 0, 0x700 ; disable SPDIF + stdcall ptr_write, ROUTING, 0, 0x1003F ; routing + stdcall gpio_write, 0x1080 ; analog mode + + mov eax, dword HCFG_LOCKSOUNDCACHE or HCFG_AUDIOENABLE + mov edx, HCFG + call [ctrl.ctrl_write32] + ret +endp + +align 4 +proc codec_read stdcall, reg:dword + stdcall ac97_read, dword [reg] + ret +endp + + +align 4 +proc codec_write stdcall, reg:dword + stdcall ac97_write, dword [reg], eax + ret +endp + + +align 4 +proc ac97_read stdcall, reg:dword + push edx + mov eax, dword [reg] + mov edx, AC97ADDRESS + call [ctrl.ctrl_write8] + + mov edx, AC97DATA + call [ctrl.ctrl_read16] + and eax, 0xFFFF + pop edx + ret +endp + +align 4 +proc ac97_write stdcall, reg:dword, val:dword + push eax edx + mov eax, dword [reg] + mov edx, AC97ADDRESS + call [ctrl.ctrl_write8] + + mov eax, dword [val] + mov edx, AC97DATA + call [ctrl.ctrl_write16] + pop edx eax + ret +endp + +align 4 +proc ptr_read stdcall, reg:dword, chn:dword + push edx + mov eax, dword [reg] + shl eax, 16 + or eax, dword [chn] + + mov edx, PTR + call [ctrl.ctrl_write32] + + mov edx, DATA + call [ctrl.ctrl_read32] + pop edx + ret +endp + +align 4 +proc ptr_write stdcall, reg:dword, chn:dword, data:dword + push eax edx + mov eax, dword [reg] + shl eax, 16 + or eax, dword [chn] + + mov edx, PTR + call [ctrl.ctrl_write32] + + mov eax, dword [data] + mov edx, DATA + call [ctrl.ctrl_write32] + pop edx eax + ret +endp + +align 4 +proc intr_enable stdcall, intrenb:dword + push edx + mov edx, INTE + call [ctrl.ctrl_read32] + + or eax, dword [intrenb] + mov edx, INTE + call [ctrl.ctrl_write32] + pop edx + ret +endp + +align 4 +proc intr_disable stdcall, intrenb:dword + push eax ebx edx + mov edx, INTE + call [ctrl.ctrl_read32] + + mov ebx, dword [intrenb] + xor ebx, -1 + and eax, ebx + mov edx, INTE + call [ctrl.ctrl_write32] + pop edx ebx eax + ret +endp + +align 4 +proc gpio_write stdcall, value:dword + push eax edx + mov eax, dword [value] + mov edx, GPIO + call [ctrl.ctrl_write32] + pop edx 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 ;Not used. + ;mov edx, [ctrl.ctrl_io_base] + ;in eax, dx + ret +endp + +align 4 +proc codec_io_w16 ;Not used. + ;mov edx, [ctrl.ctrl_io_base] + ;out dx, eax + 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 + + +align 4 +dword2str: + push eax ebx ecx + 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 + pop ecx ebx eax + ret + +hexletters db '0123456789ABCDEF' +hex_buff db 8 dup(0),13,10,0 + + +include "codec.inc" + +align 4 +devices dd (CTRL_CT0200 shl 16)+VID_Creative,msg_CT_EMU10K1X,set_Creative + dd 0 ;terminator + + +version dd (5 shl 16) or (API_VERSION and 0xFFFF) + +msg_CT_EMU10K1X db 'SB Live! Dell OEM', 13,10, 0 +msg_Creative db 'Creative ', 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 +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 +;msgCInvalid db 'codec is not valid',13,10,0 ;Asper +;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 +msgPciSubsys db 'PCI subsystem ',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 diff --git a/kernel/branches/Kolibri-A/trunk/drivers/imports.inc b/kernel/branches/Kolibri-A/trunk/drivers/imports.inc index df1ee70f0c..c4a7dac43c 100644 --- a/kernel/branches/Kolibri-A/trunk/drivers/imports.inc +++ b/kernel/branches/Kolibri-A/trunk/drivers/imports.inc @@ -26,6 +26,10 @@ kernel_export \ FpuRestore,\ ReservePortArea,\ Boot_Log,\ +\ + MutexInit,\ + MutexLock,\ + MutexUnlock,\ \ PciApi,\ PciRead32,\ diff --git a/kernel/branches/Kolibri-A/trunk/drivers/infinity.asm b/kernel/branches/Kolibri-A/trunk/drivers/infinity.asm index bcfbe909d4..307d5a85b3 100644 --- a/kernel/branches/Kolibri-A/trunk/drivers/infinity.asm +++ b/kernel/branches/Kolibri-A/trunk/drivers/infinity.asm @@ -159,31 +159,44 @@ inp_size equ IOCTL.inp_size output equ IOCTL.output out_size equ IOCTL.out_size + + align 4 + +srv_calls dd service_proc.srv_getversion ; 0 + dd service_proc.snd_create_buff ; 1 + dd service_proc.snd_destroy_buff ; 2 + dd service_proc.snd_setformat ; 3 + dd service_proc.snd_getformat ; 4 + dd service_proc.snd_reset ; 5 + dd service_proc.snd_setpos ; 6 + dd service_proc.snd_getpos ; 7 + dd service_proc.snd_setbuff ; 8 + dd service_proc.snd_out ; 9 + dd service_proc.snd_play ; 10 + dd service_proc.snd_stop ; 11 + dd service_proc.snd_setvolume ; 12 + dd service_proc.snd_getvolume ; 13 + dd service_proc.snd_setpan ; 14 + dd service_proc.snd_getpan ; 15 + dd service_proc.snd_getbuffsize ; 16 + dd service_proc.snd_getfreespace ; 17 + dd service_proc.snd_settimebase ; 18 + dd service_proc.snd_gettimestamp ; 19 +srv_calls_end: + 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, [eax] - mov [eax], dword API_VERSION - xor eax, eax - ret -@@: + cmp eax, (srv_calls_end-srv_calls)/4 + ja .fail + cmp eax, SND_CREATE_BUFF - jne @F - mov ebx, [edi+input] - stdcall CreateBuffer,[ebx],[ebx+4] - mov edi, [ioctl] - mov ecx, [edi+output] - mov ecx, [ecx] - mov [ecx], ebx - ret + ja @F + + jmp [srv_calls+eax*4] @@: mov ebx, [edi+input] mov edx, [ebx] @@ -191,114 +204,132 @@ proc service_proc stdcall, ioctl:dword cmp [edx+STREAM.magic], 'WAVE' jne .fail - cmp [edx+STREAM.size], STREAM_SIZE + cmp [edx+STREAM.size], STREAM.sizeof jne .fail - cmp eax, SND_DESTROY_BUFF - jne @F - mov eax, edx - call DestroyBuffer ;edx= stream + jmp [srv_calls+eax*4] +.fail: + mov eax, -1 ret -@@: - cmp eax, SND_SETFORMAT - jne @F - stdcall SetFormat,edx,[ebx+4] - ret -@@: - cmp eax, SND_GETFORMAT - jne @F +align 4 +.srv_getversion: + mov eax, [edi+output] + cmp [edi+out_size], 4 + jne .fail + mov eax, [eax] + mov [eax], dword API_VERSION + xor eax, eax + ret + +align 4 +.snd_create_buff: + mov ebx, [edi+input] + stdcall CreateBuffer,[ebx],[ebx+4] + mov edi, [ioctl] + mov ecx, [edi+output] + mov ecx, [ecx] + mov [ecx], ebx + ret + +align 4 +.snd_destroy_buff: + mov eax, edx + call DestroyBuffer + ret + +align 4 +.snd_setformat: + stdcall SetFormat, edx,[ebx+4] + ret + +align 4 +.snd_getformat: movzx eax, word [edx+STREAM.format] mov ecx, [edi+output] mov ecx, [ecx] mov [ecx], eax xor eax, eax ret -@@: - cmp eax, SND_RESET - jne @F + +align 4 +.snd_reset: stdcall ResetBuffer,edx,[ebx+4] ret -@@: - cmp eax, SND_SETPOS - jne @F + +align 4 +.snd_setpos: stdcall SetBufferPos,edx,[ebx+4] ret -@@: - cmp eax, SND_GETPOS - jne @F + +align 4 +.snd_getpos: stdcall GetBufferPos, edx mov edi, [ioctl] mov ecx, [edi+output] mov ecx, [ecx] mov [ecx], ebx ret -@@: - cmp eax, SND_SETBUFF - jne @F + +align 4 +.snd_setbuff: mov eax, [ebx+4] stdcall set_buffer, edx,eax,[ebx+8],[ebx+12] ret -@@: - cmp eax, SND_SETVOLUME - jne @F + +align 4 +.snd_out: + mov eax, [ebx+4] + stdcall wave_out, edx,eax,[ebx+8] + ret + +align 4 +.snd_play: + stdcall play_buffer, edx,[ebx+4] + ret + +align 4 +.snd_stop: + stdcall stop_buffer, edx + ret + +align 4 +.snd_setvolume: stdcall SetBufferVol,edx,[ebx+4],[ebx+8] ret -@@: - cmp eax, SND_GETVOLUME - jne @F +align 4 +.snd_getvolume: mov eax, [edi+output] mov ecx, [eax] mov eax, [eax+4] stdcall GetBufferVol,edx,ecx,eax ret -@@: - cmp eax, SND_SETPAN - jne @F +align 4 +.snd_setpan: stdcall SetBufferPan,edx,[ebx+4] ret -@@: - cmp eax, SND_GETPAN - jne @F + +align 4 +.snd_getpan: mov eax, [edx+STREAM.pan] mov ebx, [edi+output] mov ebx, [ebx] mov [ebx], eax xor eax, eax ret -@@: - cmp eax, SND_OUT - jne @F - mov eax, [ebx+4] - stdcall wave_out, edx,eax,[ebx+8] - ret -@@: - cmp eax, SND_PLAY - jne @F - - stdcall play_buffer, edx,[ebx+4] - ret -@@: - cmp eax, SND_STOP - jne @F - - stdcall stop_buffer, edx - ret -@@: - cmp eax, SND_GETBUFFSIZE - jne @F +align 4 +.snd_getbuffsize: mov eax, [edx+STREAM.in_size] mov ecx, [edi+output] mov ecx, [ecx] mov [ecx], eax xor eax, eax ret -@@: - cmp eax, SND_GETFREESPACE - jne @F +align 4 +.snd_getfreespace: test [edx+STREAM.format], PCM_OUT jz .fail @@ -307,12 +338,38 @@ proc service_proc stdcall, ioctl:dword mov [ecx], ebx xor eax, eax ret -@@: -.fail: - or eax, -1 +align 4 +.snd_settimebase: + cmp [edi+inp_size], 8 + jne .fail + + mov edi, [edi+input] + mov eax, [edi] + mov ebx, [edi+4] + mov dword [edx+STREAM.time_base], eax + mov dword [edx+STREAM.time_base+4], ebx + xor eax, eax + ret + +.snd_gettimestamp: + cmp [edi+out_size], 8 + jne .fail + + mov edi, [edi+output] + + push 48 + emms + fild qword [edx+STREAM.time_stamp] + fidiv dword [esp] + fadd qword [edx+STREAM.time_base] + fstp qword [edi] + add esp, 4 + + xor eax, eax ret endp + restore handle restore io_code restore input @@ -352,7 +409,7 @@ proc CreateBuffer stdcall, format:dword, size:dword call GetPid mov ebx, eax - mov eax, STREAM_SIZE + mov eax, STREAM.sizeof call CreateObject test eax, eax @@ -412,7 +469,6 @@ proc CreateBuffer stdcall, format:dword, size:dword mov [edi+STREAM.in_base], eax mov [edi+STREAM.in_size], ecx add eax, 128 - ; sub ecx, 128 mov [edi+STREAM.in_wp], eax mov [edi+STREAM.in_rp], eax mov [edi+STREAM.in_count], 0 @@ -443,13 +499,21 @@ proc CreateBuffer stdcall, format:dword, size:dword stdcall AllocKernelSpace, dword 128*1024 mov edi, [str] + xor ebx, ebx + mov [edi+STREAM.out_base], eax mov [edi+STREAM.out_wp], eax mov [edi+STREAM.out_rp], eax - mov [edi+STREAM.out_count], 0 + mov [edi+STREAM.out_count], ebx add eax, 64*1024 mov [edi+STREAM.out_top], eax + mov dword [edi+STREAM.time_base], ebx + mov dword [edi+STREAM.time_base+4], ebx + + mov dword [edi+STREAM.time_stamp], ebx + mov dword [edi+STREAM.time_stamp+4], ebx + stdcall AllocPages, dword 64/4 mov edi, [str] mov ebx, [edi+STREAM.out_base] @@ -488,7 +552,7 @@ proc CreateBuffer stdcall, format:dword, size:dword mov [ebx+STREAM.magic], 'WAVE' mov [ebx+STREAM.destroy], DestroyBuffer.destroy - mov [ebx+STREAM.size], STREAM_SIZE + mov [ebx+STREAM.size], STREAM.sizeof mov [ebx+STREAM.flags], SND_STOP pushf @@ -1039,7 +1103,7 @@ do_mix_list: cmp [ebx+STREAM.magic], 'WAVE' jne .next - cmp [ebx+STREAM.size], STREAM_SIZE + cmp [ebx+STREAM.size], STREAM.sizeof jne .next cmp [ebx+STREAM.flags], SND_PLAY; @@ -1108,7 +1172,7 @@ prepare_playlist: cmp [edi+STREAM.magic], 'WAVE' jne .next - cmp [edi+STREAM.size], STREAM_SIZE + cmp [edi+STREAM.size], STREAM.sizeof jne .next cmp [edi+STREAM.flags], SND_PLAY; diff --git a/kernel/branches/Kolibri-A/trunk/drivers/main.inc b/kernel/branches/Kolibri-A/trunk/drivers/main.inc index 67198c304d..e1d10b3160 100644 --- a/kernel/branches/Kolibri-A/trunk/drivers/main.inc +++ b/kernel/branches/Kolibri-A/trunk/drivers/main.inc @@ -91,6 +91,8 @@ SND_SETPAN equ 14 SND_GETPAN equ 15 SND_GETBUFFSIZE equ 16 SND_GETFREESPACE equ 17 +SND_SETTIMEBASE equ 18 +SND_GETTIMESTAMP equ 19 struc STREAM { @@ -113,6 +115,22 @@ struc STREAM .out_count dd ? .out_top dd ? ;16*4 + .in_base dd ? + .in_size dd ? + .in_wp dd ? + .in_rp dd ? + .in_count dd ? + .in_free dd ? + .in_top dd ? + +align 8 + + .time_base dq ? + .time_stamp dq ? + + .notify_event dd ? + .notify_id dd ? + .r_size dd ? .r_dt dd ? .r_silence dd ? @@ -125,19 +143,9 @@ struc STREAM .l_amp_f dd ? ;float point left .r_amp_f dd ? ;float point right - .in_base dd ? - .in_size dd ? - .in_wp dd ? - .in_rp dd ? - .in_count dd ? - .in_free dd ? - .in_top dd ? - - .notify_event dd ? - .notify_id dd ? + .sizeof: } -STREAM_SIZE equ 36*4 FD_OFFSET equ 24 virtual at 0 diff --git a/kernel/branches/Kolibri-A/trunk/drivers/mixer.asm b/kernel/branches/Kolibri-A/trunk/drivers/mixer.asm index f825ef4612..ccb533e463 100644 --- a/kernel/branches/Kolibri-A/trunk/drivers/mixer.asm +++ b/kernel/branches/Kolibri-A/trunk/drivers/mixer.asm @@ -87,7 +87,7 @@ end if endp align 4 -proc update_stream +proc update_streams locals stream_index dd ? event rd 6 @@ -98,6 +98,9 @@ proc update_stream mov edx, [stream_index] mov esi, [play_list+edx*4] + add dword [esi+STREAM.time_stamp], 4096 + adc dword [esi+STREAM.time_stamp+4], 0 + mov eax, [esi+STREAM.out_rp] cmp eax, [esi+STREAM.out_top] jb @f diff --git a/kernel/branches/Kolibri-A/trunk/drivers/vt823(x).asm b/kernel/branches/Kolibri-A/trunk/drivers/vt823(x).asm new file mode 100644 index 0000000000..51de417386 --- /dev/null +++ b/kernel/branches/Kolibri-A/trunk/drivers/vt823(x).asm @@ -0,0 +1,1281 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2007. 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 + +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 +BIT5 EQU 0x00000020 +BIT10 EQU 0x00000400 + +VID_VIA equ 0x1106 + +CTRL_VT82C686 equ 0x3058 +CTRL_VT8233_5 equ 0x3059 + + +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 + + +;VIA host controller registers set +;; common offsets +VIA_REG_OFFSET_STATUS equ 0x00 ;; byte - channel status + VIA_REG_STAT_ACTIVE equ 0x80 ;; RO + VIA_REG_STAT_PAUSED equ 0x40 ;; RO + VIA_REG_STAT_TRIGGER_QUEUED equ 0x08 ;; RO + VIA_REG_STAT_STOPPED equ 0x04 ;; RWC + VIA_REG_STAT_EOL equ 0x02 ;; RWC + VIA_REG_STAT_FLAG equ 0x01 ;; RWC +VIA_REG_OFFSET_CONTROL equ 0x01 ;; byte - channel control + VIA_REG_CTRL_START equ 0x80 ;; WO + VIA_REG_CTRL_TERMINATE equ 0x40 ;; WO + VIA_REG_CTRL_AUTOSTART equ 0x20 + VIA_REG_CTRL_PAUSE equ 0x08 ;; RW + VIA_REG_CTRL_INT_STOP equ 0x04 + VIA_REG_CTRL_INT_EOL equ 0x02 + VIA_REG_CTRL_INT_FLAG equ 0x01 + VIA_REG_CTRL_RESET equ 0x01 ;; RW - probably reset? undocumented + VIA_REG_CTRL_INT equ (VIA_REG_CTRL_INT_FLAG or \ + VIA_REG_CTRL_INT_EOL or \ + VIA_REG_CTRL_AUTOSTART) +VIA_REG_OFFSET_TYPE equ 0x02 ;; byte - channel type (686 only) + VIA_REG_TYPE_AUTOSTART equ 0x80 ;; RW - autostart at EOL + VIA_REG_TYPE_16BIT equ 0x20 ;; RW + VIA_REG_TYPE_STEREO equ 0x10 ;; RW + VIA_REG_TYPE_INT_LLINE equ 0x00 + VIA_REG_TYPE_INT_LSAMPLE equ 0x04 + VIA_REG_TYPE_INT_LESSONE equ 0x08 + VIA_REG_TYPE_INT_MASK equ 0x0c + VIA_REG_TYPE_INT_EOL equ 0x02 + VIA_REG_TYPE_INT_FLAG equ 0x01 +VIA_REG_OFFSET_TABLE_PTR equ 0x04 ;; dword - channel table pointer +VIA_REG_OFFSET_CURR_PTR equ 0x04 ;; dword - channel current pointer +VIA_REG_OFFSET_STOP_IDX equ 0x08 ;; dword - stop index, channel type, sample rate + VIA8233_REG_TYPE_16BIT equ 0x00200000 ;; RW + VIA8233_REG_TYPE_STEREO equ 0x00100000 ;; RW +VIA_REG_OFFSET_CURR_COUNT equ 0x0c ;; dword - channel current count (24 bit) +VIA_REG_OFFSET_CURR_INDEX equ 0x0f ;; byte - channel current index (for via8233 only) + + +VIADEV_PLAYBACK equ 0x00 +VIADEV_CAPTURE equ 0x10 +VIADEV_FM equ 0x20 + +;; AC'97 ;; +VIA_REG_AC97 equ 0x80 ; dword + VIA_REG_AC97_CODEC_ID_MASK equ 0xC0000000 ;(3<<30) + VIA_REG_AC97_CODEC_ID_SHIFT equ 30 + VIA_REG_AC97_CODEC_ID_PRIMARY equ 0x00 + VIA_REG_AC97_CODEC_ID_SECONDARY equ 0x01 + VIA_REG_AC97_SECONDARY_VALID equ 0x08000000 ;(1<<27) + VIA_REG_AC97_PRIMARY_VALID equ 0x02000000 ;(1<<25) + VIA_REG_AC97_BUSY equ 0x01000000 ;(1<<24) + VIA_REG_AC97_READ equ 0x00800000 ;(1<<23) + VIA_REG_AC97_CMD_SHIFT equ 16 + VIA_REG_AC97_CMD_MASK equ 0x7E + VIA_REG_AC97_DATA_SHIFT equ 0 + VIA_REG_AC97_DATA_MASK equ 0xFFFF + +VIA_REG_SGD_SHADOW equ 0x84 ; dword + +;; via8233-specific registers ;; +VIA_REG_OFS_PLAYBACK_VOLUME_L equ 0x02 ;; byte +VIA_REG_OFS_PLAYBACK_VOLUME_R equ 0x03 ;; byte +VIA_REG_OFS_MULTPLAY_FORMAT equ 0x02 ;; byte - format and channels + VIA_REG_MULTPLAY_FMT_8BIT equ 0x00 + VIA_REG_MULTPLAY_FMT_16BIT equ 0x80 + VIA_REG_MULTPLAY_FMT_CH_MASK equ 0x70 ;; # channels << 4 (valid = 1,2,4,6) +VIA_REG_OFS_CAPTURE_FIFO equ 0x02 ;; byte - bit 6 = fifo enable + VIA_REG_CAPTURE_FIFO_ENABLE equ 0x40 + +VIA_DXS_MAX_VOLUME equ 31 ;; max. volume (attenuation) of reg 0x32/33 + +VIA_TBL_BIT_FLAG equ 0x40000000 +VIA_TBL_BIT_EOL equ 0x80000000 + +;; pci space ;; +VIA_ACLINK_STAT equ 0x40 + ;... + VIA_ACLINK_C00_READY equ 0x01 ; primary codec ready +VIA_ACLINK_CTRL equ 0x41 + VIA_ACLINK_CTRL_ENABLE equ 0x80 ; 0: disable, 1: enable + VIA_ACLINK_CTRL_RESET equ 0x40 ; 0: assert, 1: de-assert + VIA_ACLINK_CTRL_SYNC equ 0x20 ; 0: release SYNC, 1: force SYNC hi + VIA_ACLINK_CTRL_SDO equ 0x10 ; 0: release SDO, 1: force SDO hi + VIA_ACLINK_CTRL_VRA equ 0x08 ; 0: disable VRA, 1: enable VRA + VIA_ACLINK_CTRL_PCM equ 0x04 ; 0: disable PCM, 1: enable PCM + VIA_ACLINK_CTRL_FM equ 0x02 ; via686 only + VIA_ACLINK_CTRL_SB equ 0x01 ; via686 only + VIA_ACLINK_CTRL_INIT equ (VIA_ACLINK_CTRL_ENABLE or \ + VIA_ACLINK_CTRL_RESET or \ + VIA_ACLINK_CTRL_PCM or \ + VIA_ACLINK_CTRL_VRA) +VIA_FUNC_ENABLE equ 0x42 + VIA_FUNC_MIDI_PNP equ 0x80 ; FIXME: it's 0x40 in the datasheet! + VIA_FUNC_MIDI_IRQMASK equ 0x40 ; FIXME: not documented! + VIA_FUNC_RX2C_WRITE equ 0x20 + VIA_FUNC_SB_FIFO_EMPTY equ 0x10 + VIA_FUNC_ENABLE_GAME equ 0x08 + VIA_FUNC_ENABLE_FM equ 0x04 + VIA_FUNC_ENABLE_MIDI equ 0x02 + VIA_FUNC_ENABLE_SB equ 0x01 +VIA_PNP_CONTROL equ 0x43 +VIA_FM_NMI_CTRL equ 0x48 +VIA8233_VOLCHG_CTRL equ 0x48 +VIA8233_SPDIF_CTRL equ 0x49 + VIA8233_SPDIF_DX3 equ 0x08 + VIA8233_SPDIF_SLOT_MASK equ 0x03 + VIA8233_SPDIF_SLOT_1011 equ 0x00 + VIA8233_SPDIF_SLOT_34 equ 0x01 + VIA8233_SPDIF_SLOT_78 equ 0x02 + VIA8233_SPDIF_SLOT_69 equ 0x03 +;] Asper + + +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 + +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 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 + + stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE ;remap IRQ + + 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 eax, VALID_IRQ + mov ebx, [ctrl.int_line] + mov esi, msgInvIRQ + bt eax, ebx + jnc .fail_msg + mov eax, ATTCH_IRQ + mov esi, msgAttchIRQ + bt eax, ebx + jnc .fail_msg + + stdcall AttachIntHandler, ebx, ac97_irq_VIA, 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_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_VIA + locals + status db 0 + endl + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS + call [ctrl.ctrl_read8] + test al, VIA_REG_STAT_ACTIVE + jz @f + + and al, VIA_REG_STAT_EOL or VIA_REG_STAT_FLAG or VIA_REG_STAT_STOPPED + mov byte [status], al + + mov ebx, dword [buff_list] + cmp [ctrl.user_callback], 0 + je @f + stdcall [ctrl.user_callback], ebx + @@: + mov al, byte [status] ;; ack ;; + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS + call [ctrl.ctrl_write8] + + ret +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 edi, pcmout_bdl + stosd + mov eax, 0x80004000 + stosd + + 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 + + stdcall channel_reset, VIADEV_PLAYBACK + stdcall codec_check_ready + + mov eax, pcmout_bdl + mov ebx, eax + call GetPgAddr + and ebx, 0xFFF + add eax, ebx + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR + call [ctrl.ctrl_write32] + + stdcall codec_check_ready + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_L + mov eax, 7;31 + call [ctrl.ctrl_write8] + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_R + mov eax, 7;31 + call [ctrl.ctrl_write8] + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX + mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000 + mov [ctrl.lvi_reg], 16;0xF;eax + call [ctrl.ctrl_write32] + + stdcall codec_check_ready + ret +endp + + +proc channel_reset channel:dword + mov esi, dword [channel] + mov edx, esi + add edx, VIA_REG_OFFSET_CONTROL + mov eax, VIA_REG_CTRL_PAUSE or VIA_REG_CTRL_TERMINATE or VIA_REG_CTRL_RESET + call [ctrl.ctrl_write8] + + mov edx, esi + add edx, VIA_REG_OFFSET_CONTROL + call [ctrl.ctrl_read8] + + mov eax, 50000 ; wait 50 ms + call StallExec + ; disable interrupts + mov edx, esi + add edx, VIA_REG_OFFSET_CONTROL + xor eax, eax + call [ctrl.ctrl_write8] + + ; clear interrupts + mov edx, esi + add edx, VIA_REG_OFFSET_STATUS + mov eax, 0x03 + call [ctrl.ctrl_write8] + + ;outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */ + ; mov edx, esi ;; for via686 + ; add edx, VIA_REG_OFFSET_TYPE + ; mov eax, 0x03 + ; call [ctrl.ctrl_write8] + + ;; outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR)); + ;mov edx, esi + ;add edx, VIA_REG_OFFSET_CURR_PTR + ;xor eax, eax + ;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_VIA + jne @F + mov [ctrl.vendor_ids], msg_VIA + 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, msgCtrlIsaIo + call SysMsgBoardStr + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 + call dword2str + call SysMsgBoardStr + + and eax, 0xFFC0 + mov [ctrl.ctrl_io_base], eax + +.default: + stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C + and eax, 0xFF +@@: + mov [ctrl.int_line], eax + + ;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE ;0x42 + ;mov byte [old_legacy], al + + ;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_PNP_CONTROL ;0x43 + ;mov byte [old_legacy_cfg], al + + ;mov al, VIA_FUNC_ENABLE_SB or VIA_FUNC_ENABLE_FM + ;xor al, 0xFF + ;and al, byte [old_legacy] + ;and eax, 0xFF + ;stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE, eax ;0x42 + ;mov byte [old_legacy], al + + call [ctrl.ctrl_setup] + xor eax, eax + inc eax + ret +endp + +align 4 +proc set_VIA + 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 + + +align 4 +proc init_codec + locals + counter dd ? + endl + + mov esi, msgControl + call SysMsgBoardStr + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL + and eax, 0xFF + call dword2str + call SysMsgBoardStr + + mov esi, msgStatus + call SysMsgBoardStr + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT + and eax, 0xFF + push eax + call dword2str + call SysMsgBoardStr + pop eax + + test eax, VIA_ACLINK_C00_READY + jz .ready + + call reset_codec + test eax, eax + jz .err + +.ready: + xor edx, edx ; ac_reg_0 + call [ctrl.codec_write16] + jmp .done + +.err: + xor eax, eax ; timeout error + ret + +.done: + call detect_codec + + xor eax, eax + inc eax + ret +endp + +align 4 +proc reset_codec + stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, \ + VIA_ACLINK_CTRL_ENABLE or VIA_ACLINK_CTRL_RESET or VIA_ACLINK_CTRL_SYNC + mov eax, 100000 ; wait 100 ms + call StallExec +.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 cold_reset + locals + counter dd ? + endl + + stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword 0 + + if DEBUG + mov esi, msgCold + call SysMsgBoardStr + end if + + mov eax, 100000 ; wait 100 ms ;400000 ; wait 400 ms + call StallExec + + ;; ACLink on, deassert ACLink reset, VSR, SGD data out + ;; note - FM data out has trouble with non VRA codecs !! + stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword VIA_ACLINK_CTRL_INIT + + mov [counter], 16 ; total 20*100 ms = 2s +.wait: + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT + test eax, VIA_ACLINK_C00_READY + 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 + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL + call dword2str + call SysMsgBoardStr + + mov esi, msgStatus + call SysMsgBoardStr + stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT + and eax, 0xFF + push eax + call dword2str + call SysMsgBoardStr + pop eax + + test eax, VIA_ACLINK_C00_READY ;CTRL_ST_CREADY + jz .fail + clc + ret +endp + +align 4 +play: + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX + mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000 + mov [ctrl.lvi_reg], 16 + call [ctrl.ctrl_write32] + + mov eax, VIA_REG_CTRL_INT + or eax, VIA_REG_CTRL_START + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL + call [ctrl.ctrl_write8] + + xor eax, eax + ret + +align 4 +stop: + mov eax, VIA_REG_CTRL_INT + or eax, VIA_REG_CTRL_TERMINATE + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL + call [ctrl.ctrl_write8] + + stdcall channel_reset, VIADEV_PLAYBACK + 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 ecx, [ctrl.ctrl_io_base] + mov [CTRL_INFO.irq], eax + mov [CTRL_INFO.ctrl_io_base], ecx + + xor eax, eax + ;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR + ;call [ctrl.ctrl_read32] + mov [CTRL_INFO.codec_io_base], eax + ;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX + ;call [ctrl.ctrl_read32] + mov [CTRL_INFO.codec_mem_base], eax + ;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CURR_COUNT + ;call [ctrl.ctrl_read32] + mov [CTRL_INFO.ctrl_mem_base], eax + + mov eax, [codec.chip_id] + mov [CTRL_INFO.codec_id], eax + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL + call [ctrl.ctrl_read8] + and eax, 0xFF + mov [CTRL_INFO.glob_cntrl], eax + + mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS + call [ctrl.ctrl_read8] + and eax, 0xFF + 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_check_ready stdcall + locals + counter dd ? + endl + + mov [counter], 1000 ; total 1000*1 ms = 1s +.wait: + call [ctrl.codec_read16] + test eax, VIA_REG_AC97_BUSY + jz .ok + + mov eax, 1000 ; wait 1 ms + call StallExec + + sub [counter] , 1 + jnz .wait +.err: + mov eax, -1 + ret +.ok: + and eax, 0xFFFF + ret +endp + + +align 4 +proc codec_valid stdcall + stdcall codec_check_ready + ret +endp + +align 4 +proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax + locals + counter dd ? + endl + + ;Use only primary codec. + mov eax, [ac_reg] + and eax, 0x7F + shl eax, VIA_REG_AC97_CMD_SHIFT + or eax, VIA_REG_AC97_PRIMARY_VALID or VIA_REG_AC97_READ + + mov [counter], 3 ; total 3*20 ms = 60ms +.wait: + push eax + call [ctrl.codec_write16] + + mov eax, 20000 ; wait 20 ms + call StallExec + + stdcall codec_valid, + cmp eax, 0 + pop eax + jge .ok + + sub [counter] , 1 + jnz .wait + jmp .err + +.ok: + mov eax, 25000 ; wait 25 ms + call StallExec + + call [ctrl.codec_read16] ;change edx !!! + and eax, 0xFFFF + ret +.err: + if DEBUG + mov esi, msgCInvalid + call SysMsgBoardStr + end if + mov eax, -1 ; invalid codec error + ret +endp + +align 4 +proc codec_write stdcall, ac_reg:dword + ;Use only primary codec. + mov esi, [ac_reg] + mov edx, esi + shl edx, VIA_REG_AC97_CMD_SHIFT + + shl eax, VIA_REG_AC97_DATA_SHIFT + or edx, eax + + mov eax, VIA_REG_AC97_CODEC_ID_PRIMARY ;not VIA_REG_AC97_CODEC_ID_PRIMARY + shl eax, VIA_REG_AC97_CODEC_ID_SHIFT + or edx, eax + + mov eax, edx + mov edx, esi + call [ctrl.codec_write16] + mov [codec.regs+esi], ax + + stdcall codec_check_ready + cmp eax, 0 + jl .err +.ok: + ret +.err: + if DEBUG + mov esi, msgCFail + call SysMsgBoardStr + end if + ;mov eax, -1 ; codec not ready error + 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 ;r32 + mov edx, [ctrl.ctrl_io_base] + add edx, VIA_REG_AC97 + in eax, dx + ret +endp + +align 4 +proc codec_io_w16 ;w32 + mov edx, [ctrl.ctrl_io_base] + add edx, VIA_REG_AC97 + out dx, eax + 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 + + +align 4 +dword2str: + push eax ebx ecx + 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 + pop ecx ebx eax + ret + +hexletters db '0123456789ABCDEF' +hex_buff db 8 dup(0),13,10,0 + + +include "codec.inc" + +align 4 +devices dd (CTRL_VT82C686 shl 16)+VID_VIA,msg_VT82C686,set_VIA + dd (CTRL_VT8233_5 shl 16)+VID_VIA,msg_VT8233,set_VIA + dd 0 ;terminator + + +version dd (5 shl 16) or (API_VERSION and 0xFFFF) + +msg_VT82C686 db 'VT82C686', 13,10, 0 +msg_VT8233 db 'VT8233', 13,10, 0 +msg_VIA db 'VIA' , 13,10, 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 +;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 +msgCInvalid db 'codec is not valid',13,10,0 ;Asper +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 + +chip_type rb 1 \ No newline at end of file diff --git a/kernel/branches/Kolibri-A/trunk/fs/fs_lfn.inc b/kernel/branches/Kolibri-A/trunk/fs/fs_lfn.inc index 1391030f8a..2149bb9a34 100644 --- a/kernel/branches/Kolibri-A/trunk/fs/fs_lfn.inc +++ b/kernel/branches/Kolibri-A/trunk/fs/fs_lfn.inc @@ -795,7 +795,7 @@ biosdisk_enum_root: xor eax, eax ret .big: - push ecx + push ecx edx push -'0' mov ecx, 10 @@: @@ -810,7 +810,7 @@ biosdisk_enum_root: add al, '0' stosb jnz @b - pop ecx + pop edx ecx pop eax inc eax ret diff --git a/kernel/branches/Kolibri-A/trunk/gui/event.inc b/kernel/branches/Kolibri-A/trunk/gui/event.inc index 0610cd5220..a7a0e0dd85 100644 --- a/kernel/branches/Kolibri-A/trunk/gui/event.inc +++ b/kernel/branches/Kolibri-A/trunk/gui/event.inc @@ -7,6 +7,13 @@ $Revision$ +WINDOW_MOVE_AND_RESIZE_FLAGS = \ + mouse.WINDOW_RESIZE_N_FLAG + \ + mouse.WINDOW_RESIZE_W_FLAG + \ + mouse.WINDOW_RESIZE_S_FLAG + \ + mouse.WINDOW_RESIZE_E_FLAG + \ + mouse.WINDOW_MOVE_FLAG + uglobal align 4 event_start dd ? @@ -445,7 +452,7 @@ get_event_for_app: ;; used from f10,f11,f23 xor eax,eax ret .IRQ: -;TODO: ёфхырЄ№ Єръ цх, ъръ ш фы  FlagAutoReset (BgrRedraw,Mouse,IPC,Stack,Debug) +;TODO: same thing as done for FlagAutoReset (BgrRedraw,Mouse,IPC,Stack,Debug) mov edx,[irq_owner+eax*4-64] ; eax==16+irq cmp edx,[edi+TASKDATA.pid] jne .loop @@ -460,8 +467,9 @@ get_event_for_app: ;; used from f10,f11,f23 push eax ; If the window is captured and moved by the user, then no mouse events!!! mov al, [mouse.active_sys_window.action] - test al, mouse.WINDOW_MOVE_FLAG - pop eax + and al, WINDOW_MOVE_AND_RESIZE_FLAGS + test al, al + pop eax jnz .loop @@: btr [ebx+APPDATA.event_mask],eax diff --git a/kernel/branches/Kolibri-A/trunk/gui/mouse.inc b/kernel/branches/Kolibri-A/trunk/gui/mouse.inc index deb3714977..32055cf99d 100644 --- a/kernel/branches/Kolibri-A/trunk/gui/mouse.inc +++ b/kernel/branches/Kolibri-A/trunk/gui/mouse.inc @@ -1,701 +1,701 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2010. All rights reserved. ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision: -1 $ - -include 'mousepointer.inc' - -;============================================================================== -;///// public functions /////////////////////////////////////////////////////// -;============================================================================== - -mouse.LEFT_BUTTON_FLAG = 0001b -mouse.RIGHT_BUTTON_FLAG = 0010b -mouse.MIDDLE_BUTTON_FLAG = 0100b - -mouse.BUTTONS_MASK = \ - mouse.LEFT_BUTTON_FLAG or \ - mouse.RIGHT_BUTTON_FLAG or \ - mouse.MIDDLE_BUTTON_FLAG - -mouse.WINDOW_RESIZE_N_FLAG = 000001b -mouse.WINDOW_RESIZE_W_FLAG = 000010b -mouse.WINDOW_RESIZE_S_FLAG = 000100b -mouse.WINDOW_RESIZE_E_FLAG = 001000b -mouse.WINDOW_MOVE_FLAG = 010000b - -mouse.WINDOW_RESIZE_SW_FLAG = \ - mouse.WINDOW_RESIZE_S_FLAG or \ - mouse.WINDOW_RESIZE_W_FLAG -mouse.WINDOW_RESIZE_SE_FLAG = \ - mouse.WINDOW_RESIZE_S_FLAG or \ - mouse.WINDOW_RESIZE_E_FLAG - -align 4 -;------------------------------------------------------------------------------ -mouse_check_events: ;////////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Check if mouse buttons state or cursor position has changed and call -;? appropriate handlers -;------------------------------------------------------------------------------ - push eax ebx - - mov al, [BTN_DOWN] - mov bl, [mouse.state.buttons] - and al, mouse.BUTTONS_MASK - mov cl, al - xchg cl, [mouse.state.buttons] - xor bl, al - push eax ebx - - ; did any mouse button changed its state? - or bl, bl - jz .check_position - - ; yes it did, is that the first button of all pressed down? - or cl, cl - jnz .check_buttons_released - - ; yes it is, activate window user is pointing at, if needed - call mouse._.activate_sys_window_under_cursor - - ; NOTE: this code wouldn't be necessary if we knew window did - ; already redraw itself after call above - or eax, eax - jz @f - - and [mouse.state.buttons], 0 - jmp .exit - - ; is there any system button under cursor? - @@: call mouse._.find_sys_button_under_cursor - or eax, eax - jz .check_buttons_released - - ; yes there is, activate it and exit - mov [mouse.active_sys_button.pbid], eax - mov [mouse.active_sys_button.coord], ebx - mov cl, [mouse.state.buttons] - mov [mouse.active_sys_button.buttons], cl - call sys_button_activate_handler - jmp .exit - - .check_buttons_released: - cmp [mouse.state.buttons], 0 - jnz .buttons_changed - - ; did we press some button earlier? - cmp [mouse.active_sys_button.pbid], 0 - je .buttons_changed - - ; yes we did, deactivate it - xor eax, eax - xchg eax, [mouse.active_sys_button.pbid] - mov ebx, [mouse.active_sys_button.coord] - mov cl, [mouse.active_sys_button.buttons] - push eax ebx - call sys_button_deactivate_handler - pop edx ecx - - ; is the button under cursor the one we deactivated? - call mouse._.find_sys_button_under_cursor - cmp eax, ecx - jne .exit - cmp ebx, edx - jne .exit - - ; yes it is, perform associated action - mov cl, [mouse.active_sys_button.buttons] - call sys_button_perform_handler - jmp .exit - - .buttons_changed: - test byte[esp], mouse.LEFT_BUTTON_FLAG - jz @f - mov eax, [esp + 4] - call .call_left_button_handler - - @@: test byte[esp], mouse.RIGHT_BUTTON_FLAG - jz @f - mov eax, [esp + 4] - call .call_right_button_handler - - @@: test byte[esp], mouse.MIDDLE_BUTTON_FLAG - jz .check_position - mov eax, [esp + 4] - call .call_middle_button_handler - - .check_position: - movzx eax, word[MOUSE_X] - movzx ebx, word[MOUSE_Y] - cmp eax, [mouse.state.pos.x] - jne .position_changed - cmp ebx, [mouse.state.pos.y] - je .exit - - .position_changed: - xchg eax, [mouse.state.pos.x] - xchg ebx, [mouse.state.pos.y] - - call mouse._.move_handler - - .exit: - add esp, 8 - pop ebx eax - ret - - .call_left_button_handler: - test eax, mouse.LEFT_BUTTON_FLAG - jnz mouse._.left_button_press_handler - jmp mouse._.left_button_release_handler - - .call_right_button_handler: - test eax, mouse.RIGHT_BUTTON_FLAG - jnz mouse._.right_button_press_handler - jmp mouse._.right_button_release_handler - - .call_middle_button_handler: - test eax, mouse.MIDDLE_BUTTON_FLAG - jnz mouse._.middle_button_press_handler - jmp mouse._.middle_button_release_handler - -;============================================================================== -;///// private functions ////////////////////////////////////////////////////// -;============================================================================== - -uglobal - mouse.state: - .pos POINT - .buttons db ? - - ; NOTE: since there's no unique and lifetime-constant button identifiers, - ; we're using two dwords to identify each of them: - ; * pbid - process slot (high 8 bits) and button id (low 24 bits) pack - ; * coord - left (high 16 bits) and top (low 16 bits) coordinates pack - align 4 - mouse.active_sys_button: - .pbid dd ? - .coord dd ? - .buttons db ? - - align 4 - mouse.active_sys_window: - .pslot dd ? - .old_box BOX - .new_box BOX - .delta POINT - .last_ticks dd ? - .action db ? -endg - -align 4 -;------------------------------------------------------------------------------ -mouse._.left_button_press_handler: ;/////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when left mouse button has been pressed down -;------------------------------------------------------------------------------ - test [mouse.state.buttons], not mouse.LEFT_BUTTON_FLAG - jnz .exit - - call mouse._.find_sys_window_under_cursor - call mouse._.check_sys_window_actions - mov [mouse.active_sys_window.action], al - or eax, eax - jz .exit - - xchg eax, edx - test dl, mouse.WINDOW_MOVE_FLAG - jz @f - - mov eax, [timer_ticks] - mov ebx, eax - xchg ebx, [mouse.active_sys_window.last_ticks] - sub eax, ebx - cmp eax, 50 - jg @f - - mov [mouse.active_sys_window.last_ticks], 0 - call sys_window_maximize_handler - jmp .exit - - @@: test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED - jnz .exit - mov [mouse.active_sys_window.pslot], esi - lea eax, [edi + WDATA.box] - mov ebx, mouse.active_sys_window.old_box - mov ecx, BOX.sizeof - call memmove - mov ebx, mouse.active_sys_window.new_box - call memmove - test edx, mouse.WINDOW_MOVE_FLAG - jz @f - - call .calculate_n_delta - call .calculate_w_delta - jmp .call_window_handler - - @@: test dl, mouse.WINDOW_RESIZE_W_FLAG - jz @f - call .calculate_w_delta - - @@: test dl, mouse.WINDOW_RESIZE_S_FLAG - jz @f - call .calculate_s_delta - - @@: test dl, mouse.WINDOW_RESIZE_E_FLAG - jz .call_window_handler - call .calculate_e_delta - - .call_window_handler: - mov eax, mouse.active_sys_window.old_box - call sys_window_start_moving_handler - - .exit: - ret - - .calculate_n_delta: - mov eax, [mouse.state.pos.y] - sub eax, [mouse.active_sys_window.old_box.top] - mov [mouse.active_sys_window.delta.y], eax - ret - - .calculate_w_delta: - mov eax, [mouse.state.pos.x] - sub eax, [mouse.active_sys_window.old_box.left] - mov [mouse.active_sys_window.delta.x], eax - ret - - .calculate_s_delta: - mov eax, [mouse.active_sys_window.old_box.top] - add eax, [mouse.active_sys_window.old_box.height] - sub eax, [mouse.state.pos.y] - mov [mouse.active_sys_window.delta.y], eax - ret - - .calculate_e_delta: - mov eax, [mouse.active_sys_window.old_box.left] - add eax, [mouse.active_sys_window.old_box.width] - sub eax, [mouse.state.pos.x] - mov [mouse.active_sys_window.delta.x], eax - ret - -align 4 -;------------------------------------------------------------------------------ -mouse._.left_button_release_handler: ;///////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when left mouse button has been released -;------------------------------------------------------------------------------ - xor esi, esi - xchg esi, [mouse.active_sys_window.pslot] - or esi, esi - jz .exit - - mov eax, esi - shl eax, 5 - add eax, window_data + WDATA.box - mov ebx, mouse.active_sys_window.old_box - mov ecx, BOX.sizeof - call memmove - - mov eax, mouse.active_sys_window.old_box - mov ebx, mouse.active_sys_window.new_box - call sys_window_end_moving_handler - - .exit: - ret - -align 4 -;------------------------------------------------------------------------------ -mouse._.right_button_press_handler: ;////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when right mouse button has been pressed down -;------------------------------------------------------------------------------ - test [mouse.state.buttons], not mouse.RIGHT_BUTTON_FLAG - jnz .exit - - call mouse._.find_sys_window_under_cursor - call mouse._.check_sys_window_actions - test al, mouse.WINDOW_MOVE_FLAG - jz .exit - - call sys_window_rollup_handler - - .exit: - ret - -align 4 -;------------------------------------------------------------------------------ -mouse._.right_button_release_handler: ;//////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when right mouse button has been released -;------------------------------------------------------------------------------ - ret - -align 4 -;------------------------------------------------------------------------------ -mouse._.middle_button_press_handler: ;///////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when middle mouse button has been pressed down -;------------------------------------------------------------------------------ - ret - -align 4 -;------------------------------------------------------------------------------ -mouse._.middle_button_release_handler: ;/////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when middle mouse button has been released -;------------------------------------------------------------------------------ - ret - -align 4 -;------------------------------------------------------------------------------ -mouse._.move_handler: ;//////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Called when cursor has been moved -;------------------------------------------------------------------------------ -;> eax = old x coord -;> ebx = old y coord -;------------------------------------------------------------------------------ - cmp [mouse.active_sys_button.pbid], 0 - jnz .exit - - mov esi, [mouse.active_sys_window.pslot] - or esi, esi - jz .exit - - mov eax, mouse.active_sys_window.new_box - mov ebx, mouse.active_sys_window.old_box - mov ecx, BOX.sizeof - call memmove - - mov dl, [mouse.active_sys_window.action] - test dl, mouse.WINDOW_MOVE_FLAG - jz .check_resize_w - - mov eax, [mouse.state.pos.x] - sub eax, [mouse.active_sys_window.delta.x] - mov [mouse.active_sys_window.new_box.left], eax - mov eax, [mouse.state.pos.y] - sub eax, [mouse.active_sys_window.delta.y] - mov [mouse.active_sys_window.new_box.top], eax - - mov eax, [mouse.active_sys_window.new_box.left] - or eax, eax - jge @f - xor eax, eax - mov [mouse.active_sys_window.new_box.left], eax - @@: add eax, [mouse.active_sys_window.new_box.width] - cmp eax, [Screen_Max_X] - jl @f - sub eax, [Screen_Max_X] - sub [mouse.active_sys_window.new_box.left], eax - @@: mov eax, [mouse.active_sys_window.new_box.top] - or eax, eax - jge @f - xor eax, eax - mov [mouse.active_sys_window.new_box.top], eax - @@: add eax, [mouse.active_sys_window.new_box.height] - cmp eax, [Screen_Max_Y] - jle .call_window_handler - sub eax, [Screen_Max_Y] - sub [mouse.active_sys_window.new_box.top], eax - jmp .call_window_handler - - .check_resize_w: - test dl, mouse.WINDOW_RESIZE_W_FLAG - jz .check_resize_s - - mov eax, [mouse.state.pos.x] - sub eax, [mouse.active_sys_window.delta.x] - mov [mouse.active_sys_window.new_box.left], eax - sub eax, [mouse.active_sys_window.old_box.left] - sub [mouse.active_sys_window.new_box.width], eax - - mov eax, [mouse.active_sys_window.new_box.width] - sub eax, 127 - jge @f - add [mouse.active_sys_window.new_box.left], eax - mov [mouse.active_sys_window.new_box.width], 127 - @@: mov eax, [mouse.active_sys_window.new_box.left] - or eax, eax - jge .check_resize_s - add [mouse.active_sys_window.new_box.width], eax - xor eax, eax - mov [mouse.active_sys_window.new_box.left], eax - - .check_resize_s: - test dl, mouse.WINDOW_RESIZE_S_FLAG - jz .check_resize_e - - mov eax, [mouse.state.pos.y] - add eax, [mouse.active_sys_window.delta.y] - sub eax, [mouse.active_sys_window.old_box.top] - mov [mouse.active_sys_window.new_box.height], eax - - push eax - mov edi, esi - shl edi, 5 - add edi, window_data - call window._.get_rolledup_height - mov ecx, eax - pop eax - mov eax, [mouse.active_sys_window.new_box.height] - cmp eax, ecx - jge @f - mov eax, ecx - mov [mouse.active_sys_window.new_box.height], eax - @@: add eax, [mouse.active_sys_window.new_box.top] - cmp eax, [Screen_Max_Y] - jle .check_resize_e - sub eax, [Screen_Max_Y] - neg eax - add [mouse.active_sys_window.new_box.height], eax - mov ecx, [Screen_Max_Y] - cmp ecx, eax - jge .check_resize_e - mov [mouse.active_sys_window.new_box.height], ecx - - .check_resize_e: - test dl, mouse.WINDOW_RESIZE_E_FLAG - jz .call_window_handler - - mov eax, [mouse.state.pos.x] - add eax, [mouse.active_sys_window.delta.x] - sub eax, [mouse.active_sys_window.old_box.left] - mov [mouse.active_sys_window.new_box.width], eax - - mov eax, [mouse.active_sys_window.new_box.width] - cmp eax, 127 - jge @f - mov eax, 127 - mov [mouse.active_sys_window.new_box.width], eax - @@: add eax, [mouse.active_sys_window.new_box.left] - cmp eax, [Screen_Max_X] - jle .call_window_handler - sub eax, [Screen_Max_X] - neg eax - add [mouse.active_sys_window.new_box.width], eax - mov ecx, [Screen_Max_X] - cmp ecx, eax - jge .call_window_handler - mov [mouse.active_sys_window.new_box.width], ecx - - .call_window_handler: - mov eax, mouse.active_sys_window.old_box - mov ebx, mouse.active_sys_window.new_box - - push esi - mov esi, mouse.active_sys_window.old_box - mov edi, mouse.active_sys_window.new_box - mov ecx, BOX.sizeof / 4 - repe - cmpsd - pop esi - je .exit - - mov [mouse.active_sys_window.last_ticks], 0 - call sys_window_moving_handler - - .exit: - ret - -align 4 -;------------------------------------------------------------------------------ -mouse._.find_sys_window_under_cursor: ;//////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Find system window object which is currently visible on screen and has -;? mouse cursor within its bounds -;------------------------------------------------------------------------------ -;< esi = process slot -;< edi = pointer to WDATA struct -;------------------------------------------------------------------------------ - mov esi, [Screen_Max_X] - inc esi - imul esi, [mouse.state.pos.y] - add esi, [_WinMapAddress] - add esi, [mouse.state.pos.x] - movzx esi, byte[esi] - mov edi, esi - shl edi, 5 - add edi, window_data - ret - -align 4 -;------------------------------------------------------------------------------ -mouse._.activate_sys_window_under_cursor: ;//////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - ; activate and redraw window under cursor (if necessary) - call mouse._.find_sys_window_under_cursor - movzx esi, word[WIN_STACK + esi * 2] - lea esi, [WIN_POS + esi * 2] - jmp waredraw - -align 4 -;------------------------------------------------------------------------------ -mouse._.find_sys_button_under_cursor: ;//////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Find system button object which is currently visible on screen and has -;? mouse cursor within its bounds -;------------------------------------------------------------------------------ -;< eax = pack[8(process slot), 24(button id)] or 0 -;< ebx = pack[16(button x coord), 16(button y coord)] -;------------------------------------------------------------------------------ - push ecx edx esi edi - - call mouse._.find_sys_window_under_cursor - mov edx, esi - - ; check if any process button contains cursor - mov eax, [BTN_ADDR] - mov ecx, [eax] - imul esi, ecx, SYS_BUTTON.sizeof - add esi, eax - inc ecx - add esi, SYS_BUTTON.sizeof - - .next_button: - dec ecx - jz .not_found - - add esi, -SYS_BUTTON.sizeof - - ; does it belong to our process? - cmp dx, [esi + SYS_BUTTON.pslot] - jne .next_button - - ; does it contain cursor coordinates? - mov eax, [mouse.state.pos.x] - sub eax, [edi + WDATA.box.left] - sub ax, [esi + SYS_BUTTON.left] - jl .next_button - sub ax, [esi + SYS_BUTTON.width] - jge .next_button - mov eax, [mouse.state.pos.y] - sub eax, [edi + WDATA.box.top] - sub ax, [esi + SYS_BUTTON.top] - jl .next_button - sub ax, [esi + SYS_BUTTON.height] - jge .next_button - - ; okay, return it - shl edx, 24 - mov eax, dword[esi + SYS_BUTTON.id_hi - 2] - mov ax, [esi + SYS_BUTTON.id_lo] - and eax, 0x0ffffff - or eax, edx - mov ebx, dword[esi + SYS_BUTTON.left - 2] - mov bx, [esi + SYS_BUTTON.top] - jmp .exit - - .not_found: - xor eax, eax - xor ebx, ebx - - .exit: - pop edi esi edx ecx - ret - -align 4 -;------------------------------------------------------------------------------ -mouse._.check_sys_window_actions: ;//////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;< eax = action flags or 0 -;------------------------------------------------------------------------------ - ; is window movable? - test byte[edi + WDATA.cl_titlebar + 3], 0x01 - jnz .no_action - - mov eax, [mouse.state.pos.x] - mov ebx, [mouse.state.pos.y] - sub eax, [edi + WDATA.box.left] - sub ebx, [edi + WDATA.box.top] - - ; is there a window titlebar under cursor? - push eax - call window._.get_titlebar_height - cmp ebx, eax - pop eax - jl .move_action - - ; no there isn't, can it be resized then? - mov dl, [edi + WDATA.fl_wstyle] - and dl, 0x0f - ; NOTE: dangerous optimization, revise if window types changed; - ; this currently implies only types 2 and 3 could be resized - test dl, 2 - jz .no_action - - mov ecx, [edi + WDATA.box.width] - add ecx, -window.BORDER_SIZE - mov edx, [edi + WDATA.box.height] - add edx, -window.BORDER_SIZE - - ; is it rolled up? - test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP - jnz .resize_w_or_e_action - - cmp eax, window.BORDER_SIZE - jl .resize_w_action - cmp eax, ecx - jg .resize_e_action - cmp ebx, edx - jle .no_action - - .resize_s_action: - cmp eax, window.BORDER_SIZE + 10 - jl .resize_sw_action - add ecx, -10 - cmp eax, ecx - jge .resize_se_action - mov eax, mouse.WINDOW_RESIZE_S_FLAG - jmp .exit - - .resize_w_or_e_action: - cmp eax, window.BORDER_SIZE + 10 - jl .resize_w_action.direct - add ecx, -10 - cmp eax, ecx - jg .resize_e_action.direct - jmp .no_action - - .resize_w_action: - add edx, -10 - cmp ebx, edx - jge .resize_sw_action - .resize_w_action.direct: - mov eax, mouse.WINDOW_RESIZE_W_FLAG - jmp .exit - - .resize_e_action: - add edx, -10 - cmp ebx, edx - jge .resize_se_action - .resize_e_action.direct: - mov eax, mouse.WINDOW_RESIZE_E_FLAG - jmp .exit - - .resize_sw_action: - mov eax, mouse.WINDOW_RESIZE_SW_FLAG - jmp .exit - - .resize_se_action: - mov eax, mouse.WINDOW_RESIZE_SE_FLAG - jmp .exit - - .move_action: - mov eax, mouse.WINDOW_MOVE_FLAG - jmp .exit - - .no_action: - xor eax, eax - - .exit: - ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2010. All rights reserved. ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision: 1532$ + +include 'mousepointer.inc' + +;============================================================================== +;///// public functions /////////////////////////////////////////////////////// +;============================================================================== + +mouse.LEFT_BUTTON_FLAG = 0001b +mouse.RIGHT_BUTTON_FLAG = 0010b +mouse.MIDDLE_BUTTON_FLAG = 0100b + +mouse.BUTTONS_MASK = \ + mouse.LEFT_BUTTON_FLAG or \ + mouse.RIGHT_BUTTON_FLAG or \ + mouse.MIDDLE_BUTTON_FLAG + +mouse.WINDOW_RESIZE_N_FLAG = 000001b +mouse.WINDOW_RESIZE_W_FLAG = 000010b +mouse.WINDOW_RESIZE_S_FLAG = 000100b +mouse.WINDOW_RESIZE_E_FLAG = 001000b +mouse.WINDOW_MOVE_FLAG = 010000b + +mouse.WINDOW_RESIZE_SW_FLAG = \ + mouse.WINDOW_RESIZE_S_FLAG or \ + mouse.WINDOW_RESIZE_W_FLAG +mouse.WINDOW_RESIZE_SE_FLAG = \ + mouse.WINDOW_RESIZE_S_FLAG or \ + mouse.WINDOW_RESIZE_E_FLAG + +align 4 +;------------------------------------------------------------------------------ +mouse_check_events: ;////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Check if mouse buttons state or cursor position has changed and call +;? appropriate handlers +;------------------------------------------------------------------------------ + push eax ebx + + mov al, [BTN_DOWN] + mov bl, [mouse.state.buttons] + and al, mouse.BUTTONS_MASK + mov cl, al + xchg cl, [mouse.state.buttons] + xor bl, al + push eax ebx + + ; did any mouse button changed its state? + or bl, bl + jz .check_position + + ; yes it did, is that the first button of all pressed down? + or cl, cl + jnz .check_buttons_released + + ; yes it is, activate window user is pointing at, if needed + call mouse._.activate_sys_window_under_cursor + + ; NOTE: this code wouldn't be necessary if we knew window did + ; already redraw itself after call above + or eax, eax + jz @f + + and [mouse.state.buttons], 0 + jmp .exit + + ; is there any system button under cursor? + @@: call mouse._.find_sys_button_under_cursor + or eax, eax + jz .check_buttons_released + + ; yes there is, activate it and exit + mov [mouse.active_sys_button.pbid], eax + mov [mouse.active_sys_button.coord], ebx + mov cl, [mouse.state.buttons] + mov [mouse.active_sys_button.buttons], cl + call sys_button_activate_handler + jmp .exit + + .check_buttons_released: + cmp [mouse.state.buttons], 0 + jnz .buttons_changed + + ; did we press some button earlier? + cmp [mouse.active_sys_button.pbid], 0 + je .buttons_changed + + ; yes we did, deactivate it + xor eax, eax + xchg eax, [mouse.active_sys_button.pbid] + mov ebx, [mouse.active_sys_button.coord] + mov cl, [mouse.active_sys_button.buttons] + push eax ebx + call sys_button_deactivate_handler + pop edx ecx + + ; is the button under cursor the one we deactivated? + call mouse._.find_sys_button_under_cursor + cmp eax, ecx + jne .exit + cmp ebx, edx + jne .exit + + ; yes it is, perform associated action + mov cl, [mouse.active_sys_button.buttons] + call sys_button_perform_handler + jmp .exit + + .buttons_changed: + test byte[esp], mouse.LEFT_BUTTON_FLAG + jz @f + mov eax, [esp + 4] + call .call_left_button_handler + + @@: test byte[esp], mouse.RIGHT_BUTTON_FLAG + jz @f + mov eax, [esp + 4] + call .call_right_button_handler + + @@: test byte[esp], mouse.MIDDLE_BUTTON_FLAG + jz .check_position + mov eax, [esp + 4] + call .call_middle_button_handler + + .check_position: + movzx eax, word[MOUSE_X] + movzx ebx, word[MOUSE_Y] + cmp eax, [mouse.state.pos.x] + jne .position_changed + cmp ebx, [mouse.state.pos.y] + je .exit + + .position_changed: + xchg eax, [mouse.state.pos.x] + xchg ebx, [mouse.state.pos.y] + + call mouse._.move_handler + + .exit: + add esp, 8 + pop ebx eax + ret + + .call_left_button_handler: + test eax, mouse.LEFT_BUTTON_FLAG + jnz mouse._.left_button_press_handler + jmp mouse._.left_button_release_handler + + .call_right_button_handler: + test eax, mouse.RIGHT_BUTTON_FLAG + jnz mouse._.right_button_press_handler + jmp mouse._.right_button_release_handler + + .call_middle_button_handler: + test eax, mouse.MIDDLE_BUTTON_FLAG + jnz mouse._.middle_button_press_handler + jmp mouse._.middle_button_release_handler + +;============================================================================== +;///// private functions ////////////////////////////////////////////////////// +;============================================================================== + +uglobal + mouse.state: + .pos POINT + .buttons db ? + + ; NOTE: since there's no unique and lifetime-constant button identifiers, + ; we're using two dwords to identify each of them: + ; * pbid - process slot (high 8 bits) and button id (low 24 bits) pack + ; * coord - left (high 16 bits) and top (low 16 bits) coordinates pack + align 4 + mouse.active_sys_button: + .pbid dd ? + .coord dd ? + .buttons db ? + + align 4 + mouse.active_sys_window: + .pslot dd ? + .old_box BOX + .new_box BOX + .delta POINT + .last_ticks dd ? + .action db ? +endg + +align 4 +;------------------------------------------------------------------------------ +mouse._.left_button_press_handler: ;/////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Called when left mouse button has been pressed down +;------------------------------------------------------------------------------ + test [mouse.state.buttons], not mouse.LEFT_BUTTON_FLAG + jnz .exit + + call mouse._.find_sys_window_under_cursor + call mouse._.check_sys_window_actions + mov [mouse.active_sys_window.action], al + or eax, eax + jz .exit + + xchg eax, edx + test dl, mouse.WINDOW_MOVE_FLAG + jz @f + + mov eax, [timer_ticks] + mov ebx, eax + xchg ebx, [mouse.active_sys_window.last_ticks] + sub eax, ebx + cmp eax, 50 + jg @f + + mov [mouse.active_sys_window.last_ticks], 0 + call sys_window_maximize_handler + jmp .exit + + @@: test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED + jnz .exit + mov [mouse.active_sys_window.pslot], esi + lea eax, [edi + WDATA.box] + mov ebx, mouse.active_sys_window.old_box + mov ecx, BOX.sizeof + call memmove + mov ebx, mouse.active_sys_window.new_box + call memmove + test edx, mouse.WINDOW_MOVE_FLAG + jz @f + + call .calculate_n_delta + call .calculate_w_delta + jmp .call_window_handler + + @@: test dl, mouse.WINDOW_RESIZE_W_FLAG + jz @f + call .calculate_w_delta + + @@: test dl, mouse.WINDOW_RESIZE_S_FLAG + jz @f + call .calculate_s_delta + + @@: test dl, mouse.WINDOW_RESIZE_E_FLAG + jz .call_window_handler + call .calculate_e_delta + + .call_window_handler: + mov eax, mouse.active_sys_window.old_box + call sys_window_start_moving_handler + + .exit: + ret + + .calculate_n_delta: + mov eax, [mouse.state.pos.y] + sub eax, [mouse.active_sys_window.old_box.top] + mov [mouse.active_sys_window.delta.y], eax + ret + + .calculate_w_delta: + mov eax, [mouse.state.pos.x] + sub eax, [mouse.active_sys_window.old_box.left] + mov [mouse.active_sys_window.delta.x], eax + ret + + .calculate_s_delta: + mov eax, [mouse.active_sys_window.old_box.top] + add eax, [mouse.active_sys_window.old_box.height] + sub eax, [mouse.state.pos.y] + mov [mouse.active_sys_window.delta.y], eax + ret + + .calculate_e_delta: + mov eax, [mouse.active_sys_window.old_box.left] + add eax, [mouse.active_sys_window.old_box.width] + sub eax, [mouse.state.pos.x] + mov [mouse.active_sys_window.delta.x], eax + ret + +align 4 +;------------------------------------------------------------------------------ +mouse._.left_button_release_handler: ;///////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Called when left mouse button has been released +;------------------------------------------------------------------------------ + xor esi, esi + xchg esi, [mouse.active_sys_window.pslot] + or esi, esi + jz .exit + + mov eax, esi + shl eax, 5 + add eax, window_data + WDATA.box + mov ebx, mouse.active_sys_window.old_box + mov ecx, BOX.sizeof + call memmove + + mov eax, mouse.active_sys_window.old_box + mov ebx, mouse.active_sys_window.new_box + call sys_window_end_moving_handler + + .exit: + ret + +align 4 +;------------------------------------------------------------------------------ +mouse._.right_button_press_handler: ;////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Called when right mouse button has been pressed down +;------------------------------------------------------------------------------ + test [mouse.state.buttons], not mouse.RIGHT_BUTTON_FLAG + jnz .exit + + call mouse._.find_sys_window_under_cursor + call mouse._.check_sys_window_actions + test al, mouse.WINDOW_MOVE_FLAG + jz .exit + + call sys_window_rollup_handler + + .exit: + ret + +align 4 +;------------------------------------------------------------------------------ +mouse._.right_button_release_handler: ;//////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Called when right mouse button has been released +;------------------------------------------------------------------------------ + ret + +align 4 +;------------------------------------------------------------------------------ +mouse._.middle_button_press_handler: ;///////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Called when middle mouse button has been pressed down +;------------------------------------------------------------------------------ + ret + +align 4 +;------------------------------------------------------------------------------ +mouse._.middle_button_release_handler: ;/////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Called when middle mouse button has been released +;------------------------------------------------------------------------------ + ret + +align 4 +;------------------------------------------------------------------------------ +mouse._.move_handler: ;//////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Called when cursor has been moved +;------------------------------------------------------------------------------ +;> eax = old x coord +;> ebx = old y coord +;------------------------------------------------------------------------------ + cmp [mouse.active_sys_button.pbid], 0 + jnz .exit + + mov esi, [mouse.active_sys_window.pslot] + or esi, esi + jz .exit + + mov eax, mouse.active_sys_window.new_box + mov ebx, mouse.active_sys_window.old_box + mov ecx, BOX.sizeof + call memmove + + mov dl, [mouse.active_sys_window.action] + test dl, mouse.WINDOW_MOVE_FLAG + jz .check_resize_w + + mov eax, [mouse.state.pos.x] + sub eax, [mouse.active_sys_window.delta.x] + mov [mouse.active_sys_window.new_box.left], eax + mov eax, [mouse.state.pos.y] + sub eax, [mouse.active_sys_window.delta.y] + mov [mouse.active_sys_window.new_box.top], eax + + mov eax, [mouse.active_sys_window.new_box.left] + or eax, eax + jge @f + xor eax, eax + mov [mouse.active_sys_window.new_box.left], eax + @@: add eax, [mouse.active_sys_window.new_box.width] + cmp eax, [Screen_Max_X] + jl @f + sub eax, [Screen_Max_X] + sub [mouse.active_sys_window.new_box.left], eax + @@: mov eax, [mouse.active_sys_window.new_box.top] + or eax, eax + jge @f + xor eax, eax + mov [mouse.active_sys_window.new_box.top], eax + @@: add eax, [mouse.active_sys_window.new_box.height] + cmp eax, [Screen_Max_Y] + jle .call_window_handler + sub eax, [Screen_Max_Y] + sub [mouse.active_sys_window.new_box.top], eax + jmp .call_window_handler + + .check_resize_w: + test dl, mouse.WINDOW_RESIZE_W_FLAG + jz .check_resize_s + + mov eax, [mouse.state.pos.x] + sub eax, [mouse.active_sys_window.delta.x] + mov [mouse.active_sys_window.new_box.left], eax + sub eax, [mouse.active_sys_window.old_box.left] + sub [mouse.active_sys_window.new_box.width], eax + + mov eax, [mouse.active_sys_window.new_box.width] + sub eax, 127 + jge @f + add [mouse.active_sys_window.new_box.left], eax + mov [mouse.active_sys_window.new_box.width], 127 + @@: mov eax, [mouse.active_sys_window.new_box.left] + or eax, eax + jge .check_resize_s + add [mouse.active_sys_window.new_box.width], eax + xor eax, eax + mov [mouse.active_sys_window.new_box.left], eax + + .check_resize_s: + test dl, mouse.WINDOW_RESIZE_S_FLAG + jz .check_resize_e + + mov eax, [mouse.state.pos.y] + add eax, [mouse.active_sys_window.delta.y] + sub eax, [mouse.active_sys_window.old_box.top] + mov [mouse.active_sys_window.new_box.height], eax + + push eax + mov edi, esi + shl edi, 5 + add edi, window_data + call window._.get_rolledup_height + mov ecx, eax + pop eax + mov eax, [mouse.active_sys_window.new_box.height] + cmp eax, ecx + jge @f + mov eax, ecx + mov [mouse.active_sys_window.new_box.height], eax + @@: add eax, [mouse.active_sys_window.new_box.top] + cmp eax, [Screen_Max_Y] + jle .check_resize_e + sub eax, [Screen_Max_Y] + neg eax + add [mouse.active_sys_window.new_box.height], eax + mov ecx, [Screen_Max_Y] + cmp ecx, eax + jge .check_resize_e + mov [mouse.active_sys_window.new_box.height], ecx + + .check_resize_e: + test dl, mouse.WINDOW_RESIZE_E_FLAG + jz .call_window_handler + + mov eax, [mouse.state.pos.x] + add eax, [mouse.active_sys_window.delta.x] + sub eax, [mouse.active_sys_window.old_box.left] + mov [mouse.active_sys_window.new_box.width], eax + + mov eax, [mouse.active_sys_window.new_box.width] + cmp eax, 127 + jge @f + mov eax, 127 + mov [mouse.active_sys_window.new_box.width], eax + @@: add eax, [mouse.active_sys_window.new_box.left] + cmp eax, [Screen_Max_X] + jle .call_window_handler + sub eax, [Screen_Max_X] + neg eax + add [mouse.active_sys_window.new_box.width], eax + mov ecx, [Screen_Max_X] + cmp ecx, eax + jge .call_window_handler + mov [mouse.active_sys_window.new_box.width], ecx + + .call_window_handler: + mov eax, mouse.active_sys_window.old_box + mov ebx, mouse.active_sys_window.new_box + + push esi + mov esi, mouse.active_sys_window.old_box + mov edi, mouse.active_sys_window.new_box + mov ecx, BOX.sizeof / 4 + repe + cmpsd + pop esi + je .exit + + mov [mouse.active_sys_window.last_ticks], 0 + call sys_window_moving_handler + + .exit: + ret + +align 4 +;------------------------------------------------------------------------------ +mouse._.find_sys_window_under_cursor: ;//////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Find system window object which is currently visible on screen and has +;? mouse cursor within its bounds +;------------------------------------------------------------------------------ +;< esi = process slot +;< edi = pointer to WDATA struct +;------------------------------------------------------------------------------ + mov esi, [Screen_Max_X] + inc esi + imul esi, [mouse.state.pos.y] + add esi, [_WinMapAddress] + add esi, [mouse.state.pos.x] + movzx esi, byte[esi] + mov edi, esi + shl edi, 5 + add edi, window_data + ret + +align 4 +;------------------------------------------------------------------------------ +mouse._.activate_sys_window_under_cursor: ;//////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + ; activate and redraw window under cursor (if necessary) + call mouse._.find_sys_window_under_cursor + movzx esi, word[WIN_STACK + esi * 2] + lea esi, [WIN_POS + esi * 2] + jmp waredraw + +align 4 +;------------------------------------------------------------------------------ +mouse._.find_sys_button_under_cursor: ;//////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Find system button object which is currently visible on screen and has +;? mouse cursor within its bounds +;------------------------------------------------------------------------------ +;< eax = pack[8(process slot), 24(button id)] or 0 +;< ebx = pack[16(button x coord), 16(button y coord)] +;------------------------------------------------------------------------------ + push ecx edx esi edi + + call mouse._.find_sys_window_under_cursor + mov edx, esi + + ; check if any process button contains cursor + mov eax, [BTN_ADDR] + mov ecx, [eax] + imul esi, ecx, SYS_BUTTON.sizeof + add esi, eax + inc ecx + add esi, SYS_BUTTON.sizeof + + .next_button: + dec ecx + jz .not_found + + add esi, -SYS_BUTTON.sizeof + + ; does it belong to our process? + cmp dx, [esi + SYS_BUTTON.pslot] + jne .next_button + + ; does it contain cursor coordinates? + mov eax, [mouse.state.pos.x] + sub eax, [edi + WDATA.box.left] + sub ax, [esi + SYS_BUTTON.left] + jl .next_button + sub ax, [esi + SYS_BUTTON.width] + jge .next_button + mov eax, [mouse.state.pos.y] + sub eax, [edi + WDATA.box.top] + sub ax, [esi + SYS_BUTTON.top] + jl .next_button + sub ax, [esi + SYS_BUTTON.height] + jge .next_button + + ; okay, return it + shl edx, 24 + mov eax, dword[esi + SYS_BUTTON.id_hi - 2] + mov ax, [esi + SYS_BUTTON.id_lo] + and eax, 0x0ffffff + or eax, edx + mov ebx, dword[esi + SYS_BUTTON.left - 2] + mov bx, [esi + SYS_BUTTON.top] + jmp .exit + + .not_found: + xor eax, eax + xor ebx, ebx + + .exit: + pop edi esi edx ecx + ret + +align 4 +;------------------------------------------------------------------------------ +mouse._.check_sys_window_actions: ;//////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;< eax = action flags or 0 +;------------------------------------------------------------------------------ + ; is window movable? + test byte[edi + WDATA.cl_titlebar + 3], 0x01 + jnz .no_action + + mov eax, [mouse.state.pos.x] + mov ebx, [mouse.state.pos.y] + sub eax, [edi + WDATA.box.left] + sub ebx, [edi + WDATA.box.top] + + ; is there a window titlebar under cursor? + push eax + call window._.get_titlebar_height + cmp ebx, eax + pop eax + jl .move_action + + ; no there isn't, can it be resized then? + mov dl, [edi + WDATA.fl_wstyle] + and dl, 0x0f + ; NOTE: dangerous optimization, revise if window types changed; + ; this currently implies only types 2 and 3 could be resized + test dl, 2 + jz .no_action + + mov ecx, [edi + WDATA.box.width] + add ecx, -window.BORDER_SIZE + mov edx, [edi + WDATA.box.height] + add edx, -window.BORDER_SIZE + + ; is it rolled up? + test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP + jnz .resize_w_or_e_action + + cmp eax, window.BORDER_SIZE + jl .resize_w_action + cmp eax, ecx + jg .resize_e_action + cmp ebx, edx + jle .no_action + + .resize_s_action: + cmp eax, window.BORDER_SIZE + 10 + jl .resize_sw_action + add ecx, -10 + cmp eax, ecx + jge .resize_se_action + mov eax, mouse.WINDOW_RESIZE_S_FLAG + jmp .exit + + .resize_w_or_e_action: + cmp eax, window.BORDER_SIZE + 10 + jl .resize_w_action.direct + add ecx, -10 + cmp eax, ecx + jg .resize_e_action.direct + jmp .no_action + + .resize_w_action: + add edx, -10 + cmp ebx, edx + jge .resize_sw_action + .resize_w_action.direct: + mov eax, mouse.WINDOW_RESIZE_W_FLAG + jmp .exit + + .resize_e_action: + add edx, -10 + cmp ebx, edx + jge .resize_se_action + .resize_e_action.direct: + mov eax, mouse.WINDOW_RESIZE_E_FLAG + jmp .exit + + .resize_sw_action: + mov eax, mouse.WINDOW_RESIZE_SW_FLAG + jmp .exit + + .resize_se_action: + mov eax, mouse.WINDOW_RESIZE_SE_FLAG + jmp .exit + + .move_action: + mov eax, mouse.WINDOW_MOVE_FLAG + jmp .exit + + .no_action: + xor eax, eax + + .exit: + ret diff --git a/kernel/branches/Kolibri-A/trunk/gui/window.inc b/kernel/branches/Kolibri-A/trunk/gui/window.inc index 7194f2e8a5..ebf199d8ce 100644 --- a/kernel/branches/Kolibri-A/trunk/gui/window.inc +++ b/kernel/branches/Kolibri-A/trunk/gui/window.inc @@ -1,2077 +1,2085 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; -;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - -;============================================================================== -;///// public functions /////////////////////////////////////////////////////// -;============================================================================== - -window.BORDER_SIZE = 5 - -macro FuncTable name, table_name, [label] -{ - common - align 4 - \label name#.#table_name dword - forward - dd name#.#label - common - name#.sizeof.#table_name = $ - name#.#table_name -} - -uglobal - common_colours rd 32 - draw_limits RECT -endg - -align 4 -;------------------------------------------------------------------------------ -syscall_draw_window: ;///// system function 0 ///////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - mov eax, edx - shr eax, 24 - and al, 0x0f - cmp al, 5 - jae .exit - - push eax - inc [mouse_pause] - call [_display.disable_mouse] - call window._.sys_set_window - call [_display.disable_mouse] - pop eax - - or al, al - jnz @f - - ; type I - original style - call drawwindow_I - jmp window._.draw_window_caption.2 - - @@: dec al - jnz @f - - ; type II - only reserve area, no draw - call sys_window_mouse - dec [mouse_pause] - call [draw_pointer] - jmp .exit - - @@: dec al - jnz @f - - ; type III - new style - call drawwindow_III - jmp window._.draw_window_caption.2 - - ; type IV & V - skinned window (resizable & not) - @@: mov eax, [TASK_COUNT] - movzx eax, word[WIN_POS + eax * 2] - cmp eax, [CURRENT_TASK] - setz al - movzx eax, al - push eax - call drawwindow_IV - jmp window._.draw_window_caption.2 - - .exit: - ret - -align 4 -;------------------------------------------------------------------------------ -syscall_display_settings: ;///// system function 48 /////////////////////////// -;------------------------------------------------------------------------------ -;; Redraw screen: -;< ebx = 0 -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;; Set button style: -;< ebx = 1 -;< ecx = 0 (flat) or 1 (with gradient) -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;; Set system color palette: -;< ebx = 2 -;< ecx = pointer to color table -;< edx = size of color table -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;; Get system color palette: -;< ebx = 3 -;< ecx = pointer to color table buffer -;< edx = size of color table buffer -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;; Get skinned caption height: -;< ebx = 4 -;> eax = height in pixels -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;; Get screen working area: -;< ebx = 5 -;> eax = pack[16(left), 16(right)] -;> ebx = pack[16(top), 16(bottom)] -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;; Set screen working area: -;< ebx = 6 -;< ecx = pack[16(left), 16(right)] -;< edx = pack[16(top), 16(bottom)] -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;; Get skin margins: -;< ebx = 7 -;> eax = pack[16(left), 16(right)] -;> ebx = pack[16(top), 16(bottom)] -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;; Set skin: -;< ebx = 8 -;< ecx = pointer to FileInfoBlock struct -;> eax = FS error code -;------------------------------------------------------------------------------ - cmp ebx, .sizeof.ftable / 4 - ja @f - jmp [.ftable + ebx * 4] - @@: ret - - -align 4 -syscall_display_settings.00: - xor eax, eax - inc ebx - cmp [windowtypechanged], ebx - jne .exit - mov [windowtypechanged], eax - - jmp syscall_display_settings._.redraw_whole_screen - - .exit: - ret - -align 4 -syscall_display_settings.01: - and ecx, 1 - cmp ecx, [buttontype] - je .exit - mov [buttontype], ecx - mov [windowtypechanged], ebx - - .exit: - ret - -align 4 -syscall_display_settings.02: - dec ebx - mov esi, ecx - and edx, 127 - mov edi, common_colours - mov ecx, edx - rep movsb - mov [windowtypechanged], ebx - ret - -align 4 -syscall_display_settings.03: - mov edi, ecx - and edx, 127 - mov esi, common_colours - mov ecx, edx - rep movsb - ret - -align 4 -syscall_display_settings.04: - mov eax, [_skinh] - mov [esp + 32], eax - ret - -align 4 -syscall_display_settings.05: - mov eax, [screen_workarea.left - 2] - mov ax, word[screen_workarea.right] - mov [esp + 32], eax - mov eax, [screen_workarea.top - 2] - mov ax, word[screen_workarea.bottom] - mov [esp + 20], eax - ret - -align 4 -syscall_display_settings.06: - xor esi, esi - - mov edi, [Screen_Max_X] - mov eax, ecx - movsx ebx, ax - sar eax, 16 - cmp eax, ebx - jge .check_horizontal - inc esi - or eax, eax - jge @f - xor eax, eax - @@: mov [screen_workarea.left], eax - cmp ebx, edi - jle @f - mov ebx, edi - @@: mov [screen_workarea.right], ebx - - .check_horizontal: - mov edi, [Screen_Max_Y] - mov eax, edx - movsx ebx, ax - sar eax, 16 - cmp eax, ebx - jge .check_if_redraw_needed - inc esi - or eax, eax - jge @f - xor eax, eax - @@: mov [screen_workarea.top], eax - cmp ebx, edi - jle @f - mov ebx, edi - @@: mov [screen_workarea.bottom], ebx - - .check_if_redraw_needed: - or esi, esi - jz .exit - - call repos_windows - jmp syscall_display_settings._.calculate_whole_screen - - .exit: - ret - -align 4 -syscall_display_settings.07: - mov eax, [_skinmargins + 0] - mov [esp + 32], eax - mov eax, [_skinmargins + 4] - mov [esp + 20], eax - ret - -align 4 -syscall_display_settings.08: - mov ebx, ecx - call read_skin_file - mov [esp + 32], eax - test eax, eax - jnz .exit - - call syscall_display_settings._.calculate_whole_screen - jmp syscall_display_settings._.redraw_whole_screen - - .exit: - ret - -syscall_display_settings._.calculate_whole_screen: - xor eax, eax - xor ebx, ebx - mov ecx, [Screen_Max_X] - mov edx, [Screen_Max_Y] - jmp calculatescreen - -syscall_display_settings._.redraw_whole_screen: - xor eax, eax - mov [draw_limits.left], eax - mov [draw_limits.top], eax - mov eax, [Screen_Max_X] - mov [draw_limits.right], eax - mov eax, [Screen_Max_Y] - mov [draw_limits.bottom], eax - mov eax, window_data - jmp redrawscreen - -align 4 -;------------------------------------------------------------------------------ -syscall_set_window_shape: ;///// system function 50 /////////////////////////// -;------------------------------------------------------------------------------ -;; Set window shape address: -;> ebx = 0 -;> ecx = shape data address -; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;; Set window shape scale: -;> ebx = 1 -;> ecx = scale power (resulting scale is 2^ebx) -;------------------------------------------------------------------------------ - mov edi, [current_slot] - - test ebx, ebx - jne .shape_scale - mov [edi + APPDATA.wnd_shape], ecx - - .shape_scale: - dec ebx - jnz .exit - mov [edi + APPDATA.wnd_shape_scale], ecx - - .exit: - ret - -align 4 -;------------------------------------------------------------------------------ -syscall_move_window: ;///// system function 67 //////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - mov edi, [CURRENT_TASK] - shl edi, 5 - add edi, window_data - - test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED - jnz .exit - - cmp ebx, -1 - jne @f - mov ebx, [edi + WDATA.box.left] - @@: cmp ecx, -1 - jne @f - mov ecx, [edi + WDATA.box.top] - @@: cmp edx, -1 - jne @f - mov edx, [edi + WDATA.box.width] - @@: cmp esi, -1 - jne @f - mov esi, [edi + WDATA.box.height] - - @@: push esi edx ecx ebx - mov eax, esp - mov bl, [edi + WDATA.fl_wstate] - call window._.set_window_box - add esp, BOX.sizeof - - ; NOTE: do we really need this? to be reworked -; mov byte[DONT_DRAW_MOUSE], 0 ; mouse pointer -; mov byte[MOUSE_BACKGROUND], 0 ; no mouse under -; mov byte[MOUSE_DOWN], 0 ; react to mouse up/down - - ; NOTE: do we really need this? to be reworked -; call [draw_pointer] - - .exit: - ret - -align 4 -;------------------------------------------------------------------------------ -syscall_window_settings: ;///// system function 71 ///////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - dec ebx ; subfunction #1 - set window caption - jnz .exit_fail - - ; NOTE: only window owner thread can set its caption, - ; so there's no parameter for PID/TID - - mov edi, [CURRENT_TASK] - shl edi, 5 - - mov [edi * 8 + SLOT_BASE + APPDATA.wnd_caption], ecx - or [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION - - call window._.draw_window_caption - - xor eax, eax ; eax = 0 (success) - ret - -; .get_window_caption: -; dec eax ; subfunction #2 - get window caption -; jnz .exit_fail - - ; not implemented yet - - .exit_fail: - xor eax, eax - inc eax ; eax = 1 (fail) - ret - -align 4 -;------------------------------------------------------------------------------ -set_window_defaults: ;///////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - push eax ecx - xor eax, eax - mov ecx, WIN_STACK - @@: inc eax - add ecx, 2 - ; process no - mov [ecx + 0x000], ax - ; positions in stack - mov [ecx + 0x400], ax - cmp ecx, WIN_POS - 2 - jne @b - pop ecx eax - ret - -align 4 -;------------------------------------------------------------------------------ -calculatescreen: ;///////////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Scan all windows from bottom to top, calling `setscreen` for each one -;? intersecting given screen area -;------------------------------------------------------------------------------ -;> eax = left -;> ebx = top -;> ecx = right -;> edx = bottom -;------------------------------------------------------------------------------ - push esi - pushfd - cli - - mov esi, 1 - call window._.set_screen - - push ebp - - mov ebp, [TASK_COUNT] - cmp ebp, 1 - jbe .exit - - push edx ecx ebx eax - - .next_window: - movzx edi, word[WIN_POS + esi * 2] - shl edi, 5 - - cmp [CURRENT_TASK + edi + TASKDATA.state], TSTATE_FREE - je .skip_window - - add edi, window_data - test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED - jnz .skip_window - - mov eax, [edi + WDATA.box.left] - cmp eax, [esp + RECT.right] - jg .skip_window - mov ebx, [edi + WDATA.box.top] - cmp ebx, [esp + RECT.bottom] - jg .skip_window - mov ecx, [edi + WDATA.box.width] - add ecx, eax - cmp ecx, [esp + RECT.left] - jl .skip_window - mov edx, [edi + WDATA.box.height] - add edx, ebx - cmp edx, [esp + RECT.top] - jl .skip_window - - cmp eax, [esp + RECT.left] - jae @f - mov eax, [esp + RECT.left] - @@: cmp ebx, [esp + RECT.top] - jae @f - mov ebx, [esp + RECT.top] - @@: cmp ecx, [esp + RECT.right] - jbe @f - mov ecx, [esp + RECT.right] - @@: cmp edx, [esp + RECT.bottom] - jbe @f - mov edx, [esp + RECT.bottom] - - @@: push esi - movzx esi, word[WIN_POS + esi * 2] - call window._.set_screen - pop esi - - .skip_window: - inc esi - dec ebp - jnz .next_window - - pop eax ebx ecx edx - - .exit: - pop ebp - popfd - pop esi - ret - -align 4 -;------------------------------------------------------------------------------ -repos_windows: ;/////////////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - mov ecx, [TASK_COUNT] - mov edi, window_data + WDATA.sizeof * 2 - call force_redraw_background - dec ecx - jle .exit - - .next_window: - mov [edi + WDATA.fl_redraw], 1 - test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED - jnz .fix_maximized - - mov eax, [edi + WDATA.box.left] - add eax, [edi + WDATA.box.width] - mov ebx, [Screen_Max_X] - cmp eax, ebx - jle .fix_vertical - mov eax, [edi + WDATA.box.width] - sub eax, ebx - jle @f - mov [edi + WDATA.box.width], ebx - @@: sub ebx, [edi + WDATA.box.width] - mov [edi + WDATA.box.left], ebx - - .fix_vertical: - mov eax, [edi + WDATA.box.top] - add eax, [edi + WDATA.box.height] - mov ebx, [Screen_Max_Y] - cmp eax, ebx - jle .fix_client_box - mov eax, [edi + WDATA.box.height] - sub eax, ebx - jle @f - mov [edi + WDATA.box.height], ebx - @@: sub ebx, [edi + WDATA.box.height] - mov [edi + WDATA.box.top], ebx - jmp .fix_client_box - - .fix_maximized: - mov eax, [screen_workarea.left] - mov [edi + WDATA.box.left], eax - sub eax, [screen_workarea.right] - neg eax - mov [edi + WDATA.box.width], eax - mov eax, [screen_workarea.top] - mov [edi + WDATA.box.top], eax - test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP - jnz .fix_client_box - sub eax, [screen_workarea.bottom] - neg eax - mov [edi + WDATA.box.height], eax - - .fix_client_box: - call window._.set_window_clientbox - - add edi, WDATA.sizeof - loop .next_window - - .exit: - ret - -align 4 -;------------------------------------------------------------------------------ -sys_window_mouse: ;//////////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - ; NOTE: commented out since doesn't provide necessary functionality - ; anyway, to be reworked -; push eax -; -; mov eax, [timer_ticks] -; cmp [new_window_starting], eax -; jb .exit -; -; mov byte[MOUSE_BACKGROUND], 0 -; mov byte[DONT_DRAW_MOUSE], 0 -; -; mov [new_window_starting], eax -; -; .exit: -; pop eax - ret - -align 4 -;------------------------------------------------------------------------------ -draw_rectangle: ;////////////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;> eax = pack[16(left), 16(right)] -;> ebx = pack[16(top), 16(bottom)] -;> esi = color -;------------------------------------------------------------------------------ - push eax ebx ecx edi - - xor edi, edi - - .flags_set: - push ebx - - ; set line color - mov ecx, esi - - ; draw top border - rol ebx, 16 - push ebx - rol ebx, 16 - pop bx - call [draw_line] - - ; draw bottom border - mov ebx, [esp - 2] - pop bx - call [draw_line] - - pop ebx - add ebx, 1 * 65536 - 1 - - ; draw left border - rol eax, 16 - push eax - rol eax, 16 - pop ax - call [draw_line] - - ; draw right border - mov eax, [esp - 2] - pop ax - call [draw_line] - - pop edi ecx ebx eax - ret - - .forced: - push eax ebx ecx edi - xor edi, edi - inc edi - jmp .flags_set - -align 4 -;------------------------------------------------------------------------------ -drawwindow_I_caption: ;//////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - push [edx + WDATA.cl_titlebar] - mov esi, edx - - mov edx, [esi + WDATA.box.top] - mov eax, edx - lea ebx, [edx + 21] - inc edx - add eax, [esi + WDATA.box.height] - - cmp ebx, eax - jbe @f - mov ebx, eax - @@: push ebx - - xor edi, edi - - .next_line: - mov ebx, edx - shl ebx, 16 - add ebx, edx - mov eax, [esi + WDATA.box.left] - inc eax - shl eax, 16 - add eax, [esi + WDATA.box.left] - add eax, [esi + WDATA.box.width] - dec eax - mov ecx, [esi + WDATA.cl_titlebar] - test ecx, 0x80000000 - jz @f - sub ecx, 0x00040404 - mov [esi + WDATA.cl_titlebar], ecx - @@: and ecx, 0x00ffffff - call [draw_line] - inc edx - cmp edx, [esp] - jb .next_line - - add esp, 4 - pop [esi + WDATA.cl_titlebar] - ret - -align 4 -;------------------------------------------------------------------------------ -drawwindow_I: ;//////////////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - pushad - - ; window border - - mov eax, [edx + WDATA.box.left - 2] - mov ax, word[edx + WDATA.box.left] - add ax, word[edx + WDATA.box.width] - mov ebx, [edx + WDATA.box.top - 2] - mov bx, word[edx + WDATA.box.top] - add bx, word[edx + WDATA.box.height] - - mov esi, [edx + WDATA.cl_frames] - call draw_rectangle - - ; window caption - - call drawwindow_I_caption - - ; window client area - - ; do we need to draw it? - mov edi, [esi + WDATA.cl_workarea] - test edi, 0x40000000 - jnz .exit - - ; does client area have a positive size on screen? - mov edx, [esi + WDATA.box.top] - add edx, 21 + 5 - mov ebx, [esi + WDATA.box.top] - add ebx, [esi + WDATA.box.height] - cmp edx, ebx - jg .exit - - ; okay, let's draw it - mov eax, 1 - mov ebx, 21 - mov ecx, [esi + WDATA.box.width] - mov edx, [esi + WDATA.box.height] - call [drawbar] - - .exit: - popad - ret - -align 4 -;------------------------------------------------------------------------------ -drawwindow_III_caption: ;///////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - mov ecx, [edx + WDATA.cl_titlebar] - push ecx - mov esi, edx - mov edx, [esi + WDATA.box.top] - add edx, 4 - mov ebx, [esi + WDATA.box.top] - add ebx, 20 - mov eax, [esi + WDATA.box.top] - add eax, [esi + WDATA.box.height] - - cmp ebx, eax - jb @f - mov ebx, eax - @@: push ebx - - xor edi, edi - - .next_line: - mov ebx, edx - shl ebx, 16 - add ebx, edx - mov eax, [esi + WDATA.box.left] - shl eax, 16 - add eax, [esi + WDATA.box.left] - add eax, [esi + WDATA.box.width] - add eax, 4 * 65536 - 4 - mov ecx, [esi + WDATA.cl_titlebar] - test ecx, 0x40000000 - jz @f - add ecx, 0x00040404 - @@: test ecx, 0x80000000 - jz @f - sub ecx, 0x00040404 - @@: mov [esi + WDATA.cl_titlebar], ecx - and ecx, 0x00ffffff - call [draw_line] - inc edx - cmp edx, [esp] - jb .next_line - - add esp, 4 - pop [esi + WDATA.cl_titlebar] - ret - -align 4 -;------------------------------------------------------------------------------ -drawwindow_III: ;////////////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - pushad - - ; window border - - mov eax, [edx + WDATA.box.left - 2] - mov ax, word[edx + WDATA.box.left] - add ax, word[edx + WDATA.box.width] - mov ebx, [edx + WDATA.box.top - 2] - mov bx, word[edx + WDATA.box.top] - add bx, word[edx + WDATA.box.height] - - mov esi, [edx + WDATA.cl_frames] - shr esi, 1 - and esi, 0x007f7f7f - call draw_rectangle - - push esi - mov ecx, 3 - mov esi, [edx + WDATA.cl_frames] - - .next_frame: - add eax, 1 * 65536 - 1 - add ebx, 1 * 65536 - 1 - call draw_rectangle - dec ecx - jnz .next_frame - - pop esi - add eax, 1 * 65536 - 1 - add ebx, 1 * 65536 - 1 - call draw_rectangle - - ; window caption - - call drawwindow_III_caption - - ; window client area - - ; do we need to draw it? - mov edi, [esi + WDATA.cl_workarea] - test edi, 0x40000000 - jnz .exit - - ; does client area have a positive size on screen? - mov edx, [esi + WDATA.box.top] - add edx, 21 + 5 - mov ebx, [esi + WDATA.box.top] - add ebx, [esi + WDATA.box.height] - cmp edx, ebx - jg .exit - - ; okay, let's draw it - mov eax, 5 - mov ebx, 20 - mov ecx, [esi + WDATA.box.width] - mov edx, [esi + WDATA.box.height] - sub ecx, 4 - sub edx, 4 - call [drawbar] - - .exit: - popad - ret - -align 4 -;------------------------------------------------------------------------------ -waredraw: ;//////////////////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Activate window, redrawing if necessary -;------------------------------------------------------------------------------ - push -1 - mov eax, [TASK_COUNT] - lea eax, [WIN_POS + eax * 2] - cmp eax, esi - pop eax - je .exit - - ; is it overlapped by another window now? - push ecx - call window._.check_window_draw - test ecx, ecx - pop ecx - jz .do_not_draw - - ; yes it is, activate and update screen buffer - mov byte[MOUSE_DOWN], 1 - call window._.window_activate - - pushad - mov edi, [TASK_COUNT] - movzx esi, word[WIN_POS + edi * 2] - shl esi, 5 - add esi, window_data - - mov eax, [esi + WDATA.box.left] - mov ebx, [esi + WDATA.box.top] - mov ecx, [esi + WDATA.box.width] - mov edx, [esi + WDATA.box.height] - - add ecx, eax - add edx, ebx - - mov edi, [TASK_COUNT] - movzx esi, word[WIN_POS + edi * 2] - call window._.set_screen - popad - - ; tell application to redraw itself - mov [edi + WDATA.fl_redraw], 1 - xor eax, eax - jmp .exit - - .do_not_draw: - ; no it's not, just activate the window - call window._.window_activate - xor eax, eax - mov byte[MOUSE_BACKGROUND], al - mov byte[DONT_DRAW_MOUSE], al - - - .exit: - mov byte[MOUSE_DOWN], 0 - inc eax - ret - -align 4 -;------------------------------------------------------------------------------ -minimize_window: ;///////////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;> eax = window number on screen -;------------------------------------------------------------------------------ -;# corrupts [dl*] -;------------------------------------------------------------------------------ - push edi - pushfd - cli - - ; is it already minimized? - movzx edi, word[WIN_POS + eax * 2] - shl edi, 5 - add edi, window_data - test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED - jnz .exit - - push eax ebx ecx edx esi - - ; no it's not, let's do that - or [edi + WDATA.fl_wstate], WSTATE_MINIMIZED - mov eax, [edi + WDATA.box.left] - mov [draw_limits.left], eax - mov ecx, eax - add ecx, [edi + WDATA.box.width] - mov [draw_limits.right], ecx - mov ebx, [edi + WDATA.box.top] - mov [draw_limits.top], ebx - mov edx, ebx - add edx, [edi + WDATA.box.height] - mov [draw_limits.bottom], edx - call calculatescreen - xor esi, esi - xor eax, eax - call redrawscreen - - pop esi edx ecx ebx eax - - .exit: - popfd - pop edi - ret - -align 4 -;------------------------------------------------------------------------------ -restore_minimized_window: ;//////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;> eax = window number on screen -;------------------------------------------------------------------------------ -;# corrupts [dl*] -;------------------------------------------------------------------------------ - pushad - pushfd - cli - - ; is it already restored? - movzx esi, word[WIN_POS + eax * 2] - mov edi, esi - shl edi, 5 - add edi, window_data - test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED - jz .exit - - ; no it's not, let's do that - mov [edi + WDATA.fl_redraw], 1 - and [edi + WDATA.fl_wstate], not WSTATE_MINIMIZED - mov ebp, window._.set_screen - cmp eax, [TASK_COUNT] - jz @f - mov ebp, calculatescreen - @@: mov eax, [edi + WDATA.box.left] - mov ebx, [edi + WDATA.box.top] - mov ecx, [edi + WDATA.box.width] - mov edx, [edi + WDATA.box.height] - add ecx, eax - add edx, ebx - call ebp - - mov byte[MOUSE_BACKGROUND], 0 - - .exit: - popfd - popad - ret - -align 4 -; TODO: remove this proc -;------------------------------------------------------------------------------ -window_check_events: ;///////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - ; do we have window minimize/restore request? - cmp [window_minimize], 0 - je .exit - - ; okay, minimize or restore top-most window and exit - mov eax, [TASK_COUNT] - mov bl, 0 - xchg [window_minimize], bl - dec bl - jnz @f - call minimize_window - jmp .exit - - @@: call restore_minimized_window - - .exit: - ret - -align 4 -;------------------------------------------------------------------------------ -sys_window_maximize_handler: ;///////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;> esi = process slot -;------------------------------------------------------------------------------ - mov edi, esi - shl edi, 5 - add edi, window_data - - ; can window change its height? - mov dl, [edi + WDATA.fl_wstyle] - and dl, 0x0f - cmp dl, 0x04 - je .exit - - ; toggle normal/maximized window state - mov bl, [edi + WDATA.fl_wstate] - xor bl, WSTATE_MAXIMIZED - - ; calculate and set appropriate window bounds - test bl, WSTATE_MAXIMIZED - jz .restore_size - - mov eax, [screen_workarea.left] - mov ecx, [screen_workarea.top] - push [screen_workarea.bottom] \ - [screen_workarea.right] \ - ecx \ - eax - sub [esp + BOX.width], eax - sub [esp + BOX.height], ecx - mov eax, esp - jmp .set_box - - .restore_size: - mov eax, esi - shl eax, 8 - add eax, SLOT_BASE + APPDATA.saved_box - push [eax + BOX.height] \ - [eax + BOX.width] \ - [eax + BOX.top] \ - [eax + BOX.left] - mov eax, esp - - .set_box: - test bl, WSTATE_ROLLEDUP - jz @f - - xchg eax, ecx - call window._.get_rolledup_height - mov [ecx + BOX.height], eax - xchg eax, ecx - - @@: call window._.set_window_box - add esp, BOX.sizeof - - .exit: - ret - -align 4 -;------------------------------------------------------------------------------ -sys_window_rollup_handler: ;/////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;> esi = process slot -;------------------------------------------------------------------------------ - mov edx, esi - shl edx, 8 - add edx, SLOT_BASE - - ; toggle normal/rolled up window state - mov bl, [edi + WDATA.fl_wstate] - xor bl, WSTATE_ROLLEDUP - - ; calculate and set appropriate window bounds - test bl, WSTATE_ROLLEDUP - jz .restore_size - - call window._.get_rolledup_height - push eax \ - [edi + WDATA.box.width] \ - [edi + WDATA.box.top] \ - [edi + WDATA.box.left] - mov eax, esp - jmp .set_box - - .restore_size: - test bl, WSTATE_MAXIMIZED - jnz @f - add esp, -BOX.sizeof - lea eax, [edx + APPDATA.saved_box] - jmp .set_box - - @@: mov eax, [screen_workarea.top] - push [screen_workarea.bottom] \ - [edi + WDATA.box.width] \ - eax \ - [edi + WDATA.box.left] - sub [esp + BOX.height], eax - mov eax, esp - - .set_box: - call window._.set_window_box - add esp, BOX.sizeof - - ret - -align 4 -;------------------------------------------------------------------------------ -sys_window_start_moving_handler: ;///////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;> eax = old (original) window box -;> esi = process slot -;------------------------------------------------------------------------------ - mov edi, eax - call window._.draw_negative_box - - ret - -align 4 -;------------------------------------------------------------------------------ -sys_window_end_moving_handler: ;/////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;> eax = old (original) window box -;> ebx = new (final) window box -;> esi = process slot -;------------------------------------------------------------------------------ - mov edi, ebx - call window._.draw_negative_box - - mov edi, esi - shl edi, 5 - add edi, window_data - - mov eax, ebx - mov bl, [edi + WDATA.fl_wstate] - call window._.set_window_box - ret - -align 4 -;------------------------------------------------------------------------------ -sys_window_moving_handler: ;/////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;> eax = old (from previous call) window box -;> ebx = new (current) window box -;> esi = process_slot -;------------------------------------------------------------------------------ - mov edi, eax - call window._.draw_negative_box - mov edi, ebx - call window._.draw_negative_box - ret - -;============================================================================== -;///// private functions ////////////////////////////////////////////////////// -;============================================================================== - -iglobal - FuncTable syscall_display_settings, ftable, \ - 00, 01, 02, 03, 04, 05, 06, 07, 08 - - align 4 - window_topleft dd \ - 1, 21, \ ;type 0 - 0, 0, \ ;type 1 - 5, 20, \ ;type 2 - 5, ?, \ ;type 3 {set by skin} - 5, ? ;type 4 {set by skin} -endg - -;uglobal - ; NOTE: commented out since doesn't provide necessary functionality anyway, - ; to be reworked -; new_window_starting dd ? -;endg - -align 4 -;------------------------------------------------------------------------------ -window._.invalidate_screen: ;////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;> eax = old (original) window box -;> ebx = new (final) window box -;> edi = pointer to WDATA struct -;------------------------------------------------------------------------------ - push eax ebx - - ; TODO: do we really need `draw_limits`? - mov ecx, [eax + BOX.left] - mov edx, [ebx + BOX.left] - cmp ecx, edx - jle @f - xchg ecx, edx - @@: mov [draw_limits.left], ecx - mov ecx, [eax + BOX.width] - cmp ecx, [ebx + BOX.width] - jae @f - mov ecx, [ebx + BOX.width] - @@: add ecx, edx - mov [draw_limits.right], ecx - mov ecx, [eax + BOX.top] - mov edx, [ebx + BOX.top] - cmp ecx, edx - jle @f - xchg ecx, edx - @@: mov [draw_limits.top], ecx - mov ecx, [eax + BOX.height] - cmp ecx, [ebx + BOX.height] - jae @f - mov ecx, [ebx + BOX.height] - @@: add ecx, edx - mov [draw_limits.bottom], ecx - - ; recalculate screen buffer at old position - push ebx - mov edx, [eax + BOX.height] - mov ecx, [eax + BOX.width] - mov ebx, [eax + BOX.top] - mov eax, [eax + BOX.left] - add ecx, eax - add edx, ebx - call calculatescreen - pop eax - - ; recalculate screen buffer at new position - mov edx, [eax + BOX.height] - mov ecx, [eax + BOX.width] - mov ebx, [eax + BOX.top] - mov eax, [eax + BOX.left] - add ecx, eax - add edx, ebx - call calculatescreen - - mov eax, edi - call redrawscreen - - ; tell window to redraw itself - mov [edi + WDATA.fl_redraw], 1 - - pop ebx eax - ret - -align 4 -;------------------------------------------------------------------------------ -window._.set_window_box: ;///////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;> eax = pointer to BOX struct -;> bl = new window state flags -;> edi = pointer to WDATA struct -;------------------------------------------------------------------------------ - push eax ebx esi - -; don't do anything if the new box is identical to the old - cmp bl, [edi + WDATA.fl_wstate] - jnz @f - mov esi, eax - push edi -if WDATA.box - add edi, WDATA.box -end if - mov ecx, 4 - repz cmpsd - pop edi - jz .exit -@@: - - add esp, -BOX.sizeof - - mov ebx, esp -if WDATA.box - lea esi, [edi + WDATA.box] -else - mov esi, edi ; optimization for WDATA.box = 0 -end if - xchg eax, esi - mov ecx, BOX.sizeof - call memmove - xchg eax, esi - xchg ebx, esi - call memmove - mov eax, ebx - mov ebx, esi - - call window._.check_window_position - call window._.set_window_clientbox - call window._.invalidate_screen - - add esp, BOX.sizeof - - mov cl, [esp + 4] - mov ch, cl - xchg cl, [edi + WDATA.fl_wstate] - - or cl, ch - test cl, WSTATE_MAXIMIZED - jnz .exit - - mov eax, edi - sub eax, window_data - shl eax, 3 - add eax, SLOT_BASE - - lea ebx, [edi + WDATA.box] - xchg esp, ebx - - pop [eax + APPDATA.saved_box.left] \ - [eax + APPDATA.saved_box.top] \ - [eax + APPDATA.saved_box.width] \ - edx - - xchg esp, ebx - - test ch, WSTATE_ROLLEDUP - jnz .exit - - mov [eax + APPDATA.saved_box.height], edx - - .exit: - pop esi ebx eax - ret - -align 4 -;------------------------------------------------------------------------------ -window._.set_window_clientbox: ;/////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;> edi = pointer to WDATA struct -;------------------------------------------------------------------------------ - push eax ecx edi - - mov eax, [_skinh] - mov [window_topleft + 8 * 3 + 4], eax - mov [window_topleft + 8 * 4 + 4], eax - - mov ecx, edi - sub edi, window_data - shl edi, 3 - test [ecx + WDATA.fl_wstyle], WSTYLE_CLIENTRELATIVE - jz .whole_window - - movzx eax, [ecx + WDATA.fl_wstyle] - and eax, 0x0F - mov eax, [eax * 8 + window_topleft + 0] - mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax - shl eax, 1 - neg eax - add eax, [ecx + WDATA.box.width] - mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax - - movzx eax, [ecx + WDATA.fl_wstyle] - and eax, 0x0F - push [eax * 8 + window_topleft + 0] - mov eax, [eax * 8 + window_topleft + 4] - mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax - neg eax - sub eax, [esp] - add eax, [ecx + WDATA.box.height] - mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax - add esp, 4 - jmp .exit - - .whole_window: - xor eax, eax - mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax - mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax - mov eax, [ecx + WDATA.box.width] - mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax - mov eax, [ecx + WDATA.box.height] - mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax - - .exit: - pop edi ecx eax - ret - -align 4 -;------------------------------------------------------------------------------ -window._.sys_set_window: ;///////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;< edx = pointer to WDATA struct -;------------------------------------------------------------------------------ - mov eax, [CURRENT_TASK] - shl eax, 5 - add eax, window_data - - ; save window colors - mov [eax + WDATA.cl_workarea], edx - mov [eax + WDATA.cl_titlebar], esi - mov [eax + WDATA.cl_frames], edi - - mov edi, eax - - ; was it already defined before? - test [edi + WDATA.fl_wdrawn], 1 - jnz .set_client_box - - ; NOTE: commented out since doesn't provide necessary functionality - ; anyway, to be reworked -; mov eax, [timer_ticks] ; [0xfdf0] -; add eax, 100 -; mov [new_window_starting], eax - - ; no it wasn't, performing initial window definition - movzx eax, bx - mov [edi + WDATA.box.width], eax - movzx eax, cx - mov [edi + WDATA.box.height], eax - sar ebx, 16 - sar ecx, 16 - mov [edi + WDATA.box.left], ebx - mov [edi + WDATA.box.top], ecx - - call window._.check_window_position - - push ecx edi - - mov cl, [edi + WDATA.fl_wstyle] - mov eax, [edi + WDATA.cl_frames] - - sub edi, window_data - shl edi, 3 - add edi, SLOT_BASE - - and cl, 0x0F - cmp cl, 3 - je @f - cmp cl, 4 - je @f - - xor eax, eax - - @@: mov [edi + APPDATA.wnd_caption], eax - - mov esi, [esp] - add edi, APPDATA.saved_box - movsd - movsd - movsd - movsd - - pop edi ecx - - mov esi, [CURRENT_TASK] - movzx esi, word[WIN_STACK + esi * 2] - lea esi, [WIN_POS + esi * 2] - call waredraw - - mov eax, [edi + WDATA.box.left] - mov ebx, [edi + WDATA.box.top] - mov ecx, [edi + WDATA.box.width] - mov edx, [edi + WDATA.box.height] - add ecx, eax - add edx, ebx - call calculatescreen - - mov byte[KEY_COUNT], 0 ; empty keyboard buffer - mov byte[BTN_COUNT], 0 ; empty button buffer - - .set_client_box: - ; update window client box coordinates - call window._.set_window_clientbox - - ; reset window redraw flag and exit - mov [edi + WDATA.fl_redraw], 0 - mov edx, edi - ret - -align 4 -;------------------------------------------------------------------------------ -window._.check_window_position: ;////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Check if window is inside screen area -;------------------------------------------------------------------------------ -;> edi = pointer to WDATA -;------------------------------------------------------------------------------ - push eax ebx ecx edx esi - - mov eax, [edi + WDATA.box.left] - mov ebx, [edi + WDATA.box.top] - mov ecx, [edi + WDATA.box.width] - mov edx, [edi + WDATA.box.height] - - mov esi, [Screen_Max_X] - cmp ecx, esi - ja .fix_width_high - - .check_left: - or eax, eax - jl .fix_left_low - add eax, ecx - cmp eax, esi - jg .fix_left_high - - .check_height: - mov esi, [Screen_Max_Y] - cmp edx, esi - ja .fix_height_high - - .check_top: - or ebx, ebx - jl .fix_top_low - add ebx, edx - cmp ebx, esi - jg .fix_top_high - - .exit: - pop esi edx ecx ebx eax - ret - - .fix_width_high: - mov ecx, esi - mov [edi + WDATA.box.width], esi - jmp .check_left - - .fix_left_low: - xor eax, eax - mov [edi + WDATA.box.left], eax - jmp .check_height - - .fix_left_high: - mov eax, esi - sub eax, ecx - mov [edi + WDATA.box.left], eax - jmp .check_height - - .fix_height_high: - mov edx, esi - mov [edi + WDATA.box.height], esi - jmp .check_top - - .fix_top_low: - xor ebx, ebx - mov [edi + WDATA.box.top], ebx - jmp .exit - - .fix_top_high: - mov ebx, esi - sub ebx, edx - mov [edi + WDATA.box.top], ebx - jmp .exit - -align 4 -;------------------------------------------------------------------------------ -window._.get_titlebar_height: ;//////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;> edi = pointer to WDATA -;------------------------------------------------------------------------------ - mov al, [edi + WDATA.fl_wstyle] - and al, 0x0f - cmp al, 0x03 - jne @f - mov eax, [_skinh] - ret - @@: mov eax, 21 - ret - -align 4 -;------------------------------------------------------------------------------ -window._.get_rolledup_height: ;//////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ -;> edi = pointer to WDATA -;------------------------------------------------------------------------------ - mov al, [edi + WDATA.fl_wstyle] - and al, 0x0f - cmp al, 0x03 - jb @f - mov eax, [_skinh] - add eax, 3 - ret - @@: or al, al - jnz @f - mov eax, 21 - ret - @@: mov eax, 21 + 2 - ret - -align 4 -;------------------------------------------------------------------------------ -window._.set_screen: ;///////////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Reserve window area in screen buffer -;------------------------------------------------------------------------------ -;> eax = left -;> ebx = top -;> ecx = right -;> edx = bottom -;> esi = process number -;------------------------------------------------------------------------------ -virtual at esp - ff_x dd ? - ff_y dd ? - ff_width dd ? - ff_xsz dd ? - ff_ysz dd ? - ff_scale dd ? -end virtual - - pushad - - cmp esi, 1 - jz .check_for_shaped_window - mov edi, esi - shl edi, 5 - cmp [window_data + edi + WDATA.box.width], 0 - jnz .check_for_shaped_window - cmp [window_data + edi + WDATA.box.height], 0 - jz .exit - - .check_for_shaped_window: - mov edi, esi - shl edi, 8 - add edi, SLOT_BASE - cmp [edi + APPDATA.wnd_shape], 0 - jne .shaped_window - - ; get x&y size - sub ecx, eax - sub edx, ebx - inc ecx - inc edx - - ; get WinMap start - push esi - mov edi, [Screen_Max_X] - inc edi - mov esi, edi - imul edi, ebx - add edi, eax - add edi, [_WinMapAddress] - pop eax - mov ah, al - push ax - shl eax, 16 - pop ax - - .next_line: - push ecx - shr ecx, 2 - rep stosd - mov ecx, [esp] - and ecx, 3 - rep stosb - pop ecx - add edi, esi - sub edi, ecx - dec edx - jnz .next_line - - jmp .exit - - .shaped_window: - ; for (y=0; y <= x_size; y++) - ; for (x=0; x <= x_size; x++) - ; if (shape[coord(x,y,scale)]==1) - ; set_pixel(x, y, process_number); - - sub ecx, eax - sub edx, ebx - inc ecx - inc edx - - push [edi + APPDATA.wnd_shape_scale] ; push scale first -> for loop - - ; get WinMap start -> ebp - push eax - mov eax, [Screen_Max_X] ; screen_sx - inc eax - imul eax, ebx - add eax, [esp] - add eax, [_WinMapAddress] - mov ebp, eax - - mov edi, [edi + APPDATA.wnd_shape] - pop eax - - ; eax = x_start - ; ebx = y_start - ; ecx = x_size - ; edx = y_size - ; esi = process_number - ; edi = &shape - ; [scale] - push edx ecx ; for loop - x,y size - - mov ecx, esi - shl ecx, 5 - mov edx, [window_data + ecx + WDATA.box.top] - push [window_data + ecx + WDATA.box.width] ; for loop - width - mov ecx, [window_data + ecx + WDATA.box.left] - sub ebx, edx - sub eax, ecx - push ebx eax ; for loop - x,y - - add [ff_xsz], eax - add [ff_ysz], ebx - - mov ebx, [ff_y] - - .ff_new_y: - mov edx, [ff_x] - - .ff_new_x: - ; -- body -- - mov ecx, [ff_scale] - mov eax, [ff_width] - inc eax - shr eax, cl - push ebx edx - shr ebx, cl - shr edx, cl - imul eax, ebx - add eax, edx - pop edx ebx - add eax, edi - call .read_byte - test al,al - jz @f - mov eax, esi - mov [ebp], al - ; -- end body -- - @@: inc ebp - inc edx - cmp edx, [ff_xsz] - jb .ff_new_x - - sub ebp, [ff_xsz] - add ebp, [ff_x] - add ebp, [Screen_Max_X] ; screen.x - inc ebp - inc ebx - cmp ebx, [ff_ysz] - jb .ff_new_y - - add esp, 24 - - .exit: - popad - ret - - .read_byte: - ; eax - address - ; esi - slot - push eax ecx edx esi - xchg eax, esi - lea ecx, [esp + 12] - mov edx, 1 - call read_process_memory - pop esi edx ecx eax - ret - -align 4 -;------------------------------------------------------------------------------ -window._.window_activate: ;//////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Activate window -;------------------------------------------------------------------------------ -;> esi = pointer to WIN_POS+ window data -;------------------------------------------------------------------------------ - push eax ebx - - ; if type of current active window is 3 or 4, it must be redrawn - mov ebx, [TASK_COUNT] - movzx ebx, word[WIN_POS + ebx * 2] - shl ebx, 5 - add eax, window_data - mov al, [window_data + ebx + WDATA.fl_wstyle] - and al, 0x0f - cmp al, 0x03 - je .set_window_redraw_flag - cmp al, 0x04 - jne .move_others_down - - .set_window_redraw_flag: - mov [window_data + ebx + WDATA.fl_redraw], 1 - - .move_others_down: - ; ax <- process no - movzx ebx, word[esi] - ; ax <- position in window stack - movzx ebx, word[WIN_STACK + ebx * 2] - - ; drop others - xor eax, eax - - .next_stack_window: - cmp eax, [TASK_COUNT] - jae .move_self_up - inc eax - cmp [WIN_STACK + eax * 2], bx - jbe .next_stack_window - dec word[WIN_STACK + eax * 2] - jmp .next_stack_window - - .move_self_up: - movzx ebx, word[esi] - ; number of processes - mov ax, [TASK_COUNT] - ; this is the last (and the upper) - mov [WIN_STACK + ebx * 2], ax - - ; update on screen - window stack - xor eax, eax - - .next_window_pos: - cmp eax, [TASK_COUNT] - jae .reset_vars - inc eax - movzx ebx, word[WIN_STACK + eax * 2] - mov [WIN_POS + ebx * 2], ax - jmp .next_window_pos - - .reset_vars: - mov byte[KEY_COUNT], 0 - mov byte[BTN_COUNT], 0 - mov word[MOUSE_SCROLL_H], 0 - mov word[MOUSE_SCROLL_V], 0 - - pop ebx eax - ret - -align 4 -;------------------------------------------------------------------------------ -window._.check_window_draw: ;////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Check if window is necessary to draw -;------------------------------------------------------------------------------ -;> edi = pointer to WDATA -;------------------------------------------------------------------------------ - mov cl, [edi + WDATA.fl_wstyle] - and cl, 0x0f - cmp cl, 3 - je .exit.redraw ; window type 3 - cmp cl, 4 - je .exit.redraw ; window type 4 - - push eax ebx edx esi - - mov eax, edi - sub eax, window_data - shr eax, 5 - - movzx eax, word[WIN_STACK + eax * 2] ; get value of the curr process - lea esi, [WIN_POS + eax * 2] ; get address of this process at 0xC400 - - .next_window: - add esi, 2 - - mov eax, [TASK_COUNT] - lea eax, word[WIN_POS + eax * 2] ; number of the upper window - - cmp esi, eax - ja .exit.no_redraw - - movzx edx, word[esi] - shl edx, 5 - cmp [CURRENT_TASK + edx + TASKDATA.state], TSTATE_FREE - je .next_window - - mov eax, [edi + WDATA.box.top] - mov ebx, [edi + WDATA.box.height] - add ebx, eax - - mov ecx, [window_data + edx + WDATA.box.top] - cmp ecx, ebx - jge .next_window - add ecx, [window_data + edx + WDATA.box.height] - cmp eax, ecx - jge .next_window - - mov eax, [edi + WDATA.box.left] - mov ebx, [edi + WDATA.box.width] - add ebx, eax - - mov ecx, [window_data + edx + WDATA.box.left] - cmp ecx, ebx - jge .next_window - add ecx, [window_data + edx + WDATA.box.width] - cmp eax, ecx - jge .next_window - - pop esi edx ebx eax - - .exit.redraw: - xor ecx, ecx - inc ecx - ret - - .exit.no_redraw: - pop esi edx ebx eax - xor ecx, ecx - ret - -align 4 -;------------------------------------------------------------------------------ -window._.draw_window_caption: ;//////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? -;------------------------------------------------------------------------------ - inc [mouse_pause] - call [_display.disable_mouse] - - xor eax, eax - mov edx, [TASK_COUNT] - movzx edx, word[WIN_POS + edx * 2] - cmp edx, [CURRENT_TASK] - jne @f - inc eax - @@: mov edx, [CURRENT_TASK] - shl edx, 5 - add edx, window_data - movzx ebx, [edx + WDATA.fl_wstyle] - and bl, 0x0F - cmp bl, 3 - je .draw_caption_style_3 - cmp bl, 4 - je .draw_caption_style_3 - - jmp .not_style_3 - - .draw_caption_style_3: - push edx - call drawwindow_IV_caption - add esp, 4 - jmp .2 - - .not_style_3: - cmp bl, 2 - jne .not_style_2 - - call drawwindow_III_caption - jmp .2 - - .not_style_2: - cmp bl, 0 - jne .2 - - call drawwindow_I_caption - - .2: mov edi, [CURRENT_TASK] - shl edi, 5 - test [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION - jz .exit - mov edx, [edi * 8 + SLOT_BASE + APPDATA.wnd_caption] - or edx, edx - jz .exit - - movzx eax, [edi + window_data + WDATA.fl_wstyle] - and al, 0x0F - cmp al, 3 - je .skinned - cmp al, 4 - je .skinned - - jmp .not_skinned - - .skinned: - mov ebp, [edi + window_data + WDATA.box.left - 2] - mov bp, word[edi + window_data + WDATA.box.top] - movzx eax, word[edi + window_data + WDATA.box.width] - sub ax, [_skinmargins.left] - sub ax, [_skinmargins.right] - push edx - cwde - cdq - mov ebx, 6 - idiv ebx - pop edx - or eax, eax - js .exit - - mov esi, eax - mov ebx, dword[_skinmargins.left - 2] - mov bx, word[_skinh] - sub bx, [_skinmargins.bottom] - sub bx, [_skinmargins.top] - sar bx, 1 - adc bx, 0 - add bx, [_skinmargins.top] - add bx, -3 - add ebx, ebp - jmp .dodraw - - .not_skinned: - cmp al, 1 - je .exit - - mov ebp, [edi + window_data + WDATA.box.left - 2] - mov bp, word[edi + window_data + WDATA.box.top] - movzx eax, word[edi + window_data + WDATA.box.width] - sub eax, 16 - push edx - cwde - cdq - mov ebx, 6 - idiv ebx - pop edx - or eax, eax - js .exit - - mov esi, eax - mov ebx, 0x00080007 - add ebx, ebp - - .dodraw: - mov ecx, [common_colours + 16] - or ecx, 0x80000000 - xor edi, edi - call dtext_asciiz_esi - - .exit: - dec [mouse_pause] - call [draw_pointer] - ret - -align 4 -;------------------------------------------------------------------------------ -window._.draw_negative_box: ;////////////////////////////////////////////////// -;------------------------------------------------------------------------------ -;? Draw negative box -;------------------------------------------------------------------------------ -;> edi = pointer to BOX struct -;------------------------------------------------------------------------------ - push eax ebx esi - mov eax, [edi + BOX.left - 2] - mov ax, word[edi + BOX.left] - add ax, word[edi + BOX.width] - mov ebx, [edi + BOX.top - 2] - mov bx, word[edi + BOX.top] - add bx, word[edi + BOX.height] - mov esi, 0x01000000 - call draw_rectangle.forced - pop esi ebx eax - ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + +;============================================================================== +;///// public functions /////////////////////////////////////////////////////// +;============================================================================== + +window.BORDER_SIZE = 5 + +macro FuncTable name, table_name, [label] +{ + common + align 4 + \label name#.#table_name dword + forward + dd name#.#label + common + name#.sizeof.#table_name = $ - name#.#table_name +} + +uglobal + common_colours rd 32 + draw_limits RECT +endg + +align 4 +;------------------------------------------------------------------------------ +syscall_draw_window: ;///// system function 0 ///////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + mov eax, edx + shr eax, 24 + and al, 0x0f + cmp al, 5 + jae .exit + + push eax + inc [mouse_pause] + call [_display.disable_mouse] + call window._.sys_set_window + call [_display.disable_mouse] + pop eax + + or al, al + jnz @f + + ; type I - original style + call drawwindow_I + jmp window._.draw_window_caption.2 + + @@: dec al + jnz @f + + ; type II - only reserve area, no draw + call sys_window_mouse + dec [mouse_pause] + call [draw_pointer] + jmp .exit + + @@: dec al + jnz @f + + ; type III - new style + call drawwindow_III + jmp window._.draw_window_caption.2 + + ; type IV & V - skinned window (resizable & not) + @@: mov eax, [TASK_COUNT] + movzx eax, word[WIN_POS + eax * 2] + cmp eax, [CURRENT_TASK] + setz al + movzx eax, al + push eax + call drawwindow_IV + jmp window._.draw_window_caption.2 + + .exit: + ret + +align 4 +;------------------------------------------------------------------------------ +syscall_display_settings: ;///// system function 48 /////////////////////////// +;------------------------------------------------------------------------------ +;; Redraw screen: +;< ebx = 0 +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Set button style: +;< ebx = 1 +;< ecx = 0 (flat) or 1 (with gradient) +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Set system color palette: +;< ebx = 2 +;< ecx = pointer to color table +;< edx = size of color table +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Get system color palette: +;< ebx = 3 +;< ecx = pointer to color table buffer +;< edx = size of color table buffer +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Get skinned caption height: +;< ebx = 4 +;> eax = height in pixels +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Get screen working area: +;< ebx = 5 +;> eax = pack[16(left), 16(right)] +;> ebx = pack[16(top), 16(bottom)] +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Set screen working area: +;< ebx = 6 +;< ecx = pack[16(left), 16(right)] +;< edx = pack[16(top), 16(bottom)] +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Get skin margins: +;< ebx = 7 +;> eax = pack[16(left), 16(right)] +;> ebx = pack[16(top), 16(bottom)] +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Set skin: +;< ebx = 8 +;< ecx = pointer to FileInfoBlock struct +;> eax = FS error code +;------------------------------------------------------------------------------ + cmp ebx, .sizeof.ftable / 4 + ja @f + jmp [.ftable + ebx * 4] + @@: ret + + +align 4 +syscall_display_settings.00: + xor eax, eax + inc ebx + cmp [windowtypechanged], ebx + jne .exit + mov [windowtypechanged], eax + + jmp syscall_display_settings._.redraw_whole_screen + + .exit: + ret + +align 4 +syscall_display_settings.01: + and ecx, 1 + cmp ecx, [buttontype] + je .exit + mov [buttontype], ecx + mov [windowtypechanged], ebx + + .exit: + ret + +align 4 +syscall_display_settings.02: + dec ebx + mov esi, ecx + and edx, 127 + mov edi, common_colours + mov ecx, edx + rep movsb + mov [windowtypechanged], ebx + ret + +align 4 +syscall_display_settings.03: + mov edi, ecx + and edx, 127 + mov esi, common_colours + mov ecx, edx + rep movsb + ret + +align 4 +syscall_display_settings.04: + mov eax, [_skinh] + mov [esp + 32], eax + ret + +align 4 +syscall_display_settings.05: + mov eax, [screen_workarea.left - 2] + mov ax, word[screen_workarea.right] + mov [esp + 32], eax + mov eax, [screen_workarea.top - 2] + mov ax, word[screen_workarea.bottom] + mov [esp + 20], eax + ret + +align 4 +syscall_display_settings.06: + xor esi, esi + + mov edi, [Screen_Max_X] + mov eax, ecx + movsx ebx, ax + sar eax, 16 + cmp eax, ebx + jge .check_horizontal + inc esi + or eax, eax + jge @f + xor eax, eax + @@: mov [screen_workarea.left], eax + cmp ebx, edi + jle @f + mov ebx, edi + @@: mov [screen_workarea.right], ebx + + .check_horizontal: + mov edi, [Screen_Max_Y] + mov eax, edx + movsx ebx, ax + sar eax, 16 + cmp eax, ebx + jge .check_if_redraw_needed + inc esi + or eax, eax + jge @f + xor eax, eax + @@: mov [screen_workarea.top], eax + cmp ebx, edi + jle @f + mov ebx, edi + @@: mov [screen_workarea.bottom], ebx + + .check_if_redraw_needed: + or esi, esi + jz .exit + + call repos_windows + jmp syscall_display_settings._.calculate_whole_screen + + .exit: + ret + +align 4 +syscall_display_settings.07: + mov eax, [_skinmargins + 0] + mov [esp + 32], eax + mov eax, [_skinmargins + 4] + mov [esp + 20], eax + ret + +align 4 +syscall_display_settings.08: + mov ebx, ecx + call read_skin_file + mov [esp + 32], eax + test eax, eax + jnz .exit + + call syscall_display_settings._.calculate_whole_screen + jmp syscall_display_settings._.redraw_whole_screen + + .exit: + ret + +syscall_display_settings._.calculate_whole_screen: + xor eax, eax + xor ebx, ebx + mov ecx, [Screen_Max_X] + mov edx, [Screen_Max_Y] + jmp calculatescreen + +syscall_display_settings._.redraw_whole_screen: + xor eax, eax + mov [draw_limits.left], eax + mov [draw_limits.top], eax + mov eax, [Screen_Max_X] + mov [draw_limits.right], eax + mov eax, [Screen_Max_Y] + mov [draw_limits.bottom], eax + mov eax, window_data + jmp redrawscreen + +align 4 +;------------------------------------------------------------------------------ +syscall_set_window_shape: ;///// system function 50 /////////////////////////// +;------------------------------------------------------------------------------ +;; Set window shape address: +;> ebx = 0 +;> ecx = shape data address +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Set window shape scale: +;> ebx = 1 +;> ecx = scale power (resulting scale is 2^ebx) +;------------------------------------------------------------------------------ + mov edi, [current_slot] + + test ebx, ebx + jne .shape_scale + mov [edi + APPDATA.wnd_shape], ecx + + .shape_scale: + dec ebx + jnz .exit + mov [edi + APPDATA.wnd_shape_scale], ecx + + .exit: + ret + +align 4 +;------------------------------------------------------------------------------ +syscall_move_window: ;///// system function 67 //////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + mov edi, [CURRENT_TASK] + shl edi, 5 + add edi, window_data + + test [edi + WDATA.fl_wdrawn], 1 + jz .exit + + test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED + jnz .exit + + cmp ebx, -1 + jne @f + mov ebx, [edi + WDATA.box.left] + @@: cmp ecx, -1 + jne @f + mov ecx, [edi + WDATA.box.top] + @@: cmp edx, -1 + jne @f + mov edx, [edi + WDATA.box.width] + @@: cmp esi, -1 + jne @f + mov esi, [edi + WDATA.box.height] + + @@: push esi edx ecx ebx + mov eax, esp + mov bl, [edi + WDATA.fl_wstate] + call window._.set_window_box + add esp, BOX.sizeof + + ; NOTE: do we really need this? to be reworked +; mov byte[DONT_DRAW_MOUSE], 0 ; mouse pointer +; mov byte[MOUSE_BACKGROUND], 0 ; no mouse under +; mov byte[MOUSE_DOWN], 0 ; react to mouse up/down + + ; NOTE: do we really need this? to be reworked +; call [draw_pointer] + + .exit: + ret + +align 4 +;------------------------------------------------------------------------------ +syscall_window_settings: ;///// system function 71 ///////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + dec ebx ; subfunction #1 - set window caption + jnz .exit_fail + + ; NOTE: only window owner thread can set its caption, + ; so there's no parameter for PID/TID + + mov edi, [CURRENT_TASK] + shl edi, 5 + + mov [edi * 8 + SLOT_BASE + APPDATA.wnd_caption], ecx + or [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION + + call window._.draw_window_caption + + xor eax, eax ; eax = 0 (success) + ret + +; .get_window_caption: +; dec eax ; subfunction #2 - get window caption +; jnz .exit_fail + + ; not implemented yet + + .exit_fail: + xor eax, eax + inc eax ; eax = 1 (fail) + ret + +align 4 +;------------------------------------------------------------------------------ +set_window_defaults: ;///////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + mov byte [window_data + 0x20 + WDATA.cl_titlebar + 3], 1 ; desktop is not movable + push eax ecx + xor eax, eax + mov ecx, WIN_STACK + @@: inc eax + add ecx, 2 + ; process no + mov [ecx + 0x000], ax + ; positions in stack + mov [ecx + 0x400], ax + cmp ecx, WIN_POS - 2 + jne @b + pop ecx eax + ret + +align 4 +;------------------------------------------------------------------------------ +calculatescreen: ;///////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Scan all windows from bottom to top, calling `setscreen` for each one +;? intersecting given screen area +;------------------------------------------------------------------------------ +;> eax = left +;> ebx = top +;> ecx = right +;> edx = bottom +;------------------------------------------------------------------------------ + push esi + pushfd + cli + + mov esi, 1 + call window._.set_screen + + push ebp + + mov ebp, [TASK_COUNT] + cmp ebp, 1 + jbe .exit + + push edx ecx ebx eax + + .next_window: + movzx edi, word[WIN_POS + esi * 2] + shl edi, 5 + + cmp [CURRENT_TASK + edi + TASKDATA.state], TSTATE_FREE + je .skip_window + + add edi, window_data + test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .skip_window + + mov eax, [edi + WDATA.box.left] + cmp eax, [esp + RECT.right] + jg .skip_window + mov ebx, [edi + WDATA.box.top] + cmp ebx, [esp + RECT.bottom] + jg .skip_window + mov ecx, [edi + WDATA.box.width] + add ecx, eax + cmp ecx, [esp + RECT.left] + jl .skip_window + mov edx, [edi + WDATA.box.height] + add edx, ebx + cmp edx, [esp + RECT.top] + jl .skip_window + + cmp eax, [esp + RECT.left] + jae @f + mov eax, [esp + RECT.left] + @@: cmp ebx, [esp + RECT.top] + jae @f + mov ebx, [esp + RECT.top] + @@: cmp ecx, [esp + RECT.right] + jbe @f + mov ecx, [esp + RECT.right] + @@: cmp edx, [esp + RECT.bottom] + jbe @f + mov edx, [esp + RECT.bottom] + + @@: push esi + movzx esi, word[WIN_POS + esi * 2] + call window._.set_screen + pop esi + + .skip_window: + inc esi + dec ebp + jnz .next_window + + pop eax ebx ecx edx + + .exit: + pop ebp + popfd + pop esi + ret + +align 4 +;------------------------------------------------------------------------------ +repos_windows: ;/////////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + mov ecx, [TASK_COUNT] + mov edi, window_data + WDATA.sizeof * 2 + call force_redraw_background + dec ecx + jle .exit + + .next_window: + mov [edi + WDATA.fl_redraw], 1 + test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED + jnz .fix_maximized + + mov eax, [edi + WDATA.box.left] + add eax, [edi + WDATA.box.width] + mov ebx, [Screen_Max_X] + cmp eax, ebx + jle .fix_vertical + mov eax, [edi + WDATA.box.width] + sub eax, ebx + jle @f + mov [edi + WDATA.box.width], ebx + @@: sub ebx, [edi + WDATA.box.width] + mov [edi + WDATA.box.left], ebx + + .fix_vertical: + mov eax, [edi + WDATA.box.top] + add eax, [edi + WDATA.box.height] + mov ebx, [Screen_Max_Y] + cmp eax, ebx + jle .fix_client_box + mov eax, [edi + WDATA.box.height] + sub eax, ebx + jle @f + mov [edi + WDATA.box.height], ebx + @@: sub ebx, [edi + WDATA.box.height] + mov [edi + WDATA.box.top], ebx + jmp .fix_client_box + + .fix_maximized: + mov eax, [screen_workarea.left] + mov [edi + WDATA.box.left], eax + sub eax, [screen_workarea.right] + neg eax + mov [edi + WDATA.box.width], eax + mov eax, [screen_workarea.top] + mov [edi + WDATA.box.top], eax + test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP + jnz .fix_client_box + sub eax, [screen_workarea.bottom] + neg eax + mov [edi + WDATA.box.height], eax + + .fix_client_box: + call window._.set_window_clientbox + + add edi, WDATA.sizeof + loop .next_window + + .exit: + ret + +align 4 +;------------------------------------------------------------------------------ +sys_window_mouse: ;//////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + ; NOTE: commented out since doesn't provide necessary functionality + ; anyway, to be reworked +; push eax +; +; mov eax, [timer_ticks] +; cmp [new_window_starting], eax +; jb .exit +; +; mov byte[MOUSE_BACKGROUND], 0 +; mov byte[DONT_DRAW_MOUSE], 0 +; +; mov [new_window_starting], eax +; +; .exit: +; pop eax + ret + +align 4 +;------------------------------------------------------------------------------ +draw_rectangle: ;////////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;> eax = pack[16(left), 16(right)] +;> ebx = pack[16(top), 16(bottom)] +;> esi = color +;------------------------------------------------------------------------------ + push eax ebx ecx edi + + xor edi, edi + + .flags_set: + push ebx + + ; set line color + mov ecx, esi + + ; draw top border + rol ebx, 16 + push ebx + rol ebx, 16 + pop bx + call [draw_line] + + ; draw bottom border + mov ebx, [esp - 2] + pop bx + call [draw_line] + + pop ebx + add ebx, 1 * 65536 - 1 + + ; draw left border + rol eax, 16 + push eax + rol eax, 16 + pop ax + call [draw_line] + + ; draw right border + mov eax, [esp - 2] + pop ax + call [draw_line] + + pop edi ecx ebx eax + ret + + .forced: + push eax ebx ecx edi + xor edi, edi + inc edi + jmp .flags_set + +align 4 +;------------------------------------------------------------------------------ +drawwindow_I_caption: ;//////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + push [edx + WDATA.cl_titlebar] + mov esi, edx + + mov edx, [esi + WDATA.box.top] + mov eax, edx + lea ebx, [edx + 21] + inc edx + add eax, [esi + WDATA.box.height] + + cmp ebx, eax + jbe @f + mov ebx, eax + @@: push ebx + + xor edi, edi + + .next_line: + mov ebx, edx + shl ebx, 16 + add ebx, edx + mov eax, [esi + WDATA.box.left] + inc eax + shl eax, 16 + add eax, [esi + WDATA.box.left] + add eax, [esi + WDATA.box.width] + dec eax + mov ecx, [esi + WDATA.cl_titlebar] + test ecx, 0x80000000 + jz @f + sub ecx, 0x00040404 + mov [esi + WDATA.cl_titlebar], ecx + @@: and ecx, 0x00ffffff + call [draw_line] + inc edx + cmp edx, [esp] + jb .next_line + + add esp, 4 + pop [esi + WDATA.cl_titlebar] + ret + +align 4 +;------------------------------------------------------------------------------ +drawwindow_I: ;//////////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + pushad + + ; window border + + mov eax, [edx + WDATA.box.left - 2] + mov ax, word[edx + WDATA.box.left] + add ax, word[edx + WDATA.box.width] + mov ebx, [edx + WDATA.box.top - 2] + mov bx, word[edx + WDATA.box.top] + add bx, word[edx + WDATA.box.height] + + mov esi, [edx + WDATA.cl_frames] + call draw_rectangle + + ; window caption + + call drawwindow_I_caption + + ; window client area + + ; do we need to draw it? + mov edi, [esi + WDATA.cl_workarea] + test edi, 0x40000000 + jnz .exit + + ; does client area have a positive size on screen? + mov edx, [esi + WDATA.box.top] + add edx, 21 + 5 + mov ebx, [esi + WDATA.box.top] + add ebx, [esi + WDATA.box.height] + cmp edx, ebx + jg .exit + + ; okay, let's draw it + mov eax, 1 + mov ebx, 21 + mov ecx, [esi + WDATA.box.width] + mov edx, [esi + WDATA.box.height] + call [drawbar] + + .exit: + popad + ret + +align 4 +;------------------------------------------------------------------------------ +drawwindow_III_caption: ;///////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + mov ecx, [edx + WDATA.cl_titlebar] + push ecx + mov esi, edx + mov edx, [esi + WDATA.box.top] + add edx, 4 + mov ebx, [esi + WDATA.box.top] + add ebx, 20 + mov eax, [esi + WDATA.box.top] + add eax, [esi + WDATA.box.height] + + cmp ebx, eax + jb @f + mov ebx, eax + @@: push ebx + + xor edi, edi + + .next_line: + mov ebx, edx + shl ebx, 16 + add ebx, edx + mov eax, [esi + WDATA.box.left] + shl eax, 16 + add eax, [esi + WDATA.box.left] + add eax, [esi + WDATA.box.width] + add eax, 4 * 65536 - 4 + mov ecx, [esi + WDATA.cl_titlebar] + test ecx, 0x40000000 + jz @f + add ecx, 0x00040404 + @@: test ecx, 0x80000000 + jz @f + sub ecx, 0x00040404 + @@: mov [esi + WDATA.cl_titlebar], ecx + and ecx, 0x00ffffff + call [draw_line] + inc edx + cmp edx, [esp] + jb .next_line + + add esp, 4 + pop [esi + WDATA.cl_titlebar] + ret + +align 4 +;------------------------------------------------------------------------------ +drawwindow_III: ;////////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + pushad + + ; window border + + mov eax, [edx + WDATA.box.left - 2] + mov ax, word[edx + WDATA.box.left] + add ax, word[edx + WDATA.box.width] + mov ebx, [edx + WDATA.box.top - 2] + mov bx, word[edx + WDATA.box.top] + add bx, word[edx + WDATA.box.height] + + mov esi, [edx + WDATA.cl_frames] + shr esi, 1 + and esi, 0x007f7f7f + call draw_rectangle + + push esi + mov ecx, 3 + mov esi, [edx + WDATA.cl_frames] + + .next_frame: + add eax, 1 * 65536 - 1 + add ebx, 1 * 65536 - 1 + call draw_rectangle + dec ecx + jnz .next_frame + + pop esi + add eax, 1 * 65536 - 1 + add ebx, 1 * 65536 - 1 + call draw_rectangle + + ; window caption + + call drawwindow_III_caption + + ; window client area + + ; do we need to draw it? + mov edi, [esi + WDATA.cl_workarea] + test edi, 0x40000000 + jnz .exit + + ; does client area have a positive size on screen? + mov edx, [esi + WDATA.box.top] + add edx, 21 + 5 + mov ebx, [esi + WDATA.box.top] + add ebx, [esi + WDATA.box.height] + cmp edx, ebx + jg .exit + + ; okay, let's draw it + mov eax, 5 + mov ebx, 20 + mov ecx, [esi + WDATA.box.width] + mov edx, [esi + WDATA.box.height] + sub ecx, 4 + sub edx, 4 + call [drawbar] + + .exit: + popad + ret + +align 4 +;------------------------------------------------------------------------------ +waredraw: ;//////////////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Activate window, redrawing if necessary +;------------------------------------------------------------------------------ + push -1 + mov eax, [TASK_COUNT] + lea eax, [WIN_POS + eax * 2] + cmp eax, esi + pop eax + je .exit + + ; is it overlapped by another window now? + push ecx + call window._.check_window_draw + test ecx, ecx + pop ecx + jz .do_not_draw + + ; yes it is, activate and update screen buffer + mov byte[MOUSE_DOWN], 1 + call window._.window_activate + + pushad + mov edi, [TASK_COUNT] + movzx esi, word[WIN_POS + edi * 2] + shl esi, 5 + add esi, window_data + + mov eax, [esi + WDATA.box.left] + mov ebx, [esi + WDATA.box.top] + mov ecx, [esi + WDATA.box.width] + mov edx, [esi + WDATA.box.height] + + add ecx, eax + add edx, ebx + + mov edi, [TASK_COUNT] + movzx esi, word[WIN_POS + edi * 2] + call window._.set_screen + popad + + ; tell application to redraw itself + mov [edi + WDATA.fl_redraw], 1 + xor eax, eax + jmp .exit + + .do_not_draw: + ; no it's not, just activate the window + call window._.window_activate + xor eax, eax + mov byte[MOUSE_BACKGROUND], al + mov byte[DONT_DRAW_MOUSE], al + + + .exit: + mov byte[MOUSE_DOWN], 0 + inc eax + ret + +align 4 +;------------------------------------------------------------------------------ +minimize_window: ;///////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;> eax = window number on screen +;------------------------------------------------------------------------------ +;# corrupts [dl*] +;------------------------------------------------------------------------------ + push edi + pushfd + cli + + ; is it already minimized? + movzx edi, word[WIN_POS + eax * 2] + shl edi, 5 + add edi, window_data + test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .exit + + push eax ebx ecx edx esi + + ; no it's not, let's do that + or [edi + WDATA.fl_wstate], WSTATE_MINIMIZED + mov eax, [edi + WDATA.box.left] + mov [draw_limits.left], eax + mov ecx, eax + add ecx, [edi + WDATA.box.width] + mov [draw_limits.right], ecx + mov ebx, [edi + WDATA.box.top] + mov [draw_limits.top], ebx + mov edx, ebx + add edx, [edi + WDATA.box.height] + mov [draw_limits.bottom], edx + call calculatescreen + xor esi, esi + xor eax, eax + call redrawscreen + + pop esi edx ecx ebx eax + + .exit: + popfd + pop edi + ret + +align 4 +;------------------------------------------------------------------------------ +restore_minimized_window: ;//////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;> eax = window number on screen +;------------------------------------------------------------------------------ +;# corrupts [dl*] +;------------------------------------------------------------------------------ + pushad + pushfd + cli + + ; is it already restored? + movzx esi, word[WIN_POS + eax * 2] + mov edi, esi + shl edi, 5 + add edi, window_data + test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED + jz .exit + + ; no it's not, let's do that + mov [edi + WDATA.fl_redraw], 1 + and [edi + WDATA.fl_wstate], not WSTATE_MINIMIZED + mov ebp, window._.set_screen + cmp eax, [TASK_COUNT] + jz @f + mov ebp, calculatescreen + @@: mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.top] + mov ecx, [edi + WDATA.box.width] + mov edx, [edi + WDATA.box.height] + add ecx, eax + add edx, ebx + call ebp + + mov byte[MOUSE_BACKGROUND], 0 + + .exit: + popfd + popad + ret + +align 4 +; TODO: remove this proc +;------------------------------------------------------------------------------ +window_check_events: ;///////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + ; do we have window minimize/restore request? + cmp [window_minimize], 0 + je .exit + + ; okay, minimize or restore top-most window and exit + mov eax, [TASK_COUNT] + mov bl, 0 + xchg [window_minimize], bl + dec bl + jnz @f + call minimize_window + jmp .exit + + @@: call restore_minimized_window + + .exit: + ret + +align 4 +;------------------------------------------------------------------------------ +sys_window_maximize_handler: ;///////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;> esi = process slot +;------------------------------------------------------------------------------ + mov edi, esi + shl edi, 5 + add edi, window_data + + ; can window change its height? + ; only types 2 and 3 can be resized + mov dl, [edi + WDATA.fl_wstyle] + test dl, 2 + jz .exit + + ; toggle normal/maximized window state + mov bl, [edi + WDATA.fl_wstate] + xor bl, WSTATE_MAXIMIZED + + ; calculate and set appropriate window bounds + test bl, WSTATE_MAXIMIZED + jz .restore_size + + mov eax, [screen_workarea.left] + mov ecx, [screen_workarea.top] + push [screen_workarea.bottom] \ + [screen_workarea.right] \ + ecx \ + eax + sub [esp + BOX.width], eax + sub [esp + BOX.height], ecx + mov eax, esp + jmp .set_box + + .restore_size: + mov eax, esi + shl eax, 8 + add eax, SLOT_BASE + APPDATA.saved_box + push [eax + BOX.height] \ + [eax + BOX.width] \ + [eax + BOX.top] \ + [eax + BOX.left] + mov eax, esp + + .set_box: + test bl, WSTATE_ROLLEDUP + jz @f + + xchg eax, ecx + call window._.get_rolledup_height + mov [ecx + BOX.height], eax + xchg eax, ecx + + @@: call window._.set_window_box + add esp, BOX.sizeof + + .exit: + ret + +align 4 +;------------------------------------------------------------------------------ +sys_window_rollup_handler: ;/////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;> esi = process slot +;------------------------------------------------------------------------------ + mov edx, esi + shl edx, 8 + add edx, SLOT_BASE + + ; toggle normal/rolled up window state + mov bl, [edi + WDATA.fl_wstate] + xor bl, WSTATE_ROLLEDUP + + ; calculate and set appropriate window bounds + test bl, WSTATE_ROLLEDUP + jz .restore_size + + call window._.get_rolledup_height + push eax \ + [edi + WDATA.box.width] \ + [edi + WDATA.box.top] \ + [edi + WDATA.box.left] + mov eax, esp + jmp .set_box + + .restore_size: + test bl, WSTATE_MAXIMIZED + jnz @f + add esp, -BOX.sizeof + lea eax, [edx + APPDATA.saved_box] + jmp .set_box + + @@: mov eax, [screen_workarea.top] + push [screen_workarea.bottom] \ + [edi + WDATA.box.width] \ + eax \ + [edi + WDATA.box.left] + sub [esp + BOX.height], eax + mov eax, esp + + .set_box: + call window._.set_window_box + add esp, BOX.sizeof + + ret + +align 4 +;------------------------------------------------------------------------------ +sys_window_start_moving_handler: ;///////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;> eax = old (original) window box +;> esi = process slot +;------------------------------------------------------------------------------ + mov edi, eax + call window._.draw_negative_box + + ret + +align 4 +;------------------------------------------------------------------------------ +sys_window_end_moving_handler: ;/////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;> eax = old (original) window box +;> ebx = new (final) window box +;> esi = process slot +;------------------------------------------------------------------------------ + mov edi, ebx + call window._.draw_negative_box + + mov edi, esi + shl edi, 5 + add edi, window_data + + mov eax, ebx + mov bl, [edi + WDATA.fl_wstate] + call window._.set_window_box + ret + +align 4 +;------------------------------------------------------------------------------ +sys_window_moving_handler: ;/////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;> eax = old (from previous call) window box +;> ebx = new (current) window box +;> esi = process_slot +;------------------------------------------------------------------------------ + mov edi, eax + call window._.draw_negative_box + mov edi, ebx + call window._.draw_negative_box + ret + +;============================================================================== +;///// private functions ////////////////////////////////////////////////////// +;============================================================================== + +iglobal + FuncTable syscall_display_settings, ftable, \ + 00, 01, 02, 03, 04, 05, 06, 07, 08 + + align 4 + window_topleft dd \ + 1, 21, \ ;type 0 + 0, 0, \ ;type 1 + 5, 20, \ ;type 2 + 5, ?, \ ;type 3 {set by skin} + 5, ? ;type 4 {set by skin} +endg + +;uglobal + ; NOTE: commented out since doesn't provide necessary functionality anyway, + ; to be reworked +; new_window_starting dd ? +;endg + +align 4 +;------------------------------------------------------------------------------ +window._.invalidate_screen: ;////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;> eax = old (original) window box +;> ebx = new (final) window box +;> edi = pointer to WDATA struct +;------------------------------------------------------------------------------ + push eax ebx + + ; TODO: do we really need `draw_limits`? + ; Yes, they are used by background drawing code. + mov ecx, [eax + BOX.left] + mov edx, [ebx + BOX.left] + cmp ecx, edx + jle @f + mov ecx, edx + @@: mov [draw_limits.left], ecx + mov ecx, [eax + BOX.left] + add ecx, [eax + BOX.width] + add edx, [ebx + BOX.width] + cmp ecx, edx + jae @f + mov ecx, edx + @@: mov [draw_limits.right], ecx + mov ecx, [eax + BOX.top] + mov edx, [ebx + BOX.top] + cmp ecx, edx + jle @f + mov ecx, edx + @@: mov [draw_limits.top], ecx + mov ecx, [eax + BOX.top] + add ecx, [eax + BOX.height] + add edx, [ebx + BOX.height] + cmp ecx, edx + jae @f + mov ecx, edx + @@: mov [draw_limits.bottom], ecx + + ; recalculate screen buffer at old position + push ebx + mov edx, [eax + BOX.height] + mov ecx, [eax + BOX.width] + mov ebx, [eax + BOX.top] + mov eax, [eax + BOX.left] + add ecx, eax + add edx, ebx + call calculatescreen + pop eax + + ; recalculate screen buffer at new position + mov edx, [eax + BOX.height] + mov ecx, [eax + BOX.width] + mov ebx, [eax + BOX.top] + mov eax, [eax + BOX.left] + add ecx, eax + add edx, ebx + call calculatescreen + + mov eax, edi + call redrawscreen + + ; tell window to redraw itself + mov [edi + WDATA.fl_redraw], 1 + + pop ebx eax + ret + +align 4 +;------------------------------------------------------------------------------ +window._.set_window_box: ;///////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;> eax = pointer to BOX struct +;> bl = new window state flags +;> edi = pointer to WDATA struct +;------------------------------------------------------------------------------ + push eax ebx esi + +; don't do anything if the new box is identical to the old + cmp bl, [edi + WDATA.fl_wstate] + jnz @f + mov esi, eax + push edi +if WDATA.box + add edi, WDATA.box +end if + mov ecx, 4 + repz cmpsd + pop edi + jz .exit +@@: + + add esp, -BOX.sizeof + + mov ebx, esp +if WDATA.box + lea esi, [edi + WDATA.box] +else + mov esi, edi ; optimization for WDATA.box = 0 +end if + xchg eax, esi + mov ecx, BOX.sizeof + call memmove + xchg eax, esi + xchg ebx, esi + call memmove + mov eax, ebx + mov ebx, esi + + call window._.check_window_position + call window._.set_window_clientbox + call window._.invalidate_screen + + add esp, BOX.sizeof + + mov cl, [esp + 4] + mov ch, cl + xchg cl, [edi + WDATA.fl_wstate] + + or cl, ch + test cl, WSTATE_MAXIMIZED + jnz .exit + + mov eax, edi + sub eax, window_data + shl eax, 3 + add eax, SLOT_BASE + + lea ebx, [edi + WDATA.box] + xchg esp, ebx + + pop [eax + APPDATA.saved_box.left] \ + [eax + APPDATA.saved_box.top] \ + [eax + APPDATA.saved_box.width] \ + edx + + xchg esp, ebx + + test ch, WSTATE_ROLLEDUP + jnz .exit + + mov [eax + APPDATA.saved_box.height], edx + + .exit: + pop esi ebx eax + ret + +align 4 +;------------------------------------------------------------------------------ +window._.set_window_clientbox: ;/////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;> edi = pointer to WDATA struct +;------------------------------------------------------------------------------ + push eax ecx edi + + mov eax, [_skinh] + mov [window_topleft + 8 * 3 + 4], eax + mov [window_topleft + 8 * 4 + 4], eax + + mov ecx, edi + sub edi, window_data + shl edi, 3 + test [ecx + WDATA.fl_wstyle], WSTYLE_CLIENTRELATIVE + jz .whole_window + + movzx eax, [ecx + WDATA.fl_wstyle] + and eax, 0x0F + mov eax, [eax * 8 + window_topleft + 0] + mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax + shl eax, 1 + neg eax + add eax, [ecx + WDATA.box.width] + mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax + + movzx eax, [ecx + WDATA.fl_wstyle] + and eax, 0x0F + push [eax * 8 + window_topleft + 0] + mov eax, [eax * 8 + window_topleft + 4] + mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax + neg eax + sub eax, [esp] + add eax, [ecx + WDATA.box.height] + mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax + add esp, 4 + jmp .exit + + .whole_window: + xor eax, eax + mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax + mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax + mov eax, [ecx + WDATA.box.width] + mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax + mov eax, [ecx + WDATA.box.height] + mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax + + .exit: + pop edi ecx eax + ret + +align 4 +;------------------------------------------------------------------------------ +window._.sys_set_window: ;///////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;< edx = pointer to WDATA struct +;------------------------------------------------------------------------------ + mov eax, [CURRENT_TASK] + shl eax, 5 + add eax, window_data + + ; save window colors + mov [eax + WDATA.cl_workarea], edx + mov [eax + WDATA.cl_titlebar], esi + mov [eax + WDATA.cl_frames], edi + + mov edi, eax + + ; was it already defined before? + test [edi + WDATA.fl_wdrawn], 1 + jnz .set_client_box + or [edi + WDATA.fl_wdrawn], 1 + + ; NOTE: commented out since doesn't provide necessary functionality + ; anyway, to be reworked +; mov eax, [timer_ticks] ; [0xfdf0] +; add eax, 100 +; mov [new_window_starting], eax + + ; no it wasn't, performing initial window definition + movzx eax, bx + mov [edi + WDATA.box.width], eax + movzx eax, cx + mov [edi + WDATA.box.height], eax + sar ebx, 16 + sar ecx, 16 + mov [edi + WDATA.box.left], ebx + mov [edi + WDATA.box.top], ecx + + call window._.check_window_position + + push ecx edi + + mov cl, [edi + WDATA.fl_wstyle] + mov eax, [edi + WDATA.cl_frames] + + sub edi, window_data + shl edi, 3 + add edi, SLOT_BASE + + and cl, 0x0F + cmp cl, 3 + je @f + cmp cl, 4 + je @f + + xor eax, eax + + @@: mov [edi + APPDATA.wnd_caption], eax + + mov esi, [esp] + add edi, APPDATA.saved_box + movsd + movsd + movsd + movsd + + pop edi ecx + + mov esi, [CURRENT_TASK] + movzx esi, word[WIN_STACK + esi * 2] + lea esi, [WIN_POS + esi * 2] + call waredraw + + mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.top] + mov ecx, [edi + WDATA.box.width] + mov edx, [edi + WDATA.box.height] + add ecx, eax + add edx, ebx + call calculatescreen + + mov byte[KEY_COUNT], 0 ; empty keyboard buffer + mov byte[BTN_COUNT], 0 ; empty button buffer + + .set_client_box: + ; update window client box coordinates + call window._.set_window_clientbox + + ; reset window redraw flag and exit + mov [edi + WDATA.fl_redraw], 0 + mov edx, edi + ret + +align 4 +;------------------------------------------------------------------------------ +window._.check_window_position: ;////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Check if window is inside screen area +;------------------------------------------------------------------------------ +;> edi = pointer to WDATA +;------------------------------------------------------------------------------ + push eax ebx ecx edx esi + + mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.top] + mov ecx, [edi + WDATA.box.width] + mov edx, [edi + WDATA.box.height] + + mov esi, [Screen_Max_X] + cmp ecx, esi + ja .fix_width_high + + .check_left: + or eax, eax + jl .fix_left_low + add eax, ecx + cmp eax, esi + jg .fix_left_high + + .check_height: + mov esi, [Screen_Max_Y] + cmp edx, esi + ja .fix_height_high + + .check_top: + or ebx, ebx + jl .fix_top_low + add ebx, edx + cmp ebx, esi + jg .fix_top_high + + .exit: + pop esi edx ecx ebx eax + ret + + .fix_width_high: + mov ecx, esi + mov [edi + WDATA.box.width], esi + jmp .check_left + + .fix_left_low: + xor eax, eax + mov [edi + WDATA.box.left], eax + jmp .check_height + + .fix_left_high: + mov eax, esi + sub eax, ecx + mov [edi + WDATA.box.left], eax + jmp .check_height + + .fix_height_high: + mov edx, esi + mov [edi + WDATA.box.height], esi + jmp .check_top + + .fix_top_low: + xor ebx, ebx + mov [edi + WDATA.box.top], ebx + jmp .exit + + .fix_top_high: + mov ebx, esi + sub ebx, edx + mov [edi + WDATA.box.top], ebx + jmp .exit + +align 4 +;------------------------------------------------------------------------------ +window._.get_titlebar_height: ;//////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;> edi = pointer to WDATA +;------------------------------------------------------------------------------ + mov al, [edi + WDATA.fl_wstyle] + and al, 0x0f + cmp al, 0x03 + jne @f + mov eax, [_skinh] + ret + @@: mov eax, 21 + ret + +align 4 +;------------------------------------------------------------------------------ +window._.get_rolledup_height: ;//////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ +;> edi = pointer to WDATA +;------------------------------------------------------------------------------ + mov al, [edi + WDATA.fl_wstyle] + and al, 0x0f + cmp al, 0x03 + jb @f + mov eax, [_skinh] + add eax, 3 + ret + @@: or al, al + jnz @f + mov eax, 21 + ret + @@: mov eax, 21 + 2 + ret + +align 4 +;------------------------------------------------------------------------------ +window._.set_screen: ;///////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Reserve window area in screen buffer +;------------------------------------------------------------------------------ +;> eax = left +;> ebx = top +;> ecx = right +;> edx = bottom +;> esi = process number +;------------------------------------------------------------------------------ +virtual at esp + ff_x dd ? + ff_y dd ? + ff_width dd ? + ff_xsz dd ? + ff_ysz dd ? + ff_scale dd ? +end virtual + + pushad + + cmp esi, 1 + jz .check_for_shaped_window + mov edi, esi + shl edi, 5 + cmp [window_data + edi + WDATA.box.width], 0 + jnz .check_for_shaped_window + cmp [window_data + edi + WDATA.box.height], 0 + jz .exit + + .check_for_shaped_window: + mov edi, esi + shl edi, 8 + add edi, SLOT_BASE + cmp [edi + APPDATA.wnd_shape], 0 + jne .shaped_window + + ; get x&y size + sub ecx, eax + sub edx, ebx + inc ecx + inc edx + + ; get WinMap start + push esi + mov edi, [Screen_Max_X] + inc edi + mov esi, edi + imul edi, ebx + add edi, eax + add edi, [_WinMapAddress] + pop eax + mov ah, al + push ax + shl eax, 16 + pop ax + + .next_line: + push ecx + shr ecx, 2 + rep stosd + mov ecx, [esp] + and ecx, 3 + rep stosb + pop ecx + add edi, esi + sub edi, ecx + dec edx + jnz .next_line + + jmp .exit + + .shaped_window: + ; for (y=0; y <= x_size; y++) + ; for (x=0; x <= x_size; x++) + ; if (shape[coord(x,y,scale)]==1) + ; set_pixel(x, y, process_number); + + sub ecx, eax + sub edx, ebx + inc ecx + inc edx + + push [edi + APPDATA.wnd_shape_scale] ; push scale first -> for loop + + ; get WinMap start -> ebp + push eax + mov eax, [Screen_Max_X] ; screen_sx + inc eax + imul eax, ebx + add eax, [esp] + add eax, [_WinMapAddress] + mov ebp, eax + + mov edi, [edi + APPDATA.wnd_shape] + pop eax + + ; eax = x_start + ; ebx = y_start + ; ecx = x_size + ; edx = y_size + ; esi = process_number + ; edi = &shape + ; [scale] + push edx ecx ; for loop - x,y size + + mov ecx, esi + shl ecx, 5 + mov edx, [window_data + ecx + WDATA.box.top] + push [window_data + ecx + WDATA.box.width] ; for loop - width + mov ecx, [window_data + ecx + WDATA.box.left] + sub ebx, edx + sub eax, ecx + push ebx eax ; for loop - x,y + + add [ff_xsz], eax + add [ff_ysz], ebx + + mov ebx, [ff_y] + + .ff_new_y: + mov edx, [ff_x] + + .ff_new_x: + ; -- body -- + mov ecx, [ff_scale] + mov eax, [ff_width] + inc eax + shr eax, cl + push ebx edx + shr ebx, cl + shr edx, cl + imul eax, ebx + add eax, edx + pop edx ebx + add eax, edi + call .read_byte + test al,al + jz @f + mov eax, esi + mov [ebp], al + ; -- end body -- + @@: inc ebp + inc edx + cmp edx, [ff_xsz] + jb .ff_new_x + + sub ebp, [ff_xsz] + add ebp, [ff_x] + add ebp, [Screen_Max_X] ; screen.x + inc ebp + inc ebx + cmp ebx, [ff_ysz] + jb .ff_new_y + + add esp, 24 + + .exit: + popad + ret + + .read_byte: + ; eax - address + ; esi - slot + push eax ecx edx esi + xchg eax, esi + lea ecx, [esp + 12] + mov edx, 1 + call read_process_memory + pop esi edx ecx eax + ret + +align 4 +;------------------------------------------------------------------------------ +window._.window_activate: ;//////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Activate window +;------------------------------------------------------------------------------ +;> esi = pointer to WIN_POS+ window data +;------------------------------------------------------------------------------ + push eax ebx + + ; if type of current active window is 3 or 4, it must be redrawn + mov ebx, [TASK_COUNT] + movzx ebx, word[WIN_POS + ebx * 2] + shl ebx, 5 + add eax, window_data + mov al, [window_data + ebx + WDATA.fl_wstyle] + and al, 0x0f + cmp al, 0x03 + je .set_window_redraw_flag + cmp al, 0x04 + jne .move_others_down + + .set_window_redraw_flag: + mov [window_data + ebx + WDATA.fl_redraw], 1 + + .move_others_down: + ; ax <- process no + movzx ebx, word[esi] + ; ax <- position in window stack + movzx ebx, word[WIN_STACK + ebx * 2] + + ; drop others + xor eax, eax + + .next_stack_window: + cmp eax, [TASK_COUNT] + jae .move_self_up + inc eax + cmp [WIN_STACK + eax * 2], bx + jbe .next_stack_window + dec word[WIN_STACK + eax * 2] + jmp .next_stack_window + + .move_self_up: + movzx ebx, word[esi] + ; number of processes + mov ax, [TASK_COUNT] + ; this is the last (and the upper) + mov [WIN_STACK + ebx * 2], ax + + ; update on screen - window stack + xor eax, eax + + .next_window_pos: + cmp eax, [TASK_COUNT] + jae .reset_vars + inc eax + movzx ebx, word[WIN_STACK + eax * 2] + mov [WIN_POS + ebx * 2], ax + jmp .next_window_pos + + .reset_vars: + mov byte[KEY_COUNT], 0 + mov byte[BTN_COUNT], 0 + mov word[MOUSE_SCROLL_H], 0 + mov word[MOUSE_SCROLL_V], 0 + + pop ebx eax + ret + +align 4 +;------------------------------------------------------------------------------ +window._.check_window_draw: ;////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Check if window is necessary to draw +;------------------------------------------------------------------------------ +;> edi = pointer to WDATA +;------------------------------------------------------------------------------ + mov cl, [edi + WDATA.fl_wstyle] + and cl, 0x0f + cmp cl, 3 + je .exit.redraw ; window type 3 + cmp cl, 4 + je .exit.redraw ; window type 4 + + push eax ebx edx esi + + mov eax, edi + sub eax, window_data + shr eax, 5 + + movzx eax, word[WIN_STACK + eax * 2] ; get value of the curr process + lea esi, [WIN_POS + eax * 2] ; get address of this process at 0xC400 + + .next_window: + add esi, 2 + + mov eax, [TASK_COUNT] + lea eax, word[WIN_POS + eax * 2] ; number of the upper window + + cmp esi, eax + ja .exit.no_redraw + + movzx edx, word[esi] + shl edx, 5 + cmp [CURRENT_TASK + edx + TASKDATA.state], TSTATE_FREE + je .next_window + + mov eax, [edi + WDATA.box.top] + mov ebx, [edi + WDATA.box.height] + add ebx, eax + + mov ecx, [window_data + edx + WDATA.box.top] + cmp ecx, ebx + jge .next_window + add ecx, [window_data + edx + WDATA.box.height] + cmp eax, ecx + jge .next_window + + mov eax, [edi + WDATA.box.left] + mov ebx, [edi + WDATA.box.width] + add ebx, eax + + mov ecx, [window_data + edx + WDATA.box.left] + cmp ecx, ebx + jge .next_window + add ecx, [window_data + edx + WDATA.box.width] + cmp eax, ecx + jge .next_window + + pop esi edx ebx eax + + .exit.redraw: + xor ecx, ecx + inc ecx + ret + + .exit.no_redraw: + pop esi edx ebx eax + xor ecx, ecx + ret + +align 4 +;------------------------------------------------------------------------------ +window._.draw_window_caption: ;//////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + inc [mouse_pause] + call [_display.disable_mouse] + + xor eax, eax + mov edx, [TASK_COUNT] + movzx edx, word[WIN_POS + edx * 2] + cmp edx, [CURRENT_TASK] + jne @f + inc eax + @@: mov edx, [CURRENT_TASK] + shl edx, 5 + add edx, window_data + movzx ebx, [edx + WDATA.fl_wstyle] + and bl, 0x0F + cmp bl, 3 + je .draw_caption_style_3 + cmp bl, 4 + je .draw_caption_style_3 + + jmp .not_style_3 + + .draw_caption_style_3: + push edx + call drawwindow_IV_caption + add esp, 4 + jmp .2 + + .not_style_3: + cmp bl, 2 + jne .not_style_2 + + call drawwindow_III_caption + jmp .2 + + .not_style_2: + cmp bl, 0 + jne .2 + + call drawwindow_I_caption + + .2: mov edi, [CURRENT_TASK] + shl edi, 5 + test [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION + jz .exit + mov edx, [edi * 8 + SLOT_BASE + APPDATA.wnd_caption] + or edx, edx + jz .exit + + movzx eax, [edi + window_data + WDATA.fl_wstyle] + and al, 0x0F + cmp al, 3 + je .skinned + cmp al, 4 + je .skinned + + jmp .not_skinned + + .skinned: + mov ebp, [edi + window_data + WDATA.box.left - 2] + mov bp, word[edi + window_data + WDATA.box.top] + movzx eax, word[edi + window_data + WDATA.box.width] + sub ax, [_skinmargins.left] + sub ax, [_skinmargins.right] + push edx + cwde + cdq + mov ebx, 6 + idiv ebx + pop edx + or eax, eax + js .exit + + mov esi, eax + mov ebx, dword[_skinmargins.left - 2] + mov bx, word[_skinh] + sub bx, [_skinmargins.bottom] + sub bx, [_skinmargins.top] + sar bx, 1 + adc bx, 0 + add bx, [_skinmargins.top] + add bx, -3 + add ebx, ebp + jmp .dodraw + + .not_skinned: + cmp al, 1 + je .exit + + mov ebp, [edi + window_data + WDATA.box.left - 2] + mov bp, word[edi + window_data + WDATA.box.top] + movzx eax, word[edi + window_data + WDATA.box.width] + sub eax, 16 + push edx + cwde + cdq + mov ebx, 6 + idiv ebx + pop edx + or eax, eax + js .exit + + mov esi, eax + mov ebx, 0x00080007 + add ebx, ebp + + .dodraw: + mov ecx, [common_colours + 16] + or ecx, 0x80000000 + xor edi, edi + call dtext_asciiz_esi + + .exit: + dec [mouse_pause] + call [draw_pointer] + ret + +align 4 +;------------------------------------------------------------------------------ +window._.draw_negative_box: ;////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Draw negative box +;------------------------------------------------------------------------------ +;> edi = pointer to BOX struct +;------------------------------------------------------------------------------ + push eax ebx esi + mov eax, [edi + BOX.left - 2] + mov ax, word[edi + BOX.left] + add ax, word[edi + BOX.width] + mov ebx, [edi + BOX.top - 2] + mov bx, word[edi + BOX.top] + add bx, word[edi + BOX.height] + mov esi, 0x01000000 + call draw_rectangle.forced + pop esi ebx eax + ret diff --git a/kernel/branches/Kolibri-A/trunk/hid/keyboard.inc b/kernel/branches/Kolibri-A/trunk/hid/keyboard.inc index 9d6d0b836e..f56ca11139 100644 --- a/kernel/branches/Kolibri-A/trunk/hid/keyboard.inc +++ b/kernel/branches/Kolibri-A/trunk/hid/keyboard.inc @@ -177,6 +177,7 @@ irq1: mov eax,VKEY_SCRLOCK jmp .no_key.xor @@: + xor ebx, ebx test ch,ch js .writekey movzx eax,ch ; plain key @@ -200,7 +201,6 @@ irq1: jz @f mov bl,[keymap_alt+eax] @@: - mov bh, 0 jmp .writekey .modifier: test ch, ch diff --git a/kernel/branches/Kolibri-A/trunk/kernel.asm b/kernel/branches/Kolibri-A/trunk/kernel.asm index 823287a213..d268eaf5fe 100644 --- a/kernel/branches/Kolibri-A/trunk/kernel.asm +++ b/kernel/branches/Kolibri-A/trunk/kernel.asm @@ -553,6 +553,13 @@ v20ga32: mov al, 0x3F out 0xA1, al +; Enable interrupts in IDE controller + mov al, 0 + mov dx, 0x3F6 + out dx, al + mov dl, 0x76 + out dx, al + ;!!!!!!!!!!!!!!!!!!!!!!!!!! include 'detect/disks.inc' ;!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -2048,10 +2055,13 @@ sysfn_mouse_acceleration: ; 18.19 = set/get mouse features ; cmp ecx,4 ; set mouse pointer position dec ecx jnz .set_mouse_button - mov [MOUSE_Y],dx ;y - ror edx,16 - mov [MOUSE_X],dx ;x + cmp dx, word[Screen_Max_Y] + ja .end + rol edx,16 + cmp dx, word[Screen_Max_X] + ja .end + mov [MOUSE_X], edx ret .set_mouse_button: ; cmp ecx,5 ; set mouse button features @@ -2124,15 +2134,11 @@ endg iglobal version_inf: db 0,7,7,0 ; version 0.7.7.0 - db UID_KOLIBRI + db 0 ;reserved dd __REV__ version_end: endg -UID_NONE=0 -UID_MENUETOS=1 ;official -UID_KOLIBRI=2 ;russian - sys_cachetodiskette: cmp ebx, 1 jne .no_floppy_a_save @@ -2588,6 +2594,10 @@ sys_cpuusage: mov al, [ecx+window_data+WDATA.fl_wstate] stosb + ; Event mask (+71) + mov EAX, dword [ECX+CURRENT_TASK+TASKDATA.event_mask] + stosd + pop esi pop edi @@ -2720,11 +2730,6 @@ sys_redrawstat: mov eax, [Screen_Max_Y] mov [edx + RECT.bottom], eax - mov edi, [TASK_BASE] - or [edi - twdw + WDATA.fl_wdrawn], 1 ; no new position & buttons from app - call sys_window_mouse - ret - srl1: ret