diff --git a/kernel/trunk/PROC32.INC b/kernel/trunk/PROC32.INC new file mode 100644 index 0000000000..23c56b03c1 --- /dev/null +++ b/kernel/trunk/PROC32.INC @@ -0,0 +1,268 @@ + +; Macroinstructions for defining and calling procedures + +macro stdcall proc,[arg] ; directly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call proc } + +macro invoke proc,[arg] ; indirectly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call [proc] } + +macro ccall proc,[arg] ; directly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call proc + if size@ccall + add esp,size@ccall + end if } + +macro cinvoke proc,[arg] ; indirectly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call [proc] + if size@ccall + add esp,size@ccall + end if } + +macro proc [args] ; define procedure + { common + match name params, args> + \{ define@proc name, \{ prologue name,flag,parmbytes,localbytes,reglist \} + macro locals + \{ virtual at ebp-localbytes+current + macro label . \\{ deflocal@proc .,:, \\} + struc db [val] \\{ \common deflocal@proc .,db,val \\} + struc dw [val] \\{ \common deflocal@proc .,dw,val \\} + struc dp [val] \\{ \common deflocal@proc .,dp,val \\} + struc dd [val] \\{ \common deflocal@proc .,dd,val \\} + struc dt [val] \\{ \common deflocal@proc .,dt,val \\} + struc dq [val] \\{ \common deflocal@proc .,dq,val \\} + struc rb cnt \\{ deflocal@proc .,rb cnt, \\} + struc rw cnt \\{ deflocal@proc .,rw cnt, \\} + struc rp cnt \\{ deflocal@proc .,rp cnt, \\} + struc rd cnt \\{ deflocal@proc .,rd cnt, \\} + struc rt cnt \\{ deflocal@proc .,rt cnt, \\} + struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} + macro endl + \{ purge label + restruc db,dw,dp,dd,dt,dq + restruc rb,rw,rp,rd,rt,rq + restruc byte,word,dword,pword,tword,qword + current = $-(ebp-localbytes) + end virtual \} + macro ret operand + \{ match any, operand \\{ retn operand \\} + match , operand \\{ match epilogue:reglist, epilogue@proc: + \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} + macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 + end if \} } + +macro defargs@proc [arg] + { common + if ~ arg eq + forward + local ..arg,current@arg + match argname:type, arg + \{ current@arg equ argname + label ..arg type + argname equ ..arg + if dqword eq type + dd ?,?,?,? + else if tbyte eq type + dd ?,?,? + else if qword eq type | pword eq type + dd ?,? + else + dd ? + end if \} + match =current@arg,current@arg + \{ current@arg equ arg + arg equ ..arg + ..arg dd ? \} + common + args@proc equ current@arg + forward + restore current@arg + common + end if } + +macro deflocal@proc name,def,[val] + { common + match vars, all@vars \{ all@vars equ all@vars, \} + all@vars equ all@vars name + forward + local ..var,..tmp + ..var def val + match =?, val \{ ..tmp equ \} + match any =dup (=?), val \{ ..tmp equ \} + match tmp : value, ..tmp : val + \{ tmp: end virtual + initlocal@proc ..var,def value + virtual at tmp\} + common + match first rest, ..var, \{ name equ first \} } + +macro initlocal@proc name,def + { virtual at name + def + size@initlocal = $ - name + end virtual + position@initlocal = 0 + while size@initlocal > position@initlocal + virtual at name + def + if size@initlocal - position@initlocal < 2 + current@initlocal = 1 + load byte@initlocal byte from name+position@initlocal + else if size@initlocal - position@initlocal < 4 + current@initlocal = 2 + load word@initlocal word from name+position@initlocal + else + current@initlocal = 4 + load dword@initlocal dword from name+position@initlocal + end if + end virtual + if current@initlocal = 1 + mov byte [name+position@initlocal],byte@initlocal + else if current@initlocal = 2 + mov word [name+position@initlocal],word@initlocal + else + mov dword [name+position@initlocal],dword@initlocal + end if + position@initlocal = position@initlocal + current@initlocal + end while } + +macro endp + { purge ret,locals,endl + finish@proc + purge finish@proc + restore regs@proc + match all,args@proc \{ restore all \} + restore args@proc + match all,all@vars \{ restore all \} } + +macro local [var] + { common + locals + forward done@local equ + match varname[count]:vartype, var + \{ match =BYTE, vartype \\{ varname rb count + restore done@local \\} + match =WORD, vartype \\{ varname rw count + restore done@local \\} + match =DWORD, vartype \\{ varname rd count + restore done@local \\} + match =PWORD, vartype \\{ varname rp count + restore done@local \\} + match =QWORD, vartype \\{ varname rq count + restore done@local \\} + match =TBYTE, vartype \\{ varname rt count + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + rq count+count + restore done@local \\} + match , done@local \\{ virtual + varname vartype + end virtual + rb count*sizeof.\#vartype + restore done@local \\} \} + match :varname:vartype, done@local:var + \{ match =BYTE, vartype \\{ varname db ? + restore done@local \\} + match =WORD, vartype \\{ varname dw ? + restore done@local \\} + match =DWORD, vartype \\{ varname dd ? + restore done@local \\} + match =PWORD, vartype \\{ varname dp ? + restore done@local \\} + match =QWORD, vartype \\{ varname dq ? + restore done@local \\} + match =TBYTE, vartype \\{ varname dt ? + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + dq ?,? + restore done@local \\} + match , done@local \\{ varname vartype + restore done@local \\} \} + match ,done@local + \{ var + restore done@local \} + common + endl } diff --git a/kernel/trunk/boot/bootcode.inc b/kernel/trunk/boot/bootcode.inc index 168ae9d7aa..15ac49917c 100644 --- a/kernel/trunk/boot/bootcode.inc +++ b/kernel/trunk/boot/bootcode.inc @@ -364,8 +364,8 @@ sayerr: push 0 pop es and word [es:0x9031], 0 -; \begin{Mario79} -; find HDD IDE DMA PCI device +; \begin{Mario79} +; find HDD IDE DMA PCI device ; check for PCI BIOS mov ax, 0xB101 int 0x1A @@ -402,16 +402,16 @@ sayerr: and cx, 0xFFF0 ; clear address decode type mov [es:0x9031], cx .nopci: -; \end{Mario79} +; \end{Mario79} mov al,0xf6 ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå out 0x60,al xor cx,cx wait_loop: ; variant 2 ; reading state of port of 8042 controller - in al,64h + in al,64h and al,00000010b ; ready flag -; wait until 8042 controller is ready +; wait until 8042 controller is ready loopnz wait_loop ; --------------- APM --------------------- @@ -426,7 +426,7 @@ wait_loop: ; variant 2 jz apm_end ; APM 32-bit protected-mode interface not supported mov [es : 0x9044], ax ; Save APM Version mov [es : 0x9046], cx ; Save APM flags - + ; Write APM ver ---- and ax, 0xf0f add ax, '00' @@ -437,7 +437,7 @@ wait_loop: ; variant 2 call printplain _setcursor d80x25_top_num,0 ; ------------------ - + mov ax, 0x5304 ; Disconnect interface xor bx, bx int 0x15 @@ -462,7 +462,7 @@ wait_loop: ; variant 2 mov [apm_data_16 - 0x10000 + 4], dl mov [es : 0x9040], ebx ; offset of APM entry point apm_end: -; ----------------------------------------- +; ----------------------------------------- ; DISPLAY VESA INFORMATION @@ -474,6 +474,9 @@ apm_end: cmp ax,0x004f mov si, novesa-0x10000 jnz @f + mov bx, word [es:di+0x12] + shl ebx,16 + mov [es:0x9050], ebx mov ax,[es:di+4] add ax,'0'*256+'0' mov si,vervesa-0x10000 @@ -492,7 +495,7 @@ cfgmanager: mov di, preboot_graph-0x10000 ; check bootloader block cmp [.loader_block-0x10000], -1 - jz .noloaderblock + jz .noloaderblock les bx, [.loader_block-0x10000] cmp byte [es:bx], 1 mov si, loader_block_error-0x10000 @@ -824,7 +827,7 @@ end if mov al, 32 ; BPP jb @f mov [es:0x9000], al - mov dword [es:0x9018], 0x800000 + mov dword [es:0x9018], 0xFFFFFFFF; 0x800000 @@: mov [es:0x9008],bx mov [es:0x900A],cx @@ -1230,38 +1233,42 @@ sayerr_floppy: ; PAGE TABLE push dword [es:0x9018] - - map_mem equ 64 ; amount of memory to map - +; +; mmap_mem equ 64 ; amount of memory to map +; push 0x6000 pop es ; es:di = 6000:0 - xor di,di - mov cx,256*map_mem ; Map (mapmem) M -; initialize as identity mapping - xor eax, eax - call pagetable_set - - +; xor di,di +; mov cx,256*mmap_mem ; Map (mapmem) M +;; initialize as identity mapping +; xor eax, eax +; call pagetable_set +; +; ; 4 KB PAGE DIRECTORY +; + push 0x7F00 + pop es ; es:di = 7F00:0 +; xor di, di +; mov cx, 64 / 4 +; mov eax, 0x60007 ; for 0 M +; call pagetable_set +; xor si,si +; mov di,second_base_address shr 20 +; mov cx,64/2 +; rep movs word [es:di], [es:si] - push 0x7F00 - pop es ; es:di = 7F00:0 - xor di, di - mov cx, 64 / 4 - mov eax, 0x60007 ; for 0 M - call pagetable_set - xor si,si - mov di,second_base_address shr 20 - mov cx,64/2 - rep movs word [es:di], [es:si] - - mov eax, 0x7F000 +8+16 ; Page directory and enable caches - mov cr3, eax +; mov eax, 0x7F000 +8+16 ; Page directory and enable caches +; mov cr3, eax ; SET GRAPHICS pop es - mov ax,[es:0x9008] ; vga & 320x200 + + xor ax, ax + mov es, ax + + mov ax,[es:0x9008] ; vga & 320x200 mov bx, ax cmp ax,0x13 je setgr diff --git a/kernel/trunk/const.inc b/kernel/trunk/const.inc new file mode 100644 index 0000000000..59636a7220 --- /dev/null +++ b/kernel/trunk/const.inc @@ -0,0 +1,438 @@ + + +drw0 equ 10010010b ; data read/write dpl0 +drw3 equ 11110010b ; data read/write dpl3 +cpl0 equ 10011010b ; code read dpl0 +cpl3 equ 11111010b ; code read dpl3 + +D32 equ 01000000b ; 32bit segment +G32 equ 10000000b ; page gran + + +;;;;;;;;;;;;cpu_caps flags;;;;;;;;;;;;;;;; + +CPU_386 equ 3 +CPU_486 equ 4 +CPU_PENTIUM equ 5 +CPU_P6 equ 6 +CPU_PENTIUM4 equ 0x0F + +CAPS_FPU equ 00 ;on-chip x87 floating point unit +CAPS_VME equ 01 ;virtual-mode enhancements +CAPS_DE equ 02 ;debugging extensions +CAPS_PSE equ 03 ;page-size extensions +CAPS_TSC equ 04 ;time stamp counter +CAPS_MSR equ 05 ;model-specific registers +CAPS_PAE equ 06 ;physical-address extensions +CAPS_MCE equ 07 ;machine check exception +CAPS_CX8 equ 08 ;CMPXCHG8B instruction +CAPS_APIC equ 09 ;on-chip advanced programmable + ; interrupt controller +; 10 ;unused +CAPS_SEP equ 11 ;SYSENTER and SYSEXIT instructions +CAPS_MTRR equ 12 ;memory-type range registers +CAPS_PGE equ 13 ;page global extension +CAPS_MCA equ 14 ;machine check architecture +CAPS_CMOV equ 15 ;conditional move instructions +CAPS_PAT equ 16 ;page attribute table + +CAPS_PSE36 equ 17 ;page-size extensions +CAPS_PSN equ 18 ;processor serial number +CAPS_CLFLUSH equ 19 ;CLFUSH instruction + +CAPS_DS equ 21 ;debug store +CAPS_ACPI equ 22 ;thermal monitor and software + ;controlled clock supported +CAPS_MMX equ 23 ;MMX instructions +CAPS_FXSR equ 24 ;FXSAVE and FXRSTOR instructions +CAPS_SSE equ 25 ;SSE instructions +CAPS_SSE2 equ 26 ;SSE2 instructions +CAPS_SS equ 27 ;self-snoop +CAPS_HTT equ 28 ;hyper-threading technology +CAPS_TM equ 29 ;thermal monitor supported +CAPS_IA64 equ 30 ;IA64 capabilities +CAPS_PBE equ 31 ;pending break enable + +;ecx +CAPS_SSE3 equ 32 ;SSE3 instructions +; 33 +; 34 +CAPS_MONITOR equ 35 ;MONITOR/MWAIT instructions +CAPS_DS_CPL equ 36 ; +CAPS_VMX equ 37 ;virtual mode extensions +; 38 ; +CAPS_EST equ 39 ;enhansed speed step +CAPS_TM2 equ 40 ;thermal monitor2 supported +; 41 +CAPS_CID equ 42 ; +; 43 +; 44 +CAPS_CX16 equ 45 ;CMPXCHG16B instruction +CAPS_xTPR equ 46 ; +; +;reserved +; +;ext edx /ecx +CAPS_SYSCAL equ 64 ; +CAPS_XD equ 65 ;execution disable +CAPS_FFXSR equ 66 ; +CAPS_RDTSCP equ 67 ; +CAPS_X64 equ 68 ; +CAPS_3DNOW equ 69 ; +CAPS_3DNOWEXT equ 70 ; +CAPS_LAHF equ 71 ; +CAPS_CMP_LEG equ 72 ; +CAPS_SVM equ 73 ;secure virual machine +CAPS_ALTMOVCR8 equ 74 ; + + +CR4_VME equ 0x0001 +CR4_PVI equ 0x0002 +CR4_TSD equ 0x0004 +CR4_DE equ 0x0008 +CR4_PSE equ 0x0010 +CR4_PAE equ 0x0020 +CR4_MCE equ 0x0040 +CR4_PGE equ 0x0080 +CR4_PCE equ 0x0100 +CR4_OSFXSR equ 0x0200 +CR4_OSXMMEXPT equ 0x0400 + + + +OS_BASE equ 0; 0x80400000 + +window_data equ OS_BASE+0x0000000 + +CURRENT_TASK equ OS_BASE+0x0003000 +TASK_COUNT equ OS_BASE+0x0003004 +TASK_BASE equ OS_BASE+0x0003010 +TASK_DATA equ OS_BASE+0x0003020 +TASK_EVENT equ OS_BASE+0x0003020 + +save_syscall_data equ OS_BASE+0x0005000 + +;mouseunder equ OS_BASE+0x0006900 +FLOPPY_BUFF equ OS_BASE+0x0008000 +ACTIVE_PROC_STACK equ OS_BASE+0x000A400 +idts equ OS_BASE+0x000B100 +WIN_STACK equ OS_BASE+0x000C000 +WIN_POS equ OS_BASE+0x000C400 +FDD_DATA equ OS_BASE+0x000D000 + +ENABLE_TASKSWITCH equ OS_BASE+0x000E000 +PUTPIXEL equ OS_BASE+0x000E020 +GETPIXEL equ OS_BASE+0x000E024 +BANK_SWITCH equ OS_BASE+0x000E030 + +MOUSE_PICTURE equ OS_BASE+0x000F200 +MOUSE_VISIBLE equ OS_BASE+0x000F204 +XY_TEMP equ OS_BASE+0x000F300 +KEY_COUNT equ OS_BASE+0x000F400 +KEY_BUFF equ OS_BASE+0x000F401 + +BTN_COUNT equ OS_BASE+0x000F500 +BTN_BUFF equ OS_BASE+0x000F501 + +TSC equ OS_BASE+0x000F600 +MOUSE_PORT equ OS_BASE+0x000F604 + +PS2_CHUNK equ OS_BASE+0x000FB00 +MOUSE_X equ OS_BASE+0x000FB0A +MOUSE_Y equ OS_BASE+0x000FB0C + +MOUSE_COLOR_MEM equ OS_BASE+0x000FB10 +COLOR_TEMP equ OS_BASE+0x000FB30 +BTN_DOWN equ OS_BASE+0x000FB40 +MOUSE_DOWN equ OS_BASE+0x000FB44 +X_UNDER equ OS_BASE+0x000FB4A +Y_UNDER equ OS_BASE+0x000FB4C +;ScreenBPP equ OS_BASE+0x000FBF1 +MOUSE_BUFF_COUNT equ OS_BASE+0x000FCFF +HD_CACHE_ENT equ OS_BASE+0x000FE10 +LFBAddress equ OS_BASE+0x000FE80 +MEM_AMOUNT equ OS_BASE+0x000FE8C +LFBSize equ OS_BASE+0x02f9050 + +SCR_X_SIZE equ OS_BASE+0x000FE00 +SCR_Y_SIZE equ OS_BASE+0x000FE04 +SCR_BYTES_PER_LINE equ OS_BASE+0x000FE08 +SCR_MODE equ OS_BASE+0x000FE0C + +BTN_ADDR equ OS_BASE+0x000FE88 +SYS_SHUTDOWN equ OS_BASE+0x000FF00 +TASK_ACTIVATE equ OS_BASE+0x000FF01 + +REDRAW_BACKGROUND equ OS_BASE+0x000FFF0 +BANK_RW equ OS_BASE+0x000FFF2 +MOUSE_BACKGROUND equ OS_BASE+0x000FFF4 +DONT_DRAW_MOUSE equ OS_BASE+0x000FFF5 +DONT_SWITCH equ OS_BASE+0x000FFFF + +STACK_TOP equ OS_BASE+0x003EC00 + +FONT_II equ OS_BASE+0x003EC00 +FONT_I equ OS_BASE+0x003F600 +DISK_DATA equ OS_BASE+0x0040000 +PROC_BASE equ OS_BASE+0x0080000 +TMP_BUFF equ OS_BASE+0x0090000 + +VGABasePtr equ OS_BASE+0x00A0000 + +RAMDISK equ OS_BASE+0x0100000 +RAMDISK_FAT equ OS_BASE+0x0280000 +FLOPPY_FAT equ OS_BASE+0x0282000 +SB16_Status equ OS_BASE+0x02B0000 +BUTTON_INFO equ OS_BASE+0x02C0000 +RESERVED_PORTS equ OS_BASE+0x02D0000 +IRQ_SAVE equ OS_BASE+0x02E0000 +SYS_VAR equ OS_BASE+0x02f0000 +IMG_BACKGROUND equ OS_BASE+0x0300000 +WinMapAddress equ OS_BASE+0x0460000 +display_data equ OS_BASE+0x0460000 +HD_CACHE equ OS_BASE+0x0600000 +stack_data_start equ OS_BASE+0x0700000 +eth_data_start equ OS_BASE+0x0700000 +stack_data equ OS_BASE+0x0704000 +stack_data_end equ OS_BASE+0x071ffff +VMODE_BASE equ OS_BASE+0x0760000 +resendQ equ OS_BASE+0x0770000 + +;skin_data equ OS_BASE+0x0778000 + +draw_data equ OS_BASE+0x0800000 +sysint_stack_data equ OS_BASE+0x0803000 + +tss_data equ OS_BASE+0x0920000 + +;tmp_pg_dir equ OS_BASE+0x00050000 +;tmp_page_map equ 0x00051000 +;master_tab equ 0x80200000 + +pages_tab equ 0x60000000 +master_tab equ 0x60180000 + +sys_pgdir equ OS_BASE+0x00050000 +sys_master_tab equ OS_BASE+0x00051000 +sys_pgmap equ OS_BASE+0x00052000 + +;lfb_start equ 0x00800000 + +;new_app_pdir equ OS_BASE+0x01000000 +;new_app_master_table equ OS_BASE+0x01001000 +;new_app_ptable equ OS_BASE+0x01002000 + +new_app_base equ 0x60400000 + +twdw equ (CURRENT_TASK-window_data) + +std_application_base_address equ new_app_base + +PAGES_USED equ 4 + +PG_UNMAP equ 0x000 +PG_MAP equ 0x001 +PG_WRITE equ 0x002 +PG_SW equ 0x003 +PG_USER equ 0x005 +PG_UW equ 0x007 +PG_NOCACHE equ 0x018 +PG_LARGE equ 0x080 +PG_GLOBAL equ 0x100 + +;;;;;;;;;;;boot time variables + +;BOOT_BPP equ 0x9000 ;byte bits per pixel +BOOT_SCANLINE equ 0x9001 ;word scanline length +BOOT_VESA_MODE equ 0x9008 ;word vesa video mode +;;BOOT_X_RES equ 0x900A ;word X res +;;BOOT_Y_RES equ 0x900C ;word Y res +;;BOOT_MOUSE_PORT equ 0x9010 ;byte mouse port - not used +BOOT_BANK_SW equ 0x9014 ;dword Vesa 1.2 pm bank switch +BOOT_LFB equ 0x9018 ;dword Vesa 2.0 LFB address +BOOT_MTRR equ 0x901C ;byte 0 or 1 : enable MTRR graphics acceleration +BOOT_LOG equ 0x901D ;byte not used anymore (0 or 1 : enable system log display) +BOOT_DIRECT_LFB equ 0x901E ;byte 0 or 1 : enable direct lfb write, paging disabled +BOOT_PCI_DATA equ 0x9020 ;8bytes pci data +BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no +BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr +BOOT_MEM_AMOUNT equ 0x9034 ;dword memory amount + +TMP_FILE_NAME equ 0 +TMP_CMD_LINE equ 1024 +TMP_ICON_OFFS equ 1280 + + +EVENT_REDRAW equ 0x00000001 +EVENT_KEY equ 0x00000002 +EVENT_BUTTON equ 0x00000004 +EVENT_BACKGROUND equ 0x00000010 +EVENT_MOUSE equ 0x00000020 +EVENT_IPC equ 0x00000040 +EVENT_NETWORK equ 0x00000080 +EVENT_DEBUG equ 0x00000100 +EVENT_NOTIFY equ 0x00000200 + +EV_INTR equ 1 + +struc SYS_VARS +{ .bpp dd ? + .scanline dd ? + .vesa_mode dd ? + .x_res dd ? + .y_res dd ? + .cpu_caps dd ? + dd ? + dd ? + dd ? +} + + +struc BOOT_DATA +{ .bpp dd ? + .scanline dd ? + .vesa_mode dd ? + .x_res dd ? + .y_res dd ? + .mouse_port dd ? + .bank_switch dd ? + .lfb dd ? + .vesa_mem dd ? + .log dd ? + .direct_lfb dd ? + .pci_data dd ? +; dd ? + .vrr dd ? + .ide_base dd ? + .mem_amount dd ? + .pages_count dd ? + .pagemap_size dd ? + .kernel_max dd ? + .kernel_pages dd ? + .kernel_tables dd ? + + .cpu_vendor dd ? + dd ? + dd ? + .cpu_sign dd ? + .cpu_info dd ? + .cpu_caps dd ? + dd ? + dd ? +} + +virtual at 0 + BOOT_DATA BOOT_DATA +end virtual + +struc PG_DATA +{ .mem_amount dd ? + .vesa_mem dd ? + .pages_count dd ? + .pages_free dd ? + .pages_faults dd ? + .pagemap_size dd ? + .kernel_max dd ? + .kernel_pages dd ? + .kernel_tables dd ? + .sys_page_dir dd ? + .pg_mutex dd ? + .tmp_task_mutex dd ? +} + +struc LIB +{ .lib_name rb 16 + .lib_base dd ? + .lib_start dd ? + .export dd ? + .import dd ? +} + +struc SRV +{ .srv_name rb 16 + .magic dd ? + .size dd ? + .lib dd ? + .srv_proc dd ? +} + +struc COFF_HEADER +{ .machine dw ? + .nSections dw ? + .DataTime dd ? + .pSymTable dd ? + .nSymbols dd ? + .optHeader dw ? + .flags dw ? +}; + + +struc COFF_SECTION +{ .Name rb 8 + .VirtualSize dd ? + .VirtualAddress dd ? + .SizeOfRawData dd ? + .PtrRawData dd ? + .PtrReloc dd ? + .PtrLinenumbers dd ? + .NumReloc dw ? + .NumLinenum dw ? + .Characteristics dd ? +} + +struc COFF_RELOC +{ .VirtualAddress dd ? + .SymIndex dd ? + .Type dw ? +} + +struc COFF_SYM +{ .Name rb 8 + .Value dd ? + .SectionNumber dw ? + .Type dw ? + .StorageClass db ? + .NumAuxSymbols db ? +} + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + + +SRV_SIZE equ 32 + +virtual at 0 + LIB LIB +end virtual + +virtual at 0 + SRV SRV +end virtual + +virtual at 0 + CFS COFF_SECTION +end virtual + +virtual at 0 + CRELOC COFF_RELOC +end virtual + +virtual at 0 + CSYM COFF_SYM +end virtual + +virtual at 0 + CFH COFF_HEADER +end virtual + + diff --git a/kernel/trunk/core/dll.inc b/kernel/trunk/core/dll.inc new file mode 100644 index 0000000000..ba37bbcd60 --- /dev/null +++ b/kernel/trunk/core/dll.inc @@ -0,0 +1,616 @@ +; +; This file is part of the Infinity sound AC97 driver. +; (C) copyright Serge 2006 +; email: infinity_sound@mail.ru +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + +align 4 +proc attach_int_handler stdcall, irq:dword, handler:dword + + mov ebx, [irq] ;irq num + test ebx, ebx + jz .err + mov eax, [handler] + test eax, eax + jz .err + mov [irq_tab+ebx*4], eax + stdcall enable_irq, [irq] + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc detach_int_handler + + ret +endp + +align 4 +proc enable_irq stdcall, irq_line:dword + mov ebx, [irq_line] + mov edx, 0x21 + cmp ebx, 8 + jb @F + mov edx, 0xA1 + sub ebx,8 +@@: + in al,dx + btr eax, ebx + out dx, al + ret +endp + +align 16 +;; proc irq_serv + +irq_serv: + +.irq_1: + push eax + mov eax, 1 + jmp .main +align 4 +.irq_2: + push eax + mov eax, 2 + jmp .main +align 4 +.irq_3: + push eax + mov eax, 3 + jmp .main +align 4 +.irq_4: + push eax + mov eax, 4 + jmp .main +align 4 +.irq_5: + push eax + mov eax, 5 + jmp .main +align 4 +.irq_6: + push eax + mov eax, 6 + jmp .main +align 4 +.irq_7: + push eax + mov eax, 7 + jmp .main +align 4 +.irq_8: + push eax + mov eax, 8 + jmp .main +align 4 +.irq_9: + push eax + mov eax, 9 + jmp .main +align 4 +.irq_10: + push eax + mov eax, 10 + jmp .main +align 4 +.irq_11: + push eax + mov eax, 11 + jmp .main +align 4 +.irq_12: + push eax + mov eax, 12 + jmp .main +align 4 +.irq_13: + push eax + mov eax, 13 + jmp .main +align 4 +.irq_14: + push eax + mov eax, 14 + jmp .main +align 4 +.irq_15: + push eax + mov eax, 15 + jmp .main + +align 16 +.main: + save_ring3_context + mov bx, os_data + mov ds, bx + mov es, bx + + mov ebx, [irq_tab+eax*4] + test ebx, ebx + jz .exit + + call ebx + +.exit: + restore_ring3_context + + cmp eax, 8 + mov al, 0x20 + jb @f + out 0xa0, al +@@: + out 0x20, al + + pop eax + iret + +align 4 +proc get_notify stdcall, p_ev:dword + +.wait: + mov ebx,[CURRENT_TASK] + shl ebx,8 + test dword [ebx+PROC_BASE+0xA8],EVENT_NOTIFY + jz @f + and dword [ebx+PROC_BASE+0xA8], not EVENT_NOTIFY + mov edi, [p_ev] + mov dword [edi], EV_INTR + mov eax, [ebx+PROC_BASE+APPDATA.event] + mov dword [edi+4], eax + ret +@@: + call change_task + jmp .wait +endp + +align 4 +proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword + xor eax, eax + xor ebx, ebx + mov ah, byte [bus] + mov al, 6 + mov bh, byte [devfn] + mov bl, byte [reg] + call pci_read_reg + ret +endp + +align 4 +proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword + xor eax, eax + xor ebx, ebx + mov ah, byte [bus] + mov al, 4 + mov bh, byte [devfn] + mov bl, byte [reg] + call pci_read_reg + ret +endp + +align 4 +proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword + xor eax, eax + xor ebx, ebx + mov ah, byte [bus] + mov al, 8 + mov bh, byte [devfn] + mov bl, byte [reg] + mov ecx, [val] + call pci_write_reg + 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 srv_handler stdcall, ioctl:dword + mov esi, [ioctl] + test esi, esi + jz .err + + mov edi, [esi+handle] + cmp [edi+SRV.magic], ' SRV' + jne .fail + + cmp [edi+SRV.size], SRV_SIZE + jne .fail + + stdcall [edi+SRV.srv_proc], esi + ret +.fail: + xor eax, eax + not eax + mov [esi+output], eax + mov [esi+out_size], 4 + ret +.err: + xor eax, eax + not eax + ret +endp + +align 4 +proc srv_handlerEx stdcall, ioctl:dword + mov esi, [ioctl] + test esi, esi + jz .err + add esi, new_app_base + + mov edi, [esi+handle] + cmp [edi+SRV.magic], ' SRV' + jne .fail + + cmp [edi+SRV.size], SRV_SIZE + jne .fail + + add [esi+input], new_app_base + add [esi+output], new_app_base + + stdcall [edi+SRV.srv_proc], esi + ret +.fail: + xor eax, eax + not eax + mov [esi+output], eax + mov [esi+out_size], 4 + ret +.err: + xor eax, eax + not eax + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +align 4 +proc get_service stdcall, sz_name:dword + locals + srv_ptr dd ? + counter dd ? + endl + + mov eax, [sz_name] + test eax, eax + jz .fail + + mov [srv_ptr], srv_tab + mov [counter], 16 +@@: + stdcall strncmp, [srv_ptr], [sz_name], 16 + test eax, eax + je .ok + + add [srv_ptr], SRV_SIZE + dec [counter] + jnz @B +.not_load: + + stdcall find_service, [sz_name] + test eax, eax + jz .fail + + stdcall load_lib, eax + test eax, eax + jz .fail + + mov [srv_ptr], srv_tab + mov [counter], 16 +@@: + stdcall strncmp, [srv_ptr], [sz_name], 16 + test eax, eax + je .ok + + add [srv_ptr], SRV_SIZE + dec [counter] + jnz @B +.fail: + xor eax, eax + ret +.ok: + mov eax, [srv_ptr] + ret +endp + +align 4 +proc find_service stdcall ,sz_name:dword + + mov eax, [sz_name] + test eax, eax + jz .fail + + mov esi, services +@@: + mov eax, [esi] + test eax, eax + jz .fail + push esi + stdcall strncmp, eax, [sz_name], 16 + pop esi + test eax, eax + je .ok + + add esi, 8 + jmp @B +.ok: + mov eax, [esi+4] + ret +.fail: + xor eax, eax + ret +endp + +align 4 +proc reg_service stdcall, sz_name:dword, handler:dword + locals + srv dd ? + endl + + mov eax, [sz_name] + test eax, eax + jz .fail + + mov ebx, [handler] + test ebx, ebx + jz .fail + + call alloc_service + test eax, eax + jz .fail + + mov [srv], eax + mov edi, eax + mov esi, [sz_name] + mov ecx, 16 + rep movsb + + mov edi, eax + mov [edi+SRV.magic], ' SRV' + mov [edi+SRV.size], SRV_SIZE + mov ebx, [handler] + mov [edi+SRV.srv_proc], ebx + mov eax, [srv] + ret +.fail: + xor eax, eax + ret +endp + +align 4 +proc get_proc stdcall, exp:dword, sz_name:dword + + mov edx, [exp] +.next: + mov eax, [edx] + test eax, eax + jz .end + + push edx + stdcall strncmp, eax, [sz_name], 16 + pop edx + test eax, eax + jz .ok + + add edx,8 + jmp .next +.ok: + mov eax, [edx+4] +.end: + ret +endp + +align 4 +proc link_dll stdcall, exp:dword, imp:dword + mov esi, [imp] +.next: + mov eax, [esi] + test eax, eax + jz .end + + push esi + stdcall get_proc, [exp], eax + pop esi + + test eax, eax + jz @F + + mov [esi], eax +@@: + add esi, 4 + jmp .next +.end: + ret +endp + +align 4 +proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword + +@@: + stdcall strncmp, [pSym], [sz_sym], 8 + test eax,eax + jz .ok + add [pSym], 18 + dec [count] + jnz @b + xor eax, eax + ret +.ok: + mov ebx, [pSym] + mov eax, [ebx+8] + ret +endp + +align 4 +proc load_lib stdcall, name:dword + locals + lib dd ? + base dd ? + pSym dd ? + endl + + mov eax, [name] + mov ebx, 1 ;index of first block + mov ecx, 32 ;number of blocks + mov edx, TMP_BUFF ;temp area + mov esi, 12 ;file name length + + call fileread ;read file from RD + + cmp eax,0 + jne .err + +; mov eax, [TMP_BUFF+CFH.pSymTable] +; add eax, TMP_BUFF +; mov [pSym], eax + +; mov [TMP_BUFF+20+CFS.VirtualAddress], eax + + stdcall kernel_alloc, [TMP_BUFF+20+CFS.SizeOfRawData] + mov [base], eax + + test eax, eax + jnz @f +@@: + mov [TMP_BUFF+20+CFS.VirtualAddress], eax + mov ebx, [TMP_BUFF+CFH.pSymTable] + add ebx, TMP_BUFF + mov [pSym], ebx + + stdcall LinkSection, TMP_BUFF, TMP_BUFF+20, ebx + + mov edi, [base] + test edi, edi + jnz @f +@@: + mov esi, [TMP_BUFF+20+CFS.PtrRawData] + add esi, TMP_BUFF + mov ecx, [TMP_BUFF+20+CFS.SizeOfRawData] + rep movsb + + call alloc_dll + test eax, eax + jnz @f +@@: + mov [lib], eax + + mov edi, eax + mov esi, [name] + mov ecx, 16 + rep movsb + + stdcall get_coff_sym,[pSym],[TMP_BUFF+CFH.nSymbols],szSTART + mov edi, [lib] + add eax, [base] + mov [edi+LIB.lib_start], eax + mov ebx, [base] + mov [edi+LIB.lib_base], ebx + + stdcall get_coff_sym,[pSym],[TMP_BUFF+CFH.nSymbols], szEXPORTS + mov edi, [lib] + add eax, [base] + mov [edi+LIB.export], eax + + stdcall get_coff_sym,[pSym],[TMP_BUFF+CFH.nSymbols], szIMPORTS + mov edi, [lib] + add eax, [base] + mov [edi+LIB.import], eax + + stdcall link_dll, kernel_export, eax + + mov edi, [lib] + call [edi+LIB.lib_start] + + mov eax, [lib] + ret +.err: + xor eax, eax + ret + +endp + +align 4 +proc LinkSection stdcall, pCoff:dword, pSec:dword, pSym:dword + locals + pCode dd ? + endl + + mov esi, [pSec] + mov eax, [esi+CFS.PtrRawData] + add eax, [pCoff] + mov [pCode], eax + + mov edi, [esi+CFS.PtrReloc] + add edi, [pCoff] + + movzx edx, [esi+CFS.NumReloc] + mov eax, edx + lea edx, [edx+edx*8] + add edx, eax + add edx, edi +.l_0: + cmp edi, edx + jae .exit + + mov ebx, [edi+CRELOC.SymIndex] + add ebx,ebx + lea ebx,[ebx+ebx*8] + + add ebx, [pSym] + + mov ecx, [ebx+CSYM.Value] + add ecx, [esi+CFS.VirtualAddress] + + mov eax, [edi+CRELOC.VirtualAddress] + add eax, [pCode] + add [eax], ecx + add edi, 10 + jmp .l_0 + +.exit: + ret +endp + +proc get_curr_task + mov eax,[CURRENT_TASK] + shl eax, 8 + ret +endp + +drv_sound db 'UNISOUNDOBJ', 0 +drv_infinity db 'INFINITYOBJ', 0 + +szSound db 'SOUND',0 +szInfinity db 'INFINITY',0 + +szSTART db 'START',0 +szEXPORTS db 'EXPORTS',0 +szIMPORTS db 'IMPORTS',0 + +align 16 +services: + dd szSound, drv_sound + dd szInfinity, drv_infinity + dd 0 diff --git a/kernel/trunk/core/except.inc b/kernel/trunk/core/except.inc new file mode 100644 index 0000000000..08b724ff55 --- /dev/null +++ b/kernel/trunk/core/except.inc @@ -0,0 +1,64 @@ + + +reg_eip equ ebp+4 +reg_cs equ ebp+8 +reg_eflags equ ebp+12 +reg_esp equ ebp+16 +reg_ss equ ebp+20 +fpu_ctrl equ ebp-28 + +align 4 +except_16: + push ebp + mov ebp, esp + sub esp, 28 + + push eax + push ebx + push ecx + push edx + + mov ebx, [ss:CURRENT_TASK] + shl ebx, 8 + + mov eax, [ss:ebx+PROC_BASE+APPDATA.fpu_handler] + test eax, eax + jz .default + + mov ecx, [reg_eip] + mov edx, [reg_esp] + sub edx, 4 + mov [ss:edx+new_app_base], ecx + mov [reg_esp], edx + mov dword [reg_eip], eax + + pop edx + pop ecx + pop ebx + pop eax + + leave + iretd + +.default: + + fnstenv [fpu_ctrl] + fnclex + or word [fpu_ctrl], 0111111b + fldenv [fpu_ctrl] + + pop edx + pop ecx + pop ebx + pop eax + + leave + iretd + + +restore reg_eip +restore reg_cs +restore reg_eflags +restore reg_esp +restore reg_ss +restore fpu_ctrl diff --git a/kernel/trunk/core/exports.inc b/kernel/trunk/core/exports.inc new file mode 100644 index 0000000000..199d2198e0 --- /dev/null +++ b/kernel/trunk/core/exports.inc @@ -0,0 +1,45 @@ + +iglobal + +align 16 +kernel_export: + dd szAttachIntHandler, attach_int_handler + dd szSysMsgBoardStr , sys_msg_board_str + dd szPciApi , pci_api + dd szPciRead32 , pci_read32 + dd szPciRead8 , pci_read8 + dd szPciWrite8 , pci_write8 + dd szAllocKernelSpace, alloc_kernel_space + dd szMapPage , map_page + dd szRegService , reg_service + dd szKernelAlloc , kernel_alloc + dd szKernelFree , kernel_free + dd szGetPgAddr , get_pg_addr + dd szGetCurrentTask , get_curr_task + dd szGetService , get_service + dd szServiceHandler , srv_handler + dd szFpuSave , fpu_save + dd szFpuRestore , fpu_restore + dd 0 + + szKernel db 'KERNEL', 0 + szAttachIntHandler db 'AttachIntHandler',0 + szSysMsgBoardStr db 'SysMsgBoardStr', 0 + szPciApi db 'PciApi', 0 + szPciRead32 db 'PciRead32', 0 + szPciRead8 db 'PciRead8', 0 + szPciWrite8 db 'PciWrite8',0 + szAllocKernelSpace db 'AllocKernelSpace',0 + szMapPage db 'MapPage',0 + szRegService db 'RegService',0 + szKernelAlloc db 'KernelAlloc',0 + szKernelFree db 'KernelFree',0 + szGetPgAddr db 'GetPgAddr',0 + szGetCurrentTask db 'GetCurrentTask ',0 + szGetService db 'GetService',0 + szServiceHandler db 'ServiceHandler',0 + szFpuSave db 'FpuSave',0 + szFpuRestore db 'FpuRestore',0 + +endg + diff --git a/kernel/trunk/core/heap.inc b/kernel/trunk/core/heap.inc new file mode 100644 index 0000000000..0ec41a5d39 --- /dev/null +++ b/kernel/trunk/core/heap.inc @@ -0,0 +1,1117 @@ + +HEAP_BASE equ 0x01000000 +;HEAP_SIZE equ 0x01000000 + +struc MEM_BLOCK +{ .next_block dd ? + .prev_block dd ? ;+4 + .list_next dd ? ;+8 + .list_prev dd ? ;+12 + .base dd ? ;+16 + .size dd ? ;+20 + .flags dd ? ;+24 + .handle dd ? ;+28 +} + +FREE_BLOCK equ 4 +USED_BLOCK equ 8 + +virtual at 0 + MEM_BLOCK MEM_BLOCK +end virtual + +MEM_BLOCK_SIZE equ 8*4 + +block_next equ MEM_BLOCK.next_block +block_prev equ MEM_BLOCK.prev_block +list_next equ MEM_BLOCK.list_next +list_prev equ MEM_BLOCK.list_prev +block_base equ MEM_BLOCK.base +block_size equ MEM_BLOCK.size +block_flags equ MEM_BLOCK.flags + +macro calc_index op +{ shr op, 12 + dec op + cmp op, 63 + jna @f + mov op, 63 +@@: +} + +macro remove_from_list op +{ mov edx, [op+list_next] + mov ecx, [op+list_prev] + test edx, edx + jz @f + mov [edx+list_prev], ecx +@@: + test ecx, ecx + jz @f + mov [ecx+list_next], edx +@@: + mov [op+list_next],0 + mov [op+list_prev],0 +} + +macro remove_from_free op +{ + remove_from_list op + + mov eax, [op+block_size] + calc_index eax + cmp [mem_block_list+eax*4], op + jne @f + mov [mem_block_list+eax*4], edx +@@: + cmp [mem_block_list+eax*4], 0 + jne @f + btr [mem_block_mask], eax +@@: +} + +macro remove_from_used op +{ + remove_from_list op + cmp [mem_used_list], op + jne @f + mov [mem_used_list], edx +@@: +} + +align 4 +proc init_kernel_heap + + mov ecx, 64/4 + mov edi, mem_block_list + xor eax, eax + cld + rep stosd + + mov ecx, 512/4 + mov edi, mem_block_map + not eax + rep stosd + + mov [mem_block_start], mem_block_map + mov [mem_block_end], mem_block_map+512 + mov [mem_block_arr], HEAP_BASE + + stdcall alloc_pages, dword 32 + mov ecx, 32 + mov edx, eax + mov edi, HEAP_BASE + +.l1: + stdcall map_page,edi,edx,PG_SW + add edi, 0x1000 + add edx, 0x1000 + dec ecx + jnz .l1 + + mov edi, HEAP_BASE + mov ebx, edi + add ebx, MEM_BLOCK_SIZE + xor eax, eax + mov [edi+block_next], ebx + mov [edi+block_prev], eax + mov [edi+list_next], eax + mov [edi+list_prev], eax + mov [edi+block_base], HEAP_BASE + mov [edi+block_size], 4096*MEM_BLOCK_SIZE + mov [edi+block_flags], USED_BLOCK + + mov [ebx+block_next], eax + mov [ebx+block_prev], eax + mov [ebx+list_next], eax + mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE + + mov ecx, [MEM_AMOUNT] + sub ecx, 0x00C00000 + 4096*MEM_BLOCK_SIZE + mov [ebx+block_size], ecx + mov [ebx+block_flags], FREE_BLOCK + + mov [mem_block_mask], eax + mov [mem_block_mask+4],0x80000000 + + mov [mem_used_list], eax + mov [mem_block_list+63*4], ebx + mov byte [mem_block_map], 0xFC + ret +endp + +align 4 +proc get_block stdcall, index:dword + + mov eax, 63 + mov ecx, [index] + cmp ecx, eax + jna @f + ;cmova ecx, eax + mov ecx, eax +@@: + xor esi, esi + xor ebx, ebx + xor edx, edx + not edx + + cmp ecx, 32 + jb .bit_test + + sub ecx, 32 + add ebx, 32 + add esi, 4 + +.bit_test: + shl edx, cl + and edx, [mem_block_mask+esi] + jz .high_mask + bsf eax, edx + add ebx, eax + mov eax, [mem_block_list+ebx*4] + ret + +.high_mask: + + add esi, 4 + add ebx, 32 + test esi, 0xFFFFFFF8 + jnz .big_error + mov edx, [mem_block_mask+esi] + and edx, edx + jz .high_mask + bsf eax, edx + add ebx, eax + mov eax, [mem_block_list+ebx*4] + ret + +.big_error: + xor eax, eax + ret +endp + + +align 4 +proc alloc_mem_block + + pushfd + cli + mov ebx, [mem_block_start] + mov ecx, [mem_block_end] +.l1: + bsf eax,[ebx]; + jnz found + add ebx,4 + cmp ebx, ecx + jb .l1 + popfd + xor eax,eax + ret + +found: + btr [ebx], eax + mov [mem_block_start],ebx + sub ebx, mem_block_map + shl ebx, 3 + add eax,ebx + shl eax, 5 + add eax, [mem_block_arr] + popfd + ret +endp + +proc free_mem_block + pushfd + cli + sub eax, [mem_block_arr] + shr eax, 5 + + mov ebx, mem_block_map + bts [ebx], eax + shr eax, 3 + and eax, not 3 + add eax, ebx + cmp [mem_block_start], eax + ja @f + popfd + ret +@@: + mov [mem_block_start], eax + popfd + ret +.err: + xor eax, eax + popfd + ret +endp + +align 4 +proc alloc_kernel_space stdcall, size:dword + local block_ind:DWORD + + pushfd + cli + + mov eax, [size] + add eax, 0xFFF + and eax, 0xFFFFF000; + mov [size], eax + + shr eax, 12 + sub eax, 1 + + mov [block_ind], eax + + stdcall get_block, eax + and eax, eax + jz .error + + mov edi, eax ;edi - pBlock + + cmp [edi+block_flags], FREE_BLOCK + jne .error + + mov [block_ind], ebx ;index of allocated block + + mov eax, [edi+block_size] + cmp eax, [size] + je .m_eq_size + + call alloc_mem_block + and eax, eax + jz .error + + mov esi, eax ;esi - splitted block + + mov [esi+block_next], edi + mov eax, [edi+block_prev] + mov [esi+block_prev], eax + mov [edi+block_prev], esi + mov [esi+list_next], 0 + mov [esi+list_prev], 0 + and eax, eax + jz @f + mov [eax+block_next], esi +@@: + mov ebx, [edi+block_base] + mov [esi+block_base], ebx + mov edx, [size] + mov [esi+block_size], edx + add [edi+block_base], edx + sub [edi+block_size], edx + + mov eax, [edi+block_size] + shr eax, 12 + sub eax, 1 + cmp eax, 63 + jna @f + mov eax, 63 +@@: + cmp eax, [block_ind] + je .m_eq_ind + + mov ebx, [edi+list_next] + test ebx, ebx + jz @f + + mov [ebx+list_prev], edi +@@: + mov ecx, [block_ind] + mov [mem_block_list+ecx*4], ebx + + and ebx, ebx + jnz @f + btr [mem_block_mask], ecx +@@: + mov edx, [mem_block_list+eax*4] + mov [edi+list_next], edx + test edx, edx + jz @f + mov [edx+list_prev], edi +@@: + mov [mem_block_list+eax*4], edi + bts [mem_block_mask], eax +.m_eq_ind: + mov ebx, [mem_used_list] + mov [esi+list_next], ebx + test ebx, ebx + jz @f + mov [ebx+list_prev], esi +@@: + mov [esi+block_flags], USED_BLOCK + mov [mem_used_list], esi + mov eax, [esi+block_base] + popfd + ret + +.m_eq_size: + remove_from_list edi + mov [mem_block_list+ecx*4], edx + and edx, edx + jnz @f + mov ecx, [block_ind] + btr [mem_block_mask], ecx +@@: + mov ebx, [mem_used_list] + mov [edi+list_next], ebx + test ebx, ebx + jnz @f + mov [ebx+list_prev], edi +@@: + mov [mem_used_list], edi + mov [edi+block_flags], USED_BLOCK + mov eax, [edi+block_base] + popfd + ret +.error: + xor eax, eax + popfd + ret +endp + +align 4 +proc free_kernel_space stdcall, base:dword + + mov eax, [base] + mov esi, [mem_used_list] +@@: + test esi, esi + jz .fail + + cmp [esi+block_base], eax + je .found + mov esi, [esi+list_next] + jmp @b +.found: + cmp [esi+block_flags], USED_BLOCK + jne .fail + + mov edi, [esi+block_next] + test edi, edi + jz .prev + + cmp [edi+block_flags], FREE_BLOCK + jne .prev + + remove_from_free edi + + mov edx, [edi+block_next] + mov [esi+block_next], edx + test edx, edx + jz @f + + mov [edx+block_prev], esi +@@: + mov ecx, [edi+block_size] + add [esi+block_size], ecx + + mov eax, edi + call free_mem_block +.prev: + mov edi, [esi+block_prev] + test edi, edi + jz .insert + + cmp [edi+block_flags], FREE_BLOCK + jne .insert + + remove_from_used esi + + mov edx, [esi+block_next] + mov [edi+block_next], edx + test edx, edx + jz @f + mov [edx+block_prev], edi +@@: + mov eax, esi + call free_mem_block + + mov ecx, [edi+block_size] + mov eax, [esi+block_size] + add eax, ecx + mov [edi+block_size], eax + + calc_index eax + calc_index ecx + cmp eax, ecx + je .m_eq + + push ecx + remove_from_list edi + pop ecx + + cmp [mem_block_list+ecx*4], edi + jne @f + mov [mem_block_list+ecx*4], edx +@@: + cmp [mem_block_list+ecx*4], 0 + jne @f + btr [mem_block_mask], ecx +@@: + mov esi, [mem_block_list+eax*4] + mov [mem_block_list+eax*4], edi + mov [edi+list_next], esi + test esi, esi + jz @f + mov [esi+list_prev], edi +@@: + bts [mem_block_mask], eax +.m_eq: + xor eax, eax + not eax + ret +.insert: + remove_from_used esi + + mov eax, [esi+block_size] + calc_index eax + + mov edi, [mem_block_list+eax*4] + mov [mem_block_list+eax*4], esi + mov [esi+list_next], edi + test edi, edi + jz @f + mov [edi+list_prev], esi +@@: + bts [mem_block_mask], eax + mov [esi+block_flags],FREE_BLOCK + xor eax, eax + not eax + ret +.fail: + xor eax, eax + ret +endp + +align 4 +proc kernel_alloc stdcall, size:dword + locals + lin_addr dd ? + pages_count dd ? + endl + + mov eax, [size] + add eax, 0xFFF + and eax, 0xFFFFF000; + mov [size], eax + and eax, eax + jz .error + mov ebx, eax + shr ebx, 12 + mov [pages_count], ebx + + stdcall alloc_kernel_space, eax + and eax, eax + jz .error + mov [lin_addr], eax + + mov ecx, [pages_count] + mov edx, eax + mov ebx, ecx + + shr ecx, 3 + jz .next + + and ebx, not 7 + push ebx + stdcall alloc_pages, ebx + pop ecx ; yes ecx!!! + and eax, eax + jz .error + + mov edi, eax + mov edx, [lin_addr] +@@: + stdcall map_page,edx,edi,dword PG_SW + add edx, 0x1000 + add edi, 0x1000 + dec ecx + jnz @B +.next: + mov ecx, [pages_count] + and ecx, 7 + jz .end + +@@: push ecx + call alloc_page + pop ecx + test eax, eax + jz .error + + stdcall map_page,edx,eax,dword PG_SW + add edx, 0x1000 + dec ecx + jnz @B +.end: + mov eax, [lin_addr] + ret + +.error: + xor eax, eax + ret +endp + +align 4 +proc kernel_free stdcall, base:dword + locals + size dd ? + endl + + mov eax, [base] + mov esi, [mem_used_list] +@@: + test esi, esi + jz .fail + + cmp [esi+block_base], eax + je .found + mov esi, [esi+list_next] + jmp @b +.found: + cmp [esi+block_flags], USED_BLOCK + jne .fail + + mov ecx, [esi+block_size]; + mov [size], ecx + + stdcall free_kernel_space, [base] + test eax, eax + jz .fail + + mov ecx, [size] + mov edi, [base] + + shr ecx, 12 + mov esi, edi + shr edi, 10 + add edi, pages_tab + xor edx, edx +.release: + mov eax, [edi] + test eax, 1 + jz .next + + call free_page + mov [edi],edx +.next: + invlpg [esi] + add esi, 0x1000 + add edi, 4 + dec ecx + jnz .release +.fail: + ret +endp + +restore block_next +restore block_prev +restore block_list +restore block_base +restore block_size +restore block_flags + +;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; + +align 4 +proc init_heap stdcall, heap_size:dword + locals + tab_count dd ? + endl + + mov edx, [heap_size] + and edx, edx + jz .exit + add edx, 4095 + and edx, not 4095 + mov [heap_size], edx + add edx, 0x003FFFFF + and edx, not 0x003FFFFF + shr edx, 22 + mov [tab_count], edx + + mov ebx,[CURRENT_TASK] + shl ebx,8 + mov esi, [PROC_BASE+0x8c+ebx] + add esi, 0x003FFFFF + and esi, not 0x003FFFFF + mov edi, esi + mov [PROC_BASE+0x18+ebx], esi + add esi, [heap_size] + mov [PROC_BASE+0x1C+ebx], esi + + mov eax, cr3 + and eax, not 0xFFF + stdcall map_page,[current_pdir],eax,dword PG_SW + + add edi, new_app_base +@@: + call alloc_page + test eax, eax + jz .exit + + stdcall map_page_table, [current_pdir], edi, eax + add edi, 0x00400000 + dec edx + jnz @B + + mov ecx, [tab_count] + shl ecx, 12-2 + mov ebx,[CURRENT_TASK] + shl ebx,8 + mov edi, [PROC_BASE+0x18+ebx] + add edi, new_app_base + shr edi, 10 + mov esi, edi + add edi, pages_tab + xor eax, eax + cld + rep stosd + + stdcall map_page,[current_pdir],dword PG_UNMAP + + mov ebx, [heap_size] + mov eax, ebx + sub eax, 4096 + or ebx, FREE_BLOCK + mov [pages_tab+esi], ebx + + ret +.exit: + xor eax, eax + ret +endp + +align 4 +proc user_alloc stdcall, alloc_size:dword + + mov ecx, [alloc_size] + add ecx, (4095+4096) + and ecx, not 4095 + + mov ebx, [CURRENT_TASK] + shl ebx, 8 + mov esi, dword [ebx+PROC_BASE+0x18]; heap_base + mov edi, dword [ebx+PROC_BASE+0x1C]; heap_top + add esi, new_app_base + add edi, new_app_base + +l_0: + cmp esi, edi + jae m_exit + + mov ebx, esi + shr ebx, 12 + mov eax, [pages_tab+ebx*4] + test eax, FREE_BLOCK + jz test_used + and eax, 0xFFFFF000 + cmp eax, ecx ;alloc_size + jb m_next + + mov edx, esi + add edx, ecx + sub eax, ecx; + or eax, FREE_BLOCK + shr edx, 12 + mov [pages_tab+edx*4], eax + + or ecx, USED_BLOCK + mov [pages_tab+ebx*4], ecx + shr ecx, 12 + dec ecx + inc ebx +@@: + mov dword [pages_tab+ebx*4], 2 + inc ebx + dec ecx + jnz @B + + mov eax, esi + add eax, 4096 + sub eax, new_app_base + ret +m_next: + add esi, eax + jmp l_0 +test_used: + test eax, USED_BLOCK + jz m_exit + + and eax, 0xFFFFF000 + add esi, eax + jmp l_0 +m_exit: + xor eax, eax + ret +endp + +align 4 +proc user_free stdcall, base:dword + + mov esi, [base] + test esi, esi + jz .exit + + sub esi, 4096 + shr esi, 12 + mov eax, [pages_tab+esi*4] + test eax, USED_BLOCK + jz @f + + and eax, not 4095 + mov ecx, eax + or eax, FREE_BLOCK + mov [pages_tab+esi*4], eax + inc esi + sub ecx, 4096 + shr ecx, 12 +.release: + mov eax, [pages_tab+esi*4] + call free_page + inc esi + dec ecx + jnz .release +@@: + mov ebx, [CURRENT_TASK] + shl ebx, 8 + mov esi, dword [ebx+PROC_BASE+0x18]; heap_base + mov edi, dword [ebx+PROC_BASE+0x1C]; heap_top + shr esi, 12 + shr edi, 12 +@@: + mov eax, [pages_tab+esi*4] + test eax, USED_BLOCK + jz .test_free + shr eax, 12 + add esi, eax + jmp @B +.test_free: + test eax, FREE_BLOCK + jz .err + mov edx, eax + shr edx, 12 + add edx, esi + cmp edx, edi + jae .exit + + mov ebx, [pages_tab+edx*4] + test ebx, USED_BLOCK + jz .next_free + + shr ebx, 12 + add edx, ebx + mov esi, edx + jmp @B +.next_free: + test ebx, FREE_BLOCK + jz .err + and dword [pages_tab+edx*4], 0 + add eax, ebx + and eax, not 4095 + or eax, FREE_BLOCK + mov [pages_tab+esi*4], eax + jmp @B +.exit: + xor eax, eax + inc eax + ret +.err: + xor eax, eax + ret +endp + + +;proc new_mem_resize stdcall, new_size:dword +; +; stdcall wait_mutex, pg_data.pg_mutex +; +; mov edi, [new_size] +; add edi,4095 +; and edi,not 4095 +; mov [new_size], edi + +; mov edx,[CURRENT_TASK] +; shl edx,8 +; mov esi, [PROC_BASE+0x8c+edx] +; add esi, 4095 +; and esi, not 4095 + +; cmp edi, esi +; jae .expand + +; shr edi, 12 +; shr esi, 12 +; +;@@: mov eax, [pages_tab+0x4000+edi*4] +; test eax, 1 +; jz .next +; mov dword [pages_tab+0x4000+edi*4], 2 +; mov ebx, edi +; shl ebx, 12 +; invlpg [ebx+std_application_base_address] +; call free_page +; +;.next: add edi, 1 +; cmp edi, esi +; jb @B +; +;.update_size: + +; mov ebx, [new_size] +; mov [PROC_BASE+0x8c+edx],ebx +; +;;search threads and update +;;application memory size infomation +; mov ecx,[PROC_BASE+0xb8+edx] +; mov eax,2 + +;.search_threads: +;;eax = current slot +;;ebx = new memory size +;;ecx = page directory +; cmp eax,[TASK_COUNT] +; jg .search_threads_end +; mov edx,eax +; shl edx,5 +; cmp word [CURRENT_TASK+edx+0xa],9 ;if slot empty? +; jz .search_threads_next +; shl edx,3 +; cmp [PROC_BASE+edx+0xb8],ecx ;if it is our thread? +; jnz .search_threads_next +; mov [PROC_BASE+edx+0x8c],ebx ;update memory size +;.search_threads_next: +; inc eax +; jmp .search_threads +;.search_threads_end: +; xor eax, eax +; dec [pg_data.pg_mutex] +; ret +; +; +;.expand: +; add edi, new_app_base +; add esi, new_app_base +; +;.grow: call alloc_page +; test eax, eax +; jz .exit +; stdcall map_page,esi,eax,dword PG_UW + +; push edi +; mov edi, esi +; xor eax, eax +; mov ecx, 1024 +; cld +; rep stosd +; pop edi + +; add esi, 0x1000 +; cmp esi, edi +; jna .grow +; jmp .update_size +;.exit: +; xor eax, eax +; inc eax +; dec [pg_data.pg_mutex] +; ret +;endp + + +align 4 +proc alloc_dll + pushf + cli + bsf eax, [dll_map] + jnz .find + popf + xor eax, eax + ret +.find: + btr [dll_map], eax + popf + shl eax, 5 + add eax, dll_tab + ret +endp + +align 4 +proc alloc_service + pushf + cli + bsf eax, [srv_map] + jnz .find + popf + xor eax, eax + ret + +.find: btr [srv_map], eax + popf + shl eax,5 + add eax, srv_tab + ret +endp + +if NEW + +align 16 +new_services: + cmp eax, 10 + jb .fail + ja @f + + push dword [ebp+8+new_app_base] + call get_mem_info + mov [esp+36], eax + ret +@@: + cmp eax, 11 + ja @f + + push dword [ebp+8+new_app_base] + call init_heap + mov [esp+36], eax + ret +@@: + cmp eax, 12 + ja @f + + push dword [ebp+8+new_app_base] + call user_alloc + mov [esp+36], eax + ret +@@: + cmp eax, 13 + ja @f + + push dword [ebp+8+new_app_base] + call user_free + mov [esp+36], eax + ret + +@@: + cmp eax, 14 + ja @f + mov eax, [ebp+8+new_app_base] + add eax,new_app_base + stdcall get_notify, eax + ret +;@@: +; cmp eax, 15 +; ja @f +; call set_notify +; ret +@@: + cmp eax, 16 + ja @f + + mov eax, [ebp+8+new_app_base] + add eax, new_app_base + stdcall get_service, eax + mov [esp+36], eax + ret +@@: + cmp eax, 17 + ja @f + stdcall srv_handler,[ebp+8+new_app_base],\ + [ebp+12+new_app_base],\ + [ebp+16+new_app_base] + mov [esp+36], eax + ret +;@@: +; cmp eax, 20 +; ja @f +; call CreateSound +; mov [esp+36], eax +; ret + +@@: +.fail: + xor eax, eax + mov [esp+36], eax + ret + +proc strncmp stdcall, str1:dword, str2:dword, count:dword + + mov ecx,[count] + jecxz .end + + mov ebx,ecx + + mov edi,[str1] + mov esi,edi + xor eax,eax + repne scasb + neg ecx ; cx = count - strlen + add ecx,ebx ; strlen + count - strlen + +.okay: + mov edi,esi + mov esi,[str2] + repe cmpsb + mov al,[esi-1] + xor ecx,ecx + + cmp al,[edi-1] + ja .str2_big + je .end + +.str1_big: + sub ecx,2 + +.str2_big: + not ecx +.end: + mov eax,ecx + ret +endp + + +proc get_proc stdcall, exp:dword, sz_name:dword + + mov edx, [exp] +.next: + mov eax, [edx] + test eax, eax + jz .end + + push edx + stdcall strncmp, eax, [sz_name], 16 + pop edx + test eax, eax + jz .ok + + add edx,8 + jmp .next +.ok: + mov eax, [edx+4] +.end: + ret +endp + +proc link_dll stdcall, exp:dword, imp:dword + mov esi, [imp] + +.next: + mov eax, [esi] + test eax, eax + jz .end + + push esi + stdcall get_proc, [exp], eax + pop esi + + test eax, eax + jz @F + + mov [esi], eax +@@: + add esi, 4 + jmp .next +.end: + ret +endp + +end if + + + diff --git a/kernel/trunk/core/memory.inc b/kernel/trunk/core/memory.inc new file mode 100644 index 0000000000..51ac3e77e1 --- /dev/null +++ b/kernel/trunk/core/memory.inc @@ -0,0 +1,1417 @@ + +tmp_page_tab equ 0x01000000 + +align 4 +proc mem_test + mov eax, cr0 + or eax, 0x60000000 ;disable caching + mov cr0, eax + wbinvd ;invalidate cache + + xor edi, edi + mov ebx, 'TEST' +@@: + add edi, 0x400000 + xchg ebx, dword [edi] + cmp dword [edi], 'TEST' + xchg ebx, dword [edi] + je @b + + and eax, 0x21 + mov cr0, eax + mov eax, edi + ret +endp + +align 4 +proc init_memEx + xor eax, eax + mov edi, sys_pgdir + mov ecx, 2048 + rep stosd + + bt [cpu_caps], CAPS_PSE + jnc .no_PSE + + mov ebx, cr4 + or ebx, CR4_PSE + mov eax, PG_LARGE+PG_SW + bt [cpu_caps], CAPS_PGE + jnc @F + or eax, PG_GLOBAL + or ebx, CR4_PGE +@@: + mov dword [sys_pgdir], eax + add eax, 0x00400000 + mov dword [sys_pgdir+4], eax + add eax, 0x00400000 + mov dword [sys_pgdir+8], eax + add eax, 0x00400000 + mov dword [sys_pgdir+12], eax + + mov dword [sys_pgdir+0x600], sys_master_tab+PG_SW + mov dword [sys_master_tab+0x600], sys_master_tab+PG_SW + + mov cr4, ebx + + mov ecx, [pg_data.kernel_tables] + sub ecx, 4 + mov eax, tmp_page_tab+PG_SW + mov edi, sys_pgdir+16 + mov esi, sys_master_tab+16 + + jmp .map_kernel_tabs +.no_PSE: + mov eax, PG_SW + mov esi, tmp_page_tab + mov ecx, 4096/4 ;0x0 - 0x00FFFFFF +.map_low: + mov [esi], eax + add eax, 0x1000 + mov [esi+4], eax + add eax, 0x1000 + mov [esi+8], eax + add eax, 0x1000 + mov [esi+12], eax + add eax, 0x1000 + add esi, 16 + dec ecx + jnz .map_low ;ÿäðî + + mov ecx, [pg_data.kernel_tables] + mov eax, tmp_page_tab+PG_SW + mov edi, sys_pgdir + mov esi, sys_master_tab + +.map_kernel_tabs: + + mov [edi], eax + mov [esi], eax + add eax, 0x1000 + add edi, 4 + add esi, 4 + dec ecx + jnz .map_kernel_tabs + + mov edi, tmp_page_tab + bt [cpu_caps], CAPS_PSE + jc @F + add edi, 4096*4 ;skip low kernel memory +@@: + mov ecx, [pg_data.kernel_tables] + sub ecx, 4 + shl ecx, 10 + xor eax, eax + cld + rep stosd + + mov dword [sys_pgdir+0x600], sys_master_tab+PG_SW + mov dword [sys_master_tab+0x600], sys_master_tab+PG_SW + ret +endp + +;align 4 +;proc init_mem +; +; xor eax, eax +; mov edi, sys_pgdir +; mov ecx, 2048 +; rep stosd +; +; bt [cpu_caps], CAPS_PSE +; jc .use_PSE +; +; mov eax, PG_SW +; mov esi, tmp_page_tab +; mov ecx, 4096/4 ;0x0 - 0x00FFFFFF +; +;.map_low: +; mov [esi], eax +; add eax, 0x1000 +; mov [esi+4], eax +; add eax, 0x1000 +; mov [esi+8], eax +; add eax, 0x1000 +; mov [esi+12], eax +; add eax, 0x1000 +; add esi, 16 +; dec ecx +; jnz .map_low ;ÿäðî + +; mov eax, tmp_page_tab+PG_SW +; mov ecx, 4 +; xor ebx, ebx + +;.map_page_tables: +; mov [sys_pgdir+ebx], eax +; mov [sys_master_tab+ebx], eax +; add eax, 0x1000 +; add ebx, 4 +; dec ecx +; jnz .map_page_tables + +; mov dword [sys_pgdir+0x600], sys_master_tab+PG_SW +; mov dword [sys_master_tab+0x600], sys_master_tab+PG_SW + +; ret + +;.use_PSE: +; mov ebx, cr4 +; or ebx, CR4_PSE +; mov eax, PG_LARGE+PG_SW +; bt [cpu_caps], CAPS_PGE +; jnc @F +; or eax, PG_GLOBAL +; or ebx, CR4_PGE +;@@: +; mov dword [sys_pgdir], eax +; add eax, 0x00400000 +; mov dword [sys_pgdir+4], eax +; add eax, 0x00400000 +; mov dword [sys_pgdir+8], eax +; add eax, 0x00400000 +; mov dword [sys_pgdir+12], eax +; +; mov dword [sys_pgdir+0x600], sys_master_tab+PG_SW +; mov dword [sys_master_tab+0x600], sys_master_tab+PG_SW + +; mov cr4, ebx +; ret +;endp + +align 4 +proc init_page_map + mov edi, sys_pgmap + mov ecx, 512/4 + xor eax,eax + cld + rep stosd + + not eax + mov ecx, [pg_data.pagemap_size] + sub ecx, 512 + shr ecx, 2 + rep stosd + + mov edi, sys_pgmap+512 + mov edx, [pg_data.pages_count] + mov ecx, [pg_data.kernel_tables] + bt [cpu_caps], CAPS_PSE + jnc @f + sub ecx, 4 +@@: + sub edx, 4096 + sub edx, ecx + mov [pg_data.pages_free], edx + + xor eax, eax + mov ebx, ecx + shr ecx, 5 + rep stosd + + not eax + mov ecx, ebx + and ecx, 31 + shl eax, cl + stosd + + mov [page_start], sys_pgmap+512 + mov ebx, sys_pgmap + add ebx, [pg_data.pagemap_size] + mov [page_end], ebx + + mov [pg_data.pg_mutex], 0 + + ret +endp + +;align 4 +;proc init_pg_mem +; +; mov edi, sys_pgmap +; mov ecx, 512/4 +; xor eax,eax +; cld +; rep stosd +; +; not eax +; mov ecx, [pg_data.pagemap_size] +; sub ecx, 512 +; shr ecx, 2 +; rep stosd +; +; shl eax, PAGES_USED +; mov [sys_pgmap+512], eax +; +; mov [page_start], sys_pgmap+512 +; mov ebx, sys_pgmap +; add ebx, [pg_data.pagemap_size] +; mov [page_end], ebx +; mov eax, [pg_data.pages_count] +; sub eax, 4096+PAGES_USED +; mov [pg_data.pages_free], eax +; +; mov [pg_data.pages_faults], 0 +; +; mov edi, OS_BASE+0x01000000 +; mov esi, [pg_data.kernel_tables] +; sub esi, 4 +; ja @f +; mov esi, 1 +;@@: +; call alloc_page +; stdcall map_page_table, sys_pgdir, edi, eax +; add edi, 0x00400000 +; dec esi +; jnz @B +; +; mov ecx, [pg_data.kernel_tables] +; sub ecx, 4 +; shl ecx, 10 +; mov edi, OS_BASE+0x01000000 +; shr edi, 10 +; add edi, pages_tab +; xor eax, eax +; cld +; rep stosd +; +; mov eax, cr3 +; mov cr3, eax +; +; mov [pg_data.pg_mutex], 0 +; ret +;endp + +align 4 +proc alloc_page + + pushfd + cli + mov ebx, [page_start] + mov ecx, [page_end] +.l1: + bsf eax,[ebx]; + jnz .found + add ebx,4 + cmp ebx, ecx + jb .l1 + popfd + xor eax,eax + ret +.found: + btr [ebx], eax + mov [page_start],ebx + sub ebx, sys_pgmap + shl ebx, 3 + add eax,ebx + shl eax, 12 + dec [pg_data.pages_free] + popfd + ret +endp + +align 4 +proc alloc_pages stdcall, count:dword + pushfd + cli + mov eax, [count] + add eax, 7 + shr eax, 3 + mov [count], eax + cmp eax, [pg_data.pages_free] + ja .fail + + mov ecx, [page_start] + mov ebx, [page_end] +.find: + mov edx, [count] + mov edi, ecx + +.match: + cmp byte [ecx], 0xFF + jne .next + dec edx + jz .ok + inc ecx + cmp ecx,ebx + jb .match +.fail: xor eax, eax + popfd + ret +.next: + inc ecx + cmp ecx, ebx + jb .find + popfd + xor eax, eax + ret +.ok: + sub ecx, edi + inc ecx + mov esi, edi + xor eax, eax + rep stosb + sub esi, sys_pgmap + shl esi, 3+12 + mov eax, esi + mov ebx, [count] + shl ebx, 3 + sub [pg_data.pages_free], ebx + popfd + ret +endp + +align 4 +proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword + mov eax, [phis_addr] + and eax, not 0xFFF + or eax, [flags] + mov ebx, [lin_addr] + shr ebx, 12 + mov [pages_tab+ebx*4], eax + mov eax, [lin_addr] + invlpg [eax] + ret +endp + +align 4 +proc free_page +;arg: eax page address + pushfd + cli + inc [pg_data.pages_free] + shr eax, 12 ;page index + mov ebx, sys_pgmap + bts [ebx], eax ;that's all! + shr eax, 3 + and eax, not 3 ;dword offset from page_map + add eax, ebx + cmp [page_start], eax + ja @f + popfd + ret +@@: + mov [page_start], eax + popfd + ret +endp + +align 4 +proc map_page_table stdcall,page_dir:dword, lin_addr:dword, phis_addr:dword + mov ebx, [lin_addr] + shr ebx, 22 + mov eax, [phis_addr] + and eax, not 0xFFF + or eax, PG_UW ;+PG_NOCACHE + mov ecx, [page_dir] + mov dword [ecx+ebx*4], eax + mov dword [master_tab+ebx*4], eax + mov eax, [lin_addr] + shr eax, 10 + add eax, pages_tab + invlpg [eax] + ret +endp + +align 4 +proc init_LFB + + cmp dword [LFBAddress], -1 + jne @f + + stdcall kernel_alloc, 0x280000 + mov [LFBAddress], eax + ret +@@: + test [SCR_MODE],word 0100000000000000b + jz @f + call map_LFB +@@: + ret +endp + +align 4 +proc map_LFB + locals + pg_count dd ? + endl + + mov edi, [LFBSize] + mov esi, [LFBAddress] + shr edi, 12 + mov [pg_count], edi + shr edi, 10 + + bt [cpu_caps], CAPS_PSE + jnc .map_page_tables + mov ebx, esi + or esi, PG_LARGE+PG_UW + shr ebx, 20 + mov ecx, ebx +@@: + mov [sys_pgdir+ebx], esi + add ebx, 4 + add esi, 0x00400000 + dec edi + jnz @B + + or dword [sys_pgdir+ecx], PG_GLOBAL + mov eax, cr3 ;flush TLB + mov cr3, eax + ret + +.map_page_tables: + +@@: + call alloc_page + stdcall map_page_table,sys_pgdir, esi, eax + add esi, 0x00400000 + dec edi + jnz @B + + mov eax, [LFBAddress] + mov esi, eax + shr esi, 10 + add esi, pages_tab + or eax, PG_UW + mov ecx, [pg_count] + shr ecx, 2 +.map: + mov [esi], eax + add eax, 0x1000 + mov [esi+4], eax + add eax, 0x1000 + mov [esi+8], eax + add eax, 0x1000 + mov [esi+12], eax + add eax, 0x1000 + add esi, 16 + sub ecx, 1 + jnz .map + + mov eax, cr3 ;flush TLB + mov cr3, eax + + ret +endp + +align 4 +proc new_mem_resize stdcall, new_size:dword + + stdcall wait_mutex, pg_data.pg_mutex + + mov edi, [new_size] + add edi,4095 + and edi,not 4095 + mov [new_size], edi + + mov edx,[CURRENT_TASK] + shl edx,8 + mov esi, [PROC_BASE+0x8c+edx] + add esi, 4095 + and esi, not 4095 + + cmp edi, esi + jae .expand + + shr edi, 12 + shr esi, 12 +@@: + mov eax, [pages_tab+0x00181000+edi*4] + test eax, 1 + jz .next + mov dword [pages_tab+0x00181000+edi*4], 2 + mov ebx, edi + shl ebx, 12 + invlpg [ebx+std_application_base_address] + call free_page + +.next: add edi, 1 + cmp edi, esi + jb @B + +.update_size: + + mov ebx, [new_size] + mov [PROC_BASE+0x8c+edx],ebx + +;search threads and update +;application memory size infomation + mov ecx,[PROC_BASE+0xb8+edx] + mov eax,2 + +.search_threads: +;eax = current slot +;ebx = new memory size +;ecx = page directory + cmp eax,[TASK_COUNT] + jg .search_threads_end + mov edx,eax + shl edx,5 + cmp word [CURRENT_TASK+edx+0xa],9 ;if slot empty? + jz .search_threads_next + shl edx,3 + cmp [PROC_BASE+edx+0xb8],ecx ;if it is our thread? + jnz .search_threads_next + mov [PROC_BASE+edx+0x8c],ebx ;update memory size +.search_threads_next: + inc eax + jmp .search_threads +.search_threads_end: + xor eax, eax + dec [pg_data.pg_mutex] + ret + +.expand: + add edi, new_app_base + add esi, new_app_base + + push esi + push edi + + add edi, 0x3FFFFF + and edi, not(0x3FFFFF) + add esi, 0x3FFFFF + and esi, not(0x3FFFFF) + + cmp esi, edi + jae .grow + + xchg esi, edi + + mov eax, cr3 + stdcall map_page,[tmp_task_pdir],eax,dword PG_SW+PG_NOCACHE + +@@: + call alloc_page + test eax, eax + jz .exit + + stdcall map_page_table,[tmp_task_pdir], edi, eax + + push edi + shr edi, 10 + add edi, pages_tab + mov ecx, 1024 + xor eax, eax + cld + rep stosd + pop edi + + add edi, 0x00400000 + cmp edi, esi + jb @B + + stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP +.grow: + pop edi + pop esi +@@: + call alloc_page + test eax, eax + jz .exit + stdcall map_page,esi,eax,dword PG_UW + + push edi + mov edi, esi + xor eax, eax + mov ecx, 1024 + cld + rep stosd + pop edi + + add esi, 0x1000 + cmp esi, edi + jna @B + + jmp .update_size +.exit: + xor eax, eax + inc eax + dec [pg_data.pg_mutex] + ret +endp + +align 4 +proc get_pg_addr stdcall, lin_addr:dword + mov ebx, [lin_addr] + shr ebx, 12 + mov eax, [pages_tab+ebx*4] + and eax, 0xFFFFF000 + ret +endp + +align 16 +proc page_fault_handler + pushad + + mov ebp, esp + mov eax, cr2 + sub esp, 4 + mov [esp], eax + push ds + + mov ax, 0x10 + mov ds, ax + +; mov edx, 0x400 ;bocsh +; mov al,0xff ;bocsh +; out dx, al ;bocsh +; nop ;bocsh fix + + + mov ebx, [ebp-4] + + cmp ebx, 0xe0000000 + jae .lfb_addr + + cmp ebx, 0x60400000 + jae .user_space + + cmp ebx, 0x60000000 + jae .tab_space + + jmp .kernel_space + +.user_space: + inc [pg_data.pages_faults] + + shr ebx, 12 + mov eax, [pages_tab+ebx*4] + + shr ebx, 10 + mov edx, [master_tab+ebx*4] + + test eax, 2 + jz .exit + + call alloc_page + and eax, eax + jz .exit + + stdcall map_page,[ebp-4],eax,dword PG_UW + + mov esi, [ebp-4] + and esi, 0xFFFFF000 + mov ecx, 1024 + xor eax, eax +@@: + mov [esi], eax + add esi, 4 + dec ecx + jnz @B +.exit: + pop ds + mov esp, ebp + popad + add esp, 4 + iretd + +.kernel_space: + shr ebx, 12 + mov eax, [pages_tab+ebx*4] + shr ebx, 10 + mov eax, [master_tab+ebx*4] + + pop ds + mov esp, ebp + popad + add esp, 4 + iretd + +.old_addr: + shr ebx, 12 +; mov eax, [pages_tab+ebx*4] + shr ebx, 10 + mov eax, [master_tab+ebx*4] + + pop ds + mov esp, ebp + popad + add esp, 4 + iretd + +.lfb_addr: + shr ebx, 22 + ;mov ecx, [sys_page_dir] + mov eax, [master_tab+ebx*4] + + pop ds + mov esp, ebp + popad + add esp, 4 + iretd + +.tab_space: + shr ebx, 12 +; mov eax, [pages_tab+ebx*4] + shr ebx, 10 + ;mov ecx, [sys_page_dir] + mov eax, [master_tab+ebx*4] + + pop ds + mov esp, ebp + popad + add esp, 4 + iretd +endp + +align 4 +proc map_mem stdcall, lin_addr:dword,pdir:dword,\ + ofs:dword,buf_size:dword + mov eax, [buf_size] + test eax, eax + jz .exit + + mov eax, [pdir] + and eax, 0xFFFFF000 + + stdcall map_page,[ipc_pdir],eax,dword PG_UW + mov ebx, [ofs] + shr ebx, 22 + mov esi, [ipc_pdir] + mov edi, [ipc_ptab] + mov eax, [esi+ebx*4] + and eax, 0xFFFFF000 + test eax, eax + jz .exit + stdcall map_page,edi,eax,dword PG_UW +; inc ebx +; add edi, 0x1000 +; mov eax, [esi+ebx*4] +; test eax, eax +; jz @f +; and eax, 0xFFFFF000 +; stdcall map_page, edi, eax + +@@: mov edi, [lin_addr] + and edi, 0xFFFFF000 + mov ecx, [buf_size] + add ecx, 4095 + shr ecx, 12 + inc ecx + + mov edx, [ofs] + shr edx, 12 + and edx, 0x3FF + mov esi, [ipc_ptab] + +.map: mov eax, [esi+edx*4] + and eax, 0xFFFFF000 + test eax, eax + jz .exit + stdcall map_page,edi,eax,dword PG_UW + add edi, 0x1000 + inc edx + dec ecx + jnz .map + +.exit: + ret +endp + +align 4 +proc map_memEx stdcall, lin_addr:dword,pdir:dword,\ + ofs:dword,buf_size:dword + mov eax, [buf_size] + test eax, eax + jz .exit + + mov eax, [pdir] + and eax, 0xFFFFF000 + + stdcall map_page,[proc_mem_pdir],eax,dword PG_UW + mov ebx, [ofs] + shr ebx, 22 + mov esi, [proc_mem_pdir] + mov edi, [proc_mem_tab] + mov eax, [esi+ebx*4] + and eax, 0xFFFFF000 + test eax, eax + jz .exit + stdcall map_page,edi,eax,dword PG_UW + +@@: mov edi, [lin_addr] + and edi, 0xFFFFF000 + mov ecx, [buf_size] + add ecx, 4095 + shr ecx, 12 + inc ecx + + mov edx, [ofs] + shr edx, 12 + and edx, 0x3FF + mov esi, [proc_mem_tab] + +.map: mov eax, [esi+edx*4] +; and eax, 0xFFFFF000 +; test eax, eax +; jz .exit + stdcall map_page,edi,eax,dword PG_UW + add edi, 0x1000 + inc edx + dec ecx + jnz .map +.exit: + ret +endp + + + + +sys_IPC: +;input: +; eax=1 - set ipc buffer area +; ebx=address of buffer +; ecx=size of buffer +; eax=2 - send message +; ebx=PID +; ecx=address of message +; edx=size of message + + cmp eax,1 + jne @f + call set_ipc_buff + mov [esp+36], eax + ret + +@@: + cmp eax, 2 + jne @f + stdcall sys_ipc_send, ebx, ecx, edx + mov [esp+36], eax + ret + +@@: + xor eax, eax + not eax + mov [esp+36], eax + ret + +align 4 +proc set_ipc_buff + + mov eax,[CURRENT_TASK] + shl eax,8 + add eax, PROC_BASE + pushf + cli + mov [eax+0xA0],ebx ;set fields in extended information area + mov [eax+0xA4],ecx + + add ebx, new_app_base + add ecx, ebx + add ecx, 4095 + and ecx, not 4095 + +.touch: mov eax, [ebx] + add ebx, 0x1000 + cmp ebx, ecx + jna .touch + + popf + xor eax, eax + ret +endp + +proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword + locals + dst_slot dd ? + dst_offset dd ? + buf_size dd ? + endl + + pushf + cli + + mov eax, [PID] + call pid_to_slot + test eax,eax + jz .no_pid + + mov [dst_slot], eax + shl eax,8 + mov edi,[eax+PROC_BASE+0xa0] ;is ipc area defined? + test edi,edi + jz .no_ipc_area + + mov ebx, edi + add edi, new_app_base + and ebx, 0xFFF + mov [dst_offset], ebx + + mov esi, [eax+PROC_BASE+0xa4] + mov [buf_size], esi + + stdcall map_mem, [ipc_tmp], [PROC_BASE+eax+0xB8],\ + edi, esi + + mov edi, [dst_offset] + add edi, [ipc_tmp] + cmp dword [edi], 0 + jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now + mov ebx, dword [edi+4] + mov edx, ebx + add ebx, 8 + add ebx, [msg_size] + cmp ebx, [buf_size] + ja .buffer_overflow ;esi<0 - not enough memory in buffer + mov dword [edi+4], ebx + mov eax,[TASK_BASE] + mov eax, [eax+0x04] ;eax - our PID + mov edi, [dst_offset] + add edi, [ipc_tmp] + add edi, edx + mov [edi], eax + mov ecx, [msg_size] + + mov [edi+4], ecx + add edi, 8 + mov esi, [msg_addr] + add esi, new_app_base + cld + rep movsb + + mov ebx, [ipc_tmp] + mov edx, ebx + shr ebx, 12 + xor eax, eax + mov [pages_tab+ebx*4], eax + invlpg [edx] + + mov ebx, [ipc_pdir] + mov edx, ebx + shr ebx, 12 + xor eax, eax + mov [pages_tab+ebx*4], eax + invlpg [edx] + + mov ebx, [ipc_ptab] + mov edx, ebx + shr ebx, 12 + xor eax, eax + mov [pages_tab+ebx*4], eax + invlpg [edx] + + mov eax, [dst_slot] + shl eax, 8 + or [eax+PROC_BASE+0xA8],dword 0x40 + cmp dword [check_idle_semaphore],20 + jge .ipc_no_cis + + mov dword [check_idle_semaphore],5 +.ipc_no_cis: + popf + xor eax, eax + ret +.no_pid: + popf + mov eax, 4 + ret +.no_ipc_area: + popf + xor eax, eax + inc eax + ret +.ipc_blocked: + popf + mov eax, 2 + ret +.buffer_overflow: + popf + mov eax, 3 + ret +endp + +align 4 +proc get_mem_info stdcall, val:dword + + mov esi, [val] + + mov eax, [pg_data.pages_count] + mov [esi], eax + mov ebx, [pg_data.pages_free] + mov [esi+4], ebx + mov ecx, [pg_data.pages_faults] + mov [esi+8], ecx + + ret +endp + +align 4 +new_services: + + cmp eax,4 + jle sys_sheduler + + cmp eax, 10 + jb .fail + ja @f + + add ebx, new_app_base + stdcall get_mem_info, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 11 + ja @f + + stdcall init_heap, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 12 + ja @f + + stdcall user_alloc, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 13 + ja @f + + stdcall user_free, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 14 + ja @f + add ebx,new_app_base + stdcall get_notify, ebx + ret +@@: + cmp eax, 15 + ja @f + mov ecx, [CURRENT_TASK] + shl ecx, 8 + mov eax, [ecx+PROC_BASE+APPDATA.fpu_handler] + mov [ecx+PROC_BASE+APPDATA.fpu_handler], ebx + mov [esp+36], eax + ret +@@: + cmp eax, 16 + ja @f + + add ebx, new_app_base + stdcall get_service, ebx + mov [esp+36], eax + ret +@@: + cmp eax, 17 + ja @f + stdcall srv_handlerEx, ebx + mov [esp+36], eax + ret + +@@: +.fail: + xor eax, eax + mov [esp+36], eax + ret + + +align 4 +proc strncmp stdcall, str1:dword, str2:dword, count:dword + + mov ecx,[count] + jecxz .end + + mov ebx,ecx + + mov edi,[str1] + mov esi,edi + xor eax,eax + repne scasb + neg ecx ; cx = count - strlen + add ecx,ebx ; strlen + count - strlen + +.okay: + mov edi,esi + mov esi,[str2] + repe cmpsb + mov al,[esi-1] + xor ecx,ecx + + cmp al,[edi-1] + ja .str2_big + je .end + +.str1_big: + sub ecx,2 + +.str2_big: + not ecx +.end: + mov eax,ecx + ret +endp + +align 4 +proc fpu_save + clts + mov ebx, [fpu_owner] + shl ebx, 8 + mov eax, [ebx+PROC_BASE+0x10] + mov ebx, [CURRENT_TASK] + mov [fpu_owner], ebx + + bt [cpu_caps], CAPS_FXSR + jnc .no_SSE + + fxsave [eax] + ret +.no_SSE: + fnsave [eax] + ret +endp + +align 4 +proc fpu_restore + mov ebx, [CURRENT_TASK] + shl ebx, 8 + mov eax, [ebx+PROC_BASE+0x10] + bt [cpu_caps], CAPS_FXSR + jnc .no_SSE + + fxrstor [eax] + ret +.no_SSE: + frstor [eax] + ret +endp + +align 4 +proc test_cpu + locals + cpu_type dd 0 + cpu_id dd 0 + cpu_Intel dd 0 + cpu_AMD dd 0 + endl + + mov [cpu_type], 0 + + pushfd + pop eax + mov ecx, eax + xor eax, 0x40000 + push eax + popfd + pushfd + pop eax + xor eax, ecx + mov [cpu_type], CPU_386 + jz .end_cpu + push ecx + popfd + + mov [cpu_type], CPU_486 + mov eax, ecx + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + xor eax, ecx + je .end_cpu + mov [cpu_id], 1 + + xor eax, eax + cpuid + mov [cpu_vendor], ebx + mov [cpu_vendor+4], edx + mov [cpu_vendor+8], ecx + cmp ebx, dword [intel_str] + jne .check_AMD + cmp edx, dword [intel_str+4] + jne .check_AMD + cmp ecx, dword [intel_str+8] + jne .check_AMD + mov [cpu_Intel], 1 + cmp eax, 1 + jl .end_cpuid + mov eax, 1 + cpuid + mov [cpu_sign], eax + mov [cpu_info], ebx + mov [cpu_caps], edx + mov [cpu_caps+4],ecx + + shr eax, 8 + and eax, 0x0f + mov [cpu_type], eax + ret + +.end_cpuid: + mov eax, [cpu_type] + ret + +.check_AMD: + cmp ebx, dword [AMD_str] + jne .end_cpu + cmp edx, dword [AMD_str+4] + jne .end_cpu + cmp ecx, dword [AMD_str+8] + jne .end_cpu + mov [cpu_AMD], 1 + cmp eax, 1 + jl .end_cpuid + mov eax, 1 + cpuid + mov [cpu_sign], eax + mov [cpu_info], ebx + mov [cpu_caps], edx + mov [cpu_caps+4],ecx + shr eax, 8 + and eax, 0x0f + mov [cpu_type], eax +.end_cpu: + mov eax, [cpu_type] + ret +endp + +MEM_WB equ 6 ;write-back memory +MEM_WC equ 1 ;write combined memory +MEM_UC equ 0 ;uncached memory + +align 4 +proc init_mtrr + + cmp [0x2f0000+0x901c],byte 2 + je .exit + + mov eax, cr0 + or eax, 0x60000000 ;disable caching + mov cr0, eax + wbinvd ;invalidate cache + + mov ecx, 0x2FF + rdmsr ; + push eax + + xor edx, edx + xor eax, eax + mov ecx, 0x2FF + wrmsr ;disable all MTRR + + stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB + stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC + xor edx, edx + xor eax, eax + mov ecx, 0x204 + mov ebx, 6 +@@: + wrmsr ;disable unused MTRR + inc ecx + wrmsr + inc ecx + dec ebx + jnz @b + + wbinvd ;again invalidate + + pop eax + or eax, 0x800 ;set default memtype to UC + and al, 0xF0 + mov ecx, 0x2FF + wrmsr ;and enable MTRR + + mov eax, cr0 + and eax, not 0x60000000 + mov cr0, eax ; enable caching +.exit: + ret +endp + +align 4 +proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword + + xor edx, edx + mov eax, [base] + or eax, [mem_type] + mov ecx, [reg] + lea ecx, [0x200+ecx*2] + wrmsr + + mov ebx, [size] + dec ebx + mov eax, 0xFFFFFFFF + mov edx, 0x0000000F + sub eax, ebx + sbb edx, 0 + or eax, 0x800 + inc ecx + wrmsr + ret +endp + + +iglobal +align 4 + intel_str db "GenuineIntel",0 + AMD_str db "AuthenticAMD",0 +endg + +uglobal +align 16 + irq_tab rd 16 + + + MEM_FreeSpace rd 1 + + ipc_tmp rd 1 + ipc_pdir rd 1 + ipc_ptab rd 1 + + proc_mem_map rd 1 + proc_mem_pdir rd 1 + proc_mem_tab rd 1 + + tmp_task_pdir rd 1 + tmp_task_ptab rd 1 + tmp_task_data rd 1 + + current_pdir rd 1 + + fpu_data rd 1 + fdd_buff rd 1 + +;;CPUID information + + cpu_vendor rd 3 + cpu_sign rd 1 + cpu_info rd 1 + +endg + +uglobal +align 16 + dll_tab rb 32*32 + srv_tab rb 32*32 + dll_map rd 1 + srv_map rd 1 + + mem_used_list rd 1 + mem_block_list rd 64 + mem_block_map rb 512 + mem_block_arr rd 1 + mem_block_start rd 1 + mem_block_end rd 1 + mem_block_mask rd 2 + + page_start rd 1 + page_end rd 1 + sys_page_map rd 1 + app_load rd 1 +endg + + +; push eax +; push edx +; mov edx, 0x400 ;bocsh +; mov al,0xff ;bocsh +; out dx, al ;bocsh +; nop ;bocsh fix +; pop edx +; pop eax + diff --git a/kernel/trunk/core/sys32.inc b/kernel/trunk/core/sys32.inc index 68958d3975..673a9b8dc0 100644 --- a/kernel/trunk/core/sys32.inc +++ b/kernel/trunk/core/sys32.inc @@ -54,18 +54,18 @@ apm_data_16: ; ----------------------------------------- app_code_l: - dw ((0x80000000-std_application_base_address) shr 12) and 0xffff + dw 0xFFFF;((0x80000000-std_application_base_address) shr 12) and 0xffff dw 0 - db 0 - dw 11010000b*256+11111010b+256*((0x80000000-std_application_base_address) shr 28) - db std_application_base_address shr 24 + db 0x40 + db cpl3 + dw G32+D32+0x6000+0x7; app_data_l: - dw (0x80000000-std_application_base_address) shr 12 and 0xffff + dw 0xFFFF;(0x80000000-std_application_base_address) shr 12 and 0xffff dw 0 - db 0 - dw 11010000b*256+11110010b+256*((0x80000000-std_application_base_address) shr 28) - db std_application_base_address shr 24 + db 0x40 + db drw3 + dw G32+D32+0x6000+0x7; graph_data_l: @@ -81,11 +81,10 @@ tss0_l: gdte: - idtreg: dw 8*0x41-1 dd idts+8 -label idts at 0xB100-8 +;label idts at 0xB100-8 @@ -157,7 +156,7 @@ build_interrupt_table: add edi, 8 dec ecx jnz @b - + ;mov edi,8*0x40+idts+8 mov [edi + 0], word (i40 and ((1 shl 16)-1)) mov [edi + 2], word os_code @@ -166,16 +165,20 @@ build_interrupt_table: ret - - iglobal sys_int: - dd e0,debug_exc,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15 - dd e16,e17 + dd e0,debug_exc,e2,e3 + dd e4,e5,e6,e7 + dd e8,e9,e10,e11 + dd e12,e13,page_fault_handler,e15 + + dd except_16, e17 times 14 dd unknown_interrupt - dd irq0 ,irq1 ,p_irq2 ,p_irq3 ,p_irq4 ,p_irq5,p_irq6 ,p_irq7 - dd p_irq8,p_irq9,p_irq10,p_irq11,p_irq12,irqD ,p_irq14,p_irq15 + dd irq0 , irq_serv.irq_1, p_irq2 ,irq_serv.irq_3 + dd p_irq4 ,irq_serv.irq_5,p_irq6,irq_serv.irq_7 + dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10 + dd irq_serv.irq_11,p_irq12,irqD ,p_irq14,p_irq15 times 16 dd unknown_interrupt @@ -216,7 +219,7 @@ macro exc_w_code [num] jmp exc_c } -exc_wo_code 0, 1, 2, 3, 4, 5, 6, 9, 15, 16 ; 18, 19 +exc_wo_code 0, 1, 2, 3, 4, 5, 6, 9, 15 ; 18, 19 exc_w_code 8, 10, 11, 12, 13, 14, 17 exc_c: @@ -234,13 +237,13 @@ exc_c: sti ; not debuggee => say error and terminate add esp, 28h - movzx eax, bl + movzx eax, bl mov [error_interrupt], eax call show_error_parameters - + mov edx, [0x3010] mov [edx + TASKDATA.state], byte 4 - + jmp change_task .debug: @@ -272,35 +275,56 @@ align 4 e7: save_ring3_context clts - mov ax, os_data - mov ds, ax - mov es, ax - - mov eax, [prev_user_of_fpu] - shl eax, 8 - add eax, 0x80000 + APPDATA.fpu_save_area - fsave [eax] - - mov eax, [0x3000] - mov [prev_user_of_fpu], eax - shl eax, 8 - add eax, 0x80000 - cmp [eax + APPDATA.is_fpu_saved], 0 - je @f - frstor [eax+APPDATA.fpu_save_area] - @@: - mov [eax + APPDATA.is_fpu_saved], 1 + mov ax, os_data + mov ds, ax + mov es, ax + + mov ebx, [fpu_owner] + cmp ebx, [CURRENT_TASK] + je .exit + + shl ebx, 8 + mov eax, [ebx+PROC_BASE+APPDATA.fpu_state] + bt [cpu_caps], CAPS_FXSR + jnc .no_SSE + + fxsave [eax] + mov ebx, [CURRENT_TASK] + mov [fpu_owner], ebx + shl ebx, 8 + cmp dword [ebx+PROC_BASE+APPDATA.fpu_init], 0 + je .init + mov eax, [ebx+PROC_BASE+APPDATA.fpu_state] + fxrstor [eax] restore_ring3_context iret - +.init: + fninit ;­ ¬ ­¥ ­ã¦­ë ­¥¬ áª¨à®¢ ­­ë¥ ¨áª«î祭¨ï + mov dword [ebx+PROC_BASE+APPDATA.fpu_init], 1 +.exit: + restore_ring3_context + iret +.no_SSE: + fnsave [eax] + mov ebx, [CURRENT_TASK] + mov [fpu_owner], ebx + shl ebx, 8 + cmp dword [ebx+PROC_BASE+APPDATA.fpu_init], 0 + je .init + + mov eax, [ebx+PROC_BASE+APPDATA.fpu_state] + frstor [eax] + restore_ring3_context + iret + iglobal - prev_user_of_fpu dd 1 -endg + fpu_owner dd 1 + endg writehex: pusha - + mov edi, [write_error_to] mov esi, 8 @@: @@ -334,13 +358,13 @@ uglobal endg show_error_parameters: - + mov [write_error_to],process_pid+43 mov eax,[0x3000] shl eax, 5 mov eax,[0x3000+TASKDATA.pid+eax] call writehex - + mov [write_error_to],process_error+43 mov eax,[error_interrupt] call writehex @@ -412,7 +436,7 @@ p_irq3: old_irq3_handler: mov edi,3 call irqhandler - p_irq3_1: + p_irq3_1: restore_ring3_context iret @@ -428,7 +452,7 @@ p_irq4: old_irq4_handler: mov edi,4 call irqhandler - p_irq4_1: + p_irq4_1: restore_ring3_context iret @@ -478,7 +502,7 @@ irqD: mov ax, os_data mov ds, ax mov es, ax - + mov dx,0xf0 mov al,0 out dx,al @@ -490,7 +514,7 @@ irqD: out dx,al restore_ring3_context - + iret @@ -610,12 +634,12 @@ sys_resize_app_memory: cmp eax,1 jne .no_application_mem_resize - - jmp new_mem_resize ;resize for new type of processes + stdcall new_mem_resize, ebx + mov [esp+36], eax + ret - .no_application_mem_resize: - +.no_application_mem_resize: ret @@ -692,9 +716,9 @@ uglobal app_esp dd 0x0 app_i_param dd 0x0 app_i_icon dd 0x0 - ;app_mem_pos dd 0x0 +; app_mem_pos dd 0x0 appl_path dd 0x0 - appl_path_size dd 0x0 + appl_path_size dd 0x0 endg @@ -730,13 +754,18 @@ terminate: ; terminate application term9: call set_application_table_status - - mov eax,esi - call dispose_app_cr3_table - cmp [prev_user_of_fpu],esi ; if user fpu last -> fpu user = 1 + mov eax,esi + + pushad + shl eax,8 + mov eax,[PROC_BASE+eax+0xB8] + stdcall destroy_app_space, eax + popad + + cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1 jne fpu_ok_1 - mov [prev_user_of_fpu],1 + mov [fpu_owner],1 fpu_ok_1: mov [0xf400],byte 0 ; empty keyboard buffer @@ -882,8 +911,8 @@ terminate: ; terminate application add edi, window_data ; \begin{diamond}[19.09.2006] ; skip minimized windows - test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED - jnz .check_next_window + test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .check_next_window ; \end{diamond} call waredraw .nothing_to_activate: diff --git a/kernel/trunk/core/syscall.inc b/kernel/trunk/core/syscall.inc index 13630d2279..a04de33f3d 100644 --- a/kernel/trunk/core/syscall.inc +++ b/kernel/trunk/core/syscall.inc @@ -32,7 +32,7 @@ i40: call dword [servetable+edi*4] pop eax cli - + popad pop es ds iretd @@ -57,7 +57,7 @@ uglobal save_syscall_count dd 0x0 endg -label save_syscall_data dword at 0x5000 +;label save_syscall_data dword at 0x5000 iglobal @@ -132,7 +132,7 @@ iglobal dd undefined_syscall ; 57-reserved dd file_system ; 58-Common file system interface dd sys_trace ; 59-System call trace - dd new_sys_ipc ; 60-Inter Process Communication + dd sys_IPC ; 60-Inter Process Communication dd sys_gs ; 61-Direct graphics access dd sys_pci ; 62-PCI functions dd sys_msg_board ; 63-System message board @@ -140,7 +140,7 @@ iglobal dd undefined_syscall ; 65-UTF dd sys_process_def ; 66-Process definitions - keyboard dd sys_window_move ; 67-Window move or resize - dd sys_internal_services ; 68-Some internal services + dd new_services ; 68-Some internal services dd sys_debug_services ; 69-Debug dd file_system_lfn ; 70-Common file system interface, version 2 dd syscall_windowsettings ; 71-Window settings diff --git a/kernel/trunk/core/taskman.inc b/kernel/trunk/core/taskman.inc new file mode 100644 index 0000000000..8fae26aa94 --- /dev/null +++ b/kernel/trunk/core/taskman.inc @@ -0,0 +1,1173 @@ + +struc APP_HEADER_00 +{ .banner dq ? + .version dd ? ;+8 + .start dd ? ;+12 + .i_end dd ? ;+16 + .mem_size dd ? ;+20 + .i_param dd ? ;+24 +} + +struc APP_HEADER_01 +{ .banner dq ? + .version dd ? ;+8 + .start dd ? ;+12 + .i_end dd ? ;+16 + .mem_size dd ? ;+20 + .stack_top dd ? ;+24 + .i_param dd ? ;+28 + .i_icon dd ? ;+32 +} + +align 4 +proc test_app_header stdcall, header:dword + virtual at ebx + APP_HEADER_00 APP_HEADER_00 + end virtual + + mov ebx, [header] + cmp [ebx+6], word '00' + jne .check_01_header + + mov eax,[APP_HEADER_00.start] + mov [app_start],eax + mov eax,[APP_HEADER_00.i_end] + mov [app_i_end],eax + mov eax,[APP_HEADER_00.mem_size] + mov [app_mem],eax + shr eax,1 + sub eax,0x10 + mov [app_esp],eax + mov eax,[APP_HEADER_00.i_param] + mov [app_i_param],eax + mov [app_i_icon],dword 0 + + mov eax,1 + ret + + .check_01_header: + virtual at ebx + APP_HEADER_01 APP_HEADER_01 + end virtual + + cmp [ebx+6],word '01' + jne .no_01_header + + mov eax,[APP_HEADER_01.start] + mov [app_start],eax + mov eax,[APP_HEADER_01.i_end] + mov [app_i_end],eax + mov eax,[APP_HEADER_01.mem_size] + mov [app_mem],eax + mov eax,[APP_HEADER_01.stack_top] + mov [app_esp],eax + mov eax,[APP_HEADER_01.i_param] + mov [app_i_param],eax + mov eax,[APP_HEADER_01.i_icon] + mov [app_i_icon],eax + + mov eax,1 + ret + +.no_01_header: + + xor eax, eax + ret +endp + +align 4 +proc get_new_process_place +;input: +; none +;result: +; eax=[new_process_place]<>0 - ok +; 0 - failed. +;This function find least empty slot. +;It doesn't increase [TASK_COUNT]! + mov eax,CURRENT_TASK + mov ebx,[TASK_COUNT] + inc ebx + shl ebx,5 + add ebx,eax ;ebx - address of process information for (last+1) slot +.newprocessplace: +;eax = address of process information for current slot + cmp eax,ebx + jz .endnewprocessplace ;empty slot after high boundary + add eax,0x20 + cmp word [eax+0xa],9 ;check process state, 9 means that process slot is empty + jnz .newprocessplace +.endnewprocessplace: + mov ebx,eax + sub eax,CURRENT_TASK + shr eax,5 ;calculate slot index + cmp eax,256 + jge .failed ;it should be <256 + mov word [ebx+0xa],9 ;set process state to 9 (for slot after hight boundary) + ; mov [new_process_place], eax + ret + +.failed: + xor eax,eax + ret +endp + +align 4 +proc create_app_space stdcall, app_size:dword,img_size:dword + locals + app_pages dd ? + img_pages dd ? + dir_addr dd ? + master_addr dd ? + app_tabs dd ? + endl + + stdcall wait_mutex, pg_data.pg_mutex + + xor eax, eax + mov [dir_addr], eax + mov [master_addr], eax + + mov eax, [app_size] + add eax, 4095+4096 + and eax, NOT(4095) + mov [app_size], eax + mov ebx, eax + shr eax, 12 + mov [app_pages], eax + add ebx, 0x3FFFFF + and ebx, NOT(0x3FFFFF) + shr ebx, 22 + mov [app_tabs], ebx + + mov eax, [img_size] + add eax, 4095 + and eax, NOT(4095) + + mov [img_size], eax + shr eax, 12 + mov [img_pages], eax + + call alloc_page + test eax, eax + jz .fail + mov [dir_addr], eax + stdcall map_page,[tmp_task_pdir],eax,dword PG_SW + + mov esi, sys_pgdir + mov edi, [tmp_task_pdir] + mov ecx, 384 + cld + rep movsd + + mov ecx, 384 + xor eax, eax + cld + rep stosd + + mov ecx, 256 + mov esi, sys_pgdir+0xc00 + rep movsd + + call alloc_page + test eax, eax + jz .fail + mov [master_addr], eax + stdcall map_page,[tmp_task_ptab],eax,dword PG_SW + + mov ecx, 384 + mov edi, [tmp_task_ptab] + mov esi, master_tab + cld + rep movsd + + mov ecx, 384 + xor eax, eax + rep stosd + + mov ecx, 256 + mov esi, master_tab+0xc00 + rep movsd + + mov eax, [master_addr] + or eax, PG_SW + mov ebx, [tmp_task_pdir] + mov [ebx+0x600], eax + mov ecx, [tmp_task_ptab] + mov [ecx+0x600],eax + + mov eax, [dir_addr] + call set_cr3 + + mov edx, [app_tabs] + mov edi, new_app_base +@@: + call alloc_page + test eax, eax + jz .fail + + stdcall map_page_table,[tmp_task_pdir], edi, eax + add edi, 0x00400000 + dec edx + jnz @B + + mov edi, new_app_base + shr edi, 10 + add edi, pages_tab + mov ecx, [app_tabs] + shl ecx, 10 + xor eax, eax + rep stosd + + mov edx, new_app_base + +.alloc: + call alloc_page + test eax, eax + jz .fail + + stdcall map_page,edx,eax,dword PG_UW + add edx, 0x1000 + sub [app_pages], 1 + sub [img_pages], 1 + jnz .alloc + + mov ecx, [app_pages] + and ecx, ecx + jz .next + + mov ebx, edx + shr edx, 12 +.reserve: + mov dword [pages_tab+edx*4], 0x02 + invlpg [ebx] + inc edx + dec ecx + jnz .reserve +.next: + mov edi, new_app_base + mov ecx, [img_size] + shr ecx, 2 + xor eax, eax + cld + rep stosd + + stdcall map_page,[tmp_task_ptab],dword 0,dword PG_UNMAP + stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP + + dec [pg_data.pg_mutex] + mov eax, [dir_addr] + ret +.fail: + dec [pg_data.pg_mutex] + cmp [dir_addr], 0 + jz @f + stdcall destroy_app_space, [dir_addr] +@@: + xor eax, eax + ret +endp + +align 4 +set_cr3: + mov esi, [CURRENT_TASK] + mov ebx, esi + shl esi,8 + mov [PROC_BASE+esi+0xB8],eax + imul ebx,tss_step + add ebx,tss_data + mov [ebx+28], eax + mov cr3, eax + ret + +align 4 +proc destroy_page_table stdcall, pg_tab:dword + + push esi + + mov esi, [pg_tab] + mov ecx, 1024 +.free: + mov eax, [esi] + test eax, 1 + jz .next + call free_page +.next: + add esi, 4 + dec ecx + jnz .free + pop esi + ret +endp + +align 4 +proc destroy_app_space stdcall, pg_dir:dword + + stdcall wait_mutex, pg_data.pg_mutex + + xor edx,edx + mov eax,0x2 + mov ebx, [pg_dir] + +.loop: +;eax = current slot of process + mov ecx,eax + shl ecx,5 + cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running? + jz @f ;skip empty slots + shl ecx,3 + cmp [PROC_BASE+ecx+0xB8],ebx ;compare page directory addresses + jnz @f + inc edx ;thread found +@@: + inc eax + cmp eax,[TASK_COUNT] ;exit loop if we look through all processes + jle .loop + +;edx = number of threads +;our process is zombi so it isn't counted + cmp edx,1 + jg .exit +;if there isn't threads then clear memory. + + mov eax, [pg_dir] + and eax, not 0xFFF + stdcall map_page,[tmp_task_pdir],eax,dword PG_SW + mov esi, [tmp_task_pdir] + add esi, 0x600 + mov eax, [esi] + call free_page ;destroy master table + add esi, 4 + mov edi, 383 +.destroy: + mov eax, [esi] + test eax, 1 + jz .next + and eax, not 0xFFF + stdcall map_page,[tmp_task_ptab],eax,dword PG_SW + stdcall destroy_page_table, [tmp_task_ptab] + mov eax, [esi] + call free_page +.next: + add esi, 4 + dec edi + jnz .destroy + + mov eax, [pg_dir] + call free_page +.exit: + stdcall map_page,[tmp_task_ptab],dword 0,dword PG_UNMAP + stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP + dec [pg_data.pg_mutex] + ret +endp + +align 4 +proc fs_execute + +;fn_read:dword, file_size:dword, cluster:dword + +; ebx - cmdline +; edx - flags +; ebp - full filename +; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it + + locals + cmdline dd ? + flags dd ? + filename dd ? + retval dd ? + endl + + pushad + + mov [cmdline], ebx + mov [flags], edx + mov eax, [ebp] + mov [filename], eax + + stdcall wait_mutex, pg_data.tmp_task_mutex + + mov edi, [tmp_task_data] + mov ecx, (2048+256)/4 + xor eax, eax + rep stosd + + mov esi, [filename] + mov edi, [tmp_task_data] + add edi, TMP_FILE_NAME + mov ecx, 1024 + rep movsb + + mov esi, [filename] + mov edi, [tmp_task_data] + add edi, TMP_ICON_OFFS + mov ecx, 1024 + rep movsb + + mov esi, [cmdline] + test esi, esi + jz @f + mov edi, [tmp_task_data] + add edi, TMP_CMD_LINE + mov ecx, 256 + rep movsb +@@: + mov eax, TMP_FILE_NAME + add eax, [tmp_task_data] + mov ebx, [tmp_task_data] ;cmd line + add ebx, TMP_CMD_LINE + + stdcall fs_exec, eax, ebx, [flags], [ebp+8],\ + [ebp+12], [ebp+16],[ebp+20] + mov [retval], eax + popad + mov [pg_data.tmp_task_mutex], 0 + mov eax, [retval] + ret + +endp + +align 4 +proc fs_exec stdcall file_name:dword, cmd_line:dword, flags:dword,\ + fn_read:dword, file_size:dword,\ + cluster:dword, some_data:dword + + locals + slot dd ? + app_path_size dd ? + save_cr3 dd ? + img_size dd ? + endl + +; check filename length - with terminating NULL must be no more than 1024 symbols + + mov edi, [file_name] + mov ecx, 1024 + xor eax, eax + repnz scasb + jz @f + mov eax, -ERROR_FILE_NOT_FOUND + ret +@@: + sub edi, [file_name] + mov [app_path_size], edi + + mov esi, new_process_loading + call sys_msg_board_str ; write message to message board + + pushfd + cli + +.wait_lock: + cmp [application_table_status],0 + je .get_lock + call change_task + jmp .wait_lock + +.get_lock: + mov eax, 1 + xchg eax, [application_table_status] + cmp eax, 0 + jne .wait_lock + + call set_application_table_status + + call get_new_process_place + test eax, eax + mov ecx, -0x20 ; too many processes + jz .err + mov [slot], eax + + mov edi,eax + shl edi,8 + add edi,PROC_BASE + mov ecx,256/4 + xor eax,eax + cld + rep stosd ;clean extended information about process + +; write application name + + mov edi, [file_name] + mov ecx, [app_path_size] + add edi, ecx + dec edi + std + mov al, '/' + repnz scasb + cld + jnz @f + inc edi +@@: + inc edi +; now edi points to name without path + + mov esi, edi + mov ecx, 8 ; 8 chars for name + mov edi, [slot] + shl edi, cl + add edi, PROC_BASE +.copy_process_name_loop: + lodsb + cmp al, '.' + jz .copy_process_name_done + test al, al + jz .copy_process_name_done + stosb + loop .copy_process_name_loop +.copy_process_name_done: + mov al, ' ' + rep stosb + pop eax + mov cl, 3 ; 3 chars for extension + dec esi +@@: + dec eax + cmp eax, esi + jbe .copy_process_ext_done + cmp byte [eax], '.' + jnz @b + lea esi, [eax+1] +.copy_process_ext_loop: + lodsb + test al, al + jz .copy_process_ext_done + stosb + loop .copy_process_ext_loop +.copy_process_ext_done: + mov al, ' ' + rep stosb + +; read header + + lea eax, [file_size] + mov edi, TMP_BUFF + call [fn_read] + test eax, eax + jnz .err + +; check menuet signature + + mov ecx, -0x1F +;check MENUET signature + cmp [TMP_BUFF],dword 'MENU' + jnz .err + cmp [TMP_BUFF+4],word 'ET' + jnz .err + + stdcall test_app_header, TMP_BUFF + test eax, eax + jz .err + + mov eax, cr3 + mov [save_cr3], eax + stdcall create_app_space,[app_mem], [app_mem];[file_size] + test eax, eax + jz .failed + + mov ebx,[slot] + shl ebx,8 + mov [PROC_BASE+ebx+0xB8],eax + + mov esi, TMP_BUFF + mov edi, new_app_base + mov ecx, 512/4 + cld + rep movsd + +;read file +@@: + lea eax, [file_size] + cmp dword [eax], 0 + jz .done + push edi + call [fn_read] + pop edi + add edi, 512 + test eax, eax + jz @b + cmp ebx, 6 + jne .failed +.done: + stdcall add_app_parameters, [slot], new_app_base,\ + [cmd_line],[file_name],[flags] + + mov eax, [save_cr3] + call set_cr3 + + xor eax, eax + mov [application_table_status],eax ;unlock application_table_status mutex + popfd + mov eax,[process_number] ;set result + ret + +.failed: + mov eax, [save_cr3] + call set_cr3 +.err: + + popfd + xor eax, eax + mov [application_table_status],eax + ret +endp + +align 4 +proc add_app_parameters stdcall,slot:dword,img_base:dword,\ + cmd_line:dword, app_path:dword, flags:dword + + mov eax,[slot] + bt [cpu_caps], CAPS_SSE + jnc .no_SSE + shl eax, 8 + mov ebx, eax + add eax, eax + add eax, [fpu_data] + mov [ebx+PROC_BASE+APPDATA.fpu_state], eax + mov [ebx+PROC_BASE+APPDATA.fpu_handler], 0 + mov [ebx+PROC_BASE+APPDATA.sse_handler], 0 + jmp .m1 +.no_SSE: + mov ecx, eax + mov ebx, eax + shl eax, 7 + shl ebx, 4 + sub eax, ebx ;eax*=112 + add eax, [fpu_data] + shl ecx, 8 + mov [ecx+PROC_BASE+APPDATA.fpu_state], eax + mov [ecx+PROC_BASE+APPDATA.fpu_handler], 0 + mov [ecx+PROC_BASE+APPDATA.sse_handler], 0 +.m1: + mov ebx,[slot] + cmp ebx,[TASK_COUNT] + jle .noinc + inc dword [TASK_COUNT] ;update number of processes +.noinc: + shl ebx,8 + mov eax,[app_mem] + mov [PROC_BASE+0x8c+ebx],eax + + shr ebx,3 + mov eax, new_app_base + mov dword [CURRENT_TASK+ebx+0x10],eax + +.add_command_line: + mov edx,[app_i_param] + test edx,edx + jz .no_command_line ;application don't need parameters + mov eax,[cmd_line] + test eax,eax + jz .no_command_line ;no parameters specified +;calculate parameter length + xor ecx,ecx +.command_line_len: + cmp byte [eax],0 + jz .command_line_len_end + inc eax + inc ecx + cmp ecx,255 + jl .command_line_len + +.command_line_len_end: +;ecx - parameter length +;edx - address of parameters in new process address space + inc ecx + mov edi, [img_base] + add edi, edx + mov esi, [cmd_line] + rep movsb + +.no_command_line: + + mov edx,[app_i_icon] + test edx,edx + jz .no_command_line_1 ;application don't need path of file + mov esi,[app_path] + test esi, esi + jz .no_command_line_1 ;application don't need path of file + mov ecx, 64 + mov edi, [img_base] + add edi, edx + rep movsb + +.no_command_line_1: + mov ebx,[slot] + mov eax,ebx + shl ebx,5 + add ebx,CURRENT_TASK ;ebx - pointer to information about process + mov [ebx+0xe],al ;set window number on screen = process slot + + mov [ebx],dword 1+2+4 ;set default event flags (see 40 function) + + inc dword [process_number] + mov eax,[process_number] + mov [ebx+4],eax ;set PID + + mov ecx,ebx + add ecx,(draw_data-CURRENT_TASK) ;ecx - pointer to draw data +;set draw data to full screen + + mov [ecx+0],dword 0 + mov [ecx+4],dword 0 + mov eax,[SCR_X_SIZE] + mov [ecx+8],eax + mov eax,[SCR_Y_SIZE] + mov [ecx+12],eax +;set window state to 'normal' (non-minimized/maximized/rolled-up) state + mov [ecx+WDATA.fl_wstate],WSTATE_NORMAL +;set cr3 register in TSS of application + + mov ecx,[slot] + shl ecx,8 + mov eax,[PROC_BASE+0xB8+ecx] + ;or eax, PG_NOCACHE + mov [l.cr3],eax + + mov eax,[app_start] + mov [l.eip],eax ;set eip in TSS + mov eax,[app_esp] + mov [l.esp],eax ;set stack in TSS + +;gdt + mov ax,app_code ;ax - selector of code segment + mov [l.cs],ax + mov ax,app_data + mov [l.ss],ax + mov [l.ds],ax + mov [l.es],ax + mov [l.fs],ax + mov ax,graph_data ;ax - selector of graphic segment + mov [l.gs],ax + mov [l.io],word 128 + mov [l.eflags],dword 0x3202 + + mov [l.ss0],os_data + mov ebx,[slot] + shl ebx,12 + add ebx,sysint_stack_data+4096 + mov [l.esp0],ebx + +;copy tss to it place + mov eax,tss_sceleton + mov ebx,[slot] + imul ebx,tss_step + add ebx,tss_data ;ebx - address of application TSS + mov ecx,120 + call memmove + +;Add IO access table - bit array of permitted ports + or eax,-1 + mov edi,[slot] + imul edi,tss_step + add edi,tss_data+128 + mov ecx,2048 + cld + rep stosd ;full access to 2048*8=16384 ports + + mov ecx,ebx ;ecx - address of application TSS + mov edi,[slot] + shl edi,3 +;set TSS descriptor + mov [edi+gdts+tss0+0],word tss_step ;limit (size) + mov [edi+gdts+tss0+2],cx ;part of offset + mov eax,ecx + shr eax,16 + mov [edi+gdts+tss0+4],al ;part of offset + mov [edi+gdts+tss0+7],ah ;part of offset + mov [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags + +;flush keyboard and buttons queue + mov [KEY_COUNT],byte 0 + mov [BTN_COUNT],byte 0 + + mov edi,[slot] + shl edi,5 + add edi,window_data + mov ebx,[slot] + movzx esi,word [WIN_STACK+ebx*2] + lea esi,[WIN_POS+esi*2] + call windowactivate ;gui initialization + + mov ebx,[slot] + shl ebx,5 + mov [CURRENT_TASK+ebx+0xa],byte 0 ;set process state - running +; set if debuggee + mov eax, [flags] + test byte [flags], 1 + jz .no_debug + mov [CURRENT_TASK+ebx+0xa],byte 1 ;set process state - suspended + mov eax,[CURRENT_TASK] + mov [PROC_BASE+ebx*8+0xac],eax ;set debugger PID - current +.no_debug: + + mov esi,new_process_running + call sys_msg_board_str ;output information about succefull startup + + ret +endp + +pid_to_slot: +;Input: +; eax - pid of process +;Output: +; eax - slot of process or 0 if process don't exists +;Search process by PID. + push ebx + push ecx + mov ebx,[TASK_COUNT] + shl ebx,5 + mov ecx,2*32 + +.loop: +;ecx=offset of current process info entry +;ebx=maximum permitted offset + cmp byte [CURRENT_TASK+ecx+0xa],9 + jz .endloop ;skip empty slots + cmp [CURRENT_TASK+ecx+0x4],eax ;check PID + jz .pid_found +.endloop: + add ecx,32 + cmp ecx,ebx + jle .loop + + pop ecx + pop ebx + xor eax,eax + ret + +.pid_found: + shr ecx,5 + mov eax,ecx ;convert offset to index of slot + pop ecx + pop ebx + ret + +check_region: +;input: +; ebx - start of buffer +; ecx - size of buffer +;result: +; eax = 1 region lays in app memory +; eax = 0 region don't lays in app memory + mov eax,[CURRENT_TASK] + jmp check_process_region +;----------------------------------------------------------------------------- +check_process_region: +;input: +; eax - slot +; ebx - start of buffer +; ecx - size of buffer +;result: +; eax = 1 region lays in app memory +; eax = 0 region don't lays in app memory + + test ecx,ecx + jle .ok + shl eax,5 + cmp word [CURRENT_TASK+eax+0xa],0 + jnz .failed + shl eax,3 + mov eax,[PROC_BASE+eax+0xb8] + test eax,eax + jz .failed + + mov eax,1 + ret + + +; call MEM_Get_Linear_Address +; push ebx +; push ecx +; push edx +; mov edx,ebx +; and edx,not (4096-1) +; sub ebx,edx +; add ecx,ebx +; mov ebx,edx +; add ecx,(4096-1) +; and ecx,not (4096-1) +;.loop: +;;eax - linear address of page directory +;;ebx - current page +;;ecx - current size +; mov edx,ebx +; shr edx,22 +; mov edx,[eax+4*edx] +; and edx,not (4096-1) +; test edx,edx +; jz .failed1 +; push eax +; mov eax,edx +; call MEM_Get_Linear_Address +; mov edx,ebx +; shr edx,12 +; and edx,(1024-1) +; mov eax,[eax+4*edx] +; and eax,not (4096-1) +; test eax,eax +; pop eax +; jz .failed1 +; add ebx,4096 +; sub ecx,4096 +; jg .loop +; pop edx +; pop ecx +; pop ebx +.ok: + mov eax,1 + ret +; +;.failed1: +; pop edx +; pop ecx +; pop ebx +.failed: + xor eax,eax + ret + +align 4 +proc read_process_memory +;Input: +; eax - process slot +; ebx - buffer address +; ecx - buffer size +; edx - start address in other process +;Output: +; eax - number of bytes read. + locals + slot dd ? + buff dd ? + r_count dd ? + offset dd ? + tmp_r_cnt dd ? + endl + + mov [slot], eax + mov [buff], ebx + mov [r_count], ecx + mov [tmp_r_cnt], ecx + mov [offset], edx + + pushad +.read_mem: + mov edx, [offset] + mov ebx, [tmp_r_cnt] + + mov ecx, 0x400000 + and edx, 0x3FFFFF + sub ecx, edx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + cmp ecx, 0x8000 + jna @F + mov ecx, 0x8000 +@@: + mov eax, [slot] + shl eax,8 + mov ebx, [offset] + add ebx, new_app_base + push ecx + stdcall map_memEx, [proc_mem_map],\ + [PROC_BASE+eax+0xB8],\ + ebx, ecx + pop ecx + + mov esi, [offset] + and esi, 0xfff + add esi, [proc_mem_map] + mov edi, [buff] + mov edx, ecx + rep movsb + + add [offset], edx + sub [tmp_r_cnt], edx + jnz .read_mem + + popad + mov eax, [r_count] + ret + +endp + +align 4 +proc write_process_memory +;Input: +; eax - process slot +; ebx - buffer address +; ecx - buffer size +; edx - start address in other process +;Output: +; eax - number of bytes written + + locals + slot dd ? + buff dd ? + w_count dd ? + offset dd ? + tmp_w_cnt dd ? + endl + + mov [slot], eax + mov [buff], ebx + mov [w_count], ecx + mov [tmp_w_cnt], ecx + mov [offset], edx + + pushad +.read_mem: + mov edx, [offset] + mov ebx, [tmp_w_cnt] + + mov ecx, 0x400000 + and edx, 0x3FFFFF + sub ecx, edx + cmp ecx, ebx + jbe @f + mov ecx, ebx +@@: + cmp ecx, 0x8000 + jna @F + mov ecx, 0x8000 +@@: + mov eax, [slot] + shl eax,8 + mov ebx, [offset] + add ebx, new_app_base + push ecx + stdcall map_memEx, [proc_mem_map],\ + [PROC_BASE+eax+0xB8],\ + ebx, ecx + pop ecx + + mov edi, [offset] + and edi, 0xfff + add edi, [proc_mem_map] + mov esi, [buff] + mov edx, ecx + rep movsb + + add [offset], edx + sub [tmp_w_cnt], edx + jnz .read_mem + + popad + mov eax, [w_count] + ret +endp + + +align 4 +proc new_sys_threads + locals + thread_start dd ? + thread_stack dd ? + params dd ? + slot dd ? + endl + + mov [thread_start], ebx + mov [thread_stack], ecx + mov [params], 0 + + xor edx,edx ; flags=0 + + cmp eax,1 + jnz .failed ;other subfunctions + mov esi,new_process_loading + call sys_msg_board_str + +.wait_lock: + cmp [application_table_status],0 + je .get_lock + call change_task + jmp .wait_lock + +.get_lock: + mov eax, 1 + xchg eax, [application_table_status] + cmp eax, 0 + jne .wait_lock + + call set_application_table_status + + call get_new_process_place + test eax, eax + jz .failed + + mov [slot], eax + + xor eax,eax + mov [app_i_param],eax + mov [app_i_icon],eax + + mov ebx, [thread_start] + mov ecx, [thread_stack] + + mov [app_start],ebx + mov [app_esp],ecx + + mov esi,[CURRENT_TASK] + shl esi,8 + add esi,PROC_BASE + mov ebx,esi ;ebx=esi - pointer to extended information about current thread + + mov edi,[slot] + shl edi,8 + add edi,PROC_BASE + mov edx,edi ;edx=edi - pointer to extended infomation about new thread + mov ecx,256/4 + rep stosd ;clean extended information about new thread + mov edi,edx + mov ecx,11 + rep movsb ;copy process name + mov eax,[ebx+0x8c] + mov [app_mem],eax ;set memory size + mov eax,[ebx+0xb8] + mov [edx+0xb8],eax ;copy page directory + + stdcall add_app_parameters, [slot], new_app_base,\ + [params], dword 0,dword 0 + + mov esi,new_process_running + call sys_msg_board_str ;output information about succefull startup + + mov [application_table_status],0 ;unlock application_table_status mutex + mov eax,[process_number] ;set result + ret +.failed: + mov [application_table_status],0 + mov eax,-1 + ret +endp + +align 4 +proc wait_mutex stdcall, mutex:dword + mov ebx, [mutex] +.wait_lock: + cmp dword [ebx],0 + je .get_lock + push ebx + call change_task + pop ebx + jmp .wait_lock + +.get_lock: + mov eax, 1 + xchg eax, [ebx] + test eax, eax + jnz .wait_lock + ret +endp + + +include "debug.inc" + +iglobal + new_process_loading db 'K : New Process - loading',13,10,0 + new_process_running db 'K : New Process - done',13,10,0 + start_not_enough_memory db 'K : New Process - not enough memory',13,10,0 +endg + diff --git a/kernel/trunk/drivers/CODEC.INC b/kernel/trunk/drivers/CODEC.INC new file mode 100644 index 0000000000..ae222dca5e --- /dev/null +++ b/kernel/trunk/drivers/CODEC.INC @@ -0,0 +1,223 @@ + +align 4 +proc detect_codec + locals + codec_id dd ? + endl + + stdcall codec_read, dword 0x7C + shl eax, 16 + mov [codec_id], eax + + stdcall codec_read, dword 0x7E + or eax, [codec_id] + + mov [codec.chip_id], eax + and eax, 0xFFFFFF00 + + mov edi, codecs +@@: + mov ebx, [edi] + test ebx, ebx + jz .unknown + + cmp eax, ebx + jne .next + mov eax, [edi+4] + mov [codec.ac_vendor_ids], eax + stdcall detect_chip, [edi+8] + ret +.next: + add edi, 12 + jmp @B +.unknown: + mov [codec.ac_vendor_ids], ac_unknown + mov [codec.chip_ids], chip_unknown + ret +endp + +align 4 +proc detect_chip stdcall, chip_tab:dword + + mov eax, [codec.chip_id] + and eax, 0xFF + + mov edi, [chip_tab] +@@: + mov ebx, [edi] + test ebx, ebx + jz .unknown + + cmp eax,ebx + jne .next + mov eax, [edi+4] + mov [codec.chip_ids], eax + ret +.next: + add edi, 8 + jmp @b +.unknown: + mov [codec.chip_ids], chip_unknown + ret +endp + +align 4 +proc setup_codec + + xor eax, eax + stdcall codec_write, dword CODEC_AUX_VOL + + mov eax, 0x1010 + stdcall codec_write, dword CODEC_MASTER_VOL_REG + + mov ax, 0x08 + stdcall codec_write, dword 0x0C + + mov ax, 0x0808 + stdcall codec_write, dword CODEC_PCM_OUT_REG + + mov ax, 0x0808 + stdcall codec_write, dword 0x10 + + mov ax, 0x0808 + stdcall codec_write, dword 0x12 + + mov ax, 0x0808 + stdcall codec_write, dword 0x16 + + + stdcall codec_read, dword CODEC_EXT_AUDIO_CTRL_REG + + and eax, 0FFFFh - BIT1 ; clear DRA (BIT1) + or eax, BIT0 ; set VRA (BIT0) + stdcall codec_write, dword CODEC_EXT_AUDIO_CTRL_REG + + stdcall set_sample_rate, dword 48000 + +.init_error: + + xor eax, eax ; exit with error + ret + +endp + +align 4 +proc set_master_vol stdcall, vol:dword + + mov ebx, 63 + mov ecx, 20644 + mov eax, [vol] + cmp eax, 90 + jna @f + mov eax, 90 +@@: + mul ecx + shr eax, 15 + sub ebx, eax + mov ah, bl + mov al, bl + stdcall codec_write, dword CODEC_MASTER_VOL_REG + ret +endp + +align 4 +proc get_master_vol stdcall, pvol:dword + + stdcall codec_read, dword CODEC_MASTER_VOL_REG + and eax, 0x3F + mov ebx, 63 + mov ecx, 20644 + + xchg eax, ebx + sub eax, ebx + shl eax, 15 + xor edx, edx + div ecx + mov ebx, [pvol] + mov [ebx], eax + ret +endp + +align 4 +proc set_sample_rate stdcall, rate:dword + mov eax, [rate] + stdcall codec_write, dword CODEC_PCM_FRONT_DACRATE_REG + ret +endp + +align 16 +ac_unknown db 'unknown manufacturer',13,10,0 +ac_Realtek db 'Realtek Semiconductor',13,10,0 +ac_Analog db 'Analog Devices',13,10,0 +ac_CMedia db 'C-Media Electronics',13,10,0 +chip_unknown db 'unknown chip', 13,10,0 + +CHIP_ANALOG equ 0x41445300 +CHIP_REALTEK equ 0x414C4700 +CHIP_CMEDIA equ 0x434D4900 + +align 16 +codecs dd CHIP_ANALOG, ac_Analog, chips_Analog + dd CHIP_CMEDIA, ac_CMedia, chips_CMedia + dd CHIP_REALTEK,ac_Realtek, chips_Realtek + dd 0 + +align 16 +chips_Analog dd 0x03, chip_AD1819 + dd 0x40, chip_AD1881 + dd 0x48, chip_AD1881A + dd 0x60, chip_AD1884 + dd 0x61, chip_AD1886 + dd 0x62, chip_AD1887 + dd 0x63, chip_AD1886A + dd 0x70, chip_AD1980 + dd 0x75, chip_AD1985 + dd 0 + +chips_Realtek dd 0x20, chip_ALC650 + dd 0x21, chip_ALC650D + dd 0x22, chip_ALC650E + dd 0x23, chip_ALC650F + dd 0x60, chip_ALC655 + dd 0x80, chip_ALC658 + dd 0x81, chip_ALC658D + dd 0x90, chip_ALC850 + dd 0 + +chips_CMedia dd 0x41, chip_CM9738 + dd 0x61, chip_CM9739 + dd 0x69, chip_CM9780 + dd 0x78, chip_CM9761 + dd 0x82, chip_CM9761 + dd 0x83, chip_CM9761 + dd 0 + +align 16 +;Analog Devices +chip_AD1819 db 'AD1819 ',0dh,0ah,00h +chip_AD1881 db 'AD1881 ',0dh,0ah,00h +chip_AD1881A db 'AD1881A',0dh,0ah,00h +chip_AD1884 db 'AD1885 ',0dh,0ah,00h +chip_AD1885 db 'AD1885 ',0dh,0ah,00h +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_AD1985 db 'AD1985 ',0dh,0ah,00h + +;Realtek +chip_ALC650 db 'ALC650 ',0dh,0ah,00h +chip_ALC650D db 'ALC650D',0dh,0ah,00h +chip_ALC650E db 'ALC650E',0dh,0ah,00h +chip_ALC650F db 'ALC650F',0dh,0ah,00h +chip_ALC655 db 'ALC655 ',0dh,0ah,00h +chip_ALC658 db 'ALC658 ',0dh,0ah,00h +chip_ALC658D db 'ALC658D',0dh,0ah,00h +chip_ALC850 db 'ALC850 ',0dh,0ah,00h + +;CMedia +chip_CM9738 db 'CMI9738', 0dh,0ah,0 +chip_CM9739 db 'CMI9739', 0dh,0ah,0 +chip_CM9780 db 'CMI9780', 0dh,0ah,0 +chip_CM9761 db 'CMI9761', 0dh,0ah,0 + diff --git a/kernel/trunk/drivers/INFINITY.ASM b/kernel/trunk/drivers/INFINITY.ASM new file mode 100644 index 0000000000..af2317ca88 --- /dev/null +++ b/kernel/trunk/drivers/INFINITY.ASM @@ -0,0 +1,795 @@ +; +; This file is part of the Infinity sound library. +; (C) copyright Serge 2006 +; email: infinity_sound@mail.ru +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + +format MS COFF + +include 'proc32.inc' +include 'main.inc' + +DEBUG equ 1 + +EVENT_NOTIFY equ 0x00000200 + +OS_BASE equ 0; 0x80400000 +new_app_base equ 0x60400000; 0x01000000 +PROC_BASE equ OS_BASE+0x0080000 + +public service_proc +public START +public IMPORTS + +SND_CREATE_BUFF equ 2 +SND_PLAY equ 3 +SND_STOP equ 4 +SND_SETBUFF equ 5 +SND_DESTROY_BUFF equ 6 + +DEV_PLAY equ 1 +DEV_STOP equ 2 +DEV_CALLBACK equ 3 + +struc IOCTL +{ .handle dd ? + .io_code dd ? + .input dd ? + .inp_size dd ? + .output dd ? + .out_size dd ? +} + +virtual at 0 + IOCTL IOCTL +end virtual + +section '.flat' align 16 + +START: + stdcall [GetService], szSound + test eax, eax + jz .fail + mov [hSound], eax + + stdcall [KernelAlloc], 16*512 + test eax, eax + jz .out_of_mem + mov [mix_buff], eax + + mov edi, stream_list + mov ecx, 17 + xor eax, eax + cld + rep stosd + + mov edi, stream + mov ecx, 4*STREAM_SIZE + rep stosd + + stdcall set_handler, [hSound], new_mix + + stdcall [RegService], szInfinity, service_proc + mov [stream_count],0 + + ret +.fail: + if DEBUG + mov esi, msgFail + call [SysMsgBoardStr] + end if + xor eax, eax + ret + +.out_of_mem: + if DEBUG + mov esi, msgMem + call [SysMsgBoardStr] + end if + xor eax, eax + ret + +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, SND_CREATE_BUFF + jne @F + mov ebx, [edi+input] + stdcall CreateBuffer,[ebx] + ret +@@: + cmp eax, SND_PLAY + jne @F + + mov ebx, [edi+input] + stdcall play_buffer, [ebx] + ret +@@: + cmp eax, SND_STOP + jne @F + +; if DEBUG +; mov esi, msgStop +; call [SysMsgBoardStr] +; end if + + mov ebx, [edi+input] + stdcall stop_buffer, [ebx] + ret +@@: + cmp eax, SND_SETBUFF + jne @F + + mov ebx, [edi+input] + mov eax, [ebx+4] + add eax, new_app_base + stdcall set_buffer, [ebx],eax,[ebx+8],[ebx+12] + ret +@@: + cmp eax, SND_DESTROY_BUFF + jne @F + + mov ebx, [edi+input] + stdcall DestroyBuffer, [ebx] + ret +@@: + xor eax, eax + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +TASK_COUNT equ 0x0003004 +CURRENT_TASK equ 0x0003000 + + +align 8 +proc CreateBuffer stdcall, format:dword + locals + str dd ? + endl + + call alloc_stream + and eax, eax + jz .fail + mov [str], eax + mov edi, eax + + mov edx, [stream_count] + mov [stream_list+edx*4], eax + inc [stream_count] + + mov [edi+STREAM.magic], 'WAVE' + mov [edi+STREAM.size], STREAM_SIZE + + stdcall [KernelAlloc], 180*1024 + + mov edi, [str] + mov [edi+STREAM.base], eax + mov [edi+STREAM.curr_seg], eax + mov [edi+STREAM.notify_off1], eax + add eax, 0x8000 + mov [edi+STREAM.notify_off2], eax + add eax, 0x7FFF + mov [edi+STREAM.limit], eax + + inc eax + + mov [edi+STREAM.work_buff], eax + mov [edi+STREAM.work_read], eax + mov [edi+STREAM.work_write], eax + mov [edi+STREAM.work_count], 0 + add eax, 0x10000 + mov [edi+STREAM.work_top], eax + add eax, 1024*32 + mov [edi+STREAM.r_buff], eax + + mov ebx, [CURRENT_TASK] + shl ebx, 5 + mov eax, [0x3000+ebx+4] + + mov [edi+STREAM.notify_task], eax + + mov eax, [format] + mov [edi+STREAM.format], eax + mov [edi+STREAM.flags], SND_STOP + + xor ebx, ebx + cmp eax, 19 + jb @f + mov ebx, 0x80808080 +@@: + mov [edi+STREAM.r_silence], ebx + + shl eax, 4 + mov ebx, [resampler_params+eax] + mov ecx, [resampler_params+eax+4] + mov edx, [resampler_params+eax+8] + + mov [edi+STREAM.r_size],ebx + mov [edi+STREAM.r_end], ecx + mov [edi+STREAM.r_dt], edx + + mov ebx, [resampler_params+eax+12] + mov [edi+STREAM.resample], ebx + + mov edi, [edi+STREAM.base] + mov ecx, 180*1024/4 + xor eax, eax + rep stosd + + mov eax, [str] + ret + +.fail: + xor eax, eax + ret +endp + +align 4 +pid_to_slot: + + push ebx + push ecx + mov ebx,[TASK_COUNT] + shl ebx,5 + mov ecx,2*32 +.loop: + cmp byte [CURRENT_TASK+ecx+0xa],9 + jz .endloop ;skip empty slots + cmp [CURRENT_TASK+ecx+0x4],eax ;check PID + jz .pid_found +.endloop: + add ecx,32 + cmp ecx,ebx + jle .loop + pop ecx + pop ebx + xor eax,eax + ret + +.pid_found: + shr ecx,5 + mov eax,ecx + pop ecx + pop ebx + ret + + + +align 4 +proc DestroyBuffer stdcall, str:dword + + mov esi, [str] + + cmp [esi+STREAM.magic], 'WAVE' + jne .fail + + cmp [esi+STREAM.size], STREAM_SIZE + jne .fail + + stdcall [KernelFree], [esi+STREAM.base] + + mov eax, [str] + call free_stream + + mov edi, [str] + mov ecx, STREAM_SIZE/4 + xor eax, eax + cld + rep stosd + + mov eax, [str] + mov esi, stream_list + mov ecx, 16 +@@: + cmp [esi], eax + je .remove + add esi, 4 + dec ecx + jnz @B + xor eax, eax + inc eax + ret +.remove: + mov edi, esi + add esi, 4 + cld + rep movsd + dec [stream_count] + xor eax, eax + inc eax + ret +.fail: + xor eax, eax + ret +endp + +align 4 +proc play_buffer stdcall, str:dword + + mov ebx, [str] + + cmp [ebx+STREAM.magic], 'WAVE' + jne .fail + + cmp [ebx+STREAM.size], STREAM_SIZE + jne .fail + + mov [ebx+STREAM.flags], SND_PLAY + + mov eax,[ebx+STREAM.work_buff] + mov [ebx+STREAM.work_read], eax + mov [ebx+STREAM.work_write], eax + mov [ebx+STREAM.work_count], 0 + + mov eax, [ebx+STREAM.base] + mov [ebx+STREAM.curr_seg], eax + + mov esi, [ebx+STREAM.curr_seg] + mov edi, [ebx+STREAM.work_write] + mov edx, [ebx+STREAM.r_buff] + + mov ecx, 32 + mov eax, [ebx+STREAM.r_silence] +@@: + mov [edx], eax + add edx, 4 + dec ecx + jnz @B + + mov edx, [ebx+STREAM.r_buff] + + stdcall [ebx+STREAM.resample], edi, esi, edx,\ + [ebx+STREAM.r_dt],[ebx+STREAM.r_size],[ebx+STREAM.r_end] + + mov ebx, [str] + + add [ebx+STREAM.work_count], eax; + add [ebx+STREAM.work_write], eax; + + mov eax, [ebx+STREAM.r_size] + add [ebx+STREAM.curr_seg], eax + +; if DEBUG +; mov esi, msgPlay +; call [SysMsgBoardStr] +; end if + + stdcall dev_play, [hSound] + + xor eax, eax + inc eax + ret + +.fail: + xor eax, eax + ret + +endp + + +align 4 +proc stop_buffer stdcall, str:dword + + mov edi, [str] + + cmp [edi+STREAM.magic], 'WAVE' + jne .fail + + cmp [edi+STREAM.size], STREAM_SIZE + jne .fail + + mov [edi+STREAM.flags], SND_STOP + +; stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0 + + xor eax, eax + inc eax + ret + +.fail: + xor eax, eax + ret + +endp + +align 4 +proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword + + mov edx, [str] + test edx, edx + jz .fail + + cmp [edx+STREAM.magic], 'WAVE' + jne .fail + + cmp [edx+STREAM.size], STREAM_SIZE + jne .fail + + mov esi,[src] + test esi, esi + jz .fail + + cmp esi, new_app_base + jb .fail + + mov ecx, [size] + test ecx, ecx + jz .fail + + mov eax, [edx+STREAM.base] + add eax, [offs] + + cmp eax, [edx+STREAM.base] + jb .fail + + mov edi, eax + add eax, ecx + sub eax, 1 + + cmp eax, [edx+STREAM.limit] + ja .fail + + shr ecx, 2 + cld + rep movsd + + xor eax, eax + inc eax + ret +.fail: + xor eax, eax + ret +endp + +align 4 +proc alloc_stream + + mov esi, stream_map + + pushf + cli + + bsf eax, [esi] + jnz .find + popf + xor eax, eax + ret + +.find: btr [esi], eax + popf + mov ebx, STREAM_SIZE + mul ebx + add eax, stream + ret +endp + +align 4 +proc free_stream + sub eax, stream + mov ebx, STREAM_SIZE + xor edx, edx + div ebx + + and edx, edx + jnz .err + + bts [stream_map], eax + + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc check_stream + + xor edx, edx + mov ecx, [play_count] +.l1: + mov esi, [play_list+edx] + + mov eax, [esi+STR.curr_seg] + cmp eax, [esi+STR.limit] + jb .next + +.m1: mov eax,[esi+STR.base] + mov [esi+STR.curr_seg], eax +.next: + add edx, 4 + loop .l1 + ret +endp + + +align 4 +proc prepare_playlist + +.restart: + xor ebx, ebx + xor edx, edx + mov [play_count], 0 + mov ecx, [stream_count] + jcxz .exit +.l1: + mov esi, [stream_list+ebx] + test esi, esi + jz .next + + cmp [esi+STREAM.magic], 'WAVE' + jne .next + + cmp [esi+STREAM.size], STREAM_SIZE + jne .next + + mov eax,[esi+STREAM.notify_task] + cmp eax, -1 + je .fail + + call pid_to_slot + test eax, eax + jz .fail + + cmp [esi+STREAM.flags], SND_PLAY; + jne .next + cmp [esi+STREAM.work_count], 16384 + jb .next + + mov [play_list+edx], esi + inc [play_count] + add edx, 4 +.next: + add ebx, 4 + loop .l1 +.exit: + ret + +.fail: + stdcall DestroyBuffer, esi + jmp .restart +endp + +align 4 +proc prepare_updatelist + + xor ebx, ebx + xor edx, edx + mov [play_count], 0 + mov ecx, [stream_count] + jcxz .exit +.l1: + mov eax, [stream_list+ebx] + test eax, eax + jz .next + cmp [eax+STREAM.flags], SND_PLAY + jne .next + + mov [play_list+edx], eax + inc [play_count] + add edx, 4 +.next: + add ebx, 4 + loop .l1 +.exit: + ret +endp + + +align 4 +proc set_handler stdcall, hsrv:dword, handler_proc:dword + locals + handler dd ? + io_code dd ? + input dd ? + inp_size dd ? + output dd ? + out_size dd ? + val dd ? + endl + + mov eax, [hsrv] + lea ecx, [handler_proc] + xor ebx, ebx + + mov [handler], eax + mov [io_code], DEV_CALLBACK + mov [input], ecx + mov [inp_size], 4 + mov [output], ebx + mov [out_size], 0 + + lea eax, [handler] + stdcall [ServiceHandler], eax + ret +endp + +align 4 +proc dev_play stdcall, hsrv:dword + locals + handle dd ? + io_code dd ? + input dd ? + inp_size dd ? + output dd ? + out_size dd ? + val dd ? + endl + + mov eax, [hsrv] + xor ebx, ebx + + mov [handle], eax + mov [io_code], DEV_PLAY + mov [input], ebx + mov [inp_size], ebx + mov [output], ebx + mov [out_size], ebx + + lea eax, [handle] + stdcall [ServiceHandler], eax + ret +endp + +include 'mixer.asm' + +align 16 +play_list dd 16 dup(0) +stream_list dd 17 dup(0) + +align 16 +resampler_params: + ;r_size r_end r_dt resampler_func + dd 0,0,0,0 ; 0 PCM_ALL + dd 16384, 0, 0, copy_stream ; 1 PCM_2_16_48 + dd 16384, 0, 0, m16_stereo ; 2 PCM_1_16_48 + + dd 16384, 0x08000000, 30109, resample_2 ; 3 PCM_2_16_44 + dd 8192, 0x08000000, 30109, resample_1 ; 4 PCM_1_16_44 + + dd 16384, 0x08000000, 21846, resample_2 ; 5 PCM_2_16_32 + dd 8192, 0x08000000, 21846, resample_1 ; 6 PCM_1_16_32 + + dd 16384, 0x08000000, 16384, resample_2 ; 7 PCM_2_16_24 + dd 8192, 0x08000000, 16384, resample_1 ; 8 PCM_1_16_24 + + dd 8192, 0x04000000, 15052, resample_2 ; 9 PCM_2_16_22 + dd 4096, 0x04000000, 15052, resample_1 ;10 PCM_1_16_22 + + dd 8192, 0x04000000, 10923, resample_2 ;11 PCM_2_16_16 + dd 4096, 0x04000000, 10923, resample_1 ;12 PCM_1_16_16 + + dd 8192, 0x04000000, 8192, resample_2 ;13 PCM_2_16_12 + dd 4096, 0x04000000, 8192, resample_1 ;14 PCM_1_16_12 + + dd 4096, 0x02000000, 7527, resample_2 ;15 PCM_2_16_11 + dd 2048, 0x02000000, 7527, resample_1 ;16 PCM_1_16_11 + + dd 4096, 0x02000000, 5462, resample_2 ;17 PCM_2_16_8 + dd 2048, 0x02000000, 5462, resample_1 ;18 PCM_1_16_8 + + dd 16384, 0, 0, s8_stereo ;19 PCM_2_8_48 + dd 8192, 0, 0, m8_stereo ;20 PCM_1_8_48 + + dd 8192, 0x08000000, 30109, resample_28 ;21 PCM_2_8_44 + dd 4096, 0x08000000, 30109, resample_18 ;22 PCM_1_8_44 + + dd 8192, 0x08000000, 21846, resample_28 ;23 PCM_2_8_32 + dd 4096, 0x08000000, 21846, resample_18 ;24 PCM_1_8_32 + + dd 8192, 0x08000000, 16384, resample_28 ;25 PCM_2_8_24 + dd 4096, 0x08000000, 16384, resample_18 ;26 PCM_1_8_24 + + dd 4096, 0x04000000, 15052, resample_28 ;27 PCM_2_8_22 + dd 2048, 0x04000000, 15052, resample_18 ;28 PCM_1_8_22 + + dd 4096, 0x04000000, 10923, resample_28 ;29 PCM_2_8_16 + dd 2048, 0x04000000, 10923, resample_18 ;30 PCM_1_8_16 + + dd 4096, 0x04000000, 8192, resample_28 ;31 PCM_2_8_12 + dd 2048, 0x04000000, 8192, resample_18 ;32 PCM_1_8_12 + + dd 2048, 0x02000000, 7527, resample_28 ;33 PCM_2_8_11 + dd 1024, 0x02000000, 7527, resample_18 ;34 PCM_1_8_11 + + dd 2048, 0x02000000, 5462, resample_28 ;35 PCM_2_8_8 + dd 1024, 0x02000000, 5462, resample_18 ;36 PCM_1_8_8 + + +play_count dd 0 + +stream_count dd 0 + +align 8 +hSound dd 0 + +m7 dw 0x8000,0x8000,0x8000,0x8000 +mm80 dq 0x8080808080808080 +mm_mask dq 0xFF00FF00FF00FF00 + +mix_input dd 16 dup(0) + +align 16 +;fpu_state db 512 dup(0) + +align 16 +stream db STREAM_SIZE*16 dup(0) +stream_map dd 0xFFFF ; 16 +mix_buff dd 0 +mix_buff_map dd 0 + +align 16 +IMPORTS: + +AttachIntHandler dd szAttachIntHandler +SysMsgBoardStr dd szSysMsgBoardStr +PciApi dd szPciApi +PciRead32 dd szPciRead32 +PciRead8 dd szPciRead8 +AllocKernelSpace dd szAllocKernelSpace +MapPage dd szMapPage +KernelAlloc dd szKernelAlloc +KernelFree dd szKernelFree +GetPgAddr dd szGetPgAddr +RegService dd szRegService +GetCurrentTask dd szGetCurrentTask +GetService dd szGetService +ServiceHandler dd szServiceHandler +FpuSave dd szFpuSave +FpuRestore dd szFpuRestore + dd 0 + +szKernel db 'KERNEL', 0 +szAttachIntHandler db 'AttachIntHandler',0 +szSysMsgBoardStr db 'SysMsgBoardStr', 0 +szPciApi db 'PciApi', 0 +szPciRead32 db 'PciRead32', 0 +szPciRead8 db 'PciRead8', 0 +szAllocKernelSpace db 'AllocKernelSpace',0 +szMapPage db 'MapPage',0 +szRegService db 'RegService',0 +szKernelAlloc db 'KernelAlloc',0 +szGetPgAddr db 'GetPgAddr',0 +szGetCurrentTask db 'GetCurrentTask ',0 +szGetService db 'GetService',0 +szServiceHandler db 'ServiceHandler',0 +szKernelFree db 'KernelFree',0 +szFpuSave db 'FpuSave',0 +szFpuRestore db 'FpuRestore',0 + + +szInfinity db 'INFINITY',0 +szSound db 'SOUND',0 + +if DEBUG +msgFail db 'Sound service not found',13,10,0 +msgPlay db 'Play buffer',13,10,0 +msgStop db 'Stop',13,10,0 +msgUser db 'User callback',13,10,0 +msgMem db 'Not enough memory',13,10,0 +end if diff --git a/kernel/trunk/drivers/MAIN.INC b/kernel/trunk/drivers/MAIN.INC new file mode 100644 index 0000000000..1a4c5e8a55 --- /dev/null +++ b/kernel/trunk/drivers/MAIN.INC @@ -0,0 +1,133 @@ +; +; This file is part of the Infinity sound AC97 driver. +; (C) copyright Serge 2006 +; email: infinity_sound@mail.ru +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + +PCM_2_16_48 equ 1 +PCM_1_16_48 equ 2 + +PCM_2_16_44 equ 3 +PCM_1_16_44 equ 4 + +PCM_2_16_32 equ 5 +PCM_1_16_32 equ 6 + +PCM_2_16_24 equ 7 +PCM_1_16_24 equ 8 + +PCM_2_16_22 equ 9 +PCM_1_16_22 equ 10 + +PCM_2_16_16 equ 11 +PCM_1_16_16 equ 12 + +PCM_2_16_12 equ 13 +PCM_1_16_12 equ 14 + +PCM_2_16_11 equ 15 +PCM_1_16_11 equ 16 + +PCM_2_8_48 equ 17 +PCM_1_8_48 equ 18 + +PCM_2_8_44 equ 19 +PCM_1_8_44 equ 20 + +PCM_2_8_32 equ 21 +PCM_1_8_32 equ 22 + +PCM_2_8_24 equ 23 +PCM_1_8_24 equ 24 + +PCM_2_8_22 equ 25 +PCM_1_8_22 equ 26 + +PCM_2_8_16 equ 27 +PCM_1_8_16 equ 28 + +PCM_2_8_12 equ 29 +PCM_1_8_12 equ 30 + +PCM_2_8_11 equ 31 +PCM_1_8_11 equ 32 + +SND_PLAY equ 1 +SND_STOP equ 2 + +; struc SND_DEV +;{ .magic dd 0 +; .size dd 0 +; .count dd 0 +; dd 0 +; .snd_buff dd 16 dup (0) +;} + +;virtual at 0 +; SND_DEV SND_DEV +;end virtual + +;SND_DEV_SIZE equ 80 + + +struc STREAM +{ .magic dd 0 + .size dd 0 + .device dd 0 + .format dd 0 + .flags dd 0 + + .work_buff dd 0 + .work_read dd 0 + .work_write dd 0 + .work_count dd 0 + .work_top dd 0 + .r_buff dd 0 + .r_size dd 0 + .r_end dd 0 + .r_dt dd 0 + .r_silence dd 0 + + .base dd 0 + .curr_seg dd 0 + .limit dd 0 + .buff_size dd 0 + .notify_off1 dd 0 + .notify_off2 dd 0 + .notify_task dd 0 + .resample dd 0 +} + +STREAM_SIZE equ 23*4 + +virtual at 0 + STREAM STREAM +end virtual + +struc WAVE_HEADER +{ .riff_id dd ? + .riff_size dd ? + .riff_format dd ? + + .fmt_id dd ? + .fmt_size dd ? + .format_tag dw ? + .channels dw ? + .freq dd ? + .bytes_sec dd ? + .block_align dw ? + .bits_sample dw ? + + .data_id dd ? + .data_size dd ? +} + diff --git a/kernel/trunk/drivers/MIXER.ASM b/kernel/trunk/drivers/MIXER.ASM new file mode 100644 index 0000000000..72d90deb68 --- /dev/null +++ b/kernel/trunk/drivers/MIXER.ASM @@ -0,0 +1,1290 @@ +; +; This file is part of the Infinity sound library. +; (C) copyright Serge 2006 +; email: infinity_sound@mail.ru +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + +align 4 +proc new_mix stdcall, output:dword + locals + mixCounter dd ? + mixIndex dd ? + streamIndex dd ? + inputCount dd ? + main_count dd ? + blockCount dd ? + mix_out dd ? + endl + + call prepare_playlist + + cmp [play_count], 0 + je .exit +; mov eax, fpu_state +; fnsave [eax] + call [FpuSave] + emms + mov [main_count], 32; + +.l00: + mov [mix_buff_map], 0x0000FFFF; + xor eax, eax + mov [mixCounter], eax + mov [mixIndex],eax + mov [streamIndex], eax; + mov ebx, [play_count] + mov [inputCount], ebx +.l0: + mov ecx, 4 +.l1: + mov ebx, [streamIndex] + mov esi, [play_list+ebx*4] + mov eax, [esi+STREAM.work_read] + add [esi+STREAM.work_read], 512 + + mov ebx, [mixIndex] + mov [mix_input+ebx*4], eax + inc [mixCounter] + inc [mixIndex] + inc [streamIndex] + dec [inputCount] + jz .m2 + + dec ecx + jnz .l1 + + cmp [mixCounter], 4 + jnz .m2 + + stdcall mix_4_1, [mix_input],[mix_input+4],[mix_input+8],[mix_input+12] + sub [mixIndex],4 + mov ebx, [mixIndex] + mov [mix_input+ebx*4], eax + inc [mixIndex] + mov [mixCounter], 0 + + cmp [inputCount], 0 + jnz .l0 +.m2: + cmp [mixIndex], 1 + jne @f + stdcall copy_mem, [output], [mix_input] + jmp .m3 +@@: + cmp [mixIndex], 2 + jne @f + stdcall mix_2_1, [output], [mix_input], [mix_input+4] + jmp .m3 +@@: + cmp [mixIndex], 3 + jne @f + stdcall mix_3_1, [output],[mix_input],[mix_input+4],[mix_input+8] + jmp .m3 +@@: + stdcall final_mix, [output],[mix_input],[mix_input+4],[mix_input+8], [mix_input+12] +.m3: + add [output],512 + + sub [main_count], 1 + jnz .l00 + + call update_stream + call [FpuRestore] + ret +.exit: + mov edi, [output] + mov ecx, 0x1000 + xor eax, eax + cld + rep stosd + ret +endp + + +align 4 +proc update_stream + locals + stream_index dd 0 + endl + + mov [stream_index], 0 +.l1: + mov edx, [stream_index] + mov esi, [play_list+edx*4] + + mov eax, [esi+STREAM.work_read] + cmp eax, [esi+STREAM.work_top] + jb @f + mov eax, [esi+STREAM.work_buff] +@@: + mov [esi+STREAM.work_read], eax + + cmp [esi+STREAM.format], PCM_2_16_48 + je .copy + + sub [esi+STREAM.work_count], 16384 + + cmp [esi+STREAM.work_count], 32768 + ja @f + + stdcall refill, esi +@@: + inc [stream_index] + dec [play_count] + jnz .l1 + + ret +.copy: + mov ebx, esi + mov edi, [ebx+STREAM.work_write] + cmp edi, [ebx+STREAM.work_top] + jb @f + mov edi, [ebx+STREAM.work_buff] + mov [ebx+STREAM.work_write], edi +@@: + mov esi, [ebx+STREAM.curr_seg] + mov ecx, 16384/4 + cld + rep movsd + + mov [ebx+STREAM.work_write], edi + + cmp esi, [ebx+STREAM.limit] + jb @f + + mov esi, [ebx+STREAM.base] +@@: + mov [ebx+STREAM.curr_seg], esi + + xor ecx, ecx + cmp esi, [ebx+STREAM.notify_off2] + je @f + + mov ecx,0x8000 + cmp esi, [ebx+STREAM.notify_off1] + je @f + + inc [stream_index] + dec [play_count] + jnz .l1 + + ret +@@: + mov eax, [ebx+STREAM.notify_task] + call pid_to_slot + test eax, eax + jnz @f + not eax + mov [ebx+STREAM.notify_task], eax ;-1 + jmp .l_end +@@: + shl eax, 8 + mov [eax+PROC_BASE+32],ecx + or dword [eax+PROC_BASE+0xA8],EVENT_NOTIFY +.l_end: + inc [stream_index] + dec [play_count] + jnz .l1 + ret +endp + +align 4 +proc refill stdcall, str:dword + +; if DEBUG +; mov esi, msgUser +; call [SysMsgBoardStr] +; end if + + mov ebx, [str] + + mov ecx, [ebx+STREAM.work_write] + cmp ecx, [ebx+STREAM.work_top] + jbe .m2 + mov esi, [ebx+STREAM.work_top] + sub ecx, esi + mov edi, [ebx+STREAM.work_buff] + shr ecx, 2 + rep movsd ;call memcpy + + mov [ebx+STREAM.work_write], edi +.m2: + mov esi, [ebx+STREAM.curr_seg] + mov edi, [ebx+STREAM.work_write] + mov edx, [ebx+STREAM.r_buff] + + stdcall [ebx+STREAM.resample], edi, esi, edx,\ + [ebx+STREAM.r_dt],[ebx+STREAM.r_size],[ebx+STREAM.r_end] + + mov ebx, [str] + + add [ebx+STREAM.work_count], eax; + add [ebx+STREAM.work_write], eax; + + mov eax, [ebx+STREAM.curr_seg] + add eax, [ebx+STREAM.r_size] + cmp eax, [ebx+STREAM.limit] + jb @f + mov eax, [ebx+STREAM.base] +@@: + mov [ebx+STREAM.curr_seg], eax + + xor ecx, ecx + cmp eax, [ebx+STREAM.notify_off2] + je @f + + mov ecx,0x8000 + cmp eax, [ebx+STREAM.notify_off1] + je @f + + ret +@@: + mov eax, [ebx+STREAM.notify_task] + call pid_to_slot + test eax, eax + jnz @f + not eax + mov [ebx+STREAM.notify_task], eax ;-1 + ret +@@: + shl eax, 8 + mov [eax+PROC_BASE+32],ecx + or dword [eax+PROC_BASE+0xA8],EVENT_NOTIFY + ret +endp + +align 4 +proc resample_1 stdcall, dest:dword,src:dword,r_buff:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov edi, [r_buff] + add edi, 32*2 + mov esi, [src] + mov ecx, [r_size] + shr ecx, 2 + rep movsd + + mov edi, [dest] + mov edx, [r_buff] + mov eax, 16 + +align 16 +.l1: + mov ecx, eax + mov esi, eax + and ecx, 0x7FFF + shr esi, 15 + lea esi, [edx+esi*2] + + movsx ebp, word [esi] + movsx esi, word [esi+2] + mov ebx, 32768 + imul esi, ecx + sub ebx, ecx + imul ebx, ebp + lea ecx, [ebx+esi+16384] + sar ecx, 15 + cmp ecx, 32767 ; 00007fffH + jle @f + mov ecx, 32767 ; 00007fffH + jmp .write +@@: + cmp ecx, -32768 ; ffff8000H + jge .write + mov ecx, -32768 ; ffff8000H +.write: + mov ebx, ecx + shl ebx, 16 + mov bx, cx + mov [edi], ebx + add edi, 4 + + add eax, [esp+20] ;rdt + cmp eax, [esp+28] ;r_end + jb .l1 + + mov ebp, esp + + mov esi, [src] + add esi, [r_size] + sub esi, 32*2 + mov edx, [r_buff] + mov ecx, 16 +@@: + mov ebx, [esi] + mov [edx], ebx + add esi, 4 + add edx, 4 + dec ecx + jnz @B + + sub edi, [dest] + mov eax, edi + ret +endp + +align 4 +proc resample_18 stdcall, dest:dword,src:dword,r_buff:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov edi, [r_buff] + add edi, 32 + mov esi, [src] + mov ecx, [r_size] + shr ecx, 2 + rep movsd + + mov edi, [dest] + mov edx, [r_buff] + mov esi, 16 + +align 16 +.l1: + mov ecx, esi + mov eax, esi + and ecx, 0x7FFF + shr eax, 15 + lea eax, [edx+eax] + + mov bx, word [eax] + sub bh, 0x80 + sub bl, 0x80 + movsx eax, bh + shl eax,8 + movsx ebp, bl + shl ebp,8 + mov ebx, 32768 + imul eax, ecx + sub ebx, ecx + imul ebx, ebp + lea ecx, [ebx+eax+16384] + sar ecx, 15 + cmp ecx, 32767 ; 00007fffH + jle @f + mov ecx, 32767 ; 00007fffH + jmp .write +@@: + cmp ecx, -32768 ; ffff8000H + jge .write + mov ecx, -32768 ; ffff8000H +.write: + mov ebx, ecx + shl ebx, 16 + mov bx, cx + mov [edi], ebx + add edi, 4 + + add esi, [esp+20] ;rdt + cmp esi, [esp+28] ;r_end + jb .l1 + + mov ebp, esp + + mov esi, [src] + add esi, [r_size] + sub esi, 32 + mov edx, [r_buff] + mov ecx, 8 +@@: + mov ebx, [esi] + mov [edx], ebx + add esi, 4 + add edx, 4 + dec ecx + jnz @B + + sub edi, [dest] + mov eax, edi + ret +endp + +align 4 +proc copy_stream stdcall, dest:dword,src:dword,r_buff:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov ecx, [r_size] + mov eax, ecx + shr ecx, 2 + mov esi, [src] + mov edi, [dest] + rep movsd + mov eax, 16384 + ret +endp + +align 4 +proc resample_2 stdcall, dest:dword,src:dword,r_buff:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov edi, [r_buff] + add edi, 32*4 + mov esi, [src] + mov ecx, [r_size] + shr ecx, 2 + rep movsd ;call memcpy + + mov edx, [r_buff] + mov edi, [dest] + mov ebx, [r_dt] + mov eax, 16 + emms + +align 16 +.l1: + mov ecx, eax + mov esi, eax + and ecx, 0x7FFF + shr esi, 15 + lea esi, [edx+esi*4] + + movq mm0, [esi] + movq mm1, mm0 + + movd mm2, ecx + punpcklwd mm2, mm2 + movq mm3, qword [m7] ; // 0x8000 + + psubw mm3, mm2 ; // 0x8000 - iconst + punpckldq mm3, mm2 + + pmulhw mm0, mm3 + pmullw mm1, mm3 + + movq mm4, mm1 + punpcklwd mm1, mm0 + punpckhwd mm4, mm0 + paddd mm1, mm4 + psrad mm1, 15 + packssdw mm1, mm1 + movd [edi], mm1 + add edi, 4 + + add eax, ebx + cmp eax, [r_end] + jb .l1 + emms + + mov esi, [src] + add esi, [r_size] + sub esi, 32*4 + mov edx, [r_buff] + mov ecx, 32 +@@: + mov ebx, [esi] + mov [edx], ebx + add esi, 4 + add edx, 4 + dec ecx + jnz @B + + sub edi, [dest] + mov eax, edi + ret +endp + +align 4 +proc resample_28 stdcall, dest:dword,src:dword,r_buff:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov edi, [r_buff] + add edi, 32*2 + mov esi, [src] + mov ecx, [r_size] + shr ecx, 2 + rep movsd ;call memcpy + + mov edx, [r_buff] + mov edi, [dest] + mov ebx, [r_dt] + mov eax, 16 + emms + movq mm7,[mm80] + movq mm6,[mm_mask] + +align 16 +.l1: + mov ecx, eax + mov esi, eax + and ecx, 0x7FFF + shr esi, 15 + lea esi, [edx+esi*2] + + movq mm0, [esi] + psubb mm0,mm7 + punpcklbw mm0,mm0 + pand mm0,mm6 + + movq mm1, mm0 + + movd mm2, ecx + punpcklwd mm2, mm2 + movq mm3, qword [m7] ; // 0x8000 + + psubw mm3, mm2 ; // 0x8000 - iconst + punpckldq mm3, mm2 + + pmulhw mm0, mm3 + pmullw mm1, mm3 + + movq mm4, mm1 + punpcklwd mm1, mm0 + punpckhwd mm4, mm0 + paddd mm1, mm4 + psrad mm1, 15 + packssdw mm1, mm1 + movd [edi], mm1 + add edi, 4 + + add eax, ebx + cmp eax, [r_end] + jb .l1 + emms + + mov esi, [src] + add esi, [r_size] + sub esi, 32*2 + mov edx, [r_buff] + mov ecx, 16 +@@: + mov ebx, [esi] + mov [edx], ebx + add esi, 4 + add edx, 4 + dec ecx + jnz @B + + sub edi, [dest] + mov eax, edi + ret +endp + + +proc m16_stereo stdcall, dest:dword,src:dword,r_buff:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov esi, [src] + mov edi, [dest] + mov ecx, [r_size] + shr ecx,8 +@@: + call m16_s_mmx + add edi, 128 + add esi, 64 + call m16_s_mmx + add edi, 128 + add esi, 64 + call m16_s_mmx + add edi, 128 + add esi, 64 + call m16_s_mmx + add edi, 128 + add esi, 64 + dec ecx + jnz @b + + mov eax, [r_size] + add eax, eax + ret +endp + +align 4 +proc s8_stereo stdcall, dest:dword,src:dword,r_buff:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + + mov esi, [src] + mov edi, [dest] + mov ecx, [r_size] + shr ecx, 7 + + movq mm7, [mm80] + movq mm6, [mm_mask] +@@: + call s8_s_mmx + add edi, 64 + add esi, 32 + call s8_s_mmx + add edi, 64 + add esi, 32 + call s8_s_mmx + add edi, 64 + add esi, 32 + call s8_s_mmx + add edi, 64 + add esi, 32 + dec ecx + jnz @b + + mov eax, [r_size] + add eax, eax + ret +endp + +proc m8_stereo stdcall, dest:dword,src:dword,r_buff:dword,\ + r_dt:dword, r_size:dword,r_end:dword + + mov esi, [src] + mov edi, [dest] + mov ecx, [r_size] + shr ecx, 6 + + movq mm7, [mm80] + movq mm6, [mm_mask] +@@: + call m8_s_mmx + add edi, 64 + add esi, 16 + call m8_s_mmx + add edi, 64 + add esi, 16 + call m8_s_mmx + add edi, 64 + add esi, 16 + call m8_s_mmx + add edi, 64 + add esi, 16 + dec ecx + jnz @b + + mov eax, [r_size] + add eax, eax + add eax, eax + ret +endp + +align 4 +proc alloc_mix_buff + + bsf eax, [mix_buff_map] + jnz .find + xor eax, eax + ret +.find: + btr [mix_buff_map], eax + shl eax, 9 + add eax, [mix_buff] + ret +endp + +proc m16_s_mmx + + movq mm0, [esi] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi], mm0 + movq [edi+8], mm1 + + movq mm0, [esi+8] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+16], mm0 + movq [edi+24], mm1 + + movq mm0, [esi+16] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+32], mm0 + movq [edi+40], mm1 + + movq mm0, [esi+24] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+48], mm0 + movq [edi+56], mm1 + + movq mm0, [esi+32] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+64], mm0 + movq [edi+72], mm1 + + movq mm0, [esi+40] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+80], mm0 + movq [edi+88], mm1 + + + movq mm0, [esi+48] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+96], mm0 + movq [edi+104], mm1 + + movq mm0, [esi+56] + movq mm1, mm0 + punpcklwd mm0, mm0 + punpckhwd mm1, mm1 + movq [edi+112], mm0 + movq [edi+120], mm1 + + ret +endp + +align 4 +proc s8_s_mmx + + movq mm0, [esi] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq [edi], mm0 + movq [edi+8], mm1 + + movq mm0, [esi+8] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq [edi+16], mm0 + movq [edi+24], mm1 + + movq mm0, [esi+16] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq [edi+32], mm0 + movq [edi+40], mm1 + + movq mm0, [esi+24] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq [edi+48], mm0 + movq [edi+56], mm1 + + ret + +endp + +align 4 +proc m8_s_mmx + + movq mm0, [esi] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq mm2, mm0 + punpcklwd mm0, mm0 + punpckhwd mm2, mm2 + + movq mm3, mm1 + punpcklwd mm1, mm1 + punpckhwd mm3, mm3 + + movq [edi], mm0 + movq [edi+8], mm2 + movq [edi+16], mm1 + movq [edi+24], mm3 + + movq mm0, [esi+8] + psubb mm0, mm7 + movq mm1, mm0 + punpcklbw mm0, mm0 + pand mm0, mm6 + punpckhbw mm1, mm1 + pand mm1, mm6 + movq mm2, mm0 + punpcklwd mm0, mm0 + punpckhwd mm2, mm2 + + movq mm3, mm1 + punpcklwd mm1, mm1 + punpckhwd mm3, mm3 + + movq [edi+32], mm0 + movq [edi+40], mm2 + movq [edi+48], mm1 + movq [edi+56], mm3 + + ret +endp + + +align 4 +proc mix_2_1 stdcall, output:dword, str0:dword, str1:dword + + mov edi, [output] + + stdcall mix_2_1_mmx, edi, [str0],[str1] + add edi, 128 + add [str0], 128 + add [str1], 128 + stdcall mix_2_1_mmx, edi, [str0],[str1] + add edi, 128 + add [str0], 128 + add [str1], 128 + stdcall mix_2_1_mmx, edi, [str0],[str1] + add edi, 128 + add [str0], 128 + add [str1], 128 + stdcall mix_2_1_mmx, edi, [str0],[str1] + + ret +endp + + +align 4 +proc mix_3_1 stdcall, output:dword, str0:dword, str1:dword, str2:dword + + mov edi, [output] + + stdcall mix_3_1_mmx, edi, [str0],[str1],[str2] + add edi, 128 + add [str0], 128 + add [str1], 128 + add [str2], 128 + stdcall mix_3_1_mmx, edi, [str0],[str1],[str2] + add edi, 128 + add [str0], 128 + add [str1], 128 + add [str2], 128 + stdcall mix_3_1_mmx, edi, [str0],[str1],[str2] + add edi, 128 + add [str0], 128 + add [str1], 128 + add [str2], 128 + stdcall mix_3_1_mmx, edi, [str0],[str1],[str2] + + ret +endp + +align 4 +proc mix_4_1 stdcall, str0:dword, str1:dword,\ + str2:dword, str3:dword + + local output:DWORD + + call alloc_mix_buff + and eax, eax + jz .err + mov [output], eax + + mov edi, eax + + stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3] + add edi, 128 + add [str0], 128 + add [str1], 128 + add [str2], 128 + add [str3], 128 + stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3] + add edi, 128 + add [str0], 128 + add [str1], 128 + add [str2], 128 + add [str3], 128 + stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3] + add edi, 128 + add [str0], 128 + add [str1], 128 + add [str2], 128 + add [str3], 128 + stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3] + mov eax, [output] + ret +.err: + xor eax, eax + ret +endp + + +align 4 +proc final_mix stdcall, output:dword, str0:dword, str1:dword,\ + str2:dword, str3:dword + + mov edi, [output] + + stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3] + add edi, 128 + add [str0], 128 + add [str1], 128 + add [str2], 128 + add [str3], 128 + stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3] + add edi, 128 + add [str0], 128 + add [str1], 128 + add [str2], 128 + add [str3], 128 + stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3] + add edi, 128 + add [str0], 128 + add [str1], 128 + add [str2], 128 + add [str3], 128 + stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3] + + ret +endp + +align 4 +proc mix_2_1_mmx stdcall, output:dword, str0:dword, str1:dword + + mov edx, [output] + mov eax, [str0] + mov ecx, [str1] + + movq mm0, [eax] + paddsw mm0, [ecx] + ; psraw mm0, 1 + movq [edx], mm0 + + movq mm1, [eax+8] + paddsw mm1,[ecx+8] + ; psraw mm1, 1 + movq [edx+8], mm1 + + movq mm2, [eax+16] + paddsw mm2, [ecx+16] + ; psraw mm2, 1 + movq [edx+16], mm2 + + movq mm3, [eax+24] + paddsw mm3, [ecx+24] + ; psraw mm3, 1 + movq [edx+24], mm3 + + movq mm0, [eax+32] + paddsw mm0, [ecx+32] + ; psraw mm0, 1 + movq [edx+32], mm0 + + movq mm1, [eax+40] + paddsw mm1, [ecx+40] + ; psraw mm1, 1 + movq [edx+40], mm1 + + movq mm2, [eax+48] + paddsw mm2, [ecx+48] + ; psraw mm2, 1 + movq [edx+48], mm2 + + movq mm3, [eax+56] + paddsw mm3, [ecx+56] + ; psraw mm3, 1 + movq [edx+56], mm3 + + movq mm0, [eax+64] + paddsw mm0, [ecx+64] + ; psraw mm0, 1 + movq [edx+64], mm0 + + movq mm1, [eax+72] + paddsw mm1, [ecx+72] + ; psraw mm1, 1 + movq [edx+72], mm1 + + movq mm2, [eax+80] + paddsw mm2, [ecx+80] + ; psraw mm2, 1 + movq [edx+80], mm2 + + movq mm3, [eax+88] + paddsw mm3, [ecx+88] + ; psraw mm3, 1 + + movq [edx+88], mm3 + + movq mm0, [eax+96] + paddsw mm0, [ecx+96] + ; psraw mm0, 1 + + movq [edx+96], mm0 + + movq mm1, [eax+104] + paddsw mm1, [ecx+104] + ; psraw mm1, 1 + + movq [edx+104], mm1 + + movq mm2, [eax+112] + paddsw mm2, [ecx+112] + ; psraw mm2, 1 + + movq [edx+112], mm2 + + movq mm3, [eax+120] + paddsw mm3, [ecx+120] + ; psraw mm3, 1 + + movq [edx+120], mm3 + + ret +endp + +align 4 +proc mix_3_1_mmx stdcall, output:dword, str0:dword, str1:dword, str2:dword + + mov edx, [output] + mov eax, [str0] + mov ebx, [str1] + mov ecx, [str2] + + movq mm0, [eax] + paddsw mm0, [ebx] + paddsw mm0, [ecx] + movq [edx], mm0 + + movq mm1, [eax+8] + paddsw mm1,[ebx+8] + paddsw mm1,[ecx+8] + movq [edx+8], mm1 + + movq mm2, [eax+16] + paddsw mm2, [ebx+16] + paddsw mm2, [ecx+16] + movq [edx+16], mm2 + + movq mm3, [eax+24] + paddsw mm3, [ebx+24] + paddsw mm3, [ecx+24] + movq [edx+24], mm3 + + movq mm0, [eax+32] + paddsw mm0, [ebx+32] + paddsw mm0, [ecx+32] + movq [edx+32], mm0 + + movq mm1, [eax+40] + paddsw mm1, [ebx+40] + paddsw mm1, [ecx+40] + movq [edx+40], mm1 + + movq mm2, [eax+48] + paddsw mm2, [ebx+48] + paddsw mm2, [ecx+48] + movq [edx+48], mm2 + + movq mm3, [eax+56] + paddsw mm3, [ebx+56] + paddsw mm3, [ecx+56] + movq [edx+56], mm3 + + movq mm0, [eax+64] + paddsw mm0, [ebx+64] + paddsw mm0, [ecx+64] + movq [edx+64], mm0 + + movq mm1, [eax+72] + paddsw mm1, [ebx+72] + paddsw mm1, [ecx+72] + movq [edx+72], mm1 + + movq mm2, [eax+80] + paddsw mm2, [ebx+80] + paddsw mm2, [ecx+80] + movq [edx+80], mm2 + + movq mm3, [eax+88] + paddsw mm3, [ebx+88] + paddsw mm3, [ecx+88] + movq [edx+88], mm3 + + movq mm0, [eax+96] + paddsw mm0, [ebx+96] + paddsw mm0, [ecx+96] + movq [edx+96], mm0 + + movq mm1, [eax+104] + paddsw mm1, [ebx+104] + paddsw mm1, [ecx+104] + movq [edx+104], mm1 + + movq mm2, [eax+112] + paddsw mm2, [ebx+112] + paddsw mm2, [ecx+112] + movq [edx+112], mm2 + + movq mm3, [eax+120] + paddsw mm3, [ebx+120] + paddsw mm3, [ecx+120] + movq [edx+120], mm3 + + ret +endp + +align 4 +proc mix_4_1_mmx stdcall, output:dword, str0:dword, str1:dword,\ + str2:dword, str3:dword + + mov edx, [output] + mov esi, [str0] + mov eax, [str1] + mov ebx, [str2] + mov ecx, [str3] + + movq mm0, [esi] + movq mm1, [eax] + paddsw mm0, [ebx] + paddsw mm1, [ecx] + paddsw mm0, mm1 + movq [edx], mm0 + + movq mm2, [esi+8] + movq mm3, [eax+8] + paddsw mm2, [ebx+8] + paddsw mm3, [ecx+8] + paddsw mm2, mm3 + movq [edx+8], mm2 + + movq mm0, [esi+16] + movq mm1, [eax+16] + paddsw mm0, [ebx+16] + paddsw mm1, [ecx+16] + paddsw mm0, mm1 + movq [edx+16], mm0 + + movq mm2, [esi+24] + movq mm3, [eax+24] + paddsw mm2, [ebx+24] + paddsw mm3, [ecx+24] + paddsw mm2, mm3 + movq [edx+24], mm2 + + movq mm0, [esi+32] + movq mm1, [eax+32] + paddsw mm0, [ebx+32] + paddsw mm1, [ecx+32] + paddsw mm0, mm1 + movq [edx+32], mm0 + + movq mm2, [esi+40] + movq mm3, [eax+40] + paddsw mm2, [ebx+40] + paddsw mm3, [ecx+40] + paddsw mm2, mm3 + movq [edx+40], mm2 + + movq mm0, [esi+48] + movq mm1, [eax+48] + paddsw mm0, [ebx+48] + paddsw mm1, [ecx+48] + paddsw mm0, mm1 + movq [edx+48], mm0 + + movq mm2, [esi+56] + movq mm3, [eax+56] + paddsw mm2, [ebx+56] + paddsw mm3, [ecx+56] + paddsw mm2, mm3 + movq [edx+56], mm2 + + movq mm0, [esi+64] + movq mm1, [eax+64] + paddsw mm0, [ebx+64] + paddsw mm1, [ecx+64] + paddsw mm0, mm1 + movq [edx+64], mm0 + + movq mm2, [esi+72] + movq mm3, [eax+72] + paddsw mm2, [ebx+72] + paddsw mm3, [ecx+72] + paddsw mm2, mm3 + movq [edx+72], mm2 + + movq mm2, [esi+80] + movq mm3, [eax+80] + paddsw mm2, [ebx+80] + paddsw mm3, [ecx+80] + paddsw mm2, mm3 + movq [edx+80], mm2 + + movq mm2, [esi+88] + movq mm3, [eax+88] + paddsw mm2, [ebx+88] + paddsw mm3, [ecx+88] + paddsw mm2, mm3 + movq [edx+88], mm2 + + movq mm2, [esi+96] + movq mm3, [eax+96] + paddsw mm2, [ebx+96] + paddsw mm3, [ecx+96] + paddsw mm2, mm3 + movq [edx+96], mm2 + + movq mm2, [esi+104] + movq mm3, [eax+104] + paddsw mm2, [ebx+104] + paddsw mm3, [ecx+104] + paddsw mm2, mm3 + movq [edx+104], mm2 + + movq mm2, [esi+112] + movq mm3, [eax+112] + paddsw mm2, [ebx+112] + paddsw mm3, [ecx+112] + paddsw mm2, mm3 + movq [edx+112], mm2 + + movq mm2, [esi+120] + movq mm3, [eax+120] + paddsw mm2, [ebx+120] + paddsw mm3, [ecx+120] + paddsw mm2, mm3 + movq [edx+120], mm2 + + ret +endp + +align 4 +proc copy_mem stdcall, output:dword, input:dword + + mov edi, [output] + mov esi, [input] + mov ecx, 0x80 +.l1: + mov eax, [esi] + mov [edi], eax + add esi, 4 + add edi, 4 + loop .l1 + + ret +endp + +proc memcpy +@@: + mov eax, [esi] + mov [edi], eax + add esi, 4 + add edi, 4 + dec ecx + jnz @B + ret +endp + + + diff --git a/kernel/trunk/drivers/PROC32.INC b/kernel/trunk/drivers/PROC32.INC new file mode 100644 index 0000000000..23c56b03c1 --- /dev/null +++ b/kernel/trunk/drivers/PROC32.INC @@ -0,0 +1,268 @@ + +; Macroinstructions for defining and calling procedures + +macro stdcall proc,[arg] ; directly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call proc } + +macro invoke proc,[arg] ; indirectly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call [proc] } + +macro ccall proc,[arg] ; directly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call proc + if size@ccall + add esp,size@ccall + end if } + +macro cinvoke proc,[arg] ; indirectly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call [proc] + if size@ccall + add esp,size@ccall + end if } + +macro proc [args] ; define procedure + { common + match name params, args> + \{ define@proc name, \{ prologue name,flag,parmbytes,localbytes,reglist \} + macro locals + \{ virtual at ebp-localbytes+current + macro label . \\{ deflocal@proc .,:, \\} + struc db [val] \\{ \common deflocal@proc .,db,val \\} + struc dw [val] \\{ \common deflocal@proc .,dw,val \\} + struc dp [val] \\{ \common deflocal@proc .,dp,val \\} + struc dd [val] \\{ \common deflocal@proc .,dd,val \\} + struc dt [val] \\{ \common deflocal@proc .,dt,val \\} + struc dq [val] \\{ \common deflocal@proc .,dq,val \\} + struc rb cnt \\{ deflocal@proc .,rb cnt, \\} + struc rw cnt \\{ deflocal@proc .,rw cnt, \\} + struc rp cnt \\{ deflocal@proc .,rp cnt, \\} + struc rd cnt \\{ deflocal@proc .,rd cnt, \\} + struc rt cnt \\{ deflocal@proc .,rt cnt, \\} + struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} + macro endl + \{ purge label + restruc db,dw,dp,dd,dt,dq + restruc rb,rw,rp,rd,rt,rq + restruc byte,word,dword,pword,tword,qword + current = $-(ebp-localbytes) + end virtual \} + macro ret operand + \{ match any, operand \\{ retn operand \\} + match , operand \\{ match epilogue:reglist, epilogue@proc: + \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} + macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 + end if \} } + +macro defargs@proc [arg] + { common + if ~ arg eq + forward + local ..arg,current@arg + match argname:type, arg + \{ current@arg equ argname + label ..arg type + argname equ ..arg + if dqword eq type + dd ?,?,?,? + else if tbyte eq type + dd ?,?,? + else if qword eq type | pword eq type + dd ?,? + else + dd ? + end if \} + match =current@arg,current@arg + \{ current@arg equ arg + arg equ ..arg + ..arg dd ? \} + common + args@proc equ current@arg + forward + restore current@arg + common + end if } + +macro deflocal@proc name,def,[val] + { common + match vars, all@vars \{ all@vars equ all@vars, \} + all@vars equ all@vars name + forward + local ..var,..tmp + ..var def val + match =?, val \{ ..tmp equ \} + match any =dup (=?), val \{ ..tmp equ \} + match tmp : value, ..tmp : val + \{ tmp: end virtual + initlocal@proc ..var,def value + virtual at tmp\} + common + match first rest, ..var, \{ name equ first \} } + +macro initlocal@proc name,def + { virtual at name + def + size@initlocal = $ - name + end virtual + position@initlocal = 0 + while size@initlocal > position@initlocal + virtual at name + def + if size@initlocal - position@initlocal < 2 + current@initlocal = 1 + load byte@initlocal byte from name+position@initlocal + else if size@initlocal - position@initlocal < 4 + current@initlocal = 2 + load word@initlocal word from name+position@initlocal + else + current@initlocal = 4 + load dword@initlocal dword from name+position@initlocal + end if + end virtual + if current@initlocal = 1 + mov byte [name+position@initlocal],byte@initlocal + else if current@initlocal = 2 + mov word [name+position@initlocal],word@initlocal + else + mov dword [name+position@initlocal],dword@initlocal + end if + position@initlocal = position@initlocal + current@initlocal + end while } + +macro endp + { purge ret,locals,endl + finish@proc + purge finish@proc + restore regs@proc + match all,args@proc \{ restore all \} + restore args@proc + match all,all@vars \{ restore all \} } + +macro local [var] + { common + locals + forward done@local equ + match varname[count]:vartype, var + \{ match =BYTE, vartype \\{ varname rb count + restore done@local \\} + match =WORD, vartype \\{ varname rw count + restore done@local \\} + match =DWORD, vartype \\{ varname rd count + restore done@local \\} + match =PWORD, vartype \\{ varname rp count + restore done@local \\} + match =QWORD, vartype \\{ varname rq count + restore done@local \\} + match =TBYTE, vartype \\{ varname rt count + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + rq count+count + restore done@local \\} + match , done@local \\{ virtual + varname vartype + end virtual + rb count*sizeof.\#vartype + restore done@local \\} \} + match :varname:vartype, done@local:var + \{ match =BYTE, vartype \\{ varname db ? + restore done@local \\} + match =WORD, vartype \\{ varname dw ? + restore done@local \\} + match =DWORD, vartype \\{ varname dd ? + restore done@local \\} + match =PWORD, vartype \\{ varname dp ? + restore done@local \\} + match =QWORD, vartype \\{ varname dq ? + restore done@local \\} + match =TBYTE, vartype \\{ varname dt ? + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + dq ?,? + restore done@local \\} + match , done@local \\{ varname vartype + restore done@local \\} \} + match ,done@local + \{ var + restore done@local \} + common + endl } diff --git a/kernel/trunk/drivers/SIS.ASM b/kernel/trunk/drivers/SIS.ASM new file mode 100644 index 0000000000..9fe34d73b0 --- /dev/null +++ b/kernel/trunk/drivers/SIS.ASM @@ -0,0 +1,1177 @@ + +format MS COFF + + +include 'proc32.inc' + +DEBUG equ 1 + +CPU_FREQ equ 2000d ;cpu freq in MHz + +BIT0 EQU 0x00000001 +BIT1 EQU 0x00000002 +BIT2 EQU 0x00000004 +BIT3 EQU 0x00000008 +BIT4 EQU 0x00000010 +BIT5 EQU 0x00000020 +BIT6 EQU 0x00000040 +BIT7 EQU 0x00000080 +BIT8 EQU 0x00000100 +BIT9 EQU 0x00000200 +BIT10 EQU 0x00000400 +BIT11 EQU 0x00000800 +BIT12 EQU 0x00001000 +BIT13 EQU 0x00002000 +BIT14 EQU 0x00004000 +BIT15 EQU 0x00008000 +BIT16 EQU 0x00010000 +BIT17 EQU 0x00020000 +BIT18 EQU 0x00040000 +BIT19 EQU 0x00080000 +BIT20 EQU 0x00100000 +BIT21 EQU 0x00200000 +BIT22 EQU 0x00400000 +BIT23 EQU 0x00800000 +BIT24 EQU 0x00100000 +BIT25 EQU 0x02000000 +BIT26 EQU 0x04000000 +BIT27 EQU 0x08000000 +BIT28 EQU 0x10000000 +BIT29 EQU 0x20000000 +BIT30 EQU 0x40000000 +BIT31 EQU 0x80000000 + +VID_SIS equ 0x1039 +CTRL_SIS equ 0x7012 + +PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list +PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register +PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index +PCM_OUT_SR_REG equ 0x18 ; PCM out Status register +PCM_OUT_PIV_REG equ 0x1a ; PCM out prefetched index +PCM_OUT_CIV_REG equ 0x14 ; PCM out current index + +PCM_IN_CR_REG equ 0x0b ; PCM in Control Register +MC_IN_CR_REG equ 0x2b ; MIC in Control Register +RR equ BIT1 ; reset registers. Nukes all regs + +CODEC_MASTER_VOL_REG equ 0x02 +CODEC_AUX_VOL equ 0x04 ; +CODEC_PCM_OUT_REG equ 18h ; PCM output volume +CODEC_EXT_AUDIO_REG equ 28h ; extended audio +CODEC_EXT_AUDIO_CTRL_REG equ 2ah ; extended audio control +CODEC_PCM_FRONT_DACRATE_REG equ 2ch ; PCM out sample rate +CODEC_PCM_SURND_DACRATE_REG equ 2eh ; surround sound sample rate +CODEC_PCM_LFE_DACRATE_REG equ 30h ; LFE sample rate + + +GLOB_CTRL equ 0x2C ; Global Control +CTRL_STAT equ 0x30 ; Global Status +CTRL_CAS equ 0x34 ; Codec Access Semiphore + +CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit + +CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready + +CTRL_ST_RCS equ 0x00008000 ; Read Completion Status + +CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable +CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off +CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset +CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset +CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable + +CODEC_REG_POWERDOWN equ 0x26 +CODEC_REG_ST equ 0x26 + + +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 0 + .devfn dd 0 + + .vendor dd 0 + .dev_id dd 0 + .pci_cmd dd 0 + .pci_stat dd 0 + + .codec_io_base dd 0 + .codec_mem_base dd 0 + + .ctrl_io_base dd 0 + .ctrl_mem_base dd 0 + .cfg_reg dd 0 + .int_line dd 0 + + .vendor_ids dd 0 ;vendor id string + .ctrl_ids dd 0 ;hub id string + + .buffer dd 0 + + .notify_pos dd 0 + .notify_task dd 0 + + .lvi_reg dd 0 + .ctrl_setup dd 0 + .user_callback dd 0 + .codec_read16 dd 0 + .codec_write16 dd 0 + + .ctrl_read8 dd 0 + .ctrl_read16 dd 0 + .ctrl_read32 dd 0 + + .ctrl_write8 dd 0 + .ctrl_write16 dd 0 + .ctrl_write32 dd 0 +} + +struc CODEC ;Audio Chip base class +{ + .chip_id dd 0 + .flags dd 0 + .status dd 0 + + .ac_vendor_ids dd 0 ;ac vendor id string + .chip_ids dd 0 ;chip model string + + .shadow_flag dd 0 + dd 0 + + .regs dw 0 ; codec registers + .reg_master_vol dw 0 ;0x02 + .reg_aux_out_vol dw 0 ;0x04 + .reg_mone_vol dw 0 ;0x06 + .reg_master_tone dw 0 ;0x08 + .reg_beep_vol dw 0 ;0x0A + .reg_phone_vol dw 0 ;0x0C + .reg_mic_vol dw 0 ;0x0E + .reg_line_in_vol dw 0 ;0x10 + .reg_cd_vol dw 0 ;0x12 + .reg_video_vol dw 0 ;0x14 + .reg_aux_in_vol dw 0 ;0x16 + .reg_pcm_out_vol dw 0 ;0x18 + .reg_rec_select dw 0 ;0x1A + .reg_rec_gain dw 0 ;0x1C + .reg_rec_gain_mic dw 0 ;0x1E + .reg_gen dw 0 ;0x20 + .reg_3d_ctrl dw 0 ;0X22 + .reg_page dw 0 ;0X24 + .reg_powerdown dw 0 ;0x26 + .reg_ext_audio dw 0 ;0x28 + .reg_ext_st dw 0 ;0x2a + .reg_pcm_front_rate dw 0 ;0x2c + .reg_pcm_surr_rate dw 0 ;0x2e + .reg_lfe_rate dw 0 ;0x30 + .reg_pcm_in_rate dw 0 ;0x32 + dw 0 ;0x34 + .reg_cent_lfe_vol dw 0 ;0x36 + .reg_surr_vol dw 0 ;0x38 + .reg_spdif_ctrl dw 0 ;0x3A + dw 0 ;0x3C + dw 0 ;0x3E + dw 0 ;0x40 + dw 0 ;0x42 + dw 0 ;0x44 + dw 0 ;0x46 + dw 0 ;0x48 + dw 0 ;0x4A + dw 0 ;0x4C + dw 0 ;0x4E + dw 0 ;0x50 + dw 0 ;0x52 + dw 0 ;0x54 + dw 0 ;0x56 + dw 0 ;0x58 + dw 0 ;0x5A + dw 0 ;0x5C + dw 0 ;0x5E + .reg_page_0 dw 0 ;0x60 + .reg_page_1 dw 0 ;0x62 + .reg_page_2 dw 0 ;0x64 + .reg_page_3 dw 0 ;0x66 + .reg_page_4 dw 0 ;0x68 + .reg_page_5 dw 0 ;0x6A + .reg_page_6 dw 0 ;0x6C + .reg_page_7 dw 0 ;0x6E + dw 0 ;0x70 + dw 0 ;0x72 + dw 0 ;0x74 + dw 0 ;0x76 + dw 0 ;0x78 + dw 0 ;0x7A + .reg_vendor_id_1 dw 0 ;0x7C + .reg_vendor_id_2 dw 0 ;0x7E + + + .reset dd 0 ;virual + .set_master_vol dd 0 +} + +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 + +OS_BASE equ 0; 0x80400000 +new_app_base equ 0x60400000; 0x01000000 +PROC_BASE equ OS_BASE+0x0080000 + + +public service_proc +public START +public IMPORTS + +section '.flat' align 16 + +START: + 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 + + if DEBUG + mov esi, msgInitCodec + call [SysMsgBoardStr] + end if + + call init_codec + test eax, eax + jz .fail + + if DEBUG + mov esi, [codec.ac_vendor_ids] + call [SysMsgBoardStr] + + mov esi, [codec.chip_ids] + call [SysMsgBoardStr] + end if + + call reset_controller + call setup_codec + + mov esi, msgPrimBuff + call [SysMsgBoardStr] + + call create_primary_buff + + stdcall [AttachIntHandler], [ctrl.int_line], ac97_irq + + stdcall [RegService], sz_sound_srv, service_proc + + mov esi, msgOk + call [SysMsgBoardStr] + + ret + +.fail: + if DEBUG + mov esi, msgFail + call [SysMsgBoardStr] + end if + + xor eax, eax + ret + +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, 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 ebx, [edi+input] + stdcall set_master_vol, [ebx] + ret +@@: + cmp eax, DEV_GET_MASTERVOL + jne @F + mov ebx, [edi+output] + test ebx, ebx + jz .fail + + stdcall get_master_vol, ebx + ret +@@: + cmp eax, DEV_GET_INFO + jne @F + mov ebx, [edi+output] + stdcall get_dev_info, ebx + ret +@@: +.fail: + xor eax, eax + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + +align 4 +proc ac97_irq + +; if DEBUG +; mov esi, msgIRQ +; call [SysMsgBoardStr] +; end if + + mov edx, PCM_OUT_CR_REG + mov al, 0x14 + call [ctrl.ctrl_write8] + + mov ax, 0x1c + mov edx, PCM_OUT_SR_REG + call [ctrl.ctrl_write16] + + mov edx, PCM_OUT_CIV_REG + call [ctrl.ctrl_read8] + + and eax, 0x1F + cmp eax, [civ_val] + je .skip + + mov [civ_val], eax + dec eax + and eax, 0x1F + mov [ctrl.lvi_reg], eax + + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + call [ctrl.ctrl_write8] + + mov eax, [civ_val] + add eax, 2 + and eax, 31 + mov ebx, dword [buff_list+eax*4] + + cmp [ctrl.user_callback], 0 + je @f + + stdcall [ctrl.user_callback], ebx +@@: + ret + +.skip: + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + 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 + rep stosd + + stdcall [GetPgAddr], [ctrl.buffer] + + mov ebx, 0xC0004000 + mov ecx, 4 + mov edi, pcmout_bdl +@@: + mov [edi], eax + mov [edi+4], ebx + + mov [edi+32], eax + mov [edi+4+32], ebx + + mov [edi+64], eax + mov [edi+4+64], ebx + + mov [edi+96], eax + mov [edi+4+96], ebx + + mov [edi+128], eax + mov [edi+4+128], ebx + + mov [edi+160], eax + mov [edi+4+160], ebx + + mov [edi+192], eax + mov [edi+4+192], ebx + + mov [edi+224], eax + mov [edi+4+224], ebx + + add eax, 0x4000 + add edi, 8 + loop @B + + mov edi, buff_list + mov eax, [ctrl.buffer] + mov ecx, 4 +@@: + mov [edi], eax + mov [edi+16], eax + mov [edi+32], eax + mov [edi+48], eax + mov [edi+64], eax + mov [edi+80], eax + mov [edi+96], eax + mov [edi+112], eax + + add eax, 0x4000 + add edi, 4 + loop @B + + mov ecx, pcmout_bdl + stdcall [GetPgAddr], ecx + and ecx, 0xFFF + add eax, ecx + + mov edx, PCM_OUT_BDL + call [ctrl.ctrl_write32] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + and eax, not 0x000000C0 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + + 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 [ctrl.vendor_ids], msg_SIS + + mov esi, [edi+8] + mov [ctrl.ctrl_setup], esi + + ret +.err: + xor eax, eax + 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 + + stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x10 + and eax,0xFFFE + mov [ctrl.codec_io_base], eax + + stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x14 + and eax, 0xFFC0 + mov [ctrl.ctrl_io_base], eax + + stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x18 + mov [ctrl.codec_mem_base], eax + + stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x1C + mov [ctrl.ctrl_mem_base], eax + + stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x3C + and eax, 0xFF + mov [ctrl.int_line], eax + + stdcall [PciRead8], [ctrl.bus], [ctrl.devfn], dword 0x41 + and eax, 0xFF + mov [ctrl.cfg_reg], eax + + call [ctrl.ctrl_setup] + xor eax, eax + inc eax + ret +endp + +align 4 +proc set_SIS + 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 reset_controller + + xor eax, eax + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + + mov eax, RR + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + + + ret +endp + +align 4 +proc init_codec + locals + counter dd ? + endl + + call reset_codec + and eax, eax + jz .err + + xor edx, edx ;ac_reg_0 + call [ctrl.codec_write16] + + xor eax, eax + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_write16] + + mov [counter], 200 ; total 200*5 ms = 1s +.wait: + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_read16] + and eax, 0x0F + cmp eax, 0x0F + jz .ready + + mov eax, 5000 ; wait 5 ms + call StallExec + sub [counter] , 1 + jnz .wait +.err: + xor eax, eax ; timeout error + ret +.ready: + call detect_codec + + xor eax, eax + inc eax + ret +endp + +align 4 +proc reset_codec + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + + test eax, 0x02 + jz .cold + + call warm_reset + jnc .ok +.cold: + call cold_reset + jnc .ok + + if DEBUG + mov esi, msgCFail + call [SysMsgBoardStr] + end if + xor eax, eax ; timeout error + ret +.ok: + xor eax, eax + inc eax + ret +endp + +align 4 +proc warm_reset + locals + counter dd ? + endl + + mov eax, 0x06 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgWarm + call [SysMsgBoardStr] + end if + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + test eax, 4 + jz .ok + sub [counter], 1 + jnz .wait + + if DEBUG + mov esi, msgWRFail + call [SysMsgBoardStr] + end if + + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +.fail: + stc + ret +endp + +align 4 +proc cold_reset + locals + counter dd ? + endl + + xor eax, eax + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgCold + call [SysMsgBoardStr] + end if + + mov eax, 1000000 ; wait 1 s + call StallExec + + mov eax, 2 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + test eax, 4 + jz .ok + sub [counter], 1 + jnz .wait + + if DEBUG + mov esi, msgCRFail + call [SysMsgBoardStr] + end if + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +.fail: + stc + ret +endp + +align 4 +proc play + xor eax, eax + mov [civ_val], eax + mov edx, PCM_OUT_CIV_REG + call [ctrl.ctrl_write8] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc stop + mov edx, PCM_OUT_CR_REG + mov ax, 0x14 + call [ctrl.ctrl_write8] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + ret +endp + +align 4 +proc get_dev_info stdcall, p_info:dword + virtual at esi + CTRL_INFO CTRL_INFO + end virtual + + mov esi, [p_info] + mov eax, [ctrl.int_line] + mov ebx, [ctrl.codec_io_base] + mov ecx, [ctrl.ctrl_io_base] + mov edx, [ctrl.codec_mem_base] + mov edi, [ctrl.ctrl_mem_base] + + mov [CTRL_INFO.irq], eax + mov [CTRL_INFO.codec_io_base], ebx + mov [CTRL_INFO.ctrl_io_base], ecx + mov [CTRL_INFO.codec_mem_base], edx + mov [CTRL_INFO.ctrl_mem_base], edi + + mov eax, [codec.chip_id] + mov [CTRL_INFO.codec_id], eax + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_cntrl], eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_sta], eax + + mov ebx, [ctrl.pci_cmd] + mov [CTRL_INFO.pci_cmd], ebx + + ret +endp + +align 4 +proc set_callback stdcall, handler:dword + mov eax, [handler] + mov [ctrl.user_callback], eax + ret +endp + +align 4 +proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax + + mov edx, [ac_reg] + + mov ebx, edx + shr ebx, 1 + bt [codec.shadow_flag], ebx + jc .use_shadow + + call [ctrl.codec_read16] ;change edx !!! + mov ecx, eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + test eax, CTRL_ST_RCS + jz .read_ok + + mov edx, CTRL_STAT + call [ctrl.ctrl_write32] + xor eax,eax + not eax ;timeout + ret +.read_ok: + mov edx, [ac_reg] + mov [codec.regs+edx], cx + bts [codec.shadow_flag], ebx + mov eax, ecx + ret +.use_shadow: + movzx eax, word [codec.regs+edx] + ret +endp + +align 4 +proc codec_write stdcall, ac_reg:dword + push eax + call check_semafore + and eax, eax + jz .err + pop eax + + mov esi, [ac_reg] + mov edx, esi + call [ctrl.codec_write16] + mov [codec.regs+esi], ax + shr esi, 1 + bts [codec.shadow_flag], esi + ret +.err: + pop eax + ret +endp + + +align 4 +proc codec_check_ready + + mov edx, CTRL_ST + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .not_ready + + xor eax, wax + inc eax + ret + +align 4 +.not_ready: + xor eax, eax + ret +endp + + +align 4 +proc check_semafore + local counter:DWORD + + mov [counter], 100 +.l1: + mov edx, CTRL_CAS + call [ctrl.ctrl_read8] + and eax, CAS_FLAG + jz .ok + + mov eax, 1 + call StallExec + sub [counter], 1 + jnz .l1 + xor eax, eax + ret +align 4 +.ok: + xor eax,eax + inc eax + ret +endp + +align 4 +proc StallExec + push ecx + push edx + push ebx + push eax + + mov ecx, CPU_FREQ + mul ecx + mov ebx, eax ;low + mov ecx, edx ;high + rdtsc + add ebx, eax + adc ecx,edx +@@: + rdtsc + sub eax, ebx + sbb edx, ecx + jb @B + + pop eax + pop ebx + pop edx + pop ecx + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CONTROLLER IO functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +proc codec_io_r16 + add edx, [ctrl.codec_io_base] + in ax, dx + ret +endp + +align 4 +proc codec_io_w16 + add edx, [ctrl.codec_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_r8 + add edx, [ctrl.ctrl_io_base] + in al, dx + ret +endp + +align 4 +proc ctrl_io_r16 + add edx, [ctrl.ctrl_io_base] + in ax, dx + ret +endp + +align 4 +proc ctrl_io_r32 + add edx, [ctrl.ctrl_io_base] + in eax, dx + ret +endp + +align 4 +proc ctrl_io_w8 + add edx, [ctrl.ctrl_io_base] + out dx, al + ret +endp + +align 4 +proc ctrl_io_w16 + add edx, [ctrl.ctrl_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_w32 + add edx, [ctrl.ctrl_io_base] + out dx, eax + ret +endp + +include "codec.inc" + + +align 16 +pcmout_bdl dq 32 dup(0) +buff_list dd 32 dup(0) + +align 16 +ctrl AC_CNTRL + +align 16 +codec CODEC + +civ_val dd 0 + +align 16 +devices dd (CTRL_SIS shl 16)+VID_SIS,msg_AC, set_SIS + dd 0 + +align 16 +imp_table: +IMPORTS: + +AttachIntHandler dd szAttachIntHandler +SysMsgBoardStr dd szSysMsgBoardStr +PciApi dd szPciApi +PciRead32 dd szPciRead32 +PciRead8 dd szPciRead8 +PciWrite8 dd szPciWrite8 +AllocKernelSpace dd szAllocKernelSpace +MapPage dd szMapPage +KernelAlloc dd szKernelAlloc +GetPgAddr dd szGetPgAddr +RegService dd szRegService +GetCurrentTask dd szGetCurrentTask + dd 0 + +msg_AC db '7012 AC97 controller',13,10, 0 +msg_SIS db 'Silicon Integrated Systems',13,10, 0 + +szKernel db 'KERNEL', 0 +szAttachIntHandler db 'AttachIntHandler',0 +szSysMsgBoardStr db 'SysMsgBoardStr', 0 +szPciApi db 'PciApi', 0 +szPciRead32 db 'PciRead32', 0 +szPciRead8 db 'PciRead8', 0 +szPciWrite8 db 'PciWrite8',0 +szAllocKernelSpace db 'AllocKernelSpace',0 +szMapPage db 'MapPage',0 +szRegService db 'RegService',0 +szKernelAlloc db 'KernelAlloc',0 +szGetPgAddr db 'GetPgAddr',0 +szGetCurrentTask db 'GetCurrentTask ',0 + +sz_sound_srv db 'SOUND',0 + +msgInit db 'detect hardware...',13,10,0 +msgFail db 'device not found',13,10,0 +msgPlay db 'start play', 13,10,0 +msgStop db 'stop play', 13,10,0 +msgNotify db 'call notify',13,10,0 +msgIRQ db 'AC97 IRQ', 13,10,0 +msgInitCtrl db 'init controller',13,10,0 +msgInitCodec db 'init codec',13,10,0 +msgPrimBuff db 'create primary buffer',13,10,0 +msgReg db 'set service handler',13,10,0 +msgOk db 'service installed',13,10,0 +msgCold db 'cold resret',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 diff --git a/kernel/trunk/drivers/Unisound.asm b/kernel/trunk/drivers/Unisound.asm new file mode 100644 index 0000000000..b2828d5f16 --- /dev/null +++ b/kernel/trunk/drivers/Unisound.asm @@ -0,0 +1,1394 @@ + +format MS COFF + + +include 'proc32.inc' + +DEBUG equ 1 + +REMAP_IRQ equ 0 + +;irq 0,1,2,8,12,13 íåäîñòóïíû +; FEDCBA9876543210 +VALID_IRQ equ 1100111011111000b +ATTCH_IRQ equ 0000111010101000b + +IRQ_LINE equ 0 + +CPU_FREQ equ 2600d + +BIT0 EQU 0x00000001 +BIT1 EQU 0x00000002 +BIT2 EQU 0x00000004 +BIT3 EQU 0x00000008 +BIT4 EQU 0x00000010 +BIT5 EQU 0x00000020 +BIT6 EQU 0x00000040 +BIT7 EQU 0x00000080 +BIT8 EQU 0x00000100 +BIT9 EQU 0x00000200 +BIT10 EQU 0x00000400 +BIT11 EQU 0x00000800 +BIT12 EQU 0x00001000 +BIT13 EQU 0x00002000 +BIT14 EQU 0x00004000 +BIT15 EQU 0x00008000 +BIT16 EQU 0x00010000 +BIT17 EQU 0x00020000 +BIT18 EQU 0x00040000 +BIT19 EQU 0x00080000 +BIT20 EQU 0x00100000 +BIT21 EQU 0x00200000 +BIT22 EQU 0x00400000 +BIT23 EQU 0x00800000 +BIT24 EQU 0x00100000 +BIT25 EQU 0x02000000 +BIT26 EQU 0x04000000 +BIT27 EQU 0x08000000 +BIT28 EQU 0x10000000 +BIT29 EQU 0x20000000 +BIT30 EQU 0x40000000 +BIT31 EQU 0x80000000 + +VID_INTEL equ 0x8086 +VID_NVIDIA equ 0x10DE + +CTRL_ICH equ 0x2415 +CTRL_ICH0 equ 0x2425 +CTRL_ICH2 equ 0x2435 +CTRL_ICH3 equ 0x2445 +CTRL_ICH4 equ 0x24C5 +CTRL_ICH5 equ 0x24D5 +CTRL_ICH6 equ 0x266E +CTRL_ICH7 equ 0x27DE + +CTRL_NFORCE equ 0x01B1 +CTRL_NFORCE2 equ 0x006A +CTRL_NFORCE3 equ 0x00DA + + +PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list +PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register +PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index +PCM_OUT_SR_REG equ 0x16 ; PCM out Status register +PCM_OUT_PIV_REG equ 0x1a +PCM_OUT_CIV_REG equ 0x14 ; PCM out current index + +PCM_IN_CR_REG equ 0x0b ; PCM in Control Register +MC_IN_CR_REG equ 0x2b ; MIC in Control Register +RR equ BIT1 ; reset registers. Nukes all regs + +CODEC_MASTER_VOL_REG equ 0x02 +CODEC_AUX_VOL equ 0x04 ; +CODEC_PCM_OUT_REG equ 18h ; PCM output volume +CODEC_EXT_AUDIO_REG equ 28h ; extended audio +CODEC_EXT_AUDIO_CTRL_REG equ 2ah ; extended audio control +CODEC_PCM_FRONT_DACRATE_REG equ 2ch ; PCM out sample rate +CODEC_PCM_SURND_DACRATE_REG equ 2eh ; surround sound sample rate +CODEC_PCM_LFE_DACRATE_REG equ 30h ; LFE sample rate + +GLOB_CTRL equ 0x2C ; Global Control +CTRL_STAT equ 0x30 ; Global Status +CTRL_CAS equ 0x34 ; Codec Access Semiphore + +CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit + +CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready + +CTRL_ST_RCS equ 0x00008000 ; Read Completion Status + +CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable +CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off +CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset +CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset +CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable + +CODEC_REG_POWERDOWN equ 0x26 +CODEC_REG_ST equ 0x26 + +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 0 + .devfn dd 0 + + .vendor dd 0 + .dev_id dd 0 + .pci_cmd dd 0 + .pci_stat dd 0 + + .codec_io_base dd 0 + .codec_mem_base dd 0 + + .ctrl_io_base dd 0 + .ctrl_mem_base dd 0 + .cfg_reg dd 0 + .int_line dd 0 + + .vendor_ids dd 0 ;vendor id string + .ctrl_ids dd 0 ;hub id string + + .buffer dd 0 + + .notify_pos dd 0 + .notify_task dd 0 + + .lvi_reg dd 0 + .ctrl_setup dd 0 + .user_callback dd 0 + .codec_read16 dd 0 + .codec_write16 dd 0 + + .ctrl_read8 dd 0 + .ctrl_read16 dd 0 + .ctrl_read32 dd 0 + + .ctrl_write8 dd 0 + .ctrl_write16 dd 0 + .ctrl_write32 dd 0 +} + +struc CODEC ;Audio Chip base class +{ + .chip_id dd 0 + .flags dd 0 + .status dd 0 + + .ac_vendor_ids dd 0 ;ac vendor id string + .chip_ids dd 0 ;chip model string + + .shadow_flag dd 0 + dd 0 + + .regs dw 0 ; codec registers + .reg_master_vol dw 0 ;0x02 + .reg_aux_out_vol dw 0 ;0x04 + .reg_mone_vol dw 0 ;0x06 + .reg_master_tone dw 0 ;0x08 + .reg_beep_vol dw 0 ;0x0A + .reg_phone_vol dw 0 ;0x0C + .reg_mic_vol dw 0 ;0x0E + .reg_line_in_vol dw 0 ;0x10 + .reg_cd_vol dw 0 ;0x12 + .reg_video_vol dw 0 ;0x14 + .reg_aux_in_vol dw 0 ;0x16 + .reg_pcm_out_vol dw 0 ;0x18 + .reg_rec_select dw 0 ;0x1A + .reg_rec_gain dw 0 ;0x1C + .reg_rec_gain_mic dw 0 ;0x1E + .reg_gen dw 0 ;0x20 + .reg_3d_ctrl dw 0 ;0X22 + .reg_page dw 0 ;0X24 + .reg_powerdown dw 0 ;0x26 + .reg_ext_audio dw 0 ;0x28 + .reg_ext_st dw 0 ;0x2a + .reg_pcm_front_rate dw 0 ;0x2c + .reg_pcm_surr_rate dw 0 ;0x2e + .reg_lfe_rate dw 0 ;0x30 + .reg_pcm_in_rate dw 0 ;0x32 + dw 0 ;0x34 + .reg_cent_lfe_vol dw 0 ;0x36 + .reg_surr_vol dw 0 ;0x38 + .reg_spdif_ctrl dw 0 ;0x3A + dw 0 ;0x3C + dw 0 ;0x3E + dw 0 ;0x40 + dw 0 ;0x42 + dw 0 ;0x44 + dw 0 ;0x46 + dw 0 ;0x48 + dw 0 ;0x4A + dw 0 ;0x4C + dw 0 ;0x4E + dw 0 ;0x50 + dw 0 ;0x52 + dw 0 ;0x54 + dw 0 ;0x56 + dw 0 ;0x58 + dw 0 ;0x5A + dw 0 ;0x5C + dw 0 ;0x5E + .reg_page_0 dw 0 ;0x60 + .reg_page_1 dw 0 ;0x62 + .reg_page_2 dw 0 ;0x64 + .reg_page_3 dw 0 ;0x66 + .reg_page_4 dw 0 ;0x68 + .reg_page_5 dw 0 ;0x6A + .reg_page_6 dw 0 ;0x6C + .reg_page_7 dw 0 ;0x6E + dw 0 ;0x70 + dw 0 ;0x72 + dw 0 ;0x74 + dw 0 ;0x76 + dw 0 ;0x78 + dw 0 ;0x7A + .reg_vendor_id_1 dw 0 ;0x7C + .reg_vendor_id_2 dw 0 ;0x7E + + + .reset dd 0 ;virual + .set_master_vol dd 0 +} + +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 + +OS_BASE equ 0; 0x80400000 +new_app_base equ 0x60400000; 0x01000000 +PROC_BASE equ OS_BASE+0x0080000 + +public service_proc +public START +public IMPORTS + +section '.flat' align 16 + +START: + 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 + + if DEBUG + mov esi, msgInitCodec + call [SysMsgBoardStr] + end if + + call init_codec + test eax, eax + jz .fail + + if DEBUG + mov esi, [codec.ac_vendor_ids] + call [SysMsgBoardStr] + + mov esi, [codec.chip_ids] + call [SysMsgBoardStr] + end if + + call reset_controller + call setup_codec + + mov esi, msgPrimBuff + call [SysMsgBoardStr] + + call create_primary_buff + +; if REMAP_IRQ + +; call get_LPC_bus +; cmp eax, -1 +; jz .fail + +; mov [lpc_bus], 0 ;eax +; call remap_irq +; end if + + mov eax, VALID_IRQ + mov ebx, [ctrl.int_line] + mov esi, msgInvIRQ + bt eax, ebx + jnc .fail + mov eax, ATTCH_IRQ + mov esi, msgAttchIRQ + bt eax, ebx + jnc .fail + + stdcall [AttachIntHandler], ebx, ac97_irq + + stdcall [RegService], sz_sound_srv, service_proc + + mov esi, msgOk + call [SysMsgBoardStr] + + ret + +.fail: + if DEBUG + mov esi, msgFail + call [SysMsgBoardStr] + end if + + xor eax, eax + ret + +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, 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 ebx, [edi+input] + stdcall set_master_vol, [ebx] + ret +@@: + cmp eax, DEV_GET_MASTERVOL + jne @F + mov ebx, [edi+output] + test ebx, ebx + jz .fail + + stdcall get_master_vol, ebx + ret +@@: + cmp eax, DEV_GET_INFO + jne @F + mov ebx, [edi+output] + stdcall get_dev_info, ebx + ret +@@: +.fail: + xor eax, eax + ret +endp + +restore handle +restore io_code +restore input +restore inp_size +restore output +restore out_size + + +align 4 +proc remap_irq ;for Intel chipsets ONLY !!! + mov eax, VALID_IRQ + bt eax, IRQ_LINE + jnc .exit + + mov edx, 0x4D0 + in ax,dx + bts ax, IRQ_LINE + out dx, aX + + stdcall [PciWrite8], dword 0, dword 0xF8, dword 0x61, dword IRQ_LINE + mov [ctrl.int_line], IRQ_LINE + +.exit: + ret +endp + +align 4 +proc ac97_irq + +; if DEBUG +; mov esi, msgIRQ +; call [SysMsgBoardStr] +; end if + + mov edx, PCM_OUT_CR_REG + mov al, 0x14 + call [ctrl.ctrl_write8] + + mov ax, 0x1c + mov edx, PCM_OUT_SR_REG + call [ctrl.ctrl_write16] + + mov edx, PCM_OUT_CIV_REG + call [ctrl.ctrl_read8] + + and eax, 0x1F + cmp eax, [civ_val] + je .skip + + mov [civ_val], eax + dec eax + and eax, 0x1F + mov [ctrl.lvi_reg], eax + + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + call [ctrl.ctrl_write8] + + mov eax, [civ_val] + add eax, 2 + and eax, 31 + mov ebx, dword [buff_list+eax*4] + + cmp [ctrl.user_callback], 0 + je @f + + stdcall [ctrl.user_callback], ebx +@@: + ret + +.skip: + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + 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 + + stdcall [GetPgAddr], [ctrl.buffer] + + mov ebx, 0xC0002000 + mov ecx, 4 + mov edi, pcmout_bdl +@@: + mov [edi], eax + mov [edi+4], ebx + + mov [edi+32], eax + mov [edi+4+32], ebx + + mov [edi+64], eax + mov [edi+4+64], ebx + + mov [edi+96], eax + mov [edi+4+96], ebx + + mov [edi+128], eax + mov [edi+4+128], ebx + + mov [edi+160], eax + mov [edi+4+160], ebx + + mov [edi+192], eax + mov [edi+4+192], ebx + + mov [edi+224], eax + mov [edi+4+224], ebx + + add eax, 0x4000 + add edi, 8 + loop @B + + mov edi, buff_list + mov eax, [ctrl.buffer] + mov ecx, 4 +@@: + mov [edi], eax + mov [edi+16], eax + mov [edi+32], eax + mov [edi+48], eax + mov [edi+64], eax + mov [edi+80], eax + mov [edi+96], eax + mov [edi+112], eax + + add eax, 0x4000 + add edi, 4 + loop @B + + mov ecx, pcmout_bdl + stdcall [GetPgAddr], ecx + and ecx, 0xFFF + add eax, ecx + + mov edx, PCM_OUT_BDL + call [ctrl.ctrl_write32] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + ret +endp + +align 4 +proc detect_controller + locals + last_bus dd ? + bus dd ? + devfn dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call [PciApi] + cmp eax, -1 + je .err + + mov [last_bus], eax + +.next_bus: + and [devfn], 0 +.next_dev: + stdcall [PciRead32], [bus], [devfn], dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + mov edi, devices +@@: + mov ebx, [edi] + test ebx, ebx + jz .next + + cmp eax, ebx + je .found + add edi, 12 + jmp @B + +.next: inc [devfn] + cmp [devfn], 256 + jb .next_dev + mov eax, [bus] + inc eax + mov [bus], eax + cmp eax, [last_bus] + jna .next_bus + xor eax, eax + ret +.found: + mov ebx, [bus] + mov [ctrl.bus], ebx + + mov ecx, [devfn] + mov [ctrl.devfn], ecx + + mov edx, eax + and edx, 0xFFFF + mov [ctrl.vendor], edx + shr eax, 16 + mov [ctrl.dev_id], eax + + mov ebx, [edi+4] + mov [ctrl.ctrl_ids], ebx + mov esi, [edi+8] + mov [ctrl.ctrl_setup], esi + + cmp ebx, VID_INTEL + jne @F + mov [ctrl.vendor_ids], msg_Intel + ret +@@: + cmp ebx, VID_NVIDIA + jne @F + mov [ctrl.vendor_ids], msg_NVidia +@@: + mov [ctrl.vendor_ids], 0 ;something wrong ? + ret +.err: + xor eax, eax + ret +endp + +align 4 +proc get_LPC_bus ;for Intel chipsets ONLY !!! + locals + last_bus dd ? + bus dd ? + endl + + xor eax, eax + mov [bus], eax + inc eax + call [PciApi] + cmp eax, -1 + je .err + + mov [last_bus], eax +.next_bus: + stdcall [PciRead32], [bus], dword 0xF8, dword 0 + test eax, eax + jz .next + cmp eax, -1 + je .next + + cmp eax, 0x24D08086 + je .found +.next: + mov eax, [bus] + inc eax + cmp eax, [last_bus] + mov [bus], eax + jna .next_bus +.err: + xor eax, eax + dec eax + ret +.found: + mov eax, [bus] + 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 + + stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x10 + and eax,0xFFFE + mov [ctrl.codec_io_base], eax + + stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x14 + and eax, 0xFFC0 + mov [ctrl.ctrl_io_base], eax + + stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x18 + mov [ctrl.codec_mem_base], eax + + stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x1C + mov [ctrl.ctrl_mem_base], eax + + stdcall [PciRead32], [ctrl.bus], [ctrl.devfn], dword 0x3C + and eax, 0xFF + mov [ctrl.int_line], eax + + stdcall [PciRead8], [ctrl.bus], [ctrl.devfn], dword 0x41 + and eax, 0xFF + mov [ctrl.cfg_reg], eax + + call [ctrl.ctrl_setup] + xor eax, eax + inc eax + ret +endp + +align 4 +proc set_ICH + mov [ctrl.codec_read16], codec_io_r16 ;virtual + mov [ctrl.codec_write16], codec_io_w16 ;virtual + + mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual + mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual + mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual + + mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual + mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual + mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual + ret +endp + +PG_SW equ 0x003 +PG_NOCACHE equ 0x018 + +align 4 +proc set_ICH4 + stdcall [AllocKernelSpace], dword 0x2000 + mov edi, eax + stdcall [MapPage], edi,[ctrl.codec_mem_base],PG_SW+PG_NOCACHE + mov [ctrl.codec_mem_base], edi + add edi, 0x1000 + stdcall [MapPage], edi, [ctrl.ctrl_mem_base],PG_SW+PG_NOCACHE + mov [ctrl.ctrl_mem_base], edi + + mov [ctrl.codec_read16], codec_mem_r16 ;virtual + mov [ctrl.codec_write16], codec_mem_w16 ;virtual + + mov [ctrl.ctrl_read8 ], ctrl_mem_r8 ;virtual + mov [ctrl.ctrl_read16], ctrl_mem_r16 ;virtual + mov [ctrl.ctrl_read32], ctrl_mem_r32 ;virtual + + mov [ctrl.ctrl_write8 ], ctrl_mem_w8 ;virtual + mov [ctrl.ctrl_write16], ctrl_mem_w16 ;virtual + mov [ctrl.ctrl_write32], ctrl_mem_w32 ;virtual + ret +endp + +align 4 +proc reset_controller + + xor eax, eax + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + + mov eax, RR + mov edx, PCM_IN_CR_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + call [ctrl.ctrl_write8] + + mov edx, MC_IN_CR_REG + call [ctrl.ctrl_write8] + + ret +endp + +align 4 +proc init_codec + locals + counter dd ? + endl + + call reset_codec + and eax, eax + jz .err + + xor edx, edx ;ac_reg_0 + call [ctrl.codec_write16] + + xor eax, eax + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_write16] + + mov [counter], 200 ; total 200*5 ms = 1s +.wait: + mov edx, CODEC_REG_POWERDOWN + call [ctrl.codec_read16] + and eax, 0x0F + cmp eax, 0x0F + jz .ready + + mov eax, 5000 ; wait 5 ms + call StallExec + sub [counter] , 1 + jnz .wait +.err: + xor eax, eax ; timeout error + ret +.ready: + call detect_codec + + xor eax, eax + inc eax + ret +endp + +align 4 +proc reset_codec + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + + test eax, 0x02 + jz .cold + + call warm_reset + jnc .ok +.cold: + call cold_reset + jnc .ok + + if DEBUG + mov esi, msgCFail + call [SysMsgBoardStr] + end if + xor eax, eax ; timeout error + ret +.ok: + if DEBUG + mov esi, msgResetOk + call [SysMsgBoardStr] + end if + + xor eax, eax + inc eax + ret +endp + +align 4 +proc warm_reset + locals + counter dd ? + endl + + mov eax, 0x06 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgWarm + call [SysMsgBoardStr] + end if + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + test eax, 4 + jz .ok + sub [counter], 1 + jnz .wait + + if DEBUG + mov esi, msgWRFail + call [SysMsgBoardStr] + end if + + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +.fail: + stc + ret +endp + +align 4 +proc cold_reset + locals + counter dd ? + endl + + xor eax, eax + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + if DEBUG + mov esi, msgCold + call [SysMsgBoardStr] + end if + + mov eax, 1000000 ; wait 1 s + call StallExec + + mov eax, 2 + mov edx, GLOB_CTRL + call [ctrl.ctrl_write32] + + mov [counter], 10 ; total 10*100 ms = 1s +.wait: + mov eax, 100000 ; wait 100 ms + call StallExec + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + test eax, 4 + jz .ok + sub [counter], 1 + jnz .wait + + if DEBUG + mov esi, msgCRFail + call [SysMsgBoardStr] + end if + stc + ret +.ok: + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .fail + clc + ret +.fail: + stc + ret +endp + +align 4 +proc play + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + mov edx, PCM_OUT_CR_REG + mov ax, 0x1D + call [ctrl.ctrl_write8] + ret +endp + +align 4 +proc stop + mov edx, PCM_OUT_CR_REG + mov ax, 0x14 + call [ctrl.ctrl_write8] + + mov eax, 16 + mov [ctrl.lvi_reg], eax + mov edx, PCM_OUT_LVI_REG + call [ctrl.ctrl_write8] + + ret +endp + +align 4 +proc get_dev_info stdcall, p_info:dword + virtual at esi + CTRL_INFO CTRL_INFO + end virtual + + mov esi, [p_info] + mov eax, [ctrl.int_line] + mov ebx, [ctrl.codec_io_base] + mov ecx, [ctrl.ctrl_io_base] + mov edx, [ctrl.codec_mem_base] + mov edi, [ctrl.ctrl_mem_base] + + mov [CTRL_INFO.irq], eax + mov [CTRL_INFO.codec_io_base], ebx + mov [CTRL_INFO.ctrl_io_base], ecx + mov [CTRL_INFO.codec_mem_base], edx + mov [CTRL_INFO.ctrl_mem_base], edi + + mov eax, [codec.chip_id] + mov [CTRL_INFO.codec_id], eax + + mov edx, GLOB_CTRL + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_cntrl], eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + mov [CTRL_INFO.glob_sta], eax + + mov ebx, [ctrl.pci_cmd] + mov [CTRL_INFO.pci_cmd], ebx + + ret +endp + +align 4 +proc set_callback stdcall, handler:dword + mov eax, [handler] + mov [ctrl.user_callback], eax + ret +endp + +align 4 +proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax + + mov edx, [ac_reg] + + mov ebx, edx + shr ebx, 1 + bt [codec.shadow_flag], ebx + jc .use_shadow + + call [ctrl.codec_read16] ;change edx !!! + mov ecx, eax + + mov edx, CTRL_STAT + call [ctrl.ctrl_read32] + test eax, CTRL_ST_RCS + jz .read_ok + + mov edx, CTRL_STAT + call [ctrl.ctrl_write32] + xor eax,eax + not eax ;timeout + ret +.read_ok: + mov edx, [ac_reg] + mov [codec.regs+edx], cx + bts [codec.shadow_flag], ebx + mov eax, ecx + ret +.use_shadow: + movzx eax, word [codec.regs+edx] + ret +endp + +align 4 +proc codec_write stdcall, ac_reg:dword + push eax + call check_semafore + and eax, eax + jz .err + pop eax + + mov esi, [ac_reg] + mov edx, esi + call [ctrl.codec_write16] + mov [codec.regs+esi], ax + shr esi, 1 + bts [codec.shadow_flag], esi + ret +.err: + pop eax + ret +endp + +align 4 +proc codec_check_ready + + mov edx, CTRL_ST + call [ctrl.ctrl_read32] + and eax, CTRL_ST_CREADY + jz .not_ready + + xor eax, wax + inc eax + ret + +align 4 +.not_ready: + xor eax, eax + ret +endp + +align 4 +proc check_semafore + local counter:DWORD + + mov [counter], 100 +.l1: + mov edx, CTRL_CAS + call [ctrl.ctrl_read8] + and eax, CAS_FLAG + jz .ok + + mov eax, 1 + call StallExec + sub [counter], 1 + jnz .l1 + xor eax, eax + ret +align 4 +.ok: + xor eax,eax + inc eax + ret +endp + +align 4 +proc StallExec + push ecx + push edx + push ebx + push eax + + mov ecx, CPU_FREQ + mul ecx + mov ebx, eax ;low + mov ecx, edx ;high + rdtsc + add ebx, eax + adc ecx,edx +@@: + rdtsc + sub eax, ebx + sbb edx, ecx + jb @B + + pop eax + pop ebx + pop edx + pop ecx + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; CONTROLLER IO functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +proc codec_io_r16 + add edx, [ctrl.codec_io_base] + in ax, dx + ret +endp + +align 4 +proc codec_io_w16 + add edx, [ctrl.codec_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_r8 + add edx, [ctrl.ctrl_io_base] + in al, dx + ret +endp + +align 4 +proc ctrl_io_r16 + add edx, [ctrl.ctrl_io_base] + in ax, dx + ret +endp + +align 4 +proc ctrl_io_r32 + add edx, [ctrl.ctrl_io_base] + in eax, dx + ret +endp + +align 4 +proc ctrl_io_w8 + add edx, [ctrl.ctrl_io_base] + out dx, al + ret +endp + +align 4 +proc ctrl_io_w16 + add edx, [ctrl.ctrl_io_base] + out dx, ax + ret +endp + +align 4 +proc ctrl_io_w32 + add edx, [ctrl.ctrl_io_base] + out dx, eax + ret +endp + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; MEMORY MAPPED IO (os depended) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +align 4 +proc codec_mem_r16 + add edx, [ctrl.codec_mem_base] + mov ax, word [edx] + ret +endp + +align 4 +proc codec_mem_w16 + add edx, [ctrl.codec_mem_base] + mov word [edx], ax + ret +endp + +align 4 +proc ctrl_mem_r8 + add edx, [ctrl.ctrl_mem_base] + mov al, [edx] + ret +endp + +align 4 +proc ctrl_mem_r16 + add edx, [ctrl.ctrl_mem_base] + mov ax, [edx] + ret +endp + +align 4 +proc ctrl_mem_r32 + add edx, [ctrl.ctrl_mem_base] + mov eax, [edx] + ret +endp + +align 4 +proc ctrl_mem_w8 + add edx, [ctrl.ctrl_mem_base] + mov [edx], al + + ret +endp + +align 4 +proc ctrl_mem_w16 + add edx, [ctrl.ctrl_mem_base] + mov [edx], ax + ret +endp + +align 4 +proc ctrl_mem_w32 + add edx, [ctrl.ctrl_mem_base] + mov [edx], eax + ret +endp + + +include "codec.inc" + + +align 16 +pcmout_bdl dq 32 dup(0) +buff_list dd 32 dup(0) + +align 16 +ctrl AC_CNTRL + +align 16 +codec CODEC + +lpc_bus dd 0 +civ_val dd 0 + +align 16 +devices dd (CTRL_ICH shl 16)+VID_INTEL,msg_ICH, set_ICH + dd (CTRL_ICH0 shl 16)+VID_INTEL,msg_ICH0,set_ICH + dd (CTRL_ICH2 shl 16)+VID_INTEL,msg_ICH2,set_ICH + dd (CTRL_ICH3 shl 16)+VID_INTEL,msg_ICH3,set_ICH + dd (CTRL_ICH4 shl 16)+VID_INTEL,msg_ICH4,set_ICH4 + dd (CTRL_ICH5 shl 16)+VID_INTEL,msg_ICH5,set_ICH4 + dd (CTRL_ICH6 shl 16)+VID_INTEL,msg_ICH6,set_ICH4 + dd (CTRL_ICH7 shl 16)+VID_INTEL,msg_ICH7,set_ICH4 + + dd (CTRL_NFORCE shl 16)+VID_NVIDIA,msg_NForce, set_ICH + dd (CTRL_NFORCE2 shl 16)+VID_NVIDIA,msg_NForce2,set_ICH + dd (CTRL_NFORCE3 shl 16)+VID_NVIDIA,msg_NForce3,set_ICH + + dd 0 ;terminator + +align 16 +imp_table: +IMPORTS: + +AttachIntHandler dd szAttachIntHandler +SysMsgBoardStr dd szSysMsgBoardStr +PciApi dd szPciApi +PciRead32 dd szPciRead32 +PciRead8 dd szPciRead8 +PciWrite8 dd szPciWrite8 +AllocKernelSpace dd szAllocKernelSpace +MapPage dd szMapPage +KernelAlloc dd szKernelAlloc +GetPgAddr dd szGetPgAddr +RegService dd szRegService +GetCurrentTask dd szGetCurrentTask + dd 0 + +msg_ICH db 'Intel ICH', 13,10, 0 +msg_ICH0 db 'Intel ICH0', 13,10, 0 +msg_ICH2 db 'Intel ICH2', 13,10, 0 +msg_ICH3 db 'Intel ICH3', 13,10, 0 +msg_ICH4 db 'Intel ICH4', 13,10, 0 +msg_ICH5 db 'Intel ICH5', 13,10, 0 +msg_ICH6 db 'Intel ICH6', 13,10, 0 +msg_ICH7 db 'Intel ICH7', 13,10, 0 +msg_Intel db 'Intel Corp. ', 0 + +msg_NForce db 'NForce', 13,10, 0 +msg_NForce2 db 'NForce 2', 13,10, 0 +msg_NForce3 db 'NForce 3', 13,10, 0 +msg_NVidia db 'NVidea', 0 + + +szKernel db 'KERNEL', 0 +szAttachIntHandler db 'AttachIntHandler',0 +szSysMsgBoardStr db 'SysMsgBoardStr', 0 +szPciApi db 'PciApi', 0 +szPciRead32 db 'PciRead32', 0 +szPciRead8 db 'PciRead8', 0 +szPciWrite8 db 'PciWrite8',0 +szAllocKernelSpace db 'AllocKernelSpace',0 +szMapPage db 'MapPage',0 +szRegService db 'RegService',0 +szKernelAlloc db 'KernelAlloc',0 +szGetPgAddr db 'GetPgAddr',0 +szGetCurrentTask db 'GetCurrentTask ',0 + +sz_sound_srv db 'SOUND',0 + +msgInit db 'detect hardware...',13,10,0 +msgFail db 'device not found',13,10,0 +msgAttchIRQ db 'IRQ line not supported', 13,10, 0 +msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 +msgPlay db 'start play', 13,10,0 +msgStop db 'stop play', 13,10,0 +msgNotify db 'call notify',13,10,0 +msgIRQ db 'AC97 IRQ', 13,10,0 +msgInitCtrl db 'init controller',13,10,0 +msgInitCodec db 'init codec',13,10,0 +msgPrimBuff db 'create primary buffer',13,10,0 +msgReg db 'set service handler',13,10,0 +msgOk db 'service installed',13,10,0 +msgCold db 'cold reset',13,10,0 +msgWarm db 'warm reset',13,10,0 +msgWRFail db 'warm reset failed',13,10,0 +msgCRFail db 'cold reset failed',13,10,0 +msgCFail db 'codec not ready',13,10,0 +msgResetOk db 'reset complete',13,10,0 + diff --git a/kernel/trunk/hid/keyboard.inc b/kernel/trunk/hid/keyboard.inc index 8b293843ce..67ce5fee0c 100644 --- a/kernel/trunk/hid/keyboard.inc +++ b/kernel/trunk/hid/keyboard.inc @@ -86,12 +86,12 @@ hotkey_do_test: align 4 irq1: - save_ring3_context - mov ax, os_data - mov ds, ax - mov es, ax +; save_ring3_context +; mov ax, os_data +; mov ds, ax +; mov es, ax - mov eax, [0x3004] ; top window process + movzx eax,word[0x3004] ; top window process movzx eax,word[0xC400+eax*2] shl eax,8 mov al,[0x80000+eax+APPDATA.keyboard_mode] @@ -277,11 +277,12 @@ irq1: .exit.irq1: mov [check_idle_semaphore],5 - mov al,0x20 ; ready for next irq - out 0x20,al +; mov al,0x20 ; ready for next irq +; out 0x20,al - restore_ring3_context - iret +; restore_ring3_context +; iret + ret set_lights: mov al,0xED diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 750d414e4c..728bd84917 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -10,23 +10,27 @@ ;; Compile with last version FASM ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +include "proc32.inc" include "kglobals.inc" include "lang.inc" -WinMapAddress equ 0x460000 -display_data = 0x460000 +include "const.inc" + +NEW equ 0 + +;WinMapAddress equ 0x460000 +;display_data = 0x460000 max_processes equ 255 -window_data equ 0x0000 -tss_data equ 0xD20000 +;window_data equ 0x0000 +;tss_data equ 0xD20000 ;tss_step equ (128+2048) ; tss & i/o - 16384 ports, * 256=557056 tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4 -draw_data equ 0xC00000 -sysint_stack_data equ 0xC03000 +;draw_data equ 0xC00000 +;sysint_stack_data equ 0xC03000 - -twdw equ (0x3000-window_data) +;twdw equ (0x3000-window_data) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -116,17 +120,7 @@ app_data equ 3+app_data_l-gdts ; CR0 Flags - Protected mode and Paging - mov ecx,0x00000001 - ;and ebx,65535 - ;cmp ebx,00100000000000000b ; lfb -> paging - ;jb no_paging - ;mov ax,0x0000 - ;mov es,ax - ;mov al,[es:0x901E] - ;cmp al,1 - ;je no_paging - ;or ecx, 0x80000000 - ;no_paging: + mov ecx, 0x00000021 ; Enabling 32 bit protected mode @@ -158,7 +152,7 @@ app_data equ 3+app_data_l-gdts and eax, 10011111b *65536*256 + 0xffffff ; caching enabled mov cr0, eax jmp $+2 -org $+0x10000 +org $+0x10000 mov ax,os_data ; Selector for os mov ds,ax mov es,ax @@ -228,13 +222,6 @@ boot_log: ret -uglobal - cpuid_0 dd 0,0,0,0 - cpuid_1 dd 0,0,0,0 - cpuid_2 dd 0,0,0,0 - cpuid_3 dd 0,0,0,0 -endg - iglobal firstapp db '/rd/1/LAUNCHER',0 char db 'CHAR MT ' @@ -335,7 +322,7 @@ B32: mov byte [0x2f0000+0x901e],0x0 mov eax,[0x2f0000+0x9018] ;no_d_lfb: - mov [0xfe80],eax + mov [LFBAddress],eax cmp [0xfe0c],word 0100000000000000b jge setvesa20 @@ -366,47 +353,27 @@ B32: ; MEMORY MODEL -; mov [0xfe84],dword 0x100000*16 ; apps mem base address -; movzx ecx,byte [0x2f0000+0x9030] -; dec ecx -; mov eax,16*0x100000 ; memory-16 -; shl eax,cl -; mov [0xfe8c],eax ; memory for use -; cmp eax,16*0x100000 -; jne no16mb -; mov [0xfe84],dword 0xD80000 ; !!! 10 !!! -; no16mb: + call mem_test + mov [MEM_AMOUNT], eax -; init: -; 1) 0xFE84 - applications base -; 2) 0xFE8C - total amount of memory + mov [pg_data.mem_amount], eax + mov [pg_data.kernel_max], eax - xor edi, edi - m_GMS_loop: - add edi, 0x400000 - mov eax, dword [edi] - mov dword [edi], 'TEST' - wbinvd - cmp dword [edi], 'TEST' - jne m_GMS_exit - cmp dword [0], 'TEST' - je m_GMS_exit - mov dword [es:edi], eax - jmp m_GMS_loop - m_GMS_exit: - mov [edi], eax - ; now edi contains the EXACT amount of memory + shr eax, 12 + mov edx, eax + mov [pg_data.pages_count], eax + mov [pg_data.kernel_pages], eax - mov eax, 0x100000*16 - cmp edi, eax ;0x100000*16 - jb $ ; less than 16 Mb + shr eax, 3 + mov [pg_data.pagemap_size], eax + + shr edx, 10 + cmp edx, 4 + ja @f + inc edx ;at least 4Mb for kernel heap +@@: + mov [pg_data.kernel_tables], edx - mov dword [0xFE84], eax ;0x100000*16 - cmp edi, eax ;0x100000*16 - jne @f - mov dword [0xFE84], 0xD80000 ; =0x100000*13.5 - @@: - mov dword [0xFE8C], edi ;!!!!!!!!!!!!!!!!!!!!!!!!!! include 'detect/disks.inc' @@ -414,42 +381,98 @@ include 'detect/disks.inc' ; CHECK EXTRA REGION ; ENABLE PAGING - mov eax,cr0 - or eax,0x80000000 - mov cr0,eax - jmp $+2 - - call MEM_Init -;add 0x800000-0xc00000 area - cmp word [0xfe0c],0x13 - jle .less_memory - mov eax,0x800000 ;linear address - mov ebx,0x400000 shr 12 ;size in pages (4Mb) - mov ecx,0x800000 ;physical address - jmp .end_first_block -.less_memory: - mov eax,0x980000 ;linear address - mov ebx,0x280000 shr 12 ;size in pages (2.5Mb) - mov ecx,0x980000 ;physical address -.end_first_block: - call MEM_Add_Heap ;nobody can lock mutex yet - call create_general_page_table -;add 0x1000000(0xd80000)-end_of_memory area - mov eax,second_base_address - mov ebx,[0xfe8c] - mov ecx,[0xfe84] - sub ebx,ecx - shr ebx,12 - add eax,ecx - call MEM_Add_Heap -;init physical memory manager. - call Init_Physical_Memory_Manager - - mov dword [0xfe80],0x80000000 ;0x800000 + call test_cpu +; btr [cpu_caps], CAPS_SSE ;test: dont't use sse code +; btr [cpu_caps], CAPS_SSE2 ;test: don't use sse2 + +; btr [cpu_caps], CAPS_FXSR ;test: disable sse support + ;all sse commands rise #UD exption +; btr [cpu_caps], CAPS_PSE ;test: don't use large pages +; btr [cpu_caps], CAPS_PGE ;test: don't use global pages +; btr [cpu_caps], CAPS_MTRR ;test: don't use MTRR +; btr [cpu_caps], CAPS_TSC ;test: don't use TSC + + call init_memEx + call init_page_map + + mov eax, sys_pgdir ;+PG_NOCACHE + mov cr3, eax + + mov eax,cr0 + or eax,0x80000000 + mov cr0,eax + + call init_kernel_heap + call init_LFB + call init_mtrr + + stdcall alloc_kernel_space, 0x50000 + mov [ipc_tmp], eax + mov ebx, 0x1000 + + add eax, 0x40000 + mov [proc_mem_map], eax + + add eax, 0x8000 + mov [proc_mem_pdir], eax + + add eax, ebx + mov [proc_mem_tab], eax + + add eax, ebx + mov [current_pdir], eax + + add eax, ebx + mov [tmp_task_pdir], eax + + add eax, ebx + mov [tmp_task_ptab], eax + + add eax, ebx + mov [ipc_pdir], eax + + add eax, ebx + mov [ipc_ptab], eax + + stdcall kernel_alloc, 0x1000 + mov [tmp_task_data], eax + + mov [dll_map], 0xFFFFFFFF + mov [srv_map], 0xFFFFFFFF + + call alloc_dll + mov edi, eax + mov esi, szKernel + mov ecx, 16 + rep movsb + + bt [cpu_caps], CAPS_FXSR + jnc .no_FXSR + + stdcall kernel_alloc, 512*256 + mov [fpu_data], eax + mov ebx, cr4 + or ebx, CR4_OSFXSR + mov cr4, ebx + jmp .clts +.no_FXSR: + stdcall kernel_alloc, 112*256 + mov [fpu_data], eax + mov ebx, cr4 + and ebx, not (CR4_OSFXSR+CR4_OSXMMEXPT) + mov cr4, ebx +.clts: + clts + fninit + + mov edi, irq_tab + xor eax, eax + mov ecx, 16 + rep stosd ;Set base of graphic segment to linear address of LFB - mov eax,[0xfe80] ; set for gs + mov eax,[LFBAddress] ; set for gs mov [graph_data_l+2],ax shr eax,16 mov [graph_data_l+4],al @@ -502,23 +525,12 @@ include 'vmodeld.inc' or ecx, (10+29*6) shl 16 ; "Determining amount of memory" sub ecx, 10 mov edx, 0xFFFFFF - mov ebx, [0xFE8C] + mov ebx, [MEM_AMOUNT] shr ebx, 20 mov edi, 1 mov eax, 0x00040000 call display_number -; CHECK EXTENDED REGION -; mov dword [0x80000000],0x12345678 -; cmp dword [0x80000000],0x12345678 -; jz extended_region_found -; mov esi,boot_ext_region -; call boot_log -; jmp $ -;extended_region_found: - - - ; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f mov esi,boot_irqs @@ -535,64 +547,11 @@ include 'vmodeld.inc' ; LOAD IDT lidt [cs:idtreg] -; READ CPUID RESULT - - mov esi,boot_cpuid - call boot_log - pushfd ; get current flags - pop eax - mov ecx,eax - xor eax,0x00200000 ; attempt to toggle ID bit - push eax - popfd - pushfd ; get new EFLAGS - pop eax - push ecx ; restore original flags - popfd - and eax,0x00200000 ; if we couldn't toggle ID, - and ecx,0x00200000 ; then this is i486 - cmp eax,ecx - jz nopentium - ; It's Pentium or later. Use CPUID - mov edi,cpuid_0 - mov esi,0 - cpuid_new_read: - mov eax,esi - cpuid - call cpuid_save - add edi,4*4 - cmp esi,3 - jge cpuid_done - cmp esi,[cpuid_0] - jge cpuid_done - inc esi - jmp cpuid_new_read - cpuid_save: - mov [edi+00],eax - mov [edi+04],ebx - mov [edi+8],ecx - mov [edi+12],edx - ret - cpuid_done: - nopentium: - -; CR4 flags - enable fxsave / fxrstore -; -; finit -; mov eax,1 -; cpuid -; test edx,1000000h -; jz fail_fpu -; mov eax,cr4 -; or eax,200h ; Enable fxsave/fxstor -; mov cr4,eax -; fail_fpu: - ;The CPU to this moment should be already in PM, ;and bit MP of the register cr0 should be installed in 1. -finit ;reset of the FPU (finit, instead of fninit) -fsetpm ;enable PM of the FPU -finit ;reset the registers, contents which are still equal RM +;finit ;reset of the FPU (finit, instead of fninit) +;fsetpm ;enable PM of the FPU +;finit ;reset the registers, contents which are still equal RM ;Now FPU too in PM ; DETECT DEVICES @@ -648,6 +607,19 @@ finit ;reset the registers, contents which are still equal RM ; name for OS/IDLE process mov dword [0x80000+256+APPDATA.app_name], dword 'OS/I' mov dword [0x80000+256+APPDATA.app_name+4], dword 'DLE ' + mov eax, [fpu_data] + mov dword [0x80000+APPDATA.fpu_state], eax + mov dword [0x80000+APPDATA.fpu_handler], 0 + mov dword [0x80000+APPDATA.sse_handler], 0 + + add eax, 112 + bt [cpu_caps], CAPS_FXSR + jnc .no_sse + add eax, 512-112 +.no_sse: + mov dword [0x80000+256+APPDATA.fpu_state], eax + mov dword [0x80000+256+APPDATA.fpu_handler], 0 + mov dword [0x80000+256+APPDATA.sse_handler], 0 ; task list mov [0x3020+TASKDATA.wnd_number], 1 ; on screen number mov [0x3020+TASKDATA.pid], 1 ; process id number @@ -725,11 +697,6 @@ finit ;reset the registers, contents which are still equal RM movsd call load_skin -; MTRR'S - - call enable_mtrr - - ; LOAD FIRST APPLICATION mov [0x3000],dword 1 mov [0x3004],dword 1 @@ -818,6 +785,8 @@ finit ;reset the registers, contents which are still equal RM loop ready_for_irqs ; flush the queue + stdcall attach_int_handler, dword 1, irq1 + ; mov [dma_hdd],1 cmp [IDEContrRegsBaseAddr], 0 setnz [dma_hdd] @@ -927,57 +896,6 @@ include "kernel32.inc" ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -enable_mtrr: - - pushad - - cmp [0x2f0000+0x901c],byte 2 - je no_mtrr - mov eax,[0xFE0C] ; if no LFB then no MTRR - test eax,0100000000000000b - jz no_mtrr - mov edx,[cpuid_1+3*4] ; edx - MTRR's supported ? - test edx,1000000000000b - jz no_mtrr - call find_empty_mtrr - cmp ecx,0 - jz no_mtrr - mov esi,boot_mtrr ; 'setting mtrr' - call boot_log - mov edx,0x0 ; LFB , +8 M , write combine - mov eax,[0x2f9018] - or eax,1 - wrmsr - inc ecx - mov edx,0xf - mov eax,0xff800800 - wrmsr - mov ecx,0x2ff ; enable mtrr's - rdmsr - or eax,100000000000b ; set - wrmsr - no_mtrr: - - popad - ret - - -find_empty_mtrr: ; 8 pairs checked - - mov ecx,0x201-2 - mtrr_find: - add ecx,2 - cmp ecx,0x200+8*2 - jge no_free_mtrr - rdmsr - test eax,0x0800 - jnz mtrr_find - dec ecx - ret - no_free_mtrr: - mov ecx,0 - ret - reserve_irqs_ports: pushad @@ -1413,10 +1331,10 @@ draw_num_text: ; mov edi,[0x3000] ; shl edi,8 ; add ax,word[edi+0x80000+APPDATA.wnd_clientbox.top] -; rol eax,16 +; rol eax,16 ; add ax,word[edi+0x80000+APPDATA.wnd_clientbox.left] -; rol eax,16 - +; rol eax,16 + mov edx,eax mov ecx,65 sub ecx,eax @@ -1829,14 +1747,14 @@ readmousepos: shl ebx,16 mov bx, word [esi-twdw+WDATA.box.top] sub eax,ebx - + mov edi,[0x3000] shl edi,8 sub ax,word[edi+0x80000+APPDATA.wnd_clientbox.top] rol eax,16 sub ax,word[edi+0x80000+APPDATA.wnd_clientbox.left] rol eax,16 - + mov [esp+36],eax ret nowr: @@ -1989,7 +1907,7 @@ sys_system_table: dd sysfn_centermouse ; 15 = center mouse cursor dd sysfn_getfreemem ; 16 = get free memory size dd sysfn_getallmem ; 17 = get total memory size - dd sysfn_terminate2 ; 18 = terminate thread using PID + dd sysfn_terminate2 ; 18 = terminate thread using PID ; instead of slot dd sysfn_mouse_acceleration; 19 = set/get mouse acceleration sysfn_num = ($ - sys_system_table)/4 @@ -2042,7 +1960,7 @@ sysfn_terminate: ; 18.2 = TERMINATE sysfn_terminate2: ;lock application_table_status mutex -.table_status: +.table_status: cli cmp [application_table_status],0 je .stf @@ -2076,7 +1994,7 @@ sysfn_activate: ; 18.3 = ACTIVATE WINDOW mov [window_minimize], 2 ; restore window if minimized movzx esi, word [0xC000 + ebx*2] - cmp esi, [0x3004] + cmp esi, [0x3004] je .nowindowactivate ; already active mov edi, ebx @@ -2192,7 +2110,7 @@ sysfn_centermouse: ; 18.15 = mouse centered sysfn_mouse_acceleration: ; 18.19 = set/get mouse features cmp ebx,0 ; get mouse speed factor jnz .set_mouse_acceleration - xor eax,eax + xor eax,eax mov ax,[mouse_speed_factor] mov [esp+36],eax ret @@ -2594,14 +2512,14 @@ sys_cpuusage: lea edi,[ebx+44] mov ecx,4 rep movsd - - ; Window state - + + ; Window state + mov esi,[esp] shl esi,5 add esi,window_data + WDATA.box - mov al,[esi+window_data+WDATA.fl_wstate] - mov [edi],al + mov al,[esi+window_data+WDATA.fl_wstate] + mov [edi],al pop ebx pop eax @@ -3019,7 +2937,7 @@ sys_set_window: call check_window_position - call set_window_clientbox + call set_window_clientbox push ecx esi edi ; save for window fullscreen/resize ;mov esi,edi @@ -3158,8 +3076,8 @@ sys_window_move: mov ebx, [edi + WDATA.box.top] mov ecx, [edi + WDATA.box.width] mov edx, [edi + WDATA.box.height] - add ecx, eax - add edx, ebx + add ecx,eax + add edx,ebx call calculatescreen popad @@ -3387,12 +3305,12 @@ checkmisc: jz nobackgr mov [0xfff0],byte 2 call change_task - mov [draw_data+32 + RECT.left],dword 0 - mov [draw_data+32 + RECT.top],dword 0 + mov [draw_data+32 + RECT.left],dword 0 + mov [draw_data+32 + RECT.top],dword 0 mov eax,[0xfe00] mov ebx,[0xfe04] - mov [draw_data+32 + RECT.right],eax - mov [draw_data+32 + RECT.bottom],ebx + mov [draw_data+32 + RECT.right],eax + mov [draw_data+32 + RECT.bottom],ebx call drawbackground mov [0xfff0],byte 0 mov [0xfff4],byte 0 @@ -3487,8 +3405,8 @@ redrawscreen: mov ebx, [edi + WDATA.box.top] mov ecx, [edi + WDATA.box.width] mov edx, [edi + WDATA.box.height] - add ecx, eax - add edx, ebx + add ecx,eax + add edx,ebx mov ecx,[dlye] ; ecx = area y end ebx = window y start cmp ecx,ebx @@ -3504,7 +3422,7 @@ redrawscreen: mov edx, [edi + WDATA.box.height] add ecx, eax add edx, ebx - + mov eax,[dly] ; eax = area y start edx = window y end cmp edx,eax jb ricino @@ -4145,7 +4063,7 @@ kb_read: push ecx edx - mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's + mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's kr_loop: in al,0x64 test al,1 @@ -4346,10 +4264,8 @@ setmouse: ; set mousepicture -pointer _rdtsc: - - mov edx,[cpuid_1+3*4] - test edx,00010000b - jz ret_rdtsc + bt [cpu_caps], CAPS_TSC + jnc ret_rdtsc rdtsc ret ret_rdtsc: @@ -4624,128 +4540,6 @@ no_del_keyboard_hotkey: ret -sys_ipc: - cmp eax,1 ; DEFINE IPC MEMORY - jne no_ipc_def - mov edi,[0x3000] - shl edi,8 - add edi,0x80000 - mov [edi + APPDATA.ipc_start], ebx - mov [edi + APPDATA.ipc_size], ecx - mov [esp+36],dword 0 - ret - no_ipc_def: - - cmp eax,2 ; SEND IPC MESSAGE - jne no_ipc_send - mov esi,1 - mov edi,0x3020 - ipcs1: - cmp [edi+TASKDATA.pid], ebx - je ipcs2 - add edi,0x20 - inc esi - cmp esi,[0x3004] - jbe ipcs1 - mov [esp+36],dword 4 - ret - ipcs2: - - cli - - push esi - mov eax,esi - shl eax,8 - mov ebx,[eax+0x80000 + APPDATA.ipc_start] - test ebx,ebx ; ipc area not defined ? - je ipc_err1 - - add ebx,[eax+0x80000 + APPDATA.ipc_size] - mov eax,esi - shl eax,5 - add ebx,[eax+0x3000 + TASKDATA.mem_start] ; ebx <- max data position - - mov eax,esi ; to - shl esi,8 - add esi,0x80000 - mov edi,[esi+APPDATA.ipc_start] - shl eax,5 - add eax,0x3000 - add edi,[eax+TASKDATA.mem_start] - - cmp [edi],byte 0 ; overrun ? - jne ipc_err2 - - mov ebp,edi - add edi,[edi+4] - add edi,8 - - mov esi,ecx ; from - mov eax,[0x3010] - mov eax,[eax+TASKDATA.mem_start] - add esi,eax - - mov ecx,edx ; size - - mov eax,edi - add eax,ecx - cmp eax,ebx - jg ipc_err3 ; not enough room ? - - push ecx - - mov eax,[0x3010] - mov eax,[eax+TASKDATA.pid] - mov [edi-8],eax - mov [edi-4],ecx - cld - rep movsb - - pop ecx - add ecx,8 - - mov edi,ebp ; increase memory position - add dword [edi+4],ecx - - mov edi,[esp] - shl edi,8 - or dword [edi+0x80000+APPDATA.event_mask],dword 01000000b ; ipc message - - cmp [check_idle_semaphore],dword 20 - jge ipc_no_cis - mov [check_idle_semaphore],5 - ipc_no_cis: - - xor eax, eax - - ipc_err: - add esp,4 - mov [esp+36],eax - sti - ret - - ipc_err1: - add esp,4 - mov [esp+36],dword 1 - sti - ret - ipc_err2: - add esp,4 - mov [esp+36],dword 2 - sti - ret - ipc_err3: - add esp,4 - mov [esp+36],dword 3 - sti - ret - - no_ipc_send: - - mov [esp+36],dword -1 - ret - - align 4 sys_gs: ; direct screen access @@ -4829,7 +4623,7 @@ syscall_openramdiskfile: ; OpenRamdiskFile mov edi,[0x3010] - add edi, TASKDATA.mem_start + add edi,TASKDATA.mem_start add eax,[edi] add edx,[edi] mov esi,12 @@ -4884,7 +4678,7 @@ align 4 syscall_delramdiskfile: ; DelRamdiskFile mov edi,[0x3010] - add edi, TASKDATA.mem_start + add edi,TASKDATA.mem_start add eax,[edi] call filedelete mov [esp+36],eax @@ -4895,7 +4689,7 @@ align 4 syscall_writeramdiskfile: ; WriteRamdiskFile mov edi,[0x3010] - add edi, TASKDATA.mem_start + add edi,TASKDATA.mem_start add eax,[edi] add ebx,[edi] call filesave @@ -4920,7 +4714,7 @@ align 4 syscall_readstring: ; ReadString mov edi,[0x3010] - add edi, TASKDATA.mem_start + add edi,TASKDATA.mem_start add eax,[edi] call read_string mov [esp+36],eax @@ -5065,10 +4859,10 @@ sys_apm: or [esp + 56], byte 1 ; error mov [esp + 36], dword 8 ; 32-bit protected-mode interface not supported ret - + @@: xchg eax, ecx xchg ebx, ecx - + cmp al, 3 ja @f and [esp + 56], byte 0xfe ; emulate func 0..3 as func 0 @@ -5237,6 +5031,11 @@ wraw_bacground_select db 0 buttontype dd 0x0 windowtypechanged dd 0x0 + +align 4 + pg_data PG_DATA + heap_test dd ? + cpu_caps dd 4 dup(0) endg iglobal diff --git a/kernel/trunk/kernel32.inc b/kernel/trunk/kernel32.inc index 0e85042d80..2b5eb95eab 100644 --- a/kernel/trunk/kernel32.inc +++ b/kernel/trunk/kernel32.inc @@ -121,7 +121,7 @@ virtual at 0 end virtual ; constants definition -WSTATE_NORMAL = 00000000b +WSTATE_NORMAL = 00000000b WSTATE_MAXIMIZED = 00000001b WSTATE_MINIMIZED = 00000010b WSTATE_ROLLEDUP = 00000100b @@ -171,10 +171,16 @@ struc APPDATA { .app_name db 11 dup(?) db 5 dup(?) - .fpu_save_area: db 108 dup(?) - db 3 dup(?) - .is_fpu_saved db ? - .wnd_shape dd ? + + .fpu_state dd ? ;+16 + .fpu_init dd ? ;+20 + .fpu_handler dd ? ;+24 + .sse_handler dd ? ;+28 + .event dd ? ;+32 + + db 92 dup(?) + + .wnd_shape dd ? ;+128 .wnd_shape_scale dd ? dd ? .mem_size dd ? @@ -209,9 +215,13 @@ include "core/sync.inc" ; macros for synhronization objects include "core/sys32.inc" ; process management include "core/sched.inc" ; process scheduling include "core/syscall.inc" ; system call -include "core/mem.inc" ; high-level memory management -include "core/newproce.inc" ;new process management -include "core/physmem.inc" ; access to physical memory for applications +include "core/memory.inc" +include "core/heap.inc" +include "core/taskman.inc" +include "core/dll.inc" +include "core/exports.inc" +include "core/except.inc" + ; GUI stuff include "gui/window.inc"