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 |