Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 1634 → Rev 1635

/kernel/branches/Kolibri-acpi/bus/pci/pci32.inc
0,0 → 1,654
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; PCI32.INC ;;
;; ;;
;; 32 bit PCI driver code ;;
;; ;;
;; Version 0.3 April 9, 2007 ;;
;; Version 0.2 December 21st, 2002 ;;
;; ;;
;; Author: Victor Prodan, victorprodan@yahoo.com ;;
;; Mihailov Ilia, ghost.nsk@gmail.com ;;
;; Credits: ;;
;; Ralf Brown ;;
;; Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
;***************************************************************************
; Function
; pci_api:
;
; Description
; entry point for system PCI calls
;***************************************************************************
;mmio_pci_addr equ 0x400 ; set actual PCI address here to activate user-MMIO
 
iglobal
align 4
f62call:
dd pci_fn_0
dd pci_fn_1
dd pci_fn_2
dd pci_service_not_supported ;3
dd pci_read_reg ;4 byte
dd pci_read_reg ;5 word
dd pci_read_reg ;6 dword
dd pci_service_not_supported ;7
dd pci_write_reg ;8 byte
dd pci_write_reg ;9 word
dd pci_write_reg ;10 dword
if defined mmio_pci_addr
dd pci_mmio_init ;11
dd pci_mmio_map ;12
dd pci_mmio_unmap ;13
end if
 
endg
 
align 4
 
pci_api:
 
;cross
mov eax,ebx
mov ebx,ecx
mov ecx,edx
 
cmp [pci_access_enabled],1
jne pci_service_not_supported
 
movzx edx, al
 
if defined mmio_pci_addr
cmp al, 13
ja pci_service_not_supported
else
cmp al, 10
ja pci_service_not_supported
end if
 
call dword [f62call+edx*4]
mov dword [esp+32],eax
ret
 
 
align 4
pci_api_drv:
 
cmp [pci_access_enabled],1
jne .fail
 
cmp eax, 2
ja .fail
 
jmp dword [f62call+eax*4]
 
.fail:
or eax,-1
ret
 
 
;; ============================================
 
pci_fn_0:
; PCI function 0: get pci version (AH.AL)
movzx eax,word [BOOT_VAR+0x9022]
ret
 
pci_fn_1:
; PCI function 1: get last bus in AL
mov al,[BOOT_VAR+0x9021]
ret
 
pci_fn_2:
; PCI function 2: get pci access mechanism
mov al,[BOOT_VAR+0x9020]
ret
 
pci_service_not_supported:
or eax,-1
mov dword [esp+32],eax
ret
 
;***************************************************************************
; Function
; pci_make_config_cmd
;
; Description
; creates a command dword for use with the PCI bus
; bus # in ah
; device+func in bh (dddddfff)
; register in bl
;
; command dword returned in eax ( 10000000 bbbbbbbb dddddfff rrrrrr00 )
;***************************************************************************
 
align 4
 
pci_make_config_cmd:
shl eax,8 ; move bus to bits 16-23
mov ax,bx ; combine all
and eax,0xffffff
or eax,0x80000000
ret
 
;***************************************************************************
; Function
; pci_read_reg:
;
; Description
; read a register from the PCI config space into EAX/AX/AL
; IN: ah=bus,device+func=bh,register address=bl
; number of bytes to read (1,2,4) coded into AL, bits 0-1
; (0 - byte, 1 - word, 2 - dword)
;***************************************************************************
 
align 4
 
pci_read_reg:
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
je pci_read_reg_2
 
; mechanism 1
push esi ; save register size into ESI
mov esi,eax
and esi,3
 
call pci_make_config_cmd
mov ebx,eax
; get current state
mov dx,0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax,ebx
and al,0xfc ; make address dword-aligned
out dx,eax
; get requested DWORD of config data
mov dl,0xfc
and bl,3
or dl,bl ; add to port address first 2 bits of register address
 
or esi,esi
jz pci_read_byte1
cmp esi,1
jz pci_read_word1
cmp esi,2
jz pci_read_dword1
jmp pci_fin_read1
 
pci_read_byte1:
in al,dx
jmp pci_fin_read1
pci_read_word1:
in ax,dx
jmp pci_fin_read1
pci_read_dword1:
in eax,dx
jmp pci_fin_read1
pci_fin_read1:
; restore configuration control
xchg eax,[esp]
mov dx,0xcf8
out dx,eax
 
pop eax
pop esi
ret
pci_read_reg_2:
 
test bh,128 ;mech#2 only supports 16 devices per bus
jnz pci_read_reg_err
 
push esi ; save register size into ESI
mov esi,eax
and esi,3
 
push eax
;store current state of config space
mov dx,0xcf8
in al,dx
mov ah,al
mov dl,0xfa
in al,dx
 
xchg eax,[esp]
; out 0xcfa,bus
mov al,ah
out dx,al
; out 0xcf8,0x80
mov dl,0xf8
mov al,0x80
out dx,al
; compute addr
shr bh,3 ; func is ignored in mechanism 2
or bh,0xc0
mov dx,bx
 
or esi,esi
jz pci_read_byte2
cmp esi,1
jz pci_read_word2
cmp esi,2
jz pci_read_dword2
jmp pci_fin_read2
 
pci_read_byte2:
in al,dx
jmp pci_fin_read2
pci_read_word2:
in ax,dx
jmp pci_fin_read2
pci_read_dword2:
in eax,dx
; jmp pci_fin_read2
pci_fin_read2:
 
; restore configuration space
xchg eax,[esp]
mov dx,0xcfa
out dx,al
mov dl,0xf8
mov al,ah
out dx,al
 
pop eax
pop esi
ret
 
pci_read_reg_err:
xor eax,eax
dec eax
ret
 
 
;***************************************************************************
; Function
; pci_write_reg:
;
; Description
; write a register from ECX/CX/CL into the PCI config space
; IN: ah=bus,device+func=bh,register address (dword aligned)=bl,
; value to write in ecx
; number of bytes to write (1,2,4) coded into AL, bits 0-1
; (0 - byte, 1 - word, 2 - dword)
;***************************************************************************
 
align 4
 
pci_write_reg:
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use?
je pci_write_reg_2
 
; mechanism 1
push esi ; save register size into ESI
mov esi,eax
and esi,3
 
call pci_make_config_cmd
mov ebx,eax
; get current state into ecx
mov dx,0xcf8
in eax, dx
push eax
; set up addressing to config data
mov eax,ebx
and al,0xfc ; make address dword-aligned
out dx,eax
; write DWORD of config data
mov dl,0xfc
and bl,3
or dl,bl
mov eax,ecx
 
or esi,esi
jz pci_write_byte1
cmp esi,1
jz pci_write_word1
cmp esi,2
jz pci_write_dword1
jmp pci_fin_write1
 
pci_write_byte1:
out dx,al
jmp pci_fin_write1
pci_write_word1:
out dx,ax
jmp pci_fin_write1
pci_write_dword1:
out dx,eax
jmp pci_fin_write1
pci_fin_write1:
 
; restore configuration control
pop eax
mov dl,0xf8
out dx,eax
 
xor eax,eax
pop esi
 
ret
pci_write_reg_2:
 
test bh,128 ;mech#2 only supports 16 devices per bus
jnz pci_write_reg_err
 
 
push esi ; save register size into ESI
mov esi,eax
and esi,3
 
push eax
;store current state of config space
mov dx,0xcf8
in al,dx
mov ah,al
mov dl,0xfa
in al,dx
xchg eax,[esp]
; out 0xcfa,bus
mov al,ah
out dx,al
; out 0xcf8,0x80
mov dl,0xf8
mov al,0x80
out dx,al
; compute addr
shr bh,3 ; func is ignored in mechanism 2
or bh,0xc0
mov dx,bx
; write register
mov eax,ecx
 
or esi,esi
jz pci_write_byte2
cmp esi,1
jz pci_write_word2
cmp esi,2
jz pci_write_dword2
jmp pci_fin_write2
 
pci_write_byte2:
out dx,al
jmp pci_fin_write2
pci_write_word2:
out dx,ax
jmp pci_fin_write2
pci_write_dword2:
out dx,eax
jmp pci_fin_write2
pci_fin_write2:
; restore configuration space
pop eax
mov dx,0xcfa
out dx,al
mov dl,0xf8
mov al,ah
out dx,al
 
xor eax,eax
pop esi
ret
 
pci_write_reg_err:
xor eax,eax
dec eax
ret
 
if defined mmio_pci_addr ; must be set above
;***************************************************************************
; Function
; pci_mmio_init
;
; Description
; IN: bx = device's PCI bus address (bbbbbbbbdddddfff)
; Returns eax = user heap space available (bytes)
; Error codes
; eax = -1 : PCI user access blocked,
; eax = -2 : device not registered for uMMIO service
; eax = -3 : user heap initialization failure
;***************************************************************************
pci_mmio_init:
cmp bx, mmio_pci_addr
jz @f
mov eax,-2
ret
@@:
call init_heap ; (if not initialized yet)
or eax,eax
jz @f
ret
@@:
mov eax,-3
ret
 
 
;***************************************************************************
; Function
; pci_mmio_map
;
; Description
; maps a block of PCI memory to user-accessible linear address
;
; WARNING! This VERY EXPERIMENTAL service is for one chosen PCI device only!
; The target device address should be set in kernel var mmio_pci_addr
;
; IN: ah = BAR#;
; IN: ebx = block size (bytes);
; IN: ecx = offset in MMIO block (in 4K-pages, to avoid misaligned pages);
;
; Returns eax = MMIO block's linear address in the userspace (if no error)
;
;
; Error codes
; eax = -1 : user access to PCI blocked,
; eax = -2 : an invalid BAR register referred
; eax = -3 : no i/o space on that BAR
; eax = -4 : a port i/o BAR register referred
; eax = -5 : dynamic userspace allocation problem
;***************************************************************************
 
pci_mmio_map:
and edx,0x0ffff
cmp ah,6
jc .bar_0_5
jz .bar_rom
mov eax,-2
ret
.bar_rom:
mov ah, 8 ; bar6 = Expansion ROM base address
.bar_0_5:
push ecx
add ebx, 4095
and ebx,-4096
push ebx
mov bl, ah ; bl = BAR# (0..5), however bl=8 for BAR6
shl bl, 1
shl bl, 1
add bl, 0x10 ; now bl = BAR offset in PCI config. space
mov ax, mmio_pci_addr
mov bh, al ; bh = dddddfff
mov al, 2 ; al : DW to read
call pci_read_reg
or eax, eax
jnz @f
mov eax,-3 ; empty I/O space
jmp mmio_ret_fail
@@:
test eax, 1
jz @f
mov eax,-4 ; damned ports (not MMIO space)
jmp mmio_ret_fail
@@:
pop ecx ; ecx = block size, bytes (expanded to whole page)
mov ebx, ecx ; user_alloc destroys eax, ecx, edx, but saves ebx
and eax, 0xFFFFFFF0
push eax ; store MMIO physical address + keep 2DWords in the stack
stdcall user_alloc, ecx
or eax, eax
jnz mmio_map_over
mov eax,-5 ; problem with page allocation
 
mmio_ret_fail:
pop ecx
pop edx
ret
 
mmio_map_over:
mov ecx, ebx ; ecx = size (bytes, expanded to whole page)
shr ecx, 12 ; ecx = number of pages
mov ebx, eax ; ebx = linear address
pop eax ; eax = MMIO start
pop edx ; edx = MMIO shift (pages)
shl edx, 12 ; edx = MMIO shift (bytes)
add eax, edx ; eax = uMMIO physical address
or eax, PG_SHARED
or eax, PG_UW
or eax, PG_NOCACHE
mov edi, ebx
call commit_pages
mov eax, edi
ret
 
;***************************************************************************
; Function
; pci_mmio_unmap_page
;
; Description
; unmaps the linear space previously tied to a PCI memory block
;
; IN: ebx = linear address of space previously allocated by pci_mmio_map
; returns eax = 1 if successfully unmapped
;
; Error codes
; eax = -1 if no user PCI access allowed,
; eax = 0 if unmapping failed
;***************************************************************************
 
pci_mmio_unmap:
stdcall user_free, ebx
ret
 
end if
 
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
uglobal
align 4
; VendID (2), DevID (2), Revision = 0 (1), Class Code (3), FNum (1), Bus (1)
pci_emu_dat: times 30*10 db 0
endg
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
align 4
sys_pcibios:
cmp [pci_access_enabled], 1
jne .unsupported_func
cmp [pci_bios_entry], 0
jz .emulate_bios
 
push ds
mov ax, pci_data_sel
mov ds, ax
mov eax, ebp
mov ah, 0B1h
call pword [cs:pci_bios_entry]
pop ds
 
jmp .return
;-=-=-=-=-=-=-=-=
.emulate_bios:
cmp ebp, 1 ; PCI_FUNCTION_ID
jnz .not_PCI_BIOS_PRESENT
mov edx, 'PCI '
mov al, [OS_BASE+0x2F0000 + 0x9020]
mov bx, [OS_BASE+0x2F0000 + 0x9022]
mov cl, [OS_BASE+0x2F0000 + 0x9021]
xor ah, ah
jmp .return_abcd
 
.not_PCI_BIOS_PRESENT:
cmp ebp, 2 ; FIND_PCI_DEVICE
jne .not_FIND_PCI_DEVICE
mov ebx, pci_emu_dat
..nxt: cmp [ebx], dx
jne ..no
cmp [ebx + 2], cx
jne ..no
dec si
jns ..no
mov bx, [ebx + 4]
xor ah, ah
jmp .return_ab
..no: cmp word[ebx], 0
je ..dev_not_found
add ebx, 10
jmp ..nxt
..dev_not_found:
mov ah, 0x86 ; DEVICE_NOT_FOUND
jmp .return_a
 
.not_FIND_PCI_DEVICE:
cmp ebp, 3 ; FIND_PCI_CLASS_CODE
jne .not_FIND_PCI_CLASS_CODE
mov esi, pci_emu_dat
shl ecx, 8
..nxt2: cmp [esi], ecx
jne ..no2
mov bx, [esi]
xor ah, ah
jmp .return_ab
..no2: cmp dword[esi], 0
je ..dev_not_found
add esi, 10
jmp ..nxt2
 
.not_FIND_PCI_CLASS_CODE:
cmp ebp, 8 ; READ_CONFIG_*
jb .not_READ_CONFIG
cmp ebp, 0x0A
ja .not_READ_CONFIG
mov eax, ebp
mov ah, bh
mov edx, edi
mov bh, bl
mov bl, dl
call pci_read_reg
mov ecx, eax
xor ah, ah ; SUCCESSFUL
jmp .return_abc
.not_READ_CONFIG:
cmp ebp, 0x0B ; WRITE_CONFIG_*
jb .not_WRITE_CONFIG
cmp ebp, 0x0D
ja .not_WRITE_CONFIG
lea eax, [ebp+1]
mov ah, bh
mov edx, edi
mov bh, bl
mov bl, dl
call pci_write_reg
xor ah, ah ; SUCCESSFUL
jmp .return_abc
.not_WRITE_CONFIG:
.unsupported_func:
mov ah, 0x81 ; FUNC_NOT_SUPPORTED
.return:mov dword[esp + 4 ], edi
mov dword[esp + 8], esi
.return_abcd:
mov dword[esp + 24], edx
.return_abc:
mov dword[esp + 28], ecx
.return_ab:
mov dword[esp + 20], ebx
.return_a:
mov dword[esp + 32], eax
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/bus/pci/PCIe.inc
0,0 → 1,119
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) 2010 KolibriOS team. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; PCIe.INC ;;
;; ;;
;; Extended PCI express services ;;
;; ;;
;; art_zh <artem@jerdev.co.uk> ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 1463 $
 
;***************************************************************************
; Function
; pci_ext_config:
;
; Description
; PCIe extended (memory-mapped) config space detection
;
; WARNINGs:
; 1) Very Experimental!
; 2) direct HT-detection (no ACPI or BIOS service used)
; 3) Only AMD/HT processors currently supported
;
;***************************************************************************
 
PCIe_CONFIG_SPACE equ 0xF0000000 ; to be moved to const.inc
mmio_pcie_cfg_addr dd 0x0 ; intel pcie space may be defined here
mmio_pcie_cfg_lim dd 0x0 ; upper pcie space address
 
 
align 4
 
pci_ext_config:
 
mov ebx, [mmio_pcie_cfg_addr]
or ebx,ebx
jz @f
or ebx, 0x7FFFFFFF ; required by PCI-SIG standards
jnz .pcie_failed
add ebx, 0x0FFFFC
cmp ebx, [mmio_pcie_cfg_lim]; is the space limit correct?
ja .pcie_failed
jmp .pcie_cfg_mapped
@@:
mov ebx, [cpu_vendor]
cmp ebx, dword [AMD_str]
jne .pcie_failed
mov bx, 0xC184 ; dev = 24, fn = 01, reg = 84h
 
.check_HT_mmio:
mov cx, bx
mov ax, 0x0002 ; bus = 0, 1dword to read
call pci_read_reg
mov bx, cx
sub bl, 4
and al, 0x80 ; check the NP bit
jz .no_pcie_cfg
shl eax, 8 ; bus:[27..20], dev:[19:15]
or eax, 0x00007FFC ; fun:[14..12], reg:[11:2]
mov [mmio_pcie_cfg_lim], eax
mov cl, bl
mov ax, 0x0002 ; bus = 0, 1dword to read
call pci_read_reg
mov bx, cx
test al, 0x03 ; MMIO Base RW enabled?
jz .no_pcie_cfg
test al, 0x0C ; MMIO Base locked?
jnz .no_pcie_cfg
xor al, al
shl eax, 8
test eax, 0x000F0000 ; MMIO Base must be bus0-aligned
jnz .no_pcie_cfg
mov [mmio_pcie_cfg_addr], eax
add eax, 0x000FFFFC
sub eax,[mmio_pcie_cfg_lim] ; MMIO must cover at least one bus
ja .no_pcie_cfg
 
; -- it looks like a true PCIe config space;
mov eax,[mmio_pcie_cfg_addr] ; physical address
or eax, (PG_SHARED + PG_LARGE + PG_USER)
mov ebx, PCIe_CONFIG_SPACE ; linear address
mov ecx, ebx
shr ebx, 20
add ebx, sys_pgdir ; PgDir entry @
@@:
mov dword[ebx], eax ; map 4 buses
invlpg [ecx]
cmp bl, 4
jz .pcie_cfg_mapped ; fix it later
add bl, 4 ; next PgDir entry
add eax, 0x400000 ; eax += 4M
add ecx, 0x400000
jmp @b
 
.pcie_cfg_mapped:
; -- glad to have the extended PCIe config field found
; mov esi, boot_pcie_ok
; call boot_log
ret ; <<<<<<<<<<< OK >>>>>>>>>>>
.no_pcie_cfg:
 
xor eax, eax
mov [mmio_pcie_cfg_addr], eax
mov [mmio_pcie_cfg_lim], eax
add bl, 12
cmp bl, 0xC0 ; MMIO regs lay below this offset
jb .check_HT_mmio
.pcie_failed:
; mov esi, boot_pcie_fail
; call boot_log
ret ; <<<<<<<<< FAILURE >>>>>>>>>
 
/kernel/branches/Kolibri-acpi/bus/pci/pci16.inc
0,0 → 1,51
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; PCI16.INC ;;
;; ;;
;; 16 bit PCI driver code ;;
;; ;;
;; Version 0.2 December 21st, 2002 ;;
;; ;;
;; Author: Victor Prodan, victorprodan@yahoo.com ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
init_pci_16:
 
pushad
 
xor ax,ax
mov es,ax
mov byte [es:0x9020],1 ;default mechanism:1
mov ax,0xb101
int 0x1a
or ah,ah
jnz pci16skip
 
mov [es:0x9021],cl ;last PCI bus in system
mov [es:0x9022],bx
mov [es:0x9024],edi
 
; we have a PCI BIOS, so check which configuration mechanism(s)
; it supports
; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2)
test al,1
jnz pci16skip
test al,2
jz pci16skip
mov byte [es:0x9020],2 ; if (al&3)==2 => mechanism 2
 
pci16skip:
 
mov ax,0x1000
mov es,ax
 
popad
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/bus/pci
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/bus
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/core/memory.inc
0,0 → 1,1523
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
align 4
proc alloc_page
 
pushfd
cli
push ebx
;//-
cmp [pg_data.pages_free], 1
jle .out_of_memory
;//-
 
mov ebx, [page_start]
mov ecx, [page_end]
.l1:
bsf eax,[ebx];
jnz .found
add ebx,4
cmp ebx, ecx
jb .l1
pop ebx
popfd
xor eax,eax
ret
.found:
;//-
dec [pg_data.pages_free]
jz .out_of_memory
;//-
btr [ebx], eax
mov [page_start],ebx
sub ebx, sys_pgmap
lea eax, [eax+ebx*8]
shl eax, 12
;//- dec [pg_data.pages_free]
pop ebx
popfd
ret
;//-
.out_of_memory:
mov [pg_data.pages_free], 1
xor eax, eax
pop ebx
popfd
ret
;//-
endp
 
align 4
proc alloc_pages stdcall, count:dword
pushfd
push ebx
push edi
cli
mov eax, [count]
add eax, 7
shr eax, 3
mov [count], eax
;//-
mov ebx, [pg_data.pages_free]
sub ebx, 9
js .out_of_memory
shr ebx, 3
cmp eax, ebx
jg .out_of_memory
;//-
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
.out_of_memory:
.fail:
xor eax, eax
pop edi
pop ebx
popfd
ret
.next:
inc ecx
cmp ecx, ebx
jb .find
pop edi
pop ebx
popfd
xor eax, eax
ret
.ok:
sub ecx, edi
inc ecx
push esi
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
pop esi
pop edi
pop ebx
popfd
ret
endp
 
align 4
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
push ebx
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, [flags]
mov ebx, [lin_addr]
shr ebx, 12
mov [page_tabs+ebx*4], eax
mov eax, [lin_addr]
invlpg [eax]
pop ebx
ret
endp
 
align 4
map_space: ;not implemented
 
 
ret
 
 
align 4
proc free_page
;arg: eax page address
pushfd
cli
shr eax, 12 ;page index
bts dword [sys_pgmap], eax ;that's all!
cmc
adc [pg_data.pages_free], 0
shr eax, 3
and eax, not 3 ;dword offset from page_map
add eax, sys_pgmap
cmp [page_start], eax
ja @f
popfd
ret
@@:
mov [page_start], eax
popfd
ret
endp
 
proc map_io_mem stdcall, base:dword, size:dword, flags:dword
 
push ebx
push edi
mov eax, [size]
add eax, 4095
and eax, -4096
mov [size], eax
stdcall alloc_kernel_space, eax
test eax, eax
jz .fail
push eax
 
mov edi, 0x1000
mov ebx, eax
mov ecx,[size]
mov edx, [base]
shr eax, 12
shr ecx, 12
and edx, -4096
or edx, [flags]
@@:
mov [page_tabs+eax*4], edx
; push eax
invlpg [ebx]
; pop eax
inc eax
add ebx, edi
add edx, edi
loop @B
 
pop eax
mov edx, [base]
and edx, 4095
add eax, edx
.fail:
pop edi
pop ebx
ret
endp
 
; param
; eax= page base + page flags
; ebx= linear address
; ecx= count
 
align 4
commit_pages:
push edi
test ecx, ecx
jz .fail
 
mov edi, ebx
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
 
mov edx, 0x1000
mov ebx, edi
shr ebx, 12
@@:
mov [page_tabs+ebx*4], eax
; push eax
invlpg [edi]
; pop eax
add edi, edx
add eax, edx
inc ebx
dec ecx
jnz @B
mov [pg_data.pg_mutex],ecx
.fail:
pop edi
ret
 
 
; param
; eax= base
; ecx= count
 
align 4
release_pages:
 
pushad
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
 
mov esi, eax
mov edi, eax
 
shr esi, 10
add esi, page_tabs
 
mov ebp, [pg_data.pages_free]
mov ebx, [page_start]
mov edx, sys_pgmap
@@:
xor eax, eax
xchg eax, [esi]
push eax
invlpg [edi]
pop eax
 
test eax, 1
jz .next
 
shr eax, 12
bts [edx], eax
cmc
adc ebp, 0
shr eax, 3
and eax, -4
add eax, edx
cmp eax, ebx
jae .next
 
mov ebx, eax
.next:
add edi, 0x1000
add esi, 4
dec ecx
jnz @B
mov [pg_data.pages_free], ebp
and [pg_data.pg_mutex],0
popad
ret
 
; param
; eax= base
; ecx= count
 
align 4
unmap_pages:
 
push edi
 
mov edi, eax
mov edx, eax
 
shr edi, 10
add edi, page_tabs
 
xor eax, eax
@@:
stosd
invlpg [edx]
add edx, 0x1000
loop @b
 
pop edi
ret
 
 
align 4
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
push ebx
mov ebx, [lin_addr]
shr ebx, 22
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, PG_UW ;+PG_NOCACHE
mov dword [master_tab+ebx*4], eax
mov eax, [lin_addr]
shr eax, 10
add eax, page_tabs
invlpg [eax]
pop ebx
ret
endp
 
align 4
proc init_LFB
locals
pg_count dd ?
endl
 
cmp dword [LFBAddress], -1
jne @f
mov [BOOT_VAR+0x901c],byte 2
stdcall alloc_pages, (0x280000 / 4096)
 
push eax
call alloc_page
stdcall map_page_table, LFB_BASE, eax
pop eax
or eax, PG_UW
mov ebx, LFB_BASE
mov ecx, 0x280000 / 4096
call commit_pages
mov [LFBAddress], dword LFB_BASE
ret
@@:
test [SCR_MODE],word 0100000000000000b
jnz @f
mov [BOOT_VAR+0x901c],byte 2
ret
@@:
call init_mtrr
 
mov edx, LFB_BASE
mov esi, [LFBAddress]
mov edi, 0x00C00000
mov dword [exp_lfb+4], edx
 
shr edi, 12
mov [pg_count], edi
shr edi, 10
 
bt [cpu_caps], CAPS_PSE
jnc .map_page_tables
or esi, PG_LARGE+PG_UW
mov edx, sys_pgdir+(LFB_BASE shr 20)
@@:
mov [edx], esi
add edx, 4
add esi, 0x00400000
dec edi
jnz @B
 
bt [cpu_caps], CAPS_PGE
jnc @F
or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
@@:
mov dword [LFBAddress], LFB_BASE
mov eax, cr3 ;flush TLB
mov cr3, eax
ret
 
.map_page_tables:
 
@@:
call alloc_page
stdcall map_page_table, edx, eax
add edx, 0x00400000
dec edi
jnz @B
 
mov eax, [LFBAddress]
mov edi, page_tabs + (LFB_BASE shr 10)
or eax, PG_UW
mov ecx, [pg_count]
cld
@@:
stosd
add eax, 0x1000
dec ecx
jnz @B
 
mov dword [LFBAddress], LFB_BASE
mov eax, cr3 ;flush TLB
mov cr3, eax
 
ret
endp
 
align 4
proc new_mem_resize stdcall, new_size:dword
 
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
 
mov edi, [new_size]
add edi,4095
and edi,not 4095
mov [new_size], edi
 
mov edx,[current_slot]
cmp [edx+APPDATA.heap_base],0
jne .exit
 
mov esi, [edx+APPDATA.mem_size]
add esi, 4095
and esi, not 4095
 
cmp edi, esi
jae .expand
 
shr edi, 12
shr esi, 12
@@:
mov eax, [app_page_tabs+edi*4]
test eax, 1
jz .next
mov dword [app_page_tabs+edi*4], 2
mov ebx, edi
shl ebx, 12
push eax
invlpg [ebx]
pop eax
call free_page
 
.next: add edi, 1
cmp edi, esi
jb @B
 
.update_size:
mov ebx, [new_size]
call update_mem_size
 
xor eax, eax
dec [pg_data.pg_mutex]
ret
.expand:
 
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
 
@@:
call alloc_page
test eax, eax
jz .exit_pop
 
stdcall map_page_table, edi, eax
 
push edi
shr edi, 10
add edi, page_tabs
mov ecx, 1024
xor eax, eax
cld
rep stosd
pop edi
 
add edi, 0x00400000
cmp edi, esi
jb @B
.grow:
;//-
pop edi
push edi
mov esi, [pg_data.pages_free]
sub esi, 1
shr edi, 12
cmp esi, edi
jle .out_of_memory
;//-
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
jb @B
 
jmp .update_size
;//-
.exit_pop:
.out_of_memory:
;//-
pop edi
pop esi
.exit:
xor eax, eax
inc eax
dec [pg_data.pg_mutex]
ret
endp
 
update_mem_size:
; in: edx = slot base
; ebx = new memory size
; destroys eax,ecx,edx
 
mov [APPDATA.mem_size+edx],ebx
;search threads and update
;application memory size infomation
mov ecx,[APPDATA.dir_table+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+TASKDATA.state],9 ;if slot empty?
jz .search_threads_next
shl edx,3
cmp [SLOT_BASE+edx+APPDATA.dir_table],ecx ;if it is our thread?
jnz .search_threads_next
mov [SLOT_BASE+edx+APPDATA.mem_size],ebx ;update memory size
.search_threads_next:
inc eax
jmp .search_threads
.search_threads_end:
ret
 
; param
; eax= linear address
;
; retval
; eax= phisical page address
 
align 4
get_pg_addr:
shr eax, 12
mov eax, [page_tabs+eax*4]
and eax, 0xFFFFF000
ret
 
 
align 4
; Now it is called from core/sys32::exc_c (see stack frame there)
proc page_fault_handler
 
.err_addr equ ebp-4
 
push ebx ;save exception number (#PF)
mov ebp, esp
mov ebx, cr2
push ebx ;that is locals: .err_addr = cr2
inc [pg_data.pages_faults]
 
mov eax, [pf_err_code]
 
cmp ebx, OS_BASE ;ebx == .err_addr
jb .user_space ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ;
 
cmp ebx, page_tabs
jb .kernel_space ;ñòðàíèöà â ïàìÿòè ÿäðà
 
cmp ebx, kernel_tabs
jb .alloc;.app_tabs ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ;
;ïðîñòî ñîçäàäèì îäíó
if 0 ;ïîêà ýòî ïðîñòî ëèøíåå
cmp ebx, LFB_BASE
jb .core_tabs ;òàáëèöû ñòðàíèö ÿäðà
;Îøèáêà
.lfb:
;îáëàñòü LFB
;Îøèáêà
jmp .fail
end if
.core_tabs:
.fail: ;simply return to caller
mov esp, ebp
pop ebx ;restore exception number (#PF)
ret
 
; xchg bx, bx
; add esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
; restore_ring3_context
; iretd
 
.user_space:
test eax, PG_MAP
jnz .err_access ;Ñòðàíèöà ïðèñóòñòâóåò
;Îøèáêà äîñòóïà ?
 
shr ebx, 12
mov ecx, ebx
shr ecx, 10
mov edx, [master_tab+ecx*4]
test edx, PG_MAP
jz .fail ;òàáëèöà ñòðàíèö íå ñîçäàíà
;íåâåðíûé àäðåñ â ïðîãðàììå
 
mov eax, [page_tabs+ebx*4]
test eax, 2
jz .fail ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
;èñïîëüçîâàíèÿ. Îøèáêà
.alloc:
call alloc_page
test eax, eax
jz .fail
 
stdcall map_page,[.err_addr],eax,PG_UW
 
mov edi, [.err_addr]
and edi, 0xFFFFF000
mov ecx, 1024
xor eax, eax
;cld ;caller is duty for this
rep stosd
.exit: ;iret with repeat fault instruction
add esp,12 ;clear in stack: locals(.err_addr) + #PF + ret_to_caller
restore_ring3_context
iretd
 
.err_access:
; access denied? this may be a result of copy-on-write protection for DLL
; check list of HDLLs
and ebx, not 0xFFF
mov eax, [CURRENT_TASK]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
test eax, eax
jz .fail
mov esi, [eax+HDLL.fd]
.scan_hdll:
cmp esi, eax
jz .fail
mov edx, ebx
sub edx, [esi+HDLL.base]
cmp edx, [esi+HDLL.size]
jb .fault_in_hdll
.scan_hdll.next:
mov esi, [esi+HDLL.fd]
jmp .scan_hdll
.fault_in_hdll:
; allocate new page, map it as rw and copy data
call alloc_page
test eax, eax
jz .fail
stdcall map_page,ebx,eax,PG_UW
mov edi, ebx
mov ecx, 1024
sub ebx, [esi+HDLL.base]
mov esi, [esi+HDLL.parent]
mov esi, [esi+DLLDESCR.data]
add esi, ebx
rep movsd
jmp .exit
 
.kernel_space:
test eax, PG_MAP
jz .fail ;ñòðàíèöà íå ïðèñóòñòâóåò
 
test eax,12 ;U/S (+below)
jnz .fail ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
;ÿäðà
;test eax, 8
;jnz .fail ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
 
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
 
cmp ebx, tss._io_map_0
jb .fail
 
cmp ebx, tss._io_map_0+8192
jae .fail
 
; io permission map
; copy-on-write protection
 
call alloc_page
test eax, eax
jz .fail
 
push eax
stdcall map_page,[.err_addr],eax,dword PG_SW
pop eax
mov edi, [.err_addr]
and edi, -4096
lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
 
mov ebx, esi
shr ebx, 12
mov edx, [current_slot]
or eax, PG_SW
mov [edx+APPDATA.io_map+ebx*4], eax
 
add esi, [default_io_map]
mov ecx, 4096/4
;cld ;caller is duty for this
rep movsd
jmp .exit
endp
 
; returns number of mapped bytes
proc map_mem stdcall, lin_addr:dword,slot:dword,\
ofs:dword,buf_size:dword,req_access:dword
push 0 ; initialize number of mapped bytes
 
cmp [buf_size], 0
jz .exit
 
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
and eax, 0xFFFFF000
 
stdcall map_page,[ipc_pdir],eax,PG_UW
mov ebx, [ofs]
shr ebx, 22
mov esi, [ipc_pdir]
mov edi, [ipc_ptab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000
jz .exit
stdcall map_page,edi,eax,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:
stdcall safe_map_page,[slot],[req_access],[ofs]
jnc .exit
add dword [ebp-4], 4096
add [ofs], 4096
dec ecx
jz .exit
add edi, 0x1000
inc edx
cmp edx, 0x400
jnz .map
inc ebx
mov eax, [ipc_pdir]
mov eax, [eax+ebx*4]
and eax, 0xFFFFF000
jz .exit
stdcall map_page,esi,eax,PG_UW
xor edx, edx
jmp .map
 
.exit:
pop eax
ret
endp
 
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
ofs:dword,buf_size:dword,req_access:dword
push 0 ; initialize number of mapped bytes
 
cmp [buf_size], 0
jz .exit
 
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dir_table]
and eax, 0xFFFFF000
 
stdcall map_page,[proc_mem_pdir],eax,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,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:
stdcall safe_map_page,[slot],[req_access],[ofs]
jnc .exit
add dword [ebp-4], 0x1000
add edi, 0x1000
add [ofs], 0x1000
inc edx
dec ecx
jnz .map
.exit:
pop eax
ret
endp
 
; in: esi+edx*4 = pointer to page table entry
; in: [slot], [req_access], [ofs] on the stack
; in: edi = linear address to map
; out: CF cleared <=> failed
; destroys: only eax
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
mov eax, [esi+edx*4]
test al, PG_MAP
jz .not_present
test al, PG_WRITE
jz .resolve_readonly
; normal case: writable page, just map with requested access
.map:
stdcall map_page, edi, eax, [req_access]
stc
.fail:
ret
.not_present:
; check for alloc-on-demand page
test al, 2
jz .fail
; allocate new page, save it to source page table
push ecx
call alloc_page
pop ecx
test eax, eax
jz .fail
or al, PG_UW
mov [esi+edx*4], eax
jmp .map
.resolve_readonly:
; readonly page, probably copy-on-write
; check: readonly request of readonly page is ok
test [req_access], PG_WRITE
jz .map
; find control structure for this page
pushf
cli
cld
push ebx ecx
mov eax, [slot]
shl eax, 8
mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
test eax, eax
jz .no_hdll
mov ecx, [eax+HDLL.fd]
.scan_hdll:
cmp ecx, eax
jz .no_hdll
mov ebx, [ofs]
and ebx, not 0xFFF
sub ebx, [ecx+HDLL.base]
cmp ebx, [ecx+HDLL.size]
jb .hdll_found
mov ecx, [ecx+HDLL.fd]
jmp .scan_hdll
.no_hdll:
pop ecx ebx
popf
clc
ret
.hdll_found:
; allocate page, save it in page table, map it, copy contents from base
mov eax, [ecx+HDLL.parent]
add ebx, [eax+DLLDESCR.data]
call alloc_page
test eax, eax
jz .no_hdll
or al, PG_UW
mov [esi+edx*4], eax
stdcall map_page, edi, eax, [req_access]
push esi edi
mov esi, ebx
mov ecx, 4096/4
rep movsd
pop edi esi
pop ecx ebx
popf
stc
ret
endp
 
sys_IPC:
;input:
; ebx=1 - set ipc buffer area
; ecx=address of buffer
; edx=size of buffer
; eax=2 - send message
; ebx=PID
; ecx=address of message
; edx=size of message
 
dec ebx
jnz @f
 
mov eax,[current_slot]
pushf
cli
mov [eax+APPDATA.ipc_start],ecx ;set fields in extended information area
mov [eax+APPDATA.ipc_size],edx
 
add edx, ecx
add edx, 4095
and edx, not 4095
 
.touch: mov eax, [ecx]
add ecx, 0x1000
cmp ecx, edx
jb .touch
 
popf
mov [esp+32], ebx ;ebx=0
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;2
@@:
dec ebx
jnz @f
 
stdcall sys_ipc_send, ecx, edx, esi
mov [esp+32], eax
ret
@@:
or eax,-1
mov [esp+32], eax
ret
 
;align 4
;proc set_ipc_buff
 
; mov eax,[current_slot]
; pushf
; cli
; mov [eax+APPDATA.ipc_start],ebx ;set fields in extended information area
; mov [eax+APPDATA.ipc_size],ecx
;
; add ecx, ebx
; add ecx, 4095
; and ecx, not 4095
;
;.touch: mov eax, [ebx]
; add ebx, 0x1000
; cmp ebx, ecx
; jb .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 ?
used_buf 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+SLOT_BASE+0xa0] ;is ipc area defined?
test edi,edi
jz .no_ipc_area
 
mov ebx, edi
and ebx, 0xFFF
mov [dst_offset], ebx
 
mov esi, [eax+SLOT_BASE+0xa4]
mov [buf_size], esi
 
mov ecx, [ipc_tmp]
cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page
jbe @f
push esi edi
add esi,0x1000
stdcall alloc_kernel_space,esi
mov ecx, eax
pop edi esi
@@:
mov [used_buf], ecx
stdcall map_mem, ecx, [dst_slot],\
edi, esi, PG_SW
 
mov edi, [dst_offset]
add edi, [used_buf]
cmp dword [edi], 0
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now
 
mov edx, dword [edi+4]
lea ebx, [edx+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
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 [page_tabs+ebx*4], eax
invlpg [edx]
 
mov ebx, [ipc_pdir]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs+ebx*4], eax
invlpg [edx]
 
mov ebx, [ipc_ptab]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [page_tabs+ebx*4], eax
invlpg [edx]
 
mov eax, [dst_slot]
shl eax, 8
or [eax+SLOT_BASE+0xA8],dword 0x40
cmp dword [check_idle_semaphore],20
jge .ipc_no_cis
 
mov dword [check_idle_semaphore],5
.ipc_no_cis:
push 0
jmp .ret
.no_pid:
popf
mov eax, 4
ret
.no_ipc_area:
popf
xor eax, eax
inc eax
ret
.ipc_blocked:
push 2
jmp .ret
.buffer_overflow:
push 3
.ret:
mov eax, [used_buf]
cmp eax, [ipc_tmp]
jz @f
stdcall free_kernel_space,eax
@@:
pop eax
popf
ret
endp
 
align 4
sysfn_meminfo:
 
; add ecx, new_app_base
cmp ecx, OS_BASE
jae .fail
 
mov eax, [pg_data.pages_count]
mov [ecx], eax
shl eax, 12
mov [esp+32], eax
mov eax, [pg_data.pages_free]
mov [ecx+4], eax
mov eax, [pg_data.pages_faults]
mov [ecx+8], eax
mov eax, [heap_size]
mov [ecx+12], eax
mov eax, [heap_free]
mov [ecx+16], eax
mov eax, [heap_blocks]
mov [ecx+20], eax
mov eax, [free_blocks]
mov [ecx+24], eax
ret
.fail:
or dword [esp+32], -1
ret
 
align 4
f68:
cmp ebx,4
jbe sys_sheduler
 
cmp ebx, 11
jb .fail
 
cmp ebx, 25
ja .fail
 
jmp dword [f68call+ebx*4-11*4]
.11:
call init_heap
mov [esp+32], eax
ret
.12:
stdcall user_alloc, ecx
mov [esp+32], eax
ret
.13:
stdcall user_free, ecx
mov [esp+32], eax
ret
.14:
cmp ecx, OS_BASE
jae .fail
mov edi,ecx
call get_event_ex
mov [esp+32], eax
ret
.16:
test ecx, ecx
jz .fail
cmp ecx, OS_BASE
jae .fail
stdcall get_service, ecx
mov [esp+32], eax
ret
.17:
call srv_handlerEx ;ecx
mov [esp+32], eax
ret
.19:
cmp ecx, OS_BASE
jae .fail
stdcall load_library, ecx
mov [esp+32], eax
ret
.20:
mov eax, edx
mov ebx, ecx
call user_realloc ;in: eax = pointer, ebx = new size
mov [esp+32], eax
ret
.21:
cmp ecx, OS_BASE
jae .fail
 
cmp ebx, OS_BASE
jae .fail
 
mov edi, edx
stdcall load_PE, ecx
mov esi, eax
test eax, eax
jz @F
 
push edi
push DRV_ENTRY
call eax
add esp, 8
test eax, eax
jz @F
 
mov [eax+SRV.entry], esi
 
@@:
mov [esp+32], eax
ret
.22:
cmp ecx, OS_BASE
jae .fail
 
stdcall shmem_open, ecx, edx, esi
mov [esp+24], edx
mov [esp+32], eax
ret
 
.23:
cmp ecx, OS_BASE
jae .fail
 
stdcall shmem_close, ecx
mov [esp+32], eax
ret
.24:
mov eax, [current_slot]
xchg ecx, [eax+APPDATA.exc_handler]
xchg edx, [eax+APPDATA.except_mask]
mov [esp+32], ecx ; reg_eax+8
mov [esp+20], edx ; reg_ebx+8
ret
.25:
cmp ecx,32
jae .fail
mov eax, [current_slot]
btr [eax+APPDATA.except_mask],ecx
setc byte[esp+32]
jecxz @f
bts [eax+APPDATA.except_mask],ecx
@@:
ret
 
.fail:
xor eax, eax
mov [esp+32], eax
ret
 
 
align 4
f68call: ; keep this table closer to main code
 
dd f68.11 ; init_heap
dd f68.12 ; user_alloc
dd f68.13 ; user_free
dd f68.14 ; get_event_ex
dd f68.fail ; moved to f68.24
dd f68.16 ; get_service
dd f68.17 ; call_service
dd f68.fail ; moved to f68.25
dd f68.19 ; load_dll
dd f68.20 ; user_realloc
dd f68.21 ; load_driver
dd f68.22 ; shmem_open
dd f68.23 ; shmem_close
dd f68.24
dd f68.25
 
 
align 4
proc load_pe_driver stdcall, file:dword
 
stdcall load_PE, [file]
test eax, eax
jz .fail
 
mov esi, eax
stdcall eax, DRV_ENTRY
test eax, eax
jz .fail
 
mov [eax+SRV.entry], esi
ret
 
.fail:
xor eax, eax
ret
endp
 
 
align 4
proc init_mtrr
 
cmp [BOOT_VAR+0x901c],byte 2
je .exit
 
bt [cpu_caps], CAPS_MTRR
jnc .exit
 
mov eax, cr0
or eax, 0x60000000 ;disable caching
mov cr0, eax
wbinvd ;invalidate cache
 
mov ecx, 0x2FF
rdmsr ;
; has BIOS already initialized MTRRs?
test ah, 8
jnz .skip_init
; rarely needed, so mainly placeholder
; main memory - cached
push eax
 
mov eax, [MEM_AMOUNT]
; round eax up to next power of 2
dec eax
bsr ecx, eax
mov ebx, 2
shl ebx, cl
dec ebx
; base of memory range = 0, type of memory range = MEM_WB
xor edx, edx
mov eax, MEM_WB
mov ecx, 0x200
wrmsr
; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
mov eax, 0xFFFFFFFF
mov edx, 0x0000000F
sub eax, ebx
sbb edx, 0
or eax, 0x800
inc ecx
wrmsr
; clear unused MTRRs
xor eax, eax
xor edx, edx
@@:
wrmsr
inc ecx
cmp ecx, 0x210
jb @b
; enable MTRRs
pop eax
or ah, 8
and al, 0xF0 ; default memtype = UC
mov ecx, 0x2FF
wrmsr
.skip_init:
stdcall set_mtrr, [LFBAddress],[LFBSize],MEM_WC
 
wbinvd ;again invalidate
 
mov eax, cr0
and eax, not 0x60000000
mov cr0, eax ; enable caching
.exit:
ret
endp
 
align 4
proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
; find unused register
mov ecx, 0x201
@@:
rdmsr
dec ecx
test ah, 8
jz .found
rdmsr
mov al, 0 ; clear memory type field
cmp eax, [base]
jz .ret
add ecx, 3
cmp ecx, 0x210
jb @b
; no free registers, ignore the call
.ret:
ret
.found:
; found, write values
xor edx, edx
mov eax, [base]
or eax, [mem_type]
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
 
align 4
proc stall stdcall, delay:dword
push ecx
push edx
push ebx
push eax
 
mov eax, [delay]
mul [stall_mcs]
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
 
align 4
proc create_ring_buffer stdcall, size:dword, flags:dword
locals
buf_ptr dd ?
endl
 
mov eax, [size]
test eax, eax
jz .fail
 
add eax, eax
stdcall alloc_kernel_space, eax
test eax, eax
jz .fail
 
push ebx
 
mov [buf_ptr], eax
 
mov ebx, [size]
shr ebx, 12
push ebx
 
stdcall alloc_pages, ebx
pop ecx
 
test eax, eax
jz .mm_fail
 
push edi
 
or eax, [flags]
mov edi, [buf_ptr]
mov ebx, [buf_ptr]
mov edx, ecx
shl edx, 2
shr edi, 10
@@:
mov [page_tabs+edi], eax
mov [page_tabs+edi+edx], eax
invlpg [ebx]
invlpg [ebx+0x10000]
add eax, 0x1000
add ebx, 0x1000
add edi, 4
dec ecx
jnz @B
 
mov eax, [buf_ptr]
pop edi
pop ebx
ret
.mm_fail:
stdcall free_kernel_space, [buf_ptr]
xor eax, eax
pop ebx
.fail:
ret
endp
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/heap.inc
0,0 → 1,1540
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
struc MEM_BLOCK
{ .next_block dd ?
.prev_block dd ? ;+4
.list_fd dd ? ;+8
.list_bk dd ? ;+12
.base dd ? ;+16
.size dd ? ;+20
.flags dd ? ;+24
.handle dd ? ;+28
}
 
MEM_LIST_OFFSET equ 8
FREE_BLOCK equ 4
USED_BLOCK equ 8
DONT_FREE_BLOCK equ 10h
 
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_fd equ MEM_BLOCK.list_fd
list_bk equ MEM_BLOCK.list_bk
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_fd]
mov ecx, [op+list_bk]
test edx, edx
jz @f
mov [edx+list_bk], ecx
@@:
test ecx, ecx
jz @f
mov [ecx+list_fd], edx
@@:
mov [op+list_fd],0
mov [op+list_bk],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
{
mov edx, [op+list_fd]
mov ecx, [op+list_bk]
mov [edx+list_bk], ecx
mov [ecx+list_fd], edx
mov [op+list_fd], 0
mov [op+list_bk], 0
}
 
align 4
proc init_kernel_heap
 
mov ecx, 64
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
 
mov eax, mem_used.fd-MEM_LIST_OFFSET
mov [mem_used.fd], eax
mov [mem_used.bk], eax
 
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, HEAP_BASE+MEM_BLOCK_SIZE
xor eax, eax
mov [edi+block_next], ebx
mov [edi+block_prev], eax
mov [edi+list_fd], eax
mov [edi+list_bk], 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_fd], eax
mov [ebx+list_bk], eax
mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE
 
mov ecx, [pg_data.kernel_pages]
shl ecx, 12
sub ecx, HEAP_BASE-OS_BASE+4096*MEM_BLOCK_SIZE
mov [heap_size], ecx
mov [heap_free], ecx
mov [ebx+block_size], ecx
mov [ebx+block_flags], FREE_BLOCK
 
mov [mem_block_mask], eax
mov [mem_block_mask+4],0x80000000
 
mov [mem_block_list+63*4], ebx
mov byte [mem_block_map], 0xFC
and [heap_mutex], 0
mov [heap_blocks], 4095
mov [free_blocks], 4094
ret
endp
 
; param
; eax= required size
;
; retval
; edi= memory block descriptor
; ebx= descriptor index
 
align 4
get_small_block:
mov ecx, eax
shr ecx, 12
dec ecx
cmp ecx, 63
jle .get_index
mov ecx, 63
.get_index:
lea esi, [mem_block_mask]
xor ebx, ebx
or edx, -1
 
cmp ecx, 32
jb .bit_test
 
sub ecx, 32
add ebx, 32
add esi, 4
.bit_test:
shl edx, cl
and edx, [esi]
.find:
bsf edi, edx
jz .high_mask
add ebx, edi
mov edi, [mem_block_list+ebx*4]
.check_size:
cmp eax, [edi+block_size]
ja .next
ret
 
.high_mask:
add esi, 4
cmp esi, mem_block_mask+8
jae .err
add ebx, 32
mov edx, [esi]
jmp .find
.next:
mov edi, [edi+list_fd]
test edi, edi
jnz .check_size
.err:
xor edi, edi
ret
 
align 4
alloc_mem_block:
 
mov ebx, [mem_block_start]
mov ecx, [mem_block_end]
.l1:
bsf eax,[ebx];
jnz found
add ebx,4
cmp ebx, ecx
jb .l1
xor eax,eax
ret
 
found:
btr [ebx], eax
mov [mem_block_start],ebx
sub ebx, mem_block_map
lea eax,[eax+ebx*8]
shl eax, 5
add eax, [mem_block_arr]
dec [free_blocks]
ret
align 4
free_mem_block:
mov dword [eax], 0
mov dword [eax+4], 0
mov dword [eax+8], 0
mov dword [eax+12], 0
mov dword [eax+16], 0
; mov dword [eax+20], 0
mov dword [eax+24], 0
mov dword [eax+28], 0
 
sub eax, [mem_block_arr]
shr eax, 5
 
mov ebx, mem_block_map
bts [ebx], eax
inc [free_blocks]
shr eax, 3
and eax, not 3
add eax, ebx
cmp [mem_block_start], eax
ja @f
ret
@@:
mov [mem_block_start], eax
ret
.err:
xor eax, eax
ret
 
align 4
proc alloc_kernel_space stdcall, size:dword
local block_ind:DWORD
 
push ebx
push esi
push edi
 
mov eax, [size]
add eax, 4095
and eax, not 4095
mov [size], eax
 
mov ebx, heap_mutex
call wait_mutex ;ebx
 
cmp eax, [heap_free]
ja .error
 
call get_small_block ; eax
test edi, edi
jz .error
 
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_fd], 0
mov [esi+list_bk], 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
 
remove_from_list edi
 
mov ecx, [block_ind]
mov [mem_block_list+ecx*4], edx
 
test edx, edx
jnz @f
btr [mem_block_mask], ecx
@@:
mov edx, [mem_block_list+eax*4]
mov [edi+list_fd], edx
test edx, edx
jz @f
mov [edx+list_bk], edi
@@:
mov [mem_block_list+eax*4], edi
bts [mem_block_mask], eax
.m_eq_ind:
mov ecx, mem_used.fd-MEM_LIST_OFFSET
mov edx, [ecx+list_fd]
mov [esi+list_fd], edx
mov [esi+list_bk], ecx
mov [ecx+list_fd], esi
mov [edx+list_bk], esi
 
mov [esi+block_flags], USED_BLOCK
mov eax, [esi+block_base]
mov ebx, [size]
sub [heap_free], ebx
and [heap_mutex], 0
pop edi
pop esi
pop ebx
ret
.m_eq_size:
remove_from_list edi
mov [mem_block_list+ebx*4], edx
and edx, edx
jnz @f
btr [mem_block_mask], ebx
@@:
mov ecx, mem_used.fd-MEM_LIST_OFFSET
mov edx, [ecx+list_fd]
mov [edi+list_fd], edx
mov [edi+list_bk], ecx
mov [ecx+list_fd], edi
mov [edx+list_bk], edi
 
mov [edi+block_flags], USED_BLOCK
mov eax, [edi+block_base]
mov ebx, [size]
sub [heap_free], ebx
and [heap_mutex], 0
pop edi
pop esi
pop ebx
ret
.error:
xor eax, eax
mov [heap_mutex], eax
pop edi
pop esi
pop ebx
ret
endp
 
align 4
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
push ebx
push esi
push edi
mov ebx, heap_mutex
call wait_mutex ;ebx
 
mov eax, [base]
mov esi, [mem_used.fd]
@@:
cmp esi, mem_used.fd-MEM_LIST_OFFSET
je .fail
 
cmp [esi+block_base], eax
je .found
mov esi, [esi+list_fd]
jmp @b
.found:
cmp [esi+block_flags], USED_BLOCK
jne .fail
 
mov eax, [esi+block_size]
add [heap_free], eax
 
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_fd], esi
test esi, esi
jz @f
mov [esi+list_bk], edi
@@:
bts [mem_block_mask], eax
.m_eq:
xor eax, eax
mov [heap_mutex], eax
dec eax
pop edi
pop esi
pop ebx
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_fd], edi
test edi, edi
jz @f
mov [edi+list_bk], esi
@@:
bts [mem_block_mask], eax
mov [esi+block_flags],FREE_BLOCK
xor eax, eax
mov [heap_mutex], eax
dec eax
pop edi
pop esi
pop ebx
ret
.fail:
xor eax, eax
mov [heap_mutex], eax
pop edi
pop esi
pop ebx
ret
endp
 
align 4
proc kernel_alloc stdcall, size:dword
locals
lin_addr dd ?
pages_count dd ?
endl
 
push ebx
push edi
 
mov eax, [size]
add eax, 4095
and eax, not 4095;
mov [size], eax
and eax, eax
jz .err
mov ebx, eax
shr ebx, 12
mov [pages_count], ebx
 
stdcall alloc_kernel_space, eax
test eax, eax
jz .err
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 .err
 
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 .err
 
stdcall map_page,edx,eax,dword PG_SW
add edx, 0x1000
dec ecx
jnz @B
.end:
mov eax, [lin_addr]
pop edi
pop ebx
ret
.err:
xor eax, eax
pop edi
pop ebx
ret
endp
 
align 4
proc kernel_free stdcall, base:dword
push ebx esi
 
mov ebx, heap_mutex
call wait_mutex ;ebx
 
mov eax, [base]
mov esi, [mem_used.fd]
@@:
cmp esi, mem_used.fd-MEM_LIST_OFFSET
je .fail
 
cmp [esi+block_base], eax
je .found
mov esi, [esi+list_fd]
jmp @b
.found:
cmp [esi+block_flags], USED_BLOCK
jne .fail
 
and [heap_mutex], 0
 
push ecx
mov ecx, [esi+block_size];
shr ecx, 12
call release_pages ;eax, ecx
pop ecx
stdcall free_kernel_space, [base]
pop esi ebx
ret
.fail:
xor eax, eax
mov [heap_mutex], eax
pop esi ebx
ret
endp
 
restore block_next
restore block_prev
restore block_list
restore block_base
restore block_size
restore block_flags
 
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;;
 
HEAP_TOP equ 0x5FC00000
 
align 4
proc init_heap
 
mov ebx,[current_slot]
mov eax, [ebx+APPDATA.heap_top]
test eax, eax
jz @F
sub eax,[ebx+APPDATA.heap_base]
sub eax, 4096
ret
@@:
mov esi, [ebx+APPDATA.mem_size]
add esi, 4095
and esi, not 4095
mov [ebx+APPDATA.mem_size], esi
mov eax, HEAP_TOP
mov [ebx+APPDATA.heap_base], esi
mov [ebx+APPDATA.heap_top], eax
 
sub eax, esi
shr esi, 10
mov ecx, eax
sub eax, 4096
or ecx, FREE_BLOCK
mov [page_tabs+esi], ecx
ret
endp
 
align 4
proc user_alloc stdcall, alloc_size:dword
 
push ebx
push esi
push edi
 
mov ecx, [alloc_size]
add ecx, (4095+4096)
and ecx, not 4095
 
mov ebx, [current_slot]
mov esi, dword [ebx+APPDATA.heap_base] ; heap_base
mov edi, dword [ebx+APPDATA.heap_top] ; heap_top
l_0:
cmp esi, edi
jae m_exit
 
mov ebx, esi
shr ebx, 12
mov eax, [page_tabs+ebx*4]
test al, FREE_BLOCK
jz test_used
and eax, 0xFFFFF000
cmp eax, ecx ;alloc_size
jb m_next
jz @f
 
lea edx, [esi+ecx]
sub eax, ecx
or al, FREE_BLOCK
shr edx, 12
mov [page_tabs+edx*4], eax
@@:
or ecx, USED_BLOCK
mov [page_tabs+ebx*4], ecx
shr ecx, 12
inc ebx
dec ecx
jz .no
@@:
mov dword [page_tabs+ebx*4], 2
inc ebx
dec ecx
jnz @B
.no:
 
mov edx, [current_slot]
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add ebx, [edx+APPDATA.mem_size]
call update_mem_size
 
lea eax, [esi+4096]
 
pop edi
pop esi
pop ebx
ret
test_used:
test al, USED_BLOCK
jz m_exit
 
and eax, 0xFFFFF000
m_next:
add esi, eax
jmp l_0
m_exit:
xor eax, eax
pop edi
pop esi
pop ebx
ret
endp
 
align 4
proc user_alloc_at stdcall, address:dword, alloc_size:dword
 
push ebx
push esi
push edi
 
mov ebx, [current_slot]
mov edx, [address]
and edx, not 0xFFF
mov [address], edx
sub edx, 0x1000
jb .error
mov esi, [ebx+APPDATA.heap_base]
mov edi, [ebx+APPDATA.heap_top]
cmp edx, esi
jb .error
.scan:
cmp esi, edi
jae .error
mov ebx, esi
shr ebx, 12
mov eax, [page_tabs+ebx*4]
mov ecx, eax
and ecx, 0xFFFFF000
add ecx, esi
cmp edx, ecx
jb .found
mov esi, ecx
jmp .scan
.error:
xor eax, eax
pop edi
pop esi
pop ebx
ret
.found:
test al, FREE_BLOCK
jz .error
mov eax, ecx
sub eax, edx
sub eax, 0x1000
cmp eax, [alloc_size]
jb .error
 
; Here we have 1 big free block which includes requested area.
; In general, 3 other blocks must be created instead:
; free at [esi, edx);
; busy at [edx, edx+0x1000+ALIGN_UP(alloc_size,0x1000));
; free at [edx+0x1000+ALIGN_UP(alloc_size,0x1000), ecx)
; First or third block (or both) may be absent.
mov eax, edx
sub eax, esi
jz .nofirst
or al, FREE_BLOCK
mov [page_tabs+ebx*4], eax
.nofirst:
mov eax, [alloc_size]
add eax, 0x1FFF
and eax, not 0xFFF
mov ebx, edx
add edx, eax
shr ebx, 12
or al, USED_BLOCK
mov [page_tabs+ebx*4], eax
shr eax, 12
dec eax
jz .second_nofill
inc ebx
.fill:
mov dword [page_tabs+ebx*4], 2
inc ebx
dec eax
jnz .fill
.second_nofill:
sub ecx, edx
jz .nothird
or cl, FREE_BLOCK
mov [page_tabs+ebx*4], ecx
.nothird:
 
mov edx, [current_slot]
mov ebx, [alloc_size]
add ebx, 0xFFF
and ebx, not 0xFFF
add ebx, [edx+APPDATA.mem_size]
call update_mem_size
 
mov eax, [address]
 
pop edi
pop esi
pop ebx
ret
endp
 
align 4
proc user_free stdcall, base:dword
 
push esi
 
mov esi, [base]
test esi, esi
jz .exit
 
push ebx
 
xor ebx, ebx
shr esi, 12
mov eax, [page_tabs+(esi-1)*4]
test al, USED_BLOCK
jz .cantfree
test al, DONT_FREE_BLOCK
jnz .cantfree
 
and eax, not 4095
mov ecx, eax
or al, FREE_BLOCK
mov [page_tabs+(esi-1)*4], eax
sub ecx, 4096
mov ebx, ecx
shr ecx, 12
jz .released
.release:
xor eax, eax
xchg eax, [page_tabs+esi*4]
test al, 1
jz @F
test eax, PG_SHARED
jnz @F
call free_page
mov eax, esi
shl eax, 12
invlpg [eax]
@@:
inc esi
dec ecx
jnz .release
.released:
push edi
 
mov edx, [current_slot]
mov esi, dword [edx+APPDATA.heap_base]
mov edi, dword [edx+APPDATA.heap_top]
sub ebx, [edx+APPDATA.mem_size]
neg ebx
call update_mem_size
call user_normalize
pop edi
pop ebx
pop esi
ret
.exit:
xor eax, eax
inc eax
pop esi
ret
.cantfree:
xor eax, eax
pop ebx
pop esi
ret
endp
 
user_normalize:
; in: esi=heap_base, edi=heap_top
; out: eax=0 <=> OK
; destroys: ebx,edx,esi,edi
shr esi, 12
shr edi, 12
@@:
mov eax, [page_tabs+esi*4]
test al, USED_BLOCK
jz .test_free
shr eax, 12
add esi, eax
jmp @B
.test_free:
test al, FREE_BLOCK
jz .err
mov edx, eax
shr edx, 12
add edx, esi
cmp edx, edi
jae .exit
 
mov ebx, [page_tabs+edx*4]
test bl, USED_BLOCK
jz .next_free
 
shr ebx, 12
add edx, ebx
mov esi, edx
jmp @B
.next_free:
test bl, FREE_BLOCK
jz .err
and dword [page_tabs+edx*4], 0
add eax, ebx
and eax, not 4095
or eax, FREE_BLOCK
mov [page_tabs+esi*4], eax
jmp @B
.exit:
xor eax, eax
inc eax
ret
.err:
xor eax, eax
ret
 
user_realloc:
; in: eax = pointer, ebx = new size
; out: eax = new pointer or NULL
test eax, eax
jnz @f
; realloc(NULL,sz) - same as malloc(sz)
push ebx
call user_alloc
ret
@@:
push ecx edx
lea ecx, [eax - 0x1000]
shr ecx, 12
mov edx, [page_tabs+ecx*4]
test dl, USED_BLOCK
jnz @f
; attempt to realloc invalid pointer
.ret0:
pop edx ecx
xor eax, eax
ret
@@:
test dl, DONT_FREE_BLOCK
jnz .ret0
add ebx, 0x1FFF
shr edx, 12
shr ebx, 12
; edx = allocated size, ebx = new size
add edx, ecx
add ebx, ecx
cmp edx, ebx
jb .realloc_add
; release part of allocated memory
.loop:
cmp edx, ebx
jz .release_done
dec edx
xor eax, eax
xchg eax, [page_tabs+edx*4]
test al, 1
jz .loop
call free_page
mov eax, edx
shl eax, 12
invlpg [eax]
jmp .loop
.release_done:
sub ebx, ecx
cmp ebx, 1
jnz .nofreeall
mov eax, [page_tabs+ecx*4]
and eax, not 0xFFF
mov edx, [current_slot]
mov ebx, [APPDATA.mem_size+edx]
sub ebx, eax
add ebx, 0x1000
or al, FREE_BLOCK
mov [page_tabs+ecx*4], eax
push esi edi
mov esi, [APPDATA.heap_base+edx]
mov edi, [APPDATA.heap_top+edx]
call update_mem_size
call user_normalize
pop edi esi
jmp .ret0 ; all freed
.nofreeall:
sub edx, ecx
shl ebx, 12
or ebx, USED_BLOCK
xchg [page_tabs+ecx*4], ebx
shr ebx, 12
sub ebx, edx
push ebx ecx edx
mov edx, [current_slot]
shl ebx, 12
sub ebx, [APPDATA.mem_size+edx]
neg ebx
call update_mem_size
pop edx ecx ebx
lea eax, [ecx+1]
shl eax, 12
push eax
add ecx, edx
lea edx, [ecx+ebx]
shl ebx, 12
jz .ret
push esi
mov esi, [current_slot]
mov esi, [APPDATA.heap_top+esi]
shr esi, 12
@@:
cmp edx, esi
jae .merge_done
mov eax, [page_tabs+edx*4]
test al, USED_BLOCK
jnz .merge_done
and dword [page_tabs+edx*4], 0
shr eax, 12
add edx, eax
shl eax, 12
add ebx, eax
jmp @b
.merge_done:
pop esi
or ebx, FREE_BLOCK
mov [page_tabs+ecx*4], ebx
.ret:
pop eax edx ecx
ret
.realloc_add:
; get some additional memory
mov eax, [current_slot]
mov eax, [APPDATA.heap_top+eax]
shr eax, 12
cmp edx, eax
jae .cant_inplace
mov eax, [page_tabs+edx*4]
test al, FREE_BLOCK
jz .cant_inplace
shr eax, 12
add eax, edx
sub eax, ebx
jb .cant_inplace
jz @f
shl eax, 12
or al, FREE_BLOCK
mov [page_tabs+ebx*4], eax
@@:
mov eax, ebx
sub eax, ecx
shl eax, 12
or al, USED_BLOCK
mov [page_tabs+ecx*4], eax
lea eax, [ecx+1]
shl eax, 12
push eax
push edi
lea edi, [page_tabs+edx*4]
mov eax, 2
sub ebx, edx
mov ecx, ebx
cld
rep stosd
pop edi
mov edx, [current_slot]
shl ebx, 12
add ebx, [APPDATA.mem_size+edx]
call update_mem_size
pop eax edx ecx
ret
.cant_inplace:
push esi edi
mov eax, [current_slot]
mov esi, [APPDATA.heap_base+eax]
mov edi, [APPDATA.heap_top+eax]
shr esi, 12
shr edi, 12
sub ebx, ecx
.find_place:
cmp esi, edi
jae .place_not_found
mov eax, [page_tabs+esi*4]
test al, FREE_BLOCK
jz .next_place
shr eax, 12
cmp eax, ebx
jae .place_found
add esi, eax
jmp .find_place
.next_place:
shr eax, 12
add esi, eax
jmp .find_place
.place_not_found:
pop edi esi
jmp .ret0
.place_found:
sub eax, ebx
jz @f
push esi
add esi, ebx
shl eax, 12
or al, FREE_BLOCK
mov [page_tabs+esi*4], eax
pop esi
@@:
mov eax, ebx
shl eax, 12
or al, USED_BLOCK
mov [page_tabs+esi*4], eax
inc esi
mov eax, esi
shl eax, 12
push eax
mov eax, [page_tabs+ecx*4]
and eax, not 0xFFF
or al, FREE_BLOCK
sub edx, ecx
mov [page_tabs+ecx*4], eax
inc ecx
dec ebx
dec edx
jz .no
@@:
xor eax, eax
xchg eax, [page_tabs+ecx*4]
mov [page_tabs+esi*4], eax
mov eax, ecx
shl eax, 12
invlpg [eax]
inc esi
inc ecx
dec ebx
dec edx
jnz @b
.no:
push ebx
mov edx, [current_slot]
shl ebx, 12
add ebx, [APPDATA.mem_size+edx]
call update_mem_size
pop ebx
@@:
mov dword [page_tabs+esi*4], 2
inc esi
dec ebx
jnz @b
pop eax edi esi edx ecx
ret
 
if 0
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,0x02
lea eax,[srv_tab+eax+eax*8] ;srv_tab+eax*36
ret
endp
 
end if
 
 
;;;;;;;;;;;;;; SHARED ;;;;;;;;;;;;;;;;;
 
 
; param
; eax= shm_map object
 
align 4
destroy_smap:
 
pushfd
cli
 
push esi
push edi
 
mov edi, eax
mov esi, [eax+SMAP.parent]
test esi, esi
jz .done
 
lock dec [esi+SMEM.refcount]
jnz .done
 
mov ecx, [esi+SMEM.bk]
mov edx, [esi+SMEM.fd]
 
mov [ecx+SMEM.fd], edx
mov [edx+SMEM.bk], ecx
 
stdcall kernel_free, [esi+SMEM.base]
mov eax, esi
call free
.done:
mov eax, edi
call destroy_kernel_object
 
pop edi
pop esi
popfd
 
ret
 
E_NOTFOUND equ 5
E_ACCESS equ 10
E_NOMEM equ 30
E_PARAM equ 33
 
SHM_READ equ 0
SHM_WRITE equ 1
 
SHM_ACCESS_MASK equ 3
 
SHM_OPEN equ (0 shl 2)
SHM_OPEN_ALWAYS equ (1 shl 2)
SHM_CREATE equ (2 shl 2)
 
SHM_OPEN_MASK equ (3 shl 2)
 
align 4
proc shmem_open stdcall name:dword, size:dword, access:dword
locals
action dd ?
owner_access dd ?
mapped dd ?
endl
 
push ebx
push esi
push edi
 
mov [mapped], 0
mov [owner_access], 0
 
pushfd ;mutex required
cli
 
mov eax, [access]
and eax, SHM_OPEN_MASK
mov [action], eax
 
mov ebx, [name]
test ebx, ebx
mov edx, E_PARAM
jz .fail
 
mov esi, [shmem_list.fd]
align 4
@@:
cmp esi, shmem_list
je .not_found
 
lea edx, [esi+SMEM.name] ; link , base, size
stdcall strncmp, edx, ebx, 32
test eax, eax
je .found
 
mov esi, [esi+SMEM.fd]
jmp @B
 
.not_found:
mov eax, [action]
 
cmp eax, SHM_OPEN
mov edx, E_NOTFOUND
je .fail
 
cmp eax, SHM_CREATE
mov edx, E_PARAM
je .create_shm
 
cmp eax, SHM_OPEN_ALWAYS
jne .fail
 
.create_shm:
 
mov ecx, [size]
test ecx, ecx
jz .fail
 
add ecx, 4095
and ecx, -4096
mov [size], ecx
 
mov eax, SMEM.sizeof
call malloc
test eax, eax
mov esi, eax
mov edx, E_NOMEM
jz .fail
 
stdcall kernel_alloc, [size]
test eax, eax
mov [mapped], eax
mov edx, E_NOMEM
jz .cleanup
 
mov ecx, [size]
mov edx, [access]
and edx, SHM_ACCESS_MASK
 
mov [esi+SMEM.base], eax
mov [esi+SMEM.size], ecx
mov [esi+SMEM.access], edx
mov [esi+SMEM.refcount], 0
mov [esi+SMEM.name+28], 0
 
lea eax, [esi+SMEM.name]
stdcall strncpy, eax, [name], 31
 
mov eax, [shmem_list.fd]
mov [esi+SMEM.bk], shmem_list
mov [esi+SMEM.fd], eax
 
mov [eax+SMEM.bk], esi
mov [shmem_list.fd], esi
 
mov [action], SHM_OPEN
mov [owner_access], SHM_WRITE
 
.found:
mov eax, [action]
 
cmp eax, SHM_CREATE
mov edx, E_ACCESS
je .exit
 
cmp eax, SHM_OPEN
mov edx, E_PARAM
je .create_map
 
cmp eax, SHM_OPEN_ALWAYS
jne .fail
 
.create_map:
 
mov eax, [access]
and eax, SHM_ACCESS_MASK
cmp eax, [esi+SMEM.access]
mov [access], eax
mov edx, E_ACCESS
ja .fail
 
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov ebx, [CURRENT_TASK+ebx+4]
mov eax, SMAP.sizeof
 
call create_kernel_object
test eax, eax
mov edi, eax
mov edx, E_NOMEM
jz .fail
 
inc [esi+SMEM.refcount]
 
mov [edi+SMAP.magic], 'SMAP'
mov [edi+SMAP.destroy], destroy_smap
mov [edi+SMAP.parent], esi
mov [edi+SMAP.base], 0
 
stdcall user_alloc, [esi+SMEM.size]
test eax, eax
mov [mapped], eax
mov edx, E_NOMEM
jz .cleanup2
 
mov [edi+SMAP.base], eax
 
mov ecx, [esi+SMEM.size]
mov [size], ecx
 
shr ecx, 12
shr eax, 10
 
mov esi, [esi+SMEM.base]
shr esi, 10
lea edi, [page_tabs+eax]
add esi, page_tabs
 
mov edx, [access]
or edx, [owner_access]
shl edx, 1
or edx, PG_USER+PG_SHARED
@@:
lodsd
and eax, 0xFFFFF000
or eax, edx
stosd
loop @B
 
xor edx, edx
 
cmp [owner_access], 0
jne .fail
.exit:
mov edx, [size]
.fail:
mov eax, [mapped]
 
popfd
pop edi
pop esi
pop ebx
ret
.cleanup:
mov [size], edx
mov eax, esi
call free
jmp .exit
 
.cleanup2:
mov [size], edx
mov eax, edi
call destroy_smap
jmp .exit
endp
 
align 4
proc shmem_close stdcall, name:dword
 
mov eax, [name]
test eax, eax
jz .fail
 
push esi
push edi
pushfd
cli
 
mov esi, [current_slot]
add esi, APP_OBJ_OFFSET
.next:
mov eax, [esi+APPOBJ.fd]
test eax, eax
jz @F
 
cmp eax, esi
mov esi, eax
je @F
 
cmp [eax+SMAP.magic], 'SMAP'
jne .next
 
mov edi, [eax+SMAP.parent]
test edi, edi
jz .next
 
lea edi, [edi+SMEM.name]
stdcall strncmp, [name], edi, 32
test eax, eax
jne .next
 
stdcall user_free, [esi+SMAP.base]
 
mov eax,esi
call [esi+APPOBJ.destroy]
@@:
popfd
pop edi
pop esi
.fail:
ret
endp
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/peload.inc
0,0 → 1,329
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
include 'export.inc'
 
align 4
 
proc load_PE stdcall, file_name:dword
locals
image dd ?
entry dd ?
base dd ?
endl
 
stdcall load_file, [file_name]
test eax, eax
jz .fail
 
mov [image], eax
 
mov edx, [eax+60]
 
stdcall kernel_alloc, [eax+80+edx]
test eax, eax
jz .cleanup
 
mov [base], eax
 
stdcall map_PE, eax, [image]
 
mov [entry], eax
test eax, eax
jnz .cleanup
 
stdcall kernel_free, [base]
.cleanup:
stdcall kernel_free, [image]
mov eax, [entry]
ret
.fail:
xor eax, eax
ret
endp
 
DWORD equ dword
PTR equ
 
align 4
map_PE: ;stdcall base:dword, image:dword
cld
push ebp
push edi
push esi
push ebx
sub esp, 60
mov ebx, DWORD PTR [esp+84]
mov ebp, DWORD PTR [esp+80]
mov edx, ebx
mov esi, ebx
add edx, DWORD PTR [ebx+60]
mov edi, ebp
mov DWORD PTR [esp+32], edx
mov ecx, DWORD PTR [edx+84]
 
shr ecx, 2
rep movsd
 
movzx eax, WORD PTR [edx+6]
mov DWORD PTR [esp+36], 0
mov DWORD PTR [esp+16], eax
jmp L2
L3:
mov eax, DWORD PTR [edx+264]
test eax, eax
je L4
mov esi, ebx
mov edi, ebp
add esi, DWORD PTR [edx+268]
mov ecx, eax
add edi, DWORD PTR [edx+260]
 
shr ecx, 2
rep movsd
 
L4:
mov ecx, DWORD PTR [edx+256]
add ecx, 4095
and ecx, -4096
cmp ecx, eax
jbe L6
sub ecx, eax
add eax, DWORD PTR [edx+260]
lea edi, [eax+ebp]
 
xor eax, eax
rep stosb
 
L6:
inc DWORD PTR [esp+36]
add edx, 40
L2:
mov esi, DWORD PTR [esp+16]
cmp DWORD PTR [esp+36], esi
jne L3
mov edi, DWORD PTR [esp+32]
cmp DWORD PTR [edi+164], 0
je L9
mov esi, ebp
mov ecx, ebp
sub esi, DWORD PTR [edi+52]
add ecx, DWORD PTR [edi+160]
mov eax, esi
shr eax, 16
mov DWORD PTR [esp+12], eax
jmp L11
L12:
lea ebx, [eax-8]
xor edi, edi
shr ebx,1
jmp L13
L14:
movzx eax, WORD PTR [ecx+8+edi*2]
mov edx, eax
shr eax, 12
and edx, 4095
add edx, DWORD PTR [ecx]
cmp ax, 2
je L17
cmp ax, 3
je L18
dec ax
jne L15
mov eax, DWORD PTR [esp+12]
add WORD PTR [edx+ebp], ax
L17:
add WORD PTR [edx+ebp], si
L18:
add DWORD PTR [edx+ebp], esi
L15:
inc edi
L13:
cmp edi, ebx
jne L14
add ecx, DWORD PTR [ecx+4]
L11:
mov eax, DWORD PTR [ecx+4]
test eax, eax
jne L12
L9:
mov edx, DWORD PTR [esp+32]
cmp DWORD PTR [edx+132], 0
je L20
mov eax, ebp
add eax, DWORD PTR [edx+128]
mov DWORD PTR [esp+40], 0
add eax, 20
mov DWORD PTR [esp+56], eax
L22:
mov ecx, DWORD PTR [esp+56]
cmp DWORD PTR [ecx-16], 0
jne L23
cmp DWORD PTR [ecx-8], 0
je L25
L23:
mov edi, DWORD PTR [__exports+32]
mov esi, DWORD PTR [__exports+28]
mov eax, DWORD PTR [esp+56]
mov DWORD PTR [esp+20], edi
add edi, OS_BASE
add esi, OS_BASE
mov DWORD PTR [esp+44], esi
mov ecx, DWORD PTR [eax-4]
mov DWORD PTR [esp+48], edi
mov edx, DWORD PTR [eax-20]
mov DWORD PTR [esp+52], 0
add ecx, ebp
add edx, ebp
mov DWORD PTR [esp+24], edx
mov DWORD PTR [esp+28], ecx
L26:
mov esi, DWORD PTR [esp+52]
mov edi, DWORD PTR [esp+24]
mov eax, DWORD PTR [edi+esi*4]
test eax, eax
je L27
test eax, eax
js L27
lea edi, [ebp+eax]
mov eax, DWORD PTR [esp+28]
mov DWORD PTR [eax+esi*4], 0
lea esi, [edi+2]
push eax
push 32
movzx eax, WORD PTR [edi]
mov edx, DWORD PTR [esp+56]
mov eax, DWORD PTR [edx+eax*4]
add eax, OS_BASE
push eax
push esi
call strncmp
pop ebx
xor ebx, ebx
test eax, eax
jne L32
jmp L30
L33:
push ecx
push 32
mov ecx, DWORD PTR [esp+28]
mov eax, DWORD PTR [ecx+OS_BASE+ebx*4]
add eax, OS_BASE
push eax
push esi
call strncmp
pop edx
test eax, eax
jne L34
mov esi, DWORD PTR [esp+44]
mov edx, DWORD PTR [esp+52]
mov ecx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+ebx*4]
add eax, OS_BASE
mov DWORD PTR [ecx+edx*4], eax
jmp L36
L34:
inc ebx
L32:
cmp ebx, DWORD PTR [__exports+24]
jb L33
L36:
cmp ebx, DWORD PTR [__exports+24]
jne L37
 
mov esi, msg_unresolved
call sys_msg_board_str
lea esi, [edi+2]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
 
mov DWORD PTR [esp+40], 1
jmp L37
L30:
movzx eax, WORD PTR [edi]
mov esi, DWORD PTR [esp+44]
mov edi, DWORD PTR [esp+52]
mov edx, DWORD PTR [esp+28]
mov eax, DWORD PTR [esi+eax*4]
add eax, OS_BASE
mov DWORD PTR [edx+edi*4], eax
L37:
inc DWORD PTR [esp+52]
jmp L26
L27:
add DWORD PTR [esp+56], 20
jmp L22
L25:
xor eax, eax
cmp DWORD PTR [esp+40], 0
jne L40
L20:
mov ecx, DWORD PTR [esp+32]
mov eax, ebp
add eax, DWORD PTR [ecx+40]
L40:
add esp, 60
pop ebx
pop esi
pop edi
pop ebp
ret 8
 
align 16
__exports:
export 'KERNEL', \
alloc_kernel_space, 'AllocKernelSpace', \ ; stdcall
alloc_page, 'AllocPage', \ ; gcc ABI
alloc_pages, 'AllocPages', \ ; stdcall
commit_pages, 'CommitPages', \ ; eax, ebx, ecx
\
create_event, 'CreateEvent', \ ; ecx, esi
raise_event, 'RaiseEvent', \ ; eax, ebx, edx, esi
wait_event, 'WaitEvent', \ ; eax, ebx
get_event_ex, 'GetEvent', \ ; edi
\
create_kernel_object, 'CreateObject', \
create_ring_buffer, 'CreateRingBuffer', \ ; stdcall
destroy_kernel_object, 'DestroyObject', \
free_kernel_space, 'FreeKernelSpace', \ ; stdcall
kernel_alloc, 'KernelAlloc', \ ; stdcall
kernel_free, 'KernelFree', \ ; stdcall
malloc, 'Kmalloc', \
free, 'Kfree', \
map_io_mem, 'MapIoMem', \ ; stdcall
get_pg_addr, 'GetPgAddr', \ ; eax
\
mutex_init, 'MutexInit', \ ; gcc fastcall
mutex_lock, 'MutexLock', \ ; gcc fastcall
mutex_unlock, 'MutexUnlock', \ ; gcc fastcall
\
get_display, 'GetDisplay', \
set_screen, 'SetScreen', \
pci_api_drv, 'PciApi', \
pci_read8, 'PciRead8', \ ; stdcall
pci_read16, 'PciRead16', \ ; stdcall
pci_read32, 'PciRead32', \ ; stdcall
pci_write8, 'PciWrite8', \ ; stdcall
pci_write16, 'PciWrite16', \ ; stdcall
pci_write32, 'PciWrite32', \ ; stdcall
\
get_service, 'GetService', \ ;
reg_service, 'RegService', \ ; stdcall
attach_int_handler, 'AttachIntHandler', \ ; stdcall
user_alloc, 'UserAlloc', \ ; stdcall
user_free, 'UserFree', \ ; stdcall
unmap_pages, 'UnmapPages', \ ; eax, ecx
sys_msg_board_str, 'SysMsgBoardStr', \
get_timer_ticks, 'GetTimerTicks', \
delay_hs, 'Delay', \ ; ebx
set_mouse_data, 'SetMouseData'
 
 
 
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/exports.inc
0,0 → 1,161
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
iglobal
szKernel db 'KERNEL', 0
szVersion db 'version',0
 
szRegService db 'RegService',0
szGetService db 'GetService',0
szServiceHandler db 'ServiceHandler',0
szAttachIntHandler db 'AttachIntHandler',0
szGetIntHandler db 'GetIntHandler', 0
szFpuSave db 'FpuSave',0
szFpuRestore db 'FpuRestore',0
szReservePortArea db 'ReservePortArea',0
szBoot_Log db 'Boot_Log',0
 
szMutexInit db 'MutexInit',0
szMutexLock db 'MutexLock',0
szMutexUnlock db 'MutexUnlock',0
 
szPciApi db 'PciApi', 0
szPciRead32 db 'PciRead32', 0
szPciRead16 db 'PciRead16', 0
szPciRead8 db 'PciRead8', 0
szPciWrite8 db 'PciWrite8',0
szPciWrite16 db 'PciWrite16',0
szPciWrite32 db 'PciWrite32',0
 
szAllocPage db 'AllocPage',0
szAllocPages db 'AllocPages',0
szFreePage db 'FreePage',0
szGetPgAddr db 'GetPgAddr',0
szMapPage db 'MapPage',0
szMapSpace db 'MapSpace',0
szMapIoMem db 'MapIoMem',0
szCommitPages db 'CommitPages',0
szReleasePages db 'ReleasePages',0
 
szAllocKernelSpace db 'AllocKernelSpace',0
szFreeKernelSpace db 'FreeKernelSpace',0
szKernelAlloc db 'KernelAlloc',0
szKernelFree db 'KernelFree',0
szUserAlloc db 'UserAlloc',0
szUserFree db 'UserFree',0
szKmalloc db 'Kmalloc',0
szKfree db 'Kfree',0
szCreateRingBuffer db 'CreateRingBuffer',0
 
szGetPid db 'GetPid',0
szCreateObject db 'CreateObject',0
szDestroyObject db 'DestroyObject',0
szCreateEvent db 'CreateEvent',0
szRaiseEvent db 'RaiseEvent',0
szWaitEvent db 'WaitEvent',0
szDestroyEvent db 'DestroyEvent',0
szClearEvent db 'ClearEvent',0
 
szLoadCursor db 'LoadCursor',0
 
szSysMsgBoardStr db 'SysMsgBoardStr', 0
szSysMsgBoardChar db 'SysMsgBoardChar', 0
szGetCurrentTask db 'GetCurrentTask',0
szLFBAddress db 'LFBAddress',0
szLoadFile db 'LoadFile',0
szSendEvent db 'SendEvent',0
szSetMouseData db 'SetMouseData',0
szSleep db 'Sleep',0
szGetTimerTicks db 'GetTimerTicks',0
 
szStrncat db 'strncat',0
szStrncpy db 'strncpy',0
szstrncmp db 'strncmp',0
szStrnlen db 'strnlen',0
szStrchr db 'strchr',0
szStrrchr db 'strrchr',0
 
 
align 16
kernel_export:
dd szRegService , reg_service
dd szGetService , get_service
dd szServiceHandler , srv_handler
dd szAttachIntHandler, attach_int_handler
dd szGetIntHandler , get_int_handler
dd szFpuSave , fpu_save
dd szFpuRestore , fpu_restore
dd szReservePortArea , r_f_port_area
dd szBoot_Log , boot_log
 
dd szMutexInit , mutex_init ;gcc fastcall
dd szMutexLock , mutex_lock ;gcc fastcall
dd szMutexUnlock , mutex_unlock ;gcc fastcall
 
dd szPciApi , pci_api_drv
dd szPciRead32 , pci_read32
dd szPciRead16 , pci_read16
dd szPciRead8 , pci_read8
dd szPciWrite8 , pci_write8
dd szPciWrite16 , pci_write16
dd szPciWrite32 , pci_write32
 
dd szAllocPage , alloc_page ;stdcall
dd szAllocPages , alloc_pages ;stdcall
dd szFreePage , free_page
dd szMapPage , map_page ;stdcall
dd szMapSpace , map_space
dd szMapIoMem , map_io_mem ;stdcall
dd szGetPgAddr , get_pg_addr
dd szCommitPages , commit_pages ;not implemented
dd szReleasePages , release_pages
 
dd szAllocKernelSpace, alloc_kernel_space ;stdcall
dd szFreeKernelSpace , free_kernel_space ;stdcall
dd szKernelAlloc , kernel_alloc ;stdcall
dd szKernelFree , kernel_free ;stdcall
dd szUserAlloc , user_alloc ;stdcall
dd szUserFree , user_free ;stdcall
dd szKmalloc , malloc
dd szKfree , free
dd szCreateRingBuffer, create_ring_buffer ;stdcall
 
dd szGetPid , get_pid
dd szCreateObject , create_kernel_object
dd szDestroyObject , destroy_kernel_object
dd szCreateEvent , create_event ;see EVENT.inc for specification
dd szRaiseEvent , raise_event ;see EVENT.inc for specification
dd szWaitEvent , wait_event ;see EVENT.inc for specification
dd szDestroyEvent , destroy_event ;see EVENT.inc for specification
dd szClearEvent , clear_event ;see EVENT.inc for specification
 
dd szLoadCursor , load_cursor ;stdcall
 
dd szSysMsgBoardStr , sys_msg_board_str
dd szSysMsgBoardChar , sys_msg_board
dd szGetCurrentTask , get_curr_task
dd szLoadFile , load_file ;retval eax, ebx
dd szSendEvent , send_event ;see EVENT.inc for specification
dd szSetMouseData , set_mouse_data ;stdcall
dd szSleep , delay_ms
dd szGetTimerTicks , get_timer_ticks
 
dd szStrncat , strncat
dd szStrncpy , strncpy
dd szstrncmp , strncmp
dd szStrnlen , strnlen
dd szStrchr , strchr
dd szStrrchr , strrchr
 
exp_lfb:
dd szLFBAddress , 0
dd 0 ;terminator, must be zero
 
endg
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/syscall.inc
0,0 → 1,199
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
; Old style system call converter
align 16
cross_order:
; load all registers in crossed order
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, esi
mov esi, edi
movzx edi, byte[esp+28 + 4]
sub edi,53
call dword [servetable+edi*4]
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSENTER ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 32
sysenter_entry:
; Íàñòðàèâàåì ñòåê
mov esp, [ss:tss._esp0]
sti
push ebp ; save app esp + 4
mov ebp, [ebp] ; ebp - original ebp
;------------------
pushad
cld
 
movzx eax, al
call dword [servetable2 + eax * 4]
 
popad
;------------------
xchg ecx, [ss:esp] ; â âåðøèí ñòåêà - app ecx, ecx - app esp + 4
sub ecx, 4
xchg edx, [ecx] ; edx - return point, & save original edx
push edx
mov edx, [ss:esp + 4]
mov [ecx + 4], edx ; save original ecx
pop edx
sysexit
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSTEM CALL ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 16
i40:
pushad
cld
movzx eax, al
call dword [servetable2 + eax * 4]
popad
iretd
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSCALL ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 32
syscall_entry:
; cli syscall clear IF
xchg esp, [ss:tss._esp0]
push ecx
lea ecx, [esp+4]
xchg ecx, [ss:tss._esp0]
sti
push ecx
mov ecx, [ecx]
;------------------
pushad
cld
 
movzx eax, al
call dword [servetable2 + eax * 4]
 
popad
;------------------
mov ecx, [ss:esp+4]
pop esp
sysret
 
iglobal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SYSTEM FUNCTIONS TABLE ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
servetable:
dd socket ; 53-Socket interface
dd 0
dd 0
dd 0
dd 0
dd file_system ; 58-Common file system interface
dd 0
dd 0
dd 0
dd 0 ; 62-PCI functions
dd sys_msg_board ; 63-System message board
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; NEW SYSTEM FUNCTIONS TABLE ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4
servetable2:
 
dd syscall_draw_window ; 0-DrawWindow
dd syscall_setpixel ; 1-SetPixel
dd sys_getkey ; 2-GetKey
dd sys_clock ; 3-GetTime
dd syscall_writetext ; 4-WriteText
dd delay_hs ; 5-DelayHs
dd syscall_openramdiskfile ; 6-OpenRamdiskFile
dd syscall_putimage ; 7-PutImage
dd syscall_button ; 8-DefineButton
dd sys_cpuusage ; 9-GetProcessInfo
dd sys_waitforevent ; 10-WaitForEvent
dd sys_getevent ; 11-CheckForEvent
dd sys_redrawstat ; 12-BeginDraw and EndDraw
dd syscall_drawrect ; 13-DrawRect
dd syscall_getscreensize ; 14-GetScreenSize
dd sys_background ; 15-bgr
dd sys_cachetodiskette ; 16-FlushFloppyCache
dd sys_getbutton ; 17-GetButton
dd sys_system ; 18-System Services
dd paleholder ; 19-reserved
dd sys_midi ; 20-ResetMidi and OutputMidi
dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,.
dd sys_settime ; 22-setting date,time,clock and alarm-clock
dd sys_wait_event_timeout ; 23-TimeOutWaitForEvent
dd syscall_cdaudio ; 24-PlayCdTrack,StopCd and GetCdPlaylist
dd undefined_syscall ; 25-reserved
dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,.
dd undefined_syscall ; 27-reserved
dd undefined_syscall ; 28-reserved
dd sys_date ; 29-GetDate
dd sys_current_directory ; 30-Get/SetCurrentDirectory
dd undefined_syscall ; 31-reserved
dd undefined_syscall ; 32-reserved
dd undefined_syscall ; 33-reserved
dd undefined_syscall ; 34-reserved
dd syscall_getpixel ; 35-GetPixel
dd syscall_getarea ; 36-GetArea
dd readmousepos ; 37-GetMousePosition_ScreenRelative,.
dd syscall_drawline ; 38-DrawLine
dd sys_getbackground ; 39-GetBackgroundSize,ReadBgrData,.
dd set_app_param ; 40-WantEvents
dd syscall_getirqowner ; 41-GetIrqOwner
dd get_irq_data ; 42-ReadIrqData
dd sys_outport ; 43-SendDeviceData
dd sys_programirq ; 44-ProgramIrqs
dd reserve_free_irq ; 45-ReserveIrq and FreeIrq
dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea
dd display_number ; 47-WriteNum
dd syscall_display_settings ; 48-SetRedrawType and SetButtonType
dd sys_apm ; 49-Advanced Power Management (APM)
dd syscall_set_window_shape ; 50-Window shape & scale
dd syscall_threads ; 51-Threads
dd stack_driver_stat ; 52-Stack driver status
dd cross_order ; 53-Socket interface
dd undefined_syscall ; 54-reserved
dd sound_interface ; 55-Sound interface
dd undefined_syscall ; 56-reserved
dd sys_pcibios ; 57-PCI BIOS32
dd cross_order ; 58-Common file system interface
dd undefined_syscall ; 59-reserved
dd sys_IPC ; 60-Inter Process Communication
dd sys_gs ; 61-Direct graphics access
dd pci_api ;cross_order ; 62-PCI functions
dd cross_order ; 63-System message board
dd sys_resize_app_memory ; 64-Resize application memory usage
dd sys_putimage_palette ; 65-PutImagePalette
dd sys_process_def ; 66-Process definitions - keyboard
dd syscall_move_window ; 67-Window move or resize
dd f68 ; 68-Some internal services
dd sys_debug_services ; 69-Debug
dd file_system_lfn ; 70-Common file system interface, version 2
dd syscall_window_settings ; 71-Window settings
dd sys_sendwindowmsg ; 72-Send window message
times 255 - ( ($-servetable2) /4 ) dd undefined_syscall
dd sys_end ; -1-end application
 
endg
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/dll.inc
0,0 → 1,1689
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
DRV_COMPAT equ 5 ;minimal required drivers version
DRV_CURRENT equ 5 ;current drivers model version
 
DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT
PID_KERNEL equ 1 ;os_idle thread
 
align 4
proc attach_int_handler stdcall, irq:dword, handler:dword, access_rights:dword
 
push ebx
 
mov ebx, [irq] ;irq num
test ebx, ebx
jz .err
cmp ebx, 15 ; hidnplayr says: we only have 16 IRQ's
ja .err
mov eax, [handler]
test eax, eax
jz .err
cmp [irq_owner + 4 * ebx], 0
je @f
 
mov ecx, [irq_rights + 4 * ebx] ; Rights : 0 - full access, 1 - read only, 2 - forbidden
test ecx, ecx
jnz .err
 
@@:
mov [irq_tab+ebx*4], eax
 
mov eax, [access_rights]
mov [irq_rights + 4 * ebx], eax
 
mov [irq_owner + 4 * ebx], PID_KERNEL ; all handlers belong to a kernel
 
stdcall enable_irq, [irq]
pop ebx
mov eax, 1
ret
.err:
pop ebx
xor eax, eax
ret
endp
 
uglobal
 
irq_rights rd 16
 
endg
 
proc get_int_handler stdcall, irq:dword
 
mov eax, [irq]
 
cmp [irq_rights + 4 * eax], dword 1
ja .err
 
mov eax, [irq_tab + 4 * eax]
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 1
jmp .main
align 4
.irq_2:
push 2
jmp .main
align 4
.irq_3:
push 3
jmp .main
align 4
.irq_4:
push 4
jmp .main
align 4
.irq_5:
push 5
jmp .main
; align 4
; .irq_6:
; push 6
; jmp .main
align 4
.irq_7:
push 7
jmp .main
align 4
.irq_8:
push 8
jmp .main
align 4
.irq_9:
push 9
jmp .main
align 4
.irq_10:
push 10
jmp .main
align 4
.irq_11:
push 11
jmp .main
align 4
.irq_12:
push 12
jmp .main
; align 4
; .irq_13:
; push 13
; jmp .main
; align 4
; .irq_14:
; push 14
; jmp .main
; align 4
; .irq_15:
; push 15
; jmp .main
 
align 16
.main:
save_ring3_context
mov eax, [esp + 32]
mov bx, app_data ;os_data
mov ds, bx
mov es, bx
 
cmp [v86_irqhooks+eax*8], 0
jnz v86_irq
 
mov ebx, [irq_tab+eax*4]
test ebx, ebx
jz .exit
 
call ebx
mov [check_idle_semaphore],5
 
.exit:
 
cmp dword [esp + 32], 8
mov al, 0x20
jb @f
out 0xa0, al
@@:
out 0x20, al
 
restore_ring3_context
add esp, 4
 
iret
 
align 4
proc get_notify stdcall, p_ev:dword
 
.wait:
mov ebx,[current_slot]
test dword [ebx+APPDATA.event_mask],EVENT_NOTIFY
jz @f
and dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY
mov edi, [p_ev]
mov dword [edi], EV_INTR
mov eax, [ebx+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
push ebx
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
pop ebx
ret
endp
 
align 4
proc pci_read16 stdcall, bus:dword, devfn:dword, reg:dword
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 5
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
pop ebx
ret
endp
 
align 4
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
push ebx
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
pop ebx
ret
endp
 
align 4
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
push ebx
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
pop ebx
ret
endp
 
align 4
proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 9
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
pop ebx
ret
endp
 
align 4
proc pci_write32 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
push ebx
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 10
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
pop ebx
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.sizeof
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
 
; param
; ecx= io_control
;
; retval
; eax= error code
 
align 4
srv_handlerEx:
cmp ecx, OS_BASE
jae .fail
 
mov eax, [ecx+handle]
cmp [eax+SRV.magic], ' SRV'
jne .fail
 
cmp [eax+SRV.size], SRV.sizeof
jne .fail
 
stdcall [eax+SRV.srv_proc], ecx
ret
.fail:
or eax, -1
ret
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
align 4
proc get_service stdcall, sz_name:dword
mov eax, [sz_name]
test eax, eax
jnz @F
ret
@@:
mov edx, [srv.fd]
@@:
cmp edx, srv.fd-SRV_FD_OFFSET
je .not_load
 
stdcall strncmp, edx, [sz_name], 16
test eax, eax
je .ok
 
mov edx, [edx+SRV.fd]
jmp @B
.not_load:
pop ebp
jmp load_driver
.ok:
mov eax, edx
ret
endp
 
align 4
proc reg_service stdcall, name:dword, handler:dword
 
push ebx
 
xor eax, eax
 
cmp [name], eax
je .fail
 
cmp [handler], eax
je .fail
 
mov eax, SRV.sizeof
call malloc
test eax, eax
jz .fail
 
push esi
push edi
mov edi, eax
mov esi, [name]
movsd
movsd
movsd
movsd
pop edi
pop esi
 
mov [eax+SRV.magic], ' SRV'
mov [eax+SRV.size], SRV.sizeof
 
mov ebx, srv.fd-SRV_FD_OFFSET
mov edx, [ebx+SRV.fd]
mov [eax+SRV.fd], edx
mov [eax+SRV.bk], ebx
mov [ebx+SRV.fd], eax
mov [edx+SRV.bk], eax
 
mov ecx, [handler]
mov [eax+SRV.srv_proc], ecx
pop ebx
ret
.fail:
xor eax, eax
pop ebx
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 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 eax, [pSym]
mov eax, [eax+8]
ret
endp
 
align 4
proc get_curr_task
mov eax,[CURRENT_TASK]
shl eax, 8
ret
endp
 
align 4
proc get_fileinfo stdcall, file_name:dword, info:dword
locals
cmd dd ?
offset dd ?
dd ?
count dd ?
buff dd ?
db ?
name dd ?
endl
 
xor eax, eax
mov ebx, [file_name]
mov ecx, [info]
 
mov [cmd], 5
mov [offset], eax
mov [offset+4], eax
mov [count], eax
mov [buff], ecx
mov byte [buff+4], al
mov [name], ebx
 
mov eax, 70
lea ebx, [cmd]
int 0x40
ret
endp
 
align 4
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
bytes:dword
locals
cmd dd ?
offset dd ?
dd ?
count dd ?
buff dd ?
db ?
name dd ?
endl
 
xor eax, eax
mov ebx, [file_name]
mov ecx, [off]
mov edx, [bytes]
mov esi, [buffer]
 
mov [cmd], eax
mov [offset], ecx
mov [offset+4], eax
mov [count], edx
mov [buff], esi
mov byte [buff+4], al
mov [name], ebx
 
pushad
lea ebx, [cmd]
call file_system_lfn
popad
ret
endp
 
; description
; allocate kernel memory and loads the specified file
;
; param
; file_name= full path to file
;
; retval
; eax= file image in kernel memory
; ebx= size of file
;
; warging
; You mast call kernel_free() to delete each file
; loaded by the load_file() function
 
align 4
proc load_file stdcall, file_name:dword
locals
attr dd ?
flags dd ?
cr_time dd ?
cr_date dd ?
acc_time dd ?
acc_date dd ?
mod_time dd ?
mod_date dd ?
file_size dd ?
 
file dd ?
file2 dd ?
endl
 
push esi
push edi
 
lea eax, [attr]
stdcall get_fileinfo, [file_name], eax
test eax, eax
jnz .fail
 
mov eax, [file_size]
cmp eax, 1024*1024*16
ja .fail
 
stdcall kernel_alloc, [file_size]
mov [file], eax
test eax, eax
jz .fail
 
stdcall read_file, [file_name], eax, dword 0, [file_size]
cmp ebx, [file_size]
jne .cleanup
 
mov eax, [file]
cmp dword [eax], 0x4B43504B
jne .exit
mov ebx, [eax+4]
mov [file_size], ebx
stdcall kernel_alloc, ebx
 
test eax, eax
jz .cleanup
 
mov [file2], eax
pushfd
cli
stdcall unpack, [file], eax
popfd
stdcall kernel_free, [file]
mov eax, [file2]
mov ebx, [file_size]
.exit:
push eax
lea edi, [eax+ebx] ;cleanup remain space
mov ecx, 4096 ;from file end
and ebx, 4095
jz @f
sub ecx, ebx
xor eax, eax
cld
rep stosb
@@:
mov ebx, [file_size]
pop eax
pop edi
pop esi
ret
.cleanup:
stdcall kernel_free, [file]
.fail:
xor eax, eax
xor ebx, ebx
pop edi
pop esi
ret
endp
 
align 4
proc get_proc_ex stdcall, proc_name:dword, imports:dword
 
.look_up:
mov edx, [imports]
test edx, edx
jz .end
mov edx, [edx]
test edx, edx
jz .end
.next:
mov eax, [edx]
test eax, eax
jz .next_table
 
push edx
stdcall strncmp, eax, [proc_name], 256
pop edx
test eax, eax
jz .ok
 
add edx,8
jmp .next
.next_table:
add [imports], 4
jmp .look_up
.ok:
mov eax, [edx+4]
ret
.end:
xor eax, eax
ret
endp
 
align 4
proc fix_coff_symbols stdcall uses ebx esi, sec:dword, symbols:dword,\
sym_count:dword, strings:dword, imports:dword
locals
retval dd ?
endl
 
mov edi, [symbols]
mov [retval], 1
.fix:
movzx ebx, [edi+CSYM.SectionNumber]
test ebx, ebx
jnz .internal
mov eax, dword [edi+CSYM.Name]
test eax, eax
jnz @F
 
mov edi, [edi+4]
add edi, [strings]
@@:
push edi
stdcall get_proc_ex, edi,[imports]
pop edi
 
xor ebx, ebx
test eax, eax
jnz @F
 
mov esi, msg_unresolved
call sys_msg_board_str
mov esi, edi
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
 
mov [retval],0
@@:
mov edi, [symbols]
mov [edi+CSYM.Value], eax
jmp .next
.internal:
cmp bx, -1
je .next
cmp bx, -2
je .next
 
dec ebx
shl ebx, 3
lea ebx, [ebx+ebx*4]
add ebx, [sec]
 
mov eax, [ebx+CFS.VirtualAddress]
add [edi+CSYM.Value], eax
.next:
add edi, CSYM_SIZE
mov [symbols], edi
dec [sym_count]
jnz .fix
mov eax, [retval]
ret
endp
 
align 4
proc fix_coff_relocs stdcall uses ebx esi, coff:dword, sym:dword, \
delta:dword
locals
n_sec dd ?
endl
 
mov eax, [coff]
movzx ebx, [eax+CFH.nSections]
mov [n_sec], ebx
lea esi, [eax+20]
.fix_sec:
mov edi, [esi+CFS.PtrReloc]
add edi, [coff]
 
movzx ecx, [esi+CFS.NumReloc]
test ecx, ecx
jz .next
.reloc_loop:
mov ebx, [edi+CRELOC.SymIndex]
add ebx,ebx
lea ebx,[ebx+ebx*8]
add ebx, [sym]
 
mov edx, [ebx+CSYM.Value]
 
cmp [edi+CRELOC.Type], 6
je .dir_32
 
cmp [edi+CRELOC.Type], 20
jne .next_reloc
.rel_32:
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
sub edx, eax
sub edx, 4
jmp .fix
.dir_32:
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
.fix:
add eax, [delta]
add [eax], edx
.next_reloc:
add edi, 10
dec ecx
jnz .reloc_loop
.next:
add esi, COFF_SECTION_SIZE
dec [n_sec]
jnz .fix_sec
.exit:
ret
endp
 
proc rebase_coff stdcall uses ebx esi, coff:dword, sym:dword, \
delta:dword
locals
n_sec dd ?
endl
 
mov eax, [coff]
movzx ebx, [eax+CFH.nSections]
mov [n_sec], ebx
lea esi, [eax+20]
mov edx, [delta]
.fix_sec:
mov edi, [esi+CFS.PtrReloc]
add edi, [coff]
 
movzx ecx, [esi+CFS.NumReloc]
test ecx, ecx
jz .next
.reloc_loop:
cmp [edi+CRELOC.Type], 6
jne .next_reloc
.dir_32:
mov eax, [edi+CRELOC.VirtualAddress]
add eax, [esi+CFS.VirtualAddress]
add [eax+edx], edx
.next_reloc:
add edi, 10
dec ecx
jnz .reloc_loop
.next:
add esi, COFF_SECTION_SIZE
dec [n_sec]
jnz .fix_sec
.exit:
ret
endp
 
align 4
proc load_driver stdcall, driver_name:dword
locals
coff dd ?
sym dd ?
strings dd ?
img_size dd ?
img_base dd ?
start dd ?
 
exports dd ? ;fake exports table
dd ?
file_name rb 13+16+4+1 ; '/sys/drivers/<up-to-16-chars>.obj'
endl
 
lea edx, [file_name]
mov dword [edx], '/sys'
mov dword [edx+4], '/dri'
mov dword [edx+8], 'vers'
mov byte [edx+12], '/'
mov esi, [driver_name]
.redo:
lea edx, [file_name]
lea edi, [edx+13]
mov ecx, 16
@@:
lodsb
test al, al
jz @f
stosb
loop @b
@@:
mov dword [edi], '.obj'
mov byte [edi+4], 0
stdcall load_file, edx
 
test eax, eax
jz .exit
 
mov [coff], eax
 
movzx ecx, [eax+CFH.nSections]
xor ebx, ebx
 
lea edx, [eax+20]
@@:
add ebx, [edx+CFS.SizeOfRawData]
add ebx, 15
and ebx, not 15
add edx, COFF_SECTION_SIZE
dec ecx
jnz @B
mov [img_size], ebx
 
stdcall kernel_alloc, ebx
test eax, eax
jz .fail
mov [img_base], eax
 
mov edi, eax
xor eax, eax
mov ecx, [img_size]
add ecx, 4095
and ecx, not 4095
shr ecx, 2
cld
rep stosd
 
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, [img_base]
lea eax, [edx+20]
@@:
mov [eax+CFS.VirtualAddress], edi
mov esi, [eax+CFS.PtrRawData]
test esi, esi
jnz .copy
add edi, [eax+CFS.SizeOfRawData]
jmp .next
.copy:
add esi, edx
mov ecx, [eax+CFS.SizeOfRawData]
cld
rep movsb
.next:
add edi, 15
and edi, not 15
add eax, COFF_SECTION_SIZE
dec ebx
jnz @B
 
mov ebx, [edx+CFH.pSymTable]
add ebx, edx
mov [sym], ebx
mov ecx, [edx+CFH.nSymbols]
add ecx,ecx
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
add ecx, [sym]
mov [strings], ecx
 
lea ebx, [exports]
mov dword [ebx], kernel_export
mov dword [ebx+4], 0
lea eax, [edx+20]
 
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
[strings], ebx
test eax, eax
jz .link_fail
 
mov ebx, [coff]
stdcall fix_coff_relocs, ebx, [sym], 0
 
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szVersion
test eax, eax
jz .link_fail
 
mov eax, [eax]
shr eax, 16
cmp eax, DRV_COMPAT
jb .ver_fail
 
cmp eax, DRV_CURRENT
ja .ver_fail
 
mov ebx, [coff]
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART
mov [start], eax
 
stdcall kernel_free, [coff]
 
mov ebx, [start]
stdcall ebx, DRV_ENTRY
test eax, eax
jnz .ok
 
stdcall kernel_free, [img_base]
cmp dword [file_name+13], 'SOUN'
jnz @f
cmp dword [file_name+17], 'D.ob'
jnz @f
cmp word [file_name+21], 'j'
jnz @f
mov esi, aSis
jmp .redo
@@:
xor eax, eax
ret
.ok:
mov ebx, [img_base]
mov [eax+SRV.base], ebx
mov ecx, [start]
mov [eax+SRV.entry], ecx
ret
 
.ver_fail:
mov esi, msg_CR
call sys_msg_board_str
mov esi, [driver_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
mov esi, msg_version
call sys_msg_board_str
mov esi, msg_www
call sys_msg_board_str
jmp .cleanup
 
.link_fail:
mov esi, msg_module
call sys_msg_board_str
mov esi, [driver_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
.cleanup:
stdcall kernel_free,[img_base]
.fail:
stdcall kernel_free, [coff]
.exit:
xor eax, eax
ret
endp
 
; in: edx -> COFF_SECTION struct
; out: eax = alignment as mask for bits to drop
coff_get_align:
; Rules:
; - if alignment is not given, use default = 4K;
; - if alignment is given and is no more than 4K, use it;
; - if alignment is more than 4K, revert to 4K.
push ecx
mov cl, byte [edx+CFS.Characteristics+2]
mov eax, 1
shr cl, 4
dec cl
js .default
cmp cl, 12
jbe @f
.default:
mov cl, 12
@@:
shl eax, cl
pop ecx
dec eax
ret
 
align 4
proc load_library stdcall, file_name:dword
locals
fullname rb 260
fileinfo rb 40
coff dd ?
img_base dd ?
endl
 
cli
 
; resolve file name
mov ebx, [file_name]
lea edi, [fullname+1]
mov byte [edi-1], '/'
stdcall get_full_file_name, edi, 259
test al, al
jz .fail
 
; scan for required DLL in list of already loaded for this process,
; ignore timestamp
mov esi, [CURRENT_TASK]
shl esi, 8
lea edi, [fullname]
mov ebx, [esi+SLOT_BASE+APPDATA.dlls_list_ptr]
test ebx, ebx
jz .not_in_process
mov esi, [ebx+HDLL.fd]
.scan_in_process:
cmp esi, ebx
jz .not_in_process
mov eax, [esi+HDLL.parent]
add eax, DLLDESCR.name
stdcall strncmp, eax, edi, -1
test eax, eax
jnz .next_in_process
; simple variant: load DLL which is already loaded in this process
; just increment reference counters and return address of exports table
inc [esi+HDLL.refcount]
mov ecx, [esi+HDLL.parent]
inc [ecx+DLLDESCR.refcount]
mov eax, [ecx+DLLDESCR.exports]
sub eax, [ecx+DLLDESCR.defaultbase]
add eax, [esi+HDLL.base]
ret
.next_in_process:
mov esi, [esi+HDLL.fd]
jmp .scan_in_process
.not_in_process:
 
; scan in full list, compare timestamp
lea eax, [fileinfo]
stdcall get_fileinfo, edi, eax
test eax, eax
jnz .fail
mov esi, [dll_list.fd]
.scan_for_dlls:
cmp esi, dll_list
jz .load_new
lea eax, [esi+DLLDESCR.name]
stdcall strncmp, eax, edi, -1
test eax, eax
jnz .continue_scan
.test_prev_dll:
mov eax, dword [fileinfo+24] ; last modified time
mov edx, dword [fileinfo+28] ; last modified date
cmp dword [esi+DLLDESCR.timestamp], eax
jnz .continue_scan
cmp dword [esi+DLLDESCR.timestamp+4], edx
jz .dll_already_loaded
.continue_scan:
mov esi, [esi+DLLDESCR.fd]
jmp .scan_for_dlls
 
; new DLL
.load_new:
; load file
stdcall load_file, edi
test eax, eax
jz .fail
mov [coff], eax
mov dword [fileinfo+32], ebx
 
; allocate DLLDESCR struct; size is DLLDESCR.sizeof plus size of DLL name
mov esi, edi
mov ecx, -1
xor eax, eax
repnz scasb
not ecx
lea eax, [ecx+DLLDESCR.sizeof]
push ecx
call malloc
pop ecx
test eax, eax
jz .fail_and_free_coff
; save timestamp
lea edi, [eax+DLLDESCR.name]
rep movsb
mov esi, eax
mov eax, dword [fileinfo+24]
mov dword [esi+DLLDESCR.timestamp], eax
mov eax, dword [fileinfo+28]
mov dword [esi+DLLDESCR.timestamp+4], eax
; initialize DLLDESCR struct
and dword [esi+DLLDESCR.refcount], 0 ; no HDLLs yet; later it will be incremented
mov [esi+DLLDESCR.fd], dll_list
mov eax, [dll_list.bk]
mov [dll_list.bk], esi
mov [esi+DLLDESCR.bk], eax
mov [eax+DLLDESCR.fd], esi
 
; calculate size of loaded DLL
mov edx, [coff]
movzx ecx, [edx+CFH.nSections]
xor ebx, ebx
 
add edx, 20
@@:
call coff_get_align
add ebx, eax
not eax
and ebx, eax
add ebx, [edx+CFS.SizeOfRawData]
add edx, COFF_SECTION_SIZE
dec ecx
jnz @B
; it must be nonzero and not too big
mov [esi+DLLDESCR.size], ebx
test ebx, ebx
jz .fail_and_free_dll
cmp ebx, MAX_DEFAULT_DLL_ADDR-MIN_DEFAULT_DLL_ADDR
ja .fail_and_free_dll
; allocate memory for kernel-side image
stdcall kernel_alloc, ebx
test eax, eax
jz .fail_and_free_dll
mov [esi+DLLDESCR.data], eax
; calculate preferred base address
add ebx, 0x1FFF
and ebx, not 0xFFF
mov ecx, [dll_cur_addr]
lea edx, [ecx+ebx]
cmp edx, MAX_DEFAULT_DLL_ADDR
jb @f
mov ecx, MIN_DEFAULT_DLL_ADDR
lea edx, [ecx+ebx]
@@:
mov [esi+DLLDESCR.defaultbase], ecx
mov [dll_cur_addr], edx
 
; copy sections and set correct values for VirtualAddress'es in headers
push esi
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, eax
add edx, 20
cld
@@:
call coff_get_align
add ecx, eax
add edi, eax
not eax
and ecx, eax
and edi, eax
mov [edx+CFS.VirtualAddress], ecx
add ecx, [edx+CFS.SizeOfRawData]
mov esi, [edx+CFS.PtrRawData]
push ecx
mov ecx, [edx+CFS.SizeOfRawData]
test esi, esi
jnz .copy
xor eax, eax
rep stosb
jmp .next
.copy:
add esi, [coff]
rep movsb
.next:
pop ecx
add edx, COFF_SECTION_SIZE
dec ebx
jnz @B
pop esi
 
; save some additional data from COFF file
; later we will use COFF header, headers for sections and symbol table
; and also relocations table for all sections
mov edx, [coff]
mov ebx, [edx+CFH.pSymTable]
mov edi, dword [fileinfo+32]
sub edi, ebx
jc .fail_and_free_data
mov [esi+DLLDESCR.symbols_lim], edi
add ebx, edx
movzx ecx, [edx+CFH.nSections]
lea ecx, [ecx*5]
lea edi, [edi+ecx*8+20]
add edx, 20
@@:
movzx eax, [edx+CFS.NumReloc]
lea eax, [eax*5]
lea edi, [edi+eax*2]
add edx, COFF_SECTION_SIZE
sub ecx, 5
jnz @b
stdcall kernel_alloc, edi
test eax, eax
jz .fail_and_free_data
mov edx, [coff]
movzx ecx, [edx+CFH.nSections]
lea ecx, [ecx*5]
lea ecx, [ecx*2+5]
mov [esi+DLLDESCR.coff_hdr], eax
push esi
mov esi, edx
mov edi, eax
rep movsd
pop esi
mov [esi+DLLDESCR.symbols_ptr], edi
push esi
mov ecx, [edx+CFH.nSymbols]
mov [esi+DLLDESCR.symbols_num], ecx
mov ecx, [esi+DLLDESCR.symbols_lim]
mov esi, ebx
rep movsb
pop esi
mov ebx, [esi+DLLDESCR.coff_hdr]
push esi
movzx eax, [edx+CFH.nSections]
lea edx, [ebx+20]
@@:
movzx ecx, [edx+CFS.NumReloc]
lea ecx, [ecx*5]
mov esi, [edx+CFS.PtrReloc]
mov [edx+CFS.PtrReloc], edi
sub [edx+CFS.PtrReloc], ebx
add esi, [coff]
shr ecx, 1
rep movsd
adc ecx, ecx
rep movsw
add edx, COFF_SECTION_SIZE
dec eax
jnz @b
pop esi
 
; fixup symbols
mov edx, ebx
mov eax, [ebx+CFH.nSymbols]
add edx, 20
mov ecx, [esi+DLLDESCR.symbols_num]
lea ecx, [ecx*9]
add ecx, ecx
add ecx, [esi+DLLDESCR.symbols_ptr]
 
stdcall fix_coff_symbols, edx, [esi+DLLDESCR.symbols_ptr], eax,\
ecx, 0
; test eax, eax
; jnz @F
;
;@@:
 
stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],szEXPORTS
test eax, eax
jnz @F
 
stdcall get_coff_sym,[esi+DLLDESCR.symbols_ptr],[ebx+CFH.nSymbols],sz_EXPORTS
@@:
mov [esi+DLLDESCR.exports], eax
 
; fix relocs in the hidden copy in kernel memory to default address
; it is first fix; usually this will be enough, but second fix
; can be necessary if real load address will not equal assumption
mov eax, [esi+DLLDESCR.data]
sub eax, [esi+DLLDESCR.defaultbase]
stdcall fix_coff_relocs, ebx, [esi+DLLDESCR.symbols_ptr], eax
 
stdcall kernel_free, [coff]
 
.dll_already_loaded:
inc [esi+DLLDESCR.refcount]
push esi
call init_heap
pop esi
 
mov edi, [esi+DLLDESCR.size]
stdcall user_alloc_at, [esi+DLLDESCR.defaultbase], edi
test eax, eax
jnz @f
stdcall user_alloc, edi
test eax, eax
jz .fail_and_dereference
@@:
mov [img_base], eax
mov eax, HDLL.sizeof
call malloc
test eax, eax
jz .fail_and_free_user
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov edx, [CURRENT_TASK+ebx+TASKDATA.pid]
mov [eax+HDLL.pid], edx
push eax
call init_dlls_in_thread
pop ebx
test eax, eax
jz .fail_and_free_user
mov edx, [eax+HDLL.fd]
mov [ebx+HDLL.fd], edx
mov [ebx+HDLL.bk], eax
mov [eax+HDLL.fd], ebx
mov [edx+HDLL.bk], ebx
mov eax, ebx
mov ebx, [img_base]
mov [eax+HDLL.base], ebx
mov [eax+HDLL.size], edi
mov [eax+HDLL.refcount], 1
mov [eax+HDLL.parent], esi
mov edx, ebx
shr edx, 12
or dword [page_tabs+(edx-1)*4], DONT_FREE_BLOCK
; copy entries of page table from kernel-side image to usermode
; use copy-on-write for user-mode image, so map as readonly
xor edi, edi
mov ecx, [esi+DLLDESCR.data]
shr ecx, 12
.map_pages_loop:
mov eax, [page_tabs+ecx*4]
and eax, not 0xFFF
or al, PG_USER
xchg eax, [page_tabs+edx*4]
test al, 1
jz @f
call free_page
@@:
invlpg [ebx+edi]
inc ecx
inc edx
add edi, 0x1000
cmp edi, [esi+DLLDESCR.size]
jb .map_pages_loop
 
; if real user-mode base is not equal to preferred base, relocate image
sub ebx, [esi+DLLDESCR.defaultbase]
jz @f
stdcall rebase_coff, [esi+DLLDESCR.coff_hdr], [esi+DLLDESCR.symbols_ptr], ebx
@@:
 
mov eax, [esi+DLLDESCR.exports]
sub eax, [esi+DLLDESCR.defaultbase]
add eax, [img_base]
ret
.fail_and_free_data:
stdcall kernel_free, [esi+DLLDESCR.data]
.fail_and_free_dll:
mov eax, esi
call free
.fail_and_free_coff:
stdcall kernel_free, [coff]
.fail:
xor eax, eax
ret
.fail_and_free_user:
stdcall user_free, [img_base]
.fail_and_dereference:
mov eax, 1 ; delete 1 reference
call dereference_dll
xor eax, eax
ret
endp
 
; initialize [APPDATA.dlls_list_ptr] for given thread
; DLL is per-process object, so APPDATA.dlls_list_ptr must be
; kept in sync for all threads of one process.
; out: eax = APPDATA.dlls_list_ptr if all is OK,
; NULL if memory allocation failed
init_dlls_in_thread:
mov ebx, [current_slot]
mov eax, [ebx+APPDATA.dlls_list_ptr]
test eax, eax
jnz .ret
push [ebx+APPDATA.dir_table]
mov eax, 8
call malloc
pop edx
test eax, eax
jz .ret
mov [eax], eax
mov [eax+4], eax
mov ecx, [TASK_COUNT]
mov ebx, SLOT_BASE+256
.set:
cmp [ebx+APPDATA.dir_table], edx
jnz @f
mov [ebx+APPDATA.dlls_list_ptr], eax
@@:
add ebx, 256
dec ecx
jnz .set
.ret:
ret
 
; in: eax = number of references to delete, esi -> DLLDESCR struc
dereference_dll:
sub [esi+DLLDESCR.refcount], eax
jnz .ret
mov eax, [esi+DLLDESCR.fd]
mov edx, [esi+DLLDESCR.bk]
mov [eax+DLLDESCR.bk], edx
mov [edx+DLLDESCR.fd], eax
stdcall kernel_free, [esi+DLLDESCR.coff_hdr]
stdcall kernel_free, [esi+DLLDESCR.data]
mov eax, esi
call free
.ret:
ret
 
destroy_hdll:
push ebx ecx esi edi
push eax
mov ebx, [eax+HDLL.base]
mov esi, [eax+HDLL.parent]
mov edx, [esi+DLLDESCR.size]
; The following actions require the context of application where HDLL is mapped.
; However, destroy_hdll can be called in the context of OS thread when
; cleaning up objects created by the application which is destroyed.
; So remember current cr3 and set it to page table of target.
mov eax, [ecx+APPDATA.dir_table]
; Because we cheat with cr3, disable interrupts: task switch would restore
; page table from APPDATA of current thread.
; Also set [current_slot] because it is used by user_free.
pushf
cli
push [current_slot]
mov [current_slot], ecx
mov ecx, cr3
push ecx
mov cr3, eax
push ebx ; argument for user_free
mov eax, ebx
shr ebx, 12
push ebx
mov esi, [esi+DLLDESCR.data]
shr esi, 12
.unmap_loop:
push eax
mov eax, 2
xchg eax, [page_tabs+ebx*4]
mov ecx, [page_tabs+esi*4]
and eax, not 0xFFF
and ecx, not 0xFFF
cmp eax, ecx
jz @f
call free_page
@@:
pop eax
invlpg [eax]
add eax, 0x1000
inc ebx
inc esi
sub edx, 0x1000
ja .unmap_loop
pop ebx
and dword [page_tabs+(ebx-1)*4], not DONT_FREE_BLOCK
call user_free
; Restore context.
pop eax
mov cr3, eax
pop [current_slot]
popf
; Ok, cheating is done.
pop eax
push eax
mov esi, [eax+HDLL.parent]
mov eax, [eax+HDLL.refcount]
call dereference_dll
pop eax
mov edx, [eax+HDLL.bk]
mov ebx, [eax+HDLL.fd]
mov [ebx+HDLL.bk], edx
mov [edx+HDLL.fd], ebx
call free
pop edi esi ecx ebx
ret
 
; ecx -> APPDATA for slot, esi = dlls_list_ptr
destroy_all_hdlls:
test esi, esi
jz .ret
.loop:
mov eax, [esi+HDLL.fd]
cmp eax, esi
jz free
call destroy_hdll
jmp .loop
.ret:
ret
 
align 4
stop_all_services:
push ebp
mov edx, [srv.fd]
.next:
cmp edx, srv.fd-SRV_FD_OFFSET
je .done
cmp [edx+SRV.magic], ' SRV'
jne .next
cmp [edx+SRV.size], SRV.sizeof
jne .next
 
mov ebx, [edx+SRV.entry]
mov edx, [edx+SRV.fd]
test ebx, ebx
jz .next
 
push edx
mov ebp, esp
push 0
push -1
call ebx
mov esp, ebp
pop edx
jmp .next
.done:
pop ebp
ret
 
; param
; eax= size
; ebx= pid
 
align 4
create_kernel_object:
 
push ebx
call malloc
pop ebx
test eax, eax
jz .fail
 
mov ecx,[current_slot]
add ecx, APP_OBJ_OFFSET
 
pushfd
cli
mov edx, [ecx+APPOBJ.fd]
mov [eax+APPOBJ.fd], edx
mov [eax+APPOBJ.bk], ecx
mov [eax+APPOBJ.pid], ebx
 
mov [ecx+APPOBJ.fd], eax
mov [edx+APPOBJ.bk], eax
popfd
.fail:
ret
 
; param
; eax= object
 
align 4
destroy_kernel_object:
 
pushfd
cli
mov ebx, [eax+APPOBJ.fd]
mov ecx, [eax+APPOBJ.bk]
mov [ebx+APPOBJ.bk], ecx
mov [ecx+APPOBJ.fd], ebx
popfd
 
xor edx, edx ;clear common header
mov [eax], edx
mov [eax+4], edx
mov [eax+8], edx
mov [eax+12], edx
mov [eax+16], edx
 
call free ;release object memory
ret
 
 
 
if 0
 
irq:
 
.irq0:
pusfd
pushad
push IRQ_0
jmp .master
.irq_1:
pusfd
pushad
push IRQ_1
jmp .master
 
.master:
mov ax, app_data
mov ds, eax
mov es, eax
mov ebx, [esp+4] ;IRQ_xx
mov eax, [irq_handlers+ebx+4]
call intr_handler
mov ecx, [esp+4]
cmp [irq_actids+ecx*4], 0
je @F
in al, 0x21
bts eax, ecx
out 0x21, al
mov al, 0x20
out 0x20, al
jmp .restart
 
.slave:
mov ax, app_data
mov ds, eax
mov es, eax
mov ebx, [esp+4] ;IRQ_xx
mov eax, [irq_handlers+ebx+4]
call intr_handler
mov ecx, [esp+4]
sub ecx, 8
cmp [irq_actids+ecx*4], 0
je @F
in al, 0xA1
bts eax, ecx
out 0xA1, al
mov al, 0x20
out 0xA0, al
out 0x20, al
.restart:
mov ebx, [next_slot]
test ebx, ebx
jz @F
mov [next_task],0
mov esi, [prev_slot]
call do_change_task
add esp, 4
iretd
 
end if
 
 
 
 
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/v86.inc
0,0 → 1,935
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2007-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
; Virtual-8086 mode manager
; diamond, 2007, 2008
 
DEBUG_SHOW_IO = 0
 
struc V86_machine
{
; page directory
.pagedir dd ?
; translation table: V86 address -> flat linear address
.pages dd ?
; mutex to protect all data from writing by multiple threads at one time
.mutex dd ?
; i/o permission map
.iopm dd ?
.size = $
}
virtual at 0
V86_machine V86_machine
end virtual
 
; Create V86 machine
; in: nothing
; out: eax = handle (pointer to struc V86_machine)
; eax = NULL => failure
; destroys: ebx, ecx, edx (due to malloc)
v86_create:
; allocate V86_machine structure
mov eax, V86_machine.size
call malloc
test eax, eax
jz .fail
; initialize mutex
and dword [eax+V86_machine.mutex], 0
; allocate tables
mov ebx, eax
; We allocate 4 pages.
; First is main page directory for V86 mode.
; Second page:
; first half (0x800 bytes) is page table for addresses 0 - 0x100000,
; second half is for V86-to-linear translation.
; Third and fourth are for I/O permission map.
push 8000h ; blocks less than 8 pages are discontinuous
call kernel_alloc
test eax, eax
jz .fail2
mov [ebx+V86_machine.pagedir], eax
push edi eax
mov edi, eax
add eax, 1800h
mov [ebx+V86_machine.pages], eax
; initialize tables
mov ecx, 2000h/4
xor eax, eax
rep stosd
mov [ebx+V86_machine.iopm], edi
dec eax
mov ecx, 2000h/4
rep stosd
pop eax
; page directory: first entry is page table...
mov edi, eax
add eax, 1000h
push eax
call get_pg_addr
or al, PG_UW
stosd
; ...and also copy system page tables
; thx to Serge, system is located at high addresses
add edi, (OS_BASE shr 20) - 4
push esi
mov esi, (OS_BASE shr 20) + sys_pgdir
mov ecx, 0x80000000 shr 22
rep movsd
 
mov eax, [ebx+V86_machine.pagedir] ;root dir also is
call get_pg_addr ;used as page table
or al, PG_SW
mov [edi-4096+(page_tabs shr 20)], eax
 
pop esi
; now V86 specific: initialize known addresses in first Mb
pop eax
; first page - BIOS data (shared between all machines!)
; physical address = 0
; linear address = OS_BASE
mov dword [eax], 111b
mov dword [eax+800h], OS_BASE
; page before 0xA0000 - Extended BIOS Data Area (shared between all machines!)
; physical address = 0x9C000
; linear address = 0x8009C000
; (I have seen one computer with EBDA segment = 0x9D80,
; all other computers use less memory)
mov ecx, 4
mov edx, 0x9C000
push eax
lea edi, [eax+0x9C*4]
@@:
lea eax, [edx + OS_BASE]
mov [edi+800h], eax
lea eax, [edx + 111b]
stosd
add edx, 0x1000
loop @b
pop eax
pop edi
; addresses 0xC0000 - 0xFFFFF - BIOS code (shared between all machines!)
; physical address = 0xC0000
; linear address = 0x800C0000
mov ecx, 0xC0
@@:
mov edx, ecx
shl edx, 12
push edx
or edx, 111b
mov [eax+ecx*4], edx
pop edx
add edx, OS_BASE
mov [eax+ecx*4+0x800], edx
inc cl
jnz @b
mov eax, ebx
ret
.fail2:
mov eax, ebx
call free
.fail:
xor eax, eax
ret
 
; Destroy V86 machine
; in: eax = handle
; out: nothing
; destroys: eax, ebx, ecx, edx (due to free)
v86_destroy:
push eax
stdcall kernel_free, [eax+V86_machine.pagedir]
pop eax
jmp free
 
; Translate V86-address to linear address
; in: eax=V86 address
; esi=handle
; out: eax=linear address
; destroys: nothing
v86_get_lin_addr:
push ecx edx
mov ecx, eax
mov edx, [esi+V86_machine.pages]
shr ecx, 12
and eax, 0xFFF
add eax, [edx+ecx*4] ; atomic operation, no mutex needed
pop edx ecx
ret
 
; Sets linear address for V86-page
; in: eax=linear address (must be page-aligned)
; ecx=V86 page (NOT address!)
; esi=handle
; out: nothing
; destroys: nothing
v86_set_page:
push eax ebx
mov ebx, [esi+V86_machine.pagedir]
mov [ebx+ecx*4+0x1800], eax
call get_pg_addr
or al, 111b
mov [ebx+ecx*4+0x1000], eax
pop ebx eax
ret
 
; Allocate memory in V86 machine
; in: eax=size (in bytes)
; esi=handle
; out: eax=V86 address, para-aligned (0x10 multiple)
; destroys: nothing
; ­¥¤®¯¨á ­ !!!
;v86_alloc:
; push ebx ecx edx edi
; lea ebx, [esi+V86_machine.mutex]
; call wait_mutex
; add eax, 0x1F
; shr eax, 4
; mov ebx, 0x1000 ; start with address 0x1000 (second page)
; mov edi, [esi+V86_machine.tables]
;.l:
; mov ecx, ebx
; shr ecx, 12
; mov edx, [edi+0x1000+ecx*4] ; get linear address
; test edx, edx ; page allocated?
; jz .unalloc
; mov ecx, ebx
; and ecx, 0xFFF
; add edx, ecx
; cmp dword [edx], 0 ; free block?
; jnz .n
; cmp dword [edx+4],
; and [esi+V86_machine.mutex], 0
; pop edi edx ecx ebx
; ret
 
uglobal
sys_v86_machine dd ?
endg
 
; Called from kernel.asm at first stages of loading
; Initialize system V86 machine (used to simulate BIOS int 13h)
init_sys_v86:
call v86_create
mov [sys_v86_machine], eax
test eax, eax
jz .ret
mov byte [OS_BASE + 0x500], 0xCD
mov byte [OS_BASE + 0x501], 0x13
mov byte [OS_BASE + 0x502], 0xF4
mov byte [OS_BASE + 0x503], 0xCD
mov byte [OS_BASE + 0x504], 0x10
mov byte [OS_BASE + 0x505], 0xF4
mov esi, eax
mov ebx, [eax+V86_machine.pagedir]
; one page for stack, two pages for results (0x2000 bytes = 16 sectors)
mov dword [ebx+0x99*4+0x1000], 0x99000 or 111b
mov dword [ebx+0x99*4+0x1800], OS_BASE + 0x99000
mov dword [ebx+0x9A*4+0x1000], 0x9A000 or 111b
mov dword [ebx+0x9A*4+0x1800], OS_BASE + 0x9A000
mov dword [ebx+0x9B*4+0x1000], 0x9B000 or 111b
mov dword [ebx+0x9B*4+0x1800], OS_BASE + 0x9B000
if ~DEBUG_SHOW_IO
; allow access to all ports
mov ecx, [esi+V86_machine.iopm]
xor eax, eax
mov edi, ecx
mov ecx, 10000h/8/4
rep stosd
end if
.ret:
ret
 
struc v86_regs
{
; don't change the order, it is important
.edi dd ?
.esi dd ?
.ebp dd ?
dd ? ; ignored
.ebx dd ?
.edx dd ?
.ecx dd ?
.eax dd ?
.eip dd ?
.cs dd ?
.eflags dd ? ; VM flag must be set!
.esp dd ?
.ss dd ?
.es dd ?
.ds dd ?
.fs dd ?
.gs dd ?
.size = $
}
virtual at 0
v86_regs v86_regs
end virtual
 
; Run V86 machine
; in: ebx -> registers for V86 (two structures: in and out)
; esi = handle
; ecx = expected end address (CS:IP)
; edx = IRQ to hook or -1 if not required
; out: structure pointed to by ebx is filled with new values
; eax = 1 - exception has occured, cl contains code
; eax = 2 - access to disabled i/o port, ecx contains port address
; eax = 3 - IRQ is already hooked by another VM
; destroys: nothing
v86_start:
pushad
 
cli
 
mov ecx, [CURRENT_TASK]
shl ecx, 8
add ecx, SLOT_BASE
 
mov eax, [esi+V86_machine.iopm]
call get_pg_addr
inc eax
push dword [ecx+APPDATA.io_map]
push dword [ecx+APPDATA.io_map+4]
mov dword [ecx+APPDATA.io_map], eax
mov dword [page_tabs + (tss._io_map_0 shr 10)], eax
add eax, 0x1000
mov dword [ecx+APPDATA.io_map+4], eax
mov dword [page_tabs + (tss._io_map_1 shr 10)], eax
 
push [ecx+APPDATA.dir_table]
push [ecx+APPDATA.saved_esp0]
mov [ecx+APPDATA.saved_esp0], esp
mov [tss._esp0], esp
 
mov eax, [esi+V86_machine.pagedir]
call get_pg_addr
mov [ecx+APPDATA.dir_table], eax
mov cr3, eax
 
; mov [irq_tab+5*4], my05
 
; We do not enable interrupts, because V86 IRQ redirector assumes that
; machine is running
; They will be enabled by IRET.
; sti
 
mov eax, esi
sub esp, v86_regs.size
mov esi, ebx
mov edi, esp
mov ecx, v86_regs.size/4
rep movsd
 
cmp edx, -1
jz .noirqhook
uglobal
v86_irqhooks rd 16*2
endg
cmp [v86_irqhooks+edx*8], 0
jz @f
cmp [v86_irqhooks+edx*8], eax
jz @f
mov esi, v86_irqerr
call sys_msg_board_str
inc [v86_irqhooks+edx*8+4]
mov eax, 3
jmp v86_exc_c.exit
@@:
mov [v86_irqhooks+edx*8], eax
inc [v86_irqhooks+edx*8+4]
.noirqhook:
 
popad
iretd
 
; It is only possible to leave virtual-8086 mode by faulting to
; a protected-mode interrupt handler (typically the general-protection
; exception handler, which in turn calls the virtual 8086-mode monitor).
 
iglobal
v86_exc_str1 db 'V86 : unexpected exception ',0
v86_exc_str2 db ' at ',0
v86_exc_str3 db ':',0
v86_exc_str4 db 13,10,'V86 : faulted code:',0
v86_exc_str5 db ' (unavailable)',0
v86_newline db 13,10,0
v86_io_str1 db 'V86 : access to disabled i/o port ',0
v86_io_byte db ' (byte)',13,10,0
v86_io_word db ' (word)',13,10,0
v86_io_dword db ' (dword)',13,10,0
v86_irqerr db 'V86 : IRQ already hooked',13,10,0
endg
 
v86_exc_c:
; Did we all that we have wanted to do?
cmp bl,1
jne @f
xor eax, eax
mov dr6, eax
@@: mov eax, [esp+v86_regs.size+10h+18h]
cmp word [esp+v86_regs.eip], ax
jnz @f
shr eax, 16
cmp word [esp+v86_regs.cs], ax
jz .done
@@:
; Various system events, which must be handled, result in #GP
cmp bl, 13
jnz .nogp
; If faulted EIP exceeds 0xFFFF, we have #GP and it is an error
cmp word [esp+v86_regs.eip+2], 0
jnz .nogp
; Otherwise we can safely access byte at CS:IP
; (because it is #GP, not #PF handler)
; …᫨ ¡ë ¬ë ¬®£«¨ áå«®¯®â âì ¨áª«î祭¨¥ ⮫쪮 ¨§-§  ç⥭¨ï ¡ ©â®¢ ª®¤ ,
; ¬ë ¡ë ¥£® 㦥 áå«®¯®â «¨ ¨ íâ® ¡ë«® ¡ë ­¥ #GP
movzx esi, word [esp+v86_regs.cs]
shl esi, 4
add esi, [esp+v86_regs.eip]
lodsb
cmp al, 0xCD ; int xx command = CD xx
jz .handle_int
cmp al, 0xCF
jz .handle_iret
cmp al, 0xF3
jz .handle_rep
cmp al, 0xEC
jz .handle_in
cmp al, 0xED
jz .handle_in_word
cmp al, 0xEE
jz .handle_out
cmp al, 0xEF
jz .handle_out_word
cmp al, 0xE4
jz .handle_in_imm
cmp al, 0xE6
jz .handle_out_imm
cmp al, 0x9C
jz .handle_pushf
cmp al, 0x9D
jz .handle_popf
cmp al, 0xFA
jz .handle_cli
cmp al, 0xFB
jz .handle_sti
cmp al, 0x66
jz .handle_66
jmp .nogp
.handle_int:
cmp word [esp+v86_regs.eip], 0xFFFF
jae .nogp
xor eax, eax
lodsb
; call sys_msg_board_byte
; simulate INT command
; N.B. It is possible that some checks need to be corrected,
; but at least in case of normal execution the code works.
.simulate_int:
cmp word [esp+v86_regs.esp], 6
jae @f
mov bl, 12 ; #SS exception
jmp .nogp
@@:
movzx edx, word [esp+v86_regs.ss]
shl edx, 4
push eax
movzx eax, word [esp+4+v86_regs.esp]
sub eax, 6
add edx, eax
mov eax, edx
mov esi, [esp+4+v86_regs.size+10h+4]
call v86_get_lin_addr
cmp eax, 0x1000
jae @f
mov bl, 14 ; #PF exception
jmp .nogp
@@:
lea eax, [edx+5]
call v86_get_lin_addr
cmp eax, 0x1000
jae @f
mov bl, 14 ; #PF exception
jmp .nogp
@@:
sub word [esp+4+v86_regs.esp], 6
mov eax, [esp+4+v86_regs.eip]
cmp byte [esp+1], 0
jnz @f
inc eax
inc eax
@@:
mov word [edx], ax
mov eax, [esp+4+v86_regs.cs]
mov word [edx+2], ax
mov eax, [esp+4+v86_regs.eflags]
mov word [edx+4], ax
pop eax
mov ah, 0
mov cx, [eax*4]
mov word [esp+v86_regs.eip], cx
mov cx, [eax*4+2]
mov word [esp+v86_regs.cs], cx
; note that interrupts will be disabled globally at IRET
and byte [esp+v86_regs.eflags+1], not 3 ; clear IF and TF flags
; continue V86 execution
popad
iretd
.handle_iret:
cmp word [esp+v86_regs.esp], 0x10000 - 6
jbe @f
mov bl, 12
jmp .nogp
@@:
movzx edx, word [esp+v86_regs.ss]
shl edx, 4
movzx eax, word [esp+v86_regs.esp]
add edx, eax
mov eax, edx
mov esi, [esp+v86_regs.size+10h+4]
call v86_get_lin_addr
cmp eax, 0x1000
jae @f
mov bl, 14
jmp .nogp
@@:
lea eax, [edx+5]
call v86_get_lin_addr
cmp eax, 0x1000
jae @f
mov bl, 14
jmp .nogp
@@:
mov ax, [edx]
mov word [esp+v86_regs.eip], ax
mov ax, [edx+2]
mov word [esp+v86_regs.cs], ax
mov ax, [edx+4]
mov word [esp+v86_regs.eflags], ax
add word [esp+v86_regs.esp], 6
popad
iretd
.handle_pushf:
cmp word [esp+v86_regs.esp], 1
jnz @f
mov bl, 12
jmp .nogp
@@:
movzx edx, word [esp+v86_regs.ss]
shl edx, 4
mov eax, [esp+v86_regs.esp]
sub eax, 2
movzx eax, ax
add edx, eax
mov eax, edx
mov esi, [esp+v86_regs.size+10h+4]
call v86_get_lin_addr
cmp eax, 0x1000
jae @f
mov bl, 14 ; #PF exception
jmp .nogp
@@:
lea eax, [edx+1]
call v86_get_lin_addr
cmp eax, 0x1000
jae @f
mov bl, 14
jmp .nogp
@@:
sub word [esp+v86_regs.esp], 2
mov eax, [esp+v86_regs.eflags]
mov [edx], ax
inc word [esp+v86_regs.eip]
popad
iretd
.handle_pushfd:
cmp word [esp+v86_regs.esp], 4
jae @f
mov bl, 12 ; #SS exception
jmp .nogp
@@:
movzx edx, word [esp+v86_regs.ss]
shl edx, 4
movzx eax, word [esp+v86_regs.esp]
sub eax, 4
add edx, eax
mov eax, edx
mov esi, [esp+v86_regs.size+10h+4]
call v86_get_lin_addr
cmp eax, 0x1000
jae @f
mov bl, 14 ; #PF exception
jmp .nogp
@@:
lea eax, [edx+3]
call v86_get_lin_addr
cmp eax, 0x1000
jae @f
mov bl, 14 ; #PF exception
jmp .nogp
@@:
sub word [esp+v86_regs.esp], 4
movzx eax, word [esp+v86_regs.eflags]
mov [edx], eax
add word [esp+v86_regs.eip], 2
popad
iretd
.handle_popf:
cmp word [esp+v86_regs.esp], 0xFFFF
jnz @f
mov bl, 12
jmp .nogp
@@:
movzx edx, word [esp+v86_regs.ss]
shl edx, 4
movzx eax, word [esp+v86_regs.esp]
add edx, eax
mov eax, edx
mov esi, [esp+v86_regs.size+10h+4]
call v86_get_lin_addr
cmp eax, 0x1000
jae @f
mov bl, 14 ; #PF exception
jmp .nogp
@@:
lea eax, [edx+1]
call v86_get_lin_addr
cmp eax, 0x1000
jae @f
mov bl, 14
jmp .nogp
@@:
mov ax, [edx]
mov word [esp+v86_regs.eflags], ax
add word [esp+v86_regs.esp], 2
inc word [esp+v86_regs.eip]
popad
iretd
.handle_popfd:
cmp word [esp+v86_regs.esp], 0x10000 - 4
jbe @f
mov bl, 12
jmp .nogp
@@:
movzx edx, word [esp+v86_regs.ss]
shl edx, 4
movzx eax, word [esp+v86_regs.esp]
add edx, eax
mov eax, edx
mov esi, [esp+v86_regs.size+10h+4]
call v86_get_lin_addr
cmp eax, 0x1000
jae @f
mov bl, 14
jmp .nogp
@@:
lea eax, [edx+3]
call v86_get_lin_addr
cmp eax, 0x1000
jae @f
mov bl, 14
jmp .nogp
@@:
mov eax, [edx]
mov word [esp+v86_regs.eflags], ax
add word [esp+v86_regs.esp], 4
add word [esp+v86_regs.eip], 2
popad
iretd
.handle_cli:
and byte [esp+v86_regs.eflags+1], not 2
inc word [esp+v86_regs.eip]
popad
iretd
.handle_sti:
or byte [esp+v86_regs.eflags+1], 2
inc word [esp+v86_regs.eip]
popad
iretd
.handle_rep:
cmp word [esp+v86_regs.eip], 0xFFFF
jae .nogp
lodsb
cmp al, 6Eh
jz .handle_rep_outsb
jmp .nogp
.handle_rep_outsb:
.handle_in:
.handle_out:
.invalid_io_byte:
movzx ebx, word [esp+v86_regs.edx]
mov ecx, 1
jmp .invalid_io
.handle_in_imm:
.handle_out_imm:
cmp word [esp+v86_regs.eip], 0xFFFF
jae .nogp
lodsb
movzx ebx, al
mov ecx, 1
jmp .invalid_io
.handle_66:
cmp word [esp+v86_regs.eip], 0xFFFF
jae .nogp
lodsb
cmp al, 0x9C
jz .handle_pushfd
cmp al, 0x9D
jz .handle_popfd
cmp al, 0xEF
jz .handle_out_dword
cmp al, 0xED
jz .handle_in_dword
jmp .nogp
.handle_in_word:
.handle_out_word:
movzx ebx, word [esp+v86_regs.edx]
mov ecx, 2
jmp .invalid_io
.handle_in_dword:
.handle_out_dword:
.invalid_io_dword:
movzx ebx, word [esp+v86_regs.edx]
mov ecx, 4
.invalid_io:
mov esi, v86_io_str1
call sys_msg_board_str
mov eax, ebx
call sys_msg_board_dword
mov esi, v86_io_byte
cmp ecx, 1
jz @f
mov esi, v86_io_word
cmp ecx, 2
jz @f
mov esi, v86_io_dword
@@:
call sys_msg_board_str
if DEBUG_SHOW_IO
mov edx, ebx
mov ebx, 200
call delay_hs
mov esi, [esp+v86_regs.size+10h+4]
mov eax, [esi+V86_machine.iopm]
@@:
btr [eax], edx
inc edx
loop @b
popad
iretd
else
mov eax, 2
jmp .exit
end if
.nogp:
 
mov esi, v86_exc_str1
call sys_msg_board_str
mov al, bl
call sys_msg_board_byte
mov esi, v86_exc_str2
call sys_msg_board_str
mov ax, [esp+32+4]
call sys_msg_board_word
mov esi, v86_exc_str3
call sys_msg_board_str
mov ax, [esp+32]
call sys_msg_board_word
mov esi, v86_exc_str4
call sys_msg_board_str
mov ecx, 8
movzx edx, word [esp+32+4]
shl edx, 4
add edx, [esp+32]
@@:
mov esi, [esp+v86_regs.size+10h+4]
mov eax, edx
call v86_get_lin_addr
cmp eax, 0x1000
jb .nopage
mov esi, v86_exc_str3-2
call sys_msg_board_str
mov al, [edx]
call sys_msg_board_byte
inc edx
loop @b
jmp @f
.nopage:
mov esi, v86_exc_str5
call sys_msg_board_str
@@:
mov esi, v86_newline
call sys_msg_board_str
mov eax, 1
jmp .exit
 
.done:
xor eax, eax
 
.exit:
mov [esp+v86_regs.size+10h+1Ch], eax
mov [esp+v86_regs.size+10h+18h], ebx
 
mov edx, [esp+v86_regs.size+10h+14h]
cmp edx, -1
jz @f
dec [v86_irqhooks+edx*8+4]
jnz @f
and [v86_irqhooks+edx*8], 0
@@:
 
mov esi, esp
mov edi, [esi+v86_regs.size+10h+10h]
add edi, v86_regs.size
mov ecx, v86_regs.size/4
rep movsd
mov esp, esi
 
cli
mov ecx, [CURRENT_TASK]
shl ecx, 8
pop eax
mov [SLOT_BASE+ecx+APPDATA.saved_esp0], eax
mov [tss._esp0], eax
pop eax
mov [SLOT_BASE+ecx+APPDATA.dir_table], eax
pop ebx
mov dword [SLOT_BASE+ecx+APPDATA.io_map+4], ebx
mov dword [page_tabs + (tss._io_map_1 shr 10)], ebx
pop ebx
mov dword [SLOT_BASE+ecx+APPDATA.io_map], ebx
mov dword [page_tabs + (tss._io_map_0 shr 10)], ebx
mov cr3, eax
; mov [irq_tab+5*4], 0
sti
 
popad
ret
 
;my05:
; mov dx, 30C2h
; mov cx, 4
;.0:
; in al, dx
; cmp al, 0FFh
; jz @f
; test al, 4
; jnz .1
;@@:
; add dx, 8
; in al, dx
; cmp al, 0FFh
; jz @f
; test al, 4
; jnz .1
;@@:
; loop .0
; ret
;.1:
; or al, 84h
; out dx, al
;.2:
; mov dx, 30F7h
; in al, dx
; mov byte [BOOT_VAR + 48Eh], 0FFh
; ret
 
v86_irq:
; push irq/pushad/jmp v86_irq
; eax = irq
lea esi, [esp+1Ch]
lea edi, [esi+4]
mov ecx, 8
std
rep movsd
cld
mov edi, eax
pop eax
v86_irq2:
mov esi, [v86_irqhooks+edi*8] ; get VM handle
mov eax, [esi+V86_machine.pagedir]
call get_pg_addr
mov ecx, [CURRENT_TASK]
shl ecx, 8
cmp [SLOT_BASE+ecx+APPDATA.dir_table], eax
jnz .notcurrent
lea eax, [edi+8]
cmp al, 10h
mov ah, 1
jb @f
add al, 60h
@@:
jmp v86_exc_c.simulate_int
.notcurrent:
mov ebx, SLOT_BASE + 0x100
mov ecx, [TASK_COUNT]
.scan:
cmp [ebx+APPDATA.dir_table], eax
jnz .cont
push ecx
mov ecx, [ebx+APPDATA.saved_esp0]
cmp word [ecx-v86_regs.size+v86_regs.esp], 6
jb .cont2
movzx edx, word [ecx-v86_regs.size+v86_regs.ss]
shl edx, 4
push eax
movzx eax, word [ecx-v86_regs.size+v86_regs.esp]
sub eax, 6
add edx, eax
mov eax, edx
call v86_get_lin_addr
cmp eax, 0x1000
jb .cont3
lea eax, [edx+5]
call v86_get_lin_addr
cmp eax, 0x1000
jb .cont3
pop eax
pop ecx
jmp .found
.cont3:
pop eax
.cont2:
pop ecx
.cont:
loop .scan
mov al, 20h
out 20h, al
cmp edi, 8
jb @f
out 0A0h, al
@@:
popad
iretd
.found:
mov cr3, eax
sub word [esi-v86_regs.size+v86_regs.esp], 6
mov ecx, [esi-v86_regs.size+v86_regs.eip]
mov word [edx], cx
mov ecx, [esi-v86_regs.size+v86_regs.cs]
mov word [edx+2], cx
mov ecx, [esi-v86_regs.size+v86_regs.eflags]
mov word [edx+4], cx
lea eax, [edi+8]
cmp al, 10h
jb @f
add al, 60h
@@:
mov cx, [eax*4]
mov word [esi-v86_regs.size+v86_regs.eip], cx
mov cx, [eax*4+2]
mov word [esi-v86_regs.size+v86_regs.cs], cx
and byte [esi-v86_regs.size+v86_regs.eflags+1], not 3
call update_counters
lea edi, [ebx + 0x100000000 - SLOT_BASE]
shr edi, 3
add edi, TASK_DATA
call find_next_task.found
call do_change_task
popad
iretd
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/sched.inc
0,0 → 1,412
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
align 32
irq0:
pushad
Mov ds, ax, app_data
mov es, ax
inc [timer_ticks]
mov eax, [timer_ticks]
call playNote ; <<<--- Speaker driver
sub eax,[next_usage_update]
cmp eax,100
jb .nocounter
add [next_usage_update],100
call updatecputimes
.nocounter:
mov al,0x20 ; send End Of Interrupt signal
out 0x20,al
btr dword[DONT_SWITCH], 0
jc .return
call find_next_task
jz .return ; if there is only one running process
call do_change_task
.return:
popad
iretd
 
align 4
change_task:
pushfd
cli
pushad
if 0
; \begin{Mario79} ; <- must be refractoried, if used...
cmp [dma_task_switched], 1
jne .find_next_task
mov [dma_task_switched], 0
mov ebx, [dma_process]
cmp [CURRENT_TASK], ebx
je .return
mov edi, [dma_slot_ptr]
mov [CURRENT_TASK], ebx
mov [TASK_BASE], edi
jmp @f
.find_next_task:
; \end{Mario79}
end if
call find_next_task
jz .return ; the same task -> skip switch
@@: mov byte[DONT_SWITCH], 1
call do_change_task
.return:
popad
popfd
ret
 
uglobal
align 4
; far_jump:
; .offs dd ?
; .sel dw ?
context_counter dd 0 ;noname & halyavin
next_usage_update dd 0
timer_ticks dd 0
; prev_slot dd ?
; event_sched dd ?
endg
 
align 4
update_counters:
mov edi, [TASK_BASE]
rdtsc
sub eax, [edi+TASKDATA.counter_add] ; time stamp counter add
add [edi+TASKDATA.counter_sum], eax ; counter sum
ret
align 4
updatecputimes:
xor eax,eax
xchg eax,[idleuse]
mov [idleusesec],eax
mov ecx, [TASK_COUNT]
mov edi, TASK_DATA
.newupdate:
xor eax,eax
xchg eax,[edi+TASKDATA.counter_sum]
mov [edi+TASKDATA.cpu_usage],eax
add edi,0x20
loop .newupdate
ret
 
align 4
find_next_task:
;info:
; Find next task to execute
;retval:
; ebx = address of the APPDATA for the selected task (slot-base)
; esi = previous slot-base ([current_slot] at the begin)
; edi = address of the TASKDATA for the selected task
; ZF = 1 if the task is the same
;warning:
; [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result
; [current_slot] is not set to new value (ebx)!!!
;scratched: eax,ecx
call update_counters ; edi := [TASK_BASE]
Mov esi, ebx, [current_slot]
.loop:
cmp bh,[TASK_COUNT]
jb @f
xor bh, bh
mov edi,CURRENT_TASK
@@: inc bh ; ebx += APPDATA.size
add edi,0x20 ; edi += TASKDATA.size
mov al, [edi+TASKDATA.state]
test al, al
jz .found ; state == 0
cmp al, 5
jne .loop ; state == 1,2,3,4,9
; state == 5
pushad ; more freedom for [APPDATA.wait_test]
call [ebx+APPDATA.wait_test]
mov [esp+28],eax
popad
or eax,eax
jnz @f
; testing for timeout
mov ecx, [timer_ticks]
sub ecx, [ebx+APPDATA.wait_begin]
cmp ecx, [ebx+APPDATA.wait_timeout]
jb .loop
@@: mov [ebx+APPDATA.wait_param], eax ; retval for wait
mov [edi+TASKDATA.state], 0
.found:
mov [CURRENT_TASK],bh
mov [TASK_BASE],edi
rdtsc ;call _rdtsc
mov [edi+TASKDATA.counter_add],eax ; for next using update_counters
cmp ebx, esi ;esi - previous slot-base
ret
;TODO: Íàäî áû óáðàòü èñïîëüçîâàíèå do_change_task èç V86...
; è ïîñëå ýòîãî ïåðåíåñòè îáðàáîòêó TASKDATA.counter_add/sum â do_change_task
 
align 4
do_change_task:
;param:
; ebx = address of the APPDATA for incoming task (new)
;warning:
; [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task)
; [current_slot] is the outcoming (old), and set here to a new value (ebx)
;scratched: eax,ecx,esi
mov esi,ebx
xchg esi,[current_slot]
; set new stack after saving old
mov [esi+APPDATA.saved_esp], esp
mov esp, [ebx+APPDATA.saved_esp]
; set new thread io-map
Mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)],eax,[ebx+APPDATA.io_map]
Mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)],eax,[ebx+APPDATA.io_map+4]
; set new thread memory-map
mov ecx, APPDATA.dir_table
mov eax, [ebx+ecx] ;offset>0x7F
cmp eax, [esi+ecx] ;offset>0x7F
je @f
mov cr3, eax
@@:
; set tss.esp0
 
Mov [tss._esp0],eax,[ebx+APPDATA.saved_esp0]
 
mov edx, [ebx+APPDATA.tls_base]
cmp edx, [esi+APPDATA.tls_base]
je @f
 
mov [tls_data_l+2],dx
shr edx,16
mov [tls_data_l+4],dl
mov [tls_data_l+7],dh
 
mov dx, app_tls
mov fs, dx
@@:
; set gs selector unconditionally
Mov gs,ax,graph_data
; set CR0.TS
cmp bh, byte[fpu_owner] ;bh == incoming task (new)
clts ;clear a task switch flag
je @f
mov eax, cr0 ;and set it again if the owner
or eax, CR0_TS ;of a fpu has changed
mov cr0, eax
@@: ; set context_counter (only for user pleasure ???)
inc [context_counter] ;noname & halyavin
; set debug-registers, if it's necessary
test byte[ebx+APPDATA.dbg_state], 1
jz @f
xor eax, eax
mov dr6, eax
lea esi,[ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table] ;offset>0x7F
cld
macro lodsReg [reg] {
lodsd
mov reg,eax
} lodsReg dr0, dr1, dr2, dr3, dr7
purge lodsReg
@@: ret
;end.
 
 
 
struc MUTEX_WAITER
{
.next rd 1
.prev rd 1
.task rd 1
.sizeof:
};
 
virtual at 0
MUTEX_WAITER MUTEX_WAITER
end virtual
 
;void __fastcall mutex_init(struct mutex *lock)
 
align 4
mutex_init:
lea eax, [ecx+MUTEX.next]
mov [ecx+MUTEX.count],1
mov [ecx+MUTEX.next], eax
mov [ecx+MUTEX.prev], eax
ret
 
 
;void __fastcall mutex_lock(struct mutex *lock)
 
align 4
mutex_lock:
 
dec [ecx+MUTEX.count]
jns .done
 
pushfd
cli
 
push esi
sub esp, MUTEX_WAITER.sizeof
 
mov eax, [ecx+MUTEX.prev]
lea esi, [ecx+MUTEX.next]
 
mov [ecx+MUTEX.prev], esp
mov [esp+MUTEX_WAITER.next], esi
mov [esp+MUTEX_WAITER.prev], eax
mov [eax], esp
 
mov edx, [TASK_BASE]
mov [esp+MUTEX_WAITER.task], edx
 
.forever:
 
mov eax, -1
xchg eax, [ecx+MUTEX.count]
dec eax
jz @F
 
mov [edx+TASKDATA.state], 1
call change_task
jmp .forever
@@:
mov edx, [esp+MUTEX_WAITER.next]
mov eax, [esp+MUTEX_WAITER.prev]
 
mov [eax+MUTEX_WAITER.next], edx
cmp [ecx+MUTEX.next], esi
mov [edx+MUTEX_WAITER.prev], eax
jne @F
 
mov [ecx+MUTEX.count], 0
@@:
add esp, MUTEX_WAITER.sizeof
 
pop esi
popfd
.done:
ret
 
;void __fastcall mutex_unlock(struct mutex *lock)
 
align 4
mutex_unlock:
 
pushfd
cli
 
lea eax, [ecx+MUTEX.next]
cmp eax, [ecx+MUTEX.next]
mov [ecx+MUTEX.count], 1
je @F
 
mov eax, [eax+MUTEX_WAITER.task]
mov [eax+TASKDATA.state], 0
@@:
popfd
ret
 
 
purge MUTEX_WAITER
 
if 0
 
struc TIMER
{
.next dd ?
.exp_time dd ?
.func dd ?
.arg dd ?
}
 
 
MAX_PROIRITY 0 ; highest, used for kernel tasks
MAX_USER_PRIORITY 0 ; highest priority for user processes
USER_PRIORITY 7 ; default (should correspond to nice 0)
MIN_USER_PRIORITY 14 ; minimum priority for user processes
IDLE_PRIORITY 15 ; lowest, only IDLE process goes here
NR_SCHED_QUEUES 16 ; MUST equal IDLE_PRIORYTY + 1
 
uglobal
rdy_head rd 16
endg
 
align 4
pick_task:
 
xor eax, eax
.pick:
mov ebx, [rdy_head+eax*4]
test ebx, ebx
jz .next
 
mov [next_task], ebx
test [ebx+flags.billable]
jz @F
mov [bill_task], ebx
@@:
ret
.next:
inc eax
jmp .pick
 
; param
; eax= task
;
; retval
; eax= task
; ebx= queue
; ecx= front if 1 or back if 0
align 4
shed:
cmp [eax+.tics_left], 0 ;signed compare
mov ebx, [eax+.priority]
setg ecx
jg @F
 
mov edx, [eax+.tics_quantum]
mov [eax+.ticks_left], edx
cmp ebx, (IDLE_PRIORITY-1)
je @F
inc ebx
@@:
ret
 
; param
; eax= task
align 4
enqueue:
call shed ;eax
cmp [rdy_head+ebx*4],0
jnz @F
 
mov [rdy_head+ebx*4], eax
mov [rdy_tail+ebx*4], eax
mov [eax+.next_ready], 0
jmp .pick
@@:
test ecx, ecx
jz .back
 
mov ecx, [rdy_head+ebx*4]
mov [eax+.next_ready], ecx
mov [rdy_head+ebx*4], eax
jmp .pick
.back:
mov ecx, [rdy_tail+ebx*4]
mov [ecx+.next_ready], eax
mov [rdy_tail+ebx*4], eax
mov [eax+.next_ready], 0
.pick:
call pick_proc ;select next task
ret
 
end if
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/debug.inc
0,0 → 1,429
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; diamond, 2006
sys_debug_services:
cmp ebx, 9
ja @f
jmp dword [sys_debug_services_table+ebx*4]
@@: ret
iglobal
align 4
sys_debug_services_table:
dd debug_set_event_data
dd debug_getcontext
dd debug_setcontext
dd debug_detach
dd debug_suspend
dd debug_resume
dd debug_read_process_memory
dd debug_write_process_memory
dd debug_terminate
dd debug_set_drx
endg
debug_set_event_data:
; in: ecx = pointer
; destroys eax
mov eax, [current_slot]
mov [eax+APPDATA.dbg_event_mem], ecx
ret
 
get_debuggee_slot:
; in: ecx=PID
; out: CF=1 if error
; CF=0 and eax=slot*0x20 if ok
; out: interrupts disabled
cli
mov eax, ecx
call pid_to_slot
test eax, eax
jz .ret_bad
shl eax, 5
push ebx
mov ebx, [CURRENT_TASK]
cmp [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx
pop ebx
jnz .ret_bad
; clc ; automatically
ret
.ret_bad:
stc
ret
 
debug_detach:
; in: ecx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
and dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0
call do_resume
.ret:
sti
ret
 
debug_terminate:
; in: ecx=pid
call get_debuggee_slot
jc debug_detach.ret
mov ecx, eax
shr ecx, 5
; push 2
; pop ebx
mov edx,esi
jmp sysfn_terminate
 
debug_suspend:
; in: ecx=pid
; destroys eax,ecx
cli
mov eax, ecx
call pid_to_slot
shl eax, 5
jz .ret
mov cl, [CURRENT_TASK+eax+TASKDATA.state] ; process state
test cl, cl
jz .1
cmp cl, 5
jnz .ret
mov cl, 2
.2: mov [CURRENT_TASK+eax+TASKDATA.state], cl
.ret:
sti
ret
.1:
inc ecx
jmp .2
 
do_resume:
mov cl, [CURRENT_TASK+eax+TASKDATA.state]
cmp cl, 1
jz .1
cmp cl, 2
jnz .ret
mov cl, 5
.2: mov [CURRENT_TASK+eax+TASKDATA.state], cl
.ret: ret
.1: dec ecx
jmp .2
 
debug_resume:
; in: ecx=pid
; destroys eax,ebx
cli
mov eax, ecx
call pid_to_slot
shl eax, 5
jz .ret
call do_resume
.ret: sti
ret
 
debug_getcontext:
; in:
; ecx=pid
; edx=sizeof(CONTEXT)
; esi->CONTEXT
; destroys eax,ecx,edx,esi,edi
cmp edx, 28h
jnz .ret
; push ecx
; mov ecx, esi
call check_region
; pop ecx
dec eax
jnz .ret
call get_debuggee_slot
jc .ret
mov edi, esi
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
lea esi, [eax+RING0_STACK_SIZE]
 
.ring0:
; note that following code assumes that all interrupt/exception handlers
; saves ring-3 context by pushad in this order
; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), pushad
sub esi, 8+12+20h
lodsd ;edi
mov [edi+24h], eax
lodsd ;esi
mov [edi+20h], eax
lodsd ; ebp
mov [edi+1Ch], eax
lodsd ;esp
lodsd ;ebx
mov [edi+14h], eax
lodsd ;edx
mov [edi+10h], eax
lodsd ;ecx
mov [edi+0Ch], eax
lodsd ;eax
mov [edi+8], eax
lodsd ;eip
mov [edi], eax
lodsd ;cs
lodsd ;eflags
mov [edi+4], eax
lodsd ;esp
mov [edi+18h], eax
.ret:
sti
ret
 
debug_setcontext:
; in:
; ecx=pid
; edx=sizeof(CONTEXT)
; esi->CONTEXT
; destroys eax,ecx,edx,esi,edi
cmp edx, 28h
jnz .ret
; push ebx
; mov ebx, edx
call check_region
; pop ebx
dec eax
jnz .ret
call get_debuggee_slot
jc .stiret
; mov esi, edx
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
lea edi, [eax+RING0_STACK_SIZE]
 
.ring0:
sub edi, 8+12+20h
mov eax, [esi+24h] ;edi
stosd
mov eax, [esi+20h] ;esi
stosd
mov eax, [esi+1Ch] ;ebp
stosd
scasd
mov eax, [esi+14h] ;ebx
stosd
mov eax, [esi+10h] ;edx
stosd
mov eax, [esi+0Ch] ;ecx
stosd
mov eax, [esi+8] ;eax
stosd
mov eax, [esi] ;eip
stosd
scasd
mov eax, [esi+4] ;eflags
stosd
mov eax, [esi+18h] ;esp
stosd
.stiret:
sti
.ret:
ret
 
debug_set_drx:
call get_debuggee_slot
jc .errret
mov ebp, eax
lea eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs]
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3
; [eax+10]=dr7
cmp esi, OS_BASE
jae .errret
cmp dl, 3
ja .errret
mov ecx, dr7
;fix me
xchg ecx,edx
shr edx, cl
shr edx, cl
xchg ecx,edx
 
test ecx, 2 ; bit 1+2*index = G0..G3, global break enable
jnz .errret2
test dh, dh
jns .new
; clear breakpoint
movzx edx, dl
add edx, edx
and dword [eax+edx*2], 0 ; clear DR<i>
btr dword [eax+10h], edx ; clear L<i> bit
test byte [eax+10h], 55h
jnz .okret
; imul eax, ebp, tss_step/32
; and byte [eax + tss_data + TSS._trap], not 1
and [ebp*8 + SLOT_BASE+APPDATA.dbg_state], not 1
.okret:
and dword [esp+32], 0
sti
ret
.errret:
sti
mov dword [esp+32], 1
ret
.errret2:
sti
mov dword [esp+32], 2
ret
.new:
; add new breakpoint
; dl=index; dh=flags; esi=address
test dh, 0xF0
jnz .errret
mov cl, dh
and cl, 3
cmp cl, 2
jz .errret
mov cl, dh
shr cl, 2
cmp cl, 2
jz .errret
 
mov ebx,esi
test bl, dl
 
jnz .errret
or byte [eax+10h+1], 3 ; set GE and LE flags
 
movzx edx, dh
movzx ecx, dl
add ecx, ecx
bts dword [eax+10h], ecx ; set L<i> flag
add ecx, ecx
mov [eax+ecx], ebx;esi ; set DR<i>
shl edx, cl
mov ebx, 0xF
shl ebx, cl
not ebx
and [eax+10h+2], bx
or [eax+10h+2], dx ; set R/W and LEN fields
; imul eax, ebp, tss_step/32
; or byte [eax + tss_data + TSS._trap], 1
or [ebp*8 + SLOT_BASE+APPDATA.dbg_state], 1
jmp .okret
 
debug_read_process_memory:
; in:
; ecx=pid
; edx=length
; edi->buffer in debugger
; esi=address in debuggee
; out: [esp+36]=sizeof(read)
; destroys all
; push ebx
; mov ebx, esi
call check_region
; pop ebx
dec eax
jnz .err
call get_debuggee_slot
jc .err
shr eax, 5
mov ecx, edi
call read_process_memory
sti
mov dword [esp+32], eax
ret
.err:
or dword [esp+32], -1
ret
 
debug_write_process_memory:
; in:
; ecx=pid
; edx=length
; edi->buffer in debugger
; esi=address in debuggee
; out: [esp+36]=sizeof(write)
; destroys all
; push ebx
; mov ebx, esi
call check_region
; pop ebx
dec eax
jnz debug_read_process_memory.err
call get_debuggee_slot
jc debug_read_process_memory.err
shr eax, 5
mov ecx, edi
call write_process_memory
sti
mov [esp+32], eax
ret
 
debugger_notify:
; in: eax=debugger slot
; ecx=size of debug message
; [esp+4]..[esp+4+ecx]=message
; interrupts must be disabled!
; destroys all general registers
; interrupts remain disabled
xchg ebp, eax
mov edi, [timer_ticks]
add edi, 500 ; 5 sec timeout
.1:
mov eax, ebp
shl eax, 8
mov esi, [SLOT_BASE+eax+APPDATA.dbg_event_mem]
test esi, esi
jz .ret
; read buffer header
push ecx
push eax
push eax
mov eax, ebp
mov ecx, esp
mov edx, 8
call read_process_memory
cmp eax, edx
jz @f
add esp, 12
jmp .ret
@@:
cmp dword [ecx], 0
jg @f
.2:
pop ecx
pop ecx
pop ecx
cmp dword [CURRENT_TASK], 1
jnz .notos
cmp [timer_ticks], edi
jae .ret
.notos:
sti
call change_task
cli
jmp .1
@@:
mov edx, [ecx+8]
add edx, [ecx+4]
cmp edx, [ecx]
ja .2
; advance buffer position
push edx
mov edx, 4
sub ecx, edx
mov eax, ebp
add esi, edx
call write_process_memory
pop eax
; write message
mov eax, ebp
add esi, edx
add esi, [ecx+8]
add ecx, 20
pop edx
pop edx
pop edx
call write_process_memory
; new debug event
mov eax, ebp
shl eax, 8
or byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1 ; set flag 100h
.ret:
ret
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/sys32.inc
0,0 → 1,834
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; MenuetOS process management, protected ring3 ;;
;; ;;
;; Distributed under GPL. See file COPYING for details. ;;
;; Copyright 2003 Ville Turjanmaa ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
align 4 ;3A08
build_interrupt_table:
mov edi, idts
mov esi, sys_int
mov ecx, 0x40
mov eax, (10001110b shl 24) + os_code
@@: movsw ;low word of code-entry
stosd ;interrupt gate type : os_code selector
movsw ;high word of code-entry
loop @b
movsd ;copy low dword of trap gate for int 0x40
movsd ;copy high dword of trap gate for int 0x40
lidt [esi]
ret
 
iglobal
align 4
sys_int:
;exception handlers addresses (for interrupt gate construction)
dd e0,e1,e2,e3,e4,e5,e6,except_7 ; SEE: core/fpu.inc
dd e8,e9,e10,e11,e12,e13,page_fault_exc,e15
dd e16, e17,e18, e19
times 12 dd unknown_interrupt ;int_20..int_31
 
;interrupt handlers addresses (for interrupt gate construction)
dd irq0, irq_serv.irq_1, irq_serv.irq_2
if USE_COM_IRQ
dd irq_serv.irq_3, irq_serv.irq_4
else
dd p_irq3, p_irq4 ;??? íåñòûêîâêà
end if
dd 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, irq_serv.irq_12, irqD,p_irq14,p_irq15
times 16 dd unknown_interrupt ;int_0x30..int_0x3F
 
;int_0x40 gate trap (for directly copied)
dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16
 
idtreg: ; data for LIDT instruction (!!! must be immediately below sys_int data)
dw 2*($-sys_int-4)-1
dd idts ;0x8000B100
dw 0 ;ïðîñòî âûðàâíèâàíèå
 
msg_fault_sel dd msg_exc_8,msg_exc_u,msg_exc_a,msg_exc_b
dd msg_exc_c,msg_exc_d,msg_exc_e
 
msg_exc_8 db "Double fault", 0
msg_exc_u db "Undefined Exception", 0
msg_exc_a db "Invalid TSS", 0
msg_exc_b db "Segment not present", 0
msg_exc_c db "Stack fault", 0
msg_exc_d db "General protection fault", 0
msg_exc_e db "Page fault", 0
 
msg_sel_ker db "kernel", 0
msg_sel_app db "application", 0
 
endg
 
macro save_ring3_context {
pushad
}
macro restore_ring3_context {
popad
}
macro exc_wo_code [num] {
e#num :
save_ring3_context
mov bl, num
jmp exc_c
} exc_wo_code 0,1,2,3,4,5,6,15,16,19
 
macro exc_w_code [num] {
e#num :
add esp, 4
save_ring3_context
mov bl, num
jmp exc_c
} exc_w_code 8,9,10,11,12,13,17,18
 
 
uglobal
pf_err_code dd ?
endg
 
page_fault_exc: ; äóðàêîóñòî÷èâîñòü: ñåëåêòîðû èñïîð÷åíû...
pop [ss:pf_err_code]; äåéñòâèòåëüíî äî ñëåäóþùåãî #PF
save_ring3_context
mov bl,14
 
exc_c: ; èñêëþ÷åíèÿ (âñå, êðîìå 7-ãî - #NM)
; Ôðýéì ñòåêà ïðè èñêëþ÷åíèè/ïðåðûâàíèè èç 3-ãî êîëüöà + pushad (ò.å., èìåííî çäåñü)
reg_ss equ esp+0x30
reg_esp3 equ esp+0x2C
reg_eflags equ esp+0x28
reg_cs3 equ esp+0x24
reg_eip equ esp+0x20
; ýòî ôðýéì îò pushad
reg_eax equ esp+0x1C
reg_ecx equ esp+0x18
reg_edx equ esp+0x14
reg_ebx equ esp+0x10
reg_esp0 equ esp+0x0C
reg_ebp equ esp+0x08
reg_esi equ esp+0x04
reg_edi equ esp+0x00
 
Mov ds,ax,app_data ; çàãðóçèì ïðàâèëüíûå çíà÷åíèÿ
mov es,ax ; â ñåãìåíòíûå ðåãèñòðû
cld ; è ïðèâîäèì DF ê ñòàíäàðòó
movzx ebx,bl
; redirect to V86 manager? (EFLAGS & 0x20000) != 0?
test byte[reg_eflags+2],2
jnz v86_exc_c
cmp bl,14 ; #PF
jne @f
call page_fault_handler ; SEE: core/memory.inc
@@: mov esi, [current_slot]
btr [esi+APPDATA.except_mask], ebx
jnc @f
mov eax,[esi+APPDATA.exc_handler]
test eax, eax
jnz IRetToUserHook
@@: cli
mov eax, [esi+APPDATA.debugger_slot]
test eax, eax
jnz .debug
sti
; not debuggee => say error and terminate
call show_error_parameters ;; only ONE using, inline ???
;mov edx, [TASK_BASE]
mov [edx + TASKDATA.state], byte 4 ; terminate
jmp change_task ; stack - here it does not matter at all, SEE: core/shed.inc
.debug:
; we are debugged process, notify debugger and suspend ourself
; eax=debugger PID
mov ecx,1 ; debug_message code=other_exception
cmp bl,1 ; #DB
jne .notify ; notify debugger and suspend ourself
mov ebx, dr6 ; debug_message data=DR6_image
xor edx, edx
mov dr6, edx
mov edx, dr7
mov cl, not 8
.l1: shl dl,2
jc @f
and bl, cl
@@: sar cl,1
jc .l1
mov cl, 3 ; debug_message code=debug_exception
.notify:
push ebx ; debug_message data
mov ebx, [TASK_BASE]
push [ebx+TASKDATA.pid] ; PID
push ecx ; debug_message code ((here: ecx==1/3))
mov cl, 12 ; debug_message size
call debugger_notify ;; only ONE using, inline ??? SEE: core/debug.inc
add esp,12
mov edx, [TASK_BASE]
mov byte [edx+TASKDATA.state], 1 ; suspended
call change_task ; SEE: core/shed.inc
restore_ring3_context
iretd
 
IRetToUserHook:
xchg eax, [reg_eip]
sub dword[reg_esp3], 8
mov edi, [reg_esp3]
stosd
mov [edi], ebx
restore_ring3_context
unknown_interrupt:
iretd
 
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
show_error_parameters:
mov edx,[TASK_BASE] ;not scratched below
DEBUGF 1, "K : Process - forced terminate PID: %x\n", [edx+TASKDATA.pid]
cmp bl, 0x08
jb .l0
cmp bl, 0x0e
jbe .l1
.l0: mov bl, 0x09
.l1: mov eax,[msg_fault_sel+ebx*4 - 0x08*4]
DEBUGF 1, "K : %s\n", eax
mov eax, [reg_cs3+4]
mov edi, msg_sel_app
mov ebx, [reg_esp3+4]
cmp eax, app_code
je @f
mov edi, msg_sel_ker
mov ebx, [reg_esp0+4]
@@: DEBUGF 1, "K : EAX : %x EBX : %x ECX : %x\n", [reg_eax+4], [reg_ebx+4], [reg_ecx+4]
DEBUGF 1, "K : EDX : %x ESI : %x EDI : %x\n", [reg_edx+4], [reg_esi+4], [reg_edi+4]
DEBUGF 1, "K : EBP : %x EIP : %x ESP : %x\n", [reg_ebp+4], [reg_eip+4], ebx
DEBUGF 1, "K : Flags : %x CS : %x (%s)\n", [reg_eflags+4], eax, edi
ret
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
restore reg_ss
restore reg_esp3
restore reg_eflags
restore reg_cs
restore reg_eip
restore reg_eax
restore reg_ecx
restore reg_edx
restore reg_ebx
restore reg_esp0
restore reg_ebp
restore reg_esi
restore reg_edi
 
; irq1 -> hid/keyboard.inc
macro irqh [num] {
p_irq#num :
mov edi, num
jmp irqhandler
}
 
 
 
p_irq6:
save_ring3_context
mov ax, app_data ;os_data
mov ds, ax
mov es, ax
mov edi, 6
cmp [v86_irqhooks+edi*8], 0
jnz v86_irq2
call fdc_irq
call ready_for_next_irq
restore_ring3_context
iret
 
 
p_irq14:
save_ring3_context
mov ax, app_data ;os_data
mov ds, ax
mov es, ax
mov edi, 14
cmp [v86_irqhooks+edi*8], 0
jnz v86_irq2
; mov byte [BOOT_VAR + 0x48E], 0xFF
call [irq14_func]
call ready_for_next_irq_1
restore_ring3_context
iret
p_irq15:
save_ring3_context
mov ax, app_data ;os_data
mov ds, ax
mov es, ax
mov edi, 15
cmp [v86_irqhooks+edi*8], 0
jnz v86_irq2
; mov byte [BOOT_VAR + 0x48E], 0xFF
call [irq15_func]
call ready_for_next_irq_1
restore_ring3_context
iret
 
ready_for_next_irq:
mov eax,5
mov [check_idle_semaphore],eax
; mov al, 0x20
add eax,(0x20-0x5)
 
out 0x20, al
ret
;destroy eax
ready_for_next_irq_1:
mov eax,5
mov [check_idle_semaphore],eax
; mov al, 0x20
add eax,(0x20-0x5)
out 0xa0,al
out 0x20, al
ret
 
irqD:
push eax
xor eax,eax
out 0xf0,al
mov al,0x20
out 0xa0,al
out 0x20,al
pop eax
iret
 
 
irqh 2,3,4,5,7,8,9,10,11
 
irqhandler:
 
mov esi,edi ; 1
shl esi,6 ; 1
add esi,irq00read ; 1
shl edi,12 ; 1
add edi,IRQ_SAVE
mov ecx,16
 
irqnewread:
dec ecx
js irqover
 
movzx edx, word [esi] ; 2+
 
test edx, edx ; 1
jz irqover
 
 
mov ebx, [edi] ; address of begin of buffer in edi ; + 0x0 dword - data size
mov eax, 4000 ; + 0x4 dword - data begin offset
cmp ebx, eax
je irqfull
add ebx, [edi + 0x4] ; add data size to data begin offset
cmp ebx, eax ; if end of buffer, begin cycle again
jb @f
 
xor ebx, ebx
 
@@:
add ebx, edi
movzx eax, byte[esi + 3] ; get type of data being received 1 - byte, 2 - word
dec eax
jz irqbyte
dec eax
jnz noirqword
 
in ax,dx
cmp ebx, 3999 ; check for address odd in the end of buffer
jne .odd
mov [ebx + 0x10], ax
jmp .add_size
.odd:
mov [ebx + 0x10], al ; I could make mistake here :)
mov [edi + 0x10], ah
.add_size:
add dword [edi], 2
jmp nextport
 
 
irqbyte:
in al,dx
mov [ebx + 0x10],al
inc dword [edi]
nextport:
add esi,4
jmp irqnewread
 
 
noirqword:
irqfull:
irqover:
 
ret
 
 
 
set_application_table_status:
push eax
 
mov eax,[CURRENT_TASK]
shl eax, 5
add eax,CURRENT_TASK+TASKDATA.pid
mov eax,[eax]
 
mov [application_table_status],eax
 
pop eax
 
ret
 
 
clear_application_table_status:
push eax
 
mov eax,[CURRENT_TASK]
shl eax, 5
add eax,CURRENT_TASK+TASKDATA.pid
mov eax,[eax]
 
cmp eax,[application_table_status]
jne apptsl1
xor eax,eax
mov [application_table_status],eax
apptsl1:
 
pop eax
 
ret
 
; * eax = 64 - íîìåð ôóíêöèè
; * ebx = 1 - åäèíñòâåííàÿ ïîäôóíêöèÿ
; * ecx = íîâûé ðàçìåð ïàìÿòè
;Âîçâðàùàåìîå çíà÷åíèå:
; * eax = 0 - óñïåøíî
; * eax = 1 - íåäîñòàòî÷íî ïàìÿòè
 
sys_resize_app_memory:
; ebx = 1 - resize
; ecx = new amount of memory
 
; cmp eax,1
dec ebx
jnz .no_application_mem_resize
stdcall new_mem_resize, ecx
mov [esp+32], eax
.no_application_mem_resize:
ret
 
iglobal
; process_terminating db 'K : Process - terminating',13,10,0
; process_terminated db 'K : Process - done',13,10,0
msg_obj_destroy db 'K : destroy app object',13,10,0
endg
 
; param
; esi= slot
 
terminate: ; terminate application
 
.slot equ esp ;locals
 
push esi ;save .slot
 
shl esi, 8
cmp [SLOT_BASE+esi+APPDATA.dir_table], 0
jne @F
pop esi
shl esi, 5
mov [CURRENT_TASK+esi+TASKDATA.state], 9
ret
@@:
;mov esi,process_terminating
;call sys_msg_board_str
@@:
cli
cmp [application_table_status],0
je term9
sti
call change_task
jmp @b
term9:
call set_application_table_status
 
; if the process is in V86 mode...
mov eax, [.slot]
shl eax, 8
mov esi, [eax+SLOT_BASE+APPDATA.pl0_stack]
add esi, RING0_STACK_SIZE
cmp [eax+SLOT_BASE+APPDATA.saved_esp0], esi
jz .nov86
; ...it has page directory for V86 mode
mov esi, [eax+SLOT_BASE+APPDATA.saved_esp0]
mov ecx, [esi+4]
mov [eax+SLOT_BASE+APPDATA.dir_table], ecx
; ...and I/O permission map for V86 mode
mov ecx, [esi+12]
mov [eax+SLOT_BASE+APPDATA.io_map], ecx
mov ecx, [esi+8]
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx
.nov86:
 
mov esi, [.slot]
shl esi,8
add esi, SLOT_BASE+APP_OBJ_OFFSET
@@:
mov eax, [esi+APPOBJ.fd]
test eax, eax
jz @F
 
cmp eax, esi
je @F
 
push esi
call [eax+APPOBJ.destroy]
DEBUGF 1,"%s",msg_obj_destroy
pop esi
jmp @B
@@:
 
mov eax, [.slot]
shl eax, 8
stdcall destroy_app_space, [SLOT_BASE+eax+APPDATA.dir_table], [SLOT_BASE+eax+APPDATA.dlls_list_ptr]
 
mov esi, [.slot]
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1
jne @F
 
mov [fpu_owner],1
mov eax, [256+SLOT_BASE+APPDATA.fpu_state]
clts
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
fxrstor [eax]
jmp @F
.no_SSE:
fnclex
frstor [eax]
@@:
 
mov [KEY_COUNT],byte 0 ; empty keyboard buffer
mov [BTN_COUNT],byte 0 ; empty button buffer
 
 
; remove defined hotkeys
mov eax, hotkey_list
.loop:
cmp [eax+8], esi
jnz .cont
mov ecx, [eax]
jecxz @f
push dword [eax+12]
pop dword [ecx+12]
@@:
mov ecx, [eax+12]
push dword [eax]
pop dword [ecx]
xor ecx, ecx
mov [eax], ecx
mov [eax+4], ecx
mov [eax+8], ecx
mov [eax+12], ecx
.cont:
add eax, 16
cmp eax, hotkey_list+256*16
jb .loop
; remove hotkeys in buffer
mov eax, hotkey_buffer
.loop2:
cmp [eax], esi
jnz .cont2
and dword [eax+4], 0
and dword [eax], 0
.cont2:
add eax, 8
cmp eax, hotkey_buffer+120*8
jb .loop2
 
mov ecx,esi ; remove buttons
bnewba2:
mov edi,[BTN_ADDR]
mov eax,edi
cld
movzx ebx,word [edi]
inc bx
bnewba:
dec bx
jz bnmba
add eax,0x10
cmp cx,[eax]
jnz bnewba
pusha
mov ecx,ebx
inc ecx
shl ecx,4
mov ebx,eax
add eax,0x10
call memmove
dec dword [edi]
popa
jmp bnewba2
bnmba:
 
pusha ; save window coordinates for window restoring
cld
shl esi,5
add esi,window_data
mov eax,[esi+WDATA.box.left]
mov [draw_limits.left],eax
add eax,[esi+WDATA.box.width]
mov [draw_limits.right],eax
mov eax,[esi+WDATA.box.top]
mov [draw_limits.top],eax
add eax,[esi+WDATA.box.height]
mov [draw_limits.bottom],eax
 
xor eax, eax
mov [esi+WDATA.box.left],eax
mov [esi+WDATA.box.width],eax
mov [esi+WDATA.box.top],eax
mov [esi+WDATA.box.height],eax
mov [esi+WDATA.cl_workarea],eax
mov [esi+WDATA.cl_titlebar],eax
mov [esi+WDATA.cl_frames],eax
mov dword [esi+WDATA.reserved],eax ; clear all flags: wstate, redraw, wdrawn
lea edi, [esi-window_data+draw_data]
mov ecx,32/4
rep stosd
popa
 
; debuggee test
pushad
mov edi, esi
shl edi, 5
mov eax, [SLOT_BASE+edi*8+APPDATA.debugger_slot]
test eax, eax
jz .nodebug
push 8
pop ecx
push dword [CURRENT_TASK+edi+TASKDATA.pid] ; PID
push 2
call debugger_notify
pop ecx
pop ecx
.nodebug:
popad
 
mov ebx, [.slot]
shl ebx, 8
push ebx
mov ebx,[SLOT_BASE+ebx+APPDATA.pl0_stack]
 
stdcall kernel_free, ebx
 
pop ebx
mov ebx,[SLOT_BASE+ebx+APPDATA.cur_dir]
stdcall kernel_free, ebx
 
mov edi, [.slot]
shl edi,8
add edi,SLOT_BASE
 
mov eax, [edi+APPDATA.io_map]
cmp eax, [SLOT_BASE+256+APPDATA.io_map]
je @F
call free_page
@@:
mov eax, [edi+APPDATA.io_map+4]
cmp eax, [SLOT_BASE+256+APPDATA.io_map+4]
je @F
call free_page
@@:
mov eax, 0x20202020
stosd
stosd
stosd
mov ecx,244/4
xor eax, eax
rep stosd
 
; activate window
movzx eax, word [WIN_STACK + esi*2]
cmp eax, [TASK_COUNT]
jne .dont_activate
pushad
.check_next_window:
dec eax
cmp eax, 1
jbe .nothing_to_activate
lea esi, [WIN_POS+eax*2]
movzx edi, word [esi] ; edi = process
shl edi, 5
cmp [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots
je .check_next_window
add edi, window_data
; \begin{diamond}[19.09.2006]
; skip minimized windows
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .check_next_window
; \end{diamond}
call waredraw
.nothing_to_activate:
popad
.dont_activate:
 
push esi ; remove hd1 & cd & flp reservation
shl esi, 5
mov esi, [esi+CURRENT_TASK+TASKDATA.pid]
cmp [hd1_status], esi
jnz @f
call free_hd_channel
and [hd1_status], 0
@@:
cmp [cd_status], esi
jnz @f
call free_cd_channel
and [cd_status], 0
@@:
cmp [flp_status], esi
jnz @f
and [flp_status], 0
@@:
pop esi
cmp [bgrlockpid], esi
jnz @f
and [bgrlockpid], 0
and [bgrlock], 0
@@:
 
pusha ; remove all irq reservations
mov eax,esi
shl eax, 5
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov edi,irq_owner
xor ebx, ebx
xor edx, edx
newirqfree:
cmp [edi + 4 * ebx], eax
jne nofreeirq
mov [edi + 4 * ebx], edx ; remove irq reservation
mov [irq_tab + 4 * ebx], edx ; remove irq handler
mov [irq_rights + 4 * ebx], edx ; set access rights to full access
nofreeirq:
inc ebx
cmp ebx, 16
jb newirqfree
popa
 
pusha ; remove all port reservations
mov edx,esi
shl edx, 5
add edx,CURRENT_TASK
mov edx,[edx+TASKDATA.pid]
 
rmpr0:
 
mov esi,[RESERVED_PORTS]
 
test esi,esi
jz rmpr9
 
rmpr3:
 
mov edi,esi
shl edi,4
add edi,RESERVED_PORTS
 
cmp edx,[edi]
je rmpr4
 
dec esi
jnz rmpr3
 
jmp rmpr9
 
rmpr4:
 
mov ecx,256
sub ecx,esi
shl ecx,4
 
mov esi,edi
add esi,16
cld
rep movsb
 
dec dword [RESERVED_PORTS]
 
jmp rmpr0
 
rmpr9:
 
popa
mov edi,esi ; do not run this process slot
shl edi, 5
mov [edi+CURRENT_TASK + TASKDATA.state],byte 9
; debugger test - terminate all debuggees
mov eax, 2
mov ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot
.xd0:
cmp eax, [TASK_COUNT]
ja .xd1
cmp dword [ecx], esi
jnz @f
and dword [ecx], 0
pushad
xchg eax, ecx
mov ebx, 2
call sys_system
popad
@@:
inc eax
add ecx, 0x100
jmp .xd0
.xd1:
; call systest
sti ; .. and life goes on
 
mov eax, [draw_limits.left]
mov ebx, [draw_limits.top]
mov ecx, [draw_limits.right]
mov edx, [draw_limits.bottom]
call calculatescreen
xor eax, eax
xor esi, esi
call redrawscreen
 
mov [MOUSE_BACKGROUND],byte 0 ; no mouse background
mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse
 
and [application_table_status],0
;mov esi,process_terminated
;call sys_msg_board_str
add esp, 4
ret
restore .slot
 
iglobal
boot_sched_1 db 'Building gdt tss pointer',0
boot_sched_2 db 'Building IDT table',0
endg
 
 
build_scheduler:
 
mov esi,boot_sched_1
call boot_log
; call build_process_gdt_tss_pointer
 
; mov esi,boot_sched_2
; call boot_log
 
ret
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/taskman.inc
0,0 → 1,1169
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
GREEDY_KERNEL equ 0
 
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
}
 
 
struc APP_PARAMS
{ .app_cmdline ;0x00
.app_path ;0x04
.app_eip ;0x08
.app_esp ;0x0C
.app_mem ;0x10
}
 
macro _clear_ op
{ mov ecx, op/4
xor eax, eax
cld
rep stosd
}
 
fs_execute_from_sysdir:
xor ebx, ebx
xor edx, edx
mov esi, sysdir_path
 
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 rd 64 ;256/4
filename rd 256 ;1024/4
flags dd ?
 
save_cr3 dd ?
slot dd ?
slot_base dd ?
file_base dd ?
file_size dd ?
;app header data
hdr_cmdline dd ? ;0x00
hdr_path dd ? ;0x04
hdr_eip dd ? ;0x08
hdr_esp dd ? ;0x0C
hdr_mem dd ? ;0x10
hdr_i_end dd ? ;0x14
endl
 
pushad
 
mov [flags], edx
 
; [ebp] pointer to filename
 
lea edi, [filename]
lea ecx, [edi+1024]
mov al, '/'
stosb
@@:
cmp edi, ecx
jae .bigfilename
lodsb
stosb
test al, al
jnz @b
mov esi, [ebp]
test esi, esi
jz .namecopied
mov byte [edi-1], '/'
@@:
cmp edi, ecx
jae .bigfilename
lodsb
stosb
test al, al
jnz @b
jmp .namecopied
.bigfilename:
popad
mov eax, -ERROR_FILE_NOT_FOUND
ret
 
.namecopied:
 
mov [cmdline], ebx
test ebx, ebx
jz @F
 
lea eax, [cmdline]
mov dword [eax+252], 0
stdcall strncpy, eax, ebx, 255
@@:
lea eax, [filename]
stdcall load_file, eax
mov ecx, -ERROR_FILE_NOT_FOUND
test eax, eax
jz .err_file
 
mov [file_base], eax
mov [file_size], ebx
 
lea ebx, [hdr_cmdline]
call test_app_header
mov ecx, -0x1F
test eax, eax
jz .err_hdr
 
;mov esi, new_process_loading
;call sys_msg_board_str ; write message to message board
 
.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]
test eax, eax
jnz .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
shl eax, 8
add eax, SLOT_BASE
mov [slot_base], eax
mov edi, eax
_clear_ 256 ;clean extended information about process
 
; write application name
lea eax, [filename]
stdcall strrchr, eax, '/' ; now eax points to name without path
 
lea esi, [eax+1]
test eax, eax
jnz @F
lea esi, [filename]
@@:
mov ecx, 8 ; 8 chars for name
mov edi, [slot_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 ebx, cr3
mov [save_cr3], ebx
 
stdcall create_app_space,[hdr_mem],[file_base],[file_size]
mov ecx, -30 ; no memory
test eax, eax
jz .failed
 
mov ebx,[slot_base]
mov [ebx+APPDATA.dir_table],eax
mov eax,[hdr_mem]
mov [ebx+APPDATA.mem_size],eax
 
xor edx, edx
cmp word [6], '02'
jne @f
 
not edx
@@:
mov [ebx+APPDATA.tls_base],edx
 
if GREEDY_KERNEL
else
mov ecx, [hdr_mem]
mov edi, [file_size]
add edi, 4095
and edi, not 4095
sub ecx, edi
jna @F
 
xor eax, eax
cld
rep stosb
@@:
end if
 
; release only virtual space, not phisical memory
 
stdcall free_kernel_space, [file_base]
lea eax, [hdr_cmdline]
lea ebx, [cmdline]
lea ecx, [filename]
stdcall set_app_params ,[slot],eax,ebx,ecx,[flags]
 
mov eax, [save_cr3]
call set_cr3
 
xor ebx, ebx
mov [application_table_status],ebx ;unlock application_table_status mutex
mov eax,[process_number] ;set result
ret
.failed:
mov eax, [save_cr3]
call set_cr3
.err:
.err_hdr:
stdcall kernel_free,[file_base]
.err_file:
xor eax, eax
mov [application_table_status],eax
mov eax, ecx
ret
endp
 
align 4
test_app_header:
virtual at eax
APP_HEADER_00 APP_HEADER_00
end virtual
virtual at eax
APP_HEADER_01 APP_HEADER_01
end virtual
 
cmp dword [eax], 'MENU'
jne .fail
cmp word [eax+4],'ET'
jne .fail
 
cmp [eax+6], word '00'
jne .check_01_header
 
mov ecx,[APP_HEADER_00.start]
mov [ebx+0x08], ecx ;app_eip
mov edx,[APP_HEADER_00.mem_size]
mov [ebx+0x10], edx ;app_mem
shr edx,1
sub edx,0x10
mov [ebx+0x0C], edx ;app_esp
mov ecx,[APP_HEADER_00.i_param]
mov [ebx], ecx ;app_cmdline
mov [ebx+4], dword 0 ;app_path
mov edx, [APP_HEADER_00.i_end]
mov [ebx+0x14], edx
ret
 
.check_01_header:
 
cmp [eax+6], word '01'
je @f
cmp [eax+6], word '02'
jne .fail
@@:
mov ecx,[APP_HEADER_01.start]
mov [ebx+0x08], ecx ;app_eip
mov edx,[APP_HEADER_01.mem_size]
 
; \begin{diamond}[20.08.2006]
; sanity check (functions 19,58 load app_i_end bytes and that must
; fit in allocated memory to prevent kernel faults)
cmp edx,[APP_HEADER_01.i_end]
jb .fail
; \end{diamond}[20.08.2006]
 
mov [ebx+0x10], edx ;app_mem
mov ecx,[APP_HEADER_01.stack_top]
mov [ebx+0x0C], ecx ;app_esp
mov edx,[APP_HEADER_01.i_param]
mov [ebx], edx ;app_cmdline
mov ecx,[APP_HEADER_01.i_icon]
mov [ebx+4], ecx ;app_path
mov edx, [APP_HEADER_01.i_end]
mov [ebx+0x14], edx
ret
.fail:
xor eax, eax
ret
 
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)
ret
.failed:
xor eax,eax
ret
endp
 
align 4
proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
locals
app_pages dd ?
img_pages dd ?
dir_addr dd ?
app_tabs dd ?
endl
 
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
 
xor eax, eax
mov [dir_addr], eax
 
mov eax, [app_size]
add eax, 4095
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 ecx, [img_size]
add ecx, 4095
and ecx, NOT(4095)
 
mov [img_size], ecx
shr ecx, 12
mov [img_pages], ecx
 
if GREEDY_KERNEL
lea eax, [ecx+ebx+2] ;only image size
else
lea eax, [eax+ebx+2] ;all requested memory
end if
cmp eax, [pg_data.pages_free]
ja .fail
 
call alloc_page
test eax, eax
jz .fail
mov [dir_addr], eax
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW
 
mov edi, [tmp_task_pdir]
mov ecx, (OS_BASE shr 20)/4
xor eax, eax
cld
rep stosd
 
mov ecx, (OS_BASE shr 20)/4
mov esi, sys_pgdir+(OS_BASE shr 20)
rep movsd
 
mov eax, [dir_addr]
or eax, PG_SW
mov [edi-4096+(page_tabs shr 20)], eax
 
and eax, -4096
call set_cr3
 
mov edx, [app_tabs]
mov edi, new_app_base
@@:
call alloc_page
test eax, eax
jz .fail
 
stdcall map_page_table, edi, eax
add edi, 0x00400000
dec edx
jnz @B
 
mov edi, new_app_base
shr edi, 10
add edi, page_tabs
 
mov ecx, [app_tabs]
shl ecx, 10
xor eax, eax
rep stosd
 
mov ecx, [img_pages]
mov ebx, PG_UW
mov edx, new_app_base
mov esi, [img_base]
mov edi, new_app_base
shr esi, 10
shr edi, 10
add esi, page_tabs
add edi, page_tabs
.remap:
lodsd
or eax, ebx ; force user level r/w access
stosd
add edx, 0x1000
dec [app_pages]
dec ecx
jnz .remap
 
mov ecx, [app_pages]
test ecx, ecx
jz .done
 
if GREEDY_KERNEL
mov eax, 0x02
rep stosd
else
 
.alloc:
call alloc_page
test eax, eax
jz .fail
 
stdcall map_page,edx,eax,dword PG_UW
add edx, 0x1000
dec [app_pages]
jnz .alloc
end if
 
.done:
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
je @f
stdcall destroy_app_space, [dir_addr], 0
@@:
xor eax, eax
ret
endp
 
align 4
set_cr3:
 
mov ebx, [current_slot]
mov [ebx+APPDATA.dir_table], 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
test eax, 1 shl 9
jnz .next ;skip shared pages
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, dlls_list:dword
 
xor edx,edx
push 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
add ecx,SLOT_BASE
cmp [ecx+APPDATA.dir_table],ebx ;compare page directory addresses
jnz @f
mov [ebp-4],ecx
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
pop ecx
cmp edx,1
jg .ret
;if there isn't threads then clear memory.
mov esi, [dlls_list]
call destroy_all_hdlls
 
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
 
mov eax, [pg_dir]
and eax, not 0xFFF
stdcall map_page,[tmp_task_pdir],eax,PG_SW
mov esi, [tmp_task_pdir]
mov edi, (OS_BASE shr 20)/4
.destroy:
mov eax, [esi]
test eax, 1
jz .next
and eax, not 0xFFF
stdcall map_page,[tmp_task_ptab],eax,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],0,PG_UNMAP
stdcall map_page,[tmp_task_pdir],0,PG_UNMAP
dec [pg_data.pg_mutex]
.ret:
ret
endp
 
align 4
get_pid:
mov eax, [TASK_BASE]
mov eax, [eax+TASKDATA.pid]
ret
 
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:
; esi - start of buffer
; edx - 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
; esi - start of buffer
; edx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
 
test edx,edx
jle .ok
shl eax,5
cmp word [CURRENT_TASK+eax+0xa],0
jnz .failed
shl eax,3
mov eax,[SLOT_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
; ecx - buffer address
; edx - buffer size
; esi - 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], ecx
and [r_count], 0
mov [tmp_r_cnt], edx
mov [offset], esi
 
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 ebx, [offset]
 
push ecx
stdcall map_memEx, [proc_mem_map],\
[slot], ebx, ecx, PG_MAP
pop ecx
 
mov esi, [offset]
and esi, 0xfff
sub eax, esi
jbe .ret
cmp ecx, eax
jbe @f
mov ecx, eax
mov [tmp_r_cnt], eax
@@:
add esi, [proc_mem_map]
mov edi, [buff]
mov edx, ecx
rep movsb
add [r_count], edx
 
add [offset], edx
sub [tmp_r_cnt], edx
jnz .read_mem
.ret:
popad
mov eax, [r_count]
ret
endp
 
align 4
proc write_process_memory
;Input:
; eax - process slot
; ecx - buffer address
; edx - buffer size
; esi - 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], ecx
and [w_count], 0
mov [tmp_w_cnt], edx
mov [offset], esi
 
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 ebx, [offset]
; add ebx, new_app_base
push ecx
stdcall map_memEx, [proc_mem_map],\
[slot], ebx, ecx, PG_SW
pop ecx
 
mov edi, [offset]
and edi, 0xfff
sub eax, edi
jbe .ret
cmp ecx, eax
jbe @f
mov ecx, eax
mov [tmp_w_cnt], eax
@@:
add edi, [proc_mem_map]
mov esi, [buff]
mov edx, ecx
rep movsb
 
add [w_count], edx
add [offset], edx
sub [tmp_w_cnt], edx
jnz .read_mem
.ret:
popad
mov eax, [w_count]
ret
endp
 
align 4
proc new_sys_threads
locals
slot dd ?
app_cmdline dd ? ;0x00
app_path dd ? ;0x04
app_eip dd ? ;0x08
app_esp dd ? ;0x0C
app_mem dd ? ;0x10
endl
 
cmp ebx,1
jne .failed ;other subfunctions
 
xor eax,eax
mov [app_eip], ecx
mov [app_cmdline], eax
mov [app_esp], edx
mov [app_path], eax
;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]
test eax, eax
jnz .wait_lock
 
call set_application_table_status
 
call get_new_process_place
test eax, eax
jz .failed
 
mov [slot], eax
 
mov esi,[current_slot]
mov ebx,esi ;ebx=esi - pointer to extended information about current thread
 
mov edi, eax
shl edi,8
add edi,SLOT_BASE
mov edx,edi ;edx=edi - pointer to extended infomation about new thread
mov ecx,256/4
xor eax, eax
cld
rep stosd ;clean extended information about new thread
mov esi,ebx
mov edi,edx
mov ecx,11
rep movsb ;copy process name
 
mov eax,[ebx+APPDATA.heap_base]
mov [edx+APPDATA.heap_base], eax
 
mov ecx,[ebx+APPDATA.heap_top]
mov [edx+APPDATA.heap_top], ecx
 
mov eax,[ebx+APPDATA.mem_size]
mov [edx+APPDATA.mem_size], eax
 
mov ecx,[ebx+APPDATA.dir_table]
mov [edx+APPDATA.dir_table],ecx ;copy page directory
 
mov eax,[ebx+APPDATA.dlls_list_ptr]
mov [edx+APPDATA.dlls_list_ptr],eax
 
mov eax, [ebx+APPDATA.tls_base]
test eax, eax
jz @F
 
push edx
stdcall user_alloc, 4096
pop edx
test eax, eax
jz .failed1 ;eax=0
@@:
mov [edx+APPDATA.tls_base], eax
 
lea eax, [app_cmdline]
stdcall set_app_params ,[slot],eax,dword 0,\
dword 0,dword 0
 
;mov esi,new_process_running
;call sys_msg_board_str ;output information about succefull startup
xor eax,eax
mov [application_table_status],eax ;unlock application_table_status mutex
mov eax,[process_number] ;set result
ret
.failed:
xor eax,eax
.failed1:
mov [application_table_status],eax
dec eax ;-1
ret
endp
 
; param
; ebx=mutex
 
align 4
wait_mutex:
;;Maxis use atomic bts for mutex 4.4.2009
push eax
push ebx
.do_wait:
bts dword [ebx],0
jnc .locked
call change_task
jmp .do_wait
.locked:
pop ebx
pop eax
ret
 
align 4
tls_app_entry:
 
call init_heap
stdcall user_alloc, 4096
 
mov edx, [current_slot]
mov [edx+APPDATA.tls_base], eax
mov [tls_data_l+2],ax
shr eax,16
mov [tls_data_l+4],al
mov [tls_data_l+7],ah
mov dx, app_tls
mov fs, dx
popad
iretd
 
 
EFL_IF equ 0x0200
EFL_IOPL1 equ 0x1000
EFL_IOPL2 equ 0x2000
EFL_IOPL3 equ 0x3000
 
 
align 4
proc set_app_params stdcall,slot:dword, params:dword,\
cmd_line:dword, app_path:dword, flags:dword
 
locals
pl0_stack dd ?
endl
 
stdcall kernel_alloc, RING0_STACK_SIZE+512
mov [pl0_stack], eax
 
lea edi, [eax+RING0_STACK_SIZE]
 
mov eax, [slot]
mov ebx, eax
 
shl eax, 8
mov [eax+SLOT_BASE+APPDATA.fpu_state], edi
mov [eax+SLOT_BASE+APPDATA.exc_handler], 0
mov [eax+SLOT_BASE+APPDATA.except_mask], 0
 
;set default io permission map
mov ecx, [SLOT_BASE+256+APPDATA.io_map]
mov [eax+SLOT_BASE+APPDATA.io_map], ecx
mov ecx, [SLOT_BASE+256+APPDATA.io_map+4]
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx
 
mov esi, fpu_data
mov ecx, 512/4
rep movsd
 
cmp ebx,[TASK_COUNT]
jle .noinc
inc dword [TASK_COUNT] ;update number of processes
.noinc:
shl ebx,8
lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET]
mov [SLOT_BASE+APPDATA.fd_ev+ebx],edx
mov [SLOT_BASE+APPDATA.bk_ev+ebx],edx
 
add edx, APP_OBJ_OFFSET-APP_EV_OFFSET
mov [SLOT_BASE+APPDATA.fd_obj+ebx],edx
mov [SLOT_BASE+APPDATA.bk_obj+ebx],edx
 
mov ecx, [def_cursor]
mov [SLOT_BASE+APPDATA.cursor+ebx],ecx
mov eax, [pl0_stack]
mov [SLOT_BASE+APPDATA.pl0_stack+ebx],eax
add eax, RING0_STACK_SIZE
mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax
 
push ebx
stdcall kernel_alloc, 0x1000
pop ebx
mov esi,[current_slot]
mov esi,[esi+APPDATA.cur_dir]
mov ecx,0x1000/4
mov edi,eax
mov [ebx+SLOT_BASE+APPDATA.cur_dir],eax
rep movsd
 
shr ebx,3
mov eax, new_app_base
mov dword [CURRENT_TASK+ebx+0x10],eax
 
.add_command_line:
mov edx,[params]
mov edx,[edx] ;app_cmdline
test edx,edx
jz @f ;application doesn't need parameters
 
mov eax, edx
add eax, 256
jc @f
 
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
 
mov byte [edx], 0 ;force empty string if no cmdline given
mov eax, [cmd_line]
test eax, eax
jz @f
stdcall strncpy, edx, eax, 256
@@:
mov edx,[params]
mov edx, [edx+4] ;app_path
test edx,edx
jz @F ;application don't need path of file
mov eax, edx
add eax, 1024
jc @f
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
ja @f
stdcall strncpy, edx, [app_path], 1024
@@:
mov ebx,[slot]
mov eax,ebx
shl ebx,5
lea ecx,[draw_data+ebx] ;ecx - pointer to draw data
 
mov edx, irq0.return
cmp [ebx*8+SLOT_BASE+APPDATA.tls_base], -1
jne @F
mov edx, tls_app_entry
@@:
; set window state to 'normal' (non-minimized/maximized/rolled-up) state
mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL
mov [ebx+window_data+WDATA.fl_redraw], 1
add ebx,CURRENT_TASK ;ebx - pointer to information about process
mov [ebx+TASKDATA.wnd_number],al;set window number on screen = process slot
 
mov [ebx+TASKDATA.event_mask],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
 
;set draw data to full screen
xor eax,eax
mov [ecx+0],dword eax
mov [ecx+4],dword eax
mov eax,[Screen_Max_X]
mov [ecx+8],eax
mov eax,[Screen_Max_Y]
mov [ecx+12],eax
 
mov ebx, [pl0_stack]
mov esi,[params]
lea ecx, [ebx+REG_EIP]
xor eax, eax
 
mov [ebx+REG_RET], edx
mov [ebx+REG_EDI], eax
mov [ebx+REG_ESI], eax
mov [ebx+REG_EBP], eax
mov [ebx+REG_ESP], ecx ;ebx+REG_EIP
mov [ebx+REG_EBX], eax
mov [ebx+REG_EDX], eax
mov [ebx+REG_ECX], eax
mov [ebx+REG_EAX], eax
 
mov eax, [esi+0x08] ;app_eip
mov [ebx+REG_EIP], eax ;app_entry
mov [ebx+REG_CS], dword app_code
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF
 
mov eax, [esi+0x0C] ;app_esp
mov [ebx+REG_APP_ESP], eax ;app_stack
mov [ebx+REG_SS], dword app_data
 
lea ecx, [ebx+REG_RET]
mov ebx, [slot]
shl ebx, 5
mov [ebx*8+SLOT_BASE+APPDATA.saved_esp], ecx
 
xor ecx, ecx ; process state - running
; set if debuggee
test byte [flags], 1
jz .no_debug
inc ecx ; process state - suspended
mov eax,[CURRENT_TASK]
mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot],eax
.no_debug:
mov [CURRENT_TASK+ebx+TASKDATA.state], cl
;mov esi,new_process_running
;call sys_msg_board_str ;output information about succefull startup
ret
endp
 
include "debug.inc"
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/malloc.inc
0,0 → 1,1029
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; Small heap based on malloc/free/realloc written by Doug Lea
; Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee)
; Source ftp://gee.cs.oswego.edu/pub/misc/malloc.c
; License http://creativecommons.org/licenses/publicdomain.
 
 
; eax= size
 
; temp
; esi= nb
; ebx= idx
;
align 16
malloc:
push esi
 
; nb = ((size+7)&~7)+8;
 
mov esi, eax ;size
add esi, 7
and esi, -8
add esi, 8
 
mov ebx, mst.mutex
call wait_mutex ;ebx
 
cmp esi, 256
jae .large
 
mov ecx, esi
shr ecx, 3
or eax, -1
shl eax, cl
and eax, [mst.smallmap]
jz .small
 
push ebp
push edi
 
bsf eax, eax
mov ebx, eax
 
; psize= idx<<3;
; B = &ms.smallbins[idx];
; p = B->fd;
; F = p->fd;
; rsize= psize-nb;
 
lea ebp, [eax*8] ;ebp= psize
shl eax, 4
lea edi, [mst.smallbins+eax] ;edi= B
mov edx, [edi+8] ;edx= p
mov eax, [edx+8] ;eax= F
mov ecx, ebp
sub ecx, esi ;ecx= rsize
 
; if (B == F)
cmp edi, eax
jne @F
 
btr [mst.smallmap], ebx
@@:
 
; B->fd = F;
; F->bk = B;
; if(rsize<16)
 
cmp ecx, 16
mov [edi+8], eax
mov [eax+12], edi
jae .split
 
; p->head = psize|PINUSE_BIT|CINUSE_BIT;
; (p + psize)->head |= PINUSE_BIT;
 
lea eax, [edx+8]
or dword [edx+ebp+4], 1
 
or ebp, 3
mov [edx+4], ebp
 
pop edi
pop ebp
.done:
pop esi
mov [mst.mutex], 0
ret
.split:
lea ebx, [edx+8] ;ebx=mem
 
; r = chunk_plus_offset(p, nb);
; p->head = nb|PINUSE_BIT|CINUSE_BIT;
; r->head = rsize|PINUSE_BIT;
 
lea eax, [edx+esi] ;eax= r
or esi, 3
mov [edx+4], esi
 
mov edx, ecx
or edx, 1
mov [eax+4], edx
 
; (r + rsize)->prev_foot = rsize;
 
mov [eax+ecx], ecx
 
; I = rsize>>3;
 
shr ecx, 3
 
; ms.smallmap |= 1<< I;
bts [mst.smallmap], ecx
 
; B = &ms.smallbins[I];
 
shl ecx, 4
pop edi
pop ebp
add ecx, mst.smallbins ;ecx= B
 
mov edx, [ecx+8] ; F = B->fd;
mov [ecx+8], eax ; B->fd = r;
mov [edx+12], eax ; F->bk = r;
mov [eax+8], edx ; r->fd = F;
mov [eax+12], ecx ; r->bk = B;
mov eax, ebx
pop esi
mov [mst.mutex], 0
ret
.small:
 
; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0)
;;;;;;;;;;; start a change <lrz>
mov eax,[mst.treemap]
test eax,eax
;;;;;;;;;;; end the change <lrz>
; cmp [mst.treemap], 0
jz .from_top
mov eax, esi
call malloc_small
test eax, eax
jz .from_top
pop esi
and [mst.mutex], 0
ret
.large:
 
; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0)
 
cmp [mst.treemap], 0
je .from_top
 
call malloc_large ;esi= nb
test eax, eax
jne .done
.from_top:
 
; if (nb < ms.topsize)
 
mov eax, [mst.topsize]
cmp esi, eax
jae .fail
 
; rsize = ms.topsize -= nb;
; p = ms.top;
 
mov ecx, [mst.top]
sub eax, esi
mov [mst.topsize], eax
 
; r = ms.top = chunk_plus_offset(p, nb);
; r->head = rsize | PINUSE_BIT;
; p->head = nb |PINUSE_BIT|CINUSE_BIT;
 
lea edx, [ecx+esi]
or eax, 1
mov [mst.top], edx
or esi, 3
mov [edx+4], eax
mov [ecx+4], esi
lea eax, [ecx+8]
pop esi
and [mst.mutex], 0
ret
.fail:
xor eax, eax
pop esi
and [mst.mutex], 0
ret
 
; param
; eax= mem
 
free:
push edi
mov edi, eax
add edi, -8
 
; if(p->head & CINUSE_BIT)
 
test byte [edi+4], 2
je .fail
 
mov ebx, mst.mutex
call wait_mutex ;ebx
 
; psize = p->head & (~3);
 
mov eax, [edi+4]
push esi
mov esi, eax
and esi, -4
 
; next = chunk_plus_offset(p, psize);
; if(!(p->head & PINUSE_BIT))
 
test al, 1
lea ebx, [esi+edi]
jne .next
 
; prevsize = p->prev_foot;
; prev=p - prevsize;
; psize += prevsize;
; p = prev;
 
mov ecx, [edi] ;ecx= prevsize
add esi, ecx ;esi= psize
sub edi, ecx ;edi= p
 
; if (prevsize < 256)
 
cmp ecx, 256
jae .unlink_large
 
mov eax, [edi+8] ;F = p->fd;
mov edx, [edi+12] ;B = p->bk;
 
; if (F == B)
; ms.smallmap &= ~(1<< I);
shr ecx, 3
cmp eax, edx
jne @F
btr [mst.smallmap], ecx
@@:
mov [eax+12], edx ;F->bk = B;
mov [edx+8], eax ;B->fd = F
jmp .next
.unlink_large:
mov edx, edi
call unlink_large_chunk
.next:
 
; if(next->head & PINUSE_BIT)
 
mov eax, [ebx+4]
test al, 1
jz .fail2
 
; if (! (next->head & CINUSE_BIT))
 
test al, 2
jnz .fix_next
 
; if (next == ms.top)
 
cmp ebx, [mst.top]
jne @F
 
; tsize = ms.topsize += psize;
 
mov eax, [mst.topsize]
add eax, esi
mov [mst.topsize], eax
 
; ms.top = p;
; p->head = tsize | PINUSE_BIT;
 
or eax, 1
mov [mst.top], edi
mov [edi+4], eax
.fail2:
and [mst.mutex], 0
pop esi
.fail:
pop edi
ret
@@:
 
; nsize = next->head & ~INUSE_BITS;
 
and eax, -4
add esi, eax ;psize += nsize;
 
; if (nsize < 256)
 
cmp eax, 256
jae .unl_large
 
mov edx, [ebx+8] ;F = next->fd
mov ebx, [ebx+12] ;B = next->bk
 
; if (F == B)
 
cmp edx, ebx
jne @F
mov ecx, eax
shr ecx, 3
btr [mst.smallmap], ecx
@@:
mov [edx+12], ebx ;F->bk = B
 
; p->head = psize|PINUSE_BIT;
 
mov ecx, esi
mov [ebx+8], edx
or ecx, 1
mov [edi+4], ecx
 
; (p+psize)->prev_foot = psize;
 
mov [esi+edi], esi
 
; insert_chunk(p,psize);
 
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
.unl_large:
 
; unlink_large_chunk((tchunkptr)next);
 
mov edx, ebx
call unlink_large_chunk
; p->head = psize|PINUSE_BIT;
 
mov ecx, esi
or ecx, 1
mov [edi+4], ecx
 
; (p+psize)->prev_foot = psize;
 
mov [esi+edi], esi
 
; insert_chunk(p,psize);
 
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
.fix_next:
 
; (p+psize)->prev_foot = psize;
; next->head &= ~PINUSE_BIT;
; p->head = psize|PINUSE_BIT;
 
and eax, -2
mov edx, esi
mov [ebx+4], eax
or edx, 1
mov [edi+4], edx
 
; (p+psize)->prev_foot = psize;
 
mov [esi+edi], esi
; insert_chunk(p,psize);
 
mov eax, esi
pop esi
mov ecx, edi
pop edi
jmp insert_chunk
 
; param
; ecx = chunk
; eax = size
 
insert_chunk:
 
cmp eax, 256
push esi
mov esi, ecx
jae .large
 
; I = S>>3;
; ms.smallmap |= 1<< I;
 
shr eax, 3
bts [mst.smallmap], eax
 
; B = &ms.smallbins[I];
 
shl eax, 4
add eax, mst.smallbins
mov edx, [eax+8] ;F = B->fd
mov [eax+8], esi ;B->fd = P
mov [edx+12], esi ;F->bk = P
mov [esi+8], edx ;P->fd = F
mov [esi+12], eax ;P->bk = B
pop esi
and [mst.mutex], 0
ret
.large:
mov ebx, eax
call insert_large_chunk
pop esi
and [mst.mutex], 0
ret
 
 
; param
; esi= chunk
; ebx= size
 
insert_large_chunk:
 
; I = compute_tree_index(S);
 
mov edx, ebx
shr edx, 8
bsr eax, edx
lea ecx, [eax+7]
mov edx, ebx
shr edx, cl
and edx, 1
lea ecx, [edx+eax*2]
 
; X->index = I;
mov dword [esi+28], ecx
 
; X->child[0] = X->child[1] = 0;
and dword [esi+20], 0
and dword [esi+16], 0
 
; H = &ms.treebins[I];
 
mov eax, ecx
lea edx, [mst.treebins+eax*4]
 
; if (!(ms.treemap & 1<<I))
bt [mst.treemap], ecx
jc .tree
 
; ms.treemap |= 1<<I;
bts [mst.treemap], ecx
; *H = X;
mov dword [edx], esi
jmp .done
.tree:
 
; T = *H;
mov edx, [edx]
 
; K = S << leftshift_for_tree_index(I);
mov eax, ecx
shr eax, 1
sub ecx, 31
mov edi, 37
sub edi, eax
neg ecx
sbb ecx, ecx
and ecx, edi
mov eax, ebx
shl eax, cl ;eax= K
 
jmp .loop
.not_eq_size:
 
; C = &(T->child[(K >> 31) & 1]);
mov ecx, eax
shr ecx, 31
lea ecx, [edx+ecx*4+16]
 
; K <<= 1;
; if (*C != 0)
mov edi, [ecx]
add eax, eax
test edi, edi
jz .insert_child
 
; T = *C;
mov edx, edi
.loop:
 
; for (;;)
; if ((T->head & ~INUSE_BITS) != S)
 
mov ecx, [edx+4]
and ecx, not 3
cmp ecx, ebx
jne .not_eq_size
 
; F = T->fd;
mov eax, [edx+8]
 
; T->fd = F->bk = X;
mov [eax+12], esi
mov [edx+8], esi
 
; X->fd = F;
; X->bk = T;
; X->parent = 0;
 
and dword [esi+24], 0
mov [esi+8], eax
mov [esi+12], edx
ret
.insert_child:
 
; *C = X;
mov [ecx], esi
.done:
 
; X->parent = T;
mov [esi+24], edx
 
; X->fd = X->bk = X;
mov [esi+12], esi
mov [esi+8], esi
ret
 
 
; param
; edx= chunk
 
unlink_large_chunk:
 
mov eax, [edx+12]
cmp eax, edx
push edi
mov edi, [edx+24]
je @F
 
mov ecx, [edx+8] ;F = X->fd
mov [ecx+12], eax ;F->bk = R;
mov [eax+8], ecx ;R->fd = F
jmp .parent
@@:
mov eax, [edx+20]
test eax, eax
push esi
lea esi, [edx+20]
jne .loop
 
mov eax, [edx+16]
test eax, eax
lea esi, [edx+16]
je .l2
.loop:
cmp dword [eax+20], 0
lea ecx, [eax+20]
jne @F
 
cmp dword [eax+16], 0
lea ecx, [eax+16]
je .l1
@@:
mov eax, [ecx]
mov esi, ecx
jmp .loop
.l1:
mov dword [esi], 0
.l2:
pop esi
.parent:
test edi, edi
je .done
 
mov ecx, [edx+28]
cmp edx, [mst.treebins+ecx*4]
lea ecx, [mst.treebins+ecx*4]
jne .l3
 
test eax, eax
mov [ecx], eax
jne .l5
 
mov ecx, [edx+28]
btr [mst.treemap], ecx
pop edi
ret
.l3:
cmp [edi+16], edx
jne @F
 
mov [edi+16], eax
jmp .l4
@@:
mov [edi+20], eax
.l4:
test eax, eax
je .done
.l5:
mov [eax+24], edi
mov ecx, [edx+16]
test ecx, ecx
je .l6
 
mov [eax+16], ecx
mov [ecx+24], eax
.l6:
mov edx, [edx+20]
test edx, edx
je .done
 
mov [eax+20], edx
mov [edx+24], eax
.done:
pop edi
ret
 
; param
; esi= nb
 
malloc_small:
push ebp
mov ebp, esi
 
push edi
 
bsf eax,[mst.treemap]
mov ecx, [mst.treebins+eax*4]
 
; rsize = (t->head & ~INUSE_BITS) - nb;
 
mov edi, [ecx+4]
and edi, -4
sub edi, esi
.loop:
mov ebx, ecx
.loop_1:
 
; while ((t = leftmost_child(t)) != 0)
 
mov eax, [ecx+16]
test eax, eax
jz @F
mov ecx, eax
jmp .l1
@@:
mov ecx, [ecx+20]
.l1:
test ecx, ecx
jz .unlink
 
; trem = (t->head & ~INUSE_BITS) - nb;
 
mov eax, [ecx+4]
and eax, -4
sub eax, ebp
 
; if (trem < rsize)
 
cmp eax, edi
jae .loop_1
 
; rsize = trem;
 
mov edi, eax
jmp .loop
.unlink:
 
 
; r = chunk_plus_offset((mchunkptr)v, nb);
; unlink_large_chunk(v);
 
mov edx, ebx
lea esi, [ebx+ebp]
call unlink_large_chunk
 
; if (rsize < 16)
 
cmp edi, 16
jae .split
 
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
 
lea ecx, [edi+ebp]
 
; (v+rsize + nb)->head |= PINUSE_BIT;
 
add edi, ebx
lea eax, [edi+ebp+4]
pop edi
or ecx, 3
mov [ebx+4], ecx
or dword [eax], 1
pop ebp
 
lea eax, [ebx+8]
ret
.split:
 
; v->head = nb|PINUSE_BIT|CINUSE_BIT;
; r->head = rsize|PINUSE_BIT;
; (r+rsize)->prev_foot = rsize;
 
or ebp, 3
mov edx, edi
or edx, 1
 
cmp edi, 256
mov [ebx+4], ebp
mov [esi+4], edx
mov [esi+edi], edi
jae .large
 
shr edi, 3
bts [mst.smallmap], edi
 
mov eax, edi
shl eax, 4
add eax, mst.smallbins
 
mov edx, [eax+8]
mov [eax+8], esi
mov [edx+12], esi
pop edi
mov [esi+12], eax
mov [esi+8], edx
pop ebp
lea eax, [ebx+8]
ret
.large:
lea eax, [ebx+8]
push eax
mov ebx, edi
call insert_large_chunk
pop eax
pop edi
pop ebp
ret
 
 
; param
; esi= nb
 
malloc_large:
.idx equ esp+4
.rst equ esp
 
push ebp
push esi
push edi
sub esp, 8
; v = 0;
; rsize = -nb;
 
mov edi, esi
mov ebx, esi
xor ebp, ebp
neg edi
 
; idx = compute_tree_index(nb);
 
mov edx, esi
shr edx, 8
bsr eax, edx
lea ecx, [eax+7]
shr esi, cl
and esi, 1
lea ecx, [esi+eax*2]
mov [.idx], ecx
 
; if ((t = ms.treebins[idx]) != 0)
 
mov eax, [mst.treebins+ecx*4]
test eax, eax
jz .l3
 
; sizebits = nb << leftshift_for_tree_index(idx);
 
cmp ecx, 31
jne @F
xor ecx, ecx
jmp .l1
@@:
mov edx, ecx
shr edx, 1
mov ecx, 37
sub ecx, edx
.l1:
mov edx, ebx
shl edx, cl
 
; rst = 0;
mov [.rst], ebp
.loop:
 
; trem = (t->head & ~INUSE_BITS) - nb;
 
mov ecx, [eax+4]
and ecx, -4
sub ecx, ebx
 
; if (trem < rsize)
 
cmp ecx, edi
jae @F
; v = t;
; if ((rsize = trem) == 0)
 
test ecx, ecx
mov ebp, eax
mov edi, ecx
je .l2
@@:
 
; rt = t->child[1];
 
mov ecx, [eax+20]
 
; t = t->child[(sizebits >> 31) & 1];
 
mov esi, edx
shr esi, 31
 
; if (rt != 0 && rt != t)
 
test ecx, ecx
mov eax, [eax+esi*4+16]
jz @F
cmp ecx, eax
jz @F
 
; rst = rt;
mov [.rst], ecx
@@:
; if (t == 0)
 
test eax, eax
jz @F
 
; sizebits <<= 1;
 
add edx, edx
jmp .loop
@@:
; t = rst;
mov eax, [.rst]
.l2:
; if (t == 0 && v == 0)
 
test eax, eax
jne .l4
test ebp, ebp
jne .l7
mov ecx, [.idx]
.l3:
 
; leftbits = (-1<<idx) & ms.treemap;
; if (leftbits != 0)
 
or edx, -1
shl edx, cl
and edx, [mst.treemap]
jz @F
 
bsf eax, edx
; t = ms.treebins[i];
mov eax, [mst.treebins+eax*4]
@@:
 
; while (t != 0)
test eax, eax
jz .l5
.l4:
 
; trem = (t->head & ~INUSE_BITS) - nb;
 
mov ecx, [eax+4]
and ecx, -4
sub ecx, ebx
 
; if (trem < rsize)
 
cmp ecx, edi
jae @F
; rsize = trem;
 
mov edi, ecx
; v = t;
mov ebp, eax
@@:
 
; t = leftmost_child(t);
 
mov ecx, [eax+16]
test ecx, ecx
je @F
mov eax, ecx
jmp .l6
@@:
mov eax, [eax+20]
.l6:
 
; while (t != 0)
 
test eax, eax
jne .l4
.l5:
 
; if (v != 0)
 
test ebp, ebp
jz .done
.l7:
 
; r = chunk_plus_offset((mchunkptr)v, nb);
; unlink_large_chunk(v);
 
mov edx, ebp
lea esi, [ebx+ebp]
call unlink_large_chunk
 
; if (rsize < 16)
 
cmp edi, 16
jae .large
 
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT;
 
lea ecx, [edi+ebx]
 
; (v+rsize + nb)->head |= PINUSE_BIT;
 
add edi, ebp
lea eax, [edi+ebx+4]
or ecx, 3
mov [ebp+4], ecx
or dword [eax], 1
lea eax, [ebp+8]
add esp, 8
pop edi
pop esi
pop ebp
ret
.large:
 
; v->head = nb|PINUSE_BIT|CINUSE_BIT;
; r->head = rsize|PINUSE_BIT;
 
mov edx, edi
or ebx, 3
mov [ebp+4], ebx
or edx, 1
mov [esi+4], edx
 
; (r+rsize)->prev_foot = rsize;
; insert_large_chunk((tchunkptr)r, rsize);
 
mov [esi+edi], edi
mov eax, edi
mov ecx, esi
call insert_chunk
 
lea eax, [ebp+8]
add esp, 8
pop edi
pop esi
pop ebp
ret
.done:
add esp, 8
pop edi
pop esi
pop ebp
xor eax, eax
ret
 
init_malloc:
 
stdcall kernel_alloc, 0x40000
 
mov [mst.top], eax
mov [mst.topsize], 128*1024
mov dword [eax+4], (128*1024) or 1
mov eax, mst.smallbins
@@:
mov [eax+8], eax
mov [eax+12], eax
add eax, 16
cmp eax, mst.smallbins+512
jb @B
 
ret
 
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/test_malloc.asm
0,0 → 1,223
; Tests of malloc()/free() from the kernel heap.
; This file is not included in the kernel, it is just test application.
use32
db 'MENUET01'
dd 1, start, i_end, mem, mem, 0, 0
 
start:
; Zero-initialize uglobals (as in kernel at boot)
mov ecx, (zeroend - zerostart + 3) / 4
xor eax, eax
mov edi, zerostart
rep stosd
; Initialize small heap (as in kernel at boot)
call init_malloc
; Run tests
call run_test1
call run_test2
call run_test3
; All is OK, return
or eax, -1
int 0x40
 
run_test1:
; basic test
mov eax, 1
call malloc_with_test
mov byte [eax], 0xDD
mov esi, eax
mov eax, 1
call malloc_with_test
cmp byte [esi], 0xDD
jnz memory_destroyed
mov byte [eax], 0xEE
xchg eax, esi
call free
cmp byte [esi], 0xEE
jnz memory_destroyed
xchg eax, esi
call free
ret
 
run_test2:
ret
 
run_test3:
; 1024000 times run random operation.
; Randomly select malloc(random size from 1 to 1023)
; or free(random of previously allocated areas)
mov edi, 0x12345678
xor esi, esi ; 0 areas allocated
mov ebx, 1024000
.loop:
imul edi, 1103515245
add edi, 12345
mov eax, edi
shr eax, 16
test ebx, 64
jz .prefer_free
.prefer_malloc:
test eax, 3
jz .free
jmp @f
.prefer_free:
test eax, 3
jnz .free
@@:
shr eax, 2
and eax, 1023
jz .loop
push ebx
push eax
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8], eax
call malloc_with_test
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8+4], eax
; inc [saved_state_num]
pop ecx
pop ebx
inc esi
push ecx eax
push edi
mov edi, eax
mov eax, esi
rep stosb
pop edi
jmp .common
.free:
test esi, esi
jz .loop
xor edx, edx
div esi
sub edx, esi
neg edx
dec edx
mov eax, [esp+edx*8]
; mov ecx, [saved_state_num]
; mov [saved_state+ecx*8], -1
; mov [saved_state+ecx*8+4], eax
; inc [saved_state_num]
mov ecx, [esp+edx*8+4]
push edi eax
mov edi, eax
mov al, [edi]
repz scasb
jnz memory_destroyed
pop eax edi
push ebx edx
call free
pop edx ebx
dec esi
pop eax ecx
push edi
lea edi, [esp+4]
@@:
dec edx
js @f
xchg eax, [edi]
xchg ecx, [edi+4]
add edi, 8
jmp @b
@@:
pop edi
.common:
dec ebx
jnz .loop
@@:
dec esi
js @f
pop eax ecx
call free
jmp @b
@@:
ret
 
malloc_with_test:
; calls malloc() and checks returned value
call malloc
test eax, eax
jz generic_malloc_fail
call check_mutex
call check_range
ret
 
; Stubs for kernel procedures used by heap code
wait_mutex:
inc dword [ebx]
ret
 
kernel_alloc:
cmp dword [esp+4], bufsize
jnz error1
mov eax, buffer
ret 4
 
macro $Revision [args]
{
}
 
; Error handlers
error1:
mov eax, 1
jmp error_with_code
 
generic_malloc_fail:
mov eax, 2
jmp error_with_code
 
check_mutex:
cmp [mst.mutex], 0
jnz @f
ret
@@:
mov eax, 3
jmp error_with_code
 
check_range:
cmp eax, buffer
jb @f
cmp eax, buffer+bufsize
jae @f
ret
@@:
mov eax, 4
jmp error_with_code
 
memory_destroyed:
mov eax, 5
jmp error_with_code
 
error_with_code:
mov edx, saved_state_num
; eax = error code
; 1 signals error in testing code (wrong bufsize)
; 2 = malloc() returned NULL
; 3 = mutex not released
; 4 = weird returned value from malloc()
; 5 = memory destroyed by malloc() or free()
int3 ; simplest way to report error
jmp $-1 ; just in case
 
; Include main heap code
include '../proc32.inc'
include '../const.inc'
include 'malloc.inc'
 
i_end:
 
align 4
zerostart:
mst MEM_STATE
 
align 16
bufsize = 0x40000 ; change if malloc.inc changes
buffer rb bufsize
zeroend:
 
saved_state_num dd ?
saved_state rd 0x10000
 
align 4
rb 0x10000 ; for stack
mem:
/kernel/branches/Kolibri-acpi/core/ext_lib.inc
0,0 → 1,320
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;============================================================================
;
; External kernel dependencies (libraries) loading
;
;============================================================================
 
$Revision$
 
if 0
; The code currently does not work. Kill "if 0/end if" only after correcting
; to current kernel (dll.inc).
macro library [name,fname]
{
forward
dd __#name#_library_table__,__#name#_library_name__
common
dd 0
forward
__#name#_library_name__ db fname,0
}
 
macro import lname,[name,sname]
{
common
align 4
__#lname#_library_table__:
forward
name dd __#name#_import_name__
common
dd 0
forward
__#name#_import_name__ db sname,0
}
 
macro export [name,sname]
{
align 4
forward
dd __#name#_export_name__,name
common
dd 0
forward
__#name#_export_name__ db sname,0
}
 
 
 
align 4 ; loading library (use kernel functions)
proc load_k_library stdcall, file_name:dword
locals
coff dd ?
sym dd ?
strings dd ?
img_size dd ?
img_base dd ?
exports dd ?
endl
 
cli
 
stdcall load_file, [file_name]
test eax, eax
jz .fail
 
mov [coff], eax
movzx ecx, [eax+CFH.nSections]
xor ebx, ebx
 
lea edx, [eax+20]
@@:
add ebx, [edx+CFS.SizeOfRawData]
add ebx, 15
and ebx, not 15
add edx, COFF_SECTION_SIZE
dec ecx
jnz @B
mov [img_size], ebx
 
stdcall kernel_alloc, [img_size]
 
test eax, eax
jz .fail
mov [img_base], eax
 
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, [img_base]
lea eax, [edx+20]
@@:
mov [eax+CFS.VirtualAddress], edi
mov esi, [eax+CFS.PtrRawData]
test esi, esi
jnz .copy
add edi, [eax+CFS.SizeOfRawData]
jmp .next
.copy:
add esi, edx
mov ecx, [eax+CFS.SizeOfRawData]
cld
rep movsb
.next:
add edi, 15
and edi, not 15
add eax, COFF_SECTION_SIZE
dec ebx
jnz @B
 
mov ebx, [edx+CFH.pSymTable]
add ebx, edx
mov [sym], ebx
mov ecx, [edx+CFH.nSymbols]
add ecx,ecx
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
add ecx, [sym]
mov [strings], ecx
 
lea eax, [edx+20]
 
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
[strings], dword 0
test eax, eax
jnz @F
 
@@:
mov edx, [coff]
movzx ebx, [edx+CFH.nSections]
mov edi, 0
lea eax, [edx+20]
@@:
add [eax+CFS.VirtualAddress], edi ;patch user space offset
add eax, COFF_SECTION_SIZE
dec ebx
jnz @B
 
add edx, 20
stdcall fix_coff_relocs, [coff], edx, [sym]
 
mov ebx, [coff]
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS
mov [exports], eax
 
stdcall kernel_free, [coff]
 
mov eax, [exports]
ret
.fail:
xor eax, eax
ret
endp
 
 
proc dll.Load, import_table:dword
mov esi,[import_table]
.next_lib: mov edx,[esi]
or edx,edx
jz .exit
push esi
 
mov edi,s_libname
 
mov al, '/'
stosb
mov esi,sysdir_path
@@: lodsb
stosb
or al,al
jnz @b
dec edi
mov [edi], dword '/lib'
mov [edi+4],byte '/'
add edi,5
pop esi
push esi
mov esi,[esi+4]
@@: lodsb
stosb
or al,al
jnz @b
 
pushad
stdcall load_k_library,s_libname
mov [esp+28],eax
popad
or eax,eax
jz .fail
stdcall dll.Link,eax,edx
stdcall dll.Init,[eax+4]
pop esi
add esi,8
jmp .next_lib
.exit: xor eax,eax
ret
.fail: add esp,4
xor eax,eax
inc eax
ret
endp
 
proc dll.Link, exp:dword,imp:dword
push eax
mov esi,[imp]
test esi,esi
jz .done
.next: lodsd
test eax,eax
jz .done
stdcall dll.GetProcAddress,[exp],eax
or eax,eax
jz @f
mov [esi-4],eax
jmp .next
@@: mov dword[esp],0
.done: pop eax
ret
endp
 
proc dll.Init, dllentry:dword
pushad
mov eax,mem.Alloc
mov ebx,mem.Free
mov ecx,mem.ReAlloc
mov edx,dll.Load
stdcall [dllentry]
popad
ret
endp
 
proc dll.GetProcAddress, exp:dword,sz_name:dword
mov edx,[exp]
.next: test edx,edx
jz .end
stdcall strncmp,[edx],[sz_name], dword -1
test eax,eax
jz .ok
add edx,8
jmp .next
.ok: mov eax,[edx+4]
.end: ret
endp
 
;-----------------------------------------------------------------------------
proc mem.Alloc size ;/////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------
push ebx ecx
; mov eax,[size]
; lea ecx,[eax+4+4095]
; and ecx,not 4095
; stdcall kernel_alloc, ecx
; add ecx,-4
; mov [eax],ecx
; add eax,4
 
stdcall kernel_alloc, [size]
 
pop ecx ebx
ret
endp
 
;-----------------------------------------------------------------------------
proc mem.ReAlloc mptr,size;///////////////////////////////////////////////////
;-----------------------------------------------------------------------------
push ebx ecx esi edi eax
mov eax,[mptr]
mov ebx,[size]
or eax,eax
jz @f
lea ecx,[ebx+4+4095]
and ecx,not 4095
add ecx,-4
cmp ecx,[eax-4]
je .exit
@@: mov eax,ebx
call mem.Alloc
xchg eax,[esp]
or eax,eax
jz .exit
mov esi,eax
xchg eax,[esp]
mov edi,eax
mov ecx,[esi-4]
cmp ecx,[edi-4]
jbe @f
mov ecx,[edi-4]
@@: add ecx,3
shr ecx,2
cld
rep movsd
xchg eax,[esp]
call mem.Free
.exit:
pop eax edi esi ecx ebx
ret
endp
 
;-----------------------------------------------------------------------------
proc mem.Free mptr ;//////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------
; mov eax,[mptr]
; or eax,eax
; jz @f
; push ebx ecx
; lea ecx,[eax-4]
; stdcall kernel_free, ecx
; pop ecx ebx
; @@: ret
stdcall kernel_free, [mptr]
ret
endp
 
uglobal
s_libname db 64 dup (0)
endg
end if
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/conf_lib.inc
0,0 → 1,297
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;-------------------------------------------------------------------------
;Loading configuration from ini file
; {SPraid.simba}
;-------------------------------------------------------------------------
 
$Revision$
 
iglobal
conf_path_sect: db 'path',0
 
conf_fname db '/sys/sys.conf',0
endg
; set soke kernel configuration
proc set_kernel_conf
locals
par db 30 dup(?)
endl
 
pushad
;[gui]
;mouse_speed
 
lea eax,[par]
push eax
invoke ini.get_str,conf_fname, ugui, ugui_mouse_speed,\
eax,30, ugui_mouse_speed_def
pop eax
stdcall strtoint,eax
mov [mouse_speed_factor], ax
 
;mouse_delay
lea eax,[par]
push eax
invoke ini.get_str,conf_fname, ugui, ugui_mouse_delay,\
eax,30, ugui_mouse_delay_def
pop eax
stdcall strtoint,eax
mov [mouse_delay], eax
 
 
;midibase
lea eax,[par]
push eax
invoke ini.get_str,conf_fname, udev, udev_midibase, eax,30, udev_midibase_def
pop eax
stdcall strtoint,eax
 
cmp eax, 0x100
jb @f
cmp eax, 0x10000
jae @f
mov [midi_base], ax
mov [mididp], eax
inc eax
mov [midisp], eax
@@:
popad
ret
endp
iglobal
ugui db 'gui',0
ugui_mouse_speed db 'mouse_speed',0
ugui_mouse_speed_def db '2',0
ugui_mouse_delay db 'mouse_delay',0
ugui_mouse_delay_def db '0x00A',0
 
udev db 'dev',0
udev_midibase db 'midibase',0
udev_midibase_def db '0x320',0
endg
;set up netvork configuration
proc set_network_conf
locals
par db 30 dup(?)
endl
pushad
 
;[net]
;active
lea eax,[par]
invoke ini.get_int,conf_fname, unet, unet_active, 0
or eax,eax
jz .do_not_set_net
mov eax, [stack_config]
and eax, 0xFFFFFF80
add eax, 3
mov [stack_config], eax
call ash_eth_enable
 
;addr
lea eax,[par]
push eax
invoke ini.get_str,conf_fname, unet, unet_addr, eax,30, unet_def
pop eax
stdcall do_inet_adr,eax
mov [stack_ip], eax
 
;mask
lea eax,[par]
push eax
invoke ini.get_str,conf_fname, unet, unet_mask, eax,30, unet_def
pop eax
stdcall do_inet_adr,eax
mov [subnet_mask], eax
 
;gate
lea eax,[par]
push eax
invoke ini.get_str,conf_fname, unet, unet_gate, eax,30, unet_def
pop eax
stdcall do_inet_adr,eax
mov [gateway_ip], eax
.do_not_set_net:
popad
ret
 
 
endp
iglobal
unet db 'net',0
unet_active db 'active',0
unet_addr db 'addr',0
unet_mask db 'mask',0
unet_gate db 'gate',0
unet_def db 0
endg
; convert string to DWord
proc strtoint stdcall,strs
pushad
 
mov eax,[strs]
inc eax
mov bl,[eax]
cmp bl,'x'
je .hex
cmp bl,'X'
je .hex
jmp .dec
.hex:
inc eax
stdcall strtoint_hex,eax
jmp .exit
.dec:
dec eax
stdcall strtoint_dec,eax
.exit:
mov [esp+28],eax
popad
ret
endp
 
; convert string to DWord for decimal value
proc strtoint_dec stdcall,strs
pushad
xor edx,edx
; ¯®¨áª ª®­æ 
mov esi,[strs]
@@:
lodsb
or al,al
jnz @b
mov ebx,esi
mov esi,[strs]
dec ebx
sub ebx,esi
mov ecx,1
 
@@:
dec ebx
or ebx,ebx
jz @f
imul ecx,ecx,10 ; ¯®à冷ª
jmp @b
@@:
 
xchg ebx,ecx
 
 
xor ecx,ecx
 
 
@@:
xor eax,eax
lodsb
cmp al,0
je .eend
 
sub al,30h
imul ebx
add ecx,eax
push ecx
xchg eax,ebx
mov ecx,10
div ecx
xchg eax,ebx
pop ecx
jmp @b
 
.eend:
mov [esp+28],ecx
popad
ret
endp
 
;convert string to DWord for hex value
proc strtoint_hex stdcall,strs
pushad
xor edx,edx
 
mov esi,[strs]
mov ebx,1
add esi,1
 
@@:
lodsb
or al,al
jz @f
shl ebx,4
jmp @b
@@:
xor ecx,ecx
mov esi,[strs]
 
@@:
xor eax,eax
lodsb
cmp al,0
je .eend
 
cmp al,'a'
jae .bm
cmp al,'A'
jae .bb
jmp .cc
.bm: ; 57h
sub al,57h
jmp .do
 
.bb: ; 37h
sub al,37h
jmp .do
 
.cc: ; 30h
sub al,30h
 
.do:
imul ebx
add ecx,eax
shr ebx,4
 
jmp @b
 
.eend:
mov [esp+28],ecx
popad
ret
endp
 
 
; convert string to DWord for IP addres
proc do_inet_adr stdcall,strs
pushad
 
mov esi,[strs]
mov ebx,0
.next:
push esi
@@:
lodsb
or al,al
jz @f
cmp al,'.'
jz @f
jmp @b
@@:
mov cl, al
mov [esi-1],byte 0
;pop eax
call strtoint_dec
rol eax,24
ror ebx,8
add ebx,eax
or cl,cl
jz @f
jmp .next
@@:
mov [esp+28],ebx
popad
ret
endp
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/fpu.inc
0,0 → 1,183
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
init_fpu:
clts
fninit
 
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
 
mov ebx, cr4
mov ecx, cr0
or ebx, CR4_OSFXSR+CR4_OSXMMEXPT
mov cr4, ebx
 
and ecx, not (CR0_MP+CR0_EM)
or ecx, CR0_NE
mov cr0, ecx
 
mov dword [esp-4], SSE_INIT
ldmxcsr [esp-4]
 
xorps xmm0, xmm0
xorps xmm1, xmm1
xorps xmm2, xmm2
xorps xmm3, xmm3
xorps xmm4, xmm4
xorps xmm5, xmm5
xorps xmm6, xmm6
xorps xmm7, xmm7
fxsave [fpu_data] ;[eax]
ret
.no_SSE:
mov ecx, cr0
and ecx, not CR0_EM
or ecx, CR0_MP+CR0_NE
mov cr0, ecx
fnsave [fpu_data]
ret
 
; param
; eax= 512 bytes memory area
 
align 4
fpu_save:
push ecx
push esi
push edi
 
pushfd
cli
 
clts
mov edi, eax
 
mov ecx, [fpu_owner]
mov esi, [CURRENT_TASK]
cmp ecx, esi
jne .save
 
call save_context
jmp .exit
.save:
mov [fpu_owner], esi
 
shl ecx, 8
mov eax, [ecx+SLOT_BASE+APPDATA.fpu_state]
 
call save_context
 
shl esi, 8
mov esi, [esi+SLOT_BASE+APPDATA.fpu_state]
mov ecx, 512/4
cld
rep movsd
fninit
.exit:
popfd
pop edi
pop esi
pop ecx
ret
 
align 4
save_context:
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
 
fxsave [eax]
ret
.no_SSE:
fnsave [eax]
ret
 
align 4
fpu_restore:
push ecx
push esi
 
mov esi, eax
 
pushfd
cli
 
mov ecx, [fpu_owner]
mov eax, [CURRENT_TASK]
cmp ecx, eax
jne .copy
 
clts
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
 
fxrstor [esi]
popfd
pop esi
pop ecx
ret
.no_SSE:
fnclex ;fix possible problems
frstor [esi]
popfd
pop esi
pop ecx
ret
.copy:
shl eax, 8
mov edi, [eax+SLOT_BASE+APPDATA.fpu_state]
mov ecx, 512/4
cld
rep movsd
popfd
pop esi
pop ecx
ret
 
align 4
except_7: ;#NM exception handler
save_ring3_context
clts
mov ax, app_data ;
mov ds, ax
mov es, ax
 
mov ebx, [fpu_owner]
cmp ebx, [CURRENT_TASK]
je .exit
 
shl ebx, 8
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state]
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
 
fxsave [eax]
mov ebx, [CURRENT_TASK]
mov [fpu_owner], ebx
shl ebx, 8
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state]
fxrstor [eax]
.exit:
restore_ring3_context
iret
 
.no_SSE:
fnsave [eax]
mov ebx, [CURRENT_TASK]
mov [fpu_owner], ebx
shl ebx, 8
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state]
frstor [eax]
restore_ring3_context
iret
 
iglobal
fpu_owner dd 0
endg
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/export.inc
0,0 → 1,39
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
; Macroinstruction for making export section
 
 
macro export dllname,[label,string]
{ common
local module,addresses,names,ordinal,count
count = 0
forward
count = count+1
common
dd 0,0,0, (module-OS_BASE) , 1
dd count,count,(addresses-OS_BASE),(names-OS_BASE),(ordinal-OS_BASE)
addresses:
forward
dd (label-OS_BASE)
common
names:
forward
local name
dd (name-OS_BASE)
common
ordinal: count = 0
forward
dw count
count = count+1
common
module db dllname,0
forward
name db string,0
}
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/string.inc
0,0 → 1,188
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; Author: Kees J. Bot 1 Jan 1994 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; size_t strncat(char *s1, const char *s2, size_t n)
; Append string s2 to s1.
 
; char *strchr(const char *s, int c)
 
 
; int strncmp(const char *s1, const char *s2, size_t n)
; Compare two strings.
 
; char *strncpy(char *s1, const char *s2, size_t n)
; Copy string s2 to s1.
 
; size_t strnlen(const char *s, size_t n)
; Return the length of a string.
 
; proc strrchr stdcall, s:dword, c:dword
; Look for the last occurrence a character in a string.
 
proc strncat stdcall, s1:dword, s2:dword, n:dword
push esi
push edi
mov edi, [s1] ; String s1
mov edx, [n] ; Maximum length
 
mov ecx, -1
xor al, al ; Null byte
cld
repne scasb ; Look for the zero byte in s1
dec edi ; Back one up (and clear 'Z' flag)
push edi ; Save end of s1
mov edi, [s2] ; edi = string s2
mov ecx, edx ; Maximum count
repne scasb ; Look for the end of s2
jne @F
inc ecx ; Exclude null byte
@@:
sub edx, ecx ; Number of bytes in s2
mov ecx, edx
mov esi, [s2] ; esi = string s2
pop edi ; edi = end of string s1
rep movsb ; Copy bytes
stosb ; Add a terminating null
mov eax, [s1] ; Return s1
pop edi
pop esi
ret
endp
 
align 4
proc strncmp stdcall, s1:dword, s2:dword, n:dword
 
push esi
push edi
mov ecx, [n]
test ecx, ecx ; Max length is zero?
je .done
 
mov esi, [s1] ; esi = string s1
mov edi, [s2] ; edi = string s2
cld
.compare:
cmpsb ; Compare two bytes
jne .done
cmp byte [esi-1], 0 ; End of string?
je .done
dec ecx ; Length limit reached?
jne .compare
.done:
seta al ; al = (s1 > s2)
setb ah ; ah = (s1 < s2)
sub al, ah
movsx eax, al ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1
pop edi
pop esi
ret
endp
 
align 4
proc strncpy stdcall, s1:dword, s2:dword, n:dword
 
push esi
push edi
 
mov ecx, [n] ; Maximum length
mov edi, [s2] ; edi = string s2
xor al, al ; Look for a zero byte
mov edx, ecx ; Save maximum count
cld
repne scasb ; Look for end of s2
sub edx, ecx ; Number of bytes in s2 including null
xchg ecx, edx
mov esi, [s2] ; esi = string s2
mov edi, [s1] ; edi = string s1
rep movsb ; Copy bytes
 
mov ecx, edx ; Number of bytes not copied
rep stosb ; strncpy always copies n bytes by null padding
mov eax, [s1] ; Return s1
pop edi
pop esi
ret
endp
 
align 4
proc strnlen stdcall, s:dword, n:dword
 
push edi
mov edi, [s] ; edi = string
xor al, al ; Look for a zero byte
mov edx, ecx ; Save maximum count
cmp cl, 1 ; 'Z' bit must be clear if ecx = 0
cld
repne scasb ; Look for zero
jne @F
inc ecx ; Don't count zero byte
@@:
mov eax, edx
sub eax, ecx ; Compute bytes scanned
pop edi
ret
endp
 
align 4
proc strchr stdcall, s:dword, c:dword
push edi
cld
mov edi, [s] ; edi = string
mov edx, 16 ; Look at small chunks of the string
.next:
shl edx, 1 ; Chunks become bigger each time
mov ecx, edx
xor al, al ; Look for the zero at the end
repne scasb
pushf ; Remember the flags
sub ecx, edx
neg ecx ; Some or all of the chunk
sub edi, ecx ; Step back
mov eax, [c] ; The character to look for
repne scasb
je .found
popf ; Did we find the end of string earlier?
jne .next ; No, try again
xor eax, eax ; Return NULL
pop edi
ret
.found:
pop eax ; Get rid of those flags
lea eax, [edi-1] ; Address of byte found
pop edi
ret
 
endp
 
 
proc strrchr stdcall, s:dword, c:dword
push edi
mov edi, [s] ; edi = string
mov ecx, -1
xor al, al
cld
repne scasb ; Look for the end of the string
not ecx ; -1 - ecx = Length of the string + null
dec edi ; Put edi back on the zero byte
mov eax, [c] ; The character to look for
std ; Downwards search
repne scasb
cld ; Direction bit back to default
jne .fail
lea eax, [edi+1] ; Found it
pop edi
ret
.fail:
xor eax, eax ; Not there
pop edi
ret
endp
 
 
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core/sync.inc
0,0 → 1,119
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Synhronization for MenuetOS. ;;
;; Author: Halyavin Andrey, halyavin@land.ru ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
if ~defined sync_inc
sync_inc_fix:
sync_inc fix sync_inc_fix
 
;simplest mutex.
macro SimpleMutex name
{
; iglobal
name dd 0
name#.type = 1
; endg
}
macro WaitSimpleMutex name
{
local start_wait,ok
start_wait=$
cli
cmp [name],dword 0
jz ok
sti
call change_task
jmp start_wait
ok=$
push eax
mov eax,dword [TASK_BASE+second_base_address]
mov eax,[eax+TASKDATA.pid]
mov [name],eax
pop eax
sti
}
macro ReleaseSimpleMutex name
{
mov [name],dword 0
}
macro TryWaitSimpleMutex name ;result in eax and in flags
{
local ok,try_end
cmp [name],dword 0
jz ok
xor eax,eax
jmp try_end
ok=$
xor eax,eax
inc eax
try_end=$
}
macro SimpleCriticalSection name
{
; iglobal
name dd 0
dd 0
name#.type=2
; endg
}
macro WaitSimpleCriticalSection name
{
local start_wait,first_wait,inc_counter,end_wait
push eax
mov eax,[TASK_BASE+second_base_address]
mov eax,[eax+TASKDATA.pid]
start_wait=$
cli
cmp [name],dword 0
jz first_wait
cmp [name],eax
jz inc_counter
sti
call change_task
jmp start_wait
first_wait=$
mov [name],eax
mov [name+4],dword 1
jmp end_wait
inc_counter=$
inc dword [name+4]
end_wait=$
sti
pop eax
}
macro ReleaseSimpleCriticalSection name
{
local release_end
dec dword [name+4]
jnz release_end
mov [name],dword 0
release_end=$
}
macro TryWaitSimpleCriticalSection name ;result in eax and in flags
{
local ok,try_end
mov eax,[CURRENT_TASK+second_base_address]
mov eax,[eax+TASKDATA.pid]
cmp [name],eax
jz ok
cmp [name],0
jz ok
xor eax,eax
jmp try_end
ok=$
xor eax,eax
inc eax
try_end=$
}
_cli equ call MEM_HeapLock
_sti equ call MEM_HeapUnLock
end if
 
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/core
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/build.bat
0,0 → 1,142
@echo off
cls
set languages=en ru ge et
set drivers=com_mouse emu10k1x ensoniq fm801 infinity sis sound uart viasound vmode vt823(x)
set targets=all kernel drivers skins clean
 
call :Check_Target %1
for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2
call :Target_%target%
 
if ERRORLEVEL 0 goto Exit_OK
 
echo There was an error executing script.
echo For any help, please send a report.
pause
goto :eof
 
 
 
 
:Check_Lang
set res=%1
:Check_Lang_loop
for %%a in (%languages%) do if %%a==%res% set lang=%res%
if defined lang goto :eof
 
echo Language '%res%' is incorrect
echo Enter valid language [ %languages% ]:
 
set /P res=">
goto Check_Lang_loop
goto :eof
 
:Check_Target
set res=%1
:Check_Target_loop
for %%a in (%targets%) do if %%a==%res% set target=%res%
if defined target goto :eof
 
echo Target '%res%' is incorrect
echo Enter valid target [ %targets% ]:
 
set /P res=">
goto Check_Target_loop
goto :eof
 
 
:Target_kernel
echo *** building kernel with language '%lang%' ...
 
if not exist bin mkdir bin
echo lang fix %lang% > lang.inc
fasm -m 65536 kernel.asm bin\kernel.mnt
if not %errorlevel%==0 goto :Error_FasmFailed
erase lang.inc
goto :eof
 
 
:Target_all
call :Target_kernel
call :Target_drivers
call :Target_skins
goto :eof
 
 
:Target_drivers
echo *** building drivers ...
 
if not exist bin\drivers mkdir bin\drivers
cd drivers
for %%a in (%drivers%) do (
fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj
if not %errorlevel%==0 goto :Error_FasmFailed
)
cd ..
move bin\drivers\vmode.obj bin\drivers\vmode.mdr
 
 
kpack >nul 2>&1
 
if %errorlevel%==9009 goto :Error_KpackFailed
 
echo *
echo ##############################################
echo *
echo Kpack KolibriOS drivers?
echo *
 
set /P res=[y/n]?
 
if "%res%"=="y" (
 
echo *
echo Compressing system
 
echo *
for %%a in (bin\drivers\*.obj) do (
echo ================== kpack %%a
kpack %%a
if not %errorlevel%==0 goto :Error_KpackFailed
)
 
)
goto :eof
 
 
:Target_skins
echo *** building skins ...
 
if not exist bin\skins mkdir bin\skins
cd skin
fasm -m 65536 default.asm ..\bin\skins\default.skn
if not %errorlevel%==0 goto :Error_FasmFailed
cd ..
goto :eof
 
:Target_clean
echo *** cleaning ...
rmdir /S /Q bin
goto :Exit_OK
 
 
:Error_FasmFailed
echo error: fasm execution failed
erase lang.inc >nul 2>&1
echo.
pause
exit 1
 
:Error_KpackFailed
echo *** NOTICE ***
echo If you want to pack all applications you may
echo place "kpack" in accessible directory or system %PATH%.
echo You can get this tool from KolibriOS distribution kit.
pause
exit 1
 
:Exit_OK
echo.
echo all operations have been done
pause
exit 0
/kernel/branches/Kolibri-acpi/drivers/emu10k1x.asm
0,0 → 1,1166
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
format MS COFF
 
DEBUG equ 1
 
include 'proc32.inc'
include 'imports.inc'
 
API_VERSION equ 0x01000100
 
USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices
IRQ_REMAP equ 0
IRQ_LINE equ 0
 
 
;irq 0,1,2,8,12,13 ­¥¤®áâ㯭ë
; FEDCBA9876543210
VALID_IRQ equ 1100111011111000b
ATTCH_IRQ equ 0000111010100000b
 
if USE_COM_IRQ
ATTCH_IRQ equ 0000111010111000b
end if
 
CPU_FREQ equ 2600d
 
BIT0 EQU 0x00000001
BIT1 EQU 0x00000002
BIT5 EQU 0x00000020
BIT10 EQU 0x00000400
 
VID_Creative equ 0x1102
 
CTRL_CT0200 equ 0x0006 ; Dell OEM version (EMU10K1X)
 
 
CODEC_MASTER_VOL_REG equ 0x02
CODEC_AUX_VOL equ 0x04 ;
CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume
CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio
CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control
CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate
CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate
CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate
 
 
;EMU10K1(X) host controller registers set
;; common offsets
;; some definitions were borrowed from emu10k1 driver as they seem to be the same
;;**********************************************************************************************;;
;; PCI function 0 registers, address = <val> + PCIBASE0 ;;
;;**********************************************************************************************;;
 
PTR equ 0x00 ;; Indexed register set pointer register ;;
;; NOTE: The CHANNELNUM and ADDRESS words can ;;
;; be modified independently of each other. ;;
 
DATA equ 0x04 ;; Indexed register set data register ;;
 
IPR equ 0x08 ;; Global interrupt pending register ;;
;; Clear pending interrupts by writing a 1 to ;;
;; the relevant bits and zero to the other bits ;;
IPR_MIDITRANSBUFEMPTY equ 0x00000001 ;; MIDI UART transmit buffer empty ;;
IPR_MIDIRECVBUFEMPTY equ 0x00000002 ;; MIDI UART receive buffer empty ;;
IPR_CH_0_LOOP equ 0x00000800 ;; Channel 0 loop ;;
IPR_CH_0_HALF_LOOP equ 0x00000100 ;; Channel 0 half loop ;;
IPR_CAP_0_LOOP equ 0x00080000 ;; Channel capture loop ;;
IPR_CAP_0_HALF_LOOP equ 0x00010000 ;; Channel capture half loop ;;
 
INTE equ 0x0c ;; Interrupt enable register ;;
INTE_MIDITXENABLE equ 0x00000001 ;; Enable MIDI transmit-buffer-empty interrupts ;;
INTE_MIDIRXENABLE equ 0x00000002 ;; Enable MIDI receive-buffer-empty interrupts ;;
INTE_CH_0_LOOP equ 0x00000800 ;; Channel 0 loop ;;
INTE_CH_0_HALF_LOOP equ 0x00000100 ;; Channel 0 half loop ;;
INTE_CAP_0_LOOP equ 0x00080000 ;; Channel capture loop ;;
INTE_CAP_0_HALF_LOOP equ 0x00010000 ;; Channel capture half loop ;;
 
HCFG equ 0x14 ;; Hardware config register ;;
 
HCFG_LOCKSOUNDCACHE equ 0x00000008 ;; 1 = Cancel bustmaster accesses to soundcache ;;
;; NOTE: This should generally never be used. ;;
HCFG_AUDIOENABLE equ 0x00000001 ;; 0 = CODECs transmit zero-valued samples ;;
;; Should be set to 1 when the EMU10K1 is ;;
;; completely initialized. ;;
GPIO equ 0x18 ;; Defaults: 00001080-Analog, 00001000-SPDIF. ;;
 
 
AC97DATA equ 0x1c ;; AC97 register set data register (16 bit) ;;
 
AC97ADDRESS equ 0x1e ;; AC97 register set address register (8 bit) ;;
 
;;******************************************************************************************************;;
;; Emu10k1x pointer-offset register set, accessed through the PTR and DATA registers ;;
;;******************************************************************************************************;;
PLAYBACK_LIST_ADDR equ 0x00 ;; Base DMA address of a list of pointers to each period/size ;;
;; One list entry: 4 bytes for DMA address,
;; 4 bytes for period_size << 16.
;; One list entry is 8 bytes long.
;; One list entry for each period in the buffer.
;;
PLAYBACK_LIST_SIZE equ 0x01 ;; Size of list in bytes << 19. E.g. 8 periods -> 0x00380000 ;;
PLAYBACK_LIST_PTR equ 0x02 ;; Pointer to the current period being played ;;
PLAYBACK_DMA_ADDR equ 0x04 ;; Playback DMA addresss ;;
PLAYBACK_PERIOD_SIZE equ 0x05 ;; Playback period size ;;
PLAYBACK_POINTER equ 0x06 ;; Playback period pointer. Sample currently in DAC ;;
PLAYBACK_UNKNOWN1 equ 0x07
PLAYBACK_UNKNOWN2 equ 0x08
 
;; Only one capture channel supported ;;
CAPTURE_DMA_ADDR equ 0x10 ;; Capture DMA address ;;
CAPTURE_BUFFER_SIZE equ 0x11 ;; Capture buffer size ;;
CAPTURE_POINTER equ 0x12 ;; Capture buffer pointer. Sample currently in ADC ;;
CAPTURE_UNKNOWN equ 0x13
 
;; From 0x20 - 0x3f, last samples played on each channel ;;
 
TRIGGER_CHANNEL equ 0x40 ;; Trigger channel playback ;;
TRIGGER_CHANNEL_0 equ 0x00000001 ;; Trigger channel 0 ;;
TRIGGER_CHANNEL_1 equ 0x00000002 ;; Trigger channel 1 ;;
TRIGGER_CHANNEL_2 equ 0x00000004 ;; Trigger channel 2 ;;
TRIGGER_CAPTURE equ 0x00000100 ;; Trigger capture channel ;;
 
ROUTING equ 0x41 ;; Setup sound routing ? ;;
ROUTING_FRONT_LEFT equ 0x00000001
ROUTING_FRONT_RIGHT equ 0x00000002
ROUTING_REAR_LEFT equ 0x00000004
ROUTING_REAR_RIGHT equ 0x00000008
ROUTING_CENTER_LFE equ 0x00010000
 
SPCS0 equ 0x42 ;; SPDIF output Channel Status 0 register ;;
SPCS1 equ 0x43 ;; SPDIF output Channel Status 1 register ;;
SPCS2 equ 0x44 ;; SPDIF output Channel Status 2 register ;;
 
SPCS_CLKACCYMASK equ 0x30000000 ;; Clock accuracy ;;
SPCS_CLKACCY_1000PPM equ 0x00000000 ;; 1000 parts per million ;;
SPCS_CLKACCY_50PPM equ 0x10000000 ;; 50 parts per million ;;
SPCS_CLKACCY_VARIABLE equ 0x20000000 ;; Variable accuracy ;;
SPCS_SAMPLERATEMASK equ 0x0f000000 ;; Sample rate ;;
SPCS_SAMPLERATE_44 equ 0x00000000 ;; 44.1kHz sample rate ;;
SPCS_SAMPLERATE_48 equ 0x02000000 ;; 48kHz sample rate ;;
SPCS_SAMPLERATE_32 equ 0x03000000 ;; 32kHz sample rate ;;
SPCS_CHANNELNUMMASK equ 0x00f00000 ;; Channel number ;;
SPCS_CHANNELNUM_UNSPEC equ 0x00000000 ;; Unspecified channel number ;;
SPCS_CHANNELNUM_LEFT equ 0x00100000 ;; Left channel ;;
SPCS_CHANNELNUM_RIGHT equ 0x00200000 ;; Right channel ;;
SPCS_SOURCENUMMASK equ 0x000f0000 ;; Source number ;;
SPCS_SOURCENUM_UNSPEC equ 0x00000000 ;; Unspecified source number ;;
SPCS_GENERATIONSTATUS equ 0x00008000 ;; Originality flag (see IEC-958 spec) ;;
SPCS_CATEGORYCODEMASK equ 0x00007f00 ;; Category code (see IEC-958 spec) ;;
SPCS_MODEMASK equ 0x000000c0 ;; Mode (see IEC-958 spec) ;;
SPCS_EMPHASISMASK equ 0x00000038 ;; Emphasis ;;
SPCS_EMPHASIS_NONE equ 0x00000000 ;; No emphasis ;;
SPCS_EMPHASIS_50_15 equ 0x00000008 ;; 50/15 usec 2 channel ;;
SPCS_COPYRIGHT equ 0x00000004 ;; Copyright asserted flag -- do not modify ;;
SPCS_NOTAUDIODATA equ 0x00000002 ;; 0 = Digital audio, 1 = not audio ;;
SPCS_PROFESSIONAL equ 0x00000001 ;; 0 = Consumer (IEC-958), 1 = pro (AES3-1992) ;;
 
SPDIF_SELECT equ 0x45 ;; Enables SPDIF or Analogue outputs 0-Analogue, 0x700-SPDIF ;;
 
;; This is the MPU port on the card ;;
MUDATA equ 0x47
MUCMD equ 0x48
MUSTAT equ MUCMD
 
;; From 0x50 - 0x5f, last samples captured ;;
 
 
SRV_GETVERSION equ 0
DEV_PLAY equ 1
DEV_STOP equ 2
DEV_CALLBACK equ 3
DEV_SET_BUFF equ 4
DEV_NOTIFY equ 5
DEV_SET_MASTERVOL equ 6
DEV_GET_MASTERVOL equ 7
DEV_GET_INFO equ 8
 
struc AC_CNTRL ;AC controller base class
{ .bus dd ?
.devfn dd ?
 
.vendor dd ?
.dev_id dd ?
.pci_cmd dd ?
.pci_stat dd ?
 
.codec_io_base dd ?
.codec_mem_base dd ?
 
.ctrl_io_base dd ?
.ctrl_mem_base dd ?
.cfg_reg dd ?
.int_line dd ?
 
.vendor_ids dd ? ;vendor id string
.ctrl_ids dd ? ;hub id string
 
.buffer dd ?
 
.notify_pos dd ?
.notify_task dd ?
 
.lvi_reg dd ?
.ctrl_setup dd ?
.user_callback dd ?
.codec_read16 dd ?
.codec_write16 dd ?
 
.ctrl_read8 dd ?
.ctrl_read16 dd ?
.ctrl_read32 dd ?
 
.ctrl_write8 dd ?
.ctrl_write16 dd ?
.ctrl_write32 dd ?
}
 
struc CODEC ;Audio Chip base class
{
.chip_id dd ?
.flags dd ?
.status dd ?
 
.ac_vendor_ids dd ? ;ac vendor id string
.chip_ids dd ? ;chip model string
 
.shadow_flag dd ?
dd ?
 
.regs dw ? ; codec registers
.reg_master_vol dw ? ;0x02
.reg_aux_out_vol dw ? ;0x04
.reg_mone_vol dw ? ;0x06
.reg_master_tone dw ? ;0x08
.reg_beep_vol dw ? ;0x0A
.reg_phone_vol dw ? ;0x0C
.reg_mic_vol dw ? ;0x0E
.reg_line_in_vol dw ? ;0x10
.reg_cd_vol dw ? ;0x12
.reg_video_vol dw ? ;0x14
.reg_aux_in_vol dw ? ;0x16
.reg_pcm_out_vol dw ? ;0x18
.reg_rec_select dw ? ;0x1A
.reg_rec_gain dw ? ;0x1C
.reg_rec_gain_mic dw ? ;0x1E
.reg_gen dw ? ;0x20
.reg_3d_ctrl dw ? ;0X22
.reg_page dw ? ;0X24
.reg_powerdown dw ? ;0x26
.reg_ext_audio dw ? ;0x28
.reg_ext_st dw ? ;0x2a
.reg_pcm_front_rate dw ? ;0x2c
.reg_pcm_surr_rate dw ? ;0x2e
.reg_lfe_rate dw ? ;0x30
.reg_pcm_in_rate dw ? ;0x32
dw ? ;0x34
.reg_cent_lfe_vol dw ? ;0x36
.reg_surr_vol dw ? ;0x38
.reg_spdif_ctrl dw ? ;0x3A
dw ? ;0x3C
dw ? ;0x3E
dw ? ;0x40
dw ? ;0x42
dw ? ;0x44
dw ? ;0x46
dw ? ;0x48
dw ? ;0x4A
dw ? ;0x4C
dw ? ;0x4E
dw ? ;0x50
dw ? ;0x52
dw ? ;0x54
dw ? ;0x56
dw ? ;0x58
dw ? ;0x5A
dw ? ;0x5C
dw ? ;0x5E
.reg_page_0 dw ? ;0x60
.reg_page_1 dw ? ;0x62
.reg_page_2 dw ? ;0x64
.reg_page_3 dw ? ;0x66
.reg_page_4 dw ? ;0x68
.reg_page_5 dw ? ;0x6A
.reg_page_6 dw ? ;0x6C
.reg_page_7 dw ? ;0x6E
dw ? ;0x70
dw ? ;0x72
dw ? ;0x74
dw ? ;0x76
dw ? ;0x78
dw ? ;0x7A
.reg_vendor_id_1 dw ? ;0x7C
.reg_vendor_id_2 dw ? ;0x7E
 
 
.reset dd ? ;virual
.set_master_vol dd ?
}
 
struc CTRL_INFO
{ .pci_cmd dd ?
.irq dd ?
.glob_cntrl dd ?
.glob_sta dd ?
.codec_io_base dd ?
.ctrl_io_base dd ?
.codec_mem_base dd ?
.ctrl_mem_base dd ?
.codec_id dd ?
}
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
EVENT_NOTIFY equ 0x00000200
 
public START
public service_proc
public version
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .stop
 
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
call detect_controller
test eax, eax
jz .fail
 
if DEBUG
mov esi,[ctrl.vendor_ids]
call SysMsgBoardStr
mov esi, [ctrl.ctrl_ids]
call SysMsgBoardStr
end if
 
call init_controller
test eax, eax
jz .fail
 
call init_codec
test eax, eax
jz .fail
 
call setup_codec
 
mov esi, msgPrimBuff
call SysMsgBoardStr
call create_primary_buff
mov esi, msgDone
call SysMsgBoardStr
 
if IRQ_REMAP
pushf
cli
 
mov ebx, [ctrl.int_line]
in al, 0xA1
mov ah, al
in al, 0x21
test ebx, ebx
jz .skip
bts ax, bx ;mask old line
.skip:
bts ax, IRQ_LINE ;mask new ine
out 0x21, al
mov al, ah
out 0xA1, al
 
stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE ;remap IRQ
 
mov dx, 0x4d0 ;8259 ELCR1
in al, dx
bts ax, IRQ_LINE
out dx, al ;set level-triggered mode
mov [ctrl.int_line], IRQ_LINE
popf
mov esi, msgRemap
call SysMsgBoardStr
end if
 
mov eax, VALID_IRQ
mov ebx, [ctrl.int_line]
mov esi, msgInvIRQ
bt eax, ebx
jnc .fail_msg
mov eax, ATTCH_IRQ
mov esi, msgAttchIRQ
bt eax, ebx
jnc .fail_msg
 
stdcall AttachIntHandler, ebx, ac97_irq, dword 0
stdcall create
 
.reg:
stdcall RegService, sz_sound_srv, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
xor eax, eax
ret
.fail_msg:
call SysMsgBoardStr
xor eax, eax
ret
.stop:
call stop
xor eax, eax
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edi, [ioctl]
mov eax, [edi+io_code]
 
cmp eax, SRV_GETVERSION
jne @F
mov eax, [edi+output]
cmp [edi+out_size], 4
jne .fail
 
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
cmp eax, DEV_PLAY
jne @F
if DEBUG
mov esi, msgPlay
call SysMsgBoardStr
end if
call play
ret
@@:
cmp eax, DEV_STOP
jne @F
if DEBUG
mov esi, msgStop
call SysMsgBoardStr
end if
call stop
ret
@@:
cmp eax, DEV_CALLBACK
jne @F
mov ebx, [edi+input]
stdcall set_callback, [ebx]
ret
@@:
cmp eax, DEV_SET_MASTERVOL
jne @F
mov eax, [edi+input]
mov eax, [eax]
call set_master_vol ;eax= vol
ret
@@:
cmp eax, DEV_GET_MASTERVOL
jne @F
mov ebx, [edi+output]
stdcall get_master_vol, ebx
ret
@@:
cmp eax, DEV_GET_INFO
jne @F
mov ebx, [edi+output]
stdcall get_dev_info, ebx
ret
@@:
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
 
align 4
proc ac97_irq
locals
status dd 0
endl
 
; status = inl(chip->port + IPR);
mov edx, IPR
call [ctrl.ctrl_read32]
test eax, eax
jz @f
 
mov dword [status], eax
 
mov ebx, dword [buff_list]
cmp [ctrl.user_callback], 0
je @f
stdcall [ctrl.user_callback], ebx
@@:
mov eax, dword [status] ;; ack ;;
mov edx, IPR
call [ctrl.ctrl_write32]
ret
endp
 
 
align 4
proc create_primary_buff
 
stdcall KernelAlloc, 0x10000
mov [ctrl.buffer], eax
 
mov edi, eax
mov ecx, 0x10000/4
xor eax, eax
cld
rep stosd
 
mov eax, [ctrl.buffer]
call GetPgAddr
 
mov edi, pcmout_bdl
stosd
mov eax, 0x4000000
stosd
 
mov edi, buff_list
mov eax, [ctrl.buffer]
stosd ;1.]
 
mov eax, [ctrl.buffer]
call GetPgAddr
 
stdcall ptr_write, PLAYBACK_POINTER, 0, 0
stdcall ptr_write, PLAYBACK_UNKNOWN1, 0, 0
stdcall ptr_write, PLAYBACK_UNKNOWN2, 0, 0
stdcall ptr_write, PLAYBACK_DMA_ADDR, 0, eax
 
mov eax, pcmout_bdl
mov ebx, eax
call GetPgAddr
and ebx, 0xFFF
add eax, ebx
 
stdcall ptr_write, PLAYBACK_LIST_ADDR, 0, eax
stdcall ptr_write, PLAYBACK_LIST_SIZE, 0, 0
stdcall ptr_write, PLAYBACK_LIST_PTR, 0, 0
 
;mov eax, 0x00004000
;shl eax, 16
stdcall ptr_write, PLAYBACK_PERIOD_SIZE, 0, 0x40000000;eax
 
ret
endp
 
 
align 4
proc detect_controller
locals
last_bus dd ?
bus dd ?
devfn dd ?
endl
 
xor eax, eax
mov [bus], eax
inc eax
call PciApi
cmp eax, -1
je .err
 
mov [last_bus], eax
 
.next_bus:
and [devfn], 0
.next_dev:
stdcall PciRead32, [bus], [devfn], dword 0
test eax, eax
jz .next
cmp eax, -1
je .next
 
mov edi, devices
@@:
mov ebx, [edi]
test ebx, ebx
jz .next
 
cmp eax, ebx
je .found
add edi, 12
jmp @B
.next:
inc [devfn]
cmp [devfn], 256
jb .next_dev
mov eax, [bus]
inc eax
mov [bus], eax
cmp eax, [last_bus]
jna .next_bus
xor eax, eax
ret
.found:
mov ebx, [bus]
mov [ctrl.bus], ebx
 
mov ecx, [devfn]
mov [ctrl.devfn], ecx
 
mov edx, eax
and edx, 0xFFFF
mov [ctrl.vendor], edx
shr eax, 16
mov [ctrl.dev_id], eax
 
mov ebx, [edi+4]
mov [ctrl.ctrl_ids], ebx
mov esi, [edi+8]
mov [ctrl.ctrl_setup], esi
 
cmp edx, VID_Creative
jne @F
mov [ctrl.vendor_ids], msg_Creative
ret
@@:
 
.err:
xor eax, eax
mov [ctrl.vendor_ids], eax ;something wrong ?
ret
endp
 
align 4
proc init_controller
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x2C
mov esi, msgPciSubsys
call SysMsgBoardStr
call dword2str
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
mov ebx, eax
and eax, 0xFFFF
mov [ctrl.pci_cmd], eax
shr ebx, 16
mov [ctrl.pci_stat], ebx
 
mov esi, msgPciCmd
call SysMsgBoardStr
call dword2str
call SysMsgBoardStr
 
mov esi, msgPciStat
call SysMsgBoardStr
mov eax, [ctrl.pci_stat]
call dword2str
call SysMsgBoardStr
 
mov esi, msgCtrlIsaIo
call SysMsgBoardStr
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
call dword2str
call SysMsgBoardStr
 
and eax, 0xFFC0
mov [ctrl.ctrl_io_base], eax
 
.default:
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
and eax, 0xFF
@@:
mov [ctrl.int_line], eax
 
call [ctrl.ctrl_setup]
xor eax, eax
inc eax
ret
endp
 
align 4
proc set_Creative
mov [ctrl.codec_read16], codec_io_r16 ;virtual
mov [ctrl.codec_write16], codec_io_w16 ;virtual
 
mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual
mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual
mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual
 
mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual
mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual
mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual
ret
endp
 
 
align 4
proc init_codec
call reset_codec
test eax, eax
jz .err
call detect_codec
xor eax, eax
inc eax
ret
.err:
xor eax, eax
ret
endp
 
align 4
proc reset_codec
locals
counter dd ?
endl
 
if DEBUG
mov esi, msgCold
call SysMsgBoardStr
end if
 
mov eax, 100000 ; wait 100 ms ;400000 ; wait 400 ms
call StallExec
 
stdcall ptr_read, TRIGGER_CHANNEL, 0
 
mov [counter], 16 ; total 20*100 ms = 2s
.wait:
stdcall codec_read, dword 0x26
test eax, 1
jnz .ok
 
mov eax, 100000 ; wait 100 ms
call StallExec
 
dec [counter]
jnz .wait
 
if DEBUG
mov esi, msgCRFail
call SysMsgBoardStr
end if
 
.fail:
stc
ret
.ok:
 
 
xor eax, eax
inc eax
ret
endp
 
 
align 4
play:
mov eax, INTE_CH_0_LOOP
stdcall intr_enable, eax
 
stdcall ptr_read, TRIGGER_CHANNEL, 0
mov ebx, TRIGGER_CHANNEL_0
or eax, ebx
stdcall ptr_write, TRIGGER_CHANNEL, 0, eax
 
xor eax, eax
ret
 
align 4
stop:
mov eax, INTE_CH_0_LOOP or INTE_CH_0_HALF_LOOP
stdcall intr_disable, eax
 
stdcall ptr_read, TRIGGER_CHANNEL, 0
mov ebx, TRIGGER_CHANNEL_0
xor ebx, -1
or eax, ebx
stdcall ptr_write, TRIGGER_CHANNEL, 0, eax
xor eax, eax
ret
 
align 4
proc get_dev_info stdcall, p_info:dword
virtual at esi
CTRL_INFO CTRL_INFO
end virtual
 
mov esi, [p_info]
mov eax, [ctrl.int_line]
mov ecx, [ctrl.ctrl_io_base]
mov [CTRL_INFO.irq], eax
mov [CTRL_INFO.ctrl_io_base], ecx
mov eax, [codec.chip_id]
mov [CTRL_INFO.codec_id], eax
mov ebx, [ctrl.pci_cmd]
mov [CTRL_INFO.pci_cmd], ebx
 
xor eax, eax
mov [CTRL_INFO.codec_io_base], eax
mov [CTRL_INFO.codec_mem_base], eax
mov [CTRL_INFO.ctrl_mem_base], eax
mov [CTRL_INFO.glob_cntrl], eax
mov [CTRL_INFO.glob_sta], eax
ret
endp
 
align 4
proc set_callback stdcall, handler:dword
mov eax, [handler]
mov [ctrl.user_callback], eax
ret
endp
 
 
align 4
proc create stdcall
stdcall PciRead16, [ctrl.bus], [ctrl.devfn], dword 4
test eax, 4 ; test master bit
jnz @f
or eax, 4
stdcall PciWrite16, [ctrl.bus], [ctrl.devfn], dword 4, eax ; set master bit
@@:
 
xor eax, eax
mov edx, INTE
call [ctrl.ctrl_write32]
 
stdcall ptr_write, SPCS0, 0, \
SPCS_CLKACCY_1000PPM or SPCS_SAMPLERATE_48 or \
SPCS_CHANNELNUM_LEFT or SPCS_SOURCENUM_UNSPEC or \
SPCS_GENERATIONSTATUS or 0x00001200 or \
0x00000000 or SPCS_EMPHASIS_NONE or SPCS_COPYRIGHT
stdcall ptr_write, SPCS1, 0, \
SPCS_CLKACCY_1000PPM or SPCS_SAMPLERATE_48 or \
SPCS_CHANNELNUM_LEFT or SPCS_SOURCENUM_UNSPEC or \
SPCS_GENERATIONSTATUS or 0x00001200 or \
0x00000000 or SPCS_EMPHASIS_NONE or SPCS_COPYRIGHT
stdcall ptr_write, SPCS2, 0, \
SPCS_CLKACCY_1000PPM or SPCS_SAMPLERATE_48 or \
SPCS_CHANNELNUM_LEFT or SPCS_SOURCENUM_UNSPEC or \
SPCS_GENERATIONSTATUS or 0x00001200 or \
0x00000000 or SPCS_EMPHASIS_NONE or SPCS_COPYRIGHT
 
stdcall ptr_write, SPDIF_SELECT, 0, 0x700 ; disable SPDIF
stdcall ptr_write, ROUTING, 0, 0x1003F ; routing
stdcall gpio_write, 0x1080 ; analog mode
 
mov eax, dword HCFG_LOCKSOUNDCACHE or HCFG_AUDIOENABLE
mov edx, HCFG
call [ctrl.ctrl_write32]
ret
endp
 
align 4
proc codec_read stdcall, reg:dword
stdcall ac97_read, dword [reg]
ret
endp
 
 
align 4
proc codec_write stdcall, reg:dword
stdcall ac97_write, dword [reg], eax
ret
endp
 
 
align 4
proc ac97_read stdcall, reg:dword
push edx
mov eax, dword [reg]
mov edx, AC97ADDRESS
call [ctrl.ctrl_write8]
 
mov edx, AC97DATA
call [ctrl.ctrl_read16]
and eax, 0xFFFF
pop edx
ret
endp
 
align 4
proc ac97_write stdcall, reg:dword, val:dword
push eax edx
mov eax, dword [reg]
mov edx, AC97ADDRESS
call [ctrl.ctrl_write8]
 
mov eax, dword [val]
mov edx, AC97DATA
call [ctrl.ctrl_write16]
pop edx eax
ret
endp
 
align 4
proc ptr_read stdcall, reg:dword, chn:dword
push edx
mov eax, dword [reg]
shl eax, 16
or eax, dword [chn]
 
mov edx, PTR
call [ctrl.ctrl_write32]
 
mov edx, DATA
call [ctrl.ctrl_read32]
pop edx
ret
endp
 
align 4
proc ptr_write stdcall, reg:dword, chn:dword, data:dword
push eax edx
mov eax, dword [reg]
shl eax, 16
or eax, dword [chn]
 
mov edx, PTR
call [ctrl.ctrl_write32]
 
mov eax, dword [data]
mov edx, DATA
call [ctrl.ctrl_write32]
pop edx eax
ret
endp
 
align 4
proc intr_enable stdcall, intrenb:dword
push edx
mov edx, INTE
call [ctrl.ctrl_read32]
 
or eax, dword [intrenb]
mov edx, INTE
call [ctrl.ctrl_write32]
pop edx
ret
endp
 
align 4
proc intr_disable stdcall, intrenb:dword
push eax ebx edx
mov edx, INTE
call [ctrl.ctrl_read32]
 
mov ebx, dword [intrenb]
xor ebx, -1
and eax, ebx
mov edx, INTE
call [ctrl.ctrl_write32]
pop edx ebx eax
ret
endp
 
align 4
proc gpio_write stdcall, value:dword
push eax edx
mov eax, dword [value]
mov edx, GPIO
call [ctrl.ctrl_write32]
pop edx eax
ret
endp
 
 
align 4
proc StallExec
push ecx
push edx
push ebx
push eax
 
mov ecx, CPU_FREQ
mul ecx
mov ebx, eax ;low
mov ecx, edx ;high
rdtsc
add ebx, eax
adc ecx, edx
@@:
rdtsc
sub eax, ebx
sbb edx, ecx
js @B
 
pop eax
pop ebx
pop edx
pop ecx
ret
endp
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONTROLLER IO functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
proc codec_io_r16 ;Not used.
;mov edx, [ctrl.ctrl_io_base]
;in eax, dx
ret
endp
 
align 4
proc codec_io_w16 ;Not used.
;mov edx, [ctrl.ctrl_io_base]
;out dx, eax
ret
endp
 
align 4
proc ctrl_io_r8
add edx, [ctrl.ctrl_io_base]
in al, dx
ret
endp
 
align 4
proc ctrl_io_r16
add edx, [ctrl.ctrl_io_base]
in ax, dx
ret
endp
 
align 4
proc ctrl_io_r32
add edx, [ctrl.ctrl_io_base]
in eax, dx
ret
endp
 
align 4
proc ctrl_io_w8
add edx, [ctrl.ctrl_io_base]
out dx, al
ret
endp
 
align 4
proc ctrl_io_w16
add edx, [ctrl.ctrl_io_base]
out dx, ax
ret
endp
 
align 4
proc ctrl_io_w32
add edx, [ctrl.ctrl_io_base]
out dx, eax
ret
endp
 
 
align 4
dword2str:
push eax ebx ecx
mov esi, hex_buff
mov ecx, -8
@@:
rol eax, 4
mov ebx, eax
and ebx, 0x0F
mov bl, [ebx+hexletters]
mov [8+esi+ecx], bl
inc ecx
jnz @B
pop ecx ebx eax
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
 
include "codec.inc"
 
align 4
devices dd (CTRL_CT0200 shl 16)+VID_Creative,msg_CT_EMU10K1X,set_Creative
dd 0 ;terminator
 
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
msg_CT_EMU10K1X db 'SB Live! Dell OEM', 13,10, 0
msg_Creative db 'Creative ', 0
 
szKernel db 'KERNEL', 0
sz_sound_srv db 'SOUND',0
 
msgInit db 'detect hardware...',13,10,0
msgFail db 'device not found',13,10,0
msgAttchIRQ db 'IRQ line not supported', 13,10, 0
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0
msgPlay db 'start play', 13,10,0
msgStop db 'stop play', 13,10,0
msgIRQ db 'AC97 IRQ', 13,10,0
;msgInitCtrl db 'init controller',13,10,0
;msgInitCodec db 'init codec',13,10,0
msgPrimBuff db 'create primary buffer ...',0
msgDone db 'done',13,10,0
msgRemap db 'Remap IRQ',13,10,0
;msgReg db 'set service handler',13,10,0
;msgOk db 'service installed',13,10,0
msgCold db 'cold reset',13,10,0
;msgWarm db 'warm reset',13,10,0
;msgWRFail db 'warm reset failed',13,10,0
msgCRFail db 'cold reset failed',13,10,0
;msgCFail db 'codec not ready',13,10,0
;msgCInvalid db 'codec is not valid',13,10,0 ;Asper
;msgResetOk db 'reset complete',13,10,0
;msgStatus db 'global status ',0
;msgControl db 'global control ',0
msgPciCmd db 'PCI command ',0
msgPciStat db 'PCI status ',0
msgPciSubsys db 'PCI subsystem ',0
msgCtrlIsaIo db 'controller io base ',0
;msgMixIsaIo db 'codec io base ',0
;msgCtrlMMIo db 'controller mmio base ',0
;msgMixMMIo db 'codec mmio base ',0
;msgIrqMap db 'AC97 irq map as ',0
 
section '.data' data readable writable align 16
 
pcmout_bdl rq 32
buff_list rd 32
 
codec CODEC
ctrl AC_CNTRL
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/imports.inc
0,0 → 1,93
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
macro kernel_export [name]{
forward
if used name
if DEBUG
display 'uses: ',`name,#13,#10
end if
extrn name
end if
}
; all exported kernel functions and data
 
 
kernel_export \
RegService,\
GetService,\
ServiceHandler,\
AttachIntHandler,\
GetIntHandler,\
FpuSave,\
FpuRestore,\
ReservePortArea,\
Boot_Log,\
\
MutexInit,\
MutexLock,\
MutexUnlock,\
\
PciApi,\
PciRead32,\
PciRead16,\
PciRead8,\
PciWrite8,\
PciWrite16,\
PciWrite32,\
\
AllocPage,\
AllocPages,\
FreePage,\
MapPage,\
MapSpace,\
MapIoMem,\
GetPgAddr,\
CommitPages,\
ReleasePages,\
\
AllocKernelSpace,\
FreeKernelSpace,\
KernelAlloc,\
KernelFree,\
UserAlloc,\
UserFree,\
Kmalloc,\
Kfree,\
CreateRingBuffer,\
\
GetPid,\
CreateObject,\
DestroyObject,\
CreateEvent,\
RaiseEvent,\
WaitEvent,\
DestroyEvent,\
ClearEvent,\
\
LoadCursor,\
SelectHwCursor,\
SetHwCursor,\
HwCursorRestore,\
HwCursorCreate,\
\
SysMsgBoardStr,\
SysMsgBoardChar,\
GetCurrentTask,\
LoadFile,\
SendEvent,\
SetMouseData,\
Sleep,\
GetTimerTicks,\
\
strncat,\
strncpy,\
strncmp,\
strnlen,\
strchr,\
strrchr,\
\
LFBAddress
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/viasound.asm
0,0 → 1,1281
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
format MS COFF
 
DEBUG equ 1
 
include 'proc32.inc'
include 'imports.inc'
 
API_VERSION equ 0x01000100
 
USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices
IRQ_REMAP equ 0
IRQ_LINE equ 0
 
 
;irq 0,1,2,8,12,13 ­¥¤®áâ㯭ë
; FEDCBA9876543210
VALID_IRQ equ 1100111011111000b
ATTCH_IRQ equ 0000111010100000b
 
if USE_COM_IRQ
ATTCH_IRQ equ 0000111010111000b
end if
 
CPU_FREQ equ 2600d
 
BIT0 EQU 0x00000001
BIT1 EQU 0x00000002
BIT5 EQU 0x00000020
BIT10 EQU 0x00000400
 
VID_VIA equ 0x1106
 
CTRL_VT82C686 equ 0x3058
CTRL_VT8233_5 equ 0x3059
 
 
CODEC_MASTER_VOL_REG equ 0x02
CODEC_AUX_VOL equ 0x04 ;
CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume
CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio
CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control
CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate
CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate
CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate
 
 
;VIA host controller registers set
;; common offsets
VIA_REG_OFFSET_STATUS equ 0x00 ;; byte - channel status
VIA_REG_STAT_ACTIVE equ 0x80 ;; RO
VIA_REG_STAT_PAUSED equ 0x40 ;; RO
VIA_REG_STAT_TRIGGER_QUEUED equ 0x08 ;; RO
VIA_REG_STAT_STOPPED equ 0x04 ;; RWC
VIA_REG_STAT_EOL equ 0x02 ;; RWC
VIA_REG_STAT_FLAG equ 0x01 ;; RWC
VIA_REG_OFFSET_CONTROL equ 0x01 ;; byte - channel control
VIA_REG_CTRL_START equ 0x80 ;; WO
VIA_REG_CTRL_TERMINATE equ 0x40 ;; WO
VIA_REG_CTRL_AUTOSTART equ 0x20
VIA_REG_CTRL_PAUSE equ 0x08 ;; RW
VIA_REG_CTRL_INT_STOP equ 0x04
VIA_REG_CTRL_INT_EOL equ 0x02
VIA_REG_CTRL_INT_FLAG equ 0x01
VIA_REG_CTRL_RESET equ 0x01 ;; RW - probably reset? undocumented
VIA_REG_CTRL_INT equ (VIA_REG_CTRL_INT_FLAG or \
VIA_REG_CTRL_INT_EOL or \
VIA_REG_CTRL_AUTOSTART)
VIA_REG_OFFSET_TYPE equ 0x02 ;; byte - channel type (686 only)
VIA_REG_TYPE_AUTOSTART equ 0x80 ;; RW - autostart at EOL
VIA_REG_TYPE_16BIT equ 0x20 ;; RW
VIA_REG_TYPE_STEREO equ 0x10 ;; RW
VIA_REG_TYPE_INT_LLINE equ 0x00
VIA_REG_TYPE_INT_LSAMPLE equ 0x04
VIA_REG_TYPE_INT_LESSONE equ 0x08
VIA_REG_TYPE_INT_MASK equ 0x0c
VIA_REG_TYPE_INT_EOL equ 0x02
VIA_REG_TYPE_INT_FLAG equ 0x01
VIA_REG_OFFSET_TABLE_PTR equ 0x04 ;; dword - channel table pointer
VIA_REG_OFFSET_CURR_PTR equ 0x04 ;; dword - channel current pointer
VIA_REG_OFFSET_STOP_IDX equ 0x08 ;; dword - stop index, channel type, sample rate
VIA8233_REG_TYPE_16BIT equ 0x00200000 ;; RW
VIA8233_REG_TYPE_STEREO equ 0x00100000 ;; RW
VIA_REG_OFFSET_CURR_COUNT equ 0x0c ;; dword - channel current count (24 bit)
VIA_REG_OFFSET_CURR_INDEX equ 0x0f ;; byte - channel current index (for via8233 only)
 
 
VIADEV_PLAYBACK equ 0x00
VIADEV_CAPTURE equ 0x10
VIADEV_FM equ 0x20
 
;; AC'97 ;;
VIA_REG_AC97 equ 0x80 ; dword
VIA_REG_AC97_CODEC_ID_MASK equ 0xC0000000 ;(3<<30)
VIA_REG_AC97_CODEC_ID_SHIFT equ 30
VIA_REG_AC97_CODEC_ID_PRIMARY equ 0x00
VIA_REG_AC97_CODEC_ID_SECONDARY equ 0x01
VIA_REG_AC97_SECONDARY_VALID equ 0x08000000 ;(1<<27)
VIA_REG_AC97_PRIMARY_VALID equ 0x02000000 ;(1<<25)
VIA_REG_AC97_BUSY equ 0x01000000 ;(1<<24)
VIA_REG_AC97_READ equ 0x00800000 ;(1<<23)
VIA_REG_AC97_CMD_SHIFT equ 16
VIA_REG_AC97_CMD_MASK equ 0x7E
VIA_REG_AC97_DATA_SHIFT equ 0
VIA_REG_AC97_DATA_MASK equ 0xFFFF
 
VIA_REG_SGD_SHADOW equ 0x84 ; dword
 
;; via8233-specific registers ;;
VIA_REG_OFS_PLAYBACK_VOLUME_L equ 0x02 ;; byte
VIA_REG_OFS_PLAYBACK_VOLUME_R equ 0x03 ;; byte
VIA_REG_OFS_MULTPLAY_FORMAT equ 0x02 ;; byte - format and channels
VIA_REG_MULTPLAY_FMT_8BIT equ 0x00
VIA_REG_MULTPLAY_FMT_16BIT equ 0x80
VIA_REG_MULTPLAY_FMT_CH_MASK equ 0x70 ;; # channels << 4 (valid = 1,2,4,6)
VIA_REG_OFS_CAPTURE_FIFO equ 0x02 ;; byte - bit 6 = fifo enable
VIA_REG_CAPTURE_FIFO_ENABLE equ 0x40
 
VIA_DXS_MAX_VOLUME equ 31 ;; max. volume (attenuation) of reg 0x32/33
 
VIA_TBL_BIT_FLAG equ 0x40000000
VIA_TBL_BIT_EOL equ 0x80000000
 
;; pci space ;;
VIA_ACLINK_STAT equ 0x40
;...
VIA_ACLINK_C00_READY equ 0x01 ; primary codec ready
VIA_ACLINK_CTRL equ 0x41
VIA_ACLINK_CTRL_ENABLE equ 0x80 ; 0: disable, 1: enable
VIA_ACLINK_CTRL_RESET equ 0x40 ; 0: assert, 1: de-assert
VIA_ACLINK_CTRL_SYNC equ 0x20 ; 0: release SYNC, 1: force SYNC hi
VIA_ACLINK_CTRL_SDO equ 0x10 ; 0: release SDO, 1: force SDO hi
VIA_ACLINK_CTRL_VRA equ 0x08 ; 0: disable VRA, 1: enable VRA
VIA_ACLINK_CTRL_PCM equ 0x04 ; 0: disable PCM, 1: enable PCM
VIA_ACLINK_CTRL_FM equ 0x02 ; via686 only
VIA_ACLINK_CTRL_SB equ 0x01 ; via686 only
VIA_ACLINK_CTRL_INIT equ (VIA_ACLINK_CTRL_ENABLE or \
VIA_ACLINK_CTRL_RESET or \
VIA_ACLINK_CTRL_PCM or \
VIA_ACLINK_CTRL_VRA)
VIA_FUNC_ENABLE equ 0x42
VIA_FUNC_MIDI_PNP equ 0x80 ; FIXME: it's 0x40 in the datasheet!
VIA_FUNC_MIDI_IRQMASK equ 0x40 ; FIXME: not documented!
VIA_FUNC_RX2C_WRITE equ 0x20
VIA_FUNC_SB_FIFO_EMPTY equ 0x10
VIA_FUNC_ENABLE_GAME equ 0x08
VIA_FUNC_ENABLE_FM equ 0x04
VIA_FUNC_ENABLE_MIDI equ 0x02
VIA_FUNC_ENABLE_SB equ 0x01
VIA_PNP_CONTROL equ 0x43
VIA_FM_NMI_CTRL equ 0x48
VIA8233_VOLCHG_CTRL equ 0x48
VIA8233_SPDIF_CTRL equ 0x49
VIA8233_SPDIF_DX3 equ 0x08
VIA8233_SPDIF_SLOT_MASK equ 0x03
VIA8233_SPDIF_SLOT_1011 equ 0x00
VIA8233_SPDIF_SLOT_34 equ 0x01
VIA8233_SPDIF_SLOT_78 equ 0x02
VIA8233_SPDIF_SLOT_69 equ 0x03
;] Asper
 
 
SRV_GETVERSION equ 0
DEV_PLAY equ 1
DEV_STOP equ 2
DEV_CALLBACK equ 3
DEV_SET_BUFF equ 4
DEV_NOTIFY equ 5
DEV_SET_MASTERVOL equ 6
DEV_GET_MASTERVOL equ 7
DEV_GET_INFO equ 8
 
struc AC_CNTRL ;AC controller base class
{ .bus dd ?
.devfn dd ?
 
.vendor dd ?
.dev_id dd ?
.pci_cmd dd ?
.pci_stat dd ?
 
.codec_io_base dd ?
.codec_mem_base dd ?
 
.ctrl_io_base dd ?
.ctrl_mem_base dd ?
.cfg_reg dd ?
.int_line dd ?
 
.vendor_ids dd ? ;vendor id string
.ctrl_ids dd ? ;hub id string
 
.buffer dd ?
 
.notify_pos dd ?
.notify_task dd ?
 
.lvi_reg dd ?
.ctrl_setup dd ?
.user_callback dd ?
.codec_read16 dd ?
.codec_write16 dd ?
 
.ctrl_read8 dd ?
.ctrl_read16 dd ?
.ctrl_read32 dd ?
 
.ctrl_write8 dd ?
.ctrl_write16 dd ?
.ctrl_write32 dd ?
}
 
struc CODEC ;Audio Chip base class
{
.chip_id dd ?
.flags dd ?
.status dd ?
 
.ac_vendor_ids dd ? ;ac vendor id string
.chip_ids dd ? ;chip model string
 
.shadow_flag dd ?
dd ?
 
.regs dw ? ; codec registers
.reg_master_vol dw ? ;0x02
.reg_aux_out_vol dw ? ;0x04
.reg_mone_vol dw ? ;0x06
.reg_master_tone dw ? ;0x08
.reg_beep_vol dw ? ;0x0A
.reg_phone_vol dw ? ;0x0C
.reg_mic_vol dw ? ;0x0E
.reg_line_in_vol dw ? ;0x10
.reg_cd_vol dw ? ;0x12
.reg_video_vol dw ? ;0x14
.reg_aux_in_vol dw ? ;0x16
.reg_pcm_out_vol dw ? ;0x18
.reg_rec_select dw ? ;0x1A
.reg_rec_gain dw ? ;0x1C
.reg_rec_gain_mic dw ? ;0x1E
.reg_gen dw ? ;0x20
.reg_3d_ctrl dw ? ;0X22
.reg_page dw ? ;0X24
.reg_powerdown dw ? ;0x26
.reg_ext_audio dw ? ;0x28
.reg_ext_st dw ? ;0x2a
.reg_pcm_front_rate dw ? ;0x2c
.reg_pcm_surr_rate dw ? ;0x2e
.reg_lfe_rate dw ? ;0x30
.reg_pcm_in_rate dw ? ;0x32
dw ? ;0x34
.reg_cent_lfe_vol dw ? ;0x36
.reg_surr_vol dw ? ;0x38
.reg_spdif_ctrl dw ? ;0x3A
dw ? ;0x3C
dw ? ;0x3E
dw ? ;0x40
dw ? ;0x42
dw ? ;0x44
dw ? ;0x46
dw ? ;0x48
dw ? ;0x4A
dw ? ;0x4C
dw ? ;0x4E
dw ? ;0x50
dw ? ;0x52
dw ? ;0x54
dw ? ;0x56
dw ? ;0x58
dw ? ;0x5A
dw ? ;0x5C
dw ? ;0x5E
.reg_page_0 dw ? ;0x60
.reg_page_1 dw ? ;0x62
.reg_page_2 dw ? ;0x64
.reg_page_3 dw ? ;0x66
.reg_page_4 dw ? ;0x68
.reg_page_5 dw ? ;0x6A
.reg_page_6 dw ? ;0x6C
.reg_page_7 dw ? ;0x6E
dw ? ;0x70
dw ? ;0x72
dw ? ;0x74
dw ? ;0x76
dw ? ;0x78
dw ? ;0x7A
.reg_vendor_id_1 dw ? ;0x7C
.reg_vendor_id_2 dw ? ;0x7E
 
 
.reset dd ? ;virual
.set_master_vol dd ?
}
 
struc CTRL_INFO
{ .pci_cmd dd ?
.irq dd ?
.glob_cntrl dd ?
.glob_sta dd ?
.codec_io_base dd ?
.ctrl_io_base dd ?
.codec_mem_base dd ?
.ctrl_mem_base dd ?
.codec_id dd ?
}
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
EVENT_NOTIFY equ 0x00000200
 
public START
public service_proc
public version
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .stop
 
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
call detect_controller
test eax, eax
jz .fail
 
if DEBUG
mov esi,[ctrl.vendor_ids]
call SysMsgBoardStr
mov esi, [ctrl.ctrl_ids]
call SysMsgBoardStr
end if
 
call init_controller
test eax, eax
jz .fail
 
call init_codec
test eax, eax
jz .fail
 
call setup_codec
 
mov esi, msgPrimBuff
call SysMsgBoardStr
call create_primary_buff
mov esi, msgDone
call SysMsgBoardStr
 
if IRQ_REMAP
pushf
cli
 
mov ebx, [ctrl.int_line]
in al, 0xA1
mov ah, al
in al, 0x21
test ebx, ebx
jz .skip
bts ax, bx ;mask old line
.skip:
bts ax, IRQ_LINE ;mask new ine
out 0x21, al
mov al, ah
out 0xA1, al
 
stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE ;remap IRQ
 
mov dx, 0x4d0 ;8259 ELCR1
in al, dx
bts ax, IRQ_LINE
out dx, al ;set level-triggered mode
mov [ctrl.int_line], IRQ_LINE
popf
mov esi, msgRemap
call SysMsgBoardStr
end if
 
mov eax, VALID_IRQ
mov ebx, [ctrl.int_line]
mov esi, msgInvIRQ
bt eax, ebx
jnc .fail_msg
mov eax, ATTCH_IRQ
mov esi, msgAttchIRQ
bt eax, ebx
jnc .fail_msg
 
stdcall AttachIntHandler, ebx, ac97_irq_VIA, dword 0
.reg:
stdcall RegService, sz_sound_srv, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
xor eax, eax
ret
.fail_msg:
call SysMsgBoardStr
xor eax, eax
ret
.stop:
call stop
xor eax, eax
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edi, [ioctl]
mov eax, [edi+io_code]
 
cmp eax, SRV_GETVERSION
jne @F
mov eax, [edi+output]
cmp [edi+out_size], 4
jne .fail
 
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
cmp eax, DEV_PLAY
jne @F
if DEBUG
mov esi, msgPlay
call SysMsgBoardStr
end if
call play
ret
@@:
cmp eax, DEV_STOP
jne @F
if DEBUG
mov esi, msgStop
call SysMsgBoardStr
end if
call stop
ret
@@:
cmp eax, DEV_CALLBACK
jne @F
mov ebx, [edi+input]
stdcall set_callback, [ebx]
ret
@@:
cmp eax, DEV_SET_MASTERVOL
jne @F
mov eax, [edi+input]
mov eax, [eax]
call set_master_vol ;eax= vol
ret
@@:
cmp eax, DEV_GET_MASTERVOL
jne @F
mov ebx, [edi+output]
stdcall get_master_vol, ebx
ret
@@:
cmp eax, DEV_GET_INFO
jne @F
mov ebx, [edi+output]
stdcall get_dev_info, ebx
ret
@@:
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
 
align 4
proc ac97_irq_VIA
locals
status db 0
endl
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
call [ctrl.ctrl_read8]
test al, VIA_REG_STAT_ACTIVE
jz @f
 
and al, VIA_REG_STAT_EOL or VIA_REG_STAT_FLAG or VIA_REG_STAT_STOPPED
mov byte [status], al
 
mov ebx, dword [buff_list]
cmp [ctrl.user_callback], 0
je @f
stdcall [ctrl.user_callback], ebx
@@:
mov al, byte [status] ;; ack ;;
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
call [ctrl.ctrl_write8]
 
ret
endp
 
 
align 4
proc create_primary_buff
 
stdcall KernelAlloc, 0x10000
mov [ctrl.buffer], eax
 
mov edi, eax
mov ecx, 0x10000/4
xor eax, eax
cld
rep stosd
 
mov eax, [ctrl.buffer]
call GetPgAddr
mov edi, pcmout_bdl
stosd
mov eax, 0x80004000
stosd
 
mov edi, buff_list
mov eax, [ctrl.buffer]
mov ecx, 4
@@:
mov [edi], eax
mov [edi+16], eax
mov [edi+32], eax
mov [edi+48], eax
mov [edi+64], eax
mov [edi+80], eax
mov [edi+96], eax
mov [edi+112], eax
 
;add eax, 0x4000
add edi, 4
loop @B
 
stdcall channel_reset, VIADEV_PLAYBACK
stdcall codec_check_ready
 
mov eax, pcmout_bdl
mov ebx, eax
call GetPgAddr
and ebx, 0xFFF
add eax, ebx
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR
call [ctrl.ctrl_write32]
 
stdcall codec_check_ready
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_L
mov eax, 7;31
call [ctrl.ctrl_write8]
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_R
mov eax, 7;31
call [ctrl.ctrl_write8]
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
mov [ctrl.lvi_reg], 16;0xF;eax
call [ctrl.ctrl_write32]
 
stdcall codec_check_ready
ret
endp
 
 
proc channel_reset channel:dword
mov esi, dword [channel]
mov edx, esi
add edx, VIA_REG_OFFSET_CONTROL
mov eax, VIA_REG_CTRL_PAUSE or VIA_REG_CTRL_TERMINATE or VIA_REG_CTRL_RESET
call [ctrl.ctrl_write8]
 
mov edx, esi
add edx, VIA_REG_OFFSET_CONTROL
call [ctrl.ctrl_read8]
 
mov eax, 50000 ; wait 50 ms
call StallExec
; disable interrupts
mov edx, esi
add edx, VIA_REG_OFFSET_CONTROL
xor eax, eax
call [ctrl.ctrl_write8]
 
; clear interrupts
mov edx, esi
add edx, VIA_REG_OFFSET_STATUS
mov eax, 0x03
call [ctrl.ctrl_write8]
 
;outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
; mov edx, esi ;; for via686
; add edx, VIA_REG_OFFSET_TYPE
; mov eax, 0x03
; call [ctrl.ctrl_write8]
 
;; outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
;mov edx, esi
;add edx, VIA_REG_OFFSET_CURR_PTR
;xor eax, eax
;call [ctrl.ctrl_write8]
 
ret
endp
 
 
align 4
proc detect_controller
locals
last_bus dd ?
bus dd ?
devfn dd ?
endl
 
xor eax, eax
mov [bus], eax
inc eax
call PciApi
cmp eax, -1
je .err
 
mov [last_bus], eax
 
.next_bus:
and [devfn], 0
.next_dev:
stdcall PciRead32, [bus], [devfn], dword 0
test eax, eax
jz .next
cmp eax, -1
je .next
 
mov edi, devices
@@:
mov ebx, [edi]
test ebx, ebx
jz .next
 
cmp eax, ebx
je .found
add edi, 12
jmp @B
.next:
inc [devfn]
cmp [devfn], 256
jb .next_dev
mov eax, [bus]
inc eax
mov [bus], eax
cmp eax, [last_bus]
jna .next_bus
xor eax, eax
ret
.found:
mov ebx, [bus]
mov [ctrl.bus], ebx
 
mov ecx, [devfn]
mov [ctrl.devfn], ecx
 
mov edx, eax
and edx, 0xFFFF
mov [ctrl.vendor], edx
shr eax, 16
mov [ctrl.dev_id], eax
 
mov ebx, [edi+4]
mov [ctrl.ctrl_ids], ebx
mov esi, [edi+8]
mov [ctrl.ctrl_setup], esi
 
cmp edx, VID_VIA
jne @F
mov [ctrl.vendor_ids], msg_VIA
ret
@@:
 
.err:
xor eax, eax
mov [ctrl.vendor_ids], eax ;something wrong ?
ret
endp
 
align 4
proc init_controller
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
mov ebx, eax
and eax, 0xFFFF
mov [ctrl.pci_cmd], eax
shr ebx, 16
mov [ctrl.pci_stat], ebx
 
mov esi, msgPciCmd
call SysMsgBoardStr
call dword2str
call SysMsgBoardStr
 
mov esi, msgPciStat
call SysMsgBoardStr
mov eax, [ctrl.pci_stat]
call dword2str
call SysMsgBoardStr
 
mov esi, msgCtrlIsaIo
call SysMsgBoardStr
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
call dword2str
call SysMsgBoardStr
 
and eax, 0xFFC0
mov [ctrl.ctrl_io_base], eax
 
.default:
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
and eax, 0xFF
@@:
mov [ctrl.int_line], eax
 
;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE ;0x42
;mov byte [old_legacy], al
 
;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_PNP_CONTROL ;0x43
;mov byte [old_legacy_cfg], al
 
;mov al, VIA_FUNC_ENABLE_SB or VIA_FUNC_ENABLE_FM
;xor al, 0xFF
;and al, byte [old_legacy]
;and eax, 0xFF
;stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE, eax ;0x42
;mov byte [old_legacy], al
 
call [ctrl.ctrl_setup]
xor eax, eax
inc eax
ret
endp
 
align 4
proc set_VIA
mov [ctrl.codec_read16], codec_io_r16 ;virtual
mov [ctrl.codec_write16], codec_io_w16 ;virtual
 
mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual
mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual
mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual
 
mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual
mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual
mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual
ret
endp
 
 
align 4
proc init_codec
locals
counter dd ?
endl
 
mov esi, msgControl
call SysMsgBoardStr
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL
and eax, 0xFF
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
and eax, 0xFF
push eax
call dword2str
call SysMsgBoardStr
pop eax
 
test eax, VIA_ACLINK_C00_READY
jz .ready
 
call reset_codec
test eax, eax
jz .err
 
.ready:
xor edx, edx ; ac_reg_0
call [ctrl.codec_write16]
jmp .done
 
.err:
xor eax, eax ; timeout error
ret
 
.done:
call detect_codec
 
xor eax, eax
inc eax
ret
endp
 
align 4
proc reset_codec
stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, \
VIA_ACLINK_CTRL_ENABLE or VIA_ACLINK_CTRL_RESET or VIA_ACLINK_CTRL_SYNC
mov eax, 100000 ; wait 100 ms
call StallExec
.cold:
call cold_reset
jnc .ok
 
if DEBUG
mov esi, msgCFail
call SysMsgBoardStr
end if
xor eax, eax ; timeout error
ret
.ok:
if DEBUG
mov esi, msgResetOk
call SysMsgBoardStr
end if
xor eax, eax
inc eax
ret
endp
 
 
align 4
proc cold_reset
locals
counter dd ?
endl
 
stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword 0
 
if DEBUG
mov esi, msgCold
call SysMsgBoardStr
end if
 
mov eax, 100000 ; wait 100 ms ;400000 ; wait 400 ms
call StallExec
 
;; ACLink on, deassert ACLink reset, VSR, SGD data out
;; note - FM data out has trouble with non VRA codecs !!
stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword VIA_ACLINK_CTRL_INIT
 
mov [counter], 16 ; total 20*100 ms = 2s
.wait:
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
test eax, VIA_ACLINK_C00_READY
jnz .ok
 
mov eax, 100000 ; wait 100 ms
call StallExec
 
dec [counter]
jnz .wait
 
if DEBUG
mov esi, msgCRFail
call SysMsgBoardStr
end if
 
.fail:
stc
ret
.ok:
mov esi, msgControl
call SysMsgBoardStr
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
and eax, 0xFF
push eax
call dword2str
call SysMsgBoardStr
pop eax
 
test eax, VIA_ACLINK_C00_READY ;CTRL_ST_CREADY
jz .fail
clc
ret
endp
 
align 4
play:
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
mov [ctrl.lvi_reg], 16
call [ctrl.ctrl_write32]
 
mov eax, VIA_REG_CTRL_INT
or eax, VIA_REG_CTRL_START
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
call [ctrl.ctrl_write8]
 
xor eax, eax
ret
 
align 4
stop:
mov eax, VIA_REG_CTRL_INT
or eax, VIA_REG_CTRL_TERMINATE
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
call [ctrl.ctrl_write8]
 
stdcall channel_reset, VIADEV_PLAYBACK
xor eax, eax
ret
 
align 4
proc get_dev_info stdcall, p_info:dword
virtual at esi
CTRL_INFO CTRL_INFO
end virtual
 
mov esi, [p_info]
mov eax, [ctrl.int_line]
mov ecx, [ctrl.ctrl_io_base]
mov [CTRL_INFO.irq], eax
mov [CTRL_INFO.ctrl_io_base], ecx
 
xor eax, eax
;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR
;call [ctrl.ctrl_read32]
mov [CTRL_INFO.codec_io_base], eax
;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
;call [ctrl.ctrl_read32]
mov [CTRL_INFO.codec_mem_base], eax
;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CURR_COUNT
;call [ctrl.ctrl_read32]
mov [CTRL_INFO.ctrl_mem_base], eax
 
mov eax, [codec.chip_id]
mov [CTRL_INFO.codec_id], eax
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
call [ctrl.ctrl_read8]
and eax, 0xFF
mov [CTRL_INFO.glob_cntrl], eax
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
call [ctrl.ctrl_read8]
and eax, 0xFF
mov [CTRL_INFO.glob_sta], eax
 
mov ebx, [ctrl.pci_cmd]
mov [CTRL_INFO.pci_cmd], ebx
ret
endp
 
align 4
proc set_callback stdcall, handler:dword
mov eax, [handler]
mov [ctrl.user_callback], eax
ret
endp
 
 
align 4
proc codec_check_ready stdcall
locals
counter dd ?
endl
 
mov [counter], 1000 ; total 1000*1 ms = 1s
.wait:
call [ctrl.codec_read16]
test eax, VIA_REG_AC97_BUSY
jz .ok
 
mov eax, 1000 ; wait 1 ms
call StallExec
 
sub [counter] , 1
jnz .wait
.err:
mov eax, -1
ret
.ok:
and eax, 0xFFFF
ret
endp
 
 
align 4
proc codec_valid stdcall
stdcall codec_check_ready
ret
endp
 
align 4
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax
locals
counter dd ?
endl
 
;Use only primary codec.
mov eax, [ac_reg]
and eax, 0x7F
shl eax, VIA_REG_AC97_CMD_SHIFT
or eax, VIA_REG_AC97_PRIMARY_VALID or VIA_REG_AC97_READ
 
mov [counter], 3 ; total 3*20 ms = 60ms
.wait:
push eax
call [ctrl.codec_write16]
 
mov eax, 20000 ; wait 20 ms
call StallExec
 
stdcall codec_valid,
cmp eax, 0
pop eax
jge .ok
 
sub [counter] , 1
jnz .wait
jmp .err
 
.ok:
mov eax, 25000 ; wait 25 ms
call StallExec
 
call [ctrl.codec_read16] ;change edx !!!
and eax, 0xFFFF
ret
.err:
if DEBUG
mov esi, msgCInvalid
call SysMsgBoardStr
end if
mov eax, -1 ; invalid codec error
ret
endp
 
align 4
proc codec_write stdcall, ac_reg:dword
;Use only primary codec.
mov esi, [ac_reg]
mov edx, esi
shl edx, VIA_REG_AC97_CMD_SHIFT
 
shl eax, VIA_REG_AC97_DATA_SHIFT
or edx, eax
 
mov eax, VIA_REG_AC97_CODEC_ID_PRIMARY ;not VIA_REG_AC97_CODEC_ID_PRIMARY
shl eax, VIA_REG_AC97_CODEC_ID_SHIFT
or edx, eax
 
mov eax, edx
mov edx, esi
call [ctrl.codec_write16]
mov [codec.regs+esi], ax
 
stdcall codec_check_ready
cmp eax, 0
jl .err
.ok:
ret
.err:
if DEBUG
mov esi, msgCFail
call SysMsgBoardStr
end if
;mov eax, -1 ; codec not ready error
ret
endp
 
align 4
proc StallExec
push ecx
push edx
push ebx
push eax
 
mov ecx, CPU_FREQ
mul ecx
mov ebx, eax ;low
mov ecx, edx ;high
rdtsc
add ebx, eax
adc ecx, edx
@@:
rdtsc
sub eax, ebx
sbb edx, ecx
js @B
 
pop eax
pop ebx
pop edx
pop ecx
ret
endp
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONTROLLER IO functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
proc codec_io_r16 ;r32
mov edx, [ctrl.ctrl_io_base]
add edx, VIA_REG_AC97
in eax, dx
ret
endp
 
align 4
proc codec_io_w16 ;w32
mov edx, [ctrl.ctrl_io_base]
add edx, VIA_REG_AC97
out dx, eax
ret
endp
 
align 4
proc ctrl_io_r8
add edx, [ctrl.ctrl_io_base]
in al, dx
ret
endp
 
align 4
proc ctrl_io_r16
add edx, [ctrl.ctrl_io_base]
in ax, dx
ret
endp
 
align 4
proc ctrl_io_r32
add edx, [ctrl.ctrl_io_base]
in eax, dx
ret
endp
 
align 4
proc ctrl_io_w8
add edx, [ctrl.ctrl_io_base]
out dx, al
ret
endp
 
align 4
proc ctrl_io_w16
add edx, [ctrl.ctrl_io_base]
out dx, ax
ret
endp
 
align 4
proc ctrl_io_w32
add edx, [ctrl.ctrl_io_base]
out dx, eax
ret
endp
 
 
align 4
dword2str:
push eax ebx ecx
mov esi, hex_buff
mov ecx, -8
@@:
rol eax, 4
mov ebx, eax
and ebx, 0x0F
mov bl, [ebx+hexletters]
mov [8+esi+ecx], bl
inc ecx
jnz @B
pop ecx ebx eax
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
 
include "codec.inc"
 
align 4
devices dd (CTRL_VT82C686 shl 16)+VID_VIA,msg_VT82C686,set_VIA
dd (CTRL_VT8233_5 shl 16)+VID_VIA,msg_VT8233,set_VIA
dd 0 ;terminator
 
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
msg_VT82C686 db 'VT82C686', 13,10, 0
msg_VT8233 db 'VT8233', 13,10, 0
msg_VIA db 'VIA' , 13,10, 0
 
szKernel db 'KERNEL', 0
sz_sound_srv db 'SOUND',0
 
msgInit db 'detect hardware...',13,10,0
msgFail db 'device not found',13,10,0
msgAttchIRQ db 'IRQ line not supported', 13,10, 0
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0
msgPlay db 'start play', 13,10,0
msgStop db 'stop play', 13,10,0
;msgIRQ db 'AC97 IRQ', 13,10,0
;msgInitCtrl db 'init controller',13,10,0
;msgInitCodec db 'init codec',13,10,0
msgPrimBuff db 'create primary buffer ...',0
msgDone db 'done',13,10,0
msgRemap db 'Remap IRQ',13,10,0
;msgReg db 'set service handler',13,10,0
;msgOk db 'service installed',13,10,0
msgCold db 'cold reset',13,10,0
;msgWarm db 'warm reset',13,10,0
;msgWRFail db 'warm reset failed',13,10,0
msgCRFail db 'cold reset failed',13,10,0
msgCFail db 'codec not ready',13,10,0
msgCInvalid db 'codec is not valid',13,10,0 ;Asper
msgResetOk db 'reset complete',13,10,0
msgStatus db 'global status ',0
msgControl db 'global control ',0
msgPciCmd db 'PCI command ',0
msgPciStat db 'PCI status ',0
msgCtrlIsaIo db 'controller io base ',0
;msgMixIsaIo db 'codec io base ',0
;msgCtrlMMIo db 'controller mmio base ',0
;msgMixMMIo db 'codec mmio base ',0
;msgIrqMap db 'AC97 irq map as ',0
 
 
section '.data' data readable writable align 16
 
pcmout_bdl rq 32
buff_list rd 32
 
codec CODEC
ctrl AC_CNTRL
 
chip_type rb 1
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/vt823(x).asm
0,0 → 1,1281
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
format MS COFF
 
DEBUG equ 1
 
include 'proc32.inc'
include 'imports.inc'
 
API_VERSION equ 0x01000100
 
USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices
IRQ_REMAP equ 0
IRQ_LINE equ 0
 
 
;irq 0,1,2,8,12,13 ­¥¤®áâ㯭ë
; FEDCBA9876543210
VALID_IRQ equ 1100111011111000b
ATTCH_IRQ equ 0000111010100000b
 
if USE_COM_IRQ
ATTCH_IRQ equ 0000111010111000b
end if
 
CPU_FREQ equ 2600d
 
BIT0 EQU 0x00000001
BIT1 EQU 0x00000002
BIT5 EQU 0x00000020
BIT10 EQU 0x00000400
 
VID_VIA equ 0x1106
 
CTRL_VT82C686 equ 0x3058
CTRL_VT8233_5 equ 0x3059
 
 
CODEC_MASTER_VOL_REG equ 0x02
CODEC_AUX_VOL equ 0x04 ;
CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume
CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio
CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control
CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate
CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate
CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate
 
 
;VIA host controller registers set
;; common offsets
VIA_REG_OFFSET_STATUS equ 0x00 ;; byte - channel status
VIA_REG_STAT_ACTIVE equ 0x80 ;; RO
VIA_REG_STAT_PAUSED equ 0x40 ;; RO
VIA_REG_STAT_TRIGGER_QUEUED equ 0x08 ;; RO
VIA_REG_STAT_STOPPED equ 0x04 ;; RWC
VIA_REG_STAT_EOL equ 0x02 ;; RWC
VIA_REG_STAT_FLAG equ 0x01 ;; RWC
VIA_REG_OFFSET_CONTROL equ 0x01 ;; byte - channel control
VIA_REG_CTRL_START equ 0x80 ;; WO
VIA_REG_CTRL_TERMINATE equ 0x40 ;; WO
VIA_REG_CTRL_AUTOSTART equ 0x20
VIA_REG_CTRL_PAUSE equ 0x08 ;; RW
VIA_REG_CTRL_INT_STOP equ 0x04
VIA_REG_CTRL_INT_EOL equ 0x02
VIA_REG_CTRL_INT_FLAG equ 0x01
VIA_REG_CTRL_RESET equ 0x01 ;; RW - probably reset? undocumented
VIA_REG_CTRL_INT equ (VIA_REG_CTRL_INT_FLAG or \
VIA_REG_CTRL_INT_EOL or \
VIA_REG_CTRL_AUTOSTART)
VIA_REG_OFFSET_TYPE equ 0x02 ;; byte - channel type (686 only)
VIA_REG_TYPE_AUTOSTART equ 0x80 ;; RW - autostart at EOL
VIA_REG_TYPE_16BIT equ 0x20 ;; RW
VIA_REG_TYPE_STEREO equ 0x10 ;; RW
VIA_REG_TYPE_INT_LLINE equ 0x00
VIA_REG_TYPE_INT_LSAMPLE equ 0x04
VIA_REG_TYPE_INT_LESSONE equ 0x08
VIA_REG_TYPE_INT_MASK equ 0x0c
VIA_REG_TYPE_INT_EOL equ 0x02
VIA_REG_TYPE_INT_FLAG equ 0x01
VIA_REG_OFFSET_TABLE_PTR equ 0x04 ;; dword - channel table pointer
VIA_REG_OFFSET_CURR_PTR equ 0x04 ;; dword - channel current pointer
VIA_REG_OFFSET_STOP_IDX equ 0x08 ;; dword - stop index, channel type, sample rate
VIA8233_REG_TYPE_16BIT equ 0x00200000 ;; RW
VIA8233_REG_TYPE_STEREO equ 0x00100000 ;; RW
VIA_REG_OFFSET_CURR_COUNT equ 0x0c ;; dword - channel current count (24 bit)
VIA_REG_OFFSET_CURR_INDEX equ 0x0f ;; byte - channel current index (for via8233 only)
 
 
VIADEV_PLAYBACK equ 0x00
VIADEV_CAPTURE equ 0x10
VIADEV_FM equ 0x20
 
;; AC'97 ;;
VIA_REG_AC97 equ 0x80 ; dword
VIA_REG_AC97_CODEC_ID_MASK equ 0xC0000000 ;(3<<30)
VIA_REG_AC97_CODEC_ID_SHIFT equ 30
VIA_REG_AC97_CODEC_ID_PRIMARY equ 0x00
VIA_REG_AC97_CODEC_ID_SECONDARY equ 0x01
VIA_REG_AC97_SECONDARY_VALID equ 0x08000000 ;(1<<27)
VIA_REG_AC97_PRIMARY_VALID equ 0x02000000 ;(1<<25)
VIA_REG_AC97_BUSY equ 0x01000000 ;(1<<24)
VIA_REG_AC97_READ equ 0x00800000 ;(1<<23)
VIA_REG_AC97_CMD_SHIFT equ 16
VIA_REG_AC97_CMD_MASK equ 0x7E
VIA_REG_AC97_DATA_SHIFT equ 0
VIA_REG_AC97_DATA_MASK equ 0xFFFF
 
VIA_REG_SGD_SHADOW equ 0x84 ; dword
 
;; via8233-specific registers ;;
VIA_REG_OFS_PLAYBACK_VOLUME_L equ 0x02 ;; byte
VIA_REG_OFS_PLAYBACK_VOLUME_R equ 0x03 ;; byte
VIA_REG_OFS_MULTPLAY_FORMAT equ 0x02 ;; byte - format and channels
VIA_REG_MULTPLAY_FMT_8BIT equ 0x00
VIA_REG_MULTPLAY_FMT_16BIT equ 0x80
VIA_REG_MULTPLAY_FMT_CH_MASK equ 0x70 ;; # channels << 4 (valid = 1,2,4,6)
VIA_REG_OFS_CAPTURE_FIFO equ 0x02 ;; byte - bit 6 = fifo enable
VIA_REG_CAPTURE_FIFO_ENABLE equ 0x40
 
VIA_DXS_MAX_VOLUME equ 31 ;; max. volume (attenuation) of reg 0x32/33
 
VIA_TBL_BIT_FLAG equ 0x40000000
VIA_TBL_BIT_EOL equ 0x80000000
 
;; pci space ;;
VIA_ACLINK_STAT equ 0x40
;...
VIA_ACLINK_C00_READY equ 0x01 ; primary codec ready
VIA_ACLINK_CTRL equ 0x41
VIA_ACLINK_CTRL_ENABLE equ 0x80 ; 0: disable, 1: enable
VIA_ACLINK_CTRL_RESET equ 0x40 ; 0: assert, 1: de-assert
VIA_ACLINK_CTRL_SYNC equ 0x20 ; 0: release SYNC, 1: force SYNC hi
VIA_ACLINK_CTRL_SDO equ 0x10 ; 0: release SDO, 1: force SDO hi
VIA_ACLINK_CTRL_VRA equ 0x08 ; 0: disable VRA, 1: enable VRA
VIA_ACLINK_CTRL_PCM equ 0x04 ; 0: disable PCM, 1: enable PCM
VIA_ACLINK_CTRL_FM equ 0x02 ; via686 only
VIA_ACLINK_CTRL_SB equ 0x01 ; via686 only
VIA_ACLINK_CTRL_INIT equ (VIA_ACLINK_CTRL_ENABLE or \
VIA_ACLINK_CTRL_RESET or \
VIA_ACLINK_CTRL_PCM or \
VIA_ACLINK_CTRL_VRA)
VIA_FUNC_ENABLE equ 0x42
VIA_FUNC_MIDI_PNP equ 0x80 ; FIXME: it's 0x40 in the datasheet!
VIA_FUNC_MIDI_IRQMASK equ 0x40 ; FIXME: not documented!
VIA_FUNC_RX2C_WRITE equ 0x20
VIA_FUNC_SB_FIFO_EMPTY equ 0x10
VIA_FUNC_ENABLE_GAME equ 0x08
VIA_FUNC_ENABLE_FM equ 0x04
VIA_FUNC_ENABLE_MIDI equ 0x02
VIA_FUNC_ENABLE_SB equ 0x01
VIA_PNP_CONTROL equ 0x43
VIA_FM_NMI_CTRL equ 0x48
VIA8233_VOLCHG_CTRL equ 0x48
VIA8233_SPDIF_CTRL equ 0x49
VIA8233_SPDIF_DX3 equ 0x08
VIA8233_SPDIF_SLOT_MASK equ 0x03
VIA8233_SPDIF_SLOT_1011 equ 0x00
VIA8233_SPDIF_SLOT_34 equ 0x01
VIA8233_SPDIF_SLOT_78 equ 0x02
VIA8233_SPDIF_SLOT_69 equ 0x03
;] Asper
 
 
SRV_GETVERSION equ 0
DEV_PLAY equ 1
DEV_STOP equ 2
DEV_CALLBACK equ 3
DEV_SET_BUFF equ 4
DEV_NOTIFY equ 5
DEV_SET_MASTERVOL equ 6
DEV_GET_MASTERVOL equ 7
DEV_GET_INFO equ 8
 
struc AC_CNTRL ;AC controller base class
{ .bus dd ?
.devfn dd ?
 
.vendor dd ?
.dev_id dd ?
.pci_cmd dd ?
.pci_stat dd ?
 
.codec_io_base dd ?
.codec_mem_base dd ?
 
.ctrl_io_base dd ?
.ctrl_mem_base dd ?
.cfg_reg dd ?
.int_line dd ?
 
.vendor_ids dd ? ;vendor id string
.ctrl_ids dd ? ;hub id string
 
.buffer dd ?
 
.notify_pos dd ?
.notify_task dd ?
 
.lvi_reg dd ?
.ctrl_setup dd ?
.user_callback dd ?
.codec_read16 dd ?
.codec_write16 dd ?
 
.ctrl_read8 dd ?
.ctrl_read16 dd ?
.ctrl_read32 dd ?
 
.ctrl_write8 dd ?
.ctrl_write16 dd ?
.ctrl_write32 dd ?
}
 
struc CODEC ;Audio Chip base class
{
.chip_id dd ?
.flags dd ?
.status dd ?
 
.ac_vendor_ids dd ? ;ac vendor id string
.chip_ids dd ? ;chip model string
 
.shadow_flag dd ?
dd ?
 
.regs dw ? ; codec registers
.reg_master_vol dw ? ;0x02
.reg_aux_out_vol dw ? ;0x04
.reg_mone_vol dw ? ;0x06
.reg_master_tone dw ? ;0x08
.reg_beep_vol dw ? ;0x0A
.reg_phone_vol dw ? ;0x0C
.reg_mic_vol dw ? ;0x0E
.reg_line_in_vol dw ? ;0x10
.reg_cd_vol dw ? ;0x12
.reg_video_vol dw ? ;0x14
.reg_aux_in_vol dw ? ;0x16
.reg_pcm_out_vol dw ? ;0x18
.reg_rec_select dw ? ;0x1A
.reg_rec_gain dw ? ;0x1C
.reg_rec_gain_mic dw ? ;0x1E
.reg_gen dw ? ;0x20
.reg_3d_ctrl dw ? ;0X22
.reg_page dw ? ;0X24
.reg_powerdown dw ? ;0x26
.reg_ext_audio dw ? ;0x28
.reg_ext_st dw ? ;0x2a
.reg_pcm_front_rate dw ? ;0x2c
.reg_pcm_surr_rate dw ? ;0x2e
.reg_lfe_rate dw ? ;0x30
.reg_pcm_in_rate dw ? ;0x32
dw ? ;0x34
.reg_cent_lfe_vol dw ? ;0x36
.reg_surr_vol dw ? ;0x38
.reg_spdif_ctrl dw ? ;0x3A
dw ? ;0x3C
dw ? ;0x3E
dw ? ;0x40
dw ? ;0x42
dw ? ;0x44
dw ? ;0x46
dw ? ;0x48
dw ? ;0x4A
dw ? ;0x4C
dw ? ;0x4E
dw ? ;0x50
dw ? ;0x52
dw ? ;0x54
dw ? ;0x56
dw ? ;0x58
dw ? ;0x5A
dw ? ;0x5C
dw ? ;0x5E
.reg_page_0 dw ? ;0x60
.reg_page_1 dw ? ;0x62
.reg_page_2 dw ? ;0x64
.reg_page_3 dw ? ;0x66
.reg_page_4 dw ? ;0x68
.reg_page_5 dw ? ;0x6A
.reg_page_6 dw ? ;0x6C
.reg_page_7 dw ? ;0x6E
dw ? ;0x70
dw ? ;0x72
dw ? ;0x74
dw ? ;0x76
dw ? ;0x78
dw ? ;0x7A
.reg_vendor_id_1 dw ? ;0x7C
.reg_vendor_id_2 dw ? ;0x7E
 
 
.reset dd ? ;virual
.set_master_vol dd ?
}
 
struc CTRL_INFO
{ .pci_cmd dd ?
.irq dd ?
.glob_cntrl dd ?
.glob_sta dd ?
.codec_io_base dd ?
.ctrl_io_base dd ?
.codec_mem_base dd ?
.ctrl_mem_base dd ?
.codec_id dd ?
}
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
EVENT_NOTIFY equ 0x00000200
 
public START
public service_proc
public version
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .stop
 
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
call detect_controller
test eax, eax
jz .fail
 
if DEBUG
mov esi,[ctrl.vendor_ids]
call SysMsgBoardStr
mov esi, [ctrl.ctrl_ids]
call SysMsgBoardStr
end if
 
call init_controller
test eax, eax
jz .fail
 
call init_codec
test eax, eax
jz .fail
 
call setup_codec
 
mov esi, msgPrimBuff
call SysMsgBoardStr
call create_primary_buff
mov esi, msgDone
call SysMsgBoardStr
 
if IRQ_REMAP
pushf
cli
 
mov ebx, [ctrl.int_line]
in al, 0xA1
mov ah, al
in al, 0x21
test ebx, ebx
jz .skip
bts ax, bx ;mask old line
.skip:
bts ax, IRQ_LINE ;mask new ine
out 0x21, al
mov al, ah
out 0xA1, al
 
stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE ;remap IRQ
 
mov dx, 0x4d0 ;8259 ELCR1
in al, dx
bts ax, IRQ_LINE
out dx, al ;set level-triggered mode
mov [ctrl.int_line], IRQ_LINE
popf
mov esi, msgRemap
call SysMsgBoardStr
end if
 
mov eax, VALID_IRQ
mov ebx, [ctrl.int_line]
mov esi, msgInvIRQ
bt eax, ebx
jnc .fail_msg
mov eax, ATTCH_IRQ
mov esi, msgAttchIRQ
bt eax, ebx
jnc .fail_msg
 
stdcall AttachIntHandler, ebx, ac97_irq_VIA, dword 0
.reg:
stdcall RegService, sz_sound_srv, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
xor eax, eax
ret
.fail_msg:
call SysMsgBoardStr
xor eax, eax
ret
.stop:
call stop
xor eax, eax
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edi, [ioctl]
mov eax, [edi+io_code]
 
cmp eax, SRV_GETVERSION
jne @F
mov eax, [edi+output]
cmp [edi+out_size], 4
jne .fail
 
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
cmp eax, DEV_PLAY
jne @F
if DEBUG
mov esi, msgPlay
call SysMsgBoardStr
end if
call play
ret
@@:
cmp eax, DEV_STOP
jne @F
if DEBUG
mov esi, msgStop
call SysMsgBoardStr
end if
call stop
ret
@@:
cmp eax, DEV_CALLBACK
jne @F
mov ebx, [edi+input]
stdcall set_callback, [ebx]
ret
@@:
cmp eax, DEV_SET_MASTERVOL
jne @F
mov eax, [edi+input]
mov eax, [eax]
call set_master_vol ;eax= vol
ret
@@:
cmp eax, DEV_GET_MASTERVOL
jne @F
mov ebx, [edi+output]
stdcall get_master_vol, ebx
ret
@@:
cmp eax, DEV_GET_INFO
jne @F
mov ebx, [edi+output]
stdcall get_dev_info, ebx
ret
@@:
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
 
align 4
proc ac97_irq_VIA
locals
status db 0
endl
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
call [ctrl.ctrl_read8]
test al, VIA_REG_STAT_ACTIVE
jz @f
 
and al, VIA_REG_STAT_EOL or VIA_REG_STAT_FLAG or VIA_REG_STAT_STOPPED
mov byte [status], al
 
mov ebx, dword [buff_list]
cmp [ctrl.user_callback], 0
je @f
stdcall [ctrl.user_callback], ebx
@@:
mov al, byte [status] ;; ack ;;
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
call [ctrl.ctrl_write8]
 
ret
endp
 
 
align 4
proc create_primary_buff
 
stdcall KernelAlloc, 0x10000
mov [ctrl.buffer], eax
 
mov edi, eax
mov ecx, 0x10000/4
xor eax, eax
cld
rep stosd
 
mov eax, [ctrl.buffer]
call GetPgAddr
mov edi, pcmout_bdl
stosd
mov eax, 0x80004000
stosd
 
mov edi, buff_list
mov eax, [ctrl.buffer]
mov ecx, 4
@@:
mov [edi], eax
mov [edi+16], eax
mov [edi+32], eax
mov [edi+48], eax
mov [edi+64], eax
mov [edi+80], eax
mov [edi+96], eax
mov [edi+112], eax
 
;add eax, 0x4000
add edi, 4
loop @B
 
stdcall channel_reset, VIADEV_PLAYBACK
stdcall codec_check_ready
 
mov eax, pcmout_bdl
mov ebx, eax
call GetPgAddr
and ebx, 0xFFF
add eax, ebx
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR
call [ctrl.ctrl_write32]
 
stdcall codec_check_ready
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_L
mov eax, 7;31
call [ctrl.ctrl_write8]
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFS_PLAYBACK_VOLUME_R
mov eax, 7;31
call [ctrl.ctrl_write8]
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
mov [ctrl.lvi_reg], 16;0xF;eax
call [ctrl.ctrl_write32]
 
stdcall codec_check_ready
ret
endp
 
 
proc channel_reset channel:dword
mov esi, dword [channel]
mov edx, esi
add edx, VIA_REG_OFFSET_CONTROL
mov eax, VIA_REG_CTRL_PAUSE or VIA_REG_CTRL_TERMINATE or VIA_REG_CTRL_RESET
call [ctrl.ctrl_write8]
 
mov edx, esi
add edx, VIA_REG_OFFSET_CONTROL
call [ctrl.ctrl_read8]
 
mov eax, 50000 ; wait 50 ms
call StallExec
; disable interrupts
mov edx, esi
add edx, VIA_REG_OFFSET_CONTROL
xor eax, eax
call [ctrl.ctrl_write8]
 
; clear interrupts
mov edx, esi
add edx, VIA_REG_OFFSET_STATUS
mov eax, 0x03
call [ctrl.ctrl_write8]
 
;outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
; mov edx, esi ;; for via686
; add edx, VIA_REG_OFFSET_TYPE
; mov eax, 0x03
; call [ctrl.ctrl_write8]
 
;; outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
;mov edx, esi
;add edx, VIA_REG_OFFSET_CURR_PTR
;xor eax, eax
;call [ctrl.ctrl_write8]
 
ret
endp
 
 
align 4
proc detect_controller
locals
last_bus dd ?
bus dd ?
devfn dd ?
endl
 
xor eax, eax
mov [bus], eax
inc eax
call PciApi
cmp eax, -1
je .err
 
mov [last_bus], eax
 
.next_bus:
and [devfn], 0
.next_dev:
stdcall PciRead32, [bus], [devfn], dword 0
test eax, eax
jz .next
cmp eax, -1
je .next
 
mov edi, devices
@@:
mov ebx, [edi]
test ebx, ebx
jz .next
 
cmp eax, ebx
je .found
add edi, 12
jmp @B
.next:
inc [devfn]
cmp [devfn], 256
jb .next_dev
mov eax, [bus]
inc eax
mov [bus], eax
cmp eax, [last_bus]
jna .next_bus
xor eax, eax
ret
.found:
mov ebx, [bus]
mov [ctrl.bus], ebx
 
mov ecx, [devfn]
mov [ctrl.devfn], ecx
 
mov edx, eax
and edx, 0xFFFF
mov [ctrl.vendor], edx
shr eax, 16
mov [ctrl.dev_id], eax
 
mov ebx, [edi+4]
mov [ctrl.ctrl_ids], ebx
mov esi, [edi+8]
mov [ctrl.ctrl_setup], esi
 
cmp edx, VID_VIA
jne @F
mov [ctrl.vendor_ids], msg_VIA
ret
@@:
 
.err:
xor eax, eax
mov [ctrl.vendor_ids], eax ;something wrong ?
ret
endp
 
align 4
proc init_controller
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
mov ebx, eax
and eax, 0xFFFF
mov [ctrl.pci_cmd], eax
shr ebx, 16
mov [ctrl.pci_stat], ebx
 
mov esi, msgPciCmd
call SysMsgBoardStr
call dword2str
call SysMsgBoardStr
 
mov esi, msgPciStat
call SysMsgBoardStr
mov eax, [ctrl.pci_stat]
call dword2str
call SysMsgBoardStr
 
mov esi, msgCtrlIsaIo
call SysMsgBoardStr
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
call dword2str
call SysMsgBoardStr
 
and eax, 0xFFC0
mov [ctrl.ctrl_io_base], eax
 
.default:
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
and eax, 0xFF
@@:
mov [ctrl.int_line], eax
 
;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE ;0x42
;mov byte [old_legacy], al
 
;stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_PNP_CONTROL ;0x43
;mov byte [old_legacy_cfg], al
 
;mov al, VIA_FUNC_ENABLE_SB or VIA_FUNC_ENABLE_FM
;xor al, 0xFF
;and al, byte [old_legacy]
;and eax, 0xFF
;stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_FUNC_ENABLE, eax ;0x42
;mov byte [old_legacy], al
 
call [ctrl.ctrl_setup]
xor eax, eax
inc eax
ret
endp
 
align 4
proc set_VIA
mov [ctrl.codec_read16], codec_io_r16 ;virtual
mov [ctrl.codec_write16], codec_io_w16 ;virtual
 
mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual
mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual
mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual
 
mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual
mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual
mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual
ret
endp
 
 
align 4
proc init_codec
locals
counter dd ?
endl
 
mov esi, msgControl
call SysMsgBoardStr
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL
and eax, 0xFF
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
and eax, 0xFF
push eax
call dword2str
call SysMsgBoardStr
pop eax
 
test eax, VIA_ACLINK_C00_READY
jz .ready
 
call reset_codec
test eax, eax
jz .err
 
.ready:
xor edx, edx ; ac_reg_0
call [ctrl.codec_write16]
jmp .done
 
.err:
xor eax, eax ; timeout error
ret
 
.done:
call detect_codec
 
xor eax, eax
inc eax
ret
endp
 
align 4
proc reset_codec
stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, \
VIA_ACLINK_CTRL_ENABLE or VIA_ACLINK_CTRL_RESET or VIA_ACLINK_CTRL_SYNC
mov eax, 100000 ; wait 100 ms
call StallExec
.cold:
call cold_reset
jnc .ok
 
if DEBUG
mov esi, msgCFail
call SysMsgBoardStr
end if
xor eax, eax ; timeout error
ret
.ok:
if DEBUG
mov esi, msgResetOk
call SysMsgBoardStr
end if
xor eax, eax
inc eax
ret
endp
 
 
align 4
proc cold_reset
locals
counter dd ?
endl
 
stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword 0
 
if DEBUG
mov esi, msgCold
call SysMsgBoardStr
end if
 
mov eax, 100000 ; wait 100 ms ;400000 ; wait 400 ms
call StallExec
 
;; ACLink on, deassert ACLink reset, VSR, SGD data out
;; note - FM data out has trouble with non VRA codecs !!
stdcall PciWrite8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL, dword VIA_ACLINK_CTRL_INIT
 
mov [counter], 16 ; total 20*100 ms = 2s
.wait:
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
test eax, VIA_ACLINK_C00_READY
jnz .ok
 
mov eax, 100000 ; wait 100 ms
call StallExec
 
dec [counter]
jnz .wait
 
if DEBUG
mov esi, msgCRFail
call SysMsgBoardStr
end if
 
.fail:
stc
ret
.ok:
mov esi, msgControl
call SysMsgBoardStr
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_CTRL
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword VIA_ACLINK_STAT
and eax, 0xFF
push eax
call dword2str
call SysMsgBoardStr
pop eax
 
test eax, VIA_ACLINK_C00_READY ;CTRL_ST_CREADY
jz .fail
clc
ret
endp
 
align 4
play:
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
mov eax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
mov [ctrl.lvi_reg], 16
call [ctrl.ctrl_write32]
 
mov eax, VIA_REG_CTRL_INT
or eax, VIA_REG_CTRL_START
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
call [ctrl.ctrl_write8]
 
xor eax, eax
ret
 
align 4
stop:
mov eax, VIA_REG_CTRL_INT
or eax, VIA_REG_CTRL_TERMINATE
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
call [ctrl.ctrl_write8]
 
stdcall channel_reset, VIADEV_PLAYBACK
xor eax, eax
ret
 
align 4
proc get_dev_info stdcall, p_info:dword
virtual at esi
CTRL_INFO CTRL_INFO
end virtual
 
mov esi, [p_info]
mov eax, [ctrl.int_line]
mov ecx, [ctrl.ctrl_io_base]
mov [CTRL_INFO.irq], eax
mov [CTRL_INFO.ctrl_io_base], ecx
 
xor eax, eax
;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_TABLE_PTR
;call [ctrl.ctrl_read32]
mov [CTRL_INFO.codec_io_base], eax
;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STOP_IDX
;call [ctrl.ctrl_read32]
mov [CTRL_INFO.codec_mem_base], eax
;mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CURR_COUNT
;call [ctrl.ctrl_read32]
mov [CTRL_INFO.ctrl_mem_base], eax
 
mov eax, [codec.chip_id]
mov [CTRL_INFO.codec_id], eax
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_CONTROL
call [ctrl.ctrl_read8]
and eax, 0xFF
mov [CTRL_INFO.glob_cntrl], eax
 
mov edx, VIADEV_PLAYBACK +VIA_REG_OFFSET_STATUS
call [ctrl.ctrl_read8]
and eax, 0xFF
mov [CTRL_INFO.glob_sta], eax
 
mov ebx, [ctrl.pci_cmd]
mov [CTRL_INFO.pci_cmd], ebx
ret
endp
 
align 4
proc set_callback stdcall, handler:dword
mov eax, [handler]
mov [ctrl.user_callback], eax
ret
endp
 
 
align 4
proc codec_check_ready stdcall
locals
counter dd ?
endl
 
mov [counter], 1000 ; total 1000*1 ms = 1s
.wait:
call [ctrl.codec_read16]
test eax, VIA_REG_AC97_BUSY
jz .ok
 
mov eax, 1000 ; wait 1 ms
call StallExec
 
sub [counter] , 1
jnz .wait
.err:
mov eax, -1
ret
.ok:
and eax, 0xFFFF
ret
endp
 
 
align 4
proc codec_valid stdcall
stdcall codec_check_ready
ret
endp
 
align 4
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax
locals
counter dd ?
endl
 
;Use only primary codec.
mov eax, [ac_reg]
and eax, 0x7F
shl eax, VIA_REG_AC97_CMD_SHIFT
or eax, VIA_REG_AC97_PRIMARY_VALID or VIA_REG_AC97_READ
 
mov [counter], 3 ; total 3*20 ms = 60ms
.wait:
push eax
call [ctrl.codec_write16]
 
mov eax, 20000 ; wait 20 ms
call StallExec
 
stdcall codec_valid,
cmp eax, 0
pop eax
jge .ok
 
sub [counter] , 1
jnz .wait
jmp .err
 
.ok:
mov eax, 25000 ; wait 25 ms
call StallExec
 
call [ctrl.codec_read16] ;change edx !!!
and eax, 0xFFFF
ret
.err:
if DEBUG
mov esi, msgCInvalid
call SysMsgBoardStr
end if
mov eax, -1 ; invalid codec error
ret
endp
 
align 4
proc codec_write stdcall, ac_reg:dword
;Use only primary codec.
mov esi, [ac_reg]
mov edx, esi
shl edx, VIA_REG_AC97_CMD_SHIFT
 
shl eax, VIA_REG_AC97_DATA_SHIFT
or edx, eax
 
mov eax, VIA_REG_AC97_CODEC_ID_PRIMARY ;not VIA_REG_AC97_CODEC_ID_PRIMARY
shl eax, VIA_REG_AC97_CODEC_ID_SHIFT
or edx, eax
 
mov eax, edx
mov edx, esi
call [ctrl.codec_write16]
mov [codec.regs+esi], ax
 
stdcall codec_check_ready
cmp eax, 0
jl .err
.ok:
ret
.err:
if DEBUG
mov esi, msgCFail
call SysMsgBoardStr
end if
;mov eax, -1 ; codec not ready error
ret
endp
 
align 4
proc StallExec
push ecx
push edx
push ebx
push eax
 
mov ecx, CPU_FREQ
mul ecx
mov ebx, eax ;low
mov ecx, edx ;high
rdtsc
add ebx, eax
adc ecx, edx
@@:
rdtsc
sub eax, ebx
sbb edx, ecx
js @B
 
pop eax
pop ebx
pop edx
pop ecx
ret
endp
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONTROLLER IO functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
proc codec_io_r16 ;r32
mov edx, [ctrl.ctrl_io_base]
add edx, VIA_REG_AC97
in eax, dx
ret
endp
 
align 4
proc codec_io_w16 ;w32
mov edx, [ctrl.ctrl_io_base]
add edx, VIA_REG_AC97
out dx, eax
ret
endp
 
align 4
proc ctrl_io_r8
add edx, [ctrl.ctrl_io_base]
in al, dx
ret
endp
 
align 4
proc ctrl_io_r16
add edx, [ctrl.ctrl_io_base]
in ax, dx
ret
endp
 
align 4
proc ctrl_io_r32
add edx, [ctrl.ctrl_io_base]
in eax, dx
ret
endp
 
align 4
proc ctrl_io_w8
add edx, [ctrl.ctrl_io_base]
out dx, al
ret
endp
 
align 4
proc ctrl_io_w16
add edx, [ctrl.ctrl_io_base]
out dx, ax
ret
endp
 
align 4
proc ctrl_io_w32
add edx, [ctrl.ctrl_io_base]
out dx, eax
ret
endp
 
 
align 4
dword2str:
push eax ebx ecx
mov esi, hex_buff
mov ecx, -8
@@:
rol eax, 4
mov ebx, eax
and ebx, 0x0F
mov bl, [ebx+hexletters]
mov [8+esi+ecx], bl
inc ecx
jnz @B
pop ecx ebx eax
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
 
include "codec.inc"
 
align 4
devices dd (CTRL_VT82C686 shl 16)+VID_VIA,msg_VT82C686,set_VIA
dd (CTRL_VT8233_5 shl 16)+VID_VIA,msg_VT8233,set_VIA
dd 0 ;terminator
 
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
msg_VT82C686 db 'VT82C686', 13,10, 0
msg_VT8233 db 'VT8233', 13,10, 0
msg_VIA db 'VIA' , 13,10, 0
 
szKernel db 'KERNEL', 0
sz_sound_srv db 'SOUND',0
 
msgInit db 'detect hardware...',13,10,0
msgFail db 'device not found',13,10,0
msgAttchIRQ db 'IRQ line not supported', 13,10, 0
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0
msgPlay db 'start play', 13,10,0
msgStop db 'stop play', 13,10,0
;msgIRQ db 'AC97 IRQ', 13,10,0
;msgInitCtrl db 'init controller',13,10,0
;msgInitCodec db 'init codec',13,10,0
msgPrimBuff db 'create primary buffer ...',0
msgDone db 'done',13,10,0
msgRemap db 'Remap IRQ',13,10,0
;msgReg db 'set service handler',13,10,0
;msgOk db 'service installed',13,10,0
msgCold db 'cold reset',13,10,0
;msgWarm db 'warm reset',13,10,0
;msgWRFail db 'warm reset failed',13,10,0
msgCRFail db 'cold reset failed',13,10,0
msgCFail db 'codec not ready',13,10,0
msgCInvalid db 'codec is not valid',13,10,0 ;Asper
msgResetOk db 'reset complete',13,10,0
msgStatus db 'global status ',0
msgControl db 'global control ',0
msgPciCmd db 'PCI command ',0
msgPciStat db 'PCI status ',0
msgCtrlIsaIo db 'controller io base ',0
;msgMixIsaIo db 'codec io base ',0
;msgCtrlMMIo db 'controller mmio base ',0
;msgMixMMIo db 'codec mmio base ',0
;msgIrqMap db 'AC97 irq map as ',0
 
 
section '.data' data readable writable align 16
 
pcmout_bdl rq 32
buff_list rd 32
 
codec CODEC
ctrl AC_CNTRL
 
chip_type rb 1
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/codec.inc
0,0 → 1,326
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
AD_LOSEL equ BIT5
AD_HPSEL equ BIT10
 
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
mov esi, eax
call SysMsgBoardStr
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
 
mov esi, chip_unknown
call SysMsgBoardStr
mov eax, [codec.chip_id]
call dword2str
call SysMsgBoardStr
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]
cmp ebx, 0xFF
je .unknown
 
cmp eax,ebx
jne .next
mov eax, [edi+4]
mov [codec.chip_ids], eax
mov esi, eax
call SysMsgBoardStr
ret
.next:
add edi, 8
jmp @b
.unknown:
mov [codec.chip_ids], chip_unknown
mov esi, chip_unknown
call SysMsgBoardStr
mov eax, [codec.chip_id]
call dword2str
call SysMsgBoardStr
ret
endp
 
align 4
proc setup_codec
 
xor eax, eax
stdcall codec_write, dword CODEC_AUX_VOL
 
mov eax, 0x0B0B
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
 
 
; param
; eax= volume -10000 - 0 for both channels
 
align 4
set_master_vol:
cmp eax, 0
jl @F
xor eax, eax
jmp .set
@@:
cmp eax, -9450
jg .set
mov eax, -9450 ;clamp into 6 bits
.set:
cdq
mov ebx, -150
idiv ebx
mov ah, al
stdcall codec_write, dword CODEC_MASTER_VOL_REG
xor eax, eax
ret
 
align 4
proc get_master_vol stdcall, pvol:dword
 
stdcall codec_read, dword CODEC_MASTER_VOL_REG
and eax, 0x3F
imul eax, -150
mov ebx, [pvol]
mov [ebx], eax
xor eax, 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
 
patch_AD:
stdcall codec_read, 0x76
or ax, BIT5+BIT10
stdcall codec_write, 0x76
ret
 
 
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
ac_Cirrus db 'Cirrus Logic',13,10,0
ac_Wolfson db 'Wolfson Microelectronics',13,10,0
ac_VIA db 'VIA Technologies',13,10,0
ac_SigmaTel db 'SigmaTel',13,10,0
ac_eMicro db 'eMicro',13,10,0
 
chip_unknown db 'unknown codec id ', 0
 
CHIP_ANALOG equ 0x41445300
CHIP_REALTEK equ 0x414C4700
CHIP_CMEDIA equ 0x434D4900
CHIP_CIRRUS equ 0x43525900
CHIP_WOLFSON equ 0x574D4C00
CHIP_VIA equ 0x56494100
CHIP_SIGMATEL equ 0x83847600
CHIP_EMICRO equ 0x454D4300
 
align 16
codecs dd CHIP_ANALOG, ac_Analog, chips_Analog
dd CHIP_CMEDIA, ac_CMedia, chips_CMedia
dd CHIP_REALTEK,ac_Realtek, chips_Realtek
dd CHIP_CIRRUS, ac_Cirrus, chips_Cirrus
dd CHIP_WOLFSON,ac_Wolfson, chips_Wolfson
dd CHIP_VIA, ac_VIA, chips_VIA
dd CHIP_SIGMATEL, ac_SigmaTel, chips_SigmaTel
dd CHIP_EMICRO, ac_eMicro, chips_eMicro
dd 0
 
align 16
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 0x72, chip_AD1981A
dd 0x74, chip_AD1981B
dd 0x75, chip_AD1985
dd 0xFF
 
chips_Realtek:
dd 0x10, chip_ALC201a
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 0xFF
 
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 0xFF
 
chips_Cirrus dd 0x00, chip_CS4297
dd 0x10, chip_CS4297A
dd 0x20, chip_CS4298
dd 0x28, chip_CS4294
dd 0x30, chip_CS4299
dd 0x34, chip_CS4299D
dd 0x48, chip_CS4201
dd 0x58, chip_CS4205
dd 0x60, chip_CS4291
dd 0x70, chip_CS4202
dd 0xFF
 
chips_Wolfson dd 0x00, chip_WM9700
dd 0x03, chip_WM9703
dd 0x04, chip_WM9704
dd 0xFF
 
chips_VIA dd 0x61, chip_VIA1612A
dd 0xFF
 
chips_SigmaTel dd 0x58, chip_STAC9758
dd 0xFF
 
chips_eMicro dd 0x28, chip_EM28028
dd 0xFF
 
align 16
;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_AD1981A db 'AD1981A',0dh,0ah,00h
chip_AD1981B db 'AD1981B',0dh,0ah,00h
chip_AD1985 db 'AD1985 ',0dh,0ah,00h
 
;Realtek
chip_ALC201a db 'ALC201a',0dh,0ah,00h
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
 
;Cirrus
chip_CS4297 db 'CS4297',13,10,0
chip_CS4297A db 'CS4297A',13,10,0
chip_CS4298 db 'CS4298',13,10,0
chip_CS4294 db 'CS4294',13,10,0
chip_CS4299 db 'CS4299',13,10,0
chip_CS4299D db 'CS4299D',13,10,0
chip_CS4201 db 'CS4201',13,10,0
chip_CS4205 db 'CS4205',13,10,0
chip_CS4291 db 'CS4291',13,10,0
chip_CS4202 db 'CS4202',13,10,0
 
;Wolfson
chip_WM9700 db 'WM9704',13,10,0
chip_WM9703 db 'WM9703/9704',13,10,0
chip_WM9704 db 'WM9704 (quad)',13,10,0
 
;VIA
chip_VIA1612A db 'VIA1612A',13,10,0
 
;SigmaTel
chip_STAC9758 db 'STAC9758,59',13,10,0
 
;eMicro
chip_EM28028 db 'EM28028',13,10,0
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/fm801.asm
0,0 → 1,1061
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
format MS COFF
 
DEBUG equ 1
DEBUG_IRQ equ 0
 
include 'proc32.inc'
include 'imports.inc'
 
API_VERSION equ 0x01000100
 
USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices
 
;irq 0,1,2,8,12,13 íåäîñòóïíû
; FEDCBA9876543210
VALID_IRQ equ 1100111011111000b
ATTCH_IRQ equ 0000111010100000b
 
if USE_COM_IRQ
ATTCH_IRQ equ 0000111010111000b
end if
 
CPU_FREQ equ 2000d
 
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_FM801 equ 0x1319
CTRL_FM801 equ 0x0801
 
FM_PCM_VOLUME equ 0x00
FM_FM_VOLUME equ 0x02
FM_I2S_VOLUME equ 0x04
FM_RECORD_SOURCE equ 0x06
 
FM_PLAY_CTL equ 0x08
FM_PLAY_RATE_MASK equ 0x0f00
FM_PLAY_BUF1_LAST equ 0x0001
FM_PLAY_BUF2_LAST equ 0x0002
FM_PLAY_START equ 0x0020
FM_PLAY_PAUSE equ 0x0040
FM_PLAY_STOPNOW equ 0x0080
FM_PLAY_16BIT equ 0x4000
FM_PLAY_STEREO equ 0x8000
 
FM_PLAY_DMALEN equ 0x0a
FM_PLAY_DMABUF1 equ 0x0c
FM_PLAY_DMABUF2 equ 0x10
 
FM_REC_CTL equ 0x14
FM_REC_RATE_MASK equ 0x0f00
FM_REC_BUF1_LAST equ 0x0001
FM_REC_BUF2_LAST equ 0x0002
FM_REC_START equ 0x0020
FM_REC_PAUSE equ 0x0040
FM_REC_STOPNOW equ 0x0080
FM_REC_16BIT equ 0x4000
FM_REC_STEREO equ 0x8000
 
FM_REC_DMALEN equ 0x16
FM_REC_DMABUF1 equ 0x18
FM_REC_DMABUF2 equ 0x1c
 
FM_CODEC_CTL equ 0x22
FM_VOLUME equ 0x26
FM_VOLUME_MUTE equ 0x8000
 
FM_CODEC_CMD equ 0x2a
FM_CODEC_CMD_READ equ 0x0080
FM_CODEC_CMD_VALID equ 0x0100
FM_CODEC_CMD_BUSY equ 0x0200
 
FM_CODEC_DATA equ 0x2c
 
FM_IO_CTL equ 0x52
FM_CARD_CTL equ 0x54
 
FM_INTMASK equ 0x56
FM_INTMASK_PLAY equ 0x0001
FM_INTMASK_REC equ 0x0002
FM_INTMASK_VOL equ 0x0040
FM_INTMASK_MPU equ 0x0080
 
FM_INTSTATUS equ 0x5a
FM_INTSTATUS_PLAY equ 0x0100
FM_INTSTATUS_REC equ 0x0200
FM_INTSTATUS_VOL equ 0x4000
FM_INTSTATUS_MPU equ 0x8000
 
CODEC_MASTER_VOL_REG equ 0x02 ;
CODEC_AUX_VOL equ 0x04 ;
CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume
CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio
CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control
CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate
CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate
CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate
 
SRV_GETVERSION equ 0
DEV_PLAY equ 1
DEV_STOP equ 2
DEV_CALLBACK equ 3
DEV_SET_BUFF equ 4
DEV_NOTIFY equ 5
DEV_SET_MASTERVOL equ 6
DEV_GET_MASTERVOL equ 7
DEV_GET_INFO equ 8
 
struc AC_CNTRL ;AC controller base class
{ .bus dd ?
.devfn dd ?
 
.vendor dd ?
.dev_id dd ?
.pci_cmd dd ?
.pci_stat dd ?
 
.codec_io_base dd ?
.codec_mem_base dd ?
 
.ctrl_io_base dd ?
.ctrl_mem_base dd ?
.cfg_reg dd ?
.int_line dd ?
 
.vendor_ids dd ? ;vendor id string
.ctrl_ids dd ? ;hub id string
 
.buffer dd ?
 
.notify_pos dd ?
.notify_task dd ?
 
.lvi_reg dd ?
.ctrl_setup dd ?
.user_callback dd ?
.codec_read16 dd ?
.codec_write16 dd ?
 
.ctrl_read8 dd ?
.ctrl_read16 dd ?
.ctrl_read32 dd ?
 
.ctrl_write8 dd ?
.ctrl_write16 dd ?
.ctrl_write32 dd ?
}
 
struc CODEC ;Audio Chip base class
{
.chip_id dd ?
.flags dd ?
.status dd ?
 
.ac_vendor_ids dd ? ;ac vendor id string
.chip_ids dd ? ;chip model string
 
.shadow_flag dd ?
dd ?
 
.regs dw ? ; codec registers
.reg_master_vol dw ? ;0x02
.reg_aux_out_vol dw ? ;0x04
.reg_mone_vol dw ? ;0x06
.reg_master_tone dw ? ;0x08
.reg_beep_vol dw ? ;0x0A
.reg_phone_vol dw ? ;0x0C
.reg_mic_vol dw ? ;0x0E
.reg_line_in_vol dw ? ;0x10
.reg_cd_vol dw ? ;0x12
.reg_video_vol dw ? ;0x14
.reg_aux_in_vol dw ? ;0x16
.reg_pcm_out_vol dw ? ;0x18
.reg_rec_select dw ? ;0x1A
.reg_rec_gain dw ? ;0x1C
.reg_rec_gain_mic dw ? ;0x1E
.reg_gen dw ? ;0x20
.reg_3d_ctrl dw ? ;0X22
.reg_page dw ? ;0X24
.reg_powerdown dw ? ;0x26
.reg_ext_audio dw ? ;0x28
.reg_ext_st dw ? ;0x2a
.reg_pcm_front_rate dw ? ;0x2c
.reg_pcm_surr_rate dw ? ;0x2e
.reg_lfe_rate dw ? ;0x30
.reg_pcm_in_rate dw ? ;0x32
dw ? ;0x34
.reg_cent_lfe_vol dw ? ;0x36
.reg_surr_vol dw ? ;0x38
.reg_spdif_ctrl dw ? ;0x3A
dw ? ;0x3C
dw ? ;0x3E
dw ? ;0x40
dw ? ;0x42
dw ? ;0x44
dw ? ;0x46
dw ? ;0x48
dw ? ;0x4A
dw ? ;0x4C
dw ? ;0x4E
dw ? ;0x50
dw ? ;0x52
dw ? ;0x54
dw ? ;0x56
dw ? ;0x58
dw ? ;0x5A
dw ? ;0x5C
dw ? ;0x5E
.reg_page_0 dw ? ;0x60
.reg_page_1 dw ? ;0x62
.reg_page_2 dw ? ;0x64
.reg_page_3 dw ? ;0x66
.reg_page_4 dw ? ;0x68
.reg_page_5 dw ? ;0x6A
.reg_page_6 dw ? ;0x6C
.reg_page_7 dw ? ;0x6E
dw ? ;0x70
dw ? ;0x72
dw ? ;0x74
dw ? ;0x76
dw ? ;0x78
dw ? ;0x7A
.reg_vendor_id_1 dw ? ;0x7C
.reg_vendor_id_2 dw ? ;0x7E
 
 
.reset dd ? ;virual
.set_master_vol dd ?
}
 
struc CTRL_INFO
{ .pci_cmd dd ?
.irq dd ?
.glob_cntrl dd ?
.glob_sta dd ?
.codec_io_base dd ?
.ctrl_io_base dd ?
.codec_mem_base dd ?
.ctrl_mem_base dd ?
.codec_id dd ?
}
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
EVENT_NOTIFY equ 0x00000200
 
public START
public service_proc
public version
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .stop
 
if DEBUG
mov eax, START
call dword2str
call SysMsgBoardStr
mov esi, msgInit
call SysMsgBoardStr
end if
 
call detect_controller
test eax, eax
jz .fail
 
if DEBUG
mov esi, [ctrl.vendor_ids]
call SysMsgBoardStr
mov esi, [ctrl.ctrl_ids]
call SysMsgBoardStr
 
end if
 
call init_controller
test eax, eax
jz .fail
 
call init_codec
test eax, eax
jz .fail
 
call reset_controller
call setup_codec
 
mov esi, msgPrimBuff
call SysMsgBoardStr
call create_primary_buff
 
mov esi, msgDone
call SysMsgBoardStr
 
mov eax, VALID_IRQ
mov ebx, [ctrl.int_line]
mov esi, msgInvIRQ
bt eax, ebx
jnc .fail_msg
mov eax, ATTCH_IRQ
mov esi, msgAttchIRQ
bt eax, ebx
jnc .fail_msg
 
stdcall AttachIntHandler, ebx, ac97_irq, dword 0
.reg:
 
stdcall RegService, sz_sound_srv, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
xor eax, eax
ret
.fail_msg:
call SysMsgBoardStr
xor eax, eax
ret
.stop:
call stop
xor eax, eax
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edi, [ioctl]
mov eax, [edi+io_code]
 
cmp eax, SRV_GETVERSION
jne @F
 
mov eax, [edi+output]
cmp [edi+out_size], 4
jne .fail
 
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
cmp eax, DEV_PLAY
jne @F
if DEBUG
mov esi, msgPlay
call SysMsgBoardStr
end if
call play
ret
@@:
cmp eax, DEV_STOP
jne @F
if DEBUG
mov esi, msgStop
call SysMsgBoardStr
end if
call stop
ret
@@:
cmp eax, DEV_CALLBACK
jne @F
mov ebx, [edi+input]
stdcall set_callback, [ebx]
ret
@@:
cmp eax, DEV_SET_MASTERVOL
jne @F
mov eax, [edi+input]
mov eax, [eax]
call set_master_vol ;eax= vol
ret
@@:
cmp eax, DEV_GET_MASTERVOL
jne @F
mov ebx, [edi+output]
stdcall get_master_vol, ebx
ret
;@@:
; cmp eax, DEV_GET_INFO
; jne @F
; mov ebx, [edi+output]
; stdcall get_dev_info, ebx
; ret
@@:
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
align 4
proc fill_buffer
 
cmp [ctrl.user_callback], 0
je .exit
 
mov esi, [ctrl.buffer]
mov eax, int_flip_flop
inc dword [eax]
test dword [eax],1
je @f
add esi, 0x4000
@@:
stdcall [ctrl.user_callback], esi
 
mov edx, FM_PLAY_DMABUF1
mov eax, [buffer_pgaddr]
mov esi, int_flip_flop
test dword [esi],1
je @f
mov edx, FM_PLAY_DMABUF2
add eax, 0x4000
@@:
call [ctrl.ctrl_write32]
 
.exit:
ret
endp
 
align 4
proc ac97_irq
 
if DEBUG_IRQ
mov esi, msgIRQ
call SysMsgBoardStr
end if
 
mov edx, FM_INTSTATUS
call [ctrl.ctrl_read16]
 
test eax, FM_INTSTATUS_PLAY
je .exit
 
push eax
call fill_buffer
pop eax
 
.exit:
mov edx, FM_INTSTATUS
call [ctrl.ctrl_write16]
 
ret
endp
 
align 4
proc create_primary_buff
 
stdcall KernelAlloc, 0x10000
mov [ctrl.buffer], eax
 
mov edi, eax
mov ecx, 0x10000/4
xor eax, eax
cld
rep stosd
 
mov eax, [ctrl.buffer]
call GetPgAddr
mov [buffer_pgaddr], eax
 
ret
endp
 
align 4
proc detect_controller
locals
last_bus dd ?
bus dd ?
devfn dd ?
endl
 
xor eax, eax
mov [bus], eax
inc eax
call PciApi
cmp eax, -1
je .err
 
mov [last_bus], eax
 
.next_bus:
and [devfn], 0
.next_dev:
stdcall PciRead32, [bus], [devfn], dword 0
test eax, eax
jz .next
cmp eax, -1
je .next
 
push eax
stdcall PciRead32, [bus], [devfn], dword 0x09
and eax,0xffffff
cmp eax, 0x060100 ;pci-isa
jne .no_bridge
 
mov eax, [bus]
mov [brg_bus], eax
mov eax, [devfn]
mov [brg_devfn],eax
.no_bridge:pop eax
 
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_FM
 
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
 
mov esi, msgPciCmd
call SysMsgBoardStr
call dword2str
call SysMsgBoardStr
 
mov esi, msgPciStat
call SysMsgBoardStr
mov eax, [ctrl.pci_stat]
call dword2str
call SysMsgBoardStr
 
mov esi, msgCtrlIsaIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
 
call dword2str
call SysMsgBoardStr
 
and eax,0xFFFE
mov [ctrl.ctrl_io_base], eax
 
mov esi, msgIrqNum
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
and eax, 0xFF
mov [ctrl.int_line], eax
 
call dword2str
call SysMsgBoardStr
 
call [ctrl.ctrl_setup]
xor eax, eax
inc eax
ret
endp
 
align 4
proc set_FM
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
 
mov esi, msgInitCtrl
call SysMsgBoardStr
 
mov edx, FM_CARD_CTL
call [ctrl.ctrl_read8]
push eax
or al,1
mov edx, FM_CARD_CTL
call [ctrl.ctrl_write8]
mov eax, 10
call StallExec
pop eax
and al,0xFE
mov edx, FM_CARD_CTL
call [ctrl.ctrl_write8]
mov eax, 10
call StallExec
 
mov eax, 0x0404
mov edx, FM_PCM_VOLUME
call [ctrl.ctrl_write16]
mov edx, FM_FM_VOLUME
call [ctrl.ctrl_write16]
mov edx, FM_I2S_VOLUME
call [ctrl.ctrl_write16]
 
mov edx, FM_INTMASK
call [ctrl.ctrl_read16]
and eax, not FM_INTMASK_PLAY
or eax, FM_INTMASK_REC or FM_INTMASK_MPU or FM_INTMASK_VOL
mov edx, FM_INTMASK
call [ctrl.ctrl_write16]
 
mov eax, FM_INTMASK_PLAY or FM_INTMASK_REC or FM_INTMASK_MPU or FM_INTMASK_VOL
mov edx, FM_INTSTATUS
call [ctrl.ctrl_write16]
 
ret
endp
 
align 4
proc init_codec
 
mov esi, msgInitCodec
call SysMsgBoardStr
 
mov al, FM_CODEC_CMD_READ
mov edx, FM_CODEC_CMD
call [ctrl.ctrl_write8]
 
call reset_codec
 
call detect_codec
 
xor eax, eax
inc eax
ret
endp
 
align 4
proc reset_codec
 
mov ecx, 255
.L1:
mov edx, FM_CODEC_CMD
call [ctrl.ctrl_read16]
test ah, FM_CODEC_CMD_VALID shr 8
jne .L2
loop .L1
.L2:
mov edx, FM_CODEC_CTL
call [ctrl.ctrl_read8]
push eax
or al, 0x20
mov edx, FM_CODEC_CTL
call [ctrl.ctrl_write8]
pop eax
and al,0xDF
mov edx, FM_CODEC_CTL
call [ctrl.ctrl_write8]
 
xor eax, eax
inc eax
ret
endp
 
align 4
play:
mov eax, 0x4000-1
mov edx, FM_PLAY_DMALEN
call [ctrl.ctrl_write16]
 
call fill_buffer
 
mov eax, FM_PLAY_START or FM_PLAY_STOPNOW or FM_PLAY_STEREO or FM_PLAY_16BIT or 0xA00
mov edx, FM_PLAY_CTL
call [ctrl.ctrl_write16]
 
xor eax, eax
ret
 
align 4
stop:
mov edx, FM_PLAY_CTL
call [ctrl.ctrl_read16]
and eax, not (FM_PLAY_START or FM_PLAY_STOPNOW)
or eax, FM_PLAY_BUF1_LAST or FM_PLAY_BUF2_LAST
mov edx, FM_PLAY_CTL
call [ctrl.ctrl_write16]
 
xor eax, eax
ret
 
align 4
proc get_dev_info stdcall, p_info:dword
virtual at esi
CTRL_INFO CTRL_INFO
end virtual
 
mov esi, [p_info]
mov eax, [ctrl.int_line]
mov 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 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
 
.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
 
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
endp
 
align 4
proc check_semafore
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
js @B
 
pop eax
pop ebx
pop edx
pop ecx
ret
endp
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONTROLLER IO functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
proc codec_io_r16
 
push edx
mov ecx, 255
.L1:
mov edx, FM_CODEC_CMD
call [ctrl.ctrl_read16]
test ah, FM_CODEC_CMD_BUSY shr 8
je .L2
loop .L1
.L2:
pop eax
or al, FM_CODEC_CMD_READ
mov edx, FM_CODEC_CMD
call [ctrl.ctrl_write8]
 
mov ecx, 255
.L3:
mov edx, FM_CODEC_CMD
call [ctrl.ctrl_read16]
test ah, FM_CODEC_CMD_VALID shr 8
jne .L4
loop .L3
.L4:
mov edx, FM_CODEC_DATA
call [ctrl.ctrl_read16]
 
ret
endp
 
align 4
proc codec_io_w16
 
push edx
push eax
mov ecx, 255
.L1:
mov edx, FM_CODEC_CMD
call [ctrl.ctrl_read16]
test ah, FM_CODEC_CMD_BUSY shr 8
je .L2
loop .L1
.L2:
pop eax
mov edx, FM_CODEC_DATA
call [ctrl.ctrl_write16]
 
pop eax
mov edx, FM_CODEC_CMD
call [ctrl.ctrl_write16]
 
ret
endp
 
align 4
proc ctrl_io_r8
add edx, [ctrl.ctrl_io_base]
in al, dx
ret
endp
 
align 4
proc ctrl_io_r16
add edx, [ctrl.ctrl_io_base]
in ax, dx
ret
endp
 
align 4
proc ctrl_io_r32
add edx, [ctrl.ctrl_io_base]
in eax, dx
ret
endp
 
align 4
proc ctrl_io_w8
add edx, [ctrl.ctrl_io_base]
out dx, al
ret
endp
 
align 4
proc ctrl_io_w16
add edx, [ctrl.ctrl_io_base]
out dx, ax
ret
endp
 
align 4
proc ctrl_io_w32
add edx, [ctrl.ctrl_io_base]
out dx, eax
ret
endp
 
align 4
dword2str:
mov esi, hex_buff
mov ecx, -8
@@:
rol eax, 4
mov ebx, eax
and ebx, 0x0F
mov bl, [ebx+hexletters]
mov [8+esi+ecx], bl
inc ecx
jnz @B
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
brg_bus dd ?
brg_devfn dd ?
include "codec.inc"
 
align 4
devices dd (CTRL_FM801 shl 16)+VID_FM801, msg_FM801, set_FM
dd 0
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
msg_FM801 db 'FM801 AC97 controller',13,10, 0
msg_FM db 'Forte Media',13,10, 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 ...',0
msgDone db 'done',13,10,0
;msgReg db 'set service handler',13,10,0
;msgOk db 'service installed',13,10,0
;msgStatus db 'global status ',0
;msgControl db 'global control ',0
msgPciCmd db 'PCI command ',0
msgPciStat db 'PCI status ',0
msgCtrlIsaIo db 'controller io base ',0
msgIrqNum db 'IRQ default ',0
;msgIrqMap db 'AC97 irq map as ',0
 
section '.data' data readable writable align 16
 
codec CODEC
ctrl AC_CNTRL
 
int_flip_flop rd 1
buffer_pgaddr rd 1
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/com_mouse.asm
0,0 → 1,382
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Includes source code by Kulakov Vladimir Gennadievich. ;;
;; Modified by Mario79 and Rus. ;;
;; 02.12.2009 <Lrz> ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;driver sceletone
 
format MS COFF
 
DEBUG equ 0
 
include 'proc32.inc'
include 'imports.inc'
 
API_VERSION equ 5 ;debug
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
public START
public version
 
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
STRIDE equ 4 ;size of row in devices table
 
SRV_GETVERSION equ 0
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .exit
.entry:
;Detect_COM_Mouse:
if DEBUG
mov esi, msgInit
call Boot_Log
end if
mov bx, 0x3f8
call MSMouseSearch
cmp AL,'M'
jne @f
;mov [com1_mouse_detected],1
;mov [irq_owner+4*4], 1 ; IRQ4 owner is System
 
mov dx, bx
inc dx ; 0x3f8 + 1
mov al, 1
out dx, al
 
stdcall AttachIntHandler, 4, irq4_handler, dword 0
if DEBUG
test eax, eax
jne .label1
 
mov esi, msg_error_attach_int_handler
call Boot_Log
end if
.label1:
; mov eax, 0
; mov ebx, 0x3F8
; mov ecx, 0x3FF
xor ebx,ebx
mov ecx, 0x3F8
mov edx, 0x3FF
call ReservePortArea
 
if DEBUG
cmp eax, 1
jne .go
 
mov esi, msg_error_reserve_ports
call Boot_Log
 
.go:
mov esi,boot_setmouse_type
call Boot_Log
end if
@@:
mov bx, 0x2f8
call MSMouseSearch
cmp AL,'M'
jne .resume
;mov [com2_mouse_detected],1
;mov [irq_owner+3*4], 1 ; IRQ3 owner is System
 
stdcall AttachIntHandler, 3, irq3_handler, dword 0
 
; mov eax, 0
; mov ebx, 0x2F8
; mov ecx, 0x3F8
xor ebx,ebx
mov ecx, 0x2F8
mov edx, 0x3F8
 
call ReservePortArea
if DEBUG
cmp eax, 1
jne @f
 
mov esi, msg_error_reserve_ports
call Boot_Log
@@:
 
mov esi,boot_setmouse_type + 22
call Boot_Log
end if
.resume:
 
stdcall RegService, my_service, service_proc
if DEBUG
test eax, eax
jne @f
 
mov esi, msg_exit
call Boot_Log
end if
@@:
ret
.fail:
.exit:
if DEBUG
mov esi, msg_exit
call Boot_Log
end if
xor eax, eax
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov ebx, [ioctl]
mov eax, [ebx+io_code]
cmp eax, SRV_GETVERSION
jne @F
 
mov eax, [ebx+output]
cmp [ebx+out_size], 4
jne .fail
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
.fail:
or eax, -1
ret
endp
 
align 4
MSMouseSearch:
; ÏÎÈÑÊ ÌÛØÈ ×ÅÐÅÇ COM-ÏÎÐÒÛ
MouseSearch:
; Óñòàíàâëèâàåì ñêîðîñòü
; ïðèåìà/ïåðåäà÷è 1200 áîä
; in bx COM Port Base Address
mov DX, bx
add DX,3
in AL,DX
or AL,80h ;óñòàíîâèòü áèò DLAB
out DX,AL
mov DX, bx
mov AL,60h ;1200 áîä
out DX,AL
inc DX
mov AL,0
out DX,AL
; Óñòàíîâèòü äëèíó ñëîâà 7 áèò, 1 ñòîïîâûé áèò,
; ÷åòíîñòü íå êîíòðîëèðîâàòü
mov DX, bx
add DX,3
mov AL,00000010b
out DX,AL
; Çàïðåòèòü âñå ïðåðûâàíè
mov dx, bx
inc dx
mov AL,0
out DX,AL
; Ïðîâåðèòü, ÷òî óñòðîéñòâî ïîäêëþ÷åíî è ÿâëÿåòñ
; ìûøüþ òèïà MSMouse
; Îòêëþ÷èòü ïèòàíèå ìûøè è ïðåðûâàíè
mov DX, bx
add EDX,4 ;ðåãèñòð óïðàâëåíèÿ ìîäåìîì
mov AL,0 ;ñáðîñèòü DTR, RTS è OUT2
out DX,AL
; Îæèäàòü 5 "òèêîâ" (0,2 ñ)
mov ecx, 0xFFFF
loop $
; Âêëþ÷èòü ïèòàíèå ìûøè
mov al, 1
out dx, al
mov ecx, 0xFFFF
loop $
; Î÷èñòèòü ðåãèñòð äàííûõ
mov dx, bx
in AL,DX
add edx, 4
mov AL, 1011b ;óñòàíîâèòü DTR è RTS è OUT2
out DX,AL
mov ecx, 0x1FFFF
; Öèêë îïðîñà ïîðòà
WaitData:
; Îæèäàòü åùå 10 "òèêîâ"
dec ecx
; cmp ecx,0
jz NoMouse
; Ïðîâåðèòü íàëè÷èå èäåíòèôèêàöèîííîãî áàéòà
mov DX, bx
add DX,5
in AL,DX
test AL,1 ;Äàííûå ãîòîâû?
jz WaitData
; Ââåñòè äàííûå
mov DX, bx
in AL,DX
NoMouse:
ret
 
align 4
irq3_handler:
mov dx, 0x2f8
mov esi, com2_mouse
jmp irq_handler
 
align 4
irq4_handler:
mov dx, 0x3f8
mov esi, com1_mouse
 
irq_handler:
 
; in: esi -> COM_MOUSE_DATA struc, dx = base port (xF8h)
add edx, 5 ; xFDh
in al, dx
test al, 1 ; Äàííûå ãîòîâû?
jz .Error
; Ââåñòè äàííûå
sub edx, 5
in al, dx
; Ñáðîñèòü ñòàðøèé íåçíà÷àùèé áèò
and al, 01111111b
 
; Îïðåäåëèòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà
cmp [esi+COM_MOUSE_DATA.MouseByteNumber], 2
ja .Error
jz .ThirdByte
jp .SecondByte
; Ñîõðàíèòü ïåðâûé áàéò äàííûõ
.FirstByte:
test al, 1000000b ; Ïåðâûé áàéò ïîñûëêè?
jz .Error
mov [esi+COM_MOUSE_DATA.FirstByte], al
inc [esi+COM_MOUSE_DATA.MouseByteNumber]
jmp .EndMouseInterrupt
; Ñîõðàíèòü âòîðîé áàéò äàííûõ
.SecondByte:
test al, 1000000b
jnz .Error
mov [esi+COM_MOUSE_DATA.SecondByte], al
inc [esi+COM_MOUSE_DATA.MouseByteNumber]
jmp .EndMouseInterrupt
; Ñîõðàíèòü òðåòèé áàéò äàííûõ
.ThirdByte:
test al, 1000000b
jnz .Error
mov [esi+COM_MOUSE_DATA.ThirdByte], al
mov [esi+COM_MOUSE_DATA.MouseByteNumber], 0
; (Ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ).
; Çàïèñàòü íîâîå çíà÷åíèå ñîñòîÿíèÿ êíîïîê ìûøè
mov al, [esi+COM_MOUSE_DATA.FirstByte]
mov ah, al
shr al, 3
and al, 2
shr ah, 5
and ah, 1
add al, ah
movzx eax, al
mov [BTN_DOWN], eax
 
; Ïðèáàâèòü ïåðåìåùåíèå ïî X ê êîîðäèíàòå X
mov al, [esi+COM_MOUSE_DATA.FirstByte]
shl al, 6
or al, [esi+COM_MOUSE_DATA.SecondByte]
 
cbw
movzx eax, ax
mov [MOUSE_X], eax
 
; Ïðèáàâèòü ïåðåìåùåíèå ïî Y ê êîîðäèíàòå Y
mov al, [esi+COM_MOUSE_DATA.FirstByte]
and al, 00001100b
shl al, 4
or al, [esi+COM_MOUSE_DATA.ThirdByte]
 
cbw
movzx eax, ax
neg eax
mov [MOUSE_Y], eax
 
stdcall SetMouseData, [BTN_DOWN], [MOUSE_X], [MOUSE_Y], 0, 0
 
jmp .EndMouseInterrupt
 
.Error:
; Ïðîèçîøåë ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò
; ìûøè, îáíóëèòü ñ÷åò÷èê áàéòîâ ïàêåòà äàííûõ
 
mov [esi+COM_MOUSE_DATA.MouseByteNumber],0
.EndMouseInterrupt:
 
ret
 
;all initialized data place here
 
align 4
 
struc COM_MOUSE_DATA {
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà
.MouseByteNumber db ?
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ
.FirstByte db ?
.SecondByte db ?
.ThirdByte db ?
;.timer_ticks_com dd ?
}
virtual at 0
COM_MOUSE_DATA COM_MOUSE_DATA
end virtual
 
com1_mouse COM_MOUSE_DATA
com2_mouse COM_MOUSE_DATA
 
MOUSE_X dd 0
MOUSE_Y dd 0
BTN_DOWN dd 0
 
COMPortBaseAddr dw 3F8h
 
 
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
my_service db 'COM_Mouse',0 ;max 16 chars include zero
 
if DEBUG
msgInit db 'Preved bugoga!',13,10,0
boot_setmouse_type db 'Detected - COM1 mouse',13,10,0
db 'Detected - COM2 mouse',13,10,0
msg_error_reserve_ports db 'Error reserving ports!',13,10,0
msg_error_attach_int_handler db 'Error attach interrupt handler!',13,10,0
msg_exit db 'Exit!',13,10,0
end if
 
section '.data' data readable writable align 16
 
;all uninitialized data place here
 
/kernel/branches/Kolibri-acpi/drivers/sb16/sb16.asm
0,0 → 1,393
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
format MS COFF
 
include 'config.inc'
 
;structs----------------------------------------------------------
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
;something--------------------------------------------------------
public START
public service_proc
public version
 
include '..\proc32.inc'
include '..\imports.inc'
 
section '.flat' code readable align 16
 
include 'sb16.inc'
 
;-------------------------------------------------------------------------------
proc START stdcall, state:dword
cmp [state], 1
jne .stop
.entry:
 
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
call detect ;returns DSP version or zero if
test eax,eax ;SB card not found
jz .exit
 
if DEBUG
movzx eax,al ;major version
mov esi,sb_DSP_description
dec eax
jz .sb_say_about_found_dsp
mov dword[esi],'2.x '
dec eax
jz .sb_say_about_found_dsp
mov dword[esi],'Pro '
dec eax
jz .sb_say_about_found_dsp
mov dword[esi],'16 '
.sb_say_about_found_dsp:
mov esi,msgDSPFound
call SysMsgBoardStr
end if
; xor eax,eax
; mov ebx,[sb_base_port]
; lea ecx,[ebx+0xF]
xor ebx,ebx
mov ecx,[sb_base_port]
lea edx,[ebx+0xF]
 
call ReservePortArea ;these ports must be my!
if DEBUG
dec eax
jnz @f
mov esi,msgErrRsrvPorts
call SysMsgBoardStr
@@:
end if
 
call sb_setup ;clock it, etc
 
stdcall AttachIntHandler, sb_irq_num, sb_irq, 0
 
if DEBUG
test eax,eax
jnz @f
 
mov esi,msgErrAtchIRQ
call SysMsgBoardStr
 
stdcall GetIntHandler, sb_irq_num
call SysMsgBoardNum
 
jmp .stop
@@:
mov esi,msgSucAtchIRQ
call SysMsgBoardStr
end if
stdcall RegService, my_service, service_proc
ret
.stop:
call sb_reset
.exit:
 
if DEBUG
mov esi,msgExit
call SysMsgBoardStr
end if
 
xor eax, eax
ret
endp
;-------------------------------------------------------------------------------
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
mov edi,[ioctl]
mov eax,[edi+io_code]
cmp eax,SRV_GETVERSION
jne @F
 
mov eax,[edi+output]
cmp [edi+out_size],4
jne .fail
mov [eax],dword API_VERSION
xor eax,eax
ret
@@:
cmp eax,DEV_PLAY
jne @f
if DEBUG
mov esi,msgPlay
call SysMsgBoardStr
end if
call sb_stop ;to play smth new we must stop smth old
 
call pre_fill_data ;fill first and second half of the buffer
call pre_fill_data ;
 
call sb_set_dma ;is it really needed here? Paranoia.
call sb_play
xor eax,eax ;set maximum volume
call sb_set_master_vol
xor eax,eax
ret
;@@: ;all this commented stuff in service proc
; cmp eax,DEV_STOP ;is never used. Mixer do this virtually,
; jne @f ;e.g. instead of stopping driver it
;if DEBUG ;outputs silence
; mov esi,msgStop
; call SysMsgBoardStr
;end if
; call sb_stop
; xor eax,eax
; ret
@@:
cmp eax,DEV_CALLBACK
jne @f
if DEBUG
mov esi,msgCallback
call SysMsgBoardStr
end if
mov edi,[edi+input]
mov eax,[edi]
mov [callback],eax
if DEBUG
call SysMsgBoardNum
end if
xor eax,eax
ret
@@:
cmp eax,DEV_SET_MASTERVOL ;Serge asked me to unlock
jne @F ;DEV_SET(GET)_MASTERVOL, although mixer doesn't use it.
;It doesn't use it _in current version_ - but in the future...
 
if DEBUG
mov esi,msgSetVol
call SysMsgBoardStr
end if
mov eax,[edi+input]
mov eax,[eax]
call sb_set_master_vol
xor eax,eax
ret
@@:
cmp eax,DEV_GET_MASTERVOL
jne @F
if DEBUG
mov esi,msgGetVol
call SysMsgBoardStr
end if
mov eax,[edi+output]
mov edx,[sb_master_vol]
mov [eax],edx
xor eax,eax
ret
 
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
;-------------------------------------------------------------------------------
align 4
proc sb_irq
mov edx,[sb_base_port] ;tell the DSP that we have processed IRQ
add dl,0xF ;0xF for 16 bit sound, 0xE for 8 bit sound
in al,dx ;for non-stop sound
 
pre_fill_data:
mov eax,int_flip_flop
not dword[eax]
mov eax,[eax]
test eax,eax
jns .fill_second_half
 
if sb_buffer_size eq small_buffer
stdcall [callback],SB16Buffer0 ;for 32k buffer
else if sb_buffer_size eq full_buffer
stdcall [callback],SB16Buffer0 ;for 64k buffer
stdcall [callback],SB16Buffer1 ;for 64k buffer
end if
xor eax,eax
ret
 
.fill_second_half:
if sb_buffer_size eq small_buffer
stdcall [callback],SB16Buffer1 ;for 32k buffer
else if sb_buffer_size eq full_buffer
stdcall [callback],SB16Buffer2 ;for 64k buffer
stdcall [callback],SB16Buffer3 ;for 64k buffer
end if
xor eax,eax
ret
endp
;-------------------------------------------------------------------------------
align 4
proc detect
.sb_detect_next_port:
if DEBUG
inc dword[port_second_digit_num]
end if
mov edx,sb_base_port
add byte[edx],10h
cmp byte[edx],80h
jbe .sb_try_to_detect_at_specified_port
;error - no SB card detected
.sb_not_found_err:
xor eax, eax
ret
 
.sb_try_to_detect_at_specified_port:
call sb_reset
add dl,8
mov ecx,100
.sb_check_port:
in al,dx
test al,al ;is DSP port ready to be read?
jns .sb_port_not_ready
 
sub dl,4
in al,dx ;check for AAh response
add dl,4
cmp al,0xAA
jne .sb_port_not_ready
.sb_card_found:
and dl,0xF0
add dl,0xC
sb_out 0xE1 ;get DSP version
add dl,2
@@:
in al,dx
test al,al ;is DSP port ready to be read?
jns @b
sub dl,4
in al,dx ;get major version
ror eax,16
add dl,4
@@:
in al,dx
test al,al ;is DSP port ready to be read?
jns @b
sub dl,4
in al,dx ;get minor version
xor edx,edx
mov dl,10
div dl
ror eax,16
xor ah,ah
mov [sb_DSP_version_int],eax ;for internal usage
if DEBUG
add [sb_DSP_version],eax
end if
ret
 
.sb_port_not_ready:
loop .sb_check_port ;100 retries (~100 microsec.)
jmp .sb_detect_next_port
endp
;-------------------------------------------------------------------------------
if DEBUG
proc SysMsgBoardNum ;warning: destroys eax,ebx,ecx,esi
mov ebx,eax
mov ecx,8
mov esi,(number_to_out+1)
.1:
mov eax,ebx
and eax,0xF
add al,'0'
cmp al,(10+'0')
jb @f
add al,('A'-'0'-10)
@@:
mov [esi+ecx],al
shr ebx,4
loop .1
dec esi
call SysMsgBoardStr
ret
endp
end if
;all initialized data place here
align 4
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
sb_base_port: dd 200h ;don't ask me why - see the code&docs
 
sound_dma dd sb_dma_num
 
;note that 4th DMA channel doesn't exist, it is used for cascade
;plugging the first DMA controler to the second
dma_table db 0x87,0x83,0x81,0x82,0xFF,0x8B,0x89,0x8A
 
my_service db 'SOUND',0 ;max 16 chars include zero
 
if DEBUG
number_to_out db '0x00000000',13,10,0
 
msgInit db 'detecting hardware...',13,10,0
msgExit db 'exiting... May be some problems found?',13,10,0
msgPlay db 'start play',13,10,0
;msgStop db 'stop play',13,10,0
msgCallback db 'set_callback received from the mixer!',13,10
db 'callback handler is: ',0
msgErrAtchIRQ db 'failed to attach IRQ',(sb_irq_num+'0'),13,10
db 'owner',39,'s handler: ',0
msgSucAtchIRQ db 'succesfully attached IRQ',(sb_irq_num+'0')
db ' as hardcoded',13,10,0
msgErrRsrvPorts db 'failed to reserve needed ports.',13,10
db 'Driver may work unstable',13,10,0
msgSetVol db 'DEV_SET_MASTERVOL call came',13,10,0
msgGetVol db 'DEV_GET_MASTERVOL call came',13,10,0
msgErrDMAsetup db 'failed to setup DMA - bad channel',13,10,0
;-------------------------------------------------------------------------------
msgDSPFound db 'DSP found at port 2'
label port_second_digit_num dword at $
db '00h',13,10,'DSP version '
sb_DSP_version: db '0.00 - SB'
sb_DSP_description: db 32,32,32,32,13,10,0
;-------------------------------------------------------------------------------
end if
 
section '.data' data readable writable align 16
;all uninitialized data place here
 
;pTempBuf rd 1
 
callback rd 1
 
int_flip_flop rd 1
 
sb_master_vol rd 1
 
sb_DSP_version_int rd 1
/kernel/branches/Kolibri-acpi/drivers/sb16/CONFIG.INC
0,0 → 1,50
;flags------------------------------------------------------------
DEBUG equ 1 ;show messages at debug board
use_cli_sti equ 1 ;driver become more stable (theoretically)
 
;constants--------------------------------------------------------
API_VERSION equ 0 ;debug
 
OS_BASE equ 0x80000000
new_app_base equ 0x0
PROC_BASE equ (OS_BASE+0x080000)
SB16Buffer equ (OS_BASE+0x2A0000)
SB16_Status equ (OS_BASE+0x2B0000)
DMAPage equ ((SB16Buffer-OS_BASE) shr 16)
 
SB16Buffer0 equ SB16Buffer
SB16Buffer1 equ (SB16Buffer+16384)
SB16Buffer2 equ (SB16Buffer+(2*16384))
SB16Buffer3 equ (SB16Buffer+(3*16384))
 
sb_irq_num equ 5 ;default values for SB16, may be overrided by autodetect
sb_dma_num equ 5 ;default values for SB16, may be overrided by autodetect
 
small_buffer equ 32768
full_buffer equ 65536
sb_buffer_size equ small_buffer ; FIX ring buffer overlapped events issue; full_buffer
 
__supported_buffer_sizes fix <small_buffer, full_buffer>
 
if ~(sb_buffer_size in __supported_buffer_sizes)
display 13,10,'unsupported buffer size was selected, check config.inc',13,10
stop
end if
 
sb_out_rate equ 48000
;time constant for cards older than SB16
sb_tc equ (256-(1000000/(sb_out_rate*2)))
 
SRV_GETVERSION equ 0
DEV_PLAY equ 1
DEV_STOP equ 2
DEV_CALLBACK equ 3
DEV_SET_BUFF equ 4
DEV_NOTIFY equ 5
DEV_SET_MASTERVOL equ 6
DEV_GET_MASTERVOL equ 7
DEV_GET_INFO equ 8
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
 
/kernel/branches/Kolibri-acpi/drivers/sb16/README.TXT
0,0 → 1,72
Nable 21.05.2008.
This driver is my contribution (or donation) to KolibriOS. This is provided
AS IS in hope it'll be useful, but WITHOUT ANY WARRANTY! No responcibility
for any hardware damage or data loss. Use at your own risk!
 
;-------------------------------------------------------------------------------
;Changelog:
;-------------------------------------------------------------------------------
v0.2 - DEV_SET(GET)_MASTERVOL functions are unlocked and implemented.
 
v0.1 - first release.
 
;-------------------------------------------------------------------------------
;Tiny FAQ for sound driver by Nable for SB16 sound card.
;-------------------------------------------------------------------------------
 
;What is it?--------------------------------------------------------------------
As you may know there is a sound subsystem ('INFINITY') in KolibriOS.
This subsystem includes mixer and separate interface for soundplayer
program and driver, so player application don't need to know what soundcard
is installed and how to cope with it, all work with card do the driver.
Before this time there were drivers only for AC97 integrated sound, but I
don't have such at home and if I would upgrade my computer with a newest
hardware, with 100% probability integrated sound will be HD Codec, nowadays
AC97 is not actual (2008 year is at calendar). But I'm not planning to upgrade
my computer so much now (and in next 5-6 years), writing the driver for my PCI
ESS Maestro1 card is difficult for me (may be some time later), so I decided
to write a driver for SB16. At first it is easy, there are many working
examples for DOS, there are heaps of good documentation and as an ISA device
SB16 can be programmed through I/O ports (about 5 ports are used), that is
more easy than PCI access. Now, enough lirics, lets go to physics :-)
If you still don't understand what stuff is it, I'll tell this in brief:
with this driver you can play MP3 and WAV music (using AC97SND player) and
sounds (some games and DOSBOX can produce sound output through sound
subsystem) in KolibriOS.
 
;Yeah! I need sound in Kolibri and I have SB16 card. Whats then?----------------
At first copy my SOUND.OBJ to /sys/drivers at your Kolibri system. Note,
that if you have AC97 card and it's driver started - then new driver won't
run until reboot. Then run BOARD and go to 'user' tab. Then try to run
AC97SND player. At BOARD you will see the following (if you had a proper
card):
|----------------------------|
|detecting hardware... | <- detector startup message
|DSP found at port 220h | <- if you have a proper card, it'll be
|DSP version 4.13 - SB16 | autodetected. Numbers may be different.
|failed to attach IRQ5 | <- don't mention. Old kernels reserve IRQ5
|owner's handler: 0x80D74284 | see below how to fix it.
|----------------------------|
At first, note that DSP version must be 4.xx or higher. Older cards are not
supported in this first release, maybe some time later. If nothing detected
but PNP/BIOS or some other OS detects your card - I'm sorry, it's perverted
PNP card like OPTi16, that is like HD Codec - until you init it through
PCI->ISA bridge (HD Codec of course through PCI->PCI bridge), map it, etc,
you can't use it in any way. I'd rather write a PCI device driver, than
for this extreme perversion. If your card detected and has a proper version
but you see 'failed to attach IRQ' - delete stroke 'mov [irq_owner+4*5],1' from the
file kernel.asm of your kernel source, save it, rebuild kernel, copy new
kernel to /sys/ (did you rename 'kernel' to 'kernel.mnt'? You should do it),
restart kernel (Ctrl+Alt+F12, Home). THE EASIER WAY IS TO USE A NEWER KERNEL,
since SVN802 it's fixed.
Now everything should be OK.
 
;It works for a part of the second and then stops, but system doesn't hang------
Go to 'config.inc' of my driver and change 'sb_irq_num' value from 5 to 7.
Then save, rebuild driver (compile 'sound.asm'), put 'sound' to /sys/drivers/
(you need to rename file 'sound' to 'sound.obj'), restart kernel and try again
to produce sound.
 
;-------------------------------------------------------------------------------
Ask your questions at KolibriOS forum: board.kolibrios.org
I'll try to answer you if possible.
/kernel/branches/Kolibri-acpi/drivers/sb16/SB16.INC
0,0 → 1,297
;--------------------------------
; program dma
;--------------------------------
sb_set_dma:
mov ebx,[sound_dma]
lea eax,[ebx+4] ;mask required channel
cmp bl,4
ja .use_second_dma_controller
jb @f
.dma_setup_error:
if DEBUG
mov esi,msgErrDMAsetup
call SysMsgBoardStr
end if
mov dword[esp],START.stop
ret
@@:
if use_cli_sti
cli ;here to minimize time with disabled ints
end if
out 0xA,al ;mask required channel
 
xor eax,eax
out 0xC,al ;clear byte pointer flip-flop register
 
lea eax,[ebx+0x58] ;auto-init mode for channel (ebx)
out 0xB,al ;DMA channel 0-3 mode register
 
movzx edx,byte[ebx+dma_table] ;page register
mov al,DMAPage
out dx,al
 
lea edx,[ebx*2] ;DMA channel 0-3 base address
 
mov al,0 ;LSB is 0
out dx,al
 
; mov al,0 ;MSB is 0 too
out dx,al
 
inc edx ;DMA channel 0-3 byte count
 
mov al,((sb_buffer_size-1) and 0xff)
out dx,al
 
mov al,((sb_buffer_size-1) shr 8) ;it is the same
out dx,al
 
mov eax,ebx ;unmask DMA channel
out 0xA,al
 
if use_cli_sti
sti
end if
ret
 
.use_second_dma_controller:
cmp bl,7
ja .dma_setup_error
 
sub bl,4
sub al,4
if use_cli_sti
cli ;here to minimize time with disabled ints
end if
out 0xD4,al ;mask required channel
 
xor eax,eax
out 0xD8,al ;clear byte pointer flip-flop register
 
lea eax,[ebx+0x58] ;auto-init mode for channel (ebx+4)
out 0xD6,al ;DMA channel 4-7 mode register
 
movzx edx,byte[ebx+dma_table+4] ;page register
mov al,DMAPage
out dx,al
 
lea edx,[ebx*4+0xC0] ;DMA channel 4-7 base address
 
mov al,0 ;LSB is 0 ;for 16bit DMA this contains
out dx,al ;A1-A8 lines of address bus, A0 is zero
 
; mov al,0 ;MSB is 0 too ;for 16bit DMA this contains
out dx,al ;A9-A16 lines of address bus
 
inc edx
inc edx ;DMA channel 4-7 16bit word count
 
mov al,(((sb_buffer_size/2)-1) and 0xff)
out dx,al
 
mov al,(((sb_buffer_size/2)-1) shr 8)
out dx,al
 
mov eax,ebx ;unmask DMA channel
out 0xD4,al
 
if use_cli_sti
sti
end if
ret
;-------------------------------------------------------------------------------
; out byte to SB DSP's write port
;-------------------------------------------------------------------------------
macro sb_out data_to_out {
@@:
in al,dx
test al,al ;is DSP busy?
js @b ;it's busy
mov al,data_to_out ;it's free
out dx,al
}
;-------------------------------------------------------------------------------
; stop playing
;-------------------------------------------------------------------------------
proc sb_stop
mov edx,[sb_base_port]
add dl,0xC
sb_out 0xD3 ;turn the speaker off
sb_out 0xDA ;exit 8bit DMA
sb_out 0xD9 ;exit 16bit DMA
ret
endp
;-------------------------------------------------------------------------------
; start playing
;-------------------------------------------------------------------------------
proc sb_play
and [int_flip_flop],0
mov edx,[sb_base_port]
add dl,0xC
sb_out 0xD1 ;turn speaker on
; sb_out 0x48 ;set DSP transfer size ;for older cards, not supported
; ;in this version
; mov ax,32767 ;(64k)/2-1
;@@: ;out the low byte...
; in al,dx
; test al,al ;is DSP busy?
; js @b ;it's busy
; out dx,al
 
; mov al,ah ;...then the high byte
;@@:
; in al,dx
; test al,al ;is DSP busy?
; js @b ;it's busy
; out dx,al
 
; sb_out 0x1C ;auto-init 8bit playback
 
; 0xBXh - 16 bit DMA mode
; ||||
sb_out 10110110b ;bCommand
; ||||
; |||+-reserved
; ||+--turn FIFO on (0 for off)
; |+---auto-init mode on (0 for off)
; +----A/D: 0-output, 1-input
; +------stereo on
; |+-----unsigned (1 for signed)
; ||
sb_out 00110000b ;bMode
; || ||||
; ---------reserved
;wSize is a number of 16bit samples less 1. For auto-init mode each half
;buffer is (64k)/2 bytes long and, obviously, contains ((64k)/2)/2 samples
sb_out (((sb_buffer_size/2/2)-1) and 0xFF) ;wSize.LowByte
sb_out (((sb_buffer_size/2/2)-1) shr 8) ;wSize.HighByte
ret
endp
;-------------------------------------------------------------------------------
; reset DSP
;-------------------------------------------------------------------------------
proc sb_reset
and [int_flip_flop],0
mov edx,[sb_base_port]
add dl,6
mov al,1 ;start DSP reset
 
if use_cli_sti
cli ;here to minimize time with disabled ints
end if
out dx,al
mov ecx,40 ;wait at least 3 microsec.
@@:
in al,dx
loop @b
 
xor eax,eax ;stop DSP reset
if use_cli_sti
sti
end if
out dx,al
ret
endp
 
;-------------------------------------------------------------------------------
; set the rate for playing, enable stereo
;-------------------------------------------------------------------------------
proc sb_setup
mov edx,[sb_base_port]
add dl,0xC
sb_out 40h ;set time constant, this is for old cards
sb_out sb_tc
 
sb_out 41h ;set sound rate, this can only SB16
sb_out (sb_out_rate shr 8) ;first high byte (MSB)
sb_out (sb_out_rate and 0xff) ;then low byte (LSB)
 
; mov al,0xE ;for older cards, not supported in this version
; sub dl,(0xC-4) ;talk to SB's mixer
; out dx,al ;select this register of the mixer
; mov ecx,6 ;wait for the chip
;@@:
; in al,dx
; loop @b
 
; inc edx ;now read the data port
; in al,dx
; or al,22h ;turn on stereo
; mov ah,al
 
; mov al,0xE
; dec edx ;talk to SB's mixer
; out dx,al ;select this register of the mixer
 
; mov ecx,6 ;wait for the chip
;@@:
; in al,dx
; loop @b
 
; inc edx ;now send data to the data port
; mov al,ah
; out dx,al
 
; dec edx
; mov ecx,35 ;wait for the chip
;@@:
; in al,dx
; loop @b
ret
endp
 
;-------------------------------------------------------------------------------
; set master volume of SB mixer, note, not only SB16 but SBPro and older
; this is the first step to more full support for hardware
;-------------------------------------------------------------------------------
;in: eax in range [-10000;0] - master volume for _both_ channels
;note that x*3*17/2000 and x*3/2000*17 are not the same numbers,
;because we count in integers
proc sb_set_master_vol
mov [sb_master_vol],eax
add eax,10000 ;SB sound level rise from 0 to MAX_LEVEL
lea eax,[eax+eax*2] ;*3
mov ebx,2000 ;divisor
xor edx,edx
cmp byte[sb_DSP_version_int],4
jae @f ;SBPro's MAX_LEVEL is 15, but we *11 because
;volume byte looks like that: 0xLR, where L - left
;channel volume, R - right, 0<=R,L<=15
div ebx
imul eax,17
mov edx,[sb_base_port]
push eax ;here for optimisation
add dl,4
mov al,0x22 ;write mixer register 0x22
out dx,al
in al,dx ;wait for the chip ;6
in al,dx ;wait for the chip ;5
in al,dx ;wait for the chip ;4
in al,dx ;wait for the chip ;3
in al,dx ;wait for the chip ;2
in al,dx ;wait for the chip ;1
pop eax ;go!
inc edx
out dx,al
ret
@@: ;SB16's MAX_LEVEL is 255
imul eax,17
div ebx
mov edx,[sb_base_port]
push eax ;here for optimisation
add dl,4
mov al,0x30 ;left speaker
out dx,al
pop eax ;<--+
inc edx ; \/
push eax ;here for optimisation
out dx,al ;write
dec edx
mov al,0x31 ;right speaker
out dx,al
pop eax
inc edx
out dx,al ;write
ret
endp
;-------------------------------------------------------------------------------
/kernel/branches/Kolibri-acpi/drivers/infinity.asm
0,0 → 1,1306
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; Serge 2006-2008
; email: infinity_sound@mail.ru
 
format MS COFF
 
DEBUG equ 1
 
 
include 'proc32.inc'
include 'main.inc'
include 'imports.inc'
 
 
CURRENT_API equ 0x0101 ;1.01
COMPATIBLE_API equ 0x0100 ;1.00
 
API_VERSION equ (COMPATIBLE_API shl 16) or CURRENT_API
SOUND_VERSION equ CURRENT_API
 
 
FORCE_MMX equ 0 ;set to 1 to force use mmx or
FORCE_MMX_128 equ 0 ;integer sse2 extensions
;and reduce driver size
 
;USE_SSE equ 0
 
USE_SSE2_MIXER equ 0 ;floating point mixer. Disabled by default
 
OS_BASE equ 0x80000000
 
CAPS_SSE2 equ 26
PG_SW equ 0x003
 
public START
public service_proc
public version
 
RT_INP_EMPTY equ 0xFF000001
RT_OUT_EMPTY equ 0xFF000002
RT_INP_FULL equ 0xFF000003
RT_OUT_FULL equ 0xFF000004
 
EVENT_WATCHED equ 0x10000000
EVENT_SIGNALED equ 0x20000000
MANUAL_RESET equ 0x40000000
MANUAL_DESTROY equ 0x80000000
 
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' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .exit
 
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 eax, str.fd-FD_OFFSET
mov [str.fd], eax
mov [str.bk], eax
 
if FORCE_MMX
if FORCE_MMX_128
display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10
stop
end if
mov [mix_2_core], mmx_mix_2
mov [mix_3_core], mmx_mix_3
mov [mix_4_core], mmx_mix_4
end if
 
if FORCE_MMX_128
if FORCE_MMX
display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10
stop
end if
mov [mix_2_core], mmx128_mix_2
mov [mix_3_core], mmx128_mix_3
mov [mix_4_core], mmx128_mix_4
end if
 
if 0
 
if ~(FORCE_MMX or FORCE_MMX_128) ;autodetect
mov eax, 1
cpuid
bt edx, CAPS_SSE2
jc .mmx128
;old 64-bit mmx
mov [mix_2_core], mmx_mix_2
mov [mix_3_core], mmx_mix_3
mov [mix_4_core], mmx_mix_4
jmp @F
.mmx128: ;128-bit integer sse2 extensions
mov [mix_2_core], mmx128_mix_2
mov [mix_3_core], mmx128_mix_3
mov [mix_4_core], mmx128_mix_4
@@:
end if
 
end if
stdcall set_handler, [hSound], new_mix
mov [eng_state], SND_STOP
stdcall RegService, szInfinity, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
.exit:
xor eax, eax
ret
 
.out_of_mem:
if DEBUG
mov esi, msgMem
call SysMsgBoardStr
end if
xor eax, eax
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edi, [ioctl]
mov eax, [edi+io_code]
 
cmp eax, SRV_GETVERSION
jne @F
mov eax, [edi+output]
cmp [edi+out_size], 4
jne .fail
mov eax, [eax]
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
cmp eax, SND_CREATE_BUFF
jne @F
mov ebx, [edi+input]
stdcall CreateBuffer,[ebx],[ebx+4]
mov edi, [ioctl]
mov ecx, [edi+output]
mov ecx, [ecx]
mov [ecx], ebx
ret
@@:
mov ebx, [edi+input]
mov edx, [ebx]
 
cmp [edx+STREAM.magic], 'WAVE'
jne .fail
 
cmp [edx+STREAM.size], STREAM_SIZE
jne .fail
 
cmp eax, SND_DESTROY_BUFF
jne @F
mov eax, edx
call DestroyBuffer ;edx= stream
ret
@@:
cmp eax, SND_SETFORMAT
jne @F
stdcall SetFormat,edx,[ebx+4]
ret
@@:
cmp eax, SND_GETFORMAT
jne @F
 
movzx eax, word [edx+STREAM.format]
mov ecx, [edi+output]
mov ecx, [ecx]
mov [ecx], eax
xor eax, eax
ret
@@:
cmp eax, SND_RESET
jne @F
stdcall ResetBuffer,edx,[ebx+4]
ret
@@:
cmp eax, SND_SETPOS
jne @F
stdcall SetBufferPos,edx,[ebx+4]
ret
@@:
cmp eax, SND_GETPOS
jne @F
stdcall GetBufferPos, edx
mov edi, [ioctl]
mov ecx, [edi+output]
mov ecx, [ecx]
mov [ecx], ebx
ret
@@:
cmp eax, SND_SETBUFF
jne @F
mov eax, [ebx+4]
stdcall set_buffer, edx,eax,[ebx+8],[ebx+12]
ret
@@:
cmp eax, SND_SETVOLUME
jne @F
stdcall SetBufferVol,edx,[ebx+4],[ebx+8]
ret
@@:
cmp eax, SND_GETVOLUME
jne @F
 
mov eax, [edi+output]
mov ecx, [eax]
mov eax, [eax+4]
stdcall GetBufferVol,edx,ecx,eax
ret
@@:
cmp eax, SND_SETPAN
jne @F
stdcall SetBufferPan,edx,[ebx+4]
ret
@@:
cmp eax, SND_GETPAN
jne @F
mov eax, [edx+STREAM.pan]
mov ebx, [edi+output]
mov ebx, [ebx]
mov [ebx], eax
xor eax, eax
ret
@@:
cmp eax, SND_OUT
jne @F
 
mov eax, [ebx+4]
stdcall wave_out, edx,eax,[ebx+8]
ret
@@:
cmp eax, SND_PLAY
jne @F
 
stdcall play_buffer, edx,[ebx+4]
ret
@@:
cmp eax, SND_STOP
jne @F
 
stdcall stop_buffer, edx
ret
@@:
cmp eax, SND_GETBUFFSIZE
jne @F
mov eax, [edx+STREAM.in_size]
mov ecx, [edi+output]
mov ecx, [ecx]
mov [ecx], eax
xor eax, eax
ret
@@:
cmp eax, SND_GETFREESPACE
jne @F
 
test [edx+STREAM.format], PCM_OUT
jz .fail
 
mov ebx, [edx+STREAM.in_free]
mov ecx, [edi+output]
mov [ecx], ebx
xor eax, eax
ret
@@:
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
align 4
proc CreateBuffer stdcall, format:dword, size:dword
locals
str dd ?
ring_size dd ?
ring_pages dd ?
endl
 
mov eax, [format]
cmp ax, PCM_1_8_8
ja .fail
 
test eax, PCM_OUT
jnz .test_out
test eax, PCM_RING
jnz .test_ring
;staic
test eax, PCM_STATIC
jz .test_out ;use PCM_OUT as default format
jmp .test_ok
.test_out:
test eax, PCM_RING+PCM_STATIC
jnz .fail
or [format], PCM_OUT ;force set
jmp .test_ok
.test_ring:
test eax, PCM_OUT+PCM_STATIC
jnz .fail
.test_ok:
 
call GetPid
mov ebx, eax
mov eax, STREAM_SIZE
 
call CreateObject
test eax, eax
jz .fail
mov [str], eax
 
mov ebx, [format]
mov [eax+STREAM.format], ebx
 
xor ecx, ecx
movzx ebx, bx
cmp ebx, 19
jb @f
mov ecx, 0x80808080
@@:
mov [eax+STREAM.r_silence], ecx
 
shl ebx, 2
lea ebx, [ebx+ebx*2] ;ebx*=12
 
mov ecx, [resampler_params+ebx]
mov edx, [resampler_params+ebx+4]
mov esi, [resampler_params+ebx+8]
 
mov [eax+STREAM.r_size],ecx
mov [eax+STREAM.r_dt], edx
mov [eax+STREAM.resample], esi
xor ecx, ecx
mov [eax+STREAM.l_vol], ecx
mov [eax+STREAM.r_vol], ecx
mov dword [eax+STREAM.l_amp], 0x7FFF7FFF
mov [eax+STREAM.pan], ecx
 
test [format], PCM_STATIC
jnz .static
 
; ring and waveout
 
mov ebx, 0x10000
test [format], PCM_RING
jz .waveout
 
mov ebx, [eax+STREAM.r_size]
add ebx, 4095
and ebx, -4096
add ebx, ebx
.waveout:
mov [ring_size], ebx
mov eax, ebx
shr ebx, 12
mov [ring_pages], ebx
 
stdcall CreateRingBuffer, eax, PG_SW
 
mov edi, [str]
mov ecx, [ring_size]
mov [edi+STREAM.in_base], eax
mov [edi+STREAM.in_size], ecx
add eax, 128
; sub ecx, 128
mov [edi+STREAM.in_wp], eax
mov [edi+STREAM.in_rp], eax
mov [edi+STREAM.in_count], 0
 
mov [edi+STREAM.in_free], ecx
add eax, ecx
mov [edi+STREAM.in_top], eax
 
jmp .out_buff
.static:
mov ecx, [size]
add ecx, 128 ;resampler required
mov [eax+STREAM.in_size], ecx
stdcall KernelAlloc, ecx
 
mov edi, [str]
mov [edi+STREAM.in_base], eax
add eax, 128
mov [edi+STREAM.in_wp], eax
mov [edi+STREAM.in_rp], eax
mov ebx, [size]
mov [edi+STREAM.in_count], ebx
mov [edi+STREAM.in_free], ebx
add eax, ebx
mov [edi+STREAM.in_top], eax
 
.out_buff:
stdcall AllocKernelSpace, dword 128*1024
 
mov edi, [str]
mov [edi+STREAM.out_base], eax
mov [edi+STREAM.out_wp], eax
mov [edi+STREAM.out_rp], eax
mov [edi+STREAM.out_count], 0
add eax, 64*1024
mov [edi+STREAM.out_top], eax
 
stdcall AllocPages, dword 64/4
mov edi, [str]
mov ebx, [edi+STREAM.out_base]
mov ecx, 16
or eax, PG_SW
push eax
push ebx
call CommitPages ;eax, ebx, ecx
mov ecx, 16
pop ebx
pop eax
add ebx, 64*1024
call CommitPages ;double mapped
 
mov edi, [str]
mov ecx, [edi+STREAM.in_top]
mov edi, [edi+STREAM.in_base]
sub ecx, edi
xor eax, eax
shr ecx, 2
cld
rep stosd
 
mov edi, [str]
mov edi, [edi+STREAM.out_base]
mov ecx, (64*1024)/4
rep stosd
 
xor esi, esi
mov ecx, MANUAL_DESTROY
call CreateEvent
 
mov ebx, [str]
mov [ebx+STREAM.notify_event], eax
mov [ebx+STREAM.notify_id], edx
 
mov [ebx+STREAM.magic], 'WAVE'
mov [ebx+STREAM.destroy], DestroyBuffer.destroy
mov [ebx+STREAM.size], STREAM_SIZE
mov [ebx+STREAM.flags], SND_STOP
 
pushf
cli
mov eax, str.fd-FD_OFFSET
mov edx, [eax+STREAM.str_fd]
mov [ebx+STREAM.str_fd], edx
mov [ebx+STREAM.str_bk], eax
mov [eax+STREAM.str_fd], ebx
mov [edx+STREAM.str_bk], ebx
popf
 
xor eax, eax
ret
.fail:
xor ebx, ebx
or eax, -1
ret
endp
 
;param
; eax= buffer handle
 
align 4
DestroyBuffer:
.handle equ esp ;local
 
mov [eax+STREAM.flags], SND_STOP
.destroy:
push eax
 
pushfd
cli
mov ebx, [eax+STREAM.str_fd]
mov ecx, [eax+STREAM.str_bk]
mov [ebx+STREAM.str_bk], ecx
mov [ecx+STREAM.str_fd], ebx
popf
 
stdcall KernelFree, [eax+STREAM.in_base]
mov eax, [.handle]
stdcall KernelFree, [eax+STREAM.out_base]
 
pop eax ;restore stack
call DestroyObject ;eax= stream
xor eax, eax
ret
.fail:
or eax, -1
ret
restore .handle
 
align 4
proc SetFormat stdcall, str:dword, format:dword
 
cmp word [format], PCM_1_8_8
ja .fail
 
mov edx, [str]
mov [edx+STREAM.flags], SND_STOP
 
test [edx+STREAM.format], PCM_RING
jnz .fail
 
; mov eax,[edx+STREAM.out_base]
; mov [edx+STREAM.out_wp], eax
; mov [edx+STREAM.out_rp], eax
; mov [edx+STREAM.out_count], 0
 
movzx eax, word [format]
mov word [edx+STREAM.format], ax
 
xor ebx, ebx
cmp eax, 19
jb @f
mov ebx, 0x80808080
@@:
mov [edx+STREAM.r_silence], ebx
 
shl eax, 2
lea eax, [eax+eax*2] ;eax*=12
 
mov edi, [resampler_params+eax]
mov ecx, [resampler_params+eax+4]
mov ebx, [resampler_params+eax+8]
 
mov [edx+STREAM.r_size],edi
mov [edx+STREAM.r_dt], ecx
mov [edx+STREAM.resample], ebx
 
mov edi, [edx+STREAM.in_base]
mov ecx, 128/4
mov eax, [edx+STREAM.r_silence]
cld
rep stosd
xor eax, eax
ret
.fail:
or eax, -1
ret
endp
 
; for static buffers only
; use waveout for streams
 
align 4
proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword
 
mov edx, [str]
test [edx+STREAM.format], PCM_OUT
jnz .fail
 
mov esi, [src]
mov edi, [offs]
add edi, [edx+STREAM.in_base]
add edi, 128
 
cmp edi, [edx+STREAM.in_top]
jae .fail
 
mov ecx, [size]
lea ebx, [ecx+edi]
sub ebx, [edx+STREAM.in_top]
jb @F
sub ecx, ebx
@@:
shr ecx, 2
cld
rep movsd
xor eax,eax
ret
.fail:
or eax, -1
ret
endp
 
; for stream buffers only
 
align 4
proc wave_out stdcall, str:dword,src:dword,size:dword
locals
state_saved dd ?
fpu_state rb 528
endl
 
mov edx, [str]
mov eax, [edx+STREAM.format]
test eax, PCM_OUT
jz .fail
 
cmp ax, PCM_ALL
je .fail
 
mov esi,[src]
test esi, esi
jz .fail
 
cmp esi, OS_BASE
jae .fail
 
mov [state_saved], 0
 
.main_loop:
mov edx, [str]
 
mov ebx, [size]
test ebx, ebx
jz .done
 
cmp [edx+STREAM.flags], SND_STOP
jne .fill
 
mov edi, [edx+STREAM.in_base]
mov ecx, 128/4
mov eax, [edx+STREAM.r_silence]
cld
rep stosd
 
mov ecx, [edx+STREAM.in_size]
sub ecx, 128
mov [edx+STREAM.in_wp], edi
mov [edx+STREAM.in_rp], edi
mov [edx+STREAM.in_count], 0
mov [edx+STREAM.in_free], ecx
 
mov eax,[edx+STREAM.out_base]
mov [edx+STREAM.out_wp], eax
mov [edx+STREAM.out_rp], eax
mov [edx+STREAM.out_count], 0
.fill:
cli
 
mov ecx, [edx+STREAM.in_free]
test ecx, ecx
jz .wait
 
cmp ecx, ebx
jbe @F
 
mov ecx, ebx
@@:
sub [size], ecx
add [edx+STREAM.in_count], ecx
sub [edx+STREAM.in_free], ecx
 
shr ecx, 2
mov edi, [edx+STREAM.in_wp]
mov esi, [src]
cld
rep movsd
 
mov [src], esi
cmp edi, [edx+STREAM.in_top]
jb @F
sub edi, [edx+STREAM.in_size]
@@:
mov [edx+STREAM.in_wp], edi
 
cmp [edx+STREAM.out_count], 32768
jae .skip
 
cmp [state_saved], 0
jne @F
lea eax, [fpu_state+15]
and eax, -16
call FpuSave
mov [state_saved], 1
@@:
stdcall refill, edx
 
.skip:
sti
mov edx, [str]
mov [edx+STREAM.flags], SND_PLAY
cmp [eng_state], SND_PLAY
je .main_loop
 
stdcall dev_play, [hSound]
mov [eng_state], SND_PLAY
jmp .main_loop
.wait:
sti
mov edx, [str]
mov eax, [edx+STREAM.notify_event]
mov ebx, [edx+STREAM.notify_id]
call WaitEvent ;eax ebx
jmp .main_loop
.done:
cmp [state_saved], 1
jne @F
 
lea eax, [fpu_state+15]
and eax, -16
call FpuRestore
@@:
xor eax, eax
ret
.fail:
or eax, -1
ret
endp
 
; both static and stream
; reset all but not clear buffers
 
 
; flags reserved
; RESET_INPUT equ 1 ;reserved reset and clear input buffer
; RESET_OUTPUT equ 2 ;reserved reset and clear output buffer
; RESET_ALL equ 3
 
 
align 4
proc ResetBuffer stdcall, str:dword, flags:dword
 
mov edx, [str]
mov [edx+STREAM.flags], SND_STOP
 
mov edi, [edx+STREAM.in_base]
mov ecx, 128/4
mov eax, [edx+STREAM.r_silence]
cld
rep stosd
 
mov [edx+STREAM.in_wp], edi
mov [edx+STREAM.in_rp], edi
 
test [edx+STREAM.flags], PCM_STATIC
jnz .static
mov [edx+STREAM.in_count], 0
jmp @F
.static:
mov eax, [edx+STREAM.in_size]
mov [edx+STREAM.in_count], eax
@@:
 
mov eax, [edx+STREAM.in_size]
sub eax, 128
mov [edx+STREAM.in_free], eax
 
xor eax, eax
mov ebx,[edx+STREAM.out_base]
mov [edx+STREAM.out_wp], ebx
mov [edx+STREAM.out_rp], ebx
mov [edx+STREAM.out_count], eax
ret
.fail:
or eax, -1
ret
endp
 
; for static buffers only
 
align 4
proc SetBufferPos stdcall, str:dword, pos:dword
 
mov edx, [str]
test [edx+STREAM.format], PCM_STATIC
jz .fail
 
mov [edx+STREAM.flags], SND_STOP
 
mov eax, [pos]
add eax, [edx+STREAM.in_base]
mov ebx, [edx+STREAM.in_top]
add eax, 128
 
cmp eax, ebx
jae .fail
 
mov [edx+STREAM.in_rp], eax
sub ebx, eax
mov [edx+STREAM.in_count], ebx
xor eax, eax
ret
.fail:
or eax, -1
ret
endp
 
align 4
proc GetBufferPos stdcall, str:dword
 
mov edx, [str]
test [edx+STREAM.format], PCM_STATIC
jz .fail
 
mov ebx, [edx+STREAM.in_rp]
sub ebx, [edx+STREAM.in_base]
sub ebx, 128
xor eax, eax
ret
.fail:
xor ebx,ebx
or eax, -1
ret
endp
 
; both
 
align 4
proc SetBufferVol stdcall, str:dword,l_vol:dword,r_vol:dword
 
mov edx, [str]
stdcall set_vol_param,[l_vol],[r_vol],[edx+STREAM.pan]
ret
endp
 
proc set_vol_param stdcall, l_vol:dword,r_vol:dword,pan:dword
locals
_600 dd ?
_32767 dd ?
state rb 108
endl
 
mov [_600], 0x44160000 ;600.0
mov [_32767], 32767
 
lea ebx, [state]
fnsave [ebx]
 
movq mm0, qword [l_vol]
pminsw mm0, qword [vol_max]
pmaxsw mm0, qword [vol_min]
movq qword [l_vol], mm0
movq qword [edx+STREAM.l_vol], mm0
 
movd mm1,[pan]
pminsw mm1, qword [pan_max]
pmaxsw mm1, qword [vol_min]
movd [edx+STREAM.pan], mm1
 
cmp word [edx+STREAM.pan], 0
jl @F
 
psubsw mm0,mm1
pminsw mm0, qword [vol_max]
pmaxsw mm0, qword [vol_min]
movd [l_vol],mm0
jmp .calc_amp
@@:
punpckhdq mm0,mm0
paddsw mm0,mm1
pminsw mm0, qword [vol_max]
pmaxsw mm0, qword [vol_min]
movd [r_vol], mm0
.calc_amp:
emms
fild word [l_vol]
 
call .calc
 
fistp word [edx+STREAM.l_amp]
fstp dword [edx+STREAM.l_amp_f]
fstp st0
 
fild word [r_vol]
 
call .calc
 
fistp word [edx+STREAM.r_amp]
fstp dword [edx+STREAM.r_amp_f]
fstp st0
 
fnclex
lea ebx, [state]
frstor [ebx]
 
xor eax, eax
inc eax
ret
.calc:
fdiv dword [_600]
fld st0
frndint
fxch st1
fsub st, st1
f2xm1
fld1
faddp st1, st0
fscale
fld st0
fimul dword [_32767]
ret 0
endp
 
align 4
proc GetBufferVol stdcall, str:dword,p_lvol:dword,p_rvol:dword
 
mov edx, [str]
mov eax, [p_lvol]
movsx ecx, word [edx+STREAM.l_vol]
mov [eax], ecx
 
mov eax, [p_rvol]
movsx ecx, word [edx+STREAM.r_vol]
mov [eax], ecx
xor eax, eax
ret
endp
 
align 4
proc SetBufferPan stdcall, str:dword,pan:dword
 
mov edx, [str]
stdcall set_vol_param,[edx+STREAM.l_vol],\
[edx+STREAM.r_vol],[pan]
ret
endp
 
; for static and ring buffers only
 
align 4
proc play_buffer stdcall, str:dword, flags:dword
 
mov ebx, [str]
mov eax, [ebx+STREAM.format]
test eax, PCM_OUT
jnz .fail
 
cmp ax, PCM_ALL
je .fail
 
mov [ebx+STREAM.flags], SND_PLAY
cmp [eng_state], SND_PLAY
je .done
 
stdcall dev_play, [hSound]
mov [eng_state], SND_PLAY
.done:
test [flags], PLAY_SYNC
jz @F
 
mov edx, [str]
.wait:
mov eax, [edx+STREAM.notify_event]
mov ebx, [edx+STREAM.notify_id]
call WaitEvent ;eax ebx
 
mov edx, [str]
cmp [edx+STREAM.flags], SND_STOP
jne .wait
@@:
xor eax, eax
ret
.fail:
or eax, -1
ret
endp
 
; for static and ring buffers only
 
align 4
proc stop_buffer stdcall, str:dword
 
mov edx, [str]
test [edx+STREAM.format], PCM_STATIC+PCM_RING
jz .fail
 
mov [edx+STREAM.flags], SND_STOP
 
; stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0
 
mov eax, [edx+STREAM.notify_event]
mov ebx, [edx+STREAM.notify_id]
call ClearEvent ;eax ebx
 
xor eax, eax
ret
.fail:
or eax, -1
ret
endp
 
; param
; eax= mix_list
 
align 4
do_mix_list:
 
xor edx, edx
mov esi, str.fd-FD_OFFSET
mov ebx, [esi+STREAM.str_fd]
@@:
cmp ebx, esi
je .done
 
cmp [ebx+STREAM.magic], 'WAVE'
jne .next
 
cmp [ebx+STREAM.size], STREAM_SIZE
jne .next
 
cmp [ebx+STREAM.flags], SND_PLAY;
jne .next
 
mov ecx, [ebx+STREAM.out_count]
test ecx, ecx
jnz .l1
 
test [ebx+STREAM.format], PCM_RING
jnz .next
mov [ebx+STREAM.flags], SND_STOP
jmp .next
.l1:
cmp ecx, 512
jae .add_buff
 
mov edi, [ebx+STREAM.out_rp]
add edi, ecx
sub ecx, 512
neg ecx
push eax
xor eax, eax
cld
rep stosb
pop eax
 
mov [ebx+STREAM.out_count], 512
 
.add_buff:
mov ecx, [ebx+STREAM.out_rp]
mov [eax],ecx
 
if USE_SSE2_MIXER
mov edi, dword [ebx+STREAM.l_amp_f]
mov [eax+4], edi
mov edi, dword [ebx+STREAM.r_amp_f]
mov [eax+8], edi
else
mov edi, dword [ebx+STREAM.l_amp]
mov [eax+4], edi
end if
add [ebx+STREAM.out_rp], 512
sub [ebx+STREAM.out_count], 512
 
add eax, 12
inc edx
.next:
mov ebx, [ebx+STREAM.str_fd]
jmp @B
.done:
mov eax, edx
ret
 
align 4
prepare_playlist:
 
xor edx, edx
mov [play_count], edx
mov esi, str.fd-FD_OFFSET
mov edi, [esi+STREAM.str_fd]
@@:
cmp edi, esi
je .done
 
cmp [edi+STREAM.magic], 'WAVE'
jne .next
 
cmp [edi+STREAM.size], STREAM_SIZE
jne .next
 
cmp [edi+STREAM.flags], SND_PLAY;
jne .next
 
mov [play_list+edx], edi
inc [play_count]
add edx, 4
.next:
mov edi, [edi+STREAM.str_fd]
jmp @B
.done:
ret
 
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
 
if 0
align 4
dword2str:
mov esi, hex_buff
mov ecx, -8
@@:
rol eax, 4
mov ebx, eax
and ebx, 0x0F
mov bl, [ebx+hexletters]
mov [8+esi+ecx], bl
inc ecx
jnz @B
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
end if
 
include 'mixer.asm'
include 'mix_mmx.inc'
include 'mix_sse2.inc'
 
;if USE_SSE
; include 'mix_sse.inc'
;end if
 
align 16
resampler_params:
;r_size r_dt resampler_func
dd 0,0,0 ; 0 PCM_ALL
dd 16384, 0, copy_stream ; 1 PCM_2_16_48
dd 8192, 0, m16_stereo ; 2 PCM_1_16_48
 
dd 16384, 30109, resample_2 ; 3 PCM_2_16_44
dd 8192, 30109, resample_1 ; 4 PCM_1_16_44
 
dd 16384, 21846, resample_2 ; 5 PCM_2_16_32
dd 8192, 21846, resample_1 ; 6 PCM_1_16_32
 
dd 16384, 16384, resample_2 ; 7 PCM_2_16_24
dd 8192, 16384, resample_1 ; 8 PCM_1_16_24
 
dd 8192, 15052, resample_2 ; 9 PCM_2_16_22
dd 4096, 15052, resample_1 ;10 PCM_1_16_22
 
dd 8192, 10923, resample_2 ;11 PCM_2_16_16
dd 4096, 10923, resample_1 ;12 PCM_1_16_16
 
dd 8192, 8192, resample_2 ;13 PCM_2_16_12
dd 4096, 8192, resample_1 ;14 PCM_1_16_12
 
dd 4096, 7527, resample_2 ;15 PCM_2_16_11
dd 2048, 7527, resample_1 ;16 PCM_1_16_11
 
dd 4096, 5462, resample_2 ;17 PCM_2_16_8
dd 2048, 5462, resample_1 ;18 PCM_1_16_8
 
dd 16384, 0, s8_stereo ;19 PCM_2_8_48
dd 8192, 0, m8_stereo ;20 PCM_1_8_48
 
dd 8192, 30109, resample_28 ;21 PCM_2_8_44
dd 4096, 30109, resample_18 ;22 PCM_1_8_44
 
dd 8192, 21846, resample_28 ;23 PCM_2_8_32
dd 4096, 21846, resample_18 ;24 PCM_1_8_32
 
dd 8192, 16384, resample_28 ;25 PCM_2_8_24
dd 4096, 16384, resample_18 ;26 PCM_1_8_24
 
dd 4096, 15052, resample_28 ;27 PCM_2_8_22
dd 2048, 15052, resample_18 ;28 PCM_1_8_22
 
dd 4096, 10923, resample_28 ;29 PCM_2_8_16
dd 2048, 10923, resample_18 ;30 PCM_1_8_16
 
dd 4096, 8192, resample_28 ;31 PCM_2_8_12
dd 2048, 8192, resample_18 ;32 PCM_1_8_12
 
dd 2048, 7527, resample_28 ;33 PCM_2_8_11
dd 1024, 7527, resample_18 ;34 PCM_1_8_11
 
dd 2048, 5462, resample_28 ;35 PCM_2_8_8
dd 1024, 5462, resample_18 ;36 PCM_1_8_8
 
m7 dw 0x8000,0x8000,0x8000,0x8000
mm80 dq 0x8080808080808080
mm_mask dq 0xFF00FF00FF00FF00
 
vol_max dd 0x00000000,0x00000000
vol_min dd 0x0000D8F0,0x0000D8F0
pan_max dd 0x00002710,0x00002710
 
;stream_map dd 0xFFFF ; 16
version dd (5 shl 16) or SOUND_VERSION
 
szInfinity db 'INFINITY',0
szSound db 'SOUND',0
 
if DEBUG
msgFail db 'Sound service not loaded',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
msgDestroy db 'Destroy sound buffer', 13,10,0
msgWaveout db 'Play waveout', 13,10,0
msgSetVolume db 'Set volume',13,10,0
end if
 
section '.data' data readable writable align 16
 
play_list rd 16
mix_input rd 16
play_count rd 1
hSound rd 1
eng_state rd 1
mix_buff rd 1
mix_buff_map rd 1
str.fd rd 1
str.bk rd 1
 
mix_2_core rd 1
mix_3_core rd 1
mix_4_core rd 1
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/mixer.asm
0,0 → 1,1262
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; (C) copyright Serge 2006
; email: infinity_sound@mail.ru
 
 
align 4
 
mix_list rd 32*3
 
align 4
proc new_mix stdcall, output:dword
locals
main_count rd 1
fpu_state rb 528 ;512+16
endl
 
mov [main_count], 32
call prepare_playlist
cmp [play_count], 0
je .clear
 
lea eax, [fpu_state+16]
and eax, -16 ;must be 16b aligned
call FpuSave
 
call update_stream
.mix:
lea eax, [mix_list]
call do_mix_list
test eax, eax
je .done
 
if USE_SSE2_MIXER
 
cmp eax, 1
ja @F
;use fast path
mov edi, [output]
lea edx, [mix_list]
call mix_fast
jmp .next
@@:
cmp eax, 2
ja @F
 
mov edi, [output]
lea edx, [mix_list]
call mix_fast_2_stream
jmp .next
@@:
 
end if
 
lea ebx, [mix_list]
stdcall mix_all, [output], ebx, eax
.next:
add [output], 512
dec [main_count]
jnz .mix
.exit:
lea eax, [fpu_state+16]
and eax, -16
call FpuRestore
ret
.done:
mov ecx, [main_count]
shl ecx, 7 ;ecx*= 512/4
 
mov edi, [output]
xor eax, eax
cld
rep stosd
jmp .exit
.clear:
mov edi, [output]
mov ecx, 4096
xor eax, eax
cld
rep stosd
ret
endp
 
align 4
proc update_stream
locals
stream_index dd ?
event rd 6
endl
 
mov [stream_index], 0
.l1:
mov edx, [stream_index]
mov esi, [play_list+edx*4]
 
mov eax, [esi+STREAM.out_rp]
cmp eax, [esi+STREAM.out_top]
jb @f
sub eax, 64*1024
@@:
mov [esi+STREAM.out_rp], eax
 
cmp [esi+STREAM.out_count], 16384
ja .skip
 
test [esi+STREAM.format], PCM_RING
jnz .ring
 
stdcall refill, esi
.skip:
inc [stream_index]
dec [play_count]
jnz .l1
ret
.ring:
stdcall refill_ring, esi
jmp .skip
endp
 
align 4
proc refill stdcall, str:dword
locals
r_size rd 1
endl
 
mov ebx, [str]
mov edi, [ebx+STREAM.out_wp]
cmp edi, [ebx+STREAM.out_top]
jb @F
sub edi, 0x10000
mov [ebx+STREAM.out_wp], edi
@@:
mov eax, [ebx+STREAM.in_count]
test eax, eax
jz .done
 
mov ecx, [ebx+STREAM.r_size]
cmp eax, ecx
jle @F
 
mov eax, ecx
@@:
mov ecx, eax
cmp word [ebx+STREAM.format], PCM_1_16_8
ja @F
 
shr eax, 1 ;two channles
@@:
test [ebx+STREAM.format], 1 ;even formats mono
jz @F
 
shr eax, 1 ;eax= samples
@@:
shl eax, 15 ;eax*=32768 =r_end
 
mov [r_size], ecx
 
mov esi, [ebx+STREAM.in_rp]
mov edi, [ebx+STREAM.out_wp]
 
stdcall [ebx+STREAM.resample], edi, esi, \
[ebx+STREAM.r_dt], ecx, eax
 
mov ebx, [str]
 
add [ebx+STREAM.out_count], eax;
add [ebx+STREAM.out_wp], eax;
 
mov eax, [ebx+STREAM.in_rp]
mov ecx, [r_size]
add eax, ecx
add [ebx+STREAM.in_free], ecx
sub [ebx+STREAM.in_count], ecx
 
cmp eax, [ebx+STREAM.in_top]
jb @f
 
sub eax, [ebx+STREAM.in_size]
@@:
mov [ebx+STREAM.in_rp], eax
 
.done:
mov eax, [ebx+STREAM.notify_event]
test eax, eax
jz .exit
 
mov ebx, [ebx+STREAM.notify_id]
mov edx, EVENT_WATCHED
xor esi, esi
call RaiseEvent ;eax, ebx, edx, esi
.exit:
ret
endp
 
align 4
proc refill_ring stdcall, str:dword
locals
event rd 6
endl
 
mov ebx, [str]
mov edi, [ebx+STREAM.out_wp]
cmp edi, [ebx+STREAM.out_top]
jb @F
sub edi, 0x10000
mov [ebx+STREAM.out_wp], edi
@@:
mov ecx, [ebx+STREAM.r_size]
mov eax, ecx
cmp word [ebx+STREAM.format], PCM_1_16_8
ja @F
 
shr eax, 1 ;two channles
@@:
test [ebx+STREAM.format], 1 ;even formats mono
jz @F
 
shr eax, 1 ;eax= samples
@@:
shl eax, 15 ;eax*=32768 =r_end
 
mov esi, [ebx+STREAM.in_rp]
mov edi, [ebx+STREAM.out_wp]
 
stdcall [ebx+STREAM.resample], edi, esi, \
[ebx+STREAM.r_dt], ecx, eax
 
mov ebx, [str]
 
add [ebx+STREAM.out_count], eax;
add [ebx+STREAM.out_wp], eax;
 
mov eax, [ebx+STREAM.in_rp]
mov ecx, [ebx+STREAM.r_size]
add eax, ecx
add [ebx+STREAM.in_free], ecx
sub [ebx+STREAM.in_count], ecx
 
cmp eax, [ebx+STREAM.in_top]
jb @f
 
sub eax, [ebx+STREAM.in_size]
@@:
mov [ebx+STREAM.in_rp], eax
 
sub eax, [ebx+STREAM.in_base]
sub eax, 128
lea esi, [event]
 
mov dword [esi], RT_INP_EMPTY
mov dword [esi+4], 0
mov dword [esi+8], ebx
mov dword [esi+12], eax
 
mov eax, [ebx+STREAM.notify_event]
test eax, eax
jz .exit
 
mov ebx, [ebx+STREAM.notify_id]
xor edx, edx
call RaiseEvent ;eax, ebx, edx, esi
.exit:
ret
endp
 
if USE_SSE2_MIXER
 
align 4
proc mix_all stdcall, dest:dword, list:dword, count:dword
 
mov edi, [dest]
mov ebx, 32
.mix:
mov edx, [list]
mov ecx, [count]
 
mov eax, [edx]
 
movdqa xmm1, [eax]
movss xmm2, [edx+4]
movss xmm3, [edx+8]
 
punpcklwd xmm0, xmm1
punpckhwd xmm1, xmm1
 
shufps xmm2, xmm3, 0
shufps xmm2, xmm2, 0x88
 
psrad xmm0, 16
psrad xmm1, 16
cvtdq2ps xmm0, xmm0
cvtdq2ps xmm1, xmm1
mulps xmm0, xmm2
mulps xmm1, xmm2
 
.mix_loop:
add dword [edx], 16
add edx, 12
dec ecx
jz @F
 
mov eax, [edx]
 
movdqa xmm3, [eax]
movss xmm4, [edx+4]
movss xmm5, [edx+8]
 
punpcklwd xmm2, xmm3
punpckhwd xmm3, xmm3
 
shufps xmm4, xmm5, 0
shufps xmm4, xmm4, 0x88
 
psrad xmm2, 16
psrad xmm3, 16
 
cvtdq2ps xmm2, xmm2
cvtdq2ps xmm3, xmm3
 
mulps xmm2, xmm4
mulps xmm3, xmm4
addps xmm0, xmm2
addps xmm1, xmm3
 
jmp .mix_loop
@@:
cvtps2dq xmm0, xmm0
cvtps2dq xmm1, xmm1
packssdw xmm0, xmm0
packssdw xmm1, xmm1
punpcklqdq xmm0, xmm1
movntdq [edi], xmm0
 
add edi, 16
dec ebx
jnz .mix
 
ret
endp
 
; param
; edi = dest
; edx = mix_list
 
align 4
mix_fast:
 
mov ebx, 32
mov eax, [edx]
 
movss xmm2, [edx+4] ; vol Lf
movss xmm3, [edx+8] ; vol Rf
shufps xmm2, xmm3, 0 ; Rf Rf Lf Lf
shufps xmm2, xmm2, 0x88 ; volume level Rf Lf Rf Lf
.mix:
movdqa xmm1, [eax] ; R3w L3w R2w L2w R1w L1w R0w L0w
add eax, 16
punpcklwd xmm0, xmm1 ; R1w R1w L1w L1W R0w R0w L0w L0w
punpckhwd xmm1, xmm1 ; R3w R3w L3w L3w R2w R2w L2w L2w
 
psrad xmm0, 16 ; R1d L1d R0d L0d
psrad xmm1, 16 ; R3d L3d R2d L2d
 
cvtdq2ps xmm0, xmm0 ; time to use all power
cvtdq2ps xmm1, xmm1 ; of the dark side
 
mulps xmm0, xmm2 ; R1f' L1f' R0f' L0f'
mulps xmm1, xmm2 ; R3f' L3f' R2f' L2f'
 
cvtps2dq xmm0, xmm0 ; R1d' L1d' R0d' L0d'
cvtps2dq xmm1, xmm1 ; R3d' L3d' R2d' L2d'
packssdw xmm0, xmm0 ; R1w' L1w' R0w' L0w' R1w' L1w' R0w' L0w'
packssdw xmm1, xmm1 ; R3w' L3w' R2w' L2w' R3w' L3w' R2w' L2w'
punpcklqdq xmm0, xmm1 ; R3w' L3w' R2w' L2w' R1w' L1w' R0w' L0w'
movntdq [edi], xmm0
 
add edi, 16
dec ebx
jnz .mix
 
ret
 
align 4
mix_fast_2_stream:
 
mov ebx, 32
mov eax, [edx]
 
movss xmm4, [edx+4] ; vol Lf
movss xmm5, [edx+8] ; vol Rf
mov ecx, [edx+12]
 
movss xmm6, [edx+16] ; vol Lf
movss xmm7, [edx+20] ; vol Rf
 
shufps xmm4, xmm5, 0 ; Rf Rf Lf Lf
shufps xmm4, xmm4, 0x88 ; volume level Rf Lf Rf Lf
 
shufps xmm6, xmm7, 0 ; Rf Rf Lf Lf
shufps xmm6, xmm6, 0x88 ; volume level Rf Lf Rf Lf
 
.mix:
movdqa xmm1, [eax] ; R3w L3w R2w L2w R1w L1w R0w L0w
movdqa xmm3, [ecx] ; R3w L3w R2w L2w R1w L1w R0w L0w
 
add eax, 16
add ecx, 16
 
punpcklwd xmm0, xmm1 ; R1w R1w L1w L1W R0w R0w L0w L0w
punpckhwd xmm1, xmm1 ; R3w R3w L3w L3w R2w R2w L2w L2w
 
psrad xmm0, 16 ; R1d L1d R0d L0d
psrad xmm1, 16 ; R3d L3d R2d L2d
 
cvtdq2ps xmm0, xmm0 ; time to use all power
cvtdq2ps xmm1, xmm1 ; of the dark side
 
mulps xmm0, xmm4 ; R1f' L1f' R0f' L0f'
mulps xmm1, xmm4 ; R3f' L3f' R2f' L2f'
 
punpcklwd xmm2, xmm3 ; R1w R1w L1w L1W R0w R0w L0w L0w
punpckhwd xmm3, xmm3 ; R3w R3w L3w L3w R2w R2w L2w L2w
 
psrad xmm2, 16 ; R1d L1d R0d L0d
psrad xmm3, 16 ; R3d L3d R2d L2d
 
cvtdq2ps xmm2, xmm2 ; time to use all power
cvtdq2ps xmm3, xmm3 ; of the dark side
 
mulps xmm2, xmm6 ; R1f' L1f' R0f' L0f'
mulps xmm3, xmm6 ; R3f' L3f' R2f' L2f'
 
addps xmm0, xmm2
addps xmm1, xmm3
 
cvtps2dq xmm0, xmm0 ; R1d' L1d' R0d' L0d'
cvtps2dq xmm1, xmm1 ; R3d' L3d' R2d' L2d'
packssdw xmm0, xmm0 ; R1w' L1w' R0w' L0w' R1w' L1w' R0w' L0w'
packssdw xmm1, xmm1 ; R3w' L3w' R2w' L2w' R3w' L3w' R2w' L2w'
punpcklqdq xmm0, xmm1 ; R3w' L3w' R2w' L2w' R1w' L1w' R0w' L0w'
movntdq [edi], xmm0
 
add edi, 16
dec ebx
jnz .mix
 
ret
 
else ; fixed point mmx version
 
align 4
proc mix_all stdcall, dest:dword, list:dword, count:dword
 
mov edi, [dest]
mov ebx, 64
.mix:
mov edx, [list]
mov ecx, [count]
 
mov eax, [edx]
 
movq mm0, [eax]
 
movd mm1, [edx+4]
punpckldq mm1,mm1
pmulhw mm0, mm1
psllw mm0, 1
 
.mix_loop:
add dword [edx], 8
add edx, 12
dec ecx
jz @F
 
mov eax, [edx]
movq mm1, [eax]
movd mm2, [edx+4]
punpckldq mm2,mm2
pmulhw mm1, mm2
psllw mm1, 1
paddsw mm0, mm1
jmp .mix_loop
@@:
movq [edi], mm0
add edi, 8
dec ebx
jnz .mix
 
ret
endp
 
end if
 
 
align 4
proc resample_1 stdcall, dest:dword,src:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
; dest equ esp+8
; src equ esp+12
; r_dt equ esp+16
; r_size equ esp+20
; r_end equ esp+24
 
mov edi, [dest]
mov edx, [src]
sub edx, 32*2
mov eax, 16
 
align 4
.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+16]
cmp eax, [esp+24]
jb .l1
 
mov ebp, esp
 
sub edi, [dest]
mov eax, edi
ret
endp
 
align 4
proc resample_18 stdcall, dest:dword,src:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
 
mov edi, [dest]
mov edx, [src]
sub edx, 32
 
mov esi, 16
 
align 4
.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+16]
cmp esi, [esp+24]
jb .l1
 
mov ebp, esp
sub edi, [dest]
mov eax, edi
ret
endp
 
align 4
proc copy_stream stdcall, dest:dword,src: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]
cld
rep movsd
ret
endp
 
align 4
proc resample_2 stdcall, dest:dword,src:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov edx, [src]
sub edx, 32*4
mov edi, [dest]
mov ebx, [r_dt]
mov eax, 16
emms
 
align 4
.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
 
sub edi, [dest]
mov eax, edi
ret
endp
 
align 4
proc resample_28 stdcall, dest:dword,src:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov edx, [src]
sub edx, 32*2
mov edi, [dest]
mov ebx, [r_dt]
mov eax, 16
emms
movq mm7,[mm80]
movq mm6,[mm_mask]
 
align 4
.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
 
 
sub edi, [dest]
mov eax, edi
ret
endp
 
 
proc m16_stereo stdcall, dest:dword,src: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_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_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
 
align 4
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]
mov eax, [str0]
mov ebx, [str1]
mov esi, 128
call [mix_2_core] ;edi, eax, ebx
 
add edi, esi
add eax, esi
add ebx, esi
call [mix_2_core] ;edi, eax, ebx
 
add edi, esi
add eax, esi
add ebx, esi
call [mix_2_core] ;edi, eax, ebx
 
add edi, esi
add eax, esi
add ebx, esi
call [mix_2_core] ;edi, eax, ebx
ret
endp
 
align 4
proc mix_3_1 stdcall, output:dword, str0:dword, str1:dword, str2:dword
 
mov edi, [output]
mov eax, [str0]
mov ebx, [str1]
mov ecx, [str2]
mov esi, 128
call [mix_3_core]
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
call [mix_3_core]
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
call [mix_3_core]
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
call [mix_3_core]
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
mov eax, [str0]
mov ebx, [str1]
mov ecx, [str2]
mov edx, [str3]
mov esi, 128
call [mix_4_core] ;edi, eax, ebx, ecx, edx
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
add edx, esi
call [mix_4_core] ;edi, eax, ebx, ecx, edx
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
add edx, esi
call [mix_4_core] ;edi, eax, ebx, ecx, edx
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
add edx, esi
call [mix_4_core] ;edi, eax, ebx, ecx, edx
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]
 
mov eax, [str0]
mov ebx, [str1]
mov ecx, [str2]
mov edx, [str3]
mov esi, 128
call [mix_4_core] ;edi, eax, ebx, ecx, edx
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
add edx, esi
call [mix_4_core] ;edi, eax, ebx, ecx, edx
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
add edx, esi
call [mix_4_core] ;edi, eax, ebx, ecx, edx
 
add edi, esi
add eax, esi
add ebx, esi
add ecx, esi
add edx, esi
call [mix_4_core] ;edi, eax, ebx, ecx, edx
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
 
if 0
 
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
call FpuSave
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
 
dec [main_count]
jnz .l00
 
call update_stream
emms
call FpuRestore
ret
.exit:
mov edi, [output]
mov ecx, 0x1000
xor eax, eax
cld
rep stosd
ret
endp
 
end if
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/uart.asm
0,0 → 1,976
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
format MS COFF
 
DEBUG equ 1
 
include 'proc32.inc'
include 'imports.inc'
 
 
 
API_VERSION equ 0
UART_VERSION equ API_VERSION
 
PG_SW equ 0x003
page_tabs equ 0xFDC00000 ;hack
 
OS_BASE equ 0x80000000
SLOT_BASE equ (OS_BASE+0x0080000)
TASK_COUNT equ (OS_BASE+0x0003004)
CURRENT_TASK equ (OS_BASE+0x0003000)
 
 
struc APPOBJ ;common object header
{
.magic dd ? ;
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
};
 
virtual at 0
APPOBJ APPOBJ
end virtual
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
DEBUG equ 1
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
 
THR_REG equ 0; x3f8 ;transtitter/reciever
IER_REG equ 1; x3f9 ;interrupt enable
IIR_REG equ 2; x3fA ;interrupt info
LCR_REG equ 3; x3FB ;line control
MCR_REG equ 4; x3FC ;modem control
LSR_REG equ 5; x3FD ;line status
MSR_REG equ 6; x3FE ;modem status
 
LCR_5BIT equ 0x00
LCR_6BIT equ 0x01
LCR_7BIT equ 0x02
LCR_8BIT equ 0x03
LCR_STOP_1 equ 0x00
LCR_STOP_2 equ 0x04
LCR_PARITY equ 0x08
LCR_EVEN equ 0x10
LCR_STICK equ 0x20
LCR_BREAK equ 0x40
LCR_DLAB equ 0x80
 
LSR_DR equ 0x01 ;data ready
LSR_OE equ 0x02 ;overrun error
LSR_PE equ 0x04 ;parity error
LSR_FE equ 0x08 ;framing error
LSR_BI equ 0x10 ;break interrupt
LSR_THRE equ 0x20 ;transmitter holding empty
LSR_TEMT equ 0x40 ;transmitter empty
LSR_FER equ 0x80 ;FIFO error
 
FCR_EFIFO equ 0x01 ;enable FIFO
FCR_CRB equ 0x02 ;clear reciever FIFO
FCR_CXMIT equ 0x04 ;clear transmitter FIFO
FCR_RDY equ 0x08 ;set RXRDY and TXRDY pins
FCR_FIFO_1 equ 0x00 ;1 byte trigger
FCR_FIFO_4 equ 0x40 ;4 bytes trigger
FCR_FIFO_8 equ 0x80 ;8 bytes trigger
FCR_FIFO_14 equ 0xC0 ;14 bytes trigger
 
IIR_INTR equ 0x01 ;1= no interrupts
 
IER_RDAI equ 0x01 ;reciever data interrupt
IER_THRI equ 0x02 ;transmitter empty interrupt
IER_LSI equ 0x04 ;line status interrupt
IER_MSI equ 0x08 ;modem status interrupt
 
MCR_DTR equ 0x01 ;0-> DTR=1, 1-> DTR=0
MCR_RTS equ 0x02 ;0-> RTS=1, 1-> RTS=0
MCR_OUT_1 equ 0x04 ;0-> OUT1=1, 1-> OUT1=0
MCR_OUT_2 equ 0x08 ;0-> OUT2=1, 1-> OUT2=0; enable intr
MCR_LOOP equ 0x10 ;lopback mode
 
MSR_DCTS equ 0x01 ;delta clear to send
MSR_DDSR equ 0x02 ;delta data set redy
MSR_TERI equ 0x04 ;trailinh edge of ring
MSR_DDCD equ 0x08 ;delta carrier detect
 
 
RATE_50 equ 0
RATE_75 equ 1
RATE_110 equ 2
RATE_134 equ 3
RATE_150 equ 4
RATE_300 equ 5
RATE_600 equ 6
RATE_1200 equ 7
RATE_1800 equ 8
RATE_2000 equ 9
RATE_2400 equ 10
RATE_3600 equ 11
RATE_4800 equ 12
RATE_7200 equ 13
RATE_9600 equ 14
RATE_19200 equ 15
RATE_38400 equ 16
RATE_57600 equ 17
RATE_115200 equ 18
 
COM_1 equ 1
COM_2 equ 2
COM_3 equ 3
COM_4 equ 4
COM_MAX equ 2 ;only two port supported
 
COM_1_BASE equ 0x3F8
COM_2_BASE equ 0x2F8
 
COM_1_IRQ equ 4
COM_2_IRQ equ 3
 
UART_CLOSED equ 0
UART_TRANSMIT equ 1
UART_STOP equ 2
 
struc UART
{
.lock dd ?
.base dd ?
.lcr_reg dd ?
.mcr_reg dd ?
.rate dd ?
.mode dd ?
.state dd ?
 
.rcvr_buff dd ?
.rcvr_rp dd ?
.rcvr_wp dd ?
.rcvr_count dd ?
.rcvr_top dd ?
 
.xmit_buff dd ?
.xmit_rp dd ?
.xmit_wp dd ?
.xmit_count dd ?
.xmit_free dd ?
.xmit_top dd ?
}
virtual at 0
UART UART
end virtual
 
UART_SIZE equ 18*4
 
struc CONNECTION
{
.magic dd ? ;'CNCT'
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
 
.id dd ? ;reserved
.uart dd ? ;uart pointer
}
 
virtual at 0
CONNECTION CONNECTION
end virtual
 
CONNECTION_SIZE equ 7*4
 
public START
public service_proc
public version
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .stop
 
mov eax, UART_SIZE
call Kmalloc
test eax, eax
jz .fail
 
mov [com1], eax
mov edi, eax
mov ecx, UART_SIZE/4
xor eax, eax
cld
rep stosd
 
mov eax, [com1]
mov [eax+UART.base], COM_1_BASE
 
stdcall AllocKernelSpace, 32768
 
mov edi, [com1]
mov edx, eax
 
mov [edi+UART.rcvr_buff], eax
add eax, 8192
mov [edi+UART.rcvr_top], eax
add eax, 8192
mov [edi+UART.xmit_buff], eax
add eax, 8192
mov [edi+UART.xmit_top], eax
 
call AllocPage
test eax, eax
jz .fail
 
shr edx, 12
or eax, PG_SW
mov [page_tabs+edx*4], eax
mov [page_tabs+edx*4+8], eax
 
call AllocPage
test eax, eax
jz .fail
 
or eax, PG_SW
mov [page_tabs+edx*4+4], eax
mov [page_tabs+edx*4+12], eax
 
call AllocPage
test eax, eax
jz .fail
 
or eax, PG_SW
mov [page_tabs+edx*4+16], eax
mov [page_tabs+edx*4+24], eax
 
call AllocPage
test eax, eax
jz .fail
 
or eax, PG_SW
mov [page_tabs+edx*4+20], eax
mov [page_tabs+edx*4+28], eax
 
mov eax, [edi+UART.rcvr_buff]
invlpg [eax]
invlpg [eax+0x1000]
invlpg [eax+0x2000]
invlpg [eax+0x3000]
invlpg [eax+0x4000]
invlpg [eax+0x5000]
invlpg [eax+0x6000]
invlpg [eax+0x7000]
 
mov eax, edi
call uart_reset.internal ;eax= uart
 
stdcall AttachIntHandler, COM_1_IRQ, com_1_isr, dword 0
stdcall RegService, sz_uart_srv, service_proc
ret
.fail:
.stop:
xor eax, eax
ret
endp
 
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
SRV_GETVERSION equ 0
PORT_OPEN equ 1
PORT_CLOSE equ 2
PORT_RESET equ 3
PORT_SETMODE equ 4
PORT_GETMODE equ 5
PORT_SETMCR equ 6
PORT_GETMCR equ 7
PORT_READ equ 8
PORT_WRITE equ 9
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov ebx, [ioctl]
mov eax, [ebx+io_code]
cmp eax, PORT_WRITE
ja .fail
 
cmp eax, SRV_GETVERSION
jne @F
 
mov eax, [ebx+output]
cmp [ebx+out_size], 4
jne .fail
mov [eax], dword UART_VERSION
xor eax, eax
ret
@@:
cmp eax, PORT_OPEN
jne @F
 
cmp [ebx+out_size], 4
jne .fail
 
mov ebx, [ebx+input]
mov eax, [ebx]
call uart_open
mov ebx, [ioctl]
mov ebx, [ebx+output]
mov [ebx], ecx
ret
@@:
mov esi, [ebx+input] ;input buffer
mov edi, [ebx+output]
call [uart_func+eax*4]
ret
.fail:
or eax, -1
ret
 
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
 
; param
; esi= input buffer
; +0 connection
;
; retval
; eax= error code
 
align 4
uart_reset:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
 
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
 
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
 
; set mode 2400 bod 8-bit
; disable DTR & RTS
; clear FIFO
; clear pending interrupts
;
; param
; eax= uart
 
align 4
.internal:
mov esi, eax
mov [eax+UART.state], UART_CLOSED
mov edx, [eax+UART.base]
add edx, MCR_REG
xor eax, eax
out dx, al ;clear DTR & RTS
 
mov eax, esi
mov ebx, RATE_2400
mov ecx, LCR_8BIT+LCR_STOP_1
call uart_set_mode.internal
 
mov edx, [esi+UART.base]
add edx, IIR_REG
mov eax,FCR_EFIFO+FCR_CRB+FCR_CXMIT+FCR_FIFO_14
out dx, al
.clear_RB:
mov edx, [esi+UART.base]
add edx, LSR_REG
in al, dx
test eax, LSR_DR
jz @F
 
mov edx, [esi+UART.base]
in al, dx
jmp .clear_RB
@@:
mov edx, [esi+UART.base]
add edx, IER_REG
mov eax,IER_RDAI+IER_THRI+IER_LSI
out dx, al
.clear_IIR:
mov edx, [esi+UART.base]
add edx, IIR_REG
in al, dx
test al, IIR_INTR
jnz .done
 
shr eax, 1
and eax, 3
jnz @F
 
mov edx, [esi+UART.base]
add edx, MSR_REG
in al, dx
jmp .clear_IIR
@@:
cmp eax, 1
je .clear_IIR
 
cmp eax, 2
jne @F
 
mov edx, [esi+UART.base]
in al, dx
jmp .clear_IIR
@@:
mov edx, [esi+UART.base]
add edx, LSR_REG
in al, dx
jmp .clear_IIR
.done:
mov edi, [esi+UART.rcvr_buff]
mov ecx, 8192/4
xor eax, eax
 
mov [esi+UART.rcvr_rp], edi
mov [esi+UART.rcvr_wp], edi
mov [esi+UART.rcvr_count], eax
 
cld
rep stosd
 
mov edi, [esi+UART.xmit_buff]
mov ecx, 8192/4
 
mov [esi+UART.xmit_rp], edi
mov [esi+UART.xmit_wp], edi
mov [esi+UART.xmit_count], eax
mov [esi+UART.xmit_free], 8192
 
rep stosd
ret ;eax= 0
.fail:
or eax, -1
ret
 
; param
; esi= input buffer
; +0 connection
; +4 rate
; +8 mode
;
; retval
; eax= error code
 
align 4
uart_set_mode:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
 
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
 
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
 
mov ebx, [esi+4]
mov ecx, [esi+8]
 
; param
; eax= uart
; ebx= baud rate
; ecx= mode
 
align 4
.internal:
cmp ebx, RATE_115200
ja .fail
 
cmp ecx, LCR_BREAK
jae .fail
 
mov [eax+UART.rate], ebx
mov [eax+UART.mode], ecx
 
mov esi, eax
mov bx, [divisor+ebx*2]
 
mov edx, [esi+UART.base]
push edx
add edx, LCR_REG
in al, dx
or al, 0x80
out dx, al
 
pop edx
mov al, bl
out dx, al
 
inc dx
mov al, bh
out dx, al
 
add edx, LCR_REG-1
mov eax, ecx
out dx, al
xor eax, eax
ret
.fail:
or eax, -1
ret
 
; param
; esi= input buffer
; +0 connection
; +4 modem control reg valie
;
; retval
; eax= error code
 
align 4
uart_set_mcr:
 
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
 
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
 
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
 
mov ebx, [esi+4]
 
mov [eax+UART.mcr_reg], ebx
mov edx, [eax+UART.base]
add edx, MCR_REG
mov al, bl
out dx, al
xor eax, eax
ret
.fail:
or eax, -1
ret
 
; param
; eax= port
;
; retval
; ecx= connection
; eax= error code
 
align 4
uart_open:
dec eax
cmp eax, COM_MAX
jae .fail
 
mov esi, [com1+eax*4] ;uart
push esi
.do_wait:
cmp dword [esi+UART.lock],0
je .get_lock
; call change_task
jmp .do_wait
.get_lock:
mov eax, 1
xchg eax, [esi+UART.lock]
test eax, eax
jnz .do_wait
 
mov eax, esi ;uart
call uart_reset.internal
 
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov ebx, [CURRENT_TASK+ebx+4]
mov eax, CONNECTION_SIZE
call CreateObject
pop esi ;uart
test eax, eax
jz .fail
 
mov [eax+APPOBJ.magic], 'CNCT'
mov [eax+APPOBJ.destroy], uart_close.destroy
mov [eax+CONNECTION.uart], esi
mov ecx, eax
xor eax, eax
ret
.fail:
or eax, -1
ret
restore .uart
 
; param
; esi= input buffer
 
align 4
uart_close:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
 
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
.destroy:
push [eax+CONNECTION.uart]
call DestroyObject ;eax= object
pop eax ;eax= uart
test eax, eax
jz .fail
 
mov [eax+UART.state], UART_CLOSED
mov [eax+UART.lock], 0 ;release port
xor eax, eax
ret
.fail:
or eax, -1
ret
 
 
; param
; eax= uart
; ebx= baud rate
 
align 4
set_rate:
cmp ebx, RATE_115200
ja .fail
 
mov [eax+UART.rate], ebx
mov bx, [divisor+ebx*2]
 
mov edx, [eax+UART.base]
add edx, LCR_REG
in al, dx
push eax
or al, 0x80
out dx, al
 
sub edx, LCR_REG
mov al, bl
out dx, al
 
inc edx
mov al, bh
out dx, al
 
pop eax
add edx, LCR_REG-1
out dx, al
.fail:
ret
 
 
; param
; ebx= uart
 
align 4
transmit:
push esi
push edi
 
mov edx, [ebx+UART.base]
 
pushfd
cli
 
mov esi, [ebx+UART.xmit_rp]
mov ecx, [ebx+UART.xmit_count]
test ecx, ecx
je .stop
 
cmp ecx, 16
jbe @F
mov ecx, 16
@@:
sub [ebx+UART.xmit_count], ecx
add [ebx+UART.xmit_free], ecx
cld
@@:
lodsb
out dx, al
dec ecx
jnz @B
 
cmp esi,[ebx+UART.xmit_top]
jb @F
sub esi, 8192
@@:
mov [ebx+UART.xmit_rp], esi
 
cmp [ebx+UART.xmit_count], 0
je .stop
 
mov [ebx+UART.state], UART_TRANSMIT
jmp @F
.stop:
mov [ebx+UART.state], UART_STOP
@@:
popfd
pop edi
pop esi
ret
 
 
; param
; esi= input buffer
; +0 connection
; +4 dst buffer
; +8 dst size
; edi= output buffer
; +0 bytes read
 
; retval
; eax= error code
 
align 4
uart_read:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
 
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
 
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
 
mov ebx, [esi+8] ;dst size
mov ecx, [eax+UART.rcvr_count]
cmp ecx, ebx
jbe @F
mov ecx, ebx
@@:
mov [edi], ecx ;bytes read
test ecx, ecx
jz .done
 
push ecx
 
mov edi, [esi+4] ;dst
mov esi, [eax+UART.rcvr_rp]
cld
rep movsb
pop ecx
 
cmp esi, [eax+UART.rcvr_top]
jb @F
sub esi, 8192
@@:
mov [eax+UART.rcvr_rp], esi
sub [eax+UART.rcvr_count], ecx
.done:
xor eax, eax
ret
.fail:
or eax, -1
ret
 
; param
; esi= input buffer
; +0 connection
; +4 src buffer
; +8 src size
;
; retval
; eax= error code
 
align 4
uart_write:
mov eax, [esi]
cmp [eax+APPOBJ.magic], 'CNCT'
jne .fail
 
cmp [eax+APPOBJ.destroy], uart_close.destroy
jne .fail
 
mov eax, [eax+CONNECTION.uart]
test eax, eax
jz .fail
 
mov ebx, [esi+4]
mov edx, [esi+8]
 
; param
; eax= uart
; ebx= src
; edx= count
 
align 4
.internal:
mov esi, ebx
mov edi, [eax+UART.xmit_wp]
.write:
test edx, edx
jz .fail
.wait:
cmp [eax+UART.xmit_free], 0
jne .fill
 
cmp [eax+UART.state], UART_TRANSMIT
je .wait
 
mov ebx, eax
push edx
call transmit
pop edx
mov eax, ebx
jmp .write
.fill:
mov ecx, [eax+UART.xmit_free]
cmp ecx, edx
jbe @F
mov ecx, edx
@@:
push ecx
cld
rep movsb
pop ecx
sub [eax+UART.xmit_free], ecx
add [eax+UART.xmit_count], ecx
sub edx, ecx
jnz .wait
.done:
cmp edi, [eax+UART.xmit_top]
jb @F
sub edi, 8192
@@:
mov [eax+UART.xmit_wp], edi
cmp [eax+UART.state], UART_TRANSMIT
je @F
mov ebx, eax
call transmit
@@:
xor eax, eax
ret
.fail:
or eax, -1
ret
 
 
align 4
com_2_isr:
mov ebx, [com2]
jmp com_1_isr.get_info
align 4
com_1_isr:
mov ebx, [com1]
.get_info:
mov edx, [ebx+UART.base]
add edx, IIR_REG
in al, dx
 
test al, IIR_INTR
jnz .done
 
shr eax, 1
and eax, 3
 
call [isr_action+eax*4]
jmp .get_info
.done:
ret
 
align 4
isr_line:
mov edx, [ebx+UART.base]
add edx, LSR_REG
in al, dx
ret
 
align 4
isr_recieve:
mov esi, [ebx+UART.base]
add esi, LSR_REG
mov edi, [ebx+UART.rcvr_wp]
xor ecx, ecx
cld
.read:
mov edx, esi
in al, dx
test eax, LSR_DR
jz .done
 
mov edx, [ebx+UART.base]
in al, dx
stosb
inc ecx
jmp .read
.done:
cmp edi, [ebx+UART.rcvr_top]
jb @F
sub edi, 8192
@@:
mov [ebx+UART.rcvr_wp], edi
add [ebx+UART.rcvr_count], ecx
ret
 
align 4
isr_modem:
mov edx, [ebx+UART.base]
add edx, MSR_REG
in al, dx
ret
 
 
align 4
divisor dw 2304, 1536, 1047, 857, 768, 384
dw 192, 96, 64, 58, 48, 32
dw 24, 16, 12, 6, 3, 2, 1
 
align 4
uart_func dd 0 ;SRV_GETVERSION
dd 0 ;PORT_OPEN
dd uart_close ;PORT_CLOSE
dd uart_reset ;PORT_RESET
dd uart_set_mode ;PORT_SETMODE
dd 0 ;PORT_GETMODE
dd uart_set_mcr ;PORT_SETMODEM
dd 0 ;PORT_GETMODEM
dd uart_read ;PORT_READ
dd uart_write ;PORT_WRITE
 
isr_action dd isr_modem
dd transmit
dd isr_recieve
dd isr_line
 
version dd (5 shl 16) or (UART_VERSION and 0xFFFF)
 
sz_uart_srv db 'UART',0
 
align 4
 
com1 rd 1
com2 rd 1
 
/kernel/branches/Kolibri-acpi/drivers/ensoniq.asm
0,0 → 1,1177
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;alpha version
 
format MS COFF
 
DEBUG equ 1
 
 
include 'proc32.inc'
include 'imports.inc'
 
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
 
 
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 ?
.devfn dd ?
 
.vendor dd ?
.dev_id dd ?
.pci_cmd dd ?
.pci_stat dd ?
 
.codec_io_base dd ?
.codec_mem_base dd ?
 
.ctrl_io_base dd ?
.ctrl_mem_base dd ?
.cfg_reg dd ?
.int_line dd ?
 
.vendor_ids dd ? ;vendor id string
.ctrl_ids dd ? ;hub id string
 
.buffer dd ?
 
.notify_pos dd ?
.notify_task dd ?
 
.lvi_reg dd ?
.ctrl_setup dd ?
.user_callback dd ?
.codec_read16 dd ?
.codec_write16 dd ?
 
.ctrl_read8 dd ?
.ctrl_read16 dd ?
.ctrl_read32 dd ?
 
.ctrl_write8 dd ?
.ctrl_write16 dd ?
.ctrl_write32 dd ?
}
 
struc CODEC ;Audio Chip base class
{
.chip_id dd ?
.flags dd ?
.status dd ?
 
.ac_vendor_ids dd ? ;ac vendor id string
.chip_ids dd ? ;chip model string
 
.shadow_flag dd ?
dd ?
 
.regs dw ? ; codec registers
.reg_master_vol dw ? ;0x02
.reg_aux_out_vol dw ? ;0x04
.reg_mone_vol dw ? ;0x06
.reg_master_tone dw ? ;0x08
.reg_beep_vol dw ? ;0x0A
.reg_phone_vol dw ? ;0x0C
.reg_mic_vol dw ? ;0x0E
.reg_line_in_vol dw ? ;0x10
.reg_cd_vol dw ? ;0x12
.reg_video_vol dw ? ;0x14
.reg_aux_in_vol dw ? ;0x16
.reg_pcm_out_vol dw ? ;0x18
.reg_rec_select dw ? ;0x1A
.reg_rec_gain dw ? ;0x1C
.reg_rec_gain_mic dw ? ;0x1E
.reg_gen dw ? ;0x20
.reg_3d_ctrl dw ? ;0X22
.reg_page dw ? ;0X24
.reg_powerdown dw ? ;0x26
.reg_ext_audio dw ? ;0x28
.reg_ext_st dw ? ;0x2a
.reg_pcm_front_rate dw ? ;0x2c
.reg_pcm_surr_rate dw ? ;0x2e
.reg_lfe_rate dw ? ;0x30
.reg_pcm_in_rate dw ? ;0x32
dw ? ;0x34
.reg_cent_lfe_vol dw ? ;0x36
.reg_surr_vol dw ? ;0x38
.reg_spdif_ctrl dw ? ;0x3A
dw ? ;0x3C
dw ? ;0x3E
dw ? ;0x40
dw ? ;0x42
dw ? ;0x44
dw ? ;0x46
dw ? ;0x48
dw ? ;0x4A
dw ? ;0x4C
dw ? ;0x4E
dw ? ;0x50
dw ? ;0x52
dw ? ;0x54
dw ? ;0x56
dw ? ;0x58
dw ? ;0x5A
dw ? ;0x5C
dw ? ;0x5E
.reg_page_0 dw ? ;0x60
.reg_page_1 dw ? ;0x62
.reg_page_2 dw ? ;0x64
.reg_page_3 dw ? ;0x66
.reg_page_4 dw ? ;0x68
.reg_page_5 dw ? ;0x6A
.reg_page_6 dw ? ;0x6C
.reg_page_7 dw ? ;0x6E
dw ? ;0x70
dw ? ;0x72
dw ? ;0x74
dw ? ;0x76
dw ? ;0x78
dw ? ;0x7A
.reg_vendor_id_1 dw ? ;0x7C
.reg_vendor_id_2 dw ? ;0x7E
 
 
.reset dd ? ;virual
.set_master_vol dd ?
}
 
struc CTRL_INFO
{ .pci_cmd dd ?
.irq dd ?
.glob_cntrl dd ?
.glob_sta dd ?
.codec_io_base dd ?
.ctrl_io_base dd ?
.codec_mem_base dd ?
.ctrl_mem_base dd ?
.codec_id dd ?
}
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
EVENT_NOTIFY equ 0x00000200
 
OS_BASE equ 0x80000000
SLOT_BASE equ OS_BASE+0x0080000
new_app_base equ 0
 
public START
public service_proc
public version
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .stop
 
if DEBUG
mov esi, msgDetect
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
 
jmp .fail ;force 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
 
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, dword 0
stdcall RegService, sz_sound_srv, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
xor eax, eax
ret
.stop:
call stop
xor eax, eax
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edi, [ioctl]
mov eax, [edi+io_code]
cmp eax, DEV_PLAY
jne @F
if DEBUG
mov esi, msgPlay
call SysMsgBoardStr
end if
call play
ret
@@:
cmp eax, DEV_STOP
jne @F
if DEBUG
mov esi, msgStop
call SysMsgBoardStr
end if
call stop
ret
@@:
cmp eax, DEV_CALLBACK
jne @F
mov ebx, [edi+input]
stdcall set_callback, [ebx]
ret
@@:
cmp eax, DEV_SET_MASTERVOL
jne @F
mov eax, [edi+input]
mov eax, [eax]
call set_master_vol ;eax= vol
ret
@@:
cmp eax, DEV_GET_MASTERVOL
jne @F
mov ebx, [edi+output]
stdcall get_master_vol, ebx
ret
;@@:
; cmp eax, DEV_GET_INFO
; jne @F
; mov ebx, [edi+output]
; stdcall get_dev_info, ebx
; ret
@@:
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
 
align 4
proc ac97_irq
 
; if DEBUG
; mov esi, msgIRQ
; call SysMsgBoardStr
; end if
 
 
cmp [ctrl.user_callback], 0
je @f
 
stdcall [ctrl.user_callback], ebx
@@:
ret
 
.skip:
mov edx, PCM_OUT_CR_REG
mov ax, 0x11 ;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
 
mov eax, [ctrl.buffer]
call GetPgAddr
 
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 eax, pcmout_bdl
mov ebx, eax
call GetPgAddr ;eax
and ebx, 0xFFF
add eax, ebx
 
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, 0x1274
jne @F
mov [ctrl.vendor_ids], msgEnsoniq
ret
@@:
mov [ctrl.vendor_ids], 0 ;something wrong ?
ret
.err:
xor eax, eax
ret
endp
 
align 4
proc init_controller
 
mov esi, msgPCIcmd
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
mov ebx, eax
and eax, 0xFFFF
mov [ctrl.pci_cmd], eax
shr ebx, 16
mov [ctrl.pci_stat], ebx
 
call dword2str
call SysMsgBoardStr
 
mov esi, msgIObase
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
; and eax, -16
mov [ctrl.ctrl_io_base], eax
 
call dword2str
call SysMsgBoardStr
 
mov esi, msgIRQline
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
and eax, 0xFF
mov [ctrl.int_line], eax
 
call dword2str
call SysMsgBoardStr
 
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
 
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
 
mov esi, msgControl
call SysMsgBoardStr
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
 
call dword2str
call SysMsgBoardStr
 
test eax, CTRL_ST_CREADY
jnz .ready
 
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
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]
xor eax, eax
ret
 
align 4
stop:
mov edx, PCM_OUT_CR_REG
mov ax, 0x0
call [ctrl.ctrl_write8]
 
mov ax, 0x1c
mov edx, PCM_OUT_SR_REG
call [ctrl.ctrl_write16]
xor eax, eax
ret
 
align 4
proc get_dev_info stdcall, p_info:dword
virtual at esi
CTRL_INFO CTRL_INFO
end virtual
 
mov esi, [p_info]
mov eax, [ctrl.int_line]
mov 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
.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
js @B
 
pop eax
pop ebx
pop edx
pop ecx
ret
endp
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONTROLLER IO functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
codec_io_r16:
add edx, [ctrl.codec_io_base]
in ax, dx
ret
 
align 4
codec_io_w16:
add edx, [ctrl.codec_io_base]
out dx, ax
ret
 
align 4
ctrl_io_r8:
add edx, [ctrl.ctrl_io_base]
in al, dx
ret
 
align 4
ctrl_io_r16:
add edx, [ctrl.ctrl_io_base]
in ax, dx
ret
 
align 4
ctrl_io_r32:
add edx, [ctrl.ctrl_io_base]
in eax, dx
ret
 
align 4
ctrl_io_w8:
add edx, [ctrl.ctrl_io_base]
out dx, al
ret
 
align 4
ctrl_io_w16:
add edx, [ctrl.ctrl_io_base]
out dx, ax
ret
 
align 4
ctrl_io_w32:
add edx, [ctrl.ctrl_io_base]
out dx, eax
ret
 
 
align 4
dword2str:
mov esi, hex_buff
mov ecx, -8
@@:
rol eax, 4
mov ebx, eax
and ebx, 0x0F
mov bl, [ebx+hexletters]
mov [8+esi+ecx], bl
inc ecx
jnz @B
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
 
include "codec.inc"
 
align 4
devices dd (0x5000 shl 16)+0x1274,msgEnsoniq,set_ICH
dd (0x5880 shl 16)+0x1274,msgVibra128,set_ICH
dd 0 ;terminator
 
version dd 0x00040004
 
msgEnsoniq db 'Ensonic 1371',13,10,0
msgVibra128 db 'Sound Blaster AudioPCI Vibra 128',13,10,0
 
sz_sound_srv db 'SOUND',0
 
msgDetect 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
msgStatus db 'global status ',0
msgControl db 'global control ',0
msgPCIcmd db 'PCI command ',0
msgIObase db 'IO base ',0
msgIRQline db 'IRQ line ',0
 
section '.data' data readable writable align 16
 
pcmout_bdl rq 32
buff_list rd 32
 
codec CODEC
ctrl AC_CNTRL
 
lpc_bus rd 1
civ_val rd 1
 
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/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 }
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/sceletone.asm
0,0 → 1,177
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;driver sceletone
 
format MS COFF
 
DEBUG equ 1
 
API_VERSION equ 0 ;debug
 
include 'proc32.inc'
include 'imports.inc'
 
OS_BASE equ 0;
new_app_base equ 0x60400000
PROC_BASE equ OS_BASE+0x0080000
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
public START
public service_proc
public version
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
STRIDE equ 4 ;size of row in devices table
 
SRV_GETVERSION equ 0
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .exit
.entry:
 
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
stdcall RegService, my_service, service_proc
ret
.fail:
.exit:
xor eax, eax
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov ebx, [ioctl]
mov eax, [ebx+io_code]
cmp eax, SRV_GETVERSION
jne @F
 
mov eax, [ebx+output]
cmp [ebx+out_size], 4
jne .fail
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
align 4
proc detect
locals
last_bus 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, STRIDE
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:
xor eax, eax
inc eax
ret
.err:
xor eax, eax
ret
endp
 
DEVICE_ID equ 1234; pci device id
VENDOR_ID equ 5678; device vendor id
 
 
;all initialized data place here
 
align 4
devices dd (DEVICE_ID shl 16)+VENDOR_ID
dd 0 ;terminator
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
my_service db 'MY_SERVICE',0 ;max 16 chars include zero
 
msgInit db 'detect hardware...',13,10,0
msgPCI db 'PCI accsess not supported',13,10,0
msgFail db 'device not found',13,10,0
 
section '.data' data readable writable align 16
 
;all uninitialized data place here
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/sis.asm
0,0 → 1,1307
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
format MS COFF
 
 
DEBUG equ 1
 
include 'proc32.inc'
include 'imports.inc'
 
API_VERSION equ 0x01000100
DEBUG_IRQ equ 0
 
USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices
IRQ_REMAP equ 0
IRQ_LINE equ 0
 
 
;irq 0,1,2,8,12,13 íåäîñòóïíû
; FEDCBA9876543210
VALID_IRQ equ 1100111011111000b
ATTCH_IRQ equ 0000111010100000b
 
if USE_COM_IRQ
ATTCH_IRQ equ 0000111010111000b
end if
 
CPU_FREQ equ 2600d
 
BIT0 EQU 0x00000001
BIT1 EQU 0x00000002
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 0x18 ; PCM output volume
CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio
CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control
CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate
CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate
CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate
 
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
 
SRV_GETVERSION equ 0
DEV_PLAY equ 1
DEV_STOP equ 2
DEV_CALLBACK equ 3
DEV_SET_BUFF equ 4
DEV_NOTIFY equ 5
DEV_SET_MASTERVOL equ 6
DEV_GET_MASTERVOL equ 7
DEV_GET_INFO equ 8
 
struc AC_CNTRL ;AC controller base class
{ .bus dd ?
.devfn dd ?
 
.vendor dd ?
.dev_id dd ?
.pci_cmd dd ?
.pci_stat dd ?
 
.codec_io_base dd ?
.codec_mem_base dd ?
 
.ctrl_io_base dd ?
.ctrl_mem_base dd ?
.cfg_reg dd ?
.int_line dd ?
 
.vendor_ids dd ? ;vendor id string
.ctrl_ids dd ? ;hub id string
 
.buffer dd ?
 
.notify_pos dd ?
.notify_task dd ?
 
.lvi_reg dd ?
.ctrl_setup dd ?
.user_callback dd ?
.codec_read16 dd ?
.codec_write16 dd ?
 
.ctrl_read8 dd ?
.ctrl_read16 dd ?
.ctrl_read32 dd ?
 
.ctrl_write8 dd ?
.ctrl_write16 dd ?
.ctrl_write32 dd ?
}
 
struc CODEC ;Audio Chip base class
{
.chip_id dd ?
.flags dd ?
.status dd ?
 
.ac_vendor_ids dd ? ;ac vendor id string
.chip_ids dd ? ;chip model string
 
.shadow_flag dd ?
dd ?
 
.regs dw ? ; codec registers
.reg_master_vol dw ? ;0x02
.reg_aux_out_vol dw ? ;0x04
.reg_mone_vol dw ? ;0x06
.reg_master_tone dw ? ;0x08
.reg_beep_vol dw ? ;0x0A
.reg_phone_vol dw ? ;0x0C
.reg_mic_vol dw ? ;0x0E
.reg_line_in_vol dw ? ;0x10
.reg_cd_vol dw ? ;0x12
.reg_video_vol dw ? ;0x14
.reg_aux_in_vol dw ? ;0x16
.reg_pcm_out_vol dw ? ;0x18
.reg_rec_select dw ? ;0x1A
.reg_rec_gain dw ? ;0x1C
.reg_rec_gain_mic dw ? ;0x1E
.reg_gen dw ? ;0x20
.reg_3d_ctrl dw ? ;0X22
.reg_page dw ? ;0X24
.reg_powerdown dw ? ;0x26
.reg_ext_audio dw ? ;0x28
.reg_ext_st dw ? ;0x2a
.reg_pcm_front_rate dw ? ;0x2c
.reg_pcm_surr_rate dw ? ;0x2e
.reg_lfe_rate dw ? ;0x30
.reg_pcm_in_rate dw ? ;0x32
dw ? ;0x34
.reg_cent_lfe_vol dw ? ;0x36
.reg_surr_vol dw ? ;0x38
.reg_spdif_ctrl dw ? ;0x3A
dw ? ;0x3C
dw ? ;0x3E
dw ? ;0x40
dw ? ;0x42
dw ? ;0x44
dw ? ;0x46
dw ? ;0x48
dw ? ;0x4A
dw ? ;0x4C
dw ? ;0x4E
dw ? ;0x50
dw ? ;0x52
dw ? ;0x54
dw ? ;0x56
dw ? ;0x58
dw ? ;0x5A
dw ? ;0x5C
dw ? ;0x5E
.reg_page_0 dw ? ;0x60
.reg_page_1 dw ? ;0x62
.reg_page_2 dw ? ;0x64
.reg_page_3 dw ? ;0x66
.reg_page_4 dw ? ;0x68
.reg_page_5 dw ? ;0x6A
.reg_page_6 dw ? ;0x6C
.reg_page_7 dw ? ;0x6E
dw ? ;0x70
dw ? ;0x72
dw ? ;0x74
dw ? ;0x76
dw ? ;0x78
dw ? ;0x7A
.reg_vendor_id_1 dw ? ;0x7C
.reg_vendor_id_2 dw ? ;0x7E
 
 
.reset dd ? ;virual
.set_master_vol dd ?
}
 
struc CTRL_INFO
{ .pci_cmd dd ?
.irq dd ?
.glob_cntrl dd ?
.glob_sta dd ?
.codec_io_base dd ?
.ctrl_io_base dd ?
.codec_mem_base dd ?
.ctrl_mem_base dd ?
.codec_id dd ?
}
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
EVENT_NOTIFY equ 0x00000200
 
public START
public service_proc
public version
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .stop
 
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
call detect_controller
test eax, eax
jz .fail
 
if DEBUG
mov esi,[ctrl.vendor_ids]
call SysMsgBoardStr
mov esi, [ctrl.ctrl_ids]
call SysMsgBoardStr
 
end if
 
call init_controller
test eax, eax
jz .fail
 
call init_codec
test eax, eax
jz .fail
 
call reset_controller
call setup_codec
 
mov esi, msgPrimBuff
call SysMsgBoardStr
call create_primary_buff
mov esi, msgDone
call SysMsgBoardStr
 
if IRQ_REMAP
pushf
cli
 
mov ebx, [ctrl.int_line]
in al, 0xA1
mov ah, al
in al, 0x21
test ebx, ebx
jz .skip
bts ax, bx ;mask old line
.skip
bts ax, IRQ_LINE ;mask new ine
out 0x21, al
mov al, ah
out 0xA1, al
;remap IRQ
stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE
 
mov dx, 0x4d0 ;8259 ELCR1
in al, dx
bts ax, IRQ_LINE
out dx, al ;set level-triggered mode
mov [ctrl.int_line], IRQ_LINE
popf
mov esi, msgRemap
call SysMsgBoardStr
end if
 
mov eax, VALID_IRQ
mov ebx, [ctrl.int_line]
mov esi, msgInvIRQ
bt eax, ebx
jnc .fail_msg
mov eax, ATTCH_IRQ
mov esi, msgAttchIRQ
bt eax, ebx
jnc .fail_msg
 
stdcall AttachIntHandler, ebx, ac97_irq, dword 0
.reg:
stdcall RegService, sz_sound_srv, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
xor eax, eax
ret
.fail_msg:
call SysMsgBoardStr
xor eax, eax
ret
.stop:
call stop
xor eax, eax
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edi, [ioctl]
mov eax, [edi+io_code]
 
cmp eax, SRV_GETVERSION
jne @F
 
mov eax, [edi+output]
cmp [edi+out_size], 4
jne .fail
 
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
cmp eax, DEV_PLAY
jne @F
if DEBUG
mov esi, msgPlay
call SysMsgBoardStr
end if
call play
ret
@@:
cmp eax, DEV_STOP
jne @F
if DEBUG
mov esi, msgStop
call SysMsgBoardStr
end if
call stop
ret
@@:
cmp eax, DEV_CALLBACK
jne @F
mov ebx, [edi+input]
stdcall set_callback, [ebx]
ret
@@:
cmp eax, DEV_SET_MASTERVOL
jne @F
mov eax, [edi+input]
mov eax, [eax]
call set_master_vol ;eax= vol
ret
@@:
cmp eax, DEV_GET_MASTERVOL
jne @F
mov ebx, [edi+output]
stdcall get_master_vol, ebx
ret
;@@:
; cmp eax, DEV_GET_INFO
; jne @F
; mov ebx, [edi+output]
; stdcall get_dev_info, ebx
; ret
@@:
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
align 4
proc ac97_irq
 
if DEBUG_IRQ
mov esi, msgIRQ
call SysMsgBoardStr
end if
 
mov edx, PCM_OUT_CR_REG
mov al, 0x10
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, 0x11
call [ctrl.ctrl_write8]
 
mov eax, [civ_val]
add eax, 1
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, 0x11
call [ctrl.ctrl_write8]
ret
endp
 
align 4
proc create_primary_buff
 
stdcall KernelAlloc, 0x10000
mov [ctrl.buffer], eax
 
mov edi, eax
mov ecx, 0x10000/4
xor eax, eax
cld
rep stosd
 
mov eax, [ctrl.buffer]
call GetPgAddr
 
mov 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 eax, pcmout_bdl
mov ebx, eax
call GetPgAddr ;eax
and ebx, 0xFFF
add eax, ebx
 
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
 
mov esi, msgPciCmd
call SysMsgBoardStr
call dword2str
call SysMsgBoardStr
 
mov esi, msgPciStat
call SysMsgBoardStr
mov eax, [ctrl.pci_stat]
call dword2str
call SysMsgBoardStr
 
mov esi, msgMixIsaIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
 
call dword2str
call SysMsgBoardStr
 
and eax,0xFFFE
mov [ctrl.codec_io_base], eax
 
mov esi, msgCtrlIsaIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14
 
call dword2str
call SysMsgBoardStr
 
and eax, 0xFFC0
mov [ctrl.ctrl_io_base], eax
 
mov esi, msgMixMMIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18
mov [ctrl.codec_mem_base], eax
 
call dword2str
call SysMsgBoardStr
 
mov esi, msgCtrlMMIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C
mov [ctrl.ctrl_mem_base], eax
 
call dword2str
call SysMsgBoardStr
.default:
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
 
mov esi, msgControl
call SysMsgBoardStr
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
push eax
call dword2str
call SysMsgBoardStr
pop eax
cmp eax, 0xFFFFFFFF
je .err
 
test eax, CTRL_ST_CREADY
jnz .done ;;;;;.ready
 
call reset_codec
test eax, eax
jz .err
 
.ready:
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 eax, 5000 ; wait 5 ms
call StallExec
 
mov edx, CODEC_REG_POWERDOWN
call [ctrl.codec_read16]
and eax, 0x0F
cmp eax, 0x0F
je .done
 
sub [counter] , 1
jnz .wait
.err:
xor eax, eax ; timeout error
ret
.done:
mov eax, 2 ;force set 16-bit 2-channel PCM
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
mov eax, 5000 ; wait 5 ms
call StallExec
 
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, CTRL_STAT
call [ctrl.ctrl_read32]
test eax, CTRL_ST_CREADY
jnz .ok
 
dec [counter]
jnz .wait
 
if DEBUG
mov esi, msgWRFail
call SysMsgBoardStr
end if
.fail:
stc
ret
.ok:
clc
ret
endp
 
align 4
proc cold_reset
locals
counter dd ?
endl
 
mov eax, 0x02
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
 
if DEBUG
mov esi, msgCold
call SysMsgBoardStr
end if
 
mov eax, 400000 ; wait 400 ms
call StallExec
 
mov [counter], 16 ; total 20*100 ms = 2s
.wait:
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
test eax, CTRL_ST_CREADY
jnz .ok
 
mov eax, 100000 ; wait 100 ms
call StallExec
 
dec [counter]
jnz .wait
 
if DEBUG
mov esi, msgCRFail
call SysMsgBoardStr
end if
 
.fail:
stc
ret
.ok:
mov esi, msgControl
call SysMsgBoardStr
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
push eax
call dword2str
call SysMsgBoardStr
pop eax
 
test eax, CTRL_ST_CREADY
jz .fail
clc
ret
endp
 
align 4
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]
xor eax, eax
ret
 
align 4
stop:
mov edx, PCM_OUT_CR_REG
mov ax, 0x0
call [ctrl.ctrl_write8]
 
mov ax, 0x1c
mov edx, PCM_OUT_SR_REG
call [ctrl.ctrl_write16]
xor eax, eax
ret
 
align 4
proc get_dev_info stdcall, p_info:dword
virtual at esi
CTRL_INFO CTRL_INFO
end virtual
 
mov esi, [p_info]
mov eax, [ctrl.int_line]
mov 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
.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
js @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
 
align 4
dword2str:
mov esi, hex_buff
mov ecx, -8
@@:
rol eax, 4
mov ebx, eax
and ebx, 0x0F
mov bl, [ebx+hexletters]
mov [8+esi+ecx], bl
inc ecx
jnz @B
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
include "codec.inc"
 
align 4
devices dd (CTRL_SIS shl 16)+VID_SIS,msg_AC, set_SIS
dd 0
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
msg_AC db '7012 AC97 controller',13,10, 0
msg_SIS db 'Silicon Integrated Systems',13,10, 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 ...',0
msgDone db 'done',13,10,0
msgRemap db 'Remap IRQ',13,10,0
;msgReg db 'set service handler',13,10,0
msgOk db 'service installed',13,10,0
msgCold db 'cold reset',13,10,0
msgWarm db 'warm reset',13,10,0
msgWRFail db 'warm reset failed',13,10,0
msgCRFail db 'cold reset failed',13,10,0
msgCFail db 'codec not ready',13,10,0
msgResetOk db 'reset complete',13,10,0
msgStatus db 'global status ',0
msgControl db 'global control ',0
msgPciCmd db 'PCI command ',0
msgPciStat db 'PCI status ',0
msgCtrlIsaIo db 'controller io base ',0
msgMixIsaIo db 'codec io base ',0
msgCtrlMMIo db 'controller mmio base ',0
msgMixMMIo db 'codec mmio base ',0
msgIrqMap db 'AC97 irq map as ',0
 
section '.data' data readable writable align 16
 
pcmout_bdl rq 32
buff_list rd 32
 
codec CODEC
ctrl AC_CNTRL
 
lpc_bus rd 1
civ_val rd 1
/kernel/branches/Kolibri-acpi/drivers/sound.asm
0,0 → 1,1473
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
format MS COFF
 
DEBUG equ 1
 
include 'proc32.inc'
include 'imports.inc'
 
API_VERSION equ 0x01000100
 
DEBUG_IRQ equ 0
 
USE_COM_IRQ equ 0 ;make irq 3 and irq 4 available for PCI devices
IRQ_REMAP equ 0
IRQ_LINE equ 0
 
 
;irq 0,1,2,8,12,13 íåäîñòóïíû
; FEDCBA9876543210
VALID_IRQ equ 1100111011111000b
ATTCH_IRQ equ 0000111010100000b
 
if USE_COM_IRQ
ATTCH_IRQ equ 0000111010111000b
end if
 
CPU_FREQ equ 2600d
 
BIT0 EQU 0x00000001
BIT1 EQU 0x00000002
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
 
PCM_4 equ BIT20
PCM_6 equ BIT21
 
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
CTRL_MCP04 equ 0x003A
CTRL_CK804 equ 0x0059
CTRL_CK8 equ 0x008A
CTRL_CK8S equ 0x00EA
CTRL_MCP51 equ 0x026B
 
 
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 0x18 ; PCM output volume
CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio
CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control
CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate
CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate
CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate
 
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
 
SRV_GETVERSION equ 0
DEV_PLAY equ 1
DEV_STOP equ 2
DEV_CALLBACK equ 3
DEV_SET_BUFF equ 4
DEV_NOTIFY equ 5
DEV_SET_MASTERVOL equ 6
DEV_GET_MASTERVOL equ 7
DEV_GET_INFO equ 8
 
struc AC_CNTRL ;AC controller base class
{ .bus dd ?
.devfn dd ?
 
.vendor dd ?
.dev_id dd ?
.pci_cmd dd ?
.pci_stat dd ?
 
.codec_io_base dd ?
.codec_mem_base dd ?
 
.ctrl_io_base dd ?
.ctrl_mem_base dd ?
.cfg_reg dd ?
.int_line dd ?
 
.vendor_ids dd ? ;vendor id string
.ctrl_ids dd ? ;hub id string
 
.buffer dd ?
 
.notify_pos dd ?
.notify_task dd ?
 
.lvi_reg dd ?
.ctrl_setup dd ?
.user_callback dd ?
.codec_read16 dd ?
.codec_write16 dd ?
 
.ctrl_read8 dd ?
.ctrl_read16 dd ?
.ctrl_read32 dd ?
 
.ctrl_write8 dd ?
.ctrl_write16 dd ?
.ctrl_write32 dd ?
}
 
struc CODEC ;Audio Chip base class
{
.chip_id dd ?
.flags dd ?
.status dd ?
 
.ac_vendor_ids dd ? ;ac vendor id string
.chip_ids dd ? ;chip model string
 
.shadow_flag dd ?
dd ?
 
.regs dw ? ; codec registers
.reg_master_vol dw ? ;0x02
.reg_aux_out_vol dw ? ;0x04
.reg_mone_vol dw ? ;0x06
.reg_master_tone dw ? ;0x08
.reg_beep_vol dw ? ;0x0A
.reg_phone_vol dw ? ;0x0C
.reg_mic_vol dw ? ;0x0E
.reg_line_in_vol dw ? ;0x10
.reg_cd_vol dw ? ;0x12
.reg_video_vol dw ? ;0x14
.reg_aux_in_vol dw ? ;0x16
.reg_pcm_out_vol dw ? ;0x18
.reg_rec_select dw ? ;0x1A
.reg_rec_gain dw ? ;0x1C
.reg_rec_gain_mic dw ? ;0x1E
.reg_gen dw ? ;0x20
.reg_3d_ctrl dw ? ;0X22
.reg_page dw ? ;0X24
.reg_powerdown dw ? ;0x26
.reg_ext_audio dw ? ;0x28
.reg_ext_st dw ? ;0x2a
.reg_pcm_front_rate dw ? ;0x2c
.reg_pcm_surr_rate dw ? ;0x2e
.reg_lfe_rate dw ? ;0x30
.reg_pcm_in_rate dw ? ;0x32
dw ? ;0x34
.reg_cent_lfe_vol dw ? ;0x36
.reg_surr_vol dw ? ;0x38
.reg_spdif_ctrl dw ? ;0x3A
dw ? ;0x3C
dw ? ;0x3E
dw ? ;0x40
dw ? ;0x42
dw ? ;0x44
dw ? ;0x46
dw ? ;0x48
dw ? ;0x4A
dw ? ;0x4C
dw ? ;0x4E
dw ? ;0x50
dw ? ;0x52
dw ? ;0x54
dw ? ;0x56
dw ? ;0x58
dw ? ;0x5A
dw ? ;0x5C
dw ? ;0x5E
.reg_page_0 dw ? ;0x60
.reg_page_1 dw ? ;0x62
.reg_page_2 dw ? ;0x64
.reg_page_3 dw ? ;0x66
.reg_page_4 dw ? ;0x68
.reg_page_5 dw ? ;0x6A
.reg_page_6 dw ? ;0x6C
.reg_page_7 dw ? ;0x6E
dw ? ;0x70
dw ? ;0x72
dw ? ;0x74
dw ? ;0x76
dw ? ;0x78
dw ? ;0x7A
.reg_vendor_id_1 dw ? ;0x7C
.reg_vendor_id_2 dw ? ;0x7E
 
 
.reset dd ? ;virual
.set_master_vol dd ?
}
 
struc CTRL_INFO
{ .pci_cmd dd ?
.irq dd ?
.glob_cntrl dd ?
.glob_sta dd ?
.codec_io_base dd ?
.ctrl_io_base dd ?
.codec_mem_base dd ?
.ctrl_mem_base dd ?
.codec_id dd ?
}
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
EVENT_NOTIFY equ 0x00000200
 
public START
public service_proc
public version
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .stop
 
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
call detect_controller
test eax, eax
jz .fail
 
if DEBUG
mov esi,[ctrl.vendor_ids]
call SysMsgBoardStr
mov esi, [ctrl.ctrl_ids]
call SysMsgBoardStr
 
end if
 
call init_controller
test eax, eax
jz .fail
 
call init_codec
test eax, eax
jz .fail
 
call reset_controller
call setup_codec
 
mov esi, msgPrimBuff
call SysMsgBoardStr
call create_primary_buff
mov esi, msgDone
call SysMsgBoardStr
 
if IRQ_REMAP
pushf
cli
 
mov ebx, [ctrl.int_line]
in al, 0xA1
mov ah, al
in al, 0x21
test ebx, ebx
jz .skip
bts ax, bx ;mask old line
.skip
bts ax, IRQ_LINE ;mask new ine
out 0x21, al
mov al, ah
out 0xA1, al
;remap IRQ
stdcall PciWrite8, 0, 0xF8, 0x61, IRQ_LINE
 
mov dx, 0x4d0 ;8259 ELCR1
in al, dx
bts ax, IRQ_LINE
out dx, al ;set level-triggered mode
mov [ctrl.int_line], IRQ_LINE
popf
mov esi, msgRemap
call SysMsgBoardStr
end if
 
mov eax, VALID_IRQ
mov ebx, [ctrl.int_line]
mov esi, msgInvIRQ
bt eax, ebx
jnc .fail_msg
mov eax, ATTCH_IRQ
mov esi, msgAttchIRQ
bt eax, ebx
jnc .fail_msg
 
stdcall AttachIntHandler, ebx, ac97_irq, dword 0
.reg:
stdcall RegService, sz_sound_srv, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
xor eax, eax
ret
.fail_msg:
call SysMsgBoardStr
xor eax, eax
ret
.stop:
call stop
xor eax, eax
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edi, [ioctl]
mov eax, [edi+io_code]
 
cmp eax, SRV_GETVERSION
jne @F
 
mov eax, [edi+output]
cmp [edi+out_size], 4
jne .fail
 
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
cmp eax, DEV_PLAY
jne @F
if DEBUG
mov esi, msgPlay
call SysMsgBoardStr
end if
call play
ret
@@:
cmp eax, DEV_STOP
jne @F
if DEBUG
mov esi, msgStop
call SysMsgBoardStr
end if
call stop
ret
@@:
cmp eax, DEV_CALLBACK
jne @F
mov ebx, [edi+input]
stdcall set_callback, [ebx]
ret
@@:
cmp eax, DEV_SET_MASTERVOL
jne @F
mov eax, [edi+input]
mov eax, [eax]
call set_master_vol ;eax= vol
ret
@@:
cmp eax, DEV_GET_MASTERVOL
jne @F
mov ebx, [edi+output]
stdcall get_master_vol, ebx
ret
;@@:
; cmp eax, DEV_GET_INFO
; jne @F
; mov ebx, [edi+output]
; stdcall get_dev_info, ebx
; ret
@@:
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
align 4
proc ac97_irq
 
if DEBUG_IRQ
mov esi, msgIRQ
call SysMsgBoardStr
end if
 
mov edx, PCM_OUT_CR_REG
mov al, 0x10; 0x10
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, 0x11 ;0x1D
call [ctrl.ctrl_write8]
 
mov eax, [civ_val]
add eax, 1
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, 0x11 ;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
 
mov eax, [ctrl.buffer]
call GetPgAddr
 
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 eax, pcmout_bdl
mov ebx, eax
call GetPgAddr ;eax
and ebx, 0xFFF
add eax, ebx
 
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 edx, VID_INTEL
jne @F
mov [ctrl.vendor_ids], msg_Intel
ret
@@:
cmp edx, VID_NVIDIA
jne @F
mov [ctrl.vendor_ids], msg_NVidia
ret
@@:
.err:
xor eax, eax
mov [ctrl.vendor_ids], eax ;something wrong ?
ret
endp
 
align 4
proc init_controller
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
mov ebx, eax
and eax, 0xFFFF
mov [ctrl.pci_cmd], eax
shr ebx, 16
mov [ctrl.pci_stat], ebx
 
mov esi, msgPciCmd
call SysMsgBoardStr
call dword2str
call SysMsgBoardStr
 
mov esi, msgPciStat
call SysMsgBoardStr
mov eax, [ctrl.pci_stat]
call dword2str
call SysMsgBoardStr
 
mov esi, msgMixIsaIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
 
call dword2str
call SysMsgBoardStr
 
and eax,0xFFFE
mov [ctrl.codec_io_base], eax
 
mov esi, msgCtrlIsaIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14
 
call dword2str
call SysMsgBoardStr
 
and eax, 0xFFC0
mov [ctrl.ctrl_io_base], eax
 
mov esi, msgMixMMIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18
mov [ctrl.codec_mem_base], eax
 
call dword2str
call SysMsgBoardStr
 
mov esi, msgCtrlMMIo
call SysMsgBoardStr
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C
mov [ctrl.ctrl_mem_base], eax
 
call dword2str
call SysMsgBoardStr
 
if 0
 
;;patch for some ugly BIOS ICH-ICH5 compatible
cmp [ctrl.vendor], VID_INTEL
jne .default
 
mov esi, msgIrqMap
call SysMsgBoardStr
stdcall PciRead8, 0, 0xF8, 0x61
and eax, 0xFF
call dword2str
call SysMsgBoardStr
btr eax, 7 ;when bit 7 set remap disabled
jnc @F
xor eax, eax
jmp @F
end if
 
.default:
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 MapIoMem,[ctrl.codec_mem_base],0x1000,PG_SW+PG_NOCACHE
mov [ctrl.codec_mem_base], eax
 
stdcall MapIoMem,[ctrl.ctrl_mem_base],0x1000,PG_SW+PG_NOCACHE
mov [ctrl.ctrl_mem_base], eax
 
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
 
mov esi, msgControl
call SysMsgBoardStr
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
push eax
call dword2str
call SysMsgBoardStr
pop eax
cmp eax, 0xFFFFFFFF
je .err
 
test eax, CTRL_ST_CREADY
jnz .ready
 
call reset_codec
test eax, eax
jz .err
 
.ready:
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 eax, 5000 ; wait 5 ms
call StallExec
 
mov edx, CODEC_REG_POWERDOWN
call [ctrl.codec_read16]
and eax, 0x0F
cmp eax, 0x0F
jz .done
 
sub [counter] , 1
jnz .wait
.err:
xor eax, eax ; timeout error
ret
.done:
mov eax, 2 ;force set 16-bit 2-channel PCM
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
mov eax, 5000 ; wait 5 ms
call StallExec
 
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, CTRL_STAT
call [ctrl.ctrl_read32]
test eax, CTRL_ST_CREADY
jnz .ok
 
dec [counter]
jnz .wait
 
if DEBUG
mov esi, msgWRFail
call SysMsgBoardStr
end if
.fail:
stc
ret
.ok:
clc
ret
endp
 
align 4
proc cold_reset
locals
counter dd ?
endl
 
mov eax, 0x02
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
 
if DEBUG
mov esi, msgCold
call SysMsgBoardStr
end if
 
mov eax, 400000 ; wait 400 ms
call StallExec
 
mov [counter], 16 ; total 20*100 ms = 2s
.wait:
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
test eax, CTRL_ST_CREADY
jnz .ok
 
mov eax, 100000 ; wait 100 ms
call StallExec
 
dec [counter]
jnz .wait
 
if DEBUG
mov esi, msgCRFail
call SysMsgBoardStr
end if
 
.fail:
stc
ret
.ok:
mov esi, msgControl
call SysMsgBoardStr
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
call dword2str
call SysMsgBoardStr
 
mov esi, msgStatus
call SysMsgBoardStr
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
push eax
call dword2str
call SysMsgBoardStr
pop eax
 
test eax, CTRL_ST_CREADY
jz .fail
clc
ret
endp
 
align 4
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]
xor eax, eax
ret
 
align 4
stop:
mov edx, PCM_OUT_CR_REG
mov ax, 0x0
call [ctrl.ctrl_write8]
 
mov ax, 0x1c
mov edx, PCM_OUT_SR_REG
call [ctrl.ctrl_write16]
xor eax, eax
ret
 
align 4
proc get_dev_info stdcall, p_info:dword
virtual at esi
CTRL_INFO CTRL_INFO
end virtual
 
mov esi, [p_info]
mov eax, [ctrl.int_line]
mov 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
.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
js @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
 
align 4
dword2str:
mov esi, hex_buff
mov ecx, -8
@@:
rol eax, 4
mov ebx, eax
and ebx, 0x0F
mov bl, [ebx+hexletters]
mov [8+esi+ecx], bl
inc ecx
jnz @B
ret
 
hexletters db '0123456789ABCDEF'
hex_buff db 8 dup(0),13,10,0
 
 
include "codec.inc"
 
align 4
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 (CTRL_MCP04 shl 16)+VID_NVIDIA,msg_MCP04,set_ICH
dd (CTRL_CK804 shl 16)+VID_NVIDIA,msg_CK804,set_ICH
dd (CTRL_CK8 shl 16)+VID_NVIDIA,msg_CK8,set_ICH
dd (CTRL_CK8S shl 16)+VID_NVIDIA,msg_CK8S,set_ICH
dd (CTRL_MCP51 shl 16)+VID_NVIDIA,msg_MCP51,set_ICH
 
dd 0 ;terminator
 
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
msg_ICH db '802801AA (ICH)', 13,10, 0
msg_ICH0 db '802801AB (ICH0)', 13,10, 0
msg_ICH2 db '802801BA (ICH2)', 13,10, 0
msg_ICH3 db '802801CA (ICH3)', 13,10, 0
msg_ICH4 db '802801DB (ICH4)', 13,10, 0
msg_ICH5 db '802801EB (ICH5)', 13,10, 0
msg_ICH6 db '802801FB (ICH6)', 13,10, 0
msg_ICH7 db '802801GB (ICH7)', 13,10, 0
msg_Intel db 'Intel ', 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_MCP04 db 'NForce MCP04',13,10, 0
msg_CK804 db 'NForce CK804',13,10, 0
msg_CK8 db 'NForce CK8', 13,10, 0
msg_CK8S db 'NForce CK8S', 13,10, 0
msg_MCP51 db 'NForce MCP51',13,10, 0
 
msg_NVidia db 'NVidia', 0
 
szKernel db 'KERNEL', 0
sz_sound_srv db 'SOUND',0
 
msgInit db 'detect hardware...',13,10,0
msgFail db 'device not found',13,10,0
msgAttchIRQ db 'IRQ line not supported', 13,10, 0
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0
msgPlay db 'start play', 13,10,0
msgStop db 'stop play', 13,10,0
;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 ...',0
msgDone db 'done',13,10,0
msgRemap db 'Remap IRQ',13,10,0
;msgReg db 'set service handler',13,10,0
msgOk db 'service installed',13,10,0
msgCold db 'cold reset',13,10,0
msgWarm db 'warm reset',13,10,0
msgWRFail db 'warm reset failed',13,10,0
msgCRFail db 'cold reset failed',13,10,0
msgCFail db 'codec not ready',13,10,0
msgResetOk db 'reset complete',13,10,0
msgStatus db 'global status ',0
msgControl db 'global control ',0
msgPciCmd db 'PCI command ',0
msgPciStat db 'PCI status ',0
msgCtrlIsaIo db 'controller io base ',0
msgMixIsaIo db 'codec io base ',0
msgCtrlMMIo db 'controller mmio base ',0
msgMixMMIo db 'codec mmio base ',0
msgIrqMap db 'AC97 irq map as ',0
 
section '.data' data readable writable align 16
 
pcmout_bdl rq 32
buff_list rd 32
 
codec CODEC
ctrl AC_CNTRL
 
lpc_bus rd 1
civ_val rd 1
/kernel/branches/Kolibri-acpi/drivers/main.inc
0,0 → 1,164
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2006-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; Serge 2006-2008
; email: infinity_sound@mail.ru
 
 
PLAY_SYNC equ 0x80000000
 
PCM_ALL equ 0
 
PCM_OUT equ 0x08000000
PCM_RING equ 0x10000000
PCM_STATIC equ 0x20000000
PCM_FLOAT equ 0x40000000 ;reserved
PCM_FILTER equ 0x80000000 ;reserved
 
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_16_8 equ 17
PCM_1_16_8 equ 18
 
PCM_2_8_48 equ 19
PCM_1_8_48 equ 20
 
PCM_2_8_44 equ 21
PCM_1_8_44 equ 22
 
PCM_2_8_32 equ 23
PCM_1_8_32 equ 24
 
PCM_2_8_24 equ 25
PCM_1_8_24 equ 26
 
PCM_2_8_22 equ 27
PCM_1_8_22 equ 28
 
PCM_2_8_16 equ 29
PCM_1_8_16 equ 30
 
PCM_2_8_12 equ 31
PCM_1_8_12 equ 32
 
PCM_2_8_11 equ 33
PCM_1_8_11 equ 34
 
PCM_2_8_8 equ 35
PCM_1_8_8 equ 36
 
SRV_GETVERSION equ 0
SND_CREATE_BUFF equ 1
SND_DESTROY_BUFF equ 2
SND_SETFORMAT equ 3
SND_GETFORMAT equ 4
SND_RESET equ 5
SND_SETPOS equ 6
SND_GETPOS equ 7
SND_SETBUFF equ 8
SND_OUT equ 9
SND_PLAY equ 10
SND_STOP equ 11
SND_SETVOLUME equ 12
SND_GETVOLUME equ 13
SND_SETPAN equ 14
SND_GETPAN equ 15
SND_GETBUFFSIZE equ 16
SND_GETFREESPACE equ 17
 
struc STREAM
{
.magic dd ? ;'WAVE'
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
 
.size dd ?
.str_fd dd ?
.str_bk dd ?
.device dd ?
.format dd ?
.flags dd ?
 
.out_base dd ?
.out_wp dd ?
.out_rp dd ?
.out_count dd ?
.out_top dd ? ;16*4
 
.r_size dd ?
.r_dt dd ?
.r_silence dd ?
.resample dd ?
.l_vol dd ?
.r_vol dd ?
.l_amp dw ?
.r_amp dw ?
.pan dd ?
.l_amp_f dd ? ;float point left
.r_amp_f dd ? ;float point right
 
.in_base dd ?
.in_size dd ?
.in_wp dd ?
.in_rp dd ?
.in_count dd ?
.in_free dd ?
.in_top dd ?
 
.notify_event dd ?
.notify_id dd ?
}
 
STREAM_SIZE equ 36*4
FD_OFFSET equ 24
 
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 ?
}
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/vmode.asm
0,0 → 1,736
;
; MenuetOS Driver (vmode.mdr)
; Target: Vertical Refresh Rate programming and videomode changing
;
; Author: Trans <<<<<13>>>>>
; Date: 20.07.2003
;
; Version: 1.0
; OS: MenuetOS
; Compiler: FASM
;
 
OS_BASE equ 0x80000000
 
use32
 
macro align value { rb (value-1) - ($ + value-1) mod value }
 
org OS_BASE+0x0328000
 
headerstart=$
 
mdid db 'MDAZ' ; 4 byte id
mdhver dd 0x00 ; header version
mdcode dd MDSTART ; start of code
mdver dd 0x00000001 ; driver version (subversion*65536+version)
mdname db 'Trans VideoDriver' ; 32 bytes of full driver name
times (32-($-mdname)) db ' ' ;
 
headerlen=$-headerstart
times (256-headerlen) db 0 ; reserved area for future
 
MDSTART: ; start of driver code ( base_adr+256 bytes)
; ebx(=ecx in program):
; 1 - Get DriverInfo and Driver Initial Set
; 2 - Get Current Video Mode With Vertical Refresh Rate
; 3 - Change Video Mode
; 4 - Return at Start System Video Mode
; 5 - Change vertical and horizontal size of visible screen area
; 6 - Change Vert/Hor position visible area on screen (not complete yet)
;
; MAXF - ...
MAXF=5
 
;-------Main Manager-------------
pushad
cmp ebx,1
jb mdvm_00
cmp ebx,MAXF
ja mdvm_00
shl ebx,2
add ebx,mdvm_func_table
call dword [ebx]
mov [esp+28],eax
mov [esp+24],ecx
mov [esp+20],edx
mov [esp+16],ebx
popad
retn
mdvm_00:
popad
xor eax,eax
dec eax
retn
 
; ------Drivers Functions----------
 
align 4
 
; EBX=1 (in applications ECX=1)- Get DriverInfo and Driver Initial Set
;
; IN: ecx (in app. edx) - pointer to 512-bytes info area in application
; OUT:
;
vm_info_init:
push ecx
cmp [mdrvm],dword 0
jnz .vmii_00
call vm_safe_reg
call vm_get_initial_videomode
mov eax,[initvm]
mov [currvm],eax
call vm_search_sys_func_table
call vm_get_cur_vert_rate
mov [initrr],eax
call vm_calc_pixelclock
call vm_calc_refrate
inc [mdrvm]
.vmii_00:
pop ecx
call vm_transfer_drv_info
mov ebx,dword [refrate]
mov eax,dword [mdid] ;dword [systlb]
retn
 
 
align 4
 
; EBX=2 (in applications ECX=2)- Get Current Video Mode
;
; OUT: eax = X_screen*65536+Y_screen
; ebx = current vertical rate
; ecx = current video mode (number)
vm_get_cur_mode:
cmp [mdrvm],dword 0
jz .vmgcm_00
call vm_get_cur_vert_rate
mov eax,[OS_BASE+0FE00h]
mov ebx,[OS_BASE+0FE04h]
shl eax,16
add eax,ebx
add eax,00010001h
mov ebx,[refrate]
mov ecx,[currvm]
retn
.vmgcm_00:
xor eax,eax
dec eax
retn
 
 
align 4
 
; EBX=3 (in applications ECX=3)- Change Video Mode
;
; IN: ecx = VertRate*65536+VideoMode
; OUT: eax = 0 if no error
;
vm_set_video_mode:
cmp [mdrvm],dword 0
jz .vmsvm_00
call vm_set_selected_mode
; xor eax,eax
retn
.vmsvm_00:
xor eax,eax
dec eax
retn
 
 
align 4
 
; EBX=4 (in applications ECX=4)- Return at Start System Video Mode
;
; IN:
; OUT: eax = = 0 if no error
;
vm_restore_init_video_mode:
cmp [mdrvm],dword 0
jz .vmrivm_00
call vm_restore_reg
xor eax,eax
retn
.vmrivm_00:
xor eax,eax
dec eax
retn
 
 
align 4
 
; EBX=5 (in applications ECX=5)- Change vertical and horizontal size
; of visible screen area
; IN: ecx (in app. edx) = 0/1 - -/+ horizontal size on 1 position
; = 2/3 - -/+ vertical size on 1 position (8 pixels)
; ^-^----- not complete yet
; OUT: eax = = 0 if no error
;
vm_change_screen_size:
cmp [mdrvm],dword 0
jz .vmcss_00
cmp cl,1
ja .vmcss_01
mov eax,ecx
call vm_inc_dec_width
xor eax,eax
retn
.vmcss_01:
and ecx,01h
mov eax,ecx
; call vm_inc_dec_high ; not complete yet
xor eax,eax
retn
.vmcss_00:
xor eax,eax
dec eax
retn
 
 
align 4
 
; EBX=6 (in applications ECX=6)- Change Vert/Hor position visible area on screen
;
; IN: ecx (in app. edx) = 0/1 - -/+ horizontal position on 1 point
; = 2/3 - -/+ vertical position on 1 pixel
; ^-^----- not complete yet
; OUT: eax = 0 if no error
;
vm_change_position_screen:
cmp [mdrvm],dword 0
jz .vmcps_00
; ...
xor eax,eax
retn
.vmcps_00:
xor eax,eax
dec eax
retn
 
 
;-----Drivers Subfunctions---------
 
;
; Searching i40 system functions pointer table in kernel area location
;
vm_search_sys_func_table:
push eax ; eax - current value
push ecx ; ecx - will be counter of equevalent value
push edx ; edx - last value
push esi ; esi - current address
xor ecx,ecx
mov esi,OS_BASE+010000h ; Start address of kernel location
lodsd
mov edx,eax
cld
.vmssft_00:
cmp esi,OS_BASE+30000h
ja .vmssft_03
inc ecx
lodsd
cmp edx,eax
mov edx,eax
je .vmssft_00
cmp ecx,128
ja .vmssft_02
.vmssft_01:
xor ecx,ecx
jmp .vmssft_00
.vmssft_02:
cmp edx,0
je .vmssft_01
sub esi,256*4-1
mov [systlb],esi
xor ecx,ecx
.vmssft_03_0:
inc ecx
lodsd
cmp edx,eax
mov edx,eax
jne .vmssft_03_0
mov esi,dword [systlb]
cmp cx,60
jae .vmssft_03
add esi,256*4-4
lodsb
mov edx,eax
jmp .vmssft_01
.vmssft_03:
mov [systlb],esi
pop esi
pop edx
pop ecx
pop eax
retn
 
; IN:
; OUT: eax= vertical rate in Hz
vm_get_cur_vert_rate:
push edx
push ebx
xor eax,eax
mov edx,eax
mov ebx,eax
mov dx,03DAh
.vmgcvt_00:
in al,dx
test al,8
jz .vmgcvt_00
.vmgcvt_01:
in al,dx
test al,8
jnz .vmgcvt_01
mov ebx,edx
rdtsc
mov edx,ebx
mov ebx,eax
.vmgcvt_02:
in al,dx
test al,8
jz .vmgcvt_02
.vmgcvt_03:
in al,dx
test al,8
jnz .vmgcvt_03
rdtsc
sub eax,ebx
mov ebx,eax
mov eax,[OS_BASE+0F600h]
xor edx,edx
div ebx
inc eax
mov [refrate],eax
pop ebx
pop edx
retn
 
vm_calc_pixelclock:
push ebx
push edx
xor eax,eax
mov al,[_00]
add ax,5
shl eax,3
xor ebx,ebx
mov bl,[_06]
mov bh,[_07]
and bh,00100001b
btr bx,13
jnc .vmcpc_00
or bh,2
.vmcpc_00:
xor edx,edx
mul ebx
xor edx,edx
mul [initrr]
mov [pclock],eax
pop edx
pop ebx
retn
 
;
; Safe of initial CRTC state
;
vm_safe_reg:
push edx
push ebx
push ecx
push edi
cli
mov dx,3d4h ; CRTC
mov al,11h
out dx,al
inc dx
in al,dx
and al,7fh
out dx,al ; Clear protection bit
dec dx
xor ecx,ecx
mov cl,19h
xor bl,bl
mov edi,CRTCreg
.vmsr_00:
mov al,bl
out dx,al
inc dx
in al,dx
dec dx
stosb
inc bl
loop .vmsr_00
sti
pop edi
pop ecx
pop ebx
pop edx
retn
 
;
; Restore of initial CRTC state
;
vm_restore_reg:
push eax
push ebx
push edx
push esi
mov eax,[oldX]
mov [OS_BASE+0FE00h],eax
mov eax,[oldY]
mov [OS_BASE+0FE04h],eax
mov dx,03dah
.vmrr_00:
in al,dx
test al,8
jnz .vmrr_00
.vmrr_01:
in al,dx
test al,8
jnz .vmrr_01
cli
mov dx,03c4h
mov ax,0101h
out dx,ax
mov dx,3d4h ; CRTC
mov al,11h
out dx,al
inc dx
in al,dx
and al,7fh ; Clear Protection bit
out dx,al
dec dx
xor ecx,ecx
mov cl,19h
mov esi,CRTCreg
xor bl,bl
.vmrr_02:
lodsb
mov ah,al
mov al,bl
out dx,ax
inc bl
loop .vmrr_02
sti
; call ref_screen
pop esi
pop edx
pop ecx
pop eax
retn
 
; Calculate of possible vertical refrash rate
; (light version of function)
vm_calc_refrate:
push ebx
push ecx
push edx
push edi
push esi
mov eax,[pclock]
xor edx,edx
mov edi,_m1
mov ebx,eax
mov ecx,(1696*1065)
div ecx
xor edx,edx
stosw
add edi,8
mov eax,ebx
mov ecx,(1344*804)
div ecx
xor edx,edx
stosw
add edi,8
mov eax,ebx
mov ecx,(1056*636)
div ecx
xor edx,edx
stosw
add edi,8
mov eax,ebx
mov ecx,(800*524)
div ecx
xor edx,edx
stosw
mov edi,_m1
mov esi,edi
mov ecx,5*4
.vmcrr_00:
lodsw
cmp ax,55
jb .vmcrr_01
stosw
loop .vmcrr_00
pop esi
pop edi
pop edx
pop ecx
pop ebx
retn
.vmcrr_01:
xor ax,ax
stosw
loop .vmcrr_00
pop esi
pop edi
pop edx
pop ecx
pop ebx
retn
 
vm_get_initial_videomode:
push eax
mov eax,dword [OS_BASE+0FE00h]
mov [oldX],eax
mov eax,dword [OS_BASE+0FE04h]
mov [oldY],eax
mov eax,dword [OS_BASE+0FE0Ch] ; initial video mode
and ax,01FFh
mov dword [initvm],eax
pop eax
retn
 
 
; IN: eax = 0/1 - -/+ 1 position of width
vm_inc_dec_width:
push ebx
push edx
mov ebx,eax
mov dx,3d4h ; CRTC
mov al,11h
out dx,al
inc dx
in al,dx
and al,7fh ; Clear Protection bit
out dx,al
dec dx
xor al,al
out dx,al
inc dx
in al,dx
dec al
cmp bl,0
jnz .vmidr_00
inc al
inc al
.vmidr_00:
out dx,al
pop edx
pop ebx
retn
 
;
; Copy driver info to application area
;
; IN: ecx (in app. edx) - pointer to 512-bytes info area in application
; OUT:
vm_transfer_drv_info:
push ecx
push edi
push esi
mov eax,ecx
xor ecx,ecx
mov cl,32/4
mov esi,mdname
mov edi,drvname
rep movsd
mov ecx,eax
mov eax,[mdver]
mov [drvver],eax
mov edi,[OS_BASE+3010h]
mov edi,[edi+10h]
add edi,ecx
mov esi,drvinfo
xor ecx,ecx
mov cx,512
rep movsb
pop esi
pop edi
pop ecx
retn
 
 
;
; Set selected video mode
; (light version)
;
; IN: ecx = VertRate*65536+VideoMode
;
vm_set_selected_mode:
push edx
push ecx
push esi
ror ecx,16
cmp cx,00h
je .vmssm_03
rol ecx,16
mov eax,ecx
shl eax,16
shr eax,16
mov [currvm],eax
cmp cx,112h
jne .vmssm_00
mov esi,mode0
mov ecx,639
mov edx,479
jmp .vmssm_st00
.vmssm_00:
cmp cx,115h
jne .vmssm_01
mov esi,mode1
mov ecx,799
mov edx,599
jmp .vmssm_st00
.vmssm_01:
cmp cx,118h
jne .vmssm_02
mov esi,mode2
mov ecx,1023
mov edx,767
jmp .vmssm_st00
.vmssm_02:
cmp cx,11Bh
jne .vmssm_03
mov esi,mode2
mov ecx,1279
mov edx,1023
jmp .vmssm_st00
.vmssm_03:
xor eax,eax
dec eax
pop esi
pop ecx
pop edx
retn
.vmssm_st00:
mov [OS_BASE+0FE00h],ecx
mov [OS_BASE+0FE04h],edx
cli
mov dx,03c4h
lodsw
out dx,ax
mov dx,03d4h
mov al,11h
out dx,al
inc dx
in al,dx
and al,7fh
out dx,al
dec dx
mov ecx,13
.vmssm_st01:
lodsw
out dx,ax
loop .vmssm_st01
sti
xor eax,eax
pop esi
pop ecx
pop edx
retn
 
 
;------------DATA AREA---------------
align 4
 
mdvm_func_table:
dd MDSTART
dd vm_info_init, vm_get_cur_mode
dd vm_set_video_mode, vm_restore_init_video_mode
dd vm_change_screen_size, vm_change_position_screen
 
 
CRTCreg:
_00 db ?
_01 db ?
_02 db ?
_03 db ?
_04 db ?
_05 db ?
_06 db ?
_07 db ?
_08 db ?
_09 db ?
_0a db ?
_0b db ?
_0c db ?
_0d db ?
_0e db ?
_0f db ?
_10 db ?
_11 db ?
_12 db ?
_13 db ?
_14 db ?
_15 db ?
_16 db ?
_17 db ?
_18 db ?
_19 db ?
 
align 4
 
oldX dd ?
oldY dd ?
initvm dd ?
currvm dd 0
refrate dd 0
initrr dd 0
systlb dd 0
pclock dd ?
mdrvm dd 0 ; 0 - not drv init yet, 1 - already drv init
 
 
drvinfo:
drvname: times 32 db ' '
drvver dd 0
times (32-($-drvver))/4 dd 0
drvmode dw 011Bh,0118h,0115h,0112h
times (64-($-drvmode))/2 dw 00h
_m1 dw 0,0,0,0,0
_m2 dw 0,0,0,0,0
_m3 dw 0,0,0,0,0
_m4 dw 0,0,0,0,0
_m5 dw 0,0,0,0,0
times (512-($-drvinfo)) db 0
drvinfoend:
 
 
;1280x1024 - 11Bh
mode3:
dw 0101h
dw 0d000h,9f01h,9f02h,9303h,0a904h,1905h,2806h,5a07h
dw 0110h,8411h,0ff12h,0ff15h,2916h
 
;1024x768 - 118h
mode2:
dw 0101h
dw 0a400h,7f01h,7f02h,8703h,8404h,9505h,2406h,0f507h
dw 0310h,8911h,0ff12h,0ff15h,2516h
 
;800x600 - 115h
mode1:
dw 0101h
dw 8000h,6301h,6302h,8303h,6a04h,1a05h,7206h,0f007h
dw 5910h,8d11h,5712h,5715h,7316h
 
;640x480 - 112h, 12h
mode0:
dw 0101h
dw 6000h,4f01h,4f02h,8303h,5304h,9f05h,00b06h,3e07h
dw 0ea10h,8c11h,0df12h,0df15h,0c16h
 
; 640x400
;mymode0:
; dw 0101h
;_0_7 dw 5f00h,4f01h,4f02h,8303h,5304h,9f05h,0BF06h,1f07h
; dw 9c10h,8e11h,8f12h,9615h,0B916h ;,4013h
 
; 640x800
;mymode1:
; dw 0101h
; dw 5f00h,4f01h,4f02h,8003h,5004h,9f05h,06006h,0FF07h
; dw 2d10h,8f11h,2012h,2615h,05716h ;,4013h
 
 
DRVM_END:
 
/kernel/branches/Kolibri-acpi/drivers/usb/urb.inc
0,0 → 1,115
 
struc URB
{
.fd dd ?
.bk dd ?
.dev dd ? ; pointer to associated device
.pipe dd ? ; pipe information
.status dd ? ; non-ISO status
.transfer_flags dd ? ; URB_SHORT_NOT_OK | ...
.transfer_buffer dd ? ; associated data buffer
.transfer_dma dd ? ; dma addr for transfer_buffer
.transfer_buffer_length dd ? ; data buffer length
.actual_length dd ? ; actual transfer length
.setup_packet dd ? ; setup packet (control only)
.setup_dma dd ? ; dma addr for setup_packet
.start_frame dd ? ; start frame (ISO)
.number_of_packets dd ? ; number of ISO packets
.interval dd ? ; transfer interval
 
.error_count dd ? ; number of ISO errors
.context dd ? ; context for completion
.complete dd ? ; (in) completion routine
.iso_frame_desc:
}
 
virtual at 0
URB URB
end virtual
 
 
struc REQ ;usb request
{
.request_type db ?
.request db ?
.value dw ?
.index dw ?
.length dw ?
}
 
virtual at 0
REQ REQ
end virtual
 
align 4
proc usb_control_msg stdcall, dev:dword, pipe:dword, request:dword,\
requesttype:dword, value:dword, index:dword,\
data:dword, size:dword, timeout:dword
 
locals
req REQ
endl
 
lea eax, [req]
mov ecx, [request]
mov ebx, [requesttupe]
mov edx, [value]
mov esi, [index]
mov edi, [size]
 
mov [eax+REQ.request_type], bl
mov [eax+REQ.request], cl
mov [eax+REQ.value], dx
mov [eax+REQ.index], si
mov [eax+REQ.length], di
 
stdcall usb_internal_control_msg, [dev], [pipe],\
eax, [data], [size], [timeout]
 
ret
endp
 
 
; returns status (negative) or length (positive)
static int usb_internal_control_msg(struct usb_device *usb_dev,
unsigned int pipe,
struct usb_ctrlrequest *cmd,
void *data, int len, int timeout)
{
struct urb *urb;
int retv;
int length;
 
urb = usb_alloc_urb(0, GFP_NOIO);
if (!urb)
return -ENOMEM;
usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
len, usb_api_blocking_completion, NULL);
 
retv = usb_start_wait_urb(urb, timeout, &length);
if (retv < 0)
return retv;
else
return length;
}
 
 
void usb_fill_control_urb (struct urb *urb,
struct usb_device *dev,
unsigned int pipe,
unsigned char *setup_packet,
void *transfer_buffer,
int buffer_length,
usb_complete_t complete_fn,
void *context)
{
 
urb->dev = dev;
urb->pipe = pipe;
urb->setup_packet = setup_packet;
urb->transfer_buffer = transfer_buffer;
urb->transfer_buffer_length = buffer_length;
urb->complete = complete_fn;
urb->context = context;
}
 
/kernel/branches/Kolibri-acpi/drivers/usb/usb.asm
0,0 → 1,435
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;driver sceletone
 
format MS COFF
 
API_VERSION equ 0 ;debug
 
include '../proc32.inc'
include '../imports.inc'
include 'urb.inc'
 
struc UHCI
{
.bus dd ?
.devfn dd ?
.io_base dd ?
.mm_base dd ?
.irq dd ?
.flags dd ?
.reset dd ?
.start dd ?
.stop dd ?
 
.port_c_suspend dd ?
.resuming_ports dd ?
.rh_state dd ?
.rh_numports dd ?
.is_stopped dd ?
.dead dd ?
 
.sizeof:
}
 
virtual at 0
UHCI UHCI
end virtual
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
struc TD ;transfer descriptor
{
.link dd ?
.status dd ?
.token dd ?
.buffer dd ?
 
.addr dd ?
.frame dd ?
.fd dd ?
.bk dd ?
.sizeof:
}
 
virtual at 0
TD TD
end virtual
 
public START
public service_proc
public version
 
DEBUG equ 1
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
STRIDE equ 4 ;size of row in devices table
 
SRV_GETVERSION equ 0
 
section '.flat' code readable align 16
 
proc START stdcall, state:dword
 
cmp [state], 1
jne .exit
.entry:
 
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
call init
 
stdcall RegService, my_service, service_proc
ret
.fail:
.exit:
xor eax, eax
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov ebx, [ioctl]
mov eax, [ebx+io_code]
cmp eax, SRV_GETVERSION
jne @F
 
mov eax, [ebx+output]
cmp [ebx+out_size], 4
jne .fail
mov [eax], dword API_VERSION
xor eax, eax
ret
@@:
.fail:
or eax, -1
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
align 4
proc detect
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, STRIDE
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 eax, UHCI.sizeof
call Kmalloc
test eax, eax
jz .mem_fail
 
mov ebx, [bus]
mov [eax+UHCI.bus], ebx
 
mov ecx, [devfn]
mov [eax+UHCI.devfn], ecx
ret
.mem_fail:
if DEBUG
mov esi, msgMemFail
call SysMsgBoardStr
end if
.err:
xor eax, eax
ret
endp
 
PCI_BASE equ 0x20
USB_LEGKEY equ 0xC0
 
align 4
proc init
locals
uhci dd ?
endl
 
call detect
test eax, eax
jz .fail
 
mov [uhci], eax
 
stdcall PciRead32, [eax+UHCI.bus], [eax+UHCI.devfn], PCI_BASE
and eax, 0xFFC0
mov esi, [uhci]
mov [esi+UHCI.io_base], eax
 
stdcall uhci_reset, esi
 
stdcall finish_reset, [uhci]
 
.fail:
if DEBUG
mov esi, msgDevNotFound
call SysMsgBoardStr
end if
ret
endp
 
UHCI_USBINTR equ 4 ; interrupt register
 
UHCI_USBLEGSUP_RWC equ 0x8f00 ; the R/WC bits
UHCI_USBLEGSUP_RO equ 0x5040 ; R/O and reserved bits
 
UHCI_USBCMD_RUN equ 0x0001 ; RUN/STOP bit
UHCI_USBCMD_HCRESET equ 0x0002 ; Host Controller reset
UHCI_USBCMD_EGSM equ 0x0008 ; Global Suspend Mode
UHCI_USBCMD_CONFIGURE equ 0x0040 ; Config Flag
UHCI_USBINTR_RESUME equ 0x0002 ; Resume interrupt enable
 
PORTSC0 equ 0x10
PORTSC1 equ 0x12
 
 
UHCI_RH_RESET equ 0
UHCI_RH_SUSPENDED equ 1
UHCI_RH_AUTO_STOPPED equ 2
UHCI_RH_RESUMING equ 3
 
; In this state the HC changes from running to halted
; so it can legally appear either way.
UHCI_RH_SUSPENDING equ 4
 
; In the following states it's an error if the HC is halted.
; These two must come last.
UHCI_RH_RUNNING equ 5 ; The normal state
UHCI_RH_RUNNING_NODEVS equ 6 ; Running with no devices
 
UHCI_IS_STOPPED equ 9999
 
align 4
proc uhci_reset stdcall, uhci:dword
mov esi, [uhci]
stdcall PciRead16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY
test eax, not (UHCI_USBLEGSUP_RO or UHCI_USBLEGSUP_RWC)
jnz .reset
 
mov edx, [esi+UHCI.io_base]
in ax, dx
test ax, UHCI_USBCMD_RUN
jnz .reset
 
test ax, UHCI_USBCMD_CONFIGURE
jz .reset
 
test ax, UHCI_USBCMD_EGSM
jz .reset
 
add edx, UHCI_USBINTR
in ax, dx
test ax, not UHCI_USBINTR_RESUME
jnz .reset
ret
.reset:
stdcall PciWrite16, [esi+UHCI.bus], [esi+UHCI.devfn], USB_LEGKEY, UHCI_USBLEGSUP_RWC
 
mov edx, [esi+UHCI.io_base]
mov ax, UHCI_USBCMD_HCRESET
out dx, ax
 
xor eax, eax
out dx, ax
add edx, UHCI_USBINTR
out dx, ax
ret
endp
 
proc finish_reset stdcall, uhci:dword
 
mov esi, [uhci]
mov edx, [esi+UHCI.io_base]
add edx, PORTSC0
xor eax, eax
out dx, ax
add edx, (PORTSC1-PORTSC0)
out dx, ax
 
mov [esi+UHCI.port_c_suspend], eax
mov [esi+UHCI.resuming_ports], eax
mov [esi+UHCI.rh_state], UHCI_RH_RESET
mov [esi+UHCI.rh_numports], 2
 
mov [esi+UHCI.is_stopped], UHCI_IS_STOPPED
; mov [ uhci_to_hcd(uhci)->state = HC_STATE_HALT;
; uhci_to_hcd(uhci)->poll_rh = 0;
 
mov [esi+UHCI.dead], eax ; Full reset resurrects the controller
 
ret
endp
 
proc insert_td stdcall, td:dword, frame:dword
 
mov edi, [td]
mov eax, [frame]
and eax, -1024
mov [edi+TD.frame], eax
 
mov ebx, [framelist]
mov edx, [dma_framelist]
shl eax, 5
 
mov ecx, [eax+ebx]
test ecx, ecx
jz .empty
 
mov ecx, [ecx+TD.bk] ;last TD
 
mov edx, [ecx+TD.fd]
mov [edi+TD.fd], edx
mov [edi+TD.bk], ecx
mov [ecx+TD.fd], edi
mov [edx+TD.bk], edi
 
mov eax, [ecx+TD.link]
mov [edi+TD.link], eax
mov ebx, [edi+TD.addr]
mov [ecx+TD.link], ebx
ret
.empty:
mov ecx, [eax+edx]
mov [edi+TD.link], ecx
mov [ebx+eax], edi
mov ecx, [edi+TD.addr]
mov [eax+edx], ecx
ret
endp
 
 
align 4
proc usb_get_descriptor stdcall, dev:dword, type:dword, index:dword,\
buf:dword, size:dword
 
locals
count dd ?
endl
 
mov esi, [buf]
mov ecx, [size]
xor eax, eax
cld
rep stosb
 
mov [count], 3
@@:
mov eax, [type]
shl eax, 8
add eax, [index]
stdcall usb_control_msg, [dev],pipe,USB_REQ_GET_DESCRIPTOR,\
USB_DIR_IN, eax,0,[buf], [size],\
USB_CTRL_GET_TIMEOUT
test eax, eax
jz .next
cmp eax, -1
je .next
jmp. ok
.next:
dec [count]
jnz @B
mov eax, -1
.ok:
ret
endp
 
DEVICE_ID equ 0x24D2 ; pci device id
VENDOR_ID equ 0x8086 ; device vendor id
QEMU_USB equ 0x7020
 
;all initialized data place here
 
align 4
devices dd (DEVICE_ID shl 16)+VENDOR_ID
dd (QEMU_USB shl 16)+VENDOR_ID
dd 0 ;terminator
 
version dd (5 shl 16) or (API_VERSION and 0xFFFF)
 
my_service db 'UHCI',0 ;max 16 chars include zero
 
msgInit db 'detect hardware...',13,10,0
msgPCI db 'PCI accsess not supported',13,10,0
msgDevNotFound db 'device not found',13,10,0
msgMemFail db 'Kmalloc failed', 10,10,0
;msgFail db 'device not found',13,10,0
 
section '.data' data readable writable align 16
 
;all uninitialized data place here
 
/kernel/branches/Kolibri-acpi/drivers/usb
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/drivers/mix_mmx.inc
0,0 → 1,247
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; params
; edi= output
; eax= input stream 1
; ebx= input stream 2
 
if used mmx_mix_2
 
align 4
mmx_mix_2:
movq mm0, [eax]
movq mm1, [eax+8]
movq mm2, [eax+16]
movq mm3, [eax+24]
movq mm4, [eax+32]
movq mm5, [eax+40]
movq mm6, [eax+48]
movq mm7, [eax+56]
 
paddsw mm0, [ebx]
movq [edi], mm0
paddsw mm1,[ebx+8]
movq [edi+8], mm1
paddsw mm2, [ebx+16]
movq [edi+16], mm2
paddsw mm3, [ebx+24]
movq [edi+24], mm3
paddsw mm4, [ebx+32]
movq [edi+32], mm4
paddsw mm5, [ebx+40]
movq [edi+40], mm5
paddsw mm6, [ebx+48]
movq [edi+48], mm6
paddsw mm7, [ebx+56]
movq [edi+56], mm7
 
movq mm0, [eax+64]
movq mm1, [eax+72]
movq mm2, [eax+80]
movq mm3, [eax+88]
movq mm4, [eax+96]
movq mm5, [eax+104]
movq mm6, [eax+112]
movq mm7, [eax+120]
 
paddsw mm0, [ebx+64]
movq [edi+64], mm0
paddsw mm1, [ebx+72]
movq [edi+72], mm1
paddsw mm2, [ebx+80]
movq [edi+80], mm2
paddsw mm3, [ebx+88]
movq [edi+88], mm3
paddsw mm4, [ebx+96]
movq [edi+96], mm4
paddsw mm5, [ecx+104]
movq [edx+104], mm5
paddsw mm6, [ebx+112]
movq [edi+112], mm6
paddsw mm7, [ebx+120]
movq [edi+120], mm7
ret
 
align 4
mmx_mix_3:
movq mm0, [eax]
movq mm1, [eax+8]
movq mm2, [eax+16]
movq mm3, [eax+24]
movq mm4, [eax+32]
movq mm5, [eax+40]
movq mm6, [eax+48]
movq mm7, [eax+56]
 
paddsw mm0, [ebx]
paddsw mm1, [ebx+8]
paddsw mm2, [ebx+16]
paddsw mm3, [ebx+24]
paddsw mm4, [ebx+32]
paddsw mm5, [ebx+40]
paddsw mm6, [ebx+48]
paddsw mm7, [ebx+56]
paddsw mm0, [ecx]
movq [edi], mm0
paddsw mm1,[ecx+8]
movq [edi+8], mm1
paddsw mm2, [ecx+16]
movq [edi+16], mm2
paddsw mm3, [ecx+24]
movq [edi+24], mm3
paddsw mm4, [ecx+32]
movq [edi+32], mm4
paddsw mm5, [ecx+40]
movq [edi+40], mm5
paddsw mm6, [ecx+48]
movq [edi+48], mm6
paddsw mm7, [ecx+56]
movq [edi+56], mm7
 
movq mm0, [eax+64]
movq mm1, [eax+72]
movq mm2, [eax+80]
movq mm3, [eax+88]
movq mm4, [eax+96]
movq mm5, [eax+104]
movq mm6, [eax+112]
movq mm7, [eax+120]
paddsw mm0, [ebx+64]
paddsw mm1, [ebx+72]
paddsw mm2, [ebx+80]
paddsw mm3, [ebx+88]
paddsw mm4, [ebx+96]
paddsw mm5, [ebx+104]
paddsw mm6, [ebx+112]
paddsw mm7, [ebx+120]
paddsw mm0, [ecx+64]
movq [edi+64], mm0
paddsw mm1, [ecx+72]
movq [edi+72], mm1
paddsw mm2, [ecx+80]
movq [edi+80], mm2
paddsw mm3, [ecx+88]
movq [edi+88], mm3
paddsw mm4, [ecx+96]
movq [edi+96], mm4
paddsw mm5, [ecx+104]
movq [edi+104], mm5
paddsw mm6, [ecx+112]
movq [edi+112], mm6
paddsw mm7, [ecx+120]
movq [edi+120], mm7
ret
 
align 4
mmx_mix_4:
 
movq mm0, [eax]
movq mm2, [eax+8]
movq mm4, [eax+16]
movq mm6, [eax+24]
movq mm1, [ebx]
movq mm3, [ebx+8]
movq mm5, [ebx+16]
movq mm7, [ebx+24]
paddsw mm0, [ecx]
paddsw mm2, [ecx+8]
paddsw mm4, [ecx+16]
paddsw mm6, [ecx+24]
paddsw mm1, [edx]
paddsw mm3, [edx+8]
paddsw mm5, [edx+16]
paddsw mm7, [edx+24]
 
paddsw mm0, mm1
movq [edi], mm0
paddsw mm2, mm3
movq [edi+8], mm2
paddsw mm4, mm5
movq [edi+16], mm4
paddsw mm5, mm6
movq [edi+24], mm6
 
movq mm0, [eax+32]
movq mm2, [eax+40]
movq mm4, [eax+48]
movq mm6, [eax+56]
movq mm1, [ebx+32]
movq mm3, [ebx+40]
movq mm5, [ebx+48]
movq mm7, [ebx+56]
paddsw mm0, [ecx+32]
paddsw mm2, [ecx+40]
paddsw mm4, [ecx+48]
paddsw mm6, [ecx+56]
paddsw mm1, [edx+32]
paddsw mm3, [edx+40]
paddsw mm5, [edx+48]
paddsw mm7, [edx+56]
 
paddsw mm0, mm1
movq [edi+32], mm0
paddsw mm2, mm2
movq [edi+40], mm2
paddsw mm4, mm5
movq [edi+48], mm4
paddsw mm6, mm7
movq [edi+56], mm6
 
movq mm0, [eax+64]
movq mm2, [eax+72]
movq mm4, [eax+80]
movq mm6, [eax+88]
movq mm1, [ebx+64]
movq mm3, [ebx+72]
movq mm5, [ebx+80]
movq mm7, [ebx+88]
paddsw mm0, [ecx+64]
paddsw mm2, [ecx+72]
paddsw mm4, [ecx+80]
paddsw mm6, [ecx+88]
paddsw mm1, [edx+64]
paddsw mm3, [edx+72]
paddsw mm5, [edx+80]
paddsw mm7, [edx+88]
 
paddsw mm0, mm1
movq [edi+64], mm0
paddsw mm2, mm3
movq [edi+72], mm2
paddsw mm4, mm5
movq [edi+80], mm4
paddsw mm6, mm5
movq [edi+88], mm7
 
movq mm0, [eax+96]
movq mm2, [eax+104]
movq mm4, [eax+112]
movq mm6, [eax+120]
movq mm1, [ebx+96]
movq mm3, [ebx+104]
movq mm5, [ebx+112]
movq mm7, [ebx+120]
paddsw mm0, [ecx+96]
paddsw mm2, [ecx+104]
paddsw mm4, [ecx+112]
paddsw mm6, [ecx+120]
paddsw mm1, [edx+96]
paddsw mm3, [edx+104]
paddsw mm5, [edx+112]
paddsw mm7, [edx+120]
paddsw mm0, mm1
movq [eax+96], mm0
paddsw mm2, mm3
movq [edi+104], mm2
paddsw mm4, mm5
movq [edi+112], mm4
paddsw mm6, mm7
movq [edi+120], mm6
ret
 
end if
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers/mix_sse2.inc
0,0 → 1,145
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
if used mmx128_mix_2
 
align 4
mmx128_mix_2:
prefetcht1 [eax+128]
prefetcht1 [ebx+128]
 
movaps xmm0, [eax]
movaps xmm1, [eax+16]
movaps xmm2, [eax+32]
movaps xmm3, [eax+48]
movaps xmm4, [eax+64]
movaps xmm5, [eax+80]
movaps xmm6, [eax+96]
movaps xmm7, [eax+112]
 
paddsw xmm0, [ebx]
movaps [edi], xmm0
paddsw xmm1,[ebx+16]
movaps [edi+16], xmm1
paddsw xmm2, [ebx+32]
movaps [edi+32], xmm2
paddsw xmm3, [ebx+48]
movaps [edi+48], xmm3
paddsw xmm4, [ebx+64]
movaps [edi+64], xmm4
paddsw xmm5, [ebx+80]
movaps [edi+80], xmm5
paddsw xmm6, [ebx+96]
movaps [edi+96], xmm6
paddsw xmm7, [ebx+112]
movaps [edi+112], xmm7
ret
 
align 4
mmx128_mix_3:
prefetcht1 [eax+128]
prefetcht1 [ebx+128]
prefetcht1 [ecx+128]
 
movaps xmm0, [eax]
movaps xmm1, [eax+16]
movaps xmm2, [eax+32]
movaps xmm3, [eax+48]
movaps xmm4, [eax+64]
movaps xmm5, [eax+80]
movaps xmm6, [eax+96]
movaps xmm7, [eax+112]
 
paddsw xmm0, [ebx]
paddsw xmm1, [ebx+16]
paddsw xmm2, [ebx+32]
paddsw xmm3, [ebx+48]
paddsw xmm4, [ebx+64]
paddsw xmm5, [ebx+80]
paddsw xmm6, [ebx+96]
paddsw xmm7, [ebx+112]
 
paddsw xmm0, [ecx]
movaps [edi], xmm0
paddsw xmm1, [ecx+16]
movaps [edi+16], xmm1
paddsw xmm2, [ecx+32]
movaps [edi+32], xmm2
paddsw xmm3, [ecx+48]
movaps [edi+48], xmm3
paddsw xmm4, [ecx+64]
movaps [edi+64], xmm4
paddsw xmm5, [ecx+80]
movaps [edi+80], xmm5
paddsw xmm6, [ecx+96]
movaps [edi+96], xmm6
paddsw xmm7, [ecx+112]
movaps [edi+112], xmm7
ret
 
align 4
mmx128_mix_4:
prefetcht1 [eax+128]
prefetcht1 [ebx+128]
prefetcht1 [ecx+128]
prefetcht1 [edx+128]
 
movaps xmm0, [eax]
movaps xmm2, [eax+16]
movaps xmm4, [eax+32]
movaps xmm6, [eax+48]
movaps xmm1, [ebx]
movaps xmm3, [ebx+16]
movaps xmm5, [ebx+32]
movaps xmm7, [ebx+48]
 
paddsw xmm0, [ecx]
paddsw xmm2, [ecx+16]
paddsw xmm4, [ecx+32]
paddsw xmm6, [ecx+48]
paddsw xmm1, [edx]
paddsw xmm3, [edx+16]
paddsw xmm5, [edx+32]
paddsw xmm7, [edx+48]
 
paddsw xmm0, xmm1
movaps [edi], xmm0
paddsw xmm2, xmm3
movaps [edi+16], xmm2
paddsw xmm4, xmm5
movaps [edi+32], xmm4
paddsw xmm6, xmm7
movaps [edi+48], xmm6
 
movaps xmm0, [eax+64]
movaps xmm2, [eax+80]
movaps xmm4, [eax+96]
movaps xmm6, [eax+112]
 
movaps xmm1, [ebx+64]
movaps xmm3, [ebx+80]
movaps xmm5, [ebx+96]
movaps xmm7, [ebx+112]
paddsw xmm0, [ecx+64]
paddsw xmm2, [ecx+80]
paddsw xmm4, [ecx+96]
paddsw xmm6, [ecx+112]
 
paddsw xmm1, [edx+64]
paddsw xmm3, [edx+80]
paddsw xmm5, [edx+96]
paddsw xmm7, [edx+112]
paddsw xmm0, xmm1
movaps [edi+64], xmm0
paddsw xmm2, xmm3
movaps [edi+80], xmm2
paddsw xmm4, xmm5
movaps [edi+96], xmm4
paddsw xmm6, xmm7
movaps [edi+112], xmm6
ret
end if
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/drivers
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/makefile
0,0 → 1,48
FASM=fasm
FLAGS=-m 65536
languages=en|ru|ge|et
drivers_src=com_mouse emu10k1x ensoniq fm801 infinity sis sound uart viasound vmode vt823\(x\)
skins_src=default
 
.PHONY: all kernel drivers skins clean
 
all: kernel drivers skins
 
kernel: check_lang
@echo "*** building kernel with language '$(lang)' ..."
@mkdir -p bin
@echo "lang fix $(lang)" > lang.inc
@echo "--- building 'bin/kernel.mnt' ..."
@$(FASM) $(FLAGS) kernel.asm bin/kernel.mnt
@rm -f lang.inc
 
drivers:
@echo "*** building drivers ..."
@mkdir -p bin/drivers
@cd drivers; for f in $(drivers_src); do \
echo "--- building 'bin/drivers/$${f}.obj' ..."; \
$(FASM) $(FLAGS) "$${f}.asm" "../bin/drivers/$${f}.obj" || exit $?; \
done
@mv bin/drivers/vmode.obj bin/drivers/vmode.mdr
 
skins:
@echo "*** building skins ..."
@mkdir -p bin/skins
@cd skin; for f in $(skins_src); do \
echo "--- building 'bin/skins/$${f}.skn' ..."; \
$(FASM) $(FLAGS) $${f}.asm ../bin/skins/$${f}.skn || exit $?; \
done
 
check_lang:
@case "$(lang)" in \
$(languages)) \
;; \
*) \
echo "*** error: language is incorrect or not specified"; \
exit 1; \
;; \
esac
 
clean:
rm -rf bin
rm -f lang.inc
/kernel/branches/Kolibri-acpi/kernel.asm
0,0 → 1,5330
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved.
;; PROGRAMMING:
;; Ivan Poddubny
;; Marat Zakiyanov (Mario79)
;; VaStaNi
;; Trans
;; Mihail Semenyako (mike.dld)
;; Sergey Kuzmin (Wildwest)
;; Andrey Halyavin (halyavin)
;; Mihail Lisovin (Mihasik)
;; Andrey Ignatiev (andrew_programmer)
;; NoName
;; Evgeny Grechnikov (Diamond)
;; Iliya Mihailov (Ghost)
;; Sergey Semyonov (Serge)
;; Johnny_B
;; SPraid (simba)
;; Hidnplayr
;; Alexey Teplov (<Lrz>)
;;
;; Data in this file was originally part of MenuetOS project which is
;; distributed under the terms of GNU GPL. It is modified and redistributed as
;; part of KolibriOS project under the terms of GNU GPL.
;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa
;; PROGRAMMING:
;;
;; Ville Mikael Turjanmaa, villemt@itu.jyu.fi
;; - main os coding/design
;; Jan-Michael Brummer, BUZZ2@gmx.de
;; Felix Kaiser, info@felix-kaiser.de
;; Paolo Minazzi, paolo.minazzi@inwind.it
;; quickcode@mail.ru
;; Alexey, kgaz@crosswinds.net
;; Juan M. Caravaca, bitrider@wanadoo.es
;; kristol@nic.fi
;; Mike Hibbett, mikeh@oceanfree.net
;; Lasse Kuusijarvi, kuusijar@lut.fi
;; Jarek Pelczar, jarekp3@wp.pl
;;
;; KolibriOS is distributed in the hope that it will be useful, but WITHOUT ANY
;; WARRANTY. No author or distributor accepts responsibility to anyone for the
;; consequences of using it or for whether it serves any particular purpose or
;; works at all, unless he says so in writing. Refer to the GNU General Public
;; License (the "GPL") for full details.
;
;; Everyone is granted permission to copy, modify and redistribute KolibriOS,
;; but only under the conditions described in the GPL. A copy of this license
;; is supposed to have been given to you along with KolibriOS so you can know
;; your rights and responsibilities. It should be in a file named COPYING.
;; Among other things, the copyright notice and this notice must be preserved
;; on all copies.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
include 'macros.inc'
 
$Revision$
 
 
USE_COM_IRQ equ 1 ; make irq 3 and irq 4 available for PCI devices
 
; Enabling the next line will enable serial output console
;debug_com_base equ 0x3f8 ; 0x3f8 is com1, 0x2f8 is com2, 0x3e8 is com3, 0x2e8 is com4, no irq's are used
 
include "proc32.inc"
include "kglobals.inc"
include "lang.inc"
 
include "const.inc"
max_processes equ 255
tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4
 
 
os_stack equ (os_data_l-gdts) ; GDTs
os_code equ (os_code_l-gdts)
graph_data equ (3+graph_data_l-gdts)
tss0 equ (tss0_l-gdts)
app_code equ (3+app_code_l-gdts)
app_data equ (3+app_data_l-gdts)
app_tls equ (3+tls_data_l-gdts)
pci_code_sel equ (pci_code_32-gdts)
pci_data_sel equ (pci_data_32-gdts)
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Included files:
;;
;; Kernel16.inc
;; - Booteng.inc English text for bootup
;; - Bootcode.inc Hardware setup
;; - Pci16.inc PCI functions
;;
;; Kernel32.inc
;; - Sys32.inc Process management
;; - Shutdown.inc Shutdown and restart
;; - Fat32.inc Read / write hd
;; - Vesa12.inc Vesa 1.2 driver
;; - Vesa20.inc Vesa 2.0 driver
;; - Vga.inc VGA driver
;; - Stack.inc Network interface
;; - Mouse.inc Mouse pointer
;; - Scincode.inc Window skinning
;; - Pci32.inc PCI functions
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 16 BIT ENTRY FROM BOOTSECTOR ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
use16
org 0x0
jmp start_of_code
 
version db 'Kolibri OS version 0.7.7.0+ ',13,10,13,10,0
 
include "boot/bootstr.inc" ; language-independent boot messages
include "boot/preboot.inc"
 
if lang eq en
include "boot/booteng.inc" ; english system boot messages
else if lang eq ru
include "boot/bootru.inc" ; russian system boot messages
include "boot/ru.inc" ; Russian font
else if lang eq et
include "boot/bootet.inc" ; estonian system boot messages
include "boot/et.inc" ; Estonian font
else
include "boot/bootge.inc" ; german system boot messages
end if
 
include "boot/bootcode.inc" ; 16 bit system boot code
include "bus/pci/pci16.inc"
include "detect/biosdisk.inc"
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SWITCH TO 32 BIT PROTECTED MODE ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
; CR0 Flags - Protected mode and Paging
 
mov ecx, CR0_PE
 
; Enabling 32 bit protected mode
 
sidt [cs:old_ints_h]
 
cli ; disable all irqs
cld
mov al,255 ; mask all irqs
out 0xa1,al
out 0x21,al
l.5: in al, 0x64 ; Enable A20
test al, 2
jnz l.5
mov al, 0xD1
out 0x64, al
l.6: in al, 0x64
test al, 2
jnz l.6
mov al, 0xDF
out 0x60, al
l.7: in al, 0x64
test al, 2
jnz l.7
mov al, 0xFF
out 0x64, al
 
lgdt [cs:tmp_gdt] ; Load GDT
mov eax, cr0 ; protected mode
or eax, ecx
and eax, 10011111b *65536*256 + 0xffffff ; caching enabled
mov cr0, eax
jmp pword os_code:B32 ; jmp to enable 32 bit mode
 
align 8
tmp_gdt:
 
dw 23
dd tmp_gdt+0x10000
dw 0
 
dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10011010b
db 0x00
 
dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10010010b
db 0x00
 
include "data16.inc"
 
use32
org $+0x10000
 
align 4
B32:
mov ax,os_stack ; Selector for os
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,0x3ec00 ; Set stack
 
; CLEAR 0x280000 - HEAP_BASE
 
xor eax,eax
mov edi,0x280000
mov ecx,(HEAP_BASE-OS_BASE-0x280000) / 4
cld
rep stosd
 
mov edi,0x40000
mov ecx,(0x90000-0x40000)/4
rep stosd
 
; CLEAR KERNEL UNDEFINED GLOBALS
mov edi, endofcode-OS_BASE
mov ecx, (uglobals_size/4)+4
rep stosd
 
; SAVE & CLEAR 0-0xffff
 
xor esi, esi
mov edi,0x2F0000
mov ecx,0x10000 / 4
rep movsd
mov edi,0x1000
mov ecx,0xf000 / 4
rep stosd
 
call test_cpu
bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc
 
call init_BIOS32
; MEMORY MODEL
call mem_test
call init_mem
call init_page_map
 
; ENABLE PAGING
 
mov eax, sys_pgdir-OS_BASE
mov cr3, eax
 
mov eax,cr0
or eax,CR0_PG+CR0_WP
mov cr0,eax
 
lgdt [gdts]
jmp pword os_code:high_code
 
align 4
bios32_entry dd ?
tmp_page_tabs dd ?
 
use16
org $-0x10000
include "boot/shutdown.inc" ; shutdown or restart
org $+0x10000
use32
 
__DEBUG__ fix 1
__DEBUG_LEVEL__ fix 1
include 'init.inc'
 
org OS_BASE+$
 
align 4
high_code:
mov ax, os_stack
mov bx, app_data
mov cx, app_tls
mov ss, ax
add esp, OS_BASE
 
mov ds, bx
mov es, bx
mov fs, cx
mov gs, bx
 
bt [cpu_caps], CAPS_PGE
jnc @F
 
or dword [sys_pgdir+(OS_BASE shr 20)], PG_GLOBAL
 
mov ebx, cr4
or ebx, CR4_PGE
mov cr4, ebx
@@:
xor eax, eax
mov dword [sys_pgdir], eax
mov dword [sys_pgdir+4], eax
 
mov eax, cr3
mov cr3, eax ; flush TLB
 
; SAVE REAL MODE VARIABLES
mov ax, [BOOT_VAR + 0x9031]
mov [IDEContrRegsBaseAddr], ax
; --------------- APM ---------------------
 
; init selectors
mov ebx,[BOOT_VAR+0x9040] ; offset of APM entry point
movzx eax,word [BOOT_VAR+0x9050] ; real-mode segment base address of
; protected-mode 32-bit code segment
movzx ecx,word [BOOT_VAR+0x9052] ; real-mode segment base address of
; protected-mode 16-bit code segment
movzx edx,word [BOOT_VAR+0x9054] ; real-mode segment base address of
; protected-mode 16-bit data segment
 
shl eax, 4
mov [dword apm_code_32 + 2], ax
shr eax, 16
mov [dword apm_code_32 + 4], al
 
shl ecx, 4
mov [dword apm_code_16 + 2], cx
shr ecx, 16
mov [dword apm_code_16 + 4], cl
 
shl edx, 4
mov [dword apm_data_16 + 2], dx
shr edx, 16
mov [dword apm_data_16 + 4], dl
 
mov dword[apm_entry], ebx
mov word [apm_entry + 4], apm_code_32 - gdts
 
mov eax, [BOOT_VAR + 0x9044] ; version & flags
mov [apm_vf], eax
; -----------------------------------------
; movzx eax,byte [BOOT_VAR+0x9010] ; mouse port
; mov [0xF604],byte 1 ;al
mov al, [BOOT_VAR+0x901F] ; DMA access
mov [allow_dma_access], al
movzx eax, byte [BOOT_VAR+0x9000] ; bpp
mov [ScreenBPP],al
 
mov [_display.bpp], eax
mov [_display.vrefresh], 60
mov [_display.disable_mouse], __sys_disable_mouse
 
movzx eax,word [BOOT_VAR+0x900A] ; X max
mov [_display.width], eax
dec eax
mov [Screen_Max_X],eax
mov [screen_workarea.right],eax
movzx eax,word [BOOT_VAR+0x900C] ; Y max
mov [_display.height], eax
dec eax
mov [Screen_Max_Y],eax
mov [screen_workarea.bottom],eax
movzx eax,word [BOOT_VAR+0x9008] ; screen mode
mov [SCR_MODE],eax
mov eax,[BOOT_VAR+0x9014] ; Vesa 1.2 bnk sw add
mov [BANK_SWITCH],eax
mov [BytesPerScanLine],word 640*4 ; Bytes PerScanLine
cmp [SCR_MODE],word 0x13 ; 320x200
je @f
cmp [SCR_MODE],word 0x12 ; VGA 640x480
je @f
movzx eax, word[BOOT_VAR+0x9001] ; for other modes
mov [BytesPerScanLine],ax
mov [_display.pitch], eax
@@:
mov eax, [_display.width]
mul [_display.height]
mov [_WinMapSize], eax
 
mov esi, BOOT_VAR+0x9080
movzx ecx, byte [esi-1]
mov [NumBiosDisks], ecx
mov edi, BiosDisksData
rep movsd
 
; GRAPHICS ADDRESSES
 
and byte [BOOT_VAR+0x901e],0x0
mov eax,[BOOT_VAR+0x9018]
mov [LFBAddress],eax
 
cmp [SCR_MODE],word 0100000000000000b
jge setvesa20
cmp [SCR_MODE],word 0x13
je v20ga32
mov [PUTPIXEL],dword Vesa12_putpixel24 ; Vesa 1.2
mov [GETPIXEL],dword Vesa12_getpixel24
cmp [ScreenBPP],byte 24
jz ga24
mov [PUTPIXEL],dword Vesa12_putpixel32
mov [GETPIXEL],dword Vesa12_getpixel32
ga24:
jmp v20ga24
setvesa20:
mov [PUTPIXEL],dword Vesa20_putpixel24 ; Vesa 2.0
mov [GETPIXEL],dword Vesa20_getpixel24
cmp [ScreenBPP],byte 24
jz v20ga24
v20ga32:
mov [PUTPIXEL],dword Vesa20_putpixel32
mov [GETPIXEL],dword Vesa20_getpixel32
v20ga24:
cmp [SCR_MODE],word 0x12 ; 16 C VGA 640x480
jne no_mode_0x12
mov [PUTPIXEL],dword VGA_putpixel
mov [GETPIXEL],dword Vesa20_getpixel32
no_mode_0x12:
 
; -------- Fast System Call init ----------
; Intel SYSENTER/SYSEXIT (AMD CPU support it too)
bt [cpu_caps], CAPS_SEP
jnc .SEnP ; SysEnter not Present
xor edx, edx
mov ecx, MSR_SYSENTER_CS
mov eax, os_code
wrmsr
mov ecx, MSR_SYSENTER_ESP
; mov eax, sysenter_stack ; Check it
xor eax, eax
wrmsr
mov ecx, MSR_SYSENTER_EIP
mov eax, sysenter_entry
wrmsr
.SEnP:
; AMD SYSCALL/SYSRET
cmp byte[cpu_vendor], 'A'
jne .noSYSCALL
mov eax, 0x80000001
cpuid
test edx, 0x800 ; bit_11 - SYSCALL/SYSRET support
jz .noSYSCALL
mov ecx, MSR_AMD_EFER
rdmsr
or eax, 1 ; bit_0 - System Call Extension (SCE)
wrmsr
 
; !!!! It`s dirty hack, fix it !!!
; Bits of EDX :
; Bit 31–16 During the SYSRET instruction, this field is copied into the CS register
; and the contents of this field, plus 8, are copied into the SS register.
; Bit 15–0 During the SYSCALL instruction, this field is copied into the CS register
; and the contents of this field, plus 8, are copied into the SS register.
 
; mov edx, (os_code + 16) * 65536 + os_code
mov edx, 0x1B0008
 
mov eax, syscall_entry
mov ecx, MSR_AMD_STAR
wrmsr
.noSYSCALL:
; -----------------------------------------
stdcall alloc_page
stdcall map_page, tss-0xF80, eax, PG_SW
stdcall alloc_page
inc eax
mov [SLOT_BASE+256+APPDATA.io_map], eax
stdcall map_page, tss+0x80, eax, PG_SW
stdcall alloc_page
inc eax
mov dword [SLOT_BASE+256+APPDATA.io_map+4], eax
stdcall map_page, tss+0x1080, eax, PG_SW
 
; LOAD IDT
 
call build_interrupt_table ;lidt is executed
;lidt [idtreg]
 
call init_kernel_heap
stdcall kernel_alloc, RING0_STACK_SIZE+512
mov [os_stack_seg], eax
 
lea esp, [eax+RING0_STACK_SIZE]
 
mov [tss._ss0], os_stack
mov [tss._esp0], esp
mov [tss._esp], esp
mov [tss._cs],os_code
mov [tss._ss],os_stack
mov [tss._ds],app_data
mov [tss._es],app_data
mov [tss._fs],app_data
mov [tss._gs],app_data
mov [tss._io],128
;Add IO access table - bit array of permitted ports
mov edi, tss._io_map_0
xor eax, eax
not eax
mov ecx, 8192/4
rep stosd ; access to 4096*8=65536 ports
 
mov ax,tss0
ltr ax
 
mov [LFBSize], 0x800000
call init_LFB
call init_fpu
call init_malloc
 
stdcall alloc_kernel_space, 0x51000
mov [default_io_map], eax
 
add eax, 0x2000
mov [ipc_tmp], eax
mov ebx, 0x1000
 
add eax, 0x40000
mov [proc_mem_map], eax
 
add eax, 0x8000
mov [proc_mem_pdir], eax
 
add eax, ebx
mov [proc_mem_tab], eax
 
add eax, ebx
mov [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, (unpack.LZMA_BASE_SIZE+(unpack.LZMA_LIT_SIZE shl \
(unpack.lc+unpack.lp)))*4
 
mov [unpack.p], eax
 
call init_events
mov eax, srv.fd-SRV_FD_OFFSET
mov [srv.fd], eax
mov [srv.bk], eax
 
mov edi, irq_tab
xor eax, eax
mov ecx, 16
rep stosd
 
;Set base of graphic segment to linear address of LFB
mov eax,[LFBAddress] ; set for gs
mov [graph_data_l+2],ax
shr eax,16
mov [graph_data_l+4],al
mov [graph_data_l+7],ah
 
stdcall kernel_alloc, [_WinMapSize]
mov [_WinMapAddress], eax
 
xor eax,eax
inc eax
mov [CURRENT_TASK],eax ;dword 1
mov [TASK_COUNT],eax ;dword 1
mov [TASK_BASE],dword TASK_DATA
mov [current_slot], SLOT_BASE+256
 
; set background
 
mov [BgrDrawMode],eax
mov [BgrDataWidth],eax
mov [BgrDataHeight],eax
mov [mem_BACKGROUND], 4
mov [img_background], static_background_data
 
mov [SLOT_BASE + 256 + APPDATA.dir_table], sys_pgdir - OS_BASE
 
stdcall kernel_alloc, 0x10000/8
mov edi, eax
mov [network_free_ports], eax
or eax, -1
mov ecx, 0x10000/32
rep stosd
 
; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f
 
call rerouteirqs
 
; Initialize system V86 machine
call init_sys_v86
 
; TIMER SET TO 1/100 S
 
mov al,0x34 ; set to 100Hz
out 0x43,al
mov al,0x9b ; lsb 1193180 / 1193
out 0x40,al
mov al,0x2e ; msb
out 0x40,al
 
; Enable timer IRQ (IRQ0) and hard drives IRQs (IRQ14, IRQ15)
; they are used: when partitions are scanned, hd_read relies on timer
; Also enable IRQ2, because in some configurations
; IRQs from slave controller are not delivered until IRQ2 on master is enabled
mov al, 0xFA
out 0x21, al
mov al, 0x3F
out 0xA1, al
 
; Enable interrupts in IDE controller
mov al, 0
mov dx, 0x3F6
out dx, al
mov dl, 0x76
out dx, al
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!
include 'detect/disks.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!!
 
call Parser_params
 
; READ RAMDISK IMAGE FROM HD
 
;!!!!!!!!!!!!!!!!!!!!!!!
include 'boot/rdload.inc'
;!!!!!!!!!!!!!!!!!!!!!!!
; mov [dma_hdd],1
; CALCULATE FAT CHAIN FOR RAMDISK
 
call calculatefatchain
 
; LOAD VMODE DRIVER
 
;!!!!!!!!!!!!!!!!!!!!!!!
include 'vmodeld.inc'
;!!!!!!!!!!!!!!!!!!!!!!!
 
if 0
mov ax,[OS_BASE+0x10000+bx_from_load]
cmp ax,'r1' ; if using not ram disk, then load librares and parameters {SPraid.simba}
je no_lib_load
; LOADING LIBRARES
stdcall dll.Load,@IMPORT ; loading librares for kernel (.obj files)
call load_file_parse_table ; prepare file parse table
call set_kernel_conf ; configure devices and gui
no_lib_load:
end if
 
; LOAD FONTS I and II
 
stdcall read_file, char, FONT_I, 0, 2304
stdcall read_file, char2, FONT_II, 0, 2560
 
mov esi,boot_fonts
call boot_log
 
; PRINT AMOUNT OF MEMORY
mov esi, boot_memdetect
call boot_log
 
movzx ecx, word [boot_y]
or ecx, (10+29*6) shl 16 ; "Determining amount of memory"
sub ecx, 10
mov edx, 0xFFFFFF
mov ebx, [MEM_AMOUNT]
shr ebx, 20
xor edi,edi
mov eax, 0x00040000
inc edi
call display_number_force
 
; BUILD SCHEDULER
 
call build_scheduler ; sys32.inc
 
mov esi,boot_devices
call boot_log
 
mov [pci_access_enabled],1
 
 
; SET PRELIMINARY WINDOW STACK AND POSITIONS
 
mov esi,boot_windefs
call boot_log
call set_window_defaults
 
; SET BACKGROUND DEFAULTS
 
mov esi,boot_bgr
call boot_log
call init_background
call calculatebackground
 
; RESERVE SYSTEM IRQ'S JA PORT'S
 
mov esi,boot_resirqports
call boot_log
call reserve_irqs_ports
 
; SET PORTS FOR IRQ HANDLERS
 
;mov esi,boot_setrports
;call boot_log
;call setirqreadports
 
; SET UP OS TASK
 
mov esi,boot_setostask
call boot_log
 
xor eax, eax
mov dword [SLOT_BASE+APPDATA.fpu_state], fpu_data
mov dword [SLOT_BASE+APPDATA.exc_handler], eax
mov dword [SLOT_BASE+APPDATA.except_mask], eax
 
; name for OS/IDLE process
 
mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I'
mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE '
mov edi, [os_stack_seg]
mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi
add edi, 0x2000-512
mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi
mov dword [SLOT_BASE+256+APPDATA.saved_esp0], edi ; just for case
; [SLOT_BASE+256+APPDATA.io_map] was set earlier
 
mov esi, fpu_data
mov ecx, 512/4
cld
rep movsd
 
mov dword [SLOT_BASE+256+APPDATA.exc_handler], eax
mov dword [SLOT_BASE+256+APPDATA.except_mask], eax
 
mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET
mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx
mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx
 
mov dword [SLOT_BASE+256+APPDATA.cur_dir], sysdir_path
mov dword [SLOT_BASE+256+APPDATA.tls_base], eax
 
; task list
mov dword [TASK_DATA+TASKDATA.mem_start],eax ; process base address
inc eax
mov dword [CURRENT_TASK],eax
mov dword [TASK_COUNT],eax
mov [current_slot], SLOT_BASE+256
mov [TASK_BASE],dword TASK_DATA
mov byte[TASK_DATA+TASKDATA.wnd_number],al ; on screen number
mov dword [TASK_DATA+TASKDATA.pid], eax ; process id number
 
call init_display
mov eax, [def_cursor]
mov [SLOT_BASE+APPDATA.cursor],eax
mov [SLOT_BASE+APPDATA.cursor+256],eax
 
; READ TSC / SECOND
 
mov esi,boot_tsc
call boot_log
cli
rdtsc ;call _rdtsc
mov ecx,eax
mov esi,250 ; wait 1/4 a second
call delay_ms
rdtsc ;call _rdtsc
sti
sub eax,ecx
shl eax,2
mov [CPU_FREQ],eax ; save tsc / sec
; mov ebx, 1000000
; div ebx
; ¢®®¡é¥-â® ¯à®¨§¢®¤¨â¥«ì­®áâì ¢ ¤ ­­®¬ ª®­ªà¥â­®¬ ¬¥áâ¥
; ᮢ¥à襭­® ­¥ªà¨â¨ç­ , ­® çâ®¡ë § âª­ãâì «î¡¨â¥«¥©
; ®¯â¨¬¨§¨àãîé¨å ª®¬¯¨«ïâ®à®¢ Ÿ‚“...
mov edx, 2251799814
mul edx
shr edx, 19
mov [stall_mcs], edx
; PRINT CPU FREQUENCY
mov esi, boot_cpufreq
call boot_log
 
mov ebx, edx
movzx ecx, word [boot_y]
add ecx, (10+17*6) shl 16 - 10 ; 'CPU frequency is '
mov edx, 0xFFFFFF
xor edi,edi
mov eax, 0x00040000
inc edi
call display_number_force
 
; SET VARIABLES
 
call set_variables
 
; SET MOUSE
 
;call detect_devices
stdcall load_driver, szPS2MDriver
; stdcall load_driver, szCOM_MDriver
 
mov esi,boot_setmouse
call boot_log
call setmouse
 
 
; STACK AND FDC
 
call stack_init
call fdc_init
 
; PALETTE FOR 320x200 and 640x480 16 col
 
cmp [SCR_MODE],word 0x12
jne no_pal_vga
mov esi,boot_pal_vga
call boot_log
call paletteVGA
no_pal_vga:
 
cmp [SCR_MODE],word 0x13
jne no_pal_ega
mov esi,boot_pal_ega
call boot_log
call palette320x200
no_pal_ega:
 
; LOAD DEFAULT SKIN
 
call load_default_skin
 
;protect io permission map
 
mov esi, [default_io_map]
stdcall map_page,esi,[SLOT_BASE+256+APPDATA.io_map], PG_MAP
add esi, 0x1000
stdcall map_page,esi,[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP
 
stdcall map_page,tss._io_map_0,\
[SLOT_BASE+256+APPDATA.io_map], PG_MAP
stdcall map_page,tss._io_map_1,\
[SLOT_BASE+256+APPDATA.io_map+4], PG_MAP
 
mov ax,[OS_BASE+0x10000+bx_from_load]
cmp ax,'r1' ; if not rused ram disk - load network configuration from files {SPraid.simba}
je no_st_network
call set_network_conf
no_st_network:
 
; LOAD FIRST APPLICATION
cli
 
cmp byte [BOOT_VAR+0x9030],1
jne no_load_vrr_m
 
mov ebp, vrr_m
call fs_execute_from_sysdir
 
; cmp eax,2 ; if vrr_m app found (PID=2)
sub eax,2
jz first_app_found
 
no_load_vrr_m:
 
mov ebp, firstapp
call fs_execute_from_sysdir
 
; cmp eax,2 ; continue if a process has been loaded
sub eax,2
jz first_app_found
 
mov esi, boot_failed
call boot_log
 
mov eax, 0xDEADBEEF ; otherwise halt
hlt
 
first_app_found:
 
cli
 
;mov [TASK_COUNT],dword 2
push 1
pop dword [CURRENT_TASK] ; set OS task fisrt
 
; SET KEYBOARD PARAMETERS
mov al, 0xf6 ; reset keyboard, scan enabled
call kb_write
 
; wait until 8042 is ready
xor ecx,ecx
@@:
in al,64h
and al,00000010b
loopnz @b
 
; mov al, 0xED ; svetodiody - only for testing!
; call kb_write
; call kb_read
; mov al, 111b
; call kb_write
; call kb_read
 
mov al, 0xF3 ; set repeat rate & delay
call kb_write
; call kb_read
mov al, 0 ; 30 250 ;00100010b ; 24 500 ;00100100b ; 20 500
call kb_write
; call kb_read
;// mike.dld [
call set_lights
;// mike.dld ]
 
 
; Setup serial output console (if enabled)
 
if defined debug_com_base
 
; enable Divisor latch
 
mov dx, debug_com_base+3
mov al, 1 shl 7
out dx, al
 
; Set speed to 115200 baud (max speed)
 
mov dx, debug_com_base
mov al, 0x01
out dx, al
 
mov dx, debug_com_base+1
mov al, 0x00
out dx, al
 
; No parity, 8bits words, one stop bit, dlab bit back to 0
 
mov dx, debug_com_base+3
mov al, 3
out dx, al
 
; disable interrupts
 
mov dx, debug_com_base+1
mov al, 0
out dx, al
 
; clear + enable fifo (64 bits)
 
mov dx, debug_com_base+2
mov al, 0x7 + 1 shl 5
out dx, al
 
 
end if
 
; START MULTITASKING
 
if preboot_blogesc
mov esi, boot_tasking
call boot_log
.bll1: in al, 0x60 ; wait for ESC key press
cmp al, 129
jne .bll1
end if
 
; mov [ENABLE_TASKSWITCH],byte 1 ; multitasking enabled
 
; UNMASK ALL IRQ'S
 
; mov esi,boot_allirqs
; call boot_log
;
; cli ;guarantee forbidance of interrupts.
; mov al,0 ; unmask all irq's
; out 0xA1,al
; out 0x21,al
;
; mov ecx,32
;
; ready_for_irqs:
;
; mov al,0x20 ; ready for irqs
; out 0x20,al
; out 0xa0,al
;
; loop ready_for_irqs ; flush the queue
 
stdcall attach_int_handler, 1, irq1, 0
 
; mov [dma_hdd],1
cmp [IDEContrRegsBaseAddr], 0
setnz [dma_hdd]
mov [timer_ticks_enable],1 ; for cd driver
 
sti
call change_task
 
jmp osloop
 
; jmp $ ; wait here for timer to take control
 
; Fly :)
 
include 'unpacker.inc'
include 'fdo.inc'
 
align 4
boot_log:
pushad
 
mov ebx,10*65536
mov bx,word [boot_y]
add [boot_y],dword 10
mov ecx,0x80ffffff ; ASCIIZ string with white color
xor edi,edi
mov edx,esi
inc edi
call dtext
 
mov [novesachecksum],1000
call checkVga_N13
 
popad
 
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; MAIN OS LOOP START ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 32
osloop:
call [draw_pointer]
call window_check_events
call mouse_check_events
call checkmisc
call checkVga_N13
call stack_handler
call checkidle
call check_fdd_motor_status
call check_ATAPI_device_event
jmp osloop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; MAIN OS LOOP END ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 4
checkidle:
pushad
call change_task
jmp idle_loop_entry
idle_loop:
cmp eax,[idlemem] ; eax == [timer_ticks]
jne idle_exit
rdtsc ;call _rdtsc
mov ecx,eax
hlt
rdtsc ;call _rdtsc
sub eax,ecx
add [idleuse],eax
idle_loop_entry:
mov eax,[timer_ticks] ; eax = [timer_ticks]
cmp [check_idle_semaphore],0
je idle_loop
dec [check_idle_semaphore]
idle_exit:
mov [idlemem],eax ; eax == [timer_ticks]
popad
ret
 
uglobal
idlemem dd 0x0
idleuse dd 0x0
idleusesec dd 0x0
check_idle_semaphore dd 0x0
endg
 
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; INCLUDED SYSTEM FILES ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
include "kernel32.inc"
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; KERNEL FUNCTIONS ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
reserve_irqs_ports:
 
push eax
xor eax,eax
inc eax
mov byte [irq_owner+4*0],al ;1 ; timer
;mov [irq_owner+4*1], 1 ; keyboard
mov byte [irq_owner+4*6],al ;1 ; floppy diskette
mov byte [irq_owner+4*13],al ;1 ; math co-pros
mov byte [irq_owner+4*14],al ;1 ; ide I
mov byte [irq_owner+4*15],al ;1 ; ide II
pop eax
 
; RESERVE PORTS
push 4
pop dword [RESERVED_PORTS] ;,edi
 
push 1
pop dword [RESERVED_PORTS+16+0] ;,dword 1
and dword [RESERVED_PORTS+16+4],0 ;,dword 0x0
mov dword [RESERVED_PORTS+16+8],0x2d ;,dword 0x2d
 
push 1
pop dword [RESERVED_PORTS+32+0] ;,dword 1
push 0x30
pop dword [RESERVED_PORTS+32+4] ;,dword 0x30
push 0x4d
pop dword [RESERVED_PORTS+32+8] ;,dword 0x4d
 
push 1
pop dword [RESERVED_PORTS+48+0] ;,dword 1
push 0x50
pop dword [RESERVED_PORTS+48+4] ;,dword 0x50
mov dword [RESERVED_PORTS+48+8],0xdf ;,dword 0xdf
 
push 1
pop dword [RESERVED_PORTS+64+0] ;,dword 1
 
mov dword [RESERVED_PORTS+64+4],0xe5 ;,dword 0xe5
mov dword [RESERVED_PORTS+64+8],0xff ;,dword 0xff
 
ret
 
setirqreadports:
 
mov [irq12read+0],dword 0x60 + 0x01000000 ; read port 0x60 , byte
and dword [irq12read+4],0 ; end of port list
; mov [irq12read+4],dword 0 ; end of port list
;mov [irq04read+0],dword 0x3f8 + 0x01000000 ; read port 0x3f8 , byte
;mov [irq04read+4],dword 0 ; end of port list
;mov [irq03read+0],dword 0x2f8 + 0x01000000 ; read port 0x2f8 , byte
;mov [irq03read+4],dword 0 ; end of port list
 
ret
 
iglobal
process_number dd 0x1
endg
 
set_variables:
 
mov ecx,0x100 ; flush port 0x60
.fl60: in al,0x60
loop .fl60
push eax
 
mov ax,[BOOT_VAR+0x900c]
shr ax,1
shl eax,16
mov ax,[BOOT_VAR+0x900A]
shr ax,1
mov [MOUSE_X],eax
 
xor eax,eax
mov [BTN_ADDR],dword BUTTON_INFO ; address of button list
 
mov byte [MOUSE_BUFF_COUNT],al ; mouse buffer
mov byte [KEY_COUNT],al ; keyboard buffer
mov byte [BTN_COUNT],al ; button buffer
; mov [MOUSE_X],dword 100*65536+100 ; mouse x/y
 
;!! IP 04.02.2005:
mov byte [DONT_SWITCH],al ; change task if possible
pop eax
ret
 
align 4
;input eax=43,bl-byte of output, ecx - number of port
sys_outport:
 
mov edi,ecx ; separate flag for read / write
and ecx,65535
 
mov eax,[RESERVED_PORTS]
test eax,eax
jnz .sopl8
inc eax
mov [esp+32],eax
ret
 
.sopl8:
mov edx,[TASK_BASE]
mov edx,[edx+0x4]
;and ecx,65535
;cld - set on interrupt 0x40
.sopl1:
 
mov esi,eax
shl esi,4
add esi,RESERVED_PORTS
cmp edx,[esi+0]
jne .sopl2
cmp ecx,[esi+4]
jb .sopl2
cmp ecx,[esi+8]
jg .sopl2
.sopl3:
 
test edi,0x80000000 ; read ?
jnz .sopl4
 
mov eax,ebx
mov dx,cx ; write
out dx,al
and [esp+32],dword 0
ret
 
.sopl2:
 
dec eax
jnz .sopl1
inc eax
mov [esp+32],eax
ret
 
.sopl4:
 
mov dx,cx ; read
in al,dx
and eax,0xff
and [esp+32],dword 0
mov [esp+20],eax
ret
 
display_number:
;It is not optimization
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, esi
mov esi, edi
; eax = print type, al=0 -> ebx is number
; al=1 -> ebx is pointer
; ah=0 -> display decimal
; ah=1 -> display hexadecimal
; ah=2 -> display binary
; eax bits 16-21 = number of digits to display (0-32)
; eax bits 22-31 = reserved
;
; ebx = number or pointer
; ecx = x shl 16 + y
; edx = color
xor edi, edi
display_number_force:
push eax
and eax,0x3fffffff
cmp eax,0xffff ; length > 0 ?
pop eax
jge cont_displ
ret
cont_displ:
push eax
and eax,0x3fffffff
cmp eax,61*0x10000 ; length <= 60 ?
pop eax
jb cont_displ2
ret
cont_displ2:
 
pushad
 
cmp al,1 ; ecx is a pointer ?
jne displnl1
mov ebp,ebx
add ebp,4
mov ebp,[ebp+std_application_base_address]
mov ebx,[ebx+std_application_base_address]
displnl1:
sub esp,64
 
test ah,ah ; DECIMAL
jnz no_display_desnum
shr eax,16
and eax,0xC03f
; and eax,0x3f
push eax
and eax,0x3f
mov edi,esp
add edi,4+64-1
mov ecx,eax
mov eax,ebx
mov ebx,10
d_desnum:
xor edx,edx
call division_64_bits
div ebx
add dl,48
mov [edi],dl
dec edi
loop d_desnum
pop eax
call normalize_number
call draw_num_text
add esp,64
popad
ret
no_display_desnum:
 
cmp ah,0x01 ; HEXADECIMAL
jne no_display_hexnum
shr eax,16
and eax,0xC03f
; and eax,0x3f
push eax
and eax,0x3f
mov edi,esp
add edi,4+64-1
mov ecx,eax
mov eax,ebx
mov ebx,16
d_hexnum:
xor edx,edx
call division_64_bits
div ebx
hexletters = __fdo_hexdigits
add edx,hexletters
mov dl,[edx]
mov [edi],dl
dec edi
loop d_hexnum
pop eax
call normalize_number
call draw_num_text
add esp,64
popad
ret
no_display_hexnum:
 
cmp ah,0x02 ; BINARY
jne no_display_binnum
shr eax,16
and eax,0xC03f
; and eax,0x3f
push eax
and eax,0x3f
mov edi,esp
add edi,4+64-1
mov ecx,eax
mov eax,ebx
mov ebx,2
d_binnum:
xor edx,edx
call division_64_bits
div ebx
add dl,48
mov [edi],dl
dec edi
loop d_binnum
pop eax
call normalize_number
call draw_num_text
add esp,64
popad
ret
no_display_binnum:
 
add esp,64
popad
ret
 
normalize_number:
test ah,0x80
jz .continue
mov ecx,48
and eax,0x3f
@@:
inc edi
cmp [edi],cl
jne .continue
dec eax
cmp eax,1
ja @r
mov al,1
.continue:
and eax,0x3f
ret
 
division_64_bits:
test [esp+1+4],byte 0x40
jz .continue
push eax
mov eax,ebp
div ebx
mov ebp,eax
pop eax
.continue:
ret
 
draw_num_text:
mov esi,eax
mov edx,64+4
sub edx,eax
add edx,esp
mov ebx,[esp+64+32-8+4]
; add window start x & y
mov ecx,[TASK_BASE]
 
mov edi,[CURRENT_TASK]
shl edi,8
 
mov eax,[ecx-twdw+WDATA.box.left]
add eax,[edi+SLOT_BASE+APPDATA.wnd_clientbox.left]
shl eax,16
add eax,[ecx-twdw+WDATA.box.top]
add eax,[edi+SLOT_BASE+APPDATA.wnd_clientbox.top]
add ebx,eax
mov ecx,[esp+64+32-12+4]
and ecx, not 0x80000000 ; force counted string
mov eax, [esp+64+8] ; background color (if given)
mov edi, [esp+64+4]
jmp dtext
 
align 4
 
sys_setup:
 
; 1=roland mpu midi base , base io address
; 2=keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus
; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave
; 5=system language, 1eng 2fi 3ger 4rus
; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave
; 8=fat32 partition in hd
; 9
; 10 = sound dma channel
; 11 = enable lba read
; 12 = enable pci access
 
 
and [esp+32],dword 0
dec ebx ; MIDI
jnz nsyse1
cmp ecx,0x100
 
jb nsyse1
mov esi,65535
cmp esi,ecx
 
jb nsyse1
mov [midi_base],cx ;bx
mov word [mididp],cx ;bx
inc cx ;bx
mov word [midisp],cx ;bx
ret
 
iglobal
midi_base dw 0
endg
 
nsyse1:
dec ebx ; KEYBOARD
jnz nsyse2
mov edi,[TASK_BASE]
mov eax,[edi+TASKDATA.mem_start]
add eax,edx
 
dec ecx
jnz kbnobase
mov ebx,keymap
mov ecx,128
call memmove
ret
kbnobase:
dec ecx
jnz kbnoshift
 
mov ebx,keymap_shift
mov ecx,128
call memmove
ret
kbnoshift:
dec ecx
jnz kbnoalt
mov ebx,keymap_alt
mov ecx,128
call memmove
ret
kbnoalt:
sub ecx,6
jnz kbnocountry
mov word [keyboard],dx
ret
kbnocountry:
mov [esp+32],dword 1
ret
nsyse2:
dec ebx ; CD
jnz nsyse4
 
test ecx,ecx
jz nosesl
 
cmp ecx, 4
ja nosesl
mov [cd_base],cl
 
dec ecx
jnz noprma
mov [cdbase],0x1f0
mov [cdid],0xa0
noprma:
 
dec ecx
jnz noprsl
mov [cdbase],0x1f0
mov [cdid],0xb0
noprsl:
dec ecx
jnz nosema
mov [cdbase],0x170
mov [cdid],0xa0
nosema:
dec ecx
jnz nosesl
mov [cdbase],0x170
mov [cdid],0xb0
nosesl:
ret
 
iglobal
cd_base db 0
 
endg
nsyse4:
sub ebx,2 ; SYSTEM LANGUAGE
jnz nsyse5
mov [syslang],ecx
ret
nsyse5:
sub ebx,2 ; HD BASE
jnz nsyse7
 
test ecx,ecx
jz nosethd
 
cmp ecx,4
ja nosethd
mov [hd_base],cl
 
cmp ecx,1
jnz noprmahd
mov [hdbase],0x1f0
and dword [hdid],0x0
mov dword [hdpos],ecx
; call set_FAT32_variables
noprmahd:
 
cmp ecx,2
jnz noprslhd
mov [hdbase],0x1f0
mov [hdid],0x10
mov dword [hdpos],ecx
; call set_FAT32_variables
noprslhd:
 
cmp ecx,3
jnz nosemahd
mov [hdbase],0x170
and dword [hdid],0x0
mov dword [hdpos],ecx
; call set_FAT32_variables
nosemahd:
 
cmp ecx,4
jnz noseslhd
mov [hdbase],0x170
mov [hdid],0x10
mov dword [hdpos],ecx
; call set_FAT32_variables
noseslhd:
call reserve_hd1
call reserve_hd_channel
call free_hd_channel
and dword [hd1_status],0 ; free
nosethd:
ret
 
iglobal
hd_base db 0
endg
 
nsyse7:
 
; cmp eax,8 ; HD PARTITION
dec ebx
jnz nsyse8
mov [fat32part],ecx
; call set_FAT32_variables
call reserve_hd1
call reserve_hd_channel
call free_hd_channel
; pusha
call choice_necessity_partition_1
; popa
and dword [hd1_status],0 ; free
ret
 
nsyse8:
; cmp eax,11 ; ENABLE LBA READ
and ecx,1
sub ebx,3
jnz no_set_lba_read
mov [lba_read_enabled],ecx
ret
 
no_set_lba_read:
; cmp eax,12 ; ENABLE PCI ACCESS
dec ebx
jnz no_set_pci_access
mov [pci_access_enabled],ecx
ret
no_set_pci_access:
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
include 'vmodeint.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
sys_setup_err:
or [esp+32],dword -1
ret
 
align 4
 
sys_getsetup:
 
; 1=roland mpu midi base , base io address
; 2=keyboard 1, base kaybap 2, shift keymap, 9 country 1eng 2fi 3ger 4rus
; 3=cd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave
; 5=system language, 1eng 2fi 3ger 4rus
; 7=hd base 1, pri.master 2, pri slave 3 sec master, 4 sec slave
; 8=fat32 partition in hd
; 9=get hs timer tic
 
; cmp eax,1
dec ebx
jnz ngsyse1
movzx eax,[midi_base]
mov [esp+32],eax
ret
ngsyse1:
; cmp eax,2
dec ebx
jnz ngsyse2
 
mov edi,[TASK_BASE]
mov ebx,[edi+TASKDATA.mem_start]
add ebx,edx
 
; cmp ebx,1
dec ecx
jnz kbnobaseret
mov eax,keymap
mov ecx,128
call memmove
ret
kbnobaseret:
; cmp ebx,2
dec ecx
jnz kbnoshiftret
 
mov eax,keymap_shift
mov ecx,128
call memmove
ret
kbnoshiftret:
; cmp ebx,3
dec ecx
jne kbnoaltret
 
mov eax,keymap_alt
mov ecx,128
call memmove
ret
kbnoaltret:
; cmp ebx,9
sub ecx,6
jnz ngsyse2
movzx eax,word [keyboard]
mov [esp+32],eax
ret
 
 
ngsyse2:
; cmp eax,3
dec ebx
jnz ngsyse3
movzx eax,[cd_base]
mov [esp+32],eax
ret
ngsyse3:
; cmp eax,5
sub ebx,2
jnz ngsyse5
mov eax,[syslang]
mov [esp+32],eax
ret
ngsyse5:
; cmp eax,7
sub ebx,2
jnz ngsyse7
movzx eax,[hd_base]
mov [esp+32],eax
ret
ngsyse7:
; cmp eax,8
dec ebx
jnz ngsyse8
mov eax,[fat32part]
mov [esp+32],eax
ret
ngsyse8:
; cmp eax,9
dec ebx
jnz ngsyse9
mov eax,[timer_ticks] ;[0xfdf0]
mov [esp+32],eax
ret
ngsyse9:
; cmp eax,11
sub ebx,2
jnz ngsyse11
mov eax,[lba_read_enabled]
mov [esp+32],eax
ret
ngsyse11:
; cmp eax,12
dec ebx
jnz ngsyse12
mov eax,[pci_access_enabled]
mov [esp+32],eax
ret
ngsyse12:
mov [esp+32],dword 1
ret
 
get_timer_ticks:
mov eax,[timer_ticks]
ret
 
iglobal
align 4
mousefn dd msscreen, mswin, msbutton, msset
dd app_load_cursor
dd app_set_cursor
dd app_delete_cursor
dd msz
endg
 
readmousepos:
 
; eax=0 screen relative
; eax=1 window relative
; eax=2 buttons pressed
; eax=3 set mouse pos ; reserved
; eax=4 load cursor
; eax=5 set cursor
; eax=6 delete cursor ; reserved
; eax=7 get mouse_z
 
cmp ebx, 7
ja msset
jmp [mousefn+ebx*4]
msscreen:
mov eax,[MOUSE_X]
shl eax,16
mov ax,[MOUSE_Y]
mov [esp+36-4],eax
ret
mswin:
mov eax,[MOUSE_X]
shl eax,16
mov ax,[MOUSE_Y]
mov esi,[TASK_BASE]
mov bx, word [esi-twdw+WDATA.box.left]
shl ebx,16
mov bx, word [esi-twdw+WDATA.box.top]
sub eax,ebx
 
mov edi,[CURRENT_TASK]
shl edi,8
sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top]
rol eax,16
sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left]
rol eax,16
mov [esp+36-4],eax
ret
msbutton:
movzx eax,byte [BTN_DOWN]
mov [esp+36-4],eax
ret
msz:
mov edi, [TASK_COUNT]
movzx edi, word [WIN_POS + edi*2]
cmp edi, [CURRENT_TASK]
jne @f
mov ax,[MOUSE_SCROLL_H]
shl eax,16
mov ax,[MOUSE_SCROLL_V]
mov [esp+36-4],eax
and [MOUSE_SCROLL_H],word 0
and [MOUSE_SCROLL_V],word 0
ret
@@:
and [esp+36-4],dword 0
; ret
msset:
ret
 
app_load_cursor:
cmp ecx, OS_BASE
jae msset
stdcall load_cursor, ecx, edx
mov [esp+36-4], eax
ret
 
app_set_cursor:
stdcall set_cursor, ecx
mov [esp+36-4], eax
ret
 
app_delete_cursor:
stdcall delete_cursor, ecx
mov [esp+36-4], eax
ret
 
is_input:
 
push edx
mov dx,word [midisp]
in al,dx
and al,0x80
pop edx
ret
 
is_output:
 
push edx
mov dx,word [midisp]
in al,dx
and al,0x40
pop edx
ret
 
 
get_mpu_in:
 
push edx
mov dx,word [mididp]
in al,dx
pop edx
ret
 
 
put_mpu_out:
 
push edx
mov dx,word [mididp]
out dx,al
pop edx
ret
 
 
 
align 4
 
sys_midi:
cmp [mididp],0
jnz sm0
mov [esp+36],dword 1
ret
sm0:
and [esp+36],dword 0
dec ebx
jnz smn1
; call setuart
su1:
call is_output
test al,al
jnz su1
mov dx,word [midisp]
mov al,0xff
out dx,al
su2:
mov dx,word [midisp]
mov al,0xff
out dx,al
call is_input
test al,al
jnz su2
call get_mpu_in
cmp al,0xfe
jnz su2
su3:
call is_output
test al,al
jnz su3
mov dx,word [midisp]
mov al,0x3f
out dx,al
ret
smn1:
dec ebx
jnz smn2
sm10:
call get_mpu_in
call is_output
test al,al
jnz sm10
mov al,bl
call put_mpu_out
smn2:
ret
 
detect_devices:
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;include 'detect/commouse.inc'
;include 'detect/ps2mouse.inc'
;include 'detect/dev_fd.inc'
;include 'detect/dev_hdcd.inc'
;include 'detect/sear_par.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ret
 
sys_end:
 
mov ecx, [current_slot]
mov eax, [ecx+APPDATA.tls_base]
test eax, eax
jz @F
 
stdcall user_free, eax
@@:
 
mov eax,[TASK_BASE]
mov [eax+TASKDATA.state], 3 ; terminate this program
 
waitterm: ; wait here for termination
mov ebx,100
call delay_hs
jmp waitterm
 
iglobal
align 4
sys_system_table:
dd exit_for_anyone ; 1 = obsolete
dd sysfn_terminate ; 2 = terminate thread
dd sysfn_activate ; 3 = activate window
dd sysfn_getidletime ; 4 = get idle time
dd sysfn_getcpuclock ; 5 = get cpu clock
dd sysfn_saveramdisk ; 6 = save ramdisk
dd sysfn_getactive ; 7 = get active window
dd sysfn_sound_flag ; 8 = get/set sound_flag
dd sysfn_shutdown ; 9 = shutdown with parameter
dd sysfn_minimize ; 10 = minimize window
dd sysfn_getdiskinfo ; 11 = get disk subsystem info
dd sysfn_lastkey ; 12 = get last pressed key
dd sysfn_getversion ; 13 = get kernel version
dd sysfn_waitretrace ; 14 = wait retrace
dd sysfn_centermouse ; 15 = center mouse cursor
dd sysfn_getfreemem ; 16 = get free memory size
dd sysfn_getallmem ; 17 = get total memory size
dd sysfn_terminate2 ; 18 = terminate thread using PID
; instead of slot
dd sysfn_mouse_acceleration; 19 = set/get mouse acceleration
dd sysfn_meminfo ; 20 = get extended memory info
dd sysfn_pid_to_slot ; 21 = get slot number for pid
dd sysfn_min_rest_window ; 22 = minimize and restore any window
sysfn_num = ($ - sys_system_table)/4
endg
 
sys_system:
dec ebx
cmp ebx, sysfn_num
jae @f
jmp dword [sys_system_table + ebx*4]
@@:
ret
 
 
sysfn_shutdown: ; 18.9 = system shutdown
cmp ecx,1
jl exit_for_anyone
cmp ecx,4
jg exit_for_anyone
mov [BOOT_VAR+0x9030],cl
 
mov eax,[TASK_COUNT]
mov [SYS_SHUTDOWN],al
mov [shutdown_processes],eax
and dword [esp+32], 0
exit_for_anyone:
ret
uglobal
shutdown_processes: dd 0x0
endg
 
sysfn_terminate: ; 18.2 = TERMINATE
cmp ecx,2
jb noprocessterminate
mov edx,[TASK_COUNT]
cmp ecx,edx
ja noprocessterminate
mov eax,[TASK_COUNT]
shl ecx,5
mov edx,[ecx+CURRENT_TASK+TASKDATA.pid]
add ecx,CURRENT_TASK+TASKDATA.state
cmp byte [ecx], 9
jz noprocessterminate
 
;call MEM_Heap_Lock ;guarantee that process isn't working with heap
mov [ecx],byte 3 ; clear possible i40's
;call MEM_Heap_UnLock
 
cmp edx,[application_table_status] ; clear app table stat
jne noatsc
and [application_table_status],0
noatsc:
noprocessterminate:
ret
 
sysfn_terminate2:
;lock application_table_status mutex
.table_status:
cli
cmp [application_table_status],0
je .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
mov eax,ecx
call pid_to_slot
test eax,eax
jz .not_found
mov ecx,eax
cli
call sysfn_terminate
and [application_table_status],0
sti
and dword [esp+32],0
ret
.not_found:
mov [application_table_status],0
or dword [esp+32],-1
ret
 
sysfn_activate: ; 18.3 = ACTIVATE WINDOW
cmp ecx,2
jb .nowindowactivate
cmp ecx,[TASK_COUNT]
ja .nowindowactivate
 
mov [window_minimize], 2 ; restore window if minimized
 
movzx esi, word [WIN_STACK + ecx*2]
cmp esi, [TASK_COUNT]
je .nowindowactivate ; already active
 
mov edi, ecx
shl edi, 5
add edi, window_data
movzx esi, word [WIN_STACK + ecx * 2]
lea esi, [WIN_POS + esi * 2]
call waredraw
.nowindowactivate:
ret
 
sysfn_getidletime: ; 18.4 = GET IDLETIME
mov eax,[idleusesec]
mov [esp+32], eax
ret
 
sysfn_getcpuclock: ; 18.5 = GET TSC/SEC
mov eax,[CPU_FREQ]
mov [esp+32], eax
ret
 
; SAVE ramdisk to /hd/1/menuet.img
;!!!!!!!!!!!!!!!!!!!!!!!!
include 'blkdev/rdsave.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!
align 4
sysfn_getactive: ; 18.7 = get active window
mov eax, [TASK_COUNT]
movzx eax, word [WIN_POS + eax*2]
mov [esp+32],eax
ret
 
sysfn_sound_flag: ; 18.8 = get/set sound_flag
; cmp ecx,1
dec ecx
jnz nogetsoundflag
movzx eax,byte [sound_flag] ; get sound_flag
mov [esp+32],eax
ret
nogetsoundflag:
; cmp ecx,2
dec ecx
jnz nosoundflag
xor byte [sound_flag], 1
nosoundflag:
ret
 
sysfn_minimize: ; 18.10 = minimize window
mov [window_minimize],1
ret
align 4
sysfn_getdiskinfo: ; 18.11 = get disk info table
; cmp ecx,1
dec ecx
jnz full_table
small_table:
call for_all_tables
mov ecx,10
cld
rep movsb
ret
for_all_tables:
mov edi,edx
mov esi,DRIVE_DATA
ret
full_table:
; cmp ecx,2
dec ecx
jnz exit_for_anyone
call for_all_tables
mov ecx,16384
cld
rep movsd
ret
 
sysfn_lastkey: ; 18.12 = return 0 (backward compatibility)
and dword [esp+32], 0
ret
 
sysfn_getversion: ; 18.13 = get kernel ID and version
mov edi,ecx
mov esi,version_inf
mov ecx,version_end-version_inf
rep movsb
ret
 
sysfn_waitretrace: ; 18.14 = sys wait retrace
;wait retrace functions
sys_wait_retrace:
mov edx,0x3da
WaitRetrace_loop:
in al,dx
test al,1000b
jz WaitRetrace_loop
and [esp+32],dword 0
ret
 
align 4
sysfn_centermouse: ; 18.15 = mouse centered
; removed here by <Lrz>
; call mouse_centered
;* mouse centered - start code- Mario79
;mouse_centered:
; push eax
mov eax,[Screen_Max_X]
shr eax,1
mov [MOUSE_X],ax
mov eax,[Screen_Max_Y]
shr eax,1
mov [MOUSE_Y],ax
; ret
;* mouse centered - end code- Mario79
xor eax,eax
and [esp+32],eax
; pop eax
 
ret
align 4
sysfn_mouse_acceleration: ; 18.19 = set/get mouse features
test ecx,ecx ; get mouse speed factor
jnz .set_mouse_acceleration
xor eax,eax
mov ax,[mouse_speed_factor]
mov [esp+32],eax
ret
.set_mouse_acceleration:
; cmp ecx,1 ; set mouse speed factor
dec ecx
jnz .get_mouse_delay
mov [mouse_speed_factor],dx
ret
.get_mouse_delay:
; cmp ecx,2 ; get mouse delay
dec ecx
jnz .set_mouse_delay
mov eax,[mouse_delay]
mov [esp+32],eax
ret
.set_mouse_delay:
; cmp ecx,3 ; set mouse delay
dec ecx
jnz .set_pointer_position
mov [mouse_delay],edx
ret
.set_pointer_position:
; cmp ecx,4 ; set mouse pointer position
dec ecx
jnz .set_mouse_button
cmp dx, word[Screen_Max_Y]
ja .end
rol edx,16
cmp dx, word[Screen_Max_X]
ja .end
mov [MOUSE_X], edx
ret
.set_mouse_button:
; cmp ecx,5 ; set mouse button features
dec ecx
jnz .end
mov [BTN_DOWN],dl
mov [mouse_active],1
.end:
ret
 
sysfn_getfreemem:
mov eax, [pg_data.pages_free]
shl eax, 2
mov [esp+32],eax
ret
 
sysfn_getallmem:
mov eax,[MEM_AMOUNT]
shr eax, 10
mov [esp+32],eax
ret
 
; // Alver, 2007-22-08 // {
sysfn_pid_to_slot:
mov eax, ecx
call pid_to_slot
mov [esp+32], eax
ret
 
sysfn_min_rest_window:
pushad
mov eax, edx ; ebx - operating
shr ecx, 1
jnc @f
call pid_to_slot
@@:
or eax, eax ; eax - number of slot
jz .error
cmp eax, 255 ; varify maximal slot number
ja .error
movzx eax, word [WIN_STACK + eax*2]
shr ecx, 1
jc .restore
; .minimize:
call minimize_window
jmp .exit
.restore:
call restore_minimized_window
.exit:
popad
xor eax, eax
mov [esp+32], eax
ret
.error:
popad
xor eax, eax
dec eax
mov [esp+32], eax
ret
; } \\ Alver, 2007-22-08 \\
 
uglobal
;// mike.dld, 2006-29-01 [
screen_workarea RECT
;// mike.dld, 2006-29-01 ]
window_minimize db 0
sound_flag db 0
endg
 
iglobal
version_inf:
db 0,7,7,0 ; version 0.7.7.0
db UID_KOLIBRI
dd __REV__
version_end:
endg
 
UID_NONE=0
UID_MENUETOS=1 ;official
UID_KOLIBRI=2 ;russian
 
sys_cachetodiskette:
cmp ebx, 1
jne .no_floppy_a_save
mov [flp_number], 1
jmp .save_image_on_floppy
.no_floppy_a_save:
cmp ebx, 2
jne .no_floppy_b_save
mov [flp_number], 2
.save_image_on_floppy:
call save_image
mov [esp + 32], dword 0
cmp [FDC_Status], 0
je .yes_floppy_save
.no_floppy_b_save:
mov [esp + 32], dword 1
.yes_floppy_save:
ret
 
uglobal
; bgrchanged dd 0x0
align 4
bgrlockpid dd 0
bgrlock db 0
endg
 
sys_background:
 
cmp ebx,1 ; BACKGROUND SIZE
jnz nosb1
test ecx,ecx
; cmp ecx,0
jz sbgrr
test edx,edx
; cmp edx,0
jz sbgrr
@@:
;;Maxis use atomic bts for mutexes 4.4.2009
bts dword [bgrlock], 0
jnc @f
call change_task
jmp @b
@@:
mov [BgrDataWidth],ecx
mov [BgrDataHeight],edx
; mov [bgrchanged],1
 
pushad
; return memory for old background
mov eax, [img_background]
cmp eax, static_background_data
jz @f
stdcall kernel_free, eax
@@:
; calculate RAW size
xor eax,eax
inc eax
cmp [BgrDataWidth],eax
jae @f
mov [BgrDataWidth],eax
@@:
cmp [BgrDataHeight],eax
jae @f
mov [BgrDataHeight],eax
@@:
mov eax,[BgrDataWidth]
imul eax,[BgrDataHeight]
lea eax,[eax*3]
mov [mem_BACKGROUND],eax
; get memory for new background
stdcall kernel_alloc, eax
test eax, eax
jz .memfailed
mov [img_background], eax
jmp .exit
.memfailed:
; revert to static monotone data
mov [img_background], static_background_data
xor eax, eax
inc eax
mov [BgrDataWidth], eax
mov [BgrDataHeight], eax
mov [mem_BACKGROUND], 4
.exit:
popad
mov [bgrlock], 0
 
sbgrr:
ret
 
nosb1:
 
cmp ebx,2 ; SET PIXEL
jnz nosb2
 
mov eax, [img_background]
test ecx, ecx
jz @f
cmp eax, static_background_data
jz .ret
@@:
mov ebx, [mem_BACKGROUND]
add ebx, 4095
and ebx, -4096
sub ebx, 4
cmp ecx, ebx
ja .ret
 
mov ebx,[eax+ecx]
and ebx,0xFF000000 ;255*256*256*256
and edx,0x00FFFFFF ;255*256*256+255*256+255
add edx,ebx
mov [eax+ecx],edx
.ret:
ret
nosb2:
 
cmp ebx,3 ; DRAW BACKGROUND
jnz nosb3
draw_background_temp:
; cmp [bgrchanged],1 ;0
; je nosb31
;draw_background_temp:
; mov [bgrchanged],1 ;0
mov [background_defined], 1
mov byte[BACKGROUND_CHANGED], 1
call force_redraw_background
nosb31:
ret
nosb3:
 
cmp ebx,4 ; TILED / STRETCHED
jnz nosb4
cmp ecx,[BgrDrawMode]
je nosb41
mov [BgrDrawMode],ecx
; mov [bgrchanged],1
nosb41:
ret
nosb4:
 
cmp ebx,5 ; BLOCK MOVE TO BGR
jnz nosb5
cmp [img_background], static_background_data
jnz @f
test edx, edx
jnz .fin
cmp esi, 4
ja .fin
@@:
; bughere
mov eax, ecx
mov ebx, edx
add ebx, [img_background] ;IMG_BACKGROUND
mov ecx, esi
call memmove
.fin:
ret
nosb5:
 
cmp ebx, 6
jnz nosb6
;;Maxis use atomic bts for mutex 4.4.2009
@@:
bts dword [bgrlock], 0
jnc @f
call change_task
jmp @b
@@:
mov eax, [CURRENT_TASK]
mov [bgrlockpid], eax
cmp [img_background], static_background_data
jz .nomem
stdcall user_alloc, [mem_BACKGROUND]
mov [esp+32], eax
test eax, eax
jz .nomem
mov ebx, eax
shr ebx, 12
or dword [page_tabs+(ebx-1)*4], DONT_FREE_BLOCK
mov esi, [img_background]
shr esi, 12
mov ecx, [mem_BACKGROUND]
add ecx, 0xFFF
shr ecx, 12
.z:
mov eax, [page_tabs+ebx*4]
test al, 1
jz @f
call free_page
@@:
mov eax, [page_tabs+esi*4]
or al, PG_UW
mov [page_tabs+ebx*4], eax
mov eax, ebx
shl eax, 12
invlpg [eax]
inc ebx
inc esi
loop .z
ret
.nomem:
and [bgrlockpid], 0
mov [bgrlock], 0
nosb6:
cmp ebx, 7
jnz nosb7
cmp [bgrlock], 0
jz .err
mov eax, [CURRENT_TASK]
cmp [bgrlockpid], eax
jnz .err
mov eax, ecx
mov ebx, ecx
shr eax, 12
mov ecx, [page_tabs+(eax-1)*4]
test cl, USED_BLOCK+DONT_FREE_BLOCK
jz .err
jnp .err
push eax
shr ecx, 12
dec ecx
@@:
and dword [page_tabs+eax*4], 0
mov edx, eax
shl edx, 12
push eax
invlpg [edx]
pop eax
inc eax
loop @b
pop eax
and dword [page_tabs+(eax-1)*4], not DONT_FREE_BLOCK
stdcall user_free, ebx
mov [esp+32], eax
and [bgrlockpid], 0
mov [bgrlock], 0
ret
.err:
and dword [esp+32], 0
ret
 
nosb7:
ret
 
force_redraw_background:
and [draw_data+32 + RECT.left], 0
and [draw_data+32 + RECT.top], 0
push eax ebx
mov eax,[Screen_Max_X]
mov ebx,[Screen_Max_Y]
mov [draw_data+32 + RECT.right],eax
mov [draw_data+32 + RECT.bottom],ebx
pop ebx eax
inc byte[REDRAW_BACKGROUND]
ret
 
align 4
 
sys_getbackground:
; cmp eax,1 ; SIZE
dec ebx
jnz nogb1
mov eax,[BgrDataWidth]
shl eax,16
mov ax,[BgrDataHeight]
mov [esp+32],eax
ret
 
nogb1:
; cmp eax,2 ; PIXEL
dec ebx
jnz nogb2
 
mov eax, [img_background]
test ecx, ecx
jz @f
cmp eax, static_background_data
jz .ret
@@:
mov ebx, [mem_BACKGROUND]
add ebx, 4095
and ebx, -4096
sub ebx, 4
cmp ecx, ebx
ja .ret
 
mov eax,[ecx+eax]
 
and eax, 0xFFFFFF
mov [esp+32],eax
.ret:
ret
nogb2:
 
; cmp eax,4 ; TILED / STRETCHED
dec ebx
dec ebx
jnz nogb4
mov eax,[BgrDrawMode]
nogb4:
mov [esp+32],eax
ret
 
align 4
 
sys_getkey:
mov [esp + 32],dword 1
; test main buffer
mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK
movzx ecx, word [WIN_STACK + ebx * 2]
mov edx, [TASK_COUNT]
cmp ecx, edx
jne .finish
cmp [KEY_COUNT], byte 0
je .finish
movzx eax, byte [KEY_BUFF]
shl eax, 8
push eax
dec byte [KEY_COUNT]
and byte [KEY_COUNT], 127
movzx ecx, byte [KEY_COUNT]
add ecx, 2
mov eax, KEY_BUFF + 1
mov ebx, KEY_BUFF
call memmove
pop eax
.ret_eax:
mov [esp + 32], eax
ret
.finish:
; test hotkeys buffer
mov ecx, hotkey_buffer
@@:
cmp [ecx], ebx
jz .found
add ecx, 8
cmp ecx, hotkey_buffer + 120 * 8
jb @b
ret
.found:
mov ax, [ecx + 6]
shl eax, 16
mov ah, [ecx + 4]
mov al, 2
and dword [ecx + 4], 0
and dword [ecx], 0
jmp .ret_eax
 
align 4
 
sys_getbutton:
 
mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK
mov [esp + 32], dword 1
movzx ecx, word [WIN_STACK + ebx * 2]
mov edx, [TASK_COUNT] ; less than 256 processes
cmp ecx, edx
jne .exit
movzx eax, byte [BTN_COUNT]
test eax, eax
jz .exit
mov eax, [BTN_BUFF]
and al, 0xFE ; delete left button bit
mov [BTN_COUNT], byte 0
mov [esp + 32], eax
.exit:
ret
 
 
align 4
 
sys_cpuusage:
 
; RETURN:
;
; +00 dword process cpu usage
; +04 word position in windowing stack
; +06 word windowing stack value at current position (cpu nro)
; +10 12 bytes name
; +22 dword start in mem
; +26 dword used mem
; +30 dword PID , process idenfification number
;
 
cmp ecx,-1 ; who am I ?
jne .no_who_am_i
mov ecx,[CURRENT_TASK]
.no_who_am_i:
cmp ecx, max_processes
ja .nofillbuf
 
; +4: word: position of the window of thread in the window stack
mov ax, [WIN_STACK + ecx * 2]
mov [ebx+4], ax
; +6: word: number of the thread slot, which window has in the window stack
; position ecx (has no relation to the specific thread)
mov ax, [WIN_POS + ecx * 2]
mov [ebx+6], ax
 
shl ecx, 5
 
; +0: dword: memory usage
mov eax, [ecx+CURRENT_TASK+TASKDATA.cpu_usage]
mov [ebx], eax
; +10: 11 bytes: name of the process
push ecx
lea eax, [ecx*8+SLOT_BASE+APPDATA.app_name]
add ebx, 10
mov ecx, 11
call memmove
pop ecx
 
; +22: address of the process in memory
; +26: size of used memory - 1
push edi
lea edi, [ebx+12]
xor eax, eax
mov edx, 0x100000*16
cmp ecx, 1 shl 5
je .os_mem
mov edx, [SLOT_BASE+ecx*8+APPDATA.mem_size]
mov eax, std_application_base_address
.os_mem:
stosd
lea eax, [edx-1]
stosd
 
; +30: PID/TID
mov eax, [ecx+CURRENT_TASK+TASKDATA.pid]
stosd
 
; window position and size
push esi
lea esi, [ecx + window_data + WDATA.box]
movsd
movsd
movsd
movsd
 
; Process state (+50)
mov eax, dword [ecx+CURRENT_TASK+TASKDATA.state]
stosd
 
; Window client area box
lea esi, [ecx*8 + SLOT_BASE + APPDATA.wnd_clientbox]
movsd
movsd
movsd
movsd
 
; Window state
mov al, [ecx+window_data+WDATA.fl_wstate]
stosb
 
pop esi
pop edi
 
.nofillbuf:
; return number of processes
 
mov eax,[TASK_COUNT]
mov [esp+32],eax
ret
 
align 4
sys_clock:
cli
; Mikhail Lisovin xx Jan 2005
@@: mov al, 10
out 0x70, al
in al, 0x71
test al, al
jns @f
mov esi, 1
call delay_ms
jmp @b
@@:
; end Lisovin's fix
 
xor al,al ; seconds
out 0x70,al
in al,0x71
movzx ecx,al
mov al,02 ; minutes
shl ecx,16
out 0x70,al
in al,0x71
movzx edx,al
mov al,04 ; hours
shl edx,8
out 0x70,al
in al,0x71
add ecx,edx
movzx edx,al
add ecx,edx
sti
mov [esp + 32], ecx
ret
 
 
align 4
 
sys_date:
 
cli
@@: mov al, 10
out 0x70, al
in al, 0x71
test al, al
jns @f
mov esi, 1
call delay_ms
jmp @b
@@:
 
mov ch,0
mov al,7 ; date
out 0x70,al
in al,0x71
mov cl,al
mov al,8 ; month
shl ecx,16
out 0x70,al
in al,0x71
mov ch,al
mov al,9 ; year
out 0x70,al
in al,0x71
mov cl,al
sti
mov [esp+32], ecx
ret
 
 
; redraw status
 
sys_redrawstat:
cmp ebx, 1
jne no_widgets_away
; buttons away
mov ecx,[CURRENT_TASK]
sys_newba2:
mov edi,[BTN_ADDR]
cmp [edi], dword 0 ; empty button list ?
je end_of_buttons_away
movzx ebx, word [edi]
inc ebx
mov eax,edi
sys_newba:
dec ebx
jz end_of_buttons_away
 
add eax, 0x10
cmp cx, [eax]
jnz sys_newba
 
push eax ebx ecx
mov ecx,ebx
inc ecx
shl ecx, 4
mov ebx, eax
add eax, 0x10
call memmove
dec dword [edi]
pop ecx ebx eax
 
jmp sys_newba2
 
end_of_buttons_away:
 
ret
 
no_widgets_away:
 
cmp ebx, 2
jnz srl1
 
mov edx, [TASK_BASE] ; return whole screen draw area for this app
add edx, draw_data - CURRENT_TASK
mov [edx + RECT.left], 0
mov [edx + RECT.top], 0
mov eax, [Screen_Max_X]
mov [edx + RECT.right], eax
mov eax, [Screen_Max_Y]
mov [edx + RECT.bottom], eax
 
srl1:
ret
 
;ok - 100% work
;nt - not tested
;---------------------------------------------------------------------------------------------
;eax
;0 - task switch counter. Ret switch counter in eax. Block. ok.
;1 - change task. Ret nothing. Block. ok.
;2 - performance control
; ebx
; 0 - enable or disable (inversion) PCE flag on CR4 for rdmpc in user mode.
; returned new cr4 in eax. Ret cr4 in eax. Block. ok.
; 1 - is cache enabled. Ret cr0 in eax if enabled else zero in eax. Block. ok.
; 2 - enable cache. Ret 1 in eax. Ret nothing. Block. ok.
; 3 - disable cache. Ret 0 in eax. Ret nothing. Block. ok.
;eax
;3 - rdmsr. Counter in edx. (edx:eax) [esi:edi, edx] => [edx:esi, ecx]. Ret in ebx:eax. Block. ok.
;4 - wrmsr. Counter in edx. (edx:eax) [esi:edi, edx] => [edx:esi, ecx]. Ret in ebx:eax. Block. ok.
;---------------------------------------------------------------------------------------------
iglobal
align 4
sheduler:
dd sys_sheduler.00
dd change_task
dd sys_sheduler.02
dd sys_sheduler.03
dd sys_sheduler.04
endg
sys_sheduler:
;rewritten by <Lrz> 29.12.2009
jmp dword [sheduler+ebx*4]
;.shed_counter:
.00:
mov eax,[context_counter]
mov [esp+32],eax
ret
 
.02:
;.perf_control:
inc ebx ;before ebx=2, ebx=3
cmp ebx,ecx ;if ecx=3, ebx=3
jz cache_disable
 
dec ebx ;ebx=2
cmp ebx,ecx ;
jz cache_enable ;if ecx=2 and ebx=2
 
dec ebx ;ebx=1
cmp ebx,ecx
jz is_cache_enabled ;if ecx=1 and ebx=1
 
dec ebx
test ebx,ecx ;ebx=0 and ecx=0
jz modify_pce ;if ecx=0
 
ret
 
.03:
;.rdmsr_instr:
;now counter in ecx
;(edx:eax) esi:edi => edx:esi
mov eax,esi
mov ecx,edx
rdmsr
mov [esp+32],eax
mov [esp+20],edx ;ret in ebx?
ret
 
.04:
;.wrmsr_instr:
;now counter in ecx
;(edx:eax) esi:edi => edx:esi
; Fast Call MSR can't be destroy
; ® MSR_AMD_EFER ¬®¦­® ¨§¬¥­ïâì, â.ª. ¢ í⮬ ॣ¨áâॠ«¨è
; ¢ª«îç îâáï/¢ëª«îç îâáï à áè¨à¥­­ë¥ ¢®§¬®¦­®áâ¨
cmp edx,MSR_SYSENTER_CS
je @f
cmp edx,MSR_SYSENTER_ESP
je @f
cmp edx,MSR_SYSENTER_EIP
je @f
cmp edx,MSR_AMD_STAR
je @f
 
mov eax,esi
mov ecx,edx
wrmsr
; mov [esp + 32], eax
; mov [esp + 20], edx ;ret in ebx?
@@:
ret
 
cache_disable:
mov eax,cr0
or eax,01100000000000000000000000000000b
mov cr0,eax
wbinvd ;set MESI
ret
 
cache_enable:
mov eax,cr0
and eax,10011111111111111111111111111111b
mov cr0,eax
ret
 
is_cache_enabled:
mov eax,cr0
mov ebx,eax
and eax,01100000000000000000000000000000b
jz cache_disabled
mov [esp+32],ebx
cache_disabled:
mov dword [esp+32],eax ;0
ret
 
modify_pce:
mov eax,cr4
; mov ebx,0
; or bx,100000000b ;pce
; xor eax,ebx ;invert pce
bts eax,8 ;pce=cr4[8]
mov cr4,eax
mov [esp+32],eax
ret
;---------------------------------------------------------------------------------------------
 
 
; check if pixel is allowed to be drawn
 
checkpixel:
push eax edx
 
mov edx,[Screen_Max_X] ; screen x size
inc edx
imul edx, ebx
add eax, [_WinMapAddress]
mov dl, [eax+edx] ; lea eax, [...]
 
xor ecx, ecx
mov eax, [CURRENT_TASK]
cmp al, dl
setne cl
 
pop edx eax
ret
 
iglobal
cpustring db 'CPU',0
endg
 
uglobal
background_defined db 0 ; diamond, 11.04.2006
endg
 
align 4
; check misc
 
checkmisc:
 
cmp [ctrl_alt_del], 1
jne nocpustart
 
mov ebp, cpustring
call fs_execute_from_sysdir
 
mov [ctrl_alt_del], 0
 
nocpustart:
cmp [mouse_active], 1
jne mouse_not_active
mov [mouse_active], 0
xor edi, edi
mov ecx, [TASK_COUNT]
set_mouse_event:
add edi, 256
or [edi+SLOT_BASE+APPDATA.event_mask], dword 100000b
loop set_mouse_event
 
mouse_not_active:
cmp byte[BACKGROUND_CHANGED], 0
jz no_set_bgr_event
xor edi, edi
mov ecx, [TASK_COUNT]
set_bgr_event:
add edi, 256
or [edi+SLOT_BASE+APPDATA.event_mask], 16
loop set_bgr_event
mov byte[BACKGROUND_CHANGED], 0
no_set_bgr_event:
cmp byte[REDRAW_BACKGROUND], 0 ; background update ?
jz nobackgr
cmp [background_defined], 0
jz nobackgr
; mov [draw_data+32 + RECT.left],dword 0
; mov [draw_data+32 + RECT.top],dword 0
; mov eax,[Screen_Max_X]
; mov ebx,[Screen_Max_Y]
; mov [draw_data+32 + RECT.right],eax
; mov [draw_data+32 + RECT.bottom],ebx
@@:
call drawbackground
xor eax, eax
xchg al, [REDRAW_BACKGROUND]
test al, al ; got new update request?
jnz @b
mov [draw_data+32 + RECT.left], eax
mov [draw_data+32 + RECT.top], eax
mov [draw_data+32 + RECT.right], eax
mov [draw_data+32 + RECT.bottom], eax
mov [MOUSE_BACKGROUND],byte 0
 
nobackgr:
 
; system shutdown request
 
cmp [SYS_SHUTDOWN],byte 0
je noshutdown
 
mov edx,[shutdown_processes]
 
cmp [SYS_SHUTDOWN],dl
jne no_mark_system_shutdown
 
lea ecx,[edx-1]
mov edx,OS_BASE+0x3040
jecxz @f
markz:
mov [edx+TASKDATA.state],byte 3
add edx,0x20
loop markz
@@:
 
no_mark_system_shutdown:
 
call [_display.disable_mouse]
 
dec byte [SYS_SHUTDOWN]
je system_shutdown
 
noshutdown:
 
 
mov eax,[TASK_COUNT] ; termination
mov ebx,TASK_DATA+TASKDATA.state
mov esi,1
 
newct:
mov cl,[ebx]
cmp cl,byte 3
jz terminate
cmp cl,byte 4
jz terminate
 
add ebx,0x20
inc esi
dec eax
jnz newct
ret
 
; redraw screen
 
redrawscreen:
 
; eax , if process window_data base is eax, do not set flag/limits
 
pushad
push eax
 
;;; mov ebx,2
;;; call delay_hs
 
;mov ecx,0 ; redraw flags for apps
xor ecx,ecx
newdw2:
 
inc ecx
push ecx
 
mov eax,ecx
shl eax,5
add eax,window_data
 
cmp eax,[esp+4]
je not_this_task
; check if window in redraw area
mov edi,eax
 
cmp ecx,1 ; limit for background
jz bgli
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx,eax
add edx,ebx
 
mov ecx,[draw_limits.bottom] ; ecx = area y end ebx = window y start
cmp ecx,ebx
jb ricino
 
mov ecx,[draw_limits.right] ; ecx = area x end eax = window x start
cmp ecx,eax
jb ricino
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
 
mov eax,[draw_limits.top] ; eax = area y start edx = window y end
cmp edx,eax
jb ricino
 
mov eax,[draw_limits.left] ; eax = area x start ecx = window x end
cmp ecx,eax
jb ricino
 
bgli:
 
cmp dword[esp], 1
jnz .az
; cmp byte[BACKGROUND_CHANGED], 0
; jnz newdw8
cmp byte[REDRAW_BACKGROUND], 0
jz .az
mov dl, 0
lea eax,[edi+draw_data-window_data]
mov ebx,[draw_limits.left]
cmp ebx,[eax+RECT.left]
jae @f
mov [eax+RECT.left],ebx
mov dl, 1
@@:
mov ebx,[draw_limits.top]
cmp ebx,[eax+RECT.top]
jae @f
mov [eax+RECT.top],ebx
mov dl, 1
@@:
mov ebx,[draw_limits.right]
cmp ebx,[eax+RECT.right]
jbe @f
mov [eax+RECT.right],ebx
mov dl, 1
@@:
mov ebx,[draw_limits.bottom]
cmp ebx,[eax+RECT.bottom]
jbe @f
mov [eax+RECT.bottom],ebx
mov dl, 1
@@:
add byte[REDRAW_BACKGROUND], dl
jmp newdw8
.az:
 
mov eax,edi
add eax,draw_data-window_data
 
mov ebx,[draw_limits.left] ; set limits
mov [eax + RECT.left], ebx
mov ebx,[draw_limits.top]
mov [eax + RECT.top], ebx
mov ebx,[draw_limits.right]
mov [eax + RECT.right], ebx
mov ebx,[draw_limits.bottom]
mov [eax + RECT.bottom], ebx
 
sub eax,draw_data-window_data
 
cmp dword [esp],1
jne nobgrd
inc byte[REDRAW_BACKGROUND]
 
newdw8:
nobgrd:
 
mov [eax + WDATA.fl_redraw],byte 1 ; mark as redraw
 
ricino:
 
not_this_task:
 
pop ecx
 
cmp ecx,[TASK_COUNT]
jle newdw2
 
pop eax
popad
 
ret
 
calculatebackground: ; background
 
mov edi, [_WinMapAddress] ; set os to use all pixels
mov eax,0x01010101
mov ecx, [_WinMapSize]
shr ecx, 2
rep stosd
 
mov byte[REDRAW_BACKGROUND], 0 ; do not draw background!
mov byte[BACKGROUND_CHANGED], 0
 
ret
 
uglobal
imax dd 0x0
endg
 
 
 
delay_ms: ; delay in 1/1000 sec
 
 
push eax
push ecx
 
mov ecx,esi
; <CPU clock fix by Sergey Kuzmin aka Wildwest>
imul ecx, 33941
shr ecx, 9
; </CPU clock fix>
 
in al,0x61
and al,0x10
mov ah,al
cld
 
cnt1: in al,0x61
and al,0x10
cmp al,ah
jz cnt1
 
mov ah,al
loop cnt1
 
pop ecx
pop eax
 
ret
 
 
set_app_param:
mov edi, [TASK_BASE]
mov eax, [edi + TASKDATA.event_mask]
mov [edi + TASKDATA.event_mask], ebx
mov [esp+32], eax
ret
 
 
 
delay_hs: ; delay in 1/100 secs
; ebx = delay time
push ecx
push edx
 
mov edx,[timer_ticks]
 
newtic:
mov ecx,[timer_ticks]
sub ecx,edx
cmp ecx,ebx
jae zerodelay
 
call change_task
 
jmp newtic
 
zerodelay:
pop edx
pop ecx
 
ret
 
align 16 ;very often call this subrutine
memmove: ; memory move in bytes
 
; eax = from
; ebx = to
; ecx = no of bytes
test ecx, ecx
jle .ret
 
push esi edi ecx
 
mov edi, ebx
mov esi, eax
 
test ecx, not 11b
jz @f
 
push ecx
shr ecx, 2
rep movsd
pop ecx
and ecx, 11b
jz .finish
@@:
rep movsb
 
.finish:
pop ecx edi esi
.ret:
ret
 
 
; <diamond> Sysfunction 34, read_floppy_file, is obsolete. Use 58 or 70 function instead.
;align 4
;
;read_floppy_file:
;
;; as input
;;
;; eax pointer to file
;; ebx file lenght
;; ecx start 512 byte block number
;; edx number of blocks to read
;; esi pointer to return/work area (atleast 20 000 bytes)
;;
;;
;; on return
;;
;; eax = 0 command succesful
;; 1 no fd base and/or partition defined
;; 2 yet unsupported FS
;; 3 unknown FS
;; 4 partition not defined at hd
;; 5 file not found
;; ebx = size of file
;
; mov edi,[TASK_BASE]
; add edi,0x10
; add esi,[edi]
; add eax,[edi]
;
; pushad
; mov edi,esi
; add edi,1024
; mov esi,0x100000+19*512
; sub ecx,1
; shl ecx,9
; add esi,ecx
; shl edx,9
; mov ecx,edx
; cld
; rep movsb
; popad
;
; mov [esp+36],eax
; mov [esp+24],ebx
; ret
 
 
 
align 4
 
sys_programirq:
 
mov eax, [TASK_BASE]
add ebx, [eax + TASKDATA.mem_start]
 
cmp ecx, 16
jae .not_owner
mov edi, [eax + TASKDATA.pid]
cmp edi, [irq_owner + 4 * ecx]
je .spril1
.not_owner:
xor ecx, ecx
inc ecx
jmp .end
.spril1:
 
shl ecx, 6
mov esi, ebx
lea edi, [irq00read + ecx]
push 16
pop ecx
 
cld
rep movsd
.end:
mov [esp+32], ecx
ret
 
 
align 4
 
get_irq_data:
movzx esi, bh ; save number of subfunction, if bh = 1, return data size, otherwise, read data
xor bh, bh
cmp ebx, 16
jae .not_owner
mov edx, [4 * ebx + irq_owner] ; check for irq owner
 
mov eax,[TASK_BASE]
 
cmp edx,[eax+TASKDATA.pid]
je gidril1
.not_owner:
xor edx, edx
dec edx
jmp gid1
 
gidril1:
 
shl ebx, 12
lea eax, [ebx + IRQ_SAVE] ; calculate address of the beginning of buffer + 0x0 - data size
mov edx, [eax] ; + 0x4 - data offset
dec esi
jz gid1
test edx, edx ; check if buffer is empty
jz gid1
 
mov ebx, [eax + 0x4]
mov edi, ecx
 
mov ecx, 4000 ; buffer size, used frequently
 
cmp ebx, ecx ; check for the end of buffer, if end of buffer, begin cycle again
jb @f
 
xor ebx, ebx
 
@@:
 
lea esi, [ebx + edx] ; calculate data size and offset
cld
cmp esi, ecx ; if greater than the buffer size, begin cycle again
jbe @f
 
sub ecx, ebx
sub edx, ecx
 
lea esi, [eax + ebx + 0x10]
rep movsb
 
xor ebx, ebx
@@:
lea esi, [eax + ebx + 0x10]
mov ecx, edx
add ebx, edx
 
rep movsb
mov edx, [eax]
mov [eax], ecx ; set data size to zero
mov [eax + 0x4], ebx ; set data offset
 
gid1:
mov [esp+32], edx ; eax
ret
 
 
set_io_access_rights:
push edi eax
mov edi, tss._io_map_0
; mov ecx,eax
; and ecx,7 ; offset in byte
; shr eax,3 ; number of byte
; add edi,eax
; mov ebx,1
; shl ebx,cl
test ebp,ebp
; cmp ebp,0 ; enable access - ebp = 0
jnz siar1
; not ebx
; and [edi],byte bl
btr [edi], eax
pop eax edi
ret
siar1:
bts [edi], eax
; or [edi],byte bl ; disable access - ebp = 1
pop eax edi
ret
;reserve/free group of ports
; * eax = 46 - number function
; * ebx = 0 - reserve, 1 - free
; * ecx = number start arrea of ports
; * edx = number end arrea of ports (include last number of port)
;Return value:
; * eax = 0 - succesful
; * eax = 1 - error
; * The system has reserve this ports:
; 0..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (include last number of port).
;destroys eax,ebx, ebp
r_f_port_area:
 
test ebx, ebx
jnz free_port_area
; je r_port_area
; jmp free_port_area
 
; r_port_area:
 
; pushad
 
cmp ecx,edx ; beginning > end ?
ja rpal1
cmp edx,65536
jae rpal1
mov eax,[RESERVED_PORTS]
test eax,eax ; no reserved areas ?
je rpal2
cmp eax,255 ; max reserved
jae rpal1
rpal3:
mov ebx,eax
shl ebx,4
add ebx,RESERVED_PORTS
cmp ecx,[ebx+8]
ja rpal4
cmp edx,[ebx+4]
jae rpal1
; jb rpal4
; jmp rpal1
rpal4:
dec eax
jnz rpal3
jmp rpal2
rpal1:
; popad
; mov eax,1
xor eax,eax
inc eax
ret
rpal2:
; popad
; enable port access at port IO map
cli
pushad ; start enable io map
 
cmp edx,65536 ;16384
jae no_unmask_io ; jge
mov eax,ecx
; push ebp
xor ebp,ebp ; enable - eax = port
new_port_access:
; pushad
call set_io_access_rights
; popad
inc eax
cmp eax,edx
jbe new_port_access
; pop ebp
no_unmask_io:
popad ; end enable io map
sti
 
mov eax,[RESERVED_PORTS]
add eax,1
mov [RESERVED_PORTS],eax
shl eax,4
add eax,RESERVED_PORTS
mov ebx,[TASK_BASE]
mov ebx,[ebx+TASKDATA.pid]
mov [eax],ebx
mov [eax+4],ecx
mov [eax+8],edx
 
xor eax, eax
ret
 
free_port_area:
 
; pushad
mov eax,[RESERVED_PORTS] ; no reserved areas ?
test eax,eax
jz frpal2
mov ebx,[TASK_BASE]
mov ebx,[ebx+TASKDATA.pid]
frpal3:
mov edi,eax
shl edi,4
add edi,RESERVED_PORTS
cmp ebx,[edi]
jne frpal4
cmp ecx,[edi+4]
jne frpal4
cmp edx,[edi+8]
jne frpal4
jmp frpal1
frpal4:
dec eax
jnz frpal3
frpal2:
; popad
inc eax
ret
frpal1:
push ecx
mov ecx,256
sub ecx,eax
shl ecx,4
mov esi,edi
add esi,16
cld
rep movsb
 
dec dword [RESERVED_PORTS]
;popad
;disable port access at port IO map
 
; pushad ; start disable io map
pop eax ;start port
cmp edx,65536 ;16384
jge no_mask_io
 
; mov eax,ecx
xor ebp,ebp
inc ebp
new_port_access_disable:
; pushad
; mov ebp,1 ; disable - eax = port
call set_io_access_rights
; popad
inc eax
cmp eax,edx
jbe new_port_access_disable
no_mask_io:
; popad ; end disable io map
xor eax, eax
ret
 
 
reserve_free_irq:
 
xor esi, esi
inc esi
cmp ecx, 16
jae ril1
 
push ecx
lea ecx, [irq_owner + 4 * ecx]
mov edx, [ecx]
mov eax, [TASK_BASE]
mov edi, [eax + TASKDATA.pid]
pop eax
dec ebx
jnz reserve_irq
 
cmp edx, edi
jne ril1
dec esi
mov [ecx], esi
 
jmp ril1
 
reserve_irq:
 
cmp dword [ecx], 0
jne ril1
 
mov ebx, [f_irqs + 4 * eax]
 
stdcall attach_int_handler, eax, ebx, dword 0
 
mov [ecx], edi
 
dec esi
ril1:
mov [esp+32], esi ; return in eax
ret
 
iglobal
f_irqs:
dd 0x0
dd 0x0
dd p_irq2
dd p_irq3
dd p_irq4
dd p_irq5
dd p_irq6
dd p_irq7
dd p_irq8
dd p_irq9
dd p_irq10
dd p_irq11
dd 0x0
dd 0x0
dd p_irq14
dd p_irq15
 
endg
 
drawbackground:
inc [mouse_pause]
cmp [SCR_MODE],word 0x12
je dbrv20
dbrv12:
cmp [SCR_MODE],word 0100000000000000b
jge dbrv20
cmp [SCR_MODE],word 0x13
je dbrv20
call vesa12_drawbackground
dec [mouse_pause]
call [draw_pointer]
ret
dbrv20:
cmp [BgrDrawMode],dword 1
jne bgrstr
call vesa20_drawbackground_tiled
dec [mouse_pause]
call [draw_pointer]
ret
bgrstr:
call vesa20_drawbackground_stretch
dec [mouse_pause]
call [draw_pointer]
ret
 
align 4
 
syscall_putimage: ; PutImage
sys_putimage:
test ecx,0x80008000
jnz .exit
test ecx,0x0000FFFF
jz .exit
test ecx,0xFFFF0000
jnz @f
.exit:
ret
@@:
mov edi,[current_slot]
add dx,word[edi+APPDATA.wnd_clientbox.top]
rol edx,16
add dx,word[edi+APPDATA.wnd_clientbox.left]
rol edx,16
.forced:
push ebp esi 0
mov ebp, putimage_get24bpp
mov esi, putimage_init24bpp
sys_putimage_bpp:
; call [disable_mouse] ; this will be done in xxx_putimage
; mov eax, vga_putimage
cmp [SCR_MODE], word 0x12
jz @f ;.doit
mov eax, vesa12_putimage
cmp [SCR_MODE], word 0100000000000000b
jae @f
cmp [SCR_MODE], word 0x13
jnz .doit
@@:
mov eax, vesa20_putimage
.doit:
inc [mouse_pause]
call eax
dec [mouse_pause]
pop ebp esi ebp
jmp [draw_pointer]
align 4
sys_putimage_palette:
; ebx = pointer to image
; ecx = [xsize]*65536 + [ysize]
; edx = [xstart]*65536 + [ystart]
; esi = number of bits per pixel, must be 8, 24 or 32
; edi = pointer to palette
; ebp = row delta
mov eax, [CURRENT_TASK]
shl eax, 8
add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.top]
rol edx, 16
add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.left]
rol edx, 16
.forced:
cmp esi, 1
jnz @f
push edi
mov eax, [edi+4]
sub eax, [edi]
push eax
push dword [edi]
push 0ffffff80h
mov edi, esp
call put_mono_image
add esp, 12
pop edi
ret
@@:
cmp esi, 2
jnz @f
push edi
push 0ffffff80h
mov edi, esp
call put_2bit_image
pop eax
pop edi
ret
@@:
cmp esi, 4
jnz @f
push edi
push 0ffffff80h
mov edi, esp
call put_4bit_image
pop eax
pop edi
ret
@@:
push ebp esi ebp
cmp esi, 8
jnz @f
mov ebp, putimage_get8bpp
mov esi, putimage_init8bpp
jmp sys_putimage_bpp
@@:
cmp esi, 15
jnz @f
mov ebp, putimage_get15bpp
mov esi, putimage_init15bpp
jmp sys_putimage_bpp
@@:
cmp esi, 16
jnz @f
mov ebp, putimage_get16bpp
mov esi, putimage_init16bpp
jmp sys_putimage_bpp
@@:
cmp esi, 24
jnz @f
mov ebp, putimage_get24bpp
mov esi, putimage_init24bpp
jmp sys_putimage_bpp
@@:
cmp esi, 32
jnz @f
mov ebp, putimage_get32bpp
mov esi, putimage_init32bpp
jmp sys_putimage_bpp
@@:
pop ebp esi ebp
ret
 
put_mono_image:
push ebp esi ebp
mov ebp, putimage_get1bpp
mov esi, putimage_init1bpp
jmp sys_putimage_bpp
put_2bit_image:
push ebp esi ebp
mov ebp, putimage_get2bpp
mov esi, putimage_init2bpp
jmp sys_putimage_bpp
put_4bit_image:
push ebp esi ebp
mov ebp, putimage_get4bpp
mov esi, putimage_init4bpp
jmp sys_putimage_bpp
 
putimage_init24bpp:
lea eax, [eax*3]
putimage_init8bpp:
ret
 
align 16
putimage_get24bpp:
movzx eax, byte [esi+2]
shl eax, 16
mov ax, [esi]
add esi, 3
ret 4
align 16
putimage_get8bpp:
movzx eax, byte [esi]
push edx
mov edx, [esp+8]
mov eax, [edx+eax*4]
pop edx
inc esi
ret 4
 
putimage_init1bpp:
add eax, ecx
push ecx
add eax, 7
add ecx, 7
shr eax, 3
shr ecx, 3
sub eax, ecx
pop ecx
ret
align 16
putimage_get1bpp:
push edx
mov edx, [esp+8]
mov al, [edx]
add al, al
jnz @f
lodsb
adc al, al
@@:
mov [edx], al
sbb eax, eax
and eax, [edx+8]
add eax, [edx+4]
pop edx
ret 4
 
putimage_init2bpp:
add eax, ecx
push ecx
add ecx, 3
add eax, 3
shr ecx, 2
shr eax, 2
sub eax, ecx
pop ecx
ret
align 16
putimage_get2bpp:
push edx
mov edx, [esp+8]
mov al, [edx]
mov ah, al
shr al, 6
shl ah, 2
jnz .nonewbyte
lodsb
mov ah, al
shr al, 6
shl ah, 2
add ah, 1
.nonewbyte:
mov [edx], ah
mov edx, [edx+4]
movzx eax, al
mov eax, [edx+eax*4]
pop edx
ret 4
 
putimage_init4bpp:
add eax, ecx
push ecx
add ecx, 1
add eax, 1
shr ecx, 1
shr eax, 1
sub eax, ecx
pop ecx
ret
align 16
putimage_get4bpp:
push edx
mov edx, [esp+8]
add byte [edx], 80h
jc @f
movzx eax, byte [edx+1]
mov edx, [edx+4]
and eax, 0x0F
mov eax, [edx+eax*4]
pop edx
ret 4
@@:
movzx eax, byte [esi]
add esi, 1
mov [edx+1], al
shr eax, 4
mov edx, [edx+4]
mov eax, [edx+eax*4]
pop edx
ret 4
 
putimage_init32bpp:
shl eax, 2
ret
align 16
putimage_get32bpp:
lodsd
ret 4
 
putimage_init15bpp:
putimage_init16bpp:
add eax, eax
ret
align 16
putimage_get15bpp:
; 0RRRRRGGGGGBBBBB -> 00000000RRRRR000GGGGG000BBBBB000
push ecx edx
movzx eax, word [esi]
add esi, 2
mov ecx, eax
mov edx, eax
and eax, 0x1F
and ecx, 0x1F shl 5
and edx, 0x1F shl 10
shl eax, 3
shl ecx, 6
shl edx, 9
or eax, ecx
or eax, edx
pop edx ecx
ret 4
 
align 16
putimage_get16bpp:
; RRRRRGGGGGGBBBBB -> 00000000RRRRR000GGGGGG00BBBBB000
push ecx edx
movzx eax, word [esi]
add esi, 2
mov ecx, eax
mov edx, eax
and eax, 0x1F
and ecx, 0x3F shl 5
and edx, 0x1F shl 11
shl eax, 3
shl ecx, 5
shl edx, 8
or eax, ecx
or eax, edx
pop edx ecx
ret 4
 
; eax x beginning
; ebx y beginning
; ecx x end
; edx y end
; edi color
 
__sys_drawbar:
mov esi,[current_slot]
add eax,[esi+APPDATA.wnd_clientbox.left]
add ecx,[esi+APPDATA.wnd_clientbox.left]
add ebx,[esi+APPDATA.wnd_clientbox.top]
add edx,[esi+APPDATA.wnd_clientbox.top]
.forced:
inc [mouse_pause]
; call [disable_mouse]
cmp [SCR_MODE],word 0x12
je dbv20
sdbv20:
cmp [SCR_MODE],word 0100000000000000b
jge dbv20
cmp [SCR_MODE],word 0x13
je dbv20
call vesa12_drawbar
dec [mouse_pause]
call [draw_pointer]
ret
dbv20:
call vesa20_drawbar
dec [mouse_pause]
call [draw_pointer]
ret
 
 
 
kb_read:
 
push ecx edx
 
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
kr_loop:
in al,0x64
test al,1
jnz kr_ready
loop kr_loop
mov ah,1
jmp kr_exit
kr_ready:
push ecx
mov ecx,32
kr_delay:
loop kr_delay
pop ecx
in al,0x60
xor ah,ah
kr_exit:
 
pop edx ecx
 
ret
 
 
kb_write:
 
push ecx edx
 
mov dl,al
; mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
; kw_loop1:
; in al,0x64
; test al,0x20
; jz kw_ok1
; loop kw_loop1
; mov ah,1
; jmp kw_exit
; kw_ok1:
in al,0x60
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
kw_loop:
in al,0x64
test al,2
jz kw_ok
loop kw_loop
mov ah,1
jmp kw_exit
kw_ok:
mov al,dl
out 0x60,al
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
kw_loop3:
in al,0x64
test al,2
jz kw_ok3
loop kw_loop3
mov ah,1
jmp kw_exit
kw_ok3:
mov ah,8
kw_loop4:
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
kw_loop5:
in al,0x64
test al,1
jnz kw_ok4
loop kw_loop5
dec ah
jnz kw_loop4
kw_ok4:
xor ah,ah
kw_exit:
 
pop edx ecx
 
ret
 
 
kb_cmd:
 
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
c_wait:
in al,0x64
test al,2
jz c_send
loop c_wait
jmp c_error
c_send:
mov al,bl
out 0x64,al
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's
c_accept:
in al,0x64
test al,2
jz c_ok
loop c_accept
c_error:
mov ah,1
jmp c_exit
c_ok:
xor ah,ah
c_exit:
ret
 
 
setmouse: ; set mousepicture -pointer
; ps2 mouse enable
 
mov [MOUSE_PICTURE],dword mousepointer
 
cli
 
ret
 
if used _rdtsc
_rdtsc:
bt [cpu_caps], CAPS_TSC
jnc ret_rdtsc
rdtsc
ret
ret_rdtsc:
mov edx,0xffffffff
mov eax,0xffffffff
ret
end if
 
rerouteirqs:
 
cli
 
mov al,0x11 ; icw4, edge triggered
out 0x20,al
call pic_delay
out 0xA0,al
call pic_delay
 
mov al,0x20 ; generate 0x20 +
out 0x21,al
call pic_delay
mov al,0x28 ; generate 0x28 +
out 0xA1,al
call pic_delay
 
mov al,0x04 ; slave at irq2
out 0x21,al
call pic_delay
mov al,0x02 ; at irq9
out 0xA1,al
call pic_delay
 
mov al,0x01 ; 8086 mode
out 0x21,al
call pic_delay
out 0xA1,al
call pic_delay
 
mov al,255 ; mask all irq's
out 0xA1,al
call pic_delay
out 0x21,al
call pic_delay
 
mov ecx,0x1000
cld
picl1: call pic_delay
loop picl1
 
mov al,255 ; mask all irq's
out 0xA1,al
call pic_delay
out 0x21,al
call pic_delay
 
cli
 
ret
 
 
pic_delay:
 
jmp pdl1
pdl1: ret
 
 
sys_msg_board_str:
 
pushad
@@:
cmp [esi],byte 0
je @f
mov eax,1
movzx ebx,byte [esi]
call sys_msg_board
inc esi
jmp @b
@@:
popad
ret
 
sys_msg_board_byte:
; in: al = byte to display
; out: nothing
; destroys: nothing
pushad
mov ecx, 2
shl eax, 24
jmp @f
 
sys_msg_board_word:
; in: ax = word to display
; out: nothing
; destroys: nothing
pushad
mov ecx, 4
shl eax, 16
jmp @f
 
sys_msg_board_dword:
; in: eax = dword to display
; out: nothing
; destroys: nothing
pushad
mov ecx, 8
@@:
push ecx
rol eax, 4
push eax
and al, 0xF
cmp al, 10
sbb al, 69h
das
mov bl, al
xor eax, eax
inc eax
call sys_msg_board
pop eax
pop ecx
loop @b
popad
ret
 
uglobal
msg_board_data: times 4096 db 0
msg_board_count dd 0x0
endg
 
sys_msg_board:
 
; eax=1 : write : bl byte to write
; eax=2 : read : ebx=0 -> no data, ebx=1 -> data in al
 
mov ecx, [msg_board_count]
cmp eax, 1
jne .smbl1
 
if defined debug_com_base
 
push dx ax
 
@@: ; Wait for empty transmit register (yes, this slows down system..)
mov dx, debug_com_base+5
in al, dx
test al, 1 shl 5
jz @r
 
mov dx, debug_com_base ; Output the byte
mov al, bl
out dx, al
 
pop ax dx
 
end if
 
mov [msg_board_data+ecx],bl
inc ecx
and ecx, 4095
mov [msg_board_count], ecx
mov [check_idle_semaphore], 5
ret
.smbl1:
cmp eax, 2
jne .smbl2
test ecx, ecx
jz .smbl21
mov eax, msg_board_data+1
mov ebx, msg_board_data
movzx edx, byte [ebx]
call memmove
dec [msg_board_count]
mov [esp + 36], edx ;eax
mov [esp + 24], dword 1
ret
.smbl21:
mov [esp+36], ecx
mov [esp+24], ecx
.smbl2:
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 66 sys function. ;;
;; in eax=66,ebx in [0..5],ecx,edx ;;
;; out eax ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
iglobal
align 4
f66call:
dd sys_process_def.1 ; 1 = set keyboard mode
dd sys_process_def.2 ; 2 = get keyboard mode
dd sys_process_def.3 ; 3 = get keyboard ctrl, alt, shift
dd sys_process_def.4
dd sys_process_def.5
endg
 
 
 
 
sys_process_def:
dec ebx
cmp ebx,5
jae .not_support ;if >=6 then or eax,-1
 
mov edi, [CURRENT_TASK]
jmp dword [f66call+ebx*4]
 
.not_support:
or eax,-1
ret
 
.1:
shl edi,8
mov [edi+SLOT_BASE + APPDATA.keyboard_mode],cl
 
ret
 
.2: ; 2 = get keyboard mode
shl edi,8
movzx eax, byte [SLOT_BASE+edi + APPDATA.keyboard_mode]
mov [esp+32],eax
ret
; xor eax,eax
; movzx eax,byte [shift]
; movzx ebx,byte [ctrl]
; shl ebx,2
; add eax,ebx
; movzx ebx,byte [alt]
; shl ebx,3
; add eax,ebx
.3: ;3 = get keyboard ctrl, alt, shift
;// mike.dld [
mov eax, [kb_state]
;// mike.dld ]
mov [esp+32],eax
ret
 
.4:
mov eax, hotkey_list
@@:
cmp dword [eax+8], 0
jz .found_free
add eax, 16
cmp eax, hotkey_list+16*256
jb @b
mov dword [esp+32], 1
ret
.found_free:
mov [eax+8], edi
mov [eax+4], edx
movzx ecx, cl
lea ecx, [hotkey_scancodes+ecx*4]
mov edx, [ecx]
mov [eax], edx
mov [ecx], eax
mov [eax+12], ecx
jecxz @f
mov [edx+12], eax
@@:
and dword [esp+32], 0
ret
 
.5:
movzx ebx, cl
lea ebx, [hotkey_scancodes+ebx*4]
mov eax, [ebx]
.scan:
test eax, eax
jz .notfound
cmp [eax+8], edi
jnz .next
cmp [eax+4], edx
jz .found
.next:
mov eax, [eax]
jmp .scan
.notfound:
mov dword [esp+32], 1
ret
.found:
mov ecx, [eax]
jecxz @f
mov edx, [eax+12]
mov [ecx+12], edx
@@:
mov ecx, [eax+12]
mov edx, [eax]
mov [ecx], edx
xor edx, edx
mov [eax+4], edx
mov [eax+8], edx
mov [eax+12], edx
mov [eax], edx
mov [esp+32], edx
ret
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 61 sys function. ;;
;; in eax=61,ebx in [1..3] ;;
;; out eax ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
iglobal
align 4
f61call:
dd sys_gs.1 ; resolution
dd sys_gs.2 ; bits per pixel
dd sys_gs.3 ; bytes per scanline
endg
 
 
align 4
 
sys_gs: ; direct screen access
dec ebx
cmp ebx,2
ja .not_support
jmp dword [f61call+ebx*4]
.not_support:
or [esp+32],dword -1
ret
 
 
.1: ; resolution
mov eax,[Screen_Max_X]
shl eax,16
mov ax,[Screen_Max_Y]
add eax,0x00010001
mov [esp+32],eax
ret
.2: ; bits per pixel
movzx eax,byte [ScreenBPP]
mov [esp+32],eax
ret
.3: ; bytes per scanline
mov eax,[BytesPerScanLine]
mov [esp+32],eax
ret
 
align 4 ; system functions
 
syscall_setpixel: ; SetPixel
 
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, [TASK_BASE]
add eax, [edx-twdw+WDATA.box.left]
add ebx, [edx-twdw+WDATA.box.top]
mov edi, [current_slot]
add eax, [edi+APPDATA.wnd_clientbox.left]
add ebx, [edi+APPDATA.wnd_clientbox.top]
xor edi, edi ; no force
; mov edi, 1
call [_display.disable_mouse]
jmp [putpixel]
 
align 4
 
syscall_writetext: ; WriteText
 
mov eax,[TASK_BASE]
mov ebp,[eax-twdw+WDATA.box.left]
push esi
mov esi,[current_slot]
add ebp,[esi+APPDATA.wnd_clientbox.left]
shl ebp,16
add ebp,[eax-twdw+WDATA.box.top]
add bp,word[esi+APPDATA.wnd_clientbox.top]
pop esi
add ebx,ebp
mov eax,edi
xor edi,edi
jmp dtext
 
align 4
 
syscall_openramdiskfile: ; OpenRamdiskFile
 
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, esi
mov esi, 12
call fileread
mov [esp+32], eax
ret
 
align 4
 
syscall_drawrect: ; DrawRect
 
mov edi, edx ; color + gradient
and edi, 0x80FFFFFF
test bx, bx ; x.size
je .drectr
test cx, cx ; y.size
je .drectr
 
mov eax, ebx ; bad idea
mov ebx, ecx
 
movzx ecx, ax ; ecx - x.size
shr eax, 16 ; eax - x.coord
movzx edx, bx ; edx - y.size
shr ebx, 16 ; ebx - y.coord
mov esi, [current_slot]
 
add eax, [esi + APPDATA.wnd_clientbox.left]
add ebx, [esi + APPDATA.wnd_clientbox.top]
add ecx, eax
add edx, ebx
jmp [drawbar]
.drectr:
ret
 
align 4
syscall_getscreensize: ; GetScreenSize
mov ax, [Screen_Max_X]
shl eax, 16
mov ax, [Screen_Max_Y]
mov [esp + 32], eax
ret
 
align 4
 
syscall_cdaudio: ; CD
 
cmp ebx, 4
jb .audio
jz .eject
cmp ebx, 5
jnz .ret
.load:
call .reserve
call LoadMedium
;call .free
jmp .free
; ret
.eject:
call .reserve
call clear_CD_cache
call allow_medium_removal
call EjectMedium
; call .free
jmp .free
; ret
.audio:
call sys_cd_audio
mov [esp+36-4],eax
.ret:
ret
 
.reserve:
call reserve_cd
mov eax, ecx
shr eax, 1
and eax, 1
inc eax
mov [ChannelNumber], ax
mov eax, ecx
and eax, 1
mov [DiskNumber], al
call reserve_cd_channel
and ebx, 3
inc ebx
mov [cdpos], ebx
add ebx, ebx
mov cl, 8
sub cl, bl
mov al, [DRIVE_DATA+1]
shr al, cl
test al, 2
jz .free;.err
ret
.free:
call free_cd_channel
and [cd_status], 0
ret
.err:
call .free
; pop eax
ret
 
align 4
 
syscall_getpixel: ; GetPixel
mov ecx, [Screen_Max_X]
inc ecx
xor edx, edx
mov eax, ebx
div ecx
mov ebx, edx
xchg eax, ebx
call dword [GETPIXEL] ; eax - x, ebx - y
mov [esp + 32], ecx
ret
 
align 4
 
syscall_getarea:
;eax = 36
;ebx = pointer to bufer for img BBGGRRBBGGRR...
;ecx = [size x]*65536 + [size y]
;edx = [start x]*65536 + [start y]
pushad
inc [mouse_pause]
; Check of use of the hardware cursor.
cmp [_display.disable_mouse],__sys_disable_mouse
jne @f
; Since the test for the coordinates of the mouse should not be used,
; then use the call [disable_mouse] is not possible!
cmp dword [MOUSE_VISIBLE],dword 0
jne @f
pushf
cli
call draw_mouse_under
popf
mov [MOUSE_VISIBLE],dword 1
@@:
mov edi,ebx
mov eax,edx
shr eax,16
mov ebx,edx
and ebx,0xffff
dec eax
dec ebx
; eax - x, ebx - y
mov edx,ecx
shr ecx,16
and edx,0xffff
mov esi,ecx
; ecx - size x, edx - size y
mov ebp,edx
dec ebp
lea ebp,[ebp*3]
imul ebp,esi
mov esi,ecx
dec esi
lea esi,[esi*3]
add ebp,esi
add ebp,edi
 
add ebx,edx
.start_y:
push ecx edx
.start_x:
push eax ebx ecx
add eax,ecx
 
call dword [GETPIXEL] ; eax - x, ebx - y
mov [ebp],cx
shr ecx,16
mov [ebp+2],cl
 
pop ecx ebx eax
sub ebp,3
dec ecx
jnz .start_x
pop edx ecx
dec ebx
dec edx
jnz .start_y
dec [mouse_pause]
; Check of use of the hardware cursor.
cmp [_display.disable_mouse],__sys_disable_mouse
jne @f
call [draw_pointer]
@@:
popad
ret
 
align 4
 
syscall_drawline: ; DrawLine
 
mov edi, [TASK_BASE]
movzx eax, word[edi-twdw+WDATA.box.left]
mov ebp, eax
mov esi, [current_slot]
add ebp, [esi+APPDATA.wnd_clientbox.left]
add ax, word[esi+APPDATA.wnd_clientbox.left]
add ebp,ebx
shl eax, 16
movzx ebx, word[edi-twdw+WDATA.box.top]
add eax, ebp
mov ebp, ebx
add ebp, [esi+APPDATA.wnd_clientbox.top]
add bx, word[esi+APPDATA.wnd_clientbox.top]
add ebp, ecx
shl ebx, 16
xor edi, edi
add ebx, ebp
mov ecx, edx
jmp [draw_line]
 
align 4
 
syscall_getirqowner: ; GetIrqOwner
 
cmp ebx,16
jae .err
 
cmp [irq_rights + 4 * ebx], dword 2
je .err
 
mov eax,[4 * ebx + irq_owner]
mov [esp+32],eax
 
ret
.err:
or dword [esp+32], -1
ret
 
align 4
 
syscall_reserveportarea: ; ReservePortArea and FreePortArea
 
call r_f_port_area
mov [esp+32],eax
ret
 
align 4
 
syscall_threads: ; CreateThreads
; eax=1 create thread
;
; ebx=thread start
; ecx=thread stack value
;
; on return : eax = pid
 
call new_sys_threads
 
mov [esp+32],eax
ret
 
align 4
 
stack_driver_stat:
 
call app_stack_handler ; Stack status
 
; mov [check_idle_semaphore],5 ; enable these for zero delay
; call change_task ; between sent packet
 
mov [esp+32],eax
ret
 
align 4
 
socket: ; Socket interface
call app_socket_handler
 
; mov [check_idle_semaphore],5 ; enable these for zero delay
; call change_task ; between sent packet
 
mov [esp+36],eax
mov [esp+24],ebx
ret
 
align 4
 
read_from_hd: ; Read from hd - fn not in use
 
mov edi,[TASK_BASE]
add edi,TASKDATA.mem_start
add eax,[edi]
add ecx,[edi]
add edx,[edi]
call file_read
 
mov [esp+36],eax
mov [esp+24],ebx
 
ret
 
paleholder:
ret
 
align 4
set_screen:
cmp eax, [Screen_Max_X]
jne .set
 
cmp edx, [Screen_Max_Y]
jne .set
ret
.set:
pushfd
cli
 
mov [Screen_Max_X], eax
mov [Screen_Max_Y], edx
mov [BytesPerScanLine], ecx
 
mov [screen_workarea.right],eax
mov [screen_workarea.bottom], edx
 
push ebx
push esi
push edi
 
pushad
 
stdcall kernel_free, [_WinMapAddress]
 
mov eax, [_display.width]
mul [_display.height]
mov [_WinMapSize], eax
 
stdcall kernel_alloc, eax
mov [_WinMapAddress], eax
test eax, eax
jz .epic_fail
 
popad
 
call repos_windows
xor eax, eax
xor ebx, ebx
mov ecx, [Screen_Max_X]
mov edx, [Screen_Max_Y]
call calculatescreen
pop edi
pop esi
pop ebx
 
popfd
ret
 
.epic_fail:
hlt ; Houston, we've had a problem
 
; --------------- APM ---------------------
uglobal
apm_entry dp 0
apm_vf dd 0
endg
 
align 4
sys_apm:
xor eax,eax
cmp word [apm_vf], ax ; Check APM BIOS enable
jne @f
inc eax
or dword [esp + 44], eax ; error
add eax,7
mov dword [esp + 32], eax ; 32-bit protected-mode interface not supported
ret
 
@@:
; xchg eax, ecx
; xchg ebx, ecx
 
cmp dx, 3
ja @f
and [esp + 44], byte 0xfe ; emulate func 0..3 as func 0
mov eax,[apm_vf]
mov [esp + 32], eax
shr eax, 16
mov [esp + 28], eax
ret
 
@@:
 
mov esi,[master_tab+(OS_BASE shr 20)]
xchg [master_tab], esi
push esi
mov edi, cr3
mov cr3, edi ;flush TLB
 
call pword [apm_entry] ;call APM BIOS
 
xchg eax, [esp]
mov [master_tab], eax
mov eax, cr3
mov cr3, eax
pop eax
 
mov [esp + 4 ], edi
mov [esp + 8], esi
mov [esp + 20], ebx
mov [esp + 24], edx
mov [esp + 28], ecx
mov [esp + 32], eax
setc al
and [esp + 44], byte 0xfe
or [esp + 44], al
ret
; -----------------------------------------
 
align 4
 
undefined_syscall: ; Undefined system call
mov [esp + 32], dword -1
ret
 
align 4
system_shutdown: ; shut down the system
 
cmp byte [BOOT_VAR+0x9030], 1
jne @F
ret
@@:
call stop_all_services
push 3 ; stop playing cd
pop eax
call sys_cd_audio
 
yes_shutdown_param:
cli
 
mov eax, kernel_file ; load kernel.mnt to 0x7000:0
push 12
pop esi
xor ebx,ebx
or ecx,-1
mov edx, OS_BASE+0x70000
call fileread
 
mov esi, restart_kernel_4000+OS_BASE+0x10000 ; move kernel re-starter to 0x4000:0
mov edi,OS_BASE+0x40000
mov ecx,1000
rep movsb
 
mov esi,OS_BASE+0x2F0000 ; restore 0x0 - 0xffff
mov edi, OS_BASE
mov ecx,0x10000/4
cld
rep movsd
 
call restorefatchain
 
mov al, 0xFF
out 0x21, al
out 0xA1, al
 
if 0
mov word [OS_BASE+0x467+0],pr_mode_exit
mov word [OS_BASE+0x467+2],0x1000
 
mov al,0x0F
out 0x70,al
mov al,0x05
out 0x71,al
 
mov al,0xFE
out 0x64,al
 
hlt
jmp $-1
 
else
cmp byte [OS_BASE + 0x9030], 2
jnz no_acpi_power_off
 
; scan for RSDP
; 1) The first 1 Kb of the Extended BIOS Data Area (EBDA).
movzx eax, word [OS_BASE + 0x40E]
shl eax, 4
jz @f
mov ecx, 1024/16
call scan_rsdp
jnc .rsdp_found
@@:
; 2) The BIOS read-only memory space between 0E0000h and 0FFFFFh.
mov eax, 0xE0000
mov ecx, 0x2000
call scan_rsdp
jc no_acpi_power_off
.rsdp_found:
mov esi, [eax+16] ; esi contains physical address of the RSDT
mov ebp, [ipc_tmp]
stdcall map_page, ebp, esi, PG_MAP
lea eax, [esi+1000h]
lea edx, [ebp+1000h]
stdcall map_page, edx, eax, PG_MAP
and esi, 0xFFF
add esi, ebp
cmp dword [esi], 'RSDT'
jnz no_acpi_power_off
mov ecx, [esi+4]
sub ecx, 24h
jbe no_acpi_power_off
shr ecx, 2
add esi, 24h
.scan_fadt:
lodsd
mov ebx, eax
lea eax, [ebp+2000h]
stdcall map_page, eax, ebx, PG_MAP
lea eax, [ebp+3000h]
add ebx, 0x1000
stdcall map_page, eax, ebx, PG_MAP
and ebx, 0xFFF
lea ebx, [ebx+ebp+2000h]
cmp dword [ebx], 'FACP'
jz .fadt_found
loop .scan_fadt
jmp no_acpi_power_off
.fadt_found:
; ebx is linear address of FADT
mov edi, [ebx+40] ; physical address of the DSDT
lea eax, [ebp+4000h]
stdcall map_page, eax, edi, PG_MAP
lea eax, [ebp+5000h]
lea esi, [edi+0x1000]
stdcall map_page, eax, esi, PG_MAP
and esi, 0xFFF
sub edi, esi
cmp dword [esi+ebp+4000h], 'DSDT'
jnz no_acpi_power_off
mov eax, [esi+ebp+4004h] ; DSDT length
sub eax, 36+4
jbe no_acpi_power_off
add esi, 36
.scan_dsdt:
cmp dword [esi+ebp+4000h], '_S5_'
jnz .scan_dsdt_cont
cmp byte [esi+ebp+4000h+4], 12h ; DefPackage opcode
jnz .scan_dsdt_cont
mov dl, [esi+ebp+4000h+6]
cmp dl, 4 ; _S5_ package must contain 4 bytes
; ...in theory; in practice, VirtualBox has 2 bytes
ja .scan_dsdt_cont
cmp dl, 1
jb .scan_dsdt_cont
lea esi, [esi+ebp+4000h+7]
xor ecx, ecx
cmp byte [esi], 0 ; 0 means zero byte, 0Ah xx means byte xx
jz @f
cmp byte [esi], 0xA
jnz no_acpi_power_off
inc esi
mov cl, [esi]
@@:
inc esi
cmp dl, 2
jb @f
cmp byte [esi], 0
jz @f
cmp byte [esi], 0xA
jnz no_acpi_power_off
inc esi
mov ch, [esi]
@@:
jmp do_acpi_power_off
.scan_dsdt_cont:
inc esi
cmp esi, 0x1000
jb @f
sub esi, 0x1000
add edi, 0x1000
push eax
lea eax, [ebp+4000h]
stdcall map_page, eax, edi, PG_MAP
push PG_MAP
lea eax, [edi+1000h]
push eax
lea eax, [ebp+5000h]
push eax
stdcall map_page
pop eax
@@:
dec eax
jnz .scan_dsdt
jmp no_acpi_power_off
do_acpi_power_off:
mov edx, [ebx+48]
test edx, edx
jz .nosmi
mov al, [ebx+52]
out dx, al
mov edx, [ebx+64]
@@:
in ax, dx
test al, 1
jz @b
.nosmi:
and cx, 0x0707
shl cx, 2
or cx, 0x2020
mov edx, [ebx+64]
in ax, dx
and ax, 203h
or ah, cl
out dx, ax
mov edx, [ebx+68]
test edx, edx
jz @f
in ax, dx
and ax, 203h
or ah, ch
out dx, ax
@@:
jmp $
 
 
no_acpi_power_off:
mov word [OS_BASE+0x467+0],pr_mode_exit
mov word [OS_BASE+0x467+2],0x1000
 
mov al,0x0F
out 0x70,al
mov al,0x05
out 0x71,al
 
mov al,0xFE
out 0x64,al
 
hlt
jmp $-1
 
scan_rsdp:
add eax, OS_BASE
.s:
cmp dword [eax], 'RSD '
jnz .n
cmp dword [eax+4], 'PTR '
jnz .n
xor edx, edx
xor esi, esi
@@:
add dl, [eax+esi]
inc esi
cmp esi, 20
jnz @b
test dl, dl
jz .ok
.n:
add eax, 10h
loop .s
stc
.ok:
ret
end if
 
include "data32.inc"
 
__REV__ = __REV
 
uglobals_size = $ - endofcode
diff16 "end of kernel code",0,$
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/hid/keyboard.inc
0,0 → 1,343
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;// mike.dld [
 
VKEY_LSHIFT = 0000000000000001b
VKEY_RSHIFT = 0000000000000010b
VKEY_LCONTROL = 0000000000000100b
VKEY_RCONTROL = 0000000000001000b
VKEY_LALT = 0000000000010000b
VKEY_RALT = 0000000000100000b
VKEY_CAPSLOCK = 0000000001000000b
VKEY_NUMLOCK = 0000000010000000b
VKEY_SCRLOCK = 0000000100000000b
 
VKEY_SHIFT = 0000000000000011b
VKEY_CONTROL = 0000000000001100b
VKEY_ALT = 0000000000110000b
 
uglobal
align 4
kb_state dd 0
ext_code db 0
 
keyboard_mode db 0
keyboard_data db 0
 
altmouseb db 0
ctrl_alt_del db 0
 
kb_lights db 0
 
align 4
hotkey_scancodes rd 256 ; we have 256 scancodes
hotkey_list rd 256*4 ; max 256 defined hotkeys
hotkey_buffer rd 120*2 ; buffer for 120 hotkeys
endg
 
iglobal
hotkey_tests dd hotkey_test0
dd hotkey_test1
dd hotkey_test2
dd hotkey_test3
dd hotkey_test4
hotkey_tests_num = 5
endg
 
hotkey_test0:
test al, al
setz al
ret
hotkey_test1:
test al, al
setnp al
ret
hotkey_test2:
cmp al, 3
setz al
ret
hotkey_test3:
cmp al, 1
setz al
ret
hotkey_test4:
cmp al, 2
setz al
ret
 
hotkey_do_test:
push eax
mov edx, [kb_state]
shr edx, cl
add cl, cl
mov eax, [eax+4]
shr eax, cl
and eax, 15
cmp al, hotkey_tests_num
jae .fail
xchg eax, edx
and al, 3
call [hotkey_tests + edx*4]
cmp al, 1
pop eax
ret
.fail:
stc
pop eax
ret
 
align 4
irq1:
; save_ring3_context
; mov ax, os_data
; mov ds, ax
; mov es, ax
 
movzx eax,word[TASK_COUNT] ; top window process
movzx eax,word[WIN_POS+eax*2]
shl eax,8
mov al,[SLOT_BASE+eax+APPDATA.keyboard_mode]
mov [keyboard_mode],al
 
in al,0x60
mov [keyboard_data],al
 
; ch = scancode
; cl = ext_code
; bh = 0 - normal key
; bh = 1 - modifier (Shift/Ctrl/Alt)
; bh = 2 - extended code
 
mov ch,al
cmp al,0xE0
je @f
cmp al,0xE1
jne .normal_code
@@:
mov bh, 2
mov [ext_code], al
jmp .writekey
.normal_code:
mov cl, 0
xchg cl, [ext_code]
and al,0x7F
mov bh, 1
@@: cmp al,0x2A
jne @f
cmp cl,0xE0
je .writekey
mov eax,VKEY_LSHIFT
jmp .modifier
@@: cmp al,0x36
jne @f
cmp cl,0xE0
je .writekey
mov eax,VKEY_RSHIFT
jmp .modifier
@@: cmp al,0x38
jne @f
mov eax, VKEY_LALT
test cl, cl
jz .modifier
mov al, VKEY_RALT
jmp .modifier
@@: cmp al,0x1D
jne @f
mov eax, VKEY_LCONTROL
test cl, cl
jz .modifier
mov al, VKEY_RCONTROL
cmp cl, 0xE0
jz .modifier
mov [ext_code], cl
jmp .writekey
@@: cmp al,0x3A
jne @f
mov bl,4
mov eax,VKEY_CAPSLOCK
jmp .no_key.xor
@@: cmp al,0x45
jne @f
test cl, cl
jnz .writekey
mov bl,2
mov eax,VKEY_NUMLOCK
jmp .no_key.xor
@@: cmp al,0x46
jne @f
mov bl,1
mov eax,VKEY_SCRLOCK
jmp .no_key.xor
@@:
xor ebx,ebx
test ch,ch
js .writekey
movzx eax,ch ; plain key
mov bl,[keymap+eax]
mov edx,[kb_state]
test dl,VKEY_CONTROL ; ctrl alt del
jz .noctrlaltdel
test dl,VKEY_ALT
jz .noctrlaltdel
cmp ch,53h
jne .noctrlaltdel
mov [ctrl_alt_del],1
.noctrlaltdel:
test dl,VKEY_CONTROL ; ctrl on ?
jz @f
sub bl,0x60
@@: test dl,VKEY_SHIFT ; shift on ?
jz @f
mov bl,[keymap_shift+eax]
@@: test dl,VKEY_ALT ; alt on ?
jz @f
mov bl,[keymap_alt+eax]
@@:
jmp .writekey
.modifier:
test ch, ch
js .modifier.up
or [kb_state], eax
jmp .writekey
.modifier.up:
not eax
and [kb_state], eax
jmp .writekey
.no_key.xor:
mov bh, 0
test ch, ch
js .writekey
xor [kb_state], eax
xor [kb_lights], bl
call set_lights
 
.writekey:
; test for system hotkeys
movzx eax, ch
cmp bh, 1
ja .nohotkey
jb @f
xor eax, eax
@@:
mov eax, [hotkey_scancodes + eax*4]
.hotkey_loop:
test eax, eax
jz .nohotkey
mov cl, 0
call hotkey_do_test
jc .hotkey_cont
mov cl, 2
call hotkey_do_test
jc .hotkey_cont
mov cl, 4
call hotkey_do_test
jnc .hotkey_found
.hotkey_cont:
mov eax, [eax]
jmp .hotkey_loop
.hotkey_found:
mov eax, [eax+8]
; put key in buffer for process in slot eax
mov edi, hotkey_buffer
@@:
cmp dword [edi], 0
jz .found_free
add edi, 8
cmp edi, hotkey_buffer+120*8
jb @b
; no free space - replace first entry
mov edi, hotkey_buffer
.found_free:
mov [edi], eax
movzx eax, ch
cmp bh, 1
jnz @f
xor eax, eax
@@:
mov [edi+4], ax
mov eax, [kb_state]
mov [edi+6], ax
jmp .exit.irq1
.nohotkey:
cmp [keyboard_mode],0 ; return from keymap
jne .scancode
test bh, bh
jnz .exit.irq1
test bl, bl
jz .exit.irq1
 
;.........................Part1 Start.......Code by Rus, optimize by Ghost...................................
test [kb_state], VKEY_NUMLOCK
jz .dowrite
cmp cl, 0xE0
jz .dowrite
 
cmp ch, 55
jnz @f
mov bl, 0x2A ;*
jmp .dowrite
@@:
cmp ch, 71
jb .dowrite
cmp ch, 83
ja .dowrite
;push eax
movzx eax, ch
mov bl, [numlock_map + eax - 71]
;pop eax
 
;.........................Part1 End.................................................
 
jmp .dowrite
.scancode:
mov bl, ch
.dowrite:
movzx eax,byte[KEY_COUNT]
cmp al,120
jae .exit.irq1
inc eax
mov [KEY_COUNT],al
mov [KEY_COUNT+eax],bl
 
.exit.irq1:
mov [check_idle_semaphore],5
 
; mov al,0x20 ; ready for next irq
; out 0x20,al
 
; restore_ring3_context
; iret
ret
 
set_lights:
mov al,0xED
call kb_write
mov al,[kb_lights]
call kb_write
ret
 
;// mike.dld ]
;..........................Part2 Start.......Code by Rus.......................................
numlock_map:
db 0x37 ;Num 7
db 0x38 ;Num 8
db 0x39 ;Num 9
db 0x2D ;Num -
db 0x34 ;Num 4
db 0x35 ;Num 5
db 0x36 ;Num 6
db 0x2B ;Num +
db 0x31 ;Num 1
db 0x32 ;Num 2
db 0x33 ;Num 3
db 0x30 ;Num 0
db 0x2E ;Num .
;..........................Part2 End................................................
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/hid/mousedrv.inc
0,0 → 1,456
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; check mouse
;
;
; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y
; FB10 -> FB17 mouse color mem
; FB21 x move
; FB22 y move
; FB30 color temp
; FB28 high bits temp
; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under
; FC00 -> FCFE com1/ps2 buffer
; FCFF com1/ps2 buffer count starting from FC00
 
uglobal
mousecount dd 0x0
mousedata dd 0x0
endg
 
iglobal
mouse_delay dd 10
mouse_speed_factor: dd 3
mouse_timer_ticks dd 0
endg
 
;include 'm_com.inc'
 
 
;test_mario79:
; push esi
; push eax
; mov [write_error_to],process_test_m79+43
; movzx eax,al ;[DevErrorCode]
; call writehex
; mov esi,process_test_m79
; call sys_msg_board_str
; pop eax
; pop esi
; ret
;process_test_m79 db 'K : Process - test Mario79 error 00000000',13,10,0
 
draw_mouse_under:
; return old picture
 
cmp [_display.restore_cursor], 0
je @F
 
pushad
movzx eax,word [X_UNDER]
movzx ebx,word [Y_UNDER]
stdcall [_display.restore_cursor], eax, ebx
popad
ret
@@:
pushad
xor ecx,ecx
xor edx,edx
align 4
mres:
movzx eax,word [X_UNDER]
movzx ebx,word [Y_UNDER]
add eax,ecx
add ebx,edx
push ecx
push edx
push eax
push ebx
mov eax,edx
shl eax,6
shl ecx,2
add eax,ecx
add eax,mouseunder
mov ecx,[eax]
pop ebx
pop eax
mov edi, 1 ;force
call [putpixel]
pop edx
pop ecx
inc ecx
cmp ecx, 16
jnz mres
xor ecx, ecx
inc edx
cmp edx, 24
jnz mres
popad
ret
 
save_draw_mouse:
 
cmp [_display.move_cursor], 0
je .no_hw_cursor
pushad
 
mov [X_UNDER],ax
mov [Y_UNDER],bx
movzx eax,word [MOUSE_Y]
movzx ebx,word [MOUSE_X]
push eax
push ebx
 
mov ecx, [Screen_Max_X]
inc ecx
mul ecx
add eax, [_WinMapAddress]
movzx edx, byte [ebx+eax]
shl edx, 8
mov esi, [edx+SLOT_BASE+APPDATA.cursor]
 
cmp esi, [current_cursor]
je .draw
 
push esi
call [_display.select_cursor]
mov [current_cursor], esi
.draw:
stdcall [_display.move_cursor], esi
popad
ret
.fail:
mov ecx, [def_cursor]
mov [edx+SLOT_BASE+APPDATA.cursor], ecx
stdcall [_display.move_cursor], ecx ; stdcall: [esp]=ebx,eax
popad
ret
 
.no_hw_cursor:
pushad
; save & draw
mov [X_UNDER],ax
mov [Y_UNDER],bx
push eax
push ebx
mov ecx,0
mov edx,0
align 4
drm:
push eax
push ebx
push ecx
push edx
; helloworld
push ecx
add eax,ecx ; save picture under mouse
add ebx,edx
push ecx
call getpixel
mov [COLOR_TEMP],ecx
pop ecx
mov eax,edx
shl eax,6
shl ecx,2
add eax,ecx
add eax,mouseunder
mov ebx,[COLOR_TEMP]
mov [eax],ebx
pop ecx
mov edi,edx ; y cycle
shl edi,4 ; *16 bytes per row
add edi,ecx ; x cycle
mov esi, edi
add edi, esi
add edi, esi ; *3
add edi,[MOUSE_PICTURE] ; we have our str address
mov esi, edi
add esi, 16*24*3
push ecx
mov ecx, [COLOR_TEMP]
call combine_colors
mov [MOUSE_COLOR_MEM], ecx
pop ecx
pop edx
pop ecx
pop ebx
pop eax
add eax,ecx ; we have x coord+cycle
add ebx,edx ; and y coord+cycle
push ecx
mov ecx, [MOUSE_COLOR_MEM]
mov edi, 1
call [putpixel]
pop ecx
mov ebx,[esp+0] ; pure y coord again
mov eax,[esp+4] ; and x
inc ecx ; +1 cycle
cmp ecx,16 ; if more than 16
jnz drm
xor ecx, ecx
inc edx
cmp edx,24
jnz drm
add esp,8
popad
ret
 
 
combine_colors:
; in
; ecx - color ( 00 RR GG BB )
; edi - ref to new color byte
; esi - ref to alpha byte
;
; out
; ecx - new color ( roughly (ecx*[esi]>>8)+([edi]*[esi]>>8) )
push eax
push ebx
push edx
push ecx
xor ecx, ecx
; byte 2
mov eax, 0xff
sub al, [esi+0]
mov ebx, [esp]
shr ebx, 16
and ebx, 0xff
mul ebx
shr eax, 8
add ecx, eax
xor eax, eax
xor ebx, ebx
mov al, [edi+0]
mov bl, [esi+0]
mul ebx
shr eax, 8
add ecx, eax
shl ecx, 8
; byte 1
mov eax, 0xff
sub al, [esi+1]
mov ebx, [esp]
shr ebx, 8
and ebx, 0xff
mul ebx
shr eax, 8
add ecx, eax
xor eax, eax
xor ebx, ebx
mov al, [edi+1]
mov bl, [esi+1]
mul ebx
shr eax, 8
add ecx, eax
shl ecx, 8
; byte 2
mov eax, 0xff
sub al, [esi+2]
mov ebx, [esp]
and ebx, 0xff
mul ebx
shr eax, 8
add ecx, eax
xor eax, eax
xor ebx, ebx
mov al, [edi+2]
mov bl, [esi+2]
mul ebx
shr eax, 8
add ecx, eax
pop eax
pop edx
pop ebx
pop eax
ret
 
 
__sys_disable_mouse:
cmp dword [MOUSE_VISIBLE],dword 0
je @f
ret
@@:
pushad
cmp [CURRENT_TASK],dword 1
je disable_m
mov edx,[CURRENT_TASK]
shl edx,5
add edx,window_data
movzx eax, word [MOUSE_X]
movzx ebx, word [MOUSE_Y]
mov ecx,[Screen_Max_X]
inc ecx
imul ecx,ebx
add ecx,eax
add ecx, [_WinMapAddress]
mov eax, [CURRENT_TASK]
movzx ebx, byte [ecx]
cmp eax,ebx
je yes_mouse_disable
movzx ebx, byte [ecx+16]
cmp eax,ebx
je yes_mouse_disable
mov ebx,[Screen_Max_X]
inc ebx
imul ebx,10
add ecx,ebx
movzx ebx, byte [ecx]
cmp eax,ebx
je yes_mouse_disable
movzx ebx, byte [ecx+16]
cmp eax,ebx
je yes_mouse_disable
jmp no_mouse_disable
yes_mouse_disable:
mov edx,[CURRENT_TASK]
shl edx,5
add edx,window_data
movzx eax, word [MOUSE_X]
movzx ebx, word [MOUSE_Y]
mov ecx,[edx+0] ; mouse inside the area ?
add eax,10
cmp eax,ecx
jb no_mouse_disable
sub eax,10
add ecx,[edx+8]
cmp eax,ecx
jg no_mouse_disable
mov ecx,[edx+4]
add ebx,14
cmp ebx,ecx
jb no_mouse_disable
sub ebx,14
add ecx,[edx+12]
cmp ebx,ecx
jg no_mouse_disable
disable_m:
cmp dword [MOUSE_VISIBLE],dword 0
jne no_mouse_disable
pushf
cli
call draw_mouse_under
popf
mov [MOUSE_VISIBLE],dword 1
no_mouse_disable:
popad
ret
 
__sys_draw_pointer:
cmp [mouse_pause],0
je @f
ret
@@:
push eax
mov eax,[timer_ticks]
sub eax,[MouseTickCounter]
cmp eax,1
ja @f
pop eax
ret
@@:
mov eax,[timer_ticks]
mov [MouseTickCounter],eax
pop eax
pushad
cmp dword [MOUSE_VISIBLE],dword 0 ; mouse visible ?
je chms00
mov [MOUSE_VISIBLE], dword 0
movzx ebx,word [MOUSE_Y]
movzx eax,word [MOUSE_X]
pushfd
cli
call save_draw_mouse
popfd
nodmu2:
popad
ret
chms00:
movzx ecx,word [X_UNDER]
movzx edx,word [Y_UNDER]
movzx ebx,word [MOUSE_Y]
movzx eax,word [MOUSE_X]
cmp eax,ecx
jne redrawmouse
cmp ebx,edx
jne redrawmouse
jmp nodmp
redrawmouse:
pushfd
cli
call draw_mouse_under
call save_draw_mouse
popfd
nodmp:
popad
ret
 
proc set_mouse_data stdcall, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword
 
mov eax,[BtnState]
mov [BTN_DOWN],eax
 
mov eax,[XMoving]
call mouse_acceleration
add ax,[MOUSE_X] ;[XCoordinate]
cmp ax,0
jge @@M1
mov eax,0
jmp @@M2
@@M1:
cmp ax,[Screen_Max_X] ;ScreenLength
jl @@M2
mov ax,[Screen_Max_X] ;ScreenLength-1
 
@@M2:
mov [MOUSE_X],ax ;[XCoordinate]
 
mov eax,[YMoving]
neg eax
call mouse_acceleration
 
add ax,[MOUSE_Y] ;[YCoordinate]
cmp ax,0
jge @@M3
mov ax,0
jmp @@M4
@@M3:
cmp ax,[Screen_Max_Y] ;ScreenHeigth
jl @@M4
mov ax,[Screen_Max_Y] ;ScreenHeigth-1
 
@@M4:
mov [MOUSE_Y],ax ;[YCoordinate]
 
mov eax,[VScroll]
add [MOUSE_SCROLL_V],ax
 
mov eax,[HScroll]
add [MOUSE_SCROLL_H],ax
 
mov [mouse_active],1
mov eax,[timer_ticks]
mov [mouse_timer_ticks],eax
ret
endp
 
mouse_acceleration:
push eax
mov eax,[timer_ticks]
sub eax,[mouse_timer_ticks]
cmp eax,[mouse_delay]
pop eax
ja @f
;push edx
imul eax,[mouse_speed_factor]
;pop edx
@@:
ret
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/hid/set_dtc.inc
0,0 → 1,203
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;setting date,time,clock and alarm-clock
;add sys_settime at servetable as for ex. 22 fcn:
; 22 - SETTING DATE TIME, CLOCK AND ALARM-CLOCK
; ebx =0 - set time ecx - 00SSMMHH
; ebx =1 - set date ecx=00DDMMYY
; ebx =2 - set day of week ecx- 1-7
; ebx =3 - set alarm-clock ecx - 00SSMMHH
; out: 0 -Ok 1 -wrong format 2 -battery low
sys_settime:
cli
mov al,0x0d
out 0x70,al
in al,0x71
bt ax,7
jnc bat_low
cmp ebx,2 ;day of week
jne nosetweek
test ecx,ecx ;test day of week
je wrongtime
cmp ecx,7
ja wrongtime
mov edx,0x70
call startstopclk
dec edx
mov al,6
out dx,al
inc edx
mov al,cl
out dx,al
jmp endsettime
nosetweek: ;set date
cmp ebx,1
jne nosetdate
cmp cl,0x99 ;test year
ja wrongtime
shl ecx,4
cmp cl,0x90
ja wrongtime
cmp ch,0x99 ;test month
ja wrongtime
shr ecx,4
test ch,ch
je wrongtime
cmp ch,0x12
ja wrongtime
shl ecx,8
bswap ecx ;ebx=00YYMMDD
test cl,cl ;test day
je wrongtime
shl ecx,4
cmp cl,0x90
ja wrongtime
shr ecx,4
cmp ch,2 ;February
jne testday
cmp cl,0x29
ja wrongtime
jmp setdate
testday:
cmp ch,8
jb testday1 ;Aug-Dec
bt cx,8
jnc days31
jmp days30
testday1:
bt cx,8 ;Jan-Jul ex.Feb
jnc days30
days31:
cmp cl,0x31
ja wrongtime
jmp setdate
days30:
cmp cl,0x30
ja wrongtime
setdate:
mov edx,0x70
call startstopclk
dec edx
mov al,7 ;set days
out dx,al
inc edx
mov al,cl
out dx,al
dec edx
mov al,8 ;set months
out dx,al
inc edx
mov al,ch
out dx,al
dec edx
mov al,9 ;set years
out dx,al
inc edx
shr ecx,8
mov al,ch
out dx,al
jmp endsettime
nosetdate: ;set time or alarm-clock
cmp ebx,3
ja wrongtime
cmp cl,0x23
ja wrongtime
cmp ch,0x59
ja wrongtime
shl ecx,4
cmp cl,0x90
ja wrongtime
cmp ch,0x92
ja wrongtime
shl ecx,4
bswap ecx ;00HHMMSS
cmp cl,0x59
ja wrongtime
shl ecx,4
cmp cl,0x90
ja wrongtime
shr ecx,4
 
mov edx,0x70
call startstopclk
dec edx
cmp ebx,3
je setalarm
xor eax,eax ;al=0-set seconds
out dx,al
inc edx
mov al,cl
out dx,al
dec edx
mov al,2 ;set minutes
out dx,al
inc edx
mov al,ch
out dx,al
dec edx
mov al,4 ;set hours
out dx,al
inc edx
shr ecx,8
mov al,ch
out dx,al
jmp endsettime
setalarm:
mov al,1 ;set seconds for al.
out dx,al
inc edx
mov al,cl
out dx,al
dec edx
mov al,3 ;set minutes for al.
out dx,al
inc edx
mov al,ch
out dx,al
dec edx
mov al,5 ;set hours for al.
out dx,al
inc edx
shr ecx,8
mov al,ch
out dx,al
dec edx
mov al,0x0b ;enable irq's
out dx,al
inc dx
in al,dx
bts ax,5 ;set bit 5
out dx,al
endsettime:
dec edx
call startstopclk
sti
and [esp+36-4],dword 0
ret
bat_low:
sti
mov [esp+36-4],dword 2
ret
wrongtime:
sti
mov [esp+36-4],dword 1
ret
 
startstopclk:
mov al,0x0b
out dx,al
inc dx
in al,dx
btc ax,7
out dx,al
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/hid
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/fs/fs_lfn.inc
0,0 → 1,1143
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
image_of_eax EQU esp+32
image_of_ebx EQU esp+20
 
; System function 70 - files with long names (LFN)
; diamond, 2006
 
iglobal
; in this table names must be in lowercase
rootdirs:
db 2,'rd'
dd fs_OnRamdisk
dd fs_NextRamdisk
db 7,'ramdisk'
dd fs_OnRamdisk
dd fs_NextRamdisk
db 2,'fd'
dd fs_OnFloppy
dd fs_NextFloppy
db 10,'floppydisk'
dd fs_OnFloppy
dd fs_NextFloppy
db 3,'hd0'
dd fs_OnHd0
dd fs_NextHd0
db 3,'hd1'
dd fs_OnHd1
dd fs_NextHd1
db 3,'hd2'
dd fs_OnHd2
dd fs_NextHd2
db 3,'hd3'
dd fs_OnHd3
dd fs_NextHd3
;**********************************************
db 3,'cd0'
dd fs_OnCd0
dd fs_NextCd
db 3,'cd1'
dd fs_OnCd1
dd fs_NextCd
db 3,'cd2'
dd fs_OnCd2
dd fs_NextCd
db 3,'cd3'
dd fs_OnCd3
dd fs_NextCd
;***********************************************
db 0
 
 
virtual_root_query:
dd fs_HasRamdisk
db 'rd',0
dd fs_HasFloppy
db 'fd',0
dd fs_HasHd0
db 'hd0',0
dd fs_HasHd1
db 'hd1',0
dd fs_HasHd2
db 'hd2',0
dd fs_HasHd3
db 'hd3',0
;**********************************************
dd fs_HasCd0
db 'cd0',0
dd fs_HasCd1
db 'cd1',0
dd fs_HasCd2
db 'cd2',0
dd fs_HasCd3
db 'cd3',0
;**********************************************
dd 0
 
fs_additional_handlers:
dd biosdisk_handler, biosdisk_enum_root
; add new handlers here
dd 0
 
endg
file_system_lfn:
; in: ebx->fileinfo block
; operation codes:
; 0 : read file
; 1 : read folder
; 2 : create/rewrite file
; 3 : write/append to file
; 4 : set end of file
; 5 : get file/directory attributes structure
; 6 : set file/directory attributes structure
; 7 : start application
; 8 : delete file
; 9 : create directory
 
; parse file name
lea esi, [ebx+20]
lodsb
test al, al
jnz @f
mov esi, [esi]
lodsb
@@:
cmp al, '/'
jz .notcurdir
dec esi
mov ebp, esi
test al, al
jnz @f
xor ebp, ebp
@@:
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
jmp .parse_normal
.notcurdir:
cmp byte [esi], 0
jz .rootdir
call process_replace_file_name
.parse_normal:
cmp dword [ebx], 7
jne @F
mov edx, [ebx+4]
mov ebx, [ebx+8]
call fs_execute ; esi+ebp, ebx, edx
mov [image_of_eax], eax
ret
@@:
mov edi, rootdirs-8
xor ecx, ecx
push esi
.scan1:
pop esi
add edi, ecx
scasd
scasd
mov cl, byte [edi]
test cl, cl
jz .notfound_try
inc edi
push esi
@@:
lodsb
or al, 20h
scasb
loopz @b
jnz .scan1
lodsb
cmp al, '/'
jz .found1
test al, al
jnz .scan1
pop eax
; directory /xxx
.maindir:
mov esi, [edi+4]
.maindir_noesi:
cmp dword [ebx], 1
jnz .access_denied
xor eax, eax
mov ebp, [ebx+12] ;количество блоков для считывания
mov edx, [ebx+16] ;куда записывать рузельтат
; add edx, std_application_base_address
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
mov edi, edx
push ecx
mov ecx, 32/4
rep stosd
pop ecx
mov byte [edx], 1 ; version
.maindir_loop:
call esi
jc .maindir_done
inc dword [edx+8]
dec dword [esp]
jns .maindir_loop
dec ebp
js .maindir_loop
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], 1 ; name type: UNICODE
push eax
xor eax, eax
add edi, 8
push ecx
mov ecx, 40/4-2
rep stosd
pop ecx
pop eax
push eax edx
; convert number in eax to decimal UNICODE string
push edi
push ecx
push -'0'
mov ecx, 10
@@:
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
@@:
pop eax
add al, '0'
stosb
test bl, 1 ; UNICODE name?
jz .ansi2
mov byte [edi], 0
inc edi
.ansi2:
test al, al
jnz @b
mov byte [edi-1], 0
pop ecx
pop edi
; UNICODE name length is 520 bytes, ANSI - 264
add edi, 520
test bl, 1
jnz @f
sub edi, 520-264
@@:
pop edx eax
jmp .maindir_loop
.maindir_done:
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
@@:
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
; directory /
.rootdir:
cmp dword [ebx], 1 ; read folder?
jz .readroot
.access_denied:
mov dword [image_of_eax], 10 ; access denied
ret
 
.readroot:
; virtual root folder - special handler
mov esi, virtual_root_query
mov ebp, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
push dword [ebx+4] ; first block
mov ebx, [ebx+8] ; flags
xor eax, eax
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area
mov edi, edx
mov ecx, 32/4
rep stosd
mov byte [edx], 1 ; version
.readroot_loop:
cmp dword [esi], eax
jz .readroot_done_static
call dword [esi]
add esi, 4
test eax, eax
jnz @f
.readroot_next:
or ecx, -1
xchg esi, edi
repnz scasb
xchg esi, edi
jmp .readroot_loop
@@:
xor eax, eax
inc dword [edx+8]
dec dword [esp]
jns .readroot_next
dec ebp
js .readroot_next
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], ebx ; name type: UNICODE
add edi, 8
mov ecx, 40/4-2
rep stosd
push edi
@@:
lodsb
stosb
test bl, 1
jz .ansi
mov byte [edi], 0
inc edi
.ansi:
test eax, eax
jnz @b
pop edi
add edi, 520
test bl, 1
jnz .readroot_loop
sub edi, 520-264
jmp .readroot_loop
.readroot_done_static:
mov esi, fs_additional_handlers-8
sub esp, 16
.readroot_ah_loop:
add esi, 8
cmp dword [esi], 0
jz .readroot_done
xor eax, eax
.readroot_ah_loop2:
push edi
lea edi, [esp+4]
call dword [esi+4]
pop edi
test eax, eax
jz .readroot_ah_loop
inc dword [edx+8]
dec dword [esp+16]
jns .readroot_ah_loop2
dec ebp
js .readroot_ah_loop2
push eax
xor eax, eax
inc dword [edx+4]
mov dword [edi], 0x10 ; attributes: folder
mov dword [edi+4], ebx
add edi, 8
mov ecx, 40/4-2
rep stosd
push esi edi
lea esi, [esp+12]
@@:
lodsb
stosb
test bl, 1
jz .ansi3
mov byte [edi], 0
inc edi
.ansi3:
test al, al
jnz @b
pop edi esi eax
add edi, 520
test bl, 1
jnz .readroot_ah_loop2
sub edi, 520-264
jmp .readroot_ah_loop2
.readroot_done:
add esp, 16
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
@@:
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
.notfound_try:
mov edi, fs_additional_handlers
@@:
cmp dword [edi], 0
jz .notfound
call dword [edi]
scasd
scasd
jmp @b
.notfound:
mov dword [image_of_eax], ERROR_FILE_NOT_FOUND
and dword [image_of_ebx], 0
ret
 
.notfounda:
cmp edi, esp
jnz .notfound
add esp, 8
jmp .notfound
 
.found1:
pop eax
cmp byte [esi], 0
jz .maindir
.found2:
; read partition number
xor ecx, ecx
xor eax, eax
@@:
lodsb
cmp al, '/'
jz .done1
test al, al
jz .done1
sub al, '0'
cmp al, 9
ja .notfounda
lea ecx, [ecx*5]
lea ecx, [ecx*2+eax]
jmp @b
.done1:
jecxz .notfounda
test al, al
jnz @f
dec esi
@@:
cmp byte [esi], 0
jnz @f
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
@@:
; now [edi] contains handler address, ecx - partition number,
; esi points to ASCIIZ string - rest of name
jmp dword [edi]
 
; handlers for devices
; in: ecx = 0 => query virtual directory /xxx
; in: ecx = partition number
; esi -> relative (for device) name
; ebx -> fileinfo
; ebp = 0 or pointer to rest of name from folder addressed by esi
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx
 
fs_OnRamdisk:
cmp ecx, 1
jnz file_system_lfn.notfound
mov eax, [ebx]
cmp eax, fs_NumRamdiskServices
jae .not_impl
mov ecx, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
add ebx, 4
call dword [fs_RamdiskServices + eax*4]
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
.not_impl:
mov dword [image_of_eax], 2 ; not implemented
ret
 
fs_NotImplemented:
mov eax, 2
ret
 
fs_RamdiskServices:
dd fs_RamdiskRead
dd fs_RamdiskReadFolder
dd fs_RamdiskRewrite
dd fs_RamdiskWrite
dd fs_RamdiskSetFileEnd
dd fs_RamdiskGetFileInfo
dd fs_RamdiskSetFileInfo
dd 0
dd fs_RamdiskDelete
dd fs_RamdiskCreateFolder
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4
 
fs_OnFloppy:
cmp ecx, 2
ja file_system_lfn.notfound
mov eax, [ebx]
cmp eax, fs_NumFloppyServices
jae fs_OnRamdisk.not_impl
call reserve_flp
mov [flp_number], cl
mov ecx, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
add ebx, 4
call dword [fs_FloppyServices + eax*4]
and [flp_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
 
fs_FloppyServices:
dd fs_FloppyRead
dd fs_FloppyReadFolder
dd fs_FloppyRewrite
dd fs_FloppyWrite
dd fs_FloppySetFileEnd
dd fs_FloppyGetFileInfo
dd fs_FloppySetFileInfo
dd 0
dd fs_FloppyDelete
dd fs_FloppyCreateFolder
fs_NumFloppyServices = ($ - fs_FloppyServices)/4
 
fs_OnHd0:
call reserve_hd1
mov [hdbase], 0x1F0
mov [hdid], 0
push 1
jmp fs_OnHd
fs_OnHd1:
call reserve_hd1
mov [hdbase], 0x1F0
mov [hdid], 0x10
push 2
jmp fs_OnHd
fs_OnHd2:
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0
push 3
jmp fs_OnHd
fs_OnHd3:
call reserve_hd1
mov [hdbase], 0x170
mov [hdid], 0x10
push 4
fs_OnHd:
call reserve_hd_channel
pop eax
mov [hdpos], eax
cmp ecx, 0x100
jae fs_OnHdAndBd.nf
cmp cl, [DRIVE_DATA+1+eax]
fs_OnHdAndBd:
jbe @f
.nf:
call free_hd_channel
and [hd1_status], 0
mov dword [image_of_eax], 5 ; not found
ret
@@:
mov [known_part], ecx ; mov [fat32part], ecx
push ebx esi
call choice_necessity_partition_1
pop esi ebx
mov ecx, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
mov eax, [ebx]
cmp eax, fs_NumHdServices
jae .not_impl
add ebx, 4
call dword [fs_HdServices + eax*4]
call free_hd_channel
and [hd1_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
.not_impl:
call free_hd_channel
and [hd1_status], 0
mov dword [image_of_eax], 2 ; not implemented
ret
 
fs_HdServices:
dd fs_HdRead
dd fs_HdReadFolder
dd fs_HdRewrite
dd fs_HdWrite
dd fs_HdSetFileEnd
dd fs_HdGetFileInfo
dd fs_HdSetFileInfo
dd 0
dd fs_HdDelete
dd fs_HdCreateFolder
fs_NumHdServices = ($ - fs_HdServices)/4
 
;*******************************************************
fs_OnCd0:
call reserve_cd
mov [ChannelNumber],1
mov [DiskNumber],0
push 6
push 1
jmp fs_OnCd
fs_OnCd1:
call reserve_cd
mov [ChannelNumber],1
mov [DiskNumber],1
push 4
push 2
jmp fs_OnCd
fs_OnCd2:
call reserve_cd
mov [ChannelNumber],2
mov [DiskNumber],0
push 2
push 3
jmp fs_OnCd
fs_OnCd3:
call reserve_cd
mov [ChannelNumber],2
mov [DiskNumber],1
push 0
push 4
fs_OnCd:
call reserve_cd_channel
pop eax
mov [cdpos], eax
pop eax
cmp ecx, 0x100
jae .nf
push ecx ebx
mov cl,al
mov bl,[DRIVE_DATA+1]
shr bl,cl
test bl,2
pop ebx ecx
 
jnz @f
.nf:
call free_cd_channel
and [cd_status], 0
mov dword [image_of_eax], 5 ; not found
ret
@@:
mov ecx, [ebx+12]
mov edx, [ebx+16]
; add edx, std_application_base_address
mov eax, [ebx]
cmp eax,fs_NumCdServices
jae .not_impl
add ebx, 4
call dword [fs_CdServices + eax*4]
call free_cd_channel
and [cd_status], 0
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
.not_impl:
call free_cd_channel
and [cd_status], 0
mov dword [image_of_eax], 2 ; not implemented
ret
 
fs_CdServices:
dd fs_CdRead
dd fs_CdReadFolder
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_NotImplemented
dd fs_CdGetFileInfo
dd fs_NotImplemented
dd 0
dd fs_NotImplemented
dd fs_NotImplemented
fs_NumCdServices = ($ - fs_CdServices)/4
 
;*******************************************************
 
fs_HasRamdisk:
mov al, 1 ; we always have ramdisk
ret
 
fs_HasFloppy:
cmp byte [DRIVE_DATA], 0
setnz al
ret
 
fs_HasHd0:
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 01000000b
setz al
ret
fs_HasHd1:
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00010000b
setz al
ret
fs_HasHd2:
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00000100b
setz al
ret
fs_HasHd3:
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000001b
setz al
ret
 
;*******************************************************
fs_HasCd0:
mov al, [DRIVE_DATA+1]
and al, 11000000b
cmp al, 10000000b
setz al
ret
fs_HasCd1:
mov al, [DRIVE_DATA+1]
and al, 00110000b
cmp al, 00100000b
setz al
ret
fs_HasCd2:
mov al, [DRIVE_DATA+1]
and al, 00001100b
cmp al, 00001000b
setz al
ret
fs_HasCd3:
mov al, [DRIVE_DATA+1]
and al, 00000011b
cmp al, 00000010b
setz al
ret
;*******************************************************
 
; fs_NextXXX functions:
; in: eax = partition number, from which start to scan
; out: CF=1 => no more partitions
; CF=0 => eax=next partition number
 
fs_NextRamdisk:
; we always have /rd/1
test eax, eax
stc
jnz @f
mov al, 1
clc
@@:
ret
 
fs_NextFloppy:
; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0)
test byte [DRIVE_DATA], 0xF0
jz .no1
test eax, eax
jnz .no1
inc eax
ret ; CF cleared
.no1:
test byte [DRIVE_DATA], 0x0F
jz .no2
cmp al, 2
jae .no2
mov al, 2
clc
ret
.no2:
stc
ret
 
; on hdx, we have partitions from 1 to [0x40002+x]
fs_NextHd0:
push 0
jmp fs_NextHd
fs_NextHd1:
push 1
jmp fs_NextHd
fs_NextHd2:
push 2
jmp fs_NextHd
fs_NextHd3:
push 3
fs_NextHd:
pop ecx
movzx ecx, byte [DRIVE_DATA+2+ecx]
cmp eax, ecx
jae fs_NextFloppy.no2
inc eax
clc
ret
 
;*******************************************************
fs_NextCd:
; we always have /cdX/1
test eax, eax
stc
jnz @f
mov al, 1
clc
@@:
ret
;*******************************************************
 
; Additional FS handlers.
; This handler gets the control each time when fn 70 is called
; with unknown item of root subdirectory.
; in: esi -> name
; ebp = 0 or rest of name relative to esi
; out: if the handler processes path, he must not return in file_system_lfn,
; but instead pop return address and return directly to the caller
; otherwise simply return
 
; here we test for /bd<N>/... - BIOS disks
biosdisk_handler:
cmp [NumBiosDisks], 0
jz .ret
mov al, [esi]
or al, 20h
cmp al, 'b'
jnz .ret
mov al, [esi+1]
or al, 20h
cmp al, 'd'
jnz .ret
push esi
inc esi
inc esi
cmp byte [esi], '0'
jb .ret2
cmp byte [esi], '9'
ja .ret2
xor edx, edx
@@:
lodsb
test al, al
jz .ok
cmp al, '/'
jz .ok
sub al, '0'
cmp al, 9
ja .ret2
lea edx, [edx*5]
lea edx, [edx*2+eax]
jmp @b
.ret2:
pop esi
.ret:
ret
.ok:
cmp al, '/'
jz @f
dec esi
@@:
add dl, 80h
xor ecx, ecx
@@:
cmp dl, [BiosDisksData+ecx*4]
jz .ok2
inc ecx
cmp ecx, [NumBiosDisks]
jb @b
jmp .ret2
.ok2:
add esp, 8
test al, al
jnz @f
mov esi, fs_BdNext
jmp file_system_lfn.maindir_noesi
@@:
push ecx
push fs_OnBd
mov edi, esp
jmp file_system_lfn.found2
 
fs_BdNext:
cmp eax, [BiosDiskPartitions+ecx*4]
inc eax
cmc
ret
 
fs_OnBd:
pop edx edx
; edx = disk number, ecx = partition number
; esi+ebp = name
call reserve_hd1
add edx, 0x80
mov [hdpos], edx
cmp ecx, [BiosDiskPartitions+(edx-0x80)*4]
jmp fs_OnHdAndBd
 
; This handler is called when virtual root is enumerated
; and must return all items which can be handled by this.
; It is called several times, first time with eax=0
; in: eax = 0 for first call, previously returned value for subsequent calls
; out: eax = 0 => no more items
; eax != 0 => buffer pointed to by edi contains name of item
 
; here we enumerate existing BIOS disks /bd<N>
biosdisk_enum_root:
cmp eax, [NumBiosDisks]
jae .end
push eax
movzx eax, byte [BiosDisksData+eax*4]
sub al, 80h
push eax
mov al, 'b'
stosb
mov al, 'd'
stosb
pop eax
cmp al, 10
jae .big
add al, '0'
stosb
mov byte [edi], 0
pop eax
inc eax
ret
.end:
xor eax, eax
ret
.big:
push ecx edx
push -'0'
mov ecx, 10
@@:
xor edx, edx
div ecx
push edx
test eax, eax
jnz @b
xchg eax, edx
@@:
pop eax
add al, '0'
stosb
jnz @b
pop edx ecx
pop eax
inc eax
ret
 
process_replace_file_name:
mov ebp, [full_file_name_table]
mov edi, [full_file_name_table.size]
dec edi
shl edi, 7
add edi, ebp
.loop:
cmp edi, ebp
jb .notfound
push esi edi
@@:
cmp byte [edi], 0
jz .dest_done
lodsb
test al, al
jz .cont
or al, 20h
scasb
jz @b
jmp .cont
.dest_done:
cmp byte [esi], 0
jz .found
cmp byte [esi], '/'
jnz .cont
inc esi
jmp .found
.cont:
pop edi esi
sub edi, 128
jmp .loop
.found:
pop edi eax
mov ebp, esi
cmp byte [esi], 0
lea esi, [edi+64]
jnz .ret
.notfound:
xor ebp, ebp
.ret:
ret
 
sys_current_directory:
; mov esi, [current_slot]
; mov esi, [esi+APPDATA.cur_dir]
; mov edx, esi
 
;get length string of appdata.cur_dir
mov eax, [current_slot]
mov edi, [eax+APPDATA.cur_dir]
 
dec ebx
jz .set
dec ebx
jz .get
ret
.get:
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len
; for our code: ebx->buffer,ecx=len
max_cur_dir equ 0x1000
 
mov ebx,edi
 
push ecx
push edi
 
xor eax,eax
mov ecx,max_cur_dir
 
repne scasb ;find zerro at and string
jnz .error ; no zero in cur_dir: internal error, should not happen
 
sub edi,ebx ;lenght for copy
inc edi
mov [esp+32+8],edi ;return in eax
 
cmp edx, edi
jbe @f
mov edx, edi
@@:
;source string
pop esi
;destination string
pop edi
cmp edx, 1
jbe .ret
 
mov al,'/' ;start string with '/'
stosb
mov ecx,edx
rep movsb ;copy string
.ret: ret
 
.error: add esp,8
or dword [esp+32],-1 ;error not found zerro at string ->[eax+APPDATA.cur_dir]
ret
.set:
; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string
; for our code: ebx->string to set
; use generic resolver with APPDATA.cur_dir as destination
push max_cur_dir ;0x1000
push edi ;destination
mov ebx,ecx
call get_full_file_name
ret
 
; in: ebx = file name, [esp+4] = destination, [esp+8] = sizeof destination
; destroys all registers except ebp,esp
get_full_file_name:
push ebp
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
mov edx, esi
@@:
inc esi
cmp byte [esi-1], 0
jnz @b
dec esi
cmp byte [ebx], '/'
jz .set_absolute
; string gives relative path
mov edi, [esp+8] ; destination
.relative:
cmp byte [ebx], 0
jz .set_ok
cmp word [ebx], '.'
jz .set_ok
cmp word [ebx], './'
jnz @f
add ebx, 2
jmp .relative
@@:
cmp word [ebx], '..'
jnz .doset_relative
cmp byte [ebx+2], 0
jz @f
cmp byte [ebx+2], '/'
jnz .doset_relative
@@:
dec esi
cmp byte [esi], '/'
jnz @b
add ebx, 3
jmp .relative
.set_ok:
cmp edx, edi ; is destination equal to APPDATA.cur_dir?
jz .set_ok.cur_dir
sub esi, edx
cmp esi, [esp+12]
jb .set_ok.copy
.fail:
mov byte [edi], 0
xor eax, eax ; fail
pop ebp
ret 8
.set_ok.copy:
mov ecx, esi
mov esi, edx
rep movsb
mov byte [edi], 0
.ret.ok:
mov al, 1 ; ok
pop ebp
ret 8
.set_ok.cur_dir:
mov byte [esi], 0
jmp .ret.ok
.doset_relative:
cmp edx, edi
jz .doset_relative.cur_dir
sub esi, edx
cmp esi, [esp+12]
jae .fail
mov ecx, esi
mov esi, edx
mov edx, edi
rep movsb
jmp .doset_relative.copy
.doset_relative.cur_dir:
mov edi, esi
.doset_relative.copy:
add edx, [esp+12]
mov byte [edi], '/'
inc edi
cmp edi, edx
jae .overflow
@@:
mov al, [ebx]
inc ebx
stosb
test al, al
jz .ret.ok
cmp edi, edx
jb @b
.overflow:
dec edi
jmp .fail
.set_absolute:
lea esi, [ebx+1]
call process_replace_file_name
mov edi, [esp+8]
mov edx, [esp+12]
add edx, edi
.set_copy:
lodsb
stosb
test al, al
jz .set_part2
.set_copy_cont:
cmp edi, edx
jb .set_copy
jmp .overflow
.set_part2:
mov esi, ebp
xor ebp, ebp
test esi, esi
jz .ret.ok
mov byte [edi-1], '/'
jmp .set_copy_cont
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/fs/iso9660.inc
0,0 → 1,757
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
uglobal
cd_current_pointer_of_input dd 0
cd_current_pointer_of_input_2 dd 0
cd_mem_location dd 0
cd_counter_block dd 0
IDE_Channel_1 db 0
IDE_Channel_2 db 0
endg
 
reserve_cd:
 
cli
cmp [cd_status],0
je reserve_ok2
 
sti
call change_task
jmp reserve_cd
 
reserve_ok2:
 
push eax
mov eax,[CURRENT_TASK]
shl eax,5
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov [cd_status],eax
pop eax
sti
ret
 
reserve_cd_channel:
cmp [ChannelNumber],1
jne .IDE_Channel_2
.IDE_Channel_1:
cli
cmp [IDE_Channel_1],0
je .reserve_ok_1
sti
call change_task
jmp .IDE_Channel_1
.IDE_Channel_2:
cli
cmp [IDE_Channel_2],0
je .reserve_ok_2
sti
call change_task
jmp .IDE_Channel_1
.reserve_ok_1:
mov [IDE_Channel_1],1
ret
.reserve_ok_2:
mov [IDE_Channel_2],1
ret
 
free_cd_channel:
cmp [ChannelNumber],1
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1],0
ret
.IDE_Channel_2:
mov [IDE_Channel_2],0
ret
 
uglobal
cd_status dd 0
endg
 
;----------------------------------------------------------------
;
; fs_CdRead - LFN variant for reading CD disk
;
; esi points to filename /dir1/dir2/.../dirn/file,0
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_CdRead:
push edi
cmp byte [esi], 0
jnz @f
.noaccess:
pop edi
.noaccess_2:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
.noaccess_3:
pop eax edx ecx edi
jmp .noaccess_2
 
@@:
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode],0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.found:
mov edi,[cd_current_pointer_of_input]
test byte [edi+25],10b ; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
.reteof:
mov eax, 6 ; end of file
pop edi
ret
@@:
mov ebx, [ebx]
.l1:
push ecx edx
push 0
mov eax, [edi+10] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6
@@:
mov eax,[edi+2]
mov [CDSectorAddress],eax
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_sector:
test ecx, ecx
jz .done
sub ebx, 2048
jae .next
add ebx, 2048
jnz .incomplete_sector
cmp ecx, 2048
jb .incomplete_sector
; we may read and memmove complete sector
mov [CDDataBuf_pointer],edx
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode],0
jne .noaccess_3
add edx, 2048
sub ecx, 2048
.next:
inc dword [CDSectorAddress]
jmp .new_sector
.incomplete_sector:
; we must read and memmove incomplete sector
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà
cmp [DevErrorCode],0
jne .noaccess_3
push ecx
add ecx, ebx
cmp ecx, 2048
jbe @f
mov ecx, 2048
@@:
sub ecx, ebx
push edi esi ecx
mov edi,edx
lea esi, [CDDataBuf + ebx]
cld
rep movsb
pop ecx esi edi
add edx, ecx
sub [esp], ecx
pop ecx
xor ebx, ebx
jmp .next
 
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
.eof:
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
 
;----------------------------------------------------------------
;
; fs_CdReadFolder - LFN variant for reading CD disk folder
;
; esi points to filename /dir1/dir2/.../dirn/file,0
; ebx pointer to structure 32-bit number = first wanted block, 0+
; & flags (bitfields)
; flags: bit 0: 0=ANSI names, 1=UNICODE names
; ecx number of blocks to read, 0+
; edx mem location to return data
;
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_CdReadFolder:
push edi
call cd_find_lfn
jnc .found
pop edi
cmp [DevErrorCode], 0
jne .noaccess_1
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.found:
mov edi, [cd_current_pointer_of_input]
test byte [edi+25], 10b ; do not allow read directories
jnz .found_dir
pop edi
.noaccess_1:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
.found_dir:
mov eax, [edi+2] ; eax=cluster
mov [CDSectorAddress], eax
mov eax, [edi+10] ; ðàçìåð äèðåêòðîðèè
.doit:
; init header
push eax ecx
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov [cd_mem_location], edx
add [cd_mem_location], 32
; íà÷èíàåì ïåðåáðîñêó ÁÄÂÊ â ÓÑÂÊ
;.mainloop:
mov [cd_counter_block], dword 0
dec dword [CDSectorAddress]
push ecx
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer], CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
cmp [DevErrorCode], 0
jne .noaccess_1
call .get_names_from_buffer
sub eax,2048
; äèðåêòîðèÿ çàêîí÷èëàñü?
ja .read_to_buffer
mov edi, [cd_counter_block]
mov [edx+8], edi
mov edi, [ebx]
sub [edx+4], edi
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
@@:
pop ecx edi
mov ebx, [edx+4]
ret
 
.get_names_from_buffer:
mov [cd_current_pointer_of_input_2],CDDataBuf
push eax esi edi edx
.get_names_from_buffer_1:
call cd_get_name
jc .end_buffer
inc dword [cd_counter_block]
mov eax,[cd_counter_block]
cmp [ebx],eax
jae .get_names_from_buffer_1
test ecx, ecx
jz .get_names_from_buffer_1
mov edi,[cd_counter_block]
mov [edx+4],edi
dec ecx
mov esi,ebp
mov edi,[cd_mem_location]
add edi,40
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
jnz .unicode
; jmp .unicode
.ansi:
cmp [cd_counter_block],2
jbe .ansi_parent_directory
cld
lodsw
xchg ah,al
call uni2ansi_char
cld
stosb
; ïðîâåðêà êîíöà ôàéëà
mov ax,[esi]
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_1
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp esi,eax
je .cd_get_parameters_of_file_1
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp esi,eax
jb .ansi
.cd_get_parameters_of_file_1:
mov [edi],byte 0
call cd_get_parameters_of_file
add [cd_mem_location],304
jmp .get_names_from_buffer_1
 
.ansi_parent_directory:
cmp [cd_counter_block],2
je @f
mov [edi],byte '.'
inc edi
jmp .cd_get_parameters_of_file_1
@@:
mov [edi],word '..'
add edi,2
jmp .cd_get_parameters_of_file_1
 
.unicode:
cmp [cd_counter_block],2
jbe .unicode_parent_directory
cld
movsw
; ïðîâåðêà êîíöà ôàéëà
mov ax,[esi]
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .cd_get_parameters_of_file_2
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp esi,eax
je .cd_get_parameters_of_file_2
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp esi,eax
jb .unicode
.cd_get_parameters_of_file_2:
mov [edi],word 0
call cd_get_parameters_of_file
add [cd_mem_location],560
jmp .get_names_from_buffer_1
 
.unicode_parent_directory:
cmp [cd_counter_block],2
je @f
mov [edi],word 2E00h ; '.'
add edi,2
jmp .cd_get_parameters_of_file_2
@@:
mov [edi],dword 2E002E00h ; '..'
add edi,4
jmp .cd_get_parameters_of_file_2
 
.end_buffer:
pop edx edi esi eax
ret
 
cd_get_parameters_of_file:
mov edi,[cd_mem_location]
cd_get_parameters_of_file_1:
; ïîëó÷àåì àòðèáóòû ôàéëà
xor eax,eax
; ôàéë íå àðõèâèðîâàëñÿ
inc eax
shl eax,1
; ýòî êàòàëîã?
test [ebp-8],byte 2
jz .file
inc eax
.file:
; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò
; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì
shl eax,3
; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå)
test [ebp-8],byte 1
jz .hidden
inc eax
.hidden:
shl eax,1
; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD
inc eax
mov [edi],eax
; ïîëó÷àåì âðåìÿ äëÿ ôàéëà
;÷àñ
movzx eax,byte [ebp-12]
shl eax,8
;ìèíóòà
mov al,[ebp-11]
shl eax,8
;ñåêóíäà
mov al,[ebp-10]
;âðåìÿ ñîçäàíèÿ ôàéëà
mov [edi+8],eax
;âðåìÿ ïîñëåäíåãî äîñòóïà
mov [edi+16],eax
;âðåìÿ ïîñëåäíåé çàïèñè
mov [edi+24],eax
; ïîëó÷àåì äàòó äëÿ ôàéëà
;ãîä
movzx eax,byte [ebp-15]
add eax,1900
shl eax,8
;ìåñÿö
mov al,[ebp-14]
shl eax,8
;äåíü
mov al,[ebp-13]
;äàòà ñîçäàíèÿ ôàéëà
mov [edi+12],eax
;âðåìÿ ïîñëåäíåãî äîñòóïà
mov [edi+20],eax
;âðåìÿ ïîñëåäíåé çàïèñè
mov [edi+28],eax
; ïîëó÷àåì òèï äàííûõ èìåíè
xor eax,eax
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE
jnz .unicode_1
mov [edi+4],eax
jmp @f
.unicode_1:
inc eax
mov [edi+4],eax
@@:
; ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ
xor eax,eax
mov [edi+32+4],eax
mov eax,[ebp-23]
mov [edi+32],eax
ret
 
;----------------------------------------------------------------
;
; fs_CdGetFileInfo - LFN variant for CD
; get file/directory attributes structure
;
;----------------------------------------------------------------
fs_CdGetFileInfo:
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
@@:
push edi
call cd_find_lfn
pushfd
cmp [DevErrorCode], 0
jz @f
popfd
pop edi
mov eax, 11
ret
@@:
popfd
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
@@:
 
mov edi, edx
push ebp
mov ebp, [cd_current_pointer_of_input]
add ebp, 33
call cd_get_parameters_of_file_1
pop ebp
and dword [edi+4], 0
pop edi
xor eax, eax
ret
 
;----------------------------------------------------------------
cd_find_lfn:
mov [cd_appl_data],0
; in: esi+ebp -> name
; out: CF=1 - file not found
; else CF=0 and [cd_current_pointer_of_input] direntry
push eax esi
; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ
 
call WaitUnitReady
cmp [DevErrorCode],0
jne .access_denied
 
call prevent_medium_removal
; òåñòîâîå ÷òåíèå
mov [CDSectorAddress],dword 16
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ;_1
cmp [DevErrorCode],0
jne .access_denied
 
; âû÷èñëåíèå ïîñëåäíåé ñåññèè
call WaitUnitReady
cmp [DevErrorCode],0
jne .access_denied
call Read_TOC
mov ah,[CDDataBuf+4+4]
mov al,[CDDataBuf+4+5]
shl eax,16
mov ah,[CDDataBuf+4+6]
mov al,[CDDataBuf+4+7]
add eax,15
mov [CDSectorAddress],eax
; mov [CDSectorAddress],dword 15
mov [CDDataBuf_pointer],CDDataBuf
 
.start:
inc dword [CDSectorAddress]
call ReadCDWRetr ;_1
cmp [DevErrorCode],0
jne .access_denied
 
.start_check:
; ïðîâåðêà íà âøèâîñòü
cmp [CDDataBuf+1],dword 'CD00'
jne .access_denied
cmp [CDDataBuf+5],byte '1'
jne .access_denied
; ñåêòîð ÿâëÿåòñÿ òåðìèíàòîðîì íàáîð äåñêðèïòîðîâ òîìîâ?
cmp [CDDataBuf],byte 0xff
je .access_denied
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì è óëó÷øåííûì äåñêðèïòîðîì òîìà?
cmp [CDDataBuf],byte 0x2
jne .start
; ñåêòîð ÿâëÿåòñÿ äîïîëíèòåëüíûì äåñêðèïòîðîì òîìà?
cmp [CDDataBuf+6],byte 0x1
jne .start
 
; ïàðàìåòðû root äèðåêòðîðèè
mov eax,[CDDataBuf+0x9c+2] ; íà÷àëî root äèðåêòðîðèè
mov [CDSectorAddress],eax
mov eax,[CDDataBuf+0x9c+10] ; ðàçìåð root äèðåêòðîðèè
cmp byte [esi], 0
jnz @f
mov [cd_current_pointer_of_input],CDDataBuf+0x9c
jmp .done
@@:
; íà÷èíàåì ïîèñê
.mainloop:
dec dword [CDSectorAddress]
.read_to_buffer:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè
cmp [DevErrorCode],0
jne .access_denied
push ebp
call cd_find_name_in_buffer
pop ebp
jnc .found
sub eax,2048
; äèðåêòîðèÿ çàêîí÷èëàñü?
cmp eax,0
ja .read_to_buffer
; íåò èñêîìîãî ýëåìåíòà öåïî÷êè
.access_denied:
pop esi eax
mov [cd_appl_data],1
stc
ret
; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí
.found:
; êîíåö ïóòè ôàéëà
cmp byte [esi-1], 0
jz .done
.nested:
mov eax,[cd_current_pointer_of_input]
push dword [eax+2]
pop dword [CDSectorAddress] ; íà÷àëî äèðåêòîðèè
mov eax,[eax+2+8] ; ðàçìåð äèðåêòîðèè
jmp .mainloop
; óêàçàòåëü ôàéëà íàéäåí
.done:
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .nested
@@:
pop esi eax
mov [cd_appl_data],1
clc
ret
 
cd_find_name_in_buffer:
mov [cd_current_pointer_of_input_2],CDDataBuf
.start:
call cd_get_name
jc .not_found
call cd_compare_name
jc .start
.found:
clc
ret
.not_found:
stc
ret
 
cd_get_name:
push eax
mov ebp,[cd_current_pointer_of_input_2]
mov [cd_current_pointer_of_input],ebp
mov eax,[ebp]
test eax,eax ; âõîäû çàêîí÷èëèñü?
jz .next_sector
cmp ebp,CDDataBuf+2048 ; áóôåð çàêîí÷èëñÿ?
jae .next_sector
movzx eax, byte [ebp]
add [cd_current_pointer_of_input_2],eax ; ñëåäóþùèé âõîä êàòàëîãà
add ebp,33 ; óêàçàòåëü óñòàíîâëåí íà íà÷àëî èìåíè
pop eax
clc
ret
.next_sector:
pop eax
stc
ret
 
cd_compare_name:
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
; in: esi->name, ebp->name
; out: if names match: ZF=1 and esi->next component of name
; else: ZF=0, esi is not changed
; destroys eax
push esi eax edi
mov edi,ebp
.loop:
cld
lodsb
push eax
call char_todown
call ansi2uni_char
xchg ah,al
scasw
pop eax
je .coincides
call char_toupper
call ansi2uni_char
xchg ah,al
sub edi,2
scasw
jne .name_not_coincide
.coincides:
cmp [esi],byte '/' ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
cmp [esi],byte 0 ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà
je .done
jmp .loop
.name_not_coincide:
pop edi eax esi
stc
ret
.done:
; ïðîâåðêà êîíöà ôàéëà
cmp [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';'
je .done_1
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì
movzx eax,byte [ebp-33]
add eax,ebp
sub eax,34
cmp edi,eax
je .done_1
; ïðîâåðêà êîíöà ïàïêè
movzx eax,byte [ebp-1]
add eax,ebp
cmp edi,eax
jne .name_not_coincide
.done_1:
pop edi eax
add esp,4
inc esi
clc
ret
 
char_todown:
; convert character to uppercase, using cp866 encoding
; in: al=symbol
; out: al=converted symbol
cmp al, 'A'
jb .ret
cmp al, 'Z'
jbe .az
cmp al, '€'
jb .ret
cmp al, ''
jb .rus1
cmp al, 'Ÿ'
ja .ret
; 0x90-0x9F -> 0xE0-0xEF
add al, 'à'-''
.ret:
ret
.rus1:
; 0x80-0x8F -> 0xA0-0xAF
.az:
add al, 0x20
ret
 
uni2ansi_char:
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding
; in: ax=UNICODE character
; out: al=converted ANSI character
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
.unk:
mov al, '_'
jmp .doit
.yo1:
mov al, 'ð'
jmp .doit
.yo2:
mov al, 'ñ'
jmp .doit
.rus1:
; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
jmp .doit
.rus2:
; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
.ascii:
.doit:
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/fs/ntfs.inc
0,0 → 1,1829
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
ntfs_test_bootsec:
; in: ebx->buffer, edx=size of partition
; out: CF set <=> invalid
; 1. Name=='NTFS '
cmp dword [ebx+3], 'NTFS'
jnz .no
cmp dword [ebx+7], ' '
jnz .no
; 2. Number of bytes per sector is the same as for physical device
; (that is, 0x200 for hard disk)
cmp word [ebx+11], 0x200
jnz .no
; 3. Number of sectors per cluster must be power of 2
movzx eax, byte [ebx+13]
dec eax
js .no
test al, [ebx+13]
jnz .no
; 4. FAT parameters must be zero
cmp word [ebx+14], 0
jnz .no
cmp dword [ebx+16], 0
jnz .no
cmp byte [ebx+20], 0
jnz .no
cmp word [ebx+22], 0
jnz .no
cmp dword [ebx+32], 0
jnz .no
; 5. Number of sectors <= partition size
cmp dword [ebx+0x2C], 0
ja .no
cmp [ebx+0x28], edx
ja .no
; 6. $MFT and $MFTMirr clusters must be within partition
cmp dword [ebx+0x34], 0
ja .no
push edx
movzx eax, byte [ebx+13]
mul dword [ebx+0x30]
test edx, edx
pop edx
jnz .no
cmp eax, edx
ja .no
cmp dword [ebx+0x3C], 0
ja .no
push edx
movzx eax, byte [ebx+13]
mul dword [ebx+0x38]
test edx, edx
pop edx
jnz .no
cmp eax, edx
ja .no
; 7. Clusters per FRS must be either negative and in [-31,-9] or positive and power of 2
movsx eax, byte [ebx+0x40]
cmp al, -31
jl .no
cmp al, -9
jle @f
dec eax
js .no
test [ebx+0x40], al
jnz .no
@@:
; 8. Same for clusters per IndexAllocationBuffer
movsx eax, byte [ebx+0x44]
cmp al, -31
jl .no
cmp al, -9
jle @f
dec eax
js .no
test [ebx+0x44], al
jnz .no
@@:
; OK, this is correct NTFS bootsector
clc
ret
.no:
; No, this bootsector isn't NTFS
stc
ret
 
ntfs_setup: ; CODE XREF: part_set.inc
; By given bootsector, initialize some NTFS variables
; call ntfs_test_bootsec ; checking boot sector was already
; jc problem_fat_dec_count
movzx eax, byte [ebx+13]
mov [ntfs_data.sectors_per_cluster], eax
mov eax, [ebx+0x28]
add eax, [PARTITION_START]
dec eax
mov [PARTITION_END], eax
mov [fs_type], 1
mov eax, [ebx+0x30]
mov [ntfs_data.mft_cluster], eax
mov eax, [ebx+0x38]
mov [ntfs_data.mftmirr_cluster], eax
movsx eax, byte [ebx+0x40]
test eax, eax
js .1
mul [ntfs_data.sectors_per_cluster]
shl eax, 9
jmp .2
.1:
neg eax
mov ecx, eax
mov eax, 1
shl eax, cl
.2:
mov [ntfs_data.frs_size], eax
movsx eax, byte [ebx+0x44]
test eax, eax
js .3
mul [ntfs_data.sectors_per_cluster]
shl eax, 9
jmp .4
.3:
neg eax
mov ecx, eax
mov eax, 1
shl eax, cl
.4:
mov [ntfs_data.iab_size], eax
; allocate space for buffers
add eax, [ntfs_data.frs_size]
push eax
call kernel_alloc
test eax, eax
jz problem_fat_dec_count
mov [ntfs_data.frs_buffer], eax
add eax, [ntfs_data.frs_size]
mov [ntfs_data.iab_buffer], eax
; read $MFT disposition
mov eax, [ntfs_data.mft_cluster]
mul [ntfs_data.sectors_per_cluster]
call ntfs_read_frs_sector
cmp [hd_error], 0
jnz .usemirr
cmp dword [ebx], 'FILE'
jnz .usemirr
call ntfs_restore_usa_frs
jnc .mftok
.usemirr:
and [hd_error], 0
mov eax, [ntfs_data.mftmirr_cluster]
mul [ntfs_data.sectors_per_cluster]
call ntfs_read_frs_sector
cmp [hd_error], 0
jnz @f
cmp dword [ebx], 'FILE'
jnz @f
call ntfs_restore_usa_frs
jnc .mftok
@@:
; $MFT and $MFTMirr invalid!
.fail_free_frs:
push [ntfs_data.frs_buffer]
call kernel_free
jmp problem_fat_dec_count
.fail_free_mft:
push [ntfs_data.mft_retrieval]
call kernel_free
jmp .fail_free_frs
.mftok:
; read $MFT table retrieval information
; start with one page, increase if not enough (when MFT too fragmented)
push ebx
push 0x1000
call kernel_alloc
pop ebx
test eax, eax
jz .fail_free_frs
mov [ntfs_data.mft_retrieval], eax
and [ntfs_data.mft_retrieval_size], 0
mov [ntfs_data.mft_retrieval_alloc], 0x1000/8
; $MFT base record must contain unnamed non-resident $DATA attribute
movzx eax, word [ebx+14h]
add eax, ebx
.scandata:
cmp dword [eax], -1
jz .fail_free_mft
cmp dword [eax], 0x80
jnz @f
cmp byte [eax+9], 0
jz .founddata
@@:
add eax, [eax+4]
jmp .scandata
.founddata:
cmp byte [eax+8], 0
jz .fail_free_mft
; load first portion of $DATA attribute retrieval information
mov edx, [eax+0x18]
mov [ntfs_data.mft_retrieval_end], edx
mov esi, eax
movzx eax, word [eax+0x20]
add esi, eax
sub esp, 10h
.scanmcb:
call ntfs_decode_mcb_entry
jnc .scanmcbend
call .get_mft_retrieval_ptr
mov edx, [esp] ; block length
mov [eax], edx
mov edx, [esp+8] ; block addr (relative)
mov [eax+4], edx
inc [ntfs_data.mft_retrieval_size]
jmp .scanmcb
.scanmcbend:
add esp, 10h
; there may be other portions of $DATA attribute in auxiliary records;
; if they will be needed, they will be loaded later
 
mov [ntfs_data.cur_index_size], 0x1000/0x200
push 0x1000
call kernel_alloc
test eax, eax
jz .fail_free_mft
mov [ntfs_data.cur_index_buf], eax
 
popad
call free_hd_channel
and [hd1_status], 0
ret
 
.get_mft_retrieval_ptr:
pushad
mov eax, [ntfs_data.mft_retrieval_size]
cmp eax, [ntfs_data.mft_retrieval_alloc]
jnz .ok
add eax, 0x1000/8
mov [ntfs_data.mft_retrieval_alloc], eax
shl eax, 3
push eax
call kernel_alloc
test eax, eax
jnz @f
popad
add esp, 14h
jmp .fail_free_mft
@@:
mov esi, [ntfs_data.mft_retrieval]
mov edi, eax
mov ecx, [ntfs_data.mft_retrieval_size]
add ecx, ecx
rep movsd
push [ntfs_data.mft_retrieval]
mov [ntfs_data.mft_retrieval], eax
call kernel_free
mov eax, [ntfs_data.mft_retrieval_size]
.ok:
shl eax, 3
add eax, [ntfs_data.mft_retrieval]
mov [esp+28], eax
popad
ret
 
ntfs_read_frs_sector:
push eax ecx
add eax, [PARTITION_START]
mov ecx, [ntfs_data.frs_size]
shr ecx, 9
mov ebx, [ntfs_data.frs_buffer]
push ebx
@@:
call hd_read
cmp [hd_error], 0
jnz .fail
add ebx, 0x200
inc eax
loop @b
.fail:
pop ebx
pop ecx eax
ret
 
uglobal
align 4
ntfs_cur_attr dd ?
ntfs_cur_iRecord dd ?
ntfs_cur_offs dd ? ; in sectors
ntfs_cur_size dd ? ; in sectors
ntfs_cur_buf dd ?
ntfs_cur_read dd ? ; [output]
ntfs_bCanContinue db ?
rb 3
 
ntfs_attrlist_buf rb 0x400
ntfs_attrlist_mft_buf rb 0x400
ntfs_bitmap_buf rb 0x400
 
ntfs_attr_iRecord dd ?
ntfs_attr_iBaseRecord dd ?
ntfs_attr_offs dd ?
ntfs_attr_list dd ?
ntfs_attr_size dq ?
ntfs_cur_tail dd ?
endg
 
ntfs_read_attr:
; in: global variables
; out: [ntfs_cur_read]
pushad
and [ntfs_cur_read], 0
cmp [ntfs_cur_iRecord], 0
jnz .nomft
cmp [ntfs_cur_attr], 0x80
jnz .nomft
mov eax, [ntfs_data.mft_retrieval_end]
inc eax
mul [ntfs_data.sectors_per_cluster]
cmp eax, [ntfs_cur_offs]
jbe .nomft
; precalculated part of $Mft $DATA
mov esi, [ntfs_data.mft_retrieval]
mov eax, [ntfs_cur_offs]
xor edx, edx
div [ntfs_data.sectors_per_cluster]
; eax = VCN, edx = offset in sectors from beginning of cluster
xor ecx, ecx ; ecx will contain LCN
.mftscan:
add ecx, [esi+4]
sub eax, [esi]
jb @f
add esi, 8
push eax
mov eax, [ntfs_data.mft_retrieval_end]
shl eax, 3
add eax, [ntfs_data.mft_retrieval]
cmp eax, esi
pop eax
jnz .mftscan
jmp .nomft
@@:
push ecx
add ecx, eax
add ecx, [esi]
push eax
push edx
mov eax, [ntfs_data.sectors_per_cluster]
mul ecx
; eax = sector on partition
add eax, [PARTITION_START]
pop edx
add eax, edx
mov ebx, [ntfs_cur_buf]
pop ecx
neg ecx
imul ecx, [ntfs_data.sectors_per_cluster]
sub ecx, edx
cmp ecx, [ntfs_cur_size]
jb @f
mov ecx, [ntfs_cur_size]
@@:
; ecx = number of sequential sectors to read
call hd_read
cmp [hd_error], 0
jnz .errread
add [ntfs_cur_read], 0x200
dec [ntfs_cur_size]
inc [ntfs_cur_offs]
add ebx, 0x200
mov [ntfs_cur_buf], ebx
inc eax
loop @b
pop ecx
xor eax, eax
xor edx, edx
cmp [ntfs_cur_size], eax
jz @f
add esi, 8
push eax
mov eax, [ntfs_data.mft_retrieval_end]
shl eax, 3
add eax, [ntfs_data.mft_retrieval]
cmp eax, esi
pop eax
jz .nomft
jmp .mftscan
@@:
popad
ret
.errread:
pop ecx
.errret:
stc
popad
ret
.nomft:
; 1. Read file record.
; N.B. This will do recursive call of read_attr for $MFT::$Data.
mov eax, [ntfs_cur_iRecord]
mov [ntfs_attr_iRecord], eax
and [ntfs_attr_list], 0
or dword [ntfs_attr_size], -1
or dword [ntfs_attr_size+4], -1
or [ntfs_attr_iBaseRecord], -1
call ntfs_read_file_record
test eax, eax
jz .errret
; 2. Find required attribute.
mov eax, [ntfs_data.frs_buffer]
; a) For auxiliary records, read base record
; N.B. If base record is present,
; base iRecord may be 0 (for $Mft), but SequenceNumber is nonzero
cmp dword [eax+24h], 0
jz @f
mov eax, [eax+20h]
; test eax, eax
; jz @f
.beginfindattr:
mov [ntfs_attr_iRecord], eax
call ntfs_read_file_record
test eax, eax
jz .errret
@@:
; b) Scan for required attribute and for $ATTR_LIST
mov eax, [ntfs_data.frs_buffer]
movzx ecx, word [eax+14h]
add eax, ecx
mov ecx, [ntfs_cur_attr]
and [ntfs_attr_offs], 0
.scanattr:
cmp dword [eax], -1
jz .scandone
cmp dword [eax], ecx
jz .okattr
cmp [ntfs_attr_iBaseRecord], -1
jnz .scancont
cmp dword [eax], 0x20 ; $ATTR_LIST
jnz .scancont
mov [ntfs_attr_list], eax
jmp .scancont
.okattr:
; ignore named $DATA attributes (aka NTFS streams)
cmp ecx, 0x80
jnz @f
cmp byte [eax+9], 0
jnz .scancont
@@:
mov [ntfs_attr_offs], eax
.scancont:
add eax, [eax+4]
jmp .scanattr
.continue:
pushad
and [ntfs_cur_read], 0
.scandone:
; c) Check for required offset and length
mov ecx, [ntfs_attr_offs]
jecxz .noattr
push [ntfs_cur_size]
push [ntfs_cur_read]
call .doreadattr
pop edx
pop eax
jc @f
cmp [ntfs_bCanContinue], 0
jz @f
sub edx, [ntfs_cur_read]
neg edx
shr edx, 9
sub eax, edx
mov [ntfs_cur_size], eax
jnz .not_in_cur
@@:
popad
ret
.noattr:
.not_in_cur:
cmp [ntfs_cur_attr], 0x20
jz @f
mov ecx, [ntfs_attr_list]
test ecx, ecx
jnz .lookattr
.ret_is_attr:
cmp [ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0
popad
ret
.lookattr:
; required attribute or required offset was not found in base record;
; it may be present in auxiliary records;
; scan $ATTR_LIST
mov eax, [ntfs_attr_iBaseRecord]
cmp eax, -1
jz @f
call ntfs_read_file_record
test eax, eax
jz .errret
or [ntfs_attr_iBaseRecord], -1
@@:
push [ntfs_cur_offs]
push [ntfs_cur_size]
push [ntfs_cur_read]
push [ntfs_cur_buf]
push dword [ntfs_attr_size]
push dword [ntfs_attr_size+4]
or dword [ntfs_attr_size], -1
or dword [ntfs_attr_size+4], -1
and [ntfs_cur_offs], 0
mov [ntfs_cur_size], 2
and [ntfs_cur_read], 0
mov eax, ntfs_attrlist_buf
cmp [ntfs_cur_iRecord], 0
jnz @f
mov eax, ntfs_attrlist_mft_buf
@@:
mov [ntfs_cur_buf], eax
push eax
call .doreadattr
pop esi
mov edx, 1
pop dword [ntfs_attr_size+4]
pop dword [ntfs_attr_size]
mov ebp, [ntfs_cur_read]
pop [ntfs_cur_buf]
pop [ntfs_cur_read]
pop [ntfs_cur_size]
pop [ntfs_cur_offs]
jc .errret
or edi, -1
lea ebp, [ebp+esi-1Ah]
.scanliststart:
mov eax, [ntfs_cur_attr]
.scanlist:
cmp esi, ebp
jae .scanlistdone
cmp eax, [esi]
jz @f
.scanlistcont:
movzx ecx, word [esi+4]
add esi, ecx
jmp .scanlist
@@:
; ignore named $DATA attributes (aka NTFS streams)
cmp eax, 0x80
jnz @f
cmp byte [esi+6], 0
jnz .scanlistcont
@@:
push eax
mov eax, [esi+8]
test eax, eax
jnz .testf
mov eax, dword [ntfs_attr_size]
and eax, dword [ntfs_attr_size+4]
cmp eax, -1
jnz .testfz
; if attribute is in auxiliary records, its size is defined only in first
mov eax, [esi+10h]
call ntfs_read_file_record
test eax, eax
jnz @f
.errret_pop:
pop eax
jmp .errret
@@:
mov eax, [ntfs_data.frs_buffer]
movzx ecx, word [eax+14h]
add eax, ecx
mov ecx, [ntfs_cur_attr]
@@:
cmp dword [eax], -1
jz .errret_pop
cmp dword [eax], ecx
jz @f
.l1:
add eax, [eax+4]
jmp @b
@@:
cmp eax, 0x80
jnz @f
cmp byte [eax+9], 0
jnz .l1
@@:
cmp byte [eax+8], 0
jnz .sdnores
mov eax, [eax+10h]
mov dword [ntfs_attr_size], eax
and dword [ntfs_attr_size+4], 0
jmp .testfz
.sdnores:
mov ecx, [eax+30h]
mov dword [ntfs_attr_size], ecx
mov ecx, [eax+34h]
mov dword [ntfs_attr_size+4], ecx
.testfz:
xor eax, eax
.testf:
imul eax, [ntfs_data.sectors_per_cluster]
cmp eax, [ntfs_cur_offs]
pop eax
ja @f
mov edi, [esi+10h] ; keep previous iRecord
jmp .scanlistcont
@@:
.scanlistfound:
cmp edi, -1
jnz @f
popad
ret
@@:
mov eax, [ntfs_cur_iRecord]
mov [ntfs_attr_iBaseRecord], eax
mov eax, edi
jmp .beginfindattr
.sde:
popad
stc
ret
.scanlistdone:
sub ebp, ntfs_attrlist_buf-1Ah
cmp [ntfs_cur_iRecord], 0
jnz @f
sub ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf
@@:
cmp ebp, 0x400
jnz .scanlistfound
inc edx
push esi edi
mov esi, ntfs_attrlist_buf+0x200
mov edi, ntfs_attrlist_buf
cmp [ntfs_cur_iRecord], 0
jnz @f
mov esi, ntfs_attrlist_mft_buf+0x200
mov edi, ntfs_attrlist_mft_buf
@@:
mov ecx, 0x200/4
rep movsd
mov eax, edi
pop edi esi
sub esi, 0x200
push [ntfs_cur_offs]
push [ntfs_cur_size]
push [ntfs_cur_read]
push [ntfs_cur_buf]
push dword [ntfs_attr_size]
push dword [ntfs_attr_size+4]
or dword [ntfs_attr_size], -1
or dword [ntfs_attr_size+4], -1
mov [ntfs_cur_offs], edx
mov [ntfs_cur_size], 1
and [ntfs_cur_read], 0
mov [ntfs_cur_buf], eax
mov ecx, [ntfs_attr_list]
push esi edx
call .doreadattr
pop edx esi
mov ebp, [ntfs_cur_read]
pop dword [ntfs_attr_size+4]
pop dword [ntfs_attr_size]
pop [ntfs_cur_buf]
pop [ntfs_cur_read]
pop [ntfs_cur_size]
pop [ntfs_cur_offs]
jc .errret
add ebp, ntfs_attrlist_buf+0x200-0x1A
cmp [ntfs_cur_iRecord], 0
jnz .scanliststart
add ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf
jmp .scanliststart
 
.doreadattr:
mov [ntfs_bCanContinue], 0
cmp byte [ecx+8], 0
jnz .nonresident
mov eax, [ecx+10h] ; length
mov esi, eax
mov edx, [ntfs_cur_offs]
shr eax, 9
cmp eax, edx
jb .okret
shl edx, 9
sub esi, edx
movzx eax, word [ecx+14h]
add edx, eax
add edx, ecx ; edx -> data
mov eax, [ntfs_cur_size]
cmp eax, (0xFFFFFFFF shr 9)+1
jbe @f
mov eax, (0xFFFFFFFF shr 9)+1
@@:
shl eax, 9
cmp eax, esi
jbe @f
mov eax, esi
@@:
; eax = length, edx -> data
mov [ntfs_cur_read], eax
mov ecx, eax
mov eax, edx
mov ebx, [ntfs_cur_buf]
call memmove
and [ntfs_cur_size], 0 ; CF=0
ret
.nonresident:
; Not all auxiliary records contain correct FileSize info
mov eax, dword [ntfs_attr_size]
mov edx, dword [ntfs_attr_size+4]
push eax
and eax, edx
cmp eax, -1
pop eax
jnz @f
mov eax, [ecx+30h] ; FileSize
mov edx, [ecx+34h]
mov dword [ntfs_attr_size], eax
mov dword [ntfs_attr_size+4], edx
@@:
add eax, 0x1FF
adc edx, 0
shrd eax, edx, 9
sub eax, [ntfs_cur_offs]
ja @f
; return with nothing read
and [ntfs_cur_size], 0
.okret:
clc
ret
@@:
; reduce read length
and [ntfs_cur_tail], 0
cmp [ntfs_cur_size], eax
jb @f
mov [ntfs_cur_size], eax
mov eax, dword [ntfs_attr_size]
and eax, 0x1FF
mov [ntfs_cur_tail], eax
@@:
cmp [ntfs_cur_size], 0
jz .okret
mov eax, [ntfs_cur_offs]
xor edx, edx
div [ntfs_data.sectors_per_cluster]
sub eax, [ecx+10h] ; first_vbo
jb .okret
; eax = cluster, edx = starting sector
sub esp, 10h
movzx esi, word [ecx+20h] ; mcb_info_ofs
add esi, ecx
xor ebp, ebp
.readloop:
call ntfs_decode_mcb_entry
jnc .break
add ebp, [esp+8]
sub eax, [esp]
jae .readloop
push ecx
push eax
add eax, [esp+8]
add eax, ebp
imul eax, [ntfs_data.sectors_per_cluster]
add eax, edx
add eax, [PARTITION_START]
pop ecx
neg ecx
imul ecx, [ntfs_data.sectors_per_cluster]
sub ecx, edx
cmp ecx, [ntfs_cur_size]
jb @f
mov ecx, [ntfs_cur_size]
@@:
mov ebx, [ntfs_cur_buf]
@@:
call hd_read
cmp [hd_error], 0
jnz .errread2
add ebx, 0x200
mov [ntfs_cur_buf], ebx
inc eax
add [ntfs_cur_read], 0x200
dec [ntfs_cur_size]
inc [ntfs_cur_offs]
loop @b
pop ecx
xor eax, eax
xor edx, edx
cmp [ntfs_cur_size], 0
jnz .readloop
add esp, 10h
mov eax, [ntfs_cur_tail]
test eax, eax
jz @f
sub eax, 0x200
add [ntfs_cur_read], eax
@@:
clc
ret
.errread2:
pop ecx
add esp, 10h
stc
ret
.break:
add esp, 10h ; CF=0
mov [ntfs_bCanContinue], 1
ret
 
ntfs_read_file_record:
; in: eax=iRecord
; out: [ntfs_data.frs_buffer] contains information
; eax=0 - failed, eax=1 - success
; Read attr $DATA of $Mft, starting from eax*[ntfs_data.frs_size]
push ecx edx
mov ecx, [ntfs_data.frs_size]
mul ecx
shrd eax, edx, 9
shr edx, 9
jnz .err
push [ntfs_attr_iRecord]
push [ntfs_attr_iBaseRecord]
push [ntfs_attr_offs]
push [ntfs_attr_list]
push dword [ntfs_attr_size+4]
push dword [ntfs_attr_size]
push [ntfs_cur_iRecord]
push [ntfs_cur_attr]
push [ntfs_cur_offs]
push [ntfs_cur_size]
push [ntfs_cur_buf]
push [ntfs_cur_read]
mov [ntfs_cur_attr], 0x80 ; $DATA
and [ntfs_cur_iRecord], 0 ; $Mft
mov [ntfs_cur_offs], eax
shr ecx, 9
mov [ntfs_cur_size], ecx
mov eax, [ntfs_data.frs_buffer]
mov [ntfs_cur_buf], eax
call ntfs_read_attr
mov eax, [ntfs_cur_read]
pop [ntfs_cur_read]
pop [ntfs_cur_buf]
pop [ntfs_cur_size]
pop [ntfs_cur_offs]
pop [ntfs_cur_attr]
pop [ntfs_cur_iRecord]
pop dword [ntfs_attr_size]
pop dword [ntfs_attr_size+4]
pop [ntfs_attr_list]
pop [ntfs_attr_offs]
pop [ntfs_attr_iBaseRecord]
pop [ntfs_attr_iRecord]
pop edx ecx
jc .errret
cmp eax, [ntfs_data.frs_size]
jnz .errret
mov eax, [ntfs_data.frs_buffer]
cmp dword [eax], 'FILE'
jnz .errret
push ebx
mov ebx, eax
call ntfs_restore_usa_frs
pop ebx
setnc al
movzx eax, al
.ret:
ret
.err:
pop edx ecx
.errret:
xor eax, eax
ret
 
ntfs_restore_usa_frs:
mov eax, [ntfs_data.frs_size]
ntfs_restore_usa:
pushad
shr eax, 9
mov ecx, eax
inc eax
cmp [ebx+6], ax
jnz .err
movzx eax, word [ebx+4]
lea esi, [eax+ebx]
lodsw
mov edx, eax
lea edi, [ebx+0x1FE]
@@:
cmp [edi], dx
jnz .err
lodsw
stosw
add edi, 0x1FE
loop @b
popad
clc
ret
.err:
popad
stc
ret
 
ntfs_decode_mcb_entry:
push eax ecx edi
lea edi, [esp+16]
xor eax, eax
lodsb
test al, al
jz .end
mov ecx, eax
and ecx, 0xF
cmp ecx, 8
ja .end
push ecx
rep movsb
pop ecx
sub ecx, 8
neg ecx
cmp byte [esi-1], 80h
jae .end
push eax
xor eax, eax
rep stosb
pop ecx
shr ecx, 4
cmp ecx, 8
ja .end
push ecx
rep movsb
pop ecx
sub ecx, 8
neg ecx
cmp byte [esi-1], 80h
cmc
sbb eax, eax
rep stosb
stc
.end:
pop edi ecx eax
ret
 
unichar_toupper:
push eax
call uni2ansi_char
cmp al, '_'
jz .unk
add esp, 4
call char_toupper
jmp ansi2uni_char
.unk:
pop eax
ret
 
ntfs_find_lfn:
; in: esi+ebp -> name
; out: CF=1 - file not found
; else CF=0, [ntfs_cur_iRecord] valid, eax->record in parent directory
mov [ntfs_cur_iRecord], 5 ; start parse from root cluster
.doit2:
mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT
and [ntfs_cur_offs], 0
mov eax, [ntfs_data.cur_index_size]
mov [ntfs_cur_size], eax
mov eax, [ntfs_data.cur_index_buf]
mov [ntfs_cur_buf], eax
call ntfs_read_attr
jnc @f
.ret:
ret
@@:
cmp [ntfs_cur_read], 0x20
jc .ret
pushad
mov esi, [ntfs_data.cur_index_buf]
mov eax, [esi+14h]
add eax, 10h
cmp [ntfs_cur_read], eax
jae .readok1
add eax, 1FFh
shr eax, 9
cmp eax, [ntfs_data.cur_index_size]
ja @f
.stc_ret:
popad
stc
ret
@@:
; reallocate
push eax
push [ntfs_data.cur_index_buf]
call kernel_free
pop eax
mov [ntfs_data.cur_index_size], eax
push eax
call kernel_alloc
test eax, eax
jnz @f
and [ntfs_data.cur_index_size], 0
and [ntfs_data.cur_index_buf], 0
jmp .stc_ret
@@:
mov [ntfs_data.cur_index_buf], eax
popad
jmp .doit2
.readok1:
mov ebp, [esi+8] ; subnode_size
shr ebp, 9
cmp ebp, [ntfs_data.cur_index_size]
jbe .ok2
push esi ebp
push ebp
call kernel_alloc
pop ebp esi
test eax, eax
jz .stc_ret
mov edi, eax
mov ecx, [ntfs_data.cur_index_size]
shl ecx, 9-2
rep movsd
mov esi, eax
mov [ntfs_data.cur_index_size], ebp
push esi ebp
push [ntfs_data.cur_index_buf]
call kernel_free
pop ebp esi
mov [ntfs_data.cur_index_buf], esi
.ok2:
add esi, 10h
mov edi, [esp+4]
; edi -> name, esi -> current index data, ebp = subnode size
.scanloop:
add esi, [esi]
.scanloopint:
test byte [esi+0Ch], 2
jnz .subnode
push esi
add esi, 0x52
movzx ecx, byte [esi-2]
push edi
@@:
lodsw
call unichar_toupper
push eax
mov al, [edi]
inc edi
cmp al, '/'
jz .slash
call char_toupper
call ansi2uni_char
cmp ax, [esp]
pop eax
loopz @b
jz .found
pop edi
pop esi
jb .subnode
.scanloopcont:
movzx eax, word [esi+8]
add esi, eax
jmp .scanloopint
.slash:
pop eax
pop edi
pop esi
.subnode:
test byte [esi+0Ch], 1
jz .notfound
movzx eax, word [esi+8]
mov eax, [esi+eax-8]
mul [ntfs_data.sectors_per_cluster]
mov [ntfs_cur_offs], eax
mov [ntfs_cur_attr], 0xA0 ; $INDEX_ALLOCATION
mov [ntfs_cur_size], ebp
mov eax, [ntfs_data.cur_index_buf]
mov esi, eax
mov [ntfs_cur_buf], eax
call ntfs_read_attr
mov eax, ebp
shl eax, 9
cmp [ntfs_cur_read], eax
jnz .notfound
cmp dword [esi], 'INDX'
jnz .notfound
mov ebx, esi
call ntfs_restore_usa
jc .notfound
add esi, 0x18
jmp .scanloop
.notfound:
popad
stc
ret
.found:
cmp byte [edi], 0
jz .done
cmp byte [edi], '/'
jz .next
pop edi
pop esi
jmp .scanloopcont
.done:
.next:
pop esi
pop esi
mov eax, [esi]
mov [ntfs_cur_iRecord], eax
mov [esp+1Ch], esi
mov [esp+4], edi
popad
inc esi
cmp byte [esi-1], 0
jnz .doit2
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .doit2
@@:
ret
 
;----------------------------------------------------------------
;
; ntfs_HdRead - read NTFS hard disk
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ntfs_HdRead:
cmp byte [esi], 0
jnz @f
or ebx, -1
push ERROR_ACCESS_DENIED
pop eax
ret
@@:
call ntfs_find_lfn
jnc .found
or ebx, -1
push ERROR_FILE_NOT_FOUND
pop eax
ret
.found:
mov [ntfs_cur_attr], 0x80 ; $DATA
and [ntfs_cur_offs], 0
and [ntfs_cur_size], 0
call ntfs_read_attr
jnc @f
or ebx, -1
push ERROR_ACCESS_DENIED
pop eax
ret
@@:
pushad
and dword [esp+10h], 0
xor eax, eax
test ebx, ebx
jz .zero1
cmp dword [ebx+4], 0x200
jb @f
.eof0:
popad
xor ebx, ebx
.eof:
push ERROR_END_OF_FILE
pop eax
ret
@@:
mov eax, [ebx]
test eax, 0x1FF
jz .alignedstart
push edx
mov edx, [ebx+4]
shrd eax, edx, 9
pop edx
mov [ntfs_cur_offs], eax
mov [ntfs_cur_size], 1
mov [ntfs_cur_buf], ntfs_bitmap_buf
call ntfs_read_attr.continue
mov eax, [ebx]
and eax, 0x1FF
lea esi, [ntfs_bitmap_buf+eax]
sub eax, [ntfs_cur_read]
jae .eof0
neg eax
push ecx
cmp ecx, eax
jb @f
mov ecx, eax
@@:
mov [esp+10h+4], ecx
mov edi, edx
rep movsb
mov edx, edi
pop ecx
sub ecx, [esp+10h]
jnz @f
.retok:
popad
xor eax, eax
ret
@@:
cmp [ntfs_cur_read], 0x200
jz .alignedstart
.eof_ebx:
popad
jmp .eof
.alignedstart:
mov eax, [ebx]
push edx
mov edx, [ebx+4]
add eax, 511
adc edx, 0
shrd eax, edx, 9
pop edx
.zero1:
mov [ntfs_cur_offs], eax
mov [ntfs_cur_buf], edx
mov eax, ecx
shr eax, 9
mov [ntfs_cur_size], eax
add eax, [ntfs_cur_offs]
push eax
call ntfs_read_attr.continue
pop [ntfs_cur_offs]
mov eax, [ntfs_cur_read]
add [esp+10h], eax
mov eax, ecx
and eax, not 0x1FF
cmp [ntfs_cur_read], eax
jnz .eof_ebx
and ecx, 0x1FF
jz .retok
add edx, [ntfs_cur_read]
mov [ntfs_cur_size], 1
mov [ntfs_cur_buf], ntfs_bitmap_buf
call ntfs_read_attr.continue
cmp [ntfs_cur_read], ecx
jb @f
mov [ntfs_cur_read], ecx
@@:
xchg ecx, [ntfs_cur_read]
push ecx
mov edi, edx
mov esi, ntfs_bitmap_buf
add [esp+10h+4], ecx
rep movsb
pop ecx
xor eax, eax
cmp ecx, [ntfs_cur_read]
jz @f
mov al, ERROR_END_OF_FILE
@@:
mov [esp+1Ch], eax
popad
ret
 
;----------------------------------------------------------------
;
; ntfs_HdReadFolder - read NTFS hard disk folder
;
; esi points to filename
; ebx pointer to structure 32-bit number = first wanted block, 0+
; & flags (bitfields)
; flags: bit 0: 0=ANSI names, 1=UNICODE names
; ecx number of blocks to read, 0+
; edx mem location to return data
;
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ntfs_HdReadFolder:
mov eax, 5 ; root cluster
cmp byte [esi], 0
jz .doit
call ntfs_find_lfn
jnc .doit2
.notfound:
or ebx, -1
push ERROR_FILE_NOT_FOUND
.pop_ret:
pop eax
ret
.doit:
mov [ntfs_cur_iRecord], eax
.doit2:
mov [ntfs_cur_attr], 0x10 ; $STANDARD_INFORMATION
and [ntfs_cur_offs], 0
mov [ntfs_cur_size], 1
mov [ntfs_cur_buf], ntfs_bitmap_buf
call ntfs_read_attr
jc .notfound
mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT
and [ntfs_cur_offs], 0
mov eax, [ntfs_data.cur_index_size]
mov [ntfs_cur_size], eax
mov eax, [ntfs_data.cur_index_buf]
mov [ntfs_cur_buf], eax
call ntfs_read_attr
jnc .ok
cmp [hd_error], 0
jz .notfound
or ebx, -1
push 11
jmp .pop_ret
.ok:
cmp [ntfs_cur_read], 0x20
jae @f
or ebx, -1
.fserr:
push ERROR_FAT_TABLE
jmp .pop_ret
@@:
pushad
mov esi, [ntfs_data.cur_index_buf]
mov eax, [esi+14h]
add eax, 10h
cmp [ntfs_cur_read], eax
jae .readok1
add eax, 1FFh
shr eax, 9
cmp eax, [ntfs_data.cur_index_size]
ja @f
popad
jmp .fserr
@@:
; reallocate
push eax
push [ntfs_data.cur_index_buf]
call kernel_free
pop eax
mov [ntfs_data.cur_index_size], eax
push eax
call kernel_alloc
test eax, eax
jnz @f
and [ntfs_data.cur_index_size], 0
and [ntfs_data.cur_index_buf], 0
.nomem:
popad
or ebx, -1
push 12
pop eax
ret
@@:
mov [ntfs_data.cur_index_buf], eax
popad
jmp .doit2
.readok1:
mov ebp, [esi+8] ; subnode_size
shr ebp, 9
cmp ebp, [ntfs_data.cur_index_size]
jbe .ok2
push esi ebp
push ebp
call kernel_alloc
pop ebp esi
test eax, eax
jz .nomem
mov edi, eax
mov ecx, [ntfs_data.cur_index_size]
shl ecx, 9-2
rep movsd
mov esi, eax
mov [ntfs_data.cur_index_size], ebp
push esi ebp
push [ntfs_data.cur_index_buf]
call kernel_free
pop ebp esi
mov [ntfs_data.cur_index_buf], esi
.ok2:
add esi, 10h
mov ebx, [esp+10h]
mov edx, [esp+14h]
push dword [ebx+4] ; read ANSI/UNICODE name
mov ebx, [ebx]
; init header
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
mov byte [edx], 1 ; version
mov ecx, [esp+4+18h]
push edx
mov edx, esp
; edi -> BDFE, esi -> current index data, ebp = subnode size, ebx = first wanted block,
; ecx = number of blocks to read
; edx -> parameters block: dd <output>, dd <flags>
cmp [ntfs_cur_iRecord], 5
jz .skip_specials
; dot and dotdot entries
push esi
xor esi, esi
call .add_special_entry
inc esi
call .add_special_entry
pop esi
.skip_specials:
; at first, dump index root
add esi, [esi]
.dump_root:
test byte [esi+0Ch], 2
jnz .dump_root_done
call .add_entry
movzx eax, word [esi+8]
add esi, eax
jmp .dump_root
.dump_root_done:
; now dump all subnodes
push ecx edi
mov edi, ntfs_bitmap_buf
mov [ntfs_cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
mov [ntfs_cur_attr], 0xB0 ; $BITMAP
and [ntfs_cur_offs], 0
mov [ntfs_cur_size], 2
call ntfs_read_attr
pop edi ecx
push 0 ; save offset in $BITMAP attribute
and [ntfs_cur_offs], 0
.dumploop:
mov [ntfs_cur_attr], 0xA0
mov [ntfs_cur_size], ebp
mov eax, [ntfs_data.cur_index_buf]
mov esi, eax
mov [ntfs_cur_buf], eax
push [ntfs_cur_offs]
mov eax, [ntfs_cur_offs]
imul eax, ebp
mov [ntfs_cur_offs], eax
call ntfs_read_attr
pop [ntfs_cur_offs]
mov eax, ebp
shl eax, 9
cmp [ntfs_cur_read], eax
jnz .done
push eax
mov eax, [ntfs_cur_offs]
and eax, 0x400*8-1
bt dword [ntfs_bitmap_buf], eax
pop eax
jnc .dump_subnode_done
cmp dword [esi], 'INDX'
jnz .dump_subnode_done
push ebx
mov ebx, esi
call ntfs_restore_usa
pop ebx
jc .dump_subnode_done
add esi, 0x18
add esi, [esi]
.dump_subnode:
test byte [esi+0Ch], 2
jnz .dump_subnode_done
call .add_entry
movzx eax, word [esi+8]
add esi, eax
jmp .dump_subnode
.dump_subnode_done:
inc [ntfs_cur_offs]
test [ntfs_cur_offs], 0x400*8-1
jnz .dumploop
mov [ntfs_cur_attr], 0xB0
push ecx edi
mov edi, ntfs_bitmap_buf
mov [ntfs_cur_buf], edi
mov ecx, 0x400/4
xor eax, eax
rep stosd
pop edi ecx
pop eax
push [ntfs_cur_offs]
inc eax
mov [ntfs_cur_offs], eax
mov [ntfs_cur_size], 2
push eax
call ntfs_read_attr
pop eax
pop [ntfs_cur_offs]
push eax
jmp .dumploop
.done:
pop eax
pop edx
mov ebx, [edx+4]
pop edx
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
@@:
mov [esp+1Ch], eax
mov [esp+10h], ebx
popad
ret
 
.add_special_entry:
mov eax, [edx]
inc dword [eax+8] ; new file found
dec ebx
jns .ret
dec ecx
js .ret
inc dword [eax+4] ; new file block copied
mov eax, [edx+4]
mov [edi+4], eax
; mov eax, dword [ntfs_bitmap_buf+0x20]
; or al, 0x10
mov eax, 0x10
stosd
scasd
push edx
mov eax, dword [ntfs_bitmap_buf]
mov edx, dword [ntfs_bitmap_buf+4]
call ntfs_datetime_to_bdfe
mov eax, dword [ntfs_bitmap_buf+0x18]
mov edx, dword [ntfs_bitmap_buf+0x1C]
call ntfs_datetime_to_bdfe
mov eax, dword [ntfs_bitmap_buf+8]
mov edx, dword [ntfs_bitmap_buf+0xC]
call ntfs_datetime_to_bdfe
pop edx
xor eax, eax
stosd
stosd
mov al, '.'
push edi ecx
lea ecx, [esi+1]
test byte [edi-0x24], 1
jz @f
rep stosw
pop ecx
xor eax, eax
stosw
pop edi
add edi, 520
ret
@@:
rep stosb
pop ecx
xor eax, eax
stosb
pop edi
add edi, 264
.ret:
ret
 
.add_entry:
; do not return DOS 8.3 names
cmp byte [esi+0x51], 2
jz .ret
; do not return system files
; ... note that there will be no bad effects if system files also were reported ...
cmp dword [esi], 0x10
jb .ret
mov eax, [edx]
inc dword [eax+8] ; new file found
dec ebx
jns .ret
dec ecx
js .ret
inc dword [eax+4] ; new file block copied
mov eax, [edx+4] ; flags
call ntfs_direntry_to_bdfe
push ecx esi edi
movzx ecx, byte [esi+0x50]
add esi, 0x52
test byte [edi-0x24], 1
jz .ansi
shr ecx, 1
rep movsd
adc ecx, ecx
rep movsw
and word [edi], 0
pop edi
add edi, 520
pop esi ecx
ret
.ansi:
jecxz .skip
@@:
lodsw
call uni2ansi_char
stosb
loop @b
.skip:
xor al, al
stosb
pop edi
add edi, 264
pop esi ecx
ret
 
ntfs_direntry_to_bdfe:
mov [edi+4], eax ; ANSI/UNICODE name
mov eax, [esi+48h]
test eax, 0x10000000
jz @f
and eax, not 0x10000000
or al, 0x10
@@:
stosd
scasd
push edx
mov eax, [esi+0x18]
mov edx, [esi+0x1C]
call ntfs_datetime_to_bdfe
mov eax, [esi+0x30]
mov edx, [esi+0x34]
call ntfs_datetime_to_bdfe
mov eax, [esi+0x20]
mov edx, [esi+0x24]
call ntfs_datetime_to_bdfe
pop edx
mov eax, [esi+0x40]
stosd
mov eax, [esi+0x44]
stosd
ret
 
iglobal
_24 dd 24
_60 dd 60
_10000000 dd 10000000
days400year dd 365*400+100-4+1
days100year dd 365*100+25-1
days4year dd 365*4+1
days1year dd 365
months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
_400 dd 400
_100 dd 100
endg
 
ntfs_datetime_to_bdfe:
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC
push eax
mov eax, edx
xor edx, edx
div [_10000000]
xchg eax, [esp]
div [_10000000]
pop edx
.sec:
; edx:eax = number of seconds since January 1, 1601
push eax
mov eax, edx
xor edx, edx
div [_60]
xchg eax, [esp]
div [_60]
mov [edi], dl
pop edx
; edx:eax = number of minutes
div [_60]
mov [edi+1], dl
; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32)
xor edx, edx
div [_24]
mov [edi+2], dl
mov [edi+3], byte 0
; eax = number of days since January 1, 1601
xor edx, edx
div [days400year]
imul eax, 400
add eax, 1601
mov [edi+6], ax
mov eax, edx
xor edx, edx
div [days100year]
cmp al, 4
jnz @f
dec eax
add edx, [days100year]
@@:
imul eax, 100
add [edi+6], ax
mov eax, edx
xor edx, edx
div [days4year]
shl eax, 2
add [edi+6], ax
mov eax, edx
xor edx, edx
div [days1year]
cmp al, 4
jnz @f
dec eax
add edx, [days1year]
@@:
add [edi+6], ax
push esi edx
mov esi, months
movzx eax, word [edi+6]
test al, 3
jnz .noleap
xor edx, edx
push eax
div [_400]
pop eax
test edx, edx
jz .leap
xor edx, edx
div [_100]
test edx, edx
jz .noleap
.leap:
mov esi, months2
.noleap:
pop edx
xor eax, eax
inc eax
@@:
sub edx, [esi]
jb @f
add esi, 4
inc eax
jmp @b
@@:
add edx, [esi]
pop esi
inc edx
mov [edi+4], dl
mov [edi+5], al
add edi, 8
ret
 
;----------------------------------------------------------------
;
; ntfs_HdRewrite - write to NTFS hard disk
;
; esi points to filename
; ebx ignored (reserved)
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = number of written bytes
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ntfs_HdRewrite:
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
 
;----------------------------------------------------------------
;
; ntfs_HdWrite - write to NTFS hard disk
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = bytes written (maybe 0)
; eax = 0 ok write or other = errormsg
;
;--------------------------------------------------------------
ntfs_HdWrite:
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
 
;----------------------------------------------------------------
;
; ntfs_HdSetFileEnd - set end of file on NTFS hard disk
;
; esi points to filename
; ebx points to 64-bit number = new file size
; ecx ignored (reserved)
; edx ignored (reserved)
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
ntfs_HdSetFileEnd:
ntfs_HdSetFileInfo:
;----------------------------------------------------------------
;
; ntfs_HdDelete - delete file or empty folder from NTFS hard disk
;
; esi points to filename
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
ntfs_HdDelete:
mov eax, ERROR_UNSUPPORTED_FS
ret
 
ntfs_HdGetFileInfo:
cmp byte [esi], 0
jnz @f
push 2
pop eax
ret
@@:
call ntfs_find_lfn
jnc .doit
push ERROR_FILE_NOT_FOUND
pop eax
cmp [hd_error], 0
jz @f
mov al, 11
@@:
ret
.doit:
push esi edi
mov esi, eax
mov edi, edx
xor eax, eax
call ntfs_direntry_to_bdfe
pop edi esi
xor eax, eax
ret
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/fs/ext2.inc
0,0 → 1,1318
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; 02.02.2010 turbanoff - support 70.5 ;;
;; 23.01.2010 turbanoff - support 70.0 70.1 ;;
;; ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
EXT2_BAD_INO = 1
EXT2_ROOT_INO = 2
EXT2_ACL_IDX_INO = 3
EXT2_ACL_DATA_INO = 4
EXT2_BOOT_LOADER_INO= 5
EXT2_UNDEL_DIR_INO = 6
 
;type inode
EXT2_S_IFREG = 0x8000
EXT2_S_IFDIR = 0x4000
;user inode right's
EXT2_S_IRUSR = 0x0100
EXT2_S_IWUSR = 0x0080
EXT2_S_IXUSR = 0x0040
;group inode right's
EXT2_S_IRGRP = 0x0020
EXT2_S_IWGRP = 0x0010
EXT2_S_IXGRP = 0x0008
;other inode right's
EXT2_S_IROTH = 0x0004
EXT2_S_IWOTH = 0x0002
EXT2_S_IXOTH = 0x0001
EXT2_777_MODE = EXT2_S_IROTH or EXT2_S_IWOTH or EXT2_S_IXOTH or \
EXT2_S_IRGRP or EXT2_S_IWGRP or EXT2_S_IXGRP or \
EXT2_S_IRUSR or EXT2_S_IWUSR or EXT2_S_IXUSR
 
EXT2_FT_REG_FILE = 1 ;это файл, запись в родительском каталоге
EXT2_FT_DIR = 2 ;это папка
 
FS_FT_HIDDEN = 2
FS_FT_DIR = 0x10 ;это папка
FS_FT_ASCII = 0 ;имя в ascii
FS_FT_UNICODE = 1 ;имя в unicode
 
EXT2_FEATURE_INCOMPAT_FILETYPE = 0x0002
 
uglobal
EXT2_files_in_folder dd ? ;всего файлов в папке
EXT2_read_in_folder dd ? ;сколько файлов "считали"
EXT2_end_block dd ? ;конец очередного блока папки
EXT2_counter_blocks dd ?
EXT2_filename db 256 dup ?
EXT2_parent_name db 256 dup ?
EXT2_name_len dd ?
endg
 
struct EXT2_INODE_STRUC
.i_mode dw ?
.i_uid dw ?
.i_size dd ?
.i_atime dd ?
.i_ctime dd ?
.i_mtime dd ?
.i_dtime dd ?
.i_gid dw ?
.i_links_count dw ?
.i_blocks dd ?
.i_flags dd ?
.i_osd1 dd ?
.i_block dd 15 dup ?
.i_generation dd ?
.i_file_acl dd ?
.i_dir_acl dd ?
.i_faddr dd ?
.i_osd2 dd ? ; 1..12
ends
 
struct EXT2_DIR_STRUC
.inode dd ?
.rec_len dw ?
.name_len db ?
.file_type db ?
.name db ? ; 0..255
ends
 
struct EXT2_BLOCK_GROUP_DESC
.block_bitmap dd ?
.inode_bitmap dd ?
.inode_table dd ?
.free_blocks_count dw ?
.free_inodes_count dw ?
.used_dirs_count dw ?
ends
 
struct EXT2_SB_STRUC
.inodes_count dd ? ;+0
.blocks_count dd ? ;+4
.r_block_count dd ? ;+8
.free_block_count dd ? ;+12
.free_inodes_count dd ? ;+16
.first_data_block dd ? ;+20
.log_block_size dd ? ;+24
.log_frag_size dd ? ;+28
.blocks_per_group dd ? ;+32
.frags_per_group dd ? ;+36
.inodes_per_group dd ? ;+40
.mtime dd ? ;+44
.wtime dd ? ;+48
.mnt_count dw ? ;+52
.max_mnt_count dw ? ;+54
.magic dw ? ;+56
.state dw ? ;+58
.errors dw ? ;+60
.minor_rev_level dw ? ;+62
.lastcheck dd ? ;+64
.check_intervals dd ? ;+68
.creator_os dd ? ;+72
.rev_level dd ? ;+76
.def_resuid dw ? ;+80
.def_resgid dw ? ;+82
.first_ino dd ? ;+84
.inode_size dw ? ;+88
.block_group_nr dw ? ;+90
.feature_compat dd ? ;+92
.feature_incompat dd ? ;+96
.feature_ro_compat dd ? ;+100
.uuid db 16 dup ? ;+104
.volume_name db 16 dup ? ;+120
.last_mounted db 64 dup ? ;+136
.algo_bitmap dd ? ;+200
.prealloc_blocks db ? ;+204
.preallock_dir_blocks db ? ;+205
dw ? ;+206 alignment
.journal_uuid db 16 dup ? ;+208
.journal_inum dd ? ;+224
.journal_dev dd ? ;+228
.last_orphan dd ? ;+232
.hash_seed dd 4 dup ? ;+236
.def_hash_version db ? ;+252
db 3 dup ? ;+253 reserved
.default_mount_options dd ? ;+256
.first_meta_bg dd ? ;+260
ends
 
ext2_test_superblock:
cmp [fs_type], 0x83
jne .no
 
mov eax, [PARTITION_START]
add eax, 2 ;superblock start at 1024b
call hd_read
 
cmp dword [ebx+24], 3 ;s_block_size 0,1,2,3
ja .no
cmp word [ebx+56], 0xEF53 ;s_magic
jne .no
cmp word [ebx+58], 1 ;s_state (EXT_VALID_FS=1)
jne .no
mov eax, [ebx+96]
test eax, EXT2_FEATURE_INCOMPAT_FILETYPE
jz .no
test eax, not EXT2_FEATURE_INCOMPAT_FILETYPE
jnz .no
 
; OK, this is correct EXT2 superblock
clc
ret
.no:
; No, this superblock isn't EXT2
stc
ret
 
ext2_setup:
mov [fs_type], 2
 
push 512
call kernel_alloc ; mem for superblock
mov esi, ebx
mov edi, eax
mov ecx, 512/4
rep movsd ; copy sb to reserved mem
mov ebx, eax
mov [ext2_data.sb],eax
 
mov eax, [ebx + EXT2_SB_STRUC.blocks_count]
sub eax, [ebx + EXT2_SB_STRUC.first_data_block]
dec eax
xor edx, edx
div [ebx + EXT2_SB_STRUC.blocks_per_group]
inc eax
mov [ext2_data.groups_count], eax
 
mov ecx, [ebx+24]
inc ecx
mov [ext2_data.log_block_size], ecx ; 1, 2, 3, 4 equ 1kb, 2kb, 4kb, 8kb
 
mov eax, 1
shl eax, cl
mov [ext2_data.count_block_in_block], eax
 
shl eax, 7
mov [ext2_data.count_pointer_in_block], eax
mov edx, eax ; потом еще квадрат найдем
 
shl eax, 2
mov [ext2_data.block_size], eax
 
push eax eax ; 2 kernel_alloc
 
mov eax, edx
mul edx
mov [ext2_data.count_pointer_in_block_square], eax
 
call kernel_alloc
mov [ext2_data.ext2_save_block], eax ; and for temp block
call kernel_alloc
mov [ext2_data.ext2_temp_block], eax ; and for get_inode proc
 
movzx ebp, word [ebx+88]
mov ecx, [ebx+32]
mov edx, [ebx+40]
 
mov [ext2_data.inode_size], ebp
mov [ext2_data.blocks_per_group], ecx
mov [ext2_data.inodes_per_group], edx
 
push ebp ebp ebp ;3 kernel_alloc
call kernel_alloc
mov [ext2_data.ext2_save_inode], eax
call kernel_alloc
mov [ext2_data.ext2_temp_inode], eax
call kernel_alloc
mov [ext2_data.root_inode], eax
 
mov ebx, eax
mov eax, EXT2_ROOT_INO
call ext2_get_inode ; read root inode
 
jmp return_from_part_set
 
;==================================================================
;in: eax = i_block
; ebx = pointer to return memory
ext2_get_block:
push eax ebx ecx
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START]
mov ecx, [ext2_data.count_block_in_block]
@@:
call hd_read
inc eax
add ebx, 512
loop @B
pop ecx ebx eax
ret
;===================================================================
; in: ecx = номер блока в inode (0..)
; ebp = адрес inode
; out: ecx = адрес очередного блока
ext2_get_inode_block:
cmp ecx, 12 ; 0..11 - direct block address
jb .get_direct_block
 
sub ecx, 12
cmp ecx, [ext2_data.count_pointer_in_block] ; 12.. - indirect block
jb .get_indirect_block
 
sub ecx, [ext2_data.count_pointer_in_block]
cmp ecx, [ext2_data.count_pointer_in_block_square]
jb .get_double_indirect_block
 
sub ecx, [ext2_data.count_pointer_in_block_square]
;.get_triple_indirect_block:
push eax edx ebx
 
mov eax, [ebx + EXT2_INODE_STRUC.i_block + 14*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
xor edx, edx
mov eax, ecx
div [ext2_data.count_pointer_in_block_square]
 
;eax - номер в полученном блоке edx - номер дальше
mov eax, [ebx + eax*4]
call ext2_get_block
 
mov eax, edx
jmp @F
 
.get_double_indirect_block:
push eax edx ebx
 
mov eax, [ebp + EXT2_INODE_STRUC.i_block + 13*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
mov eax, ecx
@@:
xor edx, edx
div [ext2_data.count_pointer_in_block]
 
mov eax, [ebx + eax*4]
call ext2_get_block
mov ecx, [ebx + edx*4]
 
pop ebx edx eax
ret
 
.get_indirect_block:
push eax ebx
mov eax, [ebp + EXT2_INODE_STRUC.i_block + 12*4]
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
mov ecx, [ebx + ecx*4]
pop ebx eax
ret
 
.get_direct_block:
mov ecx, dword [ebp + EXT2_INODE_STRUC.i_block + ecx*4]
ret
 
;===================================================================
;get content inode by num
;in: eax = inode_num
; ebx = address of inode content
ext2_get_inode:
 
pushad
mov edi, ebx ;сохраним адрес inode
dec eax
xor edx, edx
div [ext2_data.inodes_per_group]
 
push edx ;locale num in group
 
mov edx, 32
mul edx ; address block_group in global_desc_table
 
; в eax - смещение группы с inode-ом относительно начала глобальной дескрипторной таблицы
; найдем блок в котором он находится
 
div [ext2_data.block_size]
mov ecx, [ext2_data.sb]
add eax, [ecx + EXT2_SB_STRUC.first_data_block]
inc eax
mov ebx, [ext2_data.ext2_temp_block]
call ext2_get_block
 
add ebx, edx ; локальный номер в блоке
mov eax, [ebx+8] ; номер блока - в терминах ext2
 
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START] ; а старт раздела - в терминах hdd (512)
 
;eax - указывает на таблицу inode-ов на hdd
mov esi, eax ;сохраним его пока в esi
 
; прибавим локальный адрес inode-а
pop eax ; index
mov ecx, [ext2_data.inode_size]
mul ecx ; (index * inode_size)
mov ebp, 512
div ebp ;поделим на размер блока
 
add eax, esi ;нашли адрес блока для чтения
mov ebx, [ext2_data.ext2_temp_block]
call hd_read
 
mov esi, edx ;добавим "остаток"
add esi, ebx ;к адресу
; mov ecx, [ext2_data.inode_size]
rep movsb ;копируем inode
popad
ret
 
;----------------------------------------------------------------
; in: esi -> children
; ebx -> pointer to dir block
; out: esi -> name without parent or not_changed
; ebx -> dir_rec of inode children or trash
ext2_test_block_by_name:
push eax ecx edx edi
 
mov edx, ebx
add edx, [ext2_data.block_size] ;запомним конец блока
 
.start_rec:
cmp [ebx + EXT2_DIR_STRUC.inode], 0
jz .next_rec
 
push esi
movzx ecx, [ebx + EXT2_DIR_STRUC.name_len]
mov edi, EXT2_filename
lea esi, [ebx + EXT2_DIR_STRUC.name]
 
call utf8toansi_str
mov ecx, edi
sub ecx, EXT2_filename ;кол-во байт в получившейся строке
 
mov edi, EXT2_filename
mov esi, [esp]
@@:
jecxz .test_find
dec ecx
 
lodsb
call char_toupper
 
mov ah, [edi]
inc edi
xchg al, ah
call char_toupper
cmp al, ah
je @B
@@: ;не подошло
pop esi
.next_rec:
movzx eax, [ebx + EXT2_DIR_STRUC.rec_len]
add ebx, eax ;к след. записи
cmp ebx, edx ;проверим конец ли
jb .start_rec
jmp .ret
 
.test_find:
cmp byte [esi], 0
je .find ;нашли конец
cmp byte [esi], '/'
jne @B
inc esi
.find:
pop eax ;удаляем из стека сохраненое значение
.ret:
pop edi edx ecx eax
ret
 
;----------------------------------------------------------------
;
; ext2_HdReadFolder - read disk folder
;
; esi points to filename
; ebx pointer to structure 32-bit number = first wanted block, 0+
; & flags (bitfields)
; flags: bit 0: 0=ANSI names, 1=UNICODE names
; ecx number of blocks to read, 0+
; edx mem location to return data
;
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ext2_HdReadFolder:
cmp byte [esi], 0
jz .doit
 
push ecx ebx
call ext2_find_lfn
jnc .doit2
pop ebx
.not_found:
pop ecx
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
mov ebp, [ext2_data.root_inode]
push ecx
jmp @F
.doit2:
pop ebx
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jz .not_found
@@:
xor eax, eax
mov edi, edx
mov ecx, 32/4
rep stosd ; fill header zero
pop edi ; edi = число блоков для чтения
push edx ebx
 
;--------------------------------------------- final step
and [EXT2_read_in_folder], 0
and [EXT2_files_in_folder], 0
 
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks]
mov [EXT2_counter_blocks], eax
 
add edx, 32 ; (header pointer in stack) edx = current mem for return
xor esi, esi ; esi = номер блока по порядку
 
.new_block_folder: ;reserved label
mov ecx, esi ; получим номер блока
call ext2_get_inode_block
 
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block ; и считываем блок с hdd
 
mov eax, ebx ; eax = current dir record
add ebx, [ext2_data.block_size]
mov [EXT2_end_block], ebx ; запомним конец очередного блока
 
pop ecx
mov ecx, [ecx] ; ecx = first wanted (flags ommited)
 
.find_wanted_start:
jecxz .find_wanted_end
.find_wanted_cycle:
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz @F
inc [EXT2_files_in_folder]
dec ecx
@@:
movzx ebx, [eax+EXT2_DIR_STRUC.rec_len]
 
cmp ebx, 12 ; минимальная длина записи
jb .end_error
test ebx, 0x3 ; длина записи должна делиться на 4
jnz .end_error
 
add eax, ebx ; к следующей записи
cmp eax, [EXT2_end_block] ; проверяем "конец"
jb .find_wanted_start
 
push .find_wanted_start
.end_block: ;вылетили из цикла
mov ebx, [ext2_data.count_block_in_block]
sub [EXT2_counter_blocks], ebx
jbe .end_dir
 
inc esi ;получаем новый блок
push ecx
mov ecx, esi
call ext2_get_inode_block
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
pop ecx
mov eax, ebx
add ebx, [ext2_data.block_size]
mov [EXT2_end_block], ebx
ret ; опять в цикл
 
.wanted_end:
loop .find_wanted_cycle ; ecx = -1
 
.find_wanted_end:
mov ecx, edi
.wanted_start: ; ищем first_wanted+count
jecxz .wanted_end
cmp [eax + EXT2_DIR_STRUC.inode], 0 ; if (inode = 0) => not used
jz .empty_rec
inc [EXT2_files_in_folder]
inc [EXT2_read_in_folder]
 
mov edi, edx
push eax ecx
xor eax, eax
mov ecx, 40 / 4
rep stosd
pop ecx eax
 
push eax esi edx ;получим inode
mov eax, [eax + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_temp_inode]
call ext2_get_inode
 
lea edi, [edx + 8]
 
mov eax, [ebx + EXT2_INODE_STRUC.i_ctime] ; переведем время в ntfs формат
xor edx, edx
add eax, 3054539008 ;(369 * 365 + 89) * 24 * 3600
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_atime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_mtime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
pop edx ; пока достаем только буфер
test [ebx + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR ; для папки размер
jnz @F ; не возвращаем
 
mov eax, [ebx + EXT2_INODE_STRUC.i_size] ;low size
stosd
mov eax, [ebx + EXT2_INODE_STRUC.i_dir_acl] ;high size
stosd
xor dword [edx], FS_FT_DIR
@@:
xor dword [edx], FS_FT_DIR
pop esi eax
 
or dword [edx+4], FS_FT_ASCII ; symbol type in name
 
;теперь скопируем имя, сконвертировав из UTF-8 в CP866
push eax ecx esi
movzx ecx, [eax + EXT2_DIR_STRUC.name_len]
lea edi, [edx + 40]
lea esi, [eax + EXT2_DIR_STRUC.name]
call utf8toansi_str
pop esi ecx eax
and byte [edi], 0
 
cmp byte [edx + 40], '.'
jne @F
or dword [edx], FS_FT_HIDDEN
@@:
 
add edx, 40 + 264 ; go to next record
dec ecx ; если запись пустая ecx не надо уменьшать
.empty_rec:
movzx ebx, [eax + EXT2_DIR_STRUC.rec_len]
cmp ebx, 12 ; минимальная длина записи
jb .end_error
test ebx, 0x3 ; длина записи должна делиться на 4
jnz .end_error
 
add eax, ebx
cmp eax, [EXT2_end_block]
jb .wanted_start
 
push .wanted_start ; дошли до конца очередного блока
jmp .end_block
 
.end_dir:
pop eax ; мусор (адрес возврата в цикл)
.end_error:
pop edx
mov ebx, [EXT2_read_in_folder]
mov ecx, [EXT2_files_in_folder]
mov dword [edx], 1 ;version
xor eax, eax
mov [edx+4], ebx
mov [edx+8], ecx
lea edi, [edx + 12]
mov ecx, 20 / 4
rep stosd
ret
;====================== end ext2_HdReadFolder
utf8toansi_str:
; convert UTF-8 string to ASCII-string (codepage 866)
; in: ecx=length source, esi->source, edi->buffer
; destroys: eax,esi,edi
jecxz .ret
.start:
lodsw
cmp al, 0x80
jb .ascii
 
xchg al, ah ; big-endian
cmp ax, 0xd080
jz .yo1
cmp ax, 0xd191
jz .yo2
cmp ax, 0xd090
jb .unk
cmp ax, 0xd180
jb .rus1
cmp ax, 0xd190
jb .rus2
.unk:
mov al, '_'
jmp .doit
.yo1:
mov al, 0xf0 ; Ё capital
jmp .doit
.yo2:
mov al, 0xf1 ; ё small
jmp .doit
.rus1:
sub ax, 0xd090 - 0x80
jmp .doit
.rus2:
sub ax, 0xd18f - 0xEF
.doit:
stosb
sub ecx, 2
ja .start
ret
 
.ascii:
stosb
dec esi
dec ecx
jnz .start
.ret:
ret
 
;----------------------------------------------------------------
;
; ext2_HdRead - read hard disk
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
ext2_HdRead:
cmp byte [esi], 0
jnz @F
 
.this_is_nofile:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
@@:
push ecx ebx
call ext2_find_lfn
pop ebx ecx
jnc .doit
;.not_found:
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFREG
jz .this_is_nofile
 
;-----------------------------------------------------------------------------final step
mov edi, edx ; edi = pointer to return mem
mov esi, ebx ; esi = pointer to first_wanted
 
;///// сравним хватит ли нам файла или нет
mov ebx, [esi+4]
mov eax, [esi] ; ebx : eax - стартовый номер байта
 
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great
jb .size_less
 
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
ja .size_great
 
.size_less:
xor ebx, ebx
mov eax, ERROR_END_OF_FILE
ret
.size_great:
add eax, ecx ;add to first_wanted кол-во байт для чтения
adc ebx, 0
 
cmp [ebp + EXT2_INODE_STRUC.i_dir_acl], ebx
ja .size_great_great
jb .size_great_less
cmp [ebp + EXT2_INODE_STRUC.i_size], eax
jae .size_great_great ; а если равно, то не важно куда
 
.size_great_less:
or [EXT2_files_in_folder], 1 ;читаем по границе размера
mov ecx, [ebp + EXT2_INODE_STRUC.i_size]
sub ecx, [esi] ;(размер - старт)
jmp @F
 
.size_great_great:
and [EXT2_files_in_folder], 0 ;читаем столько сколько запросили
 
@@:
push ecx ;save for return
test esi, esi
jz .zero_start
 
;пока делаем п..ц криво =)
mov edx, [esi+4]
mov eax, [esi]
div [ext2_data.block_size]
 
mov [EXT2_counter_blocks], eax ;номер блока запоминаем
 
push ecx
mov ecx, eax
call ext2_get_inode_block
mov ebx, [ext2_data.ext2_save_block]
mov eax, ecx
call ext2_get_block
pop ecx
add ebx, edx
 
neg edx
add edx,[ext2_data.block_size] ;block_size - стартовый байт = сколько байт 1-го блока
cmp ecx, edx
jbe .only_one_block
 
mov eax, ecx
sub eax, edx
mov ecx, edx
 
mov esi, ebx
rep movsb ;кусок 1-го блока
jmp @F
 
.zero_start:
mov eax, ecx
;теперь в eax кол-во оставшихся байт для чтения
@@:
mov ebx, edi ;чтение блока прям в ->ebx
xor edx, edx
div [ext2_data.block_size] ;кол-во байт в последнем блоке (остаток) в edx
mov edi, eax ;кол-во целых блоков в edi
@@:
test edi, edi
jz .finish_block
inc [EXT2_counter_blocks]
mov ecx, [EXT2_counter_blocks]
call ext2_get_inode_block
 
mov eax, ecx ;а ebx уже забит нужным значением
call ext2_get_block
add ebx, [ext2_data.block_size]
 
dec edi
jmp @B
 
.finish_block: ;в edx - кол-во байт в последнем блоке
test edx, edx
jz .end_read
 
mov ecx, [EXT2_counter_blocks]
inc ecx
call ext2_get_inode_block
 
mov edi, ebx
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
 
mov ecx, edx
 
.only_one_block:
mov esi, ebx
rep movsb ;кусок last блока
.end_read:
pop ebx
cmp [EXT2_files_in_folder], 0
jz @F
 
mov eax, ERROR_END_OF_FILE
ret
@@:
xor eax, eax
ret
;========================
;in : esi -> name not save: eax ebx ecx
;out: ebp -> inode cf=0
; ebp -> trash cf=1
ext2_find_lfn:
mov ebp, [ext2_data.root_inode]
.next_folder:
or [EXT2_counter_blocks], -1 ;счетчик блоков папки cur block of inode
mov eax, [ebp + EXT2_INODE_STRUC.i_blocks] ;убывающий счетчик блоков
add eax, [ext2_data.count_block_in_block]
mov [EXT2_end_block], eax
.next_block_folder:
mov eax, [ext2_data.count_block_in_block]
sub [EXT2_end_block], eax
jz .not_found
inc [EXT2_counter_blocks]
mov ecx, [EXT2_counter_blocks]
call ext2_get_inode_block
 
mov eax, ecx
mov ebx, [ext2_data.ext2_save_block] ;ebx = cur dir record
call ext2_get_block
 
mov eax, esi
call ext2_test_block_by_name
cmp eax, esi ;нашли имя?
jz .next_block_folder
 
cmp byte [esi],0
jz .get_inode_ret
 
cmp [ebx + EXT2_DIR_STRUC.file_type], EXT2_FT_DIR
jne .not_found ;нашли, но это не папка
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode] ;все же папка.
call ext2_get_inode
mov ebp, ebx
jmp .next_folder
 
.not_found:
stc
ret
.get_inode_ret:
mov [EXT2_end_block], ebx ; сохраняем указатеть на dir_rec
mov eax, [ebx + EXT2_DIR_STRUC.inode]
mov ebx, [ext2_data.ext2_save_inode]
call ext2_get_inode
mov ebp, ebx
clc
ret
 
 
;========================
 
ext2_HdGetFileInfo:
cmp byte [esi], 0
jz .doit
 
call ext2_find_lfn
jnc .doit2
;.not_found:
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
mov ebp, [ext2_data.root_inode]
mov ebx, .doit ;неважно что лишь бы этому адресу не '.'
jmp @F
.doit2:
mov ebx, [EXT2_end_block]
add ebx, EXT2_DIR_STRUC.name
@@:
xor eax, eax
mov edi, edx
mov ecx, 40/4
rep stosd ; fill zero
 
cmp byte [ebx], '.'
jnz @F
or dword [edx], FS_FT_HIDDEN
@@:
 
test [ebp + EXT2_INODE_STRUC.i_mode], EXT2_S_IFDIR
jnz @F
mov eax, [ebp + EXT2_INODE_STRUC.i_size] ;low size
mov ebx, [ebp + EXT2_INODE_STRUC.i_dir_acl] ;high size
mov dword [edx+32], eax
mov dword [edx+36], ebx
xor dword [edx], FS_FT_DIR
@@:
xor dword [edx], FS_FT_DIR
 
lea edi, [edx + 8]
mov eax, [ebx + EXT2_INODE_STRUC.i_ctime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_atime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
mov eax, [ebx + EXT2_INODE_STRUC.i_mtime]
xor edx, edx
add eax, 3054539008
adc edx, 2
call ntfs_datetime_to_bdfe.sec
 
xor eax, eax
ret
 
ext2_HdRewrite:
ext2_HdWrite:
ext2_HdSetFileEnd:
ext2_HdSetFileInfo:
ext2_HdDelete:
ext2_HdCreateFolder:
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
;----------------------------------------------------------------
;
; ext2_HdCreateFolder - create new folder
;
; esi points to filename
;
; ret eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
cmp byte [esi], 0
jz .not_found
cmp byte [esi], '/'
jz .not_found
 
mov ebx, esi ; save source pointer
xor edi, edi ; slah pointer
@@:
lodsb
cmp al, 0
jz .zero
cmp al, '/'
jz .slash
jmp @B
 
.slash:
lodsb
cmp al, 0
jz .zero ; уберем слеш из имени
cmp al, '/'
jz .not_found
mov edi, esi ; edi -> next symbol after '/'
dec edi
jmp @B
 
.zero:
dec esi
test edi, edi
jz .doit
 
;слеш был
mov eax, esi
sub eax, edi
mov [EXT2_name_len], eax
 
mov ecx, edi
sub ecx, ebx
dec ecx ;выкинули '/' из имени ролителя
mov esi, ebx
mov edi, EXT2_parent_name
rep movsb
; esi - pointer to last slash
 
mov edx, esi
mov esi, EXT2_parent_name
call ext2_find_lfn
jnc .doit2
.not_found:
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.doit:
mov ebp, [ext2_data.root_inode]
mov edx, ebx ; имя создаваемой папки
sub esi, ebx
mov [EXT2_name_len], esi
.doit2:
;ebp -> parent_inode ebx->name_new_folder [EXT2_name_len]=length of name
; стратегия выбора группы для нового inode: (так делает линукс)
; 1) Ищем группу в которой меньше всего папок и в есть свободное место
; 2) Если такая группа не нашлась, то берем группу в которой больше свободного места
 
 
 
 
call ext2_balloc
jmp ext2_HdDelete
 
push ebx
push ebp
 
mov ecx, [ext2_data.sb]
cmp [ecx + EXT2_SB_STRUC.free_inodes_count],0 ; есть ли место для inode
jz .no_space
mov eax, [ecx + EXT2_SB_STRUC.free_block_count]
sub eax, [ecx + EXT2_SB_STRUC.r_block_count]
cmp eax, 2 ; и как минимум на 2 блока
jb .no_space
 
mov ecx, [ext2_data.groups_count]
mov esi, [ext2_data.global_desc_table]
mov edi, -1 ;указатель на лучшую группу
mov edx, 0
.find_group_dir:
jecxz .end_find_group_dir
movzx eax, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count]
cmp eax, edx
jbe @F
cmp [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count], 0
jz @F
mov edi, esi
movzx edx, [esi + EXT2_BLOCK_GROUP_DESC.free_inodes_count]
@@:
dec ecx
add esi, 32 ;размер структуры
jmp .find_group_dir
.end_find_group_dir:
cmp edx, 0
jz .no_space
 
;нашли группу, получим битовую карту inode-ов (найдем locale number)
mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
 
;теперь цикл по всем битам
mov esi, ebx
mov ecx, [ext2_data.inodes_per_group]
shr ecx, 5 ;делим на 32
mov ebp, ecx ; всего сохраним в ebp
or eax, -1 ; ищем первый свободный inode (!= -1)
repne scasd
jnz .test_last_dword ;нашли или нет
mov eax, [esi-4]
 
sub ebp, ecx
dec ebp
shl ebp, 5 ; глобальный номер локального номера
 
mov ecx, 32
@@:
test eax, 1
jz @F
shr eax, 1
loop @B
@@:
mov eax, 32
sub eax, ecx
 
add ebp, eax ; locale num of inode
 
mov eax, [esi-4]
;устанавливаем в eax крайний справа нулевой бит в 1
mov ecx, eax
inc ecx
or eax, ecx ; x | (x+1)
mov [esi-4], eax
mov ebx, [ext2_data.ext2_save_block]
mov eax, [edi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
call ext2_set_block
;считаем таблицу inode
sub edi, [ext2_data.global_desc_table]
shr edi, 5
 
mov eax, edi
mul [ext2_data.inodes_per_group]
add eax, ebp
inc eax ; теперь в eax (ebp) номер inode-а
mov ebp, eax
;call ext2_get_inode_address
 
mov ebx, [ext2_data.ext2_save_block]
call hd_read
add edx, ebx ; в edx адрес нужного inode
 
;забьем 0 для начала
mov edi, edx
mov ecx, [ext2_data.inode_size]
shr ecx, 2
xor eax, eax
rep stosd
 
mov edi, edx
mov eax, EXT2_S_IFDIR or EXT2_777_MODE
stosd ; i_mode
xor eax, eax
stosd ; i_uid
mov eax, [ext2_data.block_size]
stosd ; i_size
xor eax, eax
stosd ; i_atime
stosd ; i_ctime
stosd ; i_mtime
stosd ; i_dtime
stosd ; i_gid
inc eax
stosd ; i_links_count
mov eax, [ext2_data.count_block_in_block]
stosd ; i_blocks
 
 
 
 
.test_last_dword:
 
xor ebx, ebx
mov eax, ERROR_UNSUPPORTED_FS
ret
 
 
 
.no_space:
or ebx, -1
mov eax, ERROR_DISK_FULL
ret
 
;выделяет новый блок, если это можно
;иначе возвращает eax=0
ext2_balloc:
mov ecx, [ext2_data.sb]
mov eax, [ecx + EXT2_SB_STRUC.free_block_count]
sub eax, [ecx + EXT2_SB_STRUC.r_block_count]
jbe .no_space
 
mov ecx, [ext2_data.groups_count]
mov edi, [ext2_data.global_desc_table]
;mov esi, -1 ;указатель на лучшую группу
mov edx, 0
.find_group:
jecxz .end_find_group
movzx eax, [edi + EXT2_BLOCK_GROUP_DESC.free_blocks_count]
cmp eax, edx
jbe @F
mov esi, edi
mov edx, eax
@@:
dec ecx
add edi, 32 ;размер структуры
jmp .find_group
.end_find_group:
cmp edx, 0
jz .no_space
 
;нашли группу, получим битовую карту block-ов
mov eax, [esi + EXT2_BLOCK_GROUP_DESC.block_bitmap]
mov ebx, [ext2_data.ext2_save_block]
call ext2_get_block
 
;теперь цикл по всем битам
mov edi, ebx
mov ecx, [ext2_data.blocks_per_group]
shr ecx, 5 ;делим на 32
mov ebp, ecx ;всего сохраним в ebp
or eax, -1 ;ищем первый свободный inode (!= -1)
repe scasd
jz .test_last_dword ;нашли или нет
 
mov eax, [edi-4]
sub ebp, ecx
dec ebp
shl ebp, 5 ; ebp = 32*(номер div 32). Теперь найдем (номер mod 32)
 
mov ecx, 32
@@:
test eax, 1
jz @F
shr eax, 1
loop @B
@@:
mov eax, 32
sub eax, ecx
 
add ebp, eax ; ebp = номер блока в группе
 
mov eax, [edi-4]
mov ecx, eax
inc ecx
or eax, ecx ; x | (x+1) - устанавливает в 1 крайний справа нулевой бит (block used)
mov [edi-4], eax
 
mov ebx, [ext2_data.ext2_save_block]
mov eax, [esi + EXT2_BLOCK_GROUP_DESC.inode_bitmap]
; call ext2_set_block ; и пишем на hdd новую битовую маску
 
;============== тут получаем номер блока
mov eax, [ext2_data.blocks_per_group]
sub esi, [ext2_data.global_desc_table]
shr esi, 5 ;esi - номер группы
mul esi
add ebp, eax ;(номер_группы) * (blocks_per_group) + локальный номер в группе
mov eax, [ext2_data.sb]
add ebp, [eax + EXT2_SB_STRUC.first_data_block]
 
;теперь поправим глобальную дескрипторную таблицу и суперблок
mov ebx, [ext2_data.sb]
dec [ebx + EXT2_SB_STRUC.free_block_count]
mov eax, 2
add eax, [PARTITION_START]
call hd_write
mov eax, [ebx + EXT2_SB_STRUC.first_data_block]
inc eax
dec [esi + EXT2_BLOCK_GROUP_DESC.free_blocks_count];edi все еще указывает на группу в которой мы выделил блок
call ext2_set_block
 
mov eax, ebx
ret
 
.test_last_dword:
lodsd
mov ecx, [ext2_data.blocks_per_group]
and ecx, not (32-1) ;обнуляем все кроме последних 5 бит
mov edx, ecx
mov ebx, 1
@@:
jecxz .no_space
mov edx, ebx
or edx, eax ; тестируем очередной бит
shl ebx, 1
jmp @B
@@:
sub edx, ecx
dec edx ;номер в последнем блоке
 
 
.no_space:
xor eax, eax
ret
 
;in: eax = i_block
; ebx = pointer to memory
ext2_set_block:
push eax ebx ecx
mov ecx, [ext2_data.log_block_size]
shl eax, cl
add eax, [PARTITION_START]
mov ecx, [ext2_data.count_block_in_block]
@@:
call hd_write
inc eax
add ebx, 512
loop @B
pop ecx ebx eax
ret
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/fs/part_set.inc
0,0 → 1,531
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;*************************************************************
;* 13.02.2010 Find all partition and check supported FS
;* 12.07.2007 Check all 4 entry of MBR and EMBR
;* 29.04.2006 Elimination of hangup after the
;* expiration hd_wait_timeout - Mario79
;* 28.01.2006 find all Fat16/32 partition in all input point
;* to MBR - Mario79
;*************************************************************
 
uglobal
align 4
 
;******************************************************
; Please do not change this place - variables in text
; Mario79
; START place
;******************************************************
PARTITION_START dd 0x3f
PARTITION_END dd 0
fs_type db 0 ; 1=NTFS, 2=EXT2/3, 16=FAT16, 32=FAT32
align 4
 
fs_dependent_data_start:
; FATxx data
 
SECTORS_PER_FAT dd 0x1f3a
NUMBER_OF_FATS dd 0x2
SECTORS_PER_CLUSTER dd 0x8
BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes
ROOT_CLUSTER dd 2 ; first rootdir cluster
FAT_START dd 0 ; start of fat table
ROOT_START dd 0 ; start of rootdir (only fat16)
ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16)
DATA_START dd 0 ; start of data area (=first cluster 2)
LAST_CLUSTER dd 0 ; last availabe cluster
ADR_FSINFO dd 0 ; used only by fat32
 
fatRESERVED dd 0x0FFFFFF6
fatBAD dd 0x0FFFFFF7
fatEND dd 0x0FFFFFF8
fatMASK dd 0x0FFFFFFF
 
fatStartScan dd 2
 
fs_dependent_data_end:
file_system_data_size = $ - PARTITION_START
if file_system_data_size > 96
ERROR: sizeof(file system data) too big!
end if
 
virtual at fs_dependent_data_start
; NTFS data
ntfs_data:
.sectors_per_cluster dd ?
.mft_cluster dd ?
.mftmirr_cluster dd ?
.frs_size dd ? ; FRS size in bytes
.iab_size dd ? ; IndexAllocationBuffer size in bytes
.frs_buffer dd ?
.iab_buffer dd ?
.mft_retrieval dd ?
.mft_retrieval_size dd ?
.mft_retrieval_alloc dd ?
.mft_retrieval_end dd ?
.cur_index_size dd ?
.cur_index_buf dd ?
if $ > fs_dependent_data_end
ERROR: increase sizeof(fs_dependent_data)!
end if
end virtual
 
virtual at fs_dependent_data_start
; EXT2 data
ext2_data:
.log_block_size dd ?
.block_size dd ?
.count_block_in_block dd ?
.blocks_per_group dd ?
.inodes_per_group dd ?
.global_desc_table dd ?
.root_inode dd ? ; pointer to root inode in memory
.inode_size dd ?
.count_pointer_in_block dd ? ; block_size / 4
.count_pointer_in_block_square dd ? ; (block_size / 4)**2
.ext2_save_block dd ? ; ¡«®ª ­  £«®¡ «ì­ãî 1 ¯à®æ¥¤ãàã
.ext2_temp_block dd ? ; ¡«®ª ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà
.ext2_save_inode dd ? ; inode ­  £«®¡ «ì­ãî ¯à®æ¥¤ãàã
.ext2_temp_inode dd ? ; inode ¤«ï ¬¥«ª¨å ¯à®æ¥¤ãà
.sb dd ? ; superblock
.groups_count dd ?
if $ > fs_dependent_data_end
ERROR: increase sizeof(fs_dependent_data)!
end if
end virtual
 
;***************************************************************************
; End place
; Mario79
;***************************************************************************
endg
iglobal
 
partition_types: ; list of fat16/32 partitions
db 0x04 ; DOS: fat16 <32M
db 0x06 ; DOS: fat16 >32M
db 0x0b ; WIN95: fat32
db 0x0c ; WIN95: fat32, LBA-mapped
db 0x0e ; WIN95: fat16, LBA-mapped
db 0x14 ; Hidden DOS: fat16 <32M
db 0x16 ; Hidden DOS: fat16 >32M
db 0x1b ; Hidden WIN95: fat32
db 0x1c ; Hidden WIN95: fat32, LBA-mapped
db 0x1e ; Hidden WIN95: fat16, LBA-mapped
db 0xc4 ; DRDOS/secured: fat16 <32M
db 0xc6 ; DRDOS/secured: fat16 >32M
db 0xcb ; DRDOS/secured: fat32
db 0xcc ; DRDOS/secured: fat32, LBA-mapped
db 0xce ; DRDOS/secured: fat16, LBA-mapped
db 0xd4 ; Old Multiuser DOS secured: fat16 <32M
db 0xd6 ; Old Multiuser DOS secured: fat16 >32M
db 0x07 ; NTFS
db 0x27 ; NTFS, hidden
db 0x83 ; Linux native file system (ext2fs)
partition_types_end:
 
 
extended_types: ; list of extended partitions
db 0x05 ; DOS: extended partition
db 0x0f ; WIN95: extended partition, LBA-mapped
db 0xc5 ; DRDOS/secured: extended partition
db 0xd5 ; Old Multiuser DOS secured: extended partition
extended_types_end:
 
endg
 
; Partition chain used:
; MBR <---------------------
; | |
; |-> PARTITION1 |
; |-> EXTENDED PARTITION - ;not need be second partition
; |-> PARTITION3
; |-> PARTITION4
 
set_PARTITION_variables:
set_FAT32_variables: ;deprecated
and [problem_partition], 0
call reserve_hd1
call reserve_hd_channel
 
pushad
 
cmp dword [hdpos],0
je problem_hd
 
xor ecx,ecx ; partition count
;or edx,-1 ; flag for partition
xor eax,eax ; address MBR
xor ebp,ebp ; extended partition start
 
new_mbr:
test ebp,ebp ; is there extended partition? (MBR or EMBR)
jnz extended_already_set ; yes
xchg ebp,eax ; no. set it now
 
extended_already_set:
add eax,ebp ; mbr=mbr+0, ext_part=ext_start+relat_start
mov ebx,buffer
call hd_read
cmp [hd_error],0
jne problem_hd
 
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
jnz end_partition_chain
push eax ; push only one time
cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition
jnz test_primary_partition_0
cmp dword [ebx+0x1be+0xc+16],0
jnz test_primary_partition_1
cmp dword [ebx+0x1be+0xc+16+16],0
jnz test_primary_partition_2
cmp dword [ebx+0x1be+0xc+16+16+16],0
jnz test_primary_partition_3
pop eax
jmp end_partition_chain
 
test_primary_partition_0:
mov al,[ebx+0x1be+4] ; get primary partition type
call scan_partition_types
jnz test_primary_partition_1 ; no. skip over
 
inc ecx
cmp ecx,[known_part] ; is it wanted partition?
jnz test_primary_partition_1 ; no
 
pop eax
;mov edx, eax ; start sector
add eax, [ebx+0x1be+8] ; add relative start
;mov [PARTITON_START],edx
;push edx
mov edx, [ebx+0x1be+12] ; length
;add edx, eax ; add length
;dec edx ; PARTITION_END is inclusive
;mov [PARTITION_END], edx ; note that this can be changed
; when file system data will be available
mov cl, [ebx+0x1be+4] ; fs_type
;mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS)
;pop edx
jmp hd_and_partition_ok
 
test_primary_partition_1:
mov al,[ebx+0x1be+4+16] ; get primary partition type
call scan_partition_types
jnz test_primary_partition_2 ; no. skip over
 
inc ecx
cmp ecx,[known_part] ; is it wanted partition?
jnz test_primary_partition_2 ; no
 
pop eax
add eax, [ebx+0x1be+8+16]
mov edx, [ebx+0x1be+12+16]
mov cl, [ebx+0x1be+4+16]
jmp hd_and_partition_ok
 
;mov edx, eax
;add edx, [ebx+0x1be+8+16]
;push edx
;add edx, [ebx+0x1be+12+16]
;dec edx
;mov [PARTITION_END], edx
;mov al, [ebx+0x1be+4+16]
;mov [fs_type], dl
;pop edx
 
test_primary_partition_2:
mov al,[ebx+0x1be+4+16+16] ; get primary partition type
call scan_partition_types
jnz test_primary_partition_3 ; no. skip over
 
inc ecx
cmp ecx,[known_part] ; is it wanted partition?
jnz test_primary_partition_3 ; no
 
pop eax
add eax, [ebx+0x1be+8+16+16]
mov edx, [ebx+0x1be+12+16+16]
mov cl, [ebx+0x1be+4+16+16]
jmp hd_and_partition_ok
;mov edx, eax
;add edx, [ebx+0x1be+8+16+16]
;push edx
;add edx, [ebx+0x1be+12+16+16]
;dec edx
;mov [PARTITION_END], edx
;mov al, [ebx+0x1be+4+16+16]
;mov [fs_type], dl
;pop edx
 
test_primary_partition_3:
mov al,[ebx+0x1be+4+16+16+16] ; get primary partition type
call scan_partition_types
jnz test_ext_partition_0 ; no. skip over
 
inc ecx
cmp ecx,[known_part] ; is it wanted partition?
jnz test_ext_partition_0 ; no
 
pop eax
add eax, [ebx+0x1be+8+16+16+16]
mov edx, [ebx+0x1be+12+16+16+16]
mov cl, [ebx+0x1be+4+16+16+16]
jmp hd_and_partition_ok
 
;mov edx, eax
;add edx, [ebx+0x1be+8+16+16+16]
;push edx
;add edx, [ebx+0x1be+12+16+16+16]
;dec edx
;mov [PARTITION_END], edx
;mov al, [ebx+0x1be+4+16+16+16]
;mov [fs_type], dl
;pop edx
 
test_ext_partition_0:
pop eax ; ¯à®áâ® ¢ëª¨¤ë¢ ¥¬ ¨§ á⥪ 
mov al,[ebx+0x1be+4] ; get extended partition type
call scan_extended_types
jnz test_ext_partition_1
 
mov eax,[ebx+0x1be+8] ; add relative start
test eax,eax ; is there extended partition?
jnz new_mbr ; yes. read it
 
test_ext_partition_1:
mov al,[ebx+0x1be+4+16] ; get extended partition type
call scan_extended_types
jnz test_ext_partition_2
 
mov eax,[ebx+0x1be+8+16] ; add relative start
test eax,eax ; is there extended partition?
jnz new_mbr ; yes. read it
 
test_ext_partition_2:
mov al,[ebx+0x1be+4+16+16] ; get extended partition type
call scan_extended_types
jnz test_ext_partition_3
 
mov eax,[ebx+0x1be+8+16+16] ; add relative start
test eax,eax ; is there extended partition?
jnz new_mbr ; yes. read it
 
test_ext_partition_3:
mov al,[ebx+0x1be+4+16+16+16] ; get extended partition type
call scan_extended_types
jnz end_partition_chain ; no. end chain
 
mov eax,[ebx+0x1be+8+16+16+16] ; get start of extended partition
test eax,eax ; is there extended partition?
jnz new_mbr ; yes. read it
 
end_partition_chain:
;mov [partition_count],ecx
 
;cmp edx,-1 ; found wanted partition?
;jnz hd_and_partition_ok ; yes. install it
;jmp problem_partition_or_fat
problem_hd:
or [problem_partition], 2
jmp return_from_part_set
 
 
scan_partition_types:
push ecx
mov edi,partition_types
mov ecx,partition_types_end-partition_types
cld
repne scasb ; is partition type ok?
pop ecx
ret
 
scan_extended_types:
push ecx
mov edi,extended_types
mov ecx,extended_types_end-extended_types
cld
repne scasb ; is it extended partition?
pop ecx
ret
 
problem_fat_dec_count: ; bootsector is missing or another problem
; dec [partition_count] ; remove it from partition_count
 
problem_partition_or_fat:
or [problem_partition],1
 
return_from_part_set:
popad
;mov [fs_type],0
call free_hd_channel
mov [hd1_status],0 ; free
ret
 
hd_and_partition_ok:
 
;eax = PARTITION_START edx=PARTITION_LENGTH cl=fs_type
mov [fs_type], cl
;mov eax,edx
mov [PARTITION_START],eax
add edx, eax
dec edx
mov [PARTITION_END], edx
 
; mov edx, [PARTITION_END]
; sub edx, eax
; inc edx ; edx = length of partition § ç¥¬ ®­® ­ ¬??
 
; mov [hd_setup],1
mov ebx,buffer
call hd_read ; read boot sector of partition
cmp [hd_error], 0
jz boot_read_ok
cmp [fs_type], 7
jnz problem_fat_dec_count
; NTFS duplicates bootsector:
; NT4/2k/XP+ saves bootsector copy in the end of disk
; NT 3.51 saves bootsector copy in the middle of disk
and [hd_error], 0
mov eax, [PARTITION_END]
call hd_read
cmp [hd_error], 0
jnz @f
call ntfs_test_bootsec
jnc boot_read_ok
@@:
and [hd_error], 0
mov eax, edx
shr eax, 1
add eax, [PARTITION_START]
call hd_read
cmp [hd_error], 0
jnz problem_fat_dec_count ; no chance...
boot_read_ok:
 
; if we are running on NTFS, check bootsector
 
call ntfs_test_bootsec ; test ntfs
jnc ntfs_setup
 
call ext2_test_superblock ; test ext2fs
jnc ext2_setup
 
mov eax, [PARTITION_START] ;ext2 test changes [buffer]
call hd_read
cmp [hd_error], 0
jnz problem_fat_dec_count
 
cmp word [ebx+0x1fe],0xaa55 ; is it valid boot sector?
jnz problem_fat_dec_count
 
movzx eax,word [ebx+0xe] ; sectors reserved
add eax,[PARTITION_START]
mov [FAT_START],eax ; fat_start = partition_start + reserved
 
movzx eax,byte [ebx+0xd] ; sectors per cluster
test eax,eax
jz problem_fat_dec_count
mov [SECTORS_PER_CLUSTER],eax
 
movzx ecx,word [ebx+0xb] ; bytes per sector
cmp ecx,0x200
jnz problem_fat_dec_count
mov [BYTES_PER_SECTOR],ecx
 
movzx eax,word [ebx+0x11] ; count of rootdir entries (=0 fat32)
mov edx,32
mul edx
dec ecx
add eax,ecx ; round up if not equal count
inc ecx ; bytes per sector
div ecx
mov [ROOT_SECTORS],eax ; count of rootdir sectors
 
movzx eax,word [ebx+0x16] ; sectors per fat <65536
test eax,eax
jnz fat16_fatsize
mov eax,[ebx+0x24] ; sectors per fat
fat16_fatsize:
mov [SECTORS_PER_FAT],eax
 
movzx eax,byte [ebx+0x10] ; number of fats
test eax,eax ; if 0 it's not fat partition
jz problem_fat_dec_count
mov [NUMBER_OF_FATS],eax
imul eax,[SECTORS_PER_FAT]
add eax,[FAT_START]
mov [ROOT_START],eax ; rootdir = fat_start + fat_size * fat_count
add eax,[ROOT_SECTORS] ; rootdir sectors should be 0 on fat32
mov [DATA_START],eax ; data area = rootdir + rootdir_size
 
movzx eax,word [ebx+0x13] ; total sector count <65536
test eax,eax
jnz fat16_total
mov eax,[ebx+0x20] ; total sector count
fat16_total:
add eax,[PARTITION_START]
dec eax
mov [PARTITION_END],eax
inc eax
sub eax,[DATA_START] ; eax = count of data sectors
xor edx,edx
div dword [SECTORS_PER_CLUSTER]
inc eax
mov [LAST_CLUSTER],eax
dec eax ; cluster count
mov [fatStartScan],2
 
; limits by Microsoft Hardware White Paper v1.03
cmp eax,4085 ; 0xff5
jb problem_fat_dec_count ; fat12 not supported
cmp eax,65525 ; 0xfff5
jb fat16_partition
 
fat32_partition:
mov eax,[ebx+0x2c] ; rootdir cluster
mov [ROOT_CLUSTER],eax
movzx eax,word [ebx+0x30] ; fs info sector
add eax,[PARTITION_START]
mov [ADR_FSINFO],eax
call hd_read
mov eax,[ebx+0x1ec]
cmp eax,-1
jz @f
mov [fatStartScan],eax
@@:
 
popad
 
mov [fatRESERVED],0x0FFFFFF6
mov [fatBAD],0x0FFFFFF7
mov [fatEND],0x0FFFFFF8
mov [fatMASK],0x0FFFFFFF
mov [fs_type],32 ; Fat32
call free_hd_channel
mov [hd1_status],0 ; free
ret
 
fat16_partition:
xor eax,eax
mov [ROOT_CLUSTER],eax
 
popad
 
mov [fatRESERVED],0x0000FFF6
mov [fatBAD],0x0000FFF7
mov [fatEND],0x0000FFF8
mov [fatMASK],0x0000FFFF
mov [fs_type],16 ; Fat16
call free_hd_channel
mov [hd1_status],0 ; free
ret
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/fs/fat32.inc
0,0 → 1,2934
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; FAT32.INC ;;
;; ;;
;; FAT16/32 functions for KolibriOS ;;
;; ;;
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;;
;; ;;
;; See file COPYING for details ;;
;; 04.02.2007 LFN create folder - diamond ;;
;; 08.10.2006 LFN delete file/folder - diamond ;;
;; 20.08.2006 LFN set file size (truncate/extend) - diamond ;;
;; 17.08.2006 LFN write/append to file - diamond ;;
;; 23.06.2006 LFN start application - diamond ;;
;; 15.06.2006 LFN get/set file/folder info - diamond ;;
;; 27.05.2006 LFN create/rewrite file - diamond ;;
;; 04.05.2006 LFN read folder - diamond ;;
;; 29.04.2006 Elimination of hangup after the ;;
;; expiration hd_wait_timeout - Mario79 ;;
;; 23.04.2006 LFN read file - diamond ;;
;; 28.01.2006 find all Fat16/32 partition in all input point ;;
;; to MBR, see file part_set.inc - Mario79 ;;
;; 15.01.2005 get file size/attr/date, file_append - ATV ;;
;; 04.12.2004 skip volume label, file delete bug fixed - ATV ;;
;; 29.11.2004 get_free_FAT changed, append dir bug fixed - ATV ;;
;; 23.11.2004 don't allow overwrite dir with file - ATV ;;
;; 18.11.2004 get_disk_info and more error codes - ATV ;;
;; 17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV ;;
;; 10.11.2004 removedir clear whole directory structure - ATV ;;
;; 08.11.2004 rename - ATV ;;
;; 30.10.2004 file_read return also dirsize in bytes - ATV ;;
;; 20.10.2004 Makedir/Removedir - ATV ;;
;; 14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx) ;;
;; 06.9.2004 Fix free space by Mario79 added - MH ;;
;; 24.5.2004 Write back buffer for File_write -VT ;;
;; 20.5.2004 File_read function to work with syscall 58 - VT ;;
;; 30.3.2004 Error parameters at function return - VT ;;
;; 01.5.2002 Bugfix in device write - VT ;;
;; 20.5.2002 Hd status check - VT ;;
;; 29.6.2002 Improved fat32 verification - VT ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
cache_max equ 1919 ; max. is 1919*512+0x610000=0x6ffe00
 
ERROR_SUCCESS = 0
ERROR_DISK_BASE = 1
ERROR_UNSUPPORTED_FS = 2
ERROR_UNKNOWN_FS = 3
ERROR_PARTITION = 4
ERROR_FILE_NOT_FOUND = 5
ERROR_END_OF_FILE = 6
ERROR_MEMORY_POINTER = 7
ERROR_DISK_FULL = 8
ERROR_FAT_TABLE = 9
ERROR_ACCESS_DENIED = 10
 
PUSHAD_EAX equ [esp+28]
PUSHAD_ECX equ [esp+24]
PUSHAD_EDX equ [esp+20]
PUSHAD_EBX equ [esp+16]
PUSHAD_EBP equ [esp+8]
PUSHAD_ESI equ [esp+4]
PUSHAD_EDI equ [esp+0]
 
uglobal
align 4
partition_count dd 0 ; partitions found by set_FAT32_variables
longname_sec1 dd 0 ; used by analyze_directory to save 2 previous
longname_sec2 dd 0 ; directory sectors for delete long filename
 
hd_error dd 0 ; set by wait_for_sector_buffer
hd_setup dd 0
hd_wait_timeout dd 0
 
cluster_tmp dd 0 ; used by analyze_directory
; and analyze_directory_to_write
 
file_size dd 0 ; used by file_read
 
cache_search_start dd 0 ; used by find_empty_slot
endg
 
iglobal
fat_in_cache dd -1
endg
 
uglobal
align 4
fat_cache: times 512 db 0
Sector512: ; label for dev_hdcd.inc
buffer: times 512 db 0
fsinfo_buffer: times 512 db 0
endg
 
uglobal
fat16_root db 0 ; flag for fat16 rootdir
fat_change db 0 ; 1=fat has changed
endg
 
reserve_hd1:
 
cli
cmp [hd1_status],0
je reserve_ok1
 
sti
call change_task
jmp reserve_hd1
 
reserve_ok1:
 
push eax
mov eax,[CURRENT_TASK]
shl eax,5
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov [hd1_status],eax
pop eax
sti
ret
;********************************************
 
uglobal
hd_in_cache db ?
endg
 
reserve_hd_channel:
; BIOS disk accesses are protected with common mutex hd1_status
; This must be modified when hd1_status will not be valid!
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
cli
cmp [IDE_Channel_1],0
je .reserve_ok_1
sti
call change_task
jmp .IDE_Channel_1
.IDE_Channel_2:
cli
cmp [IDE_Channel_2],0
je .reserve_ok_2
sti
call change_task
jmp .IDE_Channel_2
.reserve_ok_1:
mov [IDE_Channel_1], 1
push eax
mov al, 1
jmp @f
.reserve_ok_2:
mov [IDE_Channel_2], 1
push eax
mov al, 3
@@:
cmp [hdid], 1
sbb al, -1
cmp al, [hd_in_cache]
jz @f
mov [hd_in_cache], al
call clear_hd_cache
@@:
pop eax
sti
.ret:
ret
 
free_hd_channel:
; see comment at reserve_hd_channel
cmp [hdpos], 0x80
jae .ret
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1],0
.ret:
ret
.IDE_Channel_2:
mov [IDE_Channel_2],0
ret
;********************************************
problem_partition db 0 ; used for partitions search
 
include 'part_set.inc'
 
set_FAT:
;--------------------------------
; input : EAX = cluster
; EDX = value to save
; output : EDX = old value
;--------------------------------
push eax ebx esi
 
cmp eax,2
jb sfc_error
cmp eax,[LAST_CLUSTER]
ja sfc_error
cmp [fs_type],16
je sfc_1
add eax,eax
sfc_1:
add eax,eax
mov esi,511
and esi,eax ; esi = position in fat sector
shr eax,9 ; eax = fat sector
add eax,[FAT_START]
mov ebx,fat_cache
 
cmp eax,[fat_in_cache] ; is fat sector already in memory?
je sfc_in_cache ; yes
 
cmp [fat_change],0 ; is fat changed?
je sfc_no_change ; no
call write_fat_sector ; yes. write it into disk
cmp [hd_error],0
jne sfc_error
 
sfc_no_change:
mov [fat_in_cache],eax ; save fat sector
call hd_read
cmp [hd_error],0
jne sfc_error
 
 
sfc_in_cache:
cmp [fs_type],16
jne sfc_test32
 
sfc_set16:
xchg [ebx+esi],dx ; save new value and get old value
jmp sfc_write
 
sfc_test32:
mov eax,[fatMASK]
 
sfc_set32:
and edx,eax
xor eax,-1 ; mask for high bits
and eax,[ebx+esi] ; get high 4 bits
or eax,edx
mov edx,[ebx+esi] ; get old value
mov [ebx+esi],eax ; save new value
 
sfc_write:
mov [fat_change],1 ; fat has changed
 
sfc_nonzero:
and edx,[fatMASK]
 
sfc_error:
pop esi ebx eax
ret
 
 
get_FAT:
;--------------------------------
; input : EAX = cluster
; output : EAX = next cluster
;--------------------------------
push ebx esi
 
cmp [fs_type],16
je gfc_1
add eax,eax
gfc_1:
add eax,eax
mov esi,511
and esi,eax ; esi = position in fat sector
shr eax,9 ; eax = fat sector
add eax,[FAT_START]
mov ebx,fat_cache
 
cmp eax,[fat_in_cache] ; is fat sector already in memory?
je gfc_in_cache
 
cmp [fat_change],0 ; is fat changed?
je gfc_no_change ; no
call write_fat_sector ; yes. write it into disk
cmp [hd_error],0
jne hd_error_01
 
gfc_no_change:
mov [fat_in_cache],eax
call hd_read
cmp [hd_error],0
jne hd_error_01
 
gfc_in_cache:
mov eax,[ebx+esi]
and eax,[fatMASK]
hd_error_01:
pop esi ebx
ret
 
 
get_free_FAT:
;-----------------------------------------------------------
; output : if CARRY=0 EAX = # first cluster found free
; if CARRY=1 disk full
; Note : for more speed need to use fat_cache directly
;-----------------------------------------------------------
push ecx
mov ecx,[LAST_CLUSTER] ; counter for full disk
sub ecx,2
mov eax,[fatStartScan]
cmp eax,2
jb gff_reset
 
gff_test:
cmp eax,[LAST_CLUSTER] ; if above last cluster start at cluster 2
jbe gff_in_range
gff_reset:
mov eax,2
 
gff_in_range:
push eax
call get_FAT ; get cluster state
cmp [hd_error],0
jne gff_not_found_1
 
test eax,eax ; is it free?
pop eax
je gff_found ; yes
inc eax ; next cluster
dec ecx ; is all checked?
jns gff_test ; no
 
gff_not_found_1:
add esp,4
gff_not_found:
pop ecx ; yes. disk is full
stc
ret
 
gff_found:
lea ecx,[eax+1]
mov [fatStartScan],ecx
pop ecx
clc
ret
 
 
write_fat_sector:
;-----------------------------------------------------------
; write changed fat to disk
;-----------------------------------------------------------
push eax ebx ecx
 
mov [fat_change],0
mov eax,[fat_in_cache]
cmp eax,-1
jz write_fat_not_used
mov ebx,fat_cache
mov ecx,[NUMBER_OF_FATS]
 
write_next_fat:
call hd_write
cmp [hd_error],0
jne write_fat_not_used
 
add eax,[SECTORS_PER_FAT]
dec ecx
jnz write_next_fat
 
write_fat_not_used:
pop ecx ebx eax
ret
 
 
analyze_directory:
;-----------------------------------------------------------
; input : EAX = first cluster of the directory
; EBX = pointer to filename
; output : IF CARRY=0 EAX = sector where th file is found
; EBX = pointer in buffer
; [buffer .. buffer+511]
; ECX,EDX,ESI,EDI not changed
; IF CARRY=1 filename not found
; Note : if cluster=0 it's changed to read rootdir
; save 2 previous directory sectors in longname_sec
;-----------------------------------------------------------
push ecx edx esi edi ebx ; ebx = [esp+0]
mov [longname_sec1],0
mov [longname_sec2],0
 
adr_new_cluster:
mov [cluster_tmp],eax
mov [fat16_root],0
cmp eax,[LAST_CLUSTER]
ja adr_not_found ; too big cluster number, something is wrong
cmp eax,2
jnb adr_data_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fs_type],16
jne adr_data_cluster
mov eax,[ROOT_START]
mov edx,[ROOT_SECTORS]
mov [fat16_root],1 ; flag for fat16 rootdir
jmp adr_new_sector
 
adr_data_cluster:
sub eax,2
mov edx,[SECTORS_PER_CLUSTER]
imul eax,edx
add eax,[DATA_START]
 
adr_new_sector:
mov ebx,buffer
call hd_read
cmp [hd_error],0
jne adr_not_found
 
mov ecx,512/32 ; count of dir entrys per sector = 16
 
adr_analyze:
mov edi,[ebx+11] ; file attribute
and edi,0xf
cmp edi,0xf
je adr_long_filename
test edi,0x8 ; skip over volume label
jne adr_long_filename ; Note: label can be same name as file/dir
 
mov esi,[esp+0] ; filename need to be uppercase
mov edi,ebx
push ecx
mov ecx,11
cld
rep cmpsb ; compare 8+3 filename
pop ecx
je adr_found
 
adr_long_filename:
add ebx,32 ; position of next dir entry
dec ecx
jnz adr_analyze
 
mov ecx,[longname_sec1] ; save 2 previous directory sectors
mov [longname_sec1],eax ; for delete long filename
mov [longname_sec2],ecx
inc eax ; next sector
dec edx
jne adr_new_sector
cmp [fat16_root],1 ; end of fat16 rootdir
je adr_not_found
 
adr_next_cluster:
mov eax,[cluster_tmp]
call get_FAT ; get next cluster
cmp [hd_error],0
jne adr_not_found
 
cmp eax,2 ; incorrect fat chain?
jb adr_not_found ; yes
cmp eax,[fatRESERVED] ; is it end of directory?
jb adr_new_cluster ; no. analyse it
 
adr_not_found:
pop edi edi esi edx ecx ; first edi will remove ebx
stc ; file not found
ret
 
adr_found:
pop edi edi esi edx ecx ; first edi will remove ebx
clc ; file found
ret
 
 
get_data_cluster:
;-----------------------------------------------------------
; input : EAX = cluster
; EBX = pointer to buffer
; EDX = # blocks to read in buffer
; ESI = # blocks to skip over
; output : if CARRY=0 ok EBX/EDX/ESI updated
; if CARRY=1 cluster out of range
; Note : if cluster=0 it's changed to read rootdir
;-----------------------------------------------------------
push eax ecx
 
mov [fat16_root],0
cmp eax,[LAST_CLUSTER]
ja gdc_error ; too big cluster number, something is wrong
cmp eax,2
jnb gdc_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fs_type],16
jne gdc_cluster
mov eax,[ROOT_START]
mov ecx,[ROOT_SECTORS] ; Note: not cluster size
mov [fat16_root],1 ; flag for fat16 rootdir
jmp gdc_read
 
gdc_cluster:
sub eax,2
mov ecx,[SECTORS_PER_CLUSTER]
imul eax,ecx
add eax,[DATA_START]
 
gdc_read:
test esi,esi ; first wanted block
je gdcl1 ; yes, skip count is 0
dec esi
jmp gdcl2
 
gdcl1:
call hd_read
cmp [hd_error],0
jne gdc_error
 
add ebx,512 ; update pointer
dec edx
 
gdcl2:
test edx,edx ; is all read?
je out_of_read
 
inc eax ; next sector
dec ecx
jnz gdc_read
 
out_of_read:
pop ecx eax
clc
ret
 
gdc_error:
pop ecx eax
stc
ret
 
 
get_cluster_of_a_path:
;---------------------------------------------------------
; input : EBX = pointer to a path string
; (example: the path "/files/data/document" become
; "files......data.......document...0"
; '.' = space char
; '0' = char(0) (ASCII=0) !!! )
; output : if (CARRY=1) -> ERROR in the PATH
; if (CARRY=0) -> EAX=cluster
;---------------------------------------------------------
push ebx edx
 
mov eax,[ROOT_CLUSTER]
mov edx,ebx
 
search_end_of_path:
cmp byte [edx],0
je found_end_of_path
 
inc edx ; '/'
mov ebx,edx
call analyze_directory
jc directory_not_found
 
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field
mov ax,[ebx+26] ; read the LOW 16bit cluster field
and eax,[fatMASK]
add edx,11 ; 8+3 (name+extension)
jmp search_end_of_path
 
found_end_of_path:
pop edx ebx
clc ; no errors
ret
 
directory_not_found:
pop edx ebx
stc ; errors occour
ret
 
 
bcd2bin:
;----------------------------------
; input : AL=BCD number (eg. 0x11)
; output : AH=0
; AL=decimal number (eg. 11)
;----------------------------------
xor ah,ah
shl ax,4
shr al,4
aad
ret
 
 
get_date_for_file:
;-----------------------------------------------------
; Get date from CMOS and pack day,month,year in AX
; DATE bits 0..4 : day of month 0..31
; 5..8 : month of year 1..12
; 9..15 : count of years from 1980
;-----------------------------------------------------
mov al,0x7 ;day
out 0x70,al
in al,0x71
call bcd2bin
ror eax,5
 
mov al,0x8 ;month
out 0x70,al
in al,0x71
call bcd2bin
ror eax,4
 
mov al,0x9 ;year
out 0x70,al
in al,0x71
call bcd2bin
add ax,20 ;because CMOS return only the two last
;digit (eg. 2000 -> 00 , 2001 -> 01) and we
rol eax,9 ;need the difference with 1980 (eg. 2001-1980)
ret
 
 
get_time_for_file:
;-----------------------------------------------------
; Get time from CMOS and pack hour,minute,second in AX
; TIME bits 0..4 : second (the low bit is lost)
; 5..10 : minute 0..59
; 11..15 : hour 0..23
;-----------------------------------------------------
mov al,0x0 ;second
out 0x70,al
in al,0x71
call bcd2bin
ror eax,6
 
mov al,0x2 ;minute
out 0x70,al
in al,0x71
call bcd2bin
ror eax,6
 
mov al,0x4 ;hour
out 0x70,al
in al,0x71
call bcd2bin
rol eax,11
ret
 
 
set_current_time_for_entry:
;-----------------------------------------------------
; Set current time/date for file entry
; input : ebx = file entry pointer
;-----------------------------------------------------
push eax
call get_time_for_file ; update files date/time
mov [ebx+22],ax
call get_date_for_file
mov [ebx+24],ax
pop eax
ret
 
 
 
add_disk_free_space:
;-----------------------------------------------------
; input : ecx = cluster count
; Note : negative = remove clusters from free space
; positive = add clusters to free space
;-----------------------------------------------------
test ecx,ecx ; no change
je add_dfs_no
cmp [fs_type],32 ; free disk space only used by fat32
jne add_dfs_no
 
push eax ebx
mov eax,[ADR_FSINFO]
mov ebx,fsinfo_buffer
call hd_read
cmp [hd_error],0
jne add_not_fs
 
cmp dword [ebx+0x1fc],0xaa550000 ; check sector id
jne add_not_fs
 
add [ebx+0x1e8],ecx
push [fatStartScan]
pop dword [ebx+0x1ec]
call hd_write
; cmp [hd_error],0
; jne add_not_fs
 
add_not_fs:
pop ebx eax
 
add_dfs_no:
ret
 
 
file_read:
;--------------------------------------------------------------------------
; INPUT : user-register register-in-this meaning symbol-in-this
;
; EAX EDI system call to write /
; EBX EAX (PAR0) pointer to file-name PAR0
; EDX ECX (PAR1) pointer to buffer PAR1
; ECX EBX (PAR2) vt file blocks to read PAR2
; ESI EDX (PAR3) pointer to path PAR3
; EDI ESI vt first 512 block to read
; EDI if 0 - read root
;
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 6 - end of file
; 9 - fat table corrupted
; 10 - access denied
; ebx = size of file/directory
;--------------------------------------------------------------------------
cmp [fs_type], 16
jz fat_ok_for_reading
cmp [fs_type], 32
jz fat_ok_for_reading
xor ebx,ebx
mov eax,ERROR_UNKNOWN_FS
mov [hd1_status], ebx
ret
 
fat_ok_for_reading:
; call reserve_hd1
 
pushad
 
mov ebx,edx
call get_cluster_of_a_path
jc file_to_read_not_found
 
test edi,edi ; read rootdir
jne no_read_root
 
xor eax,eax
call get_dir_size ; return rootdir size
cmp [hd_error],0
jne file_access_denied
 
mov [file_size],eax
mov eax,[ROOT_CLUSTER]
jmp file_read_start
 
no_read_root:
mov ebx,PUSHAD_EAX ; file name
call analyze_directory
jc file_to_read_not_found
 
mov eax,[ebx+28] ; file size
test byte [ebx+11],0x10 ; is it directory?
jz read_set_size ; no
 
mov eax,[ebx+20-2] ; FAT entry
mov ax,[ebx+26]
and eax,[fatMASK]
call get_dir_size
cmp [hd_error],0
jne file_access_denied
 
read_set_size:
mov [file_size],eax
 
mov eax,[ebx+20-2] ; FAT entry
mov ax,[ebx+26]
and eax,[fatMASK]
 
file_read_start:
mov ebx,PUSHAD_ECX ; pointer to buffer
mov edx,PUSHAD_EBX ; file blocks to read
mov esi,PUSHAD_ESI ; first 512 block to read
 
file_read_new_cluster:
call get_data_cluster
jc file_read_eof ; end of file or cluster out of range
 
test edx,edx ; is all read?
je file_read_OK ; yes
 
call get_FAT ; get next cluster
cmp [hd_error],0
jne file_access_denied
 
cmp eax,[fatRESERVED] ; end of file
jnb file_read_eof
cmp eax,2 ; incorrect fat chain
jnb file_read_new_cluster
 
popad
mov [hd1_status],0
mov ebx,[file_size]
mov eax,ERROR_FAT_TABLE
ret
 
file_read_eof:
cmp [hd_error],0
jne file_access_denied
popad
mov [hd1_status],0
mov ebx,[file_size]
mov eax,ERROR_END_OF_FILE
ret
 
file_read_OK:
popad
mov [hd1_status],0
mov ebx,[file_size]
xor eax,eax
ret
 
file_to_read_not_found:
cmp [hd_error],0
jne file_access_denied
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_FILE_NOT_FOUND
ret
 
file_access_denied:
popad
mov [hd1_status],0
xor ebx,ebx
mov eax,ERROR_ACCESS_DENIED
ret
 
get_dir_size:
;-----------------------------------------------------
; input : eax = first cluster (0=rootdir)
; output : eax = directory size in bytes
;-----------------------------------------------------
push edx
xor edx,edx ; count of directory clusters
test eax,eax
jnz dir_size_next
 
mov eax,[ROOT_SECTORS]
shl eax,9 ; fat16 rootdir size in bytes
cmp [fs_type],16
je dir_size_ret
mov eax,[ROOT_CLUSTER]
 
dir_size_next:
cmp eax,2 ; incorrect fat chain
jb dir_size_end
cmp eax,[fatRESERVED] ; end of directory
ja dir_size_end
call get_FAT ; get next cluster
cmp [hd_error],0
jne dir_size_ret
 
inc edx
jmp dir_size_next
 
dir_size_end:
imul eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
imul eax,edx
 
dir_size_ret:
pop edx
ret
 
 
clear_cluster_chain:
;-----------------------------------------------------
; input : eax = first cluster
;-----------------------------------------------------
push eax ecx edx
xor ecx,ecx ; cluster count
 
clean_new_chain:
cmp eax,[LAST_CLUSTER] ; end of file
ja delete_OK
cmp eax,2 ; unfinished fat chain or zero length file
jb delete_OK
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster
jz delete_OK
 
xor edx,edx
call set_FAT ; clear fat entry
cmp [hd_error],0
jne access_denied_01
 
inc ecx ; update cluster count
mov eax,edx ; old cluster
jmp clean_new_chain
 
delete_OK:
call add_disk_free_space ; add clusters to free disk space
access_denied_01:
pop edx ecx eax
ret
 
 
get_hd_info:
;-----------------------------------------------------------
; output : eax = 0 - ok
; 3 - unknown FS
; 10 - access denied
; edx = cluster size in bytes
; ebx = total clusters on disk
; ecx = free clusters on disk
;-----------------------------------------------------------
cmp [fs_type], 16
jz info_fat_ok
cmp [fs_type], 32
jz info_fat_ok
xor edx,edx
xor ebx,ebx
xor ecx,ecx
mov eax,ERROR_UNKNOWN_FS
ret
 
info_fat_ok:
; call reserve_hd1
 
xor ecx,ecx ; count of free clusters
mov eax,2
mov ebx,[LAST_CLUSTER]
 
info_cluster:
push eax
call get_FAT ; get cluster info
cmp [hd_error],0
jne info_access_denied
 
test eax,eax ; is it free?
jnz info_used ; no
inc ecx
 
info_used:
pop eax
inc eax
cmp eax,ebx ; is above last cluster?
jbe info_cluster ; no. test next cluster
 
dec ebx ; cluster count
imul edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes
mov [hd1_status],0
xor eax,eax
ret
 
info_access_denied:
add esp,4
xor edx,edx
xor ebx,ebx
xor ecx,ecx
mov eax,ERROR_ACCESS_DENIED
ret
 
update_disk:
;-----------------------------------------------------------
; write changed fat and cache to disk
;-----------------------------------------------------------
cmp [fat_change],0 ; is fat changed?
je upd_no_change
 
call write_fat_sector
cmp [hd_error],0
jne update_disk_acces_denied
 
upd_no_change:
 
call write_cache
update_disk_acces_denied:
ret
 
 
; \begin{diamond}
hd_find_lfn:
; in: esi+ebp -> name
; out: CF=1 - file not found
; else CF=0 and edi->direntry, eax=sector
; destroys eax
push esi edi
push 0
push 0
push fat16_root_first
push fat16_root_next
mov eax, [ROOT_CLUSTER]
cmp [fs_type], 32
jz .fat32
.loop:
call fat_find_lfn
jc .notfound
cmp byte [esi], 0
jz .found
.continue:
test byte [edi+11], 10h
jz .notfound
and dword [esp+12], 0
mov eax, [edi+20-2]
mov ax, [edi+26] ; cluster
.fat32:
mov [esp+8], eax
mov dword [esp+4], fat_notroot_first
mov dword [esp], fat_notroot_next
jmp .loop
.notfound:
add esp, 16
pop edi esi
stc
ret
.found:
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .continue
@@:
lea eax, [esp+8]
cmp dword [eax], 0
jz .root
call fat_get_sector
jmp .cmn
.root:
mov eax, [eax+4]
add eax, [ROOT_START]
.cmn:
add esp, 20 ; CF=0
pop esi
ret
 
;----------------------------------------------------------------
;
; fs_HdRead - LFN variant for reading hard disk
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_HdRead:
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
cmp [fs_type], 1
jz ntfs_HdRead
cmp [fs_type], 2
jz ext2_HdRead
or ebx, -1
mov eax, ERROR_UNKNOWN_FS
ret
@@:
push edi
cmp byte [esi], 0
jnz @f
.noaccess:
pop edi
.noaccess_2:
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
 
@@:
call hd_find_lfn
jnc .found
pop edi
cmp [hd_error],0
jne .noaccess_2
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
 
.found:
test byte [edi+11], 0x10 ; do not allow read directories
jnz .noaccess
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
.reteof:
mov eax, 6
pop edi
ret
@@:
mov ebx, [ebx]
.l1:
push ecx edx
push 0
mov eax, [edi+28]
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6
@@:
mov eax, [edi+20-2]
mov ax, [edi+26]
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data
.new_cluster:
jecxz .new_sector
test eax, eax
jz .eof
cmp eax, [fatRESERVED]
jae .eof
mov [cluster_tmp], eax
dec eax
dec eax
mov edi, [SECTORS_PER_CLUSTER]
imul eax, edi
add eax, [DATA_START]
.new_sector:
test ecx, ecx
jz .done
sub ebx, 512
jae .skip
add ebx, 512
jnz .force_buf
cmp ecx, 512
jb .force_buf
; we may read directly to given buffer
push ebx
mov ebx, edx
call hd_read
pop ebx
cmp [hd_error],0
jne .noaccess_1
add edx, 512
sub ecx, 512
jmp .skip
.force_buf:
; we must read sector to temporary buffer and then copy it to destination
push eax ebx
mov ebx, buffer
call hd_read
mov eax, ebx
pop ebx
cmp [hd_error],0
jne .noaccess_3
add eax, ebx
push ecx
add ecx, ebx
cmp ecx, 512
jbe @f
mov ecx, 512
@@:
sub ecx, ebx
mov ebx, edx
call memmove
add edx, ecx
sub [esp], ecx
pop ecx
pop eax
xor ebx, ebx
.skip:
inc eax
dec edi
jnz .new_sector
mov eax, [cluster_tmp]
call get_FAT
cmp [hd_error],0
jne .noaccess_1
 
jmp .new_cluster
.noaccess_3:
pop eax
.noaccess_1:
pop eax
push 11
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
.eof:
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
 
;----------------------------------------------------------------
;
; fs_HdReadFolder - LFN variant for reading hard disk folder
;
; esi points to filename
; ebx pointer to structure 32-bit number = first wanted block, 0+
; & flags (bitfields)
; flags: bit 0: 0=ANSI names, 1=UNICODE names
; ecx number of blocks to read, 0+
; edx mem location to return data
;
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_HdReadFolder:
cmp [fs_type], 1
jz ntfs_HdReadFolder
cmp [fs_type], 2
jz ext2_HdReadFolder
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
push ERROR_UNSUPPORTED_FS
pop eax
or ebx, -1
ret
@@:
mov eax, [ROOT_CLUSTER]
push edi
cmp byte [esi], 0
jz .doit
call hd_find_lfn
jnc .found
pop edi
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.found:
test byte [edi+11], 0x10 ; do not allow read files
jnz .found_dir
pop edi
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
.found_dir:
mov eax, [edi+20-2]
mov ax, [edi+26] ; eax=cluster
.doit:
push esi ecx
push ebp
sub esp, 262*2 ; reserve space for LFN
mov ebp, esp
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE name
mov ebx, [ebx]
; init header
push eax ecx
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov esi, edi ; esi points to BDFE
.new_cluster:
mov [cluster_tmp], eax
test eax, eax
jnz @f
cmp [fs_type], 32
jz .notfound
mov eax, [ROOT_START]
push [ROOT_SECTORS]
push ebx
jmp .new_sector
@@:
dec eax
dec eax
imul eax, [SECTORS_PER_CLUSTER]
push [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
push ebx
.new_sector:
mov ebx, buffer
mov edi, ebx
call hd_read
cmp [hd_error], 0
jnz .notfound2
add ebx, 512
push eax
.l1:
call fat_get_name
jc .l2
cmp byte [edi+11], 0xF
jnz .do_bdfe
add edi, 0x20
cmp edi, ebx
jb .do_bdfe
pop eax
inc eax
dec dword [esp+4]
jnz @f
mov eax, [cluster_tmp]
test eax, eax
jz .done
call get_FAT
cmp [hd_error], 0
jnz .notfound2
cmp eax, 2
jb .done
cmp eax, [fatRESERVED]
jae .done
push eax
mov eax, [SECTORS_PER_CLUSTER]
mov [esp+8], eax
pop eax
mov [cluster_tmp], eax
dec eax
dec eax
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
@@:
mov ebx, buffer
mov edi, ebx
call hd_read
cmp [hd_error], 0
jnz .notfound2
add ebx, 512
push eax
.do_bdfe:
inc dword [edx+8] ; new file found
dec dword [esp+4]
jns .l2
dec ecx
js .l2
inc dword [edx+4] ; new file block copied
call fat_entry_to_bdfe
.l2:
add edi, 0x20
cmp edi, ebx
jb .l1
pop eax
inc eax
dec dword [esp+4]
jnz .new_sector
mov eax, [cluster_tmp]
test eax, eax
jz .done
call get_FAT
cmp [hd_error], 0
jnz .notfound2
cmp eax, 2
jb .done
cmp eax, [fatRESERVED]
jae .done
push eax
mov eax, [SECTORS_PER_CLUSTER]
mov [esp+8], eax
pop eax
pop ebx
add esp, 4
jmp .new_cluster
.notfound2:
add esp, 8
.notfound:
add esp, 262*2+4
pop ebp ecx esi edi
mov eax, ERROR_FILE_NOT_FOUND
or ebx, -1
ret
.done:
add esp, 262*2+4+8
pop ebp
mov ebx, [edx+4]
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
@@:
pop ecx esi edi
ret
 
fat16_root_next:
cmp edi, buffer+0x200-0x20
jae fat16_root_next_sector
add edi, 0x20
ret ; CF=0
fat16_root_next_sector:
; read next sector
push [longname_sec2]
pop [longname_sec1]
push ecx
mov ecx, [eax+4]
push ecx
add ecx, [ROOT_START]
mov [longname_sec2], ecx
pop ecx
inc ecx
mov [eax+4], ecx
cmp ecx, [ROOT_SECTORS]
pop ecx
jae fat16_root_first.readerr
fat16_root_first:
mov eax, [eax+4]
add eax, [ROOT_START]
push ebx
mov edi, buffer
mov ebx, edi
call hd_read
pop ebx
cmp [hd_error], 0
jnz .readerr
ret ; CF=0
.readerr:
stc
ret
fat16_root_begin_write:
push edi eax
call fat16_root_first
pop eax edi
ret
fat16_root_end_write:
pusha
mov eax, [eax+4]
add eax, [ROOT_START]
mov ebx, buffer
call hd_write
popa
ret
fat16_root_next_write:
cmp edi, buffer+0x200
jae @f
ret
@@:
call fat16_root_end_write
jmp fat16_root_next_sector
fat16_root_extend_dir:
stc
ret
 
fat_notroot_next:
cmp edi, buffer+0x200-0x20
jae fat_notroot_next_sector
add edi, 0x20
ret ; CF=0
fat_notroot_next_sector:
push [longname_sec2]
pop [longname_sec1]
push eax
call fat_get_sector
mov [longname_sec2], eax
pop eax
push ecx
mov ecx, [eax+4]
inc ecx
cmp ecx, [SECTORS_PER_CLUSTER]
jae fat_notroot_next_cluster
mov [eax+4], ecx
jmp @f
fat_notroot_next_cluster:
push eax
mov eax, [eax]
call get_FAT
mov ecx, eax
pop eax
cmp [hd_error], 0
jnz fat_notroot_next_err
cmp ecx, [fatRESERVED]
jae fat_notroot_next_err
mov [eax], ecx
and dword [eax+4], 0
@@:
pop ecx
fat_notroot_first:
call fat_get_sector
push ebx
mov edi, buffer
mov ebx, edi
call hd_read
pop ebx
cmp [hd_error], 0
jnz @f
ret ; CF=0
fat_notroot_next_err:
pop ecx
@@:
stc
ret
fat_notroot_begin_write:
push eax edi
call fat_notroot_first
pop edi eax
ret
fat_notroot_end_write:
call fat_get_sector
push ebx
mov ebx, buffer
call hd_write
pop ebx
ret
fat_notroot_next_write:
cmp edi, buffer+0x200
jae @f
ret
@@:
push eax
call fat_notroot_end_write
pop eax
jmp fat_notroot_next_sector
fat_notroot_extend_dir:
push eax
call get_free_FAT
jnc .found
pop eax
ret ; CF=1
.found:
push edx
mov edx, [fatEND]
call set_FAT
mov edx, eax
mov eax, [esp+4]
mov eax, [eax]
push edx
call set_FAT
pop edx
cmp [hd_error], 0
jz @f
pop edx
pop eax
stc
ret
@@:
push ecx
or ecx, -1
call add_disk_free_space
; zero new cluster
mov ecx, 512/4
mov edi, buffer
push edi
xor eax, eax
rep stosd
pop edi
pop ecx
mov eax, [esp+4]
mov [eax], edx
and dword [eax+4], 0
pop edx
mov eax, [eax]
dec eax
dec eax
push ebx ecx
mov ecx, [SECTORS_PER_CLUSTER]
imul eax, ecx
add eax, [DATA_START]
mov ebx, edi
@@:
call hd_write
inc eax
loop @b
pop ecx ebx eax
clc
ret
 
fat_get_sector:
push ecx
mov ecx, [eax]
dec ecx
dec ecx
imul ecx, [SECTORS_PER_CLUSTER]
add ecx, [DATA_START]
add ecx, [eax+4]
mov eax, ecx
pop ecx
ret
 
;----------------------------------------------------------------
;
; fs_HdRewrite - LFN variant for writing hard disk
;
; esi points to filename
; ebx ignored (reserved)
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = number of written bytes
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fshrad:
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
fshrfs:
mov eax, ERROR_UNKNOWN_FS
xor ebx, ebx
ret
 
fs_HdCreateFolder:
mov al, 1
jmp fs_HdRewrite.common
 
fs_HdRewrite:
xor eax, eax
.common:
cmp [fs_type], 1
jz ntfs_HdRewrite
cmp [fs_type], 2
jz ext2_HdRewrite
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jnz fshrfs
@@:
cmp byte [esi], 0
jz fshrad
pushad
xor edi, edi
push esi
test ebp, ebp
jz @f
mov esi, ebp
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
lea edi, [esi-1]
jmp @b
@@:
pop esi
test edi, edi
jnz .noroot
test ebp, ebp
jnz .hasebp
mov ebp, [ROOT_CLUSTER]
cmp [fs_type], 32
jz .pushnotroot
push fat16_root_extend_dir
push fat16_root_end_write
push fat16_root_next_write
push fat16_root_begin_write
xor ebp, ebp
push ebp
push ebp
push fat16_root_first
push fat16_root_next
jmp .common1
.hasebp:
mov eax, ERROR_ACCESS_DENIED
cmp byte [ebp], 0
jz .ret1
push ebp
xor ebp, ebp
call hd_find_lfn
pop esi
jc .notfound0
jmp .common0
.noroot:
mov eax, ERROR_ACCESS_DENIED
cmp byte [edi+1], 0
jz .ret1
; check existence
mov byte [edi], 0
push edi
call hd_find_lfn
pop esi
mov byte [esi], '/'
jnc @f
.notfound0:
mov eax, ERROR_FILE_NOT_FOUND
.ret1:
mov [esp+28], eax
popad
xor ebx, ebx
ret
@@:
inc esi
.common0:
test byte [edi+11], 0x10 ; must be directory
mov eax, ERROR_ACCESS_DENIED
jz .ret1
mov ebp, [edi+20-2]
mov bp, [edi+26] ; ebp=cluster
mov eax, ERROR_FAT_TABLE
cmp ebp, 2
jb .ret1
.pushnotroot:
push fat_notroot_extend_dir
push fat_notroot_end_write
push fat_notroot_next_write
push fat_notroot_begin_write
push 0
push ebp
push fat_notroot_first
push fat_notroot_next
.common1:
call fat_find_lfn
jc .notfound
; found
test byte [edi+11], 10h
jz .exists_file
; found directory; if we are creating directory, return OK,
; if we are creating file, say "access denied"
add esp, 32
popad
test al, al
mov eax, ERROR_ACCESS_DENIED
jz @f
mov al, 0
@@:
xor ebx, ebx
ret
.exists_file:
; found file; if we are creating directory, return "access denied",
; if we are creating file, delete existing file and continue
cmp byte [esp+32+28], 0
jz @f
add esp, 32
popad
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
@@:
; delete FAT chain
push edi
xor eax, eax
mov dword [edi+28], eax ; zero size
xor ecx, ecx
mov eax, [edi+20-2]
mov ax, [edi+26]
mov word [edi+20], cx
mov word [edi+26], cx
test eax, eax
jz .done1
@@:
cmp eax, [fatRESERVED]
jae .done1
push edx
xor edx, edx
call set_FAT
mov eax, edx
pop edx
inc ecx
jmp @b
.done1:
pop edi
call get_time_for_file
mov [edi+22], ax
call get_date_for_file
mov [edi+24], ax
mov [edi+18], ax
or byte [edi+11], 20h ; set 'archive' attribute
jmp .doit
.notfound:
; file is not found; generate short name
call fat_name_is_legal
jc @f
add esp, 32
popad
mov eax, ERROR_FILE_NOT_FOUND
xor ebx, ebx
ret
@@:
sub esp, 12
mov edi, esp
call fat_gen_short_name
.test_short_name_loop:
push esi edi ecx
mov esi, edi
lea eax, [esp+12+12+8]
mov [eax], ebp
and dword [eax+4], 0
call dword [eax-4]
jc .found
.test_short_name_entry:
cmp byte [edi+11], 0xF
jz .test_short_name_cont
mov ecx, 11
push esi edi
repz cmpsb
pop edi esi
jz .short_name_found
.test_short_name_cont:
lea eax, [esp+12+12+8]
call dword [eax-8]
jnc .test_short_name_entry
jmp .found
.short_name_found:
pop ecx edi esi
call fat_next_short_name
jnc .test_short_name_loop
.disk_full:
add esp, 12+32
popa
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.found:
pop ecx edi esi
; now find space in directory
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
mov al, '~'
push ecx edi
mov ecx, 8
repnz scasb
push 1
pop eax ; 1 entry
jnz .notilde
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
xor eax, eax
@@:
cmp byte [esi], 0
jz @f
inc esi
inc eax
jmp @b
@@:
sub esi, eax
add eax, 12+13
mov ecx, 13
push edx
cdq
div ecx
pop edx
.notilde:
push -1
push -1
push -1
; find <eax> successive entries in directory
xor ecx, ecx
push eax
lea eax, [esp+16+8+12+8]
mov [eax], ebp
and dword [eax+4], 0
call dword [eax-4]
pop eax
jnc .scan_dir
.fsfrfe3:
add esp, 12+8+12+32
popad
mov eax, 11
xor ebx, ebx
ret
.scan_dir:
cmp byte [edi], 0
jz .free
cmp byte [edi], 0xE5
jz .free
xor ecx, ecx
.scan_cont:
push eax
lea eax, [esp+16+8+12+8]
call dword [eax-8]
pop eax
jnc .scan_dir
cmp [hd_error], 0
jnz .fsfrfe3
push eax
lea eax, [esp+16+8+12+8]
call dword [eax+20] ; extend directory
pop eax
jnc .scan_dir
add esp, 12+8+12+32
popad
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.free:
test ecx, ecx
jnz @f
mov [esp], edi
mov ecx, [esp+12+8+12+8]
mov [esp+4], ecx
mov ecx, [esp+12+8+12+12]
mov [esp+8], ecx
xor ecx, ecx
@@:
inc ecx
cmp ecx, eax
jb .scan_cont
; found!
; calculate name checksum
push esi ecx
mov esi, [esp+8+12]
mov ecx, 11
xor eax, eax
@@:
ror al, 1
add al, [esi]
inc esi
loop @b
pop ecx esi
pop edi
pop dword [esp+8+12+12]
pop dword [esp+8+12+12]
; edi points to first entry in free chunk
dec ecx
jz .nolfn
push esi
push eax
lea eax, [esp+8+8+12+8]
call dword [eax+8] ; begin write
mov al, 40h
.writelfn:
or al, cl
mov esi, [esp+4]
push ecx
dec ecx
imul ecx, 13
add esi, ecx
stosb
mov cl, 5
call fs_RamdiskRewrite.read_symbols
mov ax, 0xF
stosw
mov al, [esp+4]
stosb
mov cl, 6
call fs_RamdiskRewrite.read_symbols
xor eax, eax
stosw
mov cl, 2
call fs_RamdiskRewrite.read_symbols
pop ecx
lea eax, [esp+8+8+12+8]
call dword [eax+12] ; next write
xor eax, eax
loop .writelfn
pop eax
pop esi
; lea eax, [esp+8+12+8]
; call dword [eax+16] ; end write
.nolfn:
xchg esi, [esp]
mov ecx, 11
rep movsb
mov word [edi], 20h ; attributes
sub edi, 11
pop esi ecx
add esp, 12
mov byte [edi+13], 0 ; tenths of a second at file creation time
call get_time_for_file
mov [edi+14], ax ; creation time
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+16], ax ; creation date
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
xor ecx, ecx
mov word [edi+20], cx ; high word of cluster
mov word [edi+26], cx ; low word of cluster - to be filled
mov dword [edi+28], ecx ; file size - to be filled
cmp byte [esp+32+28], cl
jz .doit
; create directory
mov byte [edi+11], 10h ; attributes: folder
mov edx, edi
lea eax, [esp+8]
call dword [eax+16] ; flush directory
push ecx
mov ecx, [SECTORS_PER_CLUSTER]
shl ecx, 9
jmp .doit2
.doit:
lea eax, [esp+8]
call dword [eax+16] ; flush directory
push ecx
mov ecx, [esp+4+32+24]
.doit2:
push ecx
push edi
mov esi, edx
test ecx, ecx
jz .done
call get_free_FAT
jc .diskfull
push eax
mov [edi+26], ax
shr eax, 16
mov [edi+20], ax
lea eax, [esp+16+8]
call dword [eax+16] ; flush directory
pop eax
push edx
mov edx, [fatEND]
call set_FAT
pop edx
.write_cluster:
push eax
dec eax
dec eax
mov ebp, [SECTORS_PER_CLUSTER]
imul eax, ebp
add eax, [DATA_START]
; write data
.write_sector:
cmp byte [esp+16+32+28], 0
jnz .writedir
mov ecx, 512
cmp dword [esp+8], ecx
jb .writeshort
; we can write directly from given buffer
mov ebx, esi
add esi, ecx
jmp .writecommon
.writeshort:
mov ecx, [esp+8]
push ecx
mov edi, buffer
mov ebx, edi
rep movsb
.writedircont:
mov ecx, buffer+0x200
sub ecx, edi
push eax
xor eax, eax
rep stosb
pop eax
pop ecx
.writecommon:
call hd_write
cmp [hd_error], 0
jnz .writeerr
inc eax
sub dword [esp+8], ecx
jz .writedone
dec ebp
jnz .write_sector
; allocate new cluster
pop eax
mov ecx, eax
call get_free_FAT
jc .diskfull
push edx
mov edx, [fatEND]
call set_FAT
xchg eax, ecx
mov edx, ecx
call set_FAT
pop edx
xchg eax, ecx
jmp .write_cluster
.diskfull:
mov eax, ERROR_DISK_FULL
jmp .ret
.writeerr:
pop eax
sub esi, ecx
mov eax, 11
jmp .ret
.writedone:
pop eax
.done:
xor eax, eax
.ret:
pop edi ecx
mov ebx, esi
sub ebx, edx
pop ebp
mov [esp+32+28], eax
lea eax, [esp+8]
call dword [eax+8]
mov [edi+28], ebx
call dword [eax+16]
mov [esp+32+16], ebx
lea eax, [ebx+511]
shr eax, 9
mov ecx, [SECTORS_PER_CLUSTER]
lea eax, [eax+ecx-1]
xor edx, edx
div ecx
mov ecx, ebp
sub ecx, eax
call add_disk_free_space
add esp, 32
call update_disk
popad
ret
.writedir:
push 512
mov edi, buffer
mov ebx, edi
mov ecx, [SECTORS_PER_CLUSTER]
shl ecx, 9
cmp ecx, [esp+12]
jnz .writedircont
dec dword [esp+16]
push esi
mov ecx, 32/4
rep movsd
pop esi
mov dword [edi-32], '. '
mov dword [edi-32+4], ' '
mov dword [edi-32+8], ' '
mov byte [edi-32+11], 10h
push esi
mov ecx, 32/4
rep movsd
pop esi
mov dword [edi-32], '.. '
mov dword [edi-32+4], ' '
mov dword [edi-32+8], ' '
mov byte [edi-32+11], 10h
mov ecx, [esp+20+8]
cmp ecx, [ROOT_CLUSTER]
jnz @f
xor ecx, ecx
@@:
mov word [edi-32+26], cx
shr ecx, 16
mov [edi-32+20], cx
jmp .writedircont
 
;----------------------------------------------------------------
;
; fs_HdWrite - LFN variant for writing to hard disk
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = bytes written (maybe 0)
; eax = 0 ok write or other = errormsg
;
;--------------------------------------------------------------
fs_HdWrite.access_denied:
push ERROR_ACCESS_DENIED
fs_HdWrite.ret0:
pop eax
xor ebx, ebx
ret
 
fs_HdWrite.ret11:
push 11
jmp fs_HdWrite.ret0
 
fs_HdWrite:
cmp [fs_type], 1
jz ntfs_HdWrite
cmp [fs_type], 2
jz ext2_HdWrite
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
push ERROR_UNKNOWN_FS
jmp .ret0
@@:
cmp byte [esi], 0
jz .access_denied
pushad
call hd_find_lfn
pushfd
cmp [hd_error], 0
jz @f
popfd
popad
push 11
jmp .ret0
@@:
popfd
jnc .found
popad
push ERROR_FILE_NOT_FOUND
jmp .ret0
.found:
; FAT does not support files larger than 4GB
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
.eof:
popad
push ERROR_END_OF_FILE
jmp .ret0
@@:
mov ebx, [ebx]
.l1:
; now edi points to direntry, ebx=start byte to write,
; ecx=number of bytes to write, edx=data pointer
 
; extend file if needed
add ecx, ebx
jc .eof ; FAT does not support files larger than 4GB
push eax ; save directory sector
push 0 ; return value=0
 
call get_time_for_file
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
 
push dword [edi+28] ; save current file size
cmp ecx, [edi+28]
jbe .length_ok
cmp ecx, ebx
jz .length_ok
call hd_extend_file
jnc .length_ok
mov [esp+4], eax
; hd_extend_file can return three error codes: FAT table error, device error or disk full.
; First two cases are fatal errors, in third case we may write some data
cmp al, ERROR_DISK_FULL
jz .disk_full
pop eax
pop eax
mov [esp+4+28], eax
pop eax
popad
xor ebx, ebx
ret
.disk_full:
; correct number of bytes to write
mov ecx, [edi+28]
cmp ecx, ebx
ja .length_ok
.ret:
call update_disk
cmp [hd_error], 0
jz @f
mov byte [esp+4], 11
@@:
pop eax
pop eax
mov [esp+4+28], eax ; eax=return value
pop eax
sub edx, [esp+20]
mov [esp+16], edx ; ebx=number of written bytes
popad
ret
.length_ok:
mov esi, [edi+28]
mov eax, [edi+20-2]
mov ax, [edi+26]
mov edi, eax ; edi=current cluster
xor ebp, ebp ; ebp=current sector in cluster
; save directory
mov eax, [esp+8]
push ebx
mov ebx, buffer
call hd_write
pop ebx
cmp [hd_error], 0
jz @f
.device_err:
mov byte [esp+4], 11
jmp .ret
@@:
 
; now ebx=start pos, ecx=end pos, both lie inside file
sub ecx, ebx
jz .ret
.write_loop:
; skip unmodified sectors
cmp dword [esp], 0x200
jb .modify
sub ebx, 0x200
jae .skip
add ebx, 0x200
.modify:
; get length of data in current sector
push ecx
sub ebx, 0x200
jb .hasdata
neg ebx
xor ecx, ecx
jmp @f
.hasdata:
neg ebx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
; get current sector number
mov eax, edi
dec eax
dec eax
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
add eax, ebp
; load sector if needed
cmp dword [esp+4], 0 ; we don't need to read uninitialized data
jz .noread
cmp ecx, 0x200 ; we don't need to read sector if it is fully rewritten
jz .noread
cmp ecx, esi ; (same for the last sector)
jz .noread
push ebx
mov ebx, buffer
call hd_read
pop ebx
cmp [hd_error], 0
jz @f
.device_err2:
pop ecx
jmp .device_err
@@:
.noread:
; zero uninitialized data if file was extended (because hd_extend_file does not this)
push eax ecx edi
xor eax, eax
mov ecx, 0x200
sub ecx, [esp+4+12]
jbe @f
mov edi, buffer
add edi, [esp+4+12]
rep stosb
@@:
; zero uninitialized data in the last sector
mov ecx, 0x200
sub ecx, esi
jbe @f
mov edi, buffer
add edi, esi
rep stosb
@@:
pop edi ecx
; copy new data
mov eax, edx
neg ebx
jecxz @f
add ebx, buffer+0x200
call memmove
xor ebx, ebx
@@:
pop eax
; save sector
push ebx
mov ebx, buffer
call hd_write
pop ebx
cmp [hd_error], 0
jnz .device_err2
add edx, ecx
sub [esp], ecx
pop ecx
jz .ret
.skip:
; next sector
inc ebp
cmp ebp, [SECTORS_PER_CLUSTER]
jb @f
xor ebp, ebp
mov eax, edi
call get_FAT
mov edi, eax
cmp [hd_error], 0
jnz .device_err
@@:
sub esi, 0x200
jae @f
xor esi, esi
@@:
sub dword [esp], 0x200
jae @f
and dword [esp], 0
@@: jmp .write_loop
 
hd_extend_file.zero_size:
xor eax, eax
jmp hd_extend_file.start_extend
 
; extends file on hd to given size (new data area is undefined)
; in: edi->direntry, ecx=new size
; out: CF=0 => OK, eax=0
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or 11)
hd_extend_file:
push ebp
mov ebp, [SECTORS_PER_CLUSTER]
imul ebp, [BYTES_PER_SECTOR]
push ecx
; find the last cluster of file
mov eax, [edi+20-2]
mov ax, [edi+26]
mov ecx, [edi+28]
jecxz .zero_size
.last_loop:
sub ecx, ebp
jbe .last_found
call get_FAT
cmp [hd_error], 0
jz @f
.device_err:
pop ecx
.device_err2:
pop ebp
push 11
.ret_err:
pop eax
stc
ret
@@:
cmp eax, 2
jb .fat_err
cmp eax, [fatRESERVED]
jb .last_loop
.fat_err:
pop ecx ebp
push ERROR_FAT_TABLE
jmp .ret_err
.last_found:
push eax
call get_FAT
cmp [hd_error], 0
jz @f
pop eax
jmp .device_err
@@:
cmp eax, [fatRESERVED]
pop eax
jb .fat_err
; set length to full number of clusters
sub [edi+28], ecx
.start_extend:
pop ecx
; now do extend
push edx
mov edx, 2 ; start scan from cluster 2
.extend_loop:
cmp [edi+28], ecx
jae .extend_done
; add new cluster
push eax
call get_free_FAT
jc .disk_full
mov edx, [fatEND]
call set_FAT
mov edx, eax
pop eax
test eax, eax
jz .first_cluster
push edx
call set_FAT
pop edx
jmp @f
.first_cluster:
ror edx, 16
mov [edi+20], dx
ror edx, 16
mov [edi+26], dx
@@:
push ecx
mov ecx, -1
call add_disk_free_space
pop ecx
mov eax, edx
cmp [hd_error], 0
jnz .device_err3
add [edi+28], ebp
jmp .extend_loop
.extend_done:
mov [edi+28], ecx
pop edx ebp
xor eax, eax ; CF=0
ret
.device_err3:
pop edx
jmp .device_err2
.disk_full:
pop eax edx ebp
push ERROR_DISK_FULL
pop eax
cmp [hd_error], 0
jz @f
mov al, 11
@@: stc
ret
 
;----------------------------------------------------------------
;
; fs_HdSetFileEnd - set end of file on hard disk
;
; esi points to filename
; ebx points to 64-bit number = new file size
; ecx ignored (reserved)
; edx ignored (reserved)
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_HdSetFileEnd:
cmp [fs_type], 1
jz ntfs_HdSetFileEnd
cmp [fs_type], 2
jz ext2_HdSetFileEnd
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
push ERROR_UNKNOWN_FS
.ret:
pop eax
ret
@@:
cmp byte [esi], 0
jnz @f
.access_denied:
push ERROR_ACCESS_DENIED
jmp .ret
@@:
push edi
call hd_find_lfn
pushfd
cmp [hd_error], 0
jz @f
popfd
push 11
jmp .ret
@@:
popfd
jnc @f
pop edi
push ERROR_FILE_NOT_FOUND
jmp .ret
@@:
; must not be directory
test byte [edi+11], 10h
jz @f
pop edi
jmp .access_denied
@@:
; file size must not exceed 4 Gb
cmp dword [ebx+4], 0
jz @f
pop edi
push ERROR_END_OF_FILE
jmp .ret
@@:
push eax ; save directory sector
; set file modification date/time to current
call fat_update_datetime
mov eax, [ebx]
cmp eax, [edi+28]
jb .truncate
ja .expand
pop eax
mov ebx, buffer
call hd_write
pop edi
xor eax, eax
cmp [hd_error], 0
jz @f
mov al, 11
@@:
ret
.expand:
push ebx ebp ecx
push dword [edi+28] ; save old size
mov ecx, eax
call hd_extend_file
push eax ; return code
jnc .expand_ok
cmp al, ERROR_DISK_FULL
jz .disk_full
.pop_ret:
call update_disk
pop eax ecx ebp ebx ecx edi edi
ret
.expand_ok:
.disk_full:
; save directory
mov eax, [edi+28]
xchg eax, [esp+20]
mov ebx, buffer
call hd_write
mov eax, [edi+20-2]
mov ax, [edi+26]
mov edi, eax
cmp [hd_error], 0
jz @f
.pop_ret11:
mov byte [esp], 11
jmp .pop_ret
@@:
; now zero new data
xor ebp, ebp
; edi=current cluster, ebp=sector in cluster
; [esp+20]=new size, [esp+4]=old size, [esp]=return code
.zero_loop:
sub dword [esp+4], 0x200
jae .next_cluster
lea eax, [edi-2]
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
add eax, ebp
cmp dword [esp+4], -0x200
jz .noread
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jnz .err_next
.noread:
mov ecx, [esp+4]
neg ecx
push edi
mov edi, buffer+0x200
add edi, [esp+8]
push eax
xor eax, eax
mov [esp+12], eax
rep stosb
pop eax
pop edi
call hd_write
cmp [hd_error], 0
jz .next_cluster
.err_next:
mov byte [esp], 11
.next_cluster:
sub dword [esp+20], 0x200
jbe .pop_ret
inc ebp
cmp ebp, [SECTORS_PER_CLUSTER]
jb .zero_loop
xor ebp, ebp
mov eax, edi
call get_FAT
mov edi, eax
cmp [hd_error], 0
jnz .pop_ret11
jmp .zero_loop
.truncate:
mov [edi+28], eax
push ecx
mov ecx, [edi+20-2]
mov cx, [edi+26]
push eax
test eax, eax
jz .zero_size
; find new last cluster
@@:
mov eax, [SECTORS_PER_CLUSTER]
shl eax, 9
sub [esp], eax
jbe @f
mov eax, ecx
call get_FAT
mov ecx, eax
cmp [hd_error], 0
jz @b
.device_err3:
pop eax ecx eax edi
push 11
pop eax
ret
@@:
; we will zero data at the end of last sector - remember it
push ecx
; terminate FAT chain
push edx
mov eax, ecx
mov edx, [fatEND]
call set_FAT
mov eax, edx
pop edx
cmp [hd_error], 0
jz @f
.device_err4:
pop ecx
jmp .device_err3
.zero_size:
and word [edi+20], 0
and word [edi+26], 0
push 0
mov eax, ecx
@@:
; delete FAT chain
call clear_cluster_chain
cmp [hd_error], 0
jnz .device_err4
; save directory
mov eax, [esp+12]
push ebx
mov ebx, buffer
call hd_write
pop ebx
cmp [hd_error], 0
jnz .device_err4
; zero last sector, ignore errors
pop ecx
pop eax
dec ecx
imul ecx, [SECTORS_PER_CLUSTER]
add ecx, [DATA_START]
push eax
sar eax, 9
add ecx, eax
pop eax
and eax, 0x1FF
jz .truncate_done
push ebx eax
mov eax, ecx
mov ebx, buffer
call hd_read
pop eax
lea edi, [buffer+eax]
push ecx
mov ecx, 0x200
sub ecx, eax
xor eax, eax
rep stosb
pop eax
call hd_write
pop ebx
.truncate_done:
pop ecx eax edi
call update_disk
xor eax, eax
cmp [hd_error], 0
jz @f
mov al, 11
@@:
ret
 
fs_HdGetFileInfo:
cmp [fs_type], 1
jz ntfs_HdGetFileInfo
cmp [fs_type], 2
jz ext2_HdGetFileInfo
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
mov eax, ERROR_UNKNOWN_FS
ret
@@:
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
@@:
push edi
call hd_find_lfn
pushfd
cmp [hd_error], 0
jz @f
popfd
pop edi
mov eax, 11
ret
@@:
popfd
jmp fs_GetFileInfo_finish
 
fs_HdSetFileInfo:
cmp [fs_type], 1
jz ntfs_HdSetFileInfo
cmp [fs_type], 2
jz ext2_HdSetFileInfo
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
mov eax, ERROR_UNKNOWN_FS
ret
@@:
cmp byte [esi], 0
jnz @f
mov eax, 2
ret
@@:
push edi
call hd_find_lfn
pushfd
cmp [hd_error], 0
jz @f
popfd
pop edi
mov eax, 11
ret
@@:
popfd
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
@@:
push eax
call bdfe_to_fat_entry
pop eax
mov ebx, buffer
call hd_write
call update_disk
pop edi
xor eax, eax
ret
 
;----------------------------------------------------------------
;
; fs_HdDelete - delete file or empty folder from hard disk
;
; esi points to filename
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_HdDelete:
cmp [fs_type], 1
jz ntfs_HdDelete
cmp [fs_type], 1
jz ext2_HdDelete
cmp [fs_type], 16
jz @f
cmp [fs_type], 32
jz @f
push ERROR_UNKNOWN_FS
.pop_ret:
pop eax
ret
@@:
cmp byte [esi], 0
jnz @f
; cannot delete root!
.access_denied:
push ERROR_ACCESS_DENIED
jmp .pop_ret
@@:
and [longname_sec1], 0
and [longname_sec2], 0
push edi
call hd_find_lfn
jnc .found
pop edi
push ERROR_FILE_NOT_FOUND
jmp .pop_ret
.found:
cmp dword [edi], '. '
jz .access_denied2
cmp dword [edi], '.. '
jz .access_denied2
test byte [edi+11], 10h
jz .dodel
; we can delete only empty folders!
pushad
mov ebp, [edi+20-2]
mov bp, [edi+26]
xor ecx, ecx
lea eax, [ebp-2]
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jnz .err1
add ebx, 2*0x20
.checkempty:
cmp byte [ebx], 0
jz .empty
cmp byte [ebx], 0xE5
jnz .notempty
add ebx, 0x20
cmp ebx, buffer+0x200
jb .checkempty
inc ecx
cmp ecx, [SECTORS_PER_CLUSTER]
jb @f
mov eax, ebp
call get_FAT
cmp [hd_error], 0
jnz .err1
mov ebp, eax
xor ecx, ecx
@@:
lea eax, [ebp-2]
imul eax, [SECTORS_PER_CLUSTER]
add eax, [DATA_START]
add eax, ecx
mov ebx, buffer
call hd_read
cmp [hd_error], 0
jz .checkempty
.err1:
popad
.err2:
pop edi
push 11
pop eax
ret
.notempty:
popad
.access_denied2:
pop edi
push ERROR_ACCESS_DENIED
pop eax
ret
.empty:
popad
push ebx
mov ebx, buffer
call hd_read
pop ebx
cmp [hd_error], 0
jnz .err2
.dodel:
push eax
mov eax, [edi+20-2]
mov ax, [edi+26]
xchg eax, [esp]
; delete folder entry
mov byte [edi], 0xE5
; delete LFN (if present)
.lfndel:
cmp edi, buffer
ja @f
cmp [longname_sec2], 0
jz .lfndone
push [longname_sec2]
push [longname_sec1]
pop [longname_sec2]
and [longname_sec1], 0
push ebx
mov ebx, buffer
call hd_write
mov eax, [esp+4]
call hd_read
pop ebx
pop eax
mov edi, buffer+0x200
@@:
sub edi, 0x20
cmp byte [edi], 0xE5
jz .lfndone
cmp byte [edi+11], 0xF
jnz .lfndone
mov byte [edi], 0xE5
jmp .lfndel
.lfndone:
push ebx
mov ebx, buffer
call hd_write
pop ebx
; delete FAT chain
pop eax
call clear_cluster_chain
call update_disk
pop edi
xor eax, eax
cmp [hd_error], 0
jz @f
mov al, 11
@@:
ret
 
; \end{diamond}
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/fs/fs.inc
0,0 → 1,797
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; System service for filesystem call ;;
;; (C) 2004 Ville Turjanmaa, License: GPL ;;
;; 29.04.2006 Elimination of hangup after the ;;
;; expiration hd_wait_timeout (for LBA) - Mario79 ;;
;; 15.01.2005 get file size/attr/date, ;;
;; file_append (only for hd) - ATV ;;
;; 23.11.2004 test if hd/partition is set - ATV ;;
;; 18.11.2004 get_disk_info and more error codes - ATV ;;
;; 08.11.2004 expand_pathz and rename (only for hd) - ATV ;;
;; 20.10.2004 Makedir/Removedir (only for hd) - ATV ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
iglobal
dir0: db 'HARDDISK '
db 'RAMDISK '
db 'FLOPPYDISK '
db 0
 
dir1: db 'FIRST '
db 'SECOND '
db 'THIRD '
db 'FOURTH '
db 0
 
not_select_IDE db 0
 
hd_address_table: dd 0x1f0,0x00,0x1f0,0x10
dd 0x170,0x00,0x170,0x10
endg
 
file_system:
 
; IN:
;
; eax = 0 ; read file /RamDisk/First 6
; eax = 8 ; lba read
; eax = 15 ; get_disk_info
;
; OUT:
;
; eax = 0 : read ok
; eax = 1 : no hd base and/or partition defined
; eax = 2 : function is unsupported for this FS
; eax = 3 : unknown FS
; eax = 4 : partition not defined at hd
; eax = 5 : file not found
; eax = 6 : end of file
; eax = 7 : memory pointer not in application area
; eax = 8 : disk full
; eax = 9 : fat table corrupted
; eax = 10 : access denied
; eax = 11 : disk error
;
; ebx = size
 
; \begin{diamond}[18.03.2006]
; for subfunction 16 (start application) error codes must be negative
; because positive values are valid PIDs
; so possible return values are:
; eax > 0 : process created, eax=PID
 
; -0x10 <= eax < 0 : -eax is filesystem error code:
; eax = -1 = 0xFFFFFFFF : no hd base and/or partition defined
; eax = -3 = 0xFFFFFFFD : unknown FS
; eax = -5 = 0xFFFFFFFB : file not found
; eax = -6 = 0xFFFFFFFA : unexpected end of file (probably not executable file)
; eax = -9 = 0xFFFFFFF7 : fat table corrupted
; eax = -10 = 0xFFFFFFF6 : access denied
 
; -0x20 <= eax < -0x10: eax is process creation error code:
; eax = -0x20 = 0xFFFFFFE0 : too many processes
; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable
; eax = -0x1E = 0xFFFFFFE2 : no memory
 
; ebx is not changed
 
; \end{diamond}[18.03.2006]
 
; Extract parameters
; add eax, std_application_base_address ; abs start of info block
 
cmp dword [eax+0],15 ; GET_DISK_INFO
je fs_info
 
cmp dword [CURRENT_TASK],1 ; no memory checks for kernel requests
jz no_checks_for_kernel
mov edx,eax
cmp dword [eax+0],1
jnz .usual_check
mov ebx,[eax+12]
; add ebx,std_application_base_address
mov ecx,[eax+8]
call check_region
test eax,eax
jnz area_in_app_mem
 
.error_output:
mov esi,buffer_failed
call sys_msg_board_str
; mov eax,7
mov dword [esp+36],7
ret
iglobal
buffer_failed db 'K : Buffer check failed',13,10,0
endg
.usual_check:
cmp dword [eax+0],0
mov ecx,512
jnz .small_size
mov ecx,[eax+8]
shl ecx,9
.small_size:
mov ebx,[eax+12]
; add ebx,std_application_base_address
call check_region
test eax,eax
jz .error_output
area_in_app_mem:
mov eax,edx
no_checks_for_kernel:
 
fs_read:
 
mov ebx,[eax+20] ; program wants root directory ?
test bl,bl
je fs_getroot
test bh,bh
jne fs_noroot
fs_getroot:
; \begin{diamond}[18.03.2006]
; root - only read is allowed
; other operations return "access denied", eax=10
; (execute operation returns eax=-10)
cmp dword [eax], 0
jz .read_root
mov dword [esp+36], 10
ret
.read_root:
; \end{diamond}[18.03.2006]
mov esi,dir0
mov edi,[eax+12]
; add edi,std_application_base_address
mov ecx,11
push ecx
; cld ; already is
rep movsb
mov al,0x10
stosb
add edi,32-11-1
pop ecx
rep movsb
stosb
and dword [esp+36],0 ; ok read
mov dword [esp+24],32*2 ; size of root
ret
 
fs_info: ;start of code - Mihasik
push eax
cmp [eax+21],byte 'h'
je fs_info_h
cmp [eax+21],byte 'H'
je fs_info_h
cmp [eax+21],byte 'r'
je fs_info_r
cmp [eax+21],byte 'R'
je fs_info_r
mov eax,3 ;if unknown disk
xor ebx,ebx
xor ecx,ecx
xor edx,edx
jmp fs_info1
fs_info_r:
call ramdisk_free_space ;if ramdisk
mov ecx,edi ;free space in ecx
shr ecx,9 ;free clusters
mov ebx,2847 ;total clusters
mov edx,512 ;cluster size
xor eax,eax ;always 0
jmp fs_info1
fs_info_h: ;if harddisk
call get_hd_info
fs_info1:
pop edi
mov [esp+36],eax
mov [esp+24],ebx ; total clusters on disk
mov [esp+32],ecx ; free clusters on disk
mov [edi],edx ; cluster size in bytes
ret ;end of code - Mihasik
 
fs_noroot:
 
push dword [eax+0] ; read/write/delete/.../makedir/rename/lba/run
push dword [eax+4] ; 512 block number to read
push dword [eax+8] ; bytes to write/append or 512 blocks to read
mov ebx,[eax+12]
; add ebx,std_application_base_address
push ebx ; abs start of return/save area
 
lea esi,[eax+20] ; abs start of dir + filename
mov edi,[eax+16]
; add edi,std_application_base_address ; abs start of work area
 
call expand_pathz
 
push edi ; dir start
push ebx ; name of file start
 
mov eax,[edi+1]
cmp eax,'RD '
je fs_yesramdisk
cmp eax,'RAMD'
jne fs_noramdisk
 
fs_yesramdisk:
 
cmp byte [edi+1+11],0
je fs_give_dir1
 
mov eax,[edi+1+12]
cmp eax,'1 '
je fs_yesramdisk_first
cmp eax,'FIRS'
jne fs_noramdisk
 
fs_yesramdisk_first:
 
cmp dword [esp+20],8 ; LBA read ramdisk
jne fs_no_LBA_read_ramdisk
 
mov eax,[esp+16] ; LBA block to read
mov ecx,[esp+8] ; abs pointer to return area
 
call LBA_read_ramdisk
jmp file_system_return
 
 
fs_no_LBA_read_ramdisk:
 
cmp dword [esp+20],0 ; READ
jne fs_noramdisk_read
 
mov eax,[esp+4] ; fname
add eax,2*12+1
mov ebx,[esp+16] ; block start
inc ebx
mov ecx,[esp+12] ; block count
mov edx,[esp+8] ; return
mov esi,[esp+0]
sub esi,eax
add esi,12+1 ; file name length
call fileread
 
jmp file_system_return
 
 
fs_noramdisk_read:
fs_noramdisk:
 
;********************************************************************
mov eax,[edi+1]
cmp eax,'FD '
je fs_yesflpdisk
cmp eax,'FLOP'
jne fs_noflpdisk
 
fs_yesflpdisk:
call reserve_flp
 
cmp byte [edi+1+11],0
je fs_give_dir1
 
mov eax,[edi+1+12]
cmp eax,'1 '
je fs_yesflpdisk_first
cmp eax,'FIRS'
je fs_yesflpdisk_first
cmp eax,'2 '
je fs_yesflpdisk_second
cmp eax,'SECO'
jne fs_noflpdisk
jmp fs_yesflpdisk_second
 
fs_yesflpdisk_first:
mov [flp_number],1
jmp fs_yesflpdisk_start
fs_yesflpdisk_second:
mov [flp_number],2
fs_yesflpdisk_start:
cmp dword [esp+20],0 ; READ
jne fs_noflpdisk_read
 
mov eax,[esp+4] ; fname
add eax,2*12+1
mov ebx,[esp+16] ; block start
inc ebx
mov ecx,[esp+12] ; block count
mov edx,[esp+8] ; return
mov esi,[esp+0]
sub esi,eax
add esi,12+1 ; file name length
call floppy_fileread
 
jmp file_system_return
 
 
fs_noflpdisk_read:
fs_noflpdisk:
;*****************************************************************
 
mov eax,[edi+1]
cmp eax,'HD0 '
je fs_yesharddisk_IDE0
cmp eax,'HD1 '
je fs_yesharddisk_IDE1
cmp eax,'HD2 '
je fs_yesharddisk_IDE2
cmp eax,'HD3 '
je fs_yesharddisk_IDE3
jmp old_path_harddisk
fs_yesharddisk_IDE0:
call reserve_hd1
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE1:
call reserve_hd1
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE2:
call reserve_hd1
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
jmp fs_yesharddisk_partition
fs_yesharddisk_IDE3:
call reserve_hd1
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
fs_yesharddisk_partition:
call reserve_hd_channel
; call choice_necessity_partition
; jmp fs_yesharddisk_all
jmp fs_for_new_semantic
 
choice_necessity_partition:
mov eax,[edi+1+12]
call StringToNumber
mov [fat32part],eax
choice_necessity_partition_1:
mov ecx,[hdpos]
xor eax,eax
mov [hd_entries], eax ; entries in hd cache
mov edx,DRIVE_DATA+2
cmp ecx,0x80
jb search_partition_array
mov ecx,4
search_partition_array:
mov bl,[edx]
movzx ebx,bl
add eax,ebx
inc edx
loop search_partition_array
mov ecx,[hdpos]
mov edx,BiosDiskPartitions
sub ecx,0x80
jb .s
je .f
@@:
mov ebx,[edx]
add edx,4
add eax,ebx
loop @b
jmp .f
.s:
sub eax,ebx
.f:
add eax, [known_part] ; add eax,[fat32part]
dec eax
xor edx,edx
imul eax,100
add eax,DRIVE_DATA+0xa
mov [transfer_adress],eax
call partition_data_transfer_1
ret
 
old_path_harddisk:
mov eax,[edi+1]
cmp eax,'HD '
je fs_yesharddisk
cmp eax,'HARD'
jne fs_noharddisk
 
fs_yesharddisk:
cmp dword [esp+20],8 ; LBA read
jne fs_no_LBA_read
mov eax,[esp+16] ; LBA block to read
lea ebx,[edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH
mov ecx,[esp+8] ; abs pointer to return area
call LBA_read
jmp file_system_return
 
fs_no_LBA_read:
 
cmp byte [edi+1+11],0 ; directory read
je fs_give_dir1
call reserve_hd1
fs_for_new_semantic:
call choice_necessity_partition
 
fs_yesharddisk_all:
mov eax,1
mov ebx, [esp+24+24]
cmp [hdpos],0 ; is hd base set?
jz hd_err_return
cmp [fat32part],0 ; is partition set?
jnz @f
hd_err_return:
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
@@:
 
cmp dword [esp+20],0 ; READ
jne fs_noharddisk_read
 
mov eax,[esp+0] ; /fname
lea edi,[eax+12]
mov byte [eax],0 ; path to asciiz
inc eax ; filename start
 
mov ebx,[esp+12] ; count to read
mov ecx,[esp+8] ; buffer
mov edx,[esp+4]
add edx,12*2 ; dir start
sub edi,edx ; path length
mov esi,[esp+16] ; blocks to read
 
call file_read
 
mov edi,[esp+0]
mov byte [edi],'/'
 
call free_hd_channel
and [hd1_status], 0
jmp file_system_return
 
fs_noharddisk_read:
 
call free_hd_channel
and [hd1_status], 0
 
fs_noharddisk:
; \begin{diamond}[18.03.2006]
mov eax, 5 ; file not found
; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè?
mov ebx, [esp+24+24] ; do not change ebx in application
; \end{diamond}[18.03.2006]
 
file_system_return:
 
add esp,24
 
mov [esp+36],eax
mov [esp+24],ebx
ret
 
 
fs_give_dir1:
 
; \begin{diamond}[18.03.2006]
; /RD,/FD,/HD - only read is allowed
; other operations return "access denied", eax=10
; (execute operation returns eax=-10)
cmp dword [esp+20], 0
jz .read
add esp, 20
pop ecx
mov dword [esp+36], 10
ret
.read:
; \end{diamond}[18.03.2006]
mov al,0x10
mov ebx,1
mov edi,[esp+8]
mov esi,dir1
fs_d1_new:
mov ecx,11
; cld
rep movsb
stosb
add edi,32-11-1
dec ebx
jne fs_d1_new
 
add esp,24
 
and dword [esp+36],0 ; ok read
mov dword [esp+24],32*1 ; dir/data size
ret
 
 
 
LBA_read_ramdisk:
 
cmp [lba_read_enabled],1
je lbarrl1
 
xor ebx,ebx
mov eax,2
ret
 
lbarrl1:
 
cmp eax,18*2*80
jb lbarrl2
xor ebx,ebx
mov eax,3
ret
 
lbarrl2:
 
pushad
 
call restorefatchain
 
mov edi,ecx
mov esi,eax
 
shl esi,9
add esi,RAMDISK
mov ecx,512/4
; cld
rep movsd
 
popad
 
xor ebx,ebx
xor eax,eax
ret
 
LBA_read:
 
; IN:
;
; eax = LBA block to read
; ebx = pointer to FIRST/SECOND/THIRD/FOURTH
; ecx = abs pointer to return area
 
cmp [lba_read_enabled],1
je lbarl1
mov eax,2
ret
 
lbarl1:
 
call reserve_hd1
 
push eax
push ecx
 
mov edi,hd_address_table
mov esi,dir1
mov eax,[ebx]
mov edx,'1 '
mov ecx,4
blar0:
cmp eax,[esi]
je blar2
cmp eax,edx
je blar2
inc edx
add edi,8
add esi,11
dec ecx
jnz blar0
 
mov eax,1
mov ebx,1
jmp LBA_read_ret
 
blar2:
mov eax,[edi+0]
mov ebx,[edi+4]
 
mov [hdbase],eax
mov [hdid],ebx
 
call wait_for_hd_idle
cmp [hd_error],0
jne hd_lba_error
 
; eax = hd port
; ebx = set for primary (0x00) or slave (0x10)
 
cli
 
mov edx,eax
inc edx
xor eax,eax
out dx,al
inc edx
inc eax
out dx,al
inc edx
mov eax,[esp+4]
out dx,al
shr eax,8
inc edx
out dx,al
shr eax,8
inc edx
out dx,al
shr eax,8
inc edx
and al,1+2+4+8
add al,bl
add al,128+64+32
out dx,al
 
inc edx
mov al,20h
out dx,al
 
sti
 
call wait_for_sector_buffer
cmp [hd_error],0
jne hd_lba_error
 
cli
 
mov edi,[esp+0]
mov ecx,256
sub edx,7
cld
rep insw
 
sti
 
xor eax,eax
xor ebx,ebx
 
LBA_read_ret:
mov [hd_error],0
mov [hd1_status],0
add esp,2*4
 
ret
 
 
expand_pathz:
; IN:
; esi = asciiz path & file
; edi = buffer for path & file name
; OUT:
; edi = directory & file : / 11 + / 11 + / 11 - zero terminated
; ebx = /file name - zero terminated
; esi = pointer after source
 
push eax
push ecx
push edi ;[esp+0]
 
pathz_start:
mov byte [edi],'/'
inc edi
mov al,32
mov ecx,11
cld
rep stosb ; clear filename area
sub edi,11
mov ebx,edi ; start of dir/file name
 
pathz_new_char:
mov al,[esi]
inc esi
cmp al,0
je pathz_end
 
cmp al,'/'
jne pathz_not_path
cmp edi,ebx ; skip first '/'
jz pathz_new_char
lea edi,[ebx+11] ; start of next directory
jmp pathz_start
 
pathz_not_path:
cmp al,'.'
jne pathz_not_ext
lea edi,[ebx+8] ; start of extension
jmp pathz_new_char
 
pathz_not_ext:
cmp al,'a'
jb pathz_not_low
cmp al,'z'
ja pathz_not_low
sub al,0x20 ; char to uppercase
 
pathz_not_low:
mov [edi],al
inc edi
mov eax,[esp+0] ; start_of_dest_path
add eax,512 ; keep maximum path under 512 bytes
cmp edi,eax
jb pathz_new_char
 
pathz_end:
cmp ebx,edi ; if path end with '/'
jnz pathz_put_zero ; go back 1 level
sub ebx,12
 
pathz_put_zero:
mov byte [ebx+11],0
dec ebx ; include '/' char into file name
pop edi
pop ecx
pop eax
ret
 
;*******************************************
;* string to number
;* input eax - 4 byte string
;* output eax - number
;*******************************************
StringToNumber:
; ÏÅÐÅÂÎÄ ÑÒÐÎÊÎÂÎÃÎ ×ÈÑËÀ  ×ÈÑËÎÂÎÉ ÂÈÄ
; Âõîä:
; EDI - àäðåñ ñòðîêè ñ ÷èñëîì. Êîíåö ÷èñëà îòìå÷åí êîäîì 0Dh
; Âûõîä:
; CF - èíäèêàòîð îøèáîê:
; 0 - îøèáîê íåò;
; 1 - îøèáêà
; Åñëè CF=0, òî AX - ÷èñëî.
 
push bx
push cx
push dx
push edi
mov [partition_string],eax
mov edi,partition_string
xor cx,cx
i1:
mov al,[edi]
cmp al,32 ;13
je i_exit
; cmp al,'0'
; jb err
; cmp al,'9'
; ja err
sub al,48
shl cx,1
jc error
mov bx,cx
shl cx,1
jc error
shl cx,1
jc error
add cx,bx
jc error
cbw
add cx,ax
jc error
i3:
inc edi
jmp i1
i_exit:
mov ax,cx
clc
i4:
movzx eax,ax
pop edi
pop dx
pop cx
pop bx
ret
 
error:
stc
jmp i4
 
partition_string: dd 0
db 32
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/fs/fat12.inc
0,0 → 1,2272
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; FAT12.INC ;;
;; (C) 2005 Mario79, License: GPL ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
n_sector dd 0 ; temporary save for sector value
flp_status dd 0
clust_tmp_flp dd 0 ; used by analyze_directory and analyze_directory_to_write
path_pointer_flp dd 0
pointer_file_name_flp dd 0
save_root_flag db 0
save_flag db 0
root_read db 0 ; 0-necessary to load root, 1-not to load root
flp_fat db 0 ; 0-necessary to load fat, 1-not to load fat
flp_number db 0 ; 1- Floppy A, 2-Floppy B
old_track db 0 ; old value track
flp_label rb 15 ; Label and ID of inserted floppy disk
 
reserve_flp:
 
cli
cmp [flp_status],0
je reserve_flp_ok
 
sti
call change_task
jmp reserve_flp
 
reserve_flp_ok:
 
push eax
mov eax,[CURRENT_TASK]
shl eax,5
mov eax,[eax+CURRENT_TASK+TASKDATA.pid]
mov [flp_status],eax
pop eax
sti
ret
 
 
floppy_fileread:
;----------------------------------------------------------------
;
; fileread - sys floppy
;
; eax points to filename 11 chars - for root directory
; ebx first wanted block ; 1+ ; if 0 then set to 1
; ecx number of blocks to read ; 1+ ; if 0 then set to 1
; edx mem location to return data
; esi length of filename 12*X
; edi pointer to path /fd/1/...... - for all files in nested directories
;
; ret ebx = size or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
; 10 = access denied
;--------------------------------------------------------------
 
mov [save_flag],0
mov [path_pointer_flp],edi
test esi,esi ; return ramdisk root
jnz fr_noroot_1
cmp ebx,224/16
jbe fr_do_1
mov eax,5
xor ebx,ebx
mov [flp_status],ebx
ret
 
fr_do_1:
push ebx ecx edx
call read_flp_root
pop edx ecx ebx
cmp [FDC_Status],0
jne fdc_status_error_1
mov edi,edx
dec ebx
shl ebx,9
mov esi,FLOPPY_BUFF
add esi,ebx
shl ecx,9
cld
rep movsb
xor eax,eax
xor ebx,ebx
; mov eax,0 ; ok read
; mov ebx,0
mov [flp_status],eax
ret
fdc_status_error_1:
xor eax,eax
mov [flp_status],eax
mov eax,10
or ebx,-1
ret
 
fr_noroot_1:
sub esp,32
call expand_filename
frfloppy_1:
test ebx,ebx
jnz frfl5_1
mov ebx,1
frfl5_1:
test ecx,ecx
jnz frfl6_1
mov ecx,1
frfl6_1:
dec ebx
push eax
push eax ebx ecx edx esi edi
call read_flp_fat
cmp [FDC_Status],0
jne fdc_status_error_3_1
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
call SeekTrack
mov dh,14
l.20_1:
call ReadSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error_3_1
mov dl,16
mov edi,FDD_BUFF
inc [FDD_Sector]
l.21_1:
mov esi,eax ;Name of file we want
mov ecx,11
cld
rep cmpsb ;Found the file?
je fifound_1 ;Yes
add ecx,21
add edi, ecx ;Advance to next entry
dec dl
test dl,dl
jnz l.21_1
dec dh
test dh,dh
jnz l.20_1
fdc_status_error_3:
mov eax,5 ; file not found ?
or ebx,-1
add esp,32+28
mov [flp_status],0
ret
fdc_status_error_3_2:
cmp [FDC_Status],0
je fdc_status_error_3
fdc_status_error_3_1:
add esp,32+28
jmp fdc_status_error_1
 
fifound_1:
mov eax,[path_pointer_flp]
cmp [eax+36],byte 0
je fifound_2
add edi,0xf
mov eax,[edi]
and eax,65535
mov ebx,[path_pointer_flp]
add ebx,36
call get_cluster_of_a_path_flp
jc fdc_status_error_3_2
mov ebx,[ebx-11+28] ;file size
mov [esp+20],ebx
mov [esp+24],ebx
jmp fifound_3
fifound_2:
mov ebx,[edi-11+28] ;file size
mov [esp+20],ebx
mov [esp+24],ebx
add edi,0xf
mov eax,[edi]
fifound_3:
and eax,65535
mov [n_sector],eax ;eax=cluster
frnew_1:
add eax,31 ;bootsector+2*fat+filenames
cmp [esp+16],dword 0 ; wanted cluster ?
jne frfl7_1
call read_chs_sector
cmp [FDC_Status],0
jne fdc_status_error_5
mov edi,[esp+8]
call give_back_application_data_1
add [esp+8],dword 512
dec dword [esp+12] ; last wanted cluster ?
cmp [esp+12],dword 0
je frnoread_1
jmp frfl8_1
frfl7_1:
dec dword [esp+16]
frfl8_1:
mov edi,[n_sector]
shl edi,1 ;find next cluster from FAT
add edi,FLOPPY_FAT
mov eax,[edi]
and eax,4095
mov edi,eax
mov [n_sector],edi
cmp edi,4095 ;eof - cluster
jz frnoread2_1
cmp [esp+24],dword 512 ;eof - size
jb frnoread_1
sub [esp+24],dword 512
jmp frnew_1
 
read_chs_sector:
call calculate_chs
call ReadSectWithRetr
ret
 
frnoread2_1:
cmp [esp+16],dword 0 ; eof without read ?
je frnoread_1
mov [fdc_irq_func],fdc_null
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
mov eax,6 ; end of file
mov [flp_status],0
ret
 
frnoread_1:
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
xor eax,eax
mov [flp_status],eax
ret
 
fdc_status_error_5:
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
jmp fdc_status_error_1
 
read_flp_root:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_root_read
cmp [root_read],1
je unnecessary_root_read
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov edi,FLOPPY_BUFF
call SeekTrack
read_flp_root_1:
call ReadSectWithRetr
cmp [FDC_Status],0
jne unnecessary_root_read
push edi
call give_back_application_data_1
pop edi
add edi,512
inc [FDD_Sector]
cmp [FDD_Sector],16
jne read_flp_root_1
mov [root_read],1
unnecessary_root_read:
popa
ret
 
 
read_flp_fat:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_flp_fat
cmp [flp_fat],1
je unnecessary_flp_fat
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov edi,FLOPPY_BUFF
call SeekTrack
read_flp_fat_1:
call ReadSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat
push edi
call give_back_application_data_1
pop edi
add edi,512
inc [FDD_Sector]
cmp [FDD_Sector],19
jne read_flp_fat_1
mov [FDD_Sector],1
mov [FDD_Head],1
call ReadSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat
call give_back_application_data_1
call calculatefatchain_flp
mov [root_read],0
mov [flp_fat],1
unnecessary_flp_fat:
popa
ret
 
calculatefatchain_flp:
pushad
 
mov esi,FLOPPY_BUFF
mov edi,FLOPPY_FAT
 
fcnew_1:
mov eax,dword [esi]
mov ebx,dword [esi+4]
mov ecx,dword [esi+8]
mov edx,ecx
shr edx,4 ;8 ok
shr dx,4 ;7 ok
xor ch,ch
shld ecx,ebx,20 ;6 ok
shr cx,4 ;5 ok
shld ebx,eax,12
and ebx,0x0fffffff ;4 ok
shr bx,4 ;3 ok
shl eax,4
and eax,0x0fffffff ;2 ok
shr ax,4 ;1 ok
mov dword [edi],eax
add edi,4
mov dword [edi],ebx
add edi,4
mov dword [edi],ecx
add edi,4
mov dword [edi],edx
add edi,4
add esi,12
 
cmp edi,FLOPPY_FAT+2856*2 ;2849 clusters
jnz fcnew_1
 
popad
ret
 
check_label:
pushad
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],1 ; Ñåêòîð
call SetUserInterrupts
call FDDMotorON
call RecalibrateFDD
cmp [FDC_Status],0
jne fdc_status_error
call SeekTrack
cmp [FDC_Status],0
jne fdc_status_error
call ReadSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error
mov esi,flp_label
mov edi,FDD_BUFF+39
mov ecx,15
cld
rep cmpsb
je same_label
mov [root_read],0
mov [flp_fat],0
same_label:
mov esi,FDD_BUFF+39
mov edi,flp_label
mov ecx,15
cld
rep movsb
popad
ret
fdc_status_error:
popad
ret
 
save_flp_root:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_root_save
cmp [root_read],0
je unnecessary_root_save
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov esi,FLOPPY_BUFF
call SeekTrack
save_flp_root_1:
push esi
call take_data_from_application_1
pop esi
add esi,512
call WriteSectWithRetr
cmp [FDC_Status],0
jne unnecessary_root_save
inc [FDD_Sector]
cmp [FDD_Sector],16
jne save_flp_root_1
unnecessary_root_save:
mov [fdc_irq_func],fdc_null
popa
ret
 
save_flp_fat:
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_flp_fat_save
cmp [flp_fat],0
je unnecessary_flp_fat_save
call restorefatchain_flp
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
mov esi,FLOPPY_BUFF
call SeekTrack
save_flp_fat_1:
push esi
call take_data_from_application_1
pop esi
add esi,512
call WriteSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat_save
inc [FDD_Sector]
cmp [FDD_Sector],19
jne save_flp_fat_1
mov [FDD_Sector],1
mov [FDD_Head],1
call take_data_from_application_1
call WriteSectWithRetr
cmp [FDC_Status],0
jne unnecessary_flp_fat_save
mov [root_read],0
unnecessary_flp_fat_save:
mov [fdc_irq_func],fdc_null
popa
ret
 
 
restorefatchain_flp: ; restore fat chain
pushad
 
mov esi,FLOPPY_FAT
mov edi,FLOPPY_BUFF
 
fcnew2_1:
mov eax,dword [esi]
mov ebx,dword [esi+4]
shl ax,4
shl eax,4
shl bx,4
shr ebx,4
shrd eax,ebx,8
shr ebx,8
mov dword [edi],eax
add edi,4
mov word [edi],bx
add edi,2
add esi,8
 
cmp edi,FLOPPY_BUFF+0x1200 ;4274 bytes - all used FAT
jb fcnew2_1
 
mov esi,FLOPPY_BUFF ; duplicate fat chain
mov edi,FLOPPY_BUFF+0x1200
mov ecx,0x1200/4
cld
rep movsd
 
popad
ret
 
 
save_chs_sector:
call calculate_chs
call WriteSectWithRetr
ret
 
calculate_chs:
mov bl,[FDD_Track]
mov [old_track],bl
mov ebx,18
xor edx,edx
div ebx
inc edx
mov [FDD_Sector],dl
xor edx,edx
mov ebx,2
div ebx
mov [FDD_Track],al
mov [FDD_Head],0
test edx,edx
jz no_head_2
inc [FDD_Head]
no_head_2:
mov dl,[old_track]
cmp dl,[FDD_Track]
je no_seek_track_1
call SeekTrack
no_seek_track_1:
ret
 
 
get_cluster_of_a_path_flp:
;---------------------------------------------------------
; input : EBX = pointer to a path string
; (example: the path "/files/data/document" become
; "files......data.......document...0"
; '.' = space char
; '0' = char(0) (ASCII=0) !!! )
; output : if (CARRY=1) -> ERROR in the PATH
; if (CARRY=0) -> EAX=cluster
;---------------------------------------------------------
 
push edx
mov edx,ebx
 
search_end_of_path_flp:
cmp [save_flag],0
jne search_end_of_path_flp_1
cmp byte [edx],0
je found_end_of_path_flp
jmp search_end_of_path_flp_2
search_end_of_path_flp_1:
cmp byte [edx+12],0
je found_end_of_path_flp
search_end_of_path_flp_2:
inc edx ; '/'
call analyze_directory_flp
jc directory_not_found_flp
 
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field
mov ax,[ebx+26] ; read the LOW 16bit cluster field
and eax,0xfff ;[fatMASK]
add edx,11 ; 8+3 (name+extension)
jmp search_end_of_path_flp
 
found_end_of_path_flp:
inc edx
mov [pointer_file_name_flp],edx
pop edx
clc ; no errors
ret
 
directory_not_found_flp:
pop edx
stc ; errors occour
ret
 
analyze_directory_flp:
;--------------------------------
; input : EAX = first cluster of the directory
; EBX = pointer to filename
; output : IF CARRY=0 EAX = sector where th file is found
; EBX = pointer in buffer
; [buffer .. buffer+511]
; ECX,EDX,EDI,EDI not changed
; IF CARRY=1
;--------------------------------
push ebx ;[esp+16]
push ecx
push edx
push esi
push edi
 
 
adr56_flp:
mov [clust_tmp_flp],eax
add eax,31
pusha
call read_chs_sector
popa
cmp [FDC_Status],0
jne not_found_file_analyze_flp
 
mov ecx,512/32
mov ebx,FDD_BUFF
 
adr1_analyze_flp:
mov esi,edx ;[esp+16]
mov edi,ebx
cld
push ecx
mov ecx,11
rep cmpsb
pop ecx
je found_file_analyze_flp
 
add ebx,32
loop adr1_analyze_flp
 
mov eax,[clust_tmp_flp]
shl eax,1 ;find next cluster from FAT
add eax,FLOPPY_FAT
mov eax,[eax]
and eax,4095
cmp eax,0x0ff8
jb adr56_flp
not_found_file_analyze_flp:
pop edi
pop esi
pop edx
pop ecx
add esp,4
stc ;file not found
ret
 
found_file_analyze_flp:
pop edi
pop esi
pop edx
pop ecx
add esp,4
clc ;file found
ret
 
 
; \begin{diamond}
fat_find_lfn:
; in: esi->name
; [esp+4] = next
; [esp+8] = first
; [esp+C]... - possibly parameters for first and next
; out: CF=1 - file not found
; else CF=0, esi->next name component, edi->direntry
pusha
lea eax, [esp+0Ch+20h]
call dword [eax-4]
jc .reterr
sub esp, 262*2 ; reserve place for LFN
mov ebp, esp
push 0 ; for fat_get_name: read ASCII name
.l1:
call fat_get_name
jc .l2
call fat_compare_name
jz .found
.l2:
lea eax, [esp+0Ch+20h+262*2+4]
call dword [eax-8]
jnc .l1
add esp, 262*2+4
.reterr:
stc
popa
ret
.found:
add esp, 262*2+4
; if this is LFN entry, advance to true entry
cmp byte [edi+11], 0xF
jnz @f
lea eax, [esp+0Ch+20h]
call dword [eax-8]
jc .reterr
@@:
add esp, 8 ; CF=0
push esi
push edi
popa
ret
 
uglobal
; this is for delete support
fd_prev_sector dd ?
fd_prev_prev_sector dd ?
endg
 
flp_root_next:
cmp edi, OS_BASE+0xD200-0x20
jae @f
add edi, 0x20
ret ; CF=0
@@:
; read next sector
inc dword [eax]
cmp dword [eax], 14
jae flp_root_first.readerr
push [fd_prev_sector]
pop [fd_prev_prev_sector]
push eax
mov eax, [eax]
add eax, 19-1
mov [fd_prev_sector], eax
pop eax
flp_root_first:
mov eax, [eax]
pusha
add eax, 19
call read_chs_sector
popa
cmp [FDC_Status], 0
jnz .readerr
mov edi, FDD_BUFF
ret ; CF=0
.readerr:
stc
ret
 
flp_rootmem_first:
mov edi, FLOPPY_BUFF
clc
ret
flp_rootmem_next:
add edi, 0x20
cmp edi, FLOPPY_BUFF+14*0x200
cmc
flp_rootmem_next_write:
flp_rootmem_begin_write:
flp_rootmem_end_write:
ret
flp_rootmem_extend_dir:
stc
ret
 
flp_notroot_next:
cmp edi, OS_BASE+0xD200-0x20
jae flp_notroot_next_sector
add edi, 0x20
ret ; CF=0
flp_notroot_next_sector:
push ecx
mov ecx, [eax]
push [fd_prev_sector]
pop [fd_prev_prev_sector]
add ecx, 31
mov [fd_prev_sector], ecx
mov ecx, [(ecx-31)*2+FLOPPY_FAT]
and ecx, 0xFFF
cmp ecx, 2849
jae flp_notroot_first.err2
mov [eax], ecx
pop ecx
flp_notroot_first:
mov eax, [eax]
cmp eax, 2
jb .err
cmp eax, 2849
jae .err
pusha
add eax, 31
call read_chs_sector
popa
mov edi, FDD_BUFF
cmp [FDC_Status], 0
jnz .err
ret ; CF=0
.err2:
pop ecx
.err:
stc
ret
flp_notroot_begin_write:
pusha
mov eax, [eax]
add eax, 31
call read_chs_sector
popa
ret
flp_notroot_end_write:
pusha
mov eax, [eax]
add eax, 31
call save_chs_sector
popa
ret
flp_notroot_next_write:
cmp edi, OS_BASE+0xD200
jae @f
ret
@@:
call flp_notroot_end_write
jmp flp_notroot_next_sector
flp_notroot_extend_dir:
; find free cluster in FAT
pusha
xor eax, eax
mov edi, FLOPPY_FAT
mov ecx, 2849
repnz scasw
jnz .notfound
mov word [edi-2], 0xFFF ; mark as last cluster
sub edi, FLOPPY_FAT
shr edi, 1
dec edi
mov eax, [esp+28]
mov ecx, [eax]
mov [FLOPPY_FAT+ecx*2], di
mov [eax], edi
xor eax, eax
mov edi, FDD_BUFF
mov ecx, 128
rep stosd
popa
call flp_notroot_end_write
mov edi, FDD_BUFF
clc
ret
.notfound:
popa
stc
ret
 
fd_find_lfn:
; in: esi+ebp -> name
; out: CF=1 - file not found
; else CF=0 and edi->direntry, eax=directory cluster (0 for root)
push esi edi
push 0
push flp_root_first
push flp_root_next
.loop:
call fat_find_lfn
jc .notfound
cmp byte [esi], 0
jz .found
.continue:
test byte [edi+11], 10h
jz .notfound
movzx eax, word [edi+26] ; cluster
mov [esp+8], eax
mov dword [esp+4], flp_notroot_first
mov dword [esp], flp_notroot_next
jmp .loop
.notfound:
add esp, 12
pop edi esi
stc
ret
.found:
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .continue
@@:
mov eax, [esp+8]
add eax, 31
cmp dword [esp], flp_root_next
jnz @f
add eax, -31+19
@@:
add esp, 16 ; CF=0
pop esi
ret
 
;----------------------------------------------------------------
;
; fs_FloppyRead - LFN variant for reading floppy
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_FloppyRead:
call read_flp_fat
cmp byte [esi], 0
jnz @f
or ebx, -1
mov eax, 10 ; access denied
ret
@@:
push edi
call fd_find_lfn
jnc .found
pop edi
or ebx, -1
mov eax, 5 ; file not found
ret
.found:
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
.reteof:
mov eax, 6 ; EOF
pop edi
ret
@@:
mov ebx, [ebx]
.l1:
push ecx edx
push 0
mov eax, [edi+28]
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6 ; EOF
@@:
movzx edi, word [edi+26]
.new:
jecxz .done
test edi, edi
jz .eof
cmp edi, 0xFF8
jae .eof
sub ebx, 512
jae .skip
lea eax, [edi+31]
pusha
call read_chs_sector
popa
cmp [FDC_Status], 0
jnz .err
lea eax, [FDD_BUFF+ebx+512]
neg ebx
push ecx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
mov ebx, edx
call memmove
add edx, ecx
sub [esp], ecx
pop ecx
xor ebx, ebx
.skip:
movzx edi, word [edi*2+FLOPPY_FAT]
jmp .new
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
.eof:
mov ebx, edx
pop eax edx ecx
jmp .reteof
.err:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
mov al, 11
ret
 
;----------------------------------------------------------------
;
; fs_FloppyReadFolder - LFN variant for reading floppy folders
;
; esi points to filename
; ebx pointer to structure: 32-bit number = first wanted block, 0+
; & flags (bitfields)
; flags: bit 0: 0=ANSI names, 1=UNICODE names
; ecx number of blocks to read, 0+
; edx mem location to return data
;
; ret ebx = blocks read or 0xffffffff folder not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_FloppyReadFolder:
call read_flp_fat
push edi
cmp byte [esi], 0
jz .root
call fd_find_lfn
jnc .found
pop edi
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.found:
test byte [edi+11], 0x10 ; do not allow read files
jnz .found_dir
pop edi
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
.found_dir:
movzx eax, word [edi+26]
add eax, 31
push 0
jmp .doit
.root:
mov eax, 19
push 14
.doit:
push ecx ebp
sub esp, 262*2 ; reserve space for LFN
mov ebp, esp
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names
mov ebx, [ebx]
; init header
push eax ecx
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
pop ecx eax
mov byte [edx], 1 ; version
mov esi, edi ; esi points to BDFE
.main_loop:
pusha
call read_chs_sector
popa
cmp [FDC_Status], 0
jnz .error
mov edi, FDD_BUFF
push eax
.l1:
call fat_get_name
jc .l2
cmp byte [edi+11], 0xF
jnz .do_bdfe
add edi, 0x20
cmp edi, OS_BASE+0xD200
jb .do_bdfe
pop eax
inc eax
dec byte [esp+262*2+12]
jz .done
jns @f
; read next sector from FAT
mov eax, [(eax-31-1)*2+FLOPPY_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
jae .done
add eax, 31
mov byte [esp+262*2+12], 0
@@:
pusha
call read_chs_sector
popa
cmp [FDC_Status], 0
jnz .error
mov edi, FDD_BUFF
push eax
.do_bdfe:
inc dword [edx+8] ; new file found
dec ebx
jns .l2
dec ecx
js .l2
inc dword [edx+4] ; new file block copied
call fat_entry_to_bdfe
.l2:
add edi, 0x20
cmp edi, OS_BASE+0xD200
jb .l1
pop eax
inc eax
dec byte [esp+262*2+12]
jz .done
jns @f
; read next sector from FAT
mov eax, [(eax-31-1)*2+FLOPPY_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
jae .done
add eax, 31
mov byte [esp+262*2+12], 0
@@:
jmp .main_loop
.error:
add esp, 262*2+4
pop ebp ecx edi edi
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.done:
add esp, 262*2+4
pop ebp
mov ebx, [edx+4]
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
@@:
pop ecx edi edi
ret
 
;----------------------------------------------------------------
;
; fs_FloppyRewrite - LFN variant for writing sys floppy
;
; esi points to filename
; ebx ignored (reserved)
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = number of written bytes
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
@@:
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
fsfrfe2:
popad
fsfrfe:
mov eax, 11
xor ebx, ebx
ret
 
fs_FloppyCreateFolder:
mov al, 1
jmp fs_FloppyRewrite.common
 
fs_FloppyRewrite:
xor eax, eax
.common:
cmp byte [esi], 0
jz @b
call read_flp_fat
cmp [FDC_Status], 0
jnz fsfrfe
pushad
xor edi, edi
push esi
test ebp, ebp
jz @f
mov esi, ebp
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
lea edi, [esi-1]
jmp @b
@@:
pop esi
test edi, edi
jnz .noroot
test ebp, ebp
jnz .hasebp
call read_flp_root
cmp [FDC_Status], 0
jnz fsfrfe2
push flp_rootmem_extend_dir
push flp_rootmem_end_write
push flp_rootmem_next_write
push flp_rootmem_begin_write
xor ebp, ebp
push ebp
push flp_rootmem_first
push flp_rootmem_next
jmp .common1
.hasebp:
mov eax, ERROR_ACCESS_DENIED
cmp byte [ebp], 0
jz .ret1
push ebp
xor ebp, ebp
call fd_find_lfn
pop esi
jc .notfound0
jmp .common0
.noroot:
mov eax, ERROR_ACCESS_DENIED
cmp byte [edi+1], 0
jz .ret1
; check existence
mov byte [edi], 0
push edi
call fd_find_lfn
pop esi
mov byte [esi], '/'
jnc @f
.notfound0:
mov eax, ERROR_FILE_NOT_FOUND
.ret1:
mov [esp+28], eax
popad
xor ebx, ebx
ret
@@:
inc esi
.common0:
test byte [edi+11], 0x10 ; must be directory
mov eax, ERROR_ACCESS_DENIED
jz .ret1
movzx ebp, word [edi+26] ; ebp=cluster
mov eax, ERROR_FAT_TABLE
cmp ebp, 2
jb .ret1
cmp ebp, 2849
jae .ret1
push flp_notroot_extend_dir
push flp_notroot_end_write
push flp_notroot_next_write
push flp_notroot_begin_write
push ebp
push flp_notroot_first
push flp_notroot_next
.common1:
call fat_find_lfn
jc .notfound
; found
test byte [edi+11], 10h
jz .exists_file
; found directory; if we are creating directory, return OK,
; if we are creating file, say "access denied"
add esp, 28
popad
test al, al
mov eax, ERROR_ACCESS_DENIED
jz @f
mov al, 0
@@:
xor ebx, ebx
ret
.exists_file:
; found file; if we are creating directory, return "access denied",
; if we are creating file, delete existing file and continue
cmp byte [esp+28+28], 0
jz @f
add esp, 28
popad
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
@@:
; delete FAT chain
push edi
xor eax, eax
mov dword [edi+28], eax ; zero size
xchg ax, word [edi+26] ; start cluster
test eax, eax
jz .done1
@@:
cmp eax, 0xFF8
jae .done1
lea edi, [FLOPPY_FAT + eax*2] ; position in FAT
xor eax, eax
xchg ax, [edi]
jmp @b
.done1:
pop edi
call get_time_for_file
mov [edi+22], ax
call get_date_for_file
mov [edi+24], ax
mov [edi+18], ax
or byte [edi+11], 20h ; set 'archive' attribute
jmp .doit
.notfound:
; file is not found; generate short name
call fat_name_is_legal
jc @f
add esp, 28
popad
mov eax, ERROR_FILE_NOT_FOUND
xor ebx, ebx
ret
@@:
sub esp, 12
mov edi, esp
call fat_gen_short_name
.test_short_name_loop:
push esi edi ecx
mov esi, edi
lea eax, [esp+12+12+8]
mov [eax], ebp
call dword [eax-4]
jc .found
.test_short_name_entry:
cmp byte [edi+11], 0xF
jz .test_short_name_cont
mov ecx, 11
push esi edi
repz cmpsb
pop edi esi
jz .short_name_found
.test_short_name_cont:
lea eax, [esp+12+12+8]
call dword [eax-8]
jnc .test_short_name_entry
jmp .found
.short_name_found:
pop ecx edi esi
call fat_next_short_name
jnc .test_short_name_loop
.disk_full:
add esp, 12+28
popa
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.found:
pop ecx edi esi
; now find space in directory
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
mov al, '~'
push ecx edi
mov ecx, 8
repnz scasb
push 1
pop eax ; 1 entry
jnz .notilde
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
xor eax, eax
@@:
cmp byte [esi], 0
jz @f
inc esi
inc eax
jmp @b
@@:
sub esi, eax
add eax, 12+13
mov ecx, 13
push edx
cdq
div ecx
pop edx
.notilde:
push -1
push -1
; find <eax> successive entries in directory
xor ecx, ecx
push eax
lea eax, [esp+12+8+12+8]
mov [eax], ebp
call dword [eax-4]
pop eax
jnc .scan_dir
.fsfrfe3:
add esp, 8+8+12+28
popad
mov eax, 11
xor ebx, ebx
ret
.scan_dir:
cmp byte [edi], 0
jz .free
cmp byte [edi], 0xE5
jz .free
xor ecx, ecx
.scan_cont:
push eax
lea eax, [esp+12+8+12+8]
call dword [eax-8]
pop eax
jnc .scan_dir
cmp [FDC_Status], 0
jnz .fsfrfe3
push eax
lea eax, [esp+12+8+12+8]
call dword [eax+16] ; extend directory
pop eax
jnc .scan_dir
add esp, 8+8+12+28
popad
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.free:
test ecx, ecx
jnz @f
mov [esp], edi
mov ecx, [esp+8+8+12+8]
mov [esp+4], ecx
xor ecx, ecx
@@:
inc ecx
cmp ecx, eax
jb .scan_cont
; found!
; calculate name checksum
push esi ecx
mov esi, [esp+8+8]
mov ecx, 11
xor eax, eax
@@:
ror al, 1
add al, [esi]
inc esi
loop @b
pop ecx esi
pop edi
pop dword [esp+8+12+8]
; edi points to first entry in free chunk
dec ecx
jz .nolfn
push esi
push eax
lea eax, [esp+8+8+12+8]
call dword [eax+4] ; begin write
mov al, 40h
.writelfn:
or al, cl
mov esi, [esp+4]
push ecx
dec ecx
imul ecx, 13
add esi, ecx
stosb
mov cl, 5
call fs_RamdiskRewrite.read_symbols
mov ax, 0xF
stosw
mov al, [esp+4]
stosb
mov cl, 6
call fs_RamdiskRewrite.read_symbols
xor eax, eax
stosw
mov cl, 2
call fs_RamdiskRewrite.read_symbols
pop ecx
lea eax, [esp+8+8+12+8]
call dword [eax+8] ; next write
xor eax, eax
loop .writelfn
pop eax
pop esi
; lea eax, [esp+8+12+8]
; call dword [eax+12] ; end write
.nolfn:
xchg esi, [esp]
mov ecx, 11
rep movsb
mov word [edi], 20h ; attributes
sub edi, 11
pop esi ecx
add esp, 12
mov byte [edi+13], 0 ; tenths of a second at file creation time
call get_time_for_file
mov [edi+14], ax ; creation time
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+16], ax ; creation date
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
and word [edi+20], 0 ; high word of cluster
and word [edi+26], 0 ; low word of cluster - to be filled
and dword [edi+28], 0 ; file size - to be filled
cmp byte [esp+28+28], 0
jz .doit
; create directory
mov byte [edi+11], 10h ; attributes: folder
mov ecx, 32*2
mov edx, edi
.doit:
lea eax, [esp+8]
call dword [eax+12] ; flush directory
push ecx
push edi
push 0
mov esi, edx
test ecx, ecx
jz .done
mov ecx, 2849
mov edi, FLOPPY_FAT
push 0 ; first cluster
.write_loop:
; allocate new cluster
xor eax, eax
repnz scasw
mov al, ERROR_DISK_FULL
jnz .ret
dec edi
dec edi
 
mov eax, edi
sub eax, FLOPPY_FAT
 
shr eax, 1 ; eax = cluster
mov word [edi], 0xFFF ; mark as last cluster
xchg edi, [esp+4]
cmp dword [esp], 0
jz .first
stosw
jmp @f
.first:
mov [esp], eax
@@:
mov edi, [esp+4]
inc ecx
; write data
push ecx edi
mov ecx, 512
cmp dword [esp+20], ecx
jae @f
mov ecx, [esp+20]
@@:
mov edi, FDD_BUFF
cmp byte [esp+24+28+28], 0
jnz .writedir
push ecx
rep movsb
pop ecx
.writedircont:
push ecx
sub ecx, 512
neg ecx
push eax
xor eax, eax
rep stosb
pop eax
add eax, 31
pusha
call save_chs_sector
popa
pop ecx
cmp [FDC_Status], 0
jnz .diskerr
sub [esp+20], ecx
pop edi ecx
jnz .write_loop
.done:
xor eax, eax
.ret:
pop ebx edi edi ecx
mov [esp+28+28], eax
lea eax, [esp+8]
call dword [eax+4]
mov [edi+26], bx
mov ebx, esi
sub ebx, edx
mov [edi+28], ebx
call dword [eax+12]
mov [esp+28+16], ebx
test ebp, ebp
jnz @f
call save_flp_root
@@:
add esp, 28
cmp [FDC_Status], 0
jnz .err3
call save_flp_fat
cmp [FDC_Status], 0
jnz .err3
popa
ret
.err3:
popa
mov al, 11
xor ebx, ebx
ret
.diskerr:
sub esi, ecx
mov eax, 11
pop edi ecx
jmp .ret
.writedir:
push ecx
mov ecx, 32/4
push ecx esi
rep movsd
pop esi ecx
mov dword [edi-32], '. '
mov dword [edi-32+4], ' '
mov dword [edi-32+8], ' '
mov byte [edi-32+11], 10h
mov word [edi-32+26], ax
push esi
rep movsd
pop esi
mov dword [edi-32], '.. '
mov dword [edi-32+4], ' '
mov dword [edi-32+8], ' '
mov byte [edi-32+11], 10h
mov ecx, [esp+28+8]
mov word [edi-32+26], cx
pop ecx
jmp .writedircont
 
;----------------------------------------------------------------
;
; fs_FloppyWrite - LFN variant for writing to floppy
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = bytes written (maybe 0)
; eax = 0 ok write or other = errormsg
;
;--------------------------------------------------------------
 
@@:
push ERROR_ACCESS_DENIED
fs_FloppyWrite.ret0:
pop eax
xor ebx, ebx
ret
 
fs_FloppyWrite.ret11:
push 11
jmp fs_FloppyWrite.ret0
 
fs_FloppyWrite:
cmp byte [esi], 0
jz @b
call read_flp_fat
cmp [FDC_Status], 0
jnz .ret11
pushad
call fd_find_lfn
jnc .found
popad
push ERROR_FILE_NOT_FOUND
jmp .ret0
.found:
; FAT does not support files larger than 4GB
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
.eof:
popad
push ERROR_END_OF_FILE
jmp .ret0
@@:
mov ebx, [ebx]
.l1:
; now edi points to direntry, ebx=start byte to write,
; ecx=number of bytes to write, edx=data pointer
 
; extend file if needed
add ecx, ebx
jc .eof ; FAT does not support files larger than 4GB
push eax ; save directory cluster
push 0 ; return value=0
 
call get_time_for_file
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
 
push dword [edi+28] ; save current file size
cmp ecx, [edi+28]
jbe .length_ok
cmp ecx, ebx
jz .length_ok
call floppy_extend_file
jnc .length_ok
mov [esp+4], eax
; floppy_extend_file can return two error codes: FAT table error or disk full.
; First case is fatal error, in second case we may write some data
cmp al, ERROR_DISK_FULL
jz .disk_full
pop eax
pop eax
mov [esp+4+28], eax
pop eax
popad
xor ebx, ebx
ret
.disk_full:
; correct number of bytes to write
mov ecx, [edi+28]
cmp ecx, ebx
ja .length_ok
.ret:
pop eax
pop eax
mov [esp+4+28], eax ; eax=return value
pop eax
sub edx, [esp+20]
mov [esp+16], edx ; ebx=number of written bytes
popad
ret
.length_ok:
; save FAT & directory
; note that directory must be saved first because save_flp_fat uses buffer at 0xD000
mov esi, [edi+28]
movzx edi, word [edi+26] ; starting cluster
mov eax, [esp+8]
pusha
call save_chs_sector
popa
cmp [FDC_Status], 0
jnz .device_err
call save_flp_fat
cmp [FDC_Status], 0
jz @f
.device_err:
mov byte [esp+4], 11
jmp .ret
@@:
 
; now ebx=start pos, ecx=end pos, both lie inside file
sub ecx, ebx
jz .ret
call SetUserInterrupts
.write_loop:
; skip unmodified sectors
cmp dword [esp], 0x200
jb .modify
sub ebx, 0x200
jae .skip
add ebx, 0x200
.modify:
lea eax, [edi+31] ; current sector
; get length of data in current sector
push ecx
sub ebx, 0x200
jb .hasdata
neg ebx
xor ecx, ecx
jmp @f
.hasdata:
neg ebx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
; load sector if needed
cmp dword [esp+4], 0 ; we don't need to read uninitialized data
jz .noread
cmp ecx, 0x200 ; we don't need to read sector if it is fully rewritten
jz .noread
cmp ecx, esi ; (same for the last sector)
jz .noread
pusha
call read_chs_sector
popa
cmp [FDC_Status], 0
jz @f
.device_err2:
pop ecx
jmp .device_err
@@:
.noread:
; zero uninitialized data if file was extended (because floppy_extend_file does not this)
push eax ecx edi
xor eax, eax
mov ecx, 0x200
sub ecx, [esp+4+12]
jbe @f
mov edi, FDD_BUFF
add edi, [esp+4+12]
rep stosb
@@:
; zero uninitialized data in the last sector
mov ecx, 0x200
sub ecx, esi
jbe @f
mov edi, FDD_BUFF
add edi, esi
rep stosb
@@:
pop edi ecx eax
; copy new data
push eax
mov eax, edx
neg ebx
jecxz @f
add ebx, FDD_BUFF+0x200
call memmove
xor ebx, ebx
@@:
pop eax
; save sector
pusha
call save_chs_sector
popa
cmp [FDC_Status], 0
jnz .device_err2
add edx, ecx
sub [esp], ecx
pop ecx
jz .done
.skip:
.next_cluster:
movzx edi, word [edi*2+FLOPPY_FAT]
sub esi, 0x200
jae @f
xor esi, esi
@@:
sub dword [esp], 0x200
jae .write_loop
and dword [esp], 0
jmp .write_loop
.done:
mov [fdc_irq_func], fdc_null
jmp .ret
 
floppy_extend_file.zero_size:
xor eax, eax
jmp floppy_extend_file.start_extend
 
; extends file on floppy to given size (new data area is undefined)
; in: edi->direntry, ecx=new size
; out: CF=0 => OK, eax=0
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL)
floppy_extend_file:
push ecx
; find the last cluster of file
movzx eax, word [edi+26] ; first cluster
mov ecx, [edi+28]
jecxz .zero_size
@@:
sub ecx, 0x200
jbe @f
mov eax, [eax*2+FLOPPY_FAT]
and eax, 0xFFF
jz .fat_err
cmp eax, 0xFF8
jb @b
.fat_err:
pop ecx
push ERROR_FAT_TABLE
pop eax
stc
ret
@@:
push eax
mov eax, [eax*2+FLOPPY_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
pop eax
jb .fat_err
; set length to full number of sectors
sub [edi+28], ecx
.start_extend:
pop ecx
; now do extend
push edx esi
mov esi, FLOPPY_FAT+2*2 ; start scan from cluster 2
mov edx, 2847 ; number of clusters to scan
.extend_loop:
cmp [edi+28], ecx
jae .extend_done
; add new sector
push ecx
push edi
.scan:
mov ecx, edx
mov edi, esi
jecxz .disk_full
push eax
xor eax, eax
repnz scasw
pop eax
jnz .disk_full
mov word [edi-2], 0xFFF
mov esi, edi
mov edx, ecx
sub edi, FLOPPY_FAT
shr edi, 1
dec edi ; now edi=new cluster
test eax, eax
jz .first_cluster
mov [FLOPPY_FAT+eax*2], di
jmp @f
.first_cluster:
pop eax ; eax->direntry
push eax
mov [eax+26], di
@@:
mov eax, edi ; eax=new cluster
pop edi ; edi->direntry
pop ecx ; ecx=required size
add dword [edi+28], 0x200
jmp .extend_loop
.extend_done:
mov [edi+28], ecx
pop esi edx
xor eax, eax ; CF=0
ret
.disk_full:
pop edi ecx
pop esi edx
stc
push ERROR_DISK_FULL
pop eax
ret
 
;----------------------------------------------------------------
;
; fs_FloppySetFileEnd - set end of file on floppy
;
; esi points to filename
; ebx points to 64-bit number = new file size
; ecx ignored (reserved)
; edx ignored (reserved)
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_FloppySetFileEnd:
call read_flp_fat
cmp [FDC_Status], 0
jnz ret11
cmp byte [esi], 0
jnz @f
.access_denied:
push ERROR_ACCESS_DENIED
jmp .ret
@@:
push edi
call fd_find_lfn
jnc @f
pop edi
push ERROR_FILE_NOT_FOUND
.ret:
pop eax
jmp .doret
@@:
; must not be directory
test byte [edi+11], 10h
jz @f
pop edi
jmp .access_denied
@@:
; file size must not exceed 4 Gb
cmp dword [ebx+4], 0
jz @f
pop edi
push ERROR_END_OF_FILE
jmp .ret
@@:
push eax
; set file modification date/time to current
call fat_update_datetime
mov eax, [ebx]
cmp eax, [edi+28]
jb .truncate
ja .expand
pop eax
pushad
call save_chs_sector
popad
pop edi
xor eax, eax
cmp [FDC_Status], 0
jz @f
mov al, 11
@@:
.doret:
mov [fdc_irq_func], fdc_null
ret
.expand:
push ecx
push dword [edi+28] ; save old size
mov ecx, eax
call floppy_extend_file
push eax ; return code
jnc .expand_ok
cmp al, ERROR_DISK_FULL
jz .disk_full
pop eax ecx ecx edi edi
jmp .doret
.device_err:
pop eax
.device_err2:
pop ecx ecx eax edi
push 11
jmp .ret
.disk_full:
.expand_ok:
; save directory & FAT
mov eax, [edi+28]
xchg eax, [esp+12]
movzx edi, word [edi+26]
pusha
call save_chs_sector
popa
cmp [FDC_Status], 0
jnz .device_err
call save_flp_fat
cmp [FDC_Status], 0
jnz .device_err
call SetUserInterrupts
; now zero new data
; edi = current cluster, [esp+12]=new size, [esp+4]=old size, [esp]=return code
.zero_loop:
sub dword [esp+4], 0x200
jae .next_cluster
cmp dword [esp+4], -0x200
jz .noread
lea eax, [edi+31]
pusha
call read_chs_sector
popa
cmp [FDC_Status], 0
jnz .err_next
.noread:
mov ecx, [esp+4]
neg ecx
push edi
mov edi, FDD_BUFF+0x200
add edi, [esp+8]
xor eax, eax
mov [esp+8], eax
rep stosb
pop edi
lea eax, [edi+31]
pusha
call save_chs_sector
popa
cmp [FDC_Status], 0
jz .next_cluster
.err_next:
mov byte [esp], 11
.next_cluster:
sub dword [esp+12], 0x200
jbe .expand_done
movzx edi, word [FLOPPY_FAT+edi*2]
jmp .zero_loop
.expand_done:
pop eax ecx ecx edi edi
jmp .doret
.truncate:
mov [edi+28], eax
push ecx
movzx ecx, word [edi+26]
test eax, eax
jz .zero_size
; find new last sector
@@:
sub eax, 0x200
jbe @f
movzx ecx, word [FLOPPY_FAT+ecx*2]
jmp @b
@@:
; we will zero data at the end of last sector - remember it
push ecx
; terminate FAT chain
lea ecx, [FLOPPY_FAT+ecx+ecx]
push dword [ecx]
mov word [ecx], 0xFFF
pop ecx
and ecx, 0xFFF
jmp .delete
.zero_size:
and word [edi+26], 0
push 0
.delete:
; delete FAT chain starting with ecx
; mark all clusters as free
cmp ecx, 0xFF8
jae .deleted
lea ecx, [FLOPPY_FAT+ecx+ecx]
push dword [ecx]
and word [ecx], 0
pop ecx
and ecx, 0xFFF
jmp .delete
.deleted:
mov edi, [edi+28]
; save directory & FAT
mov eax, [esp+8]
pusha
call save_chs_sector
popa
cmp [FDC_Status], 0
jnz .device_err2
call save_flp_fat
cmp [FDC_Status], 0
jnz .device_err2
; zero last sector, ignore errors
pop eax
add eax, 31
and edi, 0x1FF
jz .truncate_done
call SetUserInterrupts
pusha
call read_chs_sector
popa
add edi, FDD_BUFF
mov ecx, FDD_BUFF+0x200
sub ecx, edi
push eax
xor eax, eax
rep stosb
pop eax
pusha
call save_chs_sector
popa
.truncate_done:
pop ecx eax edi
xor eax, eax
jmp .doret
 
fs_FloppyGetFileInfo:
call read_flp_fat
cmp [FDC_Status], 0
jnz ret11
cmp byte [esi], 0
jnz @f
mov eax, 2 ; unsupported
ret
@@:
push edi
call fd_find_lfn
jmp fs_GetFileInfo_finish
 
ret11:
mov eax, 11
ret
 
fs_FloppySetFileInfo:
call read_flp_fat
cmp [FDC_Status], 0
jnz ret11
cmp byte [esi], 0
jnz @f
mov eax, 2 ; unsupported
ret
@@:
push edi
call fd_find_lfn
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
@@:
push eax
call bdfe_to_fat_entry
pop eax
pusha
call save_chs_sector
popa
pop edi
xor eax, eax
cmp [FDC_Status], al
jz @f
mov al, 11
@@:
ret
 
;----------------------------------------------------------------
;
; fs_FloppyDelete - delete file or empty folder from floppy
;
; esi points to filename
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_FloppyDelete:
call read_flp_fat
cmp [FDC_Status], 0
jz @f
push 11
jmp .pop_ret
@@:
cmp byte [esi], 0
jnz @f
; cannot delete root!
.access_denied:
push ERROR_ACCESS_DENIED
.pop_ret:
pop eax
ret
@@:
and [fd_prev_sector], 0
and [fd_prev_prev_sector], 0
push edi
call fd_find_lfn
jnc .found
pop edi
push ERROR_FILE_NOT_FOUND
jmp .pop_ret
.found:
cmp dword [edi], '. '
jz .access_denied2
cmp dword [edi], '.. '
jz .access_denied2
test byte [edi+11], 10h
jz .dodel
; we can delete only empty folders!
push eax
movzx eax, word [edi+26]
push ebx
pusha
add eax, 31
call read_chs_sector
popa
mov ebx, FDD_BUFF + 2*0x20
.checkempty:
cmp byte [ebx], 0
jz .empty
cmp byte [ebx], 0xE5
jnz .notempty
add ebx, 0x20
cmp ebx, FDD_BUFF + 0x200
jb .checkempty
movzx eax, word [FLOPPY_FAT + eax*2]
pusha
add eax, 31
call read_chs_sector
popa
mov ebx, FDD_BUFF
jmp .checkempty
.notempty:
pop ebx
pop eax
.access_denied2:
pop edi
jmp .access_denied
.empty:
pop ebx
pop eax
pusha
call read_chs_sector
popa
.dodel:
push eax
movzx eax, word [edi+26]
xchg eax, [esp]
; delete folder entry
mov byte [edi], 0xE5
; delete LFN (if present)
.lfndel:
cmp edi, FDD_BUFF
ja @f
cmp [fd_prev_sector], 0
jz .lfndone
push [fd_prev_sector]
push [fd_prev_prev_sector]
pop [fd_prev_sector]
and [fd_prev_prev_sector], 0
pusha
call save_chs_sector
popa
pop eax
pusha
call read_chs_sector
popa
mov edi, FDD_BUFF+0x200
@@:
sub edi, 0x20
cmp byte [edi], 0xE5
jz .lfndone
cmp byte [edi+11], 0xF
jnz .lfndone
mov byte [edi], 0xE5
jmp .lfndel
.lfndone:
pusha
call save_chs_sector
popa
; delete FAT chain
pop eax
test eax, eax
jz .done
@@:
lea eax, [FLOPPY_FAT + eax*2]
push dword [eax]
and word [eax], 0
pop eax
and eax, 0xFFF
jnz @b
.done:
call save_flp_fat
pop edi
xor eax, eax
ret
 
; \end{diamond}
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/fs/parse_fn.inc
0,0 → 1,236
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;-------------------------------------------------------------------------
;
; File path partial substitution (according to configuration)
;
;
; SPraid
;
;-------------------------------------------------------------------------
 
$Revision$
 
 
iglobal
; pointer to memory for path replace table,
; size of one record is 128 bytes: 64 bytes for search pattern + 64 bytes for replace string
 
; start with one entry: sys -> <sysdir>
full_file_name_table dd sysdir_name
.size dd 1
 
tmp_file_name_size dd 1
endg
 
uglobal
; Parser_params will initialize: sysdir_name = "sys", sysdir_path = <sysdir>
sysdir_name rb 64
sysdir_path rb 64
tmp_file_name_table dd ?
endg
 
; use bx_from_load and init system directory /sys
proc Parser_params
locals
buff db 4 dup(?) ; for test cd
endl
mov eax,[OS_BASE+0x10000+bx_from_load]
mov ecx,sysdir_path
mov [ecx-64],dword 'sys'
cmp al,'r' ; if ram disk
jnz @f
mov [ecx],dword 'RD/?'
mov [ecx+3],byte ah
mov [ecx+4],byte 0
ret
@@:
cmp al,'m' ; if ram disk
jnz @f
mov [ecx],dword 'CD?/' ; if cd disk {m}
mov [ecx+4],byte '1'
mov [ecx+5],dword '/KOL'
mov [ecx+9],dword 'IBRI'
mov [ecx+13],byte 0
.next_cd:
mov [ecx+2],byte ah
inc ah
cmp ah,'5'
je .not_found_cd
lea edx,[buff]
pushad
stdcall read_file,read_firstapp,edx,0,4
popad
cmp [edx],dword 'MENU'
jne .next_cd
jmp .ok
@@:
sub al,49
mov [ecx],dword 'HD?/' ; if hard disk
mov [ecx+2],byte al
mov [ecx+4],byte ah
mov [ecx+5],dword '/KOL'
mov [ecx+9],dword 'IBRI'
mov [ecx+13],byte 0
.ok:
.not_found_cd:
ret
endp
 
proc load_file_parse_table
stdcall kernel_alloc,0x1000
mov [tmp_file_name_table],eax
mov edi,eax
mov esi,sysdir_name
mov ecx,128/4
rep movsd
 
invoke ini.enum_keys,conf_fname,conf_path_sect,get_every_key
 
mov eax,[tmp_file_name_table]
mov [full_file_name_table],eax
mov eax,[tmp_file_name_size]
mov [full_file_name_table.size],eax
ret
endp
 
uglobal
def_val_1 db 0
endg
 
proc get_every_key stdcall, f_name, sec_name, key_name
mov esi, [key_name]
mov ecx, esi
cmp byte [esi], '/'
jnz @f
inc esi
@@:
mov edi, [tmp_file_name_size]
shl edi, 7
cmp edi, 0x1000
jae .stop_parse
add edi, [tmp_file_name_table]
lea ebx, [edi+64]
@@:
cmp edi, ebx
jae .skip_this_key
lodsb
test al, al
jz @f
or al, 20h
stosb
jmp @b
@@:
stosb
 
invoke ini.get_str, [f_name],[sec_name],ecx,ebx,64,def_val_1
 
cmp byte [ebx], '/'
jnz @f
lea esi, [ebx+1]
mov edi, ebx
mov ecx, 63
rep movsb
@@:
push ebp
mov ebp, [tmp_file_name_table]
mov ecx, [tmp_file_name_size]
jecxz .noreplace
mov eax, ecx
dec eax
shl eax, 7
add ebp, eax
.replace_loop:
mov edi, ebx
mov esi, ebp
@@:
lodsb
test al, al
jz .doreplace
mov dl, [edi]
inc edi
test dl, dl
jz .replace_loop_cont
or dl, 20h
cmp al, dl
jz @b
jmp .replace_loop_cont
.doreplace:
cmp byte [edi], 0
jz @f
cmp byte [edi], '/'
jnz .replace_loop_cont
@@:
lea esi, [ebp+64]
call .replace
jc .skip_this_key2
.replace_loop_cont:
sub ebp, 128
loop .replace_loop
.noreplace:
pop ebp
 
inc [tmp_file_name_size]
.skip_this_key:
xor eax, eax
inc eax
ret
.skip_this_key2:
pop ebp
jmp .skip_this_key
.stop_parse:
xor eax, eax
ret
endp
 
proc get_every_key.replace
; in: ebx->destination, esi->first part of name, edi->second part of name
; maximum length is 64 bytes
; out: CF=1 <=> overflow
; 1) allocate temporary buffer in stack
sub esp, 64
; 2) save second part of name to temporary buffer
push esi
lea esi, [esp+4] ; esi->tmp buffer
xchg esi, edi ; edi->tmp buffer, esi->source
@@:
lodsb
stosb
test al, al
jnz @b
; 3) copy first part of name to destination
pop esi
mov edi, ebx
@@:
lodsb
test al, al
jz @f
stosb
jmp @b
@@:
; 4) restore second part of name from temporary buffer to destination
; (may cause overflow)
lea edx, [ebx+64] ; limit of destination
mov esi, esp
@@:
cmp edi, edx
jae .overflow
lodsb
stosb
test al, al
jnz @b
; all is OK
add esp, 64 ; CF is cleared
ret
.overflow:
; name is too long
add esp, 64
stc
ret
endp
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/fs
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/gui/window.inc
0,0 → 1,2085
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
;==============================================================================
;///// public functions ///////////////////////////////////////////////////////
;==============================================================================
 
window.BORDER_SIZE = 5
 
macro FuncTable name, table_name, [label]
{
common
align 4
\label name#.#table_name dword
forward
dd name#.#label
common
name#.sizeof.#table_name = $ - name#.#table_name
}
 
uglobal
common_colours rd 32
draw_limits RECT
endg
 
align 4
;------------------------------------------------------------------------------
syscall_draw_window: ;///// system function 0 /////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
mov eax, edx
shr eax, 24
and al, 0x0f
cmp al, 5
jae .exit
 
push eax
inc [mouse_pause]
call [_display.disable_mouse]
call window._.sys_set_window
call [_display.disable_mouse]
pop eax
 
or al, al
jnz @f
 
; type I - original style
call drawwindow_I
jmp window._.draw_window_caption.2
 
@@: dec al
jnz @f
 
; type II - only reserve area, no draw
call sys_window_mouse
dec [mouse_pause]
call [draw_pointer]
jmp .exit
 
@@: dec al
jnz @f
 
; type III - new style
call drawwindow_III
jmp window._.draw_window_caption.2
 
; type IV & V - skinned window (resizable & not)
@@: mov eax, [TASK_COUNT]
movzx eax, word[WIN_POS + eax * 2]
cmp eax, [CURRENT_TASK]
setz al
movzx eax, al
push eax
call drawwindow_IV
jmp window._.draw_window_caption.2
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
syscall_display_settings: ;///// system function 48 ///////////////////////////
;------------------------------------------------------------------------------
;; Redraw screen:
;< ebx = 0
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set button style:
;< ebx = 1
;< ecx = 0 (flat) or 1 (with gradient)
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set system color palette:
;< ebx = 2
;< ecx = pointer to color table
;< edx = size of color table
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Get system color palette:
;< ebx = 3
;< ecx = pointer to color table buffer
;< edx = size of color table buffer
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Get skinned caption height:
;< ebx = 4
;> eax = height in pixels
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Get screen working area:
;< ebx = 5
;> eax = pack[16(left), 16(right)]
;> ebx = pack[16(top), 16(bottom)]
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set screen working area:
;< ebx = 6
;< ecx = pack[16(left), 16(right)]
;< edx = pack[16(top), 16(bottom)]
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Get skin margins:
;< ebx = 7
;> eax = pack[16(left), 16(right)]
;> ebx = pack[16(top), 16(bottom)]
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set skin:
;< ebx = 8
;< ecx = pointer to FileInfoBlock struct
;> eax = FS error code
;------------------------------------------------------------------------------
cmp ebx, .sizeof.ftable / 4
ja @f
jmp [.ftable + ebx * 4]
@@: ret
 
 
align 4
syscall_display_settings.00:
xor eax, eax
inc ebx
cmp [windowtypechanged], ebx
jne .exit
mov [windowtypechanged], eax
 
jmp syscall_display_settings._.redraw_whole_screen
 
.exit:
ret
 
align 4
syscall_display_settings.01:
and ecx, 1
cmp ecx, [buttontype]
je .exit
mov [buttontype], ecx
mov [windowtypechanged], ebx
 
.exit:
ret
 
align 4
syscall_display_settings.02:
dec ebx
mov esi, ecx
and edx, 127
mov edi, common_colours
mov ecx, edx
rep movsb
mov [windowtypechanged], ebx
ret
 
align 4
syscall_display_settings.03:
mov edi, ecx
and edx, 127
mov esi, common_colours
mov ecx, edx
rep movsb
ret
 
align 4
syscall_display_settings.04:
mov eax, [_skinh]
mov [esp + 32], eax
ret
 
align 4
syscall_display_settings.05:
mov eax, [screen_workarea.left - 2]
mov ax, word[screen_workarea.right]
mov [esp + 32], eax
mov eax, [screen_workarea.top - 2]
mov ax, word[screen_workarea.bottom]
mov [esp + 20], eax
ret
 
align 4
syscall_display_settings.06:
xor esi, esi
 
mov edi, [Screen_Max_X]
mov eax, ecx
movsx ebx, ax
sar eax, 16
cmp eax, ebx
jge .check_horizontal
inc esi
or eax, eax
jge @f
xor eax, eax
@@: mov [screen_workarea.left], eax
cmp ebx, edi
jle @f
mov ebx, edi
@@: mov [screen_workarea.right], ebx
 
.check_horizontal:
mov edi, [Screen_Max_Y]
mov eax, edx
movsx ebx, ax
sar eax, 16
cmp eax, ebx
jge .check_if_redraw_needed
inc esi
or eax, eax
jge @f
xor eax, eax
@@: mov [screen_workarea.top], eax
cmp ebx, edi
jle @f
mov ebx, edi
@@: mov [screen_workarea.bottom], ebx
 
.check_if_redraw_needed:
or esi, esi
jz .exit
 
call repos_windows
jmp syscall_display_settings._.calculate_whole_screen
 
.exit:
ret
 
align 4
syscall_display_settings.07:
mov eax, [_skinmargins + 0]
mov [esp + 32], eax
mov eax, [_skinmargins + 4]
mov [esp + 20], eax
ret
 
align 4
syscall_display_settings.08:
mov ebx, ecx
call read_skin_file
mov [esp + 32], eax
test eax, eax
jnz .exit
 
call syscall_display_settings._.calculate_whole_screen
jmp syscall_display_settings._.redraw_whole_screen
 
.exit:
ret
 
syscall_display_settings._.calculate_whole_screen:
xor eax, eax
xor ebx, ebx
mov ecx, [Screen_Max_X]
mov edx, [Screen_Max_Y]
jmp calculatescreen
 
syscall_display_settings._.redraw_whole_screen:
xor eax, eax
mov [draw_limits.left], eax
mov [draw_limits.top], eax
mov eax, [Screen_Max_X]
mov [draw_limits.right], eax
mov eax, [Screen_Max_Y]
mov [draw_limits.bottom], eax
mov eax, window_data
jmp redrawscreen
 
align 4
;------------------------------------------------------------------------------
syscall_set_window_shape: ;///// system function 50 ///////////////////////////
;------------------------------------------------------------------------------
;; Set window shape address:
;> ebx = 0
;> ecx = shape data address
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Set window shape scale:
;> ebx = 1
;> ecx = scale power (resulting scale is 2^ebx)
;------------------------------------------------------------------------------
mov edi, [current_slot]
 
test ebx, ebx
jne .shape_scale
mov [edi + APPDATA.wnd_shape], ecx
 
.shape_scale:
dec ebx
jnz .exit
mov [edi + APPDATA.wnd_shape_scale], ecx
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
syscall_move_window: ;///// system function 67 ////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
mov edi, [CURRENT_TASK]
shl edi, 5
add edi, window_data
 
test [edi + WDATA.fl_wdrawn], 1
jz .exit
 
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jnz .exit
 
cmp ebx, -1
jne @f
mov ebx, [edi + WDATA.box.left]
@@: cmp ecx, -1
jne @f
mov ecx, [edi + WDATA.box.top]
@@: cmp edx, -1
jne @f
mov edx, [edi + WDATA.box.width]
@@: cmp esi, -1
jne @f
mov esi, [edi + WDATA.box.height]
 
@@: push esi edx ecx ebx
mov eax, esp
mov bl, [edi + WDATA.fl_wstate]
call window._.set_window_box
add esp, BOX.sizeof
 
; NOTE: do we really need this? to be reworked
; mov byte[DONT_DRAW_MOUSE], 0 ; mouse pointer
; mov byte[MOUSE_BACKGROUND], 0 ; no mouse under
; mov byte[MOUSE_DOWN], 0 ; react to mouse up/down
 
; NOTE: do we really need this? to be reworked
; call [draw_pointer]
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
syscall_window_settings: ;///// system function 71 /////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
dec ebx ; subfunction #1 - set window caption
jnz .exit_fail
 
; NOTE: only window owner thread can set its caption,
; so there's no parameter for PID/TID
 
mov edi, [CURRENT_TASK]
shl edi, 5
 
mov [edi * 8 + SLOT_BASE + APPDATA.wnd_caption], ecx
or [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION
 
call window._.draw_window_caption
 
xor eax, eax ; eax = 0 (success)
ret
 
; .get_window_caption:
; dec eax ; subfunction #2 - get window caption
; jnz .exit_fail
 
; not implemented yet
 
.exit_fail:
xor eax, eax
inc eax ; eax = 1 (fail)
ret
 
align 4
;------------------------------------------------------------------------------
set_window_defaults: ;/////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
mov byte [window_data + 0x20 + WDATA.cl_titlebar + 3], 1 ; desktop is not movable
push eax ecx
xor eax, eax
mov ecx, WIN_STACK
@@: inc eax
add ecx, 2
; process no
mov [ecx + 0x000], ax
; positions in stack
mov [ecx + 0x400], ax
cmp ecx, WIN_POS - 2
jne @b
pop ecx eax
ret
 
align 4
;------------------------------------------------------------------------------
calculatescreen: ;/////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Scan all windows from bottom to top, calling `setscreen` for each one
;? intersecting given screen area
;------------------------------------------------------------------------------
;> eax = left
;> ebx = top
;> ecx = right
;> edx = bottom
;------------------------------------------------------------------------------
push esi
pushfd
cli
 
mov esi, 1
call window._.set_screen
 
push ebp
 
mov ebp, [TASK_COUNT]
cmp ebp, 1
jbe .exit
 
push edx ecx ebx eax
 
.next_window:
movzx edi, word[WIN_POS + esi * 2]
shl edi, 5
 
cmp [CURRENT_TASK + edi + TASKDATA.state], TSTATE_FREE
je .skip_window
 
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .skip_window
 
mov eax, [edi + WDATA.box.left]
cmp eax, [esp + RECT.right]
jg .skip_window
mov ebx, [edi + WDATA.box.top]
cmp ebx, [esp + RECT.bottom]
jg .skip_window
mov ecx, [edi + WDATA.box.width]
add ecx, eax
cmp ecx, [esp + RECT.left]
jl .skip_window
mov edx, [edi + WDATA.box.height]
add edx, ebx
cmp edx, [esp + RECT.top]
jl .skip_window
 
cmp eax, [esp + RECT.left]
jae @f
mov eax, [esp + RECT.left]
@@: cmp ebx, [esp + RECT.top]
jae @f
mov ebx, [esp + RECT.top]
@@: cmp ecx, [esp + RECT.right]
jbe @f
mov ecx, [esp + RECT.right]
@@: cmp edx, [esp + RECT.bottom]
jbe @f
mov edx, [esp + RECT.bottom]
 
@@: push esi
movzx esi, word[WIN_POS + esi * 2]
call window._.set_screen
pop esi
 
.skip_window:
inc esi
dec ebp
jnz .next_window
 
pop eax ebx ecx edx
 
.exit:
pop ebp
popfd
pop esi
ret
 
align 4
;------------------------------------------------------------------------------
repos_windows: ;///////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
mov ecx, [TASK_COUNT]
mov edi, window_data + WDATA.sizeof * 2
call force_redraw_background
dec ecx
jle .exit
 
.next_window:
mov [edi + WDATA.fl_redraw], 1
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jnz .fix_maximized
 
mov eax, [edi + WDATA.box.left]
add eax, [edi + WDATA.box.width]
mov ebx, [Screen_Max_X]
cmp eax, ebx
jle .fix_vertical
mov eax, [edi + WDATA.box.width]
sub eax, ebx
jle @f
mov [edi + WDATA.box.width], ebx
@@: sub ebx, [edi + WDATA.box.width]
mov [edi + WDATA.box.left], ebx
 
.fix_vertical:
mov eax, [edi + WDATA.box.top]
add eax, [edi + WDATA.box.height]
mov ebx, [Screen_Max_Y]
cmp eax, ebx
jle .fix_client_box
mov eax, [edi + WDATA.box.height]
sub eax, ebx
jle @f
mov [edi + WDATA.box.height], ebx
@@: sub ebx, [edi + WDATA.box.height]
mov [edi + WDATA.box.top], ebx
jmp .fix_client_box
 
.fix_maximized:
mov eax, [screen_workarea.left]
mov [edi + WDATA.box.left], eax
sub eax, [screen_workarea.right]
neg eax
mov [edi + WDATA.box.width], eax
mov eax, [screen_workarea.top]
mov [edi + WDATA.box.top], eax
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
jnz .fix_client_box
sub eax, [screen_workarea.bottom]
neg eax
mov [edi + WDATA.box.height], eax
 
.fix_client_box:
call window._.set_window_clientbox
 
add edi, WDATA.sizeof
loop .next_window
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
sys_window_mouse: ;////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
; NOTE: commented out since doesn't provide necessary functionality
; anyway, to be reworked
; push eax
;
; mov eax, [timer_ticks]
; cmp [new_window_starting], eax
; jb .exit
;
; mov byte[MOUSE_BACKGROUND], 0
; mov byte[DONT_DRAW_MOUSE], 0
;
; mov [new_window_starting], eax
;
; .exit:
; pop eax
ret
 
align 4
;------------------------------------------------------------------------------
draw_rectangle: ;//////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> eax = pack[16(left), 16(right)]
;> ebx = pack[16(top), 16(bottom)]
;> esi = color
;------------------------------------------------------------------------------
push eax ebx ecx edi
 
xor edi, edi
 
.flags_set:
push ebx
 
; set line color
mov ecx, esi
 
; draw top border
rol ebx, 16
push ebx
rol ebx, 16
pop bx
call [draw_line]
 
; draw bottom border
mov ebx, [esp - 2]
pop bx
call [draw_line]
 
pop ebx
add ebx, 1 * 65536 - 1
 
; draw left border
rol eax, 16
push eax
rol eax, 16
pop ax
call [draw_line]
 
; draw right border
mov eax, [esp - 2]
pop ax
call [draw_line]
 
pop edi ecx ebx eax
ret
 
.forced:
push eax ebx ecx edi
xor edi, edi
inc edi
jmp .flags_set
 
align 4
;------------------------------------------------------------------------------
drawwindow_I_caption: ;////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
push [edx + WDATA.cl_titlebar]
mov esi, edx
 
mov edx, [esi + WDATA.box.top]
mov eax, edx
lea ebx, [edx + 21]
inc edx
add eax, [esi + WDATA.box.height]
 
cmp ebx, eax
jbe @f
mov ebx, eax
@@: push ebx
 
xor edi, edi
 
.next_line:
mov ebx, edx
shl ebx, 16
add ebx, edx
mov eax, [esi + WDATA.box.left]
inc eax
shl eax, 16
add eax, [esi + WDATA.box.left]
add eax, [esi + WDATA.box.width]
dec eax
mov ecx, [esi + WDATA.cl_titlebar]
test ecx, 0x80000000
jz @f
sub ecx, 0x00040404
mov [esi + WDATA.cl_titlebar], ecx
@@: and ecx, 0x00ffffff
call [draw_line]
inc edx
cmp edx, [esp]
jb .next_line
 
add esp, 4
pop [esi + WDATA.cl_titlebar]
ret
 
align 4
;------------------------------------------------------------------------------
drawwindow_I: ;////////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
pushad
 
; window border
 
mov eax, [edx + WDATA.box.left - 2]
mov ax, word[edx + WDATA.box.left]
add ax, word[edx + WDATA.box.width]
mov ebx, [edx + WDATA.box.top - 2]
mov bx, word[edx + WDATA.box.top]
add bx, word[edx + WDATA.box.height]
 
mov esi, [edx + WDATA.cl_frames]
call draw_rectangle
 
; window caption
 
call drawwindow_I_caption
 
; window client area
 
; do we need to draw it?
mov edi, [esi + WDATA.cl_workarea]
test edi, 0x40000000
jnz .exit
 
; does client area have a positive size on screen?
mov edx, [esi + WDATA.box.top]
add edx, 21 + 5
mov ebx, [esi + WDATA.box.top]
add ebx, [esi + WDATA.box.height]
cmp edx, ebx
jg .exit
 
; okay, let's draw it
mov eax, 1
mov ebx, 21
mov ecx, [esi + WDATA.box.width]
mov edx, [esi + WDATA.box.height]
call [drawbar]
 
.exit:
popad
ret
 
align 4
;------------------------------------------------------------------------------
drawwindow_III_caption: ;/////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
mov ecx, [edx + WDATA.cl_titlebar]
push ecx
mov esi, edx
mov edx, [esi + WDATA.box.top]
add edx, 4
mov ebx, [esi + WDATA.box.top]
add ebx, 20
mov eax, [esi + WDATA.box.top]
add eax, [esi + WDATA.box.height]
 
cmp ebx, eax
jb @f
mov ebx, eax
@@: push ebx
 
xor edi, edi
 
.next_line:
mov ebx, edx
shl ebx, 16
add ebx, edx
mov eax, [esi + WDATA.box.left]
shl eax, 16
add eax, [esi + WDATA.box.left]
add eax, [esi + WDATA.box.width]
add eax, 4 * 65536 - 4
mov ecx, [esi + WDATA.cl_titlebar]
test ecx, 0x40000000
jz @f
add ecx, 0x00040404
@@: test ecx, 0x80000000
jz @f
sub ecx, 0x00040404
@@: mov [esi + WDATA.cl_titlebar], ecx
and ecx, 0x00ffffff
call [draw_line]
inc edx
cmp edx, [esp]
jb .next_line
 
add esp, 4
pop [esi + WDATA.cl_titlebar]
ret
 
align 4
;------------------------------------------------------------------------------
drawwindow_III: ;//////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
pushad
 
; window border
 
mov eax, [edx + WDATA.box.left - 2]
mov ax, word[edx + WDATA.box.left]
add ax, word[edx + WDATA.box.width]
mov ebx, [edx + WDATA.box.top - 2]
mov bx, word[edx + WDATA.box.top]
add bx, word[edx + WDATA.box.height]
 
mov esi, [edx + WDATA.cl_frames]
shr esi, 1
and esi, 0x007f7f7f
call draw_rectangle
 
push esi
mov ecx, 3
mov esi, [edx + WDATA.cl_frames]
 
.next_frame:
add eax, 1 * 65536 - 1
add ebx, 1 * 65536 - 1
call draw_rectangle
dec ecx
jnz .next_frame
 
pop esi
add eax, 1 * 65536 - 1
add ebx, 1 * 65536 - 1
call draw_rectangle
 
; window caption
 
call drawwindow_III_caption
 
; window client area
 
; do we need to draw it?
mov edi, [esi + WDATA.cl_workarea]
test edi, 0x40000000
jnz .exit
 
; does client area have a positive size on screen?
mov edx, [esi + WDATA.box.top]
add edx, 21 + 5
mov ebx, [esi + WDATA.box.top]
add ebx, [esi + WDATA.box.height]
cmp edx, ebx
jg .exit
 
; okay, let's draw it
mov eax, 5
mov ebx, 20
mov ecx, [esi + WDATA.box.width]
mov edx, [esi + WDATA.box.height]
sub ecx, 4
sub edx, 4
call [drawbar]
 
.exit:
popad
ret
 
align 4
;------------------------------------------------------------------------------
waredraw: ;////////////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Activate window, redrawing if necessary
;------------------------------------------------------------------------------
push -1
mov eax, [TASK_COUNT]
lea eax, [WIN_POS + eax * 2]
cmp eax, esi
pop eax
je .exit
 
; is it overlapped by another window now?
push ecx
call window._.check_window_draw
test ecx, ecx
pop ecx
jz .do_not_draw
 
; yes it is, activate and update screen buffer
mov byte[MOUSE_DOWN], 1
call window._.window_activate
 
pushad
mov edi, [TASK_COUNT]
movzx esi, word[WIN_POS + edi * 2]
shl esi, 5
add esi, window_data
 
mov eax, [esi + WDATA.box.left]
mov ebx, [esi + WDATA.box.top]
mov ecx, [esi + WDATA.box.width]
mov edx, [esi + WDATA.box.height]
 
add ecx, eax
add edx, ebx
 
mov edi, [TASK_COUNT]
movzx esi, word[WIN_POS + edi * 2]
call window._.set_screen
popad
 
; tell application to redraw itself
mov [edi + WDATA.fl_redraw], 1
xor eax, eax
jmp .exit
 
.do_not_draw:
; no it's not, just activate the window
call window._.window_activate
xor eax, eax
mov byte[MOUSE_BACKGROUND], al
mov byte[DONT_DRAW_MOUSE], al
 
 
.exit:
mov byte[MOUSE_DOWN], 0
inc eax
ret
 
align 4
;------------------------------------------------------------------------------
minimize_window: ;/////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> eax = window number on screen
;------------------------------------------------------------------------------
;# corrupts [dl*]
;------------------------------------------------------------------------------
push edi
pushfd
cli
 
; is it already minimized?
movzx edi, word[WIN_POS + eax * 2]
shl edi, 5
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .exit
 
push eax ebx ecx edx esi
 
; no it's not, let's do that
or [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
mov eax, [edi + WDATA.box.left]
mov [draw_limits.left], eax
mov ecx, eax
add ecx, [edi + WDATA.box.width]
mov [draw_limits.right], ecx
mov ebx, [edi + WDATA.box.top]
mov [draw_limits.top], ebx
mov edx, ebx
add edx, [edi + WDATA.box.height]
mov [draw_limits.bottom], edx
call calculatescreen
xor esi, esi
xor eax, eax
call redrawscreen
 
pop esi edx ecx ebx eax
 
.exit:
popfd
pop edi
ret
 
align 4
;------------------------------------------------------------------------------
restore_minimized_window: ;////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;> eax = window number on screen
;------------------------------------------------------------------------------
;# corrupts [dl*]
;------------------------------------------------------------------------------
pushad
pushfd
cli
 
; is it already restored?
movzx esi, word[WIN_POS + eax * 2]
mov edi, esi
shl edi, 5
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jz .exit
 
; no it's not, let's do that
mov [edi + WDATA.fl_redraw], 1
and [edi + WDATA.fl_wstate], not WSTATE_MINIMIZED
mov ebp, window._.set_screen
cmp eax, [TASK_COUNT]
jz @f
mov ebp, calculatescreen
@@: mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
call ebp
 
mov byte[MOUSE_BACKGROUND], 0
 
.exit:
popfd
popad
ret
 
align 4
; TODO: remove this proc
;------------------------------------------------------------------------------
window_check_events: ;/////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
; do we have window minimize/restore request?
cmp [window_minimize], 0
je .exit
 
; okay, minimize or restore top-most window and exit
mov eax, [TASK_COUNT]
mov bl, 0
xchg [window_minimize], bl
dec bl
jnz @f
call minimize_window
jmp .exit
 
@@: call restore_minimized_window
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
sys_window_maximize_handler: ;/////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> esi = process slot
;------------------------------------------------------------------------------
mov edi, esi
shl edi, 5
add edi, window_data
 
; can window change its height?
; only types 2 and 3 can be resized
mov dl, [edi + WDATA.fl_wstyle]
test dl, 2
jz .exit
 
; toggle normal/maximized window state
mov bl, [edi + WDATA.fl_wstate]
xor bl, WSTATE_MAXIMIZED
 
; calculate and set appropriate window bounds
test bl, WSTATE_MAXIMIZED
jz .restore_size
 
mov eax, [screen_workarea.left]
mov ecx, [screen_workarea.top]
push [screen_workarea.bottom] \
[screen_workarea.right] \
ecx \
eax
sub [esp + BOX.width], eax
sub [esp + BOX.height], ecx
mov eax, esp
jmp .set_box
 
.restore_size:
mov eax, esi
shl eax, 8
add eax, SLOT_BASE + APPDATA.saved_box
push [eax + BOX.height] \
[eax + BOX.width] \
[eax + BOX.top] \
[eax + BOX.left]
mov eax, esp
 
.set_box:
test bl, WSTATE_ROLLEDUP
jz @f
 
xchg eax, ecx
call window._.get_rolledup_height
mov [ecx + BOX.height], eax
xchg eax, ecx
 
@@: call window._.set_window_box
add esp, BOX.sizeof
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
sys_window_rollup_handler: ;///////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> esi = process slot
;------------------------------------------------------------------------------
mov edx, esi
shl edx, 8
add edx, SLOT_BASE
 
; toggle normal/rolled up window state
mov bl, [edi + WDATA.fl_wstate]
xor bl, WSTATE_ROLLEDUP
 
; calculate and set appropriate window bounds
test bl, WSTATE_ROLLEDUP
jz .restore_size
 
call window._.get_rolledup_height
push eax \
[edi + WDATA.box.width] \
[edi + WDATA.box.top] \
[edi + WDATA.box.left]
mov eax, esp
jmp .set_box
 
.restore_size:
test bl, WSTATE_MAXIMIZED
jnz @f
add esp, -BOX.sizeof
lea eax, [edx + APPDATA.saved_box]
jmp .set_box
 
@@: mov eax, [screen_workarea.top]
push [screen_workarea.bottom] \
[edi + WDATA.box.width] \
eax \
[edi + WDATA.box.left]
sub [esp + BOX.height], eax
mov eax, esp
 
.set_box:
call window._.set_window_box
add esp, BOX.sizeof
 
ret
 
align 4
;------------------------------------------------------------------------------
sys_window_start_moving_handler: ;/////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = old (original) window box
;> esi = process slot
;------------------------------------------------------------------------------
mov edi, eax
call window._.draw_negative_box
 
ret
 
align 4
;------------------------------------------------------------------------------
sys_window_end_moving_handler: ;///////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = old (original) window box
;> ebx = new (final) window box
;> esi = process slot
;------------------------------------------------------------------------------
mov edi, ebx
call window._.draw_negative_box
 
mov edi, esi
shl edi, 5
add edi, window_data
 
mov eax, ebx
mov bl, [edi + WDATA.fl_wstate]
call window._.set_window_box
ret
 
align 4
;------------------------------------------------------------------------------
sys_window_moving_handler: ;///////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = old (from previous call) window box
;> ebx = new (current) window box
;> esi = process_slot
;------------------------------------------------------------------------------
mov edi, eax
call window._.draw_negative_box
mov edi, ebx
call window._.draw_negative_box
ret
 
;==============================================================================
;///// private functions //////////////////////////////////////////////////////
;==============================================================================
 
iglobal
FuncTable syscall_display_settings, ftable, \
00, 01, 02, 03, 04, 05, 06, 07, 08
 
align 4
window_topleft dd \
1, 21, \ ;type 0
0, 0, \ ;type 1
5, 20, \ ;type 2
5, ?, \ ;type 3 {set by skin}
5, ? ;type 4 {set by skin}
endg
 
;uglobal
; NOTE: commented out since doesn't provide necessary functionality anyway,
; to be reworked
; new_window_starting dd ?
;endg
 
align 4
;------------------------------------------------------------------------------
window._.invalidate_screen: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = old (original) window box
;> ebx = new (final) window box
;> edi = pointer to WDATA struct
;------------------------------------------------------------------------------
push eax ebx
 
; TODO: do we really need `draw_limits`?
; Yes, they are used by background drawing code.
mov ecx, [eax + BOX.left]
mov edx, [ebx + BOX.left]
cmp ecx, edx
jle @f
mov ecx, edx
@@: mov [draw_limits.left], ecx
mov ecx, [eax + BOX.left]
add ecx, [eax + BOX.width]
add edx, [ebx + BOX.width]
cmp ecx, edx
jae @f
mov ecx, edx
@@: mov [draw_limits.right], ecx
mov ecx, [eax + BOX.top]
mov edx, [ebx + BOX.top]
cmp ecx, edx
jle @f
mov ecx, edx
@@: mov [draw_limits.top], ecx
mov ecx, [eax + BOX.top]
add ecx, [eax + BOX.height]
add edx, [ebx + BOX.height]
cmp ecx, edx
jae @f
mov ecx, edx
@@: mov [draw_limits.bottom], ecx
 
; recalculate screen buffer at old position
push ebx
mov edx, [eax + BOX.height]
mov ecx, [eax + BOX.width]
mov ebx, [eax + BOX.top]
mov eax, [eax + BOX.left]
add ecx, eax
add edx, ebx
call calculatescreen
pop eax
 
; recalculate screen buffer at new position
mov edx, [eax + BOX.height]
mov ecx, [eax + BOX.width]
mov ebx, [eax + BOX.top]
mov eax, [eax + BOX.left]
add ecx, eax
add edx, ebx
call calculatescreen
 
mov eax, edi
call redrawscreen
 
; tell window to redraw itself
mov [edi + WDATA.fl_redraw], 1
 
pop ebx eax
ret
 
align 4
;------------------------------------------------------------------------------
window._.set_window_box: ;/////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = pointer to BOX struct
;> bl = new window state flags
;> edi = pointer to WDATA struct
;------------------------------------------------------------------------------
push eax ebx esi
 
; don't do anything if the new box is identical to the old
cmp bl, [edi + WDATA.fl_wstate]
jnz @f
mov esi, eax
push edi
if WDATA.box
add edi, WDATA.box
end if
mov ecx, 4
repz cmpsd
pop edi
jz .exit
@@:
 
add esp, -BOX.sizeof
 
mov ebx, esp
if WDATA.box
lea esi, [edi + WDATA.box]
else
mov esi, edi ; optimization for WDATA.box = 0
end if
xchg eax, esi
mov ecx, BOX.sizeof
call memmove
xchg eax, esi
xchg ebx, esi
call memmove
mov eax, ebx
mov ebx, esi
 
call window._.check_window_position
call window._.set_window_clientbox
call window._.invalidate_screen
 
add esp, BOX.sizeof
 
mov cl, [esp + 4]
mov ch, cl
xchg cl, [edi + WDATA.fl_wstate]
 
or cl, ch
test cl, WSTATE_MAXIMIZED
jnz .exit
 
mov eax, edi
sub eax, window_data
shl eax, 3
add eax, SLOT_BASE
 
lea ebx, [edi + WDATA.box]
xchg esp, ebx
 
pop [eax + APPDATA.saved_box.left] \
[eax + APPDATA.saved_box.top] \
[eax + APPDATA.saved_box.width] \
edx
 
xchg esp, ebx
 
test ch, WSTATE_ROLLEDUP
jnz .exit
 
mov [eax + APPDATA.saved_box.height], edx
 
.exit:
pop esi ebx eax
ret
 
align 4
;------------------------------------------------------------------------------
window._.set_window_clientbox: ;///////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> edi = pointer to WDATA struct
;------------------------------------------------------------------------------
push eax ecx edi
 
mov eax, [_skinh]
mov [window_topleft + 8 * 3 + 4], eax
mov [window_topleft + 8 * 4 + 4], eax
 
mov ecx, edi
sub edi, window_data
shl edi, 3
test [ecx + WDATA.fl_wstyle], WSTYLE_CLIENTRELATIVE
jz .whole_window
 
movzx eax, [ecx + WDATA.fl_wstyle]
and eax, 0x0F
mov eax, [eax * 8 + window_topleft + 0]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax
shl eax, 1
neg eax
add eax, [ecx + WDATA.box.width]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax
 
movzx eax, [ecx + WDATA.fl_wstyle]
and eax, 0x0F
push [eax * 8 + window_topleft + 0]
mov eax, [eax * 8 + window_topleft + 4]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax
neg eax
sub eax, [esp]
add eax, [ecx + WDATA.box.height]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax
add esp, 4
jmp .exit
 
.whole_window:
xor eax, eax
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax
mov eax, [ecx + WDATA.box.width]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax
mov eax, [ecx + WDATA.box.height]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax
 
.exit:
pop edi ecx eax
ret
 
align 4
;------------------------------------------------------------------------------
window._.sys_set_window: ;/////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;< edx = pointer to WDATA struct
;------------------------------------------------------------------------------
mov eax, [CURRENT_TASK]
shl eax, 5
add eax, window_data
 
; save window colors
mov [eax + WDATA.cl_workarea], edx
mov [eax + WDATA.cl_titlebar], esi
mov [eax + WDATA.cl_frames], edi
 
mov edi, eax
 
; was it already defined before?
test [edi + WDATA.fl_wdrawn], 1
jnz .set_client_box
or [edi + WDATA.fl_wdrawn], 1
 
; NOTE: commented out since doesn't provide necessary functionality
; anyway, to be reworked
; mov eax, [timer_ticks] ; [0xfdf0]
; add eax, 100
; mov [new_window_starting], eax
 
; no it wasn't, performing initial window definition
movzx eax, bx
mov [edi + WDATA.box.width], eax
movzx eax, cx
mov [edi + WDATA.box.height], eax
sar ebx, 16
sar ecx, 16
mov [edi + WDATA.box.left], ebx
mov [edi + WDATA.box.top], ecx
 
call window._.check_window_position
 
push ecx edi
 
mov cl, [edi + WDATA.fl_wstyle]
mov eax, [edi + WDATA.cl_frames]
 
sub edi, window_data
shl edi, 3
add edi, SLOT_BASE
 
and cl, 0x0F
cmp cl, 3
je @f
cmp cl, 4
je @f
 
xor eax, eax
 
@@: mov [edi + APPDATA.wnd_caption], eax
 
mov esi, [esp]
add edi, APPDATA.saved_box
movsd
movsd
movsd
movsd
 
pop edi ecx
 
mov esi, [CURRENT_TASK]
movzx esi, word[WIN_STACK + esi * 2]
lea esi, [WIN_POS + esi * 2]
call waredraw
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
call calculatescreen
 
mov byte[KEY_COUNT], 0 ; empty keyboard buffer
mov byte[BTN_COUNT], 0 ; empty button buffer
 
.set_client_box:
; update window client box coordinates
call window._.set_window_clientbox
 
; reset window redraw flag and exit
mov [edi + WDATA.fl_redraw], 0
mov edx, edi
ret
 
align 4
;------------------------------------------------------------------------------
window._.check_window_position: ;//////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Check if window is inside screen area
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
push eax ebx ecx edx esi
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
 
mov esi, [Screen_Max_X]
cmp ecx, esi
ja .fix_width_high
 
.check_left:
or eax, eax
jl .fix_left_low
add eax, ecx
cmp eax, esi
jg .fix_left_high
 
.check_height:
mov esi, [Screen_Max_Y]
cmp edx, esi
ja .fix_height_high
 
.check_top:
or ebx, ebx
jl .fix_top_low
add ebx, edx
cmp ebx, esi
jg .fix_top_high
 
.exit:
pop esi edx ecx ebx eax
ret
 
.fix_width_high:
mov ecx, esi
mov [edi + WDATA.box.width], esi
jmp .check_left
 
.fix_left_low:
xor eax, eax
mov [edi + WDATA.box.left], eax
jmp .check_height
 
.fix_left_high:
mov eax, esi
sub eax, ecx
mov [edi + WDATA.box.left], eax
jmp .check_height
 
.fix_height_high:
mov edx, esi
mov [edi + WDATA.box.height], esi
jmp .check_top
 
.fix_top_low:
xor ebx, ebx
mov [edi + WDATA.box.top], ebx
jmp .exit
 
.fix_top_high:
mov ebx, esi
sub ebx, edx
mov [edi + WDATA.box.top], ebx
jmp .exit
 
align 4
;------------------------------------------------------------------------------
window._.get_titlebar_height: ;////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
mov al, [edi + WDATA.fl_wstyle]
and al, 0x0f
cmp al, 0x03
jne @f
mov eax, [_skinh]
ret
@@: mov eax, 21
ret
 
align 4
;------------------------------------------------------------------------------
window._.get_rolledup_height: ;////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
mov al, [edi + WDATA.fl_wstyle]
and al, 0x0f
cmp al, 0x03
jb @f
mov eax, [_skinh]
add eax, 3
ret
@@: or al, al
jnz @f
mov eax, 21
ret
@@: mov eax, 21 + 2
ret
 
align 4
;------------------------------------------------------------------------------
window._.set_screen: ;/////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Reserve window area in screen buffer
;------------------------------------------------------------------------------
;> eax = left
;> ebx = top
;> ecx = right
;> edx = bottom
;> esi = process number
;------------------------------------------------------------------------------
virtual at esp
ff_x dd ?
ff_y dd ?
ff_width dd ?
ff_xsz dd ?
ff_ysz dd ?
ff_scale dd ?
end virtual
 
pushad
 
cmp esi, 1
jz .check_for_shaped_window
mov edi, esi
shl edi, 5
cmp [window_data + edi + WDATA.box.width], 0
jnz .check_for_shaped_window
cmp [window_data + edi + WDATA.box.height], 0
jz .exit
 
.check_for_shaped_window:
mov edi, esi
shl edi, 8
add edi, SLOT_BASE
cmp [edi + APPDATA.wnd_shape], 0
jne .shaped_window
 
; get x&y size
sub ecx, eax
sub edx, ebx
inc ecx
inc edx
 
; get WinMap start
push esi
mov edi, [Screen_Max_X]
inc edi
mov esi, edi
imul edi, ebx
add edi, eax
add edi, [_WinMapAddress]
pop eax
mov ah, al
push ax
shl eax, 16
pop ax
 
.next_line:
push ecx
shr ecx, 2
rep stosd
mov ecx, [esp]
and ecx, 3
rep stosb
pop ecx
add edi, esi
sub edi, ecx
dec edx
jnz .next_line
 
jmp .exit
 
.shaped_window:
; for (y=0; y <= x_size; y++)
; for (x=0; x <= x_size; x++)
; if (shape[coord(x,y,scale)]==1)
; set_pixel(x, y, process_number);
 
sub ecx, eax
sub edx, ebx
inc ecx
inc edx
 
push [edi + APPDATA.wnd_shape_scale] ; push scale first -> for loop
 
; get WinMap start -> ebp
push eax
mov eax, [Screen_Max_X] ; screen_sx
inc eax
imul eax, ebx
add eax, [esp]
add eax, [_WinMapAddress]
mov ebp, eax
 
mov edi, [edi + APPDATA.wnd_shape]
pop eax
 
; eax = x_start
; ebx = y_start
; ecx = x_size
; edx = y_size
; esi = process_number
; edi = &shape
; [scale]
push edx ecx ; for loop - x,y size
 
mov ecx, esi
shl ecx, 5
mov edx, [window_data + ecx + WDATA.box.top]
push [window_data + ecx + WDATA.box.width] ; for loop - width
mov ecx, [window_data + ecx + WDATA.box.left]
sub ebx, edx
sub eax, ecx
push ebx eax ; for loop - x,y
 
add [ff_xsz], eax
add [ff_ysz], ebx
 
mov ebx, [ff_y]
 
.ff_new_y:
mov edx, [ff_x]
 
.ff_new_x:
; -- body --
mov ecx, [ff_scale]
mov eax, [ff_width]
inc eax
shr eax, cl
push ebx edx
shr ebx, cl
shr edx, cl
imul eax, ebx
add eax, edx
pop edx ebx
add eax, edi
call .read_byte
test al,al
jz @f
mov eax, esi
mov [ebp], al
; -- end body --
@@: inc ebp
inc edx
cmp edx, [ff_xsz]
jb .ff_new_x
 
sub ebp, [ff_xsz]
add ebp, [ff_x]
add ebp, [Screen_Max_X] ; screen.x
inc ebp
inc ebx
cmp ebx, [ff_ysz]
jb .ff_new_y
 
add esp, 24
 
.exit:
popad
ret
 
.read_byte:
; eax - address
; esi - slot
push eax ecx edx esi
xchg eax, esi
lea ecx, [esp + 12]
mov edx, 1
call read_process_memory
pop esi edx ecx eax
ret
 
align 4
;------------------------------------------------------------------------------
window._.window_activate: ;////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Activate window
;------------------------------------------------------------------------------
;> esi = pointer to WIN_POS+ window data
;------------------------------------------------------------------------------
push eax ebx
 
; if type of current active window is 3 or 4, it must be redrawn
mov ebx, [TASK_COUNT]
movzx ebx, word[WIN_POS + ebx * 2]
shl ebx, 5
add eax, window_data
mov al, [window_data + ebx + WDATA.fl_wstyle]
and al, 0x0f
cmp al, 0x03
je .set_window_redraw_flag
cmp al, 0x04
jne .move_others_down
 
.set_window_redraw_flag:
mov [window_data + ebx + WDATA.fl_redraw], 1
 
.move_others_down:
; ax <- process no
movzx ebx, word[esi]
; ax <- position in window stack
movzx ebx, word[WIN_STACK + ebx * 2]
 
; drop others
xor eax, eax
 
.next_stack_window:
cmp eax, [TASK_COUNT]
jae .move_self_up
inc eax
cmp [WIN_STACK + eax * 2], bx
jbe .next_stack_window
dec word[WIN_STACK + eax * 2]
jmp .next_stack_window
 
.move_self_up:
movzx ebx, word[esi]
; number of processes
mov ax, [TASK_COUNT]
; this is the last (and the upper)
mov [WIN_STACK + ebx * 2], ax
 
; update on screen - window stack
xor eax, eax
 
.next_window_pos:
cmp eax, [TASK_COUNT]
jae .reset_vars
inc eax
movzx ebx, word[WIN_STACK + eax * 2]
mov [WIN_POS + ebx * 2], ax
jmp .next_window_pos
 
.reset_vars:
mov byte[KEY_COUNT], 0
mov byte[BTN_COUNT], 0
mov word[MOUSE_SCROLL_H], 0
mov word[MOUSE_SCROLL_V], 0
 
pop ebx eax
ret
 
align 4
;------------------------------------------------------------------------------
window._.check_window_draw: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Check if window is necessary to draw
;------------------------------------------------------------------------------
;> edi = pointer to WDATA
;------------------------------------------------------------------------------
mov cl, [edi + WDATA.fl_wstyle]
and cl, 0x0f
cmp cl, 3
je .exit.redraw ; window type 3
cmp cl, 4
je .exit.redraw ; window type 4
 
push eax ebx edx esi
 
mov eax, edi
sub eax, window_data
shr eax, 5
 
movzx eax, word[WIN_STACK + eax * 2] ; get value of the curr process
lea esi, [WIN_POS + eax * 2] ; get address of this process at 0xC400
 
.next_window:
add esi, 2
 
mov eax, [TASK_COUNT]
lea eax, word[WIN_POS + eax * 2] ; number of the upper window
 
cmp esi, eax
ja .exit.no_redraw
 
movzx edx, word[esi]
shl edx, 5
cmp [CURRENT_TASK + edx + TASKDATA.state], TSTATE_FREE
je .next_window
 
mov eax, [edi + WDATA.box.top]
mov ebx, [edi + WDATA.box.height]
add ebx, eax
 
mov ecx, [window_data + edx + WDATA.box.top]
cmp ecx, ebx
jge .next_window
add ecx, [window_data + edx + WDATA.box.height]
cmp eax, ecx
jge .next_window
 
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.width]
add ebx, eax
 
mov ecx, [window_data + edx + WDATA.box.left]
cmp ecx, ebx
jge .next_window
add ecx, [window_data + edx + WDATA.box.width]
cmp eax, ecx
jge .next_window
 
pop esi edx ebx eax
 
.exit.redraw:
xor ecx, ecx
inc ecx
ret
 
.exit.no_redraw:
pop esi edx ebx eax
xor ecx, ecx
ret
 
align 4
;------------------------------------------------------------------------------
window._.draw_window_caption: ;////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
inc [mouse_pause]
call [_display.disable_mouse]
 
xor eax, eax
mov edx, [TASK_COUNT]
movzx edx, word[WIN_POS + edx * 2]
cmp edx, [CURRENT_TASK]
jne @f
inc eax
@@: mov edx, [CURRENT_TASK]
shl edx, 5
add edx, window_data
movzx ebx, [edx + WDATA.fl_wstyle]
and bl, 0x0F
cmp bl, 3
je .draw_caption_style_3
cmp bl, 4
je .draw_caption_style_3
 
jmp .not_style_3
 
.draw_caption_style_3:
push edx
call drawwindow_IV_caption
add esp, 4
jmp .2
 
.not_style_3:
cmp bl, 2
jne .not_style_2
 
call drawwindow_III_caption
jmp .2
 
.not_style_2:
cmp bl, 0
jne .2
 
call drawwindow_I_caption
 
.2: mov edi, [CURRENT_TASK]
shl edi, 5
test [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION
jz .exit
mov edx, [edi * 8 + SLOT_BASE + APPDATA.wnd_caption]
or edx, edx
jz .exit
 
movzx eax, [edi + window_data + WDATA.fl_wstyle]
and al, 0x0F
cmp al, 3
je .skinned
cmp al, 4
je .skinned
 
jmp .not_skinned
 
.skinned:
mov ebp, [edi + window_data + WDATA.box.left - 2]
mov bp, word[edi + window_data + WDATA.box.top]
movzx eax, word[edi + window_data + WDATA.box.width]
sub ax, [_skinmargins.left]
sub ax, [_skinmargins.right]
push edx
cwde
cdq
mov ebx, 6
idiv ebx
pop edx
or eax, eax
js .exit
 
mov esi, eax
mov ebx, dword[_skinmargins.left - 2]
mov bx, word[_skinh]
sub bx, [_skinmargins.bottom]
sub bx, [_skinmargins.top]
sar bx, 1
adc bx, 0
add bx, [_skinmargins.top]
add bx, -3
add ebx, ebp
jmp .dodraw
 
.not_skinned:
cmp al, 1
je .exit
 
mov ebp, [edi + window_data + WDATA.box.left - 2]
mov bp, word[edi + window_data + WDATA.box.top]
movzx eax, word[edi + window_data + WDATA.box.width]
sub eax, 16
push edx
cwde
cdq
mov ebx, 6
idiv ebx
pop edx
or eax, eax
js .exit
 
mov esi, eax
mov ebx, 0x00080007
add ebx, ebp
 
.dodraw:
mov ecx, [common_colours + 16]
or ecx, 0x80000000
xor edi, edi
call dtext_asciiz_esi
 
.exit:
dec [mouse_pause]
call [draw_pointer]
ret
 
align 4
;------------------------------------------------------------------------------
window._.draw_negative_box: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Draw negative box
;------------------------------------------------------------------------------
;> edi = pointer to BOX struct
;------------------------------------------------------------------------------
push eax ebx esi
mov eax, [edi + BOX.left - 2]
mov ax, word[edi + BOX.left]
add ax, word[edi + BOX.width]
mov ebx, [edi + BOX.top - 2]
mov bx, word[edi + BOX.top]
add bx, word[edi + BOX.height]
mov esi, 0x01000000
call draw_rectangle.forced
pop esi ebx eax
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/gui/mouse.inc
0,0 → 1,701
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2010. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
include 'mousepointer.inc'
 
;==============================================================================
;///// public functions ///////////////////////////////////////////////////////
;==============================================================================
 
mouse.LEFT_BUTTON_FLAG = 0001b
mouse.RIGHT_BUTTON_FLAG = 0010b
mouse.MIDDLE_BUTTON_FLAG = 0100b
 
mouse.BUTTONS_MASK = \
mouse.LEFT_BUTTON_FLAG or \
mouse.RIGHT_BUTTON_FLAG or \
mouse.MIDDLE_BUTTON_FLAG
 
mouse.WINDOW_RESIZE_N_FLAG = 000001b
mouse.WINDOW_RESIZE_W_FLAG = 000010b
mouse.WINDOW_RESIZE_S_FLAG = 000100b
mouse.WINDOW_RESIZE_E_FLAG = 001000b
mouse.WINDOW_MOVE_FLAG = 010000b
 
mouse.WINDOW_RESIZE_SW_FLAG = \
mouse.WINDOW_RESIZE_S_FLAG or \
mouse.WINDOW_RESIZE_W_FLAG
mouse.WINDOW_RESIZE_SE_FLAG = \
mouse.WINDOW_RESIZE_S_FLAG or \
mouse.WINDOW_RESIZE_E_FLAG
 
align 4
;------------------------------------------------------------------------------
mouse_check_events: ;//////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Check if mouse buttons state or cursor position has changed and call
;? appropriate handlers
;------------------------------------------------------------------------------
push eax ebx
 
mov al, [BTN_DOWN]
mov bl, [mouse.state.buttons]
and al, mouse.BUTTONS_MASK
mov cl, al
xchg cl, [mouse.state.buttons]
xor bl, al
push eax ebx
 
; did any mouse button changed its state?
or bl, bl
jz .check_position
 
; yes it did, is that the first button of all pressed down?
or cl, cl
jnz .check_buttons_released
 
; yes it is, activate window user is pointing at, if needed
call mouse._.activate_sys_window_under_cursor
 
; NOTE: this code wouldn't be necessary if we knew window did
; already redraw itself after call above
or eax, eax
jz @f
 
and [mouse.state.buttons], 0
jmp .exit
 
; is there any system button under cursor?
@@: call mouse._.find_sys_button_under_cursor
or eax, eax
jz .check_buttons_released
 
; yes there is, activate it and exit
mov [mouse.active_sys_button.pbid], eax
mov [mouse.active_sys_button.coord], ebx
mov cl, [mouse.state.buttons]
mov [mouse.active_sys_button.buttons], cl
call sys_button_activate_handler
jmp .exit
 
.check_buttons_released:
cmp [mouse.state.buttons], 0
jnz .buttons_changed
 
; did we press some button earlier?
cmp [mouse.active_sys_button.pbid], 0
je .buttons_changed
 
; yes we did, deactivate it
xor eax, eax
xchg eax, [mouse.active_sys_button.pbid]
mov ebx, [mouse.active_sys_button.coord]
mov cl, [mouse.active_sys_button.buttons]
push eax ebx
call sys_button_deactivate_handler
pop edx ecx
 
; is the button under cursor the one we deactivated?
call mouse._.find_sys_button_under_cursor
cmp eax, ecx
jne .exit
cmp ebx, edx
jne .exit
 
; yes it is, perform associated action
mov cl, [mouse.active_sys_button.buttons]
call sys_button_perform_handler
jmp .exit
 
.buttons_changed:
test byte[esp], mouse.LEFT_BUTTON_FLAG
jz @f
mov eax, [esp + 4]
call .call_left_button_handler
 
@@: test byte[esp], mouse.RIGHT_BUTTON_FLAG
jz @f
mov eax, [esp + 4]
call .call_right_button_handler
 
@@: test byte[esp], mouse.MIDDLE_BUTTON_FLAG
jz .check_position
mov eax, [esp + 4]
call .call_middle_button_handler
 
.check_position:
movzx eax, word[MOUSE_X]
movzx ebx, word[MOUSE_Y]
cmp eax, [mouse.state.pos.x]
jne .position_changed
cmp ebx, [mouse.state.pos.y]
je .exit
 
.position_changed:
xchg eax, [mouse.state.pos.x]
xchg ebx, [mouse.state.pos.y]
 
call mouse._.move_handler
 
.exit:
add esp, 8
pop ebx eax
ret
 
.call_left_button_handler:
test eax, mouse.LEFT_BUTTON_FLAG
jnz mouse._.left_button_press_handler
jmp mouse._.left_button_release_handler
 
.call_right_button_handler:
test eax, mouse.RIGHT_BUTTON_FLAG
jnz mouse._.right_button_press_handler
jmp mouse._.right_button_release_handler
 
.call_middle_button_handler:
test eax, mouse.MIDDLE_BUTTON_FLAG
jnz mouse._.middle_button_press_handler
jmp mouse._.middle_button_release_handler
 
;==============================================================================
;///// private functions //////////////////////////////////////////////////////
;==============================================================================
 
uglobal
mouse.state:
.pos POINT
.buttons db ?
 
; NOTE: since there's no unique and lifetime-constant button identifiers,
; we're using two dwords to identify each of them:
; * pbid - process slot (high 8 bits) and button id (low 24 bits) pack
; * coord - left (high 16 bits) and top (low 16 bits) coordinates pack
align 4
mouse.active_sys_button:
.pbid dd ?
.coord dd ?
.buttons db ?
 
align 4
mouse.active_sys_window:
.pslot dd ?
.old_box BOX
.new_box BOX
.delta POINT
.last_ticks dd ?
.action db ?
endg
 
align 4
;------------------------------------------------------------------------------
mouse._.left_button_press_handler: ;///////////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when left mouse button has been pressed down
;------------------------------------------------------------------------------
test [mouse.state.buttons], not mouse.LEFT_BUTTON_FLAG
jnz .exit
 
call mouse._.find_sys_window_under_cursor
call mouse._.check_sys_window_actions
mov [mouse.active_sys_window.action], al
or eax, eax
jz .exit
 
xchg eax, edx
test dl, mouse.WINDOW_MOVE_FLAG
jz @f
 
mov eax, [timer_ticks]
mov ebx, eax
xchg ebx, [mouse.active_sys_window.last_ticks]
sub eax, ebx
cmp eax, 50
jg @f
 
mov [mouse.active_sys_window.last_ticks], 0
call sys_window_maximize_handler
jmp .exit
 
@@: test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jnz .exit
mov [mouse.active_sys_window.pslot], esi
lea eax, [edi + WDATA.box]
mov ebx, mouse.active_sys_window.old_box
mov ecx, BOX.sizeof
call memmove
mov ebx, mouse.active_sys_window.new_box
call memmove
test edx, mouse.WINDOW_MOVE_FLAG
jz @f
 
call .calculate_n_delta
call .calculate_w_delta
jmp .call_window_handler
 
@@: test dl, mouse.WINDOW_RESIZE_W_FLAG
jz @f
call .calculate_w_delta
 
@@: test dl, mouse.WINDOW_RESIZE_S_FLAG
jz @f
call .calculate_s_delta
 
@@: test dl, mouse.WINDOW_RESIZE_E_FLAG
jz .call_window_handler
call .calculate_e_delta
 
.call_window_handler:
mov eax, mouse.active_sys_window.old_box
call sys_window_start_moving_handler
 
.exit:
ret
 
.calculate_n_delta:
mov eax, [mouse.state.pos.y]
sub eax, [mouse.active_sys_window.old_box.top]
mov [mouse.active_sys_window.delta.y], eax
ret
 
.calculate_w_delta:
mov eax, [mouse.state.pos.x]
sub eax, [mouse.active_sys_window.old_box.left]
mov [mouse.active_sys_window.delta.x], eax
ret
 
.calculate_s_delta:
mov eax, [mouse.active_sys_window.old_box.top]
add eax, [mouse.active_sys_window.old_box.height]
sub eax, [mouse.state.pos.y]
mov [mouse.active_sys_window.delta.y], eax
ret
 
.calculate_e_delta:
mov eax, [mouse.active_sys_window.old_box.left]
add eax, [mouse.active_sys_window.old_box.width]
sub eax, [mouse.state.pos.x]
mov [mouse.active_sys_window.delta.x], eax
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.left_button_release_handler: ;/////////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when left mouse button has been released
;------------------------------------------------------------------------------
xor esi, esi
xchg esi, [mouse.active_sys_window.pslot]
or esi, esi
jz .exit
 
mov eax, esi
shl eax, 5
add eax, window_data + WDATA.box
mov ebx, mouse.active_sys_window.old_box
mov ecx, BOX.sizeof
call memmove
 
mov eax, mouse.active_sys_window.old_box
mov ebx, mouse.active_sys_window.new_box
call sys_window_end_moving_handler
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.right_button_press_handler: ;//////////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when right mouse button has been pressed down
;------------------------------------------------------------------------------
test [mouse.state.buttons], not mouse.RIGHT_BUTTON_FLAG
jnz .exit
 
call mouse._.find_sys_window_under_cursor
call mouse._.check_sys_window_actions
test al, mouse.WINDOW_MOVE_FLAG
jz .exit
 
call sys_window_rollup_handler
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.right_button_release_handler: ;////////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when right mouse button has been released
;------------------------------------------------------------------------------
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.middle_button_press_handler: ;/////////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when middle mouse button has been pressed down
;------------------------------------------------------------------------------
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.middle_button_release_handler: ;///////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when middle mouse button has been released
;------------------------------------------------------------------------------
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.move_handler: ;////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Called when cursor has been moved
;------------------------------------------------------------------------------
;> eax = old x coord
;> ebx = old y coord
;------------------------------------------------------------------------------
cmp [mouse.active_sys_button.pbid], 0
jnz .exit
 
mov esi, [mouse.active_sys_window.pslot]
or esi, esi
jz .exit
 
mov eax, mouse.active_sys_window.new_box
mov ebx, mouse.active_sys_window.old_box
mov ecx, BOX.sizeof
call memmove
 
mov dl, [mouse.active_sys_window.action]
test dl, mouse.WINDOW_MOVE_FLAG
jz .check_resize_w
 
mov eax, [mouse.state.pos.x]
sub eax, [mouse.active_sys_window.delta.x]
mov [mouse.active_sys_window.new_box.left], eax
mov eax, [mouse.state.pos.y]
sub eax, [mouse.active_sys_window.delta.y]
mov [mouse.active_sys_window.new_box.top], eax
 
mov eax, [mouse.active_sys_window.new_box.left]
or eax, eax
jge @f
xor eax, eax
mov [mouse.active_sys_window.new_box.left], eax
@@: add eax, [mouse.active_sys_window.new_box.width]
cmp eax, [Screen_Max_X]
jl @f
sub eax, [Screen_Max_X]
sub [mouse.active_sys_window.new_box.left], eax
@@: mov eax, [mouse.active_sys_window.new_box.top]
or eax, eax
jge @f
xor eax, eax
mov [mouse.active_sys_window.new_box.top], eax
@@: add eax, [mouse.active_sys_window.new_box.height]
cmp eax, [Screen_Max_Y]
jle .call_window_handler
sub eax, [Screen_Max_Y]
sub [mouse.active_sys_window.new_box.top], eax
jmp .call_window_handler
 
.check_resize_w:
test dl, mouse.WINDOW_RESIZE_W_FLAG
jz .check_resize_s
 
mov eax, [mouse.state.pos.x]
sub eax, [mouse.active_sys_window.delta.x]
mov [mouse.active_sys_window.new_box.left], eax
sub eax, [mouse.active_sys_window.old_box.left]
sub [mouse.active_sys_window.new_box.width], eax
 
mov eax, [mouse.active_sys_window.new_box.width]
sub eax, 127
jge @f
add [mouse.active_sys_window.new_box.left], eax
mov [mouse.active_sys_window.new_box.width], 127
@@: mov eax, [mouse.active_sys_window.new_box.left]
or eax, eax
jge .check_resize_s
add [mouse.active_sys_window.new_box.width], eax
xor eax, eax
mov [mouse.active_sys_window.new_box.left], eax
 
.check_resize_s:
test dl, mouse.WINDOW_RESIZE_S_FLAG
jz .check_resize_e
 
mov eax, [mouse.state.pos.y]
add eax, [mouse.active_sys_window.delta.y]
sub eax, [mouse.active_sys_window.old_box.top]
mov [mouse.active_sys_window.new_box.height], eax
 
push eax
mov edi, esi
shl edi, 5
add edi, window_data
call window._.get_rolledup_height
mov ecx, eax
pop eax
mov eax, [mouse.active_sys_window.new_box.height]
cmp eax, ecx
jge @f
mov eax, ecx
mov [mouse.active_sys_window.new_box.height], eax
@@: add eax, [mouse.active_sys_window.new_box.top]
cmp eax, [Screen_Max_Y]
jle .check_resize_e
sub eax, [Screen_Max_Y]
neg eax
add [mouse.active_sys_window.new_box.height], eax
mov ecx, [Screen_Max_Y]
cmp ecx, eax
jge .check_resize_e
mov [mouse.active_sys_window.new_box.height], ecx
 
.check_resize_e:
test dl, mouse.WINDOW_RESIZE_E_FLAG
jz .call_window_handler
 
mov eax, [mouse.state.pos.x]
add eax, [mouse.active_sys_window.delta.x]
sub eax, [mouse.active_sys_window.old_box.left]
mov [mouse.active_sys_window.new_box.width], eax
 
mov eax, [mouse.active_sys_window.new_box.width]
cmp eax, 127
jge @f
mov eax, 127
mov [mouse.active_sys_window.new_box.width], eax
@@: add eax, [mouse.active_sys_window.new_box.left]
cmp eax, [Screen_Max_X]
jle .call_window_handler
sub eax, [Screen_Max_X]
neg eax
add [mouse.active_sys_window.new_box.width], eax
mov ecx, [Screen_Max_X]
cmp ecx, eax
jge .call_window_handler
mov [mouse.active_sys_window.new_box.width], ecx
 
.call_window_handler:
mov eax, mouse.active_sys_window.old_box
mov ebx, mouse.active_sys_window.new_box
 
push esi
mov esi, mouse.active_sys_window.old_box
mov edi, mouse.active_sys_window.new_box
mov ecx, BOX.sizeof / 4
repe
cmpsd
pop esi
je .exit
 
mov [mouse.active_sys_window.last_ticks], 0
call sys_window_moving_handler
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.find_sys_window_under_cursor: ;////////////////////////////////////////
;------------------------------------------------------------------------------
;? Find system window object which is currently visible on screen and has
;? mouse cursor within its bounds
;------------------------------------------------------------------------------
;< esi = process slot
;< edi = pointer to WDATA struct
;------------------------------------------------------------------------------
mov esi, [Screen_Max_X]
inc esi
imul esi, [mouse.state.pos.y]
add esi, [_WinMapAddress]
add esi, [mouse.state.pos.x]
movzx esi, byte[esi]
mov edi, esi
shl edi, 5
add edi, window_data
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.activate_sys_window_under_cursor: ;////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
; activate and redraw window under cursor (if necessary)
call mouse._.find_sys_window_under_cursor
movzx esi, word[WIN_STACK + esi * 2]
lea esi, [WIN_POS + esi * 2]
jmp waredraw
 
align 4
;------------------------------------------------------------------------------
mouse._.find_sys_button_under_cursor: ;////////////////////////////////////////
;------------------------------------------------------------------------------
;? Find system button object which is currently visible on screen and has
;? mouse cursor within its bounds
;------------------------------------------------------------------------------
;< eax = pack[8(process slot), 24(button id)] or 0
;< ebx = pack[16(button x coord), 16(button y coord)]
;------------------------------------------------------------------------------
push ecx edx esi edi
 
call mouse._.find_sys_window_under_cursor
mov edx, esi
 
; check if any process button contains cursor
mov eax, [BTN_ADDR]
mov ecx, [eax]
imul esi, ecx, SYS_BUTTON.sizeof
add esi, eax
inc ecx
add esi, SYS_BUTTON.sizeof
 
.next_button:
dec ecx
jz .not_found
 
add esi, -SYS_BUTTON.sizeof
 
; does it belong to our process?
cmp dx, [esi + SYS_BUTTON.pslot]
jne .next_button
 
; does it contain cursor coordinates?
mov eax, [mouse.state.pos.x]
sub eax, [edi + WDATA.box.left]
sub ax, [esi + SYS_BUTTON.left]
jl .next_button
sub ax, [esi + SYS_BUTTON.width]
jge .next_button
mov eax, [mouse.state.pos.y]
sub eax, [edi + WDATA.box.top]
sub ax, [esi + SYS_BUTTON.top]
jl .next_button
sub ax, [esi + SYS_BUTTON.height]
jge .next_button
 
; okay, return it
shl edx, 24
mov eax, dword[esi + SYS_BUTTON.id_hi - 2]
mov ax, [esi + SYS_BUTTON.id_lo]
and eax, 0x0ffffff
or eax, edx
mov ebx, dword[esi + SYS_BUTTON.left - 2]
mov bx, [esi + SYS_BUTTON.top]
jmp .exit
 
.not_found:
xor eax, eax
xor ebx, ebx
 
.exit:
pop edi esi edx ecx
ret
 
align 4
;------------------------------------------------------------------------------
mouse._.check_sys_window_actions: ;////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;< eax = action flags or 0
;------------------------------------------------------------------------------
; is window movable?
test byte[edi + WDATA.cl_titlebar + 3], 0x01
jnz .no_action
 
mov eax, [mouse.state.pos.x]
mov ebx, [mouse.state.pos.y]
sub eax, [edi + WDATA.box.left]
sub ebx, [edi + WDATA.box.top]
 
; is there a window titlebar under cursor?
push eax
call window._.get_titlebar_height
cmp ebx, eax
pop eax
jl .move_action
 
; no there isn't, can it be resized then?
mov dl, [edi + WDATA.fl_wstyle]
and dl, 0x0f
; NOTE: dangerous optimization, revise if window types changed;
; this currently implies only types 2 and 3 could be resized
test dl, 2
jz .no_action
 
mov ecx, [edi + WDATA.box.width]
add ecx, -window.BORDER_SIZE
mov edx, [edi + WDATA.box.height]
add edx, -window.BORDER_SIZE
 
; is it rolled up?
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
jnz .resize_w_or_e_action
 
cmp eax, window.BORDER_SIZE
jl .resize_w_action
cmp eax, ecx
jg .resize_e_action
cmp ebx, edx
jle .no_action
 
.resize_s_action:
cmp eax, window.BORDER_SIZE + 10
jl .resize_sw_action
add ecx, -10
cmp eax, ecx
jge .resize_se_action
mov eax, mouse.WINDOW_RESIZE_S_FLAG
jmp .exit
 
.resize_w_or_e_action:
cmp eax, window.BORDER_SIZE + 10
jl .resize_w_action.direct
add ecx, -10
cmp eax, ecx
jg .resize_e_action.direct
jmp .no_action
 
.resize_w_action:
add edx, -10
cmp ebx, edx
jge .resize_sw_action
.resize_w_action.direct:
mov eax, mouse.WINDOW_RESIZE_W_FLAG
jmp .exit
 
.resize_e_action:
add edx, -10
cmp ebx, edx
jge .resize_se_action
.resize_e_action.direct:
mov eax, mouse.WINDOW_RESIZE_E_FLAG
jmp .exit
 
.resize_sw_action:
mov eax, mouse.WINDOW_RESIZE_SW_FLAG
jmp .exit
 
.resize_se_action:
mov eax, mouse.WINDOW_RESIZE_SE_FLAG
jmp .exit
 
.move_action:
mov eax, mouse.WINDOW_MOVE_FLAG
jmp .exit
 
.no_action:
xor eax, eax
 
.exit:
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/gui/event.inc
0,0 → 1,508
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
WINDOW_MOVE_AND_RESIZE_FLAGS = \
mouse.WINDOW_RESIZE_N_FLAG + \
mouse.WINDOW_RESIZE_W_FLAG + \
mouse.WINDOW_RESIZE_S_FLAG + \
mouse.WINDOW_RESIZE_E_FLAG + \
mouse.WINDOW_MOVE_FLAG
 
uglobal
align 4
event_start dd ?
event_end dd ?
event_uid dd 0
endg
EV_SPACE = 512
FreeEvents = event_start-EVENT.fd ; "âèðòóàëüíûé" event, èñïîëüçóþòñÿ òîëüêî ïîëÿ:
; FreeEvents.fd=event_start è FreeEvents.bk=event_end
align 4
init_events: ;; used from kernel.asm
stdcall kernel_alloc,EV_SPACE*EVENT.size
or eax,eax
jz .fail
; eax - current event, ebx - previos event below
mov ecx,EV_SPACE ; current - in allocated space
mov ebx,FreeEvents ; previos - íà÷àëî ñïèñêà
push ebx ; îíî æå è êîíåö ïîòîì áóäåò
@@: mov [ebx+EVENT.fd],eax
mov [eax+EVENT.bk],ebx
mov ebx,eax ; previos <- current
add eax,EVENT.size ; new current
loop @b
pop eax ; âîò îíî êîíöîì è ñòàëî
mov [ebx+EVENT.fd],eax
mov [eax+EVENT.bk],ebx
.fail: ret
 
EVENT_WATCHED equ 0x10000000 ;áèò 28
EVENT_SIGNALED equ 0x20000000 ;áèò 29
MANUAL_RESET equ 0x40000000 ;áèò 30
MANUAL_DESTROY equ 0x80000000 ;áèò 31
 
align 4
create_event: ;; EXPORT use
;info:
; Ïåðåíîñèì EVENT èç ñïèñêà FreeEvents â ñïèñîê ObjList òåêóùåãî ñëîòà
; EVENT.state óñòàíàâëèâàåì èç ecx, EVENT.code êîñâåííî èç esi (åñëè esi<>0)
;param:
; esi - event data
; ecx - flags
;retval:
; eax - event (=0 => fail)
; edx - uid
;scratched: ebx,ecx,esi,edi
mov ebx,[current_slot]
add ebx,APP_OBJ_OFFSET
mov edx,[TASK_BASE]
mov edx,[edx+TASKDATA.pid]
pushfd
cli
 
set_event: ;; INTERNAL use !!! don't use for Call
;info:
; Áåðåì íîâûé event èç FreeEvents, çàïîëíÿåì åãî ïîëÿ, êàê óêàçàíî â ecx,edx,esi
; è óñòàíàâëèâàåì â ñïèñîê, óêàçàííûé â ebx.
; Âîçâðàùàåì ñàì event (â eax), è åãî uid (â edx)
;param:
; ebx - start-chain "virtual" event for entry new event Right of him
; ecx - flags (copied to EVENT.state)
; edx - pid (copied to EVENT.pid)
; esi - event data (copied to EVENT.code indirect, =0 => skip)
;retval:
; eax - event (=0 => fail)
; edx - uid
;scratched: ebx,ecx,esi,edi
mov eax,FreeEvents
cmp eax,[eax+EVENT.fd]
jne @f ; not empty ???
pushad
call init_events
popad
jz RemoveEventTo.break ; POPF+RET
@@: mov eax,[eax+EVENT.fd]
mov [eax+EVENT.magic],'EVNT'
mov [eax+EVENT.destroy],destroy_event.internal
mov [eax+EVENT.state],ecx
mov [eax+EVENT.pid],edx
inc [event_uid]
Mov [eax+EVENT.id],edx,[event_uid]
or esi,esi
jz RemoveEventTo
lea edi,[eax+EVENT.code]
mov ecx,EVENT.codesize/4
cld
rep movsd
 
RemoveEventTo: ;; INTERNAL use !!! don't use for Call
;param:
; eax - óêàçàòåëü íà event, ÊÎÒÎÐÛÉ âñòàâëÿåì
; ebx - óêàçàòåëü íà event, ÏÎÑËÅ êîòîðîãî âñòàâëÿåì
;scratched: ebx,ecx
mov ecx,eax ; ecx=eax=Self, ebx=NewLeft
xchg ecx,[ebx+EVENT.fd] ; NewLeft.fd=Self, ecx=NewRight
cmp eax,ecx ; ñòîï, ñåáå äóìàþ...
je .break ; - à íå äóðàê ëè ÿ?
mov [ecx+EVENT.bk],eax ; NewRight.bk=Self
xchg ebx,[eax+EVENT.bk] ; Self.bk=NewLeft, ebx=OldLeft
xchg ecx,[eax+EVENT.fd] ; Self.fd=NewRight, ecx=OldRight
mov [ebx+EVENT.fd],ecx ; OldLeft.fd=OldRight
mov [ecx+EVENT.bk],ebx ; OldRight.bk=OldLeft
.break: popfd
ret
 
align 4
NotDummyTest: ;; INTERNAL use (not returned for fail !!!)
pop edi
call DummyTest ; not returned for fail !!!
mov ebx,eax
mov eax,[ebx+EVENT.pid]
push edi
.small: ; êðèâî êàê-òî...
pop edi
pushfd
cli
call pid_to_slot ; saved all registers (eax - retval)
shl eax,8
jz RemoveEventTo.break ; POPF+RET
jmp edi ; øòàòíûé âîçâðàò
 
align 4
raise_event: ;; EXPORT use
;info:
; Óñòàíàâëèâàåì äàííûå EVENT.code
; Åñëè òàì ôëàã EVENT_SIGNALED óæå àêòèâåí - áîëüøå íè÷åãî
; Èíà÷å: ýòîò ôëàã âçâîäèòñÿ, çà èñêëþ÷åíèåì ñëó÷àÿ íàëè÷èÿ ôëàãà EVENT_WATCHED â edx
;  ýòîì ñëó÷àå EVENT_SIGNALED âçâîäèòñÿ ëèøü ïðè íàëè÷èå EVENT_WATCHED â ñàìîì ñîáûòèè
;param:
; eax - event
; ebx - uid (for Dummy testing)
; edx - flags
; esi - event data (=0 => skip)
;scratched: ebx,ecx,esi,edi
call NotDummyTest ; not returned for fail !!!
or esi,esi
jz @f
lea edi,[ebx+EVENT.code]
mov ecx,EVENT.codesize/4
cld
rep movsd
@@:
test byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24
jnz RemoveEventTo.break ; POPF+RET
bt edx, 28 ;EVENT_WATCHED
jnc @f
test byte[ebx+EVENT.state+3], EVENT_WATCHED shr 24
jz RemoveEventTo.break ; POPF+RET
@@:
or byte[ebx+EVENT.state+3], EVENT_SIGNALED shr 24
add eax,SLOT_BASE+APP_EV_OFFSET
xchg eax,ebx
jmp RemoveEventTo
 
align 4
clear_event: ;; EXPORT use
;info:
;
;param:
; eax - event
; ebx - uid (for Dummy testing)
;scratched: ebx,ecx
call NotDummyTest ; not returned for fail !!!
add eax,SLOT_BASE+APP_OBJ_OFFSET
and byte[ebx+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24)
xchg eax,ebx
jmp RemoveEventTo
 
align 4
send_event: ;; EXPORT use
;info:
; Ñîçäàåò íîâûé EVENT (âûòàñêèâàåò èç ñïèñêà FreeEvents) â ñïèñêå EventList
; öåëåâîãî ñëîòà (eax=pid), ñ äàííûìè èç esi êîñâåííî, è state=EVENT_SIGNALED
;param:
; eax - slots pid, to sending new event
; esi - pointer to sending data (in code field of new event)
;retval:
; eax - event (=0 => fail)
; edx - uid
;warning:
; may be used as CDECL with such prefix...
; mov esi,[esp+8]
; mov eax,[esp+4]
; but not as STDCALL :(
;scratched: ebx,ecx,esi,edi
mov edx,eax
call NotDummyTest.small ; not returned for fail !!!
lea ebx,[eax+SLOT_BASE+APP_EV_OFFSET]
mov ecx,EVENT_SIGNALED
jmp set_event
 
align 4
DummyTest: ;; INTERNAL use (not returned for fail !!!)
;param:
; eax - event
; ebx - uid (for Dummy testing)
cmp [eax+EVENT.magic],'EVNT'
jne @f
cmp [eax+EVENT.id],ebx
je .ret
@@: pop eax
xor eax,eax
.ret: ret
 
 
align 4
Wait_events:
or ebx,-1 ; infinite timeout
Wait_events_ex:
;info:
; Îæèäàíèå "àáñòðàêòíîãî" ñîáûòèÿ ÷åðåç ïåðåâîä ñëîòà â 5-þ ïîçèöèþ.
; Àáñòðàêòíîñòü çàêëþ÷åíà â òîì, ÷òî ôàêò ñîáûòèÿ îïðåäåëÿåòñÿ ôóíêöèåé APPDATA.wait_test,
; êîòîðàÿ çàäàåòñÿ êëèåíòîì è ìîæåò áûòü ôàêòè÷åñêè ëþáîé.
; Ýòî ïîçâîëÿåò shed-ó íàäåæíî îïðåäåëèòü ôàêò ñîáûòèÿ, è íå ñîâåðøàòü "õîëîñòûõ" ïåðåêëþ÷åíèé,
; ïðåäíàçíà÷åííûõ äëÿ ðàçáîðîê òèïà "ñâîé/÷óæîé" âíóòðè çàäà÷è.
;param:
; edx - wait_test, êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ (àäðåñ êîäà)
; ecx - wait_param, äîïîëíèòåëüíûé ïàðàìåòð, âîçìîæíî íåîáõîäèìûé äëÿ [wait_test]
; ebx - wait_timeout
;retval:
; eax - ðåçóëüòàò âûçîâà [wait_test] (=0 => timeout)
;scratched: esi
mov esi,[current_slot]
mov [esi+APPDATA.wait_param],ecx
pushad
mov ebx,esi;ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü..........
pushfd ; ýòî ñëåäñòâèå îáùåé êîíöåïöèè: ïóñòü ô-ÿ òåñòèðîâàíèÿ èìååò
cli ; ïðàâî ðàññ÷èòûâàòü íà çàêðûòûå ïðåðûâàíèÿ, êàê ïðè âûçîâå èç shed
call edx
popfd
mov [esp+28],eax
popad
or eax,eax
jnz @f ;RET
mov [esi+APPDATA.wait_test],edx
mov [esi+APPDATA.wait_timeout],ebx
Mov [esi+APPDATA.wait_begin],eax,[timer_ticks]
mov eax,[TASK_BASE]
mov [eax+TASKDATA.state], 5
call change_task
mov eax,[esi+APPDATA.wait_param]
@@: ret
 
align 4
wait_event: ;; EXPORT use
;info:
; Îæèäàíèå ôëàãà EVENT_SIGNALED â ñîâåðøåííî êîíêðåòíîì Event
; (óñòàíàâëèâàåìîãî, íàäî ïîëàãàòü, ÷åðåç raise_event)
; Ïðè àêòèâíîì ôëàãå MANUAL_RESET - áîëüøå íè÷åãî
; Èíà÷å: ôëàãè EVENT_SIGNALED è EVENT_WATCHED ó ïîëó÷åííîãî ñîáûòèÿ ñáðàñûâàþòñÿ,
; è, ïðè àêòèâíîì MANUAL_DESTROY - ïåðåìåùàåòñÿ â ñïèñîê ObjList òåêóùåãî ñëîòà,
; à ïðè íå àêòèâíîì - óíè÷òîæàåòñÿ øòàòíî (destroy_event.internal)
;param:
; eax - event
; ebx - uid (for Dummy testing)
;scratched: ecx,edx,esi
call DummyTest
mov ecx,eax ; wait_param
mov edx, get_event_alone ; wait_test
call Wait_events ; timeout ignored
jmp wait_finish
 
align 4
get_event_ex: ;; f68:14
;info:
; Îæèäàíèå ëþáîãî ñîáûòèÿ â î÷åðåäè EventList òåêóùåãî ñëîòà
; Äàííûå ñîáûòèÿ code - êîïèðóþòñÿ â ïàìÿòü ïðèëîæåíèÿ (êîñâåííî ïî edi)
; Ïðè àêòèâíîì ôëàãå MANUAL_RESET - áîëüøå íè÷åãî
; Èíà÷å: ôëàãè EVENT_SIGNALED è EVENT_WATCHED ó ïîëó÷åííîãî ñîáûòèÿ ñáðàñûâàþòñÿ,
; è, ïðè àêòèâíîì MANUAL_DESTROY - ïåðåìåùàåòñÿ â ñïèñîê ObjList òåêóùåãî ñëîòà,
; à ïðè íå àêòèâíîì - óíè÷òîæàåòñÿ øòàòíî (destroy_event.internal)
;param:
; edi - àäðåñ â êîäå ïðèëîæåíèÿ äëÿ êîïèðîâàíèÿ äàííûõ èç EVENT.code
;retval:
; eax - ñîáñòâåííî EVENT (áóäåì íàçûâàòü ýòî åãî õýíäëîì)
;scratched: ebx,ecx,edx,esi,edi
mov edx, get_event_queue ; wait_test
call Wait_events ; timeout ignored
lea esi,[eax+EVENT.code]
mov ecx,EVENT.codesize/4
cld
rep movsd
mov [edi-EVENT.codesize+2],cl ;clear priority field
wait_finish:
test byte[eax+EVENT.state+3], MANUAL_RESET shr 24
jnz get_event_queue.ret ; RET
and byte[eax+EVENT.state+3], not((EVENT_SIGNALED+EVENT_WATCHED)shr 24)
test byte[eax+EVENT.state+3], MANUAL_DESTROY shr 24
jz destroy_event.internal
mov ebx,[current_slot]
add ebx,APP_OBJ_OFFSET
pushfd
cli
jmp RemoveEventTo
 
align 4
destroy_event: ;; EXPORT use
;info:
; Ïåðåíîñèì EVENT â ñïèñîê FreeEvents, ÷èñòèì ïîëÿ magic,destroy,pid,id
;param:
; eax - event
; ebx - uid (for Dummy testing)
;retval:
; eax - àäðåñ îáúåêòà EVENT (=0 => fail)
;scratched: ebx,ecx
call DummyTest ; not returned for fail !!!
.internal:
xor ecx,ecx ; clear common header
pushfd
cli
mov [eax+EVENT.magic],ecx
mov [eax+EVENT.destroy],ecx
mov [eax+EVENT.pid],ecx
mov [eax+EVENT.id],ecx
mov ebx,FreeEvents
jmp RemoveEventTo
 
align 4
get_event_queue:
;info:
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ get_event_ex
;warning:
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot
; -may be assumed, that interrupt are disabled
; -it is not restriction for scratched registers
;param:
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ
;retval:
; eax - àäðåñ îáúåêòà EVENT (=0 => fail)
add ebx,APP_EV_OFFSET
mov eax,[ebx+APPOBJ.bk] ; âûáèðàåì ñ êîíöà, ïî ïðèíöèïó FIFO
cmp eax,ebx ; empty ???
je get_event_alone.ret0
.ret: ret
 
align 4
get_event_alone:
;info:
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ wait_event
;warning:
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot
; -may be assumed, that interrupt are disabled
; -it is not restriction for scratched registers
;param:
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ
;retval:
; eax - àäðåñ îáúåêòà EVENT (=0 => fail)
mov eax,[ebx+APPDATA.wait_param]
test byte[eax+EVENT.state+3], EVENT_SIGNALED shr 24
jnz .ret
or byte[eax+EVENT.state+3], EVENT_WATCHED shr 24
.ret0: xor eax,eax ; NO event!!!
.ret: ret
 
align 4
sys_sendwindowmsg: ;; f72
dec ebx
jnz .ret ;subfunction==1 ?
;pushfd ;à íàôèãà?
cli
sub ecx,2
je .sendkey
dec ecx
jnz .retf
.sendbtn:
cmp byte[BTN_COUNT],1
jae .result ;overflow
inc byte[BTN_COUNT]
shl edx, 8
mov [BTN_BUFF],edx
jmp .result
.sendkey:
movzx eax,byte[KEY_COUNT]
cmp al,120
jae .result ;overflow
inc byte[KEY_COUNT]
mov [KEY_COUNT+1+eax],dl
.result:
setae byte[esp+32] ;ñ÷èòàåì, ÷òî èñõîäíî: dword[esp+32]==72
.retf: ;popfd
.ret: ret
 
align 4
sys_getevent: ;; f11
mov ebx,[current_slot] ;ïîêà ýòî âîïðîñ, ÷åãî êóäû ñóâàòü..........
pushfd ; ýòî ñëåäñòâèå îáùåé êîíöåïöèè: ïóñòü ô-ÿ òåñòèðîâàíèÿ èìååò
cli ; ïðàâî ðàññ÷èòûâàòü íà çàêðûòûå ïðåðûâàíèÿ, êàê ïðè âûçîâå èç shed
call get_event_for_app
popfd
mov [esp+32],eax
ret
 
align 4
sys_waitforevent: ;; f10
or ebx,-1 ; infinite timeout
sys_wait_event_timeout: ;; f23
mov edx,get_event_for_app ; wait_test
call Wait_events_ex ; ebx - timeout
mov [esp+32],eax
ret
 
align 4
get_event_for_app: ;; used from f10,f11,f23
;info:
; êëèåíòñêàÿ ô-ÿ òåñòèðîâàíèÿ äëÿ ïðèëîæåíèé (f10,f23)
;warning:
; -don't use [TASK_BASE],[current_slot],[CURRENT_TASK] - it is not for your slot
; -may be assumed, that interrupt are disabled
; -it is not restriction for scratched registers
;param:
; ebx - àäðåñ APPDATA ñëîòà òåñòèðîâàíèÿ
;retval:
; eax - íîìåð ñîáûòèÿ (=0 => no events)
movzx edi,bh ; bh is assumed as [CURRENT_TASK]
shl edi,5
add edi,CURRENT_TASK ; edi is assumed as [TASK_BASE]
mov ecx,[edi+TASKDATA.event_mask]
.loop: ; ïîêà íå èñ÷åðïàåì âñå áèòû ìàñêè
bsr eax,ecx ; íàõîäèì íåíóëåâîé áèò ìàñêè (31 -> 0)
jz .no_events ; èñ÷åðïàëè âñå áèòû ìàñêè, íî íè÷åãî íå íàøëè ???
btr ecx,eax ; ñáðàñûâàåì ïðîâåðÿåìûé áèò ìàñêè
; ïåðåõîäèì íà îáðàáîò÷èê ýòîãî (eax) áèòà
cmp eax,16
jae .IRQ ; eax=[16..31]=retvals, events irq0..irq15
cmp eax,9
jae .loop ; eax=[9..15], ignored
cmp eax,3
je .loop ; eax=3, ignored
ja .FlagAutoReset ; eax=[4..8], retvals=eax+1
cmp eax,1
jae .BtKy ; eax=[1,2], retvals=eax+1
.WndRedraw: ; eax=0, retval WndRedraw=1
cmp [edi-twdw+WDATA.fl_redraw],al ;al==0
jne .result
jmp .loop
.no_events:
xor eax,eax
ret
.IRQ:
;TODO: ñäåëàòü òàê æå, êàê è äëÿ FlagAutoReset (BgrRedraw,Mouse,IPC,Stack,Debug)
mov edx,[irq_owner+eax*4-64] ; eax==16+irq
cmp edx,[edi+TASKDATA.pid]
jne .loop
mov edx,eax
shl edx,12
cmp dword[IRQ_SAVE+edx-0x10000],0 ; edx==(16+irq)*0x1000
je .loop ; empty ???
ret ; retval = eax
.FlagAutoReset: ; retvals: BgrRedraw=5, Mouse=6, IPC=7, Stack=8, Debug=9
cmp eax,5 ; Mouse 5+1=6
jne @f
push eax
; If the window is captured and moved by the user, then no mouse events!!!
mov al,[mouse.active_sys_window.action]
and al,WINDOW_MOVE_AND_RESIZE_FLAGS
test al,al
pop eax
jnz .loop
@@:
btr [ebx+APPDATA.event_mask],eax
jnc .loop
.result: ; retval = eax+1
inc eax
ret
.BtKy:
movzx edx,bh
movzx edx, word[WIN_STACK+edx*2]
je .Keys ; eax=1, retval Keys=2
.Buttons: ; eax=2, retval Buttons=3
cmp byte[BTN_COUNT],0
je .loop ; empty ???
cmp edx,[TASK_COUNT]
jne .loop ; not Top ???
mov edx, [BTN_BUFF]
shr edx, 8
cmp edx, 0xFFFF ;-ID for Minimize-Button of Form
jne .result
mov [window_minimize],1
dec byte[BTN_COUNT]
jmp .loop
.Keys: ; eax==1
cmp edx,[TASK_COUNT]
jne @f ; not Top ???
cmp [KEY_COUNT],al ; al==1
jae .result ; not empty ???
@@: mov edx, hotkey_buffer
@@: cmp [edx],bh ; bh - slot for testing
je .result
add edx,8
cmp edx, hotkey_buffer+120*8
jb @b
jmp .loop
;end.
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/gui/button.inc
0,0 → 1,494
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
;==============================================================================
;///// public functions ///////////////////////////////////////////////////////
;==============================================================================
 
button.MAX_BUTTONS = 4095
 
struc SYS_BUTTON
{
.pslot dw ?
.id_lo dw ?
.left dw ?
.width dw ?
.top dw ?
.height dw ?
.id_hi dw ?
dw ?
.sizeof:
}
virtual at 0
SYS_BUTTON SYS_BUTTON
end virtual
 
align 4
;------------------------------------------------------------------------------
syscall_button: ;///// system function 8 //////////////////////////////////////
;------------------------------------------------------------------------------
;? Define/undefine GUI button object
;------------------------------------------------------------------------------
;; Define button:
;> ebx = pack[16(x), 16(width)]
;> ecx = pack[16(y), 16(height)]
;> edx = pack[8(flags), 24(button identifier)]
;> flags bits:
;> 7 (31) = 0
;> 6 (30) = don't draw button
;> 5 (29) = don't draw button frame when pressed
;> esi = button color
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;; Undefine button:
;> edx = pack[8(flags), 24(button identifier)]
;> flags bits:
;> 7 (31) = 1
;------------------------------------------------------------------------------
; do we actually need to undefine the button?
test edx, 0x80000000
jnz .remove_button
 
; do we have free button slots available?
mov edi, [BTN_ADDR]
mov eax, [edi]
cmp eax, button.MAX_BUTTONS
jge .exit
 
; does it have positive size? (otherwise it doesn't have sense)
or bx, bx
jle .exit
or cx, cx
jle .exit
 
; make coordinates clientbox-relative
push eax
mov eax, [current_slot]
rol ebx, 16
add bx, word[eax + APPDATA.wnd_clientbox.left]
rol ebx, 16
rol ecx, 16
add cx, word[eax + APPDATA.wnd_clientbox.top]
rol ecx, 16
pop eax
 
; basic checks passed, define the button
push ebx ecx edx
inc eax
mov [edi], ax
shl eax, 4
add edi, eax
; NOTE: this code doesn't rely on SYS_BUTTON struct, please revise it
; if you change something
mov ax, [CURRENT_TASK]
stosw
mov ax, dx
stosw ; button id number: bits 0-15
mov eax, ebx
rol eax, 16
stosd ; x start | x size
mov eax, ecx
rol eax, 16
stosd ; y start | y size
mov eax, edx
shr eax, 16
stosw ; button id number: bits 16-31
pop edx ecx ebx
 
; do we also need to draw the button?
test edx, 0x40000000
jnz .exit
 
; draw button body
 
pushad
 
; calculate window-relative coordinates
movzx edi, cx
shr ebx, 16
shr ecx, 16
mov eax, [TASK_BASE]
add ebx, [eax - twdw + WDATA.box.left]
add ecx, [eax - twdw + WDATA.box.top]
mov eax, ebx
shl eax, 16
mov ax, bx
add ax, word[esp + 16]
mov ebx, ecx
shl ebx, 16
mov bx, cx
 
; calculate initial color
mov ecx, esi
cmp [buttontype], 0
je @f
call button._.incecx2
 
; set button height counter
@@: mov edx, edi
 
.next_line:
call button._.button_dececx
push edi
xor edi, edi
call [draw_line]
pop edi
add ebx, 0x00010001
dec edx
jnz .next_line
 
popad
 
; draw button frame
 
push ebx ecx
 
; calculate window-relative coordinates
shr ebx, 16
shr ecx, 16
mov eax, [TASK_BASE]
add ebx, [eax - twdw + WDATA.box.left]
add ecx, [eax - twdw + WDATA.box.top]
 
; top border
mov eax, ebx
shl eax, 16
mov ax, bx
add ax, [esp + 4]
mov ebx, ecx
shl ebx, 16
mov bx, cx
push ebx
xor edi, edi
mov ecx, esi
call button._.incecx
call [draw_line]
 
; bottom border
movzx edx, word[esp + 4 + 0]
add ebx, edx
shl edx, 16
add ebx, edx
mov ecx, esi
call button._.dececx
call [draw_line]
 
; left border
pop ebx
push edx
mov edx, eax
shr edx, 16
mov ax, dx
mov edx, ebx
shr edx, 16
mov bx, dx
add bx, [esp + 4 + 0]
pop edx
mov ecx, esi
call button._.incecx
call [draw_line]
 
; right border
mov dx, [esp + 4]
add ax, dx
shl edx, 16
add eax, edx
add ebx, 0x00010000
mov ecx, esi
call button._.dececx
call [draw_line]
 
pop ecx ebx
 
.exit:
ret
 
; FIXME: mutex needed
syscall_button.remove_button:
and edx, 0x00ffffff
mov edi, [BTN_ADDR]
mov ebx, [edi]
inc ebx
imul esi, ebx, SYS_BUTTON.sizeof
add esi, edi
xor ecx, ecx
add ecx, -SYS_BUTTON.sizeof
add esi, SYS_BUTTON.sizeof
 
.next_button:
dec ebx
jz .exit
 
add ecx, SYS_BUTTON.sizeof
add esi, -SYS_BUTTON.sizeof
 
; does it belong to our process?
mov ax, [CURRENT_TASK]
cmp ax, [esi + SYS_BUTTON.pslot]
jne .next_button
 
; does the identifier match?
mov eax, dword[esi + SYS_BUTTON.id_hi - 2]
mov ax, [esi + SYS_BUTTON.id_lo]
and eax, 0x00ffffff
cmp edx, eax
jne .next_button
 
; okay, undefine it
push ebx
mov ebx, esi
lea eax, [esi + SYS_BUTTON.sizeof]
call memmove
dec dword[edi]
add ecx, -SYS_BUTTON.sizeof
pop ebx
jmp .next_button
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
sys_button_activate_handler: ;/////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = pack[8(process slot), 24(button id)]
;> ebx = pack[16(button x coord), 16(button y coord)]
;> cl = mouse button mask this system button was pressed with
;------------------------------------------------------------------------------
call button._.find_button
or eax, eax
jz .exit
 
mov ebx, dword[eax + SYS_BUTTON.id_hi - 2]
call button._.negative_button
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
sys_button_deactivate_handler: ;///////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = pack[8(process slot), 24(button id)]
;> ebx = pack[16(button x coord), 16(button y coord)]
;> cl = mouse button mask this system button was pressed with
;------------------------------------------------------------------------------
call button._.find_button
or eax, eax
jz .exit
 
mov ebx, dword[eax + SYS_BUTTON.id_hi - 2]
call button._.negative_button
 
.exit:
ret
 
align 4
;------------------------------------------------------------------------------
sys_button_perform_handler: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = pack[8(process slot), 24(button id)]
;> ebx = pack[16(button x coord), 16(button y coord)]
;> cl = mouse button mask this system button was pressed with
;------------------------------------------------------------------------------
shl eax, 8
mov al, cl
movzx ebx, byte[BTN_COUNT]
mov [BTN_BUFF + ebx * 4], eax
inc bl
mov [BTN_COUNT], bl
ret
 
;==============================================================================
;///// private functions //////////////////////////////////////////////////////
;==============================================================================
 
;------------------------------------------------------------------------------
button._.find_button: ;////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Find system button by specified process slot, id and coordinates
;------------------------------------------------------------------------------
;> eax = pack[8(process slot), 24(button id)] or 0
;> ebx = pack[16(button x coord), 16(button y coord)]
;------------------------------------------------------------------------------
;< eax = pointer to SYS_BUTTON struct or 0
;------------------------------------------------------------------------------
push ecx edx esi edi
 
mov edx, eax
shr edx, 24
and eax, 0x0ffffff
 
mov edi, [BTN_ADDR]
mov ecx, [edi]
imul esi, ecx, SYS_BUTTON.sizeof
add esi, edi
inc ecx
add esi, SYS_BUTTON.sizeof
 
.next_button:
dec ecx
jz .not_found
 
add esi, -SYS_BUTTON.sizeof
 
; does it belong to our process?
cmp dx, [esi + SYS_BUTTON.pslot]
jne .next_button
 
; does id match?
mov edi, dword[esi + SYS_BUTTON.id_hi - 2]
mov di, [esi + SYS_BUTTON.id_lo]
and edi, 0x0ffffff
cmp eax, edi
jne .next_button
 
; does coordinates match?
mov edi, dword[esi + SYS_BUTTON.left - 2]
mov di, [esi + SYS_BUTTON.top]
cmp ebx, edi
jne .next_button
 
; okay, return it
mov eax, esi
jmp .exit
 
.not_found:
xor eax, eax
 
.exit:
pop edi esi edx ecx
ret
 
;------------------------------------------------------------------------------
button._.dececx: ;/////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
sub cl, 0x20
jnc @f
xor cl, cl
@@: sub ch, 0x20
jnc @f
xor ch, ch
@@: rol ecx, 16
sub cl, 0x20
jnc @f
xor cl, cl
@@: rol ecx, 16
ret
 
;------------------------------------------------------------------------------
button._.incecx: ;/////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
add cl, 0x20
jnc @f
or cl, -1
@@: add ch, 0x20
jnc @f
or ch, -1
@@: rol ecx, 16
add cl, 0x20
jnc @f
or cl, -1
@@: rol ecx, 16
ret
 
;------------------------------------------------------------------------------
button._.incecx2: ;////////////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
add cl, 0x14
jnc @f
or cl, -1
@@: add ch, 0x14
jnc @f
or ch, -1
@@: rol ecx, 16
add cl, 0x14
jnc @f
or cl, -1
@@: rol ecx, 16
ret
 
;------------------------------------------------------------------------------
button._.button_dececx: ;//////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
cmp [buttontype], 1
jne .finish
 
push eax
mov al, 1
cmp edi, 20
jg @f
mov al, 2
 
@@: sub cl, al
jnc @f
xor cl, cl
@@: sub ch, al
jnc @f
xor ch, ch
@@: rol ecx, 16
sub cl, al
jnc @f
xor cl, cl
@@: rol ecx, 16
 
pop eax
 
.finish:
ret
 
;------------------------------------------------------------------------------
button._.negative_button: ;////////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Invert system button border
;------------------------------------------------------------------------------
; if requested, do not display button border on press.
test ebx, 0x20000000
jnz .exit
 
pushad
 
xchg esi, eax
 
movzx ecx, [esi + SYS_BUTTON.pslot]
shl ecx, 5
add ecx, window_data
 
mov eax, dword[esi + SYS_BUTTON.left]
mov ebx, dword[esi + SYS_BUTTON.top]
add eax, [ecx + WDATA.box.left]
add ebx, [ecx + WDATA.box.top]
push eax ebx
pop edx ecx
rol eax, 16
rol ebx, 16
add ax, cx
add bx, dx
 
mov esi, 0x01000000
call draw_rectangle.forced
 
popad
 
.exit:
ret
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/gui/mousepointer.inc
0,0 → 1,250
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
iglobal
 
align 4
mousepointer:
db 0x00,0x00,0x00,0x74,0x74,0x74,0x6e,0x6e,0x6e,0x6f
db 0x6f,0x6f,0x71,0x71,0x71,0x75,0x75,0x75,0x79,0x79
db 0x79,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0
db 0xc0,0xc0,0x00,0x00,0x00,0x54,0x54,0x54,0x57,0x57
db 0x57,0x5f,0x5f,0x5f,0x68,0x68,0x68,0x71,0x71,0x71
db 0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x47,0x47,0x47,0x50
db 0x50,0x50,0x5b,0x5b,0x5b,0x67,0x67,0x67,0x70,0x70
db 0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3f,0x3f,0x3f
db 0x4b,0x4b,0x4b,0x59,0x59,0x59,0x66,0x66,0x66,0x70
db 0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e
db 0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3a,0x3a
db 0x3a,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66,0x66
db 0x70,0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e
db 0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x39
db 0x39,0x39,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66
db 0x66,0x71,0x71,0x71,0x78,0x78,0x78,0x7c,0x7c,0x7c
db 0x7e,0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0xff
db 0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00
db 0x39,0x39,0x39,0x4a,0x4a,0x4a,0x5a,0x5a,0x5a,0x68
db 0x68,0x68,0x72,0x72,0x72,0x79,0x79,0x79,0x7d,0x7d
db 0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00
db 0x00,0x3c,0x3c,0x3c,0x4e,0x4e,0x4e,0x5e,0x5e,0x5e
db 0x6b,0x6b,0x6b,0x75,0x75,0x75,0x7a,0x7a,0x7a,0x7e
db 0x7e,0x7e,0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00
db 0x00,0x00,0x43,0x43,0x43,0x55,0x55,0x55,0x64,0x64
db 0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d
db 0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0
db 0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x4e,0x4e,0x4e,0x5f,0x5f,0x5f,0x6d
db 0x6d,0x6d,0x76,0x76,0x76,0x7c,0x7c,0x7c,0x80,0x80
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x14
db 0x14,0x14,0x1b,0x1b,0x1b,0x29,0x29,0x29,0x3a,0x3a
db 0x3a,0x4c,0x4c,0x4c,0x5d,0x5d,0x5d,0x6c,0x6c,0x6c
db 0x75,0x75,0x75,0x7b,0x7b,0x7b,0x80,0x80,0x80,0xc0
db 0xc0,0xc0,0x00,0x00,0x00,0x2f,0x2f,0x2f,0x80,0x80
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00
db 0x21,0x21,0x21,0x2e,0x2e,0x2e,0x40,0x40,0x40,0x52
db 0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f,0x77,0x77
db 0x77,0x7c,0x7c,0x7c,0x80,0x80,0x80,0x00,0x00,0x00
db 0x47,0x47,0x47,0x3b,0x3b,0x3b,0x80,0x80,0x80,0xff
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x25,0x25
db 0x25,0x30,0x30,0x30,0x42,0x42,0x42,0x54,0x54,0x54
db 0x64,0x64,0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d
db 0x7d,0x7d,0x00,0x00,0x00,0x62,0x62,0x62,0x52,0x52
db 0x52,0x4a,0x4a,0x4a,0x43,0x43,0x43,0x80,0x80,0x80
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x33
db 0x33,0x33,0x42,0x42,0x42,0x54,0x54,0x54,0x64,0x64
db 0x64,0x71,0x71,0x71,0x79,0x79,0x79,0x7d,0x7d,0x7d
db 0x72,0x72,0x72,0x6b,0x6b,0x6b,0x5f,0x5f,0x5f,0x5a
db 0x5a,0x5a,0x54,0x54,0x54,0x80,0x80,0x80,0xff,0xff
db 0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x35,0x35,0x35
db 0x41,0x41,0x41,0x53,0x53,0x53,0x63,0x63,0x63,0x70
db 0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d,0x77,0x77
db 0x77,0x73,0x73,0x73,0x6c,0x6c,0x6c,0x68,0x68,0x68
db 0x62,0x62,0x62,0x5a,0x5a,0x5a,0x80,0x80,0x80,0xff
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x41,0x41
db 0x41,0x52,0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f
db 0x78,0x78,0x78,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x79
db 0x79,0x79,0x74,0x74,0x74,0x72,0x72,0x72,0x6e,0x6e
db 0x6e,0x66,0x66,0x66,0x80,0x80,0x80,0xc0,0xc0,0xc0
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x44,0x44,0x44,0x52
db 0x52,0x52,0x62,0x62,0x62,0x6e,0x6e,0x6e,0x77,0x77
db 0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7c,0x7c,0x7c
db 0x7a,0x7a,0x7a,0x79,0x79,0x79,0x75,0x75,0x75,0x6f
db 0x6f,0x6f,0x65,0x65,0x65,0x00,0x00,0x00,0x00,0x00
db 0x00,0x48,0x48,0x48,0x4b,0x4b,0x4b,0x56,0x56,0x56
db 0x65,0x65,0x65,0x70,0x70,0x70,0x78,0x78,0x78,0x7d
db 0x7d,0x7d,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e
db 0x7e,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76,0x76
db 0x6f,0x6f,0x6f,0x65,0x65,0x65,0x5c,0x5c,0x5c,0x56
db 0x56,0x56,0x58,0x58,0x58,0x60,0x60,0x60,0x6b,0x6b
db 0x6b,0x73,0x73,0x73,0x7a,0x7a,0x7a,0x7d,0x7d,0x7d
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f
db 0x7f,0x7f,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76
db 0x76,0x70,0x70,0x70,0x6a,0x6a,0x6a,0x66,0x66,0x66
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x77
db 0x77,0x77,0x73,0x73,0x73,0x71,0x71,0x71,0x71,0x71
db 0x71,0x74,0x74,0x74,0x78,0x78,0x78,0x7b,0x7b,0x7b
db 0x7d,0x7d,0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7c,0x7c,0x7c
db 0x7a,0x7a,0x7a,0x78,0x78,0x78,0x78,0x78,0x78,0x7a
db 0x7a,0x7a,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7f,0x7f
db 0x7f,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
db 0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7e,0x7e
db 0x7e,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e
db 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80
db 0x80,0x80
 
mousepointer1:
db 0xff,0xff,0xff,0x06,0x06,0x06,0x0a,0x0a
db 0x0a,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0xff,0xff,0xff,0xff,0xff,0xff,0x19,0x19,0x19,0x16
db 0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2e,0x2e,0x2e
db 0x23,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x3f
db 0x3f,0x29,0x29,0x29,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47
db 0x47,0x47,0x2c,0x2c,0x2c,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0x47,0x47,0x47,0x29,0x29,0x29
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0x40,0x40,0x40,0x23,0x23
db 0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xaa,0xaa,0xaa,0x9f,0x9f,0x9f,0x8c,0x8c,0x8c
db 0x70,0x70,0x70,0x4f,0x4f,0x4f,0x30,0x30,0x30,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8f,0x8f,0x8f
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0x9c,0x9c,0x9c,0x87,0x87,0x87,0x6c,0x6c
db 0x6c,0x4f,0x4f,0x4f,0x32,0x32,0x32,0x19,0x19,0x19
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff
db 0xff,0xff,0x69,0x69,0x69,0x84,0x84,0x84,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x92,0x92,0x92,0x79,0x79,0x79,0x59,0x59,0x59,0x3c
db 0x3c,0x3c,0x24,0x24,0x24,0x11,0x11,0x11,0x00,0x00
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x37,0x37,0x37
db 0x5d,0x5d,0x5d,0x70,0x70,0x70,0x76,0x76,0x76,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0x75,0x75,0x75,0x51,0x51,0x51,0x31,0x31,0x31
db 0x19,0x19,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x16,0x16,0x16,0x2d,0x2d,0x2d,0x49,0x49
db 0x49,0x53,0x53,0x53,0x54,0x54,0x54,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x78
db 0x78,0x78,0x54,0x54,0x54,0x30,0x30,0x30,0x16,0x16
db 0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x0f,0x0f,0x0f,0x1f,0x1f,0x1f,0x30,0x30,0x30,0x33
db 0x33,0x33,0x33,0x33,0x33,0x3b,0x3b,0x3b,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x62,0x62,0x62,0x3b,0x3b,0x3b,0x1c,0x1c,0x1c,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08
db 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x24,0x24,0x24,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6e,0x6e
db 0x6e,0x48,0x48,0x48,0x25,0x25,0x25,0x0e,0x0e,0x0e
db 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00
db 0x00,0x00,0x0a,0x0a,0x0a,0x09,0x09,0x09,0x00,0x00
db 0x00,0x00,0x00,0x00,0x29,0x29,0x29,0xff,0xff,0xff
db 0xff,0xff,0xff,0x7c,0x7c,0x7c,0x71,0x71,0x71,0x50
db 0x50,0x50,0x2b,0x2b,0x2b,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x02,0x02,0x02,0x04,0x04,0x04,0x00
db 0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x36,0x56,0x56
db 0x56,0x69,0x69,0x69,0x64,0x64,0x64,0x4a,0x4a,0x4a
db 0x28,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x05,0x05,0x05
db 0x00,0x00,0x00,0x21,0x21,0x21,0x39,0x39,0x39,0x49
db 0x49,0x49,0x48,0x48,0x48,0x35,0x35,0x35,0x1d,0x1d
db 0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00
db 0x00,0x00,0x00,0x00,0x1d,0x1d,0x1d,0x27,0x27,0x27
db 0x27,0x27,0x27,0x1d,0x1d,0x1d,0x0f,0x0f,0x0f,0x06
db 0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00
 
endg
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/gui/skincode.inc
0,0 → 1,460
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
include "skindata.inc"
 
;skin_data = 0x00778000
 
read_skin_file:
stdcall load_file, ebx
test eax, eax
jz .notfound
cmp dword [eax], 'SKIN'
jnz .noskin
cmp ebx, 32*1024
jb @f
mov ebx, 32*1024
@@:
lea ecx, [ebx+3]
shr ecx, 2
mov esi, eax
mov edi, skin_data
rep movsd
stdcall kernel_free, eax
 
call parse_skin_data
xor eax, eax
ret
.notfound:
xor eax, eax
inc eax
ret
.noskin:
stdcall kernel_free, eax
push 2
pop eax
ret
 
struct SKIN_HEADER
.ident dd ?
.version dd ?
.params dd ?
.buttons dd ?
.bitmaps dd ?
ends
 
struct SKIN_PARAMS
.skin_height dd ?
.margin.right dw ?
.margin.left dw ?
.margin.bottom dw ?
.margin.top dw ?
.colors.inner dd ?
.colors.outer dd ?
.colors.frame dd ?
.colors_1.inner dd ?
.colors_1.outer dd ?
.colors_1.frame dd ?
.dtp.size dd ?
.dtp.data db 40 dup (?)
ends
 
struct SKIN_BUTTONS
.type dd ?
.pos:
.left dw ?
.top dw ?
.size:
.width dw ?
.height dw ?
ends
 
struct SKIN_BITMAPS
.kind dw ?
.type dw ?
.data dd ?
ends
 
load_default_skin:
mov [_skinh],22
mov ebx,_skin_file_default
call read_skin_file
ret
 
parse_skin_data:
mov ebp,skin_data
cmp [ebp+SKIN_HEADER.ident],'SKIN'
jne .exit
 
mov edi,skin_udata
mov ecx,(skin_udata.end-skin_udata)/4
xor eax,eax
cld
rep stosd
 
mov ebx,[ebp+SKIN_HEADER.params]
add ebx,skin_data
mov eax,[ebx+SKIN_PARAMS.skin_height]
mov [_skinh],eax
mov eax,[ebx+SKIN_PARAMS.colors.inner]
mov [skin_active.colors.inner],eax
mov eax,[ebx+SKIN_PARAMS.colors.outer]
mov [skin_active.colors.outer],eax
mov eax,[ebx+SKIN_PARAMS.colors.frame]
mov [skin_active.colors.frame],eax
mov eax,[ebx+SKIN_PARAMS.colors_1.inner]
mov [skin_inactive.colors.inner],eax
mov eax,[ebx+SKIN_PARAMS.colors_1.outer]
mov [skin_inactive.colors.outer],eax
mov eax,[ebx+SKIN_PARAMS.colors_1.frame]
mov [skin_inactive.colors.frame],eax
lea esi,[ebx+SKIN_PARAMS.dtp.data]
mov edi,common_colours
mov ecx,[ebx+SKIN_PARAMS.dtp.size]
and ecx,127
rep movsb
mov eax,dword[ebx+SKIN_PARAMS.margin.right]
mov dword[_skinmargins+0],eax
mov eax,dword[ebx+SKIN_PARAMS.margin.bottom]
mov dword[_skinmargins+4],eax
 
mov ebx,[ebp+SKIN_HEADER.bitmaps]
add ebx,skin_data
.lp1: cmp dword[ebx],0
je .end_bitmaps
movzx eax,[ebx+SKIN_BITMAPS.kind]
movzx ecx,[ebx+SKIN_BITMAPS.type]
dec eax
jnz .not_left
xor eax,eax
mov edx,skin_active.left.data
or ecx,ecx
jnz @f
mov edx,skin_inactive.left.data
@@: jmp .next_bitmap
.not_left:
dec eax
jnz .not_oper
mov esi,[ebx+SKIN_BITMAPS.data]
add esi,skin_data
mov eax,[esi+0]
neg eax
mov edx,skin_active.oper.data
or ecx,ecx
jnz @f
mov edx,skin_inactive.oper.data
@@: jmp .next_bitmap
.not_oper:
dec eax
jnz .not_base
mov eax,[skin_active.left.width]
mov edx,skin_active.base.data
or ecx,ecx
jnz @f
mov eax,[skin_inactive.left.width]
mov edx,skin_inactive.base.data
@@: jmp .next_bitmap
.not_base:
add ebx,8
jmp .lp1
.next_bitmap:
mov ecx,[ebx+SKIN_BITMAPS.data]
add ecx,skin_data
mov [edx+4],eax
mov eax,[ecx+0]
mov [edx+8],eax
add ecx,8
mov [edx+0],ecx
add ebx,8
jmp .lp1
.end_bitmaps:
 
mov ebx,[ebp+SKIN_HEADER.buttons]
add ebx,skin_data
.lp2: cmp dword[ebx],0
je .end_buttons
mov eax,[ebx+SKIN_BUTTONS.type]
dec eax
jnz .not_close
mov edx,skin_btn_close
jmp .next_button
.not_close:
dec eax
jnz .not_minimize
mov edx,skin_btn_minimize
jmp .next_button
.not_minimize:
add ebx,12
jmp .lp2
.next_button:
movsx eax,[ebx+SKIN_BUTTONS.left]
mov [edx+SKIN_BUTTON.left],eax
movsx eax,[ebx+SKIN_BUTTONS.top]
mov [edx+SKIN_BUTTON.top],eax
movsx eax,[ebx+SKIN_BUTTONS.width]
mov [edx+SKIN_BUTTON.width],eax
movsx eax,[ebx+SKIN_BUTTONS.height]
mov [edx+SKIN_BUTTON.height],eax
add ebx,12
jmp .lp2
.end_buttons:
 
.exit:
ret
 
sys_putimage_with_check:
or ebx,ebx
jz @f
call sys_putimage.forced
@@: ret
 
drawwindow_IV_caption:
 
mov ebp,skin_active
or al,al
jnz @f
mov ebp,skin_inactive
@@:
 
mov esi,[esp+4]
mov eax,[esi+WDATA.box.width] ; window width
mov edx,[ebp+SKIN_DATA.left.left]
shl edx,16
mov ecx,[ebp+SKIN_DATA.left.width]
shl ecx,16
add ecx,[_skinh]
 
mov ebx, [ebp+SKIN_DATA.left.data]
call sys_putimage_with_check
 
mov esi,[esp+4]
mov eax,[esi+WDATA.box.width]
sub eax,[ebp+SKIN_DATA.left.width]
sub eax,[ebp+SKIN_DATA.oper.width]
cmp eax,[ebp+SKIN_DATA.base.left]
jng .non_base
xor edx,edx
mov ecx,[ebp+SKIN_DATA.base.width]
jecxz .non_base
div ecx
 
inc eax
 
mov ebx,[ebp+SKIN_DATA.base.data]
mov ecx,[ebp+SKIN_DATA.base.width]
shl ecx,16
add ecx,[_skinh]
mov edx,[ebp+SKIN_DATA.base.left]
sub edx,[ebp+SKIN_DATA.base.width]
shl edx,16
.baseskinloop:
shr edx,16
add edx,[ebp+SKIN_DATA.base.width]
shl edx,16
 
push eax ebx ecx edx
call sys_putimage_with_check
pop edx ecx ebx eax
 
dec eax
jnz .baseskinloop
.non_base:
 
mov esi,[esp+4]
mov edx,[esi+WDATA.box.width]
sub edx,[ebp+SKIN_DATA.oper.width]
inc edx
shl edx,16
mov ebx,[ebp+SKIN_DATA.oper.data]
 
mov ecx,[ebp+SKIN_DATA.oper.width]
shl ecx,16
add ecx,[_skinh]
call sys_putimage_with_check
 
ret
 
;//mike.dld, 2006-08-02 ]
 
 
drawwindow_IV:
;param1 - aw_yes
 
pusha
 
push edx
 
mov edi,edx
 
mov ebp,skin_active
cmp byte [esp+32+4+4],0
jne @f
mov ebp,skin_inactive
@@:
 
mov eax,[edi+WDATA.box.left]
shl eax,16
mov ax,word [edi+WDATA.box.left]
add ax,word [edi+WDATA.box.width]
mov ebx,[edi+WDATA.box.top]
shl ebx,16
mov bx,word [edi+WDATA.box.top]
add bx,word [edi+WDATA.box.height]
; mov esi,[edi+24]
; shr esi,1
; and esi,0x007f7f7f
mov esi,[ebp+SKIN_DATA.colors.outer]
call draw_rectangle
mov ecx,3
_dw3l:
add eax,1*65536-1
add ebx,1*65536-1
test ax,ax
js no_skin_add_button
test bx,bx
js no_skin_add_button
mov esi,[ebp+SKIN_DATA.colors.frame] ;[edi+24]
call draw_rectangle
dec ecx
jnz _dw3l
mov esi,[ebp+SKIN_DATA.colors.inner]
add eax,1*65536-1
add ebx,1*65536-1
test ax,ax
js no_skin_add_button
test bx,bx
js no_skin_add_button
call draw_rectangle
 
cmp dword[skin_data],'SKIN'
je @f
xor eax,eax
xor ebx,ebx
mov esi,[esp]
mov ecx,[esi+WDATA.box.width]
inc ecx
mov edx,[_skinh]
mov edi,[common_colours+4] ; standard grab color
call [drawbar]
jmp draw_clientbar
@@:
 
mov al,[esp+32+4+4]
call drawwindow_IV_caption
 
draw_clientbar:
 
mov esi,[esp]
 
mov edx,[esi+WDATA.box.top] ; WORK AREA
add edx,21+5
mov ebx,[esi+WDATA.box.top]
add ebx,[esi+WDATA.box.height]
cmp edx,ebx
jg _noinside2
mov eax,5
mov ebx,[_skinh]
mov ecx,[esi+WDATA.box.width]
mov edx,[esi+WDATA.box.height]
sub ecx,4
sub edx,4
mov edi,[esi+WDATA.cl_workarea]
test edi,0x40000000
jnz _noinside2
call [drawbar]
_noinside2:
 
cmp dword[skin_data],'SKIN'
jne no_skin_add_button
 
;* close button
mov edi,[BTN_ADDR]
movzx eax,word [edi]
cmp eax,1000
jge no_skin_add_button
inc eax
mov [edi],ax
 
shl eax,4
add eax,edi
 
mov bx,[CURRENT_TASK]
mov [eax],bx
 
add eax,2 ; save button id number
mov bx,1
mov [eax],bx
add eax,2 ; x start
xor ebx,ebx
cmp [skin_btn_close.left],0
jge _bCx_at_right
mov ebx,[esp]
mov ebx,[ebx+WDATA.box.width]
inc ebx
_bCx_at_right:
add ebx,[skin_btn_close.left]
mov [eax],bx
add eax,2 ; x size
mov ebx,[skin_btn_close.width]
dec ebx
mov [eax],bx
add eax,2 ; y start
mov ebx,[skin_btn_close.top]
mov [eax],bx
add eax,2 ; y size
mov ebx,[skin_btn_close.height]
dec ebx
mov [eax],bx
 
;* minimize button
mov edi,[BTN_ADDR]
movzx eax,word [edi]
cmp eax,1000
jge no_skin_add_button
inc eax
mov [edi],ax
 
shl eax,4
add eax,edi
 
mov bx,[CURRENT_TASK]
mov [eax],bx
 
add eax,2 ; save button id number
mov bx,65535 ;999
mov [eax],bx
add eax,2 ; x start
xor ebx,ebx
cmp [skin_btn_minimize.left],0
jge _bMx_at_right
mov ebx,[esp]
mov ebx,[ebx+WDATA.box.width]
inc ebx
_bMx_at_right:
add ebx,[skin_btn_minimize.left]
mov [eax],bx
add eax,2 ; x size
mov ebx,[skin_btn_minimize.width]
dec ebx
mov [eax],bx
add eax,2 ; y start
mov ebx,[skin_btn_minimize.top]
mov [eax],bx
add eax,2 ; y size
mov ebx,[skin_btn_minimize.height]
dec ebx
mov [eax],bx
 
no_skin_add_button:
pop edi
popa
 
ret 4
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/gui/font.inc
0,0 → 1,132
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
; // Alver 22.06.2008 // {
align 4
dtext_asciiz_esi: ; for skins title out
push eax
xor eax, eax
inc eax
jmp dtext.1
; } \\ Alver \\
 
align 4
dtext: ; Text String Output (rw by Johnny_B[john@kolibrios.org])
; ebx x & y
; ecx style ( 0xX0000000 ) & color ( 0x00RRGGBB )
; X = ABnnb:
; nn = font
; A = 0 <=> output esi characters; otherwise output ASCIIZ string
; B = 1 <=> fill background with color eax
; edx start of text
; edi 1 force
 
; // Alver 22.06.2008 // {
push eax
xor eax, eax
.1:
; } \\ Alver \\
pushad
call [_display.disable_mouse]
 
movsx eax, bx ; eax=y
sar ebx, 16 ; ebx=x
xchg eax, ebx ; eax=x, ebx=y
cmp esi, 255
jb .loop
mov esi, 255
.loop:
test ecx, ecx
js .test_asciiz
dec esi
js .end
jmp @f
.test_asciiz:
cmp byte [edx], 0
jz .end
; // Alver 22.06.2008 // {
cmp byte [esp+28], 1
jne @f
dec esi
js .end
; } \\ Alver \\
@@:
inc edx
pushad
movzx edx, byte [edx-1]
test ecx, 0x10000000
jnz .font2
mov esi, 9
lea ebp, [FONT_I+8*edx+edx]
.symloop1:
mov dl, byte [ebp]
or dl, 1 shl 6
.pixloop1:
shr dl, 1
jz .pixloop1end
jnc .nopix
call [putpixel]
jmp .pixloop1cont
.nopix:
test ecx, 0x40000000
jz .pixloop1cont
push ecx
mov ecx, [esp+4+20h+20h]
call [putpixel]
pop ecx
.pixloop1cont:
inc eax
jmp .pixloop1
.pixloop1end:
sub eax, 6
inc ebx
inc ebp
dec esi
jnz .symloop1
popad
add eax, 6
jmp .loop
.font2:
add edx, edx
lea ebp, [FONT_II+4*edx+edx+1]
push 9
movzx esi, byte [ebp-1]
.symloop2:
mov dl, byte [ebp]
push esi
.pixloop2:
shr dl, 1
jnc .nopix2
call [putpixel]
jmp .pixloop2cont
.nopix2:
test ecx, 0x40000000
jz .pixloop2cont
push ecx
mov ecx, [esp+12+20h+20h]
call [putpixel]
pop ecx
.pixloop2cont:
inc eax
dec esi
jnz .pixloop2
pop esi
sub eax, esi
inc ebx
inc ebp
dec dword [esp]
jnz .symloop2
pop eax
add dword [esp+28], esi
popad
jmp .loop
.end:
popad
pop eax ; << // Alver 22.06.2008 // <<
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/gui/skindata.inc
0,0 → 1,64
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;
; WINDOW SKIN DATA
;
 
iglobal
_skin_file_default db '/sys/DEFAULT.SKN',0
endg
 
struct SKIN_DATA
.colors.inner dd ?
.colors.outer dd ?
.colors.frame dd ?
.left.data dd ?
.left.left dd ?
.left.width dd ?
.oper.data dd ?
.oper.left dd ?
.oper.width dd ?
.base.data dd ?
.base.left dd ?
.base.width dd ?
ends
 
struct SKIN_BUTTON
.left dd ?
.top dd ?
.width dd ?
.height dd ?
ends
 
uglobal
 
align 4
 
skin_udata:
_skinh dd ?
 
_skinmargins: ; rw 4
.right dw ?
.left dw ?
.bottom dw ?
.top dw ?
 
skin_btn_close SKIN_BUTTON
skin_btn_minimize SKIN_BUTTON
 
skin_active SKIN_DATA
skin_inactive SKIN_DATA
 
align 4
 
skin_udata.end:
 
endg
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/gui
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/blkdev/rd.inc
0,0 → 1,2272
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; RAMDISK functions ;;
;; (C) 2004 Ville Turjanmaa, License: GPL ;;
;; Addings by M.Lisovin ;;
;; LFN support by diamond ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; calculate fat chain
 
calculatefatchain:
 
pushad
 
mov esi,RAMDISK+512
mov edi,RAMDISK_FAT
 
fcnew:
mov eax,dword [esi]
mov ebx,dword [esi+4]
mov ecx,dword [esi+8]
mov edx,ecx
shr edx,4 ;8 ok
shr dx,4 ;7 ok
xor ch,ch
shld ecx,ebx,20 ;6 ok
shr cx,4 ;5 ok
shld ebx,eax,12
and ebx,0x0fffffff ;4 ok
shr bx,4 ;3 ok
shl eax,4
and eax,0x0fffffff ;2 ok
shr ax,4 ;1 ok
mov dword [edi],eax
mov dword [edi+4],ebx
mov dword [edi+8],ecx
mov dword [edi+12],edx
add edi,16
add esi,12
 
cmp edi,RAMDISK_FAT+2856*2 ;2849 clusters
jnz fcnew
 
popad
ret
 
 
restorefatchain: ; restore fat chain
 
pushad
 
mov esi,RAMDISK_FAT
mov edi,RAMDISK+512
 
fcnew2:
mov eax,dword [esi]
mov ebx,dword [esi+4]
shl ax,4
shl eax,4
shl bx,4
shr ebx,4
shrd eax,ebx,8
shr ebx,8
mov dword [edi],eax
mov word [edi+4],bx
add edi,6
add esi,8
 
cmp edi,RAMDISK+512+4278 ;4274 bytes - all used FAT
jb fcnew2
 
mov esi,RAMDISK+512 ; duplicate fat chain
mov edi,RAMDISK+512+0x1200
mov ecx,1069 ;4274/4
cld
rep movsd
 
popad
ret
 
 
ramdisk_free_space:
;---------------------------------------------
;
; returns free space in edi
; rewr.by Mihasik
;---------------------------------------------
 
push eax ebx ecx
 
mov edi,RAMDISK_FAT ;start of FAT
xor ax,ax ;Free cluster=0x0000 in FAT
xor ebx,ebx ;counter
mov ecx,2849 ;2849 clusters
cld
rdfs1:
repne scasw
jnz rdfs2 ;if last cluster not 0
inc ebx
test ecx, ecx
jnz rdfs1
rdfs2:
shl ebx,9 ;free clusters*512
mov edi,ebx
 
pop ecx ebx eax
ret
 
 
expand_filename:
;---------------------------------------------
;
; exapand filename with '.' to 11 character
; eax - pointer to filename
;---------------------------------------------
 
push esi edi ebx
 
mov edi,esp ; check for '.' in the name
add edi,12+8
 
mov esi,eax
 
mov eax,edi
mov [eax+0],dword ' '
mov [eax+4],dword ' '
mov [eax+8],dword ' '
 
flr1:
 
cmp [esi],byte '.'
jne flr2
mov edi,eax
add edi,7
jmp flr3
 
flr2:
 
mov bl,[esi]
mov [edi],bl
 
flr3:
 
inc esi
inc edi
 
mov ebx,eax
add ebx,11
 
cmp edi,ebx
jbe flr1
 
pop ebx edi esi
ret
 
fileread:
;----------------------------------------------------------------
;
; fileread - sys floppy
;
; eax points to filename 11 chars
; ebx first wanted block ; 1+ ; if 0 then set to 1
; ecx number of blocks to read ; 1+ ; if 0 then set to 1
; edx mem location to return data
; esi length of filename 12*X 0=root
;
; ret ebx = size or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
test ebx,ebx ;if ebx=0 - set to 1
jnz frfl5
inc ebx
frfl5:
test ecx,ecx ;if ecx=0 - set to 1
jnz frfl6
inc ecx
frfl6:
test esi,esi ; return ramdisk root
jnz fr_noroot ;if not root
cmp ebx,14 ;14 clusters=root dir
ja oorr
cmp ecx,14
ja oorr
jmp fr_do
oorr:
mov eax,5 ;out of root range (fnf)
xor ebx,ebx
dec ebx ;0xffffffff
ret
 
fr_do: ;reading rootdir
mov edi,edx
dec ebx
push edx
mov edx,ecx
add edx,ebx
cmp edx,15 ;ebx+ecx=14+1
pushf
jbe fr_do1
sub edx,14
sub ecx,edx
fr_do1:
shl ebx,9
mov esi,RAMDISK+512*19
add esi,ebx
shl ecx,7
cld
rep movsd
popf
pop edx
jae fr_do2
xor eax,eax ; ok read
xor ebx,ebx
ret
fr_do2: ;if last cluster
mov eax,6 ;end of file
xor ebx,ebx
ret
 
fr_noroot:
 
sub esp,32
call expand_filename
 
dec ebx
 
push eax
 
push eax ebx ecx edx esi edi
call rd_findfile
je fifound
add esp,32+28 ;if file not found
ret
 
fifound:
 
mov ebx,[edi-11+28] ;file size
mov [esp+20],ebx
mov [esp+24],ebx
add edi,0xf
movzx eax,word [edi]
mov edi,eax ;edi=cluster
 
frnew:
 
add eax,31 ;bootsector+2*fat+filenames
shl eax,9 ;*512
add eax,RAMDISK ;image base
mov ebx,[esp+8]
mov ecx,512 ;[esp+4]
 
cmp [esp+16],dword 0 ; wanted cluster ?
jne frfl7
call memmove
add [esp+8],dword 512
dec dword [esp+12] ; last wanted cluster ?
je frnoread
jmp frfl8
frfl7:
dec dword [esp+16]
frfl8:
movzx eax,word [edi*2+RAMDISK_FAT] ; find next cluster from FAT
mov edi,eax
cmp edi,4095 ;eof - cluster
jz frnoread2
 
cmp [esp+24],dword 512 ;eof - size
jb frnoread
sub [esp+24],dword 512
 
jmp frnew
 
frnoread2:
 
cmp [esp+16],dword 0 ; eof without read ?
je frnoread
 
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
mov eax,6 ; end of file
ret
 
frnoread:
 
pop edi esi edx ecx
add esp,4
pop ebx ; ebx <- eax : size of file
add esp,36
xor eax,eax ;read ok
ret
 
 
 
rd_findfile:
;by Mihasik
;IN: eax - pointer to filename OUT: filestring+11 in edi or notZero in flags and fnf in eax,ebx
 
mov edi,RAMDISK+512*18+512 ;Point at directory
cld
rd_newsearch:
mov esi,eax
mov ecx,11
rep cmpsb
je rd_ff
add cl,21
add edi,ecx
cmp edi,RAMDISK+512*33
jb rd_newsearch
mov eax,5 ;if file not found - eax=5
xor ebx,ebx
dec ebx ;ebx=0xffffffff and zf=0
rd_ff:
ret
 
; \begin{diamond}
 
uni2ansi_str:
; convert UNICODE zero-terminated string to ASCII-string (codepage 866)
; in: esi->source, edi->buffer (may be esi=edi)
; destroys: eax,esi,edi
lodsw
test ax, ax
jz .done
cmp ax, 0x80
jb .ascii
cmp ax, 0x401
jz .yo1
cmp ax, 0x451
jz .yo2
cmp ax, 0x410
jb .unk
cmp ax, 0x440
jb .rus1
cmp ax, 0x450
jb .rus2
.unk:
mov al, '_'
jmp .doit
.yo1:
mov al, 'ð'
jmp .doit
.yo2:
mov al, 'ñ'
jmp .doit
.rus1:
; 0x410-0x43F -> 0x80-0xAF
add al, 0x70
jmp .doit
.rus2:
; 0x440-0x44F -> 0xE0-0xEF
add al, 0xA0
.ascii:
.doit:
stosb
jmp uni2ansi_str
.done:
mov byte [edi], 0
ret
 
ansi2uni_char:
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding
mov ah, 0
; 0x00-0x7F - trivial map
cmp al, 0x80
jb .ret
; 0x80-0xAF -> 0x410-0x43F
cmp al, 0xB0
jae @f
add ax, 0x410-0x80
.ret:
ret
@@:
; 0xE0-0xEF -> 0x440-0x44F
cmp al, 0xE0
jb .unk
cmp al, 0xF0
jae @f
add ax, 0x440-0xE0
ret
; 0xF0 -> 0x401
; 0xF1 -> 0x451
@@:
cmp al, 'ð'
jz .yo1
cmp al, 'ñ'
jz .yo2
.unk:
mov al, '_' ; ah=0
ret
.yo1:
mov ax, 0x401
ret
.yo2:
mov ax, 0x451
ret
 
char_toupper:
; convert character to uppercase, using cp866 encoding
; in: al=symbol
; out: al=converted symbol
cmp al, 'a'
jb .ret
cmp al, 'z'
jbe .az
cmp al, 'ñ'
jz .yo1
cmp al, ' '
jb .ret
cmp al, 'à'
jb .rus1
cmp al, 'ï'
ja .ret
; 0xE0-0xEF -> 0x90-0x9F
sub al, 'à'-''
.ret:
ret
.rus1:
; 0xA0-0xAF -> 0x80-0x8F
.az:
and al, not 0x20
ret
.yo1:
; 0xF1 -> 0xF0
dec ax
ret
 
fat_get_name:
; in: edi->FAT entry
; out: CF=1 - no valid entry
; else CF=0 and ebp->ASCIIZ-name
; (maximum length of filename is 255 (wide) symbols without trailing 0,
; but implementation requires buffer 261 words)
; destroys eax
cmp byte [edi], 0
jz .no
cmp byte [edi], 0xE5
jnz @f
.no:
stc
ret
@@:
cmp byte [edi+11], 0xF
jz .longname
test byte [edi+11], 8
jnz .no
push ecx
push edi ebp
test byte [ebp-4], 1
jnz .unicode_short
 
mov eax, [edi]
mov ecx, [edi+4]
mov [ebp], eax
mov [ebp+4], ecx
 
mov ecx, 8
@@:
cmp byte [ebp+ecx-1], ' '
loope @b
 
mov eax, [edi+8]
cmp al, ' '
je .done
shl eax, 8
mov al, '.'
 
lea ebp, [ebp+ecx+1]
mov [ebp], eax
mov ecx, 3
@@:
rol eax, 8
cmp al, ' '
jne .done
loop @b
dec ebp
.done:
and byte [ebp+ecx+1], 0 ; CF=0
pop ebp edi ecx
ret
.unicode_short:
mov ecx, 8
push ecx
@@:
mov al, [edi]
inc edi
call ansi2uni_char
mov [ebp], ax
inc ebp
inc ebp
loop @b
pop ecx
@@:
cmp word [ebp-2], ' '
jnz @f
dec ebp
dec ebp
loop @b
@@:
mov word [ebp], '.'
inc ebp
inc ebp
mov ecx, 3
push ecx
@@:
mov al, [edi]
inc edi
call ansi2uni_char
mov [ebp], ax
inc ebp
inc ebp
loop @b
pop ecx
@@:
cmp word [ebp-2], ' '
jnz @f
dec ebp
dec ebp
loop @b
dec ebp
dec ebp
@@:
and word [ebp], 0 ; CF=0
pop ebp edi ecx
ret
.longname:
; LFN
mov al, byte [edi]
and eax, 0x3F
dec eax
cmp al, 20
jae .no ; ignore invalid entries
mov word [ebp+260*2], 0 ; force null-terminating for orphans
imul eax, 13*2
add ebp, eax
test byte [edi], 0x40
jz @f
mov word [ebp+13*2], 0
@@:
push eax
; now copy name from edi to ebp ...
mov eax, [edi+1]
mov [ebp], eax ; symbols 1,2
mov eax, [edi+5]
mov [ebp+4], eax ; 3,4
mov eax, [edi+9]
mov [ebp+8], ax ; 5
mov eax, [edi+14]
mov [ebp+10], eax ; 6,7
mov eax, [edi+18]
mov [ebp+14], eax ; 8,9
mov eax, [edi+22]
mov [ebp+18], eax ; 10,11
mov eax, [edi+28]
mov [ebp+22], eax ; 12,13
; ... done
pop eax
sub ebp, eax
test eax, eax
jz @f
; if this is not first entry, more processing required
stc
ret
@@:
; if this is first entry:
test byte [ebp-4], 1
jnz .ret
; buffer at ebp contains UNICODE name, convert it to ANSI
push esi edi
mov esi, ebp
mov edi, ebp
call uni2ansi_str
pop edi esi
.ret:
clc
ret
 
fat_compare_name:
; compares ASCIIZ-names, case-insensitive (cp866 encoding)
; in: esi->name, ebp->name
; out: if names match: ZF=1 and esi->next component of name
; else: ZF=0, esi is not changed
; destroys eax
push ebp esi
.loop:
mov al, [ebp]
inc ebp
call char_toupper
push eax
lodsb
call char_toupper
cmp al, [esp]
jnz .done
pop eax
test al, al
jnz .loop
dec esi
pop eax
pop ebp
xor eax, eax ; set ZF flag
ret
.done:
cmp al, '/'
jnz @f
cmp byte [esp], 0
jnz @f
mov [esp+4], esi
@@:
pop eax
pop esi ebp
ret
 
fat_time_to_bdfe:
; in: eax=FAT time
; out: eax=BDFE time
push ecx edx
mov ecx, eax
mov edx, eax
shr eax, 11
shl eax, 16 ; hours
and edx, 0x1F
add edx, edx
mov al, dl ; seconds
shr ecx, 5
and ecx, 0x3F
mov ah, cl ; minutes
pop edx ecx
ret
 
fat_date_to_bdfe:
push ecx edx
mov ecx, eax
mov edx, eax
shr eax, 9
add ax, 1980
shl eax, 16 ; year
and edx, 0x1F
mov al, dl ; day
shr ecx, 5
and ecx, 0xF
mov ah, cl ; month
pop edx ecx
ret
 
bdfe_to_fat_time:
push edx
mov edx, eax
shr eax, 16
and dh, 0x3F
shl eax, 6
or al, dh
shr dl, 1
and dl, 0x1F
shl eax, 5
or al, dl
pop edx
ret
 
bdfe_to_fat_date:
push edx
mov edx, eax
shr eax, 16
sub ax, 1980
and dh, 0xF
shl eax, 4
or al, dh
and dl, 0x1F
shl eax, 5
or al, dl
pop edx
ret
 
fat_entry_to_bdfe:
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi
; destroys eax
mov eax, [ebp-4]
mov [esi+4], eax ; ASCII/UNICODE name
fat_entry_to_bdfe2:
movzx eax, byte [edi+11]
mov [esi], eax ; attributes
movzx eax, word [edi+14]
call fat_time_to_bdfe
mov [esi+8], eax ; creation time
movzx eax, word [edi+16]
call fat_date_to_bdfe
mov [esi+12], eax ; creation date
and dword [esi+16], 0 ; last access time is not supported on FAT
movzx eax, word [edi+18]
call fat_date_to_bdfe
mov [esi+20], eax ; last access date
movzx eax, word [edi+22]
call fat_time_to_bdfe
mov [esi+24], eax ; last write time
movzx eax, word [edi+24]
call fat_date_to_bdfe
mov [esi+28], eax ; last write date
mov eax, [edi+28]
mov [esi+32], eax ; file size (low dword)
xor eax, eax
mov [esi+36], eax ; file size (high dword)
test ebp, ebp
jz .ret
push ecx edi
lea edi, [esi+40]
mov esi, ebp
test byte [esi-4], 1
jz .ansi
mov ecx, 260/2
rep movsd
mov [edi-2], ax
@@:
mov esi, edi
pop edi ecx
.ret:
ret
.ansi:
mov ecx, 264/4
rep movsd
mov [edi-1], al
jmp @b
 
bdfe_to_fat_entry:
; convert BDFE at edx to FAT entry at edi
; destroys eax
; attributes byte
test byte [edi+11], 8 ; volume label?
jnz @f
mov al, [edx]
and al, 0x27
and byte [edi+11], 0x10
or byte [edi+11], al
@@:
mov eax, [edx+8]
call bdfe_to_fat_time
mov [edi+14], ax ; creation time
mov eax, [edx+12]
call bdfe_to_fat_date
mov [edi+16], ax ; creation date
mov eax, [edx+20]
call bdfe_to_fat_date
mov [edi+18], ax ; last access date
mov eax, [edx+24]
call bdfe_to_fat_time
mov [edi+22], ax ; last write time
mov eax, [edx+28]
call bdfe_to_fat_date
mov [edi+24], ax ; last write date
ret
 
ramdisk_root_first:
mov edi, RAMDISK+512*19
clc
ret
ramdisk_root_next:
add edi, 0x20
cmp edi, RAMDISK+512*33
cmc
ret
 
ramdisk_root_extend_dir:
stc
ret
 
uglobal
; this is for delete support
rd_prev_sector dd ?
rd_prev_prev_sector dd ?
endg
 
ramdisk_notroot_next:
add edi, 0x20
test edi, 0x1FF
jz ramdisk_notroot_next_sector
ret ; CF=0
ramdisk_notroot_next_sector:
push ecx
mov ecx, [eax]
push [rd_prev_sector]
pop [rd_prev_prev_sector]
mov [rd_prev_sector], ecx
mov ecx, [ecx*2+RAMDISK_FAT]
and ecx, 0xFFF
cmp ecx, 2849
jae ramdisk_notroot_first.err2
mov [eax], ecx
pop ecx
ramdisk_notroot_first:
mov eax, [eax]
cmp eax, 2
jb .err
cmp eax, 2849
jae .err
shl eax, 9
lea edi, [eax+(31 shl 9)+RAMDISK]
clc
ret
.err2:
pop ecx
.err:
stc
ret
ramdisk_notroot_next_write:
test edi, 0x1FF
jz ramdisk_notroot_next_sector
ramdisk_root_next_write:
ret
 
ramdisk_notroot_extend_dir:
pusha
xor eax, eax
mov edi, RAMDISK_FAT
mov ecx, 2849
repnz scasw
jnz .notfound
mov word [edi-2], 0xFFF
sub edi, RAMDISK_FAT
shr edi, 1
dec edi
mov eax, [esp+28]
mov ecx, [eax]
mov [RAMDISK_FAT+ecx*2], di
mov [eax], edi
shl edi, 9
add edi, (31 shl 9)+RAMDISK
mov [esp], edi
xor eax, eax
mov ecx, 128
rep stosd
popa
clc
ret
.notfound:
popa
stc
ret
 
rd_find_lfn:
; in: esi+ebp -> name
; out: CF=1 - file not found
; else CF=0 and edi->direntry
push esi edi
push 0
push ramdisk_root_first
push ramdisk_root_next
.loop:
call fat_find_lfn
jc .notfound
cmp byte [esi], 0
jz .found
.continue:
test byte [edi+11], 10h
jz .notfound
movzx eax, word [edi+26]
mov [esp+8], eax
mov dword [esp+4], ramdisk_notroot_first
mov dword [esp], ramdisk_notroot_next
test eax, eax
jnz .loop
mov dword [esp+4], ramdisk_root_first
mov dword [esp], ramdisk_notroot_next
jmp .loop
.notfound:
add esp, 12
pop edi esi
stc
ret
.found:
test ebp, ebp
jz @f
mov esi, ebp
xor ebp, ebp
jmp .continue
@@:
mov eax, [esp+8]
add esp, 16 ; CF=0
pop esi
ret
 
;----------------------------------------------------------------
;
; fs_RamdiskRead - LFN variant for reading sys floppy
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to read, 0+
; edx mem location to return data
;
; ret ebx = bytes read or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_RamdiskRead:
cmp byte [esi], 0
jnz @f
or ebx, -1
mov eax, 10 ; access denied
ret
@@:
push edi
call rd_find_lfn
jnc .found
pop edi
or ebx, -1
mov eax, 5 ; file not found
ret
.found:
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
xor ebx, ebx
.reteof:
mov eax, 6 ; EOF
pop edi
ret
@@:
mov ebx, [ebx]
.l1:
push ecx edx
push 0
mov eax, [edi+28]
sub eax, ebx
jb .eof
cmp eax, ecx
jae @f
mov ecx, eax
mov byte [esp], 6 ; EOF
@@:
movzx edi, word [edi+26] ; cluster
.new:
jecxz .done
test edi, edi
jz .eof
cmp edi, 0xFF8
jae .eof
lea eax, [edi+31] ; bootsector+2*fat+filenames
shl eax, 9 ; *512
add eax, RAMDISK ; image base
; now eax points to data of cluster
sub ebx, 512
jae .skip
lea eax, [eax+ebx+512]
neg ebx
push ecx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
mov ebx, edx
call memmove
add edx, ecx
sub [esp], ecx
pop ecx
xor ebx, ebx
.skip:
movzx edi, word [edi*2+RAMDISK_FAT] ; find next cluster from FAT
jmp .new
.eof:
mov ebx, edx
pop eax edx ecx
sub ebx, edx
jmp .reteof
.done:
mov ebx, edx
pop eax edx ecx edi
sub ebx, edx
ret
 
;----------------------------------------------------------------
;
; fs_RamdiskReadFolder - LFN variant for reading sys floppy folder
;
; esi points to filename; only root is folder on ramdisk
; ebx pointer to structure 32-bit number = first wanted block
; & flags (bitfields)
; flags: bit 0: 0=ANSI names, 1=UNICODE names
; ecx number of blocks to read, 0+
; edx mem location to return data
;
; ret ebx = size or 0xffffffff file not found
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
fs_RamdiskReadFolder:
push edi
cmp byte [esi], 0
jz .root
call rd_find_lfn
jnc .found
pop edi
or ebx, -1
mov eax, ERROR_FILE_NOT_FOUND
ret
.found:
test byte [edi+11], 0x10
jnz .found_dir
pop edi
or ebx, -1
mov eax, ERROR_ACCESS_DENIED
ret
.found_dir:
movzx eax, word [edi+26]
add eax, 31
push 0
jmp .doit
.root:
mov eax, 19
push 14
.doit:
push esi ecx ebp
sub esp, 262*2 ; reserve space for LFN
mov ebp, esp
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names
mov ebx, [ebx]
; init header
push eax ecx
mov edi, edx
mov ecx, 32/4
xor eax, eax
rep stosd
mov byte [edx], 1 ; version
pop ecx eax
mov esi, edi ; esi points to block of data of folder entry (BDFE)
.main_loop:
mov edi, eax
shl edi, 9
add edi, RAMDISK
push eax
.l1:
call fat_get_name
jc .l2
cmp byte [edi+11], 0xF
jnz .do_bdfe
add edi, 0x20
test edi, 0x1FF
jnz .do_bdfe
pop eax
inc eax
dec byte [esp+262*2+16]
jz .done
jns @f
; read next sector from FAT
mov eax, [(eax-31-1)*2+RAMDISK_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
jae .done
add eax, 31
mov byte [esp+262*2+16], 0
@@:
mov edi, eax
shl edi, 9
add edi, RAMDISK
push eax
.do_bdfe:
inc dword [edx+8] ; new file found
dec ebx
jns .l2
dec ecx
js .l2
inc dword [edx+4] ; new file block copied
call fat_entry_to_bdfe
.l2:
add edi, 0x20
test edi, 0x1FF
jnz .l1
pop eax
inc eax
dec byte [esp+262*2+16]
jz .done
jns @f
; read next sector from FAT
mov eax, [(eax-31-1)*2+RAMDISK_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
jae .done
add eax, 31
mov byte [esp+262*2+16], 0
@@:
jmp .main_loop
.done:
add esp, 262*2+4
pop ebp
mov ebx, [edx+4]
xor eax, eax
dec ecx
js @f
mov al, ERROR_END_OF_FILE
@@:
pop ecx esi edi edi
ret
 
iglobal
label fat_legal_chars byte
; 0 = not allowed
; 1 = allowed only in long names
; 3 = allowed
times 32 db 0
; ! " # $ % & ' ( ) * + , - . /
db 1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0
; 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
db 3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0
; @ A B C D E F G H I J K L M N O
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
; P Q R S T U V W X Y Z [ \ ] ^ _
db 3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3
; ` a b c d e f g h i j k l m n o
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
; p q r s t u v w x y z { | } ~
db 3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0
endg
 
fat_name_is_legal:
; in: esi->(long) name
; out: CF set <=> legal
; destroys eax
push esi
xor eax, eax
@@:
lodsb
test al, al
jz .done
cmp al, 80h
jae .big
test [fat_legal_chars+eax], 1
jnz @b
.err:
pop esi
clc
ret
.big:
; 0x80-0xAF, 0xE0-0xEF
cmp al, 0xB0
jb @b
cmp al, 0xE0
jb .err
cmp al, 0xF0
jb @b
jmp .err
.done:
sub esi, [esp]
cmp esi, 257
pop esi
ret
 
fat_next_short_name:
; in: edi->8+3 name
; out: name corrected
; CF=1 <=> error
pushad
mov ecx, 8
mov al, '~'
std
push edi
add edi, 7
repnz scasb
pop edi
cld
jz .tilde
; tilde is not found, insert "~1" at end
add edi, 6
cmp word [edi], ' '
jnz .insert_tilde
@@: dec edi
cmp byte [edi], ' '
jz @b
inc edi
.insert_tilde:
mov word [edi], '~1'
popad
clc
ret
.tilde:
push edi
add edi, 7
xor ecx, ecx
@@:
; after tilde may be only digits and trailing spaces
cmp byte [edi], '~'
jz .break
cmp byte [edi], ' '
jz .space
cmp byte [edi], '9'
jnz .found
dec edi
jmp @b
.space:
dec edi
inc ecx
jmp @b
.found:
inc byte [edi]
add dword [esp], 8
jmp .zerorest
.break:
jecxz .noplace
inc edi
mov al, '1'
@@:
xchg al, [edi]
inc edi
cmp al, ' '
mov al, '0'
jnz @b
.succ:
pop edi
popad
clc
ret
.noplace:
dec edi
cmp edi, [esp]
jz .err
add dword [esp], 8
mov word [edi], '~1'
inc edi
inc edi
@@:
mov byte [edi], '0'
.zerorest:
inc edi
cmp edi, [esp]
jb @b
pop edi
popad
;clc ; automatically
ret
.err:
pop edi
popad
stc
ret
 
fat_gen_short_name:
; in: esi->long name
; edi->buffer (8+3=11 chars)
; out: buffer filled
pushad
mov eax, ' '
push edi
stosd
stosd
stosd
pop edi
xor eax, eax
push 8
pop ebx
lea ecx, [edi+8]
.loop:
lodsb
test al, al
jz .done
call char_toupper
cmp al, ' '
jz .space
cmp al, 80h
ja .big
test [fat_legal_chars+eax], 2
jnz .symbol
.inv_symbol:
mov al, '_'
or bh, 1
.symbol:
cmp al, '.'
jz .dot
.normal_symbol:
dec bl
jns .store
mov bl, 0
.space:
or bh, 1
jmp .loop
.store:
stosb
jmp .loop
.big:
cmp al, 0xB0
jb .normal_symbol
cmp al, 0xE0
jb .inv_symbol
cmp al, 0xF0
jb .normal_symbol
jmp .inv_symbol
.dot:
test bh, 2
jz .firstdot
pop ebx
add ebx, edi
sub ebx, ecx
push ebx
cmp ebx, ecx
jb @f
pop ebx
push ecx
@@:
cmp edi, ecx
jbe .skip
@@:
dec edi
mov al, [edi]
dec ebx
mov [ebx], al
mov byte [edi], ' '
cmp edi, ecx
ja @b
.skip:
mov bh, 3
jmp @f
.firstdot:
cmp bl, 8
jz .space
push edi
or bh, 2
@@:
mov edi, ecx
mov bl, 3
jmp .loop
.done:
test bh, 2
jz @f
pop edi
@@:
lea edi, [ecx-8]
test bh, 1
jz @f
call fat_next_short_name
@@:
popad
ret
 
;----------------------------------------------------------------
;
; fs_RamdiskRewrite - LFN variant for writing ramdisk
; fs_RamdiskCreateFolder - create folder on ramdisk
;
; esi points to file/folder name
; ebx ignored (reserved)
; ecx number of bytes to write, 0+ (ignored for folders)
; edx mem location to data (ignored for folders)
;
; ret ebx = number of written bytes
; eax = 0 ok read or other = errormsg
;
;--------------------------------------------------------------
@@:
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
 
fs_RamdiskCreateFolder:
mov al, 1 ; create folder
jmp fs_RamdiskRewrite.common
 
fs_RamdiskRewrite:
xor eax, eax ; create file
.common:
cmp byte [esi], 0
jz @b
pushad
xor edi, edi
push esi
test ebp, ebp
jz @f
mov esi, ebp
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
lea edi, [esi-1]
jmp @b
@@:
pop esi
test edi, edi
jnz .noroot
test ebp, ebp
jnz .hasebp
push ramdisk_root_extend_dir
push ramdisk_root_next_write
push edi
push ramdisk_root_first
push ramdisk_root_next
jmp .common1
.hasebp:
mov eax, ERROR_ACCESS_DENIED
cmp byte [ebp], 0
jz .ret1
push ebp
xor ebp, ebp
call rd_find_lfn
pop esi
jc .notfound0
jmp .common0
.noroot:
mov eax, ERROR_ACCESS_DENIED
cmp byte [edi+1], 0
jz .ret1
; check existence
mov byte [edi], 0
push edi
call rd_find_lfn
pop esi
mov byte [esi], '/'
jnc @f
.notfound0:
mov eax, ERROR_FILE_NOT_FOUND
.ret1:
mov [esp+28], eax
popad
xor ebx, ebx
ret
@@:
inc esi
.common0:
test byte [edi+11], 0x10 ; must be directory
mov eax, ERROR_ACCESS_DENIED
jz .ret1
movzx ebp, word [edi+26] ; ebp=cluster
mov eax, ERROR_FAT_TABLE
cmp ebp, 2
jb .ret1
cmp ebp, 2849
jae .ret1
push ramdisk_notroot_extend_dir
push ramdisk_notroot_next_write
push ebp
push ramdisk_notroot_first
push ramdisk_notroot_next
.common1:
call fat_find_lfn
jc .notfound
; found
test byte [edi+11], 10h
jz .exists_file
; found directory; if we are creating directory, return OK,
; if we are creating file, say "access denied"
add esp, 20
popad
test al, al
mov eax, ERROR_ACCESS_DENIED
jz @f
mov al, 0
@@:
xor ebx, ebx
ret
.exists_file:
; found file; if we are creating directory, return "access denied",
; if we are creating file, delete existing file and continue
cmp byte [esp+20+28], 0
jz @f
add esp, 20
popad
mov eax, ERROR_ACCESS_DENIED
xor ebx, ebx
ret
@@:
; delete FAT chain
push edi
xor eax, eax
mov dword [edi+28], eax ; zero size
xchg ax, word [edi+26] ; start cluster
test eax, eax
jz .done1
@@:
cmp eax, 0xFF8
jae .done1
lea edi, [RAMDISK_FAT + eax*2] ; position in FAT
xor eax, eax
xchg ax, [edi]
jmp @b
.done1:
pop edi
call get_time_for_file
mov [edi+22], ax
call get_date_for_file
mov [edi+24], ax
mov [edi+18], ax
or byte [edi+11], 20h ; set 'archive' attribute
jmp .doit
.notfound:
; file is not found; generate short name
call fat_name_is_legal
jc @f
add esp, 20
popad
mov eax, ERROR_FILE_NOT_FOUND
xor ebx, ebx
ret
@@:
sub esp, 12
mov edi, esp
call fat_gen_short_name
.test_short_name_loop:
push esi edi ecx
mov esi, edi
lea eax, [esp+12+12+8]
mov [eax], ebp
call dword [eax-4]
jc .found
.test_short_name_entry:
cmp byte [edi+11], 0xF
jz .test_short_name_cont
mov ecx, 11
push esi edi
repz cmpsb
pop edi esi
jz .short_name_found
.test_short_name_cont:
lea eax, [esp+12+12+8]
call dword [eax-8]
jnc .test_short_name_entry
jmp .found
.short_name_found:
pop ecx edi esi
call fat_next_short_name
jnc .test_short_name_loop
.disk_full:
add esp, 12+20
popad
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.found:
pop ecx edi esi
; now find space in directory
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~'
mov al, '~'
push ecx edi
mov ecx, 8
repnz scasb
push 1
pop eax ; 1 entry
jnz .notilde
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total
xor eax, eax
@@:
cmp byte [esi], 0
jz @f
inc esi
inc eax
jmp @b
@@:
sub esi, eax
add eax, 12+13
mov ecx, 13
push edx
cdq
div ecx
pop edx
.notilde:
push -1
push -1
; find <eax> successive entries in directory
xor ecx, ecx
push eax
lea eax, [esp+12+8+12+8]
mov [eax], ebp
call dword [eax-4]
pop eax
.scan_dir:
cmp byte [edi], 0
jz .free
cmp byte [edi], 0xE5
jz .free
xor ecx, ecx
.scan_cont:
push eax
lea eax, [esp+12+8+12+8]
call dword [eax-8]
pop eax
jnc .scan_dir
push eax
lea eax, [esp+12+8+12+8]
call dword [eax+8] ; extend directory
pop eax
jnc .scan_dir
add esp, 8+8+12+20
popad
mov eax, ERROR_DISK_FULL
xor ebx, ebx
ret
.free:
test ecx, ecx
jnz @f
mov [esp], edi
mov ecx, [esp+8+8+12+8]
mov [esp+4], ecx
xor ecx, ecx
@@:
inc ecx
cmp ecx, eax
jb .scan_cont
; found!
; calculate name checksum
push esi ecx
mov esi, [esp+8+8]
mov ecx, 11
xor eax, eax
@@:
ror al, 1
add al, [esi]
inc esi
loop @b
pop ecx esi
pop edi
pop dword [esp+8+12+8]
; edi points to last entry in free chunk
dec ecx
jz .nolfn
push esi
push eax
mov al, 40h
.writelfn:
or al, cl
mov esi, [esp+4]
push ecx
dec ecx
imul ecx, 13
add esi, ecx
stosb
mov cl, 5
call .read_symbols
mov ax, 0xF
stosw
mov al, [esp+4]
stosb
mov cl, 6
call .read_symbols
xor eax, eax
stosw
mov cl, 2
call .read_symbols
pop ecx
lea eax, [esp+8+8+12+8]
call dword [eax+4] ; next write
xor eax, eax
loop .writelfn
pop eax
pop esi
.nolfn:
xchg esi, [esp]
mov ecx, 11
rep movsb
mov word [edi], 20h ; attributes
sub edi, 11
pop esi ecx
add esp, 12
mov byte [edi+13], 0 ; tenths of a second at file creation time
call get_time_for_file
mov [edi+14], ax ; creation time
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+16], ax ; creation date
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
and word [edi+20], 0 ; high word of cluster
and word [edi+26], 0 ; low word of cluster - to be filled
and dword [edi+28], 0 ; file size - to be filled
cmp byte [esp+20+28], 0
jz .doit
; create directory
mov byte [edi+11], 10h ; attributes: folder
mov ecx, 32*2
mov edx, edi
.doit:
push edx
push ecx
push edi
add edi, 26 ; edi points to low word of cluster
push edi
jecxz .done
mov ecx, 2849
mov edi, RAMDISK_FAT
.write_loop:
; allocate new cluster
xor eax, eax
repnz scasw
jnz .disk_full2
dec edi
dec edi
 
; lea eax, [edi-(RAMDISK_FAT)]
 
mov eax, edi
sub eax, RAMDISK_FAT
 
shr eax, 1 ; eax = cluster
mov word [edi], 0xFFF ; mark as last cluster
xchg edi, [esp]
stosw
pop edi
push edi
inc ecx
; write data
cmp byte [esp+16+20+28], 0
jnz .writedir
shl eax, 9
add eax, RAMDISK+31*512
.writefile:
mov ebx, edx
xchg eax, ebx
push ecx
mov ecx, 512
cmp dword [esp+12], ecx
jae @f
mov ecx, [esp+12]
@@:
call memmove
add edx, ecx
sub [esp+12], ecx
pop ecx
jnz .write_loop
.done:
mov ebx, edx
pop edi edi ecx edx
sub ebx, edx
mov [edi+28], ebx
add esp, 20
mov [esp+16], ebx
popad
xor eax, eax
ret
.disk_full2:
mov ebx, edx
pop edi edi ecx edx
sub ebx, edx
mov [edi+28], ebx
add esp, 20
mov [esp+16], ebx
popad
push ERROR_DISK_FULL
pop eax
ret
.writedir:
mov edi, eax
shl edi, 9
add edi, RAMDISK+31*512
mov esi, edx
mov ecx, 32/4
push ecx
rep movsd
mov dword [edi-32], '. '
mov dword [edi-32+4], ' '
mov dword [edi-32+8], ' '
mov byte [edi-32+11], 10h
mov word [edi-32+26], ax
mov esi, edx
pop ecx
rep movsd
mov dword [edi-32], '.. '
mov dword [edi-32+4], ' '
mov dword [edi-32+8], ' '
mov byte [edi-32+11], 10h
mov eax, [esp+16+8]
mov word [edi-32+26], ax
xor eax, eax
mov ecx, (512-32*2)/4
rep stosd
pop edi edi ecx edx
add esp, 20
popad
xor eax, eax
xor ebx, ebx
ret
 
.read_symbol:
or ax, -1
test esi, esi
jz .retFFFF
lodsb
test al, al
jnz ansi2uni_char
xor eax, eax
xor esi, esi
.retFFFF:
ret
 
.read_symbols:
call .read_symbol
stosw
loop .read_symbols
ret
 
;----------------------------------------------------------------
;
; fs_RamdiskWrite - LFN variant for writing to sys floppy
;
; esi points to filename
; ebx pointer to 64-bit number = first wanted byte, 0+
; may be ebx=0 - start from first byte
; ecx number of bytes to write, 0+
; edx mem location to data
;
; ret ebx = bytes written (maybe 0)
; eax = 0 ok write or other = errormsg
;
;--------------------------------------------------------------
@@:
push ERROR_ACCESS_DENIED
fs_RamdiskWrite.ret0:
pop eax
xor ebx, ebx
ret
 
fs_RamdiskWrite:
cmp byte [esi], 0
jz @b
pushad
call rd_find_lfn
jnc .found
popad
push ERROR_FILE_NOT_FOUND
jmp .ret0
.found:
; must not be directory
test byte [edi+11], 10h
jz @f
popad
push ERROR_ACCESS_DENIED
jmp .ret0
@@:
; FAT does not support files larger than 4GB
test ebx, ebx
jz .l1
cmp dword [ebx+4], 0
jz @f
.eof:
popad
push ERROR_END_OF_FILE
jmp .ret0
@@:
mov ebx, [ebx]
.l1:
; now edi points to direntry, ebx=start byte to write,
; ecx=number of bytes to write, edx=data pointer
call fat_update_datetime
 
; extend file if needed
add ecx, ebx
jc .eof ; FAT does not support files larger than 4GB
push 0 ; return value=0
cmp ecx, [edi+28]
jbe .length_ok
cmp ecx, ebx
jz .length_ok
call ramdisk_extend_file
jnc .length_ok
; ramdisk_extend_file can return two error codes: FAT table error or disk full.
; First case is fatal error, in second case we may write some data
mov [esp], eax
cmp al, ERROR_DISK_FULL
jz .disk_full
pop eax
mov [esp+28], eax
popad
xor ebx, ebx
ret
.disk_full:
; correct number of bytes to write
mov ecx, [edi+28]
cmp ecx, ebx
ja .length_ok
.ret:
pop eax
mov [esp+28], eax ; eax=return value
sub edx, [esp+20]
mov [esp+16], edx ; ebx=number of written bytes
popad
ret
.length_ok:
; now ebx=start pos, ecx=end pos, both lie inside file
sub ecx, ebx
jz .ret
movzx edi, word [edi+26] ; starting cluster
.write_loop:
sub ebx, 0x200
jae .next_cluster
push ecx
neg ebx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
mov eax, edi
shl eax, 9
add eax, RAMDISK+31*512+0x200
sub eax, ebx
mov ebx, eax
mov eax, edx
call memmove
xor ebx, ebx
add edx, ecx
sub [esp], ecx
pop ecx
jz .ret
.next_cluster:
movzx edi, word [edi*2+RAMDISK_FAT]
jmp .write_loop
 
ramdisk_extend_file.zero_size:
xor eax, eax
jmp ramdisk_extend_file.start_extend
 
; extends file on ramdisk to given size, new data area is filled by 0
; in: edi->direntry, ecx=new size
; out: CF=0 => OK, eax=0
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL)
ramdisk_extend_file:
push ecx
; find the last cluster of file
movzx eax, word [edi+26] ; first cluster
mov ecx, [edi+28]
jecxz .zero_size
@@:
sub ecx, 0x200
jbe @f
mov eax, [eax*2+RAMDISK_FAT]
and eax, 0xFFF
jz .fat_err
cmp eax, 0xFF8
jb @b
.fat_err:
pop ecx
push ERROR_FAT_TABLE
pop eax
stc
ret
@@:
push eax
mov eax, [eax*2+RAMDISK_FAT]
and eax, 0xFFF
cmp eax, 0xFF8
pop eax
jb .fat_err
; set length to full number of sectors and make sure that last sector is zero-padded
sub [edi+28], ecx
push eax edi
mov edi, eax
shl edi, 9
lea edi, [edi+RAMDISK+31*512+0x200+ecx]
neg ecx
xor eax, eax
rep stosb
pop edi eax
.start_extend:
pop ecx
; now do extend
push edx esi
mov esi, RAMDISK_FAT+2*2 ; start scan from cluster 2
mov edx, 2847 ; number of clusters to scan
.extend_loop:
cmp [edi+28], ecx
jae .extend_done
; add new sector
push ecx
mov ecx, edx
push edi
mov edi, esi
jecxz .disk_full
push eax
xor eax, eax
repnz scasw
pop eax
jnz .disk_full
mov word [edi-2], 0xFFF
mov esi, edi
mov edx, ecx
sub edi, RAMDISK_FAT
shr edi, 1
dec edi ; now edi=new cluster
test eax, eax
jz .first_cluster
mov [RAMDISK_FAT+eax*2], di
jmp @f
.first_cluster:
pop eax ; eax->direntry
push eax
mov [eax+26], di
@@:
push edi
shl edi, 9
add edi, RAMDISK+31*512
xor eax, eax
mov ecx, 512/4
rep stosd
pop eax ; eax=new cluster
pop edi ; edi->direntry
pop ecx ; ecx=required size
add dword [edi+28], 0x200
jmp .extend_loop
.extend_done:
mov [edi+28], ecx
pop esi edx
xor eax, eax ; CF=0
ret
.disk_full:
pop edi ecx
pop esi edx
stc
push ERROR_DISK_FULL
pop eax
ret
 
fat_update_datetime:
call get_time_for_file
mov [edi+22], ax ; last write time
call get_date_for_file
mov [edi+24], ax ; last write date
mov [edi+18], ax ; last access date
ret
 
;----------------------------------------------------------------
;
; fs_RamdiskSetFileEnd - set end of file on ramdisk
;
; esi points to filename
; ebx points to 64-bit number = new file size
; ecx ignored (reserved)
; edx ignored (reserved)
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_RamdiskSetFileEnd:
cmp byte [esi], 0
jnz @f
.access_denied:
push ERROR_ACCESS_DENIED
jmp .ret
@@:
push edi
call rd_find_lfn
jnc @f
pop edi
push ERROR_FILE_NOT_FOUND
.ret:
pop eax
ret
@@:
; must not be directory
test byte [edi+11], 10h
jz @f
pop edi
jmp .access_denied
@@:
; file size must not exceed 4Gb
cmp dword [ebx+4], 0
jz @f
pop edi
push ERROR_END_OF_FILE
jmp .ret
@@:
; set file modification date/time to current
call fat_update_datetime
mov eax, [ebx]
cmp eax, [edi+28]
jb .truncate
ja .expand
pop edi
xor eax, eax
ret
.expand:
push ecx
mov ecx, eax
call ramdisk_extend_file
pop ecx
pop edi
ret
.truncate:
mov [edi+28], eax
push ecx
movzx ecx, word [edi+26]
test eax, eax
jz .zero_size
; find new last sector
@@:
sub eax, 0x200
jbe @f
movzx ecx, word [RAMDISK_FAT+ecx*2]
jmp @b
@@:
; zero data at the end of last sector
push ecx
mov edi, ecx
shl edi, 9
lea edi, [edi+RAMDISK+31*512+eax+0x200]
mov ecx, eax
neg ecx
xor eax, eax
rep stosb
pop ecx
; terminate FAT chain
lea ecx, [RAMDISK_FAT+ecx+ecx]
push dword [ecx]
mov word [ecx], 0xFFF
pop ecx
and ecx, 0xFFF
jmp .delete
.zero_size:
and word [edi+26], 0
.delete:
; delete FAT chain starting with ecx
; mark all clusters as free
cmp ecx, 0xFF8
jae .deleted
lea ecx, [RAMDISK_FAT+ecx+ecx]
push dword [ecx]
and word [ecx], 0
pop ecx
and ecx, 0xFFF
jmp .delete
.deleted:
pop ecx
pop edi
xor eax, eax
ret
 
fs_RamdiskGetFileInfo:
cmp byte [esi], 0
jnz @f
mov eax, 2 ; unsupported
ret
@@:
push edi
call rd_find_lfn
fs_GetFileInfo_finish:
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
@@:
push esi ebp
xor ebp, ebp
mov esi, edx
and dword [esi+4], 0
call fat_entry_to_bdfe2
pop ebp esi
pop edi
xor eax, eax
ret
 
fs_RamdiskSetFileInfo:
cmp byte [esi], 0
jnz @f
mov eax, 2 ; unsupported
ret
@@:
push edi
call rd_find_lfn
jnc @f
pop edi
mov eax, ERROR_FILE_NOT_FOUND
ret
@@:
call bdfe_to_fat_entry
pop edi
xor eax, eax
ret
 
;----------------------------------------------------------------
;
; fs_RamdiskDelete - delete file or empty folder from ramdisk
;
; esi points to filename
;
; ret eax = 0 ok or other = errormsg
;
;--------------------------------------------------------------
fs_RamdiskDelete:
cmp byte [esi], 0
jnz @f
; cannot delete root!
.access_denied:
push ERROR_ACCESS_DENIED
.pop_ret:
pop eax
ret
@@:
and [rd_prev_sector], 0
and [rd_prev_prev_sector], 0
push edi
call rd_find_lfn
jnc .found
pop edi
push ERROR_FILE_NOT_FOUND
jmp .pop_ret
.found:
cmp dword [edi], '. '
jz .access_denied2
cmp dword [edi], '.. '
jz .access_denied2
test byte [edi+11], 10h
jz .dodel
; we can delete only empty folders!
movzx eax, word [edi+26]
push ebx
mov ebx, eax
shl ebx, 9
add ebx, RAMDISK + 31*0x200 + 2*0x20
.checkempty:
cmp byte [ebx], 0
jz .empty
cmp byte [ebx], 0xE5
jnz .notempty
add ebx, 0x20
test ebx, 0x1FF
jnz .checkempty
movzx eax, word [RAMDISK_FAT + eax*2]
test eax, eax
jz .empty
mov ebx, eax
shl ebx, 9
add ebx, RAMDISK + 31*0x200
jmp .checkempty
.notempty:
pop ebx
.access_denied2:
pop edi
jmp .access_denied
.empty:
pop ebx
.dodel:
movzx eax, word [edi+26]
; delete folder entry
mov byte [edi], 0xE5
; delete LFN (if present)
.lfndel:
test edi, 0x1FF
jnz @f
cmp [rd_prev_sector], 0
jz @f
cmp [rd_prev_sector], -1
jz .lfndone
mov edi, [rd_prev_sector]
push [rd_prev_prev_sector]
pop [rd_prev_sector]
or [rd_prev_prev_sector], -1
shl edi, 9
add edi, RAMDISK + 31*0x200 + 0x200
@@:
sub edi, 0x20
cmp byte [edi], 0xE5
jz .lfndone
cmp byte [edi+11], 0xF
jnz .lfndone
mov byte [edi], 0xE5
jmp .lfndel
.lfndone:
; delete FAT chain
test eax, eax
jz .done
lea eax, [RAMDISK_FAT + eax*2]
push dword [eax]
and word [eax], 0
pop eax
and eax, 0xFFF
jmp .lfndone
.done:
pop edi
xor eax, eax
ret
 
; \end{diamond}
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/blkdev/rdsave.inc
0,0 → 1,30
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
iglobal
saverd_fileinfo:
dd 2 ; subfunction: write
dd 0 ; (reserved)
dd 0 ; (reserved)
dd 1440*1024 ; size 1440 Kb
dd RAMDISK
db 0
.name:
dd ?
endg
sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only)
call restorefatchain
mov ebx, saverd_fileinfo
mov [saverd_fileinfo.name], ecx
pushad
call file_system_lfn ;in ebx
popad
mov [esp+32], eax
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/blkdev/hd_drv.inc
0,0 → 1,928
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; Low-level driver for HDD access
; DMA support by Mario79
; Access through BIOS by diamond
 
align 4
hd_read:
;-----------------------------------------------------------
; input : eax = block to read
; ebx = destination
;-----------------------------------------------------------
and [hd_error], 0
push ecx esi edi ; scan cache
 
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
call calculate_cache
add esi,8
 
mov edi,1
 
hdreadcache:
 
cmp dword [esi+4],0 ; empty
je nohdcache
 
cmp [esi],eax ; correct sector
je yeshdcache
 
nohdcache:
 
add esi,8
inc edi
dec ecx
jnz hdreadcache
 
call find_empty_slot ; ret in edi
cmp [hd_error],0
jne return_01
; Read through BIOS?
cmp [hdpos], 0x80
jae .bios
; DMA read is permitted if [allow_dma_access]=1 or 2
cmp [allow_dma_access], 2
ja .nodma
cmp [dma_hdd], 1
jnz .nodma
call hd_read_dma
jmp @f
.nodma:
call hd_read_pio
jmp @f
.bios:
call bd_read
@@:
cmp [hd_error], 0
jne return_01
; lea esi,[edi*8+HD_CACHE]
; push eax
call calculate_cache_1
lea esi,[edi*8+esi]
; pop eax
 
mov [esi],eax ; sector number
mov dword [esi+4],1 ; hd read - mark as same as in hd
 
yeshdcache:
 
mov esi,edi
shl esi,9
; add esi,HD_CACHE+65536
push eax
call calculate_cache_2
add esi,eax
pop eax
 
mov edi,ebx
mov ecx,512/4
cld
rep movsd ; move data
return_01:
pop edi esi ecx
ret
 
align 4
hd_read_pio:
push eax edx
 
call wait_for_hd_idle
cmp [hd_error],0
jne hd_read_error
 
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al ; ATAFeatures ॣ¨áâà "®á®¡¥­­®á⥩"
inc edx
inc eax
out dx,al ; ATASectorCount áçñâ稪 ᥪâ®à®¢
inc edx
mov eax,[esp+4]
out dx,al ; ATASectorNumber ॣ¨áâà ­®¬¥à  ᥪâ®à 
shr eax,8
inc edx
out dx,al ; ATACylinder ­®¬¥à 樫¨­¤à  (¬« ¤è¨© ¡ ©â)
shr eax,8
inc edx
out dx,al ; ­®¬¥à 樫¨­¤à  (áâ à訩 ¡ ©â)
shr eax,8
inc edx
and al,1+2+4+8
add al,byte [hdid]
add al,128+64+32
out dx,al ; ­®¬¥à £®«®¢ª¨/­®¬¥à ¤¨áª 
inc edx
mov al,20h
out dx,al ; ATACommand ॣ¨áâà ª®¬ ­¤
sti
 
call wait_for_sector_buffer
 
cmp [hd_error],0
jne hd_read_error
 
cli
push edi
shl edi,9
; add edi,HD_CACHE+65536
push eax
call calculate_cache_2
add edi,eax
pop eax
 
mov ecx,256
mov edx,[hdbase]
cld
rep insw
pop edi
sti
 
pop edx eax
ret
 
disable_ide_int:
; mov edx,[hdbase]
; add edx,0x206
; mov al,2
; out dx,al
cli
ret
 
enable_ide_int:
; mov edx,[hdbase]
; add edx,0x206
; mov al,0
; out dx,al
sti
ret
 
align 4
hd_write:
;-----------------------------------------------------------
; input : eax = block
; ebx = pointer to memory
;-----------------------------------------------------------
push ecx esi edi
 
; check if the cache already has the sector and overwrite it
 
; mov ecx,cache_max
; mov esi,HD_CACHE+8
call calculate_cache
add esi,8
 
mov edi,1
 
hdwritecache:
 
cmp dword [esi+4],0 ; if cache slot is empty
je not_in_cache_write
 
cmp [esi],eax ; if the slot has the sector
je yes_in_cache_write
 
not_in_cache_write:
 
add esi,8
inc edi
dec ecx
jnz hdwritecache
 
; sector not found in cache
; write the block to a new location
 
call find_empty_slot ; ret in edi
cmp [hd_error],0
jne hd_write_access_denied
 
; lea esi,[edi*8+HD_CACHE]
; push eax
call calculate_cache_1
lea esi,[edi*8+esi]
; pop eax
 
mov [esi],eax ; sector number
 
yes_in_cache_write:
 
mov dword [esi+4],2 ; write - differs from hd
 
shl edi,9
; add edi,HD_CACHE+65536
push eax
call calculate_cache_2
add edi,eax
pop eax
 
mov esi,ebx
mov ecx,512/4
cld
rep movsd ; move data
hd_write_access_denied:
pop edi esi ecx
ret
 
align 4
cache_write_pio:
; call disable_ide_int
 
call wait_for_hd_idle
cmp [hd_error],0
jne hd_write_error
 
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al
inc edx
inc eax
out dx,al
inc edx
mov eax,[esi] ; eax = sector to write
out dx,al
shr eax,8
inc edx
out dx,al
shr eax,8
inc edx
out dx,al
shr eax,8
inc edx
and al,1+2+4+8
add al,byte [hdid]
add al,128+64+32
out dx,al
inc edx
mov al,30h
out dx,al
sti
 
call wait_for_sector_buffer
 
cmp [hd_error],0
jne hd_write_error
 
push ecx esi
 
cli
mov esi,edi
shl esi,9
; add esi,HD_CACHE+65536 ; esi = from memory position
push eax
call calculate_cache_2
add esi,eax
pop eax
 
mov ecx,256
mov edx,[hdbase]
cld
rep outsw
sti
 
; call enable_ide_int
pop esi ecx
 
ret
 
save_hd_wait_timeout:
 
push eax
mov eax,[timer_ticks]
add eax,300 ; 3 sec timeout
mov [hd_wait_timeout],eax
pop eax
ret
 
align 4
check_hd_wait_timeout:
 
push eax
mov eax,[hd_wait_timeout]
cmp [timer_ticks], eax
jg hd_timeout_error
pop eax
mov [hd_error],0
ret
 
;iglobal
; hd_timeout_str db 'K : FS - HD timeout',0
; hd_read_str db 'K : FS - HD read error',0
; hd_write_str db 'K : FS - HD write error',0
; hd_lba_str db 'K : FS - HD LBA error',0
;endg
 
hd_timeout_error:
 
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_timeout_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD timeout\n"
 
mov [hd_error],1
pop eax
ret
 
hd_read_error:
 
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_read_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD read error\n"
pop edx eax
ret
 
hd_write_error:
 
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_write_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD write error\n"
ret
 
hd_write_error_dma:
; call clear_hd_cache
; call clear_application_table_status
; mov esi, hd_write_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD read error\n"
pop esi
ret
 
hd_lba_error:
; call clear_hd_cache
; call clear_application_table_status
; mov esi,hd_lba_str
; call sys_msg_board_str
DEBUGF 1,"K : FS - HD LBA error\n"
jmp LBA_read_ret
 
 
align 4
wait_for_hd_idle:
 
push eax edx
 
call save_hd_wait_timeout
 
mov edx,[hdbase]
add edx,0x7
 
wfhil1:
 
call check_hd_wait_timeout
cmp [hd_error],0
jne @f
 
in al,dx
test al,128
jnz wfhil1
 
@@:
 
pop edx eax
ret
 
 
align 4
wait_for_sector_buffer:
 
push eax edx
 
mov edx,[hdbase]
add edx,0x7
 
call save_hd_wait_timeout
 
hdwait_sbuf: ; wait for sector buffer to be ready
 
call check_hd_wait_timeout
cmp [hd_error],0
jne @f
 
in al,dx
test al,8
jz hdwait_sbuf
 
mov [hd_error],0
 
cmp [hd_setup],1 ; do not mark error for setup request
je buf_wait_ok
 
test al,1 ; previous command ended up with an error
jz buf_wait_ok
@@:
mov [hd_error],1
 
buf_wait_ok:
 
pop edx eax
ret
 
; \begin{Mario79}
align 4
wait_for_sector_dma_ide0:
push eax
push edx
call save_hd_wait_timeout
.wait:
call change_task
cmp [irq14_func], hdd_irq14
jnz .done
call check_hd_wait_timeout
cmp [hd_error], 0
jz .wait
mov [irq14_func], hdd_irq_null
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
.done:
pop edx
pop eax
ret
 
align 4
wait_for_sector_dma_ide1:
push eax
push edx
call save_hd_wait_timeout
.wait:
call change_task
cmp [irq15_func], hdd_irq15
jnz .done
call check_hd_wait_timeout
cmp [hd_error], 0
jz .wait
mov [irq15_func], hdd_irq_null
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
mov al, 0
out dx, al
.done:
pop edx
pop eax
ret
 
iglobal
align 4
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary
IDE_descriptor_table:
dd IDE_DMA
dw 0x2000
dw 0x8000
 
dma_cur_sector dd not 40h
dma_hdpos dd 0
irq14_func dd hdd_irq_null
irq15_func dd hdd_irq_null
endg
 
uglobal
; all uglobals are zeroed at boot
dma_process dd 0
dma_slot_ptr dd 0
cache_chain_pos dd 0
cache_chain_ptr dd 0
cache_chain_size db 0
cache_chain_started db 0
dma_task_switched db 0
dma_hdd db 0
allow_dma_access db 0
endg
 
align 4
hdd_irq14:
pushfd
cli
pushad
mov [irq14_func], hdd_irq_null
mov dx, [IDEContrRegsBaseAddr]
mov al, 0
out dx, al
; call update_counters
; mov ebx, [dma_process]
; cmp [CURRENT_TASK], ebx
; jz .noswitch
; mov [dma_task_switched], 1
; mov edi, [dma_slot_ptr]
; mov eax, [CURRENT_TASK]
; mov [dma_process], eax
; mov eax, [TASK_BASE]
; mov [dma_slot_ptr], eax
; mov [CURRENT_TASK], ebx
; mov [TASK_BASE], edi
; mov byte [DONT_SWITCH], 1
; call do_change_task
.noswitch:
popad
popfd
align 4
hdd_irq_null:
ret
 
align 4
hdd_irq15:
pushfd
cli
pushad
mov [irq15_func], hdd_irq_null
mov dx, [IDEContrRegsBaseAddr]
add dx, 8
mov al, 0
out dx, al
; call update_counters
; mov ebx, [dma_process]
; cmp [CURRENT_TASK], ebx
; jz .noswitch
; mov [dma_task_switched], 1
; mov edi, [dma_slot_ptr]
; mov eax, [CURRENT_TASK]
; mov [dma_process], eax
; mov eax, [TASK_BASE]
; mov [dma_slot_ptr], eax
; mov [CURRENT_TASK], ebx
; mov [TASK_BASE], edi
; mov byte [DONT_SWITCH], 1
; call do_change_task
.noswitch:
popad
popfd
ret
 
align 4
hd_read_dma:
push eax
push edx
mov edx,[dma_hdpos]
cmp edx,[hdpos]
jne .notread
mov edx, [dma_cur_sector]
cmp eax, edx
jb .notread
add edx, 15
cmp [esp+4], edx
ja .notread
mov eax, [esp+4]
sub eax, [dma_cur_sector]
shl eax, 9
add eax, (OS_BASE+IDE_DMA)
push ecx esi edi
mov esi, eax
shl edi, 9
; add edi, HD_CACHE+0x10000
push eax
call calculate_cache_2
add edi,eax
pop eax
 
mov ecx, 512/4
cld
rep movsd
pop edi esi ecx
pop edx
pop eax
ret
.notread:
mov eax, IDE_descriptor_table
mov dword [eax], IDE_DMA
mov word [eax+4], 0x2000
sub eax, OS_BASE
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
jz @f
add edx, 8
@@:
push edx
add edx, 4
out dx, eax
pop edx
mov al, 0
out dx, al
add edx, 2
mov al, 6
out dx, al
call wait_for_hd_idle
cmp [hd_error], 0
jnz hd_read_error
call disable_ide_int
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al
inc edx
mov eax, 10h
out dx, al
inc edx
mov eax, [esp+4]
out dx, al
shr eax, 8
inc edx
out dx, al
shr eax, 8
inc edx
out dx, al
shr eax, 8
inc edx
and al, 0xF
add al, byte [hdid]
add al, 11100000b
out dx, al
inc edx
mov al, 0xC8
out dx, al
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
jz @f
add dx, 8
@@:
mov al, 9
out dx, al
mov eax, [CURRENT_TASK]
mov [dma_process], eax
mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax
cmp [hdbase], 0x1F0
jnz .ide1
mov [irq14_func], hdd_irq14
jmp @f
.ide1:
mov [irq15_func], hdd_irq15
@@:
call enable_ide_int
cmp [hdbase], 0x1F0
jnz .wait_ide1
call wait_for_sector_dma_ide0
jmp @f
.wait_ide1:
call wait_for_sector_dma_ide1
@@:
cmp [hd_error], 0
jnz hd_read_error
mov eax,[hdpos]
mov [dma_hdpos],eax
pop edx
pop eax
mov [dma_cur_sector], eax
jmp hd_read_dma
 
align 4
write_cache_sector:
mov [cache_chain_size],1
mov [cache_chain_pos],edi
write_cache_chain:
cmp [hdpos], 0x80
jae bd_write_cache_chain
push esi
mov eax, IDE_descriptor_table
mov edx,eax
pusha
mov esi,[cache_chain_pos]
shl esi, 9
call calculate_cache_2
add esi,eax
mov edi, (OS_BASE+IDE_DMA)
mov dword [edx], IDE_DMA
movzx ecx, [cache_chain_size]
shl ecx, 9
mov word [edx+4], cx
shr ecx,2
cld
rep movsd
popa
sub eax, OS_BASE
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
jz @f
add edx, 8
@@:
push edx
add edx, 4
out dx, eax
pop edx
mov al, 0
out dx, al
add edx, 2
mov al, 6
out dx, al
call wait_for_hd_idle
cmp [hd_error], 0
jnz hd_write_error_dma
call disable_ide_int
xor eax, eax
mov edx, [hdbase]
inc edx
out dx, al
inc edx
mov al, [cache_chain_size]
out dx, al
inc edx
mov esi, [cache_chain_ptr]
mov eax, [esi]
out dx, al
shr eax, 8
inc edx
out dx, al
shr eax, 8
inc edx
out dx, al
shr eax, 8
inc edx
and al, 0xF
add al, byte [hdid]
add al, 11100000b
out dx, al
inc edx
mov al, 0xCA
out dx, al
mov dx, [IDEContrRegsBaseAddr]
cmp [hdbase], 0x1F0
jz @f
add dx, 8
@@:
mov al, 1
out dx, al
mov eax, [CURRENT_TASK]
mov [dma_process], eax
mov eax, [TASK_BASE]
mov [dma_slot_ptr], eax
cmp [hdbase], 0x1F0
jnz .ide1
mov [irq14_func], hdd_irq14
jmp @f
.ide1:
mov [irq15_func], hdd_irq15
@@:
call enable_ide_int
mov [dma_cur_sector], not 0x40
cmp [hdbase], 0x1F0
jnz .wait_ide1
call wait_for_sector_dma_ide0
jmp @f
.wait_ide1:
call wait_for_sector_dma_ide1
@@:
cmp [hd_error], 0
jnz hd_write_error_dma
pop esi
ret
 
uglobal
IDEContrRegsBaseAddr dw ?
endg
; \end{Mario79}
 
; \begin{diamond}
uglobal
bios_hdpos dd 0 ; 0 is invalid value for [hdpos]
bios_cur_sector dd ?
bios_read_len dd ?
endg
bd_read:
push eax
push edx
mov edx, [bios_hdpos]
cmp edx, [hdpos]
jne .notread
mov edx, [bios_cur_sector]
cmp eax, edx
jb .notread
add edx, [bios_read_len]
dec edx
cmp eax, edx
ja .notread
sub eax, [bios_cur_sector]
shl eax, 9
add eax, (OS_BASE+0x9A000)
push ecx esi edi
mov esi, eax
shl edi, 9
; add edi, HD_CACHE+0x10000
push eax
call calculate_cache_2
add edi,eax
pop eax
 
mov ecx, 512/4
cld
rep movsd
pop edi esi ecx
pop edx
pop eax
ret
.notread:
push ecx
mov dl, 42h
mov ecx, 16
call int13_call
pop ecx
test eax, eax
jnz .v86err
test edx, edx
jz .readerr
mov [bios_read_len], edx
mov edx, [hdpos]
mov [bios_hdpos], edx
pop edx
pop eax
mov [bios_cur_sector], eax
jmp bd_read
.readerr:
.v86err:
mov [hd_error], 1
jmp hd_read_error
 
bd_write_cache_chain:
pusha
mov esi, [cache_chain_pos]
shl esi, 9
call calculate_cache_2
add esi, eax
mov edi, OS_BASE + 0x9A000
movzx ecx, [cache_chain_size]
push ecx
shl ecx, 9-2
rep movsd
pop ecx
mov dl, 43h
mov eax, [cache_chain_ptr]
mov eax, [eax]
call int13_call
test eax, eax
jnz .v86err
cmp edx, ecx
jnz .writeerr
popa
ret
.v86err:
.writeerr:
popa
mov [hd_error], 1
jmp hd_write_error
 
uglobal
int13_regs_in rb v86_regs.size
int13_regs_out rb v86_regs.size
endg
 
int13_call:
; Because this code uses fixed addresses,
; it can not be run simultaniously by many threads.
; In current implementation it is protected by common mutex 'hd1_status'
mov word [OS_BASE + 510h], 10h ; packet length
mov word [OS_BASE + 512h], cx ; number of sectors
mov dword [OS_BASE + 514h], 9A000000h ; buffer 9A00:0000
mov dword [OS_BASE + 518h], eax
and dword [OS_BASE + 51Ch], 0
push ebx ecx esi edi
mov ebx, int13_regs_in
mov edi, ebx
mov ecx, v86_regs.size/4
xor eax, eax
rep stosd
mov byte [ebx+v86_regs.eax+1], dl
mov eax, [hdpos]
lea eax, [BiosDisksData+(eax-80h)*4]
mov dl, [eax]
mov byte [ebx+v86_regs.edx], dl
movzx edx, byte [eax+1]
; mov dl, 5
test edx, edx
jnz .hasirq
dec edx
jmp @f
.hasirq:
pushad
stdcall enable_irq, edx
popad
@@:
mov word [ebx+v86_regs.esi], 510h
mov word [ebx+v86_regs.ss], 9000h
mov word [ebx+v86_regs.esp], 0A000h
mov word [ebx+v86_regs.eip], 500h
mov [ebx+v86_regs.eflags], 20200h
mov esi, [sys_v86_machine]
mov ecx, 0x502
call v86_start
and [bios_hdpos], 0
pop edi esi ecx ebx
movzx edx, byte [OS_BASE + 512h]
test byte [int13_regs_out+v86_regs.eflags], 1
jnz @f
mov edx, ecx
@@:
ret
; \end{diamond}
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/blkdev/cd_drv.inc
0,0 → 1,929
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;**********************************************************
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ óñòðîéñòâîì ÑD (ATAPI)
;**********************************************************
; Àâòîð ÷àñòè èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷
; Àäàïòàöèÿ, äîðàáîòêà è ðàçðàáîòêà Mario79,<Lrz>
 
; Ìàêñèìàëüíîå êîëè÷åñòâî ïîâòîðåíèé îïåðàöèè ÷òåíèÿ
MaxRetr equ 10
; Ïðåäåëüíîå âðåìÿ îæèäàíèÿ ãîòîâíîñòè ê ïðèåìó êîìàíäû
; (â òèêàõ)
BSYWaitTime equ 1000 ;2
NoTickWaitTime equ 0xfffff
CDBlockSize equ 2048
;********************************************
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ Ñ ÏÎÂÒÎÐÀÌÈ *
;* Ìíîãîêðàòíîå ïîâòîðåíèå ÷òåíèÿ ïðè ñáîÿõ *
;********************************************
ReadCDWRetr:
;-----------------------------------------------------------
; input : eax = block to read
; ebx = destination
;-----------------------------------------------------------
pushad
mov eax,[CDSectorAddress]
mov ebx,[CDDataBuf_pointer]
call cd_calculate_cache
xor edi,edi
add esi,8
inc edi
.hdreadcache:
; cmp dword [esi+4],0 ; empty
; je .nohdcache
cmp [esi],eax ; correct sector
je .yeshdcache
.nohdcache:
add esi,8
inc edi
dec ecx
jnz .hdreadcache
call find_empty_slot_CD_cache ; ret in edi
 
push edi
push eax
call cd_calculate_cache_2
shl edi,11
add edi,eax
mov [CDDataBuf_pointer],edi
pop eax
pop edi
 
call ReadCDWRetr_1
cmp [DevErrorCode],0
jne .exit
 
mov [CDDataBuf_pointer],ebx
call cd_calculate_cache_1
lea esi,[edi*8+esi]
mov [esi],eax ; sector number
; mov dword [esi+4],1 ; hd read - mark as same as in hd
.yeshdcache:
mov esi,edi
shl esi,11 ;9
push eax
call cd_calculate_cache_2
add esi,eax
pop eax
mov edi,ebx ;[CDDataBuf_pointer]
mov ecx,512 ;/4
cld
rep movsd ; move data
.exit:
popad
ret
 
ReadCDWRetr_1:
pushad
 
; Öèêë, ïîêà êîìàíäà íå âûïîëíåíà óñïåøíî èëè íå
; èñ÷åðïàíî êîëè÷åñòâî ïîïûòîê
mov ECX,MaxRetr
@@NextRetr:
; Ïîäàòü êîìàíäó
;*************************************************
;* ÏÎËÍÎÅ ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÊÎÌÏÀÊÒ-ÄÈÑÊÀ *
;* Ñ÷èòûâàþòñÿ äàííûå ïîëüçîâàòåëÿ, èíôîðìàöèÿ *
;* ñóáêàíàëà è êîíòðîëüíàÿ èíôîðìàöèÿ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
;* CDSectorAddress - àäðåñ ñ÷èòûâàåìîãî ñåêòîðà. *
;* Äàííûå ñ÷èòûâàåòñÿ â ìàññèâ CDDataBuf. *
;*************************************************
;ReadCD:
push ecx
; pusha
; Çàäàòü ðàçìåð ñåêòîðà
; mov [CDBlockSize],2048 ;2352
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ
; ñåêòîðà äàííûõ
; Çàäàòü êîä êîìàíäû Read CD
mov [PacketCommand],byte 0x28 ;0xBE
; Çàäàòü àäðåñ ñåêòîðà
mov AX,word [CDSectorAddress+2]
xchg AL,AH
mov word [PacketCommand+2],AX
mov AX,word [CDSectorAddress]
xchg AL,AH
mov word [PacketCommand+4],AX
; mov eax,[CDSectorAddress]
; mov [PacketCommand+2],eax
; Çàäàòü êîëè÷åñòâî ñ÷èòûâàåìûõ ñåêòîðîâ
mov [PacketCommand+8],byte 1
; Çàäàòü ñ÷èòûâàíèå äàííûõ â ïîëíîì îáúåìå
; mov [PacketCommand+9],byte 0xF8
; Ïîäàòü êîìàíäó
call SendPacketDatCommand
pop ecx
; ret
 
; cmp [DevErrorCode],0
test eax,eax
jz @@End_4
 
or ecx,ecx ;{SPraid.simba} (for cd load)
jz @@End_4
dec ecx
 
cmp [timer_ticks_enable],0
jne @f
mov eax,NoTickWaitTime
.wait:
dec eax
; test eax,eax
jz @@NextRetr
jmp .wait
@@:
; Çàäåðæêà íà 2,5 ñåêóíäû
; mov EAX,[timer_ticks]
; add EAX,50 ;250
;@@Wait:
; call change_task
; cmp EAX,[timer_ticks]
; ja @@Wait
loop @@NextRetr
@@End_4:
mov dword [DevErrorCode],eax
popad
ret
 
 
; Óíèâåðñàëüíûå ïðîöåäóðû, îáåñïå÷èâàþùèå âûïîëíåíèå
; ïàêåòíûõ êîìàíä â ðåæèìå PIO
 
; Ìàêñèìàëüíî äîïóñòèìîå âðåìÿ îæèäàíèÿ ðåàêöèè
; óñòðîéñòâà íà ïàêåòíóþ êîìàíäó (â òèêàõ)
 
MaxCDWaitTime equ 1000 ;200 ;10 ñåêóíä
uglobal
; Îáëàñòü ïàìÿòè äëÿ ôîðìèðîâàíèÿ ïàêåòíîé êîìàíäû
PacketCommand: rb 12 ;DB 12 DUP (?)
; Îáëàñòü ïàìÿòè äëÿ ïðèåìà äàííûõ îò äèñêîâîäà
;CDDataBuf DB 4096 DUP (0)
; Ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ â áàéòàõ
;CDBlockSize DW ?
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà äàííûõ
CDSectorAddress: DD ?
; Âðåìÿ íà÷àëà î÷åðåäíîé îïåðàöèè ñ äèñêîì
TickCounter_1 DD 0
; Âðåìÿ íà÷àëà îæèäàíèÿ ãîòîâíîñòè óñòðîéñòâà
WURStartTime DD 0
; óêàçàòåëü áóôåðà äëÿ ñ÷èòûâàíèÿ
CDDataBuf_pointer dd 0
endg
;****************************************************
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, *
;* ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×Ó ÎÄÍÎÃÎ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ *
;* ÐÀÇÌÅÐÎÌ 2048 ÁÀÉÒ ÎÒ ÓÑÒÐÎÉÑÒÂÀ Ê ÕÎÑÒÓ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò; *
;* CDBlockSize - ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ. *
; return eax DevErrorCode
;****************************************************
SendPacketDatCommand:
xor eax,eax
; mov byte [DevErrorCode],al
; Çàäàòü ðåæèì CHS
mov byte [ATAAddressMode],al
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
mov byte [ATAFeatures],al
mov byte [ATASectorCount],al
mov byte [ATASectorNumber],al
; Çàãðóçèòü ðàçìåð ïåðåäàâàåìîãî áëîêà
mov [ATAHead],al
; mov AX,[CDBlockSize]
mov [ATACylinder],CDBlockSize
mov [ATACommand],0A0h
call SendCommandToHDD_1
test eax,eax
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
jnz @@End_8 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
 
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó
; ïàêåòíîé êîìàíäû
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
mov ecx,NoTickWaitTime
@@WaitDevice0:
cmp [timer_ticks_enable],0
jne @f
dec ecx
; test ecx,ecx
jz @@Err1_1
jmp .test
@@:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,BSYWaitTime
ja @@Err1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
.test:
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitDevice0
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitDevice0
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Err6
; Ïîñëàòü ïàêåòíóþ êîìàíäó
cli
mov DX,[ATABasePortAddr]
mov AX,[PacketCommand]
out DX,AX
mov AX,[PacketCommand+2]
out DX,AX
mov AX,[PacketCommand+4]
out DX,AX
mov AX,[PacketCommand+6]
out DX,AX
mov AX,[PacketCommand+8]
out DX,AX
mov AX,[PacketCommand+10]
out DX,AX
sti
; Îæèäàíèå ãîòîâíîñòè äàííûõ
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
mov ecx,NoTickWaitTime
@@WaitDevice1:
cmp [timer_ticks_enable],0
jne @f
dec ecx
; test ecx,ecx
jz @@Err1_1
jmp .test_1
@@:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,MaxCDWaitTime
ja @@Err1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
.test_1:
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitDevice1
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitDevice1
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Err6_temp
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf
; Çàãðóçèòü àäðåñ ðåãèñòðà äàííûõ êîíòðîëëåðà
mov DX,[ATABasePortAddr] ;ïîðò 1x0h
; Çàãðóçèòü â ñ÷åò÷èê ðàçìåð áëîêà â áàéòàõ
xor ecx,ecx
mov CX,CDBlockSize
; Âû÷èñëèòü ðàçìåð áëîêà â 16-ðàçðÿäíûõ ñëîâàõ
shr CX,1 ;ðàçäåëèòü ðàçìåð áëîêà íà 2
; Ïðèíÿòü áëîê äàííûõ
cli
cld
rep insw
sti
; Óñïåøíîå çàâåðøåíèå ïðèåìà äàííûõ
@@End_8:
xor eax,eax
ret
 
; Çàïèñàòü êîä îøèáêè
@@Err1_1:
xor eax,eax
inc eax
ret
; mov [DevErrorCode],1
; ret
@@Err6_temp:
mov eax,7
ret
; mov [DevErrorCode],7
; ret
@@Err6:
mov eax,6
ret
; mov [DevErrorCode],6
;@@End_8:
; ret
 
 
 
;***********************************************
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, *
;* ÍÅ ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×È ÄÀÍÍÛÕ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç *
;* ãëîáàëüíûå ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò. *
;***********************************************
SendPacketNoDatCommand:
pushad
xor eax,eax
; mov byte [DevErrorCode],al
; Çàäàòü ðåæèì CHS
mov byte [ATAAddressMode],al
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
mov byte [ATAFeatures],al
mov byte [ATASectorCount],al
mov byte [ATASectorNumber],al
mov word [ATACylinder],ax
mov byte [ATAHead],al
mov [ATACommand],0A0h
call SendCommandToHDD_1
; cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
test eax,eax
jnz @@End_9 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó
; ïàêåòíîé êîìàíäû
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
@@WaitDevice0_1:
call change_task
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,BSYWaitTime
ja @@Err1_3 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitDevice0_1
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Err6_1
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitDevice0_1
; Ïîñëàòü ïàêåòíóþ êîìàíäó
; cli
mov DX,[ATABasePortAddr]
mov AX,word [PacketCommand]
out DX,AX
mov AX,word [PacketCommand+2]
out DX,AX
mov AX,word [PacketCommand+4]
out DX,AX
mov AX,word [PacketCommand+6]
out DX,AX
mov AX,word [PacketCommand+8]
out DX,AX
mov AX,word [PacketCommand+10]
out DX,AX
; sti
cmp [ignore_CD_eject_wait],1
je @@clear_DEC
; Îæèäàíèå ïîäòâåðæäåíèÿ ïðèåìà êîìàíäû
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
@@WaitDevice1_1:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,MaxCDWaitTime
ja @@Err1_3 ;îøèáêà òàéì-àóòà
; Îæèäàòü îñâîáîæäåíèÿ óñòðîéñòâà
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitDevice1_1
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Err6_1
test AL,40h ;ñîñòîÿíèå ñèãíàëà DRDY
jz @@WaitDevice1_1
@@clear_DEC:
and [DevErrorCode],0
popad
ret
; Çàïèñàòü êîä îøèáêè
@@Err1_3:
xor eax,eax
inc eax
jmp @@End_9
@@Err6_1:
mov eax,6
@@End_9:
mov [DevErrorCode],eax
popad
ret
 
;****************************************************
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); *
;* DiskNumber - íîìåð äèñêà (0 èëè 1); *
;* ATAFeatures - "îñîáåííîñòè"; *
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; *
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; *
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; *
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; *
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); *
;* ATACommand - êîä êîìàíäû. *
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: *
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; *
;* â DevErrorCode - íîëü. *
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò *
;* âîçâðàùåí êîä îøèáêè â eax *
;****************************************************
SendCommandToHDD_1:
; pushad
; mov [DevErrorCode],0 not need
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà
cmp [ATAAddressMode],1
ja @@Err2_4
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà
mov BX,[ChannelNumber]
cmp BX,1
jb @@Err3_4
cmp BX,2
ja @@Err3_4
; Óñòàíîâèòü áàçîâûé àäðåñ
dec BX
shl BX,1
movzx ebx,bx
mov AX,[ebx+StandardATABases]
mov [ATABasePortAddr],AX
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû
; Âûáðàòü íóæíûé äèñê
mov DX,[ATABasePortAddr]
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê
mov AL,[DiskNumber]
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà
ja @@Err4_4
shl AL,4
or AL,10100000b
out DX,AL
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ
inc DX
mov eax,[timer_ticks]
mov [TickCounter_1],eax
mov ecx,NoTickWaitTime
@@WaitHDReady_2:
cmp [timer_ticks_enable],0
jne @f
dec ecx
; test ecx,ecx
jz @@Err1_4
jmp .test
@@:
call change_task
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
mov eax,[timer_ticks]
sub eax,[TickCounter_1]
cmp eax,BSYWaitTime ;300 ;îæèäàòü 3 ñåê.
ja @@Err1_4 ;îøèáêà òàéì-àóòà
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ
.test:
in AL,DX
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
test AL,80h
jnz @@WaitHDReady_2
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ
test AL,08h
jnz @@WaitHDReady_2
 
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà
cli
mov DX,[ATABasePortAddr]
inc DX ;ðåãèñòð "îñîáåííîñòåé"
mov AL,[ATAFeatures]
out DX,AL
inc DX ;ñ÷åò÷èê ñåêòîðîâ
mov AL,[ATASectorCount]
out DX,AL
inc DX ;ðåãèñòð íîìåðà ñåêòîðà
mov AL,[ATASectorNumber]
out DX,AL
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò)
mov AX,[ATACylinder]
out DX,AL
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò)
mov AL,AH
out DX,AL
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà
mov AL,[DiskNumber]
shl AL,4
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè
ja @@Err5_4
or AL,[ATAHead]
or AL,10100000b
mov AH,[ATAAddressMode]
shl AH,6
or AL,AH
out DX,AL
; Ïîñëàòü êîìàíäó
mov AL,[ATACommand]
inc DX ;ðåãèñòð êîìàíä
out DX,AL
sti
; Ñáðîñèòü ïðèçíàê îøèáêè
; mov [DevErrorCode],0
@@End_10:
xor eax,eax
ret
; Çàïèñàòü êîä îøèáêè
@@Err1_4:
xor eax,eax
inc eax
; mov [DevErrorCode],1
ret
@@Err2_4:
mov eax,2
; mov [DevErrorCode],2
ret
@@Err3_4:
mov eax,3
; mov [DevErrorCode],3
ret
@@Err4_4:
mov eax,4
; mov [DevErrorCode],4
ret
@@Err5_4:
mov eax,5
; mov [DevErrorCode],5
; Çàâåðøåíèå ðàáîòû ïðîãðàììû
ret
; sti
; popad
 
;*************************************************
;* ÎÆÈÄÀÍÈÅ ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ Ê ÐÀÁÎÒÅ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;*************************************************
WaitUnitReady:
pusha
; Çàïîìíèòü âðåìÿ íà÷àëà îïåðàöèè
mov EAX,[timer_ticks]
mov [WURStartTime],EAX
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó TEST UNIT READY
mov [PacketCommand],word 00h
; ÖÈÊË ÎÆÈÄÀÍÈß ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ
mov ecx,NoTickWaitTime
@@SendCommand:
; Ïîäàòü êîìàíäó ïðîâåðêè ãîòîâíîñòè
call SendPacketNoDatCommand
cmp [timer_ticks_enable],0
jne @f
cmp [DevErrorCode],0
je @@End_11
dec ecx
; cmp ecx,0
jz .Error
jmp @@SendCommand
@@:
call change_task
; Ïðîâåðèòü êîä îøèáêè
cmp [DevErrorCode],0
je @@End_11
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ ãîòîâíîñòè
mov EAX,[timer_ticks]
sub EAX,[WURStartTime]
cmp EAX,MaxCDWaitTime
jb @@SendCommand
.Error:
; Îøèáêà òàéì-àóòà
mov [DevErrorCode],1
@@End_11:
popa
ret
 
;*************************************************
;* ÇÀÏÐÅÒÈÒÜ ÑÌÅÍÓ ÄÈÑÊÀ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;*************************************************
prevent_medium_removal:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
; Çàäàòü êîä êîìàíäû
mov [PacketCommand],byte 0x1E
; Çàäàòü êîä çàïðåòà
mov [PacketCommand+4],byte 11b
; Ïîäàòü êîìàíäó
call SendPacketNoDatCommand
mov eax,ATAPI_IDE0_lock
add eax,[cdpos]
dec eax
mov [eax],byte 1
popa
ret
 
;*************************************************
;* ÐÀÇÐÅØÈÒÜ ÑÌÅÍÓ ÄÈÑÊÀ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;*************************************************
allow_medium_removal:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
; Çàäàòü êîä êîìàíäû
mov [PacketCommand],byte 0x1E
; Çàäàòü êîä çàïðåòà
mov [PacketCommand+4],byte 00b
; Ïîäàòü êîìàíäó
call SendPacketNoDatCommand
mov eax,ATAPI_IDE0_lock
add eax,[cdpos]
dec eax
mov [eax],byte 0
popa
ret
 
;*************************************************
;* ÇÀÃÐÓÇÈÒÜ ÍÎÑÈÒÅËÜ Â ÄÈÑÊÎÂÎÄ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;*************************************************
LoadMedium:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT
; Çàäàòü êîä êîìàíäû
mov [PacketCommand],word 1Bh
; Çàäàòü îïåðàöèþ çàãðóçêè íîñèòåëÿ
mov [PacketCommand+4],word 00000011b
; Ïîäàòü êîìàíäó
call SendPacketNoDatCommand
popa
ret
 
;*************************************************
;* ÈÇÂËÅ×Ü ÍÎÑÈÒÅËÜ ÈÇ ÄÈÑÊÎÂÎÄÀ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;*************************************************
EjectMedium:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT
; Çàäàòü êîä êîìàíäû
mov [PacketCommand],word 1Bh
; Çàäàòü îïåðàöèþ èçâëå÷åíèÿ íîñèòåëÿ
mov [PacketCommand+4],word 00000010b
; Ïîäàòü êîìàíäó
call SendPacketNoDatCommand
popa
ret
 
;*************************************************
;* Ïðîâåðèòü ñîáûòèå íàæàòèÿ êíîïêè èçâëå÷åíèÿ *
;* äèñêà *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;*************************************************
align 4
check_ATAPI_device_event:
pusha
mov eax,[timer_ticks]
sub eax,[timer_ATAPI_check]
cmp eax,100
jb .end_1
mov al,[DRIVE_DATA+1]
and al,11b
cmp al,10b
jz .ide3
.ide2_1:
mov al,[DRIVE_DATA+1]
and al,1100b
cmp al,1000b
jz .ide2
.ide1_1:
mov al,[DRIVE_DATA+1]
and al,110000b
cmp al,100000b
jz .ide1
.ide0_1:
mov al,[DRIVE_DATA+1]
and al,11000000b
cmp al,10000000b
jz .ide0
.end:
 
sti
mov eax,[timer_ticks]
mov [timer_ATAPI_check],eax
.end_1:
popa
ret
 
.ide3:
cli
cmp [ATAPI_IDE3_lock],1
jne .ide2_1
cmp [IDE_Channel_2],0
jne .ide1_1
cmp [cd_status],0
jne .end
mov [IDE_Channel_2],1
call reserve_ok2
mov [ChannelNumber],2
mov [DiskNumber],1
mov [cdpos],4
call GetEvent_StatusNotification
cmp [CDDataBuf+4],byte 1
je .eject_ide3
call syscall_cdaudio.free
jmp .ide2_1
.eject_ide3:
call .eject
call syscall_cdaudio.free
jmp .ide2_1
 
.ide2:
cli
cmp [ATAPI_IDE2_lock],1
jne .ide1_1
cmp [IDE_Channel_2],0
jne .ide1_1
cmp [cd_status],0
jne .end
mov [IDE_Channel_2],1
call reserve_ok2
mov [ChannelNumber],2
mov [DiskNumber],0
mov [cdpos],3
call GetEvent_StatusNotification
cmp [CDDataBuf+4],byte 1
je .eject_ide2
call syscall_cdaudio.free
jmp .ide1_1
.eject_ide2:
call .eject
call syscall_cdaudio.free
jmp .ide1_1
 
.ide1:
cli
cmp [ATAPI_IDE1_lock],1
jne .ide0_1
cmp [IDE_Channel_1],0
jne .end
cmp [cd_status],0
jne .end
mov [IDE_Channel_1],1
call reserve_ok2
mov [ChannelNumber],1
mov [DiskNumber],1
mov [cdpos],2
call GetEvent_StatusNotification
cmp [CDDataBuf+4],byte 1
je .eject_ide1
call syscall_cdaudio.free
jmp .ide0_1
.eject_ide1:
call .eject
call syscall_cdaudio.free
jmp .ide0_1
 
.ide0:
cli
cmp [ATAPI_IDE0_lock],1
jne .end
cmp [IDE_Channel_1],0
jne .end
cmp [cd_status],0
jne .end
mov [IDE_Channel_1],1
call reserve_ok2
mov [ChannelNumber],1
mov [DiskNumber],0
mov [cdpos],1
call GetEvent_StatusNotification
cmp [CDDataBuf+4],byte 1
je .eject_ide0
call syscall_cdaudio.free
jmp .end
.eject_ide0:
call .eject
call syscall_cdaudio.free
jmp .end
 
.eject:
call clear_CD_cache
call allow_medium_removal
mov [ignore_CD_eject_wait],1
call EjectMedium
mov [ignore_CD_eject_wait],0
ret
iglobal
timer_ATAPI_check dd 0
ATAPI_IDE0_lock db 0
ATAPI_IDE1_lock db 0
ATAPI_IDE2_lock db 0
ATAPI_IDE3_lock db 0
ignore_CD_eject_wait db 0
endg
;*************************************************
;* Ïîëó÷èòü ñîîáùåíèå î ñîáûòèè èëè ñîñòîÿíèè *
;* óñòðîéñòâà *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;*************************************************
GetEvent_StatusNotification:
pusha
mov [CDDataBuf_pointer],CDDataBuf
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
; Çàäàòü êîä êîìàíäû
mov [PacketCommand],byte 4Ah
mov [PacketCommand+1],byte 00000001b
; Çàäàòü çàïðîñ êëàññà ñîîáùåíèé
mov [PacketCommand+4],byte 00010000b
; Ðàçìåð âûäåëåííîé îáëàñòè
mov [PacketCommand+7],byte 8h
mov [PacketCommand+8],byte 0h
; Ïîäàòü êîìàíäó
call SendPacketDatCommand
popa
ret
 
;*************************************************
; ïðî÷èòàòü èíôîðìàöèþ èç TOC
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;*************************************************
Read_TOC:
pusha
mov [CDDataBuf_pointer],CDDataBuf
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
; Ñôîðìèðîâàòü ïàêåòíóþ êîìàíäó äëÿ ñ÷èòûâàíèÿ
; ñåêòîðà äàííûõ
mov [PacketCommand],byte 0x43
; Çàäàòü ôîðìàò
mov [PacketCommand+2],byte 1
; Ðàçìåð âûäåëåííîé îáëàñòè
mov [PacketCommand+7],byte 0xFF
mov [PacketCommand+8],byte 0h
; Ïîäàòü êîìàíäó
call SendPacketDatCommand
popa
ret
 
;*************************************************
;* ÎÏÐÅÄÅËÈÒÜ ÎÁÙÅÅ ÊÎËÈ×ÅÑÒÂÎ ÑÅÊÒÎÐΠÍÀ ÄÈÑÊÅ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;*************************************************
;ReadCapacity:
; pusha
;; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
; call clear_packet_buffer
;; Çàäàòü ðàçìåð áóôåðà â áàéòàõ
; mov [CDBlockSize],8
;; Ñôîðìèðîâàòü êîìàíäó READ CAPACITY
; mov [PacketCommand],word 25h
;; Ïîäàòü êîìàíäó
; call SendPacketDatCommand
; popa
; ret
 
clear_packet_buffer:
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
and [PacketCommand],dword 0
and [PacketCommand+4],dword 0
and [PacketCommand+8],dword 0
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/blkdev/flp_drv.inc
0,0 → 1,626
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;**********************************************************
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ êîíòðîëëåðîì ãèáêîãî äèñêà
;**********************************************************
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
; Àäàïòàöèÿ è äîðàáîòêà Mario79
 
;give_back_application_data: ; ïåðåñëàòü ïðèëîæåíèþ
; mov edi,[TASK_BASE]
; mov edi,[edi+TASKDATA.mem_start]
; add edi,ecx
give_back_application_data_1:
mov esi,FDD_BUFF ;FDD_DataBuffer ;0x40000
xor ecx,ecx
mov cx,128
cld
rep movsd
ret
 
;take_data_from_application: ; âçÿòü èç ïðèëîæåíè
; mov esi,[TASK_BASE]
; mov esi,[esi+TASKDATA.mem_start]
; add esi,ecx
take_data_from_application_1:
mov edi,FDD_BUFF ;FDD_DataBuffer ;0x40000
xor ecx,ecx
mov cx,128
cld
rep movsd
ret
 
; Êîäû çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì (FDC_Status)
FDC_Normal equ 0 ;íîðìàëüíîå çàâåðøåíèå
FDC_TimeOut equ 1 ;îøèáêà òàéì-àóòà
FDC_DiskNotFound equ 2 ;â äèñêîâîäå íåò äèñêà
FDC_TrackNotFound equ 3 ;äîðîæêà íå íàéäåíà
FDC_SectorNotFound equ 4 ;ñåêòîð íå íàéäåí
 
; Ìàêñèìàëüíûå çíà÷åíèÿ êîîðäèíàò ñåêòîðà (çàäàííûå
; çíà÷åíèÿ ñîîòâåòñòâóþò ïàðàìåòðàì ñòàíäàðòíîãî
; òðåõäþéìîâîãî ãèáêîãî äèñêà îáúåìîì 1,44 Ìá)
MAX_Track equ 79
MAX_Head equ 1
MAX_Sector equ 18
 
uglobal
; Ñ÷åò÷èê òèêîâ òàéìåðà
TickCounter dd ?
; Êîä çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì ÍÃÌÄ
FDC_Status DB ?
; Ôëàã ïðåðûâàíèÿ îò ÍÃÌÄ
FDD_IntFlag DB ?
; Ìîìåíò íà÷àëà ïîñëåäíåé îïåðàöèè ñ ÍÃÌÄ
FDD_Time DD ?
; Íîìåð äèñêîâîäà
FDD_Type db 0
; Êîîðäèíàòû ñåêòîðà
FDD_Track DB ?
FDD_Head DB ?
FDD_Sector DB ?
 
; Áëîê ðåçóëüòàòà îïåðàöèè
FDC_ST0 DB ?
FDC_ST1 DB ?
FDC_ST2 DB ?
FDC_C DB ?
FDC_H DB ?
FDC_R DB ?
FDC_N DB ?
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè
ReadRepCounter DB ?
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè
RecalRepCounter DB ?
endg
; Îáëàñòü ïàìÿòè äëÿ õðàíåíèÿ ïðî÷èòàííîãî ñåêòîðà
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?)
fdd_motor_status db 0
timer_fdd_motor dd 0
 
;*************************************
;* ÈÍÈÖÈÀËÈÇÀÖÈß ÐÅÆÈÌÀ ÏÄÏ ÄËß ÍÃÌÄ *
;*************************************
Init_FDC_DMA:
pushad
mov al,0
out 0x0c,al ; reset the flip-flop to a known state.
mov al,6 ; mask channel 2 so we can reprogram it.
out 0x0a,al
mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy
out 0x0b,al
mov al,0
out 0x0c,al ; reset the flip-flop to a known state.
mov eax,0xD000
out 0x04,al ; set the channel 2 starting address to 0
shr eax,8
out 0x04,al
shr eax,8
out 0x81,al
mov al,0
out 0x0c, al ; reset flip-flop
mov al, 0xff ;set count (actual size -1)
out 0x5, al
mov al,0x1 ;[dmasize] ;(0x1ff = 511 / 0x23ff =9215)
out 0x5,al
mov al,2
out 0xa,al
popad
ret
 
;***********************************
;* ÇÀÏÈÑÀÒÜ ÁÀÉÒ Â ÏÎÐÒ ÄÀÍÍÛÕ FDC *
;* Ïàðàìåòðû: *
;* AL - âûâîäèìûé áàéò. *
;***********************************
FDCDataOutput:
; pusha
push eax ecx edx
mov AH,AL ;çàïîìíèòü áàéò â AH
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà
mov [FDC_Status],FDC_Normal
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïðèåìó äàííûõ
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC)
mov ecx, 0x10000 ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà
@@TestRS:
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS
and AL,0C0h ;âûäåëèòü ðàçðÿäû 6 è 7
cmp AL,80h ;ïðîâåðèòü ðàçðÿäû 6 è 7
je @@OutByteToFDC
loop @@TestRS
; Îøèáêà òàéì-àóòà
mov [FDC_Status],FDC_TimeOut
jmp @@End_5
; Âûâåñòè áàéò â ïîðò äàííûõ
@@OutByteToFDC:
inc DX
mov AL,AH
out DX,AL
@@End_5:
; popa
pop edx ecx eax
ret
 
;******************************************
;* ÏÐÎ×ÈÒÀÒÜ ÁÀÉÒ ÈÇ ÏÎÐÒÀ ÄÀÍÍÛÕ FDC *
;* Ïðîöåäóðà íå èìååò âõîäíûõ ïàðàìåòðîâ. *
;* Âûõîäíûå äàííûå: *
;* AL - ñ÷èòàííûé áàéò. *
;******************************************
FDCDataInput:
push ECX
push DX
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà
mov [FDC_Status],FDC_Normal
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïåðåäà÷å äàííûõ
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC)
xor CX,CX ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà
@@TestRS_1:
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS
and AL,0C0h ;âûäëèòü ðàçðÿäû 6 è 7
cmp AL,0C0h ;ïðîâåðèòü ðàçðÿäû 6 è 7
je @@GetByteFromFDC
loop @@TestRS_1
; Îøèáêà òàéì-àóòà
mov [FDC_Status],FDC_TimeOut
jmp @@End_6
; Ââåñòè áàéò èç ïîðòà äàííûõ
@@GetByteFromFDC:
inc DX
in AL,DX
@@End_6: pop DX
pop ECX
ret
 
;*********************************************
;* ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ *
;*********************************************
FDCInterrupt:
; Óñòàíîâèòü ôëàã ïðåðûâàíè
mov [FDD_IntFlag],1
ret
 
 
;******************************************
;* ÓÑÒÀÍÎÂÈÒÜ ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈÉ *
;* ÍÃÌÄ *
;******************************************
SetUserInterrupts:
mov [fdc_irq_func],FDCInterrupt
ret
 
;*******************************************
;* ÎÆÈÄÀÍÈÅ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ *
;*******************************************
WaitFDCInterrupt:
pusha
; Ñáðîñèòü áàéò ñîñòîÿíèÿ îïåðàöèè
mov [FDC_Status],FDC_Normal
; Ñáðîñèòü ôëàã ïðåðûâàíè
mov [FDD_IntFlag],0
; Îáíóëèòü ñ÷åò÷èê òèêîâ
mov eax,[timer_ticks]
mov [TickCounter],eax
; Îæèäàòü óñòàíîâêè ôëàãà ïðåðûâàíèÿ ÍÃÌÄ
@@TestRS_2:
cmp [FDD_IntFlag],0
jnz @@End_7 ;ïðåðûâàíèå ïðîèçîøëî
call change_task
mov eax,[timer_ticks]
sub eax,[TickCounter]
cmp eax,50 ;25 ;5 ;îæèäàòü 5 òèêîâ
jb @@TestRS_2
; jl @@TestRS_2
; Îøèáêà òàéì-àóòà
mov [FDC_Status],FDC_TimeOut
; mov [flp_status],0
@@End_7: popa
ret
 
;*********************************
;* ÂÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ "A:" *
;*********************************
FDDMotorON:
pusha
; cmp [fdd_motor_status],1
; je fdd_motor_on
mov al,[flp_number]
cmp [fdd_motor_status],al
je fdd_motor_on
; Ïðîèçâåñòè ñáðîñ êîíòðîëëåðà ÍÃÌÄ
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè
mov AL,0
out DX,AL
; Âûáðàòü è âêëþ÷èòü ìîòîð äèñêîâîäà
cmp [flp_number],1
jne FDDMotorON_B
; call FDDMotorOFF_B
mov AL,1Ch ; Floppy A
jmp FDDMotorON_1
FDDMotorON_B:
; call FDDMotorOFF_A
mov AL,2Dh ; Floppy B
FDDMotorON_1:
out DX,AL
; Îáíóëèòü ñ÷åò÷èê òèêîâ
mov eax,[timer_ticks]
mov [TickCounter],eax
; Îæèäàòü 0,5 ñ
@@dT:
call change_task
mov eax,[timer_ticks]
sub eax,[TickCounter]
cmp eax,50 ;10
jb @@dT
cmp [flp_number],1
jne fdd_motor_on_B
mov [fdd_motor_status],1
jmp fdd_motor_on
fdd_motor_on_B:
mov [fdd_motor_status],2
fdd_motor_on:
call save_timer_fdd_motor
popa
ret
 
;*****************************************
;* ÑÎÕÐÀÍÅÍÈÅ ÓÊÀÇÀÒÅËß ÂÐÅÌÅÍÈ *
;*****************************************
save_timer_fdd_motor:
mov eax,[timer_ticks]
mov [timer_fdd_motor],eax
ret
 
;*****************************************
;* ÏÐÎÂÅÐÊÀ ÇÀÄÅÐÆÊÈ ÂÛÊËÞ×ÅÍÈß ÌÎÒÎÐÀ *
;*****************************************
align 4
check_fdd_motor_status:
cmp [fdd_motor_status],0
je end_check_fdd_motor_status_1
mov eax,[timer_ticks]
sub eax,[timer_fdd_motor]
cmp eax,500
jb end_check_fdd_motor_status
call FDDMotorOFF
mov [fdd_motor_status],0
end_check_fdd_motor_status_1:
mov [flp_status],0
end_check_fdd_motor_status:
ret
 
;**********************************
;* ÂÛÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ *
;**********************************
FDDMotorOFF:
push AX
push DX
cmp [flp_number],1
jne FDDMotorOFF_1
call FDDMotorOFF_A
jmp FDDMotorOFF_2
FDDMotorOFF_1:
call FDDMotorOFF_B
FDDMotorOFF_2:
pop DX
pop AX
; ñáðîñ ôëàãîâ êåøèðîâàíèÿ â ñâÿçè ñ óñòàðåâàíèåì èíôîðìàöèè
mov [root_read],0
mov [flp_fat],0
ret
 
FDDMotorOFF_A:
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè
mov AL,0Ch ; Floppy A
out DX,AL
ret
 
FDDMotorOFF_B:
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè
mov AL,5h ; Floppy B
out DX,AL
ret
 
;*******************************
;* ÐÅÊÀËÈÁÐÎÂÊÀ ÄÈÑÊÎÂÎÄÀ "A:" *
;*******************************
RecalibrateFDD:
pusha
call save_timer_fdd_motor
; Ïîäàòü êîìàíäó "Ðåêàëèáðîâêà"
mov AL,07h
call FDCDataOutput
mov AL,00h
call FDCDataOutput
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè
call WaitFDCInterrupt
; cmp [FDC_Status],0
; je no_fdc_status_error
; mov [flp_status],0
;no_fdc_status_error:
call save_timer_fdd_motor
popa
ret
 
;*****************************************************
;* ÏÎÈÑÊ ÄÎÐÎÆÊÈ *
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: *
;* FDD_Track - íîìåð äîðîæêè (0-79); *
;* FDD_Head - íîìåð ãîëîâêè (0-1). *
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. *
;*****************************************************
SeekTrack:
pusha
call save_timer_fdd_motor
; Ïîäàòü êîìàíäó "Ïîèñê"
mov AL,0Fh
call FDCDataOutput
; Ïåðåäàòü áàéò íîìåðà ãîëîâêè/íàêîïèòåë
mov AL,[FDD_Head]
shl AL,2
call FDCDataOutput
; Ïåðåäàòü áàéò íîìåðà äîðîæêè
mov AL,[FDD_Track]
call FDCDataOutput
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè
call WaitFDCInterrupt
cmp [FDC_Status],FDC_Normal
jne @@Exit
; Ñîõðàíèòü ðåçóëüòàò ïîèñêà
mov AL,08h
call FDCDataOutput
call FDCDataInput
mov [FDC_ST0],AL
call FDCDataInput
mov [FDC_C],AL
; Ïðîâåðèòü ðåçóëüòàò ïîèñêà
; Ïîèñê çàâåðøåí?
test [FDC_ST0],100000b
je @@Err
; Çàäàííûé òðåê íàéäåí?
mov AL,[FDC_C]
cmp AL,[FDD_Track]
jne @@Err
; Íîìåð ãîëîâêè ñîâïàäàåò ñ çàäàííûì?
mov AL,[FDC_ST0]
and AL,100b
shr AL,2
cmp AL,[FDD_Head]
jne @@Err
; Îïåðàöèÿ çàâåðøåíà óñïåøíî
mov [FDC_Status],FDC_Normal
jmp @@Exit
@@Err: ; Òðåê íå íàéäåí
mov [FDC_Status],FDC_TrackNotFound
; mov [flp_status],0
@@Exit:
call save_timer_fdd_motor
popa
ret
 
;*******************************************************
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ *
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: *
;* FDD_Track - íîìåð äîðîæêè (0-79); *
;* FDD_Head - íîìåð ãîëîâêè (0-1); *
;* FDD_Sector - íîìåð ñåêòîðà (1-18). *
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. *
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ *
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. *
;*******************************************************
ReadSector:
pushad
call save_timer_fdd_motor
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ
mov AX,0
mov DX,03F7h
out DX,AL
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè
mov [dmamode],0x46
call Init_FDC_DMA
; Ïîäàòü êîìàíäó "×òåíèå äàííûõ"
mov AL,0E6h ;÷òåíèå â ìóëüòèòðåêîâîì ðåæèìå
call FDCDataOutput
mov AL,[FDD_Head]
shl AL,2
call FDCDataOutput
mov AL,[FDD_Track]
call FDCDataOutput
mov AL,[FDD_Head]
call FDCDataOutput
mov AL,[FDD_Sector]
call FDCDataOutput
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò)
call FDCDataOutput
mov AL,18 ;+1; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå
call FDCDataOutput
mov AL,1Bh ;çíà÷åíèå GPL
call FDCDataOutput
mov AL,0FFh ;çíà÷åíèå DTL
call FDCDataOutput
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè
call WaitFDCInterrupt
cmp [FDC_Status],FDC_Normal
jne @@Exit_1
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè
call GetStatusInfo
test [FDC_ST0],11011000b
jnz @@Err_1
mov [FDC_Status],FDC_Normal
jmp @@Exit_1
@@Err_1: mov [FDC_Status],FDC_SectorNotFound
; mov [flp_status],0
@@Exit_1:
call save_timer_fdd_motor
popad
ret
 
;*******************************************************
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) *
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: *
;* FDD_Track - íîìåð äîðîæêè (0-79); *
;* FDD_Head - íîìåð ãîëîâêè (0-1); *
;* FDD_Sector - íîìåð ñåêòîðà (1-18). *
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. *
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ *
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. *
;*******************************************************
ReadSectWithRetr:
pusha
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè
mov [RecalRepCounter],0
@@TryAgain:
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè
mov [ReadRepCounter],0
@@ReadSector_1:
call ReadSector
cmp [FDC_Status],0
je @@Exit_2
cmp [FDC_Status],1
je @@Err_3
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè
inc [ReadRepCounter]
cmp [ReadRepCounter],3
jb @@ReadSector_1
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè
call RecalibrateFDD
call SeekTrack
inc [RecalRepCounter]
cmp [RecalRepCounter],3
jb @@TryAgain
; mov [flp_status],0
@@Exit_2:
popa
ret
@@Err_3:
mov [flp_status],0
popa
ret
 
;*******************************************************
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ *
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: *
;* FDD_Track - íîìåð äîðîæêè (0-79); *
;* FDD_Head - íîìåð ãîëîâêè (0-1); *
;* FDD_Sector - íîìåð ñåêòîðà (1-18). *
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. *
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè *
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. *
;*******************************************************
WriteSector:
pushad
call save_timer_fdd_motor
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ
mov AX,0
mov DX,03F7h
out DX,AL
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè
mov [dmamode],0x4A
call Init_FDC_DMA
; Ïîäàòü êîìàíäó "Çàïèñü äàííûõ"
mov AL,0xC5 ;0x45 ;çàïèñü â ìóëüòèòðåêîâîì ðåæèìå
call FDCDataOutput
mov AL,[FDD_Head]
shl AL,2
call FDCDataOutput
mov AL,[FDD_Track]
call FDCDataOutput
mov AL,[FDD_Head]
call FDCDataOutput
mov AL,[FDD_Sector]
call FDCDataOutput
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò)
call FDCDataOutput
mov AL,18; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå
call FDCDataOutput
mov AL,1Bh ;çíà÷åíèå GPL
call FDCDataOutput
mov AL,0FFh ;çíà÷åíèå DTL
call FDCDataOutput
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè
call WaitFDCInterrupt
cmp [FDC_Status],FDC_Normal
jne @@Exit_3
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè
call GetStatusInfo
test [FDC_ST0],11000000b ;11011000b
jnz @@Err_2
mov [FDC_Status],FDC_Normal
jmp @@Exit_3
@@Err_2: mov [FDC_Status],FDC_SectorNotFound
@@Exit_3:
call save_timer_fdd_motor
popad
ret
 
;*******************************************************
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) *
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: *
;* FDD_Track - íîìåð äîðîæêè (0-79); *
;* FDD_Head - íîìåð ãîëîâêè (0-1); *
;* FDD_Sector - íîìåð ñåêòîðà (1-18). *
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. *
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè *
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. *
;*******************************************************
WriteSectWithRetr:
pusha
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè
mov [RecalRepCounter],0
@@TryAgain_1:
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè
mov [ReadRepCounter],0
@@WriteSector_1:
call WriteSector
cmp [FDC_Status],0
je @@Exit_4
cmp [FDC_Status],1
je @@Err_4
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè
inc [ReadRepCounter]
cmp [ReadRepCounter],3
jb @@WriteSector_1
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè
call RecalibrateFDD
call SeekTrack
inc [RecalRepCounter]
cmp [RecalRepCounter],3
jb @@TryAgain_1
@@Exit_4:
popa
ret
@@Err_4:
mov [flp_status],0
popa
ret
 
;*********************************************
;* ÏÎËÓ×ÈÒÜ ÈÍÔÎÐÌÀÖÈÞ Î ÐÅÇÓËÜÒÀÒÅ ÎÏÅÐÀÖÈÈ *
;*********************************************
GetStatusInfo:
push AX
call FDCDataInput
mov [FDC_ST0],AL
call FDCDataInput
mov [FDC_ST1],AL
call FDCDataInput
mov [FDC_ST2],AL
call FDCDataInput
mov [FDC_C],AL
call FDCDataInput
mov [FDC_H],AL
call FDCDataInput
mov [FDC_R],AL
call FDCDataInput
mov [FDC_N],AL
pop AX
ret
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/blkdev/fdc.inc
0,0 → 1,71
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
iglobal
;function pointers.
fdc_irq_func dd fdc_null
endg
 
uglobal
dmasize db 0x0
dmamode db 0x0
endg
 
fdc_init: ;start with clean tracks.
mov edi,OS_BASE+0xD201
mov al,0
mov ecx,160
rep stosb
ret
 
fdc_irq:
call [fdc_irq_func]
fdc_null:
ret
 
save_image:
call reserve_flp
call restorefatchain
pusha
call check_label
cmp [FDC_Status],0
jne unnecessary_save_image
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],0 ; Ñòîðîíà
mov [FDD_Sector],1 ; Ñåêòîð
mov esi,RAMDISK
call SeekTrack
save_image_1:
push esi
call take_data_from_application_1
pop esi
add esi,512
call WriteSectWithRetr
; call WriteSector
cmp [FDC_Status],0
jne unnecessary_save_image
inc [FDD_Sector]
cmp [FDD_Sector],19
jne save_image_1
mov [FDD_Sector],1
inc [FDD_Head]
cmp [FDD_Head],2
jne save_image_1
mov [FDD_Head],0
inc [FDD_Track]
call SeekTrack
cmp [FDD_Track],80
jne save_image_1
unnecessary_save_image:
mov [fdc_irq_func],fdc_null
popa
mov [flp_status],0
ret
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/blkdev/ide_cache.inc
0,0 → 1,922
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;**************************************************************************
;
; [cache_ide[X]_pointer]
; or [cache_ide[X]_data_pointer] first entry in cache list
;
; +0 - lba sector
; +4 - state of cache sector
; 0 = empty
; 1 = used for read ( same as in hd )
; 2 = used for write ( differs from hd )
;
; [cache_ide[X]_system_data]
; or [cache_ide[x]_appl_data] - cache entries
;
;**************************************************************************
 
$Revision$
 
 
align 4
write_cache:
;-----------------------------------------------------------
; write all changed sectors to disk
;-----------------------------------------------------------
push eax ecx edx esi edi
 
; write difference ( 2 ) from cache to hd
call calculate_cache
add esi,8
mov edi,1
write_cache_more:
cmp dword [esi+4],2 ; if cache slot is not different
jne .write_chain
mov dword [esi+4],1 ; same as in hd
mov eax,[esi] ; eax = sector to write
cmp eax,[PARTITION_START]
jb danger
cmp eax,[PARTITION_END]
ja danger
cmp [hdpos], 0x80
jae @f
; DMA write is permitted only if [allow_dma_access]=1
cmp [allow_dma_access], 2
jae .nodma
cmp [dma_hdd], 1
jnz .nodma
@@:
; Ž¡ê¥¤¨­ï¥¬ § ¯¨áì 楯®çª¨ ¯®á«¥¤®¢ â¥«ì­ëå ᥪâ®à®¢ ¢ ®¤­® ®¡à é¥­¨¥ ª ¤¨áªã
cmp ecx, 1
jz .nonext
cmp dword [esi+8+4], 2
jnz .nonext
push eax
inc eax
cmp eax, [esi+8]
pop eax
jnz .nonext
cmp [cache_chain_started], 1
jz @f
mov [cache_chain_started], 1
mov [cache_chain_size], 0
mov [cache_chain_pos], edi
mov [cache_chain_ptr], esi
@@:
inc [cache_chain_size]
cmp [cache_chain_size], 16
jnz .continue
jmp .write_chain
.nonext:
call flush_cache_chain
mov [cache_chain_size], 1
mov [cache_chain_ptr], esi
call write_cache_sector
jmp .continue
.nodma:
call cache_write_pio
.write_chain:
call flush_cache_chain
.continue:
danger:
add esi,8
inc edi
dec ecx
jnz write_cache_more
call flush_cache_chain
return_02:
pop edi esi edx ecx eax
ret
 
flush_cache_chain:
cmp [cache_chain_started], 0
jz @f
call write_cache_chain
mov [cache_chain_started], 0
@@:
ret
;--------------------------------------------------------------------
align 4
find_empty_slot:
;-----------------------------------------------------------
; find empty or read slot, flush cache if next 10% is used by write
; output : edi = cache slot
;-----------------------------------------------------------
; push ecx esi
 
search_again:
call calculate_cache_3
shr ecx,3
search_for_empty:
inc edi
call calculate_cache_4
jbe inside_cache
mov edi,1
inside_cache:
push esi
call calculate_cache_1
cmp dword [edi*8+esi+4],2
pop esi
jb found_slot ; it's empty or read
dec ecx
jnz search_for_empty
call write_cache ; no empty slots found, write all
cmp [hd_error],0
jne found_slot_access_denied
jmp search_again ; and start again
found_slot:
call calculate_cache_5
found_slot_access_denied:
ret
;--------------------------------------------------------------------
align 4
clear_hd_cache:
mov [fat_in_cache],-1
mov [fat_change],0
ret
;--------------------------------------------------------------------
align 4
calculate_cache:
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos],1
jne .ide1
cmp [hdd_appl_data],0
jne .ide0_appl_data
mov ecx,[cache_ide0_system_sad_size]
mov esi,[cache_ide0_pointer]
ret
.ide0_appl_data:
mov ecx,[cache_ide0_appl_sad_size]
mov esi,[cache_ide0_data_pointer]
ret
.ide1:
cmp [hdpos],2
jne .ide2
cmp [hdd_appl_data],0
jne .ide1_appl_data
mov ecx,[cache_ide1_system_sad_size]
mov esi,[cache_ide1_pointer]
ret
.ide1_appl_data:
mov ecx,[cache_ide1_appl_sad_size]
mov esi,[cache_ide1_data_pointer]
ret
.ide2:
cmp [hdpos],3
jne .ide3
cmp [hdd_appl_data],0
jne .ide2_appl_data
mov ecx,[cache_ide2_system_sad_size]
mov esi,[cache_ide2_pointer]
ret
.ide2_appl_data:
mov ecx,[cache_ide2_appl_sad_size]
mov esi,[cache_ide2_data_pointer]
ret
.ide3:
cmp [hdpos],4
jne .noide
cmp [hdd_appl_data],0
jne .ide3_appl_data
mov ecx,[cache_ide3_system_sad_size]
mov esi,[cache_ide3_pointer]
ret
.ide3_appl_data:
mov ecx,[cache_ide3_appl_sad_size]
mov esi,[cache_ide3_data_pointer]
ret
.noide:
push eax
mov eax,[hdpos]
sub eax,80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax,byte [BiosDisksData+eax*4+2]
imul eax,cache_ide1-cache_ide0
add eax,cache_ide0
jmp .get
@@:
imul eax,cache_ide1-cache_ide0
add eax,BiosDiskCaches
.get:
cmp [hdd_appl_data],0
jne .bd_appl_data
mov ecx,[cache_ide0_system_sad_size-cache_ide0+eax]
mov esi,[cache_ide0_pointer-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
mov ecx,[cache_ide0_appl_sad_size-cache_ide0+eax]
mov esi,[cache_ide0_data_pointer-cache_ide0+eax]
pop eax
ret
;--------------------------------------------------------------------
align 4
calculate_cache_1:
; lea esi,[edi*8+HD_CACHE]
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos],1
jne .ide1
cmp [hdd_appl_data],0
jne .ide0_appl_data
mov esi,[cache_ide0_pointer]
ret
.ide0_appl_data:
mov esi,[cache_ide0_data_pointer]
ret
.ide1:
cmp [hdpos],2
jne .ide2
cmp [hdd_appl_data],0
jne .ide1_appl_data
mov esi,[cache_ide1_pointer]
ret
.ide1_appl_data:
mov esi,[cache_ide1_data_pointer]
ret
.ide2:
cmp [hdpos],3
jne .ide3
cmp [hdd_appl_data],0
jne .ide2_appl_data
mov esi,[cache_ide2_pointer]
ret
.ide2_appl_data:
mov esi,[cache_ide2_data_pointer]
ret
.ide3:
cmp [hdpos],4
jne .noide
cmp [hdd_appl_data],0
jne .ide3_appl_data
mov esi,[cache_ide3_pointer]
ret
.ide3_appl_data:
mov esi,[cache_ide3_data_pointer]
ret
.noide:
push eax
mov eax,[hdpos]
sub eax,80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax,byte [BiosDisksData+eax*4+2]
imul eax,cache_ide1-cache_ide0
add eax,cache_ide0
jmp .get
@@:
imul eax,cache_ide1-cache_ide0
add eax,BiosDiskCaches
.get:
cmp [hdd_appl_data],0
jne .bd_appl_data
mov esi,[cache_ide0_pointer-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
mov esi,[cache_ide0_data_pointer-cache_ide0+eax]
pop eax
ret
 
;--------------------------------------------------------------------
align 4
calculate_cache_2:
; add esi,HD_CACHE+65536
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos],1
jne .ide1
cmp [hdd_appl_data],0
jne .ide0_appl_data
mov eax,[cache_ide0_system_data]
ret
.ide0_appl_data:
mov eax,[cache_ide0_appl_data]
ret
.ide1:
cmp [hdpos],2
jne .ide2
cmp [hdd_appl_data],0
jne .ide1_appl_data
mov eax,[cache_ide1_system_data]
ret
.ide1_appl_data:
mov eax,[cache_ide1_appl_data]
ret
.ide2:
cmp [hdpos],3
jne .ide3
cmp [hdd_appl_data],0
jne .ide2_appl_data
mov eax,[cache_ide2_system_data]
ret
.ide2_appl_data:
mov eax,[cache_ide2_appl_data]
ret
.ide3:
cmp [hdpos],4
jne .noide
cmp [hdd_appl_data],0
jne .ide3_appl_data
mov eax,[cache_ide3_system_data]
ret
.ide3_appl_data:
mov eax,[cache_ide3_appl_data]
ret
.noide:
mov eax,[hdpos]
sub eax,80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax,byte [BiosDisksData+eax*4+2]
imul eax,cache_ide1-cache_ide0
add eax,cache_ide0
jmp .get
@@:
imul eax,cache_ide1-cache_ide0
add eax,BiosDiskCaches
.get:
cmp [hdd_appl_data],0
jne .bd_appl_data
mov eax,[cache_ide0_system_data-cache_ide0+eax]
ret
.bd_appl_data:
mov eax,[cache_ide0_appl_data-cache_ide0+eax]
ret
;--------------------------------------------------------------------
align 4
calculate_cache_3:
; mov ecx,cache_max*10/100
; mov edi,[cache_search_start]
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos],1
jne .ide1
cmp [hdd_appl_data],0
jne .ide0_appl_data
mov ecx,[cache_ide0_system_sad_size]
mov edi,[cache_ide0_search_start]
ret
.ide0_appl_data:
mov ecx,[cache_ide0_appl_sad_size]
mov edi,[cache_ide0_appl_search_start]
ret
.ide1:
cmp [hdpos],2
jne .ide2
cmp [hdd_appl_data],0
jne .ide1_appl_data
mov ecx,[cache_ide1_system_sad_size]
mov edi,[cache_ide1_search_start]
ret
.ide1_appl_data:
mov ecx,[cache_ide1_appl_sad_size]
mov edi,[cache_ide1_appl_search_start]
ret
.ide2:
cmp [hdpos],3
jne .ide3
cmp [hdd_appl_data],0
jne .ide2_appl_data
mov ecx,[cache_ide2_system_sad_size]
mov edi,[cache_ide2_search_start]
ret
.ide2_appl_data:
mov ecx,[cache_ide2_appl_sad_size]
mov edi,[cache_ide2_appl_search_start]
ret
.ide3:
cmp [hdpos],4
jne .noide
cmp [hdd_appl_data],0
jne .ide3_appl_data
mov ecx,[cache_ide3_system_sad_size]
mov edi,[cache_ide3_search_start]
ret
.ide3_appl_data:
mov ecx,[cache_ide3_appl_sad_size]
mov edi,[cache_ide3_appl_search_start]
ret
.noide:
push eax
mov eax,[hdpos]
sub eax,80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax,byte [BiosDisksData+eax*4+2]
imul eax,cache_ide1-cache_ide0
add eax,cache_ide0
jmp .get
@@:
imul eax,cache_ide1-cache_ide0
add eax,BiosDiskCaches
.get:
cmp [hdd_appl_data],0
jne .bd_appl_data
mov ecx,[cache_ide0_system_sad_size-cache_ide0+eax]
mov edi,[cache_ide0_search_start-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
mov ecx,[cache_ide0_appl_sad_size-cache_ide0+eax]
mov edi,[cache_ide0_appl_search_start-cache_ide0+eax]
pop eax
ret
;--------------------------------------------------------------------
align 4
calculate_cache_4:
; cmp edi,cache_max
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos],1
jne .ide1
cmp [hdd_appl_data],0
jne .ide0_appl_data
cmp edi,[cache_ide0_system_sad_size]
ret
.ide0_appl_data:
cmp edi,[cache_ide0_appl_sad_size]
ret
.ide1:
cmp [hdpos],2
jne .ide2
cmp [hdd_appl_data],0
jne .ide1_appl_data
cmp edi,[cache_ide1_system_sad_size]
ret
.ide1_appl_data:
cmp edi,[cache_ide1_appl_sad_size]
ret
.ide2:
cmp [hdpos],3
jne .ide3
cmp [hdd_appl_data],0
jne .ide2_appl_data
cmp edi,[cache_ide2_system_sad_size]
ret
.ide2_appl_data:
cmp edi,[cache_ide2_appl_sad_size]
ret
.ide3:
cmp [hdpos],4
jne .noide
cmp [hdd_appl_data],0
jne .ide3_appl_data
cmp edi,[cache_ide3_system_sad_size]
ret
.ide3_appl_data:
cmp edi,[cache_ide3_appl_sad_size]
ret
.noide:
push eax
mov eax,[hdpos]
sub eax,80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax,byte [BiosDisksData+eax*4+2]
imul eax,cache_ide1-cache_ide0
add eax,cache_ide0
jmp .get
@@:
imul eax,cache_ide1-cache_ide0
add eax,BiosDiskCaches
.get:
cmp [hdd_appl_data],0
jne .bd_appl_data
cmp edi,[cache_ide0_system_sad_size-cache_ide0+eax]
pop eax
ret
.bd_appl_data:
cmp edi,[cache_ide0_appl_sad_size-cache_ide0+eax]
pop eax
ret
 
;--------------------------------------------------------------------
align 4
calculate_cache_5:
; mov [cache_search_start],edi
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [hdpos],1
jne .ide1
cmp [hdd_appl_data],0
jne .ide0_appl_data
mov [cache_ide0_search_start],edi
ret
.ide0_appl_data:
mov [cache_ide0_appl_search_start],edi
ret
.ide1:
cmp [hdpos],2
jne .ide2
cmp [hdd_appl_data],0
jne .ide1_appl_data
mov [cache_ide1_search_start],edi
ret
.ide1_appl_data:
mov [cache_ide1_appl_search_start],edi
ret
.ide2:
cmp [hdpos],3
jne .ide3
cmp [hdd_appl_data],0
jne .ide2_appl_data
mov [cache_ide2_search_start],edi
ret
.ide2_appl_data:
mov [cache_ide2_appl_search_start],edi
ret
.ide3:
cmp [hdpos],4
jne .noide
cmp [hdd_appl_data],0
jne .ide3_appl_data
mov [cache_ide3_search_start],edi
ret
.ide3_appl_data:
mov [cache_ide3_appl_search_start],edi
ret
.noide:
push eax
mov eax,[hdpos]
sub eax,80h
cmp byte [BiosDisksData+eax*4+2], -1
jz @f
movzx eax,byte [BiosDisksData+eax*4+2]
imul eax,cache_ide1-cache_ide0
add eax,cache_ide0
jmp .get
@@:
imul eax,cache_ide1-cache_ide0
add eax,BiosDiskCaches
.get:
cmp [hdd_appl_data],0
jne .bd_appl_data
mov [cache_ide0_search_start-cache_ide0+eax],edi
pop eax
ret
.bd_appl_data:
mov [cache_ide0_appl_search_start-cache_ide0+eax],edi
pop eax
ret
 
;--------------------------------------------------------------------
align 4
find_empty_slot_CD_cache:
;-----------------------------------------------------------
; find empty or read slot, flush cache if next 10% is used by write
; output : edi = cache slot
;-----------------------------------------------------------
.search_again:
call cd_calculate_cache_3
.search_for_empty:
inc edi
call cd_calculate_cache_4
jbe .inside_cache
mov edi,1
.inside_cache:
call cd_calculate_cache_5
ret
;--------------------------------------------------------------------
clear_CD_cache:
pusha
.ide0:
xor eax,eax
cmp [cdpos],1
jne .ide1
mov [cache_ide0_search_start],eax
mov ecx,[cache_ide0_system_sad_size]
mov edi,[cache_ide0_pointer]
call .clear
mov [cache_ide0_appl_search_start],eax
mov ecx,[cache_ide0_appl_sad_size]
mov edi,[cache_ide0_data_pointer]
jmp .continue
.ide1:
cmp [cdpos],2
jne .ide2
mov [cache_ide1_search_start],eax
mov ecx,[cache_ide1_system_sad_size]
mov edi,[cache_ide1_pointer]
call .clear
mov [cache_ide1_appl_search_start],eax
mov ecx,[cache_ide1_appl_sad_size]
mov edi,[cache_ide1_data_pointer]
jmp .continue
.ide2:
cmp [cdpos],3
jne .ide3
mov [cache_ide2_search_start],eax
mov ecx,[cache_ide2_system_sad_size]
mov edi,[cache_ide2_pointer]
call .clear
mov [cache_ide2_appl_search_start],eax
mov ecx,[cache_ide2_appl_sad_size]
mov edi,[cache_ide2_data_pointer]
jmp .continue
.ide3:
mov [cache_ide3_search_start],eax
mov ecx,[cache_ide3_system_sad_size]
mov edi,[cache_ide3_pointer]
call .clear
mov [cache_ide3_appl_search_start],eax
mov ecx,[cache_ide3_appl_sad_size]
mov edi,[cache_ide3_data_pointer]
.continue:
call .clear
popa
ret
.clear:
shl ecx,1
cld
rep stosd
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache:
; mov ecx,cache_max ; entries in cache
; mov esi,HD_CACHE+8
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos],1
jne .ide1
cmp [cd_appl_data],0
jne .ide0_appl_data
mov ecx,[cache_ide0_system_sad_size]
mov esi,[cache_ide0_pointer]
ret
.ide0_appl_data:
mov ecx,[cache_ide0_appl_sad_size]
mov esi,[cache_ide0_data_pointer]
ret
.ide1:
cmp [cdpos],2
jne .ide2
cmp [cd_appl_data],0
jne .ide1_appl_data
mov ecx,[cache_ide1_system_sad_size]
mov esi,[cache_ide1_pointer]
ret
.ide1_appl_data:
mov ecx,[cache_ide1_appl_sad_size]
mov esi,[cache_ide1_data_pointer]
ret
.ide2:
cmp [cdpos],3
jne .ide3
cmp [cd_appl_data],0
jne .ide2_appl_data
mov ecx,[cache_ide2_system_sad_size]
mov esi,[cache_ide2_pointer]
ret
.ide2_appl_data:
mov ecx,[cache_ide2_appl_sad_size]
mov esi,[cache_ide2_data_pointer]
ret
.ide3:
cmp [cd_appl_data],0
jne .ide3_appl_data
mov ecx,[cache_ide3_system_sad_size]
mov esi,[cache_ide3_pointer]
ret
.ide3_appl_data:
mov ecx,[cache_ide3_appl_sad_size]
mov esi,[cache_ide3_data_pointer]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_1:
; lea esi,[edi*8+HD_CACHE]
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos],1
jne .ide1
cmp [cd_appl_data],0
jne .ide0_appl_data
mov esi,[cache_ide0_pointer]
ret
.ide0_appl_data:
mov esi,[cache_ide0_data_pointer]
ret
.ide1:
cmp [cdpos],2
jne .ide2
cmp [cd_appl_data],0
jne .ide1_appl_data
mov esi,[cache_ide1_pointer]
ret
.ide1_appl_data:
mov esi,[cache_ide1_data_pointer]
ret
.ide2:
cmp [cdpos],3
jne .ide3
cmp [cd_appl_data],0
jne .ide2_appl_data
mov esi,[cache_ide2_pointer]
ret
.ide2_appl_data:
mov esi,[cache_ide2_data_pointer]
ret
.ide3:
cmp [cd_appl_data],0
jne .ide3_appl_data
mov esi,[cache_ide3_pointer]
ret
.ide3_appl_data:
mov esi,[cache_ide3_data_pointer]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_2:
; add esi,HD_CACHE+65536
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos],1
jne .ide1
cmp [cd_appl_data],0
jne .ide0_appl_data
mov eax,[cache_ide0_system_data]
ret
.ide0_appl_data:
mov eax,[cache_ide0_appl_data]
ret
.ide1:
cmp [cdpos],2
jne .ide2
cmp [cd_appl_data],0
jne .ide1_appl_data
mov eax,[cache_ide1_system_data]
ret
.ide1_appl_data:
mov eax,[cache_ide1_appl_data]
ret
.ide2:
cmp [cdpos],3
jne .ide3
cmp [cd_appl_data],0
jne .ide2_appl_data
mov eax,[cache_ide2_system_data]
ret
.ide2_appl_data:
mov eax,[cache_ide2_appl_data]
ret
.ide3:
cmp [cd_appl_data],0
jne .ide3_appl_data
mov eax,[cache_ide3_system_data]
ret
.ide3_appl_data:
mov eax,[cache_ide3_appl_data]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_3:
; mov ecx,cache_max*10/100
; mov edi,[cache_search_start]
 
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos],1
jne .ide1
cmp [cd_appl_data],0
jne .ide0_appl_data
mov edi,[cache_ide0_search_start]
ret
.ide0_appl_data:
mov edi,[cache_ide0_appl_search_start]
ret
.ide1:
cmp [cdpos],2
jne .ide2
cmp [cd_appl_data],0
jne .ide1_appl_data
mov edi,[cache_ide1_search_start]
ret
.ide1_appl_data:
mov edi,[cache_ide1_appl_search_start]
ret
.ide2:
cmp [cdpos],3
jne .ide3
cmp [cd_appl_data],0
jne .ide2_appl_data
mov edi,[cache_ide2_search_start]
ret
.ide2_appl_data:
mov edi,[cache_ide2_appl_search_start]
ret
.ide3:
cmp [cd_appl_data],0
jne .ide3_appl_data
mov edi,[cache_ide3_search_start]
ret
.ide3_appl_data:
mov edi,[cache_ide3_appl_search_start]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_4:
; cmp edi,cache_max
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos],1
jne .ide1
cmp [cd_appl_data],0
jne .ide0_appl_data
cmp edi,[cache_ide0_system_sad_size]
ret
.ide0_appl_data:
cmp edi,[cache_ide0_appl_sad_size]
ret
.ide1:
cmp [cdpos],2
jne .ide2
cmp [cd_appl_data],0
jne .ide1_appl_data
cmp edi,[cache_ide1_system_sad_size]
ret
.ide1_appl_data:
cmp edi,[cache_ide1_appl_sad_size]
ret
.ide2:
cmp [cdpos],3
jne .ide3
cmp [cd_appl_data],0
jne .ide2_appl_data
cmp edi,[cache_ide2_system_sad_size]
ret
.ide2_appl_data:
cmp edi,[cache_ide2_appl_sad_size]
ret
.ide3:
cmp [cd_appl_data],0
jne .ide3_appl_data
cmp edi,[cache_ide3_system_sad_size]
ret
.ide3_appl_data:
cmp edi,[cache_ide3_appl_sad_size]
ret
;--------------------------------------------------------------------
align 4
cd_calculate_cache_5:
; mov [cache_search_start],edi
; 1 - IDE0 ... 4 - IDE3
.ide0:
cmp [cdpos],1
jne .ide1
cmp [cd_appl_data],0
jne .ide0_appl_data
mov [cache_ide0_search_start],edi
ret
.ide0_appl_data:
mov [cache_ide0_appl_search_start],edi
ret
.ide1:
cmp [cdpos],2
jne .ide2
cmp [cd_appl_data],0
jne .ide1_appl_data
mov [cache_ide1_search_start],edi
ret
.ide1_appl_data:
mov [cache_ide1_appl_search_start],edi
ret
.ide2:
cmp [cdpos],3
jne .ide3
cmp [cd_appl_data],0
jne .ide2_appl_data
mov [cache_ide2_search_start],edi
ret
.ide2_appl_data:
mov [cache_ide2_appl_search_start],edi
ret
.ide3:
cmp [cd_appl_data],0
jne .ide3_appl_data
mov [cache_ide3_search_start],edi
ret
.ide3_appl_data:
mov [cache_ide3_appl_search_start],edi
ret
;--------------------------------------------------------------------
;align 4
;calculate_linear_to_real:
; shr eax, 12
; mov eax, [page_tabs+eax*4]
; and eax, 0xFFFFF000
; ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/blkdev/cdrom.inc
0,0 → 1,271
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
sys_cd_audio:
 
cmp word [cdbase],word 0
jnz @f
mov eax,1
ret
@@:
 
; eax=1 cdplay at ebx 0x00FFSSMM
; eax=2 get tracklist size of ecx to [ebx]
; eax=3 stop/pause playing
 
cmp eax,1
jnz nocdp
call sys_cdplay
ret
nocdp:
 
cmp eax,2
jnz nocdtl
mov edi,[TASK_BASE]
add edi,TASKDATA.mem_start
add ebx,[edi]
call sys_cdtracklist
ret
nocdtl:
 
cmp eax,3
jnz nocdpause
call sys_cdpause
ret
nocdpause:
 
mov eax,0xffffff01
ret
 
 
 
sys_cd_atapi_command:
 
pushad
 
mov dx,word [cdbase]
add dx,6
mov ax,word [cdid]
out dx,al
mov esi,10
call delay_ms
mov dx,word [cdbase]
add dx,7
in al,dx
and al,0x80
cmp al,0
jnz res
jmp cdl6
res:
mov dx,word [cdbase]
add dx,7
mov al,0x8
out dx,al
mov dx,word [cdbase]
add dx,0x206
mov al,0xe
out dx,al
mov esi,1
call delay_ms
mov dx,word [cdbase]
add dx,0x206
mov al,0x8
out dx,al
mov esi,30
call delay_ms
xor cx,cx
cdl5:
inc cx
cmp cx,10
jz cdl6
mov dx,word [cdbase]
add dx,7
in al,dx
and al,0x88
cmp al,0x00
jz cdl5
mov esi,100
call delay_ms
jmp cdl5
cdl6:
mov dx,word [cdbase]
add dx,4
mov al,0
out dx,al
mov dx,word [cdbase]
add dx,5
mov al,0
out dx,al
mov dx,word [cdbase]
add dx,7
mov al,0xec
out dx,al
mov esi,5
call delay_ms
mov dx,word [cdbase]
add dx,1
mov al,0
out dx,al
add dx,1
mov al,0
out dx,al
add dx,1
mov al,0
out dx,al
add dx,1
mov al,0
out dx,al
add dx,1
mov al,128
out dx,al
add dx,2
mov al,0xa0
out dx,al
xor cx,cx
mov dx,word [cdbase]
add dx,7
cdl1:
inc cx
cmp cx,100
jz cdl2
in al,dx
and ax,0x88
cmp al,0x8
jz cdl2
mov esi,2
call delay_ms
jmp cdl1
cdl2:
 
popad
ret
 
 
sys_cdplay:
 
mov ax,5
push ax
push ebx
cdplay:
call sys_cd_atapi_command
cli
mov dx,word [cdbase]
mov ax,0x0047
out dx,ax
mov al,1
mov ah,[esp+0] ; min xx
out dx,ax
mov ax,[esp+1] ; fr sec
out dx,ax
mov ax,256+99
out dx,ax
mov ax,0x0001
out dx,ax
mov ax,0x0000
out dx,ax
mov esi,10
call delay_ms
sti
add dx,7
in al,dx
test al,1
jz cdplayok
mov ax,[esp+4]
dec ax
mov [esp+4],ax
cmp ax,0
jz cdplayfail
jmp cdplay
cdplayfail:
cdplayok:
pop ebx
pop ax
xor eax, eax
ret
 
 
sys_cdtracklist:
 
push ebx
tcdplay:
call sys_cd_atapi_command
mov dx,word [cdbase]
mov ax,0x43+2*256
out dx,ax
mov ax,0x0
out dx,ax
mov ax,0x0
out dx,ax
mov ax,0x0
out dx,ax
mov ax,200
out dx,ax
mov ax,0x0
out dx,ax
in al,dx
mov cx,1000
mov dx,word [cdbase]
add dx,7
cld
cdtrnwewait:
mov esi,10
call delay_ms
in al,dx
and al,128
cmp al,0
jz cdtrl1
loop cdtrnwewait
cdtrl1:
; read the result
mov ecx,[esp+0]
mov dx,word [cdbase]
cdtrread:
add dx,7
in al,dx
and al,8
cmp al,8
jnz cdtrdone
sub dx,7
in ax,dx
mov [ecx],ax
add ecx,2
jmp cdtrread
cdtrdone:
pop ecx
xor eax, eax
ret
 
 
sys_cdpause:
 
call sys_cd_atapi_command
 
mov dx,word [cdbase]
mov ax,0x004B
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
mov ax,0
out dx,ax
 
mov esi,10
call delay_ms
add dx,7
in al,dx
 
xor eax, eax
ret
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/blkdev
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/sound/playnote.inc
0,0 → 1,166
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; PLAYNOTE.INC version 1.1 22 November 2003 ;;
;; ;;
;; Player Notes for Speaker PC ;;
;; subfunction #55 from function #55 Menuet OS ;;
;; ;;
;; Copyright 2003 VaStaNi ;;
;; vastani@ukr.net ;;
;; >>>- SIMPLY - QUICKLY - SHORTLY -<<< ;;
;; ;;
;; Note: playnote.txt ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
align 4
sound_interface:
 
cmp eax,ebx ; this is subfunction #55 ?
jne retFunc55 ; if no then return.
 
cmp byte [sound_flag],0
jne retFunc55
 
movzx eax, byte [countDelayNote]
or al, al ; player is busy ?
jnz retFunc55 ; return counter delay Note
 
mov [memAdrNote],esi;edx
call get_pid
mov [pidProcessNote],eax
xor eax, eax ; Ok! EAX = 0
retFunc55:
mov [esp+32], eax ; return value EAX for application
ret
 
iglobal
align 4
kontrOctave dw 0x4742, 0x4342, 0x3F7C, 0x3BEC, 0x388F, 0x3562
dw 0x3264, 0x2F8F, 0x2CE4, 0x2A5F, 0x2802, 0x25BF
memAdrNote dd 0
pidProcessNote dd 0
slotProcessNote dd 0
count_timer_Note dd 1
mem8253r42 dw 0
countDelayNote db 0
endg
 
playNote:
; jmp NotPlayNotes
mov esi, [memAdrNote]
or esi, esi ; ESI = 0 ? - OFF Notes Play ?
jz NotPlayNotes ; if ESI = 0 -> ignore play pocedure
cmp eax, [count_timer_Note]
jb NotPlayNotes
push eax
inc eax
mov [count_timer_Note], eax
mov al, [countDelayNote]
dec al ; decrement counter Delay for Playing Note
jz NewLoadNote@Delay
cmp al, 0xFF ; this is first Note Play ?
jne NextDelayNote
;This is FIRST Note, save counter channel 2 chip 8253
mov al, 0xB6 ; control byte to timer chip 8253
out 0x43, al ; Send it to the control port chip 8253
in al, 0x42 ; Read Lower byte counter channel 2 chip 8253
mov ah, al ; AH = Lower byte counter channel 2
in al, 0x42 ; Read Upper byte counter channel 2 chip 8253
mov [mem8253r42], ax ; Save counter channel 2 timer chip 8253
NewLoadNote@Delay:
cld
; lodsb ; load AL - counter Delay
call ReadNoteByte
or al, al ; THE END ?
jz EndPlayNote
cmp al, 0x81
jnc NoteforOctave
mov [countDelayNote], al
; lodsw ; load AX - counter for Note!
call ReadNoteByte
mov ah,al
call ReadNoteByte
xchg al,ah
jmp pokeNote
 
EndPlayNote: ; THE END Play Notes!
in al, 0x61 ; Get contents of system port B chip 8255
and al, 0xFC ; Turn OFF timer and speaker
out 0x61, al ; Send out new values to port B chip 8255
mov ax, [mem8253r42] ; memorize counter channel 2 timer chip 8253
xchg al, ah ; reverse byte in word
out 0x42, al ; restore Lower byte counter channel 2
mov al, ah ; AL = Upper byte counter channel 2
out 0x42, al ; restore Upper byte channel 2
xor eax, eax ; EAX = 0
mov [memAdrNote], eax ; clear header control Delay-Note string
NextDelayNote:
mov [countDelayNote], al ; save new counter delay Note
pop eax
NotPlayNotes:
RET
 
NoteforOctave:
sub al, 0x81 ; correction value for delay Note
mov [countDelayNote], al ; save counter delay this new Note
; lodsb ; load pack control code
call ReadNoteByte
cmp al, 0xFF ; this is PAUSE ?
jne packCode ; no, this is PACK CODE
in al, 0x61 ; Get contents of system port B chip 8255
and al, 0xFC ; Turn OFF timer and speaker
out 0x61, al ; Send out new values to port B chip 8255
jmp saveESI
 
packCode:
mov cl, al ; save code
and al, 0xF ; clear upper bits
dec al ; correction
add al, al ; transform number to offset constant
movsx eax, al ; EAX - offset
add eax, dword kontrOctave ; EAX - address from constant
mov ax, [eax] ; read constant
shr cl, 4 ; transform for number Octave
shr ax, cl ; calculate from Note this Octave!
pokeNote:
out 0x42, al ; Lower byte Out to channel 2 timer chip 8253
mov al, ah
out 0x42, al ; Upper byte Out to channel 2 timer chip 8253
in al, 0x61 ; Get contents of system port B chip 8255
or al, 3 ; Turn ON timer and speaker
out 0x61, al ; Send out new values to port B chip 8255
saveESI:
; mov [memAdrNote], esi ; save new header control Delay-Note string
pop eax
RET
ReadNoteByte:
;result:
; al - note
push eax
push ecx
push edx
push esi
 
mov eax,[pidProcessNote]
call pid_to_slot
test eax,eax
jz .failed
lea ecx,[esp+12]
mov edx,1
mov esi,[memAdrNote]
inc [memAdrNote]
 
call read_process_memory
.failed:
pop esi
pop edx
pop ecx
pop eax
ret
;------------------- END CODE -------------------
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/sound
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/docs/sysfuncr.txt
0,0 → 1,4684
‘ˆ‘’…Œ›… ”“Š–ˆˆ Ž…€–ˆŽŽ‰ ‘ˆ‘’…Œ› Kolibri 0.7.5.0+
 
®¬¥à ä㭪樨 ¯®¬¥é ¥âáï ¢ ॣ¨áâà eax.
‚맮¢ á¨á⥬­®© ä㭪樨 ®áãé¥á⢫ï¥âáï ª®¬ ­¤®© "int 0x40".
‚ᥠॣ¨áâàë, ªà®¬¥ ® 㪠§ ­­ëå ¢ ¢®§¢à é ¥¬®¬ §­ ç¥­¨¨,
¢ª«îç ï ॣ¨áâà ä« £®¢ eflags, á®åà ­ïîâáï.
 
 
======================================================================
============== ”ã­ªæ¨ï 0 - ®¯à¥¤¥«¨âì ¨ ­ à¨á®¢ âì ®ª­®. =============
======================================================================
Ž¯à¥¤¥«ï¥â ®ª­® ¯à¨«®¦¥­¨ï. ¨áã¥â à ¬ªã ®ª­ , § £®«®¢®ª ¨ à ¡®çãî
®¡« áâì. „«ï ®ª®­ ᮠ᪨­®¬ ®¯à¥¤¥«ï¥â áâ ­¤ àâ­ë¥ ª­®¯ª¨ § ªàëâ¨ï ¨
¬¨­¨¬¨§ æ¨¨.
 à ¬¥âàë:
* eax = 0 - ­®¬¥à ä㭪樨
* ebx = [ª®®à¤¨­ â  ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x]
* ecx = [ª®®à¤¨­ â  ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y]
* edx = 0xXYRRGGBB, £¤¥:
* Y = áâ¨«ì ®ª­ :
* Y=0 - ⨯ I - ®ª­® 䨪á¨à®¢ ­­ëå à §¬¥à®¢
* Y=1 - ⮫쪮 ®¯à¥¤¥«¨âì ®¡« áâì ®ª­ , ­¨ç¥£® ­¥ à¨á®¢ âì
* Y=2 - ⨯ II - ®ª­® ¨§¬¥­ï¥¬ëå à §¬¥à®¢
* Y=3 - ®ª­® ᮠ᪨­®¬
* Y=4 - ®ª­® ᮠ᪨­®¬ 䨪á¨à®¢ ­­ëå à §¬¥à®¢
* ®áâ «ì­ë¥ ¢®§¬®¦­ë¥ §­ ç¥­¨ï (®â 5 ¤® 15) § à¥§¥à¢¨à®¢ ­ë,
¢ë§®¢ ä㭪樨 á â ª¨¬¨ Y ¨£­®à¨àã¥âáï
* RR, GG, BB = ᮮ⢥âá⢥­­® ªà á­ ï, §¥«¥­ ï, ᨭïï
á®áâ ¢«ïî騥 æ¢¥â  à ¡®ç¥© ®¡« á⨠®ª­ 
(¨£­®à¨àã¥âáï ¤«ï á⨫ï Y=2)
* X = DCBA (¡¨âë)
* A = 1 - ã ®ª­  ¥áâì § £®«®¢®ª; ¤«ï á⨫¥© Y=3,4  ¤à¥á áâப¨
§ £®«®¢ª  § ¤ ñâáï ¢ edi, ¤«ï ¯à®ç¨å á⨫¥©
¨á¯®«ì§ã¥âáï ¯®¤äã­ªæ¨ï 1 ä㭪樨 71
* B = 1 - ª®®à¤¨­ âë ¢á¥å £à ä¨ç¥áª¨å ¯à¨¬¨â¨¢®¢ § ¤ îâáï
®â­®á¨â¥«ì­® ª«¨¥­â᪮© ®¡« á⨠®ª­ 
* C = 1 - ­¥ § ªà è¨¢ âì à ¡®çãî ®¡« áâì ¯à¨ ®âà¨á®¢ª¥ ®ª­ 
* D = 0 - ­®à¬ «ì­ ï § «¨¢ª  à ¡®ç¥© ®¡« áâ¨, 1 - £à ¤¨¥­â­ ï
‘«¥¤ãî騥 ¯ à ¬¥âàë ¯à¥¤­ §­ ç¥­ë ¤«ï ®ª®­ ⨯  I ¨ II ¨
¨£­®à¨àãîâáï ¤«ï á⨫¥© Y=1,3:
* esi = 0xXYRRGGBB - 梥⠧ £®«®¢ª 
* RR, GG, BB ®¯à¥¤¥«ïîâ á ¬ 梥â
* Y=0 - ®¡ëç­®¥ ®ª­®, Y=1 - ­¥¯¥à¥¬¥é ¥¬®¥ ®ª­®
* X ®¯à¥¤¥«ï¥â £à ¤¨¥­â § £®«®¢ª : X=0 - ­¥â £à ¤¨¥­â ,
X=8 - ®¡ëç­ë© £à ¤¨¥­â,
¤«ï ®ª®­ ⨯  II X=4 - ­¥£ â¨¢­ë© £à ¤¨¥­â
* ¯à®ç¨¥ §­ ç¥­¨ï X ¨ Y § à¥§¥à¢¨à®¢ ­ë
* edi = 0x00RRGGBB - 梥â à ¬ª¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ®«®¦¥­¨¥ ¨ à §¬¥àë ®ª­  ãáâ ­ ¢«¨¢ îâáï ¯à¨ ¯¥à¢®¬ ¢ë§®¢¥
í⮩ ä㭪樨 ¨ ¨£­®à¨àãîâáï ¯à¨ ¯®á«¥¤ãîé¨å; ¤«ï ¨§¬¥­¥­¨ï
¯®«®¦¥­¨ï ¨/¨«¨ à §¬¥à®¢ 㦥 ᮧ¤ ­­®£® ®ª­  ¨á¯®«ì§ã©â¥
67-î äã­ªæ¨î.
* „«ï ®ª®­ á⨫¥© Y=3,4 á § £®«®¢ª®¬ (A=1) áâப  § £®«®¢ª 
ãáâ ­ ¢«¨¢ ¥âáï ¯à¨ ¯¥à¢®¬ ¢ë§®¢¥ í⮩ ä㭪樨 ¨ ¨£­®à¨àã¥âáï ¯à¨
¯®á«¥¤ãîé¨å (â®ç­¥¥ £®¢®àï, ¨£­®à¨àã¥âáï ¯®á«¥ ¢ë§®¢ 
¯®¤ä㭪樨 2 ä㭪樨 12 - ª®­æ  ¯¥à¥à¨á®¢ª¨);
¤«ï ¨§¬¥­¥­¨ï áâப¨ § £®«®¢ª  㦥 ᮧ¤ ­­®£® ®ª­  ¨á¯®«ì§ã©â¥
¯®¤äã­ªæ¨î 1 ä㭪樨 71.
* …᫨ ¨á¯®«ì§®¢ âì ®ª­  ᮮ⢥âáâ¢ãîé¨å á⨫¥©, â® ¯®«®¦¥­¨¥
¨/¨«¨ à §¬¥àë ®ª­  ¬®£ãâ ¬¥­ïâìáï ¯®«ì§®¢ â¥«¥¬.
’¥ªã騥 ¯®«®¦¥­¨¥ ¨ à §¬¥àë ¬®£ãâ ¡ëâì ¯®«ãç¥­ë ¢ë§®¢®¬ ä㭪樨 9.
* Žª­® ¤®«¦­® 㬥é âìáï ­  íªà ­¥. …᫨ ¯¥à¥¤ ­­ë¥ ª®®à¤¨­ âë
¨ à §¬¥àë ­¥ 㤮¢«¥â¢®àïîâ í⮬ã ãá«®¢¨î, ⮠ᮮ⢥âáâ¢ãîé ï
ª®®à¤¨­ â  (¨«¨, ¢®§¬®¦­®, ®¡¥) áç¨â ¥âáï ­ã«¥¬,   ¥á«¨ ¨ íâ®
­¥ ¯®¬®£ ¥â, ⮠ᮮ⢥âáâ¢ãî騩 à §¬¥à (¨«¨, ¢®§¬®¦­®, ®¡ )
ãáâ ­ ¢«¨¢ ¥âáï ¢ à §¬¥à íªà ­ .
„ «¥¥ ®¡®§­ ç¨¬ xpos,ypos,xsize,ysize - §­ ç¥­¨ï, ¯¥à¥¤ ¢ ¥¬ë¥
¢ ebx,ecx. Š®®à¤¨­ âë ¯à¨¢®¤ïâáï ®â­®á¨â¥«ì­® «¥¢®£® ¢¥àå­¥£®
㣫  ®ª­ , ª®â®àë©, â ª¨¬ ®¡à §®¬, § ¤ ¥âáï ª ª (0,0), ª®®à¤¨­ âë
¯à ¢®£® ­¨¦­¥£® 㣫  áãâì (xsize,ysize).
*  §¬¥àë ®ª­  ¯®­¨¬ îâáï ¢ á¬ëá«¥ ª®®à¤¨­ â ¯à ¢®£® ­¨¦­¥£® 㣫 .
â® ¦¥ ®â­®á¨âáï ¨ ª® ¢á¥¬ ®áâ «ì­ë¬ äã­ªæ¨ï¬.
â® ®§­ ç ¥â, ç⮠ॠ«ì­ë¥ à §¬¥àë ­  1 ¯¨ªá¥«ì ¡®«ìè¥.
* ‚¨¤ ®ª­  ⨯  I:
* à¨áã¥âáï ¢­¥è­ïï à ¬ª  梥â , 㪠§ ­­®£® ¢ edi,
è¨à¨­®© 1 ¯¨ªá¥«ì
* à¨áã¥âáï § £®«®¢®ª - ¯àאַ㣮«ì­¨ª á «¥¢ë¬ ¢¥àå­¨¬ 㣫®¬ (1,1)
¨ ¯à ¢ë¬ ­¨¦­¨¬ (xsize-1,min(25,ysize)) 梥â , 㪠§ ­­®£® ¢ esi
(á ãç¥â®¬ £à ¤¨¥­â )
* ¥á«¨ ysize>=26, â® § ªà è¨¢ ¥âáï à ¡®ç ï ®¡« áâì ®ª­  -
¯àאַ㣮«ì­¨ª á «¥¢ë¬ ¢¥àå­¨¬ 㣫®¬ (1,21) ¨ ¯à ¢ë¬ ­¨¦­¨¬
(xsize-1,ysize-1) (à §¬¥à ¬¨ (xsize-1)*(ysize-21)) - 梥⮬,
㪠§ ­­ë¬ ¢ edx (á ãç¥â®¬ £à ¤¨¥­â )
* ¥á«¨ A=1 ¨ áâப  § £®«®¢ª  ãáâ ­®¢«¥­  ¯®¤ä㭪樥© 1
ä㭪樨 71, â® ®­  ¢ë¢®¤¨âáï ¢ ᮮ⢥âáâ¢ãî饬 ¬¥á⥠§ £®«®¢ª 
* ‚¨¤ ®ª­  á⨫ï Y=1:
* ¯®«­®áâìî ®¯à¥¤¥«ï¥âáï ¯à¨«®¦¥­¨¥¬
* ‚¨¤ ®ª­  ⨯  II:
* à¨áã¥âáï ¢­¥è­ïï à ¬ª  è¨à¨­®© 1 ¯¨ªá¥«ì "§ â¥­ñ­­®£®" 梥â 
edi (¢á¥ á®áâ ¢«ïî騥 æ¢¥â  ã¬¥­ìè îâáï ¢ ¤¢  à § )
* à¨áã¥âáï ¯à®¬¥¦ãâ®ç­ ï à ¬ª  è¨à¨­®© 3 ¯¨ªá¥«ï æ¢¥â  edi
* à¨áã¥âáï ¢­ãâ७­ïï à ¬ª  è¨à¨­®© 1 ¯¨ªá¥«ì
"§ â¥­ñ­­®£®" æ¢¥â  edi
* à¨áã¥âáï § £®«®¢®ª - ¯àאַ㣮«ì­¨ª á «¥¢ë¬ ¢¥àå­¨¬ 㣫®¬ (4,4)
¨ ¯à ¢ë¬ ­¨¦­¨¬ (xsize-4,min(20,ysize)) 梥â , 㪠§ ­­®£® ¢ esi
(á ãç¥â®¬ £à ¤¨¥­â )
* ¥á«¨ ysize>=26, â® § ªà è¨¢ ¥âáï à ¡®ç ï ®¡« áâì ®ª­  -
¯àאַ㣮«ì­¨ª á «¥¢ë¬ ¢¥àå­¨¬ 㣫®¬ (5,20) ¨ ¯à ¢ë¬ ­¨¦­¨¬
(xsize-5,ysize-5) - 梥⮬, 㪠§ ­­ë¬ ¢ edx (á ãç¥â®¬ £à ¤¨¥­â )
* ¥á«¨ A=1 ¨ áâப  § £®«®¢ª  ãáâ ­®¢«¥­  ¯®¤ä㭪樥© 1
ä㭪樨 71, â® ®­  ¢ë¢®¤¨âáï ¢ ᮮ⢥âáâ¢ãî饬 ¬¥á⥠§ £®«®¢ª 
* ‚¨¤ ®ª­  ᮠ᪨­®¬:
* à¨áã¥âáï ¢­¥è­ïï à ¬ª  è¨à¨­®© 1 ¯¨ªá¥«ì
æ¢¥â  'outer' ¨§ ᪨­ 
* à¨áã¥âáï ¯à®¬¥¦ãâ®ç­ ï à ¬ª  è¨à¨­®© 3 ¯¨ªá¥«ï
æ¢¥â  'frame' ¨§ ᪨­ 
* à¨áã¥âáï ¢­ãâ७­ïï à ¬ª  è¨à¨­®© 1 ¯¨ªá¥«ì
æ¢¥â  'inner' ¨§ ᪨­ 
* à¨áã¥âáï § £®«®¢®ª (¯® ª à⨭ª ¬ ¨§ ᪨­ ) ¢ ¯àאַ㣮«ì­¨ª¥
(0,0) - (xsize,_skinh-1)
* ¥á«¨ ysize>=26, â® § ªà è¨¢ ¥âáï à ¡®ç ï ®¡« áâì ®ª­  -
¯àאַ㣮«ì­¨ª á «¥¢ë¬ ¢¥àå­¨¬ 㣫®¬ (5,_skinh) ¨ ¯à ¢ë¬ ­¨¦­¨¬
(xsize-5,ysize-5) - 梥⮬, 㪠§ ­­ë¬ ¢ edx (á ãç¥â®¬ £à ¤¨¥­â )
* ®¯à¥¤¥«ïîâáï ¤¢¥ áâ ­¤ àâ­ë¥ ª­®¯ª¨: § ªàëâ¨ï ¨ ¬¨­¨¬¨§ æ¨¨
(ᬮâਠäã­ªæ¨î 8)
* ¥á«¨ A=1 ¨ ¢ edi (­¥­ã«¥¢®©) 㪠§ â¥«ì ­  áâப㠧 £®«®¢ª ,
â® ®­  ¢ë¢®¤¨âáï ¢ § £®«®¢ª¥ ¢ ¬¥áâ¥, ®¯à¥¤¥«ï¥¬®¬ ᪨­®¬
* ‡­ ç¥­¨¥ ¯¥à¥¬¥­­®© _skinh ¤®áâ㯭® ª ª १ã«ìâ â ¢ë§®¢ 
¯®¤ä㭪樨 4 ä㭪樨 48
 
======================================================================
================= ”ã­ªæ¨ï 1 - ¯®áâ ¢¨âì â®çªã ¢ ®ª­¥. ================
======================================================================
 à ¬¥âàë:
* eax = 1 - ­®¬¥à ä㭪樨
* ebx = x-ª®®à¤¨­ â  (®â­®á¨â¥«ì­® ®ª­ )
* ecx = y-ª®®à¤¨­ â  (®â­®á¨â¥«ì­® ®ª­ )
* edx = 0x00RRGGBB - 梥â â®çª¨
edx = 0x01xxxxxx - ¨­¢¥àâ¨à®¢ âì 梥â â®çª¨
(¬« ¤è¨¥ 24 ¡¨â  ¨£­®à¨àãîâáï)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
======================================================================
============== ”ã­ªæ¨ï 2 - ¯®«ãç¨âì ª®¤ ­ ¦ â®© ª« ¢¨è¨. =============
======================================================================
‡ ¡¨à ¥â ª®¤ ­ ¦ â®© ª« ¢¨è¨ ¨§ ¡ãä¥à .
 à ¬¥âàë:
* eax = 2 - ­®¬¥à ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¥á«¨ ¡ãä¥à ¯ãáâ, ¢®§¢à é ¥âáï eax=1
* ¥á«¨ ¡ãä¥à ­¥¯ãáâ, â® ¢®§¢à é ¥âáï al=0, ah=ª®¤ ­ ¦ â®© ª« ¢¨è¨,
áâ à襥 á«®¢® ॣ¨áâà  eax ®¡­ã«¥­®
* ¥á«¨ ¥áâì "£®àïç ï ª« ¢¨è ", â® ¢®§¢à é ¥âáï
al=2, ah=᪠­ª®¤ ­ ¦ â®© ª« ¢¨è¨ (0 ¤«ï ã¯à ¢«ïîé¨å ª« ¢¨è),
áâ à襥 á«®¢® ॣ¨áâà  eax ᮤ¥à¦¨â á®áâ®ï­¨¥ ã¯à ¢«ïîé¨å ª« ¢¨è
¢ ¬®¬¥­â ­ ¦ â¨ï £®àï祩 ª« ¢¨è¨
‡ ¬¥ç ­¨ï:
* ‘ãé¥áâ¢ã¥â ®¡é¥á¨á⥬­ë© ¡ãä¥à ­ ¦ âëå ª« ¢¨è à §¬¥à®¬ 120 ¡ ©â,
®à£ ­¨§®¢ ­­ë© ª ª ®ç¥à¥¤ì.
* ‘ãé¥áâ¢ã¥â ¥éñ ®¤¨­ ®¡é¥á¨á⥬­ë© ¡ãä¥à ­  120 "£®àïç¨å ª« ¢¨è".
* à¨ ¢ë§®¢¥ í⮩ ä㭪樨 ¯à¨«®¦¥­¨¥¬ á ­¥ ªâ¨¢­ë¬ ®ª­®¬
áç¨â ¥âáï, çâ® ¡ãä¥à ­ ¦ âëå ª« ¢¨è ¯ãáâ.
* ® 㬮«ç ­¨î íâ  äã­ªæ¨ï ¢®§¢à é ¥â ASCII-ª®¤ë; ¯¥à¥ª«îç¨âìáï ­ 
०¨¬ ᪠­ª®¤®¢ (¨ ­ § ¤) ¬®¦­® á ¨á¯®«ì§®¢ ­¨¥¬ ä㭪樨 66.
Ž¤­ ª®, £®àï稥 ª« ¢¨è¨ ¢á¥£¤  ¢®§¢à é îâáï ª ª ᪠­ª®¤ë.
* “§­ âì, ª ª¨¥ ª®¬¡¨­ æ¨¨ ª« ¢¨è ᮮ⢥âáâ¢ãîâ ª ª¨¬ ª®¤ ¬, ¬®¦­®,
§ ¯ãá⨢ ¯à¨«®¦¥­¨ï keyascii ¨ scancode.
* ‘ª ­ª®¤ë ¢®§¢à é îâáï ­¥¯®á।á⢥­­® ª« ¢¨ âãன ¨ 䨪á¨à®¢ ­ë;
ASCII-ª®¤ë ¯®«ãç îâáï á ¨á¯®«ì§®¢ ­¨¥¬ â ¡«¨æ ¯à¥®¡à §®¢ ­¨ï,
ª®â®àë¥ ¬®¦­® ãáâ ­®¢¨âì ¯®¤ä㭪樥© 2 ä㭪樨 21 ¨ ¯à®ç¨â âì
¯®¤ä㭪樥© 2 ä㭪樨 26.
* Š ª á«¥¤á⢨¥, ASCII-ª®¤ë ãç¨â뢠îâ ⥪ãéãî à áª« ¤ªã ª« ¢¨ âãàë
(rus/en) ¢ ®â«¨ç¨¥ ®â ᪠­ª®¤®¢.
* ®áâ㯠¥â ¨­ä®à¬ æ¨ï ⮫쪮 ® â¥å £®àïç¨å ª« ¢¨è å, ª®â®àë¥ ¡ë«¨
®¯à¥¤¥«¥­ë í⨬ ¯®â®ª®¬ ¯®¤ä㭪樥© 4 ä㭪樨 66.
 
======================================================================
================ ”ã­ªæ¨ï 3 - ¯®«ãç¨âì á¨á⥬­®¥ ¢à¥¬ï. ===============
======================================================================
 à ¬¥âàë:
* eax = 3 - ­®¬¥à ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0x00SSMMHH, £¤¥ HH:MM:SS = ç áë:¬¨­ãâë:ᥪ㭤ë
* ª ¦¤ë© í«¥¬¥­â ¢®§¢à é ¥âáï ª ª BCD-ç¨á«®, ­ ¯à¨¬¥à,
¤«ï ¢à¥¬¥­¨ 23:59:59 १ã«ìâ â ¡ã¤¥â 0x00595923
‡ ¬¥ç ­¨ï:
* ‘¬®âਠ⠪¦¥ ¯®¤äã­ªæ¨î 9 ä㭪樨 26 - ¯®«ã祭¨¥ ¢à¥¬¥­¨
á ¬®¬¥­â  § ¯ã᪠ á¨á⥬ë; ®­  ¢® ¬­®£¨å á«ãç ïå 㤮¡­¥¥,
¯®áª®«ìªã ¢®§¢à é ¥â ¯à®áâ® DWORD-§­ ç¥­¨¥ áç¥â稪  ¢à¥¬¥­¨.
* ‘¨á⥬­®¥ ¢à¥¬ï ¬®¦­® ãáâ ­®¢¨âì ä㭪樥© 22.
 
======================================================================
============== ”ã­ªæ¨ï 4 - ¢ë¢¥á⨠áâபã ⥪áâ  ¢ ®ª­®. =============
======================================================================
 à ¬¥âàë:
* eax = 4 - ­®¬¥à ä㭪樨
* ebx = [ª®®à¤¨­ â  ¯® ®á¨ x]*65536 + [ª®®à¤¨­ â  ¯® ®á¨ y]
* ecx = 0xX0RRGGBB, £¤¥
* RR, GG, BB § ¤ îâ 梥â ⥪áâ 
* X=ABnn (¡¨âë):
* nn § ¤ ¥â ¨á¯®«ì§ã¥¬ë© èà¨äâ: 0=á¨á⥬­ë© ¬®­®è¨à¨­­ë©,
1=á¨á⥬­ë© èà¨äâ ¯¥à¥¬¥­­®© è¨à¨­ë
* A=0 - ¢ë¢®¤¨âì esi ᨬ¢®«®¢, A=1 - ¢ë¢®¤¨âì ASCIIZ-áâபã
* B=1 - § ªà è¨¢ âì ä®­ 梥⮬ edi
* edx = 㪠§ â¥«ì ­  ­ ç «® áâப¨
* esi = ¤«ï A=0 ¤«¨­  áâப¨, ¤®«¦­  ¡ëâì ­¥ ¡®«ìè¥ 255;
¤«ï A=1 ¨£­®à¨àã¥âáï
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ¥à¢ë© á¨á⥬­ë© èà¨äâ áç¨â뢠¥âáï ¯à¨ § £à㧪¥ ¨§ ä ©«  char.mt,
¢â®à®© - ¨§ char2.mt.
* Ž¡  èà¨äâ  ¨¬¥îâ ¢ëá®âã 9 ¯¨ªá¥«¥©, è¨à¨­  ¬®­®è¨à¨­­®£® èà¨äâ 
à ¢­  6 ¯¨ªá¥«¥©.
 
======================================================================
========================= ”ã­ªæ¨ï 5 - ¯ ã§ . =========================
======================================================================
‡ ¤¥à¦¨¢ ¥â ¢ë¯®«­¥­¨¥ ¯à®£à ¬¬ë ­  § ¤ ­­®¥ ¢à¥¬ï.
 à ¬¥âàë:
* eax = 5 - ­®¬¥à ä㭪樨
* ebx = ¢à¥¬ï ¢ á®âëå ¤®«ïå ᥪ㭤ë
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ¥à¥¤ ç  ebx=0 ­¥ ¯¥à¥¤ ¥â ã¯à ¢«¥­¨¥ á«¥¤ãî饬㠯à®æ¥ááã ¨
¢®®¡é¥ ­¥ ¯à®¨§¢®¤¨â ­¨ª ª¨å ¤¥©á⢨©. …᫨ ¤¥©á⢨⥫쭮
âॡã¥âáï ¯¥à¥¤ âì ã¯à ¢«¥­¨¥ á«¥¤ãî饬㠯à®æ¥ááã
(§ ª®­ç¨âì ⥪ã騩 ª¢ ­â ¢à¥¬¥­¨), ¨á¯®«ì§ã©â¥ ¯®¤äã­ªæ¨î 1
ä㭪樨 68.
 
======================================================================
=============== ”ã­ªæ¨ï 6 - ¯à®ç¨â âì ä ©« á à ¬¤¨áª . ===============
======================================================================
 à ¬¥âàë:
* eax = 6 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨¬ï ä ©« 
* ecx = ­®¬¥à áâ à⮢®£® ¡«®ª , áç¨â ï á 1;
ecx=0 - ç¨â âì á ­ ç «  ä ©«  (â® ¦¥ á ¬®¥, çâ® ¨ ecx=1)
* edx = ç¨á«® ¡«®ª®¢ ¤«ï ç⥭¨ï;
edx=0 - ç¨â âì ®¤¨­ ¡«®ª (â® ¦¥ á ¬®¥, çâ® ¨ edx=1)
* esi = 㪠§ â¥«ì ­  ®¡« áâì ¯ ¬ïâ¨, ªã¤  ¡ã¤ãâ § ¯¨á ­ë ¤ ­­ë¥
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ¤«¨­  ä ©«  ¢ ¡ ©â å, ¥á«¨ ä ©« ãᯥ譮 ¯à®ç¨â ­
* eax = -1, ¥á«¨ ä ©« ­¥ ­ ©¤¥­
‡ ¬¥ç ­¨ï:
* „ ­­ ï äã­ªæ¨ï ï¥âáï ãáâ à¥¢è¥©; äã­ªæ¨ï 70
¯®§¢®«ï¥â ¢ë¯®«­ïâì ⥠¦¥ ¤¥©á⢨ï á à áè¨à¥­­ë¬¨ ¢®§¬®¦­®áâﬨ.
* «®ª = 512 ¡ ©â.
* „«ï ç⥭¨ï ¢á¥£® ä ©«  ¬®¦­® 㪠§ âì § ¢¥¤®¬® ¡®«ì讥 §­ ç¥­¨¥
¢ edx, ­ ¯à¨¬¥à, edx = -1; ­® ¢ í⮬ á«ãç ¥ ¡ã¤ì⥠£®â®¢ë ª ⮬ã,
çâ® ¯à®£à ¬¬  "㯠¤¥â", ¥á«¨ ä ©« ®ª ¦¥âáï ᫨誮¬ ¡®«ì訬
¨ "­¥ ¢«¥§¥â" ¢ ¯ ¬ïâì ¯à®£à ¬¬ë.
* ˆ¬ï ä ©«  ¤®«¦­® ¡ëâì «¨¡® ¢ ä®à¬ â¥ 8+3 ᨬ¢®«®¢
(¯¥à¢ë¥ 8 ᨬ¢®«®¢ - ᮡá⢥­­® ¨¬ï, ¯®á«¥¤­¨¥ 3 - à áè¨à¥­¨¥,
ª®à®âª¨¥ ¨¬¥­  ¨ à áè¨à¥­¨ï ¤®¯®«­ïîâáï ¯à®¡¥« ¬¨),
«¨¡® ¢ ä®à¬ â¥ 8.3 ᨬ¢®«®¢ "FILE.EXT"/"FILE.EX "
(¨¬ï ­¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥­¨¥ 3 ᨬ¢®« ,
¤®¯®«­¥­­®¥ ¯à¨ ­¥®¡å®¤¨¬®á⨠¯à®¡¥« ¬¨).
ˆ¬ï ä ©«  ¤®«¦­® ¡ëâì § ¯¨á ­® § £« ¢­ë¬¨ ¡ãª¢ ¬¨.
‡ ¢¥àè î騩 ᨬ¢®« á ª®¤®¬ 0 ­¥ ­ã¦¥­ (­¥ ASCIIZ-áâப ).
* â  äã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯ª¨ ­  à ¬¤¨áª¥.
 
======================================================================
=============== ”ã­ªæ¨ï 7 - ¢ë¢¥á⨠¨§®¡à ¦¥­¨¥ ¢ ®ª­®. ==============
======================================================================
 à ¬¥âàë:
* eax = 7 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨§®¡à ¦¥­¨¥ ¢ ä®à¬ â¥ BBGGRRBBGGRR...
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y]
* edx = [ª®®à¤¨­ â  ¯® ®á¨ x]*65536 + [ª®®à¤¨­ â  ¯® ®á¨ y]
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* Š®®à¤¨­ âë ¨§®¡à ¦¥­¨ï - íâ® ª®®à¤¨­ âë ¢¥àå­¥£® «¥¢®£® 㣫 
¨§®¡à ¦¥­¨ï ®â­®á¨â¥«ì­® ®ª­ .
*  §¬¥à ¨§®¡à ¦¥­¨ï ¢ ¡ ©â å ¥áâì 3*xsize*ysize.
 
======================================================================
=============== ”ã­ªæ¨ï 8 - ®¯à¥¤¥«¨âì/㤠«¨âì ª­®¯ªã. ===============
======================================================================
 à ¬¥âàë ¤«ï ®¯à¥¤¥«¥­¨ï ª­®¯ª¨:
* eax = 8 - ­®¬¥à ä㭪樨
* ebx = [ª®®à¤¨­ â  ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x]
* ecx = [ª®®à¤¨­ â  ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y]
* edx = 0xXYnnnnnn, £¤¥:
* nnnnnn = ¨¤¥­â¨ä¨ª â®à ª­®¯ª¨
* áâ à訩 (31-©) ¡¨â edx á¡à®è¥­
* ¥á«¨ 30-© ¡¨â edx ãáâ ­®¢«¥­ - ­¥ ¯à®à¨á®¢ë¢ âì ª­®¯ªã
* ¥á«¨ 29-© ¡¨â edx ãáâ ­®¢«¥­ - ­¥ à¨á®¢ âì à ¬ªã
¯à¨ ­ ¦ â¨¨ ­  ª­®¯ªã
* esi = 0x00RRGGBB - 梥⠪­®¯ª¨
 à ¬¥âàë ¤«ï 㤠«¥­¨ï ª­®¯ª¨:
* eax = 8 - ­®¬¥à ä㭪樨
* edx = 0x80nnnnnn, £¤¥ nnnnnn - ¨¤¥­â¨ä¨ª â®à ª­®¯ª¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
*  §¬¥àë ª­®¯ª¨ ¤®«¦­ë ¡ëâì ¡®«ìè¥ 0 ¨ ¬¥­ìè¥ 0x8000.
* „«ï ®ª®­ ᮠ᪨­®¬ ¯à¨ ®¯à¥¤¥«¥­¨¨ ®ª­  (¢ë§®¢¥ 0-© ä㭪樨)
ᮧ¤ îâáï ¤¢¥ áâ ­¤ àâ­ë¥ ª­®¯ª¨ - § ªàëâ¨ï ®ª­ 
á ¨¤¥­â¨ä¨ª â®à®¬ 1 ¨ ¬¨­¨¬¨§ æ¨¨ ®ª­  á ¨¤¥­â¨ä¨ª â®à®¬ 0xffff.
* ‘®§¤ ­¨¥ ¤¢ãå ª­®¯®ª á ®¤¨­ ª®¢ë¬¨ ¨¤¥­â¨ä¨ª â®à ¬¨
¢¯®«­¥ ¤®¯ãá⨬®.
* Š­®¯ª  á ¨¤¥­â¨ä¨ª â®à®¬ 0xffff ¯à¨ ­ ¦ â¨¨ ¨­â¥à¯à¥â¨àã¥âáï
á¨á⥬®© ª ª ª­®¯ª  ¬¨­¨¬¨§ æ¨¨, á¨á⥬  ®¡à ¡ â뢠¥â â ª®¥
­ ¦ â¨¥ á ¬®áâ®ï⥫쭮, ­¥ ®¡à é ïáì ª ¯à¨«®¦¥­¨î.
‚ ®áâ «ì­®¬ íâ® ®¡ëç­ ï ª­®¯ª .
* Ž¡é¥¥ ª®«¨ç¥á⢮ ª­®¯®ª ¤«ï ¢á¥å ¯à¨«®¦¥­¨© ®£à ­¨ç¥­®
ç¨á«®¬ 4095.
 
======================================================================
============= ”ã­ªæ¨ï 9 - ¨­ä®à¬ æ¨ï ® ¯®â®ª¥ ¢ë¯®«­¥­¨ï. ============
======================================================================
 à ¬¥âàë:
* eax = 9 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¡ãä¥à à §¬¥à  1 Š¡
* ecx = ­®¬¥à á«®â  ¯®â®ª 
ecx = -1 - ¯®«ãç¨âì ¨­ä®à¬ æ¨î ® ⥪ã饬 ¯®â®ª¥
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ¬ ªá¨¬ «ì­ë© ­®¬¥à á«®â  ¯®â®ª 
* ¡ãä¥à, ­  ª®â®àë© ãª §ë¢ ¥â ebx, ᮤ¥à¦¨â á«¥¤ãîéãî ¨­ä®à¬ æ¨î:
* +0: dword: ¨á¯®«ì§®¢ ­¨¥ ¯à®æ¥áá®à  (᪮«ìª® ⠪⮢ ¢ ᥪ㭤ã
ã室¨â ­  ¨á¯®«­¥­¨¥ ¨¬¥­­® í⮣® ¯®â®ª )
* +4: word: ¯®§¨æ¨ï ®ª­  ¯®â®ª  ¢ ®ª®­­®¬ áâíª¥
* +6: word: (­¥ ¨¬¥¥â ®â­®è¥­¨ï ª § ¯à®è¥­­®¬ã ¯®â®ªã)
­®¬¥à á«®â  ¯®â®ª , ®ª­® ª®â®à®£® ­ å®¤¨âáï ¢ ®ª®­­®¬ áâíª¥
¢ ¯®§¨æ¨¨ ecx
* +8: word: § à¥§¥à¢¨à®¢ ­®
* +10 = +0xA: 11 ¡ ©â: ¨¬ï ¯à®æ¥áá 
(¨¬ï ᮮ⢥âáâ¢ãî饣® ¨á¯®«­ï¥¬®£® ä ©«  ¢ ä®à¬ â¥ 8+3)
* +21 = +0x15: byte: § à¥§¥à¢¨à®¢ ­®, íâ®â ¡ ©â ­¥ ¨§¬¥­ï¥âáï
* +22 = +0x16: dword:  ¤à¥á ¯à®æ¥áá  ¢ ¯ ¬ïâ¨
* +26 = +0x1A: dword: à §¬¥à ¨á¯®«ì§ã¥¬®© ¯ ¬ï⨠- 1
* +30 = +0x1E: dword: ¨¤¥­â¨ä¨ª â®à (PID/TID)
* +34 = +0x22: dword: ª®®à¤¨­ â  ®ª­  ¯®â®ª  ¯® ®á¨ x
* +38 = +0x26: dword: ª®®à¤¨­ â  ®ª­  ¯®â®ª  ¯® ®á¨ y
* +42 = +0x2A: dword: à §¬¥à ®ª­  ¯®â®ª  ¯® ®á¨ x
* +46 = +0x2E: dword: à §¬¥à ®ª­  ¯®â®ª  ¯® ®á¨ y
* +50 = +0x32: word: á®áâ®ï­¨¥ á«®â  ¯®â®ª :
* 0 = ¯®â®ª ¢ë¯®«­ï¥âáï
* 1 = ¯®â®ª ¯à¨®áâ ­®¢«¥­
* 2 = ¯®â®ª ¯à¨®áâ ­®¢«¥­ ¢ ¬®¬¥­â ®¦¨¤ ­¨ï ᮡëâ¨ï
* 3 = ¯®â®ª § ¢¥àè ¥âáï ¢ १ã«ìâ â¥ ¢ë§®¢  ä㭪樨 -1 ¨«¨
­ á¨«ìá⢥­­® ª ª á«¥¤á⢨¥ ¢ë§®¢  ¯®¤ä㭪樨 2 ä㭪樨 18
¨«¨ § ¢¥à襭¨ï à ¡®âë á¨á⥬ë
* 4 = ¯®â®ª § ¢¥àè ¥âáï ¢ १ã«ìâ â¥ ¨áª«î祭¨ï
* 5 = ¯®â®ª ®¦¨¤ ¥â ᮡëâ¨ï
* 9 = § ¯à®è¥­­ë© á«®â ᢮¡®¤¥­, ¢áï ®áâ «ì­ ï ¨­ä®à¬ æ¨ï ®
᫮⥠­¥ ¨¬¥¥â á¬ëá« 
* +52 = +0x34: word: § à¥§¥à¢¨à®¢ ­®, íâ® á«®¢® ­¥ ¨§¬¥­ï¥âáï
* +54 = +0x36: dword: ª®®à¤¨­ â  ­ ç «  ª«¨¥­â᪮© ®¡« áâ¨
¯® ®á¨ x
* +58 = +0x3A: dword: ª®®à¤¨­ â  ­ ç «  ª«¨¥­â᪮© ®¡« áâ¨
¯® ®á¨ y
* +62 = +0x3E: dword: è¨à¨­  ª«¨¥­â᪮© ®¡« áâ¨
* +66 = +0x42: dword: ¢ëá®â  ª«¨¥­â᪮© ®¡« áâ¨
* +70 = +0x46: byte: á®áâ®ï­¨¥ ®ª­  - ¡¨â®¢®¥ ¯®«¥
* ¡¨â 0 (¬ áª  1): ®ª­® ¬ ªá¨¬¨§¨à®¢ ­®
* ¡¨â 1 (¬ áª  2): ®ª­® ¬¨­¨¬¨§¨à®¢ ­® ¢ ¯ ­¥«ì § ¤ ç
* ¡¨â 2 (¬ áª  4): ®ª­® á¢ñà­ãâ® ¢ § £®«®¢®ª
‡ ¬¥ç ­¨ï:
* ‘«®âë ­ã¬¥àãîâáï á 1.
* ‚®§¢à é ¥¬®¥ §­ ç¥­¨¥ ­¥ ¥áâì ®¡é¥¥ ç¨á«® ¯®â®ª®¢, ¯®áª®«ìªã
¡ë¢ îâ ᢮¡®¤­ë¥ á«®âë.
* à¨ ᮧ¤ ­¨¨ ¯à®æ¥áá   ¢â®¬ â¨ç¥áª¨ ᮧ¤ ¥âáï ¯®â®ª ¢ë¯®«­¥­¨ï.
* ”ã­ªæ¨ï ¢ë¤ ¥â ¨­ä®à¬ æ¨î ® ¯®â®ª¥. Š ¦¤ë© ¯à®æ¥áá ¨¬¥¥â
å®âï ¡ë ®¤¨­ ¯®â®ª. Ž¤¨­ ¯à®æ¥áá ¬®¦¥â ᮧ¤ âì ­¥áª®«ìª® ¯®â®ª®¢,
¢ í⮬ á«ãç ¥ ª ¦¤ë© ¯®â®ª ¯®«ãç ¥â ᢮© á«®â, ¯à¨ç¥¬ ¯®«ï
+10, +22, +26 ¢ íâ¨å á«®â å ᮢ¯ ¤ îâ.
„«ï ¯à¨«®¦¥­¨© ­¥ áãé¥áâ¢ã¥â ®¡é¥£® ᯮᮡ  ®¯à¥¤¥«¨âì,
¯à¨­ ¤«¥¦ â «¨ ¤¢  ¯®â®ª  ®¤­®¬ã ¯à®æ¥ááã.
* €ªâ¨¢­®¥ ®ª­® - ®ª­®, ­ å®¤ï饥áï ­  ¢¥à設¥ ®ª®­­®£® áâíª ,
®­® ¯®«ãç ¥â á®®¡é¥­¨ï ® ¢¢®¤¥ á ª« ¢¨ âãàë. „«ï ­¥£® ¯®§¨æ¨ï ¢
®ª®­­®¬ áâíª¥ ᮢ¯ ¤ ¥â á ¢®§¢à é ¥¬ë¬ §­ ç¥­¨¥¬.
* ‘«®â 1 ᮮ⢥âáâ¢ã¥â ᯥ樠«ì­®¬ã ¯®â®ªã ®¯¥à æ¨®­­®© á¨á⥬ë,
¤«ï ª®â®à®£®:
* ®ª­® ­ å®¤¨âáï ¢­¨§ã ®ª®­­®£® áâíª , ¯®«ï +4 ¨ +6 ᮤ¥à¦ â
§­ ç¥­¨¥ 1
* ¨¬ï ¯à®æ¥áá  - "OS/IDLE" (¤®¯®«­¥­­®¥ ¯à®¡¥« ¬¨)
*  ¤à¥á ¯à®æ¥áá  ¢ ¯ ¬ï⨠ࠢ¥­ 0, à §¬¥à ¨á¯®«ì§ã¥¬®© ¯ ¬ïâ¨
16 Mb (0x1000000)
* PID=1
* ª®®à¤¨­ âë ¨ à §¬¥àë ®ª­ , à ¢­® ª ª ¨ ª«¨¥­â᪮© ®¡« áâ¨,
ãá«®¢­® ¯®« £ îâáï à ¢­ë¬¨ 0
* á®áâ®ï­¨¥ á«®â  - ¢á¥£¤  0 (¢ë¯®«­ï¥âáï)
* ¢à¥¬ï ¢ë¯®«­¥­¨ï ᪫ ¤ë¢ ¥âáï ¨§ ¢à¥¬¥­¨, ã室ï饣® ­ 
ᮡá⢥­­® à ¡®âã, ¨ ¢à¥¬¥­¨ ¯à®áâ®ï ¢ ®¦¨¤ ­¨¨ ¯à¥à뢠­¨ï
(ª®â®à®¥ ¬®¦­® ¯®«ãç¨âì ¢ë§®¢®¬ ¯®¤ä㭪樨 4 ä㭪樨 18).
*  ç¨­ ï á® á«®â  2, à §¬¥é îâáï ®¡ëç­ë¥ ¯à¨«®¦¥­¨ï.
* Ž¡ëç­ë¥ ¯à¨«®¦¥­¨ï à §¬¥é îâáï ¢ ¯ ¬ï⨠¯®  ¤à¥áã 0x0
(ª®­áâ ­â  ï¤à  std_application_base_address).
 «®¦¥­¨ï ­¥ ¯à®¨á室¨â, ¯®áª®«ìªã ã ª ¦¤®£® ¯à®æ¥áá  á¢®ï
â ¡«¨æ  áâà ­¨æ.
* à¨ ᮧ¤ ­¨¨ ¯®â®ª  ¥¬ã ­ §­ ç îâáï ᫮⠢ á¨á⥬­®© â ¡«¨æ¥ ¨
¨¤¥­â¨ä¨ª â®à (Process/Thread IDentifier = PID/TID), ª®â®àë¥ ¤«ï
§ ¤ ­­®£® ¯®â®ª  ­¥ ¨§¬¥­ïîâáï á® ¢à¥¬¥­¥¬.
®á«¥ § ¢¥à襭¨ï ¯®â®ª  ¥£® ᫮⠬®¦¥â ¡ëâì § ­®¢® ¨á¯®«ì§®¢ ­
¤«ï ¤à㣮£® ¯®â®ª . ˆ¤¥­â¨ä¨ª â®à ¯®â®ª  ­¥ ¬®¦¥â ¡ëâì ­ §­ ç¥­
¤à㣮¬ã ¯®â®ªã ¤ ¦¥ ¯®á«¥ § ¢¥à襭¨ï ¯¥à¢®£®.
 §­ ç ¥¬ë¥ ­®¢ë¬ ¯®â®ª ¬ ¨¤¥­â¨ä¨ª â®àë ¬®­®â®­­® à áâãâ.
* …᫨ ¯®â®ª ¥é¥ ­¥ ®¯à¥¤¥«¨« ᢮¥ ®ª­® ¢ë§®¢®¬ ä㭪樨 0, â®
¯®«®¦¥­¨¥ ¨ à §¬¥àë í⮣® ®ª­  ¯®« £ îâáï ­ã«ï¬¨.
* Š®®à¤¨­ âë ª«¨¥­â᪮© ®¡« á⨠®ª­  ¡¥àãâáï ®â­®á¨â¥«ì­® ®ª­ .
* ‚ ¤ ­­ë© ¬®¬¥­â ¨á¯®«ì§ã¥âáï ⮫쪮 ç áâì ¡ãä¥à  à §¬¥à®¬
71 = 0x47 ¡ ©â . ’¥¬ ­¥ ¬¥­¥¥ ४®¬¥­¤ã¥âáï ¨á¯®«ì§®¢ âì ¡ãä¥à
à §¬¥à®¬ 1 Š¡ ¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨, ¢ ¡ã¤ã饬 ¬®£ãâ ¡ëâì
¤®¡ ¢«¥­ë ­¥ª®â®àë¥ ¯®«ï.
 
======================================================================
==================== ”ã­ªæ¨ï 10 - ®¦¨¤ âì ᮡëâ¨ï. ===================
======================================================================
…᫨ ®ç¥à¥¤ì á®®¡é¥­¨© ¯ãáâ , â® ¦¤¥â ¯®ï¢«¥­¨ï á®®¡é¥­¨ï ¢ ®ç¥à¥¤¨.
‚ â ª®¬ á®áâ®ï­¨¨ ¯®â®ª ­¥ ¯®«ã砥⠯à®æ¥áá®à­®£® ¢à¥¬¥­¨.
‡ â¥¬ áç¨â뢠¥â á®®¡é¥­¨¥ ¨§ ®ç¥à¥¤¨.
 
 à ¬¥âàë:
* eax = 10 - ­®¬¥à ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ᮡë⨥ (ᬮâਠᯨ᮪ ᮡë⨩)
‡ ¬¥ç ­¨ï:
* “ç¨â뢠îâáï ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã,
ãáâ ­ ¢«¨¢ ¥¬ãî ä㭪樥© 40. ® 㬮«ç ­¨î í⮠ᮡëâ¨ï
¯¥à¥à¨á®¢ª¨, ­ ¦ â¨ï ­  ª« ¢¨è¨ ¨ ­  ª­®¯ª¨.
* „«ï ¯à®¢¥àª¨, ¥áâì «¨ á®®¡é¥­¨¥ ¢ ®ç¥à¥¤¨, ¨á¯®«ì§ã©â¥ äã­ªæ¨î 11.
—â®¡ë ¦¤ âì ­¥ ¡®«¥¥ ®¯à¥¤¥«¥­­®£® ¢à¥¬¥­¨, ¨á¯®«ì§ã©â¥
äã­ªæ¨î 23.
 
======================================================================
======= ”ã­ªæ¨ï 11 - ¯à®¢¥à¨âì, ¥áâì «¨ ᮡë⨥, ¡¥§ ®¦¨¤ ­¨ï. =======
======================================================================
…᫨ ¢ ®ç¥à¥¤¨ á®®¡é¥­¨© ¥áâì ª ª®¥-⮠ᮡë⨥, â® áç¨â뢠¥â ¨
¢®§¢à é ¥â ¥£®. …᫨ ®ç¥à¥¤ì ¯ãáâ , ¢®§¢à é ¥â ­ã«ì.
 à ¬¥âàë:
* eax = 11 - ­®¬¥à ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ®ç¥à¥¤ì á®®¡é¥­¨© ¯ãáâ 
* ¨­ ç¥ eax = ᮡë⨥ (ᬮâਠᯨ᮪ ᮡë⨩)
‡ ¬¥ç ­¨ï:
* “ç¨â뢠îâáï ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã,
ãáâ ­ ¢«¨¢ ¥¬ãî ä㭪樥© 40. ® 㬮«ç ­¨î í⮠ᮡëâ¨ï
¯¥à¥à¨á®¢ª¨, ­ ¦ â¨ï ­  ª« ¢¨è¨ ¨ ­  ª­®¯ª¨.
* „«ï ®¦¨¤ ­¨ï ¯®ï¢«¥­¨ï ᮡëâ¨ï ¢ ®ç¥à¥¤¨, ¨á¯®«ì§ã©â¥ äã­ªæ¨î 10.
—â®¡ë ¦¤ âì ­¥ ¡®«¥¥ ®¯à¥¤¥«¥­­®£® ¢à¥¬¥­¨, ¨á¯®«ì§ã©â¥
äã­ªæ¨î 23.
 
======================================================================
=========== ”ã­ªæ¨ï 12 - ­ ç âì/§ ª®­ç¨âì ¯¥à¥à¨á®¢ªã ®ª­ . ==========
======================================================================
 
-------------- ®¤äã­ªæ¨ï 1 - ­ ç âì ¯¥à¥à¨á®¢ªã ®ª­ . ---------------
 à ¬¥âàë:
* eax = 12 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
------------- ®¤äã­ªæ¨ï 2 - § ª®­ç¨âì ¯¥à¥à¨á®¢ªã ®ª­ . -------------
 à ¬¥âàë:
* eax = 12 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ”ã­ªæ¨ï ­ ç «  ¯¥à¥à¨á®¢ª¨ 㤠«ï¥â ¢á¥ ®¯à¥¤¥«ñ­­ë¥
ä㭪樥© 8 ª­®¯ª¨, ¨å á«¥¤ã¥â ®¯à¥¤¥«¨âì ¯®¢â®à­®.
 
======================================================================
============ ”ã­ªæ¨ï 13 - ­ à¨á®¢ âì ¯àאַ㣮«ì­¨ª ¢ ®ª­¥. ===========
======================================================================
 à ¬¥âàë:
* eax = 13 - ­®¬¥à ä㭪樨
* ebx = [ª®®à¤¨­ â  ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x]
* ecx = [ª®®à¤¨­ â  ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y]
* edx = 梥â 0xRRGGBB ¨«¨ 0x80RRGGBB ¤«ï £à ¤¨¥­â­®© § «¨¢ª¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ®¤ ª®®à¤¨­ â ¬¨ ¯®­¨¬ îâáï ª®®à¤¨­ âë «¥¢®£® ¢¥àå­¥£® 㣫 
¯àאַ㣮«ì­¨ª  ®â­®á¨â¥«ì­® ®ª­ .
 
======================================================================
================ ”ã­ªæ¨ï 14 - ¯®«ãç¨âì à §¬¥àë íªà ­ . ===============
======================================================================
 à ¬¥âàë:
* eax = 14 - ­®¬¥à ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = [xsize]*65536 + [ysize], £¤¥
* xsize = x-ª®®à¤¨­ â  ¯à ¢®£® ­¨¦­¥£® 㣫  íªà ­  =
à §¬¥à ¯® £®à¨§®­â «¨ - 1
* ysize = y-ª®®à¤¨­ â  ¯à ¢®£® ­¨¦­¥£® 㣫  íªà ­  =
à §¬¥à ¯® ¢¥à⨪ «¨ - 1
‡ ¬¥ç ­¨ï:
* ‘¬®âਠ⠪¦¥ ¯®¤äã­ªæ¨î 5 ä㭪樨 48 - ¯®«ãç¨âì à §¬¥àë à ¡®ç¥©
®¡« á⨠íªà ­ .
 
======================================================================
= ”ã­ªæ¨ï 15, ¯®¤äã­ªæ¨ï 1 - ãáâ ­®¢¨âì à §¬¥à ä®­®¢®£® ¨§®¡à ¦¥­¨ï. =
======================================================================
 à ¬¥âàë:
* eax = 15 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx = è¨à¨­  ¨§®¡à ¦¥­¨ï
* edx = ¢ëá®â  ¨§®¡à ¦¥­¨ï
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ‚맮¢ ä㭪樨 ®¡ï§ â¥«¥­ ¯¥à¥¤ ¢ë§®¢®¬ ¯®¤ä㭪権 2 ¨ 5.
* „«ï ®¡­®¢«¥­¨ï íªà ­  (¯®á«¥ § ¢¥à襭¨ï á¥à¨¨ ª®¬ ­¤, à ¡®â îé¨å á
ä®­®¬) ¢ë§ë¢ ©â¥ ¯®¤äã­ªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä®­ .
* …áâì ¯ à­ ï äã­ªæ¨ï ¯®«ã祭¨ï à §¬¥à®¢ ä®­®¢®£® ¨§®¡à ¦¥­¨ï -
¯®¤äã­ªæ¨ï 1 ä㭪樨 39.
 
======================================================================
= ”ã­ªæ¨ï 15, ¯®¤äã­ªæ¨ï 2 - ¯®áâ ¢¨âì â®çªã ­  ä®­®¢®¬ ¨§®¡à ¦¥­¨¨. =
======================================================================
 à ¬¥âàë:
* eax = 15 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ᬥ饭¨¥
* edx = 梥â â®çª¨ 0xRRGGBB
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ‘¬¥é¥­¨¥ ¤«ï â®çª¨ á ª®®à¤¨­ â ¬¨ (x,y) ¢ëç¨á«ï¥âáï ª ª
(x+y*xsize)*3.
* …᫨ 㪠§ ­­®¥ ᬥ饭¨¥ ¯à¥¢ëè ¥â ãáâ ­®¢«¥­­ë© ¯®¤ä㭪樥© 1
à §¬¥à, ¢ë§®¢ ¨£­®à¨àã¥âáï.
* „«ï ®¡­®¢«¥­¨ï íªà ­  (¯®á«¥ § ¢¥à襭¨ï á¥à¨¨ ª®¬ ­¤, à ¡®â îé¨å á
ä®­®¬) ¢ë§ë¢ ©â¥ ¯®¤äã­ªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä®­ .
* …áâì ¯ à­ ï äã­ªæ¨ï ¯®«ã祭¨ï â®çª¨ á ä®­®¢®£® ¨§®¡à ¦¥­¨ï -
¯®¤äã­ªæ¨ï 2 ä㭪樨 39.
 
======================================================================
============ ”ã­ªæ¨ï 15, ¯®¤äã­ªæ¨ï 3 - ¯¥à¥à¨á®¢ âì ä®­. ============
======================================================================
 à ¬¥âàë:
* eax = 15 - ­®¬¥à ä㭪樨
* ebx = 3 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
======================================================================
===== ”ã­ªæ¨ï 15, ¯®¤äã­ªæ¨ï 4 - ãáâ ­®¢¨âì ०¨¬ ®âà¨á®¢ª¨ ä®­ . ====
======================================================================
 à ¬¥âàë:
* eax = 15 - ­®¬¥à ä㭪樨
* ebx = 4 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ०¨¬ ®âà¨á®¢ª¨:
* 1 = § ¬®áâ¨âì
* 2 = à áâï­ãâì
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* „«ï ®¡­®¢«¥­¨ï íªà ­  (¯®á«¥ § ¢¥à襭¨ï á¥à¨¨ ª®¬ ­¤, à ¡®â îé¨å á
ä®­®¬) ¢ë§ë¢ ©â¥ ¯®¤äã­ªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä®­ .
* …áâì ¯ à­ ï ª®¬ ­¤  ¯®«ã祭¨ï ०¨¬  ®âà¨á®¢ª¨ ä®­  -
¯®¤äã­ªæ¨ï 4 ä㭪樨 39.
 
======================================================================
===== ”ã­ªæ¨ï 15, ¯®¤äã­ªæ¨ï 5 - ¯®¬¥áâ¨âì ¡«®ª ¯¨ªá¥«¥© ­  ä®­. =====
======================================================================
 à ¬¥âàë:
* eax = 15 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¤ ­­ë¥ ¢ ä®à¬ â¥ BBGGRRBBGGRR...
* edx = ᬥ饭¨¥ ¢ ¤ ­­ëå ä®­®¢®£® ¨§®¡à ¦¥­¨ï
* esi = à §¬¥à ¤ ­­ëå ¢ ¡ ©â å = 3 * ç¨á«® ¯¨ªá¥«¥©
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* à®¢¥àª¨ ª®à४⭮á⨠ᬥ饭¨ï ¨ à §¬¥à  ­¥ ¯à®¨§¢®¤¨âáï.
* –¢¥â ª ¦¤®£® ¯¨ªá¥«ï åà ­¨âáï ª ª 3-¡ ©â­ ï ¢¥«¨ç¨­  BBGGRR.
* ¨ªá¥«¨ ä®­®¢®£® ¨§®¡à ¦¥­¨ï § ¯¨á뢠îâáï ¯®á«¥¤®¢ â¥«ì­®
á«¥¢  ­ ¯à ¢®, ᢥàåã ¢­¨§.
* ‘¬¥é¥­¨¥ ¯¨ªá¥«ï á ª®®à¤¨­ â ¬¨ (x,y) ¥áâì (x+y*xsize)*3.
* „«ï ®¡­®¢«¥­¨ï íªà ­  (¯®á«¥ § ¢¥à襭¨ï á¥à¨¨ ª®¬ ­¤, à ¡®â îé¨å á
ä®­®¬) ¢ë§ë¢ ©â¥ ¯®¤äã­ªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä®­ .
 
======================================================================
====================== ”ã­ªæ¨ï 15, ¯®¤äã­ªæ¨ï 6 ======================
==== ‘¯à®¥æ¨à®¢ âì ¤ ­­ë¥ ä®­  ­   ¤à¥á­®¥ ¯à®áâà ­á⢮ ¯à®æ¥áá . ====
======================================================================
 à ¬¥âàë:
* eax = 15 - ­®¬¥à ä㭪樨
* ebx = 6 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 㪠§ â¥«ì ­  ¤ ­­ë¥ ä®­ , 0 ¯à¨ ®è¨¡ª¥
‡ ¬¥ç ­¨ï:
* ‘¯à®¥æ¨à®¢ ­­ë¥ ¤ ­­ë¥ ¤®áâã¯­ë ­  ç⥭¨¥ ¨ § ¯¨áì.
*  §¬¥à ¤ ­­ëå ä®­  à ¢¥­ 3*xsize*ysize. ˆ§¬¥­¥­¨¥ à §¬¥à®¢ ä®­ 
¡«®ª¨àã¥âáï ­  ¢à¥¬ï à ¡®âë á á¯à®¥æ¨à®¢ ­­ë¬¨ ¤ ­­ë¬¨.
* –¢¥â ª ¦¤®£® ¯¨ªá¥«ï åà ­¨âáï ª ª 3-¡ ©â®¢ ï ¢¥«¨ç¨­  BBGGRR.
* ¨ªá¥«¨ ä®­®¢®£® ¨§®¡à ¦¥­¨ï § ¯¨á뢠îâáï ¯®á«¥¤®¢ â¥«ì­®
á«¥¢  ­ ¯à ¢®, ᢥàåã ¢­¨§.
 
======================================================================
====================== ”ã­ªæ¨ï 15, ¯®¤äã­ªæ¨ï 7 ======================
=== ‡ ªàëâì ¯à®¥ªæ¨î ¤ ­­ëå ä®­  ­   ¤à¥á­®¥ ¯à®áâà ­á⢮ ¯à®æ¥áá . ==
======================================================================
 à ¬¥âàë:
* eax = 15 - ­®¬¥à ä㭪樨
* ebx = 7 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¤ ­­ë¥ ä®­ 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 1 ¯à¨ ãᯥå¥, 0 ¯à¨ ®è¨¡ª¥
 
======================================================================
============= ”ã­ªæ¨ï 16 - á®åà ­¨âì à ¬¤¨áª ­  ¤¨áª¥âã. =============
======================================================================
 à ¬¥âàë:
* eax = 16 - ­®¬¥à ä㭪樨
* ebx = 1 ¨«¨ ebx = 2 - ­  ª ªãî ¤¨áª¥âã á®åà ­ïâì
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ®è¨¡ª 
 
======================================================================
============== ”ã­ªæ¨ï 17 - ¯®«ãç¨âì ª®¤ ­ ¦ â®© ª­®¯ª¨. =============
======================================================================
‡ ¡¨à ¥â ª®¤ ­ ¦ â®© ª­®¯ª¨ ¨§ ¡ãä¥à .
 à ¬¥âàë:
* eax = 17 - ­®¬¥à ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¥á«¨ ¡ãä¥à ¯ãáâ, ¢®§¢à é ¥âáï eax=1
* ¥á«¨ ¡ãä¥à ­¥¯ãáâ:
* áâ à訥 24 ¡¨â  eax ᮤ¥à¦ â ¨¤¥­â¨ä¨ª â®à ª­®¯ª¨
(¢ ç áâ­®áâ¨, ¢ ah ®ª §ë¢ ¥âáï ¬« ¤è¨© ¡ ©â ¨¤¥­â¨ä¨ª â®à ;
¥á«¨ ¢á¥ ª­®¯ª¨ ¨¬¥îâ ¨¤¥­â¨ä¨ª â®à, ¬¥­ì訩 256,
â® ¤«ï à §«¨ç¥­¨ï ¤®áâ â®ç­® ah)
* al = 0 - ª­®¯ª  ¡ë«  ­ ¦ â  «¥¢®© ª­®¯ª®© ¬ëè¨
* al = ¡¨â, ᮮ⢥âáâ¢ãî騩 ­ ¦ ¢è¥© ª­®¯ª¥ ¬ëè¨, ¥á«¨ ­¥ «¥¢®©
‡ ¬¥ç ­¨ï:
* "ãä¥à" åà ­¨â ⮫쪮 ®¤­ã ª­®¯ªã, ¯à¨ ­ ¦ â¨¨ ­®¢®© ª­®¯ª¨
¨­ä®à¬ æ¨ï ® áâ à®© â¥àï¥âáï.
* à¨ ¢ë§®¢¥ í⮩ ä㭪樨 ¯à¨«®¦¥­¨¥¬ á ­¥ ªâ¨¢­ë¬ ®ª­®¬
¢®§¢à é ¥âáï ®â¢¥â "¡ãä¥à ¯ãáâ".
* ‚®§¢à é ¥¬®¥ §­ ç¥­¨¥ al ᮮ⢥âáâ¢ã¥â á®áâ®ï­¨î ª­®¯®ª ¬ëè¨
¢ ä®à¬ â¥ ¯®¤ä㭪樨 2 ä㭪樨 37 ¢ ¬®¬¥­â ­ ç «  ­ ¦ â¨ï
­  ª­®¯ªã, §  ¨áª«î祭¨¥¬ ¬« ¤è¥£® ¡¨â  (ᮮ⢥âáâ¢ãî饣® «¥¢®©
ª­®¯ª¥ ¬ëè¨), ª®â®àë© á¡à á뢠¥âáï.
 
======================================================================
==== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 2 - § ¢¥àè¨âì ¯à®æ¥áá/¯®â®ª ¯® á«®âã. ====
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­®¬¥à á«®â  ¯à®æ¥áá /¯®â®ª 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ¥«ì§ï § ¢¥àè¨âì ¯®â®ª ®¯¥à æ¨®­­®© á¨á⥬ë OS/IDLE (­®¬¥à á«®â 
1), ¬®¦­® § ¢¥àè¨âì «î¡®© ®¡ëç­ë© ¯®â®ª/¯à®æ¥áá.
* ‘¬®âਠ⠪¦¥ ¯®¤äã­ªæ¨î 18 - § ¢¥à襭¨¥
¯à®æ¥áá /¯®â®ª  á § ¤ ­­ë¬ ¨¤¥­â¨ä¨ª â®à®¬.
 
======================================================================
= ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 3 - ᤥ« âì  ªâ¨¢­ë¬ ®ª­® § ¤ ­­®£® ¯®â®ª . =
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 3 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­®¬¥à á«®â  ¯®â®ª 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* à¨ 㪠§ ­¨¨ ª®à४⭮£®, ­® ­¥áãé¥áâ¢ãî饣® á«®â   ªâ¨¢¨§¨àã¥âáï
ª ª®¥-â® ®ª­®.
* “§­ âì, ª ª®¥ ®ª­® ï¥âáï  ªâ¨¢­ë¬, ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 7.
 
======================================================================
”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 4 - ¯®«ãç¨âì áçñâ稪 ¯ãáâëå ⠪⮢ ¢ ᥪ㭤ã.
======================================================================
®¤ ¯ãáâ묨 ⠪⠬¨ ¯®­¨¬ ¥âáï ¢à¥¬ï, ¢ ª®â®à®¥ ¯à®æ¥áá®à ¯à®áâ ¨¢ ¥â
¢ ®¦¨¤ ­¨¨ ¯à¥à뢠­¨ï (¢ ¨­áâàãªæ¨¨ hlt).
 
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 4 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = §­ ç¥­¨¥ áçñâ稪  ¯ãáâëå ⠪⮢ ¢ ᥪ㭤ã
 
======================================================================
======== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 5 - ¯®«ãç¨âì ⠪⮢ãî ç áâ®âã. =======
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ⠪⮢ ï ç áâ®â  (¯® ¬®¤ã«î 2^32 ⠪⮢ = 4ƒƒæ)
 
======================================================================
”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 6 - á®åà ­¨âì à ¬¤¨áª ¢ ä ©« ­  ¦ñá⪮¬ ¤¨áª¥.
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 6 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  áâபã á ¯®«­ë¬ ¨¬¥­¥¬ ä ©« 
(­ ¯à¨¬¥à, "/hd0/1/kolibri/kolibri.img")
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* ¨­ ç¥ eax = ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
‡ ¬¥ç ­¨ï:
* ‚ᥠ¯ ¯ª¨ ¢ 㪠§ ­­®¬ ¯ã⨠¤®«¦­ë áãé¥á⢮¢ âì, ¨­ ç¥ ¢¥à­ñâáï
§­ ç¥­¨¥ 5, "ä ©« ­¥ ­ ©¤¥­".
 
======================================================================
====== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 7 - ¯®«ãç¨âì ­®¬¥à  ªâ¨¢­®£® ®ª­ . =====
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 7 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ­®¬¥à  ªâ¨¢­®£® ®ª­  (­®¬¥à á«®â  ¯®â®ª , ®ª­® ª®â®à®£®
 ªâ¨¢­®)
‡ ¬¥ç ­¨ï:
* €ªâ¨¢­®¥ ®ª­® ­ å®¤¨âáï ¢¢¥àåã ®ª®­­®£® áâíª  ¨ ¯®«ãç ¥â
á®®¡é¥­¨ï ®¡® ¢áñ¬ ¢¢®¤¥ á ª« ¢¨ âãàë.
* ‘¤¥« âì ®ª­®  ªâ¨¢­ë¬ ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 3.
 
======================================================================
==== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 8 - ®âª«îç¨âì/à §à¥è¨âì §¢ãª ᯨª¥à . ====
======================================================================
à¨ ®âª«îçñ­­®¬ §¢ãª¥ ¢ë§®¢ë ¯®¤ä㭪樨 55 ä㭪樨 55 ¨£­®à¨àãîâáï.
à¨ ¢ª«îçñ­­®¬ - ­ ¯à ¢«ïîâáï ­  ¢áâ஥­­ë© ᯨª¥à.
 
--------------- ®¤¯®¤äã­ªæ¨ï 1 - ¯®«ãç¨âì á®áâ®ï­¨¥. ----------------
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 8 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 1 - ­®¬¥à ¯®¤¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - §¢ãª ᯨª¥à  à §à¥èñ­; 1 - § ¯à¥éñ­
 
-------------- ®¤¯®¤äã­ªæ¨ï 2 - ¯¥à¥ª«îç¨âì á®áâ®ï­¨¥. --------------
¥à¥ª«îç ¥â á®áâ®ï­¨ï à §à¥è¥­¨ï/§ ¯à¥é¥­¨ï.
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 8 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 2 - ­®¬¥à ¯®¤¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
======================================================================
= ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 9 - § ¢¥à襭¨¥ à ¡®âë á¨á⥬ë á ¯ à ¬¥â஬. =
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 9 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¯ à ¬¥âà:
* 2 = ¢ëª«îç¨âì ª®¬¯ìîâ¥à
* 3 = ¯¥à¥§ £à㧨âì ª®¬¯ìîâ¥à
* 4 = ¯¥à¥§ ¯ãáâ¨âì ï¤à® ¨§ ä ©«  kernel.mnt ­  à ¬¤¨áª¥
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¯à¨ ­¥¢¥à­®¬ ecx ॣ¨áâàë ­¥ ¬¥­ïîâáï (â.¥. eax=18)
* ¯à¨ ¯à ¢¨«ì­®¬ ¢ë§®¢¥ ¢á¥£¤  ¢®§¢à é ¥âáï ¯à¨§­ ª ãá¯¥å  eax=0
‡ ¬¥ç ­¨ï:
* ¥ á«¥¤ã¥â ¯®« £ âìáï ­  ¢®§¢à é ¥¬®¥ §­ ç¥­¨¥ ¯à¨ ­¥¢¥à­®¬
¢ë§®¢¥, ®­® ¬®¦¥â ¨§¬¥­¨âìáï ¢ ¯®á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à .
 
======================================================================
======== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 10 - ᢥà­ãâì ®ª­® ¯à¨«®¦¥­¨ï. =======
======================================================================
‘¢®à ç¨¢ ¥â ᮡá⢥­­®¥ ®ª­®.
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 10 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* Œ¨­¨¬¨§¨à®¢ ­­®¥ ®ª­® á â®çª¨ §à¥­¨ï ä㭪樨 9 á®åà ­ï¥â ¯®«®¦¥­¨¥
¨ à §¬¥àë.
* ‚®ááâ ­®¢«¥­¨¥ ®ª­  ¯à¨«®¦¥­¨ï ¯à®¨á室¨â ¯à¨  ªâ¨¢¨§¨à®¢ ­¨¨
¯®¤ä㭪樥© 3.
* Ž¡ëç­® ­¥â ­¥®¡å®¤¨¬®á⨠® ᢮à ç¨¢ âì/à §¢®à ç¨¢ âì ᢮ñ ®ª­®:
᢮à ç¨¢ ­¨¥ ®ª­  ®áãé¥á⢫ï¥âáï á¨á⥬®© ¯à¨ ­ ¦ â¨¨ ­  ª­®¯ªã
¬¨­¨¬¨§ æ¨¨ (ª®â®à ï ¤«ï ®ª®­ ᮠ᪨­®¬ ®¯à¥¤¥«ï¥âáï  ¢â®¬ â¨ç¥áª¨
ä㭪樥© 0, ¤«ï ®ª®­ ¡¥§ ᪨­  ¥ñ ¬®¦­® ®¯à¥¤¥«¨âì ä㭪樥© 8),
¢®ááâ ­®¢«¥­¨¥ - ¯à¨«®¦¥­¨¥¬ @panel.
 
======================================================================
====================== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 11 =====================
============= ®«ãç¨âì ¨­ä®à¬ æ¨î ® ¤¨áª®¢®© ¯®¤á¨á⥬¥. =============
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 11 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ⨯ â ¡«¨æë:
* 1 = ª®à®âª ï ¢¥àá¨ï, 10 ¡ ©â
* 2 = ¯®«­ ï ¢¥àá¨ï, 65536 ¡ ©â
* edx = 㪠§ â¥«ì ­  ¡ãä¥à (¢ ¯à¨«®¦¥­¨¨) ¤«ï â ¡«¨æë
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
”®à¬ â â ¡«¨æë: ª®à®âª ï ¢¥àá¨ï:
* +0: byte: ¨­ä®à¬ æ¨ï ® ƒŒ„ (¤¨áª®¢®¤ å ¤«ï ¤¨áª¥â), AAAABBBB,
£¤¥ AAAA § ¤ ñâ ⨯ ¯¥à¢®£® ¤¨áª®¢®¤ , BBBB - ¢â®à®£® ᮣ« á­®
á«¥¤ãî饬ã ᯨáªã:
* 0 = ­¥â ¤¨áª®¢®¤ 
* 1 = 360Kb, 5.25''
* 2 = 1.2Mb, 5.25''
* 3 = 720Kb, 3.5''
* 4 = 1.44Mb, 3.5''
* 5 = 2.88Mb, 3.5'' (â ª¨¥ ¤¨áª¥âë ᥩç á 㦥 ­¥ ¨á¯®«ì§ãîâáï)
 ¯à¨¬¥à, ¤«ï áâ ­¤ àâ­®© ª®­ä¨£ãà æ¨¨ ¨§ ®¤­®£® 1.44-¤¨áª®¢®¤ 
§¤¥áì ¡ã¤¥â 40h,   ¤«ï á«ãç ï 1.2Mb ­  A: ¨ 1.44Mb ­  B:
§­ ç¥­¨¥ ®ª §ë¢ ¥âáï 24h.
* +1: byte: ¨­ä®à¬ æ¨ï ® ¦ñáâª¨å ¤¨áª å ¨ CD-¯à¨¢®¤ å, AABBCCDD,
£¤¥ AA ᮮ⢥âáâ¢ã¥â ª®­â஫«¥àã IDE0, ..., DD - IDE3:
* 0 = ãáâனá⢮ ®âáãâáâ¢ã¥â
* 1 = ¦ñá⪨© ¤¨áª
* 2 = CD-¯à¨¢®¤
 ¯à¨¬¥à, ¢ á«ãç ¥ HD ­  IDE0 ¨ CD ­  IDE2 §¤¥áì ¡ã¤¥â 48h.
* +2: 4 db: ç¨á«® ­ ©¤¥­­ëå à §¤¥«®¢ ­  ¦ñáâª¨å ¤¨áª å á
ᮮ⢥âá⢥­­® IDE0,...,IDE3.
à¨ ®âáãâá⢨¨ ¦ñá⪮£® ¤¨áª  ­  IDEx ᮮ⢥âáâ¢ãî騩 ¡ ©â
­ã«¥¢®©, ¯à¨ ­ «¨ç¨¨ ¯®ª §ë¢ ¥â ç¨á«® à á¯®§­ ­­ëå à §¤¥«®¢,
ª®â®àëå ¬®¦¥â ¨ ­¥ ¡ëâì (¥á«¨ ­®á¨â¥«ì ­¥ ®âä®à¬ â¨à®¢ ­ ¨«¨
¥á«¨ ä ©«®¢ ï á¨á⥬  ­¥ ¯®¤¤¥à¦¨¢ ¥âáï). ‚ ⥪ã饩 ¢¥àᨨ ï¤à 
¤«ï ¦ñáâª¨å ¤¨áª®¢ ¯®¤¤¥à¦¨¢ îâáï ⮫쪮 FAT16, FAT32 ¨ NTFS.
* +6: 4 db: § à¥§¥à¢¨à®¢ ­®
”®à¬ â â ¡«¨æë: ¯®«­ ï ¢¥àá¨ï:
* +0: 10 db: â ª¨¥ ¦¥, ª ª ¨ ¢ ª®à®âª®© ¢¥àᨨ
* +10: 100 db: ¤ ­­ë¥ ¤«ï ¯¥à¢®£® à §¤¥« 
* +110: 100 db: ¤ ­­ë¥ ¤«ï ¢â®à®£® à §¤¥« 
* ...
* +10+100*(n-1): 100 db: ¤ ­­ë¥ ¤«ï ¯®á«¥¤­¥£® à §¤¥« 
 §¤¥«ë à á¯®«®¦¥­ë ¢ á«¥¤ãî饬 ¯®à浪¥: á­ ç «  ¯®á«¥¤®¢ â¥«ì­® ¢á¥
à á¯®§­ ­­ë¥ à §¤¥«ë ­  HD ­  IDE0 (¥á«¨ ¥áâì),
§ â¥¬ ­  HD ­  IDE1 (¥á«¨ ¥áâì) ¨ â.¤. ¤® IDE3.
”®à¬ â ¨­ä®à¬ æ¨¨ ® à §¤¥«¥:
* +0: dword: ­ ç «ì­ë© 䨧¨ç¥áª¨© ᥪâ®à à §¤¥« 
* +4: dword: ¯®á«¥¤­¨© 䨧¨ç¥áª¨© ᥪâ®à à §¤¥« 
(¯à¨­ ¤«¥¦¨â à §¤¥«ã)
* +8: byte: ⨯ ä ©«®¢®© á¨á⥬ë:
16=FAT16, 32=FAT32, 1=NTFS
* ä®à¬ â ¤ «ì­¥©è¨å ¤ ­­ëå § ¢¨á¨â ®â ä ©«®¢®© á¨á⥬ë,
¬®¦¥â ¬¥­ïâìáï á ¨§¬¥­¥­¨ï¬¨ ¢ ï¤à¥ ¨ ¯®í⮬㠭¥ ®¯¨á뢠¥âáï
‡ ¬¥ç ­¨ï:
* Š®à®âª ï â ¡«¨æ  ¬®¦¥â ¡ëâì ¨á¯®«ì§®¢ ­  ¤«ï ¯®«ã祭¨ï ¨­ä®à¬ æ¨¨
®¡ ¨¬¥îé¨åáï ãáâனá⢠å.
 
======================================================================
========== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 13 - ¯®«ãç¨âì ¢¥àá¨î ï¤à . =========
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 13 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¡ãä¥à (­¥ ¬¥­¥¥ 16 ¡ ©â), ªã¤  ¡ã¤¥â ¯®¬¥é¥­ 
¨­ä®à¬ æ¨ï
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‘âàãªâãà  ¡ãä¥à :
db a,b,c,d ¤«ï ¢¥àᨨ a.b.c.d
db UID_xxx: ®¤­® ¨§ UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2
dd REV - ­®¬¥à svn-ॢ¨§¨¨ ï¤à 
„«ï ï¤à  Kolibri 0.7.1.0:
db 0,7,1,0
db 2
dd 638
 
======================================================================
====================== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 14 =====================
======= Ž¦¨¤ âì ­ ç «  ®¡à â­®£® 室  «ãç  à §¢ñà⪨ ¬®­¨â®à . =======
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 14 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 ª ª ¯à¨§­ ª ãᯥå 
‡ ¬¥ç ­¨ï:
* ”ã­ªæ¨ï ¯à¥¤­ §­ ç¥­  ¨áª«îç¨â¥«ì­® ¤«ï  ªâ¨¢­ëå
¢ë᮪®¯à®¨§¢®¤¨â¥«ì­ëå £à ä¨ç¥áª¨å ¯à¨«®¦¥­¨©; ¨á¯®«ì§ã¥âáï ¤«ï
¯« ¢­®£® ¢ë¢®¤  £à ä¨ª¨.
 
======================================================================
== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 15 - ¯®¬¥áâ¨âì ªãàá®à ¬ëè¨ ¢ 業âà íªà ­ . =
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 15 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 ª ª ¯à¨§­ ª ãᯥå 
 
======================================================================
====================== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 16 =====================
============ ®«ãç¨âì à §¬¥à ᢮¡®¤­®© ®¯¥à â¨¢­®© ¯ ¬ïâ¨. ===========
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 16 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = à §¬¥à ᢮¡®¤­®© ¯ ¬ï⨠¢ ª¨«®¡ ©â å
 
======================================================================
====================== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 17 =====================
============ ®«ãç¨âì à §¬¥à ¨¬¥î饩áï ®¯¥à â¨¢­®© ¯ ¬ïâ¨. ===========
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 17 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ®¡é¨© à §¬¥à ¨¬¥î饩áï ¯ ¬ï⨠¢ ª¨«®¡ ©â å
 
======================================================================
====================== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 18 =====================
============= ‡ ¢¥àè¨âì ¯à®æ¥áá/¯®â®ª ¯® ¨¤¥­â¨ä¨ª â®àã. =============
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 18 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¤¥­â¨ä¨ª â®à ¯à®æ¥áá /¯®â®ª  (PID/TID)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = -1 - ®è¨¡ª  (¯à®æ¥áá ­¥ ­ ©¤¥­ ¨«¨ ï¥âáï á¨á⥬­ë¬)
‡ ¬¥ç ­¨ï:
* ¥«ì§ï § ¢¥àè¨âì ¯®â®ª ®¯¥à æ¨®­­®© á¨á⥬ë OS/IDLE (­®¬¥à á«®â 
1), ¬®¦­® § ¢¥àè¨âì «î¡®© ®¡ëç­ë© ¯®â®ª/¯à®æ¥áá.
* ‘¬®âਠ⠪¦¥ ¯®¤äã­ªæ¨î 2 - § ¢¥à襭¨¥
¯à®æ¥áá /¯®â®ª  ¯® § ¤ ­­®¬ã á«®âã.
 
======================================================================
=== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 19 - ¯®«ãç¨âì/ãáâ ­®¢¨âì ­ áâனª¨ ¬ëè¨. ==
======================================================================
 
------------- ®¤¯®¤äã­ªæ¨ï 0 - ¯®«ãç¨âì ᪮à®áâì ¬ëè¨. --------------
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 19 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 0 - ­®¬¥à ¯®¤¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ⥪ãé ï ᪮à®áâì ¬ëè¨
 
------------ ®¤¯®¤äã­ªæ¨ï 1 - ãáâ ­®¢¨âì ᪮à®áâì ¬ëè¨. -------------
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 19 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 1 - ­®¬¥à ¯®¤¯®¤ä㭪樨
* edx = ­®¢®¥ §­ ç¥­¨¥ ᪮à®áâ¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
------------- ®¤¯®¤äã­ªæ¨ï 2 - ¯®«ãç¨âì § ¤¥à¦ªã ¬ëè¨. --------------
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 19 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 2 - ­®¬¥à ¯®¤¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ⥪ãé ï § ¤¥à¦ª  ¬ëè¨
 
------------ ®¤¯®¤äã­ªæ¨ï 3 - ãáâ ­®¢¨âì § ¤¥à¦ªã ¬ëè¨. -------------
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 19 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 3 - ­®¬¥à ¯®¤¯®¤ä㭪樨
* edx = ­®¢®¥ §­ ç¥­¨¥ § ¤¥à¦ª¨ ¬ëè¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
-------- ®¤¯®¤äã­ªæ¨ï 4 - ãáâ ­®¢¨âì ¯®«®¦¥­¨¥ ªãàá®à  ¬ëè¨. --------
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 19 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 4 - ­®¬¥à ¯®¤¯®¤ä㭪樨
* edx = [ª®®à¤¨­ â  ¯® ®á¨ x]*65536 + [ª®®à¤¨­ â  ¯® ®á¨ y]
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
------- ®¤¯®¤äã­ªæ¨ï 5 - ᨬ㫨஢ âì á®áâ®ï­¨¥ ª« ¢¨è ¬ëè¨. --------
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 19 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 5 - ­®¬¥à ¯®¤¯®¤ä㭪樨
* edx = ¨­ä®à¬ æ¨ï ® í¬ã«¨à㥬®¬ á®áâ®ï­¨¨ ª­®¯®ª ¬ëè¨:
(ᮮ⢥âáâ¢ã¥â ¢®§¢à é ¥¬®¬ã §­ ç¥­¨î ¯®¤ä㭪樨 2 ä㭪樨 37)
* ¡¨â 0 ãáâ ­®¢«¥­ = «¥¢ ï ª­®¯ª  ­ ¦ â 
* ¡¨â 1 ãáâ ­®¢«¥­ = ¯à ¢ ï ª­®¯ª  ­ ¦ â 
* ¡¨â 2 ãáâ ­®¢«¥­ = á।­ïï ª­®¯ª  ­ ¦ â 
* ¡¨â 3 ãáâ ­®¢«¥­ = 4-ï ª­®¯ª  ­ ¦ â 
* ¡¨â 4 ãáâ ­®¢«¥­ = 5-ï ª­®¯ª  ­ ¦ â 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ¥ª®¬¥­¤ã¥¬ ï ᪮à®áâì ¬ëè¨ (¢ ¯®¤¯®¤ä㭪樨 1) ®â 1 ¤® 9.
“áâ ­ ¢«¨¢ ¥¬ ï ¢¥«¨ç¨­  ­¥ ¯à®¢¥àï¥âáï ª®¤®¬ ï¤à , ¯®í⮬ã
¨á¯®«ì§ã©â¥ ®áâ®à®¦­®, ¯à¨ ­¥ª®à४⭮¬ §­ ç¥­¨¨ ªãàá®à ¬®¦¥â
"§ ¬ñ৭ãâì". ‘ª®à®áâì ¬ëè¨ ¬®¦­® ॣ㫨஢ âì ¢ ¯à¨«®¦¥­¨¨ SETUP.
* ¥ª®¬¥­¤ã¥¬ ï ¢¥«¨ç¨­  § ¤¥à¦ª¨ (¢ ¯®¤¯®¤ä㭪樨 3) = 10.
Œ¥­ì訥 §­ ç¥­¨ï ­¥ ®¡à ¡ â뢠îâáï COM-¬ëè ¬¨. à¨ ®ç¥­ì ¡®«ìè¨å
§­ ç¥­¨ïå ­¥¢®§¬®¦­® ¯¥à¥¤¢¨¦¥­¨¥ ¬ëè¨ ­  1 ¯¨ªá¥«ì ¨ ªãàá®à ¡ã¤¥â
¯à룠âì ­  ¢¥«¨ç¨­ã ãáâ ­®¢«¥­­®© ᪮à®á⨠(¯®¤¯®¤äã­ªæ¨ï 1).
“áâ ­ ¢«¨¢ ¥¬ ï ¢¥«¨ç¨­  ­¥ ¯à®¢¥àï¥âáï ª®¤®¬ ï¤à .
‚¥«¨ç¨­ã § ¤¥à¦ª¨ ¬®¦­® ¬¥­ïâì ¢ ¯à¨«®¦¥­¨¨ SETUP.
* ®¤¯®¤äã­ªæ¨ï 4 ­¥ ¯à®¢¥àï¥â ¯¥à¥¤ ­­®¥ §­ ç¥­¨¥. ¥à¥¤ ¢ë§®¢®¬
­¥®¡å®¤¨¬® 㧭 âì ⥪ã饥 à §à¥è¥­¨¥ íªà ­  (¯®¤ä㭪樥© 14)
¨ ¯à®¢¥à¨âì, çâ® ãáâ ­ ¢«¨¢ ¥¬®¥ ¯®«®¦¥­¨¥ ­¥ ¢ë室¨â §  ¯à¥¤¥«ë
íªà ­ .
 
======================================================================
====================== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 20 =====================
============= ®«ãç¨âì ¨­ä®à¬ æ¨î ®¡ ®¯¥à â¨¢­®© ¯ ¬ïâ¨. =============
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 20 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¡ãä¥à ¤«ï ¨­ä®à¬ æ¨¨ (36 ¡ ©â)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ®¡é¨© à §¬¥à ¨¬¥î饩áï ®¯¥à â¨¢­®© ¯ ¬ï⨠¢ ¡ ©â å
¨«¨ -1 ¢ á«ãç ¥ ®è¨¡ª¨
* ¡ãä¥à, ­  ª®â®àë© ãª §ë¢ ¥â ecx, ᮤ¥à¦¨â á«¥¤ãîéãî ¨­ä®à¬ æ¨î:
* +0: dword: ®¡é¨© à §¬¥à ¨¬¥î饩áï ®¯¥à â¨¢­®© ¯ ¬ï⨠¢ áâà ­¨æ å
* +4: dword: à §¬¥à ᢮¡®¤­®© ®¯¥à â¨¢­®© ¯ ¬ï⨠¢ áâà ­¨æ å
* +8: dword: ç¨á«® áâà ­¨ç­ëå ®è¨¡®ª (¨áª«î祭¨© #PF)
¢ ¯à¨«®¦¥­¨ïå
* +12: dword: à §¬¥à ªãç¨ ï¤à  ¢ ¡ ©â å
* +16: dword: à §¬¥à ᢮¡®¤­®© ¯ ¬ï⨠¢ ªãç¥ ï¤à  ¢ ¡ ©â å
* +20: dword: ®¡é¥¥ ª®«¨ç¥á⢮ ¡«®ª®¢ ¯ ¬ï⨠¢ ªãç¥ ï¤à 
* +24: dword: ª®«¨ç¥á⢮ ᢮¡®¤­ëå ¡«®ª®¢ ¯ ¬ï⨠¢ ªãç¥ ï¤à 
* +28: dword: à §¬¥à ­ ¨¡®«ì襣® ᢮¡®¤­®£® ¡«®ª  ¢ ªãç¥ ï¤à 
(§ à¥§¥à¢¨à®¢ ­®)
* +32: dword: à §¬¥à ­ ¨¡®«ì襣® ¢ë¤¥«¥­­®£® ¡«®ª  ¢ ªãç¥ ï¤à 
(§ à¥§¥à¢¨à®¢ ­®)
 
======================================================================
====================== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 21 =====================
======= ®«ãç¨âì ­®¬¥à á«®â  ¯à®æ¥áá /¯®â®ª  ¯® ¨¤¥­â¨ä¨ª â®àã. ======
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 21 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¤¥­â¨ä¨ª â®à ¯à®æ¥áá /¯®â®ª  (PID/TID)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ®è¨¡ª  (­¥¢¥à­ë© ¨¤¥­â¨ä¨ª â®à)
* ¨­ ç¥ eax = ­®¬¥à á«®â 
 
======================================================================
”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 22 - ®¯¥à æ¨¨ á ®ª­®¬ ¤à㣮£® ¯à®æ¥áá /¯®â®ª .
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 22 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ⨯ ®¯¥à æ¨¨:
* 0 = ¬¨­¨¬¨§ æ¨ï ®ª­ , ¯®â®ª § ¤ ­ ­®¬¥à®¬ á«®â 
* 1 = ¬¨­¨¬¨§ æ¨ï ®ª­ , ¯®â®ª § ¤ ­ ¨¤¥­â¨ä¨ª â®à®¬
* 2 = ¢®ááâ ­®¢«¥­¨¥ ®ª­ , ¯®â®ª § ¤ ­ ­®¬¥à®¬ á«®â 
* 3 = ¢®ááâ ­®¢«¥­¨¥ ®ª­ , ¯®â®ª § ¤ ­ ¨¤¥­â¨ä¨ª â®à®¬
* edx = ¯ à ¬¥âà ®¯¥à æ¨¨ (­®¬¥à á«®â  ¨«¨ PID/TID)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = -1 - ®è¨¡ª  (­¥¯à ¢¨«ì­ë© ¯ à ¬¥âà)
‡ ¬¥ç ­¨ï:
* ®â®ª ¬®¦¥â ᢥà­ãâì ᢮ñ ®ª­® ¢ë§®¢®¬ ¯®¤ä㭪樨 10.
* ‚®ááâ ­®¢«¥­¨¥ ®ª­  á ®¤­®¢à¥¬¥­­®©  ªâ¨¢¨§ æ¨¥© ®áãé¥á⢫ï¥âáï
¯®¤ä㭪樨 3 (¯à¨­¨¬ î饩 ­®¬¥à á«®â ).
 
======================================================================
==================== ”ã­ªæ¨ï 20 - ¨­â¥à䥩á MIDI. ====================
======================================================================
 
------------------------ ®¤äã­ªæ¨ï 1 - á¡à®á ------------------------
 à ¬¥âàë:
* eax = 20 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
 
-------------------- ®¤äã­ªæ¨ï 2 - ¢ë¢¥á⨠¡ ©â ---------------------
 à ¬¥âàë:
* eax = 20 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* cl = ¡ ©â ¤«ï ¢ë¢®¤ 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥ (®¤¨­ ª®¢® ¤«ï ®¡¥¨å ¯®¤ä㭪権):
* eax = 0 - ãᯥ譮
* eax = 1 - ­¥ ®¯à¥¤¥«ñ­ ¡ §®¢ë© ¯®àâ
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì ®¯à¥¤¥«ñ­ ¡ §®¢ë© ¯®à⠢맮¢®¬
¯®¤ä㭪樨 1 ä㭪樨 21.
 
======================================================================
==== ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 1 - ãáâ ­®¢¨âì ¡ §®¢ë© ¯®àâ MPU MIDI. ====
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­®¬¥à ¡ §®¢®£® ¯®àâ 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = -1 - ®è¨¡®ç­ë© ­®¬¥à ¯®àâ 
‡ ¬¥ç ­¨ï:
* ®¬¥à ¯®àâ  ¤®«¦¥­ 㤮¢«¥â¢®àïâì ãá«®¢¨ï¬ 0x100<=ecx<=0xFFFF.
* “áâ ­®¢ª  ¡ §ë ­ã¦­  ¤«ï à ¡®âë ä㭪樨 20.
* ®«ãç¨âì ãáâ ­®¢«¥­­ë© ¡ §®¢ë© ¯®àâ ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 1 ä㭪樨 26.
 
======================================================================
===== ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 2 - ãáâ ­®¢¨âì à áª« ¤ªã ª« ¢¨ âãàë. ====
======================================================================
 áª« ¤ª  ª« ¢¨ âãàë ¨á¯®«ì§ã¥âáï ¤«ï ¯à¥®¡à §®¢ ­¨ï ᪠­ª®¤®¢,
¯®áâ㯠îé¨å ®â ª« ¢¨ âãàë, ¢ ASCII-ª®¤ë, áç¨â뢠¥¬ë¥ ä㭪樥© 2.
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ª ªãî à áª« ¤ªã ãáâ ­ ¢«¨¢ âì:
* 1 = ­®à¬ «ì­ãî
* 2 = à áª« ¤ªã ¯à¨ ­ ¦ â®¬ Shift
* 3 = à áª« ¤ªã ¯à¨ ­ ¦ â®¬ Alt
* edx = 㪠§ â¥«ì ­  à áª« ¤ªã - â ¡«¨æã ¤«¨­®© 128 ¡ ©â
ˆ«¨:
* ecx = 9
* dx = ¨¤¥­â¨ä¨ª â®à áâà ­ë (1=eng, 2=fi, 3=ger, 4=rus)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ¯ à ¬¥âà § ¤ ­ ­¥¢¥à­®
‡ ¬¥ç ­¨ï:
* …᫨ ­ ¦ â Alt, â® ¨á¯®«ì§ã¥âáï à áª« ¤ª  á Alt;
¥á«¨ ­¥ ­ ¦ â Alt, ­® ­ ¦ â Shift, â®
¨á¯®«ì§ã¥âáï à áª« ¤ª  á Shift;
¥á«¨ ­¥ ­ ¦ âë Alt ¨ Shift, ­® ­ ¦ â Ctrl, â® ¨á¯®«ì§ã¥âáï
­®à¬ «ì­ ï à áª« ¤ª , ¯®á«¥ 祣® ¨§ ª®¤  ¢ëç¨â ¥âáï 0x60;
¥á«¨ ­¥ ­ ¦ â  ­¨ ®¤­  ¨§ ã¯à ¢«ïîé¨å ª« ¢¨è, â® ¨á¯®«ì§ã¥âáï
­®à¬ «ì­ ï à áª« ¤ª .
* ®«ãç¨âì à áª« ¤ª¨ ¨ ¨¤¥­â¨ä¨ª â®à áâà ­ë ¬®¦­® á ¯®¬®éìî
¯®¤ä㭪樨 2 ä㭪樨 26.
* ˆ¤¥­â¨ä¨ª â®à áâà ­ë - £«®¡ «ì­ ï á¨á⥬­ ï ¯¥à¥¬¥­­ ï, ª®â®à ï
á ¬¨¬ ï¤à®¬ ­¥ ¨á¯®«ì§ã¥âáï; ®¤­ ª® ¯à¨«®¦¥­¨¥ @panel ®â®¡à ¦ ¥â
ᮮ⢥âáâ¢ãîéãî ⥪ã饩 áâà ­¥ ¨ª®­ªã.
* à¨«®¦¥­¨¥ @panel ¯¥à¥ª«îç ¥â à áª« ¤ª¨ ¯® § ¯à®áã ¯®«ì§®¢ â¥«ï.
 
======================================================================
=========== ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 3 - ãáâ ­®¢¨âì ¡ §ã CD. ===========
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 3 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¡ §  CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0
‡ ¬¥ç ­¨ï:
*  §  CD ¨á¯®«ì§ã¥âáï ä㭪樥© 24.
* ®«ãç¨âì ãáâ ­®¢«¥­­ãî ¡ §ã CD ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 3 ä㭪樨 26.
 
======================================================================
========= ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 5 - ãáâ ­®¢¨âì ï§ëª á¨á⥬ë. ========
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ï§ëª á¨á⥬ë (1=eng, 2=fi, 3=ger, 4=rus)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0
‡ ¬¥ç ­¨ï:
* Ÿ§ëª á¨á⥬ë - £«®¡ «ì­ ï á¨á⥬­ ï ¯¥à¥¬¥­­ ï, ­¨ª ª
­¥ ¨á¯®«ì§ã¥¬ ï á ¬¨¬ ï¤à®¬, ®¤­ ª® ¯à¨«®¦¥­¨¥ @panel à¨áã¥â
ᮮ⢥âáâ¢ãîéãî ¨ª®­ªã.
* à®¢¥à®ª ­  ª®à४⭮áâì ­¥ ¤¥« ¥âáï, ¯®áª®«ìªã ï¤à® íâã
¯¥à¥¬¥­­ãî ­¥ ¨á¯®«ì§ã¥â.
* ®«ãç¨âì ï§ëª á¨áâ¥¬ë ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 5 ä㭪樨 26.
 
======================================================================
=========== ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 7 - ãáâ ­®¢¨âì ¡ §ã HD. ===========
======================================================================
 §  HD ­ã¦­  ¤«ï ®¯à¥¤¥«¥­¨ï, ­  ª ª®© ¦ñá⪨© ¤¨áª ¯¨á âì, ¯à¨
¨á¯®«ì§®¢ ­¨¨ ãáâ à¥¢è¥£® ᨭ⠪á¨á  /HD ¢ ãáâ à¥¢è¥© ä㭪樨 58;
¯à¨ ¨á¯®«ì§®¢ ­¨¨ ᮢ६¥­­®£® ᨭ⠪á¨á  /HD0,/HD1,/HD2,/HD3
¡ §  ãáâ ­ ¢«¨¢ ¥âáï  ¢â®¬ â¨ç¥áª¨.
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 7 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¡ §  HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0
‡ ¬¥ç ­¨ï:
* ‹î¡®¥ ¯à¨«®¦¥­¨¥ ¢ «î¡®© ¬®¬¥­â ¢à¥¬¥­¨ ¬®¦¥â ¨§¬¥­¨âì ¡ §ã.
* ¥ á«¥¤ã¥â ¨§¬¥­ïâì ¡ §ã, ª®£¤  ª ª®¥-­¨¡ã¤ì ¯à¨«®¦¥­¨¥ à ¡®â ¥â
á ¦ñá⪨¬ ¤¨áª®¬. …᫨ ­¥ å®â¨â¥ £«îª®¢ á¨á⥬ë.
* ®«ãç¨âì ãáâ ­®¢«¥­­ãî ¡ §ã ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 7 ä㭪樨 26.
* ‘«¥¤ã¥â â ª¦¥ ®¯à¥¤¥«¨âì ¨á¯®«ì§ã¥¬ë© à §¤¥« ¦ñá⪮£® ¤¨áª 
¯®¤ä㭪樥© 8.
 
======================================================================
========== ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 8 - ãáâ ­®¢¨âì à §¤¥« HD. ==========
======================================================================
 §¤¥« HD ­ã¦¥­ ¤«ï ®¯à¥¤¥«¥­¨ï, ­  ª ª®© à §¤¥« ¦ñá⪮£® ¤¨áª 
¯¨á âì, ¯à¨ ¨á¯®«ì§®¢ ­¨¨ ãáâ à¥¢è¥£® ᨭ⠪á¨á  /HD ¢ ãáâ à¥¢è¥©
ä㭪樨 58; ¯à¨ ¨á¯®«ì§®¢ ­¨¨ ᮢ६¥­­®£® ᨭ⠪á¨á 
/HD0,/HD1,/HD2,/HD3 ¡ §  ¨ à §¤¥« ãáâ ­ ¢«¨¢ îâáï  ¢â®¬ â¨ç¥áª¨.
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 8 - ­®¬¥à ¯®¤ä㭪樨
* ecx = à §¤¥« HD (áç¨â ï á 1)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0
‡ ¬¥ç ­¨ï:
* ‹î¡®¥ ¯à¨«®¦¥­¨¥ ¢ «î¡®© ¬®¬¥­â ¢à¥¬¥­¨ ¬®¦¥â ¨§¬¥­¨âì à §¤¥«.
* ¥ á«¥¤ã¥â ¨§¬¥­ïâì à §¤¥«, ª®£¤  ª ª®¥-­¨¡ã¤ì ¯à¨«®¦¥­¨¥ à ¡®â ¥â
á ¦ñá⪨¬ ¤¨áª®¬. …᫨ ­¥ å®â¨â¥ £«îª®¢ á¨á⥬ë.
* ®«ãç¨âì ãáâ ­®¢«¥­­ë© à §¤¥« ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 8
ä㭪樨 26.
* à®¢¥à®ª ­  ª®à४⭮áâì ­¥ ¤¥« ¥âáï.
* “§­ âì ç¨á«® à §¤¥«®¢ ­  ¦ñá⪮¬ ¤¨áª¥ ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 11 ä㭪樨 18.
* ‘«¥¤ã¥â â ª¦¥ ®¯à¥¤¥«¨âì ¨á¯®«ì§ã¥¬ãî ¡ §ã ¦ñá⪮£® ¤¨áª 
¯®¤ä㭪樥© 7.
 
======================================================================
====================== ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 11 =====================
===========  §à¥è¨âì/§ ¯à¥â¨âì ­¨§ª®ã஢­¥¢ë© ¤®áâ㯠ª HD. ==========
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 11 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 0/1 - § ¯à¥â¨âì/à §à¥è¨âì
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0
‡ ¬¥ç ­¨ï:
* ˆá¯®«ì§ã¥âáï ¯à¨ LBA-ç⥭¨¨ (¯®¤äã­ªæ¨ï 8 ä㭪樨 58).
* ’¥ªãé ï ॠ«¨§ æ¨ï ¨á¯®«ì§ã¥â ⮫쪮 ¬« ¤è¨© ¡¨â ecx.
* ®«ãç¨âì ⥪ã饥 á®áâ®ï­¨¥ ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 11 ä㭪樨 26.
 
======================================================================
====================== ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 12 =====================
==========  §à¥è¨âì/§ ¯à¥â¨âì ­¨§ª®ã஢­¥¢ë© ¤®áâ㯠ª PCI. ==========
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 12 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 0/1 - § ¯à¥â¨âì/à §à¥è¨âì
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0
‡ ¬¥ç ­¨ï:
* ˆá¯®«ì§ã¥âáï ¯à¨ à ¡®â¥ á 設®© PCI (äã­ªæ¨ï 62).
* ’¥ªãé ï ॠ«¨§ æ¨ï ¨á¯®«ì§ã¥â ⮫쪮 ¬« ¤è¨© ¡¨â ecx.
* ®«ãç¨âì ⥪ã饥 á®áâ®ï­¨¥ ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 12 ä㭪樨 26.
 
======================================================================
============= ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 13, ¯®¤¯®¤äã­ªæ¨ï 1 =============
==== ˆ­¨æ¨ «¨§¨à®¢ âì + ¯®«ãç¨âì ¨­ä®à¬ æ¨î ® ¤à ©¢¥à¥ vmode.mdr. ====
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 13 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 1 - ­®¬¥à ä㭪樨 ¤à ©¢¥à 
* edx = 㪠§ â¥«ì ­  ¡ãä¥à à §¬¥à  512 ¡ ©â
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¥á«¨ ¤à ©¢¥à ­¥ § £à㦥­ (­¨ª®£¤  ­¥ ¡ë¢ ¥â ¢ ⥪ã饩 ॠ«¨§ æ¨¨):
* eax = -1
* ebx, ecx à §àãè îâáï
* ¥á«¨ ¤à ©¢¥à § £à㦥­:
* eax = 'MDAZ' (¢ á⨫¥ fasm' , â.¥. 'M' - ¬« ¤è¨© ¡ ©â,
'Z' - áâ à訩) - ᨣ­ âãà 
* ebx = ⥪ãé ï ç áâ®â  à §¢ñà⪨ (¢ ƒæ)
* ecx à §àãè ¥âáï
* ¡ãä¥à, ­  ª®â®àë© ãª §ë¢ ¥â edx, § ¯®«­¥­
”®à¬ â ¡ãä¥à :
* +0: 32*byte: ¨¬ï ¤à ©¢¥à , "Trans VideoDriver" (¡¥§ ª ¢ë祪,
¤®¯®«­¥­® ¯à®¡¥« ¬¨)
* +32 = +0x20: dword: ¢¥àá¨ï ¤à ©¢¥à  (¢¥àá¨ï x.y ª®¤¨àã¥âáï ª ª
y*65536+x), ¤«ï ⥪ã饩 ॠ«¨§ æ¨¨ 1 (1.0)
* +36 = +0x24: 7*dword: § à¥§¥à¢¨à®¢ ­® (0 ¢ ⥪ã饩 ॠ«¨§ æ¨¨)
* +64 = +0x40: 32*word: ᯨ᮪ ¯®¤¤¥à¦¨¢ ¥¬ëå ¢¨¤¥®à¥¦¨¬®¢ (ª ¦¤®¥
á«®¢® - ­®¬¥à ¢¨¤¥®à¥¦¨¬ , ¯®á«¥ ᮡá⢥­­® ᯨ᪠ ¨¤ã⠭㫨)
* +128 = +0x80: 32*(5*word): ᯨ᮪ ¯®¤¤¥à¦¨¢ ¥¬ëå ç áâ®â à §¢ñà⮪
¤«ï ¢¨¤¥®à¥¦¨¬®¢: ¤«ï ª ¦¤®£® ¢¨¤¥®à¥¦¨¬ , 㪠§ ­­®£® ¢ ¯à¥¤ë¤ã饬
¯®«¥, 㪠§ ­® ¤® 5 ¯®¤¤¥à¦¨¢ ¥¬ëå ç áâ®â
(¢ ­¥¨á¯®«ì§ã¥¬ëå ¯®§¨æ¨ïå § ¯¨á ­ë ­ã«¨)
‡ ¬¥ç ­¨ï:
* ”ã­ªæ¨ï ¨­¨æ¨ «¨§¨àã¥â ¤à ©¢¥à (¥á«¨ ®­ ¥éñ ­¥ ¨­¨æ¨ «¨§¨à®¢ ­)
¨ ¤®«¦­  ¢ë§ë¢ âìáï ¯¥à¢®©, ¯¥à¥¤ ®áâ «ì­ë¬¨ (¨­ ç¥ ®­¨ ¡ã¤ãâ
¢®§¢à é âì -1, ­¨ç¥£® ­¥ ¤¥« ï).
* ‚ ⥪ã饩 ॠ«¨§ æ¨¨ ¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 ®¤­  ç áâ®â  à §¢ñà⪨
­  ¢¨¤¥®à¥¦¨¬.
 
======================================================================
============= ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 13, ¯®¤¯®¤äã­ªæ¨ï 2 =============
============= ®«ãç¨âì ¨­ä®à¬ æ¨î ® ⥪ã饬 ¢¨¤¥®à¥¦¨¬¥. =============
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 13 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 2 - ­®¬¥à ä㭪樨 ¤à ©¢¥à 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ¤à ©¢¥à ­¥ § £à㦥­ ¨«¨ ­¥ ¨­¨æ¨ «¨§¨à®¢ ­;
ebx,ecx à §àãè îâáï
* eax = [è¨à¨­ ]*65536 + [¢ëá®â ]
* ebx = ç áâ®â  ¢¥à⨪ «ì­®© à §¢ñà⪨ (¢ ƒæ)
* ecx = ­®¬¥à ⥪ã饣® ¢¨¤¥®à¥¦¨¬ 
‡ ¬¥ç ­¨ï:
* „à ©¢¥à ¯à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì ¨­¨æ¨ «¨§¨à®¢ ­ ¢ë§®¢®¬
ä㭪樨 ¤à ©¢¥à  1.
* …᫨ ­ã¦­ë ⮫쪮 à §¬¥àë íªà ­ , 楫¥á®®¡à §­¥© ¨á¯®«ì§®¢ âì
äã­ªæ¨î 14 á ãçñ⮬ ⮣®, çâ® ®­  ¢®§¢à é ¥â à §¬¥àë ­  1 ¬¥­ìè¥.
 
======================================================================
= ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 13, ¯®¤¯®¤äã­ªæ¨ï 3 - ãáâ ­®¢¨âì ¢¨¤¥®à¥¦¨¬.
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 13 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 3 - ­®¬¥à ä㭪樨 ¤à ©¢¥à 
* edx = [ç áâ®â  à §¢ñà⪨]*65536 + [­®¬¥à ¢¨¤¥®à¥¦¨¬ ]
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ¤à ©¢¥à ­¥ § £à㦥­, ­¥ ¨­¨æ¨ «¨§¨à®¢ ­ ¨«¨
¯à®¨§®è«  ®è¨¡ª 
* eax = 0 - ãᯥ譮
* ebx, ecx à §àãè îâáï
‡ ¬¥ç ­¨ï:
* „à ©¢¥à ¯à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì ¨­¨æ¨ «¨§¨à®¢ ­ ¢ë§®¢®¬
ä㭪樨 ¤à ©¢¥à  1.
* ®¬¥à ¢¨¤¥®à¥¦¨¬  ¨ ç áâ®â  ¤®«¦­ë ¡ëâì ¢ â ¡«¨æ¥, ¢®§¢à é ¥¬®©
ä㭪樥© ¤à ©¢¥à  1.
 
======================================================================
============= ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 13, ¯®¤¯®¤äã­ªæ¨ï 4 =============
================= ‚¥à­ãâìáï ª ­ ç «ì­®¬ã ¢¨¤¥®à¥¦¨¬ã. ================
======================================================================
‚®§¢à é ¥â íªà ­ ¢ ¢¨¤¥®à¥¦¨¬, ãáâ ­®¢«¥­­ë© ¯à¨ § £à㧪¥ á¨á⥬ë.
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 13 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 4 - ­®¬¥à ä㭪樨 ¤à ©¢¥à 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ¤à ©¢¥à ­¥ § £à㦥­ ¨«¨ ­¥ ¨­¨æ¨ «¨§¨à®¢ ­
* eax = 0 - ãᯥ譮
* ebx, ecx à §àãè îâáï
‡ ¬¥ç ­¨ï:
* „à ©¢¥à ¯à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì ¨­¨æ¨ «¨§¨à®¢ ­ ¢ë§®¢®¬
ä㭪樨 ¤à ©¢¥à  1.
 
======================================================================
============= ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 13, ¯®¤¯®¤äã­ªæ¨ï 5 =============
======== “¢¥«¨ç¨âì/㬥­ìè¨âì à §¬¥à ¢¨¤¨¬®© ®¡« á⨠¬®­¨â®à . ========
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 13 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 5 - ­®¬¥à ä㭪樨 ¤à ©¢¥à 
* edx = 0/1 - 㬥­ìè¨âì/㢥«¨ç¨âì à §¬¥à ¯® £®à¨§®­â «¨
­  ®¤­ã ¯®§¨æ¨î
* edx = 2/3 - ¢ ⥪ã饩 ॠ«¨§ æ¨¨ ­¥ ¯®¤¤¥à¦¨¢ ¥âáï; ¯« ­¨àã¥âáï
ª ª 㬥­ì襭¨¥/㢥«¨ç¥­¨¥ à §¬¥à  ¯® ¢¥à⨪ «¨ ­  ®¤­ã ¯®§¨æ¨î
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ¤à ©¢¥à ­¥ § £à㦥­ ¨«¨ ­¥ ¨­¨æ¨ «¨§¨à®¢ ­
* eax = 0 - ãᯥ譮
* ebx, ecx à §àãè îâáï
‡ ¬¥ç ­¨ï:
* „à ©¢¥à ¯à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì ¨­¨æ¨ «¨§¨à®¢ ­ ¢ë§®¢®¬
ä㭪樨 ¤à ©¢¥à  1.
* ”ã­ªæ¨ï ¢«¨ï¥â ⮫쪮 ­  䨧¨ç¥áª¨© à §¬¥à ¨§®¡à ¦¥­¨ï
­  ¬®­¨â®à¥; «®£¨ç¥áª¨© à §¬¥à (ç¨á«® ¯¨ªá¥«¥©) ­¥ ¬¥­ï¥âáï.
 
======================================================================
============ ”ã­ªæ¨ï 22 - ãáâ ­®¢¨âì á¨á⥬­ãî ¤ âã/¢à¥¬ï. ===========
======================================================================
 à ¬¥âàë:
* eax = 22 - ­®¬¥à ä㭪樨
* ebx = 0 - ãáâ ­®¢¨âì ¢à¥¬ï
* ecx = 0x00SSMMHH - ¢à¥¬ï ¢ ¤¢®¨ç­®-¤¥áïâ¨ç­®¬ ª®¤¥ (BCD):
* HH=ç á 00..23
* MM=¬¨­ãâ  00..59
* SS=ᥪ㭤  00..59
* ebx = 1 - ãáâ ­®¢¨âì ¤ âã
* ecx = 0x00DDMMYY - ¤ â  ¢ ¤¢®¨ç­®-¤¥áïâ¨ç­®¬ ª®¤¥ (BCD):
* DD=¤¥­ì 01..31
* MM=¬¥áïæ 01..12
* YY=£®¤ 00..99
* ebx = 2 - ãáâ ­®¢¨âì ¤¥­ì ­¥¤¥«¨
* ecx = 1 ¤«ï ¢®áªà¥á¥­ìï, ..., 7 ¤«ï áã¡¡®âë
* ebx = 3 - ãáâ ­®¢¨âì ¡ã¤¨«ì­¨ª
* ecx = 0x00SSMMHH
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ¯ à ¬¥âà § ¤ ­ ­¥¢¥à­®
* eax = 2 - CMOS-¡ â à¥©ª¨ à §à廊«¨áì
‡ ¬¥ç ­¨ï:
* –¥­­®áâì ãáâ ­®¢ª¨ ¤­ï ­¥¤¥«¨ ¯à¥¤áâ ¢«ï¥âáï ᮬ­¨â¥«ì­®©,
¯®áª®«ìªã ®­ ¬ «® £¤¥ ¨á¯®«ì§ã¥âáï
(¤¥­ì ­¥¤¥«¨ ¬®¦­® à ááç¨â âì ¯® ¤ â¥).
* ã¤¨«ì­¨ª ¬®¦­® ãáâ ­®¢¨âì ­  áà ¡ â뢠­¨¥ ¢ § ¤ ­­®¥ ¢à¥¬ï
ª ¦¤ë¥ áã⪨. à¨ í⮬ ®âª«îç¨âì ¥£® áãé¥áâ¢ãî騬¨ á¨á⥬­ë¬¨
äã­ªæ¨ï¬¨ ­¥«ì§ï.
* ‘à ¡ â뢠­¨¥ ¡ã¤¨«ì­¨ª  § ª«îç ¥âáï ¢ £¥­¥à æ¨¨ IRQ8.
* ‚®®¡é¥-â® CMOS ¯®¤¤¥à¦¨¢ ¥â ¤«ï ¡ã¤¨«ì­¨ª  ãáâ ­®¢ªã §­ ç¥­¨ï
0xFF ¢ ª ç¥á⢥ ®¤­®£® ¨§ ¯ à ¬¥â஢ ¨ ®§­ ç ¥â íâ®, çâ®
ᮮ⢥âáâ¢ãî騩 ¯ à ¬¥âà ¨£­®à¨àã¥âáï. ® ¢ ⥪ã饩 ॠ«¨§ æ¨¨
íâ® ­¥ ¯à®©¤ñâ (¢¥à­ñâáï §­ ç¥­¨¥ 1).
* ã¤¨«ì­¨ª - £«®¡ «ì­ë© á¨á⥬­ë© à¥áãàá; ãáâ ­®¢ª  ¡ã¤¨«ì­¨ª 
 ¢â®¬ â¨ç¥áª¨ ®â¬¥­ï¥â ¯à¥¤ë¤ãéãî ãáâ ­®¢ªã. ‚¯à®ç¥¬, ­  ¤ ­­ë©
¬®¬¥­â ­¨ ®¤­  ¯à®£à ¬¬  ¥£® ­¥ ¨á¯®«ì§ã¥â.
 
======================================================================
============== ”ã­ªæ¨ï 23 - ®¦¨¤ âì ᮡëâ¨ï á â ©¬ ã⮬. =============
======================================================================
…᫨ ®ç¥à¥¤ì á®®¡é¥­¨© ¯ãáâ , ¦¤ñâ ¯®ï¢«¥­¨ï á®®¡é¥­¨ï ¢ ®ç¥à¥¤¨,
­® ­¥ ¡®«¥¥ 㪠§ ­­®£® ¢à¥¬¥­¨. ‡ â¥¬ áç¨â뢠¥â á®®¡é¥­¨¥ ¨§ ®ç¥à¥¤¨.
 
 à ¬¥âàë:
* eax = 23 - ­®¬¥à ä㭪樨
* ebx = â ©¬ ãâ (¢ á®âëå ¤®«ïå ᥪ㭤ë)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ®ç¥à¥¤ì á®®¡é¥­¨© ¯ãáâ 
* ¨­ ç¥ eax = ᮡë⨥ (ᬮâਠᯨ᮪ ᮡë⨩)
‡ ¬¥ç ­¨ï:
* “ç¨â뢠îâáï ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã,
ãáâ ­ ¢«¨¢ ¥¬ãî ä㭪樥© 40. ® 㬮«ç ­¨î í⮠ᮡëâ¨ï
¯¥à¥à¨á®¢ª¨, ­ ¦ â¨ï ­  ª« ¢¨è¨ ¨ ­  ª­®¯ª¨.
* „«ï ¯à®¢¥àª¨, ¥áâì «¨ á®®¡é¥­¨¥ ¢ ®ç¥à¥¤¨, ¨á¯®«ì§ã©â¥ äã­ªæ¨î 11.
—â®¡ë ¦¤ âì ᪮«ì 㣮¤­® ¤®«£®, ¨á¯®«ì§ã©â¥ äã­ªæ¨î 10.
* ¥à¥¤ ç  ebx=0 ¯à¨¢®¤¨â ª ¬®¬¥­â «ì­®¬ã ¢®§¢à é¥­¨î eax=0.
* à¨ ⥪ã饩 ॠ«¨§ æ¨¨ ¯à®¨§®©¤ñâ ­¥¬¥¤«¥­­ë© ¢®§¢à â ¨§ ä㭪樨
á eax=0, ¥á«¨ á«®¦¥­¨¥ ebx á ⥪ã騬 §­ ç¥­¨¥¬ áçñâ稪  ¢à¥¬¥­¨
¢ë§®¢¥â 32-¡¨â­®¥ ¯¥à¥¯®«­¥­¨¥.
 
======================================================================
======= ”ã­ªæ¨ï 24, ¯®¤äã­ªæ¨ï 1 - ­ ç âì ¯à®¨£à뢠âì CD-audio. ======
======================================================================
 à ¬¥âàë:
* eax = 24 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 0x00FRSSMM, £¤¥
* MM = ­ ç «ì­ ï ¬¨­ãâ 
* SS = ­ ç «ì­ ï ᥪ㭤 
* FR = ­ ç «ì­ë© ä३¬
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ­¥ ®¯à¥¤¥«¥­  ¡ §  CD
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ­ã¦­® ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ CD ¢ë§®¢®¬
¯®¤ä㭪樨 3 ä㭪樨 21.
* ‚ ᥪ㭤¥ 75 ä३¬®¢, ¢ ¬¨­ã⥠60 ᥪ㭤.
* ”ã­ªæ¨ï  á¨­åà®­­  (¢®§¢à é ¥â ã¯à ¢«¥­¨¥, ª®£¤  ­ ç «®áì
¯à®¨£à뢠­¨¥).
 
======================================================================
===== ”ã­ªæ¨ï 24, ¯®¤äã­ªæ¨ï 2 - ¯®«ãç¨âì ¨­ä®à¬ æ¨î ® ¤®à®¦ª å. =====
======================================================================
 à ¬¥âàë:
* eax = 24 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¡ãä¥à ¤«ï â ¡«¨æë
(¬ ªá¨¬ã¬ 8*64h+4 ¡ ©â=100 ¤®à®¦¥ª)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ­¥ ®¯à¥¤¥«¥­  ¡ §  CD
‡ ¬¥ç ­¨ï:
* ”®à¬ â â ¡«¨æë á ¨­ä®à¬ æ¨¥© ® ¤®à®¦ª å â ª®© ¦¥, ª ª ¨ ¤«ï
ATAPI-CD ª®¬ ­¤ë 43h (READ TOC), ®¡ëç­®© â ¡«¨æë (¯®¤ª®¬ ­¤  00h).
€¤à¥á  ¢®§¢à é îâáï ¢ ä®à¬ â¥ MSF.
* à¥¤¢ à¨â¥«ì­® ­ã¦­® ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ CD ¢ë§®¢®¬
¯®¤ä㭪樨 3 ä㭪樨 21.
* ”ã­ªæ¨ï ¢®§¢à é ¥â ¨­ä®à¬ æ¨î ⮫쪮 ® ­¥ ¡®«¥¥ 祬 100
¯¥à¢ëå ¤®à®¦ª å. ‚ ¡®«ì設á⢥ á«ãç ¥¢ í⮣® ¤®áâ â®ç­®.
 
======================================================================
==== ”ã­ªæ¨ï 24, ¯®¤äã­ªæ¨ï 3 - ®áâ ­®¢¨âì ¯à®¨£à뢠¥¬®¥ CD-audio. ===
======================================================================
 à ¬¥âàë:
* eax = 24 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ­¥ ®¯à¥¤¥«¥­  ¡ §  CD
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ­ã¦­® ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ CD ¢ë§®¢®¬
¯®¤ä㭪樨 3 ä㭪樨 21.
 
======================================================================
======= ”ã­ªæ¨ï 24, ¯®¤äã­ªæ¨ï 4 - ¨§¢«¥çì «®â®ª ¯à¨¢®¤  ¤¨áª . ======
======================================================================
 à ¬¥âàë:
* eax = 24 - ­®¬¥à ä㭪樨
* ebx = 4 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­®¬¥à CD/DVD-¤¨áª 
(®â 0=Primary Master ¤® 3=Secondary Slave)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ”ã­ªæ¨ï ¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 ¤«ï ATAPI-ãáâனá⢠(CD ¨ DVD).
* à¨ ¨§¢«¥ç¥­¨¨ «®âª  ¯à®¨§¢®¤¨âáï à §¡«®ª¨à®¢ª  àãç­®£® ã¯à ¢«¥­¨ï
¬¥å ­¨§¬®¬ «®âª .
* à¨ ¨§¢«¥ç¥­¨¨ «®âª  ª®¤ ¯à®¨§¢®¤¨â ®ç¨áâªã ªíè  á®®â¢¥âáâ¢ãî饣®
ãáâனá⢠.
* à¨¬¥à®¬ ¨á¯®«ì§®¢ ­¨ï ä㭪樨 ï¥âáï ¯à¨«®¦¥­¨¥ CD_tray.
 
======================================================================
====== ”ã­ªæ¨ï 24, ¯®¤äã­ªæ¨ï 5 - § £à㧨âì «®â®ª ¯à¨¢®¤  ¤¨áª . =====
======================================================================
 à ¬¥âàë:
* eax = 24 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­®¬¥à CD/DVD-¤¨áª 
(®â 0=Primary Master ¤® 3=Secondary Slave)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ”ã­ªæ¨ï ¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 ¤«ï ATAPI-ãáâனá⢠(CD ¨ DVD).
* à¨¬¥à®¬ ¨á¯®«ì§®¢ ­¨ï ä㭪樨 ï¥âáï ¯à¨«®¦¥­¨¥ CD_tray.
 
======================================================================
===== ”ã­ªæ¨ï 26, ¯®¤äã­ªæ¨ï 1 - ¯®«ãç¨âì ¡ §®¢ë© ¯®àâ MPU MIDI. =====
======================================================================
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ­®¬¥à ¯®àâ 
‡ ¬¥ç ­¨ï:
* “áâ ­®¢¨âì ¡ §®¢ë© ¯®àâ ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 1 ä㭪樨 21.
 
======================================================================
====== ”ã­ªæ¨ï 26, ¯®¤äã­ªæ¨ï 2 - ¯®«ãç¨âì à áª« ¤ªã ª« ¢¨ âãàë. =====
======================================================================
 áª« ¤ª  ª« ¢¨ âãàë ¨á¯®«ì§ã¥âáï ¤«ï ¯à¥®¡à §®¢ ­¨ï ᪠­ª®¤®¢,
¯®áâ㯠îé¨å ®â ª« ¢¨ âãàë, ¢ ASCII-ª®¤ë, áç¨â뢠¥¬ë¥ ä㭪樥© 2.
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ª ªãî à áª« ¤ªã ¯®«ãç âì:
* 1 = ­®à¬ «ì­ãî
* 2 = à áª« ¤ªã ¯à¨ ­ ¦ â®¬ Shift
* 3 = à áª« ¤ªã ¯à¨ ­ ¦ â®¬ Alt
* edx = 㪠§ â¥«ì ­  ¡ãä¥à ¤«¨­®© 128 ¡ ©â, ªã¤  ¡ã¤¥â ᪮¯¨à®¢ ­ 
à áª« ¤ª 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
ˆ«¨:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 9
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ¨¤¥­â¨ä¨ª â®à áâà ­ë (1=eng, 2=fi, 3=ger, 4=rus)
‡ ¬¥ç ­¨ï:
* …᫨ ­ ¦ â Alt, â® ¨á¯®«ì§ã¥âáï à áª« ¤ª  á Alt;
¥á«¨ ­¥ ­ ¦ â Alt, ­® ­ ¦ â Shift, â® ¨á¯®«ì§ã¥âáï
à áª« ¤ª  á Shift;
¥á«¨ ­¥ ­ ¦ âë Alt ¨ Shift, ­® ­ ¦ â Ctrl, â® ¨á¯®«ì§ã¥âáï
­®à¬ «ì­ ï à áª« ¤ª , ¯®á«¥ 祣® ¨§ ª®¤  ¢ëç¨â ¥âáï 0x60;
¥á«¨ ­¥ ­ ¦ â  ­¨ ®¤­  ¨§ ã¯à ¢«ïîé¨å ª« ¢¨è, â® ¨á¯®«ì§ã¥âáï
­®à¬ «ì­ ï à áª« ¤ª .
* “áâ ­®¢¨âì à áª« ¤ª¨ ¨ ¨¤¥­â¨ä¨ª â®à áâà ­ë ¬®¦­® á ¯®¬®éìî
¯®¤ä㭪樨 2 ä㭪樨 21.
* ˆ¤¥­â¨ä¨ª â®à áâà ­ë - £«®¡ «ì­ ï á¨á⥬­ ï ¯¥à¥¬¥­­ ï, ª®â®à ï
á ¬¨¬ ï¤à®¬ ­¥ ¨á¯®«ì§ã¥âáï; ®¤­ ª® ¯à¨«®¦¥­¨¥ @panel ®â®¡à ¦ ¥â
ᮮ⢥âáâ¢ãîéãî ⥪ã饩 áâà ­¥ ¨ª®­ªã
(¨á¯®«ì§ãï ®¯¨á뢠¥¬ãî äã­ªæ¨î).
* à¨«®¦¥­¨¥ @panel ¯¥à¥ª«îç ¥â à áª« ¤ª¨ ¯® § ¯à®áã ¯®«ì§®¢ â¥«ï.
 
======================================================================
============ ”ã­ªæ¨ï 26, ¯®¤äã­ªæ¨ï 3 - ¯®«ãç¨âì ¡ §ã CD. ============
======================================================================
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 3 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ¡ §  CD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
‡ ¬¥ç ­¨ï:
*  §  CD ¨á¯®«ì§ã¥âáï ä㭪樥© 24.
* “áâ ­®¢¨âì ¡ §ã CD ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 3 ä㭪樨 21.
 
======================================================================
========== ”ã­ªæ¨ï 26, ¯®¤äã­ªæ¨ï 5 - ¯®«ãç¨âì ï§ëª á¨á⥬ë. =========
======================================================================
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ï§ëª á¨á⥬ë (1=eng, 2=fi, 3=ger, 4=rus)
‡ ¬¥ç ­¨ï:
* Ÿ§ëª á¨á⥬ë - £«®¡ «ì­ ï á¨á⥬­ ï ¯¥à¥¬¥­­ ï, ­¨ª ª
­¥ ¨á¯®«ì§ã¥¬ ï á ¬¨¬ ï¤à®¬, ®¤­ ª® ¯à¨«®¦¥­¨¥ @panel à¨áã¥â
ᮮ⢥âáâ¢ãîéãî ¨ª®­ªã (¨á¯®«ì§ãï ®¯¨á뢠¥¬ãî äã­ªæ¨î).
* “áâ ­®¢¨âì ï§ëª á¨áâ¥¬ë ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 5 ä㭪樨 21.
 
======================================================================
============ ”ã­ªæ¨ï 26, ¯®¤äã­ªæ¨ï 7 - ¯®«ãç¨âì ¡ §ã HD. ============
======================================================================
 §  HD ­ã¦­  ¤«ï ®¯à¥¤¥«¥­¨ï, ­  ª ª®© ¦ñá⪨© ¤¨áª ¯¨á âì, ¯à¨
¨á¯®«ì§®¢ ­¨¨ ãáâ à¥¢è¥£® ᨭ⠪á¨á  /HD ¢ ãáâ à¥¢è¥© ä㭪樨 58;
¯à¨ ¨á¯®«ì§®¢ ­¨¨ ᮢ६¥­­®£® ᨭ⠪á¨á  /HD0,/HD1,/HD2,/HD3
¡ §  ãáâ ­ ¢«¨¢ ¥âáï  ¢â®¬ â¨ç¥áª¨.
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 7 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ¡ §  HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
‡ ¬¥ç ­¨ï:
* ‹î¡®¥ ¯à¨«®¦¥­¨¥ ¢ «î¡®© ¬®¬¥­â ¢à¥¬¥­¨ ¬®¦¥â ¨§¬¥­¨âì ¡ §ã.
* “áâ ­®¢¨âì ¡ §ã ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 7 ä㭪樨 21.
* ®«ãç¨âì ¨á¯®«ì§ã¥¬ë© à §¤¥« ¦ñá⪮£® ¤¨áª  ¬®¦­® ¯®¤ä㭪樥© 8.
 
======================================================================
=========== ”ã­ªæ¨ï 26, ¯®¤äã­ªæ¨ï 8 - ¯®«ãç¨âì à §¤¥« HD. ===========
======================================================================
 §¤¥« HD ­ã¦¥­ ¤«ï ®¯à¥¤¥«¥­¨ï, ­  ª ª®© à §¤¥« ¦ñá⪮£® ¤¨áª 
¯¨á âì, ¯à¨ ¨á¯®«ì§®¢ ­¨¨ ãáâ à¥¢è¥£® ᨭ⠪á¨á  /HD ¢ ãáâ à¥¢è¥©
ä㭪樨 58; ¯à¨ ¨á¯®«ì§®¢ ­¨¨ ᮢ६¥­­®£® ᨭ⠪á¨á 
/HD0,/HD1,/HD2,/HD3 ¡ §  ¨ à §¤¥« ãáâ ­ ¢«¨¢ îâáï  ¢â®¬ â¨ç¥áª¨.
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 8 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = à §¤¥« HD (áç¨â ï á 1)
‡ ¬¥ç ­¨ï:
* ‹î¡®¥ ¯à¨«®¦¥­¨¥ ¢ «î¡®© ¬®¬¥­â ¢à¥¬¥­¨ ¬®¦¥â ¨§¬¥­¨âì à §¤¥«.
* “áâ ­®¢¨âì à §¤¥« ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 8 ä㭪樨 21.
* “§­ âì ç¨á«® à §¤¥«®¢ ­  ¦ñá⪮¬ ¤¨áª¥ ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 11 ä㭪樨 18.
* ®«ãç¨âì ¨á¯®«ì§ã¥¬ãî ¡ §ã ¦ñá⪮£® ¤¨áª  ¬®¦­® ¯®¤ä㭪樥© 7.
 
======================================================================
=== ”ã­ªæ¨ï 26, ¯®¤äã­ªæ¨ï 9 - ¯®«ãç¨âì §­ ç¥­¨¥ áçñâ稪  ¢à¥¬¥­¨. ===
======================================================================
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 9 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ç¨á«® á®âëå ¤®«¥© ᥪ㭤ë, ¯à®è¥¤è¨å á ¬®¬¥­â 
§ ¯ã᪠ á¨á⥬ë
‡ ¬¥ç ­¨ï:
* ‘çñâ稪 ¡¥àñâáï ¯® ¬®¤ã«î 2^32, ç⮠ᮮ⢥âáâ¢ã¥â ­¥¬­®£¨¬ ¡®«¥¥
497 áã⮪.
* ‘¨á⥬­®¥ ¢à¥¬ï ¬®¦­® ¯®«ãç¨âì ä㭪樥© 3.
 
======================================================================
====================== ”ã­ªæ¨ï 26, ¯®¤äã­ªæ¨ï 11 =====================
=========== “§­ âì, à §à¥èñ­ «¨ ­¨§ª®ã஢­¥¢ë© ¤®áâ㯠ª HD. ==========
======================================================================
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 11 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0/1 - § ¯à¥éñ­/à §à¥èñ­
‡ ¬¥ç ­¨ï:
* ˆá¯®«ì§ã¥âáï ¯à¨ LBA-ç⥭¨¨ (¯®¤äã­ªæ¨ï 8 ä㭪樨 58).
* “áâ ­®¢¨âì ⥪ã饥 á®áâ®ï­¨¥ ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 11 ä㭪樨 21.
 
======================================================================
====================== ”ã­ªæ¨ï 26, ¯®¤äã­ªæ¨ï 12 =====================
========== “§­ âì, à §à¥èñ­ «¨ ­¨§ª®ã஢­¥¢ë© ¤®áâ㯠ª PCI. ==========
======================================================================
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 12 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0/1 - § ¯à¥éñ­/à §à¥èñ­
‡ ¬¥ç ­¨ï:
* ˆá¯®«ì§ã¥âáï ¯à¨ à ¡®â¥ á 設®© PCI (äã­ªæ¨ï 62).
* ’¥ªãé ï ॠ«¨§ æ¨ï ¨á¯®«ì§ã¥â ⮫쪮 ¬« ¤è¨© ¡¨â ecx.
* “áâ ­®¢¨âì ⥪ã饥 á®áâ®ï­¨¥ ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 12 ä㭪樨 21.
 
======================================================================
================ ”ã­ªæ¨ï 29 - ¯®«ãç¨âì á¨á⥬­ãî ¤ âã. ===============
======================================================================
 à ¬¥âàë:
* eax = 29 - ­®¬¥à ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0x00DDMMYY, £¤¥
(¨á¯®«ì§ã¥âáï ¤¢®¨ç­®-¤¥áïâ¨ç­®¥ ª®¤¨à®¢ ­¨¥, BCD)
* YY = ¤¢¥ ¬« ¤è¨¥ æ¨äàë £®¤  (00..99)
* MM = ¬¥áïæ (01..12)
* DD = ¤¥­ì (01..31)
‡ ¬¥ç ­¨ï:
* ‘¨á⥬­ãî ¤ âã ¬®¦­® ãáâ ­®¢¨âì ä㭪樥© 22.
 
======================================================================
================ ”ã­ªæ¨ï 30 - à ¡®â  á ⥪ã饩 ¯ ¯ª®©. ===============
======================================================================
 
-------- ®¤äã­ªæ¨ï 1 - ãáâ ­®¢¨âì ⥪ãéãî ¯ ¯ªã ¤«ï ¯®â®ª . ---------
 à ¬¥âàë:
* eax = 30 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¯ãâñ¬ ª ­®¢®© ⥪ã饩 ¯ ¯ª¥
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
--------- ®¤äã­ªæ¨ï 2 - ¯®«ãç¨âì ⥪ãéãî ¯ ¯ªã ¤«ï ¯®â®ª . ----------
 à ¬¥âàë:
* eax = 30 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¡ãä¥à
* edx = à §¬¥à ¡ãä¥à 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = - 1 ®é¨¡ª , ¯ ¯ª  ⥪ã饣® ¯®â®ª  ¨¬¥¥â ¤«¨­­ã ¡®«¥¥ 祬 4096 ᨬ¢®«®¢.
* eax = ¤«¨­  ¨¬¥­¨ ⥪ã饩 ¯ ¯ª¨ (¢ª«îç ï § ¢¥àè î騩 0)
‡ ¬¥ç ­¨ï:
* …᫨ à §¬¥à  ¡ãä¥à  ­¥¤®áâ â®ç­® ¤«ï ª®¯¨à®¢ ­¨ï ¢á¥£® ¨¬¥­¨,
ª®¯¨àãîâáï ⮫쪮 ¯¥à¢ë¥ (edx-1) ¡ ©â
¨ ¢ ª®­æ¥ áâ ¢¨âáï § ¢¥àè î騩 0.
 
======================================================================
================ ”ã­ªæ¨ï 32 - 㤠«¨âì ä ©« á à ¬¤¨áª . ===============
======================================================================
 à ¬¥âàë:
* eax = 32 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨¬ï ä ©« 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮; ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
‡ ¬¥ç ­¨ï:
* â  äã­ªæ¨ï ãáâ à¥« ; äã­ªæ¨ï 58 ¯®§¢®«ï¥â ¢ë¯®«­ïâì
⥠¦¥ ¤¥©á⢨ï á à áè¨à¥­­ë¬¨ ¢®§¬®¦­®áâﬨ.
* ’¥ªãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â ⮫쪮 §­ ç¥­¨ï 0(ãᯥå) ¨
5(ä ©« ­¥ ­ ©¤¥­).
* ˆ¬ï ä ©«  ¤®«¦­® ¡ëâì «¨¡® ¢ ä®à¬ â¥ 8+3 ᨬ¢®«®¢ (¯¥à¢ë¥
8 ᨬ¢®«®¢ - ᮡá⢥­­® ¨¬ï, ¯®á«¥¤­¨¥ 3 - à áè¨à¥­¨¥,
ª®à®âª¨¥ ¨¬¥­  ¨ à áè¨à¥­¨ï ¤®¯®«­ïîâáï ¯à®¡¥« ¬¨),
«¨¡® ¢ ä®à¬ â¥ 8.3 ᨬ¢®«®¢ "FILE.EXT"/"FILE.EX "
(¨¬ï ­¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥­¨¥ 3 ᨬ¢®« ,
¤®¯®«­¥­­®¥ ¯à¨ ­¥®¡å®¤¨¬®á⨠¯à®¡¥« ¬¨).
ˆ¬ï ä ©«  ¤®«¦­® ¡ëâì § ¯¨á ­® § £« ¢­ë¬¨ ¡ãª¢ ¬¨.
‡ ¢¥àè î騩 ᨬ¢®« á ª®¤®¬ 0 ­¥ ­ã¦¥­ (­¥ ASCIIZ-áâப ).
* â  äã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª ­  à ¬¤¨áª¥.
 
======================================================================
=============== ”ã­ªæ¨ï 33 - § ¯¨á âì ä ©« ­  à ¬¤¨áª. ===============
======================================================================
 à ¬¥âàë:
* eax = 33 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨¬ï ä ©« 
* ecx = 㪠§ â¥«ì ­  ¤ ­­ë¥ ¤«ï § ¯¨á¨
* edx = ç¨á«® ¡ ©â ¤«ï § ¯¨á¨
* á«¥¤ã¥â ãáâ ­ ¢«¨¢ âì esi=0
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
‡ ¬¥ç ­¨ï:
* â  äã­ªæ¨ï ãáâ à¥« ; äã­ªæ¨ï 70 ¯®§¢®«ï¥â ¢ë¯®«­ïâì
⥠¦¥ ¤¥©á⢨ï á à áè¨à¥­­ë¬¨ ¢®§¬®¦­®áâﬨ.
* …᫨ 㪠§ âì ­¥­ã«¥¢®¥ §­ ç¥­¨¥ ¢ esi ¨ ­  à ¬¤¨áª¥ 㦥 ¥áâì
㪠§ ­­ë© ä ©«, â® ¡ã¤¥â ᮧ¤ ­ ¥éñ ®¤¨­ ä ©« á ⥬ ¦¥ ¨¬¥­¥¬.
* ‚ ¯à®â¨¢­®¬ á«ãç ¥ ä ©« ¯¥à¥§ ¯¨á뢠¥âáï.
* ˆ¬ï ä ©«  ¤®«¦­® ¡ëâì «¨¡® ¢ ä®à¬ â¥ 8+3 ᨬ¢®«®¢
(¯¥à¢ë¥ 8 ᨬ¢®«®¢ - ᮡá⢥­­® ¨¬ï, ¯®á«¥¤­¨¥ 3 - à áè¨à¥­¨¥,
ª®à®âª¨¥ ¨¬¥­  ¨ à áè¨à¥­¨ï ¤®¯®«­ïîâáï ¯à®¡¥« ¬¨),
«¨¡® ¢ ä®à¬ â¥ 8.3 ᨬ¢®«®¢ "FILE.EXT"/"FILE.EX "
(¨¬ï ­¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥­¨¥ 3 ᨬ¢®« ,
¤®¯®«­¥­­®¥ ¯à¨ ­¥®¡å®¤¨¬®á⨠¯à®¡¥« ¬¨).
ˆ¬ï ä ©«  ¤®«¦­® ¡ëâì § ¯¨á ­® § £« ¢­ë¬¨ ¡ãª¢ ¬¨.
‡ ¢¥àè î騩 ᨬ¢®« á ª®¤®¬ 0 ­¥ ­ã¦¥­ (­¥ ASCIIZ-áâப ).
* â  äã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª ­  à ¬¤¨áª¥.
 
======================================================================
============ ”ã­ªæ¨ï 35 - ¯à®ç¨â âì 梥â â®çª¨ ­  íªà ­¥. ============
======================================================================
 à ¬¥âàë:
* eax = 35
* ebx = y*xsize+x, £¤¥
* (x,y) = ª®®à¤¨­ âë â®çª¨ (áç¨â ï ®â 0)
* xsize = à §¬¥à íªà ­  ¯® £®à¨§®­â «¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 梥â 0x00RRGGBB
‡ ¬¥ç ­¨ï:
* “§­ âì à §¬¥àë íªà ­  ¬®¦­® ¢ë§®¢®¬ ä㭪樨 14. Ž¡à â¨â¥ ¢­¨¬ ­¨¥,
çâ® ®­  ¢ëç¨â ¥â 1 ¨§ ®¡®¨å à §¬¥à®¢.
* Š ¢¨¤¥®¯ ¬ï⨠¥áâì â ª¦¥ ¯àאַ© ¤®áâ㯠(¡¥§ ¢ë§®¢®¢ á¨á⥬­ëå
ä㭪権) ç¥à¥§ ᥫ¥ªâ®à gs.  à ¬¥âàë ⥪ã饣® ¢¨¤¥®à¥¦¨¬ 
¬®¦­® ¯®«ãç¨âì ä㭪樥© 61.
 
======================================================================
=============== ”ã­ªæ¨ï 36 - ¯à®ç¨â âì ®¡« áâì íªà ­ . ===============
======================================================================
 à ¬¥âàë:
* eax = 36 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¯à¥¤¢ à¨â¥«ì­® ¢ë¤¥«¥­­ãî ®¡« áâì ¯ ¬ïâ¨,
ªã¤  ¡ã¤¥â ¯®¬¥é¥­® ¨§®¡à ¦¥­¨¥ ¢ ä®à¬ â¥ BBGGRRBBGGRR...
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y]
* edx = [ª®®à¤¨­ â  ¯® ®á¨ x]*65536 + [ª®®à¤¨­ â  ¯® ®á¨ y]
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* Š®®à¤¨­ âë ®¡« á⨠- íâ® ª®®à¤¨­ âë ¢¥àå­¥£® «¥¢®£® 㣫 
®¡« á⨠®â­®á¨â¥«ì­® íªà ­ .
*  §¬¥à ¨§®¡à ¦¥­¨ï ¢ ¡ ©â å ¥áâì 3*xsize*ysize.
 
======================================================================
==================== ”ã­ªæ¨ï 37 - à ¡®â  á ¬ëèìî. ====================
======================================================================
 
-------------- ®¤äã­ªæ¨ï 0 - íªà ­­ë¥ ª®®à¤¨­ âë ¬ëè¨ ---------------
 à ¬¥âàë:
* eax = 37 - ­®¬¥à ä㭪樨
* ebx = 0 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = x*65536 + y, (x,y)=ª®®à¤¨­ âë ªãàá®à  ¬ëè¨ (áç¨â ï ®â 0)
 
---------- ®¤äã­ªæ¨ï 1 - ª®®à¤¨­ âë ¬ëè¨ ®â­®á¨â¥«ì­® ®ª­  ----------
 à ¬¥âàë:
* eax = 37 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = x*65536 + y, (x,y)=ª®®à¤¨­ âë ªãàá®à  ¬ëè¨ ®â­®á¨â¥«ì­®
®ª­  ¯à¨«®¦¥­¨ï (áç¨â ï ®â 0)
‡ ¬¥ç ­¨ï:
* ‡­ ç¥­¨¥ ¢ëç¨á«ï¥âáï ¯® ä®à¬ã«¥ (x-xwnd)*65536 + (y-ywnd).
…᫨ y>=ywnd, â® ¬« ¤è¥¥ á«®¢® ­¥®âà¨æ â¥«ì­® ¨ ᮤ¥à¦¨â
®â­®á¨â¥«ì­ãî y-ª®®à¤¨­ âã,   áâ à襥 - ®â­®á¨â¥«ì­ãî x-ª®®à¤¨­ âã
(¯à ¢¨«ì­®£® §­ ª ). ‚ ¯à®â¨¢­®¬ á«ãç ¥ ¬« ¤è¥¥ á«®¢® ®âà¨æ â¥«ì­®
¨ ¢áñ à ¢­® ᮤ¥à¦¨â ®â­®á¨â¥«ì­ãî y-ª®®à¤¨­ âã,
  ª áâ à襬ã á«®¢ã á«¥¤ã¥â ¯à¨¡ ¢¨âì 1.
 
----------------- ®¤äã­ªæ¨ï 2 - ­ ¦ âë¥ ª­®¯ª¨ ¬ëè¨ -----------------
 à ¬¥âàë:
* eax = 37 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax ᮤ¥à¦¨â ¨­ä®à¬ æ¨î ® ­ ¦ âëå ª­®¯ª å ¬ëè¨:
* ¡¨â 0 ãáâ ­®¢«¥­ = «¥¢ ï ª­®¯ª  ­ ¦ â 
* ¡¨â 1 ãáâ ­®¢«¥­ = ¯à ¢ ï ª­®¯ª  ­ ¦ â 
* ¡¨â 2 ãáâ ­®¢«¥­ = á।­ïï ª­®¯ª  ­ ¦ â 
* ¡¨â 3 ãáâ ­®¢«¥­ = 4-ï ª­®¯ª  ­ ¦ â 
* ¡¨â 4 ãáâ ­®¢«¥­ = 5-ï ª­®¯ª  ­ ¦ â 
* ¯à®ç¨¥ ¡¨âë á¡à®è¥­ë
 
------------------ ®¤äã­ªæ¨ï 4 - § £à㧨âì ªãàá®à -------------------
 à ¬¥âàë:
* eax = 37 - ­®¬¥à ä㭪樨
* ebx = 4 - ­®¬¥à ¯®¤ä㭪樨
* dx = ¨áâ®ç­¨ª ¤ ­­ëå:
* dx = LOAD_FROM_FILE = 0 - ¤ ­­ë¥ ¢ ä ©«¥
* ecx = 㪠§ â¥«ì ­  ¯®«­ë© ¯ãâì ª ä ©«ã ªãàá®à 
* ä ©« ªãàá®à  ¤®«¦¥­ ¡ëâì ¢ ä®à¬ â¥ .cur, áâ ­¤ àâ­®¬ ¤«ï
MS Windows, ¯à¨çñ¬ à §¬¥à®¬ 32*32 ¯¨ªá¥«ï
* dx = LOAD_FROM_MEM = 1 - ¤ ­­ë¥ ä ©«  㦥 § £à㦥­ë ¢ ¯ ¬ïâì
* ecx = 㪠§ â¥«ì ­  ¤ ­­ë¥ ä ©«  ªãàá®à 
* ä®à¬ â ¤ ­­ëå â ª®© ¦¥, ª ª ¨ ¢ ¯à¥¤ë¤ã饬 á«ãç ¥
* dx = LOAD_INDIRECT = 2 - ¤ ­­ë¥ ¢ ¯ ¬ïâ¨
* ecx = 㪠§ â¥«ì ­  ®¡à § ªãàá®à  ¢ ä®à¬ â¥ ARGB 32*32 ¯¨ªá¥«ï
* edx = 0xXXYY0002, £¤¥
* XX = x-ª®®à¤¨­ â  "£®àï祩 â®çª¨" ªãàá®à 
* YY = y-ª®®à¤¨­ â 
* 0 <= XX, YY <= 31
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ­¥ã¤ ç 
* ¨­ ç¥ eax = åí­¤« ªãàá®à 
 
------------------ ®¤äã­ªæ¨ï 5 - ãáâ ­®¢¨âì ªãàá®à ------------------
“áâ ­ ¢«¨¢ ¥â ­®¢ë© ªãàá®à ¤«ï ®ª­  ⥪ã饣® ¯®â®ª .
 à ¬¥âàë:
* eax = 37 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
* ecx = åí­¤« ªãàá®à 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = åí­¤« ¯à¥¤ë¤ã饣® ãáâ ­®¢«¥­­®£® ªãàá®à 
‡ ¬¥ç ­¨ï:
* …᫨ ¯¥à¥¤ ­ ­¥ª®à४â­ë© åí­¤«, â® äã­ªæ¨ï ¢®ááâ ­®¢¨â ªãàá®à
¯® 㬮«ç ­¨î (áâ ­¤ àâ­ãî áâ५ªã). ‚ ç áâ­®áâ¨, ª ¢®ááâ ­®¢«¥­¨î
ªãàá®à  ¯® 㬮«ç ­¨î ¯à¨¢®¤¨â ¯¥à¥¤ ç  ecx=0.
 
------------------- ®¤äã­ªæ¨ï 6 - 㤠«¨âì ªãàá®à --------------------
 à ¬¥âàë:
* eax = 37 - ­®¬¥à ä㭪樨
* ebx = 6 - ­®¬¥à ¯®¤ä㭪樨
* ecx = åí­¤« ªãàá®à 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* Šãàá®à ¤®«¦¥­ ¡ë« ¡ëâì à ­¥¥ § £à㦥­ ⥪ã騬 ¯®â®ª®¬
(¢ë§®¢®¬ ¯®¤ä㭪樨 4). ”ã­ªæ¨ï ­¥ 㤠«ï¥â á¨á⥬­ë¥ ªãàá®àë ¨
ªãàá®àë, § £à㦥­­ë¥ ¤à㣨¬¨ ¯à¨«®¦¥­¨ï¬¨.
* …᫨ 㤠«ï¥âáï  ªâ¨¢­ë© (ãáâ ­®¢«¥­­ë© ¯®¤ä㭪樥© 5) ªãàá®à, â®
¢®ááâ ­ ¢«¨¢ ¥âáï ªãàá®à ¯® 㬮«ç ­¨î (áâ ­¤ àâ­ ï áâ५ª ).
 
------------------ ®¤äã­ªæ¨ï 7 - ¤ ­­ë¥ ¯à®ªàã⪨ -------------------
 à ¬¥âàë:
* eax = 37 - ­®¬¥à ä㭪樨
* ebx = 6 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = [horizontal offset]*65536 + [vertical offset]
‡ ¬¥ç ­¨ï:
* „ ­­ë¥ ¤®áâ㯭ë ⮫쪮  ªâ¨¢­®¬ã ®ª­ã.
* ®á«¥ ¯à®ç⥭¨ï §­ ç¥­¨ï ®¡­ã«ïîâáï.
* „ ­­ë¥ ¨¬¥îâ §­ ª®¢ë¥ §­ ç¥­¨ï.
 
======================================================================
================== ”ã­ªæ¨ï 38 - ­ à¨á®¢ âì ®â१®ª. ==================
======================================================================
 à ¬¥âàë:
* eax = 38 - ­®¬¥à ä㭪樨
* ebx = [ª®®à¤¨­ â  ­ ç «  ¯® ®á¨ x]*65536 +
[ª®®à¤¨­ â  ª®­æ  ¯® ®á¨ x]
* ecx = [ª®®à¤¨­ â  ­ ç «  ¯® ®á¨ y]*65536 +
[ª®®à¤¨­ â  ª®­æ  ¯® ®á¨ y]
* edx = 0x00RRGGBB - 梥â
edx = 0x01xxxxxx - à¨á®¢ âì ¨­¢¥àá­ë© ®â१®ª
(¬« ¤è¨¥ 24 ¡¨â  ¨£­®à¨àãîâáï)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* Š®®à¤¨­ âë ¡¥àãâáï ®â­®á¨â¥«ì­® ®ª­ .
* Š®­¥ç­ ï â®çª  â ª¦¥ à¨áã¥âáï.
 
======================================================================
== ”ã­ªæ¨ï 39, ¯®¤äã­ªæ¨ï 1 - ¯®«ãç¨âì à §¬¥à ä®­®¢®£® ¨§®¡à ¦¥­¨ï. ==
======================================================================
 à ¬¥âàë:
* eax = 39 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = [è¨à¨­ ]*65536 + [¢ëá®â ]
‡ ¬¥ç ­¨ï:
* …áâì ¯ à­ ï ª®¬ ­¤  ãáâ ­®¢ª¨ à §¬¥à®¢ ä®­®¢®£® ¨§®¡à ¦¥­¨ï -
¯®¤äã­ªæ¨ï 1 ä㭪樨 15. ®á«¥ ª®â®à®©, ࠧ㬥¥âáï, á«¥¤ã¥â
§ ­®¢® ®¯à¥¤¥«¨âì á ¬® ¨§®¡à ¦¥­¨¥.
 
======================================================================
= ”ã­ªæ¨ï 39, ¯®¤äã­ªæ¨ï 2 - ¯à®ç¨â âì â®çªã á ä®­®¢®£® ¨§®¡à ¦¥­¨ï. =
======================================================================
 à ¬¥âàë:
* eax = 39 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ᬥ饭¨¥
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0x00RRGGBB - 梥â â®çª¨, ¥á«¨ ᬥ饭¨¥ ¤®¯ãá⨬®
(¬¥­ìè¥ 0x160000-16)
* eax = 2 - ¨­ ç¥
‡ ¬¥ç ­¨ï:
* ¥ á«¥¤ã¥â ¯®« £ âìáï ­  ¢®§¢à é ¥¬®¥ §­ ç¥­¨¥ ¢ á«ãç ¥ ­¥¢¥à­®£®
ᬥ饭¨ï, ®­® ¬®¦¥â ¨§¬¥­¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à .
* ‘¬¥é¥­¨¥ â®çª¨ á ª®®à¤¨­ â ¬¨ (x,y) ¢ëç¨á«ï¥âáï ª ª (x+y*xsize)*3.
* …áâì ¯ à­ ï äã­ªæ¨ï ãáâ ­®¢ª¨ â®çª¨ ­  ä®­®¢®¬ ¨§®¡à ¦¥­¨¨ -
¯®¤äã­ªæ¨ï 2 ä㭪樨 15.
 
======================================================================
====== ”ã­ªæ¨ï 39, ¯®¤äã­ªæ¨ï 4 - ¯®«ãç¨âì ०¨¬ ®âà¨á®¢ª¨ ä®­ . =====
======================================================================
 à ¬¥âàë:
* eax = 39 - ­®¬¥à ä㭪樨
* ebx = 4 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 1 - § ¬®áâ¨âì
* eax = 2 - à áâï­ãâì
‡ ¬¥ç ­¨ï:
* …áâì ¯ à­ ï äã­ªæ¨ï ãáâ ­®¢ª¨ ०¨¬  ®âà¨á®¢ª¨ ä®­  -
¯®¤äã­ªæ¨ï 4 ä㭪樨 15.
 
======================================================================
======== ”ã­ªæ¨ï 40 - ãáâ ­®¢¨âì ¬ áªã ¤«ï ®¦¨¤ ¥¬ëå ᮡë⨩. ========
======================================================================
Œ áª  ¤«ï ®¦¨¤ ¥¬ëå ᮡë⨩ ¢«¨ï¥â ­  ä㭪樨 à ¡®âë á ᮡëâ¨ï¬¨ 10,
11, 23 - ®­¨ á®®¡é îâ ⮫쪮 ® ᮡëâ¨ïå, à §à¥èñ­­ëå í⮩ ¬ áª®©.
 à ¬¥âàë:
* eax = 40 - ­®¬¥à ä㭪樨
* ebx = ¬ áª : ¡¨â i ᮮ⢥âáâ¢ã¥â ᮡëâ¨î i+1 (á¬. ᯨ᮪ ᮡë⨩)
(ãáâ ­®¢«¥­­ë© ¡¨â à §à¥è ¥â ¨§¢¥é¥­¨¥ ® ᮡë⨨)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ¯à¥¤ë¤ã饥 §­ ç¥­¨¥ ¬ áª¨
‡ ¬¥ç ­¨ï:
* Œ áª  ¯® 㬮«ç ­¨î (7=111b) à §à¥è ¥â ¨§¢¥é¥­¨ï ® ¯¥à¥à¨á®¢ª¥
¨ ­ ¦ â¨ïå ª« ¢¨è ¨ ª­®¯®ª.
â®£® ¤®áâ â®ç­® ¤«ï ¡®«ì設á⢠ ¯à¨«®¦¥­¨©.
* ‘®¡ëâ¨ï, § ¯à¥éñ­­ë¥ ¢ ¬ áª¥, ¢áñ à ¢­® á®åà ­ïîâáï, ¥á«¨
¯à¨å®¤ïâ; ® ­¨å ¯à®áâ® ­¥ ¨§¢¥é îâ ä㭪樨 à ¡®âë á ᮡëâ¨ï¬¨.
* ”㭪樨 à ¡®âë á ᮡëâ¨ï¬¨ ãç¨â뢠îâ ¬ áªã ­  ¬®¬¥­â
¢ë§®¢  ä㭪樨,   ­¥ ­  ¬®¬¥­â ¯®áâ㯫¥­¨ï á®®¡é¥­¨ï.
 
======================================================================
================= ”ã­ªæ¨ï 41 - 㧭 âì ¢« ¤¥«ìæ  IRQ. =================
======================================================================
 à ¬¥âàë:
* eax = 41 - ­®¬¥à ä㭪樨
* ebx = ­®¬¥à IRQ, 0..15
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = PID ¢« ¤¥«ìæ 
* eax = 0, ¥á«¨ ¢« ¤¥«ìæ  ­¥â
* eax = -1 ¤«ï ­¥ª®à४⭮£® ebx
 
======================================================================
========= ”ã­ªæ¨ï 42 - à ¡®â  á ¤ ­­ë¬¨, ¯®«ã祭­ë¬¨ ¯® IRQ. =========
======================================================================
à¨ ¢®§­¨ª­®¢¥­¨¨ IRQ á¨á⥬  ¬®¦¥â áç¨â뢠âì ¤ ­­ë¥ ¨§ 㪠§ ­­ëå
à ­¥¥ ä㭪樥© 44 ¯®à⮢ ¨ § ¯¨á뢠âì í⨠¤ ­­ë¥ ¢ ¡ãä¥à.
 
-------------------- ®¤äã­ªæ¨ï 0 - ç⥭¨¥ ¤ ­­ëå --------------------
 à ¬¥âàë:
* eax = 42 - ­®¬¥à ä㭪樨
* bl = ­®¬¥à IRQ, 0..15
* bh = 0 - ­®¬¥à ¯®¤ä㭪樨
* ®áâ «ì­ ï ç áâì ॣ¨áâà  ebx ¤®«¦­  ¡ëâì ®¡­ã«¥­ 
* ecx = 㪠§ â¥«ì ­  ¡ãä¥à à §¬¥à®¬ ­¥ ¬¥­¥¥ 4000 ¡ ©â
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥: (á¨âã æ¨î ¬®¦­® à §«¨ç¨âì ¯® §­ ç¥­¨î eax)
* ¥á«¨ ¯®â®ª ­¥ ï¥âáï ¢« ¤¥«ì楬 IRQ
(¨«¨ ­®¬¥à IRQ § ¤ ­ ­¥¢¥à­®): eax = -1
* ¥á«¨ ¤ ­­ëå ­¥â: eax = 0
* ¥á«¨ ¢áñ ¢ ¯®à浪¥ ¨ ¤ ­­ë¥ ¡ë«¨:
eax = à §¬¥à ¤ ­­ëå, ¯à®ç¨â ­­ëå ¨§ ¡ãä¥à  (¢ ¡ ©â å)
 
------------ ®¤äã­ªæ¨ï 1 - 㧭 âì à §¬¥à ¤ ­­ëå ¢ ¡ãä¥à¥ ------------
 à ¬¥âàë:
* eax = 42 - ­®¬¥à ä㭪樨
* bl = ­®¬¥à IRQ, 0..15
* bh = 1 - ­®¬¥à ¯®¤ä㭪樨
* ®áâ «ì­ ï ç áâì ॣ¨áâà  ebx ¤®«¦­  ¡ëâì ®¡­ã«¥­ 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¥á«¨ ¯®â®ª ­¥ ï¥âáï ¢« ¤¥«ì楬 IRQ
(¨«¨ ­®¬¥à IRQ § ¤ ­ ­¥¢¥à­®): eax = -1
* ¨­ ç¥ eax = à §¬¥à ¤ ­­ëå ¢ ¡ãä¥à¥
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¯®â®ª ¤®«¦¥­ § à¥§¥à¢¨à®¢ âì ¤«ï ᥡï 㪠§ ­­ë© IRQ
ä㭪樥© 45.
*  §¬¥à ¡ãä¥à  ¤«ï ¤ ­­ëå - 4000 ¡ ©â, ¯à¨ ¯¥à¥¯®«­¥­¨¨
"ᢥ¦¨¥" ¤ ­­ë¥ ¯¥à¥áâ îâ § ¯¨á뢠âìáï ¢ ¡ãä¥à.
 
======================================================================
=================== ”ã­ªæ¨ï 43 - ¢¢®¤/¢ë¢®¤ ¢ ¯®àâ. ==================
======================================================================
 
------------------------ ‚뢮¤ ¤ ­­ëå ¢ ¯®àâ -------------------------
 à ¬¥âàë:
* eax = 43 - ­®¬¥à ä㭪樨
* bl = ¡ ©â ¤«ï ¢ë¢®¤ 
* ecx = ­®¬¥à ¯®àâ  0xnnnn (®â 0 ¤® 0xFFFF)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ¯®â®ª ­¥ § à¥§¥à¢¨à®¢ « 㪠§ ­­ë© ¯®àâ
 
------------------------ ‚¢®¤ ¤ ­­ëå ¨§ ¯®àâ  ------------------------
 à ¬¥âàë:
* eax = 43 - ­®¬¥à ä㭪樨
* ebx ¨£­®à¨àã¥âáï
* ecx = 0x8000nnnn, £¤¥ nnnn = ­®¬¥à ¯®àâ  (®â 0 ¤® 0xFFFF)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¯à¨ í⮬ ebx = ¢¢¥¤ñ­­ë© ¡ ©â
* eax = 1 - ¯®â®ª ­¥ § à¥§¥à¢¨à®¢ « ¤ ­­ë© ¯®àâ
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¯®â®ª ¤®«¦¥­ § à¥§¥à¢¨à®¢ âì §  ᮡ®©
㪠§ ­­ë© ¯®àâ ä㭪樥© 46.
* „«ï § à¥§¥à¢¨à®¢ ­­ëå ¯®à⮢ ¢¬¥áâ® ¢ë§®¢  íâ¨å ä㭪権
«ãçè¥ ¨á¯®«ì§®¢ âì ª®¬ ­¤ë ¯à®æ¥áá®à  in/out - íâ® §­ ç¨â¥«ì­®
¡ëáâ॥ ¨ ­¥áª®«ìª® ª®à®ç¥ ¨ ¯à®é¥. ˆ§ ­¥§ à¥§¥à¢¨à®¢ ­­ëå
¯®à⮢ ç¨â âì ¢áñ à ¢­® ­¥«ì§ï.
 
======================================================================
======== ”ã­ªæ¨ï 44 - ®¯à¥¤¥«¨âì ¤¥©áâ¢¨ï ¯à¨ ¯®áâ㯫¥­¨¨ IRQ. =======
======================================================================
à¨ ¢®§­¨ª­®¢¥­¨¨ IRQ á¨á⥬  ¬®¦¥â áç¨â뢠âì ¤ ­­ë¥ ¨§ 㪠§ ­­ëå í⮩
ä㭪樥© ¯®à⮢ ¨ § ¯¨á뢠âì í⨠¤ ­­ë¥ ¢ ¡ãä¥à, ®âªã¤  ¨å ¬®¦­®
¯à®ç¨â âì ä㭪樥© 42.
 à ¬¥âàë:
* eax = 44 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¬ áᨢ áâàãªâãà, ®¯¨á뢠îé¨å ¯® ®¤­®¬ã ¯®àâã:
* +0: word: 0 ®§­ ç ¥â ª®­¥æ ¬ áᨢ , ¨­ ç¥ ­®¬¥à ¯®àâ 
* +2: byte: § à¥§¥à¢¨à®¢ ­® (¨£­®à¨àã¥âáï)
* +3: byte: 1=áç¨â뢠âì ¡ ©â ¨§ í⮣® ¯®àâ , 2=áç¨â뢠âì á«®¢®
* ecx = ­®¬¥à IRQ, 0..15
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ¯®â®ª ­¥ ï¥âáï ¢« ¤¥«ì楬 㪠§ ­­®£® IRQ
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¯®â®ª ¤®«¦¥­ § à¥§¥à¢¨à®¢ âì §  ᮡ®©
㪠§ë¢ ¥¬ë© IRQ ä㭪樥© 45.
* à¨­¨¬ îâáï ¢® ¢­¨¬ ­¨¥ ⮫쪮 ¯¥à¢ë¥ 16 ¯®à⮢.
* ’¥ªãé ï ॠ«¨§ æ¨ï à áᬠâਢ ¥â ­¥¯à ¢¨«ì­®¥ §­ ç¥­¨¥ ¯®«ï +3
ª ª ᨣ­ « ¯à¥ªà é¥­¨ï ®¡à ¡®âª¨ IRQ.
 
======================================================================
============ ”ã­ªæ¨ï 45 - § à¥§¥à¢¨à®¢ âì/®á¢®¡®¤¨âì IRQ. ============
======================================================================
 à ¬¥âàë:
* eax = 45 - ­®¬¥à ä㭪樨
* ebx = 0 - § à¥§¥à¢¨à®¢ âì, 1 = ®á¢®¡®¤¨âì
* ecx = ­®¬¥à IRQ, 0..15
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ®è¨¡ª  (­¥¢¥à­ë© ­®¬¥à IRQ ¨«¨
¯®¯ë⪠ § à¥§¥à¢¨à®¢ âì ­¥á¢®¡®¤­ë© IRQ ¨«¨ ®á¢®¡®¤¨âì IRQ, ­¥
§ à¥§¥à¢¨à®¢ ­­ë© ⥪ã騬 ¯®â®ª®¬)
‡ ¬¥ç ­¨ï:
* ¥§¥à¢¨à®¢ ­¨¥ IRQ ­ã¦­® ¤«ï à ¡®âë ä㭪権 42 ¨ 44.
* ’®«ìª® ®¤¨­ ¯®â®ª ¬®¦¥â § à¥§¥à¢¨à®¢ âì ª®­ªà¥â­ë© IRQ.
* IRQ, ®¡à ¡ â뢠¥¬ë¥ á¨á⥬®© á ¬®áâ®ï⥫쭮, १¥à¢¨àãîâáï
á¨á⥬®© (¯®â®ª®¬ 1) ¯à¨ § £à㧪¥.
* à¨ § ¢¥à襭¨¨ ¯®â®ª   ¢â®¬ â¨ç¥áª¨ ®á¢®¡®¦¤ îâáï
¢á¥ § à¥§¥à¢¨à®¢ ­­ë¥ ¨¬ IRQ.
 
======================================================================
= ”ã­ªæ¨ï 46 - § à¥§¥à¢¨à®¢ âì/®á¢®¡®¤¨âì £à㯯㠯®à⮢ ¢¢®¤ /¢ë¢®¤ .
======================================================================
Š § à¥§¥à¢¨à®¢ ­­ë¬ ¯®àâ ¬ ¬®¦­® ®¡à é âìáï ­ ¯àï¬ãî ¨§ ¯à¨«®¦¥­¨ï
ª®¬ ­¤ ¬¨ in/out (४®¬¥­¤ã¥¬ë© ᯮᮡ) ¨ ¢ë§®¢®¬ ä㭪樨 43
(­¥à¥ª®¬¥­¤ã¥¬ë© ᯮᮡ).
 à ¬¥âàë:
* eax = 46 - ­®¬¥à ä㭪樨
* ebx = 0 - § à¥§¥à¢¨à®¢ âì, 1 - ®á¢®¡®¤¨âì
* ecx = ­®¬¥à ­ ç «  ¤¨ ¯ §®­  ¯®à⮢
* edx = ­®¬¥à ª®­æ  ¤¨ ¯ §®­  ¯®à⮢ (¢ª«îç¨â¥«ì­®)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ®è¨¡ª 
‡ ¬¥ç ­¨ï:
* ‚ á«ãç ¥ १¥à¢¨à®¢ ­¨ï ¯®à⮢ ®è¨¡ª®© áç¨â ¥âáï ¢ë¯®«­¥­¨¥
®¤­®£® ¨§ ãá«®¢¨©:
* ­ ç «ì­ë©  ¤à¥á ¡®«ìè¥ ª®­¥ç­®£®;
* 㪠§ ­­ë© ¤¨ ¯ §®­ ᮤ¥à¦¨â ­¥ª®à४â­ë© ­®¬¥à ¯®àâ 
(ª®à४â­ë¥ - ®â 0 ¤® 0xFFFF);
* ¯à¥¢ë襭® ®£à ­¨ç¥­¨¥ ­  ®¡é¥¥ ç¨á«® § à¥§¥à¢¨à®¢ ­­ëå ®¡« á⥩
- ¤®¯ã᪠¥âáï ¬ ªá¨¬ã¬ 255;
* 㪠§ ­­ë© ¤¨ ¯ §®­ ¯¥à¥á¥ª ¥âáï á ®¤­¨¬ ¨§
à ­¥¥ § à¥§¥à¢¨à®¢ ­­ëå
* ‚ á«ãç ¥ ®á¢®¡®¦¤¥­¨ï ¯®à⮢ ®è¨¡ª®© áç¨â ¥âáï ¯®¯ë⪠
®á¢®¡®¦¤¥­¨ï ¤¨ ¯ §®­ , ª®â®àë© à ­¥¥ ­¥ ¡ë« 楫¨ª®¬
§ à¥§¥à¢¨à®¢ ­ í⮩ ¦¥ ä㭪樥© (á â ª¨¬¨ ¦¥ §­ ç¥­¨ï¬¨ ecx,edx).
* à¨ ®¡­ à㦥­¨¨ ®è¨¡ª¨ (¢ ®¡®¨å á«ãç ïå) ­¨ª ª¨å ¤¥©á⢨©
­¥ ¯à®¨§¢®¤¨âáï.
* à¨ § £à㧪¥ á¨á⥬  १¥à¢¨àã¥â §  ᮡ®© ¯®àâë
0..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (¢ª«îç¨â¥«ì­®).
* à¨ § ¢¥à襭¨¨ ¯®â®ª   ¢â®¬ â¨ç¥áª¨ ®á¢®¡®¦¤ îâáï ¢á¥
§ à¥§¥à¢¨à®¢ ­­ë¥ ¨¬ ¯®àâë.
 
======================================================================
================= ”ã­ªæ¨ï 47 - ¢ë¢¥á⨠ç¨á«® ¢ ®ª­®. =================
======================================================================
 à ¬¥âàë:
* eax = 47 - ­®¬¥à ä㭪樨
* ebx = ¯ à ¬¥âàë ¯à¥®¡à §®¢ ­¨ï ç¨á«  ¢ ⥪áâ:
* bl = 0 - ecx ᮤ¥à¦¨â ç¨á«®
* bl = 1 - ecx ᮤ¥à¦¨â 㪠§ â¥«ì ­  dword/qword-ç¨á«®
* bh = 0 - ®â®¡à ¦ âì ¢ ¤¥áïâ¨ç­®© á¨á⥬¥ áç¨á«¥­¨ï
* bh = 1 - ®â®¡à ¦ âì ¢ è¥áâ­ ¤æ â¥à¨ç­®© á¨á⥬¥
* bh = 2 - ®â®¡à ¦ âì ¢ ¤¢®¨ç­®© á¨á⥬¥
* ¡¨âë 16-21 = ᪮«ìª® æ¨äà ®â®¡à ¦ âì
* ¡¨âë 22-29 § à¥§¥à¢¨à®¢ ­ë ¨ ¤®«¦­ë ¡ëâì ãáâ ­®¢«¥­ë ¢ 0
* ¡¨â 30 ãáâ ­®¢«¥­ = ¢ë¢®¤¨âì qword (64-¡¨â­®¥ ç¨á«®);
¯à¨ í⮬ ¤®«¦­® ¡ëâì bl = 1
* ¡¨â 31 ãáâ ­®¢«¥­ = ­¥ ¢ë¢®¤¨âì ¢¥¤ã騥 ­ã«¨ ç¨á« 
* ecx = ç¨á«® (¯à¨ bl=0) ¨«¨ 㪠§ â¥«ì (¯à¨ bl=1)
* edx = [ª®®à¤¨­ â  ¯® ®á¨ x]*65536 + [ª®®à¤¨­ â  ¯® ®á¨ y]
* esi = 0xX0RRGGBB:
* RR, GG, BB § ¤ îâ 梥â
* X = ABnn (¡¨âë)
* nn = èà¨äâ (0/1)
* A ¨£­®à¨àã¥âáï
* B=1 - § ªà è¨¢ âì ä®­ 梥⮬ edi
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* “ª § ­­ ï ¤«¨­  ­¥ ¤®«¦­  ¯à¥¢®á室¨âì 60.
* ‚뢮¤¨âáï ஢­® 㪠§ ­­®¥ ª®«¨ç¥á⢮ æ¨äà. …᫨ ç¨á«® ¬ «® ¨
¬®¦¥â ¡ëâì § ¯¨á ­® ¬¥­ì訬 ª®«¨ç¥á⢮¬ æ¨äà, ®­® ¤®¯®«­ï¥âáï
¢¥¤ã騬¨ ­ã«ï¬¨; ¥á«¨ ç¨á«® ¢¥«¨ª® ¨ ­¥ ¬®¦¥â ¡ëâì § ¯¨á ­®
â ª¨¬ ª®«¨ç¥á⢮¬ æ¨äà, "«¨è­¨¥" ¢¥¤ã騥 æ¨äàë ®¡à¥§ îâáï.
*  à ¬¥âàë èà¨ä⮢ 㪠§ ­ë ¢ ®¯¨á ­¨¨ ä㭪樨 4 (¢ë¢®¤  ⥪áâ ).
 
======================================================================
======= ”ã­ªæ¨ï 48, ¯®¤äã­ªæ¨ï 0 - ¯à¨¬¥­¨âì ­ áâனª¨ íªà ­ . =======
======================================================================
 à ¬¥âàë:
* eax = 48 - ­®¬¥à ä㭪樨
* ebx = 0 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 0 - § à¥§¥à¢¨à®¢ ­®
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ”ã­ªæ¨ï ¯¥à¥à¨á®¢ë¢ ¥â íªà ­ ¯®á«¥ ¨§¬¥­¥­¨ï ¯ à ¬¥â஢
¯®¤äã­ªæ¨ï¬¨ 1 ¨ 2.
* ‚맮¢ ä㭪樨 ¡¥§ ¯à¥¤è¥áâ¢ãîé¨å ¢ë§®¢®¢ 㪠§ ­­ëå ¯®¤ä㭪権
¨£­®à¨àã¥âáï.
* ‚맮¢ ä㭪樨 á ­¥­ã«¥¢ë¬ ecx ¨£­®à¨àã¥âáï.
 
======================================================================
========= ”ã­ªæ¨ï 48, ¯®¤äã­ªæ¨ï 1 - ãáâ ­®¢¨âì áâ¨«ì ª­®¯®ª. ========
======================================================================
 à ¬¥âàë:
* eax = 48 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ⨯ ª­®¯®ª:
* 0 = ¯«®áª¨¥
* 1 = ®¡êñ¬­ë¥
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ®á«¥ ¢ë§®¢  ®¯¨á뢠¥¬®© ä㭪樨 á«¥¤ã¥â ¯¥à¥à¨á®¢ âì íªà ­
¯®¤ä㭪樥© 0.
* ’¨¯ ª­®¯®ª ¢«¨ï¥â ⮫쪮 ­  ¨å ¯à®à¨á®¢ªã ä㭪樥© 8.
 
======================================================================
==== ”ã­ªæ¨ï 48, ¯®¤äã­ªæ¨ï 2 - ãáâ ­®¢¨âì áâ ­¤ àâ­ë¥ æ¢¥â  ®ª®­. ===
======================================================================
 à ¬¥âàë:
* eax = 48 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  â ¡«¨æã 梥⮢
* edx = à §¬¥à â ¡«¨æë 梥⮢
(¤®«¦¥­ ¡ëâì 40 ¡ ©â ¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨)
”®à¬ â â ¡«¨æë 梥⮢ 㪠§ ­ ¢ ®¯¨á ­¨¨ ¯®¤ä㭪樨 3.
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ®á«¥ ¢ë§®¢  ®¯¨á뢠¥¬®© ä㭪樨 á«¥¤ã¥â ¯¥à¥à¨á®¢ âì íªà ­
¯®¤ä㭪樥© 0.
* ’ ¡«¨æ  áâ ­¤ àâ­ëå 梥⮢ ¢«¨ï¥â ⮫쪮 ­  ¯à¨«®¦¥­¨ï,
ª®â®àë¥ íâã â ¡«¨æã ï¢­ë¬ ®¡à §®¬ ¯®«ãç îâ (¯®¤ä㭪樥© 3) ¨
¨á¯®«ì§ãîâ (㪠§ë¢ ï æ¢¥â  ¨§ ­¥ñ ¯à¨ ¢ë§®¢ å ä㭪権 à¨á®¢ ­¨ï).
* ’ ¡«¨æ  áâ ­¤ àâ­ëå 梥⮢ ¢å®¤¨â ¢ ᪨­ ¨ ãáâ ­ ¢«¨¢ ¥âáï § ­®¢®
¯à¨ ãáâ ­®¢ª¥ ᪨­  (¯®¤ä㭪樨 8).
* ’ ¡«¨æã 梥⮢ ¬®¦­® ¯à®á¬ âਢ âì/¨§¬¥­ïâì ¨­â¥à ªâ¨¢­® á ¯®¬®éìî
¯à¨«®¦¥­¨ï desktop.
 
======================================================================
===== ”ã­ªæ¨ï 48, ¯®¤äã­ªæ¨ï 3 - ¯®«ãç¨âì áâ ­¤ àâ­ë¥ æ¢¥â  ®ª®­. ====
======================================================================
 à ¬¥âàë:
* eax = 48 - ­®¬¥à ä㭪樨
* ebx = 3 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¡ãä¥à à §¬¥à®¬ edx ¡ ©â,
ªã¤  ¡ã¤¥â § ¯¨á ­  â ¡«¨æ 
* edx = à §¬¥à â ¡«¨æë 梥⮢
(¤®«¦¥­ ¡ëâì 40 ¡ ©â ¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
”®à¬ â â ¡«¨æë 梥⮢: ª ¦¤ë© í«¥¬¥­â -
dword-§­ ç¥­¨¥ æ¢¥â  0x00RRGGBB
* +0: dword: frames - 梥â à ¬ª¨
* +4: dword: grab - 梥⠧ £®«®¢ª 
* +8: dword: grab_button - 梥⠪­®¯ª¨ ­  ¯®«®á¥ § £®«®¢ª 
* +12 = +0xC: dword: grab_button_text - 梥â ⥪áâ  ­  ª­®¯ª¥
­  ¯®«®á¥ § £®«®¢ª 
* +16 = +0x10: dword: grab_text - 梥â ⥪áâ  ­  § £®«®¢ª¥
* +20 = +0x14: dword: work - 梥â à ¡®ç¥© ®¡« áâ¨
* +24 = +0x18: dword: work_button - 梥⠪­®¯ª¨ ¢ à ¡®ç¥© ®¡« áâ¨
* +28 = +0x1C: dword: work_button_text - 梥â ⥪áâ  ­  ª­®¯ª¥
¢ à ¡®ç¥© ®¡« áâ¨
* +32 = +0x20: dword: work_text - 梥â ⥪áâ  ¢ à ¡®ç¥© ®¡« áâ¨
* +36 = +0x24: dword: work_graph - 梥⠣à ä¨ª¨ ¢ à ¡®ç¥© ®¡« áâ¨
‡ ¬¥ç ­¨ï:
* ‘âàãªâãà  â ¡«¨æë 梥⮢ ®¯¨á ­  ¢ áâ ­¤ àâ­®¬ ¢ª«îç ¥¬®¬ ä ©«¥
macros.inc ¯®¤ ­ §¢ ­¨¥¬ system_colors; ­ ¯à¨¬¥à, ¬®¦­® ¯¨á âì:
sc system_colors ; ®¡ê¥­¨¥ ¯¥à¥¬¥­­®©
... ; £¤¥-â® ­ ¤® ¢ë§¢ âì
; ®¯¨á뢠¥¬ãî äã­ªæ¨î á ecx=sc
mov ecx, [sc.work_button_text] ; ç¨â ¥¬ 梥â ⥪áâ 
; ­  ª­®¯ª¥ ¢ à ¡®ç¥© ®¡« áâ¨
* ˆá¯®«ì§®¢ ­¨¥/­¥¨á¯®«ì§®¢ ­¨¥ íâ¨å 梥⮢ - ¤¥«® ¨áª«îç¨â¥«ì­®
á ¬®© ¯à®£à ¬¬ë. „«ï ¨á¯®«ì§®¢ ­¨ï ­ã¦­® ¯à®áâ® ¯à¨ ¢ë§®¢¥ ä㭪権
à¨á®¢ ­¨ï 㪠§ë¢ âì 梥â, ¢§ïâë© ¨§ í⮩ â ¡«¨æë.
* à¨ ¨§¬¥­¥­¨¨ â ¡«¨æë áâ ­¤ àâ­ëå 梥⮢ (¯®¤ä㭪樥© 2 á
¯®á«¥¤ãî騬 ¯à¨¬¥­¥­¨¥¬ ¨§¬¥­¥­¨© ¯®¤ä㭪樥© 0 ¨«¨
¯à¨ ãáâ ­®¢ª¥ ᪨­  ¯®¤ä㭪樥© 8) ¢á¥¬ ®ª­ ¬ ¯®áë« ¥âáï á®®¡é¥­¨¥
® ­¥®¡å®¤¨¬®á⨠¯¥à¥à¨á®¢ª¨ (ᮡë⨥ á ª®¤®¬ 1).
* ‘â ­¤ àâ­ë¥ æ¢¥â  ¬®¦­® ¯à®á¬ âਢ âì/¨§¬¥­ïâì ¨­â¥à ªâ¨¢­®
á ¯®¬®éìî ¯à¨«®¦¥­¨ï desktop.
 
======================================================================
========== ”ã­ªæ¨ï 48, ¯®¤äã­ªæ¨ï 4 - ¯®«ãç¨âì ¢ëá®âã ᪨­ . =========
======================================================================
 à ¬¥âàë:
* eax = 48 - ­®¬¥à ä㭪樨
* ebx = 4 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ¢ëá®â  ᪨­ 
‡ ¬¥ç ­¨ï:
* ‚ëá®â®© ᪨­  ¯® ®¯à¥¤¥«¥­¨î áç¨â ¥âáï ¢ëá®â  § £®«®¢ª  ®ª®­,
¨á¯®«ì§ãîé¨å ᪨­.
* ‘¬®âਠ⠪¦¥ ®¡éãî áâàãªâãàã ®ª­  ¢ ®¯¨á ­¨¨ ä㭪樨 0.
 
======================================================================
===== ”ã­ªæ¨ï 48, ¯®¤äã­ªæ¨ï 5 - ¯®«ãç¨âì à ¡®çãî ®¡« áâì íªà ­ . ====
======================================================================
 à ¬¥âàë:
* eax = 48 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = [left]*65536 + [right]
* ebx = [top]*65536 + [bottom]
‡ ¬¥ç ­¨ï:
*  ¡®ç ï ®¡« áâì íªà ­  ®¯à¥¤¥«ï¥â ¯®«®¦¥­¨¥ ¨ ª®®à¤¨­ âë
¬ ªá¨¬¨§¨à®¢ ­­®£® ®ª­ .
*  ¡®ç ï ®¡« áâì íªà ­  ¯à¨ ­®à¬ «ì­®© à ¡®â¥ ¥áâì ¢¥áì íªà ­
§  ¢ëç¥â®¬ ¯ ­¥«¨ (@panel).
* (left,top) - ª®®à¤¨­ âë «¥¢®£® ¢¥àå­¥£® 㣫 ,
(right,bottom) - ª®®à¤¨­ âë ¯à ¢®£® ­¨¦­¥£®.
’ ª¨¬ ®¡à §®¬, à §¬¥à à ¡®ç¥© ®¡« á⨠¯® ®á¨ x ®¯à¥¤¥«ï¥âáï
ä®à¬ã«®© right-left+1, ¯® ®á¨ y - ä®à¬ã«®© bottom-right+1.
* ‘¬®âਠ⠪¦¥ äã­ªæ¨î 14,
¯®§¢®«ïîéãî ®¯à¥¤¥«¨âì à §¬¥àë ¢á¥£® íªà ­ .
* …áâì ¯ à­ ï äã­ªæ¨ï ãáâ ­®¢ª¨ à ¡®ç¥© ®¡« á⨠- ¯®¤äã­ªæ¨ï 6.
 
======================================================================
==== ”ã­ªæ¨ï 48, ¯®¤äã­ªæ¨ï 6 - ãáâ ­®¢¨âì à ¡®çãî ®¡« áâì íªà ­ . ===
======================================================================
 à ¬¥âàë:
* eax = 48 - ­®¬¥à ä㭪樨
* ebx = 6 - ­®¬¥à ¯®¤ä㭪樨
* ecx = [left]*65536 + [right]
* edx = [top]*65536 + [bottom]
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
*  ¡®ç ï ®¡« áâì íªà ­  ®¯à¥¤¥«ï¥â ¯®«®¦¥­¨¥ ¨ ª®®à¤¨­ âë
¬ ªá¨¬¨§¨à®¢ ­­®£® ®ª­ .
* â  äã­ªæ¨ï ¨á¯®«ì§ã¥âáï ⮫쪮 ¯à¨«®¦¥­¨¥¬ @panel,
ãáâ ­ ¢«¨¢ î騬 à ¡®ç¥© ®¡« áâìî ¢¥áì íªà ­ §  ¢ëç¥â®¬ ¯ ­¥«¨.
* (left,top) - ª®®à¤¨­ âë «¥¢®£® ¢¥àå­¥£® 㣫 ,
(right,bottom) - ª®®à¤¨­ âë ¯à ¢®£® ­¨¦­¥£®.
’ ª¨¬ ®¡à §®¬, à §¬¥à à ¡®ç¥© ®¡« á⨠¯® ®á¨ x ®¯à¥¤¥«ï¥âáï
ä®à¬ã«®© right-left+1, ¯® ®á¨ y - ä®à¬ã«®© bottom-right+1.
* …᫨ left>=right, â® x-ª®®à¤¨­ âë à ¡®ç¥© ®¡« á⨠­¥ ¨§¬¥­ïîâáï.
…᫨ left<0, â® left ­¥ ãáâ ­ ¢«¨¢ ¥âáï. …᫨ right ¡®«ìè¥
¨«¨ à ¢­® è¨à¨­ë íªà ­ , â® right ­¥ ãáâ ­ ¢«¨¢ ¥âáï.
€­ «®£¨ç­® ¯® ®á¨ y.
* ‘¬®âਠ⠪¦¥ äã­ªæ¨î 14,
¯®§¢®«ïîéãî ®¯à¥¤¥«¨âì à §¬¥àë ¢á¥£® íªà ­ .
* …áâì ¯ à­ ï äã­ªæ¨ï ¯®«ã祭¨ï à ¡®ç¥© ®¡« á⨠-
¯®¤äã­ªæ¨ï 5.
* â  äã­ªæ¨ï  ¢â®¬ â¨ç¥áª¨ ¯¥à¥à¨á®¢ë¢ ¥â íªà ­, ¯® 室㠤¥« 
®¡­®¢«ï¥â ª®®à¤¨­ âë ¨ à §¬¥àë ¬ ªá¨¬¨§¨à®¢ ­­ëå ®ª®­.
‚ᥠ®ª­  ¨§¢¥é îâáï ® ­¥®¡å®¤¨¬®á⨠¯¥à¥à¨á®¢ª¨ (ᮡë⨥ 1).
 
======================================================================
====================== ”ã­ªæ¨ï 48, ¯®¤äã­ªæ¨ï 7 ======================
============ ®«ãç¨âì ®¡« áâì ᪨­  ¤«ï ⥪áâ  § £®«®¢ª . ============
======================================================================
‚®§¢à é ¥â ®¡« áâì § £®«®¢ª  ®ª­  ᮠ᪨­®¬, ¯à¥¤­ §­ ç¥­­ãî
¤«ï ¢ë¢®¤  ⥪áâ  § £®«®¢ª .
 à ¬¥âàë:
* eax = 48 - ­®¬¥à ä㭪樨
* ebx = 7 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = [left]*65536 + [right]
* ebx = [top]*65536 + [bottom]
‡ ¬¥ç ­¨ï:
* ˆá¯®«ì§®¢ ­¨¥/­¥¨á¯®«ì§®¢ ­¨¥ í⮩ ä㭪樨 -
«¨ç­®¥ ¤¥«® ¯à¨«®¦¥­¨ï.
* ¥ª®¬¥­¤ã¥âáï ãç¨â뢠âì §­ ç¥­¨ï, ¢®§¢à é ¥¬ë¥ í⮩ ä㭪樥©,
¯à¨ ¢ë¡®à¥ ¬¥áâ  ¤«ï à¨á®¢ ­¨ï ⥪áâ  § £®«®¢ª  (ä㭪樥© 4) ¨«¨
ª ª®£®-­¨¡ã¤ì § ¬¥­¨â¥«ï ⥪áâ  § £®«®¢ª 
(¯® ãᬮâ७¨î ¯à¨«®¦¥­¨ï).
 
======================================================================
==== ”ã­ªæ¨ï 48, ¯®¤äã­ªæ¨ï 8 - ãáâ ­®¢¨âì ¨á¯®«ì§ã¥¬ë© ᪨­ ®ª®­. ===
======================================================================
 à ¬¥âàë:
* eax = 48 - ­®¬¥à ä㭪樨
* ebx = 8 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¨¬ï ä ©«  ᪨­ 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ­¥ 㤠«®áì § £à㧨âì ä ©«
* eax = 2 - ä ©« ­¥ ï¥âáï ä ©«®¬ ᪨­ 
‡ ¬¥ç ­¨ï:
* à¨ ãᯥ譮© § £à㧪¥ ᪨­  ¢á¥ ®ª­  ¨§¢¥é îâáï ® ­¥®¡å®¤¨¬®áâ¨
¯¥à¥à¨á®¢ª¨ (ᮡë⨥ 1).
* à¨ § £à㧪¥ á¨á⥬  áç¨â뢠¥â ᪨­ ¨§ ä ©«  default.skn
­  à ¬¤¨áª¥.
* ®«ì§®¢ â¥«ì ¬®¦¥â ¨§¬¥­ïâì ᪨­ áâ â¨ç¥áª¨, ᮧ¤ ¢ ᢮©
default.skn, ¨«¨ ¤¨­ ¬¨ç¥áª¨ á ¯®¬®éìî ¯à¨«®¦¥­¨ï desktop.
 
======================================================================
============ ”ã­ªæ¨ï 49 - Advanced Power Management (APM). ===========
======================================================================
 à ¬¥âàë:
* eax = 49 - ­®¬¥à ä㭪樨
* dx = ­®¬¥à ä㭪樨 APM ( ­ «®£ ax ¢ ᯥæ¨ä¨ª æ¨¨)
* bx, cx = ¯ à ¬¥âàë ä㭪樨 APM
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* 16-¡¨â­ë¥ ॣ¨áâàë ax, bx, cx, dx, si, di ¨ ä« £ CF
ãáâ ­®¢«¥­ë ¢ ᮮ⢥âá⢨¨ ᮠᯥæ¨ä¨ª æ¨¥© APM
* áâ à訥 ¯®«®¢¨­ë 32-¡¨â­ëå ॣ¨áâ஢ eax, ebx, ecx,
edx, esi, edi à §àãè îâáï
‡ ¬¥ç ­¨ï:
* ‘¯¥æ¨ä¨ª æ¨ï APM 1.2 ®¯¨á뢠¥âáï ¢ ¤®ªã¬¥­â¥
"Advanced Power Management (APM) BIOS Specification"
(Revision 1.2), ¤®áâ㯭®¬ ­ 
http://www.microsoft.com/whdc/archive/amp_12.mspx;
ªà®¬¥ ⮣®, ®­  ¢ª«î祭  ¢ ¨§¢¥áâ­ë© Interrupt List by Ralf Brown
(http://www.pobox.com/~ralf/files.html,
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/).
 
======================================================================
================= ”ã­ªæ¨ï 50 - ãáâ ­®¢ª  ä®à¬ë ®ª­ . =================
======================================================================
Ž¡ëç­ë¥ ®ª­  ¯à¥¤áâ ¢«ïîâ ᮡ®© ¯àאַ㣮«ì­¨ª¨. ‘ ¯®¬®éìî í⮩ ä㭪樨
®ª­ã ¬®¦­® ¯à¨¤ âì ¯à®¨§¢®«ì­ãî ä®à¬ã. ”®à¬  § ¤ ñâáï ­ ¡®à®¬ â®ç¥ª
¢­ãâਠ®¡à ¬«ïî饣® ¯àאַ㣮«ì­¨ª , ¯à¨­ ¤«¥¦ é¨å ®ª­ã. ®«®¦¥­¨¥ ¨
à §¬¥àë ®¡à ¬«ïî饣® ¯àאַ㣮«ì­¨ª  § ¤ îâáï ä㭪樥© 0 ¨ ¨§¬¥­ïîâáï
ä㭪樥© 67.
 
--------------- “áâ ­®¢ª  ¤ ­­ëå á ¨­ä®à¬ æ¨¥© ® ä®à¬¥ ---------------
 à ¬¥âàë:
* eax = 50 - ­®¬¥à ä㭪樨
* ebx = 0 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¤ ­­ë¥ ä®à¬ë (¬ áᨢ ¡ ©â 0/1)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
------------------ “áâ ­®¢ª  ¬ áèâ ¡  ¤ ­­ëå ä®à¬ë -------------------
 à ¬¥âàë:
* eax = 50 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx § ¤ ñâ ¬ áèâ ¡: ª ¦¤ë© ¡ ©â ¤ ­­ëå ®¯à¥¤¥«ï¥â
(2^scale)*(2^scale) ¯¨ªá¥«¥©
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* Œ áèâ ¡ ¯® 㬮«ç ­¨î à ¢¥­ 0 (¬ áèâ ¡¨àãî騩 ¬­®¦¨â¥«ì 1). …᫨ ¢
¤ ­­ëå ä®à¬ë ®¤¨­ ¡ ©â ᮮ⢥âáâ¢ã¥â ®¤­®¬ã ¯¨ªá¥«î, â® ¬ áèâ ¡
¬®¦­® ­¥ ãáâ ­ ¢«¨¢ âì.
* Ž¡®§­ ç¨¬ xsize = è¨à¨­  ®ª­  (¢ ¯¨ªá¥«ïå), ysize = ¢ëá®â ;
®¡à â¨â¥ ¢­¨¬ ­¨¥, çâ® ®­¨ ­  ¥¤¨­¨æã ¡®«ìè¥, 祬 ãáâ ­ ¢«¨¢ ¥¬ë¥
äã­ªæ¨ï¬¨ 0, 67.
* ® ®¯à¥¤¥«¥­¨î ¬ áèâ ¡  xsize ¨ ysize ¤®«¦­ë ¤¥«¨âìáï ­  2^scale.
*  ©â ¤ ­­ëå ¯® ᬥ饭¨î a ¤®«¦¥­ ¡ëâì 0/1 ¨
®¯à¥¤¥«ï¥â ¯à¨­ ¤«¥¦­®áâì ®ª­ã ª¢ ¤à â  á® áâ®à®­®© 2^scale
(¯à¨ scale=0 ¯®«ãç ¥¬ ¯¨ªá¥«ì) ¨ ª®®à¤¨­ â ¬¨ «¥¢®£® ¢¥àå­¥£® 㣫 
(a mod (xsize shr scale), a div (xsize shr scale))
*  §¬¥à ¤ ­­ëå: (xsize shr scale)*(ysize shr scale).
* „ ­­ë¥ ¤®«¦­ë ¯à¨áãâá⢮¢ âì ¢ ¯ ¬ï⨠¨ ­¥ ¬¥­ïâìáï
¯®á«¥ ãáâ ­®¢ª¨ ä®à¬ë.
* ‘¨á⥬  ¯à®á¬ âਢ ¥â ¤ ­­ë¥ ® ä®à¬¥ ¯à¨ ª ¦¤®© ¯¥à¥à¨á®¢ª¥ ®ª­ 
ä㭪樥© 0.
* ‚맮¢ ¯®¤ä㭪樨 0 á ­ã«¥¢ë¬ 㪠§ â¥«¥¬ ¯à¨¢®¤¨â ª ¢®§¢à âã
ª ¯àאַ㣮«ì­®© ä®à¬¥.
 
======================================================================
===================== ”ã­ªæ¨ï 51 - ᮧ¤ âì ¯®â®ª. ====================
======================================================================
 à ¬¥âàë:
* eax = 51 - ­®¬¥à ä㭪樨
* ebx = 1 - ¥¤¨­á⢥­­ ï ¯®¤äã­ªæ¨ï
* ecx =  ¤à¥á â®çª¨ ¢å®¤  ¯®â®ª  (­ ç «ì­ë© eip)
* edx = 㪠§ â¥«ì áâíª  ¯®â®ª  (­ ç «ì­ë© esp)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ®è¨¡ª  (¢ á¨á⥬¥ ᫨誮¬ ¬­®£® ¯®â®ª®¢)
* ¨­ ç¥ eax = TID - ¨¤¥­â¨ä¨ª â®à ¯®â®ª 
 
======================================================================
= ”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 0 - ¯®«ãç¨âì ª®­ä¨£ãà æ¨î á¥â¥¢®£® ¤à ©¢¥à .
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 0 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ¤¢®©­®¥ á«®¢® ª®­ä¨£ãà æ¨¨
‡ ¬¥ç ­¨ï:
* ‘«®¢® ª®­ä¨£ãà æ¨¨ ¬®¦­® ãáâ ­®¢¨âì ¯®¤ä㭪樥© 2.
* Ÿ¤à® ­¥ ¨á¯®«ì§ã¥â ᮮ⢥âáâ¢ãîéãî ¯¥à¥¬¥­­ãî.
–¥­­®áâì í⮩ ¯¥à¥¬¥­­®© ¨ à ¡®â îé¨å á ­¥© ¯®¤ä㭪権 0 ¨ 2
¯à¥¤áâ ¢«ï¥âáï ᮬ­¨â¥«ì­®©.
 
======================================================================
======= ”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 1 - ¯®«ãç¨âì «®ª «ì­ë© IP- ¤à¥á. ======
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = IP- ¤à¥á (4 ¡ ©â )
‡ ¬¥ç ­¨ï:
* ‹®ª «ì­ë© IP- ¤à¥á ãáâ ­ ¢«¨¢ ¥âáï ¯®¤ä㭪樥© 3.
 
======================================================================
”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 2 - ãáâ ­®¢¨âì ª®­ä¨£ãà æ¨î á¥â¥¢®£® ¤à ©¢¥à .
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¤¢®©­®¥ á«®¢® ª®­ä¨£ãà æ¨¨; ¥á«¨ ¬« ¤è¨¥ 7 ¡¨â ®¡à §ãîâ
ç¨á«® 3, íâ® ¢®á¯à¨­¨¬ ¥âáï ª ª § ¯à®á ­  [¯¥à¥-]¨­¨æ¨ «¨§ æ¨î
Ethernet-ª àâë, ¢ ¯à®â¨¢­®¬ á«ãç ¥ Ethernet ¢ëª«îç ¥âáï
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¥á«¨ ­¥ § ¯à®è¥­ Ethernet-¨­â¥à䥩á, â® ¢®§¢à é ¥âáï eax=2,
­® íâ® ¬®¦¥â ¨§¬¥­¨âìáï ¢ ¡ã¤ãé¨å ¢¥àá¨ïå ï¤à 
* ¥á«¨ § ¯à®è¥­ Ethernet-¨­â¥à䥩á, â® eax=0 ®§­ ç ¥â ®è¨¡ªã
(®âáãâá⢨¥ Ethernet-ª àâë),   ­¥­ã«¥¢®¥ §­ ç¥­¨¥ - ãᯥå
‡ ¬¥ç ­¨ï:
* ‘«®¢® ª®­ä¨£ãà æ¨¨ ¬®¦­® ¯à®ç¨â âì ¯®¤ä㭪樥© 0.
* Ÿ¤à® ­¥ ¨á¯®«ì§ã¥â ᮮ⢥âáâ¢ãîéãî ¯¥à¥¬¥­­ãî.
–¥­­®áâì í⮩ ¯¥à¥¬¥­­®©, ¯®¤ä㭪樨 0 ¨ ç á⨠¯®¤ä㭪樨 2,
ãáâ ­ ¢«¨¢ î饩 íâã ¯¥à¥¬¥­­ãî, ¯à¥¤áâ ¢«ï¥âáï ᮬ­¨â¥«ì­®©.
 
======================================================================
====== ”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 3 - ãáâ ­®¢¨âì «®ª «ì­ë© IP- ¤à¥á. =====
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 3 - ­®¬¥à ¯®¤ä㭪樨
* ecx = IP- ¤à¥á (4 ¡ ©â )
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=3, ­® íâ® ¬®¦¥â ¡ëâì ¨§¬¥­¥­®
¢ ¡ã¤ãé¨å ¢¥àá¨ïå
‡ ¬¥ç ­¨ï:
* ‹®ª «ì­ë© IP- ¤à¥á ¬®¦­® ¯®«ãç¨âì ¯®¤ä㭪樥© 1.
 
======================================================================
= ”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 6 - ¤®¡ ¢¨âì ¤ ­­ë¥ ¢ á⥪ ¢å®¤­®© ®ç¥à¥¤¨. =
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 6 - ­®¬¥à ¯®¤ä㭪樨
* edx = à §¬¥à ¤ ­­ëå
* esi = 㪠§ â¥«ì ­  ¤ ­­ë¥
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ®è¨¡ª 
* eax = 0 - ãᯥ譮
‡ ¬¥ç ­¨ï:
* â  äã­ªæ¨ï ¯à¥¤­ §­ ç¥­  ⮫쪮 ¤«ï ¬¥¤«¥­­ëå á¥â¥¢ëå ¤à ©¢¥à®¢
(PPP, SLIP).
*  §¬¥à ¤ ­­ëå ­¥ ¤®«¦¥­ ¯à¥¢®á室¨âì 1500 ¡ ©â,
å®âï ¯à®¢¥à®ª ª®à४⭮á⨠­¥ ¤¥« ¥âáï.
 
======================================================================
====================== ”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 8 ======================
============= à®ç¨â âì ¤ ­­ë¥ ¨§ á¥â¥¢®© ®ç¥à¥¤¨ ¢ë¢®¤ . ============
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 8 - ­®¬¥à ¯®¤ä㭪樨
* esi = 㪠§ â¥«ì ­  ¡ãä¥à à §¬¥à®¬ 1500 ¡ ©â
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ç¨á«® ¯à®ç¨â ­­ëå ¡ ©â (¢ ⥪ã饩 ॠ«¨§ æ¨¨
«¨¡® 0 = ­¥â ¤ ­­ëå, «¨¡® 1500)
* ¤ ­­ë¥ ᪮¯¨à®¢ ­ë ¢ ¡ãä¥à
‡ ¬¥ç ­¨ï:
* â  äã­ªæ¨ï ¯à¥¤­ §­ ç¥­  ⮫쪮 ¤«ï ¬¥¤«¥­­ëå á¥â¥¢ëå ¤à ©¢¥à®¢
(PPP, SLIP).
 
======================================================================
=========== ”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 9 - ¯®«ãç¨âì gateway IP. ==========
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 9 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = gateway IP (4 ¡ ©â )
 
======================================================================
========= ”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 10 - ¯®«ãç¨âì ¬ áªã ¯®¤á¥â¨. ========
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 10 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ¬ áª  ¯®¤á¥â¨
 
======================================================================
========= ”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 11 - ãáâ ­®¢¨âì gateway IP. =========
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 11 - ­®¬¥à ¯®¤ä㭪樨
* ecx = gateway IP (4 ¡ ©â )
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=11, ­® íâ® ¬®¦¥â ¡ëâì ¨§¬¥­¥­®
¢ ¡ã¤ãé¨å ॠ«¨§ æ¨ïå
 
======================================================================
======== ”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 12 - ãáâ ­®¢¨âì ¬ áªã ¯®¤á¥â¨. =======
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 12 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¬ áª  ¯®¤á¥â¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=12, ­® íâ® ¬®¦¥â ¡ëâì ¨§¬¥­¥­®
¢ ¡ã¤ãé¨å ¢¥àá¨ïå
 
======================================================================
============ ”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 13 - ¯®«ãç¨âì DNS IP. ============
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 13 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = DNS IP (4 ¡ ©â )
 
======================================================================
=========== ”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 14 - ãáâ ­®¢¨âì DNS IP. ===========
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 14 - ­®¬¥à ¯®¤ä㭪樨
* ecx = DNS IP (4 ¡ ©â )
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ⥪ãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â eax=14, ­® íâ® ¬®¦¥â ¡ëâì ¨§¬¥­¥­®
¢ á«¥¤ãîé¨å ¢¥àá¨ïå
 
======================================================================
====== ”ã­ªæ¨ï 52, ¯®¤äã­ªæ¨ï 15 - ¯®«ãç¨âì «®ª «ì­ë© MAC- ¤à¥á. =====
======================================================================
 à ¬¥âàë:
* eax = 52 - ­®¬¥à ä㭪樨
* ebx = 15 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 0 - ç¨â âì ¯¥à¢ë¥ 4 ¡ ©â ,
ecx = 4 - ç¨â âì ¯®á«¥¤­¨¥ 2 ¡ ©â 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¤«ï ecx=0: eax = ¯¥à¢ë¥ 4 ¡ ©â  MAC- ¤à¥á 
* ¤«ï ecx=4: ax = ¯®á«¥¤­¨¥ 2 ¡ ©â  MAC- ¤à¥á ,
áâ àè ï ¯®«®¢¨­  eax à §àãè ¥âáï
* ¤«ï ¤à㣨å ecx: eax = -1 ª ª ¯à¨§­ ª ®è¨¡ª¨
 
======================================================================
============ ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 0 - ®âªàëâì UDP-᮪¥â. ===========
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 0 - ­®¬¥à ¯®¤ä㭪樨
* ecx = «®ª «ì­ë© ¯®àâ (ãç¨â뢠¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®),
ecx = 0 - ¯à¥¤®áâ ¢¨âì á¨á⥬¥ ¢ë¡®à «®ª «ì­®£® ¯®àâ 
* edx = 㤠«ñ­­ë© ¯®àâ (ãç¨â뢠¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®)
* esi = 㤠«ñ­­ë© IP
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 = 0xFFFFFFFF - ®è¨¡ª ; ebx à §àãè ¥âáï
* eax = åí­¤« ᮪¥â  (­¥ª®â®à®¥ ç¨á«®, ®¤­®§­ ç­® ¨¤¥­â¨ä¨æ¨àãî饥
᮪¥â ¨ ¨¬¥î饥 á¬ë᫠⮫쪮 ¤«ï á¨á⥬ë) - ãᯥ譮;
ebx à §àãè ¥âáï
 
======================================================================
============ ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 1 - § ªàëâì UDP-᮪¥â. ===========
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx = åí­¤« ᮪¥â 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ­¥¢¥à­ë© åí­¤«
* eax = 0 - ãᯥ譮
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* ’¥ªãé ï ॠ«¨§ æ¨ï ­¥ § ªà뢠¥â  ¢â®¬ â¨ç¥áª¨ ¢á¥ ᮪¥âë ¯®â®ª 
¯à¨ ¥£® § ¢¥à襭¨¨. ‚ ç áâ­®áâ¨, ­¥ á«¥¤ã¥â ¯à¨¡¨¢ âì ¯®â®ª
á ªã祩 ®âªàëâëå ᮪¥â®¢ - ¡ã¤¥â ãâ¥çª  à¥áãàᮢ.
 
======================================================================
============== ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 2 - ®¯à®á ᮪¥â . ==============
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = åí­¤« ᮪¥â 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ç¨á«® ¯®«ã祭­ëå ¡ ©â, 0 ¤«ï ­¥¢¥à­®£® åí­¤« 
* ebx à §àãè ¥âáï
 
======================================================================
======== ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 3 - ¯à®ç¨â âì ¡ ©â ¨§ ᮪¥â . ========
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 3 - ­®¬¥à ¯®¤ä㭪樨
* ecx = åí­¤« ᮪¥â 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¥á«¨ ­¥â ¯à¨­ïâëå ¤ ­­ëå ¨«¨ 㪠§ ­ ­¥¢¥à­ë© åí­¤«:
eax=0, bl=0, ¯à®ç¨¥ ¡ ©âë ebx à §àãè îâáï
* ¥á«¨ ¡ë«¨ ¯à¨­ïâë¥ ¤ ­­ë¥: eax=ç¨á«® ®áâ ¢è¨åáï ¡ ©â
(¢®§¬®¦­®, 0), bl=¯à®ç¨â ­­ë© ¡ ©â, ¯à®ç¨¥ ¡ ©âë ebx à §àãè îâáï
 
======================================================================
========== ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 4 - § ¯¨á âì ¢ UDP-᮪¥â. ==========
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 4 - ­®¬¥à ¯®¤ä㭪樨
* ecx = åí­¤« ᮪¥â 
* edx = ç¨á«® ¡ ©â ¤«ï § ¯¨á¨
* esi = 㪠§ â¥«ì ­  ¤ ­­ë¥ ¤«ï § ¯¨á¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0xffffffff - ®è¨¡ª  (­¥¢¥à­ë© åí­¤« ¨«¨ ­¥¤®áâ â®ç­® ¯ ¬ïâ¨)
* eax = 0 - ãᯥ譮
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* —¨á«® ¡ ©â ¤«ï § ¯¨á¨ ­¥ ¬®¦¥â ¯à¥¢ëè âì 1500-28, å®âï
ᮮ⢥âáâ¢ãî饩 ¯à®¢¥àª¨ ­¥ ¤¥« ¥âáï.
 
======================================================================
============ ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 5 - ®âªàëâì TCP-᮪¥â. ===========
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
* ecx = «®ª «ì­ë© ¯®àâ (ãç¨â뢠¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®),
ecx = 0 - ¯à¥¤®áâ ¢¨âì á¨á⥬¥ ¢ë¡®à «®ª «ì­®£® ¯®àâ 
* edx = 㤠«ñ­­ë© ¯®àâ (ãç¨â뢠¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®)
* esi = 㤠«ñ­­ë© IP
* edi = ०¨¬ ®âªàëâ¨ï: SOCKET_PASSIVE=0 ¨«¨ SOCKET_ACTIVE=1
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 = 0xFFFFFFFF - ®è¨¡ª ; ebx à §àãè ¥âáï
* eax = åí­¤« ᮪¥â  (­¥ª®â®à®¥ ç¨á«®, ®¤­®§­ ç­® ¨¤¥­â¨ä¨æ¨àãî饥
᮪¥â ¨ ¨¬¥î饥 á¬ë᫠⮫쪮 ¤«ï á¨á⥬ë) - ãᯥ譮;
ebx à §àãè ¥âáï
 
======================================================================
====== ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 6 - ¯®«ãç¨âì á®áâ®ï­¨¥ TCP-᮪¥â . =====
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 6 - ­®¬¥à ¯®¤ä㭪樨
* ecx = åí­¤« ᮪¥â 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 ¤«ï ­¥¢¥à­®£® ᮪¥â  ¨«¨ áâ âãá: ®¤­® ¨§
* TCB_LISTEN = 1
* TCB_SYN_SENT = 2
* TCB_SYN_RECEIVED = 3
* TCB_ESTABLISHED = 4
* TCB_FIN_WAIT_1 = 5
* TCB_FIN_WAIT_2 = 6
* TCB_CLOSE_WAIT = 7
* TCB_CLOSING = 8
* TCB_LAST_ASK = 9
* TCB_TIME_WAIT = 10
* TCB_CLOSED = 11
* ebx à §àãè ¥âáï
 
======================================================================
========== ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 7 - § ¯¨á âì ¢ TCP-᮪¥â. ==========
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 7 - ­®¬¥à ¯®¤ä㭪樨
* ecx = åí­¤« ᮪¥â 
* edx = ç¨á«® ¡ ©â ¤«ï § ¯¨á¨
* esi = 㪠§ â¥«ì ­  ¤ ­­ë¥ ¤«ï § ¯¨á¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0xffffffff - ®è¨¡ª  (­¥¢¥à­ë© åí­¤« ¨«¨ ­¥¤®áâ â®ç­® ¯ ¬ïâ¨)
* eax = 0 - ãᯥ譮
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* —¨á«® ¡ ©â ¤«ï § ¯¨á¨ ­¥ ¬®¦¥â ¯à¥¢ëè âì 1500-40,
å®âï ᮮ⢥âáâ¢ãî饩 ¯à®¢¥àª¨ ­¥ ¤¥« ¥âáï.
 
======================================================================
============ ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 8 - § ªàëâì TCP-᮪¥â. ===========
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 8 - ­®¬¥à ¯®¤ä㭪樨
* ecx = åí­¤« ᮪¥â 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ®è¨¡ª  (­¥¢¥à­ë© åí­¤« ¨«¨
­¥¤®áâ â®ç­® ¯ ¬ï⨠¤«ï ¯ ª¥â  § ªàëâ¨ï ᮪¥â )
* eax = 0 - ãᯥ譮
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* ’¥ªãé ï ॠ«¨§ æ¨ï ­¥ § ªà뢠¥â  ¢â®¬ â¨ç¥áª¨ ¢á¥ ᮪¥âë ¯®â®ª 
¯à¨ ¥£® § ¢¥à襭¨¨. ‚ ç áâ­®áâ¨, ­¥ á«¥¤ã¥â ¯à¨¡¨¢ âì ¯®â®ª
á ªã祩 ®âªàëâëå ᮪¥â®¢ - ¡ã¤¥â ãâ¥çª  à¥áãàᮢ.
 
======================================================================
== ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 9 - ¯à®¢¥à¨âì, ᢮¡®¤¥­ «¨ «®ª «ì­ë© ¯®àâ. =
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 9 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­®¬¥à «®ª «ì­®£® ¯®àâ  (¨á¯®«ì§ãîâáï ⮫쪮 ¬« ¤è¨¥ 16 ¡¨â)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ¯®à⠨ᯮ«ì§ã¥âáï
* eax = 1 - ¯®àâ ᢮¡®¤¥­
* ebx à §àãè ¥âáï
 
======================================================================
==== ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 10 - ¯®«ãç¨âì áâ âãá ª ¡¥«ï Ethernet. ====
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 10 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* al = -1 - ¤à ©¢¥à á¥â¥¢®© ª àâë ­¥ § £à㦥­ ¨«¨
­¥ ¯®¤¤¥à¦¨¢ ¥â íâã äã­ªæ¨î
* al = 0 - ª ¡¥«ì ­¥ ¯®¤ª«îçñ­
* al = 1 - ª ¡¥«ì ¯®¤ª«îçñ­
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* ’¥ªãé ï ॠ«¨§ æ¨ï ï¤à  ¯®¤¤¥à¦¨¢ ¥â íâã äã­ªæ¨î
⮫쪮 ¤«ï á¥â¥¢ëå ª àâ RTL8139.
 
======================================================================
==== ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 11 - ¯à®ç¨â âì ¤ ­­ë¥ á¥â¥¢®£® á⥪ . ====
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 11 - ­®¬¥à ¯®¤ä㭪樨
* ecx = åí­¤« ᮪¥â 
* edx = 㪠§ â¥«ì ­  ¡ãä¥à
* esi = ç¨á«® ¡ ©â ¤«ï ç⥭¨ï;
* esi = 0 - ç¨â âì ¢á¥ ¤ ­­ë¥ (¬ ªá¨¬ã¬ 4096 ¡ ©â)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ç¨á«® ¯à®ç¨â ­­ëå ¡ ©â (0 ¯à¨ ­¥¢¥à­®¬ åí­¤«¥)
* ebx à §àãè ¥âáï
 
======================================================================
”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 255 - ®â« ¤®ç­ ï ¨­ä®à¬ æ¨ï á¥â¥¢®£® ¤à ©¢¥à .
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 255 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ⨯ § ¯à è¨¢ ¥¬®© ¨­ä®à¬ æ¨¨ (ᬮâਠ­¨¦¥)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = § ¯à®è¥­­ ï ¨­ä®à¬ æ¨ï
* ebx à §àãè ¥âáï
‚®§¬®¦­ë¥ §­ ç¥­¨ï ecx:
* 100: ¤«¨­  ®ç¥à¥¤¨ 0 (empty queue)
* 101: ¤«¨­  ®ç¥à¥¤¨ 1 (ip-out queue)
* 102: ¤«¨­  ®ç¥à¥¤¨ 2 (ip-in queue)
* 103: ¤«¨­  ®ç¥à¥¤¨ 3 (net1out queue)
* 200: ç¨á«® í«¥¬¥­â®¢ ¢ â ¡«¨æ¥ ARP
* 201: à §¬¥à â ¡«¨æë ARP (¢ í«¥¬¥­â å) (20 ¢ ⥪ã饩 ¢¥àᨨ)
* 202: ¯à®ç¨â âì í«¥¬¥­â edx â ¡«¨æë ARP ¢® ¢à¥¬¥­­ë© ¡ãä¥à, ®âªã¤ 
¡¥àãâ ¨­ä®à¬ æ¨î 5 ¯®á«¥¤ãîé¨å ⨯®¢;
¢ í⮬ á«ãç ¥ eax ­¥®¯à¥¤¥«ñ­
* 203: IP- ¤à¥á, § ¯®¬­¥­­ë© ⨯®¬ 202
* 204: áâ à襥 dword MAC- ¤à¥á , § ¯®¬­¥­­®£® ⨯®¬ 202
* 205: ¬« ¤è¥¥ word MAC- ¤à¥á , § ¯®¬­¥­­®£® ⨯®¬ 202
* 206: á«®¢® áâ âãá , § ¯®¬­¥­­®¥ ⨯®¬ 202
* 207: á«®¢® ttl, § ¯®¬­¥­­®¥ ⨯®¬ 202
* 2: ®¡é¥¥ ç¨á«® ¯®«ã祭­ëå IP-¯ ª¥â®¢
* 3: ®¡é¥¥ ç¨á«® ¯¥à¥¤ ­­ëå IP-¯ ª¥â®¢
* 4: ®¡é¥¥ ç¨á«® ᤠ¬¯«¥­­ëå ¯®«ã祭­ëå ¯ ª¥â®¢
* 5: ®¡é¥¥ ç¨á«® ¯®«ã祭­ëå ARP-¯ ª¥â®¢
* 6: áâ âãá ¤à ©¢¥à  ¯ ª¥â®¢, 0=­¥ ªâ¨¢¥­,
­¥­ã«¥¢®¥ §­ ç¥­¨¥= ªâ¨¢¥­
 
======================================================================
====================== ”ã­ªæ¨ï 55, ¯®¤äã­ªæ¨ï 55 =====================
==========  ç âì ¯à®¨£à뢠âì ¤ ­­ë¥ ­  ¢áâ஥­­®¬ ᯨª¥à¥. ==========
======================================================================
 à ¬¥âàë:
* eax = 55 - ­®¬¥à ä㭪樨
* ebx = 55 - ­®¬¥à ¯®¤ä㭪樨
* esi = 㪠§ â¥«ì ­  ¤ ­­ë¥
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 55 - ®è¨¡ª  (ᯨª¥à ®âª«îçñ­ ¨«¨ § ­ïâ)
„ ­­ë¥ - íâ® ¬ áᨢ í«¥¬¥­â®¢ ¯¥à¥¬¥­­®© ¤«¨­ë.
”®à¬ â ª ¦¤®£® í«¥¬¥­â  ®¯à¥¤¥«ï¥âáï ¯¥à¢ë¬ ¡ ©â®¬:
* 0 = ª®­¥æ ¤ ­­ëå
* 1..0x80 = § ¤ ñâ ¤«¨â¥«ì­®áâì §¢ãç ­¨ï ¢ á®âëå ¤®«ïå ᥪ㭤ë
­®âë, ®¯à¥¤¥«ï¥¬®© ­¥¯®á।á⢥­­ë¬ §­ ç¥­¨¥¬ ç áâ®âë
* á«¥¤ãî饥 á«®¢® (2 ¡ ©â ) ᮤ¥à¦¨â ¤¥«¨â¥«ì ç áâ®âë;
ç áâ®â  ®¯à¥¤¥«ï¥âáï ª ª 1193180/divider
* 0x81 = invalid
* 0x82..0xFF = ­®â , ®¯à¥¤¥«ï¥¬ ï ®ªâ ¢®© ¨ ­®¬¥à®¬:
* ¤«¨â¥«ì­®áâì ¢ á®âëå ¤®«ïå ᥪ㭤ë = (¯¥à¢ë© ¡ ©â)-0x81
* ¯à¨áãâáâ¢ã¥â ¥éñ ®¤¨­ ¡ ©â;
* (¢â®à®© ¡ ©â)=0xFF - ¯ ã§ 
* ¨­ ç¥ ®­ ¨¬¥¥â ¢¨¤ a*0x10+b, £¤¥ b=­®¬¥à ­®âë ¢ ®ªâ ¢¥ ®â 1
¤® 12, a=­®¬¥à ®ªâ ¢ë (áç¨â ï á 0)
‡ ¬¥ç ­¨ï:
* ¨é ­¨¥ ᯨª¥à®¬ ¬®¦¥â ¡ëâì § ¯à¥é¥­®/à §à¥è¥­® ¯®¤ä㭪樥© 8
ä㭪樨 18.
* ”ã­ªæ¨ï ¢®§¢à é ¥â ã¯à ¢«¥­¨¥, á®®¡é¨¢ ªã¤  á«¥¤ã¥â ¨­ä®à¬ æ¨î
® § ¯à®á¥. ‘ ¬® ¯à®¨£à뢠­¨¥ ¨¤ñâ ­¥§ ¢¨á¨¬® ®â ¯à®£à ¬¬ë.
* „ ­­ë¥ ¤®«¦­ë á®åà ­ïâìáï ¢ ¯ ¬ï⨠¯® ªà ©­¥© ¬¥à¥
¤® ª®­æ  ¯à®¨£à뢠­¨ï.
 
======================================================================
======================= ”ã­ªæ¨ï 57 - PCI BIOS. =======================
======================================================================
 à ¬¥âàë:
* eax = 57 - ­®¬¥à ä㭪樨
* ebp ᮮ⢥âáâ¢ã¥â ॣ¨áâàã al ¢ ᯥæ¨ä¨ª æ¨¨ PCI BIOS
* ®áâ «ì­ë¥ ॣ¨áâàë - ¯® ᯥæ¨ä¨ª æ¨¨ PCI BIOS
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* CF ­¥ ®¯à¥¤¥«ñ­
* ®áâ «ì­ë¥ ॣ¨áâàë - ¯® ᯥæ¨ä¨ª æ¨¨ PCI BIOS
‡ ¬¥ç ­¨ï:
* Œ­®£¨å १ã«ìâ â®¢ í⮩ ä㭪樨 ¬®¦­® â ª¦¥ ¤®¡¨âìáï ¢ë§®¢®¬
ᮮ⢥âáâ¢ãîé¨å ¯®¤ä㭪権 ä㭪樨 62.
* ”ã­ªæ¨ï ¢ë§ë¢ ¥â à áè¨à¥­¨¥ PCI32 BIOS, ¤®ªã¬¥­â¨à®¢ ­­®¥,
­ ¯à¨¬¥à, ¢ http://alpha1.dyns.net/files/PCI/bios21.pdf.
* …᫨ BIOS ­¥ ¯®¤¤¥à¦¨¢ ¥â íâ® à áè¨à¥­¨¥, ¯®¢¥¤¥­¨¥ ä㭪樨
í¬ã«¨àã¥âáï (ç¥à¥§  ­ «®£¨ ¯®¤ä㭪権 ä㭪樨 62 ०¨¬  ï¤à ).
 
======================================================================
============== ”ã­ªæ¨ï 58 - à ¡®â  á ä ©«®¢®© á¨á⥬®©. ==============
======================================================================
 à ¬¥âàë:
* eax = 58
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮; ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ¢ § ¢¨á¨¬®á⨠®â ¯®¤ä㭪樨 ¬®¦¥â ¢®§¢à é âìáï §­ ç¥­¨¥ ¨
¢ ¤à㣨å ॣ¨áâà å
Ž¡é¨© ä®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ­®¬¥à ¡«®ª 
* +8: dword: à §¬¥à
* +12 = +0xC: dword: 㪠§ â¥«ì ­  ¤ ­­ë¥
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¯ ¬ïâì ¤«ï à ¡®âë á¨á⥬ë
(4096 ¡ ©â)
* +20 = +0x14: n db: ASCIIZ-áâப  á ¨¬¥­¥¬ ä ©« 
“â®ç­¥­¨ï - ¢ ¤®ªã¬¥­â æ¨¨ ­  ᮮ⢥âáâ¢ãîéãî ¯®¤äã­ªæ¨î.
ˆ¬ï ä ©«  ­¥çã¢á⢨⥫쭮 ª ॣ¨áâàã « â¨­áª¨å ¡ãª¢,
àãá᪨¥ ¡ãª¢ë ¤®«¦­ë ¡ëâì § £« ¢­ë¬¨.
”®à¬ â ¨¬¥­¨ ä ©« :
/base/number/dir1/dir2/.../dirn/file,
£¤¥ /base/number ¨¤¥­â¨ä¨æ¨àã¥â ãáâனá⢮, ­  ª®â®à®¬ ¨é¥âáï ä ©«:
®¤­® ¨§
* /RD/1 = /RAMDISK/1 ¤«ï ¤®áâ㯠 ª à ¬¤¨áªã
* /FD/1 = /FLOPPYDISK/1 ¤«ï ¤®áâ㯠 ª ¯¥à¢®¬ã ä«®¯¯¨-¤¨áª®¢®¤ã,
/FD/2 = /FLOPPYDISK/2 ¤«ï ¢â®à®£® ä«®¯¯¨-¤¨áª®¢®¤ 
* /HD/x = /HARDDISK/x - ãáâ à¥¢è¨© ¢ à¨ ­â ¤®áâ㯠 ª ¦ñá⪮¬ã ¤¨áªã
(¢ í⮬ á«ãç ¥ ¡ §  ®¯à¥¤¥«ï¥âáï ¯®¤ä㭪樥© 7 ä㭪樨 21),
x - ­®¬¥à à §¤¥«  (áç¨â ï á 1)
* /HD0/x, /HD1/x, /HD2/x, /HD3/x ¤«ï ¤®áâ㯠 ᮮ⢥âá⢥­­®
ª ãáâனá⢠¬ IDE0 (Primary Master), IDE1 (Primary Slave),
IDE2 (Secondary Master), IDE3 (Secondary Slave);
x - ­®¬¥à à §¤¥«  ­  ¢ë¡à ­­®¬ ¢¨­ç¥áâ¥à¥, ¨§¬¥­ï¥âáï ®â 1 ¤® 255
(­  ª ¦¤®¬ ¨§ ¢¨­ç¥áâ¥à®¢ ­ã¬¥à æ¨ï ­ ç¨­ ¥âáï á 1)
‡ ¬¥ç ­¨ï:
* ‚ ¯¥à¢ëå ¤¢ãå á«ãç ïå ¤®¯ã᪠¥âáï ¨á¯®«ì§®¢ ­¨¥ FIRST ¢¬¥áâ® 1,
SECOND ¢¬¥áâ® 2, ­® ¨á¯®«ì§®¢ âì íâã ¢®§¬®¦­®áâì
­¥ ४®¬¥­¤ã¥âáï ¤«ï 㤮¡á⢠ ¯¥à¥å®¤  ­  ¡ã¤ã騥 à áè¨à¥­¨ï.
*  ª« ¤ë¢ ¥âáï ®£à ­¨ç¥­¨¥ n<=39.
* ˆ¬¥­  ¯ ¯®ª ¨ ä ©«  dir1,...,dirn,file ¤®«¦­ë ¡ëâì ¢ ä®à¬ â¥ 8.3:
¨¬ï ­¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥­¨¥ ­¥ ¡®«¥¥ 3 ᨬ¢®«®¢.
•¢®áâ®¢ë¥ ¯à®¡¥«ë ¨£­®à¨àãîâáï. „àã£¨å ¯à®¡¥«®¢ ¡ëâì ­¥ ¤®«¦­®.
…᫨ ¨¬ï § ­¨¬ ¥â ஢­® 8 ᨬ¢®«®¢, â®çªã ¬®¦­® ®¯ãáâ¨âì
(å®âï ¯®«ì§®¢ âìáï í⨬ ­¥ ४®¬¥­¤ã¥âáï ¤«ï 㤮¡á⢠ ¯¥à¥å®¤ 
­  ¡ã¤ã騥 à áè¨à¥­¨ï).
* ”ã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª ­  à ¬¤¨áª¥.
à¨¬¥àë:
* '/RAMDISK/FIRST/KERNEL.ASM',0
'/rd/1/kernel.asm',0
* '/HD0/1/kernel.asm',0
* '/hd0/1/menuet/pics/tanzania.bmp',0
„®áâã¯­ë¥ ¯®¤ä㭪樨:
* ¯®¤äã­ªæ¨ï 0 - ç⥭¨¥ ä ©« /¯ ¯ª¨
* ¯®¤äã­ªæ¨ï 8 - LBA-ç⥭¨¥ á ãáâனá⢠
* ¯®¤äã­ªæ¨ï 15 - ¯®«ã祭¨¥ ¨­ä®à¬ æ¨¨ ® ä ©«®¢®© á¨á⥬¥
 
======================================================================
========== ”ã­ªæ¨ï 58, ¯®¤äã­ªæ¨ï 0 - ¯à®ç¨â âì ä ©«/¯ ¯ªã. ==========
======================================================================
 à ¬¥âàë:
* eax = 58
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 0 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ­®¬¥à ¡«®ª  ¤«ï ç⥭¨ï (áç¨â ï á 0)
* +8: dword: ç¨á«® ¡«®ª®¢ ¤«ï ç⥭¨ï
* +12 = +0xC: dword: 㪠§ â¥«ì ­  ¡ãä¥à, ªã¤  ¡ã¤ãâ § ¯¨á ­ë ¤ ­­ë¥
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë
(4096 ¡ ©â)
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx = à §¬¥à ä ©«  (¢ ¡ ©â å) ¨«¨
-1=0xffffffff, ¥á«¨ ä ©« ­¥ ­ ©¤¥­
‡ ¬¥ç ­¨ï:
*  §¬¥à ¡«®ª  - 512 ¡ ©â.
* â  äã­ªæ¨ï ãáâ à¥« , ¤«ï ç⥭¨ï ä ©«®¢ ¨á¯®«ì§ã©â¥ ¯®¤äã­ªæ¨î 0
ä㭪樨 70, ¤«ï ç⥭¨ï ¯ ¯®ª - ¯®¤äã­ªæ¨î 1 ä㭪樨 70.
* ”ã­ªæ¨ï ¯®§¢®«ï¥â ç¨â âì ᮤ¥à¦¨¬®¥ ¯ ¯ª¨. ˆ§ ä ©«®¢ëå á¨á⥬
¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 FAT. ”®à¬ â FAT-¯ ¯ª¨ ®¯¨á ­ ¢ «î¡®©
¤®ªã¬¥­â æ¨¨ ¯® FAT.
*  §¬¥à ¯ ¯ª¨ ®¯à¥¤¥«ï¥âáï ¯® à §¬¥àã 楯®çª¨ ª« áâ¥à®¢ ¢ FAT.
* …᫨ ä ©« ª®­ç¨«áï à ­ìè¥, 祬 ¡ë« ¯à®ç¨â ­ ¯®á«¥¤­¨© § ¯à®è¥­­ë©
¡«®ª, â® äã­ªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥à­ñâ
eax=6 (EOF).
* ”ã­ªæ¨ï ¯®§¢®«ï¥â ç¨â âì ª®à­¥¢ë¥ ¯ ¯ª¨ /rd/1,/fd/x,/hd[n]/x, ­®
¢ ¯¥à¢ëå ¤¢ãå á«ãç ïå ⥪ãé ï ॠ«¨§ æ¨ï ­¥ á«¥¤ã¥â
ãáâ ­®¢«¥­­ë¬ ¯à ¢¨« ¬:
¤«ï /rd/1:
* ¥á«¨ 㪠§ ­® 0 ¡«®ª®¢ ¤«ï ç⥭¨ï, áç¨â ¥âáï,
çâ® § ¯à è¨¢ ¥âáï 1;
* ¥á«¨ § ¯à è¨¢ ¥âáï ¡®«ìè¥ 14 ¡«®ª®¢ ¨«¨ ­ ç «ì­ë© ¡«®ª
­¥ ¬¥­ìè¥ 14-£®, â® ¢®§¢à é ¥âáï eax=5 (not found) ¨ ebx=-1;
* à §¬¥à ª®à­¥¢®£® ª â «®£  à ¬¤¨áª  = 14 ¡«®ª®¢,
0x1C00=7168 ¡ ©â; ­® ¢®§¢à é ¥âáï ebx=0
(§  ¨áª«î祭¨¥¬ á«ãç ï ¯à¥¤ë¤ã饣® ¯ã­ªâ );
* ª ª ­¨ áâà ­­®, ¬®¦­® ¯à®ç¨â âì 14-© ¡«®ª (â ¬, ¢®®¡é¥ £®¢®àï,
¬ãá®à - ­ ¯®¬¨­ î, áçñâ ¢¥¤ñâáï á 0);
* ¥á«¨ ¡ë« § ¯à®è¥­ å®âï ¡ë ®¤¨­ ¡«®ª á ­®¬¥à®¬, ­¥ ¬¥­ì訬 14,
â® ¢®§¢à é ¥âáï eax=6(EOF); ¨­ ç¥ eax=0.
„«ï /fd/x:
* ¥á«¨ ­ ç «ì­ë© ¡«®ª ­¥ ¬¥­ìè¥ 14-£®, â® ¢®§¢à é ¥âáï
eax=5 (not found) ¨ ebx=0;
* ªáâ â¨ £®¢®àï, ä®à¬ â FAT12 ¤®¯ã᪠¥â ¤¨áª¥âë á à §¬¥à®¬
ª®à­¥¢®£® ª â «®£  ¬¥­ìè¥ ¨«¨ ¡®«ìè¥ 14 ¡«®ª®¢;
* ¯à®¢¥àª¨ ¤«¨­ë ­¥ ¤¥« ¥âáï;
* ¥á«¨ 㤠«®áì ¯à®ç¨â âì ¤ ­­ë¥ á ¤¨áª¥âë, ¢®§¢à é ¥âáï
eax=0,ebx=0; ¢ ¯à®â¨¢­®¬ á«ãç ¥ eax=10 (access denied), ebx=-1.
* ”ã­ªæ¨ï ®¡à ¡ â뢠¥â ç⥭¨¥ ᯥ樠«ì­ëå ¯ ¯®ª /,/rd,/fd,/hd[n];
­® १ã«ìâ â ­¥ ᮮ⢥âáâ¢ã¥â ®¦¨¤ ¥¬®¬ã
(¯® à ¡®â¥ á ®¡ëç­ë¬¨ ä ©« ¬¨/¯ ¯ª ¬¨), ­¥ á«¥¤ã¥â ãáâ ­®¢«¥­­ë¬
¯à ¢¨« ¬, ¬®¦¥â ¨§¬¥­¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à  ¨ ¯®â®¬ã
­¥ ®¯¨á뢠¥âáï. „«ï ¯®«ã祭¨ï ¨­ä®à¬ æ¨¨ ®¡ ®¡®à㤮¢ ­¨¨
¨á¯®«ì§ã©â¥ ¯®¤äã­ªæ¨î 11 ä㭪樨 18 ¨«¨
ç¨â ©â¥ ᮮ⢥âáâ¢ãî騥 ¯ ¯ª¨ ¯®¤ä㭪樥© 1 ä㭪樨 70.
 
======================================================================
========= ”ã­ªæ¨ï 58, ¯®¤äã­ªæ¨ï 8 - LBA-ç⥭¨¥ á ãáâனá⢠. ========
======================================================================
 à ¬¥âàë:
* eax = 58 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 8 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ­®¬¥à ¡«®ª  ¤«ï ç⥭¨ï (áç¨â ï á 0)
* +8: dword: ¨£­®à¨àã¥âáï (ãáâ ­ ¢«¨¢ ©â¥ ¢ 1)
* +12 = +0xC: dword: 㪠§ â¥«ì ­  ¡ãä¥à, ªã¤  ¡ã¤ãâ § ¯¨á ­ë ¤ ­­ë¥
(512 ¡ ©â)
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë
(4096 ¡ ©â)
* +20 = +0x14: ASCIIZ-¨¬ï ãáâனá⢠: ­¥çã¢á⢨⥫쭮 ª ॣ¨áâàã,
®¤­® ¨§ /rd/1 = /RamDisk/1, /hd/n = /HardDisk/n,
1<=n<=4 - ­®¬¥à ãáâனá⢠: 1=IDE0, ..., 4=IDE3.
‚¬¥áâ® æ¨äà ¤®¯ã᪠¥âáï, å®âï ¨ ­¥ ४®¬¥­¤ã¥âáï ¤«ï 㤮¡á⢠
¯¥à¥å®¤  ­  ¡ã¤ã騥 à áè¨à¥­¨ï,
¨á¯®«ì§®¢ ­¨¥ 'first','second','third','fourth'.
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¥á«¨ 㪠§ ­® ¨¬ï ãáâனá⢠ /hd/xxx, £¤¥ xxx ­¥ ­ å®¤¨âáï
¢ ᯨ᪥ ¢ëè¥:
* eax = ebx = 1
* ¥á«¨ 㪠§ ­® ­¥¯à ¢¨«ì­®¥ ¨¬ï ãáâனá⢠
(§  ¨áª«î祭¨¥¬ ¯à¥¤ë¤ã饣® á«ãç ï):
* eax = 5
* ebx ­¥ ¬¥­ï¥âáï
* ¥á«¨ LBA-¤®áâ㯠§ ¯à¥éñ­ ¯®¤ä㭪樥© 11 ä㭪樨 21:
* eax = 2
* ebx à §àãè ¥âáï
* ¤«ï à ¬¤¨áª : ¯®¯ë⪠ ç⥭¨ï ¡«®ª  §  ¯à¥¤¥« ¬¨ à ¬¤¨áª 
(18*2*80 ¡«®ª®¢) ¯à¨¢®¤¨â ª
* eax = 3
* ebx = 0
* ¯à¨ ãᯥ譮¬ ç⥭¨¨:
* eax = ebx = 0
‡ ¬¥ç ­¨ï:
*  §¬¥à ¡«®ª  - 512 ¡ ©â; ç¨â ¥âáï ®¤¨­ ¡«®ª.
* ¥ á«¥¤ã¥â ¯®« £ âìáï ­  ¢®§¢à é ¥¬®¥ §­ ç¥­¨¥,
®­® ¬®¦¥â ¨§¬¥­¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå.
* ’ॡã¥âáï, çâ®¡ë ¡ë« à §à¥èñ­ LBA-¤®áâ㯠ª ãáâனá⢠¬
¯®¤ä㭪樥© 11 ä㭪樨 21. “§­ âì íâ® ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樥© 11 ä㭪樨 26.
* LBA-ç⥭¨¥ ¤¨áª¥âë ­¥ ¯®¤¤¥à¦¨¢ ¥âáï.
* ”ã­ªæ¨ï áç¨â뢠¥â ¤ ­­ë¥ 䨧¨ç¥áª®£® ¦ñá⪮£® ¤¨áª ;
¥á«¨ ¯® ª ª¨¬-â® ¯à¨ç¨­ ¬ ­ã¦­ë ¤ ­­ë¥ ª®­ªà¥â­®£® à §¤¥« ,
¯à¨¤ñâáï ®¯à¥¤¥«ïâì ­ ç «ì­ë© ᥪâ®à í⮣® à §¤¥« 
(«¨¡® ­ ¯àï¬ãî ç¥à¥§ MBR, «¨¡® ¨§ à áè¨à¥­­®© áâàãªâãàë,
¢®§¢à é ¥¬®© ⮩ ¦¥ ¯®¤ä㭪樥© 11 ä㭪樨 18).
* ”ã­ªæ¨ï ­¥ ¯à®¢¥àï¥â ª®¤ ®è¨¡ª¨ ¦ñá⪮£® ¤¨áª , â ª çâ® § ¯à®á
­¥áãé¥áâ¢ãî饣® ᥪâ®à  ¢áñ à ¢­® çâ®-â® ¯à®ç¨â ¥â
(¢¥à®ïâ­¥¥ ¢á¥£®, ­ã«¨, ­® íâ® ®¯à¥¤¥«ï¥âáï ãáâனá⢮¬) ¨
íâ® ¡ã¤¥â áç¨â âìáï ãᯥ宬 (eax=0).
 
======================================================================
= ”ã­ªæ¨ï 58, ¯®¤äã­ªæ¨ï 15 - ¯®«ãç¨âì ¨­ä®à¬ æ¨î ® ä ©«®¢®© á¨á⥬¥.
======================================================================
 à ¬¥âàë:
* eax = 58 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 15 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ¨£­®à¨àã¥âáï
* +8: dword: ¨£­®à¨àã¥âáï
* +12 = +0xC: dword: ¨£­®à¨àã¥âáï
* +16 = +0x10: dword: ¨£­®à¨àã¥âáï
* +20 = +0x14: (¯à®¢¥àï¥âáï ⮫쪮 ¢â®à®© ᨬ¢®«, áࠧ㠯®á«¥ á«íè )
/rd=/RAMDISK ¨«¨ /hd=/HARDDISK
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¥á«¨ ¢â®à®© ᨬ¢®« ­¥ ¯à¨­ ¤«¥¦¨â ¬­®¦¥áâ¢ã {'r','R','h','H'}:
* eax = 3
* ebx = ecx = dword [fileinfo] = 0
* ¤«ï à ¬¤¨áª :
* eax = 0 (ãᯥå)
* ebx = ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ = 2847
* ecx = ç¨á«® ᢮¡®¤­ëå ª« áâ¥à®¢
* dword [fileinfo] = à §¬¥à ª« áâ¥à  = 512
* ¤«ï ¦ñá⪮£® ¤¨áª : ¡ §  ¨ à §¤¥« ®¯à¥¤¥«ïîâáï ¯®¤äã­ªæ¨ï¬¨ 7 ¨ 8
ä㭪樨 21:
* eax = 0 (ãᯥå)
* ebx = ®¡é¥¥ ç¨á«® ª« áâ¥à®¢
* ecx = ç¨á«® ᢮¡®¤­ëå ª« áâ¥à®¢
* dword [fileinfo] = à §¬¥à ª« áâ¥à  (¢ ¡ ©â å)
‡ ¬¥ç ­¨ï:
* ¥ 㤨¢«ï©â¥áì áâà ­­®¬ã à á¯®«®¦¥­¨î 4-£® ¢®§¢à é ¥¬®£®
¯ à ¬¥âà  - ª®£¤  ¯¨á «áï íâ®â ª®¤, ¯à¨ á¨á⥬­ëå ¢ë§®¢ å
¯à¨«®¦¥­¨î ¢®§¢à é «¨áì ⮫쪮 ॣ¨áâàë eax,ebx,ecx (¨§
pushad-áâàãªâãàë, ¯¥à¥¤ î饩áï ª ª  à£ã¬¥­â á¨á⥬­®© ä㭪樨).
’¥¯¥àì íâ® ¨á¯à ¢«¥­®, â ª çâ®, ¢®§¬®¦­®, ¨¬¥¥â á¬ëá« ¢®§¢à é âì
à §¬¥à ª« áâ¥à  ¢ edx, ¯®ª  íâã äã­ªæ¨î ­¥ ­ ç «¨ ¨á¯®«ì§®¢ âì.
* ‚®®¡é¥-â® ¥éñ áãé¥áâ¢ã¥â ¯®¤äã­ªæ¨ï 11 ä㭪樨 18, ¢®§¢à é îé ï
¨­ä®à¬ æ¨î ® ä ©«®¢®© á¨á⥬¥. ® à áè¨à¥­­®© â ¡«¨æ¥ ¤¨áª®¢®©
¯®¤á¨áâ¥¬ë ¬®¦­® ®¯à¥¤¥«¨âì à §¬¥à ª« áâ¥à  (â ¬ ®­ åà ­¨âáï
¢ ᥪâ®à å) ¨ ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ ¤«ï ¦ñáâª¨å ¤¨áª®¢.
 
======================================================================
=========== ”ã­ªæ¨ï 60 - Inter Process Communication (IPC). ==========
======================================================================
IPC ¯à¨¬¥­ï¥âáï ¤«ï ¯®áë«®ª á®®¡é¥­¨© ®â ®¤­®£® ¯à®æ¥áá /¯®â®ª 
¤à㣮¬ã. à¨ í⮬ á«¥¤ã¥â ¯à¥¤¢ à¨â¥«ì­® ¤®£®¢®à¨âìáï ® ⮬, ª ª
¨­â¥à¯à¥â¨à®¢ âì ª®­ªà¥â­®¥ á®®¡é¥­¨¥.
 
-------- ®¤äã­ªæ¨ï 1 - ãáâ ­®¢¨âì ®¡« áâì ¤«ï ¯®«ã祭¨ï IPC ---------
‚ë§ë¢ ¥âáï ¯à®æ¥áᮬ-¯à¨ñ¬­¨ª®¬.
 à ¬¥âàë:
* eax = 60 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¡ãä¥à
* edx = à §¬¥à ¡ãä¥à 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ¢á¥£¤  ãᯥ譮
”®à¬ â IPC-¡ãä¥à :
* +0: dword: ¥á«¨ §¤¥áì ­¥ 0, â® ¡ãä¥à áç¨â ¥âáï § ¡«®ª¨à®¢ ­­ë¬;
¡«®ª¨àã©â¥/à §¡«®ª¨àã©â¥ ¡ãä¥à, ª®£¤  ¢ë á ­¨¬  ªâ¨¢­® à ¡®â ¥â¥
¨ ¢ ¬ ­ ¤®, çâ®¡ë ¨§¢­¥ ­¥ ¨§¬¥­ï«¨áì ¤ ­­ë¥ ¡ãä¥à 
(­¥ ¯®áâ㯠«¨ ­®¢ë¥ á®®¡é¥­¨ï)
* +4: dword: § ­ïâ® ¬¥áâ  ¢ ¡ãä¥à¥ (¢ ¡ ©â å)
* +8: ¯¥à¢®¥ á®®¡é¥­¨¥
* +8+n: ¢â®à®¥ á®®¡é¥­¨¥
* ...
”®à¬ â á®®¡é¥­¨ï:
* +0: dword: PID ¯à®æ¥áá /¯®â®ª , ¯®á« ¢è¥£® á®®¡é¥­¨¥
* +4: dword: ¤«¨­  á®®¡é¥­¨ï (­¥ áç¨â ï íâ®â § £®«®¢®ª)
* +8: n*byte: ¤ ­­ë¥ á®®¡é¥­¨ï
 
--------------- ®¤äã­ªæ¨ï 2 - ¯®á« âì á®®¡é¥­¨¥ IPC. ----------------
‚ë§ë¢ ¥âáï ¯à®æ¥áᮬ-¨­¨æ¨ â®à®¬.
 à ¬¥âàë:
* eax = 60 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = PID ¯à¨ñ¬­¨ª 
* edx = 㪠§ â¥«ì ­  ¤ ­­ë¥ á®®¡é¥­¨ï
* esi = ¤«¨­  á®®¡é¥­¨ï (¢ ¡ ©â å)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ¯à¨ñ¬­¨ª ­¥ ®¯à¥¤¥«¨« ¡ãä¥à ¤«ï IPC-á®®¡é¥­¨©
(¬®¦¥â ¡ëâì, ¥éñ ­¥ ãᯥ«,   ¬®¦¥â ¡ëâì, íâ® ­¥ â®â ¯®â®ª,
ª®â®àë© ­ã¦¥­)
* eax = 2 - ¯à¨ñ¬­¨ª § ¡«®ª¨à®¢ « IPC-¡ãä¥à;
¯®¯à®¡ã©â¥ ­¥¬­®£® ¯®¤®¦¤ âì
* eax = 3 - ¯¥à¥¯®«­¥­¨¥ IPC-¡ãä¥à  ¯à¨ñ¬­¨ª 
* eax = 4 - ¯à®æ¥áá /¯®â®ª  á â ª¨¬ PID ­¥ áãé¥áâ¢ã¥â
‡ ¬¥ç ­¨ï:
* ‘¨á⥬  áࠧ㠯®á«¥ § ¯¨á¨ IPC-á®®¡é¥­¨ï ¢ ¡ãä¥à ¯®áë« ¥â
¯®â®ªã-¯à¨ñ¬­¨ªã ᮡë⨥ á ª®¤®¬ 7 (á¬. ª®¤ë ᮡë⨩).
 
======================================================================
=== ”ã­ªæ¨ï 61 - ¯®«ãç¨âì ¯ à ¬¥âàë ¤«ï ¯àאַ£® ¤®áâ㯠 ª £à ä¨ª¥. ===
======================================================================
à®£à ¬¬¥ ¤®áâã¯­ë ¤ ­­ë¥ £à ä¨ç¥áª®£® íªà ­  (®¡« áâì ¯ ¬ïâ¨, ª®â®à ï
ᮡá⢥­­® ¨ ®â®¡à ¦ ¥â ᮤ¥à¦¨¬®¥ íªà ­ ) ­ ¯àï¬ãî ¡¥§ ¢ë§®¢®¢
á¨á⥬­ëå ä㭪権 ç¥à¥§ ᥫ¥ªâ®à gs:
mov eax, [gs:0]
¯®¬¥áâ¨â ¢ eax ¯¥à¢ë© dword ¡ãä¥à , ᮤ¥à¦ é¨© ¨­ä®à¬ æ¨î ® 梥â¥
«¥¢®© ¢¥àå­¥© â®çª¨ (¨, ¢®§¬®¦­®, æ¢¥â  ­¥áª®«ìª¨å á«¥¤ãîé¨å).
mov [gs:0], eax
¯à¨ à ¡®â¥ ¢ ०¨¬ å VESA c LFB
ãáâ ­®¢¨â 梥⠫¥¢®© ¢¥àå­¥© â®çª¨
(¨ ¢®§¬®¦­®, æ¢¥â  ­¥áª®«ìª¨å á«¥¤ãîé¨å).
„«ï ¨­â¥à¯à¥â æ¨¨ ¤ ­­ëå £à ä¨ç¥áª®£® íªà ­  âॡã¥âáï §­ ­¨¥
­¥ª®â®àëå ¯ à ¬¥â஢, ª®â®àë¥ ¢®§¢à é îâáï í⮩ ä㭪樥©.
‡ ¬¥ç ­¨ï:
*  à ¬¥âàë £à ä¨ª¨ ®ç¥­ì ।ª® ¬¥­ïîâáï ¯à¨ à ¡®â¥ á¨á⥬ë,
  ¨¬¥­­®, ⮫쪮 ¢ á«ãç ïå, ª®£¤  ¯®«ì§®¢ â¥«ì à ¡®â ¥â
á ¯à®£à ¬¬®© VRR.
* à¨ ¨§¬¥­¥­¨¨ ¢¨¤¥®à¥¦¨¬  á¨á⥬  ¯¥à¥à¨á®¢ë¢ ¥â ¢á¥ ®ª­ 
(ᮡë⨥ á ª®¤®¬ 1) ¨ ¯¥à¥à¨á®¢ë¢ ¥â ä®­ (ᮡë⨥ 5).
â¨ ¦¥ ᮡëâ¨ï ¯à®¨á室ïâ ¨ ¢ ¤à㣨å á«ãç ïå,
ª®â®àë¥ ¢áâà¥ç îâáï §­ ç¨â¥«ì­® ç é¥, 祬 ¨§¬¥­¥­¨¥ ¢¨¤¥®à¥¦¨¬ .
* à¨ à ¡®â¥ ¢ ¢¨¤¥®à¥¦¨¬ å á LFB ᥫ¥ªâ®à gs 㪠§ë¢ ¥â ­ 
ᮡá⢥­­® LFB, â ª çâ® ç⥭¨¥/§ ¯¨áì ¯® gs ¯à¨¢®¤ïâ
­¥¯®á।á⢥­­® ª ¨§¬¥­¥­¨î ᮤ¥à¦¨¬®£® íªà ­ . à¨ à ¡®â¥ ¢
¢¨¤¥®à¥¦¨¬ å ¡¥§ LFB gs 㪠§ë¢ ¥â ­  ­¥ª®â®àãî ®¡« áâì ¤ ­­ëå
ï¤à , ¯à¨çñ¬ ¢á¥ ä㭪樨 ¢ë¢®¤  ­  íªà ­ ¤®¡à®á®¢¥áâ­® ¢ë¯®«­ïîâ
¤¢®©­ãî à ¡®âã ¯® § ¯¨á¨ ­¥¯®á।á⢥­­® ­  íªà ­ ¨ ¯® § ¯¨á¨
¢ íâ®â ¡ãä¥à. ‚ १ã«ìâ â¥ ¯à¨ ç⥭¨¨ ᮤ¥à¦¨¬®£® í⮣® ¡ãä¥à 
१ã«ìâ âë ᮮ⢥âáâ¢ãîâ ᮤ¥à¦¨¬®¬ã íªà ­ 
(á, ¢®®¡é¥ £®¢®àï, ¡®«ì訬 æ¢¥â®¢ë¬ à §à¥è¥­¨¥¬),
  § ¯¨áì ¨£­®à¨àã¥âáï.
ˆáª«î祭¨¥¬ ï¥âáï ०¨¬ 320*200, ¤«ï ª®â®à®£® ¢ £« ¢­®¬ 横«¥
á¨á⥬­®£® ¯®â®ª  ¢ë¯®«­ï¥âáï ®¡­®¢«¥­¨¥ íªà ­  ¢ ᮮ⢥âá⢨¨
á ¤¢¨¦¥­¨ï¬¨ ªãàá®à  ¬ëè¨.
 
-------------------------  §à¥è¥­¨¥ íªà ­  --------------------------
 à ¬¥âàë:
* eax = 61 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = [à §à¥è¥­¨¥ ¯® ®á¨ x]*65536 + [à §à¥è¥­¨¥ ¯® ®á¨ y]
‡ ¬¥ç ­¨ï:
* Œ®¦­® ¨á¯®«ì§®¢ âì äã­ªæ¨î 14 á ãçñ⮬ ⮣®, çâ® ®­  ¢®§¢à é ¥â
à §¬¥àë ­  1 ¬¥­ìè¥. â® ¯®«­®áâìî íª¢¨¢ «¥­â­ë© ᯮᮡ.
 
------------------------ —¨á«® ¡¨â ­  ¯¨ªá¥«ì ------------------------
 à ¬¥âàë:
* eax = 61 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ç¨á«® ¡¨â ­  ¯¨ªá¥«ì (24 ¨«¨ 32)
 
------------------------ —¨á«® ¡ ©â ­  áâபã ------------------------
 à ¬¥âàë:
* eax = 61 - ­®¬¥à ä㭪樨
* ebx = 3 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ç¨á«® ¡ ©â, ª®â®à®¥ § ­¨¬ ¥â ®¤­  áâப  à §¢ñà⪨
(£®à¨§®­â «ì­ ï «¨­¨ï ­  íªà ­¥)
 
======================================================================
===== ”ã­ªæ¨ï 62, ¯®¤äã­ªæ¨ï 0 - ¯®«ãç¨âì ¢¥àá¨î PCI-¨­â¥à䥩á . =====
======================================================================
 à ¬¥âàë:
* eax = 62 - ­®¬¥à ä㭪樨
* bl = 0 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ­; ¨­ ç¥
* ah.al = ¢¥àá¨ï PCI-¨­â¥àä¥©á  (ah=¢¥àá¨ï, al=¯®¤¢¥àá¨ï)
* áâ à襥 á«®¢® eax ®¡­ã«¥­®
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì à §à¥èñ­ ­¨§ª®ã஢­¥¢ë© ¤®áâ㯠ª PCI
¤«ï ¯à¨«®¦¥­¨© ¯®¤ä㭪樥© 12 ä㭪樨 21.
* …᫨ PCI BIOS ­¥ ¯®¤¤¥à¦¨¢ ¥âáï, â® §­ ç¥­¨¥ ax ­¥®¯à¥¤¥«¥­®.
 
======================================================================
==== ”ã­ªæ¨ï 62, ¯®¤äã­ªæ¨ï 1 - ¯®«ãç¨âì ­®¬¥à ¯®á«¥¤­¥© PCI-設ë. ===
======================================================================
 à ¬¥âàë:
* eax = 62 - ­®¬¥à ä㭪樨
* bl = 1 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ­; ¨­ ç¥
* al = ­®¬¥à ¯®á«¥¤­¥© PCI-設ë; ®á⠢訥áï ¡ ©âë eax à §àãè îâáï
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì à §à¥èñ­ ­¨§ª®ã஢­¥¢ë© ¤®áâ㯠ª PCI
¤«ï ¯à¨«®¦¥­¨© ¯®¤ä㭪樥© 12 ä㭪樨 21.
* …᫨ PCI BIOS ­¥ ¯®¤¤¥à¦¨¢ ¥âáï, â® §­ ç¥­¨¥ al ­¥®¯à¥¤¥«¥­®.
 
======================================================================
====================== ”ã­ªæ¨ï 62, ¯®¤äã­ªæ¨ï 2 ======================
== ®«ãç¨âì ¬¥å ­¨§¬ ®¡à é¥­¨ï ª ª®­ä¨£ãà æ¨®­­®¬ã ¯à®áâà ­áâ¢ã PCI. =
======================================================================
 à ¬¥âàë:
* eax = 62 - ­®¬¥à ä㭪樨
* bl = 2 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ­; ¨­ ç¥
* al = ¬¥å ­¨§¬ (1 ¨«¨ 2); ¯à®ç¨¥ ¡ ©âë eax à §àãè îâáï
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì à §à¥èñ­ ­¨§ª®ã஢­¥¢ë© ¤®áâ㯠ª PCI
¤«ï ¯à¨«®¦¥­¨© ¯®¤ä㭪樥© 12 ä㭪樨 21.
* Œ¥å ­¨§¬ ®¡à é¥­¨ï ¢ë¡¨à ¥âáï ¢ ᮮ⢥âá⢨¨
á å à ªâ¥à¨á⨪ ¬¨ ®¡®à㤮¢ ­¨ï.
* ®¤ä㭪樨 ç⥭¨ï ¨ § ¯¨á¨  ¢â®¬ â¨ç¥áª¨ à ¡®â îâ
á ¢ë¡à ­­ë¬ ¬¥å ­¨§¬®¬.
 
======================================================================
======== ”ã­ªæ¨ï 62, ¯®¤ä㭪樨 4,5,6 - ¯à®ç¨â âì PCI-ॣ¨áâà. =======
======================================================================
 à ¬¥âàë:
* eax = 62 - ­®¬¥à ä㭪樨
* bl = 4 - ç¨â âì ¡ ©â
* bl = 5 - ç¨â âì á«®¢®
* bl = 6 - ç¨â âì ¤¢®©­®¥ á«®¢®
* bh = ­®¬¥à PCI-設ë
* ch = dddddfff, £¤¥ ddddd = ­®¬¥à ãáâனá⢠ ­  設¥,
fff = ­®¬¥à ä㭪樨 ãáâனá⢠
* cl = ­®¬¥à ॣ¨áâà  (¤®«¦¥­ ¡ëâì çñâ­ë¬ ¤«ï bl=5,
¤¥«¨âìáï ­  4 ¤«ï bl=6)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ®è¨¡ª  (§ ¯à¥éñ­ ¤®áâ㯠ª PCI ¨«¨
­¥¯®¤¤¥à¦¨¢ ¥¬ë¥ ¯ à ¬¥âàë); ¨­ ç¥
* al/ax/eax (¢ § ¢¨á¨¬®á⨠®â § ¯à®è¥­­®£® à §¬¥à ) ᮤ¥à¦¨â ¤ ­­ë¥;
®áâ ¢è ïáï ç áâì ॣ¨áâà  eax à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì à §à¥èñ­ ­¨§ª®ã஢­¥¢ë© ¤®áâ㯠ª PCI
¤«ï ¯à¨«®¦¥­¨© ¯®¤ä㭪樥© 12 ä㭪樨 21.
* Œ¥å ­¨§¬ ¤®áâ㯠 2 ¯®¤¤¥à¦¨¢ ¥â ⮫쪮 16 ãáâனá⢠­  設¥ ¨
¨£­®à¨àã¥â ­®¬¥à ä㭪樨. ®«ãç¨âì ¬¥å ­¨§¬ ¤®áâ㯠 ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 2.
* ¥ª®â®àë¥ à¥£¨áâàë áâ ­¤ àâ­ë ¨ áãé¥áâ¢ãîâ ¤«ï ¢á¥å ãáâனáâ¢,
­¥ª®â®àë¥ ®¯à¥¤¥«ïîâáï ª®­ªà¥â­ë¬ ãáâனá⢮¬. ‘¯¨á®ª ¯¥à¢ëå
¢å®¤¨â, ­ ¯à¨¬¥à, ¢ ¨§¢¥áâ­ë© Interrupt List by Ralf Brown
(http://www.pobox.com/~ralf/files.html,
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/);
ᯨ᮪ ¢â®àëå ¤®«¦¥­ ¡ëâì 㪠§ ­ ¢ ¤®ªã¬¥­â æ¨¨ ¯® ãáâனáâ¢ã.
 
======================================================================
======= ”ã­ªæ¨ï 62, ¯®¤ä㭪樨 8,9,10 - § ¯¨á âì ¢ PCI-ॣ¨áâà. ======
======================================================================
 à ¬¥âàë:
* eax = 62 - ­®¬¥à ä㭪樨
* bl = 8 - ¯¨á âì ¡ ©â
* bl = 9 - ¯¨á âì á«®¢®
* bl = 10 - ¯¨á âì ¤¢®©­®¥ á«®¢®
* bh = ­®¬¥à PCI-設ë
* ch = dddddfff, £¤¥ ddddd = ­®¬¥à ãáâனá⢠ ­  設¥,
fff = ­®¬¥à ä㭪樨 ãáâனá⢠
* cl = ­®¬¥à ॣ¨áâà  (¤®«¦¥­ ¡ëâì çñâ­ë¬ ¤«ï bl=9,
¤¥«¨âìáï ­  4 ¤«ï bl=10)
* dl/dx/edx (¢ § ¢¨á¨¬®á⨠®â § ¯à®è¥­­®£® à §¬¥à ) ᮤ¥à¦¨â
¤ ­­ë¥ ¤«ï § ¯¨á¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ®è¨¡ª  (§ ¯à¥éñ­ ¤®áâ㯠ª PCI ¨«¨
­¥¯®¤¤¥à¦¨¢ ¥¬ë¥ ¯ à ¬¥âàë)
* eax = 0 - ãᯥ譮
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì à §à¥èñ­ ­¨§ª®ã஢­¥¢ë© ¤®áâ㯠ª PCI
¤«ï ¯à¨«®¦¥­¨© ¯®¤ä㭪樥© 12 ä㭪樨 21.
* Œ¥å ­¨§¬ ¤®áâ㯠 2 ¯®¤¤¥à¦¨¢ ¥â ⮫쪮 16 ãáâனá⢠­  設¥ ¨
¨£­®à¨àã¥â ­®¬¥à ä㭪樨. ®«ãç¨âì ¬¥å ­¨§¬ ¤®áâ㯠 ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 2.
* ¥ª®â®àë¥ à¥£¨áâàë áâ ­¤ àâ­ë ¨ áãé¥áâ¢ãîâ ¤«ï ¢á¥å ãáâனáâ¢,
­¥ª®â®àë¥ ®¯à¥¤¥«ïîâáï ª®­ªà¥â­ë¬ ãáâனá⢮¬. ‘¯¨á®ª ¯¥à¢ëå
¢å®¤¨â, ­ ¯à¨¬¥à, ¢ ¨§¢¥áâ­ë© Interrupt List by Ralf Brown;
ᯨ᮪ ¢â®àëå ¤®«¦¥­ ¡ëâì 㪠§ ­ ¢ ¤®ªã¬¥­â æ¨¨ ¯® ãáâனáâ¢ã.
 
======================================================================
====================== ”ã­ªæ¨ï 62, ¯®¤äã­ªæ¨ï 11 =====================
== ˆ­¨æ¨ «¨§¨à®¢ âì ¯®«ì§®¢ â¥«ì᪨© ‚/‚ á ®â®¡à ¦¥­¨¥¬ ­  ¯ ¬ïâì ==
======================================================================
 à ¬¥âàë:
* eax = 62 - ­®¬¥à ä㭪樨
* bl = 11 - ­®¬¥à ¯®¤ä㭪樨
* cx =  ¤à¥á PCI-ãáâனá⢠
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ­;
* eax = -2 - ¤®áâ㯠ª MMIO-¡«®ª ¬ ãáâனá⢠ ­¥ à §à¥èñ­;
* eax = -3 - ®è¨¡ª   ««®ª æ¨¨ ¯®«ì§®¢ â¥«ì᪮© ¤¨­. ¯ ¬ïâ¨; ¨­ ç¥
* eax = à §¬¥à ¤®áâ㯭®© ¤¨­ ¬¨ç¥áª®© ¯ ¬ïâ¨.
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì à §à¥èñ­ ­¨§ª®ã஢­¥¢ë© ¤®áâ㯠ª PCI
¤«ï ¯à¨«®¦¥­¨© ¯®¤ä㭪樥© 12 ä㭪樨 21.
*  ¤à¥á PCI-ãáâனá⢠ ¤®«¦¥­ ᮢ¯ ¤ âì á á¨á⥬­®© ¯¥à¥¬¥­­®©
mmio_pci_addr
 
======================================================================
====================== ”ã­ªæ¨ï 62, ¯®¤äã­ªæ¨ï 12 =====================
== ‚뤥«¨âì ¤¨ ¯ §®­ «¨­¥©­ëå  ¤à¥á®¢ ¤«ï ¯®«ì§®¢ â¥«ì᪮£® MMIO ==
======================================================================
 à ¬¥âàë:
* eax = 62 - ­®¬¥à ä㭪樨
* bl = 12 - ­®¬¥à ¯®¤ä㭪樨
* bh = ­®¬¥à BAR-ॣ¨áâà  ¢ ª®­ä¨£ãà æ¨®­­®© §®­¥ PCI
* ecx = à §¬¥à MMIO-¡«®ª  (¢ ¡ ©â å)
* edx = ᬥ饭¨¥ ®â­®á¨â¥«ì­® ­ ç «  MMIO-¡«®ª  (¢ 4K-áâà ­¨æ å!)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ­;
* eax = -2 - ­¥¢¥à­ë© ­®¬¥à BAR-ॣ¨áâà ;
* eax = -3 - BAR ­¥ ᮤ¥à¦¨â  ¤à¥á  IO;
* eax = -4 - BAR  ¤à¥áã¥â ¯®àâë IO;
* eax = -5 - ®è¨¡ª   ««®ª æ¨¨; ¨­ ç¥
* eax = ­ ç «ì­ë©  ¤à¥á MMIO ¢  ¤à¥á­®¬ ¯à®áâà ­á⢥ ¯à¨«®¦¥­¨ï.
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì à §à¥èñ­ ­¨§ª®ã஢­¥¢ë© ¤®áâ㯠ª PCI
¤«ï ¯à¨«®¦¥­¨© ¯®¤ä㭪樥© 12 ä㭪樨 21.
* €¤à¥á PCI-ãáâனá⢠ § ¤ ¥âáï á¨á⥬­®© ¯¥à¥¬¥­­®© mmio_pci_addr.
* à¥¤®áâ ¢«¥­­ë© ¤¨ ¯ §®­ «¨­¥©­ëå  ¤à¥á®¢ ¤®«¦¥­ ®á¢®¡®¦¤ âìáï
¯®á।á⢮¬ ¢ë§®¢  ä㭪樨 62:13
 
======================================================================
====================== ”ã­ªæ¨ï 62, ¯®¤äã­ªæ¨ï 13 =====================
== Žá¢®¡®¤¨âì ¤¨ ¯ §®­ «¨­¥©­ëå  ¤à¥á®¢ ¯®«ì§®¢ â¥«ì᪮£® MMIO ==
======================================================================
 à ¬¥âàë:
* eax = 62 - ­®¬¥à ä㭪樨
* bl = 12 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­ ç «ì­ë©  ¤à¥á ®á¢®¡®¦¤ ¥¬®£® MMIO-¡«®ª  ¢  ¤à¥á­®¬
¯à®áâà ­á⢥ ¯à¨«®¦¥­¨ï
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 1 - ¡«®ª ãᯥ譮 ®á¢®¡®¦¤¥­;
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¯à¨«®¦¥­¨î ¤®«¦¥­ ¡ëâì ¢ë¤¥«¥­ uMMIO-¡«®ª (fn62:12)
 
======================================================================
================ ”ã­ªæ¨ï 63 - à ¡®â  á ¤®áª®© ®â« ¤ª¨. ===============
======================================================================
„®áª  ®â« ¤ª¨ ¯à¥¤áâ ¢«ï¥â ᮡ®© á¨á⥬­ë© ¡ãä¥à (­  4096 ¡ ©â),
¢ ª®â®àë© «î¡ ï ¯à®£à ¬¬  ¬®¦¥â § ¯¨á âì (¢®®¡é¥ £®¢®àï, ¯à®¨§¢®«ì­ë¥)
¤ ­­ë¥ ¨ ¨§ ª®â®à®£® ¤àã£ ï ¯à®£à ¬¬  ¬®¦¥â í⨠¤ ­­ë¥ ¯à®ç¨â âì.
…áâì ᮣ« è¥­¨¥, ¢ ᮮ⢥âá⢨¨ á ª®â®àë¬ § ¯¨á뢠¥¬ë¥ ¤ ­­ë¥ -
⥪áâ®¢ë¥ áâப¨, ¨­â¥à¯à¥â¨àã¥¬ë¥ ª ª ®â« ¤®ç­ë¥ á®®¡é¥­¨ï ® 室¥
¢ë¯®«­¥­¨ï ¯à®£à ¬¬ë. Ÿ¤à® ¢ ®¯à¥¤¥«ñ­­ëå á¨âã æ¨ïå â ª¦¥ § ¯¨á뢠¥â
­  ¤®áªã ®â« ¤ª¨ ᢥ¤¥­¨ï ® ¢ë¯®«­¥­¨¨ ­¥ª®â®àëå ä㭪権;
¯® ᮣ« è¥­¨î á®®¡é¥­¨ï ï¤à  ­ ç¨­ îâáï á ¯à¥ä¨ªá  "K : ".
„«ï ¯à®á¬®âà  ¤®áª¨ ®â« ¤ª¨ ᮧ¤ ­® ¯à¨«®¦¥­¨¥ board,
ª®â®à®¥ áç¨â뢠¥â ¤ ­­ë¥ ¨§ ¡ãä¥à  ¨ ®â®¡à ¦ ¥â ¨å ¢ ᢮ñ¬ ®ª­¥. board
¯®­¨¬ ¥â ¯®á«¥¤®¢ â¥«ì­®áâì ª®¤®¢ 13,10 ª ª ¯¥à¥å®¤ ­  ­®¢ãî áâபã.
‘¨¬¢®« á ­ã«¥¢ë¬ ª®¤®¬ ¢ ª®­æ¥ áâப¨ ­¥ ®¡ï§ â¥«¥­, ­® ¨ ­¥ ¬¥è ¥â.
‚ á¢ï§¨ á ¯®ï¢«¥­¨¥¬ ®â« ¤ç¨ª  業­®áâì ¤®áª¨ ®â« ¤ª¨ ­¥áª®«ìª®
á­¨§¨« áì, ¯®áª®«ìªã ®â« ¤ç¨ª ¯®§¢®«ï¥â ¯®«­®áâìî ª®­â஫¨à®¢ âì 室
¢ë¯®«­¥­¨ï ¯à®£à ¬¬ë, ¯à¨çñ¬ ¤«ï í⮣® ­¥ âॡã¥âáï ­¨ª ª¨å ãᨫ¨©
á® áâ®à®­ë á ¬®© ¯à®£à ¬¬ë. ’¥¬ ­¥ ¬¥­¥¥ ¢® ¬­®£¨å á«ãç ïå
¤®áª  ®â« ¤ª¨ ¯à®¤®«¦ ¥â ®áâ ¢ âìáï ¯®«¥§­®©.
 
---------------------------- ‡ ¯¨áì ¡ ©â  ----------------------------
 à ¬¥âàë:
* eax = 63 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* cl = ¡ ©â ¤ ­­ëå
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
*  ©â § ¯¨á뢠¥âáï ¢ ¡ãä¥à. „«¨­  ¡ãä¥à  - 512 ¡ ©â.
à¨ ¯¥à¥¯®«­¥­¨¨ ¡ãä¥à  ¢á¥ ¯®«ã祭­ë¥ ¤ ­­ë¥ â¥àïîâáï
¨ § ¯®«­¥­¨¥ ­ ç¨­ ¥âáï á­®¢  á ­ã«ï.
* „«ï ¢ë¢®¤  ­  ¤®áªã ®â« ¤ª¨ ¡®«¥¥ á«®¦­ëå ®¡ê¥ªâ®¢ (áâப, ç¨á¥«)
¤®áâ â®ç­® í⮩ ä㭪樨, ¢ë§ë¢ ¥¬®© ¢ 横«¥. Œ®¦­® ­¥ ¯¨á âì
¢àãç­ãî ᮮ⢥âáâ¢ãî騩 ª®¤,   ¢®á¯®«ì§®¢ âìáï ä ©«®¬ debug.inc,
¢å®¤ï騬 ¢ ¤¨áâਡã⨢.
 
---------------------------- —⥭¨¥ ¡ ©â  ----------------------------
‡ ¡¨à ¥â ¡ ©â ¨§ ¡ãä¥à .
 à ¬¥âàë:
* eax = 63 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ebx = 0 - ¡ãä¥à ¯ãáâ
* eax = ¡ ©â, ebx = 1 - ¡ ©â ãᯥ譮 ¯à®ç¨â ­
 
======================================================================
========== ”ã­ªæ¨ï 64 - ¯¥à¥à á¯à¥¤¥«¨âì ¯ ¬ïâì ¯à¨«®¦¥­¨ï. ==========
======================================================================
 à ¬¥âàë:
* eax = 64 - ­®¬¥à ä㭪樨
* ebx = 1 - ¥¤¨­á⢥­­ ï ¯®¤äã­ªæ¨ï
* ecx = ­®¢ë© à §¬¥à ¯ ¬ïâ¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ­¥¤®áâ â®ç­® ¯ ¬ïâ¨
‡ ¬¥ç ­¨ï:
* …áâì ¤à㣮© ᯮᮡ ¢ë¤¥«¥­¨ï/®á¢®¡®¦¤¥­¨ï ¤¨­ ¬¨ç¥áª®© ¯ ¬ï⨠-
¯®¤ä㭪樨 11, 12, 13 ä㭪樨 68.
* ”ã­ªæ¨ï ­¥ ¬®¦¥â ¨á¯®«ì§®¢ âìáï ᮢ¬¥áâ­® á 68.11, 68.12, 68.13.
‚맮¢ ä㭪樨 ¡ã¤¥â ¨£­®à¨à®¢ âìáï, ¥á«¨ ¯à¨«®¦¥­¨¥ ᮧ¤ áâ
«®ª «ì­ãî ªãç㠢맮¢®¬ 68.11.
 
======================================================================
========= ”ã­ªæ¨ï 65 - ¢ë¢¥á⨠¨§®¡à ¦¥­¨¥ á ¯ «¨âன ¢ ®ª­®. ========
======================================================================
 à ¬¥âàë:
* eax = 65 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨§®¡à ¦¥­¨¥
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y]
* edx = [ª®®à¤¨­ â  ¯® ®á¨ x]*65536 + [ª®®à¤¨­ â  ¯® ®á¨ y]
* esi = ç¨á«® ¡¨â ­  ¯¨ªá¥«ì, ¤®«¦­® ¡ëâì 1,2,4,8,15,16,24 ¨«¨ 32
* edi = 㪠§ â¥«ì ­  ¯ «¨âàã (2 ¢ á⥯¥­¨ esi 梥⮢ 0x00RRGGBB);
¨£­®à¨àã¥âáï ¯à¨ esi > 8
* ebp = ᬥ饭¨¥ ¤ ­­ëå ª ¦¤®© á«¥¤ãî饩 áâப¨ ¨§®¡à ¦¥­¨ï
®â­®á¨â¥«ì­® ¯à¥¤ë¤ã饩
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* Š®®à¤¨­ âë ¨§®¡à ¦¥­¨ï - íâ® ª®®à¤¨­ âë ¢¥àå­¥£® «¥¢®£® 㣫 
¨§®¡à ¦¥­¨ï ®â­®á¨â¥«ì­® ®ª­ .
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 1 ¡¨â®¬ ­  ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥­¨ï,
§  ¨áª«î祭¨¥¬, ¡ëâì ¬®¦¥â, ¯®á«¥¤­¨å ¡ ©â®¢ áâப, ᮤ¥à¦¨â
¨­ä®à¬ æ¨î ® 梥⥠8 ¯¨ªá¥«¥©, áâ à訩 ¡¨â ᮮ⢥âáâ¢ã¥â ¯¥à¢®¬ã
¯¨ªá¥«î.
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 2 ¡¨â ¬¨ ­  ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥­¨ï,
§  ¨áª«î祭¨¥¬, ¡ëâì ¬®¦¥â, ¯®á«¥¤­¨å ¡ ©â®¢ áâப, ᮤ¥à¦¨â
¨­ä®à¬ æ¨î ® 梥⥠4 ¯¨ªá¥«¥©, áâ à訥 ¤¢  ¡¨â  ᮮ⢥âáâ¢ãîâ
¯¥à¢®¬ã ¯¨ªá¥«î.
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 4 ¡¨â ¬¨ ­  ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥­¨ï,
§  ¨áª«î祭¨¥¬ ¯®á«¥¤­¨å ¡ ©â®¢ áâப (¥á«¨ è¨à¨­  ¨§®¡à ¦¥­¨ï
­¥çñâ­ ), ᮤ¥à¦¨â ¨­ä®à¬ æ¨î ® 梥⥠2 ¯¨ªá¥«¥©, áâ àè ï â¥âà ¤ 
ᮮ⢥âáâ¢ã¥â ¯¥à¢®¬ã ¯¨ªá¥«î.
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 8 ¡¨â ¬¨ ­  ¯¨ªá¥«ì: ª ¦¤ë© ¡ ©â ¨§®¡à ¦¥­¨ï
à áᬠâਢ ¥âáï ª ª ¨­¤¥ªá ¢ ¯ «¨âà¥.
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 15 ¡¨â ¬¨ ­  ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï
ª®¤¨àã¥âáï ª ª (¢ ¡¨â®¢®¬ ¯à¥¤áâ ¢«¥­¨¨) 0RRRRRGGGGGBBBBB -
¯® 5 ¯¨ªá¥«¥© ­  ª ¦¤ë© 梥â.
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 16 ¡¨â ¬¨ ­  ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï
ª®¤¨àã¥âáï ª ª RRRRRGGGGGGBBBBB (á奬  5+6+5).
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 24 ¡¨â ¬¨ ­  ¯¨ªá¥«ì: 梥⠪ ¦¤®£® ¯¨ªá¥«ï
ª®¤¨àã¥âáï âà¥¬ï ¡ ©â ¬¨ - ¯®á«¥¤®¢ â¥«ì­® ᨭïï, §¥«ñ­ ï, ªà á­ ï
á®áâ ¢«ïî騥 梥â .
* ”®à¬ â ¨§®¡à ¦¥­¨ï á 32 ¡¨â ¬¨ ­  ¯¨ªá¥«ì:  ­ «®£¨ç­® 24, ⮫쪮
¥áâì ¥éñ ¨£­®à¨àã¥¬ë© ç¥â¢ñàâë© ¡ ©â.
* ‚맮¢ ä㭪樨 7 íª¢¨¢ «¥­â¥­ ¢ë§®¢ã í⮩ ä㭪樨 á ¯ à ¬¥âà ¬¨
esi=24, ebp=0.
 
======================================================================
================= ”ã­ªæ¨ï 66 - à ¡®â  á ª« ¢¨ âãன. =================
======================================================================
¥¦¨¬ ¢¢®¤  ¢«¨ï¥â ­  १ã«ìâ âë ç⥭¨ï ª« ¢¨è ä㭪樥© 2.
à¨ § £à㧪¥ ¯à®£à ¬¬ë ¤«ï ­¥ñ ãáâ ­ ¢«¨¢ ¥âáï ASCII-०¨¬ ¢¢®¤ .
…᫨ ¢ë§ë¢ ¥âáï ­¥áãé¥áâ¢ãîé ï ¯®¤äã­ªæ¨ï ¢®§¢à é ¥âáï ¢ eax=-1.
 
-------- ®¤äã­ªæ¨ï 1 - ãáâ ­®¢¨âì ०¨¬ ¢¢®¤  á ª« ¢¨ âãàë. ---------
 à ¬¥âàë:
* eax = 66 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ०¨¬:
* 0 = ®¡ëç­ë© (ASCII-ᨬ¢®«ë)
* 1 = ᪠­ª®¤ë
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
--------- ®¤äã­ªæ¨ï 2 - ¯®«ãç¨âì ०¨¬ ¢¢®¤  á ª« ¢¨ âãàë. ----------
 à ¬¥âàë:
* eax = 66 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ⥪ã騩 ०¨¬
 
------- ®¤äã­ªæ¨ï 3 - ¯®«ãç¨âì á®áâ®ï­¨¥ ã¯à ¢«ïîé¨å ª« ¢¨è. --------
 à ¬¥âàë:
* eax = 66 - ­®¬¥à ä㭪樨
* ebx = 3 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ¡¨â®¢ ï ¬ áª :
* ¡¨â 0 (¬ áª  1): «¥¢ë© Shift ­ ¦ â
* ¡¨â 1 (¬ áª  2): ¯à ¢ë© Shift ­ ¦ â
* ¡¨â 2 (¬ áª  4): «¥¢ë© Ctrl ­ ¦ â
* ¡¨â 3 (¬ áª  8): ¯à ¢ë© Ctrl ­ ¦ â
* ¡¨â 4 (¬ áª  0x10): «¥¢ë© Alt ­ ¦ â
* ¡¨â 5 (¬ áª  0x20): ¯à ¢ë© Alt ­ ¦ â
* ¡¨â 6 (¬ áª  0x40): CapsLock ¢ª«îçñ­
* ¡¨â 7 (¬ áª  0x80): NumLock ¢ª«îçñ­
* ¡¨â 8 (¬ áª  0x100): ScrollLock ¢ª«îçñ­
* ¯à®ç¨¥ ¡¨âë á¡à®è¥­ë
 
----- ®¤äã­ªæ¨ï 4 - ãáâ ­®¢¨âì ®¡é¥á¨á⥬­ãî "£®àïçãî ª« ¢¨èã". -----
Ž ­ ¦ â¨¨ "£®àï祩 ª« ¢¨è¨" ¨§¢¥é îâáï ⮫쪮 ¯à¨«®¦¥­¨ï,
ãáâ ­®¢¨¢è¨¥ ¥ñ;  ªâ¨¢­®¥ ¯à¨«®¦¥­¨¥ (ª ª®â®à®¬ã ¯®áâ㯠¥â
¢¥áì ­®à¬ «ì­ë© ¢¢®¤) â ª¨å ª« ¢¨è ­¥ ¯®«ãç ¥â.
ˆ§¢¥é¥­¨¥ § ª«îç ¥âáï ¢ ¯®á뫪¥ ᮡëâ¨ï á ª®¤®¬ 2.
à®ç¨â âì "£®àïçãî ª« ¢¨èã" ¬®¦­® â ª ¦¥, ª ª ¨ ®¡ëç­ãî, -
ä㭪樥© 2.
 à ¬¥âàë:
* eax = 66 - ­®¬¥à ä㭪樨
* ebx = 4 - ­®¬¥à ¯®¤ä㭪樨
* cl § ¤ ñâ ᪠­ª®¤ ª« ¢¨è¨;
¨á¯®«ì§ã©â¥ cl=0 ¤«ï § ¤ ­¨ï ª®¬¡¨­ æ¨© ⨯  Ctrl+Shift
* edx = 0xXYZ § ¤ ñâ ¢®§¬®¦­ë¥ á®áâ®ï­¨ï ã¯à ¢«ïîé¨å ª« ¢¨è:
* Z (¬« ¤è¨¥ 4 ¡¨â ) § ¤ ñâ á®áâ®ï­¨¥ ª« ¢¨è LShift ¨ RShift:
* 0 = ­¨ ®¤­  ¨§ ª« ¢¨è ­¥ ¤®«¦­  ¡ëâì ­ ¦ â ;
* 1 = ஢­® ®¤­  ¨§ ª« ¢¨è ¤®«¦­  ¡ëâì ­ ¦ â ;
* 2 = ®¡¥ ª« ¢¨è¨ ¤®«¦­ë ¡ëâì ­ ¦ âë;
* 3 = ¤®«¦­  ¡ëâì ­ ¦ â  LShift, ­® ­¥ RShift;
* 4 = ¤®«¦­  ¡ëâì ­ ¦ â  RShift, ­® ­¥ LShift
* Y -  ­ «®£¨ç­® ¤«ï LCtrl ¨ RCtrl;
* X -  ­ «®£¨ç­® ¤«ï LAlt ¨ RAlt
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax=0 - ãᯥ譮
* eax=1 - ᫨誮¬ ¬­®£® "£®àïç¨å ª« ¢¨è" (¤®¯ã᪠¥âáï ¬ ªá¨¬ã¬ 256)
‡ ¬¥ç ­¨ï:
* ƒ®àïç ï ª« ¢¨è  ¬®¦¥â áà ¡ â뢠âì «¨¡® ¯à¨ ­ ¦ â¨¨,
«¨¡® ¯à¨ ®â¯ã᪠­¨¨. ‘ª ­ª®¤ ®â¯ã᪠­¨ï ª« ¢¨è¨ ­  128 ¡®«ìè¥,
祬 ᪠­ª®¤ ­ ¦ â¨ï (â.¥. ãáâ ­®¢«¥­ áâ à訩 ¡¨â).
* ¥áª®«ìª® ¯à¨«®¦¥­¨© ¬®£ãâ ãáâ ­®¢¨âì ®¤­ã ¨ âã ¦¥ ª®¬¡¨­ æ¨î;
® ­ ¦ â¨¨ â ª®© ª®¬¡¨­ æ¨¨ ¡ã¤ãâ ¨§¢¥é âìáï ¢á¥ â ª¨¥ ¯à¨«®¦¥­¨ï.
 
------ ®¤äã­ªæ¨ï 5 - 㤠«¨âì ãáâ ­®¢«¥­­ãî "£®àïçãî ª« ¢¨èã". -------
 à ¬¥âàë:
* eax = 66 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
* cl = ᪠­ª®¤ ª« ¢¨è¨ ¨ edx = 0xXYZ â ª¨¥ ¦¥, ª ª ¨ ¢ ¯®¤ä㭪樨 4
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ­¥â â ª®© £®àï祩 ª« ¢¨è¨
‡ ¬¥ç ­¨ï:
* à¨ § ¢¥à襭¨¨ ¯à®æ¥áá /¯®â®ª  㤠«ïîâáï ¢á¥ ãáâ ­®¢«¥­­ë¥ ¨¬
£®àï稥 ª« ¢¨è¨.
* ‚맮¢ ä㭪樨 ­¥ ¢«¨ï¥â ­  ¤à㣨¥ ¯à¨«®¦¥­¨ï.
…᫨ ¤à㣮¥ ¯à¨«®¦¥­¨¥ ®¯à¥¤¥«¨«® íâã ¦¥ ª®¬¡¨­ æ¨î,
®­® ¯®-¯à¥¦­¥¬ã ¡ã¤¥â ¯®«ãç âì 㢥¤®¬«¥­¨ï.
 
======================================================================
============ ”ã­ªæ¨ï 67 - ¨§¬¥­¨âì ¯®«®¦¥­¨¥/à §¬¥àë ®ª­ . ===========
======================================================================
 à ¬¥âàë:
* eax = 67 - ­®¬¥à ä㭪樨
* ebx = ­®¢ ï x-ª®®à¤¨­ â  ®ª­ 
* ecx = ­®¢ ï y-ª®®à¤¨­ â  ®ª­ 
* edx = ­®¢ë© x-à §¬¥à ®ª­ 
* esi = ­®¢ë© y-à §¬¥à ®ª­ 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ‡­ ç¥­¨¥ -1 ¤«ï ¯ à ¬¥âà  ®§­ ç ¥â "­¥ ¨§¬¥­ïâì"; ­ ¯à¨¬¥à, ¤«ï
¯¥à¥¬¥é¥­¨ï ®ª­  ¡¥§ ¨§¬¥­¥­¨ï à §¬¥à®¢ ¬®¦­® 㪠§ âì edx=esi=-1.
* à¥¤¢ à¨â¥«ì­® ®ª­® ¤®«¦­® ¡ëâì ®¯à¥¤¥«¥­® ä㭪樥© 0.
Ž­  ¦¥ § ¤ ñâ ­ ç «ì­ë¥ ª®®à¤¨­ âë ¨ à §¬¥àë ®ª­ .
*  §¬¥àë ®ª­  ¯®­¨¬ îâáï ¢ á¬ëá«¥ ä㭪樨 0, â.¥.
­  ®¤¨­ ¯¨ªá¥«ì ¬¥­ìè¥, 祬 ॠ«ì­ë¥ à §¬¥àë.
* ‚맮¢ ä㭪樨 ¤«ï ¬ ªá¨¬¨§¨à®¢ ­­ëå ®ª®­ ¯à®áâ® ¨£­®à¨àã¥âáï.
* „«ï ®ª®­ ᮮ⢥âáâ¢ãîé¨å á⨫¥© ¯®«®¦¥­¨¥ ¨/¨«¨ à §¬¥àë ¬®£ãâ ¡ëâì
¨§¬¥­¥­ë ¯®«ì§®¢ â¥«¥¬; ⥪ã騥 ¯®«®¦¥­¨¥ ¨ à §¬¥àë ¬®£ãâ ¡ëâì
¯®«ãç¥­ë ¢ë§®¢®¬ ä㭪樨 9.
* ”ã­ªæ¨ï ¯®áë« ¥â ®ª­ã ᮡë⨥ ¯¥à¥à¨á®¢ª¨ (á ª®¤®¬ 1).
 
======================================================================
=== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 0 - ¯®«ãç¨âì áçñâ稪 ¯¥à¥ª«î祭¨© § ¤ ç. ==
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 0 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ç¨á«® ¯¥à¥ª«î祭¨© § ¤ ç á ¬®¬¥­â  § £à㧪¨ á¨á⥬ë
(¯® ¬®¤ã«î 2^32)
 
======================================================================
====================== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 1 ======================
============ ¥à¥ª«îç¨âìáï ­  á«¥¤ãî騩 ¯®â®ª ¢ë¯®«­¥­¨ï. ============
======================================================================
”ã­ªæ¨ï § ¢¥àè ¥â ⥪ã騩 ª¢ ­â ¢à¥¬¥­¨, ¢ë¤¥«¥­­ë© ¯®â®ªã,
¨ ¯¥à¥ª«îç ¥âáï ­  á«¥¤ãî騩.
(Š ª®© ¯®â®ª ª ª®£® ¯à®æ¥áá  ¡ã¤¥â á«¥¤ãî騬, ¯à¥¤áª § âì ­¥«ì§ï).
®§¤­¥¥, ª®£¤  ¤® ⥪ã饣® ¯®â®ª  ¤®©¤ñâ ®ç¥à¥¤ì,
¢ë¯®«­¥­¨¥ ¢®§®¡­®¢¨âáï.
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
======================================================================
=============== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 2 - ªíè + rdpmc. ==============
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = âॡ㥬®¥ ¤¥©á⢨¥:
* ecx = 0 - à §à¥è¨âì ¢ë¯®«­¥­¨¥ ¨­áâàãªæ¨¨ rdpmc
(ReaD Performance-Monitoring Counters)
* ecx = 1 - 㧭 âì, ¢ª«îçñ­/¢ëª«î祭 ªíè
* ecx = 2 - ¢ª«îç¨âì ªíè
* ecx = 3 - ¢ëª«îç¨âì ªíè
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¤«ï ecx=0:
* eax = §­ ç¥­¨¥ cr4
* ¤«ï ecx=1:
* eax = (cr0 and 0x60000000):
* eax = 0 - ªíè ¢ª«îçñ­
* eax <> 0 - ªíè ¢ëª«î祭
* ¤«ï ecx=2 ¨ ecx=3:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
 
======================================================================
========== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 3 - ¯à®ç¨â âì MSR-ॣ¨áâà. =========
======================================================================
MSR = Model Specific Register; ¯®«­ë© ᯨ᮪ MSR-ॣ¨áâ஢ ¯à®æ¥áá®à 
ᮤ¥à¦¨âáï ¢ ¤®ªã¬¥­â æ¨¨ ¯® ¯à®æ¥áá®àã (­ ¯à¨¬¥à, IA-32 Intel
Architecture Software Developer's Manual, Volume 3, Appendix B);
ª ¦¤®¥ ᥬ¥©á⢮ ¯à®æ¥áá®à®¢ ¨¬¥¥â ᢮ñ ¯®¤¬­®¦¥á⢮ MSR-ॣ¨áâ஢.
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 3 - ­®¬¥à ¯®¤ä㭪樨
* ecx ¨£­®à¨àã¥âáï
* edx =  ¤à¥á MSR
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ebx:eax = áâ à訩:¬« ¤è¨© dword १ã«ìâ â 
‡ ¬¥ç ­¨ï:
* “ª § ­¨¥ ¢ ecx ­¥áãé¥áâ¢ãî饣® ¨«¨ ­¥à¥ «¨§®¢ ­­®£® ¤«ï ¤ ­­®£®
¯à®æ¥áá®à  MSR ¯®¢«¥çñ⠨᪫î祭¨¥ ¢ ï¤à¥, ª®â®à®¥ ¯à¨¡ìñâ ¯®â®ª.
* à¥¤¢ à¨â¥«ì­® á«¥¤ã¥â ®¯à¥¤¥«¨âì, ¯®¤¤¥à¦¨¢ îâáï «¨ MSR ¢ 楫®¬,
ª®¬ ­¤®© cpuid. ˆ­ ç¥ ¢®§­¨ª­¥â 㦥 ¤à㣮¥ ¨áª«î祭¨¥ ¢ ï¤à¥,
ª®â®à®¥ ¢áñ à ¢­® ¯à¨¡ìñâ ¯®â®ª.
 
======================================================================
========= ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 4 - § ¯¨á âì ¢ MSR-ॣ¨áâà. =========
======================================================================
MSR = Model Specific Register; ¯®«­ë© ᯨ᮪ MSR-ॣ¨áâ஢ ¯à®æ¥áá®à 
ᮤ¥à¦¨âáï ¢ ¤®ªã¬¥­â æ¨¨ ¯® ¯à®æ¥áá®àã (­ ¯à¨¬¥à, IA-32 Intel
Architecture Software Developer's Manual, Volume 3, Appendix B);
ª ¦¤®¥ ᥬ¥©á⢮ ¯à®æ¥áá®à®¢ ¨¬¥¥â ᢮ñ ¯®¤¬­®¦¥á⢮ MSR-ॣ¨áâ஢.
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 4 - ­®¬¥à ¯®¤ä㭪樨
* ecx ¨£­®à¨àã¥âáï
* edx =  ¤à¥á MSR
* esi:edi = áâ à訩:¬« ¤è¨© dword
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* “ª § ­¨¥ ¢ ecx ­¥áãé¥áâ¢ãî饣® ¨«¨ ­¥à¥ «¨§®¢ ­­®£® ¤«ï ¤ ­­®£®
¯à®æ¥áá®à  MSR ¯®¢«¥çñ⠨᪫î祭¨¥ ¢ ï¤à¥, ª®â®à®¥ ¯à¨¡ìñâ ¯®â®ª.
* à¥¤¢ à¨â¥«ì­® á«¥¤ã¥â ®¯à¥¤¥«¨âì, ¯®¤¤¥à¦¨¢ îâáï «¨ MSR ¢ 楫®¬,
ª®¬ ­¤®© cpuid. ˆ­ ç¥ ¢®§­¨ª­¥â 㦥 ¤à㣮¥ ¨áª«î祭¨¥ ¢ ï¤à¥,
ª®â®à®¥ ¢áñ à ¢­® ¯à¨¡ìñâ ¯®â®ª.
 
======================================================================
===== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 11 - ¨­¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá . ====
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 11 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ­¥ãᯥå
* ¨­ ç¥ à §¬¥à ᮧ¤ ­­®© ªãç¨
‡ ¬¥ç ­¨ï:
* ‚맮¢ ä㭪樨 ¨­¨æ¨ «¨§¨àã¥â ªãçã, ¨§ ª®â®à®© ¢¯®á«¥¤á⢨¨ ¬®¦­®
¢ë¤¥«ïâì ¨ ®á¢®¡®¦¤ âì ¡«®ª¨ ¯ ¬ï⨠¯®¤äã­ªæ¨ï¬¨ 12 ¨ 13.
 §¬¥à ªãç¨ à ¢¥­ à §¬¥à㠢ᥩ ᢮¡®¤­®© ¯ ¬ï⨠¯à¨«®¦¥­¨ï.
* à¨ ¯®¢â®à­®¬ ¢ë§®¢¥ ä㭪樨 ⥬ ¦¥ ¯à®æ¥áᮬ äã­ªæ¨ï ¢¥à­ñâ
à §¬¥à áãé¥áâ¢ãî饩 ªãç¨.
* ®á«¥ ᮧ¤ ­¨ï ªãç¨ ¢ë§®¢ë ä㭪樨 64 ¨£­®à¨àãîâáï.
 
======================================================================
========== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 12 - ¢ë¤¥«¨âì ¡«®ª ¯ ¬ïâ¨. =========
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 12 - ­®¬¥à ¯®¤ä㭪樨
* ecx = âà¥¡ã¥¬ë© à §¬¥à ¢ ¡ ©â å
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 㪠§ â¥«ì ­  ¢ë¤¥«¥­­ë© ¡«®ª
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® á«¥¤ã¥â ¨­¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá  ¢ë§®¢®¬
¯®¤ä㭪樨 11.
* ”ã­ªæ¨ï ¢ë¤¥«ï¥â 楫®¥ ç¨á«® áâà ­¨æ (4 Š¡) â ª, çâ® ä ªâ¨ç¥áª¨©
à §¬¥à ¢ë¤¥«¥­­®£® ¡«®ª  ¡®«ìè¥ ¨«¨ à ¢¥­ § ¯à®è¥­­®¬ã.
 
======================================================================
========= ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 13 - ®á¢®¡®¤¨âì ¡«®ª ¯ ¬ïâ¨. ========
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 13 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¡«®ª ¯ ¬ïâ¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 1 - ãᯥ譮
* eax = 0 - ­¥ã¤ ç 
‡ ¬¥ç ­¨ï:
* «®ª ¯ ¬ï⨠¤®«¦¥­ ¡ëâì à ­¥¥ ¢ë¤¥«¥­ ¯®¤ä㭪樥© 12
¨«¨ ¯®¤ä㭪樥© 20.
 
======================================================================
==================== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 14 =======================
===== Ž¦¨¤ âì ¯®«ã祭¨ï ᨣ­ « , ®â ¤àã£¨å ¯à¨«®¦¥­¨©/¤à ©¢¥à®¢. =====
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 14 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¡ãä¥à ¤«ï ¨­ä®à¬ æ¨¨ (24 ¡ ©â )
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¡ãä¥à, ­  ª®â®àë© ãª §ë¢ ¥â ecx, ᮤ¥à¦¨â á«¥¤ãîéãî ¨­ä®à¬ æ¨î:
* +0: dword: ¨¤¥­â¨ä¨ª â®à ¯®á«¥¤ãîé¨å ¤ ­­ëå ᨣ­ « 
* +4: ¤ ­­ë¥ ¯à¨­ï⮣® ᨣ­ «  (20 ¡ ©â), ä®à¬ â ª®â®àëå
®¯à¥¤¥«ï¥âáï ¯¥à¢ë¬ dword-®¬
 
======================================================================
== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 15 - ãáâ ­®¢¨âì ®¡à ¡®â稪 ¨áª«î祭¨© FPU. =
======================================================================
“¤ «¥­  (¢ ⥪ã饩 ॠ«¨§ æ¨¨ ¯à®áâ® ¢®§¢à é ¥â 0)
ˆá¯®«ì§®¢ âì ¯®¤ä㭪樨 24, 25
 
======================================================================
=========== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 16 - § £à㧨âì ¤à ©¢¥à. ===========
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 16 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¨¬¥­¥¬ ¤à ©¢¥à 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ­¥ã¤ ç 
* ¨­ ç¥ eax = åí­¤« ¤à ©¢¥à 
‡ ¬¥ç ­¨ï:
* …᫨ ¤à ©¢¥à ¥éñ ­¥ § £à㦥­, ®­ § £à㦠¥âáï;
¥á«¨ ¤à ©¢¥à 㦥 § £à㦥­, ­¨ç¥£® ­¥ ¬¥­ï¥âáï.
* ˆ¬ï ¤à ©¢¥à  çã¢á⢨⥫쭮 ª ॣ¨áâàã ᨬ¢®«®¢.
Œ ªá¨¬ «ì­ ï ¤«¨­  ¨¬¥­¨ - 16 ᨬ¢®«®¢, ¢ª«îç ï § ¢¥àè î騩
­ã«¥¢®© ᨬ¢®«, ®áâ «ì­ë¥ ᨬ¢®«ë ¨£­®à¨àãîâáï.
* „à ©¢¥à á ¨¬¥­¥¬ ABC § £à㦠¥âáï ¨§ ä ©«  /rd/1/drivers/ABC.obj.
 
======================================================================
========== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 17 - ã¯à ¢«¥­¨¥ ¤à ©¢¥à®¬. =========
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 17 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ã¯à ¢«ïîéãî áâàãªâãàã:
* +0: dword: åí­¤« ¤à ©¢¥à 
* +4: dword: ª®¤ ä㭪樨 ¤à ©¢¥à 
* +8: dword: 㪠§ â¥«ì ­  ¢å®¤­ë¥ ¤ ­­ë¥
* +12 = +0xC: dword: à §¬¥à ¢å®¤­ëå ¤ ­­ëå
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¢ë室­ë¥ ¤ ­­ë¥
* +20 = +0x14: dword: à §¬¥à ¢ë室­ëå ¤ ­­ëå
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ®¯à¥¤¥«ï¥âáï ¤à ©¢¥à®¬
‡ ¬¥ç ­¨ï:
* Š®¤ë ä㭪権 ¨ áâàãªâãà  ¢å®¤­ëå/¢ë室­ëå ¤ ­­ëå
®¯à¥¤¥«ïîâáï ¤à ©¢¥à®¬.
* à¥¤¢ à¨â¥«ì­® ¤®«¦¥­ ¡ëâì ¯®«ã祭 åí­¤« ¤à ©¢¥à  ¯®¤ä㭪樥© 16.
 
======================================================================
== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 18 - ãáâ ­®¢¨âì ®¡à ¡®â稪 ¨áª«î祭¨© SSE. =
======================================================================
“¤ «¥­  (¢ ⥪ã饩 ॠ«¨§ æ¨¨ ¯à®áâ® ¢®§¢à é ¥â 0)
ˆá¯®«ì§®¢ âì ¯®¤ä㭪樨 24, 25
 
======================================================================
============= ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 19 - § £à㧨âì DLL. =============
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 19 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¯®«­ë¬ ¯ãâñ¬ ª DLL
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ­¥ã¤ ç 
* ¨­ ç¥ eax = 㪠§ â¥«ì ­  â ¡«¨æã íªá¯®àâ  DLL
‡ ¬¥ç ­¨ï:
* ’ ¡«¨æ  íªá¯®àâ  ¯à¥¤áâ ¢«ï¥â ᮡ®© ¬ áᨢ áâàãªâãà ¯® 2 dword' ,
§ ª ­ç¨¢ î騩áï ­ã«ñ¬. ¥à¢ë© dword ¢ áâàãªâãॠï¥âáï
㪠§ â¥«¥¬ ­  ¨¬ï ä㭪樨, ¢â®à®© ᮤ¥à¦¨â  ¤à¥á ä㭪樨.
 
======================================================================
====== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 20 - ¯¥à¥à á¯à¥¤¥«¨âì ¡«®ª ¯ ¬ïâ¨. =====
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 20 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­®¢ë© à §¬¥à ¢ ¡ ©â å
* edx = 㪠§ â¥«ì ­  㦥 ¢ë¤¥«¥­­ë© ¡«®ª ¯ ¬ïâ¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 㪠§ â¥«ì ­  ¯¥à¥à á¯à¥¤¥«ñ­­ë© ¡«®ª, 0 ¯à¨ ®è¨¡ª¥
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® á«¥¤ã¥â ¨­¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá  ¢ë§®¢®¬
¯®¤ä㭪樨 11.
* ”ã­ªæ¨ï ¢ë¤¥«ï¥â 楫®¥ ç¨á«® áâà ­¨æ (4 Š¡) â ª, çâ® ä ªâ¨ç¥áª¨©
à §¬¥à ¢ë¤¥«¥­­®£® ¡«®ª  ¡®«ìè¥ ¨«¨ à ¢¥­ § ¯à®è¥­­®¬ã.
* …᫨ edx=0, â® ¢ë§®¢ ä㭪樨 íª¢¨¢ «¥­â¥­ ¢ë¤¥«¥­¨î ¯ ¬ïâ¨
¯®¤ä㭪樥© 12. ‚ ¯à®â¨¢­®¬ á«ãç ¥ ¡«®ª ¯ ¬ï⨠¯®  ¤à¥áã edx
¤®«¦¥­ ¡ëâì à ­¥¥ ¢ë¤¥«¥­ ¯®¤ä㭪樥© 12 ¨«¨
®¯¨á뢠¥¬®© ¯®¤ä㭪樥©.
* …᫨ ecx=0, â® äã­ªæ¨ï ®á¢®¡®¦¤ ¥â ¡«®ª ¯ ¬ï⨠¯®  ¤à¥áã edx ¨
¢®§¢à é ¥â 0.
* ‘®¤¥à¦¨¬®¥ ¯ ¬ï⨠¢¯«®âì ¤® ­ ¨¬¥­ì襣® ¨§ áâ à®£® ¨ ­®¢®£®
à §¬¥à®¢ á®åà ­ï¥âáï.
 
======================================================================
=== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 22 - ®âªàëâì ¨¬¥­®¢ ­­ãî ®¡« áâì ¯ ¬ïâ¨. ==
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 22 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¬ï ®¡« áâ¨. Œ ªá¨¬ã¬ 31 ᨬ¢®«, ¢ª«îç ï § ¢¥àè î騩 ­®«ì
* edx = à §¬¥à ®¡« á⨠¢ ¡ ©â å ¤«ï SHM_CREATE ¨ SHM_OPEN_ALWAYS
* esi = ä« £¨ ®âªàëâ¨ï ¨ ¤®áâ㯠:
* SHM_OPEN = 0x00 - ®âªàëâì áãé¥áâ¢ãîéãî ®¡« áâì ¯ ¬ïâ¨.
…᫨ ®¡« áâì á â ª¨¬ ¨¬¥­¥¬ ­¥ áãé¥áâ¢ã¥â,
äã­ªæ¨ï ¢¥à­ñâ ª®¤ ®è¨¡ª¨ 5.
* SHM_OPEN_ALWAYS = 0x04 - ®âªàëâì áãé¥áâ¢ãîéãî ¨«¨ ᮧ¤ âì ­®¢ãî
®¡« áâì ¯ ¬ïâ¨.
* SHM_CREATE = 0x08 - ᮧ¤ âì ­®¢ãî ®¡« áâì ¯ ¬ïâ¨.
…᫨ ®¡« áâì á â ª¨¬ ¨¬¥­¥¬ 㦥 áãé¥áâ¢ã¥â,
äã­ªæ¨ï ¢¥à­ñâ ª®¤ ®è¨¡ª¨ 10.
* SHM_READ = 0x00 - ¤®áâ㯠⮫쪮 ­  ç⥭¨¥
* SHM_WRITE = 0x01 - ¤®áâ㯠­  ç⥭¨¥ ¨ § ¯¨áì
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 㪠§ â¥«ì ­  ®¡« áâì ¯ ¬ïâ¨, 0 ¯à¨ ®è¨¡ª¥
* ¯à¨ ᮧ¤ ­¨¨ ­®¢®© ®¡« á⨠(SHM_CREATE ¨«¨ SHM_OPEN_ALWAYS):
edx = 0 - ãᯥå, ¨­ ç¥ - ª®¤ ®è¨¡ª¨
* ¯à¨ ®âªàë⨨ áãé¥áâ¢ãî饩 ®¡« á⨠(SHM_OPEN ¨«¨ SHM_OPEN_ALWAYS):
edx = ª®¤ ®è¨¡ª¨ (¯à¨ eax=0) ¨«¨ à §¬¥à ®¡« á⨠¢ ¡ ©â å
Š®¤ë ®è¨¡®ª:
* E_NOTFOUND = 5
* E_ACCESS = 10
* E_NOMEM = 30
* E_PARAM = 33
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® á«¥¤ã¥â ¨­¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá  ¢ë§®¢®¬
¯®¤ä㭪樨 11.
* …᫨ ᮧ¤ ñâáï ­®¢ ï ®¡« áâì, â® ä« £¨ ¤®áâ㯠 ãáâ ­ ¢«¨¢ îâ
¬ ªá¨¬ «ì­ë¥ ¯à ¢  ¤®áâ㯠 ¤«ï ®áâ «ì­ëå ¯à®æ¥áᮢ. ®¯ë⪠
®âªàëâ¨ï ¤à㣨¬ ¯®â®ª®¬ á ­¥à §à¥èñ­­ë¬¨ ¯à ¢ ¬¨ ¯à®¢ «¨âáï
á ª®¤®¬ ®è¨¡ª¨ E_ACCESS.
* à®æ¥áá, ᮧ¤ ¢è¨© ®¡« áâì, ¢á¥£¤  ¨¬¥¥â ¤®áâ㯠­  § ¯¨áì.
 
======================================================================
=== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 23 - § ªàëâì ¨¬¥­®¢ ­­ãî ®¡« áâì ¯ ¬ïâ¨. ==
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 23 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¬ï ®¡« áâ¨. Œ ªá¨¬ã¬ 31 ᨬ¢®«, ¢ª«îç ï § ¢¥àè î騩 ­®«ì
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* Ž¡« áâì ¯ ¬ï⨠䨧¨ç¥áª¨ ®á¢®¡®¦¤ ¥âáï (á § ¡ë¢ ­¨¥¬ ¢á¥å ¤ ­­ëå
¨ ¢ë᢮¡®¦¤¥­¨¥¬ 䨧¨ç¥áª®© ¯ ¬ïâ¨), ª®£¤  ¥ñ § ªà®îâ
¢á¥ ®âªàë¢è¨¥ ¯®â®ª¨.
* à¨ § ¢¥à襭¨¨ ¯®â®ª  ®á¢®¡®¦¤ îâáï ¢á¥ ®âªàëâë¥ ¨¬
®¡« á⨠¯ ¬ïâ¨.
 
======================================================================
==== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 24 - ãáâ ­®¢¨âì ®¡à ¡®â稪 ¨áª«î祭¨© ===
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 24 - ­®¬¥à ¯®¤ä㭪樨
* ecx =  ¤à¥á ­®¢®£® ®¡à ¡®â稪  ¨áª«î祭¨©
* edx = ¬ áª  ®¡à ¡ â뢠¥¬ëå ¨áª«î祭¨©
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax =  ¤à¥á áâ à®£® ®¡à ¡®â稪  ¨áª«î祭¨© (0, ¥á«¨ ­¥ ãáâ ­®¢«¥­)
* ebx = ¬ áª  áâ à®£® ®¡à ¡®â稪  ¨áª«î祭¨©
‡ ¬¥ç ­¨ï:
* ®¬¥à ¡¨â  ¢ ¬ áª¥ ¨áª«î祭¨© ᮮ⢥âáâ¢ãîâ ­®¬¥à㠨᪫î祭¨ï ¯®
ᯥæ¨ä¨ª æ¨¨ ­  ¯à®æ¥áá®à (Intel-PC). ’ ª ­ ¯à¨¬¥à, ¨áª«î祭¨ï FPU
¨¬¥îâ ­®¬¥à 16 (#MF),   SSE - 19 (#XF).
* ‚ ¤ ­­®© ॠ«¨§ æ¨¨ ¨£­®à¨àã¥âáï § ¯à®á ­  ¯¥à¥å¢ â ¨áª«î祭¨ï 7
- á¨á⥬  ®¡à ¡ â뢠¥â #NM á ¬®áâ®ï⥫쭮.
* ®«ì§®¢ â¥«ì᪨© ®¡à ¡®â稪 ¯®«ã砥⠭®¬¥à ¨áª«î祭¨ï ¯ à ¬¥â஬
¢ á⥪¥. ®í⮬㠯ࠢ¨«ì­ë© ¢ë室 ¨§ ®¡à ¡®â稪 : RET 4. ‚®§¢à â
¯à¨ í⮬ ¯à®¨§¢®¤¨âáï ­  ª®¬ ­¤ã, ¢ë§¢ ¢èãî ¨áª«î祭¨¥.
* à¨ ¯¥à¥¤ ç¥ ã¯à ¢«¥­¨ï ®¡à ¡®â稪㠨᪫î祭¨©, á¡à á뢠¥âáï
ᮮ⢥âáâ¢ãî騩 ¡¨â ¢ ¬ áª¥ ¨áª«î祭¨©. ‚®§­¨ª­®¢¥­¨¥ í⮣® ¦¥
¨áª«î祭¨ï ¢ ¯®á«¥¤á⢨¨ - ¯à¨¢¥¤¥â ª default-®¡à ¡®âª¥ â ª®¢®£®.
€ ¨¬¥­­®: ª § ¢¥à襭¨î à ¡®âë ¯à¨«®¦¥­¨ï, ¨«¨ ¯à¨®áâ ­®¢ª¥ á
­®â¨ä¨ª æ¨¥© ®â« ¦¨¢ î饬㠯ਫ®¦¥­¨î.
* ®á«¥ § ¢¥à襭¨ï ªà¨â¨ç¥áª¨å ¤¥©á⢨© ¢ ®¡à ¡®â稪¥ ¯®«ì§®¢ â¥«ï,
¢®ááâ ­®¢«¥­¨¥ ¡¨â  ¬ áª¨ ¤ ­­®£® ¨áª«î祭¨ï ¬®¦­® ᤥ« âì
¯®¤ä㭪樥© 25. ‘¡à®á ä« £®¢ ¨áª«î祭¨© ¢ ¬®¤ã«ïå FPU ¨ XMM -
â ª¦¥ ¢®§« £ ¥âáï ­  ®¡à ¡®â稪 ¯®«ì§®¢ â¥«ï.
 
======================================================================
= ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 25 - ¨§¬¥­¥­¨¥ á®áâ®ï­¨ï  ªâ¨¢­®á⨠ᨣ­ «  =
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 25 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­®¬¥à ᨣ­ « 
* edx = §­ ç¥­¨¥ ãáâ ­ ¢«¨¢ ¥¬®©  ªâ¨¢­®á⨠(0/1)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = áâ à®¥ §­ ç¥­¨¥  ªâ¨¢­®á⨠ᨣ­ «  (0/1)
‡ ¬¥ç ­¨ï:
* ‚ ⥪ã饩 ॠ«¨§ æ¨¨ ¨§¬¥­ï¥âáï ⮫쪮 ¬ áª  ¯®«ì§®¢ â¥«ì᪮£®
®¡à ¡®â稪  ¨áª«î祭¨©, ãáâ ­®¢«¥­­®£® ¯®¤ä㭪樥© 24. à¨ í⮬,
­®¬¥à ᨣ­ «  ᮮ⢥âáâ¢ã¥â ­®¬¥à㠨᪫î祭¨ï.
 
======================================================================
======================== ”ã­ªæ¨ï 69 - ®â« ¤ª . =======================
======================================================================
à®æ¥áá ¬®¦¥â § £à㧨âì ¤à㣮© ¯à®æ¥áá ª ª ®â« ¦¨¢ ¥¬ë© ãáâ ­®¢ª®©
ᮮ⢥âáâ¢ãî饣® ¡¨â  ¯à¨ ¢ë§®¢¥ ¯®¤ä㭪樨 7 ä㭪樨 70.
“ ¯à®æ¥áá  ¬®¦¥â ¡ëâì ⮫쪮 ®¤¨­ ®â« ¤ç¨ª; ®¤¨­ ¯à®æ¥áá ¬®¦¥â
®â« ¦¨¢ âì ­¥áª®«ìª® à §­ëå. ‘¨á⥬  㢥¤®¬«ï¥â ®â« ¤ç¨ª ® ᮡëâ¨ïå,
¯à®¨á室ïé¨å á ®â« ¦¨¢ ¥¬ë¬ ¯à®æ¥áᮬ. ‘®®¡é¥­¨ï § ¯¨á뢠îâáï ¢ ¡ãä¥à,
®¯à¥¤¥«ñ­­ë© ¯®¤ä㭪樥© 0.
”®à¬ â á®®¡é¥­¨ï:
* +0: dword: ª®¤ á®®¡é¥­¨ï
* +4: dword: PID ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá 
* +8: ¬®£ãâ ¯à¨áãâá⢮¢ âì ¤®¯®«­¨â¥«ì­ë¥ ¤ ­­ë¥,
®¯à¥¤¥«ï¥¬ë¥ ª®¤®¬ á®®¡é¥­¨ï
Š®¤ë á®®¡é¥­¨©:
* 1 = ¨áª«î祭¨¥
* ¤®¯®«­¨â¥«ì­® ¯¥à¥¤ ñâáï dword-­®¬¥à ¨áª«î祭¨ï
* ¯à®æ¥áá ¯à¨®áâ ­®¢«¥­
* 2 = ¯à®æ¥áá § ¢¥à訫áï
* ¯à¨å®¤¨â ¯à¨ «î¡®¬ § ¢¥à襭¨¨: ª ª ç¥à¥§ á¨á⥬­ãî äã­ªæ¨î -1,
â ª ¨ ¯à¨ "㡨©á⢥" «î¡ë¬ ¤à㣨¬ ¯à®æ¥áᮬ
(¢ ⮬ ç¨á«¥ á ¬¨¬ ®â« ¤ç¨ª®¬)
* 3 = ®â« ¤®ç­®¥ ¨áª«î祭¨¥ int 1 = #DB
* ¤®¯®«­¨â¥«ì­® ¯¥à¥¤ ñâáï dword-®¡à § ॣ¨áâà  DR6:
* ¡¨âë 0-3: ¢ë¯®«­¥­® ãá«®¢¨¥ ᮮ⢥âáâ¢ãî饩 â®çª¨ ®áâ ­®¢ 
(ãáâ ­®¢«¥­­®© ¯®¤ä㭪樥© 9)
* ¡¨â 14: ¨áª«î祭¨¥ ¯à®¨§®è«® ¨§-§  ०¨¬ 
¯®è £®¢®© âà áá¨à®¢ª¨ (ãáâ ­®¢«¥­ ä« £ TF)
* ¯à®æ¥áá ¯à¨®áâ ­®¢«¥­
à¨ § ¢¥à襭¨¨ ®â« ¤ç¨ª  ¯à¨¡¨¢ îâáï ¢á¥ ®â« ¦¨¢ ¥¬ë¥ ¯à®æ¥ááë.
…᫨ ®â« ¤ç¨ª í⮣® ­¥ å®ç¥â, ®­ ¤®«¦¥­ ¯à¥¤¢ à¨â¥«ì­® ®âª«îç¨âìáï
¯®¤ä㭪樥© 3.
 
‚ᥠ¯®¤ä㭪樨 ¯à¨¬¥­¨¬ë ⮫쪮 ª ¯à®æ¥áá ¬/¯®â®ª ¬, § ¯ã饭­ë¬
¨§ ⥪ã饣® ä㭪樥© 70 á ãáâ ­®¢«¥­­ë¬ ä« £®¬ ®â« ¤ª¨.
Žâ« ¤ª  ¬­®£®¯®â®ç­ëå ¯à®£à ¬¬ ¯®ª  ­¥ ¯®¤¤¥à¦¨¢ ¥âáï.
®«­ë© ᯨ᮪ ¯®¤ä㭪権:
* ¯®¤äã­ªæ¨ï 0 - ®¯à¥¤¥«¨âì ®¡« áâì ¤ ­­ëå ¤«ï ®â« ¤®ç­ëå á®®¡é¥­¨©
* ¯®¤äã­ªæ¨ï 1 - ¯®«ãç¨âì á®áâ®ï­¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª 
* ¯®¤äã­ªæ¨ï 2 - ãáâ ­®¢¨âì á®áâ®ï­¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª 
* ¯®¤äã­ªæ¨ï 3 - ®âª«îç¨âìáï ®â ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá 
* ¯®¤äã­ªæ¨ï 4 - ¯à¨®áâ ­®¢¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª
* ¯®¤äã­ªæ¨ï 5 - ¢®§®¡­®¢¨âì ¢ë¯®«­¥­¨¥ ®â« ¦¨¢ ¥¬®£® ¯®â®ª 
* ¯®¤äã­ªæ¨ï 6 - ¯à®ç¨â âì ¨§ ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá 
* ¯®¤äã­ªæ¨ï 7 - § ¯¨á âì ¢ ¯ ¬ïâì ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá 
* ¯®¤äã­ªæ¨ï 8 - § ¢¥àè¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª
* ¯®¤äã­ªæ¨ï 9 - ãáâ ­®¢¨âì/á­ïâì  ¯¯ à â­ãî â®çªã ®áâ ­®¢ 
 
======================================================================
====================== ”ã­ªæ¨ï 69, ¯®¤äã­ªæ¨ï 0 ======================
========= Ž¯à¥¤¥«¨âì ®¡« áâì ¤ ­­ëå ¤«ï ®â« ¤®ç­ëå á®®¡é¥­¨©. ========
======================================================================
 à ¬¥âàë:
* eax = 69 - ­®¬¥à ä㭪樨
* ebx = 0 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì
”®à¬ â ®¡« á⨠¤ ­­ëå:
* +0: dword: N = à §¬¥à ¡ãä¥à  (­¥ áç¨â ï í⮣® § £®«®¢ª )
* +4: dword: § ­ïâ® ¢ ¡ãä¥à¥
* +8: N*byte: ¡ãä¥à
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* …᫨ ¯®«¥ à §¬¥à  ®âà¨æ â¥«ì­®, ¡ãä¥à áç¨â ¥âáï § ¡«®ª¨à®¢ ­­ë¬
¨ ¯à¨ ¯®áâ㯫¥­¨¨ ­®¢®£® á®®¡é¥­¨ï á¨á⥬  ¡ã¤¥â ¦¤ âì.
„«ï ᨭåà®­¨§ æ¨¨ ®¡à ¬«ï©â¥ ¢áî à ¡®âã á ¡ãä¥à®¬ ®¯¥à æ¨ï¬¨
¡«®ª¨à®¢ª¨/à §¡«®ª¨à®¢ª¨
neg [bufsize]
* „ ­­ë¥ ¢ ¡ãä¥à¥ âà ªâãîâáï ª ª ¬ áᨢ í«¥¬¥­â®¢ ¯¥à¥¬¥­­®© ¤«¨­ë -
á®®¡é¥­¨©. ”®à¬ â á®®¡é¥­¨ï 㪠§ ­ ¢ ®¡é¥¬ ®¯¨á ­¨¨.
 
======================================================================
====================== ”ã­ªæ¨ï 69, ¯®¤äã­ªæ¨ï 1 ======================
========= ®«ãç¨âì á®áâ®ï­¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . =========
======================================================================
 à ¬¥âàë:
* eax = 69 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¤¥­â¨ä¨ª â®à ¯®â®ª 
* edx = ¤«¨­  áâàãªâãàë ª®­â¥ªáâ , ¤®«¦­® ¡ëâì 0x28=40 ¡ ©â
* esi = 㪠§ â¥«ì ­  áâàãªâãàã ª®­â¥ªáâ 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
”®à¬ â áâàãªâãàë ª®­â¥ªáâ : (FPU ¯®ª  ­¥ ¯®¤¤¥à¦¨¢ ¥âáï)
* +0: dword: eip
* +4: dword: eflags
* +8: dword: eax
* +12 = +0xC: dword: ecx
* +16 = +0x10: dword: edx
* +20 = +0x14: dword: ebx
* +24 = +0x18: dword: esp
* +28 = +0x1C: dword: ebp
* +32 = +0x20: dword: esi
* +36 = +0x24: dword: edi
‡ ¬¥ç ­¨ï:
* …᫨ ¯®â®ª ¢ë¯®«­ï¥â ª®¤ 0-ª®«ìæ , ¢®§¢à é ¥âáï
á®áâ®ï­¨¥ ॣ¨áâ஢ 3-ª®«ìæ .
* à®æ¥áá ¤®«¦¥­ ¡ëâì § £à㦥­ ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ­® ¢
®¡é¥¬ ®¯¨á ­¨¨).
 
======================================================================
====================== ”ã­ªæ¨ï 69, ¯®¤äã­ªæ¨ï 2 ======================
======== “áâ ­®¢¨âì á®áâ®ï­¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ========
======================================================================
 à ¬¥âàë:
* eax = 69 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¤¥­â¨ä¨ª â®à ¯®â®ª 
* edx = ¤«¨­  áâàãªâãàë ª®­â¥ªáâ , ¤®«¦­® ¡ëâì 0x28=40 ¡ ©â
* esi = 㪠§ â¥«ì ­  áâàãªâãàã ª®­â¥ªáâ 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
”®à¬ â áâàãªâãàë ª®­â¥ªáâ  ãª § ­ ¢ ®¯¨á ­¨¨ ¯®¤ä㭪樨 1.
‡ ¬¥ç ­¨ï:
* …᫨ ¯®â®ª ¢ë¯®«­ï¥â ª®¤ 0-ª®«ìæ , ãáâ ­ ¢«¨¢ ¥âáï
á®áâ®ï­¨¥ ॣ¨áâ஢ 3-ª®«ìæ .
* à®æ¥áá ¤®«¦¥­ ¡ëâì § £à㦥­ ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ­® ¢
®¡é¥¬ ®¯¨á ­¨¨).
 
======================================================================
== ”ã­ªæ¨ï 69, ¯®¤äã­ªæ¨ï 3 - ®âª«îç¨âìáï ®â ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . =
======================================================================
 à ¬¥âàë:
* eax = 69 - ­®¬¥à ä㭪樨
* ebx = 3 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¤¥­â¨ä¨ª â®à
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* …᫨ ¯à®æ¥áá ¡ë« ¯à¨®áâ ­®¢«¥­, ®­ ¢®§®¡­®¢«ï¥â ¢ë¯®«­¥­¨¥.
 
======================================================================
==== ”ã­ªæ¨ï 69, ¯®¤äã­ªæ¨ï 4 - ¯à¨®áâ ­®¢¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª. ====
======================================================================
 à ¬¥âàë:
* eax = 69 - ­®¬¥à ¯à®æ¥áá 
* ebx = 4 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¤¥­â¨ä¨ª â®à
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* à®æ¥áá ¤®«¦¥­ ¡ëâì § £à㦥­ ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ­® ¢
®¡é¥¬ ®¯¨á ­¨¨).
 
======================================================================
====================== ”ã­ªæ¨ï 69, ¯®¤äã­ªæ¨ï 5 ======================
============ ‚®§®¡­®¢¨âì ¢ë¯®«­¥­¨¥ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ============
======================================================================
 à ¬¥âàë:
* eax = 69 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¤¥­â¨ä¨ª â®à
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* à®æ¥áá ¤®«¦¥­ ¡ëâì § £à㦥­ ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ­® ¢
®¡é¥¬ ®¯¨á ­¨¨).
 
======================================================================
====================== ”ã­ªæ¨ï 69, ¯®¤äã­ªæ¨ï 6 ======================
============= à®ç¨â âì ¨§ ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . ============
======================================================================
 à ¬¥âàë:
* eax = 69 - ­®¬¥à ä㭪樨
* ebx = 6 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¤¥­â¨ä¨ª â®à
* edx = ᪮«ìª® ¡ ©â ç¨â âì
* esi =  ¤à¥á ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá 
* edi = 㪠§ â¥«ì ­  ¡ãä¥à ¤«ï ¤ ­­ëå
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 ¯à¨ ®è¨¡ª¥ (­¥¢¥à­ë© PID ¨«¨ ¡ãä¥à)
* ¨­ ç¥ eax = ç¨á«® ¯à®ç¨â ­­ëå ¡ ©â (¢®§¬®¦­®, 0,
¥á«¨ ¢ esi ᫨誮¬ ¡®«ì讥 §­ ç¥­¨¥)
‡ ¬¥ç ­¨ï:
* à®æ¥áá ¤®«¦¥­ ¡ëâì § £à㦥­ ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ­® ¢
®¡é¥¬ ®¯¨á ­¨¨).
 
======================================================================
”ã­ªæ¨ï 69, ¯®¤äã­ªæ¨ï 7 - § ¯¨á âì ¢ ¯ ¬ïâì ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá .
======================================================================
 à ¬¥âàë:
* eax = 69 - ­®¬¥à ä㭪樨
* ebx = 7 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¤¥­â¨ä¨ª â®à
* edx = ᪮«ìª® ¡ ©â ¯¨á âì
* esi =  ¤à¥á ¯ ¬ï⨠¢ ®â« ¦¨¢ ¥¬®¬ ¯à®æ¥áá¥
* edi = 㪠§ â¥«ì ­  ¤ ­­ë¥
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 ¯à¨ ®è¨¡ª¥ (­¥¢¥à­ë© PID ¨«¨ ¡ãä¥à)
* ¨­ ç¥ eax = ç¨á«® § ¯¨á ­­ëå ¡ ©â (¢®§¬®¦­®, 0,
¥á«¨ ¢ esi ᫨誮¬ ¡®«ì讥 §­ ç¥­¨¥)
‡ ¬¥ç ­¨ï:
* à®æ¥áá ¤®«¦¥­ ¡ëâì § £à㦥­ ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ­® ¢
®¡é¥¬ ®¯¨á ­¨¨).
 
======================================================================
====== ”ã­ªæ¨ï 69, ¯®¤äã­ªæ¨ï 8 - § ¢¥àè¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª. ======
======================================================================
 à ¬¥âàë:
* eax = 69 - ­®¬¥à ä㭪樨
* ebx = 8 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¤¥­â¨ä¨ª â®à
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* à®æ¥áá ¤®«¦¥­ ¡ëâì § £à㦥­ ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ­® ¢
®¡é¥¬ ®¯¨á ­¨¨).
* ”ã­ªæ¨ï  ­ «®£¨ç­  ¯®¤ä㭪樨 2 ä㭪樨 18 á ¤¢ã¬ï ®â«¨ç¨ï¬¨:
âॡã¥âáï ¢ë¯®«­¥­¨¥ ¯¥à¢®£® § ¬¥ç ­¨ï ¨ ¯à¨­¨¬ ¥âáï PID,
  ­¥ ­®¬¥à á«®â .
 
======================================================================
====================== ”ã­ªæ¨ï 69, ¯®¤äã­ªæ¨ï 9 ======================
============= “áâ ­®¢¨âì/á­ïâì  ¯¯ à â­ãî â®çªã ®áâ ­®¢ . ============
======================================================================
 à ¬¥âàë:
* eax = 69 - ­®¬¥à ä㭪樨
* ebx = 9 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¨¤¥­â¨ä¨ª â®à ¯®â®ª 
* dl = ¨­¤¥ªá â®çª¨ ®áâ ­®¢ , ®â 0 ¤® 3 ¢ª«îç¨â¥«ì­®
* dh = ä« £¨:
* ¥á«¨ áâ à訩 ¡¨â á¡à®è¥­ - ãáâ ­®¢¨âì â®çªã ®áâ ­®¢ :
* ¡¨âë 0-1 - ãá«®¢¨¥:
* 00 = â®çª  ®áâ ­®¢  ­  ¢ë¯®«­¥­¨¥
* 01 = â®çª  ®áâ ­®¢  ­  § ¯¨áì
* 11 = â®çª  ®áâ ­®¢  ­  ç⥭¨¥/§ ¯¨áì
* ¡¨âë 2-3 - ¤«¨­ ; ¤«ï â®ç¥ª ®áâ ­®¢  ­  ¨á¯®«­¥­¨¥ ¤®«¦­® ¡ëâì
00, ¢ ¯à®â¨¢­®¬ á«ãç ¥ ®¤­® ¨§
* 00 = ¡ ©â
* 01 = á«®¢®
* 11 = ¤¢®©­®¥ á«®¢®
* esi =  ¤à¥á â®çª¨ ®áâ ­®¢ ; ¤®«¦¥­ ¡ëâì ¢ë஢­¥­
ᮮ⢥âá⢥­­® ¤«¨­¥ (â.¥. ¤®«¦¥­ ¡ëâì çñâ­ë¬ ¤«ï
â®ç¥ª ®áâ ­®¢  ­  á«®¢®, ªà â¥­ 4 ¤«ï ¤¢®©­®£® á«®¢ )
* ¥á«¨ áâ à訩 ¡¨â ãáâ ­®¢«¥­ - á¡à®á¨âì â®çªã ®áâ ­®¢ 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ®è¨¡ª  ¢® ¢å®¤­ëå ¤ ­­ëå
* eax = 2 - (§ à¥§¥à¢¨à®¢ ­®, ­¨ª®£¤  ­¥ ¢®§¢à é ¥âáï
¢ ⥪ã饩 ॠ«¨§ æ¨¨) á í⨬ ¨­¤¥ªá®¬ 㦥 ãáâ ­®¢«¥­ 
£«®¡ «ì­ ï â®çª  ®áâ ­®¢ 
‡ ¬¥ç ­¨ï:
* à®æ¥áá ¤®«¦¥­ ¡ëâì § £à㦥­ ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ­® ¢
®¡é¥¬ ®¯¨á ­¨¨).
* €¯¯ à â­ë¥ â®çª¨ ®áâ ­®¢  ॠ«¨§ãîâáï ç¥à¥§ DRx-ॣ¨áâàë
¯à®æ¥áá®à , ®âá ¢á¥ ®£à ­¨ç¥­¨ï.
* ”ã­ªæ¨ï ¬®¦¥â ¯¥à¥ãáâ ­®¢¨âì à ­¥¥ ãáâ ­®¢«¥­­ãî ¥© ¦¥
â®çªã ®áâ ­®¢  (­¨ª ª ­¥ á®®¡é ï ®¡ í⮬).
‚¥¤¨â¥ ᯨ᮪ ãáâ ­®¢«¥­­ëå â®ç¥ª ®áâ ­®¢  ¢ ®â« ¤ç¨ª¥.
* ‘à ¡ â뢠­¨¥ â®çª¨ ®áâ ­®¢  § ª«îç ¥âáï ¢ £¥­¥à¨à®¢ ­¨¨
®â« ¤®ç­®£® ¨áª«î祭¨ï #DB, ® ª®â®à®¬ á¨á⥬  á®®¡é ¥â ®â« ¤ç¨ªã.
* ’®çª  ®áâ ­®¢  ­  § ¯¨áì ¨ ç⥭¨¥/§ ¯¨áì áà ¡ â뢠¥â ¯®á«¥
¢ë¯®«­¥­¨ï ¢ë§¢ ¢è¥© ¥ñ ¨­áâàãªæ¨¨.
 
======================================================================
= ”ã­ªæ¨ï 70 - à ¡®â  á ä ©«®¢®© á¨á⥬®© á ¯®¤¤¥à¦ª®© ¤«¨­­ëå ¨¬ñ­. =
======================================================================
 à ¬¥âàë:
* eax = 70
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮; ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ¢ § ¢¨á¨¬®á⨠®â ¯®¤ä㭪樨 ¬®¦¥â ¢®§¢à é âìáï §­ ç¥­¨¥ ¨
¢ ¤à㣨å ॣ¨áâà å
Ž¡é¨© ä®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ᬥ饭¨¥ ¢ ä ©«¥
* +8: dword: áâ à訩 dword ᬥ饭¨ï (¤®«¦¥­ ¡ëâì 0) ¨«¨ ¯®«¥ ä« £®¢
* +12 = +0xC: dword: à §¬¥à
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¤ ­­ë¥
* +20 = +0x14: n db: ASCIIZ-áâப  á ¨¬¥­¥¬ ä ©« 
¨«¨
* +20 = +0x14: db 0
* +21 = +0x15: dd 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¨¬¥­¥¬ ä ©« 
“â®ç­¥­¨ï - ¢ ¤®ªã¬¥­â æ¨¨ ­  ᮮ⢥âáâ¢ãîéãî ¯®¤äã­ªæ¨î.
ˆ¬ï ä ©«  ­¥çã¢á⢨⥫쭮 ª ॣ¨áâà㠡㪢. ãá᪨¥ ¡ãª¢ë ¤®«¦­ë ¡ëâì
§ ¯¨á ­ë ¢ ª®¤¨à®¢ª¥ cp866 (DOS).
”®à¬ â ¨¬¥­¨ ä ©« :
/base/number/dir1/dir2/.../dirn/file,
£¤¥ /base/number ¨¤¥­â¨ä¨æ¨àã¥â ãáâனá⢮, ­  ª®â®à®¬ ¨é¥âáï ä ©«:
®¤­® ¨§
* /RD/1 = /RAMDISK/1 ¤«ï ¤®áâ㯠 ª à ¬¤¨áªã
* /FD/1 = /FLOPPYDISK/1 ¤«ï ¤®áâ㯠 ª ¯¥à¢®¬ã ä«®¯¯¨-¤¨áª®¢®¤ã,
/FD/2 = /FLOPPYDISK/2 ¤«ï ¢â®à®£® ä«®¯¯¨-¤¨áª®¢®¤ 
* /HD0/x, /HD1/x, /HD2/x, /HD3/x ¤«ï ¤®áâ㯠 ᮮ⢥âá⢥­­®
ª ¦ñá⪨¬ ¤¨áª ¬ ­  IDE0 (Primary Master), IDE1 (Primary Slave),
IDE2 (Secondary Master), IDE3 (Secondary Slave);
x - ­®¬¥à à §¤¥«  ­  ¢ë¡à ­­®¬ ¢¨­ç¥áâ¥à¥, ¨§¬¥­ï¥âáï ®â 1 ¤® 255
(­  ª ¦¤®¬ ¨§ ¢¨­ç¥áâ¥à®¢ ­ã¬¥à æ¨ï ­ ç¨­ ¥âáï á 1)
* /CD0/1, /CD1/1, /CD2/1, /CD3/1 ¤«ï ¤®áâ㯠 ᮮ⢥âá⢥­­®
ª CD ­  IDE0 (Primary Master), IDE1 (Primary Slave),
IDE2 (Secondary Master), IDE3 (Secondary Slave)
* /SYS - ®¯à¥¤¥«ï¥â á¨á⥬­ãî ¯ ¯ªã; ¯à¨ ®¡ëç­®© § £à㧪¥ á¨á⥬ë
á ¤¨áª¥âë íª¢¨¢ «¥­â­® /RD/1
à¨¬¥àë:
* '/rd/1/kernel.asm',0
* '/HD0/1/kernel.asm',0
* '/hd0/2/menuet/pics/tanzania.bmp',0
* '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0
* '/sys/MySuperApp.ini',0
„®áâã¯­ë¥ ¯®¤ä㭪樨:
* ¯®¤äã­ªæ¨ï 0 - ç⥭¨¥ ä ©« 
* ¯®¤äã­ªæ¨ï 1 - ç⥭¨¥ ¯ ¯ª¨
* ¯®¤äã­ªæ¨ï 2 - ᮧ¤ ­¨¥/¯¥à¥§ ¯¨áì ä ©« 
* ¯®¤äã­ªæ¨ï 3 - § ¯¨áì ¢ áãé¥áâ¢ãî騩 ä ©«
* ¯®¤äã­ªæ¨ï 4 - ãáâ ­®¢ª  à §¬¥à  ä ©« 
* ¯®¤äã­ªæ¨ï 5 - ¯®«ã祭¨¥  âਡã⮢ ä ©« /¯ ¯ª¨
* ¯®¤äã­ªæ¨ï 6 - ãáâ ­®¢ª   âਡã⮢ ä ©« /¯ ¯ª¨
* ¯®¤äã­ªæ¨ï 7 - § ¯ã᪠¯à®£à ¬¬ë
* ¯®¤äã­ªæ¨ï 8 - 㤠«¥­¨¥ ä ©« /¯ ¯ª¨
* ¯®¤äã­ªæ¨ï 9 - ᮧ¤ ­¨¥ ¯ ¯ª¨
„«ï CD-¯à¨¢®¤®¢ ¢ á¢ï§¨ á  ¯¯ à â­ë¬¨ ®£à ­¨ç¥­¨ï¬¨ ¤®áâ㯭ë
⮫쪮 ¯®¤ä㭪樨 0,1,5 ¨ 7, ¢ë§®¢ ¤àã£¨å ¯®¤ä㭪権 § ¢¥àè¨âáï
®è¨¡ª®© á ª®¤®¬ 2.
à¨ ¯¥à¢®¬ ®¡à é¥­¨¨ ¯®¤ä㭪権 0,1,5,7 ª ãáâனá⢠¬ ATAPI
(CD ¨ DVD) ¯à®¨§¢®¤¨âáï ¡«®ª¨à®¢ª  àãç­®£® ã¯à ¢«¥­¨ï ¬¥å ­¨§¬®¬
«®âª . â® á¢ï§ ­® á ªíè¨à®¢ ­¨¥¬ ¤ ­­ëå, ¯®«ã祭­ëå ®â ¯à¨¢®¤ .
 §¡«®ª¨à®¢ª  ®áãé¥á⢫ï¥âáï ¯à¨ ®¡à é¥­¨¨ ¯®¤ä㭪樨 4 ä㭪樨 24
ª ᮮ⢥âáâ¢ãî饬ã ãáâனáâ¢ã.
 
======================================================================
= ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 0 - ç⥭¨¥ ä ©«  á ¯®¤¤¥à¦ª®© ¤«¨­­ëå ¨¬ñ­. =
======================================================================
 à ¬¥âàë:
* eax = 70 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 0 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ¯®§¨æ¨ï ¢ ä ©«¥ (¢ ¡ ©â å)
* +8: dword: 0 (§ à¥§¥à¢¨à®¢ ­® ¯®¤ áâ à訩 dword ¯®§¨æ¨¨)
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ç¨â âì
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¡ãä¥à, ªã¤  ¡ã¤ãâ § ¯¨á ­ë ¤ ­­ë¥
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
¨«¨
* +20 = +0x14: db 0
* +21 = +0x15: dd 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¨¬¥­¥¬ ä ©« 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx = ç¨á«® ¯à®ç¨â ­­ëå ¡ ©â ¨«¨
-1=0xffffffff, ¥á«¨ ä ©« ­¥ ­ ©¤¥­
‡ ¬¥ç ­¨ï:
* …᫨ ä ©« ª®­ç¨«áï à ­ìè¥, 祬 ¡ë« ¯à®ç¨â ­ ¯®á«¥¤­¨© § ¯à®è¥­­ë©
¡«®ª, â® äã­ªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥à­ñâ
eax=6 (EOF).
* ”ã­ªæ¨ï ­¥ ¯®§¢®«ï¥â ç¨â âì ¯ ¯ª¨
(¢¥à­ñâáï eax=10, access denied).
 
======================================================================
= ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 1 - ç⥭¨¥ ¯ ¯ª¨ á ¯®¤¤¥à¦ª®© ¤«¨­­ëå ¨¬ñ­. =
======================================================================
 à ¬¥âàë:
* eax = 70 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 1 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ¨­¤¥ªá ­ ç «ì­®£® ¡«®ª  (áç¨â ï á 0)
* +8: dword: ¯®«¥ ä« £®¢:
* ¡¨â 0 (¬ áª  1): ¢ ª ª®¬ ä®à¬ â¥ ¢®§¢à é âì ¨¬¥­ ,
0=ANSI, 1=UNICODE
* ¯à®ç¨¥ ¡¨âë § à¥§¥à¢¨à®¢ ­ë ¨ ¤®«¦­ë ¡ëâì ãáâ ­®¢«¥­ë ¢ 0
¤«ï ¡ã¤ã饩 ᮢ¬¥á⨬®áâ¨
* +12 = +0xC: dword: ᪮«ìª® ¡«®ª®¢ ç¨â âì
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¡ãä¥à, ªã¤  ¡ã¤ãâ § ¯¨á ­ë
¤ ­­ë¥, à §¬¥à ¡ãä¥à  ¤®«¦¥­ ¡ëâì ­¥ ¬¥­ìè¥ 32 + [+12]*560 ¡ ©â
* +20 = +0x14: ASCIIZ-¨¬ï ¯ ¯ª¨, ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
¨«¨
* +20 = +0x14: db 0
* +21 = +0x15: dd 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¨¬¥­¥¬ ä ©« 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx = ç¨á«® ä ©«®¢, ¨­ä®à¬ æ¨ï ® ª®â®àëå ¡ë«  § ¯¨á ­  ¢ ¡ãä¥à,
¨«¨ -1=0xffffffff, ¥á«¨ ¯ ¯ª  ­¥ ­ ©¤¥­ 
‘âàãªâãà  ¡ãä¥à :
* +0: 32*byte: § £®«®¢®ª
* +32 = +0x20: n1*byte: ¡«®ª á ¨­ä®à¬ æ¨¥© ® ä ©«¥ 1
* +32+n1: n2*byte: ¡«®ª á ¨­ä®à¬ æ¨¥© ® ä ©«¥ 2
* ...
‘âàãªâãà  § £®«®¢ª :
* +0: dword: ¢¥àá¨ï áâàãªâãàë (⥪ãé ï ¢¥àá¨ï = 1)
* +4: dword: ª®«¨ç¥á⢮ à §¬¥éñ­­ëå ¡«®ª®¢; ­¥ ¡®«ìè¥, 祬 § ¯à®è¥­®
¢ ¯®«¥ +12 ¨­ä®à¬ æ¨®­­®© áâàãªâãàë; ¬®¦¥â ¡ëâì ¬¥­ìè¥,
¥á«¨ ¢ ¯ ¯ª¥ ª®­ç¨«¨áì ä ©«ë (â® ¦¥ á ¬®¥, çâ® ¨ ¢ ebx)
* +8: dword: ®¡é¥¥ ç¨á«® ä ©«®¢ ¢ ¯ ¯ª¥
* +12 = +0xC: 20*byte: § à¥§¥à¢¨à®¢ ­® (­ã«¨)
‘âàãªâãà  ¡«®ª  ¤ ­­ëå ¢å®¤  ª â «®£  („‚Š):
* +0: dword:  âਡãâë ä ©« :
* ¡¨â 0 (¬ áª  1): ä ©« ⮫쪮 ¤«ï ç⥭¨ï
* ¡¨â 1 (¬ áª  2): ä ©« ï¥âáï áªàëâë¬
* ¡¨â 2 (¬ áª  4): ä ©« ï¥âáï á¨á⥬­ë¬
* ¡¨â 3 (¬ áª  8): íâ® ­¥ ä ©«,   ¬¥âª  ⮬ 
(­  § ¤ ­­®¬ à §¤¥«¥ ¢áâà¥ç ¥âáï ­¥ ¡®«¥¥ ®¤­®£® à §  ¨
⮫쪮 ¢ ª®à­¥¢®© ¯ ¯ª¥)
* ¡¨â 4 (¬ áª  0x10): íâ® ¯ ¯ª 
* ¡¨â 5 (¬ áª  0x20): ä ©« ­¥  à娢¨à®¢ «áï - ¬­®£¨¥ ¯à®£à ¬¬ë
 à娢 æ¨¨ ¨¬¥îâ ®¯æ¨î, ¯® ª®â®à®©  à娢¨àãîâáï ⮫쪮 ä ©«ë
á ãáâ ­®¢«¥­­ë¬ í⨬ ¡¨â®¬, ¯®á«¥ 祣® íâ®â ¡¨â á¡à á뢠¥âáï -
íâ® ¬®¦¥â ¡ëâì ¯®«¥§­® ¤«ï  ¢â®¬ â¨ç¥áª®£® ᮧ¤ ­¨ï
backup- à娢®¢, ¨¡® ¯à¨ § ¯¨á¨ ¡¨â ®¡ëç­® ãáâ ­ ¢«¨¢ ¥âáï
(­¥ ¢ Kolibri, ¯à ¢¤ )
* +4: byte: ⨯ ¤ ­­ëå ¨¬¥­¨:
(ᮢ¯ ¤ ¥â á ¡¨â®¬ 0 ä« £®¢ ¨­ä®à¬ æ¨®­­®© áâàãªâãàë)
* 0 = ASCII = 1-¡ ©â­®¥ ¯à¥¤áâ ¢«¥­¨¥ ª ¦¤®£® ᨬ¢®« 
* 1 = UNICODE = 2-¡ ©â­®¥ ¯à¥¤áâ ¢«¥­¨¥ ª ¦¤®£® ᨬ¢®« 
* +5: 3*byte: § à¥§¥à¢¨à®¢ ­® (­ã«¨)
* +8: 4*byte: ¢à¥¬ï ᮧ¤ ­¨ï ä ©« 
* +12 = +0xC: 4*byte: ¤ â  ᮧ¤ ­¨ï ä ©« 
* +16 = +0x10: 4*byte: ¢à¥¬ï ¯®á«¥¤­¥£® ¤®áâ㯠 (ç⥭¨¥ ¨«¨ § ¯¨áì)
* +20 = +0x14: 4*byte: ¤ â  ¯®á«¥¤­¥£® ¤®áâ㯠
* +24 = +0x18: 4*byte: ¢à¥¬ï ¯®á«¥¤­¥© ¬®¤¨ä¨ª æ¨¨
* +28 = +0x1C: 4*byte: ¤ â  ¯®á«¥¤­¥© ¬®¤¨ä¨ª æ¨¨
* +32 = +0x20: qword: à §¬¥à ä ©«  ¢ ¡ ©â å (¤® 16777216 ’¡)
* +40 = +0x28: ¨¬ï
* ¤«ï ä®à¬ â  ASCII: ¬ ªá¨¬ «ì­ ï ¤«¨­  ¨¬¥­¨ 263 ᨬ¢®« 
(263 ¡ ©â ), ¡ ©â ¯®á«¥ ¨¬¥­¨ ¨¬¥¥â §­ ç¥­¨¥ 0
* ¤«ï ä®à¬ â  UNICODE: ¬ ªá¨¬ «ì­ ï ¤«¨­  ¨¬¥­¨ 259 ᨬ¢®«®¢
(518 ¡ ©â), ¤¢  ¡ ©â  ¯®á«¥ ¨¬¥­¨ ¨¬¥îâ §­ ç¥­¨¥ 0
”®à¬ â ¢à¥¬¥­¨:
* +0: byte: ᥪ㭤ë
* +1: byte: ¬¨­ãâë
* +2: byte: ç áë
* +3: byte: § à¥§¥à¢¨à®¢ ­® (0)
* ­ ¯à¨¬¥à, 23.59.59 § ¯¨á뢠¥âáï ª ª (¢ hex) 3B 3B 17 00
”®à¬ â ¤ âë:
* +0: byte: ¤¥­ì
* +1: byte: ¬¥áïæ
* +2: word: £®¤
* ­ ¯à¨¬¥à, 25.11.1979 § ¯¨á뢠¥âáï ª ª (¢ hex) 19 0B BB 07
‡ ¬¥ç ­¨ï:
* …᫨ ¢ „‚Š ¯à¨áãâáâ¢ã¥â ¨¬ï ¢ ASCII, â® ¤«¨­  „‚Š á®áâ ¢«ï¥â
304 ¡ ©â , ¥á«¨ ¢ UNICODE - 560 ¡ ©â. ‡­ ç¥­¨¥ ¤«¨­ë ¢ëà ¢­¥­®
­  楫®¥ ªà â­®¥ 16 ¡ ©â
(¤«ï ã᪮७¨ï ®¡à ¡®âª¨ ¢ ªíè-¯ ¬ï⨠CPU).
* ¥à¢ë© ᨬ¢®« ¯®á«¥ ¨¬¥­¨ ­ã«¥¢®© (ASCIIZ-áâப ). „ «ì­¥©è¨¥
¤ ­­ë¥ ᮤ¥à¦ â ¬ãá®à.
* …᫨ ä ©«ë ¢ ¯ ¯ª¥ ª®­ç¨«¨áì à ­ìè¥, 祬 ¡ë«® ¯à®ç¨â ­®
§ ¯à®è¥­­®¥ ª®«¨ç¥á⢮, â® äã­ªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â,
¯®á«¥ 祣® ¢¥à­ñâ eax=6 (EOF).
* ‹î¡ ï ¯ ¯ª  ­  ¤¨áª¥, ªà®¬¥ ª®à­¥¢®©, ᮤ¥à¦¨â ¤¢  ᯥ樠«ì­ëå
¢å®¤  "." ¨ "..", ¨¤¥­â¨ä¨æ¨àãîé¨å ᮮ⢥âá⢥­­® ᠬ㠯 ¯ªã ¨
த¨â¥«ìáªãî ¯ ¯ªã.
* ”ã­ªæ¨ï ¯®§¢®«ï¥â â ª¦¥ ç¨â âì ¢¨àâã «ì­ë¥ ¯ ¯ª¨ "/", "/rd",
"/fd", "/hd[n]", ¯à¨ í⮬  âਡãâë ¯®¤¯ ¯®ª ¯®« £ îâáï à ¢­ë¬¨
0x10,   ¢à¥¬¥­  ¨ ¤ âë ®¡­ã«¥­ë. €«ìâ¥à­ â¨¢­ë© ᯮᮡ ¯®«ã祭¨ï
¨­ä®à¬ æ¨¨ ®¡ ®¡®à㤮¢ ­¨¨ - ¯®¤äã­ªæ¨ï 11 ä㭪樨 18.
 
======================================================================
====================== ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 2 ======================
======== ‘®§¤ ­¨¥/¯¥à¥§ ¯¨áì ä ©«  á ¯®¤¤¥à¦ª®© ¤«¨­­ëå ¨¬ñ­. ========
======================================================================
 à ¬¥âàë:
* eax = 70 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 2 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +8: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ¯¨á âì
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¤ ­­ë¥
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
¨«¨
* +20 = +0x14: db 0
* +21 = +0x15: dd 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¨¬¥­¥¬ ä ©« 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx = ç¨á«® § ¯¨á ­­ëå ¡ ©â (¢®§¬®¦­®, 0)
‡ ¬¥ç ­¨ï:
* …᫨ ä ©« á â ª¨¬ ¨¬¥­¥¬ ­¥ áãé¥á⢮¢ «, ®­ ᮧ¤ ñâáï; ¥á«¨
áãé¥á⢮¢ «, â® ¯¥à¥§ ¯¨á뢠¥âáï.
* …᫨ ᢮¡®¤­®£® ¬¥áâ  ­  ¤¨áª¥ ­¥¤®áâ â®ç­®, â® äã­ªæ¨ï § ¯¨è¥â,
᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥à­ñâ ª®¤ ®è¨¡ª¨ 8.
* ”ã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥à­ñâáï ª®¤ ®è¨¡ª¨ 2).
 
======================================================================
====================== ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 3 ======================
======== ‡ ¯¨áì ¢ áãé¥áâ¢ãî騩 ä ©« á ¯®¤¤¥à¦ª®© ¤«¨­­ëå ¨¬ñ­. =======
======================================================================
 à ¬¥âàë:
* eax = 70 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 3 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ¯®§¨æ¨ï ¢ ä ©«¥ (¢ ¡ ©â å)
* +8: dword: áâ à訩 dword ¯®§¨æ¨¨ (¤®«¦¥­ ¡ëâì 0 ¤«ï FAT)
* +12 = +0xC: dword: ᪮«ìª® ¡ ©â ¯¨á âì
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¤ ­­ë¥
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
¨«¨
* +20 = +0x14: db 0
* +21 = +0x15: dd 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¨¬¥­¥¬ ä ©« 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx = ç¨á«® § ¯¨á ­­ëå ¡ ©â (¢®§¬®¦­®, 0)
‡ ¬¥ç ­¨ï:
* ” ©« ¤®«¦¥­ 㦥 áãé¥á⢮¢ âì, ¨­ ç¥ ¢¥à­ñâáï eax=5.
* …¤¨­á⢥­­ë¬ १ã«ìâ â®¬ § ¯¨á¨ 0 ¡ ©â ï¥âáï ãáâ ­®¢ª  ¢
 âਡãâ å ä ©«  ¤ âë/¢à¥¬¥­¨ ¬®¤¨ä¨ª æ¨¨ ¨ ¤®áâ㯠 ¢ ⥪ãéãî.
* …᫨ ­ ç «ì­ ï ¨/¨«¨ ª®­¥ç­ ï ¯®§¨æ¨ï ¢ë室¨â §  ¯à¥¤¥«ë ä ©« 
(§  ¨áª«î祭¨¥¬ ¯à¥¤ë¤ã饣® á«ãç ï), ä ©« à áè¨àï¥âáï ¤®
­¥®¡å®¤¨¬®£® à §¬¥à  ­ã«¥¢ë¬¨ ᨬ¢®« ¬¨.
* ”ã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥à­ñâáï ª®¤ ®è¨¡ª¨ 2).
 
======================================================================
========= ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 4 - ãáâ ­®¢ª  à §¬¥à  ä ©« . ========
======================================================================
 à ¬¥âàë:
* eax = 70 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 4 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ¬« ¤è¨© dword ­®¢®£® à §¬¥à  ä ©« 
* +8: dword: áâ à訩 dword ­®¢®£® à §¬¥à  ä ©« 
(¤®«¦¥­ ¡ëâì 0 ¤«ï FAT)
* +12 = +0xC: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +16 = +0x10: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
¨«¨
* +20 = +0x14: db 0
* +21 = +0x15: dd 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¨¬¥­¥¬ ä ©« 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* …᫨ ­®¢ë© à §¬¥à ä ©«  ¬¥­ìè¥ áâ à®£®, ä ©« ãᥪ ¥âáï. …᫨
­®¢ë© à §¬¥à ¡®«ìè¥ áâ à®£®, ä ©« à áè¨àï¥âáï ­ã«¥¢ë¬¨ ᨬ¢®« ¬¨.
…᫨ ­®¢ë© à §¬¥à à ¢¥­ áâ à®¬ã, ¥¤¨­á⢥­­ë¬ १ã«ìâ â®¬ ¢ë§®¢ 
ï¥âáï ãáâ ­®¢ª  ¤ âë/¢à¥¬¥­¨ ¬®¤¨ä¨ª æ¨¨ ¨ ¤®áâ㯠 ¢ ⥪ã騥.
* …᫨ ᢮¡®¤­®£® ¬¥áâ  ­  ¤¨áª¥ ­¥¤®áâ â®ç­® ¤«ï à áè¨à¥­¨ï ä ©« ,
â® äã­ªæ¨ï à áè¨à¨â ­ áª®«ìª® ¢®§¬®¦­®, ¯®á«¥ 祣® ¢¥à­ñâ
ª®¤ ®è¨¡ª¨ 8.
* ”ã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥à­ñâáï ª®¤ ®è¨¡ª¨ 2).
 
======================================================================
=== ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 5 - ¯®«ã祭¨¥ ¨­ä®à¬ æ¨¨ ® ä ©«¥/¯ ¯ª¥. ===
======================================================================
 à ¬¥âàë:
* eax = 70 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 5 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +8: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +12 = +0xC: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¡ãä¥à, ªã¤  ¡ã¤ãâ § ¯¨á ­ë ¤ ­­ë¥
(40 ¡ ©â)
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
¨«¨
* +20 = +0x14: db 0
* +21 = +0x15: dd 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¨¬¥­¥¬ ä ©« 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx à §àãè ¥âáï
ˆ­ä®à¬ æ¨ï ® ä ©«¥ ¢®§¢à é ¥âáï ¢ ä®à¬ â¥ „‚Š
(¡«®ª  ¤ ­­ëå ¢å®¤  ª â «®£ ), 㪠§ ­­®¬ ¢ ®¯¨á ­¨¨
¯®¤ä㭪樨 1, ­® ¡¥§ ¨¬¥­¨ ä ©« 
(â® ¥áâì ¯¥à¢ë¥ 40 = 0x28 ¡ ©â).
‡ ¬¥ç ­¨ï:
* ”ã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥â ¢¨àâã «ì­ë¥ ¯ ¯ª¨ ⨯  /, /rd ¨
ª®à­¥¢ë¥ ¯ ¯ª¨ ⨯  /rd/1.
 
======================================================================
===== ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 6 - ãáâ ­®¢ª   âਡã⮢ ä ©« /¯ ¯ª¨. ====
======================================================================
 à ¬¥âàë:
* eax = 70 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 6 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +8: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +12 = +0xC: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¡ãä¥à á  âਡãâ ¬¨ (32 ¡ ©â )
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
¨«¨
* +20 = +0x14: db 0
* +21 = +0x15: dd 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¨¬¥­¥¬ ä ©« 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx à §àãè ¥âáï
€âਡãâë ä ©«  - ¯¥à¢ë¥ 32 ¡ ©â  ¢ „‚Š (¡«®ª¥ ¤ ­­ëå ¢å®¤  ª â «®£ ),
ä®à¬ â ª®â®à®£® 㪠§ ­ ¢ ®¯¨á ­¨¨ ¯®¤ä㭪樨 1
(â® ¥áâì ¡¥§ ¨¬¥­¨ ¨ à §¬¥à  ä ©« ). €âਡãâ ä ©«/¯ ¯ª /¬¥âª  ⮬ 
(¡¨âë 3,4 ¢ dword'¥ +0) ­¥ ¬¥­ï¥âáï.
 ©â +4 (ä®à¬ â ¨¬¥­¨) ¨£­®à¨àã¥âáï.
‡ ¬¥ç ­¨ï:
* ”ã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥â ¢¨àâã «ì­ë¥ ¯ ¯ª¨ ⨯  /, /rd ¨
ª®à­¥¢ë¥ ¯ ¯ª¨ ⨯  /rd/1.
* ”ã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥à­ñâáï ª®¤ ®è¨¡ª¨ 2).
 
======================================================================
============ ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 7 - § ¯ã᪠¯à®£à ¬¬ë. ============
======================================================================
 à ¬¥âàë:
* eax = 70 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 7 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ¯®«¥ ä« £®¢:
* ¡¨â 0: § ¯ãáâ¨âì ¯à®æ¥áá ª ª ®â« ¦¨¢ ¥¬ë©
* ®áâ «ì­ë¥ ¡¨âë § à¥§¥à¢¨à®¢ ­ë ¨ ¤®«¦­ë ¡ëâì ãáâ ­®¢«¥­ë ¢ 0
* +8: dword: 0 ¨«¨ 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¯ à ¬¥âà ¬¨
* +12 = +0xC: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +16 = +0x10: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
¨«¨
* +20 = +0x14: db 0
* +21 = +0x15: dd 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¨¬¥­¥¬ ä ©« 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax > 0 - ¯à®£à ¬¬  § £à㦥­ , eax ᮤ¥à¦¨â PID
* eax < 0 - ¯à®¨§®è«  ®è¨¡ª , -eax ᮤ¥à¦¨â
ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* Š®¬ ­¤­ ï áâப  ¤®«¦­  § ª ­ç¨¢ âìáï ᨬ¢®«®¬ á ª®¤®¬ 0
(ASCIIZ-áâப ); ãç¨â뢠îâáï «¨¡® ¢á¥ ᨬ¢®«ë ¤® § ¢¥àè î饣® ­ã«ï
¢ª«îç¨â¥«ì­®, «¨¡® ¯¥à¢ë¥ 256 ᨬ¢®«®¢, ¢ § ¢¨á¨¬®á⨠®â ⮣®,
çâ® ¬¥­ìè¥.
* …᫨ ¯à®æ¥áá § ¯ã᪠¥âáï ª ª ®â« ¦¨¢ ¥¬ë©, ®­ ᮧ¤ ñâáï
¢ § ¬®à®¦¥­­®¬ á®áâ®ï­¨¨; ¤«ï § ¯ã᪠ ¨á¯®«ì§ã©â¥
¯®¤äã­ªæ¨î 5 ä㭪樨 69.
 
======================================================================
========== ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 8 - 㤠«¥­¨¥ ä ©« /¯ ¯ª¨. ==========
======================================================================
 à ¬¥âàë:
* eax = 70 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 8 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +8: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +12 = +0xC: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +16 = +0x10: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
¨«¨
* +20 = +0x14: db 0
* +21 = +0x15: dd 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¨¬¥­¥¬ ä ©« 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* ”ã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥à­ñâáï ª®¤ ®è¨¡ª¨ 2).
* Œ®¦­® 㤠«ïâì ⮫쪮 ¯ãáâë¥ ¯ ¯ª¨ (¯®¯ë⪠ 㤠«¥­¨ï ­¥¯ãá⮩ ¯ ¯ª¨
¯à¨¢¥¤ñâ ª ®è¨¡ª¥ á ª®¤®¬ 10, "¤®áâ㯠§ ¯à¥éñ­").
 
======================================================================
============= ”ã­ªæ¨ï 70, ¯®¤äã­ªæ¨ï 9 - ᮧ¤ ­¨¥ ¯ ¯ª¨. =============
======================================================================
 à ¬¥âàë:
* eax = 70 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 9 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +8: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +12 = +0xC: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +16 = +0x10: dword: 0 (§ à¥§¥à¢¨à®¢ ­®)
* +20 = +0x14: ASCIIZ-¨¬ï ¯ ¯ª¨, ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
¨«¨
* +20 = +0x14: db 0
* +21 = +0x15: dd 㪠§ â¥«ì ­  ASCIIZ-áâபã á ¨¬¥­¥¬ ¯ ¯ª¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* ”ã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥à­ñâáï ª®¤ ®è¨¡ª¨ 2).
* ®¤¨â¥«ìáª ï ¯ ¯ª  ¤®«¦­  㦥 áãé¥á⢮¢ âì.
* …᫨ ¯ ¯ª  㦥 áãé¥áâ¢ã¥â, äã­ªæ¨ï § ¢¥àè¨âáï ãᯥ譮 (eax=0).
 
======================================================================
=== ”ã­ªæ¨ï 71, ¯®¤äã­ªæ¨ï 1 - ãáâ ­®¢¨âì § £®«®¢®ª ®ª­  ¯à®£à ¬¬ë. ==
======================================================================
 à ¬¥âàë:
* eax = 71 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx =  ¤à¥á áâப¨ § £®«®¢ª 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ‘âப  § £®«®¢ª  ¤®«¦­  ¡ëâì ¢ ä®à¬ â¥ ASCIIZ. ‚ § £®«®¢ª¥
®â®¡à ¦ ¥âáï ­¥ ¡®«¥¥ 255 ᨬ¢®«®¢ ­¥§ ¢¨á¨¬® ®â ¯®«­®© ¤«¨­ë
áâப¨.
* —⮡ë ã¡à âì § £®«®¢®ª, ¯¥à¥¤ ©â¥ NULL ¢ ecx.
 
======================================================================
================ ”ã­ªæ¨ï 72 - ¯®á« âì á®®¡é¥­¨¥ ®ª­ã. ================
======================================================================
 
--- ®¤äã­ªæ¨ï 1 - ¯®á« âì á®®¡é¥­¨¥ á ¯ à ¬¥â஬  ªâ¨¢­®¬ã ®ª­ã. ----
 à ¬¥âàë:
* eax = 72 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ª®¤ ᮡëâ¨ï: 2 ¨«¨ 3
* edx = ª®¤ ª« ¢¨è¨ ¤«ï ecx=2, ¨¤¥­â¨ä¨ª â®à ª­®¯ª¨ ¤«ï ecx=3
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ¡ãä¥à § ¯®«­¥­
 
======================================================================
========== ”ã­ªæ¨ï -1 - § ¢¥àè¨âì ¢ë¯®«­¥­¨¥ ¯®â®ª /¯à®æ¥áá  =========
======================================================================
 à ¬¥âàë:
* eax = -1 - ­®¬¥à ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â ­¨ §­ ç¥­¨ï, ­¨ ã¯à ¢«¥­¨ï
‡ ¬¥ç ­¨ï:
* …᫨ ¯à®æ¥áá ® ­¥ ᮧ¤ ¢ « ¯®â®ª®¢, â® ã ­¥£® ¥áâì ⮫쪮
®¤¨­ ¯®â®ª, § ¢¥à襭¨¥ ª®â®à®£® ¯à¨¢®¤¨â ª § ¢¥à襭¨î ¯à®æ¥áá .
* …᫨ ⥪ã騩 ¯®â®ª - ¯®á«¥¤­¨© ¢ ¯à®æ¥áá¥, â® ¥£® § ¢¥à襭¨¥
â ª¦¥ ¯à¨¢®¤¨â ª § ¢¥à襭¨î ¯à®æ¥áá .
* â  äã­ªæ¨ï § ¢¥àè ¥â ⥪ã騩 ¯®â®ª. „à㣮© ¯®â®ª ¬®¦­® ¯à¨¡¨âì
¢ë§®¢®¬ ¯®¤ä㭪樨 2 ä㭪樨 18.
 
======================================================================
=========================== ‘¯¨á®ª ᮡë⨩ ===========================
======================================================================
Žç¥à¥¤­®¥ ᮡë⨥ ¬®¦­® ¯®«ãç¨âì ¢ë§®¢®¬ ®¤­®© ¨§ ä㭪権 10
(®¦¨¤ âì ᮡëâ¨ï), 11 (¯à®¢¥à¨âì ¡¥§ ®¦¨¤ ­¨ï), 23
(®¦¨¤ âì ¢ â¥ç¥­¨¥ § ¤ ­­®£® ¢à¥¬¥­¨).
â¨ ä㭪樨 ¢®§¢à é îâ ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã,
ãáâ ­ ¢«¨¢ ¥¬ãî ä㭪樥© 40. ® 㬮«ç ­¨î íâ® ¯¥à¢ë¥ âà¨, 祣®
¢¯®«­¥ ¤®áâ â®ç­® ¤«ï ¬­®£¨å ¯à¨«®¦¥­¨©.
Š®¤ë ᮡë⨩:
* 1 = á®®¡é¥­¨¥ ® ¯¥à¥à¨á®¢ª¥ (á¡à á뢠¥âáï ¯à¨ ¢ë§®¢¥ ä㭪樨 0)
* 2 = ­ ¦ â  ª« ¢¨è  ­  ª« ¢¨ âãॠ(¯®áâ㯠¥â, ⮫쪮 ª®£¤  ®ª­®
 ªâ¨¢­®) ¨«¨ ­ ¦ â  "£®àïç ï ª« ¢¨è ";
á¡à á뢠¥âáï, ª®£¤  ¢á¥ ª« ¢¨è¨ ¨§ ¡ãä¥à  áç¨â ­ë ä㭪樥© 2
* 3 = ­ ¦ â  ª­®¯ª , ®¯à¥¤¥«ñ­­ ï à ­¥¥ ä㭪樥© 8 (¨«¨ ª­®¯ª 
§ ªàëâ¨ï, ᮧ¤ ­­ ï ­¥ï¢­® ä㭪樥© 0; ª­®¯ª  ¬¨­¨¬¨§ æ¨¨
®¡à ¡ â뢠¥âáï á¨á⥬®© ¨ ® ­¥© á®®¡é¥­¨ï ­¥ ¯à¨å®¤¨â;
¯®áâ㯠¥â, ⮫쪮 ª®£¤  ®ª­®  ªâ¨¢­®; á¡à á뢠¥âáï, ª®£¤  ¢á¥
ª­®¯ª¨ ¨§ ¡ãä¥à  áç¨â ­ë ä㭪樥© 17)
* 4 = § à¥§¥à¢¨à®¢ ­® (¢ ⥪ã饩 ॠ«¨§ æ¨¨ ­¨ª®£¤  ­¥ ¯à¨å®¤¨â ¤ ¦¥
¯à¨ à §¬ áª¨à®¢ª¥ ä㭪樥© 40)
* 5 = ¯¥à¥à¨á®¢ë¢ ¥âáï ä®­ à ¡®ç¥£® á⮫  (á¡à á뢠¥âáï
 ¢â®¬ â¨ç¥áª¨ ¯®á«¥ ¯¥à¥à¨á®¢ª¨, â ª çâ® ¥á«¨ ¢® ¢à¥¬ï ¯¥à¥à¨á®¢ª¨
ä®­  ¯à®£à ¬¬  ­¥ ¦¤ñâ ¨ ­¥ ¯à®¢¥àï¥â ᮡëâ¨ï, â® í⮣® ᮡëâ¨ï
®­  ­¥ § ¬¥â¨â)
* 6 = ᮡë⨥ ®â ¬ëè¨ (çâ®-â® á«ã稫®áì - ­ ¦ â¨¥ ­  ª­®¯ªã ¬ëè¨
¨«¨ ¯¥à¥¬¥é¥­¨¥; á¡à á뢠¥âáï ¯à¨ ¯à®ç⥭¨¨)
* 7 = ¯à®¨§®è«® ᮡë⨥ IPC (ᬮâਠäã­ªæ¨î 60 - Inter Process
Communication; á¡à á뢠¥âáï ¯à¨ ¯à®ç⥭¨¨)
* 8 = ¯à®¨§®è«® á¥â¥¢®¥ ᮡë⨥ (á¡à á뢠¥âáï ¯à¨ ¯à®ç⥭¨¨;
ᬮâਠࠡ®âã á á¥âìî)
* 9 = ¯à®¨§®è«® ®â« ¤®ç­®¥ ᮡë⨥ (á¡à á뢠¥âáï ¯à¨ ¯à®ç⥭¨¨;
ᬮâਠ®â« ¤®ç­ãî ¯®¤á¨á⥬ã)
* 16..31 = ¯à®¨§®è«® ᮡë⨥ á ᮮ⢥âáâ¢ãî騬 IRQ
(16=IRQ0, 31=IRQ15) (á¡à á뢠¥âáï ¯à¨ áç¨â뢠­¨¨ ¢á¥å ¤ ­­ëå IRQ)
 
======================================================================
==================== Š®¤ë ®è¨¡®ª ä ©«®¢®© á¨á⥬ë ====================
======================================================================
* 0 = ãᯥ譮
* 1 = ­¥ ®¯à¥¤¥«¥­  ¡ §  ¨/¨«¨ à §¤¥« ¦ñá⪮£® ¤¨áª  (¯®¤äã­ªæ¨ï¬¨
7, 8 ä㭪樨 21)
* 2 = äã­ªæ¨ï ­¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï ¤ ­­®© ä ©«®¢®© á¨á⥬ë
* 3 = ­¥¨§¢¥áâ­ ï ä ©«®¢ ï á¨á⥬ 
* 4 = § à¥§¥à¢¨à®¢ ­®, ­¨ª®£¤  ­¥ ¢®§¢à é ¥âáï ¢ ⥪ã饩 ॠ«¨§ æ¨¨
* 5 = ä ©« ­¥ ­ ©¤¥­
* 6 = ä ©« § ª®­ç¨«áï
* 7 = 㪠§ â¥«ì ¢­¥ ¯ ¬ï⨠¯à¨«®¦¥­¨ï
* 8 = ¤¨áª § ¯®«­¥­
* 9 = â ¡«¨æ  FAT à §àã襭 
* 10 = ¤®áâ㯠§ ¯à¥éñ­
* 11 = ®è¨¡ª  ãáâனá⢠
à¨ § ¯ã᪥ ¯à®£à ¬¬ë ¢®§¬®¦­ë â ª¦¥ á«¥¤ãî騥 ª®¤ë ®è¨¡®ª:
* 30 = 0x1E = ­¥¤®áâ â®ç­® ¯ ¬ïâ¨
* 31 = 0x1F = ä ©« ­¥ ï¥âáï ¨á¯®«­¨¬ë¬
* 32 = 0x20 = ᫨誮¬ ¬­®£® ¯à®æ¥áᮢ
/kernel/branches/Kolibri-acpi/docs/sysfuncs.txt
0,0 → 1,4583
SYSTEM FUNCTIONS of OS Kolibri 0.7.5.0
 
Number of the function is located in the register eax.
The call of the system function is executed by "int 0x40" command.
All registers except explicitly declared in the returned value,
including eflags, are preserved.
 
 
======================================================================
============== Function 0 - define and draw the window. ==============
======================================================================
Defines an application window. Draws a frame of the window, header and
working area. For skinned windows defines standard close and minimize
buttons.
Parameters:
* eax = 0 - function number
* ebx = [coordinate on axis x]*65536 + [size on axis x]
* ecx = [coordinate on axis y]*65536 + [size on axis y]
* edx = 0xXYRRGGBB, where:
* Y = style of the window:
* Y=0 - type I - fixed-size window
* Y=1 - only define window area, draw nothing
* Y=2 - type II - variable-size window
* Y=3 - skinned window
* Y=4 - skinned fixed-size window
* other possible values (from 5 up to 15) are reserved,
function call with such Y is ignored
* RR, GG, BB = accordingly red, green, blue components of a color
of the working area of the window (are ignored for style Y=2)
* X = DCBA (bits)
* A = 1 - window has caption; for styles Y=3,4 caption string
must be passed in edi, for other styles use
subfunction 1 of function 71
* B = 1 - coordinates of all graphics primitives are relative to
window client area
* C = 1 - don't fill working area on window draw
* D = 0 - normal filling of the working area, 1 - gradient
The following parameters are intended for windows
of a type I and II, and ignored for styles Y=1,3:
* esi = 0xXYRRGGBB - color of the header
* RR, GG, BB define color
* Y=0 - usual window, Y=1 - unmovable window
* X defines a gradient of header: X=0 - no gradient,
X=8 - usual gradient,
for windows of a type II X=4 - negative gradient
* other values of X and Y are reserved
* edi = 0x00RRGGBB - color of the frame
Returned value:
* function does not return value
Remarks:
* Position and sizes of the window are installed by the first
call of this function and are ignored at subsequent; to change
position and/or sizes of already created window use function 67.
* For windows with styles Y=3,4 and caption (A=1) caption string
is set by the first call of this function and is ignored
at subsequent (strictly speaking, is ignored after a call to
subfunction 2 of function 12 - end redraw); to change caption of
already created window use subfunction 1 of function 71.
* If the window has appropriate styles, position and/or sizes can be
changed by user. Current position and sizes can be obtained
by function 9.
* The window must fit on the screen. If the transferred
coordinates and sizes do not satisfy to this condition,
appropriate coordinate (or, probably, both) is considered as zero,
and if it does not help too, the appropriate size
(or, probably, both) is installed in a size of the screen.
Further let us designate xpos,ypos,xsize,ysize - values passed
in ebx,ecx. The coordinates are resulted concerning
the left upper corner of the window, which, thus, is set as (0,0),
coordinates of the right lower corner essence (xsize,ysize).
* The sizes of the window are understood in sence of coordinates
of the right lower corner. This concerns all other functions too.
It means, that the real sizes are on 1 pixel more.
* The window of type I looks as follows:
* draw external frame of color indicated in edi, 1 pixel in width
* draw header - rectangle with the left upper corner (1,1) and
right lower (xsize-1,min(25,ysize)) color indicated in esi
(taking a gradient into account)
* if ysize>=26, fill the working area of the window -
rectangle with the left upper corner (1,21) and right lower
(xsize-1,ysize-1) (sizes (xsize-1)*(ysize-21)) with color
indicated in edx (taking a gradient into account)
* if A=1 and caption has been already set by subfunction 1
of function 71, it is drawn in the corresponding place of header
* The window of style Y=1 looks as follows:
* completely defined by the application
* The window of type II looks as follows:
* draw external frame of width 1 pixel with the "shaded" color
edi (all components of the color decrease twice)
* draw intermediate frame of width 3 pixels with color edi
* draw internal frame of width 1 pixel with the "shaded" color edi
* draw header - rectangle with the left upper corner (4,4)
and right lower (xsize-4,min(20,ysize)) color, indicated in esi
(taking a gradient into account)
* if ysize>=26, fill the working area of the window -
rectangle with the left upper corner (5,20) and right lower
(xsize-5,ysize-5) with color indicated in edx
(taking a gradient into account)
* if A=1 and caption has been already set by subfunction 1
of function 71, it is drawn in the corresponding place of header
* The skinned window looks as follows:
* draw external frame of width 1 pixel
with color 'outer' from the skin
* draw intermediate frame of width 3 pixel
with color 'frame' from the skin
* draw internal frame of width 1 pixel
with color 'inner' from the skin
* draw header (on bitmaps from the skin) in a rectangle
(0,0) - (xsize,_skinh-1)
* if ysize>=26, fill the working area of the window -
rectangle with the left upper corner (5,_skinh) and right lower
(xsize-5,ysize-5) with color indicated in edx
(taking a gradient into account)
* define two standard buttons: close and minimize
(see function 8)
* if A=1 and edi contains (nonzero) pointer to caption string,
it is drawn in place in header defined in the skin
* value _skinh is accessible as the result of call
subfunction 4 of function 48
 
======================================================================
================ Function 1 - put pixel in the window. ===============
======================================================================
Parameters:
* eax = 1 - function number
* ebx = x-coordinate (relative to the window)
* ecx = y-coordinate (relative to the window)
* edx = 0x00RRGGBB - color of a pixel
edx = 0x01xxxxxx - invert color of a pixel
(low 24 bits are ignored)
Returned value:
* function does not return value
 
======================================================================
============ Function 2 - get the code of the pressed key. ===========
======================================================================
Takes away the code of the pressed key from the buffer.
Parameters:
* eax = 2 - function number
Returned value:
* if the buffer is empty, function returns eax=1
* if the buffer is not empty, function returns al=0,
ah=code of the pressed key, high word of eax is zero
* if there is "hotkey", function returns al=2,
ah=scancode of the pressed key (0 for control keys),
high word of eax contains a status of control keys at the moment
of pressing a hotkey
Remarks:
* There is a common system buffer of the pressed keys
by a size of 120 bytes, organized as queue.
* There is one more common system buffer on 120 "hotkeys".
* If the application with the inactive window calls this function,
the buffer of the pressed keys is considered to be empty.
* By default this function returns ASCII-codes; to switch
to the scancodes mode (and back) use function 66.
However, hotkeys are always notificated as scancodes.
* To find out, what keys correspond to what codes, start
the application keyascii and scancode.
* Scancodes come directly from keyboard and are fixed;
ASCII-codes turn out with usage of the conversion tables,
which can be set by subfunction 2 of function 21
and get by subfunction 2 of function 26.
* As a consequence, ASCII-codes take into account current
keyboard layout (rus/en) as opposed to scancodes.
* This function notifies only about those hotkeys, which were
defined by this thread by subfunction 4 of function 66.
 
======================================================================
==================== Function 3 - get system time. ===================
======================================================================
Parameters:
* eax = 3 - function number
Returned value:
* eax = 0x00SSMMHH, where HH:MM:SS = Hours:Minutes:Seconds
* each item is BCD-number, for example,
for time 23:59:59 function returns 0x00595923
Remarks:
* See also subfunction 9 of function 26 - get time from
the moment of start of the system; it is more convenient, because
returns simply DWORD-value of the time counter.
* System time can be set by function 22.
 
======================================================================
============ Function 4 - draw text string in the window. ============
======================================================================
Parameters:
* eax = 4 - function number
* ebx = [coordinate on axis x]*65536 + [coordinate on axis y]
* ecx = 0xX0RRGGBB, where
* RR, GG, BB specify text color
* X=ABnn (bits):
* nn specifies the used font: 0=system monospaced,
1=system font of variable width
* A=0 - output esi characters, A=1 - output ASCIIZ-string
* B=1 - fill background with the color edi
* edx = pointer to the beginning of the string
* esi = for A=0 length of the string, must not exceed 255;
for A=1 is ignored
Returned value:
* function does not return value
Remarks:
* First system font is read out at loading from the file char.mt,
second - from char2.mt.
* Both fonts have height 9 pixels, width of the monospaced font
is equal to 6 pixels.
 
======================================================================
========================= Function 5 - delay. ========================
======================================================================
Delays execution of the program on the given time.
Parameters:
* eax = 5 - function number
* ebx = time in the 1/100 of second
Returned value:
* function does not return value
Remarks:
* Passing ebx=0 does not transfer control to the next process
and does not make any operations at all. If it is really required
to transfer control to the next process (to complete a current
time slice), use subfunction 1 of function 68.
 
======================================================================
============== Function 6 - read the file from ramdisk. ==============
======================================================================
Parameters:
* eax = 6 - function number
* ebx = pointer to the filename
* ecx = number of start block, beginning from 1;
ecx=0 - read from the beginning of the file (same as ecx=1)
* edx = number of blocks to read;
edx=0 - read one block (same as edx=1)
* esi = pointer to memory area for the data
Returned value:
* eax = file size in bytes, if the file was successfully read
* eax = -1, if the file was not found
Remarks:
* This function is out-of-date; function 70 allows
to fulfil the same operations with the extended possibilities.
* Block = 512 bytes.
* For reading all file you can specify the certainly large value
in edx, for example, edx = -1; but in this case be ready that
the program will "fall", if the file will appear too large and can
not be placed in the program memory.
* The filename must be either in the format 8+3 characters
(first 8 characters - name itself, last 3 - extension,
the short names and extensions are supplemented with spaces),
or in the format 8.3 characters "FILE.EXT"/"FILE.EX "
(name no more than 8 characters, dot, extension 3 characters
supplemented if necessary by spaces).
The filename must be written with capital letters. The terminating
character with code 0 is not necessary (not ASCIIZ-string).
* This function does not support folders on the ramdisk.
 
======================================================================
=============== Function 7 - draw image in the window. ===============
======================================================================
Paramters:
* eax = 7 - function number
* ebx = pointer to the image in the format BBGGRRBBGGRR...
* ecx = [size on axis x]*65536 + [size on axis y]
* edx = [coordinate on axis x]*65536 + [coordinate on axis y]
Returned value:
* function does not return value
Remarks:
* Coordinates of the image are coordinates of the upper left corner
of the image relative to the window.
* Size of the image in bytes is 3*xsize*ysize.
 
======================================================================
=============== Function 8 - define/delete the button. ===============
======================================================================
Parameters for button definition:
* eax = 8 - function number
* ebx = [coordinate on axis x]*65536 + [size on axis x]
* ecx = [coordinate on axis y]*65536 + [size on axis y]
* edx = 0xXYnnnnnn, where:
* nnnnnn = identifier of the button
* high (31st) bit of edx is cleared
* if 30th bit of edx is set - do not draw the button
* if 29th bit of edx is set - do not draw a frame
at pressing the button
* esi = 0x00RRGGBB - color of the button
Parameters for button deleting:
* eax = 8 - function number
* edx = 0x80nnnnnn, where nnnnnn - identifier of the button
Returned value:
* function does not return value
Remarks:
* Sizes of the button must be more than 0 and less than 0x8000.
* For skinned windows definition of the window
(call of 0th function) creates two standard buttons -
for close of the window with identifier 1 and
for minimize of the window with identifier 0xffff.
* The creation of two buttons with same identifiers is admitted.
* The button with the identifier 0xffff at pressing is interpreted
by the system as the button of minimization, the system handles
such pressing independently, not accessing to the application.
In rest it is usual button.
* Total number of buttons for all applications is limited to 4095.
 
======================================================================
============ Function 9 - information on execution thread. ===========
======================================================================
Parameters:
* eax = 9 - function number
* ebx = pointer to 1-Kb buffer
* ecx = number of the slot of the thread
ecx = -1 - get information on the current thread
Returned value:
* eax = maximum number of the slot of a thread
* buffer pointed to by ebx contains the following information:
* +0: dword: usage of the processor (how many time units
per second leaves on execution of this thread)
* +4: word: position of the window of thread in the window stack
* +6: word: (has no relation to the specified thread)
number of the thread slot, which window has in the window stack
position ecx
* +8: word: reserved
* +10 = +0xA: 11 bytes: name of the process
(name of corresponding executable file in the format 8+3)
* +21 = +0x15: byte: reserved, this byte is not changed
* +22 = +0x16: dword: address of the process in memory
* +26 = +0x1A: dword: size of used memory - 1
* +30 = +0x1E: dword: identifier (PID/TID)
* +34 = +0x22: dword: coordinate of the thread window on axis x
* +38 = +0x26: dword: coordinate of the thread window on axis y
* +42 = +0x2A: dword: size of the thread window on axis x
* +46 = +0x2E: dword: size of the thread window on axis y
* +50 = +0x32: word: status of the thread slot:
* 0 = thread is running
* 1 = thread is suspended
* 2 = thread is suspended while waiting for event
* 3 = thread is terminating as a result of call to function -1
or under duress as a result of call to subfunction 2
of function 18 or termination of the system
* 4 = thread is terminating as a result of exception
* 5 = thread waits for event
* 9 = requested slot is free, all other information on the slot
is not meaningful
* +52 = +0x34: word: reserved, this word is not changed
* +54 = +0x36: dword: coordinate of the client area on axis x
* +58 = +0x3A: dword: coordinate of the client area on axis y
* +62 = +0x3E: dword: width of the client area
* +66 = +0x42: dword: height of the client area
* +70 = +0x46: byte: state of the window - bitfield
* bit 0 (mask 1): window is maximized
* bit 1 (mask 2): window is minimized to panel
* bit 2 (mask 4): window is rolled up
Remarks:
* Slots are numbered starting from 1.
* Returned value is not a total number of threads, because there
can be free slots.
* When process is starting, system automatically creates
execution thread.
* Function gives information on the thread. Each process has
at least one thread. One process can create many threads,
in this case each thread has its own slot and the fields
+10, +22, +26 in these slots coincide.
Applications have no common way to define whether two threads
belong to one process.
* The active window - window on top of the window stack -
receives the messages on a keyboard input. For such window
the position in the window stack coincides with returned value.
* Slot 1 corresponds to special system thread, for which:
* the window is in the bottom of the window stack, the fields
+4 and +6 contain value 1
* name of the process - "OS/IDLE" (supplemented by spaces)
* address of the process in memory is 0, size of used memory is
16 Mb (0x1000000)
* PID=1
* coordinates and sizes of the window and the client area are by
convention set to 0
* status of the slot is always 0 (running)
* the execution time adds of time leaving on operations itself
and idle time in waiting for interrupt (which can be got by call
to subfunction 4 of function 18).
* Beginning from slot 2, the normal applications are placed.
* Applications are placed in memory at the address 0x0
(kernel constant 'std_application_base_address').
There is no intersection, as each process has its own page table.
* At creation of the thread it is assigned the slot
in the system table and identifier (Process/Thread IDentifier =
PID/TID), which do not vary with time for given thread.
After completion of the thread its slot can be anew used
for another thread. The thread identifier can not be assigned
to other thread even after completion of this thread.
Identifiers, assigned to new threads, grow monotonously.
* If the thread has not yet defined the window by call to
function 0, the position and the sizes
of its window are considered to be zero.
* Coordinates of the client area are relative to the window.
* At the moment only the part of the buffer by a size
71 = 0x37 bytes is used. Nevertheless it is recommended to use
1-Kb buffer for the future compatibility, in the future
some fields can be added.
 
======================================================================
==================== Function 10 - wait for event. ===================
======================================================================
If the message queue is empty, waits for appearance of the message
in queue. In this state thread does not consume CPU time.
Then reads out the message from queue.
 
Parameters:
* eax = 10 - function number
Returned value:
* eax = event (see the list of events)
Remarks:
* Those events are taken into account only which enter into
a mask set by function 40. By default it is
redraw, key and button events.
* To check, whether there is a message in queue, use function 11.
To wait for no more than given time, use function 23.
 
======================================================================
=============== Function 11 - check for event, no wait. ==============
======================================================================
If the message queue contains event, function reads out
and return it. If the queue is empty, function returns 0.
Parameters:
* eax = 11 - function number
Returned value:
* eax = 0 - message queue is empty
* else eax = event (see the list of events)
Remarks:
* Those events are taken into account only, which enter into
a mask set by function 40. By default it is
redraw, key and button events.
* To wait for event, use function 10.
To wait for no more than given time, use function 23.
 
======================================================================
=============== Function 12 - begin/end window redraw. ===============
======================================================================
 
---------------- Subfunction 1 - begin window redraw. ----------------
Parameters:
* eax = 12 - function number
* ebx = 1 - subfunction number
Returned value:
* function does not return value
 
----------------- Subfunction 2 - end window redraw. -----------------
Parameters:
* eax = 12 - function number
* ebx = 2 - subfunction number
Returned value:
* function does not return value
Remarks:
* Subfunction 1 deletes all buttons defined with
function 8, they must be defined again.
 
======================================================================
============ Function 13 - draw a rectangle in the window. ===========
======================================================================
Parameters:
* eax = 13 - function number
* ebx = [coordinate on axis x]*65536 + [size on axis x]
* ecx = [coordinate on axis y]*65536 + [size on axis y]
* edx = color 0xRRGGBB or 0x80RRGGBB for gradient fill
Returned value:
* function does not return value
Remarks:
* Coordinates are understood as coordinates of the left upper corner
of a rectangle relative to the window.
 
======================================================================
=================== Function 14 - get screen size. ===================
======================================================================
Parameters:
* eax = 14 - function number
Returned value:
* eax = [xsize]*65536 + [ysize], where
* xsize = x-coordinate of the right lower corner of the screen =
horizontal size - 1
* ysize = y-coordinate of the right lower corner of the screen =
vertical size - 1
Remarks:
* See also subfunction 5 of function 48 - get sizes of
working area of the screen.
 
======================================================================
== Function 15, subfunction 1 - set a size of the background image. ==
======================================================================
Parameters:
* eax = 15 - function number
* ebx = 1 - subfunction number
* ecx = width of the image
* edx = height of the image
Returned value:
* function does not return value
Remarks:
* Before calling subfunctions 2 and 5 you should call this function
to set image size!
* For update of the screen (after completion of a series of commands
working with a background) call subfunction 3.
* There is a pair function for get size of the background image -
subfunction 1 of function 39.
 
======================================================================
=== Function 15, subfunction 2 - put pixel on the background image. ==
======================================================================
Parameters:
* eax = 15 - function number
* ebx = 2 - subfunction number
* ecx = offset
* edx = color of a pixel 0xRRGGBB
Returned value:
* function does not return value
Remarks:
* Offset for a pixel with coordinates (x,y) is calculated as
(x+y*xsize)*3.
* If the given offset exceeds size set by subfunction 1,
the call is ignored.
* For update of the screen (after completion of a series of commands
working with a background) call subfunction 3.
* There is a pair function for get pixel on the background image -
subfunction 2 of function 39.
 
======================================================================
=========== Function 15, subfunction 3 - redraw background. ==========
======================================================================
Parameters:
* eax = 15 - function number
* ebx = 3 - subfunction number
Returned value:
* function does not return value
 
======================================================================
== Function 15, subfunction 4 - set drawing mode for the background. =
======================================================================
Parameters:
* eax = 15 - function number
* ebx = 4 - subfunction number
* ecx = drawing mode:
* 1 = tile
* 2 = stretch
Returned value:
* function does not return value
Remarks:
* For update of the screen (after completion of a series of commands
working with a background) call subfunction 3.
* There is a pair function for get drawing mode of the background -
subfunction 4 of function 39.
 
======================================================================
===================== Function 15, subfunction 5 =====================
============ Put block of pixels on the background image. ============
======================================================================
Parameters:
* eax = 15 - function number
* ebx = 5 - subfunction number
* ecx = pointer to the data in the format BBGGRRBBGGRR...
* edx = offset in data of the background image
* esi = size of data in bytes = 3 * number of pixels
Returned value:
* function does not return value
Remarks:
* Offset and size are not checked for correctness.
* Color of each pixel is stored as 3-bytes value BBGGRR.
* Pixels of the background image are written sequentially
from left to right, from up to down.
* Offset of pixel with coordinates (x,y) is (x+y*xsize)*3.
* For update of the screen (after completion of a series of commands
working with a background) call subfunction 3.
 
======================================================================
===================== Function 15, subfunction 6 =====================
======== Map background data to the address space of process. ========
======================================================================
Parameters:
* eax = 15 - function number
* ebx = 6 - subfunction number
Returned value:
* eax = pointer to background data, 0 if error
Remarks:
* Mapped data are available for read and write.
* Size of background data is 3*xsize*ysize. The system blocks
changes of background sizes while process works with mapped data.
* Color of each pixel is stored as 3-bytes value BBGGRR.
* Pixels of the background image are written sequentially
from left to right, from up to down.
 
======================================================================
===== Function 15, subfunction 7 - close mapped background data. =====
======================================================================
Parameters:
* eax = 15 - function number
* ebx = 7 - subfunction number
* ecx = pointer to mapped data
Returned value:
* eax = 1 - success, 0 - error
 
======================================================================
=============== Function 16 - save ramdisk on a floppy. ==============
======================================================================
Parameters:
* eax = 16 - function number
* ebx = 1 or ebx = 2 - on which floppy save
Returned value:
* eax = 0 - success
* eax = 1 - error
 
======================================================================
======= Function 17 - get the identifier of the pressed button. ======
======================================================================
Takes away the code of the pressed button from the buffer.
Parameters:
* eax = 17 - function number
Returned value:
* if the buffer is empty, function returns eax=1
* if the buffer is not empty:
* high 24 bits of eax contain button identifier (in particular,
ah contains low byte of the identifier; if all buttons have
the identifier less than 256, ah is enough to distinguish)
* al = 0 - the button was pressed with left mouse button
* al = bit corresponding to used mouse button otherwise
Remarks:
* "Buffer" keeps only one button, at pressing the new button the
information about old is lost.
* The call of this function by an application with inactive window
will return answer "buffer is empty".
* Returned value for al corresponds to the state of mouse buttons
as in subfunction 2 of function 37 at the beginning
of button press, excluding lower bit, which is cleared.
 
======================================================================
= Function 18, subfunction 2 - terminate process/thread by the slot. =
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 2 - subfunction number
* ecx = number of the slot of process/thread
Returned value:
* function does not return value
Remarks:
* It is impossible to terminate system thread OS/IDLE (with
number of the slot 1),
it is possible to terminate any normal process/thread.
* See also subfunction 18 - terminate
process/thread by the identifier.
 
======================================================================
===================== Function 18, subfunction 3 =====================
============= Make active the window of the given thread. ============
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 3 - subfunction number
* ecx = number of the thread slot
Returned value:
* function does not return value
Remarks:
* If correct, but nonexistent slot is given,
some window is made active.
* To find out, which window is active, use subfunction 7.
 
======================================================================
===================== Function 18, subfunction 4 =====================
=========== Get counter of idle time units per one second. ===========
======================================================================
Idle time units are units, in which the processor stands idle
in waiting for interrupt (in the command 'hlt').
 
Parameters:
* eax = 18 - function number
* ebx = 4 - subfunction number
Returned value:
* eax = value of the counter of idle time units per one second
 
======================================================================
========== Function 18, subfunction 5 - get CPU clock rate. ==========
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 5 - subfunction number
Returned value:
* eax = clock rate (modulo 2^32 clock ticks = 4GHz)
 
======================================================================
Function 18, subfunction 6 - save ramdisk to the file on hard drive.
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 6 - subfunction number
* ecx = pointer to the full path to file
(for example, "/hd0/1/kolibri/kolibri.img")
Returned value:
* eax = 0 - success
* else eax = error code of the file system
Remarks:
* All folders in the given path must exist, otherwise function
returns value 5, "file not found".
 
======================================================================
=========== Function 18, subfunction 7 - get active window. ==========
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 7 - subfunction number
Returned value:
* eax = number of the active window
(number of the slot of the thread with active window)
Remarks:
* Active window is at the top of the window stack and receives
messages on all keyboard input.
* To make a window active, use subfunction 3.
 
======================================================================
== Function 18, subfunction 8 - disable/enable the internal speaker. =
======================================================================
If speaker sound is disabled, all calls to subfunction 55 of
function 55 are ignored. If speaker sound is enabled,
they are routed on builtin speaker.
 
------------------- Subsubfunction 1 - get status. -------------------
Parameters:
* eax = 18 - function number
* ebx = 8 - subfunction number
* ecx = 1 - number of the subsubfunction
Returned value:
* eax = 0 - speaker sound is enabled; 1 - disabled
 
----------------- Subsubfunction 2 - toggle status. ------------------
Toggles states of disable/enable.
Parameters:
* eax = 18 - function number
* ebx = 8 - subfunction number
* ecx = 2 - number of the subsubfunction
Returned value:
* function does not return value
 
======================================================================
== Function 18, subfunction 9 - system shutdown with the parameter. ==
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 9 - subfunction number
* ecx = parameter:
* 2 = turn off computer
* 3 = reboot computer
* 4 = restart the kernel from the file 'kernel.mnt' on ramdisk
Returned value:
* at incorrect ecx the registers do not change (i.e. eax=18)
* by correct call function always returns eax=0
as the tag of success
Remarks:
* Do not rely on returned value by incorrect call, it can be
changed in future versions of the kernel.
 
======================================================================
===== Function 18, subfunction 10 - minimize application window. =====
======================================================================
Minimizes the own window.
Parameters:
* eax = 18 - function number
* ebx = 10 - subfunction number
Returned value:
* function does not return value
Remarks:
* The minimized window from the point of view of function 9
keeps position and sizes.
* Restoring of an application window occurs at its activation by
subfunction 3.
* Usually there is no necessity to minimize/restire a window
obviously: minimization of a window is carried out by the system
at pressing the minimization button (for skinned windows
it is defined automatically by function 0,
for other windows it can be defined manually by function 8),
restore of a window is done by the application '@panel'.
 
======================================================================
Function 18, subfunction 11 - get information on the disk subsystem.
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 11 - subfunction number
* ecx = type of the table:
* 1 = short version, 10 bytes
* 2 = full version, 65536 bytes
* edx = pointer to the buffer (in the application) for the table
Returned value:
* function does not return value
Format of the table: short version:
* +0: byte: information about FDD's (drives for floppies),
AAAABBBB, where AAAA gives type of the first drive, BBBB -
of the second regarding to the following list:
* 0 = there is no drive
* 1 = 360Kb, 5.25''
* 2 = 1.2Mb, 5.25''
* 3 = 720Kb, 3.5''
* 4 = 1.44Mb, 3.5''
* 5 = 2.88Mb, 3.5'' (such drives are not used anymore)
For example, for the standard configuration from one 1.44-drive
here will be 40h, and for the case 1.2Mb on A: and 1.44Mb on B:
the value is 24h.
* +1: byte: information about hard disks and CD-drives, AABBCCDD,
where AA corresponds to the controller IDE0, ..., DD - IDE3:
* 0 = device is absent
* 1 = hard drive
* 2 = CD-drive
For example, in the case HD on IDE0 and CD on IDE2
this field contains 48h.
* +2: 4 db: number of the retrieved partitions on hard disks
at accordingly IDE0,...,IDE3.
If the hard disk on IDEx is absent, appropriate byte is zero,
otherwise it shows number of the recognized partitions, which
can be not presented (if the drive is not formatted or if
the file system is not supported). Current version of the kernel
supports only FAT16, FAT32 and NTFS for hard disks.
* +6: 4 db: reserved
Format of the table: full version:
* +0: 10 db: same as for the short version
* +10: 100 db: data for the first partition
* +110: 100 db: data for the second partition
* ...
* +10+100*(n-1): 100 db: data for the last partition
The partitions are located as follows: at first sequentially all
recoginzed partitions on HD on IDE0 (if present),
then on HD on IDE1 (if present) and so on up to IDE3.
Format of the information about partition
(at moment only FAT is supported):
* +0: dword: first physical sector of the partition
* +4: dword: last physical sector of the partition
(belongs to the partition)
* +8: byte: file system type:
16=FAT16, 32=FAT32, 1=NTFS
* other data are dependent on file system, are modified with
kernel modifications and therefore are not described
Remarks:
* The short table can be used for obtaining the information about
available devices.
 
======================================================================
========== Function 18, subfunction 13 - get kernel version. =========
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 13 - subfunction number
* ecx = pointer to the buffer (not less than 16 bytes), where
the information will be placed
Returned value:
* function does not return value
Structure of the buffer:
db a,b,c,d for version a.b.c.d
db UID_xxx: one of UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2
dd REV - kernel SVN revision number
For Kolibri 0.7.1.0 kernel:
db 0,7,0,0
db 2
dd 638
 
======================================================================
======= Function 18, subfunction 14 - wait for screen retrace. =======
======================================================================
Waits for the beginning of retrace of the scanning ray of the screen
monitor.
Parameters:
* eax = 18 - function number
* ebx = 14 - subfunction number
Returned value:
* eax = 0 as the tag of success
Remarks:
* Function is intended only for active high-efficiency graphics
applications; is used for smooth output of a graphics.
 
======================================================================
== Function 18, subfunction 15 - center mouse cursor on the screen. ==
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 15 - subfunction number
Returned value:
* eax = 0 as the tag of success
 
======================================================================
========= Function 18, subfunction 16 - get size of free RAM. ========
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 16 - subfunction number
Returned value:
* eax = size of free memory in kilobytes
 
======================================================================
======== Function 18, subfunction 17 - get full amount of RAM. =======
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 17 - subfunction number
Returned value:
* eax = total size of existing memory in kilobytes
 
======================================================================
===================== Function 18, subfunction 18 ====================
============= Terminate process/thread by the identifier. ============
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 18 - subfunction number
* ecx = identifer of process/thread (PID/TID)
Returned value:
* eax = 0 - success
* eax = -1 - error (process is not found or is system)
Remarks:
* It is impossible to terminate system thread OS/IDLE (identifier
1), it is possible to terminate any normal process/thread.
* See also subfunction 2 - terminate
process/thread by given slot.
 
======================================================================
======== Function 18, subfunction 19 - get/set mouse features. =======
======================================================================
 
---------------- Subsubfunction 0 - get mouse speed. -----------------
Parameters:
* eax = 18 - function number
* ebx = 19 - subfunction number
* ecx = 0 - subsubfunction number
Returned value:
* eax = current mouse speed
 
---------------- Subsubfunction 1 - set mouse speed. -----------------
Parameters:
* eax = 18 - function number
* ebx = 19 - subfunction number
* ecx = 1 - subsubfunction number
* edx = new value for speed
Returned value:
* function does not return value
 
---------------- Subsubfunction 2 - get mouse delay. -----------------
Parameters:
* eax = 18 - function number
* ebx = 19 - subfunction number
* ecx = 2 - subsubfunction number
Returned value:
* eax = current mouse delay
 
---------------- Subsubfunction 3 - set mouse delay. -----------------
Parameters:
* eax = 18 - function number
* ebx = 19 - subfunction number
* ecx = 3 - subsubfunction number
* edx = new value for mouse delay
Returned value:
* function does not return value
 
----------- Subsubfunction 4 - set mouse pointer position. -----------
Parameters:
* eax = 18 - function number
* ebx = 19 - subfunction number
* ecx = 4 - subsubfunction number
* edx = [coordinate on axis x]*65536 + [coordinate on axis y]
Returned value:
* function does not return value
 
-------- Subsubfunction 5 - simulate state of mouse buttons. ---------
Parameters:
* eax = 18 - function number
* ebx = 19 - subfunction number
* ecx = 5 - subsubfunction number
* edx = information about emulated state of mouse buttons:
(same as return value in subfunction 2 of function 37)
* bit 0 is set = left button is pressed
* bit 1 is set = right button is pressed
* bit 2 is set = middle button is pressed
* bit 3 is set = 4th button is pressed
* bit 4 is set = 5th button is pressed
Returned value:
* function does not return value
Remarks:
* It is recommended to set speed of the mouse (in subsubfunction 1)
from 1 up to 9. The installed value is not inspected by the kernel
code, so set it carefully, at incorrect value the cursor
can "freeze". Speed of the mouse can be regulated through the
application SETUP.
* Recommended delay of the mouse (in subsubfunction 3) = 10. Lower
value is not handled by COM mice. At the very large values the
movement of the mouse on 1 pixel is impossible and the cursor will
jump on the value of installed speed (subsubfunction 1). The
installed value is not inspected by the kernel code.
Mouse delay can be regulated through the application SETUP.
* The subsubfunction 4 does not check the passed value. Before
its call find out current screen resolution (with function 14)
and check that the value of position is inside the limits of the
screen.
 
======================================================================
======== Function 18, subfunction 20 - get information on RAM. =======
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 20 - subfunction number
* ecx = pointer to the buffer for information (36 bytes)
Returned value:
* eax = total size of existing RAM in pages
or -1 if error has occured
* buffer pointed to by ecx contains the following information:
* +0: dword: total size of existing RAM in pages
* +4: dword: size of free RAM in pages
* +8: dword: number of page faults (exceptions #PF)
in applications
* +12: dword: size of kernel heap in bytes
* +16: dword: free in kernel heap in bytes
* +20: dword: total number of memory blocks in kernel heap
* +24: dword: number of free memory blocks in kernel heap
* +28: dword: size of maximum free block in kernel heap
(reserved)
* +32: dword: size of maximum allocated block in kernel heap
(reserved)
 
======================================================================
===================== Function 18, subfunction 21 ====================
======== Get slot number of process/thread by the identifier. ========
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 21 - subfunction number
* ecx = identifer of process/thread (PID/TID)
Returned value:
* eax = 0 - error (invalid identifier)
* otherwise eax = slot number
 
======================================================================
===================== Function 18, subfunction 22 ====================
============== Operations with window of another thread. =============
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 22 - subfunction number
* ecx = operation type:
* 0 = minimize window of the thread with given slot number
* 1 = minimize window of the thread with given identifier
* 2 = restore window of the thread with given slot number
* 3 = restore window of the thread with given identifier
* edx = parameter (slot number or PID/TID)
Returned value:
* eax = 0 - success
* eax = -1 - error (invalid identifier)
Remarks:
* The thread can minimize its window with subfunction 10.
* One can restore and activate window simultaneously with
subfunction 3 (which requires slot number).
 
======================================================================
==================== Function 20 - MIDI interface. ===================
======================================================================
 
----------------------- Subfunction 1 - reset ------------------------
Parameters:
* eax = 20 - function number
* ebx = 1 - subfunction number
 
-------------------- Subfunction 2 - output byte ---------------------
Parameters:
* eax = 20 - function number
* ebx = 2 - subfunction number
* cl = byte for output
Returned value (is the same for both subfunctions):
* eax = 0 - success
* eax = 1 - base port is not defined
Remarks:
* Previously the base port must be defined by
subfunction 1 of function 21.
 
======================================================================
======== Function 21, subfunction 1 - set MPU MIDI base port. ========
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 1 - subfunction number
* ecx = number of base port
Returned value
* eax = 0 - success
* eax = -1 - erratic number of a port
Remarks:
* Number of a port must satisfy to conditions 0x100<=ecx<=0xFFFF.
* The installation of base is necessary for function 20.
* To get base port use subfunction 1 of function 26.
 
======================================================================
========== Function 21, subfunction 2 - set keyboard layout. =========
======================================================================
Keyboard layout is used to convert keyboard scancodes to ASCII-codes,
which will be read by function 2.
Parameters:
* eax = 21 - function number
* ebx = 2 - subfunction number
* ecx = which layout to set:
* 1 = normal layout
* 2 = layout at pressed Shift
* 3 = layout at pressed Alt
* edx = pointer to layout - table of length 128 bytes
Or:
* ecx = 9
* dx = country identifier (1=eng, 2=fi, 3=ger, 4=rus)
Returned value:
* eax = 0 - success
* eax = 1 - incorrect parameter
Remarks:
* If Alt is pressed, the layout with Alt is used;
if Alt is not pressed, but Shift is pressed,
the layout with Shift is used;
if Alt and Shift are not pressed, but Ctrl is pressed, the normal
layout is used and then from the code is subtracted 0x60;
if no control key is pressed, the normal layout is used.
* To get layout and country identifier use
subfunction 2 of function 26.
* Country identifier is global system variable, which is not used
by the kernel itself; however the application '@panel' displays
the corresponding icon.
* The application @panel switches layouts on user request.
 
======================================================================
============== Function 21, subfunction 3 - set CD base. =============
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 3 - subfunction number
* ecx = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Returned value:
* eax = 0
Remarks:
* CD base is used by function 24.
* To get CD base use subfunction 3 of function 26.
 
======================================================================
========== Function 21, subfunction 5 - set system language. =========
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 5 - subfunction number
* ecx = system language (1=eng, 2=fi, 3=ger, 4=rus)
Returned value:
* eax = 0
Remarks:
* System language is global system variable and is not used
by the kernel itself, however application @panel draws the
appropriate icon.
* Function does not check for correctness, as the kernel does not
use this variable.
* To get system language use subfunction 5 of function 26.
 
======================================================================
============== Function 21, subfunction 7 - set HD base. =============
======================================================================
The HD base defines hard disk to write with usage of obsolete
syntax /HD in obsolete function 58; at usage of modern syntax
/HD0,/HD1,/HD2,/HD3 base is set automatically.
Parameters:
* eax = 21 - function number
* ebx = 7 - subfunction number
* ecx = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Returned value:
* eax = 0
Remarks:
* Any application at any time can change the base.
* Do not change base, when any application works with hard disk.
If you do not want system bugs.
* To get HD base use subfunction 7 of function 26.
* It is also necessary to define used partition of hard disk by
subfunction 8.
 
======================================================================
========= Function 21, subfunction 8 - set used HD partition. ========
======================================================================
The HD partition defines partition of the hard disk to write with
usage of obsolete syntax /HD and obsolete function 58;
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3
base and partition are set automatically.
Parameters:
* eax = 21 - function number
* ebx = 8 - subfunction number
* ecx = HD partition (beginning from 1)
Return value:
* eax = 0
Remarks:
* Any application at any time can change partition.
* Do not change partition when any application works with hard disk.
If you do not want system bugs.
* To get used partition use subfunction 8 of function 26.
* There is no correctness checks.
* To get the number of partitions of a hard disk use
subfunction 11 of function 18.
* It is also necessary to define used HD base by subfunction 7.
 
======================================================================
Function 21, subfunction 11 - enable/disable low-level access to HD.
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 11 - subfunction number
* ecx = 0/1 - disable/enable
Returned value:
* eax = 0
Remarks:
* Is used in LBA-read (subfunction 8 of function 58).
* The current implementation uses only low bit of ecx.
* To get current status use subfunction 11 of function 26.
 
======================================================================
Function 21, subfunction 12 - enable/disable low-level access to PCI.
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 12 - subfunction number
* ecx = 0/1 - disable/enable
Returned value:
* eax = 0
Remarks:
* Is used in operations with PCI bus (function 62).
* The current implementation uses only low bit of ecx.
* To get current status use subfunction 12 of function 26.
 
======================================================================
============ Function 21, subfunction 13, subsubfunction 1 ===========
======== Initialize + get information on the driver vmode.mdr. =======
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 1 - number of the driver function
* edx = pointer to 512-bytes buffer
Returned value:
* if driver is not loaded
(never happens in the current implementation):
* eax = -1
* ebx, ecx destroyed
* if driver is loaded:
* eax = 'MDAZ' (in fasm style, that is 'M' - low byte, 'Z' - high)
- signature
* ebx = current frequency of the scanning (in Hz)
* ecx destroyed
* buffer pointed to by edx is filled
Format of the buffer:
* +0: 32*byte: driver name, "Trans VideoDriver"
(without quotes, supplemented by spaces)
* +32 = +0x20: dword: driver version (version x.y is encoded as
y*65536+x), for the current implementation is 1 (1.0)
* +36 = +0x24: 7*dword: reserved (0 in the current implementation)
* +64 = +0x40: 32*word: list of supported videomodes (each word
is number of a videomode, after list itself there are zeroes)
* +128 = +0x80: 32*(5*word): list of supported frequences of the
scannings for videomodes: for each videomode listed in the
previous field up to 5 supported frequences are given
(unused positions contain zeroes)
Remarks:
* Function initializes the driver (if it is not initialized yet)
and must be called first, before others (otherwise they will do
nothing and return -1).
* The current implementation supports only one frequency
of the scanning on videomode.
 
======================================================================
============ Function 21, subfunction 13, subsubfunction 2 ===========
================ Get information on current videomode. ===============
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 2 - number of the driver function
Returned value:
* eax = -1 - driver is not loaded or not initialized;
ebx,ecx are destroyed
* eax = [width]*65536 + [height]
* ebx = frequency of the vertical scanning (in Hz)
* ecx = number of current videomode
Remarks:
* Driver must be initialized by call to
driver function 1.
* If only screen sizes are required, it is more expedient to use
function 14 taking into account that it
returns sizes on 1 less.
 
======================================================================
=== Function 21, subfunction 13, subsubfunction 3 - set videomode. ===
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 3 - number of the driver function
* edx = [scanning frequency]*65536 + [videomode number]
Returned value:
* eax = -1 - driver is not loaded, not initialized or
an error has occured
* eax = 0 - success
* ebx, ecx destroyed
Remarks:
* Driver must be initialized by driver function 1.
* The videomode number and frequency must be in the table
returned by driver function 1.
 
======================================================================
============ Function 21, subfunction 13, subsubfunction 4 ===========
================== Return to the initial videomode. ==================
======================================================================
Returns the screen to the videomode set at system boot.
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 4 - number of the driver function
Returned value:
* eax = -1 - driver is not loaded or not initialized
* eax = 0 - success
* ebx, ecx destroyed
Remarks:
* Driver must be initialized by call to driver function 1.
 
======================================================================
============ Function 21, subfunction 13, subsubfunction 5 ===========
===== Increase/decrease the size of the visible area of monitor. =====
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 13 - subfunction number
* ecx = 5 - number of the driver function
* edx = 0/1 - decrease/increase horizontal size on 1 position
* edx = 2/3 - is not supported in the current implementation;
is planned as decrease/increase vertical size on 1 position
Returned value:
* eax = -1 - driver is not loaded or not initialized
* eax = 0 - success
* ebx, ecx destroyed
Remarks:
* Driver must be initialized by call to driver function 1.
* Function influences only the physical size of the screen image;
the logical size (number of pixels) does not change.
 
======================================================================
================= Function 22 - set system date/time. ================
======================================================================
Parameters:
* eax = 22 - function number
* ebx = 0 - set time
* ecx = 0x00SSMMHH - time in the binary-decimal code (BCD):
* HH=hour 00..23
* MM=minute 00..59
* SS=second 00..59
* ebx = 1 - set date
* ecx = 0x00DDMMYY - date in the binary-decimal code (BCD):
* DD=day 01..31
* MM=month 01..12
* YY=year 00..99
* ebx = 2 - set day of week
* ecx = 1 for Sunday, ..., 7 for Saturday
* ebx = 3 - set alarm clock
* ecx = 0x00SSMMHH
Returned value:
* eax = 0 - success
* eax = 1 - incorrect parameter
* eax = 2 - CMOS-battery was unloaded
Remarks:
* Value of installation of day of week seems to be doubtful,
as it a little where is used
(day of week can be calculated by date).
* Alarm clock can be set on operation in the given time every day.
But there is no existing system function to disable it.
* Operation of alarm clock consists in generation IRQ8.
* Generally CMOS supports for alarm clock set of value 0xFF
as one of parameters and it means that the appropriate parameter
is ignored. But current implementation does not allow this
(will return 1).
* Alarm clock is a global system resource; the set of
an alarm clock cancels automatically the previous set.
However, at moment no program uses it.
 
======================================================================
============= Function 23 - wait for event with timeout. =============
======================================================================
If the message queue is empty, waits for new message in the queue,
but no more than given time. Then reads out a message from the queue.
 
Parameters:
* eax = 23 - function number
* ebx = timeout (in 1/100 of second)
Returned value:
* eax = 0 - the message queue is empty
* otherwise eax = event (see the list of events)
Remarks:
* Only those events are taken into account, which enter into
the mask set by function 40. By default it is
redraw, key and button events.
* To check for presence of a message in the queue use function 11.
To wait without timeout use function 10.
* Transmission ebx=0 results in immediate returning eax=0.
* Current implementation returns immediately with eax=0,
if the addition of ebx with the current value of time counter
makes 32-bit overflow.
 
======================================================================
======== Function 24, subfunction 1 - begin to play CD-audio. ========
======================================================================
Parameters:
* eax = 24 - function number
* ebx = 1 - subfunction number
* ecx = 0x00FRSSMM, where
* MM = starting minute
* SS = starting second
* FR = starting frame
Returned value:
* eax = 0 - success
* eax = 1 - CD base is not defined
Remarks:
* Previously CD base must be defined by the call to
subfunction 3 of function 21.
* One second includes 75 frames, one minute includes 60 seconds.
* The function is asynchronous (returns control, when play begins).
 
======================================================================
======= Function 24, subfunction 2 - get information on tracks. ======
======================================================================
Parameters:
* eax = 24 - function number
* ebx = 2 - subfunction number
* ecx = pointer to the buffer for the table
(maximum 8*64h+4 bytes=100 tracks)
Returned value:
* eax = 0 - success
* eax = 1 - CD base is not defined
Remarks:
* The format of the table with tracks information is the same as
for ATAPI-CD command 43h (READ TOC), usual table (subcommand 00h).
Function returns addresses in MSF.
* Previously CD base port must be set by call to
subfunction 3 of function 21.
* Function returns information only about no more than 100
first tracks. In most cases it is enough.
 
======================================================================
========== Function 24, subfunction 3 - stop play CD-audio. ==========
======================================================================
Parameters:
* eax = 24 - function number
* ebx = 1 - subfunction number
Returned value:
* eax = 0 - success
* eax = 1 - CD base is not defined
Remarks:
* Previously CD base port must be defined by call to
subfunction 3 of function 21.
 
======================================================================
======= Function 24, subfunction 4 - eject tray of disk drive. =======
======================================================================
Parameters:
* eax = 24 - function number
* ebx = 4 - subfunction number
* ecx = position of CD/DVD-drive
(from 0=Primary Master to 3=Secondary Slave)
Returned value:
* function does not return value
Remarks:
* The function is supported only for ATAPI devices (CD and DVD).
* When the tray is being ejected,
manual control of tray is unlocked.
* When the tray is being ejected, the code clears the cache for
corresponding device.
* An example of usage of the function is the application CD_tray.
 
======================================================================
======== Function 24, subfunction 5 - load tray of disk drive. =======
======================================================================
Parameters:
* eax = 24 - function number
* ebx = 5 - subfunction number
* ecx = position of CD/DVD-drive
(from 0=Primary Master to 3=Secondary Slave)
Returned value:
* function does not return value
Remarks:
* The function is supported only for ATAPI devices (CD and DVD).
* An example of usage of the function is the application CD_tray.
 
======================================================================
======== Function 26, subfunction 1 - get MPU MIDI base port. ========
======================================================================
Parameters:
* eax = 26 - function number
* ebx = 1 - subfunction number
Returned value:
* eax = port number
Parameters:
* To set base port use subfunction 1 of function 21.
 
======================================================================
========== Function 26, subfunction 2 - get keyboard layout. =========
======================================================================
The keyboard layout is used to convert keyboard scancodes to
ASCII-codes for function 2.
Parameters:
* eax = 26 - function number
* ebx = 2 - subfunction number
* ecx = what layout to get:
* 1 = normal layout
* 2 = layout with pressed Shift
* 3 = layout with pressed Alt
* edx = pointer to the 128-bytes buffer, where the layout will be
copied
Returned value:
* function does not return value
Or:
* eax = 26 - function number
* ebx = 2 - subfunction number
* ecx = 9
Returned value:
* eax = country identifier (1=eng, 2=fi, 3=ger, 4=rus)
Remarks:
* If Alt is pressed, the layout with Alt is used;
if Alt is not pressed, but Shift is pressed,
the layout with Shift is used;
if Alt and Shift are not pressed, but Ctrl is pressed, the normal
layout is used and then from the code is subtracted 0x60;
if no control key is pressed, the normal layout is used.
* To set layout and country identifier use
subfunction 2 of function 21.
* Country identifier is global system variable, which is not used
by the kernel itself; however the application '@panel' displays
the corresponding icon (using this function).
* The application @panel switches layouts on user request.
 
======================================================================
============== Function 26, subfunction 3 - get CD base. =============
======================================================================
Parameters:
* eax = 26 - function number
* ebx = 3 - subfunction number
Returned value:
* eax = CD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Remarks:
* CD base is used by function 24.
* To set CD base use subfunction 3 of function 21.
 
======================================================================
========== Function 26, subfunction 5 - get system language. =========
======================================================================
Parameters:
* eax = 26 - function number
* ebx = 5 - subfunction number
Returned value:
* eax = system language (1=eng, 2=fi, 3=ger, 4=rus)
Remarks:
* System language is global system variable and is not used
by the kernel itself, however application @panel draws the
appropriate icon (using this function).
* To set system language use subfunction 5 of function 21.
 
======================================================================
============== Function 26, subfunction 7 - get HD base. =============
======================================================================
The HD base defines hard disk to write with usage of obsolete
syntax /HD in obsolete function 58; at usage of modern syntax
/HD0,/HD1,/HD2,/HD3 base is set automatically.
Parameters:
* eax = 26 - function number
* ebx = 7 - subfunction number
Returned value:
* eax = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3
Remarks:
* Any application in any time can change HD base.
* To set base use subfunction 7 of function 21.
* To get used partition of hard disk use subfunction 8.
 
======================================================================
========= Function 26, subfunction 8 - get used HD partition. ========
======================================================================
The HD partition defines partition of the hard disk to write with
usage of obsolete syntax /HD in obsolete function 58;
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3
base and partition are set automatically.
Parameters:
* eax = 26 - function number
* ebx = 8 - subfunction number
Returned value:
* eax = HD partition (beginning from 1)
Remarks:
* Any application in any time can change partition.
* To set partition use subfunction 8 of function 21.
* To get number of partitions on a hard disk use
subfunction 11 of function 18.
* To get base of used hard disk, use subfunction 7.
 
======================================================================
=== Function 26, subfunction 9 - get the value of the time counter. ==
======================================================================
Parameters:
* eax = 26 - function number
* ebx = 9 - subfunction number
Returned value:
* eax = number of 1/100s of second, past from the system boot time
Remarks:
* Counter takes modulo 2^32, that correspond to a little more
than 497 days.
* To get system time use function 3.
 
======================================================================
===================== Function 26, subfunction 11 ====================
========== Find out whether low-level HD access is enabled. ==========
======================================================================
Parameters:
* eax = 26 - function number
* ebx = 11 - subfunction number
Returned value:
* eax = 0/1 - disabled/enabled
Remarks:
* Is used in LBA read (subfunction 8 of function 58).
* To set current state use subfunction 11 of function 21.
 
======================================================================
===================== Function 26, subfunction 12 ====================
========== Find out whether low-level PCI access is enabled. =========
======================================================================
Parameters:
* eax = 26 - function number
* ebx = 12 - subfunction number
Returned value:
* eax = 0/1 - disabled/enabled
Remarks:
* Is used by operations with PCI bus (function 62).
* The current implementation uses only low bit of ecx.
* To set the current state use subfunction 12 of function 21.
 
======================================================================
=================== Function 29 - get system date. ===================
======================================================================
Parameters:
* eax = 29 - function number
Returned value:
* eax = 0x00DDMMYY, where
(binary-decimal coding, BCD, is used)
* YY = two low digits of year (00..99)
* MM = month (01..12)
* DD = day (01..31)
Remarks:
* To set system date use function 22.
 
======================================================================
============= Function 30 - work with the current folder. ============
======================================================================
 
--------- Subfunction 1 - set current folder for the thread. ---------
Parameters:
* eax = 30 - function number
* ebx = 1 - subfunction number
* ecx = pointer to ASCIIZ-string with the path to new current folder
Returned value:
* function does not return value
 
--------- Subfunction 2 - get current folder for the thread. ---------
Parameters:
* eax = 30 - function number
* ebx = 2 - subfunction number
* ecx = pointer to buffer
* edx = size of buffer
Returned value:
* eax = size of the current folder's name (including terminating 0)
Remarks:
* If the buffer is too small to hold all data, only first (edx-1)
bytes are copied and than terminating 0 is inserted.
 
======================================================================
=============== Function 32 - delete file from ramdisk. ==============
======================================================================
Parameters:
* eax = 32 - function number
* ebx = pointer to the filename
Returned value:
* eax = 0 - success; otherwise file system error code
Remarks:
* This function is obsolete; function 58 allows to fulfill
the same operations with the extended possibilities.
* The current implementation returns only values 0(success) and
5(file not found).
* The filename must be either in the format 8+3 characters
(first 8 characters - name itself, last 3 - extension,
the short names and extensions are supplemented with spaces),
or in the format 8.3 characters "FILE.EXT"/"FILE.EX "
(name no more than 8 characters, dot, extension 3 characters
supplemented if necessary by spaces).
The filename must be written with capital letters. The terminating
character with code 0 is not necessary (not ASCIIZ-string).
* This function does not support folders on the ramdisk.
 
======================================================================
================ Function 33 - write file to ramdisk. ================
======================================================================
Parameters:
* eax = 33 - function number
* ebx = pointer to the filename
* ecx = pointer to data for writing
* edx = number of bytes for writing
* should be set esi=0
Returned value:
* eax = 0 - success, otherwise file system error code
Remarks:
* This function is obsolete; function 70 allows to fulfil
the same operations with extended possibilities.
* If esi contains non-zero value and selected file already exists,
one more file with the same name will be created.
* Otherwise file will be overwritten.
* The filename must be either in the format 8+3 characters
(first 8 characters - name itself, last 3 - extension,
the short names and extensions are supplemented with spaces),
or in the format 8.3 characters "FILE.EXT"/"FILE.EX "
(name no more than 8 characters, dot, extension 3 characters
supplemented if necessary by spaces).
The filename must be written with capital letters. The terminating
character with code 0 is not necessary (not ASCIIZ-string).
* This function does not support folders on the ramdisk.
 
======================================================================
======= Function 35 - read the color of a pixel on the screen. =======
======================================================================
Parameters:
* eax = 35
* ebx = y*xsize+x, where
* (x,y) = coordinates of a pixel (beginning from 0)
* xsize = horizontal screen size
Returned value:
* eax = color 0x00RRGGBB
Remarks:
* To get screen sizes use function 14. Pay attention,
that it subtracts 1 from both sizes.
* There is also direct access (without any system calls)
to videomemory through the selector gs. To get parameters of
the current videomode, use function 61.
 
======================================================================
=================== Function 36 - read screen area. ==================
======================================================================
Paramters:
* eax = 36 - function number
* ebx = pointer to the previously allocated memory area,
where will be placed the image in the format BBGGRRBBGGRR...
* ecx = [size on axis x]*65536 + [size on axis y]
* edx = [coordinate on axis x]*65536 + [coordinate on axis y]
Returned value:
* function does not return value
Remarks:
* Coordinates of the image are coordinates of the upper left corner
of the image relative to the screen.
* Size of the image in bytes is 3*xsize*ysize.
 
======================================================================
=================== Function 37 - work with mouse. ===================
======================================================================
 
---------- Subfunction 0 - screen coordinates of the mouse -----------
Parameters:
* eax = 37 - function number
* ebx = 0 - subfunction number
Returned value:
* eax = x*65536 + y, (x,y)=coordinates of the mouse pointer
(beginning from 0)
 
-- Subfunction 1 - coordinates of the mouse relative to the window ---
Parameters:
* eax = 37 - function number
* ebx = 1 - subfunction number
Returned value:
* eax = x*65536 + y, (x,y)=coordinates of the mouse pointer
relative to the application window (beginning from 0)
Remarks:
* The value is calculated by formula (x-xwnd)*65536 + (y-ywnd).
If y>=ywnd, the low word is non-negative and contains
relative y-coordinate, and the high word - relative x-coordinate
(with correct sign). Otherwise the low word is negative and still
contains relative y-coordinate, and to the high word
1 should be added.
 
------------ Subfunction 2 - pressed buttons of the mouse ------------
Parameters:
* eax = 37 - function number
* ebx = 2 - subfunction number
Returned value:
* eax contains information on the pressed mouse buttons:
* bit 0 is set = left button is pressed
* bit 1 is set = right button is pressed
* bit 2 is set = middle button is pressed
* bit 3 is set = 4th button is pressed
* bit 4 is set = 5th button is pressed
* other bits are cleared
 
-------------------- Subfunction 4 - load cursor ---------------------
Parameters:
* eax = 37 - function number
* ebx = 4 - subfunction number
* dx = data source:
* dx = LOAD_FROM_FILE = 0 - data in a file
* ecx = pointer to full path to the cursor file
* the file must be in the format .cur, which is standard for
MS Windows, at that of the size 32*32 pixels
* dx = LOAD_FROM_MEM = 1 - data of file are already loaded in memory
* ecx = pointer to data of the cursor file
* the data format is the same as in the previous case
* dx = LOAD_INDIRECT = 2 - data in memory
* ecx = pointer to cursor image in the format ARGB 32*32 pixels
* edx = 0xXXYY0002, where
* XX = x-coordinate of cursor hotspot
* YY = y-coordinate
* 0 <= XX, YY <= 31
Returned value:
* eax = 0 - failed
* otherwise eax = cursor handle
 
--------------------- Subfunction 5 - set cursor ---------------------
Sets new cursor for the window of the current thread.
Parameters:
* eax = 37 - function number
* ebx = 5 - subfunction number
* ecx = cursor handle
Returned value:
* eax = handle of previous cursor
Remarks:
* If the handle is incorrect, the function restores the default
cursor (standard arrow). In particular, ecx=0 restores it.
 
------------------- Subfunction 6 - delete cursor --------------------
Parameters:
* eax = 37 - function number
* ebx = 6 - subfunction number
* ecx = cursor handle
Returned value:
* eax destroyed
Remarks:
* The cursor must be loaded previously by the current thread
(with the call to subfunction 4). The function does not delete
system cursors and cursors, loaded by another applications.
* If the active cursor (set by subfunction 5) is deleted,
the system restores the default cursor (standard arrow).
 
------------------ Subfunction 7 - get scroll data -------------------
Parameters:
* eax = 37 - function number
* ebx = 7 - subfunction number
Returned value:
* eax = [horizontal offset]*65536 + [vertical offset]
Remarks:
* Scroll data is available for active window only.
* Values are zeroed after reading.
* Values are signed.
 
======================================================================
====================== Function 38 - draw line. ======================
======================================================================
Parameters:
* eax = 38 - function number
* ebx = [start coordinate on axis x]*65536 +
[end coordinate on axis x]
* ecx = [start coordinate on axis y]*65536 +
[end coordinate on axis y]
* edx = 0x00RRGGBB - color
edx = 0x01xxxxxx - draw inversed line
(low 24 bits are ignored)
Returned value:
* function does not return value
Remarks:
* Coordinates are relative to the window.
* End point is also drawn.
 
======================================================================
== Function 39, subfunction 1 - get a size of the background image. ==
======================================================================
Parameters:
* eax = 39 - function number
* ebx = 1 - subfunction number
Returned value:
* eax = [width]*65536 + [height]
Remarks:
* There is a pair function to set sizes of background image -
subfunction 1 of function 15. After which it is necessary,
of course, anew to define image.
 
======================================================================
== Function 39, subfunction 2 - get pixel from the background image. =
======================================================================
Parameters:
* eax = 39 - function number
* ebx = 2 - subfunction number
* ecx = offset
Returned value:
* eax = 0x00RRGGBB - pixel color, if offset is valid
(less than 0x160000-16)
* eax = 2 otherwise
Remarks:
* Do not rely on returned value for invalid offsets, it may be
changed in future kernel versions.
* Offset for pixel with coordinates (x,y)
is calculated as (x+y*xsize)*3.
* There is a pair function to set pixel on the background image -
subfunction 2 of function 15.
 
======================================================================
== Function 39, subfunction 4 - get drawing mode for the background. =
======================================================================
Parameters:
* eax = 39 - function number
* ebx = 4 - subfunction number
Returned value:
* eax = 1 - tile
* eax = 2 - stretch
Remarks:
* There is a pair function to set drawing mode -
subfunction 4 of function 15.
 
======================================================================
=========== Function 40 - set the mask for expected events. ==========
======================================================================
The mask for expected events affects function working with events
10, 11, 23 - they notify only about events allowed by this mask.
Parameters:
* eax = 40 - function number
* ebx = mask: bit i corresponds to event i+1 (see list of events)
(set bit permits notice on event)
Returned value:
* eax = previous value of mask
Remarks:
* Default mask (7=111b) enables nofices about redraw,
keys and buttons. This is enough for many applications.
* Events prohibited in the mask are saved anyway, when come;
they are simply not informed with event functions.
* Event functions take into account the mask on moment of
function call, not on moment of event arrival.
 
======================================================================
==================== Function 41 - get IRQ owner. ====================
======================================================================
Parameters:
* eax = 41 - function number
* ebx = IRQ number, 0..15
Returned value:
* eax = owner PID
* eax = 0, if there is no owner
* eax = -1 for incorrect ebx
 
======================================================================
================== Function 42 - work with IRQ data. =================
======================================================================
When an IRQ occurs, the system reads data from ports indicated
earlier by function 44 and writes this data to
internal buffer. This function reads out data from that buffer.
 
--------------------- Subfunction 0 - read data ----------------------
Parameters:
* eax = 42 - function number
* bl = IRQ number, 0..15
* bh = 0 - subfunction number
* rest of ebx must be zeroed
* ecx = pointer to a buffer with size not less than 4000 bytes
Returned value: (use value of eax to distinguish)
* if the thread is not IRQ owner
(or IRQ number is incorrect): eax = -1
* if there is no data: eax = 0
* if all is ok:
eax = size of data read (in bytes)
 
------------- Subfunction 1 - get size of data in buffer -------------
Parameters:
* eax = 42 - function number
* bl = IRQ number, 0..15
* bh = 0 - subfunction number
* rest of ebx must be zeroed
Returned value:
* if the thread is not IRQ owner
(or IRQ number is incorrect): eax = -1
* otherwise eax = size of data in buffer
Remarks:
* Previously the thread must reserve indicated IRQ for itself
by function 45.
* The size of data buffer is 4000 bytes, on overflow
"fresh" data cease to be written in the buffer.
 
======================================================================
================ Function 43 - input/output to a port. ===============
======================================================================
 
------------------------ Output data to port -------------------------
Parameters:
* eax = 43 - function number
* bl = byte for output
* ecx = port number 0xnnnn (from 0 to 0xFFFF)
Returned value:
* eax = 0 - success
* eax = 1 - the thread has not reserved the selected port
 
------------------------ Input data from port ------------------------
Parameters:
* eax = 43 - function number
* ebx is ignored
* ecx = 0x8000nnnn, where nnnn = port number (from 0 to 0xFFFF)
Returned value:
* eax = 0 - success, thus ebx = entered byte
* eax = 1 - the thread has not reserved the selected port
Remarks:
* Previously the thread must reserve the selected port
for itself by function 46.
* Instead of call to this function it is better to use
processor instructions in/out - this is much
faster and a bit shorter and easier.
 
======================================================================
=========== Function 44 - define operations at IRQ arrival. ==========
======================================================================
At IRQ arrival the system can read the data from ports defined
by this function and write these data to internal buffer, whence
they can be read by ôóíêöèåé 42.
Parameters:
* eax = 44 - function number
* ebx = pointer to the array of structures each describing one port:
* +0: word: 0 means end of array, otherwise port number
* +2: byte: reserved (ignored)
* +3: byte: 1=read byte from this port, 2=read word
* ecx = IRQ number, 0..15
Returned value:
* eax = 0 - success
* eax = 1 - the thread is not owner of selected IRQ
Remarks:
* Previously the thread must reserve for itself selected IRQ
by function 45.
* First 16 ports are considered only.
* The current implementation considers incorrect value of field +3
as a signal to terminate IRQ processing.
 
======================================================================
=================== Function 45 - reserve/free IRQ. ==================
======================================================================
Parameters:
* eax = 45 - function number
* ebx = 0 - reserve, 1 = free
* ecx = IRQ number, 0..15
Returned value:
* eax = 0 - success
* eax = 1 - error (invalid IRQ number
or attempt to reserve not free IRQ
or to free IRQ, not reserved by this thread)
Remarks:
* IRQ reservation is required for functions 42 and 44.
* Only one thread can reserve the specific IRQ.
* IRQs, handled by the system itself, are reserved by the system
(thread 1) at booting.
* When a thread terminates, all reserved by it IRQs
are freed automatically.
 
======================================================================
====== Function 46 - reserve/free a group of input/output ports. =====
======================================================================
To work with reserved ports an application can access directly by
commands in/out (recommended way) and can use function 43
(not recommended way).
Parameters:
* eax = 46 - function number
* ebx = 0 - reserve, 1 - free
* ecx = start port number
* edx = end port number (inclusive)
Returned value:
* eax = 0 - success
* eax = 1 - error
Remarks:
* For ports reservation: an error occurs if and only if
one from the following condition satisfies:
* start port is more than end port;
* the selected range contains incorrect port number
(correct are from 0 to 0xFFFF);
* limit for the total number of reserved areas is exceeded
(maximum 255 are allowed);
* the selected range intersects with any of earlier reserved
* For ports free: an error is an attempt to free range,
that was not earlier reserved by this function
(with same ecx,edx).
* If an error occurs (for both cases) function performs no action.
* At booting the system reserves for itself ports
0..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (inclusively).
* When a thread terminates, all reserved by it ports
are freed automatically.
 
======================================================================
============= Function 47 - draw a number in the window. =============
======================================================================
Parameters:
* eax = 47 - function number
* ebx = parameters of conversion number to text:
* bl = 0 - ecx contains number
* bl = 1 - ecx contains pointer to dword/qword-number
* bh = 0 - display in decimal number system
* bh = 1 - display in hexadecimal system
* bh = 2 - display in binary system
* bits 16-21 = how many digits to display
* bits 22-29 reserved and must be set to 0
* bit 30 set = display qword (64-bit) number (must be bl=1)
* bit 31 set = do not display leading zeroes of the number
* ecx = number (if bl=0) or pointer (if bl=1)
* edx = [coordinate on axis x]*65536 + [coordinate on axis y]
* esi = 0xX0RRGGBB:
* RR, GG, BB specify the color
* X = ABnn (bits)
* nn = font (0/1)
* A is ignored
* B=1 - fill background with the color edi
Returned value:
* function does not return value
Remarks:
* The given length must not exceed 60.
* The exactly given amount of digits is output. If number is small
and can be written by smaller amount of digits, it is supplemented
by leading zeroes; if the number is big and can not be written by
given amount of digits, extra digits are not drawn.
* Parameters of fonts are shown in the description of function 4
(text output).
 
======================================================================
========= Function 48, subfunction 0 - apply screen settings. ========
======================================================================
Parameters:
* eax = 48 - function number
* ebx = 0 - subfunction number
* ecx = 0 - reserved
Returned value:
* function does not return value
Remarks:
* Function redraws the screen after parameters change by
subfunctions 1 and 2.
* Function call without prior call to one of indicated subfunctions
is ignored.
* Function call with nonzero ecx is ignored.
 
======================================================================
=========== Function 48, subfunction 1 - set button style. ===========
======================================================================
Parameters:
* eax = 48 - function number
* ebx = 1 - subfunction number
* ecx = button style:
* 0 = flat
* 1 = 3d
Returned value:
* function does not return value
Remarks:
* After call to this function one should redraw the screen by
subfunction 0.
* Button style influences only to their draw of function 8.
 
======================================================================
====== Function 48, subfunction 2 - set standard window colors. ======
======================================================================
Parameters:
* eax = 48 - function number
* ebx = 2 - subfunction number
* ecx = pointer to the color table
* edx = size of the color table
(must be 40 bytes for future compatibility)
Format of the color table is shown in description of subfunction 3.
Returned value:
* function does not return value
Remarks:
* After call to this function one should redraw the screen by
subfunction 0.
* Table of standard colors influences only to applications,
which receive this table obviously (by subfunction 3)
and use it (specifying colors from it to drawing functions).
* Table of standard colors is included in skin and is installed
anew with skin installation (by subfunction 8).
* Color table can be viewed/changed interactively with
the application 'desktop'.
 
======================================================================
====== Function 48, subfunction 3 - get standard window colors. ======
======================================================================
Parameters:
* eax = 48 - function number
* ebx = 3 - subfunction number
* ecx = pointer to the buffer with size edx bytes,
where table will be written
* edx = size of color table
(must be 40 bytes for future compatibility)
Returned value:
* function does not return value
Format of the color table:
each item is dword-value for color 0x00RRGGBB
* +0: dword: frames - color of frame
* +4: dword: grab - color of header
* +8: dword: grab_button - color of button on header bar
* +12 = +0xC: dword: grab_button_text - color of text on button
on header bar
* +16 = +0x10: dword: grab_text - color of text on header
* +20 = +0x14: dword: work - color of working area
* +24 = +0x18: dword: work_button - color of button in working area
* +28 = +0x1C: dword: work_button_text - color of text on button
in working area
* +32 = +0x20: dword: work_text - color of text in working area
* +36 = +0x24: dword: work_graph - color of graphics in working area
Remarks:
* Structure of the color table is described in the standard
include file 'macros.inc' as 'system_colors'; for example,
it is possible to write:
sc system_colors ; variable declaration
... ; somewhere one must call
; this function with ecx=sc
mov ecx, [sc.work_button_text] ; read text color on
; buttin in working area
* A program itself desides to use or not to use color table.
For usage program must simply at calls to drawing functions select
color taken from the table.
* At change of the table of standard colors (by subfunction 2 with
the subsequent application of changes by subfunction 0 or
at skin set by subfunction 8) the system sends to all windows
redraw message (the event with code 1).
* Color table can be viewed/changed interactively with
the application 'desktop'.
 
======================================================================
============ Function 48, subfunction 4 - get skin height. ===========
======================================================================
Parameters:
* eax = 48 - function number
* ebx = 4 - subfunction number
Returned value:
* eax = skin height
Remarks:
* Skin height is defined as the height of a header
of skinned windows.
* See also general structure of window in the description
of function 0.
 
======================================================================
======== Function 48, subfunction 5 - get screen working area. =======
======================================================================
Parameters:
* eax = 48 - function number
* ebx = 5 - subfunction number
Returned value:
* eax = [left]*65536 + [right]
* ebx = [top]*65536 + [bottom]
Remarks:
* The screen working area defines position and coordinates of
a maximized window.
* The screen working area in view of normal work is all screen
without system panel (the application '@panel').
* (left,top) are coordinates of the left upper corner,
(right,bottom) are coordinates of the right lower one.
Thus the size of working area on x axis can be calculated by
formula right-left+1, on y axis - by formula bottom-right+1.
* See also function 14,
to get sizes of all screen.
* There is a pair function to set working area - subfunction 6.
 
======================================================================
======== Function 48, subfunction 6 - set screen working area. =======
======================================================================
Parameters:
* eax = 48 - function number
* ebx = 6 - subfunction number
* ecx = [left]*65536 + [right]
* edx = [top]*65536 + [bottom]
Returned value:
* function does not return value
Remarks:
* The screen working area defines position and coordinates of
a maximized window.
* This function is used only by the application '@panel',
which set working area to all screen without system panel.
* (left,top) are coordinates of the left upper corner,
(right,bottom) are coordinates of the right lower one.
Thus the size of working area on x axis can be calculated by
formula right-left+1, on y axis - by formula bottom-right+1.
* If 'left'>='right', x-coordinate of working area is not changed.
If 'left'<0, 'left' will not be set. If 'right' is greater than or
equal to screen width, 'right' will not be set.
Similarly on y axis.
* See also function 14,
to get sizes of all screen.
* There is a pair function to get working area - subfunction 5.
* This function redraws the screen automatically,
updating coordinates and sizes of maximized windows.
The system sends to all windows redraw message (the event 1).
 
======================================================================
=========== Function 48, subfunction 7 - get skin margins. ===========
======================================================================
Returns the area of a header of a skinned window, intended for
a text of a header.
Parameters:
* eax = 48 - function number
* ebx = 7 - subfunction number
Returned value:
* eax = [left]*65536 + [right]
* ebx = [top]*65536 + [bottom]
Remarks:
* An application decides itself to use or not to use this function.
* It is recommended to take into account returned value
of this function for choice of a place for drawing header text
(by function 4) or a substitute of header text
(at the discretion of an application).
 
======================================================================
============= Function 48, subfunction 8 - set used skin. ============
======================================================================
Parameters:
* eax = 48 - function number
* ebx = 8 - subfunction number
* ecx = pointer to a block for function 58, in
which the fields of intermediate buffer and file name are filled
Returned value:
* eax = 0 - success
* otherwise eax = file system error code; if file does not
contain valid skin, function returns error 3
(unknown file system).
Remarks:
* After successful skin loading the system sends to all windows
redraw message (the event 1).
* At booting the system reads skin from file 'default.skn'
on ramdisk.
* User can change the skin statically by creating hisself
'default.skn' or dynamically with the application 'desktop'.
 
======================================================================
=========== Function 49 - Advanced Power Management (APM). ===========
======================================================================
Parameters:
* eax = 49 - function number
* dx = number of the APM function
(analogue of ax in APM specification)
* bx, cx = parameters of the APM function
Returned value:
* 16-bit registers ax, bx, cx, dx, si, di and carry flag CF
are set according to the APM specification
* high halves of 32-bit registers eax, ebx, ecx,
edx, esi, edi are destroyed
Remarks:
* APM 1.2 specification is described in the document
"Advanced Power Management (APM) BIOS Specification"
(Revision 1.2), available at
http://www.microsoft.com/whdc/archive/amp_12.mspx;
besides it is included in famous Interrupt List by Ralf Brown
(http://www.pobox.com/~ralf/files.html,
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/).
 
======================================================================
=================== Function 50 - set window shape. ==================
======================================================================
Normal windows have rectangular shape. This function can give to
a window any shape. The shape is given by a set of points inside
the base rectangle belonging to a window. Position and coordinates
of the base rectangle are set by function 0
and changed by function 67.
 
--------------------------- Set shape data ---------------------------
Parameters:
* eax = 50 - function number
* ebx = 0 - subfunction number
* ecx = pointer to shape data (array of bytes 0/1)
Returned value:
* function does not return value
 
-------------------------- Set shape scale ---------------------------
Parameters:
* eax = 50 - function number
* ebx = 1 - subfunction number
* ecx sets a scale: each byte of data defines
(2^scale)*(2^scale) pixels
Returned value:
* function does not return value
Remarks:
* Default scale is 0 (scale factor is 1). If in the shape data
one byte corresponds to one pixel, there is no necessity
to set scale.
* Let's designate xsize = window width (in pixels), ysize = height;
pay attention, that they are one pixel more than defined by
functions 0, 67.
* On definition of scale xsize and ysize must be divisible
on 2^scale.
* Byte of data on offset 'a' must be 0/1 and defines belonging
to a window of square with the side 2^scale (if scale=0,
this is one pixel) and coordinates of the left upper corner
(a mod (xsize shr scale), a div (xsize shr scale))
* Data size: (xsize shr scale)*(ysize shr scale).
* Data must be presented in the memory and not change
after set of shape.
* The system views the shape data at every window redraw by
function 0.
* The call of subfunction 0 with NULL pointer results in return
to the rectangular shape.
 
======================================================================
==================== Function 51 - create thread. ====================
======================================================================
Parameters:
* eax = 51 - function number
* ebx = 1 - unique subfunction
* ecx = address of thread entry point (starting eip)
* edx = pointer to thread stack (starting esp)
Returned value:
* eax = -1 - error (there is too many threads)
* otherwise eax = TID - thread identifier
</UL>
 
======================================================================
=== Function 52, subfunction 0 - get network driver configuration. ===
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 0 - subfunction number
Returned value:
* eax = configuration dword
Remarks:
* Configuration dword can be set by subfunction 2.
* The kernel does not use this variable. The value of this
variable and working with it subfunctions 0 and 2 is represented
doubtful.
 
======================================================================
========= Function 52, subfunction 1 - get local IP-address. =========
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 1 - subfunction number
Returned value:
* eax = IP-address (4 bytes)
Remarks:
* Local IP-address is set by subfunction 3.
 
======================================================================
=== Function 52, subfunction 2 - set network driver configuration. ===
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 2 - subfunction number
* ecx = configuration dword; if low 7 bits derivate the number 3,
function [re-]initializes Ethernet-card, otherwise
Ethernet turns off
Returned value:
* if Ethernet-interface is not requested, function returns eax=2,
but this can be changed in future kernel versions
* if Ethernet-interface is requested, eax=0 means error
(absence of Ethernet-card), and nonzero value - success
Remarks:
* Configuration dword can be read by subfunction 0.
* The kernel does not use this variable. The value of this
variable, subfunction 0 and part of subfunction 2, which set it,
is represented doubtful.
 
======================================================================
========= Function 52, subfunction 3 - set local IP-address. =========
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 3 - subfunction number
* ecx = IP-address (4 bytes)
Returned value:
* the current implementation returns eax=3, but this can be changed
in future versions
Remarks:
* Local IP-address can be get by subfunction 1.
 
======================================================================
= Function 52, subfunction 6 - add data to the stack of input queue. =
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 6 - subfunction number
* edx = data size
* esi = data pointer
Returned value:
* eax = -1 - error
* eax = 0 - success
Remarks:
* This function is intended only for slow network drivers
(PPP, SLIP).
* Data size must not exceed 1500 bytes, though function
performs no checks on correctness.
 
======================================================================
Function 52, subfunction 8 - read data from the network output queue.
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 8 - subfunction number
* esi = pointer to 1500-byte buffer
Returned value:
* eax = number of read bytes (in the current implementation
either 0 = no data or 1500)
* data was copied in buffer
Remarks:
* This function is intended only for slow network drivers
(PPP, SLIP).
 
======================================================================
============ Function 52, subfunction 9 - get gateway IP. ============
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 9 - subfunction number
Returned value:
* eax = gateway IP (4 bytes)
 
======================================================================
=========== Function 52, subfunction 10 - get subnet mask. ===========
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 10 - subfunction number
Returned value:
* eax = subnet mask
 
======================================================================
============ Function 52, subfunction 11 - set gateway IP. ===========
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 11 - subfunction number
* ecx = gateway IP (4 bytes)
Returned value:
* the current implementation returns eax=11, but this can be changed
in future versions
 
======================================================================
=========== Function 52, subfunction 12 - set subnet mask. ===========
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 12 - subfunction number
* ecx = subnet mask
Returned value:
* the current implementation returns eax=12, but this can be changed
in future versions
 
======================================================================
============== Function 52, subfunction 13 - get DNS IP. =============
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 13 - subfunction number
Returned value:
* eax = DNS IP (4 bytes)
 
======================================================================
============== Function 52, subfunction 14 - set DNS IP. =============
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 14 - subfunction number
* ecx = DNS IP (4 bytes)
Returned value:
* the current implementation returns eax=14, but this can be changed
in future versions
 
======================================================================
======== Function 52, subfunction 15 - get local MAC address. ========
======================================================================
Parameters:
* eax = 52 - function number
* ebx = 15 - subfunction number
* ecx = 0 - read first 4 bytes,
ecx = 4 - read last 2 bytes
Returned value:
* for ecx=0: eax = first 4 bytes of MAC address
* for ecx=4: ax = last 2 bytes of MAC address,
high half of eax is destroyed
* for other ecx: eax = -1 indicates an error
 
======================================================================
============ Function 53, subfunction 0 - open UDP-socket. ===========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 0 - subfunction number
* ecx = local port (only low word is taken into account),
ecx = 0 - let the system choose a port
* edx = remote port (only low word is taken into account)
* esi = remote IP
Returned value:
* eax = -1 = 0xFFFFFFFF - error; ebx destroyed
* eax = socket handle (some number which unambiguously identifies
socket and have sense only for the system) - success;
ebx destroyed
 
======================================================================
=========== Function 53, subfunction 1 - close UDP-socket. ===========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 1 - subfunction number
* ecx = socket handle
Returned value:
* eax = -1 - incorrect handle
* eax = 0 - success
* ebx destroyed
Remarks:
* The current implementation does not close automatically all
sockets of a thread at termination. In particular, one should not
kill a thread with many opened sockets - there will be an outflow
of resources.
 
======================================================================
============== Function 53, subfunction 2 - poll socket. =============
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 2 - subfunction number
* ecx = socket handle
Returned value:
* eax = number of read bytes, 0 for incorrect handle
* ebx destroyed
 
======================================================================
========= Function 53, subfunction 3 - read byte from socket. ========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 3 - subfunction number
* ecx = socket handle
Returned value:
* if there is no read data or handle is incorrect: eax=0, bl=0,
other bytes of ebx are destroyed
* if there are read data: eax=number of rest bytes
(possibly 0), bl=read byte, other bytes of ebx are destroyed
 
======================================================================
========== Function 53, subfunction 4 - write to UDP-socket. =========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 4 - subfunction number
* ecx = socket handle
* edx = number of bytes to write
* esi = pointer to data to write
Returned value:
* eax = 0xffffffff - error (invalid handle or not enough memory)
* eax = 0 - success
* ebx destroyed
Remarks:
* Number of bytes to write must not exceed 1500-28, though
the appropriate check is not made.
 
======================================================================
============ Function 53, subfunction 5 - open TCP-socket. ===========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 5 - subfunction number
* ecx = local port (only low word is taken into account),
ecx = 0 - let the system choose a port
* edx = remote port (only low word is taken into account)
* esi = remote IP
* edi = open mode: SOCKET_PASSIVE=0 or SOCKET_ACTIVE=1
Returned value:
* eax = -1 = 0xFFFFFFFF - error; ebx destroys
* eax = socket handle (some number which unambiguously identifies
socket and have sense only for the system) - success;
ebx destroyed
 
======================================================================
========= Function 53, subfunction 6 - get TCP-socket status. ========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 6 - subfunction number
* ecx = socket handle
Returned value:
* eax = 0 for incorrect handle or socket status: one of
* TCB_LISTEN = 1
* TCB_SYN_SENT = 2
* TCB_SYN_RECEIVED = 3
* TCB_ESTABLISHED = 4
* TCB_FIN_WAIT_1 = 5
* TCB_FIN_WAIT_2 = 6
* TCB_CLOSE_WAIT = 7
* TCB_CLOSING = 8
* TCB_LAST_ASK = 9
* TCB_TIME_WAIT = 10
* TCB_CLOSED = 11
* ebx destroyed
 
======================================================================
========== Function 53, subfunction 7 - write to TCP-socket. =========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 7 - subfunction number
* ecx = socket handle
* edx = number of bytes to write
* esi = pointer to data to write
Returned value:
* eax = 0xffffffff - error (invalid handle or not enough memory)
* eax = 0 - success
* ebx destroyed
Remarks:
* Number of bytes to write must not exceed 1500-40, though
the appropriate check is not made.
 
======================================================================
=========== Function 53, subfunction 8 - close TCP-socket. ===========
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 8 - subfunction number
* ecx = socket handle
Returned value:
* eax = -1 - error (invalid handle or
not enough memory for socket close packet)
* eax = 0 - success
* ebx destroyed
Remarks:
* The current implementation does not close automatically all
sockets of a thread at termination. In particular, one should not
kill a thread with many opened sockets - there will be an outflow
of resources.
 
======================================================================
=== Function 53, subfunction 9 - check whether local port is free. ===
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 9 - subfunction number
* ecx = local port number (low 16 bits are used only)
Returned value:
* eax = 0 - port is used
* eax = 1 - port is free
* ebx destroyed
 
======================================================================
===== Function 53, subfunction 10 - query Ethernet cable status. =====
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 10 - subfunction number
Returned value:
* al = -1 - a network driver is not loaded or
does not support this function
* al = 0 - Ethernet cable is unplugged
* al = 1 - Ethernet cable is plugged
* ebx destroyed
Remarks:
* The current kernel implementation supports this function
only for RTL8139 network cards.
 
======================================================================
======= Function 53, subfunction 11 - read network stack data. =======
======================================================================
Paramters:
* eax = 53 - function number
* ebx = 11 - subfunction number
* ecx = socket handle
* edx = pointer to buffer
* esi = number of bytes to read;
* esi = 0 - read all data (maximum 4096 bytes)
Returned value:
* eax = number of bytes read (0 for incorrect handle)
* ebx destroyed
 
======================================================================
= Function 53, subfunction 255 - debug information of network driver.
======================================================================
Parameters:
* eax = 53 - function number
* ebx = 255 - subfunction number
* ecx = type of requested information (see below)
Returned value:
* eax = requested information
* ebx destroyed
Possible values for ecx:
* 100: length of queue 0 (empty queue)
* 101: length of queue 1 (ip-out queue)
* 102: length of queue 2 (ip-in queue)
* 103: length of queue 3 (net1out queue)
* 200: number of items in the ARP table
* 201: size of the ARP table (in items) (20 for current version)
* 202: read item at edx of the ARP table to the temporary buffer,
whence 5 following types take information;
in this case eax is not defined
* 203: IP-address saved by type 202
* 204: high dword of MAC-address saved by type 202
* 205: low word of MAC-address saved by type 202
* 206: status word saved by type 202
* 207: ttl word saved by type 202
* 2: total number of received IP-packets
* 3: total number of transferred IP-packets
* 4: total number of dumped received packets
* 5: total number of received ARP-packets
* 6: status of packet driver, 0=inactive, nonzero=active
 
======================================================================
Function 55, subfunction 55 - begin to play data on built-in speaker.
======================================================================
Parameters:
* eax = 55 - function number
* ebx = 55 - subfunction number
* esi = pointer to data
Returned value:
* eax = 0 - success
* eax = 55 - error (speaker is off or busy)
Data is an array of items with variable length.
Format of each item is defined by first byte:
* 0 = end of data
* 1..0x80 = sets sound duration on 1/100 of second; sound note
is defined by immediate value of frequency
* following word (2 bytes) contains frequency divider;
frequency is defined as 1193180/divider
* 0x81 = invalid
* 0x82..0xFF = note is defined by octave and number:
* duration in 1/100 of second = (first byte)-0x81
* there is one more byte;
* (second byte)=0xFF - delay
* otherwise it looks like a*0x10+b, where b=number of the note in
an octave from 1 to 12, a=number of octave (beginning from 0)
Remarks:
* Speaker play can be disabled/enabled by
subfunction 8 of function 18.
* Function returns control, having informed the system
an information on request. Play itself goes independently from
the program.
* The data must be kept in the memory at least up to the end
of play.
 
======================================================================
======================= Function 57 - PCI BIOS. ======================
======================================================================
Parameters:
* eax = 57 - function number
* ebp corresponds to al in PCI BIOS specification
* other registers are set according to PCI BIOS specification
Returned value:
* CF is undefined
* other registers are set according to PCI BIOS specification
Remarks:
* Many effects of this function can be also achieved with
corresponding subfunctions of function 62.
* The function calls PCI32 BIOS extension, documented e.g. in
http://alpha1.dyns.net/files/PCI/bios21.pdf.
* If BIOS does not support this extension, its behavior is emulated
(through kernel-mode analogues of subfunctions of function 62).
 
======================================================================
================ Function 58 - work with file system. ================
======================================================================
Parameters:
* eax = 58
* ebx = pointer to the information structure
Returned value:
* eax = 0 - success; otherwise file system error code
* some subfunctions return value in other registers too
General format of the information structure:
* +0: dword: subfunction number
* +4: dword: number of block
* +8: dword: size
* +12 = +0xC: dword: pointer to data
* +16 = +0x10: dword: pointer to a memory for system operations
(4096 bytes)
* +20 = +0x14: n db: ASCIIZ-string with the file name
Specifications - in documentation on the appropriate subfunction.
Filename is case-insensitive for latin letters, russian letters
must be capital.
Format of filename:
/base/number/dir1/dir2/.../dirn/file,
where /base/number identifies device, on which file is located:
one of
* /RD/1 = /RAMDISK/1 to access ramdisk
* /FD/1 = /FLOPPYDISK/1 to access first floppy drive,
/FD/2 = /FLOPPYDISK/2 to access second one
* /HD/x = /HARDDISK/x - obsolete variant of access to hard disk
(in this case base is defined by subfunction 7 of function 21),
x - partition number (beginning from 1)
* /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices
IDE0 (Primary Master), IDE1 (Primary Slave),
IDE2 (Secondary Master), IDE3 (Secondary Slave);
x - partition number on the selected hard drive, varies from 1
to 255 (on each hard drive the indexing starts from 1)
Remarks:
* In the first two cases it is also possible to use FIRST
instead of 1, SECOND instead of 2, but it is not recommended
for convenience of transition to the future extensions.
* Limitation n<=39 is imposed.
* Names of folders and file dir1,...,dirn,file must have the
format 8.3: name no more than 8 characters, dot, extension no
more than 3 characters. Trailing spaces are ignored, no other
spaces is allowed. If name occupies equally 8 characters,
dot may be omitted (though it is not recommended to use this
feature for convenience of transition to the future extensions).
* This function does not support folders on ramdisk.
Examples:
* '/RAMDISK/FIRST/KERNEL.ASM',0
'/rd/1/kernel.asm',0
* '/HD0/1/kernel.asm',0
* '/hd0/1/menuet/pics/tanzania.bmp',0
Existing subfunctions:
* subfunction 0 - read file/folder
* subfunction 8 - LBA-read from device
* subfunction 15 - get file system information
 
======================================================================
=========== Function 58, subfunction 0 - read file/folder. ===========
======================================================================
Parameters:
* eax = 58
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 0 = subfunction number
* +4: dword: first block to read (beginning from 0)
* +8: dword: amount of blocks to read
* +12 = +0xC: dword: pointer to buffer for data
* +16 = +0x10: dword: pointer to buffer for system operations
(4096 bytes)
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
given in the general description
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx = file size (in bytes) or -1=0xffffffff, if file was not found
Remarks:
* Block size is 512 bytes.
* This function is obsolete, for reading files use subfunction 0
of function 70, for reading folders - subfunction 1 of
function 70.
* Function can read contents of a folder. Only FAT file system is
supported. The format of FAT-folder is described
in any FAT documentation.
* Size of a folder is determined by size of FAT clusters chain.
* If file was ended before last requested block was read,
the function will read as many as it can, and after that return
eax=6 (EOF).
* Function can read root folders /rd/1,/fd/x,/hd[n]/x, but
in the first two cases the current implementation does not follow
to the declared rules:
for /rd/1:
* if one want to read 0 blocks, function considers,
that he requested 1;
* if one requests more than 14 blocks or starting block is
not less than 14, function returns eax=5 (not found) è ebx=-1;
* size of ramdisk root folder is 14 blocks,
0x1C00=7168 áàéò; but function returns ebx=0
(except of the case of previous item);
* strangely enough, it is possible to read 14th block (which
generally contains a garbage - I remind, the indexing begins
from 0);
* if some block with the number not less than 14 was requested,
function returns eax=6(EOF); otherwise eax=0.
For /fd/x:
* if the start block is not less than 14, function returns
eax=5 (not found) and ebx=0;
* note that format of FAT12 allows floppies with the root size
more or less than 14 blocks;
* check for length is not performed;
* if data was successful read, function returns
eax=0,ebx=0; otherwise eax=10 (access denied), ebx=-1.
* The function handles reading of special folders /,/rd,/fd,/hd[n];
but the result does not correspond to expected (on operations with
normal files/folders), does not follow the declared rules,
may be changed in future versions of the kernel and consequently
is not described. To obtain the information about the equipment
use subfunction 11 of function 18 or
read corresponding folder with subfunction 1 of function 70.
 
======================================================================
========= Function 58, subfunction 8 - LBA-read from device. =========
======================================================================
Parameters:
* eax = 58 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 8 = subfunction number
* +4: dword: number of block to read (beginning from 0)
* +8: dword: ignored (set to 1)
* +12 = +0xC: dword: pointer to buffer for data (512 bytes)
* +16 = +0x10: dword: pointer to buffer for system operations
(4096 bytes)
* +20 = +0x14: ASCIIZ-name of device: case-insensitive, one of
/rd/1 = /RamDisk/1, /hd/n = /HardDisk/n,
1<=n<=4 - number of device: 1=IDE0, ..., 4=IDE3.
Instead of digits it is allowed, though not recommended for
convenience of transition to future extensions, to use
'first','second','third','fourth'.
Returned value:
* for device name /hd/xxx, where xxx is not in the list above:
* eax = ebx = 1
* for invalid device name (except for the previous case):
* eax = 5
* ebx does not change
* if LBA-access is disabled by subfunction 11 of function 21:
* eax = 2
* ebx destroyed
* for ramdisk: attempt to read block outside ramdisk
(18*2*80 blocks) results in
* eax = 3
* ebx = 0
* for successful read:
* eax = ebx = 0
Remarks:
* Block size is 512 bytes; function reads one block.
* Do not depend on returned value, it can be changed
in future versions.
* Function requires that LBA-access to devices is enabled by
subfunction 11 of function 21. To check this one can use
subfunction 11 of function 26.
* LBA-read of floppy is not supported.
* Function reads data on physical hard drive; if for any reason
data of the concrete partition are required, application must
define starting sector of this partition (either directly
through MBR, or from the full structure returned by
ïîäôóíêöèåé 11 ôóíêöèè 18).
* Function does not check error code of hard disk, so request of
nonexisting sector reads something (most probably it will be
zeroes, but this is defined by device) and this is considered
as success (eax=0).
 
======================================================================
==== Function 58, subfunction 15 - get information on file system. ===
======================================================================
Parameters:
* eax = 58 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 15 = subfunction number
* +4: dword: ignored
* +8: dword: ignored
* +12 = +0xC: dword: ignored
* +16 = +0x10: dword: ignored
* +20 = +0x14: (only second character is checked)
/rd=/RAMDISK or /hd=/HARDDISK
Returned value:
* if the second character does not belong to set {'r','R','h','H'}:
* eax = 3
* ebx = ecx = dword [fileinfo] = 0
* for ramdisk:
* eax = 0 (success)
* ebx = total number of clusters = 2847
* ecx = number of free clusters
* dword [fileinfo] = cluster size = 512
* for hard disk: base and partition are defined by subfunctions
7 and 8 of function 21:
* eax = 0 (success)
* ebx = total number of clusters
* ecx = number of free clusters
* dword [fileinfo] = cluster size (in bytes)
Remarks:
* Be not surprised to strange layout of 4th returned parameter
- when this code was writing, at system calls application got
only registers eax,ebx,ecx (from pushad-structure transmitted
as argument to the system function). Now it is corrected, so,
probably, it is meaningful to return cluster size in edx, while
this function is not used yet.
* There exists also subfunction 11 of function 18,
which returns information on file system. From the full table
of disk subsystem it is possible to deduce cluster size (there
it is stored in sectors) and total number of clusters
for hard disks.
 
======================================================================
========== Function 60 - Inter Process Communication (IPC). ==========
======================================================================
IPC is used for message dispatching from one process/thread to
another. Previously it is necessary to agree how to interpret
the concrete message.
 
----------- Subfunction 1 - set the area for IPC receiving -----------
Is called by process-receiver.
Parameters:
* eax = 60 - function number
* ebx = 1 - subfunction number
* ecx = pointer to the buffer
* edx = size of the buffer
Returned value:
* eax = 0 - always success
Format of IPC-buffer:
* +0: dword: if nonzero, buffer is considered locked;
lock/unlock the buffer, when you work with it and need that
buffer data are not changed from outside (no new messages)
* +4: dword: occupied place in the buffer (in bytes)
* +8: first message
* +8+n: second message
* ...
Format of a message:
* +0: dword: PID of sender
* +4: dword: message length (not including this header)
* +8: n*byte: message data
 
------------------ Subfunction 2 - send IPC message ------------------
Is called by process-sender.
Parameters:
* eax = 60 - function number
* ebx = 2 - subfunction number
* ecx = PID of receiver
* edx = pointer to the message data
* esi = message length (in bytes)
Returned value:
* eax = 0 - success
* eax = 1 - the receiver has not defined buffer for IPC messages
(can be, still have no time,
and can be, this is not right process)
* eax = 2 - the receiver has blocked IPC-buffer; try to wait a bit
* eax = 3 - overflow of IPC-buffer of the receiver
* eax = 4 - process/thread with such PID does not exist
Remarks:
* Immediately after writing of IPC-message to the buffer the system
sends to the receiver the event with code 7 (see event codes).
 
======================================================================
==== Function 61 - get parameters for the direct graphics access. ====
======================================================================
The data of the graphics screen (the memory area which displays
screen contents) are accessible to a program directly, without
any system calls, through the selector gs:
mov eax, [gs:0]
places in eax the first dword of the buffer, which contains
information on color of the left upper point (and, possibly, colors
of several following).
mov [gs:0], eax
by work in VESA modes with LFB sets color of the left upper point
(and, possibly, colors of several following).
To interpret the data of graphics screen program needs to know
some parameters, returning by this function.
Remarks:
* Graphics parameters changes very seldom at work,
namely, only in cases, when user works with the application VRR.
* At videomode change the system redraws all windows (event
with code 1) and redraws the background (event 5).
Same events occur in other cases too, which meet much more often,
than videomode change.
* By operation in videomodes with LFB the selector gs points to
LFB itself, so reading/writing on gs result directly in
change of screen contents. By operation in videomodes without
LFB gs points to some data area in the kernel, and all functions
of screen output fulfil honesty double operation on writing
directly to the screen and writing to this buffer. In result
at reading contents of this buffer the results correspond to
screen contents (with, generally speaking, large color
resolution), and writing is ignored.
One exception is the mode 320*200, for which main loop of the
system thread updates the screen according to mouse movements.
 
------------------------- Screen resolution --------------------------
Parameters:
* eax = 61 - function number
* ebx = 1 - subfunction number
Returned value:
* eax = [resolution on x axis]*65536 + [resolution on y axis]
Remarks:
* One can use function 14 paying attention that
it returns sizes on 1 pixel less. It is fully equivalent way.
 
---------------------- Number of bits per pixel ----------------------
Parameters:
* eax = 61 - function number
* ebx = 2 - subfunction number
Returned value:
* eax = number of bits per pixel (24 or 32)
 
-------------------- Number of bytes per scanline --------------------
Parameters:
* eax = 61 - function number
* ebx = 3 - subfunction number
Returned value:
* eax = number of bytes occupied by one scanline
(horizontal line on the screen)
 
======================================================================
===== Function 62, subfunction 0 - get version of PCI-interface. =====
======================================================================
Parameters:
* eax = 62 - function number
* bl = 0 - subfunction number
Returned value:
* eax = -1 - PCI access is disabled; otherwise
* ah.al = version of PCI-interface (ah=version, al=subversion)
* high word of eax is zeroed
Remarks:
* Previously low-level access to PCI for applications must be
enabled by subfunction 12 of function 21.
* If PCI BIOS is not supported, the value of ax is undefined.
 
======================================================================
==== Function 62, subfunction 1 - get number of the last PCI-bus. ====
======================================================================
Parameters:
* eax = 62 - function number
* bl = 1 - subfunction number
Returned value:
* eax = -1 - access to PCI is disabled; otherwise
* al = number of the last PCI-bus; other bytes of eax are destroyed
Remarks:
* Previously low-level access to PCI for applications must be
enabled by subfunction 12 of function 21.
* If PCI BIOS is not supported, the value of ax is undefined.
 
======================================================================
===================== Function 62, subfunction 2 =====================
===== Get mechanism of addressing to the PCI configuration space. ====
======================================================================
Parameters:
* eax = 62 - function number
* bl = 2 - subfunction number
Returned value:
* eax = -1 - access to PCI is disabled; otherwise
* al = mechanism (1 or 2); other bytes of eax are destroyed
Remarks:
* Previously low-level access to PCI for applications must be
enabled by subfunction 12 of function 21.
* Addressing mechanism is selected depending on
equipment characteristics.
* Subfunctions of read and write work automatically
with the selected mechanism.
 
======================================================================
======== Function 62, subfunctions 4,5,6 - read PCI-register. ========
======================================================================
Parameters:
* eax = 62 - function number
* bl = 4 - read byte
* bl = 5 - read word
* bl = 6 - read dword
* bh = number of PCI-bus
* ch = dddddfff, where ddddd = number of the device on the bus,
fff = function number of device
* cl = number of register (must be even for bl=5,
divisible by 4 for bl=6)
Returned value:
* eax = -1 - error (access to PCI is disabled or parameters
are not supported); otherwise
* al/ax/eax (depending on requested size) contains the data;
the other part of register eax is destroyed
Remarks:
* Previously low-level access to PCI for applications must be
enabled by subfunction 12 of function 21.
* Access mechanism 2 supports only 16 devices on a bus and ignores
function number. To get access mechanism use subfunction 2.
* Some registers are standard and exist for all devices, some are
defined by the concrete device. The list of registers of the
first type can be found e.g. in famous
Interrupt List by Ralf Brown
(http://www.pobox.com/~ralf/files.html,
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/);
registers of the second type must be listed
in the device documentation.
 
======================================================================
====== Function 62, subfunctions 8,9,10 - write to PCI-register. =====
======================================================================
Parameters:
* eax = 62 - function number
* bl = 8 - write byte
* bl = 9 - write word
* bl = 10 - write dword
* bh = number of PCI-bus
* ch = dddddfff, where ddddd = number of the device on the bus,
fff = function number of device
* cl = number of register (must be even for bl=9,
divisible by 4 for bl=10)
* dl/dx/edx (depending on requested size) contatins
the data to write
Returned value:
* eax = -1 - error (access to PCI is disabled or parameters
are not supported)
* eax = 0 - success
Remarks:
* Previously low-level access to PCI for applications must be
enabled by subfunction 12 of function 21.
* Access mechanism 2 supports only 16 devices on a bus and ignores
function number. To get access mechanism use subfunction 2.
* Some registers are standard and exist for all devices, some are
defined by the concrete device. The list of registers of the
first type can be found e.g. in famous Interrupt List by
Ralf Brown; registers of the second type must be listed
in the device documentation.
 
======================================================================
===================== Function 62, subfunction 11 ====================
== Initialize user-accessible MMIO channel ==
======================================================================
Parameters:
* eax = 62 - function
* bl = 11 - subfunction
* cx = PCI-address (bbbbbbbb dddddfff)
Returns:
* eax = -1 - PCI access not granted;
* eax = -2 - no user MMIO access to this PCI address;
* eax = -3 - memory allocation error; otherwise
* eax = available user heap size.
Remarks:
* Low-level PCI access must be allowed (fn21:12)
* PCI-address should correspond the system var [mmio_pci_addr]
 
======================================================================
===================== Function 62, subfunction 12 ====================
== Request user-accessible MMIO address space ==
======================================================================
Parameters:
* eax = 62 - function
* bl = 12 - subfunction
* bh = BAR number in PCI configuration space
* ecx = MMIO-block size needed (bytes)
* edx = MMIO-offset (number of whole 4Kb-pages!)
Returns:
* eax = -1 - user PCI access denied;
* eax = -2 - invalid BAR number;
* eax = -3 - BAR contains no valid IO addres;
* eax = -4 - BAR addresses IO ports;
* eax = -5 - dynamic allocation error; otherwise
* eax = MMIO start address (in application's linear space).
Remarks:
* Low-level PCI access must be allowed (fn21:12)
* The system var [mmio_pci_addr] sets the actual PCI-address
* The granted MMIO addresses should be released after use (fn62:13)
 
======================================================================
===================== Function 62, subfunction 13 ====================
== Release a block of user MMIO addresses ==
======================================================================
 à ¬¥âàë:
* eax = 62 - function
* bl = 12 - subfunction
* ecx = MMIO start address (in application's linear space).
Returns:
* eax = 1 if the block is successfully released;
* eax = 0 in case of reallocation error;
Remarks:
* A valid uMMIO block should exist at this address (fn62:12)
 
======================================================================
============== Function 63 - work with the debug board. ==============
======================================================================
The debug board is the global system buffer (with the size
1024 bytes), to which any program can write (generally speaking,
arbitrary) data and from which other program can read these data.
By the agreement written data are text strings interpreted as
debug messages on a course of program execution. The kernel in
some situations also writes to the debug board information on
execution of some functions; by the agreement kernel messages
begins from the prefix "K : ".
For view of the debug board the application 'board' was created,
which reads data from the buffer and displays them in its window.
'board' interpretes the sequence of codes 13,10 as newline.
A character with null code in an end of line is not necessary,
but also does not prevent.
Because debugger has been written, the value of the debug board
has decreased, as debugger allows to inspect completely a course of
program execution without any efforts from the direction of program
itself. Nevertheless in some cases the debug board is still useful.
 
----------------------------- Write byte -----------------------------
Parameters:
* eax = 63 - function number
* ebx = 1 - subfunction number
* cl = data byte
Returned value:
* function does not return value
Remarks:
* Byte is written to the buffer. Buffer size is 512 bytes.
At buffer overflow all obtained data are lost.
* For output to the debug board of more complicated objects
(strings, numbers) it is enough to call this function in cycle.
It is possible not to write the appropriate code manually and use
file 'debug.inc', which is included into the distributive.
 
----------------------------- Read byte ------------------------------
Takes away byte from the buffer.
Parameters:
* eax = 63 - function number
* ebx = 2 - subfunction number
Returned value:
* eax = ebx = 0 - the buffer is empty
* eax = byte, ebx = 1 - byte was successfully read
 
======================================================================
============== Function 64 - resize application memory. ==============
======================================================================
Parameters:
* eax = 64 - function number
* ebx = 1 - unique subfunction
* ecx = new memory size
Returned value:
* eax = 0 - success
* eax = 1 - not enough memory
Remarks:
* There is another way to dynamically allocate/free memory -
subfunctions 11, 12, 13 of function 68.
* The function cannot be used together with 68.11, 68.12, 68.13.
The function call will be ignored after creation of process heap
with function 68.11.
 
======================================================================
======== Function 65 - draw image with palette in the window. ========
======================================================================
Parameters:
* eax = 65 - function number
* ebx = pointer to the image
* ecx = [size on axis x]*65536 + [size on axis y]
* edx = [coordinate on axis x]*65536 + [coordinate on axis y]
* esi = number of bits per pixel, must be 1,2,4,8,15,16,24 or 32
* edi = pointer to palette (2 to the power esi colors 0x00RRGGBB);
ignored when esi > 8
* ebp = offset of next row data relative to previous row data
Returned value:
* function does not return value
Remarks:
* Coordinates of the image are coordinates of the upper left corner
of the image relative to the window.
* Format of image with 1 bit per pixel: each byte of image
(possibly excluding last bytes in rows), contains information on
the color of 8 pixels, MSB corresponds to first pixel.
* Format of image with 2 bits per pixel: each byte of image
(possibly excluding last bytes in rows), contains information on
the color of 4 pixels, two MSBs correspond to first pixel.
* Format of image with 4 bits per pixel: each byte of image
excluding last bytes in rows (if width is odd) contains
information on the color of 2 pixels, high-order tetrad
corresponds to first pixel.
* Format of image with 8 bits per pixel: each byte of image is
index in the palette.
* Format of image with 15 bits per pixel: the color of each pixel
is coded as (bit representation) 0RRRRRGGGGGBBBBB - 5 bits per
each color.
* Format of image with 16 bits per pixel: the color of each pixel
is coded as RRRRRGGGGGGBBBBB (5+6+5).
* Format of image with 24 bits per pixel: the color of each pixel
is coded as 3 bytes - sequentially blue, green, red components.
* Format of image with 32 bits per pixel: similar to 24, but
one additional ignored byte is present.
* The call to function 7 is equivalent to call to this function
with esi=24, ebp=0.
 
======================================================================
================== Function 66 - work with keyboard. =================
======================================================================
The input mode influences results of reading keys by function 2.
When a program loads, ASCII input mode is set for it.
If subfunction is not support then eax=-1.
 
-------------- Subfunction 1 - set keyboard input mode. --------------
Parameters:
* eax = 66 - function number
* ebx = 1 - subfunction number
* ecx = mode:
* 0 = normal (ASCII-characters)
* 1 = scancodes
Returned value:
* function does not return value
 
-------------- Subfunction 2 - get keyboard input mode. --------------
Parameters:
* eax = 66 - function number
* ebx = 2 - subfunction number
Returned value:
* eax = current mode
 
------------ Subfunction 3 - get status of control keys. -------------
Parameters:
* eax = 66 - function number
* ebx = 3 - subfunction number
Returned value:
* eax = bit mask:
* bit 0 (mask 1): left Shift is pressed
* bit 1 (mask 2): right Shift is pressed
* bit 2 (mask 4): left Ctrl is pressed
* bit 3 (mask 8): right Ctrl is pressed
* bit 4 (mask 0x10): left Alt is pressed
* bit 5 (mask 0x20): right Alt is pressed
* bit 6 (mask 0x40): CapsLock is on
* bit 7 (mask 0x80): NumLock is on
* bit 8 (mask 0x100): ScrollLock is on
* other bits are cleared
 
-------------- Subfunction 4 - set system-wide hotkey. ---------------
When hotkey is pressed, the system notifies only those applications,
which have installed it; the active application (which receives
all normal input) does not receive such keys.
The notification consists in sending event with the code 2.
Reading hotkey is the same as reading normal key - by function 2.
Parameters:
* eax = 66 - function number
* ebx = 4 - subfunction number
* cl determines key scancode;
use cl=0 to give combinations such as Ctrl+Shift
* edx = 0xXYZ determines possible states of control keys:
* Z (low 4 bits) determines state of LShift and RShift:
* 0 = no key must be pressed;
* 1 = exactly one key must be pressed;
* 2 = both keys must be pressed;
* 3 = must be pressed LShift, but not RShift;
* 4 = must be pressed RShift, but not LShift
* Y - similar for LCtrl and RCtrl;
* X - similar for LAlt and RAlt
Returned value:
* eax=0 - success
* eax=1 - too mant hotkeys (maximum 256 are allowed)
Remarks:
* Hotkey can work either at pressing or at release. Release
scancode of a key is more on 128 than pressing scancode
(i.e. high bit is set).
* Several applications can set the same combination;
all such applications will be informed on pressing
such combination.
 
-------------- Subfunction 5 - delete installed hotkey. --------------
Parameters:
* eax = 66 - function number
* ebx = 5 - subfunction number
* cl = scancode of key and edx = 0xXYZ the same as in subfunction 4
Returned value:
* eax = 0 - success
* eax = 1 - there is no such hotkey
Remarks:
* When a process/thread terminates, all hotkey installed by it are
deleted.
* The call to this subfunction does not affect other applications.
If other application has defined the same combination, it will
still receive notices.
 
======================================================================
========= Function 67 - change position/sizes of the window. =========
======================================================================
Parameters:
* eax = 67 - function number
* ebx = new x-coordinate of the window
* ecx = new y-coordinate of the window
* edx = new x-size of the window
* esi = new y-size of the window
Returned value:
* function does not return value
Remarks:
* The value -1 for a parameter means "do not change"; e.g. to move
the window without resizing it is possible to specify edx=esi=-1.
* Previously the window must be defined by function 0.
It sets initial coordinates and sizes of the window.
* Sizes of the window are understood in sense of function 0,
that is one pixel less than real sizes.
* The function call for maximized windows is simply ignored.
* For windows of appropriate styles position and/or sizes can be
changed by user; current position and sizes can be obtained by
call to function 9.
* The function sends to the window redraw event (with the code 1).
 
======================================================================
====== Function 68, subfunction 0 - get the task switch counter. =====
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 0 - subfunction number
Returned value:
* eax = number of task switches from the system booting
(modulo 2^32)
 
======================================================================
======= Function 68, subfunction 1 - switch to the next thread. ======
======================================================================
The function completes the current time slice allocated to the
thread and switches to the next. (Which thread in which process
will be next, is unpredictable). Later, when execution queue
will reach the current thread, execution will be continued.
Parameters:
* eax = 68 - function number
* ebx = 1 - subfunction number
Returned value:
* function does not return value
 
======================================================================
============= Function 68, subfunction 2 - cache + rdpmc. ============
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 2 - subfunction number
* ecx = required action:
* ecx = 0 - enable instruction 'rdpmc'
(ReaD Performance-Monitoring Counters) for applications
* ecx = 1 - find out whether cache is disabled/enabled
* ecx = 2 - enable cache
* ecx = 3 - disable cache
Returned value:
* for ecx=0:
* eax = the value of cr4
* for ecx=1:
* eax = (cr0 and 0x60000000):
* eax = 0 - cache is on
* eax <> 0 - cache is off
* for ecx=2 and ecx=3:
* function does not return value
 
======================================================================
=========== Function 68, subfunction 3 - read MSR-register. ==========
======================================================================
MSR = Model Specific Register; the complete list of MSR-registers
of a processor is included to the documentation on it (for example,
IA-32 Intel Architecture Software Developer's Manual,
Volume 3, Appendix B); each processor family has its own subset
of the MSR-registers.
Parameters:
* eax = 68 - function number
* ebx = 3 - subfunction number
* ecx is ignored
* edx = MSR address
Returned value:
* ebx:eax = high:low dword of the result
Remarks:
* If ecx contains nonexistent or not implemented for this processor
MSR, processor will generate an exception in the kernel, which
will kill the thread.
* Previously it is necessary to check, whether MSRs are supported
as a whole, with the instruction 'cpuid'. Otherwise processor
will generate other exception in the kernel, which will anyway
kill the thread.
 
======================================================================
========= Function 68, subfunction 4 - write to MSR-register. ========
======================================================================
MSR = Model Specific Register; the complete list of MSR-registers
of a processor is included to the documentation on it (for example,
IA-32 Intel Architecture Software Developer's Manual,
Volume 3, Appendix B); each processor family has its own subset
of the MSR-registers.
Parameters:
* eax = 68 - function number
* ebx = 4 - subfunction number
* ecx is ignored
* edx = MSR address
* esi:edi = high:low dword
Returned value:
* function does not return value
Remarks:
* If ecx contains nonexistent or not implemented for this processor
MSR, processor will generate an exception in the kernel, which
will kill the thread.
* Previously it is necessary to check, whether MSRs are supported
as a whole, with the instruction 'cpuid'. Otherwise processor
will generate other exception in the kernel, which will anyway
kill the thread.
 
======================================================================
======= Function 68, subfunction 11 - initialize process heap. =======
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 11 - subfunction number
Returned value:
* eax = 0 - failed
* otherwise size of created heap
Remarks:
* The function call initializes heap, from which one can in future
allocate and free memory blocks with subfunctions 12 and 13.
Heap size is equal to total amount of free application memory.
* The second function call from the same process results in
returning the size of the existing heap.
* After creation of the heap calls to function 64 will be ignored.
 
======================================================================
======== Function 68, subfunction 12 - allocate memory block. ========
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 12 - subfunction number
* ecx = required size in bytes
Returned value:
* eax = pointer to the allocated block
Remarks:
* Before this call one must initialize process heap by call to
subfunction 11.
* The function allocates an integer number of pages (4 Kb) in such
way that the real size of allocated block is more than or equal to
requested size.
 
======================================================================
========== Function 68, subfunction 13 - free memory block. ==========
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 13 - subfunction number
* ecx = pointer to the memory block
Returned value:
* eax = 1 - success
* eax = 0 - failed
Remarks:
* The memory block must have been allocated by subfunction 12
or subfunction 20.
 
======================================================================
===================== Function 68, subfunction 14 ====================
====== Waiting delivering of signal from another program/driver ======
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 14 - subfunction number
* ecx = pointer to the buffer for information (24 bytes)
Returned value:
* buffer pointed to by ecx contains the following information:
* +0: dword: identifier for underlying data of signal
* +4: data of signal (20 bytes), format of which is defining by
first dword
 
======================================================================
====== Function 68, subfunction 15 - set FPU exception handler. ======
======================================================================
Deleted (in current implementation only 0 is returned).
Using subfunctions 24, 25 is true.
 
======================================================================
============= Function 68, subfunction 16 - load driver. =============
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 16 - subfunction number
* ecx = pointer to ASCIIZ-string with driver name
Returned value:
* eax = 0 - failed
* otherwise eax = driver handle
Remarks:
* If the driver was not loaded yet, it is loaded;
if the driver was loaded yet, nothing happens.
* Driver name is case-sensitive.
Maximum length of the name is 16 characters, including
terminating null character, the rest is ignored.
* Driver ABC is loaded from file /rd/1/drivers/ABC.obj.
 
======================================================================
============ Function 68, subfunction 17 - driver control. ===========
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 17 - subfunction number
* ecx = pointer to the control structure:
* +0: dword: handle of driver
* +4: dword: code of driver function
* +8: dword: pointer to input data
* +12 = +0xC: dword: size of input data
* +16 = +0x10: dword: pointer to output data
* +20 = +0x14: dword: size of output data
Returned value:
* eax = error code
0 - successful call
-1 - any error.
-2, -3, -4, etc. reserved for kernel error codes
1, 2, 3, etc driver specific error codes
Remarks:
* Function codes and the structure of input/output data
are defined by driver.
* Previously one must obtain driver handle by subfunction 16.
 
======================================================================
====== Function 68, subfunction 18 - set SSE exception handler. ======
======================================================================
Deleted (in current implementation only 0 is returned).
Using subfunctions 24, 25 is true.
 
======================================================================
=============== Function 68, subfunction 19 - load DLL. ==============
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 19 - subfunction number
* ecx = pointer to ASCIIZ-string with the full path to DLL
Returned value:
* eax = 0 - failed
* otherwise eax = pointer to DLL export table
Remarks:
* Export table is an array of structures of 2 dword's, terminated
by zero. The first dword in structure points to function name,
the second dword contains address of function.
 
======================================================================
======= Function 68, subfunction 20 - reallocate memory block. =======
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 20 - subfunction number
* ecx = new size in bytes
* edx = pointer to already allocated block
Returned value:
* eax = pointer to the reallocated block, 0 = error
Remarks:
* Before this call one must initialize process heap by call to
subfunction 11.
* The function allocates an integer number of pages (4 Kb) in such
way that the real size of allocated block is more than or equal to
requested size.
* If edx=0, the function call is equivalent to memory allocation
with subfunction 12. Otherwise the block at edx
must be allocated earlier with subfunction 12 or this subfunction.
* If ecx=0, the function frees memory block at edx and returns 0.
* The contents of the block are unchanged up to the shorter of
the new and old sizes.
 
======================================================================
====== Function 68, subfunction 24 - set new exceptions handler ======
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 24 - subfunction number
* ecx = address of the new exception handler
* edx = the mask of processing exceptions
Returned value:
* eax = address of the old exception handler (0, if it was not set)
* ebx = the old mask of exception handler
Remarks:
* Bit number in mask of exceptions is correspond to exception number
by CPU-specification (Intel-PC). For example, FPU-exception have
number 16 (#MF), and SSE-exception - 19 (#XF)
* The current implementation ignore the inquiry for hook of 7
exception - system process #NM by one's own.
* User handler get exception number in stack parameter. So, correct
exit from handler is: RET 4. Return from handler is to the same
instruction, that was cause the exception
* When control is transfering to user handler, corresponding bit in
exception mask is clearing. Rising this exception in consequence
- reduce to default-handling. Exactly: terminating the application,
or suspending with debug-notify to owner.
* After completion of critical operations in user handler, it may be
rising corresponding bit in exception mask by using subfunction 25
Clearing exceptions flags in FPU and/or XMM modules - is
responsibility of user handler too.
 
======================================================================
==== Function 68, subfunction 25 - change state of signal activity ===
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 25 - subfunction number
* ecx = signal number
* edx = value of activity (0/1)
Returned value:
* eax = value of old activity for this signal (0/1)
Remarks:
* In current implementation, it is changed only exception mask for
user exception handler, wich was previously set by subfunction 24.
At that, number of signal correspond to exception number.
 
======================================================================
====================== Fucntion 69 - debugging. ======================
======================================================================
A process can load other process as debugged by set of corresponding
bit by call to subfunction 7 of function 70.
A process can have only one debugger; one process can debug some
others. The system notifies debugger on events occuring with
debugged process. Messages are written to the buffer defined by
subfunction 0.
Format of a message:
* +0: dword: message code
* +4: dword: PID of debugged process
* +8: there can be additional data depending on message code
Message codes:
* 1 = exception
* in addition dword-number of the exception is given
* process is suspended
* 2 = process has terminated
* comes at any termination: both through the system function -1,
and at "murder" by any other process (including debugger itself)
* 3 = debug exception int 1 = #DB
* in addition dword-image of the register DR6 is given:
* bits 0-3: condition of the corresponding breakpoint (set by
subfunction 9) is satisfied
* áèò 14: exception has occured because of the trace mode
(flag TF is set TF)
* process is suspended
When debugger terminates, all debugged processes are killed.
If debugger does not want this, it must previously detach by
subfunction 3.
 
All subfunctions are applicable only to processes/threads started
from the current by function 70 with set debugging flag.
Debugging of multithreaded programs is not supported yet.
The full list of subfunctions:
* subfunction 0 - define data area for debug messages
* subfunction 1 - get contents of registers of debugged thread
* subfunction 2 - set contents of registers of debugged thread
* subfunction 3 - detach from debugged process
* subfunction 4 - suspend debugged thread
* subfunction 5 - resume debugged thread
* subfunction 6 - read from the memory of debugged process
* subfunction 7 - write to the memory of debugged process
* subfunction 8 - terminate debugged thread
* subfunction 9 - set/clear hardware breakpoint
 
======================================================================
= Function 69, subfunction 0 - define data area fror debug messages. =
======================================================================
Parameters:
* eax = 69 - function number
* ebx = 0 - subfunction number
* ecx = pointer
Format of data area:
* +0: dword: N = buffer size (not including this header)
* +4: dword: occupied place
* +8: N*byte: buffer
Returned value:
* function does not return value
Remarks:
* If the size field is negative, the buffer is considered locked
and at arrival of new message the system will wait.
For synchronization frame all work with the buffer by operations
lock/unlock
neg [bufsize]
* Data in the buffer are considered as array of items with variable
length - messages. Format of a message is explained in
general description.
 
======================================================================
===================== Function 69, subfunction 1 =====================
============ Get contents of registers of debugged thread. ===========
======================================================================
Parameters:
* eax = 69 - function number
* ebx = 1 - subfunction number
* ecx = thread identifier
* edx = size of context structure, must be 0x28=40 bytes
* esi = pointer to context structure
Returned value:
* function does not return value
Format of context structure: (FPU is not supported yet)
* +0: dword: eip
* +4: dword: eflags
* +8: dword: eax
* +12 = +0xC: dword: ecx
* +16 = +0x10: dword: edx
* +20 = +0x14: dword: ebx
* +24 = +0x18: dword: esp
* +28 = +0x1C: dword: ebp
* +32 = +0x20: dword: esi
* +36 = +0x24: dword: edi
Remarks:
* If the thread executes code of ring-0, the function returns
contents of registers of ring-3.
* Process must be loaded for debugging (as is shown in
general description).
 
======================================================================
===================== Function 69, subfunction 2 =====================
============ Set contents of registers of debugged thread. ===========
======================================================================
Parameters:
* eax = 69 - function number
* ebx = 2 - subfunction number
* ecx = thread identifier
* edx = size of context structure, must be 0x28=40 bytes
Returned value:
* function does not return value
Format of context structure is shown in the description of
subfunction 1.
Remarks:
* If the thread executes code of ring-0, the function returns
contents of registers of ring-3.
* Process must be loaded for debugging (as is shown in
general description).
 
======================================================================
===== Function 69, subfunction 3 - detach from debugged process. =====
======================================================================
Parameters:
* eax = 69 - function number
* ebx = 3 - subfunction number
* ecx = identifier
Returned value:
* function does not return value
Remarks:
* If the process was suspended, it resumes execution.
 
======================================================================
======== Function 69, subfunction 4 - suspend debugged thread. =======
======================================================================
Parameters:
* eax = 69 - function number
* ebx = 4 - subfunction number
* ecx = thread identifier
Returned value:
* function does not return value
Remarks:
* Process must be loaded for debugging (as is shown in
general description).
 
======================================================================
======== Function 69, subfunction 5 - resume debugged thread. ========
======================================================================
Parameters:
* eax = 69 - function number
* ebx = 5 - subfunction number
* ecx = thread identifier
Returned value:
* function does not return value
Remarks:
* Process must be loaded for debugging (as is shown in
general description).
 
======================================================================
= Fucntion 69, subfunction 6 - read from memory of debugged process. =
======================================================================
Parameters:
* eax = 69 - function number
* ebx = 6 - subfunction number
* ecx = identifier
* edx = number of bytes to read
* esi = address in the memory of debugged process
* edi = pointer to buffer for data
Returned value:
* eax = -1 at an error (invalid PID or buffer)
* otherwise eax = number of read bytes (possibly, 0,
if esi is too large)
Remarks:
* Process must be loaded for debugging (as is shown in
general description).
 
======================================================================
== Function 69, subfunction 7 - write to memory of debugged process. =
======================================================================
Parameters:
* eax = 69 - function number
* ebx = 7 - subfunction number
* ecx = identifier
* edx = number of bytes to write
* esi = address of memory in debugged process
* edi = pointer to data
Returned value:
* eax = -1 at an error (invalid PID or buffer)
* otherwise eax = number of written bytes (possibly, 0,
if esi is too large)
Remarks:
* Process must be loaded for debugging (as is shown in
general description).
 
======================================================================
======= Function 69, subfunction 8 - terminate debugged thread. ======
======================================================================
Parameters:
* eax = 69 - function number
* ebx = 8 - subfunction number
* ecx = identifier
Returned value:
* function does not return value
Remarks:
* Process must be loaded for debugging (as is shown in
general description).
* The function is similar to subfunction 2 of function 18
with two differences: it requires first remark and
accepts PID rather than slot number.
 
======================================================================
===== Function 69, subfunction 9 - set/clear hardware breakpoint. ====
======================================================================
Parameters:
* eax = 69 - function number
* ebx = 9 - subfunction number
* ecx = thread identifier
* dl = index of breakpoint, from 0 to 3 inclusively
* dh = flags:
* if high bit is cleared - set breakpoint:
* bits 0-1 - condition:
* 00 = breakpoint on execution
* 01 = breakpoint on read
* 11 = breakpoint on read/write
* bits 2-3 - length; for breakpoints on exception it must be
00, otherwise one of
* 00 = byte
* 01 = word
* 11 = dword
* esi = breakpoint address; must be aligned according to
the length (i.e. must be even for word breakpoints,
divisible by 4 for dword)
* if high bit is set - clear breakpoint
Returned value:
* eax = 0 - success
* eax = 1 - error in the input data
* eax = 2 - (reserved, is never returned in the current
implementation) a global breakpoint with that index is already set
Remarks:
* Process must be loaded for debugging (as is shown in
general description).
* Hardware breakpoints are implemented through DRx-registers of
the processor, all limitations results from this.
* The function can reinstall the breakpoint, previously set
by it (and it does not inform on this).
Carry on the list of set breakpoints in the debugger.
* Breakpoints generate debug exception #DB, on which the system
notifies debugger.
* Breakpoints on write and read/write act after
execution of the caused it instruction.
 
======================================================================
==== Function 70 - work with file system with long names support. ====
======================================================================
Parameters:
* eax = 70
* ebx = pointer to the information structure
Returned value:
* eax = 0 - success; otherwise file system error code
* some subfunctions return value in other registers too
General format of the information structure:
* +0: dword: subfunction number
* +4: dword: file offset
* +8: dword: high dword of offset (must be 0) or flags field
* +12 = +0xC: dword: size
* +16 = +0x10: dword: pointer to data
* +20 = +0x14: n db: ASCIIZ-string with the filename
or
* +20 = +0x14: db 0
* +21 = +0x15: dd pointer to ASCIIZ-string with the filename
Specifications - in documentation on the appropriate subfunction.
Filename is case-insensitive. Russian letters must be written in
the encoding cp866 (DOS).
Format of filename:
/base/number/dir1/dir2/.../dirn/file,
where /base/number identifies device, on which file is located:
one of
* /RD/1 = /RAMDISK/1 to access ramdisk
* /FD/1 = /FLOPPYDISK/1 to access first floppy drive,
/FD/2 = /FLOPPYDISK/2 to access second one
* /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices
IDE0 (Primary Master), IDE1 (Primary Slave),
IDE2 (Secondary Master), IDE3 (Secondary Slave);
x - partition number on the selected hard drive, varies from 1
to 255 (on each hard drive the indexing starts from 1)
* /CD0/1, /CD1/1, /CD2/1, /CD3/1 to access accordingly to
CD on IDE0 (Primary Master), IDE1 (Primary Slave),
IDE2 (Secondary Master), IDE3 (Secondary Slave)
* /SYS means system folder; with the usual boot (from floppy)
is equivalent to /RD/1
Examples:
* '/rd/1/kernel.asm',0
* '/HD0/1/kernel.asm',0
* '/hd0/2/menuet/pics/tanzania.bmp',0
* '/hd0/1/Program files/NameOfProgram/SomeFile.SomeExtension',0
* '/sys/MySuperApp.ini',0
Available subfunctions:
* subfunction 0 - read file
* subfunction 1 - read folder
* subfunction 2 - create/rewrite file
* subfunction 3 - write to existing file
* subfunction 4 - set file size
* subfunction 5 - get attributes of file/folder
* subfunction 6 - set attributes of file/folder
* subfunction 7 - start application
* subfunction 8 - delete file/folder
* subfunction 9 - create folder
For CD-drives due to hardware limitations only subfunctions
0,1,5 and 7 are available, other subfunctions return error
with code 2.
At the first call of subfunctions 0,1,5,7 to ATAPI devices
(CD and DVD) the manual control of tray is locked due to caching
drive data. Unlocking is made when subfunction 4 of function 24
is called for corresponding device.
 
======================================================================
=== Function 70, subfunction 0 - read file with long names support. ==
======================================================================
Parameters:
* eax = 70 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 0 = subfunction number
* +4: dword: file offset (in bytes)
* +8: dword: 0 (reserved for high dword of offset)
* +12 = +0xC: dword: number of bytes to read
* +16 = +0x10: dword: pointer to buffer for data
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
given in the general description
or
* +20 = +0x14: db 0
* +21 = +0x15: dd pointer to ASCIIZ-string with file name
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx = number of read bytes or -1=0xffffffff if file was not found
Remarks:
* If file was ended before last requested block was read,
the function will read as many as it can, and after that return
eax=6 (EOF).
* The function does not allow to read folder (returns eax=10,
access denied).
 
======================================================================
== Function 70, subfunction 1 - read folder with long names support. =
======================================================================
Parameters:
* eax = 70 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 1 = subfunction number
* +4: dword: index of starting block (beginning from 0)
* +8: dword: flags field:
* bit 0 (mask 1): in what format to return names,
0=ANSI, 1=UNICODE
* other bits are reserved and must be set to 0 for the future
compatibility
* +12 = +0xC: dword: number of blocks to read
* +16 = +0x10: dword: pointer to buffer for data, buffer size
must be not less than 32 + [+12]*560 bytes
* +20 = +0x14: ASCIIZ-name of folder, the rules of names forming are
given in the general description
or
* +20 = +0x14: db 0
* +21 = +0x15: dd pointer to ASCIIZ-string with file name
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx = number of files, information on which was written to
the buffer, or -1=0xffffffff, if folder was not found
Structure of the buffer:
* +0: 32*byte: header
* +32 = +0x20: n1*byte: block with information on file 1
* +32+n1: n2*byte: block with information on file 2
* ...
Structure of header:
* +0: dword: version of structure (current is 1)
* +4: dword: number of placed blocks; is not greater than requested
in the field +12 of information structure; can be less, if
there are no more files in folder (the same as in ebx)
* +8: dword: total number of files in folder
* +12 = +0xC: 20*byte: reserved (zeroed)
Structure of block of data for folder entry (BDFE):
* +0: dword: attributes of file:
* bit 0 (mask 1): file is read-only
* bit 1 (mask 2): file is hidden
* bit 2 (mask 4): file is system
* bit 3 (mask 8): this is not a file but volume label
(for one partition meets no more than once and
only in root folder)
* bit 4 (mask 0x10): this is a folder
* bit 5 (mask 0x20): file was not archived - many archivation
programs have an option to archive only files with this bit set,
and after archiving this bit is cleared - it can be useful
for automatically creating of backup-archives as at writing
this bit is usually set
* +4: byte: type of name data:
(coincides with bit 0 of flags in the information structure)
* 0 = ASCII = 1-byte representation of each character
* 1 = UNICODE = 2-byte representation of each character
* +5: 3*byte: reserved (zero)
* +8: 4*byte: time of file creation
* +12 = +0xC: 4*byte: date of file creation
* +16 = +0x10: 4*byte: time of last access (read or write)
* +20 = +0x14: 4*byte: date of last access
* +24 = +0x18: 4*byte: time of last modification
* +28 = +0x1C: 4*byte: date of last modification
* +32 = +0x20: qword: file size in bytes (up to 16777216 Tb)
* +40 = +0x28: name
* for ASCII format: maximum length is 263 characters
(263 bytes), byte after the name has value 0
* for UNICODE format: maximum length is 259 characters
(518 bytes), 2 bytes after the name have value 0
Time format:
* +0: byte: seconds
* +1: byte: minutes
* +2: byte: hours
* +3: byte: reserved (0)
* for example, 23.59.59 is written as (in hex) 3B 3B 17 00
Date format:
* +0: byte: day
* +1: byte: month
* +2: word: year
* for example, 25.11.1979 is written as (in hex) 19 0B BB 07
Remarks:
* If BDFE contains ASCII name, the length of BDFE is 304 bytes,
if UNICODE name - 560 bytes. Value of length is aligned
on 16-byte bound (to accelerate processing in CPU cache).
* First character after a name is zero (ASCIIZ-string). The further
data contain garbage.
* If files in folder were ended before requested number was read,
the function will read as many as it can, and after that return
eax=6 (EOF).
* Any folder on the disk, except for root, contains two special
entries "." and "..", identifying accordingly the folder itself
and the parent folder.
* The function allows also to read virtual folders "/", "/rd",
"/fd", "/hd[n]", thus attributes of subfolders are set to 0x10,
and times and dates are zeroed. An alternative way to get the
equipment information - subfunction 11 of function 18.
 
======================================================================
===================== Function 70, subfunction 2 =====================
============ Create/rewrite file with long names support. ============
======================================================================
Parameters:
* eax = 70 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 2 = subfunction number
* +4: dword: 0 (reserved)
* +8: dword: 0 (reserved)
* +12 = +0xC: dword: number of bytes to read
* +16 = +0x10: dword: pointer to data
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
given in the general description
or
* +20 = +0x14: db 0
* +21 = +0x15: dd pointer to ASCIIZ-string with file name
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx = number of written bytes (possibly 0)
Remarks:
* If a file with given name did not exist, it is created;
if it existed, it is rewritten.
* If there is not enough free space on disk, the function will
write as many as can and then return error code 8.
* The function is not supported for CD (returns error code 2).
 
======================================================================
===================== Function 70, subfunction 3 =====================
=========== Write to existing file with long names support. ==========
======================================================================
Parameters:
* eax = 70 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 3 = subfunction number
* +4: dword: file offset (in bytes)
* +8: dword: high dword of offset (must be 0 for FAT)
* +12 = +0xC: dword: number of bytes to write
* +16 = +0x10: dword: pointer to data
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
given in the general description
or
* +20 = +0x14: db 0
* +21 = +0x15: dd pointer to ASCIIZ-string with file name
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx = number of written bytes (possibly 0)
Remarks:
* The file must already exist, otherwise function returns eax=5.
* The only result of write 0 bytes is update in the file attributes
date/time of modification and access to the current date/time.
* If beginning and/or ending position is greater than file size
(except for the previous case), the file is expanded to needed
size with zero characters.
* The function is not supported for CD (returns error code 2).
 
======================================================================
============ Function 70, subfunction 4 - set end of file. ===========
======================================================================
Parameters:
* eax = 70 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 4 = subfunction number
* +4: dword: low dword of new file size
* +8: dword: high dword of new file size (must be 0 for FAT)
* +12 = +0xC: dword: 0 (reserved)
* +16 = +0x10: dword: 0 (reserved)
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
given in the general description
or
* +20 = +0x14: db 0
* +21 = +0x15: dd pointer to ASCIIZ-string with file name
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx destroyed
Remarks:
* If the new file size is less than old one, file is truncated.
If the new size is greater than old one, file is expanded with
characters with code 0. If the new size is equal to old one,
the only result of call is set date/time of modification and
access to the current date/time.
* If there is not enough free space on disk for expansion, the
function will expand to maximum possible size and then return
error code 8.
* The function is not supported for CD (returns error code 2).
 
======================================================================
==== Function 70, subfunction 5 - get information on file/folder. ====
======================================================================
Parameters:
* eax = 70 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 5 = subfunction number
* +4: dword: 0 (reserved)
* +8: dword: 0 (reserved)
* +12 = +0xC: dword: 0 (reserved)
* +16 = +0x10: dword: pointer to buffer for data (40 bytes)
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
given in the general description
or
* +20 = +0x14: db 0
* +21 = +0x15: dd pointer to ASCIIZ-string with file name
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx destroyed
Information on file is returned in the BDFE format (block of data
for folder entry), explained in the description of
subfunction 1, but without filename
(i.e. only first 40 = 0x28 bytes).
Remarks:
* The function does not support virtual folders such as /, /rd and
root folders like /rd/1.
 
======================================================================
===== Function 70, subfunction 6 - set attributes of file/folder. ====
======================================================================
Parameters:
* eax = 70 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 6 = subfunction number
* +4: dword: 0 (reserved)
* +8: dword: 0 (reserved)
* +12 = +0xC: dword: 0 (reserved)
* +16 = +0x10: dword: pointer to buffer with attributes (32 bytes)
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
given in the general description
or
* +20 = +0x14: db 0
* +21 = +0x15: dd pointer to ASCIIZ-string with file name
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx destroyed
File attributes are first 32 bytes in BDFE (block of data
for folder entry), explained in the description of subfunction 1
(that is, without name and size of file). Attribute
file/folder/volume label (bits 3,4 in dword +0) is not changed.
Byte +4 (name format) is ignored.
Remarks:
* The function does not support virtual folders such as /, /rd and
root folders like /rd/1.
* The function is not supported for CD (returns error code 2).
 
======================================================================
=========== Function 70, subfunction 7 - start application. ==========
======================================================================
Parameters:
* eax = 70 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 7 = subfunction number
* +4: dword: flags field:
* áèò 0: start process as debugged
* other bits are reserved and must be set to 0
* +8: dword: 0 or pointer to ASCIIZ-string with parameters
* +12 = +0xC: dword: 0 (reserved)
* +16 = +0x10: dword: 0 (reserved)
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
given in the general description
or
* +20 = +0x14: db 0
* +21 = +0x15: dd pointer to ASCIIZ-string with file name
Returned value:
* eax > 0 - program is loaded, eax contains PID
* eax < 0 - an error has occured, -eax contains
file system error code
* ebx destroyed
Remarks:
* Command line must be terminated by the character with the code 0
(ASCIIZ-string); function takes into account either all characters
up to terminating zero inclusively or first 256 character
regarding what is less.
* If the process is started as debugged, it is created in
the suspended state; to run use subfunction 5 of function 69.
 
======================================================================
========== Function 70, subfunction 8 - delete file/folder. ==========
======================================================================
Parameters:
* eax = 70 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 8 = subfunction number
* +4: dword: 0 (reserved)
* +8: dword: 0 (reserved)
* +12 = +0xC: dword: 0 (reserved)
* +16 = +0x10: dword: 0 (reserved)
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are
given in the general description
or
* +20 = +0x14: db 0
* +21 = +0x15: dd pointer to ASCIIZ-string with file name
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx destroyed
Remarks:
* The function is not supported for CD (returns error code 2).
* The function can delete only empty folders (attempt to delete
nonempty folder results in error with code 10, "access denied").
 
======================================================================
============= Function 70, subfunction 9 - create folder. ============
======================================================================
Parameters:
* eax = 70 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 9 = subfunction number
* +4: dword: 0 (reserved)
* +8: dword: 0 (reserved)
* +12 = +0xC: dword: 0 (reserved)
* +16 = +0x10: dword: 0 (reserved)
* +20 = +0x14: ASCIIZ-name of folder, the rules of names forming are
given in the general description
or
* +20 = +0x14: db 0
* +21 = +0x15: dd pointer to ASCIIZ-string with folder name
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx destroyed
Remarks:
* The function is not supported for CD (returns error code 2).
* The parent folder must already exist.
* If target folder already exists, function returns success (eax=0).
 
======================================================================
========== Function 71, subfunction 1 - set window caption. ==========
======================================================================
Parameters:
* eax = 71 - function number
* ebx = 1 - subfunction number
* ecx = pointer to caption string
Returned value:
* function does not return value
Remarks:
* String must be in the ASCIIZ-format. Disregarding real string
length, no more than 255 characters are drawn.
* Pass NULL in ecx to remove caption.
 
======================================================================
=============== Function 72 - send message to a window. ==============
======================================================================
 
- Subfunction 1 - send message with parameter to the active window. --
Parameters:
* eax = 72 - function number
* ebx = 1 - subfunction number
* ecx = event code: 2 or 3
* edx = parameter: key code for ecx=2, button identifier for ecx=3
Returned value:
* eax = 0 - success
* eax = 1 - buffer is full
 
======================================================================
=============== Function -1 - terminate thread/process ===============
======================================================================
Parameters:
* eax = -1 - function number
Returned value:
* function does not return neither value nor control
Remarks:
* If the process did not create threads obviously, it has only
one thread, which termination results in process termination.
* If the current thread is last in the process, its termination
also results in process terminates.
* This function terminates the current thread. Other thread can be
killed by call to subfunction 2 of function 18.
 
======================================================================
=========================== List of events ===========================
======================================================================
Next event can be retrieved by the call of one from functions 10
(to wait for event), 11 (to check without waiting), 23
(to wait during the given time).
These functions return only those events, which enter into a mask set
by function 40. By default it is first three,
there is enough for most applications.
Codes of events:
* 1 = redraw event (is reset by call to function 0)
* 2 = key on keyboard is pressed (acts, only when the window is
active) or hotkey is pressed; is reset, when all keys from
the buffer are read out by function 2
* 3 = button is pressed, defined earlier by function 8
(or close button, created implicitly by function 0;
minimize button is handled by the system and sends no message;
acts, only when the window is active;
is reset when all buttons from the buffer
are read out by function 17)
* 4 = reserved (in current implementation never comes even after
unmasking by function 40)
* 5 = the desktop background is redrawed (is reset automatically
after redraw, so if in redraw time program does not wait and
does not check events, it will not remark this event)
* 6 = mouse event (something happened - button pressing or moving;
is reset at reading)
* 7 = IPC event (see function 60 -
Inter Process Communication; is reset at reading)
* 8 = network event (is reset at reading)
* 9 = debug event (is reset at reading; see
debug subsystem)
* 16..31 = event with appropriate IRQ
(16=IRQ0, 31=IRQ15) (is reset after reading all IRQ data)
 
======================================================================
=================== Error codes of the file system ===================
======================================================================
* 0 = success
* 1 = base and/or partition of a hard disk is not defined
(by subfunctions 7, 8 of function 21)
* 2 = function is not supported for the given file system
* 3 = unknown file system
* 4 = reserved, is never returned in the current implementation
* 5 = file not found
* 6 = end of file, EOF
* 7 = pointer lies outside of application memory
* 8 = disk is full
* 9 = FAT table is destroyed
* 10 = access denied
* 11 = device error
Application start functions can return also following errors:
* 30 = 0x1E = not enough memory
* 31 = 0x1F = file is not executable
* 32 = 0x20 = too many processes
/kernel/branches/Kolibri-acpi/docs/loader_doc.txt
0,0 → 1,88
; (english text below)
 
;------------------------------------------
; Èíòåðôåéñ ñîõðàíåíèÿ ïàðàìåòðîâ
;------------------------------------------
Åñëè ïðè ïåðåäà÷å óïðàâëåíèÿ ÿäðó çàãðóç÷èê óñòàíàâëèâàåò AX='KL',
òî â DS:SI ÿäðî îæèäàåò äàëüíåãî óêàçàòåëÿ íà ñëåäóþùóþ ñòðóêòóðó:
db âåðñèÿ ñòðóêòóðû, äîëæíà áûòü 1
dw ôëàãè:
áèò 0 óñòàíîâëåí = ïðèñóòñòâóåò îáðàç ðàìäèñêà â ïàìÿòè
dd äàëüíèé óêàçàòåëü íà ïðîöåäóðó ñîõðàíåíèÿ ïàðàìåòðîâ
ìîæåò áûòü 0, åñëè çàãðóç÷èê íå ïîääåðæèâàåò
Ïðîöåäóðà ñîõðàíåíèÿ ïàðàìåòðîâ äîëæíà çàïèñàòü ïåðâûé ñåêòîð ÿäðà
kernel.mnt íàçàä íà òî ìåñòî, îòêóäà îíà åãî ñ÷èòàëà; âîçâðàò èç
ïðîöåäóðû îñóùåñòâëÿåòñÿ ïî retf.
 
;------------------------------------------
; Óêàçàíèå çàãðóç÷èêîì ñèñòåìíîãî êàòàëîãà
;------------------------------------------
Ïåðåä ïåðåäà÷åé óïðàâëåíèÿ ÿäðó ìîãóò áûòü óñòàíîâëåíû ñëåäóþùèå ðåãèñòðû:
CX='HA'
DX='RD'
Ýòî óêàçûâàåò íà òî, ÷òî ðåãèñòð BX óêàçûâàåò íà ñèñòåìíûé ðàçäåë. Êàòàëîã /kolibri/ íà
ýòîì ðàçäåëå ÿâëÿåòñÿ ñèñòåìíûì, ê íåìó ìîæíî îáðàùàòüñÿ êàê ê /sys/
 
Âîçìîæíûå çíà÷åíèÿ ðåãèñòðà BL (óêàçûâàåò íà óñòðîéñòâî):
'a' - Primary Master
'b' - Primary Slave
'c' - Secondary Master
'd' - Secondary Slave
'r' - RAM äèñê
'm' - Ïðèâîäû CD-ROM
 
Âîçìîæíûå çíà÷åíèÿ ðåãèñòðà BH (óêàçûâàåò íà ðàçäåë):
äëÿ BL='a','b','c','d','r' - óêàçûâàåò íà ðàçäåë, ãäå ðàñïîëîæåí ñèñòåìíûé êàòàëîã
äëÿ BL='m',óêàçûâàåò íà íîìåð ôèçè÷åñêîãî óñòðîéñòâà, ñ êîòîðîãî íàäî íà÷èíàòü ïîèñê ñèñòåìíîãî êàòàëîãà.
 
ïðèìåðû çíà÷åíèé ðåãèñòðà BX:
'a1' - /hd0/1/
'a2' - /hd0/2/
'b1' - /hd1/1/
'd4' - /hd3/4/
'm0' - ïîèñê ïî ñèäþêàì êàòàëîãà kolibri
'r1' - /rd/1/
 
 
;------------------------------------------
; Interface for saving boot-screen settings
;------------------------------------------
If a loader sets AX='KL' when transferring control to the kernel,
the kernel expects in DS:SI far pointer to the following structure:
db structure version, must be 1
dw flags
bit 0 set = ramdisk image in memory is present
dd far pointer to save settings procedure
may be 0 if such procedure is not supported by loader
Procedure for saving settings must write the first sector of the kernel
kernel.mnt back to the place, from where it has been read; return from
this procedure must be with retf.
 
;------------------------------------------
; System directory information from loader
;------------------------------------------
Before transfer of control to the kernel following registers can be set:
CX = 'HA'
DX = 'RD'
This indicates that the register BX identifies system partition. The folder /kolibri/ in
this partition is system folder, it can be referenced as /sys/
 
Possible values for register BL (indicates the device):
'a' - Primary Master
'b' - Primary Slave
'c' - Secondary Master
'd' - Secondary Slave
'r' - RAM disc
'm' - ROM drives
 
Possible values for register BH (indicates section):
for BL = 'a', 'b', 'c', 'd', 'r' to denote partition where the system folder
for BL = 'm', indicates the number of physical devices, which must begin a systematic search directory.
 
Examples of register BX:
'a1' - /hd0/1/
'a2' - /hd0/2/
'b1' - /hd1/1/
'd4' - /hd3/4/
'm0' - search directory 'kolibri' by all CD-ROMs
'r1' - /rd/1/
/kernel/branches/Kolibri-acpi/docs/apm.txt
0,0 → 1,518
--------p-155300-----------------------------
INT 15 - Advanced Power Management v1.0+ - INSTALLATION CHECK
AX = 5300h
BX = device ID of system BIOS (0000h)
Return: CF clear if successful
AH = major version (BCD)
AL = minor version (BCD)
BX = 504Dh ("PM")
CX = flags (see #00472)
CF set on error
AH = error code (06h,09h,86h) (see #00473)
BUG: early versions of the Award Modular BIOS with built-in APM support
reportedly do not set BX on return
 
Bitfields for APM flags:
Bit(s) Description (Table 00472)
0 16-bit protected mode interface supported
1 32-bit protected mode interface supported
2 CPU idle call reduces processor speed
3 BIOS power management disabled
4 BIOS power management disengaged (APM v1.1)
5-7 reserved
 
(Table 00473)
Values for APM error code:
01h power management functionality disabled
02h interface connection already in effect
03h interface not connected
04h real-mode interface not connected
05h 16-bit protected-mode interface already connected
06h 16-bit protected-mode interface not supported
07h 32-bit protected-mode interface already connected
08h 32-bit protected-mode interface not supported
09h unrecognized device ID
0Ah invalid parameter value in CX
0Bh (APM v1.1) interface not engaged
0Ch (APM v1.2) function not supported
0Dh (APM v1.2) Resume Timer disabled
0Eh-1Fh reserved for other interface and general errors
20h-3Fh reserved for CPU errors
40h-5Fh reserved for device errors
60h can't enter requested state
61h-7Fh reserved for other system errors
80h no power management events pending
81h-85h reserved for other power management event errors
86h APM not present
87h-9Fh reserved for other power management event errors
A0h-FEh reserved
FFh undefined
--------p-155301-----------------------------
INT 15 - Advanced Power Management v1.0+ - CONNECT REAL-MODE INTERFACE
AX = 5301h
BX = device ID of system BIOS (0000h)
Return: CF clear if successful
CF set on error
AH = error code (02h,05h,07h,09h) (see #00473)
Note: on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0
compatibility mode until it is informed that the user supports a
newer version of APM (see AX=530Eh)
SeeAlso: AX=5302h,AX=5303h,AX=5304h
--------p-155302-----------------------------
INT 15 R - Advanced Power Management v1.0+ - CONNECT 16-BIT PROTMODE INTERFACE
AX = 5302h
BX = device ID of system BIOS (0000h)
Return: CF clear if successful
AX = real-mode segment base address of protected-mode 16-bit code
segment
BX = offset of entry point
CX = real-mode segment base address of protected-mode 16-bit data
segment
---APM v1.1---
SI = APM BIOS code segment length
DI = APM BIOS data segment length
CF set on error
AH = error code (02h,05h,06h,07h,09h) (see #00473)
Notes: the caller must initialize two consecutive descriptors with the
returned segment base addresses; these descriptors must be valid
whenever the protected-mode interface is called, and will have
their limits arbitrarily set to 64K.
the protected mode interface is invoked by making a far call with the
same register values as for INT 15; it must be invoked while CPL=0,
the code segment descriptor must have a DPL of 0, the stack must be
in a 16-bit segment and have enough room for BIOS use and possible
interrupts, and the current I/O permission bit map must allow access
to the I/O ports used for power management.
functions 00h-03h are not available from protected mode
on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0
compatibility mode until it is informed that the user supports a
newer version of APM (see AX=530Eh)
SeeAlso: AX=5301h,AX=5303h,AX=5304h
--------p-155303-----------------------------
INT 15 - Advanced Power Management v1.0+ - CONNECT 32-BIT PROTMODE INTERFACE
AX = 5303h
BX = device ID of system BIOS (0000h)
Return: CF clear if successful
AX = real-mode segment base address of protected-mode 32-bit code
segment
EBX = offset of entry point
CX = real-mode segment base address of protected-mode 16-bit code
segment
DX = real-mode segment base address of protected-mode 16-bit data
segment
---APM v1.1---
SI = APM BIOS code segment length
DI = APM BIOS data segment length
CF set on error
AH = error code (02h,05h,07h,08h,09h) (see #00473)
Notes: the caller must initialize three consecutive descriptors with the
returned segment base addresses for 32-bit code, 16-bit code, and
16-bit data, respectively; these descriptors must be valid whenever
the protected-mode interface is called, and will have their limits
arbitrarily set to 64K.
the protected mode interface is invoked by making a far call to the
32-bit code segment with the same register values as for INT 15; it
must be invoked while CPL=0, the code segment descriptor must have a
DPL of 0, the stack must be in a 32-bit segment and have enough room
for BIOS use and possible interrupts, and the current I/O permission
bit map must allow access to the I/O ports used for power management.
functions 00h-03h are not available from protected mode
on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0
compatibility mode until it is informed that the user supports a
newer version of APM (see AX=530Eh)
SeeAlso: AX=5301h,AX=5302h,AX=5304h
--------p-155304-----------------------------
INT 15 - Advanced Power Management v1.0+ - DISCONNECT INTERFACE
AX = 5304h
BX = device ID of system BIOS (0000h)
Return: CF clear if successful
CF set on error
AH = error code (03h,09h) (see #00473)
SeeAlso: AX=5301h,AX=5302h,AX=5303h
--------p-155305-----------------------------
INT 15 - Advanced Power Management v1.0+ - CPU IDLE
AX = 5305h
Return: CF clear if successful (after system leaves idle state)
CF set on error
AH = error code (03h,0Bh) (see #00473)
Notes: call when the system is idle and should be suspended until the next
system event or interrupt
should not be called from within a hardware interrupt handler to avoid
reentrance problems
if an interrupt causes the system to resume normal processing, the
interrupt may or may not have been handled when the BIOS returns
from this call; thus, the caller should allow interrupts on return
interrupt handlers may not retain control if the BIOS allows
interrupts while in idle mode even if they are able to determine
that they were called from idle mode
the caller should issue this call continuously in a loop until it needs
to perform some processing of its own
SeeAlso: AX=1000h,AX=5306h,INT 2F/AX=1680h
--------p-155306-----------------------------
INT 15 - Advanced Power Management v1.0+ - CPU BUSY
AX = 5306h
Return: CF clear if successful
CF set on error
AH = error code (03h,0Bh) (see #00473)
Notes: called to ensure that the system runs at full speed even on systems
where the BIOS is unable to recognize increased activity (especially
if interrupts are hooked by other programs and not chained to the
BIOS)
this call may be made even when the system is already running at full
speed, but it will create unnecessary overhead
should not be called from within a hardware interrupt handler to avoid
reentrance problems
SeeAlso: AX=5305h
--------p-155307-----------------------------
INT 15 - Advanced Power Management v1.0+ - SET POWER STATE
AX = 5307h
BX = device ID (see #00474)
CX = system state ID (see #00475)
Return: CF clear if successful
CF set on error
AH = error code (01h,03h,09h,0Ah,0Bh,60h) (see #00473)
Note: should not be called from within a hardware interrupt handler to avoid
reentrance problems
SeeAlso: AX=530Ch
 
(Table 00474)
Values for APM device IDs:
0000h system BIOS
0001h all devices for which the system BIOS manages power
01xxh display (01FFh for all attached display devices)
02xxh secondary storage (02FFh for all attached secondary storage devices)
03xxh parallel ports (03FFh for all attached parallel ports)
04xxh serial ports (04FFh for all attached serial ports)
---APM v1.1+ ---
05xxh network adapters (05FFh for all attached network adapters)
06xxh PCMCIA sockets (06FFh for all)
0700h-7FFFh reserved
80xxh system battery devices (APM v1.2)
8100h-DFFFh reserved
Exxxh OEM-defined power device IDs
F000h-FFFFh reserved
 
(Table 00475)
Values for system state ID:
0000h ready (not supported for device ID 0001h)
0001h stand-by
0002h suspend
0003h off (not supported for device ID 0001h in APM v1.0)
---APM v1.1---
0004h last request processing notification (only for device ID 0001h)
0005h last request rejected (only for device ID 0001h)
0006h-001Fh reserved system states
0020h-003Fh OEM-defined system states
0040h-007Fh OEM-defined device states
0080h-FFFFh reserved device states
--------p-155307CX0001-----------------------
INT 15 - Advanced Power Management v1.0+ - SYSTEM STAND-BY
AX = 5307h
CX = 0001h
BX = 0001h (device ID for all power-managed devices)
Return: CF clear
Notes: puts the entire system into stand-by mode; normally called in response
to a System Stand-by Request notification after any necessary
processing, but may also be invoked at the caller's discretion
should not be called from within a hardware interrupt handler to avoid
reentrance problems
the stand-by state is typically exited on an interrupt
SeeAlso: AX=4280h,AX=5307h/CX=0002h"SUSPEND",AX=5307h/CX=0003h,AX=530Bh
--------p-155307CX0002-----------------------
INT 15 - Advanced Power Management v1.0+ - SUSPEND SYSTEM
AX = 5307h
CX = 0002h
BX = 0001h (device ID for all power-managed devices)
Return: after system is resumed
CF clear
Notes: puts the entire system into a low-power suspended state; normally
called in response to a Suspend System Request notification after
any necessary processing, but may also be invoked at the caller's
discretion
should not be called from within a hardware interrupt handler to avoid
reentrance problems
the caller may need to update its date and time values because the
system could have been suspended for a long period of time
SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh
--------p-155307CX0003-----------------------
INT 15 - Advanced Power Management v1.2 - TURN OFF SYSTEM
AX = 5307h
CX = 0003h
BX = 0001h (device ID for all power-managed devices)
Return: after system is resumed
CF clear
Notes: if supported by the system's power supply, turns off the system power
SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh
--------p-155308-----------------------------
INT 15 - Advanced Power Management v1.0+ - ENABLE/DISABLE POWER MANAGEMENT
AX = 5308h
BX = device ID for all devices power-managed by APM
0001h (APM v1.1+)
FFFFh (APM v1.0)
CX = new state
0000h disabled
0001h enabled
Return: CF clear if successful
CF set on error
AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473)
Notes: when power management is disabled, the system BIOS will not
automatically power down devices, enter stand-by or suspended mode,
or perform any power-saving actions in response to AX=5305h calls
should not be called from within a hardware interrupt handler to avoid
reentrance problems
the APM BIOS should never be both disabled and disengaged at the same
time
SeeAlso: AX=5309h,AX=530Dh,AX=530Fh
--------p-155309-----------------------------
INT 15 - Advanced Power Management v1.0+ - RESTORE POWER-ON DEFAULTS
AX = 5309h
BX = device ID for all devices power-managed by APM
0001h (APM v1.1)
FFFFh (APM v1.0)
Return: CF clear if successful
CF set on error
AH = error code (03h,09h,0Bh) (see #00473)
Note: should not be called from within a hardware interrupt handler to avoid
reentrance problems
SeeAlso: AX=5308h
--------p-15530A-----------------------------
INT 15 - Advanced Power Management v1.0+ - GET POWER STATUS
AX = 530Ah
BX = device ID
0001h all devices power-managed by APM
80xxh specific battery unit number XXh (01h-FFh) (APM v1.2)
Return: CF clear if successful
BH = AC line status
00h off-line
01h on-line
02h on backup power (APM v1.1)
FFh unknown
other reserved
BL = battery status (see #00476)
CH = battery flag (APM v1.1+) (see #00477)
CL = remaining battery life, percentage
00h-64h (0-100) percentage of full charge
FFh unknown
DX = remaining battery life, time (APM v1.1) (see #00478)
---if specific battery unit specified---
SI = number of battery units currently installed
CF set on error
AH = error code (09h,0Ah) (see #00473)
Notes: should not be called from within a hardware interrupt handler to avoid
reentrance problems
supported in real mode (INT 15) and both 16-bit and 32-bit protected
mode
 
(Table 00476)
Values for APM v1.0+ battery status:
00h high
01h low
02h critical
03h charging
FFh unknown
other reserved
SeeAlso: #00477,#00478
 
Bitfields for APM v1.1+ battery flag:
Bit(s) Description (Table 00477)
0 high
1 low
2 critical
3 charging
4 selected battery not present (APM v1.2)
5-6 reserved (0)
7 no system battery
Note: all bits set (FFh) if unknown
SeeAlso: #00476,#00478
 
Bitfields for APM v1.1+ remaining battery life:
Bit(s) Description (Table 00478)
15 time units: 0=seconds, 1=minutes
14-0 battery life in minutes or seconds
Note: all bits set (FFFFh) if unknown
SeeAlso: #00476,#00477
--------p-15530B-----------------------------
INT 15 - Advanced Power Management v1.0+ - GET POWER MANAGEMENT EVENT
AX = 530Bh
Return: CF clear if successful
BX = event code (see #00479)
CX = event information (APM v1.2) if BX=0003h or BX=0004h
bit 0: PCMCIA socket was powered down in suspend state
CF set on error
AH = error code (03h,0Bh,80h) (see #00473)
Notes: although power management events are often asynchronous, notification
will not be made until polled via this call to permit software to
only receive event notification when it is prepared to process
power management events; since these events are not very time-
critical, it should be sufficient to poll once or twice per second
the critical resume notification is made after the system resumes
from an emergency suspension; normally, the system BIOS only notifies
its partner that it wishes to suspend and relies on the partner to
actually request the suspension, but no notification is made on an
emergency suspension
should not be called from within a hardware interrupt handler to avoid
reentrance problems
SeeAlso: AX=5307h,AX=5307h/CX=0001h"STAND-BY",AX=5307h/CX=0002h"SUSPEND"
 
(Table 00479)
Values for APM event code:
0001h system stand-by request
0002h system suspend request
0003h normal resume system notification
0004h critical resume system notification
0005h battery low notification
---APM v1.1---
0006h power status change notification
0007h update time notification
0008h critical system suspend notification
0009h user system standby request notification
000Ah user system suspend request notification
000Bh system standby resume notification
---APM v1.2---
000Ch capabilities change notification (see AX=5310h)
------
000Dh-00FFh reserved system events
01xxh reserved device events
02xxh OEM-defined APM events
0300h-FFFFh reserved
--------p-15530C-----------------------------
INT 15 - Advanced Power Management v1.1+ - GET POWER STATE
AX = 530Ch
BX = device ID (see #00474)
Return: CF clear if successful
CX = system state ID (see #00475)
CF set on error
AH = error code (01h,09h) (see #00473)
SeeAlso: AX=5307h
--------p-15530D-----------------------------
INT 15 - Advanced Power Management v1.1+ - EN/DISABLE DEVICE POWER MANAGEMENT
AX = 530Dh
BX = device ID (see #00474)
CX = function
0000h disable power management
0001h enable power management
Return: CF clear if successful
CF set on error
AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473)
Desc: specify whether automatic power management should be active for a
given device
SeeAlso: AX=5308h,AX=530Fh
--------p-15530E-----------------------------
INT 15 - Advanced Power Management v1.1+ - DRIVER VERSION
AX = 530Eh
BX = device ID of system BIOS (0000h)
CH = APM driver major version (BCD)
CL = APM driver minor version (BCD) (02h for APM v1.2)
Return: CF clear if successful
AH = APM connection major version (BCD)
AL = APM connection minor version (BCD)
CF set on error
AH = error code (03h,09h,0Bh) (see #00473)
SeeAlso: AX=5300h,AX=5303h
--------p-15530F-----------------------------
INT 15 - Advanced Power Management v1.1+ - ENGAGE/DISENGAGE POWER MANAGEMENT
AX = 530Fh
BX = device ID (see #00474)
CX = function
0000h disengage power management
0001h engage power management
Return: CF clear if successful
CF set on error
AH = error code (01h,09h) (see #00473)
Notes: unlike AX=5308h, this call does not affect the functioning of the APM
BIOS
when cooperative power management is disengaged, the APM BIOS performs
automatic power management of the system or device
SeeAlso: AX=5308h,AX=530Dh
--------p-155310-----------------------------
INT 15 - Advanced Power Management v1.2 - GET CAPABILITIES
AX = 5310h
BX = device ID (see #00474)
0000h (APM BIOS)
other reserved
Return: CF clear if successful
BL = number of battery units supported (00h if no system batteries)
CX = capabilities flags (see #00480)
CF set on error
AH = error code (01h,09h,86h) (see #00473)
Notes: this function is supported via the INT 15, 16-bit protected mode, and
32-bit protected mode interfaces; it does not require that a
connection be established prior to use
this function will return the capabilities currently in effect, not
any new settings which have been made but do not take effect until
a system restart
SeeAlso: AX=5300h,AX=530Fh,AX=5311h,AX=5312h,AX=5313h
 
Bitfields for APM v1.2 capabilities flags:
Bit(s) Description (Table 00480)
15-8 reserved
7 PCMCIA Ring Indicator will wake up system from suspend mode
6 PCMCIA Ring Indicator will wake up system from standby mode
5 Resume on Ring Indicator will wake up system from suspend mode
4 Resume on Ring Indicator will wake up system from standby mode
3 resume timer will wake up system from suspend mode
2 resume timer will wake up system from standby mode
1 can enter global suspend state
0 can enter global standby state
--------p-155311-----------------------------
INT 15 - Advanced Power Management v1.2 - GET/SET/DISABLE RESUME TIMER
AX = 5311h
BX = device ID (see #00474)
0000h (APM BIOS)
other reserved
CL = function
00h disable Resume Timer
01h get Resume Timer
02h set Resume Timer
CH = resume time, seconds (BCD)
DL = resume time, minutes (BCD)
DH = resume time, hours (BCD)
SI = resume date (BCD), high byte = month, low byte = day
DI = resume date, year (BCD)
Return: CF clear if successful
---if getting timer---
CH = resume time, seconds (BCD)
DL = resume time, minutes (BCD)
DH = resume time, hours (BCD)
SI = resume date (BCD), high byte = month, low byte = day
DI = resume date, year (BCD)
CF set on error
AH = error code (03h,09h,0Ah,0Bh,0Ch,0Dh,86h) (see #00473)
Notes: this function is supported via the INT 15, 16-bit protected mode, and
32-bit protected mode interfaces
SeeAlso: AX=5300h,AX=5310h,AX=5312h,AX=5313h
--------p-155312-----------------------------
INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE RESUME ON RING
AX = 5312h
BX = device ID (see #00474)
0000h (APM BIOS)
other reserved
CL = function
00h disable Resume on Ring Indicator
01h enable Resume on Ring Indicator
02h get Resume on Ring Indicator status
Return: CF clear if successful
CX = resume status (0000h disabled, 0001h enabled)
CF set on error
AH = error code (03h,09h,0Ah,0Bh,0Ch,86h) (see #00473)
Notes: this function is supported via the INT 15, 16-bit protected mode, and
32-bit protected mode interfaces
SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5313h
--------p-155313-----------------------------
INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE TIMER-BASED REQUESTS
AX = 5313h
BX = device ID (see #00474)
0000h (APM BIOS)
other reserved
CL = function
00h disable timer-based requests
01h enable timer-based requests
02h get timer-based requests status
Return: CF clear if successful
CX = timer-based requests status (0000h disabled, 0001h enabled)
CF set on error
AH = error code (03h,09h,0Ah,0Bh,86h) (see #00473)
Notes: this function is supported via the INT 15, 16-bit protected mode, and
32-bit protected mode interfaces
some BIOSes set AH on return even when successful
SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5312h
/kernel/branches/Kolibri-acpi/docs
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/memmap.inc
0,0 → 1,264
;
; MEMORY MAP
;
; Boot:
;
; 0:9000 byte bits per pixel
; 0:9001 word scanline length
; 0:9008 word vesa video mode
; 0:900A word X res
; 0:900C word Y res
; 0:9010 byte mouse port - not used
; 0:9014 dword Vesa 1.2 pm bank switch
; 0:9018 dword Vesa 2.0 LFB address
; 0:901C byte 0 or 1 : enable MTRR graphics acceleration
; 0:901D byte not used anymore (0 or 1 : enable system log display)
; 0:901E byte 0 or 1 : enable direct lfb write, paging disabled
; 0:901F byte DMA write : 1=yes, 2=no
; 0:9020 8bytes pci data
; 0:9030 byte VRR start enabled 1, 2-no
; 0:9031 word IDEContrRegsBaseAddr
; 0x9040 - dword - entry point of APM BIOS
; 0x9044 - word - version (BCD)
; 0x9046 - word - flags
; 0:907F byte number of BIOS hard disks
; 0:9080 Nbytes BIOS hard disks
; 0:9100 word available physical memory map: number of blocks
; 0:9104 available physical memory map: blocks
;
; Runtime:
;
; 0x00000000 -> 0x7FFFFFFF application 2Gb
 
; 0x80000000 -> 0FFF physical page zero - do not write
; (used by int 13h in some configurations)
;
; 0x80001000 -> 2FFF window_data - 256 entries
;
; 0000 dword x start
; 0004 dword y start
; 0008 dword x size
; 000C dword y size
; 0010 dword color of work area
; 0014 dword color of grab bar
; 0018 dword color of frames
; 001C dword window flags, +30 = window drawn, +31 redraw flag
;
; 3000 -> 4FFF task list - 256 entries
;
; 00 dword process count
; 04 dword no of processes
; 10 dword base of running process at 0x3000+
;
; 20 dword application event mask
; 24 dword PID - process identification number
; 2a byte slot state: 0=running, 1,2=suspended
; 3=zombie, 4=terminate,
; 5=waiting for event, 9 = not used
; 2e byte window number on screen
; 30 dword exact position in memory
; 34 dword counter sum
; 38 dword time stamp counter add
; 3c dword cpu usage in cpu timer tics
;
;
; 5000 -> 68FF free (6k6)
; 6900 -> 6EFF saved picture under mouse pointer (1k5)
;
; 6F00 -> 6FFF free (256)
;
; 7000 -> 7FFF used CD driver
;
; 8000 -> A3FF used FLOPPY driver
;
; A400 -> B0FF free (3k3), unused ACTIVE_PROC_STACK
 
; B100 -> B307 IDT for int_0x00..int_0x40
 
; B308 -> BFFF free (3k3)
 
; C000 -> C3FF window stack C000 no of windows - all in words
; C402 -> C7FF window position in stack
; D000 -> D1FF FDC controller
; D200 -> D3FF FDC controller for Fat12
; D400 -> DFFF free (3k)
; E000 byte multitasking started
; E020 dword putpixel address
; E024 dword getpixel address
; E030 dword Vesa 1.2 pm bank switch address
; E034 -> F1FF free (4k5)
; F200 dword mousepicture -pointer
; F204 dword mouse appearance counter
; F208 -> F2FF free (248)
; F300 dword x & y temp for windowmove
; F304 -> F3FF free (252)
; F400 byte no of keys in buffer
; F401 byte 'buffer'
; F402 -> F4FF reserved for keys
; F500 byte no of buttons in buffer
; F501 dword 'buffer'
; F502 -> F5FF reserved for buttons
; F600 dword tsc / second
; F604 byte (unused?) mouse port: 1 ps2, 2 com1, 3 com2
; F605 -> FAFF free (1k2)
; FB00 -> FB0F mouse memory 00 chunk count, that includes:
; FB08 word -- mouse H-scroll
; FB0A word -- mouse x
; FB0C word -- mouse y
; FB0E word -- mouse V-scroll
; FB10 -> FB17 mouse color mem
; FB21 x move
; FB22 y move
; FB28 high bits temp
; FB30 color temp
; FB40 byte buttons down
; FB44 byte 0 mouse down -> do not draw
; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under
; FBF1 byte bits per pixel
; FC00 -> FCFE com1/ps2 buffer
; FCFF com1/ps2 buffer count starting from FC00
; FD00 -> FDFF free (256)
; FE00 dword screen x size
; FE04 dword screen y size
; FE08 dword screen y multiplier
; FE0C dword screen mode
; FE10 -> FE7F free (112)
; FE80 dword address of LFB in physical
; FE84 dword address of applications memory start in physical ?
; FE88 dword address of button list
; FE8C dword memory to use
; FE90 -> FEFF free (112)
; FF00 byte 1 = system shutdown request
; FF01 byte task activation request?
; FFF0 byte >0 if redraw background request from app
; FFF1 byte >0 if background changed
; FFF2 write and read bank in screen
; FFF4 byte 0 if first mouse draw & do not return picture under
; FFF5 byte 1 do not draw pointer
; FFFF byte do not change task for 1/100 sec.
;
; 0x80010000 -> 6CBFF kernel, 32-bit run-time code (up to 371 Kb)
 
; 0x8006CC00 -> 6DBFF stack at boot time (4Kb)
;
; 0x8006DC00 -> 6E5FF basic text font II
; 0x8006E600 -> 6Efff basic text font I
; 0x8006F000 -> 6FFFF main page directory
 
; 0x80070000 -> 7FFFF data of retrieved disks and partitions (Mario79)
; 0x80080000 -> 8FFFF additional app info, in 256 byte steps - 256 entries
;
; 00 11db name of app running
; 0x10 dword pointer to fpu save area
; 0x14 dword event count
; 0x18 dword user fpu exceptoins handler
; 0x1c dword user sse exceptions handler
; 20 dword PL0 stack base
; 24 dword user heap base
; 28 dword user heap top
; 2c dword window cursor handle
; 30 dword first event in list
; 34 dword last event in list
; 38 dword first kernel object in list
; 3c dword last kernel object in list
; 40 dword thread esp
; 44 dword io permission map page 0
; 48 dword io permission map page 1
; 4c dword debug state: 1= load debug registers
; 50 dword current directory ptr
; 54 dword wait timeout
; 58 dword thread TSS._esp0 (= pl0 stack base + size except for V86)
; 5C-7F unused
;
; 80 dword address of random shaped window area
; 84 byte shape area scale
; 88 dword free
; 8C dword application memory size
; 90 dword window X position save
; 94 dword window Y position save
; 98 dword window X size save
; 9C dword window Y size save
; A0 dword IPC memory start
; A4 dword IPC memory size
; A8 dword event bits: mouse, stack,..
; AC dword 0 or debugger slot
; B0 dword free
; B4 byte keyboard mode: 0 = keymap, 1 = scancodes
; B8 dword physical address of directory table
; BC dword address of debug event memory
; C0 5 dd thread debug registers: DR0,DR1,DR2,DR3,DR7
;
; 0x80090000 -> 9FFFF tmp (64k) - unused?
; 0x800A0000 -> AFFFF screen access area
; 0x800B0000 -> FFFFF bios rest in peace -area (320k) ?
; 0x80100000 -> 27FFFF diskette image (1m5)
; 0x80280000 -> 281FFF ramdisk fat (8k)
; 0x80282000 -> 283FFF floppy fat (8k)
;
; 0x80284000 -> 28BFFF HDD DMA AREA (32k)
; 0x8028C000 -> 297FFF free (48k)
;
; 0x80298000 -> 29ffff auxiliary table for background smoothing code (32k)
;
; 0x802A0000 -> 2B00ff wav device buffer (64k)
; 0x802A0000 -> 2B00ff wav device status (256)
; 0x802B0100 -> 2Bffff free (63k8)
; 0x802C0000 -> 2C3fff button info (8k)
;
; 0000 word number of buttons
; first button entry at 0x10
; +0000 word process number
; +0002 word button id number : bits 00-15
; +0004 word x start
; +0006 word x size
; +0008 word y start
; +000A word y size
; +000C word button id number : bits 16-31
;
; 0x802C4000 -> 2CFFFF free (48k)
;
; 0x802D0000 -> 2DFFFF reserved port area (64k)
;
; 0000 dword no of port areas reserved
; 0010 dword process id
; dword start port
; dword end port
; dword 0
;
; 0x802E0000 -> 2EFFFF irq data area (64k)
; 0x802F0000 -> 2FFFFF low memory save (64k)
;
; 0x80300000 -> 31FFFF tcp memory (128k)
; 0x80320000 -> 327FFF tcp memory (32k)
;
; 0x80328000 -> 32FFFF !vrr driver (32k)
 
; 0x80330000 -> 377FFF skin data (32k)
 
; 0x80338000 -> 338FFF draw data - 256 entries (4k)
; 00 dword draw limit - x start
; 04 dword draw limit - y start
; 08 dword draw limit - x end
; 0C dword draw limit - y end
; 0x80339000 -> 3BFFF3 free (12k)
; 0x8033BFF4 -> 33BFFF background info
; 0x8033C000 page map (length b = memsize shr 15)
; 0x8033C000 + b start of static pagetables
 
; 0x803FFFFF <- no direct address translation beyond this point
; =============================================================
 
; 0x805FF000 -> 5FFF80 TSS
; 0x80600000 -> 601FFF i/o maps
 
; 0x80800000 -> kernel heap
; 0x80FFFFFF heap min limit
; 0xFDBFFFFF heap max limit
 
; 0xF0000000 -> 0xF1FFFFFF PCI-express extended config space
; 0xFDC00000 -> 0xFDFFFFFF page tables 4Mb
; 0xFE000000 -> 0xFFFFFFFF LFB 32Mb
; 0xFE000000 -> 0xFE7FFFFF application available LFB 8Mb
; 0xFE800000 -> 0xFFFFFFFF kernel LFB part 24 Mb
 
 
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/init.inc
0,0 → 1,435
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
MEM_WB equ 6 ;write-back memory
MEM_WC equ 1 ;write combined memory
MEM_UC equ 0 ;uncached memory
 
align 4
proc mem_test
; if we have BIOS with fn E820, skip the test
cmp dword [BOOT_VAR-OS_BASE + 0x9100], 0
jnz .ret
 
mov eax, cr0
and eax, not (CR0_CD+CR0_NW)
or eax, CR0_CD ;disable caching
mov cr0, eax
wbinvd ;invalidate cache
 
xor edi, edi
mov ebx, 'TEST'
@@:
add edi, 0x100000
xchg ebx, dword [edi]
cmp dword [edi], 'TEST'
xchg ebx, dword [edi]
je @b
 
and eax, not (CR0_CD+CR0_NW) ;enable caching
mov cr0, eax
inc dword [BOOT_VAR-OS_BASE + 0x9100]
xor eax, eax
mov [BOOT_VAR-OS_BASE + 0x9104], eax
mov [BOOT_VAR-OS_BASE + 0x9108], eax
mov [BOOT_VAR-OS_BASE + 0x910C], edi
mov [BOOT_VAR-OS_BASE + 0x9110], eax
.ret:
ret
endp
 
align 4
proc init_mem
; calculate maximum allocatable address and number of allocatable pages
mov edi, BOOT_VAR-OS_BASE + 0x9104
mov ecx, [edi-4]
xor esi, esi ; esi will hold total amount of memory
xor edx, edx ; edx will hold maximum allocatable address
.calcmax:
; round all to pages
mov eax, [edi]
test eax, 0xFFF
jz @f
neg eax
and eax, 0xFFF
add [edi], eax
adc dword [edi+4], 0
sub [edi+8], eax
sbb dword [edi+12], 0
jc .unusable
@@:
and dword [edi+8], not 0xFFF
jz .unusable
; ignore memory after 4 Gb
cmp dword [edi+4], 0
jnz .unusable
mov eax, [edi]
cmp dword [edi+12], 0
jnz .overflow
add eax, [edi+8]
jnc @f
.overflow:
mov eax, 0xFFFFF000
@@:
cmp edx, eax
jae @f
mov edx, eax
@@:
sub eax, [edi]
mov [edi+8], eax
add esi, eax
jmp .usable
.unusable:
and dword [edi+8], 0
.usable:
add edi, 20
loop .calcmax
.calculated:
mov [MEM_AMOUNT-OS_BASE], esi
mov [pg_data.mem_amount-OS_BASE], esi
shr esi, 12
mov [pg_data.pages_count-OS_BASE], esi
 
shr edx, 12
add edx, 31
and edx, not 31
shr edx, 3
mov [pg_data.pagemap_size-OS_BASE], edx
 
add edx, (sys_pgmap-OS_BASE)+4095
and edx, not 4095
mov [tmp_page_tabs], edx
 
mov edx, esi
and edx, -1024
cmp edx, (OS_BASE/4096)
jbe @F
mov edx, (OS_BASE/4096)
jmp .set
@@:
cmp edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
jae .set
mov edx, (HEAP_BASE-OS_BASE+HEAP_MIN_SIZE)/4096
.set:
mov [pg_data.kernel_pages-OS_BASE], edx
shr edx, 10
mov [pg_data.kernel_tables-OS_BASE], edx
 
xor eax, eax
mov edi, sys_pgdir-OS_BASE
mov ecx, 4096/4
cld
rep stosd
 
mov edx, (sys_pgdir-OS_BASE)+ 0x800; (OS_BASE shr 20)
bt [cpu_caps-OS_BASE], CAPS_PSE
jnc .no_PSE
 
mov ebx, cr4
or ebx, CR4_PSE
mov eax, PG_LARGE+PG_SW
mov cr4, ebx
dec [pg_data.kernel_tables-OS_BASE]
 
mov [edx], eax
add edx, 4
 
mov edi, [tmp_page_tabs]
jmp .map_kernel_heap ; new kernel fits to the first 4Mb - nothing to do with ".map_low"
.no_PSE:
mov eax, PG_SW
mov ecx, [tmp_page_tabs]
shr ecx, 12
.map_low:
mov edi, [tmp_page_tabs]
@@: ;
stosd
add eax, 0x1000
dec ecx
jnz @B
 
.map_kernel_heap:
mov ecx, [pg_data.kernel_tables-OS_BASE]
shl ecx, 10
xor eax, eax
rep stosd
 
mov ecx, [pg_data.kernel_tables-OS_BASE]
mov eax, [tmp_page_tabs]
or eax, PG_SW
mov edi, edx
.map_kernel_tabs:
stosd
add eax, 0x1000
dec ecx
jnz .map_kernel_tabs
 
mov dword [sys_pgdir-OS_BASE+(page_tabs shr 20)], sys_pgdir+PG_SW-OS_BASE
 
mov edi, (sys_pgdir-OS_BASE)
lea esi, [edi+(OS_BASE shr 20)]
movsd
movsd
ret
endp
 
align 4
proc init_page_map
; mark all memory as unavailable
mov edi, sys_pgmap-OS_BASE
mov ecx, [pg_data.pagemap_size-OS_BASE]
shr ecx, 2
xor eax, eax
cld
rep stosd
 
; scan through memory map and mark free areas as available
mov ebx, BOOT_VAR-OS_BASE + 0x9104
mov edx, [ebx-4]
.scanmap:
mov ecx, [ebx+8]
shr ecx, 12 ; ecx = number of pages
jz .next
mov edi, [ebx]
shr edi, 12 ; edi = first page
mov eax, edi
shr edi, 5
shl edi, 2
add edi, sys_pgmap-OS_BASE
and eax, 31
jz .startok
add ecx, eax
sub ecx, 32
jbe .onedword
push ecx
mov ecx, eax
or eax, -1
shl eax, cl
or [edi], eax
add edi, 4
pop ecx
.startok:
push ecx
shr ecx, 5
or eax, -1
rep stosd
pop ecx
and ecx, 31
neg eax
shl eax, cl
dec eax
or [edi], eax
jmp .next
.onedword:
add ecx, 32
sub ecx, eax
@@:
bts [edi], eax
inc eax
loop @b
.next:
add ebx, 20
dec edx
jnz .scanmap
 
; mark kernel memory as allocated (unavailable)
mov ecx, [tmp_page_tabs]
mov edx, [pg_data.pages_count-OS_BASE]
shr ecx, 12
add ecx, [pg_data.kernel_tables-OS_BASE]
sub edx, ecx
mov [pg_data.pages_free-OS_BASE], edx
 
mov edi, sys_pgmap-OS_BASE
mov ebx, ecx
shr ecx, 5
xor eax, eax
rep stosd
 
not eax
mov ecx, ebx
and ecx, 31
shl eax, cl
and [edi], eax
add edi, OS_BASE
mov [page_start-OS_BASE], edi;
 
mov ebx, sys_pgmap
add ebx, [pg_data.pagemap_size-OS_BASE]
mov [page_end-OS_BASE], ebx
 
mov [pg_data.pg_mutex-OS_BASE], 0
ret
endp
 
align 4
 
init_BIOS32:
mov edi, 0xE0000
.pcibios_nxt:
cmp dword[edi], '_32_' ; "magic" word
je .BIOS32_found
.pcibios_nxt2:
add edi, 0x10
cmp edi, 0xFFFF0
je .BIOS32_not_found
jmp .pcibios_nxt
.BIOS32_found: ; magic word found, check control summ
 
movzx ecx, byte[edi + 9]
shl ecx, 4
mov esi, edi
xor eax, eax
cld ; paranoia
@@: lodsb
add ah, al
loop @b
jnz .pcibios_nxt2 ; control summ must be zero
; BIOS32 service found !
mov ebp, [edi + 4]
mov [bios32_entry], ebp
; check PCI BIOS present
mov eax, '$PCI'
xor ebx, ebx
push cs ; special for 'ret far' from BIOS
call ebp
test al, al
jnz .PCI_BIOS32_not_found
 
; çäåñü ñîçäàþòñÿ äèñêðèïòîðû äëÿ PCI BIOS
 
add ebx, OS_BASE
dec ecx
mov [(pci_code_32-OS_BASE)], cx ;limit 0-15
mov [(pci_data_32-OS_BASE)], cx ;limit 0-15
 
mov [(pci_code_32-OS_BASE)+2], bx ;base 0-15
mov [(pci_data_32-OS_BASE)+2], bx ;base 0-15
 
shr ebx, 16
mov [(pci_code_32-OS_BASE)+4], bl ;base 16-23
mov [(pci_data_32-OS_BASE)+4], bl ;base 16-23
 
shr ecx, 16
and cl, 0x0F
mov ch, bh
add cx, D32
mov [(pci_code_32-OS_BASE)+6], cx ;lim 16-19 &
mov [(pci_data_32-OS_BASE)+6], cx ;base 24-31
 
mov [(pci_bios_entry-OS_BASE)], edx
; jmp .end
.PCI_BIOS32_not_found:
; çäåñü äîëæíà çàïîëíÿòñÿ pci_emu_dat
.BIOS32_not_found:
.end:
ret
 
align 4
proc test_cpu
locals
cpu_type dd ?
cpu_id dd ?
cpu_Intel dd ?
cpu_AMD dd ?
endl
 
xor eax, eax
mov [cpu_type], eax
mov [cpu_caps-OS_BASE], eax
mov [cpu_caps+4-OS_BASE], eax
 
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_cpuid
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_cpuid
mov [cpu_id], 1
 
xor eax, eax
cpuid
 
mov [cpu_vendor-OS_BASE], ebx
mov [cpu_vendor+4-OS_BASE], edx
mov [cpu_vendor+8-OS_BASE], ecx
cmp ebx, dword [intel_str-OS_BASE]
jne .check_AMD
cmp edx, dword [intel_str+4-OS_BASE]
jne .check_AMD
cmp ecx, dword [intel_str+8-OS_BASE]
jne .check_AMD
mov [cpu_Intel], 1
cmp eax, 1
jl .end_cpuid
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE],ecx
 
shr eax, 8
and eax, 0x0f
ret
.end_cpuid:
mov eax, [cpu_type]
ret
 
.check_AMD:
cmp ebx, dword [AMD_str-OS_BASE]
jne .unknown
cmp edx, dword [AMD_str+4-OS_BASE]
jne .unknown
cmp ecx, dword [AMD_str+8-OS_BASE]
jne .unknown
mov [cpu_AMD], 1
cmp eax, 1
jl .unknown
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE],ecx
shr eax, 8
and eax, 0x0f
ret
.unknown:
mov eax, 1
cpuid
mov [cpu_sign-OS_BASE], eax
mov [cpu_info-OS_BASE], ebx
mov [cpu_caps-OS_BASE], edx
mov [cpu_caps+4-OS_BASE],ecx
shr eax, 8
and eax, 0x0f
ret
endp
 
 
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/const.inc
0,0 → 1,770
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
dpl0 equ 10010000b ; data read dpl0
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 ;
 
; CPU MSR names
MSR_SYSENTER_CS equ 0x174
MSR_SYSENTER_ESP equ 0x175
MSR_SYSENTER_EIP equ 0x176
MSR_AMD_EFER equ 0xC0000080 ; Extended Feature Enable Register
MSR_AMD_STAR equ 0xC0000081 ; SYSCALL/SYSRET Target Address Register
 
CR0_PE equ 0x00000001 ;protected mode
CR0_MP equ 0x00000002 ;monitor fpu
CR0_EM equ 0x00000004 ;fpu emulation
CR0_TS equ 0x00000008 ;task switch
CR0_ET equ 0x00000010 ;extension type hardcoded to 1
CR0_NE equ 0x00000020 ;numeric error
CR0_WP equ 0x00010000 ;write protect
CR0_AM equ 0x00040000 ;alignment check
CR0_NW equ 0x20000000 ;not write-through
CR0_CD equ 0x40000000 ;cache disable
CR0_PG equ 0x80000000 ;paging
 
 
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
 
SSE_IE equ 0x0001
SSE_DE equ 0x0002
SSE_ZE equ 0x0004
SSE_OE equ 0x0008
SSE_UE equ 0x0010
SSE_PE equ 0x0020
SSE_DAZ equ 0x0040
SSE_IM equ 0x0080
SSE_DM equ 0x0100
SSE_ZM equ 0x0200
SSE_OM equ 0x0400
SSE_UM equ 0x0800
SSE_PM equ 0x1000
SSE_FZ equ 0x8000
 
SSE_INIT equ (SSE_IM+SSE_DM+SSE_ZM+SSE_OM+SSE_UM+SSE_PM)
 
 
struc TSS
{
._back rw 2
._esp0 rd 1
._ss0 rw 2
._esp1 rd 1
._ss1 rw 2
._esp2 rd 1
._ss2 rw 2
._cr3 rd 1
._eip rd 1
._eflags rd 1
._eax rd 1
._ecx rd 1
._edx rd 1
._ebx rd 1
._esp rd 1
._ebp rd 1
._esi rd 1
._edi rd 1
._es rw 2
._cs rw 2
._ss rw 2
._ds rw 2
._fs rw 2
._gs rw 2
._ldt rw 2
._trap rw 1
._io rw 1
rb 24
._io_map_0 rb 4096
._io_map_1 rb 4096
}
 
virtual at 0
TSS TSS
end virtual
 
TSS_SIZE equ (128+8192)
 
OS_BASE equ 0x80000000
 
window_data equ (OS_BASE+0x0001000)
 
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)
 
mouseunder equ (OS_BASE+0x0006900)
CDDataBuf equ (OS_BASE+0x0007000)
FLOPPY_BUFF equ (OS_BASE+0x0008000)
ACTIVE_PROC_STACK equ (OS_BASE+0x000A400) ;unused
idts equ (OS_BASE+0x000B100)
WIN_STACK equ (OS_BASE+0x000C000)
WIN_POS equ (OS_BASE+0x000C400)
FDD_BUFF equ (OS_BASE+0x000D000)
 
;unused ? only one reference
ENABLE_TASKSWITCH equ (OS_BASE+0x000E000)
 
PUTPIXEL equ (OS_BASE+0x000E020)
GETPIXEL equ (OS_BASE+0x000E024)
 
;unused ? only one reference
BANK_SWITCH equ (OS_BASE+0x000E030)
 
;unused ? store mousepointer
MOUSE_PICTURE equ (OS_BASE+0x000F200)
 
MOUSE_VISIBLE equ (OS_BASE+0x000F204)
WIN_TEMP_XY 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)
 
CPU_FREQ equ (OS_BASE+0x000F600)
 
;unused ? no active references
MOUSE_PORT equ (OS_BASE+0x000F604)
 
;unused
PS2_CHUNK equ (OS_BASE+0x000FB00)
 
MOUSE_SCROLL_H equ (OS_BASE+0x000FB08)
MOUSE_X equ (OS_BASE+0x000FB0A)
MOUSE_Y equ (OS_BASE+0x000FB0C)
MOUSE_SCROLL_V equ (OS_BASE+0x000FB0E)
 
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)
 
;unused ? only one reference
MOUSE_BUFF_COUNT equ (OS_BASE+0x000FCFF)
 
Screen_Max_X equ (OS_BASE+0x000FE00)
Screen_Max_Y equ (OS_BASE+0x000FE04)
BytesPerScanLine equ (OS_BASE+0x000FE08)
SCR_MODE equ (OS_BASE+0x000FE0C)
 
LFBAddress equ (OS_BASE+0x000FE80)
BTN_ADDR equ (OS_BASE+0x000FE88)
MEM_AMOUNT equ (OS_BASE+0x000FE8C)
 
SYS_SHUTDOWN equ (OS_BASE+0x000FF00)
TASK_ACTIVATE equ (OS_BASE+0x000FF01)
 
REDRAW_BACKGROUND equ (OS_BASE+0x000FFF0)
BACKGROUND_CHANGED equ (OS_BASE+0x000FFF1)
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)
 
TMP_STACK_TOP equ 0x006CC00
 
FONT_II equ (OS_BASE+0x006DC00)
FONT_I equ (OS_BASE+0x006E600)
 
sys_pgdir equ (OS_BASE+0x006F000)
 
DRIVE_DATA equ (OS_BASE+0x0070000)
 
SLOT_BASE equ (OS_BASE+0x0080000)
 
;unused
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)
 
IDE_DMA equ 0x284000
 
BgrAuxTable equ (OS_BASE+0x0298000)
; unused?
SB16Buffer equ (OS_BASE+0x2A0000)
SB16_Status equ (OS_BASE+0x02B0000)
 
BUTTON_INFO equ (OS_BASE+0x02C0000)
RESERVED_PORTS equ (OS_BASE+0x02D0000)
IRQ_SAVE equ (OS_BASE+0x02E0000)
BOOT_VAR equ (OS_BASE+0x02f0000)
 
stack_data_start equ (OS_BASE+0x0300000)
eth_data_start equ (OS_BASE+0x0300000)
stack_data equ (OS_BASE+0x0304000)
stack_data_end equ (OS_BASE+0x031ffff)
resendQ equ (OS_BASE+0x0320000)
VMODE_BASE equ (OS_BASE+0x0328000)
skin_data equ (OS_BASE+0x0330000)
draw_data equ (OS_BASE+0x0338000);
 
BgrDrawMode equ (OS_BASE+0x033BFF4)
BgrDataWidth equ (OS_BASE+0x033BFF8)
BgrDataHeight equ (OS_BASE+0x033BFFC)
 
sys_pgmap equ (OS_BASE+0x033C000)
 
UPPER_KERNEL_PAGES equ (OS_BASE+0x0400000)
 
virtual at (OS_BASE+0x05FFF80)
tss TSS
end virtual
 
HEAP_BASE equ (OS_BASE+0x0800000)
HEAP_MIN_SIZE equ 0x01000000
 
page_tabs equ 0xFDC00000
app_page_tabs equ 0xFDC00000
kernel_tabs equ (page_tabs+ (OS_BASE shr 10)) ;0xFDE00000
master_tab equ (page_tabs+ (page_tabs shr 10)) ;0xFDFF70000
 
LFB_BASE equ 0xFE000000
 
 
new_app_base equ 0;
 
twdw equ 0x2000 ;(CURRENT_TASK-window_data)
 
std_application_base_address equ new_app_base
RING0_STACK_SIZE equ (0x2000 - 512) ;512 áàéò äëÿ êîíòåêñòà FPU
 
REG_SS equ (RING0_STACK_SIZE-4)
REG_APP_ESP equ (RING0_STACK_SIZE-8)
REG_EFLAGS equ (RING0_STACK_SIZE-12)
REG_CS equ (RING0_STACK_SIZE-16)
REG_EIP equ (RING0_STACK_SIZE-20)
REG_EAX equ (RING0_STACK_SIZE-24)
REG_ECX equ (RING0_STACK_SIZE-28)
REG_EDX equ (RING0_STACK_SIZE-32)
REG_EBX equ (RING0_STACK_SIZE-36)
REG_ESP equ (RING0_STACK_SIZE-40) ;RING0_STACK_SIZE-20
REG_EBP equ (RING0_STACK_SIZE-44)
REG_ESI equ (RING0_STACK_SIZE-48)
REG_EDI equ (RING0_STACK_SIZE-52)
REG_RET equ (RING0_STACK_SIZE-56) ;irq0.return
 
 
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
 
PG_SHARED equ 0x200
 
;;;;;;;;;;;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_EXTENDED equ 0x00000200
 
EV_INTR equ 1
 
struc THR_DATA
{
rb (8192-512)
.pl0_stack:
.fpu_state rb 512
.tls_page rb 4096
.pdbr rb 4096
}
 
THR_DATA_SIZE equ 4096*4
 
virtual at (OS_BASE-THR_DATA_SIZE)
thr_data THR_DATA
end virtual
 
struc SYS_VARS
{ .bpp dd ?
.scanline dd ?
.vesa_mode dd ?
.x_res dd ?
.y_res dd ?
}
 
struc APPOBJ ;common object header
{
.magic dd ? ;
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
};
 
virtual at 0
APPOBJ APPOBJ
end virtual
 
APP_OBJ_OFFSET equ 48
APP_EV_OFFSET equ 40
 
struc CURSOR
{
;common object header
.magic dd ? ;'CURS'
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
 
;cursor data
.base dd ? ;allocated memory
.hot_x dd ? ;hotspot coords
.hot_y dd ?
 
.list_next dd ? ;next cursor in cursor list
.list_prev dd ? ;prev cursor in cursor list
.dev_obj dd ? ;device depended data
 
.sizeof:
}
virtual at 0
CURSOR CURSOR
end virtual
 
 
struc EVENT
{
.magic dd ? ;'EVNT'
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
 
.id dd ? ;event uid
.state dd ? ;internal flags
.code dd ?
rd 5
.size = $ - .magic
.codesize = $ - .code
}
 
virtual at 0
EVENT EVENT
end virtual
 
 
struc SMEM
{
.bk dd ?
.fd dd ? ;+4
.base dd ? ;+8
.size dd ? ;+12
.access dd ? ;+16
.refcount dd ? ;+20
.name rb 32 ;+24
.sizeof:
}
 
struc SMAP
{
.magic dd ? ; SMAP
.destroy dd ? ;internal destructor
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
 
.base dd ? ;mapped base
.parent dd ? ;SMEM
.sizeof:
}
 
virtual at 0
SMEM SMEM
end virtual
 
virtual at 0
SMAP SMAP
end virtual
 
struc DLLDESCR
{
.bk dd ?
.fd dd ? ;+4
.data dd ? ;+8
.size dd ? ;+12
.timestamp dq ?
.refcount dd ?
.defaultbase dd ?
.coff_hdr dd ?
.symbols_ptr dd ?
.symbols_num dd ?
.symbols_lim dd ?
.exports dd ? ;export table
.name:
.sizeof:
}
 
struc HDLL
{
.fd dd ? ;next object in list
.bk dd ? ;prev object in list
.pid dd ? ;owner id
 
.base dd ? ;mapped base
.size dd ? ;mapped size
.refcount dd ? ;reference counter for this process and this lib
.parent dd ? ;DLLDESCR
.sizeof:
}
 
virtual at 0
DLLDESCR DLLDESCR
end virtual
 
virtual at 0
HDLL HDLL
end virtual
 
struc display_t
{
.x dd ?
.y dd ?
.width dd ?
.height dd ?
.bpp dd ?
.vrefresh dd ?
.pitch dd ?
.lfb dd ?
 
.modes dd ?
.ddev dd ?
.connector dd ?
.crtc dd ?
 
.cr_list.next dd ?
.cr_list.prev dd ?
 
.cursor dd ?
 
.init_cursor dd ?
.select_cursor dd ?
.show_cursor dd ?
.move_cursor dd ?
.restore_cursor dd ?
.disable_mouse dd ?
}
 
virtual at 0
display_t display_t
end virtual
 
struc HEAP_DATA
{
.mutex rd 1
.refcount rd 1
.heap_base rd 1
.heap_top rd 1
.app_mem rd 1
}
 
HEAP_DATA_SIZE equ 20
virtual at 0
HEAP_DATA HEAP_DATA
end virtual
 
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 MEM_STATE
{ .mutex rd 1
.smallmap rd 1
.treemap rd 1
.topsize rd 1
.top rd 1
.smallbins rd 4*32
.treebins rd 32
}
 
struc PG_DATA
{ .mem_amount dd ?
.vesa_mem dd ?
.pages_count dd ?
.pages_free dd ?
.pages_faults dd ?
.pagemap_size dd ?
.kernel_pages dd ?
.kernel_tables dd ?
.sys_page_dir dd ?
.pg_mutex dd ?
}
 
;struc LIB
;{ .lib_name rb 16
; .lib_base dd ?
; .lib_start dd ?
; .export dd ?
; .import dd ?
;}
 
struc SRV
{
.srv_name rb 16 ;ASCIIZ string
.magic dd ? ;+0x10 ;'SRV '
.size dd ? ;+0x14 ;size of structure SRV
.fd dd ? ;+0x18 ;next SRV descriptor
.bk dd ? ;+0x1C ;prev SRV descriptor
.base dd ? ;+0x20 ;service base address
.entry dd ? ;+0x24 ;service START function
.srv_proc dd ? ;+0x28 ;user mode service handler
.srv_proc_ex dd ? ;+0x2C ;kernel mode service handler
.sizeof:
}
 
SRV_FD_OFFSET equ 0x18
 
DRV_ENTRY equ 1
DRV_EXIT equ -1
 
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 ?
}
COFF_SECTION_SIZE equ 40
 
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 ?
}
CSYM_SIZE equ 18
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
;virtual at 0
; LIB LIB
;end virtual
 
virtual at 0
SRV SRV
end virtual
 
virtual at 0
CFH COFF_HEADER
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
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/unpacker.inc
0,0 → 1,527
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; void __stdcall unpack(void* packed_data, void* unpacked_data);
unpack:
pushad
mov esi, [esp+32+4]
mov edi, [esp+32+8]
mov eax, [esi+8]
and al, 0xC0
cmp al, 0xC0
jz .failed
mov eax, [esi+8]
push eax
add esi, 12
and al, not 0xC0
dec al
jz .lzma
.failed:
pop eax
popad
ret 8
.lzma:
call .lzma_unpack
.common:
pop eax
test al, 0x80
jnz .ctr1
test al, 0x40
jz .ok
lodsd
mov ecx, eax
jecxz .ok
mov dl, [esi]
mov esi, [esp+32+8]
.c1:
lodsb
sub al, 0E8h
cmp al, 1
ja .c1
cmp byte [esi], dl
jnz .c1
lodsd
; "bswap eax" is not supported on i386
shr ax, 8
ror eax, 16
xchg al, ah
sub eax, esi
add eax, [esp+32+8]
mov [esi-4], eax
loop .c1
.ok:
popad
ret 8
.ctr1:
lodsd
mov ecx, eax
jecxz .ok
mov dl, [esi]
mov esi, [esp+32+8]
.c2:
lodsb
@@:
cmp al, 0xF
jnz .f
lodsb
cmp al, 80h
jb @b
cmp al, 90h
jb @f
.f:
sub al, 0E8h
cmp al, 1
ja .c2
@@:
cmp byte [esi], dl
jnz .c2
lodsd
shr ax, 8
ror eax, 16
xchg al, ah
sub eax, esi
add eax, [esp+32+8]
mov [esi-4], eax
loop .c2
jmp .ok
 
.lzma_unpack:
 
.pb = 2 ; pos state bits
.lp = 0 ; literal pos state bits
.lc = 3 ; literal context bits
.posStateMask = ((1 shl .pb)-1)
.literalPosMask = ((1 shl .lp)-1)
 
.kNumPosBitsMax = 4
.kNumPosStatesMax = (1 shl .kNumPosBitsMax)
 
.kLenNumLowBits = 3
.kLenNumLowSymbols = (1 shl .kLenNumLowBits)
.kLenNumMidBits = 3
.kLenNumMidSymbols = (1 shl .kLenNumMidBits)
.kLenNumHighBits = 8
.kLenNumHighSymbols = (1 shl .kLenNumHighBits)
 
.LenChoice = 0
.LenChoice2 = 1
.LenLow = 2
.LenMid = (.LenLow + (.kNumPosStatesMax shl .kLenNumLowBits))
.LenHigh = (.LenMid + (.kNumPosStatesMax shl .kLenNumMidBits))
.kNumLenProbs = (.LenHigh + .kLenNumHighSymbols)
 
.kNumStates = 12
.kNumLitStates = 7
.kStartPosModelIndex = 4
.kEndPosModelIndex = 14
.kNumFullDistances = (1 shl (.kEndPosModelIndex/2))
.kNumPosSlotBits = 6
.kNumLenToPosStates = 4
.kNumAlignBits = 4
.kAlignTableSize = (1 shl .kNumAlignBits)
.kMatchMinLen = 2
 
.IsMatch = 0
.IsRep = (.IsMatch + (.kNumStates shl .kNumPosBitsMax))
.IsRepG0 = (.IsRep + .kNumStates)
.IsRepG1 = (.IsRepG0 + .kNumStates)
.IsRepG2 = (.IsRepG1 + .kNumStates)
.IsRep0Long = (.IsRepG2 + .kNumStates)
.PosSlot = (.IsRep0Long + (.kNumStates shl .kNumPosBitsMax))
.SpecPos = (.PosSlot + (.kNumLenToPosStates shl .kNumPosSlotBits))
.Align_ = (.SpecPos + .kNumFullDistances - .kEndPosModelIndex)
.Lencoder = (.Align_ + .kAlignTableSize)
.RepLencoder = (.Lencoder + .kNumLenProbs)
.Literal = (.RepLencoder + .kNumLenProbs)
 
.LZMA_BASE_SIZE = 1846 ; must be ==Literal
.LZMA_LIT_SIZE = 768
 
.kNumTopBits = 24
.kTopValue = (1 shl .kNumTopBits)
 
.kNumBitModelTotalBits = 11
.kBitModelTotal = (1 shl .kNumBitModelTotalBits)
.kNumMoveBits = 5
 
push edi
; int state=0;
xor ebx, ebx
mov [.previousByte], bl
; unsigned rep0=1,rep1=1,rep2=1,rep3=1;
mov eax, 1
mov edi, .rep0
stosd
stosd
stosd
stosd
; int len=0;
; result=0;
mov ecx, .Literal + (.LZMA_LIT_SIZE shl (.lc+.lp))
mov eax, .kBitModelTotal/2
mov edi, [.p]
rep stosd
; RangeDecoderInit
; rd->ExtraBytes = 0
; rd->Buffer = stream
; rd->BufferLim = stream+bufferSize
; rd->Range = 0xFFFFFFFF
pop edi
mov ebp, [esi-8] ; dest_length
add ebp, edi ; ebp = destination limit
lodsd
; rd->code_ = eax
mov [.code_], eax
or [.range], -1
.main_loop:
cmp edi, ebp
jae .main_loop_done
mov edx, edi
and edx, .posStateMask
mov eax, ebx
shl eax, .kNumPosBitsMax+2
lea eax, [.IsMatch*4 + eax + edx*4]
add eax, [.p]
call .RangeDecoderBitDecode
jc .1
movzx eax, [.previousByte]
if .literalPosMask
mov ah, dl
and ah, .literalPosMask
end if
shr eax, 8-.lc
imul eax, .LZMA_LIT_SIZE*4
add eax, .Literal*4
add eax, [.p]
cmp ebx, .kNumLitStates
jb .literal
xor edx, edx
sub edx, [.rep0]
mov dl, [edi + edx]
call .LzmaLiteralDecodeMatch
jmp @f
.literal:
call .LzmaLiteralDecode
@@:
mov [.previousByte], al
stosb
mov al, bl
cmp bl, 4
jb @f
mov al, 3
cmp bl, 10
jb @f
mov al, 6
@@: sub bl, al
jmp .main_loop
.1:
lea eax, [.IsRep*4 + ebx*4]
add eax, [.p]
call .RangeDecoderBitDecode
jnc .10
lea eax, [.IsRepG0*4 + ebx*4]
add eax, [.p]
call .RangeDecoderBitDecode
jc .111
mov eax, ebx
shl eax, .kNumPosBitsMax+2
lea eax, [.IsRep0Long*4 + eax + edx*4]
add eax, [.p]
call .RangeDecoderBitDecode
jc .1101
cmp bl, 7
setae bl
lea ebx, [9 + ebx + ebx]
xor edx, edx
sub edx, [.rep0]
mov al, [edi + edx]
stosb
mov [.previousByte], al
jmp .main_loop
.111:
lea eax, [.IsRepG1*4 + ebx*4]
add eax, [.p]
call .RangeDecoderBitDecode
mov eax, [.rep1]
jnc .l3
.l1:
lea eax, [.IsRepG2*4 + ebx*4]
add eax, [.p]
call .RangeDecoderBitDecode
mov eax, [.rep2]
jnc .l2
xchg [.rep3], eax
.l2:
push [.rep1]
pop [.rep2]
.l3:
xchg eax, [.rep0]
mov [.rep1], eax
.1101:
mov eax, .RepLencoder*4
add eax, [.p]
call .LzmaLenDecode
cmp bl, 7
setc bl
adc bl, bl
xor bl, 3
add bl, 8
jmp .repmovsb
.10:
mov eax, [.rep0]
xchg eax, [.rep1]
xchg eax, [.rep2]
xchg eax, [.rep3]
cmp bl, 7
setc bl
adc bl, bl
xor bl, 3
add bl, 7
mov eax, .Lencoder*4
add eax, [.p]
call .LzmaLenDecode
mov eax, .kNumLenToPosStates-1
cmp eax, ecx
jb @f
mov eax, ecx
@@:
push ecx
mov ecx, .kNumPosSlotBits
shl eax, cl
shl eax, 2
add eax, .PosSlot*4
add eax, [.p]
call .RangeDecoderBitTreeDecode
mov [.rep0], ecx
cmp ecx, .kStartPosModelIndex
jb .l6
push ecx
mov eax, ecx
and eax, 1
shr ecx, 1
or eax, 2
dec ecx
shl eax, cl
mov [.rep0], eax
pop edx
cmp edx, .kEndPosModelIndex
jae .l5
sub eax, edx
shl eax, 2
add eax, (.SpecPos - 1)*4
add eax, [.p]
call .RangeDecoderReverseBitTreeDecode
add [.rep0], ecx
jmp .l6
.l5:
sub ecx, .kNumAlignBits
call .RangeDecoderDecodeDirectBits
mov ecx, .kNumAlignBits
shl eax, cl
add [.rep0], eax
mov eax, .Align_*4
add eax, [.p]
call .RangeDecoderReverseBitTreeDecode
add [.rep0], ecx
.l6:
pop ecx
inc [.rep0]
jz .main_loop_done
.repmovsb:
add ecx, .kMatchMinLen
push esi
mov esi, edi
sub esi, [.rep0]
rep movsb
pop esi
mov al, [edi-1]
mov [.previousByte], al
jmp .main_loop
.main_loop_done:
ret
 
.RangeDecoderBitDecode:
; in: eax->prob
; out: CF=bit; destroys eax
push edx
mov edx, [.range]
shr edx, .kNumBitModelTotalBits
imul edx, [eax]
cmp [.code_], edx
jae .ae
mov [.range], edx
mov edx, .kBitModelTotal
sub edx, [eax]
shr edx, .kNumMoveBits
add [eax], edx
clc
.n:
lahf
cmp [.range], .kTopValue
jae @f
shl [.range], 8
shl [.code_], 8
lodsb
mov byte [.code_], al
@@:
sahf
pop edx
ret
.ae:
sub [.range], edx
sub [.code_], edx
mov edx, [eax]
shr edx, .kNumMoveBits
sub [eax], edx
stc
jmp .n
 
.RangeDecoderDecodeDirectBits:
; in: ecx=numTotalBits
; out: eax=result; destroys edx
xor eax, eax
.l:
shr [.range], 1
shl eax, 1
mov edx, [.code_]
sub edx, [.range]
jb @f
mov [.code_], edx
or eax, 1
@@:
cmp [.range], .kTopValue
jae @f
shl [.range], 8
shl [.code_], 8
push eax
lodsb
mov byte [.code_], al
pop eax
@@:
loop .l
ret
 
.LzmaLiteralDecode:
; in: eax->probs
; out: al=byte; destroys edx
push ecx
mov ecx, 1
@@:
push eax
lea eax, [eax+ecx*4]
call .RangeDecoderBitDecode
pop eax
adc cl, cl
jnc @b
.LzmaLiteralDecode.ret:
mov al, cl
pop ecx
ret
.LzmaLiteralDecodeMatch:
; in: eax->probs, dl=matchByte
; out: al=byte; destroys edx
push ecx
mov ecx, 1
.LzmaLiteralDecodeMatch.1:
add dl, dl
setc ch
push eax
lea eax, [eax+ecx*4+0x100*4]
call .RangeDecoderBitDecode
pop eax
adc cl, cl
jc .LzmaLiteralDecode.ret
xor ch, cl
test ch, 1
mov ch, 0
jnz @b
jmp .LzmaLiteralDecodeMatch.1
 
.LzmaLenDecode:
; in: eax->prob, edx=posState
; out: ecx=len
push eax
add eax, .LenChoice*4
call .RangeDecoderBitDecode
pop eax
jnc .0
push eax
add eax, .LenChoice2*4
call .RangeDecoderBitDecode
pop eax
jc @f
mov ecx, .kLenNumMidBits
shl edx, cl
lea eax, [eax + .LenMid*4 + edx*4]
call .RangeDecoderBitTreeDecode
add ecx, .kLenNumLowSymbols
ret
@@:
add eax, .LenHigh*4
mov ecx, .kLenNumHighBits
call .RangeDecoderBitTreeDecode
add ecx, .kLenNumLowSymbols + .kLenNumMidSymbols
ret
.0:
mov ecx, .kLenNumLowBits
shl edx, cl
lea eax, [eax + .LenLow*4 + edx*4]
.RangeDecoderBitTreeDecode:
; in: eax->probs,ecx=numLevels
; out: ecx=length; destroys edx
push ebx
mov edx, 1
mov ebx, edx
@@:
push eax
lea eax, [eax+edx*4]
call .RangeDecoderBitDecode
pop eax
adc dl, dl
add bl, bl
loop @b
sub dl, bl
pop ebx
mov ecx, edx
ret
.RangeDecoderReverseBitTreeDecode:
; in: eax->probs,ecx=numLevels
; out: ecx=length; destroys edx
push ebx ecx
mov edx, 1
xor ebx, ebx
@@:
push eax
lea eax, [eax+edx*4]
call .RangeDecoderBitDecode
lahf
adc edx, edx
sahf
rcr ebx, 1
pop eax
loop @b
pop ecx
rol ebx, cl
mov ecx, ebx
pop ebx
ret
 
uglobal
align 4
;unpack.p rd unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp))
unpack.p dd ?
unpack.code_ dd ?
unpack.range dd ?
unpack.rep0 dd ?
unpack.rep1 dd ?
unpack.rep2 dd ?
unpack.rep3 dd ?
unpack.previousByte db ?
endg
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/kernel32.inc
0,0 → 1,311
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; KERNEL32.INC ;;
;; ;;
;; Included 32 bit kernel files for MenuetOS ;;
;; ;;
;; This file is kept separate as it will be easier to ;;
;; maintain and compile with an automated SETUP program ;;
;; in the future. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;struc db [a] { common . db a
; if ~used .
; display 'not used db: ',`.,13,10
; end if }
;struc dw [a] { common . dw a
; if ~used .
; display 'not used dw: ',`.,13,10
; end if }
;struc dd [a] { common . dd a
; if ~used .
; display 'not used dd: ',`.,13,10
; end if }
;struc dp [a] { common . dp a
; if ~used .
; display 'not used dp: ',`.,13,10
; end if }
;struc dq [a] { common . dq a
; if ~used .
; display 'not used dq: ',`.,13,10
; end if }
;struc dt [a] { common . dt a
; if ~used .
; display 'not used dt: ',`.,13,10
; end if }
 
struc POINT {
.x dd ?
.y dd ?
.sizeof:
}
virtual at 0
POINT POINT
end virtual
 
struc RECT {
.left dd ?
.top dd ?
.right dd ?
.bottom dd ?
.sizeof:
}
virtual at 0
RECT RECT
end virtual
 
struc BOX {
.left dd ?
.top dd ?
.width dd ?
.height dd ?
.sizeof:
}
virtual at 0
BOX BOX
end virtual
 
struc DISPMODE {
.width rw 1
.height rw 1
.bpp rw 1
.freq rw 1
}
 
; constants definition
WSTATE_NORMAL = 00000000b
WSTATE_MAXIMIZED = 00000001b
WSTATE_MINIMIZED = 00000010b
WSTATE_ROLLEDUP = 00000100b
 
WSTATE_REDRAW = 00000001b
WSTATE_WNDDRAWN = 00000010b
 
WSTYLE_HASCAPTION = 00010000b
WSTYLE_CLIENTRELATIVE = 00100000b
 
struc TASKDATA
{
.event_mask dd ?
.pid dd ?
dw ?
.state db ?
db ?
dw ?
.wnd_number db ?
db ?
.mem_start dd ?
.counter_sum dd ?
.counter_add dd ?
.cpu_usage dd ?
}
virtual at 0
TASKDATA TASKDATA
end virtual
 
TSTATE_RUNNING = 0
TSTATE_RUN_SUSPENDED = 1
TSTATE_WAIT_SUSPENDED = 2
TSTATE_ZOMBIE = 3
TSTATE_TERMINATING = 4
TSTATE_WAITING = 5
TSTATE_FREE = 9
 
; structures definition
struc WDATA {
.box BOX
.cl_workarea dd ?
.cl_titlebar dd ?
.cl_frames dd ?
.reserved db ?
.fl_wstate db ?
.fl_wdrawn db ?
.fl_redraw db ?
.sizeof:
}
virtual at 0
WDATA WDATA
end virtual
label WDATA.fl_wstyle byte at WDATA.cl_workarea + 3
 
struc APPDATA
{
.app_name db 11 dup(?)
db 5 dup(?)
 
.fpu_state dd ? ;+16
.ev_count_ dd ? ;unused ;+20
.exc_handler dd ? ;+24
.except_mask dd ? ;+28
.pl0_stack dd ? ;unused ;+32
.heap_base dd ? ;+36
.heap_top dd ? ;+40
.cursor dd ? ;+44
.fd_ev dd ? ;+48
.bk_ev dd ? ;+52
.fd_obj dd ? ;+56
.bk_obj dd ? ;+60
.saved_esp dd ? ;+64
.io_map rd 2 ;+68
.dbg_state dd ? ;+76
.cur_dir dd ? ;+80
.wait_timeout dd ? ;+84
.saved_esp0 dd ? ;+88
.wait_begin dd ? ;+92 +++
.wait_test dd ? ;+96 +++
.wait_param dd ? ;+100 +++
.tls_base dd ? ;+104
.dlls_list_ptr dd ? ;+108
db 16 dup(?) ;+112
 
.wnd_shape dd ? ;+128
.wnd_shape_scale dd ? ;+132
dd ? ;+136
.mem_size dd ? ;+140
.saved_box BOX
.ipc_start dd ?
.ipc_size dd ?
.event_mask dd ?
.debugger_slot dd ?
dd ?
.keyboard_mode db ?
db 3 dup(?)
.dir_table dd ?
.dbg_event_mem dd ?
.dbg_regs:
.dbg_regs.dr0 dd ?
.dbg_regs.dr1 dd ?
.dbg_regs.dr2 dd ?
.dbg_regs.dr3 dd ?
.dbg_regs.dr7 dd ?
.wnd_caption dd ?
.wnd_clientbox BOX
}
virtual at 0
APPDATA APPDATA
end virtual
 
;// mike.dld, 2006-29-01 ]
 
struc MUTEX
{
.count rd 1
.next rd 1
.prev rd 1
}
 
virtual at 0
MUTEX MUTEX
end virtual
 
 
; Core functions
include "core/sync.inc" ; macros for synhronization objects
include "core/sys32.inc" ; process management
include "core/sched.inc" ; process scheduling
include "core/syscall.inc" ; system call
include "core/fpu.inc" ; all fpu/sse support
include "core/memory.inc"
include "core/heap.inc" ; kernel and app heap
include "core/malloc.inc" ; small kernel heap
include "core/taskman.inc"
include "core/dll.inc"
include "core/peload.inc" ;
include "core/exports.inc"
include "core/string.inc"
include "core/v86.inc" ; virtual-8086 manager
 
; GUI stuff
include "gui/window.inc"
include "gui/event.inc"
include "gui/font.inc"
include "gui/button.inc"
 
; shutdown
 
; file system
 
include "fs/fs.inc" ; syscall
include "fs/fat32.inc" ; read / write for fat32 filesystem
include "fs/ntfs.inc" ; read / write for ntfs filesystem
include "fs/fat12.inc" ; read / write for fat12 filesystem
include "blkdev/rd.inc" ; ramdisk read /write
include "fs/fs_lfn.inc" ; syscall, version 2
include "fs/iso9660.inc" ; read for iso9660 filesystem CD
include "fs/ext2.inc" ; read / write for ext2 filesystem
 
; sound
 
include "sound/playnote.inc" ; player Note for Speaker PC
 
; display
 
include "video/vesa12.inc" ; Vesa 1.2 functions
include "video/vesa20.inc" ; Vesa 2.0 functions
include "video/vga.inc" ; VGA 16 color functions
include "video/cursors.inc" ; cursors functions
 
; Network Interface & TCPIP Stack
 
include "network/stack.inc"
 
;include "drivers/uart.inc"
 
 
; Mouse pointer
 
include "gui/mouse.inc"
 
; Window skinning
 
include "gui/skincode.inc"
 
; Pci functions
 
include "bus/pci/pci32.inc"
 
; Floppy drive controller
 
include "blkdev/fdc.inc"
include "blkdev/flp_drv.inc"
 
; IDE cache
include "blkdev/ide_cache.inc"
 
; HD drive controller
include "blkdev/hd_drv.inc"
 
; CD drive controller
 
include "blkdev/cdrom.inc"
include "blkdev/cd_drv.inc"
 
; Character devices
 
include "hid/keyboard.inc"
include "hid/mousedrv.inc"
 
; setting date,time,clock and alarm-clock
 
include "hid/set_dtc.inc"
 
;% -include
 
;parser file names
include "fs/parse_fn.inc"
 
; work with conf lib
include "core/conf_lib.inc"
 
; load external lib
include "core/ext_lib.inc"
 
; list of external functions
include "imports.inc"
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/detect/biosdisk.inc
0,0 → 1,81
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; Detect all BIOS hard drives.
; diamond, 2008
 
xor cx, cx
mov es, cx
mov di, 0x9080
mov byte [es:di-1], cl
cmp [preboot_biosdisk], 1
jnz bdde
mov dl, 80h
bdds:
mov ah, 15h
push cx dx di
int 13h
pop di dx cx
jc bddc
test ah, ah
jz bddc
inc cx
mov ah, 48h
push ds
push es
pop ds
mov si, 0xA000
mov word [si], 1Eh
mov ah, 48h
int 13h
pop ds
jc bddc2
inc byte [es:0x907F]
cmp word [es:si], 1Eh
jb bddl
cmp word [es:si+1Ah], 0xFFFF
jz bddl
mov al, dl
stosb
push ds
lds si, [es:si+1Ah]
mov al, [si+6]
and al, 0xF
stosb
mov al, byte [si+4]
shr al, 4
and ax, 1
cmp word [si], 1F0h
jz @f
inc ax
inc ax
cmp word [si], 170h
jz @f
or ax,-1
; mov ax, -1
@@:
stosw
pop ds
jmp bddc2
bddl:
mov al, dl
stosb
xor ax,ax
stosb
dec ax
stosw
; mov al, 0
; stosb
; mov ax, -1
; stosw
bddc2:
cmp cl, [es:0x475]
jae bdde
bddc:
inc dl
jnz bdds
bdde:
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/detect/sear_par.inc
0,0 → 1,157
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;****************************************************
; ïîèñê ëîãè÷åñêèõ äèñêîâ íà îáíàðóæåííûõ HDD
; è çàíåñåíèå äàííûõ â îáëàñòü òàáëèöû
; àâòîð Mario79
;****************************************************
mov [transfer_adress],DRIVE_DATA+0xa
search_partitions_ide0:
test [DRIVE_DATA+1],byte 0x40
jz search_partitions_ide1
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
mov [known_part],1
search_partitions_ide0_1:
call set_PARTITION_variables
test [problem_partition],2
jnz search_partitions_ide1 ; not found part
test [problem_partition],1
jnz @F ; not found known_part
;cmp [problem_partition],0
;jne search_partitions_ide1
inc byte [DRIVE_DATA+2]
call partition_data_transfer
add [transfer_adress],100
@@:
inc [known_part]
jmp search_partitions_ide0_1
 
search_partitions_ide1:
test [DRIVE_DATA+1],byte 0x10
jz search_partitions_ide2
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
mov [known_part],1
search_partitions_ide1_1:
call set_PARTITION_variables
test [problem_partition],2
jnz search_partitions_ide2
test [problem_partition],1
jnz @F
;cmp [problem_partition],0
;jne search_partitions_ide2
inc byte [DRIVE_DATA+3]
call partition_data_transfer
add [transfer_adress],100
@@:
inc [known_part]
jmp search_partitions_ide1_1
 
search_partitions_ide2:
test [DRIVE_DATA+1],byte 0x4
jz search_partitions_ide3
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
mov [known_part],1
search_partitions_ide2_1:
call set_PARTITION_variables
test [problem_partition],2
jnz search_partitions_ide3
test [problem_partition],1
jnz @F
;cmp [problem_partition],0
;jne search_partitions_ide3
inc byte [DRIVE_DATA+4]
call partition_data_transfer
add [transfer_adress],100
@@:
inc [known_part]
jmp search_partitions_ide2_1
 
search_partitions_ide3:
test [DRIVE_DATA+1],byte 0x1
jz end_search_partitions_ide
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
mov [known_part],1
search_partitions_ide3_1:
call set_PARTITION_variables
test [problem_partition],2
jnz end_search_partitions_ide
test [problem_partition],1
jnz @F
;cmp [problem_partition],0
;jne end_search_partitions_ide
inc byte [DRIVE_DATA+5]
call partition_data_transfer
add [transfer_adress],100
@@:
inc [known_part]
jmp search_partitions_ide3_1
 
end_search_partitions_ide:
mov [hdpos], 80h
mov ecx, [NumBiosDisks]
test ecx, ecx
jz end_search_partitions
start_search_partitions_bd:
push ecx
mov eax, [hdpos]
and [BiosDiskPartitions+(eax-80h)*4], 0
mov [known_part], 1
search_partitions_bd:
call set_PARTITION_variables
test [problem_partition],2
jnz end_search_partitions_bd
test [problem_partition],1
jnz @F
;cmp [problem_partition], 0
;jne end_search_partitions_bd
mov eax, [hdpos]
inc [BiosDiskPartitions+(eax-80h)*4]
call partition_data_transfer
add [transfer_adress], 100
@@:
inc [known_part]
jmp search_partitions_bd
end_search_partitions_bd:
pop ecx
inc [hdpos]
loop start_search_partitions_bd
jmp end_search_partitions
 
partition_data_transfer:
mov edi,[transfer_adress]
mov esi,PARTITION_START ;start of file_system_data
mov ecx,(file_system_data_size+3)/4
rep movsd
ret
uglobal
transfer_adress dd 0
endg
partition_data_transfer_1:
; cli
push edi
mov edi,PARTITION_START
mov esi,[transfer_adress]
mov ecx,(file_system_data_size+3)/4
rep movsd
pop edi
; sti
ret
 
end_search_partitions:
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/detect/dev_hdcd.inc
0,0 → 1,385
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;******************************************************
; ïîèñê ïðèâîäîâ HDD è CD
; àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
; àäàïòàöèÿ è äîðàáîòêà Mario79
;******************************************************
 
;****************************************************
;* ÏÎÈÑÊ HDD è CD *
;****************************************************
FindHDD:
mov [ChannelNumber],1
mov [DiskNumber],0
call FindHDD_3
; mov ax,[Sector512+176]
; mov [DRIVE_DATA+6],ax
; mov ax,[Sector512+126]
; mov [DRIVE_DATA+8],ax
; mov ax,[Sector512+128]
; mov [DRIVE_DATA+8],ax
mov [DiskNumber],1
call FindHDD_3
; mov al,[Sector512+176]
; mov [DRIVE_DATA+7],al
inc [ChannelNumber]
mov [DiskNumber],0
call FindHDD_3
; mov al,[Sector512+176]
; mov [DRIVE_DATA+8],al
mov [DiskNumber],1
call FindHDD_1
; mov al,[Sector512+176]
; mov [DRIVE_DATA+9],al
 
jmp EndFindHDD
 
FindHDD_1:
call ReadHDD_ID
cmp [DevErrorCode],0
jne FindHDD_2
cmp [Sector512+6],word 16
ja FindHDD_2
cmp [Sector512+12],word 255
ja FindHDD_2
inc byte [DRIVE_DATA+1]
jmp FindHDD_2_2
FindHDD_2:
call DeviceReset
cmp [DevErrorCode],0
jne FindHDD_2_2
call ReadCD_ID
cmp [DevErrorCode],0
jne FindHDD_2_2
inc byte [DRIVE_DATA+1]
inc byte [DRIVE_DATA+1]
FindHDD_2_2:
ret
 
FindHDD_3:
call FindHDD_1
shl byte [DRIVE_DATA+1],2
ret
 
 
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà â ðåæèìå LBA
uglobal
SectorAddress DD ?
endg
;*************************************************
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÆÅÑÒÊÎÃÎ ÄÈÑÊÀ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); *
;* DiskNumber - íîìåð äèñêà íà êàíàëå (0 èëè 1). *
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ *
;* â ìàññèâ Sector512. *
;*************************************************
ReadHDD_ID:
; Çàäàòü ðåæèì CHS
mov [ATAAddressMode],0
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà
mov [ATAFeatures],0
mov [ATAHead],0
mov [ATACommand],0ECh
call SendCommandToHDD
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
jne @@End ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
mov DX,[ATABasePortAddr]
add DX,7 ;àäðåñ ðåãèñòðà ñîñòîÿíè
mov ecx,0xffff
@@WaitCompleet:
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
dec ecx
; cmp ecx,0
jz @@Error1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitCompleet
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Error6
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitCompleet
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
; mov AX,DS
; mov ES,AX
mov EDI,Sector512 ;offset Sector512
mov DX,[ATABasePortAddr] ;ðåãèñòð äàííûõ
mov CX,256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ
rep insw ;ïðèíÿòü áëîê äàííûõ
ret
; Çàïèñàòü êîä îøèáêè
@@Error1:
mov [DevErrorCode],1
ret
@@Error6:
mov [DevErrorCode],6
@@End: ret
 
 
iglobal
; Ñòàíäàðòíûå áàçîâûå àäðåñà êàíàëîâ 1 è 2
StandardATABases DW 1F0h, 170h
endg
uglobal
; Íîìåð êàíàëà
ChannelNumber DW ?
; Íîìåð äèñêà
DiskNumber DB ?
; Áàçîâûé àäðåñ ãðóïïû ïîðòîâ êîíòðîëëåðà ATA
ATABasePortAddr DW ?
; Ïàðàìåòðû ATA-êîìàíäû
ATAFeatures DB ? ;îñîáåííîñòè
ATASectorCount DB ? ;êîëè÷åñòâî îáðàáàòûâàåìûõ ñåêòîðîâ
ATASectorNumber DB ? ;íîìåð íà÷àëüíîãî ñåêòîðà
ATACylinder DW ? ;íîìåð íà÷àëüíîãî öèëèíäðà
ATAHead DB ? ;íîìåð íà÷àëüíîé ãîëîâêè
ATAAddressMode DB ? ;ðåæèì àäðåñàöèè (0 - CHS, 1 - LBA)
ATACommand DB ? ;êîä êîìàíäû, ïîäëåæàùåé âûïîëíåíèþ
; Êîä îøèáêè (0 - íåò îøèáîê, 1 - ïðåâûøåí äîïóñòèìûé
; èíòåðâàë îæèäàíèÿ, 2 - íåâåðíûé êîä ðåæèìà àäðåñàöèè,
; 3 - íåâåðíûé íîìåð êàíàëà, 4 - íåâåðíûé íîìåð äèñêà,
; 5 - íåâåðíûé íîìåð ãîëîâêè, 6 - îøèáêà ïðè âûïîëíåíèè
; êîìàíäû)
DevErrorCode dd ?
endg
;****************************************************
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); *
;* DiskNumber - íîìåð äèñêà (0 èëè 1); *
;* ATAFeatures - "îñîáåííîñòè"; *
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; *
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; *
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; *
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; *
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); *
;* ATACommand - êîä êîìàíäû. *
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: *
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; *
;* â DevErrorCode - íîëü. *
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò *
;* âîçâðàùåí êîä îøèáêè. *
;****************************************************
SendCommandToHDD:
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà
cmp [ATAAddressMode],1
ja @@Err2
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà
mov BX,[ChannelNumber]
cmp BX,1
jb @@Err3
cmp BX,2
ja @@Err3
; Óñòàíîâèòü áàçîâûé àäðåñ
dec BX
shl BX,1
movzx ebx,bx
mov AX,[ebx+StandardATABases]
mov [ATABasePortAddr],AX
; Îæèäàíèå ãîòîâíîñòè HDD ê ïðèåìó êîìàíäû
; Âûáðàòü íóæíûé äèñê
mov DX,[ATABasePortAddr]
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê
mov AL,[DiskNumber]
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà
ja @@Err4
shl AL,4
or AL,10100000b
out DX,AL
; Îæèäàòü, ïîêà äèñê íå áóäåò ãîòîâ
inc DX
mov ecx,0xfff
; mov eax,[timer_ticks]
; mov [TickCounter_1],eax
@@WaitHDReady:
; Ïðîâåðèòü âðåìÿ îæèäàíè
dec ecx
; cmp ecx,0
jz @@Err1
; mov eax,[timer_ticks]
; sub eax,[TickCounter_1]
; cmp eax,300 ;îæèäàòü 300 òèêîâ
; ja @@Err1 ;îøèáêà òàéì-àóòà
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè
in AL,DX
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
test AL,80h
jnz @@WaitHDReady
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà DRQ
test AL,08h
jnz @@WaitHDReady
; Çàãðóçèòü êîìàíäó â ðåãèñòðû êîíòðîëëåðà
cli
mov DX,[ATABasePortAddr]
inc DX ;ðåãèñòð "îñîáåííîñòåé"
mov AL,[ATAFeatures]
out DX,AL
inc DX ;ñ÷åò÷èê ñåêòîðîâ
mov AL,[ATASectorCount]
out DX,AL
inc DX ;ðåãèñòð íîìåðà ñåêòîðà
mov AL,[ATASectorNumber]
out DX,AL
inc DX ;íîìåð öèëèíäðà (ìëàäøèé áàéò)
mov AX,[ATACylinder]
out DX,AL
inc DX ;íîìåð öèëèíäðà (ñòàðøèé áàéò)
mov AL,AH
out DX,AL
inc DX ;íîìåð ãîëîâêè/íîìåð äèñêà
mov AL,[DiskNumber]
shl AL,4
cmp [ATAHead],0Fh ;ïðîâåðèòü íîìåð ãîëîâêè
ja @@Err5
or AL,[ATAHead]
or AL,10100000b
mov AH,[ATAAddressMode]
shl AH,6
or AL,AH
out DX,AL
; Ïîñëàòü êîìàíäó
mov AL,[ATACommand]
inc DX ;ðåãèñòð êîìàíä
out DX,AL
sti
; Ñáðîñèòü ïðèçíàê îøèáêè
mov [DevErrorCode],0
ret
; Çàïèñàòü êîä îøèáêè
@@Err1: mov [DevErrorCode],1
ret
@@Err2: mov [DevErrorCode],2
ret
@@Err3: mov [DevErrorCode],3
ret
@@Err4: mov [DevErrorCode],4
ret
@@Err5: mov [DevErrorCode],5
; Çàâåðøåíèå ðàáîòû ïðîãðàììû
ret
 
;*************************************************
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÓÑÒÐÎÉÑÒÂÀ ATAPI *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;* Èäåíòèôèêàöèîííûé áëîê äàííûõ ñ÷èòûâàåòñÿ *
;* â ìàññèâ Sector512. *
;*************************************************
ReadCD_ID:
; Çàäàòü ðåæèì CHS
mov [ATAAddressMode],0
; Ïîñëàòü êîìàíäó èäåíòèôèêàöèè óñòðîéñòâà
mov [ATAFeatures],0
mov [ATASectorCount],0
mov [ATASectorNumber],0
mov [ATACylinder],0
mov [ATAHead],0
mov [ATACommand],0A1h
call SendCommandToHDD
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
jne @@End_1 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
; Îæèäàòü ãîòîâíîñòü äàííûõ HDD
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
mov ecx,0xffff
@@WaitCompleet_1:
; Ïðîâåðèòü âðåì
dec ecx
; cmp ecx,0
jz @@Error1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitCompleet_1
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Error6_1
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitCompleet_1
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
; mov AX,DS
; mov ES,AX
mov EDI,Sector512 ;offset Sector512
mov DX,[ATABasePortAddr] ;ïîðò 1x0h
mov CX,256 ;÷èñëî ñ÷èòûâàåìûõ ñëîâ
rep insw
ret
; Çàïèñàòü êîä îøèáêè
@@Error1_1:
mov [DevErrorCode],1
ret
@@Error6_1:
mov [DevErrorCode],6
@@End_1:
ret
 
;*************************************************
;* ÑÁÐÎÑ ÓÑÒÐÎÉÑÒÂÀ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); *
;* DiskNumber - íîìåð äèñêà (0 èëè 1). *
;*************************************************
DeviceReset:
; Ïðîâåðèòü êîððåêòíîñòü íîìåðà êàíàëà
mov BX,[ChannelNumber]
cmp BX,1
jb @@Err3_2
cmp BX,2
ja @@Err3_2
; Óñòàíîâèòü áàçîâûé àäðåñ
dec BX
shl BX,1
movzx ebx,bx
mov DX,[ebx+StandardATABases]
mov [ATABasePortAddr],DX
; Âûáðàòü íóæíûé äèñê
add DX,6 ;àäðåñ ðåãèñòðà ãîëîâîê
mov AL,[DiskNumber]
cmp AL,1 ;ïðîâåðèòü íîìåðà äèñêà
ja @@Err4_2
shl AL,4
or AL,10100000b
out DX,AL
; Ïîñëàòü êîìàíäó "Ñáðîñ"
mov AL,08h
inc DX ;ðåãèñòð êîìàíä
out DX,AL
mov ecx,0x80000
@@WaitHDReady_1:
; Ïðîâåðèòü âðåìÿ îæèäàíè
dec ecx
; cmp ecx,0
je @@Err1_2 ;îøèáêà òàéì-àóòà
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíè
in AL,DX
; Ïðîâåðèòü ñîñòîÿíèå ñèãíàëà BSY
test AL,80h
jnz @@WaitHDReady_1
; Ñáðîñèòü ïðèçíàê îøèáêè
mov [DevErrorCode],0
ret
; Îáðàáîòêà îøèáîê
@@Err1_2: mov [DevErrorCode],1
ret
@@Err3_2: mov [DevErrorCode],3
ret
@@Err4_2: mov [DevErrorCode],4
; Çàïèñàòü êîä îøèáêè
ret
 
EndFindHDD:
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/detect/dev_fd.inc
0,0 → 1,30
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;***************************************************
; ïðåäâàðèòåëüíàÿ î÷èñòêà îáëàñòè òàáëèöû
; ïîèñê è çàíåñåíèå â òàáëèöó ïðèâîäîâ FDD
; àâòîð Mario79
;***************************************************
xor eax,eax
mov edi,DRIVE_DATA
mov ecx,16384
cld
rep stosd
 
mov al,0x10
out 0x70,al
mov cx,0xff
wait_cmos:
dec cx
test cx,cx
jnz wait_cmos
in al,0x71
mov [DRIVE_DATA],al
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/detect/getcache.inc
0,0 → 1,212
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
pusha
 
mov eax,[pg_data.pages_free]
; 1/32
shr eax,5
; round off up to 8 pages
shr eax,3
shl eax,3
; translate pages in butes *4096
shl eax,12
; check a upper size of the cache, no more than 1 Mb on the physical device
cmp eax,1024*1024
jbe @f
mov eax,1024*1024
jmp .continue
@@:
; check a lower size of the cache, not less than 128 Kb on the physical device
cmp eax,128*1024
jae @f
mov eax,128*1024
@@:
.continue:
mov [cache_ide0_size],eax
mov [cache_ide1_size],eax
mov [cache_ide2_size],eax
mov [cache_ide3_size],eax
xor eax,eax
mov [hdd_appl_data],1 ;al
mov [cd_appl_data],1
mov ch,[DRIVE_DATA+1]
mov cl,ch
and cl,11b
je .ide2
mov esi,cache_ide3
call get_cache_ide
.ide2:
mov cl,ch
shr cl,2
and cl,11b
je .ide1
mov esi,cache_ide2
call get_cache_ide
.ide1:
mov cl,ch
shr cl,4
and cl,11b
je .ide0
mov esi,cache_ide1
call get_cache_ide
.ide0:
mov cl,ch
shr cl,6
and cl,11b
je @f
mov esi,cache_ide0
call get_cache_ide
@@:
xor ecx,ecx
cmp [NumBiosDisks],ecx
jz .endbd
mov esi,BiosDiskCaches
.loopbd:
push ecx
movsx ecx,byte [BiosDisksData+ecx*4+2]
inc ecx
jz .getbd
add ecx,ecx
movzx eax,byte [DRIVE_DATA+1]
shl eax,cl
and ah,3
cmp ah,1
jz .contbd
pop ecx
mov byte [BiosDisksData+ecx*4+2], -1
push ecx
.getbd:
mov eax,[cache_ide0_size]
mov [esi+cache_ide0_size-cache_ide0],eax
mov cl,1
call get_cache_ide
.contbd:
pop ecx
add esi,cache_ide1-cache_ide0
inc ecx
cmp ecx,[NumBiosDisks]
jb .loopbd
.endbd:
jmp end_get_cache
 
get_cache_ide:
and [esi+cache_ide0_search_start-cache_ide0],0
and [esi+cache_ide0_appl_search_start-cache_ide0],0
push ecx
stdcall kernel_alloc,[esi+cache_ide0_size-cache_ide0]
mov [esi+cache_ide0_pointer-cache_ide0],eax
pop ecx
mov edx,eax
mov eax,[esi+cache_ide0_size-cache_ide0]
shr eax,3
mov [esi+cache_ide0_system_data_size-cache_ide0],eax
mov ebx,eax
imul eax,7
mov [esi+cache_ide0_appl_data_size-cache_ide0],eax
add ebx,edx
mov [esi+cache_ide0_data_pointer-cache_ide0],ebx
 
cmp cl,10b
je .cd
push ecx
mov eax,[esi+cache_ide0_system_data_size-cache_ide0]
call calculate_for_hd
add eax,[esi+cache_ide0_pointer-cache_ide0]
mov [esi+cache_ide0_system_data-cache_ide0],eax
mov [esi+cache_ide0_system_sad_size-cache_ide0],ecx
 
push edi
mov edi,[esi+cache_ide0_pointer-cache_ide0]
call clear_ide_cache
pop edi
 
mov eax,[esi+cache_ide0_appl_data_size-cache_ide0]
call calculate_for_hd
add eax,[esi+cache_ide0_data_pointer-cache_ide0]
mov [esi+cache_ide0_appl_data-cache_ide0],eax
mov [esi+cache_ide0_appl_sad_size-cache_ide0],ecx
 
push edi
mov edi,[esi+cache_ide0_data_pointer-cache_ide0]
call clear_ide_cache
pop edi
 
pop ecx
ret
.cd:
push ecx
mov eax,[esi+cache_ide0_system_data_size-cache_ide0]
call calculate_for_cd
add eax,[esi+cache_ide0_pointer-cache_ide0]
mov [esi+cache_ide0_system_data-cache_ide0],eax
mov [esi+cache_ide0_system_sad_size-cache_ide0],ecx
 
push edi
mov edi,[esi+cache_ide0_pointer-cache_ide0]
call clear_ide_cache
pop edi
 
mov eax,[esi+cache_ide0_appl_data_size-cache_ide0]
call calculate_for_cd
add eax,[esi+cache_ide0_data_pointer-cache_ide0]
mov [esi+cache_ide0_appl_data-cache_ide0],eax
mov [esi+cache_ide0_appl_sad_size-cache_ide0],ecx
 
push edi
mov edi,[esi+cache_ide0_data_pointer-cache_ide0]
call clear_ide_cache
pop edi
 
pop ecx
ret
 
calculate_for_hd:
push eax
mov ebx,eax
shr eax,9
shl eax,3
sub ebx,eax
shr ebx,9
mov ecx,ebx
shl ebx,9
pop eax
sub eax,ebx
dec ecx
ret
 
calculate_for_cd:
push eax
mov ebx,eax
shr eax,11
shl eax,3
sub ebx,eax
shr ebx,11
mov ecx,ebx
shl ebx,11
pop eax
sub eax,ebx
dec ecx
ret
 
clear_ide_cache:
push eax
shl ecx,1
xor eax,eax
cld
rep stosd
pop eax
ret
 
end_get_cache:
; mov [cache_ide0_pointer],HD_CACHE
; mov [cache_ide0_system_data],HD_CACHE+65536
; mov [cache_ide0_system_sad_size],1919
popa
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/detect/biosmem.inc
0,0 → 1,43
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; Query physical memory map from BIOS.
; diamond, 2009
 
push ds
; first call to fn E820
mov eax, 0xE820
xor ebx, ebx
mov es, bx
mov ds, bx
mov di, 0x9104
mov [di-4], ebx ; no blocks yet
mov ecx, 20
mov edx, 0x534D4150
int 15h
jc no_E820
cmp eax, 0x534D4150
jnz no_E820
e820_mem_loop:
cmp byte [di+16], 1 ; ignore non-free areas
jnz e820_mem_next
inc byte [0x9100]
add di, 20
e820_mem_next:
; consequent calls to fn E820
test ebx, ebx
jz e820_test_done
cmp byte [0x9100], 32
jae e820_test_done
mov eax, 0xE820
int 15h
jc e820_test_done
jmp e820_mem_loop
no_E820:
; let's hope for mem_test from init.inc
e820_test_done:
pop ds
/kernel/branches/Kolibri-acpi/detect/disks.inc
0,0 → 1,15
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
include 'dev_fd.inc'
include 'dev_hdcd.inc'
include 'getcache.inc'
include 'sear_par.inc'
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/detect
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/video/vesa20.inc
0,0 → 1,1150
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; VESA20.INC ;;
;; ;;
;; Vesa 2.0 functions for MenuetOS ;;
;; ;;
;; Copyright 2002 Ville Turjanmaa ;;
;; Alexey, kgaz@crosswindws.net ;;
;; - Voodoo compatible graphics ;;
;; Juan M. Caravaca ;;
;; - Graphics optimimizations eg. drawline ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; If you're planning to write your own video driver I suggest
; you replace the VESA12.INC file and see those instructions.
 
;Screen_Max_X equ 0xfe00
;Screen_Max_Y equ 0xfe04
;BytesPerScanLine equ 0xfe08
;LFBAddress equ 0xfe80
;ScreenBPP equ 0xfbf1
 
 
 
;*************************************************
; getpixel
;
; in:
; eax = x coordinate
; ebx = y coordinate
;
; ret:
; ecx = 00 RR GG BB
 
getpixel:
push eax ebx edx edi
call dword [GETPIXEL]
pop edi edx ebx eax
ret
 
Vesa20_getpixel24:
; eax = x
; ebx = y
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [eax+eax*2] ; edi = x*3
add edi, ebx ; edi = x*3+(y*y multiplier)
mov ecx, [LFB_BASE+edi]
and ecx, 0xffffff
ret
 
Vesa20_getpixel32:
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier)
mov ecx, [LFB_BASE+edi]
and ecx, 0xffffff
ret
 
;*************************************************
 
virtual at esp
putimg:
.real_sx dd ?
.real_sy dd ?
.image_sx dd ?
.image_sy dd ?
.image_cx dd ?
.image_cy dd ?
.pti dd ?
.abs_cx dd ?
.abs_cy dd ?
.line_increment dd ?
.winmap_newline dd ?
.screen_newline dd ?
.stack_data = 4*12
.edi dd ?
.esi dd ?
.ebp dd ?
.esp dd ?
.ebx dd ?
.edx dd ?
.ecx dd ?
.eax dd ?
.ret_addr dd ?
.arg_0 dd ?
end virtual
 
align 16
; ebx = pointer
; ecx = size [x|y]
; edx = coordinates [x|y]
; ebp = pointer to 'get' function
; esi = pointer to 'init' function
; edi = parameter for 'get' function
 
vesa20_putimage:
pushad
call [_display.disable_mouse]
sub esp, putimg.stack_data
; save pointer to image
mov [putimg.pti], ebx
; unpack the size
mov eax, ecx
and ecx, 0xFFFF
shr eax, 16
mov [putimg.image_sx], eax
mov [putimg.image_sy], ecx
; unpack the coordinates
mov eax, edx
and edx, 0xFFFF
shr eax, 16
mov [putimg.image_cx], eax
mov [putimg.image_cy], edx
; calculate absolute (i.e. screen) coordinates
mov eax, [TASK_BASE]
mov ebx, [eax-twdw + WDATA.box.left]
add ebx, [putimg.image_cx]
mov [putimg.abs_cx], ebx
mov ebx, [eax-twdw + WDATA.box.top]
add ebx, [putimg.image_cy]
mov [putimg.abs_cy], ebx
; real_sx = MIN(wnd_sx-image_cx, image_sx);
mov ebx, [eax-twdw + WDATA.box.width] ; ebx = wnd_sx
; \begin{diamond}[20.08.2006]
; note that WDATA.box.width is one pixel less than real window x-size
inc ebx
; \end{diamond}[20.08.2006]
sub ebx, [putimg.image_cx]
ja @f
add esp, putimg.stack_data
popad
ret
@@:
cmp ebx, [putimg.image_sx]
jbe .end_x
mov ebx, [putimg.image_sx]
.end_x:
mov [putimg.real_sx], ebx
; init real_sy
mov ebx, [eax-twdw + WDATA.box.height] ; ebx = wnd_sy
; \begin{diamond}[20.08.2006]
inc ebx
; \end{diamond}[20.08.2006]
sub ebx, [putimg.image_cy]
ja @f
add esp, putimg.stack_data
popad
ret
@@:
cmp ebx, [putimg.image_sy]
jbe .end_y
mov ebx, [putimg.image_sy]
.end_y:
mov [putimg.real_sy], ebx
; line increment
mov eax, [putimg.image_sx]
mov ecx, [putimg.real_sx]
sub eax, ecx
;; imul eax, [putimg.source_bpp]
; lea eax, [eax + eax * 2]
call esi
add eax, [putimg.arg_0]
mov [putimg.line_increment], eax
; winmap new line increment
mov eax, [Screen_Max_X]
inc eax
sub eax, [putimg.real_sx]
mov [putimg.winmap_newline], eax
; screen new line increment
mov eax, [BytesPerScanLine]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul ecx, ebx
sub eax, ecx
mov [putimg.screen_newline], eax
; pointer to image
mov esi, [putimg.pti]
; pointer to screen
mov edx, [putimg.abs_cy]
imul edx, [BytesPerScanLine]
mov eax, [putimg.abs_cx]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul eax, ebx
add edx, eax
; pointer to pixel map
mov eax, [putimg.abs_cy]
imul eax, [Screen_Max_X]
add eax, [putimg.abs_cy]
add eax, [putimg.abs_cx]
add eax, [_WinMapAddress]
xchg eax, ebp
; get process number
mov ebx, [CURRENT_TASK]
cmp byte [ScreenBPP], 32
je put_image_end_32
;put_image_end_24:
mov edi, [putimg.real_sy]
align 4
.new_line:
mov ecx, [putimg.real_sx]
; push ebp edx
align 4
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
; mov eax, [esi] ; eax = RRBBGGRR
mov [LFB_BASE+edx], ax
shr eax, 16
mov [LFB_BASE+edx+2], al
.skip:
; add esi, 3 ;[putimg.source_bpp]
add edx, 3
inc ebp
dec ecx
jnz .new_x
; pop edx ebp
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline] ;[BytesPerScanLine]
add ebp, [putimg.winmap_newline] ;[Screen_Max_X]
; inc ebp
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
.finish:
add esp, putimg.stack_data
popad
ret
 
put_image_end_32:
mov edi, [putimg.real_sy]
align 4
.new_line:
mov ecx, [putimg.real_sx]
; push ebp edx
align 4
.new_x:
push [putimg.edi]
mov eax, [putimg.ebp+4]
call eax
cmp [ebp], bl
jne .skip
; mov eax, [esi] ; ecx = RRBBGGRR
mov [LFB_BASE+edx], eax
.skip:
; add esi, [putimg.source_bpp]
add edx, 4
inc ebp
dec ecx
jnz .new_x
; pop edx ebp
add esi, [putimg.line_increment]
add edx, [putimg.screen_newline] ;[BytesPerScanLine]
add ebp, [putimg.winmap_newline] ;[Screen_Max_X]
; inc ebp
cmp [putimg.ebp], putimage_get1bpp
jz .correct
cmp [putimg.ebp], putimage_get2bpp
jz .correct
cmp [putimg.ebp], putimage_get4bpp
jnz @f
.correct:
mov eax, [putimg.edi]
mov byte [eax], 80h
@@:
dec edi
jnz .new_line
.finish:
add esp, putimg.stack_data
popad
call VGA__putimage
mov [EGA_counter],1
ret
 
 
;*************************************************
align 4
__sys_putpixel:
 
; eax = x coordinate
; ebx = y coordinate
; ecx = ?? RR GG BB ; 0x01000000 negation
; edi = 0x00000001 force
 
;;; mov [novesachecksum], dword 0
pushad
cmp [Screen_Max_X], eax
jb .exit
cmp [Screen_Max_Y], ebx
jb .exit
test edi,1 ; force ?
jnz .forced
 
; not forced:
 
push eax
mov edx,[_display.width] ; screen x size
imul edx, ebx
add eax, [_WinMapAddress]
movzx edx, byte [eax+edx]
cmp edx, [CURRENT_TASK]
pop eax
jne .exit
 
.forced:
; check if negation
test ecx,0x01000000
jz .noneg
call getpixel
not ecx
mov [esp+32-8],ecx
.noneg:
; OK to set pixel
call dword [PUTPIXEL] ; call the real put_pixel function
.exit:
popad
ret
 
align 4
Vesa20_putpixel24:
; eax = x
; ebx = y
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [eax+eax*2] ; edi = x*3
mov eax, [esp+32-8+4]
mov [LFB_BASE+ebx+edi], ax
shr eax, 16
mov [LFB_BASE+ebx+edi+2], al
ret
 
 
align 4
Vesa20_putpixel32:
; eax = x
; ebx = y
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier
lea edi, [ebx+eax*4] ; edi = x*4+(y*y multiplier)
mov eax, [esp+32-8+4] ; eax = color
mov [LFB_BASE+edi], eax
ret
 
;*************************************************
 
;align 4
calculate_edi:
mov edi, ebx
imul edi, [Screen_Max_X]
add edi, ebx
add edi, eax
ret
 
;*************************************************
 
; DRAWLINE
 
align 4
__sys_draw_line:
; inc [mouse_pause]
call [_display.disable_mouse]
 
; draw a line
; eax = HIWORD = x1
; LOWORD = x2
; ebx = HIWORD = y1
; LOWORD = y2
; ecx = color
; edi = force ?
pusha
 
dl_x1 equ esp+20
dl_y1 equ esp+16
dl_x2 equ esp+12
dl_y2 equ esp+8
dl_dx equ esp+4
dl_dy equ esp+0
 
xor edx, edx ; clear edx
xor esi, esi ; unpack arguments
xor ebp, ebp
mov si, ax ; esi = x2
mov bp, bx ; ebp = y2
shr eax, 16 ; eax = x1
shr ebx, 16 ; ebx = y1
push eax ; save x1
push ebx ; save y1
push esi ; save x2
push ebp ; save y2
; checking x-axis...
sub esi, eax ; esi = x2-x1
push esi ; save y2-y1
jl .x2lx1 ; is x2 less than x1 ?
jg .no_vline ; x1 > x2 ?
mov edx, ebp ; else (if x1=x2)
call vline
push edx ; necessary to rightly restore stack frame at .exit
jmp .exit
.x2lx1:
neg esi ; get esi absolute value
.no_vline:
; checking y-axis...
sub ebp, ebx ; ebp = y2-y1
push ebp ; save y2-y1
jl .y2ly1 ; is y2 less than y1 ?
jg .no_hline ; y1 > y2 ?
mov edx, [dl_x2] ; else (if y1=y2)
call hline
jmp .exit
 
.y2ly1:
neg ebp ; get ebp absolute value
.no_hline:
cmp ebp, esi
jle .x_rules ; |y2-y1| < |x2-x1| ?
cmp [dl_y2], ebx ; make sure y1 is at the begining
jge .no_reverse1
neg dword [dl_dx]
mov edx, [dl_x2]
mov [dl_x2], eax
mov [dl_x1], edx
mov edx, [dl_y2]
mov [dl_y2], ebx
mov [dl_y1], edx
.no_reverse1:
mov eax, [dl_dx]
cdq ; extend eax sing to edx
shl eax, 16 ; using 16bit fix-point maths
idiv ebp ; eax = ((x2-x1)*65536)/(y2-y1)
mov edx, ebp ; edx = counter (number of pixels to draw)
mov ebp, 1 *65536 ; <<16 ; ebp = dy = 1.0
mov esi, eax ; esi = dx
jmp .y_rules
 
.x_rules:
cmp [dl_x2], eax ; make sure x1 is at the begining
jge .no_reverse2
neg dword [dl_dy]
mov edx, [dl_x2]
mov [dl_x2], eax
mov [dl_x1], edx
mov edx, [dl_y2]
mov [dl_y2], ebx
mov [dl_y1], edx
.no_reverse2:
xor edx, edx
mov eax, [dl_dy]
cdq ; extend eax sing to edx
shl eax, 16 ; using 16bit fix-point maths
idiv esi ; eax = ((y2-y1)*65536)/(x2-x1)
mov edx, esi ; edx = counter (number of pixels to draw)
mov esi, 1 *65536 ;<< 16 ; esi = dx = 1.0
mov ebp, eax ; ebp = dy
.y_rules:
mov eax, [dl_x1]
mov ebx, [dl_y1]
shl eax, 16
shl ebx, 16
align 4
.draw:
push eax ebx
shr eax, 16
shr ebx, 16
call [putpixel]
pop ebx eax
add ebx, ebp ; y = y+dy
add eax, esi ; x = x+dx
dec edx
jnz .draw
; force last drawn pixel to be at (x2,y2)
mov eax, [dl_x2]
mov ebx, [dl_y2]
call [putpixel]
.exit:
add esp, 6*4
popa
; dec [mouse_pause]
call [draw_pointer]
ret
 
 
hline:
; draw an horizontal line
; eax = x1
; edx = x2
; ebx = y
; ecx = color
; edi = force ?
push eax edx
cmp edx, eax ; make sure x2 is above x1
jge @f
xchg eax, edx
align 4
@@:
call [putpixel]
inc eax
cmp eax, edx
jle @b
pop edx eax
ret
 
 
vline:
; draw a vertical line
; eax = x
; ebx = y1
; edx = y2
; ecx = color
; edi = force ?
push ebx edx
cmp edx, ebx ; make sure y2 is above y1
jge @f
xchg ebx, edx
align 4
@@:
call [putpixel]
inc ebx
cmp ebx, edx
jle @b
pop edx ebx
ret
 
 
;*************************************************
 
 
virtual at esp
drbar:
.bar_sx dd ?
.bar_sy dd ?
.bar_cx dd ?
.bar_cy dd ?
.abs_cx dd ?
.abs_cy dd ?
.real_sx dd ?
.real_sy dd ?
.color dd ?
.line_inc_scr dd ?
.line_inc_map dd ?
.stack_data = 4*11
end virtual
 
align 4
; eax cx
; ebx cy
; ecx xe
; edx ye
; edi color
vesa20_drawbar:
pushad
call [_display.disable_mouse]
sub esp, drbar.stack_data
mov [drbar.color], edi
sub edx, ebx
jle .exit ;// mike.dld, 2005-01-29
sub ecx, eax
jle .exit ;// mike.dld, 2005-01-29
mov [drbar.bar_sy], edx
mov [drbar.bar_sx], ecx
mov [drbar.bar_cx], eax
mov [drbar.bar_cy], ebx
mov edi, [TASK_BASE]
add eax, [edi-twdw + WDATA.box.left] ; win_cx
add ebx, [edi-twdw + WDATA.box.top] ; win_cy
mov [drbar.abs_cx], eax
mov [drbar.abs_cy], ebx
; real_sx = MIN(wnd_sx-bar_cx, bar_sx);
mov ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx
; \begin{diamond}[20.08.2006]
; note that WDATA.box.width is one pixel less than real window x-size
inc ebx
; \end{diamond}[20.08.2006]
sub ebx, [drbar.bar_cx]
ja @f
.exit: ;// mike.dld, 2005-01-29
add esp, drbar.stack_data
popad
xor eax, eax
inc eax
ret
@@:
cmp ebx, [drbar.bar_sx]
jbe .end_x
mov ebx, [drbar.bar_sx]
.end_x:
mov [drbar.real_sx], ebx
; real_sy = MIN(wnd_sy-bar_cy, bar_sy);
mov ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy
; \begin{diamond}[20.08.2006]
inc ebx
; \end{diamond}
sub ebx, [drbar.bar_cy]
ja @f
add esp, drbar.stack_data
popad
xor eax, eax
inc eax
ret
@@:
cmp ebx, [drbar.bar_sy]
jbe .end_y
mov ebx, [drbar.bar_sy]
.end_y:
mov [drbar.real_sy], ebx
; line_inc_map
mov eax, [Screen_Max_X]
sub eax, [drbar.real_sx]
inc eax
mov [drbar.line_inc_map], eax
; line_inc_scr
mov eax, [drbar.real_sx]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul eax, ebx
neg eax
add eax, [BytesPerScanLine]
mov [drbar.line_inc_scr], eax
; pointer to screen
mov edx, [drbar.abs_cy]
imul edx, [BytesPerScanLine]
mov eax, [drbar.abs_cx]
; movzx ebx, byte [ScreenBPP]
; shr ebx, 3
imul eax, ebx
add edx, eax
; pointer to pixel map
mov eax, [drbar.abs_cy]
imul eax, [Screen_Max_X]
add eax, [drbar.abs_cy]
add eax, [drbar.abs_cx]
add eax, [_WinMapAddress]
xchg eax, ebp
; get process number
mov ebx, [CURRENT_TASK]
cmp byte [ScreenBPP], 24
jne draw_bar_end_32
draw_bar_end_24:
mov eax, [drbar.color] ;; BBGGRR00
mov bh, al ;; bh = BB
shr eax, 8 ;; eax = RRGG
; eax - color high RRGG
; bl - process num
; bh - color low BB
; ecx - temp
; edx - pointer to screen
; esi - counter
; edi - counter
mov esi, [drbar.real_sy]
align 4
.new_y:
mov edi, [drbar.real_sx]
align 4
.new_x:
cmp byte [ebp], bl
jne .skip
 
mov [LFB_BASE+edx], bh
mov [LFB_BASE+edx + 1], ax
.skip:
; add pixel
add edx, 3
inc ebp
dec edi
jnz .new_x
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
; <Ivan 15.10.04> drawing gradient bars
test eax, 0x00800000
jz @f
test bh, bh
jz @f
dec bh
@@:
; </Ivan 15.10.04>
dec esi
jnz .new_y
add esp, drbar.stack_data
popad
xor eax, eax
ret
 
draw_bar_end_32:
mov eax, [drbar.color] ;; BBGGRR00
mov esi, [drbar.real_sy]
align 4
.new_y:
mov edi, [drbar.real_sx]
align 4
.new_x:
cmp byte [ebp], bl
jne .skip
 
mov [LFB_BASE+edx], eax
.skip:
; add pixel
add edx, 4
inc ebp
dec edi
jnz .new_x
; add line
add edx, [drbar.line_inc_scr]
add ebp, [drbar.line_inc_map]
; <Ivan 15.10.04> drawing gradient bars
test eax, 0x80000000
jz @f
test al, al
jz @f
dec al
@@:
; </Ivan 15.10.04>
dec esi
jnz .new_y
add esp, drbar.stack_data
popad
call VGA_draw_bar
xor eax, eax
mov [EGA_counter],1
ret
 
align 4
vesa20_drawbackground_tiled:
call [_display.disable_mouse]
pushad
; External loop for all y from start to end
mov ebx, [draw_data+32+RECT.top] ; y start
dp2:
mov ebp, [draw_data+32+RECT.left] ; x start
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
; and LFB data (output for our function) [edi]
mov eax, [BytesPerScanLine]
mul ebx
xchg ebp, eax
add ebp, eax
add ebp, eax
add ebp, eax
cmp [ScreenBPP], byte 24 ; 24 or 32 bpp ? - x size
jz @f
add ebp, eax
@@:
add ebp, LFB_BASE
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
call calculate_edi
xchg edi, ebp
add ebp, [_WinMapAddress]
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
; 2) Calculate offset in background memory block
push eax
xor edx, edx
mov eax, ebx
div dword [BgrDataHeight] ; edx := y mod BgrDataHeight
pop eax
push eax
mov ecx, [BgrDataWidth]
mov esi, edx
imul esi, ecx ; esi := (y mod BgrDataHeight) * BgrDataWidth
xor edx, edx
div ecx ; edx := x mod BgrDataWidth
sub ecx, edx
add esi, edx ; esi := (y mod BgrDataHeight)*BgrDataWidth + (x mod BgrDataWidth)
pop eax
lea esi, [esi*3]
add esi, [img_background]
xor edx, edx
inc edx
; 3) Loop through redraw rectangle and copy background data
; Registers meaning:
; eax = x, ebx = y (screen coordinates)
; ecx = deltax - number of pixels left in current tile block
; edx = 1
; esi -> bgr memory, edi -> output
; ebp = offset in WinMapAddress
dp3:
cmp [ebp], dl
jnz nbgp
movsb
movsb
movsb
jmp @f
nbgp:
add esi, 3
add edi, 3
@@:
cmp [ScreenBPP], byte 25 ; 24 or 32 bpp?
sbb edi, -1 ; +1 for 32 bpp
; I do not use 'inc eax' because this is slightly slower then 'add eax,1'
add ebp, edx
add eax, edx
cmp eax, [draw_data+32+RECT.right]
ja dp4
sub ecx, edx
jnz dp3
; next tile block on x-axis
mov ecx, [BgrDataWidth]
sub esi, ecx
sub esi, ecx
sub esi, ecx
jmp dp3
dp4:
; next scan line
inc ebx
cmp ebx, [draw_data+32+RECT.bottom]
jbe dp2
popad
mov [EGA_counter], 1
call VGA_drawbackground
ret
 
; ----------
 
 
vesa20_drawbackground_stretch:
call [_display.disable_mouse]
pushad
; Helper variables
; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1)
mov eax, [BgrDataWidth]
dec eax
xor edx, edx
div dword [Screen_Max_X]
push eax ; high
xor eax, eax
div dword [Screen_Max_X]
push eax ; low
; the same for height
mov eax, [BgrDataHeight]
dec eax
xor edx, edx
div dword [Screen_Max_Y]
push eax ; high
xor eax, eax
div dword [Screen_Max_Y]
push eax ; low
; External loop for all y from start to end
mov ebx, [draw_data+32+RECT.top] ; y start
mov ebp, [draw_data+32+RECT.left] ; x start
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
; and LFB data (output for our function) [edi]
mov eax, [BytesPerScanLine]
mul ebx
xchg ebp, eax
add ebp, eax
add ebp, eax
add ebp, eax
cmp [ScreenBPP], byte 24 ; 24 or 32 bpp ? - x size
jz @f
add ebp, eax
@@:
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
call calculate_edi
xchg edi, ebp
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
push ebx
push eax
; 2) Calculate offset in background memory block
mov eax, ebx
imul ebx, dword [esp+12]
mul dword [esp+8]
add edx, ebx ; edx:eax = y * 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
mov esi, edx
imul esi, [BgrDataWidth]
push edx
push eax
mov eax, [esp+8]
mul dword [esp+28]
push eax
mov eax, [esp+12]
mul dword [esp+28]
add [esp], edx
pop edx ; edx:eax = x * 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
add esi, edx
lea esi, [esi*3]
add esi, [img_background]
push eax
push edx
push esi
; 3) Smooth horizontal
bgr_resmooth0:
mov ecx, [esp+8]
mov edx, [esp+4]
mov esi, [esp]
push edi
mov edi, bgr_cur_line
call smooth_line
bgr_resmooth1:
mov eax, [esp+16+4]
inc eax
cmp eax, [BgrDataHeight]
jae bgr.no2nd
mov ecx, [esp+8+4]
mov edx, [esp+4+4]
mov esi, [esp+4]
add esi, [BgrDataWidth]
add esi, [BgrDataWidth]
add esi, [BgrDataWidth]
mov edi, bgr_next_line
call smooth_line
bgr.no2nd:
pop edi
sdp3:
xor esi, esi
mov ecx, [esp+12]
; 4) Loop through redraw rectangle and copy background data
; Registers meaning:
; esi = offset in current line, edi -> output
; ebp = offset in WinMapAddress
; dword [esp] = offset in bgr data
; qword [esp+4] = x * 2^32 * (BgrDataWidth-1) / (ScreenWidth-1)
; qword [esp+12] = y * 2^32 * (BgrDataHeight-1) / (ScreenHeight-1)
; dword [esp+20] = x
; dword [esp+24] = y
; precalculated constants:
; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
sdp3a:
mov eax, [_WinMapAddress]
cmp [ebp+eax], byte 1
jnz snbgp
mov eax, [bgr_cur_line+esi]
test ecx, ecx
jz .novert
mov ebx, [bgr_next_line+esi]
call [overlapping_of_points_ptr]
.novert:
 
mov [LFB_BASE+edi], ax
shr eax, 16
 
mov [LFB_BASE+edi+2], al
snbgp:
cmp [ScreenBPP], byte 25
sbb edi, -4
add ebp, 1
mov eax, [esp+20]
add eax, 1
mov [esp+20], eax
add esi, 4
cmp eax, [draw_data+32+RECT.right]
jbe sdp3a
sdp4:
; next y
mov ebx, [esp+24]
add ebx, 1
mov [esp+24], ebx
cmp ebx, [draw_data+32+RECT.bottom]
ja sdpdone
; advance edi, ebp to next scan line
sub eax, [draw_data+32+RECT.left]
sub ebp, eax
add ebp, [Screen_Max_X]
add ebp, 1
sub edi, eax
sub edi, eax
sub edi, eax
cmp [ScreenBPP], byte 24
jz @f
sub edi, eax
@@:
add edi, [BytesPerScanLine]
; restore ecx,edx; advance esi to next background line
mov eax, [esp+28]
mov ebx, [esp+32]
add [esp+12], eax
mov eax, [esp+16]
adc [esp+16], ebx
sub eax, [esp+16]
mov ebx, eax
lea eax, [eax*3]
imul eax, [BgrDataWidth]
sub [esp], eax
mov eax, [draw_data+32+RECT.left]
mov [esp+20], eax
test ebx, ebx
jz sdp3
cmp ebx, -1
jnz bgr_resmooth0
push edi
mov esi, bgr_next_line
mov edi, bgr_cur_line
mov ecx, [Screen_Max_X]
inc ecx
rep movsd
jmp bgr_resmooth1
sdpdone:
add esp, 44
popad
mov [EGA_counter],1
call VGA_drawbackground
ret
 
uglobal
align 4
bgr_cur_line rd 1920 ; maximum width of screen
bgr_next_line rd 1920
endg
 
smooth_line:
mov al, [esi+2]
shl eax, 16
mov ax, [esi]
test ecx, ecx
jz @f
mov ebx, [esi+2]
shr ebx, 8
call [overlapping_of_points_ptr]
@@:
stosd
mov eax, [esp+20+8]
add eax, 1
mov [esp+20+8], eax
cmp eax, [draw_data+32+RECT.right]
ja @f
add ecx, [esp+36+8]
mov eax, edx
adc edx, [esp+40+8]
sub eax, edx
lea eax, [eax*3]
sub esi, eax
jmp smooth_line
@@:
mov eax, [draw_data+32+RECT.left]
mov [esp+20+8], eax
ret
 
align 16
overlapping_of_points:
if 0
; this version of procedure works, but is slower than next version
push ecx edx
mov edx, eax
push esi
shr ecx, 24
mov esi, ecx
mov ecx, ebx
movzx ebx, dl
movzx eax, cl
sub eax, ebx
movzx ebx, dh
imul eax, esi
add dl, ah
movzx eax, ch
sub eax, ebx
imul eax, esi
add dh, ah
ror ecx, 16
ror edx, 16
movzx eax, cl
movzx ebx, dl
sub eax, ebx
imul eax, esi
pop esi
add dl, ah
mov eax, edx
pop edx
ror eax, 16
pop ecx
ret
else
push ecx edx
mov edx, eax
push esi
shr ecx, 26
mov esi, ecx
mov ecx, ebx
shl esi, 9
movzx ebx, dl
movzx eax, cl
sub eax, ebx
movzx ebx, dh
add dl, [BgrAuxTable+(eax+0x100)+esi]
movzx eax, ch
sub eax, ebx
add dh, [BgrAuxTable+(eax+0x100)+esi]
ror ecx, 16
ror edx, 16
movzx eax, cl
movzx ebx, dl
sub eax, ebx
add dl, [BgrAuxTable+(eax+0x100)+esi]
pop esi
mov eax, edx
pop edx
ror eax, 16
pop ecx
ret
end if
 
iglobal
align 4
overlapping_of_points_ptr dd overlapping_of_points
endg
 
init_background:
mov edi, BgrAuxTable
xor edx, edx
.loop2:
mov eax, edx
shl eax, 8
neg eax
mov ecx, 0x200
.loop1:
mov byte [edi], ah
inc edi
add eax, edx
loop .loop1
add dl, 4
jnz .loop2
test byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8)
jz @f
mov [overlapping_of_points_ptr], overlapping_of_points_mmx
@@:
ret
 
align 16
overlapping_of_points_mmx:
movd mm0, eax
movd mm4, eax
movd mm1, ebx
pxor mm2, mm2
punpcklbw mm0, mm2
punpcklbw mm1, mm2
psubw mm1, mm0
movd mm3, ecx
psrld mm3, 24
packuswb mm3, mm3
packuswb mm3, mm3
pmullw mm1, mm3
psrlw mm1, 8
packuswb mm1, mm2
paddb mm4, mm1
movd eax, mm4
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/video/vesa12.inc
0,0 → 1,1004
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; VESA12.INC ;;
;; ;;
;; Vesa 1.2 functions for MenuetOS ;;
;; ;;
;; Copyright 2002 Ville Turjanmaa ;;
;; ;;
;; quickcode@mail.ru - bankswitch for S3 cards ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
TRIDENT equ 0
S3_VIDEO equ 0
INTEL_VIDEO equ 0
 
if TRIDENT
if S3_VIDEO or INTEL_VIDEO
stop
end if
end if
 
if S3_VIDEO
if TRIDENT or INTEL_VIDEO
stop
end if
end if
 
if INTEL_VIDEO
if S3_VIDEO or TRIDENT
stop
end if
end if
 
 
; A complete video driver should include the following types of function
;
; Putpixel
; Getpixel
;
; Drawimage
; Drawbar
;
; Drawbackground
;
;
; Modifying the set_bank -function is mostly enough
; for different Vesa 1.2 setups.
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
; set_bank for Trident videocards, work on Trident 9440
; modified by Mario79
 
if TRIDENT
set_bank:
pushfd
cli
cmp al,[BANK_RW]
je .retsb
 
mov [BANK_RW],al
push dx
mov dx,3D8h
out dx,al
pop dx
.retsb:
popfd
ret
end if
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
; set_bank for S3 videocards, work on S3 ViRGE PCI (325)
; modified by kmeaw
 
if S3_VIDEO
set_bank:
pushfd
cli
cmp al,[BANK_RW]
je .retsb
 
mov [BANK_RW],al
push ax
push dx
push cx
mov cl, al
mov dx, 0x3D4
mov al, 0x38
out dx, al ;CR38 Register Lock 1 ;Note: Traditionally 48h is used to
;unlock and 00h to lock
inc dx
mov al, 0x48
out dx, al ;3d5 -?
dec dx
mov al, 0x31
out dx, al ;CR31 Memory Configuration Register
;0 Enable Base Address Offset (CPUA BASE). Enables bank operation if set, ;disables if clear.
;4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index 51h,
;for the 864/964 see index 69h.
 
inc dx
in al, dx
dec dx
mov ah, al
mov al, 0x31
out dx, ax
mov al, ah
or al, 9
inc dx
out dx, al
dec dx
mov al, 0x35
out dx, al ;CR35 CRT Register Lock
inc dx
in al, dx
dec dx
and al, 0xF0
mov ch, cl
and ch, 0x0F
or ch, al
mov al, 0x35
out dx, al
inc dx
mov al, ch
out dx, ax
dec dx
mov al, 0x51 ;Extended System Control 2 Register
out dx, al
inc dx
in al, dx
dec dx
and al, 0xF3
shr cl, 2
and cl, 0x0C
or cl, al
mov al, 0x51
out dx, al
inc dx
mov al, cl
out dx, al
dec dx
mov al, 0x38
out dx, al
inc dx
xor al, al
out dx, al
dec dx
pop cx
pop dx
pop ax
.retsb:
popfd
ret
end if
 
;Set bank function for Intel 810/815 chipsets
; *****Modified by Protopopius, Russia.*****
; ********* http://menuetos.hut.ru **************
; ************************************************
 
if INTEL_VIDEO
 
set_bank:
pushfd
cli
 
cmp al,[BANK_RW]
je .retsb
 
mov [BANK_RW],al
push ax
push dx
mov dx,3CEh
mov ah,al ; Save value for later use
mov al,10h ; Index GR10 (Address Mapping)
out dx,al ; Select GR10
inc dl
mov al,3 ; Set bits 0 and 1 (Enable linear page mapping)
out dx,al ; Write value
dec dl
mov al,11h ; Index GR11 (Page Selector)
out dx,al ; Select GR11
inc dl
mov al,ah ; Write address
out dx,al ; Write the value
pop dx
pop ax
.retsb:
popfd
ret
end if
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
 
if (TRIDENT or S3_VIDEO or INTEL_VIDEO)
else
set_bank:
pushfd
cli
 
cmp al,[BANK_RW]
je .retsb
 
mov [BANK_RW],al
push ax
push dx
mov ah,al
mov dx,0x03D4
mov al,0x39
out dx,al
inc dl
mov al,0xA5
out dx,al
dec dl
mov al,6Ah
out dx,al
inc dl
mov al,ah
out dx,al
dec dl
mov al,0x39
out dx,al
inc dl
mov al,0x5A
out dx,al
dec dl
pop dx
pop ax
 
.retsb:
popfd
ret
end if
 
vesa12_drawbackground:
 
call [_display.disable_mouse]
 
push eax
push ebx
push ecx
push edx
 
xor edx,edx
mov eax,dword[BgrDataWidth]
mov ebx,dword[BgrDataHeight]
mul ebx
mov ebx,3
mul ebx
mov [imax],eax
mov eax,[draw_data+32+RECT.left]
mov ebx,[draw_data+32+RECT.top]
xor edi,edi ;no force
 
v12dp3:
 
push eax
push ebx
 
cmp [BgrDrawMode],dword 1 ; tiled background
jne no_vesa12_tiled_bgr
 
push edx
 
xor edx,edx
div dword [BgrDataWidth]
 
push edx
mov eax,ebx
xor edx,edx
div dword [BgrDataHeight]
mov ebx,edx
pop eax
 
pop edx
 
no_vesa12_tiled_bgr:
 
cmp [BgrDrawMode],dword 2 ; stretched background
jne no_vesa12_stretched_bgr
 
push edx
 
mul dword [BgrDataWidth]
mov ecx,[Screen_Max_X]
inc ecx
div ecx
 
push eax
mov eax,ebx
mul dword [BgrDataHeight]
mov ecx,[Screen_Max_Y]
inc ecx
div ecx
mov ebx,eax
pop eax
 
pop edx
 
no_vesa12_stretched_bgr:
 
 
mov esi,ebx
imul esi, dword [BgrDataWidth]
add esi,eax
lea esi,[esi*3]
add esi,[img_background] ;IMG_BACKGROUND
pop ebx
pop eax
 
v12di4:
 
mov cl,[esi+2]
shl ecx,16
mov cx,[esi]
pusha
mov esi,eax
mov edi,ebx
mov eax,[Screen_Max_X]
add eax,1
mul ebx
add eax, [_WinMapAddress]
cmp [eax+esi],byte 1
jnz v12nbgp
mov eax,[BytesPerScanLine]
mov ebx,edi
mul ebx
add eax, esi
lea eax, [VGABasePtr+eax+esi*2]
cmp [ScreenBPP],byte 24
jz v12bgl3
add eax,esi
 
v12bgl3:
 
push ebx
push eax
 
sub eax,VGABasePtr
 
shr eax,16
call set_bank
pop eax
and eax,65535
add eax,VGABasePtr
pop ebx
 
mov [eax],cx
add eax,2
shr ecx,16
mov [eax],cl
sti
 
v12nbgp:
 
popa
add esi,3
inc eax
cmp eax,[draw_data+32+RECT.right]
jg v12nodp31
jmp v12dp3
 
v12nodp31:
 
mov eax,[draw_data+32+RECT.left]
inc ebx
cmp ebx,[draw_data+32+RECT.bottom]
jg v12dp4
jmp v12dp3
 
v12dp4:
 
pop edx
pop ecx
pop ebx
pop eax
ret
 
 
vesa12_drawbar:
 
call [_display.disable_mouse]
 
;; mov [novesachecksum],dword 0
sub edx,ebx
sub ecx,eax
push esi
push edi
push eax
push ebx
push ecx
push edx
mov ecx,[TASK_BASE]
add eax,[ecx-twdw+WDATA.box.left]
add ebx,[ecx-twdw+WDATA.box.top]
push eax
mov eax,ebx ; y
mov ebx,[BytesPerScanLine]
mul ebx
pop ecx
add eax,ecx ; x
add eax,ecx
add eax,ecx
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x start
jz dbpi2412
add eax,ecx
 
dbpi2412:
 
add eax,VGABasePtr
mov edi,eax
 
; x size
 
mov eax,[esp+4] ; [esp+6]
mov ecx,eax
add ecx,eax
add ecx,eax
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz dbpi24312
add ecx,eax
 
dbpi24312:
 
mov ebx,[esp+0]
 
; check limits ?
 
push eax
push ecx
mov eax,[TASK_BASE]
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.left]
cmp ecx,0
jnz dbcblimitlset12
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.top]
cmp ecx,0
jnz dbcblimitlset12
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.right]
cmp ecx,[Screen_Max_X]
jnz dbcblimitlset12
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.bottom]
cmp ecx,[Screen_Max_Y]
jnz dbcblimitlset12
pop ecx
pop eax
push dword 0
jmp dbcblimitlno12
 
dbcblimitlset12:
 
pop ecx
pop eax
push dword 1
 
dbcblimitlno12:
 
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ?
jz dbpi24bit12
jmp dbpi32bit12
 
 
; DRAWBAR 24 BBP
 
 
dbpi24bit12:
 
push eax
push ebx
push edx
mov eax,ecx
mov ebx,3
div ebx
mov ecx,eax
pop edx
pop ebx
pop eax
cld
 
dbnewpi12:
 
push ebx
push edi
push ecx
 
xor edx,edx
mov eax,edi
sub eax,VGABasePtr
mov ebx,3
div ebx
add eax, [_WinMapAddress]
mov ebx,[CURRENT_TASK]
cld
 
dbnp2412:
 
mov dl,[eax]
push eax
push ecx
cmp dl,bl
jnz dbimp24no12
cmp [esp+5*4],dword 0
jz dbimp24yes12
; call dbcplimit
; jnz dbimp24no12
 
dbimp24yes12:
 
push edi
mov eax,edi
sub eax,VGABasePtr
shr eax,16
call set_bank
and edi,0xffff
add edi,VGABasePtr
mov eax,[esp+8+3*4+16+4+4]
stosw
shr eax,16
stosb
sti
pop edi
add edi,3
pop ecx
pop eax
inc eax
loop dbnp2412
jmp dbnp24d12
 
dbimp24no12:
 
pop ecx
pop eax
cld
add edi,3
inc eax
loop dbnp2412
 
dbnp24d12:
 
mov eax,[esp+3*4+16+4]
test eax,0x80000000
jz nodbgl2412
cmp al,0
jz nodbgl2412
dec eax
mov [esp+3*4+16+4],eax
 
nodbgl2412:
 
pop ecx
pop edi
pop ebx
add edi,[BytesPerScanLine]
dec ebx
jz dbnonewpi12
jmp dbnewpi12
 
dbnonewpi12:
 
add esp,7*4
 
ret
 
 
; DRAWBAR 32 BBP
 
 
dbpi32bit12:
 
cld
shr ecx,2
 
dbnewpi3212:
 
push ebx
push edi
push ecx
 
mov eax,edi
sub eax,VGABasePtr
shr eax,2
add eax, [_WinMapAddress]
mov ebx,[CURRENT_TASK]
cld
 
dbnp3212:
 
mov dl,[eax]
push eax
push ecx
cmp dl,bl
jnz dbimp32no12
cmp [esp+5*4],dword 0
jz dbimp32yes12
; call dbcplimit
; jnz dbimp32no12
 
dbimp32yes12:
 
push edi
mov eax,edi
sub eax,VGABasePtr
shr eax,16
call set_bank
and edi,0xffff
add edi,VGABasePtr
mov eax,[esp+8+3*4+16+4+4]
stosw
shr eax,16
stosb
sti
pop edi
add edi,4
inc ebp
pop ecx
pop eax
inc eax
loop dbnp3212
jmp dbnp32d12
 
dbimp32no12:
 
pop ecx
pop eax
inc eax
add edi,4
inc ebp
loop dbnp3212
 
dbnp32d12:
 
mov eax,[esp+12+16+4]
test eax,0x80000000
jz nodbgl3212
cmp al,0
jz nodbgl3212
dec eax
mov [esp+12+16+4],eax
 
nodbgl3212:
 
pop ecx
pop edi
pop ebx
add edi,[BytesPerScanLine]
dec ebx
jz nodbnewpi3212
jmp dbnewpi3212
 
nodbnewpi3212:
 
add esp,7*4
ret
 
 
Vesa12_putpixel24:
 
mov edi,eax ; x
mov eax,ebx ; y
lea edi,[edi+edi*2]
mov ebx,[BytesPerScanLine]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,VGABasePtr
mov eax,[esp+28]
stosw
shr eax,16
mov [edi],al
sti
ret
 
 
 
Vesa12_putpixel32:
 
mov edi,eax ; x
mov eax,ebx ; y
shl edi,2
mov ebx,[BytesPerScanLine]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,VGABasePtr
mov ecx,[esp+28]
mov [edi],ecx
sti
ret
 
 
Vesa12_getpixel24:
 
mov edi,eax ; x
mov eax,ebx ; y
lea edi,[edi+edi*2]
mov ebx,[BytesPerScanLine]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,VGABasePtr
mov ecx,[edi]
and ecx,255*256*256+255*256+255
sti
ret
 
 
Vesa12_getpixel32:
 
mov edi,eax ; x
mov eax,ebx ; y
shl edi,2
mov ebx,[BytesPerScanLine]
xor edx,edx
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,VGABasePtr
mov ecx,[edi]
and ecx,255*256*256+255*256+255
sti
 
ret
 
 
 
vesa12_putimage:
; ebx = pointer to image
; ecx = size [x|y]
; edx = coordinates [x|y]
; ebp = pointer to 'get' function
; esi = pointer to 'init' function
; edi = parameter for 'get' function
 
; mov ebx,image
; mov ecx,320*65536+240
; mov edx,20*65536+20
 
call [_display.disable_mouse]
 
mov [novesachecksum],dword 0
push esi
push edi
push eax
push ebx
push ecx
push edx
movzx eax,word [esp+2]
movzx ebx,word [esp+0]
mov ecx,[TASK_BASE]
add eax,[ecx-twdw+WDATA.box.left]
add ebx,[ecx-twdw+WDATA.box.top]
push eax
mov eax,ebx ; y
mul dword [BytesPerScanLine]
pop ecx
add eax,ecx ; x
add eax,ecx
add eax,ecx
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x start
jz pi2412
add eax,ecx
 
pi2412:
 
add eax,VGABasePtr
mov edi,eax
 
; x size
 
movzx ecx,word [esp+6]
 
mov esi,[esp+8]
movzx ebx,word [esp+4]
 
; check limits while draw ?
 
push ecx
mov eax,[TASK_BASE]
cmp dword [eax+draw_data-CURRENT_TASK+RECT.left], 0
jnz dbcblimitlset212
cmp dword [eax+draw_data-CURRENT_TASK+RECT.top], 0
jnz dbcblimitlset212
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.right]
cmp ecx,[Screen_Max_X]
jnz dbcblimitlset212
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.bottom]
cmp ecx,[Screen_Max_Y]
jnz dbcblimitlset212
pop ecx
push 0
jmp dbcblimitlno212
 
dbcblimitlset212:
 
pop ecx
push 1
 
dbcblimitlno212:
 
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ?
jnz pi32bit12
 
pi24bit12:
 
newpi12:
 
push edi
push ecx
push ebx
 
mov edx,edi
sub edx,VGABasePtr
mov ebx,3
div ebx
add edx, [_WinMapAddress]
mov ebx,[CURRENT_TASK]
mov bh,[esp+4*3]
 
np2412:
 
cmp bl,[edx]
jnz imp24no12
; mov eax,[esi]
push dword [esp+4*3+20]
call ebp
; cmp bh,0
; jz imp24yes12
; call dbcplimit
; jnz imp24no12
 
imp24yes12:
 
push edi
push eax
mov eax,edi
sub eax,VGABasePtr
shr eax,16
call set_bank
pop eax
and edi,0xffff
add edi,VGABasePtr
mov [edi],ax
shr eax,16
mov [edi+2],al
pop edi
 
imp24no12:
 
inc edx
; add esi,3
add edi,3
dec ecx
jnz np2412
 
np24d12:
 
pop ebx
pop ecx
pop edi
 
add edi,[BytesPerScanLine]
add esi,[esp+32]
cmp ebp,putimage_get1bpp
jz .correct
cmp ebp,putimage_get2bpp
jz .correct
cmp ebp,putimage_get4bpp
jnz @f
.correct:
mov eax,[esp+20]
mov byte[eax],80h
@@:
dec ebx
jnz newpi12
 
nonewpi12:
 
pop eax edx ecx ebx eax edi esi
xor eax, eax
ret
 
 
pi32bit12:
 
newpi3212:
 
push edi
push ecx
push ebx
 
mov edx,edi
sub edx,VGABasePtr
shr edx,2
add edx, [_WinMapAddress]
mov ebx,[CURRENT_TASK]
mov bh,[esp+4*3]
 
np3212:
 
cmp bl,[edx]
jnz imp32no12
; mov eax,[esi]
push dword [esp+4*3+20]
call ebp
; cmp bh,0
; jz imp32yes12
; call dbcplimit
; jnz imp32no12
 
imp32yes12:
 
push edi
push eax
mov eax,edi
sub eax,VGABasePtr
shr eax,16
call set_bank
pop eax
and edi,0xffff
mov [edi+VGABasePtr],eax
pop edi
 
imp32no12:
 
inc edx
; add esi,3
add edi,4
dec ecx
jnz np3212
 
np32d12:
 
pop ebx
pop ecx
pop edi
 
add edi,[BytesPerScanLine]
cmp ebp,putimage_get1bpp
jz .correct
cmp ebp,putimage_get2bpp
jz .correct
cmp ebp,putimage_get4bpp
jnz @f
.correct:
mov eax,[esp+20]
mov byte[eax],80h
@@:
dec ebx
jnz newpi3212
 
nonewpi3212:
 
pop eax edx ecx ebx eax edi esi
xor eax, eax
ret
 
 
vesa12_read_screen_pixel:
 
and eax,0x3FFFFF
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ?
jz v12rsp24
mov edi,eax
shl edi,2
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,VGABasePtr
mov eax,[edi]
and eax,0x00ffffff
ret
v12rsp24:
 
imul eax,3
mov edi,eax
shr eax,16
call set_bank
and edi,65535
add edi,VGABasePtr
mov eax,[edi]
and eax,0x00ffffff
ret
 
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/video/cursors.inc
0,0 → 1,806
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
LOAD_FROM_FILE equ 0
LOAD_FROM_MEM equ 1
LOAD_INDIRECT equ 2
LOAD_SYSTEM equ 3
 
struc BITMAPINFOHEADER {
.biSize dd ? ; DWORD
.biWidth dd ? ; LONG
.biHeight dd ? ; LONG
.biPlanes dw ? ; WORD
.biBitCount dw ? ; WORD
.biCompression dd ? ; DWORD
.biSizeImage dd ? ; DWORD
.biXPelsPerMeter dd ? ; LONG
.biYPelsPerMeter dd ? ; LONG
.biClrUsed dd ? ; DWORD
.biClrImportant dd ? ; DWORD
}
 
virtual at 0
BI BITMAPINFOHEADER
end virtual
 
align 4
proc init_cursor stdcall, dst:dword, src:dword
locals
rBase dd ?
pQuad dd ?
pBits dd ?
pAnd dd ?
width dd ?
height dd ?
counter dd ?
endl
 
mov esi, [src]
add esi,[esi+18]
mov eax,esi
 
cmp [esi+BI.biBitCount], 24
je .img_24
cmp [esi+BI.biBitCount], 8
je .img_8
cmp [esi+BI.biBitCount], 4
je .img_4
 
.img_2:
add eax, [esi]
mov [pQuad],eax
add eax,8
mov [pBits],eax
add eax, 128
mov [pAnd],eax
mov eax,[esi+4]
mov [width],eax
mov ebx,[esi+8]
shr ebx,1
mov [height],ebx
 
mov edi, [dst]
add edi, 32*31*4
mov [rBase],edi
 
mov esi,[pQuad]
.l21:
mov ebx, [pBits]
mov ebx, [ebx]
bswap ebx
mov eax, [pAnd]
mov eax, [eax]
bswap eax
mov [counter], 32
@@:
xor edx, edx
shl eax,1
setc dl
dec edx
 
xor ecx, ecx
shl ebx,1
setc cl
mov ecx, [esi+ecx*4]
and ecx, edx
and edx, 0xFF000000
or edx, ecx
mov [edi], edx
 
add edi, 4
dec [counter]
jnz @B
 
add [pBits], 4
add [pAnd], 4
mov edi,[rBase]
sub edi,128
mov [rBase],edi
sub [height],1
jnz .l21
ret
 
.img_4:
add eax, [esi]
mov [pQuad],eax
add eax,64
mov [pBits],eax
add eax, 0x200
mov [pAnd],eax
mov eax,[esi+4]
mov [width],eax
mov ebx,[esi+8]
shr ebx,1
mov [height],ebx
 
mov edi, [dst]
add edi, 32*31*4
mov [rBase],edi
 
mov esi,[pQuad]
mov ebx, [pBits]
.l4:
mov eax, [pAnd]
mov eax, [eax]
bswap eax
mov [counter], 16
@@:
xor edx, edx
shl eax,1
setc dl
dec edx
 
movzx ecx, byte [ebx]
and cl, 0xF0
shr ecx, 2
mov ecx, [esi+ecx]
and ecx, edx
and edx, 0xFF000000
or edx, ecx
mov [edi], edx
 
xor edx, edx
shl eax,1
setc dl
dec edx
 
movzx ecx, byte [ebx]
and cl, 0x0F
mov ecx, [esi+ecx*4]
and ecx, edx
and edx, 0xFF000000
or edx, ecx
mov [edi+4], edx
 
inc ebx
add edi, 8
dec [counter]
jnz @B
 
add [pAnd], 4
mov edi,[rBase]
sub edi,128
mov [rBase],edi
sub [height],1
jnz .l4
ret
.img_8:
add eax, [esi]
mov [pQuad],eax
add eax,1024
mov [pBits],eax
add eax, 1024
mov [pAnd],eax
mov eax,[esi+4]
mov [width],eax
mov ebx,[esi+8]
shr ebx,1
mov [height],ebx
 
mov edi, [dst]
add edi, 32*31*4
mov [rBase],edi
 
mov esi,[pQuad]
mov ebx, [pBits]
.l81:
mov eax, [pAnd]
mov eax, [eax]
bswap eax
mov [counter], 32
@@:
xor edx, edx
shl eax,1
setc dl
dec edx
 
movzx ecx, byte [ebx]
mov ecx, [esi+ecx*4]
and ecx, edx
and edx, 0xFF000000
or edx, ecx
mov [edi], edx
 
inc ebx
add edi, 4
dec [counter]
jnz @B
 
add [pAnd], 4
mov edi,[rBase]
sub edi,128
mov [rBase],edi
sub [height],1
jnz .l81
ret
.img_24:
add eax, [esi]
mov [pQuad],eax
add eax, 0xC00
mov [pAnd],eax
mov eax,[esi+BI.biWidth]
mov [width],eax
mov ebx,[esi+BI.biHeight]
shr ebx,1
mov [height],ebx
 
mov edi, [dst]
add edi, 32*31*4
mov [rBase],edi
 
mov esi,[pAnd]
mov ebx, [pQuad]
.row_24:
mov eax, [esi]
bswap eax
mov [counter], 32
@@:
xor edx, edx
shl eax,1
setc dl
dec edx
 
mov ecx, [ebx]
and ecx, 0x00FFFFFF
and ecx, edx
and edx, 0xFF000000
or edx, ecx
mov [edi], edx
add ebx, 3
add edi, 4
dec [counter]
jnz @B
 
add esi, 4
mov edi,[rBase]
sub edi,128
mov [rBase],edi
sub [height],1
jnz .row_24
ret
endp
 
align 4
proc set_cursor stdcall, hcursor:dword
mov eax, [hcursor]
cmp [eax+CURSOR.magic], 'CURS'
jne .fail
; cmp [eax+CURSOR.size], CURSOR_SIZE
; jne .fail
mov ebx, [current_slot]
xchg eax, [ebx+APPDATA.cursor]
ret
.fail:
mov eax, [def_cursor]
mov ebx, [current_slot]
xchg eax, [ebx+APPDATA.cursor]
ret
endp
 
; param
; eax= pid
; ebx= src
; ecx= flags
 
create_cursor:
.src equ esp
.flags equ esp+4
.hcursor equ esp+8
 
sub esp, 4 ;space for .hcursor
push ecx
push ebx
 
mov ebx, eax
mov eax, CURSOR.sizeof
call create_kernel_object
test eax, eax
jz .fail
 
mov [.hcursor],eax
 
xor ebx, ebx
mov [eax+CURSOR.magic], 'CURS'
mov [eax+CURSOR.destroy], destroy_cursor
mov [eax+CURSOR.hot_x], ebx
mov [eax+CURSOR.hot_y], ebx
 
stdcall kernel_alloc, 0x1000
test eax, eax
jz .fail
 
mov edi, [.hcursor]
mov [edi+CURSOR.base], eax
 
mov esi, [.src]
mov ebx, [.flags]
cmp bx, LOAD_INDIRECT
je .indirect
 
movzx ecx, word [esi+10]
movzx edx, word [esi+12]
mov [edi+CURSOR.hot_x], ecx
mov [edi+CURSOR.hot_y], edx
 
stdcall init_cursor, eax, esi
 
mov eax, [.hcursor]
lea eax, [eax+CURSOR.list_next]
lea edx, [_display.cr_list.next]
 
pushfd
cli
mov ecx, [edx]
 
mov [eax], ecx
mov [eax+4], edx
 
mov [ecx+4], eax
mov [edx], eax
popfd
 
mov eax, [.hcursor]
.check_hw:
cmp [_display.init_cursor], 0
je .fail
 
push eax
call [_display.init_cursor]
add esp, 4
 
mov eax, [.hcursor]
.fail:
add esp, 12
ret
.indirect:
shr ebx, 16
movzx ecx, bh
movzx edx, bl
mov [eax+CURSOR.hot_x], ecx
mov [eax+CURSOR.hot_y], edx
 
xchg edi, eax
mov ecx, 1024
cld
rep movsd
jmp .check_hw
 
align 4
proc load_cursor stdcall, src:dword, flags:dword
locals
handle dd ?
endl
 
xor eax, eax
cmp [create_cursor], eax
je .fail2
 
mov [handle], eax
cmp word [flags], LOAD_FROM_FILE
jne @F
 
stdcall load_file, [src]
test eax, eax
jz .fail
mov [src], eax
@@:
push ebx
push esi
push edi
 
mov eax, [CURRENT_TASK]
shl eax, 5
mov eax, [CURRENT_TASK+eax+4]
mov ebx, [src]
mov ecx, [flags]
call create_cursor ;eax, ebx, ecx
mov [handle], eax
 
cmp word [flags], LOAD_FROM_FILE
jne .exit
stdcall kernel_free, [src]
.exit:
pop edi
pop esi
pop ebx
.fail:
mov eax, [handle]
.fail2:
ret
endp
 
align 4
proc delete_cursor stdcall, hcursor:dword
locals
hsrv dd ?
io_code dd ?
input dd ?
inp_size dd ?
output dd ?
out_size dd ?
endl
 
mov esi, [hcursor]
cmp [esi+CURSOR.magic], 'CURS'
jne .fail
 
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov ebx, [CURRENT_TASK+ebx+4]
cmp ebx, [esi+CURSOR.pid]
jne .fail
 
mov ebx, [current_slot]
cmp esi, [ebx+APPDATA.cursor]
jne @F
mov eax, [def_cursor]
mov [ebx+APPDATA.cursor], eax
@@:
mov eax, [hcursor]
call [eax+APPOBJ.destroy]
.fail:
ret
endp
 
; param
; eax= cursor
 
align 4
destroy_cursor:
 
push eax
stdcall kernel_free, [eax+CURSOR.base]
pop eax
 
call destroy_kernel_object
ret
 
align 4
select_cursor:
mov eax, [esp+4]
mov [_display.cursor], eax
ret 4
 
align 4
proc restore_24 stdcall, x:dword, y:dword
 
push ebx
 
mov ebx, [cur_saved_base]
mov edx, [cur.h]
test edx, edx
jz .ret
 
push esi
push edi
 
mov esi, cur_saved_data
mov ecx, [cur.w]
lea ecx, [ecx+ecx*2]
push ecx
@@:
mov edi, ebx
add ebx, [BytesPerScanLine]
 
mov ecx, [esp]
rep movsb
dec edx
jnz @B
 
pop ecx
pop edi
pop esi
.ret:
pop ebx
ret
endp
 
align 4
proc restore_32 stdcall, x:dword, y:dword
 
push ebx
 
mov ebx, [cur_saved_base]
mov edx, [cur.h]
test edx, edx
jz .ret
 
push esi
push edi
 
mov esi, cur_saved_data
@@:
mov edi, ebx
add ebx, [BytesPerScanLine]
 
mov ecx, [cur.w]
rep movsd
dec edx
jnz @B
 
pop edi
.ret:
pop esi
pop ebx
ret
endp
 
align 4
proc move_cursor_24 stdcall, hcursor:dword, x:dword, y:dword
locals
h dd ?
_dx dd ?
_dy dd ?
endl
 
mov esi, [hcursor]
mov ecx, [x]
mov eax, [y]
mov ebx, [BytesPerScanLine]
 
xor edx, edx
sub ecx, [esi+CURSOR.hot_x]
lea ebx, [ecx+32-1]
mov [x], ecx
sets dl
dec edx
and ecx, edx ;clip x to 0<=x
mov [cur.left], ecx
mov edi, ecx
sub edi, [x]
mov [_dx], edi
 
xor edx, edx
sub eax, [esi+CURSOR.hot_y]
lea edi, [eax+32-1]
mov [y], eax
sets dl
dec edx
and eax, edx ;clip y to 0<=y
mov [cur.top], eax
mov edx, eax
sub edx, [y]
mov [_dy], edx
 
mul dword [BytesPerScanLine]
lea edx, [LFB_BASE+ecx*3]
add edx, eax
mov [cur_saved_base],edx
 
cmp ebx, [Screen_Max_X]
jbe @F
mov ebx, [Screen_Max_X]
@@:
cmp edi, [Screen_Max_Y]
jbe @F
mov edi, [Screen_Max_Y]
@@:
mov [cur.right], ebx
mov [cur.bottom], edi
 
sub ebx, [x]
sub edi, [y]
inc ebx
inc edi
 
mov [cur.w], ebx
mov [cur.h], edi
mov [h], edi
 
mov eax, edi
mov edi, cur_saved_data
@@:
mov esi, edx
add edx, [BytesPerScanLine]
mov ecx, [cur.w]
lea ecx, [ecx+ecx*2]
rep movsb
dec eax
jnz @B
 
;draw cursor
mov ebx, [cur_saved_base]
mov eax, [_dy]
shl eax, 5
add eax, [_dx]
 
mov esi, [hcursor]
mov esi, [esi+CURSOR.base]
lea edx, [esi+eax*4]
.row:
mov ecx, [cur.w]
mov esi, edx
mov edi, ebx
add edx, 32*4
add ebx, [BytesPerScanLine]
.pix:
lodsd
test eax, 0xFF000000
jz @F
mov [edi], ax
shr eax, 16
mov [edi+2],al
@@:
add edi, 3
dec ecx
jnz .pix
 
dec [h]
jnz .row
ret
endp
 
 
align 4
proc move_cursor_32 stdcall, hcursor:dword, x:dword, y:dword
locals
h dd ?
_dx dd ?
_dy dd ?
endl
 
mov esi, [hcursor]
mov ecx, [x]
mov eax, [y]
 
xor edx, edx
sub ecx, [esi+CURSOR.hot_x]
lea ebx, [ecx+32-1]
mov [x], ecx
sets dl
dec edx
and ecx, edx ;clip x to 0<=x
mov [cur.left], ecx
mov edi, ecx
sub edi, [x]
mov [_dx], edi
 
xor edx, edx
sub eax, [esi+CURSOR.hot_y]
lea edi, [eax+32-1]
mov [y], eax
sets dl
dec edx
and eax, edx ;clip y to 0<=y
mov [cur.top], eax
mov edx, eax
sub edx, [y]
mov [_dy], edx
 
mul dword [BytesPerScanLine]
lea edx, [LFB_BASE+eax+ecx*4]
mov [cur_saved_base],edx
 
cmp ebx, [Screen_Max_X]
jbe @F
mov ebx, [Screen_Max_X]
@@:
cmp edi, [Screen_Max_Y]
jbe @F
mov edi, [Screen_Max_Y]
@@:
mov [cur.right], ebx
mov [cur.bottom], edi
 
sub ebx, [x]
sub edi, [y]
inc ebx
inc edi
 
mov [cur.w], ebx
mov [cur.h], edi
mov [h], edi
 
mov eax, edi
mov edi, cur_saved_data
@@:
mov esi, edx
add edx, [BytesPerScanLine]
mov ecx, [cur.w]
rep movsd
dec eax
jnz @B
 
;draw cursor
mov ebx, [cur_saved_base]
mov eax, [_dy]
shl eax, 5
add eax, [_dx]
 
mov esi, [hcursor]
mov esi, [esi+CURSOR.base]
lea edx, [esi+eax*4]
.row:
mov ecx, [cur.w]
mov esi, edx
mov edi, ebx
add edx, 32*4
add ebx, [BytesPerScanLine]
.pix:
lodsd
test eax, 0xFF000000
jz @F
mov [edi], eax
@@:
add edi, 4
dec ecx
jnz .pix
 
dec [h]
jnz .row
ret
endp
 
 
align 4
get_display:
mov eax, _display
ret
 
align 4
init_display:
 
xor eax, eax
mov edi, _display
 
mov [edi+display_t.init_cursor], eax
mov [edi+display_t.select_cursor], eax
mov [edi+display_t.show_cursor], eax
mov [edi+display_t.move_cursor], eax
mov [edi+display_t.restore_cursor], eax
 
lea ecx, [edi+display_t.cr_list.next]
mov [edi+display_t.cr_list.next], ecx
mov [edi+display_t.cr_list.prev], ecx
 
cmp [SCR_MODE],word 0x13
jbe .fail
 
test word [SCR_MODE], 0x4000
jz .fail
 
mov ebx, restore_32
mov ecx, move_cursor_32
movzx eax, byte [ScreenBPP]
cmp eax, 32
je @F
 
mov ebx, restore_24
mov ecx, move_cursor_24
cmp eax, 24
jne .fail
@@:
mov [_display.select_cursor], select_cursor
mov [_display.move_cursor], ecx
mov [_display.restore_cursor], ebx
 
stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM
mov [def_cursor], eax
ret
.fail:
xor eax, eax
mov [_display.select_cursor], eax
mov [_display.move_cursor], eax
ret
 
 
 
 
 
 
 
 
 
 
align 4
def_arrow:
file 'arrow.cur'
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/video/vga.inc
0,0 → 1,450
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; VGA.INC ;;
;; ;;
;; 640x480 mode 0x12 VGA functions for MenuetOS ;;
;; ;;
;; Paul Butcher, paul.butcher@asa.co.uk ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
paletteVGA:
 
;16 colour palette
mov dx,0x3c8
mov al,0
out dx,al
 
mov ecx,16
mov dx,0x3c9
xor eax,eax
 
palvganew:
 
mov al,0
test ah,4
jz palvgalbl1
add al,31
test ah,8
jz palvgalbl1
add al,32
palvgalbl1:
out dx,al ; red 0,31 or 63
mov al,0
test ah,2
jz palvgalbl2
add al,31
test ah,8
jz palvgalbl2
add al,32
palvgalbl2:
out dx,al ; blue 0,31 or 63
mov al,0
test ah,1
jz palvgalbl3
add al,31
test ah,8
jz palvgalbl3
add al,32
palvgalbl3:
out dx,al ; green 0,31 or 63
add ah,1
loop palvganew
; mov dx, 3ceh
; mov ax, 0005h
; out dx, ax
ret
 
palette320x200:
 
mov edx,0x3c8
xor eax, eax
out dx,al
mov ecx,256
mov edx,0x3c9
xor eax,eax
 
palnew:
mov al,0
test ah,64
jz pallbl1
add al,21
pallbl1:
test ah,128
jz pallbl2
add al,42
pallbl2:
out dx,al
mov al,0
test ah,8
jz pallbl3
add al,8
pallbl3:
test ah,16
jz pallbl4
add al,15
pallbl4:
test ah,32
jz pallbl5
add al,40
pallbl5:
out dx,al
mov al,0
test ah,1
jz pallbl6
add al,8
pallbl6:
test ah,2
jz pallbl7
add al,15
pallbl7:
test ah,4
jz pallbl8
add al,40
pallbl8:
out dx,al
add ah,1
loop palnew
 
ret
align 4
uglobal
novesachecksum dd 0x0
EGA_counter db 0
VGA_drawing_screen db 0
VGA_8_pixels:
rb 16
temp:
.cx dd 0
endg
align 4
checkVga_N13:
 
cmp [SCR_MODE],dword 0x13
jne @f
 
; cnvl:
pushad
cmp [EGA_counter],1
je novesal
mov ecx,[MOUSE_X]
cmp ecx,[novesachecksum]
jne novesal
popad
@@:
ret
 
novesal:
mov [novesachecksum],ecx
mov ecx,0
movzx eax,word [MOUSE_Y]
cmp eax,100
jge m13l3
mov eax,100
m13l3:
cmp eax,480-100
jbe m13l4
mov eax,480-100
m13l4:
sub eax,100
imul eax,640*4
add ecx,eax
movzx eax,word [MOUSE_X]
cmp eax,160
jge m13l1
mov eax,160
m13l1:
cmp eax,640-160
jbe m13l2
mov eax,640-160
m13l2:
sub eax,160
shl eax,2
add ecx,eax
mov esi,[LFBAddress]
add esi,ecx
mov edi,VGABasePtr
mov edx,200
mov ecx,320
cld
m13pix:
lodsd
test eax,eax
jz .save_pixel
push eax
mov ebx,eax
and eax,(128+64+32) ; blue
shr eax,5
and ebx,(128+64+32)*256 ; green
shr ebx,8+2
add eax,ebx
pop ebx
and ebx,(128+64)*256*256 ; red
shr ebx,8+8
add eax,ebx
.save_pixel:
stosb
loop m13pix
mov ecx,320
add esi,4*(640-320)
dec edx
jnz m13pix
mov [EGA_counter],0
popad
ret
 
VGA_drawbackground:
; draw all
cmp [SCR_MODE],dword 0x12
jne .end
pushad
mov esi,[LFBAddress]
mov edi,VGABasePtr
mov ebx,640/32 ; 640*480/(8*4)
mov edx,480
@@:
push ebx edx esi edi
shl edx,9
lea edx,[edx+edx*4]
add esi,edx
shr edx,5
add edi,edx
call VGA_draw_long_line
pop edi esi edx ebx
dec edx
jnz @r
call VGA_draw_long_line_1
popad
.end:
ret
 
VGA_draw_long_line:
mov dx,3ceh
mov ax,0ff08h
cli
out dx, ax
mov ax,0005h
out dx, ax
m12pix:
call VGA_draw_32_pixels
dec ebx
jnz m12pix
mov dx,3c4h
mov ax,0ff02h
out dx,ax
mov dx,3ceh
mov ax,0205h
out dx,ax
mov dx,3ceh
mov al,08h
out dx,al
sti
ret
 
VGA_draw_32_pixels:
xor eax,eax
mov ebp,VGA_8_pixels
mov [ebp],eax
mov [ebp+4],eax
mov [ebp+8],eax
mov [ebp+12],eax
mov ch,4
.main_loop:
mov cl,8
.convert_pixels_to_VGA:
lodsd ; eax = 24bit colour
test eax,eax
jz .end
rol eax,8
mov al,ch
ror eax,8
mov ch,1
dec cl
shl ch,cl
cmp al,85
jbe .p13green
or [ebp],ch
cmp al,170
jbe .p13green
or [ebp+12],ch
.p13green:
cmp ah,85
jbe .p13red
or [ebp+4],ch
cmp ah,170
jbe .p13red
or [ebp+12],ch
.p13red:
shr eax,8
cmp ah,85
jbe .p13cont
or [ebp+8],ch
cmp ah,170
jbe .p13cont
or [ebp+12],ch
.p13cont:
ror eax,8
mov ch,ah
inc cl
.end:
dec cl
jnz .convert_pixels_to_VGA
inc ebp
dec ch
jnz .main_loop
push esi
sub ebp,4
mov esi,ebp
mov dx, 3c4h
mov ah, 1h
@@:
mov al, 02h
out dx,ax
xchg ax,bp
lodsd
mov [edi],eax
xchg ax,bp
shl ah, 1
cmp ah, 10h
jnz @r
add edi,4
pop esi
ret
 
VGA_putpixel:
; eax = x
; ebx = y
mov ecx,eax
mov eax, [esp+32-8+4] ; color
shl ebx,9
lea ebx,[ebx+ebx*4] ; óìíîæåíèå íà 5
lea edx, [ebx+ecx*4] ; + x*BytesPerPixel (Vesa2.0 32)
mov edi,edx
add edi, [LFBAddress] ; + LFB address
mov [edi], eax ; write to LFB for Vesa2.0
shr edx,5 ; change BytesPerPixel to 1/8
mov edi,edx
add edi, VGABasePtr ; address of pixel in VGA area
and ecx,0x07 ; bit no. (modulo 8)
pushfd
; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8)
xor edx,edx
test eax,eax
jz .p13cont
cmp al,85
jbe .p13green
or dl,0x01
cmp al,170
jbe .p13green
or dl,0x08
.p13green:
cmp ah,85
jbe .p13red
or dl,0x02
cmp ah,170
jbe .p13red
or dl,0x08
.p13red:
shr eax,8
cmp ah,85
jbe .p13cont
or dl,0x04
cmp ah,170
jbe .p13cont
or dl,0x08
.p13cont:
ror edx,8
inc cl
xor eax,eax
inc ah
shr ax,cl
mov dx,3cfh
cli
out dx,al
mov al,[edi] ; dummy read
rol edx,8
mov [edi],dl
popfd
;.end:
ret
 
VGA__putimage:
; ecx = size [x|y]
; edx = coordinates [x|y]
cmp [SCR_MODE],dword 0x12
jne @f
pushad
rol edx,16
movzx eax,dx
rol edx,16
movzx ebx,dx
movzx edx,cx
rol ecx,16
movzx ecx,cx
call VGA_draw_bar_1
popad
@@:
ret
 
VGA_draw_bar:
; eax cx
; ebx cy
; ecx xe
; edx ye
cmp [SCR_MODE],dword 0x12
jne @f
pushad
sub ecx,eax
sub edx,ebx
and eax,0xffff
and ebx,0xffff
and ecx,0xffff
and edx,0xffff
call VGA_draw_bar_1
popad
@@:
ret
 
VGA_draw_bar_1:
mov [temp.cx],eax
mov eax, [TASK_BASE]
add ebx, [eax-twdw + 4]
mov eax, [eax-twdw + 0]
add eax, [temp.cx]
and eax,0xfff8
shl ebx,9
lea ebx,[ebx+ebx*4] ; óìíîæåíèå íà 5
lea ebx, [ebx+eax*4] ; + x*BytesPerPixel (Vesa2.0 32)
mov esi,ebx
add esi, [LFBAddress] ; + LFB address
shr ebx,5 ; change BytesPerPixel to 1/8
mov edi,ebx
add edi, VGABasePtr ; address of pixel in VGA area
mov ebx,ecx
shr ebx,5
inc ebx
.main_loop:
call VGA_draw_long_line_1
dec edx
jnz .main_loop
call VGA_draw_long_line_1
ret
 
VGA_draw_long_line_1:
push ebx edx esi edi
shl edx,9
lea edx,[edx+edx*4]
add esi,edx
shr edx,5
add edi,edx
call VGA_draw_long_line
pop edi esi edx ebx
ret
 
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/video/arrow.cur
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/kernel/branches/Kolibri-acpi/video
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/fdo.inc
0,0 → 1,437
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
_esp equ esp
 
;
; Formatted Debug Output (FDO)
; Copyright (c) 2005-2006, mike.dld
; Created: 2005-01-29, Changed: 2006-11-10
;
; For questions and bug reports, mail to mike.dld@gmail.com
;
; Available format specifiers are: %s, %d, %u, %x (with partial width support)
;
 
; to be defined:
; __DEBUG__ equ 1
; __DEBUG_LEVEL__ equ 5
 
macro debug_func name {
if used name
name@of@func equ name
}
 
macro debug_beginf {
align 4
name@of@func:
}
 
debug_endf fix end if
 
macro DEBUGS _sign,[_str] {
common
local tp
tp equ 0
match _arg:_num,_str \{
DEBUGS_N _sign,_num,_arg
tp equ 1
\}
match =0 _arg,tp _str \{
DEBUGS_N _sign,,_arg
\}
}
 
macro DEBUGS_N _sign,_num,[_str] {
common
pushf
pushad
local ..str,..label,is_str
is_str = 0
forward
if _str eqtype ''
is_str = 1
end if
common
if is_str = 1
jmp ..label
..str db _str,0
..label:
mov edx,..str
else
esp equ esp+4*8+4
mov edx,_str
esp equ _esp
end if
if ~_num eq
if _num eqtype eax
if _num in <eax,ebx,ecx,edx,edi,ebp,esp>
mov esi,_num
else if ~_num eq esi
movzx esi,_num
end if
else if _num eqtype 0
mov esi,_num
else
local tp
tp equ 0
match [_arg],_num \{
mov esi,dword[_arg]
tp equ 1
\}
match =0 =dword[_arg],tp _num \{
mov esi,dword[_arg]
tp equ 1
\}
match =0 =word[_arg],tp _num \{
movzx esi,word[_arg]
tp equ 1
\}
match =0 =byte[_arg],tp _num \{
movzx esi,byte[_arg]
tp equ 1
\}
match =0,tp \{
'Error: specified string width is incorrect'
\}
end if
else
mov esi,0x7FFFFFFF
end if
call fdo_debug_outstr
popad
popf
}
 
macro DEBUGD _sign,_dec {
local tp
tp equ 0
match _arg:_num,_dec \{
DEBUGD_N _sign,_num,_arg
tp equ 1
\}
match =0 _arg,tp _dec \{
DEBUGD_N _sign,,_arg
\}
}
 
macro DEBUGD_N _sign,_num,_dec {
pushf
pushad
if (~_num eq)
if (_dec eqtype eax | _dec eqtype 0)
'Error: precision allowed only for in-memory variables'
end if
if (~_num in <1,2,4>)
if _sign
'Error: 1, 2 and 4 are only allowed for precision in %d'
else
'Error: 1, 2 and 4 are only allowed for precision in %u'
end if
end if
end if
if _dec eqtype eax
if _dec in <ebx,ecx,edx,esi,edi,ebp,esp>
mov eax,_dec
else if ~_dec eq eax
if _sign = 1
movsx eax,_dec
else
movzx eax,_dec
end if
end if
else if _dec eqtype 0
mov eax,_dec
else
; add esp,4*8+4
esp equ esp+4*8+4
if _num eq
mov eax,dword _dec
else if _num = 1
if _sign = 1
movsx eax,byte _dec
else
movzx eax,byte _dec
end if
else if _num = 2
if _sign = 1
movsx eax,word _dec
else
movzx eax,word _dec
end if
else
mov eax,dword _dec
end if
esp equ _esp
; sub esp,4*8+4
end if
mov cl,_sign
call fdo_debug_outdec
popad
popf
}
 
macro DEBUGH _sign,_hex {
local tp
tp equ 0
match _arg:_num,_hex \{
DEBUGH_N _sign,_num,_arg
tp equ 1
\}
match =0 _arg,tp _hex \{
DEBUGH_N _sign,,_arg
\}
}
 
macro DEBUGH_N _sign,_num,_hex {
pushf
pushad
if (~_num eq) & (~_num in <1,2,3,4,5,6,7,8>)
'Error: 1..8 are only allowed for precision in %x'
end if
if _hex eqtype eax
if _hex in <eax,ebx,ecx,edx,esi,edi,ebp,esp>
if ~_hex eq eax
mov eax,_hex
end if
mov edx,8
else if _hex in <ax,bx,cx,dx,si,di,bp,sp>
if ~_hex eq ax
movzx eax,_hex
end if
if (_num eq)
mov edx,4
end if
else if _hex in <al,ah,bl,bh,cl,ch,dl,dh>
if ~_hex eq al
movzx eax,_hex
end if
if (_num eq)
mov edx,2
end if
end if
else if _hex eqtype 0
mov eax,_hex
else
; add esp,4*8+4
esp equ esp+4*8+4
mov eax,dword _hex
esp equ _esp
; sub esp,4*8+4
end if
if ~_num eq
mov edx,_num
else
if ~_hex eqtype eax
mov edx,8
end if
end if
call fdo_debug_outhex
popad
popf
}
 
;-----------------------------------------------------------------------------
 
debug_func fdo_debug_outchar
debug_beginf
pushad
movzx ebx,al
mov eax,1
mov ecx,sys_msg_board
call ecx ; sys_msg_board
popad
ret
debug_endf
 
debug_func fdo_debug_outstr
debug_beginf
mov eax,1
.l1: dec esi
js .l2
movzx ebx,byte[edx]
or bl,bl
jz .l2
mov ecx,sys_msg_board
call ecx ; sys_msg_board
inc edx
jmp .l1
.l2: ret
debug_endf
 
debug_func fdo_debug_outdec
debug_beginf
or cl,cl
jz @f
or eax,eax
jns @f
neg eax
push eax
mov al,'-'
call fdo_debug_outchar
pop eax
@@: push 10
pop ecx
push -'0'
.l1: xor edx,edx
div ecx
push edx
test eax,eax
jnz .l1
.l2: pop eax
add al,'0'
jz .l3
call fdo_debug_outchar
jmp .l2
.l3: ret
debug_endf
 
debug_func fdo_debug_outhex
__fdo_hexdigits db '0123456789ABCDEF'
debug_beginf
mov cl,dl
neg cl
add cl,8
shl cl,2
rol eax,cl
.l1: rol eax,4
push eax
and eax,0x0000000F
mov al,[__fdo_hexdigits+eax]
call fdo_debug_outchar
pop eax
dec edx
jnz .l1
ret
debug_endf
 
;-----------------------------------------------------------------------------
 
macro DEBUGF _level,_format,[_arg] {
common
if __DEBUG__ = 1 & _level >= __DEBUG_LEVEL__
local ..f1,f2,a1,a2,c1,c2,c3,..lbl
_debug_str_ equ __debug_str_ # a1
a1 = 0
c2 = 0
c3 = 0
f2 = 0
repeat ..lbl-..f1
virtual at 0
db _format,0,0
load c1 word from %-1
end virtual
if c1 = '%s'
virtual at 0
db _format,0,0
store word 0 at %-1
load c1 from f2-c2
end virtual
if c1 <> 0
DEBUGS 0,_debug_str_+f2-c2
end if
c2 = c2 + 1
f2 = %+1
DEBUGF_HELPER S,a1,0,_arg
else if c1 = '%x'
virtual at 0
db _format,0,0
store word 0 at %-1
load c1 from f2-c2
end virtual
if c1 <> 0
DEBUGS 0,_debug_str_+f2-c2
end if
c2 = c2 + 1
f2 = %+1
DEBUGF_HELPER H,a1,0,_arg
else if c1 = '%d' | c1 = '%u'
local c4
if c1 = '%d'
c4 = 1
else
c4 = 0
end if
virtual at 0
db _format,0,0
store word 0 at %-1
load c1 from f2-c2
end virtual
if c1 <> 0
DEBUGS 0,_debug_str_+f2-c2
end if
c2 = c2 + 1
f2 = %+1
DEBUGF_HELPER D,a1,c4,_arg
else if c1 = '\n'
c3 = c3 + 1
end if
end repeat
virtual at 0
db _format,0,0
load c1 from f2-c2
end virtual
if (c1<>0)&(f2<>..lbl-..f1-1)
DEBUGS 0,_debug_str_+f2-c2
end if
virtual at 0
..f1 db _format,0
..lbl:
__debug_strings equ __debug_strings,_debug_str_,<_format>,..lbl-..f1-1-c2-c3
end virtual
end if
}
 
macro __include_debug_strings dummy,[_id,_fmt,_len] {
common
local c1,a1,a2
forward
if defined _len & ~_len eq
_id:
a1 = 0
a2 = 0
repeat _len
virtual at 0
db _fmt,0,0
load c1 word from %+a2-1
end virtual
if (c1='%s')|(c1='%x')|(c1='%d')|(c1='%u')
db 0
a2 = a2 + 1
else if (c1='\n')
dw $0A0D
a1 = a1 + 1
a2 = a2 + 1
else
db c1 and 0x0FF
end if
end repeat
db 0
end if
}
 
macro DEBUGF_HELPER _letter,_num,_sign,[_arg] {
common
local num
num = 0
forward
if num = _num
DEBUG#_letter _sign,_arg
end if
num = num+1
common
_num = _num+1
}
 
macro include_debug_strings {
if __DEBUG__ = 1
match dbg_str,__debug_strings \{
__include_debug_strings dbg_str
\}
end if
}
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/data32.inc
0,0 → 1,467
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
keymap:
 
db '6',27
db '1234567890-=',8,9
db 'qwertyuiop[]',13
db '~asdfghjkl;',39,96,0,'\zxcvbnm,./',0,'45 '
db '@234567890123',180,178,184,'6',176,'7'
db 179,'8',181,177,183,185,182
db 'AB<D',255,'FGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
keymap_shift:
db '6',27
db '!@#$%^&*()_+',8,9
db 'QWERTYUIOP{}',13
db '~ASDFGHJKL:"~',0,'|ZXCVBNM<>?',0,'45 '
db '@234567890123',180,178,184,'6',176,'7'
db 179,'8',181,177,183,185,182
db 'AB>D',255,'FGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
 
keymap_alt:
db ' ',27
db ' @ $ {[]}\ ',8,9
db ' ',13
db ' ',0,' ',0,'4',0,' '
db ' ',180,178,184,'6',176,'7'
db 179,'8',181,177,183,185,182
db 'ABCD',255,'FGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
 
boot_memdetect db 'Determining amount of memory',0
boot_fonts db 'Fonts loaded',0
boot_tss db 'Setting TSSs',0
boot_cpuid db 'Reading CPUIDs',0
boot_devices db 'Detecting devices',0
boot_timer db 'Setting timer',0
boot_irqs db 'Reprogramming IRQs',0
boot_setmouse db 'Setting mouse',0
boot_windefs db 'Setting window defaults',0
boot_bgr db 'Calculating background',0
boot_resirqports db 'Reserving IRQs & ports',0
boot_setrports db 'Setting addresses for IRQs',0
boot_setostask db 'Setting OS task',0
boot_allirqs db 'Unmasking all IRQs',0
boot_tsc db 'Reading TSC',0
boot_cpufreq db 'CPU frequency is ',' ',' MHz',0
boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0
boot_pal_vga db 'Setting VGA 640x480 palette',0
boot_failed db 'Failed to start first app',0
boot_mtrr db 'Setting MTRR',0
if preboot_blogesc
boot_tasking db 'All set - press ESC to start',0
end if
 
;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
 
msg_unresolved db 'unresolved ',0
msg_module db 'in module ',0
msg_version db 'incompatible driver version',13,10,0
msg_www db 'please visit www.kolibrios.org',13,10,0
msg_CR db 13,10,0
aSis db 'SIS',0
 
intel_str db "GenuineIntel",0
AMD_str db "AuthenticAMD",0
 
;szSound db 'SOUND',0
;szInfinity db 'INFINITY',0
szHwMouse db 'ATI2D',0
szPS2MDriver db 'PS2MOUSE',0
;szCOM_MDriver db 'COM_MOUSE',0
szUSB db 'USB',0
szAtiHW db '/rd/1/drivers/ati2d.drv',0
 
szSTART db 'START',0
szEXPORTS db 'EXPORTS',0
sz_EXPORTS db '_EXPORTS',0
 
szIMPORTS db 'IMPORTS',0
 
read_firstapp db '/sys/'
firstapp db 'LAUNCHER',0
 
char db '/sys/FONTS/CHAR.MT',0
char2 db '/sys/FONTS/CHAR2.MT',0
 
bootpath db '/KOLIBRI '
bootpath2 db 0
vmode db '/sys/drivers/VMODE.MDR',0
vrr_m db 'VRR_M',0
kernel_file db 'KERNEL MNT'
 
 
align 4
 
shmem_list:
.bk dd shmem_list
.fd dd shmem_list
 
dll_list:
.bk dd dll_list
.fd dd dll_list
 
MAX_DEFAULT_DLL_ADDR = 0x20000000
MIN_DEFAULT_DLL_ADDR = 0x10000000
dll_cur_addr dd MIN_DEFAULT_DLL_ADDR
 
; supported videomodes
 
 
; mike.dld {
db 0
dd servetable-0x10000
draw_line dd __sys_draw_line
draw_pointer dd __sys_draw_pointer
;//mike.dld, 2006-08-02 [
;drawbar dd __sys_drawbar
drawbar dd __sys_drawbar.forced
;//mike.dld, 2006-08-02 ]
putpixel dd __sys_putpixel
; } mike.dld
 
 
align 4
keyboard dd 1
syslang dd 1
 
boot_y dd 10
 
pci_bios_entry dd 0
dw pci_code_sel
 
if __DEBUG__ eq 1
include_debug_strings
end if
 
IncludeIGlobals
 
align 16
gdts:
 
dw gdte-$-1
dd gdts
dw 0
 
; Attention! Do not change the order of the first four selectors. They are used in Fast System Call
; must be : os_code, os_data, app_code, app_data, ....
 
int_code_l:
os_code_l:
dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10011010b
db 0x00
 
int_data_l:
os_data_l:
dw 0xffff
dw 0x0000
db 0x00
dw 11011111b *256 +10010010b
db 0x00
 
app_code_l:
dw 0xFFFF
dw 0
db 0
db cpl3
dw G32+D32+0xF;
 
app_data_l:
dw 0xFFFF
dw 0
db 0
db drw3
dw G32+D32+0xF;
 
; ------------- PCI BIOS ------------------
 
pci_code_32:
dw 0 ;lim 0-15
dw 0 ;base 0-15
db 0 ;base 16-23
db cpl0 ;type
db D32 ;lim 16-19+props
db 0 ;base 24-31
 
pci_data_32:
dw 0 ;lim 0-15
dw 0 ;base 0-15
db 0 ;base 16-23
db dpl0 ;type
db D32 ;lim 16-19+props
db 0 ;base 24-31
 
; --------------- APM ---------------------
apm_code_32:
dw 0x0f ; limit 64kb
db 0, 0, 0
dw 11010000b *256 +10011010b
db 0x00
apm_code_16:
dw 0x0f
db 0, 0, 0
dw 10010000b *256 +10011010b
db 0x00
apm_data_16:
dw 0x0f
db 0, 0, 0
dw 10010000b *256 +10010010b
db 0x00
; -----------------------------------------
 
graph_data_l:
 
dw 0x7ff
dw 0x0000
db 0x00
dw 11010000b *256 +11110010b
db 0x00
tss0_l:
dw TSS_SIZE-1
dw tss and 0xFFFF
db (tss shr 16) and 0xFF
db 10001001b
dw (tss shr 16) and 0xFF00
 
tls_data_l:
dw 0x0FFF
dw 0
db 0
db drw3
dw D32
 
endofcode:
gdte:
 
align 16
cur_saved_data rb 4096
fpu_data: rb 512
 
; device irq owners
irq_owner rd 16 ; process id
 
; on irq read ports
 
irq00read rd 16
irq01read rd 16
irq02read rd 16
irq03read rd 16
irq04read rd 16
irq05read rd 16
irq06read rd 16
irq07read rd 16
irq08read rd 16
irq09read rd 16
irq10read rd 16
irq11read rd 16
irq12read rd 16
irq13read rd 16
irq14read rd 16
irq15read rd 16
 
irq_tab rd 16
 
mem_block_map rb 512
mem_block_list rd 64
large_block_list rd 31
mem_block_mask rd 2
large_block_mask rd 1
 
mem_used.fd rd 1
mem_used.bk rd 1
 
mem_block_arr rd 1
mem_block_start rd 1
mem_block_end rd 1
 
heap_mutex rd 1
heap_size rd 1
heap_free rd 1
heap_blocks rd 1
free_blocks rd 1
 
mst MEM_STATE
 
page_start rd 1
page_end rd 1
sys_page_map rd 1
os_stack_seg rd 1
 
 
srv.fd rd 1
srv.bk rd 1
 
 
align 16
 
_display display_t
 
_WinMapAddress rd 1
_WinMapSize rd 1
 
def_cursor rd 1
current_cursor rd 1
hw_cursor rd 1
cur_saved_base rd 1
 
cur.lock rd 1 ;1 - lock update, 2- hide
cur.left rd 1 ;cursor clip box
cur.top rd 1
cur.right rd 1
cur.bottom rd 1
cur.w rd 1
cur.h 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
 
default_io_map rd 1
 
LFBSize rd 1
 
stall_mcs rd 1
current_slot rd 1
 
; status
hd1_status rd 1 ; 0 - free : other - pid
application_table_status rd 1 ; 0 - free : other - pid
 
; device addresses
mididp rd 1
midisp rd 1
 
cdbase rd 1
cdid rd 1
 
hdbase rd 1 ; for boot 0x1f0
hdid rd 1
hdpos rd 1 ; for boot 0x1
label known_part dword
fat32part rd 1 ; for boot 0x1
cdpos rd 1
 
;CPUID information
cpu_vendor rd 3
cpu_sign rd 1
cpu_info rd 1
cpu_caps rd 4
 
 
pg_data PG_DATA
heap_test rd 1
 
buttontype rd 1
windowtypechanged rd 1
 
hd_entries rd 1 ;unused ? 0xfe10
 
;* start code - Mario79
 
mouse_active rd 1
mouse_pause rd 1
MouseTickCounter rd 1
 
;* end code - Mario79
 
img_background rd 1
mem_BACKGROUND rd 1
static_background_data rd 1
 
cache_ide0:
cache_ide0_pointer rd 1
cache_ide0_size rd 1 ; not use
cache_ide0_data_pointer rd 1
cache_ide0_system_data_size rd 1 ; not use
cache_ide0_appl_data_size rd 1 ; not use
cache_ide0_system_data rd 1
cache_ide0_appl_data rd 1
cache_ide0_system_sad_size rd 1
cache_ide0_appl_sad_size rd 1
cache_ide0_search_start rd 1
cache_ide0_appl_search_start rd 1
 
cache_ide1:
cache_ide1_pointer rd 1
cache_ide1_size rd 1 ; not use
cache_ide1_data_pointer rd 1
cache_ide1_system_data_size rd 1 ; not use
cache_ide1_appl_data_size rd 1 ; not use
cache_ide1_system_data rd 1
cache_ide1_appl_data rd 1
cache_ide1_system_sad_size rd 1
cache_ide1_appl_sad_size rd 1
cache_ide1_search_start rd 1
cache_ide1_appl_search_start rd 1
 
cache_ide2:
cache_ide2_pointer rd 1
cache_ide2_size rd 1 ; not use
cache_ide2_data_pointer rd 1
cache_ide2_system_data_size rd 1 ; not use
cache_ide2_appl_data_size rd 1 ; not use
cache_ide2_system_data rd 1
cache_ide2_appl_data rd 1
cache_ide2_system_sad_size rd 1
cache_ide2_appl_sad_size rd 1
cache_ide2_search_start rd 1
cache_ide2_appl_search_start rd 1
 
cache_ide3:
cache_ide3_pointer rd 1
cache_ide3_size rd 1 ; not use
cache_ide3_data_pointer rd 1
cache_ide3_system_data_size rd 1 ; not use
cache_ide3_appl_data_size rd 1 ; not use
cache_ide3_system_data rd 1
cache_ide3_appl_data rd 1
cache_ide3_system_sad_size rd 1
cache_ide3_appl_sad_size rd 1
cache_ide3_search_start rd 1
cache_ide3_appl_search_start rd 1
 
debug_step_pointer rd 1
hdd_appl_data rb 1 ; 0 = system cache, 1 - application cache
cd_appl_data rb 1 ; 0 = system cache, 1 - application cache
 
lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled
pci_access_enabled rd 1 ; 0 = disabled , 1 = enabled
timer_ticks_enable rb 1 ; for cd driver
 
NumBiosDisks rd 1
BiosDisksData rb 200h
BiosDiskCaches rb 80h*(cache_ide1-cache_ide0)
BiosDiskPartitions rd 80h
 
IncludeUGlobals
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/stack.inc
0,0 → 1,908
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; STACK.INC ;;
;; ;;
;; TCP/IP stack for Menuet OS ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; Version 0.7 ;;
;; Added a timer per socket to allow delays when rx window ;;
;; gets below 1KB ;;
;; ;;
;;10.01.2007 Bugfix for checksum function from Paolo Franchetti ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;*******************************************************************
; Interface
; The interfaces defined in ETHERNET.INC plus:
; stack_init
; stack_handler
; app_stack_handler
; app_socket_handler
; checksum
;
;*******************************************************************
 
uglobal
StackCounters:
dumped_rx_count dd 0
arp_tx_count: dd 0
arp_rx_count: dd 0
ip_rx_count: dd 0
ip_tx_count: dd 0
endg
 
; socket buffers
SOCKETBUFFSIZE equ 4096 ; state + config + buffer.
SOCKETHEADERSIZE equ SOCKET.rxData ; thus 4096 - SOCKETHEADERSIZE bytes data
 
;NUM_SOCKETS equ 16 ; Number of open sockets supported. Was 20
 
; IPBUFF status values
BUFF_EMPTY equ 0
BUFF_RX_FULL equ 1
BUFF_ALLOCATED equ 2
BUFF_TX_FULL equ 3
 
NUM_IPBUFFERS equ 20 ; buffers allocated for TX/RX
 
NUMQUEUES equ 4
 
EMPTY_QUEUE equ 0
IPIN_QUEUE equ 1
IPOUT_QUEUE equ 2
NET1OUT_QUEUE equ 3
 
NO_BUFFER equ 0xFFFF
IPBUFFSIZE equ 1500 ; MTU of an ethernet packet
NUMQUEUEENTRIES equ NUM_IPBUFFERS
NUMRESENDENTRIES equ 18 ; Buffers for TCP resend packets
 
; These are the 0x40 function codes for application access to the stack
STACK_DRIVER_STATUS equ 52
SOCKET_INTERFACE equ 53
 
 
; 128KB allocated for the stack and network driver buffers and other
; data requirements
;stack_data_start equ 0x700000
;eth_data_start equ 0x700000
;stack_data equ 0x704000
;stack_data_end equ 0x71ffff
 
; 32 bit word
stack_config equ stack_data
 
; 32 bit word - IP Address in network format
stack_ip equ stack_data + 4
 
; 1 byte. 0 == inactive, 1 = active
ethernet_active equ stack_data + 9
 
 
; TODO :: empty memory area
 
; Address of selected socket
;sktAddr equ stack_data + 32
; Parameter to checksum routine - data ptr
checkAdd1 equ stack_data + 36
; Parameter to checksum routine - 2nd data ptr
checkAdd2 equ stack_data + 40
; Parameter to checksum routine - data size
checkSize1 equ stack_data + 44
; Parameter to checksum routine - 2nd data size
checkSize2 equ stack_data + 46
; result of checksum routine
checkResult equ stack_data + 48
 
; holds the TCP/UDP pseudo header. SA|DA|0|prot|UDP len|
pseudoHeader equ stack_data + 50
 
; receive and transmit IP buffer allocation
;sockets equ stack_data + 62
Next_free2 equ stack_data + 62;Next_free2 equ sockets + (SOCKETBUFFSIZE * NUM_SOCKETS)
; 1560 byte buffer for rx / tx ethernet packets
Ether_buffer equ Next_free2
Next_free3 equ Ether_buffer + 1518
last_1sTick equ Next_free3
IPbuffs equ Next_free3 + 1
queues equ IPbuffs + ( NUM_IPBUFFERS * IPBUFFSIZE )
queueList equ queues + (2 * NUMQUEUES)
last_1hsTick equ queueList + ( 2 * NUMQUEUEENTRIES )
 
;resendQ equ queueList + ( 2 * NUMQUEUEENTRIES )
;resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP
; equ resendBuffer + ( IPBUFFSIZE * NUMRESENDENTRIES )
 
 
 
;resendQ equ 0x770000
;resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP ; XTODO: validate size
resendBuffer equ resendQ + ( 8 * NUMRESENDENTRIES ) ; for TCP
 
 
uglobal
net_sockets rd 2
endg
 
; simple macro for memory set operation
macro _memset_dw adr,value,amount
{
mov edi, adr
mov ecx, amount
if value = 0
xor eax, eax
else
mov eax, value
end if
cld
rep stosd
}
 
 
; Below, the main network layer source code is included
;
include "queue.inc"
include "eth_drv/ethernet.inc"
include "ip.inc"
include "socket.inc"
 
;***************************************************************************
; Function
; stack_init
;
; Description
; Clear all allocated memory to zero. This ensures that
; on startup, the stack is inactive, and consumes no resources
; This is a kernel function, called prior to the OS main loop
; in set_variables
;
;***************************************************************************
 
stack_init:
; Init two address spaces with default values
_memset_dw stack_data_start, 0, 0x20000/4
_memset_dw resendQ, 0, NUMRESENDENTRIES * 2
 
mov [net_sockets], 0
mov [net_sockets + 4], 0
 
; Queries initialization
call queueInit
 
; The following block sets up the 1s timer
mov al, 0x0
out 0x70, al
in al, 0x71
mov [last_1sTick], al
ret
 
 
 
;***************************************************************************
; Function
; stack_handler
;
; Description
; The kernel loop routine for the stack
; This is a kernel function, called in the main loop
;
;***************************************************************************
align 4
stack_handler:
 
call ethernet_driver
call ip_rx
 
 
; Test for 10ms tick, call tcp timer
mov eax, [timer_ticks] ;[0xfdf0]
cmp eax, [last_1hsTick]
je sh_001
 
mov [last_1hsTick], eax
call tcp_tx_handler
 
sh_001:
 
; Test for 1 second event, call 1s timer functions
mov al, 0x0 ;second
out 0x70, al
in al, 0x71
cmp al, [last_1sTick]
je sh_exit
 
mov [last_1sTick], al
 
stdcall arp_table_manager, ARP_TABLE_TIMER, 0, 0
call tcp_tcb_handler
 
sh_exit:
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Checksum [by Johnny_B]
;; IN:
;; buf_ptr=POINTER to buffer
;; buf_size=SIZE of buffer
;; OUT:
;; AX=16-bit checksum
;; Saves all used registers
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
proc checksum_jb stdcall uses ebx esi ecx,\
buf_ptr:DWORD, buf_size:DWORD
 
xor eax, eax
xor ebx, ebx ;accumulator
mov esi, dword[buf_ptr]
mov ecx, dword[buf_size]
shr ecx, 1 ; ecx=ecx/2
jnc @f ; if CF==0 then size is even number
mov bh, byte[esi + ecx*2]
@@:
cld
 
.loop:
lodsw ;eax=word[esi],esi=esi+2
xchg ah,al ;cause must be a net byte-order
add ebx, eax
loop .loop
 
mov eax, ebx
shr eax, 16
add ax, bx
not ax
 
ret
endp
 
;***************************************************************************
; Function
; checksum
;
; Description
; checkAdd1,checkAdd2, checkSize1, checkSize2, checkResult
; Dont break anything; Most registers are used by the caller
; This code is derived from the 'C' source, cksum.c, in the book
; Internetworking with TCP/IP Volume II by D.E. Comer
;
;***************************************************************************
 
 
checksum:
pusha
mov eax, [checkAdd1]
xor edx, edx ; edx is the accumulative checksum
xor ebx, ebx
mov cx, [checkSize1]
shr cx, 1
jz cs1_1
 
cs1:
mov bh, [eax]
mov bl, [eax + 1]
 
add eax, 2
add edx, ebx
 
loopw cs1
 
cs1_1:
and word [checkSize1], 0x01
jz cs_test2
 
mov bh, [eax]
xor bl, bl
 
add edx, ebx
 
cs_test2:
mov cx, [checkSize2]
cmp cx, 0
jz cs_exit ; Finished if no 2nd buffer
 
mov eax, [checkAdd2]
 
shr cx, 1
jz cs2_1
 
cs2:
mov bh, [eax]
mov bl, [eax + 1]
 
add eax, 2
add edx, ebx
 
loopw cs2
 
cs2_1:
and word [checkSize2], 0x01
jz cs_exit
 
mov bh, [eax]
xor bl, bl
 
add edx, ebx
 
cs_exit:
mov ebx, edx
 
shr ebx, 16
and edx, 0xffff
add edx, ebx
mov eax, edx
shr eax, 16
add edx, eax
not dx
 
mov [checkResult], dx
popa
ret
 
 
 
 
;***************************************************************************
; Function
; app_stack_handler
;
; Description
; This is an application service, called by int 0x40, function 52
; It provides application access to the network interface layer
;
;***************************************************************************
iglobal
align 4
f52call:
dd app_stack_handler.00
dd app_stack_handler.01
dd app_stack_handler.02
dd app_stack_handler.03
dd app_stack_handler.fail ;04
dd app_stack_handler.fail ;05
dd stack_insert_packet ;app_stack_handler.06
dd app_stack_handler.fail ;07
dd stack_get_packet ;app_stack_handler.08
dd app_stack_handler.09
dd app_stack_handler.10
dd app_stack_handler.11
dd app_stack_handler.12
dd app_stack_handler.13
dd app_stack_handler.14
dd app_stack_handler.15
endg
app_stack_handler:
;in ebx,ecx
;out eax
cmp ebx,15
ja .fail ;if more than 15 then exit
 
jmp dword [f52call+ebx*4]
 
 
.00:
; Read the configuration word
mov eax, [stack_config]
ret
 
.01:
; read the IP address
mov eax, [stack_ip]
ret
 
.02:
; write the configuration word
mov [stack_config], ecx
 
; <Slip shouldn't be active anyway - thats an operational issue.>
; If ethernet now enabled, probe for the card, reset it and empty
; the packet buffer
; If all successfull, enable the card.
; If ethernet now disabled, set it as disabled. Should really
; empty the tcpip data area too.
 
; ethernet interface is '3' in ls 7 bits
and cl, 0x7f
cmp cl, 3
je ash_eth_enable
; Ethernet isn't enabled, so make sure that the card is disabled
mov [ethernet_active], byte 0
ret
 
.03:
; write the IP Address
mov [stack_ip], ecx
ret
;old functions was deleted
;.06:
; Insert an IP packet into the stacks received packet queue
; call stack_insert_packet
; ret
 
; Test for any packets queued for transmission over the network
 
;.08:
; call stack_get_packet
; Extract a packet queued for transmission by the network
; ret
 
.09:
; read the gateway IP address
mov eax, [gateway_ip]
ret
 
.10:
; read the subnet mask
mov eax, [subnet_mask]
ret
.11:
; write the gateway IP Address
mov [gateway_ip], ecx
ret
 
.12:
; write the subnet mask
mov [subnet_mask], ecx
ret
 
.13:
; read the dns
mov eax, [dns_ip]
ret
 
.14:
; write the dns IP Address
mov [dns_ip], ecx
ret
 
.15:
;<added by Frank Sommer>
; in ecx we need 4 to read the last 2 bytes
; or we need 0 to read the first 4 bytes
cmp ecx,4
ja .param_error
 
; read MAC, returned (in mirrored byte order) in eax
mov eax, [node_addr + ecx]
ret
 
.param_error:
or eax, -1 ; params not accepted
ret
 
.16:
; 0 -> arp_probe
; 1 -> arp_announce
; 2 -> arp_responce (not supported yet)
test ecx,ecx
je a_probe
 
dec ebx
jz a_ann ; arp announce
.fail:
or eax, -1
ret
 
; cmp ebx,2
; jne a_resp ; arp response
 
; arp probe, sender IP must be set to 0.0.0.0, target IP is set to address being probed
; ecx: pointer to target MAC, MAC should set to 0 by application
; edx: target IP
a_probe:
push dword [stack_ip]
 
mov edx, [stack_ip]
and [stack_ip], dword 0
mov esi, ecx ; pointer to target MAC address
call arp_request
 
pop dword [stack_ip]
ret
 
; arp announce, sender IP must be set to target IP
; ecx: pointer to target MAC
a_ann:
mov edx, [stack_ip]
mov esi, ecx ; pointer to target MAC address
call arp_request
ret
 
.17:
;</added by Frank Sommer>
; modified by [smb]
 
;<added by Johnny_B>
; ARPTable manager interface
;see "proc arp_table_manager" for more details
stdcall arp_table_manager,ecx,edx,esi ;Opcode,Index,Extra
ret
;</added by Johnny_B>
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ash_eth_enable:
; Probe for the card. This will reset it and enable the interface
; if found
call eth_probe
test eax,eax
jz ash_eth_done ; Abort if no hardware found
 
mov [ethernet_active], byte 1
ash_eth_done:
ret
;***************************************************************************
; Function
; app_socket_handler
;
; Description
; This is an application service, called by int 0x40, function 53
; It provides application access to stack socket services
; such as opening sockets
;
;***************************************************************************
iglobal
align 4
f53call:
dd socket_open ;00
dd socket_close ;01
dd socket_poll ;02
dd socket_read ;03
dd socket_write ;04
dd socket_open_tcp ;05
dd socket_status ;06
dd socket_write_tcp ;07
dd socket_close_tcp ;08
dd is_localport_unused ;09
dd app_socket_handler.10
dd socket_read_packet ;11
endg
 
app_socket_handler:
;in ebx,ecx,edx,wsi
;out eax
cmp eax,255
je stack_internal_status
 
cmp eax,11
ja .fail ;if more than 15 then exit
 
jmp dword [f53call+eax*4]
 
.10:
mov eax,dword[drvr_cable]
test eax,eax
jnz @f ; if function is not implented, return -1
or al,-1
ret
@@:
jmp dword[drvr_cable]
 
.fail:
or eax,-1
ret
uglobal
ARPTmp:
times 14 db 0
endg
 
;***************************************************************************
; Function
; stack_internal_status
;
; Description
; Returns information about the internal status of the stack
; This is only useful for debugging
; It works with the ethernet driver
; sub function in ebx
; return requested data in eax
;
;***************************************************************************
; This sub function allows access to debugging information on the stack
; ecx holds the request:
; 100 : return length of empty queue
; 101 : return length of IPOUT QUEUE
; 102 : return length of IPIN QUEUE
; 103 : return length of NET1OUT QUEUE
; 200 : return # of ARP entries
; 201 : return size of ARP table ( max # entries )
; 202 : select ARP table entry #
; 203 : return IP of selected table entry
; 204 : return High 4 bytes of MAC address of selected table entry
; 205 : return low 2 bytes of MAC address of selected table entry
; 206 : return status word of selected table entry
; 207 : return Time to live of selected table entry
 
 
; 2 : return number of IP packets received
; 3 : return number of packets transmitted
; 4 : return number of received packets dumped
; 5 : return number of arp packets received
; 6 : return status of packet driver
; ( 0 == not active, FFFFFFFF = successful )
 
 
stack_internal_status:
cmp ebx, 100
jnz notsis100
 
; 100 : return length of EMPTY QUEUE
mov ebx, EMPTY_QUEUE
call queueSize
ret
 
notsis100:
cmp ebx, 101
jnz notsis101
 
; 101 : return length of IPOUT QUEUE
mov ebx, IPOUT_QUEUE
call queueSize
ret
 
notsis101:
cmp ebx, 102
jnz notsis102
 
; 102 : return length of IPIN QUEUE
mov ebx, IPIN_QUEUE
call queueSize
ret
 
notsis102:
cmp ebx, 103
jnz notsis103
 
; 103 : return length of NET1OUT QUEUE
mov ebx, NET1OUT_QUEUE
call queueSize
ret
 
notsis103:
cmp ebx, 200
jnz notsis200
 
; 200 : return num entries in arp table
movzx eax, byte [NumARP]
ret
 
notsis200:
cmp ebx, 201
jnz notsis201
 
; 201 : return arp table size
mov eax, 20 ; ARP_TABLE_SIZE
ret
 
notsis201:
cmp ebx, 202
jnz notsis202
 
; 202 - read the requested table entry
; into a temporary buffer
; ecx holds the entry number
 
mov eax, ecx
mov ecx, 14 ; ARP_ENTRY_SIZE
mul ecx
 
mov ecx, [eax + ARPTable]
mov [ARPTmp], ecx
mov ecx, [eax + ARPTable+4]
mov [ARPTmp+4], ecx
mov ecx, [eax + ARPTable+8]
mov [ARPTmp+8], ecx
mov cx, [eax + ARPTable+12]
mov [ARPTmp+12], cx
ret
 
notsis202:
cmp ebx, 203
jnz notsis203
 
; 203 - return IP address
mov eax, [ARPTmp]
ret
 
notsis203:
cmp ebx, 204
jnz notsis204
 
; 204 - return MAC high dword
mov eax, [ARPTmp+4]
ret
 
notsis204:
cmp ebx, 205
jnz notsis205
 
; 205 - return MAC ls word
movzx eax, word [ARPTmp+8]
ret
 
notsis205:
cmp ebx, 206
jnz notsis206
 
; 206 - return status word
movzx eax, word [ARPTmp+10]
ret
 
notsis206:
cmp ebx, 207
jnz notsis207
 
; 207 - return ttl word
movzx eax, word [ARPTmp+12]
ret
 
notsis207:
cmp ebx, 2
jnz notsis2
 
; 2 : return number of IP packets received
mov eax, [ip_rx_count]
ret
 
notsis2:
cmp ebx, 3
jnz notsis3
 
; 3 : return number of packets transmitted
mov eax, [ip_tx_count]
ret
 
notsis3:
cmp ebx, 4
jnz notsis4
 
; 4 : return number of received packets dumped
mov eax, [dumped_rx_count]
ret
 
notsis4:
cmp ebx, 5
jnz notsis5
 
; 5 : return number of arp packets received
mov eax, [arp_rx_count]
ret
 
notsis5:
cmp ebx, 6
jnz notsis6
 
; 6 : return status of packet driver
; ( 0 == not active, FFFFFFFF = successful )
mov eax, [eth_status]
ret
 
notsis6:
xor eax, eax
ret
 
 
 
;***************************************************************************
; Function
; stack_get_packet
;
; Description
; extracts an IP packet from the NET1 output queue
; and sends the data to the calling process
; pointer to data in edx
; returns number of bytes read in eax
;
;***************************************************************************
stack_get_packet:
; Look for a buffer to tx
mov eax, NET1OUT_QUEUE
call dequeue
cmp ax, NO_BUFFER
je sgp_non_exit ; Exit if no buffer available
 
push eax ; Save buffer number for freeing at end
 
push edx
; convert buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
pop edx
 
push eax ; save address of IP data
; Get the address of the callers data
mov edi,[TASK_BASE]
add edi,TASKDATA.mem_start
add edx,[edi]
mov edi, edx
pop eax
 
mov ecx, 1500 ; should get the actual number of bytes to write
mov esi, eax
cld
rep movsb ; copy the data across
 
; And finally, return the buffer to the free queue
pop eax
call freeBuff
 
mov eax, 1500
ret
 
sgp_non_exit:
xor eax, eax
ret
 
 
 
;***************************************************************************
; Function
; stack_insert_packet
;
; Description
; writes an IP packet into the stacks receive queue
; # of bytes to write in ecx
; pointer to data in edx
; returns 0 in eax ok, -1 == failed
;
;***************************************************************************
stack_insert_packet:
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je sip_err_exit
 
push eax
 
; save the pointers to the data buffer & size
push edx
push ecx
 
; convert buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
 
mov edx, eax
 
; So, edx holds the IPbuffer ptr
 
pop ecx ; count of bytes to send
mov ebx, ecx ; need the length later
pop eax ; get callers ptr to data to send
 
; Get the address of the callers data
mov edi,[TASK_BASE]
add edi,TASKDATA.mem_start
add eax,[edi]
mov esi, eax
 
mov edi, edx
cld
rep movsb ; copy the data across
 
pop ebx
 
mov eax, IPIN_QUEUE
call queue
 
inc dword [ip_rx_count]
 
mov eax, 0
ret
 
sip_err_exit:
mov eax, 0xFFFFFFFF
ret
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/eth_drv/drivers/3c59x.inc
0,0 → 1,2378
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;; Copyright (c) 2004, Endre Kozma <endre.kozma@axelero.hu>
;; All rights reserved.
;;
;; Redistribution and use in source and binary forms, with or without
;; modification, are permitted provided that the following conditions are
;; met:
;;
;; 1. Redistributions of source code must retain the above copyright notice,
;; this list of conditions and the following disclaimer.
;;
;; 2. Redistributions in binary form must reproduce the above copyright
;; notice, this list of conditions and the following disclaimer in the
;; documentation and/or other materials provided with the distribution.
;;
;; 3. The name of the author may not be used to endorse or promote products
;; derived from this software without specific prior written permission.
;;
;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
;; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
;; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
;; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 3C59X.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Driver for 3Com fast etherlink 3c59x and ;;
;; etherlink XL 3c900 and 3c905 cards ;;
;; References: ;;
;; www.3Com.com - data sheets ;;
;; DP83840A.pdf - ethernet physical layer ;;
;; 3c59x.c - linux driver ;;
;; ethernet driver template by Mike Hibbett ;;
;; ;;
;; Credits ;;
;; Mike Hibbett, ;;
;; who kindly supplied me with a 3Com905C-TX-M card ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; History
;; =======
;; $Log: 3C59X.INC,v $
;; Revision 1.3 2004/07/11 12:21:12 kozma
;; Support of vortex chips (3c59x) added.
;; Support of 3c920 and 3c982 added.
;; Corrections.
;;
;; Revision 1.2 2004/06/12 19:40:20 kozma
;; Function e3c59x_set_available_media added in order to set
;; the default media in case auto detection finds no valid link.
;; Incorrect mii check removed (3c900 Cyclone works now).
;; Cleanups.
;;
;; Revision 1.1 2004/06/12 18:27:15 kozma
;; Initial revision
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; comment the next line out if you don't want debug info printed
; on the debug board. This option adds a lot of bytes to the driver
; so it's worth to comment it out.
; E3C59X_DEBUG equ 1
 
; forcing full duplex mode makes sense at some cards and link types
E3C59X_FORCE_FD equ 1
 
macro virt_to_dma reg
{
sub reg, OS_BASE
}
 
macro dma_to_virt reg
{
add reg, OS_BASE
}
 
macro zero_to_virt reg
{
 
}
 
macro virt_to_zero reg
{
 
}
 
macro zero_to_dma reg
{
sub reg, OS_BASE
}
 
macro dma_to_zero reg
{
add reg, OS_BASE
}
 
macro strtbl name, [string]
{
common
label name dword
forward
local label
dd label
forward
label db string, 0
}
 
; Ethernet frame symbols
ETH_ALEN equ 6
ETH_HLEN equ (2*ETH_ALEN+2)
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for
; mininmum 64bytes frame length
; PCI programming
PCI_REG_COMMAND equ 0x4 ; command register
PCI_REG_STATUS equ 0x6 ; status register
PCI_REG_LATENCY equ 0xd ; latency timer register
PCI_REG_CAP_PTR equ 0x34 ; capabilities pointer
PCI_REG_CAPABILITY_ID equ 0x0 ; capapility ID in pm register block
PCI_REG_PM_STATUS equ 0x4 ; power management status register
PCI_REG_PM_CTRL equ 0x4 ; power management control register
PCI_BIT_PIO equ 0 ; bit0: io space control
PCI_BIT_MMIO equ 1 ; bit1: memory space control
PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master
; Registers
E3C59X_REG_POWER_MGMT_CTRL equ 0x7c
E3C59X_REG_UP_LIST_PTR equ 0x38
E3C59X_REG_UP_PKT_STATUS equ 0x30
E3C59X_REG_TX_FREE_THRESH equ 0x2f
E3C59X_REG_DN_LIST_PTR equ 0x24
E3C59X_REG_DMA_CTRL equ 0x20
E3C59X_REG_TX_STATUS equ 0x1b
E3C59X_REG_RX_STATUS equ 0x18
E3C59X_REG_TX_DATA equ 0x10
; Common window registers
E3C59X_REG_INT_STATUS equ 0xe
E3C59X_REG_COMMAND equ 0xe
; Register window 7
E3C59X_REG_MASTER_STATUS equ 0xc
E3C59X_REG_POWER_MGMT_EVENT equ 0xc
E3C59X_REG_MASTER_LEN equ 0x6
E3C59X_REG_VLAN_ETHER_TYPE equ 0x4
E3C59X_REG_VLAN_MASK equ 0x0
E3C59X_REG_MASTER_ADDRESS equ 0x0
; Register window 6
E3C59X_REG_BYTES_XMITTED_OK equ 0xc
E3C59X_REG_BYTES_RCVD_OK equ 0xa
E3C59X_REG_UPPER_FRAMES_OK equ 0x9
E3C59X_REG_FRAMES_DEFERRED equ 0x8
E3C59X_REG_FRAMES_RCVD_OK equ 0x7
E3C59X_REG_FRAMES_XMITTED_OK equ 0x6
E3C59X_REG_RX_OVERRUNS equ 0x5
E3C59X_REG_LATE_COLLISIONS equ 0x4
E3C59X_REG_SINGLE_COLLISIONS equ 0x3
E3C59X_REG_MULTIPLE_COLLISIONS equ 0x2
E3C59X_REG_SQE_ERRORS equ 0x1
E3C59X_REG_CARRIER_LOST equ 0x0
; Register window 5
E3C59X_REG_INDICATION_ENABLE equ 0xc
E3C59X_REG_INTERRUPT_ENABLE equ 0xa
E3C59X_REG_TX_RECLAIM_THRESH equ 0x9
E3C59X_REG_RX_FILTER equ 0x8
E3C59X_REG_RX_EARLY_THRESH equ 0x6
E3C59X_REG_TX_START_THRESH equ 0x0
; Register window 4
E3C59X_REG_UPPER_BYTES_OK equ 0xe
E3C59X_REG_BAD_SSD equ 0xc
E3C59X_REG_MEDIA_STATUS equ 0xa
E3C59X_REG_PHYSICAL_MGMT equ 0x8
E3C59X_REG_NETWORK_DIAGNOSTIC equ 0x6
E3C59X_REG_FIFO_DIAGNOSTIC equ 0x4
E3C59X_REG_VCO_DIAGNOSTIC equ 0x2 ; may not supported
; Bits in register window 4
E3C59X_BIT_AUTOSELECT equ 24
; Register window 3
E3C59X_REG_TX_FREE equ 0xc
E3C59X_REG_RX_FREE equ 0xa
E3C59X_REG_MEDIA_OPTIONS equ 0x8
E3C59X_REG_MAC_CONTROL equ 0x6
E3C59X_REG_MAX_PKT_SIZE equ 0x4
E3C59X_REG_INTERNAL_CONFIG equ 0x0
; Register window 2
E3C59X_REG_RESET_OPTIONS equ 0xc
E3C59X_REG_STATION_MASK_HI equ 0xa
E3C59X_REG_STATION_MASK_MID equ 0x8
E3C59X_REG_STATION_MASK_LO equ 0x6
E3C59X_REG_STATION_ADDRESS_HI equ 0x4
E3C59X_REG_STATION_ADDRESS_MID equ 0x2
E3C59X_REG_STATION_ADDRESS_LO equ 0x0
; Register window 1
E3C59X_REG_TRIGGER_BITS equ 0xc
E3C59X_REG_SOS_BITS equ 0xa
E3C59X_REG_WAKE_ON_TIMER equ 0x8
E3C59X_REG_SMB_RXBYTES equ 0x7
E3C59X_REG_SMB_DIAG equ 0x5
E3C59X_REG_SMB_ARB equ 0x4
E3C59X_REG_SMB_STATUS equ 0x2
E3C59X_REG_SMB_ADDRESS equ 0x1
E3C59X_REG_SMB_FIFO_DATA equ 0x0
; Register window 0
E3C59X_REG_EEPROM_DATA equ 0xc
E3C59X_REG_EEPROM_COMMAND equ 0xa
E3C59X_REG_BIOS_ROM_DATA equ 0x8
E3C59X_REG_BIOS_ROM_ADDR equ 0x4
; Physical management bits
E3C59X_BIT_MGMT_DIR equ 2 ; drive with the data written in mgmtData
E3C59X_BIT_MGMT_DATA equ 1 ; MII management data bit
E3C59X_BIT_MGMT_CLK equ 0 ; MII management clock
; MII commands
E3C59X_MII_CMD_MASK equ (1111b shl 10)
E3C59X_MII_CMD_READ equ (0110b shl 10)
E3C59X_MII_CMD_WRITE equ (0101b shl 10)
; MII registers
E3C59X_REG_MII_BMCR equ 0 ; basic mode control register
E3C59X_REG_MII_BMSR equ 1 ; basic mode status register
E3C59X_REG_MII_ANAR equ 4 ; auto negotiation advertisement register
E3C59X_REG_MII_ANLPAR equ 5 ; auto negotiation link partner ability register
E3C59X_REG_MII_ANER equ 6 ; auto negotiation expansion register
; MII bits
E3C59X_BIT_MII_AUTONEG_COMPLETE equ 5 ; auto-negotiation complete
E3C59X_BIT_MII_PREAMBLE_SUPPRESSION equ 6
; eeprom bits and commands
E3C59X_EEPROM_CMD_READ equ 0x80
E3C59X_EEPROM_BIT_BUSY equ 15
; eeprom registers
E3C59X_EEPROM_REG_OEM_NODE_ADDR equ 0xa
E3C59X_EEPROM_REG_CAPABILITIES equ 0x10
; Commands for command register
E3C59X_SELECT_REGISTER_WINDOW equ (1 shl 11)
 
IS_VORTEX equ 0x1
IS_BOOMERANG equ 0x2
IS_CYCLONE equ 0x4
IS_TORNADO equ 0x8
EEPROM_8BIT equ 0x10
HAS_PWR_CTRL equ 0x20
HAS_MII equ 0x40
HAS_NWAY equ 0x80
HAS_CB_FNS equ 0x100
INVERT_MII_PWR equ 0x200
INVERT_LED_PWR equ 0x400
MAX_COLLISION_RESET equ 0x800
EEPROM_OFFSET equ 0x1000
HAS_HWCKSM equ 0x2000
EXTRA_PREAMBLE equ 0x4000
 
iglobal
align 4
e3c59x_hw_versions:
dw 0x5900, IS_VORTEX ; 3c590 Vortex 10Mbps
dw 0x5920, IS_VORTEX ; 3c592 EISA 10Mbps Demon/Vortex
dw 0x5970, IS_VORTEX ; 3c597 EISA Fast Demon/Vortex
dw 0x5950, IS_VORTEX ; 3c595 Vortex 100baseTx
dw 0x5951, IS_VORTEX ; 3c595 Vortex 100baseT4
dw 0x5952, IS_VORTEX ; 3c595 Vortex 100base-MII
dw 0x9000, IS_BOOMERANG ; 3c900 Boomerang 10baseT
dw 0x9001, IS_BOOMERANG ; 3c900 Boomerang 10Mbps Combo
dw 0x9004, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPO
dw 0x9005, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps Combo
dw 0x9006, IS_CYCLONE or HAS_HWCKSM ; 3c900 Cyclone 10Mbps TPC
dw 0x900A, IS_CYCLONE or HAS_HWCKSM ; 3c900B-FL Cyclone 10base-FL
dw 0x9050, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseTx
dw 0x9051, IS_BOOMERANG or HAS_MII ; 3c905 Boomerang 100baseT4
dw 0x9055, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B Cyclone 100baseTx
dw 0x9058, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c905B Cyclone 10/100/BNC
dw 0x905A, IS_CYCLONE or HAS_HWCKSM ; 3c905B-FX Cyclone 100baseFx
dw 0x9200, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c905C Tornado
dw 0x9800, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3c980 Cyclone
dw 0x9805, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c982 Dual Port Server Cyclone
dw 0x7646, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM ; 3cSOHO100-TX Hurricane
dw 0x5055, IS_CYCLONE or EEPROM_8BIT or HAS_HWCKSM ; 3c555 Laptop Hurricane
dw 0x6055, IS_TORNADO or HAS_NWAY or EEPROM_8BIT or HAS_CB_FNS \
or INVERT_MII_PWR or HAS_HWCKSM ; 3c556 Laptop Tornado
dw 0x6056, IS_TORNADO or HAS_NWAY or EEPROM_OFFSET or HAS_CB_FNS \
or INVERT_MII_PWR or HAS_HWCKSM ; 3c556B Laptop Hurricane
dw 0x5b57, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 [Megahertz] 10/100 LAN CardBus
dw 0x5057, IS_BOOMERANG or HAS_MII or EEPROM_8BIT ; 3c575 Boomerang CardBus
dw 0x5157, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT \
or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE575BT Cyclone CardBus
dw 0x5257, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CCFE575CT Tornado CardBus
dw 0x6560, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFE656 Cyclone CardBus
dw 0x6562, IS_CYCLONE or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
or INVERT_LED_PWR or HAS_HWCKSM ; 3CCFEM656B Cyclone+Winmodem CardBus
dw 0x6564, IS_TORNADO or HAS_NWAY or HAS_CB_FNS or EEPROM_8BIT or INVERT_MII_PWR \
or MAX_COLLISION_RESET or HAS_HWCKSM ; 3CXFEM656C Tornado+Winmodem CardBus
dw 0x4500, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c450 HomePNA Tornado
dw 0x9201, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920 Tornado
dw 0x1201, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port A
dw 0x1202, IS_TORNADO or HAS_HWCKSM or HAS_NWAY ; 3c982 Hydra Dual Port B
dw 0x9056, IS_CYCLONE or HAS_NWAY or HAS_HWCKSM or EXTRA_PREAMBLE ; 3c905B-T4
dw 0x9210, IS_TORNADO or HAS_NWAY or HAS_HWCKSM ; 3c920B-EMB-WNM Tornado
E3C59X_HW_VERSIONS_SIZE= $-e3c59x_hw_versions
endg
 
; RX/TX buffers sizes
E3C59X_MAX_ETH_PKT_SIZE equ 1536 ; max packet size
E3C59X_NUM_RX_DESC equ 4 ; a power of 2 number
E3C59X_NUM_TX_DESC equ 4 ; a power of 2 number
E3C59X_RX_BUFFER_SIZE equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_RX_DESC)
E3C59X_TX_BUFFER_SIZE equ (E3C59X_MAX_ETH_FRAME_SIZE*E3C59X_NUM_TX_DESC)
; Download Packet Descriptor
E3C59X_DPD_DN_NEXT_PTR equ 0
E3C59X_DPD_FRAME_START_HDR equ 4
E3C59X_DPD_DN_FRAG_ADDR equ 8 ; for packet data
E3C59X_DPD_DN_FRAG_LEN equ 12 ; for packet data
E3C59X_DPD_SIZE equ 16 ; a power of 2 number
; Upload Packet Descriptor
E3C59X_UPD_UP_NEXT_PTR equ 0
E3C59X_UPD_PKT_STATUS equ 4
E3C59X_UPD_UP_FRAG_ADDR equ 8 ; for packet data
E3C59X_UPD_UP_FRAG_LEN equ 12 ; for packet data
E3C59X_UPD_SIZE equ 16
 
; RX/TX buffers
if defined E3C59X_LINUX
E3C59X_MAX_ETH_FRAME_SIZE = 160 ; size of ethernet frame + bytes alignment
e3c59x_rx_buff = 0
else
E3C59X_MAX_ETH_FRAME_SIZE = 1520 ; size of ethernet frame + bytes alignment
e3c59x_rx_buff = eth_data_start
end if
 
e3c59x_tx_buff = e3c59x_rx_buff+E3C59X_RX_BUFFER_SIZE
e3c59x_dpd_buff = e3c59x_tx_buff+E3C59X_TX_BUFFER_SIZE
e3c59x_upd_buff = e3c59x_dpd_buff+(E3C59X_DPD_SIZE*E3C59X_NUM_TX_DESC)
 
uglobal
e3c59x_curr_upd: dd 0
e3c59x_prev_dpd: dd 0
e3c59x_prev_tx_frame: dd 0
e3c59x_transmit_function: dd 0
e3c59x_receive_function: dd 0
endg
 
iglobal
e3c59x_ver_id: db 17
endg
 
uglobal
e3c59x_full_bus_master: db 0
e3c59x_has_hwcksm: db 0
e3c59x_preamble: db 0
e3c59x_dn_list_ptr_cleared: db 0
e3c59x_self_directed_packet: rb 6
endg
 
if defined E3C59X_DEBUG
e3c59x_hw_type_str: db "Detected hardware type : ", 0
e3c59x_device_str: db "Device ID : 0x"
e3c59x_device_id_str: db "ffff", 13, 10, 0
e3c59x_vendor_str: db "Vendor ID : 0x"
e3c59x_vendor_id_str: db "ffff", 13, 10, 0
e3c59x_io_info_str: db "IO address : 0x"
e3c59x_io_addr_str: db "ffff", 13, 10, 0
e3c59x_mac_info_str: db "MAC address : "
e3c59x_mac_addr_str: db "ff:ff:ff:ff:ff:ff", 13, 10, 0
e3c59x_boomerang_str: db " (boomerang)", 13, 10, 0
e3c59x_vortex_str: db " (vortex)", 13, 10, 0
e3c59x_link_type_str: db "Established link type : ", 0
e3c59x_new_line_str: db 13, 10, 0
e3c59x_link_type: dd 0
 
e3c59x_charset: db '0123456789abcdef'
 
strtbl e3c59x_link_str, \
"No valid link type detected", \
"10BASE-T half duplex", \
"10BASE-T full-duplex", \
"100BASE-TX half duplex", \
"100BASE-TX full duplex", \
"100BASE-T4", \
"100BASE-FX", \
"10Mbps AUI", \
"10Mbps COAX (BNC)", \
"miiDevice - not supported"
 
strtbl e3c59x_hw_str, \
"3c590 Vortex 10Mbps", \
"3c592 EISA 10Mbps Demon/Vortex", \
"3c597 EISA Fast Demon/Vortex", \
"3c595 Vortex 100baseTx", \
"3c595 Vortex 100baseT4", \
"3c595 Vortex 100base-MII", \
"3c900 Boomerang 10baseT", \
"3c900 Boomerang 10Mbps Combo", \
"3c900 Cyclone 10Mbps TPO", \
"3c900 Cyclone 10Mbps Combo", \
"3c900 Cyclone 10Mbps TPC", \
"3c900B-FL Cyclone 10base-FL", \
"3c905 Boomerang 100baseTx", \
"3c905 Boomerang 100baseT4", \
"3c905B Cyclone 100baseTx", \
"3c905B Cyclone 10/100/BNC", \
"3c905B-FX Cyclone 100baseFx", \
"3c905C Tornado", \
"3c980 Cyclone", \
"3c982 Dual Port Server Cyclone", \
"3cSOHO100-TX Hurricane", \
"3c555 Laptop Hurricane", \
"3c556 Laptop Tornado", \
"3c556B Laptop Hurricane", \
"3c575 [Megahertz] 10/100 LAN CardBus", \
"3c575 Boomerang CardBus", \
"3CCFE575BT Cyclone CardBus", \
"3CCFE575CT Tornado CardBus", \
"3CCFE656 Cyclone CardBus", \
"3CCFEM656B Cyclone+Winmodem CardBus", \
"3CXFEM656C Tornado+Winmodem CardBus", \
"3c450 HomePNA Tornado", \
"3c920 Tornado", \
"3c982 Hydra Dual Port A", \
"3c982 Hydra Dual Port B", \
"3c905B-T4", \
"3c920B-EMB-WNM Tornado"
 
end if ; defined E3C59X_DEBUG
 
;***************************************************************************
; Function
; e3c59x_debug
; Description
; prints debug info to the debug board
; Parameters
; ebp - io_addr
; Return value
; Destroyed registers
; eax, ebx, ecx, edx, edi, esi
;
;***************************************************************************
if defined E3C59X_DEBUG
align 4
e3c59x_debug:
pushad
; print device type
mov esi, e3c59x_hw_type_str
call sys_msg_board_str
movzx ecx, byte [e3c59x_ver_id]
mov esi, [e3c59x_hw_str+ecx*4]
call sys_msg_board_str
mov esi, e3c59x_boomerang_str
cmp dword [e3c59x_transmit_function], e3c59x_boomerang_transmit
jz .boomerang
mov esi, e3c59x_vortex_str
.boomerang:
call sys_msg_board_str
; print device/vendor
mov ax, [pci_data+2]
mov cl, 2
mov ebx, e3c59x_device_id_str
call e3c59x_print_hex
mov esi, e3c59x_device_str
call sys_msg_board_str
mov ax, [pci_data]
mov cl, 2
mov ebx, e3c59x_vendor_id_str
call e3c59x_print_hex
mov esi, e3c59x_vendor_str
call sys_msg_board_str
; print io address
mov ax, [io_addr]
mov ebx, e3c59x_io_addr_str
mov cl, 2
call e3c59x_print_hex
mov esi, e3c59x_io_info_str
call sys_msg_board_str
; print MAC address
mov ebx, e3c59x_mac_addr_str
xor ecx, ecx
.mac_loop:
push ecx
mov al, [node_addr+ecx]
mov cl, 1
call e3c59x_print_hex
inc ebx
pop ecx
inc cl
cmp cl, 6
jne .mac_loop
mov esi, e3c59x_mac_info_str
call sys_msg_board_str
; print link type
mov esi, e3c59x_link_type_str
call sys_msg_board_str
xor eax, eax
bsr ax, word [e3c59x_link_type]
jz @f
sub ax, 4
@@:
mov esi, [e3c59x_link_str+eax*4]
call sys_msg_board_str
mov esi, e3c59x_new_line_str
call sys_msg_board_str
popad
ret
 
;***************************************************************************
; Function
; e3c59x_print_hex
; Description
; prints a hexadecimal value
; Parameters
; eax - value to be printed out
; ebx - where to print
; cl - value size (1, 2, 4)
; Return value
; ebx - end address after the print
; Destroyed registers
; eax, ebx
;
;***************************************************************************
align 4
e3c59x_print_hex:
cmp cl, 1
je .print_byte
cmp cl, 2
jz .print_word
.print_dword:
push eax
bswap eax
xchg ah, al
call .print_word
pop eax
.print_word:
push eax
xchg ah, al
call .print_byte
pop eax
.print_byte:
movzx eax, al
push eax
and al, 0xf0
shr al, 4
mov al, byte [eax+e3c59x_charset]
mov [ebx], al
inc ebx
pop eax
and al, 0x0f
mov al, byte [eax+e3c59x_charset]
mov [ebx], al
inc ebx
ret
end if ; defined E3C59X_DEBUG
 
;***************************************************************************
; Function
; e3c59x_try_link_detect
; Description
; e3c59x_try_link_detect checks if link exists
; Parameters
; ebp - io_addr
; Return value
; al - 0 ; no link detected
; al - 1 ; link detected
; Destroyed registers
; eax, ebx, ecx, edx, edi, esi
;
;***************************************************************************
align 4
e3c59x_try_link_detect:
; download self-directed packet
mov edi, node_addr
mov bx, 0x0608 ; packet type
mov esi, e3c59x_self_directed_packet
mov ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes
call dword [e3c59x_transmit_function]
; switch to register window 5
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+5
out dx, ax
; program RxFilter for promiscuous operation
mov ax, (10000b shl 11)
lea edx, [ebp+E3C59X_REG_RX_FILTER]
in al, dx
or al, 1111b
lea edx, [ebp+E3C59X_REG_COMMAND]
out dx, ax
; switch to register window 4
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4
out dx, ax
; check loop
xor ebx, ebx
mov ecx, 0xffff ; 65535 tries
.loop:
push ecx ebx
call dword [e3c59x_receive_function]
pop ebx ecx
test al, al
jnz .finish
.no_packet_received:
; switch to register window 4
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4
out dx, ax
; read linkbeatdetect
lea edx, [ebp+E3C59X_REG_MEDIA_STATUS]
in ax, dx
test ah, 1000b ; test linkBeatDetect
jnz .link_detected
xor al, al
jmp .finish
.link_detected:
; test carrierSense
test al, 100000b
jz .no_carrier_sense
inc ebx
.no_carrier_sense:
dec ecx
jns .loop
; assume the link is good if 0 < ebx < 25 %
test ebx, ebx
setnz al
jz .finish
cmp ebx, 16384 ; 25%
setb al
.finish:
if defined E3C59X_DEBUG
test al, al
jz @f
or byte [e3c59x_link_type+1], 100b
@@:
end if ; defined E3C59X_DEBUG
ret
 
;***************************************************************************
; Function
; e3c59x_try_phy
; Description
; e3c59x_try_phy checks the auto-negotiation function
; in the PHY at PHY index. It can also be extended to
; include link detection for non-IEEE 802.3u
; auto-negotiation devices, for instance the BCM5000.
; Parameters
; ah - PHY index
; ebp - io_addr
; Return value
; al - 0 link is auto-negotiated
; al - 1 no link is auto-negotiated
; Destroyed registers
; eax, ebx, ecx, edx, esi
;
;***************************************************************************
align 4
e3c59x_try_phy:
mov al, E3C59X_REG_MII_BMCR
push eax
call e3c59x_mdio_read ; returns with window #4
or ah, 0x80 ; software reset
mov ebx, eax
pop eax
push eax
call e3c59x_mdio_write ; returns with window #4
; wait for reset to complete
mov esi, 2000 ; 2000ms = 2s
call delay_ms
pop eax
push eax
call e3c59x_mdio_read ; returns with window #4
test ah, 0x80
jnz .fail_finish
pop eax
push eax
; wait for a while after reset
mov esi, 20 ; 20ms
call delay_ms
pop eax
push eax
mov al, E3C59X_REG_MII_BMSR
call e3c59x_mdio_read ; returns with window #4
test al, 1 ; extended capability supported?
jz .no_ext_cap
; auto-neg capable?
test al, 1000b
jz .fail_finish ; not auto-negotiation capable
; auto-neg complete?
test al, 100000b
jnz .auto_neg_ok
; restart auto-negotiation
pop eax
push eax
mov al, E3C59X_REG_MII_ANAR
push eax
call e3c59x_mdio_read ; returns with window #4
or ax, (1111b shl 5) ; advertise only 10base-T and 100base-TX
mov ebx, eax
pop eax
call e3c59x_mdio_write ; returns with window #4
pop eax
push eax
call e3c59x_mdio_read ; returns with window #4
mov ebx, eax
or bh, 10010b ; restart auto-negotiation
pop eax
push eax
call e3c59x_mdio_write ; returns with window #4
mov esi, 4000 ; 4000ms = 4 seconds
call delay_ms
pop eax
push eax
mov al, E3C59X_REG_MII_BMSR
call e3c59x_mdio_read ; returns with window #4
test al, 100000b ; auto-neg complete?
jnz .auto_neg_ok
jmp .fail_finish
.auto_neg_ok:
; compare advertisement and link partner ability registers
pop eax
push eax
mov al, E3C59X_REG_MII_ANAR
call e3c59x_mdio_read ; returns with window #4
xchg eax, [esp]
mov al, E3C59X_REG_MII_ANLPAR
call e3c59x_mdio_read ; returns with window #4
pop ebx
and eax, ebx
and eax, 1111100000b
push eax
if defined E3C59X_DEBUG
mov word [e3c59x_link_type], ax
end if ; defined E3C59X_DEBUG
; switch to register window 3
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3
out dx, ax
; set full-duplex mode
lea edx, [ebp+E3C59X_REG_MAC_CONTROL]
in ax, dx
and ax, not 0x120 ; clear full duplex and flow control
pop ebx
test ebx, (1010b shl 5) ; check for full-duplex
jz .half_duplex
or ax, 0x120 ; set full duplex and flow control
.half_duplex:
out dx, ax
mov al, 1
ret
.no_ext_cap:
; not yet implemented BCM5000
.fail_finish:
pop eax
xor al, al
ret
 
;***************************************************************************
; Function
; e3c59x_try_mii
; Description
; e3c59x_try_MII checks the on-chip auto-negotiation logic
; or an off-chip MII PHY, depending upon what is set in
; xcvrSelect by the caller.
; It exits when it finds the first device with a good link.
; Parameters
; ebp - io_addr
; Return value
; al - 0
; al - 1
; Destroyed registers
; eax, ebx, ecx, edx, esi
;
;***************************************************************************
align 4
e3c59x_try_mii:
; switch to register window 3
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3
out dx, ax
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
in eax, dx
and eax, (1111b shl 20)
cmp eax, (1000b shl 20) ; is auto-negotiation set?
jne .mii_device
; auto-negotiation is set
; switch to register window 4
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4
out dx, ax
; PHY==24 is the on-chip auto-negotiation logic
; it supports only 10base-T and 100base-TX
mov ah, 24
call e3c59x_try_phy
test al, al
jz .fail_finish
mov cl, 24
jmp .check_preamble
.mii_device:
cmp eax, (0110b shl 20)
jne .fail_finish
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4
out dx, ax
lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
in ax, dx
and al, (1 shl E3C59X_BIT_MGMT_DIR) or (1 shl E3C59X_BIT_MGMT_DATA)
cmp al, (1 shl E3C59X_BIT_MGMT_DATA)
je .serch_for_phy
xor al, al
ret
.serch_for_phy:
; search for PHY
mov cl, 31
.search_phy_loop:
cmp cl, 24
je .next_phy
mov ah, cl ; ah = phy
mov al, E3C59X_REG_MII_BMCR ; al = Basic Mode Status Register
push ecx
call e3c59x_mdio_read
pop ecx
test ax, ax
jz .next_phy
cmp ax, 0xffff
je .next_phy
mov ah, cl ; ah = phy
push ecx
call e3c59x_try_phy
pop ecx
test al, al
jnz .check_preamble
.next_phy:
dec cl
jns .search_phy_loop
.fail_finish:
xor al, al
ret
; epilog
.check_preamble:
push eax ; eax contains the return value of e3c59x_try_phy
; check hard coded preamble forcing
movzx eax, byte [e3c59x_ver_id]
test word [eax*4+e3c59x_hw_versions+2], EXTRA_PREAMBLE
setnz [e3c59x_preamble] ; force preamble
jnz .finish
; check mii for preamble suppression
mov ah, cl
mov al, E3C59X_REG_MII_BMSR
call e3c59x_mdio_read
test al, 1000000b ; preamble suppression?
setz [e3c59x_preamble] ; no
.finish:
pop eax
ret
 
;***************************************************************************
; Function
; e3c59x_test_packet
; Description
; e3c59x_try_loopback try a loopback packet for 10BASE2 or AUI port
; Parameters
; ebp - io_addr
; Return value
; al - 0
; al - 1
; Destroyed registers
; eax, ebx, ecx, edx, edi, esi
;
;***************************************************************************
align 4
e3c59x_test_packet:
; switch to register window 3
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3
out dx, ax
; set fullDuplexEnable in MacControl register
lea edx, [ebp+E3C59X_REG_MAC_CONTROL]
in ax, dx
or ax, 0x120
out dx, ax
; switch to register window 5
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+5
out dx, ax
; set RxFilter to enable individual address matches
mov ax, (10000b shl 11)
lea edx, [ebp+E3C59X_REG_RX_FILTER]
in al, dx
or al, 1
lea edx, [ebp+E3C59X_REG_COMMAND]
out dx, ax
; issue RxEnable and TxEnable
call e3c59x_rx_reset
call e3c59x_tx_reset
; download a self-directed test packet
mov edi, node_addr
mov bx, 0x0608 ; packet type
mov esi, e3c59x_self_directed_packet
mov ecx, 6 ; 6 + 6 + 2 + 6 = 20 bytes
call dword [e3c59x_transmit_function]
; wait for 2s
mov esi, 2000 ; 2000ms = 2s
call delay_ms
; check if self-directed packet is received
call dword [e3c59x_receive_function]
test al, al
jnz .finish
; switch to register window 3
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3
out dx, ax
; clear fullDuplexEnable in MacControl register
lea edx, [ebp+E3C59X_REG_MAC_CONTROL]
in ax, dx
and ax, not 0x120
out dx, ax
xor al, al
.finish:
ret
 
;***************************************************************************
; Function
; e3c59x_try_loopback
; Description
; tries a loopback packet for 10BASE2 or AUI port
; Parameters
; al - 0: 10Mbps AUI connector
; 1: 10BASE-2
; ebp - io_addr
; Return value
; al - 0
; al - 1
; Destroyed registers
; eax, ebx, ecx, edx, edi, esi
;
;***************************************************************************
align 4
e3c59x_try_loopback:
push eax
; switch to register window 3
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3
out dx, ax
pop eax
push eax
if defined E3C59X_DEBUG
mov bl, al
inc bl
shl bl, 3
or byte [e3c59x_link_type+1], bl
end if ; defined E3C59X_DEBUG
test al, al ; aui or coax?
jz .complete_loopback
; enable 100BASE-2 DC-DC converter
mov ax, (10b shl 11) ; EnableDcConverter
out dx, ax
.complete_loopback:
mov cl, 2 ; give a port 3 chances to complete a loopback
.next_try:
push ecx
call e3c59x_test_packet
pop ecx
test al, al
jnz .finish
dec cl
jns .next_try
.finish:
xchg eax, [esp]
test al, al
jz .aui_finish
; issue DisableDcConverter command
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, (10111b shl 11)
out dx, ax
.aui_finish:
pop eax ; al contains the result of operation
if defined E3C59X_DEBUG
test al, al
jnz @f
and byte [e3c59x_link_type+1], not 11000b
@@:
end if ; defined E3C59X_DEBUG
ret
 
;***************************************************************************
; Function
; e3c59x_set_available_media
; Description
; sets the first available media
; Parameters
; ebp - io_addr
; Return value
; al - 0
; al - 1
; Destroyed registers
; eax, edx
;
;***************************************************************************
align 4
e3c59x_set_available_media:
; switch to register window 3
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3
out dx, ax
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
in eax, dx
push eax
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
in ax, dx
test al, 10b
jz @f
; baseTXAvailable
pop eax
and eax, not (1111b shl 20)
or eax, (100b shl 20)
if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD
mov word [e3c59x_link_type], (1 shl 8)
else if defined E3C59X_DEBUG
mov word [e3c59x_link_type], (1 shl 7)
end if
jmp .set_media
@@:
test al, 100b
jz @f
; baseFXAvailable
pop eax
and eax, not (1111b shl 20)
or eax, (101b shl 20)
if defined E3C59X_DEBUG
mov word [e3c59x_link_type], (1 shl 10)
end if
jmp .set_media
@@:
test al, 1000000b
jz @f
; miiDevice
pop eax
and eax, not (1111b shl 20)
or eax, (0110b shl 20)
if defined E3C59X_DEBUG
mov word [e3c59x_link_type], (1 shl 13)
end if
jmp .set_media
@@:
test al, 1000b
jz @f
.set_default:
; 10bTAvailable
pop eax
and eax, not (1111b shl 20)
if defined E3C59X_DEBUG & defined E3C59X_FORCE_FD
mov word [e3c59x_link_type], (1 shl 6)
else if defined E3C59X_DEBUG
mov word [e3c59x_link_type], (1 shl 5)
end if ; E3C59X_FORCE_FD
jmp .set_media
@@:
test al, 10000b
jz @f
; coaxAvailable
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, (10b shl 11) ; EnableDcConverter
out dx, ax
pop eax
and eax, not (1111b shl 20)
or eax, (11b shl 20)
if defined E3C59X_DEBUG
mov word [e3c59x_link_type], (1 shl 12)
end if ; defined E3C59X_DEBUG
jmp .set_media
@@:
test al, 10000b
jz .set_default
; auiAvailable
pop eax
and eax, not (1111b shl 20)
or eax, (1 shl 20)
if defined E3C59X_DEBUG
mov word [e3c59x_link_type], (1 shl 11)
end if ; defined E3C59X_DEBUG
.set_media:
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
out dx, eax
if defined E3C59X_FORCE_FD
; set fullDuplexEnable in MacControl register
lea edx, [ebp+E3C59X_REG_MAC_CONTROL]
in ax, dx
or ax, 0x120
out dx, ax
end if ; E3C59X_FORCE_FD
mov al, 1
ret
 
;***************************************************************************
; Function
; e3c59x_set_active_port
; Description
; It selects the media port (transceiver) to be used
; Parameters:
; ebp - io_addr
; Return value:
; Destroyed registers
; eax, ebx, ecx, edx, edi, esi
;
;***************************************************************************
align 4
e3c59x_set_active_port:
; switch to register window 3
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3
out dx, ax
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
in eax, dx
test eax, (1 shl 24) ; check if autoselect enable
jz .set_first_available_media
; check 100BASE-TX and 10BASE-T
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
in ax, dx
test al, 1010b ; check whether 100BASE-TX or 10BASE-T available
jz .mii_device ; they are not available
; set auto-negotiation
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
in eax, dx
and eax, not (1111b shl 20)
or eax, (1000b shl 20)
out dx, eax
call e3c59x_try_mii
test al, al
jz .mii_device
ret
.mii_device:
; switch to register window 3
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3
out dx, ax
; check for off-chip mii device
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
in ax, dx
test al, 1000000b ; check miiDevice
jz .base_fx
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
in eax, dx
and eax, not (1111b shl 20)
or eax, (0110b shl 20) ; set MIIDevice
out dx, eax
call e3c59x_try_mii
test al, al
jz .base_fx
ret
.base_fx:
; switch to register window 3
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3
out dx, ax
; check for 100BASE-FX
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
in ax, dx ; read media option register
test al, 100b ; check 100BASE-FX
jz .aui_enable
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
in eax, dx
and eax, not (1111b shl 20)
or eax, (0101b shl 20) ; set 100base-FX
out dx, eax
call e3c59x_try_link_detect
test al, al
jz .aui_enable
ret
.aui_enable:
; switch to register window 3
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3
out dx, ax
; check for 10Mbps AUI connector
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
in ax, dx ; read media option register
test al, 100000b ; check 10Mbps AUI connector
jz .coax_available
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
in eax, dx
and eax, not (1111b shl 20)
or eax, (0001b shl 20) ; set 10Mbps AUI connector
out dx, eax
xor al, al ; try 10Mbps AUI connector
call e3c59x_try_loopback
test al, al
jz .coax_available
ret
.coax_available:
; switch to register window 3
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+3
out dx, ax
; check for coaxial 10BASE-2 port
lea edx, [ebp+E3C59X_REG_MEDIA_OPTIONS]
in ax, dx ; read media option register
test al, 10000b ; check 10BASE-2
jz .set_first_available_media
lea edx, [ebp+E3C59X_REG_INTERNAL_CONFIG]
in eax, dx
and eax, not (1111b shl 20)
or eax, (0011b shl 20) ; set 10BASE-2
out dx, eax
mov al, 1
call e3c59x_try_loopback
test al, al
jz .set_first_available_media
ret
.set_first_available_media:
jmp e3c59x_set_available_media
 
;***************************************************************************
; Function
; e3c59x_wake_up
; Description
; set the power state to D0
; Destroyed registers
; eax, ebx, ecx, edx, edi, esi
;
;***************************************************************************
align 4
e3c59x_wake_up:
; wake up - we directly do it by programming PCI
; check if the device is power management capable
mov al, 2
mov ah, [pci_bus]
mov bl, PCI_REG_STATUS
mov bh, [pci_dev]
push eax ebx
call pci_read_reg
test al, 10000b ; is there "new capabilities" linked list?
pop ebx eax
jz .device_awake
; search for power management register
mov al, 1
mov bl, PCI_REG_CAP_PTR
push eax ebx
call pci_read_reg
mov cl, al
cmp cl, 0x3f
pop ebx eax
jbe .device_awake
; traverse the list
mov al, 2
.pm_loop:
mov bl, cl
push eax ebx
call pci_read_reg
cmp al, 1
je .set_pm_state
test ah, ah
mov cl, ah
pop ebx eax
jnz .pm_loop
jmp .device_awake
; waku up the device if necessary
.set_pm_state:
pop ebx eax
add bl, PCI_REG_PM_CTRL
push eax ebx
call pci_read_reg
mov cx, ax
test cl, 3
pop ebx eax
jz .device_awake
and cl, not 11b ; set state to D0
call pci_write_reg
.device_awake:
ret
 
;***************************************************************************
; Function
; e3c59x_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
; Destroyed registers
; eax, ebx, ecx, edx, edi, esi
;
;***************************************************************************
align 4
e3c59x_probe:
movzx ebp, word [io_addr]
mov al, 2
mov ah, [pci_bus]
mov bh, [pci_dev]
mov bl, PCI_REG_COMMAND
push ebp eax ebx
call pci_read_reg
mov cx, ax
or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO)
and cl, not (1 shl PCI_BIT_MMIO)
pop ebx eax
call pci_write_reg
; wake up the card
call e3c59x_wake_up
pop ebp
; get chip version
mov ax, [pci_data+2]
mov ecx, E3C59X_HW_VERSIONS_SIZE/4-1
.chip_ver_loop:
cmp ax, [e3c59x_hw_versions+ecx*4]
jz .chip_ver_found
dec ecx
jns .chip_ver_loop
xor ecx, ecx
.chip_ver_found:
mov [e3c59x_ver_id], cl
test word [e3c59x_hw_versions+2+ecx*4], HAS_HWCKSM
setnz [e3c59x_has_hwcksm]
; set pci latency for vortex cards
test word [e3c59x_hw_versions+2+ecx*4], IS_VORTEX
jz .not_vortex
mov cx, 11111000b ; 248 = max latency
mov al, 1
mov ah, [pci_bus]
mov bl, PCI_REG_LATENCY
mov bh, [pci_dev]
call pci_write_reg
.not_vortex:
; set RX/TX functions
mov ax, E3C59X_EEPROM_REG_CAPABILITIES
call e3c59x_read_eeprom
test al, 100000b ; full bus master?
setnz [e3c59x_full_bus_master]
jnz .boomerang_func
mov dword [e3c59x_transmit_function], e3c59x_vortex_transmit
mov dword [e3c59x_receive_function], e3c59x_vortex_poll
jmp @f
.boomerang_func: ; full bus master, so use boomerang functions
mov dword [e3c59x_transmit_function], e3c59x_boomerang_transmit
mov dword [e3c59x_receive_function], e3c59x_boomerang_poll
@@:
; read MAC from eeprom
mov ecx, 2
.mac_loop:
lea ax, [E3C59X_EEPROM_REG_OEM_NODE_ADDR+ecx]
call e3c59x_read_eeprom
xchg ah, al ; htons
mov [node_addr+ecx*2], ax
dec ecx
jns .mac_loop
test byte [e3c59x_full_bus_master], 0xff
jz .set_preamble
; switch to register window 2
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+2
out dx, ax
; activate xcvr by setting some magic bits
lea edx, [ebp+E3C59X_REG_RESET_OPTIONS]
in ax, dx
and ax, not 0x4010
movzx ebx, byte [e3c59x_ver_id]
test word [ebx*4+e3c59x_hw_versions+2], INVERT_LED_PWR
jz @f
or al, 0x10
@@:
test word [ebx*4+e3c59x_hw_versions+2], INVERT_MII_PWR
jz @f
or ah, 0x40
@@:
out dx, ax
.set_preamble:
; use preamble as default
mov byte [e3c59x_preamble], 1 ; enable preamble
 
;***************************************************************************
; Function
; e3c59x_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; Destroyed registers
; eax, ebx, ecx, edx, edi, esi
;
;***************************************************************************
e3c59x_reset:
; issue global reset
call e3c59x_global_reset
; disable interrupts
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, (1110b shl 11)
out dx, ax
; enable Statistics
mov ax, (10101b shl 11)
out dx, ax
; set indication
mov ax, (1111b shl 11) or 0x6c6
out dx, ax
; acknowledge (clear) every interrupt indicator
mov ax, (1101b shl 11) or 0x661
out dx, ax
; switch to register window 2
mov ax, E3C59X_SELECT_REGISTER_WINDOW+2
out dx, ax
; write MAC addres back into the station address registers
lea edx, [ebp+E3C59X_REG_STATION_ADDRESS_LO]
mov esi, node_addr
cld
outsw
add edx, 2
outsw
add edx, 2
outsw
add edx, 2
; clear station mask
xor eax, eax
out dx, ax
add edx, 2
out dx, ax
add edx, 2
out dx, ax
; switch to register window 6
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+6
out dx, ax
; clear all statistics by reading
lea edx, [ebp+E3C59X_REG_CARRIER_LOST]
mov cl, 9
.stat_clearing_loop:
in al, dx
inc edx
dec cl
jns .stat_clearing_loop
in ax, dx
add dx, 2
in ax, dx
; switch to register window 4
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4
out dx, ax
; clear BadSSD
lea edx, [ebp+E3C59X_REG_BAD_SSD]
in al, dx
; clear extra statistics bit in NetworkDiagnostic
lea edx, [ebp+E3C59X_REG_NETWORK_DIAGNOSTIC]
in ax, dx
or ax, 0x0040
out dx, ax
; SetRxEarlyThreshold
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, (10001b shl 11)+(E3C59X_MAX_ETH_PKT_SIZE shr 2)
out dx, ax
test byte [e3c59x_full_bus_master], 0xff
jz .skip_boomerang_setting
; set upRxEarlyEnable
lea edx, [ebp+E3C59X_REG_DMA_CTRL]
in eax, dx
or eax, 0x20
out dx, eax
; TxFreeThreshold
lea edx, [ebp+E3C59X_REG_TX_FREE_THRESH]
mov al, (E3C59X_MAX_ETH_PKT_SIZE / 256)
out dx, al
; program DnListPtr
lea edx, [ebp+E3C59X_REG_DN_LIST_PTR]
xor eax, eax
out dx, eax
.skip_boomerang_setting:
; initialization
call e3c59x_rx_reset
call e3c59x_tx_reset
call e3c59x_set_active_port
call e3c59x_rx_reset
call e3c59x_tx_reset
; switch to register window 5
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+5
out dx, ax
; program RxFilter for promiscuous operation
mov ax, (10000b shl 11)
lea edx, [ebp+E3C59X_REG_RX_FILTER]
in al, dx
or al, 1111b
lea edx, [ebp+E3C59X_REG_COMMAND]
out dx, ax
; switch to register window 4
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4
out dx, ax
; wait for linkDetect
lea edx, [ebp+E3C59X_REG_MEDIA_STATUS]
mov cl, 20 ; wait for max 2s
mov esi, 100 ; 100ms
.link_detect_loop:
call delay_ms
in ax, dx
test ah, 1000b ; linkDetect
jnz @f
dec cl
jnz .link_detect_loop
@@:
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
if defined E3C59X_DEBUG
call e3c59x_debug
end if ; defined E3C59X_DEBUG
ret
 
;***************************************************************************
; Function
; e3c59x_global_reset
; Description
; resets the device
; Parameters:
; ebp - io_addr
; Return value:
; Destroyed registers
; ax, ecx, edx, esi
;
;***************************************************************************
align 4
e3c59x_global_reset:
; GlobalReset
lea edx, [ebp+E3C59X_REG_COMMAND]
xor eax, eax
; or al, 0x14
out dx, ax
; wait for GlobalReset to complete
mov ecx, 64000
.global_reset_loop:
in ax, dx
test ah, 10000b ; check CmdInProgress
jz .finish
dec ecx
jnz .global_reset_loop
.finish:
; wait for 2 seconds for NIC to boot
mov esi, 2000 ; 2000ms = 2s
push ebp
call delay_ms
pop ebp
ret
 
;***************************************************************************
; Function
; e3c59x_tx_reset
; Description
; resets and enables transmitter engine
; Parameters:
; ebp - io_addr
; Return value:
; Destroyed registers
; ax, ecx, edx
;
;***************************************************************************
align 4
e3c59x_tx_reset:
; TxReset
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, (01011b shl 11)
out dx, ax
; Wait for TxReset to complete
mov ecx, 200000
.tx_reset_loop:
in ax, dx
test ah, 10000b ; check CmdInProgress
jz .tx_set_prev
dec ecx
jns .tx_reset_loop
.tx_set_prev:
test byte [e3c59x_full_bus_master], 0xff
jz .tx_enable
; init last_dpd
mov dword [e3c59x_prev_dpd], e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE
mov dword [e3c59x_prev_tx_frame], e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE
.tx_enable:
mov ax, (01001b shl 11) ; TxEnable
out dx, ax
ret
 
;***************************************************************************
; Function
; e3c59x_rx_reset
; Description
; resets and enables receiver engine
; Parameters:
; ebp - io_addr
; Return value:
; Destroyed registers
; eax, ebx, ecx, edx, edi, esi
;
;***************************************************************************
align 4
e3c59x_rx_reset:
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, (0101b shl 11) or 0x4 ; RxReset
out dx, ax
; wait for RxReset to complete
mov ecx, 200000
.rx_reset_loop:
in ax, dx
test ah, 10000b ; check CmdInProgress
jz .setup_upd
dec ecx
jns .rx_reset_loop
.setup_upd:
; check if full bus mastering
test byte [e3c59x_full_bus_master], 0xff
jz .rx_enable
; create upd ring
mov eax, e3c59x_upd_buff
zero_to_virt eax
mov [e3c59x_curr_upd], eax
mov esi, eax
virt_to_dma esi
mov edi, e3c59x_rx_buff
zero_to_dma edi
mov ebx, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE
zero_to_virt ebx
mov cl, E3C59X_NUM_RX_DESC-1
.upd_loop:
mov [ebx+E3C59X_UPD_UP_NEXT_PTR], esi
and dword [eax+E3C59X_UPD_PKT_STATUS], 0
mov [eax+E3C59X_UPD_UP_FRAG_ADDR], edi
mov dword [eax+E3C59X_UPD_UP_FRAG_LEN], E3C59X_MAX_ETH_FRAME_SIZE or (1 shl 31)
add edi, E3C59X_MAX_ETH_FRAME_SIZE
add esi, E3C59X_UPD_SIZE
mov ebx, eax
add eax, E3C59X_UPD_SIZE
dec cl
jns .upd_loop
mov eax, e3c59x_upd_buff
zero_to_dma eax
lea edx, [ebp+E3C59X_REG_UP_LIST_PTR]
out dx, eax ; write E3C59X_REG_UP_LIST_PTR
lea edx, [ebp+E3C59X_REG_COMMAND]
.rx_enable:
mov ax, (00100b shl 11) ; RxEnable
out dx, ax
ret
 
;***************************************************************************
; Function
; e3c59x_write_eeprom
; Description
; reads eeprom
; Note : the caller must switch to the register window 0
; before calling this function
; Parameters:
; ax - register to be read (only the first 63 words can be read)
; cx - value to be read into the register
; Return value:
; ax - word read
; Destroyed registers
; ax, ebx, edx
;
;***************************************************************************
; align 4
;e3c59x_write_eeprom:
; mov edx, [io_addr]
; add edx, E3C59X_REG_EEPROM_COMMAND
; cmp ah, 11b
; ja .finish ; address may have a value of maximal 1023
; shl ax, 2
; shr al, 2
; push eax
;; wait for busy
; mov ebx, 0xffff
;@@:
; in ax, dx
; test ah, 0x80
; jz .write_enable
; dec ebx
; jns @r
;; write enable
;.write_enable:
; xor eax, eax
; mov eax, (11b shl 4)
; out dx, ax
;; wait for busy
; mov ebx, 0xffff
;@@:
; in ax, dx
; test ah, 0x80
; jz .erase_loop
; dec ebx
; jns @r
;.erase_loop:
; pop eax
; push eax
; or ax, (11b shl 6) ; erase register
; out dx, ax
; mov ebx, 0xffff
;@@:
; in ax, dx
; test ah, 0x80
; jz .write_reg
; dec ebx
; jns @r
;.write_reg:
; add edx, E3C59X_REG_EEPROM_DATA-E3C59X_REG_EEPROM_COMMAND
; mov eax, ecx
; out dx, ax
;; write enable
; add edx, E3C59X_REG_EEPROM_COMMAND-E3C59X_REG_EEPROM_DATA
; xor eax, eax
; mov eax, (11b shl 4)
; out dx, ax
; wait for busy
; mov ebx, 0xffff
;@@:
; in ax, dx
; test ah, 0x80
; jz .issue_write_reg
; dec ebx
; jns @r
;.issue_write_reg:
; pop eax
; or ax, 01b shl 6
; out dx, ax
;.finish:
; ret
;***************************************************************************
; Function
; e3c59x_read_eeprom
; Description
; reads eeprom
; Parameters:
; ax - register to be read (only the first 63 words can be read)
; ebp - io_addr
; Return value:
; ax - word read
; Destroyed registers
; ax, ebx, edx, ebp
;
;***************************************************************************
align 4
e3c59x_read_eeprom:
push eax
; switch to register window 0
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+0
out dx, ax
pop eax
and ax, 111111b ; take only the first 6 bits into account
movzx ebx, byte [e3c59x_ver_id]
test word [ebx*4+e3c59x_hw_versions+2], EEPROM_8BIT
jz @f
add ax, 0x230 ; hardware constant
jmp .read
@@:
add ax, E3C59X_EEPROM_CMD_READ
test word [ebx*4+e3c59x_hw_versions+2], EEPROM_OFFSET
jz .read
add ax, 0x30
.read:
lea edx, [ebp+E3C59X_REG_EEPROM_COMMAND]
out dx, ax
mov ebx, 0xffff ; duration of about 162 us ;-)
.wait_for_reading:
in ax, dx
test ah, 0x80 ; check bit eepromBusy
jz .read_data
dec ebx
jns .wait_for_reading
.read_data:
lea edx, [ebp+E3C59X_REG_EEPROM_DATA]
in ax, dx
ret
 
;***************************************************************************
; Function
; e3c59x_mdio_sync
; Description
; initial synchronization
; Parameters
; ebp - io_addr
; Return value
; Destroyed registers
; ax, edx, cl
;
;***************************************************************************
align 4
e3c59x_mdio_sync:
; switch to register window 4
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+4
out dx, ax
cmp byte [e3c59x_preamble], 0
je .no_preamble
; send 32 logic ones
lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
mov cl, 31
.loop:
mov ax, (1 shl E3C59X_BIT_MGMT_DATA) or (1 shl E3C59X_BIT_MGMT_DIR)
out dx, ax
in ax, dx ; delay
mov ax, (1 shl E3C59X_BIT_MGMT_DATA) \
or (1 shl E3C59X_BIT_MGMT_DIR) \
or (1 shl E3C59X_BIT_MGMT_CLK)
out dx, ax
in ax, dx ; delay
dec cl
jns .loop
.no_preamble:
ret
 
;***************************************************************************
; Function
; e3c59x_mdio_read
; Description
; read MII register
; see page 16 in D83840A.pdf
; Parameters
; ah - PHY addr
; al - register addr
; ebp - io_addr
; Return value
; ax - register read
; Destroyed registers
; eax, ebx, cx, edx
;
;***************************************************************************
align 4
e3c59x_mdio_read:
push eax
call e3c59x_mdio_sync ; returns with window #4
pop eax
lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
shl al, 3
shr ax, 3
and ax, not E3C59X_MII_CMD_MASK
or ax, E3C59X_MII_CMD_READ
mov ebx, eax
xor ecx, ecx
mov cl, 13
.cmd_loop:
mov ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii
bt ebx, ecx
jnc .zero_bit
or al, (1 shl E3C59X_BIT_MGMT_DATA)
.zero_bit:
out dx, ax
push eax
in ax, dx ; delay
pop eax
or al, (1 shl E3C59X_BIT_MGMT_CLK) ; write
out dx, ax
in ax, dx ; delay
dec cl
jns .cmd_loop
; read data (18 bits with the two transition bits)
mov cl, 17
xor ebx, ebx
.read_loop:
shl ebx, 1
xor eax, eax ; read comand
out dx, ax
in ax, dx ; delay
in ax, dx
test al, (1 shl E3C59X_BIT_MGMT_DATA)
jz .dont_set
inc ebx
.dont_set:
mov ax, (1 shl E3C59X_BIT_MGMT_CLK)
out dx, ax
in ax, dx ; delay
dec cl
jns .read_loop
mov eax, ebx
ret
 
;***************************************************************************
; Function
; e3c59x_mdio_write
; Description
; write MII register
; see page 16 in D83840A.pdf
; Parameters
; ah - PHY addr
; al - register addr
; bx - word to be written
; ebp - io_addr
; Return value
; ax - register read
; Destroyed registers
; eax, ebx, cx, edx
;
;***************************************************************************
align 4
e3c59x_mdio_write:
push eax
call e3c59x_mdio_sync
pop eax
lea edx, [ebp+E3C59X_REG_PHYSICAL_MGMT]
shl al, 3
shr ax, 3
and ax, not E3C59X_MII_CMD_MASK
or ax, E3C59X_MII_CMD_WRITE
shl eax, 2
or eax, 10b ; transition bits
shl eax, 16
mov ax, bx
mov ebx, eax
mov ecx, 31
.cmd_loop:
mov ax, (1 shl E3C59X_BIT_MGMT_DIR) ; write mii
bt ebx, ecx
jnc .zero_bit
or al, (1 shl E3C59X_BIT_MGMT_DATA)
.zero_bit:
out dx, ax
push eax
in ax, dx ; delay
pop eax
or al, (1 shl E3C59X_BIT_MGMT_CLK) ; write
out dx, ax
in ax, dx ; delay
dec ecx
jns .cmd_loop
ret
 
;***************************************************************************
; Function
; e3c59x_transmit
; Description
; Transmits a packet of data via the ethernet card
; edi - Pointer to 48 bit destination address
; bx - Type of packet
; ecx - size of packet
; esi - pointer to packet data
; ebp - io_addr
; Destroyed registers
; eax, ecx, edx, ebp
;
;***************************************************************************
align 4
e3c59x_transmit:
jmp dword [e3c59x_transmit_function]
 
;***************************************************************************
; Function
; e3c59x_check_tx_status
; Description
; Checks TxStatus queue.
; Return value
; al - 0 no error was found
; al - 1 error was found TxReset is needed
; Destroyed registers
; eax, ecx, edx, ebp
;
;***************************************************************************
e3c59x_check_tx_status:
movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC
; clear TxStatus queue
lea edx, [ebp+E3C59X_REG_TX_STATUS]
mov cl, 31 ; max number of queue entries
.tx_status_loop:
in al, dx
test al, al
jz .finish ; no error
test al, 0x3f
jnz .finish ; error
.no_error_found:
; clear current TxStatus entry which advances the next one
xor al, al
out dx, al
dec cl
jns .tx_status_loop
.finish:
ret
 
;***************************************************************************
; Function
; e3c59x_vortex_transmit
; Description
; Transmits a packet of data via the ethernet card
; edi - Pointer to 48 bit destination address
; bx - Type of packet
; ecx - size of packet
; esi - pointer to packet data
; ebp - io_addr
; Destroyed registers
; eax, edx, ecx, edi, esi, ebp
;
;***************************************************************************
align 4
e3c59x_vortex_transmit:
push ecx
call e3c59x_check_tx_status
pop ecx
test al, al
jz .no_error_found
jmp e3c59x_tx_reset
.no_error_found:
; switch to register window 7
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+7
out dx, ax
; check for master operation in progress
lea edx, [ebp+E3C59X_REG_MASTER_STATUS]
in ax, dx
test ah, 0x80
jnz .finish ; no DMA for sending
; dword boundary correction
cmp ecx, E3C59X_MAX_ETH_FRAME_SIZE
ja .finish ; packet is too long
; write Frame Start Header
mov eax, ecx
; add header length and extend the complete length to dword boundary
add eax, ETH_HLEN+3
and eax, not 3
lea edx, [ebp+E3C59X_REG_TX_DATA]
out dx, eax
; prepare the complete frame
push esi
mov esi, edi
mov edi, e3c59x_tx_buff
zero_to_virt edi
cld
; copy destination address
movsd
movsw
; copy source address
mov esi, node_addr
movsd
movsw
; copy packet type
mov [edi], bx
add edi, 2
; copy packet data
pop esi
push ecx
shr ecx, 2
rep movsd
pop ecx
and ecx, 3
rep movsb
mov ecx, eax
; program frame address to be sent
lea edx, [ebp+E3C59X_REG_MASTER_ADDRESS]
mov eax, e3c59x_tx_buff
zero_to_dma eax
out dx, eax
; program frame length
lea edx, [ebp+E3C59X_REG_MASTER_LEN]
mov eax, ecx
out dx, ax
; start DMA Down
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, (10100b shl 11) + 1 ; StartDMADown
out dx, ax
.finish:
ret
 
;***************************************************************************
; Function
; e3c59x_boomerang_transmit
; Description
; Transmits a packet of data via the ethernet card
; edi - Pointer to 48 bit destination address
; bx - Type of packet
; ecx - size of packet
; esi - pointer to packet data
; ebp - io_addr
; Destroyed registers
; eax, ebx, ecx, edx, esi, edi, ebp
;
;***************************************************************************
align 4
e3c59x_boomerang_transmit:
push ecx
call e3c59x_check_tx_status
pop ecx
test al, al
jz .no_error_found
jmp e3c59x_tx_reset
.no_error_found:
cmp ecx, E3C59X_MAX_ETH_FRAME_SIZE
ja .finish ; packet is too long
; calculate descriptor address
mov eax, [e3c59x_prev_dpd]
cmp eax, e3c59x_dpd_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_DPD_SIZE
jb @f
; wrap around
mov eax, e3c59x_dpd_buff-E3C59X_DPD_SIZE
@@:
add eax, E3C59X_DPD_SIZE
zero_to_virt eax
push eax
; check DnListPtr
lea edx, [ebp+E3C59X_REG_DN_LIST_PTR]
in eax, dx
; mark if Dn_List_Ptr is cleared
test eax, eax
setz [e3c59x_dn_list_ptr_cleared]
; finish if no more free descriptor is available - FIXME!
cmp eax, [esp]
pop eax
jz .finish
push eax esi
mov esi, edi
; calculate tx_buffer address
mov edi, [e3c59x_prev_tx_frame]
cmp edi, e3c59x_tx_buff+(E3C59X_NUM_TX_DESC-1)*E3C59X_MAX_ETH_FRAME_SIZE
jb @f
; wrap around
mov edi, e3c59x_tx_buff-E3C59X_MAX_ETH_FRAME_SIZE
@@:
add edi, E3C59X_MAX_ETH_FRAME_SIZE
zero_to_virt edi
mov eax, edi
cld
; copy destination address
movsd
movsw
; copy source address
mov esi, node_addr
movsd
movsw
; copy packet type
mov [edi], bx
add edi, 2
; copy packet data
pop esi
push ecx
shr ecx, 2
rep movsd
pop ecx
push ecx
and ecx, 3
rep movsb
; padding, do we really need it?
pop ecx
add ecx, ETH_HLEN
cmp ecx, ETH_ZLEN
jae @f
mov ecx, ETH_ZLEN
@@:
; calculate
mov ebx, ecx
;test byte [e3c59x_has_hwcksm], 0xff
;jz @f
;or ebx, (1 shl 26) ; set AddTcpChecksum
;@@:
or ebx, 0x8000 ; transmission complete notification
or ecx, 0x80000000 ; last fragment
; program DPD
mov edi, eax
pop eax
and dword [eax+E3C59X_DPD_DN_NEXT_PTR], 0
mov dword [eax+E3C59X_DPD_FRAME_START_HDR], ebx
virt_to_dma edi
mov dword [eax+E3C59X_DPD_DN_FRAG_ADDR], edi
mov [eax+E3C59X_DPD_DN_FRAG_LEN], ecx
; calculate physical address
virt_to_dma eax
push eax
cmp byte [e3c59x_dn_list_ptr_cleared], 0
jz .add_to_list
; write Dn_List_Ptr
out dx, eax
jmp .finish
.add_to_list:
; DnStall
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, ((110b shl 11)+2)
out dx, ax
; wait for DnStall to complete
mov ecx, 6000
.wait_for_stall:
in ax, dx ; read E3C59X_REG_INT_STATUS
test ah, 10000b
jz .dnstall_ok
dec ecx
jnz .wait_for_stall
.dnstall_ok:
pop eax
push eax
mov ebx, [e3c59x_prev_dpd]
zero_to_virt ebx
mov [ebx], eax
lea edx, [ebp+E3C59X_REG_DN_LIST_PTR]
in eax, dx
test eax, eax
jnz .dnunstall
; if Dn_List_Ptr has been cleared fill it up
pop eax
push eax
out dx, eax
.dnunstall:
; DnUnStall
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, ((110b shl 11)+3)
out dx, ax
.finish:
pop eax
dma_to_zero eax
mov [e3c59x_prev_dpd], eax
dma_to_zero edi
mov [e3c59x_prev_tx_frame], edi
ret
 
;***************************************************************************
; Function
; e3c59x_poll
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
; Destroyed registers
; eax, ebx, edx, ecx, edi, esi, ebp
;
;***************************************************************************
align 4
e3c59x_poll:
jmp dword [e3c59x_receive_function]
 
;***************************************************************************
; Function
; e3c59x_vortex_poll
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
; Parameters
; ebp - io_addr
; Return value
; al - 0 ; no packet received
; al - 1 ; packet received
; Destroyed registers
; eax, ebx, edx, ecx, edi, esi, ebp
;
;***************************************************************************
align 4
e3c59x_vortex_poll:
and word [eth_rx_data_len], 0 ; assume no packet received
movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC
.rx_status_loop:
; examine RxStatus
lea edx, [ebp+E3C59X_REG_RX_STATUS]
in ax, dx
test ax, ax
jz .finish
test ah, 0x80 ; rxIncomplete
jz .check_error
jmp .finish
.check_error:
test ah, 0x40
jz .check_length
; discard the top frame received advancing the next one
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, (01000b shl 11)
out dx, ax
jmp .rx_status_loop
.check_length:
and eax, 0x1fff
cmp eax, E3C59X_MAX_ETH_PKT_SIZE
ja .discard_frame ; frame is too long discard it
.check_dma:
push eax
; switch to register window 7
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, E3C59X_SELECT_REGISTER_WINDOW+7
out dx, ax
; check for master operation in progress
lea edx, [ebp+E3C59X_REG_MASTER_STATUS]
in ax, dx
test ah, 0x80
jz .read_frame ; no DMA for receiving
pop eax
jmp .finish
.read_frame:
; program buffer address to read in
lea edx, [ebp+E3C59X_REG_MASTER_ADDRESS]
if defined E3C59X_LINUX
mov eax, e3c59x_rx_buff
zero_to_dma eax
else
mov eax, Ether_buffer
end if
out dx, eax
; program frame length
lea edx, [ebp+E3C59X_REG_MASTER_LEN]
mov ax, 1560
out dx, ax
; start DMA Up
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, (10100b shl 11) ; StartDMAUp
out dx, ax
; check for master operation in progress
.dma_loop:
lea edx, [ebp+E3C59X_REG_MASTER_STATUS]
in ax, dx
test ah, 0x80
jnz .dma_loop
; registrate the received packet length
pop eax
mov word [eth_rx_data_len], ax
; discard the top frame received
.discard_frame:
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, (01000b shl 11)
out dx, ax
.finish:
; set return value
cmp word [eth_rx_data_len], 0
setne al
ret
 
;***************************************************************************
; Function
; e3c59x_boomerang_poll
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
; Parameters
; ebp - io_addr
; Return value
; al - 0 ; no packet received
; al - 1 ; packet received
; Destroyed registers
; eax, edx, ecx, edi, esi, ebp
;
;***************************************************************************
align 4
e3c59x_boomerang_poll:
and word [eth_rx_data_len], 0 ; assume no packet received
movzx ebp, word [io_addr] ; to be implemented in ETHERNET.INC
; check if packet is uploaded
mov eax, [e3c59x_curr_upd]
test byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x80 ; upPktComplete
jnz .check_error
jmp .finish
; packet is uploaded check for any error
.check_error:
test byte [eax+E3C59X_UPD_PKT_STATUS+1], 0x40 ; upError
jz .copy_packet_length
and dword [eax+E3C59X_UPD_PKT_STATUS], 0
jmp .finish
.copy_packet_length:
mov ecx, [eax+E3C59X_UPD_PKT_STATUS]
and ecx, 0x1fff
cmp ecx, E3C59X_MAX_ETH_PKT_SIZE
jbe .copy_packet
and dword [eax+E3C59X_UPD_PKT_STATUS], 0
jmp .finish
.copy_packet:
push ecx
mov word [eth_rx_data_len], cx
mov esi, [eax+E3C59X_UPD_UP_FRAG_ADDR]
dma_to_virt esi
mov edi, Ether_buffer
shr ecx, 2 ; first copy dword-wise
cld
rep movsd ; copy the dwords
pop ecx
and ecx, 3
rep movsb ; copy the rest bytes
mov eax, [e3c59x_curr_upd]
and dword [eax+E3C59X_UPD_PKT_STATUS], 0
virt_to_zero eax
cmp eax, e3c59x_upd_buff+(E3C59X_NUM_RX_DESC-1)*E3C59X_UPD_SIZE
jb .no_wrap
; wrap around
mov eax, e3c59x_upd_buff-E3C59X_UPD_SIZE
.no_wrap:
add eax, E3C59X_UPD_SIZE
zero_to_virt eax
mov [e3c59x_curr_upd], eax
.finish:
; check if the NIC is in the upStall state
lea edx, [ebp+E3C59X_REG_UP_PKT_STATUS]
in eax, dx
test ah, 0x20 ; UpStalled
jz .noUpUnStall
; issue upUnStall command
lea edx, [ebp+E3C59X_REG_COMMAND]
mov ax, ((110b shl 11)+1) ; upUnStall
out dx, ax
.noUpUnStall:
; set return value
cmp word [eth_rx_data_len], 0
setnz al
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/eth_drv/drivers/forcedeth.inc
0,0 → 1,2692
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; FORCEDETH.INC ;;
;; ;;
;; Ethernet driver for Kolibri OS ;;
;; ;;
;; Version 0.1 24 June 2008 - 23 Sep 2008 ;;
;; ;;
;; Driver for chips of NVIDIA nForce2 ;;
;; References: ;;
;; forcedeth.c - linux driver (etherboot project) ;;
;; ethernet driver template by Mike Hibbett ;;
;; ;;
;; The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; Copyright 2008 shurf, ;;
;; cit.utc@gmail.com ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
;********************************************************************
; Interface
; forcedeth_reset
; forcedeth_probe
; forcedeth_poll
; forcedeth_transmit
; forcedeth_cable
;
;********************************************************************
 
;**************************************************************************
; forcedeth Register Definitions
;**************************************************************************
 
PCI_REG_COMMAND equ 0x04 ; command register
 
PCI_COMMAND_IO equ 0x01 ; Enable response in I/O space
PCI_COMMAND_MASTER equ 0x04 ; Enable bus mastering
PCI_LATENCY_TIMER equ 0x0d ; 8 bits
 
PCI_VENDOR_ID equ 0x00 ; 16 bit
PCI_REVISION_ID equ 0x08 ; 8 bits
 
PCI_BASE_ADDRESS_0 equ 0x10 ; 32 bits
PCI_BASE_ADDRESS_1 equ 0x14 ; 32 bits
PCI_BASE_ADDRESS_2 equ 0x18 ; 32 bits
PCI_BASE_ADDRESS_3 equ 0x1c ; 32 bits
PCI_BASE_ADDRESS_4 equ 0x20 ; 32 bits
PCI_BASE_ADDRESS_5 equ 0x24 ; 32 bits
 
PCI_BASE_ADDRESS_SPACE_IO equ 0x01
PCI_BASE_ADDRESS_IO_MASK equ (not 0x03)
PCI_BASE_ADDRESS_MEM_MASK equ (not 0x0f)
 
PCI_BASE_ADDRESS_MEM_TYPE_MASK equ 0x06
PCI_BASE_ADDRESS_MEM_TYPE_32 equ 0x00 ; 32 bit address
PCI_BASE_ADDRESS_MEM_TYPE_1M equ 0x02 ; Below 1M [obsolete]
PCI_BASE_ADDRESS_MEM_TYPE_64 equ 0x04 ; 64 bit address
 
; NIC specific static variables go here
PCI_DEVICE_ID_NVIDIA_NVENET_1 equ 0x01c3
PCI_DEVICE_ID_NVIDIA_NVENET_2 equ 0x0066
PCI_DEVICE_ID_NVIDIA_NVENET_4 equ 0x0086
PCI_DEVICE_ID_NVIDIA_NVENET_5 equ 0x008c
PCI_DEVICE_ID_NVIDIA_NVENET_3 equ 0x00d6
PCI_DEVICE_ID_NVIDIA_NVENET_7 equ 0x00df
PCI_DEVICE_ID_NVIDIA_NVENET_6 equ 0x00e6
PCI_DEVICE_ID_NVIDIA_NVENET_8 equ 0x0056
PCI_DEVICE_ID_NVIDIA_NVENET_9 equ 0x0057
PCI_DEVICE_ID_NVIDIA_NVENET_10 equ 0x0037
PCI_DEVICE_ID_NVIDIA_NVENET_11 equ 0x0038
PCI_DEVICE_ID_NVIDIA_NVENET_12 equ 0x0268
PCI_DEVICE_ID_NVIDIA_NVENET_13 equ 0x0269
PCI_DEVICE_ID_NVIDIA_NVENET_14 equ 0x0372
PCI_DEVICE_ID_NVIDIA_NVENET_15 equ 0x0373
 
ETH_DATA_LEN equ 1500
 
; rx/tx mac addr + type + vlan + align + slack
RX_NIC_BUFSIZE equ (ETH_DATA_LEN + 64)
; even more slack
RX_ALLOC_BUFSIZE equ (ETH_DATA_LEN + 128)
 
NvRegIrqStatus equ 0x00
NvRegIrqMask equ 0x04
NvRegUnknownSetupReg6 equ 0x08
NvRegPollingInterval equ 0x0c
NvRegMacReset equ 0x3c
NvRegMisc1 equ 0x80
NvRegTransmitterControl equ 0x84
NvRegTransmitterStatus equ 0x88
NvRegPacketFilterFlags equ 0x8c
NvRegOffloadConfig equ 0x90
NvRegReceiverControl equ 0x94
NvRegReceiverStatus equ 0x98
NvRegRandomSeed equ 0x9c
NvRegUnknownSetupReg1 equ 0xA0
NvRegUnknownSetupReg2 equ 0xA4
NvRegMacAddrA equ 0xA8 ; MAC address low
NvRegMacAddrB equ 0xAC ; MAC address high
NvRegMulticastAddrA equ 0xB0
NvRegMulticastAddrB equ 0xB4
NvRegMulticastMaskA equ 0xB8
NvRegMulticastMaskB equ 0xBC
NvRegPhyInterface equ 0xC0
NvRegTxRingPhysAddr equ 0x100
NvRegRxRingPhysAddr equ 0x104
NvRegRingSizes equ 0x108
NvRegUnknownTransmitterReg equ 0x10c
NvRegLinkSpeed equ 0x110
NvRegUnknownSetupReg5 equ 0x130
NvRegUnknownSetupReg3 equ 0x13c
NvRegTxRxControl equ 0x144
NvRegMIIStatus equ 0x180
NvRegUnknownSetupReg4 equ 0x184
NvRegAdapterControl equ 0x188
NvRegMIISpeed equ 0x18c
NvRegMIIControl equ 0x190
NvRegMIIData equ 0x194
NvRegWakeUpFlags equ 0x200
NvRegPowerState equ 0x26c
NvRegPowerState2 equ 0x600
 
NVREG_UNKSETUP1_VAL equ 0x16070f
NVREG_UNKSETUP2_VAL equ 0x16
NVREG_UNKSETUP3_VAL1 equ 0x200010
NVREG_UNKSETUP4_VAL equ 8
NVREG_UNKSETUP5_BIT31 equ (1 shl 31)
NVREG_UNKSETUP6_VAL equ 3
 
NVREG_TXRXCTL_RXCHECK equ 0x0400
NVREG_MIISTAT_ERROR equ 0x0001
NVREG_MIISTAT_MASK equ 0x000f
NVREG_MIISTAT_MASK2 equ 0x000f
NVREG_MIICTL_INUSE equ 0x08000
NVREG_MIICTL_WRITE equ 0x00400
NVREG_MIICTL_ADDRSHIFT equ 5
 
NVREG_MIISPEED_BIT8 equ (1 shl 8)
NVREG_MIIDELAY equ 5
 
NVREG_IRQ_RX_ERROR equ 0x0001
NVREG_IRQ_RX equ 0x0002
NVREG_IRQ_RX_NOBUF equ 0x0004
NVREG_IRQ_LINK equ 0x0040
NVREG_IRQ_TIMER equ 0x0020
NVREG_IRQMASK_WANTED_2 equ 0x0147
 
NVREG_IRQ_RX_ALL equ (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF)
NVREG_IRQ_TX_ALL equ 0 ; ???????????
NVREG_IRQ_OTHER_ALL equ (NVREG_IRQ_LINK or NVREG_IRQ_TIMER)
 
NVREG_IRQSTAT_MASK equ 0x1ff
 
NVREG_TXRXCTL_KICK equ 0x0001
NVREG_TXRXCTL_BIT1 equ 0x0002
NVREG_TXRXCTL_BIT2 equ 0x0004
NVREG_TXRXCTL_IDLE equ 0x0008
NVREG_TXRXCTL_RESET equ 0x0010
NVREG_TXRXCTL_RXCHECK equ 0x0400
 
NVREG_MCASTADDRA_FORCE equ 0x01
 
NVREG_MAC_RESET_ASSERT equ 0x0F3
 
NVREG_MISC1_HD equ 0x02
NVREG_MISC1_FORCE equ 0x3b0f3c
 
NVREG_PFF_ALWAYS equ 0x7F0008
NVREG_PFF_PROMISC equ 0x80
NVREG_PFF_MYADDR equ 0x20
 
NVREG_OFFLOAD_HOMEPHY equ 0x601
NVREG_OFFLOAD_NORMAL equ RX_NIC_BUFSIZE
 
NVREG_RNDSEED_MASK equ 0x00ff
NVREG_RNDSEED_FORCE equ 0x7f00
NVREG_RNDSEED_FORCE2 equ 0x2d00
NVREG_RNDSEED_FORCE3 equ 0x7400
 
; NVREG_POLL_DEFAULT is the interval length of the timer source on the nic
; NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
NVREG_POLL_DEFAULT equ 970
 
NVREG_ADAPTCTL_START equ 0x02
NVREG_ADAPTCTL_LINKUP equ 0x04
NVREG_ADAPTCTL_PHYVALID equ 0x40000
NVREG_ADAPTCTL_RUNNING equ 0x100000
NVREG_ADAPTCTL_PHYSHIFT equ 24
 
NVREG_WAKEUPFLAGS_VAL equ 0x7770
 
NVREG_POWERSTATE_POWEREDUP equ 0x8000
NVREG_POWERSTATE_VALID equ 0x0100
NVREG_POWERSTATE_MASK equ 0x0003
NVREG_POWERSTATE_D0 equ 0x0000
NVREG_POWERSTATE_D1 equ 0x0001
NVREG_POWERSTATE_D2 equ 0x0002
NVREG_POWERSTATE_D3 equ 0x0003
 
NVREG_POWERSTATE2_POWERUP_MASK equ 0x0F11
NVREG_POWERSTATE2_POWERUP_REV_A3 equ 0x0001
 
NVREG_RCVCTL_START equ 0x01
NVREG_RCVSTAT_BUSY equ 0x01
 
NVREG_XMITCTL_START equ 0x01
 
NVREG_LINKSPEED_FORCE equ 0x10000
NVREG_LINKSPEED_10 equ 1000
NVREG_LINKSPEED_100 equ 100
NVREG_LINKSPEED_1000 equ 50
 
NVREG_RINGSZ_TXSHIFT equ 0
NVREG_RINGSZ_RXSHIFT equ 16
 
LPA_1000FULL equ 0x0800
 
; Link partner ability register.
LPA_SLCT equ 0x001f ; Same as advertise selector
LPA_10HALF equ 0x0020 ; Can do 10mbps half-duplex
LPA_10FULL equ 0x0040 ; Can do 10mbps full-duplex
LPA_100HALF equ 0x0080 ; Can do 100mbps half-duplex
LPA_100FULL equ 0x0100 ; Can do 100mbps full-duplex
LPA_100BASE4 equ 0x0200 ; Can do 100mbps 4k packets
LPA_RESV equ 0x1c00 ; Unused...
LPA_RFAULT equ 0x2000 ; Link partner faulted
LPA_LPACK equ 0x4000 ; Link partner acked us
LPA_NPAGE equ 0x8000 ; Next page bit
 
MII_READ equ (-1)
MII_PHYSID1 equ 0x02 ; PHYS ID 1
MII_PHYSID2 equ 0x03 ; PHYS ID 2
MII_BMCR equ 0x00 ; Basic mode control register
MII_BMSR equ 0x01 ; Basic mode status register
MII_ADVERTISE equ 0x04 ; Advertisement control reg
MII_LPA equ 0x05 ; Link partner ability reg
MII_SREVISION equ 0x16 ; Silicon revision
MII_RESV1 equ 0x17 ; Reserved...
MII_NCONFIG equ 0x1c ; Network interface config
 
; PHY defines
PHY_OUI_MARVELL equ 0x5043
PHY_OUI_CICADA equ 0x03f1
PHYID1_OUI_MASK equ 0x03ff
PHYID1_OUI_SHFT equ 6
PHYID2_OUI_MASK equ 0xfc00
PHYID2_OUI_SHFT equ 10
PHY_INIT1 equ 0x0f000
PHY_INIT2 equ 0x0e00
PHY_INIT3 equ 0x01000
PHY_INIT4 equ 0x0200
PHY_INIT5 equ 0x0004
PHY_INIT6 equ 0x02000
PHY_GIGABIT equ 0x0100
 
PHY_TIMEOUT equ 0x1
PHY_ERROR equ 0x2
 
PHY_100 equ 0x1
PHY_1000 equ 0x2
PHY_HALF equ 0x100
 
PHY_RGMII equ 0x10000000
 
; desc_ver values:
; This field has two purposes:
; - Newer nics uses a different ring layout. The layout is selected by
; comparing np->desc_ver with DESC_VER_xy.
; - It contains bits that are forced on when writing to NvRegTxRxControl.
DESC_VER_1 equ 0x0
DESC_VER_2 equ (0x02100 or NVREG_TXRXCTL_RXCHECK)
 
MAC_ADDR_LEN equ 6
 
NV_TX_LASTPACKET equ (1 shl 16)
NV_TX_RETRYERROR equ (1 shl 19)
NV_TX_LASTPACKET1 equ (1 shl 24)
NV_TX_DEFERRED equ (1 shl 26)
NV_TX_CARRIERLOST equ (1 shl 27)
NV_TX_LATECOLLISION equ (1 shl 28)
NV_TX_UNDERFLOW equ (1 shl 29)
NV_TX_ERROR equ (1 shl 30)
NV_TX_VALID equ (1 shl 31)
 
NV_TX2_LASTPACKET equ (1 shl 29)
NV_TX2_RETRYERROR equ (1 shl 18)
NV_TX2_LASTPACKET1 equ (1 shl 23)
NV_TX2_DEFERRED equ (1 shl 25)
NV_TX2_CARRIERLOST equ (1 shl 26)
NV_TX2_LATECOLLISION equ (1 shl 27)
NV_TX2_UNDERFLOW equ (1 shl 28)
; error and valid are the same for both
NV_TX2_ERROR equ (1 shl 30)
NV_TX2_VALID equ (1 shl 31)
 
NV_RX_DESCRIPTORVALID equ (1 shl 16)
NV_RX_AVAIL equ (1 shl 31)
 
NV_RX2_DESCRIPTORVALID equ (1 shl 29)
 
RX_RING equ 4
TX_RING equ 2
 
FLAG_MASK_V1 equ 0xffff0000
FLAG_MASK_V2 equ 0xffffc000
LEN_MASK_V1 equ (0xffffffff xor FLAG_MASK_V1)
LEN_MASK_V2 equ (0xffffffff xor FLAG_MASK_V2)
 
; Miscelaneous hardware related defines:
NV_PCI_REGSZ_VER1 equ 0x270
NV_PCI_REGSZ_VER2 equ 0x604
; various timeout delays: all in usec
NV_TXRX_RESET_DELAY equ 4
NV_TXSTOP_DELAY1 equ 10
NV_TXSTOP_DELAY1MAX equ 500000
NV_TXSTOP_DELAY2 equ 100
NV_RXSTOP_DELAY1 equ 10
NV_RXSTOP_DELAY1MAX equ 500000
NV_RXSTOP_DELAY2 equ 100
NV_SETUP5_DELAY equ 5
NV_SETUP5_DELAYMAX equ 50000
NV_POWERUP_DELAY equ 5
NV_POWERUP_DELAYMAX equ 5000
NV_MIIBUSY_DELAY equ 50
NV_MIIPHY_DELAY equ 10
NV_MIIPHY_DELAYMAX equ 10000
NV_MAC_RESET_DELAY equ 64
NV_WAKEUPPATTERNS equ 5
NV_WAKEUPMASKENTRIES equ 4
 
; Advertisement control register.
ADVERTISE_SLCT equ 0x001f ; Selector bits
ADVERTISE_CSMA equ 0x0001 ; Only selector supported
ADVERTISE_10HALF equ 0x0020 ; Try for 10mbps half-duplex
ADVERTISE_10FULL equ 0x0040 ; Try for 10mbps full-duplex
ADVERTISE_100HALF equ 0x0080 ; Try for 100mbps half-duplex
ADVERTISE_100FULL equ 0x0100 ; Try for 100mbps full-duplex
ADVERTISE_100BASE4 equ 0x0200 ; Try for 100mbps 4k packets
ADVERTISE_RESV equ 0x1c00 ; Unused...
ADVERTISE_RFAULT equ 0x2000 ; Say we can detect faults
ADVERTISE_LPACK equ 0x4000 ; Ack link partners response
ADVERTISE_NPAGE equ 0x8000 ; Next page bit
 
ADVERTISE_FULL equ (ADVERTISE_100FULL or ADVERTISE_10FULL or ADVERTISE_CSMA)
ADVERTISE_ALL equ (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL)
 
MII_1000BT_CR equ 0x09
MII_1000BT_SR equ 0x0a
ADVERTISE_1000FULL equ 0x0200
ADVERTISE_1000HALF equ 0x0100
 
BMCR_ANRESTART equ 0x0200 ; Auto negotiation restart
BMCR_ANENABLE equ 0x1000 ; Enable auto negotiation
BMCR_SPEED100 equ 0x2000 ; Select 100Mbps
BMCR_LOOPBACK equ 0x4000 ; TXD loopback bits
BMCR_RESET equ 0x8000 ; Reset the DP83840
 
; Basic mode status register.
BMSR_ERCAP equ 0x0001 ; Ext-reg capability
BMSR_JCD equ 0x0002 ; Jabber detected
BMSR_LSTATUS equ 0x0004 ; Link status
BMSR_ANEGCAPABLE equ 0x0008 ; Able to do auto-negotiation
BMSR_RFAULT equ 0x0010 ; Remote fault detected
BMSR_ANEGCOMPLETE equ 0x0020 ; Auto-negotiation complete
BMSR_RESV equ 0x07c0 ; Unused...
BMSR_10HALF equ 0x0800 ; Can do 10mbps, half-duplex
BMSR_10FULL equ 0x1000 ; Can do 10mbps, full-duplex
BMSR_100HALF equ 0x2000 ; Can do 100mbps, half-duplex
BMSR_100FULL equ 0x4000 ; Can do 100mbps, full-duplex
BMSR_100BASE4 equ 0x8000 ; Can do 100mbps, 4k packets
 
ETH_ALEN equ 6
ETH_HLEN equ (2 * ETH_ALEN + 2)
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for
; mininmum 64bytes frame length
 
uglobal
forcedeth_mmio_addr dd 0 ; memory map physical address
forcedeth_mmio_size dd 0 ; size of memory bar
forcedeth_vendor_id dw 0 ; Vendor ID
forcedeth_device_id dw 0 ; Device ID
forcedeth_orig_mac0 dd 0 ; MAC
forcedeth_orig_mac1 dd 0 ; MAC
forcedeth_mapio_addr dd 0 ; mapped IO address
forcedeth_txflags dd 0 ;
forcedeth_desc_ver dd 0 ;
forcedeth_irqmask dd 0 ; IRQ-mask
forcedeth_wolenabled dd 0 ; WOL
forcedeth_in_shutdown dd 0 ;
forcedeth_cur_rx dd 0 ;
forcedeth_refill_rx dd 0 ;
forcedeth_phyaddr dd 0 ;
forcedeth_phy_oui dd 0 ;
forcedeth_gigabit dd 0 ;
forcedeth_needs_mac_reset dd 0 ;
forcedeth_linkspeed dd 0 ;
forcedeth_duplex dd 0 ;
forcedeth_next_tx dd 0 ; next TX descriptor number
forcedeth_nic_tx dd 0 ; ??? d'nt used ???
forcedeth_packetlen dd 0 ;
forcedeth_nocable dd 0 ; no cable present
endg
 
struc forcedeth_TxDesc {
.PacketBuffer dd ?
.FlagLen dd ?
}
virtual at 0
forcedeth_TxDesc forcedeth_TxDesc
sizeof.forcedeth_TxDesc = $ - forcedeth_TxDesc
end virtual
 
struc forcedeth_RxDesc {
.PacketBuffer dd ?
.FlagLen dd ?
}
virtual at 0
forcedeth_RxDesc forcedeth_RxDesc
sizeof.forcedeth_RxDesc = $ - forcedeth_RxDesc
end virtual
 
virtual at eth_data_start
; Define the TX Descriptor
align 256
forcedeth_tx_ring rb TX_RING * sizeof.forcedeth_TxDesc
; Create a static buffer of size RX_BUF_SZ for each
; TX Descriptor. All descriptors point to a
; part of this buffer
align 256
forcedeth_txb rb TX_RING * RX_NIC_BUFSIZE
; Define the RX Descriptor
align 256
forcedeth_rx_ring rb RX_RING * sizeof.forcedeth_RxDesc
; Create a static buffer of size RX_BUF_SZ for each
; RX Descriptor. All descriptors point to a
; part of this buffer
align 256
forcedeth_rxb rb RX_RING * RX_NIC_BUFSIZE
end virtual
 
 
;***************************************************************************
; Function
; forcedeth_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; No inputs
; All registers destroyed
;
;***************************************************************************
forcedeth_reset:
 
; 1) erase previous misconfiguration
; 4.1-1: stop adapter: ignored, 4.3 seems to be overkill
 
; writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA)
mov edi, dword [forcedeth_mapio_addr]
mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE
 
; writel(0, base + NvRegMulticastAddrB)
mov dword [edi+NvRegMulticastAddrB], 0
; writel(0, base + NvRegMulticastMaskA)
mov dword [edi+NvRegMulticastMaskA], 0
; writel(0, base + NvRegMulticastMaskB)
mov dword [edi+NvRegMulticastMaskB], 0
 
; writel(0, base + NvRegPacketFilterFlags)
mov dword [edi+NvRegPacketFilterFlags], 0
; writel(0, base + NvRegTransmitterControl)
mov dword [edi+NvRegTransmitterControl], 0
; writel(0, base + NvRegReceiverControl)
mov dword [edi+NvRegReceiverControl], 0
 
; writel(0, base + NvRegAdapterControl)
mov dword [edi+NvRegAdapterControl], 0
 
 
; 2) initialize descriptor rings
; init_ring(nic)
call forcedeth_init_ring
 
; writel(0, base + NvRegLinkSpeed)
mov dword [edi+NvRegLinkSpeed], 0
; writel(0, base + NvRegUnknownTransmitterReg)
mov dword [edi+NvRegUnknownTransmitterReg], 0
 
; txrx_reset(nic)
call forcedeth_txrx_reset
; writel(0, base + NvRegUnknownSetupReg6)
mov dword [edi+NvRegUnknownSetupReg6], 0
 
; np->in_shutdown = 0
mov dword [forcedeth_in_shutdown], 0
 
 
; 3) set mac address
; writel(mac[0], base + NvRegMacAddrA)
mov eax, dword [forcedeth_orig_mac0]
mov dword [edi+NvRegMacAddrA], eax
; writel(mac[1], base + NvRegMacAddrB)
mov eax, dword [forcedeth_orig_mac1]
mov dword [edi+NvRegMacAddrB], eax
 
 
; 4) give hw rings
; writel((u32) virt_to_le32desc(&rx_ring[0]), base + NvRegRxRingPhysAddr)
mov eax, forcedeth_rx_ring
 
;DEBUGF 1," K : FORCEDETH: rx_ring at 0x%x\n", eax
 
sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov dword [edi+NvRegRxRingPhysAddr], eax
 
; writel((u32) virt_to_le32desc(&tx_ring[0]), base + NvRegTxRingPhysAddr)
mov eax, forcedeth_tx_ring
sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov dword [edi+NvRegTxRingPhysAddr], eax
 
; writel(((RX_RING - 1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING - 1) << NVREG_RINGSZ_TXSHIFT), base + NvRegRingSizes)
mov dword [edi+NvRegRingSizes], (((RX_RING - 1) shl NVREG_RINGSZ_RXSHIFT) + ((TX_RING - 1) shl NVREG_RINGSZ_TXSHIFT))
 
; 5) continue setup
; np->linkspeed = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10
mov dword [forcedeth_linkspeed], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
; np->duplex = 0
mov dword [forcedeth_duplex], 0
 
; writel(np->linkspeed, base + NvRegLinkSpeed)
mov dword [edi+NvRegLinkSpeed], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
 
; writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3)
mov dword [edi+NvRegUnknownSetupReg3], NVREG_UNKSETUP3_VAL1
; writel(np->desc_ver, base + NvRegTxRxControl)
mov eax, dword [forcedeth_desc_ver]
mov dword [edi+NvRegTxRxControl], eax
; pci_push(base)
call forcedeth_pci_push
; writel(NVREG_TXRXCTL_BIT1 | np->desc_ver, base + NvRegTxRxControl)
or eax, NVREG_TXRXCTL_BIT1
mov dword [edi+NvRegTxRxControl], eax
 
; reg_delay(NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, "open: SetupReg5, Bit 31 remained off\n")
push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;;
stdcall forcedeth_reg_delay,NvRegUnknownSetupReg5,NVREG_UNKSETUP5_BIT31,NVREG_UNKSETUP5_BIT31,NV_SETUP5_DELAY,NV_SETUP5_DELAYMAX,0
pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;;
 
; writel(0, base + NvRegUnknownSetupReg4)
mov dword [edi+NvRegUnknownSetupReg4], 0
 
; writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus)
mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK2
 
; printf("%d-Mbs Link, %s-Duplex\n", np->linkspeed & NVREG_LINKSPEED_10 ? 10 : 100, np->duplex ? "Full" : "Half")
;;;;;;;;;;; DEBUGF
 
; 6) continue setup
; writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1)
mov dword [edi+NvRegMisc1], (NVREG_MISC1_FORCE or NVREG_MISC1_HD)
; writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus)
mov eax, dword [edi+NvRegTransmitterStatus]
mov dword [edi+NvRegTransmitterStatus], eax
 
; writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags)
mov dword [edi+NvRegPacketFilterFlags], NVREG_PFF_ALWAYS
 
; writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig)
mov dword [edi+NvRegOffloadConfig], NVREG_OFFLOAD_NORMAL
 
; writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus)
mov eax, dword [edi+NvRegReceiverStatus]
mov dword [edi+NvRegReceiverStatus], eax
 
; Get a random number
; i = random()
push edi
stdcall sys_clock ; eax = 0x00SSMMHH (current system time)
pop edi
 
; writel(NVREG_RNDSEED_FORCE | (i & NVREG_RNDSEED_MASK), base + NvRegRandomSeed)
and eax, NVREG_RNDSEED_MASK
or eax, NVREG_RNDSEED_FORCE
mov dword [edi+NvRegRandomSeed], eax
 
; writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1)
mov dword [edi+NvRegUnknownSetupReg1], NVREG_UNKSETUP1_VAL
; writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2)
mov dword [edi+NvRegUnknownSetupReg2], NVREG_UNKSETUP2_VAL
; writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval)
mov dword [edi+NvRegPollingInterval], NVREG_POLL_DEFAULT
; writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6)
mov dword [edi+NvRegUnknownSetupReg6], NVREG_UNKSETUP6_VAL
 
; writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT) | NVREG_ADAPTCTL_PHYVALID | NVREG_ADAPTCTL_RUNNING,
; base + NvRegAdapterControl)
mov eax, dword [forcedeth_phyaddr]
shl eax, NVREG_ADAPTCTL_PHYSHIFT
or eax, (NVREG_ADAPTCTL_PHYVALID or NVREG_ADAPTCTL_RUNNING)
mov dword [edi+NvRegAdapterControl], eax
; writel(NVREG_MIISPEED_BIT8 | NVREG_MIIDELAY, base + NvRegMIISpeed)
mov dword [edi+NvRegMIISpeed], (NVREG_MIISPEED_BIT8 or NVREG_MIIDELAY)
 
; writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4)
mov dword [edi+NvRegUnknownSetupReg4], NVREG_UNKSETUP4_VAL
 
; writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags)
mov dword [edi+NvRegWakeUpFlags], NVREG_WAKEUPFLAGS_VAL
; i = readl(base + NvRegPowerState)
mov eax, dword [edi+NvRegPowerState]
 
; if ((i & NVREG_POWERSTATE_POWEREDUP) == 0)
test eax, NVREG_POWERSTATE_POWEREDUP
jnz @f
; writel(NVREG_POWERSTATE_POWEREDUP | i, base + NvRegPowerState)
or eax, NVREG_POWERSTATE_POWEREDUP
mov dword [edi+NvRegPowerState], eax
 
@@:
 
; pci_push(base)
call forcedeth_pci_push
 
; nv_udelay(10)
mov esi, 10
call forcedeth_nv_udelay
 
; writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState)
mov eax, dword [edi+NvRegPowerState]
or eax, NVREG_POWERSTATE_VALID
mov dword [edi+NvRegPowerState], eax
 
; ??? disable all interrupts ???
; writel(0, base + NvRegIrqMask)
mov dword [edi+NvRegIrqMask], 0
 
;;; ; ??? Mask RX interrupts
;;; mov dword [edi+NvRegIrqMask], NVREG_IRQ_RX_ALL
;;; ; ??? Mask TX interrupts
;;; ;mov dword [edi+NvRegIrqMask], NVREG_IRQ_TX_ALL
;;; ; ??? Mask OTHER interrupts
;;; mov dword [edi+NvRegIrqMask], NVREG_IRQ_OTHER_ALL
; pci_push(base)
call forcedeth_pci_push
 
; writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus)
mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK2
 
; writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus)
mov dword [edi+NvRegIrqStatus], NVREG_IRQSTAT_MASK
 
; pci_push(base)
call forcedeth_pci_push
 
 
; writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA)
mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE
 
; writel(0, base + NvRegMulticastAddrB)
mov dword [edi+NvRegMulticastAddrB], 0
 
; writel(0, base + NvRegMulticastMaskA)
mov dword [edi+NvRegMulticastMaskA], 0
 
; writel(0, base + NvRegMulticastMaskB)
mov dword [edi+NvRegMulticastMaskB], 0
 
; writel(NVREG_PFF_ALWAYS | NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags)
mov dword [edi+NvRegPacketFilterFlags], (NVREG_PFF_ALWAYS or NVREG_PFF_MYADDR)
 
; set_multicast(nic)
call forcedeth_set_multicast
; One manual link speed update: Interrupts are enabled, future link
; speed changes cause interrupts and are handled by nv_link_irq().
 
; miistat = readl(base + NvRegMIIStatus)
mov eax, dword [edi+NvRegMIIStatus]
 
; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK
 
; dprintf(("startup: got 0x%hX.\n", miistat));
;;; DEBUGF 1," K : FORCEDETH: startup: got 0x%x\n", eax
 
 
; ret = update_linkspeed(nic)
call forcedeth_update_linkspeed
push eax
; start_tx(nic)
call forcedeth_start_tx
 
pop eax
; if (ret) {
; //Start Connection netif_carrier_on(dev);
; } else {
; printf("no link during initialization.\n");
; }
 
;*** added by shurf (21.09.2008)
mov dword [forcedeth_nocable], 0
;***
 
test eax, eax
jnz .return
DEBUGF 1," K : FORCEDETH: no link during initialization.\n"
 
;*** added by shurf (21.09.2008)
mov dword [forcedeth_nocable], 1
;***
 
.return:
 
; Indicate that we have successfully reset the card
mov eax, dword [pci_data]
mov dword [eth_status], eax
ret
 
 
;***************************************************************************
; Function
; forcedeth_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
;
;***************************************************************************
forcedeth_probe:
 
; DEBUGF 1," K : FORCEDETH: 0x%x 0x%x, 0x%x\n", [io_addr]:8,[pci_bus]:2,[pci_dev]:2
 
mov dword [forcedeth_needs_mac_reset], 0
 
; BEGIN of adjust_pci_device()
; read word from PCI-device
mov al, 1 ;;;;;;;;;;;;;;2
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, PCI_REG_COMMAND
call pci_read_reg
mov bx, ax ; new command
or bx, PCI_COMMAND_MASTER
or bx, PCI_COMMAND_IO
cmp bx, ax
je @f
; Enabling PCI-device (make card as bus master)
DEBUGF 1," K : FORCEDETH: Updating PCI command 0x%x->0x%x\n", ax, bx
mov cx, bx
mov al, 1 ;;;;;;;;;;;;2
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, PCI_REG_COMMAND
call pci_write_reg
 
; Check latency settings
@@:
; Get current latency settings from Latency timer register (byte)
mov al, 0 ;;;;;;;;;1
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, PCI_LATENCY_TIMER
call pci_read_reg
 
; see if its at least 32
cmp al, 32
jge @f
; set latency to 32
DEBUGF 1, "K : FORCEDETH: PCI latency timer (CFLT) is unreasonably low at %d.\n", al
DEBUGF 1, "K : FORCEDETH: Setting to 32 clocks.\n"
mov cl, 32
mov al, 0 ;;;;;;;1
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, PCI_LATENCY_TIMER
call pci_write_reg
; END of adjust_pci_device()
 
@@:
; BEGIN of pci_bar_start (addr = pci_bar_start(pci, PCI_BASE_ADDRESS_0))
mov al, 2 ; dword
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, PCI_BASE_ADDRESS_0
call pci_read_reg
test eax, PCI_BASE_ADDRESS_SPACE_IO
jz @f
and eax, PCI_BASE_ADDRESS_IO_MASK
jmp .next
@@: push eax
and eax, PCI_BASE_ADDRESS_MEM_TYPE_MASK
cmp eax, PCI_BASE_ADDRESS_MEM_TYPE_64
jne .not64
mov al, 2 ; dword
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, PCI_BASE_ADDRESS_0 + 4
call pci_read_reg
or eax, eax
jz .not64
DEBUGF 1,"K : FORCEDETH: pci_bar_start: Unhandled 64bit BAR\n"
or eax, -1
jmp .next
.not64:
pop eax
and eax, PCI_BASE_ADDRESS_MEM_MASK
.next:
; END of pci_bar_start
; addr = eax
mov dword [forcedeth_mmio_addr], eax
 
; BEGIN of pci_bar_size (sz = pci_bar_size(pci, PCI_BASE_ADDRESS_0))
 
; Save original bar
mov al, 2 ; dword
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, PCI_BASE_ADDRESS_0
call pci_read_reg
mov dword [forcedeth_tmp_start], eax
; Compute which bits can be set
; (ecx - value to write)
mov al, 2 ; dword
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, PCI_BASE_ADDRESS_0
mov ecx, (not 0)
call pci_write_reg
mov al, 2 ; dword
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, PCI_BASE_ADDRESS_0
call pci_read_reg
push eax
; Restore the original size
mov al, 2 ; dword
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, PCI_BASE_ADDRESS_0
mov ecx, dword [forcedeth_tmp_start]
call pci_write_reg
; Find the significant bits
pop eax
test dword [forcedeth_tmp_start], PCI_BASE_ADDRESS_SPACE_IO
jz @f
and eax, PCI_BASE_ADDRESS_IO_MASK
jmp .next2
@@: and eax, PCI_BASE_ADDRESS_MEM_MASK
.next2:
; Find the lowest bit set
mov ecx, eax
sub eax, 1
not eax
and ecx, eax
 
; END of pci_bar_start
mov dword [forcedeth_mmio_size], ecx
 
DEBUGF 1," K : FORCEDETH: mmio_addr= 0x%x [mmio_size= 0x%x]\n", [forcedeth_mmio_addr]:8, [forcedeth_mmio_size]:8
 
; Get Vendor and Device ID
mov al, 2
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, PCI_VENDOR_ID
call pci_read_reg
mov word [forcedeth_vendor_id], ax
shr eax, 16
mov word [forcedeth_device_id], ax
 
DEBUGF 1," K : FORCEDETH: vendor_id= 0x%x device_id= 0x%x\n", [forcedeth_vendor_id]:4, [forcedeth_device_id]:4
 
; handle different descriptor versions
mov eax, dword [forcedeth_device_id]
cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_1
je .ver1
cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_2
je .ver1
cmp eax, PCI_DEVICE_ID_NVIDIA_NVENET_3
je .ver1
mov dword [forcedeth_desc_ver], DESC_VER_2
jmp @f
.ver1: mov dword [forcedeth_desc_ver], DESC_VER_1
@@:
; read the mac address
; map memory
stdcall map_io_mem, [forcedeth_mmio_addr], [forcedeth_mmio_size], (PG_SW+PG_NOCACHE)
test eax, eax
jz .fail
 
mov dword [forcedeth_mapio_addr], eax
mov edi, eax
mov eax, dword [edi+NvRegMacAddrA]
mov dword [forcedeth_orig_mac0], eax
mov edx, dword [edi+NvRegMacAddrB]
mov dword [forcedeth_orig_mac1], edx
 
; save MAC-address to global variable node_addr
mov dword [node_addr], eax
mov word [node_addr+4], dx
 
; reverse if desired
cmp word [forcedeth_device_id], 0x03E5
jae .no_reverse_mac
mov al, byte [node_addr]
xchg al, byte [node_addr+5]
mov byte [node_addr], al
mov al, byte [node_addr+1]
xchg al, byte [node_addr+4]
mov byte [node_addr+4], al
mov al, byte [node_addr+2]
xchg al, byte [node_addr+3]
mov byte [node_addr+3], al
.no_reverse_mac:
 
; DEBUGF 1," K : FORCEDETH: orig_mac0= 0x%x\n", [forcedeth_orig_mac0]:8
; DEBUGF 1," K : FORCEDETH: orig_mac1= 0x%x\n", [forcedeth_orig_mac1]:8
DEBUGF 1," K : FORCEDETH: MAC = %x-%x-%x-%x-%x-%x\n", [node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2,
 
; disable WOL
mov edi, dword [forcedeth_mapio_addr]
mov dword [edi+NvRegWakeUpFlags], 0
mov dword [forcedeth_wolenabled], 0
mov dword [forcedeth_txflags], (NV_TX2_LASTPACKET or NV_TX2_VALID)
cmp dword [forcedeth_desc_ver], DESC_VER_1
jne @f
mov dword [forcedeth_txflags], (NV_TX_LASTPACKET or NV_TX_VALID)
@@:
 
; BEGIN of switch (pci->dev_id)
 
cmp word [forcedeth_device_id], 0x01C3
jne .next_0x0066
; nforce
mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER)
jmp .end_switch
 
.next_0x0066:
cmp word [forcedeth_device_id], 0x0066
je @f
cmp word [forcedeth_device_id], 0x00D6
je @f
jmp .next_0x0086
@@:
mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER)
cmp dword [forcedeth_desc_ver], DESC_VER_1
jne @f
or dword [forcedeth_txflags], NV_TX_LASTPACKET1
jmp .end_switch
@@: or dword [forcedeth_txflags], NV_TX2_LASTPACKET1
jmp .end_switch
 
.next_0x0086:
cmp word [forcedeth_device_id], 0x0086
je @f
cmp word [forcedeth_device_id], 0x008c
je @f
cmp word [forcedeth_device_id], 0x00e6
je @f
cmp word [forcedeth_device_id], 0x00df
je @f
cmp word [forcedeth_device_id], 0x0056
je @f
cmp word [forcedeth_device_id], 0x0057
je @f
cmp word [forcedeth_device_id], 0x0037
je @f
cmp word [forcedeth_device_id], 0x0038
je @f
jmp .next_0x0268
@@:
; np->irqmask = NVREG_IRQMASK_WANTED_2;
; np->irqmask |= NVREG_IRQ_TIMER;
mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER)
 
; if (np->desc_ver == DESC_VER_1)
cmp dword [forcedeth_desc_ver], DESC_VER_1
jne @f
; np->tx_flags |= NV_TX_LASTPACKET1;
or dword [forcedeth_txflags], NV_TX_LASTPACKET1
jmp .end_switch
; else
@@:
; np->tx_flags |= NV_TX2_LASTPACKET1;
or dword [forcedeth_txflags], NV_TX2_LASTPACKET1
 
; break;
jmp .end_switch
 
.next_0x0268:
; cmp word [forcedeth_device_id], 0x0268
; je @f
; cmp word [forcedeth_device_id], 0x0269
; je @f
; cmp word [forcedeth_device_id], 0x0372
; je @f
; cmp word [forcedeth_device_id], 0x0373
; je @f
; jmp .default_switch
;@@:
cmp word [forcedeth_device_id], 0x0268
jb .default_switch
; pci_read_config_byte(pci, PCI_REVISION_ID, &revision_id);
mov al, 0 ; byte
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, PCI_REVISION_ID
call pci_read_reg
mov ecx, eax ; cl = revision_id
 
; take phy and nic out of low power mode
; powerstate = readl(base + NvRegPowerState2);
mov edi, dword [forcedeth_mapio_addr]
mov eax, dword [edi+NvRegPowerState2] ; eax = powerstate
; powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK;
and eax, not NVREG_POWERSTATE2_POWERUP_MASK
; if ((pci->dev_id==PCI_DEVICE_ID_NVIDIA_NVENET_12||pci->dev_id==PCI_DEVICE_ID_NVIDIA_NVENET_13)&&revision_id>=0xA3)
cmp dword [forcedeth_device_id], PCI_DEVICE_ID_NVIDIA_NVENET_12
je @f
cmp dword [forcedeth_device_id], PCI_DEVICE_ID_NVIDIA_NVENET_13
je @f
jmp .end_if
@@:
cmp cl, 0xA3
jl .end_if
; powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3;
or eax, NVREG_POWERSTATE2_POWERUP_REV_A3
 
.end_if:
 
; writel(powerstate, base + NvRegPowerState2);
mov dword [edi+NvRegPowerState2], eax
 
; //DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ
; np->irqmask = NVREG_IRQMASK_WANTED_2;
; np->irqmask |= NVREG_IRQ_TIMER;
mov dword [forcedeth_irqmask], 0 ;;;;;;;;;;;;;;;;(NVREG_IRQMASK_WANTED_2 or NVREG_IRQ_TIMER)
; needs_mac_reset = 1;
mov dword [forcedeth_needs_mac_reset], 1
; if (np->desc_ver == DESC_VER_1)
cmp dword [forcedeth_desc_ver], DESC_VER_1
jne @f
; np->tx_flags |= NV_TX_LASTPACKET1;
or dword [forcedeth_txflags], NV_TX_LASTPACKET1
jmp .end_if2
@@:
; else
; np->tx_flags |= NV_TX2_LASTPACKET1;
or dword [forcedeth_txflags], NV_TX2_LASTPACKET1
 
.end_if2:
; break;
jmp .end_switch
 
.default_switch:
DEBUGF 1," K : FORCEDETH: Your card was undefined in this driver.\n"
DEBUGF 1," K : FORCEDETH: Review driver_data in Kolibri driver and send a patch\n"
 
.end_switch:
 
; END of switch (pci->dev_id)
 
 
; Find a suitable phy
mov dword [forcedeth_tmp_i], 1
.for_loop:
; for (i = 1; i <= 32; i++)
; phyaddr = i & 0x1f
mov ebx, dword [forcedeth_tmp_i]
and ebx, 0x1f
 
; id1 = mii_rw(phyaddr, MII_PHYSID1, MII_READ)
;EBX - addr, EAX - miireg, ECX - value
mov eax, MII_PHYSID1
mov ecx, MII_READ
call forcedeth_mii_rw ; id1 = eax
 
; if (id1 < 0 || id1 == 0xffff)
cmp eax, 0xffffffff
je .continue_for
test eax, 0x80000000
jnz .continue_for
mov dword [forcedeth_tmp_id1], eax
 
; id2 = mii_rw(nic, phyaddr, MII_PHYSID2, MII_READ)
mov eax, MII_PHYSID2
mov ecx, MII_READ
call forcedeth_mii_rw ; id2 = eax
 
; if (id2 < 0 || id2 == 0xffff)
cmp eax, 0xffffffff
je .continue_for
test eax, 0x80000000
jnz .continue_for
mov dword [forcedeth_tmp_id2], eax
 
jmp .break_for
.continue_for:
inc dword [forcedeth_tmp_i]
cmp dword [forcedeth_tmp_i], 32
jle .for_loop
jmp .end_for
 
.break_for:
 
;;;; DEBUGF 1," K : FORCEDETH: id1=0x%x id2=0x%x\n", [forcedeth_tmp_id1]:8, [forcedeth_tmp_id2]:8
 
; id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT
mov eax, dword [forcedeth_tmp_id1]
and eax, PHYID1_OUI_MASK
shl eax, PHYID1_OUI_SHFT
mov dword [forcedeth_tmp_id1], eax
 
; id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT
mov eax, dword [forcedeth_tmp_id2]
and eax, PHYID2_OUI_MASK
shr eax, PHYID2_OUI_SHFT
mov dword [forcedeth_tmp_id2], eax
 
DEBUGF 1," K : FORCEDETH: Found PHY 0x%x:0x%x at address 0x%x\n", [forcedeth_tmp_id1]:8, [forcedeth_tmp_id2]:8, ebx
 
; np->phyaddr = phyaddr;
mov dword [forcedeth_phyaddr], ebx
 
; np->phy_oui = id1 | id2;
mov eax, dword [forcedeth_tmp_id1]
or eax, dword [forcedeth_tmp_id2]
mov dword [forcedeth_phy_oui], eax
 
.end_for:
 
; if (i == 33)
cmp dword [forcedeth_tmp_i], 33
jne @f
; PHY in isolate mode? No phy attached and user wants to
; test loopback? Very odd, but can be correct.
DEBUGF 1," K : FORCEDETH: Could not find a valid PHY.\n"
 
jmp .next3
 
@@:
 
; if (i != 33)
; reset it
call forcedeth_phy_init
 
.next3:
 
; dprintf(("%s: forcedeth.c: subsystem: %hX:%hX bound to %s\n",
; pci->name, pci->vendor, pci->dev_id, pci->name));
DEBUGF 1," K : FORCEDETH: subsystem: 0x%x:0x%x bound to forcedeth\n", [forcedeth_vendor_id]:4, [forcedeth_device_id]:4
 
 
; if(needs_mac_reset) mac_reset(nic);
cmp dword [forcedeth_needs_mac_reset], 0
je @f
call forcedeth_mac_reset
 
@@:
; if(!forcedeth_reset(nic)) return 0; // no valid link
call forcedeth_reset
test eax, eax
jnz @f
mov eax, 0
jmp .return
 
@@:
 
; point to NIC specific routines
; dev->disable = forcedeth_disable;
; nic->poll = forcedeth_poll;
; nic->transmit = forcedeth_transmit;
; nic->irq = forcedeth_irq;
;;;;;;;;;stdcall attach_int_handler, 11, forcedeth_int_handler, 0
 
; return 1
mov eax, 1
jmp .return
 
.fail:
mov eax, 0
 
.return:
ret
 
uglobal
forcedeth_tmp_start dd ?
forcedeth_tmp_reg dd ?
forcedeth_tmp_i dd ?
forcedeth_tmp_id1 dd ?
forcedeth_tmp_id2 dd ?
forcedeth_tmp_phyinterface dd ?
forcedeth_tmp_newls dd ?
forcedeth_tmp_newdup dd ?
forcedeth_tmp_retval dd ?
forcedeth_tmp_control_1000 dd ?
forcedeth_tmp_lpa dd ?
forcedeth_tmp_adv dd ?
forcedeth_tmp_len dd ?
forcedeth_tmp_valid dd ?
forcedeth_tmp_nr dd ?
forcedeth_tmp_ptxb dd ?
endg
 
;***************************************************************************
; Function
; forcedeth_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
;
;***************************************************************************
forcedeth_poll:
 
mov word [eth_rx_data_len], 0
 
; ????????????????????????????
; ??? Clear events? ???
mov edi, dword [forcedeth_mapio_addr]
mov dword [edi+NvRegIrqStatus], NVREG_IRQSTAT_MASK
; ????????????????????????????
 
.top:
 
; i = np->cur_rx % RX_RING
mov eax, dword [forcedeth_cur_rx]
and eax, (RX_RING-1)
mov dword [forcedeth_tmp_i], eax
 
; Flags = le32_to_cpu(rx_ring[i].FlagLen)
; Flags = rx_ring[i].FlagLen
mov cl, sizeof.forcedeth_RxDesc
mul cl
add eax, forcedeth_rx_ring
mov ebx, eax
mov eax, [ebx + forcedeth_RxDesc.FlagLen]
 
 
; if (Flags & NV_RX_AVAIL)
test eax, NV_RX_AVAIL
; return 0; /* still owned by hardware, */
; still owned by hardware
jnz .return0
 
;;;;; DEBUGF 1,"poll: FlagLen = %x\n", eax
 
; if (np->desc_ver == DESC_VER_1) {
cmp dword [forcedeth_desc_ver], DESC_VER_1
jne @f
; if (!(Flags & NV_RX_DESCRIPTORVALID))
test eax, NV_RX_DESCRIPTORVALID
; return 0;
jz .return0
jmp .next
; } else {
@@:
; if (!(Flags & NV_RX2_DESCRIPTORVALID))
test eax, NV_RX2_DESCRIPTORVALID
; return 0;
jz .return0
; }
.next:
 
; len = nv_descr_getlength(&rx_ring[i], np->desc_ver)
; len = rx_ring[i].FlagLen & ((np->desc_ver == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2);
; eax = FlagLen
cmp dword [forcedeth_desc_ver], DESC_VER_1
jne @f
and eax, LEN_MASK_V1
jmp .next2
@@:
and eax, LEN_MASK_V2
 
.next2:
 
; mov dword [forcedeth_tmp_len], eax
 
; valid = 1
mov dword [forcedeth_tmp_valid], 1
; got a valid packet - forward it to the network core
; nic->packetlen = len;
mov dword [forcedeth_packetlen], eax
;
mov word [eth_rx_data_len], ax
;;;;;;;;; DEBUGF 1,"poll: packet len = 0x%x\n", [forcedeth_packetlen]
 
 
; memcpy(nic->packet, rxb + (i * RX_NIC_BUFSIZE), nic->packetlen);
; Copy packet to system buffer (Ether_buffer)
;???? ecx = (len-4)
mov ecx, eax
push ecx
shr ecx, 2
 
; rxb + (i * RX_NIC_BUFSIZE)
mov eax, dword [forcedeth_tmp_i]
mov bx, RX_NIC_BUFSIZE
mul bx
add eax, forcedeth_rxb
 
mov esi, eax
mov edi, Ether_buffer
cld ; set to increment
rep movsd ; mov dword from [esi++] to [edi++]
pop ecx
and ecx, 3 ; copy rest 1-3 bytes
rep movsb
 
; wmb();
; ???
 
; np->cur_rx++;
inc dword [forcedeth_cur_rx]
 
; if (!valid)
cmp dword [forcedeth_tmp_valid], 0
jne @f
; goto top;
jmp .top
@@:
; alloc_rx(nic);
call forcedeth_alloc_rx
 
; return 1;
jmp .return1
 
;;;;; DEBUGF 1,"K : FORCEDETH: poll: ...\n"
 
 
.return0:
mov eax, 0
jmp .return
.return1:
mov eax, 1
.return:
;;push eax
 
; ????????????????????????????????????????????????
; ????? clear interrupt mask/status
; read IRQ status
;;mov edi, dword [forcedeth_mapio_addr]
;;mov eax, dword [edi+NvRegIrqStatus]
 
; clear events
;;and eax, not (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF or NVREG_IRQ_LINK or NVREG_IRQ_TIMER)
 
; write IRQ status
;;mov dword [edi+NvRegIrqStatus], eax
; ????????????????????????????????????????????????
 
;;pop eax
ret
 
 
;***************************************************************************
; Function
; forcedeth_transmit
;
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
;
;***************************************************************************
forcedeth_transmit:
 
; send the packet to destination
;pusha
;DEBUGF 1,"K : FORCEDETH: transmit: packet type = 0x%x\n", ebx
;DEBUGF 1,"K : FORCEDETH: transmit: packet len = 0x%x\n", ecx
;mov eax, dword [edi]
;DEBUGF 1,"K : FORCEDETH: transmit: dest adr = 0x%x\n", eax
;mov eax, dword [edi+4]
;DEBUGF 1,"K : FORCEDETH: transmit: dest adr2 = 0x%x\n", eax
;mov eax, dword [node_addr]
;DEBUGF 1,"K : FORCEDETH: transmit: src adr = 0x%x\n", eax
;mov eax, dword [node_addr+4]
;DEBUGF 1,"K : FORCEDETH: transmit: src adr2 = 0x%x\n", eax
;popa
 
; int nr = np->next_tx % TX_RING
mov eax, dword [forcedeth_next_tx]
and eax, (TX_RING-1)
mov dword [forcedeth_tmp_nr], eax
; point to the current txb incase multiple tx_rings are used
; ptxb = txb + (nr * RX_NIC_BUFSIZE)
push ecx
mov cx, RX_NIC_BUFSIZE
mul cx ; AX*CX, result to DX:AX
add eax, forcedeth_txb
mov dword [forcedeth_tmp_ptxb], eax
push esi
mov esi, edi ; dst MAC
mov edi, eax ; packet buffer
cld ; set to increment
; copy the packet to ring buffer
; memcpy(ptxb, d, ETH_ALEN); /* dst */
movsd
movsw
; memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
mov esi, node_addr
movsd
movsw
 
; nstype = htons((u16) t); /* type */
; memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); /* type */
mov word [edi], bx
add edi, 2
; memcpy(ptxb + ETH_HLEN, p, s);
pop esi
pop ecx
push ecx
shr ecx, 2 ; count in dwords
rep movsd ; copy dwords from [esi+=4] to [edi+=4]
pop ecx
push ecx
and ecx, 3 ; copy rest 1-3 bytes
rep movsb ; copy bytess from [esi++] to [edi++]
 
 
; s += ETH_HLEN;
; while (s < ETH_ZLEN) /* pad to min length */
; ptxb[s++] = '\0';
; pad to min length
pop ecx
add ecx, ETH_HLEN
push ecx ; header length + data length
cmp ecx, ETH_ZLEN
jge @f
mov eax, ETH_ZLEN
sub eax, ecx
xchg eax, ecx
mov al, 0
rep stosb ; copy byte from al to [edi++]
 
@@:
 
; tx_ring[nr].PacketBuffer = (u32) virt_to_le32desc(ptxb);
mov eax, dword [forcedeth_tmp_nr]
mov cl, sizeof.forcedeth_TxDesc
mul cl
add eax, forcedeth_tx_ring
mov ebx, eax
mov eax, dword [forcedeth_tmp_ptxb]
sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov [ebx + forcedeth_TxDesc.PacketBuffer], eax
 
;DEBUGF 1,"K : FORCEDETH: transmit: PacketBuffer = 0x%x\n", eax
;DEBUGF 1,"K : FORCEDETH: transmit: txflags = 0x%x\n", [forcedeth_txflags]:8
 
; wmb();
; tx_ring[nr].FlagLen = cpu_to_le32((s - 1) | np->tx_flags);
pop eax ; header length + data length
mov ecx, dword [forcedeth_txflags]
or eax, ecx
mov [ebx + forcedeth_TxDesc.FlagLen], eax
 
; writel(NVREG_TXRXCTL_KICK | np->desc_ver, base + NvRegTxRxControl);
mov edi, dword [forcedeth_mapio_addr]
mov eax, dword [forcedeth_desc_ver]
or eax, NVREG_TXRXCTL_KICK
mov dword [edi+NvRegTxRxControl], eax
 
; pci_push(base);
call forcedeth_pci_push
 
; np->next_tx++
inc dword [forcedeth_next_tx] ; may be need to reset? Overflow?
 
ret
 
;***************************************************************************
; Function
; forcedeth_cable
;
; Description
; Return AL=0, if cable is not connected
; Returm AL=1, if cable is connected
;
;***************************************************************************
forcedeth_cable:
 
mov al, 1
cmp dword [forcedeth_nocable], 1
jne .return
mov al, 0
 
.return:
ret
 
;***************************************************************************
; read/write a register on the PHY.
; Caller must guarantee serialization
; Input: EAX - miireg, EBX - addr, ECX - value
; Output: EAX - retval
forcedeth_mii_rw:
push ebx
push eax ; save miireg
; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus)
mov edi, dword [forcedeth_mapio_addr]
mov dword [edi+NvRegMIIStatus], NVREG_MIISTAT_MASK
 
; reg = readl(base + NvRegMIIControl)
mov eax, dword [edi+NvRegMIIControl]
test eax, NVREG_MIICTL_INUSE
jz @f
; writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl)
mov dword [edi+NvRegMIIControl], NVREG_MIICTL_INUSE
; nv_udelay(NV_MIIBUSY_DELAY)
mov esi, NV_MIIBUSY_DELAY
call forcedeth_nv_udelay
@@:
; reg = (addr << NVREG_MIICTL_ADDRSHIFT) | miireg
pop edx ; restore miireg
mov eax, ebx
shl eax, NVREG_MIICTL_ADDRSHIFT
or eax, edx
mov dword [forcedeth_tmp_reg], eax
 
cmp ecx, MII_READ
je @f
; writel(value, base + NvRegMIIData)
mov dword [edi+NvRegMIIData], ecx
; reg |= NVREG_MIICTL_WRITE
or dword [forcedeth_tmp_reg], NVREG_MIICTL_WRITE
@@:
; writel(reg, base + NvRegMIIControl)
mov eax, dword [forcedeth_tmp_reg]
mov dword [edi+NvRegMIIControl], eax
 
push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;;
 
; reg_delay(NvRegMIIControl, NVREG_MIICTL_INUSE, 0, NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, NULL)
stdcall forcedeth_reg_delay,NvRegMIIControl,NVREG_MIICTL_INUSE,0,NV_MIIPHY_DELAY,NV_MIIPHY_DELAYMAX,0
 
pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;;
 
test eax, eax
jz @f
;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw of reg %d at PHY %d timed out.\n", edx, ebx
mov eax, 0xffffffff
jmp .return
@@:
cmp ecx, MII_READ
je @f
;it was a write operation - fewer failures are detectable
;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw wrote 0x%x to reg %d at PHY %d\n", ecx, edx, ebx
mov eax, 0
jmp .return
@@:
; readl(base + NvRegMIIStatus)
mov eax, dword [edi+NvRegMIIStatus]
test eax, NVREG_MIISTAT_ERROR
jz @f
;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw of reg %d at PHY %d failed.\n", edx, ebx
mov eax, 0xffffffff
jmp .return
@@:
; retval = readl(base + NvRegMIIData)
mov eax, dword [edi+NvRegMIIData]
;;;;;;;; DEBUGF 1,"K : FORCEDETH: mii_rw read from reg %d at PHY %d: 0x%x.\n", edx, ebx, eax
.return:
pop ebx
ret
 
 
 
; Input: ESI - delay
; Output: none
forcedeth_nv_udelay:
 
push ebx
cmp dword [forcedeth_in_shutdown], 0
jne @f
call forcedeth_udelay ; delay on ESI
jmp .return
@@:
.loop:
cmp esi, 0
je .return
; Don't allow an rx_ring overflow to happen
; while shutting down the NIC it will
; kill the receive function.
 
call forcedeth_drop_rx
mov ebx, 3 ; sleep = 3
cmp ebx, esi ; if(sleep > delay)
jle @f
mov ebx, esi ; sleep = delay
@@:
push esi
mov esi, ebx
; udelay(sleep)
call forcedeth_udelay ; delay on ESI
pop esi
sub esi, ebx ; delay -= sleep
jmp .loop
 
.return:
pop ebx
ret
 
 
; Input: none
; Output: none
forcedeth_drop_rx:
 
push eax ebx ecx edi
 
; events = readl(base + NvRegIrqStatus)
mov edi, dword [forcedeth_mapio_addr]
mov eax, dword [edi+NvRegIrqStatus]
 
test eax, eax
jz @f
; writel(events, base + NvRegIrqStatus)
mov dword [edi+NvRegIrqStatus], eax
@@:
;if (!(events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)))
test eax, (NVREG_IRQ_RX_ERROR or NVREG_IRQ_RX or NVREG_IRQ_RX_NOBUF)
jz .return
.loop:
; i = np->cur_rx % RX_RING
mov eax, dword [forcedeth_cur_rx]
and eax, (RX_RING-1)
; //Flags = le32_to_cpu(rx_ring[i].FlagLen)
; Flags = rx_ring[i].FlagLen
mov cl, sizeof.forcedeth_RxDesc
mul cl
add eax, forcedeth_rx_ring
mov ebx, eax
mov eax, [ebx + forcedeth_RxDesc.FlagLen]
; len = nv_descr_getlength(&rx_ring[i], np->desc_ver)
; > len = Flags & ((np->desc_ver == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2)
; ??? len don't used later !!! ???
; ...
test eax, NV_RX_AVAIL
jnz .return ; still owned by hardware,
; wmb()
; ??? may be empty function ???
; np->cur_rx++
inc dword [forcedeth_cur_rx]
; alloc_rx(NULL)
call forcedeth_alloc_rx
.return:
pop edi ecx ebx eax
ret
 
 
; Fill rx ring entries.
; Return 1 if the allocations for the skbs failed and the
; rx engine is without Available descriptors
; Input: none
; Output: none
forcedeth_alloc_rx:
 
push eax ebx ecx edx
; refill_rx = np->refill_rx
mov ecx, dword [forcedeth_refill_rx]
.loop:
cmp dword [forcedeth_cur_rx], ecx
je .loop_end
; nr = refill_rx % RX_RING
mov eax, ecx
and eax, (RX_RING-1) ; nr
; rx_ring[nr].PacketBuffer = &rxb[nr * RX_NIC_BUFSIZE]
push ecx
push eax
mov cl, sizeof.forcedeth_RxDesc
mul cl
add eax, forcedeth_rx_ring
mov ebx, eax
pop eax
mov cx, RX_NIC_BUFSIZE
mul cx
pop ecx
add eax, forcedeth_rxb
sub eax, OS_BASE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov [ebx + forcedeth_RxDesc.PacketBuffer], eax
; wmb()
; ...
; rx_ring[nr].FlagLen = RX_NIC_BUFSIZE | NV_RX_AVAIL
mov [ebx + forcedeth_RxDesc.FlagLen], (RX_NIC_BUFSIZE or NV_RX_AVAIL)
inc ecx
jmp .loop
.loop_end:
; np->refill_rx = refill_rx
mov [forcedeth_refill_rx], ecx
.return:
pop edx ecx ebx eax
ret
 
 
; Delay in millisec
; Input: ESI - delay in ms
; Output: none
forcedeth_udelay:
call delay_ms
ret
 
; Input: offset:word, mask:dword, target:dword, delay:word, delaymax:word, msg:dword
; Output: EAX - 0|1
;;;;proc forcedeth_reg_delay,offset:word,mask:dword,target:dword,delay:word,delaymax:word,msg:dword
proc forcedeth_reg_delay,offset:dword,mask:dword,target:dword,delay:dword,delaymax:dword,msg:dword
 
push ebx esi edi
; pci_push(base)
call forcedeth_pci_push
.loop:
; nv_udelay(delay)
mov esi, dword [delay]
call forcedeth_nv_udelay ; delay in esi
mov eax, dword [delaymax]
sub eax, dword [delay]
mov dword [delaymax], eax
; if (delaymax < 0)
test dword [delaymax], 0x80000000
jz @f
; return 1
mov eax, 1
jmp .return
@@:
; while ((readl(base + offset) & mask) != target)
mov edi, dword [forcedeth_mapio_addr]
mov ebx, dword [offset]
mov eax, dword [edi+ebx]
and eax, dword [mask]
cmp eax, dword [target]
jne .loop
xor eax, eax
.return:
pop edi esi ebx
ret
endp
 
 
; Input: none
; Output: none
forcedeth_pci_push:
push eax edi
;force out pending posted writes
mov edi, dword [forcedeth_mapio_addr]
mov eax, dword [edi]
pop edi eax
ret
 
 
; Input: none
; Output: EAX - result (0 = OK, other = error)
forcedeth_phy_init:
 
push ebx ecx
; set advertise register
; reg = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ);
; EBX - addr, EAX - miireg, ECX - value
mov ebx, dword [forcedeth_phyaddr]
mov eax, MII_ADVERTISE
mov ecx, MII_READ
call forcedeth_mii_rw ; reg = eax
 
; reg |=
; (ADVERTISE_10HALF | ADVERTISE_10FULL | ADVERTISE_100HALF |
; ADVERTISE_100FULL | 0x800 | 0x400);
or eax, (ADVERTISE_10HALF or ADVERTISE_10FULL or ADVERTISE_100HALF or ADVERTISE_100FULL or 0x800 or 0x400)
 
; if (mii_rw(nic, np->phyaddr, MII_ADVERTISE, reg))
; EBX - addr, EAX - miireg, ECX - value
mov ecx, eax ; reg
mov eax, MII_ADVERTISE
call forcedeth_mii_rw ; eax -> return
 
test eax, eax
jz @f
; printf("phy write to advertise failed.\n");
DEBUGF 1," K : FORCEDETH: phy write to advertise failed.\n"
 
; return PHY_ERROR;
mov eax, PHY_ERROR
jmp .return
@@:
; get phy interface type
; phyinterface = readl(base + NvRegPhyInterface);
mov edi, dword [forcedeth_mapio_addr]
mov eax, dword [edi+NvRegPhyInterface] ; phyinterface = eax
mov dword [forcedeth_tmp_phyinterface], eax
 
;;;;;;;;;;;;;;;;;;;;;;;;;
DEBUGF 1," K : FORCEDETH: phy interface type = 0x%x\n", [forcedeth_tmp_phyinterface]:8
;;;;;;;;;;;;;;;;;;;;;;;;;
 
; see if gigabit phy
; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ);
; EBX - addr, EAX - miireg, ECX - value
mov eax, MII_BMSR
mov ecx, MII_READ
call forcedeth_mii_rw ; mii_status = eax
; if (mii_status & PHY_GIGABIT)
test eax, PHY_GIGABIT
jnz .gigabit
; np->gigabit = 0;
mov dword [forcedeth_gigabit], 0
jmp .next_if
 
.gigabit:
; np->gigabit = PHY_GIGABIT;
mov dword [forcedeth_gigabit], PHY_GIGABIT
 
; mii_control_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_CR, MII_READ);
; EBX - addr, EAX - miireg, ECX - value
mov eax, MII_1000BT_CR
mov ecx, MII_READ
call forcedeth_mii_rw ; mii_control_1000 = eax
; mii_control_1000 &= ~ADVERTISE_1000HALF;
and eax, (not ADVERTISE_1000HALF)
 
; if (phyinterface & PHY_RGMII)
test dword [forcedeth_tmp_phyinterface], PHY_RGMII
jz @f
; mii_control_1000 |= ADVERTISE_1000FULL
or eax, ADVERTISE_1000FULL
jmp .next
@@:
; mii_control_1000 &= ~ADVERTISE_1000FULL
and eax, (not ADVERTISE_1000FULL)
 
.next:
; if (mii_rw(nic, np->phyaddr, MII_1000BT_CR, mii_control_1000))
; EBX - addr, EAX - miireg, ECX - value
mov ecx, eax
mov eax, MII_1000BT_CR
call forcedeth_mii_rw ; eax -> return
 
test eax, eax
jz .next_if
 
; printf("phy init failed.\n");
DEBUGF 1," K : FORCEDETH: phy init failed.\n"
 
; return PHY_ERROR;
mov eax, PHY_ERROR
jmp .return
 
.next_if:
 
; reset the phy
; if (phy_reset(nic))
call forcedeth_phy_reset
test eax, eax
jz @f
; printf("phy reset failed\n")
DEBUGF 1," K : FORCEDETH: phy reset failed.\n"
; return PHY_ERROR
mov eax, PHY_ERROR
jmp .return
@@:
 
; phy vendor specific configuration
; if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII))
cmp dword [forcedeth_phy_oui], PHY_OUI_CICADA
jne .next_if2
test dword [forcedeth_tmp_phyinterface], PHY_RGMII
jz .next_if2
 
; phy_reserved = mii_rw(nic, np->phyaddr, MII_RESV1, MII_READ)
; EBX - addr, EAX - miireg, ECX - value
mov eax, MII_RESV1
mov ecx, MII_READ
call forcedeth_mii_rw ; phy_reserved = eax
; phy_reserved &= ~(PHY_INIT1 | PHY_INIT2)
and eax, (not (PHY_INIT1 or PHY_INIT2))
; phy_reserved |= (PHY_INIT3 | PHY_INIT4)
or eax, (PHY_INIT3 or PHY_INIT4)
; if (mii_rw(nic, np->phyaddr, MII_RESV1, phy_reserved))
; EBX - addr, EAX - miireg, ECX - value
mov ecx, eax
mov eax, MII_RESV1
call forcedeth_mii_rw ; eax -> return
test eax, eax
jz @f
; printf("phy init failed.\n")
DEBUGF 1," K : FORCEDETH: phy init failed.\n"
; return PHY_ERROR
mov eax, PHY_ERROR
jmp .return
@@:
; phy_reserved = mii_rw(nic, np->phyaddr, MII_NCONFIG, MII_READ);
; EBX - addr, EAX - miireg, ECX - value
mov eax, MII_NCONFIG
mov ecx, MII_READ
call forcedeth_mii_rw ; phy_reserved = eax
 
; phy_reserved |= PHY_INIT5
or eax, PHY_INIT5
; if (mii_rw(nic, np->phyaddr, MII_NCONFIG, phy_reserved))
; EBX - addr, EAX - miireg, ECX - value
mov ecx, eax
mov eax, MII_NCONFIG
call forcedeth_mii_rw ; eax -> return
test eax, eax
jz .next_if2
; printf("phy init failed.\n")
DEBUGF 1," K : FORCEDETH: phy init failed.\n"
; return PHY_ERROR
mov eax, PHY_ERROR
jmp .return
 
.next_if2:
 
; if (np->phy_oui == PHY_OUI_CICADA)
cmp dword [forcedeth_phy_oui], PHY_OUI_CICADA
jne .restart
; phy_reserved = mii_rw(nic, np->phyaddr, MII_SREVISION, MII_READ)
; EBX - addr, EAX - miireg, ECX - value
mov eax, MII_SREVISION
mov ecx, MII_READ
call forcedeth_mii_rw ; phy_reserved = eax
; phy_reserved |= PHY_INIT6
or eax, PHY_INIT6
; if (mii_rw(nic, np->phyaddr, MII_SREVISION, phy_reserved))
mov ecx, eax
mov eax, MII_SREVISION
call forcedeth_mii_rw ; eax -> return
test eax, eax
jz .restart
; printf("phy init failed.\n");
DEBUGF 1," K : FORCEDETH: phy init failed.\n"
; return PHY_ERROR;
jmp .return
 
.restart:
; restart auto negotiation
; mii_control = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ)
; EBX - addr, EAX - miireg, ECX - value
mov eax, MII_BMCR
mov ecx, MII_READ
call forcedeth_mii_rw ; mii_control = eax
 
; mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE)
or eax, (BMCR_ANRESTART or BMCR_ANENABLE)
; if (mii_rw(nic, np->phyaddr, MII_BMCR, mii_control))
mov ecx, eax
mov eax, MII_BMCR
call forcedeth_mii_rw ; eax -> return
test eax, eax
jz .ok
 
; return PHY_ERROR;
mov eax, PHY_ERROR
jmp .return
 
.ok:
mov eax, 0
.return:
pop ecx ebx
ret
 
 
; Input: none
; Output: EAX - result (0 = OK, other = error)
forcedeth_phy_reset:
 
push ebx ecx edx
 
; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ);
; EBX - addr, EAX - miireg, ECX - value
mov ebx, dword [forcedeth_phyaddr]
mov eax, MII_BMCR
mov ecx, MII_READ
call forcedeth_mii_rw ; miicontrol = eax
 
; miicontrol |= BMCR_RESET;
or eax, BMCR_RESET
push eax
 
; if (mii_rw(nic, np->phyaddr, MII_BMCR, miicontrol))
; EBX - addr, EAX - miireg, ECX - value
mov ecx, eax
mov eax, MII_BMCR
call forcedeth_mii_rw ; miicontrol = eax
 
test eax, eax
jz @f
pop eax
mov eax, 0xffffffff
jmp .return
@@:
pop eax
 
; wait for 500ms
; mdelay(500)
mov esi, 500
call forcedeth_udelay
 
; must wait till reset is deasserted
; while (miicontrol & BMCR_RESET) {
mov edx, 100
.while_loop:
test eax, BMCR_RESET
jz .while_loop_exit
 
; mdelay(10);
mov esi, 10
call forcedeth_udelay
 
; miicontrol = mii_rw(nic, np->phyaddr, MII_BMCR, MII_READ);
; EBX - addr, EAX - miireg, ECX - value
mov eax, MII_BMCR
mov ecx, MII_READ
call forcedeth_mii_rw ; miicontrol = eax
 
; FIXME: 100 tries seem excessive
; if (tries++ > 100)
dec edx
jnz .while_loop
; return -1;
mov eax, 0xffffffff
jmp .return
.while_loop_exit:
; return 0
mov eax, 0
.return:
pop edx ecx ebx
ret
 
; Input: none
; Output: none
forcedeth_mac_reset:
push esi edi
 
; dprintf("mac_reset\n")
DEBUGF 1," K : FORCEDETH: mac_reset.\n"
 
; writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl)
mov edi, dword [forcedeth_mapio_addr]
mov eax, dword [forcedeth_desc_ver]
or eax, (NVREG_TXRXCTL_BIT2 or NVREG_TXRXCTL_RESET)
mov dword [edi+NvRegTxRxControl], eax
 
; pci_push(base)
call forcedeth_pci_push
; writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset)
mov dword [edi+NvRegMacReset], NVREG_MAC_RESET_ASSERT
 
; pci_push(base)
call forcedeth_pci_push
 
; udelay(NV_MAC_RESET_DELAY)
mov esi, NV_MAC_RESET_DELAY
call forcedeth_nv_udelay
 
; writel(0, base + NvRegMacReset)
mov dword [edi+NvRegMacReset], 0
 
; pci_push(base)
call forcedeth_pci_push
; udelay(NV_MAC_RESET_DELAY)
mov esi, NV_MAC_RESET_DELAY
call forcedeth_nv_udelay
 
; writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl)
mov eax, dword [forcedeth_desc_ver]
or eax, NVREG_TXRXCTL_BIT2
mov dword [edi+NvRegTxRxControl], eax
; pci_push(base)
call forcedeth_pci_push
 
pop edi esi
ret
 
; Input: none
; Output: none
forcedeth_init_ring:
push eax ebx ecx
 
; np->next_tx = np->nic_tx = 0
mov dword[forcedeth_next_tx], 0
mov dword[forcedeth_nic_tx], 0
 
; for (i = 0; i < TX_RING; i++)
mov ecx, TX_RING
 
.for_loop:
; tx_ring[i].FlagLen = 0;
mov eax, ecx
dec eax
mov bl, sizeof.forcedeth_TxDesc
mul bl
add eax, forcedeth_tx_ring
mov ebx, eax
mov dword [ebx + forcedeth_TxDesc.FlagLen], 0
loop .for_loop
 
; np->cur_rx = RX_RING;
mov dword [forcedeth_cur_rx], RX_RING
; np->refill_rx = 0;
mov dword [forcedeth_refill_rx], 0
;for (i = 0; i < RX_RING; i++)
mov ecx, RX_RING
 
.for_loop2:
; rx_ring[i].FlagLen = 0;
mov eax, ecx
dec eax
mov bl, sizeof.forcedeth_RxDesc
mul bl
add eax, forcedeth_rx_ring
mov ebx, eax
mov dword [ebx + forcedeth_RxDesc.FlagLen], 0
loop .for_loop2
; alloc_rx(nic);
call forcedeth_alloc_rx
 
.return:
pop ecx ebx eax
ret
 
; Input: none
; Output: none
forcedeth_txrx_reset:
push eax esi edi
 
; dprintf(("txrx_reset\n"))
DEBUGF 1," K : FORCEDETH: txrx_reset.\n"
 
; writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl)
mov edi, dword [forcedeth_mapio_addr]
mov eax, dword [forcedeth_desc_ver]
or eax, (NVREG_TXRXCTL_BIT2 or NVREG_TXRXCTL_RESET)
mov dword [edi+NvRegTxRxControl], eax
 
; pci_push(base)
call forcedeth_pci_push
 
; nv_udelay(NV_TXRX_RESET_DELAY)
mov esi, NV_TXRX_RESET_DELAY
call forcedeth_nv_udelay
 
; writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl)
mov eax, dword [forcedeth_desc_ver]
or eax, NVREG_TXRXCTL_BIT2
mov dword [edi+NvRegTxRxControl], eax
; pci_push(base)
call forcedeth_pci_push
 
.return:
pop edi esi eax
ret
 
; Input: none
; Output: none
forcedeth_set_multicast:
push edi
 
; u32 addr[2];
; u32 mask[2];
; u32 pff;
; u32 alwaysOff[2];
; u32 alwaysOn[2];
;
; memset(addr, 0, sizeof(addr));
; memset(mask, 0, sizeof(mask));
;
; pff = NVREG_PFF_MYADDR;
;
; alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0;
;
; addr[0] = alwaysOn[0];
; addr[1] = alwaysOn[1];
; mask[0] = alwaysOn[0] | alwaysOff[0];
; mask[1] = alwaysOn[1] | alwaysOff[1];
;
; addr[0] |= NVREG_MCASTADDRA_FORCE;
; pff |= NVREG_PFF_ALWAYS;
; stop_rx();
call forcedeth_stop_rx
; writel(addr[0], base + NvRegMulticastAddrA);
mov edi, dword [forcedeth_mapio_addr]
mov dword [edi+NvRegMulticastAddrA], NVREG_MCASTADDRA_FORCE
; writel(addr[1], base + NvRegMulticastAddrB);
mov dword [edi+NvRegMulticastAddrB], 0
; writel(mask[0], base + NvRegMulticastMaskA);
mov dword [edi+NvRegMulticastMaskA], 0
; writel(mask[1], base + NvRegMulticastMaskB);
mov dword [edi+NvRegMulticastMaskB], 0
; writel(pff, base + NvRegPacketFilterFlags);
mov dword [edi+NvRegPacketFilterFlags], (NVREG_PFF_MYADDR or NVREG_PFF_ALWAYS)
; start_rx(nic);
call forcedeth_start_rx
 
.return:
pop edi
ret
 
; Input: none
; Output: none
forcedeth_start_rx:
push edi
 
; dprintf(("start_rx\n"))
DEBUGF 1," K : FORCEDETH: start_rx.\n"
 
; Already running? Stop it.
; if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) {
mov edi, dword [forcedeth_mapio_addr]
mov eax, dword [edi+NvRegReceiverControl]
test eax, NVREG_RCVCTL_START
jz @f
; writel(0, base + NvRegReceiverControl)
mov dword [edi+NvRegReceiverControl], 0
; pci_push(base)
call forcedeth_pci_push
 
@@:
; writel(np->linkspeed, base + NvRegLinkSpeed);
mov eax, dword [forcedeth_linkspeed]
mov dword [edi+NvRegLinkSpeed], eax
; pci_push(base);
call forcedeth_pci_push
; writel(NVREG_RCVCTL_START, base + NvRegReceiverControl);
mov dword [edi+NvRegReceiverControl], NVREG_RCVCTL_START
; pci_push(base);
call forcedeth_pci_push
 
.return:
pop edi
ret
 
; Input: none
; Output: none
forcedeth_stop_rx:
push esi edi
 
; dprintf(("stop_rx\n"))
DEBUGF 1," K : FORCEDETH: stop_rx.\n"
 
; writel(0, base + NvRegReceiverControl)
mov edi, dword [forcedeth_mapio_addr]
mov dword [edi+NvRegReceiverControl], 0
 
push ebx edx edi ;;;;;;;;;;;;;;;;;;;;;;
; reg_delay(NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, "stop_rx: ReceiverStatus remained busy");
stdcall forcedeth_reg_delay,NvRegReceiverStatus,NVREG_RCVSTAT_BUSY,0,NV_RXSTOP_DELAY1,NV_RXSTOP_DELAY1MAX,0
pop edi edx ebx ;;;;;;;;;;;;;;;;;;;;;;
 
 
; nv_udelay(NV_RXSTOP_DELAY2)
mov esi, NV_RXSTOP_DELAY2
call forcedeth_nv_udelay
 
; writel(0, base + NvRegLinkSpeed)
mov dword [edi+NvRegLinkSpeed], 0
 
.return:
pop edi esi
ret
 
; Input: none
; Output: EAX
forcedeth_update_linkspeed:
push ebx ecx esi edi
 
; BMSR_LSTATUS is latched, read it twice:
; we want the current value.
; mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ)
;EBX - addr, EAX - miireg, ECX - value
mov ebx, dword [forcedeth_phyaddr]
mov eax, MII_BMSR
mov ecx, MII_READ
call forcedeth_mii_rw
 
 
; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ)
;EBX - addr, EAX - miireg, ECX - value
mov ebx, dword [forcedeth_phyaddr]
mov eax, MII_BMSR
mov ecx, MII_READ
call forcedeth_mii_rw ; mii_status = eax
; yhlu
 
; for(i=0;i<30;i++) {
mov ecx, 30
.for_loop:
push ecx
 
; mii_status = mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ);
;EBX - addr, EAX - miireg, ECX - value
;mov ebx, dword [forcedeth_phyaddr]
mov eax, MII_BMSR
mov ecx, MII_READ
call forcedeth_mii_rw ; mii_status = eax
 
; if((mii_status & BMSR_LSTATUS) && (mii_status & BMSR_ANEGCOMPLETE)) break;
test eax, BMSR_LSTATUS
jz @f
test eax, BMSR_ANEGCOMPLETE
jz @f
; break
pop ecx
jmp .break
@@:
 
; mdelay(100);
push eax ; ???
mov esi, 100
call forcedeth_udelay
pop eax ; ???
 
pop ecx
loop .for_loop
 
.break:
 
; if (!(mii_status & BMSR_LSTATUS)) {
test eax, BMSR_LSTATUS
jnz @f
 
; printf("no link detected by phy - falling back to 10HD.\n")
DEBUGF 1," K : FORCEDETH: update_linkspeed: no link detected by phy - falling back to 10HD.\n"
 
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
 
; newdup = 0;
mov dword [forcedeth_tmp_newdup], 0
; retval = 0;
mov dword [forcedeth_tmp_retval], 0
 
; goto set_speed;
jmp .set_speed
 
@@:
 
; check auto negotiation is complete
; if (!(mii_status & BMSR_ANEGCOMPLETE)) {
test eax, BMSR_ANEGCOMPLETE
jnz @f
 
; still in autonegotiation - configure nic for 10 MBit HD and wait.
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
 
; newdup = 0
mov dword [forcedeth_tmp_newdup], 0
 
; retval = 0
mov dword [forcedeth_tmp_retval], 0
 
; printf("autoneg not completed - falling back to 10HD.\n")
DEBUGF 1," K : FORCEDETH: update_linkspeed: autoneg not completed - falling back to 10HD.\n"
 
; goto set_speed
jmp .set_speed
 
@@:
 
; retval = 1
mov dword [forcedeth_tmp_retval], 1
; if (np->gigabit == PHY_GIGABIT) {
cmp dword [forcedeth_gigabit], PHY_GIGABIT
jne .end_if
; control_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_CR, MII_READ)
;EBX - addr, EAX - miireg, ECX - value
;mov ebx, dword [forcedeth_phyaddr]
mov eax, MII_1000BT_CR
mov ecx, MII_READ
call forcedeth_mii_rw ; control_1000 = eax
mov dword [forcedeth_tmp_control_1000], eax
; status_1000 = mii_rw(nic, np->phyaddr, MII_1000BT_SR, MII_READ)
;EBX - addr, EAX - miireg, ECX - value
;mov ebx, dword [forcedeth_phyaddr]
mov eax, MII_1000BT_SR
mov ecx, MII_READ
call forcedeth_mii_rw ; status_1000 = eax
;mov dword [forcedeth_tmp_status_1000], eax
; if ((control_1000 & ADVERTISE_1000FULL) &&
; (status_1000 & LPA_1000FULL)) {
test eax, LPA_1000FULL
jz .end_if
test dword [forcedeth_tmp_control_1000], ADVERTISE_1000FULL
jz .end_if
 
; printf ("update_linkspeed: GBit ethernet detected.\n")
DEBUGF 1," K : FORCEDETH: update_linkspeed: GBit ethernet detected.\n"
 
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_1000
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_1000)
 
; newdup = 1
mov dword [forcedeth_tmp_newdup], 1
 
; goto set_speed
jmp .set_speed
 
.end_if:
 
; adv = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ);
;EBX - addr, EAX - miireg, ECX - value
;mov ebx, dword [forcedeth_phyaddr]
mov eax, MII_ADVERTISE
mov ecx, MII_READ
call forcedeth_mii_rw ; adv = eax
mov dword [forcedeth_tmp_adv], eax
 
; lpa = mii_rw(nic, np->phyaddr, MII_LPA, MII_READ);
;EBX - addr, EAX - miireg, ECX - value
;mov ebx, dword [forcedeth_phyaddr]
mov eax, MII_LPA
mov ecx, MII_READ
call forcedeth_mii_rw ; lpa = eax
mov dword [forcedeth_tmp_lpa], eax
 
; dprintf(("update_linkspeed: PHY advertises 0x%hX, lpa 0x%hX.\n", adv, lpa));
DEBUGF 1," K : FORCEDETH: update_linkspeed: PHY advertises 0x%x, lpa 0x%x.\n", [forcedeth_tmp_adv]:8, [forcedeth_tmp_lpa]:8
 
; FIXME: handle parallel detection properly, handle gigabit ethernet
; lpa = lpa & adv
mov eax, dword [forcedeth_tmp_adv]
and dword [forcedeth_tmp_lpa], eax
 
mov eax, dword [forcedeth_tmp_lpa]
 
; if (lpa & LPA_100FULL) {
test eax, LPA_100FULL
jz @f
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_100)
; newdup = 1
mov dword [forcedeth_tmp_newdup], 1
jmp .set_speed
@@:
; } else if (lpa & LPA_100HALF) {
test eax, LPA_100HALF
jz @f
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_100)
; newdup = 0
mov dword [forcedeth_tmp_newdup], 0
jmp .set_speed
@@:
; } else if (lpa & LPA_10FULL) {
test eax, LPA_10FULL
jz @f
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
; newdup = 1
mov dword [forcedeth_tmp_newdup], 1
jmp .set_speed
@@:
; } else if (lpa & LPA_10HALF) {
test eax, LPA_10HALF
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10;
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
; newdup = 0;
mov dword [forcedeth_tmp_newdup], 0
jmp .set_speed
@@:
; } else {
; printf("bad ability %hX - falling back to 10HD.\n", lpa)
DEBUGF 1," K : FORCEDETH: update_linkspeed: bad ability 0x%x - falling back to 10HD.\n", eax
 
; newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10
mov dword [forcedeth_tmp_newls], (NVREG_LINKSPEED_FORCE or NVREG_LINKSPEED_10)
; newdup = 0
mov dword [forcedeth_tmp_newdup], 0
; }
 
.set_speed:
 
; if (np->duplex == newdup && np->linkspeed == newls)
mov eax, dword [forcedeth_tmp_newdup]
cmp eax, dword [forcedeth_duplex]
jne .end_if2
mov eax, dword [forcedeth_tmp_newls]
cmp eax, dword [forcedeth_linkspeed]
jne .end_if2
; return retval;
jmp .return
.end_if2:
; dprintf(("changing link setting from %d/%s to %d/%s.\n",
; np->linkspeed, np->duplex ? "Full-Duplex": "Half-Duplex", newls, newdup ? "Full-Duplex": "Half-Duplex"))
DEBUGF 1," K : FORCEDETH: update_linkspeed: changing link from %x/XD to %x/XD.\n", [forcedeth_linkspeed]:8, [forcedeth_tmp_newls]:8 ; !!!!!!!!!!!!!!!!!!!!!!!!!!!!
; np->duplex = newdup
mov eax, dword [forcedeth_tmp_newdup]
mov dword [forcedeth_duplex], eax
 
; np->linkspeed = newls
mov eax, [forcedeth_tmp_newls]
mov dword [forcedeth_linkspeed], eax
; if (np->gigabit == PHY_GIGABIT) {
cmp dword [forcedeth_gigabit], PHY_GIGABIT
jne .end_if3
 
; phyreg = readl(base + NvRegRandomSeed);
mov edi, dword [forcedeth_mapio_addr]
mov eax, dword [edi+NvRegRandomSeed]
 
; phyreg &= ~(0x3FF00);
and eax, not (0x3FF00)
mov ecx, eax ; phyreg = ecx
 
; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10)
mov eax, dword [forcedeth_linkspeed]
and eax, 0xFFF
cmp eax, NVREG_LINKSPEED_10
jne @f
; phyreg |= NVREG_RNDSEED_FORCE3
or ecx, NVREG_RNDSEED_FORCE3
jmp .end_if4
@@:
; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100)
cmp eax, NVREG_LINKSPEED_100
jne @f
; phyreg |= NVREG_RNDSEED_FORCE2
or ecx, NVREG_RNDSEED_FORCE2
jmp .end_if4
@@:
; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000)
cmp eax, NVREG_LINKSPEED_1000
jne .end_if4
; phyreg |= NVREG_RNDSEED_FORCE
or ecx, NVREG_RNDSEED_FORCE
.end_if4:
; writel(phyreg, base + NvRegRandomSeed)
mov dword [edi+NvRegRandomSeed], ecx
 
.end_if3:
; phyreg = readl(base + NvRegPhyInterface)
mov ecx, dword [edi+NvRegPhyInterface]
 
; phyreg &= ~(PHY_HALF | PHY_100 | PHY_1000)
and ecx, not (PHY_HALF or PHY_100 or PHY_1000)
; if (np->duplex == 0)
cmp dword [forcedeth_duplex], 0
jne @f
; phyreg |= PHY_HALF
or ecx, PHY_HALF
@@:
; if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100)
mov eax, dword [forcedeth_linkspeed]
and eax, 0xFFF
cmp eax, NVREG_LINKSPEED_100
jne @f
; phyreg |= PHY_100
or ecx, PHY_100
jmp .end_if5
@@:
; else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000)
cmp eax, NVREG_LINKSPEED_1000
jne .end_if5
; phyreg |= PHY_1000
or ecx, PHY_1000
 
.end_if5:
 
; writel(phyreg, base + NvRegPhyInterface)
mov dword [edi+NvRegPhyInterface], ecx
; writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD), base + NvRegMisc1);
cmp dword [forcedeth_duplex], 0
je @f
mov ecx, 0
jmp .next
@@:
mov ecx, NVREG_MISC1_HD
.next:
or ecx, NVREG_MISC1_FORCE
mov dword [edi+NvRegMisc1], ecx
 
; pci_push(base)
call forcedeth_pci_push
 
; writel(np->linkspeed, base + NvRegLinkSpeed)
mov eax, dword [forcedeth_linkspeed]
mov dword [edi+NvRegLinkSpeed], eax
 
; pci_push(base)
call forcedeth_pci_push
 
.return:
; return retval
mov eax, dword [forcedeth_tmp_retval]
pop edi esi ecx ebx
ret
 
; Input: none
; Output: none
forcedeth_start_tx:
push edi
; dprintf(("start_tx\n"))
DEBUGF 1," K : FORCEDETH: start_tx.\n"
 
; writel(NVREG_XMITCTL_START, base + NvRegTransmitterControl)
mov edi, dword [forcedeth_mapio_addr]
mov dword [edi+NvRegTransmitterControl], NVREG_XMITCTL_START
 
; pci_push(base)
call forcedeth_pci_push
 
.return:
pop edi
ret
 
; Interrupt handler
forcedeth_int_handler:
DEBUGF 1," K : FORCEDETH: interrupt handler.\n"
 
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/eth_drv/drivers/rtl8169.inc
0,0 → 1,1219
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; RTL8169.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.1 11 February 2007 ;;
;; ;;
;; Driver for chips of RealTek 8169 family ;;
;; References: ;;
;; r8169.c - linux driver (etherboot project) ;;
;; ethernet driver template by Mike Hibbett ;;
;; ;;
;; The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; Copyright 2007 mike.dld, ;;
;; mike.dld@gmail.com ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
ETH_ALEN equ 6
ETH_HLEN equ (2 * ETH_ALEN + 2)
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for
; mininmum 64bytes frame length
 
RTL8169_REG_MAC0 equ 0x0 ; Ethernet hardware address
RTL8169_REG_MAR0 equ 0x8 ; Multicast filter
RTL8169_REG_TxDescStartAddr equ 0x20
RTL8169_REG_TxHDescStartAddr equ 0x28
RTL8169_REG_FLASH equ 0x30
RTL8169_REG_ERSR equ 0x36
RTL8169_REG_ChipCmd equ 0x37
RTL8169_REG_TxPoll equ 0x38
RTL8169_REG_IntrMask equ 0x3C
RTL8169_REG_IntrStatus equ 0x3E
RTL8169_REG_TxConfig equ 0x40
RTL8169_REG_RxConfig equ 0x44
RTL8169_REG_RxMissed equ 0x4C
RTL8169_REG_Cfg9346 equ 0x50
RTL8169_REG_Config0 equ 0x51
RTL8169_REG_Config1 equ 0x52
RTL8169_REG_Config2 equ 0x53
RTL8169_REG_Config3 equ 0x54
RTL8169_REG_Config4 equ 0x55
RTL8169_REG_Config5 equ 0x56
RTL8169_REG_MultiIntr equ 0x5C
RTL8169_REG_PHYAR equ 0x60
RTL8169_REG_TBICSR equ 0x64
RTL8169_REG_TBI_ANAR equ 0x68
RTL8169_REG_TBI_LPAR equ 0x6A
RTL8169_REG_PHYstatus equ 0x6C
RTL8169_REG_RxMaxSize equ 0xDA
RTL8169_REG_CPlusCmd equ 0xE0
RTL8169_REG_RxDescStartAddr equ 0xE4
RTL8169_REG_ETThReg equ 0xEC
RTL8169_REG_FuncEvent equ 0xF0
RTL8169_REG_FuncEventMask equ 0xF4
RTL8169_REG_FuncPresetState equ 0xF8
RTL8169_REG_FuncForceEvent equ 0xFC
 
; InterruptStatusBits
RTL8169_ISB_SYSErr equ 0x8000
RTL8169_ISB_PCSTimeout equ 0x4000
RTL8169_ISB_SWInt equ 0x0100
RTL8169_ISB_TxDescUnavail equ 0x80
RTL8169_ISB_RxFIFOOver equ 0x40
RTL8169_ISB_LinkChg equ 0x20
RTL8169_ISB_RxOverflow equ 0x10
RTL8169_ISB_TxErr equ 0x08
RTL8169_ISB_TxOK equ 0x04
RTL8169_ISB_RxErr equ 0x02
RTL8169_ISB_RxOK equ 0x01
 
; RxStatusDesc
RTL8169_SD_RxRES equ 0x00200000
RTL8169_SD_RxCRC equ 0x00080000
RTL8169_SD_RxRUNT equ 0x00100000
RTL8169_SD_RxRWT equ 0x00400000
 
; ChipCmdBits
RTL8169_CMD_Reset equ 0x10
RTL8169_CMD_RxEnb equ 0x08
RTL8169_CMD_TxEnb equ 0x04
RTL8169_CMD_RxBufEmpty equ 0x01
 
; Cfg9346Bits
RTL8169_CFG_9346_Lock equ 0x00
RTL8169_CFG_9346_Unlock equ 0xC0
 
; rx_mode_bits
RTL8169_RXM_AcceptErr equ 0x20
RTL8169_RXM_AcceptRunt equ 0x10
RTL8169_RXM_AcceptBroadcast equ 0x08
RTL8169_RXM_AcceptMulticast equ 0x04
RTL8169_RXM_AcceptMyPhys equ 0x02
RTL8169_RXM_AcceptAllPhys equ 0x01
 
; RxConfigBits
RTL8169_RXC_FIFOShift equ 13
RTL8169_RXC_DMAShift equ 8
 
; TxConfigBits
RTL8169_TXC_InterFrameGapShift equ 24
RTL8169_TXC_DMAShift equ 8 ; DMA burst value (0-7) is shift this many bits
 
; rtl8169_PHYstatus
RTL8169_PHYS_TBI_Enable equ 0x80
RTL8169_PHYS_TxFlowCtrl equ 0x40
RTL8169_PHYS_RxFlowCtrl equ 0x20
RTL8169_PHYS_1000bpsF equ 0x10
RTL8169_PHYS_100bps equ 0x08
RTL8169_PHYS_10bps equ 0x04
RTL8169_PHYS_LinkStatus equ 0x02
RTL8169_PHYS_FullDup equ 0x01
 
; GIGABIT_PHY_registers
RTL8169_PHY_CTRL_REG equ 0
RTL8169_PHY_STAT_REG equ 1
RTL8169_PHY_AUTO_NEGO_REG equ 4
RTL8169_PHY_1000_CTRL_REG equ 9
 
; GIGABIT_PHY_REG_BIT
RTL8169_PHY_Restart_Auto_Nego equ 0x0200
RTL8169_PHY_Enable_Auto_Nego equ 0x1000
 
; PHY_STAT_REG = 1;
RTL8169_PHY_Auto_Neco_Comp equ 0x0020
 
; PHY_AUTO_NEGO_REG = 4;
RTL8169_PHY_Cap_10_Half equ 0x0020
RTL8169_PHY_Cap_10_Full equ 0x0040
RTL8169_PHY_Cap_100_Half equ 0x0080
RTL8169_PHY_Cap_100_Full equ 0x0100
 
; PHY_1000_CTRL_REG = 9;
RTL8169_PHY_Cap_1000_Full equ 0x0200
RTL8169_PHY_Cap_1000_Half equ 0x0100
 
RTL8169_PHY_Cap_PAUSE equ 0x0400
RTL8169_PHY_Cap_ASYM_PAUSE equ 0x0800
 
RTL8169_PHY_Cap_Null equ 0x0
 
; _MediaType
RTL8169_MT_10_Half equ 0x01
RTL8169_MT_10_Full equ 0x02
RTL8169_MT_100_Half equ 0x04
RTL8169_MT_100_Full equ 0x08
RTL8169_MT_1000_Full equ 0x10
 
; _TBICSRBit
RTL8169_TBI_LinkOK equ 0x02000000
 
; _DescStatusBit
RTL8169_DSB_OWNbit equ 0x80000000
RTL8169_DSB_EORbit equ 0x40000000
RTL8169_DSB_FSbit equ 0x20000000
RTL8169_DSB_LSbit equ 0x10000000
 
; MAC address length
MAC_ADDR_LEN equ 6
 
; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4)
MAX_ETH_FRAME_SIZE equ 1536
 
TX_FIFO_THRESH equ 256 ; In bytes
 
RX_FIFO_THRESH equ 7 ; 7 means NO threshold, Rx buffer level before first PCI xfer
RX_DMA_BURST equ 7 ; Maximum PCI burst, '6' is 1024
TX_DMA_BURST equ 7 ; Maximum PCI burst, '6' is 1024
ETTh equ 0x3F ; 0x3F means NO threshold
 
EarlyTxThld equ 0x3F ; 0x3F means NO early transmit
RxPacketMaxSize equ 0x0800 ; Maximum size supported is 16K-1
InterFrameGap equ 0x03 ; 3 means InterFrameGap = the shortest one
 
NUM_TX_DESC equ 1 ; Number of Tx descriptor registers
NUM_RX_DESC equ 4 ; Number of Rx descriptor registers
RX_BUF_SIZE equ 1536 ; Rx Buffer size
 
HZ equ 1000
 
RTL_MIN_IO_SIZE equ 0x80
TX_TIMEOUT equ (6*HZ)
 
RTL8169_TIMER_EXPIRE_TIME equ 100
 
ETH_HDR_LEN equ 14
DEFAULT_MTU equ 1500
DEFAULT_RX_BUF_LEN equ 1536
 
 
;#ifdef RTL8169_JUMBO_FRAME_SUPPORT
;#define MAX_JUMBO_FRAME_MTU ( 10000 )
;#define MAX_RX_SKBDATA_SIZE ( MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN )
;#else
MAX_RX_SKBDATA_SIZE equ 1600
;#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT
 
;#ifdef RTL8169_USE_IO
;!!!#define RTL_W8(reg, val8) outb ((val8), ioaddr + (reg))
macro RTL_W8 reg,val8 {
if ~reg eq dx
mov dx,word[rtl8169_tpc.mmio_addr]
add dx,reg
end if
if ~val8 eq al
mov al,val8
end if
out dx,al
}
;!!!#define RTL_W16(reg, val16) outw ((val16), ioaddr + (reg))
macro RTL_W16 reg,val16 {
if ~reg eq dx
mov dx,word[rtl8169_tpc.mmio_addr]
add dx,reg
end if
if ~val16 eq ax
mov ax,val16
end if
out dx,ax
}
;!!!#define RTL_W32(reg, val32) outl ((val32), ioaddr + (reg))
macro RTL_W32 reg,val32 {
if ~reg eq dx
mov dx,word[rtl8169_tpc.mmio_addr]
add dx,reg
end if
if ~val32 eq eax
mov eax,val32
end if
out dx,eax
}
;!!!#define RTL_R8(reg) inb (ioaddr + (reg))
macro RTL_R8 reg {
if ~reg eq dx
mov dx,word[rtl8169_tpc.mmio_addr]
add dx,reg
end if
in al,dx
}
;!!!#define RTL_R16(reg) inw (ioaddr + (reg))
macro RTL_R16 reg {
if ~reg eq dx
mov dx,word[rtl8169_tpc.mmio_addr]
add dx,reg
end if
in ax,dx
}
;!!!#define RTL_R32(reg) ((unsigned long) inl (ioaddr + (reg)))
macro RTL_R32 reg {
if ~reg eq dx
mov dx,word[rtl8169_tpc.mmio_addr]
add dx,reg
end if
in eax,dx
}
;#else
; write/read MMIO register
;#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg))
;#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg))
;#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg))
;#define RTL_R8(reg) readb (ioaddr + (reg))
;#define RTL_R16(reg) readw (ioaddr + (reg))
;#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg)))
;#endif
 
MCFG_METHOD_01 equ 0x01
MCFG_METHOD_02 equ 0x02
MCFG_METHOD_03 equ 0x03
MCFG_METHOD_04 equ 0x04
MCFG_METHOD_05 equ 0x05
MCFG_METHOD_11 equ 0x0b
MCFG_METHOD_12 equ 0x0c
MCFG_METHOD_13 equ 0x0d
MCFG_METHOD_14 equ 0x0e
MCFG_METHOD_15 equ 0x0f
 
PCFG_METHOD_1 equ 0x01 ; PHY Reg 0x03 bit0-3 == 0x0000
PCFG_METHOD_2 equ 0x02 ; PHY Reg 0x03 bit0-3 == 0x0001
PCFG_METHOD_3 equ 0x03 ; PHY Reg 0x03 bit0-3 == 0x0002
 
PCI_COMMAND_IO equ 0x1 ; Enable response in I/O space
PCI_COMMAND_MEM equ 0x2 ; Enable response in mem space
PCI_COMMAND_MASTER equ 0x4 ; Enable bus mastering
PCI_LATENCY_TIMER equ 0x0d ; 8 bits
PCI_COMMAND_SPECIAL equ 0x8 ; Enable response to special cycles
PCI_COMMAND_INVALIDATE equ 0x10 ; Use memory write and invalidate
PCI_COMMAND_VGA_PALETTE equ 0x20 ; Enable palette snooping
PCI_COMMAND_PARITY equ 0x40 ; Enable parity checking
PCI_COMMAND_WAIT equ 0x80 ; Enable address/data stepping
PCI_COMMAND_SERR equ 0x100 ; Enable SERR
PCI_COMMAND_FAST_BACK equ 0x200 ; Enable back-to-back writes
 
struc rtl8169_TxDesc {
.status dd ?
.vlan_tag dd ?
.buf_addr dd ?
.buf_Haddr dd ?
}
virtual at 0
rtl8169_TxDesc rtl8169_TxDesc
sizeof.rtl8169_TxDesc = $ - rtl8169_TxDesc
end virtual
 
struc rtl8169_RxDesc {
.status dd ?
.vlan_tag dd ?
.buf_addr dd ?
.buf_Haddr dd ?
}
virtual at 0
rtl8169_RxDesc rtl8169_RxDesc
sizeof.rtl8169_RxDesc = $ - rtl8169_RxDesc
end virtual
 
virtual at eth_data_start
 
; Define the TX Descriptor
align 256
rtl8169_tx_ring rb NUM_TX_DESC * sizeof.rtl8169_TxDesc
 
; Create a static buffer of size RX_BUF_SZ for each
; TX Descriptor. All descriptors point to a
; part of this buffer
align 256
rtl8169_txb rb NUM_TX_DESC * RX_BUF_SIZE
 
; Define the RX Descriptor
align 256
rtl8169_rx_ring rb NUM_RX_DESC * sizeof.rtl8169_RxDesc
 
; Create a static buffer of size RX_BUF_SZ for each
; RX Descriptor All descriptors point to a
; part of this buffer
align 256
rtl8169_rxb rb NUM_RX_DESC * RX_BUF_SIZE
 
rtl8169_tpc:
.mmio_addr dd ? ; memory map physical address
.chipset dd ?
.pcfg dd ?
.mcfg dd ?
.cur_rx dd ? ; Index into the Rx descriptor buffer of next Rx pkt
.cur_tx dd ? ; Index into the Tx descriptor buffer of next Rx pkt
.TxDescArrays dd ? ; Index of Tx Descriptor buffer
.RxDescArrays dd ? ; Index of Rx Descriptor buffer
.TxDescArray dd ? ; Index of 256-alignment Tx Descriptor buffer
.RxDescArray dd ? ; Index of 256-alignment Rx Descriptor buffer
.RxBufferRing rd NUM_RX_DESC ; Index of Rx Buffer array
.Tx_skbuff rd NUM_TX_DESC
 
end virtual
 
rtl8169_intr_mask = RTL8169_ISB_LinkChg or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxFIFOOver or RTL8169_ISB_TxErr or RTL8169_ISB_TxOK or RTL8169_ISB_RxErr or RTL8169_ISB_RxOK
rtl8169_rx_config = (RX_FIFO_THRESH shl RTL8169_RXC_FIFOShift) or (RX_DMA_BURST shl RTL8169_RXC_DMAShift) or 0x0000000E
 
iglobal
 
;static struct {
; const char *name;
; u8 mcfg; /* depend on RTL8169 docs */
; u32 RxConfigMask; /* should clear the bits supported by this chip */
;}
rtl_chip_info dd \
MCFG_METHOD_01, 0xff7e1880, \ ; RTL8169
MCFG_METHOD_02, 0xff7e1880, \ ; RTL8169s/8110s
MCFG_METHOD_03, 0xff7e1880, \ ; RTL8169s/8110s
MCFG_METHOD_04, 0xff7e1880, \ ; RTL8169sb/8110sb
MCFG_METHOD_05, 0xff7e1880, \ ; RTL8169sc/8110sc
MCFG_METHOD_11, 0xff7e1880, \ ; RTL8168b/8111b // PCI-E
MCFG_METHOD_12, 0xff7e1880, \ ; RTL8168b/8111b // PCI-E
MCFG_METHOD_13, 0xff7e1880, \ ; RTL8101e // PCI-E 8139
MCFG_METHOD_14, 0xff7e1880, \ ; RTL8100e // PCI-E 8139
MCFG_METHOD_15, 0xff7e1880 ; RTL8100e // PCI-E 8139
 
mac_info dd \
0x38800000, MCFG_METHOD_15, \
0x38000000, MCFG_METHOD_12, \
0x34000000, MCFG_METHOD_13, \
0x30800000, MCFG_METHOD_14, \
0x30000000, MCFG_METHOD_11, \
0x18000000, MCFG_METHOD_05, \
0x10000000, MCFG_METHOD_04, \
0x04000000, MCFG_METHOD_03, \
0x00800000, MCFG_METHOD_02, \
0x00000000, MCFG_METHOD_01 ; catch-all
 
endg
 
PCI_COMMAND_IO equ 0x1 ; Enable response in I/O space
PCI_COMMAND_MEM equ 0x2 ; Enable response in mem space
PCI_COMMAND_MASTER equ 0x4 ; Enable bus mastering
PCI_LATENCY_TIMER equ 0x0d ; 8 bits
PCI_COMMAND_SPECIAL equ 0x8 ; Enable response to special cycles
PCI_COMMAND_INVALIDATE equ 0x10 ; Use memory write and invalidate
PCI_COMMAND_VGA_PALETTE equ 0x20 ; Enable palette snooping
PCI_COMMAND_PARITY equ 0x40 ; Enable parity checking
PCI_COMMAND_WAIT equ 0x80 ; Enable address/data stepping
PCI_COMMAND_SERR equ 0x100 ; Enable SERR
PCI_COMMAND_FAST_BACK equ 0x200 ; Enable back-to-back writes
 
PCI_VENDOR_ID equ 0x00 ; 16 bits
PCI_DEVICE_ID equ 0x02 ; 16 bits
PCI_COMMAND equ 0x04 ; 16 bits
 
PCI_BASE_ADDRESS_0 equ 0x10 ; 32 bits
PCI_BASE_ADDRESS_1 equ 0x14 ; 32 bits
PCI_BASE_ADDRESS_2 equ 0x18 ; 32 bits
PCI_BASE_ADDRESS_3 equ 0x1c ; 32 bits
PCI_BASE_ADDRESS_4 equ 0x20 ; 32 bits
PCI_BASE_ADDRESS_5 equ 0x24 ; 32 bits
 
PCI_BASE_ADDRESS_MEM_TYPE_MASK equ 0x06
PCI_BASE_ADDRESS_MEM_TYPE_32 equ 0x00 ; 32 bit address
PCI_BASE_ADDRESS_MEM_TYPE_1M equ 0x02 ; Below 1M [obsolete]
PCI_BASE_ADDRESS_MEM_TYPE_64 equ 0x04 ; 64 bit address
 
PCI_BASE_ADDRESS_IO_MASK equ (not 0x03)
PCI_BASE_ADDRESS_MEM_MASK equ (not 0x0f)
PCI_BASE_ADDRESS_SPACE_IO equ 0x01
PCI_ROM_ADDRESS equ 0x30 ; 32 bits
 
proc CONFIG_CMD,where:byte
movzx eax,byte[pci_bus]
shl eax,8
mov al,[pci_dev]
shl eax,8
mov al,[where]
and al,not 3
or eax,0x80000000
ret
endp
 
proc pci_read_config_byte,where:dword
push edx
stdcall CONFIG_CMD,[where]
mov dx,0xCF8
out dx,eax
mov edx,[where]
and edx,3
add edx,0xCFC
in al,dx
pop edx
ret
endp
 
proc pci_read_config_word,where:dword
push edx
stdcall CONFIG_CMD,[where]
mov dx,0xCF8
out dx,eax
mov edx,[where]
and edx,2
add edx,0xCFC
in ax,dx
pop edx
ret
endp
 
proc pci_read_config_dword,where:dword
push edx
stdcall CONFIG_CMD,[where]
mov edx,0xCF8
out dx,eax
mov edx,0xCFC
in eax,dx
pop edx
ret
endp
 
proc pci_write_config_byte,where:dword,value:byte
push edx
stdcall CONFIG_CMD,[where]
mov dx,0xCF8
out dx,eax
mov edx,[where]
and edx,3
add edx,0xCFC
mov al,[value]
out dx,al
pop edx
ret
endp
 
proc pci_write_config_word,where:dword,value:word
push edx
stdcall CONFIG_CMD,[where]
mov dx,0xCF8
out dx,eax
mov edx,[where]
and edx,2
add edx,0xCFC
mov ax,[value]
out dx,ax
pop edx
ret
endp
 
proc pci_write_config_dword,where:dword,value:dword
push edx
stdcall CONFIG_CMD,[where]
mov edx,0xCF8
out dx,eax
mov edx,0xCFC
mov eax,[value]
out dx,eax
pop edx
ret
endp
 
; Set device to be a busmaster in case BIOS neglected to do so.
; Also adjust PCI latency timer to a reasonable value, 32.
proc adjust_pci_device
 
; DEBUGF 1,"K : adjust_pci_device\n"
 
stdcall pci_read_config_word,PCI_COMMAND
mov bx,ax
or bx,PCI_COMMAND_MASTER or PCI_COMMAND_IO
cmp ax,bx
je @f
; DEBUGF 1,"K : adjust_pci_device: The PCI BIOS has not enabled this device!\nK : Updating PCI command %x->%x. pci_bus %x pci_device_fn %x\n",ax,bx,[pci_bus]:2,[pci_dev]:2
stdcall pci_write_config_word,PCI_COMMAND,ebx
@@:
stdcall pci_read_config_byte,PCI_LATENCY_TIMER
cmp al,32
jae @f
; DEBUGF 1,"K : adjust_pci_device: PCI latency timer (CFLT) is unreasonably low at %d.\nK : Setting to 32 clocks.\n",al
stdcall pci_write_config_byte,PCI_LATENCY_TIMER,32
@@:
ret
endp
 
; Find the start of a pci resource
proc pci_bar_start,index:dword
stdcall pci_read_config_dword,[index]
test eax,PCI_BASE_ADDRESS_SPACE_IO
jz @f
and eax,PCI_BASE_ADDRESS_IO_MASK
jmp .exit
@@: push eax
and eax,PCI_BASE_ADDRESS_MEM_TYPE_MASK
cmp eax,PCI_BASE_ADDRESS_MEM_TYPE_64
jne .not64
mov eax,[index]
add eax,4
stdcall pci_read_config_dword,eax
or eax,eax
jz .not64
; DEBUGF 1,"K : pci_bar_start: Unhandled 64bit BAR\n"
add esp,4
or eax,-1
ret
.not64:
pop eax
and eax,PCI_BASE_ADDRESS_MEM_MASK
.exit:
ret
endp
 
proc rtl8169_init_board
 
; DEBUGF 1,"K : rtl8169_init_board\n"
 
call adjust_pci_device
 
stdcall pci_bar_start,PCI_BASE_ADDRESS_0
mov [rtl8169_tpc.mmio_addr],eax
; Soft reset the chip
RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset
 
; Check that the chip has finished the reset
mov ecx,1000
@@: RTL_R8 RTL8169_REG_ChipCmd
test al,RTL8169_CMD_Reset
jz @f
stdcall udelay,10
loop @b
@@:
; identify config method
RTL_R32 RTL8169_REG_TxConfig
and eax,0x7c800000
; DEBUGF 1,"K : rtl8169_init_board: TxConfig & 0x7c800000 = 0x%x\n",eax
mov esi,mac_info-8
@@: add esi,8
mov ecx,eax
and ecx,[esi]
cmp ecx,[esi]
jne @b
mov eax,[esi+4]
mov [rtl8169_tpc.mcfg],eax
 
mov [rtl8169_tpc.pcfg],PCFG_METHOD_3
stdcall RTL8169_READ_GMII_REG,3
and al,0x0f
or al,al
jnz @f
mov [rtl8169_tpc.pcfg],PCFG_METHOD_1
jmp .pconf
@@: dec al
jnz .pconf
mov [rtl8169_tpc.pcfg],PCFG_METHOD_2
.pconf:
 
; identify chip attached to board
mov ecx,10
mov eax,[rtl8169_tpc.mcfg]
@@: dec ecx
js @f
cmp eax,[rtl_chip_info+ecx*8]
jne @b
mov [rtl8169_tpc.chipset],ecx
jmp .match
@@:
; if unknown chip, assume array element #0, original RTL-8169 in this case
; DEBUGF 1,"K : rtl8169_init_board: PCI device: unknown chip version, assuming RTL-8169\n"
RTL_R32 RTL8169_REG_TxConfig
; DEBUGF 1,"K : rtl8169_init_board: PCI device: TxConfig = 0x%x\n",eax
 
mov [rtl8169_tpc.chipset],0
 
xor eax,eax
inc eax
ret
 
.match:
xor eax,eax
ret
endp
 
proc rtl8169_hw_PHY_config
 
; DEBUGF 1,"K : rtl8169_hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[rtl8169_tpc.mcfg],[rtl8169_tpc.pcfg]
 
; DBG_PRINT("priv->mcfg=%d, priv->pcfg=%d\n", tpc->mcfg, tpc->pcfg);
 
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_04
jne .not_4
; stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001
; stdcall RTL8169_WRITE_GMII_REG,0x1b,0x841e
; stdcall RTL8169_WRITE_GMII_REG,0x0e,0x7bfb
; stdcall RTL8169_WRITE_GMII_REG,0x09,0x273a
stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0002
stdcall RTL8169_WRITE_GMII_REG,0x01,0x90D0
stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000
jmp .exit
.not_4:
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02
je @f
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03
jne .not_2_or_3
@@: stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001
stdcall RTL8169_WRITE_GMII_REG,0x15,0x1000
stdcall RTL8169_WRITE_GMII_REG,0x18,0x65C7
stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000
stdcall RTL8169_WRITE_GMII_REG,0x03,0x00A1
stdcall RTL8169_WRITE_GMII_REG,0x02,0x0008
stdcall RTL8169_WRITE_GMII_REG,0x01,0x1020
stdcall RTL8169_WRITE_GMII_REG,0x00,0x1000
stdcall RTL8169_WRITE_GMII_REG,0x04,0x0800
stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000
stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000
stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41
stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE60
stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140
stdcall RTL8169_WRITE_GMII_REG,0x00,0x0077
stdcall RTL8169_WRITE_GMII_REG,0x04,0x7800
stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000
stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000
stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01
stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20
stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95
stdcall RTL8169_WRITE_GMII_REG,0x00,0xFA00
stdcall RTL8169_WRITE_GMII_REG,0x04,0xA800
stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000
stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000
stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41
stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE20
stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140
stdcall RTL8169_WRITE_GMII_REG,0x00,0x00BB
stdcall RTL8169_WRITE_GMII_REG,0x04,0xB800
stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000
stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000
stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01
stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20
stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95
stdcall RTL8169_WRITE_GMII_REG,0x00,0xBF00
stdcall RTL8169_WRITE_GMII_REG,0x04,0xF800
stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000
stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000
stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000
stdcall RTL8169_WRITE_GMII_REG,0x0B,0x0000
jmp .exit
.not_2_or_3:
; DBG_PRINT("tpc->mcfg=%d. Discard hw PHY config.\n", tpc->mcfg);
; DEBUGF 1,"K : tpc.mcfg=%d, discard hw PHY config\n",[rtl8169_tpc.mcfg]
.exit:
ret
endp
 
;proc pci_write_config_byte
; ret
;endp
 
proc RTL8169_WRITE_GMII_REG,RegAddr:byte,value:dword
 
;;; DEBUGF 1,"K : RTL8169_WRITE_GMII_REG: 0x%x 0x%x\n",[RegAddr]:2,[value]
 
movzx eax,[RegAddr]
shl eax,16
or eax,[value]
or eax,0x80000000
RTL_W32 RTL8169_REG_PHYAR,eax
stdcall udelay,1 ;;;1000
 
mov ecx,2000
; Check if the RTL8169 has completed writing to the specified MII register
@@: RTL_R32 RTL8169_REG_PHYAR
test eax,0x80000000
jz .exit
stdcall udelay,1 ;;;100
loop @b
.exit:
ret
endp
 
proc RTL8169_READ_GMII_REG,RegAddr:byte
 
;;; DEBUGF 1,"K : RTL8169_READ_GMII_REG: 0x%x\n",[RegAddr]:2
 
push ecx
movzx eax,[RegAddr]
shl eax,16
; or eax,0x0
RTL_W32 RTL8169_REG_PHYAR,eax
stdcall udelay,1 ;;;1000
 
mov ecx,2000
; Check if the RTL8169 has completed retrieving data from the specified MII register
@@: RTL_R32 RTL8169_REG_PHYAR
test eax,0x80000000
jnz .exit
stdcall udelay,1 ;;;100
loop @b
 
or eax,-1
pop ecx
ret
.exit:
RTL_R32 RTL8169_REG_PHYAR
and eax,0xFFFF
pop ecx
ret
endp
 
proc rtl8169_set_rx_mode
 
; DEBUGF 1,"K : rtl8169_set_rx_mode\n"
 
; IFF_ALLMULTI
; Too many to filter perfectly -- accept all multicasts
RTL_R32 RTL8169_REG_RxConfig
mov ecx,[rtl8169_tpc.chipset]
and eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
or eax,rtl8169_rx_config or (RTL8169_RXM_AcceptBroadcast or RTL8169_RXM_AcceptMulticast or RTL8169_RXM_AcceptMyPhys)
RTL_W32 RTL8169_REG_RxConfig,eax
 
; Multicast hash filter
RTL_W32 RTL8169_REG_MAR0 + 0,0xffffffff
RTL_W32 RTL8169_REG_MAR0 + 4,0xffffffff
ret
endp
 
proc rtl8169_init_ring
 
; DEBUGF 1,"K : rtl8169_init_ring\n"
 
xor eax,eax
mov [rtl8169_tpc.cur_rx],eax
mov [rtl8169_tpc.cur_tx],eax
 
mov edi,[rtl8169_tpc.TxDescArray]
mov ecx,(NUM_TX_DESC * sizeof.rtl8169_TxDesc) / 4
cld
rep stosd
mov edi,[rtl8169_tpc.RxDescArray]
mov ecx,(NUM_RX_DESC * sizeof.rtl8169_RxDesc) / 4
rep stosd
 
mov edi,rtl8169_tpc.Tx_skbuff
mov eax,rtl8169_txb
mov ecx,NUM_TX_DESC
@@: stosd
inc eax ; add eax,RX_BUF_SIZE ???
loop @b
 
;!!! for (i = 0; i < NUM_RX_DESC; i++) {
;!!! if (i == (NUM_RX_DESC - 1))
;!!! tpc->RxDescArray[i].status = (OWNbit | EORbit) | RX_BUF_SIZE;
;!!! else
;!!! tpc->RxDescArray[i].status = OWNbit | RX_BUF_SIZE;
;!!! tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
;!!! tpc->RxDescArray[i].buf_addr = virt_to_bus(tpc->RxBufferRing[i]);
;!!! }
mov esi,rtl8169_tpc.RxBufferRing
mov edi,[rtl8169_tpc.RxDescArray]
mov eax,rtl8169_rxb
mov ecx,NUM_RX_DESC
@@: mov [esi],eax
mov [edi+rtl8169_RxDesc.buf_addr],eax
sub [edi+rtl8169_RxDesc.buf_addr],OS_BASE ; shurf 28.09.2008
mov [edi+rtl8169_RxDesc.status],RTL8169_DSB_OWNbit or RX_BUF_SIZE
add esi,4
add edi,sizeof.rtl8169_RxDesc
add eax,RX_BUF_SIZE
loop @b
 
or [edi - sizeof.rtl8169_RxDesc + rtl8169_RxDesc.status],RTL8169_DSB_EORbit
 
ret
endp
 
proc rtl8169_hw_start
 
; DEBUGF 1,"K : rtl8169_hw_start\n"
 
; Soft reset the chip
RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset
; Check that the chip has finished the reset
mov ecx,1000
@@: RTL_R8 RTL8169_REG_ChipCmd
and al,RTL8169_CMD_Reset
jz @f
stdcall udelay,10
loop @b
@@:
RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Unlock
RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_TxEnb or RTL8169_CMD_RxEnb
RTL_W8 RTL8169_REG_ETThReg,ETTh
; For gigabit rtl8169
RTL_W16 RTL8169_REG_RxMaxSize,RxPacketMaxSize
; Set Rx Config register
RTL_R32 RTL8169_REG_RxConfig
mov ecx,[rtl8169_tpc.chipset]
and eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask
or eax,rtl8169_rx_config
RTL_W32 RTL8169_REG_RxConfig,eax
; Set DMA burst size and Interframe Gap Time
RTL_W32 RTL8169_REG_TxConfig,(TX_DMA_BURST shl RTL8169_TXC_DMAShift) or (InterFrameGap shl RTL8169_TXC_InterFrameGapShift)
RTL_R16 RTL8169_REG_CPlusCmd
RTL_W16 RTL8169_REG_CPlusCmd,ax
 
RTL_R16 RTL8169_REG_CPlusCmd
or ax,1 shl 3
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02
jne @f
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03
jne @f
or ax,1 shl 14
; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n"
jmp .set
@@:;DEBUGF 1,"K : Set MAC Reg C+CR Offset 0xE0: bit-3\n"
.set: RTL_W16 RTL8169_REG_CPlusCmd,ax
 
; RTL_W16 0xE2,0x1517
; RTL_W16 0xE2,0x152a
; RTL_W16 0xE2,0x282a
RTL_W16 0xE2,0x0000
 
MOV [rtl8169_tpc.cur_rx],0
push eax ; shurf 28.09.2008
mov eax, [rtl8169_tpc.TxDescArray] ; shurf 28.09.2008
sub eax, OS_BASE ; shurf 28.09.2008
RTL_W32 RTL8169_REG_TxDescStartAddr,eax ;[rtl8169_tpc.TxDescArray] ; shurf 28.09.2008
mov eax, [rtl8169_tpc.RxDescArray] ; shurf 28.09.2008
sub eax, OS_BASE ; shurf 28.09.2008
RTL_W32 RTL8169_REG_RxDescStartAddr,eax ;[rtl8169_tpc.RxDescArray] ; shurf 28.09.2008
pop eax ; shurf 28.09.2008
RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Lock
stdcall udelay,10
RTL_W32 RTL8169_REG_RxMissed,0
call rtl8169_set_rx_mode
; no early-rx interrupts
RTL_R16 RTL8169_REG_MultiIntr
and ax,0xF000
RTL_W16 RTL8169_REG_MultiIntr,ax
RTL_W16 RTL8169_REG_IntrMask,0 ; rtl8169_intr_mask
ret
endp
 
proc udelay,msec:dword
push esi
mov esi,[msec]
call delay_ms
pop esi
ret
endp
 
;***************************************************************************
; Function
; rtl8169_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
; Destroyed registers
; eax, ebx, ecx, edx
;
;***************************************************************************
proc rtl8169_probe
 
; DEBUGF 1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
 
call rtl8169_init_board
 
mov ecx,MAC_ADDR_LEN
mov edx,[rtl8169_tpc.mmio_addr]
add edx,RTL8169_REG_MAC0
xor ebx,ebx
; Get MAC address. FIXME: read EEPROM
@@: RTL_R8 dx
mov [node_addr+ebx],al
inc edx
inc ebx
loop @b
 
; DEBUGF 1,"K : rtl8169_probe: MAC = %x-%x-%x-%x-%x-%x\n",[node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2
 
; Config PHY
stdcall rtl8169_hw_PHY_config
; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
RTL_W8 0x82,0x01
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03
jae @f
; DEBUGF 1,"K : Set PCI Latency=0x40\n"
; stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40
@@:
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02
jne @f
; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0x82h = 0x01h\n"
RTL_W8 0x82,0x01
; DEBUGF 1,"K : Set PHY Reg 0x0bh = 0x00h\n"
stdcall RTL8169_WRITE_GMII_REG,0x0b,0x0000 ; w 0x0b 15 0 0
@@:
; if TBI is not enabled
RTL_R8 RTL8169_REG_PHYstatus
test al,RTL8169_PHYS_TBI_Enable
jz .tbi_dis
stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG
; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
and eax,0x0C1F
or eax,RTL8169_PHY_Cap_10_Half or RTL8169_PHY_Cap_10_Full or RTL8169_PHY_Cap_100_Half or RTL8169_PHY_Cap_100_Full
stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG,eax
; enable 1000 Full Mode
stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_1000_CTRL_REG,RTL8169_PHY_Cap_1000_Full or RTL8169_PHY_Cap_1000_Half ; rtl8168
; Enable auto-negotiation and restart auto-nigotiation
stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_CTRL_REG,RTL8169_PHY_Enable_Auto_Nego or RTL8169_PHY_Restart_Auto_Nego
stdcall udelay,100
mov ecx,10000
; wait for auto-negotiation process
@@: dec ecx
jz @f
stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_STAT_REG
stdcall udelay,100
test eax,RTL8169_PHY_Auto_Neco_Comp
jz @b
RTL_R8 RTL8169_REG_PHYstatus
jmp @f
.tbi_dis:
stdcall udelay,100
@@:
call rtl8169_reset
ret
endp
 
;***************************************************************************
; Function
; rt8169_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; Destroyed registers
; eax, ebx, ecx, edx
;
;***************************************************************************
proc rtl8169_reset
 
; DEBUGF 1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2
 
mov [rtl8169_tpc.TxDescArrays],rtl8169_tx_ring
; Tx Desscriptor needs 256 bytes alignment
mov [rtl8169_tpc.TxDescArray],rtl8169_tx_ring
 
mov [rtl8169_tpc.RxDescArrays],rtl8169_rx_ring
; Rx Desscriptor needs 256 bytes alignment
mov [rtl8169_tpc.RxDescArray],rtl8169_rx_ring
 
call rtl8169_init_ring
call rtl8169_hw_start
; Construct a perfect filter frame with the mac address as first match
; and broadcast for all others
mov edi,rtl8169_txb
or al,-1
mov ecx,192
cld
rep stosb
 
mov esi,node_addr
mov edi,rtl8169_txb
movsd
movsw
 
mov eax,[pci_data]
mov [eth_status],eax
ret
endp
 
;***************************************************************************
; Function
; rtl8169_transmit
; Description
; Transmits a packet of data via the ethernet card
; d - edi - Pointer to 48 bit destination address
; t - bx - Type of packet
; s - ecx - size of packet
; p - esi - pointer to packet data
; Destroyed registers
; eax, edx, esi, edi
;
;***************************************************************************
proc rtl8169_transmit
 
; DEBUGF 1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi
 
push ecx edx esi
mov eax,MAX_ETH_FRAME_SIZE
mul [rtl8169_tpc.cur_tx]
mov esi,edi
; point to the current txb incase multiple tx_rings are used
mov edi,[rtl8169_tpc.Tx_skbuff + eax * 4]
mov eax,edi
cld
; copy destination address
movsd
movsw
; copy source address
mov esi,node_addr
movsd
movsw
; copy packet type
mov [edi],bx
add edi,2
; copy the packet data
pop esi edx ecx
push ecx
shr ecx,2
rep movsd
pop ecx
push ecx
and ecx,3
rep movsb
 
;!!! s += ETH_HLEN;
;!!! s &= 0x0FFF;
;!!! while (s < ETH_ZLEN)
;!!! ptxb[s++] = '\0';
mov edi,eax
pop ecx
push eax
add ecx,ETH_HLEN
and ecx,0x0FFF
xor al,al
add edi,ecx
@@: cmp ecx,ETH_ZLEN
jae @f
stosb
inc ecx
jmp @b
@@: pop eax
 
mov ebx,eax
mov eax,sizeof.rtl8169_TxDesc
mul [rtl8169_tpc.cur_tx]
add eax,[rtl8169_tpc.TxDescArray]
xchg eax,ebx
mov [ebx + rtl8169_TxDesc.buf_addr],eax
sub [ebx + rtl8169_TxDesc.buf_addr],OS_BASE ; shurf 28.09.2008
 
mov eax,ecx
cmp eax,ETH_ZLEN
jae @f
mov eax,ETH_ZLEN
@@: or eax,RTL8169_DSB_OWNbit or RTL8169_DSB_FSbit or RTL8169_DSB_LSbit
cmp [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1
jne @f
or eax,RTL8169_DSB_EORbit
@@: mov [ebx + rtl8169_TxDesc.status],eax
 
RTL_W8 RTL8169_REG_TxPoll,0x40 ; set polling bit
 
inc [rtl8169_tpc.cur_tx]
and [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1
 
;!!! to = currticks() + TX_TIMEOUT;
;!!! while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to)); /* wait */
mov ecx,TX_TIMEOUT / 10
@@: test [ebx + rtl8169_TxDesc.status],RTL8169_DSB_OWNbit
jnz @f
stdcall udelay,10
loop @b
; DEBUGF 1,"K : rtl8169_transmit: TX Time Out\n"
@@:
 
ret
endp
 
;***************************************************************************
; Function
; rtl8169_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
; Destroyed register(s)
; eax, edx, ecx
;
;***************************************************************************
proc rtl8169_poll
 
; DEBUGF 1,"K : rtl8169_poll\n" ;: 0x%x : none\n",[io_addr]:8
 
mov word[eth_rx_data_len],0
 
mov eax,sizeof.rtl8169_RxDesc
mul [rtl8169_tpc.cur_rx]
add eax,[rtl8169_tpc.RxDescArray]
mov ebx,eax
 
; DEBUGF 1,"K : rtl8169_RxDesc.status = 0x%x\n",[ebx + rtl8169_RxDesc.status]
 
test [ebx + rtl8169_RxDesc.status],RTL8169_DSB_OWNbit ; 0x80000600
jnz .exit
 
; DEBUGF 1,"K : rtl8169_tpc.cur_rx = %u\n",[rtl8169_tpc.cur_rx]
 
; h/w no longer present (hotplug?) or major error, bail
RTL_R16 RTL8169_REG_IntrStatus
 
; DEBUGF 1,"K : IntrStatus = 0x%x\n",ax
 
cmp ax,0xFFFF
je .exit
 
push eax
and ax,not (RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK)
RTL_W16 RTL8169_REG_IntrStatus,ax
 
mov eax,[ebx + rtl8169_RxDesc.status]
 
; DEBUGF 1,"K : RxDesc.status = 0x%x\n",eax
 
test eax,RTL8169_SD_RxRES
jnz .else
and eax,0x00001FFF
; jz .exit.pop
add eax,-4
mov [eth_rx_data_len],ax
 
; DEBUGF 1,"K : rtl8169_poll: data length = %u\n",ax
 
push eax
mov ecx,eax
shr ecx,2
mov eax,[rtl8169_tpc.cur_rx]
mov edx,[rtl8169_tpc.RxBufferRing + eax * 4]
mov esi,edx
mov edi,Ether_buffer
cld
rep movsd
pop ecx
and ecx,3
rep movsb
 
mov eax,RTL8169_DSB_OWNbit or RX_BUF_SIZE
cmp [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1
jne @f
or eax,RTL8169_DSB_EORbit
@@: mov [ebx + rtl8169_RxDesc.status],eax
 
mov [ebx + rtl8169_RxDesc.buf_addr],edx
sub [ebx + rtl8169_RxDesc.buf_addr],OS_BASE ; shurf 28.09.2008
jmp @f
.else:
; DEBUGF 1,"K : rtl8169_poll: Rx Error\n"
; FIXME: shouldn't I reset the status on an error
@@:
inc [rtl8169_tpc.cur_rx]
and [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1
.exit.pop:
pop eax
and ax,RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK
RTL_W16 RTL8169_REG_IntrStatus,ax
.exit:
ret
endp
 
proc rtl8169_cable
ret
endp
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/eth_drv/drivers/i8255x.inc
0,0 → 1,760
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; I8255X.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.3 11 August 2003 ;;
;; ;;
;; This driver is based on the eepro100 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2002 Mike Hibbett, ;;
;; mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;********************************************************************
; Interface
; I8255x_reset
; I8255x_probe
; I8255x_poll
; I8255x_transmit
;
; These functions are referenced in ethernet.inc
;
;********************************************************************
 
 
rxfd_status equ eth_data_start
rxfd_command equ eth_data_start + 2
rxfd_link equ eth_data_start + 4
rxfd_rx_buf_addr equ eth_data_start + 8
rxfd_count equ eth_data_start + 12
rxfd_size equ eth_data_start + 14
rxfd_packet equ eth_data_start + 16
 
 
 
uglobal
eeprom_data: times 16 dd 0
 
align 4
 
lstats:
tx_good_frames: dd 0
tx_coll16_errs: dd 0
tx_late_colls: dd 0
tx_underruns: dd 0
tx_lost_carrier: dd 0
tx_deferred: dd 0
tx_one_colls: dd 0
tx_multi_colls: dd 0
tx_total_colls: dd 0
rx_good_frames: dd 0
rx_crc_errs: dd 0
rx_align_errs: dd 0
rx_resource_errs: dd 0
rx_overrun_errs: dd 0
rx_colls_errs: dd 0
rx_runt_errs: dd 0
done_marker: dd 0
 
align 4
 
confcmd:
confcmd_status: dw 0
confcmd_command: dw 0
confcmd_link: dd 0
endg
 
iglobal
confcmd_data: db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1
db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2
db 0x80, 0x3f, 0x05
endg
 
uglobal
align 4
 
txfd:
txfd_status: dw 0
txfd_command: dw 0
txfd_link: dd 0
txfd_tx_desc_addr: dd 0
txfd_count: dd 0
txfd_tx_buf_addr0: dd 0
txfd_tx_buf_size0: dd 0
txfd_tx_buf_addr1: dd 0
txfd_tx_buf_size1: dd 0
 
align 4
 
hdr:
hdr_dst_addr: times 6 db 0
hdr_src_addr: times 6 db 0
hdr_type: dw 0
endg
 
 
;***************************************************************************
; Function
; wait_for_cmd_done
;
; Description
; waits for the hardware to complete a command
; port address in edx
;
; al destroyed
;***************************************************************************
wait_for_cmd_done:
in al, dx
cmp al, 0
jne wait_for_cmd_done
ret
 
 
 
;***************************************************************************
; Function
; mdio_read
;
; Description
; This probably reads a register in the "physical media interface chip"
; Phy_id in ebx
; location in ecx
;
; Data returned in eax
;
;***************************************************************************
mdio_read:
mov edx, [io_addr]
add edx, 16 ; SCBCtrlMDI
 
mov eax, 0x08000000
shl ecx, 16
or eax, ecx
shl ebx, 21
or eax, ebx
 
out dx, eax
 
mrlp:
call delay_us
in eax, dx
mov ecx, eax
and ecx, 0x10000000
jz mrlp
 
and eax, 0xffff
ret
 
 
 
;***************************************************************************
; Function
; mdio_write
;
; Description
; This probably writes a register in the "physical media interface chip"
; Phy_id in ebx
; location in ecx
; data in edx
; Data returned in eax
;
;***************************************************************************
mdio_write:
mov eax, 0x04000000
shl ecx, 16
or eax, ecx
shl ebx, 21
or eax, ebx
or eax, edx
 
mov edx, [io_addr]
add edx, 16 ; SCBCtrlMDI
out dx, eax
 
mwlp:
call delay_us
in eax, dx
mov ecx, eax
and ecx, 0x10000000
jz mwlp
 
and eax, 0xffff
ret
 
 
 
;/***********************************************************************/
;/* I82557 related defines */
;/***********************************************************************/
 
; Serial EEPROM section.
; A "bit" grungy, but we work our way through bit-by-bit :->.
; EEPROM_Ctrl bits.
EE_SHIFT_CLK equ 0x01 ; EEPROM shift clock.
EE_CS equ 0x02 ; EEPROM chip select.
EE_DATA_WRITE equ 0x04 ; EEPROM chip data in.
EE_DATA_READ equ 0x08 ; EEPROM chip data out.
EE_WRITE_0 equ 0x4802
EE_WRITE_1 equ 0x4806
EE_ENB equ 0x4802
 
 
; The EEPROM commands include the alway-set leading bit.
EE_READ_CMD equ 6
 
; The SCB accepts the following controls for the Tx and Rx units:
CU_START equ 0x0010
CU_RESUME equ 0x0020
CU_STATSADDR equ 0x0040
CU_SHOWSTATS equ 0x0050 ; Dump statistics counters.
CU_CMD_BASE equ 0x0060 ; Base address to add to add CU commands.
CU_DUMPSTATS equ 0x0070 ; Dump then reset stats counters.
 
RX_START equ 0x0001
RX_RESUME equ 0x0002
RX_ABORT equ 0x0004
RX_ADDR_LOAD equ 0x0006
RX_RESUMENR equ 0x0007
INT_MASK equ 0x0100
DRVR_INT equ 0x0200 ; Driver generated interrupt.
 
 
;***************************************************************************
; Function
; do_eeprom_cmd
;
; Description
; writes a cmd to the ethernet cards eeprom, by bit bashing
; cmd in ebx
; cmd length in ecx
; return in eax
;***************************************************************************
do_eeprom_cmd:
mov edx, [io_addr] ; We only require the value in dx
add dx, 14 ; the value SCBeeprom
 
mov ax, EE_ENB
out dx, ax
call delay_us
 
mov ax, 0x4803 ; EE_ENB | EE_SHIFT_CLK
out dx, ax
call delay_us
 
; dx holds ee_addr
; ecx holds count
; eax holds cmd
xor edi, edi ; this will be the receive data
 
dec_001:
mov esi, 1
 
dec ecx
shl esi, cl
inc ecx
and esi, ebx
mov eax, EE_WRITE_0 ; I am assuming this doesnt affect the flags..
cmp esi,0
jz dec_002
mov eax, EE_WRITE_1
 
dec_002:
out dx, ax
call delay_us
 
or ax, EE_SHIFT_CLK
out dx, ax
call delay_us
 
shl edi,1
 
in ax, dx
and ax, EE_DATA_READ
cmp ax,0
jz dec_003
inc edi
 
dec_003:
loop dec_001
 
mov ax, EE_ENB
out dx, ax
call delay_us
 
mov ax, 0x4800
out dx, ax
call delay_us
 
mov eax, edi
 
ret
 
 
;***************************************************************************
; Function
; I8255x_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
;
;***************************************************************************
I8255x_probe:
DEBUGF 1," K : Probing i8255x device \n"
mov eax, [io_addr]
 
mov ebx, [pci_bus]
mov ecx, [pci_dev]
mov edx, 0x04 ; PCI_COMMAND
call pcibios_read_config_word
 
or ax, 0x05
mov ebx, [pci_bus]
mov ecx, [pci_dev]
mov edx, 0x04 ; PCI_COMMAND
call pcibios_write_config_word
 
mov ebx, 0x6000000
mov ecx, 27
call do_eeprom_cmd
and eax, 0xffe0000
cmp eax, 0xffe0000
je bige
 
mov ebx, 0x1800000
mov ecx, 0x40
jmp doread
 
bige:
mov ebx, 0x6000000
mov ecx, 0x100
 
doread:
; do-eeprom-cmd will destroy all registers
; we have eesize in ecx
; read_cmd in ebx
 
; Ignore full eeprom - just load the mac address
mov ecx, 0
 
drlp:
push ecx ; save count
push ebx
mov eax, ecx
shl eax, 16
or ebx, eax
mov ecx, 27
call do_eeprom_cmd
 
pop ebx
pop ecx
 
mov edx, ecx
shl edx, 2
mov esi, eeprom_data
add esi, edx
mov [esi], eax
 
inc ecx
cmp ecx, 16
jne drlp
 
; OK, we have the MAC address.
; Now reset the card
 
mov edx, [io_addr]
add dx, 8 ; SCBPort
xor eax, eax ; The reset cmd == 0
out dx, eax
 
mov esi, 10
call delay_ms ; Give the card time to warm up.
 
mov eax, lstats
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
 
mov eax, 0x0140 ; INT_MASK | CU_STATSADDR
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
 
call wait_for_cmd_done
 
mov eax, 0
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
 
mov eax, 0x0106 ; INT_MASK | RX_ADDR_LOAD
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
 
call wait_for_cmd_done
 
; build rxrd structure
mov ax, 0x0001
mov [rxfd_status], ax
mov ax, 0x0000
mov [rxfd_command], ax
 
mov eax, rxfd_status
sub eax, OS_BASE
mov [rxfd_link], eax
 
mov eax, Ether_buffer
sub eax, OS_BASE
mov [rxfd_rx_buf_addr], eax
 
mov ax, 0
mov [rxfd_count], ax
 
mov ax, 1528
mov [rxfd_size], ax
 
mov edx, [io_addr]
add edx, 4 ; SCBPointer
 
mov eax, rxfd_status
sub eax, OS_BASE
out dx, eax
 
mov edx, [io_addr]
add edx, 2 ; SCBCmd
 
mov ax, 0x0101 ; INT_MASK | RX_START
out dx, ax
 
call wait_for_cmd_done
 
; start the reciver
 
mov ax, 0
mov [rxfd_status], ax
 
mov ax, 0xc000
mov [rxfd_command], ax
 
mov edx, [io_addr]
add edx, 4 ; SCBPointer
 
mov eax, rxfd_status
sub eax, OS_BASE
out dx, eax
 
mov edx, [io_addr]
add edx, 2 ; SCBCmd
 
mov ax, 0x0101 ; INT_MASK | RX_START
out dx, ax
 
; Init TX Stuff
 
mov edx, [io_addr]
add edx, 4 ; SCBPointer
 
mov eax, 0
out dx, eax
 
mov edx, [io_addr]
add edx, 2 ; SCBCmd
 
mov ax, 0x0160 ; INT_MASK | CU_CMD_BASE
out dx, ax
 
call wait_for_cmd_done
 
; Set TX Base address
 
; First, set up confcmd values
 
mov ax, 2
mov [confcmd_command], ax
mov eax, txfd
sub eax, OS_BASE
mov [confcmd_link], eax
 
mov ax, 1
mov [txfd_command], ax ; CmdIASetup
 
mov ax, 0
mov [txfd_status], ax
 
mov eax, confcmd
sub eax, OS_BASE
mov [txfd_link], eax
 
 
 
; ETH_ALEN is 6 bytes
 
mov esi, eeprom_data
mov edi, node_addr
mov ecx, 3
drp000:
mov eax, [esi]
mov [edi], al
shr eax, 8
inc edi
mov [edi], al
inc edi
add esi, 4
loop drp000
 
; Hard code your MAC address into node_addr at this point,
; If you cannot read the MAC address from the eeprom in the previous step.
; You also have to write the mac address into txfd_tx_desc_addr, rather
; than taking data from eeprom_data
 
mov esi, eeprom_data
mov edi, txfd_tx_desc_addr
mov ecx, 3
drp001:
mov eax, [esi]
mov [edi], al
shr eax, 8
inc edi
mov [edi], al
inc edi
add esi, 4
loop drp001
 
 
mov esi, eeprom_data + (6 * 4)
mov eax, [esi]
shr eax, 8
and eax, 0x3f
cmp eax, 4 ; DP83840
je drp002
cmp eax, 10 ; DP83840A
je drp002
jmp drp003
 
drp002:
mov ebx, [esi]
and ebx, 0x1f
push ebx
mov ecx, 23
call mdio_read
pop ebx
or eax, 0x0422
mov ecx, 23
mov edx, eax
call mdio_write
 
drp003:
mov ax, 0x4002 ; Cmdsuspend | CmdConfigure
mov [confcmd_command], ax
mov ax, 0
mov [confcmd_status], ax
mov eax, txfd
mov [confcmd_link], eax
mov ebx, confcmd_data
mov al, 0x88 ; fifo of 8 each
mov [ebx + 1], al
mov al, 0
mov [ebx + 4], al
mov al, 0x80
mov [ebx + 5], al
mov al, 0x48
mov [ebx + 15], al
mov al, 0x80
mov [ebx + 19], al
mov al, 0x05
mov [ebx + 21], al
 
mov eax, txfd
sub eax, OS_BASE
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
 
mov eax, 0x0110 ; INT_MASK | CU_START
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
 
call wait_for_cmd_done
jmp skip
 
; wait for thing to start
drp004:
mov ax, [txfd_status]
cmp ax, 0
je drp004
 
skip:
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
 
I8255x_exit:
ret
 
 
 
;***************************************************************************
; Function
; I8255x_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; No inputs
; All registers destroyed
;
;***************************************************************************
I8255x_reset:
ret
 
 
 
;***************************************************************************
; Function
; I8255x_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
;
;***************************************************************************
I8255x_poll:
mov ax, 0 ; assume no data
mov [eth_rx_data_len], ax
 
mov ax, [rxfd_status]
cmp ax, 0
je i8p_exit
 
mov ax, 0
mov [rxfd_status], ax
 
mov ax, 0xc000
mov [rxfd_command], ax
 
mov edx, [io_addr]
add edx, 4 ; SCBPointer
 
mov eax, rxfd_status
sub eax, OS_BASE
out dx, eax
 
mov edx, [io_addr]
add edx, 2 ; SCBCmd
 
mov ax, 0x0101 ; INT_MASK | RX_START
out dx, ax
 
call wait_for_cmd_done
 
mov esi, rxfd_packet
mov edi, Ether_buffer
mov ecx, 1518
cld
rep movsb
 
mov ax, [rxfd_count]
and ax, 0x3fff
mov [eth_rx_data_len], ax
 
i8p_exit:
ret
 
 
 
;***************************************************************************
; Function
; I8255x_transmit
;
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
;
;***************************************************************************
I8255x_transmit:
 
mov [hdr_type], bx
 
mov eax, [edi]
mov [hdr_dst_addr], eax
mov ax, [edi+4]
mov [hdr_dst_addr+4], ax
 
mov eax, [node_addr]
mov [hdr_src_addr], eax
mov ax, [node_addr+4]
mov [hdr_src_addr+4], ax
 
mov edx, [io_addr]
in ax, dx
and ax, 0xfc00
out dx, ax
 
xor ax, ax
mov [txfd_status], ax
mov ax, 0x400C ; Cmdsuspend | CmdTx | CmdTxFlex
mov [txfd_command], ax
mov eax, txfd
mov [txfd_link], eax
mov eax, 0x02208000
mov [txfd_count], eax
mov eax, txfd_tx_buf_addr0
sub eax, OS_BASE
mov [txfd_tx_desc_addr], eax
mov eax, hdr
sub eax, OS_BASE
mov [txfd_tx_buf_addr0], eax
mov eax, 14 ; sizeof hdr
mov [txfd_tx_buf_size0], eax
 
; Copy the buffer address and size in
mov eax, esi
sub eax, OS_BASE
mov [txfd_tx_buf_addr1], eax
mov eax, ecx
mov [txfd_tx_buf_size1], eax
 
mov eax, txfd
sub eax, OS_BASE
mov edx, [io_addr]
add edx, 4 ; SCBPointer
out dx, eax
 
mov ax, 0x0110 ; INT_MASK | CU_START
mov edx, [io_addr]
add edx, 2 ; SCBCmd
out dx, ax
 
call wait_for_cmd_done
 
mov edx, [io_addr]
in ax, dx
 
I8t_001:
mov ax, [txfd_status]
cmp ax, 0
je I8t_001
 
mov edx, [io_addr]
in ax, dx
 
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/eth_drv/drivers/pcnet32.inc
0,0 → 1,848
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; PCNET32.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; - Version 1.0 31 July 2004: ;;
;; Initial release ;;
;; ;;
;; - Version 1.01 29 March 2008: ;;
;; Adapted to work with kolibrios flat kernel ;;
;; Debug info is updated, and now uses DEBUGF macro ;;
;; by hidnplayr@kolibrios.org ;;
;; ;;
;; This driver is based on the PCNet32 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2004 Jarek Pelczar, ;;
;; jpelczar@interia.pl ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
PCNET32_PORT_AUI equ 0x00
PCNET32_PORT_10BT equ 0x01
PCNET32_PORT_GPSI equ 0x02
PCNET32_PORT_MII equ 0x03
PCNET32_PORT_PORTSEL equ 0x03
PCNET32_PORT_ASEL equ 0x04
PCNET32_PORT_100 equ 0x40
PCNET32_PORT_FD equ 0x80
PCNET32_DMA_MASK equ 0xffffffff
 
PCNET32_LOG_TX_BUFFERS equ 1
PCNET32_LOG_RX_BUFFERS equ 2
 
PCNET32_TX_RING_SIZE equ (1 shl PCNET32_LOG_TX_BUFFERS)
PCNET32_TX_RING_MOD_MASK equ (PCNET32_TX_RING_SIZE-1)
PCNET32_TX_RING_LEN_BITS equ 0
PCNET32_RX_RING_SIZE equ (1 shl PCNET32_LOG_RX_BUFFERS)
PCNET32_RX_RING_MOD_MASK equ (PCNET32_RX_RING_SIZE-1)
PCNET32_RX_RING_LEN_BITS equ (PCNET32_LOG_RX_BUFFERS shl 4)
PCNET32_PKT_BUF_SZ equ 1544
PCNET32_PKT_BUF_SZ_NEG equ 0xf9f8
 
pcnet32_txb equ (eth_data_start)
pcnet32_rxb equ ((pcnet32_txb+(PCNET32_PKT_BUF_SZ*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_tx_ring equ ((pcnet32_rxb+(PCNET32_PKT_BUF_SZ*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_rx_ring equ ((pcnet32_tx_ring+(16*PCNET32_TX_RING_SIZE)+0xf) and 0xfffffff0)
 
virtual at ((pcnet32_rx_ring+(16*PCNET32_RX_RING_SIZE)+0xf) and 0xfffffff0)
pcnet32_private:
.mode dw ?
.tlen_rlen dw ?
.phys_addr db ?,?,?,?,?,?
.reserved dw ?
.filter dd ?,?
.rx_ring dd ?
.tx_ring dd ?
.cur_rx dd ?
.cur_tx dd ?
.dirty_rx dd ?
.dirty_tx dd ?
.tx_full db ?
.options dd ?
.full_duplex db ?
.chip_version dd ?
.mii db ?
.ltint db ?
.dxsuflo db ?
.fset db ?
.fdx db ?
end virtual
 
virtual at 0
pcnet32_rx_head:
.base dd ?
.buf_length dw ?
.status dw ?
.msg_length dd ?
.reserved dd ?
end virtual
 
virtual at 0
pcnet32_tx_head:
.base dd ?
.length dw ?
.status dw ?
.misc dd ?
.reserved dd ?
end virtual
 
uglobal
pcnet32_access:
.read_csr dd ?
.write_csr dd ?
.read_bcr dd ?
.write_bcr dd ?
.read_rap dd ?
.write_rap dd ?
.reset dd ?
endg
 
iglobal
pcnet32_options_mapping:
dd PCNET32_PORT_ASEL ; 0 Auto-select
dd PCNET32_PORT_AUI ; 1 BNC/AUI
dd PCNET32_PORT_AUI ; 2 AUI/BNC
dd PCNET32_PORT_ASEL ; 3 not supported
dd PCNET32_PORT_10BT or PCNET32_PORT_FD ; 4 10baseT-FD
dd PCNET32_PORT_ASEL ; 5 not supported
dd PCNET32_PORT_ASEL ; 6 not supported
dd PCNET32_PORT_ASEL ; 7 not supported
dd PCNET32_PORT_ASEL ; 8 not supported
dd PCNET32_PORT_MII ; 9 MII 10baseT
dd PCNET32_PORT_MII or PCNET32_PORT_FD ; 10 MII 10baseT-FD
dd PCNET32_PORT_MII ; 11 MII (autosel)
dd PCNET32_PORT_10BT ; 12 10BaseT
dd PCNET32_PORT_MII or PCNET32_PORT_100 ; 13 MII 100BaseTx
dd PCNET32_PORT_MII or PCNET32_PORT_100 or PCNET32_PORT_FD ; 14 MII 100BaseTx-FD
dd PCNET32_PORT_ASEL ; 15 not supported
endg
 
PCNET32_WIO_RDP equ 0x10
PCNET32_WIO_RAP equ 0x12
PCNET32_WIO_RESET equ 0x14
PCNET32_WIO_BDP equ 0x16
PCNET32_DWIO_RDP equ 0x10
PCNET32_DWIO_RAP equ 0x14
PCNET32_DWIO_RESET equ 0x18
PCNET32_DWIO_BDP equ 0x1C
PCNET32_TOTAL_SIZE equ 0x20
; ebx - index
; return:
; eax - data
pcnet32_wio_read_csr:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
mov ax,bx
out dx,ax
lea edx,[ebp+PCNET32_WIO_RDP]
in ax,dx
and eax,0xffff
pop edx
ret
; eax - data
; ebx - index
pcnet32_wio_write_csr:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
xchg eax,ebx
out dx,ax
xchg eax,ebx
lea edx,[ebp+PCNET32_WIO_RDP]
out dx,ax
pop edx
ret
; ebx - index
; return:
; eax - data
pcnet32_wio_read_bcr:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
mov ax,bx
out dx,ax
lea edx,[ebp+PCNET32_WIO_BDP]
in ax,dx
and eax,0xffff
pop edx
ret
; eax - data
; ebx - index
pcnet32_wio_write_bcr:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
xchg eax,ebx
out dx,ax
xchg eax,ebx
lea edx,[ebp+PCNET32_WIO_BDP]
out dx,ax
pop edx
ret
pcnet32_wio_read_rap:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
in ax,dx
and eax,0xffff
pop edx
ret
; eax - val
pcnet32_wio_write_rap:
push edx
lea edx,[ebp+PCNET32_WIO_RAP]
out dx,ax
pop edx
ret
pcnet32_wio_reset:
push edx
push eax
lea edx,[ebp+PCNET32_WIO_RESET]
in ax,dx
pop eax
pop edx
ret
pcnet32_wio_check:
push edx
mov ax,88
lea edx,[ebp+PCNET32_WIO_RAP]
out dx,ax
nop
nop
in ax,dx
cmp ax,88
sete al
pop edx
ret
 
iglobal
pcnet32_wio:
dd pcnet32_wio_read_csr
dd pcnet32_wio_write_csr
dd pcnet32_wio_read_bcr
dd pcnet32_wio_write_bcr
dd pcnet32_wio_read_rap
dd pcnet32_wio_write_rap
dd pcnet32_wio_reset
endg
 
; ebx - index
; return:
; eax - data
pcnet32_dwio_read_csr:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
mov ebx,eax
out dx,eax
lea edx,[ebp+PCNET32_DWIO_RDP]
in eax,dx
and eax,0xffff
pop edx
ret
; ebx - index
; eax - data
pcnet32_dwio_write_csr:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
xchg eax,ebx
out dx,eax
lea edx,[ebp+PCNET32_DWIO_RDP]
xchg eax,ebx
out dx,eax
pop edx
ret
; ebx - index
; return:
; eax - data
pcnet32_dwio_read_bcr:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
mov ebx,eax
out dx,eax
lea edx,[ebp+PCNET32_DWIO_BDP]
in eax,dx
and eax,0xffff
pop edx
ret
; ebx - index
; eax - data
pcnet32_dwio_write_bcr:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
xchg eax,ebx
out dx,eax
lea edx,[ebp+PCNET32_DWIO_BDP]
xchg eax,ebx
out dx,eax
pop edx
ret
pcnet32_dwio_read_rap:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
in eax,dx
and eax,0xffff
pop edx
ret
; eax - val
pcnet32_dwio_write_rap:
push edx
lea edx,[ebp+PCNET32_DWIO_RAP]
out dx,eax
pop edx
ret
pcnet32_dwio_reset:
push edx
push eax
lea edx,[ebp+PCNET32_DWIO_RESET]
in eax,dx
pop eax
pop edx
ret
pcnet32_dwio_check:
push edx
lea edx,[PCNET32_DWIO_RAP]
mov eax,88
out dx,eax
nop
nop
in eax,dx
and eax,0xffff
cmp eax,88
sete al
pop edx
ret
 
iglobal
pcnet32_dwio:
dd pcnet32_dwio_read_csr
dd pcnet32_dwio_write_csr
dd pcnet32_dwio_read_bcr
dd pcnet32_dwio_write_bcr
dd pcnet32_dwio_read_rap
dd pcnet32_dwio_write_rap
dd pcnet32_dwio_reset
endg
 
 
 
pcnet32_init_ring:
mov [pcnet32_private.tx_full],0
mov [pcnet32_private.cur_rx],0
mov [pcnet32_private.cur_tx],0
mov [pcnet32_private.dirty_rx],0
mov [pcnet32_private.dirty_tx],0
mov edi,pcnet32_rx_ring
mov ecx,PCNET32_RX_RING_SIZE
mov ebx,pcnet32_rxb
sub ebx,OS_BASE
.rx_init:
mov [edi+pcnet32_rx_head.base],ebx
mov [edi+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
mov [edi+pcnet32_rx_head.status],word 0x8000
add ebx,PCNET32_PKT_BUF_SZ
; inc ebx
add edi,16
loop .rx_init
mov edi,pcnet32_tx_ring
mov ecx,PCNET32_TX_RING_SIZE
.tx_init:
mov [edi+pcnet32_tx_head.base],dword 0
mov [edi+pcnet32_tx_head.status],word 0
add edi,16
loop .tx_init
mov [pcnet32_private.tlen_rlen],(PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
mov esi,node_addr
mov edi,pcnet32_private.phys_addr
cld
movsd
movsw
mov eax,pcnet32_rx_ring
sub eax,OS_BASE
mov dword [pcnet32_private.rx_ring],eax
 
mov eax,pcnet32_tx_ring
sub eax,OS_BASE
mov dword [pcnet32_private.tx_ring],eax
ret
 
 
 
pcnet32_reset:
; Reset PCNET32
mov ebp,[io_addr]
call dword [pcnet32_access.reset]
; set 32bit mode
mov ebx,20
mov eax,2
call dword [pcnet32_access.write_bcr]
; set/reset autoselect bit
mov ebx,2
call dword [pcnet32_access.read_bcr]
and eax,not 2
test [pcnet32_private.options],PCNET32_PORT_ASEL
jz .L1
or eax,2
.L1:
call dword [pcnet32_access.write_bcr]
; Handle full duplex setting
cmp byte [pcnet32_private.full_duplex],0
je .L2
mov ebx,9
call dword [pcnet32_access.read_bcr]
and eax,not 3
test [pcnet32_private.options],PCNET32_PORT_FD
jz .L3
or eax,1
cmp [pcnet32_private.options],PCNET32_PORT_FD or PCNET32_PORT_AUI
jne .L4
or eax,2
jmp .L4
.L3:
test [pcnet32_private.options],PCNET32_PORT_ASEL
jz .L4
cmp [pcnet32_private.chip_version],0x2627
jne .L4
or eax,3
.L4:
mov ebx,9
call dword [pcnet32_access.write_bcr]
.L2:
; set/reset GPSI bit
mov ebx,124
call dword [pcnet32_access.read_csr]
mov ecx,[pcnet32_private.options]
and ecx,PCNET32_PORT_PORTSEL
cmp ecx,PCNET32_PORT_GPSI
jne .L5
or eax,0x10
.L5:
call dword [pcnet32_access.write_csr]
cmp [pcnet32_private.mii],0
je .L6
test [pcnet32_private.options],PCNET32_PORT_ASEL
jnz .L6
mov ebx,32
call dword [pcnet32_access.read_bcr]
and eax,not 0x38
test [pcnet32_private.options],PCNET32_PORT_FD
jz .L7
or eax,0x10
.L7:
test [pcnet32_private.options],PCNET32_PORT_100
jz .L8
or eax,0x08
.L8:
call dword [pcnet32_access.write_bcr]
jmp .L9
.L6:
test [pcnet32_private.options],PCNET32_PORT_ASEL
jz .L9
mov ebx,32
; DEBUGF 1," K : ASEL, enable auto-negotiation\n"
call dword [pcnet32_access.read_bcr]
and eax,not 0x98
or eax,0x20
call dword [pcnet32_access.write_bcr]
.L9:
cmp [pcnet32_private.ltint],0
je .L10
mov ebx,5
call dword [pcnet32_access.read_csr]
or eax,(1 shl 14)
call dword [pcnet32_access.write_csr]
.L10:
mov eax,[pcnet32_private.options]
and eax,PCNET32_PORT_PORTSEL
shl eax,7
mov [pcnet32_private.mode],ax
mov [pcnet32_private.filter],dword 0xffffffff
mov [pcnet32_private.filter+4],dword 0xffffffff
call pcnet32_init_ring
mov ebx,1
mov eax,pcnet32_private
sub eax,OS_BASE
and eax,0xffff
call dword [pcnet32_access.write_csr]
mov eax,pcnet32_private
sub eax,OS_BASE
mov ebx,2
shr eax,16
call dword [pcnet32_access.write_csr]
mov ebx,4
mov eax,0x0915
call dword [pcnet32_access.write_csr]
mov ebx,0
mov eax,1
call dword [pcnet32_access.write_csr]
mov ecx,100
.L11:
xor ebx,ebx
call dword [pcnet32_access.read_csr]
test ax,0x100
jnz .L12
loop .L11
.L12:
; DEBUGF 1," K : hardware reset\n"
xor ebx,ebx
mov eax,0x0002
call dword [pcnet32_access.write_csr]
xor ebx,ebx
call dword [pcnet32_access.read_csr]
; DEBUGF 1," K : PCNET reset complete\n"
ret
 
 
 
pcnet32_adjust_pci_device:
;*******Get current setting************************
mov al, 2 ;read a word
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, 0x04 ;from command Register
call pci_read_reg
;******see if its already set as bus master********
mov bx, ax
and bx,5
cmp bx,5
je pcnet32_adjust_pci_device_Latency
;******Make card a bus master*******
mov cx, ax ;value to write
mov bh, [pci_dev]
mov al, 2 ;write a word
or cx,5
mov ah, [pci_bus]
mov bl, 0x04 ;to command register
call pci_write_reg
;******Check latency setting***********
pcnet32_adjust_pci_device_Latency:
;*******Get current latency setting************************
; mov al, 1 ;read a byte
; mov bh, [pci_dev]
; mov ah, [pci_bus]
; mov bl, 0x0D ;from Lantency Timer Register
; call pci_read_reg
;******see if its aat least 64 clocks********
; cmp ax,64
; jge pcnet32_adjust_pci_device_Done
;******Set latency to 32 clocks*******
; mov cx, 64 ;value to write
; mov bh, [pci_dev]
; mov al, 1 ;write a byte
; mov ah, [pci_bus]
; mov bl, 0x0D ;to Lantency Timer Register
; call pci_write_reg
;******Check latency setting***********
pcnet32_adjust_pci_device_Done:
ret
 
 
 
 
pcnet32_probe:
mov ebp,[io_addr]
call pcnet32_wio_reset
xor ebx,ebx
call pcnet32_wio_read_csr
cmp eax,4
jne .try_dwio
call pcnet32_wio_check
and al,al
jz .try_dwio
; DEBUGF 1," K : Using WIO\n"
mov esi,pcnet32_wio
jmp .L1
.try_dwio:
call pcnet32_dwio_reset
xor ebx,ebx
call pcnet32_dwio_read_csr
cmp eax,4
jne .no_dev
call pcnet32_dwio_check
and al,al
jz .no_dev
; DEBUGF 1," K : Using DWIO\n"
mov esi,pcnet32_dwio
jmp .L1
.no_dev:
DEBUGF 1," K : PCNET32 not found\n"
ret
.L1:
mov edi,pcnet32_access
mov ecx,7
cld
rep movsd
mov ebx,88
call dword [pcnet32_access.read_csr]
mov ecx,eax
mov ebx,89
call dword [pcnet32_access.read_csr]
shl eax,16
or eax,ecx
mov ecx,eax
and ecx,0xfff
cmp ecx,3
jne .no_dev
shr eax,12
and eax,0xffff
mov [pcnet32_private.chip_version],eax
; DEBUGF 1," K : PCNET32 chip version OK\n"
mov [pcnet32_private.fdx],0
mov [pcnet32_private.mii],0
mov [pcnet32_private.fset],0
mov [pcnet32_private.dxsuflo],0
mov [pcnet32_private.ltint],0
mov eax,[pcnet32_private.chip_version]
cmp eax,0x2420
je .L2
cmp eax,0x2430
je .L3
cmp eax,0x2621
je .L4
cmp eax,0x2623
je .L5
cmp eax,0x2624
je .L6
cmp eax,0x2625
je .L7
cmp eax,0x2626
je .L8
cmp eax,0x2627
je .L9
DEBUGF 1," K : Invalid chip rev\n"
jmp .no_dev
.L2:
; DEBUGF 1," K : PCnet/PCI 79C970\n"
jmp .L10
.L3:
; DEBUGF 1," K : PCnet/PCI 79C970\n"
jmp .L10
.L4:
; DEBUGF 1," K : PCnet/PCI II 79C970A\n"
mov [pcnet32_private.fdx],1
jmp .L10
.L5:
; DEBUGF 1," K : PCnet/FAST 79C971\n"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
mov [pcnet32_private.fset],1
mov [pcnet32_private.ltint],1
jmp .L10
.L6:
; DEBUGF 1," K : PCnet/FAST+ 79C972\n"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
mov [pcnet32_private.fset],1
jmp .L10
.L7:
; DEBUGF 1," K : PCnet/FAST III 79C973\n"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
jmp .L10
.L8:
; DEBUGF 1," K : PCnet/Home 79C978\n"
mov [pcnet32_private.fdx],1
mov ebx,49
call dword [pcnet32_access.read_bcr]
call dword [pcnet32_access.write_bcr]
jmp .L10
.L9:
; DEBUGF 1," K : PCnet/FAST III 79C975\n"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
.L10:
cmp [pcnet32_private.fset],1
jne .L11
mov ebx,18
call dword [pcnet32_access.read_bcr]
or eax,0x800
call dword [pcnet32_access.write_bcr]
mov ebx,80
call dword [pcnet32_access.read_csr]
and eax,0xc00
or eax,0xc00
call dword [pcnet32_access.write_csr]
mov [pcnet32_private.dxsuflo],1
mov [pcnet32_private.ltint],1
.L11:
; read MAC
mov edi,node_addr
mov edx,ebp
mov ecx,6
.Lmac:
in al,dx
stosb
inc edx
loop .Lmac
; DEBUGF 1," K : MAC read\n"
call pcnet32_adjust_pci_device
; DEBUGF 1," K : PCI done\n"
mov eax,PCNET32_PORT_ASEL
mov [pcnet32_private.options],eax
mov [pcnet32_private.mode],word 0x0003
mov [pcnet32_private.tlen_rlen],word (PCNET32_TX_RING_LEN_BITS or PCNET32_RX_RING_LEN_BITS)
mov esi,node_addr
mov edi,pcnet32_private.phys_addr
cld
movsd
movsw
mov [pcnet32_private.filter],dword 0
mov [pcnet32_private.filter+4],dword 0
mov eax,pcnet32_rx_ring
sub eax,OS_BASE
mov dword [pcnet32_private.rx_ring],eax
 
mov eax,pcnet32_tx_ring
sub eax,OS_BASE
mov dword [pcnet32_private.tx_ring],eax
; DEBUGF 1," K : Switching to 32\n"
mov ebx,20
mov eax,2
call dword [pcnet32_access.write_bcr]
mov ebx,1
mov eax,(pcnet32_private and 0xffff)
call dword [pcnet32_access.write_csr]
mov ebx,2
mov eax,(pcnet32_private shr 16) and 0xffff
call dword [pcnet32_access.write_csr]
mov ebx,0
mov eax,1
call dword [pcnet32_access.write_csr]
mov esi,1
call delay_ms
call pcnet32_reset
mov eax, [pci_data]
mov [eth_status], eax
ret
 
 
 
pcnet32_poll:
xor ax,ax
mov [eth_rx_data_len],ax
mov eax,[pcnet32_private.cur_rx]
and eax,PCNET32_RX_RING_MOD_MASK
mov ebx,eax
imul esi,eax,PCNET32_PKT_BUF_SZ
add esi,pcnet32_rxb
shl ebx,4
add ebx,pcnet32_rx_ring
mov cx,[ebx+pcnet32_rx_head.status]
test cx,0x8000
jnz .L1
cmp ch,3
jne .L1
mov ecx,[ebx+pcnet32_rx_head.msg_length]
and ecx,0xfff
sub ecx,4
mov [eth_rx_data_len],cx
; DEBUGF 1," K : PCNETRX: %ub\n",cx
push ecx
shr ecx,2
mov edi,Ether_buffer
cld
rep movsd
pop ecx
and ecx,3
rep movsb
mov [ebx+pcnet32_rx_head.buf_length],word PCNET32_PKT_BUF_SZ_NEG
or [ebx+pcnet32_rx_head.status],word 0x8000
inc [pcnet32_private.cur_rx]
.L1:
ret
 
 
 
 
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
pcnet32_xmit:
push edi
push esi
push ebx
push ecx
; DEBUGF 1," K : PCNETTX\n"
mov esi,edi
mov edi,[pcnet32_private.cur_tx]
imul edi,PCNET32_PKT_BUF_SZ
add edi,pcnet32_txb ; edi=ptxb
mov eax,edi
cld ; copy MAC
movsd
movsw
mov esi,node_addr
cld
movsd
movsw
mov [edi],bx
add edi,2
mov esi,[esp+8]
mov ecx,[esp]
push ecx
shr ecx,2
cld
rep movsd
pop ecx
and ecx,3
rep movsb
; mov ecx,[esp]
; add ecx,14 ; ETH_HLEN
; xor eax,eax
; pad to min length (60=ETH_ZLEN)
; cmp ecx,60
; jae .L1
; sub ecx,60
; cld
; rep stosb
;.L1:
mov edi,pcnet32_tx_ring+0 ; entry=0
mov ecx,[esp]
add ecx,14
cmp cx,60
jae .L1
mov cx,60
.L1:
neg cx
mov [edi+pcnet32_tx_head.length],cx
mov [edi+pcnet32_tx_head.misc],dword 0
sub eax,OS_BASE
mov [edi+pcnet32_tx_head.base],eax
mov [edi+pcnet32_tx_head.status],word 0x8300
; trigger an immediate send poll
mov ebx,0
mov eax,0x0008 ; 0x0048
mov ebp,[io_addr]
call dword [pcnet32_access.write_csr]
mov dword [pcnet32_private.cur_tx],0
; wait for TX to complete
mov ecx,[timer_ticks];[0xfdf0]
add ecx,100
.L2:
mov ax,[edi+pcnet32_tx_head.status]
test ax,0x8000
jz .L3
cmp ecx,[timer_ticks];[0xfdf0]
jb .L4
mov esi,10
call delay_ms
jnz .L2
.L4:
DEBUGF 1," K : PCNET: Send timeout\n"
.L3:
mov dword [edi+pcnet32_tx_head.base],0
pop ecx
pop ebx
pop esi
pop edi
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/eth_drv/drivers/sis900.inc
0,0 → 1,1158
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; SIS900.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.4 26 April 2004 ;;
;; ;;
;; This driver is based on the SIS900 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2004 Jason Delozier, ;;
;; cordata51@hotmail.com ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; Updates: ;;
;; Revision Look up table and SIS635 Mac Address by Jarek Pelczar ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;********************************************************************
; Interface
; SIS900_reset
; SIS900_probe
; SIS900_poll
; SIS900_transmit
;
;********************************************************************
;********************************************************************
; Comments:
; Known to work with the following SIS900 ethernet cards:
; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x91
; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x90
;
; If your card is not listed, try it and let me know if it
; functions properly and it will be aded to the list. If not
; we may be able to add support for it.
;
; How To Use:
; Add the following lines to Ethernet.inc in their appropriate locations
;
; include "Sis900.INC"
; dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll,
; SIS900_transmit
; dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll,
; SIS900_transmit ;untested
;
; ToDo:
; - Enable MII interface for reading speed
; and duplex settings.
;
; - Update Poll routine to support packet fragmentation.
;
; - Add additional support for other sis900 based cards
;
;********************************************************************
 
; comment the next line out if you don't want debug info printed
; on the debug board. This option adds a lot of bytes to the driver
; so it's worth to comment it out.
; SIS900_DEBUG equ 1
 
 
;* buffers and descriptors
cur_rx db 0
NUM_RX_DESC equ 4 ;* Number of RX descriptors *
NUM_TX_DESC equ 1 ;* Number of TX descriptors *
RX_BUFF_SZ equ 1520 ;* Buffer size for each Rx buffer *
TX_BUFF_SZ equ 1516 ;* Buffer size for each Tx buffer *
 
uglobal
align 4
txd: times (3 * NUM_TX_DESC) dd 0
rxd: times (3 * NUM_RX_DESC) dd 0
endg
 
txb equ eth_data_start
rxb equ txb + (NUM_TX_DESC * TX_BUFF_SZ)
SIS900_ETH_ALEN equ 6 ;* Size of Ethernet address *
SIS900_ETH_HLEN equ 14 ;* Size of ethernet header *
SIS900_ETH_ZLEN equ 60 ;* Minimum packet length *
SIS900_DSIZE equ 0x00000fff
SIS900_CRC_SIZE equ 4
SIS900_RFADDR_shift equ 16
;SIS900 Symbolic offsets to registers.
SIS900_cr equ 0x0 ; Command Register
SIS900_cfg equ 0x4 ; Configuration Register
SIS900_mear equ 0x8 ; EEPROM Access Register
SIS900_ptscr equ 0xc ; PCI Test Control Register
SIS900_isr equ 0x10 ; Interrupt Status Register
SIS900_imr equ 0x14 ; Interrupt Mask Register
SIS900_ier equ 0x18 ; Interrupt Enable Register
SIS900_epar equ 0x18 ; Enhanced PHY Access Register
SIS900_txdp equ 0x20 ; Transmit Descriptor Pointer Register
SIS900_txcfg equ 0x24 ; Transmit Configuration Register
SIS900_rxdp equ 0x30 ; Receive Descriptor Pointer Register
SIS900_rxcfg equ 0x34 ; Receive Configuration Register
SIS900_flctrl equ 0x38 ; Flow Control Register
SIS900_rxlen equ 0x3c ; Receive Packet Length Register
SIS900_rfcr equ 0x48 ; Receive Filter Control Register
SIS900_rfdr equ 0x4C ; Receive Filter Data Register
SIS900_pmctrl equ 0xB0 ; Power Management Control Register
SIS900_pmer equ 0xB4 ; Power Management Wake-up Event Register
;SIS900 Command Register Bits
SIS900_RELOAD equ 0x00000400
SIS900_ACCESSMODE equ 0x00000200
SIS900_RESET equ 0x00000100
SIS900_SWI equ 0x00000080
SIS900_RxRESET equ 0x00000020
SIS900_TxRESET equ 0x00000010
SIS900_RxDIS equ 0x00000008
SIS900_RxENA equ 0x00000004
SIS900_TxDIS equ 0x00000002
SIS900_TxENA equ 0x00000001
;SIS900 Configuration Register Bits
SIS900_DESCRFMT equ 0x00000100 ; 7016 specific
SIS900_REQALG equ 0x00000080
SIS900_SB equ 0x00000040
SIS900_POW equ 0x00000020
SIS900_EXD equ 0x00000010
SIS900_PESEL equ 0x00000008
SIS900_LPM equ 0x00000004
SIS900_BEM equ 0x00000001
SIS900_RND_CNT equ 0x00000400
SIS900_FAIR_BACKOFF equ 0x00000200
SIS900_EDB_MASTER_EN equ 0x00002000
;SIS900 Eeprom Access Reigster Bits
SIS900_MDC equ 0x00000040
SIS900_MDDIR equ 0x00000020
SIS900_MDIO equ 0x00000010 ; 7016 specific
SIS900_EECS equ 0x00000008
SIS900_EECLK equ 0x00000004
SIS900_EEDO equ 0x00000002
SIS900_EEDI equ 0x00000001
;SIS900 TX Configuration Register Bits
SIS900_ATP equ 0x10000000 ;Automatic Transmit Padding
SIS900_MLB equ 0x20000000 ;Mac Loopback Enable
SIS900_HBI equ 0x40000000 ;HeartBeat Ignore (Req for full-dup)
SIS900_CSI equ 0x80000000 ;CarrierSenseIgnore (Req for full-du
;SIS900 RX Configuration Register Bits
SIS900_AJAB equ 0x08000000 ;
SIS900_ATX equ 0x10000000 ;Accept Transmit Packets
SIS900_ARP equ 0x40000000 ;accept runt packets (<64bytes)
SIS900_AEP equ 0x80000000 ;accept error packets
;SIS900 Interrupt Reigster Bits
SIS900_WKEVT equ 0x10000000
SIS900_TxPAUSEEND equ 0x08000000
SIS900_TxPAUSE equ 0x04000000
SIS900_TxRCMP equ 0x02000000
SIS900_RxRCMP equ 0x01000000
SIS900_DPERR equ 0x00800000
SIS900_SSERR equ 0x00400000
SIS900_RMABT equ 0x00200000
SIS900_RTABT equ 0x00100000
SIS900_RxSOVR equ 0x00010000
SIS900_HIBERR equ 0x00008000
SIS900_SWINT equ 0x00001000
SIS900_MIBINT equ 0x00000800
SIS900_TxURN equ 0x00000400
SIS900_TxIDLE equ 0x00000200
SIS900_TxERR equ 0x00000100
SIS900_TxDESC equ 0x00000080
SIS900_TxOK equ 0x00000040
SIS900_RxORN equ 0x00000020
SIS900_RxIDLE equ 0x00000010
SIS900_RxEARLY equ 0x00000008
SIS900_RxERR equ 0x00000004
SIS900_RxDESC equ 0x00000002
SIS900_RxOK equ 0x00000001
;SIS900 Interrupt Enable Reigster Bits
SIS900_IE equ 0x00000001
;SIS900 Revision ID
SIS900B_900_REV equ 0x03
SIS630A_900_REV equ 0x80
SIS630E_900_REV equ 0x81
SIS630S_900_REV equ 0x82
SIS630EA1_900_REV equ 0x83
SIS630ET_900_REV equ 0x84
SIS635A_900_REV equ 0x90
SIS900_960_REV equ 0x91
;SIS900 Receive Filter Control Register Bits
SIS900_RFEN equ 0x80000000
SIS900_RFAAB equ 0x40000000
SIS900_RFAAM equ 0x20000000
SIS900_RFAAP equ 0x10000000
SIS900_RFPromiscuous equ 0x70000000
;SIS900 Reveive Filter Data Mask
SIS900_RFDAT equ 0x0000FFFF
;SIS900 Eeprom Address
SIS900_EEPROMSignature equ 0x00
SIS900_EEPROMVendorID equ 0x02
SIS900_EEPROMDeviceID equ 0x03
SIS900_EEPROMMACAddr equ 0x08
SIS900_EEPROMChecksum equ 0x0b
;The EEPROM commands include the alway-set leading bit.
;SIS900 Eeprom Command
SIS900_EEread equ 0x0180
SIS900_EEwrite equ 0x0140
SIS900_EEerase equ 0x01C0
SIS900_EEwriteEnable equ 0x0130
SIS900_EEwriteDisable equ 0x0100
SIS900_EEeraseAll equ 0x0120
SIS900_EEwriteAll equ 0x0110
SIS900_EEaddrMask equ 0x013F
SIS900_EEcmdShift equ 16
;For SiS962 or SiS963, request the eeprom software access
SIS900_EEREQ equ 0x00000400
SIS900_EEDONE equ 0x00000200
SIS900_EEGNT equ 0x00000100
;General Varibles
SIS900_pci_revision: db 0
SIS900_Status dd 0x03000000
sis900_specific_table:
; dd SIS630A_900_REV,Get_Mac_SIS630A_900_REV,0
; dd SIS630E_900_REV,Get_Mac_SIS630E_900_REV,0
dd SIS630S_900_REV,Get_Mac_SIS635_900_REV,0
dd SIS630EA1_900_REV,Get_Mac_SIS635_900_REV,0
dd SIS630ET_900_REV,Get_Mac_SIS635_900_REV,0;SIS630ET_900_REV_SpecialFN
dd SIS635A_900_REV,Get_Mac_SIS635_900_REV,0
dd SIS900_960_REV,SIS960_get_mac_addr,0
dd SIS900B_900_REV,SIS900_get_mac_addr,0
dd 0,0,0,0 ; end of list
sis900_get_mac_func: dd 0
sis900_special_func: dd 0
sis900_table_entries: db 8
 
;***************************************************************************
; Function
; SIS900_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
;not done - still need to probe mii transcievers
;***************************************************************************
if defined SIS900_DEBUG
SIS900_Debug_Str_Unsupported db 'Sorry your card is unsupported ',13,10,0
end if
SIS900_probe:
;******Wake Up Chip*******
mov al, 4
mov bh, [pci_dev]
mov ecx, 0
mov ah, [pci_bus]
mov bl, 0x40
call pci_write_reg
;*******Set some PCI Settings*********
call SIS900_adjust_pci_device
;*****Get Card Revision******
mov al, 1 ;one byte to read
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, 0x08 ;Revision Register
call pci_read_reg
mov [SIS900_pci_revision], al ;save the revision for later use
;****** Look up through the sis900_specific_table
mov esi,sis900_specific_table
.probe_loop:
cmp dword [esi],0 ; Check if we reached end of the list
je .probe_loop_failed
cmp al,[esi] ; Check if revision is OK
je .probe_loop_ok
add esi,12 ; Advance to next entry
jmp .probe_loop
.probe_loop_failed:
jmp SIS900_Probe_Unsupported
;*********Find Get Mac Function*********
.probe_loop_ok:
mov eax,[esi+4] ; Get pointer to "get MAC" function
mov [sis900_get_mac_func],eax
mov eax,[esi+8] ; Get pointer to special initialization fn
mov [sis900_special_func],eax
;******** Get MAC ********
call dword [sis900_get_mac_func]
;******** Call special initialization fn if requested ********
cmp dword [sis900_special_func],0
je .no_special_init
call dword [sis900_special_func]
.no_special_init:
;******** Set table entries ********
mov al,[SIS900_pci_revision]
cmp al,SIS635A_900_REV
jae .ent16
cmp al,SIS900B_900_REV
je .ent16
jmp .ent8
.ent16:
mov byte [sis900_table_entries],16
.ent8:
;*******Probe for mii transceiver*******
;TODO!!*********************
;*******Initialize Device*******
call sis900_init
ret
 
SIS900_Probe_Unsupported:
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Str_Unsupported
call sys_msg_board_str
end if
ret
;***************************************************************************
; Function: sis900_init
;
; Description: resets the ethernet controller chip and various
; data structures required for sending and receiving packets.
;
; Arguments:
;
; returns: none
;not done
;***************************************************************************
sis900_init:
call SIS900_reset ;Done
call SIS900_init_rxfilter ;Done
call SIS900_init_txd ;Done
call SIS900_init_rxd ;Done
call SIS900_set_rx_mode ;done
call SIS900_set_tx_mode
;call SIS900_check_mode
ret
 
;***************************************************************************
; Function
; SIS900_reset
; Description
; disables interrupts and soft resets the controller chip
;
;done+
;***************************************************************************
if defined SIS900_DEBUG
SIS900_Debug_Reset_Failed db 'Reset Failed ',0
end if
SIS900_reset:
;******Disable Interrupts and reset Receive Filter*******
mov ebp, [io_addr] ; base address
xor eax, eax ; 0 to initialize
lea edx,[ebp+SIS900_ier]
out dx, eax ; Write 0 to location
lea edx,[ebp+SIS900_imr]
out dx, eax ; Write 0 to location
lea edx,[ebp+SIS900_rfcr]
out dx, eax ; Write 0 to location
;*******Reset Card***********************************************
lea edx,[ebp+SIS900_cr]
in eax, dx ; Get current Command Register
or eax, SIS900_RESET ; set flags
or eax, SIS900_RxRESET ;
or eax, SIS900_TxRESET ;
out dx, eax ; Write new Command Register
;*******Wait Loop************************************************
lea edx,[ebp+SIS900_isr]
mov ecx, [SIS900_Status] ; Status we would like to see from card
mov ebx, 2001 ; only loop 1000 times
SIS900_Wait:
dec ebx ; 1 less loop
jz SIS900_DoneWait_e ; 1000 times yet?
in eax, dx ; move interrup status to eax
and eax, ecx
xor ecx, eax
jz SIS900_DoneWait
jmp SIS900_Wait
SIS900_DoneWait_e:
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Reset_Failed
call sys_msg_board_str
end if
SIS900_DoneWait:
;*******Set Configuration Register depending on Card Revision********
lea edx,[ebp+SIS900_cfg]
mov eax, SIS900_PESEL ; Configuration Register Bit
mov bl, [SIS900_pci_revision] ; card revision
mov cl, SIS635A_900_REV ; Check card revision
cmp bl, cl
je SIS900_RevMatch
mov cl, SIS900B_900_REV ; Check card revision
cmp bl, cl
je SIS900_RevMatch
out dx, eax ; no revision match
jmp SIS900_Reset_Complete
SIS900_RevMatch: ; Revision match
or eax, SIS900_RND_CNT ; Configuration Register Bit
out dx, eax
SIS900_Reset_Complete:
mov eax, [pci_data]
mov [eth_status], eax
ret
 
;***************************************************************************
; Function: sis_init_rxfilter
;
; Description: sets receive filter address to our MAC address
;
; Arguments:
;
; returns:
;done+
;***************************************************************************
SIS900_init_rxfilter:
;****Get Receive Filter Control Register ********
mov ebp, [io_addr] ; base address
lea edx,[ebp+SIS900_rfcr]
in eax, dx ; get register
push eax
;****disable packet filtering before setting filter*******
mov eax, SIS900_RFEN ;move receive filter enable flag
not eax ;1s complement
pop ebx ;and with our saved register
and eax, ebx ;disable receiver
push ebx ;save filter for another use
out dx, eax ;set receive disabled
;********load MAC addr to filter data register*********
xor ecx, ecx
SIS900_RXINT_Mac_Write:
;high word of eax tells card which mac byte to write
mov eax, ecx
lea edx,[ebp+SIS900_rfcr]
shl eax, 16 ;
out dx, eax ;
lea edx,[ebp+SIS900_rfdr]
mov ax, word [node_addr+ecx*2] ; Get Mac ID word
out dx, ax ; Send Mac ID
inc cl ; send next word
cmp cl, 3 ; more to send?
jne SIS900_RXINT_Mac_Write
;********enable packet filitering *****
pop eax ;old register value
lea edx,[ebp+SIS900_rfcr]
or eax, SIS900_RFEN ;enable filtering
out dx, eax ;set register
ret
 
;***************************************************************************
;*
;* Function: sis_init_txd
;*
;* Description: initializes the Tx descriptor
;*
;* Arguments:
;*
;* returns:
;*done
;***************************************************************************
SIS900_init_txd:
;********** initialize TX descriptor **************
mov [txd], dword 0 ;put link to next descriptor in link field
mov [txd+4],dword 0 ;clear status field
mov [txd+8], dword txb - OS_BASE ;save address to buffer ptr field
;*************** load Transmit Descriptor Register ***************
mov dx, [io_addr] ; base address
add dx, SIS900_txdp ; TX Descriptor Pointer
mov eax, txd - OS_BASE ; First Descriptor
out dx, eax ; move the pointer
ret
 
;***************************************************************************
;* Function: sis_init_rxd
;*
;* Description: initializes the Rx descriptor ring
;*
;* Arguments:
;*
;* Returns:
;*done
;***************************************************************************
SIS900_init_rxd:
xor ecx,ecx
mov [cur_rx], cl ;Set cuurent rx discriptor to 0
;******** init RX descriptors ********
SIS900_init_rxd_Loop:
mov eax, ecx ;current descriptor
imul eax, 12 ;
mov ebx, ecx ;determine next link descriptor
inc ebx ;
cmp ebx, NUM_RX_DESC ;
jne SIS900_init_rxd_Loop_0 ;
xor ebx, ebx ;
SIS900_init_rxd_Loop_0: ;
imul ebx, 12 ;
add ebx, rxd - OS_BASE ;
mov [rxd+eax], ebx ;save link to next descriptor
mov [rxd+eax+4],dword RX_BUFF_SZ ;status bits init to buf size
mov ebx, ecx ;find where the buf is located
imul ebx,RX_BUFF_SZ ;
add ebx, rxb - OS_BASE ;
mov [rxd+eax+8], ebx ;save buffer pointer
inc ecx ;next descriptor
cmp ecx, NUM_RX_DESC ;
jne SIS900_init_rxd_Loop ;
;********* load Receive Descriptor Register with address of first
; descriptor*********
mov dx, [io_addr]
add dx, SIS900_rxdp
mov eax, rxd - OS_BASE
out dx, eax
ret
 
;***************************************************************************
;* Function: sis900_set_tx_mode
;*
;* Description:
;* sets the transmit mode to allow for full duplex
;*
;*
;* Arguments:
;*
;* Returns:
;*
;* Comments:
;* If you are having problems transmitting packet try changing the
;* Max DMA Burst, Possible settings are as follows:
;* 0x00000000 = 512 bytes
;* 0x00100000 = 4 bytes
;* 0x00200000 = 8 bytes
;* 0x00300000 = 16 bytes
;* 0x00400000 = 32 bytes
;* 0x00500000 = 64 bytes
;* 0x00600000 = 128 bytes
;* 0x00700000 = 256 bytes
;***************************************************************************
SIS900_set_tx_mode:
mov ebp,[io_addr]
lea edx,[ebp+SIS900_cr]
in eax, dx ; Get current Command Register
or eax, SIS900_TxENA ;Enable Receive
out dx, eax
lea edx,[ebp+SIS900_txcfg]; Transmit config Register offset
mov eax, SIS900_ATP ;allow automatic padding
or eax, SIS900_HBI ;allow heartbeat ignore
or eax, SIS900_CSI ;allow carrier sense ignore
or eax, 0x00600000 ;Max DMA Burst
or eax, 0x00000100 ;TX Fill Threshold
or eax, 0x00000020 ;TX Drain Threshold
out dx, eax
ret
 
;***************************************************************************
;* Function: sis900_set_rx_mode
;*
;* Description:
;* sets the receive mode to accept all broadcast packets and packets
;* with our MAC address, and reject all multicast packets. Also allows
;* full-duplex
;*
;* Arguments:
;*
;* Returns:
;*
;* Comments:
;* If you are having problems receiving packet try changing the
;* Max DMA Burst, Possible settings are as follows:
;* 0x00000000 = 512 bytes
;* 0x00100000 = 4 bytes
;* 0x00200000 = 8 bytes
;* 0x00300000 = 16 bytes
;* 0x00400000 = 32 bytes
;* 0x00500000 = 64 bytes
;* 0x00600000 = 128 bytes
;* 0x00700000 = 256 bytes
;***************************************************************************
SIS900_mc_filter: times 16 dw 0
SIS900_set_rx_mode:
mov ebp,[io_addr]
;**************update Multicast Hash Table in Receive Filter
mov ebx, 0xffff
xor cl, cl
SIS900_set_rx_mode_Loop:
mov eax, ecx
shl eax, 1
mov [SIS900_mc_filter+eax], bx
lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Reg offset
mov eax, 4 ;determine table entry
add al, cl
shl eax, 16
out dx, eax ;tell card which entry to modify
lea edx,[ebp+SIS900_rfdr] ; Receive Filter Control Reg offset
mov eax, ebx ;entry value
out dx, ax ;write value to table in card
inc cl ;next entry
cmp cl,[sis900_table_entries] ;
jl SIS900_set_rx_mode_Loop
;*******Set Receive Filter Control Register*************
lea edx,[ebp+SIS900_rfcr] ; Receive Filter Control Register offset
mov eax, SIS900_RFAAB ;accecpt all broadcast packets
or eax, SIS900_RFAAM ;accept all multicast packets
or eax, SIS900_RFAAP ;Accept all packets
or eax, SIS900_RFEN ;enable receiver filter
out dx, eax
;******Enable Receiver************
lea edx,[ebp+SIS900_cr] ; Command Register offset
in eax, dx ; Get current Command Register
or eax, SIS900_RxENA ;Enable Receive
out dx, eax
;*********Set
lea edx,[ebp+SIS900_rxcfg] ; Receive Config Register offset
mov eax, SIS900_ATX ;Accept Transmit Packets
; (Req for full-duplex and PMD Loopback)
or eax, 0x00600000 ;Max DMA Burst
or eax, 0x00000002 ;RX Drain Threshold, 8X8 bytes or 64bytes
out dx, eax ;
ret
 
;***************************************************************************
; * SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model
; * @pci_dev: the sis900 pci device
; * @net_dev: the net device to get address for
; *
; * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM
; * is shared by
; * LAN and 1394. When access EEPROM, send EEREQ signal to hardware first
; * and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access
; * by LAN, otherwise is not. After MAC address is read from EEPROM, send
; * EEDONE signal to refuse EEPROM access by LAN.
; * The EEPROM map of SiS962 or SiS963 is different to SiS900.
; * The signature field in SiS962 or SiS963 spec is meaningless.
; * MAC address is read into @net_dev->dev_addr.
; *done
;*
;* Return 0 is EAX = failure
;*Done+
;***************************************************************************
if defined SIS900_DEBUG
SIS900_Debug_Str_GetMac_Start db 'Attempting to get SIS900 Mac ID: ',13,10,0
SIS900_Debug_Str_GetMac_Failed db 'Access to EEprom Failed',13,10,0
SIS900_Debug_Str_GetMac_Address db 'Your Mac ID is: ',0
SIS900_Debug_Str_GetMac_Address2 db 'Your SIS96x Mac ID is: ',0
end if
SIS960_get_mac_addr:
mov ebp,[io_addr]
;**********Send Request for eeprom access*********************
lea edx,[ebp+SIS900_mear] ; Eeprom access register
mov eax, SIS900_EEREQ ; Request access to eeprom
out dx, eax ; Send request
xor ebx,ebx ;
;******Loop 4000 times and if access not granted error out*****
SIS96X_Get_Mac_Wait:
in eax, dx ;get eeprom status
and eax, SIS900_EEGNT ;see if eeprom access granted flag is set
jnz SIS900_Got_EEP_Access ;if it is, go access the eeprom
inc ebx ;else keep waiting
cmp ebx, 4000 ;have we tried 4000 times yet?
jl SIS96X_Get_Mac_Wait ;if not ask again
xor eax, eax ;return zero in eax indicating failure
;*******Debug **********************
if defined SIS900_DEBUG
mov esi,SIS900_Debug_Str_GetMac_Failed
call sys_msg_board_str
end if
jmp SIS960_get_mac_addr_done
;**********EEprom access granted, read MAC from card*************
SIS900_Got_EEP_Access:
; zero based so 3-16 bit reads will take place
mov ecx, 2
SIS96x_mac_read_loop:
mov eax, SIS900_EEPROMMACAddr ;Base Mac Address
add eax, ecx ;Current Mac Byte Offset
push ecx
call sis900_read_eeprom ;try to read 16 bits
pop ecx
mov [node_addr+ecx*2], ax ;save 16 bits to the MAC ID varible
dec ecx ;one less word to read
jns SIS96x_mac_read_loop ;if more read more
mov eax, 1 ;return non-zero indicating success
;*******Debug Print MAC ID to debug window**********************
if defined SIS900_DEBUG
mov esi,SIS900_Debug_Str_GetMac_Address2
call sys_msg_board_str
mov edx, node_addr
call Create_Mac_String
end if
;**********Tell EEPROM We are Done Accessing It*********************
SIS960_get_mac_addr_done:
lea edx,[ebp+SIS900_mear] ; Eeprom access register
mov eax, SIS900_EEDONE ;tell eeprom we are done
out dx,eax
ret
;***************************************************************************
;* sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model
;* @pci_dev: the sis900 pci device
;* @net_dev: the net device to get address for
;*
;* Older SiS900 and friends, use EEPROM to store MAC address.
;* MAC address is read from read_eeprom() into @net_dev->dev_addr.
;* done/untested
;***************************************************************************
SIS900_get_mac_addr:
;*******Debug **********************
if defined SIS900_DEBUG
mov esi,SIS900_Debug_Str_GetMac_Start
call sys_msg_board_str
end if
;******** check to see if we have sane EEPROM *******
mov eax, SIS900_EEPROMSignature ;Base Eeprom Signature
call sis900_read_eeprom ;try to read 16 bits
cmp ax, 0xffff
je SIS900_Bad_Eeprom
cmp ax, 0
je SIS900_Bad_Eeprom
;**************Read MacID**************
; zero based so 3-16 bit reads will take place
mov ecx, 2
SIS900_mac_read_loop:
mov eax, SIS900_EEPROMMACAddr ;Base Mac Address
add eax, ecx ;Current Mac Byte Offset
push ecx
call sis900_read_eeprom ;try to read 16 bits
pop ecx
mov [node_addr+ecx*2], ax ;save 16 bits to the MAC ID storage
dec ecx ;one less word to read
jns SIS900_mac_read_loop ;if more read more
mov eax, 1 ;return non-zero indicating success
;*******Debug Print MAC ID to debug window**********************
if defined SIS900_DEBUG
mov esi,SIS900_Debug_Str_GetMac_Address
call sys_msg_board_str
mov edx, node_addr
call Create_Mac_String
end if
ret
 
SIS900_Bad_Eeprom:
xor eax, eax
;*******Debug **********************
if defined SIS900_DEBUG
mov esi,SIS900_Debug_Str_GetMac_Failed
call sys_msg_board_str
end if
ret
;***************************************************************************
;* Get_Mac_SIS635_900_REV: - Get MAC address for model 635
;*
;*
;***************************************************************************
Get_Mac_SIS635_900_REV:
if defined SIS900_DEBUG
mov esi,SIS900_Debug_Str_GetMac_Start
call sys_msg_board_str
end if
mov ebp,[io_addr]
lea edx,[ebp+SIS900_rfcr]
in eax,dx
mov edi,eax ; EDI=rfcrSave
lea edx,[ebp+SIS900_cr]
or eax,SIS900_RELOAD
out dx,eax
xor eax,eax
out dx,eax
; Disable packet filtering before setting filter
lea edx,[ebp+SIS900_rfcr]
mov eax,edi
and edi,not SIS900_RFEN
out dx,eax
; Load MAC to filter data register
xor ecx,ecx
mov esi,node_addr
.get_mac_loop:
lea edx,[ebp+SIS900_rfcr]
mov eax,ecx
shl eax,SIS900_RFADDR_shift
out dx,eax
lea edx,[ebp+SIS900_rfdr]
in eax,dx
mov [esi],ax
add esi,2
inc ecx
cmp ecx,3
jne .get_mac_loop
; Enable packet filtering
;lea edx,[ebp+SIS900_rfcr]
;mov eax,edi
;or eax,SIS900_RFEN
;out dx, eax
;*******Debug Print MAC ID to debug window**********************
if defined SIS900_DEBUG
mov esi,SIS900_Debug_Str_GetMac_Address
call sys_msg_board_str
mov edx, node_addr
call Create_Mac_String
end if
ret
;***************************************************************************
;* Function: sis900_read_eeprom
;*
;* Description: reads and returns a given location from EEPROM
;*
;* Arguments: eax - location: requested EEPROM location
;*
;* Returns: eax : contents of requested EEPROM location
;*
; Read Serial EEPROM through EEPROM Access Register, Note that location is
; in word (16 bits) unit */
;done+
;***************************************************************************
sis900_read_eeprom:
push esi
push edx
push ecx
push ebx
mov ebp,[io_addr]
mov ebx, eax ;location of Mac byte to read
or ebx, SIS900_EEread ;
lea edx,[ebp+SIS900_mear] ; Eeprom access register
xor eax, eax ; start send
out dx,eax
call SIS900_Eeprom_Delay_1
mov eax, SIS900_EECLK
out dx, eax
call SIS900_Eeprom_Delay_1
;************ Shift the read command (9) bits out. *********
mov cl, 8 ;
sis900_read_eeprom_Send:
mov eax, 1
shl eax, cl
and eax, ebx
jz SIS900_Read_Eeprom_8
mov eax, 9
jmp SIS900_Read_Eeprom_9
SIS900_Read_Eeprom_8:
mov eax, 8
SIS900_Read_Eeprom_9:
out dx, eax
call SIS900_Eeprom_Delay_1
or eax, SIS900_EECLK
out dx, eax
call SIS900_Eeprom_Delay_1
cmp cl, 0
je sis900_read_eeprom_Send_Done
dec cl
jmp sis900_read_eeprom_Send
;*********************
sis900_read_eeprom_Send_Done:
mov eax, SIS900_EECS ;
out dx, eax
call SIS900_Eeprom_Delay_1
;********** Read 16-bits of data in ***************
mov cx, 16 ;16 bits to read
sis900_read_eeprom_Send2:
mov eax, SIS900_EECS
out dx, eax
call SIS900_Eeprom_Delay_1
or eax, SIS900_EECLK
out dx, eax
call SIS900_Eeprom_Delay_1
in eax, dx
shl ebx, 1
and eax, SIS900_EEDO
jz SIS900_Read_Eeprom_0
or ebx, 1
SIS900_Read_Eeprom_0:
dec cx
jnz sis900_read_eeprom_Send2
;************** Terminate the EEPROM access. **************
xor eax, eax
out dx, eax
call SIS900_Eeprom_Delay_1
mov eax, SIS900_EECLK
out dx, eax
mov eax, ebx
and eax, 0x0000ffff ;return only 16 bits
pop ebx
pop ecx
pop edx
pop esi
ret
;***************************************************************************
; Function
; SIS900_Eeprom_Delay_1
; Description
;
;
;
;
;***************************************************************************
SIS900_Eeprom_Delay_1:
push eax
in eax, dx
pop eax
ret
 
;***************************************************************************
; Function
; SIS900_poll
; Description
; polls card to see if there is a packet waiting
;
; Currently only supports one descriptor per packet, if packet is fragmented
; between multiple descriptors you will lose part of the packet
;***************************************************************************
if defined SIS900_DEBUG
SIS900_Debug_Pull_Packet_good db 'Good Packet Waiting: ',13,10,0
SIS900_Debug_Pull_Bad_Packet_Status db 'Bad Packet Waiting: Status',13,10,0
SIS900_Debug_Pull_Bad_Packet_Size db 'Bad Packet Waiting: Size',13,10,0
end if
SIS900_poll:
;**************Get Status **************
xor eax, eax ;get RX_Status
mov [eth_rx_data_len], ax
mov al, [cur_rx] ;find current discriptor
imul eax, 12 ;
mov ecx, [rxd+eax+4] ; get receive status
;**************Check Status **************
mov ebx, ecx ;move status
;Check RX_Status to see if packet is waiting
and ebx, 0x80000000
jnz SIS900_poll_IS_packet
ret
;**********There is a packet waiting check it for errors**************
SIS900_poll_IS_packet:
mov ebx, ecx ;move status
and ebx, 0x67C0000 ;see if there are any errors
jnz SIS900_Poll_Error_Status
;**************Check size of packet*************
and ecx, SIS900_DSIZE ;get packet size minus CRC
cmp cx, SIS900_CRC_SIZE
;make sure packet contains data
jle SIS900_Poll_Error_Size
;*******Copy Good Packet to receive buffer******
sub cx, SIS900_CRC_SIZE ;dont want crc
mov word [eth_rx_data_len], cx ;save size of packet
;**********Continue copying packet****************
push ecx
; first copy dword-wise, divide size by 4
shr ecx, 2
mov esi, [rxd+eax+8] ; set source
add esi, OS_BASE ; get linear address
mov edi, Ether_buffer ; set destination
cld ; clear direction
rep movsd ; copy the dwords
pop ecx
and ecx, 3 ;
rep movsb
;********Debug, tell user we have a good packet*************
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Pull_Packet_good
call sys_msg_board_str
end if
jmp SIS900_Poll_Cnt ;
;*************Error occured let user know through debug window***********
SIS900_Poll_Error_Status:
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Pull_Bad_Packet_Status
call sys_msg_board_str
end if
jmp SIS900_Poll_Cnt
SIS900_Poll_Error_Size:
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Pull_Bad_Packet_Size
call sys_msg_board_str
end if
;*************Increment to next available descriptor**************
SIS900_Poll_Cnt:
;Reset status, allow ethernet card access to descriptor
mov ecx, RX_BUFF_SZ
mov [rxd+eax+4], ecx ;
inc [cur_rx] ;get next descriptor
and [cur_rx],3 ;only 4 descriptors 0-3
;******Enable Receiver************
mov ebp, [io_addr] ; Base Address
lea edx,[ebp+SIS900_cr] ; Command Register offset
in eax, dx ; Get current Command Register
or eax, SIS900_RxENA ;Enable Receive
out dx, eax
ret
;***************************************************************************
; Function
; SIS900_transmit
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
;
; only one transmit descriptor is used
;
;***************************************************************************
if defined SIS900_DEBUG
SIS900_Debug_Transmit_Packet db 'Transmitting Packet: ',13,10,0
SIS900_Debug_Transmit_Packet_Err db 'Transmitting Packet Error: ',13,10,0
end if
str1 db 'Transmitting packet:',13,10,0
str2 db ' ',0
SIS900_transmit:
mov ebp, [io_addr] ; Base Address
;******** Stop the transmitter ********
lea edx,[ebp+SIS900_cr] ; Command Register offset
in eax, dx ; Get current Command Register
or eax, SIS900_TxDIS ; Disable Transmitter
out dx, eax
;*******load Transmit Descriptor Register *******
lea edx,[ebp+SIS900_txdp]
mov eax, txd - OS_BASE
out dx, eax
;******* copy packet to descriptor*******
push esi
mov esi, edi ;copy destination addess
mov edi, txb
cld
movsd
movsw
mov esi, node_addr ;copy my mac address
movsd
movsw
mov [edi], bx ;copy packet type
add edi, 2
pop esi ;restore pointer to source of packet
push ecx ;save packet size
shr ecx, 2 ;divide by 4, size in bytes send in dwords
rep movsd ;copy data to decriptor
pop ecx ;restore packet size
push ecx ;save packet size
and ecx, 3 ;last three bytes if not a multiple of 4
rep movsb
;**************set length tag**************
pop ecx ;restore packet size
add ecx, SIS900_ETH_HLEN ;add header to length
and ecx, SIS900_DSIZE ;
;**************pad to minimum packet size **************not needed
;cmp ecx, SIS900_ETH_ZLEN
;jge SIS900_transmit_Size_Ok
;push ecx
;mov ebx, SIS900_ETH_ZLEN
;sub ebx, ecx
;mov ecx, ebx
;rep movsb
;pop ecx
SIS900_transmit_Size_Ok:
mov [txd+4], dword 0x80000000 ;card owns descriptor
or [txd+4], ecx ;set size of packet
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Transmit_Packet
call sys_msg_board_str
end if
;***************restart the transmitter ********
lea edx,[ebp+SIS900_cr]
in eax, dx ; Get current Command Register
or eax, SIS900_TxENA ; Enable Transmitter
out dx, eax
;****make sure packet transmitted successfully****
; mov esi,10
; call delay_ms
mov eax, [txd+4]
and eax, 0x6200000
jz SIS900_transmit_OK
;**************Tell user there was an error through debug window
if defined SIS900_DEBUG
mov esi, SIS900_Debug_Transmit_Packet_Err
call sys_msg_board_str
end if
SIS900_transmit_OK:
;******** Disable interrupts by clearing the interrupt mask. ********
lea edx,[ebp+SIS900_imr] ; Interupt Mask Register
xor eax, eax
out dx,eax
ret
 
;***************************************************************************
;* Function: Create_Mac_String
;*
;* Description: Converts the 48 bit value to a string for display
;*
;* String Format: XX:XX:XX:XX:XX:XX
;*
;* Arguments: node_addr is location of 48 bit MAC ID
;*
;* Returns: Prints string to general debug window
;*
;*
;done
;***************************************************************************
if defined SIS900_DEBUG
 
SIS900_Char_String db '0','1','2','3','4','5','6','7','8','9'
db 'A','B','C','D','E','F'
Mac_str_build: times 20 db 0
Create_Mac_String:
pusha
xor ecx, ecx
Create_Mac_String_loop:
mov al,byte [edx+ecx];[node_addr+ecx]
push eax
shr eax, 4
and eax, 0x0f
mov bl, byte [SIS900_Char_String+eax]
mov [Mac_str_build+ecx*3], bl
pop eax
and eax, 0x0f
mov bl, byte [SIS900_Char_String+eax]
mov [Mac_str_build+1+ecx*3], bl
cmp ecx, 5
je Create_Mac_String_done
mov bl, ':'
mov [Mac_str_build+2+ecx*3], bl
inc ecx
jmp Create_Mac_String_loop
Create_Mac_String_done: ;Insert CR and Zero Terminate
mov [Mac_str_build+2+ecx*3],byte 13
mov [Mac_str_build+3+ecx*3],byte 10
mov [Mac_str_build+4+ecx*3],byte 0
mov esi, Mac_str_build
call sys_msg_board_str ;Print String to message board
popa
ret
end if
;***************************************************************************
;* Set device to be a busmaster in case BIOS neglected to do so.
;* Also adjust PCI latency timer to a reasonable value, 64.
;***************************************************************************
SIS900_adjust_pci_device:
;*******Get current setting************************
mov al, 2 ;read a word
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, 0x04 ;from command Register
call pci_read_reg
;******see if its already set as bus master********
mov bx, ax
and bx,5
cmp bx,5
je SIS900_adjust_pci_device_Latency
;******Make card a bus master*******
mov cx, ax ;value to write
mov bh, [pci_dev]
mov al, 2 ;write a word
or cx,5
mov ah, [pci_bus]
mov bl, 0x04 ;to command register
call pci_write_reg
;******Check latency setting***********
SIS900_adjust_pci_device_Latency:
;*******Get current latency setting************************
mov al, 1 ;read a byte
mov bh, [pci_dev]
mov ah, [pci_bus]
mov bl, 0x0D ;from Lantency Timer Register
call pci_read_reg
;******see if its aat least 64 clocks********
cmp ax,64
jge SIS900_adjust_pci_device_Done
;******Set latency to 32 clocks*******
mov cx, 64 ;value to write
mov bh, [pci_dev]
mov al, 1 ;write a byte
mov ah, [pci_bus]
mov bl, 0x0D ;to Lantency Timer Register
call pci_write_reg
;******Check latency setting***********
SIS900_adjust_pci_device_Done:
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/eth_drv/drivers/rtl8029.inc
0,0 → 1,959
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; RTL8029.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.2 31 July 2002 ;;
;; ;;
;; This driver is based on the ns8390 driver from ;;
;; the etherboot 5.0.6 project. The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2002 Mike Hibbett, ;;
;; mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; While this implementation handles only PCI bus RTL8029 ;;
;; hardware, it can be easily adapted to other NE2000 clone ;;
;; products. I just dont have any to try! ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;********************************************************************
; Interface
; rtl8029_reset
; rtl8029_probe
; rtl8029_poll
; rtl8029_transmit
;
;********************************************************************
 
 
 
 
;**************************************************************************
; 8390 Register Definitions
;**************************************************************************
D8390_P0_COMMAND equ 0x00
D8390_P0_PSTART equ 0x01
D8390_P0_PSTOP equ 0x02
D8390_P0_BOUND equ 0x03
D8390_P0_TSR equ 0x04
D8390_P0_TPSR equ 0x04
D8390_P0_TBCR0 equ 0x05
D8390_P0_TBCR1 equ 0x06
D8390_P0_ISR equ 0x07
D8390_P0_RSAR0 equ 0x08
D8390_P0_RSAR1 equ 0x09
D8390_P0_RBCR0 equ 0x0A
D8390_P0_RBCR1 equ 0x0B
D8390_P0_RSR equ 0x0C
D8390_P0_RCR equ 0x0C
D8390_P0_TCR equ 0x0D
D8390_P0_DCR equ 0x0E
D8390_P0_IMR equ 0x0F
D8390_P1_COMMAND equ 0x00
D8390_P1_PAR0 equ 0x01
D8390_P1_PAR1 equ 0x02
D8390_P1_PAR2 equ 0x03
D8390_P1_PAR3 equ 0x04
D8390_P1_PAR4 equ 0x05
D8390_P1_PAR5 equ 0x06
D8390_P1_CURR equ 0x07
D8390_P1_MAR0 equ 0x08
 
D8390_COMMAND_PS0 equ 0x0 ; Page 0 select
D8390_COMMAND_PS1 equ 0x40 ; Page 1 select
D8390_COMMAND_PS2 equ 0x80 ; Page 2 select
D8390_COMMAND_RD2 equ 0x20 ; Remote DMA control
D8390_COMMAND_RD1 equ 0x10
D8390_COMMAND_RD0 equ 0x08
D8390_COMMAND_TXP equ 0x04 ; transmit packet
D8390_COMMAND_STA equ 0x02 ; start
D8390_COMMAND_STP equ 0x01 ; stop
 
D8390_COMMAND_RD2_STA equ 0x22
D8390_COMMAND_RD2_STP equ 0x21
D8390_COMMAND_RD1_STA equ 0x12
D8390_COMMAND_RD0_STA equ 0x0A
D8390_COMMAND_PS0_RD2_STP equ 0x21
D8390_COMMAND_PS1_RD2_STP equ 0x61
D8390_COMMAND_PS0_RD2_STA equ 0x22
D8390_COMMAND_PS0_TXP_RD2_STA equ 0x26
 
D8390_RCR_MON equ 0x20 ; monitor mode
 
D8390_DCR_FT1 equ 0x40
D8390_DCR_LS equ 0x08 ; Loopback select
D8390_DCR_WTS equ 0x01 ; Word transfer select
 
D8390_DCR_FT1_LS equ 0x48
D8390_DCR_WTS_FT1_LS equ 0x49
 
D8390_ISR_PRX equ 0x01 ; successful recv
D8390_ISR_PTX equ 0x02 ; successful xmit
D8390_ISR_RXE equ 0x04 ; receive error
D8390_ISR_TXE equ 0x08 ; transmit error
D8390_ISR_OVW equ 0x10 ; Overflow
D8390_ISR_CNT equ 0x20 ; Counter overflow
D8390_ISR_RDC equ 0x40 ; Remote DMA complete
D8390_ISR_RST equ 0x80 ; reset
 
D8390_RSTAT_PRX equ 0x01 ; successful recv
D8390_RSTAT_CRC equ 0x02 ; CRC error
D8390_RSTAT_FAE equ 0x04 ; Frame alignment error
D8390_RSTAT_OVER equ 0x08 ; FIFO overrun
 
D8390_TXBUF_SIZE equ 6
D8390_RXBUF_END equ 32
D8390_PAGE_SIZE equ 256
 
ETH_ALEN equ 6
ETH_HLEN equ 14
ETH_ZLEN equ 60
ETH_FRAME_LEN equ 1514
 
FLAG_PIO equ 0x01
FLAG_16BIT equ 0x02
ASIC_PIO equ 0
 
VENDOR_NONE equ 0
VENDOR_WD equ 1
VENDOR_NOVELL equ 2
VENDOR_3COM equ 3
 
NE_ASIC_OFFSET equ 0x10
NE_RESET equ 0x0F ; Used to reset card
NE_DATA equ 0x00 ; Used to read/write NIC mem
 
MEM_8192 equ 32
MEM_16384 equ 64
MEM_32768 equ 128
 
ISA_MAX_ADDR equ 0x400
 
uglobal
eth_flags: db 0
eth_vendor: db 0
eth_nic_base: dw 0
eth_asic_base: dw 0
eth_memsize: db 0
eth_rx_start: db 0
eth_tx_start: db 0
eth_bmem: dd 0
eth_rmem: dd 0
romdata: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
endg
 
iglobal
test_data: db 'NE*000 memory',0
test_buffer: db ' ',0
endg
 
uglobal
eth_type: dw 0
pkthdr: db 0,0,0,0 ; status, next, (short) len
pktoff: dw 0
eth_rx_data_ptr: dd 0
eth_tmp_len: dw 0
endg
 
 
 
;***************************************************************************
; Function
; eth_pio_read
;
; Description
; Read a frame from the ethernet card via Programmed I/O
; src in ebx
; cnt in ecx
; dst in edi
;***************************************************************************
eth_pio_read:
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epr_001
 
inc ecx
and ecx, 0xFFFFFFFE
 
epr_001:
mov al, D8390_COMMAND_RD2_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
 
mov al, cl
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR0
out dx, al
 
mov al, ch
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR1
out dx, al
 
mov al, bl
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR0
out dx, al
 
mov al, bh
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR1
out dx, al
 
mov al, D8390_COMMAND_RD0_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
 
mov dx, [eth_asic_base]
add dx, ASIC_PIO
 
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epr_003
 
shr ecx, 1
 
epr_002:
; 2 bytes at a time
in ax, dx
mov [edi], ax
add edi, 2
loop epr_002
ret
 
epr_003:
; 1 byte at a time
in al, dx
mov [edi], al
inc edi
loop epr_003
ret
 
 
 
 
;***************************************************************************
; Function
; eth_pio_write
;
; Description
; writes a frame to the ethernet card via Programmed I/O
; dst in ebx
; cnt in ecx
; src in esi
;***************************************************************************
eth_pio_write:
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epw_001
 
inc ecx
and ecx, 0xFFFFFFFE
 
epw_001:
mov al, D8390_COMMAND_RD2_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
 
mov al, D8390_ISR_RDC
mov dx, [eth_nic_base]
add dx, D8390_P0_ISR
out dx, al
 
 
mov al, cl
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR0
out dx, al
 
mov al, ch
mov dx, [eth_nic_base]
add dx, D8390_P0_RBCR1
out dx, al
 
mov al, bl
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR0
out dx, al
 
mov al, bh
mov dx, [eth_nic_base]
add dx, D8390_P0_RSAR1
out dx, al
 
mov al, D8390_COMMAND_RD1_STA
mov dx, [eth_nic_base]
add dx, D8390_P0_COMMAND
out dx, al
 
mov dx, [eth_asic_base]
add dx, ASIC_PIO
 
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, 0
je epw_003
 
shr ecx, 1
 
epw_002:
; 2 bytes at a time
mov ax, [esi]
add esi, 2
out dx, ax
 
loop epw_002
jmp epw_004
 
epw_003:
; 1 byte at a time
mov al, [esi]
inc esi
out dx, al
loop epw_003
 
epw_004:
mov dx, [eth_nic_base]
add dx, D8390_P0_ISR
 
epw_005:
in al, dx
and al, D8390_ISR_RDC
cmp al, D8390_ISR_RDC
jne epw_005
 
ret
 
 
 
;***************************************************************************
; Function
; rtl8029_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; No inputs
; All registers destroyed
;
;***************************************************************************
rtl8029_reset:
mov bx, [eth_nic_base]
 
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_RD2_STP
out dx, al
 
mov dx, bx
add dx, D8390_P0_DCR
mov al, [eth_flags]
and al, FLAG_16BIT
cmp al, FLAG_16BIT
jne nsr_001
 
mov al, 0x49
jmp nsr_002
 
nsr_001:
mov al, 0x48
 
nsr_002:
out dx, al
 
xor al, al
 
mov dx, bx
add dx, D8390_P0_RBCR0
out dx, al
 
mov dx, bx
add dx, D8390_P0_RBCR1
out dx, al
 
mov dx, bx
add dx, D8390_P0_RCR
mov al, 0x20
out dx, al
 
mov dx, bx
add dx, D8390_P0_TCR
mov al, 2
out dx, al
 
mov dx, bx
add dx, D8390_P0_TPSR
mov al, [eth_tx_start]
out dx, al
 
mov dx, bx
add dx, D8390_P0_PSTART
mov al, [eth_rx_start]
out dx, al
 
mov dx, bx
add dx, D8390_P0_PSTOP
mov al, [eth_memsize]
out dx, al
 
mov dx, bx
add dx, D8390_P0_BOUND
mov al, [eth_memsize]
dec al
out dx, al
 
mov dx, bx
add dx, D8390_P0_ISR
mov al, 0xff
out dx, al
 
mov dx, bx
add dx, D8390_P0_IMR
xor al, al
out dx, al
 
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS1_RD2_STP
out dx, al
 
mov dx, bx
add dx, D8390_P1_PAR0
mov esi, node_addr
mov ecx, ETH_ALEN
 
nsr_003:
mov al, [esi]
out dx, al
 
inc esi
inc dx
loop nsr_003
 
mov dx, bx
add dx, D8390_P1_MAR0
mov ecx, ETH_ALEN
 
mov al, 0xff
 
nsr_004:
out dx, al
inc dx
loop nsr_004
 
mov dx, bx
add dx, D8390_P1_CURR
mov al, [eth_rx_start]
out dx, al
 
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_RD2_STA
out dx, al
 
mov dx, bx
add dx, D8390_P0_ISR
mov al, 0xff
out dx, al
 
mov dx, bx
add dx, D8390_P0_TCR
mov al, 0
out dx, al
 
mov dx, bx
add dx, D8390_P0_RCR
mov al, 4
out dx, al
 
ret
 
 
 
;***************************************************************************
; Function
; rtl8029_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
;
;***************************************************************************
rtl8029_probe:
mov eax, [io_addr]
mov [eth_nic_base], ax ; The IO address space is 16 bit only
 
mov al, VENDOR_NONE
mov [eth_vendor], al
 
mov al, [eth_vendor]
cmp al, VENDOR_NONE
 
jne ep_check_have_vendor
xor eax, eax
mov [eth_bmem], eax
 
mov al, FLAG_PIO
mov [eth_flags], al
 
mov ax, [eth_nic_base]
add ax, NE_ASIC_OFFSET
mov [eth_asic_base], ax
 
mov al, MEM_16384
mov [eth_memsize], al
 
mov al, 32
mov [eth_tx_start], al
 
add al, D8390_TXBUF_SIZE
mov [eth_rx_start], al
 
mov dx, [eth_asic_base]
add dx, NE_RESET
 
in al, dx
out dx, al
 
in al, 0x84
 
mov bx, [eth_nic_base]
 
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_RD2_STP
out dx, al
 
mov dx, bx
add dx, D8390_P0_RCR
mov al, D8390_RCR_MON
out dx, al
 
mov dx, bx
add dx, D8390_P0_DCR
mov al, D8390_DCR_FT1_LS
out dx, al
 
mov dx, bx
add dx, D8390_P0_PSTART
mov al, MEM_8192
out dx, al
 
mov dx, bx
add dx, D8390_P0_PSTOP
mov al, MEM_16384
out dx, al
 
mov esi, test_data
mov ebx, 8192
mov ecx, 14
call eth_pio_write
 
mov ebx, 8192
mov ecx, 14
mov edi, test_buffer
call eth_pio_read
 
mov esi, test_buffer
mov edi, test_data
mov ecx, 13
cld
rep cmpsb
 
je ep_set_vendor
 
mov al, [eth_flags]
or al, FLAG_16BIT
mov [eth_flags], al
 
mov al, MEM_32768
mov [eth_memsize], al
 
mov al, 64
mov [eth_tx_start], al
 
add al, D8390_TXBUF_SIZE
mov [eth_rx_start], al
 
mov bx, [eth_nic_base]
 
mov dx, bx
add dx, D8390_P0_DCR
mov al, D8390_DCR_WTS_FT1_LS
out dx, al
 
mov dx, bx
add dx, D8390_P0_PSTART
mov al, MEM_16384
out dx, al
 
mov dx, bx
add dx, D8390_P0_PSTOP
mov al, MEM_32768
out dx, al
 
mov esi, test_data
mov ebx, 16384
mov ecx, 14
call eth_pio_write
 
mov ebx, 16384
mov ecx, 14
mov edi, test_buffer
call eth_pio_read
 
mov esi, test_buffer
mov edi, test_data
mov ecx, 13
cld
rep cmpsb
 
ep_set_vendor:
; this bit is odd - probably left over from my hacking
mov ax, [eth_nic_base]
cmp ax, 0
je rtl8029_exit
cmp ax, ISA_MAX_ADDR
jbe ep_001
mov al, [eth_flags]
or al, FLAG_16BIT
mov [eth_flags], al
 
ep_001:
mov al, VENDOR_NOVELL
mov [eth_vendor], al
 
mov ebx, 0
mov ecx, 16
mov edi, romdata
call eth_pio_read
 
 
mov ecx, ETH_ALEN
mov esi, romdata
mov edi, node_addr
 
mov bl, [eth_flags]
and bl, FLAG_16BIT
 
ep_002:
mov al, [esi]
mov [edi], al
 
inc edi
inc esi
cmp bl, FLAG_16BIT
jne ep_003
 
inc esi
 
ep_003:
loop ep_002
 
ep_check_have_vendor:
mov al, [eth_vendor]
cmp al, VENDOR_NONE
je rtl8029_exit
 
cmp al, VENDOR_3COM
je ep_reset_card
 
mov eax, [eth_bmem]
mov [eth_rmem], eax
 
ep_reset_card:
; Reset the card
call rtl8029_reset
 
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
 
rtl8029_exit:
ret
 
 
 
;***************************************************************************
; Function
; rtl8029_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
;
;***************************************************************************
rtl8029_poll:
mov eax, Ether_buffer
mov [eth_rx_data_ptr], eax
 
mov bx, [eth_nic_base]
 
mov dx, bx
add dx, D8390_P0_RSR
in al, dx
 
and al, D8390_RSTAT_PRX
cmp al, D8390_RSTAT_PRX
jne nsp_exit
 
mov dx, bx
add dx, D8390_P0_BOUND
in al, dx
inc al
 
cmp al, [eth_memsize]
jb nsp_001
 
mov al, [eth_rx_start]
 
nsp_001:
mov ch, al
 
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS1
out dx, al
 
mov dx, bx
add dx, D8390_P1_CURR
in al, dx ; get current page
mov cl, al
 
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0
out dx, al
 
cmp cl, [eth_memsize]
jb nsp_002
 
mov cl, [eth_rx_start]
 
nsp_002:
cmp cl, ch
je nsp_exit
 
xor ax, ax
mov ah, ch
 
mov [pktoff], ax
 
mov al, [eth_flags]
and al, FLAG_PIO
cmp al, FLAG_PIO
jne nsp_003
 
movzx ebx, word [pktoff]
mov edi, pkthdr
mov ecx, 4
call eth_pio_read
jmp nsp_004
 
nsp_003:
mov edi, [eth_rmem]
movzx eax, word [pktoff]
add edi, eax
mov eax, [edi]
mov [pkthdr], eax
 
nsp_004:
mov ax, [pktoff]
add ax, 4
mov [pktoff], ax
 
mov ax, [pkthdr + 2]
sub ax, 4
 
mov [eth_tmp_len], ax
 
cmp ax, ETH_ZLEN
jb nsp_exit
 
cmp ax, ETH_FRAME_LEN
ja nsp_exit
 
mov al, [pkthdr]
and al, D8390_RSTAT_PRX
cmp al, D8390_RSTAT_PRX
jne nsp_exit
 
; Right, we can now get the data
 
mov ax, [eth_tmp_len]
mov [eth_rx_data_len], ax
 
xor ebx, ebx
mov bh, [eth_memsize]
sub bx, [pktoff]
 
cmp [eth_tmp_len], bx
jbe nsp_005
 
mov al, [eth_flags]
and al, FLAG_PIO
cmp al, FLAG_PIO
jne nsp_006
 
push ebx
mov ecx, ebx
xor ebx, ebx
mov bx, [pktoff]
mov edi, [eth_rx_data_ptr]
call eth_pio_read
pop ebx
jmp nsp_007
 
nsp_006:
; Not implemented, as we are using PIO mode on this card
 
nsp_007:
xor ax, ax
mov ah, [eth_rx_start]
mov [pktoff], ax
 
mov eax, [eth_rx_data_ptr]
add eax, ebx
mov [eth_rx_data_ptr], eax
 
mov ax, [eth_tmp_len]
sub ax, bx
mov [eth_tmp_len], ax
 
nsp_005:
mov al, [eth_flags]
and al, FLAG_PIO
cmp al, FLAG_PIO
jne nsp_008
 
xor ebx, ebx
mov bx, [pktoff]
xor ecx, ecx
mov cx, [eth_tmp_len]
mov edi, [eth_rx_data_ptr]
call eth_pio_read
jmp nsp_009
 
nsp_008:
; Not implemented, as we are using PIO mode on this card
 
nsp_009:
mov al, [pkthdr+1]
cmp al, [eth_rx_start]
jne nsp_010
 
mov al, [eth_memsize]
 
nsp_010:
mov dx, [eth_nic_base]
add dx, D8390_P0_BOUND
dec al
out dx, al
 
nsp_exit:
ret
 
 
 
;***************************************************************************
; Function
; rtl8029_transmit
;
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
;
;***************************************************************************
rtl8029_transmit:
mov [eth_type], bx
 
pusha
 
mov esi, edi
xor bx, bx
mov bh, [eth_tx_start]
mov ecx, ETH_ALEN
call eth_pio_write
 
mov esi, node_addr
xor bx, bx
mov bh, [eth_tx_start]
add bx, ETH_ALEN
mov ecx, ETH_ALEN
call eth_pio_write
 
mov esi, eth_type
xor bx, bx
mov bh, [eth_tx_start]
add bx, ETH_ALEN
add bx, ETH_ALEN
mov ecx, 2
call eth_pio_write
 
popa
 
xor bx, bx
mov bh, [eth_tx_start]
add bx, ETH_HLEN
push ecx
call eth_pio_write
pop ecx
 
add ecx, ETH_HLEN
cmp ecx, ETH_ZLEN
jae nst_001
 
mov ecx, ETH_ZLEN
 
nst_001:
push ecx
 
mov bx, [eth_nic_base]
 
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_RD2_STA
out dx, al
 
mov dx, bx
add dx, D8390_P0_TPSR
mov al, [eth_tx_start]
out dx, al
 
pop ecx
 
mov dx, bx
add dx, D8390_P0_TBCR0
mov al, cl
out dx, al
 
mov dx, bx
add dx, D8390_P0_TBCR1
mov al, ch
out dx, al
 
mov dx, bx
add dx, D8390_P0_COMMAND
mov al, D8390_COMMAND_PS0_TXP_RD2_STA
out dx, al
 
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/eth_drv/drivers/rtl8139.inc
0,0 → 1,621
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; RTL8139.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 0.2 11 August 2003 ;;
;; ;;
;; Driver for chips of RealTek 8139 family ;;
;; References: ;;
;; www.realtek.com.hw - data sheets ;;
;; rtl8139.c - linux driver ;;
;; 8139too.c - linux driver ;;
;; ethernet driver template by Mike Hibbett ;;
;; ;;
;; The copyright statement is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; Copyright 2003 Endre Kozma, ;;
;; endre.kozma@axelero.hu ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; 10.01.2007 Bugfix for l8139_transmit from Paolo Franchetti ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
ETH_ALEN equ 6
ETH_HLEN equ (2 * ETH_ALEN + 2)
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for
; mininmum 64bytes frame length
 
PCI_REG_COMMAND equ 0x04 ; command register
PCI_BIT_PIO equ 0 ; bit0: io space control
PCI_BIT_MMIO equ 1 ; bit1: memory space control
PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master
 
RTL8139_REG_MAR0 equ 0x08 ; multicast filter register 0
RTL8139_REG_MAR4 equ 0x0c ; multicast filter register 4
RTL8139_REG_TSD0 equ 0x10 ; transmit status of descriptor
RTL8139_REG_TSAD0 equ 0x20 ; transmit start address of descriptor
RTL8139_REG_RBSTART equ 0x30 ; RxBuffer start address
RTL8139_REG_COMMAND equ 0x37 ; command register
RTL8139_REG_CAPR equ 0x38 ; current address of packet read
RTL8139_REG_IMR equ 0x3c ; interrupt mask register
RTL8139_REG_ISR equ 0x3e ; interrupt status register
RTL8139_REG_TXCONFIG equ 0x40 ; transmit configuration register
RTL8139_REG_TXCONFIG_0 equ 0x40 ; transmit configuration register 0
RTL8139_REG_TXCONFIG_1 equ 0x41 ; transmit configuration register 1
RTL8139_REG_TXCONFIG_2 equ 0x42 ; transmit configuration register 2
RTL8139_REG_TXCONFIG_3 equ 0x43 ; transmit configuration register 3
RTL8139_REG_RXCONFIG equ 0x44 ; receive configuration register 0
RTL8139_REG_RXCONFIG_0 equ 0x44 ; receive configuration register 0
RTL8139_REG_RXCONFIG_1 equ 0x45 ; receive configuration register 1
RTL8139_REG_RXCONFIG_2 equ 0x46 ; receive configuration register 2
RTL8139_REG_RXCONFIG_3 equ 0x47 ; receive configuration register 3
RTL8139_REG_MPC equ 0x4c ; missed packet counter
RTL8139_REG_9346CR equ 0x50 ; serial eeprom 93C46 command register
RTL8139_REG_CONFIG1 equ 0x52 ; configuration register 1
RTL8139_REG_CONFIG4 equ 0x5a ; configuration register 4
RTL8139_REG_HLTCLK equ 0x5b ; undocumented halt clock register
RTL8139_REG_BMCR equ 0x62 ; basic mode control register
RTL8139_REG_ANAR equ 0x66 ; auto negotiation advertisement register
 
; 5.1 packet header
RTL8139_BIT_RUNT equ 4 ; total packet length < 64 bytes
RTL8139_BIT_LONG equ 3 ; total packet length > 4k
RTL8139_BIT_CRC equ 2 ; crc error occured
RTL8139_BIT_FAE equ 1 ; frame alignment error occured
RTL8139_BIT_ROK equ 0 ; received packet is ok
; 5.4 command register
RTL8139_BIT_RST equ 4 ; reset bit
RTL8139_BIT_RE equ 3 ; receiver enabled
RTL8139_BIT_TE equ 2 ; transmitter enabled
RTL8139_BIT_BUFE equ 0 ; rx buffer is empty, no packet stored
; 5.6 interrupt status register
RTL8139_BIT_ISR_TOK equ 2 ; transmit ok
RTL8139_BIT_ISR_RER equ 1 ; receive error interrupt
RTL8139_BIT_ISR_ROK equ 0 ; receive ok
; 5.7 transmit configyration register
RTL8139_BIT_TX_MXDMA equ 8 ; Max DMA burst size per Tx DMA burst
RTL8139_BIT_TXRR equ 4 ; Tx Retry count 16+(TXRR*16)
; 5.8 receive configuration register
RTL8139_BIT_RXFTH equ 13 ; Rx fifo threshold
RTL8139_BIT_RBLEN equ 11 ; Ring buffer length indicator
RTL8139_BIT_RX_MXDMA equ 8 ; Max DMA burst size per Rx DMA burst
RTL8139_BIT_NOWRAP equ 7 ; transfered data wrapping
RTL8139_BIT_9356SEL equ 6 ; eeprom selector 9346/9356
RTL8139_BIT_AER equ 5 ; accept error packets
RTL8139_BIT_AR equ 4 ; accept runt packets
RTL8139_BIT_AB equ 3 ; accept broadcast packets
RTL8139_BIT_AM equ 2 ; accept multicast packets
RTL8139_BIT_APM equ 1 ; accept physical match packets
RTL8139_BIT_AAP equ 0 ; accept all packets
; 5.9 93C46/93C56 command register
RTL8139_BIT_93C46_EEM1 equ 7 ; RTL8139 eeprom operating mode1
RTL8139_BIT_93C46_EEM0 equ 6 ; RTL8139 eeprom operating mode0
RTL8139_BIT_93C46_EECS equ 3 ; chip select
RTL8139_BIT_93C46_EESK equ 2 ; serial data clock
RTL8139_BIT_93C46_EEDI equ 1 ; serial data input
RTL8139_BIT_93C46_EEDO equ 0 ; serial data output
; 5.11 configuration register 1
RTL8139_BIT_LWACT equ 4 ; see RTL8139_REG_CONFIG1
RTL8139_BIT_SLEEP equ 1 ; sleep bit at older chips
RTL8139_BIT_PWRDWN equ 0 ; power down bit at older chips
RTL8139_BIT_PMEn equ 0 ; power management enabled
; 5.14 configuration register 4
RTL8139_BIT_LWPTN equ 2 ; see RTL8139_REG_CONFIG4
; 6.2 transmit status register
RTL8139_BIT_ERTXTH equ 16 ; early TX threshold
RTL8139_BIT_TOK equ 15 ; transmit ok
RTL8139_BIT_OWN equ 13 ; tx DMA operation is completed
; 6.18 basic mode control register
RTL8139_BIT_ANE equ 12 ; auto negotiation enable
; 6.20 auto negotiation advertisement register
RTL8139_BIT_TXFD equ 8 ; 100base-T full duplex
RTL8139_BIT_TX equ 7 ; 100base-T
RTL8139_BIT_10FD equ 6 ; 10base-T full duplex
RTL8139_BIT_10 equ 5 ; 10base-T
RTL8139_BIT_SELECTOR equ 0 ; binary encoded selector CSMA/CD=00001
; RX/TX buffer size
RTL8139_RBLEN equ 0 ; 0==8K 1==16k 2==32k 3==64k
RTL8139_RX_BUFFER_SIZE equ (8192 shl RTL8139_RBLEN)
MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC
RTL8139_NUM_TX_DESC equ 4
RTL8139_TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE * RTL8139_NUM_TX_DESC)
RTL8139_TXRR equ 8 ; total retries = 16+(TXRR*16)
RTL8139_TX_MXDMA equ 6 ; 0==16 1==32 2==64 3==128
; 4==256 5==512 6==1024 7==2048
RTL8139_ERTXTH equ 8 ; in unit of 32 bytes e.g:(8*32)=256
RTL8139_RX_MXDMA equ 7 ; 0==16 1==32 2==64 3==128
; 4==256 5==512 6==1024 7==unlimited
RTL8139_RXFTH equ 7 ; 0==16 1==32 2==64 3==128
; 4==256 5==512 6==1024 7==no threshold
RTL8139_RX_CONFIG equ ((RTL8139_RBLEN shl RTL8139_BIT_RBLEN) \
or (RTL8139_RX_MXDMA shl RTL8139_BIT_RX_MXDMA) \
or (1 shl RTL8139_BIT_NOWRAP) \
or (RTL8139_RXFTH shl RTL8139_BIT_RXFTH) \
or (1 shl RTL8139_BIT_AB) or (1 shl RTL8139_BIT_APM) \
or (1 shl RTL8139_BIT_AER) or (1 shl RTL8139_BIT_AR) \
or (1 shl RTL8139_BIT_AM))
RTL8139_TX_TIMEOUT equ 30 ; 300 milliseconds timeout
 
EE_93C46_REG_ETH_ID equ 7 ; MAC offset
EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address
EE_93C56_READ_CMD equ (6 shl 8) ; 110b + 8bit address
EE_93C46_CMD_LENGTH equ 9 ; start bit + cmd + 6bit address
EE_93C56_CMD_LENGTH equ 11 ; start bit + cmd + 8bit ddress
 
VER_RTL8139 equ 1100000b
VER_RTL8139A equ 1110000b
; VER_RTL8139AG equ 1110100b
VER_RTL8139B equ 1111000b
VER_RTL8130 equ VER_RTL8139B
VER_RTL8139C equ 1110100b
VER_RTL8100 equ 1111010b
VER_RTL8100B equ 1110101b
VER_RTL8139D equ VER_RTL8100B
VER_RTL8139CP equ 1110110b
VER_RTL8101 equ 1110111b
 
IDX_RTL8139 equ 0
IDX_RTL8139A equ 1
IDX_RTL8139B equ 2
IDX_RTL8139C equ 3
IDX_RTL8100 equ 4
IDX_RTL8139D equ 5
IDX_RTL8139D equ 6
IDX_RTL8101 equ 7
 
 
; These two must be 4 byte aligned ( which they are )
rtl8139_rx_buff equ eth_data_start
rtl8139_tx_buff equ rtl8139_rx_buff + (RTL8139_RX_BUFFER_SIZE + MAX_ETH_FRAME_SIZE)
 
uglobal
align 4
rtl8139_rx_buff_offset: dd 0
curr_tx_desc dd 0
endg
 
iglobal
hw_ver_array: db VER_RTL8139, VER_RTL8139A, VER_RTL8139B, VER_RTL8139C
db VER_RTL8100, VER_RTL8139D, VER_RTL8139CP, VER_RTL8101
HW_VER_ARRAY_SIZE = $-hw_ver_array
endg
 
uglobal
hw_ver_id: db 0
endg
 
;***************************************************************************
; Function
; rtl8139_probe
; Description
; Searches for an ethernet card, enables it and clears the rx buffer
; If a card was found, it enables the ethernet -> TCPIP link
; Destroyed registers
; eax, ebx, ecx, edx
;
;***************************************************************************
rtl8139_probe:
; enable the device
mov al, 2
mov ah, [pci_bus]
mov bh, [pci_dev]
mov bl, PCI_REG_COMMAND
call pci_read_reg
mov cx, ax
or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO)
and cl, not (1 shl PCI_BIT_MMIO)
mov al, 2
mov ah, [pci_bus]
mov bh, [pci_dev]
mov bl, PCI_REG_COMMAND
call pci_write_reg
; get chip version
mov edx, [io_addr]
add edx, RTL8139_REG_TXCONFIG_2
in ax, dx
shr ah, 2
shr ax, 6
and al, 01111111b
mov ecx, HW_VER_ARRAY_SIZE-1
.chip_ver_loop:
cmp al, [hw_ver_array+ecx]
je .chip_ver_found
dec ecx
jns .chip_ver_loop
xor cl, cl ; default RTL8139
.chip_ver_found:
mov [hw_ver_id], cl
; wake up the chip
mov edx, [io_addr]
add edx, RTL8139_REG_HLTCLK
mov al, 'R' ; run the clock
out dx, al
; unlock config and BMCR registers
add edx, RTL8139_REG_9346CR - RTL8139_REG_HLTCLK
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0)
out dx, al
; enable power management
add edx, RTL8139_REG_CONFIG1 - RTL8139_REG_9346CR
in al, dx
cmp byte [hw_ver_id], IDX_RTL8139B
jl .old_chip
; set LWAKE pin to active high (default value).
; it is for Wake-On-LAN functionality of some motherboards.
; this signal is used to inform the motherboard to execute a wake-up process.
; only at newer chips.
or al, (1 shl RTL8139_BIT_PMEn)
and al, not (1 shl RTL8139_BIT_LWACT)
out dx, al
add edx, RTL8139_REG_CONFIG4 - RTL8139_REG_CONFIG1
in al, dx
and al, not (1 shl RTL8139_BIT_LWPTN)
out dx, al
jmp .finish_wake_up
.old_chip:
; wake up older chips
and al, not ((1 shl RTL8139_BIT_SLEEP) or (1 shl RTL8139_BIT_PWRDWN))
out dx, al
.finish_wake_up:
; lock config and BMCR registers
xor al, al
mov edx, [io_addr]
add edx, RTL8139_REG_9346CR
out dx, al
;***************************************************************************
; Function
; rt8139_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; Destroyed registers
; eax, ebx, ecx, edx
;
;***************************************************************************
rtl8139_reset:
mov edx, [io_addr]
add edx, RTL8139_REG_COMMAND
mov al, 1 shl RTL8139_BIT_RST
out dx, al
mov cx, 1000 ; wait no longer for the reset
.wait_for_reset:
in al, dx
test al, 1 shl RTL8139_BIT_RST
jz .reset_completed ; RST remains 1 during reset
dec cx
jns .wait_for_reset
.reset_completed:
; get MAC (hardware address)
mov ecx, 2
.mac_read_loop:
lea eax, [EE_93C46_REG_ETH_ID+ecx]
push ecx
call rtl8139_read_eeprom
pop ecx
mov [node_addr+ecx*2], ax
dec ecx
jns .mac_read_loop
; unlock config and BMCR registers
mov edx, [io_addr]
add edx, RTL8139_REG_9346CR
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0)
out dx, al
; initialize multicast registers (no filtering)
mov eax, 0xffffffff
add edx, RTL8139_REG_MAR0 - RTL8139_REG_9346CR
out dx, eax
add edx, RTL8139_REG_MAR4 - RTL8139_REG_MAR0
out dx, eax
; enable Rx/Tx
mov al, (1 shl RTL8139_BIT_RE) or (1 shl RTL8139_BIT_TE)
add edx, RTL8139_REG_COMMAND - RTL8139_REG_MAR4
out dx, al
; 32k Rxbuffer, unlimited dma burst, no wrapping, no rx threshold
; accept broadcast packets, accept physical match packets
mov ax, RTL8139_RX_CONFIG
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND
out dx, ax
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144
mov ax, (RTL8139_TX_MXDMA shl RTL8139_BIT_TX_MXDMA) \
or (RTL8139_TXRR shl RTL8139_BIT_TXRR)
add edx, RTL8139_REG_TXCONFIG - RTL8139_REG_RXCONFIG
out dx, ax
; enable auto negotiation
add edx, RTL8139_REG_BMCR - RTL8139_REG_TXCONFIG
in ax, dx
or ax, (1 shl RTL8139_BIT_ANE)
out dx, ax
; set auto negotiation advertisement
add edx, RTL8139_REG_ANAR - RTL8139_REG_BMCR
in ax, dx
or ax, (1 shl RTL8139_BIT_SELECTOR) or (1 shl RTL8139_BIT_10) \
or (1 shl RTL8139_BIT_10FD) or (1 shl RTL8139_BIT_TX) \
or (1 shl RTL8139_BIT_TXFD)
out dx, ax
; lock config and BMCR registers
xor eax, eax
add edx, RTL8139_REG_9346CR - RTL8139_REG_ANAR
out dx, al
; init RX/TX pointers
mov [rtl8139_rx_buff_offset], eax
mov [curr_tx_desc], eax
; clear missing packet counter
add edx, RTL8139_REG_MPC - RTL8139_REG_9346CR
out dx, eax
; disable all interrupts
add edx, RTL8139_REG_IMR - RTL8139_REG_MPC
out dx, ax
; set RxBuffer address, init RX buffer offset, init TX ring
mov eax, rtl8139_rx_buff ; simba
sub eax,OS_BASE
add edx, RTL8139_REG_RBSTART - RTL8139_REG_IMR
out dx, eax
; Indicate that we have successfully reset the card
mov eax, [pci_data]
mov [eth_status], eax
ret
 
;***************************************************************************
; Function
; rtl8139_read_eeprom
; Description
; reads eeprom type 93c46 and 93c56
; Parameters
; al - word to be read (6bit in case of 93c46 and 8bit otherwise)
; Return value
; ax - word read in
; Destroyed register(s)
; eax, cx, ebx, edx
;
;***************************************************************************
rtl8139_read_eeprom:
movzx ebx, al
mov edx, [io_addr]
add edx, RTL8139_REG_RXCONFIG
in al, dx
test al, (1 shl RTL8139_BIT_9356SEL)
jz .type_93c46
; and bl, 01111111b ; don't care first bit
or bx, EE_93C56_READ_CMD ; it contains start bit
mov cx, EE_93C56_CMD_LENGTH-1 ; cmd_loop counter
jmp .read_eeprom
.type_93c46:
and bl, 00111111b
or bx, EE_93C46_READ_CMD ; it contains start bit
mov cx, EE_93C46_CMD_LENGTH-1 ; cmd_loop counter
.read_eeprom:
add edx, RTL8139_REG_9346CR - RTL8139_REG_RXCONFIG_0
; mov al, (1 shl RTL8139_BIT_93C46_EEM1)
; out dx, al
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \
or (1 shl RTL8139_BIT_93C46_EECS) ; wake up the eeprom
out dx, al
.cmd_loop:
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS)
bt bx, cx
jnc .zero_bit
or al, (1 shl RTL8139_BIT_93C46_EEDI)
.zero_bit:
out dx, al
; push eax
; in eax, dx ; eeprom delay
; pop eax
or al, (1 shl RTL8139_BIT_93C46_EESK)
out dx, al
; in eax, dx ; eeprom delay
dec cx
jns .cmd_loop
; in eax, dx ; eeprom delay
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS)
out dx, al
mov cl, 0xf
.read_loop:
shl ebx, 1
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \
or (1 shl RTL8139_BIT_93C46_EECS) \
or (1 shl RTL8139_BIT_93C46_EESK)
out dx, al
; in eax, dx ; eeprom delay
in al, dx
and al, (1 shl RTL8139_BIT_93C46_EEDO)
jz .dont_set
inc ebx
.dont_set:
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \
or (1 shl RTL8139_BIT_93C46_EECS)
out dx, al
; in eax, dx ; eeprom delay
dec cl
jns .read_loop
xor al, al
out dx, al
mov ax, bx
ret
 
;***************************************************************************
; Function
; rtl8139_transmit
; Description
; Transmits a packet of data via the ethernet card
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; Size of packet in ecx
; Pointer to packet data in esi
; Destroyed registers
; eax, edx, esi, edi
; ToDo
; for waiting of timeout the rtl8139 internal timer
; should be used
;
;***************************************************************************
rtl8139_transmit:
cmp ecx, MAX_ETH_FRAME_SIZE
jg .finish ; packet is too long
push ecx
; check descriptor
mov ecx, [curr_tx_desc]
mov edx, [io_addr]
lea edx, [edx+ecx*4+RTL8139_REG_TSD0]
push edx ebx
in ax, dx
test ax, 0x1fff ; or no size given
jz .send_packet
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
jz .send_packet
; wait for timeout
mov ebx, RTL8139_TX_TIMEOUT
mov eax, 0x5 ; delay x/100 secs
int 0x40
in ax, dx
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN)
jz .send_packet
; chip hung, reset it
call rtl8139_reset
; reset the card
.send_packet:
; calculate tx_buffer address
pop ebx
push esi
mov eax, MAX_ETH_FRAME_SIZE
mul dword [curr_tx_desc]
mov esi, edi
lea edi, [rtl8139_tx_buff+eax]
mov eax, edi
cld
; copy destination address
movsd
movsw
; copy source address
mov esi, node_addr
movsd
movsw
; copy packet type
mov [edi], bx
add edi, 2
; copy the packet data
pop esi edx ecx
push ecx
shr ecx, 2
rep movsd
pop ecx
push ecx
and ecx, 3
rep movsb
; set address
sub eax,OS_BASE
add edx, RTL8139_REG_TSAD0 - RTL8139_REG_TSD0
out dx, eax
; set size and early threshold
pop eax ; pick up the size
add eax, ETH_HLEN
cmp eax, ETH_ZLEN
jnc .no_pad
mov eax, ETH_ZLEN
.no_pad:
or eax, (RTL8139_ERTXTH shl RTL8139_BIT_ERTXTH)
add edx, RTL8139_REG_TSD0 - RTL8139_REG_TSAD0
out dx, eax
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
inc dword [curr_tx_desc]
and dword [curr_tx_desc], 3
.finish:
ret
 
;***************************************************************************
; Function
; rtl8139_poll
;
; Description
; Polls the ethernet card for a received packet
; Received data, if any, ends up in Ether_buffer
; Destroyed register(s)
; eax, edx, ecx
;
;***************************************************************************
rtl8139_poll:
mov word [eth_rx_data_len], 0
mov edx, [io_addr]
add edx, RTL8139_REG_COMMAND
in al, dx
test al, (1 shl RTL8139_BIT_BUFE)
jnz .finish
; new packet received copy it from rx_buffer into Ether_buffer
mov eax, rtl8139_rx_buff
add eax, [rtl8139_rx_buff_offset]
; check if packet is ok
test byte [eax], (1 shl RTL8139_BIT_ROK)
jz .reset_rx
; packet is ok copy it into the Ether_buffer
movzx ecx, word [eax+2] ; packet length
sub ecx, 4 ; don't copy CRC
mov word [eth_rx_data_len], cx
push ecx
shr ecx, 2 ; first copy dword-wise
lea esi, [eax+4] ; don't copy the packet header
mov edi, Ether_buffer
cld
rep movsd ; copy the dwords
pop ecx
and ecx, 3
rep movsb ; copy the rest bytes
; update rtl8139_rx_buff_offset
movzx eax, word [eax+2] ; packet length
add eax, [rtl8139_rx_buff_offset]
add eax, 4+3 ; packet header is 4 bytes long + dword alignment
and eax, not 3 ; dword alignment
cmp eax, RTL8139_RX_BUFFER_SIZE
jl .no_wrap
sub eax, RTL8139_RX_BUFFER_SIZE
.no_wrap:
mov [rtl8139_rx_buff_offset], eax
; update CAPR register
sub eax, 0x10 ; value 0x10 is a constant for CAPR
add edx, RTL8139_REG_CAPR - RTL8139_REG_COMMAND
out dx, ax
.finish:
; clear active interrupt sources
mov edx, [io_addr]
add edx, RTL8139_REG_ISR
in ax, dx
out dx, ax
ret
.reset_rx:
in al, dx ; read command register
push eax
and al, not (1 shl RTL8139_BIT_RE)
out dx, al
pop eax
out dx, al
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND
mov ax, RTL8139_RX_CONFIG
out dx, ax
ret
 
rtl8139_cable:
pusha
mov edx, [io_addr]
add edx, 0x58
in al,dx
test al,1 SHL 2
jnz .notconnected
popa
xor al,al
inc al
ret
.notconnected:
popa
xor al,al
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/eth_drv/drivers
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/network/eth_drv/ethernet.inc
0,0 → 1,509
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ETHERNET.INC ;;
;; ;;
;; Ethernet network layer for Menuet OS ;;
;; ;;
;; This file contains the following: ;;
;; PCI bus scanning for valid devices ;;
;; Table of supported ethernet drivers ;;
;; Code to identify and activate a supported driver ;;
;; ARP handler ;;
;; Driver interface to the IP layer ;;
;; Gateway support ;;
;; ;;
;; Individual driver files are included here ;;
;; ;;
;; The PCI bus scanning code was ported from the etherboot ;;
;; 5.0.6 project. The copyright statement for that code is ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;; remaining parts Copyright 2002 Mike Hibbett ;;
;; mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;********************************************************************
; Interface
; ethernet_driver called by stack_handler in stack.inc
; eth_probe called by app_stack_handler in stack.inc
;
;********************************************************************
 
ETHER_IP equ 0x0008 ; Reversed from 0800 for intel
ETHER_ARP equ 0x0608 ; Reversed from 0806 for intel
ETHER_RARP equ 0x3580
 
struc ETH_FRAME
{ .DstMAC dp ? ;destination MAC-address [6 bytes]
.SrcMAC dp ? ;source MAC-address [6 bytes]
.Type dw ? ;type of the upper-layer protocol [2 bytes]
.Data db ? ;data [46-1500 bytes]
}
 
virtual at Ether_buffer
ETH_FRAME ETH_FRAME
end virtual
 
 
; Some useful information on data structures
 
; Ethernet Packet - ARP Request example
;
; 0 1 2 3
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
;
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Dest H/W Address |
; | ( 14 byte header ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | Source H/W Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Protocol - ARP 08 06 |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | H/W Type 00 01 | Protocol Type 08 00 |
; | ( ARP Request packet ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | HLen 0x06 | PLen 0x04 | OpCode 00 01 |
; | ( 0001 for request, 0002 for reply ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Source Hardware Address ( MAC Address ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | Source IP Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | | Destination Hardware Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Destination IP Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
; Include individual drivers source files at this point.
; If you create a new driver, include it below.
 
include "drivers/rtl8029.inc"
include "drivers/i8255x.inc"
include "drivers/rtl8139.inc"
include "drivers/3c59x.inc"
include "drivers/sis900.inc"
include "drivers/pcnet32.inc"
include "drivers/rtl8169.inc"
include "drivers/forcedeth.inc"
 
; PCICards
; ========
; PCI vendor and hardware types for hardware supported by the above drivers
; If you add a driver, ensure you update this datastructure, otherwise the
; card will not be probed.
; Each driver is defined by 4 double words. These are
; PCIVendorDevice probeFunction ResetFunction PollFunction transmitFunction
; The last entry must be kept at all zeros, to indicate the end of the list
; As a PCI driver may support more than one hardware implementation, there may
; be several lines which refer to the same functions.
; The first driver found on the PCI bus will be the one used.
 
PCICARDS_ENTRY_SIZE equ 24 ; Size of each PCICARDS entry
 
iglobal
PCICards:
dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
dd 0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0
 
dd 0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit, 0
 
dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable ; tested by hidnplayr: works ok
dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable ; tested by hidnplayr: works ok
dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable
 
dd 0x816810ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x816910ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x011616ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x43001186, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
dd 0x816710ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0
 
dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
dd 0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0
 
dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0
 
dd 0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0
dd 0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0
dd 0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0
 
;dd 0x08031516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable
 
; following cards are untested
dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0
;dd 0x08001516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable
;dd 0x08911516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable
 
dd 0x006610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; nVidia Corporation nForce2 Ethernet Controller
dd 0x01c310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x00D610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x008610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x008c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x00e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x00df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x005610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x005710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x003710de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x003810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x026810de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x026910de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x037210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x037310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x03e510de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x03e610de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x03ee10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x03ef10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x045010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x045110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x045210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x045310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x054c10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x054d10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x054e10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x054f10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x07dc10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x07dd10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x07de10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x07df10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x076010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; MCP77 Ethernet Controller
dd 0x076110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x076210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x076310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x0ab010de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x0ab110de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x0ab210de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x0ab310de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
dd 0x0d7d10de, forcedeth_probe, forcedeth_reset, forcedeth_poll, forcedeth_transmit, forcedeth_cable ; not tested
 
rb PCICARDS_ENTRY_SIZE ; end of list marker, do not remove
endg
 
uglobal
;Net-stack's interface's settings
node_addr: db 0,0,0,0,0,0
gateway_ip: dd 0
dns_ip: dd 0
 
eth_rx_data_len: dw 0
eth_status: dd 0
io_addr: dd 0
hdrtype: db 0
vendor_device: dd 0
pci_data: dd 0
pci_dev: dd 0
pci_bus: dd 0
 
; These will hold pointers to the selected driver functions
drvr_probe: dd 0
drvr_reset: dd 0
drvr_poll: dd 0
drvr_transmit: dd 0
drvr_cable: dd 0
 
endg
 
iglobal
broadcast_add: db 0xff,0xff,0xff,0xff,0xff,0xff
subnet_mask: dd 0x00ffffff ; 255.255.255.0
endg
 
include "arp.inc" ;arp-protocol functions
include "pci.inc" ;PCI bus access functions
 
 
;***************************************************************************
; Function
; eth_tx
;
; Description
; Looks at the NET1OUT_QUEUE for data to send.
; Stores that destination IP in a location used by the tx routine
; Looks up the MAC address in the ARP table; stores that where
; the tx routine can get it
; Get the length of the data. Store that where the tx routine wants it
; Call tx
; Places buffer on empty queue when the tx routine finished
;
;***************************************************************************
proc eth_tx stdcall uses ebx esi edi
local MACAddress dp ? ;allocate 6 bytes in the stack
 
; Look for a buffer to tx
mov eax, NET1OUT_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit ; Exit if no buffer available
 
push eax ;save buffer number
 
; convert buffer pointer eax to the absolute address
imul eax, IPBUFFSIZE
add eax, IPbuffs
 
; Extract the destination IP
; find the destination IP in the ARP table, get MAC
; store this MAC in 'MACAddress'
mov ebx, eax ; Save buffer address
mov edx, [ebx + 16] ; get destination address
 
; If the destination address is 255.255.255.255,
; set the MACAddress to all ones ( broadcast )
cld
mov esi, broadcast_add
lea edi, [MACAddress]
movsd
movsw
cmp edx, 0xffffffff
je .send ; If it is broadcast, just send
 
lea eax, [MACAddress] ;cause this is local variable
stdcall arp_table_manager, ARP_TABLE_IP_TO_MAC, edx, eax ;opcode,IP,MAC_ptr - Get the MAC address.
 
cmp eax, ARP_VALID_MAPPING
je .send
 
; No valid entry. Has the request been sent, but timed out?
cmp eax, ARP_RESPONSE_TIMEOUT
je .freebuf
 
.wait_response: ;we wait arp-response
; Re-queue the packet, and exit
pop ebx
mov eax, NET1OUT_QUEUE
call queue ; Get the buffer back
jmp .exit
 
.send: ;if ARP_VALID_MAPPING then send the packet
lea edi, [MACAddress] ; Pointer to 48 bit destination address
movzx ecx, word[ebx+2] ; Size of IP packet to send
xchg ch, cl ; because mirror byte-order
mov esi, ebx ; Pointer to packet data
mov bx, ETHER_IP ; Type of packet
push ebp
call dword [drvr_transmit] ; Call the drivers transmit function
pop ebp
 
; OK, we have sent a packet, so increment the count
inc dword [ip_tx_count]
 
; And finally, return the buffer to the free queue
.freebuf:
pop eax
call freeBuff
 
.exit:
ret
endp
 
;***************************************************************************
; Function
; ether_IP_handler
;
; Description
; Called when an IP ethernet packet is received on the ethernet
; Header + Data is in Ether_buffer[]
; We just need to get a buffer from the 'free' queue, and
; store the packet in it, then insert the packet number into the
; IPRX queue.
; If no queue entry is available, the packet is silently discarded
; All registers may be destroyed
;
;***************************************************************************
;uglobal
; ether_IP_handler_cnt dd ?
;endg
ether_IP_handler:
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je eiph00x
 
; convert buffer pointer eax to the absolute address
push eax
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
 
mov edi, eax
 
; get a pointer to the start of the DATA
mov esi, ETH_FRAME.Data
 
; Now store it all away
mov ecx, IPBUFFSIZE / 4 ; Copy all of the available
; data across - worse case
cld
rep movsd
 
; inc [ether_IP_handler_cnt]
; DEBUGF 1, "K : ether_IP_handler (%u)\n", [ether_IP_handler_cnt]
 
; And finally, place the buffer in the IPRX queue
pop ebx
mov eax, IPIN_QUEUE
call queue
 
eiph00x:
ret
 
;***************************************************************************
; Function
; eth_probe
; Description
; Searches for an ethernet card. If found, the card is enabled and
; the ethernet -> IP link established
;
; This function scans the PCI bus looking for a supported device.
; ISA bus is currently not supported.
;
; eax is 0 if no hardware found
;***************************************************************************
eth_probe:
; Find a card on the PCI bus, and get it's address
call scan_bus ; Find the ethernet cards PIC address
xor eax, eax
cmp [io_addr], eax
je ep_00x ; Return 0 in eax if no cards found
 
call dword [drvr_probe] ; Call the drivers probe function
 
mov eax, [io_addr] ; return a non zero value
 
ep_00x:
ret
 
;***************************************************************************
; Function
; ethernet_driver
;
; Description
; The ethernet RX and TX handler
; This is a kernel function, called by stack_handler
;
;***************************************************************************
ethernet_driver:
; Do nothing if the driver is inactive
cmp [ethernet_active], byte 0
je eth_exit
 
call eth_rx
call eth_tx
 
eth_exit:
ret
 
;***************************************************************************
; Function
; eth_rx
;
; Description
; Polls the ethernet card for received data. Extracts if present
; Depending on the Protocol within the packet:
; ARP : Pass to ARP_handler. This may result in an ARP reply
; being tx'ed
; IP : Store in an IP buffer
;
;***************************************************************************
eth_rx:
xor ax, ax
mov [eth_rx_data_len], ax
call dword [drvr_poll] ; Call the drivers poll function
 
mov ax, [eth_rx_data_len]
cmp ax, 0
je .exit
 
 
; Check the protocol. Call appropriate handler
 
mov ax, [ETH_FRAME.Type] ; The address of the protocol word
 
cmp ax, ETHER_IP
je .is_ip ; It's IP
 
cmp ax, ETHER_ARP
je .is_arp ; It is ARP
 
DEBUGF 1,"K : eth_rx - dumped (%u)\n", ax
inc [dumped_rx_count]
jmp .exit ; If not IP or ARP, ignore
 
.is_ip:
; DEBUGF 1,"K : eth_rx - IP packet\n"
inc dword [ip_rx_count]
call ether_IP_handler
jmp .exit
 
.is_arp:
; DEBUGF 1,"K : eth_rx - ARP packet\n"
; At this point, the packet is still in the Ether_buffer
call arp_handler
 
.exit:
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/eth_drv/arp.inc
0,0 → 1,556
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ARP.INC ;;
;; ;;
;; Address Resolution Protocol ;;
;; ;;
;; This file contains the following: ;;
;; arp_table_manager - Manages an ARPTable ;;
;; arp_request - Sends an ARP request on the ethernet ;;
;; arp_handler - Called when an ARP packet is received ;;
;; ;;
;; Changes history: ;;
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;;
;; 11.11.2006 - [Johnny_B] and [smb] ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
ARP_NO_ENTRY equ 0
ARP_VALID_MAPPING equ 1
ARP_AWAITING_RESPONSE equ 2
ARP_RESPONSE_TIMEOUT equ 3
 
struc ARP_ENTRY ;=14 bytes
{ .IP dd ? ;+00
.MAC dp ? ;+04
.Status dw ? ;+10
.TTL dw ? ;+12 : ( in seconds )
}
 
virtual at 0
ARP_ENTRY ARP_ENTRY
end virtual
 
; The TTL field is decremented every second, and is deleted when it
; reaches 0. It is refreshed every time a packet is received
; If the TTL field is 0xFFFF it is a static entry and is never deleted
; The status field can be the following values:
; 0x0000 entry not used
; 0x0001 entry holds a valid mapping
; 0x0002 entry contains an IP address, awaiting ARP response
; 0x0003 No response received to ARP request.
; The last status value is provided to allow the network layer to delete
; a packet that is queued awaiting an ARP response
 
 
; The follow is the ARP Table.
; This table must be manually updated and the kernel recompilied if
; changes are made to it.
; Empty entries are filled with zeros
 
ARP_ENTRY_SIZE equ 14 ; Number of bytes per entry
ARP_TABLE_SIZE equ 20 ; Size of table
ARP_TABLE_ENTRIES equ 0 ; Number of static entries in the table
 
;TO ADD A STATIC ENTRY, DONT FORGET, PUT "ARPTable" from "uglobal" to "iglobal"!!!
;AND ALSO - IP and MAC have net byte-order, BUT STATUS AND TTL HAVE A MIRROR BYTE-ORDER!!!
uglobal
ARPTable:
;example, static entry -> db 11,22,33,44, 0x11,0x22,0x33,0x44,0x55,0x66, 0x01,0x00, 0xFF,0xFF
times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE db 0
endg
 
iglobal
NumARP: dd ARP_TABLE_ENTRIES
ARPTable_ptr dd ARPTable ;pointer to ARPTable
endg
 
ARP_REQ_OPCODE equ 0x0100 ;request
ARP_REP_OPCODE equ 0x0200 ;reply
 
struc ARP_PACKET
{ .HardwareType dw ? ;+00
.ProtocolType dw ? ;+02
.HardwareSize db ? ;+04
.ProtocolSize db ? ;+05
.Opcode dw ? ;+06
.SenderMAC dp ? ;+08
.SenderIP dd ? ;+14
.TargetMAC dp ? ;+18
.TargetIP dd ? ;+24
}
 
virtual at 0
ARP_PACKET ARP_PACKET
end virtual
 
 
 
;***************************************************************************
; Function
; arp_table_manager [by Johnny_B]
;
; Description
; Does a most required operations with ARP-table
; IN:
; Operation: see Opcode's constants below
; Index: Index of entry in the ARP-table
; Extra: Extra parameter for some Opcodes
; OUT:
; EAX = Returned value depends on opcodes, more detailed see below
;
;***************************************************************************
;Opcode's constants
ARP_TABLE_ADD equ 1
ARP_TABLE_DEL equ 2
ARP_TABLE_GET equ 3
ARP_TABLE_GET_ENTRIES_NUMBER equ 4
ARP_TABLE_IP_TO_MAC equ 5
ARP_TABLE_TIMER equ 6
 
;Index's constants
EXTRA_IS_ARP_PACKET_PTR equ 0 ;if Extra contain pointer to ARP_PACKET
EXTRA_IS_ARP_ENTRY_PTR equ -1 ;if Extra contain pointer to ARP_ENTRY
 
align 4
proc arp_table_manager stdcall uses ebx esi edi ecx edx,\
Opcode:DWORD,Index:DWORD,Extra:DWORD
 
mov ebx, dword[ARPTable_ptr] ;ARPTable base
mov ecx, dword[NumARP] ;ARP-entries counter
 
mov eax, dword[Opcode]
cmp eax, ARP_TABLE_TIMER
je .timer
cmp eax, ARP_TABLE_ADD
je .add
cmp eax, ARP_TABLE_DEL
je .del
cmp eax, ARP_TABLE_GET
je .get
cmp eax, ARP_TABLE_IP_TO_MAC
je .ip_to_mac
cmp eax, ARP_TABLE_GET_ENTRIES_NUMBER
je .get_entries_number
jmp .exit ;if unknown opcode
 
 
;;BEGIN TIMER
;;Description: it must be callback every second. It is responsible for removing expired routes.
;;IN: Operation: ARP_TABLE_TIMER
;; Index: must be zero
;; Extra: must be zero
;;OUT:
;; EAX=not defined
;;
.timer:
test ecx, ecx
jz .exit ;if NumARP=0 nothing to do
sub ecx, ARP_TABLE_ENTRIES ;ecx=dynamic entries number
jz .exit ;if NumARP=number of static entries then exit
 
add ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE ;ebx=dynamic entries base
 
.timer_loop:
movsx esi, word [ebx + ARP_ENTRY.TTL]
cmp esi, 0xFFFFFFFF
je .timer_loop_end ;if TTL==0xFFFF then it's static entry
 
test esi, esi
jnz .timer_loop_end_with_dec ;if TTL!=0
 
; Ok, TTL is 0
;if Status==AWAITING_RESPONSE and TTL==0
;then we have to change it to ARP_RESPONSE_TIMEOUT
cmp word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
jne @f
 
mov word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT
mov word [ebx + ARP_ENTRY.TTL], word 0x000A ;10 sec
jmp .timer_loop_end
 
@@:
;if TTL==0 and Status==VALID_MAPPING, we have to delete it
;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too
mov esi, dword[NumARP]
sub esi, ecx ;esi=index of entry, will be deleted
stdcall arp_table_manager,ARP_TABLE_DEL,esi,0 ;opcode,index,extra
jmp .timer_loop_end
 
 
.timer_loop_end_with_dec:
dec word [ebx + ARP_ENTRY.TTL] ;decrease TTL
.timer_loop_end:
add ebx, ARP_ENTRY_SIZE
loop .timer_loop
 
jmp .exit
;;END TIMER
 
;;BEGIN ADD
;;Description: it adds an entry in the table. If ARP-table already
;; contains same IP, it will be updated.
;;IN: Operation: ARP_TABLE_ADD
;; Index: specifies what contains Extra-parameter
;; Extra: if Index==EXTRA_IS_ARP_PACKET_PTR,
;; then Extra contains pointer to ARP_PACKET,
;; otherwise Extra contains pointer to ARP_ENTRY
;;OUT:
;; EAX=index of entry, that has been added
;;
.add:
 
sub esp, ARP_ENTRY_SIZE ;Allocate ARP_ENTRY_SIZE byte in stack
 
mov esi, [Extra] ;pointer
mov edi, [Index] ;opcode
 
cmp edi, EXTRA_IS_ARP_PACKET_PTR
je .arp_packet_to_entry ;if Extra contain ptr to ARP_PACKET and we have to form arp-entry
;else it contain ptr to arp-entry
 
cld
; esi already has been loaded
mov edi, esp ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
mov ecx,ARP_ENTRY_SIZE/2 ;ARP_ENTRY_SIZE must be even number!!!
rep movsw ;copy
jmp .search
 
.arp_packet_to_entry:
mov edx, dword[esi + ARP_PACKET.SenderIP] ;esi=base of ARP_PACKET
mov [esp + ARP_ENTRY.IP], edx
 
cld
lea esi, [esi + ARP_PACKET.SenderMAC]
lea edi, [esp + ARP_ENTRY.MAC]
movsd
movsw
mov word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING ; specify the type - a valid entry
mov word[esp + ARP_ENTRY.TTL], 0x0E10 ; = 1 hour
 
.search:
mov edx, dword[esp + ARP_ENTRY.IP] ;edx=IP-address, which we'll search
mov ecx, dword[NumARP] ;ecx=ARP-entries counter
jecxz .add_to_end ;if ARP-entries number == 0
imul eax, ecx, ARP_ENTRY_SIZE ;eax=current table size(in bytes)
@@:
sub eax, ARP_ENTRY_SIZE
cmp dword[ebx + eax + ARP_ENTRY.IP], edx
loopnz @b
jz .replace ; found, replace existing entry, ptr to it is in eax
 
.add_to_end:
;else add to end
or eax,-1 ;set eax=0xFFFFFFFF if adding is impossible
mov ecx, dword[NumARP]
cmp ecx, ARP_TABLE_SIZE
je .add_exit ;if arp-entries number is equal to arp-table maxsize
 
imul eax, dword[NumARP], ARP_ENTRY_SIZE ;eax=ptr to end of ARPTable
inc dword [NumARP] ;increase ARP-entries counter
 
.replace:
cld
mov esi, esp ;esp=base of ARP-entry, that will be added
lea edi, [ebx + eax] ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
mov ecx,ARP_ENTRY_SIZE/2 ;ARP_ENTRY_SIZE must be even number!!!
rep movsw
 
mov ecx, ARP_ENTRY_SIZE
xor edx, edx ;"div" takes operand from EDX:EAX
div ecx ;eax=index of entry, which has been added
 
.add_exit:
add esp, ARP_ENTRY_SIZE ;free stack
jmp .exit
;;END ADD
 
;;BEGIN DEL
;;Description: it deletes an entry in the table.
;;IN: Operation: ARP_TABLE_DEL
;; Index: index of entry, that should be deleted
;; Extra: must be zero
;;OUT:
;; EAX=not defined
;;
.del:
mov esi, [Index]
imul esi, ARP_ENTRY_SIZE
 
mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE
sub ecx, esi
 
lea edi, [ebx + esi] ;edi=ptr to entry that should be deleted
lea esi, [edi + ARP_ENTRY_SIZE] ;esi=ptr to next entry
 
shr ecx,1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER!
cld
rep movsw
 
dec dword[NumARP] ;decrease arp-entries counter
jmp .exit
;;END DEL
 
;;BEGIN GET
;;Description: it reads an entry of table into buffer.
;;IN: Operation: ARP_TABLE_GET
;; Index: index of entry, that should be read
;; Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE)
;;OUT:
;; EAX=not defined
;;
.get:
mov esi, [Index]
imul esi, ARP_ENTRY_SIZE ;esi=ptr to required ARP_ENTRY
mov edi, [Extra] ;edi=buffer for reading
mov ecx, ARP_ENTRY_SIZE/2 ; must be even number!!!
cld
rep movsw
jmp .exit
;;END GET
 
;;BEGIN IP_TO_MAC
;;Description: it gets an IP from Index, scans each entry in the table and writes
;; MAC, that relates to specified IP, into buffer specified in Extra.
;; And if it cannot find an IP-address in the table, it does an ARP-request of that.
;;IN: Operation: ARP_TABLE_IP_TO_MAC
;; Index: IP that should be transformed into MAC
;; Extra: pointer to buffer where will be written the MAC-address.
;;OUT:
;; EAX=ARP table entry status code.
;; If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request.
;; If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system.
;; If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long.
;; If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC.
;;
;; If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet
;; resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this
;; function with 1sec delay. sure, only if it not return a valid MAC after a first call.
;;
.ip_to_mac:
 
xor eax, eax
mov edi, dword[Extra]
cld
stosd
stosw
 
 
; first, check destination IP to see if it is on 'this' network.
; The test is:
; if ( destIP & subnet_mask == stack_ip & subnet_mask )
; destination is local
; else
; destination is remote, so pass to gateway
 
mov eax, [Index] ;eax=required IP
mov esi, eax
and esi, [subnet_mask]
mov ecx, [stack_ip]
and ecx, [subnet_mask]
cmp esi, ecx
je @f ;if we and target IP are located in the same network
mov eax, [gateway_ip]
mov [Index], eax
@@:
 
cmp dword[NumARP], 0
je .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP.
;EAX will be containing a zero, it's equal to ARP_NO_ENTRY
 
mov ecx, dword[NumARP]
imul esi, ecx, ARP_ENTRY_SIZE ;esi=current ARP-table size
 
@@:
sub esi, ARP_ENTRY_SIZE
cmp [ebx + esi], eax ; ebx=ARPTable base
loopnz @b ; Return back if non match
jnz .ip_to_mac_send_request ; and request IP->MAC if none found in the table
 
; Return the entry status in eax
movzx eax, word[ebx + esi + ARP_ENTRY.Status]
 
; esi holds index
cld
lea esi, [ebx + esi + ARP_ENTRY.MAC]
mov edi, [Extra] ;edi=ptr to buffer for write MAC
movsd
movsw
jmp .exit
 
.ip_to_mac_send_request:
stdcall arp_request,[Index],stack_ip,node_addr ;TargetIP,SenderIP_ptr,SenderMAC_ptr
mov eax, ARP_NO_ENTRY
jmp .exit
 
;;END IP_TO_MAC
 
;;BEGIN GET_ENTRIES_NUMBER
;;Description: returns an ARP-entries number in the ARPTable
;;IN: Operation: ARP_TABLE_GET_ENTRIES_NUMBER
;; Index: must be zero
;; Extra: must be zero
;;OUT:
;; EAX=ARP-entries number in the ARPTable
.get_entries_number:
mov eax, dword[NumARP]
jmp .exit
;;END GET_ENTRIES_NUMBER
 
.exit:
ret
endp
 
 
;***************************************************************************
; Function
; arp_handler
;
; Description
; Called when an ARP packet is received on the ethernet
; Header + Data is in Ether_buffer[]
; It looks to see if the packet is a request to resolve this Hosts
; IP address. If it is, send the ARP reply packet.
; This Hosts IP address is in dword [stack_ip] ( in network format )
; This Hosts MAC address is in node_addr[6]
; All registers may be destroyed
;
;***************************************************************************
arp_handler:
; Is this a REQUEST?
; Is this a request for My Host IP
; Yes - So construct a response message.
; Send this message to the ethernet card for transmission
 
stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_PACKET_PTR,ETH_FRAME.Data + ARP_PACKET
 
inc dword[arp_rx_count] ;increase ARP-packets counter
 
cmp word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REQ_OPCODE ; Is this a request packet?
jne .exit ; No - so exit
 
mov eax, [stack_ip]
cmp eax, dword[ETH_FRAME.Data + ARP_PACKET.TargetIP] ; Is it looking for my IP address?
jne .exit ; No - so quit now
 
; OK, it is a request for my MAC address. Build the frame and send it
; We can reuse the packet.
 
mov word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REP_OPCODE
 
cld
mov esi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC
movsd
movsw
 
mov esi, ETH_FRAME.Data + ARP_PACKET.SenderIP
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetIP
movsd
 
mov esi, node_addr
mov edi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
movsd
movsw
 
mov esi, stack_ip
mov edi, ETH_FRAME.Data + ARP_PACKET.SenderIP
movsd
 
; Now, send it!
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC ;ptr to destination MAC address
mov bx, ETHER_ARP ;type of protocol
mov ecx, 28 ;data size
mov esi, ETH_FRAME.Data + ARP_PACKET ;ptr to data
push ebp
call dword [drvr_transmit] ;transmit packet
pop ebp
 
.exit:
ret
 
 
;***************************************************************************
; Function
; arp_request [by Johnny_B]
;
; Description
; Sends an ARP request on the ethernet
; IN:
; TargetIP : requested IP address
; SenderIP_ptr : POINTER to sender's IP address(our system's address)
; SenderMAC_ptr : POINTER to sender's MAC address(our system's address)
; OUT:
; EAX=0 (if all is ok), otherwise EAX is not defined
;
; EBX,ESI,EDI will be saved
;
;***************************************************************************
proc arp_request stdcall uses ebx esi edi,\
TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD
 
inc dword[arp_tx_count] ; increase counter
 
sub esp, 28 ; allocate memory for ARP_PACKET
 
mov word[esp + ARP_PACKET.HardwareType],0x0100 ;Ethernet
mov word[esp + ARP_PACKET.ProtocolType],0x0008 ;IP
mov byte[esp + ARP_PACKET.HardwareSize],0x06 ;MAC-addr length
mov byte[esp + ARP_PACKET.ProtocolSize],0x04 ;IP-addr length
mov word[esp + ARP_PACKET.Opcode],0x0100 ;Request
 
cld
mov esi,[SenderMAC_ptr]
lea edi,[esp + ARP_PACKET.SenderMAC] ;Our MAC-addr
movsd
movsw
 
mov esi,[SenderIP_ptr]
lea edi,[esp + ARP_PACKET.SenderIP] ;Our IP-addr
movsd
 
xor eax, eax
lea edi, [esp + ARP_PACKET.TargetMAC] ;Required MAC-addr(zeroed)
stosd
stosw
 
mov esi, dword[TargetIP]
mov dword[esp + ARP_PACKET.TargetIP],esi ;Required IP-addr(we get it as function parameter)
 
; Now, send it!
mov edi, broadcast_add ; Pointer to 48 bit destination address
mov bx, ETHER_ARP ; Type of packet
mov ecx, 28 ; size of packet
lea esi, [esp + ARP_PACKET]; pointer to packet data
push ebp
call dword [drvr_transmit] ; Call the drivers transmit function
pop ebp
 
add esp, 28 ; free memory, allocated before for ARP_PACKET
 
; Add an entry in the ARP table, awaiting response
sub esp, ARP_ENTRY_SIZE ;allocate memory for ARP-entry
 
mov esi, dword[TargetIP]
mov dword[esp + ARP_ENTRY.IP],esi
 
lea edi, [esp + ARP_ENTRY.MAC]
xor eax, eax
stosd
stosw
 
mov word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
mov word[esp + ARP_ENTRY.TTL], 0x000A ; 10 seconds
 
stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp
add esp, ARP_ENTRY_SIZE ; free memory
 
.exit:
ret
endp
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/eth_drv/pci.inc
0,0 → 1,351
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;***************************************************************************
;
; PCI CODE FOLLOWS
;
; the following functions provide access to the PCI interface.
; These functions are used by scan_bus, and also some ethernet drivers
;
;***************************************************************************
 
; PCI Bus defines
PCI_HEADER_TYPE equ 0x0e ;8 bit
PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit
PCI_BASE_ADDRESS_5 equ 0x24 ;32 bits
PCI_BASE_ADDRESS_SPACE_IO equ 0x01
PCI_VENDOR_ID equ 0x00 ;16 bit
PCI_BASE_ADDRESS_IO_MASK equ 0xFFFFFFFC
 
;***************************************************************************
; Function
; config_cmd
;
; Description
; creates a command dword for use with the PCI bus
; bus # in ebx
; devfn in ecx
; where in edx
;
; command dword returned in eax
; Only eax destroyed
;***************************************************************************
config_cmd:
push ecx
mov eax, ebx
shl eax, 16
or eax, 0x80000000
shl ecx, 8
or eax, ecx
pop ecx
or eax, edx
and eax, 0xFFFFFFFC
ret
 
;***************************************************************************
; Function
; pcibios_read_config_byte
;
; Description
; reads a byte from the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; byte returned in al ( rest of eax zero )
; Only eax/edx destroyed
;***************************************************************************
pcibios_read_config_byte:
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
 
xor eax, eax
and dx, 0x03
add dx, 0xCFC
; and dx, 0xFFC
in al, dx
ret
 
;***************************************************************************
; Function
; pcibios_read_config_word
;
; Description
; reads a word from the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; word returned in ax ( rest of eax zero )
; Only eax/edx destroyed
;***************************************************************************
pcibios_read_config_word:
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
 
xor eax, eax
and dx, 0x02
add dx, 0xCFC
; and dx, 0xFFC
in ax, dx
ret
 
;***************************************************************************
; Function
; pcibios_read_config_dword
;
; Description
; reads a dword from the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; dword returned in eax
; Only eax/edx destroyed
;***************************************************************************
pcibios_read_config_dword:
push edx
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
xor eax, eax
mov dx, 0xCFC
in eax, dx
pop edx
ret
 
;***************************************************************************
; Function
; pcibios_write_config_byte
;
; Description
; write a byte in al to the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; Only eax/edx destroyed
;***************************************************************************
pcibios_write_config_byte:
push ax
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
pop ax
 
and dx, 0x03
add dx, 0xCFC
out dx, al
ret
 
;***************************************************************************
; Function
; pcibios_write_config_word
;
; Description
; write a word in ax to the PCI config space
; bus # in ebx
; devfn in ecx
; where in edx ( ls 16 bits significant )
;
; Only eax/edx destroyed
;***************************************************************************
pcibios_write_config_word:
push ax
call config_cmd
push dx
mov dx, 0xCF8
out dx, eax
pop dx
pop ax
 
and dx, 0x02
add dx, 0xCFC
out dx, ax
ret
 
;***************************************************************************
; Function
; delay_us
;
; Description
; delays for 30 to 60 us
;
; I would prefer this routine to be able to delay for
; a selectable number of microseconds, but this works for now.
;
; If you know a better way to do 2us delay, pleae tell me!
;***************************************************************************
delay_us:
push eax
push ecx
 
mov ecx,2
 
in al,0x61
and al,0x10
mov ah,al
cld
 
dcnt1:
in al,0x61
and al,0x10
cmp al,ah
jz dcnt1
 
mov ah,al
loop dcnt1
 
pop ecx
pop eax
 
ret
 
;***************************************************************************
; Function
; scan_bus
;
; Description
; Scans the PCI bus for a supported device
; If a supported device is found, the drvr_ variables are initialised
; to that drivers functions ( as defined in the PCICards table)
;
; io_addr holds card I/O space. 32 bit, but only LS 16 bits valid
; pci_data holds the PCI vendor + device code
; pci_dev holds PCI bus dev #
; pci_bus holds PCI bus #
;
; io_addr will be zero if no card found
;
;***************************************************************************
scan_bus:
xor eax, eax
mov [hdrtype], al
mov [pci_data], eax
 
xor ebx, ebx ; ebx = bus# 0 .. 255
 
sb_bus_loop:
xor ecx, ecx ; ecx = devfn# 0 .. 254 ( not 255? )
 
sb_devf_loop:
mov eax, ecx
and eax, 0x07
 
cmp eax, 0
jne sb_001
 
mov edx, PCI_HEADER_TYPE
call pcibios_read_config_byte
mov [hdrtype], al
jmp sb_002
 
sb_001:
mov al, [hdrtype]
and al, 0x80
cmp al, 0x80
jne sb_inc_devf
 
sb_002:
mov edx, PCI_VENDOR_ID
call pcibios_read_config_dword
mov [vendor_device], eax
cmp eax, 0xffffffff
je sb_empty
cmp eax, 0
jne sb_check_vendor
 
sb_empty:
mov [hdrtype], byte 0
jmp sb_inc_devf
 
sb_check_vendor:
; iterate though PCICards until end or match found
mov esi, PCICards
 
sb_check:
cmp [esi], dword 0
je sb_inc_devf ; Quit if at last entry
cmp eax, [esi]
je sb_got_card
add esi, PCICARDS_ENTRY_SIZE
jmp sb_check
 
sb_got_card:
; indicate that we have found the card
mov [pci_data], eax
mov [pci_dev], ecx
mov [pci_bus], ebx
 
; Define the driver functions
push eax
mov eax, [esi+4]
mov [drvr_probe], eax
mov eax, [esi+8]
mov [drvr_reset], eax
mov eax, [esi+12]
mov [drvr_poll], eax
mov eax, [esi+16]
mov [drvr_transmit], eax
mov eax, [esi+20]
mov [drvr_cable], eax
pop eax
 
mov edx, PCI_BASE_ADDRESS_0
 
sb_reg_check:
call pcibios_read_config_dword
mov [io_addr], eax
and eax, PCI_BASE_ADDRESS_IO_MASK
cmp eax, 0
je sb_inc_reg
mov eax, [io_addr]
and eax, PCI_BASE_ADDRESS_SPACE_IO
cmp eax, 0
je sb_inc_reg
 
mov eax, [io_addr]
and eax, PCI_BASE_ADDRESS_IO_MASK
mov [io_addr], eax
 
sb_exit1:
ret
 
sb_inc_reg:
add edx, 4
cmp edx, PCI_BASE_ADDRESS_5
jbe sb_reg_check
 
sb_inc_devf:
inc ecx
cmp ecx, 255
jb sb_devf_loop
inc ebx
cmp ebx, 256
jb sb_bus_loop
 
; We get here if we didn't find our card
; set io_addr to 0 as an indication
xor eax, eax
mov [io_addr], eax
 
sb_exit2:
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/eth_drv
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/network/socket.inc
0,0 → 1,1107
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; SOCKET.INC ;;
;; ;;
;; Sockets constants, structures and functions ;;
;; ;;
;; This file contains the following: ;;
;; is_localport_unused ;;
;; get_free_socket ;;
;; socket_open ;;
;; socket_open_tcp ;;
;; socket_close ;;
;; socket_close_tcp ;;
;; socket_poll ;;
;; socket_status ;;
;; socket_read ;;
;; socket_write ;;
;; socket_write_tcp ;;
;; ;;
;; ;;
;; Changes history: ;;
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;;
;; 11.11.2006 - [Johnny_B] and [smb] ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
; socket data structure
struct SOCKET
.PrevPtr dd ? ; pointer to previous socket in list
.NextPtr dd ? ; pointer to next socket in list
.Number dd ? ; socket number (unique within single process)
.PID dd ? ; application process id
.LocalIP dd ? ; local IP address
.LocalPort dw ? ; local port
.RemoteIP dd ? ; remote IP address
.RemotePort dw ? ; remote port
.OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
.rxDataCount dd ? ; rx data count
.TCBState dd ? ; TCB state
.TCBTimer dd ? ; TCB timer (seconds)
.ISS dd ? ; initial send sequence
.IRS dd ? ; initial receive sequence
.SND_UNA dd ? ; sequence number of unack'ed sent packets
.SND_NXT dd ? ; bext send sequence number to use
.SND_WND dd ? ; send window
.RCV_NXT dd ? ; next receive sequence number to use
.RCV_WND dd ? ; receive window
.SEG_LEN dd ? ; segment length
.SEG_WND dd ? ; segment window
.wndsizeTimer dd ? ; window size timer
.lock dd ? ; lock mutex
.rxData dd ? ; receive data buffer here
ends
 
; TCP opening modes
SOCKET_PASSIVE = 0
SOCKET_ACTIVE = 1
 
; socket types
SOCK_STREAM = 1
SOCK_DGRAM = 2
 
; pointer to bitmap of free ports (1=free, 0=used)
uglobal
align 4
network_free_ports dd ?
endg
 
iglobal
align 4
network_free_hint dd 1024/8
endg
 
;; Allocate memory for socket data and put new socket into the list
; Newly created socket is initialized with calling PID and number and
; put into beginning of list (which is a fastest way).
;
; @return socket structure address in EAX
;;
proc net_socket_alloc stdcall uses ebx ecx edx edi
stdcall kernel_alloc, SOCKETBUFFSIZE
DEBUGF 1, "K : net_socket_alloc (0x%x)\n", eax
; check if we can allocate needed amount of memory
or eax, eax
jz .exit
 
; zero-initialize allocated memory
push eax
mov edi, eax
mov ecx, SOCKETBUFFSIZE / 4
cld
xor eax, eax
rep stosd
pop eax
 
; add socket to the list by changing pointers
mov ebx, net_sockets
push [ebx + SOCKET.NextPtr]
mov [ebx + SOCKET.NextPtr], eax
mov [eax + SOCKET.PrevPtr], ebx
pop ebx
mov [eax + SOCKET.NextPtr], ebx
or ebx, ebx
jz @f
mov [ebx + SOCKET.PrevPtr], eax
 
@@: ; set socket owner PID to the one of calling process
mov ebx, [TASK_BASE]
mov ebx, [ebx + TASKDATA.pid]
mov [eax + SOCKET.PID], ebx
 
; find first free socket number and use it
;mov edx, ebx
mov ebx, net_sockets
xor ecx, ecx
.next_socket_number:
inc ecx
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .last_socket_number
cmp [ebx + SOCKET.Number], ecx
jne .next_socket
;cmp [ebx + SOCKET.PID], edx
;jne .next_socket
mov ebx, net_sockets
jmp .next_socket_number
 
.last_socket_number:
mov [eax + SOCKET.Number], ecx
 
.exit:
ret
endp
 
;; Free socket data memory and pop socket off the list
;
; @param sockAddr is a socket structure address
;;
proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD
mov eax, [sockAddr]
DEBUGF 1, "K : net_socket_free (0x%x)\n", eax
; check if we got something similar to socket structure address
or eax, eax
jz .error
 
; make sure sockAddr is one of the socket addresses in the list
mov ebx, net_sockets
;mov ecx, [TASK_BASE]
;mov ecx, [ecx + TASKDATA.pid]
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .error
cmp ebx, eax
jne .next_socket
;cmp [ebx + SOCKET.PID], ecx
;jne .next_socket
 
; okay, we found the correct one
; mark local port as unused
movzx ebx, [eax + SOCKET.LocalPort]
push eax
mov eax, [network_free_ports]
xchg bl, bh
lock bts [eax], ebx
pop eax
; remove it from the list first, changing pointers
mov ebx, [eax + SOCKET.NextPtr]
mov eax, [eax + SOCKET.PrevPtr]
mov [eax + SOCKET.NextPtr], ebx
or ebx, ebx
jz @f
mov [ebx + SOCKET.PrevPtr], eax
 
@@: ; and finally free the memory structure used
stdcall kernel_free, [sockAddr]
ret
 
.error:
DEBUGF 1, "K : failed\n"
ret
endp
 
;; Get socket structure address by its number
; Scan through sockets list to find the socket with specified number.
; This proc uses SOCKET.PID indirectly to check if socket is owned by
; calling process.
;
; @param sockNum is a socket number
; @return socket structure address or 0 (not found) in EAX
;;
proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD
mov eax, [sockNum]
; check if we got something similar to socket number
or eax, eax
jz .error
 
; scan through sockets list
mov ebx, net_sockets
;mov ecx, [TASK_BASE]
;mov ecx, [ecx + TASKDATA.pid]
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .error
cmp [ebx + SOCKET.Number], eax
jne .next_socket
;cmp [ebx + SOCKET.PID], ecx
;jne .next_socket
 
; okay, we found the correct one
mov eax, ebx
ret
 
.error:
xor eax, eax
ret
endp
 
;; Get socket number by its structure address
; Scan through sockets list to find the socket with specified address.
; This proc uses SOCKET.PID indirectly to check if socket is owned by
; calling process.
;
; @param sockAddr is a socket structure address
; @return socket number (SOCKET.Number) or 0 (not found) in EAX
;;
proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD
mov eax, [sockAddr]
; check if we got something similar to socket structure address
or eax, eax
jz .error
 
; scan through sockets list
mov ebx, net_sockets
;mov ecx, [TASK_BASE]
;mov ecx, [ecx + TASKDATA.pid]
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .error
cmp ebx, eax
jne .next_socket
;cmp [ebx + SOCKET.PID], ecx
;jne .next_socket
 
; okay, we found the correct one
mov eax, [ebx + SOCKET.Number]
ret
 
.error:
xor eax, eax
ret
endp
 
;; [53.9] Check if local port is used by any socket in the system.
; Scan through sockets list, checking SOCKET.LocalPort.
; Useful when you want a to generate a unique local port number.
; This proc doesn't guarantee that after calling it and trying to use
; the port reported being free in calls to socket_open/socket_open_tcp it'll
; still be free or otherwise it'll still be used if reported being in use.
;
; @param BX is a port number
; @return 1 (port is free) or 0 (port is in use) in EAX
;;
proc is_localport_unused stdcall
movzx ebx, bx
mov eax, [network_free_ports]
bt [eax], ebx
setc al
movzx eax, al
ret
endp
 
;======================================
set_local_port:
;--------------------------------------
;? Set local port in socket structure.
;--------------------------------------
;> eax -> struct SOCKET
;> bx = local port, or 0 if the kernel must select it itself
;--------------------------------------
;< CF set on error / cleared on success
;< [eax+SOCKET.LocalPort] filled on success
;======================================
; 0. Prepare: save registers, make eax point to ports table, expand port to ebx.
push eax ecx
mov eax, [network_free_ports]
movzx ebx, bx
; 1. Test, whether the kernel should choose port itself. If no, proceed to 5.
test ebx, ebx
jnz .given
; 2. Yes, it should. Set ecx = limit of table, eax = start value
lea ecx, [eax+0x10000/8]
add eax, [network_free_hint]
; 3. First scan loop: from free hint to end of table.
.scan1:
; 3a. For each dword, find bit set to 1
bsf ebx, [eax]
jz .next1
; 3b. If such bit has been found, atomically test again and clear it.
lock btr [eax], ebx
; 3c. If the bit was still set (usual case), we have found and reserved one port.
; Proceed to 6.
jc .found
; 3d. Otherwise, someone has reserved it between bsf and btr, so retry search.
jmp .scan1
.next1:
; 3e. All bits are cleared, so advance to next dword.
add eax, 4
; 3f. Check limit and continue loop.
cmp eax, ecx
jb .scan1
; 4. Second scan loop: from port 1024 (start of non-system ports) to free hint.
mov eax, [network_free_ports]
mov ecx, eax
add ecx, [network_free_hint]
add eax, 1024/8
; 4a. Test whether there is something to scan.
cmp eax, ecx
jae .fail
; 4b. Enter the loop, the process is same as for 3.
.scan2:
bsf ebx, [eax]
jz .next2
lock btr [eax], ebx
jc .found
jmp .scan2
.next2:
add eax, 4
cmp eax, ecx
jb .scan2
; 4c. None found. Fail.
.fail:
pop ecx eax
stc
ret
; 5. No, the kernel should reserve selected port.
.given:
; 5a. Atomically test old value and clear bit.
lock btr [eax], ebx
; 5b. If the bit was set, reservation is successful. Proceed to 8.
jc .set
; 5c. Otherwise, fail.
jmp .fail
.found:
; 6. We have found the bit set to 1, convert the position to port number.
sub eax, [network_free_ports]
lea ebx, [ebx+eax*8]
; 7. Update free hint.
add eax, 4
cmp eax, 65536/8
jb @f
mov eax, 1024/8
@@:
mov [network_free_hint], eax
.set:
; 8. Restore eax, set SOCKET.LocalPort and return.
pop ecx eax
xchg bl, bh ; Intel -> network byte order
mov [eax + SOCKET.LocalPort], bx
clc
ret
 
;; [53.0] Open DGRAM socket (connectionless, unreliable)
;
; @param BX is local port number
; @param CX is remote port number
; @param EDX is remote IP address
; @return socket number or -1 (error) in EAX
;;
proc socket_open stdcall
call net_socket_alloc
or eax, eax
jz .error
 
DEBUGF 1, "K : socket_open (0x%x)\n", eax
 
push eax
 
call set_local_port
jc .error.free
xchg ch, cl
mov [eax + SOCKET.RemotePort], cx
mov ebx, [stack_ip]
mov [eax + SOCKET.LocalIP], ebx
mov [eax + SOCKET.RemoteIP], edx
 
;pop eax ; Get the socket number back, so we can return it
stdcall net_socket_addr_to_num
ret
 
.error.free:
stdcall net_socket_free;, eax
 
.error:
DEBUGF 1, "K : socket_open (fail)\n"
or eax, -1
ret
endp
 
;; [53.5] Open STREAM socket (connection-based, sequenced, reliable, two-way)
;
; @param BX is local port number
; @param CX is remote port number
; @param EDX is remote IP address
; @param ESI is open mode (SOCKET_ACTIVE, SOCKET_PASSIVE)
; @return socket number or -1 (error) in EAX
;;
proc socket_open_tcp stdcall
local sockAddr dd ?
 
cmp esi, SOCKET_PASSIVE
jne .skip_port_check
 
push ebx
mov eax, ebx
xchg al, ah
mov ebx, net_sockets
 
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .last_socket
cmp [ebx + SOCKET.TCBState], TCB_LISTEN
jne .next_socket
cmp [ebx + SOCKET.LocalPort], ax
jne .next_socket
 
xchg al, ah
DEBUGF 1, "K : error: port %u is listened by 0x%x\n", ax, ebx
pop ebx
jmp .error
 
.last_socket:
pop ebx
 
.skip_port_check:
call net_socket_alloc
or eax, eax
jz .error
 
DEBUGF 1, "K : socket_open_tcp (0x%x)\n", eax
 
mov [sockAddr], eax
 
; TODO - check this works!
;mov [eax + SOCKET.wndsizeTimer], 0 ; Reset the window timer.
 
call set_local_port
jc .error.free
xchg ch, cl
mov [eax + SOCKET.RemotePort], cx
mov [eax + SOCKET.OrigRemotePort], cx
mov ebx, [stack_ip]
mov [eax + SOCKET.LocalIP], ebx
mov [eax + SOCKET.RemoteIP], edx
mov [eax + SOCKET.OrigRemoteIP], edx
 
mov ebx, TCB_LISTEN
cmp esi, SOCKET_PASSIVE
je @f
mov ebx, TCB_SYN_SENT
@@: mov [eax + SOCKET.TCBState], ebx ; Indicate the state of the TCB
 
cmp ebx, TCB_LISTEN
je .exit
 
; Now, if we are in active mode, then we have to send a SYN to the specified remote port
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
 
push eax
 
mov bl, TH_SYN
xor ecx, ecx
stdcall build_tcp_packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
 
mov esi, [sockAddr]
 
; increment SND.NXT in socket
add esi, SOCKET.SND_NXT
call inc_inet_esi
 
.exit:
; Get the socket number back, so we can return it
stdcall net_socket_addr_to_num, [sockAddr]
ret
 
.error.free:
stdcall net_socket_free, eax
 
.error:
DEBUGF 1, "K : socket_open_tcp (fail)\n"
or eax, -1
ret
endp
 
;; [53.1] Close DGRAM socket
;
; @param EBX is socket number
; @return 0 (closed successfully) or -1 (error) in EAX
;;
proc socket_close stdcall
DEBUGF 1, "K : socket_close (0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx
or eax, eax
jz .error
 
stdcall net_socket_free, eax
 
xor eax, eax
ret
 
.error:
DEBUGF 1, "K : socket_close (fail)\n"
or eax, -1
ret
endp
 
;; [53.8] Close STREAM socket
; Closing TCP sockets takes time, so when you get successful return code
; from this function doesn't always mean that socket is actually closed.
;
; @param EBX is socket number
; @return 0 (closed successfully) or -1 (error) in EAX
;;
proc socket_close_tcp stdcall
local sockAddr dd ?
 
DEBUGF 1, "K : socket_close_tcp (0x%x)\n", ebx
; first, remove any resend entries
pusha
 
mov esi, resendQ
mov ecx, 0
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
je .last_resendq ; None left
cmp [esi + 4], ebx
je @f ; found one
inc ecx
add esi, 8
jmp .next_resendq
 
@@: mov dword[esi + 4], 0
inc ecx
add esi, 8
jmp .next_resendq
 
.last_resendq:
popa
 
stdcall net_socket_num_to_addr, ebx
or eax, eax
jz .error
 
mov ebx, eax
mov [sockAddr], eax
 
cmp [ebx + SOCKET.TCBState], TCB_LISTEN
je .destroy_tcb
cmp [ebx + SOCKET.TCBState], TCB_SYN_SENT
je .destroy_tcb
cmp [ebx + SOCKET.TCBState], TCB_CLOSED
je .destroy_tcb
 
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .error
 
push eax
 
mov bl, TH_FIN+TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_packet, [sockAddr]
 
mov ebx, [sockAddr]
; increament SND.NXT in socket
lea esi, [ebx + SOCKET.SND_NXT]
call inc_inet_esi
 
; Get the socket state
mov eax, [ebx + SOCKET.TCBState]
cmp eax, TCB_SYN_RECEIVED
je .fin_wait_1
cmp eax, TCB_ESTABLISHED
je .fin_wait_1
 
; assume CLOSE WAIT
; Send a fin, then enter last-ack state
mov [ebx + SOCKET.TCBState], TCB_LAST_ACK
jmp .send
 
.fin_wait_1:
; Send a fin, then enter finwait2 state
mov [ebx + SOCKET.TCBState], TCB_FIN_WAIT_1
 
.send:
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
jmp .exit
 
.destroy_tcb:
 
; Clear the socket variables
stdcall net_socket_free, ebx
 
.exit:
xor eax, eax
ret
 
.error:
DEBUGF 1, "K : socket_close_tcp (fail)\n"
or eax, -1
ret
endp
 
;; [53.2] Poll socket
;
; @param EBX is socket number
; @return count or bytes in rx buffer or 0 (error) in EAX
;;
proc socket_poll stdcall
; DEBUGF 1, "socket_poll(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx
or eax, eax
jz .error
 
mov eax, [eax + SOCKET.rxDataCount]
ret
 
.error:
xor eax, eax
ret
endp
 
;; [53.6] Get socket TCB state
;
; @param EBX is socket number
; @return socket TCB state or 0 (error) in EAX
;;
proc socket_status stdcall
;; DEBUGF 1, "socket_status(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx
or eax, eax
jz .error
 
mov eax, [eax + SOCKET.TCBState]
ret
 
.error:
xor eax, eax
ret
endp
 
;; [53.3] Get one byte from rx buffer
; This function can return 0 in two cases: if there's one byte read and
; non left, and if an error occured. Behavior should be changed and function
; shouldn't be used for now. Consider using [53.11] instead.
;
; @param EBX is socket number
; @return number of bytes left in rx buffer or 0 (error) in EAX
; @return byte read in BL
;;
proc socket_read stdcall
; DEBUGF 1, "socket_read(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx
or eax, eax
jz .error
 
lea ebx, [eax + SOCKET.lock]
call wait_mutex
 
mov ebx, eax
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes
test eax, eax
jz .error_release
 
dec eax
mov esi, ebx ; esi is address of socket
mov [ebx + SOCKET.rxDataCount], eax ; store new count
movzx eax, byte[ebx + SOCKET.rxData] ; get the byte
 
mov ecx, SOCKETBUFFSIZE - SOCKET.rxData - 1
lea edi, [esi + SOCKET.rxData]
lea esi, [edi + 1]
cld
push ecx
shr ecx, 2
rep movsd
pop ecx
and ecx, 3
rep movsb
 
mov [ebx + SOCKET.lock], 0
mov ebx, eax
 
ret
 
.error_release:
mov [ebx + SOCKET.lock], 0
.error:
xor ebx, ebx
ret
endp
 
;; [53.11] Get specified number of bytes from rx buffer
; Number of bytes in rx buffer can be less than requested size. In this case,
; only available number of bytes is read.
; This function can return 0 in two cases: if there's no data to read, and if
; an error occured. Behavior should be changed.
;
; @param EBX is socket number
; @param ECX is pointer to application buffer
; @param EDX is application buffer size (number of bytes to read)
; @return number of bytes read or 0 (error) in EAX
;;
proc socket_read_packet stdcall
; DEBUGF 1, "socket_read_packet(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx ; get real socket address
or eax, eax
jz .error
 
lea ebx, [eax + SOCKET.lock]
call wait_mutex
 
mov ebx, eax
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes
test eax, eax ; if count of bytes is zero..
jz .exit ; exit function (eax will be zero)
 
test edx, edx ; if buffer size is zero, copy all data
jz .copy_all_bytes
cmp edx, eax ; if buffer size is larger then the bytes of data, copy all data
jge .copy_all_bytes
 
sub eax, edx ; store new count (data bytes in buffer - bytes we're about to copy)
mov [ebx + SOCKET.rxDataCount], eax ;
push eax
mov eax, edx ; number of bytes we want to copy must be in eax
call .start_copy ; copy to the application
 
mov esi, ebx ; now we're going to copy the remaining bytes to the beginning
add esi, SOCKET.rxData ; we dont need to copy the header
mov edi, esi ; edi is where we're going to copy to
add esi, edx ; esi is from where we copy
pop ecx ; count of bytes we have left
push ecx ; push it again so we can re-use it later
shr ecx, 2 ; divide eax by 4
cld
rep movsd ; copy all full dwords
pop ecx
and ecx, 3
rep movsb ; copy remaining bytes
 
.exit:
mov [ebx + SOCKET.lock], 0
ret ; at last, exit
 
.error:
xor eax, eax
ret
 
.copy_all_bytes:
xor esi, esi
mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero)
call .start_copy
mov [ebx + SOCKET.lock], 0
ret
 
.start_copy:
mov edi, ecx
mov esi, ebx
add esi, SOCKET.rxData ; we dont need to copy the header
mov ecx, eax ; eax is count of bytes
push ecx
shr ecx, 2 ; divide eax by 4
cld ; copy all full dwords
rep movsd
pop ecx
and ecx, 3
rep movsb ; copy the rest bytes
retn ; exit, or go back to shift remaining bytes if any
endp
 
;; [53.4] Send data through DGRAM socket
;
; @param EBX is socket number
; @param ECX is application data size (number of bytes to send)
; @param EDX is pointer to application data buffer
; @return 0 (sent successfully) or -1 (error) in EAX
;;
proc socket_write stdcall
; DEBUGF 1, "socket_write(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx ; get real socket address
or eax, eax
jz .error
 
mov ebx, eax
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .error
 
; Save the queue entry number
push eax
 
; save the pointers to the data buffer & size
push edx
push ecx
 
; convert buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
 
mov edx, eax
 
; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
 
; Fill in the IP header (some data is in the socket descriptor)
mov eax, [ebx + SOCKET.LocalIP]
mov [edx + IP_PACKET.SourceAddress], eax
mov eax, [ebx + SOCKET.RemoteIP]
mov [edx + IP_PACKET.DestinationAddress], eax
 
mov [edx + IP_PACKET.VersionAndIHL], 0x45
mov [edx + IP_PACKET.TypeOfService], 0
 
pop eax ; Get the UDP data length
push eax
 
add eax, 20 + 8 ; add IP header and UDP header lengths
xchg al, ah
mov [edx + IP_PACKET.TotalLength], ax
xor eax, eax
mov [edx + IP_PACKET.Identification], ax
mov [edx + IP_PACKET.FlagsAndFragmentOffset], 0x0040
mov [edx + IP_PACKET.TimeToLive], 0x20
mov [edx + IP_PACKET.Protocol], PROTOCOL_UDP
 
; Checksum left unfilled
mov [edx + IP_PACKET.HeaderChecksum], ax
 
; Fill in the UDP header (some data is in the socket descriptor)
mov ax, [ebx + SOCKET.LocalPort]
mov [edx + 20 + UDP_PACKET.SourcePort], ax
 
mov ax, [ebx + SOCKET.RemotePort]
mov [edx + 20 + UDP_PACKET.DestinationPort], ax
 
pop eax
push eax
 
add eax, 8
xchg al, ah
mov [edx + 20 + UDP_PACKET.Length], ax
 
; Checksum left unfilled
xor eax, eax
mov [edx + 20 + UDP_PACKET.Checksum], ax
 
pop ecx ; count of bytes to send
mov ebx, ecx ; need the length later
pop eax ; get callers ptr to data to send
 
; Get the address of the callers data
mov edi, [TASK_BASE]
add edi, TASKDATA.mem_start
add eax, [edi]
mov esi, eax
 
mov edi, edx
add edi, 28
cld
rep movsb ; copy the data across
 
; we have edx as IPbuffer ptr.
; Fill in the UDP checksum
; First, fill in pseudoheader
mov eax, [edx + IP_PACKET.SourceAddress]
mov [pseudoHeader], eax
mov eax, [edx + IP_PACKET.DestinationAddress]
mov [pseudoHeader + 4], eax
mov word[pseudoHeader + 8], PROTOCOL_UDP shl 8 + 0 ; 0 + protocol
add ebx, 8
mov eax, ebx
xchg al, ah
mov [pseudoHeader + 10], ax
 
mov eax, pseudoHeader
mov [checkAdd1], eax
mov [checkSize1], word 12
mov eax, edx
add eax, 20
mov [checkAdd2], eax
mov eax, ebx
mov [checkSize2], ax ; was eax!! mjh 8/7/02
 
call checksum
 
; store it in the UDP checksum ( in the correct order! )
mov ax, [checkResult]
 
; If the UDP checksum computes to 0, we must make it 0xffff
; (0 is reserved for 'not used')
test ax, ax
jnz @f
mov ax, 0xffff
 
@@: xchg al, ah
mov [edx + 20 + UDP_PACKET.Checksum], ax
 
; Fill in the IP header checksum
GET_IHL ecx,edx ; get IP-Header length
stdcall checksum_jb,edx,ecx ; buf_ptr, buf_size
xchg al, ah
mov [edx + IP_PACKET.HeaderChecksum], ax
 
; Check destination IP address.
; If it is the local host IP, route it back to IP_RX
 
pop ebx
 
mov eax, NET1OUT_QUEUE
mov ecx, [edx + SOCKET.RemoteIP]
mov edx, [stack_ip]
cmp edx, ecx
jne .not_local
mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
call queue
 
xor eax, eax
ret
 
.error:
or eax, -1
ret
endp
 
;; [53.7] Send data through STREAM socket
;
; @param EBX is socket number
; @param ECX is application data size (number of bytes to send)
; @param EDX is pointer to application data buffer
; @return 0 (sent successfully) or -1 (error) in EAX
;;
proc socket_write_tcp stdcall
local sockAddr dd ?
 
; DEBUGF 1, "socket_write_tcp(0x%x)\n", ebx
stdcall net_socket_num_to_addr, ebx
or eax, eax
jz .error
 
mov ebx, eax
mov [sockAddr], ebx
 
; If the sockets window timer is nonzero, do not queue packet
cmp [ebx + SOCKET.wndsizeTimer], 0
jne .error
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .error
 
push eax
 
; Get the address of the callers data
mov edi, [TASK_BASE]
add edi, TASKDATA.mem_start
add edx, [edi]
mov esi, edx
 
pop eax
push eax
 
push ecx
mov bl, TH_ACK
stdcall build_tcp_packet, [sockAddr]
pop ecx
 
; Check destination IP address.
; If it is the local host IP, route it back to IP_RX
 
pop ebx
push ecx
 
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
 
.not_local:
pop ecx
push ebx ; save ipbuffer number
 
call queue
 
mov esi, [sockAddr]
 
; increament SND.NXT in socket
; Amount to increment by is in ecx
add esi, SOCKET.SND_NXT
call add_inet_esi
 
pop ebx
 
; Copy the IP buffer to a resend queue
; If there isn't one, dont worry about it for now
mov esi, resendQ
mov ecx, 0
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
je .exit ; None found
cmp dword[esi + 4], 0
je @f ; found one
inc ecx
add esi, 8
jmp .next_resendq
 
@@: push ebx
 
; OK, we have a buffer descriptor ptr in esi.
; resend entry # in ecx
; Populate it
; socket #
; retries count
; retry time
; fill IP buffer associated with this descriptor
 
stdcall net_socket_addr_to_num, [sockAddr]
mov [esi + 4], eax
mov byte[esi + 1], TCP_RETRIES
mov word[esi + 2], TCP_TIMEOUT
 
inc ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
mov edi, resendBuffer - IPBUFFSIZE
 
@@: add edi, IPBUFFSIZE
loop @b
 
; we have dest buffer location in edi
pop eax
; convert source buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
mov esi, eax
 
; do copy
mov ecx, IPBUFFSIZE
cld
rep movsb
 
.exit:
xor eax, eax
ret
 
.error:
or eax, -1
ret
endp
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/tcp.inc
0,0 → 1,1169
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; TCP.INC ;;
;; ;;
;; TCP Processes for Menuet OS TCP/IP stack ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; v0.6 : Added reset handling in the established state ;;
;; Added a timer per socket to allow delays when ;;
;; rx window gets below 1KB ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; TCP TCB states
TCB_LISTEN equ 1
TCB_SYN_SENT equ 2
TCB_SYN_RECEIVED equ 3
TCB_ESTABLISHED equ 4
TCB_FIN_WAIT_1 equ 5
TCB_FIN_WAIT_2 equ 6
TCB_CLOSE_WAIT equ 7
TCB_CLOSING equ 8
TCB_LAST_ACK equ 9
TCB_TIMED_WAIT equ 10
TCB_CLOSED equ 11
 
TH_FIN = 0x01
TH_SYN = 0x02
TH_RST = 0x04
TH_PUSH = 0x08
TH_ACK = 0x10
TH_URG = 0x20
 
TWOMSL equ 10 ; # of secs to wait before closing socket
 
TCP_RETRIES equ 5 ; Number of times to resend a packet
TCP_TIMEOUT equ 20 ; resend if not replied to in x hs
 
;*******************************************************************
; Interface
;
; tcp_tx_handler Handles the TCP transmit queue
; tcp_rx The protocol handler for received data
; buildTCPPacket fills in the packet headers and data
; tcpStateMachine Main state machine for received TCP packets
; tcp_tcb_handler 1s timer, to erase tcb's in TIME_WAIT state
;
;*******************************************************************
 
 
; TCP Payload ( Data field in IP datagram )
;
; 0 1 2 3
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;20 | Source Port | Destination Port |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;24 | Sequence Number |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;28 | Acknowledgment Number |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;32 | Data | |U|A|P|R|S|F| |
; | Offset| Reserved |R|C|S|S|Y|I| Window |
; | | |G|K|H|T|N|N| |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;36 | Checksum | Urgent Pointer |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;40 | Options | Padding |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | data
 
 
struc TCP_PACKET
{ .SourcePort dw ? ;+00
.DestinationPort dw ? ;+02
.SequenceNumber dd ? ;+04
.AckNumber dd ? ;+08
.DataOffset db ? ;+12 - DataOffset[0-3 bits] and Reserved[4-7]
.Flags db ? ;+13 - Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN
.Window dw ? ;+14
.Checksum dw ? ;+16
.UrgentPointer dw ? ;+18
.Options rb 3 ;+20
.Padding db ? ;+23
.Data db ? ;+24
}
 
virtual at 0
TCP_PACKET TCP_PACKET
end virtual
 
 
 
;***************************************************************************
; Function
; tcp_tcb_handler
;
; Description
; Handles sockets in the timewait state, closing them
; when the TCB timer expires
;
;***************************************************************************
 
proc tcp_tcb_handler stdcall uses ebx
; scan through all the sockets, decrementing active timers
 
mov ebx, net_sockets
 
cmp [ebx + SOCKET.NextPtr], 0
je .exit
;DEBUGF 1, "K : sockets:\n"
 
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .exit
 
;DEBUGF 1, "K : %x-%x: %x-%x-%x-%u\n", [ebx + SOCKET.PID]:2, [ebx + SOCKET.Number]:2, [ebx + SOCKET.LocalPort]:4, [ebx + SOCKET.RemoteIP], [ebx + SOCKET.RemotePort]:4, [ebx + SOCKET.TCBState]
 
cmp [ebx + SOCKET.TCBTimer], 0
jne .decrement_tcb
cmp [ebx + SOCKET.wndsizeTimer], 0
jne .decrement_wnd
jmp .next_socket
 
.decrement_tcb:
; decrement it, delete socket if TCB timer = 0 & socket in timewait state
dec [ebx + SOCKET.TCBTimer]
jnz .next_socket
 
cmp [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
jne .next_socket
 
push [ebx + SOCKET.PrevPtr]
stdcall net_socket_free, ebx
pop ebx
jmp .next_socket
 
.decrement_wnd:
; TODO - prove it works!
dec [ebx + SOCKET.wndsizeTimer]
jmp .next_socket
 
.exit:
ret
endp
 
 
;***************************************************************************
; Function
; tcp_tx_handler
;
; Description
; Handles queued TCP data
; This is a kernel function, called by stack_handler
;
;***************************************************************************
 
proc tcp_tx_handler stdcall
; decrement all resend buffers timers. If they
; expire, queue them for sending, and restart the timer.
; If the retries counter reach 0, delete the entry
 
mov esi, resendQ
mov ecx, 0
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
je .exit ; None left
cmp dword[esi + 4], 0
jne @f ; found one
inc ecx
add esi, 8
jmp .next_resendq
 
@@: ; we have one. decrement it's timer by 1
dec word[esi + 2]
jz @f
inc ecx
add esi, 8
jmp .next_resendq ; Timer not zero, so move on
 
@@:
xor ebx, ebx
; restart timer, and decrement retries
; After the first resend, back of on next, by a factor of 5
mov [esi + 2], word TCP_TIMEOUT * 5
dec byte[esi + 1]
jnz @f
 
; retries now 0, so delete from queue
xchg [esi + 4], ebx
 
@@: ; resend packet
pushad
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
jne .tth004z
 
; TODO - try again in 10ms.
test ebx, ebx
jnz @f
mov [esi + 4], ebx
 
@@: ; Mark it to expire in 10ms - 1 tick
mov byte[esi + 1], 1
mov word[esi + 2], 1
jmp .tth005
 
.tth004z:
; we have a buffer # in ax
push eax ecx
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
 
; we have the buffer address in eax
mov edi, eax
pop ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
imul esi, ecx, IPBUFFSIZE
add esi, resendBuffer
 
; we have resend buffer location in esi
mov ecx, IPBUFFSIZE
 
; copy data across
push edi
cld
rep movsb
pop edi
 
; queue packet
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
cmp edx, [edi + IP_PACKET.DestinationAddress]
jne .not_local
mov eax, IPIN_QUEUE
 
.not_local:
pop ebx
call queue
 
.tth005:
popad
 
inc ecx
add esi, 8
jmp .next_resendq
 
.exit:
ret
endp
 
 
;***************************************************************************
; Function
; tcp_rx
;
; Description
; TCP protocol handler
; This is a kernel function, called by ip_rx
; IP buffer address given in edx
; IP buffer number in eax
; Free up (or re-use) IP buffer when finished
;
;***************************************************************************
 
proc tcp_rx stdcall uses ebx
; The process is as follows.
; Look for a socket with matching remote IP, remote port, local port
; if not found, then
; look for remote IP + local port match ( where sockets remote port = 0)
; if not found, then
; look for a socket where local socket port == IP packets remote port
; where sockets remote port, remote IP = 0
; discard if not found
; Call sockets tcbStateMachine, with pointer to packet.
; the state machine will not delete the packet, so do that here.
 
push eax
 
; Look for a socket where
; IP Packet TCP Destination Port = local Port
; IP Packet SA = Remote IP
; IP Packet TCP Source Port = remote Port
 
mov ebx, net_sockets
 
.next_socket.1:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .next_socket.1.exit
 
; DEBUGF 1, "K : tcp_rx - 1.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
 
mov ax, [edx + 20 + TCP_PACKET.DestinationPort] ; get the dest. port from the TCP hdr
cmp [ebx + SOCKET.LocalPort], ax ; get the dest. port from the TCP hdr
jne .next_socket.1 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 1.addr: %x - %x\n", [edx + IP_PACKET.SourceAddress], [ebx + SOCKET.RemoteIP]
 
mov eax, [edx + IP_PACKET.SourceAddress] ; get the source IP Addr from the IP hdr
cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP
jne .next_socket.1 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 1.sport: %x - %x\n", [edx + 20 + TCP_PACKET.SourcePort]:4, [ebx + SOCKET.RemotePort]:4
 
mov ax, [edx + 20 + TCP_PACKET.SourcePort] ; get the source port from the TCP hdr
cmp [ebx + SOCKET.RemotePort], ax ; compare with socket's remote port
jne .next_socket.1 ; different - try next socket
 
; We have a complete match - use this socket
jmp .change_state
 
.next_socket.1.exit:
 
; If we got here, there was no match
; Look for a socket where
; IP Packet TCP Destination Port = local Port
; IP Packet SA = Remote IP
; socket remote Port = 0
 
mov ebx, net_sockets
 
.next_socket.2:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .next_socket.2.exit
 
; DEBUGF 1, "K : tcp_rx - 2.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
 
mov ax, [edx + 20 + TCP_PACKET.DestinationPort] ; get the dest. port from the TCP hdr
cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port
jne .next_socket.2 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 2.addr: %x - %x\n", [edx + IP_PACKET.SourceAddress], [ebx + SOCKET.RemoteIP]
 
mov eax, [edx + IP_PACKET.SourceAddress] ; get the source IP Addr from the IP hdr
cmp [ebx + SOCKET.RemoteIP], eax ; compare with socket's remote IP
jne .next_socket.2 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 2.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4
 
cmp [ebx + SOCKET.RemotePort], 0 ; only match a remote socket of 0
jne .next_socket.2 ; different - try next socket
 
; We have a complete match - use this socket
jmp .change_state
 
.next_socket.2.exit:
 
; If we got here, there was no match
; Look for a socket where
; IP Packet TCP Destination Port = local Port
; socket Remote IP = 0
; socket remote Port = 0
 
mov ebx, net_sockets
 
.next_socket.3:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .next_socket.3.exit
 
; DEBUGF 1, "K : tcp_rx - 3.dport: %x - %x\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [ebx + SOCKET.LocalPort]:4
 
mov ax, [edx + 20 + TCP_PACKET.DestinationPort] ; get destination port from the TCP hdr
cmp [ebx + SOCKET.LocalPort], ax ; compare with socket's local port
jne .next_socket.3 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 3.addr: 00000000 - %x\n", [ebx + SOCKET.RemoteIP]
 
cmp [ebx + SOCKET.RemoteIP], 0 ; only match a socket remote IP of 0
jne .next_socket.3 ; different - try next socket
 
; DEBUGF 1, "K : tcp_rx - 3.sport: 0000 - %x\n", [ebx + SOCKET.RemotePort]:4
 
cmp [ebx + SOCKET.RemotePort], 0 ; only match a remote socket of 0
jne .next_socket.3 ; different - try next socket
 
; We have a complete match - use this socket
jmp .change_state
 
.next_socket.3.exit:
 
; If we got here, we need to reject the packet
 
DEBUGF 1, "K : tcp_rx - dumped\n"
DEBUGF 1, "K : --------: %x-%x-%x (flags: %x)\n", [edx + 20 + TCP_PACKET.DestinationPort]:4, [edx + IP_PACKET.SourceAddress], [edx + 20 + TCP_PACKET.SourcePort]:4, [edx + 20 + TCP_PACKET.Flags]:2
 
inc [dumped_rx_count]
jmp .exit
 
.change_state:
 
; We have a valid socket/TCB, so call the TCB State Machine for that skt.
; socket is pointed to by ebx
; IP packet is pointed to by edx
; IP buffer number is on stack ( it will be popped at the end)
 
stdcall tcpStateMachine, ebx
 
.exit:
pop eax
call freeBuff
ret
endp
 
 
;***************************************************************************
; Function
; buildTCPPacket
;
; Description
; builds an IP Packet with TCP data fully populated for transmission
; You may destroy any and all registers
; TCP control flags specified in bl
; This TCB is in [sktAddr]
; User data pointed to by esi
; Data length in ecx
; Transmit buffer number in eax
;
;***************************************************************************
 
proc build_tcp_packet stdcall, sockAddr:DWORD
push ecx ; Save data length
 
; convert buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
 
mov edx, eax
 
mov [edx + 20 + TCP_PACKET.Flags], bl ; TCP flags
 
mov ebx, [sockAddr]
 
; So, ebx holds the socket ptr, edx holds the IPbuffer ptr
 
; Fill in the IP header ( some data is in the socket descriptor)
mov eax, [ebx + SOCKET.LocalIP]
mov [edx + IP_PACKET.SourceAddress], eax
mov eax, [ebx + SOCKET.RemoteIP]
mov [edx + IP_PACKET.DestinationAddress], eax
 
mov [edx + IP_PACKET.VersionAndIHL], 0x45
mov [edx + IP_PACKET.TypeOfService], 0
 
pop eax ; Get the TCP data length
push eax
 
add eax, 20 + 20 ; add IP header and TCP header lengths
rol ax, 8
mov [edx + IP_PACKET.TotalLength], ax
mov [edx + IP_PACKET.Identification], 0
mov [edx + IP_PACKET.FlagsAndFragmentOffset], 0x0040
mov [edx + IP_PACKET.TimeToLive], 0x20
mov [edx + IP_PACKET.Protocol], PROTOCOL_TCP
 
; Checksum left unfilled
mov [edx + IP_PACKET.HeaderChecksum], 0
 
; Fill in the TCP header (some data is in the socket descriptor)
mov ax, [ebx + SOCKET.LocalPort]
mov [edx + 20 + TCP_PACKET.SourcePort], ax ; Local Port
 
mov ax, [ebx + SOCKET.RemotePort]
mov [edx + 20 + TCP_PACKET.DestinationPort], ax ; desitination Port
 
; Checksum left unfilled
mov [edx + 20 + TCP_PACKET.Checksum], 0
 
; sequence number
mov eax, [ebx + SOCKET.SND_NXT]
mov [edx + 20 + TCP_PACKET.SequenceNumber], eax
 
; ack number
mov eax, [ebx + SOCKET.RCV_NXT]
mov [edx + 20 + TCP_PACKET.AckNumber], eax
 
; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size)
; 768 bytes seems better
mov [edx + 20 + TCP_PACKET.Window], 0x0003
 
; Urgent pointer (0)
mov [edx + 20 + TCP_PACKET.UrgentPointer], 0
 
; data offset ( 0x50 )
mov [edx + 20 + TCP_PACKET.DataOffset], 0x50
 
pop ecx ; count of bytes to send
mov ebx, ecx ; need the length later
 
cmp ebx, 0
jz @f
 
mov edi, edx
add edi, 40
cld
rep movsb ; copy the data across
 
@@: ; we have edx as IPbuffer ptr.
; Fill in the TCP checksum
; First, fill in pseudoheader
mov eax, [edx + IP_PACKET.SourceAddress]
mov [pseudoHeader], eax
mov eax, [edx + IP_PACKET.DestinationAddress]
mov [pseudoHeader + 4], eax
mov word[pseudoHeader + 8], PROTOCOL_TCP shl 8 + 0
add ebx, 20
mov [pseudoHeader + 10], bh
mov [pseudoHeader + 11], bl
 
mov eax, pseudoHeader
mov [checkAdd1], eax
mov word[checkSize1], 12
mov eax, edx
add eax, 20
mov [checkAdd2], eax
mov eax, ebx
mov [checkSize2], ax
 
call checksum
 
; store it in the TCP checksum ( in the correct order! )
mov ax, [checkResult]
rol ax, 8
mov [edx + 20 + TCP_PACKET.Checksum], ax
 
; Fill in the IP header checksum
GET_IHL eax, edx ; get IP-Header length
stdcall checksum_jb, edx, eax ; buf_ptr, buf_size
rol ax, 8
mov [edx + IP_PACKET.HeaderChecksum], ax
 
ret
endp
 
 
; Increments the 32 bit value pointed to by esi in internet order
proc inc_inet_esi stdcall
push eax
mov eax, [esi]
bswap eax
inc eax
bswap eax
mov [esi], eax
pop eax
ret
endp
 
 
; Increments the 32 bit value pointed to by esi in internet order
; by the value in ecx
proc add_inet_esi stdcall
push eax
mov eax, [esi]
bswap eax
add eax, ecx
bswap eax
mov [esi], eax
pop eax
ret
endp
 
 
iglobal
TCBStateHandler dd \
stateTCB_LISTEN, \
stateTCB_SYN_SENT, \
stateTCB_SYN_RECEIVED, \
stateTCB_ESTABLISHED, \
stateTCB_FIN_WAIT_1, \
stateTCB_FIN_WAIT_2, \
stateTCB_CLOSE_WAIT, \
stateTCB_CLOSING, \
stateTCB_LAST_ACK, \
stateTCB_TIME_WAIT, \
stateTCB_CLOSED
endg
 
 
;***************************************************************************
; Function
; tcpStateMachine
;
; Description
; TCP state machine
; This is a kernel function, called by tcp_rx
;
; IP buffer address given in edx
; Socket/TCB address in ebx
;
; The IP buffer will be released by the caller
;***************************************************************************
 
proc tcpStateMachine stdcall, sockAddr:DWORD
; as a packet has been received, update the TCB timer
mov [ebx + SOCKET.TCBTimer], TWOMSL
 
; If the received packet has an ACK bit set,
; remove any packets in the resend queue that this
; received packet acknowledges
pushad
test [edx + 20 + TCP_PACKET.Flags], TH_ACK
jz .call_handler ; No ACK, so no data yet
 
; get skt number in eax
stdcall net_socket_addr_to_num, ebx
 
; The ack number is in [edx + 28], inet format
; skt in eax
 
mov esi, resendQ
xor ecx, ecx
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
je .call_handler ; None left
cmp [esi + 4], eax
je @f ; found one
inc ecx
add esi, 8
jmp .next_resendq
 
@@: ; Can we delete this buffer?
 
; If yes, goto @@. No, goto .next_resendq
; Get packet data address
 
push ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
imul edi, ecx, IPBUFFSIZE
add edi, resendBuffer
 
; we have dest buffer location in edi. incoming packet in edx.
; Get this packets sequence number
; preserve al, ecx, esi, edx
mov ecx, [edi + 20 + TCP_PACKET.SequenceNumber]
bswap ecx
movzx ebx, word[edi + 2]
xchg bl, bh
sub ebx, 40
add ecx, ebx ; ecx is now seq# of last byte +1, intel format
 
; get recievd ack #, in intel format
mov ebx, [edx + 20 + TCP_PACKET.AckNumber]
bswap ebx
 
cmp ebx, ecx ; Finally. ecx = rx'ed ack. ebx = last byte in que
; DANGER! need to handle case that we have just
; passed the 2**32, and wrapped round!
pop ecx
jae @f ; if rx > old, delete old
 
inc ecx
add esi, 8
jmp .next_resendq
 
@@: mov dword[esi + 4], 0
inc ecx
add esi, 8
jmp .next_resendq
 
.call_handler:
popad
 
; Call handler for given TCB state
 
mov eax, [ebx + SOCKET.TCBState]
cmp eax, TCB_LISTEN
jb .exit
cmp eax, TCB_CLOSED
ja .exit
 
stdcall [TCBStateHandler + (eax - 1) * 4], [sockAddr]
 
.exit:
ret
endp
 
;***************************************************************************
; Function
; signal_network_event
;
; Description
; Signals about network event to socket owner
; This is a kernel function, called from TCP handler
;
; Socket/TCB address in ebx
;***************************************************************************
proc signal_network_event
push ecx esi eax
mov eax, [ebx + SOCKET.PID]
mov ecx, 1
mov esi, TASK_DATA + TASKDATA.pid
 
.next_pid:
cmp [esi], eax
je .found_pid
inc ecx
add esi, 0x20
cmp ecx, [TASK_COUNT]
jbe .next_pid
 
.found_pid:
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
pop eax esi ecx
ret
endp
 
proc stateTCB_LISTEN stdcall, sockAddr:DWORD
; In this case, we are expecting a SYN packet
; For now, if the packet is a SYN, process it, and send a response
; If not, ignore it
 
; Look at control flags
test [edx + 20 + TCP_PACKET.Flags], TH_SYN
jz .exit
 
; We have a SYN. update the socket with this IP packets details,
; And send a response
 
mov eax, [edx + IP_PACKET.SourceAddress]
mov [ebx + SOCKET.RemoteIP], eax
mov ax, [edx + 20 + TCP_PACKET.SourcePort]
mov [ebx + SOCKET.RemotePort], ax
mov eax, [edx + 20 + TCP_PACKET.SequenceNumber]
mov [ebx + SOCKET.IRS], eax
mov [ebx + SOCKET.RCV_NXT], eax
lea esi, [ebx + SOCKET.RCV_NXT]
call inc_inet_esi ; RCV.NXT
mov eax, [ebx + SOCKET.ISS]
mov [ebx + SOCKET.SND_NXT], eax
 
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
 
push ebx
push eax
mov bl, TH_SYN + TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
 
pop ebx
mov esi, [sockAddr]
mov [esi + SOCKET.TCBState], TCB_SYN_RECEIVED
call signal_network_event
 
; increment SND.NXT in socket
add esi, SOCKET.SND_NXT
call inc_inet_esi
 
.exit:
ret
endp
 
 
proc stateTCB_SYN_SENT stdcall, sockAddr:DWORD
; We are awaiting an ACK to our SYN, with a SYM
; Look at control flags - expecting an ACK
 
mov al, [edx + 20 + TCP_PACKET.Flags]
and al, TH_SYN + TH_ACK
cmp al, TH_SYN + TH_ACK
je .syn_ack
 
test al, TH_SYN
jz .exit
 
mov [ebx + SOCKET.TCBState], TCB_SYN_RECEIVED
push TH_SYN + TH_ACK
jmp .send
 
.syn_ack:
mov [ebx + SOCKET.TCBState], TCB_ESTABLISHED
push TH_ACK
 
.send:
call signal_network_event
; Store the recv.nxt field
mov eax, [edx + 20 + TCP_PACKET.SequenceNumber]
 
; Update our recv.nxt field
mov [ebx + SOCKET.RCV_NXT], eax
lea esi, [ebx + SOCKET.RCV_NXT]
call inc_inet_esi
 
; Send an ACK
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
pop ebx
je .exit
 
push eax
 
xor ecx, ecx
xor esi, esi
stdcall build_tcp_packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
 
.exit:
ret
endp
 
 
proc stateTCB_SYN_RECEIVED stdcall, sockAddr:DWORD
; In this case, we are expecting an ACK packet
; For now, if the packet is an ACK, process it,
; If not, ignore it
 
test [edx + 20 + TCP_PACKET.Flags], TH_RST
jz .check_ack
 
push [ebx + SOCKET.OrigRemotePort] [ebx + SOCKET.OrigRemoteIP]
pop [ebx + SOCKET.RemoteIP] [ebx + SOCKET.RemotePort]
 
mov [ebx + SOCKET.TCBState], TCB_LISTEN
jmp .signal
 
.check_ack:
; Look at control flags - expecting an ACK
test [edx + 20 + TCP_PACKET.Flags], TH_ACK
jz .exit
 
mov [ebx + SOCKET.TCBState], TCB_ESTABLISHED
.signal:
call signal_network_event
 
.exit:
ret
endp
 
 
proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
; Here we are expecting data, or a request to close
; OR both...
 
; Ignore all packets with sequnce number other than next expected
 
; recv.nxt is in dword [edx+24], in inet format
; recv seq is in [sktAddr]+56, in inet format
; just do a comparision
mov eax, [ebx + SOCKET.RCV_NXT]
cmp eax, [edx + 20 + TCP_PACKET.SequenceNumber]
jne .exit
 
; Did we receive a FIN or RST?
test [edx + 20 + TCP_PACKET.Flags], TH_FIN+TH_RST
jz .check_ack
 
; It was a fin or reset.
 
; Remove resend entries from the queue - I dont want to send any more data
pushad
 
; get skt #
stdcall net_socket_addr_to_num, ebx
 
mov esi, resendQ
mov ecx, 0
 
.next_resendq:
cmp ecx, NUMRESENDENTRIES
je .last_resendq ; None left
cmp [esi + 4], eax
je @f ; found one
inc ecx
add esi, 8
jmp .next_resendq
 
@@: mov dword[esi + 4], 0
inc ecx
add esi, 8
jmp .next_resendq
 
.last_resendq:
popad
 
@@: ; Send an ACK to that fin, and enter closewait state
 
mov [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
test [edx + 20 + TCP_PACKET.Flags], TH_RST
je @f
mov [ebx + SOCKET.TCBState], TCB_CLOSED
@@:
call signal_network_event
lea esi, [ebx + SOCKET.RCV_NXT]
mov eax, [esi] ; save original
call inc_inet_esi
;; jmp ste_ack - NO, there may be data
 
.check_ack:
; Check that we received an ACK
test [edx + 20 + TCP_PACKET.Flags], TH_ACK
jz .exit
 
; TODO - done, I think!
; First, look at the incoming window. If this is less than or equal to 1024,
; Set the socket window timer to 1. This will stop an additional packets being queued.
; ** I may need to tweak this value, since I do not know how many packets are already queued
mov cx, [edx + 20 + TCP_PACKET.Window]
xchg cl, ch
cmp cx, 1024
ja @f
 
mov [ebx + SOCKET.wndsizeTimer], 1
 
@@: ; OK, here is the deal
 
 
; Read the data bytes, store in socket buffer
movzx ecx, [edx + IP_PACKET.TotalLength]
xchg cl, ch
sub ecx, 40 ; Discard 40 bytes of header
ja .data ; Read data, if any
 
; If we had received a fin, we need to ACK it.
cmp [ebx + SOCKET.TCBState], TCB_CLOSE_WAIT
je .ack
jmp .exit
 
.data:
push ebx
add ebx, SOCKET.lock
call wait_mutex
pop ebx
 
push ecx
push ebx
mov eax, [ebx + SOCKET.rxDataCount]
add eax, ecx
cmp eax, SOCKETBUFFSIZE - SOCKETHEADERSIZE
ja .overflow
 
mov [ebx + SOCKET.rxDataCount], eax ; increment the count of bytes in buffer
 
; point to the location to store the data
lea edi, [ebx + eax + SOCKETHEADERSIZE]
sub edi, ecx
 
add edx, 40 ; edx now points to the data
mov esi, edx
 
cld
rep movsb ; copy the data across
mov [ebx + SOCKET.lock], 0 ; release mutex
 
; flag an event to the application
pop ebx
call signal_network_event
 
pop ecx
 
; Update our recv.nxt field
lea esi, [ebx + SOCKET.RCV_NXT]
call add_inet_esi
 
.ack:
; Send an ACK
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
 
push eax
 
mov bl, TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
 
.exit:
ret
.overflow:
; no place in buffer
; so simply restore stack and exit
pop eax ecx
mov [ebx + SOCKET.lock], 0
ret
endp
 
 
proc stateTCB_FIN_WAIT_1 stdcall, sockAddr:DWORD
; We can either receive an ACK of a fin, or a fin
mov al, [edx + 20 + TCP_PACKET.Flags]
and al, TH_FIN + TH_ACK
 
cmp al, TH_ACK
jne @f
 
; It was an ACK
mov [ebx + SOCKET.TCBState], TCB_FIN_WAIT_2
jmp .exit
 
@@: mov [ebx + SOCKET.TCBState], TCB_CLOSING
cmp al, TH_FIN
je @f
mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
 
@@: lea esi, [ebx + SOCKET.RCV_NXT]
call inc_inet_esi
 
; Send an ACK
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
 
push eax
 
mov bl, TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
 
.exit:
ret
endp
 
 
proc stateTCB_FIN_WAIT_2 stdcall, sockAddr:DWORD
test [edx + 20 + TCP_PACKET.Flags], TH_FIN
jz .exit
 
; Change state, as we have a fin
mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
 
lea esi, [ebx + SOCKET.RCV_NXT]
call inc_inet_esi
 
; Send an ACK
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit
 
push eax
 
mov bl, TH_ACK
xor ecx, ecx
xor esi, esi
stdcall build_tcp_packet, [sockAddr]
 
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [sockAddr]
cmp edx, [ecx + SOCKET.RemoteIP]
jne .not_local
mov eax, IPIN_QUEUE
 
.not_local:
; Send it.
pop ebx
call queue
 
.exit:
ret
endp
 
 
proc stateTCB_CLOSE_WAIT stdcall, sockAddr:DWORD
; Intentionally left empty
; socket_close_tcp handles this
ret
endp
 
 
proc stateTCB_CLOSING stdcall, sockAddr:DWORD
; We can either receive an ACK of a fin, or a fin
test [edx + 20 + TCP_PACKET.Flags], TH_ACK
jz .exit
 
mov [ebx + SOCKET.TCBState], TCB_TIMED_WAIT
 
.exit:
ret
endp
 
 
proc stateTCB_LAST_ACK stdcall, sockAddr:DWORD
; Look at control flags - expecting an ACK
test [edx + 20 + TCP_PACKET.Flags], TH_ACK
jz .exit
 
; delete the socket
stdcall net_socket_free, ebx
 
.exit:
ret
endp
 
 
proc stateTCB_TIME_WAIT stdcall, sockAddr:DWORD
ret
endp
 
 
proc stateTCB_CLOSED stdcall, sockAddr:DWORD
ret
endp
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/queue.inc
0,0 → 1,229
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; QUEUE.INC ;;
;; ;;
;; Buffer queue management for Menuet OS TCP/IP Stack ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;*******************************************************************
; Interface
;
; queueInit Configures the queues to empty
; dequeue Removes a buffer pointer from a queue
; queue Inserts a buffer pointer into a queue
; freeBuff Adds the buffer pointer to the list of free buffers
; queueSize Returns the number of entries in a queue
;
; The various defines for queue names can be found in stack.inc
;
;*******************************************************************
 
 
;***************************************************************************
; Function
; freeBuff
;
; Description
; Adds a buffer number to the beginning of the free list.
; buffer number in eax ( ms word zeroed )
; all other registers preserved
; This always works, so no error returned
;***************************************************************************
;uglobal
; freeBuff_cnt dd ?
;endg
freeBuff:
; inc [freeBuff_cnt]
; DEBUGF 1, "K : freeBuff (%u)\n", [freeBuff_cnt]
push ebx
push ecx
mov ebx, queues + EMPTY_QUEUE * 2
cli ; Ensure that another process does not interfer
mov cx, [ebx]
mov [ebx], ax
mov [queueList + eax * 2], cx
sti
pop ecx
pop ebx
 
ret
 
 
;***************************************************************************
; Function
; queueSize
;
; Description
; Counts the number of entries in a queue
; queue number in ebx ( ms word zeroed )
; Queue size returned in eax
; This always works, so no error returned
;***************************************************************************
queueSize:
xor eax, eax
shl ebx, 1
add ebx, queues
movzx ecx, word [ebx]
cmp cx, NO_BUFFER
je qs_exit
 
qs_001:
inc eax
shl ecx, 1
add ecx, queueList
movzx ecx, word [ecx]
cmp cx, NO_BUFFER
je qs_exit
jmp qs_001
 
qs_exit:
ret
 
 
;***************************************************************************
; Function
; queue
;
; Description
; Adds a buffer number to the *end* of a queue
; This is quite quick because these queues will be short
; queue number in eax ( ms word zeroed )
; buffer number in ebx ( ms word zeroed )
; all other registers preserved
; This always works, so no error returned
;***************************************************************************
;uglobal
; queue_cnt dd ?
;endg
queue:
; inc [queue_cnt]
; DEBUGF 1, "K : queue (%u)\n", [queue_cnt]
push ebx
shl ebx, 1
add ebx, queueList ; eax now holds address of queue entry
mov [ebx], word NO_BUFFER ; This buffer will be the last
 
cli
shl eax, 1
add eax, queues ; eax now holds address of queue
movzx ebx, word [eax]
 
cmp bx, NO_BUFFER
jne qu_001
 
pop ebx
; The list is empty, so add this to the head
mov [eax], bx
jmp qu_exit
 
qu_001:
; Find the last entry
shl ebx, 1
add ebx, queueList
mov eax, ebx
movzx ebx, word [ebx]
cmp bx, NO_BUFFER
jne qu_001
 
mov ebx, eax
pop eax
mov [ebx], ax
 
qu_exit:
sti
ret
 
 
 
;***************************************************************************
; Function
; dequeue
;
; Description
; removes a buffer number from the head of a queue
; This is fast, as it unlinks the first entry in the list
; queue number in eax ( ms word zeroed )
; buffer number returned in eax ( ms word zeroed )
; all other registers preserved
;
;***************************************************************************
;uglobal
; dequeue_cnt dd ?
;endg
dequeue:
push ebx
shl eax, 1
add eax, queues ; eax now holds address of queue
mov ebx, eax
cli
movzx eax, word [eax]
cmp ax, NO_BUFFER
je dq_exit
; inc [dequeue_cnt]
; DEBUGF 1, "K : dequeue (%u)\n", [dequeue_cnt]
push eax
shl eax, 1
add eax, queueList ; eax now holds address of queue entry
mov ax, [eax]
mov [ebx], ax
pop eax
 
dq_exit:
sti
pop ebx
ret
 
 
;***************************************************************************
; Function
; queueInit
;
; Description
; Initialises the queues to empty, and creates the free queue
; list.
;
;***************************************************************************
queueInit:
mov esi, queues
mov ecx, NUMQUEUES
mov ax, NO_BUFFER
 
qi001:
mov [esi], ax
inc esi
inc esi
loop qi001
 
mov esi, queues + ( 2 * EMPTY_QUEUE )
 
; Initialise empty queue list
 
xor ax, ax
mov [esi], ax
 
mov ecx, NUMQUEUEENTRIES - 1
mov esi, queueList
 
qi002:
inc ax
mov [esi], ax
inc esi
inc esi
loop qi002
 
mov ax, NO_BUFFER
mov [esi], ax
 
ret
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/udp.inc
0,0 → 1,155
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ;;
;; UDP.INC ;;
;; ;;
;; UDP Processes for Menuet OS TCP/IP stack ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;*******************************************************************
; Interface
;
; udp_rx Handles received IP packets with the UDP protocol
;
;*******************************************************************
 
 
;
; UDP Payload ( Data field in IP datagram )
;
; 0 1 2 3
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
;
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Source Port | Destination Port |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Length ( UDP Header + Data ) | Checksum |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | UDP Data |
; +-+-+-.......... -+
;
 
struc UDP_PACKET
{ .SourcePort dw ? ;+00
.DestinationPort dw ? ;+02
.Length dw ? ;+04 - Length of (UDP Header + Data)
.Checksum dw ? ;+06
.Data db ? ;+08
}
 
virtual at 0
UDP_PACKET UDP_PACKET
end virtual
 
 
;***************************************************************************
; Function
; udp_rx [by Johnny_B]
;
; Description
; UDP protocol handler
; This is a kernel function, called by ip_rx
; IP buffer address given in edx
; IP buffer number in eax
; Free up (or re-use) IP buffer when finished
;
;***************************************************************************
 
proc udp_rx stdcall
push eax
 
; First validate the header & checksum. Discard buffer if error
 
; Look for a socket where
; IP Packet UDP Destination Port = local Port
; IP Packet SA = Remote IP
 
mov ax, [edx + 20 + UDP_PACKET.DestinationPort] ; get the local port from
; the IP packet's UDP header
 
mov ebx, net_sockets
 
.next_socket:
mov ebx, [ebx + SOCKET.NextPtr]
or ebx, ebx
jz .exit ; No match, so exit
cmp [ebx + SOCKET.LocalPort], ax ; ax will hold the 'wrong' value,
; but the comparision is correct
jne .next_socket ; Return back if no match
 
; For dhcp, we must allow any remote server to respond.
; I will accept the first incoming response to be the one
; I bind to, if the socket is opened with a destination IP address of
; 255.255.255.255
cmp [ebx + SOCKET.RemoteIP], 0xffffffff
je @f
 
mov eax, [edx + IP_PACKET.SourceAddress] ; get the Source address from the IP packet
cmp [ebx + SOCKET.RemoteIP], eax
jne .exit ; Quit if the source IP is not valid
 
@@: ; OK - we have a valid UDP packet for this socket.
; First, update the sockets remote port number with the incoming msg
; - it will have changed
; from the original ( 69 normally ) to allow further connects
mov ax, [edx + 20 + UDP_PACKET.SourcePort] ; get the UDP source port
; ( was 69, now new )
mov [ebx + SOCKET.RemotePort], ax
 
; Now, copy data to socket. We have socket address as [eax + sockets].
; We have IP packet in edx
 
; get # of bytes in ecx
movzx ecx, [edx + IP_PACKET.TotalLength] ; total length of IP packet. Subtract
xchg cl, ch ; 20 + 8 gives data length
sub ecx, 28
 
mov eax, [ebx + SOCKET.rxDataCount] ; get # of bytes already in buffer
add [ebx + SOCKET.rxDataCount], ecx ; increment the count of bytes in buffer
 
; ecx has count, edx points to data
 
add edx, 28 ; edx now points to the data
lea edi, [ebx + eax + SOCKETHEADERSIZE]
mov esi, edx
 
cld
rep movsb ; copy the data across
 
; flag an event to the application
mov eax, [ebx + SOCKET.PID] ; get socket owner PID
mov ecx, 1
mov esi, TASK_DATA + TASKDATA.pid
 
.next_pid:
cmp [esi], eax
je .found_pid
inc ecx
add esi, 0x20
cmp ecx, [TASK_COUNT]
jbe .next_pid
 
jmp .exit
 
.found_pid:
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
 
mov [check_idle_semaphore], 200
 
.exit:
pop eax
call freeBuff ; Discard the packet
ret
endp
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/ip.inc
0,0 → 1,244
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; IP.INC ;;
;; ;;
;; IP Processes for Menuet OS TCP/IP stack ;;
;; ;;
;; Version 0.3 29 August 2002 ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; IP underlying protocols numbers
PROTOCOL_ICMP equ 1
PROTOCOL_TCP equ 6
PROTOCOL_UDP equ 17
 
struc IP_PACKET
{ .VersionAndIHL db ? ;+00 - Version[0-3 bits] and IHL(header length)[4-7 bits]
.TypeOfService db ? ;+01
.TotalLength dw ? ;+02
.Identification dw ? ;+04
.FlagsAndFragmentOffset dw ? ;+06 - Flags[0-2] and FragmentOffset[3-15]
.TimeToLive db ? ;+08
.Protocol db ? ;+09
.HeaderChecksum dw ? ;+10
.SourceAddress dd ? ;+12
.DestinationAddress dd ? ;+16
.DataOrOptional dd ? ;+20
}
 
virtual at 0
IP_PACKET IP_PACKET
end virtual
 
 
;*******************************************************************
; Interface
;
; ip_rx processes all packets received by the network layer
; It calls the appropriate protocol handler
;
;
;
;*******************************************************************
 
 
;
; IP Packet after reception - Normal IP packet format
;
; 0 1 2 3
; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
;
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;0 |Version| IHL |Type of Service| Total Length |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;4 | Identification |Flags| Fragment Offset |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;8 | Time to Live | Protocol | Header Checksum |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;12 | Source Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;16 | Destination Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;20 | Data |
; +-+-+-.......... -+
;
;
; [smb] attention! according to RFC 791 IP packet may have 'options' sections,
; so we can't simply think, that data have offset 20. We must calculate offset from
; IHL field
;
macro GET_IHL reg, header_addr
{
movzx reg, byte [header_addr]
; we need 4-7 bits, so....
and reg, 0x0000000F
; IHL keeps number of octets, so we need to << 2 'reg'
shl reg, 2
}
 
 
include "tcp.inc"
include "udp.inc"
include "icmp.inc"
 
;***************************************************************************
; Function
; ip_rx
;
; Description
; This is a kernel function, called by stack_handler
; Processes all IP-packets received by the network layer
; It calls the appropriate protocol handler
;
;***************************************************************************
proc ip_rx stdcall
local buffer_number dd ?
 
; Look for a buffer to tx
mov eax, IPIN_QUEUE
call dequeue
cmp ax, NO_BUFFER
je .exit ; Exit if no buffer available
 
mov [buffer_number], eax ;save buffer number
 
; convert buffer pointer eax to the absolute address
imul eax, IPBUFFSIZE
add eax, IPbuffs
 
mov ebx, eax ; ebx=pointer to IP_PACKET
 
; DEBUGF 1, "K : ip_rx - proto: %u\n", [ebx + IP_PACKET.Protocol]:1
 
; Validate the IP checksum
mov dx, word[ebx + IP_PACKET.HeaderChecksum]
xchg dh,dl ; Get the checksum in intel format
mov [ebx + IP_PACKET.HeaderChecksum], 0 ; clear checksum field - need to when
; recalculating checksum
; this needs two data pointers and two size #.
; 2nd pointer can be of length 0
 
GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx
stdcall checksum_jb, ebx, ecx ;buf_ptr, buf_size
cmp dx, ax
 
; DEBUGF 1, "K : ip_rx - checksums: %x - %x\n", dx, ax
 
jnz .dump.1 ;if CHECKSUM isn't valid then dump packet
mov edx, ebx ; EDX (IP-BUFFER POINTER) WILL BE USED FOR *_rx HANDLERS BELOW!!!
 
; DEBUGF 1, "K : ip_rx - dest: %x - %x\n", [ebx + IP_PACKET.DestinationAddress], [stack_ip]
 
; Validate the IP address, if it isn't broadcast
mov eax, [stack_ip]
cmp dword[ebx + IP_PACKET.DestinationAddress], eax
je @f
 
; If the IP address is 255.255.255.255, accept it
; - it is a broadcast packet, which we need for dhcp
 
mov eax, [ebx + IP_PACKET.DestinationAddress]
cmp eax, 0xffffffff
je @f
mov ecx, [stack_ip]
and eax, [subnet_mask]
and ecx, [subnet_mask]
cmp eax, ecx
jne .dump.2
mov eax, [ebx + IP_PACKET.DestinationAddress]
or eax, [subnet_mask]
cmp eax, 0xffffffff
jne .dump.2
 
@@:
mov al, [ebx + IP_PACKET.VersionAndIHL]
and al, 0x0f ;get IHL(header length)
cmp al, 0x05 ;if IHL!= 5*4(20 bytes)
; DEBUGF 1, "K : ip_rx - ihl: %x - 05\n", al
jnz .dump.3 ;then dump it
 
; DEBUGF 1, "K : ip_rx - ttl: %x - 00\n", [ebx + IP_PACKET.TimeToLive]:2
 
cmp [ebx + IP_PACKET.TimeToLive], 0
je .dump.4 ;if TTL==0 then dump it
 
mov ax, [ebx + IP_PACKET.FlagsAndFragmentOffset]
and ax, 0xFFBF ;get flags
; DEBUGF 1, "K : ip_rx - flags: %x - 0000\n", ax
cmp ax, 0 ;if some flags was set then we dump this packet
jnz .dump.5 ;the flags should be used for fragmented packets
 
; Check the protocol, and call the appropriate handler
; Each handler will re-use or free the queue buffer as appropriate
 
mov al, [ebx + IP_PACKET.Protocol]
 
cmp al , PROTOCOL_TCP
jne .not_tcp
; DEBUGF 1,"K : ip_rx - TCP packet\n"
mov eax, dword[buffer_number]
call tcp_rx
jmp .exit
 
.not_tcp:
cmp al, PROTOCOL_UDP
jne .not_udp
; DEBUGF 1,"K : ip_rx - UDP packet\n"
mov eax, dword[buffer_number]
call udp_rx
jmp .exit
 
.not_udp:
cmp al, PROTOCOL_ICMP
jne .dump.6 ;protocol ain't supported
 
; DEBUGF 1,"K : ip_rx - ICMP packet\n"
;GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx
mov eax, dword[buffer_number]
stdcall icmp_rx,eax,ebx,ecx ;buffer_number,IPPacketBase,IPHeaderLength
jmp .exit
 
 
.dump.1:
DEBUGF 1, "K : ip_rx - dumped (checksum: 0x%x-0x%x)\n", dx, ax
jmp .dump.x
 
.dump.2:
DEBUGF 1, "K : ip_rx - dumped (ip: %u.%u.%u.%u)\n", [ebx + IP_PACKET.DestinationAddress + 0]:1, [ebx + IP_PACKET.DestinationAddress + 1]:1, [ebx + IP_PACKET.DestinationAddress + 2]:1, [ebx + IP_PACKET.DestinationAddress + 3]:1
jmp .dump.x
 
.dump.3:
DEBUGF 1, "K : ip_rx - dumped (ihl: %u)\n", al
jmp .dump.x
 
.dump.4:
DEBUGF 1, "K : ip_rx - dumped (ttl: %u)\n", [ebx + IP_PACKET.TimeToLive]
jmp .dump.x
 
.dump.5:
DEBUGF 1, "K : ip_rx - dumped (flags: 0x%x)\n", ax
jmp .dump.x
 
.dump.6:
DEBUGF 1, "K : ip_rx - dumped (proto: %u)\n", [ebx + IP_PACKET.Protocol]:1
 
.dump.x:
inc dword[dumped_rx_count]
mov eax, [buffer_number]
call freeBuff
 
.exit:
ret
endp
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network/icmp.inc
0,0 → 1,193
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; ICMP.INC ;;
;; ;;
;; Internet Control Message Protocol ( RFC 792 ) ;;
;; ;;
;; Last revision: 11.11.2006 ;;
;; ;;
;; This file contains the following: ;;
;; icmp_rx - processes ICMP-packets received by the IP layer ;;
;; ;;
;; Changes history: ;;
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;;
;; 11.11.2006 - [Johnny_B] and [smb] ;;
;; ;;
;; Current status: ;;
;; This implemetation of ICMP proto supports message of ECHO type.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
struc ICMP_PACKET
{ .Type db ? ;+00
.Code db ? ;+01
.Checksum dw ? ;+02
.Identifier dw ? ;+04
.SequenceNumber dw ? ;+06
.Data db ? ;+08
}
 
virtual at 0
ICMP_PACKET ICMP_PACKET
end virtual
 
 
; Example:
; ECHO message format
;
;
; 0 1 2 3
; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Type | Code | Checksum |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Identifier | Sequence Number |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Data ...
; +-+-+-+-+-
;
 
;
; ICMP types & codes, RFC 792 and FreeBSD's ICMP sources
;
 
ICMP_ECHOREPLY equ 0 ; echo reply message
 
ICMP_UNREACH equ 3
ICMP_UNREACH_NET equ 0 ; bad net
ICMP_UNREACH_HOST equ 1 ; bad host
ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol
ICMP_UNREACH_PORT equ 3 ; bad port
ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop
ICMP_UNREACH_SRCFAIL equ 5 ; src route failed
ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net
ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host
ICMP_UNREACH_ISOLATED equ 8 ; src host isolated
ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access
ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto
ICMP_UNREACH_TOSNET equ 11 ; bad tos for net
ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host
ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib
ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio.
ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff
 
ICMP_SOURCEQUENCH equ 4 ; packet lost, slow down
 
ICMP_REDIRECT equ 5 ; shorter route, codes:
ICMP_REDIRECT_NET equ 0 ; for network
ICMP_REDIRECT_HOST equ 1 ; for host
ICMP_REDIRECT_TOSNET equ 2 ; for tos and net
ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host
 
ICMP_ALTHOSTADDR equ 6 ; alternate host address
ICMP_ECHO equ 8 ; echo service
ICMP_ROUTERADVERT equ 9 ; router advertisement
ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement
ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing
 
ICMP_ROUTERSOLICIT equ 10 ; router solicitation
ICMP_TIMXCEED equ 11 ; time exceeded, code:
ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit
ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass
 
ICMP_PARAMPROB equ 12 ; ip header bad
ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr
ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent
ICMP_PARAMPROB_LENGTH equ 2 ; bad length
 
ICMP_TSTAMP equ 13 ; timestamp request
ICMP_TSTAMPREPLY equ 14 ; timestamp reply
ICMP_IREQ equ 15 ; information request
ICMP_IREQREPLY equ 16 ; information reply
ICMP_MASKREQ equ 17 ; address mask request
ICMP_MASKREPLY equ 18 ; address mask reply
ICMP_TRACEROUTE equ 30 ; traceroute
ICMP_DATACONVERR equ 31 ; data conversion error
ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect
ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you
ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here
ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req
ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply
ICMP_SKIP equ 39 ; SKIP
 
ICMP_PHOTURIS equ 40 ; Photuris
ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index
ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed
ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed
 
 
;***************************************************************************
; Function
; icmp_rx [by Johnny_B]
;
; Description
; ICMP protocol handler
; This is a kernel function, called by ip_rx
;
; IN:
; buffer_number - # of IP-buffer. This buffer must be reused or marked as empty afterwards
; IPPacketBase - IP_PACKET base address
; IPHeaderLength - Header length of IP_PACKET
;
; OUT:
; EAX=not defined
;
; All used registers will be saved
;
;***************************************************************************
proc icmp_rx stdcall uses ebx esi edi,\
buffer_number:DWORD,IPPacketBase:DWORD,IPHeaderLength:DWORD
 
mov esi,[IPPacketBase] ;esi=IP_PACKET base address
mov edi, esi
add edi,[IPHeaderLength] ;edi=ICMP_PACKET base address
 
cmp byte[edi + ICMP_PACKET.Type], ICMP_ECHO ; Is this an echo request? discard if not
jz .icmp_echo
 
mov eax, [buffer_number]
call freeBuff
jmp .exit
 
.icmp_echo:
 
; swap the source and destination addresses
mov ecx, [esi + IP_PACKET.DestinationAddress]
mov ebx, [esi + IP_PACKET.SourceAddress]
mov [esi + IP_PACKET.DestinationAddress], ebx
mov [esi + IP_PACKET.SourceAddress], ecx
 
; recalculate the IP header checksum
mov eax,[IPHeaderLength]
stdcall checksum_jb,esi,eax ;buf_ptr,buf_size
 
mov byte[esi + IP_PACKET.HeaderChecksum], ah
mov byte[esi + IP_PACKET.HeaderChecksum + 1], al ; ?? correct byte order?
 
mov byte[edi + ICMP_PACKET.Type], ICMP_ECHOREPLY ; change the request to a response
mov word[edi + ICMP_PACKET.Checksum], 0 ; clear ICMP checksum prior to re-calc
 
; Calculate the length of the ICMP data ( IP payload)
xor eax, eax
mov ah, byte[esi + IP_PACKET.TotalLength]
mov al, byte[esi + IP_PACKET.TotalLength + 1]
sub ax, word[IPHeaderLength] ;ax=ICMP-packet length
 
stdcall checksum_jb,edi,eax ;buf_ptr,buf_size
 
mov byte[edi + ICMP_PACKET.Checksum], ah
mov byte[edi + ICMP_PACKET.Checksum + 1], al
 
; Queue packet for transmission
mov ebx, [buffer_number]
mov eax, NET1OUT_QUEUE
call queue
 
.exit:
ret
endp
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/network
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/vmodeint.inc
0,0 → 1,58
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;
; Call of videomode driver's functions
;
; (Add in System function 21 (and/or 26) as a subfunction 13)
;
; Author: Trans
; Date: 19.07.2003
;
; Include in MeOS kernel and compile with FASM
;
 
uglobal
old_screen_width dd ?
old_screen_height dd ?
endg
 
; cmp eax,13 ; CALL VIDEOMODE DRIVER FUNCTIONS
dec ebx
jnz .no_vmode_drv_access
pushd [Screen_Max_X] [Screen_Max_Y]
popd [old_screen_height] [old_screen_width]
or eax,-1 ; If driver is absent then eax does not change
call (VMODE_BASE+0x100) ; Entry point of video driver
mov [esp+36-4],eax
mov [esp+24-4],ebx
mov [esp+32-4],ecx
; mov [esp+28],edx
mov eax,[old_screen_width]
mov ebx,[old_screen_height]
sub eax,[Screen_Max_X]
jnz @f
sub ebx,[Screen_Max_Y]
jz .resolution_wasnt_changed
jmp .lp1
@@: sub ebx,[Screen_Max_Y]
.lp1: sub [screen_workarea.right],eax
sub [screen_workarea.bottom],ebx
 
call repos_windows
xor eax,eax
xor ebx,ebx
mov ecx, [Screen_Max_X]
mov edx, [Screen_Max_Y]
call calculatescreen
 
.resolution_wasnt_changed:
ret
.no_vmode_drv_access:
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/bootcode.inc
0,0 → 1,1191
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; BOOTCODE.INC ;;
;; ;;
;; KolibriOS 16-bit loader, ;;
;; based on bootcode for MenuetOS ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;==========================================================================
;
; 16 BIT FUNCTIONS
;
;==========================================================================
 
 
putchar:
; in: al=character
mov ah, 0Eh
mov bh, 0
int 10h
ret
 
print:
; in: si->string
mov al, 186
call putchar
mov al, ' '
call putchar
 
printplain:
; in: si->string
pusha
lodsb
@@:
call putchar
lodsb
test al,al
jnz @b
popa
ret
 
getkey:
; get number in range [bl,bh] (bl,bh in ['0'..'9'])
; in: bx=range
; out: ax=digit (1..9, 10 for 0)
mov ah, 0
int 16h
cmp al, bl
jb getkey
cmp al, bh
ja getkey
push ax
call putchar
pop ax
and ax, 0Fh
jnz @f
mov al, 10
@@:
ret
 
setcursor:
; in: dl=column, dh=row
mov ah, 2
mov bh, 0
int 10h
ret
 
macro _setcursor row,column
{
mov dx, row*256 + column
call setcursor
}
 
boot_read_floppy:
push si
xor si, si
mov ah, 2 ; read
@@:
push ax
int 0x13
pop ax
jnc @f
inc si
cmp si, 10
jb @b
mov si, badsect
sayerr_plain:
call printplain
jmp $
@@:
pop si
ret
 
; convert abs. sector number (AX) to BIOS T:H:S
; sector number = (abs.sector%BPB_SecPerTrk)+1
; pre.track number = (abs.sector/BPB_SecPerTrk)
; head number = pre.track number%BPB_NumHeads
; track number = pre.track number/BPB_NumHeads
; Return: cl - sector number
; ch - track number
; dl - drive number (0 = a:)
; dh - head number
conv_abs_to_THS:
push bx
mov bx,word [BPB_SecPerTrk]
xor dx,dx
div bx
inc dx
mov cl, dl ; cl = sector number
mov bx,word [BPB_NumHeads]
xor dx,dx
div bx
; !!!!!!! ax = track number, dx = head number
mov ch,al ; ch=track number
xchg dh,dl ; dh=head number
mov dl,0 ; dl=0 (drive 0 (a:))
pop bx
retn
; needed variables
BPB_SecPerTrk dw 0 ; sectors per track
BPB_NumHeads dw 0 ; number of heads
BPB_FATSz16 dw 0 ; size of FAT
BPB_RootEntCnt dw 0 ; count of root dir. entries
BPB_BytsPerSec dw 0 ; bytes per sector
BPB_RsvdSecCnt dw 0 ; number of reserved sectors
BPB_TotSec16 dw 0 ; count of the sectors on the volume
BPB_SecPerClus db 0 ; number of sectors per cluster
BPB_NumFATs db 0 ; number of FAT tables
abs_sector_adj dw 0 ; adjustment to make abs. sector number
end_of_FAT dw 0 ; end of FAT table
FirstDataSector dw 0 ; begin of data
 
;=========================================================================
;
; 16 BIT CODE
;
;=========================================================================
 
include 'bootvesa.inc' ;Include source for boot vesa
 
start_of_code:
cld
; \begin{diamond}[02.12.2005]
; if bootloader sets ax = 'KL', then ds:si points to loader block
cmp ax, 'KL'
jnz @f
mov word [cs:cfgmanager.loader_block], si
mov word [cs:cfgmanager.loader_block+2], ds
@@:
; \end{diamond}[02.12.2005]
 
; if bootloader sets cx = 'HA' and dx = 'RD', then bx contains identifier of source hard disk
; (see comment to bx_from_load)
cmp cx, 'HA'
jnz no_hd_load
cmp dx,'RD'
jnz no_hd_load
mov word [cs:bx_from_load], bx ; {SPraid}[13.03.2007]
no_hd_load:
 
; set up stack
mov ax, 3000h
mov ss, ax
mov sp, 0EC00h
; set up segment registers
push cs
pop ds
push cs
pop es
 
; set videomode
mov ax, 3
int 0x10
 
if lang eq ru
; Load & set russian VGA font (RU.INC)
mov bp, RU_FNT1 ; RU_FNT1 - First part
mov bx, 1000h ; 768 bytes
mov cx, 30h ; 48 symbols
mov dx, 80h ; 128 - position of first symbol
mov ax, 1100h
int 10h
 
mov bp, RU_FNT2 ; RU_FNT2 -Second part
mov bx, 1000h ; 512 bytes
mov cx, 20h ; 32 symbols
mov dx, 0E0h ; 224 - position of first symbol
mov ax, 1100h
int 10h
; End set VGA russian font
else if lang eq et
mov bp, ET_FNT ; ET_FNT1
mov bx, 1000h ;
mov cx, 255 ; 256 symbols
xor dx, dx ; 0 - position of first symbol
mov ax, 1100h
int 10h
end if
 
; draw frames
push 0xb800
pop es
xor di, di
mov ah, 1*16+15
 
; draw top
mov si, d80x25_top
mov cx, d80x25_top_num * 80
@@:
lodsb
stosw
loop @b
; draw spaces
mov si, space_msg
mov dx, 25 - d80x25_top_num - d80x25_bottom_num
dfl1:
push si
mov cx, 80
@@:
lodsb
stosw
loop @b
pop si
dec dx
jnz dfl1
; draw bottom
mov si, d80x25_bottom
mov cx, d80x25_bottom_num * 80
@@:
lodsb
stosw
loop @b
 
mov byte [space_msg+80], 0 ; now space_msg is null terminated
 
_setcursor d80x25_top_num,0
 
 
; TEST FOR 386+
 
mov bx, 0x4000
pushf
pop ax
mov dx, ax
xor ax, bx
push ax
popf
pushf
pop ax
and ax, bx
and dx, bx
cmp ax, dx
jnz cpugood
mov si, not386
sayerr:
call print
jmp $
cpugood:
 
push 0
popf
sti
 
; set up esp
movzx esp, sp
 
push 0
pop es
and word [es:0x9031], 0
; \begin{Mario79}
; find HDD IDE DMA PCI device
; check for PCI BIOS
mov ax, 0xB101
int 0x1A
jc .nopci
cmp edx, 'PCI '
jnz .nopci
; find PCI class code
; class 1 = mass storage
; subclass 1 = IDE controller
; a) class 1, subclass 1, programming interface 0x80
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x80
xor si, si ; device index = 0
int 0x1A
jnc .found
; b) class 1, subclass 1, programming interface 0x8A
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x8A
xor si, si ; device index = 0
int 0x1A
jnc .found
; c) class 1, subclass 1, programming interface 0x85
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x85
xor si, si
int 0x1A
jc .nopci
.found:
; get memory base
mov ax, 0xB10A
mov di, 0x20 ; memory base is config register at 0x20
int 0x1A
jc .nopci
and cx, 0xFFF0 ; clear address decode type
mov [es:0x9031], cx
.nopci:
; \end{Mario79}
 
mov al, 0xf6 ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå
out 0x60, al
xor cx, cx
wait_loop: ; variant 2
; reading state of port of 8042 controller
in al, 64h
and al, 00000010b ; ready flag
; wait until 8042 controller is ready
loopnz wait_loop
 
;;;/diamond today 5.02.2008
; set keyboard typematic rate & delay
mov al, 0xf3
out 0x60, al
xor cx, cx
@@:
in al, 64h
test al, 2
loopnz @b
mov al, 0
out 0x60, al
xor cx, cx
@@:
in al, 64h
test al, 2
loopnz @b
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; --------------- APM ---------------------
and word [es:0x9044], 0 ; ver = 0.0 (APM not found)
mov ax, 0x5300
xor bx, bx
int 0x15
jc apm_end ; APM not found
test cx, 2
jz apm_end ; APM 32-bit protected-mode interface not supported
mov [es:0x9044], ax ; Save APM Version
mov [es:0x9046], cx ; Save APM flags
 
; Write APM ver ----
and ax, 0xf0f
add ax, '00'
mov si, msg_apm
mov [si + 5], ah
mov [si + 7], al
_setcursor 0, 3
call printplain
; ------------------
 
mov ax, 0x5304 ; Disconnect interface
xor bx, bx
int 0x15
mov ax, 0x5303 ; Connect 32 bit mode interface
xor bx, bx
int 0x15
 
mov [es:0x9040], ebx
mov [es:0x9050], ax
mov [es:0x9052], cx
mov [es:0x9054], dx
 
apm_end:
_setcursor d80x25_top_num, 0
 
;CHECK current of code
cmp [cfgmanager.loader_block], -1
jz noloaderblock
les bx, [cfgmanager.loader_block]
cmp byte [es:bx], 1
mov si, loader_block_error
jnz sayerr
push 0
pop es
 
noloaderblock:
; DISPLAY VESA INFORMATION
call print_vesa_info
call calc_vmodes_table
call check_first_parm ;check and enable cursor_pos
 
; \begin{diamond}[30.11.2005]
cfgmanager:
; settings:
; a) preboot_graph = graphical mode
; preboot_gprobe = probe this mode?
; b) preboot_dma = use DMA access?
; c) preboot_vrrm = use VRR?
; d) preboot_device = from what boot?
 
; determine default settings
mov [.bSettingsChanged], 0
 
;.preboot_gr_end:
mov di, preboot_device
; if image in memory is present and [preboot_device] is uninitialized,
; set it to use this preloaded image
cmp byte [di], 0
jnz .preboot_device_inited
cmp [.loader_block], -1
jz @f
les bx, [.loader_block]
test byte [es:bx+1], 1
jz @f
mov byte [di], 3
jmp .preboot_device_inited
@@:
; otherwise, set [preboot_device] to 1 (default value - boot from floppy)
mov byte [di], 1
.preboot_device_inited:
; following 4 lines set variables to 1 if its current value is 0
cmp byte [di+preboot_dma-preboot_device], 1
adc byte [di+preboot_dma-preboot_device], 0
cmp byte [di+preboot_biosdisk-preboot_device], 1
adc byte [di+preboot_biosdisk-preboot_device], 0
; default value for VRR is OFF
cmp byte [di+preboot_vrrm-preboot_device], 0
jnz @f
mov byte [di+preboot_vrrm-preboot_device], 2
@@:
; notify user
_setcursor 5,2
 
mov si, linef
call printplain
mov si, start_msg
call print
mov si, time_msg
call print
; get start time
call .gettime
mov [.starttime], eax
mov word [.timer], .newtimer
mov word [.timer+2], cs
.printcfg:
 
_setcursor 9,0
mov si, current_cfg_msg
call print
mov si, curvideo_msg
call print
 
call draw_current_vmode
 
mov si, usebd_msg
cmp [preboot_biosdisk], 1
call .say_on_off
mov si, vrrm_msg
cmp [preboot_vrrm], 1
call .say_on_off
mov si, preboot_device_msg
call print
mov al, [preboot_device]
and eax, 7
mov si, [preboot_device_msgs+eax*2]
call printplain
.show_remarks:
; show remarks in gray color
mov di, ((21-num_remarks)*80 + 2)*2
push 0xB800
pop es
mov cx, num_remarks
mov si, remarks
.write_remarks:
lodsw
push si
xchg ax, si
mov ah, 1*16+7 ; background: blue (1), foreground: gray (7)
push di
.write_remark:
lodsb
test al, al
jz @f
stosw
jmp .write_remark
@@:
pop di
pop si
add di, 80*2
loop .write_remarks
.wait:
_setcursor 25,0 ; out of screen
; set timer interrupt handler
cli
push 0
pop es
push dword [es:8*4]
pop dword [.oldtimer]
push dword [.timer]
pop dword [es:8*4]
; mov eax, [es:8*4]
; mov [.oldtimer], eax
; mov eax, [.timer]
; mov [es:8*4], eax
sti
; wait for keypressed
xor ax,ax
int 16h
push ax
; restore timer interrupt
; push 0
; pop es
mov eax, [.oldtimer]
mov [es:8*4], eax
mov [.timer], eax
 
_setcursor 7,0
mov si, space_msg
call printplain
; clear remarks and restore normal attributes
push es
mov di, ((21-num_remarks)*80 + 2)*2
push 0xB800
pop es
mov cx, num_remarks
mov ax, ' ' + (1*16 + 15)*100h
@@:
push cx
mov cx, 76
rep stosw
pop cx
add di, 4*2
loop @b
pop es
pop ax
; switch on key
cmp al, 13
jz .continue
or al, 20h
cmp al, 'a'
jz .change_a
cmp al, 'b'
jz .change_b
cmp al, 'c'
jz .change_c
cmp al, 'd'
jnz .show_remarks
_setcursor 15,0
mov si, bdev
call print
mov bx, '14'
call getkey
mov [preboot_device], al
_setcursor 13,0
.d:
mov [.bSettingsChanged], 1
call clear_vmodes_table ;clear vmodes_table
jmp .printcfg
.change_a:
.loops:
call draw_vmodes_table
_setcursor 25,0 ; out of screen
xor ax,ax
int 0x16
; call clear_table_cursor ;clear current position of cursor
 
mov si,word [cursor_pos]
 
cmp ah,0x48;x,0x48E0 ; up
jne .down
cmp si,modes_table
jbe .loops
sub word [cursor_pos],size_of_step
jmp .loops
 
.down: cmp ah,0x50;x,0x50E0 ; down
jne .pgup
cmp word[es:si+10],-1
je .loops
add word [cursor_pos],size_of_step
jmp .loops
 
.pgup: cmp ah,0x49 ; page up
jne .pgdn
sub si, size_of_step*long_v_table
cmp si, modes_table
jae @f
mov si, modes_table
@@:
mov word [cursor_pos], si
mov si, word [home_cursor]
sub si, size_of_step*long_v_table
cmp si, modes_table
jae @f
mov si, modes_table
@@:
mov word [home_cursor], si
jmp .loops
 
.pgdn: cmp ah,0x51 ; page down
jne .enter
mov ax, [end_cursor]
add si, size_of_step*long_v_table
cmp si, ax
jb @f
mov si, ax
sub si, size_of_step
@@:
mov word [cursor_pos], si
mov si, word [home_cursor]
sub ax, size_of_step*long_v_table
add si, size_of_step*long_v_table
cmp si, ax
jb @f
mov si, ax
@@:
mov word [home_cursor], si
jmp .loops
 
.enter: cmp al,0x0D;x,0x1C0D ; enter
jne .loops
push word [cursor_pos]
pop bp
push word [es:bp]
pop word [x_save]
push word [es:bp+2]
pop word [y_save]
push word [es:bp+6]
pop word [number_vm]
mov word [preboot_graph],bp ;save choose
jmp .d
 
.change_b:
_setcursor 15,0
; mov si, ask_dma
; call print
; mov bx, '13'
; call getkey
; mov [preboot_dma], al
mov si, ask_bd
call print
mov bx, '12'
call getkey
mov [preboot_biosdisk], al
_setcursor 11,0
jmp .d
.change_c:
_setcursor 15,0
mov si, vrrmprint
call print
mov bx, '12'
call getkey
mov [preboot_vrrm], al
_setcursor 12,0
jmp .d
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.say_on_off:
pushf
call print
mov si, on_msg
popf
jz @f
mov si, off_msg
@@: jmp printplain
; novesa and vervesa strings are not used at the moment of executing this code
virtual at novesa
.oldtimer dd ?
.starttime dd ?
.bSettingsChanged db ?
.timer dd ?
end virtual
.loader_block dd -1
.gettime:
mov ah, 0
int 1Ah
xchg ax, cx
shl eax, 10h
xchg ax, dx
ret
.newtimer:
push ds
push cs
pop ds
pushf
call [.oldtimer]
pushad
call .gettime
sub eax, [.starttime]
sub ax, 18*5
jae .timergo
neg ax
add ax, 18-1
mov bx, 18
xor dx, dx
div bx
if lang eq ru
; ¯®¤®¦¤¨â¥ 5 ᥪ㭤, 4/3/2 ᥪ㭤ë, 1 ᥪ㭤ã
cmp al, 5
mov cl, ' '
jae @f
cmp al, 1
mov cl, 'ã'
jz @f
mov cl, 'ë'
@@: mov [time_str+9], cl
else if lang eq et
cmp al, 1
ja @f
mov [time_str+9], ' '
mov [time_str+10],' '
@@:
else
; wait 5/4/3/2 seconds, 1 second
cmp al, 1
mov cl, 's'
ja @f
mov cl, ' '
@@: mov [time_str+9], cl
end if
add al, '0'
mov [time_str+1], al
mov si, time_msg
_setcursor 7,0
call print
_setcursor 25,0
popad
pop ds
iret
.timergo:
push 0
pop es
mov eax, [.oldtimer]
mov [es:8*4], eax
mov sp, 0EC00h
.continue:
sti
_setcursor 6,0
mov si, space_msg
call printplain
call printplain
_setcursor 6,0
mov si, loading_msg
call print
_setcursor 15,0
cmp [.bSettingsChanged], 0
jz .load
cmp [.loader_block], -1
jz .load
les bx, [.loader_block]
mov eax, [es:bx+3]
push ds
pop es
test eax, eax
jz .load
push eax
mov si, save_quest
call print
.waityn:
mov ah, 0
int 16h
or al, 20h
cmp al, 'n'
jz .loadc
cmp al, 'y'
jnz .waityn
call putchar
mov byte [space_msg+80], 186
 
pop eax
push cs
push .cont
push eax
retf ;call back
.loadc:
pop eax
.cont:
push cs
pop ds
mov si, space_msg
mov byte [si+80], 0
_setcursor 15,0
call printplain
_setcursor 15,0
.load:
; \end{diamond}[02.12.2005]
 
; ASK GRAPHICS MODE
 
call set_vmode
 
; GRAPHICS ACCELERATION
; force yes
mov [es:0x901C], byte 1
 
; DMA ACCESS TO HD
 
mov al, [preboot_dma]
mov [es:0x901F], al
 
; VRR_M USE
 
mov al,[preboot_vrrm]
mov [es:0x9030], al
mov [es:0x901E], byte 1
 
; BOOT DEVICE
 
mov al, [preboot_device]
dec al
mov [boot_dev], al
 
; GET MEMORY MAP
include 'detect/biosmem.inc'
 
; READ DISKETTE TO MEMORY
 
cmp [boot_dev],0
jne no_sys_on_floppy
mov si,diskload
call print
xor ax, ax ; reset drive
xor dx, dx
int 0x13
; do we boot from CD-ROM?
mov ah, 41h
mov bx, 55AAh
xor dx, dx
int 0x13
jc .nocd
cmp bx, 0AA55h
jnz .nocd
mov ah, 48h
push ds
push es
pop ds
mov si, 0xa000
mov word [si], 30
int 0x13
pop ds
jc .nocd
push ds
lds si, [es:si+26]
test byte [ds:si+10], 40h
pop ds
jz .nocd
; yes - read all floppy by 18 sectors
 
; TODO: !!!! read only first sector and set variables !!!!!
; ...
; TODO: !!! then read flippy image track by track
mov cx, 0x0001 ; startcyl,startsector
.a1:
push cx dx
mov al, 18
mov bx, 0xa000
call boot_read_floppy
mov si, movedesc
push es
push ds
pop es
mov cx, 256*18
mov ah, 0x87
int 0x15
pop es
pop dx cx
test ah, ah
jnz sayerr_floppy
add dword [si+8*3+2], 512*18
inc dh
cmp dh, 2
jnz .a1
mov dh, 0
inc ch
cmp ch, 80
jae ok_sys_on_floppy
pusha
mov al, ch
shr ch, 2
add al, ch
aam
xchg al, ah
add ax, '00'
mov si, pros
mov [si], ax
call printplain
popa
jmp .a1
.nocd:
; no - read only used sectors from floppy
; now load floppy image to memory
; at first load boot sector and first FAT table
 
; read only first sector and fill variables
mov cx, 0x0001 ; first logical sector
xor dx, dx ; head = 0, drive = 0 (a:)
mov al, 1 ; read one sector
mov bx, 0xB000 ; es:bx -> data area
call boot_read_floppy
; fill the necessary parameters to work with a floppy
mov ax, word [es:bx+24]
mov word [BPB_SecPerTrk], ax
mov ax, word [es:bx+26]
mov word [BPB_NumHeads], ax
mov ax, word [es:bx+17]
mov word [BPB_RootEntCnt], ax
mov ax, word [es:bx+14]
mov word [BPB_RsvdSecCnt], ax
mov ax, word [es:bx+19]
mov word [BPB_TotSec16], ax
mov al, byte [es:bx+13]
mov byte [BPB_SecPerClus], al
mov al, byte [es:bx+16]
mov byte [BPB_NumFATs], al
;<Lrz> 18.11.2008
mov ax, word [es:bx+22]
mov word [BPB_FATSz16], ax
mov cx, word [es:bx+11]
mov word [BPB_BytsPerSec], cx
 
; count of clusters in FAT12 ((size_of_FAT*2)/3)
; mov ax, word [BPB_FATSz16]
; mov cx, word [BPB_BytsPerSec]
;end <Lrz> 18.11.2008
xor dx, dx
mul cx
shl ax, 1
mov cx, 3
div cx ; now ax - number of clusters in FAT12
mov word [end_of_FAT], ax
 
; load first FAT table
mov cx, 0x0002 ; startcyl,startsector ; TODO!!!!!
xor dx, dx ; starthead,drive
mov al, byte [BPB_FATSz16] ; no of sectors to read
add bx, word [BPB_BytsPerSec] ; es:bx -> data area
call boot_read_floppy
mov bx, 0xB000
 
; and copy them to extended memory
mov si, movedesc
mov [si+8*2+3], bh ; from
mov ax, word [BPB_BytsPerSec]
shr ax, 1 ; words per sector
mov cx, word [BPB_RsvdSecCnt]
add cx, word [BPB_FATSz16]
mul cx
push ax ; save to stack count of words in boot+FAT
xchg ax, cx
push es
push ds
pop es
mov ah, 0x87
int 0x15
pop es
test ah, ah
jz @f
sayerr_floppy:
mov dx, 0x3f2
mov al, 0
out dx, al
mov si, memmovefailed
jmp sayerr_plain
@@:
pop ax ; restore from stack count of words in boot+FAT
shl ax, 1 ; make bytes count from count of words
and eax, 0ffffh
add dword [si+8*3+2], eax
 
; copy first FAT to second copy
; TODO: BPB_NumFATs !!!!!
add bx, word [BPB_BytsPerSec] ; !!! TODO: may be need multiply by BPB_RsvdSecCnt !!!
mov byte [si+8*2+3], bh ; bx - begin of FAT
mov ax, word [BPB_BytsPerSec]
shr ax, 1 ; words per sector
mov cx, word [BPB_FATSz16]
mul cx
mov cx, ax ; cx - count of words in FAT
 
push es
push ds
pop es
mov ah, 0x87
int 0x15
pop es
test ah, ah
jnz sayerr_floppy
mov ax, cx
shl ax, 1
and eax, 0ffffh ; ax - count of bytes in FAT
add dword [si+8*3+2], eax
; reading RootDir
; TODO: BPB_NumFATs
add bx, ax
add bx, 100h
and bx, 0ff00h ; bx - place in buffer to write RootDir
push bx
 
mov bx, word [BPB_BytsPerSec]
shr bx, 5 ; divide bx by 32
mov ax, word [BPB_RootEntCnt]
xor dx, dx
div bx
push ax ; ax - count of RootDir sectors
 
mov ax, word [BPB_FATSz16]
xor cx, cx
mov cl, byte [BPB_NumFATs]
mul cx
add ax, word [BPB_RsvdSecCnt] ; ax - first sector of RootDir
 
mov word [FirstDataSector], ax
pop bx
push bx
add word [FirstDataSector], bx ; Begin of data region of floppy
; read RootDir
call conv_abs_to_THS
pop ax
pop bx ; place in buffer to write
push ax
call boot_read_floppy ; read RootDir into buffer
; copy RootDir
mov byte [si+8*2+3], bh ; from buffer
pop ax ; ax = count of RootDir sectors
mov cx, word [BPB_BytsPerSec]
mul cx
shr ax, 1
mov cx, ax ; count of words to copy
push es
push ds
pop es
mov ah, 0x87
int 0x15
pop es
 
mov ax, cx
shl ax, 1
and eax, 0ffffh ; ax - count of bytes in RootDir
add dword [si+8*3+2], eax ; add count of bytes copied
 
; Reading data clusters from floppy
mov byte [si+8*2+3], bh
push bx
 
mov di, 2 ; First data cluster
.read_loop:
mov bx, di
shr bx, 1 ; bx+di = di*1.5
jnc .even
test word [es:bx+di+0xB200], 0xFFF0 ; TODO: may not be 0xB200 !!!
jmp @f
.even:
test word [es:bx+di+0xB200], 0xFFF ; TODO: may not be 0xB200 !!!
 
@@:
jz .skip
; read cluster di
;.read:
;conv cluster di to abs. sector ax
; ax = (N-2) * BPB_SecPerClus + FirstDataSector
mov ax, di
sub ax, 2
xor bx, bx
mov bl, byte [BPB_SecPerClus]
mul bx
add ax, word [FirstDataSector]
call conv_abs_to_THS
pop bx
push bx
mov al, byte [BPB_SecPerClus] ; number of sectors in cluster
call boot_read_floppy
push es
push ds
pop es
pusha
;
mov ax, word [BPB_BytsPerSec]
xor cx, cx
mov cl, byte [BPB_SecPerClus]
mul cx
shr ax, 1 ; ax = (BPB_BytsPerSec * BPB_SecPerClus)/2
mov cx, ax ; number of words to copy (count words in cluster)
;
mov ah, 0x87
int 0x15 ; copy data
test ah, ah
popa
pop es
jnz sayerr_floppy
; skip cluster di
.skip:
mov ax, word [BPB_BytsPerSec]
xor cx, cx
mov cl, byte [BPB_SecPerClus]
mul cx
and eax, 0ffffh ; ax - count of bytes in cluster
add dword [si+8*3+2], eax
 
mov ax, word [end_of_FAT] ; max cluster number
pusha
; draw percentage
; total clusters: ax
; read clusters: di
xchg ax, di
mov cx, 100
mul cx
div di
aam
xchg al, ah
add ax, '00'
mov si, pros
cmp [si], ax
jz @f
mov [si], ax
call printplain
@@:
popa
inc di
cmp di, word [end_of_FAT] ; max number of cluster
jnz .read_loop
pop bx ; clear stack
 
ok_sys_on_floppy:
mov si, backspace2
call printplain
mov si, okt
call printplain
no_sys_on_floppy:
xor ax, ax ; reset drive
xor dx, dx
int 0x13
mov dx, 0x3f2 ; floppy motor off
mov al, 0
out dx, al
 
 
; SET GRAPHICS
 
xor ax, ax
mov es, ax
 
mov ax, [es:0x9008] ; vga & 320x200
mov bx, ax
cmp ax, 0x13
je setgr
cmp ax, 0x12
je setgr
mov ax, 0x4f02 ; Vesa
setgr:
int 0x10
test ah, ah
mov si, fatalsel
jnz v_mode_error
; set mode 0x12 graphics registers:
cmp bx, 0x12
jne gmok2
 
mov al, 0x05
mov dx, 0x03ce
push dx
out dx, al ; select GDC mode register
mov al, 0x02
inc dx
out dx, al ; set write mode 2
 
mov al, 0x02
mov dx, 0x03c4
out dx, al ; select VGA sequencer map mask register
mov al, 0x0f
inc dx
out dx, al ; set mask for all planes 0-3
 
mov al, 0x08
pop dx
out dx, al ; select GDC bit mask register
; for writes to 0x03cf
gmok2:
push ds
pop es
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/booteng.inc
0,0 → 1,110
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;======================================================================
;
; BOOT DATA
;
;======================================================================
 
$Revision$
 
 
d80x25_bottom:
db 186,' KolibriOS is based on MenuetOS and comes with ABSOLUTELY '
db 'NO WARRANTY ',186
db 186,' See file COPYING for details '
db ' ',186
line_full_bottom
d80x25_bottom_num = 3
 
msg_apm db " APM x.x ", 0
vervesa db "Version of Vesa: Vesa x.x",13,10,0
novesa db "Display: EGA/CGA",13,10,0
s_vesa db "Version of VESA: "
.ver db "?.?",13,10,0
 
gr_mode db "Select a videomode: ",13,10,0
;s_bpp db 13,10,186," ƒ«ã¡¨­  梥â : "
; .bpp dw "??"
; db 13,10,0
 
vrrmprint db "Apply VRR? (picture frequency greater than 60Hz"
db " only for transfers:",13,10
db 186," 1024*768->800*600 and 800*600->640*480) [1-yes,2-no]:",0
 
 
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
 
bdev db "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-use preloaded ram-image from kernel restart;"
db 13,10,186," "
db "4-create blank image]: ",0
probetext db 13,10,13,10,186," Use standart graphics mode? [1-yes, "
db "2-probe bios (Vesa 3.0)]: ",0
;memokz256 db 13,10,186," RAM 256 Mb",0
;memokz128 db 13,10,186," RAM 128 Mb",0
;memokz64 db 13,10,186," RAM 64 Mb",0
;memokz32 db 13,10,186," RAM 32 Mb",0
;memokz16 db 13,10,186," RAM 16 Mb",0
prnotfnd db "Fatal - Videomode not found.",0
;modena db "Fatal - VBE 0x112+ required.",0
not386 db "Fatal - CPU 386+ required.",0
btns db "Fatal - Can't determine color depth.",0
fatalsel db "Fatal - Graphics mode not supported by hardware.",0
pres_key db "Press any key to choose a new videomode.",0
badsect db 13,10,186," Fatal - Bad sector. Replace floppy.",0
memmovefailed db 13,10,186," Fatal - Int 0x15 move failed.",0
okt db " ... OK"
linef db 13,10,0
diskload db "Loading diskette: 00 %",8,8,8,8,0
pros db "00"
backspace2 db 8,8,0
boot_dev db 0 ; 0=floppy, 1=hd
start_msg db "Press [abcd] to change settings, press [Enter] to continue booting",13,10,0
time_msg db " or wait "
time_str db " 5 seconds"
db " before automatical continuation",13,10,0
current_cfg_msg db "Current settings:",13,10,0
curvideo_msg db " [a] Videomode: ",0
 
;modes_msg dw mode4,mode1,mode2,mode3
;modevesa20 db " with LFB",0
;modevesa12 db ", VESA 1.2 Bnk",0
mode0 db "320x200, EGA/CGA 256 colors",13,10,0
mode9 db "640x480, VGA 16 colors",13,10,0
 
;probeno_msg db " (standard mode)",0
;probeok_msg db " (check nonstandard modes)",0
;dma_msg db " [b] Use DMA for HDD access:",0
usebd_msg db " [b] Add disks visible by BIOS:",0
on_msg db " on",13,10,0
off_msg db " off",13,10,0
;readonly_msg db " only for reading",13,10,0
vrrm_msg db " [c] Use VRR:",0
preboot_device_msg db " [d] Floppy image: ",0
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
pdm1 db "real floppy",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "use already loaded image",13,10,0
pdm4 db "create blank image",13,10,0
loading_msg db "Loading KolibriOS...",0
save_quest db "Remember current settings? [y/n]: ",0
loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0
 
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿',13,10,0
_r1 db 186,' ³ 320x200 EGA/CGA 256 colors ³ ³',13,10,0
_r2 db 186,' ³ 640x480 VGA 16 colors ³ ³',13,10,0
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³',13,10,0
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ',13,10,0
 
remark1 db "Default values were selected to match most of configurations, but not all.",0
remark2 db "If you have CRT-monitor, enable VRR in the item [c].",0
remark3 db "If the system does not boot, try to disable the item [b].",0
remarks dw remark1, remark2, remark3
num_remarks = 3
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/bootet.inc
0,0 → 1,115
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;======================================================================
;
; BOOT DATA
;
;======================================================================
 
$Revision$
 
 
d80x25_bottom:
db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY '
db 'NO WARRANTY ',186
db 186,' See file COPYING for details '
db ' ',186
line_full_bottom
d80x25_bottom_num = 3
 
novesa db "Ekraan: EGA/CGA",13,10,0
vervesa db "Vesa versioon: Vesa x.x",13,10,0
vervesa_off=20
msg_apm db " APM x.x ", 0
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
db "[3] 1024x768, [4] 1280x1024",13,10
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
db "[7] 1024x768, [8] 1280x1024",13,10
db 186," EGA/CGA 256 värvi: [9] 320x200, "
db "VGA 16 värvi: [0] 640x480",13,10
db 186," Vali reziim: ",0
bt24 db "Bitti pikseli kohta: 24",13,10,0
bt32 db "Bitti pikseli kohta: 32",13,10,0
vrrmprint db "Kinnita VRR? (ekraani sagedus suurem kui 60Hz"
db " ainult:",13,10
db 186," 1024*768->800*600 ja 800*600->640*480) [1-jah,2-ei]:",0
;askmouse db " Hiir:"
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
; db " Vali port [1-3]: ",0
;no_com1 db 13,10,186, " No COM1 mouse",0
;no_com2 db 13,10,186, " No COM2 mouse",0
;ask_dma db "Use DMA for HDD access? [1-yes, 2-only for reading, 3-no]: ",0
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
;gr_direct db 186," Use direct LFB writing? "
; db "[1-yes/2-no] ? ",0
;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / "
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
bdev db "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-kasuta eellaaditud mäluketast kerneli restardist;"
db 13,10,186," "
db "4-loo tühi pilt]: ",0
probetext db 13,10,13,10,186," Kasuta standartset graafika reziimi? [1-jah, "
db "2-leia biosist (Vesa 3.0)]: ",0
;memokz256 db 13,10,186," RAM 256 Mb",0
;memokz128 db 13,10,186," RAM 128 Mb",0
;memokz64 db 13,10,186," RAM 64 Mb",0
;memokz32 db 13,10,186," RAM 32 Mb",0
;memokz16 db 13,10,186," RAM 16 Mb",0
prnotfnd db "Fataalne - Videoreziimi ei leitud.",0
;modena db "Fataalne - VBE 0x112+ on vajalik.",0
not386 db "Fataalne - CPU 386+ on vajalik.",0
btns db "Fataalne - Ei suuda värvisügavust määratleda.",0
fatalsel db "Fataalne - Graafilist reziimi riistvara ei toeta.",0
badsect db 13,10,186," Fataalne - Vigane sektor. Asenda diskett.",0
memmovefailed db 13,10,186," Fataalne - Int 0x15 liigutamine ebaõnnestus.",0
okt db " ... OK"
linef db 13,10,0
diskload db "Loen disketti: 00 %",8,8,8,8,0
pros db "00"
backspace2 db 8,8,0
boot_dev db 0 ; 0=floppy, 1=hd
start_msg db "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0
time_msg db " või oota "
time_str db " 5 sekundit"
db " automaatseks jätkamiseks",13,10,0
current_cfg_msg db "Praegused seaded:",13,10,0
curvideo_msg db " [a] Videoreziim: ",0
mode1 db "640x480",0
mode2 db "800x600",0
mode3 db "1024x768",0
mode4 db "1280x1024",0
modes_msg dw mode4,mode1,mode2,mode3
modevesa20 db " koos LFB",0
modevesa12 db ", VESA 1.2 Bnk",0
mode9 db "320x200, EGA/CGA 256 värvi",0
mode10 db "640x480, VGA 16 värvi",0
probeno_msg db " (standard reziim)",0
probeok_msg db " (kontrolli ebastandardseid reziime)",0
;dma_msg db " [b] Kasuta DMA'd HDD juurdepääsuks:",0
usebd_msg db " [b] Add disks visible by BIOS:",0
on_msg db " sees",13,10,0
off_msg db " väljas",13,10,0
;readonly_msg db " ainult lugemiseks",13,10,0
vrrm_msg db " [c] Kasuta VRR:",0
preboot_device_msg db " [d] Disketi kujutis: ",0
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
pdm1 db "reaalne diskett",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "kasuta juba laaditud kujutist",13,10,0
pdm4 db "loo tühi pilt",13,10,0
loading_msg db "Laadin KolibriOS...",0
save_quest db "Jäta meelde praegused seaded? [y/n]: ",0
loader_block_error db "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0
 
remark1 db "Default values were selected to match most of configurations, but not all.",0
remark2 db "If you have CRT-monitor, enable VRR in the item [c].",0
remark3 db "If the system does not boot, try to disable the item [b].",0
remarks dw remark1, remark2, remark3
num_remarks = 3
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/bootge.inc
0,0 → 1,120
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;======================================================================
;
; BOOT DATA
;
;======================================================================
 
$Revision$
 
 
d80x25_bottom:
; db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY '
; db 'NO WARRANTY ',186
; db 186,' See file COPYING for details '
; db ' ',186
 
db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche '
db ' Garantie vertrieben ',186
db 186,' Details stehen in der Datei COPYING '
db ' ',186
line_full_bottom
d80x25_bottom_num = 3
 
novesa db "Anzeige: EGA/CGA ",13,10,0
vervesa db "Vesa-Version: Vesa ",13,10,0
vervesa_off=22
msg_apm db " APM x.x ", 0
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
db "[3] 1024x768, [4] 1280x1024",13,10
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
db "[7] 1024x768, [8] 1280x1024",13,10
db 186," EGA/CGA 256 Farben: [9] 320x200, "
db "VGA 16 Farben: [0] 640x480",13,10
db 186," Waehle Modus: ",0
bt24 db "Bits Per Pixel: 24",13,10,0
bt32 db "Bits Per Pixel: 32",13,10,0
vrrmprint db "VRR verwenden? (Monitorfrequenz groesser als 60Hz"
db " only for transfers:",13,10
db 186," 1024*768->800*600 und 800*600->640*480) [1-ja,2-nein]:",0
;askmouse db " Maus angeschlossen an:"
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
; db " Waehle Port [1-3]: ",0
;no_com1 db 13,10,186, " Keine COM1 Maus",0
;no_com2 db 13,10,186, " Keine COM2 Maus",0
;ask_dma db "Nutze DMA zum HDD Zugriff? [1-ja, 2-allein fur Lesen, 3-nein]: ",0
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
;gr_direct db 186," Benutze direct LFB? "
; db "[1-ja/2-nein] ? ",0
;mem_model db 13,10,186," Hauptspeicher [1-16 Mb / 2-32 Mb / "
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
bdev db "Lade die Ramdisk von [1-Diskette; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-benutze ein bereits geladenes Kernel image;"
db 13,10,186," "
db "4-create blank image]: ",0
probetext db 13,10,13,10,186," Nutze Standardgrafikmodi? [1-ja, "
db "2-BIOS Test (Vesa 3.0)]: ",0
;memokz256 db 13,10,186," RAM 256 Mb",0
;memokz128 db 13,10,186," RAM 128 Mb",0
;memokz64 db 13,10,186," RAM 64 Mb",0
;memokz32 db 13,10,186," RAM 32 Mb",0
;memokz16 db 13,10,186," RAM 16 Mb",0
prnotfnd db "Fatal - Videomodus nicht gefunden.",0
;modena db "Fatal - VBE 0x112+ required.",0
not386 db "Fatal - CPU 386+ benoetigt.",0
btns db "Fatal - konnte Farbtiefe nicht erkennen.",0
fatalsel db "Fatal - Grafikmodus nicht unterstuetzt.",0
badsect db 13,10,186," Fatal - Sektorfehler, Andere Diskette neutzen.",0
memmovefailed db 13,10,186," Fatal - Int 0x15 Fehler.",0
okt db " ... OK"
linef db 13,10,0
diskload db "Lade Diskette: 00 %",8,8,8,8,0
pros db "00"
backspace2 db 8,8,0
boot_dev db 0 ; 0=floppy, 1=hd
start_msg db "Druecke [abcd], um die Einstellungen zu aendern , druecke [Enter] zum starten",13,10,0
time_msg db " oder warte "
time_str db " 5 Sekunden"
db " bis zum automatischen Start",13,10,0
current_cfg_msg db "Aktuelle Einstellungen:",13,10,0
curvideo_msg db " [a] Videomodus: ",0
mode1 db "640x480",0
mode2 db "800x600",0
mode3 db "1024x768",0
mode4 db "1280x1024",0
modes_msg dw mode4,mode1,mode2,mode3
modevesa20 db " mit LFB",0
modevesa12 db ", VESA 1.2 Bnk",0
mode9 db "320x200, EGA/CGA 256 colors",0
mode10 db "640x480, VGA 16 colors",0
probeno_msg db " (Standard Modus)",0
probeok_msg db " (teste nicht-standard Modi)",0
;dma_msg db " [b] Nutze DMA zum HDD Aufschreiben:",0
usebd_msg db " [b] Add disks visible by BIOS:",0
on_msg db " an",13,10,0
off_msg db " aus",13,10,0
;readonly_msg db " fur Lesen",13,10,0
vrrm_msg db " [c] Nutze VRR:",0
preboot_device_msg db " [d] Diskettenimage: ",0
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
pdm1 db "Echte Diskette",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "Nutze bereits geladenes Image",13,10,0
pdm4 db "create blank image",13,10,0
loading_msg db "Lade KolibriOS...",0
save_quest db "Aktuelle Einstellungen speichern? [y/n]: ",0
loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0
 
remark1 db "Default values were selected to match most of configurations, but not all.",0
remark2 db "If you have CRT-monitor, enable VRR in the item [c].",0
remark3 db "If the system does not boot, try to disable the item [b].",0
remarks dw remark1, remark2, remark3
num_remarks = 3
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/bootru.inc
0,0 → 1,91
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;=================================================================
;
; BOOT DATA
;
;=================================================================
 
$Revision$
 
 
d80x25_bottom:
db 186,' Kolibri OS ®á­®¢ ­  ­  Menuet OS ¨ ­¥ ¯à¥¤®áâ ¢«ï¥â '
db '­¨ª ª¨å £ àa­â¨©. ',186
db 186,' ®¤à®¡­¥¥ ᬮâà¨â¥ ¢ ä ©«¥ COPYING.TXT '
db ' ',186
line_full_bottom
d80x25_bottom_num = 3
 
msg_apm db " APM x.x ", 0
novesa db "‚¨¤¥®ª àâ : EGA/CGA",13,10,0
s_vesa db "‚¥àá¨ï VESA: "
.ver db "?.?",13,10,0
 
gr_mode db "‚ë¡¥à¨â¥ ¢¨¤¥®à¥¦¨¬: ",13,10,0
vrrmprint db "ˆá¯®«ì§®¢ âì VRR? (ç áâ®â  ª ¤à®¢ ¢ëè¥ 60 ƒæ"
db " ⮫쪮 ¤«ï ¯¥à¥å®¤®¢:",13,10
db 186," 1024*768>800*600 ¨ 800*600>640*480) [1-¤ , 2-­¥â]: ",0
;ask_dma db "ˆá¯®«ì§®¢ âì DMA ¤«ï ¤®áâ㯠 ª HDD? [1-¤ , 2-⮫쪮 ç⥭¨¥, 3-­¥â]: ",0
ask_bd db "„®¡ ¢¨âì ¤¨áª¨, ¢¨¤¨¬ë¥ ç¥à¥§ BIOS ¢ ०¨¬¥ V86? [1-¤ , 2-­¥â]: ",0
bdev db "‡ £à㧨âì ®¡à § ¨§ [1-¤¨áª¥â ; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-¨á¯®«ì§®¢ âì 㦥 § £à㦥­­ë© ®¡à §;"
db 13,10,186," "
db "4-ᮧ¤ âì ç¨áâë© ®¡à §]: ",0
prnotfnd db "Žè¨¡ª  - ‚¨¤¥®à¥¦¨¬ ­¥ ­ ©¤¥­.",0
not386 db "Žè¨¡ª  - ’ॡã¥âáï ¯à®æ¥áá®à 386+.",0
fatalsel db "Žè¨¡ª  - ‚ë¡à ­­ë© ¢¨¤¥®à¥¦¨¬ ­¥ ¯®¤¤¥à¦¨¢ ¥âáï.",0
pres_key db " ¦¨¬¨â¥ «î¡ãî ª« ¢¨èã, ¤«ï ¯¥à¥å®¤  ¢ ¢ë¡®à ०¨¬®¢.",0
badsect db 13,10,186," Žè¨¡ª  - „¨áª¥â  ¯®¢à¥¦¤¥­ . ®¯à®¡ã©â¥ ¤àã£ãî.",0
memmovefailed db 13,10,186," Žè¨¡ª  - Int 0x15 move failed.",0
okt db " ... OK"
linef db 13,10,0
diskload db "‡ £à㧪  ¤¨áª¥âë: 00 %",8,8,8,8,0
pros db "00"
backspace2 db 8,8,0
boot_dev db 0
start_msg db " ¦¬¨â¥ [abcd] ¤«ï ¨§¬¥­¥­¨ï ­ áâ஥ª, [Enter] ¤«ï ¯à®¤®«¦¥­¨ï § £à㧪¨",13,10,0
time_msg db " ¨«¨ ¯®¤®¦¤¨â¥ "
time_str db " 5 ᥪ㭤 "
db " ¤®  ¢â®¬ â¨ç¥áª®£® ¯à®¤®«¦¥­¨ï",13,10,0
current_cfg_msg db "’¥ªã騥 ­ áâனª¨:",13,10,0
curvideo_msg db " [a] ‚¨¤¥®à¥¦¨¬: ",0
 
 
mode0 db "320x200, EGA/CGA 256 梥⮢",13,10,0
mode9 db "640x480, VGA 16 梥⮢",13,10,0
 
usebd_msg db " [b] „®¡ ¢¨âì ¤¨áª¨, ¢¨¤¨¬ë¥ ç¥à¥§ BIOS:",0
on_msg db " ¢ª«",13,10,0
off_msg db " ¢ëª«",13,10,0
readonly_msg db " ⮫쪮 ç⥭¨¥",13,10,0
vrrm_msg db " [c] ˆá¯®«ì§®¢ ­¨¥ VRR:",0
preboot_device_msg db " [d] Ž¡à § ¤¨áª¥âë: ",0
preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4
pdm1 db "­ áâ®ïé ï ¤¨áª¥â ",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "¨á¯®«ì§®¢ âì 㦥 § £à㦥­­ë© ®¡à §",13,10,0
pdm4 db "ᮧ¤ âì ç¨áâë© ®¡à §",13,10,0
loading_msg db "ˆ¤ñâ § £à㧪  KolibriOS...",0
save_quest db "‡ ¯®¬­¨âì ⥪ã騥 ­ áâனª¨? [y/n]: ",0
loader_block_error db "Žè¨¡ª  ¢ ¤ ­­ëå ­ ç «ì­®£® § £àã§ç¨ª , ¯à®¤®«¦¥­¨¥ ­¥¢®§¬®¦­®.",0
 
 
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ',13,10,0
_r1 db 186,' ³ 320x200 EGA/CGA 256 梥⮢ ³ ³ ',13,10,0
_r2 db 186,' ³ 640x480 VGA 16 梥⮢ ³ ³ ',13,10,0
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³ ',13,10,0
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ',13,10,0
 
 
remark1 db "‡­ ç¥­¨ï ¯® 㬮«ç ­¨î ¢ë¡à ­ë ¤«ï 㤮¡á⢠ ¡®«ì設á⢠, ­® ­¥ ¢á¥å.",0
remark2 db "…᫨ 㠂 á ‹’-¬®­¨â®à, ¢ª«îç¨â¥ VRR ¢ ¯ã­ªâ¥ [c].",0
remark3 db "…᫨ 㠂 á ­¥ £à㧨âáï á¨á⥬ , ¯®¯à®¡ã©â¥ ®âª«îç¨âì ¯ã­ªâ [b].",0
remarks dw remark1, remark2, remark3
num_remarks = 3
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/bootvesa.inc
0,0 → 1,755
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
struc VBE_VGAInfo {
.VESASignature dd ? ; char
.VESAVersion dw ? ; short
.OemStringPtr dd ? ; char *
.Capabilities dd ? ; ulong
.VideoModePtr dd ? ; ulong
.TotalMemory dw ? ; short
; VBE 2.0+
.OemSoftwareRev db ? ; short
.OemVendorNamePtr dw ? ; char *
.OemProductNamePtr dw ? ; char *
.OemProductRevPtr dw ? ; char *
.reserved rb 222 ; char
.OemData rb 256 ; char
}
 
struc VBE_ModeInfo {
.ModeAttributes dw ? ; short
.WinAAttributes db ? ; char
.WinBAttributes db ? ; char
.WinGranularity dw ? ; short
.WinSize dw ? ; short
.WinASegment dw ? ; ushort
.WinBSegment dw ? ; ushort
.WinFuncPtr dd ? ; void *
.BytesPerScanLine dw ? ; short
.XRes dw ? ; short
.YRes dw ? ; short
.XCharSize db ? ; char
.YCharSize db ? ; char
.NumberOfPlanes db ? ; char
.BitsPerPixel db ? ; char
.NumberOfBanks db ? ; char
.MemoryModel db ? ; char
.BankSize db ? ; char
.NumberOfImagePages db ? ; char
.res1 db ? ; char
.RedMaskSize db ? ; char
.RedFieldPosition db ? ; char
.GreenMaskSize db ? ; char
.GreenFieldPosition db ? ; char
.BlueMaskSize db ? ; char
.BlueFieldPosition db ? ; char
.RsvedMaskSize db ? ; char
.RsvedFieldPosition db ? ; char
.DirectColorModeInfo db ? ; char ; MISSED IN THIS TUTORIAL!! SEE ABOVE
; VBE 2.0+
.PhysBasePtr dd ? ; ulong
.OffScreenMemOffset dd ? ; ulong
.OffScreenMemSize dw ? ; short
; VBE 3.0+
.LinbytesPerScanLine dw ? ; short
.BankNumberOfImagePages db ? ; char
.LinNumberOfImagePages db ? ; char
.LinRedMaskSize db ? ; char
.LinRedFieldPosition db ? ; char
.LingreenMaskSize db ? ; char
.LinGreenFieldPosition db ? ; char
.LinBlueMaskSize db ? ; char
.LinBlueFieldPosition db ? ; char
.LinRsvdMaskSize db ? ; char
.LinRsvdFieldPosition db ? ; char
.MaxPixelClock dd ? ; ulong
.res2 rb 190 ; char
}
 
virtual at $A000
vi VBE_VGAInfo
mi VBE_ModeInfo
modes_table:
end virtual
cursor_pos dw 0 ;âðåìåííîå õðàíåíèå êóðñîðà.
home_cursor dw 0 ;current shows rows a table
end_cursor dw 0 ;end of position current shows rows a table
scroll_start dw 0 ;start position of scroll bar
scroll_end dw 0 ;end position of scroll bar
long_v_table equ 9 ;long of visible video table
size_of_step equ 10
scroll_area_size equ (long_v_table-2)
int2str:
dec bl
jz @f
xor edx,edx
div ecx
push edx
call int2str
pop eax
@@: or al,0x30
mov [ds:di],al
inc di
ret
 
int2strnz:
cmp eax,ecx
jb @f
xor edx,edx
div ecx
push edx
call int2strnz
pop eax
@@: or al,0x30
mov [es:di],al
inc di
ret
 
;-------------------------------------------------------
;Write message about incorrect v_mode and write message about jmp on swith v_mode
v_mode_error:
_setcursor 19,2
mov si, fatalsel
call printplain
_setcursor 20,2
mov si,pres_key
call printplain
xor eax,eax
int 16h
jmp cfgmanager.d
;-------------------------------------------------------
;
 
 
 
;-------------------------------------------------------
print_vesa_info:
_setcursor 5,2
 
mov [es:vi.VESASignature],'VBE2'
mov ax,0x4F00
mov di,vi ;0xa000
int 0x10
or ah,ah
jz @f
mov [es:vi.VESASignature],'VESA'
mov ax,$4F00
mov di,vi
int 0x10
or ah,ah
jnz .exit
@@:
cmp [es:vi.VESASignature],'VESA'
jne .exit
cmp [es:vi.VESAVersion],0x0100
jb .exit
jmp .vesaok2
 
.exit:
mov si,novesa
call printplain
ret
 
.vesaok2:
mov ax,[es:vi.VESAVersion]
add ax,'00'
 
mov [s_vesa.ver], ah
mov [s_vesa.ver+2], al
mov si,s_vesa
call printplain
 
_setcursor 4,2
mov si,word[es:vi.OemStringPtr]
mov di,si
 
push ds
mov ds,word[es:vi.OemStringPtr+2]
call printplain
pop ds
 
ret
;-----------------------------------------------------------------------------
 
calc_vmodes_table:
pushad
 
; push 0
; pop es
 
lfs si, [es:vi.VideoModePtr]
 
mov bx,modes_table
;save no vesa mode of work 320x200, EGA/CGA 256 梥⮢ and 640x480, VGA 16 梥⮢
mov word [es:bx],640
mov word [es:bx+2],480
mov word [es:bx+6],0x13
mov word [es:bx+10],640
mov word [es:bx+12],480
mov word [es:bx+16],0x12
add bx,20
.next_mode:
mov cx,word [fs:si] ; mode number
cmp cx,-1
je .modes_ok.2
 
mov ax,0x4F01
mov di,mi
int 0x10
 
or ah,ah
jnz .modes_ok.2;vesa_info.exit
 
test [es:mi.ModeAttributes],00000001b ;videomode support ?
jz @f
test [es:mi.ModeAttributes],00010000b ;picture ?
jz @f
test [es:mi.ModeAttributes],10000000b ;LFB ?
jz @f
 
cmp [es:mi.BitsPerPixel], 24 ;It show only videomodes to have support 24 and 32 bpp
jb @f
 
; cmp [es:mi.BitsPerPixel],16
; jne .l0
; cmp [es:mi.GreenMaskSize],5
; jne .l0
; mov [es:mi.BitsPerPixel],15
 
 
.l0:
cmp [es:mi.XRes],640
jb @f
cmp [es:mi.YRes],480
jb @f
; cmp [es:mi.BitsPerPixel],8
; jb @f
 
mov ax,[es:mi.XRes]
mov [es:bx+0],ax ; +0[2] : resolution X
mov ax,[es:mi.YRes]
mov [es:bx+2],ax ; +2[2] : resolution Y
mov ax,[es:mi.ModeAttributes]
mov [es:bx+4],ax ; +4[2] : attributes
 
cmp [s_vesa.ver],'2'
jb .lp1
 
or cx,0x4000 ; use LFB
.lp1: mov [es:bx+6],cx ; +6 : mode number
movzx ax,byte [es:mi.BitsPerPixel]
mov word [es:bx+8],ax ; +8 : bits per pixel
add bx,size_of_step ; size of record
 
@@:
add si,2
jmp .next_mode
 
.modes_ok.2:
 
mov word[es:bx],-1 ;end video table
mov word[end_cursor],bx ;save end cursor position
;;;;;;;;;;;;;;;;;;
;Sort array
; mov si,modes_table
;.new_mode:
; mov ax,word [es:si]
; cmp ax,-1
; je .exxit
; add ax,word [es:si+2]
; add ax,word [es:si+8]
; mov bp,si
;.again:
; add bp,12
; mov bx,word [es:bp]
; cmp bx,-1
; je .exit
; add bx,word [es:bp+2]
; add bx,word [es:bp+8]
;
; cmp ax,bx
; ja .loops
; jmp .again
;.loops:
; push dword [es:si]
; push dword [es:si+4]
; push dword [es:si+8]
; push dword [es:bp]
; push dword [es:bp+4]
; push dword [es:bp+8]
;
; pop dword [es:si+8]
; pop dword [es:si+4]
; pop dword [es:si]
; pop dword [es:bp+8]
; pop dword [es:bp+4]
; pop dword [es:bp]
; jmp .new_mode
;
;.exit: add si,12
; jmp .new_mode
;.exxit:
popad
ret
 
;-----------------------------------------------------------------------------
 
draw_current_vmode:
push 0
pop es
 
mov si,word [cursor_pos]
 
cmp word [es:si+6],0x12
je .no_vesa_0x12
 
cmp word [es:si+6],0x13
je .no_vesa_0x13
 
mov di,loader_block_error
movzx eax,word[es:si+0]
mov ecx,10
call int2strnz
mov byte[es:di],'x'
inc di
movzx eax,word[es:si+2]
call int2strnz
mov byte[es:di],'x'
inc di
movzx eax,word[es:si+8]
call int2strnz
mov dword[es:di],0x00000d0a
mov si,loader_block_error
push ds
push es
pop ds
call printplain
pop ds
ret
.no_vesa_0x13:
mov si,mode0
jmp .print
.no_vesa_0x12:
mov si,mode9
.print:
call printplain
ret
;-----------------------------------------------------------------------------
check_first_parm:
mov si,word [preboot_graph]
test si,si
jnz .no_zero ;if no zero
.zerro:
; mov ax,modes_table
; mov word [cursor_pos],ax
; mov word [home_cursor],ax
; mov word [preboot_graph],ax
;SET default video of mode first probe will fined a move of work 1024x768@32
 
mov ax,1024
mov bx,768
mov si,modes_table
call .loops
test ax,ax
jz .ok_found_mode
mov ax,800
mov bx,600
mov si,modes_table
call .loops
test ax,ax
jz .ok_found_mode
mov ax,640
mov bx,480
mov si,modes_table
call .loops
test ax,ax
jz .ok_found_mode
 
mov si,modes_table
jmp .ok_found_mode
 
 
 
.no_zero:
mov bp,word [number_vm]
cmp bp,word [es:si+6]
jz .ok_found_mode
mov ax,word [x_save]
mov bx,word [y_save]
mov si,modes_table
call .loops
test ax,ax
jz .ok_found_mode
 
mov si,modes_table
; cmp ax,modes_table
; jb .zerro ;check on correct if bellow
; cmp ax,word [end_cursor]
; ja .zerro ;check on correct if anymore
 
.ok_found_mode:
mov word [home_cursor],si
; mov word [cursor_pos],si
mov word [preboot_graph],si
mov ax,si
 
mov ecx,long_v_table
 
.loop: add ax,size_of_step
cmp ax,word [end_cursor]
jae .next_step
loop .loop
.next_step:
sub ax,size_of_step*long_v_table
cmp ax,modes_table
jae @f
mov ax,modes_table
@@:
 
mov word [home_cursor],ax
mov si,[preboot_graph]
mov word [cursor_pos],si
 
push word [es:si]
pop word [x_save]
push word [es:si+2]
pop word [y_save]
push word [es:si+6]
pop word [number_vm]
 
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;
.loops:
cmp ax,word [es:si]
jne .next
cmp bx,word [es:si+2]
jne .next
cmp word [es:si+8],32
je .ok
cmp word [es:si+8],24
je .ok
.next: add si,size_of_step
cmp word [es:si],-1
je .exit
jmp .loops
.ok: xor ax,ax
ret
.exit: or ax,-1
ret
 
 
;-----------------------------------------------------------------------------
 
;default_vmode:
;-----------------------------------------------------------------------------
draw_vmodes_table:
_setcursor 9, 2
mov si,gr_mode
call printplain
 
mov si,_st
call printplain
 
push word [cursor_pos]
pop ax
push word [home_cursor]
pop si
mov cx,si
 
cmp ax,si
je .ok
jb .low
 
 
add cx,size_of_step*long_v_table
cmp ax,cx
jb .ok
sub cx,size_of_step*long_v_table
add cx,size_of_step
cmp cx,word[end_cursor]
jae .ok
add si,size_of_step
push si
pop word [home_cursor]
jmp .ok
 
 
.low: sub cx,size_of_step
cmp cx,modes_table
jb .ok
push cx
push cx
pop word [home_cursor]
pop si
 
 
.ok:
; calculate scroll position
push si
mov ax, [end_cursor]
sub ax, modes_table
mov bx, size_of_step
cwd
div bx
mov si, ax ; si = size of list
mov ax, [home_cursor]
sub ax, modes_table
cwd
div bx
mov di, ax
mov ax, scroll_area_size*long_v_table
cwd
div si
test ax, ax
jnz @f
inc ax
@@:
cmp al, scroll_area_size
jb @f
mov al, scroll_area_size
@@:
mov cx, ax
; cx = scroll height
; calculate scroll pos
xor bx, bx ; initialize scroll pos
sub al, scroll_area_size+1
neg al
sub si, long_v_table-1
jbe @f
mul di
div si
mov bx, ax
@@:
inc bx
imul ax, bx, size_of_step
add ax, [home_cursor]
mov [scroll_start], ax
imul cx, size_of_step
add ax, cx
mov [scroll_end], ax
pop si
mov bp,long_v_table ;show rows
.@@_next_bit:
;clear cursor
mov ax,' '
mov word[ds:_r1+21],ax
mov word[ds:_r1+50],ax
 
mov word[ds:_r2+21],ax
mov word[ds:_r2+45],ax
 
mov word[ds:_rs+21],ax
mov word[ds:_rs+46],ax
; draw string
cmp word [es:si+6],0x12
je .show_0x12
cmp word [es:si+6],0x13
je .show_0x13
 
movzx eax,word[es:si]
cmp ax,-1
je .@@_end
mov di,_rs+23
mov ecx,10
mov bl,4
call int2str
movzx eax,word[es:si+2]
inc di
mov bl,4
call int2str
 
movzx eax,word[es:si+8]
inc di
mov bl,2
call int2str
 
cmp si, word [cursor_pos]
jne .next
;draw cursor
mov word[ds:_rs+21],'>>'
mov word[ds:_rs+46],'<<'
 
 
.next:
push si
mov si,_rs
.@@_sh:
; add to the string pseudographics for scrollbar
pop bx
push bx
mov byte [si+53], ' '
cmp bx, [scroll_start]
jb @f
cmp bx, [scroll_end]
jae @f
mov byte [si+53], 0xDB ; filled bar
@@:
push bx
add bx, size_of_step
cmp bx, [end_cursor]
jnz @f
mov byte [si+53], 31 ; 'down arrow' symbol
@@:
sub bx, [home_cursor]
cmp bx, size_of_step*long_v_table
jnz @f
mov byte [si+53], 31 ; 'down arrow' symbol
@@:
pop bx
cmp bx, [home_cursor]
jnz @f
mov byte [si+53], 30 ; 'up arrow' symbol
@@:
call printplain
pop si
add si,size_of_step
 
dec bp
jnz .@@_next_bit
 
.@@_end:
mov si,_bt
call printplain
ret
.show_0x13:
push si
 
cmp si, word [cursor_pos]
jne @f
mov word[ds:_r1+21],'>>'
mov word[ds:_r1+50],'<<'
@@:
mov si,_r1
jmp .@@_sh
.show_0x12:
push si
cmp si, word [cursor_pos]
jne @f
 
mov word[ds:_r2+21],'>>'
mov word[ds:_r2+45],'<<'
@@:
mov si,_r2
jmp .@@_sh
 
;-----------------------------------------------------------------------------
;Clear arrea of current video page (0xb800)
clear_vmodes_table:
pusha
; draw frames
push es
push 0xb800
pop es
mov di,1444
xor ax,ax
mov ah, 1*16+15
mov cx,70
mov bp,12
.loop_start:
rep stosw
mov cx,70
add di,20
dec bp
jns .loop_start
pop es
popa
ret
 
;-----------------------------------------------------------------------------
 
set_vmode:
push 0 ;0;x1000
pop es
 
mov si,word [preboot_graph] ;[preboot_graph]
mov cx,word [es:si+6] ; number of mode
 
mov ax,word [es:si+0] ; resolution X
mov bx,word [es:si+2] ; resolution Y
 
 
mov word [es:0x900A],ax ; resolution X
mov word [es:0x900C],bx ; resolution Y
mov word [es:0x9008],cx ; number of mode
 
cmp cx,0x12
je .mode0x12_0x13
cmp cx,0x13
je .mode0x12_0x13
 
 
cmp byte [s_vesa.ver],'2'
jb .vesa12
 
; VESA 2 and Vesa 3
 
mov ax,0x4f01
and cx,0xfff
mov di,mi;0xa000
int 0x10
; LFB
mov eax,[es:mi.PhysBasePtr];di+0x28]
mov [es:0x9018],eax
; ---- vbe voodoo
BytesPerLine equ 0x10
mov ax, [es:di+BytesPerLine]
mov [es:0x9001], ax
; BPP
cmp [es:mi.BitsPerPixel],16
jne .l0
cmp [es:mi.GreenMaskSize],5
jne .l0
mov [es:mi.BitsPerPixel],15
.l0:
mov al, byte [es:di+0x19]
mov [es:0x9000], al
jmp .exit
 
.mode0x12_0x13:
mov byte [es:0x9000], 32
or dword [es:0x9018], 0xFFFFFFFF; 0x800000
 
 
; VESA 1.2 PM BANK SWITCH ADDRESS
 
.vesa12:
 
 
mov ax,0x4f0A
xor bx,bx
int 0x10
xor eax,eax
xor ebx,ebx
mov ax,es
shl eax,4
mov bx,di
add eax,ebx
movzx ebx,word[es:di]
add eax,ebx
push 0x0000
pop es
mov [es:0x9014],eax
.exit:
ret
 
 
; mov dword[es:0x9018],0x000A0000
; ret
 
;=============================================================================
;=============================================================================
;=============================================================================
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/ru.inc
0,0 → 1,102
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; Generated by RUFNT.EXE
; By BadBugsKiller (C)
; Modifyed by BadBugsKiller 12.01.2004 17:45
; Øðèôò óìåíüøåí â ðàçìåðå è òåïåðü ñîñòîèò èç 2-óõ ÷àñòåé,
; ñîäåðæàùèõ òîëüêî ñèìâîëû ðóññêîãî àëôàâèòà.
; ñèìâîëû â êîäèðîâêå ASCII (ÄÎÑ'îâñêàÿ), êîäîâàÿ ñòðàíèöà 866.
RU_FNT1:
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
RU_FNT2:
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00
db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00
db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00
db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/preboot.inc
0,0 → 1,38
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
display_modechg db 0 ; display mode change for text, yes/no (0 or 2)
;
; !! Important note !!
;
; Must be set to 2, to avoid two screenmode
; changes within a very short period of time.
 
display_atboot db 0 ; show boot screen messages ( 2-no )
 
preboot_graph dw 0 ; graph mode
x_save dw 0 ; x
y_save dw 0 ; y
number_vm dw 0 ;
;pixel_save dw 0 ; per to pixel
preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes)
preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no)
preboot_dma db 0 ; use DMA for access to HDD (1-always, 2-only for read, 3-never)
preboot_device db 0 ; boot device
; (1-floppy 2-harddisk 3-kernel restart 4-format ram disk)
;!!!! 0 - autodetect !!!!
preboot_blogesc = 0 ; start immediately after bootlog
preboot_biosdisk db 0 ; use V86 to access disks through BIOS (1-yes, 2-no)
 
if $>0x200
ERROR: prebooting parameters must fit in first sector!!!
end if
hdsysimage db 'KOLIBRI IMG' ; load from
image_save db 'KOLIBRI IMG' ; save to
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/bootstr.inc
0,0 → 1,62
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; boot data: common strings (for all languages)
macro line_full_top {
db 201
times 78 db 205
db 187
}
macro line_full_bottom {
db 200
times 78 db 205
db 188
}
macro line_half {
db 186,' '
times 76 db 0xc4
db ' ',186
}
macro line_space {
db 186
times 78 db 32
db 186
}
d80x25_top:
line_full_top
cur_line_pos = 75
store byte ' ' at d80x25_top+cur_line_pos+1
rev_var = __REV__
while rev_var > 0
store byte rev_var mod 10 + '0' at d80x25_top+cur_line_pos
cur_line_pos = cur_line_pos - 1
rev_var = rev_var / 10
end while
store byte ' ' at d80x25_top+cur_line_pos
store dword ' SVN' at d80x25_top+cur_line_pos-4
 
space_msg: line_space
verstr:
; line_space
; version string
db 186,32
repeat 78
load a byte from version+%-1
if a = 13
break
end if
db a
end repeat
repeat 78 - ($-verstr)
db ' '
end repeat
db 32,186
line_half
d80x25_top_num = 4
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/et.inc
0,0 → 1,16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; Full ASCII code font
; only õ and ä added
; Kaitz
ET_FNT:
fontfile file "ETFONT.FNT"
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/shutdown.inc
0,0 → 1,209
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Shutdown for Menuet ;;
;; ;;
;; Distributed under General Public License ;;
;; See file COPYING for details. ;;
;; Copyright 2003 Ville Turjanmaa ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
align 4
pr_mode_exit:
 
; setup stack
mov ax, 0x3000
mov ss, ax
mov esp, 0x0EC00
; setup ds
push cs
pop ds
 
lidt [old_ints_h]
;remap IRQs
mov al,0x11
out 0x20,al
call rdelay
out 0xA0,al
call rdelay
 
mov al,0x08
out 0x21,al
call rdelay
mov al,0x70
out 0xA1,al
call rdelay
 
mov al,0x04
out 0x21,al
call rdelay
mov al,0x02
out 0xA1,al
call rdelay
 
mov al,0x01
out 0x21,al
call rdelay
out 0xA1,al
call rdelay
 
mov al,0xB8
out 0x21,al
call rdelay
mov al,0xBD
out 0xA1,al
sti
 
temp_3456:
xor ax,ax
mov es,ax
mov al,byte [es:0x9030]
cmp al,1
jl nbw
cmp al,4
jle nbw32
 
nbw:
in al,0x60
cmp al,6
jae nbw
mov bl,al
nbw2:
in al,0x60
cmp al,bl
je nbw2
cmp al,240 ;ax,240
jne nbw31
mov al,bl
dec ax
jmp nbw32
nbw31:
add bl,128
cmp al,bl
jne nbw
sub al,129
 
nbw32:
 
dec ax
dec ax ; 2 = power off
jnz no_apm_off
call APM_PowerOff
jmp $
no_apm_off:
 
dec ax ; 3 = reboot
jnz restart_kernel ; 4 = restart kernel
push 0x40
pop ds
mov word[0x0072],0x1234
jmp 0xF000:0xFFF0
 
 
rdelay:
ret
 
APM_PowerOff:
mov ax, 5304h
xor bx, bx
int 15h
;!!!!!!!!!!!!!!!!!!!!!!!!
mov ax,0x5300
xor bx,bx
int 0x15
push ax
 
mov ax,0x5301
xor bx,bx
int 0x15
 
mov ax,0x5308
mov bx,1
mov cx,bx
int 0x15
 
mov ax,0x530E
xor bx,bx
pop cx
int 0x15
 
mov ax,0x530D
mov bx,1
mov cx,bx
int 0x15
 
mov ax,0x530F
mov bx,1
mov cx,bx
int 0x15
 
mov ax,0x5307
mov bx,1
mov cx,3
int 0x15
;!!!!!!!!!!!!!!!!!!!!!!!!
ret
 
restart_kernel:
 
mov ax,0x0003 ; set text mode for screen
int 0x10
jmp 0x4000:0000
 
restart_kernel_4000:
cli
 
push ds
pop es
mov cx, 0x8000
push cx
push 0x7000
pop ds
xor si, si
xor di, di
rep movsw
pop cx
mov ds, cx
push 0x2000
pop es
rep movsw
push 0x9000
pop ds
push 0x3000
pop es
mov cx, 0xE000/2
rep movsw
 
wbinvd ; write and invalidate cache
 
mov al, 00110100b
out 43h, al
jcxz $+2
mov al, 0xFF
out 40h, al
jcxz $+2
out 40h, al
jcxz $+2
sti
 
; (hint by Black_mirror)
; We must read data from keyboard port,
; because there may be situation when previous keyboard interrupt is lost
; (due to return to real mode and IRQ reprogramming)
; and next interrupt will not be generated (as keyboard waits for handling)
in al, 0x60
 
; bootloader interface
push 0x1000
pop ds
mov si, kernel_restart_bootblock
mov ax, 'KL'
jmp 0x1000:0000
 
 
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/rdload.inc
0,0 → 1,125
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
; READ RAMDISK IMAGE FROM HD
 
cmp [boot_dev+OS_BASE+0x10000],1
jne no_sys_on_hd
 
test [DRIVE_DATA+1],byte 0x40
jz position_2
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
mov [fat32part],0
position_1_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [DRIVE_DATA+2]
cmp [fat32part],eax
jle position_1_1
position_2:
test [DRIVE_DATA+1],byte 0x10
jz position_3
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
mov [fat32part],0
position_2_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [DRIVE_DATA+3]
cmp eax,[fat32part]
jle position_2_1
position_3:
test [DRIVE_DATA+1],byte 0x4
jz position_4
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
mov [fat32part],0
position_3_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [DRIVE_DATA+4]
cmp eax,[fat32part]
jle position_3_1
position_4:
test [DRIVE_DATA+1],byte 0x1
jz no_sys_on_hd
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
mov [fat32part],0
position_4_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [DRIVE_DATA+5]
cmp eax,[fat32part]
jle position_4_1
jmp yes_sys_on_hd
 
search_and_read_image:
call set_FAT32_variables
mov edx, bootpath
call read_image
test eax, eax
jz image_present
mov edx, bootpath2
call read_image
test eax, eax
jz image_present
ret
image_present:
mov [image_retrieved],1
ret
 
read_image:
mov eax, hdsysimage+OS_BASE+0x10000
mov ebx, 1474560/512
mov ecx, RAMDISK
mov esi, 0
mov edi, 12
call file_read
ret
 
image_retrieved db 0
counter_of_partitions db 0
no_sys_on_hd:
; test_to_format_ram_disk (need if not using ram disk)
cmp [boot_dev+OS_BASE+0x10000],3
jne not_format_ram_disk
; format_ram_disk
mov edi, RAMDISK
mov ecx, 0x1080
xor eax,eax
@@:
stosd
loop @b
 
mov ecx, 0x58F7F
mov eax,0xF6F6F6F6
@@:
stosd
loop @b
mov [RAMDISK+0x200],dword 0xFFFFF0 ; fat table
mov [RAMDISK+0x4200],dword 0xFFFFF0
not_format_ram_disk:
yes_sys_on_hd:
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot/ETFONT.FNT
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/kernel/branches/Kolibri-acpi/boot
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/sec_loader/trunk/build_ru.bat
0,0 → 1,4
@fasm -m 65535 loader.asm loader
@echo off
REM @fasm -m 65535 loader.asm loader > loader.lst
REM @pause
/kernel/branches/Kolibri-acpi/sec_loader/trunk/debug_msg.inc
0,0 → 1,77
; Copyright (c) 2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
;Òóò îïðåäåëåíû âñå ñîîáùåíèÿ, êîòîðûå íóæíû â ïðîöåññå îòëàäêè, è ñîâñåì íå íóæíû â ðàáî÷åé êîïèè ïðîãðàììû.
If DEBUG
cseg_msg db ' - Adress of code segment',0
stack_msg db 'Set stack & segments is have completed',0
show_string db 'Have loaded size:'
show_decode db ' ',0
show_db1 db ' -Message debug1',0
show_db2 db ' -Message debug2',0
 
 
lm_l_found db '[loader] is found',0
lm_lf_timeout db 'timeout is found',0
lm_lf_default db 'name default is found and end parsing section',0
lm_lf_section db 'found section [',0
lm_lf_default_f db 'found default parametr',0
lm_l_end db 'section [loader] is end',0
show_all_sect db 'SHOW ALL Sections',0
no_show_only_w db 'Not show sections - only work on default sect',0
_not_found db '[ not found',0
_found_1 db '[] found',0
_found_2 db '[ found',0
say_hello db 'Hello $)',0
ramdiskFS_st db 'Start use_RamdiskFS macros',0
free_memory_msg db ' -Kb availability system free memory',0
RamdiskSize_msg db ' -Kb equal RamdiskSize',0
RamdiskSector_msg db ' -byts RamdiskSector',0
RamdiskCluster_msg db ' -RamdiskCluster',0
RamdiskFile_msg db ' -size RamdiskFile',0
fat_create_msg db ' -first create fat table, point to next block',0
BPB_msg db ' -in byte, why we get data from move BPB struct',0
firstDataSect_msg db ' -first data sector, offset to data in sectors',0
size_root_dir_msg db ' -size root dir in sectrors',0
DataClasters_msg db ' -size data in Clasters',0
first_entry_in_fat db ' -data segment in FIRST entry FAT',0
check_root_fat_ db ' : --------------',0
check_name_fat_msg_y db 'Name is present that is BAD',0
check_name_fat_msg_n db 'Name is not present that is GOOD',0
name_of_seg_get_64 db ' -name of seg where we get 64 Kb of data',0
convertion_file_name_msg_y db '->Destination name of file is GOOD',0
convertion_file_name_msg_n db '->Destination name of file is BAD',0
alarm_msg db '%%%%%%%% WARNING: MISS THE FILE %%%%%%%%%%%',0
start_making_FAT12_msg db '>>>>>> Begin make a RAMDISK and FS after 1 Mb <<<<<<<',0
make_fat12_RFS_msg db '-Make FAT12 Ram FS',0
get_type_FS_msg db '-End make RamDisk',0
seg_where_get_data db ' - Segment where we get data for move up file',0
return_code_af_move db ' -return code after 0x87 int 0x15, move block',0
return_code_af_fat_m db ' -return code after 0x87 int 0x15, move fat struc',0
 
 
 
end if
/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_def_sect.inc
0,0 → 1,2094
; Copyright (c) 2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
; â ýòîé ñåêöèè èäåò ðàçáîð ïàðàìåòðîâ óêàçàòåëü íà ñåêöèþ õðàíèòüñÿ â point_default
;òèïû îøèáîê ïðè îáðàáîòêå ìàêðîñà
;Ìàêðîñ RamdiskFS
;/îïðåäåëåíèå ôëàãîâ â çàïèñè êîðíåâîé äèðåêòîðèè
ATTR_READ_ONLY equ 0x01
ATTR_HIDDEN equ 0x02
ATTR_SYSTEM equ 0x04
ATTR_VOLUME_ID equ 0x08
ATTR_DIRECTORY equ 0x10
ATTR_ARCHIVE equ 0x20
 
 
 
show_error_1 equ 0x1 ;êîí÷èëèñü äàííûå - íå çàïëàíèðîâàííûé êîíåö ñåêöèè
show_error_2 equ 0x2 ;íåò çàâåðøàþùåãî ñèìâîëà â ðàçìåðå ðàì äèñêà.
show_error_3 equ 0x4 ; ðàì äèñê áóäåò èìåòü ðàçìåð =64 êá.
show_error_4 equ 0x8 ;
 
macro use_parse_def_sect
{
mov di,point_default
push ini_data_
pop es
mov si,point_to_point_def
sub si,2
mov cx,[si] ;çàãðóçèì óêàçàòåëü íàñëåäóþùèþ ñåêöèþ
 
xor ax,ax ;îáíóëèì àx äëÿ î÷èñòêè ôëàãîâ
 
sub cx,di ;âîò òåïåðü èìååì èñòèíûé ðàçìåð
mov save_cx_d,cx ;ñîõðàíèì çíà÷åíèå cx ñâîåé ïåðåìåííîé
;îáíóëèì ïåðåìåííóþ ôëàãîâ, ýòî íåîáõîäèìî, äëÿ òîãî, ÷òî áû èçáåæàòü îáðàáîòêó ïîâòîðÿþùèõñÿ çíà÷åíèé
 
mov status_flag,ax
;;;;
;ÂÕîä â îáðàáîòêó ïàðñèíãà çíà÷åíèé ñåêöèé. es:di - óêàçàòåëü íà íà÷àëî ñåêöèè cx ðàçìåð ñåêöèè äîñòóïíîé äëÿ ïàðñèíãà
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ñîãëàøåíèå íå ðàçðóøàåì bp, es, cs, sp
;use_Loader_Image ;çàãðóçèòü îáðàç âûøå 1 ìá
use_RamdiskFS
;ïðîâåðÿåòñÿ ñàìûé ïîñëåäíèé.
use_LoaderModule ;îñîáåííîñòü - ïåðåäàåò óïðàâëåíèå íà çàãðóæåííûé ìîäóëü.
}
 
macro use_LoaderModule
;êàê âàðèàíò ñåé÷àñ èñïîëüçóåòñÿ ìîäåëü, ïðè çàãðóçêå ìîäóëÿ íà íåãî ïåðåäàåòñÿ óïðàâëåíèå, ðåøåíèå âðåìåíîå
;óïðàâëåíèå áóäåò ïåðåäàâàòüñÿ òîëüêî ïîñëå îáðàáîòêè âñåé ñåêöèè
{
local .found_end_str
 
mov di,point_default ;restore value
mov cx,save_cx_d
;îáðàáîòêà êîíñòðóêöèè òèïà LoaderModule=kord/kolibri.ldm
.start_p_LM:
call get_firs_sym ;get first symbol on new line
test cx,cx
jz ._afterLoaderModule ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà )
cmp al,'L'
jnz .start_p_LM
;ïðîâåðêà íà çíà÷åíèå LoaderModule
; parse_LoaderModule
mov bx,cx
mov ax,di
 
mov si,parse_LoaderModule
mov cx,parse_LoaderModule_e - parse_LoaderModule
repe cmpsb
jnz .rest_value_loop_LM ;is not compare
 
sub bx,parse_LoaderModule_e - parse_LoaderModule ;correct cx
add bx,cx
mov cx,bx
 
test status_flag,flag_found_LM ;îöåíêà ôëàãîâ
jz .correct_is_not_set_LM
 
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì
; call printplain
; jmp .get_next_str
 
.correct_is_not_set_LM:
mov ax,0x3d20 ;cut al=' ' ah='='
repe scasb
jcxz .rest_value_loop_LM ;not found param timeout
cmp ah,byte [es:di-1] ;find '='
jnz .rest_value_loop_LM
repe scasb ;cut ' '
inc cx
dec di
;di óêàçûâàåò íà íà÷àëî áëîêà èíôîðìàöèè, â cx äëèííà äî êîíöà ñåêöèè.
;ïîñëå çàãðóçêè çàíîñèòüñÿ çíà÷åíèå çàíÿòîé ïàìÿòè.
;äëÿ òîãî ÷òî áû çàãðóçèòü ìîäóëü, âîñïîëüçóåìñÿ callback ñåðâèñîì
;îðèãèíàëüíîå ðåøåíèå - ðàçìåñòèì dd ïåðåä ñòðî÷êîé è ïîñëå ñòðî÷êè ðàçìåñòèì byte =0
;ýòî âûãëÿäèò òàê: â ini ôàéëå ñóùåñòâóåò ñòðî÷êà LoaderModule = kord/kernel.loader
;ìû åå ìîäèôèöèðóåì äî òàêîãî ñîñòîÿíèÿ dw,dw,db'kord/kernel.loader',0 êîíå÷íî ñîõðàíèâ òå çíà÷åíèÿ êîòîðûå ìû çàìåíÿåì
;ñîõðàíèëè ïåâûå 2 word
push dword [es:di-6]
lea si,[di-6]
 
push word [es:di-2]
xor ax,ax
mov word [es:di-6],ax ;âíîñèì íóæíûå çíà÷åíèÿ
;info_real_mode_size ðàçìåð è óêàçàòåëü íà îáëàñòü â êîòîðóþ ìîæíî çàãðóçèòüñÿ
mov ax,info_real_mode_size ;0x3000 ;ñëåäóþùèé ñåãìåíò çà äàííûìè
 
 
mov word [es:di-4],ax
mov word [es:di-2],16 ;êîë-âî áëîêîâ ïî 4 êá =64 êá ò.å. áîëüøå íå ñ÷èòàåì
;;;;;; ïîèñê êîíöà ñòðî÷êè
@@: mov al,byte [es:di]
cmp al,' '
jz .found_end_str
cmp al,0xa
jz .found_end_str
cmp al,0xd
jz .found_end_str
inc di
dec cx
jnz @b
;;;not found äîïóñòèì,÷òî ýòî êîíåö ôàéëà è îí íå èìååò ïðèâû÷íîãî çàâåðåøíèÿ ñòðîêè
.found_end_str:
 
push word [es:di]
xor ax,ax
mov word [es:di],ax
; xor ax,ax ; function 1 - read file
mov di,si ;file_data
inc ax
push si
push es
 
push es
pop ds
push cs
pop es
 
call far dword [es:loader_callback]
 
push cs
pop ds
 
pop es
pop si
 
test bx,bx
jnz .error_LM
 
 
jmp far dword [es:si]
 
 
.error_LM:
call error.LoaderModule
.rest_value_loop_LM:
mov di,ax
mov cx,bx
jmp .start_p_LM
 
._afterLoaderModule:
}
 
macro use_RamdiskFS
; ôîðìèðîâàíèå ðàì äèñêà, + îáðàáîòêà âñåãî ñâÿçàííîãî.
{
if DEBUG
local ._not_memory_in_sys
;//////// clear window
mov ax,3
int 0x10
;\\\\\\\\\ clear window is end
mov si,ramdiskFS_st
call printplain
end if
; îáíóëèì ðåãèñòð ñîñòîÿíèÿ îøèáîê
xor ax,ax
mov show_errors_sect,ax
use_free_memory ; óçíàåì êàêîãî îáúåìà ó íàñ äîñòóïíà ïàìÿòü. çíà÷åíèå âîçàðàùàåòñÿ â ax
;óçíàåì ñêîëüêî ó íàñ åñòü ïàìÿòè è ñìîæåì ëè ìû ñôîðìèðîâàòü íóæíîãî ðàçìåðà ðàì äèñê.
use_RamdiskSize ;çíà÷åíèå âîçâðàùàåòñÿ â bx
cmp free_ad_memory,bx ; ðàçìåðíîñòü â êá.
jbe ._not_memory_in_sys
movzx eax,bx
shl eax,10 ;*1024 = get size in byte
mov save_ramdisksize,eax ; ñîðõàíèì ðàçìåð â byte
 
get_type_FS ;ïîëó÷èì òèï ôàéëîâîé ñèñòåìû + ñîçäàäèì åå
 
._not_memory_in_sys:
if DEBUG
;pause
xor ax,ax
int 0x16
end if
}
macro use_RamdiskSize
{
local .start_p_RS
local .correct_is_not_set_RS
local .CS
local .correct_val_RS
local .correct_size_RS
local .rest_value_loop_RS
local .end_get_RS_ERROR_1
local .end_get_RS_ERROR_2
local ._end_parse_RS
;îáðàáàòûâàåòñÿ ðàçìåð ôîðìèðóåìîãî ðàì äèñêà
;çàãðóçèì íà÷àëî ñåêöèè, ò.ê. áóäåì ïðîñìàòðèâàòü ñ íà÷àëà è âñþ ñåêöèþ
mov di,point_default ;restore value
mov cx,save_cx_d
.start_p_RS:
call get_firs_sym ;get first symbol on new line
test cx,cx
jz ._end_parse_RS ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà )
cmp al,'R'
jnz .start_p_RS
;ïðîâåðêà íà çíà÷åíèÿ RamdiskSize
; parse_RamdiskSize
mov bx,cx
mov ax,di
 
mov si,parse_RamdiskSize
mov cx,parse_RamdiskSize_e - parse_RamdiskSize
repe cmpsb
jnz .rest_value_loop_RS ;is not compare
 
sub bx,parse_RamdiskSize_e - parse_RamdiskSize ;correct cx
add bx,cx
mov cx,bx
 
test status_flag,flag_found_RS ;îöåíêà ôëàãîâ
jz .correct_is_not_set_RS
 
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì
; call printplain
; jmp .get_next_str
 
.correct_is_not_set_RS:
mov ax,0x3d20 ;cut al=' ' ah='='
repe scasb
jcxz .end_get_RS_ERROR_1 ;not found param
cmp ah,byte [es:di-1] ;find '='
jnz .start_p_RS ; ïåðåéäåì íà íà÷àëî è ïîïðîáóåì íàéòè åùå ñåêöèþ
repe scasb ;cut ' '
inc cx
dec di
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Òóò íóæíî ïðåîáðàçîâûâàòü ñòðî÷êó â öèôðîâîå çíà÷åíèå.
;;;;;;;;;;;;;;;;;;;;;;;;;;
xor bx,bx
mov cx,5
@@: mov al,byte [es:di]
cmp al,'0'
jb .CS
cmp al,'9'
jbe .correct_val_RS
.CS:
cmp al,'K'
jz .correct_size_RS
jmp .end_get_RS_ERROR_2
.correct_val_RS:
imul bx,10
xor al,0x30
add bl,al
inc di
loop @b
 
.correct_size_RS:
;âîçìîæåí 1 âàðèàíò, êîãäà ðàçìåð çàäàí â K êèëëîáàéòàõ
;âíóòðåííûé ôîðìàò äàííûõ ýòî êîë-âî çàïðîùåíîé ïàìÿòè â êá.
test bx,bx
jnz @f ;åñëè çíà÷åíèå îòëè÷íî îò 0
;;;;;ñîîáùåíèå îá îøèáêå, ðàçìåð "íàéäåíîãî" áëîêà =0 ìèíèìàëüíî ìû äîëæíû
;óñòàíîâèòü 64 êá ðàçìåð ðàì äèñêà.
or show_errors_sect,show_error_3
mov bx,64
@@:
jmp ._end_parse_RS
 
 
.rest_value_loop_RS:
mov di,ax
mov cx,bx
jmp .start_p_RS
.end_get_RS_ERROR_1:
;ñîîáùåíèå îá îøèáêå - äàííûé ó÷àñòîê êîäà íå áûë êîððåêòíî îáðàáîòàí :(
or show_errors_sect,show_error_1
jmp ._end_parse_RS
.end_get_RS_ERROR_2:
or show_errors_sect,show_error_2
 
._end_parse_RS:
if DEBUG
pusha
movzx eax,bx
mov cx,0x0a
mov di,RamdiskSize_msg
mov dword[ds:di],' '
mov word [ds:di+4],' '
call decode
;Show size
mov si,RamdiskSize_msg
call printplain
 
popa
end if
 
}
 
macro use_free_memory
{
local _support_function_use_free_memory
;ìàêðîñ äëÿ ïîëó÷åíèÿ îáùåãî ÷èñëà äîñòóïíîé ïàìÿòè â êá, äëÿ ôîðìèðîâàíèÿ ðàì äèñêà çà ïðåäåëàìè 1 ìá.
;èñïîëüçóåòñÿ 0õ88 ôóíêöèÿ 0õ15 ïðåðûâàíèÿ
; åñëè ïîääåðæèâàåòñÿ ôóíêöèÿ, òî â ax çíà÷åíèå â êá, åñëè íåò, òî â ax=0
mov ah,0x88 ;ah,0x88
int 0x15
jnc ._support_function_use_free_memory
xor ax,ax
;âîçâðàùàåò â ax ÷èñëî â êá
._support_function_use_free_memory:
mov free_ad_memory,ax ; åñëè íå ïîääåðæèâàåòñÿ áèîñîì, òî â ax=0
if DEBUG
pushad
movzx eax,ax
mov cx,0x0a
mov di,free_memory_msg
mov dword[ds:di],' '
mov word [ds:di+4],' '
call decode
;Show size
mov si,free_memory_msg
call printplain
 
popad
end if
 
 
 
 
}
macro show_ERRORS
{
 
}
 
macro get_type_FS ;ïîëó÷èòü è ñîçäàòü îáðàç äëÿ çàäàííîé RFS.
{
mov di,point_default ;restore value
mov cx,save_cx_d
.start_g_tpe_RFS:
call get_firs_sym ;get first symbol on new line
test cx,cx
jz ._end_parse_FRS ;._end_get_type_RFS ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà )
cmp al,'R'
jnz .start_g_tpe_RFS
;ïðîâåðêà íà çíà÷åíèÿ RamdiskSize
; parse_RamdiskSize
mov bx,cx
mov ax,di
 
mov si,parse_RamdiskFS
mov cx,parse_RamdiskFS_e - parse_RamdiskFS
repe cmpsb
jnz .start_g_tpe_RFS_rest_v ;is not compare
 
sub bx,parse_RamdiskFS_e - parse_RamdiskFS ;correct cx
add bx,cx
mov cx,bx
 
test status_flag,flag_found_GTRFMS ;îöåíêà ôëàãîâ
jz .correct_is_not_set_FRS
 
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì
; call printplain
; jmp .get_next_str
 
.correct_is_not_set_FRS:
mov ax,0x3d20 ;cut al=' ' ah='='
repe scasb
test cx,cx
jz .end_get_FRS_ERROR_1 ;not found param
cmp ah,byte [es:di-1] ;find '='
jnz .start_g_tpe_RFS ; ïåðåéäåì íà íà÷àëî è ïîïðîáóåì íàéòè åùå ñåêöèþ
repe scasb ;cut ' '
inc cx
dec di
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Òóò íóæíî ïðåîáðàçîâûâàòü ñòðî÷êó â öèôðîâîå çíà÷åíèå.
;;;;;;;;;;;;;;;;;;;;;;;;;;
mov bx,cx
mov ax,di
 
mov si,parse_RFS_FAT
mov cx,parse_RFS_FAT_e - parse_RFS_FAT
repe cmpsb
jnz .krfs_cmp ;is not compare
 
make_FAT_RamFS ;ñäåëàòü
 
if DEBUG
pusha
mov si,make_fat12_RFS_msg
call printplain
popa
end if
jmp ._end_parse_FRS
 
.krfs_cmp:
mov cx,bx
mov di,ax
 
mov si,parse_RFS_KRFS
mov cx,parse_RFS_KRFS_e - parse_RFS_KRFS
repe cmpsb
; jnz @f ;is not compare
 
jmp ._end_parse_FRS
 
 
.start_g_tpe_RFS_rest_v:
mov cx,bx
mov di,ax
jmp .start_g_tpe_RFS
.end_get_FRS_ERROR_1:
;ñîîáùåíèå îá îøèáêå - äàííûé ó÷àñòîê êîäà íå áûë êîððåêòíî îáðàáîòàí :(
or show_errors_sect,show_error_1
jmp ._end_parse_FRS
.end_get_FRS_ERROR_2:
or show_errors_sect,show_error_2
 
._end_parse_FRS:
if DEBUG
pusha
mov si,get_type_FS_msg
call printplain
popa
end if
 
 
 
}
macro make_FAT_RamFS
{
local .RS1
local .fat12
local .fat16
; ìû äîëæíû ñôîðìèðîâàòü â íà÷àëüíûé îáðàç Ram FS, à ïîòîì çàïèñàòü åãî çà îáëàñòü âûøå 1 ìá..
;äëÿ ñëó÷àÿ ñ FAT12
; mov di,fat12_buffer ;ds äîëæåí áûòü = cs
;es:di - óêàçûâàþò íà íà÷àëî áëîêà äëÿ ôîðìèðîâàíèÿ ðàì ôñ.
use_RamdiskSector ;âîçðàùàåìîå çíà÷åíèå â ax ðàçìåð ñåêòîðà â áàéòàõ
cmp ax,4096 ;ïî ñïåöèôèêàöèè çíà÷åíèå äîëæíî áûòü â ïðåäåëàõ îò 1 äî 4096
ja .RS1
test ax,ax
jnz @f ;îøèáêà åñëè ñþäà ïðûãíóëè âñå òàêè ...
 
.RS1: mov word [fat12_buffer.BPB_BytsPerSec],512
;;;;;;;;;;ñêàæåì ÷òî ïî äåôîëòó áóäåì þçàòü çíà÷åíèå...
@@: mov word [fat12_buffer.BPB_BytsPerSec],ax ;òóò âñå îê
 
;BPB_SecPerClus êîë-âî ñåêòîðîâ â êëàñòåðå
use_RamdiskCluster ;âîçðàùàåìîå çíà÷åíèå â al
cmp al,128
ja @f
; test al,0x1 ;ïðîâåðêà íà êðàòíîñòü )
; jnz @f
 
mov byte [fat12_buffer.BPB_SecPerClus],al
 
;incorrect value will be set dafault
 
;íèæå íåêîððåêòíîå çíà÷åíèå â ò.ê. ðàçìåð êðàòåí 2 è â äèàïàçîíå îò 1 äî 128 âêëþ÷èòåëüíî
; ìû äîëæíû ðóãíóòüñÿ íà ýòî
;@@: ;mov byte [fat12_buffer.BPB_SecPerClus],1
 
;;;;; îïðåäåëåèì êàêàÿ ó íàñ áóäåò èñïîëüçîâàòüñÿ FAT
;ïî óñëîâèþ, fat12<4085<=fat16<65525<=fat32
; fat12_buffer.BPB_BytsPerSec*fat12_buffer.BPB_SecPerClus = êîë-âî ñåêòîðîâ
movzx eax,word [fat12_buffer.BPB_BytsPerSec]
movzx ebx,byte [fat12_buffer.BPB_SecPerClus]
 
imul ebx,eax ;òóò ðàçìåðíîñòü ñåêòîðà
mov eax,save_ramdisksize ;ðàçìåð çàïðîøåííîãî ðàì äèñêà â áàéòàõ
cdq
idiv ebx
;;;;;;;; ñåé÷àñ ÷àñòíîå â eax, à îñòàòîê â edx
;ïîëó÷èì êîë-âî ñåêòîðîâ, è ìîæåì óæå îïðåäåëèòü òèï FAT êîòîðóþ íóæíî äåëàòü.
cmp eax,4085
jb .fat12
cmp eax,65525
jb .fat16
;;;;;;;;;;;;;;;;;;;;;;;; òóò fat32
mov set_ramfs,32 ;óñòàíîâèì òèï ôàéëîâîé ñèñòåìû
mov word [fat12_buffer.BPB_RsvdSecCnt],32
xor eax,eax
mov word [fat12_buffer.BPB_RootEntCnt],ax
mov word [fat12_buffer.BPB_TotSec16],ax
mov dword [fat12_buffer.BPB_TotSec32],eax
 
 
.fat16: ;fat16
;Äëÿ FAT12 è FAT16 äèñêîâ ýòî ïîëå ñîäåðæèò êîëè÷åñòâî ñåêòîðîâ, à BPB_TotSec32 ðàâíî 0, åñëè çíà÷åíèå <óìåùàåòñÿ> (ìåíüøå 0x10000).
jmp $
mov set_ramfs,16 ;óñòàíîâèì òèï ôàéëîâîé ñèñòåìû
movzx ebx,byte [fat12_buffer.BPB_SecPerClus]
imul eax,ebx
 
cmp eax,0x10000
jae @f
mov word [fat12_buffer.BPB_TotSec16],ax
mov dword [fat12_buffer.BPB_TotSec32],0
@@:
;êîëè÷åñòâî ñåêòîðîâ çàíèìàåìîå îäíîé êîïèåé ôàò
; mov word [fat12_buffer.BPB_FATSz16],0x9 ;Äëÿ FAT12/FAT16 ýòî êîëè÷åñòâî ñåêòîðîâ îäíîé FAT. ??
;;;; çàïîëíèì BPB_RootEntCnt Äëÿ FAT12 è FAT16 äèñêîâ, ýòî ïîëå ñîäåðæèò ÷èñëî
;32-áàéòíûõ ýëåìåíòîâ êîðíåâîé äèðåêòîðèè. Äëÿ FAT32 äèñêîâ, ýòî ïîëå äîëæíî
;áûòü 0. Ïîêà êîíñòàíòà, íóæíî áóäåò ïîçæå äîäåëàòü.
mov eax,root_dir_entry_count
mov word [fat12_buffer.BPB_RootEntCnt],ax ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb)
;ïî äîêóìåíòàöèè ðåêîìåíäóþò îòðåçàòü 16 êá äëÿ ðóò äèð íî ýòî î÷ ìíîãî, äàæå äëÿ êîîñ. èìõî äëÿ íà÷àëà õâàòèò è 7 êá
;;;;;;;
;Äëÿ FAT16 ýòî êîëè÷åñòâî ñåêòîðîâ îäíîé FAT. Äëÿ FAT32 ýòî çíà÷åíèå
;ðàâíî 0, à êîëè÷åñòâî ñåêòîðîâ îäíîé FAT ñîäåðæèòñÿ â BPB_FATSz32.
;RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec;
 
;TmpVal1 = DskSize - (BPB_ResvdSecCnt + RootDirSectors);
;TmpVal2 = (256 * BPB_SecPerClus) + BPB_NumFATs;
;If(FATType == FAT32)
; TmpVal2 = TmpVal2 / 2;
;FATSz = (TMPVal1 + (TmpVal2 - 1)) / TmpVal2;
;If(FATType == FAT32) {
; BPB_FATSz16 = 0;
; BPB_FATSz32 = FATSz;
;} else {
; BPB_FATSz16 = LOWORD(FATSz);
; /* there is no BPB_FATSz32 in a FAT16 BPB */
;}
;=====================================
;RootDirSectors
movzx ebx, word [fat12_buffer.BPB_BytsPerSec]
imul eax,32
add eax,ebx
dec eax
 
cdq
idiv ebx
;;;;;;;; ñåé÷àñ ÷àñòíîå â eax, à îñòàòîê â edx äëÿ äèñêåòû 1.44 ó íàñ äîëæíî áûòü çíà÷åíèå =14
;BPB_ResvdSecCnt + RootDirSectors
movzx ebx, word [fat12_buffer.BPB_RsvdSecCnt]
add ebx,eax
;DskSize ó íàñ ýòî çíà÷åíèå óæå ïîëó÷åíî è äîñòóïíî
movzx eax,word [fat12_buffer.BPB_TotSec16] ;äîëæåí áûòü â ñåêòîðàõ
sub eax,ebx
 
 
;TmpVal1=eax
shl edi,8 ;=edi*256
movzx ecx,byte [fat12_buffer.BPB_NumFATs]
add edi,ecx
;TmpVal2=edi
add eax,edi
dec eax
cdq
idiv edi
;FATSz = ñåé÷àñ ÷àñòíîå â eax, à îñòàòîê â edx
mov word [fat12_buffer.BPB_FATSz16],ax
 
 
 
 
 
 
 
 
.fat12: ;fat12
if DEBUG
; âûâåäåì â îòëàäêå, ÷òî ñîáèðàåìñÿ äåëàòü îáðàç äèñêà c FS=fat12
pushad
mov si,start_making_FAT12_msg
call printplain
popad
end if
 
 
 
;Äëÿ FAT12 è FAT16 äèñêîâ ýòî ïîëå ñîäåðæèò êîëè÷åñòâî ñåêòîðîâ, à BPB_TotSec32 ðàâíî 0, åñëè çíà÷åíèå <óìåùàåòñÿ> (ìåíüøå 0x10000).
mov set_ramfs,12 ;óñòàíîâèì òèï ôàéëîâîé ñèñòåìû
movzx ebx,byte [fat12_buffer.BPB_SecPerClus]
imul eax,ebx
 
cmp eax,0x10000
jae @f
mov word [fat12_buffer.BPB_TotSec16],ax
mov dword [fat12_buffer.BPB_TotSec32],0
@@:
;êîëè÷åñòâî ñåêòîðîâ çàíèìàåìîå îäíîé êîïèåé ôàò
; mov word [fat12_buffer.BPB_FATSz16],0x9 ;Äëÿ FAT12/FAT16 ýòî êîëè÷åñòâî ñåêòîðîâ îäíîé FAT. ??
;;;; çàïîëíèì BPB_RootEntCnt Äëÿ FAT12 è FAT16 äèñêîâ, ýòî ïîëå ñîäåðæèò ÷èñëî
;32-áàéòíûõ ýëåìåíòîâ êîðíåâîé äèðåêòîðèè. Äëÿ FAT32 äèñêîâ, ýòî ïîëå äîëæíî
;áûòü 0. Ïîêà êîíñòàíòà, íóæíî áóäåò ïîçæå äîäåëàòü.
mov eax,root_dir_entry_count
mov word [fat12_buffer.BPB_RootEntCnt],ax ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb)
;ïî äîêóìåíòàöèè ðåêîìåíäóþò îòðåçàòü 16 êá äëÿ ðóò äèð íî ýòî î÷ ìíîãî, äàæå äëÿ êîîñ. èìõî äëÿ íà÷àëà õâàòèò è 7 êá
;;;;;;;
;DskSize(â ñåêòîðàõ)*12 (ðàçìåðíîñòü ôàéëîâîé ñèñòåìû, ò.å ïðåäïîëîæèì ñêîëüêî áèòîâ ïîòðåáóåòñÿ äëÿ àäðåñàöèè ýòîãî îáúåìà) /8 (÷òî ïîëó÷èòü ðàçìåð â áàéòàõ)
;ïîëó÷åííîå ÷èñëî îêðóãëÿåì â áîëüøóþ ñòîðîíó êðàòíîå ñåêòîðó ò.å. 512 áàéò Òàêîé ïîäõîä íå óíèâåðñàëåí, íî ïîêà ïîéäåò
;âîîáùå ó ìåëêîñîôò ýòî âñå ñ÷èòàåòñÿ ðó÷êàìè, íî ìû áóäåì þçàòü òîëüêî ïîä êîîñ ðàì äèñê ñ ôàò12
movzx eax, word [fat12_buffer.BPB_TotSec16]
imul eax,12
shr eax,3 ;äåëèì íà 8 íî ò.å. íàì íóæíî äåëèòü åùå è íà 512 èëè áîëåå â çàâèñèìîñòè îò ðàçìåðîâ êëàñòåðà
movzx ebx,word [fat12_buffer.BPB_BytsPerSec] ;ðàçìåð ñåêòîðà
cdq
idiv ebx ;ðàçäåëèì íà ðàçìåð êëàñòåðà
;ñåé÷àñ ó íàñ â eax çíà÷åíèå åãî íóæíî îêðóãëèòü â áîëüøóþ ñòîðîíó êðàòíîìó 512 áàéòàì
;ïðèìåíèì ñëåäóþùåå î÷èñòèì and è äîáàâèì 512 áàéò. òàêèì îáðàçîì âûðàâíèì íà 512 áàéò
;íî ò.ê. âñå ðàâíî äåëèòü íèæíèé êîä íàì íå íóæåí
; and eax,0xfff200
; add eax,0x200 ;äîáàâèì 512 áàéò äëÿ 1.44 äèñêåòû èäåàëüíî ïîäõîäèò ))
 
inc ax
;ïî èäåå äîëæíî íà êàæäóþ ôàò òàáëèöó
;ðåçåðâèðîâàòüñÿ 9 ñåêòîðîâ ò.å. ïîëó÷àåòñÿ 2*9=18+1 =19 ñåêòîðîâ ò.å. ðóò äèð íàõîäèòüñÿ íà ñ 20 ñåòîðà ò.å. ñ àäðåñà 0õ2600
;ñåé÷àñ íóæíî âû÷èñëèòü ñêîëüêî áóäåò ñåêòîðîâ çàíèìàòü ôàò ) íóæíî ðàçäåëèòü íà 512
;FATSz = ñåé÷àñ ÷àñòíîå â eax
mov word [fat12_buffer.BPB_FATSz16],ax
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_firstDataSector ;ïîëó÷èòü ñìåùåíèå äî äàííûõ
;ñîçäàäèì ïåâóþ çàïèñü â ôàò ïî îïðåäåëåííîìó àäðåñó.
first_create_fat_table
;çàêèíèì BPB ôàéëîâîé ñèñòåìû çà 1 ìá.
use_BPB_RAM
;
;êîïèðîâàíèå ôàéëà.
use_RamdiskFile
 
;;;; âû÷èñëÿåì óêàçàòåëü íà êîðíåâóþ äèð FirstRootDirSecNum = BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz16);
; movzx ebx, [fat12_buffer.BPB_NumFATs]
; movzx eax,ax
; imul eax,ebx
;eax=(BPB_NumFATs * BPB_FATSz16)
; inc eax
; BPB_ResvdSecCnt çíà÷åíèå òîëüêî 1 äëÿ fat12/16
;â eax óêàçàòåëü íà root dir. äëÿ äèñêåòû fat12 äîëæíî ïîëó÷èòüñÿ ïðè êîë-âî êîïèé fat 1 = 1+ (1*1) =2 èëè 3
 
if DEBUG
pusha
; mov ax,point_default
; mov ax,cx
mov cx,0x0a
mov di,show_db1
; mov dword[ds:di],' '
; mov word [ds:di+4],' '
call decode
;Show size
mov si,show_db1
call printplain
;
; xor ax,ax
; int 0x16
popa
end if
 
 
 
 
 
 
 
}
 
macro use_RamdiskSector
{
;äëÿ íåêîòîðûõ FS áóäåò èãíîðèðîâàòüñÿ
mov di,point_default ;restore value
mov cx,save_cx_d
 
.start_RamdiskSector:
call get_firs_sym ;get first symbol on new line
test cx,cx
jz .end_RamdiskSector ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà )
 
cmp al,'R'
jnz .start_RamdiskSector
;ïðîâåðêà íà çíà÷åíèÿ RamdiskSize
; parse_RamdiskSize
 
mov bx,cx
mov ax,di
 
mov si,parse_RamdiskSector
mov cx,parse_RamdiskSector_e - parse_RamdiskSector
repe cmpsb
jnz .RamdiskSector_rest_val ;is not compare
 
sub bx,parse_RamdiskSector_e - parse_RamdiskSector ;correct cx
add bx,cx
mov cx,bx
 
test status_flag,flag_found_RamdiskSector ;îöåíêà ôëàãîâ
jz .correct_is_not_set_RamdiskSector
 
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì
; call printplain
; jmp .get_next_str
 
.correct_is_not_set_RamdiskSector:
mov ax,0x3d20 ;cut al=' ' ah='='
repe scasb
jcxz .end_get_RamS_ERROR_1 ;not found param
cmp ah,byte [es:di-1] ;find '='
jnz .start_RamdiskSector ; ïåðåéäåì íà íà÷àëî è ïîïðîáóåì íàéòè åùå ñåêöèþ
repe scasb ;cut ' '
inc cx
dec di
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
xor bx,bx
mov cx,4
@@: movzx ax,byte [es:di]
cmp al,'0'
jb .end_RamdiskSector
cmp al,'9'
ja .end_RamdiskSector
;;;;;;;;;;;;;;;;;;;
 
imul bx,10
xor al,0x30
add bx,ax
 
inc di
 
loop @b
jmp .end_RamdiskSector
 
 
.RamdiskSector_rest_val:
mov cx,bx
mov di,ax
jmp .start_RamdiskSector
.end_get_RamS_ERROR_1:
 
.end_RamdiskSector:
mov ax,bx
 
if DEBUG
pusha
movzx eax,bx;save_cx_d;point_default
mov cx,0x0a
mov di,RamdiskSector_msg
mov dword[ds:di],' '
mov dword [ds:di+4],' '
call decode
;Show size
mov si,RamdiskSector_msg
call printplain
 
popa
end if
 
; pop di
; pop es
}
 
macro use_RamdiskCluster
{
;äëÿ íåêîòîðûõ FS áóäåò èãíîðèðîâàòüñÿ
; push es
; push di
mov di,point_default ;restore value
mov cx,save_cx_d
; push ini_data_
; pop es
.start_RamdiskCluster:
call get_firs_sym ;get first symbol on new line
test cx,cx
jz .end_RamdiskCluster ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà )
cmp al,'R'
jnz .start_RamdiskCluster
;ïðîâåðêà íà çíà÷åíèÿ RamdiskSize
; parse_RamdiskSize
 
mov bx,cx
mov ax,di
 
mov si,parse_RamdiskCluster
mov cx,parse_RamdiskCluster_e - parse_RamdiskCluster
repe cmpsb
jnz .RamdiskCluster_rest_val ;is not compare
 
sub bx,parse_RamdiskCluster_e - parse_RamdiskCluster ;correct cx
add bx,cx
mov cx,bx
 
test status_flag,flag_found_RamdiskCluster ;îöåíêà ôëàãîâ
jz .correct_is_not_set_RamdiskCluster
 
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì
; call printplain
; jmp .get_next_str
 
.correct_is_not_set_RamdiskCluster:
mov ax,0x3d20 ;cut al=' ' ah='='
repe scasb
jcxz .end_get_RamSC_ERROR_1 ;not found param
cmp ah,byte [es:di-1] ;find '='
jnz .start_RamdiskCluster ; ïåðåéäåì íà íà÷àëî è ïîïðîáóåì íàéòè åùå ñåêöèþ
repe scasb ;cut ' '
inc cx
dec di
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@: movzx ax,byte [es:di]
cmp al,'0'
jb .end_RamdiskCluster
cmp al,'9'
ja .end_RamdiskCluster
;;;;;;;;;;;;;;;;;;;
xor al,0x30
 
jmp .end_RamdiskCluster
 
 
.RamdiskCluster_rest_val:
mov cx,bx
mov di,ax
jmp .start_RamdiskCluster
.end_get_RamSC_ERROR_1:
 
.end_RamdiskCluster:
if DEBUG
pusha
mov cx,0x0a
mov di,RamdiskCluster_msg
; mov word[ds:di],' '
call decode
;Show size
mov si,RamdiskCluster_msg
call printplain
 
popa
end if
 
}
 
macro use_Loader_Image
;ïðåäíàçíà÷åí äëÿ çàãðóçêè îáðàçîâ âûøå 1 Ìá.
;ïåðâîíà÷àëüíàÿ âåðñèÿ çàãðóæàåò îáðàç äèñêåòû 1.44 ìá
{
local .start_p_LI
local .exit
local .error_LI
local .rest_value_loop
local .found_end_str
mov di,point_default ;restore value
mov cx,save_cx_d
;îáðàáîòêà êîíñòðóêöèè òèïà LoaderModule=kord/kolibri.ldm
.start_p_LI:
call get_firs_sym ;get first symbol on new line
test cx,cx
jz .exit ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà )
cmp al,'L'
jnz .start_p_LI
;ïðîâåðêà íà çíà÷åíèå LoaderModule
; parse_LoaderModule
mov bx,cx
mov ax,di
 
mov si,parse_LoaderImage
mov cx,parse_LoaderImage_e - parse_LoaderImage
repe cmpsb
jnz .rest_value_loop ;is not compare
 
sub bx,parse_LoaderImage_e - parse_LoaderImage ;correct cx
add bx,cx
mov cx,bx
 
; test status_flag,flag_found_LM ;îöåíêà ôëàãîâ
; jz .correct_is_not_set_LI
 
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì
; call printplain
; jmp .get_next_str
 
;.correct_is_not_set_LI:
mov ax,0x3d20 ;cut al=' ' ah='='
repe scasb
jcxz .rest_value_loop_LI ;not found param timeout
cmp ah,byte [es:di-1] ;find '='
jnz .rest_value_loop_LI
repe scasb ;cut ' '
inc cx
dec di
;di óêàçûâàåò íà íà÷àëî áëîêà èíôîðìàöèè, â cx äëèííà äî êîíöà ñåêöèè.
;ïîñëå çàãðóçêè çàíîñèòüñÿ çíà÷åíèå çàíÿòîé ïàìÿòè.
;äëÿ òîãî ÷òî áû çàãðóçèòü ìîäóëü, âîñïîëüçóåìñÿ callback ñåðâèñîì
;îðèãèíàëüíîå ðåøåíèå - ðàçìåñòèì dd ïåðåä ñòðî÷êîé è ïîñëå ñòðî÷êè ðàçìåñòèì byte =0
;ýòî âûãëÿäèò òàê: â ini ôàéëå ñóùåñòâóåò ñòðî÷êà LoaderModule = kord/kernel.loader
;ìû åå ìîäèôèöèðóåì äî òàêîãî ñîñòîÿíèÿ dw,dw,db'kord/kernel.loader',0 êîíå÷íî ñîõðàíèâ òå çíà÷åíèÿ êîòîðûå ìû çàìåíÿåì
;ñîõðàíèëè ïåâûå 2 word
push dword [es:di-6]
lea si,[di-6]
 
push word [es:di-2]
xor ax,ax
mov word [es:di-6],ax ;âíîñèì íóæíûå çíà÷åíèÿ
;info_real_mode_size ðàçìåð è óêàçàòåëü íà îáëàñòü â êîòîðóþ ìîæíî çàãðóçèòüñÿ
mov ax,info_real_mode_size ;0x3000 ;ñëåäóþùèé ñåãìåíò çà äàííûìè
 
 
mov word [es:di-4],ax
mov word [es:di-2],16 ;êîë-âî áëîêîâ ïî 4 êá =64 êá ò.å. áîëüøå íå ñ÷èòàåì
;;;;;; ïîèñê êîíöà ñòðî÷êè
@@: mov al,byte [es:di]
cmp al,' '
jz .found_end_str
cmp al,0xa
jz .found_end_str
cmp al,0xd
jz .found_end_str
inc di
dec cx
jnz @b
;;;not found äîïóñòèì,÷òî ýòî êîíåö ôàéëà è îí íå èìååò ïðèâû÷íîãî çàâåðåøíèÿ ñòðîêè
.found_end_str:
; ÷òåíèå áëîêà ïî 64 êá â ñåãìåíò è çàáðàñûâàíèå åãî âûøå 1 ìá.
push word [es:di]
xor ax,ax
mov word [es:di],ax
; xor ax,ax ; function 1 - read file
mov di,si ;file_data
inc ax
push si
push es
call far dword [loader_callback]
push cs
pop ds
 
pop es
pop si
 
test bx,bx
jnz .error_LM
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; çàáðàñûâàíèå áëîêà â 64 êá âûøå 1 ìá.
mov si,table_15_87
push es
push ds
pop es
mov cx, 256*18
mov ah, 0x87
int 0x15
pop es
pop dx cx
test ah, ah
 
 
 
jmp far dword [es:si]
 
 
 
 
.rest_value_loop:
mov di,ax
mov cx,bx
jmp .start_p_LI
 
.exit:
 
 
 
}
 
 
 
macro name_in_root_fat
;ìàêðîñ, êîòîðûé çàïèñûâàåò èíôîðìàöèþ î çàãðóæåííîì ôàéëå â êîðíåâóþ ôàò òàáëèöó
{
 
}
 
 
 
macro use_RamdiskFile
{
;çàãðóçêà ôàéëîâ ñ èñïîëüçîâàíèå callback ñåðâèñà ïåðâè÷íîãî çàãðóç÷èêà
;èñïîëüçóåòñÿ òîëüêî äëÿ çàãðóçêè íåîáõîäèìûõ è íåáîëüøèõ ôàéëîâ, ò.ê. äîñòàòî÷íî ìåäëåííî ðàáîòàåò
;äëÿ çàãðóçêè èñïîëüçóåò 0õ87 ôóíêöèþ int 0x15 ïðåðûâàíèÿ - çàãðóçêà áëîêîâ äàííûõ äî 64 êá âûøå 1 ìá
local .start_loop
local ._end
local .rest_value_loop
local .error
mov di,point_default ;restore value
mov cx,save_cx_d
mov data_offset,0 ;clean offset
;îáðàáîòêà êîíñòðóêöèè òèïà LoaderModule=kord/kolibri.ldm
.start_loop:
call get_firs_sym ;get first symbol on new line
test cx,cx
jz ._end ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà )
cmp al,'R'
jnz .start_loop
;ïðîâåðêà íà çíà÷åíèå RamdiskFile
mov bx,cx
mov ax,di
 
mov si,parse_RamdiskFile
mov cx,parse_RamdiskFile_e - parse_RamdiskFile
repe cmpsb
jnz .rest_value_loop ;is not compare
 
sub bx,parse_RamdiskFile_e - parse_RamdiskFile ;correct cx
add bx,cx
mov cx,bx
; test status_flag,flag_found_LM ;îöåíêà ôëàãîâ
; jz .correct_is_not_set_LM
 
; mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì
; call printplain
; jmp .get_next_str
 
;.correct_is_not_set_LM:
mov ax,0x3d20 ;cut al=' ' ah='='
repe scasb
test ecx,ecx
jz .rest_value_loop ;not found param timeout
cmp ah,byte [es:di-1] ;find '='
jnz .rest_value_loop
repe scasb ;cut ' '
inc cx
dec di
 
mov save_di_RAMDISK,di
mov save_cx_RAMDISK,cx
;di óêàçûâàåò íà íà÷àëî áëîêà èíôîðìàöèè, â cx äëèííà äî êîíöà ñåêöèè.
;ïîñëå çàãðóçêè çàíîñèòüñÿ çíà÷åíèå çàíÿòîé ïàìÿòè.
;äëÿ òîãî ÷òî áû çàãðóçèòü ìîäóëü, âîñïîëüçóåìñÿ callback ñåðâèñîì
;îðèãèíàëüíîå ðåøåíèå - ðàçìåñòèì dd ïåðåä ñòðî÷êîé è ïîñëå ñòðî÷êè ðàçìåñòèì byte =0
;ýòî âûãëÿäèò òàê: â ini ôàéëå ñóùåñòâóåò ñòðî÷êà RamdiskFile = @menu,@menu
;ìû åå ìîäèôèöèðóåì äî òàêîãî ñîñòîÿíèÿ dw,dw,db'@menu',0 êîíå÷íî ñîõðàíèâ òå çíà÷åíèÿ êîòîðûå ìû çàìåíÿåì
;ñîõðàíèëè ïåâûå 2 word
 
;
@@: mov al,byte [es:di]
cmp al,',' ; ò.å. èùåì ðàçäåëèòåëü
jz .found_end_str
inc di
dec cx
jnz @b
;;;not found äîïóñòèì,÷òî ýòî êîíåö ôàéëà è îí íå èìååò ïðèâû÷íîãî çàâåðøåíèÿ ñòðîêè
.found_end_str:
; mov al,byte [es:di]
; cmp al,' ' ; óáèðàåì ïðîáåëû, åñëè îíè åñòü
; jnz @f
; inc di
; dec cx
; jnz .found_end_str
 
;@@:
mov point_to_dest_file_name,di
inc di
;ïðîâåðêà èíäèâèäóàëüíîñòè èìåíè ôàéëà
check_name_file
;/restore di - point and cx -size section
mov di,save_di_RAMDISK
mov cx,save_cx_RAMDISK
 
test al,al
jnz .start_loop ;åñëè â al çíà÷åíèå íå =0, òî òàêîå èìÿ óæå ñóùåñòâóåò â ñèñòåìå.
 
 
 
push dword [es:di-6]
lea si,[di-6]
 
push word [es:di-2]
push di
xor ax,ax
mov word [es:di-6],ax ;âíîñèì íóæíûå çíà÷åíèÿ
;info_real_mode_size ðàçìåð è óêàçàòåëü íà îáëàñòü â êîòîðóþ ìîæíî çàãðóçèòüñÿ
mov ax,info_real_mode_size ;0x3000 ;ñëåäóþùèé ñåãìåíò çà äàííûìè
 
 
mov word [es:di-4],ax
mov word [es:di-2],16 ;êîë-âî áëîêîâ ïî 4 êá =64 êá ò.å. áîëüøå íå ÷èòàåì
 
mov di,point_to_dest_file_name
 
if DEBUG
pushad
; mov ax,di
mov cx,0x0a
mov di,name_of_seg_get_64
mov dword[ds:di],' '
mov word[ds:di+4],' '
call decode
;Show size
mov si,name_of_seg_get_64
call printplain
 
popad
end if
 
push word [es:di]
push cx
xor ax,ax
mov word [es:di],ax
; xor ax,ax ; function 1 - read file
push di
mov di,si ;file_data
inc ax
push si
push es
push bp
 
push es
pop ds
push cs
pop es
 
call far dword [es:loader_callback]
 
 
push cs
pop ds
 
pop bp
pop es
pop si
 
cmp bx,2
ja .error
; ñåé÷àñ ó íàñ â dx:ax ðàçìåð ôàéëà, êîòîðûé ìû çàãðóçèëè.
; âîçìîæíà ñèòóàöèÿ, êîãäà â bx=1 ò.å. åñòü åùå äàííûå íà äèñêå
mov status_flag_loader_f,bx
 
shl edx,16
mov dx,ax
; shr edx,10 ;ðàçìåð ôàéëà â êá.
;;â edx ðàçìåð â áàéòàõ.
mov save_file_size,edx
mov eax,edx
;âîññòàíîâèì ïîëíîñòüþ ôàéë ñöåíàðèÿ
pop di
pop cx ;äëèííà îñòàòêà ñ 2-îé ÷àñòüþ èìåíè ò.å. ñ èìåíåì íàçíà÷åíèåì.
pop word [es:di]
pop di
pop word [es:di-2]
pop dword [es:di-6]
 
if DEBUG
pushad
mov cx,0x0a
mov di,RamdiskFile_msg
mov dword[ds:di],' '
call decode
;Show size
mov si,RamdiskFile_msg
call printplain
 
popad
end if
 
 
 
 
 
 
 
 
 
 
; çàãðóçèì ÷åìó ó íàñ ðàâåí êëàñòåð
; mov ax,word [fat12_buffer.BPB_BytsPerSec] ;êîë-âî áàéòîâ â ñåêòîðå ìîæåò áûòü ëþáîå 512 1024 2048 4096 2 áàéòà
; movzx bx,byte [fat12_buffer.BPB_SecPerClus] ;êîë-âî ñåêòîðîâ â êëàñòåðå
; imul ax,bx
;ñåé÷àñ â eax ðàçìåð êëàñòåðà (512) áàéò
;â edx äëèíà ôàéëà â áàéòàõ äî 64 êá
;çàêèíèì ôàéë çà 1 ìá
;1 íàì íóæíî ñîñòàâèòü ôàò òàáëèöó ò.å. ïðîèçâåñòè ðàçìåòêó ðàìäèñêà, çàòåì ïåðåíåñåì ïî àäðåñó ôàéë
 
;çàïèñàòü èíôîðàìàöèþ î ôàéëå â êîðíåâóþ äèðåêòîðèþ
register_file_in_fat
;ïåðåíåñòè çà 1 ìá ñîäåðæèìîå ôàéëà
move_file_up
 
;ïðîâåðèì, çàãðóæåí ëè äî êîíöà ôàéë? ò.å. åñëè ðàçìåð ôàéëà áîëüøå ÷åì 64 êá, òî áóäåò ïîäãðóæàòü îñòàâøèåñÿ áëîêè
cmp status_flag_loader_f,0x1
jnz @f
;íóæíî äîçàãóçèòü äàííûå ôàéëà è ïåðåíåñòè èõ çà 1-ûé ìá ñîãëàñíî ôàò ñòðóêòóðå
 
 
 
 
 
 
 
 
 
@@:
;òóò îðãàíèçîâàí öèêë ïî çàãðóçêå ôàéëîâ â êîðíåâóþ äèðåêòîðèþ
mov di,save_di_RAMDISK
mov cx,save_cx_RAMDISK
if DEBUG
pusha
xor ax,ax
int 0x16
popa
end if
 
 
jmp .start_loop
 
 
.error:
;call error.LoaderModule
;fixme!
.rest_value_loop:
mov di,ax
mov cx,bx
jmp .start_loop
 
._end:
;ïåðåíåñåì çà 1-ûé ìá ôàò è ðóò äèð
move_up_fat_and_root_d
 
 
 
 
 
 
;çàãðóçêà áëîêà
; mov ah,0x87
; mov cx, ;size in byte
 
;es:si point to descripts
 
 
}
 
macro use_BPB_RAM ;çàêèíóòü ñàìûå ïåðâûå 512 áàéò çà 1-é ìá
;äàííûé ìàêðîñ çàêèäûâàåò BPB ñòðóêòóðó ò.å. ïåðâûå 512 áàéò, ïîêà òîëüêî ôàò12 çà 1 ìá
{
mov ax,fat12_buffer
mov si,table_15_87
add word [si+8*2+2],ax
push es
push ds
pop es
mov cx,256 ;áóò ñåêòîð óêëàäûâàåòñÿ â 512 áàéò 512/2=256
mov ah, 0x87
int 0x15
pop es
;add 512 byte for destination adress
; add dword [si+8*3+2], 512
; test ah, ah
; jz
if DEBUG
pusha
mov ax,word [si+8*2+2]
mov cx,0x0a
mov di,BPB_msg
call decode
;Show size
mov si,BPB_msg
call printplain
popa
end if
}
macro first_create_fat_table
;äàííûé ìàêðîñ ñîçäàåò îôîðìëÿåò 3 ïåðâûõ áàéòà fat òàáëèöû, è óñòàíàâëèâàåò óêàçàòåëü íà ñëåäóþùèé áëîê, è âíîñèò 0 çíà÷åíèå
;äëÿ ñìåùåíèÿ â êîðíåâîé òàáëèöå.
{
mov al,byte [fat12_buffer.BPB_Media]
 
 
push ds
 
 
mov di,info_real_mode_size
add di,0x1000
 
if DEBUG
pushad
 
mov ax,info_real_mode_size
add ax,0x1000
; mov ax,ds
mov cx,0xa
mov di,first_entry_in_fat
mov dword [di],' '
mov word [di+4],' '
call decode
;Show size
mov si,first_entry_in_fat
call printplain
 
xor ax,ax
int 0x16
popad
end if
 
 
push di ; push word info_real_mode_size+0x1000 ;cëåäóþùèé ñåãìåíò çà çàãðóæåííûì ó÷àñòêîì
xor di,di
mov point_to_free_root,di ;çíà÷åíèå ñìåùåíèÿ =0 â êîðíåâîé ôàò òàáëèöå îïèñàíèÿ
 
pop ds ; çàãðóæåí ñëåäóþùèé ñåãìåíò ò.å. ïóñòîé ñåãìåíò
 
mov byte [di],al
or ax,-1
inc di
mov word [di],ax
 
pop ds
mov point_next_fat_str,3
 
if DEBUG
pushad
mov ax,point_next_fat_str
mov cx,0x0a
mov di,fat_create_msg
call decode
;Show size
mov si,fat_create_msg
call printplain
popad
end if
 
}
macro register_file_in_fat
;ìàêðîñ ðåãèñòðàöèè ôàéëà â ôàéëîâîé ñòðóêòóðå Fat
;ïîêà ïîääåðæèâàåòñÿ òîëüêî ôàò12, ïîêà ))
;âû÷èñëåíèå ñìåæíûõ êëàñòåðîâ è çàíåñåíèå èíôû â fat/
{
local .step2
local .step3
local .end
local .eof_file
 
;di point on root dir íà ôðè ñåêöèþ.
push es
 
mov ax,info_real_mode_size
add ax,0x1000
mov es,ax ; push word info_real_mode_size+0x1000 ;ñåãìåíò ñëåäóþùèé çà çàãðóæåííûì áëîêîì â 64 êá
 
; îïðåäåëÿåì òèï ôàò ïîêà íå îïðåäåëÿåì, ïîêà òîëüêî ôàò 12
; 12 áèò, äëÿ âû÷åñëåíèÿ ñîñåäíèõ êàëàñòåðîâ.
mov di,firstDataSect ;â ñåêòîðàõ
sub di,size_root_dir
;òåïåðü â ax ðàçìåð â ñåêòîðàõ íà÷àëà ðóò äèð
shl di,9 ;imul 512
add di,point_to_free_root ;ñìåùåíèå â óæå çàïèñàííûõ 32-õ ñòðóêòóðàõ.
;íåîáõîäèìî âíåñòè çíà÷åíèå â ðóò äèð ò.å. 32 áàéòà
if DEBUG
pushad
; mov ax,point_default
; mov ax,
mov cx,0x0a
mov di,show_db2
mov dword[ds:di],' '
mov word [ds:di+4],' '
call decode
;Show size
mov si,show_db2
call printplain
;
; xor ax,ax
; int 0x16
popad
end if
 
 
 
;gs:di - óêàçàòåëü äëÿ âíåñåíèÿ èíôîðàöèè â ðóò îáëàñòü ôàò òàáëèöû èíîðìàöèè î ôàéëå.
mov si,shot_name_fat
mov cx,11
;çàïèøåì â ñòðóêòóðó èìÿ
@@: lodsb
stosb
loop @b
 
;çàïèøåì àòðèáóòû ôàéëà è DIR_NTRes - çàðåçåâðèðîâàííûé áàéò =0
xor ax,ax
mov ah,ATTR_VOLUME_ID
mov word [es:di],ax
add di,2
;DIR_CrtTimeTenth
mov byte [es:di],100
inc di
;DIR_CrtTime
mov word [es:di],0x032b ;äàòà
add di,2
;DIR_CrtDate
mov word [es:di],0x0 ;âðåìÿ ><
add di,2
;DIR_LstAccDate
mov word [es:di],0x032b ;äàòà ìîåãî
add di,2
;DIR_FstClusHI
mov word [es:di],0x0 ;âðåìÿ äëÿ ôàò12 /16 âñåãäà 0
add di,2
;DIR_WrtTime
mov word [es:di],0x0 ;âðåìÿ ><
add di,2
;DIR_WrtDate
mov word [es:di],0x032b
add di,2
mov ax,point_next_fat_str
mov word [es:di],ax
add di,2
 
push di
;DIR_FstClusLO Ìëàäøåå ñëîâî íîìåðà ïåðâîãî êëàñòåðà.
; mov ax,point_next_fat_str ;çàãðóçèì óêàçàòåëü íà ýëåìåíò ôàò òàáëèöû ò.å. ýòî íîìåð ôàò çàïèñè
;FATOffset = N + (N / 2) ò.å. ýòî óæå ó íàñ ñìåùåíèå ìû çíàåì ÷òî -íà÷èíàåòñÿ âñå ñ 3-ãî ýëåìåíòà çàïèñè ôàò
mov bx,ax
shr bx,1
add ax,bx
;â àõ ñåé÷àñ FATOffset
;ThisFATEntOffset = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);
mov bx, word [fat12_buffer.BPB_BytsPerSec]
cwd
idiv bx
;ax=ThisFATEntOffset= rem (FATOffset / BPB_BytsPerSec) ÷åòíûé èëè íå÷åòíûé óêàçàòåëü.
mov si,ax
;íàì íóæíî â öèêëå çàïèñàòü âñå êëàñòåðû êîòîðûå áóäóò èñïîëüçîâàíû äëÿ ðàçìåùåíèÿ ôàéëà.
;óçíàåì ðàçìåð êëàñòåðà.
movzx eax,word [fat12_buffer.BPB_BytsPerSec]
movzx ebx,byte [fat12_buffer.BPB_SecPerClus]
imul eax,ebx
;ax - ðàçìåð êëàñòåðà.
;ñåé÷àñ áóäåì çàïèñûâàòü âî âðåìåííûé áóôåð ôàò òàáëèöó äëÿ âûáðàííîãî ôàéëà. Ïîñêîëüêó ìû åãî çàãðóçèëè âîçìîæíî íå ïîëíîñòüþ
;ìû îáðàáîòàåì çàïèñü äëÿ ôàò ïîëíîñòüþ, â íå çàâèñèìîñòè îò ïðåäåëà áóôåðà ãäå âîçìîæíà ÷àñòü ôàéëà.
mov ebx,save_file_size ;ðàçìåð ôàéëà â áàéòàõ
@@: sub ebx,eax
cmp ebx,eax
jbe .eof_file
 
inc point_next_fat_str
mov cx,point_next_fat_str ;çàãðóçèì óêàçàòåëü íà ýëåìåíò ôàò òàáëèöû ò.å. ýòî íîìåð ôàò çàïèñè
;FATOffset = N + (N / 2) ò.å. ýòî óæå ó íàñ ñìåùåíèå ìû çíàåì ÷òî -íà÷èíàåòñÿ âñå ñ 3-ãî ýëåìåíòà çàïèñè ôàò
mov dx,ax
shr dx,1
add cx,dx
 
 
 
test si,0x1
jz .step2
shl cx,4
mov word[es:si],cx
inc si
add cx,ax
jmp @b
 
.step2: and cx,0x0FFF
mov word[es:si],cx
inc si
add cx,ax
jmp @b
 
.eof_file:
mov cx,0x0fff
test si,0x1
jz .step3
shl cx,4
mov word[es:si],cx
jmp .end
 
.step3: and cx,0x0FFF
mov word[es:si],cx
 
.end: inc point_next_fat_str
 
pop di
;DIR_FileSize 32-áèòíûé DWORD ñîäåðæèò ðàçìåð ôàéëà â áàéòàõ.
mov eax,save_file_size
mov dword [es:di],eax
 
if DEBUG
pushad
 
mov di,firstDataSect ;â ñåêòîðàõ
sub di,size_root_dir
;òåïåðü â ax ðàçìåð â ñåêòîðàõ íà÷àëà ðóò äèð
shl di,9 ;imul 512
add di,point_to_free_root ;ñìåùåíèå â óæå çàïèñàííûõ 32-õ ñòðóêòóðàõ.
 
push di
 
mov si,dest_name_fat
mov cx,11
 
;çàïèøåì â ñòðóêòóðó èìÿ
@@: mov al,byte [es:di]
inc di
mov byte [ds:si],al
inc si
loop @b
mov di,si
inc di
pop ax
mov cx,0xa
call decode
 
mov si,dest_name_fat
call printplain
popad
 
END IF
 
 
 
 
 
add point_to_free_root,32 ;óâåëèöèì ñìåùåíèå äî ñëåäóþùåãî çíà÷åíèÿ.
pop es
 
}
 
 
 
 
 
macro get_firstDataSector
;ìàêðîñ äëÿ âû÷èñëåíèÿ ïåâîãî ñåêòîðà äàííûõ ò.å. äàííûõ ôàéëîâ â ôàòå
;âû÷èñëèì FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors;
{
mov ax,word [fat12_buffer.BPB_FATSz16]
movzx bx,byte [fat12_buffer.BPB_NumFATs]
imul ax,bx ;9x1=9
;ax=BPB_NumFATs * FATSz
mov bx,word [fat12_buffer.BPB_RootEntCnt] ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb)
shr bx,4 ;imul bx,32 and then div 512 -> in bx size in sectors
add ax,bx ;9+14=23
mov size_root_dir,bx
movzx bx,byte [fat12_buffer.BPB_RsvdSecCnt] ;add 1 for fat 16/12
add ax,bx
;ax=firstDataSector - ãäå íà÷èíàåòñÿ ïåðâûé ñåêòîðî îò 0 ñåêòîðà â ñåêòîðàõ. - ôàêòè÷åñêè = 24 ñåêòîð
mov firstDataSect,ax ;ñîõðàíèì äëÿ âû÷èñëåíèÿ
; ïîëó÷èìçíà÷åíèå êëàñòåðîâ, ýòî îáúåì â êîòîðûé ìû ìîæåì çàïèñàòü äàííûå
mov bx,word [fat12_buffer.BPB_TotSec16]
sub bx,ax
mov ax,bx
movzx bx,byte [fat12_buffer.BPB_SecPerClus]
cwd
idiv bx
mov DataClasters,ax
 
if DEBUG
pushad
mov ax,firstDataSect ;ïåðâûé ñåêòîð äàííûõ
mov cx,0x0a
mov di,firstDataSect_msg
call decode
;Show size
mov si,firstDataSect_msg
call printplain
;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,size_root_dir ;ðàçìåð ðóò äèð â ñåòîêòîðàõ
mov cx,0x0a
mov di,size_root_dir_msg
call decode
;Show size
mov si,size_root_dir_msg
call printplain
;;;;;;;;;;;;;;;;;;;;;;;;;;
mov ax,DataClasters ;êëàñòåðû
mov cx,0x0a
mov di,DataClasters_msg
call decode
;Show size
mov si,DataClasters_msg
call printplain
popad
 
end if
 
}
 
macro use_RamdiskPATHS
;ïàðñèíã ïóòè èñòî÷íèêà ôàéëîâ.
{
 
}
 
macro use_RamdiskPATHD
;ïàðñèíã ïóòè íàçíà÷åíèÿ ôàéëîâ.
{
 
}
macro check_name_file
;ìàêðîñ ïðîâåðêè èìåíè íà ïîâòîð, èìÿ äîëæíî áûòü óíèêàëüíûì.
;âõîäíûå äàííûå: es- ñåãìåíò ãäå ëåæèò ôàéë äëÿ ïàðñèíãà ò.å. startos.ini
;di - óêàçàòåëü íà èìÿ ôàéëà ò.å. es:di óêàçûâàåò íà èìÿ ôàéëà íàçíà÷åíèÿ
;âûõîäíûå äàííûå eax =-1 èìÿ ñîâïàëî, eax=0 èìÿ íå ñîâïàëî.
{
local .no_equal
local .exit
local .loop_size_root_dir
;âû÷èñëèì äëèííó ñòðî÷êè èìåíè íàçíà÷åíèÿ, êîòîðóþ áóäåì ñðàâíèâàòü ñ óæå çàïèñàííûìè äàííûìè.
;ïðåîáðàçóåì â àíàëîã ôàò çàïèñè ñòî÷êó ñ èìåíåì íàçíà÷åíèÿ
convertion_file_name ; ïðåîáðàçîâàëè èìÿ ïî íóæíûì ïðàâèëàì
test ax,ax
jnz .exit
 
lea si,[shot_name_fat] ; desination name of file
 
;âû÷èñëèì óêàçàòåëü íà êîðíåâóþ äèðåêòîðèþ
mov di,firstDataSect
sub di,size_root_dir
;òåïåðü â ax ðàçìåð â ñåêòîðàõ íà÷àëà ðóò äèð
shl di,9 ;imul 512
;di= Ýòî ñìåùåíèå îò íà÷àëà áóôåðà äî ðóò äèðåêòîðèè. â ïðåäåëàõ 64 êá.
;çàãðóçèì çíà÷åíèå - ò.å. êîë-âî ýëåìåíòîâ, êîòîðûå ìû ìîæåì ïðîñìàòðèâàòü.
mov dx,root_dir_entry_count
mov ax,info_real_mode_size
add ax,0x1000
 
 
mov gs,ax
.loop_size_root_dir:
DEBUG1 equ 0
if DEBUG1
pushad
push di
mov eax,dword[gs:di]
lea si,[check_root_fat_+14]
mov dword [ds:si],'----'
mov dword [ds:si+4],'----'
mov dword [ds:si+8],'----'
mov dword[ds:si],eax
mov eax,dword[gs:di+4]
mov dword[ds:si+4],eax
mov eax,dword[gs:di+8]
mov dword[ds:si+8],eax
 
;
xor eax,eax
mov ax,gs;point_next_fat_str
mov cx,0x0a
mov di,check_root_fat_
mov dword [di],' '
mov word [di+4],' '
call decode
xor eax,eax
pop ax
mov di,(check_root_fat_+7)
mov dword [di],' '
mov word [di+4],' '
call decode
 
;Show size
lea si,[check_root_fat_]
call printplain
 
lea si,[shot_name_fat]
call printplain
 
xor ax,ax
int 0x16
popad
end if
 
xor bx,bx
mov cx,11 ;size of name in struct FAT
 
@@:
mov al,byte [ds:si+bx] ;ds:si - point to name of convertion variable.
mov ah,byte [gs:di+bx] ;gs:di - point to name in fat struct
inc bx
 
if DEBUG
; pushad
; lea si,[check_root_fat_+14]
; mov dword [ds:si],'----'
; mov word [ds:si],ax
; call printplain
 
; xor ax,ax
; int 0x16
 
; popad
end if
 
 
 
cmp ah,al
jnz .no_equal
 
; dec cx
; jnz @b
loop @b
 
;.succesfuly:
;ïå÷àëüíî, òàêîå èìÿ óæå èìååòñÿ :(
or ax,-1
jmp .exit
 
 
.no_equal:
add di,32 ;fat struct =32 byte
dec dx
jnz .loop_size_root_dir
 
;.exit_check_name:
and ax,0
 
.exit:
 
if DEBUG
pushad
;Show size
lea si,[check_name_fat_msg_n]
test ax,ax
jz @f
lea si,[check_name_fat_msg_y]
call printplain
lea si,[alarm_msg]
@@: call printplain
popad
end if
 
}
 
 
macro convertion_file_name
;ìàêðîñ êîíâåðòàöèè èìåíè, ýòî íóæíî ïîñêîëüêó ôîðìàò ïðåäñòàâëåííûé íå ñîîòâåòñâóåò ôàò è íàïðÿìóþ ðåäêî ìîæíî êîãäà èñïîëüçîâàòü
;ïðåîáðàçîâàíèå èìåíè òèïà hello.asm â 'HELLO ASM', â ñîîòâåòñòâèè ñ ïðàâèëàìè fat.
;âõîäíûå ïàðàìåòðû es:di óêàçàòåëü íà èìÿ ôàéëà êîòîðîå íóæíî ïðåîáðàçîâàòü, êîíå÷íûé áóôåð shot_name_fat
{
local .next_step
local .error
local .st1
local .st2
local .st2_l
local .st3
local .st4_s
local .st4
local .st5
 
;âû÷èñëèì äëèííó ñòðî÷êè èìåíè íàçíà÷åíèÿ, êîòîðóþ áóäåì ñðàâíèâàòü ñ óæå çàïèñàííûìè äàííûìè.
; mov di,point_to_dest_file_name âõîäíîé ïàðàìåòð
mov si,shot_name_fat
or first_input,-1 ;ïðè ïåðâîì âõîäå óñòàíàâëèâàåì ôëàã
mov cx,11 ;äëèííà èìåíè â ñòóêòóðå ôàò òàáëèöû
 
@@:
mov al,byte [es:di]
cmp al,0xa
jz .st4_s
cmp al,0xd
jz .st4_s
cmp al,0x20
jz .st4_s
 
cmp al,0x20
jb .error
cmp al,0x22
jz .error
cmp al,0x2a
jz .error
cmp al,0x2b
jz .error
cmp al,0x2c
jz .error
cmp al,0x2F
jz .error
 
cmp al,0x3a
jz .error
cmp al,0x3b
jz .error
cmp al,0x3c
jz .error
cmp al,0x3d
jz .error
cmp al,0x3E
jz .error
cmp al,0x3F
jz .error
 
cmp al,0x5b
jz .error
cmp al,0x5c
jz .error
cmp al,0x5d
jz .error
 
cmp al,0x7c
jz .error
 
cmp first_input,-1
jnz .next_step
and first_input,0 ;ñáîðîñèì ôëàã.
cmp al,'.'
jz .error ;îáðàáîòêà òî÷êè, ôàéë íå ìîæåò íà÷èíàòüñÿ ñ òî÷êè
 
.next_step:
cmp al,0x2e
jnz .st2 ;îáðàáîòêà òî÷êè, â ñåðåäèíå ôàéëà
;òóò ó íàñ óñòàíîâëåí ðàçäåëèòåëü
;âñå îñòàëüíåî ìåñòî çàéìóò ïðîáåëû
mov al,' '
 
;!fixme îáðàáîòàíû íå âñå èñêëþ÷åíèÿ :(
cmp cl,3 ;ôîðìàò ôàéëà òàêîé GIDGIDIIASM ò.å. gidgidii.asm
jbe .st2
 
 
.st3:
mov byte [si],al
inc si
dec cx
cmp cx,3
ja .st3
; inc cx
inc di
jmp @b
 
.st2:
cmp al,0x60
jbe .st2_l
xor al,0x20 ;ñäåëàåì çàãëàâíûå áóêâû
.st2_l: mov byte [si],al
inc di
inc si
; dec cx
; jnz @b
loop @b
.st5: xor ax,ax
jmp @f
 
;;;;;;;;ôàéë çàêîí÷èëñÿ, è íóæíî âíåñòè â êîíåö ïðîáåëû
.st4_s: mov al,' '
.st4: mov byte [si],al
inc si
loop .st4
jmp .st5
 
.error: or ax,-1
@@:
 
if DEBUG
pushad
mov si,convertion_file_name_msg_y
test ax,ax
jz @f
mov si,convertion_file_name_msg_n
@@: call printplain
 
mov si,shot_name_fat
mov byte [si+12],0
call printplain
popad
 
end if
}
 
macro move_file_up
;ìàêðîñ êîòîðûé ïåðåìåùàåò çà 1 ìá ñ ïðàâèëàìè ôàò äàííûå ôàéëà.
{
local .st1
local .correct_on_byte
;ñåé÷àñ èìååò áûòü ñèòóàöèÿ, êîãäà BPB óæå ïåðåìåùåí çà 1 ìá, ôàò, è ðóò äèð áóäóò ïîçæå ïåðåìåùåíû,
;à íàì íóæíî âû÷èñëèòü ìåñòî, è ïåðåíåñòè òóäà ñîäåðæèìîå ôàéëà
;ïîëó÷åíîå çíà÷åíèå óêàçûâàåò â áàéòàõ íà íà÷àëî äàííûõ
 
mov ax,info_real_mode_size ; ñåãìåíò ãäå ðàñïîëîæåíû äàííûå
mov si,table_15_87
mov word [si+8*2+2],ax
;ñìåùåíèå äî äàííûõ óæå çà 1-ì ìá
movzx eax,firstDataSect
movzx edx,data_offset
add eax,edx
 
movzx ebx,word [fat12_buffer.BPB_BytsPerSec]
movzx edx,byte [fat12_buffer.BPB_SecPerClus]
imul bx,dx ;ïîëó÷èì ðàçìåð êëàñòåðà
 
 
 
push ebx ;save bx
 
imul eax,ebx
; shl eax,9 ;óìíîæèì íà 512
if DEBUG
pushad
xor eax,eax
mov ax,info_real_mode_size
mov cx,0x0a
mov di,seg_where_get_data
mov dword [di],' '
mov word [di+4],' '
call decode
;Show size
mov si,seg_where_get_data
call printplain
popad
 
end if
 
; mov bx,word [fat12_buffer.BPB_BytsPerSec]
; movzx dx,byte [fat12_buffer.BPB_SecPerClus]
; imul bx,dx
; cwd
; idiv bx
 
mov dl,0x10
 
@@: cmp eax,0x00010000
jb @f
 
sub eax,0x00010000
inc dl
jmp @b
 
 
@@: mov byte [si+8*3+3],dl ;êóäà ïèñàòü
mov word [si+8*3+2],ax
 
mov ecx,save_file_size ;ðàçìåð ôàéëà â áàéòàõ.
cmp ecx,0x0000ffff ;ðàçìåð áëîêà ò.å. 64 êá
jbe .correct_on_byte ;êîððåêòèðîâêà íà áàéò çíà÷åíèÿ
 
 
 
mov ecx,0x00010000 ;65536
sub save_file_size,ecx ;îòíèìèì
; jmp .st1 ;ïîëó÷èì 0õ8000
 
 
 
 
;êîððåêòèðîâêà çíà÷åíèÿ äîëæíà áûòü âûïîëåíåíà íà ðàçìåð êëàñòåðà
.correct_on_byte:
;/óçíàåì ðàçìåð êëàñòåðà
pop eax ;restore size of claster
push ecx
@@: inc data_offset
 
cmp eax,ecx
jae @f
sub ecx,eax
jmp @b
@@: pop ecx
 
 
 
 
test ecx,0x1
jz .st1
inc ecx
.st1: shr ecx,1 ; ïðåîáðàçîâàòü çíà÷åíèå äëÿ 0x87 function
 
;ïåðåíåñåì áëîê çà 1 ìá
push es
push ds
pop es
 
mov ah, 0x87
int 0x15
pop es
 
if DEBUG
pusha
; mov ax,point_next_fat_str
mov cx,0x0a
mov di,return_code_af_move
call decode
;Show size
mov si,return_code_af_move
call printplain
popa
 
end if
 
}
 
 
macro move_up_fat_and_root_d
;ìàêðîñ, êîòîðûé ïîçâîëÿåò ïåðåíåñòè âûøå 1 ìá â ñòðóêòóðó îáðàçà ôàò òàáëèöó è ðóò äèðåêòîðèþ
{
local .st1
 
mov ax,info_real_mode_size
add ax,0x1000
 
mov si,table_15_87
mov word [si+8*2+2],ax
;ñìåùåíèå äî äàííûõ
mov ax,512
mov word [si+8*3+2],ax
;fixme! òóò íåîáõîäèìî ñäåëàòü ïîäåðæêó ò.å. ôîðìèðîâàòü ñìåùåíèå ôàéëà â óæå çàïèñàííûõ äàííûõ.
 
movzx ecx,word [fat12_buffer.BPB_FATSz16]
movzx bx,byte [fat12_buffer.BPB_NumFATs]
imul cx,bx ;9x1=9
 
add cx,size_root_dir ;ðàçìåð êîðíåâîé äèððåêòîðèè
shl ecx,9 ;imul 512
 
 
;êîððåêòèðîâêà çíà÷åíèÿ
test ecx,0x1
jz .st1
inc ecx
.st1: shr ecx,1
 
push es
push ds
pop es
 
mov ah, 0x87
int 0x15
pop es
 
if DEBUG
pusha
; mov ax,point_next_fat_str
mov cx,0x0a
mov di,return_code_af_fat_m
call decode
;Show size
mov si,return_code_af_fat_m
call printplain
popa
 
end if
 
}
/kernel/branches/Kolibri-acpi/sec_loader/trunk/sl_proc.inc
0,0 → 1,524
; Copyright (c) 2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
; òóò îïèñûâàþòñÿ ïðîöåäóðû êîòîðûå èñïîëüçóþòñÿ â secondary loader
color_sym_black equ 0
color_sym_blue equ 1
color_sym_green equ 2
color_sym_turquoise equ 3
color_sym_red equ 4
 
color_sym_lightgray equ 7
 
color_sym_lightblue equ 9
color_sym_lettuce equ 10
color_sym_pink equ 12
color_sym_yellow equ 14
color_sym_white equ 15
if DEBUG
decode:
;input eax - ÷èñëî, es:di êóäà ïèñàòü, cx=10
cmp eax,ecx
jb @f
xor edx,edx
div ecx
push edx
call decode
pop eax
@@: or al,0x30
mov [ds:di],al
inc di
ret
 
end if
 
 
putchar:
; in: al=character
mov ah, 0Eh
mov bh, 0
int 10h
ret
 
printplain:
; in: si->string
pushad
lodsb
@@:
call putchar
lodsb
test al,al
jnz @b
mov al,13
call putchar
 
mov al,10
call putchar
popad
ret
getkey:
; get number in range [bl,bh] (bl,bh in ['0'..'9'])
; in: bx=range
; out: ax=digit (1..9, 10 for 0)
mov ah, 0
int 16h
cmp al, bl
jb getkey
cmp al, bh
ja getkey
push ax
call putchar
pop ax
and ax, 0Fh
jnz @f
mov al, 10
@@:
ret
 
;setcursor:
; in: dl=column, dh=row
; mov ah, 2
; mov bh, 0
; int 10h
; ret
 
;macro _setcursor row,column
;{
; mov dx, row*256 + column
; call setcursor
;}
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_firs_sym:
.start:
mov al,byte [es:di]
inc di
dec cx
jcxz .exit
 
cmp al,0xa ;cmp al,0xa
jz ._entry
 
cmp al,';'
jnz .start
 
.first_com:
 
mov al,0xa
repnz scasb
jcxz .exit
._entry:
mov al,byte [es:di]
.first_sp:
cmp al,' '
jnz .not_space
 
; mov al,' ' ;cut ' '
repe scasb
dec di
inc cx
mov al,byte [es:di]
.not_space:
cmp al,';'
jz .first_com
.exit: ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
show_name_section:
push si
push ini_data_
pop es
 
 
mov al,']'
repnz scasb
test cx,cx
jz error.incorect_section_def
.find_val_name_fb1:
mov al,'n'
.find_val_name_fb:
repnz scasb
jcxz .not_name_sec_fb
 
mov si,parse_name
 
push cx
push di
 
mov cx,parse_name_e -parse_name
repe cmpsb
pop di
pop cx
jz .yaaa_find_value
 
 
jmp .find_val_name_fb
 
.yaaa_find_value:
sub cx,parse_name_e -parse_name
add di,parse_name_e -parse_name
 
mov ax,0x3d20 ; ah='='
repe scasb
test cx,cx
jz .not_name_sec_fb
 
cmp ah,byte [es:di-1] ;find '='
jnz .find_val_name_fb1
repe scasb ;cut ' '
inc cx
dec di
 
 
;âñå âûðåçàëè è âñå ãîòîâî äëÿ âûâîäà èìåíè ñåêöèè ))
push es
pop ds
 
.def_sect_name:
push 0xb800
pop es
;clear array for message
xor ax,ax
if DEBUG
mov ax,0x0720
end if
 
mov cx,39
mov si,di
mov di,dx
sub di,2
rep stosw
;//////////////////////
 
 
mov di,dx
mov ah,color_sym_white;color_sym_lightblue
mov cx,36
lodsb
sub di,2
cmp al,'"'
jz @f
cmp al,"'"
jnz .end_sh_name_sec
@@: lodsb
@@:
stosw
lodsb
cmp al,'"'
jz .end_sh_name_sec
cmp al,"'"
jz .end_sh_name_sec
loop @b
mov al,'}'
mov ah,color_sym_yellow
stosw
.end_sh_name_sec:
push cs
pop ds
 
pop si
ret
 
.not_name_sec_fb: ;íåò èìåíè â íàçâàíèè ñåêöèè - çíà÷èò òàê è ñêàæåì îá ýòîì
push cs
pop ds
mov di,default_section_name
jmp .def_sect_name
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;ïðîöåäóðà ïîèñêà ââåðõ ñëåäóþùåé ñåêöèè
;â point_default ñîäåðæèòüñÿ óêàçàòåëü íà äåôàóëò ñåêöèþ, è â ïðåäåëàõ âðåéìà ìû áåãàåì ïî çàðàíåå ïðîïàðñåíûìè çíà÷åíèÿì óêàçàòåëåé
;äëÿ òîãî ÷òî áû îòîáðàçèòü è ïðîïàðñèòü ñëåäóþùèé ôðåéì, íàì íóæíî ïîëó÷èòü çà ïåðäûäóùèé èëè ñëåäóþùèé óêàçàòåëü
find_before_sect:
mov di,point_default
.e:
push ini_data_
pop es
mov cx,di ;ïðåäïîëîæèì áóäåì ïðîñìàòðèâàòü ê íà÷àëó, òåêóùàÿ ïîçèöèÿ di = ñêîëüêî ñèìâîëîâ îò íà÷àëà äîêóìåíòà èìååòñÿ
mov bx,cx ;êîïèÿ
 
;íàñòðîèëè óêàçàòåëü íà äåôàóëò ñåêöèþ
;áóäåì èñêàòü ââåðõ
.find_start_section:
std ;óñòàíîâêà ôëàãà íàïðàâëåíèÿ - áóäåì ïðîñìàòèðâàòü ê íà÷àëó íàøåãî èíè ôàéëà
;áóäåì èñêàòü íà÷àëî ñåêöèè ò.å. '[' ýòîò ñèìâîë
mov al,0xa
repnz scasb ;ïðîñêàíèðóåì íà íàëè÷åå ñèìâîëà íà÷àëà ñåêöèè
jcxz .go_ ;ìû ïðîñìîòðåëè äî íà÷àëà ôàéëà, íî òàê è íè÷åãî íå íàøëè ;(( ïî òèõîìó âûéäåì )
 
mov find_sec_di,di ;ñîõðàíèì äàííûå
mov cx,di ;
 
sub bx,cx
mov cx,bx ;â ñx çíà÷åíèå - êîë-âî ñèìâîëîâ
cld
call get_firs_sym
.ret_go:
jcxz ._not_section ; â äàííîì ñëó÷àå èìååì êîíñòðóêöèþ 0xa ... ; hello [ñåêöèÿ] îáëîìñ èùåì äàëåå
 
cmp di,point_loader ; ñåêöèþ loader ìû íå çàíîñèì èíà÷å êðàõ
jz ._not_section
;âñå óäà÷íî ìû íàøëè âõîæäåíèå ñåêöèè ïðåäûäóùåé
cmp al,'['
jnz ._not_section
mov point_default,di
.exit_scan_sect:
ret
;;;;;;;; âîññòàíîâèì çíà÷åíèÿ è ïðîäîëæèì ïîèñêè íà÷àëà ñåêöèè êîòîðàÿ íàñ óñòðîèò ))
._not_section:
mov di,find_sec_di
mov cx,di
mov bx,cx
jmp .find_start_section
.go_:
cld
mov cx,bx ;â ñx çíà÷åíèå - êîë-âî ñèìâîëîâ
 
mov al,byte [es:di]
push word .f_go
cmp al,' '
jz @f
jmp get_firs_sym.not_space
@@:
jmp get_firs_sym.first_sp
 
.f_go:
jcxz .exit_scan_sect ; â äàííîì ñëó÷àå èìååì êîíñòðóêöèþ 0xa ... ; hello [ñåêöèÿ] îáëîìñ èùåì äàëåå
 
cmp di,point_loader ; ñåêöèþ loader ìû íå çàíîñèì èíà÷å êðàõ
jz .exit_scan_sect
;âñå óäà÷íî ìû íàøëè âõîæäåíèå ñåêöèè ïðåäûäóùåé
cmp al,'['
jnz .exit_scan_sect
mov point_default,di
ret
 
 
 
 
 
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
find_next_sect:
mov di,point_default
push ini_data_
pop es
mov cx,save_cx;di ;ïðåäïîëîæèì áóäåì ïðîñìàòðèâàòü ê êîíöó, òåêóùàÿ ïîçèöèÿ di = ñêîëüêî ñèìâîëîâ îò íà÷àëà äîêóìåíòà èìååòñÿ
sub cx,di ;ñåé÷àñ â cx îñòàòîê ò.å. ñêîëüêî ìîæíî êðóòèòü äî êîíöà è íå âûëàçèòü íà íà÷àëî
jmp .let_s_go
.h:
push ini_data_
pop es
mov cx,save_cx;di ;ïðåäïîëîæèì áóäåì ïðîñìàòðèâàòü ê êîíöó, òåêóùàÿ ïîçèöèÿ di = ñêîëüêî ñèìâîëîâ îò íà÷àëà äîêóìåíòà èìååòñÿ
; sub cx,di ;ñåé÷àñ â cx îñòàòîê ò.å. ñêîëüêî ìîæíî êðóòèòü äî êîíöà è íå âûëàçèòü íà íà÷àëî
 
mov al,byte [es:di]
push word .let_s_go_ret
cmp al,' '
jz @f
jmp get_firs_sym.not_space
@@:
jmp get_firs_sym.first_sp
 
 
 
 
;íàñòðîèëè óêàçàòåëü íà äåôàóëò ñåêöèþ
;áóäåì èñêàòü âíèç
.let_s_go:
call get_firs_sym
.let_s_go_ret:
jcxz .exit_scan_sect ; â äàííîì ñëó÷àå èìååì êîíñòðóêöèþ 0xa ... ; hello [ñåêöèÿ] îáëîìñ èùåì äàëåå
cmp al,'['
jnz .let_s_go
cmp di,point_loader
jz .let_s_go
;âñå óäà÷íî ìû íàøëè âõîæäåíèå ñåêöèè ïðåäûäóùåé
mov point_default,di
.exit_scan_sect:
ret
 
;;;;;;;;;;;;;;;;;;;;;;;;;;
;clean old cursor
clean_active_cursor:
;íå èçìåíÿåò çíà÷åíèå ax
;îòîáðàæåíèå êóðñîðà ïî óìîë÷àíèþ
lea si,point_to_hframe
mov di,962-160
mov dx,point_default
mov cx,18
.clean_show_cur:
mov bx,[si]
add di,160
cmp bx,dx
jz .clean_cursor_
sub si,2
loop .clean_show_cur
 
; jmp $
 
.clean_cursor_:
push 0xb800
pop es
push ax
mov point_to_point_def,si
xor ax,ax
if DEBUG
mov ax,0x0720
end if
stosw
add di,68
stosw
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;óñòàíîâêà òàéìåðà è îòîáðàæåíèå ñ÷åò÷èêà âðåìåíè
gettime:
mov ah,0
int 1Ah
xchg ax, cx
shl eax, 10h
xchg ax, dx
ret
newtimer:
push ds
 
push cs
pop ds
 
pushf
call far dword [old_timer]
 
pushad
call gettime
 
sub eax, dword[start_timer]
mov bx, word [value_timeout]
imul bx,18
sub bx, ax
jbe .timergo
 
push es
 
push 0xb800
pop es
mov ax,bx
 
mov bx, 18
xor dx, dx
div bx
 
mov bx,10
mov di,3734
call .decode
 
xor ax,ax
stosw
 
; wait 5/4/3/2 seconds, 1 second
pop es
popad
pop ds
 
iret
.timergo:
push 0
pop es
mov eax,dword [old_timer]
mov [es:8*4], eax
mov dword [timer_],eax
mov sp, word [start_stack]
mov bp,word [save_bp_from_timer]
;;íå âîññòàíîâëåíûé ñòåê :(
sti
jmp parse_start.parse_run_only
 
 
.decode:
;input ax - ÷èñëî, es:di êóäà ïèñàòü, bx=10
cmp ax,bx
jb @f
xor dx,dx
div bx
push dx
call .decode
pop ax
@@: or al,0x30
push ax
mov ah,9
stosw
pop ax
ret
 
show_bl_sc_sect:
;1) îòîáðàæåíèå ñïèñêà ñåêöèé. Åñëè ñåêöèÿ íå èìåò èìÿ - îøèáêà - âûâîä Section unname
;ïðîâåðêà íà íàëè÷åå èìåíè.
;âõîäíûå äàííûå es:di -óêàçàòåëü íà ñåêöèþ - cx ðàçìåð ñåêöèè
; push bp
mov bx,point_to_eframe
lea si,point_to_hframe
mov dx,966
 
.home_show_fb:
cmp si,bx
jb ._show_space_fb
mov di,[si]
sub si,2
mov cx,[si]
sub cx,di ;home first section it's end before section
call show_name_section
add dx,160
jmp .home_show_fb
._show_space_fb:
sub dx,4
push 0xb800
pop es
@@:
cmp dx,0xE64
ja .exit_show_fb
mov di,dx
;clear array for message
xor ax,ax
if DEBUG
mov ax,0x0720
end if
mov cx,39
rep stosw
;//////////////////////
 
add dx,160
jmp @b
.exit_show_fb:
; pop bp
ret
 
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/booteng.inc
0,0 → 1,98
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; booteng.asm the module for Secondary Loader ;;
;; ;;
;; KolibriOS 16-bit loader module, ;;
;; based on bootcode for KolibriOS ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;======================================================================
;
; BOOT DATA
;
;======================================================================
 
d80x25_bottom:
db 186,' KolibriOS is based on MenuetOS and comes with ABSOLUTELY '
db 'NO WARRANTY ',186
db 186,' See file COPYING for details '
db ' ',186
line_full_bottom
d80x25_bottom_num = 3
 
msg_apm db " APM x.x ", 0
vervesa db "Version of Vesa: Vesa x.x",13,10,0
novesa db "Display: EGA/CGA",13,10,0
s_vesa db "Version of VESA: "
.ver db "?.?",13,10,0
 
gr_mode db "Select a videomode: ",13,10,0
 
vrrmprint db "Apply VRR? (picture frequency greater than 60Hz"
db " only for transfers:",13,10
db 186," 1024*768->800*600 and 800*600->640*480) [1-yes,2-no]:",0
 
 
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
 
bdev db "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-use preloaded ram-image from kernel restart;"
db 13,10,186," "
db "4-create blank image]: ",0
probetext db 13,10,13,10,186," Use standart graphics mode? [1-yes, "
db "2-probe bios (Vesa 3.0)]: ",0
prnotfnd db "Fatal - Videomode not found.",0
not386 db "Fatal - CPU 386+ required.",0
btns db "Fatal - Can't determine color depth.",0
fatalsel db "Fatal - Graphics mode not supported by hardware.",0
pres_key db "Press any key to choose a new videomode.",0
badsect db 13,10,186," Fatal - Bad sector. Replace floppy.",0
memmovefailed db 13,10,186," Fatal - Int 0x15 move failed.",0
okt db " ... OK"
linef db 13,10,0
diskload db "Loading diskette: 00 %",8,8,8,8,0
pros db "00"
backspace2 db 8,8,0
boot_dev db 0 ; 0=floppy, 1=hd
start_msg db "Press [abc] to change settings, press [Enter] to continue booting",13,10,0
time_msg db " or wait "
time_str db " 5 seconds"
db " before automatical continuation",13,10,0
current_cfg_msg db "Current settings:",13,10,0
curvideo_msg db " [a] Videomode: ",0
 
mode0 db "320x200, EGA/CGA 256 colors",13,10,0
mode9 db "640x480, VGA 16 colors",13,10,0
 
usebd_msg db " [b] Add disks visible by BIOS:",0
on_msg db " on",13,10,0
off_msg db " off",13,10,0
;readonly_msg db " only for reading",13,10,0
vrrm_msg db " [c] Use VRR:",0
preboot_device_msg db " [d] Floppy image: ",0
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
pdm1 db "real floppy",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "use already loaded image",13,10,0
pdm4 db "create blank image",13,10,0
loading_msg db "Loading KolibriOS...",0
save_quest db "Remember current settings? [y/n]: ",0
loader_block_error db "Bootloader data invalid, I cannot continue. Stopped.",0
 
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿',13,10,0
_r1 db 186,' ³ 320x200 EGA/CGA 256 colors ³ ³',13,10,0
_r2 db 186,' ³ 640x480 VGA 16 colors ³ ³',13,10,0
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³',13,10,0
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ',13,10,0
 
remark1 db "Default values were selected to match most of configurations, but not all.",0
remark2 db "If you have LCD-monitor, disable VRR in the item [c] - you do not need it.",0
remark3 db "If the system does not boot, try to disable the item [b].",0
remarks dw remark1, remark2, remark3
num_remarks = 3
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/bootru.inc
0,0 → 1,87
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;=================================================================
;
; BOOT DATA
;
;=================================================================
 
 
d80x25_bottom:
db 186,' Kolibri OS ®á­®¢ ­  ­  Menuet OS ¨ ­¥ ¯à¥¤®áâ ¢«ï¥â '
db '­¨ª ª¨å £ àa­â¨©. ',186
db 186,' ®¤à®¡­¥¥ ᬮâà¨â¥ ¢ ä ©«¥ COPYING.TXT '
db ' ',186
line_full_bottom
msg_apm db " APM x.x ", 0
novesa db "‚¨¤¥®ª àâ : EGA/CGA",13,10,0
s_vesa db "‚¥àá¨ï VESA: "
.ver db "?.?",13,10,0
 
gr_mode db "‚ë¡¥à¨â¥ ¢¨¤¥®à¥¦¨¬: ",13,10,0
vrrmprint db "ˆá¯®«ì§®¢ âì VRR? (ç áâ®â  ª ¤à®¢ ¢ëè¥ 60 ƒæ"
db " ⮫쪮 ¤«ï ¯¥à¥å®¤®¢:",13,10
db 186," 1024*768>800*600 ¨ 800*600>640*480) [1-¤ , 2-­¥â]: ",0
;ask_dma db "ˆá¯®«ì§®¢ âì DMA ¤«ï ¤®áâ㯠 ª HDD? [1-¤ , 2-⮫쪮 ç⥭¨¥, 3-­¥â]: ",0
ask_bd db "„®¡ ¢¨âì ¤¨áª¨, ¢¨¤¨¬ë¥ ç¥à¥§ BIOS ¢ ०¨¬¥ V86? [1-¤ , 2-­¥â]: ",0
bdev db "‡ £à㧨âì ®¡à § ¨§ [1-¤¨áª¥â ; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-¨á¯®«ì§®¢ âì 㦥 § £à㦥­­ë© ®¡à §;"
db 13,10,186," "
db "4-ᮧ¤ âì ç¨áâë© ®¡à §]: ",0
prnotfnd db "Žè¨¡ª  - ‚¨¤¥®à¥¦¨¬ ­¥ ­ ©¤¥­.",0
not386 db "Žè¨¡ª  - ’ॡã¥âáï ¯à®æ¥áá®à 386+.",0
fatalsel db "Žè¨¡ª  - ‚ë¡à ­­ë© ¢¨¤¥®à¥¦¨¬ ­¥ ¯®¤¤¥à¦¨¢ ¥âáï.",0
pres_key db " ¦¨¬¨â¥ «î¡ãî ª« ¢¨èã, ¤«ï ¯¥à¥å®¤  ¢ ¢ë¡®à ०¨¬®¢.",0
badsect db 13,10,186," Žè¨¡ª  - „¨áª¥â  ¯®¢à¥¦¤¥­ . ®¯à®¡ã©â¥ ¤àã£ãî.",0
memmovefailed db 13,10,186," Žè¨¡ª  - Int 0x15 move failed.",0
okt db " ... OK"
linef db 13,10,0
diskload db "‡ £à㧪  ¤¨áª¥âë: 00 %",8,8,8,8,0
pros db "00"
backspace2 db 8,8,0
boot_dev db 0
start_msg db " ¦¬¨â¥ [abc] ¤«ï ¨§¬¥­¥­¨ï ­ áâ஥ª, [Enter] ¤«ï ¯à®¤®«¦¥­¨ï § £à㧪¨",13,10,0
time_msg db " ¨«¨ ¯®¤®¦¤¨â¥ "
time_str db " 5 ᥪ㭤 "
db " ¤®  ¢â®¬ â¨ç¥áª®£® ¯à®¤®«¦¥­¨ï",13,10,0
current_cfg_msg db "’¥ªã騥 ­ áâனª¨:",13,10,0
curvideo_msg db " [a] ‚¨¤¥®à¥¦¨¬: ",0
 
 
mode0 db "320x200, EGA/CGA 256 梥⮢",13,10,0
mode9 db "640x480, VGA 16 梥⮢",13,10,0
 
usebd_msg db " [b] „®¡ ¢¨âì ¤¨áª¨, ¢¨¤¨¬ë¥ ç¥à¥§ BIOS:",0
on_msg db " ¢ª«",13,10,0
off_msg db " ¢ëª«",13,10,0
readonly_msg db " ⮫쪮 ç⥭¨¥",13,10,0
vrrm_msg db " [c] ˆá¯®«ì§®¢ ­¨¥ VRR:",0
;preboot_device_msg db " [d] Ž¡à § ¤¨áª¥âë: ",0
;preboot_device_msgs dw 0,pdm1,pdm2,pdm3,pdm4
;pdm1 db "­ áâ®ïé ï ¤¨áª¥â ",13,10,0
;pdm2 db "C:\kolibri.img (FAT32)",13,10,0
;pdm3 db "¨á¯®«ì§®¢ âì 㦥 § £à㦥­­ë© ®¡à §",13,10,0
;pdm4 db "ᮧ¤ âì ç¨áâë© ®¡à §",13,10,0
loading_msg db "ˆ¤ñâ § £à㧪  KolibriOS...",0
save_quest db "‡ ¯®¬­¨âì ⥪ã騥 ­ áâனª¨? [y/n]: ",0
loader_block_error db "Žè¨¡ª  ¢ ¤ ­­ëå ­ ç «ì­®£® § £àã§ç¨ª , ¯à®¤®«¦¥­¨¥ ­¥¢®§¬®¦­®.",0
 
 
_st db 186,' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ',13,10,0
_r1 db 186,' ³ 320x200 EGA/CGA 256 梥⮢ ³ ³ ',13,10,0
_r2 db 186,' ³ 640x480 VGA 16 梥⮢ ³ ³ ',13,10,0
_rs db 186,' ³ ????x????@?? SVGA VESA ³ ³ ',13,10,0
_bt db 186,' ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ',13,10,0
 
 
remark1 db "‡­ ç¥­¨ï ¯® 㬮«ç ­¨î ¢ë¡à ­ë ¤«ï 㤮¡á⢠ ¡®«ì設á⢠, ­® ­¥ ¢á¥å.",0
remark2 db "…᫨ 㠂 á LCD-¬®­¨â®à, ®âª«îç¨â¥ VRR ¢ ¯ã­ªâ¥ [c] - ®­ ‚ ¬ ­¥ ­ã¦¥­.",0
remark3 db "…᫨ 㠂 á ­¥ £à㧨âáï á¨á⥬ , ¯®¯à®¡ã©â¥ ®âª«îç¨âì ¯ã­ªâ [b].",0
remarks dw remark1, remark2, remark3
num_remarks = 3
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/kolibri_ldm.asm
0,0 → 1,808
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Last modify Alexey Teplov <Lrz> 2008. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; kolibri_ldm.asm the module for Secondary Loader ;;
;; ;;
;; KolibriOS 16-bit loader module, ;;
;; based on bootcode for KolibriOS ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
include "lang.inc"
 
macro _setcursor row,column
{
mov dx, row*256 + column
call setcursor
}
long_v_table equ 9 ;long of visible video table
size_of_step equ 10
d80x25_bottom_num equ 3
d80x25_top_num equ 4
;It's a module for Secondary Loader to load kolibri OS
;
start_of_code:
cld
; \begin{diamond}[02.12.2005]
; if bootloader sets ax = 'KL', then ds:si points to loader block
; cmp ax, 'KL'
; jnz @f
; mov word [cs:cfgmanager.loader_block], si
; mov word [cs:cfgmanager.loader_block+2], ds
;@@:
; \end{diamond}[02.12.2005]
 
; if bootloader sets cx = 'HA' and dx = 'RD', then bx contains identifier of source hard disk
; (see comment to bx_from_load)
; cmp cx, 'HA'
; jnz no_hd_load
; cmp dx,'RD'
; jnz no_hd_load
; mov word [cs:bx_from_load], bx ; {SPraid}[13.03.2007]
;no_hd_load:
 
; set up stack
push cs
pop ss
xor ax,ax
mov sp,ax
; mov ax, 3000h
; mov ss, ax
; mov sp, 0EC00h
; set up segment registers
push cs
pop ds
push cs
pop es
 
; set videomode
mov ax, 3
int 0x10
 
;if lang eq ru
; Load & set russian VGA font (RU.INC)
mov bp, RU_FNT1 ; RU_FNT1 - First part
mov bx, 1000h ; 768 bytes
mov cx, 30h ; 48 symbols
mov dx, 80h ; 128 - position of first symbol
mov ax, 1100h
int 10h
 
mov bp, RU_FNT2 ; RU_FNT2 -Second part
mov bx, 1000h ; 512 bytes
mov cx, 20h ; 32 symbols
mov dx, 0E0h ; 224 - position of first symbol
mov ax, 1100h
int 10h
; End set VGA russian font
;else if lang eq et
; mov bp, ET_FNT ; ET_FNT1
; mov bx, 1000h ;
; mov cx, 255 ; 256 symbols
; xor dx, dx ; 0 - position of first symbol
; mov ax, 1100h
; int 10h
;end if
 
; draw frames
push 0xb800
pop es
xor di, di
mov ah, 1*16+15
 
; draw top
mov si, d80x25_top
mov cx, d80x25_top_num * 80
@@:
lodsb
stosw
loop @b
; draw spaces
mov si, space_msg
mov dx, 25 - d80x25_top_num - d80x25_bottom_num
dfl1:
push si
mov cx, 80
@@:
lodsb
stosw
loop @b
pop si
dec dx
jnz dfl1
; draw bottom
mov si, d80x25_bottom
mov cx, d80x25_bottom_num * 80
@@:
lodsb
stosw
loop @b
 
mov byte [space_msg+80], 0 ; now space_msg is null terminated
 
_setcursor d80x25_top_num,0
 
 
; TEST FOR 386+
 
mov bx, 0x4000
pushf
pop ax
mov dx, ax
xor ax, bx
push ax
popf
pushf
pop ax
and ax, bx
and dx, bx
cmp ax, dx
jnz cpugood
mov si, not386
sayerr:
call print
jmp $
cpugood:
 
push 0
popf
sti
 
; set up esp
movzx esp, sp
 
push 0
pop es
and word [es:0x9031], 0
; \begin{Mario79}
; find HDD IDE DMA PCI device
; check for PCI BIOS
mov ax, 0xB101
int 0x1A
jc .nopci
cmp edx, 'PCI '
jnz .nopci
; find PCI class code
; class 1 = mass storage
; subclass 1 = IDE controller
; a) class 1, subclass 1, programming interface 0x80
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x80
xor si, si ; device index = 0
int 0x1A
jnc .found
; b) class 1, subclass 1, programming interface 0x8A
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x8A
xor si, si ; device index = 0
int 0x1A
jnc .found
; c) class 1, subclass 1, programming interface 0x85
mov ax, 0xB103
mov ecx, 1*10000h + 1*100h + 0x85
xor si, si
int 0x1A
jc .nopci
.found:
; get memory base
mov ax, 0xB10A
mov di, 0x20 ; memory base is config register at 0x20
int 0x1A
jc .nopci
and cx, 0xFFF0 ; clear address decode type
mov [es:0x9031], cx
.nopci:
; \end{Mario79}
 
mov al, 0xf6 ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå
out 0x60, al
xor cx, cx
wait_loop: ; variant 2
; reading state of port of 8042 controller
in al, 64h
and al, 00000010b ; ready flag
; wait until 8042 controller is ready
loopnz wait_loop
 
;;;/diamond today 5.02.2008
; set keyboard typematic rate & delay
mov al, 0xf3
out 0x60, al
xor cx, cx
@@:
in al, 64h
test al, 2
loopnz @b
mov al, 0
out 0x60, al
xor cx, cx
@@:
in al, 64h
test al, 2
loopnz @b
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; --------------- APM ---------------------
and word [es:0x9044], 0 ; ver = 0.0 (APM not found)
mov ax, 0x5300
xor bx, bx
int 0x15
jc apm_end ; APM not found
test cx, 2
jz apm_end ; APM 32-bit protected-mode interface not supported
mov [es:0x9044], ax ; Save APM Version
mov [es:0x9046], cx ; Save APM flags
 
; Write APM ver ----
and ax, 0xf0f
add ax, '00'
mov si, msg_apm
mov [si + 5], ah
mov [si + 7], al
_setcursor 0, 3
call printplain
; ------------------
 
mov ax, 0x5304 ; Disconnect interface
xor bx, bx
int 0x15
mov ax, 0x5303 ; Connect 32 bit mode interface
xor bx, bx
int 0x15
 
mov [es:0x9040], ebx
mov [es:0x9050], ax
mov [es:0x9052], cx
mov [es:0x9054], dx
 
apm_end:
_setcursor d80x25_top_num, 0
 
;CHECK current of code
cmp [cfgmanager.loader_block], -1
jz noloaderblock
les bx, [cfgmanager.loader_block]
cmp byte [es:bx], 1
mov si, loader_block_error
jnz sayerr
push 0
pop es
 
noloaderblock:
; DISPLAY VESA INFORMATION
call print_vesa_info
call calc_vmodes_table
call check_first_parm ;check and enable cursor_pos
 
 
; \begin{diamond}[30.11.2005]
cfgmanager:
; settings:
; a) preboot_graph = graphical mode
; preboot_gprobe = probe this mode?
; b) preboot_dma = use DMA access?
; c) preboot_vrrm = use VRR?
 
; determine default settings
mov [.bSettingsChanged], 0
 
;.preboot_gr_end:
mov di, preboot_device
; if image in memory is present and [preboot_device] is uninitialized,
; set it to use this preloaded image
cmp byte [di], 0
jnz .preboot_device_inited
cmp [.loader_block], -1
jz @f
les bx, [.loader_block]
test byte [es:bx+1], 1
jz @f
mov byte [di], 3
jmp .preboot_device_inited
@@:
; otherwise, set [preboot_device] to 1 (default value - boot from floppy)
mov byte [di], 1
.preboot_device_inited:
; following 6 lines set variables to 1 if its current value is 0
cmp byte [di+preboot_dma-preboot_device], 1
adc byte [di+preboot_dma-preboot_device], 0
cmp byte [di+preboot_biosdisk-preboot_device], 1
adc byte [di+preboot_biosdisk-preboot_device], 0
cmp byte [di+preboot_vrrm-preboot_device], 1
adc byte [di+preboot_vrrm-preboot_device], 0
; notify user
_setcursor 5,2
 
mov si, linef
call printplain
mov si, start_msg
call print
mov si, time_msg
call print
; get start time
call .gettime
mov [.starttime], eax
mov word [.timer], .newtimer
mov word [.timer+2], cs
.printcfg:
_setcursor 9,0
mov si, current_cfg_msg
call print
mov si, curvideo_msg
call print
 
call draw_current_vmode
 
mov si, usebd_msg
cmp [preboot_biosdisk], 1
call .say_on_off
mov si, vrrm_msg
cmp [preboot_vrrm], 1
call .say_on_off
; mov si, preboot_device_msg
; call print
; mov al, [preboot_device]
; and eax, 7
; mov si, [preboot_device_msgs+eax*2]
; call printplain
.show_remarks:
; show remarks in gray color
mov di, ((21-num_remarks)*80 + 2)*2
push 0xB800
pop es
mov cx, num_remarks
mov si, remarks
.write_remarks:
lodsw
push si
xchg ax, si
mov ah, 1*16+7 ; background: blue (1), foreground: gray (7)
push di
.write_remark:
lodsb
test al, al
jz @f
stosw
jmp .write_remark
@@:
pop di
pop si
add di, 80*2
loop .write_remarks
.wait:
_setcursor 25,0 ; out of screen
; set timer interrupt handler
cli
push 0
pop es
push dword [es:8*4]
pop dword [.oldtimer]
push dword [.timer]
pop dword [es:8*4]
; mov eax, [es:8*4]
; mov [.oldtimer], eax
; mov eax, [.timer]
; mov [es:8*4], eax
sti
; wait for keypressed
xor ax,ax
int 16h
push ax
; restore timer interrupt
; push 0
; pop es
mov eax, [.oldtimer]
mov [es:8*4], eax
mov [.timer], eax
_setcursor 7,0
mov si, space_msg
call printplain
; clear remarks and restore normal attributes
push es
mov di, ((21-num_remarks)*80 + 2)*2
push 0xB800
pop es
mov cx, num_remarks
mov ax, ' ' + (1*16 + 15)*100h
@@:
push cx
mov cx, 76
rep stosw
pop cx
add di, 4*2
loop @b
pop es
pop ax
; switch on key
cmp al, 13
jz .continue
or al, 20h
cmp al, 'a'
jz .change_a
cmp al, 'b'
jz .change_b
cmp al, 'c'
jnz .show_remarks
 
_setcursor 15,0
mov si, vrrmprint
call print
mov bx, '12'
call getkey
mov [preboot_vrrm], al
_setcursor 12,0
.d:
mov [.bSettingsChanged], 1
call clear_vmodes_table ;clear vmodes_table
jmp .printcfg
.change_a:
.loops:
call draw_vmodes_table
_setcursor 25,0 ; out of screen
xor ax,ax
int 0x16
; call clear_table_cursor ;clear current position of cursor
 
mov si,word [cursor_pos]
 
cmp ah,0x48;x,0x48E0 ; up
jne .down
cmp si,modes_table
jbe .loops
sub word [cursor_pos],size_of_step
jmp .loops
 
.down: cmp ah,0x50;x,0x50E0 ; down
jne .pgup
cmp word[es:si+10],-1
je .loops
add word [cursor_pos],size_of_step
jmp .loops
 
.pgup: cmp ah,0x49 ; page up
jne .pgdn
sub si, size_of_step*long_v_table
cmp si, modes_table
jae @f
mov si, modes_table
@@:
mov word [cursor_pos], si
mov si, word [home_cursor]
sub si, size_of_step*long_v_table
cmp si, modes_table
jae @f
mov si, modes_table
@@:
mov word [home_cursor], si
jmp .loops
 
.pgdn: cmp ah,0x51 ; page down
jne .enter
mov ax, [end_cursor]
add si, size_of_step*long_v_table
cmp si, ax
jb @f
mov si, ax
sub si, size_of_step
@@:
mov word [cursor_pos], si
mov si, word [home_cursor]
sub ax, size_of_step*long_v_table
add si, size_of_step*long_v_table
cmp si, ax
jb @f
mov si, ax
@@:
mov word [home_cursor], si
jmp .loops
 
.enter: cmp al,0x0D;x,0x1C0D ; enter
jne .loops
push word [cursor_pos]
pop bp
push word [es:bp]
pop word [x_save]
push word [es:bp+2]
pop word [y_save]
push word [es:bp+6]
pop word [number_vm]
mov word [preboot_graph],bp ;save choose
jmp .d
 
.change_b:
_setcursor 15,0
; mov si, ask_dma
; call print
; mov bx, '13'
; call getkey
; mov [preboot_dma], al
mov si, ask_bd
call print
mov bx, '12'
call getkey
mov [preboot_biosdisk], al
_setcursor 11,0
jmp .d
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.say_on_off:
pushf
call print
mov si, on_msg
popf
jz @f
mov si, off_msg
@@: jmp printplain
; novesa and vervesa strings are not used at the moment of executing this code
virtual at novesa
.oldtimer dd ?
.starttime dd ?
.bSettingsChanged db ?
.timer dd ?
end virtual
.loader_block dd -1
.gettime:
mov ah, 0
int 1Ah
xchg ax, cx
shl eax, 10h
xchg ax, dx
ret
.newtimer:
push ds
push cs
pop ds
pushf
call [.oldtimer]
pushad
call .gettime
sub eax, [.starttime]
sub ax, 18*5
jae .timergo
neg ax
add ax, 18-1
mov bx, 18
xor dx, dx
div bx
if lang eq ru
; ¯®¤®¦¤¨â¥ 5 ᥪ㭤, 4/3/2 ᥪ㭤ë, 1 ᥪ㭤ã
cmp al, 5
mov cl, ' '
jae @f
cmp al, 1
mov cl, 'ã'
jz @f
mov cl, 'ë'
@@: mov [time_str+9], cl
else if lang eq et
cmp al, 1
ja @f
mov [time_str+9], ' '
mov [time_str+10],' '
@@:
else
; wait 5/4/3/2 seconds, 1 second
cmp al, 1
mov cl, 's'
ja @f
mov cl, ' '
@@: mov [time_str+9], cl
end if
add al, '0'
mov [time_str+1], al
mov si, time_msg
_setcursor 7,0
call print
_setcursor 25,0
popad
pop ds
iret
.timergo:
push 0
pop es
mov eax, [.oldtimer]
mov [es:8*4], eax
mov sp, 0EC00h
.continue:
sti
_setcursor 6,0
mov si, space_msg
call printplain
call printplain
_setcursor 6,0
mov si, loading_msg
call print
_setcursor 15,0
cmp [.bSettingsChanged], 0
jz .load
cmp [.loader_block], -1
jz .load
les bx, [.loader_block]
mov eax, [es:bx+3]
push ds
pop es
test eax, eax
jz .load
push eax
mov si, save_quest
call print
.waityn:
mov ah, 0
int 16h
or al, 20h
cmp al, 'n'
jz .loadc
cmp al, 'y'
jnz .waityn
call putchar
mov byte [space_msg+80], 186
pop eax
push cs
push .cont
push eax
retf
.loadc:
pop eax
.cont:
push cs
pop ds
mov si, space_msg
mov byte [si+80], 0
_setcursor 15,0
call printplain
_setcursor 15,0
.load:
; \end{diamond}[02.12.2005]
 
; ASK GRAPHICS MODE
 
call set_vmode
 
; GRAPHICS ACCELERATION
; force yes
mov [es:0x901C], byte 1
 
; DMA ACCESS TO HD
 
mov al, [preboot_dma]
mov [es:0x901F], al
 
; VRR_M USE
 
mov al,[preboot_vrrm]
mov [es:0x9030], al
mov [es:0x901E], byte 1
 
; BOOT DEVICE
 
mov al, [preboot_device]
dec al
mov [boot_dev], al
 
 
 
 
 
 
;;;;;;;;;;; set videomode
xor ax, ax
mov es, ax
 
mov ax, [es:0x9008] ; vga & 320x200
mov bx, ax
cmp ax, 0x13
je setgr
cmp ax, 0x12
je setgr
mov ax, 0x4f02 ; Vesa
setgr:
int 0x10
test ah, ah
mov si, fatalsel
jnz v_mode_error
; set mode 0x12 graphics registers:
cmp bx, 0x12
jne gmok2
 
mov al, 0x05
mov dx, 0x03ce
push dx
out dx, al ; select GDC mode register
mov al, 0x02
inc dx
out dx, al ; set write mode 2
 
mov al, 0x02
mov dx, 0x03c4
out dx, al ; select VGA sequencer map mask register
mov al, 0x0f
inc dx
out dx, al ; set mask for all planes 0-3
 
mov al, 0x08
pop dx
out dx, al ; select GDC bit mask register
; for writes to 0x03cf
gmok2:
push ds
pop es
 
jmp $
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include "lang.inc"
include "bootstr.inc" ; language-independent boot messages
;if lang eq en
;include "booteng.inc" ; english system boot messages
;else if lang eq ru
include "bootru.inc" ; russian system boot messages
include "ru.inc" ; Russian font
;else if lang eq et
;include "bootet.inc" ; estonian system boot messages
;include "et.inc" ; Estonian font
;else
;include "bootge.inc" ; german system boot messages
;end if
 
include 'macros.inc'
include 'bootvesa.inc'
 
include "preboot.inc"
 
 
setcursor:
; in: dl=column, dh=row
mov ah, 2
mov bh, 0
int 10h
ret
 
putchar:
; in: al=character
mov ah, 0Eh
mov bh, 0
int 10h
ret
 
print:
; in: si->string
mov al, 186
call putchar
mov al, ' '
call putchar
 
printplain:
; in: si->string
pusha
lodsb
@@:
call putchar
lodsb
cmp al, 0
jnz @b
popa
ret
 
getkey:
; get number in range [bl,bh] (bl,bh in ['0'..'9'])
; in: bx=range
; out: ax=digit (1..9, 10 for 0)
mov ah, 0
int 16h
cmp al, bl
jb getkey
cmp al, bh
ja getkey
push ax
call putchar
pop ax
and ax, 0Fh
jnz @f
mov al, 10
@@:
ret
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/ETFONT.FNT
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/bootet.inc
0,0 → 1,119
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; kolibri_ldm.asm the module for Secondary Loader ;;
;; ;;
;; KolibriOS 16-bit loader module, ;;
;; based on bootcode for KolibriOS ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;======================================================================
;
; BOOT DATA
;
;======================================================================
 
 
d80x25_bottom:
db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY '
db 'NO WARRANTY ',186
db 186,' See file COPYING for details '
db ' ',186
line_full_bottom
d80x25_bottom_num = 3
 
novesa db "Ekraan: EGA/CGA",13,10,0
vervesa db "Vesa versioon: Vesa x.x",13,10,0
vervesa_off=20
msg_apm db " APM x.x ", 0
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
db "[3] 1024x768, [4] 1280x1024",13,10
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
db "[7] 1024x768, [8] 1280x1024",13,10
db 186," EGA/CGA 256 värvi: [9] 320x200, "
db "VGA 16 värvi: [0] 640x480",13,10
db 186," Vali reziim: ",0
bt24 db "Bitti pikseli kohta: 24",13,10,0
bt32 db "Bitti pikseli kohta: 32",13,10,0
vrrmprint db "Kinnita VRR? (ekraani sagedus suurem kui 60Hz"
db " ainult:",13,10
db 186," 1024*768->800*600 ja 800*600->640*480) [1-jah,2-ei]:",0
;askmouse db " Hiir:"
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
; db " Vali port [1-3]: ",0
;no_com1 db 13,10,186, " No COM1 mouse",0
;no_com2 db 13,10,186, " No COM2 mouse",0
;ask_dma db "Use DMA for HDD access? [1-yes, 2-only for reading, 3-no]: ",0
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
;gr_direct db 186," Use direct LFB writing? "
; db "[1-yes/2-no] ? ",0
;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / "
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
bdev db "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-kasuta eellaaditud mäluketast kerneli restardist;"
db 13,10,186," "
db "4-loo tühi pilt]: ",0
probetext db 13,10,13,10,186," Kasuta standartset graafika reziimi? [1-jah, "
db "2-leia biosist (Vesa 3.0)]: ",0
;memokz256 db 13,10,186," RAM 256 Mb",0
;memokz128 db 13,10,186," RAM 128 Mb",0
;memokz64 db 13,10,186," RAM 64 Mb",0
;memokz32 db 13,10,186," RAM 32 Mb",0
;memokz16 db 13,10,186," RAM 16 Mb",0
prnotfnd db "Fataalne - Videoreziimi ei leitud.",0
;modena db "Fataalne - VBE 0x112+ on vajalik.",0
not386 db "Fataalne - CPU 386+ on vajalik.",0
btns db "Fataalne - Ei suuda värvisügavust määratleda.",0
fatalsel db "Fataalne - Graafilist reziimi riistvara ei toeta.",0
badsect db 13,10,186," Fataalne - Vigane sektor. Asenda diskett.",0
memmovefailed db 13,10,186," Fataalne - Int 0x15 liigutamine ebaõnnestus.",0
okt db " ... OK"
linef db 13,10,0
diskload db "Loen disketti: 00 %",8,8,8,8,0
pros db "00"
backspace2 db 8,8,0
boot_dev db 0 ; 0=floppy, 1=hd
start_msg db "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0
time_msg db " või oota "
time_str db " 5 sekundit"
db " automaatseks jätkamiseks",13,10,0
current_cfg_msg db "Praegused seaded:",13,10,0
curvideo_msg db " [a] Videoreziim: ",0
mode1 db "640x480",0
mode2 db "800x600",0
mode3 db "1024x768",0
mode4 db "1280x1024",0
modes_msg dw mode4,mode1,mode2,mode3
modevesa20 db " koos LFB",0
modevesa12 db ", VESA 1.2 Bnk",0
mode9 db "320x200, EGA/CGA 256 värvi",0
mode10 db "640x480, VGA 16 värvi",0
probeno_msg db " (standard reziim)",0
probeok_msg db " (kontrolli ebastandardseid reziime)",0
;dma_msg db " [b] Kasuta DMA'd HDD juurdepääsuks:",0
usebd_msg db " [b] Add disks visible by BIOS:",0
on_msg db " sees",13,10,0
off_msg db " väljas",13,10,0
;readonly_msg db " ainult lugemiseks",13,10,0
vrrm_msg db " [c] Kasuta VRR:",0
preboot_device_msg db " [d] Disketi kujutis: ",0
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
pdm1 db "reaalne diskett",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "kasuta juba laaditud kujutist",13,10,0
pdm4 db "loo tühi pilt",13,10,0
loading_msg db "Laadin KolibriOS...",0
save_quest db "Jäta meelde praegused seaded? [y/n]: ",0
loader_block_error db "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0
 
remark1 db "Default values were selected to match most of configurations, but not all.",0
remark2 db "If you have LCD-monitor, disable VRR in the item [c] - you do not need it.",0
remark3 db "If the system does not boot, try to disable the item [b].",0
remarks dw remark1, remark2, remark3
num_remarks = 3
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/bootge.inc
0,0 → 1,118
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;======================================================================
;
; BOOT DATA
;
;======================================================================
 
 
d80x25_bottom:
; db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY '
; db 'NO WARRANTY ',186
; db 186,' See file COPYING for details '
; db ' ',186
 
db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche '
db ' Garantie vertrieben ',186
db 186,' Details stehen in der Datei COPYING '
db ' ',186
line_full_bottom
d80x25_bottom_num = 3
 
novesa db "Anzeige: EGA/CGA ",13,10,0
vervesa db "Vesa-Version: Vesa ",13,10,0
vervesa_off=22
msg_apm db " APM x.x ", 0
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, "
db "[3] 1024x768, [4] 1280x1024",13,10
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, "
db "[7] 1024x768, [8] 1280x1024",13,10
db 186," EGA/CGA 256 Farben: [9] 320x200, "
db "VGA 16 Farben: [0] 640x480",13,10
db 186," Waehle Modus: ",0
bt24 db "Bits Per Pixel: 24",13,10,0
bt32 db "Bits Per Pixel: 32",13,10,0
vrrmprint db "VRR verwenden? (Monitorfrequenz groesser als 60Hz"
db " only for transfers:",13,10
db 186," 1024*768->800*600 und 800*600->640*480) [1-ja,2-nein]:",0
;askmouse db " Maus angeschlossen an:"
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
; db " Waehle Port [1-3]: ",0
;no_com1 db 13,10,186, " Keine COM1 Maus",0
;no_com2 db 13,10,186, " Keine COM2 Maus",0
;ask_dma db "Nutze DMA zum HDD Zugriff? [1-ja, 2-allein fur Lesen, 3-nein]: ",0
ask_bd db "Add disks visible by BIOS emulated in V86-mode? [1-yes, 2-no]: ",0
;gr_direct db 186," Benutze direct LFB? "
; db "[1-ja/2-nein] ? ",0
;mem_model db 13,10,186," Hauptspeicher [1-16 Mb / 2-32 Mb / "
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0
bdev db "Lade die Ramdisk von [1-Diskette; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-benutze ein bereits geladenes Kernel image;"
db 13,10,186," "
db "4-create blank image]: ",0
probetext db 13,10,13,10,186," Nutze Standardgrafikmodi? [1-ja, "
db "2-BIOS Test (Vesa 3.0)]: ",0
;memokz256 db 13,10,186," RAM 256 Mb",0
;memokz128 db 13,10,186," RAM 128 Mb",0
;memokz64 db 13,10,186," RAM 64 Mb",0
;memokz32 db 13,10,186," RAM 32 Mb",0
;memokz16 db 13,10,186," RAM 16 Mb",0
prnotfnd db "Fatal - Videomodus nicht gefunden.",0
;modena db "Fatal - VBE 0x112+ required.",0
not386 db "Fatal - CPU 386+ benoetigt.",0
btns db "Fatal - konnte Farbtiefe nicht erkennen.",0
fatalsel db "Fatal - Grafikmodus nicht unterstuetzt.",0
badsect db 13,10,186," Fatal - Sektorfehler, Andere Diskette neutzen.",0
memmovefailed db 13,10,186," Fatal - Int 0x15 Fehler.",0
okt db " ... OK"
linef db 13,10,0
diskload db "Lade Diskette: 00 %",8,8,8,8,0
pros db "00"
backspace2 db 8,8,0
boot_dev db 0 ; 0=floppy, 1=hd
start_msg db "Druecke [abcd], um die Einstellungen zu aendern , druecke [Enter] zum starten",13,10,0
time_msg db " oder warte "
time_str db " 5 Sekunden"
db " bis zum automatischen Start",13,10,0
current_cfg_msg db "Aktuelle Einstellungen:",13,10,0
curvideo_msg db " [a] Videomodus: ",0
mode1 db "640x480",0
mode2 db "800x600",0
mode3 db "1024x768",0
mode4 db "1280x1024",0
modes_msg dw mode4,mode1,mode2,mode3
modevesa20 db " mit LFB",0
modevesa12 db ", VESA 1.2 Bnk",0
mode9 db "320x200, EGA/CGA 256 colors",0
mode10 db "640x480, VGA 16 colors",0
probeno_msg db " (Standard Modus)",0
probeok_msg db " (teste nicht-standard Modi)",0
;dma_msg db " [b] Nutze DMA zum HDD Aufschreiben:",0
usebd_msg db " [b] Add disks visible by BIOS:",0
on_msg db " an",13,10,0
off_msg db " aus",13,10,0
;readonly_msg db " fur Lesen",13,10,0
vrrm_msg db " [c] Nutze VRR:",0
preboot_device_msg db " [d] Diskettenimage: ",0
preboot_device_msgs dw 0,pdm1,pdm2,pdm3
pdm1 db "Echte Diskette",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "Nutze bereits geladenes Image",13,10,0
pdm4 db "create blank image",13,10,0
loading_msg db "Lade KolibriOS...",0
save_quest db "Aktuelle Einstellungen speichern? [y/n]: ",0
loader_block_error db "Bootloader Daten ungueltig, Kann nicht fortfahren. Angehalten.",0
 
remark1 db "Default values were selected to match most of configurations, but not all.",0
remark2 db "If you have LCD-monitor, disable VRR in the item [c] - you do not need it.",0
remark3 db "If the system does not boot, try to disable the item [b].",0
remarks dw remark1, remark2, remark3
num_remarks = 3
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/bootstr.inc
0,0 → 1,55
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
 
; boot data: common strings (for all languages)
macro line_full_top {
db 201
times 78 db 205
db 187
}
macro line_full_bottom {
db 200
times 78 db 205
db 188
}
macro line_half {
db 186,' '
times 76 db 0xc4
db ' ',186
}
macro line_space {
db 186
times 78 db 32
db 186
}
d80x25_top:
line_full_top
cur_line_pos = 75
; store byte ' ' at d80x25_top+cur_line_pos+1
; store byte ' ' at d80x25_top+cur_line_pos
; store dword ' SVN' at d80x25_top+cur_line_pos-4
 
space_msg: line_space
;verstr:
; line_space
; version string
; db 186,32
; repeat 78
; load a byte from version+%-1
; if a = 13
; break
; end if
; db a
; end repeat
; repeat 78 - ($-verstr)
; db ' '
; end repeat
; db 32,186
; line_half
 
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/bootvesa.inc
0,0 → 1,754
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
struc VBE_VGAInfo {
.VESASignature dd ? ; char
.VESAVersion dw ? ; short
.OemStringPtr dd ? ; char *
.Capabilities dd ? ; ulong
.VideoModePtr dd ? ; ulong
.TotalMemory dw ? ; short
; VBE 2.0+
.OemSoftwareRev db ? ; short
.OemVendorNamePtr dw ? ; char *
.OemProductNamePtr dw ? ; char *
.OemProductRevPtr dw ? ; char *
.reserved rb 222 ; char
.OemData rb 256 ; char
}
 
struc VBE_ModeInfo {
.ModeAttributes dw ? ; short
.WinAAttributes db ? ; char
.WinBAttributes db ? ; char
.WinGranularity dw ? ; short
.WinSize dw ? ; short
.WinASegment dw ? ; ushort
.WinBSegment dw ? ; ushort
.WinFuncPtr dd ? ; void *
.BytesPerScanLine dw ? ; short
.XRes dw ? ; short
.YRes dw ? ; short
.XCharSize db ? ; char
.YCharSize db ? ; char
.NumberOfPlanes db ? ; char
.BitsPerPixel db ? ; char
.NumberOfBanks db ? ; char
.MemoryModel db ? ; char
.BankSize db ? ; char
.NumberOfImagePages db ? ; char
.res1 db ? ; char
.RedMaskSize db ? ; char
.RedFieldPosition db ? ; char
.GreenMaskSize db ? ; char
.GreenFieldPosition db ? ; char
.BlueMaskSize db ? ; char
.BlueFieldPosition db ? ; char
.RsvedMaskSize db ? ; char
.RsvedFieldPosition db ? ; char
.DirectColorModeInfo db ? ; char ; MISSED IN THIS TUTORIAL!! SEE ABOVE
; VBE 2.0+
.PhysBasePtr dd ? ; ulong
.OffScreenMemOffset dd ? ; ulong
.OffScreenMemSize dw ? ; short
; VBE 3.0+
.LinbytesPerScanLine dw ? ; short
.BankNumberOfImagePages db ? ; char
.LinNumberOfImagePages db ? ; char
.LinRedMaskSize db ? ; char
.LinRedFieldPosition db ? ; char
.LingreenMaskSize db ? ; char
.LinGreenFieldPosition db ? ; char
.LinBlueMaskSize db ? ; char
.LinBlueFieldPosition db ? ; char
.LinRsvdMaskSize db ? ; char
.LinRsvdFieldPosition db ? ; char
.MaxPixelClock dd ? ; ulong
.res2 rb 190 ; char
}
 
virtual at $A000
vi VBE_VGAInfo
mi VBE_ModeInfo
modes_table:
end virtual
cursor_pos dw 0 ;âðåìåííîå õðàíåíèå êóðñîðà.
home_cursor dw 0 ;current shows rows a table
end_cursor dw 0 ;end of position current shows rows a table
scroll_start dw 0 ;start position of scroll bar
scroll_end dw 0 ;end position of scroll bar
long_v_table equ 9 ;long of visible video table
size_of_step equ 10
scroll_area_size equ (long_v_table-2)
int2str:
dec bl
jz @f
xor edx,edx
div ecx
push edx
call int2str
pop eax
@@: or al,0x30
mov [ds:di],al
inc di
ret
 
int2strnz:
cmp eax,ecx
jb @f
xor edx,edx
div ecx
push edx
call int2strnz
pop eax
@@: or al,0x30
mov [es:di],al
inc di
ret
 
;-------------------------------------------------------
;Write message about incorrect v_mode and write message about jmp on swith v_mode
v_mode_error:
_setcursor 19,2
mov si, fatalsel
call printplain
_setcursor 20,2
mov si,pres_key
call printplain
xor eax,eax
int 16h
jmp cfgmanager.d
;-------------------------------------------------------
;
 
 
 
;-------------------------------------------------------
print_vesa_info:
_setcursor 5,2
 
mov [es:vi.VESASignature],'VBE2'
mov ax,0x4F00
mov di,vi ;0xa000
int 0x10
or ah,ah
jz @f
mov [es:vi.VESASignature],'VESA'
mov ax,$4F00
mov di,vi
int 0x10
or ah,ah
jnz .exit
@@:
cmp [es:vi.VESASignature],'VESA'
jne .exit
cmp [es:vi.VESAVersion],0x0100
jb .exit
jmp .vesaok2
 
.exit:
mov si,novesa
call printplain
ret
 
.vesaok2:
mov ax,[es:vi.VESAVersion]
add ax,'00'
 
mov [s_vesa.ver], ah
mov [s_vesa.ver+2], al
mov si,s_vesa
call printplain
 
_setcursor 4,2
mov si,word[es:vi.OemStringPtr]
mov di,si
 
push ds
mov ds,word[es:vi.OemStringPtr+2]
call printplain
pop ds
 
ret
;-----------------------------------------------------------------------------
 
calc_vmodes_table:
pushad
 
; push 0
; pop es
 
lfs si, [es:vi.VideoModePtr]
 
mov bx,modes_table
;save no vesa mode of work 320x200, EGA/CGA 256 梥⮢ and 640x480, VGA 16 梥⮢
mov word [es:bx],640
mov word [es:bx+2],480
mov word [es:bx+6],0x13
mov word [es:bx+10],640
mov word [es:bx+12],480
mov word [es:bx+16],0x12
add bx,20
.next_mode:
mov cx,word [fs:si] ; mode number
cmp cx,-1
je .modes_ok.2
 
mov ax,0x4F01
mov di,mi
int 0x10
 
or ah,ah
jnz .modes_ok.2;vesa_info.exit
 
test [es:mi.ModeAttributes],00000001b ;videomode support ?
jz @f
test [es:mi.ModeAttributes],00010000b ;picture ?
jz @f
test [es:mi.ModeAttributes],10000000b ;LFB ?
jz @f
 
cmp [es:mi.BitsPerPixel], 24 ;It show only videomodes to have support 24 and 32 bpp
jb @f
 
; cmp [es:mi.BitsPerPixel],16
; jne .l0
; cmp [es:mi.GreenMaskSize],5
; jne .l0
; mov [es:mi.BitsPerPixel],15
 
 
.l0:
cmp [es:mi.XRes],640
jb @f
cmp [es:mi.YRes],480
jb @f
; cmp [es:mi.BitsPerPixel],8
; jb @f
 
mov ax,[es:mi.XRes]
mov [es:bx+0],ax ; +0[2] : resolution X
mov ax,[es:mi.YRes]
mov [es:bx+2],ax ; +2[2] : resolution Y
mov ax,[es:mi.ModeAttributes]
mov [es:bx+4],ax ; +4[2] : attributes
 
cmp [s_vesa.ver],'2'
jb .lp1
 
or cx,0x4000 ; use LFB
.lp1: mov [es:bx+6],cx ; +6 : mode number
movzx ax,byte [es:mi.BitsPerPixel]
mov word [es:bx+8],ax ; +8 : bits per pixel
add bx,size_of_step ; size of record
 
@@:
add si,2
jmp .next_mode
 
.modes_ok.2:
 
mov word[es:bx],-1 ;end video table
mov word[end_cursor],bx ;save end cursor position
;;;;;;;;;;;;;;;;;;
;Sort array
; mov si,modes_table
;.new_mode:
; mov ax,word [es:si]
; cmp ax,-1
; je .exxit
; add ax,word [es:si+2]
; add ax,word [es:si+8]
; mov bp,si
;.again:
; add bp,12
; mov bx,word [es:bp]
; cmp bx,-1
; je .exit
; add bx,word [es:bp+2]
; add bx,word [es:bp+8]
;
; cmp ax,bx
; ja .loops
; jmp .again
;.loops:
; push dword [es:si]
; push dword [es:si+4]
; push dword [es:si+8]
; push dword [es:bp]
; push dword [es:bp+4]
; push dword [es:bp+8]
;
; pop dword [es:si+8]
; pop dword [es:si+4]
; pop dword [es:si]
; pop dword [es:bp+8]
; pop dword [es:bp+4]
; pop dword [es:bp]
; jmp .new_mode
;
;.exit: add si,12
; jmp .new_mode
;.exxit:
popad
ret
 
;-----------------------------------------------------------------------------
 
draw_current_vmode:
push 0
pop es
 
mov si,word [cursor_pos]
 
cmp word [es:si+6],0x12
je .no_vesa_0x12
 
cmp word [es:si+6],0x13
je .no_vesa_0x13
 
mov di,loader_block_error
movzx eax,word[es:si+0]
mov ecx,10
call int2strnz
mov byte[es:di],'x'
inc di
movzx eax,word[es:si+2]
call int2strnz
mov byte[es:di],'x'
inc di
movzx eax,word[es:si+8]
call int2strnz
mov dword[es:di],0x00000d0a
mov si,loader_block_error
push ds
push es
pop ds
call printplain
pop ds
ret
.no_vesa_0x13:
mov si,mode0
jmp .print
.no_vesa_0x12:
mov si,mode9
.print:
call printplain
ret
;-----------------------------------------------------------------------------
check_first_parm:
mov si,word [preboot_graph]
test si,si
jnz .no_zero ;if no zero
.zerro:
; mov ax,modes_table
; mov word [cursor_pos],ax
; mov word [home_cursor],ax
; mov word [preboot_graph],ax
;SET default video of mode first probe will fined a move of work 1024x768@32
 
mov ax,1024
mov bx,768
mov si,modes_table
call .loops
test ax,ax
jz .ok_found_mode
mov ax,800
mov bx,600
mov si,modes_table
call .loops
test ax,ax
jz .ok_found_mode
mov ax,640
mov bx,480
mov si,modes_table
call .loops
test ax,ax
jz .ok_found_mode
 
mov si,modes_table
jmp .ok_found_mode
 
 
 
.no_zero:
mov bp,word [number_vm]
cmp bp,word [es:si+6]
jz .ok_found_mode
mov ax,word [x_save]
mov bx,word [y_save]
mov si,modes_table
call .loops
test ax,ax
jz .ok_found_mode
 
mov si,modes_table
; cmp ax,modes_table
; jb .zerro ;check on correct if bellow
; cmp ax,word [end_cursor]
; ja .zerro ;check on correct if anymore
 
.ok_found_mode:
mov word [home_cursor],si
; mov word [cursor_pos],si
mov word [preboot_graph],si
mov ax,si
 
mov ecx,long_v_table
 
.loop: add ax,size_of_step
cmp ax,word [end_cursor]
jae .next_step
loop .loop
.next_step:
sub ax,size_of_step*long_v_table
cmp ax,modes_table
jae @f
mov ax,modes_table
@@:
 
mov word [home_cursor],ax
mov si,[preboot_graph]
mov word [cursor_pos],si
 
push word [es:si]
pop word [x_save]
push word [es:si+2]
pop word [y_save]
push word [es:si+6]
pop word [number_vm]
 
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;
.loops:
cmp ax,word [es:si]
jne .next
cmp bx,word [es:si+2]
jne .next
cmp word [es:si+8],32
je .ok
cmp word [es:si+8],24
je .ok
.next: add si,size_of_step
cmp word [es:si],-1
je .exit
jmp .loops
.ok: xor ax,ax
ret
.exit: or ax,-1
ret
 
 
;-----------------------------------------------------------------------------
 
;default_vmode:
;-----------------------------------------------------------------------------
draw_vmodes_table:
_setcursor 9, 2
mov si,gr_mode
call printplain
 
mov si,_st
call printplain
 
push word [cursor_pos]
pop ax
push word [home_cursor]
pop si
mov cx,si
 
cmp ax,si
je .ok
jb .low
 
 
add cx,size_of_step*long_v_table
cmp ax,cx
jb .ok
sub cx,size_of_step*long_v_table
add cx,size_of_step
cmp cx,word[end_cursor]
jae .ok
add si,size_of_step
push si
pop word [home_cursor]
jmp .ok
 
 
.low: sub cx,size_of_step
cmp cx,modes_table
jb .ok
push cx
push cx
pop word [home_cursor]
pop si
 
 
.ok:
; calculate scroll position
push si
mov ax, [end_cursor]
sub ax, modes_table
mov bx, size_of_step
cwd
div bx
mov si, ax ; si = size of list
mov ax, [home_cursor]
sub ax, modes_table
cwd
div bx
mov di, ax
mov ax, scroll_area_size*long_v_table
cwd
div si
test ax, ax
jnz @f
inc ax
@@:
cmp al, scroll_area_size
jb @f
mov al, scroll_area_size
@@:
mov cx, ax
; cx = scroll height
; calculate scroll pos
xor bx, bx ; initialize scroll pos
sub al, scroll_area_size+1
neg al
sub si, long_v_table-1
jbe @f
mul di
div si
mov bx, ax
@@:
inc bx
imul ax, bx, size_of_step
add ax, [home_cursor]
mov [scroll_start], ax
imul cx, size_of_step
add ax, cx
mov [scroll_end], ax
pop si
mov bp,long_v_table ;show rows
.@@_next_bit:
;clear cursor
mov ax,' '
mov word[ds:_r1+21],ax
mov word[ds:_r1+50],ax
 
mov word[ds:_r2+21],ax
mov word[ds:_r2+45],ax
 
mov word[ds:_rs+21],ax
mov word[ds:_rs+46],ax
; draw string
cmp word [es:si+6],0x12
je .show_0x12
cmp word [es:si+6],0x13
je .show_0x13
 
movzx eax,word[es:si]
cmp ax,-1
je .@@_end
mov di,_rs+23
mov ecx,10
mov bl,4
call int2str
movzx eax,word[es:si+2]
inc di
mov bl,4
call int2str
 
movzx eax,word[es:si+8]
inc di
mov bl,2
call int2str
 
cmp si, word [cursor_pos]
jne .next
;draw cursor
mov word[ds:_rs+21],'>>'
mov word[ds:_rs+46],'<<'
 
 
.next:
push si
mov si,_rs
.@@_sh:
; add to the string pseudographics for scrollbar
pop bx
push bx
mov byte [si+53], ' '
cmp bx, [scroll_start]
jb @f
cmp bx, [scroll_end]
jae @f
mov byte [si+53], 0xDB ; filled bar
@@:
push bx
add bx, size_of_step
cmp bx, [end_cursor]
jnz @f
mov byte [si+53], 31 ; 'down arrow' symbol
@@:
sub bx, [home_cursor]
cmp bx, size_of_step*long_v_table
jnz @f
mov byte [si+53], 31 ; 'down arrow' symbol
@@:
pop bx
cmp bx, [home_cursor]
jnz @f
mov byte [si+53], 30 ; 'up arrow' symbol
@@:
call printplain
pop si
add si,size_of_step
 
dec bp
jnz .@@_next_bit
 
.@@_end:
mov si,_bt
call printplain
ret
.show_0x13:
push si
 
cmp si, word [cursor_pos]
jne @f
mov word[ds:_r1+21],'>>'
mov word[ds:_r1+50],'<<'
@@:
mov si,_r1
jmp .@@_sh
.show_0x12:
push si
cmp si, word [cursor_pos]
jne @f
 
mov word[ds:_r2+21],'>>'
mov word[ds:_r2+45],'<<'
@@:
mov si,_r2
jmp .@@_sh
 
;-----------------------------------------------------------------------------
;Clear arrea of current video page (0xb800)
clear_vmodes_table:
pusha
; draw frames
push es
push 0xb800
pop es
mov di,1444
xor ax,ax
mov ah, 1*16+15
mov cx,70
mov bp,12
.loop_start:
rep stosw
mov cx,70
add di,20
dec bp
jns .loop_start
pop es
popa
ret
 
;-----------------------------------------------------------------------------
 
set_vmode:
push 0 ;0;x1000
pop es
 
mov si,word [preboot_graph] ;[preboot_graph]
mov cx,word [es:si+6] ; number of mode
 
mov ax,word [es:si+0] ; resolution X
mov bx,word [es:si+2] ; resolution Y
 
 
mov word [es:0x900A],ax ; resolution X
mov word [es:0x900C],bx ; resolution Y
mov word [es:0x9008],cx ; number of mode
 
cmp cx,0x12
je .mode0x12_0x13
cmp cx,0x13
je .mode0x12_0x13
 
 
cmp byte [s_vesa.ver],'2'
jb .vesa12
 
; VESA 2 and Vesa 3
 
mov ax,0x4f01
and cx,0xfff
mov di,mi;0xa000
int 0x10
; LFB
mov eax,[es:mi.PhysBasePtr];di+0x28]
mov [es:0x9018],eax
; ---- vbe voodoo
BytesPerLine equ 0x10
mov ax, [es:di+BytesPerLine]
mov [es:0x9001], ax
; BPP
cmp [es:mi.BitsPerPixel],16
jne .l0
cmp [es:mi.GreenMaskSize],5
jne .l0
mov [es:mi.BitsPerPixel],15
.l0:
mov al, byte [es:di+0x19]
mov [es:0x9000], al
jmp .exit
 
.mode0x12_0x13:
mov byte [es:0x9000], 32
or dword [es:0x9018], 0xFFFFFFFF; 0x800000
 
 
; VESA 1.2 PM BANK SWITCH ADDRESS
 
.vesa12:
 
 
mov ax,0x4f0A
xor bx,bx
int 0x10
xor eax,eax
xor ebx,ebx
mov ax,es
shl eax,4
mov bx,di
add eax,ebx
movzx ebx,word[es:di]
add eax,ebx
push 0x0000
pop es
mov [es:0x9014],eax
.exit:
ret
 
 
; mov dword[es:0x9018],0x000A0000
; ret
 
;=============================================================================
;=============================================================================
;=============================================================================
 
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/build_ru.bat
0,0 → 1,89
@echo off
 
set languages=en ru ge et
call :Check_Lang %1
for %%a in (ru) do if %%a==%target%
call :Target_%target%
 
if ERRORLEVEL 0 goto Exit_OK
 
echo There was an error executing script.
echo For any help, please send a report.
pause
goto :eof
 
 
 
 
:Check_Lang
set res=%1
:Check_Lang_loop
for %%a in (%languages%) do if %%a==%res% set lang=%res%
if defined lang call :make_all goto :eof
 
echo Language '%res%' is incorrect
echo Enter valid language [ %languages% ]:
 
set /P res=">
goto Check_Lang_loop
goto :eof
 
 
:make_all
echo *** building module Kolibri.ldm for Secondary Loader with language '%lang%' ...
 
if not exist bin mkdir bin
echo lang fix %lang% > lang.inc
fasm -m 65536 kolibri_ldm.asm bin\kolibri.ldm
if not %errorlevel%==0 goto :Error_FasmFailed
erase lang.inc
goto Exit_OK
 
 
:Target_all
call :Target_kernel
call :Target_drivers
call :Target_skins
goto :eof
 
 
:Target_drivers
echo *** building drivers ...
 
if not exist bin\drivers mkdir bin\drivers
cd drivers
for %%a in (%drivers%) do (
fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj
if not %errorlevel%==0 goto :Error_FasmFailed
)
cd ..
move bin\drivers\vmode.obj bin\drivers\vmode.mdr
goto :eof
 
 
:Target_skins
echo *** building skins ...
 
if not exist bin\skins mkdir bin\skins
cd skin
fasm -m 65536 default.asm ..\bin\skins\default.skn
if not %errorlevel%==0 goto :Error_FasmFailed
cd ..
goto :eof
 
:Target_clean
echo *** cleaning ...
rmdir /S /Q bin
goto :Exit_OK
 
 
:Error_FasmFailed
echo error: fasm execution failed
erase lang.inc
pause
exit 1
 
:Exit_OK
echo all operations has been done
pause
exit 0
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/et.inc
0,0 → 1,14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
; Full ASCII code font
; only õ and ä added
; Kaitz
ET_FNT:
fontfile file "ETFONT.FNT"
 
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/macros.inc
0,0 → 1,86
 
 
; structure definition helper
macro struct name, [arg]
{
common
name@struct equ name
struc name arg {
}
 
macro struct_helper name
{
match xname,name
\{
virtual at 0
xname xname
sizeof.#xname = $ - xname
name equ sizeof.#xname
end virtual
\}
}
 
ends fix } struct_helper name@struct
 
;// mike.dld, 2006-29-01 [
 
; macros definition
macro diff16 title,l1,l2
{
local s,d
s = l2-l1
display title,': 0x'
repeat 16
d = 48 + s shr ((16-%) shl 2) and $0F
if d > 57
d = d + 65-57-1
end if
display d
end repeat
display 13,10
}
macro diff10 title,l1,l2
{
local s,d,z,m
s = l2-l1
z = 0
m = 1000000000
display title,': '
repeat 10
d = '0' + s / m
s = s - (s/m)*m
m = m / 10
if d <> '0'
z = 1
end if
if z <> 0
display d
end if
end repeat
display 13,10
}
 
; \begin{diamond}[29.09.2006]
; may be useful for kernel debugging
; example 1:
; dbgstr 'Hello, World!'
; example 2:
; dbgstr 'Hello, World!', save_flags
macro dbgstr string*, f
{
local a
iglobal_nested
a db 'K : ',string,13,10,0
endg_nested
if ~ f eq
pushfd
end if
push esi
mov esi, a
call sys_msg_board_str
pop esi
if ~ f eq
popfd
end if
}
; \end{diamond}[29.09.2006]
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/preboot.inc
0,0 → 1,36
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
display_modechg db 0 ; display mode change for text, yes/no (0 or 2)
;
; !! Important note !!
;
; Must be set to 2, to avoid two screenmode
; changes within a very short period of time.
 
display_atboot db 0 ; show boot screen messages ( 2-no )
 
preboot_graph dw 0 ; graph mode
x_save dw 0 ; x
y_save dw 0 ; y
number_vm dw 0 ;
;pixel_save dw 0 ; per to pixel
preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes)
preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no)
preboot_dma db 0 ; use DMA for access to HDD (1-always, 2-only for read, 3-never)
preboot_device db 0 ; boot device
; (1-floppy 2-harddisk 3-kernel restart 4-format ram disk)
;!!!! 0 - autodetect !!!!
preboot_blogesc = 0 ; start immediately after bootlog
preboot_biosdisk db 0 ; use V86 to access disks through BIOS (1-yes, 2-no)
 
; if $>0x200
;ERROR: prebooting parameters must fit in first sector!!!
; end if
;hdsysimage db 'KOLIBRI IMG' ; load from
;image_save db 'KOLIBRI IMG' ; save to
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/rdload.inc
0,0 → 1,123
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
; READ RAMDISK IMAGE FROM HD
 
cmp [boot_dev+OS_BASE+0x10000],1
jne no_sys_on_hd
 
test [DRIVE_DATA+1],byte 0x40
jz position_2
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
mov [fat32part],0
position_1_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [DRIVE_DATA+2]
cmp [fat32part],eax
jle position_1_1
position_2:
test [DRIVE_DATA+1],byte 0x10
jz position_3
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
mov [fat32part],0
position_2_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [DRIVE_DATA+3]
cmp eax,[fat32part]
jle position_2_1
position_3:
test [DRIVE_DATA+1],byte 0x4
jz position_4
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
mov [fat32part],0
position_3_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [DRIVE_DATA+4]
cmp eax,[fat32part]
jle position_3_1
position_4:
test [DRIVE_DATA+1],byte 0x1
jz no_sys_on_hd
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
mov [fat32part],0
position_4_1:
inc [fat32part]
call search_and_read_image
cmp [image_retrieved],1
je yes_sys_on_hd
movzx eax,byte [DRIVE_DATA+5]
cmp eax,[fat32part]
jle position_4_1
jmp yes_sys_on_hd
 
search_and_read_image:
call set_FAT32_variables
mov edx, bootpath
call read_image
test eax, eax
jz image_present
mov edx, bootpath2
call read_image
test eax, eax
jz image_present
ret
image_present:
mov [image_retrieved],1
ret
 
read_image:
mov eax, hdsysimage+OS_BASE+0x10000
mov ebx, 1474560/512
mov ecx, RAMDISK
mov esi, 0
mov edi, 12
call file_read
ret
 
image_retrieved db 0
counter_of_partitions db 0
no_sys_on_hd:
; test_to_format_ram_disk (need if not using ram disk)
cmp [boot_dev+OS_BASE+0x10000],3
jne not_format_ram_disk
; format_ram_disk
mov edi, RAMDISK
mov ecx, 0x1080
xor eax,eax
@@:
stosd
loop @b
 
mov ecx, 0x58F7F
mov eax,0xF6F6F6F6
@@:
stosd
loop @b
mov [RAMDISK+0x200],dword 0xFFFFF0 ; fat table
mov [RAMDISK+0x4200],dword 0xFFFFF0
not_format_ram_disk:
yes_sys_on_hd:
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/ru.inc
0,0 → 1,100
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
; Generated by RUFNT.EXE
; By BadBugsKiller (C)
; Modifyed by BadBugsKiller 12.01.2004 17:45
; Øðèôò óìåíüøåí â ðàçìåðå è òåïåðü ñîñòîèò èç 2-óõ ÷àñòåé,
; ñîäåðæàùèõ òîëüêî ñèìâîëû ðóññêîãî àëôàâèòà.
; ñèìâîëû â êîäèðîâêå ASCII (ÄÎÑ'îâñêàÿ), êîäîâàÿ ñòðàíèöà 866.
RU_FNT1:
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00
RU_FNT2:
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00
db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00
db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00
db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm/shutdown.inc
0,0 → 1,207
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Shutdown for Menuet ;;
;; ;;
;; Distributed under General Public License ;;
;; See file COPYING for details. ;;
;; Copyright 2003 Ville Turjanmaa ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
align 4
pr_mode_exit:
 
; setup stack
mov ax, 0x3000
mov ss, ax
mov esp, 0x0EC00
; setup ds
push cs
pop ds
 
lidt [old_ints_h]
;remap IRQs
mov al,0x11
out 0x20,al
call rdelay
out 0xA0,al
call rdelay
 
mov al,0x08
out 0x21,al
call rdelay
mov al,0x70
out 0xA1,al
call rdelay
 
mov al,0x04
out 0x21,al
call rdelay
mov al,0x02
out 0xA1,al
call rdelay
 
mov al,0x01
out 0x21,al
call rdelay
out 0xA1,al
call rdelay
 
mov al,0xB8
out 0x21,al
call rdelay
mov al,0xBD
out 0xA1,al
sti
 
temp_3456:
xor ax,ax
mov es,ax
mov al,byte [es:0x9030]
cmp al,1
jl nbw
cmp al,4
jle nbw32
 
nbw:
in al,0x60
cmp al,6
jae nbw
mov bl,al
nbw2:
in al,0x60
cmp al,bl
je nbw2
cmp al,240 ;ax,240
jne nbw31
mov al,bl
dec ax
jmp nbw32
nbw31:
add bl,128
cmp al,bl
jne nbw
sub al,129
 
nbw32:
 
dec ax
dec ax ; 2 = power off
jnz no_apm_off
call APM_PowerOff
jmp $
no_apm_off:
 
dec ax ; 3 = reboot
jnz restart_kernel ; 4 = restart kernel
push 0x40
pop ds
mov word[0x0072],0x1234
jmp 0xF000:0xFFF0
 
 
rdelay:
ret
 
APM_PowerOff:
mov ax, 5304h
xor bx, bx
int 15h
;!!!!!!!!!!!!!!!!!!!!!!!!
mov ax,0x5300
xor bx,bx
int 0x15
push ax
 
mov ax,0x5301
xor bx,bx
int 0x15
 
mov ax,0x5308
mov bx,1
mov cx,bx
int 0x15
 
mov ax,0x530E
xor bx,bx
pop cx
int 0x15
 
mov ax,0x530D
mov bx,1
mov cx,bx
int 0x15
 
mov ax,0x530F
mov bx,1
mov cx,bx
int 0x15
 
mov ax,0x5307
mov bx,1
mov cx,3
int 0x15
;!!!!!!!!!!!!!!!!!!!!!!!!
ret
 
restart_kernel:
 
mov ax,0x0003 ; set text mode for screen
int 0x10
jmp 0x4000:0000
 
restart_kernel_4000:
cli
 
push ds
pop es
mov cx, 0x8000
push cx
push 0x7000
pop ds
xor si, si
xor di, di
rep movsw
pop cx
mov ds, cx
push 0x2000
pop es
rep movsw
push 0x9000
pop ds
push 0x3000
pop es
mov cx, 0xE000/2
rep movsw
 
wbinvd ; write and invalidate cache
 
mov al, 00110100b
out 43h, al
jcxz $+2
mov al, 0xFF
out 40h, al
jcxz $+2
out 40h, al
jcxz $+2
sti
 
; (hint by Black_mirror)
; We must read data from keyboard port,
; because there may be situation when previous keyboard interrupt is lost
; (due to return to real mode and IRQ reprogramming)
; and next interrupt will not be generated (as keyboard waits for handling)
in al, 0x60
 
; bootloader interface
push 0x1000
pop ds
mov si, kernel_restart_bootblock
mov ax, 'KL'
jmp 0x1000:0000
 
 
/kernel/branches/Kolibri-acpi/sec_loader/trunk/kolibri_ldm
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/kernel/branches/Kolibri-acpi/sec_loader/trunk/loader.asm
0,0 → 1,317
; Copyright (c) 2008-2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
;start of the project 13.02.2008 year.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Secondary Loader copyright Alexey Teplov nickname <Lrz>
;if you need log preproc
;/////////////
;include 'listing.inc'
;enable listing
;////////////
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;start of code: ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
use16
org 0x0
jmp start
include 'sl_equ.inc' ; â ôàéëå ðàçìåùåíû âñå equ ïðåäîïðåäåëåíèÿ
include 'boot_st.inc'
include 'debug_msg.inc' ;here is message from debug
include 'parse_dat.inc'
include 'sl_proc.inc'
include 'parse.inc'
include 'parse_loader.inc'
include 'parse_any.inc'
include 'parse_def_sect.inc'
include 'parse_err.inc'
 
file_data dw 0x0,ini_data_ ;ôîðìàò: ñìåùåíèå: ñåãìåíò ò.ê. èñïîëüçóåòñÿ les
size_data dw 16 ;16 áëîêîâ ïî 4 êá ò.å ïðåäåë äî 64 êá
name_ini_f db 'kord/startos.ini',0
 
;////////////
loader_callback dd ?
load_drive dw ?
load_ft dw ?
;Start code
 
start:
; Save far pointer to callback procedure, ds:si is point
mov word [cs:loader_callback], si
mov word [cs:loader_callback+2], ds
; Save type of drive
mov word [cs:load_drive],ax
; Save type of FT
mov word [cs:load_ft],bx
; set up stack
mov ax, cs
mov ss, ax
xor sp, sp
; set up segment registers
mov ds,ax
mov es,ax
; just to be sure: force DF=0, IF=1
cld
sti
 
; set videomode
mov ax,3
int 0x10
 
mov si,version
call printplain
mov al,'#'
mov cx,80
;input cx=size al=char áóäåò âûâäåí ñèìâîë ñêîëüêî ðàç óêàçàíî â cx
@@:
call putchar
loop @b
 
if DEBUG
pushad
mov ax,cs
shl eax,4 ; â äåñÿòè÷íîé ñèñòåìå àäðåñ ñåãìåíòà
mov cx,0xa
mov di,cseg_msg
call decode
;***************
mov si,cseg_msg
call printplain
popad
end if
 
 
if DEBUG
mov si,stack_msg
call printplain
end if
 
; Require 586 or higher processor (cpuid and rdtsc,rdmsr/wrmsr commands)
; install int 6 (#UD) handler
xor bx, bx
mov ds, bx
push word [bx+6*4+2]
push word [bx+6*4]
mov word [bx+6*4], ud16
mov word [bx+6*4+2], cs
; issue CPUID command
xor eax, eax ; N.B.: will cause #UD before 386
cpuid ; N.B.: will cause #UD before later 486s
test eax, eax
jz cpubad
; get processor features
xor eax, eax
inc ax
cpuid
test dl, 10h ; CPUID[1].edx[4] - TSC support
jz cpubad
test dl, 20h ; CPUID[1].edx[5] - MSR support
jnz cpugood
 
ud16: ; #UD handler, called if processor did not recognize some commands
cpubad:
; restore int 6 (#UD) handler
pop word [6*4]
pop word [6*4+2]
; say error
push cs
pop ds
mov si, badprocessor
sayerr:
call printplain
jmp $
 
cpugood:
; restore int 6 (#UD) handler
pop dword [6*4]
push cs
pop ds
 
; set up esp
movzx esp, sp
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; init memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
 
 
; Load startos.ini
mov cx,loop_read_startos_file ;êîë-âî ïîïûòîê ÷òåíèÿ ôàéëà êîíôèãóðàöèè startos.ini
align 4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Load startos.ini ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
load_startos_file:
 
xor ax,ax
mov di,file_data
inc ax ;function 1 - read file
push cx
call far dword [loader_callback]
pop cx
push cs
push cs
pop ds
pop es
 
test bx,bx
jz check_conf_file
dec cx
jnz load_startos_file
 
;SET DEFAULT Not use ini file
error_ini:
mov si, error_ini_f1 ;Error: cannot load ini file, buffer is full
dec bx
jz err_show_ini
mov si, error_ini_f2 ;Error: ini file not found
dec bx
jz err_show_ini
mov si, error_ini_f3 ;Error: cannot read ini file
dec bx
jz err_show_ini
 
mov si, error_ini_nf ;Error: unrecognized error when loading ini file
err_show_ini:
call printplain
mov si, error_ini_common
call printplain
; wait for keypress
xor ax,ax
int 16h
 
ini_loaded:
 
jmp $
 
align 4
check_conf_file:
;Check config file in current dir
push ax ;save size file
if DEBUG
mov cx,0x0a
mov di,show_decode
call decode
;Show size
mov si,show_string
call printplain
end if
 
 
;Show message
mov si,load_ini
call printplain
 
pop cx ;restore size file
use_parse ;parsing startos.ini
;
jmp ini_loaded
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;DATA
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; table for move to extended memory (int 15h, ah=87h)
align 4
table_15_87:
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
 
db 0xff,0xff
db 0x0,0x10
db 0x00,0x93,0x0,0x0
 
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0
 
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
 
fat12_buffer:
.BS_jmpBoot db 0x90,0x90,0x90 ;3 áàéòà NOP èíñòðóêöèÿ - íè÷åãî íå äåëàòü
.BS_OEMName db 'K SyS 64' ;8 áàéò
.BPB_BytsPerSec dw 512 ;êîë-âî áàéòîâ â ñåêòîðå ìîæåò áûòü ëþáîå 512 1024 2048 4096 2 áàéòà
.BPB_SecPerClus db 0x1 ;êîë-âî ñåêòîðîâ â êëàñòåðå
.BPB_RsvdSecCnt dw 0x1 ;äëÿ FAt12/16 òîëüêî 1, äëÿ FAT32 îáû÷íî 32
.BPB_NumFATs db 0x1 ;êîë-âî ôàò òàáëèö, íà òîò ñëó÷àé åñëè áóäåò ñáðîñ íà äèñêåòó îáðàçà ðàì äèñêà
.BPB_RootEntCnt dw 512 ;äëÿ ìàê ñîâìåñòèìîñòè ñ fat16
.BPB_TotSec16 dw 0x0 ;êë-âî ñåêòîðîâ
.BPB_Media db 0xF0
.BPB_FATSz16 dw 0x0
.BPB_SecPerTrk dw 0x0 ;ñîäåðæèò ãåîìåòðèþ äèñêà äëÿ RAMFS íà êàê áû áåç ðàçíèöû, ïîêà ïóñòîå ïîëå, ïîçæå âíåñòè ðåàëüíûå çíà÷åíèÿ.
.BPB_NumHeads dw 0x0
.BPB_HiddSec dd 0x0 ;êîë-âî ñêðûòûõ ñåêòîðîâ
.BPB_TotSec32 dd 0x0
.BS_DrvNum db 'R' ;îò ñëîâà RAM
.BS_Reserved1 db 0x0
.BS_BootSig db 0x29
.BS_VolID db 'RFKS'
.BS_VolLab db 'RAM DISK FS' ;11 ñèìâîëîâ
.BS_FilSysType db 'FAT12 ' ;8 ñèìâîëîâ
;62 áàéòà ñòðóêòóðà fat12.
db (512-($-fat12_buffer))dup(0x90)
 
 
 
;ñòðóêòóðà äëÿ äèððåêòîðèè fat
struc FAT_32_entry ;Byte Directory Entry Structure
{
.DIR_Name rb 11
.DIR_Attr db ?
.DIR_NTRes db ?
.DIR_CrtTimeTenth db ?
.DIR_CrtTime dw ?
.DIR_CrtDate dw ?
.DIR_LstAccDate dw ?
.DIR_FstClusHI dw ?
.DIR_WrtTime dw ?
.DIR_WrtDate dw ?
.DIR_FstClusLO dw ?
.DIR_FileSize dd ?
 
 
}
;Òóò áóäóò ðàñïîëîãàòñüÿ äàííûå, êîòîðûå çàòðóäíèòåëüíî ðàñïîëîãàòü â ñòåêîâîé îáëàñòè....
;;;
;timer
shot_name_fat rb 11 ;âðåìåííûé áóôåð äëÿ fat12, â íåì õðàíÿòüñÿ èìåíà ôàéëîâ ïðèâåäåííûå ê ïðàâèëàì FAT /* âäàëüíåéøåì ïåðåíåñòè â ñòýê
 
if DEBUG
rb 1 ;íóæåí äëÿ îòëàäêè è âûâîäà èìåíè ôàéëà ïîñëå ïðåîáðàçîâàíèÿ
dest_name_fat db 24 dup('_');12
db 0x0
end if
 
value_timeout rw 1 ;value to timeout
old_timer rd 1 ;ñòàðîå çíà÷åíèå âåêòîðà òàéìåðà
start_timer rd 1 ;çíà÷åíèå òàéìåðà
timer_ rd 1 ;íîâîå çíà÷åíèå âåêòîðà òàéìåðà ò.å. SL
start_stack rw 1 ;save stack
save_bp_from_timer rw 1 ;save bp from timer
 
/kernel/branches/Kolibri-acpi/sec_loader/trunk/loader.lst
0,0 → 1,2147
flat assembler version 1.68 (65535 kilobytes memory)
0000: E9 E1 0A jmp start
0003: 53 65 63 6F 6E 64 61 72 79 20 4C 6F 61 version db 'Secondary Loader v 0.009', 0
0010: 64 65 72 20 76 20 30 2E 30 30 39 00
001C: 53 65 6C 65 63 74 20 73 65 63 74 69 6F select_section db 'Select section:'
0029: 6E 3A
002B: 53 65 63 74 69 6F 6E 20 64 65 73 63 72 section_description db 'Section description:'
0038: 69 70 74 69 6F 6E 3A
003F: 53 6F 66 74 20 28 63 29 20 32 30 30 38 soft_mes db 'Soft (c) 2008'
004C: 3E 46 61 74 61 6C 20 2D 20 43 50 55 20 badprocessor db '>Fatal - CPU 586+ required.', 0
0059: 35 38 36 2B 20 72 65 71 75 69 72 65 64
0066: 2E 00
0068: 3E 45 72 72 6F 72 3A 20 63 61 6E 6E 6F error_ini_f1 db '>Error: cannot load ini file, buffer is full', 0
0075: 74 20 6C 6F 61 64 20 69 6E 69 20 66 69
0082: 6C 65 2C 20 62 75 66 66 65 72 20 69 73
008F: 20 66 75 6C 6C 00
0095: 3E 45 72 72 6F 72 3A 20 69 6E 69 20 66 error_ini_f2 db '>Error: ini file not found', 0
00A2: 69 6C 65 20 6E 6F 74 20 66 6F 75 6E 64
00AF: 00
00B0: 3E 45 72 72 6F 72 3A 20 63 61 6E 6E 6F error_ini_f3 db '>Error: cannot read ini file', 0
00BD: 74 20 72 65 61 64 20 69 6E 69 20 66 69
00CA: 6C 65 00
00CD: 3E 45 72 72 6F 72 3A 20 75 6E 72 65 63 error_ini_nf db '>Error: unrecognized error when loading ini file', 0
00DA: 6F 67 6E 69 7A 65 64 20 65 72 72 6F 72
00E7: 20 77 68 65 6E 20 6C 6F 61 64 69 6E 67
00F4: 20 69 6E 69 20 66 69 6C 65 00
00FE: 3E 4E 6F 74 20 66 6F 75 6E 64 20 73 65 not_found_sec_loader db '>Not found section [loader]', 0
010B: 63 74 69 6F 6E 20 5B 6C 6F 61 64 65 72
0118: 5D 00
011A: 3E 4E 6F 74 20 66 6F 75 6E 64 20 76 61 not_found_def_sect db '>Not found value default in section [loader]', 0
0127: 6C 75 65 20 64 65 66 61 75 6C 74 20 69
0134: 6E 20 73 65 63 74 69 6F 6E 20 5B 6C 6F
0141: 61 64 65 72 5D 00
0147: 3E 45 72 72 6F 72 20 69 6E 20 73 65 63 default_eq_loader db '>Error in section [loader] parametr default=loader', 0
0154: 74 69 6F 6E 20 5B 6C 6F 61 64 65 72 5D
0161: 20 70 61 72 61 6D 65 74 72 20 64 65 66
016E: 61 75 6C 74 3D 6C 6F 61 64 65 72 00
017A: 3E 46 6F 75 6E 64 20 65 71 75 61 6C 20 found_equal_default db '>Found equal parametr default will be use first value', 0
0187: 70 61 72 61 6D 65 74 72 20 64 65 66 61
0194: 75 6C 74 20 77 69 6C 6C 20 62 65 20 75
01A1: 73 65 20 66 69 72 73 74 20 76 61 6C 75
01AE: 65 00
01B0: 3E 46 6F 75 6E 64 20 65 71 75 61 6C 20 found_equal_timeout db '>Found equal parametr timeout will be use first value', 0
01BD: 70 61 72 61 6D 65 74 72 20 74 69 6D 65
01CA: 6F 75 74 20 77 69 6C 6C 20 62 65 20 75
01D7: 73 65 20 66 69 72 73 74 20 76 61 6C 75
01E4: 65 00
01E6: 3E 53 65 63 74 69 6F 6E 20 74 69 6D 65 set_default_timeout_val db '>Section timeout has incorrect value, will be use default value', 0
01F3: 6F 75 74 20 68 61 73 20 69 6E 63 6F 72
0200: 72 65 63 74 20 76 61 6C 75 65 2C 20 77
020D: 69 6C 6C 20 62 65 20 75 73 65 20 64 65
021A: 66 61 75 6C 74 20 76 61 6C 75 65 00
0226: 3E 49 20 77 69 6C 6C 20 75 73 65 20 70 error_ini_common db '>I will use predefined settings and try to boot. Let's hope for the best...'
0233: 72 65 64 65 66 69 6E 65 64 20 73 65 74
0240: 74 69 6E 67 73 20 61 6E 64 20 74 72 79
024D: 20 74 6F 20 62 6F 6F 74 2E 20 4C 65 74
025A: 27 73 20 68 6F 70 65 20 66 6F 72 20 74
0267: 68 65 20 62 65 73 74 2E 2E 2E
0271: 0D 0A 50 72 65 73 73 20 61 6E 79 20 6B db 13, 10, 'Press any key to continue...', 0
027E: 65 79 20 74 6F 20 63 6F 6E 74 69 6E 75
028B: 65 2E 2E 2E 00
0290: 3E 49 6E 69 20 66 69 6C 65 20 6C 6F 61 load_ini db '>Ini file loaded successfully', 0
029D: 64 65 64 20 73 75 63 63 65 73 73 66 75
02AA: 6C 6C 79 00
02AE: 3E 45 6E 64 20 70 61 72 73 69 6E 67 20 parse_ini_end db '>End parsing ini file', 0
02BB: 69 6E 69 20 66 69 6C 65 00
02C4: 3E 50 6F 69 6E 74 20 74 6F 20 64 65 66 point_to_default_sec_not_found db '>Point to default section is not found in ini file', 0
02D1: 61 75 6C 74 20 73 65 63 74 69 6F 6E 20
02DE: 69 73 20 6E 6F 74 20 66 6F 75 6E 64 20
02EB: 69 6E 20 69 6E 69 20 66 69 6C 65 00
02F7: 3E 49 6E 63 6F 72 65 63 74 20 73 65 63 incorect_section_define db '>Incorect section define not found ']'', 0
0304: 74 69 6F 6E 20 64 65 66 69 6E 65 20 6E
0311: 6F 74 20 66 6F 75 6E 64 20 27 5D 27 00
031E: 22 53 65 63 74 69 6F 6E 20 75 6E 6E 61 default_section_name db '"Section unname"'
032B: 6D 65 22
032E: 50 72 65 73 73 20 61 6E 79 20 6B 65 79 start_msg db 'Press any key to change default section, press [Enter] to continue booting'
033B: 20 74 6F 20 63 68 61 6E 67 65 20 64 65
0348: 66 61 75 6C 74 20 73 65 63 74 69 6F 6E
0355: 2C 20 70 72 65 73 73 20 5B 45 6E 74 65
0362: 72 5D 20 74 6F 20 63 6F 6E 74 69 6E 75
036F: 65 20 62 6F 6F 74 69 6E 67
0378: 6F 72 20 77 61 69 74 20 34 20 73 65 63 time_msg db 'or wait 4 seconds before default continuation'
0385: 6F 6E 64 73 20 62 65 66 6F 72 65 20 64
0392: 65 66 61 75 6C 74 20 63 6F 6E 74 69 6E
039F: 75 61 74 69 6F 6E
03A5: 73 65 63 6F 6E 64 73 20 62 65 66 6F 72 time_str db 'seconds before default continuation'
03B2: 65 20 64 65 66 61 75 6C 74 20 63 6F 6E
03BF: 74 69 6E 75 61 74 69 6F 6E
03C8: 53 65 74 20 73 74 61 63 6B 20 26 20 73 stack_msg db 'Set stack & segments is have completed', 0
03D5: 65 67 6D 65 6E 74 73 20 69 73 20 68 61
03E2: 76 65 20 63 6F 6D 70 6C 65 74 65 64 00
03EF: 48 61 76 65 20 6C 6F 61 64 65 64 20 73 show_string db 'Have loaded size:'
03FC: 69 7A 65 3A
0400: 20 20 20 20 20 20 00 show_decode db ' ', 0
0407: 20 20 20 20 20 20 20 2D 4D 65 73 73 61 show_db1 db ' -Message debug1', 0
0414: 67 65 20 64 65 62 75 67 31 00
041E: 20 20 20 20 20 20 20 2D 4D 65 73 73 61 show_db2 db ' -Message debug2', 0
042B: 67 65 20 64 65 62 75 67 32 00
0435: 5B 6C 6F 61 64 65 72 5D 20 69 73 20 66 lm_l_found db '[loader] is found', 0
0442: 6F 75 6E 64 00
0447: 74 69 6D 65 6F 75 74 20 69 73 20 66 6F lm_lf_timeout db 'timeout is found', 0
0454: 75 6E 64 00
0458: 6E 61 6D 65 20 64 65 66 61 75 6C 74 20 lm_lf_default db 'name default is found and end parsing section', 0
0465: 69 73 20 66 6F 75 6E 64 20 61 6E 64 20
0472: 65 6E 64 20 70 61 72 73 69 6E 67 20 73
047F: 65 63 74 69 6F 6E 00
0486: 66 6F 75 6E 64 20 73 65 63 74 69 6F 6E lm_lf_section db 'found section [', 0
0493: 20 5B 00
0496: 66 6F 75 6E 64 20 64 65 66 61 75 6C 74 lm_lf_default_f db 'found default parametr', 0
04A3: 20 70 61 72 61 6D 65 74 72 00
04AD: 73 65 63 74 69 6F 6E 20 5B 6C 6F 61 64 lm_l_end db 'section [loader] is end', 0
04BA: 65 72 5D 20 69 73 20 65 6E 64 00
04C5: 53 48 4F 57 20 41 4C 4C 20 53 65 63 74 show_all_sect db 'SHOW ALL Sections', 0
04D2: 69 6F 6E 73 00
04D7: 4E 6F 74 20 73 68 6F 77 20 73 65 63 74 no_show_only_w db 'Not show sections - only work on default sect', 0
04E4: 69 6F 6E 73 20 2D 20 6F 6E 6C 79 20 77
04F1: 6F 72 6B 20 6F 6E 20 64 65 66 61 75 6C
04FE: 74 20 73 65 63 74 00
0505: 5B 20 6E 6F 74 20 66 6F 75 6E 64 00 _not_found db '[ not found', 0
0511: 5B 5D 20 66 6F 75 6E 64 00 _found_1 db '[] found', 0
051A: 5B 20 66 6F 75 6E 64 00 _found_2 db '[ found', 0
0522: 48 65 6C 6C 6F 20 24 29 00 say_hello db 'Hello $)', 0
052B: 53 74 61 72 74 20 75 73 65 5F 52 61 6D ramdiskFS_st db 'Start use_RamdiskFS macros', 0
0538: 64 69 73 6B 46 53 20 6D 61 63 72 6F 73
0545: 00
0546: 20 20 20 20 20 20 20 2D 4B 62 20 61 76 free_memory_msg db ' -Kb availability system free memory', 0
0553: 61 69 6C 61 62 69 6C 69 74 79 20 73 79
0560: 73 74 65 6D 20 66 72 65 65 20 6D 65 6D
056D: 6F 72 79 00
0571: 20 20 20 20 20 20 20 2D 4B 62 20 65 71 RamdiskSize_msg db ' -Kb equal RamdiskSize', 0
057E: 75 61 6C 20 52 61 6D 64 69 73 6B 53 69
058B: 7A 65 00
058E: 20 20 20 20 20 20 20 20 2D 62 79 74 73 RamdiskSector_msg db ' -byts RamdiskSector', 0
059B: 20 52 61 6D 64 69 73 6B 53 65 63 74 6F
05A8: 72 00
05AA: 20 20 20 20 20 20 20 2D 52 61 6D 64 69 RamdiskCluster_msg db ' -RamdiskCluster', 0
05B7: 73 6B 43 6C 75 73 74 65 72 00
05C1: 20 20 20 20 20 20 20 2D 73 69 7A 65 20 RamdiskFile_msg db ' -size RamdiskFile', 0
05CE: 52 61 6D 64 69 73 6B 46 69 6C 65 00
05DA: 20 20 20 20 20 20 20 2D 66 69 72 73 74 fat_create_msg db ' -first create fat table, point to next block', 0
05E7: 20 63 72 65 61 74 65 20 66 61 74 20 74
05F4: 61 62 6C 65 2C 20 70 6F 69 6E 74 20 74
0601: 6F 20 6E 65 78 74 20 62 6C 6F 63 6B 00
060E: 20 20 20 20 20 20 20 2D 69 6E 20 62 79 BPB_msg db ' -in byte, why we get data from move BPB struct', 0
061B: 74 65 2C 20 77 68 79 20 77 65 20 67 65
0628: 74 20 64 61 74 61 20 66 72 6F 6D 20 6D
0635: 6F 76 65 20 42 50 42 20 73 74 72 75 63
0642: 74 00
0644: 20 20 20 20 20 20 20 2D 66 69 72 73 74 firstDataSect_msg db ' -first data sector, offset to data in sectors', 0
0651: 20 64 61 74 61 20 73 65 63 74 6F 72 2C
065E: 20 6F 66 66 73 65 74 20 74 6F 20 64 61
066B: 74 61 20 69 6E 20 73 65 63 74 6F 72 73
0678: 00
0679: 20 20 20 20 20 20 20 2D 73 69 7A 65 20 size_root_dir_msg db ' -size root dir in sectrors', 0
0686: 72 6F 6F 74 20 64 69 72 20 69 6E 20 73
0693: 65 63 74 72 6F 72 73 00
069B: 20 20 20 20 20 20 20 2D 73 69 7A 65 20 DataClasters_msg db ' -size data in Clasters', 0
06A8: 64 61 74 61 20 69 6E 20 43 6C 61 73 74
06B5: 65 72 73 00
06B9: 20 20 20 20 20 20 20 2D 69 66 20 2D 31 check_name_fat_msg db ' -if -1 name is present, else 0 then not present name', 0
06C6: 20 6E 61 6D 65 20 69 73 20 70 72 65 73
06D3: 65 6E 74 2C 20 65 6C 73 65 20 30 20 74
06E0: 68 65 6E 20 6E 6F 74 20 70 72 65 73 65
06ED: 6E 74 20 6E 61 6D 65 00
06F5: 20 20 20 20 20 20 20 2D 69 66 20 2D 31 convertion_file_name_msg db ' -if -1, then destination name is bad', 0
0702: 2C 20 74 68 65 6E 20 64 65 73 74 69 6E
070F: 61 74 69 6F 6E 20 6E 61 6D 65 20 69 73
071C: 20 62 61 64 00
0721: 2D 4D 61 6B 65 20 46 41 54 31 32 20 52 make_fat12_RFS_msg db '-Make FAT12 Ram FS', 0
072E: 61 6D 20 46 53 00
0734: 2D 45 6E 64 20 6D 61 6B 65 20 52 61 6D get_type_FS_msg db '-End make RamDisk', 0
0741: 44 69 73 6B 00
0746: 20 20 20 20 2D 72 65 74 75 72 6E 20 63 return_code_af_move db ' -return code after 0x87 int 0x15, move block', 0
0753: 6F 64 65 20 61 66 74 65 72 20 30 78 38
0760: 37 20 69 6E 74 20 30 78 31 35 2C 20 6D
076D: 6F 76 65 20 62 6C 6F 63 6B 00
0777: 20 20 20 20 2D 72 65 74 75 72 6E 20 63 return_code_af_fat_m db ' -return code after 0x87 int 0x15, move fat struc', 0
0784: 6F 64 65 20 61 66 74 65 72 20 30 78 38
0791: 37 20 69 6E 74 20 30 78 31 35 2C 20 6D
079E: 6F 76 65 20 66 61 74 20 73 74 72 75 63
07AB: 00
07AC: 5B 6C 6F 61 64 65 72 5D parse_loader db '[loader]'
07B4: 74 69 6D 65 6F 75 74 parse_l_timeout db 'timeout'
07BB: 64 65 66 61 75 6C 74 parse_l_default db 'default'
07C2: 61 6D 65 parse_name db 'ame'
07C5: 64 65 73 63 72 69 70 74 parse_descript db 'descript'
07CD: 4C 6F 61 64 65 72 4D 6F 64 75 6C 65 parse_LoaderModule db 'LoaderModule'
07D9: 52 61 6D 64 69 73 6B 53 69 7A 65 parse_RamdiskSize db 'RamdiskSize'
07E4: 52 61 6D 64 69 73 6B 46 53 parse_RamdiskFS db 'RamdiskFS'
07ED: 52 61 6D 64 69 73 6B 53 65 63 74 6F 72 parse_RamdiskSector db 'RamdiskSector'
07FA: 52 61 6D 64 69 73 6B 43 6C 75 73 74 65 parse_RamdiskCluster db 'RamdiskCluster'
0807: 72
0808: 46 41 54 parse_RFS_FAT db 'FAT'
080B: 4B 52 46 53 parse_RFS_KRFS db 'KRFS'
080F: 4C 6F 61 64 65 72 49 6D 61 67 65 parse_Loader_Image db 'LoaderImage'
081A: 52 61 6D 64 69 73 6B 46 69 6C 65 parse_RamdiskFile db 'RamdiskFile'
0825: 66 39 C8 cmp eax, ecx
0828: 72 0D jb @f
082A: 66 31 D2 xor edx, edx
082D: 66 F7 F1 div ecx
0830: 66 52 push edx
0832: E8 F0 FF call decode
0835: 66 58 pop eax
0837: 0C 30 or al, 0x30
0839: 88 05 mov [ ds : di ], al
083B: 47 inc di
083C: C3 ret
083D: B4 0E mov ah, 0Eh
083F: B7 00 mov bh, 0
0841: CD 10 int 10h
0843: C3 ret
0844: 60 pusha
0845: AC lodsb
0846: E8 F4 FF call putchar
0849: AC lodsb
084A: 3C 00 cmp al, 0
084C: 75 F8 jnz @b
084E: B0 0D mov al, 13
0850: E8 EA FF call putchar
0853: B0 0A mov al, 10
0855: E8 E5 FF call putchar
0858: 61 popa
0859: C3 ret
085A: B4 00 mov ah, 0
085C: CD 16 int 16h
085E: 38 D8 cmp al, bl
0860: 72 F8 jb getkey
0862: 38 F8 cmp al, bh
0864: 77 F4 ja getkey
0866: 50 push ax
0867: E8 D3 FF call putchar
086A: 58 pop ax
086B: 83 E0 0F and ax, 0Fh
086E: 75 02 jnz @f
0870: B0 0A mov al, 10
0872: C3 ret
0873: 26 8A 05 mov al, byte [ es : di ]
0876: 47 inc di
0877: 49 dec cx
0878: E3 20 jcxz .exit
087A: 3C 0A cmp al, 0xa
087C: 74 0A jz ._entry
087E: 3C 3B cmp al, ';'
0880: 75 F1 jnz .start
0882: B0 0A mov al, 0xa
0884: F2 repnz
0885: AE scasb
0886: E3 12 jcxz .exit
0888: 26 8A 05 mov al, byte [ es : di ]
088B: 3C 20 cmp al, ' '
088D: 75 07 jnz .not_space
088F: F3 repe
0890: AE scasb
0891: 4F dec di
0892: 41 inc cx
0893: 26 8A 05 mov al, byte [ es : di ]
0896: 3C 3B cmp al, ';'
0898: 74 E8 jz .first_com
089A: C3 ret
089B: 56 push si
089C: 68 00 20 push ini_data_
089F: 07 pop es
08A0: B0 5D mov al, ']'
08A2: F2 repnz
08A3: AE scasb
08A4: 85 C9 test cx, cx
08A6: 0F 84 0F 02 jz error.incorect_section_def
08AA: B0 6E mov al, 'n'
08AC: F2 repnz
08AD: AE scasb
08AE: E3 69 jcxz .not_name_sec_fb
08B0: BE C2 07 mov si, parse_name
08B3: 51 push cx
08B4: 57 push di
08B5: B9 03 00 mov cx, parse_name_e - parse_name
08B8: F3 repe
08B9: A6 cmpsb
08BA: 5F pop di
08BB: 59 pop cx
08BC: 74 02 jz .yaaa_find_value
08BE: EB EC jmp .find_val_name_fb
08C0: 83 E9 03 sub cx, parse_name_e - parse_name
08C3: 83 C7 03 add di, parse_name_e - parse_name
08C6: B8 20 3D mov ax, 0x3d20
08C9: F3 repe
08CA: AE scasb
08CB: 85 C9 test cx, cx
08CD: 74 4A jz .not_name_sec_fb
08CF: 26 3A 65 FF cmp ah, byte [ es : di - 1 ]
08D3: 75 D5 jnz .find_val_name_fb1
08D5: F3 repe
08D6: AE scasb
08D7: 41 inc cx
08D8: 4F dec di
08D9: 06 push es
08DA: 1F pop ds
08DB: 68 00 B8 push 0xb800
08DE: 07 pop es
08DF: 31 C0 xor ax, ax
08E1: B8 20 07 mov ax, 0x0720
08E4: B9 27 00 mov cx, 39
08E7: 89 FE mov si, di
08E9: 89 D7 mov di, dx
08EB: 83 EF 02 sub di, 2
08EE: F3 rep
08EF: AB stosw
08F0: 89 D7 mov di, dx
08F2: B4 0F mov ah, color_sym_white
08F4: B9 24 00 mov cx, 36
08F7: AC lodsb
08F8: 83 EF 02 sub di, 2
08FB: 3C 22 cmp al, '"'
08FD: 74 04 jz @f
08FF: 3C 27 cmp al, '''
0901: 75 12 jnz .end_sh_name_sec
0903: AC lodsb
0904: AB stosw
0905: AC lodsb
0906: 3C 22 cmp al, '"'
0908: 74 0B jz .end_sh_name_sec
090A: 3C 27 cmp al, '''
090C: 74 07 jz .end_sh_name_sec
090E: E2 F4 loop @b
0910: B0 7D mov al, '}'
0912: B4 0E mov ah, color_sym_yellow
0914: AB stosw
0915: 0E push cs
0916: 1F pop ds
0917: 5E pop si
0918: C3 ret
0919: 0E push cs
091A: 1F pop ds
091B: BF 1E 03 mov di, default_section_name
091E: EB BB jmp .def_sect_name
0920: 8B 7E F4 mov di, point_default
0923: 68 00 20 push ini_data_
0926: 07 pop es
0927: 89 F9 mov cx, di
0929: 89 CB mov bx, cx
092B: FD std
092C: B0 0A mov al, 0xa
092E: F2 repnz
092F: AE scasb
0930: E3 25 jcxz .go_
0932: 89 7E C6 mov find_sec_di, di
0935: 89 F9 mov cx, di
0937: 29 CB sub bx, cx
0939: 89 D9 mov cx, bx
093B: FC cld
093C: E8 34 FF call get_firs_sym
093F: E3 0D jcxz ._not_section
0941: 3B 7E F6 cmp di, point_loader
0944: 74 08 jz ._not_section
0946: 3C 5B cmp al, '['
0948: 75 04 jnz ._not_section
094A: 89 7E F4 mov point_default, di
094D: C3 ret
094E: 8B 7E C6 mov di, find_sec_di
0951: 89 F9 mov cx, di
0953: 89 CB mov bx, cx
0955: EB D4 jmp .find_start_section
0957: FC cld
0958: 89 D9 mov cx, bx
095A: 26 8A 05 mov al, byte [ es : di ]
095D: 68 6A 09 push word .f_go
0960: 3C 20 cmp al, ' '
0962: 74 03 jz @f
0964: E9 2F FF jmp get_firs_sym.not_space
0967: E9 21 FF jmp get_firs_sym.first_sp
096A: E3 E1 jcxz .exit_scan_sect
096C: 3B 7E F6 cmp di, point_loader
096F: 74 DC jz .exit_scan_sect
0971: 3C 5B cmp al, '['
0973: 75 D8 jnz .exit_scan_sect
0975: 89 7E F4 mov point_default, di
0978: C3 ret
0979: 8B 7E F4 mov di, point_default
097C: 68 00 20 push ini_data_
097F: 07 pop es
0980: 8B 4E FE mov cx, save_cx
0983: 29 F9 sub cx, di
0985: EB 17 jmp .let_s_go
0987: 68 00 20 push ini_data_
098A: 07 pop es
098B: 8B 4E FE mov cx, save_cx
098E: 26 8A 05 mov al, byte [ es : di ]
0991: 68 A1 09 push word .let_s_go_ret
0994: 3C 20 cmp al, ' '
0996: 74 03 jz @f
0998: E9 FB FE jmp get_firs_sym.not_space
099B: E9 ED FE jmp get_firs_sym.first_sp
099E: E8 D2 FE call get_firs_sym
09A1: E3 0C jcxz .exit_scan_sect
09A3: 3C 5B cmp al, '['
09A5: 75 F7 jnz .let_s_go
09A7: 3B 7E F6 cmp di, point_loader
09AA: 74 F2 jz .let_s_go
09AC: 89 7E F4 mov point_default, di
09AF: C3 ret
09B0: 8D 76 F2 lea si, point_to_hframe
09B3: BF 22 03 mov di, 962 - 160
09B6: 8B 56 F4 mov dx, point_default
09B9: B9 12 00 mov cx, 18
09BC: 8B 1C mov bx, [ si ]
09BE: 81 C7 A0 00 add di, 160
09C2: 39 D3 cmp bx, dx
09C4: 74 05 jz .clean_cursor_
09C6: 83 EE 02 sub si, 2
09C9: E2 F1 loop .clean_show_cur
09CB: 68 00 B8 push 0xb800
09CE: 07 pop es
09CF: 50 push ax
09D0: 89 76 CA mov point_to_point_def, si
09D3: 31 C0 xor ax, ax
09D5: B8 20 07 mov ax, 0x0720
09D8: AB stosw
09D9: 83 C7 44 add di, 68
09DC: AB stosw
09DD: 58 pop ax
09DE: C3 ret
09DF: B4 00 mov ah, 0
09E1: CD 1A int 1Ah
09E3: 91 xchg ax, cx
09E4: 66 C1 E0 10 shl eax, 10h
09E8: 92 xchg ax, dx
09E9: C3 ret
09EA: 1E push ds
09EB: 0E push cs
09EC: 1F pop ds
09ED: 9C pushf
09EE: FF 1E D4 1A call far dword [ old_timer ]
09F2: 66 60 pushad
09F4: E8 E8 FF call gettime
09F7: 66 2B 06 D8 1A sub eax, dword [ start_timer ]
09FC: 8B 1E D2 1A mov bx, word [ value_timeout ]
0A00: 6B DB 12 imul bx, 18
0A03: 29 C3 sub bx, ax
0A05: 76 1F jbe .timergo
0A07: 06 push es
0A08: 68 00 B8 push 0xb800
0A0B: 07 pop es
0A0C: 89 D8 mov ax, bx
0A0E: BB 12 00 mov bx, 18
0A11: 31 D2 xor dx, dx
0A13: F7 F3 div bx
0A15: BB 0A 00 mov bx, 10
0A18: BF 96 0E mov di, 3734
0A1B: E8 24 00 call .decode
0A1E: 31 C0 xor ax, ax
0A20: AB stosw
0A21: 07 pop es
0A22: 66 61 popad
0A24: 1F pop ds
0A25: CF iret
0A26: 6A 00 push 0
0A28: 07 pop es
0A29: 66 A1 D4 1A mov eax, dword [ old_timer ]
0A2D: 26 66 A3 20 00 mov [ es : 8 * 4 ], eax
0A32: 66 A3 DC 1A mov dword [ timer_ ], eax
0A36: 8B 26 E0 1A mov sp, word [ start_stack ]
0A3A: 8B 2E E2 1A mov bp, word [ save_bp_from_timer ]
0A3E: FB sti
0A3F: E9 D8 06 jmp parse_start.parse_run_only
0A42: 39 D8 cmp ax, bx
0A44: 72 09 jb @f
0A46: 31 D2 xor dx, dx
0A48: F7 F3 div bx
0A4A: 52 push dx
0A4B: E8 F4 FF call .decode
0A4E: 58 pop ax
0A4F: 0C 30 or al, 0x30
0A51: 50 push ax
0A52: B4 09 mov ah, 9
0A54: AB stosw
0A55: 58 pop ax
0A56: C3 ret
0A57: 8B 5E C8 mov bx, point_to_eframe
0A5A: 8D 76 F2 lea si, point_to_hframe
0A5D: BA C6 03 mov dx, 966
0A60: 39 DE cmp si, bx
0A62: 72 12 jb ._show_space_fb
0A64: 8B 3C mov di, [ si ]
0A66: 83 EE 02 sub si, 2
0A69: 8B 0C mov cx, [ si ]
0A6B: 29 F9 sub cx, di
0A6D: E8 2B FE call show_name_section
0A70: 81 C2 A0 00 add dx, 160
0A74: EB EA jmp .home_show_fb
0A76: 83 EA 04 sub dx, 4
0A79: 68 00 B8 push 0xb800
0A7C: 07 pop es
0A7D: 81 FA 64 0E cmp dx, 0xE64
0A81: 77 12 ja .exit_show_fb
0A83: 89 D7 mov di, dx
0A85: 31 C0 xor ax, ax
0A87: B8 20 07 mov ax, 0x0720
0A8A: B9 27 00 mov cx, 39
0A8D: F3 rep
0A8E: AB stosw
0A8F: 81 C2 A0 00 add dx, 160
0A93: EB E8 jmp @b
0A95: C3 ret
0A96: 89 C7 mov di, ax
0A98: 89 D9 mov cx, bx
0A9A: FF 66 FC jmp ret_on_ch
0A9D: C9 leave
0A9E: BE 1A 01 mov si, not_found_def_sect
0AA1: E9 F4 00 jmp err_show_ini
0AA4: C9 leave
0AA5: BE FE 00 mov si, not_found_sec_loader
0AA8: E9 ED 00 jmp err_show_ini
0AAB: C9 leave
0AAC: BE 47 01 mov si, default_eq_loader
0AAF: E9 E6 00 jmp err_show_ini
0AB2: C9 leave
0AB3: BE C4 02 mov si, point_to_default_sec_not_found
0AB6: E9 DF 00 jmp err_show_ini
0AB9: C9 leave
0ABA: BE F7 02 mov si, incorect_section_define
0ABD: E9 D8 00 jmp err_show_ini
0AC0: 68 00 B8 push word 0xb800
0AC3: 07 pop es
0AC4: C3 ret
0AC5: 00 00 00 20 file_data dw 0x0, ini_data_
0AC9: 10 00 size_data dw 16
0ACB: 6B 6F 72 64 2F 73 74 61 72 74 6F 73 2E name_ini_f db 'kord/startos.ini', 0
0AD8: 69 6E 69 00
0ADC: 00 00 00 00 loader_callback dd ?
0AE0: 00 00 load_drive dw ?
0AE2: 00 00 load_ft dw ?
0AE4: 2E 89 36 DC 0A mov word [ cs : loader_callback ], si
0AE9: 2E 8C 1E DE 0A mov word [ cs : loader_callback + 2 ], ds
0AEE: 2E A3 E0 0A mov word [ cs : load_drive ], ax
0AF2: 2E 89 1E E2 0A mov word [ cs : load_ft ], bx
0AF7: 8C C8 mov ax, cs
0AF9: 8E D0 mov ss, ax
0AFB: 31 E4 xor sp, sp
0AFD: 8E D8 mov ds, ax
0AFF: 8E C0 mov es, ax
0B01: FC cld
0B02: FB sti
0B03: B8 03 00 mov ax, 3
0B06: CD 10 int 0x10
0B08: BE 03 00 mov si, version
0B0B: E8 36 FD call printplain
0B0E: B0 23 mov al, '#'
0B10: B9 50 00 mov cx, 80
0B13: E8 27 FD call putchar
0B16: E2 FB loop @b
0B18: BE C8 03 mov si, stack_msg
0B1B: E8 26 FD call printplain
0B1E: 31 DB xor bx, bx
0B20: 8E DB mov ds, bx
0B22: FF 77 1A push word [ bx + 6 * 4 + 2 ]
0B25: FF 77 18 push word [ bx + 6 * 4 ]
0B28: C7 47 18 4A 0B mov word [ bx + 6 * 4 ], ud16
0B2D: 8C 4F 1A mov word [ bx + 6 * 4 + 2 ], cs
0B30: 66 31 C0 xor eax, eax
0B33: 0F A2 cpuid
0B35: 66 85 C0 test eax, eax
0B38: 74 10 jz cpubad
0B3A: 66 31 C0 xor eax, eax
0B3D: 40 inc ax
0B3E: 0F A2 cpuid
0B40: F6 C2 10 test dl, 10h
0B43: 74 05 jz cpubad
0B45: F6 C2 20 test dl, 20h
0B48: 75 12 jnz cpugood
0B4A: 8F 06 18 00 pop word [ 6 * 4 ]
0B4E: 8F 06 1A 00 pop word [ 6 * 4 + 2 ]
0B52: 0E push cs
0B53: 1F pop ds
0B54: BE 4C 00 mov si, badprocessor
0B57: E8 EA FC call printplain
0B5A: EB FE jmp $
0B5C: 66 8F 06 18 00 pop dword [ 6 * 4 ]
0B61: 0E push cs
0B62: 1F pop ds
0B63: 66 0F B7 E4 movzx esp, sp
0B67: B9 03 00 mov cx, loop_read_startos_file
0B6C: 31 C0 xor ax, ax
0B6E: BF C5 0A mov di, file_data
0B71: 40 inc ax
0B72: 51 push cx
0B73: FF 1E DC 0A call far dword [ loader_callback ]
0B77: 59 pop cx
0B78: 0E push cs
0B79: 0E push cs
0B7A: 1F pop ds
0B7B: 07 pop es
0B7C: 85 DB test bx, bx
0B7E: 74 28 jz check_conf_file
0B80: 49 dec cx
0B81: 75 E9 jnz load_startos_file
0B83: BE 68 00 mov si, error_ini_f1
0B86: 4B dec bx
0B87: 74 0F jz err_show_ini
0B89: BE 95 00 mov si, error_ini_f2
0B8C: 4B dec bx
0B8D: 74 09 jz err_show_ini
0B8F: BE B0 00 mov si, error_ini_f3
0B92: 4B dec bx
0B93: 74 03 jz err_show_ini
0B95: BE CD 00 mov si, error_ini_nf
0B98: E8 A9 FC call printplain
0B9B: BE 26 02 mov si, error_ini_common
0B9E: E8 A3 FC call printplain
0BA1: 31 C0 xor ax, ax
0BA3: CD 16 int 16h
0BA5: EB FE jmp $
0BA8: 50 push ax
0BA9: B9 0A 00 mov cx, 0x0a
0BAC: BF 00 04 mov di, show_decode
0BAF: E8 73 FC call decode
0BB2: BE EF 03 mov si, show_string
0BB5: E8 8C FC call printplain
0BB8: BE 90 02 mov si, load_ini
0BBB: E8 86 FC call printplain
0BBE: 59 pop cx
0BBF: C8 00 01 00 enter 256, 0
0BC3: 89 2E E2 1A mov word [ save_bp_from_timer ], bp
0BC7: 89 4E FE mov save_cx, cx
0BCA: C4 3E C5 0A les di, dword [ file_data ]
0BCE: 31 C0 xor ax, ax
0BD0: 89 46 F8 mov status_flag, ax
0BD3: C7 46 C4 00 30 mov info_real_mode_size, ini_data_ + 0x1000
0BD8: FC cld
0BD9: C7 46 FC EE 0B mov ret_on_ch, .start
0BDE: 26 8A 05 mov al, byte [ es : di ]
0BE1: 68 F1 0B push word .first_ret
0BE4: 3C 20 cmp al, ' '
0BE6: 74 03 jz .first_sp_1
0BE8: E9 AB FC jmp get_firs_sym.not_space
0BEB: E9 9D FC jmp get_firs_sym.first_sp
0BEE: E8 82 FC call get_firs_sym
0BF1: 85 C9 test cx, cx
0BF3: 0F 84 AD FE jz error.not_loader
0BF7: 3C 5B cmp al, '['
0BF9: 74 02 jz .parse_loader
0BFB: EB F1 jmp .start
0BFD: 89 CB mov bx, cx
0BFF: 89 F8 mov ax, di
0C01: BE AC 07 mov si, parse_loader
0C04: B9 08 00 mov cx, parse_loader_e - parse_loader
0C07: F3 repe
0C08: A6 cmpsb
0C09: 0F 85 89 FE jnz error.rest_value
0C0D: 89 46 F6 mov point_loader, ax
0C10: 83 EB 08 sub bx, parse_loader_e - parse_loader
0C13: 01 CB add bx, cx
0C15: 89 D9 mov cx, bx
0C17: 60 pusha
0C18: BE 35 04 mov si, lm_l_found
0C1B: E8 26 FC call printplain
0C1E: 61 popa
0C1F: 89 FA mov dx, di
0C21: E8 4F FC call get_firs_sym
0C24: E3 04 jcxz .loader_f_end
0C26: 3C 5B cmp al, '['
0C28: 75 F7 jnz @b
0C2A: 29 CB sub bx, cx
0C2C: 89 D7 mov di, dx
0C2E: 89 D9 mov cx, bx
0C30: C7 46 FC 35 0C mov ret_on_ch, .get_next_str
0C35: E8 3B FC call get_firs_sym
0C38: 85 C9 test cx, cx
0C3A: 0F 84 57 01 jz .end_loader
0C3E: 3C 74 cmp al, 't'
0C40: 0F 84 DE 00 jz .loader_timeout
0C44: 3C 64 cmp al, 'd'
0C46: 75 ED jnz .get_next_str
0C48: 89 CB mov bx, cx
0C4A: 89 F8 mov ax, di
0C4C: BE BB 07 mov si, parse_l_default
0C4F: B9 07 00 mov cx, parse_l_default_e - parse_l_default
0C52: F3 repe
0C53: A6 cmpsb
0C54: 0F 85 3E FE jnz error.rest_value
0C58: 83 EB 07 sub bx, parse_l_default_e - parse_l_default
0C5B: 01 CB add bx, cx
0C5D: 89 D9 mov cx, bx
0C5F: F7 46 F8 01 00 test status_flag, flag_found_default
0C64: 74 08 jz .correct_is_not_set
0C66: BE 7A 01 mov si, found_equal_default
0C69: E8 D8 FB call printplain
0C6C: EB C7 jmp .get_next_str
0C6E: B8 20 3D mov ax, 0x3d20
0C71: F3 repe
0C72: AE scasb
0C73: 85 C9 test cx, cx
0C75: 0F 84 1C 01 jz .end_loader
0C79: 26 3A 65 FF cmp ah, byte [ es : di - 1 ]
0C7D: 75 B6 jnz .get_next_str
0C7F: F3 repe
0C80: AE scasb
0C81: 41 inc cx
0C82: 4F dec di
0C83: 89 CB mov bx, cx
0C85: 89 FA mov dx, di
0C87: 26 8A 05 mov al, byte [ es : di ]
0C8A: 47 inc di
0C8B: 49 dec cx
0C8C: 85 C9 test cx, cx
0C8E: 0F 84 0B FE jz error.error_get_size_d_sect
0C92: 3C 20 cmp al, ' '
0C94: 74 F1 jz @b
0C96: 3C 0D cmp al, 0xd
0C98: 74 04 jz .found_size_d_sect
0C9A: 3C 0A cmp al, 0xa
0C9C: 75 E9 jnz @b
0C9E: 41 inc cx
0C9F: 89 D8 mov ax, bx
0CA1: 29 CB sub bx, cx
0CA3: 89 5E FA mov save_cx_d, bx
0CA6: 89 D7 mov di, dx
0CA8: 89 D9 mov cx, bx
0CAA: 89 C3 mov bx, ax
0CAC: 89 D0 mov ax, dx
0CAE: BE AC 07 mov si, parse_loader
0CB1: 46 inc si
0CB2: F3 repe
0CB3: A6 cmpsb
0CB4: 75 03 jnz .check_section
0CB6: E9 F2 FD jmp error.default_eq_loader
0CB9: 89 D9 mov cx, bx
0CBB: 89 C7 mov di, ax
0CBD: 89 FE mov si, di
0CBF: 57 push di
0CC0: 51 push cx
0CC1: 8B 4E FE mov cx, save_cx
0CC4: C4 3E C5 0A les di, dword [ file_data ]
0CC8: 26 8A 05 mov al, byte [ es : di ]
0CCB: 68 DB 0C push word .first_ret_d
0CCE: 3C 20 cmp al, ' '
0CD0: 74 03 jz .first_sp_1_d
0CD2: E9 C1 FB jmp get_firs_sym.not_space
0CD5: E9 B3 FB jmp get_firs_sym.first_sp
0CD8: E8 98 FB call get_firs_sym
0CDB: E3 38 jcxz .correct_exit
0CDD: 3C 5B cmp al, '['
0CDF: 74 02 jz .found_sect_d
0CE1: EB F5 jmp .start_d
0CE3: 89 CB mov bx, cx
0CE5: 89 F8 mov ax, di
0CE7: 56 push si
0CE8: 8B 4E FA mov cx, save_cx_d
0CEB: 06 push es
0CEC: 1F pop ds
0CED: 47 inc di
0CEE: F3 repe
0CEF: A6 cmpsb
0CF0: 0E push cs
0CF1: 1F pop ds
0CF2: 5E pop si
0CF3: 75 1A jnz .not_compare_d_s
0CF5: 26 80 3D 5D cmp byte [ es : di ], ']'
0CF9: 75 14 jnz .not_compare_d_s
0CFB: 83 4E F8 01 or status_flag, flag_found_default
0CFF: 59 pop cx
0D00: 5F pop di
0D01: 89 46 F4 mov point_default, ax
0D04: 60 pusha
0D05: BE 96 04 mov si, lm_lf_default_f
0D08: E8 39 FB call printplain
0D0B: 61 popa
0D0C: E9 26 FF jmp .get_next_str
0D0F: 89 D9 mov cx, bx
0D11: 89 C7 mov di, ax
0D13: EB C3 jmp .start_d
0D15: 59 pop cx
0D16: 5F pop di
0D17: 60 pusha
0D18: BE 58 04 mov si, lm_lf_default
0D1B: E8 26 FB call printplain
0D1E: 61 popa
0D1F: E9 13 FF jmp .get_next_str
0D22: 89 CB mov bx, cx
0D24: 89 F8 mov ax, di
0D26: BE B4 07 mov si, parse_l_timeout
0D29: B9 07 00 mov cx, parse_l_timeout_e - parse_l_timeout
0D2C: F3 repe
0D2D: A6 cmpsb
0D2E: 0F 85 64 FD jnz error.rest_value
0D32: 83 EB 07 sub bx, parse_l_timeout_e - parse_l_timeout
0D35: 01 CB add bx, cx
0D37: 89 D9 mov cx, bx
0D39: F7 46 F8 02 00 test status_flag, flag_found_timeout
0D3E: 74 09 jz .correct_is_not_set_t
0D40: BE B0 01 mov si, found_equal_timeout
0D43: E8 FE FA call printplain
0D46: E9 EC FE jmp .get_next_str
0D49: B8 20 3D mov ax, 0x3d20
0D4C: F3 repe
0D4D: AE scasb
0D4E: E3 35 jcxz .timeout_sec_end_d
0D50: 26 3A 65 FF cmp ah, byte [ es : di - 1 ]
0D54: 0F 85 DD FE jnz .get_next_str
0D58: F3 repe
0D59: AE scasb
0D5A: 41 inc cx
0D5B: 4F dec di
0D5C: 51 push cx
0D5D: 31 DB xor bx, bx
0D5F: B9 02 00 mov cx, 2
0D62: 26 8A 05 mov al, byte [ es : di ]
0D65: 3C 30 cmp al, '0'
0D67: 72 0B jb .end_get_val_t
0D69: 3C 39 cmp al, '9'
0D6B: 77 07 ja .end_get_val_t
0D6D: 6B DB 0A imul bx, 10
0D70: 34 30 xor al, 0x30
0D72: 00 C3 add bl, al
0D74: 47 inc di
0D75: E2 EB loop @b
0D77: 89 1E D2 1A mov word [ value_timeout ], bx
0D7B: 60 pusha
0D7C: BE 47 04 mov si, lm_lf_timeout
0D7F: E8 C2 FA call printplain
0D82: 61 popa
0D83: EB 0C jmp @f
0D85: C7 06 D2 1A 05 00 mov word [ value_timeout ], default_timeout_value
0D8B: BE E6 01 mov si, set_default_timeout_val
0D8E: E8 B3 FA call printplain
0D91: 59 pop cx
0D92: E9 A0 FE jmp .get_next_str
0D95: 60 pusha
0D96: BE AD 04 mov si, lm_l_end
0D99: E8 A8 FA call printplain
0D9C: 61 popa
0D9D: 31 C0 xor ax, ax
0D9F: CD 16 int 16h
0DA1: 60 pusha
0DA2: A1 D2 1A mov ax, word [ value_timeout ]
0DA5: B9 0A 00 mov cx, 0x0a
0DA8: BF 07 04 mov di, show_db1
0DAB: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' '
0DB2: C7 45 04 20 20 mov word [ ds : di + 4 ], ' '
0DB7: E8 6B FA call decode
0DBA: BE 07 04 mov si, show_db1
0DBD: E8 84 FA call printplain
0DC0: 61 popa
0DC1: 85 C0 test ax, ax
0DC3: 0F 84 53 03 jz .parse_run_only
0DC7: 60 pusha
0DC8: BE C5 04 mov si, show_all_sect
0DCB: E8 76 FA call printplain
0DCE: 61 popa
0DCF: B0 F6 mov al, 0xf6
0DD1: E6 60 out 0x60, al
0DD3: 31 C9 xor cx, cx
0DD5: E4 64 in al, 64h
0DD7: 24 02 and al, 00000010b
0DD9: E0 FA loopnz .wait_loop
0DDB: B0 F3 mov al, 0xf3
0DDD: E6 60 out 0x60, al
0DDF: 31 C9 xor cx, cx
0DE1: E4 64 in al, 64h
0DE3: A8 02 test al, 2
0DE5: E0 FA loopnz @b
0DE7: B0 00 mov al, 0
0DE9: E6 60 out 0x60, al
0DEB: 31 C9 xor cx, cx
0DED: E4 64 in al, 64h
0DEF: A8 02 test al, 2
0DF1: E0 FA loopnz @b
0DF3: E8 E9 FB call gettime
0DF6: 66 A3 D8 1A mov dword [ start_timer ], eax
0DFA: C7 06 DC 1A EA 09 mov word [ timer_ ], newtimer
0E00: 8C 0E DE 1A mov word [ timer_ + 2 ], cs
0E04: FA cli
0E05: 6A 00 push 0
0E07: 07 pop es
0E08: 26 66 FF 36 20 00 push dword [ es : 8 * 4 ]
0E0E: 66 8F 06 D4 1A pop dword [ old_timer ]
0E13: 66 FF 36 DC 1A push dword [ timer_ ]
0E18: 26 66 8F 06 20 00 pop dword [ es : 8 * 4 ]
0E1E: FB sti
0E1F: C7 46 BE 12 00 mov save_descript_size, 18
0E24: 31 C0 xor ax, ax
0E26: B8 20 07 mov ax, 0x0720
0E29: 68 00 B8 push 0xb800
0E2C: 07 pop es
0E2D: 31 FF xor di, di
0E2F: B9 D0 07 mov cx, 25 * 80
0E32: F3 rep
0E33: AB stosw
0E34: BF A4 00 mov di, 164
0E37: BE 03 00 mov si, version
0E3A: B9 19 00 mov cx, version_end - version
0E3D: B4 0E mov ah, color_sym_yellow
0E3F: AC lodsb
0E40: AB stosw
0E41: E2 FC loop @b
0E43: BF 1E 01 mov di, 286
0E46: B4 0C mov ah, color_sym_pink
0E48: B0 4B mov al, 'K'
0E4A: AB stosw
0E4B: B0 20 mov al, ' '
0E4D: AB stosw
0E4E: B4 07 mov ah, color_sym_lightgray
0E50: BE 3F 00 mov si, soft_mes
0E53: B9 0D 00 mov cx, soft_mes_end - soft_mes
0E56: AC lodsb
0E57: AB stosw
0E58: E2 FC loop @b
0E5A: BF E0 01 mov di, 480
0E5D: B4 0E mov ah, color_sym_yellow
0E5F: B0 C4 mov al, 'Ä'
0E61: B9 3D 00 mov cx, 61
0E64: F3 rep
0E65: AB stosw
0E66: BF 24 03 mov di, 804
0E69: BE 1C 00 mov si, select_section
0E6C: B9 0F 00 mov cx, select_section_end - select_section
0E6F: B4 07 mov ah, color_sym_lightgray
0E71: AC lodsb
0E72: AB stosw
0E73: E2 FC loop @b
0E75: BF 70 03 mov di, 880
0E78: BE 2B 00 mov si, section_description
0E7B: B9 14 00 mov cx, section_description_end - section_description
0E7E: AC lodsb
0E7F: AB stosw
0E80: E2 FC loop @b
0E82: 8B 4E FE mov cx, save_cx
0E85: C4 3E C5 0A les di, dword [ file_data ]
0E89: 89 FE mov si, di
0E8B: 89 CB mov bx, cx
0E8D: BA 12 00 mov dx, size_show_section
0E90: 26 8A 05 mov al, byte [ es : di ]
0E93: 68 B9 0E push word .first_ret_bl_sc
0E96: 3C 20 cmp al, ' '
0E98: 74 03 jz .first_bl_sc
0E9A: E9 F9 F9 jmp get_firs_sym.not_space
0E9D: E9 EB F9 jmp get_firs_sym.first_sp
0EA0: E8 D0 F9 call get_firs_sym
0EA3: 85 C9 test cx, cx
0EA5: 0F 84 09 FC jz error.correct_exit_bl
0EA9: 3C 5B cmp al, '['
0EAB: 75 F3 jnz .start_hbl
0EAD: 89 FE mov si, di
0EAF: 89 CB mov bx, cx
0EB1: BA 12 00 mov dx, size_show_section
0EB4: EB 09 jmp .analisist_al
0EB6: E8 BA F9 call get_firs_sym
0EB9: 85 C9 test cx, cx
0EBB: 0F 84 F3 FB jz error.correct_exit_bl
0EBF: 3C 5B cmp al, '['
0EC1: 75 F3 jnz .start_bl
0EC3: 3B 7E F6 cmp di, point_loader
0EC6: 74 EE jz .start_bl
0EC8: 3B 7E F4 cmp di, point_default
0ECB: 74 05 jz .save_point_def
0ECD: 4A dec dx
0ECE: 75 E6 jnz .start_bl
0ED0: EB CE jmp .start_hbl
0ED2: 89 F7 mov di, si
0ED4: 89 D9 mov cx, bx
0ED6: 8D 76 F2 lea si, point_to_hframe
0ED9: BA 13 00 mov dx, size_show_section + 1
0EDC: 26 8A 05 mov al, byte [ es : di ]
0EDF: 68 EF 0E push word .first_ret_mfb
0EE2: 3C 20 cmp al, ' '
0EE4: 74 03 jz .first_bl_mbf
0EE6: E9 AD F9 jmp get_firs_sym.not_space
0EE9: E9 9F F9 jmp get_firs_sym.first_sp
0EEC: E8 84 F9 call get_firs_sym
0EEF: E3 13 jcxz .val_buff_comp
0EF1: 3C 5B cmp al, '['
0EF3: 75 F7 jnz .start_mfb
0EF5: 3B 7E F6 cmp di, point_loader
0EF8: 74 F2 jz .start_mfb
0EFA: 89 3C mov [ si ], di
0EFC: 83 EE 02 sub si, 2
0EFF: 4A dec dx
0F00: 75 EA jnz .start_mfb
0F02: EB 08 jmp @f
0F04: FF 76 FE push save_cx
0F07: 8F 04 pop word [ si ]
0F09: 83 EE 02 sub si, 2
0F0C: 83 C6 04 add si, 4
0F0F: 89 76 C8 mov point_to_eframe, si
0F12: E8 42 FB call show_bl_sc_sect
0F15: 8D 76 F2 lea si, point_to_hframe
0F18: BF 22 03 mov di, 962 - 160
0F1B: 8B 46 F4 mov ax, point_default
0F1E: B9 12 00 mov cx, size_show_section
0F21: 8B 1C mov bx, [ si ]
0F23: 81 C7 A0 00 add di, 160
0F27: 39 C3 cmp bx, ax
0F29: 74 05 jz .show_cursor_activ
0F2B: 83 EE 02 sub si, 2
0F2E: E2 F1 loop .home_show_cur
0F30: 89 76 CA mov point_to_point_def, si
0F33: B8 10 04 mov ax, ( color_sym_red * 0x100 + 0x10 )
0F36: AB stosw
0F37: 83 C7 44 add di, 68
0F3A: 40 inc ax
0F3B: AB stosw
0F3C: 8B 7E F4 mov di, point_default
0F3F: 68 00 20 push ini_data_
0F42: 8B 76 CA mov si, point_to_point_def
0F45: 07 pop es
0F46: 83 EE 02 sub si, 2
0F49: 8B 0C mov cx, [ si ]
0F4B: 29 F9 sub cx, di
0F4D: E8 23 F9 call get_firs_sym
0F50: 85 C9 test cx, cx
0F52: 0F 84 91 00 jz .exit?0Pz
0F56: 3C 64 cmp al, 'd'
0F58: 75 F3 jnz .start_p_sh_d?0Py
0F5A: 89 CB mov bx, cx
0F5C: 89 F8 mov ax, di
0F5E: BE C5 07 mov si, parse_descript
0F61: B9 08 00 mov cx, parse_descript_e - parse_descript
0F64: F3 repe
0F65: A6 cmpsb
0F66: 75 78 jnz .rest_value_loop_sh_d?0Q0
0F68: 83 EB 08 sub bx, parse_descript_e - parse_descript
0F6B: 01 CB add bx, cx
0F6D: 89 D9 mov cx, bx
0F6F: B8 20 3D mov ax, 0x3d20
0F72: F3 repe
0F73: AE scasb
0F74: E3 6A jcxz .rest_value_loop_sh_d?0Q0
0F76: 26 3A 65 FF cmp ah, byte [ es : di - 1 ]
0F7A: 75 64 jnz .rest_value_loop_sh_d?0Q0
0F7C: F3 repe
0F7D: AE scasb
0F7E: 41 inc cx
0F7F: 4F dec di
0F80: 57 push di
0F81: 5E pop si
0F82: 06 push es
0F83: 1F pop ds
0F84: 68 00 B8 push 0xb800
0F87: 07 pop es
0F88: BF 10 04 mov di, 1040
0F8B: BB 12 00 mov bx, 18
0F8E: 89 7E C6 mov find_sec_di, di
0F91: 89 5E FA mov save_cx_d, bx
0F94: 57 push di
0F95: 31 C0 xor ax, ax
0F97: B9 26 00 mov cx, 38
0F9A: 57 push di
0F9B: F3 rep
0F9C: AB stosw
0F9D: 5F pop di
0F9E: 39 5E BE cmp save_descript_size, bx
0FA1: 74 07 jz @f
0FA3: 81 C7 A0 00 add di, 160
0FA7: 4B dec bx
0FA8: 75 ED jnz @b
0FAA: 5F pop di
0FAB: AC lodsb
0FAC: B4 0A mov ah, color_sym_lettuce
0FAE: 3C 22 cmp al, '"'
0FB0: 74 04 jz .loop_message?0Q2
0FB2: 3C 27 cmp al, '''
0FB4: 75 20 jnz .end_sh_desc_sec?0Q1
0FB6: B9 26 00 mov cx, 38
0FB9: AC lodsb
0FBA: 3C 22 cmp al, '"'
0FBC: 74 18 jz .end_sh_desc_sec?0Q1
0FBE: 3C 27 cmp al, '''
0FC0: 74 14 jz .end_sh_desc_sec?0Q1
0FC2: AB stosw
0FC3: E2 F4 loop @b
0FC5: 81 46 C6 A0 00 add find_sec_di, 160
0FCA: 8B 7E C6 mov di, find_sec_di
0FCD: FF 4E FA dec save_cx_d
0FD0: 83 7E FA 00 cmp save_cx_d, 0
0FD4: 75 E0 jnz .loop_message?0Q2
0FD6: FF 76 FA push save_cx_d
0FD9: 8F 46 BE pop save_descript_size
0FDC: 0E push cs
0FDD: 1F pop ds
0FDE: EB 07 jmp .exit?0Pz
0FE0: 89 C7 mov di, ax
0FE2: 89 D9 mov cx, bx
0FE4: E9 66 FF jmp .start_p_sh_d?0Py
0FE7: 66 A1 D4 1A mov eax, dword [ old_timer ]
0FEB: 66 3B 06 DC 1A cmp eax, dword [ timer_ ]
0FF0: 74 5E jz .interrupt_16
0FF2: 31 C0 xor ax, ax
0FF4: BF 20 0D mov di, 3360
0FF7: B9 40 01 mov cx, 80 * 4
0FFA: F3 rep
0FFB: AB stosw
0FFC: BF 22 0D mov di, 3362
0FFF: B4 0C mov ah, color_sym_pink
1001: B0 DA mov al, 0xDA
1003: AB stosw
1004: B0 C4 mov al, 0xc4
1006: B9 4C 00 mov cx, 76
1009: F3 rep
100A: AB stosw
100B: B0 BF mov al, 0xBF
100D: AB stosw
100E: 83 C7 04 add di, 4
1011: B0 B3 mov al, 0xb3
1013: AB stosw
1014: 81 C7 98 00 add di, 152
1018: AB stosw
1019: 83 C7 04 add di, 4
101C: AB stosw
101D: 81 C7 98 00 add di, 152
1021: AB stosw
1022: 83 C7 04 add di, 4
1025: B0 C0 mov al, 0xc0
1027: AB stosw
1028: B0 C4 mov al, 0xc4
102A: B9 4C 00 mov cx, 76
102D: F3 rep
102E: AB stosw
102F: B0 D9 mov al, 0xd9
1031: AB stosw
1032: BE 2E 03 mov si, start_msg
1035: B9 4A 00 mov cx, start_msg_e - start_msg
1038: BF C6 0D mov di, 3526
103B: AC lodsb
103C: AB stosw
103D: E2 FC loop @b
103F: 83 C7 2C add di, 44
1042: BE 78 03 mov si, time_msg
1045: B9 2D 00 mov cx, time_msg_e - time_msg
1048: AC lodsb
1049: AB stosw
104A: E2 FC loop @b
104C: 89 26 E0 1A mov word [ start_stack ], sp
1050: 31 C0 xor ax, ax
1052: CD 16 int 0x16
1054: 66 8B 1E D4 1A mov ebx, dword [ old_timer ]
1059: 66 3B 1E DC 1A cmp ebx, dword [ timer_ ]
105E: 74 2A jz @f
1060: FA cli
1061: 6A 00 push 0
1063: 07 pop es
1064: 26 66 89 1E 20 00 mov [ es : 8 * 4 ], ebx
106A: 66 89 1E DC 1A mov dword [ timer_ ], ebx
106F: FB sti
1070: 50 push ax
1071: 68 00 B8 push 0xb800
1074: 07 pop es
1075: 31 C0 xor ax, ax
1077: B8 20 07 mov ax, 0x0720
107A: BF 20 0D mov di, 3360
107D: B9 40 01 mov cx, 80 * 4
1080: F3 rep
1081: AB stosw
1082: 68 00 20 push ini_data_
1085: 07 pop es
1086: E8 CE F9 call show_bl_sc_sect
1089: 58 pop ax
108A: E8 23 F9 call clean_active_cursor
108D: 80 FC 48 cmp ah, 0x48
1090: 74 21 jz .up
1092: 80 FC 50 cmp ah, 0x50
1095: 74 3A jz .down
1097: 80 FC 49 cmp ah, 0x49
109A: 74 53 jz .pgup
109C: 80 FC 51 cmp ah, 0x51
109F: 74 5B jz .pgdown
10A1: 80 FC 47 cmp ah, 0x47
10A4: 74 63 jz .home
10A6: 80 FC 4F cmp ah, 0x4f
10A9: 74 66 jz .end
10AB: 3C 0D cmp al, 0xD
10AD: 0F 85 64 FE jnz .show_active_cursor
10B1: EB 6F jmp .end_show_all
10B3: 8B 76 CA mov si, point_to_point_def
10B6: 83 C6 02 add si, 2
10B9: 8D 46 F2 lea ax, point_to_hframe
10BC: 39 C6 cmp si, ax
10BE: 77 0B ja @f
10C0: 89 76 CA mov point_to_point_def, si
10C3: 8B 04 mov ax, [ si ]
10C5: 89 46 F4 mov point_default, ax
10C8: E9 4A FE jmp .show_active_cursor
10CB: E8 52 F8 call find_before_sect
10CE: E9 B1 FD jmp .show_all_scr
10D1: 8B 76 CA mov si, point_to_point_def
10D4: 8B 46 C8 mov ax, point_to_eframe
10D7: 83 EE 02 sub si, 2
10DA: 39 C6 cmp si, ax
10DC: 72 0B jb @f
10DE: 89 76 CA mov point_to_point_def, si
10E1: 8B 04 mov ax, [ si ]
10E3: 89 46 F4 mov point_default, ax
10E6: E9 2C FE jmp .show_active_cursor
10E9: E8 8D F8 call find_next_sect
10EC: E9 93 FD jmp .show_all_scr
10EF: B9 12 00 mov cx, size_show_section
10F2: 51 push cx
10F3: E8 2A F8 call find_before_sect
10F6: 59 pop cx
10F7: E2 F9 loop @b
10F9: E9 86 FD jmp .show_all_scr
10FC: B9 12 00 mov cx, size_show_section
10FF: 51 push cx
1100: E8 76 F8 call find_next_sect
1103: 59 pop cx
1104: E2 F9 loop @b
1106: E9 79 FD jmp .show_all_scr
1109: 31 FF xor di, di
110B: E8 79 F8 call find_next_sect.h
110E: E9 71 FD jmp .show_all_scr
1111: 8B 7E FE mov di, save_cx
1114: E8 0C F8 call find_before_sect.e
1117: E9 68 FD jmp .show_all_scr
111A: 60 pusha
111B: BE D7 04 mov si, no_show_only_w
111E: E8 23 F7 call printplain
1121: 61 popa
1122: 8B 7E F4 mov di, point_default
1125: 68 00 20 push ini_data_
1128: 07 pop es
1129: 8B 76 CA mov si, point_to_point_def
112C: 83 EE 02 sub si, 2
112F: 8B 0C mov cx, [ si ]
1131: 31 C0 xor ax, ax
1133: 29 F9 sub cx, di
1135: 89 4E FA mov save_cx_d, cx
1138: 89 46 F8 mov status_flag, ax
113B: BE 2B 05 mov si, ramdiskFS_st
113E: E8 03 F7 call printplain
1141: 31 C0 xor ax, ax
1143: 89 46 C0 mov show_errors_sect, ax
1146: B4 88 mov ah, 0x88
1148: CD 15 int 0x15
114A: 73 02 jnc ._support_function_use_free_memory
114C: 31 C0 xor ax, ax
114E: 89 46 C2 mov free_ad_memory, ax
1151: 60 pusha
1152: 66 0F B7 C0 movzx eax, ax
1156: B9 0A 00 mov cx, 0x0a
1159: BF 46 05 mov di, free_memory_msg
115C: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' '
1163: C7 45 04 20 20 mov word [ ds : di + 4 ], ' '
1168: E8 BA F6 call decode
116B: BE 46 05 mov si, free_memory_msg
116E: E8 D3 F6 call printplain
1171: 61 popa
1172: 8B 7E F4 mov di, point_default
1175: 8B 4E FA mov cx, save_cx_d
1178: E8 F8 F6 call get_firs_sym
117B: 85 C9 test cx, cx
117D: 74 6E jz ._end_parse_RS?0k2
117F: 3C 52 cmp al, 'R'
1181: 75 F5 jnz .start_p_RS?0ju
1183: 89 CB mov bx, cx
1185: 89 F8 mov ax, di
1187: BE D9 07 mov si, parse_RamdiskSize
118A: B9 0B 00 mov cx, parse_RamdiskSize_e - parse_RamdiskSize
118D: F3 repe
118E: A6 cmpsb
118F: 75 4C jnz .rest_value_loop_RS?0jz
1191: 83 EB 0B sub bx, parse_RamdiskSize_e - parse_RamdiskSize
1194: 01 CB add bx, cx
1196: 89 D9 mov cx, bx
1198: F7 46 F8 02 00 test status_flag, flag_found_RS
119D: 74 00 jz .correct_is_not_set_RS?0jv
119F: B8 20 3D mov ax, 0x3d20
11A2: F3 repe
11A3: AE scasb
11A4: E3 3D jcxz .end_get_RS_ERROR_1?0k0
11A6: 26 3A 65 FF cmp ah, byte [ es : di - 1 ]
11AA: 75 CC jnz .start_p_RS?0ju
11AC: F3 repe
11AD: AE scasb
11AE: 41 inc cx
11AF: 4F dec di
11B0: 31 DB xor bx, bx
11B2: B9 05 00 mov cx, 5
11B5: 26 8A 05 mov al, byte [ es : di ]
11B8: 3C 30 cmp al, '0'
11BA: 72 04 jb .CS?0jw
11BC: 3C 39 cmp al, '9'
11BE: 76 06 jbe .correct_val_RS?0jx
11C0: 3C 4B cmp al, 'K'
11C2: 74 0C jz .correct_size_RS?0jy
11C4: EB 23 jmp .end_get_RS_ERROR_2?0k1
11C6: 6B DB 0A imul bx, 10
11C9: 34 30 xor al, 0x30
11CB: 00 C3 add bl, al
11CD: 47 inc di
11CE: E2 E5 loop @b
11D0: 85 DB test bx, bx
11D2: 75 07 jnz @f
11D4: 83 4E C0 04 or show_errors_sect, show_error_3
11D8: BB 40 00 mov bx, 64
11DB: EB 10 jmp ._end_parse_RS?0k2
11DD: 89 C7 mov di, ax
11DF: 89 D9 mov cx, bx
11E1: EB 95 jmp .start_p_RS?0ju
11E3: 83 4E C0 01 or show_errors_sect, show_error_1
11E7: EB 04 jmp ._end_parse_RS?0k2
11E9: 83 4E C0 02 or show_errors_sect, show_error_2
11ED: 60 pusha
11EE: 66 0F B7 C3 movzx eax, bx
11F2: B9 0A 00 mov cx, 0x0a
11F5: BF 71 05 mov di, RamdiskSize_msg
11F8: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' '
11FF: C7 45 04 20 20 mov word [ ds : di + 4 ], ' '
1204: E8 1E F6 call decode
1207: BE 71 05 mov si, RamdiskSize_msg
120A: E8 37 F6 call printplain
120D: 61 popa
120E: 39 5E C2 cmp free_ad_memory, bx
1211: 0F 86 80 07 jbe ._not_memory_in_sys?0iL
1215: 66 0F B7 C3 movzx eax, bx
1219: 66 C1 E0 0A shl eax, 10
121D: 66 89 46 BA mov save_ramdisksize, eax
1221: 8B 7E F4 mov di, point_default
1224: 8B 4E FA mov cx, save_cx_d
1227: E8 49 F6 call get_firs_sym
122A: 85 C9 test cx, cx
122C: 0F 84 5D 07 jz ._end_parse_FRS
1230: 3C 52 cmp al, 'R'
1232: 75 F3 jnz .start_g_tpe_RFS
1234: 89 CB mov bx, cx
1236: 89 F8 mov ax, di
1238: BE E4 07 mov si, parse_RamdiskFS
123B: B9 09 00 mov cx, parse_RamdiskFS_e - parse_RamdiskFS
123E: F3 repe
123F: A6 cmpsb
1240: 0F 85 38 07 jnz .start_g_tpe_RFS_rest_v
1244: 83 EB 09 sub bx, parse_RamdiskFS_e - parse_RamdiskFS
1247: 01 CB add bx, cx
1249: 89 D9 mov cx, bx
124B: F7 46 F8 04 00 test status_flag, flag_found_GTRFMS
1250: 74 00 jz .correct_is_not_set_FRS
1252: B8 20 3D mov ax, 0x3d20
1255: F3 repe
1256: AE scasb
1257: 85 C9 test cx, cx
1259: 0F 84 26 07 jz .end_get_FRS_ERROR_1
125D: 26 3A 65 FF cmp ah, byte [ es : di - 1 ]
1261: 75 C4 jnz .start_g_tpe_RFS
1263: F3 repe
1264: AE scasb
1265: 41 inc cx
1266: 4F dec di
1267: 89 CB mov bx, cx
1269: 89 F8 mov ax, di
126B: BE 08 08 mov si, parse_RFS_FAT
126E: B9 03 00 mov cx, parse_RFS_FAT_e - parse_RFS_FAT
1271: F3 repe
1272: A6 cmpsb
1273: 0F 85 F7 06 jnz .krfs_cmp
1277: 8B 7E F4 mov di, point_default
127A: 8B 4E FA mov cx, save_cx_d
127D: E8 F3 F5 call get_firs_sym
1280: 85 C9 test cx, cx
1282: 74 54 jz .end_RamdiskSector
1284: 3C 52 cmp al, 'R'
1286: 75 F5 jnz .start_RamdiskSector
1288: 89 CB mov bx, cx
128A: 89 F8 mov ax, di
128C: BE ED 07 mov si, parse_RamdiskSector
128F: B9 0D 00 mov cx, parse_RamdiskSector_e - parse_RamdiskSector
1292: F3 repe
1293: A6 cmpsb
1294: 75 3C jnz .RamdiskSector_rest_val
1296: 83 EB 0D sub bx, parse_RamdiskSector_e - parse_RamdiskSector
1299: 01 CB add bx, cx
129B: 89 D9 mov cx, bx
129D: F7 46 F8 08 00 test status_flag, flag_found_RamdiskSector
12A2: 74 00 jz .correct_is_not_set_RamdiskSector
12A4: B8 20 3D mov ax, 0x3d20
12A7: F3 repe
12A8: AE scasb
12A9: E3 2D jcxz .end_get_RamS_ERROR_1
12AB: 26 3A 65 FF cmp ah, byte [ es : di - 1 ]
12AF: 75 CC jnz .start_RamdiskSector
12B1: F3 repe
12B2: AE scasb
12B3: 41 inc cx
12B4: 4F dec di
12B5: 31 DB xor bx, bx
12B7: B9 04 00 mov cx, 4
12BA: 26 0F B6 05 movzx ax, byte [ es : di ]
12BE: 3C 30 cmp al, '0'
12C0: 72 16 jb .end_RamdiskSector
12C2: 3C 39 cmp al, '9'
12C4: 77 12 ja .end_RamdiskSector
12C6: 6B DB 0A imul bx, 10
12C9: 34 30 xor al, 0x30
12CB: 01 C3 add bx, ax
12CD: 47 inc di
12CE: E2 EA loop @b
12D0: EB 06 jmp .end_RamdiskSector
12D2: 89 D9 mov cx, bx
12D4: 89 C7 mov di, ax
12D6: EB A5 jmp .start_RamdiskSector
12D8: 89 D8 mov ax, bx
12DA: 60 pusha
12DB: 66 0F B7 C3 movzx eax, bx
12DF: B9 0A 00 mov cx, 0x0a
12E2: BF 8E 05 mov di, RamdiskSector_msg
12E5: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' '
12EC: 66 C7 45 04 20 20 20 20 mov dword [ ds : di + 4 ], ' '
12F4: E8 2E F5 call decode
12F7: BE 8E 05 mov si, RamdiskSector_msg
12FA: E8 47 F5 call printplain
12FD: 61 popa
12FE: 3D 00 10 cmp ax, 4096
1301: 77 04 ja .RS1?0sn
1303: 85 C0 test ax, ax
1305: 75 06 jnz @f
1307: C7 06 87 1A 00 02 mov word [ fat12_buffer.BPB_BytsPerSec ], 512
130D: A3 87 1A mov word [ fat12_buffer.BPB_BytsPerSec ], ax
1310: 8B 7E F4 mov di, point_default
1313: 8B 4E FA mov cx, save_cx_d
1316: E8 5A F5 call get_firs_sym
1319: 85 C9 test cx, cx
131B: 74 47 jz .end_RamdiskCluster
131D: 3C 52 cmp al, 'R'
131F: 75 F5 jnz .start_RamdiskCluster
1321: 89 CB mov bx, cx
1323: 89 F8 mov ax, di
1325: BE FA 07 mov si, parse_RamdiskCluster
1328: B9 0E 00 mov cx, parse_RamdiskCluster_e - parse_RamdiskCluster
132B: F3 repe
132C: A6 cmpsb
132D: 75 2F jnz .RamdiskCluster_rest_val
132F: 83 EB 0E sub bx, parse_RamdiskCluster_e - parse_RamdiskCluster
1332: 01 CB add bx, cx
1334: 89 D9 mov cx, bx
1336: F7 46 F8 16 00 test status_flag, flag_found_RamdiskCluster
133B: 74 00 jz .correct_is_not_set_RamdiskCluster
133D: B8 20 3D mov ax, 0x3d20
1340: F3 repe
1341: AE scasb
1342: E3 20 jcxz .end_get_RamSC_ERROR_1
1344: 26 3A 65 FF cmp ah, byte [ es : di - 1 ]
1348: 75 CC jnz .start_RamdiskCluster
134A: F3 repe
134B: AE scasb
134C: 41 inc cx
134D: 4F dec di
134E: 26 0F B6 05 movzx ax, byte [ es : di ]
1352: 3C 30 cmp al, '0'
1354: 72 0E jb .end_RamdiskCluster
1356: 3C 39 cmp al, '9'
1358: 77 0A ja .end_RamdiskCluster
135A: 34 30 xor al, 0x30
135C: EB 06 jmp .end_RamdiskCluster
135E: 89 D9 mov cx, bx
1360: 89 C7 mov di, ax
1362: EB B2 jmp .start_RamdiskCluster
1364: 60 pusha
1365: B9 0A 00 mov cx, 0x0a
1368: BF AA 05 mov di, RamdiskCluster_msg
136B: E8 B7 F4 call decode
136E: BE AA 05 mov si, RamdiskCluster_msg
1371: E8 D0 F4 call printplain
1374: 61 popa
1375: 3C 80 cmp al, 128
1377: 77 6B ja @f
1379: A2 89 1A mov byte [ fat12_buffer.BPB_SecPerClus ], al
137C: 66 0F B7 06 87 1A movzx eax, word [ fat12_buffer.BPB_BytsPerSec ]
1382: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ]
1388: 66 0F AF D8 imul ebx, eax
138C: 66 8B 46 BA mov eax, save_ramdisksize
1390: 66 99 cdq
1392: 66 F7 FB idiv ebx
1395: 66 3D F5 0F 00 00 cmp eax, 4085
139B: 0F 82 8E 00 jb .fat12?0so
139F: 66 3D F5 FF 00 00 cmp eax, 65525
13A5: 72 18 jb .fat16?0sp
13A7: C7 46 B4 20 00 mov set_ramfs, 32
13AC: C7 06 8A 1A 20 00 mov word [ fat12_buffer.BPB_RsvdSecCnt ], 32
13B2: 66 31 C0 xor eax, eax
13B5: A3 8D 1A mov word [ fat12_buffer.BPB_RootEntCnt ], ax
13B8: A3 8F 1A mov word [ fat12_buffer.BPB_TotSec16 ], ax
13BB: 66 A3 9C 1A mov dword [ fat12_buffer.BPB_TotSec32 ], eax
13BF: EB FE jmp $
13C1: C7 46 B4 10 00 mov set_ramfs, 16
13C6: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ]
13CC: 66 0F AF C3 imul eax, ebx
13D0: 66 3D 00 00 01 00 cmp eax, 0x10000
13D6: 73 0C jae @f
13D8: A3 8F 1A mov word [ fat12_buffer.BPB_TotSec16 ], ax
13DB: 66 C7 06 9C 1A 00 00 00 00 mov dword [ fat12_buffer.BPB_TotSec32 ], 0
13E4: 66 B8 E0 00 00 00 mov eax, root_dir_entry_count
13EA: A3 8D 1A mov word [ fat12_buffer.BPB_RootEntCnt ], ax
13ED: 66 0F B7 1E 87 1A movzx ebx, word [ fat12_buffer.BPB_BytsPerSec ]
13F3: 66 6B C0 20 imul eax, 32
13F7: 66 01 D8 add eax, ebx
13FA: 66 48 dec eax
13FC: 66 99 cdq
13FE: 66 F7 FB idiv ebx
1401: 66 0F B7 1E 8A 1A movzx ebx, word [ fat12_buffer.BPB_RsvdSecCnt ]
1407: 66 01 C3 add ebx, eax
140A: 66 0F B7 06 8F 1A movzx eax, word [ fat12_buffer.BPB_TotSec16 ]
1410: 66 29 D8 sub eax, ebx
1413: 66 C1 E7 08 shl edi, 8
1417: 66 0F B6 0E 8C 1A movzx ecx, byte [ fat12_buffer.BPB_NumFATs ]
141D: 66 01 CF add edi, ecx
1420: 66 01 F8 add eax, edi
1423: 66 48 dec eax
1425: 66 99 cdq
1427: 66 F7 FF idiv edi
142A: A3 92 1A mov word [ fat12_buffer.BPB_FATSz16 ], ax
142D: C7 46 B4 0C 00 mov set_ramfs, 12
1432: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ]
1438: 66 0F AF C3 imul eax, ebx
143C: 66 3D 00 00 01 00 cmp eax, 0x10000
1442: 73 0C jae @f
1444: A3 8F 1A mov word [ fat12_buffer.BPB_TotSec16 ], ax
1447: 66 C7 06 9C 1A 00 00 00 00 mov dword [ fat12_buffer.BPB_TotSec32 ], 0
1450: 66 B8 E0 00 00 00 mov eax, root_dir_entry_count
1456: A3 8D 1A mov word [ fat12_buffer.BPB_RootEntCnt ], ax
1459: 66 0F B7 06 8F 1A movzx eax, word [ fat12_buffer.BPB_TotSec16 ]
145F: 66 6B C0 0C imul eax, 12
1463: 66 C1 E8 03 shr eax, 3
1467: 66 0F B7 1E 87 1A movzx ebx, word [ fat12_buffer.BPB_BytsPerSec ]
146D: 66 99 cdq
146F: 66 F7 FB idiv ebx
1472: 40 inc ax
1473: A3 92 1A mov word [ fat12_buffer.BPB_FATSz16 ], ax
1476: A1 92 1A mov ax, word [ fat12_buffer.BPB_FATSz16 ]
1479: 0F B6 1E 8C 1A movzx bx, byte [ fat12_buffer.BPB_NumFATs ]
147E: 0F AF C3 imul ax, bx
1481: 8B 1E 8D 1A mov bx, word [ fat12_buffer.BPB_RootEntCnt ]
1485: C1 EB 04 shr bx, 4
1488: 01 D8 add ax, bx
148A: 89 5E B0 mov size_root_dir, bx
148D: 0F B6 1E 8A 1A movzx bx, byte [ fat12_buffer.BPB_RsvdSecCnt ]
1492: 01 D8 add ax, bx
1494: 89 46 AE mov firstDataSect, ax
1497: 8B 1E 8F 1A mov bx, word [ fat12_buffer.BPB_TotSec16 ]
149B: 29 C3 sub bx, ax
149D: 89 D8 mov ax, bx
149F: 0F B6 1E 89 1A movzx bx, byte [ fat12_buffer.BPB_SecPerClus ]
14A4: 99 cwd
14A5: F7 FB idiv bx
14A7: 89 46 AC mov DataClasters, ax
14AA: 60 pusha
14AB: 8B 46 AE mov ax, firstDataSect
14AE: B9 0A 00 mov cx, 0x0a
14B1: BF 44 06 mov di, firstDataSect_msg
14B4: E8 6E F3 call decode
14B7: BE 44 06 mov si, firstDataSect_msg
14BA: E8 87 F3 call printplain
14BD: 8B 46 B0 mov ax, size_root_dir
14C0: B9 0A 00 mov cx, 0x0a
14C3: BF 79 06 mov di, size_root_dir_msg
14C6: E8 5C F3 call decode
14C9: BE 79 06 mov si, size_root_dir_msg
14CC: E8 75 F3 call printplain
14CF: 8B 46 AC mov ax, DataClasters
14D2: B9 0A 00 mov cx, 0x0a
14D5: BF 9B 06 mov di, DataClasters_msg
14D8: E8 4A F3 call decode
14DB: BE 9B 06 mov si, DataClasters_msg
14DE: E8 63 F3 call printplain
14E1: 61 popa
14E2: A0 91 1A mov al, byte [ fat12_buffer.BPB_Media ]
14E5: 1E push ds
14E6: 8B 7E C4 mov di, info_real_mode_size
14E9: 81 C7 00 10 add di, 0x1000
14ED: 57 push di
14EE: 31 FF xor di, di
14F0: 89 7E AA mov point_to_free_root, di
14F3: 1F pop ds
14F4: 88 05 mov byte [ di ], al
14F6: 83 C8 FF or ax, - 1
14F9: 47 inc di
14FA: 89 05 mov word [ di ], ax
14FC: 1F pop ds
14FD: C7 46 B2 03 00 mov point_next_fat_str, 3
1502: 60 pusha
1503: 8B 46 B2 mov ax, point_next_fat_str
1506: B9 0A 00 mov cx, 0x0a
1509: BF DA 05 mov di, fat_create_msg
150C: E8 16 F3 call decode
150F: BE DA 05 mov si, fat_create_msg
1512: E8 2F F3 call printplain
1515: 61 popa
1516: B8 7C 1A mov ax, fat12_buffer
1519: BE 3C 1A mov si, table_15_87
151C: 01 44 12 add word [ si + 8 * 2 + 2 ], ax
151F: 06 push es
1520: 1E push ds
1521: 07 pop es
1522: B9 1F 00 mov cx, 31
1525: B4 87 mov ah, 0x87
1527: CD 15 int 0x15
1529: 07 pop es
152A: 60 pusha
152B: 8B 44 12 mov ax, word [ si + 8 * 2 + 2 ]
152E: B9 0A 00 mov cx, 0x0a
1531: BF 0E 06 mov di, BPB_msg
1534: E8 EE F2 call decode
1537: BE 0E 06 mov si, BPB_msg
153A: E8 07 F3 call printplain
153D: 61 popa
153E: 8B 7E F4 mov di, point_default
1541: 8B 4E FA mov cx, save_cx_d
1544: C7 46 A6 00 00 mov data_offset, 0
1549: E8 27 F3 call get_firs_sym
154C: 85 C9 test cx, cx
154E: 0F 84 B3 03 jz ._end?1D2
1552: 3C 52 cmp al, 'R'
1554: 75 F3 jnz .start_loop?1D1
1556: 89 CB mov bx, cx
1558: 89 F8 mov ax, di
155A: BE 1A 08 mov si, parse_RamdiskFile
155D: B9 0B 00 mov cx, parse_RamdiskFile_e - parse_RamdiskFile
1560: F3 repe
1561: A6 cmpsb
1562: 0F 85 98 03 jnz .rest_value_loop?1D3
1566: 83 EB 0B sub bx, parse_RamdiskFile_e - parse_RamdiskFile
1569: 01 CB add bx, cx
156B: 89 D9 mov cx, bx
156D: B8 20 3D mov ax, 0x3d20
1570: F3 repe
1571: AE scasb
1572: 66 85 C9 test ecx, ecx
1575: 0F 84 85 03 jz .rest_value_loop?1D3
1579: 26 3A 65 FF cmp ah, byte [ es : di - 1 ]
157D: 0F 85 7D 03 jnz .rest_value_loop?1D3
1581: F3 repe
1582: AE scasb
1583: 41 inc cx
1584: 4F dec di
1585: 89 7E A2 mov save_di_RAMDISK, di
1588: 89 4E A0 mov save_cx_RAMDISK, cx
158B: 26 8A 05 mov al, byte [ es : di ]
158E: 3C 2C cmp al, ','
1590: 74 04 jz .found_end_str
1592: 47 inc di
1593: 49 dec cx
1594: 75 F5 jnz @b
1596: 89 7E A8 mov point_to_dest_file_name, di
1599: 47 inc di
159A: BE BA 1A mov si, shot_name_fat
159D: 83 4E A4 FF or first_input, - 1
15A1: B9 0B 00 mov cx, 11
15A4: 26 8A 05 mov al, byte [ es : di ]
15A7: 3C 0A cmp al, 0xa
15A9: 74 7D jz .st4_s?1GP
15AB: 3C 0D cmp al, 0xd
15AD: 74 79 jz .st4_s?1GP
15AF: 3C 20 cmp al, 0x20
15B1: 74 75 jz .st4_s?1GP
15B3: 3C 20 cmp al, 0x20
15B5: 72 7A jb .error?1GK
15B7: 3C 22 cmp al, 0x22
15B9: 74 76 jz .error?1GK
15BB: 3C 2A cmp al, 0x2a
15BD: 74 72 jz .error?1GK
15BF: 3C 2B cmp al, 0x2b
15C1: 74 6E jz .error?1GK
15C3: 3C 2C cmp al, 0x2c
15C5: 74 6A jz .error?1GK
15C7: 3C 2F cmp al, 0x2F
15C9: 74 66 jz .error?1GK
15CB: 3C 3A cmp al, 0x3a
15CD: 74 62 jz .error?1GK
15CF: 3C 3B cmp al, 0x3b
15D1: 74 5E jz .error?1GK
15D3: 3C 3C cmp al, 0x3c
15D5: 74 5A jz .error?1GK
15D7: 3C 3D cmp al, 0x3d
15D9: 74 56 jz .error?1GK
15DB: 3C 3E cmp al, 0x3E
15DD: 74 52 jz .error?1GK
15DF: 3C 3F cmp al, 0x3F
15E1: 74 4E jz .error?1GK
15E3: 3C 5B cmp al, 0x5b
15E5: 74 4A jz .error?1GK
15E7: 3C 5C cmp al, 0x5c
15E9: 74 46 jz .error?1GK
15EB: 3C 5D cmp al, 0x5d
15ED: 74 42 jz .error?1GK
15EF: 3C 7C cmp al, 0x7c
15F1: 74 3E jz .error?1GK
15F3: 83 7E A4 FF cmp first_input, - 1
15F7: 75 08 jnz .next_step?1GJ
15F9: 83 66 A4 00 and first_input, 0
15FD: 3C 2E cmp al, '.'
15FF: 74 30 jz .error?1GK
1601: 3C 2E cmp al, 0x2e
1603: 75 13 jnz .st2?1GM
1605: B0 20 mov al, ' '
1607: 80 F9 03 cmp cl, 3
160A: 76 0C jbe .st2?1GM
160C: 88 04 mov byte [ si ], al
160E: 46 inc si
160F: 49 dec cx
1610: 83 F9 03 cmp cx, 3
1613: 77 F7 ja .st3?1GO
1615: 47 inc di
1616: EB 8C jmp @b
1618: 3C 60 cmp al, 0x60
161A: 76 02 jbe .st2_l?1GN
161C: 34 20 xor al, 0x20
161E: 88 04 mov byte [ si ], al
1620: 47 inc di
1621: 46 inc si
1622: E2 80 loop @b
1624: 31 C0 xor ax, ax
1626: EB 0C jmp @f
1628: B0 20 mov al, ' '
162A: 88 04 mov byte [ si ], al
162C: 46 inc si
162D: E2 FB loop .st4?1GQ
162F: EB F3 jmp .st5?1GR
1631: 83 C8 FF or ax, - 1
1634: 60 pusha
1635: B9 0A 00 mov cx, 0x0a
1638: BF F5 06 mov di, convertion_file_name_msg
163B: E8 E7 F1 call decode
163E: BE F5 06 mov si, convertion_file_name_msg
1641: E8 00 F2 call printplain
1644: BE BA 1A mov si, shot_name_fat
1647: C6 44 0C 00 mov byte [ si + 12 ], 0
164B: E8 F6 F1 call printplain
164E: 61 popa
164F: 85 C0 test ax, ax
1651: 75 39 jnz .exit?1GI
1653: BE BA 1A mov si, shot_name_fat
1656: 8B 7E AE mov di, firstDataSect
1659: 2B 7E B0 sub di, size_root_dir
165C: C1 E7 09 shl di, 9
165F: BA E0 00 mov dx, root_dir_entry_count
1662: 8B 46 C4 mov ax, info_real_mode_size
1665: 05 00 10 add ax, 0x1000
1668: 8E E8 mov gs, ax
166A: B9 0B 00 mov cx, 11
166D: 8A 00 mov al, byte [ ds : si + bx ]
166F: 65 8A 21 mov ah, byte [ gs : di + bx ]
1672: 43 inc bx
1673: 38 C4 cmp ah, al
1675: 75 07 jnz .no_equal?1GH
1677: E2 F4 loop @b
1679: 83 C8 FF or ax, - 1
167C: EB 0E jmp .exit?1GI
167E: B9 0B 00 mov cx, 11
1681: 31 DB xor bx, bx
1683: 83 C7 20 add di, 32
1686: 4A dec dx
1687: 75 E4 jnz @b
1689: 83 E0 00 and ax, 0
168C: 60 pusha
168D: B9 0A 00 mov cx, 0x0a
1690: BF B9 06 mov di, check_name_fat_msg
1693: 66 C7 05 20 20 20 20 mov dword [ di ], ' '
169A: C7 45 04 20 20 mov word [ di + 4 ], ' '
169F: E8 83 F1 call decode
16A2: BE B9 06 mov si, check_name_fat_msg
16A5: E8 9C F1 call printplain
16A8: 61 popa
16A9: 8B 7E A2 mov di, save_di_RAMDISK
16AC: 8B 4E A0 mov cx, save_cx_RAMDISK
16AF: 84 C0 test al, al
16B1: 0F 85 94 FE jnz .start_loop?1D1
16B5: 26 66 FF 75 FA push dword [ es : di - 6 ]
16BA: 8D 75 FA lea si, [ di - 6 ]
16BD: 26 FF 75 FE push word [ es : di - 2 ]
16C1: 57 push di
16C2: 31 C0 xor ax, ax
16C4: 26 89 45 FA mov word [ es : di - 6 ], ax
16C8: 8B 46 C4 mov ax, info_real_mode_size
16CB: 26 89 45 FC mov word [ es : di - 4 ], ax
16CF: 26 C7 45 FE 10 00 mov word [ es : di - 2 ], 16
16D5: 8B 7E A8 mov di, point_to_dest_file_name
16D8: 26 FF 35 push word [ es : di ]
16DB: 51 push cx
16DC: 31 C0 xor ax, ax
16DE: 26 89 05 mov word [ es : di ], ax
16E1: 57 push di
16E2: 89 F7 mov di, si
16E4: 40 inc ax
16E5: 56 push si
16E6: 06 push es
16E7: 55 push bp
16E8: 06 push es
16E9: 1F pop ds
16EA: 0E push cs
16EB: 07 pop es
16EC: 26 FF 1E DC 0A call far dword [ es : loader_callback ]
16F1: 0E push cs
16F2: 1F pop ds
16F3: 5D pop bp
16F4: 07 pop es
16F5: 5E pop si
16F6: 83 FB 02 cmp bx, 2
16F9: 0F 87 01 02 ja .error?1D4
16FD: 89 5E 9E mov status_flag_loader_f, bx
1700: 66 C1 E2 10 shl edx, 16
1704: 89 C2 mov dx, ax
1706: 66 89 56 B6 mov save_file_size, edx
170A: 66 89 D0 mov eax, edx
170D: 5F pop di
170E: 59 pop cx
170F: 26 8F 05 pop word [ es : di ]
1712: 5F pop di
1713: 26 8F 45 FE pop word [ es : di - 2 ]
1717: 26 66 8F 45 FA pop dword [ es : di - 6 ]
171C: 60 pusha
171D: B9 0A 00 mov cx, 0x0a
1720: BF C1 05 mov di, RamdiskFile_msg
1723: 66 C7 05 20 20 20 20 mov dword [ ds : di ], ' '
172A: E8 F8 F0 call decode
172D: BE C1 05 mov si, RamdiskFile_msg
1730: E8 11 F1 call printplain
1733: 61 popa
1734: 06 push es
1735: 8B 46 C4 mov ax, info_real_mode_size
1738: 05 00 10 add ax, 0x1000
173B: 8E C0 mov es, ax
173D: 8B 7E AE mov di, firstDataSect
1740: 2B 7E B0 sub di, size_root_dir
1743: C1 E7 09 shl di, 9
1746: 03 7E AA add di, point_to_free_root
1749: BE BA 1A mov si, shot_name_fat
174C: B9 0B 00 mov cx, 11
174F: AC lodsb
1750: AA stosb
1751: E2 FC loop @b
1753: 31 C0 xor ax, ax
1755: B4 08 mov ah, ATTR_VOLUME_ID
1757: 26 89 05 mov word [ es : di ], ax
175A: 83 C7 02 add di, 2
175D: 26 C6 05 64 mov byte [ es : di ], 100
1761: 47 inc di
1762: 26 C7 05 2B 03 mov word [ es : di ], 0x032b
1767: 83 C7 02 add di, 2
176A: 26 C7 05 00 00 mov word [ es : di ], 0x0
176F: 83 C7 02 add di, 2
1772: 26 C7 05 2B 03 mov word [ es : di ], 0x032b
1777: 83 C7 02 add di, 2
177A: 26 C7 05 00 00 mov word [ es : di ], 0x0
177F: 83 C7 02 add di, 2
1782: 26 C7 05 00 00 mov word [ es : di ], 0x0
1787: 83 C7 02 add di, 2
178A: 26 C7 05 2B 03 mov word [ es : di ], 0x032b
178F: 83 C7 02 add di, 2
1792: 8B 46 B2 mov ax, point_next_fat_str
1795: 26 89 05 mov word [ es : di ], ax
1798: 83 C7 02 add di, 2
179B: 57 push di
179C: 89 C3 mov bx, ax
179E: D1 EB shr bx, 1
17A0: 01 D8 add ax, bx
17A2: 8B 1E 87 1A mov bx, word [ fat12_buffer.BPB_BytsPerSec ]
17A6: 99 cwd
17A7: F7 FB idiv bx
17A9: 89 C6 mov si, ax
17AB: 66 0F B7 06 87 1A movzx eax, word [ fat12_buffer.BPB_BytsPerSec ]
17B1: 66 0F B6 1E 89 1A movzx ebx, byte [ fat12_buffer.BPB_SecPerClus ]
17B7: 66 0F AF C3 imul eax, ebx
17BB: 66 8B 5E B6 mov ebx, save_file_size
17BF: 66 29 C3 sub ebx, eax
17C2: 66 39 C3 cmp ebx, eax
17C5: 76 29 jbe .eof_file?1US
17C7: FF 46 B2 inc point_next_fat_str
17CA: 8B 4E B2 mov cx, point_next_fat_str
17CD: 89 C2 mov dx, ax
17CF: D1 EA shr dx, 1
17D1: 01 D1 add cx, dx
17D3: F7 C6 01 00 test si, 0x1
17D7: 74 0B jz .step2?1UP
17D9: C1 E1 04 shl cx, 4
17DC: 26 89 0C mov word [ es : si ], cx
17DF: 46 inc si
17E0: 01 C1 add cx, ax
17E2: EB DB jmp @b
17E4: 81 E1 FF 0F and cx, 0x0FFF
17E8: 26 89 0C mov word [ es : si ], cx
17EB: 46 inc si
17EC: 01 C1 add cx, ax
17EE: EB CF jmp @b
17F0: B9 FF 0F mov cx, 0x0fff
17F3: F7 C6 01 00 test si, 0x1
17F7: 74 08 jz .step3?1UQ
17F9: C1 E1 04 shl cx, 4
17FC: 26 89 0C mov word [ es : si ], cx
17FF: EB 07 jmp .end?1UR
1801: 81 E1 FF 0F and cx, 0x0FFF
1805: 26 89 0C mov word [ es : si ], cx
1808: FF 46 B2 inc point_next_fat_str
180B: 5F pop di
180C: 66 8B 46 B6 mov eax, save_file_size
1810: 26 66 89 05 mov dword [ es : di ], eax
1814: 66 60 pushad
1816: 8B 7E AE mov di, firstDataSect
1819: 2B 7E B0 sub di, size_root_dir
181C: C1 E7 09 shl di, 9
181F: 03 7E AA add di, point_to_free_root
1822: BE C6 1A mov si, dest_name_fat
1825: B9 0B 00 mov cx, 11
1828: 26 8A 05 mov al, byte [ es : di ]
182B: 47 inc di
182C: 88 04 mov byte [ ds : si ], al
182E: 46 inc si
182F: E2 F7 loop @b
1831: 31 C0 xor ax, ax
1833: 88 04 mov byte [ si ], al
1835: BE C6 1A mov si, dest_name_fat
1838: E8 09 F0 call printplain
183B: 66 61 popad
183D: 83 46 AA 20 add point_to_free_root, 32
1841: 07 pop es
1842: 8B 46 C4 mov ax, info_real_mode_size
1845: BE 3C 1A mov si, table_15_87
1848: 89 44 12 mov word [ si + 8 * 2 + 2 ], ax
184B: 66 0F B7 46 AE movzx eax, firstDataSect
1850: 66 0F B7 56 A6 movzx edx, data_offset
1855: 66 01 D0 add eax, edx
1858: 66 0F B7 1E 87 1A movzx ebx, word [ fat12_buffer.BPB_BytsPerSec ]
185E: 66 0F B6 16 89 1A movzx edx, byte [ fat12_buffer.BPB_SecPerClus ]
1864: 0F AF DA imul bx, dx
1867: 66 53 push ebx
1869: 66 0F AF C3 imul eax, ebx
186D: 60 pusha
186E: B9 0A 00 mov cx, 0x0a
1871: BF 07 04 mov di, show_db1
1874: E8 AE EF call decode
1877: BE 07 04 mov si, show_db1
187A: E8 C7 EF call printplain
187D: 61 popa
187E: B2 10 mov dl, 0x10
1880: 66 3D 00 00 01 00 cmp eax, 0x00010000
1886: 72 0A jb @f
1888: 66 2D 00 00 01 00 sub eax, 0x00010000
188E: FE C2 inc dl
1890: EB EE jmp @b
1892: 88 54 1B mov byte [ si + 8 * 3 + 3 ], dl
1895: 89 44 1A mov word [ si + 8 * 3 + 2 ], ax
1898: 66 8B 4E B6 mov ecx, save_file_size
189C: 66 81 F9 FF FF 00 00 cmp ecx, 0x0000ffff
18A3: 76 0A jbe .correct_on_byte?1cJ
18A5: 66 B9 00 00 01 00 mov ecx, 0x00010000
18AB: 66 29 4E B6 sub save_file_size, ecx
18AF: 66 58 pop eax
18B1: 66 51 push ecx
18B3: FF 46 A6 inc data_offset
18B6: 66 39 C8 cmp eax, ecx
18B9: 73 05 jae @f
18BB: 66 29 C1 sub ecx, eax
18BE: EB F3 jmp @b
18C0: 66 59 pop ecx
18C2: 66 F7 C1 01 00 00 00 test ecx, 0x1
18C9: 74 02 jz .st1?1cI
18CB: 66 41 inc ecx
18CD: 66 D1 E9 shr ecx, 1
18D0: 06 push es
18D1: 1E push ds
18D2: 07 pop es
18D3: B4 87 mov ah, 0x87
18D5: CD 15 int 0x15
18D7: 07 pop es
18D8: 60 pusha
18D9: B9 0A 00 mov cx, 0x0a
18DC: BF 46 07 mov di, return_code_af_move
18DF: E8 43 EF call decode
18E2: BE 46 07 mov si, return_code_af_move
18E5: E8 5C EF call printplain
18E8: 61 popa
18E9: 83 7E 9E 01 cmp status_flag_loader_f, 0x1
18ED: 75 00 jnz @f
18EF: 8B 7E A2 mov di, save_di_RAMDISK
18F2: 8B 4E A0 mov cx, save_cx_RAMDISK
18F5: 60 pusha
18F6: 31 C0 xor ax, ax
18F8: CD 16 int 0x16
18FA: 61 popa
18FB: E9 4B FC jmp .start_loop?1D1
18FE: 89 C7 mov di, ax
1900: 89 D9 mov cx, bx
1902: E9 44 FC jmp .start_loop?1D1
1905: 8B 46 C4 mov ax, info_real_mode_size
1908: 05 00 10 add ax, 0x1000
190B: BE 3C 1A mov si, table_15_87
190E: 89 44 12 mov word [ si + 8 * 2 + 2 ], ax
1911: B8 00 02 mov ax, 512
1914: 89 44 1A mov word [ si + 8 * 3 + 2 ], ax
1917: 66 0F B7 0E 92 1A movzx ecx, word [ fat12_buffer.BPB_FATSz16 ]
191D: 0F B6 1E 8C 1A movzx bx, byte [ fat12_buffer.BPB_NumFATs ]
1922: 0F AF CB imul cx, bx
1925: 03 4E B0 add cx, size_root_dir
1928: 66 C1 E1 09 shl ecx, 9
192C: 66 F7 C1 01 00 00 00 test ecx, 0x1
1933: 74 02 jz .st1?1ho
1935: 66 41 inc ecx
1937: 66 D1 E9 shr ecx, 1
193A: 06 push es
193B: 1E push ds
193C: 07 pop es
193D: B4 87 mov ah, 0x87
193F: CD 15 int 0x15
1941: 07 pop es
1942: 60 pusha
1943: B9 0A 00 mov cx, 0x0a
1946: BF 77 07 mov di, return_code_af_fat_m
1949: E8 D9 EE call decode
194C: BE 77 07 mov si, return_code_af_fat_m
194F: E8 F2 EE call printplain
1952: 61 popa
1953: 60 pusha
1954: B9 0A 00 mov cx, 0x0a
1957: BF 07 04 mov di, show_db1
195A: E8 C8 EE call decode
195D: BE 07 04 mov si, show_db1
1960: E8 E1 EE call printplain
1963: 61 popa
1964: 60 pusha
1965: BE 21 07 mov si, make_fat12_RFS_msg
1968: E8 D9 EE call printplain
196B: 61 popa
196C: EB 1F jmp ._end_parse_FRS
196E: 89 D9 mov cx, bx
1970: 89 C7 mov di, ax
1972: BE 0B 08 mov si, parse_RFS_KRFS
1975: B9 04 00 mov cx, parse_RFS_KRFS_e - parse_RFS_KRFS
1978: F3 repe
1979: A6 cmpsb
197A: EB 11 jmp ._end_parse_FRS
197C: 89 D9 mov cx, bx
197E: 89 C7 mov di, ax
1980: E9 A4 F8 jmp .start_g_tpe_RFS
1983: 83 4E C0 01 or show_errors_sect, show_error_1
1987: EB 04 jmp ._end_parse_FRS
1989: 83 4E C0 02 or show_errors_sect, show_error_2
198D: 60 pusha
198E: BE 34 07 mov si, get_type_FS_msg
1991: E8 B0 EE call printplain
1994: 61 popa
1995: 31 C0 xor ax, ax
1997: CD 16 int 0x16
1999: 8B 7E F4 mov di, point_default
199C: 8B 4E FA mov cx, save_cx_d
199F: E8 D1 EE call get_firs_sym
19A2: 85 C9 test cx, cx
19A4: 0F 84 8E 00 jz ._afterLoaderModule
19A8: 3C 4C cmp al, 'L'
19AA: 75 F3 jnz .start_p_LM
19AC: 89 CB mov bx, cx
19AE: 89 F8 mov ax, di
19B0: BE CD 07 mov si, parse_LoaderModule
19B3: B9 0C 00 mov cx, parse_LoaderModule_e - parse_LoaderModule
19B6: F3 repe
19B7: A6 cmpsb
19B8: 75 75 jnz .rest_value_loop_LM
19BA: 83 EB 0C sub bx, parse_LoaderModule_e - parse_LoaderModule
19BD: 01 CB add bx, cx
19BF: 89 D9 mov cx, bx
19C1: F7 46 F8 01 00 test status_flag, flag_found_LM
19C6: 74 00 jz .correct_is_not_set_LM
19C8: B8 20 3D mov ax, 0x3d20
19CB: F3 repe
19CC: AE scasb
19CD: E3 60 jcxz .rest_value_loop_LM
19CF: 26 3A 65 FF cmp ah, byte [ es : di - 1 ]
19D3: 75 5A jnz .rest_value_loop_LM
19D5: F3 repe
19D6: AE scasb
19D7: 41 inc cx
19D8: 4F dec di
19D9: 26 66 FF 75 FA push dword [ es : di - 6 ]
19DE: 8D 75 FA lea si, [ di - 6 ]
19E1: 26 FF 75 FE push word [ es : di - 2 ]
19E5: 31 C0 xor ax, ax
19E7: 26 89 45 FA mov word [ es : di - 6 ], ax
19EB: 8B 46 C4 mov ax, info_real_mode_size
19EE: 26 89 45 FC mov word [ es : di - 4 ], ax
19F2: 26 C7 45 FE 10 00 mov word [ es : di - 2 ], 16
19F8: 26 8A 05 mov al, byte [ es : di ]
19FB: 3C 20 cmp al, ' '
19FD: 74 0C jz .found_end_str?1mb
19FF: 3C 0A cmp al, 0xa
1A01: 74 08 jz .found_end_str?1mb
1A03: 3C 0D cmp al, 0xd
1A05: 74 04 jz .found_end_str?1mb
1A07: 47 inc di
1A08: 49 dec cx
1A09: 75 ED jnz @b
1A0B: 26 FF 35 push word [ es : di ]
1A0E: 31 C0 xor ax, ax
1A10: 26 89 05 mov word [ es : di ], ax
1A13: 89 F7 mov di, si
1A15: 40 inc ax
1A16: 56 push si
1A17: 06 push es
1A18: 06 push es
1A19: 1F pop ds
1A1A: 0E push cs
1A1B: 07 pop es
1A1C: 26 FF 1E DC 0A call far dword [ es : loader_callback ]
1A21: 0E push cs
1A22: 1F pop ds
1A23: 07 pop es
1A24: 5E pop si
1A25: 85 DB test bx, bx
1A27: 75 03 jnz .error_LM
1A29: 26 FF 2C jmp far dword [ es : si ]
1A2C: E8 91 F0 call error.LoaderModule
1A2F: 89 C7 mov di, ax
1A31: 89 D9 mov cx, bx
1A33: E9 69 FF jmp .start_p_LM
1A36: EB FE jmp $
1A38: E9 6A F1 jmp ini_loaded
1A3C: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0
1A44: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0
1A4C: FF FF db 0xff, 0xff
1A4E: 00 10 db 0x0, 0x10
1A50: 00 93 00 00 db 0x00, 0x93, 0x0, 0x0
1A54: FF FF 00 00 10 93 00 00 db 0xff, 0xff, 0x0, 0x00, 0x10, 0x93, 0x0, 0x0
1A5C: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0
1A64: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0
1A6C: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0
1A74: 00 00 00 00 00 00 00 00 db 0x00, 0x00, 0x0, 0x00, 0x00, 0x00, 0x0, 0x0
1A7C: 90 90 90 .BS_jmpBoot db 0x90, 0x90, 0x90
1A7F: 4B 20 53 79 53 20 36 34 .BS_OEMName db 'K SyS 64'
1A87: 00 02 .BPB_BytsPerSec dw 512
1A89: 01 .BPB_SecPerClus db 0x1
1A8A: 01 00 .BPB_RsvdSecCnt dw 0x1
1A8C: 01 .BPB_NumFATs db 0x1
1A8D: 00 02 .BPB_RootEntCnt dw 512
1A8F: 00 00 .BPB_TotSec16 dw 0x0
1A91: F0 .BPB_Media db 0xF0
1A92: 00 00 .BPB_FATSz16 dw 0x0
1A94: 00 00 .BPB_SecPerTrk dw 0x0
1A96: 00 00 .BPB_NumHeads dw 0x0
1A98: 00 00 00 00 .BPB_HiddSec dd 0x0
1A9C: 00 00 00 00 .BPB_TotSec32 dd 0x0
1AA0: 52 .BS_DrvNum db 'R'
1AA1: 00 .BS_Reserved1 db 0x0
1AA2: 29 .BS_BootSig db 0x29
1AA3: 52 46 4B 53 .BS_VolID db 'RFKS'
1AA7: 52 41 4D 20 44 49 53 4B 20 46 53 .BS_VolLab db 'RAM DISK FS'
1AB2: 46 41 54 31 32 20 20 20 .BS_FilSysType db 'FAT12 '
1ABA: shot_name_fat rb 11
1AC5: rb 1
1AC6: dest_name_fat rb 12
1AD2: value_timeout rw 1
1AD4: old_timer rd 1
1AD8: start_timer rd 1
1ADC: timer_ rd 1
1AE0: start_stack rw 1
1AE2: save_bp_from_timer rw 1
3 passes, 0.8 seconds, 6842 bytes.
/kernel/branches/Kolibri-acpi/sec_loader/trunk/sl_equ.inc
0,0 → 1,98
; Copyright (c) 2008-2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
; Ïðåäîïðåäåëåíèÿ
DEBUG equ 1 ;êîìïèëÿöèÿ ñ îòëàäî÷íîé èíôîðìàöèåé =1 áåç îòëàäî÷íîé èíôîðàöèè =0
loop_read_startos_file equ 3 ;êîë-âî ïîïûòîê ñ÷èòàòü ÷åðåç callback ñåðâèñ ôàéë êîíôèãóðàöèè áëîê2
root_dir_entry_count equ 224 ;êîë-âî ýëåìåíòîâ â êîðíåâîé äèððåêòîðèè
;point_to_fat_struc equ 0xA000 ;âðåìåííûé áóôåð, êóäà áóäåò ðàçìåùåíà Fat òàáëèöà, è çàòåì ïåðåíåñåíà çà 1 ìá
ini_data_ equ 0x2000 ;ôàéë ãäå ðàçìåùåí ôàéë ñöåíàðèÿ çàãðóçêè, òàì ïðîèñõîäèò ñèíòàêñè÷åñêèé ðàçáîð
size_show_section equ 18
default_timeout_value equ 5 ;default value to timeout is will was some errors
flag_found_default equ 0x1 ;default value is found
flag_found_timeout equ 0x2 ;timeout value is found
flag_found_LM equ 0x1 ;found LM value
flag_found_RS equ 0x2 ;found RS value
flag_found_GTRFMS equ 0x4 ;found type RamFS
flag_found_RamdiskSector equ 0x8 ;found RamdiskSector
flag_found_RamdiskCluster equ 0x16 ;found RamdiskCluster
;statick data ýòè äàííûå íå ïðåäîïðåäåëÿþòñÿ â òå÷åíèè âûïîëíåíèÿ âñåé ïðîãðàììû.
save_cx equ word [bp-2] ;save cx size ini file
ret_on_ch equ word [bp-4] ;point to return ðàçðóøàåìîå çíà÷åíèå
save_cx_d equ word [bp-6] ;save cx - size default section and working section
status_flag equ word [bp-8] ;status flag
point_loader equ word [bp-10]
point_default equ word [bp-12] ;point to default
 
;äàííûå êîòîðûå çàâèñèìû îò âåòêè âûïîëíåíèÿ è êîòîðûå ìîãóò áûòü ïåðåîïðåäåëåíû â ïðîöåññå âûïîëíåíèÿ ïðîãðàììû.
point_to_hframe equ word [bp-14] ;point on start frame (for change section)
point_to_1 equ word [bp-16]
point_to_2 equ word [bp-18]
point_to_3 equ word [bp-20]
point_to_4 equ word [bp-22]
point_to_5 equ word [bp-24]
point_to_6 equ word [bp-26]
point_to_7 equ word [bp-28]
point_to_8 equ word [bp-30]
point_to_9 equ word [bp-32]
point_to_10 equ word [bp-34]
point_to_11 equ word [bp-36]
point_to_12 equ word [bp-38]
point_to_13 equ word [bp-40]
point_to_14 equ word [bp-42]
point_to_15 equ word [bp-44]
point_to_16 equ word [bp-46]
point_to_16 equ word [bp-48]
point_to_17 equ word [bp-50]
point_to_18 equ word [bp-52]
;here array for fast scroling 16 word - poin to start section
point_to_point_def equ word [bp-54]
point_to_eframe equ word [bp-56] ;point on point frame
 
 
 
; òóò ðàñïîëîæåíî âðåìåííîå õðàíèëèùå äëÿ cx è di ïðè ïåðåõîäå íà ñëåäóþùèé áóôåð ïðè ïîèñêå ñåêöèé
find_sec_di equ word [bp-58] ;òóò áóäåò õðàíèòüñÿ di
info_real_mode_size equ word [bp-60];òóò õðàíèòüñÿ èíôîðìàöèÿ î çàíÿòîé îáëàñòè ò.å. ðàçìåð, ìîæíî óçíàòü ñêîëüêî îñòàëîñü ìåñòà âû÷èñëèâ
free_ad_memory equ word [bp-62] ;ñêîëüêî ó íàñ ðàñøèðåííîé ïàìÿòè äëÿ ôîðìèðîâàíèÿ ðàì äèñêà è çàãðóçêè ìîäóëåé
show_errors_sect equ word [bp-64] ;ïåðåìåíàÿ êîòîðàÿ õðàíèò áèòû îøèáîê äëÿ êàæäîé ëîãè÷åñêîé ñåêöèè.
save_descript_size equ word [bp-66] ;save descript size previos section ñîõðàíèì ðàçìåð ïðåäûäóùåé ñåêöèè êîòîðóþ âûâîäèëè
save_ramdisksize equ dword [bp-70] ;save size of ramdisk in byte
save_file_size equ dword [bp-74] ;save size of reading file
set_ramfs equ word [bp-76] ;îïðåäåëåííûé òèï ôàéëîâîé ñèñòåìû,íóæíî äëÿ ôîðìèðîâàíèÿ ðàì äèñêà
point_next_fat_str equ word [bp-78] ;óêàçàòåëü íà ñëåäóþùèé ýëåìåíò fat òàáëèöû
size_root_dir equ word [bp-80] ;êîë-âî ýëåìåíòîâ â ñåêòîðàõ ïî 512 áàéò êîðíåâîé äèðåêòîðèè
firstDataSect equ word [bp-82] ;ïåðâûé ñåêòîð äàííûõ â ñåòîðàõ îò 0
DataClasters equ word [bp-84] ;ðàçìåð ìàññèâà äîñòóïíîé äëÿ çàïèñè äàííûõ â êëàñòåðàõ.
point_to_free_root equ word [bp-86] ;óêàçàòåëü íà ñëåäóþùèé ïóñòóþ çàïèñü â ðóò äèð
point_to_dest_file_name equ word [bp-88] ;óêàçûâàåò íà íà÷àëî èìåíè ôàéëà íàçíà÷åíèÿ. â ôîðìàòå es:point_to_dest_file_name, ãäå es =0x2000
data_offset equ word [bp-90] ;ñìåùåíèå â êëàñòåðàõ äëÿ çàïèñàííûõ äàííûõ ò.å ïåðåêèíóòûõ çà 1-é ìá
first_input equ word [bp-92] ;ïîëå äëÿ ôëàãîâ â ïðåîáðàçîâàíèè èìåíè.
save_di_RAMDISK equ word [bp-94] ;ñîõðàíèì di -óêàçàòåëÿ ïðè îáðàáîòêå ñåêöèè
save_cx_RAMDISK equ word [bp-96] ;ñîõðàíèì ðàçìåð îñòàòêà ñåêöèè
status_flag_loader_f equ word [bp-98] ;ñîõðàíèì ðåçóëüòàò âûïîëåíåíèÿ çàãðóçêè ôàéëà
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;äàííûå êîòîðûå èñïîëüçóþòñÿ ïðè îáðàáîòêå ñåêöèè, ò.å. ïîñëå íàæàòèÿ Enter, óæå íå âîçìîæíî âåðíóòüñÿ â ïåðâîíà÷àëüíûé ýêðàí
;äëÿ âîçâðàòà, íåîáõîäèìî ïåðåçàïóñòèòü ïîëíîñòüþ êîä ò.å. ñòàðòîâàòü ñ 0õ1000:0000
/kernel/branches/Kolibri-acpi/sec_loader/trunk/startos.ini
0,0 → 1,98
; Copyright (c) 2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
; ýòî êîììåíòàðèé
[loader]
; ñåêöèÿ [loader] ñîäåðæèò ïàðàìåòðû çàãðóç÷èêà
; â òå÷åíèå timeout ñåêóíä çàãðóç÷èê áóäåò æäàòü ðåàêöèè ïîëüçîâàòåëÿ,
; åñëè å¸ íå ïîñëåäóåò, áóäåò çàãðóæåíà êîíôèãóðàöèÿ, óêàçàííàÿ â default
timeout=5
default=kolibri_EE
; ïðî÷èå ñåêöèè - ïî îäíîé íà êàæäóþ êîíôèãóðàöèþ
; è ïî îäíîé íà êàæäûé âòîðè÷íûé ìîäóëü
[main]
name="Kord OS v 0.00001"
descript="This is x64 OS microkernel"
kernel=kord/kord001.ker
module=kord/fat.mod
module=kord/ntfs.mod
RamdiskFS=fat
RamdiskSector=512
RamdiskCluster=1
RamdiskSize=1440K
RamdiskFile=kord/launcher,launcher
RamdiskFile=kord/filema~1/kfar,"File Managers/kfar"
[beta]
name="Kord OS v 0.00002 beta"
descript="This is x64 OS microkernel version 2"
kernel=kord/kord002.ker
module=kord/fat.mod
module=kord/ntfs.mod
RamdiskFS=fat
RamdiskSector=512
RamdiskCluster=1
RamdiskSize=1440K
RamdiskFile=kord/launcher,launcher
RamdiskFile=kord/filema~1/kfar,"File Managers/kfar"
[kolibri_EE]
name="KOLIBRY EXCLUSIVE EDITION"
descript="KOLIBRY EXCLUSIVE EDITION BEST OF THE BEST opetation system"
LoaderModule=kolibri/kolibri.ldm
RamdiskFS=FAT
RamdiskSector=512
RamdiskCluster=1
RamdiskSize=1440K
LoaderRamImage=kolibri.img
RamdiskPATH=/kolibri/
RamdiskFile=@menu,@menu
RamdiskFile=@PANEL,@PANEL
RamdiskFile=@RB,@PANEL
 
[legacy_kolibri]
name="KolibriOS"
descript="Standart KolibriOS"
LoaderModule=kord/kolibri.ldm
RamdiskFS=fat
RamdiskSector=512
RamdiskCluster=1
RamdiskSize=1440K
RamdiskPATH=/kolibri/
RamdiskFile=@menu,@menu
RamdiskFile=@PANEL,@PANEL
RamdiskFile=@RB,@RB
RamdiskFile=@rcher,@rcher
RamdiskFile=@ss,@ss
RamdiskFile=ac97snd,ac97snd
RamdiskFile=animage,animage
RamdiskFile=AUTOEXEC.CMD,AUTOEXEC.CMD
RamdiskFile=AUTORUN.DAT,AUTORUN.DAT
RamdiskFile=calc,calc
RamdiskFile=calendar,calendar
RamdiskFile=progs/cdp,cdp
RamdiskFile=cmd,cmd
RamdiskFile=config.inc,config.inc
RamdiskFile=copy2,copy2
 
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/build.bat
0,0 → 1,20
echo off
cls
echo ** bulding after win loader **
@fasm -m 65535 after_win/kordldr.win.asm after_win/kordldr.win
echo ==============================
echo ** building first loader for cd/dvd **
@fasm -m 65535 cdfs/bootsect.asm cdfs/bootsect.bin
echo ==============================
echo ** building first loader for fat12/fat16 **
@fasm -m 65535 fat1x/bootsect.asm fat1x/bootsect.bin
@fasm -m 65535 fat1x/kordldr.f1x.asm fat1x/kordldr.f1x
echo ==============================
echo ** building firs loader for fat32 **
@fasm -m 65535 fat32/bootsect.asm fat32/bootsect.bin
@fasm -m 65535 fat32/kordldr.f1x.asm fat32/kordldr.f1x
echo ==============================
echo ** make a image of fdd **
@fasm -m 65535 floppy.asc kord.img
 
@pause
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/floppy.asc
0,0 → 1,49
include "mkfloppy.inc"
;// insert boot sect
file "fat1x/bootsect.bin", 512
 
; fat1
db 0F0h, 0FFh, 0FFh, 9*512-3 dup 0
; fat2
db 0F0h, 0FFh, 0FFh, 9*512-3 dup 0
 
; root
dent kordldr, "KORDLDR F1X", FA_ARC
dent kord, "KORD ",FA_DIR
dent kolibri, "KOLIBRI ",FA_DIR
; ...
 
rb 33*512-$
;///////////////////////////
defdir kord
{
dent loader, "LOADER ", FA_ARC
dent ini,"STARTOS INI", FA_ARC
}
 
defdir kolibri
{
dent kolibri_ldm, "KOLIBRI LDM", FA_ARC
}
 
 
; data
stof kordldr, "fat1x/kordldr.f1x"
stod kord,root
 
stof loader, "../loader"
stof ini,"../startos.ini"
 
store dword ini_base/512+1 at ini_base+1F8h
store word (ini_size+511)/512-1 at ini_base+1FCh
store word 220h at ini_base+1FEh
 
stod kolibri,root
stof kolibri_ldm, "../kolibri_ldm/bin/kolibri.ldm"
store dword kolibri_ldm_base/512+1 at kolibri_ldm_base+1F8h
store word (kolibri_ldm_size+511)/512-1 at kolibri_ldm_base+1FCh
store word 220h at kolibri_ldm_base+1FEh
 
 
; ...
rb 2*80*18*512-$
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/mkfloppy.inc
0,0 → 1,90
; ---------------------------------------------------------------------------
; mkfloppy.inc
; ---------------------------------------------------------------------------
; Created by Phantom-84
; ---------------------------------------------------------------------------
 
FA_RO equ 01h
FA_HID equ 02h
FA_SYS equ 04h
FA_VOL equ 08h
FA_DIR equ 10h
FA_ARC equ 20h
 
DSTAMP equ 28C1h
TSTAMP equ 6000h
 
root_size=0
 
macro reset id
{
local count, cur, disp, val, var
times 511-($+511) mod 512 db 0
if id#_size>0
count=(id#_size+511)/512
cur=id#_base/512-(33-2)
repeat count
if %=count
val=0FFFh
else
val=cur+1
end if
if cur and 1
val=val shl 4
end if
disp=(cur*3)/2
load var word from 512+disp
var=var or val
store word var at 512+disp
store word var at 10*512+disp
cur=cur+1
end repeat
end if
}
 
macro dent id, name, attr
{
@@ db name
times @b+11-$ db 32
db attr
dw 0, TSTAMP, DSTAMP, DSTAMP, 0, TSTAMP, DSTAMP
if id#_size=0
dw 0
else
dw id#_base/512-(33-2)
end if
if (attr) and FA_DIR
dd 0
else
dd id#_size
end if
}
 
macro orgdir id, parentid
{
id#_base:
dent id, ".", FA_DIR
dent parentid, "..", FA_DIR
}
 
macro findir id
{
id#_size=$-id#_base
reset id
}
 
macro stod id, parentid
{
orgdir id, parentid
id
findir id
}
 
macro stof id, name
{
id#_base: file name
id#_size=$-id#_base
reset id
}
 
defdir fix macro
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/build.bat
0,0 → 1,2
@fasm -m 65535 kordldr.win.asm kordldr.win
@pause
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/fat.inc
0,0 → 1,509
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
; in: ss:bp = 0:dat
; in: es:bx = address to load file
; in: ds:si -> ASCIIZ name
; in: cx = limit in sectors
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file has been loaded, bx=2 - file not found
; out: dx:ax = file size (0xFFFFFFFF if file not found)
load_file_fat:
mov eax, [bp + root_clus - dat]
mov [bp + cur_obj - dat], root_string
push es
push bx
push cx
.parse_dir_loop:
; convert name to FAT name
push [bp + cur_obj - dat]
push ax
mov [bp + cur_obj - dat], si
push ss
pop es
; convert ASCIIZ filename to FAT name
mov di, fat_filename
push di
mov cx, 8+3
mov al, ' '
rep stosb
pop di
mov cl, 8 ; 8 symbols per name
mov bl, 1
.nameloop:
lodsb
test al, al
jz .namedone
cmp al, '/'
jz .namedone
cmp al, '.'
jz .namedot
dec cx
js .badname
cmp al, 'a'
jb @f
cmp al, 'z'
ja @f
sub al, 'a'-'A'
@@:
stosb
jmp .nameloop
.namedot:
inc bx
jp .badname
add di, cx
mov cl, 3
jmp .nameloop
.badname:
mov si, badname_msg
jmp find_error_si
.namedone:
; scan directory
pop ax ; eax = cluster of directory
; high word of eax is preserved by operations above
push ds
push si
; read a folder sector-by-sector and scan
; first, try to use the cache
push ss
pop ds
mov bx, -2
mov cx, [bp + rootcache_size - dat]
cmp [bp + root_clus - dat], eax
jz .lookcache_root
mov di, foldcache_mark
xor bx, bx
mov cx, [bp + cachelimit - dat]
@@:
lea si, [di+bx]
mov edx, dword [foldcache_clus+si-foldcache_mark+bx]
cmp edx, eax
jz .cacheok
test edx, edx
jz .cacheadd ; the cache has place for new entry
inc bx
inc bx
dec cx
js @b
; the folder is not present in the cache, so add it
; the cache is full; find the oldest entry and replace it with the new one
mov bx, -2
mov dx, [bp + cachelimit - dat]
@@:
inc bx
inc bx
cmp word [di+bx], dx ; marks have values 0 through [cachelimit]
jnz @b
.cacheadd:
or word [di+bx], 0xFFFF ; very big value, it will be changed soon
and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet
lea si, [di+bx]
mov dword [foldcache_clus+si-foldcache_mark+bx], eax
.cacheok:
; update cache marks
mov dx, [di+bx]
mov cx, [foldcache_size+di-foldcache_mark+bx]
mov di, [bp + cachelimit - dat]
add di, di
.cacheupdate:
cmp [foldcache_mark+di], dx
adc [foldcache_mark+di], 0
dec di
dec di
jns .cacheupdate
and [foldcache_mark+bx], 0
; done, bx contains (position in cache)*2
.lookcache_root:
; bx = (position in cache)*2 for non-root folders; bx = -2 for root folder
;mov dx, bx
;shl dx, 8
;add dx, 0x9200
lea dx, [bx + 0x92]
xchg dl, dh
mov ds, dx
mov si, fat_filename ; ss:si -> filename in FAT style
call fat_scan_for_filename
jz .lookup_done
; cache miss, read folder data from disk
; we are reading parent directory, it can result in disk read errors; restore [cur_obj]
mov di, sp
mov bx, [bp + cur_obj - dat]
xchg bx, [ss:di+4]
mov [bp + cur_obj - dat], bx
mov bx, cx
add bx, 0xF
shr bx, 4
shl cx, 5
mov di, cx ; es:di -> free space in cache entry
; external loop: scan clusters
.folder_next_cluster:
; internal loop: scan sectors in cluster
movzx ecx, byte [ss:0x320D] ; BPB_SecPerClus
push eax
; FAT12/16 root - special handling
test eax, eax
jnz .folder_notroot
mov cx, [ss:0x3211] ; BPB_RootEntCnt
mov dx, cx
add cx, 0xF
rcr cx, 1
shr cx, 3
mov eax, [bp + root_start - dat]
jmp .folder_next_sector
.folder_notroot:
mul ecx
add eax, [bp + data_start - dat]
.folder_next_sector:
sub dx, 0x10
; skip first bx sectors
dec bx
jns .folder_skip_sector
push cx
push es di
push 0x8000
pop es
xor bx, bx
mov cx, 1
push es
call read
jc ..found_disk_error
; copy data to the cache...
pop ds
pop di es
cmp di, 0x2000 ; ...if there is free space, of course
jae @f
pusha
mov cx, 0x100
xor si, si
rep movsw
mov di, es
shr di, 8
cmp di, 0x90
jz .update_rootcache_size
add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache
jmp .updated_cachesize
.update_rootcache_size:
mov cl, 0x10
cmp cx, dx
jb @f
mov cx, dx
@@:
add [bp + rootcache_size - dat], cx
.updated_cachesize:
popa
@@:
push es
mov cl, 0x10 ; ch=0 at this point
cmp cx, dx
jb @f
mov cx, dx
@@:
call fat_scan_for_filename
pop es
pop cx
jz .lookup_done_pop
.folder_skip_sector:
inc eax
loop .folder_next_sector
pop eax ; eax = current cluster
test eax, eax
jz @f
call [bp + get_next_cluster_ptr - dat]
jc .folder_next_cluster
@@:
stc
push eax
.lookup_done_pop:
pop eax
.lookup_done:
pop si
; CF=1 <=> failed
jnc .found
pop ds
pop [bp + cur_obj - dat]
mov si, error_not_found
jmp find_error_si
.found:
mov eax, [di+20-2]
mov edx, [di+28]
mov ax, [di+26] ; get cluster
test byte [di+11], 10h ; directory?
pop ds
pop [bp + cur_obj - dat] ; forget old [cur_obj]
jz .regular_file
cmp byte [si-1], 0
jnz .parse_dir_loop
..directory_error:
mov si, directory_string
jmp find_error_si
.regular_file:
cmp byte [si-1], 0
jz @f
..notdir_error:
mov si, notdir_string
jmp find_error_si
@@:
; ok, we have found a regular file and the caller requested it
; parse FAT chunk
push ss
pop es
push ss
pop ds
mov di, 0x4005
mov byte [di-5], 1 ; non-resident attribute
mov dword [di-4], 1
stosd
pop cx
push cx
.parsefat:
call [bp + get_next_cluster_ptr - dat]
jnc .done
mov esi, [di-8]
add esi, [di-4]
cmp eax, esi
jz .contc
mov dword [di], 1
scasd
stosd
jmp @f
.contc:
inc dword [di-8]
@@:
sub cl, [0x320D]
sbb ch, 0
ja .parsefat
.done:
xor eax, eax
stosd
mov si, 0x4000
load_file_common_end:
xor ecx, ecx
pop cx
pop bx
pop es
mov [bp + filesize - dat], edx
mov [bp + sectors_read - dat], ecx
add edx, 0x1FF
shr edx, 9
mov [bp + filesize_sectors - dat], edx
cmp edx, ecx
seta al
mov ah, 0
push ax
call read_file_chunk
continue_load_common_end:
mov [bp + cur_chunk_ptr - dat], si
pop bx
mov ax, word [bp + filesize - dat]
mov dx, word [bp + filesize+2 - dat]
jnc @f
mov bl, 3 ; read error
@@:
ret
 
continue_load_file:
; es:bx -> buffer for output, ecx = cx = number of sectors
mov si, [bp + cur_chunk_ptr - dat]
push ecx
add ecx, [bp + sectors_read - dat]
mov [bp + sectors_read - dat], ecx
cmp [bp + filesize_sectors - dat], ecx
pop ecx
seta al
mov ah, 0
push ax
push continue_load_common_end
push ss
pop ds
cmp [bp + cur_chunk_resident - dat], ah
jnz .nonresident
.resident:
mov ax, word [bp + num_sectors - dat]
jmp read_file_chunk.resident.continue
.nonresident:
mov eax, [bp + cur_cluster - dat]
mov edx, [bp + num_sectors - dat]
add eax, [bp + cur_delta - dat]
jmp read_file_chunk.nonresident.continue
 
fat_scan_for_filename:
; in: ss:si -> 11-bytes FAT name
; in: ds:0 -> part of directory data
; in: cx = number of entries
; out: if found: CF=0, ZF=1, es:di -> directory entry
; out: if not found, but continue required: CF=1 and ZF=0
; out: if not found and zero item reached: CF=1 and ZF=1
push ds
pop es
xor di, di
push cx
jcxz .noent
.loop:
cmp byte [di], 0
jz .notfound
test byte [di+11], 8 ; volume label?
jnz .cont ; ignore volume labels
pusha
mov cx, 11
repz cmps byte [ss:si], byte [es:di]
popa
jz .done
.cont:
add di, 0x20
loop .loop
.noent:
inc cx ; clear ZF flag
.notfound:
stc
.done:
pop cx
ret
 
fat12_get_next_cluster:
; in: ax = cluster (high word of eax is zero)
; out: if there is next cluster: CF=1, ax = next cluster
; out: if there is no next cluster: CF=0
push si
push ds
push 0x6000
pop ds
mov si, ax
shr si, 1
add si, ax
test al, 1
lodsw
jz @f
shr ax, 4
@@:
and ax, 0xFFF
cmp ax, 0xFF7
pop ds si
ret
 
fat16_get_next_cluster:
; in: ax = cluster (high word of eax is zero)
; out: if there is next cluster: CF=1, ax = next cluster
; out: if there is no next cluster: CF=0
; each sector contains 200h bytes = 100h FAT entries
; so ah = # of sector, al = offset in sector
push si
mov si, ax
shr si, 8
; calculate segment for this sector of FAT table
; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si)
; segment = 6000 + 20*si, offset = 0
push es
push si
shl si, 5
add si, 0x6000
mov es, si
pop si
cmp byte [ss:0x3400+si], 0 ; sector already loaded?
jnz .noread
; load corresponding sector, try all FATs if disk read error detected
pusha
movzx di, byte [ss:0x3210] ; BPB_NumFATs
xor bx, bx
mov ax, [ss:0x320E] ; BPB_RsvdSecCnt
xor dx, dx
add ax, si
adc dx, bx
@@:
push es
push dx ax
pop eax
mov cx, 1 ; read 1 sector
call read
pop es
jnc @f
add ax, [ss:0x3216] ; BPB_FATSz16
adc dx, bx
dec di
jnz @b
..found_disk_error:
mov si, disk_error_msg
jmp find_error_si
@@:
popa
.noread:
mov si, ax
and si, 0xFF
add si, si
mov ax, [es:si]
pop es
cmp ax, 0xFFF7
pop si
ret
 
fat32_get_next_cluster:
; in: eax = cluster
; out: if there is next cluster: CF=1, eax = next cluster
; out: if there is no next cluster: CF=0
push di
push ax
shr eax, 7
; eax = FAT sector number; look in cache
push si
mov si, cache1head
call cache_lookup
pop si
jnc .noread
; read FAT, try all FATs if disk read error detected
push es
pushad
movzx edx, word [ss:0x320E] ; BPB_RsvdSecCnt
add eax, edx
movzx si, byte [ss:0x3210] ; BPB_NumFATs
@@:
lea cx, [di - 0x3400 + (0x6000 shr (9-3))]
shl cx, 9-3
mov es, cx
xor bx, bx
mov cx, 1
call read
jnc @f
add eax, [ss:0x3224] ; BPB_FATSz32
dec si
jnz @b
jmp ..found_disk_error
@@:
popad
pop es
.noread:
; get requested item
lea ax, [di - 0x3400 + (0x6000 shr (9-3))]
pop di
and di, 0x7F
shl di, 2
shl ax, 9-3
push ds
mov ds, ax
and byte [di+3], 0x0F
mov eax, [di]
pop ds
pop di
;and eax, 0x0FFFFFFF
cmp eax, 0x0FFFFFF7
ret
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/kordldr.win.asm
0,0 → 1,921
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
; KordOS bootloader, based on mtldr, KolibriOS bootloader, by diamond
; It is used when main bootloader is Windows loader.
 
; this code is loaded:
; NT/2k/XP: by ntldr to 0D00:0000
; 9x: by io.sys from config.sys to xxxx:0100
; Vista: by bootmgr to 0000:7C00
format binary
use16
 
; in any case, we relocate this code to 0000:0600
org 0x600
; entry point for 9x and Vista booting
call @f
db 'NTFS'
@@:
pop si
sub si, 3
cmp si, 100h
jnz boot_vista
mov si, load_question + 100h - 600h
call out_string
; mov si, answer + 100h - 0600h ; already is
xxy: mov ah, 0
int 16h
or al, 20h
mov [si], al
cmp al, 'y'
jz xxz
cmp al, 'n'
jnz xxy
; continue load Windows
; call out_string
; ret
out_string:
push bx
@@:
lodsb
test al, al
jz @f
mov ah, 0Eh
mov bx, 7
int 10h
jmp @b
@@:
pop bx
ret
xxz:
; boot KordOS
call out_string
; 9x bootloader has already hooked some interrupts; to correctly remove all DOS handlers,
; issue int 19h (reboot interrupt) and trace its DOS handler until original BIOS handler is reached
xor di, di
mov ds, di
mov word [di+4], new01handler + 100h - 600h
mov [di+6], cs
pushf
pop ax
or ah, 1
push ax
popf
; we cannot issue INT 19h directly, because INT command clears TF
; int 19h ; don't issue it directly, because INT command clears TF
; so instead we use direct call
; pushf ; there will be no IRET
call far [di + 19h*4]
xxt:
xor di, di
mov ds, di
cmp word [di + 8*4+2], 0F000h
jz @f
les bx, [di + 8*4]
mov eax, [es:bx+1]
mov [di + 8*4], eax
@@:
mov si, 100h
boot_vista:
; relocate cs:si -> 0000:0600
push cs
pop ds
xor ax, ax
mov es, ax
mov di, 0x600
mov cx, 2000h/2
rep movsw
jmp 0:real_entry
 
load_question db 'Load KordOS? [y/n]: ',0
answer db ?
db 13,10,0
 
new01handler:
; [sp]=ip, [sp+2]=cs, [sp+4]=flags
push bp
mov bp, sp
push ds
lds bp, [bp+2]
cmp word [ds:bp], 19cdh
jz xxt
pop ds
pop bp
iret
 
; read from hard disk
; in: eax = absolute sector
; cx = number of sectors
; es:bx -> buffer
; out: CF=1 if error
read:
pushad
add eax, [bp + partition_start - dat]
cmp [bp + use_lba - dat], 0
jz .chs
; LBA read
push ds
.lbado:
push ax
push cx
cmp cx, 0x7F
jbe @f
mov cx, 0x7F
@@:
; create disk address packet on the stack
; dq starting LBA
push 0
push 0
push eax
; dd buffer
push es
push bx
; dw number of blocks to transfer (no more than 0x7F)
push cx
; dw packet size in bytes
push 10h
; issue BIOS call
push ss
pop ds
mov si, sp
mov dl, [bp + boot_drive - dat]
mov ah, 42h
int 13h
jc .disk_error_lba
add sp, 10h ; restore stack
; increase current sector & buffer; decrease number of sectors
movzx esi, cx
mov ax, es
shl cx, 5
add ax, cx
mov es, ax
pop cx
pop ax
add eax, esi
sub cx, si
jnz .lbado
pop ds
popad
ret
.disk_error_lba:
add sp, 14h
pop ds
popad
stc
ret
 
.chs:
pusha
pop edi ; loword(edi) = di, hiword(edi) = si
push bx
 
; eax / (SectorsPerTrack) -> eax, remainder bx
movzx esi, [bp + sectors - dat]
xor edx, edx
div esi
mov bx, dx ; bx = sector-1
 
; eax -> dx:ax
push eax
pop ax
pop dx
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
div [bp + heads - dat]
 
; number of sectors: read no more than to end of track
sub si, bx
cmp cx, si
jbe @f
mov cx, si
@@:
 
inc bx
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector
; convert to int13 format
movzx edi, cx
mov dh, dl
mov dl, [bp + boot_drive - dat]
shl ah, 6
mov ch, al
mov al, cl
mov cl, bl
or cl, ah
pop bx
mov si, 3
mov ah, 2
@@:
push ax
int 13h
jnc @f
xor ax, ax
int 13h ; reset drive
pop ax
dec si
jnz @b
add sp, 12
popad
stc
ret
@@:
pop ax
mov ax, es
mov cx, di
shl cx, 5
add ax, cx
mov es, ax
push edi
popa
add eax, edi
sub cx, di
jnz .chs
popad
ret
 
disk_error2 db 'Fatal: cannot read partitions info: '
disk_error_msg db 'disk read error',0
disk_params_msg db 'Fatal: cannot get drive parameters',0
start_msg db 2,' KordOS bootloader',13,10,0
part_msg db 'looking at partition '
part_char db '0' ; will be incremented before writing message
db ' ... ',0
errfs_msg db 'unknown filesystem',13,10,0
fatxx_msg db 'FATxx'
newline db 13,10,0
ntfs_msg db 'NTFS',13,10,0
error_msg db 'Error'
colon db ': ',0
root_string db '\',0
nomem_msg db 'No memory',0
filesys_string db '(filesystem)',0
directory_string db 'is a directory',0
notdir_string db 'not a directory',0
 
; entry point for NT/2k/XP booting
; ntldr loads our code to 0D00:0000 and jumps to 0D00:0256
repeat 600h + 256h - $
db 1 ; any data can be here; 1 in ASCII is a nice face :)
end repeat
; cs=es=0D00, ds=07C0, ss=0
; esi=edi=ebp=0, esp=7C00
xor si, si
jmp boot_vista
 
real_entry:
; ax = 0
mov ds, ax
mov es, ax
; our stack is 4 Kb: memory range 2000-3000
mov ss, ax
mov sp, 3000h
mov bp, dat
sti ; just for case
; say hi to user
mov si, start_msg
call out_string
; we are booting from hard disk identified by [boot_drive]
mov dl, [bp + boot_drive - dat]
; is LBA supported?
mov [bp + use_lba - dat], 0
mov ah, 41h
mov bx, 55AAh
int 13h
jc .no_lba
cmp bx, 0AA55h
jnz .no_lba
test cl, 1
jz .no_lba
inc [bp + use_lba - dat]
jmp disk_params_ok
.no_lba:
; get drive geometry
mov ah, 8
mov dl, [bp + boot_drive - dat]
int 13h
jnc @f
mov si, disk_params_msg
call out_string
jmp $
@@:
movzx ax, dh
inc ax
mov [bp + heads - dat], ax
and cx, 3Fh
mov [bp + sectors - dat], cx
disk_params_ok:
; determine size of cache for folders
int 12h ; ax = size of available base memory in Kb
sub ax, 94000h / 1024
jc nomem
shr ax, 3
mov [bp + cachelimit - dat], ax ; size of cache - 1
; scan all partitions
new_partition_ex:
xor eax, eax ; read first sector of current disk area
mov [bp + extended_part_cur - dat], eax ; no extended partition yet
mov [bp + cur_partition_ofs - dat], 31BEh ; start from first partition
push es
mov cx, 1
mov bx, 3000h
call read
pop es
jnc new_partition
mov si, disk_error2
call out_string
jmp $
new_partition:
mov bx, [bp + cur_partition_ofs - dat]
mov al, [bx+4] ; partition type
test al, al
jz next_partition
cmp al, 5
jz @f
cmp al, 0xF
jnz not_extended
@@:
; extended partition
mov eax, [bx+8] ; partition start
add eax, [bp + extended_part_start - dat]
mov [bp + extended_part_cur - dat], eax
next_partition:
add [bp + cur_partition_ofs - dat], 10h
cmp [bp + cur_partition_ofs - dat], 31FEh
jb new_partition
mov eax, [bp + extended_part_cur - dat]
test eax, eax
jz partitions_done
cmp [bp + extended_part_start - dat], 0
jnz @f
mov [bp + extended_part_start - dat], eax
@@:
mov [bp + extended_parent - dat], eax
mov [bp + partition_start - dat], eax
jmp new_partition_ex
partitions_done:
mov si, total_kaput
call out_string
jmp $
not_extended:
mov eax, [bx+8]
add eax, [bp + extended_parent - dat]
mov [bp + partition_start - dat], eax
; try to load from current partition
; inform user
mov si, part_msg
inc [si + part_char - part_msg]
call out_string
; read bootsector
xor eax, eax
mov [bp + cur_obj - dat], filesys_string
push es
mov cx, 1
mov bx, 3200h
call read
pop es
mov si, disk_error_msg
jc find_error_si
movzx si, byte [bx+13]
mov word [bp + sect_per_clust - dat], si
test si, si
jz unknown_fs
lea ax, [si-1]
test si, ax
jnz unknown_fs
; determine file system
; Number of bytes per sector == 0x200 (this loader assumes that physical sector size is 200h)
cmp word [bx+11], 0x200
jnz unknown_fs
; is it NTFS?
cmp dword [bx+3], 'NTFS'
jnz not_ntfs
cmp byte [bx+16], bl
jz ntfs
not_ntfs:
; is it FAT? FAT12/FAT16/FAT32?
; get count of sectors to dword in cx:si
mov si, [bx+19]
xor cx, cx
test si, si
jnz @f
mov si, [bx+32]
mov cx, [bx+34]
@@:
xor eax, eax
; subtract size of system area
sub si, [bx+14] ; BPB_ResvdSecCnt
sbb cx, ax
mov ax, [bx+17] ; BPB_RootEntCnt
add ax, 0xF
rcr ax, 1
shr ax, 3
sub si, ax
sbb cx, 0
push cx
push si
mov ax, word [bx+22]
test ax, ax
jnz @f
mov eax, [bx+36]
@@:
movzx ecx, byte [bx+16]
imul ecx, eax
pop eax
sub eax, ecx
; now eax = count of sectors in the data region
xor edx, edx
div [bp + sect_per_clust - dat]
; now eax = count of clusters in the data region
mov si, fatxx_msg
cmp eax, 0xFFF5
jae test_fat32
; test magic value in FAT bootsector - FAT12/16 bootsector has it at the offset +38
cmp byte [bx+38], 0x29
jnz not_fat
cmp ax, 0xFF5
jae fat16
fat12:
mov [bp + get_next_cluster_ptr - dat], fat12_get_next_cluster
mov di, cx ; BPB_NumFATs
mov ax, '12'
push ax ; save for secondary loader
mov word [si+3], ax
call out_string
movzx ecx, word [bx+22] ; BPB_FATSz16
; FAT12: read entire FAT table (it is no more than 0x1000*3/2 = 0x1800 bytes)
.fatloop:
; if first copy is not readable, try to switch to other copies
push 0x6000
pop es
xor bx, bx
movzx eax, word [0x320E] ; BPB_RsvdSecCnt
push cx
cmp cx, 12
jb @f
mov cx, 12
@@:
call read
pop cx
jnc fat1x_common
add eax, ecx ; switch to next copy of FAT
dec di
jnz .fatloop
mov si, disk_error_msg
jmp find_error_si
fat16:
mov [bp + get_next_cluster_ptr - dat], fat16_get_next_cluster
mov ax, '16'
push ax ; save for secondary loader
mov word [si+3], ax
call out_string
; FAT16: init FAT cache - no sectors loaded
mov di, 0x3400
xor ax, ax
mov cx, 0x100/2
rep stosw
fat1x_common:
mov bx, 0x3200
movzx eax, word [bx+22] ; BPB_FATSz16
xor esi, esi ; no root cluster
jmp fat_common
test_fat32:
; FAT32 bootsector has it at the offset +66
cmp byte [bx+66], 0x29
jnz not_fat
mov [bp + get_next_cluster_ptr - dat], fat32_get_next_cluster
mov ax, '32'
push ax ; save for secondary loader
mov word [si+3], ax
call out_string
; FAT32 - init cache for FAT table: no sectors loaded
lea si, [bp + cache1head - dat]
mov [si], si ; no sectors in cache:
mov [si+2], si ; 'prev' & 'next' links point to self
mov [bp + cache1end - dat], 3400h ; first free item = 3400h
mov [bp + cache1limit - dat], 3C00h
mov eax, [bx+36] ; BPB_FATSz32
mov esi, [bx+44] ; BPB_RootClus
jmp fat_common
not_fat:
unknown_fs:
mov si, errfs_msg
call out_string
jmp next_partition
fat_common:
push ss
pop es
movzx edx, byte [bx+16] ; BPB_NumFATs
mul edx
mov [bp + root_start - dat], eax ; this is for FAT1x
; eax = total size of all FAT tables, in sectors
movzx ecx, word [bx+17] ; BPB_RootEntCnt
add ecx, 0xF
shr ecx, 4
add eax, ecx
mov cx, word [bx+14] ; BPB_RsvdSecCnt
add [bp + root_start - dat], ecx ; this is for FAT1x
add eax, ecx
; cluster 2 begins from sector eax
movzx ebx, byte [bx+13] ; BPB_SecPerClus
sub eax, ebx
sub eax, ebx
mov [bp + data_start - dat], eax
; no clusters in folders cache
mov di, foldcache_clus - 2
xor ax, ax
mov cx, 7*8/2 + 1
rep stosw
mov [bp + root_clus - dat], esi
; load secondary loader
mov [bp + load_file_ptr - dat], load_file_fat
load_secondary:
push 0x1000
pop es
xor bx, bx
mov si, kernel_name
mov cx, 0x30000 / 0x200
call [bp + load_file_ptr - dat]
; say error if needed
mov si, error_too_big
dec bx
js @f
jz find_error_si
mov si, disk_error_msg
jmp find_error_si
@@:
; fill loader information and jump to secondary loader
mov al, 'h' ; boot device: hard drive
mov ah, [bp + boot_drive - dat]
sub ah, 80h ; boot device: identifier
pop bx ; restore file system ID ('12'/'16'/'32'/'nt')
mov si, callback
jmp 1000h:0000h
 
nomem:
mov si, nomem_msg
call out_string
jmp $
 
ntfs:
push 'nt' ; save for secondary loader
mov si, ntfs_msg
call out_string
xor eax, eax
mov [bp + data_start - dat], eax
mov ecx, [bx+40h] ; frs_size
cmp cl, al
jg .1
neg cl
inc ax
shl eax, cl
jmp .2
.1:
mov eax, ecx
shl eax, 9
.2:
mov [bp + frs_size - dat], ax
; standard value for frs_size is 0x400 bytes = 1 Kb, and it cannot be set different
; (at least with standard tools)
; we allow extra size, but no more than 0x1000 bytes = 4 Kb
mov si, invalid_volume_msg
cmp eax, 0x1000
ja find_error_si
; must be multiple of sector size
test ax, 0x1FF
jnz find_error_si
shr ax, 9
xchg cx, ax
; initialize cache - no data loaded
lea si, [bp + cache1head - dat]
mov [si], si
mov [si+2], si
mov word [si+4], 3400h ; first free item = 3400h
mov word [si+6], 3400h + 8*8 ; 8 items in this cache
; read first MFT record - description of MFT itself
mov [bp + cur_obj - dat], mft_string
mov eax, [bx+30h] ; mft_cluster
mul [bp + sect_per_clust - dat]
push 0x8000
pop es
xor bx, bx
push es
call read
pop ds
call restore_usa
; scan for unnamed $DATA attribute
mov [bp + freeattr - dat], 4000h
mov ax, 80h
call load_attr
push ss
pop ds
mov si, nodata_string
jc find_error_si
; load secondary loader
mov [bp + load_file_ptr - dat], load_file_ntfs
jmp load_secondary
 
find_error_si:
push si
find_error_sp:
cmp [bp + in_callback - dat], 0
jnz error_in_callback
push ss
pop ds
push ss
pop es
mov si, error_msg
call out_string
mov si, [bp + cur_obj - dat]
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jz @f
mov ah, 0Eh
mov bx, 7
int 10h
jmp @b
@@:
mov si, colon
call out_string
pop si
call out_string
mov si, newline
call out_string
mov sp, 0x3000
jmp next_partition
error_in_callback:
; return status: file not found, except for read errors
mov bx, 2
cmp si, disk_error_msg
jnz @f
inc bx
@@:
mov ax, 0xFFFF
mov dx, ax
mov sp, 3000h - 6
ret
 
callback:
; in: ax = function number; only functions 1 and 2 are defined for now
; save caller's stack
mov dx, ss
mov cx, sp
; set our stack (required because we need ss=0)
xor si, si
mov ss, si
mov sp, 3000h
mov bp, dat
mov [bp + in_callback - dat], 1
push dx
push cx
; set ds:si -> ASCIIZ name
lea si, [di+6]
; set cx = limit in sectors; 4Kb = 8 sectors
movzx ecx, word [di+4]
shl cx, 3
; set es:bx = pointer to buffer
les bx, [di]
; call our function
stc ; unsupported function
dec ax
jz callback_readfile
dec ax
jnz callback_ret
call continue_load_file
jmp callback_ret_succ
callback_readfile:
; function 1: read file
; in: ds:di -> information structure
; dw:dw address
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
; ASCIIZ name
; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error
; out: dx:ax = file size (0xFFFFFFFF if file was not found)
call [bp + load_file_ptr - dat]
callback_ret_succ:
clc
callback_ret:
; restore caller's stack
pop cx
pop ss
mov sp, cx
; return to caller
retf
 
read_file_chunk.resident:
; auxiliary label for read_file_chunk procedure
mov di, bx
lodsw
read_file_chunk.resident.continue:
mov dx, ax
add dx, 0x1FF
shr dx, 9
cmp dx, cx
jbe @f
mov ax, cx
shl ax, 9
@@:
xchg ax, cx
rep movsb
xchg ax, cx
clc ; no disk error if no disk requests
mov word [bp + num_sectors - dat], ax
ret
 
read_file_chunk:
; in: ds:si -> file chunk
; in: es:bx -> buffer for output
; in: ecx = maximum number of sectors to read (high word must be 0)
; out: CF=1 <=> disk read error
lodsb
mov [bp + cur_chunk_resident - dat], al
test al, al
jz .resident
; normal case: load (non-resident) attribute from disk
.read_block:
lodsd
xchg eax, edx
test edx, edx
jz .ret
lodsd
; eax = start cluster, edx = number of clusters, cx = limit in sectors
imul eax, [bp + sect_per_clust - dat]
add eax, [bp + data_start - dat]
mov [bp + cur_cluster - dat], eax
imul edx, [bp + sect_per_clust - dat]
mov [bp + num_sectors - dat], edx
and [bp + cur_delta - dat], 0
.nonresident.continue:
cmp edx, ecx
jb @f
mov edx, ecx
@@:
test dx, dx
jz .read_block
add [bp + cur_delta - dat], edx
sub [bp + num_sectors - dat], edx
sub ecx, edx
push cx
mov cx, dx
call read
pop cx
jc .ret
test cx, cx
jnz .read_block
.ret:
ret
 
cache_lookup:
; in: eax = value to look, si = pointer to cache structure
; out: di->cache entry; CF=1 <=> the value was not found
push ds bx
push ss
pop ds
mov di, [si+2]
.look:
cmp di, si
jz .not_in_cache
cmp eax, [di+4]
jz .in_cache
mov di, [di+2]
jmp .look
.not_in_cache:
; cache miss
; cache is full?
mov di, [si+4]
cmp di, [si+6]
jnz .cache_not_full
; yes, delete the oldest entry
mov di, [si]
mov bx, [di]
mov [si], bx
push word [di+2]
pop word [bx+2]
jmp .cache_append
.cache_not_full:
; no, allocate new item
add word [si+4], 8
.cache_append:
mov [di+4], eax
stc
jmp @f
.in_cache:
; delete this sector from the list
push si
mov si, [di]
mov bx, [di+2]
mov [si+2], bx
mov [bx], si
pop si
@@:
; add new sector to the end of list
mov bx, di
xchg bx, [si+2]
push word [bx]
pop word [di]
mov [bx], di
mov [di+2], bx
pop bx ds
ret
 
include 'fat.inc'
include 'ntfs.inc'
 
total_kaput db 13,10,'Fatal error: cannot load the secondary loader',0
error_too_big db 'file is too big',0
nodata_string db '$DATA '
error_not_found db 'not found',0
noindex_string db '$INDEX_ROOT not found',0
badname_msg db 'bad name for FAT',0
invalid_volume_msg db 'invalid volume',0
mft_string db '$MFT',0
fragmented_string db 'too fragmented file',0
invalid_read_request_string db 'cannot read attribute',0
 
kernel_name db 'kord/loader',0
 
align 4
dat:
 
extended_part_start dd 0 ; start sector for main extended partition
extended_part_cur dd ? ; start sector for current extended child
extended_parent dd 0 ; start sector for current extended parent
partition_start dd 0 ; start sector for current logical disk
cur_partition_ofs dw ? ; offset in MBR data for current partition
sect_per_clust dd 0
; change this variable if you want to boot from other physical drive
boot_drive db 80h
in_callback db 0
 
; uninitialized data
use_lba db ?
cur_chunk_resident db ?
align 2
heads dw ?
sectors dw ?
cache1head rw 2
cache1end dw ?
cache1limit dw ?
data_start dd ?
cachelimit dw ?
load_file_ptr dw ?
cur_obj dw ?
missing_slash dw ?
root_clus dd ?
root_start dd ?
get_next_cluster_ptr dw ?
frs_size dw ?
freeattr dw ?
index_root dw ?
index_alloc dw ?
cur_index_seg dw ?
cur_index_cache dw ?
filesize dd ?
filesize_sectors dd ?
cur_cluster dd ?
cur_delta dd ?
num_sectors dd ?
sectors_read dd ?
cur_chunk_ptr dw ?
 
rootcache_size dw ? ; must be immediately before foldcache_clus
if $-dat >= 0x80
warning: unoptimal data displacement!
end if
foldcache_clus rd 7
foldcache_mark rw 7
foldcache_size rw 7
fat_filename rb 11
 
if $ > 2000h
error: file is too big
end if
 
; for NT/2k/XP, file must be 16 sectors = 0x2000 bytes long
repeat 0x2600 - $
db 2 ; any data can be here; 2 is another nice face in ASCII :)
end repeat
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/kordldr.win.txt
0,0 → 1,391
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
Íåò ïîâåñòè ïå÷àëüíåå íà ñâåòå,
×åì ïîâåñòü î çàêëèíèâøåì Reset'å...
 
Çàãðóç÷èê äëÿ FAT- è NTFS-òîìîâ äëÿ ñëó÷àåâ, êîãäà îñíîâíîé áóòñåêòîð çàãðóæàåò
Windows, äëÿ íîñèòåëåé ñ ðàçìåðîì ñåêòîðà 512 áàéò.
 
=====================================================================
 
Òðåáîâàíèÿ äëÿ ðàáîòû:
1) Âñå èñïîëüçóåìûå ôàéëû äîëæíû áûòü ÷èòàáåëüíû.
2) Ìèíèìàëüíûé ïðîöåññîð - 80386.
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 592K ñâîáîäíîé áàçîâîé ïàìÿòè.
4) Ïóòè ê èñïîëüçóåìûì ôàéëàì íå äîëæíû ñîäåðæàòü ñèìâîëè÷åñêèõ ññûëîê NTFS
(æ¸ñòêèå ññûëêè äîïóñêàþòñÿ).
5) Èñïîëüçóåìûå ôàéëû íå äîëæíû áûòü ñæàòûìè èëè ðàçðåæåííûìè ôàéëàìè
(àêòóàëüíî äëÿ NTFS, äëÿ FAT âûïîëíåíî àâòîìàòè÷åñêè).
 
=====================================================================
 
Äîêóìåíòàöèÿ â òåìó (ññûëêè ïðîâåðÿëèñü íà âàëèäíîñòü 08.08.2008):
îôèöèàëüíàÿ ñïåöèôèêàöèÿ FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
â ôîðìàòå PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf
ðóññêèé ïåðåâîä: http://wasm.ru/docs/11/fatgen103-rus.zip
ñïåöèôèêàöèÿ NTFS: file://C:/windows/system32/drivers/ntfs.sys
è file://C:/ntldr ëèáî file://C:/bootmgr
íåîôèöèàëüíîå îïèñàíèå NTFS: http://sourceforge.net/project/showfiles.php?group_id=13956&package_id=16543
îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
îôèöèàëüíîå îïèñàíèå bcdedit äëÿ Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcdedit_reff.mspx
îôèöèàëüíîå îïèñàíèå ðàáîòû ñ áàçîé äàííûõ çàãðóç÷èêà Vista: http://www.microsoft.com/whdc/system/platform/firmware/bcd.mspx
ôîðìàò òàáëèöû ðàçäåëîâ æ¸ñòêîãî äèñêà: http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/prork/prcb_dis_qxql.mspx
 
=====================================================================
 
Ñõåìà èñïîëüçóåìîé ïàìÿòè:
600-2000 êîä çàãðóç÷èêà (è äàííûå)
2000-3000 ñòåê
3000-3200 ñåêòîð MBR
3200-3400 áóòñåêòîð ëîãè÷åñêîãî äèñêà
3400-3C00 èíôîðìàöèÿ î êýøå äëÿ òàáëèö FAT16/FAT32:
äëÿ FAT16 - ìàññèâ íà 0x100 áàéò, êàæäûé áàéò ðàâåí
0 èëè 1 â çàâèñèìîñòè îò òîãî, çàãðóæåí ëè
ñîîòâåòñòâóþùèé ñåêòîð òàáëèöû FAT16;
äëÿ FAT32 - 100h âõîäîâ ïî 8 áàéò: 4 áàéòà
(äâå ññûëêè - âïåð¸ä è íàçàä) äëÿ îðãàíèçàöèè L2-ñïèñêà
âñåõ ïðî÷èòàííûõ ñåêòîðîâ â ïîðÿäêå âîçðàñòàíèÿ
ïîñëåäíåãî âðåìåíè èñïîëüçîâàíèÿ + 4 áàéòà äëÿ íîìåðà
ñåêòîðà; ïðè ïåðåïîëíåíèè êýøà âûêèäûâàåòñÿ ýëåìåíò èç
ãîëîâû ñïèñêà, òî åñòü òîò, ê êîòîðîìó äîëüøå âñåõ
íå áûëî îáðàùåíèé
3400-3440 èíôîðìàöèÿ î êýøå äëÿ ôàéëîâûõ çàïèñåé NTFS â
òàêîì æå ôîðìàòå, êàê è êýø äëÿ FAT32, íî íà 8 âõîäîâ
3480-34C0 çàãîëîâêè äëÿ êýøåé çàïèñåé èíäåêñà NTFS
3500-3D00 èíôîðìàöèÿ î êýøàõ çàïèñåé èíäåêñà NTFS: ñ êàæäîé
ôàéëîâîé çàïèñüþ ñâÿçàí ñâîé êýø äëÿ
ñîîòâåòñòâóþùåãî èíäåêñà
4000-8000 ìåñòî äëÿ èíôîðìàöèè îá àòðèáóòàõ äëÿ NTFS
60000-80000 òàáëèöà FAT12 / ìåñòî ïîä òàáëèöó FAT16 /
êýø äëÿ òàáëèöû FAT32 / êýø äëÿ ñòðóêòóð NTFS
80000-90000 òåêóùèé ðàññìàòðèâàåìûé êëàñòåð
90000-92000 FAT: êýø äëÿ êîðíåâîé ïàïêè
92000-... FAT: êýø äëÿ íåêîðíåâûõ ïàïîê (êàæäîé ïàïêå îòâîäèòñÿ
2000h áàéò = 100h âõîäîâ, îäíîâðåìåííî â êýøå
ìîæåò íàõîäèòüñÿ íå áîëåå 7 ïàïîê;
òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé
ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî
ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area)
 
=====================================================================
 
Îñíîâíîé ïðîöåññ çàãðóçêè.
0a. Çàãðóçêà èç-ïîä DOS è Win9x: óñòàíîâêà kordldr.win îñóùåñòâëÿåòñÿ
ðàçìåùåíèåì êîìàíäû install=c:\kordldr.win â ïåðâîé ñòðîêå config.sys;
ïðè ýòîì îñíîâíîé çàãðóç÷èê ñèñòåìû çàãðóæàåò kordldr.win êàê îáû÷íûé
com-ôàéë, â êàêîé-òî ñåãìåíò ïî ñìåùåíèþ 100h è ïåðåäà¸ò óïðàâëåíèå
â íà÷àëî êîäà (xxxx:0100).
0á. Çàãðóçêà èç-ïîä WinNT/2000/XP: óñòàíîâêà kordldr.win îñóùåñòâëÿåòñÿ
äîáàâëåíèåì ñòðîêè íàïîäîáèå c:\kordldr.win="KordOS" â ñåêöèþ
[operating systems] ôàéëà boot.ini; åñëè çàãðóæàåìûé ôàéë èìååò ðàçìåð
íå ìåíåå 8 Êá (0x2000 áàéò) è ïî ñìåùåíèþ 3 ñîäåðæèò ñèãíàòóðó 'NTFS'
(â ñëó÷àå kordldr.win òàê è åñòü), òî îñíîâíîé çàãðóç÷èê êàæäîé èç
ýòèõ ñèñòåì çàãðóæàåò kordldr.win ïî àäðåñó 0D00:0000 è ïåðåäà¸ò
óïðàâëåíèå íà àäðåñ 0D00:0256.
0â. Çàãðóçêà èç-ïîä Vista: óñòàíîâêà kordldr.win îñóùåñòâëÿåòñÿ ìàíèïóëÿöèÿìè
ñ áàçîé äàííûõ îñíîâíîãî çàãðóç÷èêà ÷åðåç bcdedit è ïîäðîáíî îïèñàíà â
èíñòðóêöèè ê kordldr.win; îñíîâíîé çàãðóç÷èê çàãðóæàåò öåëèêîì
kordldr.win ïî àäðåñó 0000:7C00 è ïåðåäà¸ò óïðàâëåíèå â íà÷àëî êîäà.
1. Ïðè çàãðóçêå èç-ïîä DOS/9x îñíîâíîé çàãðóç÷èê íå îæèäàåò, ÷òî çàãðóæåííàÿ
èì ïðîãðàììà îêàæåòñÿ â ñâîþ î÷åðåäü çàãðóç÷èêîì, è â ýòîì ñëó÷àå
kordldr.win îêàçûâàåòñÿ â óñëîâèÿõ, êîãäà îñíîâíîé çàãðóç÷èê óæå
óñòàíîâèë êàêîå-òî îêðóæåíèå, â ÷àñòíîñòè, ïåðåõâàòèë íåêîòîðûå
ïðåðûâàíèÿ. Ïîýòîìó ïåðåä îñòàëüíûìè äåéñòâèÿìè çàãðóç÷èê äîëæåí
âîññòàíîâèòü ñèñòåìó â íà÷àëüíîå ñîñòîÿíèå. (Ïðè çàãðóçêå ïîä
NT-ëèíåéêîé òàêîé ïðîáëåìû íå âîçíèêàåò, ïîñêîëüêó òàì îñíîâíîé
çàãðóç÷èê íè÷åãî â ñèñòåìå íå òðîãàåò.) Ïîýòîìó ïåðåä ñîáñòâåííî
èíèöèàëèçàöèåé KordOS ïðè ðàáîòå èç-ïîä DOS/9x ïðîèçâîäÿòñÿ
äîïîëíèòåëüíûå äåéñòâèÿ. Ïåðâûì äåëîì kordldr ïðîâåðÿåò, êàêîé èç
ñëó÷àåâ 0à è 0â èìååò ìåñòî (ñëó÷àé 0á îòëè÷àåòñÿ òåì, ÷òî ïåðåäà¸ò
óïðàâëåíèå íå íà íà÷àëî êîäà): îïðåäåëÿåò çíà÷åíèå ip (êîìàíäà call
ïîìåùàåò â ñòåê àäðåñ ñëåäóþùåé ïîñëå call èíñòðóêöèè, êîìàíäà pop si
âûòàëêèâàåò åãî â ðåãèñòð si), è åñëè îíî ðàâíî 100h, òî kordldr
çàãðóæåí êàê com-ôàéë èç-ïîä DOS/9x. Òîãäà îí ñïðàøèâàåò ïîäòâåðæäåíèÿ
ó ïîëüçîâàòåëÿ (ïîñêîëüêó â ýòîé ñõåìå kordldr çàãðóæàåòñÿ âñåãäà,
îí äîëæåí îñòàâèòü âîçìîæíîñòü ïðîäîëæèòü çàãðóçêó DOS/9x). Åñëè
ïîëüçîâàòåëü õî÷åò ïðîäîëæèòü îáû÷íóþ çàãðóçêó, kordldr çàâåðøàåòñÿ.
Èíà÷å èñïîëüçóåòñÿ òîò ôàêò, ÷òî ïðè âûäà÷å ïðåðûâàíèÿ ïåðåçàãðóçêè
int 19h ñèñòåìà ïðåäâàðèòåëüíî ñíèìàåò âñå ñâîè ïåðåõâàòû BIOSîâñêèõ
ïðåðûâàíèé, à ïîòîì â ñâîþ î÷åðåäü âûäà¸ò int 19h óæå BIOSó. Òàê ÷òî
kordldr óñòàíàâëèâàåò ñâîé îáðàáîò÷èê òðàññèðîâî÷íîãî ïðåðûâàíèÿ,
óñòàíàâëèâàåò ôëàã òðàññèðîâêè è ïåðåäà¸ò óïðàâëåíèå DOSîâñêîìó
îáðàáîò÷èêó. Îáðàáîò÷èê òðàññèðîâî÷íîãî ïðåðûâàíèÿ íè÷åãî íå äåëàåò
äî òåõ ïîð, ïîêà ñëåäóþùåé èíñòðóêöèåé íå îêàçûâàåòñÿ int 19h, à
â ýòîò ìîìåíò îòáèðàåò óïðàâëåíèå è ïðîäîëæàåò çàãðóçêó KordOS.
Ïðè ýòîì BIOSîâñêèå îáðàáîò÷èêè âîññòàíîâëåíû çà èñêëþ÷åíèåì,
áûòü ìîæåò, ïðåðûâàíèÿ òàéìåðà int 8, êîòîðîå, âîçìîæíî, âîññòàíîâëåíî
äî êîìàíäû jmp far íà îðèãèíàëüíûé îáðàáîò÷èê.  ïîñëåäíåì ñëó÷àå åãî
íóæíî âîññòàíîâèòü ÿâíî.
2. Çàãðóç÷èê ïåðåìåùàåò ñâîé êîä íà àäðåñ 0000:0600.
3. (ìåòêà real_entry) Çàãðóç÷èê óñòàíàâëèâàåò ñåãìåíòíûå ðåãèñòðû ds = es = 0,
íàñòðàèâàåò ñòåê ss:sp = 0000:3000 è óñòàíàâëèâàåò bp òàê, ÷òîáû
âñå äàííûå ìîæíî áûëî àäðåñîâàòü ÷åðåç [bp+N] ñ îäíîáàéòîâûì N
(â äàëüíåéøåì îíè òàê è áóäóò àäðåñîâàòüñÿ äëÿ îñâîáîæäåíèÿ ds è
ýêîíîìèè íà ðàçìåðå êîäà). Ðàçðåøàåò ïðåðûâàíèÿ íà ñëó÷àé, åñëè
îíè áûëè çàïðåùåíû. Âûäà¸ò ñîîáùåíèå î íà÷àëå çàãðóçêè, íà÷èíàþùååñÿ
ñ âåñ¸ëîé ðîæèöû (ñèìâîë ñ ASCII-êîäîì 2).
4. Îïðåäåëÿåò õàðàêòåðèñòèêè æ¸ñòêîãî äèñêà, óêàçàííîãî â êà÷åñòâå
çàãðóçî÷íîãî: ïðîâåðÿåò ïîääåðæêó LBA (ôóíêöèÿ 41h ïðåðûâàíèÿ 13h),
åñëè LBA íå ïîääåðæèâàåòñÿ, òî îïðåäåëÿåò ãåîìåòðèþ - ÷èñëî äîðîæåê
è ÷èñëî ñåêòîðîâ íà äîðîæêå (ôóíêöèÿ 8 ïðåðûâàíèÿ 13h), ýòè ïàðàìåòðû
íóæíû ôóíêöèè ÷òåíèÿ ñ äèñêà.
5. (ìåòêà new_partition_ex) Óñòðàèâàåò öèêë ïî ðàçäåëàì æ¸ñòêîãî äèñêà.
Öåëü öèêëà - äëÿ êàæäîãî ëîãè÷åñêîãî äèñêà ïîïûòàòüñÿ çàãðóçèòüñÿ ñ
íåãî (äåéñòâèÿ ïî çàãðóçêå ñ êîíêðåòíîãî ëîãè÷åñêîãî äèñêà íà÷èíàþòñÿ
ñ ìåòêè not_extended), ïðè îøèáêå çàãðóçêè óïðàâëåíèå ïåðåäà¸òñÿ
íàçàä ýòîìó öèêëó (ìåòêà next_partition), è ïîèñê ïîäõîäÿùåãî ðàçäåëà
ïðîäîëæàåòñÿ. Íà âûõîäå çàïîëíÿåòñÿ îäíà ïåðåìåííàÿ partition_start,
èìåþùàÿ ñìûñë íà÷àëà òåêóùåãî ðàññìàòðèâàåìîãî ëîãè÷åñêîãî äèñêà,
íî ïî õîäó äåëà èç-çà ïðèêîëîâ òàáëèö ðàçäåëîâ èñïîëüçóþòñÿ åù¸ ÷åòûðå
ïåðåìåííûõ. cur_partition_ofs - ôàêòè÷åñêè ñ÷¸ò÷èê öèêëà, ôîðìàëüíî
óêàçàòåëü íà òåêóùèé âõîä â òåêóùåé çàãðóçî÷íîé çàïèñè. Ñàìà
çàãðóçî÷íàÿ çàïèñü ñ÷èòûâàåòñÿ â ïàìÿòü íà÷èíàÿ ñ àäðåñà 3000h.
Òðè îñòàâøèõñÿ íóæíû äëÿ ïðàâèëüíîé ðàáîòû ñ ðàñøèðåííûìè ðàçäåëàìè.
 êàæäîé çàãðóçî÷íîé çàïèñè ïîìåùàåòñÿ íå áîëåå 4 çàïèñåé î ðàçäåëàõ.
Ïîýòîìó ãëàâíîé çàãðóçî÷íîé çàïèñè, ðàçìåùàþùåéñÿ â ïåðâîì ôèçè÷åñêîì
ñåêòîðå äèñêà, ìîæåò íå õâàòèòü, è îáû÷íî ñîçäà¸òñÿ òàê íàçûâàåìûé
ðàñøèðåííûé ðàçäåë ñ ðàñøèðåííûìè çàãðóçî÷íûìè çàïèñÿìè, ôîðìàò
êîòîðûõ ïî÷òè èäåíòè÷åí ãëàâíîé. Ðàñøèðåííûé ðàçäåë ìîæåò áûòü òîëüêî
îäèí, íî â í¸ì ìîæåò áûòü ìíîãî ëîãè÷åñêèõ äèñêîâ è ðàñøèðåííûõ
çàãðóçî÷íûõ çàïèñåé. Ðàñøèðåííûå çàãðóçî÷íûå çàïèñè îðãàíèçîâàíû
â îäíîñâÿçíûé ñïèñîê, â êàæäîé òàêîé çàïèñè ïåðâûé âõîä óêàçûâàåò
íà ñîîòâåòñòâóþùèé ëîãè÷åñêèé äèñê, à âòîðîé - íà ñëåäóþùóþ ðàñøèðåííóþ
çàãðóçî÷íóþ çàïèñü.
Ïðè ýòîì â ãëàâíîé çàãðóçî÷íîé çàïèñè âñå àäðåñà ðàçäåëîâ ÿâëÿþòñÿ
àáñîëþòíûìè íîìåðàìè ñåêòîðîâ. Â ðàñøèðåííûõ æå çàïèñÿõ àäðåñà ðàçäåëîâ
îòíîñèòåëüíû, ïðè÷¸ì ñ ðàçíûìè áàçàìè: àäðåñ ëîãè÷åñêîãî äèñêà
óêàçûâàåòñÿ îòíîñèòåëüíî ðàñøèðåííîé çàïèñè, à àäðåñ ñëåäóþùåé
ðàñøèðåííîé çàïèñè óêàçûâàåòñÿ îòíîñèòåëüíî íà÷àëà ðàñøèðåííîãî
ðàçäåëà. Òàêîé ðàçíîáîé âûãëÿäèò íåñêîëüêî ñòðàííî, íî èìååò ìåñòî
áûòü. Òðè îñòàâøèõñÿ ïåðåìåííûõ ñîäåðæàò: extended_part_start -
íà÷àëî ðàñøèðåííîãî ðàçäåëà; extended_parent - òåêóùàÿ ðàññìàòðèâàåìàÿ
ðàñøèðåííàÿ çàãðóçî÷íàÿ çàïèñü; extended_part_cur - ñëåäóþùàÿ
çàãðóçî÷íàÿ çàïèñü äëÿ ðàññìîòðåíèÿ.
Öèêë âûãëÿäèò òàê: ïðîñìàòðèâàþòñÿ âñå ðàçäåëû, óêàçàííûå â òåêóùåé
(ãëàâíîé èëè ðàñøèðåííîé) çàãðóçî÷íîé çàïèñè; äëÿ íîðìàëüíûõ ðàçäåëîâ
(îíè æå ëîãè÷åñêèå äèñêè) ïðîèñõîäèò ïåðåõîä íà not_extended, ãäå
óñòàíàâëèâàåòñÿ partition_start è íà÷èíàåòñÿ ñîáñòâåííî çàãðóçêà
(ïîñëåäóþùèå øàãè); ïðè âñòðå÷å ñ ðàçäåëîì, òèï êîòîðîãî óêàçûâàåò
íà ðàñøèðåííîñòü (5 èëè 0xF), êîä çàïîìèíàåò íà÷àëî ýòîãî ðàçäåëà
(â ãëàâíîé çàãðóçî÷íîé çàïèñè òàêîé òèï îçíà÷àåò ðàñøèðåííûé ðàçäåë,
â ðàñøèðåííîé - òîëüêî óêàçàòåëü íà ñëåäóþùóþ ðàñøèðåííóþ çàïèñü,
â îáîèõ ñëó÷àÿõ îí ìîæåò âñòðåòèòüñÿ òîëüêî îäèí ðàç â äàííîé çàïèñè);
êîãäà êîä äîõîäèò äî êîíöà ñïèñêà, âñå íîðìàëüíûå ðàçäåëû, îïèñûâàåìûå
â ýòîé çàïèñè, óæå ïðîñìîòðåíû, òàê ÷òî êîä ñ ÷èñòîé ñîâåñòüþ ïåðåõîäèò
ê ñëåäóþùåé ðàñøèðåííîé çàïèñè. Åñëè îí å¸ íå âñòðåòèë, çíà÷èò, óæå
âñå ëîãè÷åñêèå ðàçäåëû áûëè ïîäâåðãíóòû ïîïûòêàì çàãðóçèòüñÿ, è âñå
áåçðåçóëüòàòíî, òàê ÷òî âûâîäèòñÿ ðóãàòåëüñòâî è ðàáîòà îñòàíàâëèâàåòñÿ
(jmp $).
Ìîæåò âîçíèêíóòü âîïðîñ, çà÷åì íóæíà òàêàÿ ñëîæíàÿ ñõåìà è ïî÷åìó
íåëüçÿ óçíàòü íóæíûé ëîãè÷åñêèé äèñê çàðàíåå èëè õîòÿ áû îãðàíè÷èòüñÿ
ïåðâûì ïîïàâøèìñÿ ëîãè÷åñêèì äèñêîì, íå êðóòÿ öèêë. Òàê âîò, âàðèàíò
ñ ïðåäâàðèòåëüíûì îïðåäåëåíèåì íóæíîãî ðàçäåëà â äàííîì ñëó÷àå íå
èñïîëüçóåòñÿ, ïîñêîëüêó ïîâë¸ê áû çà ñîáîé íåòðèâèàëüíûå ëèøíèå
äåéñòâèÿ ïî óñòàíîâêå (â òåêóùåì âèäå óñòàíîâêó ìîæíî ïðîâåñòè âðó÷íóþ,
è îíà ñâîäèòñÿ ê óêàçàíèþ ñèñòåìíîìó çàãðóç÷èêó íà ñóùåñòâîâàíèå
kordldr); êñòàòè, â àëüòåðíàòèâíîé âåðñèè çàãðóçêè ïîñëå
Windows-çàãðóç÷èêà, êîãäà óñòàíîâêà îñóùåñòâëÿåòñÿ íå âðó÷íóþ, à
ñïåöèàëüíîé ïðîãðàììîé ïîä Windows, èñïîëüçóåòñÿ ìîäèôèöèðîâàííàÿ
âåðñèÿ, â êîòîðîé êàê ðàç íà÷àëüíûé ôèçè÷åñêèé ñåêòîð íóæíîãî ðàçäåëà
ïðîïèñûâàåòñÿ óñòàíîâùèêîì. Ñàì kordldr íå ìîæåò óñòàíîâèòü, ñ êàêîãî
ðàçäåëà åãî çàãðóçèë Windows-çàãðóç÷èê (è âîîáùå ïîä NT/2000/XP îáÿçàí
áûòü ôàéëîì íà äèñêå C:\). Âàðèàíò ñ ïåðâûì ïîïàâøèìñÿ ëîãè÷åñêèì
äèñêîì áûë ðåàëèçîâàí â ïåðâîé âåðñèè çàãðóç÷èêà, íî ïî õîäó äåëà
îáíàðóæèëîñü, ÷òî òàêè íóæíî êðóòèòü öèêë: âî-âòîðûõ, ìîæåò áûòü
ïðèÿòíûì, ÷òî ñàìà ñèñòåìà ìîæåò ñòîÿòü âîâñå íå íà ñèñòåìíîì C:\, à è
íà äðóãèõ äèñêàõ; âî-ïåðâûõ, äèñê C: ìîæåò è íå áûòü ïåðâûì ëîãè÷åñêèì
ðàçäåëîì - Vista ëþáèò ñîçäàâàòü ñêðûòûé ïåðâè÷íûé ðàçäåë ïåðåä
ñèñòåìíûì, è òîãäà äèñê C: ñòàíîâèòñÿ âòîðûì ëîãè÷åñêèì.
6. Èçâåùàåò ïîëüçîâàòåëÿ î òîì, ÷òî ïðîèñõîäèò ïîïûòêà çàãðóçêè ñ î÷åðåäíîãî
ëîãè÷åñêîãî äèñêà.
7. ×èòàåò ïåðâûé ñåêòîð ëîãè÷åñêîãî äèñêà è îïðåäåëÿåò ôàéëîâóþ ñèñòåìó.
È â FAT, è â NTFS ïîëå ñî ñìåùåíèåì +11 ñîäåðæèò ÷èñëî áàéò â ñåêòîðå
è äîëæíî ñîâïàäàòü ñ õàðàêòåðèñòèêîé ôèçè÷åñêîãî íîñèòåëÿ, òî åñòü
200h áàéò. È â FAT, è â NTFS ïîëå ñî ñìåùåíèåì +13 ñîäåðæèò ÷èñëî
ñåêòîðîâ â êëàñòåðå è äîëæíî áûòü ñòåïåíüþ äâîéêè.
Êðèòåðèé NTFS: ïîëå ñî ñìåùåíèåì +3 ñîäåðæèò ñòðîêó NTFS è ïîëå ñî
ñìåùåíèåì +16 íóëåâîå (â FAT îíî ñîäåðæèò ÷èñëî òàáëèö FAT è îáÿçàíî
áûòü íåíóëåâûì).
Êðèòåðèé FAT: çàãðóç÷èê âû÷èñëÿåò ÷èñëî êëàñòåðîâ, îïðåäåëÿåò
ïðåäïîëîæèòåëüíûé òèï (FAT12/FAT16/FAT32) è ïðîâåðÿåò áàéò ïî ñìåùåíèþ
+38 äëÿ FAT12/16, +66 äëÿ FAT32 (îí äîëæåí áûòü ðàâåí 0x29).
Ïîñëå îïðåäåëåíèÿ òèïà ôàéëîâîé ñèñòåìû èçâåùàåò ïîëüçîâàòåëÿ îá
îïðåäåë¸ííîì òèïå. Åñëè ôàéëîâàÿ ñèñòåìà íå ðàñïîçíàíà, âûäà¸ò
ñîîòâåòñòâóþùåå ñîîáùåíèå è ïåðåõîäèò ê ñëåäóþùåìó ëîãè÷åñêîìó äèñêó.
8a. Äëÿ FAT12-òîìîâ: çàñîâûâàåò â ñòåê èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû -
êîíñòàíòó '12'; óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ ïîëó÷åíèÿ ñëåäóþùåãî
â öåïî÷êå FAT êëàñòåðà íà FAT12-îáðàáîò÷èê; ñ÷èòûâàåò â ïàìÿòü âñþ
òàáëèöó FAT12 (îíà íå ïðåâîñõîäèò 0x1800 áàéò = 6 Êá), ïðè îøèáêå
÷òåíèÿ ïûòàåòñÿ èñïîëüçîâàòü äðóãèå êîïèè FAT.
8á. Äëÿ FAT16-òîìîâ: çàñîâûâàåò â ñòåê èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû -
êîíñòàíòó '16'; óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ ïîëó÷åíèÿ ñëåäóþùåãî
â öåïî÷êå FAT êëàñòåðà íà FAT16-îáðàáîò÷èê; èíèöèàëèçèðóåò èíôîðìàöèþ
î êýøå ñåêòîðîâ FAT (ìàññèâ áàéò ñ âîçìîæíûìè çíà÷åíèÿìè 0 è 1,
îçíà÷àþùèìè, áûë ëè óæå çàãðóæåí ñîîòâåòñòâóþùèé ñåêòîð - âñåãî â
òàáëèöå FAT16 íå áîëåå 0x100 ñåêòîðîâ) - íè îäèí ñåêòîð åù¸ íå
çàãðóæåí, âñå áàéòû íóëåâûå.
8â. Äëÿ FAT32-òîìîâ: çàñîâûâàåò â ñòåê èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû -
êîíñòàíòó '32'; óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ ïîëó÷åíèÿ ñëåäóþùåãî
â öåïî÷êå FAT êëàñòåðà íà FAT16-îáðàáîò÷èê; èíèöèàëèçèðóåò èíôîðìàöèþ
î êýøå ñåêòîðîâ FAT (ôîðìàò èíôîðìàöèè îïèñàí âûøå, â ðàñïðåäåëåíèè
èñïîëüçóåìîé çàãðóç÷èêîì ïàìÿòè) - íè îäèí ñåêòîð åù¸ íå çàãðóæåí.
8ã. Îáùåå äëÿ FAT-òîìîâ: îïðåäåëÿåò çíà÷åíèÿ ñëóæåáíûõ ïåðåìåííûõ
root_start (ïåðâûé ñåêòîð êîðíåâîãî êàòàëîãà â FAT12/16, èãíîðèðóåòñÿ
ïðè îáðàáîòêå FAT32-òîìîâ), data_start (íà÷àëî äàííûõ ñ ïîïðàâêîé,
ââîäèìîé äëÿ òîãî, ÷òîáû êëàñòåð N íà÷èíàëñÿ ñ ñåêòîðà
N*sectors_per_cluster+data_start), root_clus (ïåðâûé êëàñòåð êîðíåâîãî
êàòàëîãà â FAT32, 0 â FAT12/16); óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ
çàãðóçêè ôàéëà íà FAT-îáðàáîò÷èê.
8ä. Äëÿ NTFS-òîìîâ: çàñîâûâàåò â ñòåê èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû -
êîíñòàíòó 'nt'; îïðåäåëÿåò çíà÷åíèå ñëóæåáíîé ïåðåìåííîé frs_size
(ðàçìåð â áàéòàõ ôàéëîâîé çàïèñè, File Record Segment), äëÿ ïîëíîé
êîððåêòíîñòè ïðîâåðÿåò, ÷òî ýòî çíà÷åíèå (ðàâíîå 0x400 áàéò íà âñåõ
ðåàëüíûõ NTFS-òîìàõ - åäèíñòâåííûé ñïîñîá èçìåíèòü åãî çàêëþ÷àåòñÿ
â ïåðåñîçäàíèè âñåõ ñèñòåìíûõ ñòðóêòóð âðó÷íóþ) íå ïðåâîñõîäèò 0x1000
è êðàòíî ðàçìåðó ñåêòîðà 0x200 áàéò; èíèöèàëèçèðóåò êýø ôàéëîâûõ
çàïèñåé - íè÷åãî åù¸ íå çàãðóæåíî; ñ÷èòûâàåò ïåðâûé êëàñòåð $MFT
è çàãðóæàåò èíôîðìàöèþ î ðàñïîëîæåíèè íà äèñêå âñåé òàáëèöû $MFT
(àòðèáóò 0x80, $Data); óñòàíàâëèâàåò óêàçàòåëü íà ôóíêöèþ çàãðóçêè
ôàéëà íà NTFS-îáðàáîò÷èê.
9. (ìåòêà load_secondary) Âûçûâàåò ôóíêöèþ çàãðóçêè ôàéëà äëÿ ôàéëà âòîðè÷íîãî
çàãðóç÷èêà. Ïðè îáíàðóæåíèè îøèáêè ïåðåõîäèò íà îáðàáîò÷èê îøèáîê ñ
ñîîòâåòñòâóþùèì ñîîáùåíèåì.
10. Óñòàíàâëèâàåò ðåãèñòðû äëÿ âòîðè÷íîãî çàãðóç÷èêà: al='h' (æ¸ñòêèé äèñê),
ah=íîìåð äèñêà (äëÿ ãîòîâîãî áèíàðíèêà - 0 (BIOS-èäåíòèôèêàòîð 80h),
ìîæåò áûòü èçìåí¸í ïóò¸ì ìîäèôèêàöèè êîíñòàíòû â èñõîäíèêå èëè
ñïåöèàëüíûì óñòàíîâùèêîì), bx=èäåíòèôèêàòîð ôàéëîâîé ñèñòåìû (áåð¸òñÿ
èç ñòåêà, êóäà ðàíåå áûë çàñóíóò íà øàãå 8), ds:si=óêàçàòåëü íà
callback-ôóíêöèþ.
11. Ïåðåäà¸ò óïðàâëåíèå âòîðè÷íîìó çàãðóç÷èêó äàëüíèì ïåðåõîäîì íà 1000:0000.
 
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà:
ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà.
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê.
×òåíèå ôàéëà:
1. Ñîõðàíÿåò ñòåê âûçûâàþùåãî êîäà è óñòàíàâëèâàåò ñâîé ñòåê:
ss:sp = 0:3000, bp=dat: ïàðà ss:bp ïðè ðàáîòå ñ îñòàëüíûì
êîäîì äîëæíà óêàçûâàòü íà 0:dat.
2. Ðàçáèðàåò ïåðåäàííûå ïàðàìåòðû è âûçûâàåò ïðîöåäóðó çàãðóçêè ôàéëà.
3. Âîññòàíàâëèâàåò ñòåê âûçûâàþùåãî êîäà è âîçâðàùàåò óïðàâëåíèå.
 
Âñïîìîãàòåëüíûå ïðîöåäóðû.
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read):
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
ss:bp = 0:dat
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå
eax = ñòàðòîâûé ñåêòîð (îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà)
cx = ÷èñëî ñåêòîðîâ (äîëæíî áûòü áîëüøå íóëÿ)
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå,
ôëàã CF óñòàíîâëåí, åñëè âîçíèêëà îøèáêà ÷òåíèÿ
1. Ïåðåâîäèò ñòàðòîâûé ñåêòîð (îòñ÷èòûâàåìûé îò íà÷àëà òîìà) â ñåêòîð íà
óñòðîéñòâå, ïðèáàâëÿÿ íîìåð ïåðâîãî ñåêòîðà ëîãè÷åñêîãî äèñêà,
íàéäåííûé ïðè ïåðåáîðå äèñêîâ.
2.  öèêëå (øàãè 3-6) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè
CHS-âåðñèÿ: âñå ÷èòàåìûå ñåêòîðû áûëè íà îäíîé äîðîæêå.
LBA-âåðñèÿ: ÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå
ñïåöèôèêàöèè EDD BIOS).
CHS-âåðñèÿ:
3. Ïåðåâîäèò àáñîëþòíûé íîìåð ñåêòîðà â CHS-ñèñòåìó: ñåêòîð ðàññ÷èòûâàåòñÿ êàê
åäèíèöà ïëþñ îñòàòîê îò äåëåíèÿ àáñîëþòíîãî íîìåðà íà ÷èñëî ñåêòîðîâ
íà äîðîæêå; äîðîæêà ðàññ÷èòûâàåòñÿ êàê îñòàòîê îò äåëåíèÿ ÷àñòíîãî,
ïîëó÷åííîãî íà ïðåäûäóùåì øàãå, íà ÷èñëî äîðîæåê, à öèëèíäð - êàê
÷àñòíîå îò ýòîãî æå äåëåíèÿ. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå,
÷åì ÷èñëî ñåêòîðîâ äî êîíöà äîðîæêè, óìåíüøàåò ÷èñëî ñåêòîðîâ äëÿ
÷òåíèÿ.
4. Ôîðìèðóåò äàííûå äëÿ âûçîâà int 13h (ah=2 - ÷òåíèå, al=÷èñëî ñåêòîðîâ,
dh=ãîëîâêà, (ìëàäøèå 6 áèò cl)=ñåêòîð,
(ñòàðøèå 2 áèòà cl è âåñü ch)=äîðîæêà, dl=äèñê, es:bx->áóôåð).
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, âûïîëíÿåò ñáðîñ äèñêà
è ïîâòîðÿåò ïîïûòêó ÷òåíèÿ, âñåãî äåëàåòñÿ íå áîëåå òð¸õ ïîïûòîê
(íåñêîëüêî ïîïûòîê íóæíî â ñëó÷àå äèñêåòû äëÿ ãàðàíòèè òîãî, ÷òî
ìîòîð ðàñêðóòèëñÿ). Åñëè âñå òðè ðàçà ïðîèñõîäèò îøèáêà ÷òåíèÿ,
ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì "Read error".
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3.
LBA-âåðñèÿ:
3. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé
èòåðàöèè) äî 7Fh.
4. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè
push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â
ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà
êëàëè).
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, ïåðåõîäèò íà êîä îáðàáîòêè
îøèáîê ñ ñîîáùåíèåì "Read error". Î÷èùàåò ñòåê îò ïàêåòà,
ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå.
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3.
 
Ïðîöåäóðà îáðàáîòêè îøèáîê (find_error_si è find_error_sp):
íà âõîäå: óêàçàòåëü íà ñîîáùåíèå îá îøèáêå â si ëèáî íà âåðõóøêå ñòåêà
0. Åñëè âûçûâàåòñÿ find_error_si, îíà ïîìåùàåò ïåðåäàííûé óêàçàòåëü â ñòåê.
1. Åñëè îøèáêà ïðîèçîøëà â ïðîöåññå ðàáîòû callback-ôóíêöèè, òî
(ìåòêà error_in_callback) îáðàáîò÷èê ïðîñòî âîçâðàùàåò óïðàâëåíèå
âûçâàâøåìó êîäó, ðàïîðòóÿ î íåíàéäåííîì ôàéëå.
2. Åñëè æå îøèáêà ïðîèçîøëà äî ïåðåäà÷è óïðàâëåíèÿ âòîðè÷íîìó çàãðóç÷èêó,
îáðàáîò÷èê âûâîäèò ñîîáùåíèå òèïà "Error: <òåêóùèé îáúåêò>: <îøèáêà>"
è (âîññòàíîâèâ ñòåê) ïåðåõîäèò ê ñëåäóþùåìó ëîãè÷åñêîìó äèñêó.
 
Ïðîöåäóðà ÷òåíèÿ ôàéëà/àòðèáóòà ïî èçâåñòíîìó ðàçìåùåíèþ íà äèñêå
(read_file_chunk):
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
ds:si = óêàçàòåëü íà èíôîðìàöèþ î ðàçìåùåíèè
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå
ecx = ëèìèò ÷èñëà ñåêòîðîâ äëÿ ÷òåíèÿ, ñòàðøåå ñëîâî äîëæíî áûòü 0
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå,
ôëàã CF óñòàíîâëåí, åñëè âîçíèêëà îøèáêà ÷òåíèÿ
1. Îïðåäåëÿåò, ÿâëÿåòñÿ ëè àòðèáóò ðåçèäåíòíûì (âîçìîæíî òîëüêî â NTFS
è îçíà÷àåò, ÷òî äàííûå ôàéëà/àòðèáóòà óæå áûëè öåëèêîì ïðî÷èòàíû ïðè
îáðàáîòêå èíôîðìàöèè î ôàéëå) èëè íåðåçèäåíòíûì (îçíà÷àåò, ÷òî äàííûå
õðàíÿòñÿ ãäå-òî íà äèñêå, è èìååòñÿ èíôîðìàöèÿ î òîì, ãäå èìåííî).
2. Äëÿ ðåçèäåíòíûõ àòðèáóòîâ (ìåòêà read_file_chunk.resident) ïðîñòî êîïèðóåò
äàííûå ïî ìåñòó íàçíà÷åíèÿ (ñ ó÷¸òîì óêàçàííîãî ëèìèòà).
3. Äëÿ íåðåçèäåíòíûõ àòðèáóòîâ èíôîðìàöèÿ ñîñòîèò èç ïàð <ðàçìåð î÷åðåäíîãî
ôðàãìåíòà ôàéëà â êëàñòåðàõ, ñòàðòîâûé êëàñòåð ôðàãìåíòà>; ïðîöåäóðà
÷èòàåò ôðàãìåíòû, ïîêà ôàéë íå çàêîí÷èòñÿ èëè ïîêà íå áóäåò äîñòèãíóò
óêàçàííûé ëèìèò.
 
Ïðîöåäóðà ïðîñìîòðà êýøà (cache_lookup):
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
eax = èñêîìîå çíà÷åíèå
ss:si = óêàçàòåëü íà ñòðóêòóðó-çàãîëîâîê êýøà
íà âûõîäå: ss:di = óêàçàòåëü íà âõîä â êýøå; ôëàã CF óñòàíîâëåí, åñëè çíà÷åíèå
áûëî òîëüêî ÷òî äîáàâëåíî, è ñáðîøåí, åñëè îíî óæå áûëî â êýøå.
1. Ïðîñìàòðèâàåò êýø â ïîèñêàõ óêàçàííîãî çíà÷åíèÿ. Åñëè çíà÷åíèå íàéäåíî
(ïðè ýòîì ôëàã CF îêàçûâàåòñÿ ñáðîøåííûì), ïåðåõîäèò ê øàãó 4.
2. Åñëè êýø óæå çàïîëíåí, óäàëÿåò èç êýøà ñàìûé ñòàðûé âõîä (îí íàõîäèòñÿ â
ãîëîâå äâóñâÿçíîãî ñïèñêà), èíà÷å äîáàâëÿåò ê êýøó åù¸ îäèí âõîä.
3. Óñòàíàâëèâàåò â ïîëó÷åííîì âõîäå óêàçàííîå çíà÷åíèå. Óñòàíàâëèâàåò ôëàã
CF, ïîñëåäóþùèå øàãè íå ìåíÿþò ñîñòîÿíèÿ ôëàãîâ. Ïåðåõîäèò ê øàãó 5.
4. Óäàëÿåò âõîä èç ñïèñêà.
5. Äîáàâëÿåò ñåêòîð â êîíåö ñïèñêà (ñàìûé íîâûé âõîä).
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win/ntfs.inc
0,0 → 1,587
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
restore_usa:
; Update Sequence Array restore
; in: ds:bx -> USA-protected structure
push bx
lea di, [bx+1feh]
mov cx, [bx+6]
add bx, [bx+4]
dec cx
@@:
mov ax, [bx+2]
mov [di], ax
inc bx
inc bx
add di, 200h
loop @b
pop bx
ret
 
find_attr:
; in: ds:di->file record, ax=attribute
; out: ds:di->attribute or di=0 if not found
add di, [di+14h]
.1:
; attributes' codes are formally dwords, but all of them fit in word
cmp word [di], -1
jz .notfound
cmp word [di], ax
jnz .continue
; for $DATA attribute, scan only unnamed
cmp ax, 80h
jnz .found
cmp byte [di+9], 0
jz .found
.continue:
add di, [di+4]
jmp .1
.notfound:
xor di, di
.found:
ret
 
process_mcb_nonres:
; in: ds:si->attribute, es:di->buffer
; out: es:di->buffer end
pushad
pop di
add si, [si+20h]
xor ebx, ebx
.loop:
lodsb
test al, al
jz .done
push invalid_read_request_string
movzx cx, al
shr cx, 4
jz find_error_sp
xchg ax, dx
and dx, 0Fh
jz find_error_sp
add si, cx
add si, dx
pop ax
push si
dec si
movsx eax, byte [si]
dec cx
jz .l1e
.l1:
dec si
shl eax, 8
mov al, [si]
loop .l1
.l1e:
xchg ebp, eax
dec si
movsx eax, byte [si]
mov cx, dx
dec cx
jz .l2e
.l2:
dec si
shl eax, 8
mov al, byte [si]
loop .l2
.l2e:
pop si
add ebx, ebp
; eax=length, ebx=disk block
stosd
mov eax, ebx
stosd
cmp di, 0x8000 - 12
jbe .loop
..attr_overflow:
mov si, fragmented_string
jmp find_error_si
.done:
xor ax, ax
stosw
stosw
push di
popad
ret
 
load_attr:
; in: ax=attribute, ds:bx->base record
; out: if found: CF=0, attribute loaded to [freeattr], [freeattr] updated,
; edx=size of attribute in bytes
; out: if not found: CF=1
mov di, [bp + freeattr - dat]
push ss
pop es
mov byte [es:di], 1
inc di
cmp di, 0x8000 - 12
ja ..attr_overflow
or edx, -1 ; file size is not known yet
; scan for attribute
push di
mov di, bx
add di, [di+14h]
@@:
call find_attr.1
test di, di
jz .notfound1
cmp byte [di+8], 0
jnz .nonresident
mov si, di
pop di
push ds
jmp .resident
.aux_resident:
mov ax, ds
mov si, di
pop di ds bx ds edx
push ss
pop es
push ds
mov ds, ax
; resident attribute
.resident:
dec di
mov al, 0
stosb
mov ax, [si+10h]
stosw
push di
add di, ax
cmp di, 0x8000 - 12
pop di
ja ..attr_overflow
movzx edx, ax ; length of attribute
xchg ax, cx
add si, [si+14h]
rep movsb
mov [bp + freeattr - dat], di
pop ds
ret
.nonresident:
; nonresident attribute
cmp dword [di+10h], 0
jnz @b
; read start of data
mov si, di
mov edx, [di+30h] ; size of attribute
pop di
call process_mcb_nonres
sub di, 4
push di
.notfound1:
pop di
push edx
; $ATTRIBUTE_LIST is always in base file record
cmp ax, 20h
jz .nofragmented
; try to load $ATTRIBUTE_LIST = 20h
push ax
mov ax, 20h
push [bp + freeattr - dat]
mov [bp + freeattr - dat], di
push di
call load_attr
pop di
pop [bp + freeattr - dat]
pop ax
jc .nofragmented
push ds bx
pusha
mov si, di
push ss
pop ds
push 0x8100
pop es
xor ecx, ecx
mov cl, 0x78
xor bx, bx
push es
call read_file_chunk
pop ds
jc ..found_disk_error
test cx, cx
jz ..attr_overflow
popa
push ss
pop es
xor bx, bx
.1:
cmp [bx], ax
jnz .continue1
; only unnamed $DATA attributes!
cmp ax, 80h
jnz @f
cmp byte [bx+6], 0
jnz .continue1
@@:
cmp dword [bx+10h], 0
jz .continue1
cmp dword [bx+8], 0
jnz @f
dec di
cmp di, [bp + freeattr - dat]
lea di, [di+1]
jnz .continue1
@@:
push ds di
push ax
mov eax, [bx+10h]
mov ecx, [bx+8]
call read_file_record
pop ax
mov di, [14h]
.2:
call find_attr.1
cmp byte [di+8], 0
jz .aux_resident
cmp dword [di+10h], ecx
jnz .2
mov si, di
mov di, sp
cmp dword [ss:di+8], -1
jnz @f
push dword [si+30h] ; size of attribute
pop dword [ss:di+8]
@@:
pop di
call process_mcb_nonres
sub di, 4
pop ds
.continue1:
add bx, [bx+4]
cmp bx, dx
jb .1
pop bx ds
.nofragmented:
pop edx
dec di
cmp di, [bp + freeattr - dat]
jnz @f
stc
ret
@@:
inc di
xor ax, ax
stosw
stosw
mov [bp + freeattr - dat], di
ret
 
read_file_record:
; in: eax = index of record
; out: ds:0 -> record
; find place in cache
push di
push si
mov si, cache1head
call cache_lookup
pop si
pushf
sub di, 3400h
shl di, 10-3
add di, 0x6000
mov ds, di
popf
pop di
jnc .noread
; read file record <eax> to ds:0
pushad
push ds
push es
movzx ecx, [bp + frs_size - dat]
shr cx, 9
mul ecx
push ds
pop es
push ss
pop ds
mov si, 0x4000
xor bx, bx
push [bp + cur_obj - dat]
mov [bp + cur_obj - dat], mft_string
push es
call read_attr
; initialize cache for $INDEX_ALLOCATION for this record
pop si
push si
sub si, 0x6000
mov ax, si
shr si, 10-3
shr ax, 2
add si, 3480h
add ax, 3500h
mov [si], si
mov [si+2], si
mov [si+4], ax
pop ds
call restore_usa
pop [bp + cur_obj - dat]
pop es
pop ds
popad
.noread:
ret
 
read_attr:
; in: eax = offset in sectors, ecx = size in sectors (<10000h), es:bx -> buffer, ds:si -> attribute
push invalid_read_request_string
cmp byte [si], 0
jnz .nonresident
cmp eax, 10000h shr 9
jae find_error_sp
shl ax, 9
shl cx, 9
cmp ax, [si+2]
jae find_error_sp
cmp cx, [si+2]
ja find_error_sp
add si, 3
add si, ax
mov di, bx
rep movsb
pop ax
ret
.nonresident:
inc si
.loop:
mov edx, dword [si]
add si, 8
test edx, edx
jz find_error_sp
imul edx, [bp + sect_per_clust - dat]
sub eax, edx
jnc .loop
add eax, edx
sub edx, eax
push cx
cmp ecx, edx
jb @f
mov cx, dx
@@:
push bx
mov ebx, [si-4]
imul ebx, [bp + sect_per_clust - dat]
add eax, ebx
pop bx
call read
jc ..found_disk_error
mov dx, cx
pop cx
xor eax, eax
sub cx, dx
jnz .loop
pop ax
ret
 
load_file_ntfs:
; in: ss:bp = 0:dat
; in: es:bx = address to load file
; in: ds:si -> ASCIIZ name
; in: cx = limit in sectors
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part has been loaded, bx=2 - file not found
; out: dx:ax = file size (0xFFFFFFFF if file not found)
push es bx cx
mov eax, 5 ; root cluster
mov [bp + cur_obj - dat], root_string
.parse_dir_loop:
push ds si
call read_file_record
; find attributes $INDEX_ROOT, $INDEX_ALLOCATION, $BITMAP
mov ax, [bp + freeattr - dat]
mov [bp + index_root - dat], ax
mov ax, 90h ; $INDEX_ROOT
xor bx, bx
call load_attr
mov si, noindex_string
jc find_error_si
mov ax, [bp + freeattr - dat]
mov [bp + index_alloc - dat], ax
mov ax, 0A0h ; $INDEX_ALLOCATION
call load_attr
jnc @f
mov [bp + index_alloc - dat], bx
@@:
push ds
; search for entry
mov si, [bp + index_root - dat]
push ss
pop ds
push 0x8100
pop es
xor ecx, ecx
mov cl, 0x78
xor bx, bx
push es
call read_file_chunk
pop ds
jc ..found_disk_error
test cx, cx
jz ..attr_overflow
mov si, invalid_read_request_string
cmp word [bx+10], 0
jnz find_error_si
; calculate number of items in cache
mov di, [bx+8] ; subnode_size
mov ax, 0x4000
sub ax, word [bp + frs_size - dat]
cwd
div di
test ax, ax
jz find_error_si
mov si, invalid_volume_msg
test di, 0x1FF
jnz find_error_si
pop cx
mov [bp + cur_index_seg - dat], cx
shl ax, 3
sub cx, 6000h
mov si, cx
shr cx, 2
shr si, 10-3
add cx, ax
add si, 3480h
mov [bp + cur_index_cache - dat], si
add cx, 3500h
mov [ss:si+6], cx
mov dx, di
add bx, 10h
.scan_record:
add bx, [bx]
.scan:
test byte [bx+0Ch], 2
jnz .look_child
movzx cx, byte [bx+50h] ; namelen
lea di, [bx+52h] ; name
push ds
pop es
pop si ds
push ds si
xor ax, ax
.1:
lodsb
cmp al, '/'
jnz @f
mov al, 0
@@:
cmp al, 'A'
jb .nocapital
cmp al, 'Z'
ja .nocapital
or al, 20h
.nocapital:
cmp al, 'a'
jb .notletter
cmp al, 'z'
ja .notletter
or byte [es:di], 20h
.notletter:
scasw
loopz .1
jb .look_child
ja @f
cmp byte [si], 0
jz .file_found
cmp byte [si], '/'
jz .file_found
@@:
push es
pop ds
add bx, [bx+8]
jmp .scan
.look_child:
push es
pop ds
test byte [bx+0Ch], 1
jz .not_found
mov si, [bp + index_alloc - dat]
test si, si
jz .not_found
add bx, [bx+8]
mov eax, [bx-8]
mov es, [bp + cur_index_seg - dat]
push si
mov si, [bp + cur_index_cache - dat]
call cache_lookup
pop si
pushf
mov bx, di
mov bh, 0
shr bx, 3
imul bx, dx
add bx, [bp + frs_size - dat]
popf
jnc .noread
push es
push dx
push ss
pop ds
movzx ecx, dx
shr cx, 9
mul [bp + sect_per_clust - dat]
call read_attr
pop dx
pop es
push es
pop ds
call restore_usa
.noread:
push es
pop ds
add bx, 18h
jmp .scan_record
.not_found:
pop [bp + cur_obj - dat]
mov si, error_not_found
jmp find_error_si
.file_found:
pop [bp + cur_obj - dat]
pop cx
mov ax, [bp + index_root - dat]
mov [bp + freeattr - dat], ax
mov eax, [es:bx]
test byte [es:bx+48h+3], 10h
jz .regular_file
cmp byte [si], 0
jz ..directory_error
inc si
jmp .parse_dir_loop
.regular_file:
cmp byte [si], 0
jnz ..notdir_error
; read entry
call read_file_record
xor bx, bx
mov ax, 80h
call load_attr
mov si, nodata_string
jc find_error_si
mov si, [bp + index_root - dat]
mov [bp + freeattr - dat], si
push ss
pop ds
jmp load_file_common_end
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/after_win
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs/bootsect.asm
0,0 → 1,1024
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
jmp far 0:real_start
; special text
org $+0x7C00
real_start:
; initialize
xor ax, ax
mov ss, ax
mov sp, 0x7C00
mov ds, ax
mov es, ax
cld
sti
mov [bootdrive], dl
; check LBA support
mov ah, 41h
mov bx, 55AAh
int 13h
mov si, aNoLBA
jc err_
cmp bx, 0AA55h
jnz err_
test cl, 1
jz err_
; get file system information
; scan for Primary Volume Descriptor
db 66h
push 10h-1
pop eax
pvd_scan_loop:
mov cx, 1
inc eax
mov bx, 0x1000
call read_sectors
jnc @f
fatal_read_err:
mov si, aReadError
err_:
call out_string
mov si, aPressAnyKey
call out_string
xor ax, ax
int 16h
int 18h
jmp $
@@:
push ds
pop es
cmp word [bx+1], 'CD'
jnz pvd_scan_loop
cmp word [bx+3], '00'
jnz pvd_scan_loop
cmp byte [bx+5], '1'
jnz pvd_scan_loop
; we have found ISO9660 descriptor, look for type
cmp byte [bx], 1 ; Primary Volume Descriptor?
jz pvd_found
cmp byte [bx], 0xFF ; Volume Descriptor Set Terminator?
jnz pvd_scan_loop
; Volume Descriptor Set Terminator reached, no PVD found - fatal error
mov si, no_pvd
jmp err_
pvd_found:
add bx, 80h
mov ax, [bx]
mov [lb_size], ax
; calculate number of logical blocks in one sector
mov ax, 800h
cwd
div word [bx]
mov [lb_per_sec], ax
; get location of root directory
mov di, root_location
movzx eax, byte [bx+1Dh]
add eax, [bx+1Eh]
stosd
; get memory size
int 12h
mov si, nomem_str
cmp ax, 71000h / 400h
jb err_
shr ax, 1
sub ax, 60000h / 800h
mov [size_rest], ax
mov [free_ptr], 60000h / 800h
; load path table
; if size > 62K => it's very strange, avoid using it
; if size > (size of cache)/2 => avoid using it too
mov ecx, [bx+4]
cmp ecx, 0x10000 - 0x800
ja nopathtable
shr ax, 1
cmp ax, 0x20
jae @f
shl ax, 11
cmp cx, ax
ja nopathtable
@@:
; size is ok, try to load it
mov [pathtable_size], cx
mov eax, [bx+12]
xor edx, edx
div dword [lb_per_sec]
imul dx, [bx]
mov [pathtable_start], dx
add cx, dx
call cx_to_sectors
xor bx, bx
push 6000h
pop es
call read_sectors
jc nopathtable
; path table has been loaded
inc [use_path_table]
sub [size_rest], cx
add [free_ptr], cx
nopathtable:
; init cache
mov ax, [size_rest]
mov [cache_size], ax
mov ax, [free_ptr]
mov [cache_start], ax
; load secondary loader
mov di, secondary_loader_info
call load_file
test bx, bx
jnz noloader
; set registers for secondary loader
mov ah, [bootdrive]
mov al, 'c'
mov bx, 'is'
mov si, callback
jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000
 
noloader:
mov si, aKernelNotFound
jmp err_
 
read_sectors:
; es:bx = pointer to data
; eax = first sector
; cx = number of sectors
pushad
push ds
do_read_sectors:
push ax
push cx
cmp cx, 0x7F
jbe @f
mov cx, 0x7F
@@:
; create disk address packet on the stack
; dq starting LBA
db 66h
push 0
push eax
; dd buffer
push es
push bx
; dw number of blocks to transfer (no more than 0x7F)
push cx
; dw packet size in bytes
push 10h
; issue BIOS call
push ss
pop ds
mov si, sp
mov dl, [cs:bootdrive]
mov ah, 42h
int 13h
jc diskreaderr
; restore stack
add sp, 10h
; increase current sector & buffer; decrease number of sectors
movzx esi, cx
mov ax, es
shl cx, 7
add ax, cx
mov es, ax
pop cx
pop ax
add eax, esi
sub cx, si
jnz do_read_sectors
pop ds
popad
ret
diskreaderr:
add sp, 10h + 2*2
pop ds
popad
stc
out_string.ret:
ret
 
out_string:
; in: ds:si -> ASCIIZ string
lodsb
test al, al
jz .ret
mov ah, 0Eh
mov bx, 7
int 10h
jmp out_string
 
aNoLBA db 'The drive does not support LBA!',0
aReadError db 'Read error',0
no_pvd db 'Primary Volume Descriptor not found!',0
nomem_str db 'No memory',0
aPressAnyKey db 13,10,'Press any key...',13,10,0
 
load_file:
; in: ds:di -> information structure
; dw:dw address
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
; ASCIIZ name
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found
; out: dx:ax = file size (0xFFFFFFFF if file not found)
; parse path to the file
lea si, [di+6]
mov eax, [cs:root_location]
cmp [cs:use_path_table], 0
jz parse_dir
; scan for path in path table
push di
push 6000h
pop es
mov di, [cs:pathtable_start] ; es:di = pointer to current entry in path table
mov dx, 1 ; dx = number of current entry in path table, start from 1
mov cx, [cs:pathtable_size]
pathtable_newparent:
mov bx, dx ; bx = number of current parent in path table: root = 1
scan_path_table_e:
call is_last_component
jnc path_table_scanned
scan_path_table_i:
cmp word [es:di+6], bx
jb .next
ja path_table_notfound
call test_filename1
jc .next
@@:
lodsb
cmp al, '/'
jnz @b
jmp pathtable_newparent
.next:
; go to next entry
inc dx
movzx ax, byte [es:di]
add ax, 8+1
and al, not 1
add di, ax
sub cx, ax
ja scan_path_table_i
path_table_notfound:
pop di
mov ax, -1
mov dx, ax
mov bx, 2 ; file not found
ret
path_table_scanned:
movzx eax, byte [es:di+1]
add eax, [es:di+2]
pop di
parse_dir:
; eax = logical block, ds:di -> information structure, ds:si -> file name
; was the folder already read?
push di ds
push cs
pop ds
mov [cur_desc_end], 2000h
mov bx, cachelist
.scan1:
mov bx, [bx+2]
cmp bx, cachelist
jz .notfound
cmp [bx+4], eax
jnz .scan1
.found:
; yes; delete this item from the list (the following code will append this item to the tail)
mov di, [bx]
push word [bx+2]
pop word [di+2]
mov di, [bx+2]
push word [bx]
pop word [di]
mov di, bx
jmp .scan
.notfound:
; no; load first sector of the folder to get its size
push eax
push si
mov si, 1
call load_phys_sector_for_lb_force
mov bx, si
pop si
pop eax
jnc @f
; read error - return
.readerr:
pop ds
.readerr2:
pop di
mov ax, -1
mov dx, ax
mov bx, 3
ret
@@:
; first item of the folder describes the folder itself
; do not cache too big folders: size < 64K and size <= (total cache size)/2
cmp word [bx+12], 0
jnz .nocache
mov cx, [cache_size] ; cx = cache size in sectors
shr cx, 1 ; cx = (cache size)/2
cmp cx, 0x20
jae @f
shl cx, 11
cmp [bx+10], cx
ja .nocache
@@:
; we want to cache this folder; get space for it
mov cx, [bx+10]
call cx_to_sectors
jnz .yescache
.nocache:
push dword [bx+10]
pop dword [cur_nocache_len]
call lb_to_sector
push ds
pop es
pop ds
.nocache_loop:
push eax
mov dx, 1800h
call scan_for_filename_in_sector
mov cx, dx
pop eax
jnc .j_scandone
sub cx, bx
sub word [es:cur_nocache_len], cx
sbb word [es:cur_nocache_len+2], 0
jb .j_scandone
ja @f
cmp word [es:cur_nocache_len], 0
jz .j_scandone
@@:
mov cx, 1
inc eax
push es
mov bx, 1000h
call read_sectors
pop es
jc .readerr2
jmp .nocache_loop
.j_scandone:
jmp .scandone
.yescache:
push bx
mov bx, [cachelist.head]
.freeloop:
cmp cx, [size_rest]
jbe .sizeok
@@:
; if we are here: there is not enough free space, so we must delete old folders' data
; N.B. We know that after deleting some folders the space will be available (size <= (total cache size)/2).
; one loop iteration: delete data of one folder
pusha
mov dx, [bx+10]
mov es, dx ; es = segment of folder data to be deleted
xor di, di
mov ax, [bx+8]
add ax, 0x7FF
rcr ax, 1
shr ax, 10
push ax
shl ax, 11-4 ; get number of paragraphs in folder data to be deleted
mov cx, [cache_size]
add cx, [cache_start]
push ds
push ax
add ax, dx
mov ds, ax
pop ax
shl cx, 11-4
sub cx, dx ; cx = number of paragraphs to be moved
push si
xor si, si
; move cx paragraphs from ds:si to es:di to get free space in the end of cache
@@:
sub cx, 1000h
jbe @f
push cx
mov cx, 8000h
rep movsw
mov cx, ds
add cx, 1000h
mov ds, cx
mov cx, es
add cx, 1000h
mov es, cx
pop cx
jmp @b
@@:
add cx, 1000h
shl cx, 3
rep movsw
pop si
pop ds
; correct positions in cache for existing items
mov cx, 80h
mov di, 8400h
.correct:
cmp [di+10], dx
jbe @f
sub [di+10], ax
@@:
add di, 12
loop .correct
; some additional space is free now
pop ax
add [size_rest], ax
sub [free_ptr], ax
; add cache item to the list of free items
mov dx, [bx]
mov ax, [free_cache_item]
mov [bx], ax
mov [free_cache_item], bx
mov bx, dx
; current iteration done
popa
jmp .freeloop
.sizeok:
mov [cachelist.head], bx
mov word [bx+2], cachelist
; allocate new item in cache
mov di, [free_cache_item]
test di, di
jz .nofree
push word [di]
pop [free_cache_item]
jmp @f
.nofree:
mov di, [last_cache_item]
add [last_cache_item], 12
@@:
pop bx
push si di
; mov [di+4], eax ; start of folder
scasd
stosd
push ax
mov ax, [free_ptr]
shl ax, 11-4
mov [di+10-8], ax
mov es, ax
pop ax
add [free_ptr], cx
sub [size_rest], cx
; read folder data
; first sector is already in memory, 0000:bx
pusha
mov cx, [bx+10]
mov [di+8-8], cx ; folder size in bytes
mov si, bx
xor di, di
mov cx, 0x1800
sub cx, si
rep movsb
pop ax
push di
popa
; read rest of folder
mov esi, dword [lb_per_sec]
add eax, esi
dec si
not si
and ax, si
mov si, word [bx+10]
mov bx, di
pop di
sub si, bx
jbe @f
mov [cur_limit], esi
call read_many_bytes
pop si
jnc .scan
jmp .readerr
@@:
pop si
.scan:
; now we have required cache item; append it to the end of list
mov bx, [cachelist.tail]
mov [cachelist.tail], di
mov [di+2], bx
mov word [di], cachelist
mov [bx], di
; scan for given filename
mov es, [di+10]
mov dx, [di+8]
pop ds
xor bx, bx
call scan_for_filename_in_sector
.scandone:
push cs
pop es
mov bx, 2000h
cmp bx, [es:cur_desc_end]
jnz filefound
j_notfound:
jmp path_table_notfound
filefound:
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
@@:
mov cl, [es:bx+8]
test al, al
jz @f
; parse next component of file name
test cl, 2 ; directory?
jz j_notfound
mov eax, [es:bx]
pop di
jmp parse_dir
@@:
test cl, 2 ; directory?
jnz j_notfound ; do not allow read directories as regular files
; ok, now load the file
pop di
les bx, [di]
call normalize
movzx esi, word [di+4] ; esi = limit in 4K blocks
shl esi, 12 ; esi = limit in bytes
push cs
pop ds
mov [cur_limit], esi
mov di, 2000h
loadloop:
and [cur_start], 0
.loadnew:
mov esi, [cur_limit]
mov eax, [cur_start]
add esi, eax
mov [overflow], 1
sub esi, [di+4]
jb @f
xor esi, esi
dec [overflow]
@@:
add esi, [di+4] ; esi = number of bytes to read
mov [cur_start], esi
sub esi, eax
jz .loadcontinue
xor edx, edx
div dword [lb_size] ; eax = number of logical blocks to skip,
mov [first_byte], dx; [first_byte] = number of bytes to skip in 1st block
cmp byte [di+10], 0
jnz .interleaved
add eax, [di]
; read esi bytes from logical block eax to buffer es:bx
call read_many_bytes.with_first
jc .readerr3
.loadcontinue:
mov [cur_chunk], di
add di, 11
cmp di, [cur_desc_end]
jae @f
cmp [cur_limit], 0
jnz loadloop
@@:
mov bx, [overflow]
.calclen:
; calculate length of file
xor ax, ax
xor dx, dx
mov di, 2000h
@@:
add ax, [di+4]
adc dx, [di+6]
add di, 11
cmp di, [cur_desc_end]
jb @b
ret
.interleaved:
mov [cur_unit_limit], esi
push esi
; skip first blocks
movzx ecx, byte [di+9] ; Unit Size
movzx esi, byte [di+10] ; Interleave Gap
add si, cx
mov edx, [di]
@@:
sub eax, ecx
jb @f
add edx, esi
jmp @b
@@:
add ecx, eax ; ecx = number of logical blocks to skip
lea eax, [ecx+edx] ; eax = first logical block
pop esi
.interleaved_loop:
; get number of bytes in current file unit
push eax
movzx eax, byte [di+9]
sub ax, cx
imul eax, dword [lb_size]
cmp eax, esi
ja .i2
.i1:
xchg esi, eax
.i2:
pop eax
sub [cur_unit_limit], esi
push eax
; read esi bytes from logical block eax to buffer es:bx
call read_many_bytes.with_first
pop eax
jnc @f
.readerr3:
mov bx, 3
jmp .calclen
@@:
mov esi, [cur_unit_limit]
test esi, esi
jz .loadcontinue
movzx ecx, byte [di+9] ; add Unit Size
add cl, byte [di+10] ; add Interleave Gap
adc ch, 0
add eax, ecx
xor cx, cx
mov [first_byte], cx
jmp .interleaved_loop
 
cx_to_sectors:
add cx, 7FFh
rcr cx, 1
shr cx, 10
ret
 
is_last_component:
; in: ds:si -> name
; out: CF set <=> current component is not last (=> folder)
push si
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
stc
@@:
pop si
ret
 
test_filename1:
; in: ds:si -> filename, es:di -> path table item
; out: CF set <=> no match
pusha
mov cl, [es:di]
add di, 8
jmp test_filename2.start
test_filename2:
; in: ds:si -> filename, es:bx -> directory item
; out: CF set <=> no match
pusha
mov cl, [es:bx+32]
lea di, [bx+33]
.start:
mov ch, 0
@@:
lodsb
test al, al
jz .test1
cmp al, '/'
jz .test1
call toupper
mov ah, al
mov al, [es:di]
call toupper
inc di
cmp al, ah
loopz @b
jnz .next1
; if we have reached this point: current name is done
lodsb
test al, al
jz .ret
cmp al, '/'
jz .ret
; if we have reached this point: current name is done, but input name continues
; so they do not match
jmp .next1
.test1:
; if we have reached this point: input name is done, but current name continues
; "filename.ext;version" in ISO-9660 represents file "filename.ext"
; "filename." and "filename.;version" are also possible for "filename"
cmp byte [es:di], '.'
jnz @f
inc di
dec cx
jz .ret
@@:
cmp byte [es:di], ';'
jnz .next1
jmp .ret
.next1:
stc
.ret:
popa
ret
 
toupper:
; in: al=symbol
; out: al=symbol in uppercase
cmp al, 'a'
jb .ret
cmp al, 'z'
ja .ret
sub al, 'a'-'A'
.ret:
ret
 
scan_for_filename_in_sector:
; in: ds:si->filename, es:bx->folder data, dx=limit
; out: CF=0 if found
push bx
.loope:
push bx
.loop:
cmp bx, dx
jae .notfound
cmp byte [es:bx], 0
jz .loopd
test byte [es:bx+25], 4 ; ignore files with Associated bit
jnz .next
call test_filename2
jc .next
push ds es di
push es
pop ds
push cs
pop es
mov di, [es:cur_desc_end]
movzx eax, byte [bx+1]
add eax, [bx+2]
stosd ; first logical block
mov eax, [bx+10]
stosd ; length
mov al, [bx+25]
stosb ; flags
mov ax, [bx+26]
stosw ; File Unit size, Interleave Gap size
mov [es:cur_desc_end], di
cmp di, 3000h
pop di es ds
jae .done
test byte [es:bx+25], 80h
jz .done
.next:
add bl, [es:bx]
adc bh, 0
jmp .loop
.loopd:
mov ax, bx
pop bx
@@:
add bx, [cs:lb_size]
jz .done2
cmp bx, ax
jb @b
jmp .loope
.notfound:
stc
.done:
pop bx
.done2:
pop bx
ret
 
lb_to_sector:
xor edx, edx
div dword [lb_per_sec]
ret
 
load_phys_sector_for_lb_force:
; in: eax = logical block, ds=0
; in: si=0 - accept 0 logical blocks, otherwise force read at least 1
; out: 0000:1000 = physical sector data; si -> logical block
; out: eax = next physical sector
; out: CF=1 if read error
; destroys cx
; this procedure reads 0-3 or 1-4 logical blocks, up to the end of physical sector
call lb_to_sector
or si, dx
jnz @f
mov si, 1800h
jmp .done
@@:
mov si, 1000h
imul dx, [lb_size]
add si, dx
mov cx, 1
push es bx
push ds
pop es
mov bx, 1000h
call read_sectors
pop bx es
inc eax
.done:
ret
 
normalize:
; in: es:bx = far pointer
; out: es:bx = normalized pointer (i.e. 0 <= bx < 0x10)
push ax bx
mov ax, es
shr bx, 4
add ax, bx
mov es, ax
pop bx ax
and bx, 0x0F
ret
 
read_many_bytes:
and [first_byte], 0
read_many_bytes.with_first:
; read esi bytes from logical block dx:ax to buffer es:bx
; out: CF=1 <=> disk error
push di
; load first physical sector
push bx si
mov si, [first_byte]
call load_phys_sector_for_lb_force
jnc @f
pop si bx
.ret:
pop di
ret
@@:
add si, [first_byte]
mov ecx, 1800h
sub cx, si
mov ebx, esi
pop bx
sub ebx, ecx
jnc @f
add cx, bx
xor ebx, ebx
@@:
pop di
sub [cur_limit], ecx
rep movsb
mov esi, ebx
mov bx, di
call normalize
; load other physical sectors
; read esi bytes from physical sector eax to buffer es:bx
test esi, esi
jz .ret
push esi
add esi, 0x7FF
and si, not 0x7FF
cmp esi, [cur_limit]
jbe .okplace
.noplace:
sub esi, 800h
.okplace:
shr esi, 11 ; si = number of sectors
mov cx, si
jz @f
call read_sectors
@@:
pop esi
jc .ret
movzx ecx, cx
add eax, ecx
shl ecx, 11
sub [cur_limit], ecx
sub esi, ecx
jc .big
jz .nopost
push bx es
push ds
pop es
mov bx, 1000h
mov cx, 1
call read_sectors
pop es di
jc .ret2
mov cx, si
mov si, 1000h
sub word [cur_limit], cx
sbb word [cur_limit+2], 0
rep movsb
mov bx, di
call normalize
.nopost:
clc
.ret2:
pop di
ret
.big:
mov ax, es
sub ax, 80h
mov es, ax
add bx, 800h
add bx, si
call normalize
sub [cur_limit], esi
jmp .nopost
 
; Callback function for secondary loader
callback:
; in: ax = function number; only function 1 is defined for now
dec ax
jz callback_readfile
dec ax
jz callback_continueread
stc ; unsupported function
retf
 
callback_readfile:
; function 1: read file
; in: ds:di -> information structure
; dw:dw address
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
; ASCIIZ name
; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error
; out: dx:ax = file size (0xFFFFFFFF if file was not found)
call load_file
clc ; function is supported
retf
 
callback_continueread:
; function 2: continue to read file
; in: ds:di -> information structure
; dw:dw address
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=3 - read error
; out: dx:ax = file size
les bx, [di]
call normalize
movzx esi, word [di+4] ; si = limit in 4K blocks
shl esi, 12 ; bp:si = limit in bytes
push cs
pop ds
mov [cur_limit], esi
mov di, [cur_chunk]
call loadloop.loadnew
clc ; function is supported
retf
 
secondary_loader_info:
dw 0, 0x1000
dw 0x30000 / 0x1000
db 'kord/loader',0
aKernelNotFound db 'Fatal error: cannot load the secondary loader',0
 
align 2
cachelist:
.head dw cachelist
.tail dw cachelist
free_cache_item dw 0
last_cache_item dw 0x8400
 
use_path_table db 0
bootdrive db ?
align 2
lb_size dw ? ; Logical Block size in bytes
dw 0 ; to allow access dword [lb_size]
lb_per_sec dw ? ; Logical Blocks per physical sector
dw 0 ; to allow access dword [lb_per_sec]
free_ptr dw ? ; first free block in cache (cache block = sector = 0x800 bytes)
size_rest dw ? ; free space in cache (in blocks)
cache_size dw ?
cache_start dw ?
pathtable_size dw ?
pathtable_start dw ?
root_location dd ?
cur_desc_end dw ?
cur_nocache_len dd ?
cur_limit dd ?
cur_unit_limit dd ?
overflow dw ?
cur_chunk dw ?
first_byte dw ?
cur_start dd ?
 
;times 83FEh-$ db 0
db 43h
; just to make file 2048 bytes long :)
db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
 
dw 0xAA55 ; this is not required for CD, but to be consistent...
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs/build.bat
0,0 → 1,2
@fasm -m 65535 bootsect.asm bootsect.bin
@pause
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs/bootsect.txt
0,0 → 1,418
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
Sector not found. N. N.N.N. N.N.N.N.N.N.N. N.N. N.N.N.N.N.N.?
 
Áóòñåêòîð äëÿ çàãðóçêè ñ CD/DVD ñ ôàéëîâîé ñèñòåìîé ISO-9660.
(ISO-9660 è å¸ ðàñøèðåíèÿ - ñòàíäàðò äëÿ CD; DVD ìîæåò èñïîëüçîâàòü
ëèáî ISO-9660, ëèáî UDF.)
 
=====================================================================
 
Òðåáîâàíèÿ äëÿ ðàáîòû:
1) Ñàì áóòñåêòîð è âñå èñïîëüçóåìûå ôàéëû äîëæíû áûòü ÷èòàáåëüíû.
2) Ìèíèìàëüíûé ïðîöåññîð - 80386.
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 452K ñâîáîäíîé áàçîâîé ïàìÿòè.
 
=====================================================================
 
Äîêóìåíòàöèÿ â òåìó (ññûëêè ïðîâåðÿëèñü íà âàëèäíîñòü 14.09.2008):
ñòàíäàðò ISO-9660: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
ñòàíäàðò çàãðóçî÷íîãî CD: http://www.phoenix.com/NR/rdonlyres/98D3219C-9CC9-4DF5-B496-A286D893E36A/0/specscdrom.pdf
îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
 
=====================================================================
 
Ñõåìà èñïîëüçóåìîé ïàìÿòè:
1000-1800 âðåìåííûé áóôåð äëÿ ÷òåíèÿ îäèíî÷íûõ ñåêòîðîâ
...-7C00 ñòåê
7C00-8400 êîä áóòñåêòîðà
8400-8A00 èíôîðìàöèÿ î êýøå äëÿ ïàïîê: ìàññèâ âõîäîâ ñëåäóþùåãî
ôîðìàòà:
dw ñëåäóþùèé ýëåìåíò â L2-ñïèñêå çàêýøèðîâàííûõ ïàïîê,
óïîðÿäî÷åííîì ïî âðåìåíè èñïîëüçîâàíèÿ
(ãîëîâà ñïèñêà - ñàìûé ñòàðûé);
dw ïðåäûäóùèé ýëåìåíò â òîì æå ñïèñêå;
dd ïåðâûé ñåêòîð ïàïêè;
dw ðàçìåð ïàïêè â áàéòàõ;
dw ñåãìåíò êýøà
60000-... ñîäåðæèìîå Path Table, åñëè îíà èñïîëüçóåòñÿ
+ êýø äëÿ ïàïîê;
òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé
ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî
ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area
 
=====================================================================
 
Îñíîâíîé ïðîöåññ çàãðóçêè.
Òî÷êà âõîäà (start): ïîëó÷àåò óïðàâëåíèå îò BIOS ïðè çàãðóçêå, ïðè ýòîì
dl ñîäåðæèò èäåíòèôèêàòîð äèñêà, ñ êîòîðîãî èä¸ò çàãðóçêà
1. Ïðè ïåðåäà÷å óïðàâëåíèÿ çàãðóçî÷íîìó êîäó â ñëó÷àå CD/DVD ïàðà cs:ip
ðàâíà íå 0:7C00, à íà 07C0:0000. Ïîýòîìó ñíà÷àëà çàãðóç÷èê äåëàåò
äàëüíèé ïðûæîê íà ñàìîãî ñåáÿ ñ öåëüþ ïîëó÷èòü cs=0 (â íåêîòîðûõ
ìåñòàõ èñïîëüçóåòñÿ àäðåñàöèÿ ïåðåìåííûõ çàãðóç÷èêà ÷åðåç cs, ïîñêîëüêó
è ds, è es ìîãóò áûòü çàíÿòû ïîä äðóãèå ñåãìåíòû).
2. Íàñòðàèâàåò ñòåê ss:sp = 0:7C00 (íåïîñðåäñòâåííî ïåðåä îñíîâíûì êîäîì)
è ñåãìåíòíûå ðåãèñòðû ds=es=0. Ôîðñèðóåò ñáðîøåííûé ôëàã íàïðàâëåíèÿ
è ðàçðåø¸ííûå ïðåðûâàíèÿ. Ñîõðàíÿåò èäåíòèôèêàòîð çàãðóçî÷íîãî äèñêà
â ñïåöèàëüíóþ ïåðåìåííóþ.
3. Ïðîâåðÿåò ïîääåðæêó LBA. Äëÿ CD/DVD íîñèòåëÿ BIOS îáÿçàíà ïðåäîñòàâëÿòü
LBA-ôóíêöèè.
4. Èùåò îïèñàòåëü òîìà CD (Primary Volume Descriptor, PVD): ïî ñòàíäàðòó
ISO9660 ñî ñìåùåíèÿ 10h íà÷èíàåòñÿ öåïî÷êà îïèñàòåëåé òîìà,
çàâåðøàþùàÿñÿ ñïåöèàëüíûì îïèñàòåëåì (Volume Descriptor Set
Terminator). Êîä ïî î÷åðåäè ñ÷èòûâàåò âñå ñåêòîðà, ïîêà íå íàòêí¸òñÿ
ëèáî íà èñêîìûé îïèñàòåëü, ëèáî íà òåðìèíàòîð. Âî âòîðîì ñëó÷àå
âûäà¸òñÿ ñîîòâåòñòâóþùåå ñîîáùåíèå, è çàãðóçêà ïðåêðàùàåòñÿ.
Âîîáùå ãîâîðÿ, â ñëó÷àå ìóëüòèñåññèîííûõ CD îñíîâíîé êàòàëîã ñîäåðæèìîãî CD
ðàñïîëàãàåòñÿ â ïîñëåäíåé ñåññèè. È ñïåöèôèêàöèÿ ElTorito çàãðóçî÷íîãî
CD îïåðèðóåò òàêæå ñ ïîñëåäíåé ñåññèåé. Îäíàêî íà ïðàêòèêå îêàçûâàåòñÿ,
÷òî: âî-ïåðâûõ, ðåàëüíûå BIOSû íå ïîíèìàþò ìóëüòèñåññèîííûõ CD è
âñåãäà èñïîëüçóþò ïåðâóþ ñåññèþ; âî-âòîðûõ, BIOSîâñêèé int 13h ïðîñòî
íå ïîçâîëÿåò ïîëó÷èòü èíôîðìàöèþ î ïîñëåäíåé ñåññèè.  ñâÿçè ñ ýòèì
çàãðóç÷èê òàêæå èñïîëüçóåò ïåðâóþ ñåññèþ. (Â-òðåòüèõ, â îäíîé èç BIOS
îáíàðóæèëàñü çàãîòîâêà, êîòîðàÿ â ñëó÷àå çàïðîñà ñåêòîðà 10h, â êîòîðîì
âî âñåõ íîðìàëüíûõ ñëó÷àÿõ è ðàñïîëàãàåòñÿ PVD, ïåðåíàïðàâëÿåò åãî
íà ñåêòîð 10h+(íà÷àëî ñåññèè). Åñëè áû ýòîò BIOS åù¸ è ãðóçèëñÿ ñ
ïîñëåäíåé ñåññèè, òî áëàãîäàðÿ çàãîòîâêå çàãðóç÷èê áåç âñÿêèõ
ìîäèôèêàöèé òàêæå ÷èòàë áû ïîñëåäíþþ ñåññèþ.)
5. (ìåòêà pvd_found) Ñ÷èòûâàåò èç PVD íåêîòîðóþ èíôîðìàöèþ î òîìå âî
âíóòðåííèå ïåðåìåííûå: ðàçìåð ëîãè÷åñêîãî áëîêà (ñîãëàñíî ñïåöèôèêàöèè,
äîëæåí áûòü ñòåïåíüþ äâîéêè îò 512 äî ðàçìåðà ëîãè÷åñêîãî ñåêòîðà,
ðàâíîãî 2048 äëÿ CD è DVD); ïîëîæåíèå íà äèñêå êîðíåâîé ïàïêè;
âû÷èñëÿåò ÷èñëî áëîêîâ â ñåêòîðå (èç ïðåäûäóùåãî ïðèìå÷àíèÿ ñëåäóåò,
÷òî îíî âñåãäà öåëîå è ñàìî ÿâëÿåòñÿ ñòåïåíüþ äâîéêè).
6. Ïîëó÷àåò ðàçìåð áàçîâîé ïàìÿòè âûçîâîì int 12h; íà åãî îñíîâå âû÷èñëÿåò
ðàçìåð ïðîñòðàíñòâà, êîòîðîå ìîæåò èñïîëüçîâàòü çàãðóç÷èê (îò
àäðåñà 6000:0000 äî êîíöà äîñòóïíîé ïàìÿòè).
7. Çàãðóæàåò òàáëèöó ïóòåé CD (Path Table) - îáëàñòü äàííûõ, êîòîðàÿ ñîäåðæèò
áàçîâóþ èíôîðìàöèþ îáî âñåõ ïàïêàõ íà äèñêå. Åñëè òàáëèöà ñëèøêîì
âåëèêà (áîëüøå 62K èëè áîëüøå ïîëîâèíû äîñòóïíîé ïàìÿòè), òî îíà
èãíîðèðóåòñÿ. Åñëè òàáëèöà ïóòåé íåäîñòóïíà, òî çàïðîñ òèïà
dir1/dir2/dir3/file ïðèâåä¸ò ê ïîñëåäîâàòåëüíîìó ðàçáîðó êîðíåâîé
ïàïêè è ïàïîê dir1,dir2,dir3; åñëè äîñòóïíà, òî äîñòàòî÷íî ðàçîáðàòü
ñàìó òàáëèöó ïóòåé (ãäå çàïèñàíî ïîëîæåíèå ïàïêè dir1/dir2/dir3)
è ïàïêó dir3. Åñëè òàáëèöà çàãðóæåíà, òî ñîîòâåòñòâåííî óìåíüøàåòñÿ
îáú¸ì îñòàâøåéñÿ äîñòóïíîé ïàìÿòè è óâåëè÷èâàåòñÿ óêàçàòåëü íà
ñâîáîäíóþ îáëàñòü.
8. Çàïîìèíàåò îáùèé ðàçìåð è íà÷àëî êýøà äëÿ ïàïîê (âñÿ îñòàâøàÿñÿ ïîñëå ï.7
äîñòóïíàÿ ïàìÿòü îòâîäèòñÿ ïîä ýòîò êýø).
9. Âûäà¸ò çàïðîñ íà ÷òåíèå ôàéëà âòîðè÷íîãî çàãðóç÷èêà kord/loader. Ïðè îøèáêå
ïå÷àòàåò ñîîòâåòñòâóþùåå ñîîáùåíèå è ïðåêðàùàåò çàãðóçêó ñ CD.
10. Óñòàíàâëèâàåò ðåãèñòðû äëÿ âòîðè÷íîãî çàãðóç÷èêà: al='c' èäåíòèôèöèðóåò
òèï óñòðîéñòâà - CD/DVD; ah=BIOS-èäåíòèôèêàòîð äèñêà; bx='is'
èäåíòèôèöèðóåò ôàéëîâóþ ñèñòåìó ISO-9660; ds:si óêàçûâàåò íà
callback-ôóíêöèþ, êîòîðóþ ìîæåò âûçûâàòü âòîðè÷íûé çàãðóç÷èê.
11. Ïåðåäà¸ò óïðàâëåíèå âòîðè÷íîìó çàãðóç÷èêó, ñîâåðøàÿ äàëüíèé ïðûæîê
íà àäðåñ, êóäà kord/loader áûë çàãðóæåí.
 
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà (callback):
ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà.
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê.
Ïåðåíàïðàâëÿåò çàïðîñ ñîîòâåòñòâóþùåé ëîêàëüíîé ïðîöåäóðå (load_file ïðè
ïåðâîì çàïðîñå íà çàãðóçêó ôàéëà, loadloop.loadnew ïðè ïîñëåäóþùèõ
çàïðîñàõ íà ïðîäîëæåíèå çàãðóçêè ôàéëà).
 
Âñïîìîãàòåëüíûå ïðîöåäóðû.
Êîä îáðàáîòêè îøèáîê (err):
1. Âûâîäèò ñòðîêó ñ ñîîáùåíèåì îá îøèáêå.
2. Âûâîäèò ñòðîêó "Press any key...".
3. Æä¸ò íàæàòèÿ any key.
4. Âûçûâàåò int 18h, äàâàÿ øàíñ BIOSó ïîïûòàòüñÿ çàãðóçèòüñÿ îòêóäà-íèáóäü åù¸.
5. Äëÿ ïîäñòðàõîâêè çàöèêëèâàåòñÿ.
 
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read_sectors):
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå
eax = ñòàðòîâûé ñåêòîð
cx = ÷èñëî ñåêòîðîâ
íà âûõîäå:
es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå
åñëè ïðîèçîøëà îøèáêà ÷òåíèÿ, ôëàã CF óñòàíîâëåí
1.  öèêëå (øàãè 2-4) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè
÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå ñïåöèôèêàöèè
EDD BIOS).
2. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé
èòåðàöèè) äî 7Fh.
3. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè
push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â
ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà
êëàëè).
4. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, î÷èùàåò ñòåê,
óñòàíàâëèâàåò CF=1 è âûõîäèò èç ïðîöåäóðû.
Î÷èùàåò ñòåê îò ïàêåòà, ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå.
5.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 2.
 
Ïðîöåäóðà âûâîäà íà ýêðàí ASCIIZ-ñòðîêè (out_string):
íà âõîäå: ds:si -> ñòðîêà
 öèêëå, ïîêà íå äîñòèãíóò çàâåðøàþùèé íîëü, âûçûâàåò ôóíêöèþ int 10h/ah=0Eh.
 
Ïðîöåäóðà çàãðóçêè ôàéëà (load_file):
íà âõîäå:
ds:di = óêàçàòåëü íà èíôîðìàöèîííóþ ñòðóêòóðó, îïèñàííóþ â ñïåöèôèêàöèè
íà çàãðóç÷èê, à òàêæå â êîììåíòàðèÿõ ê êîäó
íà âûõîäå:
bx = ñòàòóñ: 0=óñïåõ, 1=ôàéë ñëèøêîì áîëüøîé, ïðî÷èòàíà òîëüêî ÷àñòü,
2=ôàéë íå íàéäåí, 3=îøèáêà ÷òåíèÿ
dx:ax = ðàçìåð ôàéëà, 0xFFFFFFFF, åñëè ôàéë íå íàéäåí
1. Åñëè ïîäãîòîâèòåëüíûé êîä çàãðóçèë òàáëèöó ïóòåé, òî èùåò ïàïêó â òàáëèöå,
èíà÷å ïåðåõîäèò ñðàçó ê øàãó 4, óñòàíîâèâ eax = íà÷àëüíûé áëîê
êîðíåâîé ïàïêè.
2. Óñòàíàâëèâàåò es:di íà íà÷àëî òàáëèöû ïóòåé. Îãðàíè÷åíèå íà ðàçìåð
ãàðàíòèðóåò, ÷òî âñÿ òàáëèöà ïîìåùàåòñÿ â ñåãìåíòå 6000h.
Èíèöèàëèçèðóåò dx (â êîòîðîì áóäåò õðàíèòñÿ íîìåð òåêóùåãî âõîäà â
òàáëèöå, ñ÷èòàÿ ñ 1), cx (ðàçìåð îñòàâøåãîñÿ ó÷àñòêà òàáëèöû),
bx (íîìåð âõîäà, ñîîòâåòñòâóþùåãî ðîäèòåëüñêîé ïàïêå äëÿ òåêóùåãî
ðàññìàòðèâàåìîãî ó÷àñòêà ïóòè).
3. Â öèêëå èùåò âõîä ñ íóæíûì ðîäèòåëüñêèì ýëåìåíòîì è íóæíûì èìåíåì. Ýëåìåíòû
òàáëèöû ïóòåé óïîðÿäî÷åíû (ïîäðîáíî î ïîðÿäêå íàïèñàíî â ñïåöèôèêàöèè),
òàê ÷òî åñëè ðîäèòåëüñêèé ýëåìåíò äëÿ î÷åðåäíîãî âõîäà áîëüøå íóæíîãî,
òî íóæíîãî âõîäà â òàáëèöå íåò ñîâñåì, è â ýòîì ñëó÷àå ïðîèñõîäèò
âûõîä èç ïðîöåäóðû ñ bx=2, ax=dx=0xFFFF. Åñëè îáíàðóæèëñÿ ýëåìåíò,
ñîîòâåòñòâóþùèé î÷åðåäíîé ïàïêå â çàïðîøåííîì ïóòè, òî íà ðàññìîòðåíèå
âûíîñèòñÿ ñëåäóþùàÿ êîìïîíåíòà ïóòè. Åñëè ýòà êîìïîíåíòà ïîñëåäíÿÿ,
òî îñòàëîñü íàéòè ôàéë â ïàïêå, è êîä ïåðåõîäèò ê ïóíêòó 4,
óñòàíîâèâ eax = íà÷àëüíûé áëîê ýòîé ïàïêè. Åñëè æå íåò, òî ýòà
êîìïîíåíòà äîëæíà çàäàâàòü èìÿ ïàïêè, è êîä âîçâðàùàåòñÿ ê ïóíêòó 3,
ñêîððåêòèðîâàâ óêàçàòåëü íà èìÿ ds:si è íîìåð ðîäèòåëüñêîãî âõîäà bx.
4. (parse_dir) Íà ýòîì øàãå çàäàíû íà÷àëüíûé ëîãè÷åñêèé áëîê ïàïêè â eax
è óêàçàòåëü íà èìÿ ôàéëà îòíîñèòåëüíî ýòîé ïàïêè â ds:si. Åñëè
ïàïêó èñêàëè ïî òàáëèöå ïóòåé, òî èìÿ ôàéëà óæå íå ñîäåðæèò ïîäïàïîê;
åñëè æå íåò, òî ïîäïàïêè âïîëíå âîçìîæíû.
5. Ôàéëû â ISO-9660 ìîãóò ñîñòîÿòü èç íåñêîëüêèõ êóñêîâ (File Section), êàæäûé
èç êîòîðûõ çàäà¸òñÿ îòäåëüíûì âõîäîì â ïàïêå. Èíôîðìàöèÿ îáî âñåõ
òàêèõ êóñêàõ ïðè ïðîñìîòðå ïàïêè çàïîìèíàåòñÿ â îáëàñòè, íà÷èíàþùåéñÿ
ñ àäðåñà 0000:2000. Ïåðåìåííàÿ cur_desc_end ñîäåðæèò óêàçàòåëü íà
êîíåö ýòîé îáëàñòè, îí æå óêàçàòåëü, êóäà áóäåò ïîìåùåíà èíôîðìàöèÿ
ïðè îáíàðóæåíèè ñëåäóþùåãî âõîäà. (Ïàïêè, ñîãëàñíî ñïåöèôèêàöèè,
äîëæíû çàäàâàòüñÿ îäíèì êóñêîì.)
6. Êîä ñíà÷àëà èùåò çàïðîøåííóþ ïàïêó â êýøå ïàïîê.
7. (parse_dir.found) Åñëè ïàïêà óæå åñòü â êýøå, òî îíà óäàëÿåòñÿ èç ñïèñêà,
îòñîðòèðîâàííîãî ïî äàâíîñòè ïîñëåäíåãî îáðàùåíèÿ è êîä ïåðåõîäèò ê
ï.15. (Ñëåäóþùèì äåéñòâèåì ñòàíåò äîáàâëåíèå ïàïêè â êîíåö ñïèñêà.)
8. (parse_dir.notfound) Åñëè æå ïàïêè íåò â êýøå, òî å¸ ïðèä¸òñÿ çàãðóæàòü
ñ äèñêà. Ñíà÷àëà çàãðóæàåòñÿ ïåðâûé ñåêòîð (ôèçè÷åñêèé ñåêòîð,
ñîäåðæàùèé ïåðâûé ëîãè÷åñêèé áëîê). Ïðè îøèáêå ââîäà/âûâîäà
ïðîèñõîäèò íåìåäëåííûé âûõîä èç ïðîöåäóðû ñ bx=3, dx=ax=0xFFFF.
Ïåðâûé ýëåìåíò ïàïêè ñîäåðæèò èíôîðìàöèþ î ñàìîé ýòîé ïàïêå, êîíêðåòíî
çàãðóç÷èê èíòåðåñóåòñÿ å¸ ðàçìåðîì.
9. Åñëè ðàçìåð ïàïêè ñëèøêîì áîëüøîé (áîëüøå èëè ðàâåí 64K ëèáî áîëüøå ïîëîâèíû
îáùåãî ðàçìåðà êýøà), òî êýøèðîâàòüñÿ îíà íå áóäåò.  ýòîì ñëó÷àå êîä
ñ÷èòûâàåò ïàïêó ïîñåêòîðíî âî âðåìåííûé áóôåð (0000:1000) è ïîñåêòîðíî
ñêàíèðóåò íà íàëè÷èå çàïðîøåííîãî èìåíè, ïîêà íå íàéä¸ò òàêîãî èìåíè
èëè ïîêà íå êîí÷àòñÿ äàííûå. (Öèêë íà÷èíàåòñÿ ñî ñêàíèðîâàíèÿ,
ïîñêîëüêó ïåðâàÿ ÷àñòü äàííûõ óæå ïðî÷èòàíà.)  êîíöå êîä ïåðåõîäèò
ê ï.17.
10. (parse_dir.yescache) Åñëè ïðèíÿòî ðåøåíèå î êýøèðîâàíèè ïàïêè, òî íóæíî
îáåñïå÷èòü äîñòàòî÷íîå êîëè÷åñòâî ñâîáîäíîãî ìåñòà. Äëÿ ýòîãî ìîæåò
ïîíàäîáèòüñÿ âûêèíóòü êàêîå-òî êîëè÷åñòâî ñòàðûõ äàííûõ (öèêë
parse_dir.freeloop). Íî åñëè ïðîñòî âûêèäûâàòü, òî, âîîáùå ãîâîðÿ,
ñâîáîäíîå ïðîñòðàíñòâî îêàæåòñÿ ðàçîðâàííûì íà íåñêîëüêî ôðàãìåíòîâ.
Ïîýòîìó ïðè âûêèäûâàíèè êàêîé-òî ïàïêè èç êýøà çàãðóç÷èê ïåðåìåùàåò
âñå ñëåäóþùèå çà íåé äàííûå íàçàä ïî ïàìÿòè è ñîîòâåòñòâåííî
êîððåêòèðóåò èíôîðìàöèþ î ìåñòîíàõîæäåíèè äàííûõ â èíôîðìàöèè î êýøå.
Ïðè ýòîì íîâîå ïðîñòðàíñòâî âñåãäà äîáàâëÿåòñÿ â êîíåö äîñòóïíîé
ïàìÿòè. Öèêë âûêèäûâàíèÿ ïðîäîëæàåòñÿ, ïîêà íå îñâîáîäèòñÿ ìåñòî,
äîñòàòî÷íîå äëÿ õðàíåíèÿ ïàïêè. Èç-çà îãðàíè÷åíèé íà ðàçìåð êýøèðóåìûõ
ïàïîê â êîíöå êîíöîâ ìåñòî íàéä¸òñÿ.
11. Âûäåëÿåòñÿ íîâûé ýëåìåíò êýøà. Âñå óäàë¸ííûå íà øàãå 10 ýëåìåíòû
îðãàíèçóþòñÿ â åäèíûé ñïèñîê ñâîáîäíûõ ýëåìåíòîâ; åñëè îí íåïóñò,
òî î÷åðåäíîé ýëåìåíò áåð¸òñÿ èç ýòîãî ñïèñêà; åñëè æå ïóñò, òî
áåð¸òñÿ ñîâñåì íîâûé ýëåìåíò èç îáëàñòè ïàìÿòè, ïðåäíàçíà÷åííîé äëÿ
ýëåìåíòîâ êýøà.
12.  íîâîì ýëåìåíòå çàïîëíÿþòñÿ ïîëÿ íà÷àëüíîãî áëîêà, ñåãìåíòà ñ äàííûìè,
ðàçìåðà â áàéòàõ.
13. Óæå ïðî÷èòàííûå äàííûå ïåðâîãî ôèçè÷åñêîãî ñåêòîðà ïåðåñûëàþòñÿ íà
çàêîííîå ìåñòî â êýøå.
14. Åñëè âñå äàííûå íå èñ÷åðïûâàþòñÿ ïåðâûì ñåêòîðîì, òî äîãðóæàþòñÿ îñòàâøèåñÿ
äàííûå ñ äèñêà. Ïðè îøèáêå ÷òåíèÿ, êàê è ðàíüøå, ïðîèñõîäèò âûõîä èç
ïðîöåäóðû ñ bx=3, ax=dx=0xFFFF.
15. (parse_dir.scan) Íîâûé ýëåìåíò äîáàâëÿåòñÿ â êîíåö ñïèñêà âñåõ ýëåìåíòîâ
êýøà.
16. Çàãðóç÷èê èùåò çàïðîøåííîå èìÿ â çàãðóæåííûõ äàííûõ ïàïêè.
(Èç-çà îãðàíè÷åíèé íà ðàçìåð êýøèðóåìîé ïàïêè âñå äàííûå ðàñïîëàãàþòñÿ
â îäíîì ñåãìåíòå.)
17. (parse_dir.scandone) Åñëè â ïðîöåññå ñêàíèðîâàíèÿ ïàïêè íå áûëî íàéäåíî
íèêàêèõ êóñêîâ ôàéëà, òî cur_desc_end òàêîé æå, êàêèì áûë âíà÷àëå.
 ýòîì ñëó÷àå ïðîöåäóðà ðàïîðòóåò î íåíàéäåííîì ôàéëå è âûõîäèò.
18. (filefound) Ïðîïóñêàåò òåêóùóþ êîìïîíåíòó èìåíè. Åñëè îíà áûëà íå ïîñëåäíåé
(òî åñòü ïîäïàïêîé, â êîòîðîé íóæíî ïðîèçâîäèòü äàëüíåéøèé ïîèñê),
òî êîä ïðîâåðÿåò, ÷òî íàéäåííûé âõîä - äåéñòâèòåëüíî ïîäïàïêà,
óñòàíàâëèâàåò íîâûé ñòàðòîâûé áëîê è âîçâðàùàåòñÿ ê ï.4.
Åñëè æå ïîñëåäíåé, òî êîä ïðîâåðÿåò, ÷òî íàéäåííûé âõîä - ðåãóëÿðíûé
ôàéë è íà÷èíàåò çàãðóçêó ôàéëà.
19. Íîðìàëèçóåò óêàçàòåëü, ïî êîòîðîìó òðåáóåòñÿ ïðî÷èòàòü ôàéë. Ïîä
íîðìàëèçàöèåé ïîíèìàåòñÿ ïðåîáðàçîâàíèå òèïà
1234:FC08 -> (1234+0FC0):0008, êîòîðîå íå ìåíÿåò ñóììàðíîãî àäðåñà,
íî ãàðàíòèðóåò îòñóòñòâèå ïåðåïîëíåíèé: â ïðèâåä¸ííîì ïðèìåðå ïîïûòêà
ïåðåñëàòü 400h áàéò ïî rep movsb ïðèâåä¸ò ê òîìó, ÷òî ïîñëåäíèå 8
áàéò çàïèøóòñÿ íå â íóæíîå ìåñòî, à íà 64K ðàíüøå. Äàëåå íîðìàëèçàöèÿ
áóäåò ïðîèçâîäèòüñÿ ïîñëå êàæäîé ïåðåñûëêè. Â cur_limit ïîìåùàåò
ïðåäåëüíûé ðàçìåð äëÿ ÷òåíèÿ â áàéòàõ.
20. (loadloop) Â öèêëå ïî íàéäåííûì ôðàãìåíòàì ôàéëà çàãðóæàåò ýòè ôðàãìåíòû
(ïóíêòû 21-27).
21. Îáíóëÿåò ïåðåìåííóþ [cur_start], èìåþùóþ ñìûñë ÷èñëà áàéò, êîòîðîå
íóæíî ïðîïóñòèòü ñ íà÷àëà ôðàãìåíòà.
22. (loadloop.loadnew) Íà ýòó ìåòêó óïðàâëåíèå ìîæåò ïîïàñòü ëèáî ñ ïðåäûäóùåãî
øàãà, ëèáî íàïðÿìóþ èç callback-ïðîöåäóðû ïðè çàïðîñå íà ïðîäîëæåíèå
÷òåíèÿ. Äëÿ ýòîãî è íóæíà âûøåóïîìÿíóòàÿ ïåðåìåííàÿ [cur_start] -
ïðè ïðîäîëæåíèè ÷òåíèÿ, ïðåðâàâøåãîñÿ èç-çà êîíöà áóôåðà ïîñåðåäèíå
ôðàãìåíòà, òàì áóäåò çàïèñàíî ñîîòâåòñòâóþùåå çíà÷åíèå.
23. Îïðåäåëÿåò òåêóùóþ äëèíó (õðàíèòñÿ â esi) êàê ìèíèìóì èç äëèíû ôðàãìåíòà
è ìàêñèìàëüíîé äëèíû îñòàòêà. Åñëè âòîðîå ñòðîãî ìåíüøå, òî
çàïîìèíàåò, ÷òî ôàéë ñëèøêîì áîëüøîé è ïðî÷èòàí òîëüêî ÷àñòè÷íî.
Îïðåäåëÿåò íîâîå çíà÷åíèå ÷èñëà ïðî÷èòàííûõ áàéò âî ôðàãìåíòå
äëÿ âîçìîæíûõ áóäóùèõ âûçîâîâ [cur_start].
24. Ïåðåâîäèò ïðîïóñêàåìîå ÷èñëî áàéò â ÷èñëî ëîãè÷åñêèõ áëîêîâ è áàéò
â ïåðâîì áëîêå, ïîñëåäíåå ÷èñëî çàïèñûâàåò â ïåðåìåííóþ [first_byte],
îòêóäà å¸ ïîçäíåå äîñòàíåò read_many_bytes.with_first.
25. Åñëè ôðàãìåíò çàïèñàí â îáû÷íîì ðåæèìå (non-interleaved mode), òî êîä
îïðåäåëÿåò íà÷àëüíûé áëîê ôðàãìåíòà è âûçûâàåò âñïîìîãàòåëüíóþ ôóíêöèþ
÷òåíèÿ áëîêîâ. Ïðè îøèáêå ÷òåíèÿ óñòàíàâëèâàåò bx=3 (êîä îøèáêè ÷òåíèÿ)
è âûõîäèò èç öèêëà ê ï.28.
26. Åñëè ôðàãìåíò çàïèñàí â ÷åðåäóåìîì ðåæèìå (interleaved mode), òî ñíà÷àëà
êîä ïðîïóñêàåò íóæíîå êîëè÷åñòâî íåïðåðûâíûõ ÷àñòåé, à ïîòîì
â öèêëå çàãðóæàåò íåïðåðûâíûå ÷àñòè ñ ïîìîùüþ òîé æå ôóíêöèè,
â ïðîìåæóòêàõ ìåæäó ÷àñòÿìè óâåëè÷èâàÿ íîìåð íà÷àëüíîãî áëîêà.
Ïîêà íå êîí÷èòñÿ ôðàãìåíò èëè ïîêà íå íàáåð¸òñÿ çàïðîøåííîå ÷èñëî áàéò.
Ïðè îøèáêå ÷òåíèÿ äåëàåò òî æå ñàìîå, ÷òî è â ïðåäûäóùåì ñëó÷àå.
27. (loadloop.loadcontinue) Åñëè ôðàãìåíòû åù¸ íå êîí÷èëèñü è ïðåäåëüíûé ðàçìåð
åù¸ íå äîñòèãíóò, ïåðåõîäèò ê ñëåäóþùåìó ôðàãìåíòó è ï.20. Â ïðîòèâíîì
ñëó÷àå óñòàíàâëèâàåò bx=0 ëèáî bx=1 â çàâèñèìîñòè îò òîãî, áûëî ëè
ïåðåïîëíåíèå â ï.23.
28. (loadloop.calclen) Ïîäñ÷èòûâàåò îáùóþ äëèíó ôàéëà, ñóììèðóÿ äëèíû âñåõ
ôðàãìåíòîâ.
 
Ïðîöåäóðà ïðîâåðêè, ÿâëÿåòñÿ ëè òåêóùàÿ êîìïîíåíòà èìåíè ôàéëà ïîñëåäíåé
(is_last_component):
íà âõîäå: ds:si = óêàçàòåëü íà èìÿ
íà âûõîäå: ôëàã CF óñòàíîâëåí, åñëè åñòü ïîñëåäóþùèå êîìïîíåíòû
 öèêëå çàãðóæàåò ñèìâîëû èìåíè â ïîèñêàõ íóëåâîãî è '/'; åñëè íàø¸ëñÿ ïåðâûé,
òî âûõîäèò (ïðè ýòîì CF=0); åñëè íàø¸ëñÿ âòîðîé, òî óñòàíàâëèâàåò CF
è âûõîäèò.
 
Ïðîöåäóðû ïðîâåðêè íà ñîâïàäåíèå òåêóùåé êîìïîíåíòû èìåíè ôàéëà ñ èìåíåì
òåêóùåãî ýëåìåíòà (test_filename1 äëÿ òàáëèöû ïóòåé, test_filename2 äëÿ ïàïêè):
íà âõîäå: ds:si = óêàçàòåëü íà èìÿ, es:di = óêàçàòåëü íà ýëåìåíò
òàáëèöû ïóòåé äëÿ test_filename1, ïàïêè äëÿ test_filename2
íà âûõîäå: CF óñòàíîâëåí, åñëè èìåíà íå ñîâïàäàþò
 öèêëå ïðîâåðÿåò ñîâïàäåíèå ïðèâåä¸ííûõ ê âåðõíåìó ðåãèñòðó î÷åðåäíûõ ñèìâîëîâ
èì¸í ôàéëà è ýëåìåíòà. Óñëîâèÿ âûõîäà èç öèêëà: çàêîí÷èëîñü èìÿ ôàéëà
â ds:si (òî åñòü, î÷åðåäíîé ñèìâîë - íóëåâîé ëèáî '/') - ñîâïàäåíèå
âîçìîæíî òîëüêî â ñèòóàöèè òèïà èìåíè "filename.ext" è ýëåìåíòà
"filename.ext;1" (â ISO9660 ";1" - âåðñèÿ ôàéëà, ýëåìåíòû ñ îäèíàêîâûìè
èìåíàìè â ïàïêå îòñîðòèðîâàíû ïî óáûâàíèþ âåðñèé);
íåñîâïàäåíèå ñèìâîëîâ - îçíà÷àåò, ÷òî èìåíà íå ñîâïàäàþò;
çàêîí÷èëîñü èìÿ ýëåìåíòà - íóæíî ïðîâåðèòü, çàêîí÷èëîñü ëè ïðè ýòîì èìÿ
ôàéëà, è â çàâèñèìîñòè îò ýòîãî ïðèíèìàòü ðåøåíèå î ñîâïàäåíèè.
 
Ïðîöåäóðà ïðèâåäåíèÿ ñèìâîëà â âåðõíèé ðåãèñòð (toupper):
íà âõîäå: ASCII-ñèìâîë
íà âûõîäå: òîò æå ñèìâîë â âåðõíåì ðåãèñòðå (îí ñàì, åñëè ïîíÿòèå ðåãèñòðà ê
íåìó íåïðèìåíèìî)
Èç ñèìâîëîâ â äèàïàçîíå 'a' - 'z' âêëþ÷èòåëüíî âû÷èòàåò êîíñòàíòó 'a'-'A',
îñòàëüíûå ñèìâîëû íå òðîãàåò.
 
Ïðîöåäóðà ïîèñêà ôàéëà â äàííûõ ïàïêè (scan_for_filename_in_sector):
íà âõîäå:
ds:si = óêàçàòåëü íà èìÿ ôàéëà
es:bx = óêàçàòåëü íà íà÷àëî äàííûõ ïàïêè
es:dx = óêàçàòåëü íà êîíåö äàííûõ ïàïêè
íà âûõîäå:
CF ñáðîøåí, åñëè íàéäåí ôèíàëüíûé ôðàãìåíò ôàéëà
(è äàëüøå ñêàíèðîâàòü ïàïêó íå íóæíî)
â îáëàñòü äëÿ èíôîðìàöèè î ôðàãìåíòàõ ôàéëà çàïèñûâàåòñÿ íàéäåííîå
 öèêëå ïðîñìàòðèâàåò âñå âõîäû ïàïêè, ïðîïóñêàÿ òå, ó êîòîðûõ óñòàíîâëåí
áèò Associated (ýòî ñïåöèàëüíûå âõîäû, äîïîëíÿþùèå îñíîâíûå). Åñëè
èìÿ î÷åðåäíîãî âõîäà ñîâïàäàåò ñ èìåíåì ôàéëà, òî çàïîìèíàåò íîâûé
ôðàãìåíò. Åñëè ôðàãìåíò ôèíàëüíûé (íå óñòàíîâëåí áèò Multi-Extent),
òî êîä âûõîäèò ñ CF=0. Åñëè äîñòèãíóò êîíåö äàííûõ, òî êîä âûõîäèò
ñ CF=1. Åñëè î÷åðåäíîé âõîä íóëåâîé (ïåðâûé áàéò íàñòîÿùåãî âõîäà
ñîäåðæèò äëèíó è íå ìîæåò áûòü íóë¸ì), òî ïðîöåäóðà ïåðåõîäèò ê
ðàññìîòðåíèþ ñëåäóþùåãî ëîãè÷åñêîãî áëîêà. Ïðè ýòîì ïîòåíöèàëüíî
âîçìîæíî ïåðåïîëíåíèå ïðè äîáàâëåíèè ðàçìåðà áëîêà; ïîñêîëüêó òàêîé
ñöåíàðèé îçíà÷àåò, ÷òî ïðîöåäóðà âûçâàíà äëÿ êýøèðîâàííîé ïàïêè
ñ ðàçìåðîì ïî÷òè 64K è íà÷àëîì äàííûõ bx=0 (ýòî ñâîéñòâî âûçûâàþùåãî
êîäà), à ðàçìåð áëîêà - ñòåïåíü äâîéêè, òî ïîñëå ïåðåïîëíåíèÿ âñåãäà
bx=0, òàê ÷òî ýòî ìîæíî îáíàðóæèòü ïî âçâåä¸ííîìó ZF ïîñëå ñëîæåíèÿ;
â ýòîì ñëó÷àå òàêæå ïðîèñõîäèò âûõîä (à ïîñëå ïåðåïîëíåíèÿ CF=1).
 
Ïðîöåäóðà ïåðåâîäà ëîãè÷åñêîãî áëîêà â íîìåð ñåêòîðà:
íà âõîäå: eax = ëîãè÷åñêèé áëîê
íà âûõîäå: eax = ôèçè÷åñêèé ñåêòîð, dx = íîìåð ëîãè÷åñêîãî áëîêà â ñåêòîðå
Îñóùåñòâëÿåò îáû÷íîå äåëåíèå 32-áèòíîãî ÷èñëà íà 32-áèòíîå (÷èñëî ëîãè÷åñêèõ
áëîêîâ â ñåêòîðå, õðàíÿùååñÿ âî âíóòðåííåé ïåðåìåííîé).
 
Ïðîöåäóðà çàãðóçêè ôèçè÷åñêîãî ñåêòîðà, ñîäåðæàùåãî óêàçàííûé ëîãè÷åñêèé áëîê
(load_phys_sector_for_lb_force):
íà âõîäå: eax = ëîãè÷åñêèé áëîê;
si - èíäèêàòîð, çàäàþùèé, ñëåäóåò ëè ÷èòàòü äàííûå â ñëó÷àå,
åñëè ëîãè÷åñêèé áëîê íà÷èíàåòñÿ ñ íà÷àëà ôèçè÷åñêîãî:
si = 0 - íå íóæíî, si íåíóëåâîé - íóæíî
íà âûõîäå:
ôèçè÷åñêèé ñåêòîð çàãðóæåí ïî àäðåñó 0000:1000
si óêàçûâàåò íà äàííûå ëîãè÷åñêîãî áëîêà
CF óñòàíîâëåí ïðè îøèáêå ÷òåíèÿ
Ïðåîáðàçóåò ïðåäûäóùåé ïðîöåäóðîé íîìåð ëîãè÷åñêîãî áëîêà â íîìåð ôèçè÷åñêîãî
ñåêòîðà è íîìåð ëîãè÷åñêîãî áëîêà âíóòðè ñåêòîðà; åñëè ïîñëåäíÿÿ
âåëè÷èíà íóëåâàÿ è íèêàêèõ äåéñòâèé â ýòîì ñëó÷àå íå çàïðîøåíî (si=0),
òî íè÷åãî è íå äåëàåò; èíà÷å óñòàíàâëèâàåò si â ñîîòâåòñòâèè ñ íåé
è ÷èòàåò ñåêòîð.
 
Ïðîöåäóðû ÷òåíèÿ íóæíîãî ÷èñëà áàéò èç íåïðåðûâíîé öåïî÷êè ëîãè÷åñêèõ áëîêîâ
(read_many_bytes è read_many_bytes.with_first):
íà âõîäå:
eax = ëîãè÷åñêèé áëîê
esi = ÷èñëî áàéò äëÿ ÷òåíèÿ
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå
cur_limit = ðàçìåð áóôåðà (íå ìåíüøå esi)
íà âûõîäå:
es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå
åñëè ïðîèçîøëà îøèáêà ÷òåíèÿ, ôëàã CF óñòàíîâëåí
cur_limit ñîîòâåòñòâóþùèì îáðàçîì óìåíüøåí
Îòëè÷èå äâóõ ïðîöåäóð: âòîðàÿ äîïîëíèòåëüíî ïðèíèìàåò âî âíèìàíèå ïåðåìåííóþ
[first_byte], íà÷èíàÿ ÷òåíèå ïåðâîãî áëîêà ñî ñìåùåíèÿ [first_byte];
ñîîòâåòñòâåííî, ïåðâàÿ ÷èòàåò áëîê ñ íà÷àëà, îáíóëÿÿ [first_byte]
ïðè âõîäå.
1. Îòäåëüíî ñ÷èòûâàåò ïåðâûé ôèçè÷åñêèé ñåêòîð âî âðåìåííóþ îáëàñòü 0000:1000,
åñëè ïåðâûé ëîãè÷åñêèé áëîê íà÷èíàåòñÿ íå ñ íà÷àëà ñåêòîðà. Ïðè
îøèáêå ÷òåíèÿ âûõîäèò èç ïðîöåäóðû.
2. Ïåðåñûëàåò íóæíóþ ÷àñòü äàííûõ (âîçìîæíî, 0 áàéò), ïðî÷èòàííûõ â ï.1,
â áóôåð. Íîðìàëèçóåò óêàçàòåëü íà áóôåð.
3. Åñëè âñå íåîáõîäèìûå äàííûå óæå ïðî÷èòàíû, âûõîäèò èç ïðîöåäóðû.
4. Äàëüíåéøèå äàííûå íàõîäÿòñÿ â íåñêîëüêèõ ôèçè÷åñêèõ ñåêòîðàõ, ïðè ýòîì,
âîçìîæíî, ïîñëåäíèé ñåêòîð ñ÷èòûâàòü íóæíî íå öåëèêîì.
5. Åñëè â áóôåðå åñòü ìåñòî äëÿ ñ÷èòûâàíèÿ âñåõ ñåêòîðîâ, òî ñðàçó ÷èòàþòñÿ
âñå ñåêòîðà, ïîñëå ÷åãî óêàçàòåëü íà áóôåð íóæíûì îáðàçîì óìåíüøàåòñÿ.
6. Åñëè æå íåò, òî ñ÷èòûâàþòñÿ âñå ñåêòîðà, êðîìå ïîñëåäíåãî, ïîñëå ÷åãî
ïîñëåäíèé ñåêòîð ñ÷èòûâàåòñÿ îòäåëüíî âî âðåìåííóþ îáëàñòü, è óæå
îòòóäà íóæíàÿ ÷àñòü äàííûõ êîïèðóåòñÿ â áóôåð.
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/cdfs
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/bootsect.asm
0,0 → 1,392
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
use_lba = 0
org 0x7C00
jmp start
nop
; FAT parameters, BPB
; note: they can be changed at install, replaced with real values
; these settings are for most typical 1.44M floppies
db 'KOLIBRI ' ; BS_OEMName, ignored
dw 200h ; BPB_BytsPerSec
BPB_SecsPerClus db 1
BPB_RsvdSecCnt dw 1
BPB_NumFATs db 2
BPB_RootEntCnt dw 0xE0
dw 2880 ; BPB_TotSec16
db 0xF0 ; BPB_Media
BPB_FATSz16 dw 9
BPB_SecPerTrk dw 18
BPB_NumHeads dw 2
BPB_HiddSec dd 0
dd 0 ; BPB_TotSec32
BS_DrvNum db 0
db 0 ; BS_Reserved1
db ')' ; BS_BootSig
dd 12344321h ; BS_VolID
filename:
db 'KORD.OS ' ; BS_VolLab
db 'FAT12 ' ; BS_FilSysType
; Used memory map:
; 8000:0000 - current directory
; 9000:0000 - root directory data [cached]
start:
xor ax, ax
mov ss, ax
mov sp, 0x7C00
mov ds, ax
mov bp, sp
cld
sti
mov [bp+BS_DrvNum-0x7C00], dl
if use_lba
mov ah, 41h
mov bx, 55AAh
int 13h
mov si, aNoLBA
jc err_
cmp bx, 0AA55h
jnz err_
test cx, 1
jz err_
else
mov ah, 8
int 13h
jc @f ; on error, assume that BPB geometry is valid
mov al, dh
mov ah, 0
inc ax
mov [bp+BPB_NumHeads-0x7C00], ax
and cx, 3Fh
mov [bp+BPB_SecPerTrk-0x7C00], cx
@@:
end if
; get FAT parameters
xor bx, bx
mov al, [bp+BPB_NumFATs-0x7C00]
mov ah, 0
mul [bp+BPB_FATSz16-0x7C00]
add ax, [bp+BPB_RsvdSecCnt-0x7C00]
adc dx, bx
push dx
push ax ; root directory start = dword [bp-4]
mov cx, [bp+BPB_RootEntCnt-0x7C00]
add cx, 0xF
rcr cx, 1
shr cx, 3 ; cx = size of root directory in sectors
add ax, cx
adc dx, bx
push dx
push ax ; data start = dword [bp-8]
; load start of root directory (no more than 0x2000 bytes = 0x10 sectors)
cmp cx, 0x10
jb @f
mov cx, 0x10
@@:
mov ax, [bp-4]
mov dx, [bp-2]
push 0x9000
pop es
call read_sectors
add word [bp-4], cx ; dword [bp-4] = start of non-cached root data
adc word [bp-2], bx
; load kordldr.f12
mov si, main_loader
call lookup_in_root_dir
jc noloader
test byte [es:di+11], 10h ; directory?
jz kordldr_ok
noloader:
mov si, aLoaderNotFound
err_:
call out_string
mov si, aPressAnyKey
call out_string
xor ax, ax
int 16h
int 18h
jmp $
kordldr_ok:
mov ax, [es:di+26] ; get file cluster
mov bx, 0x7E00
xor cx, cx
mov es, cx
sub ax, 2
jc noloader
push bx ; save return address: bx = 7E00
mov cl, [bp+BPB_SecsPerClus-0x7C00]
mul cx
; fall through - 'ret' in read_sectors will return to 7E00
 
read_sectors2:
; same as read_sectors, but dx:ax is relative to start of data
add ax, [bp-8]
adc dx, [bp-6]
read_sectors:
; ss:bp = 0:7C00
; es:bx = pointer to data
; dx:ax = first sector
; cx = number of sectors
pusha
add ax, word [bp+BPB_HiddSec-0x7C00]
adc dx, word [bp+BPB_HiddSec+2-0x7C00]
if use_lba
push ds
do_read_sectors:
push ax
push cx
push dx
cmp cx, 0x7F
jbe @f
mov cx, 0x7F
@@:
; create disk address packet on the stack
; dq starting LBA
push 0
push 0
push dx
push ax
; dd buffer
push es
push bx
; dw number of blocks to transfer (no more than 0x7F)
push cx
; dw packet size in bytes
push 10h
; issue BIOS call
push ss
pop ds
mov si, sp
mov dl, [bp+BS_DrvNum-0x7C00]
mov ah, 42h
int 13h
mov si, aReadError
jc err_
; restore stack
add sp, 10h
; increase current sector & buffer; decrease number of sectors
mov si, cx
mov ax, es
shl cx, 5
add ax, cx
mov es, ax
pop dx
pop cx
pop ax
add ax, si
adc dx, 0
sub cx, si
jnz do_read_sectors
pop ds
popa
ret
else
do_read_sectors:
pusha
pop di
push bx
 
; (dword in dx:ax) / (SectorsPerTrack) -> (dword in dx:ax), remainder bx
mov si, ax
xchg ax, dx
xor dx, dx
div [bp+BPB_SecPerTrk-0x7C00]
push ax
mov ax, si
div [bp+BPB_SecPerTrk-0x7C00]
mov bx, dx ; bx=sector-1
pop dx
 
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
div [bp+BPB_NumHeads-0x7C00]
 
; number of sectors: read no more than to end of track
push bx
sub bx, [bp+BPB_SecPerTrk-0x7C00]
neg bx
cmp cx, bx
jbe @f
mov cx, bx
@@:
pop bx
 
inc bx
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
mov di, cx
mov dh, dl
mov dl, [bp+BS_DrvNum-0x7C00]
shl ah, 6
mov ch, al
mov al, cl
mov cl, bl
or cl, ah
pop bx
mov si, 3
mov ah, 2
@@:
push ax
int 13h
jnc @f
xor ax, ax
int 13h ; reset drive
pop ax
dec si
jnz @b
mov si, aReadError
jmp err_
@@:
pop ax
mov ax, es
mov cx, di
shl cx, 5
add ax, cx
mov es, ax
push di
popa
add ax, di
adc dx, 0
sub cx, di
jnz do_read_sectors
popa
ret
end if
 
scan_for_filename:
; in: ds:si -> 11-bytes FAT name
; in: es:0 -> part of directory data
; in: cx = number of entries
; out: if found: CF=0, ZF=1, es:di -> directory entry
; out: if not found, but continue required: CF=1 and ZF=0
; out: if not found and zero item reached: CF=1 and ZF=1
xor di, di
push cx
sloop:
cmp byte [es:di], 0
jz snotfound
test byte [es:di+11], 8 ; volume label?
jnz scont ; ignore volume labels
pusha
mov cx, 11
repz cmpsb
popa
jz sdone
scont:
add di, 0x20
loop sloop
inc cx ; clear ZF flag
snotfound:
stc
sdone:
pop cx
lrdret:
ret
 
lookup_in_root_dir:
; ss:bp = 0:7C00
; in: ds:si -> 11-bytes FAT name
; out: if found: CF=0, es:di -> directory entry
; out: if not found: CF=1
mov cx, [bp+BPB_RootEntCnt-0x7C00]
push cx
; first, look in root directory cache
push 0x9000
pop es
test ch, ch
jz @f
mov cx, 0x100
@@:
mov ax, [bp-4]
mov dx, [bp-2] ; dx:ax = starting sector of not cached data of root directory
lrdloop:
call scan_for_filename
pop bx
jz lrdret
sub bx, cx
mov cx, bx
stc
jz lrdret
; read no more than 0x10000 bytes, or 0x10000/0x20 = 0x800 entries
push cx
cmp ch, 0x8
jb @f
mov cx, 0x800
@@:
push 0x8000
pop es
push cx
push es
xor bx, bx
add cx, 0xF
shr cx, 4
call read_sectors
pop es
add ax, cx
adc dx, bx
pop cx
jmp lrdloop
 
out_string:
; in: ds:si -> ASCIIZ string
lodsb
test al, al
jz lrdret
mov ah, 0Eh
mov bx, 7
int 10h
jmp out_string
 
aReadError db 'Read error',0
if use_lba
aNoLBA db 'The drive does not support LBA!',0
end if
aLoaderNotFound db 'Loader not found',0
aPressAnyKey db 13,10,'Press any key...',13,10,0
main_loader db 'KORDLDR F1X'
 
if use_lba
db 0 ; make bootsector 512 bytes in length
end if
 
; bootsector signature
dw 0xAA55
 
; display offsets of all procedures used by kordldr.f12.asm
macro show [procedure]
{
bits = 16
display `procedure,' = '
repeat bits/4
d = '0' + procedure shr (bits - %*4) and 0Fh
if d > '9'
d = d + 'A'-'9'-1
end if
display d
end repeat
display 13,10
}
 
show read_sectors, read_sectors2, lookup_in_root_dir, scan_for_filename, err_, noloader
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/build.bat
0,0 → 1,3
@fasm -m 65535 bootsect.asm bootsect.bin
@fasm -m 65535 kordldr.f1x.asm kordldr.f1x
@pause
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/kordldr.f1x.asm
0,0 → 1,667
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
org 0x7E00
; the KordOS FAT12/FAT16 bootsector loads first cluster of this file to 0:7E00 and transfers control to here
; ss:bp = 0:7C00
virtual at bp
rb 3 ; BS_jmpBoot
rb 8 ; BS_OEMName, ignored
dw ? ; BPB_BytsPerSec
BPB_SecsPerClus db ?
BPB_RsvdSecCnt dw ?
BPB_NumFATs db ?
BPB_RootEntCnt dw ?
BPB_TotSec16 dw ?
db ? ; BPB_Media
BPB_FATSz16 dw ?
BPB_SecPerTrk dw ?
BPB_NumHeads dw ?
BPB_HiddSec dd ?
BPB_TotSec32 dd ?
BS_DrvNum db ?
fat_type db ? ; this is BS_Reserved1,
; we use it to save FS type: 0=FAT12, 1=FAT16
db ? ; BS_BootSig
num_sectors dd ? ; BS_VolID
; rb 11 ; BS_VolLab
; rb 3 ; BS_FilSysType, first 3 bytes
read_sectors dw ?
read_sectors2 dw ?
lookup_in_root_dir dw ?
scan_for_filename dw ?
err_ dw ?
noloader dw ?
cachelimit dw ?
filesize: ; will be used to save file size
rb 5 ; BS_FilSysType, last 5 bytes
; following variables are located in the place of starting code;
; starting code is no more used at this point
sect_per_clus dw ?
cur_cluster dw ?
next_cluster dw ?
flags dw ?
cur_delta dd ?
end virtual
 
; procedures from boot sector
; LBA version
lba_read_sectors = 7CE2h
lba_read_sectors2 = 7CDCh
lba_lookup_in_root_dir = 7D4Fh
lba_scan_for_filename = 7D2Dh
lba_err = 7CB5h
lba_noloader = 7CB2h
; CHS version
chs_read_sectors = 7CDEh
chs_read_sectors2 = 7CD8h
chs_lookup_in_root_dir = 7D70h
chs_scan_for_filename = 7D4Eh
chs_err = 7CB1h
chs_noloader = 7CAEh
 
push ax cx ; save our position on disk
push ss
pop es
; determine version of bootsector (LBA vs CHS)
; mov [read_sectors], chs_read_sectors
; mov [read_sectors2], chs_read_sectors2
; mov [lookup_in_root_dir], chs_lookup_in_root_dir
; mov [scan_for_filename], chs_scan_for_filename
; mov [err], chs_err
; mov [noloader], chs_noloader
lea di, [read_sectors]
mov si, chs_proc_addresses
mov cx, 6*2
cmp word [chs_scan_for_filename], 0xFF31 ; 'xor di,di'
jz @f
add si, cx
; mov [read_sectors], lba_read_sectors
; mov [read_sectors2], lba_read_sectors2
; mov [lookup_in_root_dir], lba_lookup_in_root_dir
; mov [scan_for_filename], lba_scan_for_filename
; mov [err], lba_err
; mov [noloader], lba_noloader
@@:
rep movsb
mov cl, [BPB_SecsPerClus]
mov [sect_per_clus], cx
xor bx, bx
; determine size of cache for folders
int 12h ; ax = size of available base memory in Kb
sub ax, 94000h / 1024
jae @f
nomem:
mov si, nomem_str
jmp [err_]
@@:
shr ax, 3
mov [cachelimit], ax ; size of cache - 1
; get type of file system - FAT12 or FAT16?
; calculate number of clusters
mov ax, [BPB_TotSec16]
xor dx, dx
test ax, ax
jnz @f
mov ax, word [BPB_TotSec32]
mov dx, word [BPB_TotSec32+2]
@@:
sub ax, [bp-8] ; dword [bp-8] = first data sector
sbb dx, [bp-6]
jb j_noloader
div [sect_per_clus]
; ax = number of clusters
; note: this is loader for FAT12/FAT16, so 'div' does not overflow on correct volumes
mov [fat_type], ch
cmp ax, 0xFF5
jb init_fat12
inc [fat_type]
init_fat16:
; no sectors loaded
mov di, 0x8200
xor ax, ax
mov cx, 0x100/2
rep stosw
jmp init_fat_done
init_fat12:
; read FAT
push 0x6000
pop es
mov ax, [BPB_RsvdSecCnt]
mov cx, [BPB_FATSz16]
cmp cx, 12
jb @f
mov cx, 12
@@:
xor dx, dx
call [read_sectors]
init_fat_done:
; if cluster = sector, we need to read second part of our file
; (bootsector loads only first cluster of kordldr.f1x)
pop cx ax ; restore our position on disk
cmp cx, 1
ja kordldr_full
sub ax, [bp-8]
inc ax
inc ax ; ax = first cluster of kordldr.f12
call get_next_cluster
jc @f
j_noloader:
jmp [noloader]
@@:
dec ax
dec ax
push 0x800
pop es
call [read_sectors2]
kordldr_full:
; ...continue loading...
mov di, secondary_loader_info
call load_file
test bx, bx
mov bx, [err_]
jz @f
mov si, aKernelNotFound
jmp bx
@@:
; for subsequent calls to callback function, hook error handler
; mov byte [bx], 0xE9 ; 'jmp' opcode
; mov ax, hooked_err - 3
; sub ax, bx
; mov word [bx+1], ax
; push hooked_err / ret
mov word [bx], 0x68 + ((hooked_err and 0xFF) shl 8)
mov word [bx+2], (hooked_err shr 8) + (0xC3 shl 8)
; set registers for secondary loader
mov ah, [BS_DrvNum]
mov al, 'f'
test ah, ah
jns @f
sub ah, 80h
mov al, 'h'
@@:
mov bx, '12'
cmp [fat_type], 0
jz @f
mov bh, '6'
@@:
mov si, callback ; ds:si = far pointer to callback procedure
jmp far [si-callback+secondary_loader_info] ; jump to 1000:0000
 
nomem_str db 'No memory',0
 
chs_proc_addresses:
dw chs_read_sectors
dw chs_read_sectors2
dw chs_lookup_in_root_dir
dw chs_scan_for_filename
dw chs_err
dw chs_noloader
lba_proc_addresses:
dw lba_read_sectors
dw lba_read_sectors2
dw lba_lookup_in_root_dir
dw lba_scan_for_filename
dw lba_err
dw lba_noloader
 
get_next_cluster:
; in: ax = cluster
; out: if there is next cluster: CF=1, ax = next cluster
; out: if there is no next cluster: CF=0
push si
cmp [fat_type], 0
jnz gnc16
; for FAT12
push ds
push 0x6000
pop ds
mov si, ax
shr si, 1
add si, ax
test al, 1
lodsw
jz @f
shr ax, 4
@@:
and ax, 0xFFF
cmp ax, 0xFF7
pop ds si
ret
; for FAT16
gnc16:
; each sector contains 200h bytes = 100h FAT entries
; so ah = # of sector, al = offset in sector
mov si, ax
mov ah, 0
shr si, 8
; calculate segment for this sector of FAT table
; base for FAT table is 6000:0000, so the sector #si has to be loaded to (60000 + 200*si)
; segment = 6000 + 20*si, offset = 0
push es
push si
shl si, 5
add si, 0x6000
mov es, si
pop si
cmp byte [ss:0x8200+si], ah ; sector already loaded?
jnz @f
; load corresponding sector
pusha
push es
xor bx, bx
mov ax, [BPB_RsvdSecCnt]
xor dx, dx
add ax, si
adc dx, bx
mov cx, 1 ; read 1 sector
call [read_sectors]
pop es
popa
@@:
mov si, ax
add si, si
; mov ax, [es:si]
lods word [es:si]
pop es
cmp ax, 0xFFF7
pop si
ret
 
if $ > 0x8000
error 'get_next_cluster must fit in first sector of kordldr.f1x!'
end if
 
load_file:
; in: ss:bp = 0:7C00
; in: ds:di -> information structure
; dw:dw address
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
; ASCIIZ name
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found
; out: dx:ax = file size (0xFFFFFFFF if file not found)
xor ax, ax ; start from root directory
mov dx, -1
mov word [filesize], dx
mov word [filesize+2], dx ; initialize file size with invalid value
lea si, [di+6]
parse_dir_loop:
; convert name to FAT name
push di
push ax
push ss
pop es
; convert ASCIIZ filename to FAT name
mov di, filename
push di
mov cx, 8+3
mov al, ' '
rep stosb
pop di
mov cl, 8 ; 8 symbols per name
mov bl, 1
nameloop:
lodsb
test al, al
jz namedone
cmp al, '/'
jz namedone
cmp al, '.'
jz namedot
dec cx
js badname
cmp al, 'a'
jb @f
cmp al, 'z'
ja @f
sub al, 'a'-'A'
@@:
stosb
jmp nameloop
namedot:
inc bx
jp badname
add di, cx
mov cl, 3
jmp nameloop
badname: ; do not make direct js/jp to notfound_pop:
; this generates long forms of conditional jumps and results in longer code
jmp notfound_pop
namedone:
; scan directory
pop ax ; ax = cluster of directory or 0 for root
push ds
push si
push es
pop ds
mov si, filename ; ds:si -> filename in FAT style
test ax, ax
jnz lookup_in_notroot_dir
; for root directory, use the subroutine from bootsector
call [lookup_in_root_dir]
jmp lookup_done
lookup_in_notroot_dir:
; for other directories, read a folder sector-by-sector and scan
; first, try to use the cache
push ds
push cs
pop ds
mov bx, [cachelimit]
add bx, bx
mov di, foldcache_mark
@@:
mov dx, [foldcache_clus+di-foldcache_mark+bx]
cmp dx, ax
jz cacheok
test dx, dx
jz cacheadd ; the cache has place for new entry
dec bx
dec bx
jns @b
; the folder is not present in the cache, so add it
; the cache is full; find the oldest entry and replace it with the new one
mov dx, [cachelimit]
@@:
inc bx
inc bx
cmp word [di+bx], dx ; marks have values 0 through [cachelimit]
jnz @b
cacheadd:
or word [di+bx], 0xFFFF ; very big value, it will be changed soon
mov [foldcache_clus+di-foldcache_mark+bx], ax
and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet
cacheok:
; update cache marks
mov dx, [di+bx]
mov cx, [foldcache_size+di-foldcache_mark+bx]
mov di, [cachelimit]
add di, di
cacheupdate:
cmp [foldcache_mark+di], dx
adc [foldcache_mark+di], 0
dec di
dec di
jns cacheupdate
and [foldcache_mark+bx], 0
; done, bx contains (position in cache)*2
pop ds
; mov dx, bx
; shl dx, 8 ; dx = (position in cache)*0x2000/0x10
; add dx, 0x9200
lea dx, [bx+0x92]
xchg dl, dh
mov es, dx
jcxz not_in_cache
call [scan_for_filename]
jz lookup_done
not_in_cache:
; cache miss, read folder data from disk
mov bx, cx
shr bx, 4
shl cx, 5
mov di, cx ; es:di -> free space in cache entry
; external loop: scan clusters
folder_next_cluster:
; internal loop: scan sectors in cluster
mov cx, [sect_per_clus]
push ax
dec ax
dec ax
mul cx
add ax, [bp-8]
adc dx, [bp-6] ; dx:ax = absolute sector
folder_next_sector:
; skip first bx sectors
dec bx
jns folder_skip_sector
push cx
push es di
push 0x8000
pop es
xor bx, bx
mov cx, 1
push es
call [read_sectors]
; copy data to the cache...
pop ds
pop di es
cmp di, 0x2000 ; ...if there is free space, of course
jae @f
push si di
mov cx, 0x100
xor si, si
rep movsw
mov di, es
shr di, 8
add [ss:foldcache_size+di-0x92], 0x10 ; 0x10 new entries in the cache
pop di si
@@:
push es
push 0x8000
pop es
push cs
pop ds
mov cx, 0x10
call [scan_for_filename]
pop es
pop cx
jz lookup_done_pop
folder_skip_sector:
inc ax
jnz @f
inc dx
@@:
loop folder_next_sector
pop ax ; ax = current cluster
call get_next_cluster
jc folder_next_cluster
stc
push ax
lookup_done_pop:
pop ax
lookup_done:
pop si
pop ds
; CF=1 <=> failed
jnc found
notfound:
pop di
mov bx, 2 ; file not found
mov ax, 0xFFFF
mov dx, ax ; invalid file size
ret
notfound_pop:
pop ax
jmp notfound
found:
mov ax, [es:di+26] ; get cluster
test byte [es:di+11], 10h ; directory?
jz regular_file
cmp byte [si-1], 0
jz notfound ; don't read directories as a regular files
; ok, we have found a directory and the caller requested a file into it
pop di
jmp parse_dir_loop ; restart with new cluster in ax
regular_file:
cmp byte [si-1], 0
jnz notfound ; file does not contain another files
; ok, we have found a regular file and the caller requested it
; save file size
mov dx, [es:di+28]
mov [filesize], dx
mov dx, [es:di+30]
mov [filesize+2], dx
pop di
mov si, [di+4]
shl si, 3
push si ; [ds:di+4] = limit in 4K blocks
les bx, [di] ; es:bx -> buffer
clusloop:
; ax = first cluster, top of stack contains limit in sectors
mov si, ax ; remember current cluster
xor cx, cx ; cx will contain number of consecutive clusters
mov word [cur_delta], cx
mov word [cur_delta+2], cx
mov di, ax
clusfind:
inc di
inc cx
call get_next_cluster
jnc clusread
cmp ax, di
jz clusfind
stc
clusread:
pop di ; limit in sectors
push ax ; save next cluster
pushf ; save flags
; read cx clusters, starting from si
; calculate number of sectors
xchg ax, cx
mul [sect_per_clus]
; dx:ax = number of sectors; compare with limit
mov word [num_sectors], ax
mov word [num_sectors+2], dx
jmp @f
continue_load_file:
les bx, [di] ; es:bx -> buffer
mov di, [di+4] ; ds:di = limit in 4K blocks
shl di, 3 ; now di = limit in sectors
mov ax, word [num_sectors]
mov dx, word [num_sectors+2]
mov si, [cur_cluster]
push [next_cluster]
push [flags]
or ax, dx
jz nextclus
@@:
test dx, dx
jnz clusdecrease
push dx ; limit was not exceeded
cmp ax, di
jbe @f
pop ax
clusdecrease:
push 1 ; limit was exceeded
mov ax, di
@@:
sub di, ax ; calculate new limit
sub word [num_sectors], ax
sbb word [num_sectors+2], 0
; calculate starting sector
xchg ax, cx
lea ax, [si-2]
mul [sect_per_clus]
add ax, word [cur_delta]
adc dx, word [cur_delta+2]
add word [cur_delta], cx
adc word [cur_delta+2], 0
; read
call [read_sectors2]
pop dx
; next cluster?
nextclus:
popf
pop ax
mov [cur_cluster], si
mov [next_cluster], ax
pushf
pop [flags]
jnc @f ; no next cluster => return
mov dl, 1 ; dh=0 in any case
test di, di
jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded
push di
jmp clusloop ; all is ok, continue
hooked_err:
mov sp, 7C00h-12-2 ; restore stack
mov dx, 3 ; return: read error
@@:
mov bx, dx
mov ax, [filesize]
mov dx, [filesize+2]
ret
 
; Callback function for secondary loader
callback:
; in: ax = function number; only functions 1 and 2 are defined for now
; save caller's stack
mov dx, ss
mov cx, sp
; set our stack (required because we need ss=0)
xor si, si
mov ss, si
mov sp, 7C00h-8
mov bp, 7C00h
push dx
push cx
; call our function
stc ; unsupported function
dec ax
jz callback_readfile
dec ax
jnz callback_ret
; function 2: continue loading file
; can be called only after function 1 returned value bx=1 (only part of file was loaded)
; in: ds:di -> information structure
; dw:dw address
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error
; out: dx:ax = file size
call continue_load_file
jmp callback_ret_succ
callback_readfile:
; function 1: read file
; in: ds:di -> information structure
; dw:dw address
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
; ASCIIZ name
; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error
; out: dx:ax = file size (0xFFFFFFFF if file was not found)
call load_file
callback_ret_succ:
clc ; function is supported
callback_ret:
; restore caller's stack
pop cx
pop ss
mov sp, cx
; return to caller
retf
 
secondary_loader_info:
dw 0, 0x1000
dw 0x30000 / 0x1000
db 'kord/loader',0
aKernelNotFound db 'Fatal error: cannot load the secondary loader',0
 
foldcache_clus dw 0,0,0,0,0,0,0 ; start with no folders in cache
foldcache_mark rw 7
foldcache_size rw 7
filename rb 11
if $ > 0x8200
error: table overwritten
end if
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x/bootsect.txt
0,0 → 1,360
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
Âñòðå÷àþòñÿ âèðóñ è FAT.
- Ïðèâåò, òû êòî?
- ß? Âèðóñ.
- A ÿ AFT, òî åñòü TAF, òî åñòü FTA, ÷åðò, ñîâñåì çàïóòàëñÿ...
 
Áóòñåêòîð äëÿ FAT12/FAT16-òîìà íà íîñèòåëå ñ ðàçìåðîì ñåêòîðà 0x200 = 512 áàéò.
 
=====================================================================
 
Åñòü äâå âåðñèè â çàâèñèìîñòè îò òîãî, ïîääåðæèâàåò ëè íîñèòåëü LBA,
âûáîð îñóùåñòâëÿåòñÿ óñòàíîâêîé êîíñòàíòû use_lba â ïåðâîé ñòðîêå èñõîäíèêà.
Òðåáîâàíèÿ äëÿ ðàáîòû:
1) Ñàì áóòñåêòîð, ïåðâàÿ êîïèÿ FAT è âñå èñïîëüçóåìûå ôàéëû
äîëæíû áûòü ÷èòàáåëüíû.
2) Ìèíèìàëüíûé ïðîöåññîð - 80186.
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 592K ñâîáîäíîé áàçîâîé ïàìÿòè.
 
=====================================================================
 
Äîêóìåíòàöèÿ â òåìó (ññûëêè âàëèäíû íà ìîìåíò íàïèñàíèÿ ýòîãî ôàéëà, 15.05.2008):
îôèöèàëüíàÿ ñïåöèôèêàöèÿ FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
â ôîðìàòå PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf
ðóññêèé ïåðåâîä: http://wasm.ru/docs/11/fatgen103-rus.zip
îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
 
=====================================================================
 
Ìàêñèìàëüíîå êîëè÷åñòâî êëàñòåðîâ íà FAT12-òîìå - 0xFF4 = 4084; êàæäûé êëàñòåð
çàíèìàåò 12 áèò â òàáëèöå FAT, òàê ÷òî îáùèé ðàçìåð íå ïðåâîñõîäèò
0x17EE = 6126 áàéò. Âñÿ òàáëèöà ïîìåùàåòñÿ â ïàìÿòè.
Ìàêñèìàëüíîå êîëè÷åñòâî êëàñòåðîâ íà FAT16-òîìå - 0xFFF4 = 65524; êàæäûé
êëàñòåð çàíèìàåò 16 áèò â òàáëèöå FAT, òàê ÷òî îáùèé ðàçìåð íå ïðåâîñõîäèò
0x1FFE8 = 131048 áàéò. Âñÿ òàáëèöà òàêæå ïîìåùàåòñÿ â ïàìÿòè, îäíàêî â
ýòîì ñëó÷àå íåñêîëüêî íåöåëåñîîáðàçíî ñ÷èòûâàòü âñþ òàáëèöó, ïîñêîëüêó
íà ïðàêòèêå íóæíà òîëüêî íåáîëüøàÿ å¸ ÷àñòü. Ïîýòîìó ìåñòî â ïàìÿòè
ðåçåðâèðóåòñÿ, íî äàííûå ñ÷èòûâàþòñÿ òîëüêî â ìîìåíò, êîãäà ê íèì
äåéñòâèòåëüíî èä¸ò îáðàùåíèå.
 
Ñõåìà èñïîëüçóåìîé ïàìÿòè:
...-7C00 ñòåê
7C00-7E00 êîä áóòñåêòîðà
7E00-8200 âñïîìîãàòåëüíûé ôàéë çàãðóç÷èêà (kordldr.f1x)
8200-8300 ñïèñîê çàãðóæåííûõ ñåêòîðîâ òàáëèöû FAT16
(1 = ñîîòâåòñòâóþùèé ñåêòîð çàãðóæåí)
60000-80000 çàãðóæåííàÿ òàáëèöà FAT12 / ìåñòî äëÿ òàáëèöû FAT16
80000-90000 òåêóùèé êëàñòåð òåêóùåé ðàññìàòðèâàåìîé ïàïêè
90000-92000 êýø äëÿ êîðíåâîé ïàïêè
92000-... êýø äëÿ íåêîðíåâûõ ïàïîê (êàæäîé ïàïêå îòâîäèòñÿ
2000h áàéò = 100h âõîäîâ, îäíîâðåìåííî â êýøå
ìîæåò íàõîäèòüñÿ íå áîëåå 7 ïàïîê;
òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé
ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî
ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area)
 
=====================================================================
 
Îñíîâíîé ïðîöåññ çàãðóçêè.
Òî÷êà âõîäà (start): ïîëó÷àåò óïðàâëåíèå îò BIOS ïðè çàãðóçêå, ïðè ýòîì
dl ñîäåðæèò èäåíòèôèêàòîð äèñêà, ñ êîòîðîãî èä¸ò çàãðóçêà
1. Íàñòðàèâàåò ñòåê ss:sp = 0:7C00 (ñòåê ðàñïîëàãàåòñÿ íåïîñðåäñòâåííî ïåðåä
êîäîì), ñåãìåíò äàííûõ ds = 0, è óñòàíàâëèâàåò ss:bp íà íà÷àëî
áóòñåêòîðà (â äàëüíåéøåì äàííûå áóäóò àäðåñîâàòüñÿ ÷åðåç [bp+N] -
ýòî îñâîáîæäàåò ds è ýêîíîìèò íà ðàçìåðå êîäà).
2. LBA-âåðñèÿ: ïðîâåðÿåò, ïîääåðæèâàåò ëè íîñèòåëü LBA, âûçîâîì ôóíêöèè 41h
ïðåðûâàíèÿ 13h. Åñëè íåò, ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ
ñîîáùåíèåì îá îòñóòñòâèè LBA.
CHS-âåðñèÿ: îïðåäåëÿåò ãåîìåòðèþ íîñèòåëÿ âûçîâîì ôóíêöèè 8 ïðåðûâàíèÿ 13h è
çàïèñûâàåò ïîëó÷åííûå äàííûå ïîâåðõ BPB. Åñëè âûçîâ çàâåðøèëñÿ îøèáêîé,
ïðåäïîëàãàåò óæå ñóùåñòâóþùèå äàííûå êîððåêòíûìè.
3. Âû÷èñëÿåò íåêîòîðûå ïàðàìåòðû FAT-òîìà: íà÷àëüíûé ñåêòîð êîðíåâîé ïàïêè
è íà÷àëüíûé ñåêòîð äàííûõ. Êëàä¸ò èõ â ñòåê; âïîñëåäñòâèè îíè
âñåãäà áóäóò ëåæàòü â ñòåêå è àäðåñîâàòüñÿ ÷åðåç bp.
4. Ñ÷èòûâàåò íà÷àëî êîðíåâîé ïàïêè ïî àäðåñó 9000:0000. ×èñëî ñ÷èòûâàåìûõ
ñåêòîðîâ - ìèíèìóì èç ðàçìåðà êîðíåâîé ïàïêè, óêàçàííîãî â BPB, è 16
(ðàçìåð êýøà äëÿ êîðíåâîé ïàïêè - 2000h áàéò = 16 ñåêòîðîâ).
5. Èùåò â êîðíåâîé ïàïêå ýëåìåíò kordldr.f1x. Åñëè íå íàõîäèò, èëè åñëè
îí îêàçûâàåòñÿ ïàïêîé, èëè åñëè ôàéë èìååò íóëåâóþ äëèíó -
ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì î
íåíàéäåííîì çàãðóç÷èêå.
Çàìå÷àíèå: íà ýòîì ýòàïå çàãðóçêè èñêàòü ìîæíî òîëüêî â êîðíåâîé
ïàïêå è òîëüêî èìåíà, çàäàííûå â ôîðìàòå ôàéëîâîé ñèñòåìå FAT
(8+3 - 8 áàéò íà èìÿ, 3 áàéòà íà ðàñøèðåíèå, âñå áóêâû äîëæíû
áûòü çàãëàâíûìè, ïðè íåîáõîäèìîñòè èìÿ è ðàñøèðåíèå äîïîëíÿþòñÿ
ïðîáåëàìè, ðàçäåëÿþùåé òî÷êè íåò, çàâåðøàþùåãî íóëÿ íåò).
6. Çàãðóæàåò ïåðâûé êëàñòåð ôàéëà kordldr.f1x ïî àäðåñó 0:7E00 è ïåðåäà¸ò
åìó óïðàâëåíèå. Ïðè ýòîì â ðåãèñòðàõ dx:ax îêàçûâàåòñÿ àáñîëþòíûé
íîìåð ïåðâîãî ñåêòîðà kordldr.f1x, à â cx - ÷èñëî ñ÷èòàííûõ ñåêòîðîâ
(ðàâíîå ðàçìåðó êëàñòåðà).
 
Âñïîìîãàòåëüíûå ïðîöåäóðû áóòñåêòîðà.
Êîä îáðàáîòêè îøèáîê (err):
1. Âûâîäèò ñòðîêó ñ ñîîáùåíèåì îá îøèáêå.
2. Âûâîäèò ñòðîêó "Press any key...".
3. Æä¸ò íàæàòèÿ any key.
4. Âûçûâàåò int 18h, äàâàÿ øàíñ BIOSó ïîïûòàòüñÿ çàãðóçèòüñÿ îòêóäà-íèáóäü åù¸.
5. Äëÿ ïîäñòðàõîâêè çàöèêëèâàåòñÿ.
 
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read_sectors è read_sectors2):
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
ss:bp = 0:7C00
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå
dx:ax = ñòàðòîâûé ñåêòîð (îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà
äëÿ read_sectors, îòíîñèòåëüíî íà÷àëà äàííûõ äëÿ read_sectors2)
cx = ÷èñëî ñåêòîðîâ (äîëæíî áûòü áîëüøå íóëÿ)
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå
0. Åñëè âûçûâàåòñÿ read_sectors2, îíà ïåðåâîäèò óêàçàííûé åé íîìåð ñåêòîðà
â íîìåð îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà, ïðèáàâëÿÿ íîìåð ñåêòîðà
íà÷àëà äàííûõ, õðàíÿùèéñÿ â ñòåêå êàê [bp-8].
1. Ïåðåâîäèò ñòàðòîâûé ñåêòîð (îòñ÷èòûâàåìûé îò íà÷àëà òîìà) â ñåêòîð íà
óñòðîéñòâå, ïðèáàâëÿÿ çíà÷åíèå ñîîòâåòñòâóþùåãî ïîëÿ èç BPB.
2.  öèêëå (øàãè 3-6) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè
CHS-âåðñèÿ: âñå ÷èòàåìûå ñåêòîðû áûëè íà îäíîé äîðîæêå.
LBA-âåðñèÿ: ÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå
ñïåöèôèêàöèè EDD BIOS).
CHS-âåðñèÿ:
3. Ïåðåâîäèò àáñîëþòíûé íîìåð ñåêòîðà â CHS-ñèñòåìó: ñåêòîð ðàññ÷èòûâàåòñÿ êàê
åäèíèöà ïëþñ îñòàòîê îò äåëåíèÿ àáñîëþòíîãî íîìåðà íà ÷èñëî ñåêòîðîâ
íà äîðîæêå; äîðîæêà ðàññ÷èòûâàåòñÿ êàê îñòàòîê îò äåëåíèÿ ÷àñòíîãî,
ïîëó÷åííîãî íà ïðåäûäóùåì øàãå, íà ÷èñëî äîðîæåê, à öèëèíäð - êàê
÷àñòíîå îò ýòîãî æå äåëåíèÿ. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå,
÷åì ÷èñëî ñåêòîðîâ äî êîíöà äîðîæêè, óìåíüøàåò ÷èñëî ñåêòîðîâ äëÿ
÷òåíèÿ.
4. Ôîðìèðóåò äàííûå äëÿ âûçîâà int 13h (ah=2 - ÷òåíèå, al=÷èñëî ñåêòîðîâ,
dh=ãîëîâêà, (ìëàäøèå 6 áèò cl)=ñåêòîð,
(ñòàðøèå 2 áèòà cl è âåñü ch)=äîðîæêà, dl=äèñê, es:bx->áóôåð).
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, âûïîëíÿåò ñáðîñ äèñêà
è ïîâòîðÿåò ïîïûòêó ÷òåíèÿ, âñåãî äåëàåòñÿ íå áîëåå òð¸õ ïîïûòîê
(íåñêîëüêî ïîïûòîê íóæíî â ñëó÷àå äèñêåòû äëÿ ãàðàíòèè òîãî, ÷òî
ìîòîð ðàñêðóòèëñÿ). Åñëè âñå òðè ðàçà ïðîèñõîäèò îøèáêà ÷òåíèÿ,
ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì "Read error".
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3.
LBA-âåðñèÿ:
3. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé
èòåðàöèè) äî 7Fh.
4. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè
push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â
ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà
êëàëè).
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, ïåðåõîäèò íà êîä îáðàáîòêè
îøèáîê ñ ñîîáùåíèåì "Read error". Î÷èùàåò ñòåê îò ïàêåòà,
ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå.
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3.
 
Ïðîöåäóðà ïîèñêà ýëåìåíòà ïî èìåíè â óæå ïðî÷èòàííûõ äàííûõ ïàïêè
(scan_for_filename):
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
ds:si = óêàçàòåëü íà èìÿ ôàéëà â ôîðìàòå FAT (11 áàéò, 8 íà èìÿ,
3 íà ðàñøèðåíèå, âñå áóêâû çàãëàâíûå, åñëè èìÿ/ðàñøèðåíèå
êîðî÷å, îíî äîïîëíÿåòñÿ äî ìàêñèìóìà ïðîáåëàìè)
es = ñåãìåíò äàííûõ ïàïêè
cx = ÷èñëî ýëåìåíòîâ â ïðî÷èòàííûõ äàííûõ
íà âûõîäå: ZF îïðåäåëÿåò, íóæíî ëè ïðîäîëæàòü ðàçáîð äàííûõ ïàïêè
(ZF=1, åñëè ëèáî íàéäåí çàïðîøåííûé ýëåìåíò, ëèáî äîñòèãíóò
êîíåö ïàïêè); CF îïðåäåëÿåò, óäàëîñü ëè íàéòè ýëåìåíò ñ èñêîìûì èìåíåì
(CF=1, åñëè íå óäàëîñü); åñëè óäàëîñü, òî es:di óêàçûâàåò íà íåãî.
scan_for_filename ñ÷èòàåò, ÷òî äàííûå ïàïêè ðàçìåùàþòñÿ íà÷èíàÿ ñ es:0.
Ïåðâîé êîìàíäîé ïðîöåäóðà îáíóëÿåò di. Çàòåì ïðîñòî â öèêëå ïî ýëåìåíòàì ïàïêè
ïðîâåðÿåò èìåíà.
 
Ïðîöåäóðà ïîèñêà ýëåìåíòà â êîðíåâîé ïàïêå (lookup_in_root_dir):
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
ss:bp = 0:7C00
ds:si = óêàçàòåëü íà èìÿ ôàéëà â ôîðìàòå FAT (ñì. âûøå)
íà âûõîäå: ôëàã CF îïðåäåëÿåò, óäàëîñü ëè íàéòè ôàéë; åñëè óäàëîñü, òî
CF ñáðîøåí è es:di óêàçûâàåò íà ýëåìåíò ïàïêè
Íà÷èíàåò ñ ïðîñìîòðà êýøèðîâàííîé (íà÷àëüíîé) ÷àñòè êîðíåâîé ïàïêè.  öèêëå
ñêàíèðóåò ýëåìåíòû; åñëè ïî ðåçóëüòàòàì ñêàíèðîâàíèÿ îáíàðóæèâàåò,
÷òî íóæíî ÷èòàòü ïàïêó äàëüøå, òî ñ÷èòûâàåò íå áîëåå 0x10000 = 64K
áàéò (îãðàíè÷åíèå ââåäåíî ïî äâóì ïðè÷èíàì: âî-ïåðâûõ, ÷òîáû çàâåäîìî
íå âûëåçòè çà ïðåäåëû èñïîëüçóåìîé ïàìÿòè, âî-âòîðûõ, ñêàíèðîâàíèå
ïðåäïîëàãàåò, ÷òî âñå îáðàáàòûâàåìûå ýëåìåíòû ðàñïîëàãàþòñÿ â îäíîì
ñåãìåíòå) è ïðîäîëæàåò öèêë.
Ñêàíèðîâàíèå ïðåêðàùàåòñÿ â òð¸õ ñëó÷àÿõ: îáíàðóæåí èñêîìûé ýëåìåíò;
êîí÷èëèñü ýëåìåíòû â ïàïêå (ñóäÿ ïî ÷èñëó ýëåìåíòîâ, óêàçàííîìó â BPB);
î÷åðåäíîé ýëåìåíò ïàïêè ñèãíàëèçèðóåò î êîíöå (ïåðâûé áàéò íóëåâîé).
 
Ïðîöåäóðà âûâîäà íà ýêðàí ASCIIZ-ñòðîêè (out_string):
íà âõîäå: ds:si -> ñòðîêà
 öèêëå, ïîêà íå äîñòèãíóò çàâåðøàþùèé íîëü, âûçûâàåò ôóíêöèþ int 10h/ah=0Eh.
 
=====================================================================
 
Ðàáîòà âñïîìîãàòåëüíîãî çàãðóç÷èêà kordldr.f1x:
1. Îïðåäåëÿåò, áûë ëè îí çàãðóæåí CHS- èëè LBA-âåðñèåé áóòñåêòîðà.
 çàâèñèìîñòè îò ýòîãî óñòàíàâëèâàåò ñìåùåíèÿ èñïîëüçóåìûõ ïðîöåäóð
áóòñåêòîðà. Êðèòåðèé ïðîâåðêè: scan_for_filename äîëæíà íà÷èíàòüñÿ
ñ èíñòðóêöèè 'xor di,di' ñ êîäîì 31 FF (âîîáùå-òî ýòà èíñòðóêöèÿ ìîæåò
ñ ðàâíûì óñïåõîì àññåìáëèðîâàòüñÿ è êàê 33 FF, íî fasm ãåíåðèðóåò
èìåííî òàêóþ ôîðìó).
2. Óçíà¸ò ðàçìåð ñâîáîäíîé áàçîâîé ïàìÿòè (ò.å. ñâîáîäíîãî íåïðåðûâíîãî êóñêà
àäðåñîâ ïàìÿòè, íà÷èíàþùåãîñÿ ñ 0) âûçîâîì int 12h.  ñîîòâåòñòâèè ñ
íèì âû÷èñëÿåò ÷èñëî ýëåìåíòîâ â êýøå ïàïîê. Õîòÿ áû äëÿ îäíîãî ýëåìåíòà
ìåñòî äîëæíî áûòü, îòñþäà îãðàíè÷åíèå â 592 Kb (94000h áàéò).
Çàìå÷àíèå: ýòîò ðàçìåð íå ìîæåò ïðåâîñõîäèòü 0A0000h áàéò è
íà ïðàêòèêå îêàçûâàåòñÿ íåìíîãî (íà 1-2 êèëîáàéòà) ìåíüøèì èç-çà
íàëè÷èÿ äîïîëíèòåëüíîé îáëàñòè äàííûõ BIOS "ââåðõó" áàçîâîé ïàìÿòè.
3. Îïðåäåëÿåò òèï ôàéëîâîé ñèñòåìû: FAT12 èëè FAT16. Ñîãëàñíî îôèöèàëüíîé
ñïåöèôèêàöèè îò Microsoft (âåðñèÿ 1.03 ñïåöèôèêàöèè äàòèðîâàíà,
ê ñëîâó, 06 äåêàáðÿ 2000 ãîäà), ðàçðÿäíîñòü FAT îïðåäåëÿåòñÿ
èñêëþ÷èòåëüíî ÷èñëîì êëàñòåðîâ: ìàêñèìàëüíîå ÷èñëî êëàñòåðîâ íà
FAT12-òîìå ðàâíî 4094 = 0xFF4. Ñîãëàñíî çäðàâîìó ñìûñëó, íà FAT12
ìîæåò áûòü 0xFF5 êëàñòåðîâ, íî íå áîëüøå: êëàñòåðû íóìåðóþòñÿ ñ 2,
à ÷èñëî 0xFF7 íå ìîæåò áûòü êîððåêòíûì íîìåðîì êëàñòåðà.
Win95/98/Me ñëåäóåò çäðàâîìó ñìûñëó: ðàçãðàíè÷åíèå FAT12/16 äåëàåòñÿ
ïî ìàêñèìóìó 0xFF5. Äðàéâåð FAT â WinNT/2k/XP/Vista âîîáùå ïîñòóïàåò
ÿâíî íåâåðíî, ñ÷èòàÿ, ÷òî 0xFF6 (èëè ìåíüøå) êëàñòåðîâ îçíà÷àåò
FAT12-òîì, â ðåçóëüòàòå ïîëó÷àåòñÿ, ÷òî ïîñëåäíèé êëàñòåð
(â ñëó÷àå 0xFF6) íåàäðåñóåì. Îñíîâíîé çàãðóç÷èê osloader.exe
[âñòðîåí â ntldr] äëÿ NT/2k/XP äåëàåò òàê æå. Ïåðâè÷íûé çàãðóç÷èê
[áóòñåêòîð FAT12/16 çàãðóæàåò ïåðâûé ñåêòîð ntldr, è ðàçáîð FAT-òàáëèöû
ëåæèò íà í¸ì] â NT/2k ïîäâåðæåí òîé æå îøèáêå.  XP å¸ òàêè èñïðàâèëè
â ñîîòâåòñòâèè ñî ñïåöèôèêàöèåé. Linux ïðè îïðåäåëåíèè FAT12/FAT16
÷åñòíî ñëåäóåò ñïåöèôèêàöèè.
Çäåñü êîä îñíîâàí âñ¸ æå íà ñïåöèôèêàöèè. 9x ìåðòâà, à â ëèíåéêå NT
Microsoft åñëè è áóäåò èñïðàâëÿòü îøèáêè, òî ñîãëàñíî ñîáñòâåííîìó
îïèñàíèþ.
4. Äëÿ FAT12: çàãðóæàåò â ïàìÿòü ïåðâóþ êîïèþ òàáëèöû FAT ïî àäðåñó 6000:0000.
Åñëè ðàçìåð, óêàçàííûé â BPB, ïðåâîñõîäèò 12 ñåêòîðîâ,
ýòî îçíà÷àåò, ÷òî çàÿâëåííûé ðàçìåð ñëèøêîì áîëüøîé (ýòî íå ñ÷èòàåòñÿ
îøèáêîé ôàéëîâîé ñèñòåìû), è ÷èòàþòñÿ òîëüêî 12 ñåêòîðîâ (òàáëèöà FAT12
çàâåäîìî âëåçàåò â òàêîé îáú¸ì äàííûõ).
Äëÿ FAT16: èíèöèàëèçèðóåò âíóòðåííèå äàííûå, óêàçûâàÿ, ÷òî íèêàêîé ñåêòîð
FAT íå çàãðóæåí (îíè áóäóò ïîäãðóæàòüñÿ ïîçäíåå, êîãäà ïîíàäîáÿòñÿ
è òîëüêî òå, êîòîðûå ïîíàäîáÿòñÿ).
5. Åñëè êëàñòåð ðàâåí ñåêòîðó, òî áóòñåêòîð çàãðóçèë òîëüêî ÷àñòü ôàéëà
kordldr.f1x, è çàãðóç÷èê ïîäãðóæàåò âòîðóþ ñâîþ ÷àñòü, èñïîëüçóÿ
çíà÷åíèÿ ðåãèñòðîâ íà âõîäå â kordldr.f1x.
6. Çàãðóæàåò âòîðè÷íûé çàãðóç÷èê kord/loader ïî àäðåñó 1000:0000. Åñëè ôàéë íå
íàéäåí, èëè îêàçàëñÿ ïàïêîé, èëè îêàçàëñÿ ñëèøêîì áîëüøèì, òî ïåðåõîäèò
íà êîä îáðàáîòêè îøèáîê èç áóòñåêòîðà ñ ñîîáùåíèåì
"Fatal error: cannot load the secondary loader".
Çàìå÷àíèå: íà ýòîì ýòàïå èìÿ ôàéëà óæå ìîæíî óêàçûâàòü âìåñòå ñ ïóò¸ì
è â ôîðìàòå ASCIIZ, õîòÿ ïîääåðæêè äëèííûõ èì¸í è íåàíãëèéñêèõ ñèìâîëîâ
ïî-ïðåæíåìó íåò.
7. Èçìåíÿåò êîä îáðàáîòêè îøèáîê áóòñåêòîðà íà ïåðåõîä íà ìåòêó hooked_err.
Ýòî íóæíî, ÷òîáû ïîñëåäóþùèå îáðàùåíèÿ ê êîäó áóòñåêòîðà â ñëó÷àå
îøèáîê ÷òåíèÿ íå âûâîäèë ñîîòâåòñòâóþùåå ñîîáùåíèå ñ ïîñëåäóþùåé
ïåðåçàãðóçêîé, à ðàïîðòîâàë îá îøèáêå ÷òåíèÿ, êîòîðóþ ìîã áû
êàê-íèáóäü îáðàáîòàòü âòîðè÷íûé çàãðóç÷èê.
8. Åñëè çàãðóçî÷íûé äèñê èìååò èäåíòèôèêàòîð ìåíüøå 0x80,
òî óñòàíàâëèâàåò al='f' ("floppy"), ah=èäåíòèôèêàòîð äèñêà,
èíà÷å al='h' ("hard"), ah=èäåíòèôèêàòîð äèñêà-0x80 (íîìåð äèñêà).
Óñòàíàâëèâàåò bx='12', åñëè òèï ôàéëîâîé ñèñòåìû - FAT12, è
bx='16' â ñëó÷àå FAT16. Óñòàíàâëèâàåò si=ñìåùåíèå ôóíêöèè îáðàòíîãî
âûçîâà. Ïîñêîëüêó â ýòîò ìîìåíò ds=0, òî ds:si îáðàçóþò ïîëíûé àäðåñ.
9. Ïåðåäà¸ò óïðàâëåíèå ïî àäðåñó 1000:0000.
 
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà:
ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà.
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê.
1. Ñîõðàíÿåò ñòåê âûçûâàþùåãî êîäà è óñòàíàâëèâàåò ñâîé ñòåê:
ss:sp = 0:(7C00-8), bp=7C00: ïàðà ss:bp ïðè ðàáîòå ñ îñòàëüíûì
êîäîì äîëæíà óêàçûâàòü íà 0:7C00, à -8 áåð¸òñÿ îò òîãî, ÷òî
èíèöèàëèçèðóþùèé êîä áóòñåêòîðà óæå ïîìåñòèë â ñòåê 2 äâîéíûõ ñëîâà,
è îíè äîëæíû ñîõðàíÿòüñÿ â íåèçìåííîñòè.
2. Ðàçáèðàåò ïåðåäàííûå ïàðàìåòðû, âûÿñíÿåò, êàêîå äåéñòâèå çàïðîøåíî,
è âûçûâàåò íóæíóþ âñïîìîãàòåëüíóþ ïðîöåäóðó.
3. Âîññòàíàâëèâàåò ñòåê âûçûâàþùåãî êîäà è âîçâðàùàåò óïðàâëåíèå.
 
Âñïîìîãàòåëüíûå ïðîöåäóðû kordldr.f1x.
Ïðîöåäóðà ïîëó÷åíèÿ ñëåäóþùåãî êëàñòåðà â FAT (get_next_cluster):
1. Âñïîìèíàåò ðàçðÿäíîñòü FAT, âû÷èñëåííóþ ðàíåå.
Äëÿ FAT12:
2. Óñòàíàâëèâàåò ds = 0x6000 - ñåãìåíò, êóäà ðàíåå áûëà ñ÷èòàíà
âñÿ òàáëèöà FAT.
3. Ïîäñ÷èòûâàåò si = (êëàñòåð) + (êëàñòåð)/2 - ñìåùåíèå â ýòîì ñåãìåíòå
ñëîâà, çàäàþùåãî ñëåäóþùèé êëàñòåð. Çàãðóæàåò ñëîâî ïî ýòîìó àäðåñó.
4. Åñëè êëàñòåð èìååò íå÷¸òíûé íîìåð, òî ñîîòâåòñòâóþùèé åìó ýëåìåíò
ðàñïîëàãàåòñÿ â ñòàðøèõ 12 áèòàõ ñëîâà, è ñëîâî íóæíî ñäâèíóòü âïðàâî
íà 4 áèòà; â ïðîòèâíîì ñëó÷àå - â ìëàäøèõ 12 áèòàõ, è äåëàòü íè÷åãî íå
íàäî.
5. Âûäåëÿåò èç ïîëó÷èâøåãîñÿ ñëîâà 12 áèò. Ñðàâíèâàåò èõ ñ ïðåäåëîì 0xFF7:
íîìåðà íîðìàëüíûõ êëàñòåðîâ ìåíüøå, è ôëàã CF óñòàíàâëèâàåòñÿ;
ñïåöèàëüíûå çíà÷åíèÿ EOF è BadClus ñáðàñûâàþò ôëàã CF.
Äëÿ FAT16:
2. Âû÷èñëÿåò àäðåñ ïàìÿòè, ïðåäíàçíà÷åííîé äëÿ ñîîòâåòñòâóþùåãî ñåêòîðà äàííûõ
â òàáëèöå FAT.
3. Åñëè ñåêòîð åù¸ íå çàãðóæåí, òî çàãðóæàåò åãî.
4. Âû÷èñëÿåò ñìåùåíèå äàííûõ äëÿ êîíêðåòíîãî êëàñòåðà îòíîñèòåëüíî íà÷àëà
ñåêòîðà.
5. Çàãðóæàåò ñëîâî â ax èç àäðåñà, âû÷èñëåííîìó íà øàãàõ 1 è 3.
6. Ñðàâíèâàåò åãî ñ ïðåäåëîì 0xFFF7: íîìåðà íîðìàëüíûõ êëàñòåðîâ ìåíüøå, è ôëàã
CF óñòàíàâëèâàåòñÿ; ñïåöèàëüíûå çíà÷åíèÿ EOF è BadClus ñáðàñûâàþò CF.
 
Ïðîöåäóðà çàãðóçêè ôàéëà (load_file):
1. Òåêóùàÿ ðàññìàòðèâàåìàÿ ïàïêà - êîðíåâàÿ. Â öèêëå âûïîëíÿåò øàãè 2-4.
2. Êîíâåðòèðóåò èìÿ òåêóùåãî ðàññìàòðèâàåìîãî êîìïîíåíòà èìåíè (êîìïîíåíòû
ðàçäåëÿþòñÿ ñèìâîëîì '/') â FAT-ôîðìàò 8+3. Åñëè ýòî íåâîçìîæíî
(áîëüøå 8 ñèìâîëîâ â èìåíè, áîëüøå 3 ñèìâîëîâ â ðàñøèðåíèè èëè
áîëüøå îäíîé òî÷êè), âîçâðàùàåòñÿ ñ îøèáêîé.
3. Èùåò ýëåìåíò ñ òàêèì èìåíåì â òåêóùåé ðàññìàòðèâàåìîé ïàïêå. Äëÿ êîðíåâîé
ïàïêè èñïîëüçóåòñÿ ïðîöåäóðà èç áóòñåêòîðà. Äëÿ îñòàëüíûõ ïàïîê:
a) Ïðîâåðÿåò, åñòü ëè òàêàÿ ïàïêà â êýøå íåêîðíåâûõ ïàïîê.
(Èäåíòèôèêàöèÿ ïàïîê îñóùåñòâëÿåòñÿ ïî íîìåðó íà÷àëüíîãî êëàñòåðà.)
Åñëè òàêîé ïàïêè åù¸ íåò, äîáàâëÿåò å¸ â êýø; åñëè òîò ïåðåïîëíÿåòñÿ,
âûêèäûâàåò ïàïêó, ê êîòîðîé äîëüøå âñåãî íå áûëî îáðàùåíèé. (Äëÿ
êàæäîãî ýëåìåíòà êýøà õðàíèòñÿ ìåòêà îò 0 äî (ðàçìåð êýøà)-1,
îïðåäåëÿþùàÿ åãî íîìåð ïðè ñîðòèðîâêå ïî äàâíîñòè ïîñëåäíåãî îáðàùåíèÿ.
Ïðè îáðàùåíèè ê êàêîìó-òî ýëåìåíòó åãî ìåòêà ñòàíîâèòñÿ íóëåâîé,
à òå ìåòêè, êîòîðûå ìåíüøå ñòàðîãî çíà÷åíèÿ, óâåëè÷èâàþòñÿ íà åäèíèöó.)
á) Ïðîñìàòðèâàåò â ïîèñêàõ çàïðîøåííîãî èìåíè âñå ýëåìåíòû èç êýøà,
èñïîëüçóÿ ïðîöåäóðó èç áóòñåêòîðà. Åñëè îáíàðóæèâàåò èñêîìûé ýëåìåíò,
ïåðåõîäèò ê øàãó 4. Åñëè îáíàðóæèâàåò êîíåö ïàïêè, âîçâðàùàåòñÿ èç
ïðîöåäóðû ñ îøèáêîé.
â)  öèêëå ñ÷èòûâàåò ïàïêó ïîñåêòîðíî. Ïðè ýòîì ïðîïóñêàåò íà÷àëüíûå
ñåêòîðû, êîòîðûå óæå íàõîäÿòñÿ â êýøå è óæå áûëè ïðîñìîòðåíû. Êàæäûé
ïðî÷èòàííûé ñåêòîð êîïèðóåò â êýø, åñëè òàì åù¸ îñòà¸òñÿ ìåñòî,
è ïðîñìàòðèâàåò â í¸ì âñå ýëåìåíòû. Ðàáîòàåò, ïîêà íå ñëó÷èòñÿ îäíî èç
òð¸õ ñîáûòèé: íàéäåí èñêîìûé ýëåìåíò; êîí÷èëèñü êëàñòåðû (ñóäÿ ïî
öåïî÷êå êëàñòåðîâ â FAT); î÷åðåäíîé ýëåìåíò ïàïêè ñèãíàëèçèðóåò î êîíöå
(ïåðâûé áàéò íóëåâîé).  äâóõ ïîñëåäíèõ ñëó÷àÿõ âîçâðàùàåòñÿ ñ îøèáêîé.
4. Ïðîâåðÿåò òèï íàéäåííîãî ýëåìåíòà (ôàéë/ïàïêà): ïîñëåäíèé ýëåìåíò â
çàïðîøåííîì èìåíè äîëæåí áûòü ôàéëîì, âñå ïðîìåæóòî÷íûå - ïàïêàìè.
Åñëè òåêóùèé êîìïîíåíò èìåíè - ïðîìåæóòî÷íûé, ïðîäâèãàåò òåêóùóþ
ðàññìàòðèâàåìóþ ïàïêó è âîçâðàùàåòñÿ ê ïóíêòó 2.
5. Ïðîõîäèò ïî öåïî÷êå êëàñòåðîâ â FAT è ñ÷èòûâàåò âñå êëàñòåðû â óêàçàííûé
ïðè âûçîâå áóôåð ïîñëåäîâàòåëüíûìè âûçîâàìè ôóíêöèè áóòñåêòîðà;
ïðè ýòîì åñëè íåñêîëüêî êëàñòåðîâ ôàéëà ðàñïîëîæåíû íà äèñêå
ïîñëåäîâàòåëüíî, òî èõ ÷òåíèå îáúåäèíÿåòñÿ â îäíó îïåðàöèþ.
Ñëåäèò çà òåì, ÷òîáû íå ïðåâûñèòü óêàçàííûé ïðè âûçîâå ïðîöåäóðû
ëèìèò ÷èñëà ñåêòîðîâ äëÿ ÷òåíèÿ.
 
Ïðîöåäóðà ïðîäîëæåíèÿ çàãðóçêè ôàéëà (continue_load_file): âñòðîåíà
âíóòðü øàãà 5 load_file; çàãðóæàåò â ðåãèñòðû íóæíûå çíà÷åíèÿ (ðàíåå
ñîõðàí¸ííûå èç load_file) è ïðîäîëæàåò øàã 5.
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat1x
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/bootsect.asm
0,0 → 1,358
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
use_lba = 0
org 0x7C00
jmp start
nop
; FAT parameters, BPB
; they must be changed at install, replaced with real values
rb 8 ; BS_OEMName, ignored
dw 200h ; BPB_BytsPerSec
BPB_SecsPerClus db ?
BPB_RsvdSecCnt dw ?
BPB_NumFATs db ?
BPB_RootEntCnt dw ?
dw ? ; BPB_TotSec16
db ? ; BPB_Media
dw ? ; BPB_FATSz16 = 0 for FAT32
BPB_SecPerTrk dw ?
BPB_NumHeads dw ?
BPB_HiddSec dd ?
dd ? ; BPB_TotSec32
BPB_FATSz32 dd ?
BPB_ExtFlags dw ?
dw ? ; BPB_FSVer
BPB_RootClus dd ?
dw ? ; BPB_FSInfo
BPB_BkBootSec dw ?
rb 12 ; BPB_Reserved
BS_DrvNum db ?
db ? ; BS_Reserved1
db ? ; BS_BootSig
dd ? ; BS_VolID
rb 11 ; BS_VolLab
rb 8 ;
 
curseg dw 0x8000
 
start:
xor ax, ax
mov ss, ax
mov sp, 0x7C00
mov ds, ax
mov bp, sp
cld
sti
push dx ; byte [bp-2] = boot drive
if use_lba
mov ah, 41h
mov bx, 55AAh
int 13h
mov si, aNoLBA
jc err_
cmp bx, 0AA55h
jnz err_
test cl, 1
jz err_
else
mov ah, 8
int 13h
jc @f
movzx ax, dh
inc ax
mov [bp+BPB_NumHeads-0x7C00], ax
and cx, 3Fh
mov [bp+BPB_SecPerTrk-0x7C00], cx
@@:
end if
; get FAT parameters
xor bx, bx
movzx eax, [bp+BPB_NumFATs-0x7C00]
mul [bp+BPB_FATSz32-0x7C00]
movzx ecx, [bp+BPB_RsvdSecCnt-0x7C00]
push ecx ; FAT start = dword [bp-6]
add eax, ecx
push eax ; data start = dword [bp-10]
;push dword -1 ; dword [bp-14] = current sector for FAT cache
db 66h
push -1 ; dword [bp-14] = current sector for FAT cache
mov eax, [bp+BPB_RootClus-0x7C00]
mov si, main_loader
call lookup_in_dir
jnc kordldr_ok
noloader:
mov si, aLoaderNotFound
err_:
call out_string
mov si, aPressAnyKey
call out_string
xor ax, ax
int 16h
int 18h
jmp $
kordldr_ok:
mov eax, [es:di+20-2] ; hiword(eax) = hiword(cluster)
mov ax, [es:di+26] ; loword(eax) = loword(cluster)
mov es, bx ; es = 0
mov bx, 0x7E00
push bx ; save return address: bx = 7E00
; fall through - 'ret' in read_cluster will return to 7E00
 
read_cluster:
; ss:bp = 0:7C00
; es:bx = pointer to data
; eax = cluster
sub eax, 2
movzx ecx, [bp+BPB_SecsPerClus-0x7C00]
mul ecx
 
read_sectors2:
; same as read_sectors32, but eax is relative to start of data
add eax, [bp-10]
read_sectors32:
; ss:bp = 0:7C00
; es:bx = pointer to data
; eax = first sector
; cx = number of sectors
; some high words of 32-bit registers are destroyed!
pusha
add eax, [bp+BPB_HiddSec-0x7C00]
if use_lba
push ds
do_read_sectors:
push ax
push cx
cmp cx, 0x7F
jbe @f
mov cx, 0x7F
@@:
; create disk address packet on the stack
; dq starting LBA
push 0
push 0
push eax
; dd buffer
push es
push bx
; dw number of blocks to transfer (no more than 0x7F)
push cx
; dw packet size in bytes
push 10h
; issue BIOS call
push ss
pop ds
mov si, sp
mov dl, [bp-2]
mov ah, 42h
int 13h
mov si, aReadError
jc err_
; restore stack
add sp, 10h
; increase current sector & buffer; decrease number of sectors
movzx esi, cx
mov ax, es
shl cx, 5
add ax, cx
mov es, ax
pop cx
pop ax
add eax, esi
sub cx, si
jnz do_read_sectors
pop ds
popa
ret
else
do_read_sectors:
pusha
pop edi ; loword(edi) = di, hiword(edi) = si
push bx
 
; eax / (SectorsPerTrack) -> eax, remainder bx
movzx esi, [bp+BPB_SecPerTrk-0x7C00]
xor edx, edx
div esi
mov bx, dx ; bx=sector-1
 
; eax -> dx:ax
push eax
pop ax
pop dx
; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
div [bp+BPB_NumHeads-0x7C00]
 
; number of sectors: read no more than to end of track
sub si, bx
cmp cx, si
jbe @f
mov cx, si
@@:
 
inc bx
; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
movzx edi, cx
mov dh, dl
mov dl, [bp-2]
shl ah, 6
mov ch, al
mov al, cl
mov cl, bl
or cl, ah
pop bx
mov si, 3
mov ah, 2
@@:
push ax
int 13h
jnc @f
xor ax, ax
int 13h ; reset drive
pop ax
dec si
jnz @b
mov si, aReadError
jmp err_
@@:
pop ax
mov ax, es
mov cx, di
shl cx, 5
add ax, cx
mov es, ax
push edi
popa
add eax, edi
sub cx, di
jnz do_read_sectors
popa
ret
end if
 
lookup_in_dir:
; in: ds:si -> 11-bytes FAT name
; in: eax = cluster
; in: bx = 0
; out: if found: CF=0, es:di -> directory entry
; out: if not found: CF=1
; push 0x8000
; pop es
; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000
mov es, [bp-7C00h + curseg]
push es
push eax
call read_cluster
mov ax, es
cmp ah, 82h
jb @f
mov ax, 8200h
@@:
mov [bp-7C00h + curseg], ax
pop eax
pop es
; scan for filename
shl cx, 4
xor di, di
sloop:
cmp byte [es:di], bl
jz snotfound
test byte [es:di+11], 8 ; volume label?
jnz scont ; ignore volume labels
pusha
mov cx, 11
repz cmpsb
popa
jz sdone
scont:
add di, 0x20
loop sloop
; next cluster
push 0x6000
pop es
push es ax
shr eax, 7
cmp eax, [bp-14]
mov [bp-14], eax
jz @f
add eax, [bp-6]
mov cx, 1
call read_sectors32
@@:
pop di es
and di, 0x7F
shl di, 2
and byte [es:di+3], 0x0F
mov eax, [es:di]
;and eax, 0x0FFFFFFF
cmp eax, 0x0FFFFFF7
jb lookup_in_dir
snotfound:
stc
sdone:
ret
 
out_string:
; in: ds:si -> ASCIIZ string
lodsb
test al, al
jz sdone
mov ah, 0Eh
mov bx, 7
int 10h
jmp out_string
 
aReadError db 'Read error',0
if use_lba
aNoLBA db 'The drive does not support LBA!',0
end if
aLoaderNotFound db 'Loader not found',0
aPressAnyKey db 13,10,'Press any key...',13,10,0
main_loader db 'KORDLDR F32'
 
db 56h
; just to make file 512 bytes long :)
db 'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
 
; bootsector signature
dw 0xAA55
 
; display offsets of all procedures used by kordldr.f12.asm
macro show [procedure]
{
bits = 16
display `procedure,' = '
repeat bits/4
d = '0' + procedure shr (bits - %*4) and 0Fh
if d > '9'
d = d + 'A'-'9'-1
end if
display d
end repeat
display 13,10
}
 
show read_sectors32, read_sectors2, err_, noloader
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/build.bat
0,0 → 1,3
@fasm -m 65535 bootsect.asm bootsect.bin
@fasm -m 65535 kordldr.f32.asm kordldr.f32
@pause
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/kordldr.f32.asm
0,0 → 1,672
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
org 0x7E00
; the KordOS FAT32 bootsector loads first cluster of this file to 0:7E00 and transfers control to here
; ss:bp = 0:7C00
; ds = 0
virtual at bp
rb 3 ; BS_jmpBoot
rb 8 ; BS_OEMName, ignored
dw ? ; BPB_BytsPerSec
BPB_SecsPerClus db ?
BPB_RsvdSecCnt dw ?
BPB_NumFATs db ?
BPB_RootEntCnt dw ?
dw ? ; BPB_TotSec16
db ? ; BPB_Media
dw ? ; BPB_FATSz16 = 0 for FAT32
BPB_SecPerTrk dw ?
BPB_NumHeads dw ?
BPB_HiddSec dd ?
dd ? ; BPB_TotSec32
BPB_FATSz32 dd ?
BPB_ExtFlags dw ?
dw ? ; BPB_FSVer
BPB_RootClus dd ?
filesize:
dw ? ; BPB_FSInfo
dw ? ; BPB_BkBootSec
rb 12 ; BPB_Reserved
BS_DrvNum db ?
db ? ; BS_Reserved1
db ? ; BS_BootSig
dd ? ; BS_VolID
; rb 11 ; BS_VolLab
; rb 5 ; BS_FilSysType, first 5 bytes
read_sectors32 dw ?
read_sectors2 dw ?
err_ dw ?
noloader dw ?
cachelimit dw ?
fatcachehead rw 2
fatcacheend dw ?
rb 3 ; BS_FilSysType, last 3 bytes
curseg dw ?
num_sectors dd ?
cur_cluster dd ?
next_cluster dd ?
flags dw ?
cur_delta dd ?
end virtual
 
; procedures from boot sector
; LBA version
lba_read_sectors2 = 7CD6h
lba_err = 7CAAh
lba_noloader = 7CA7h ; = lba_err - 3
; CHS version
chs_read_sectors2 = 7CD2h
chs_err = 7CA6h
chs_noloader = 7CA3h ; = chs_err - 3
 
push eax cx ; save our position on disk
; determine version of bootsector (LBA vs CHS)
mov [read_sectors2], chs_read_sectors2
mov bx, chs_err
mov [err_], bx
; mov [noloader], chs_noloader
cmp byte [bx], 0xE8 ; [chs_err] = 0xE8 for CHS version, 0x14 for LBA version
jz @f
add [read_sectors2], lba_read_sectors2 - chs_read_sectors2
add [err_], lba_err - chs_err
; mov [noloader], lba_noloader
@@:
xor bx, bx
; determine size of cache for folders
int 12h ; ax = size of available base memory in Kb
sub ax, 92000h / 1024
jae @f
nomem:
mov si, nomem_str
jmp [err_]
@@:
shr ax, 3
mov [cachelimit], ax ; size of cache - 1
mov es, bx
; no folders in cache yet
mov di, foldcache_clus
mov cx, 8*4/2 + 1
xor ax, ax
rep stosw
; bootsector code caches one FAT sector, [bp-14], in 6000:0000
; initialize our (more advanced) FAT caching from this
mov di, 8400h
mov cx, di
lea si, [fatcachehead]
mov [si], si ; no sectors in cache:
mov [si+2], si ; 'prev' & 'next' links point to self
mov [fatcacheend], di ; first free item = 8400h
stosw ; 'next cached sector' link
stosw ; 'prev cached sector' link
mov eax, [bp-14]
stosd ; first sector number in cache
test eax, eax
js @f
mov [si], cx ; 'first cached sector' link = 8400h
mov [si+2], cx ; 'next cached sector' link = 8400h
mov [fatcacheend], di ; first free item = 8406h
@@:
; if cluster = sector, we need to read second part of our file
; (bootsector loads only first cluster of kordldr.f32)
pop cx eax ; restore our position on disk
cmp cx, 1
ja kordldr_full
sub eax, [bp-10]
inc eax
inc eax ; eax = first cluster of kordldr.f32
call get_next_cluster
jc @f
; jmp [noloader]
mov ax, [err_]
sub ax, 3
jmp ax
@@:
dec eax
dec eax
push 0x800
pop es
call [read_sectors2]
kordldr_full:
; bootsector code has read some data of root directory to 8000:0000
; initialize our folder caching from this
mov eax, [BPB_RootClus]
mov [foldcache_clus], eax
mov cx, [curseg]
mov ax, 8000h
sub cx, ax ; cx = size of data read in paragraphs (0x10 bytes)
shr cx, 1 ; cx = size of folder data read in entries (0x20 bytes)
mov [foldcache_size], cx
shl cx, 4
push ds
mov ds, ax
push 0x9000
pop es
xor si, si
xor di, di
rep movsw
pop ds
; ...continue loading...
mov di, secondary_loader_info
call load_file
test bx, bx
mov bx, [err_]
jz @f
mov si, aKernelNotFound
jmp bx
@@:
; for subsequent calls to callback function, hook error handler
; push hooked_err / ret
mov dword [bx], 0x68 + (hooked_err shl 8) + (0xC3 shl 24)
; set registers for secondary loader
mov ah, [bp-2] ; drive id
mov al, 'f'
btr ax, 15
jnc @f
mov al, 'h'
@@:
mov bx, '32'
mov si, callback
jmp far [si+secondary_loader_info-callback]
 
nomem_str db 'No memory',0
 
cluster2sector:
sub eax, 2
clustersz2sectorsz:
movzx ecx, [BPB_SecsPerClus]
mul ecx
ret
 
get_next_cluster:
; in: eax = cluster
; out: if there is next cluster: CF=1, eax = next cluster
; out: if there is no next cluster: CF=0
push di bx
push ds
push ss
pop ds
push ax
shr eax, 7
; eax = FAT sector number; look in cache
mov di, 8400h
.cache_lookup:
cmp di, [fatcacheend]
jae .not_in_cache
scasd
scasd
jnz .cache_lookup
.in_cache:
sub di, 8
; delete this sector from the list
push si
mov si, [di]
mov bx, [di+2]
mov [si+2], bx
mov [bx], si
pop si
jmp @f
.not_in_cache:
; cache miss
; cache is full?
mov di, [fatcacheend]
cmp di, 8C00h
jnz .cache_not_full
; yes, delete the oldest entry
mov di, [fatcachehead]
mov bx, [di]
mov [fatcachehead], bx
push word [di+2]
pop word [bx+2]
jmp .cache_append
.cache_not_full:
; no, allocate new sector
add [fatcacheend], 8
.cache_append:
; read FAT
mov [di+4], eax
push es
pushad
lea cx, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))] ; +0x10000 - for FASM
shl cx, 9-3
mov es, cx
xor bx, bx
mov cx, 1
add eax, [bp-6] ; FAT start
sub eax, [bp-10]
call [read_sectors2]
popad
pop es
@@:
; add new sector to the end of list
mov bx, di
xchg bx, [fatcachehead+2]
push word [bx]
pop word [di]
mov [bx], di
mov [di+2], bx
; get requested item
lea ax, [di + 0x10000 - 0x8400 + (0x6000 shr (9-3))]
pop di
and di, 0x7F
shl di, 2
shl ax, 9-3
mov ds, ax
and byte [di+3], 0x0F
mov eax, [di]
pop ds
pop bx di
;and eax, 0x0FFFFFFF
cmp eax, 0x0FFFFFF7
ret
 
if $ > 0x8000
error 'get_next_cluster must fit in first sector of kordldr.f32!'
end if
 
load_file:
; in: ss:bp = 0:7C00
; in: ds:di -> information structure
; dw:dw address
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
; ASCIIZ name
; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found
; out: dx:ax = file size (0xFFFFFFFF if file not found)
mov eax, [BPB_RootClus] ; start from root directory
or dword [filesize], -1 ; initialize file size with invalid value
lea si, [di+6]
parse_dir_loop:
; convert name to FAT name
push di
push ax
push ss
pop es
; convert ASCIIZ filename to FAT name
filename equ bp
mov di, filename
push di
mov cx, 8+3
mov al, ' '
rep stosb
pop di
mov cl, 8 ; 8 symbols per name
mov bl, 1
nameloop:
lodsb
test al, al
jz namedone
cmp al, '/'
jz namedone
cmp al, '.'
jz namedot
dec cx
js badname
cmp al, 'a'
jb @f
cmp al, 'z'
ja @f
sub al, 'a'-'A'
@@:
stosb
jmp nameloop
namedot:
inc bx
jp badname
add di, cx
mov cl, 3
jmp nameloop
badname: ; do not make direct js/jp to notfound_pop:
; this generates long forms of conditional jumps and results in longer code
jmp notfound_pop
namedone:
; scan directory
pop ax ; eax = cluster of directory
; high word of eax is preserved by operations above
push ds
push si
; read a folder sector-by-sector and scan
; first, try to use the cache
push ss
pop ds
mov di, foldcache_mark
xor bx, bx
mov cx, [cachelimit]
@@:
lea si, [di+bx]
mov edx, dword [foldcache_clus+si-foldcache_mark+bx]
cmp edx, eax
jz cacheok
test edx, edx
jz cacheadd ; the cache has place for new entry
inc bx
inc bx
dec cx
jns @b
; the folder is not present in the cache, so add it
; the cache is full; find the oldest entry and replace it with the new one
mov bx, -2
mov dx, [cachelimit]
@@:
inc bx
inc bx
cmp word [di+bx], dx ; marks have values 0 through [cachelimit]
jnz @b
lea si, [di+bx]
cacheadd:
or word [di+bx], 0xFFFF ; very big value, it will be changed soon
and [foldcache_size+di-foldcache_mark+bx], 0 ; no folder items yet
mov dword [foldcache_clus+si-foldcache_mark+bx], eax
cacheok:
; update cache marks
mov dx, [di+bx]
mov cx, [foldcache_size+di-foldcache_mark+bx]
mov di, [cachelimit]
add di, di
cacheupdate:
cmp [foldcache_mark+di], dx
adc [foldcache_mark+di], 0
dec di
dec di
jns cacheupdate
and [foldcache_mark+bx], 0
; done, bx contains (position in cache)*2
;mov dx, bx
;shl dx, 8 ; dx = (position in cache)*0x2000/0x10
;add dx, 0x9000
lea dx, [bx + 0x90]
xchg dl, dh
mov ds, dx
mov si, filename ; ss:si -> filename in FAT style
call scan_for_filename
jz lookup_done
; cache miss, read folder data from disk
mov bx, cx
shr bx, 4
shl cx, 5
mov di, cx ; es:di -> free space in cache entry
; external loop: scan clusters
folder_next_cluster:
; internal loop: scan sectors in cluster
push eax
call cluster2sector
folder_next_sector:
; skip first bx sectors
dec bx
jns folder_skip_sector
push cx
push es di
push 0x8000
pop es
xor bx, bx
mov cx, 1
push es
push eax
call [read_sectors2]
pop eax
; copy data to the cache...
pop ds
pop di es
cmp di, 0x2000 ; ...if there is free space, of course
jae @f
pusha
mov cx, 0x100
xor si, si
rep movsw
mov di, es
shr di, 8
add [ss:foldcache_size+di-0x90], 0x10 ; 0x10 new entries in the cache
popa
@@:
push es
mov cl, 0x10 ; ch=0 at this point
call scan_for_filename
pop es
pop cx
jz lookup_done_pop
folder_skip_sector:
inc eax
loop folder_next_sector
pop eax ; eax = current cluster
call get_next_cluster
jc folder_next_cluster
stc
push eax
lookup_done_pop:
pop eax
lookup_done:
pop si
; CF=1 <=> failed
jnc found
pop ds
notfound:
pop di
notfound2:
mov bx, 2 ; file not found
mov ax, 0xFFFF
mov dx, ax ; invalid file size
ret
notfound_pop:
pop ax
jmp notfound
found:
mov eax, [di+20-2]
mov edx, [di+28]
mov ax, [di+26] ; get cluster
test byte [di+11], 10h ; directory?
pop ds
pop di
jz regular_file
cmp byte [si-1], 0
jz notfound2 ; don't read directories as regular files
; ok, we have found a directory and the caller requested a file into it
jmp parse_dir_loop ; restart with new cluster in ax
regular_file:
cmp byte [si-1], 0
jnz notfound2 ; file does not contain another files
; ok, we have found a regular file and the caller requested it
; save file size
mov [filesize], edx
mov si, [di+4] ; [ds:di+4] = limit in 4K blocks
shl si, 3
push si
les bx, [di] ; es:bx -> buffer
clusloop:
; eax = first cluster, top of stack contains limit in sectors
mov esi, eax ; remember current cluster
xor ecx, ecx ; ecx will contain number of consecutive clusters
mov [cur_delta], ecx
mov edi, eax
clusfind:
inc edi
inc ecx
call get_next_cluster
jnc clusread
cmp eax, edi
jz clusfind
stc
clusread:
pop di ; limit in sectors
movzx edi, di
push eax ; save next cluster
pushf ; save flags
; read cx clusters, starting from si
; calculate number of sectors
xchg eax, ecx
call clustersz2sectorsz
mov [num_sectors], eax
jmp @f
continue_load_file:
les bx, [di] ; es:bx -> buffer
movzx edi, word [di+4] ; di = limit in 4K blocks
shl di, 3 ; now di = limit in sectors
mov eax, [num_sectors]
mov esi, [cur_cluster]
push [next_cluster]
push [flags]
test eax, eax
jz nextclus
@@:
; eax = number of sectors; compare with limit
cmp eax, edi
seta dl
push dx ; limit was exceeded?
jbe @f
mov eax, edi
@@:
sub di, ax ; calculate new limit
sub [num_sectors], eax
mov [cur_cluster], esi
; calculate starting sector
push ax
xchg eax, esi
call cluster2sector
pop cx
add eax, [cur_delta]
add [cur_delta], ecx
; read
call [read_sectors2]
pop dx
; next cluster?
nextclus:
popf
pop eax
mov [next_cluster], eax
pushf
pop [flags]
jnc @f ; no next cluster => return
mov dl, 1 ; dh=0 in any case
test di, di
jz @f ; if there is next cluster but current limit is 0 => return: limit exceeded
push di
jmp clusloop ; all is ok, continue
hooked_err:
mov sp, 7C00h-14-2 ; restore stack
mov dx, 3 ; return: read error
@@:
mov bx, dx
mov ax, [filesize]
mov dx, [filesize+2]
ret
 
scan_for_filename:
; in: ss:si -> 11-bytes FAT name
; in: ds:0 -> part of directory data
; in: cx = number of entries
; in: bh = 0
; out: if found: CF=0, ZF=1, es:di -> directory entry
; out: if not found, but continue required: CF=1 and ZF=0
; out: if not found and zero item reached: CF=1 and ZF=1
push ds
pop es
xor di, di
push cx
jcxz snoent
sloop:
cmp byte [di], bh
jz snotfound
test byte [di+11], 8 ; volume label?
jnz scont ; ignore volume labels
pusha
mov cx, 11
repz cmps byte [ss:si], byte [es:di]
popa
jz sdone
scont:
add di, 0x20
loop sloop
snoent:
inc cx ; clear ZF flag
snotfound:
stc
sdone:
pop cx
lrdret:
ret
 
; Callback function for secondary loader
callback:
; in: ax = function number; only functions 1 and 2 are defined for now
; save caller's stack
mov dx, ss
mov cx, sp
; set our stack (required because we need ss=0)
xor si, si
mov ss, si
mov sp, 7C00h-10
mov bp, 7C00h
push dx
push cx
; call our function
stc ; unsupported function
dec ax
jz callback_readfile
dec ax
jnz callback_ret
; function 2: continue loading file
; can be called only after function 1 returned value bx=1 (only part of file was loaded)
; in: ds:di -> information structure
; dw:dw address
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error
; out: dx:ax = file size
call continue_load_file
jmp callback_ret_succ
callback_readfile:
; function 1: read file
; in: ds:di -> information structure
; dw:dw address
; dw limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
; ASCIIZ name
; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error
; out: dx:ax = file size (0xFFFFFFFF if file was not found)
call load_file
callback_ret_succ:
clc ; function is supported
callback_ret:
; restore caller's stack
pop cx
pop ss
mov sp, cx
; return to caller
retf
 
secondary_loader_info:
dw 0, 0x1000
dw 0x30000 / 0x1000
db 'kord/loader',0
aKernelNotFound db 'Fatal error: cannot load the secondary loader',0
 
;if $ > 0x8200
;error 'total size of kordldr.f32 must not exceed 1024 bytes!'
;end if
 
;foldcache_clus dd 0,0,0,0,0,0,0,0 ; start with no folders in cache
;foldcache_mark dw 0
; rw 7
;foldcache_size rw 8
foldcache_clus rd 8
foldcache_mark rw 8
foldcache_size rw 8
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32/bootsect.txt
0,0 → 1,333
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
×èòàé ìåæäó ñòðîê - òàì íèêîãäà íå áûâàåò îïå÷àòîê.
 
Áóòñåêòîð äëÿ FAT32-òîìà íà íîñèòåëå ñ ðàçìåðîì ñåêòîðà 0x200 = 512 áàéò.
 
=====================================================================
 
Åñòü äâå âåðñèè â çàâèñèìîñòè îò òîãî, ïîääåðæèâàåò ëè íîñèòåëü LBA,
âûáîð îñóùåñòâëÿåòñÿ óñòàíîâêîé êîíñòàíòû use_lba â ïåðâîé ñòðîêå èñõîäíèêà.
Òðåáîâàíèÿ äëÿ ðàáîòû:
1) Ñàì áóòñåêòîð, ïåðâàÿ êîïèÿ FAT è âñå èñïîëüçóåìûå ôàéëû
äîëæíû áûòü ÷èòàáåëüíû. (Åñëè äåëî ïðîèñõîäèò íà íîñèòåëå ñ ðàçáèåíèåì íà
ðàçäåëû è çàãðóçî÷íûé êîä â MBR äîñòàòî÷íî óìíûé, òî ÷èòàáåëüíîñòè ðåçåðâíîé
êîïèè áóòñåêòîðà (ñåêòîð íîìåð 6 íà òîìå) äîñòàòî÷íî âìåñòî ÷èòàáåëüíîñòè
ñàìîãî áóòñåêòîðà).
2) Ìèíèìàëüíûé ïðîöåññîð - 80386.
3) Â ñèñòåìå äîëæíî áûòü êàê ìèíèìóì 584K ñâîáîäíîé áàçîâîé ïàìÿòè.
 
=====================================================================
 
Äîêóìåíòàöèÿ â òåìó (ññûëêè ïðîâåðÿëèñü íà âàëèäíîñòü 15.05.2008):
îôèöèàëüíàÿ ñïåöèôèêàöèÿ FAT: http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
â ôîðìàòå PDF: http://staff.washington.edu/dittrich/misc/fatgen103.pdf
ðóññêèé ïåðåâîä: http://wasm.ru/docs/11/fatgen103-rus.zip
îôèöèàëüíàÿ ñïåöèôèêàöèÿ ðàñøèðåíèÿ EDD BIOS 3.0: http://www.phoenix.com/NR/rdonlyres/19FEBD17-DB40-413C-A0B1-1F3F560E222F/0/specsedd30.pdf
òî æå, âåðñèÿ 1.1: http://www.phoenix.com/NR/rdonlyres/9BEDED98-6B3F-4DAC-BBB7-FA89FA5C30F0/0/specsedd11.pdf
îïèñàíèå ôóíêöèé BIOS: Interrupt List by Ralf Brown: http://www.cs.cmu.edu/~ralf/files.html
îôèöèàëüíàÿ ñïåöèôèêàöèÿ Boot BIOS: http://www.phoenix.com/NR/rdonlyres/56E38DE2-3E6F-4743-835F-B4A53726ABED/0/specsbbs101.pdf
 
=====================================================================
 
Ñõåìà èñïîëüçóåìîé ïàìÿòè:
...-7C00 ñòåê
7C00-7E00 êîä áóòñåêòîðà
7E00-8200 âñïîìîãàòåëüíûé ôàéë çàãðóç÷èêà (kordldr.f32)
8400-8C00 èíôîðìàöèÿ î êýøå äëÿ òàáëèöû FAT: 100h âõîäîâ ïî 8
áàéò: 4 áàéòà (äâå ññûëêè - âïåð¸ä è íàçàä) äëÿ
îðãàíèçàöèè L2-ñïèñêà âñåõ ïðî÷èòàííûõ ñåêòîðîâ â
ïîðÿäêå âîçðàñòàíèÿ ïîñëåäíåãî âðåìåíè èñïîëüçîâàíèÿ
+ 4 áàéòà äëÿ íîìåðà ñåêòîðà; ïðè ïåðåïîëíåíèè êýøà
âûêèäûâàåòñÿ ýëåìåíò èç ãîëîâû ñïèñêà, òî åñòü òîò,
ê êîòîðîìó äîëüøå âñåõ íå áûëî îáðàùåíèé
60000-80000 êýø äëÿ òàáëèöû FAT (100h ñåêòîðîâ)
80000-90000 òåêóùèé êëàñòåð òåêóùåé ðàññìàòðèâàåìîé ïàïêè
90000-... êýø äëÿ ñîäåðæèìîãî ïàïîê (êàæäîé ïàïêå îòâîäèòñÿ
2000h áàéò = 100h âõîäîâ, îäíîâðåìåííî â êýøå
ìîæåò íàõîäèòüñÿ íå áîëåå 8 ïàïîê;
òî÷íûé ðàçìåð îïðåäåëÿåòñÿ ðàçìåðîì äîñòóïíîé
ôèçè÷åñêîé ïàìÿòè - êàê ïðàâèëî, íåïîñðåäñòâåííî
ïåðåä A0000 ðàçìåùàåòñÿ EBDA, Extended BIOS Data Area)
 
=====================================================================
 
Îñíîâíîé ïðîöåññ çàãðóçêè.
Òî÷êà âõîäà (start): ïîëó÷àåò óïðàâëåíèå îò BIOS ïðè çàãðóçêå, ïðè ýòîì
dl ñîäåðæèò èäåíòèôèêàòîð äèñêà, ñ êîòîðîãî èä¸ò çàãðóçêà
1. Íàñòðàèâàåò ñòåê ss:sp = 0:7C00 (ñòåê ðàñïîëàãàåòñÿ íåïîñðåäñòâåííî ïåðåä
êîäîì), ñåãìåíò äàííûõ ds = 0, è óñòàíàâëèâàåò ss:bp íà íà÷àëî
áóòñåêòîðà (â äàëüíåéøåì äàííûå áóäóò àäðåñîâàòüñÿ ÷åðåç [bp+N] -
ýòî îñâîáîæäàåò ds è ýêîíîìèò íà ðàçìåðå êîäà). Ñîõðàíÿåò â ñòåêå
èäåíòèôèêàòîð çàãðóçî÷íîãî äèñêà äëÿ ïîñëåäóþùåãî îáðàùåíèÿ
÷åðåç byte [bp-2].
2. LBA-âåðñèÿ: ïðîâåðÿåò, ïîääåðæèâàåò ëè íîñèòåëü LBA, âûçîâîì ôóíêöèè 41h
ïðåðûâàíèÿ 13h. Åñëè íåò, ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ
ñîîáùåíèåì îá îòñóòñòâèè LBA.
CHS-âåðñèÿ: îïðåäåëÿåò ãåîìåòðèþ íîñèòåëÿ âûçîâîì ôóíêöèè 8 ïðåðûâàíèÿ 13h è
çàïèñûâàåò ïîëó÷åííûå äàííûå ïîâåðõ BPB. Åñëè âûçîâ çàâåðøèëñÿ îøèáêîé,
ïðåäïîëàãàåò óæå ñóùåñòâóþùèå äàííûå êîððåêòíûìè.
3. Âû÷èñëÿåò íà÷àëî äàííûõ FAT-òîìà, ñîõðàíÿåò åãî â ñòåê äëÿ ïîñëåäóþùåãî
îáðàùåíèÿ ÷åðåç dword [bp-10].  ïðîöåññå âû÷èñëåíèÿ óçíà¸ò íà÷àëî
ïåðâîé FAT, ñîõðàíÿåò è åãî â ñòåê äëÿ ïîñëåäóþùåãî îáðàùåíèÿ ÷åðåç
dword [bp-6].
4. (Çàêàí÷èâàÿ òåìó ïàðàìåòðîâ â ñòåêå) Ïîìåùàåò â ñòåê dword-çíà÷åíèå -1
äëÿ ïîñëåäóþùåãî îáðàùåíèÿ ÷åðåç dword [bp-14] - èíèöèàëèçàöèÿ
ïåðåìåííîé, ñîäåðæàùåé òåêóùèé ñåêòîð, íàõîäÿùèéñÿ â êýøå FAT
(-1 íå ÿâëÿåòñÿ âàëèäíûì çíà÷åíèåì äëÿ íîìåðà ñåêòîðà FAT).
5. Èùåò â êîðíåâîé ïàïêå ýëåìåíò kordldr.f32. Åñëè íå íàõîäèò - ïåðåõîäèò íà
êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì î íåíàéäåííîì çàãðóç÷èêå.
Çàìå÷àíèå: íà ýòîì ýòàïå çàãðóçêè èñêàòü ìîæíî òîëüêî â êîðíåâîé
ïàïêå è òîëüêî èìåíà, çàäàííûå â ôîðìàòå ôàéëîâîé ñèñòåìå FAT
(8+3 - 8 áàéò íà èìÿ, 3 áàéòà íà ðàñøèðåíèå, âñå áóêâû äîëæíû
áûòü çàãëàâíûìè, ïðè íåîáõîäèìîñòè èìÿ è ðàñøèðåíèå äîïîëíÿþòñÿ
ïðîáåëàìè, ðàçäåëÿþùåé òî÷êè íåò, çàâåðøàþùåãî íóëÿ íåò).
6. Çàãðóæàåò ïåðâûé êëàñòåð ôàéëà kordldr.f32 ïî àäðåñó 0:7E00 è ïåðåäà¸ò
åìó óïðàâëåíèå. Ïðè ýòîì â ðåãèñòðå eax îêàçûâàåòñÿ àáñîëþòíûé
íîìåð ïåðâîãî ñåêòîðà kordldr.f32, à â cx - ÷èñëî ñ÷èòàííûõ ñåêòîðîâ
(ðàâíîå ðàçìåðó êëàñòåðà).
 
Âñïîìîãàòåëüíûå ïðîöåäóðû áóòñåêòîðà.
Êîä îáðàáîòêè îøèáîê (err):
1. Âûâîäèò ñòðîêó ñ ñîîáùåíèåì îá îøèáêå.
2. Âûâîäèò ñòðîêó "Press any key...".
3. Æä¸ò íàæàòèÿ any key.
4. Âûçûâàåò int 18h, äàâàÿ øàíñ BIOSó ïîïûòàòüñÿ çàãðóçèòüñÿ îòêóäà-íèáóäü åù¸.
5. Äëÿ ïîäñòðàõîâêè çàöèêëèâàåòñÿ.
 
Ïðîöåäóðà ÷òåíèÿ êëàñòåðà (read_cluster):
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
ss:bp = 0:7C00
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå
eax = íîìåð êëàñòåðà
íà âûõîäå: ecx = ÷èñëî ïðî÷èòàííûõ ñåêòîðîâ (ðàçìåð êëàñòåðà),
es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå,
eax è ñòàðøèå ñëîâà äðóãèõ 32-áèòíûõ ðåãèñòðîâ ðàçðóøàþòñÿ
Çàãðóæàåò â ecx ðàçìåð êëàñòåðà, ïåðåêîäèðóåò íîìåð êëàñòåðà â íîìåð ñåêòîðà
è ïåðåõîäèò ê ñëåäóþùåé ïðîöåäóðå.
 
Ïðîöåäóðà ÷òåíèÿ ñåêòîðîâ (read_sectors32 è read_sectors2):
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
ss:bp = 0:7C00
es:bx = óêàçàòåëü íà íà÷àëî áóôåðà, êóäà áóäóò ïðî÷èòàíû äàííûå
eax = ñòàðòîâûé ñåêòîð (îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà
äëÿ read_sectors32, îòíîñèòåëüíî íà÷àëà äàííûõ
äëÿ read_sectors2)
cx = ÷èñëî ñåêòîðîâ (äîëæíî áûòü áîëüøå íóëÿ)
íà âûõîäå: es:bx óêàçûâàåò íà êîíåö áóôåðà, â êîòîðûé áûëè ïðî÷èòàíû äàííûå
ñòàðøèå ñëîâà 32-áèòíûõ ðåãèñòðîâ ìîãóò ðàçðóøèòüñÿ
0. Åñëè âûçûâàåòñÿ read_sectors2, îíà ïåðåâîäèò óêàçàííûé åé íîìåð ñåêòîðà
â íîìåð îòíîñèòåëüíî íà÷àëà ëîãè÷åñêîãî äèñêà, ïðèáàâëÿÿ íîìåð ñåêòîðà
íà÷àëà äàííûõ, õðàíÿùèéñÿ â ñòåêå êàê [bp-10].
1. Ïåðåâîäèò ñòàðòîâûé ñåêòîð (îòñ÷èòûâàåìûé îò íà÷àëà òîìà) â ñåêòîð íà
óñòðîéñòâå, ïðèáàâëÿÿ çíà÷åíèå ñîîòâåòñòâóþùåãî ïîëÿ èç BPB.
2.  öèêëå (øàãè 3-6) ÷èòàåò ñåêòîðû, ñëåäèò çà òåì, ÷òîáû íà êàæäîé èòåðàöèè
CHS-âåðñèÿ: âñå ÷èòàåìûå ñåêòîðû áûëè íà îäíîé äîðîæêå.
LBA-âåðñèÿ: ÷èñëî ÷èòàåìûõ ñåêòîðîâ íå ïðåâîñõîäèëî 7Fh (òðåáîâàíèå
ñïåöèôèêàöèè EDD BIOS).
CHS-âåðñèÿ:
3. Ïåðåâîäèò àáñîëþòíûé íîìåð ñåêòîðà â CHS-ñèñòåìó: ñåêòîð ðàññ÷èòûâàåòñÿ êàê
åäèíèöà ïëþñ îñòàòîê îò äåëåíèÿ àáñîëþòíîãî íîìåðà íà ÷èñëî ñåêòîðîâ
íà äîðîæêå; äîðîæêà ðàññ÷èòûâàåòñÿ êàê îñòàòîê îò äåëåíèÿ ÷àñòíîãî,
ïîëó÷åííîãî íà ïðåäûäóùåì øàãå, íà ÷èñëî äîðîæåê, à öèëèíäð - êàê
÷àñòíîå îò ýòîãî æå äåëåíèÿ. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå,
÷åì ÷èñëî ñåêòîðîâ äî êîíöà äîðîæêè, óìåíüøàåò ÷èñëî ñåêòîðîâ äëÿ
÷òåíèÿ.
4. Ôîðìèðóåò äàííûå äëÿ âûçîâà int 13h (ah=2 - ÷òåíèå, al=÷èñëî ñåêòîðîâ,
dh=ãîëîâêà, (ìëàäøèå 6 áèò cl)=ñåêòîð,
(ñòàðøèå 2 áèòà cl è âåñü ch)=äîðîæêà, dl=äèñê, es:bx->áóôåð).
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, âûïîëíÿåò ñáðîñ äèñêà
è ïîâòîðÿåò ïîïûòêó ÷òåíèÿ, âñåãî äåëàåòñÿ íå áîëåå òð¸õ ïîïûòîê
(íåñêîëüêî ïîïûòîê íóæíî â ñëó÷àå äèñêåòû äëÿ ãàðàíòèè òîãî, ÷òî
ìîòîð ðàñêðóòèëñÿ). Åñëè âñå òðè ðàçà ïðîèñõîäèò îøèáêà ÷òåíèÿ,
ïåðåõîäèò íà êîä îáðàáîòêè îøèáîê ñ ñîîáùåíèåì "Read error".
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3.
LBA-âåðñèÿ:
3. Åñëè ÷èñëî ñåêòîðîâ äëÿ ÷òåíèÿ áîëüøå 7Fh, óìåíüøàåò åãî (äëÿ òåêóùåé
èòåðàöèè) äî 7Fh.
4. Ôîðìèðóåò â ñòåêå ïàêåò äëÿ int 13h (êëàä¸ò âñå íóæíûå äàííûå êîìàíäàìè
push, ïðè÷¸ì â îáðàòíîì ïîðÿäêå: ñòåê - ñòðóêòóðà LIFO, è äàííûå â
ñòåêå õðàíÿòñÿ â îáðàòíîì ïîðÿäêå ïî îòíîøåíèþ ê òîìó, êàê èõ òóäà
êëàëè).
5. Âûçûâàåò BIOS. Åñëè BIOS ðàïîðòóåò îá îøèáêå, ïåðåõîäèò íà êîä îáðàáîòêè
îøèáîê ñ ñîîáùåíèåì "Read error". Î÷èùàåò ñòåê îò ïàêåòà,
ñôîðìèðîâàííîãî íà ïðåäûäóùåì øàãå.
6.  ñîîòâåòñòâèè ñ ÷èñëîì ïðî÷èòàííûõ íà òåêóùåé èòåðàöèè ñåêòîðîâ
êîððåêòèðóåò òåêóùèé ñåêòîð, ÷èñëî îñòàâøèõñÿ ñåêòîðîâ è óêàçàòåëü íà
áóôåð (â ïàðå es:bx êîððåêòèðóåòñÿ es). Åñëè âñ¸ ïðî÷èòàíî, çàêàí÷èâàåò
ðàáîòó, èíà÷å âîçâðàùàåòñÿ íà øàã 3.
 
Ïðîöåäóðà ïîèñêà ýëåìåíòà â ïàïêå (lookup_in_dir):
íà âõîäå äîëæíî áûòü óñòàíîâëåíî:
ss:bp = 0:7C00
ds:si = óêàçàòåëü íà èìÿ ôàéëà â ôîðìàòå FAT (ñì. âûøå)
eax = íà÷àëüíûé êëàñòåð ïàïêè
bx = 0
íà âûõîäå: ôëàã CF îïðåäåëÿåò, óäàëîñü ëè íàéòè ôàéë; åñëè óäàëîñü, òî
CF ñáðîøåí è es:di óêàçûâàåò íà ýëåìåíò ïàïêè
 öèêëå ñ÷èòûâàåò êëàñòåðû ïàïêè è èùåò çàïðîøåííûé ýëåìåíò â ïðî÷èòàííûõ
äàííûõ. Äëÿ ÷òåíèÿ êëàñòåðà èñïîëüçóåò óæå îïèñàííóþ ïðîöåäóðó read_clusters,
äëÿ ïðîäâèæåíèÿ ïî öåïî÷êå êëàñòåðîâ - îïèñàííóþ äàëåå ïðîöåäóðó
get_next_clusters. Äàííûå ÷èòàþòñÿ â îáëàñòü ïàìÿòè, íà÷èíàþùóþñÿ ñ àäðåñà
8000:0000, ïðè ýòîì ïåðâûå 2000h áàéò èç äàííûõ ïàïêè (ìîæåò áûòü, ìåíüøå,
åñëè ÷òåíèå ïðåðâ¸òñÿ ðàíüøå) íå ïåðåêðûâàþòñÿ ïîñëåäóþùèìè ÷òåíèÿìè
(ýòî áóäåò èñïîëüçîâàíî ïîçäíåå, â ñèñòåìå êýøèðîâàíèÿ èç kordldr.f32).
Âûõîä îñóùåñòâëÿåòñÿ â ëþáîì èç ñëåäóþùèõ ñëó÷àåâ: íàéäåí çàïðîøåííûé ýëåìåíò;
êîí÷èëèñü ýëåìåíòû â ïàïêå (ïåðâûé áàéò î÷åðåäíîãî ýëåìåíòà íóëåâîé);
êîí÷èëèñü äàííûå ïàïêè â ñîîòâåòñòâèè ñ öåïî÷êîé êëàñòåðîâ èç FAT.
 
Ïðîöåäóðà âûâîäà íà ýêðàí ASCIIZ-ñòðîêè (out_string):
íà âõîäå: ds:si -> ñòðîêà
 öèêëå, ïîêà íå äîñòèãíóò çàâåðøàþùèé íîëü, âûçûâàåò ôóíêöèþ int 10h/ah=0Eh.
 
=====================================================================
 
Ðàáîòà âñïîìîãàòåëüíîãî çàãðóç÷èêà kordldr.f32:
1. Îïðåäåëÿåò, áûë ëè îí çàãðóæåí CHS- èëè LBA-âåðñèåé áóòñåêòîðà.
 çàâèñèìîñòè îò ýòîãî óñòàíàâëèâàåò ñìåùåíèÿ èñïîëüçóåìûõ ïðîöåäóð
áóòñåêòîðà. Êðèòåðèé ïðîâåðêè: â CHS-âåðñèè ïî àäðåñó err íàõîäèòñÿ
áàéò 0xE8 (ìàøèííàÿ êîìàíäà call), â LBA-âåðñèè ïî òîìó æå àäðåñó
íàõîäèòñÿ áàéò 0x14, à àäðåñ ïðîöåäóðû err äðóãîé.
2. Óçíà¸ò ðàçìåð ñâîáîäíîé áàçîâîé ïàìÿòè (ò.å. ñâîáîäíîãî íåïðåðûâíîãî êóñêà
àäðåñîâ ïàìÿòè, íà÷èíàþùåãîñÿ ñ 0) âûçîâîì int 12h.  ñîîòâåòñòâèè ñ
íèì âû÷èñëÿåò ÷èñëî ýëåìåíòîâ â êýøå ïàïîê. Õîòÿ áû äëÿ îäíîãî ýëåìåíòà
ìåñòî äîëæíî áûòü, îòñþäà îãðàíè÷åíèå â 592 Kb (94000h áàéò).
Çàìå÷àíèå: ýòîò ðàçìåð íå ìîæåò ïðåâîñõîäèòü 0A0000h áàéò è
íà ïðàêòèêå îêàçûâàåòñÿ íåìíîãî (íà 1-2 êèëîáàéòà) ìåíüøèì èç-çà
íàëè÷èÿ äîïîëíèòåëüíîé îáëàñòè äàííûõ BIOS "ââåðõó" áàçîâîé ïàìÿòè.
3. Èíèöèàëèçèðóåò êýøèðîâàíèå ïàïîê. Áóòñåêòîð óæå çàãðóçèë êàêóþ-òî ÷àñòü
äàííûõ êîðíåâîé ïàïêè; êîïèðóåò çàãðóæåííûå äàííûå â êýø è çàïîìèíàåò,
÷òî â êýøå åñòü êîðíåâàÿ ïàïêà.
4. Èíèöèàëèçèðóåò êýøèðîâàíèå FAT. Áóòñåêòîð èìååò äåëî ñ FAT â òîì è òîëüêî
òîì ñëó÷àå, êîãäà åìó ïðèõîäèòñÿ çàãðóæàòü äàííûå êîðíåâîé ïàïêè,
íå ïîìåñòèâøèåñÿ â îäèí êëàñòåð.  ýòîì ñëó÷àå â ïàìÿòè ïðèñóòñòâóåò
îäèí ñåêòîð FAT (åñëè áûëî íåñêîëüêî îáðàùåíèé - ïîñëåäíèé èç
èñïîëüçîâàííûõ).
5. Åñëè êëàñòåð ðàâåí ñåêòîðó, òî áóòñåêòîð çàãðóçèë òîëüêî ÷àñòü ôàéëà
kordldr.f32, è çàãðóç÷èê ïîäãðóæàåò âòîðóþ ñâîþ ÷àñòü, èñïîëüçóÿ
çíà÷åíèÿ ðåãèñòðîâ íà âõîäå â kordldr.f32.
6. Çàãðóæàåò âòîðè÷íûé çàãðóç÷èê kord/loader ïî àäðåñó 1000:0000. Åñëè ôàéë íå
íàéäåí, èëè îêàçàëñÿ ïàïêîé, èëè îêàçàëñÿ ñëèøêîì áîëüøèì, òî ïåðåõîäèò
íà êîä îáðàáîòêè îøèáîê èç áóòñåêòîðà ñ ñîîáùåíèåì
"Fatal error: cannot load the secondary loader".
Çàìå÷àíèå: íà ýòîì ýòàïå èìÿ ôàéëà óæå ìîæíî óêàçûâàòü âìåñòå ñ ïóò¸ì
è â ôîðìàòå ASCIIZ, õîòÿ ïîääåðæêè äëèííûõ èì¸í è íåàíãëèéñêèõ ñèìâîëîâ
ïî-ïðåæíåìó íåò.
7. Èçìåíÿåò êîä îáðàáîòêè îøèáîê áóòñåêòîðà íà ïåðåõîä íà ìåòêó hooked_err.
Ýòî íóæíî, ÷òîáû ïîñëåäóþùèå îáðàùåíèÿ ê êîäó áóòñåêòîðà â ñëó÷àå
îøèáîê ÷òåíèÿ íå âûâîäèë ñîîòâåòñòâóþùåå ñîîáùåíèå ñ ïîñëåäóþùåé
ïåðåçàãðóçêîé, à ðàïîðòîâàë îá îøèáêå ÷òåíèÿ, êîòîðóþ ìîãëî áû
êàê-íèáóäü îáðàáîòàòü ÿäðî.
8. Åñëè çàãðóçî÷íûé äèñê èìååò èäåíòèôèêàòîð ìåíüøå 0x80,
òî óñòàíàâëèâàåò al='f' ("floppy"), ah=èäåíòèôèêàòîð äèñêà,
èíà÷å al='h' ("hard"), ah=èäåíòèôèêàòîð äèñêà-0x80 (íîìåð äèñêà).
(Ãîâîðèòå, äèñêåòîê ñ FAT32 íå áûâàåò?  ÷¸ì-òî Âû ïðàâû... íî
óâåðåíû ëè Âû, ÷òî íåò çàãðóçî÷íûõ óñòðîéñòâ, ïîäîáíûõ äèñêåòàì,
íî áîëüøåãî ðàçìåðà, è äëÿ êîòîðûõ BIOS-èäåíòèôèêàòîð ìåíüøå 0x80?)
Óñòàíàâëèâàåò bx='32' (òèï ôàéëîâîé ñèñòåìû - FAT32).
Óñòàíàâëèâàåò si=ñìåùåíèå ôóíêöèè îáðàòíîãî âûçîâà. Ïîñêîëüêó â ýòîò
ìîìåíò ds=0, òî ds:si îáðàçóþò ïîëíûé àäðåñ.
9. Ïåðåäà¸ò óïðàâëåíèå ïî àäðåñó 1000:0000.
 
Ôóíêöèÿ îáðàòíîãî âûçîâà äëÿ âòîðè÷íîãî çàãðóç÷èêà:
ïðåäîñòàâëÿåò âîçìîæíîñòü ÷òåíèÿ ôàéëà.
Âõîä è âûõîä îïèñàíû â ñïåöèôèêàöèè íà çàãðóç÷èê.
1. Ñîõðàíÿåò ñòåê âûçûâàþùåãî êîäà è óñòàíàâëèâàåò ñâîé ñòåê:
ss:sp = 0:(7C00-10), bp=7C00: ïàðà ss:bp ïðè ðàáîòå ñ îñòàëüíûì
êîäîì äîëæíà óêàçûâàòü íà 0:7C00, à -10 áåð¸òñÿ îò òîãî, ÷òî
èíèöèàëèçèðóþùèé êîä áóòñåêòîðà óæå ïîìåñòèë â ñòåê 10 áàéò ïàðàìåòðîâ,
è îíè äîëæíû ñîõðàíÿòüñÿ â íåèçìåííîñòè. (Çíà÷åíèå [ebp-14],
"òåêóùèé ñåêòîð, íàõîäÿùèéñÿ â êýøå FAT", íå èñïîëüçóåòñÿ ïîñëå
èíèöèàëèçàöèè êýøèðîâàíèÿ â kordldr.f32.)
2. Ðàçáèðàåò ïåðåäàííûå ïàðàìåòðû è âûçûâàåò íóæíóþ èç âñïîìîãàòåëüíûõ
ïðîöåäóð (çàãðóçêè ôàéëà ëèáî ïðîäîëæåíèÿ çàãðóçêè ôàéëà).
3. Âîññòàíàâëèâàåò ñòåê âûçûâàþùåãî êîäà è âîçâðàùàåò óïðàâëåíèå.
 
Âñïîìîãàòåëüíûå ïðîöåäóðû kordldr.f32.
Ïðîöåäóðà ïîëó÷åíèÿ ñëåäóþùåãî êëàñòåðà â FAT (get_next_cluster):
1. Âû÷èñëÿåò íîìåð ñåêòîðà â FAT, â êîòîðîì íàõîäèòñÿ çàïðîøåííûé ýëåìåíò.
(Â ñåêòîðå 0x200 áàéò, êàæäûé âõîä çàíèìàåò 4 áàéòà.)
2. Ïðîâåðÿåò, åñòü ëè ñåêòîð â êýøå. Åñëè åñòü, ïðîïóñêàåò øàãè 3 è 4.
3. Åñëè íåò, òî â êýø íóæíî âñòàâèòü íîâûé ýëåìåíò. Åñëè êýø åù¸ íå çàïîëíåí,
âûäåëÿåò î÷åðåäíîé ýëåìåíò â êîíöå êýøà. Åñëè çàïîëíåí, óäàëÿåò
ñàìûé ñòàðûé ýëåìåíò (òîò, ê êîòîðîìó äîëüøå âñåãî íå áûëî îáðàùåíèé);
äëÿ òîãî, ÷òîáû îòñëåæèâàòü ïîðÿäîê ýëåìåíòîâ ïî âðåìåíè ïîñëåäíåãî
îáðàùåíèÿ, âñå (âûäåëåííûå) ýëåìåíòû êýøà ñâÿçàíû â äâóñâÿçíûé ñïèñîê,
â êîòîðîì ïåðâûì ýëåìåíòîì ÿâëÿåòñÿ ñàìûé ñòàðûé, à ññûëêè âïåð¸ä
óêàçûâàþò íà ñëåäóþùèé ïî âðåìåíè ïîñëåäíåãî îáðàùåíèÿ.
4. ×èòàåò ñîîòâåòñòâóþùèé ñåêòîð FAT ñ äèñêà.
5. Êîððåêòèðóåò ñïèñîê: òåêóùèé îáðàáàòûâàåìûé ýëåìåíò óäàëÿåòñÿ ñ òîé ïîçèöèè,
ãäå îí íàõîäèòñÿ, è äîáàâëÿåòñÿ â êîíåö. ( ñëó÷àå ñî ñâåæåäîáàâëåííûìè
â êýø ýëåìåíòàìè óäàëåíèÿ íå äåëàåòñÿ, ïîñêîëüêó èõ â ñïèñêå åù¸ íåò.)
6. Ñ÷èòûâàåò íóæíûé âõîä â FAT, ñáðàñûâàÿ ñòàðøèå 4 áèòà.
7. Ñðàâíèâàåò ïðî÷èòàííîå çíà÷åíèå ñ ïðåäåëîì: åñëè îíî ñòðîãî ìåíüøå
0x0FFFFFF7, òî îíî çàäà¸ò íîìåð ñëåäóþùåãî êëàñòåðà â öåïî÷êå;
â ïðîòèâíîì ñëó÷àå öåïî÷êà çàêîí÷èëàñü.
 
Ïðîöåäóðà çàãðóçêè ôàéëà (load_file):
1. Òåêóùàÿ ðàññìàòðèâàåìàÿ ïàïêà - êîðíåâàÿ. Â öèêëå âûïîëíÿåò øàãè 2-4.
2. Êîíâåðòèðóåò èìÿ òåêóùåãî ðàññìàòðèâàåìîãî êîìïîíåíòà èìåíè (êîìïîíåíòû
ðàçäåëÿþòñÿ ñèìâîëîì '/') â FAT-ôîðìàò 8+3. Åñëè ýòî íåâîçìîæíî
(áîëüøå 8 ñèìâîëîâ â èìåíè, áîëüøå 3 ñèìâîëîâ â ðàñøèðåíèè èëè
áîëüøå îäíîé òî÷êè), âîçâðàùàåòñÿ ñ îøèáêîé.
3. Èùåò ýëåìåíò ñ òàêèì èìåíåì â òåêóùåé ðàññìàòðèâàåìîé ïàïêå.
à) Ïðîâåðÿåò, åñòü ëè òàêàÿ ïàïêà â êýøå ïàïîê. (Èäåíòèôèêàöèÿ ïàïîê
îñóùåñòâëÿåòñÿ ïî íîìåðó íà÷àëüíîãî êëàñòåðà.) Åñëè òàêîé ïàïêè åù¸
íåò, äîáàâëÿåò å¸ â êýø; åñëè òîò ïåðåïîëíÿåòñÿ, âûêèäûâàåò ïàïêó,
ê êîòîðîé äîëüøå âñåãî íå áûëî îáðàùåíèé. (Äëÿ êàæäîãî ýëåìåíòà êýøà
õðàíèòñÿ ìåòêà îò 0 äî (ðàçìåð êýøà)-1, îïðåäåëÿþùàÿ åãî íîìåð ïðè
ñîðòèðîâêå ïî äàâíîñòè ïîñëåäíåãî îáðàùåíèÿ. Ïðè îáðàùåíèè ê êàêîìó-òî
ýëåìåíòó åãî ìåòêà ñòàíîâèòñÿ íóëåâîé, à òå ìåòêè, êîòîðûå ìåíüøå
ñòàðîãî çíà÷åíèÿ, óâåëè÷èâàþòñÿ íà åäèíèöó.)
á) Ïðîñìàòðèâàåò â ïîèñêàõ çàïðîøåííîãî èìåíè âñå ýëåìåíòû èç êýøà,
èñïîëüçóÿ ïðîöåäóðó èç áóòñåêòîðà. Åñëè îáíàðóæèâàåò èñêîìûé ýëåìåíò,
ïåðåõîäèò ê øàãó 4. Åñëè îáíàðóæèâàåò êîíåö ïàïêè, âîçâðàùàåòñÿ èç
ïðîöåäóðû ñ îøèáêîé.
â)  öèêëå ñ÷èòûâàåò ïàïêó ïîñåêòîðíî. Ïðè ýòîì ïðîïóñêàåò íà÷àëüíûå
ñåêòîðû, êîòîðûå óæå íàõîäÿòñÿ â êýøå è óæå áûëè ïðîñìîòðåíû. Êàæäûé
ïðî÷èòàííûé ñåêòîð êîïèðóåò â êýø, åñëè òàì åù¸ îñòà¸òñÿ ìåñòî,
è ïðîñìàòðèâàåò â í¸ì âñå ýëåìåíòû. Ðàáîòàåò, ïîêà íå ñëó÷èòñÿ îäíî èç
òð¸õ ñîáûòèé: íàéäåí èñêîìûé ýëåìåíò; êîí÷èëèñü êëàñòåðû (ñóäÿ ïî
öåïî÷êå êëàñòåðîâ â FAT); î÷åðåäíîé ýëåìåíò ïàïêè ñèãíàëèçèðóåò î êîíöå
(ïåðâûé áàéò íóëåâîé).  äâóõ ïîñëåäíèõ ñëó÷àÿõ âîçâðàùàåòñÿ ñ îøèáêîé.
4. Ïðîâåðÿåò òèï íàéäåííîãî ýëåìåíòà (ôàéë/ïàïêà): ïîñëåäíèé ýëåìåíò â
çàïðîøåííîì èìåíè äîëæåí áûòü ôàéëîì, âñå ïðîìåæóòî÷íûå - ïàïêàìè.
Åñëè òåêóùèé êîìïîíåíò èìåíè - ïðîìåæóòî÷íûé, ïðîäâèãàåò òåêóùóþ
ðàññìàòðèâàåìóþ ïàïêó è âîçâðàùàåòñÿ ê ïóíêòó 2.
5. Ïðîõîäèò ïî öåïî÷êå êëàñòåðîâ â FAT è ñ÷èòûâàåò âñå êëàñòåðû â óêàçàííûé
ïðè âûçîâå áóôåð ïîñëåäîâàòåëüíûìè âûçîâàìè ôóíêöèè áóòñåêòîðà;
ïðè ýòîì åñëè íåñêîëüêî êëàñòåðîâ ôàéëà ðàñïîëîæåíû íà äèñêå
ïîñëåäîâàòåëüíî, òî èõ ÷òåíèå îáúåäèíÿåòñÿ â îäíó îïåðàöèþ.
Ñëåäèò çà òåì, ÷òîáû íå ïðåâûñèòü óêàçàííûé ïðè âûçîâå ïðîöåäóðû
ëèìèò ÷èñëà ñåêòîðîâ äëÿ ÷òåíèÿ.
 
Ïðîöåäóðà ïðîäîëæåíèÿ çàãðóçêè ôàéëà (continue_load_file): âñòðîåíà
âíóòðü øàãà 5 load_file; çàãðóæàåò â ðåãèñòðû íóæíûå çíà÷åíèÿ (ðàíåå
ñîõðàí¸ííûå èç load_file) è ïðîäîëæàåò øàã 5.
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/fat32
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot/PrimaryLoader.txt
0,0 → 1,91
; Copyright (c) 2008-2009, diamond
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
Ñïåöèôèêàöèÿ íà ïåðâè÷íûé çàãðóç÷èê KordOS.
Çàãðóç÷èê äîëæåí ïðåäîñòàâëÿòü ñëåäóþùèå ñåðâèñû:
1. Ïðè çàãðóçêå êîìïüþòåðà, ïîëó÷èâ óïðàâëåíèå îò BIOS'à, çàãðóæàòü
ôàéë loader èç ïàïêè kord ïî àäðåñó 1000:0000.
Ðàçìåð ôàéëà loader íå ïðåâîñõîäèò 30000h = 192 Kb.
2. Ïðè ýòîì óñòàíàâëèâàòü ñëåäóþùèå ðåãèñòðû:
ax èäåíòèôèöèðóåò óñòðîéñòâî:
al = òèï:
'f' - ôëîïèê
'h' - HDD
'c' - CD/DVD
'u' - USB ôëåøêà
'?' - íåèçâåñòíîå óñòðîéñòâî
ah = íîìåð óñòðîéñòâà (ñðåäè âñåõ óñòðîéñòâ ôèêñèðîâàííîãî òèïà)
bx = òèï ôàéëîâîé ñèñòåìû:
'12' = FAT12
'16' = FAT16
'32' = FAT32
'nt' = NTFS
'is' = ISO-9660
ds:si = far-óêàçàòåëü íà callback-ñåðâèñ
3. Ïðåäîñòàâëÿòü callback-ñåðâèñ äëÿ âòîðè÷íîãî çàãðóç÷èêà - far-ïðîöåäóðó:
íà âõîäå: ax = çàïðàøèâàåìàÿ ôóíêöèÿ
íà âûõîäå: CF=1, åñëè ôóíêöèÿ íå ïîääåðæèâàåòñÿ; CF=0 èíà÷å
Çàãðóç÷èê ìîæåò ðàçðóøàòü âñå ðåãèñòðû, âêëþ÷àÿ ñåãìåíòíûå,
çà èñêëþ÷åíèåì ss è sp.
4. Âñåãäà äîëæíà ïîääåðæèâàòüñÿ callback-ôóíêöèÿ 1:
íàçíà÷åíèå: ïðî÷èòàòü ôàéë, ðàñïîëîæåííûé íà çàãðóçî÷íîì óñòðîéñòâå
íà âõîäå: ax = 1, ds:di = óêàçàòåëü íà èíôîðìàöèîííóþ ñòðóêòóðó:
dw:dw far-óêàçàòåëü íà áóôåð,
ïåðâîå ñëîâî - ñìåùåíèå, âòîðîå - ñåãìåíò
dw ìàêñèìàëüíîå ÷èñëî 4Kb-áëîêîâ äëÿ ÷òåíèÿ (0x1000 áàéò)
äîëæíî áûòü íåíóëåâûì è ñòðîãî ìåíüøå 0x100
ASCIIZ èìÿ ôàéëà â ôîðìàòå "<ïàïêà1>/<ïàïêà2>/<ôàéë>"
Åñëè èìÿ ôàéëà ñîäåðæèò ñèìâîëû èç ñòàðøåé ïîëîâèíû
ASCIIZ-òàáëèöû èëè íå ÿâëÿåòñÿ 8.3-èìåíåì (â ñìûñëå, îäíà èç êîìïîíåíò
èìåíè ôàéëà èìååò èìÿ äëèííåå 8 ñèìâîëîâ èëè ðàñøèðåíèå äëèííåå 3),
çàãðóç÷èê ìîæåò íå íàéòè òàêîé ôàéë, äàæå åñëè îí åñòü
(à ìîæåò è íàéòè).
íà âûõîäå: bx = ñòàòóñ:
0 = óñïåøíî
1 = ôàéë îêàçàëñÿ ñëèøêîì áîëüøèì, áóôåð çàïîëíåí öåëèêîì
è åñòü åù¸ äàííûå ôàéëà
2 = ôàéë íå íàéäåí
3 = ïðîèçîøëà îøèáêà ÷òåíèÿ
dx:ax = ðàçìåð ôàéëà èëè FFFF:FFFF, åñëè ôàéë íå íàéäåí
5. Âñåãäà äîëæíà ïîääåðæèâàòüñÿ callback-ôóíêöèÿ 2:
íàçíà÷åíèå: ïðîäîëæèòü ÷òåíèå ôàéëà, ÷àñòè÷íî çàãðóæåííîãî ôóíêöèåé 1
íà âõîäå: ax = 2, ds:di = óêàçàòåëü íà èíôîðìàöèîííóþ ñòðóêòóðó:
dw:dw far-óêàçàòåëü íà áóôåð,
ïåðâîå ñëîâî - ñìåùåíèå, âòîðîå - ñåãìåíò
dw ìàêñèìàëüíîå ÷èñëî 4Kb-áëîêîâ äëÿ ÷òåíèÿ (0x1000 áàéò)
äîëæíî áûòü íåíóëåâûì è ñòðîãî ìåíüøå 0x100
íà âûõîäå: bx = ñòàòóñ:
0 = óñïåøíî
1 = ôàéë îêàçàëñÿ ñëèøêîì áîëüøèì, áóôåð çàïîëíåí öåëèêîì
è åñòü åù¸ äàííûå ôàéëà
3 = ïðîèçîøëà îøèáêà ÷òåíèÿ
dx:ax = ðàçìåð ôàéëà
Ôóíêöèþ ìîæíî âûçûâàòü òîëüêî â ñëó÷àå, êîãäà ïîñëåäíèé âûçîâ ôóíêöèè
1 è âñå ïîñëåäóþùèå âûçîâû ôóíêöèè 2 âåðíóëè bx=1 (èíûìè ñëîâàìè,
òîëüêî äëÿ ïðîäîëæåíèÿ çàãðóçêè ôàéëà, êîòîðûé óæå áûë ÷àñòè÷íî
çàãðóæåí, íî åù¸ íå çàãðóæåí ïîëíîñòüþ).
Çàãðóç÷èê ìîæåò áûòü óâåðåí, ÷òî äàííûå â îáëàñòÿõ ïàìÿòè 0-9000 è
60000-A0000 íå áóäóò ìîäèôèöèðîâàíû ÿäðîì.
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/kernel/branches/Kolibri-acpi/sec_loader/trunk/boot_st.inc
0,0 → 1,68
; Copyright (c) 2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
;======================================================================
;
; BOOT DATA
;
;======================================================================
 
 
version db 'Secondary Loader v 0.010',0
version_end:
 
select_section db 'Select section:'
select_section_end:
section_description db 'Section description:'
section_description_end:
soft_mes db 'Soft (c) 2008-2009'
soft_mes_end:
 
badprocessor db '>Fatal - CPU 586+ required.',0
error_ini_f1 db '>Error: cannot load ini file, buffer is full',0
error_ini_f2 db '>Error: ini file not found',0
error_ini_f3 db '>Error: cannot read ini file',0
error_ini_nf db '>Error: unrecognized error when loading ini file',0
not_found_sec_loader db '>Not found section [loader]',0
not_found_def_sect db '>Not found value default in section [loader]',0
default_eq_loader db '>Error in section [loader] parametr default=loader',0
found_equal_default db '>Found equal parametr default will be use first value',0
found_equal_timeout db '>Found equal parametr timeout will be use first value',0
set_default_timeout_val db '>Section timeout has incorrect value, will be use default value',0
error_ini_common db ">I will use predefined settings and try to boot. Let's hope for the best..."
db 13,10,"Press any key to continue...",0
load_ini db '>Ini file loaded successfully',0
parse_ini_end db '>End parsing ini file',0
point_to_default_sec_not_found db '>Point to default section is not found in ini file',0
incorect_section_define db ">Incorect section define not found ']'",0
default_section_name db '"Section unname"'
 
start_msg db "Press any key to change default section, press [Enter] to continue booting"
start_msg_e:
time_msg db "or wait 4 seconds before default continuation"
time_msg_e:
time_str db "seconds before default continuation"
time_str_e:
/kernel/branches/Kolibri-acpi/sec_loader/trunk/listing.inc
0,0 → 1,635
; Listing generator
; LocoDelAssembly 2007.06.01
 
INSTRUCTIONS equ bt in ja jb jc je jg jl jo jp js jz or \
aaa aad aam aas adc add and bsf bsr btc btr bts cbw cdq clc \
cld cli cmc cmp cqo cwd daa das dec div fld fst hlt inc ins \
int jae jbe jge jle jmp jna jnb jnc jne jng jnl jno jnp jns \
jnz jpe jpo lar lds lea les lfs lgs lsl lss ltr mov mul neg \
nop not out pop por rcl rcr ret rol ror rsm sal sar sbb shl \
shr stc std sti str sub ud2 xor \
arpl call cdqe clgi clts cmps cwde emms fabs fadd fbld fchs \
fcom fcos fdiv feni fild fist fld1 fldz fmul fnop fsin fstp \
fsub ftst fxam fxch idiv imul insb insd insw int1 int3 into \
invd iret jcxz jnae jnbe jnge jnle lahf lgdt lidt lldt lmsw \
lods loop movd movq movs orpd orps outs pand popa popd popf \
popq popw push pxor retd retf retn retq retw sahf salc scas \
seta setb setc sete setg setl seto setp sets setz sgdt shld \
shrd sidt sldt smsw stgi stos test verr verw wait xadd xchg \
xlat \
addpd addps addsd addss andpd andps bound bswap cmova cmovb \
cmovc cmove cmovg cmovl cmovo cmovp cmovs cmovz cmppd cmpps \
cmpsb cmpsd cmpsq cmpss cmpsw cpuid divpd divps divsd divss \
enter f2xm1 faddp fbstp fclex fcomi fcomp fdisi fdivp fdivr \
femms ffree fiadd ficom fidiv fimul finit fistp fisub fldcw \
fldpi fmulp fneni fprem fptan fsave fsqrt fstcw fstsw fsubp \
fsubr fucom fwait fyl2x icebp iretd iretq iretw jecxz jrcxz \
lddqu leave lodsb lodsd lodsq lodsw loopd loope loopq loopw \
loopz maxpd maxps maxsd maxss minpd minps minsd minss movsb \
movsd movsq movss movsw movsx movzx mulpd mulps mulsd mulss \
mwait outsb outsd outsw pabsb pabsd pabsw paddb paddd paddq \
paddw pandn pause pavgb pavgw pf2id pf2iw pfacc pfadd pfmax \
pfmin pfmul pfrcp pfsub pi2fd pi2fw popad popaw popfd popfq \
popfw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb \
psubd psubq psubw pusha pushd pushf pushq pushw rcpps rcpss \
rdmsr rdpmc rdtsc retfd retfq retfw retnd retnq retnw scasb \
scasd scasq scasw setae setbe setge setle setna setnb setnc \
setne setng setnl setno setnp setns setnz setpe setpo stosb \
stosd stosq stosw subpd subps subsd subss vmrun vmxon wrmsr \
xlatb xorpd xorps \
andnpd andnps cmovae cmovbe cmovge cmovle cmovna cmovnb cmovnc\
cmovne cmovng cmovnl cmovno cmovnp cmovns cmovnz cmovpe cmovpo\
comisd comiss fcmovb fcmove fcmovu fcomip fcompp fdivrp ffreep\
ficomp fidivr fisttp fisubr fldenv fldl2e fldl2t fldlg2 fldln2\
fnclex fndisi fninit fnsave fnstcw fnstsw fpatan fprem1 frstor\
frstpm fscale fsetpm fstenv fsubrp fucomi fucomp fxsave haddpd\
haddps hsubpd hsubps invlpg lfence looped loopeq loopew loopne\
loopnz loopzd loopzq loopzw mfence movapd movaps movdqa movdqu\
movhpd movhps movlpd movlps movnti movntq movsxd movupd movups\
paddsb paddsw pextrw pfnacc pfsubr phaddd phaddw phsubd phsubw\
pinsrw pmaxsw pmaxub pminsw pminub pmulhw pmullw psadbw pshufb\
pshufd pshufw psignb psignd psignw pslldq psrldq psubsb psubsw\
pswapd pushad pushaw pushfd pushfq pushfw rdmsrq rdtscp setalc\
setnae setnbe setnge setnle sfence shufpd shufps skinit sqrtpd\
sqrtps sqrtsd sqrtss swapgs sysret vmcall vmload vmread vmsave\
vmxoff wbinvd wrmsrq \
clflush cmovnae cmovnbe cmovnge cmovnle cmpeqpd cmpeqps \
cmpeqsd cmpeqss cmplepd cmpleps cmplesd cmpless cmpltpd \
cmpltps cmpltsd cmpltss cmpxchg fcmovbe fcmovnb fcmovne \
fcmovnu fdecstp fincstp fnstenv frndint fsincos fucomip \
fucompp fxrstor fxtract fyl2xp1 invlpga ldmxcsr loopned \
loopneq loopnew loopnzd loopnzq loopnzw monitor movddup \
movdq2q movhlps movlhps movntdq movntpd movntps movq2dq \
paddusb paddusw palignr pavgusb pcmpeqb pcmpeqd pcmpeqw \
pcmpgtb pcmpgtd pcmpgtw pfcmpeq pfcmpge pfcmpgt pfpnacc \
pfrsqrt phaddsw phsubsw pmaddwd pmulhrw pmulhuw pmuludq \
pshufhw pshuflw psubusb psubusw rsqrtps rsqrtss stmxcsr \
syscall sysexit sysretq ucomisd ucomiss vmclear vmmcall \
vmptrld vmptrst vmwrite \
addsubpd addsubps cmpneqpd cmpneqps cmpneqsd cmpneqss cmpnlepd\
cmpnleps cmpnlesd cmpnless cmpnltpd cmpnltps cmpnltsd cmpnltss\
cmpordpd cmpordps cmpordsd cmpordss cvtdq2pd cvtdq2ps cvtpd2dq\
cvtpd2pi cvtpd2ps cvtpi2pd cvtpi2ps cvtps2dq cvtps2pd cvtps2pi\
cvtsd2si cvtsd2ss cvtsi2sd cvtsi2ss cvtss2sd cvtss2si fcmovnbe\
maskmovq movmskpd movmskps movshdup movsldup packssdw packsswb\
packuswb pfrcpit1 pfrcpit2 pfrsqit1 pmovmskb pmulhrsw prefetch\
sysenter sysexitq unpckhpd unpckhps unpcklpd unpcklps vmlaunch\
vmresume \
cmpxchg8b cvttpd2dq cvttpd2pi cvttps2dq cvttps2pi cvttsd2si \
cvttss2si pmaddubsw prefetchw punpckhbw punpckhdq punpckhwd \
punpcklbw punpckldq punpcklwd \
cmpunordpd cmpunordps cmpunordsd cmpunordss cmpxchg16b \
loadall286 loadall386 maskmovdqu prefetcht0 prefetcht1 \
prefetcht2 punpckhqdq punpcklqdq prefetchnta
 
PREFIXES equ rep lock repe repz repne repnz
 
DATA_DEFINITORS equ db dw du dd dp df dq dt file
DATA_RESERVERS equ rb rw rd rp rf rq rt
 
CRLF equ 13, 10 ; Remove 13 for Linux
MAX_BYTES equ 13
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MODE MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
macro use16
{
use16
_USE = 16
}
 
macro use32
{
use32
_USE = 32
}
 
macro use64
{
use64
_USE = 64
}
 
macro detect_mode
{
local aux
 
_USE = 32
 
virtual at 0
xchg eax, eax
load aux byte from 0
 
if aux = $66
_USE = 16
else if aux = $87
_USE = 64
end if
end virtual
}
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISPLAYING MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
macro display_address address*
{
local aux, digit
 
aux = address
 
repeat _USE / 4
digit = aux shr (_USE - 4 * %) and $F
 
display digit + '0' + ('9' - 'B') and (9 - digit) shr 4 and $F
end repeat
 
display ': '
}
 
macro display_bytes pointer
{
local aux, size, digit
 
size = $ - pointer
 
if size > MAX_BYTES
size = MAX_BYTES
end if
 
repeat size
load aux byte from pointer+%-1
 
digit = aux shr 4
display digit + '0' + ('9' - 'B') and (9 - digit) shr 4 and $F
 
digit = aux and $F
display digit + '0' + ('9' - 'B') and (9 - digit) shr 4 and $F
 
 
display ' '
end repeat
 
repeat MAX_BYTES - size
display ' '
end repeat
}
 
; The macro below in some situations doesn't adds a space to separate things unfortunatelly, so for readability ensurance
; another one will be used instead...
;macro display_args [args]
;{
;common
; aux = 1
;
;forward
; if ~args eq
; if aux
; display ' '
; else
; display ', '
; end if
;
; aux = 0
;
; match =ON, _RESOLVE_EQUATES
; \{
; match args, args
; \\{
; irps arg, args
; \\\{
; display \\\`arg
; \\\}
; \\}
; \}
; match =OFF, _RESOLVE_EQUATES
; \{
; irps arg, args
; \\{
; display \\`arg
; \\}
;
; \}
; end if
;}
 
; This one separates everything with one space. A very ugly listing but at least you will not see things
; like "push ebxesiedi" nor "ret word0"
 
macro display_args [args]
{
common
aux = 1
 
forward
if ~args eq
if ~aux
display ','
end if
 
aux = 0
 
match =ON, _RESOLVE_EQUATES
\{
match args, args
\\{
if ~args eqtype ""
irps arg, args
\\\{
display ' ', \\\`arg
\\\}
else
display " '", args, "'"
end if
\\}
\}
match =OFF, _RESOLVE_EQUATES
\{
if ~args eqtype ""
irps arg, args
\\{
display ' ', \\`arg
\\}
else
display " '", args, "'"
end if
\}
end if
}
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;; INSTRUCTIONS & PREFIXES MACROSES ;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
macro prefix mnemonic
{
local aux
 
macro mnemonic [args]
\{
\common
match =1, _ON_VIRTUAL\\{_LISTING equ 0\\}
match =equ, args\\{_LISTING equ 0\\}
match =equ any, args\\{_LISTING equ 0\\}
 
match =1, _LISTING
\\{
display_address $
aux = $
\\}
 
mnemonic
 
match =1, _LISTING
\\{
display_bytes aux
 
display \`mnemonic
display CRLF
\\}
 
match =1, _ON_VIRTUAL\\{restore _LISTING\\}
match =equ, args\\{restore _LISTING\\}
match =equ any, args\\{restore _LISTING\\}
 
def_prefix mnemonic
args
purge mnemonic
\}
}
 
macro def_prefix mnemonic
{
macro def_prefix mnemonic
\{
prefix mnemonic
\}
def_prefix mnemonic
}
 
macro instruction mnemonic
{
local aux
 
macro mnemonic [args]
\{
\common
match =1, _ON_VIRTUAL\\{_LISTING equ 0\\}
match =equ, args\\{_LISTING equ 0\\}
match =equ any, args\\{_LISTING equ 0\\}
 
match =1, _LISTING
\\{
display_address $
aux = $
\\}
 
mnemonic args
 
match =1, _LISTING
\\{
display_bytes aux
 
display \`mnemonic
 
virtual at 0
db \`mnemonic
repeat 11 - $
display ' '
end repeat
end virtual
 
display_args args
display CRLF
\\}
 
match =1, _ON_VIRTUAL\\{restore _LISTING\\}
match =equ, args\\{restore _LISTING\\}
match =equ any, args\\{restore _LISTING\\}
\}
}
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DATA MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
macro data_define mnemonic
{
local aux
macro mnemonic [args]
\{
\common
match =1, _ON_VIRTUAL\\{_LISTING equ 0\\}
match =equ, args\\{_LISTING equ 0\\}
match =equ any, args\\{_LISTING equ 0\\}
 
match =1, _LISTING
\\{
display_address $
aux = $
\\}
 
mnemonic args
 
match =1, _LISTING
\\{
display_bytes aux
 
display \`mnemonic
 
display_args args
display CRLF
 
aux = aux + MAX_BYTES
 
repeat ($ - aux + MAX_BYTES - 1) / MAX_BYTES
display_address aux
display_bytes aux
display CRLF
 
aux = aux + MAX_BYTES
end repeat
\\}
 
match =1, _ON_VIRTUAL\\{restore _LISTING\\}
match =equ, args\\{restore _LISTING\\}
match =equ any, args\\{restore _LISTING\\}
\}
 
struc mnemonic [args]
\{
\common
match =1, _ON_VIRTUAL\\{_LISTING equ 0\\}
match =equ, args\\{_LISTING equ 0\\}
match =equ any, args\\{_LISTING equ 0\\}
 
match =1, _LISTING
\\{
display_address $
aux = $
\\}
 
. mnemonic args
 
match =1, _LISTING
\\{
display_bytes aux
 
display \`., ' ', \`mnemonic
 
display_args args
display CRLF
 
aux = aux + MAX_BYTES
 
repeat ($ - aux + MAX_BYTES - 1) / MAX_BYTES
display_address aux
display_bytes aux
display CRLF
 
aux = aux + MAX_BYTES
end repeat
\\}
 
match =1, _ON_VIRTUAL\\{restore _LISTING\\}
match =equ, args\\{restore _LISTING\\}
match =equ any, args\\{restore _LISTING\\}
\}
}
 
macro data_reserve mnemonic
{
local aux
macro mnemonic [args]
\{
\common
match =1, _ON_VIRTUAL\\{_LISTING equ 0\\}
match =equ, args\\{_LISTING equ 0\\}
match =equ any, args\\{_LISTING equ 0\\}
 
match =1, _LISTING
\\{
display_address $
aux = $
\\}
 
mnemonic args
 
match =1, _LISTING
\\{
times MAX_BYTES display ' '
 
display \`mnemonic
 
display_args args
display CRLF
\\}
 
match =1, _ON_VIRTUAL\\{restore _LISTING\\}
match =equ, args\\{restore _LISTING\\}
match =equ any, args\\{restore _LISTING\\}
\}
 
struc mnemonic [args]
\{
\common
match =1, _ON_VIRTUAL\\{_LISTING equ 0\\}
match =equ, args\\{_LISTING equ 0\\}
match =equ any, args\\{_LISTING equ 0\\}
 
match =1, _LISTING
\\{
display_address $
aux = $
\\}
 
. mnemonic args
 
match =1, _LISTING
\\{
times MAX_BYTES display ' '
 
display \`., ' ', \`mnemonic
 
display_args args
display CRLF
\\}
 
match =1, _ON_VIRTUAL\\{restore _LISTING\\}
match =equ, args\\{restore _LISTING\\}
match =equ any, args\\{restore _LISTING\\}
\}
}
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;; LISTING CONTROL MACROSES ;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
macro virtual [args]
{
common
_ON_VIRTUAL equ 1
 
virtual args
}
 
macro end [args]
{
common
match =virtual, args\{restore _ON_VIRTUAL\}
 
end args
}
 
macro enable_listing
{
detect_mode
 
match =0, _MACROSES_INSTALLED
\{
match instructions, INSTRUCTIONS
\\{
irps ins, instructions
\\\{
instruction ins
\\\}
\\}
 
match prefixes, PREFIXES
\\{
irps prefix, prefixes
\\\{
def_prefix prefix
\\\}
\\}
 
match data_definitors, DATA_DEFINITORS
\\{
irps def, data_definitors
\\\{
data_define def
\\\}
\\}
 
match data_reservers, DATA_RESERVERS
\\{
irps def, data_reservers
\\\{
data_reserve def
\\\}
\\}
\}
 
_MACROSES_INSTALLED equ 1
_LISTING equ 1
}
 
macro disable_listing
{
_LISTING equ 0
}
 
macro enable [feature*]
{
forward
UNKNOWN equ 1
 
match =resolve_equates, feature
\{
restore _RESOLVE_EQUATES
_RESOLVE_EQUATES equ ON
UNKNOWN equ 0
\}
 
match =listing, feature
\{
enable_listing
UNKNOWN equ 0
\}
 
match =1, UNKNOWN
\{
display 'ERROR: Unknown "',`feature, '" feature', 13, 10
err
\}
 
restore UNKNOWN
restore UNKNOWN
}
 
macro disable [feature*]
{
UNKNOWN equ 1
 
match =resolve_equates, feature
\{
restore _RESOLVE_EQUATES
_RESOLVE_EQUATES equ OFF
UNKNOWN equ 0
\}
 
match =listing, feature
\{
disable_listing
UNKNOWN equ 0
\}
 
match =1, UNKNOWN
\{
display 'ERROR: Unknown "',`feature, '" feature', 13, 10
err
\}
 
restore UNKNOWN
restore UNKNOWN
}
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INITIALIZATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
_MACROSES_INSTALLED equ 0
_ON_VIRTUAL equ 0
 
disable resolve_equates
/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse.inc
0,0 → 1,118
; Copyright (c) 2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
; Ìîäóëü ïàðñèíãà - ýòî ñòàíäàðòíûé êîìïîíåíò, âñòðàèâàåìûé âî âòîðè÷íûé çàãðóç÷èê.
; Äàííûé ìîäóëü ïîçâîëÿåò ñòàíäàðòíî ïðîèçâåñòè ðàçáîð ini ôàéëà
; (è ñ èñïîëüçîâàíèåì ïîëó÷åííûõ äàííûõ ÎÑ áóäåò çàãðóæàòüñÿ äàëüøå).
;  íà÷àëå íàéäåì îòêðûâàþùèé "[" - ýòî áóäåò óêàçûâàòü íà íà÷àëî
; ñåêöèè. Ïîääåðæèâàåòñÿ 1 ñåêöèÿ ýòî [loader], îñòàëüíûå ñåêöèè ìîãóò èìåòü
; ëþáûå èìåíà, íî îíè äîëæíû áûòü çàêëþ÷åíû â â ñêîáêè []
macro use_parse
{
;input cx=size of ini file
parse_start:
;es:di as 2000:0000 new segment
;óñòàíîâèì óêàçàòåëü íà çàãðóæåííûé áëîê
enter 256,0 ;set 16 byte for current task in stack
;we are is not use bp because bp is pointer on array 16 byte
mov word [save_bp_from_timer],bp ;save point to own data array
mov save_cx,cx ;it's placed size of ini file
les di,dword [file_data]
;îáíóëèì âñå ïåðåìåííûå âûäåëåííûå èç ñòåêà
;init flag
xor ax,ax
mov status_flag,ax
;set data size
mov info_real_mode_size,ini_data_ +0x1000 ;èçìåíèì çíà÷åíèå çàíÿòîñòè ïàìÿòè
 
;ïîèñê íà÷àëà áëîêà.
;///////////check [loader]
cld
 
mov ret_on_ch,.start ;set return
mov al,byte [es:di]
push word .first_ret
cmp al,' '
jz .first_sp_1
jmp get_firs_sym.not_space
.first_sp_1:
jmp get_firs_sym.first_sp
 
.start:
call get_firs_sym ;get first symbol on new line
.first_ret: ;ïåðâûé âîçâðàò
; jcxz .end_file ;.end_loader ;found or not found parametrs in section exit in section
test cx,cx
jz error.not_loader
cmp al,'['
jz .parse_loader
jmp .start
;////// ïðîâåðêà íà íàëè÷åå ñåêöèè loader
use_parse_loader
;pause
if DEBUG
xor ax,ax
int 16h
end if
;////// âûâîä ãðàôè÷åñêîãî ýêðàíà, âûáîð, ñåêöèè ïîä äåôîëòó
use_any_sec
;ïàðñèíã âûáðàíîé èëè äåôîëòíîé ñåêöèè ò.å. ðàçáîð ïàðàìåòðîâ âûïîëíåíèå ñöåíàðèÿ
use_parse_def_sect
 
;//////////////////
;/end parse block
;//////////////////
;.end_bl:
; mov cx,bx
;
; jmp .start
 
.exit:
 
; mov si,parse_ini_end
; call printplain
;
;if DEBUG
; pusha
; mov ax,cx
; mov cx,0x0a
; mov di,show_db1_dec
; mov dword[ds:di],' '
; call decode
;Show size
; mov si,show_db1
; call printplain
;
; popa
;end if
jmp $
 
;///////////////////procedure //////////
;input es:di - is pointer to date
;cx - counter
;return: cx - status if =0 - end of date else es:di point to first symbol on new line
 
}
/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_any.inc
0,0 → 1,683
; Copyright (c) 2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
;òóò ðàñïîëîãàåòñÿ ìîäóëü ñ ïîìîùüþ êîòîðîãî áóäóò ïàðñèòüñÿ âñå îñòàëüíûå ñåêöèè
color_sym_black equ 0
color_sym_blue equ 1
color_sym_green equ 2
color_sym_turquoise equ 3
color_sym_red equ 4
 
color_sym_lightgray equ 7
 
color_sym_lightblue equ 9
color_sym_lettuce equ 10
color_sym_pink equ 12
color_sym_yellow equ 14
 
macro use_any_sec
{
;óçíàåì ðàáîòó ïðåäûäóùåãî øàãà ò.å. ÷åìó = timeout, åñëè îí 0, òî âèçóàëüíàÿ ÷àñòü íå áóäåò îòîáðàæåíà íà äèñïëåå ñ âûáîðîì çàãðóçî÷íûõ ñåêöèé.
;èíà÷å ìû åå äîëæíû îòîáðàçèòü è æäàòü çàÿâëåíîå âðåìÿ äëÿ âûáîðà è êîíèãóðèðîâàíèÿ ïóêíêòîâ ñåêöèè îò ïîëüçîâàòåëÿ.
 
if DEBUG
pusha
mov ax,word [value_timeout] ;èäåò ïðîâåðêà íà íàëè÷åå çíà÷åíèÿ timeout, äëÿ áîëåå áûñòðîé ðàáîòû, ýòîò ïàðàìåòð äîëæåí áûòü óæå îáðàáîòàí,ò.å. â ýòîì ñëó÷àå ïðè åãî =0 áóäåò ñôîðìèðîâàí óêàçàòåëü òîëüêî íà äåôîëòíóþ ñåêöèþ, èíà÷å èíôîðìàöèÿ áóäåò ñîáðàíà ïî âñåì ñåêöèÿì è ñîñòàâëåíû óêàçàòåëè â áëîêå ïàìÿòè
; mov ax,cx
mov cx,0x0a
mov di,show_db1
mov dword[ds:di],' '
mov word [ds:di+4],' '
call decode
;Show size
mov si,show_db1
call printplain
;
popa
end if
 
test ax,ax
jz .parse_run_only
 
;îòîáðàçèì ïîëíûé ñïèñîê âñåõ íàéäåíûõ ñåêöèé.
if DEBUG
pusha
mov si,show_all_sect
call printplain
popa
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mov al, 0xf6 ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå
out 0x60, al
xor cx, cx
.wait_loop: ; variant 2
; reading state of port of 8042 controller
in al, 64h
and al, 00000010b ; ready flag
; wait until 8042 controller is ready
loopnz .wait_loop
 
 
; set keyboard typematic rate & delay
mov al, 0xf3
out 0x60, al
xor cx, cx
@@:
in al, 64h
test al, 2
loopnz @b
mov al, 0
out 0x60, al
xor cx, cx
@@:
in al, 64h
test al, 2
loopnz @b
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; get start time
call gettime
mov dword [start_timer],eax
mov word [timer_],newtimer
mov word [timer_+2],cs
;óñòàíîâèòü ñâîå ïðåðûâàíèå íà òàéìåð ò.å. êîä áóäåò ïåððûâàòüñÿ ~18 ðàç â ñåê è ïåðåõîäèòü íà îáðàáîò÷èê
cli
push 0
pop es
push dword [es:8*4]
pop dword [old_timer]
push dword [timer_]
pop dword [es:8*4]
sti
 
;ïðîöåäóðà ôîðìèðîâàíèÿ áóôåðà äëÿ ñêðîëèíãà ñåêöèé
;if DEBUG
; pusha
; mov ax,point_default
; mov ax,cx
; mov cx,0x0a
; mov di,show_db1
; mov dword[ds:di],' '
; mov word [ds:di+4],' '
; call decode
;Show size
; mov si,show_db1
; call printplain
;
; xor ax,ax
; int 0x16
; popa
;end if
;;;;;;;;;;;;;ðàçìåð ïðåäûäóùåé ñåöèè óñòàíîâèì =0
mov save_descript_size,18
;îòîáðàçèòü black screen
show_bl_sc ;es=0xb800
.show_all_scr:
get_frame_buffer ;es=0x2000
;îòîáðàæåíèå ñåêöèé
call show_bl_sc_sect ;es=0xb800
;îòîáðàçèòü àêòèâíûé êóðñîð
.show_active_cursor:
show_act_cursor
show_descript ;ìàêðîñ ïî îòîáðàæåíèþ îïèñàíèÿ ñåêöèè
 
;îòîáðàçèòü Press any key ....
mov eax,dword [old_timer]
cmp eax,dword [timer_]
jz .interrupt_16
 
show_timer_message
mov word [start_stack],sp
.interrupt_16:
xor ax,ax ;ïîëó÷èì èíôîðìàöèþ î òîì ÷òî íàæàòî
int 0x16
;check on change
mov ebx,dword [old_timer]
cmp ebx,dword [timer_]
jz @f
;restore timer interrupt
cli
push 0
pop es
; mov eax,dword [old_timer] ; âîññòàíîâèì ïðåæäíåå ïðåðûâàíèå
mov [es:8*4],ebx
mov dword [timer_],ebx
sti
push ax
clear_timer_msg
pop ax
@@:
call clean_active_cursor ;clean old cursor ;es=0xb800
 
cmp ah,0x48 ;ðåàêöèÿ ñèñòåìû íà ñîáûòèÿ
jz .up
cmp ah,0x50
jz .down
cmp ah,0x49
jz .pgup
cmp ah,0x51
jz .pgdown
cmp ah,0x47
jz .home
cmp ah,0x4f
jz .end
 
cmp al,0xD
jnz .show_active_cursor
 
jmp .end_show_all ;ïàðñèíã ñåêöèè êîòîðàÿ óêàçàíà â point_default
.up:
mov si,point_to_point_def ;çíà÷åíèå óêàçàòåëÿ
add si,2
lea ax,point_to_hframe
 
cmp si,ax
ja @f
 
mov point_to_point_def,si
mov ax,[si]
mov point_default,ax
jmp .show_active_cursor
@@:
call find_before_sect
jmp .show_all_scr
 
 
 
.down:
mov si,point_to_point_def ;çíà÷åíèå óêàçàòåëÿ
mov ax,point_to_eframe ;óêàçàòåëü íà ïîñëåäíèé ýëåìåíò
sub si,2
cmp si,ax
jb @f
 
mov point_to_point_def,si
mov ax,[si]
mov point_default,ax
jmp .show_active_cursor
 
@@: call find_next_sect
jmp .show_all_scr
 
.pgup:
mov cx,size_show_section
@@:
push cx
call find_before_sect
pop cx
loop @b
jmp .show_all_scr
 
 
.pgdown:
mov cx,size_show_section
@@:
push cx
call find_next_sect
pop cx
loop @b
jmp .show_all_scr
 
.home:
xor di,di
call find_next_sect.h
jmp .show_all_scr
 
.end:
mov di,save_cx
call find_before_sect.e
jmp .show_all_scr
 
 
 
 
; òóò ìû áóäåì ïàðñèòü òîëüêî äåôîëòíóþ ñåêöèþ è âûïîëíÿòü åå íè÷åãî íå ïðåäëàãàÿ ïîëüçîâàòåëþ èç äèàëîãîâ.
.parse_run_only:
if DEBUG
pusha
mov si,no_show_only_w
call printplain
popa
end if
 
 
.end_show_all:
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
;show black screen SL
macro show_bl_sc
{
;;;;;;;;;;;;;;;
;î÷èñòèì ýêðàí è âûâåäåì ìåíþ
; draw frames
xor ax,ax
if DEBUG
mov ax,0x0720
end if
push 0xb800
pop es
xor di, di
; draw top
mov cx, 25 * 80
rep stosw
;;;;;;;;;;;;;;;;;;;;;;; show 'Secondary Loader v0.xxx'
mov di,164
mov si,version
mov cx,version_end-version
mov ah,color_sym_yellow
@@:
lodsb
stosw
loop @b
;;;;;;;;;;;;;;;;;;;;;;; show firm ))
mov di,(2*160-(2*(soft_mes_end-soft_mes+4))) ;286
mov ah,color_sym_pink;color_sym_red
mov al,'K'
stosw
mov al,' '
stosw
mov ah,color_sym_lightgray;color_sym_lightblue;color_sym_pink
mov si,soft_mes
mov cx,soft_mes_end- soft_mes
@@:
lodsb
stosw
loop @b
;;;;;;;;;;;;;;;;;;;;;;; show '__________________________'
mov di,480
mov ah,color_sym_yellow
mov al,'Ä'
mov cx,61
rep stosw
;;;;;;;;;;;;;;;;;;;;;;; show 'Select section'
mov di,804
mov si,select_section
mov cx,select_section_end - select_section
mov ah,color_sym_lightgray
@@:
lodsb
stosw
loop @b
;;;;;;;;;;;;;;;;;;;;;;; show 'Section description'
mov di,880
mov si,section_description
mov cx,section_description_end - section_description
; mov ah,color_sym_lightgray
@@:
lodsb
stosw
loop @b
 
}
 
macro show_timer_message
{
;;;;;;;;;;;;;;;;;;;;; show Press any key
;;;;;;;;;;;;;;;;;;;;; show ramk
 
xor ax,ax
mov di,3360
mov cx,80*4
rep stosw
 
mov di,3362
mov ah,color_sym_pink
mov al,0xDA
stosw
mov al,0xc4
mov cx,76
rep stosw
mov al,0xBF
stosw
add di,4
mov al,0xb3
stosw
add di,152
stosw
add di,4
stosw
add di,152
stosw
add di,4
mov al,0xc0
stosw
mov al,0xc4
mov cx,76
rep stosw
mov al,0xd9
stosw
;;;;;;;;;;;;;;;;;;;;;;;;ramk is complete show
;show first message
mov si,start_msg
mov cx,start_msg_e-start_msg
mov di,3526
@@:
lodsb
stosw
loop @b
;;;;;;;;;;;;;;;;;;;; show press Enter to....
add di,44
mov si,time_msg
mov cx,time_msg_e-time_msg
@@:
lodsb
stosw
loop @b
}
 
 
 
 
 
 
 
 
macro get_frame_buffer
{
mov cx,save_cx ;it's placed size of ini file
les di,dword [file_data]
 
mov si,di ;point frame
mov bx,cx
mov dx,size_show_section
; mov point_to_hframe,di ; âíåñåì çíà÷åíèå, òàê ïîäñòðàõîâêà íå áîëåå
 
mov al,byte [es:di]
push word .first_ret_bl_sc
cmp al,' '
jz .first_bl_sc
jmp get_firs_sym.not_space
.first_bl_sc:
jmp get_firs_sym.first_sp
 
.start_hbl:
call get_firs_sym ;get first symbol on new line
test cx,cx
jz error.correct_exit_bl ;critical error not found default point it's not possible because it's param chacking before
cmp al,'['
jnz .start_hbl
 
mov si,di ;point frame
mov bx,cx
mov dx,size_show_section
jmp .analisist_al
 
 
.start_bl:
call get_firs_sym ;get first symbol on new line
.first_ret_bl_sc: ;ïåðâûé âîçâðàò
test cx,cx
jz error.correct_exit_bl ;critical error not found default point it's not possible because it's param chacking before
.analisist_al:
cmp al,'['
jnz .start_bl
;ïðîñìàòðèâàåì ini ôàéë ñ íà÷àëà â ïîèñêàõ ñåêöèè óêàçàíîé êàê default
;ïîèñê ôðåéìà â êîòîðîì ñîäåðæèòüñÿ çíà÷åíèå default
.found_sect_bl:
cmp di,point_loader
jz .start_bl
cmp di,point_default
jz .save_point_def
 
dec dx
jnz .start_bl
 
jmp .start_hbl
 
 
.save_point_def:
;èòàê äàëåå ìû äîëæíû çàïîëíèòü frame áóôåð àäðåñîâ ñåêöèé, ÷òî áû ïîòîì ïî íåìó áûñòðî ïåðåìåùàòüñÿ íå âû÷èñëÿÿ ñíîâà àäðåñà
mov di,si ;óêàçàòåëü íà íà÷àëî
mov cx,bx
lea si,point_to_hframe
mov dx,size_show_section+1 ;ò.ê. ó íàñ ñòðóêòóðà ñîäåðæèò ðàçìåð ìåæäó ïåðâûì è âòîðûì óêàçàòåëåì, òî íàì íóæíî íà 1 àäðåñ áîëüøå îáñ÷èòàòü ñåêöèé.
;ïåðåõîäèì íà îáðàáîòêó çíà÷åíèÿ óêàçàòåëÿ
mov al,byte [es:di]
push word .first_ret_mfb
cmp al,' '
jz .first_bl_mbf
jmp get_firs_sym.not_space
.first_bl_mbf:
jmp get_firs_sym.first_sp
 
.start_mfb:
call get_firs_sym ;get first symbol on new line
.first_ret_mfb: ;ïåðâûé âîçâðàò
jcxz .val_buff_comp ;.end_loader ;found or not found parametrs in section exit in section
cmp al,'['
jnz .start_mfb
 
.found_sect_mfb:
cmp di,point_loader ;if we have section loader
jz .start_mfb
 
mov [si],di
 
sub si,2
dec dx
jnz .start_mfb
;bufer is full
jmp @f
.val_buff_comp:
push save_cx
pop word [si]
sub si,2
@@:
 
add si,4
mov point_to_eframe,si
 
}
 
macro show_act_cursor
{
;îòîáðàæåíèå êóðñîðà ïî óìîë÷àíèþ
lea si,point_to_hframe
mov di,962-160
mov ax,point_default
mov cx,size_show_section
.home_show_cur:
mov bx,[si]
add di,160
cmp bx,ax
jz .show_cursor_activ
sub si,2
loop .home_show_cur
 
.show_cursor_activ:
; push 0xb800
; pop es
mov point_to_point_def,si
mov ax,(color_sym_red*0x100+0x10)
stosw
add di,68
inc ax
stosw
}
 
macro clear_timer_msg
{
push 0xb800
pop es
xor ax,ax
if DEBUG
mov ax,0x0720
end if
;;;;;;;;;;;;;;;;;;;;; show Press any key
mov di,3360
mov cx,80*4
rep stosw
 
;show sect
push ini_data_
pop es
call show_bl_sc_sect ;es=0xb800
 
}
 
macro show_descript
;Ýòîò ìàêðîñ ïîêàçûâàåò êðàòêîå îïèñàíèå, åñëè îíî åñòü ó ñåêöèè â ïóíêòå
;Section description
{
local .start_p_sh_d
local .exit
local .rest_value_loop_sh_d
local .end_sh_desc_sec
local .loop_message
local .show_mess_prev_eq
mov di,point_default
push ini_data_
mov si,point_to_point_def
pop es
sub si,2
mov cx,[si] ;çàãðóçèì óêàçàòåëü íàñëåäóþùèþ ñåêöèþ
sub cx,di ;âîò òåïåðü èìååì èñòèíûé ðàçìåð
;di - óêàçàòåëü íà äåôîëòíóþ ñåêöèþ ò.å. âûáðàííóþ cx - ðàçìåð îáëàñòè. äëÿ ïðîñìîòðà
 
.start_p_sh_d:
call get_firs_sym ;get first symbol on new line
test cx,cx
jz .exit ;íåòó? íó ëàäíî - ñëåäóþùåå çíà÷åíèå òîãäà )
cmp al,'d'
jnz .start_p_sh_d
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
mov bx,cx
mov ax,di
 
mov si,parse_descript
mov cx,parse_descript_e - parse_descript
repe cmpsb
jnz .rest_value_loop_sh_d ;is not compare
 
sub bx,parse_descript_e - parse_descript ;correct cx
add bx,cx
mov cx,bx
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ðàçáîð àëÿ ' = '
mov ax,0x3d20 ;cut al=' ' ah='='
repe scasb
jcxz .rest_value_loop_sh_d ;not found param timeout
cmp ah,byte [es:di-1] ;find '='
jnz .rest_value_loop_sh_d
repe scasb ;cut ' '
inc cx
dec di
;;;;;;;;;;;;;;;;;;;;di óêàçûâàåò íà ñòðî÷êó, êîòîðóþ íàì íóæíî âûâîäèòü.
;ñòðî÷êà áóäåò âûâîäèòüñÿ áëîêàìè ïî 37 ñèìâîëîâ.
;íàñòðîèì êóäà áóäåì âûâîäèòü ò.å. íà÷àëî
;es:di - óêàçûâàþò íà ñòðî÷êó èç êîòîðîé ìû áåðåì ñèìâîë, ds:si êóäà áóäåì âûâîäèòü
push di
pop si
 
push es
pop ds
 
push 0xb800
pop es
mov di,1040
mov bx,18
mov find_sec_di,di
mov save_cx_d,bx
;;;;;;;;;;;;;;;;;;;;;;;;;;
;clean string
 
push di
xor ax,ax
 
@@: mov cx,38
push di
rep stosw
pop di
 
cmp save_descript_size,bx
jz @f
 
 
add di,160
dec bx
jnz @b
 
@@: pop di
;enter in mess
.show_mess_prev_eq:
lodsb
mov ah,color_sym_lettuce;color_sym_turquoise
; sub di,2
cmp al,'"'
jz .loop_message
cmp al,"'"
jnz .end_sh_desc_sec
 
.loop_message:
mov cx,38
@@:
lodsb
cmp al,'"'
jz .end_sh_desc_sec
cmp al,"'"
jz .end_sh_desc_sec
stosw
loop @b
add find_sec_di,160
mov di,find_sec_di
dec save_cx_d
cmp save_cx_d,0
jnz .loop_message
 
.end_sh_desc_sec:
push save_cx_d
pop save_descript_size
 
push cs
pop ds
jmp .exit
 
 
.rest_value_loop_sh_d:
mov di,ax
mov cx,bx
jmp .start_p_sh_d
 
.exit:
}
/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_dat.inc
0,0 → 1,56
; Copyright (c) 2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
;Òóò ïðåäñòàâëåííû òåãè, äëÿ ñðàâíåíèÿ
parse_loader db '[loader]'
parse_loader_e:
parse_l_timeout db 'timeout'
parse_l_timeout_e:
parse_l_default db 'default'
parse_l_default_e:
parse_name db 'ame'
parse_name_e:
parse_descript db 'descript'
parse_descript_e:
 
parse_LoaderModule db 'LoaderModule'
parse_LoaderModule_e:
parse_RamdiskSize db 'RamdiskSize'
parse_RamdiskSize_e:
parse_RamdiskFS db 'RamdiskFS'
parse_RamdiskFS_e:
parse_RamdiskSector db 'RamdiskSector'
parse_RamdiskSector_e:
parse_RamdiskCluster db 'RamdiskCluster'
parse_RamdiskCluster_e:
parse_RFS_FAT db 'FAT'
parse_RFS_FAT_e:
parse_RFS_KRFS db 'KRFS'
parse_RFS_KRFS_e:
parse_Loader_Image db 'LoaderImage'
parse_Loader_Image_e:
parse_RamdiskFile db 'RamdiskFile'
parse_RamdiskFile_e:
/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_loader.inc
0,0 → 1,332
; Copyright (c) 2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov nickname <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
;áëîê ìàêðîñîâ ïî îáðàáîòêå ñåêöèè [loader]
;âõîäíûå äàííûå:
;es:di - óêàçàòåëü íà ñåêöèþ íà÷èíàþùèþñÿ ñ '[' âñòå÷àþùèþñÿ ïîñëå 0õa
;cx - ñ÷åò÷èê êîë-âî áàéò äëÿ ïðîâåðêå â êàäðå
;
macro use_parse_loader
{
.parse_loader:
;//////////////////
;/ parse [loader]
;//////////////////
mov bx,cx ;cîõðàíèì â ðåãèñòðû çíà÷åíèÿ ñ÷åò÷èêà è óêàçàòåëÿ
mov ax,di
 
; mov word [bp-4],.start ;is alredy set, see up
mov si,parse_loader
mov cx,parse_loader_e - parse_loader
repe cmpsb
jnz error.rest_value ;öåïî÷êà íå ñîâïàëà :( ïåðåéäåì äàëåå ò.å. áóäåì ñíîâà èñêàòü))
 
;ñîõðàíèì óêàçàòåëüíà loader, ÷òî áû ïîòîì áîëüøå åãî íå èñêàòü
mov point_loader,ax
sub bx,parse_loader_e - parse_loader ;correct cx
add bx,cx
mov cx,bx
 
if DEBUG
pusha
mov si,lm_l_found
call printplain
popa
end if
;/////////////////end check [loader]. [loader] is found
;parsing section [loader]
;first found end section,let's found '[' -it's start next section
;in previosly steep bx =cx we are not need save cx, save only di - point
mov dx,di
@@:
call get_firs_sym
jcxz .loader_f_end ;.end_loader ; end äàæå åñëè ìû íå íàøëè ñåêöèþ ïðåäïîëîæèì ÷òî ñåêöèÿ [loader] ñòîèò â êîíöå
cmp al,'['
jnz @b
 
.loader_f_end:
sub bx,cx ;bx = n byte presend in section [loader]
mov di,dx ;restore di
;////////////////parse parametrs in section [loader]
;//timeout=5
;//default=main
; mov di,dx ;set pointer on section [loader] i think it's not need
mov cx,bx ;set counter for parsing section [loader] cx= êîë-âó ñèìâîëîâ â ñåêöèè [loader]
mov ret_on_ch,.get_next_str ; return point
;;;;;;; parse timeout & default
.get_next_str:
call get_firs_sym ;get first symbol on new line
 
test cx,cx
jz .end_loader
; jcxz .end_loader ;çàâåðøåíèå ïàðñèíãà çíà÷åíèé timeout & default
cmp al,'t'
jz .loader_timeout
cmp al,'d'
jnz .get_next_str
;//////[loader].default
;input di point to data cx=size [loader]
mov bx,cx
mov ax,di
 
mov si,parse_l_default
mov cx,parse_l_default_e - parse_l_default
repe cmpsb
 
jnz error.rest_value ;is not compare öåïî÷êà íå ñîâïàëà
 
sub bx,parse_l_default_e - parse_l_default ;correct cx
add bx,cx
mov cx,bx
 
test status_flag,flag_found_default
jz .correct_is_not_set
 
mov si,found_equal_default ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì
call printplain
jmp .get_next_str
 
.correct_is_not_set:
mov ax,0x3d20 ;cut al=' ' ah='='
repe scasb
test cx,cx
jz .end_loader
cmp ah,byte [es:di-1] ;find '='
jnz .get_next_str
repe scasb ;cut ' '
inc cx
dec di
;ñåé÷àñ es:di óêàçûâàþò íà íàçâàíèå ñåêöèè, èìÿ ñåêöèè ïî äåôîëòó íå äîëæíî áûòü loader ò.å. èíà÷å âîçìîæíî çàöèêëèâàíèå
;óñòàíîâèì óêàçàòåëü si íà ýòî çíà÷åíèå è ñíà÷àëà ïðîâåðèì
 
;ïîëó÷åíèå äëèííû ñåêöèè
; cx=bx ñîäåðæèò äëèííó îñòàòêà ñåêöèè
; di=ax óêàçàòåëü íà òåêóùèþ ñåêöèþ
mov bx,cx
mov dx,di
 
@@: mov al,byte [es:di]
inc di
dec cx
test cx,cx
jz error.error_get_size_d_sect ;ïåðåõîä íà îáðàáîòêó îøèáêè ïî íàõîæäåíèþ äëèíû äåôîëòíîé ñåêöèè
cmp al,' '
jz @b
cmp al,0xd
jz .found_size_d_sect
cmp al,0xa
jnz @b
.found_size_d_sect:
;
inc cx ;correct cx
mov ax,bx
sub bx,cx ; â bx äëèíà ñåêöèè êîòîðàÿ îïðåäåëåíà ïî äåôîëòó
mov save_cx_d,bx
mov di,dx
 
mov cx,bx ;set size default section
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ïðîâåðêà íà =loader
;save in reg point and ñ÷åò÷èê
;check on loader
mov bx,ax
mov ax,dx
 
mov si,parse_loader
inc si ;set only loader and 6 char in counter
repe cmpsb
jnz .check_section ;öåïî÷êà íå ñîâïàëà :( ïåðåéäåì äàëåå )) çíà÷èò íå èñêëþ÷åíèå
 
jmp error.default_eq_loader ;error êðèòè÷åñêàÿ îøèáêà ò.å. â äåôîëòå ïðèñóòñòâóåò èìÿ [loader]
 
.check_section: ;ïîèñê ñîîòâåòñòâóþùåé ñåêöèè íàì íóæíî áóäåò óçíàòü àäðåñ ýòîé ñåêöèè
mov cx,bx
mov di,ax
 
;/////////////////////////////
; mov ret_on_ch,.start_d ;set return
mov si,di ;óñòàíîâèì óêàçàòåëü íà íàøó ñåêöèþ, êîòîðàÿ ïî äåôîëòó
 
push di ;save point di
 
push cx ;save cx
;óñòàíîâèì óêàçàòåëü es:di íà íà÷àëî ini ôàéëà
mov cx,save_cx ;it's placed size of ini file
les di,dword [file_data]
 
 
mov al,byte [es:di]
push word .first_ret_d
cmp al,' '
jz .first_sp_1_d
jmp get_firs_sym.not_space
.first_sp_1_d:
jmp get_firs_sym.first_sp
 
.start_d:
call get_firs_sym ;get first symbol on new line
.first_ret_d: ;ïåðâûé âîçâðàò
jcxz .correct_exit ;.end_loader ;found or not found parametrs in section exit in section
cmp al,'['
jz .found_sect_d
jmp .start_d
;ïðîñìàòðèâàåì ini ôàéë ñ íà÷àëà â ïîèñêàõ ñåêöèè óêàçàíîé êàê default
;èäåò ïðîâåðêà íà íàëè÷åå çíà÷åíèÿ timeout, äëÿ áîëåå áûñòðîé ðàáîòû, ýòîò ïàðàìåòð äîëæåí áûòü óæå îáðàáîòàí,ò.å. â ýòîì ñëó÷àå ïðè åãî =0 áóäåò ñôîðìèðîâàí óêàçàòåëü òîëüêî íà äåôîëòíóþ ñåêöèþ, èíà÷å èíôîðìàöèÿ áóäåò ñîáðàíà ïî âñåì ñåêöèÿì è ñîñòàâëåíû óêàçàòåëè â áëîêå ïàìÿòè
.found_sect_d:
 
;check on name section
mov bx,cx
mov ax,di
push si ;save point
; mov si,parse_loader
mov cx,save_cx_d ;load size section
push es
pop ds
 
inc di
repe cmpsb
push cs
pop ds
pop si
jnz .not_compare_d_s ;öåïî÷êà íå ñîâïàëà :( ïåðåéäåì äàëåå )) çíà÷èò íå èñêëþ÷åíèå
cmp byte[es:di],']'
jnz .not_compare_d_s ;íåò â êîíöå íàøåé ñåêöèè çàâåðøàþùåãî ñèìâîëà :(
 
 
 
;set flag -we have found default -not enter again in this prosedure
or status_flag,flag_found_default
pop cx
pop di
mov point_default,ax ;point to [
 
if DEBUG
pusha
mov si,lm_lf_default_f
call printplain
popa
end if
jmp .get_next_str
 
.not_compare_d_s:
 
mov cx,bx
mov di,ax
jmp .start_d
 
.correct_exit:
pop cx ;âîññòàíîâèì çíà÷åíèå ñ÷åò÷èêà
pop di
 
 
if DEBUG
pusha
mov si,lm_lf_default
call printplain
popa
end if
jmp .get_next_str
 
;//////////[loader].timeout
.loader_timeout:
mov bx,cx
mov ax,di
 
mov si,parse_l_timeout
mov cx,parse_l_timeout_e - parse_l_timeout
repe cmpsb
jnz error.rest_value ;is not compare
 
sub bx,parse_l_timeout_e - parse_l_timeout ;correct cx
add bx,cx
mov cx,bx
 
test status_flag,flag_found_timeout
jz .correct_is_not_set_t
 
mov si,found_equal_timeout ;ìû íàøëè ÷òî ôëàã óæå óñòàíîâëåí, èíôîðìèðóåì
call printplain
jmp .get_next_str
 
.correct_is_not_set_t:
mov ax,0x3d20 ;cut al=' ' ah='='
repe scasb
jcxz .timeout_sec_end_d ;not found param timeout
cmp ah,byte [es:di-1] ;find '='
jnz .get_next_str
repe scasb ;cut ' '
inc cx
dec di
;get timeout value
;2 çíàêa ìîæåò áûòü îáðàáîòàíî ò.å. çíà÷åíèå îò 0 äî 99 ñåêóíä
push cx
xor bx,bx
mov cx,2
@@: mov al,byte [es:di]
cmp al,'0'
jb .end_get_val_t
cmp al,'9'
ja .end_get_val_t
imul bx,10
xor al,0x30
add bl,al
.end_get_val_t:
inc di
loop @b
mov word [value_timeout],bx
; pop cx
 
if DEBUG
pusha
mov si,lm_lf_timeout
call printplain
popa
end if
 
jmp @f
.timeout_sec_end_d:
mov word [value_timeout],default_timeout_value
mov si,set_default_timeout_val
call printplain
@@: pop cx
jmp .get_next_str
 
;///////here end block loader
.end_loader:
if DEBUG
pusha
mov si,lm_l_end
call printplain
popa
end if
 
}
/kernel/branches/Kolibri-acpi/sec_loader/trunk/parse_err.inc
0,0 → 1,66
; Copyright (c) 2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of the <organization> nor the
; names of its contributors may be used to endorse or promote products
; derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
 
error:
.rest_value:
mov di,ax ;restore value after repe cmpsb
mov cx,bx
jmp ret_on_ch ;return
 
;///// îøèáêà ïðè íàõîäæåíèè äëèííû ñåêöèè â ïàðàìåòðå default
.error_get_size_d_sect:
leave ;clear array in stack
mov si,not_found_def_sect
jmp err_show_ini
 
;/////ERROR
.not_loader:
leave ;clear array in stack
mov si,not_found_sec_loader
jmp err_show_ini
 
.default_eq_loader: ;êðèòè÷åñêàÿ îøèáêà default ñåêöèÿ = loader
leave
mov si,default_eq_loader
jmp err_show_ini
.correct_exit_bl:
leave
mov si,point_to_default_sec_not_found
jmp err_show_ini
.incorect_section_def:
leave
mov si,incorect_section_define
jmp err_show_ini
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;show message error
.LoaderModule:
push word 0xb800
pop es
 
 
 
ret
/kernel/branches/Kolibri-acpi/sec_loader/trunk
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/kernel/branches/Kolibri-acpi/sec_loader
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property
/kernel/branches/Kolibri-acpi/macros.inc
0,0 → 1,106
 
__REV = 0
 
macro $Revision a {
match =: Num =$,a \{
if __REV < Num
__REV = Num
end if
\}
}
 
$Revision$
 
 
; structure definition helper
macro struct name, [arg]
{
common
name@struct equ name
struc name arg {
}
 
macro struct_helper name
{
match xname,name
\{
virtual at 0
xname xname
sizeof.#xname = $ - xname
name equ sizeof.#xname
end virtual
\}
}
 
ends fix } struct_helper name@struct
 
;// mike.dld, 2006-29-01 [
 
; macros definition
macro diff16 title,l1,l2
{
local s,d
s = l2-l1
display title,': 0x'
repeat 16
d = 48 + s shr ((16-%) shl 2) and $0F
if d > 57
d = d + 65-57-1
end if
display d
end repeat
display 13,10
}
macro diff10 title,l1,l2
{
local s,d,z,m
s = l2-l1
z = 0
m = 1000000000
display title,': '
repeat 10
d = '0' + s / m
s = s - (s/m)*m
m = m / 10
if d <> '0'
z = 1
end if
if z <> 0
display d
end if
end repeat
display 13,10
}
 
include 'kglobals.inc'
 
; \begin{diamond}[29.09.2006]
; may be useful for kernel debugging
; example 1:
; dbgstr 'Hello, World!'
; example 2:
; dbgstr 'Hello, World!', save_flags
macro dbgstr string*, f
{
local a
iglobal_nested
a db 'K : ',string,13,10,0
endg_nested
if ~ f eq
pushfd
end if
push esi
mov esi, a
call sys_msg_board_str
pop esi
if ~ f eq
popfd
end if
}
; \end{diamond}[29.09.2006]
 
macro Mov op1,op2,op3 ; op1 = op2 = op3
{
mov op2,op3
mov op1,op2
}
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/bootloader/boot_fat12.asm
0,0 → 1,287
; FAT12 boot sector for Kolibri OS
;
; Copyright (C) Alex Nogueira Teixeira
; Copyright (C) Diamond
; Copyright (C) Dmitry Kartashov aka shurf
;
; Distributed under GPL, see file COPYING for details
;
; Version 1.0
 
lf equ 0ah
cr equ 0dh
 
pos_read_tmp equ 0700h ;position for temporary read
boot_program equ 07c00h ;position for boot code
seg_read_kernel equ 01000h ;segment to kernel read
 
jmp start_program
nop
 
; Boot Sector and BPB Structure
include 'floppy1440.inc'
;include 'floppy2880.inc'
;include 'floppy1680.inc'
;include 'floppy1743.inc'
 
start_program:
 
xor ax,ax
mov ss,ax
mov sp,boot_program
push ss
pop ds
 
; print loading string
mov si,loading+boot_program
loop_loading:
lodsb
or al,al
jz read_root_directory
mov ah,0eh
mov bx,7
int 10h
jmp loop_loading
 
read_root_directory:
push ss
pop es
 
; calculate some disk parameters
; - beginning sector of RootDir
mov ax,word [BPB_FATSz16+boot_program]
xor cx,cx
mov cl,byte [BPB_NumFATs+boot_program]
mul cx
add ax,word [BPB_RsvdSecCnt+boot_program]
mov word [FirstRootDirSecNum+boot_program],ax ; 19
mov si,ax
 
; - count of sectors in RootDir
mov bx,word [BPB_BytsPerSec+boot_program]
mov cl,5 ; divide ax by 32
shr bx,cl ; bx = directory entries per sector
mov ax,word [BPB_RootEntCnt+boot_program]
xor dx,dx
div bx
mov word [RootDirSecs+boot_program],ax ; 14
 
; - data start
add si,ax ; add beginning sector of RootDir and count sectors in RootDir
mov word [data_start+boot_program],si ; 33
; reading root directory
; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!!
mov ah,2 ; read
push ax
 
mov ax,word [FirstRootDirSecNum+boot_program]
call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
pop ax
mov bx,pos_read_tmp ; es:bx read buffer
call read_sector
 
mov si,bx ; read buffer address: es:si
mov ax,[RootDirSecs+boot_program]
mul word [BPB_BytsPerSec+boot_program]
add ax,si ; AX = end of root dir. in buffer pos_read_tmp
 
; find kernel file in root directory
loop_find_dir_entry:
push si
mov cx,11
mov di,kernel_name+boot_program
rep cmpsb ; compare es:si and es:di, cx bytes long
pop si
je found_kernel_file
add si,32 ; next dir. entry
cmp si,ax ; end of directory
jb loop_find_dir_entry
 
file_error_message:
mov si,error_message+boot_program
 
loop_error_message:
lodsb
or al,al
jz freeze_pc
mov ah,0eh
mov bx,7
int 10h
jmp loop_error_message
 
freeze_pc:
jmp $ ; endless loop
 
; === KERNEL FOUND. LOADING... ===
 
found_kernel_file:
mov bp,[si+01ah] ; first cluster of kernel file
; <diamond>
mov [cluster1st+boot_program],bp ; starting cluster of kernel file
; <\diamond>
 
; reading first FAT table
mov ax,word [BPB_RsvdSecCnt+boot_program] ; begin first FAT abs sector number
call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
mov bx,pos_read_tmp ; es:bx read position
mov ah,2 ; ah=2 (read)
mov al, byte [BPB_FATSz16+boot_program] ; FAT size in sectors (TODO: max 255 sectors)
call read_sector
jc file_error_message ; read error
 
mov ax,seg_read_kernel
mov es,ax
xor bx,bx ; es:bx = 1000h:0000h
 
 
; reading kernel file
loop_obtains_kernel_data:
; read one cluster of file
call obtain_cluster
jc file_error_message ; read error
 
; add one cluster length to segment:offset
push bx
mov bx,es
mov ax,word [BPB_BytsPerSec+boot_program] ;\
movsx cx,byte [BPB_SecPerClus+boot_program] ; | !!! TODO: !!!
mul cx ; | out this from loop !!!
shr ax,4 ;/
add bx,ax
mov es,bx
pop bx
 
mov di,bp
shr di,1
pushf
add di,bp ; di = bp * 1.5
add di,pos_read_tmp
mov ax,[di] ; read next entry from FAT-chain
popf
jc move_4_right
and ax,0fffh
jmp verify_end_sector
move_4_right:
mov cl,4
shr ax,cl
verify_end_sector:
cmp ax,0ff8h ; last cluster
jae execute_kernel
mov bp,ax
jmp loop_obtains_kernel_data
 
execute_kernel:
; <diamond>
mov ax,'KL'
push 0
pop ds
mov si,loader_block+boot_program
; </diamond>
push word seg_read_kernel
push word 0
retf ; jmp far 1000:0000
 
 
;------------------------------------------
; loading cluster from file to es:bx
obtain_cluster:
; bp - cluster number to read
; carry = 0 -> read OK
; carry = 1 -> read ERROR
 
; print one dot
push bx
mov ax,0e2eh ; ah=0eh (teletype), al='.'
xor bh,bh
int 10h
 
; convert cluster number to sector number
mov ax,bp ; data cluster to read
sub ax,2
xor bx,bx
mov bl,byte [BPB_SecPerClus+boot_program]
mul bx
add ax,word [data_start+boot_program]
pop bx
 
writesec:
call conv_abs_to_THS ; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
patchhere:
mov ah,2 ; ah=2 (read)
mov al,byte [BPB_SecPerClus+boot_program] ; al=(one cluster)
call read_sector
retn
;------------------------------------------
 
;------------------------------------------
; read sector from disk
read_sector:
push bp
mov bp,20 ; try 20 times
newread:
dec bp
jz file_error_message
push ax bx cx dx
int 13h
pop dx cx bx ax
jc newread
pop bp
retn
;------------------------------------------
; convert abs. sector number (AX) to BIOS T:H:S
; sector number = (abs.sector%BPB_SecPerTrk)+1
; pre.track number = (abs.sector/BPB_SecPerTrk)
; head number = pre.track number%BPB_NumHeads
; track number = pre.track number/BPB_NumHeads
; Return: cl - sector number
; ch - track number
; dl - drive number (0 = a:)
; dh - head number
conv_abs_to_THS:
push bx
mov bx,word [BPB_SecPerTrk+boot_program]
xor dx,dx
div bx
inc dx
mov cl, dl ; cl = sector number
mov bx,word [BPB_NumHeads+boot_program]
xor dx,dx
div bx
; !!!!!!! ax = track number, dx = head number
mov ch,al ; ch=track number
xchg dh,dl ; dh=head number
mov dl,0 ; dl=0 (drive 0 (a:))
pop bx
retn
;------------------------------------------
 
loading db cr,lf,'Starting system ',00h
error_message db 13,10
kernel_name db 'KERNEL MNT ?',cr,lf,00h
FirstRootDirSecNum dw ?
RootDirSecs dw ?
data_start dw ?
 
; <diamond>
write1st:
push cs
pop ds
mov byte [patchhere+1+boot_program], 3 ; change ah=2 to ah=3
mov ax,[cluster1st+boot_program]
push 1000h
pop es
xor bx,bx
call writesec
mov byte [patchhere+1+boot_program], 2 ; change back ah=3 to ah=2
retf
cluster1st dw ?
loader_block:
db 1
dw 0
dw write1st+boot_program
dw 0
; <\diamond>
 
times 0x1fe-$ db 00h
 
db 55h,0aah ;boot signature
/kernel/branches/Kolibri-acpi/bootloader/floppy1440.inc
0,0 → 1,19
BS_OEMName db 'KOLIBRI ' ; db 8
BPB_BytsPerSec dw 512 ; bytes per sector
BPB_SecPerClus db 1 ; sectors per cluster
BPB_RsvdSecCnt dw 1 ; number of reserver sectors
BPB_NumFATs db 2 ; count of FAT data structures
BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors)
BPB_TotSec16 dw 2880 ; count of sectors on the volume (2880 for 1.44 mbytes disk)
BPB_Media db 0f0h ; f0 - used for removable media
BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT
BPB_SecPerTrk dw 18 ; sectors per track
BPB_NumHeads dw 2 ; number of heads
BPB_HiddSec dd 0 ; count of hidden sectors
BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535)
BS_DrvNum db 0 ; int 13h drive number
BS_Reserved db 0 ; reserved
BS_BootSig db 29h ; Extended boot signature
BS_VolID dd 0 ; Volume serial number
BS_VolLab db 'KOLIBRI ' ; Volume label (db 11)
BS_FilSysType db 'FAT12 ' ; file system type (db 8)
/kernel/branches/Kolibri-acpi/bootloader/floppy1680.inc
0,0 → 1,19
BS_OEMName db 'KOLIBRI ' ; db 8
BPB_BytsPerSec dw 512 ; bytes per sector
BPB_SecPerClus db 1 ; sectors per cluster
BPB_RsvdSecCnt dw 1 ; number of reserver sectors
BPB_NumFATs db 2 ; count of FAT data structures
BPB_RootEntCnt dw 112 ; count of 32-byte dir. entries (112*32 = 7 sectors)
BPB_TotSec16 dw 3360 ; count of sectors on the volume (3360 for 1.68 mbytes disk)
BPB_Media db 0f0h ; f0 - used for removable media
BPB_FATSz16 dw 10 ; count of sectors by one copy of FAT
BPB_SecPerTrk dw 21 ; sectors per track
BPB_NumHeads dw 2 ; number of heads
BPB_HiddSec dd 0 ; count of hidden sectors
BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535)
BS_DrvNum db 0 ; int 13h drive number
BS_Reserved db 0 ; reserved
BS_BootSig db 29h ; Extended boot signature
BS_VolID dd 0 ; Volume serial number
BS_VolLab db 'KOLIBRI ' ; Volume label (db 11)
BS_FilSysType db 'FAT12 ' ; file system type (db 8)
/kernel/branches/Kolibri-acpi/bootloader/floppy1743.inc
0,0 → 1,19
BS_OEMName db 'KOLIBRI ' ; db 8
BPB_BytsPerSec dw 512 ; bytes per sector
BPB_SecPerClus db 1 ; sectors per cluster
BPB_RsvdSecCnt dw 1 ; number of reserver sectors
BPB_NumFATs db 2 ; count of FAT data structures
BPB_RootEntCnt dw 224 ; count of 32-byte dir. entries (224*32 = 14 sectors)
BPB_TotSec16 dw 3486 ; count of sectors on the volume (3486 for 1.74 mbytes disk)
BPB_Media db 0f0h ; f0 - used for removable media
BPB_FATSz16 dw 11 ; count of sectors by one copy of FAT
BPB_SecPerTrk dw 21 ; sectors per track
BPB_NumHeads dw 2 ; number of heads
BPB_HiddSec dd 0 ; count of hidden sectors
BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535)
BS_DrvNum db 0 ; int 13h drive number
BS_Reserved db 0 ; reserved
BS_BootSig db 29h ; Extended boot signature
BS_VolID dd 0 ; Volume serial number
BS_VolLab db 'KOLIBRI ' ; Volume label (db 11)
BS_FilSysType db 'FAT12 ' ; file system type (db 8)
/kernel/branches/Kolibri-acpi/bootloader/floppy2880.inc
0,0 → 1,19
BS_OEMName db 'KOLIBRI ' ; db 8
BPB_BytsPerSec dw 512 ; bytes per sector
BPB_SecPerClus db 2 ; sectors per cluster
BPB_RsvdSecCnt dw 1 ; number of reserver sectors
BPB_NumFATs db 2 ; count of FAT data structures
BPB_RootEntCnt dw 240 ; count of 32-byte dir. entries (240*32 = 15 sectors)
BPB_TotSec16 dw 5760 ; count of sectors on the volume (5760 for 2.88 mbytes disk)
BPB_Media db 0f0h ; f0 - used for removable media
BPB_FATSz16 dw 9 ; count of sectors by one copy of FAT
BPB_SecPerTrk dw 36 ; sectors per track
BPB_NumHeads dw 2 ; number of heads
BPB_HiddSec dd 0 ; count of hidden sectors
BPB_TotSec32 dd 0 ; count of sectors on the volume (if > 65535)
BS_DrvNum db 0 ; int 13h drive number
BS_Reserved db 0 ; reserved
BS_BootSig db 29h ; Extended boot signature
BS_VolID dd 0 ; Volume serial number
BS_VolLab db 'KOLIBRI ' ; Volume label (db 11)
BS_FilSysType db 'FAT12 ' ; file system type (db 8)
/kernel/branches/Kolibri-acpi/bootloader/readme
0,0 → 1,43
‡ £à㧮ç­ë© ᥪâ®à ¤«ï Ž‘ Š®«¨¡à¨ (FAT12, ¤¨áª¥â )
 
- Ž¯¨á ­¨¥
®§¢®«ï¥â § £à㦠âì KERNEL.MNT á ¤¨áª¥â/®¡à §®¢
®¡êñ¬®¬ 1.44M, 1.68M, 1.72M ¨ 2.88M
„«ï ¢ë¡®à  ®¡êñ¬  ¤¨áª , ¤«ï ª®â®à®£® ­ ¤® ᮡà âì
§ £à㧮ç­ë© ᥪâ®à, ­¥®¡å®¤¨¬® ¢ ä ©«¥ boot_fat12.asm
à áª®¬¬¥­â¨à®¢ âì áâப㠢¨¤ :
include 'floppy????.inc'
¤«ï ­¥®¡å®¤¨¬®£® ®¡êñ¬  ¤¨áª . „®áâã¯­ë¥ ¢ à¨ ­âë:
floppy1440.inc,
floppy1680.inc,
floppy1743.inc ¨ floppy2880.inc
 
- ‘¡®àª 
fasm boot_fat12.asm
 
- „«ï § ¯¨á¨ § £à㧮筮£® ᥪâ®à  ­  ¤¨áª/®¡à § ¯®¤ Linux
¬®¦­® ¢®á¯®«ì§®¢ âìáï á«¥¤ãî饩 ª®¬ ­¤®©:
dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc
 
---------------------------------------------------------------------
 
Floppy FAT12 boot sector for KolibriOS.
 
- Description
Allows booting KERNEL.MNT floppies/images
with volumes of 1.44M, 1.68M, 1.72M and 2.88M
To select the volume of the disk, which should gather
boot sector, it was necessary in file boot_fat12.asm
uncomment line:
include 'floppy????. inc'
for the necessary disk volume. Available options is:
floppy1440.inc,
floppy1680.inc,
floppy1743.inc and floppy2880.inc
 
- Compile
fasm boot_fat12.asm
 
- To write boot sector to the floppy/image under Linux
you can use the following command:
dd if=boot_fat12.bin of=288.img bs=512 count=1 conv=notrunc
/kernel/branches/Kolibri-acpi/data16.inc
0,0 → 1,55
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
flm db 0
preboot_lfb db 0
preboot_bootlog db 0
boot_drive db 0
bx_from_load: dw 'r1' ; ñòðóêòóðà äëÿ õðàíåíèÿ ïàðàìåòðîâ- îòêóäà ãàøðóçèëèñü, áåðåòñÿ íèæå èç bx ; {SPraid}[13.03.2007]
; a,b,c,d - âèí÷åñòåðû, r - ðàì äèñê
; # äèñêà... ñèìâîë, à íå áàéò. '1', à íå 1
 
align 4
old_ints_h:
dw 0x400
dd 0
dw 0
 
kernel_restart_bootblock:
db 1 ; version
dw 1 ; floppy image is in memory
dd 0 ; cannot save parameters
 
; table for move to extended memory (int 15h, ah=87h)
align 8
movedesc:
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
 
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0
 
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
 
fwmovedesc:
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
 
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0
 
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
 
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/imports.inc
0,0 → 1,27
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;============================================================================
;
; External kernel dependencies
;
;============================================================================
 
$Revision$
 
 
align 4
@IMPORT:
 
library \
libini,'libini.obj'
 
import libini, \
ini.lib_init,'lib_init',\
ini.get_str,'ini.get_str',\
ini.enum_keys,'ini.enum_keys',\
ini.get_int,'ini.get_int'
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/kglobals.inc
0,0 → 1,69
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;------------------------------------------------------------------
; use "iglobal" for inserting initialized global data definitions.
;------------------------------------------------------------------
macro iglobal {
IGlobals equ IGlobals,
macro __IGlobalBlock { }
 
macro iglobal_nested {
IGlobals equ IGlobals,
macro __IGlobalBlock \{ }
 
;-------------------------------------------------------------
; use 'uglobal' for inserting uninitialized global definitions.
; even when you define some data values, these variables
; will be stored as uninitialized data.
;-------------------------------------------------------------
macro uglobal {
UGlobals equ UGlobals,
macro __UGlobalBlock { }
 
macro uglobal_nested {
UGlobals equ UGlobals,
macro __UGlobalBlock \{ }
 
endg fix } ; Use endg for ending iglobal and uglobal blocks.
endg_nested fix \}
 
macro IncludeIGlobals{
macro IGlobals dummy,[n] \{ __IGlobalBlock
purge __IGlobalBlock \}
match I, IGlobals \{ I \} }
 
 
macro IncludeUGlobals{
macro UGlobals dummy,[n] \{
\common
\local begin, size
begin = $
virtual at $
\forward
__UGlobalBlock
purge __UGlobalBlock
\common
size = $ - begin
end virtual
rb size
\}
match U, UGlobals \{ U \} }
 
macro IncludeAllGlobals {
IncludeIGlobals
IncludeUGlobals
}
iglobal
endg
 
uglobal
endg
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/proc32.inc
0,0 → 1,271
 
$Revision$
 
 
; 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) | (parmbytes=0)
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 }
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/vmodeld.inc
0,0 → 1,35
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision$
 
 
;
; Load of videomode driver in memory
;
; (driver is located at VMODE_BASE - 32kb) // if this area not occuped anything
;
; Author: Trans
; Date: 19.07.2003
;
; Include in MeOS kernel and compile with FASM
;
 
 
; LOAD VIDEOMODE DRIVER
; If vmode.mdr file not found
or eax,-1 ; Driver ID = -1 (not present in system)
mov [VMODE_BASE],eax ;
mov [VMODE_BASE+0x100],byte 0xC3 ; Instruction RETN - driver loop
stdcall read_file, vmode, VMODE_BASE, 0, 0x8000 ;{SPraid.simba}
; mov esi, vmode
; xor ebx, ebx
; mov ecx, 0x8000 ; size of memory area for driver
; mov edx, VMODE_BASE ; Memory position of driver
; xor ebp, ebp
; call fs_RamdiskRead
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property
/kernel/branches/Kolibri-acpi/skin/default.asm
0,0 → 1,38
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
include 'me_skin.inc'
 
SKIN_PARAMS \
height = bmp_base.height,\ ; skin height
margins = [5:1:43:1],\ ; margins [left:top:right:bottom]
colors active = [binner=0x00081d:\ ; border inner color
bouter=0x00081d:\ ; border outer color
bframe=0x0054e7],\ ; border frame color
colors inactive = [binner=0x00081d:\ ; border inner color
bouter=0x00081d:\ ; border outer color
bframe=0x1a8acc],\ ; border frame color
dtp = 'myblue.dtp' ; dtp colors
 
SKIN_BUTTONS \
close = [-21:3][16:16],\ ; buttons coordinates
minimize = [-39:3][16:16] ; [left:top][width:height]
 
SKIN_BITMAPS \
left active = bmp_left,\ ; skin bitmaps pointers
left inactive = bmp_left1,\
oper active = bmp_oper,\
oper inactive = bmp_oper1,\
base active = bmp_base,\
base inactive = bmp_base1
 
BITMAP bmp_left ,'left.bmp' ; skin bitmaps
BITMAP bmp_oper ,'oper.bmp'
BITMAP bmp_base ,'base.bmp'
BITMAP bmp_left1,'left_1.bmp'
BITMAP bmp_oper1,'oper_1.bmp'
BITMAP bmp_base1,'base_1.bmp'
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/skin/me_skin.inc
0,0 → 1,242
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;============================================================================
; This file should be used to generate skins of new standard
;============================================================================
; skin file structure:
;----------------------------------------------------------------------------
; header:
; dd 'SKIN'
; dd = version (1 for now)
; dd @ params
; dd @ buttons
; dd @ bitmaps
; ...
;----------------------------------------------------------------------------
; NOTE: order of sections listed below is insignificant
; since they're identified by pointer in above header
;----------------------------------------------------------------------------
; ...
; params:
; dd = skin height
; dw = right margin
; dw = left margin
; dw = bottom margin
; dw = top margin
; dd = inner line color
; dd = outer line color
; dd = frame color
; dd = dtp file size
; ?? = dtp file itself
; ...
;----------------------------------------------------------------------------
; ...
; buttons:
; dd = button type (1 = close, 2 = minimize)
; dw = left button coord (could be negative)
; dw = top button coord (could be negative)
; dw = button width
; dw = button height
; ... etc for all buttons
; dd = 0 (end of buttons list)
; ...
;----------------------------------------------------------------------------
; ...
; bitmaps:
; dw = bitmap kind (1 = left, 2 = oper, 3 = base)
; dw = bitmap type (1 = active, 0 = inactive)
; dd @ bitmap
; ... etc for all bitmaps
; dd 0 (end of bitmaps list)
; ...
;----------------------------------------------------------------------------
; ...
; bitmap:
; dd = bitmap width
; dd = bitmap height
; ?? = raw bitmap data
; ... etc for all bitmaps
; ...
;============================================================================
 
dd 'SKIN',1,__params__,__buttons__,__bitmaps__
 
struc BITMAPFILEHEADER {
.bfType dw ? ; WORD
.bfSize dd ? ; DWORD
.bfReserved1 dw ? ; WORD
.bfReserved2 dw ? ; WORD
.bfOffBits dd ? ; DWORD
}
 
struc BITMAPINFOHEADER {
.biSize dd ? ; DWORD
.biWidth dd ? ; LONG
.biHeight dd ? ; LONG
.biPlanes dw ? ; WORD
.biBitCount dw ? ; WORD
.biCompression dd ? ; DWORD
.biSizeImage dd ? ; DWORD
.biXPelsPerMeter dd ? ; LONG
.biYPelsPerMeter dd ? ; LONG
.biClrUsed dd ? ; DWORD
.biClrImportant dd ? ; DWORD
}
 
struc _bmp {
.h BITMAPFILEHEADER
.i BITMAPINFOHEADER
}
virtual at 0
_bmp _bmp
end virtual
 
macro BITMAP _name*,_fname*
{
local w,h,a,r,g,b
virtual at 0
file _fname
load w dword from _bmp.i.biWidth
load h dword from _bmp.i.biHeight
end virtual
align 4
label _name
.width = w
.height = h
dd w,h
a=54+(w*3+(w mod 4))*(h-1)
size = $
repeat h
repeat w
virtual at 0
file _fname
load r from a+0
load g from a+1
load b from a+2
end virtual
db r,g,b
a=a+3
end repeat
a=a-w*3*2-(w mod 4)
end repeat
}
 
macro define_colors name,[col,val]
{
common
local a,b,c
forward
match =binner,col \{ a = val \}
match =bouter,col \{ b = val \}
match =bframe,col \{ c = val \}
common
name equ a,b,c
}
 
macro SKIN_PARAMS [a]
{
common
local _height,_margins,_colors,_colors_1,_dtp,_dtp_sz
__params__:
forward
match qq == ww,a
\{
match =height,qq \\{ _height = ww \\}
match =margins,qq \\{
match [q1:q2:q3:q4],ww
\\\{
_margins equ q3,q1,q4,q2
\\\}
\\}
match =colors =active,qq
\\{
match [q10==q11:q20==q21:q30==q31],ww
\\\{
define_colors _colors,q10,q11,q20,q21,q30,q31
\\\}
\\}
match =colors =inactive,qq
\\{
match [q10==q11:q20==q21:q30==q31],ww
\\\{
define_colors _colors_1,q10,q11,q20,q21,q30,q31
\\\}
\\}
match =dtp,qq \\{ _dtp equ ww \\}
\}
common
dd _height
dw _margins
dd _colors,_colors_1
virtual at 0
file _dtp
_dtp_sz = $
end virtual
dd _dtp_sz
file _dtp
}
 
macro SKIN_BUTTONS [a]
{
common
local btn
__buttons__:
forward
match qq == ww,a
\{
btn = 0
match =close,qq \\{ btn = 1 \\}
match =minimize,qq \\{ btn = 2 \\}
match [q1:q2][q3:q4],ww
\\{
if btn <> 0
dd btn
dw q1,q2,q3,q4
end if
\\}
\}
common
dd 0
}
 
macro SKIN_BITMAPS [a]
{
common
local bmp
__bitmaps__:
forward
match qq == ww,a
\{
bmp=-1
match qqq =active,qq \\{ bmp = 1 \\}
match qqq =inactive,qq \\{ bmp = 0 \\}
match =left qqq,qq
\\{
if bmp >= 0
dw 1,bmp
dd ww
end if
\\}
match =oper qqq,qq
\\{
if bmp >= 0
dw 2,bmp
dd ww
end if
\\}
match =base qqq,qq
\\{
if bmp >= 0
dw 3,bmp
dd ww
end if
\\}
\}
common
dd 0
}
Property changes:
Added: svn:keywords
+Rev
\ No newline at end of property
/kernel/branches/Kolibri-acpi/skin/base.bmp
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/kernel/branches/Kolibri-acpi/skin/base_1.bmp
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/kernel/branches/Kolibri-acpi/skin/left.bmp
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/kernel/branches/Kolibri-acpi/skin/left_1.bmp
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/kernel/branches/Kolibri-acpi/skin/myblue.dtp
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/kernel/branches/Kolibri-acpi/skin/oper.bmp
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/kernel/branches/Kolibri-acpi/skin/oper_1.bmp
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/kernel/branches/Kolibri-acpi/skin
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
/kernel/branches/Kolibri-acpi/sys.conf
0,0 → 1,18
[path]
/rd/1=/sys
/rd/1/dll=/sys/lib
 
[net]
active=1
addr=192.168.1.2
mask=255.255.255.0
gate=192.168.1.1
 
[gui]
mouse_speed=1
mouse_delay=0x00A
 
[dev]
sb16=0x220
sound_dma=1
midibase=0x320
/kernel/branches/Kolibri-acpi/COPYING.TXT
0,0 → 1,347
 
GNU GENERAL PUBLIC LICENSE
 
Version 2, June 1991
 
 
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
 
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
 
 
Preamble
 
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
 
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
 
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
 
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
 
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
 
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
 
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
 
The precise terms and conditions for copying, distribution and
modification follow.
 
 
GNU GENERAL PUBLIC LICENSE
 
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
 
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
 
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
 
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
 
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
 
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
 
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
 
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
 
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
 
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
 
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
 
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
 
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
 
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
 
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
 
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
 
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
 
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
 
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
 
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
 
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
 
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
 
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
 
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
 
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
 
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
 
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
 
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
 
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
 
NO WARRANTY
 
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
 
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
 
END OF TERMS AND CONDITIONS
 
Appendix: How to Apply These Terms to Your New Programs
 
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
 
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
 
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
 
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.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
Also add information on how to contact you by electronic and paper mail.
 
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
 
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
 
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
 
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
 
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
 
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
 
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
/kernel/branches/Kolibri-acpi
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
+*.obj
Added: tsvn:logminsize
+5
\ No newline at end of property