/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" |