Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 163 → Rev 164

/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,<params \} }
 
prologue@proc equ prologuedef
 
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,localbytes
end if
end if
irps reg, reglist \{ push reg \} }
 
epilogue@proc equ epiloguedef
 
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if flag and 10000b
retn
else
retn parmbytes
end if }
 
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
virtual at ebp+8
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $ - (ebp+8)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
match prologue:reglist, prologue@proc:<regs> \{ 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:<regs>
\\\{ 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 }
/kernel/trunk/boot/bootcode.inc
474,6 → 474,9
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
824,7 → 827,7
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,37 → 1233,41
; 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]
; 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
 
xor ax, ax
mov es, ax
 
mov ax,[es:0x9008] ; vga & 320x200
mov bx, ax
cmp ax,0x13
/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
 
 
/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
/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
/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
 
/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
 
 
 
/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
 
/kernel/trunk/core/sys32.inc
54,18 → 54,18
; -----------------------------------------
 
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
gdte:
 
 
 
idtreg:
dw 8*0x41-1
dd idts+8
label idts at 0xB100-8
;label idts at 0xB100-8
 
 
 
166,16 → 165,20
 
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
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:
276,25 → 279,46
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 ebx, [fpu_owner]
cmp ebx, [CURRENT_TASK]
je .exit
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
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
fpu_owner dd 1
endg
 
 
611,11 → 635,11
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:
 
ret
 
 
732,11 → 756,16
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
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
/kernel/trunk/core/syscall.inc
57,7 → 57,7
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
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
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
/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
 
/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
 
/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
/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 ?
}
 
/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
 
 
 
/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,<params \} }
 
prologue@proc equ prologuedef
 
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,localbytes
end if
end if
irps reg, reglist \{ push reg \} }
 
epilogue@proc equ epiloguedef
 
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if flag and 10000b
retn
else
retn parmbytes
end if }
 
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
virtual at ebp+8
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $ - (ebp+8)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
match prologue:reglist, prologue@proc:<regs> \{ 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:<regs>
\\\{ 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 }
/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
/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
 
/kernel/trunk/hid/keyboard.inc
86,12 → 86,12
 
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
.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
/kernel/trunk/kernel.asm
10,24 → 10,28
;; 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)
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Included files:
116,17 → 120,7
 
; 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
 
228,13 → 222,6
 
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
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,48 → 353,28
 
; 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
 
mov dword [0xFE84], eax ;0x100000*16
cmp edi, eax ;0x100000*16
jne @f
mov dword [0xFE84], 0xD80000 ; =0x100000*13.5
shr edx, 10
cmp edx, 4
ja @f
inc edx ;at least 4Mb for kernel heap
@@:
mov dword [0xFE8C], edi
mov [pg_data.kernel_tables], edx
 
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!
include 'detect/disks.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!!
414,42 → 381,98
 
; CHECK EXTRA REGION
; ENABLE PAGING
 
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
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 init_kernel_heap
call init_LFB
call init_mtrr
 
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
stdcall alloc_kernel_space, 0x50000
mov [ipc_tmp], eax
mov ebx, 0x1000
mov dword [0xfe80],0x80000000 ;0x800000
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
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
; 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
; 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
movsd
call load_skin
 
; MTRR'S
 
call enable_mtrr
 
 
; LOAD FIRST APPLICATION
mov [0x3000],dword 1
mov [0x3004],dword 1
818,6 → 785,8
 
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
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
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
4346,10 → 4264,8
 
 
_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
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
5237,6 → 5031,11
 
buttontype dd 0x0
windowtypechanged dd 0x0
 
align 4
pg_data PG_DATA
heap_test dd ?
cpu_caps dd 4 dup(0)
endg
 
iglobal
/kernel/trunk/kernel32.inc
171,10 → 171,16
{
.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,10 → 215,14
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"
include "gui/event.inc"