Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 203 → Rev 204

/kernel/tags/kolibri0.6.3.0/core/memory.inc
0,0 → 1,1328
 
tmp_page_tab equ 0x01000000
 
align 4
proc mem_test
mov eax, cr0
or eax, (CR0_CD+CR0_NW);disable caching
mov cr0, eax
wbinvd ;invalidate cache
 
xor edi, edi
mov ebx, 'TEST'
@@:
add edi, 0x400000
xchg ebx, dword [edi]
cmp dword [edi], 'TEST'
xchg ebx, dword [edi]
je @b
 
and eax, not (CR0_CD+CR0_NW)
mov cr0, eax
mov eax, edi
ret
endp
 
align 4
proc init_memEx
xor eax, eax
mov edi, sys_pgdir
mov ecx, 2048
rep stosd
 
bt [cpu_caps], CAPS_PSE
jnc .no_PSE
 
mov ebx, cr4
or ebx, CR4_PSE
mov eax, PG_LARGE+PG_SW
bt [cpu_caps], CAPS_PGE
jnc @F
or eax, PG_GLOBAL
or ebx, CR4_PGE
 
@@:
mov cr4, ebx
 
mov dword [sys_pgdir], eax
add eax, 0x00400000
mov dword [sys_pgdir+4], eax
add eax, 0x00400000
mov dword [sys_pgdir+8], eax
add eax, 0x00400000
mov dword [sys_pgdir+12], eax
 
mov dword [sys_pgdir+0x600], sys_pgdir+PG_SW
 
mov ecx, [pg_data.kernel_tables]
sub ecx, 4
mov eax, tmp_page_tab+PG_SW
mov edi, sys_pgdir+16
 
jmp .map_kernel_tabs
.no_PSE:
mov eax, PG_SW
mov esi, tmp_page_tab
mov ecx, 4096/4 ;0x0 - 0x00FFFFFF
.map_low:
mov [esi], eax
add eax, 0x1000
mov [esi+4], eax
add eax, 0x1000
mov [esi+8], eax
add eax, 0x1000
mov [esi+12], eax
add eax, 0x1000
add esi, 16
dec ecx
jnz .map_low ;ÿäðî
 
mov ecx, [pg_data.kernel_tables]
mov eax, tmp_page_tab+PG_SW
mov edi, sys_pgdir
 
.map_kernel_tabs:
 
mov [edi], eax
add eax, 0x1000
add edi, 4
dec ecx
jnz .map_kernel_tabs
 
mov edi, tmp_page_tab
bt [cpu_caps], CAPS_PSE
jc @F
add edi, 4096*4 ;skip low kernel memory
@@:
mov ecx, [pg_data.kernel_tables]
sub ecx, 4
shl ecx, 10
xor eax, eax
cld
rep stosd
 
mov dword [sys_pgdir+0x600], sys_pgdir+PG_SW
 
ret
endp
 
align 4
proc init_page_map
mov edi, sys_pgmap
mov ecx, 512/4
xor eax,eax
cld
rep stosd
 
not eax
mov ecx, [pg_data.pagemap_size]
sub ecx, 512
shr ecx, 2
rep stosd
 
mov edi, sys_pgmap+512
mov edx, [pg_data.pages_count]
mov ecx, [pg_data.kernel_tables]
bt [cpu_caps], CAPS_PSE
jnc @f
sub ecx, 4
@@:
sub edx, 4096
sub edx, ecx
mov [pg_data.pages_free], edx
 
xor eax, eax
mov ebx, ecx
shr ecx, 5
rep stosd
 
not eax
mov ecx, ebx
and ecx, 31
shl eax, cl
stosd
 
mov [page_start], sys_pgmap+512
mov ebx, sys_pgmap
add ebx, [pg_data.pagemap_size]
mov [page_end], ebx
 
mov [pg_data.pg_mutex], 0
 
ret
endp
 
align 4
proc alloc_page
 
pushfd
cli
mov ebx, [page_start]
mov ecx, [page_end]
.l1:
bsf eax,[ebx];
jnz .found
add ebx,4
cmp ebx, ecx
jb .l1
popfd
xor eax,eax
ret
.found:
btr [ebx], eax
mov [page_start],ebx
sub ebx, sys_pgmap
shl ebx, 3
add eax,ebx
shl eax, 12
dec [pg_data.pages_free]
popfd
ret
endp
 
align 4
proc alloc_pages stdcall, count:dword
pushfd
cli
mov eax, [count]
add eax, 7
shr eax, 3
mov [count], eax
cmp eax, [pg_data.pages_free]
ja .fail
 
mov ecx, [page_start]
mov ebx, [page_end]
.find:
mov edx, [count]
mov edi, ecx
.match:
cmp byte [ecx], 0xFF
jne .next
dec edx
jz .ok
inc ecx
cmp ecx,ebx
jb .match
.fail: xor eax, eax
popfd
ret
.next:
inc ecx
cmp ecx, ebx
jb .find
popfd
xor eax, eax
ret
.ok:
sub ecx, edi
inc ecx
mov esi, edi
xor eax, eax
rep stosb
sub esi, sys_pgmap
shl esi, 3+12
mov eax, esi
mov ebx, [count]
shl ebx, 3
sub [pg_data.pages_free], ebx
popfd
ret
endp
 
align 4
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, [flags]
mov ebx, [lin_addr]
shr ebx, 12
mov [pages_tab+ebx*4], eax
mov eax, [lin_addr]
invlpg [eax]
ret
endp
 
align 4
proc free_page
;arg: eax page address
pushfd
cli
inc [pg_data.pages_free]
shr eax, 12 ;page index
mov ebx, sys_pgmap
bts [ebx], eax ;that's all!
shr eax, 3
and eax, not 3 ;dword offset from page_map
add eax, ebx
cmp [page_start], eax
ja @f
popfd
ret
@@:
mov [page_start], eax
popfd
ret
endp
 
align 4
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
mov ebx, [lin_addr]
shr ebx, 22
mov eax, [phis_addr]
and eax, not 0xFFF
or eax, PG_UW ;+PG_NOCACHE
mov dword [current_pgdir+ebx*4], eax
mov eax, [lin_addr]
shr eax, 10
add eax, pages_tab
invlpg [eax]
ret
endp
 
align 4
proc init_LFB
 
cmp dword [LFBAddress], -1
jne @f
 
mov [0x2f0000+0x901c],byte 2
stdcall kernel_alloc, 0x280000
mov [LFBAddress], eax
 
ret
@@:
test [SCR_MODE],word 0100000000000000b
jz @f
call map_LFB
@@:
ret
endp
 
align 4
proc map_LFB
locals
pg_count dd ?
endl
 
mov edi, [LFBSize]
mov esi, [LFBAddress]
shr edi, 12
mov [pg_count], edi
shr edi, 10
 
bt [cpu_caps], CAPS_PSE
jnc .map_page_tables
mov ebx, esi
or esi, PG_LARGE+PG_UW
shr ebx, 20
mov ecx, ebx
@@:
mov [sys_pgdir+ebx], esi
add ebx, 4
add esi, 0x00400000
dec edi
jnz @B
 
or dword [sys_pgdir+ecx], PG_GLOBAL
mov eax, cr3 ;flush TLB
mov cr3, eax
ret
 
.map_page_tables:
 
@@:
call alloc_page
stdcall map_page_table, esi, eax
add esi, 0x00400000
dec edi
jnz @B
 
mov eax, [LFBAddress]
mov esi, eax
shr esi, 10
add esi, pages_tab
or eax, PG_UW
mov ecx, [pg_count]
shr ecx, 2
.map:
mov [esi], eax
add eax, 0x1000
mov [esi+4], eax
add eax, 0x1000
mov [esi+8], eax
add eax, 0x1000
mov [esi+12], eax
add eax, 0x1000
add esi, 16
sub ecx, 1
jnz .map
 
mov eax, cr3 ;flush TLB
mov cr3, eax
 
ret
endp
 
align 4
proc new_mem_resize stdcall, new_size:dword
 
stdcall wait_mutex, pg_data.pg_mutex
 
mov edi, [new_size]
add edi,4095
and edi,not 4095
mov [new_size], edi
 
mov edx,[CURRENT_TASK]
shl edx,8
cmp [PROC_BASE+APPDATA.heap_base+edx],0
jne .exit
 
mov esi, [PROC_BASE+APPDATA.mem_size+edx]
add esi, 4095
and esi, not 4095
 
cmp edi, esi
jae .expand
 
shr edi, 12
shr esi, 12
@@:
mov eax, [pages_tab+0x00181000+edi*4]
test eax, 1
jz .next
mov dword [pages_tab+0x00181000+edi*4], 2
mov ebx, edi
shl ebx, 12
invlpg [ebx+std_application_base_address]
call free_page
 
.next: add edi, 1
cmp edi, esi
jb @B
 
.update_size:
 
mov ebx, [new_size]
mov [PROC_BASE+0x8c+edx],ebx
 
;search threads and update
;application memory size infomation
mov ecx,[PROC_BASE+0xb8+edx]
mov eax,2
 
.search_threads:
;eax = current slot
;ebx = new memory size
;ecx = page directory
cmp eax,[TASK_COUNT]
jg .search_threads_end
mov edx,eax
shl edx,5
cmp word [CURRENT_TASK+edx+0xa],9 ;if slot empty?
jz .search_threads_next
shl edx,3
cmp [PROC_BASE+edx+0xb8],ecx ;if it is our thread?
jnz .search_threads_next
mov [PROC_BASE+edx+0x8c],ebx ;update memory size
.search_threads_next:
inc eax
jmp .search_threads
.search_threads_end:
xor eax, eax
dec [pg_data.pg_mutex]
ret
 
.expand:
add edi, new_app_base
add esi, new_app_base
 
push esi
push edi
 
add edi, 0x3FFFFF
and edi, not(0x3FFFFF)
add esi, 0x3FFFFF
and esi, not(0x3FFFFF)
 
cmp esi, edi
jae .grow
 
xchg esi, edi
 
@@:
call alloc_page
test eax, eax
jz .exit
 
stdcall map_page_table, edi, eax
 
push edi
shr edi, 10
add edi, pages_tab
mov ecx, 1024
xor eax, eax
cld
rep stosd
pop edi
 
add edi, 0x00400000
cmp edi, esi
jb @B
.grow:
pop edi
pop esi
@@:
call alloc_page
test eax, eax
jz .exit
stdcall map_page,esi,eax,dword PG_UW
 
push edi
mov edi, esi
xor eax, eax
mov ecx, 1024
cld
rep stosd
pop edi
 
add esi, 0x1000
cmp esi, edi
jna @B
 
jmp .update_size
.exit:
xor eax, eax
inc eax
dec [pg_data.pg_mutex]
ret
endp
 
align 4
proc get_pg_addr stdcall, lin_addr:dword
mov ebx, [lin_addr]
shr ebx, 12
mov eax, [pages_tab+ebx*4]
and eax, 0xFFFFF000
ret
endp
 
align 4
proc page_fault_handler
pushad
 
mov ebp, esp
mov eax, cr2
push eax
push ds
push es
 
mov ax, 0x10
mov ds, ax
mov es, ax
 
inc [pg_data.pages_faults]
 
mov ebx, [ebp-4]
 
cmp ebx, 0xe0000000
jae .lfb_addr
 
cmp ebx, 0x60400000
jae .user_space
 
cmp ebx, master_tab+0x1000
jae .alloc
 
cmp ebx, 0x60000000
jae .tab_space
 
jmp .kernel_space
 
.user_space:
shr ebx, 12
mov ecx, ebx
shr ecx, 10
mov edx, [master_tab+ecx*4]
test edx, 1
jz .fail
 
mov eax, [pages_tab+ebx*4]
test eax, 2
jz .fail
.alloc:
call alloc_page
and eax, eax
jz .exit
 
stdcall map_page,[ebp-4],eax,dword PG_UW
 
mov edi, [ebp-4]
and edi, 0xFFFFF000
mov ecx, 1024
xor eax, eax
cld
rep stosd
.exit:
pop es
pop ds
mov esp, ebp
popad
add esp, 4
iretd
.fail:
pop es
pop ds
mov esp, ebp
popad
add esp, 4
 
save_ring3_context ;debugger support
 
mov bl, 14
jmp exc_c
iretd
 
.kernel_space:
; shr ebx, 12
; mov eax, [pages_tab+ebx*4]
; shr ebx, 10
; mov eax, [master_tab+ebx*4]
jmp .exit
.old_addr:
; shr ebx, 12
; mov eax, [pages_tab+ebx*4]
; shr ebx, 10
; mov eax, [master_tab+ebx*4]
jmp .exit
.lfb_addr:
; shr ebx, 22
; ;mov ecx, [sys_page_dir]
; mov eax, [master_tab+ebx*4]
jmp .exit
.tab_space:
; shr ebx, 12
; mov eax, [pages_tab+ebx*4]
; shr ebx, 10
; ;mov ecx, [sys_page_dir]
; mov eax, [master_tab+ebx*4]
jmp .exit
endp
 
align 4
proc map_mem stdcall, lin_addr:dword,pdir:dword,\
ofs:dword,buf_size:dword
mov eax, [buf_size]
test eax, eax
jz .exit
 
mov eax, [pdir]
and eax, 0xFFFFF000
 
stdcall map_page,[ipc_pdir],eax,dword PG_UW
mov ebx, [ofs]
shr ebx, 22
mov esi, [ipc_pdir]
mov edi, [ipc_ptab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000
test eax, eax
jz .exit
stdcall map_page,edi,eax,dword PG_UW
; inc ebx
; add edi, 0x1000
; mov eax, [esi+ebx*4]
; test eax, eax
; jz @f
; and eax, 0xFFFFF000
; stdcall map_page, edi, eax
 
@@: mov edi, [lin_addr]
and edi, 0xFFFFF000
mov ecx, [buf_size]
add ecx, 4095
shr ecx, 12
inc ecx
 
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
mov esi, [ipc_ptab]
 
.map: mov eax, [esi+edx*4]
and eax, 0xFFFFF000
test eax, eax
jz .exit
stdcall map_page,edi,eax,dword PG_UW
add edi, 0x1000
inc edx
dec ecx
jnz .map
 
.exit:
ret
endp
 
align 4
proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
ofs:dword,buf_size:dword
mov eax, [buf_size]
test eax, eax
jz .exit
 
mov eax, [pdir]
and eax, 0xFFFFF000
 
stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
mov ebx, [ofs]
shr ebx, 22
mov esi, [proc_mem_pdir]
mov edi, [proc_mem_tab]
mov eax, [esi+ebx*4]
and eax, 0xFFFFF000
test eax, eax
jz .exit
stdcall map_page,edi,eax,dword PG_UW
 
@@: mov edi, [lin_addr]
and edi, 0xFFFFF000
mov ecx, [buf_size]
add ecx, 4095
shr ecx, 12
inc ecx
 
mov edx, [ofs]
shr edx, 12
and edx, 0x3FF
mov esi, [proc_mem_tab]
 
.map: mov eax, [esi+edx*4]
; and eax, 0xFFFFF000
; test eax, eax
; jz .exit
stdcall map_page,edi,eax,dword PG_UW
add edi, 0x1000
inc edx
dec ecx
jnz .map
.exit:
ret
endp
 
 
 
 
sys_IPC:
;input:
; eax=1 - set ipc buffer area
; ebx=address of buffer
; ecx=size of buffer
; eax=2 - send message
; ebx=PID
; ecx=address of message
; edx=size of message
 
cmp eax,1
jne @f
call set_ipc_buff
mov [esp+36], eax
ret
@@:
cmp eax, 2
jne @f
stdcall sys_ipc_send, ebx, ecx, edx
mov [esp+36], eax
ret
@@:
xor eax, eax
not eax
mov [esp+36], eax
ret
 
align 4
proc set_ipc_buff
 
mov eax,[CURRENT_TASK]
shl eax,8
add eax, PROC_BASE
pushf
cli
mov [eax+0xA0],ebx ;set fields in extended information area
mov [eax+0xA4],ecx
 
add ebx, new_app_base
add ecx, ebx
add ecx, 4095
and ecx, not 4095
 
.touch: mov eax, [ebx]
add ebx, 0x1000
cmp ebx, ecx
jna .touch
 
popf
xor eax, eax
ret
endp
 
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
locals
dst_slot dd ?
dst_offset dd ?
buf_size dd ?
endl
 
pushf
cli
 
mov eax, [PID]
call pid_to_slot
test eax,eax
jz .no_pid
 
mov [dst_slot], eax
shl eax,8
mov edi,[eax+PROC_BASE+0xa0] ;is ipc area defined?
test edi,edi
jz .no_ipc_area
 
mov ebx, edi
add edi, new_app_base
and ebx, 0xFFF
mov [dst_offset], ebx
 
mov esi, [eax+PROC_BASE+0xa4]
mov [buf_size], esi
 
stdcall map_mem, [ipc_tmp], [PROC_BASE+eax+0xB8],\
edi, esi
 
mov edi, [dst_offset]
add edi, [ipc_tmp]
cmp dword [edi], 0
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now
mov ebx, dword [edi+4]
mov edx, ebx
add ebx, 8
add ebx, [msg_size]
cmp ebx, [buf_size]
ja .buffer_overflow ;esi<0 - not enough memory in buffer
mov dword [edi+4], ebx
mov eax,[TASK_BASE]
mov eax, [eax+0x04] ;eax - our PID
mov edi, [dst_offset]
add edi, [ipc_tmp]
add edi, edx
mov [edi], eax
mov ecx, [msg_size]
 
mov [edi+4], ecx
add edi, 8
mov esi, [msg_addr]
add esi, new_app_base
cld
rep movsb
 
mov ebx, [ipc_tmp]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [pages_tab+ebx*4], eax
invlpg [edx]
 
mov ebx, [ipc_pdir]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [pages_tab+ebx*4], eax
invlpg [edx]
 
mov ebx, [ipc_ptab]
mov edx, ebx
shr ebx, 12
xor eax, eax
mov [pages_tab+ebx*4], eax
invlpg [edx]
 
mov eax, [dst_slot]
shl eax, 8
or [eax+PROC_BASE+0xA8],dword 0x40
cmp dword [check_idle_semaphore],20
jge .ipc_no_cis
 
mov dword [check_idle_semaphore],5
.ipc_no_cis:
popf
xor eax, eax
ret
.no_pid:
popf
mov eax, 4
ret
.no_ipc_area:
popf
xor eax, eax
inc eax
ret
.ipc_blocked:
popf
mov eax, 2
ret
.buffer_overflow:
popf
mov eax, 3
ret
endp
 
align 4
sysfn_meminfo:
 
add ebx, new_app_base
cmp ebx, new_app_base
jb .fail
 
mov eax, [pg_data.pages_count]
mov [ebx], eax
shl eax, 12
mov [esp+36], eax
mov ecx, [pg_data.pages_free]
mov [ebx+4], ecx
mov edx, [pg_data.pages_faults]
mov [ebx+8], edx
mov esi, [heap_size]
mov [ebx+12], esi
mov edi, [heap_free]
mov [ebx+16], edi
mov eax, [heap_blocks]
mov [ebx+20], eax
mov ecx, [free_blocks]
mov [ebx+24], ecx
ret
.fail:
mov dword [esp+36], -1
ret
 
align 4
new_services:
 
cmp eax,4
jle sys_sheduler
 
cmp eax, 11
jb .fail
ja @f
 
call init_heap
mov [esp+36], eax
ret
@@:
cmp eax, 12
ja @f
 
stdcall user_alloc, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 13
ja @f
add ebx, new_app_base
stdcall user_free, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 14
ja @f
add ebx,new_app_base
cmp ebx, new_app_base
jb .fail
stdcall get_notify, ebx
ret
@@:
cmp eax, 15
ja @f
mov ecx, [CURRENT_TASK]
shl ecx, 8
mov eax, [ecx+PROC_BASE+APPDATA.fpu_handler]
mov [ecx+PROC_BASE+APPDATA.fpu_handler], ebx
mov [esp+36], eax
ret
@@:
cmp eax, 16
ja @f
 
test ebx, ebx
jz .fail
add ebx, new_app_base
cmp ebx, new_app_base
jb .fail
stdcall get_service, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 17
ja @f
stdcall srv_handlerEx, ebx
mov [esp+36], eax
ret
@@:
cmp eax, 18
ja @f
mov ecx, [CURRENT_TASK]
shl ecx, 8
mov eax, [ecx+PROC_BASE+APPDATA.sse_handler]
mov [ecx+PROC_BASE+APPDATA.sse_handler], ebx
mov [esp+36], eax
ret
@@:
cmp eax, 19
ja @f
add ebx, new_app_base
cmp ebx, new_app_base
jb .fail
stdcall load_library, ebx
mov [esp+36], eax
ret
@@:
.fail:
xor eax, eax
mov [esp+36], eax
ret
 
align 4
proc strncmp stdcall, str1:dword, str2:dword, count:dword
 
mov ecx,[count]
jecxz .end
 
mov ebx,ecx
 
mov edi,[str1]
mov esi,edi
xor eax,eax
repne scasb
neg ecx ; cx = count - strlen
add ecx,ebx ; strlen + count - strlen
 
.okay:
mov edi,esi
mov esi,[str2]
repe cmpsb
mov al,[esi-1]
xor ecx,ecx
 
cmp al,[edi-1]
ja .str2_big
je .end
 
.str1_big:
sub ecx,2
 
.str2_big:
not ecx
.end:
mov eax,ecx
ret
endp
 
align 4
proc fpu_save
clts
mov ebx, [fpu_owner]
shl ebx, 8
mov eax, [ebx+PROC_BASE+0x10]
mov ebx, [CURRENT_TASK]
mov [fpu_owner], ebx
 
bt [cpu_caps], CAPS_FXSR
jnc .no_SSE
 
fxsave [eax]
fninit ;re-init fpu
ret
.no_SSE:
fnsave [eax]
ret
endp
 
align 4
proc fpu_restore
mov ebx, [CURRENT_TASK]
shl ebx, 8
mov eax, [ebx+PROC_BASE+0x10]
bt [cpu_caps], CAPS_FXSR
jnc .no_SSE
 
fxrstor [eax]
ret
.no_SSE:
fnclex ;fix possible problems
frstor [eax]
ret
endp
 
align 4
proc test_cpu
locals
cpu_type dd ?
cpu_id dd ?
cpu_Intel dd ?
cpu_AMD dd ?
endl
 
mov [cpu_type], 0
 
pushfd
pop eax
mov ecx, eax
xor eax, 0x40000
push eax
popfd
pushfd
pop eax
xor eax, ecx
mov [cpu_type], CPU_386
jz .end_cpu
push ecx
popfd
 
mov [cpu_type], CPU_486
mov eax, ecx
xor eax, 0x200000
push eax
popfd
pushfd
pop eax
xor eax, ecx
je .end_cpu
mov [cpu_id], 1
 
xor eax, eax
cpuid
mov [cpu_vendor], ebx
mov [cpu_vendor+4], edx
mov [cpu_vendor+8], ecx
cmp ebx, dword [intel_str]
jne .check_AMD
cmp edx, dword [intel_str+4]
jne .check_AMD
cmp ecx, dword [intel_str+8]
jne .check_AMD
mov [cpu_Intel], 1
cmp eax, 1
jl .end_cpuid
mov eax, 1
cpuid
mov [cpu_sign], eax
mov [cpu_info], ebx
mov [cpu_caps], edx
mov [cpu_caps+4],ecx
 
shr eax, 8
and eax, 0x0f
mov [cpu_type], eax
ret
 
.end_cpuid:
mov eax, [cpu_type]
ret
 
.check_AMD:
cmp ebx, dword [AMD_str]
jne .end_cpu
cmp edx, dword [AMD_str+4]
jne .end_cpu
cmp ecx, dword [AMD_str+8]
jne .end_cpu
mov [cpu_AMD], 1
cmp eax, 1
jl .end_cpuid
mov eax, 1
cpuid
mov [cpu_sign], eax
mov [cpu_info], ebx
mov [cpu_caps], edx
mov [cpu_caps+4],ecx
shr eax, 8
and eax, 0x0f
mov [cpu_type], eax
.end_cpu:
mov eax, [cpu_type]
ret
endp
 
MEM_WB equ 6 ;write-back memory
MEM_WC equ 1 ;write combined memory
MEM_UC equ 0 ;uncached memory
 
align 4
proc init_mtrr
 
cmp [0x2f0000+0x901c],byte 2
je .exit
 
mov eax, cr0
or eax, 0x60000000 ;disable caching
mov cr0, eax
wbinvd ;invalidate cache
 
mov ecx, 0x2FF
rdmsr ;
push eax
 
xor edx, edx
xor eax, eax
mov ecx, 0x2FF
wrmsr ;disable all MTRR
 
stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB
stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC
xor edx, edx
xor eax, eax
mov ecx, 0x204
mov ebx, 6
@@:
wrmsr ;disable unused MTRR
inc ecx
wrmsr
inc ecx
dec ebx
jnz @b
 
wbinvd ;again invalidate
 
pop eax
or eax, 0x800 ;set default memtype to UC
and al, 0xF0
mov ecx, 0x2FF
wrmsr ;and enable MTRR
 
mov eax, cr0
and eax, not 0x60000000
mov cr0, eax ; enable caching
.exit:
ret
endp
 
align 4
proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
 
xor edx, edx
mov eax, [base]
or eax, [mem_type]
mov ecx, [reg]
lea ecx, [0x200+ecx*2]
wrmsr
 
mov ebx, [size]
dec ebx
mov eax, 0xFFFFFFFF
mov edx, 0x0000000F
sub eax, ebx
sbb edx, 0
or eax, 0x800
inc ecx
wrmsr
ret
endp
 
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
 
iglobal
align 4
intel_str db "GenuineIntel",0
AMD_str db "AuthenticAMD",0
endg
 
uglobal
align 16
irq_tab rd 16
 
 
MEM_FreeSpace rd 1
 
ipc_tmp rd 1
ipc_pdir rd 1
ipc_ptab rd 1
 
proc_mem_map rd 1
proc_mem_pdir rd 1
proc_mem_tab rd 1
 
tmp_task_pdir rd 1
tmp_task_ptab rd 1
tmp_task_data rd 1
 
; current_pdir rd 1
 
fpu_data rd 1
fdd_buff rd 1
 
stall_mcs rd 1
;;CPUID information
 
cpu_vendor rd 3
cpu_sign rd 1
cpu_info rd 1
 
endg
 
uglobal
align 16
dll_tab rb 32*32
srv_tab rb 32*32
dll_map rd 1
srv_map rd 1
 
mem_used_list rd 1
mem_block_list rd 64
mem_block_map rb 512
mem_block_arr rd 1
mem_block_start rd 1
mem_block_end rd 1
mem_block_mask rd 2
heap_size rd 1
heap_free rd 1
heap_blocks rd 1
free_blocks rd 1
 
page_start rd 1
page_end rd 1
sys_page_map rd 1
; app_load rd 1
endg
 
 
; push eax
; push edx
; mov edx, 0x400 ;bocsh
; mov al,0xff ;bocsh
; out dx, al ;bocsh
; pop edx
; pop eax
 
/kernel/tags/kolibri0.6.3.0/core/sys32.inc
0,0 → 1,995
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; MenuetOS process management, protected ring3 ;;
;; ;;
;; Distributed under GPL. See file COPYING for details. ;;
;; Copyright 2003 Ville Turjanmaa ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
idtreg:
dw 8*0x41-1
dd idts+8
;label idts at 0xB100-8
 
 
uglobal
tss_sceleton:
l.back dw 0,0
l.esp0 dd 0
l.ss0 dw 0,0
l.esp1 dd 0
l.ss1 dw 0,0
l.esp2 dd 0
l.ss2 dw 0,0
l.cr3 dd 0
l.eip dd 0
l.eflags dd 0
l.eax dd 0
l.ecx dd 0
l.edx dd 0
l.ebx dd 0
l.esp dd 0
l.ebp dd 0
l.esi dd 0
l.edi dd 0
l.es dw 0,0
l.cs dw 0,0
l.ss dw 0,0
l.ds dw 0,0
l.fs dw 0,0
l.gs dw 0,0
l.ldt dw 0,0
l.trap dw 0
l.io dw 0
endg
 
 
build_process_gdt_tss_pointer:
 
mov ecx,tss_data
mov edi,0
setgdtl2:
mov [edi+gdts+ tss0 +0], word tss_step
mov [edi+gdts+ tss0 +2], cx
mov eax,ecx
shr eax,16
mov [edi+gdts+ tss0 +4], al
mov [edi+gdts+ tss0 +7], ah
mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
add ecx,tss_step
add edi,8
cmp edi,8*(max_processes+5)
jbe setgdtl2
 
ret
 
 
build_interrupt_table:
 
mov edi, idts+8
mov esi, sys_int
mov ecx, 0x40
@@:
mov eax, [esi]
mov [edi], ax ; lower part of offset
mov [edi+2], word os_code ; segment selector
shr eax, 16
mov [edi+4], word 10001110b shl 8 ; interrupt descriptor
mov [edi+6], ax
add esi, 4
add edi, 8
dec ecx
jnz @b
 
;mov edi,8*0x40+idts+8
mov [edi + 0], word (i40 and ((1 shl 16)-1))
mov [edi + 2], word os_code
mov [edi + 4], word 11101110b*256
mov [edi + 6], word (i40 shr 16)
 
ret
 
iglobal
sys_int:
dd e0,debug_exc,e2,e3
dd e4,e5,e6,e7
dd e8,e9,e10,e11
dd e12,e13,page_fault_handler,e15
 
dd except_16, e17,e18, except_19
times 12 dd unknown_interrupt
 
dd irq0 , irq_serv.irq_1, p_irq2 ,irq_serv.irq_3
dd p_irq4 ,irq_serv.irq_5,p_irq6,irq_serv.irq_7
dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10
dd irq_serv.irq_11,p_irq12,irqD ,p_irq14,p_irq15
 
times 16 dd unknown_interrupt
 
dd i40
endg
 
macro save_ring3_context
{
push ds es
pushad
}
macro restore_ring3_context
{
popad
pop es ds
}
 
; simply return control to interrupted process
unknown_interrupt:
iret
 
macro exc_wo_code [num]
{
forward
e#num :
save_ring3_context
mov bl, num
jmp exc_c
}
 
macro exc_w_code [num]
{
forward
e#num :
add esp, 4
save_ring3_context
mov bl, num
jmp exc_c
}
 
exc_wo_code 0, 1, 2, 3, 4, 5, 6, 9, 15, 18
exc_w_code 8, 10, 11, 12, 13, 14, 17
 
exc_c:
mov ax, os_data
mov ds, ax
mov es, ax
 
; test if debugging
cli
mov eax, [0x3000]
shl eax, 8
mov eax, [0x80000+eax+APPDATA.debugger_slot]
test eax, eax
jnz .debug
sti
; not debuggee => say error and terminate
add esp, 28h
movzx eax, bl
mov [error_interrupt], eax
call show_error_parameters
 
mov edx, [0x3010]
mov [edx + TASKDATA.state], byte 4
 
jmp change_task
 
.debug:
; we are debugged process, notify debugger and suspend ourself
; eax=debugger PID
cld
movzx ecx, bl
push ecx
mov ecx, [0x3010]
push dword [ecx+TASKDATA.pid] ; PID of current process
push 12
pop ecx
push 1 ; 1=exception
call debugger_notify
pop ecx
pop ecx
pop ecx
mov edx, [0x3010]
mov byte [edx+TASKDATA.state], 1 ; suspended
call change_task
restore_ring3_context
iretd
 
;;;;;;;;;;;;;;;;;;;;;;;
;; FPU ERROR HANDLER ;;
;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
e7:
save_ring3_context
clts
mov ax, os_data
mov ds, ax
mov es, ax
 
mov ebx, [fpu_owner]
cmp ebx, [CURRENT_TASK]
je .exit
 
shl ebx, 8
mov eax, [ebx+PROC_BASE+APPDATA.fpu_state]
bt [cpu_caps], CAPS_FXSR
jnc .no_SSE
 
fxsave [eax]
mov ebx, [CURRENT_TASK]
mov [fpu_owner], ebx
shl ebx, 8
cmp dword [ebx+PROC_BASE+APPDATA.fpu_init], 0
je .init
mov eax, [ebx+PROC_BASE+APPDATA.fpu_state]
fxrstor [eax]
restore_ring3_context
iret
 
.no_SSE:
fnsave [eax]
mov ebx, [CURRENT_TASK]
mov [fpu_owner], ebx
shl ebx, 8
cmp dword [ebx+PROC_BASE+APPDATA.fpu_init], 0
je .ready
 
mov eax, [ebx+PROC_BASE+APPDATA.fpu_state]
frstor [eax]
restore_ring3_context
iret
.init:
fninit ;­ ¬ ­¥ ­ã¦­ë ­¥¬ áª¨à®¢ ­­ë¥ ¨áª«î祭¨ï
.ready:
mov dword [ebx+PROC_BASE+APPDATA.fpu_init], 1
.exit:
restore_ring3_context
iret
 
iglobal
fpu_owner dd 1
endg
 
 
writehex:
pusha
 
mov edi, [write_error_to]
mov esi, 8
@@:
mov ecx, eax
and ecx, 0xf
 
mov cl,[ecx+hexletters]
mov [edi],cl
dec edi
 
shr eax,4
dec esi
jnz @b
 
popa
ret
 
iglobal
hexletters db '0123456789ABCDEF'
 
error_interrupt dd -1
 
process_error db 'K : Process - forced terminate INT: 00000000',13,10,0
process_pid db 'K : Process - forced terminate PID: 00000000',13,10,0
process_eip db 'K : Process - forced terminate EIP: 00000000',13,10,0
system_error db 'K : Kernel error',13,10,0
endg
 
uglobal
write_error_to dd 0x0
endg
 
show_error_parameters:
 
mov [write_error_to],process_pid+43
mov eax,[0x3000]
shl eax, 5
mov eax,[0x3000+TASKDATA.pid+eax]
call writehex
 
mov [write_error_to],process_error+43
mov eax,[error_interrupt]
call writehex
 
cmp dword [esp+4+4], os_code ; CS
jnz @f
mov esi,system_error
call sys_msg_board_str
@@:
mov eax, [esp+4] ; EIP
 
mov [write_error_to],process_eip+43
call writehex
 
mov esi,process_error
call sys_msg_board_str
 
mov esi,process_pid
call sys_msg_board_str
 
mov esi,process_eip
call sys_msg_board_str
 
ret
 
 
 
; irq1 -> hid/keyboard.inc
 
 
macro irqh [num]
{
forward
p_irq#num :
save_ring3_context
mov edi, num
jmp irq_c
}
 
irqh 2,5,7,8,9,10,11
 
irq_c:
mov ax, os_data
mov ds, ax
mov es, ax
call irqhandler
restore_ring3_context
iret
 
p_irq6:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
call fdc_irq
call ready_for_next_irq
restore_ring3_context
iret
 
p_irq3:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
cmp [com2_mouse_detected],0
je old_irq3_handler
call check_mouse_data_com2
jmp p_irq3_1
old_irq3_handler:
mov edi,3
call irqhandler
p_irq3_1:
restore_ring3_context
iret
 
p_irq4:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
cmp [com1_mouse_detected],0
je old_irq4_handler
call check_mouse_data_com1
jmp p_irq4_1
old_irq4_handler:
mov edi,4
call irqhandler
p_irq4_1:
restore_ring3_context
iret
 
p_irq12:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
call check_mouse_data_ps2
restore_ring3_context
iret
 
p_irq14:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
call [irq14_func]
call ready_for_next_irq_1
restore_ring3_context
iret
p_irq15:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
call [irq15_func]
call ready_for_next_irq_1
restore_ring3_context
iret
 
ready_for_next_irq:
mov [check_idle_semaphore],5
mov al, 0x20
out 0x20, al
ret
 
ready_for_next_irq_1:
mov [check_idle_semaphore],5
mov al, 0x20
out 0xa0,al
out 0x20, al
ret
 
irqD:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
 
mov dx,0xf0
mov al,0
out dx,al
 
mov dx,0xa0
mov al,0x20
out dx,al
mov dx,0x20
out dx,al
 
restore_ring3_context
 
iret
 
 
irqhandler:
 
push edi
 
mov esi,edi ; 1
shl esi,6 ; 1
add esi,irq00read ; 1
shl edi,12 ; 1
add edi,0x2E0000
mov ecx,16
 
mov [check_idle_semaphore],5
 
irqnewread:
dec ecx
js irqover
 
mov dx,[esi] ; 2+
 
cmp dx,0 ; 1
jz irqover
cmp [esi+3],byte 1 ; 2 ; byte read
jne noirqbyte ; 4-11
 
in al,dx
 
mov edx,[edi]
cmp edx,4000
je irqfull
mov ebx,edi
add ebx,0x10
add ebx,edx
mov [ebx],al
inc edx
mov [edi],edx
 
add esi,4
jmp irqnewread
 
noirqbyte:
 
 
cmp [esi+3],byte 2 ; word read
jne noirqword
 
in ax,dx
 
mov edx,[edi]
cmp edx,4000
je irqfull
mov ebx,edi
add ebx,0x10
add ebx,edx
mov [ebx],ax
add edx,2
mov [edi],edx
add esi,4
jmp irqnewread
 
noirqword:
irqfull:
irqover:
 
mov al,0x20 ; ready for next irq
out 0x20,al
 
pop ebx
cmp ebx,7
jbe noa0
out 0xa0,al
noa0:
 
ret
 
 
 
set_application_table_status:
push eax
 
mov eax,[0x3000]
shl eax, 5
add eax,0x3000+TASKDATA.pid
mov eax,[eax]
 
mov [application_table_status],eax
 
pop eax
 
ret
 
 
clear_application_table_status:
push eax
 
mov eax,[0x3000]
shl eax, 5
add eax,0x3000+TASKDATA.pid
mov eax,[eax]
 
cmp eax,[application_table_status]
jne apptsl1
mov [application_table_status],0
apptsl1:
 
pop eax
 
ret
 
 
 
sys_resize_app_memory:
; eax = 1 - resize
; ebx = new amount of memory
 
cmp eax,1
jne .no_application_mem_resize
 
stdcall new_mem_resize, ebx
mov [esp+36], eax
ret
 
.no_application_mem_resize:
ret
 
 
 
get_app_params:
 
push eax
 
cmp [0x90000+6],word '00'
jne no_00_header
 
mov eax,[0x90000+12]
mov [app_start],eax
mov eax,[0x90000+16]
mov [app_i_end],eax
mov eax,[0x90000+20]
mov [app_mem],eax
; \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 eax,[app_i_end]
jb no_01_header
; \end{diamond}[20.08.2006]
shr eax,1
sub eax,0x10
mov [app_esp],eax
mov eax,[0x90000+24]
mov [app_i_param],eax
mov [app_i_icon],dword 0
 
pop eax
clc
ret
 
no_00_header:
 
 
cmp [0x90000+6],word '01'
jne no_01_header
 
mov eax,[0x90000+12]
mov [app_start],eax
mov eax,[0x90000+16]
mov [app_i_end],eax
mov eax,[0x90000+20]
mov [app_mem],eax
; \begin{diamond}[20.08.2006]
cmp eax,[app_i_end]
jb no_01_header
; \end{diamond}[20.08.2006]
mov eax,[0x90000+24]
mov [app_esp],eax
mov eax,[0x90000+28]
mov [app_i_param],eax
mov eax,[0x90000+32]
mov [app_i_icon],eax
 
pop eax
clc
ret
 
no_01_header:
 
pop eax
stc
ret
 
 
uglobal
new_process_place dd 0x0
app_start dd 0x0
app_i_end dd 0x0
app_mem dd 0x0
app_esp dd 0x0
app_i_param dd 0x0
app_i_icon dd 0x0
; app_mem_pos dd 0x0
appl_path dd 0x0
appl_path_size dd 0x0
endg
 
 
sys_threads:
 
; eax=1 create thread
;
; ebx=thread start
; ecx=thread stack value
;
; on return : eax = pid
jmp new_sys_threads
 
iglobal
process_terminating db 'K : Process - terminating',13,10,0
process_terminated db 'K : Process - done',13,10,0
endg
 
 
terminate: ; terminate application
push esi
mov esi,process_terminating
call sys_msg_board_str
pop esi
 
@@:
cli
cmp [application_table_status],0
je term9
sti
call change_task
jmp @b
term9:
 
call set_application_table_status
 
mov eax,esi
 
pushad
shl eax,8
mov eax,[PROC_BASE+eax+0xB8]
stdcall destroy_app_space, eax
popad
 
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1
jne fpu_ok_1
 
mov [fpu_owner],1
mov eax, [256+PROC_BASE+0x10]
bt [cpu_caps], CAPS_FXSR
jnc .no_SSE
fxrstor [eax]
jmp fpu_ok_1
.no_SSE:
fnclex
frstor [eax]
fpu_ok_1:
 
mov [0xf400],byte 0 ; empty keyboard buffer
mov [0xf500],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,[0xfe88]
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 [dlx],eax
add eax,[esi+WDATA.box.width]
mov [dlxe],eax
mov eax,[esi+WDATA.box.top]
mov [dly],eax
add eax,[esi+WDATA.box.height]
mov [dlye],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, [0x80000+edi*8+APPDATA.debugger_slot]
test eax, eax
jz .nodebug
push 8
pop ecx
push dword [0x3000+edi+TASKDATA.pid] ; PID
push 2
call debugger_notify
pop ecx
pop ecx
.nodebug:
popad
 
pusha ; at 0x80000+
mov edi,esi
shl edi,8
add edi,0x80000
mov ecx,256/4
xor eax, eax
rep stosd
popa
 
pusha ; name to spaces
mov edi,esi
shl edi,8
add edi,0x80000+APPDATA.app_name
mov ecx,11
mov eax,' '
rep stosb
popa
 
 
; activate window
movzx eax, word [0xC000 + esi*2]
cmp eax, [0x3004]
jne .dont_activate
pushad
.check_next_window:
dec eax
cmp eax, 1
jbe .nothing_to_activate
lea esi, [0xc400+eax*2]
movzx edi, word [esi] ; edi = process
shl edi, 5
cmp [0x3000 + 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+0x3000+TASKDATA.pid]
cmp [hd1_status], esi
jnz @f
mov [hd1_status], 0
@@:
cmp [cd_status], esi
jnz @f
mov [cd_status], 0
@@:
cmp [flp_status], esi
jnz @f
mov [flp_status], 0
@@:
pop esi
 
pusha ; remove all irq reservations
mov eax,esi
shl eax, 5
mov eax,[eax+0x3000+TASKDATA.pid]
mov edi,irq_owner
mov ecx,16
newirqfree:
scasd
jne nofreeirq
mov [edi-4],dword 0
nofreeirq:
loop newirqfree
popa
 
 
pusha ; remove all port reservations
mov edx,esi
shl edx, 5
add edx,0x3000
mov edx,[edx+TASKDATA.pid]
 
rmpr0:
 
mov esi,[0x2d0000]
 
cmp esi,0
je rmpr9
 
rmpr3:
 
mov edi,esi
shl edi,4
add edi,0x2d0000
 
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 [0x2d0000]
 
jmp rmpr0
 
rmpr9:
 
popa
mov edi,esi ; do not run this process slot
shl edi, 5
mov [edi+0x3000 + TASKDATA.state],byte 9
; debugger test - terminate all debuggees
mov eax, 2
mov ecx, 0x80000+2*0x100+APPDATA.debugger_slot
.xd0:
cmp eax, [0x3004]
ja .xd1
cmp dword [ecx], esi
jnz @f
and dword [ecx], 0
pushad
xchg eax, ebx
mov eax, 2
call sys_system
popad
@@:
inc eax
add ecx, 0x100
jmp .xd0
.xd1:
; call systest
sti ; .. and life goes on
 
mov eax, [dlx]
mov ebx, [dly]
mov ecx, [dlxe]
mov edx, [dlye]
call calculatescreen
xor eax, eax
xor esi, esi
call redrawscreen
 
mov [0xfff4],byte 0 ; no mouse background
mov [0xfff5],byte 0 ; draw mouse
 
mov [application_table_status],0
mov esi,process_terminated
call sys_msg_board_str
 
ret
 
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
call build_interrupt_table
 
ret
 
/kernel/tags/kolibri0.6.3.0/core/dll.inc
0,0 → 1,935
;
; This file is part of the Infinity sound AC97 driver.
; (C) copyright Serge 2006
; email: infinity_sound@mail.ru
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
 
align 4
proc attach_int_handler stdcall, irq:dword, handler:dword
 
mov ebx, [irq] ;irq num
test ebx, ebx
jz .err
mov eax, [handler]
test eax, eax
jz .err
mov [irq_tab+ebx*4], eax
stdcall enable_irq, [irq]
ret
.err:
xor eax, eax
ret
endp
 
align 4
proc detach_int_handler
 
ret
endp
 
align 4
proc enable_irq stdcall, irq_line:dword
mov ebx, [irq_line]
mov edx, 0x21
cmp ebx, 8
jb @F
mov edx, 0xA1
sub ebx,8
@@:
in al,dx
btr eax, ebx
out dx, al
ret
endp
 
align 16
;; proc irq_serv
 
irq_serv:
 
.irq_1:
push eax
mov eax, 1
jmp .main
align 4
.irq_2:
push eax
mov eax, 2
jmp .main
align 4
.irq_3:
push eax
mov eax, 3
jmp .main
align 4
.irq_4:
push eax
mov eax, 4
jmp .main
align 4
.irq_5:
push eax
mov eax, 5
jmp .main
align 4
.irq_6:
push eax
mov eax, 6
jmp .main
align 4
.irq_7:
push eax
mov eax, 7
jmp .main
align 4
.irq_8:
push eax
mov eax, 8
jmp .main
align 4
.irq_9:
push eax
mov eax, 9
jmp .main
align 4
.irq_10:
push eax
mov eax, 10
jmp .main
align 4
.irq_11:
push eax
mov eax, 11
jmp .main
align 4
.irq_12:
push eax
mov eax, 12
jmp .main
align 4
.irq_13:
push eax
mov eax, 13
jmp .main
align 4
.irq_14:
push eax
mov eax, 14
jmp .main
align 4
.irq_15:
push eax
mov eax, 15
jmp .main
 
align 16
.main:
save_ring3_context
mov bx, os_data
mov ds, bx
mov es, bx
 
mov ebx, [irq_tab+eax*4]
test ebx, ebx
jz .exit
 
call ebx
 
.exit:
restore_ring3_context
 
cmp eax, 8
mov al, 0x20
jb @f
out 0xa0, al
@@:
out 0x20, al
 
pop eax
iret
 
align 4
proc get_notify stdcall, p_ev:dword
 
.wait:
mov ebx,[CURRENT_TASK]
shl ebx,8
test dword [ebx+PROC_BASE+0xA8],EVENT_NOTIFY
jz @f
and dword [ebx+PROC_BASE+0xA8], not EVENT_NOTIFY
mov edi, [p_ev]
mov dword [edi], EV_INTR
mov eax, [ebx+PROC_BASE+APPDATA.event]
mov dword [edi+4], eax
ret
@@:
call change_task
jmp .wait
endp
 
align 4
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 6
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
ret
endp
 
align 4
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 4
mov bh, byte [devfn]
mov bl, byte [reg]
call pci_read_reg
ret
endp
 
align 4
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
xor eax, eax
xor ebx, ebx
mov ah, byte [bus]
mov al, 8
mov bh, byte [devfn]
mov bl, byte [reg]
mov ecx, [val]
call pci_write_reg
ret
endp
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
 
align 4
proc srv_handler stdcall, ioctl:dword
mov esi, [ioctl]
test esi, esi
jz .err
 
mov edi, [esi+handle]
cmp [edi+SRV.magic], ' SRV'
jne .fail
 
cmp [edi+SRV.size], SRV_SIZE
jne .fail
 
stdcall [edi+SRV.srv_proc], esi
ret
.fail:
xor eax, eax
not eax
mov [esi+output], eax
mov [esi+out_size], 4
ret
.err:
xor eax, eax
not eax
ret
endp
 
align 4
proc srv_handlerEx stdcall, ioctl:dword
mov esi, [ioctl]
test esi, esi
jz .err
add esi, new_app_base
 
mov edi, [esi+handle]
cmp [edi+SRV.magic], ' SRV'
jne .fail
 
cmp [edi+SRV.size], SRV_SIZE
jne .fail
 
add [esi+input], new_app_base
add [esi+output], new_app_base
 
stdcall [edi+SRV.srv_proc], esi
ret
.fail:
xor eax, eax
not eax
mov [esi+output], eax
mov [esi+out_size], 4
ret
.err:
xor eax, eax
not eax
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
align 4
proc get_service stdcall, sz_name:dword
locals
srv_ptr dd ?
counter dd ?
endl
 
mov eax, [sz_name]
test eax, eax
jnz @F
ret
@@:
mov [srv_ptr], srv_tab
mov [counter], 16
@@:
stdcall strncmp, [srv_ptr], [sz_name], 16
test eax, eax
je .ok
 
add [srv_ptr], SRV_SIZE
dec [counter]
jnz @B
.not_load:
stdcall find_service, [sz_name]
test eax, eax
jnz @F
ret
@@:
stdcall load_driver, eax
ret
.ok:
mov eax, [srv_ptr]
ret
endp
 
align 4
proc find_service stdcall ,sz_name:dword
 
mov eax, [sz_name]
test eax, eax
jz .fail
 
mov esi, services
@@:
mov eax, [esi]
test eax, eax
jz .fail
push esi
stdcall strncmp, eax, [sz_name], 16
pop esi
test eax, eax
je .ok
 
add esi, 8
jmp @B
.ok:
mov eax, [esi+4]
ret
.fail:
xor eax, eax
ret
endp
 
align 4
proc reg_service stdcall, sz_name:dword, handler:dword
locals
srv dd ?
endl
 
mov eax, [sz_name]
test eax, eax
jz .fail
 
mov ebx, [handler]
test ebx, ebx
jz .fail
 
call alloc_service
test eax, eax
jz .fail
 
mov [srv], eax
mov edi, eax
mov esi, [sz_name]
mov ecx, 16
rep movsb
 
mov edi, eax
mov [edi+SRV.magic], ' SRV'
mov [edi+SRV.size], SRV_SIZE
mov ebx, [handler]
mov [edi+SRV.srv_proc], ebx
mov eax, [srv]
ret
.fail:
xor eax, eax
ret
endp
 
align 4
proc get_proc stdcall, exp:dword, sz_name:dword
 
mov edx, [exp]
.next:
mov eax, [edx]
test eax, eax
jz .end
 
push edx
stdcall strncmp, eax, [sz_name], 16
pop edx
test eax, eax
jz .ok
 
add edx,8
jmp .next
.ok:
mov eax, [edx+4]
.end:
ret
endp
 
align 4
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword
 
@@:
stdcall strncmp, [pSym], [sz_sym], 8
test eax,eax
jz .ok
add [pSym], 18
dec [count]
jnz @b
xor eax, eax
ret
.ok:
mov ebx, [pSym]
mov eax, [ebx+8]
ret
endp
 
align 4
proc 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]
sub ebx, new_app_base
mov ecx, [info]
sub ecx, new_app_base
 
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]
sub ebx, new_app_base
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]
sub ebx, new_app_base
sub esi, new_app_base
 
mov [cmd], eax
mov [offset], ecx
mov [offset+4], eax
mov [count], edx
mov [buff], esi
mov byte [buff+4], al
mov [name], ebx
 
mov eax, 70
lea ebx, [cmd]
sub ebx, new_app_base
int 0x40
ret
endp
 
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 ?
endl
 
lea eax, [attr]
stdcall get_fileinfo, [file_name], eax
test eax, eax
jnz .fail
 
stdcall kernel_alloc, [file_size]
mov [file], eax
 
stdcall read_file, [file_name], eax, dword 0, [file_size]
cmp ebx, [file_size]
jne .cleanup
mov eax, [file]
ret
.cleanup:
stdcall kernel_free, [file]
.fail:
xor eax, eax
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], 16
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, 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:
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, coff:dword, sec:dword, sym:dword
locals
n_sec dd ?
endl
 
mov eax, [coff]
movzx ebx, [eax+CFH.nSections]
mov [n_sec], ebx
.fix_sec:
mov esi, [sec]
mov edi, [esi+CFS.PtrReloc]
add edi, [coff]
 
movzx ecx, [esi+CFS.NumReloc]
test ecx, ecx
jz .next
.next_reloc:
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], edx
add edi, 10
dec ecx
jnz .next_reloc
.next:
add [sec], 40
dec [n_sec]
jnz .fix_sec
.exit:
ret
endp
 
align 4
proc load_driver stdcall, file_name:dword
locals
coff dd ?
sym dd ?
strings dd ?
img_size dd ?
img_base dd ?
start dd ?
 
exports dd ? ;fake exports table
dd ?
endl
 
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, 18
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, 40
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
jnz @F
 
mov esi, msg_module
call sys_msg_board_str
mov esi, [file_name]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
 
stdcall kernel_free,[coff]
xor eax, eax
ret
@@:
mov ebx, [coff]
add ebx, 20
stdcall fix_coff_relocs, [coff], ebx, [sym]
 
mov ebx, [coff]
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART
mov [start], eax
 
stdcall kernel_free, [coff]
 
mov ebx, [start]
call ebx
test eax, eax
jnz .ok
 
stdcall kernel_free, [img_base]
xor eax, eax
ret
.ok:
mov ebx, [img_base]
mov [eax+SRV.base], ebx
ret
.fail:
xor eax, eax
ret
endp
 
align 4
proc load_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, 18
dec ecx
jnz @B
mov [img_size], ebx
 
call init_heap
stdcall user_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
add edi, new_app_base
mov ecx, [eax+CFS.SizeOfRawData]
cld
rep movsb
.next:
add edi, 15-new_app_base
and edi, not 15
add eax, 40
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, new_app_base
lea eax, [edx+20]
@@:
add [eax+CFS.VirtualAddress], edi ;patch user space offset
add eax, 40
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
 
 
drv_sound db '/rd/1/drivers/unisound.obj', 0
drv_infinity db '/rd/1/drivers/infinity.obj', 0
 
szSound db 'SOUND',0
szInfinity db 'INFINITY',0
 
szSTART db 'START',0
szEXPORTS db 'EXPORTS',0
szIMPORTS db 'IMPORTS',0
 
msg_unresolved db 'unresolved ',0
msg_module db 'in module ',0
msg_CR db 13,10,0
 
align 16
services:
dd szSound, drv_sound
dd szInfinity, drv_infinity
dd 0
/kernel/tags/kolibri0.6.3.0/core/syscall.inc
0,0 → 1,147
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SYSTEM CALL ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 32
i40:
push ds es
pushad
cld
 
mov ax,word os_data
mov ds,ax
mov es,ax
 
; for syscall trace function
call save_registers
 
; load all registers in crossed order
mov edi,[esp+28] ; eax
mov eax,[esp+16] ; ebx
mov ebx,[esp+24] ; ecx
mov ecx,[esp+20] ; edx
mov edx,[esp+4] ; esi
mov esi,[esp+0] ; edi
 
; enable interupts - a task switch or an IRQ _CAN_ interrupt i40 handler
sti
push eax
and edi,0xff
call dword [servetable+edi*4]
pop eax
cli
 
popad
pop es ds
iretd
 
align 4
save_registers:
mov esi, [0x3010]
mov eax, [esi+TASKDATA.pid] ; load PID
lea esi, [esp+4]
inc [save_syscall_count]
mov edi,[save_syscall_count]
and edi,0xF
shl edi,6
add edi,save_syscall_data+32
mov [edi-32],eax
mov ecx,32 / 4
cld
rep movsd
ret
 
uglobal
save_syscall_count dd 0x0
endg
 
;label save_syscall_data dword at 0x5000
 
 
iglobal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SYSTEM FUNCTIONS TABLE ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
servetable:
 
dd sys_drawwindow ; 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 sys_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 undefined_syscall ; 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 sys_sb16 ; 25-SetSb16
dd sys_getsetup ; 26-GetMidiBase,GetKeymap,GetShiftKeymap,.
dd sys_wss ; 27-SetWssMainVol and SetWssCdVol
dd sys_sb16II ; 28-SetSb16
dd sys_date ; 29-GetDate
dd undefined_syscall ; 30-reserved
dd undefined_syscall ; 31-reserved
dd syscall_delramdiskfile ; 32-DelRamdiskFile
dd syscall_writeramdiskfile; 33-WriteRamdiskFile
dd undefined_syscall ; 34-reserved
dd syscall_getpixel ; 35-GetPixel
dd syscall_readstring ; 36-ReadString (not yet ready)
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 display_settings ; 48-SetRedrawType and SetButtonType
dd sys_apm ; 49-Advanced Power Management (APM)
dd random_shaped_window ; 50-Window shape & scale
dd syscall_threads ; 51-Threads
dd stack_driver_stat ; 52-Stack driver status
dd socket ; 53-Socket interface
dd user_events ; 54-User events
dd sound_interface ; 55-Sound interface
dd undefined_syscall ; 56-reserved
dd undefined_syscall ; 57-reserved
dd file_system ; 58-Common file system interface
dd sys_trace ; 59-System call trace
dd sys_IPC ; 60-Inter Process Communication
dd sys_gs ; 61-Direct graphics access
dd sys_pci ; 62-PCI functions
dd sys_msg_board ; 63-System message board
dd sys_resize_app_memory ; 64-Resize application memory usage
dd undefined_syscall ; 65-UTF
dd sys_process_def ; 66-Process definitions - keyboard
dd sys_window_move ; 67-Window move or resize
dd new_services ; 68-Some internal services
dd sys_debug_services ; 69-Debug
dd file_system_lfn ; 70-Common file system interface, version 2
dd syscall_windowsettings ; 71-Window settings
 
times 255 - ( ($-servetable) /4 ) dd undefined_syscall
 
dd sys_end ; -1-end application
endg
/kernel/tags/kolibri0.6.3.0/core/taskman.inc
0,0 → 1,1166
GREEDY_KERNEL equ 0; 1
 
 
struc APP_HEADER_00
{ .banner dq ?
.version dd ? ;+8
.start dd ? ;+12
.i_end dd ? ;+16
.mem_size dd ? ;+20
.i_param dd ? ;+24
}
 
struc APP_HEADER_01
{ .banner dq ?
.version dd ? ;+8
.start dd ? ;+12
.i_end dd ? ;+16
.mem_size dd ? ;+20
.stack_top dd ? ;+24
.i_param dd ? ;+28
.i_icon dd ? ;+32
}
 
align 4
proc test_app_header stdcall, header:dword
virtual at ebx
APP_HEADER_00 APP_HEADER_00
end virtual
 
mov ebx, [header]
cmp [ebx+6], word '00'
jne .check_01_header
 
mov eax,[APP_HEADER_00.start]
mov [app_start],eax
mov eax,[APP_HEADER_00.i_end]
mov [app_i_end],eax
mov eax,[APP_HEADER_00.mem_size]
mov [app_mem],eax
shr eax,1
sub eax,0x10
mov [app_esp],eax
mov eax,[APP_HEADER_00.i_param]
mov [app_i_param],eax
mov [app_i_icon],dword 0
 
mov eax,1
ret
 
.check_01_header:
virtual at ebx
APP_HEADER_01 APP_HEADER_01
end virtual
 
cmp [ebx+6],word '01'
jne .no_01_header
 
mov eax,[APP_HEADER_01.start]
mov [app_start],eax
mov eax,[APP_HEADER_01.i_end]
mov [app_i_end],eax
mov eax,[APP_HEADER_01.mem_size]
mov [app_mem],eax
mov eax,[APP_HEADER_01.stack_top]
mov [app_esp],eax
mov eax,[APP_HEADER_01.i_param]
mov [app_i_param],eax
mov eax,[APP_HEADER_01.i_icon]
mov [app_i_icon],eax
 
mov eax,1
ret
 
.no_01_header:
 
xor eax, eax
ret
endp
 
align 4
proc get_new_process_place
;input:
; none
;result:
; eax=[new_process_place]<>0 - ok
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [TASK_COUNT]!
mov eax,CURRENT_TASK
mov ebx,[TASK_COUNT]
inc ebx
shl ebx,5
add ebx,eax ;ebx - address of process information for (last+1) slot
.newprocessplace:
;eax = address of process information for current slot
cmp eax,ebx
jz .endnewprocessplace ;empty slot after high boundary
add eax,0x20
cmp word [eax+0xa],9 ;check process state, 9 means that process slot is empty
jnz .newprocessplace
.endnewprocessplace:
mov ebx,eax
sub eax,CURRENT_TASK
shr eax,5 ;calculate slot index
cmp eax,256
jge .failed ;it should be <256
mov word [ebx+0xa],9 ;set process state to 9 (for slot after hight boundary)
; mov [new_process_place], eax
ret
 
.failed:
xor eax,eax
ret
endp
 
align 4
proc create_app_space stdcall, app_size:dword,img_size:dword
locals
app_pages dd ?
img_pages dd ?
dir_addr dd ?
app_tabs dd ?
endl
 
stdcall wait_mutex, pg_data.pg_mutex
 
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 esi, sys_pgdir
mov edi, [tmp_task_pdir]
mov ecx, 384
cld
rep movsd
 
mov ecx, 384
xor eax, eax
cld
rep stosd
 
mov ecx, 256
mov esi, sys_pgdir+0xc00
rep movsd
 
mov eax, [dir_addr]
or eax, PG_SW
mov ebx, [tmp_task_pdir]
mov [ebx+0x600], eax
 
mov eax, [dir_addr]
call set_cr3
 
mov edx, [app_tabs]
mov edi, new_app_base
@@:
call alloc_page
test eax, eax
jz .fail
 
stdcall map_page_table, edi, eax
add edi, 0x00400000
dec edx
jnz @B
 
mov edi, new_app_base
shr edi, 10
add edi, pages_tab
mov ecx, [app_tabs]
shl ecx, 10
xor eax, eax
rep stosd
 
mov edx, new_app_base
.alloc:
call alloc_page
test eax, eax
jz .fail
 
stdcall map_page,edx,eax,dword PG_UW
add edx, 0x1000
sub [app_pages], 1
sub [img_pages], 1
jnz .alloc
 
mov ecx, [app_pages]
and ecx, ecx
jz .next
 
mov ebx, edx
shr edx, 12
.reserve:
mov dword [pages_tab+edx*4], 0x02
invlpg [ebx]
inc edx
dec ecx
jnz .reserve
.next:
mov edi, new_app_base
mov ecx, [img_size]
shr ecx, 2
xor eax, eax
cld
rep stosd
 
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
 
dec [pg_data.pg_mutex]
mov eax, [dir_addr]
ret
.fail:
dec [pg_data.pg_mutex]
cmp [dir_addr], 0
jz @f
stdcall destroy_app_space, [dir_addr]
@@:
xor eax, eax
ret
endp
 
align 4
set_cr3:
mov esi, [CURRENT_TASK]
mov ebx, esi
shl esi,8
mov [PROC_BASE+esi+0xB8],eax
imul ebx,tss_step
add ebx,tss_data
mov [ebx+28], eax
mov cr3, eax
ret
 
align 4
proc destroy_page_table stdcall, pg_tab:dword
 
push esi
 
mov esi, [pg_tab]
mov ecx, 1024
.free:
mov eax, [esi]
test eax, 1
jz .next
call free_page
.next:
add esi, 4
dec ecx
jnz .free
pop esi
ret
endp
 
align 4
proc destroy_app_space stdcall, pg_dir:dword
 
stdcall wait_mutex, pg_data.pg_mutex
 
xor edx,edx
mov eax,0x2
mov ebx, [pg_dir]
 
.loop:
;eax = current slot of process
mov ecx,eax
shl ecx,5
cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running?
jz @f ;skip empty slots
shl ecx,3
cmp [PROC_BASE+ecx+0xB8],ebx ;compare page directory addresses
jnz @f
inc edx ;thread found
@@:
inc eax
cmp eax,[TASK_COUNT] ;exit loop if we look through all processes
jle .loop
 
;edx = number of threads
;our process is zombi so it isn't counted
cmp edx,1
jg .exit
;if there isn't threads then clear memory.
 
mov eax, [pg_dir]
and eax, not 0xFFF
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW
mov esi, [tmp_task_pdir]
add esi, 0x604
mov edi, 383
.destroy:
mov eax, [esi]
test eax, 1
jz .next
and eax, not 0xFFF
stdcall map_page,[tmp_task_ptab],eax,dword PG_SW
stdcall destroy_page_table, [tmp_task_ptab]
mov eax, [esi]
call free_page
.next:
add esi, 4
dec edi
jnz .destroy
 
mov eax, [pg_dir]
call free_page
.exit:
stdcall map_page,[tmp_task_ptab],dword 0,dword PG_UNMAP
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
dec [pg_data.pg_mutex]
ret
endp
 
align 4
proc fs_execute
 
;fn_read:dword, file_size:dword, cluster:dword
 
; ebx - cmdline
; edx - flags
; ebp - full filename
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it
 
locals
cmdline dd ?
flags dd ?
filename dd ?
retval dd ?
endl
 
pushad
 
mov [cmdline], ebx
mov [flags], edx
mov eax, [ebp]
mov [filename], eax
 
stdcall wait_mutex, pg_data.tmp_task_mutex
 
mov edi, [tmp_task_data]
mov ecx, (2048+256)/4
xor eax, eax
rep stosd
 
mov esi, [filename]
mov edi, [tmp_task_data]
add edi, TMP_FILE_NAME
mov ecx, 1024
rep movsb
 
mov esi, [filename]
mov edi, [tmp_task_data]
add edi, TMP_ICON_OFFS
mov ecx, 1024
rep movsb
 
mov esi, [cmdline]
test esi, esi
jz @f
mov edi, [tmp_task_data]
add edi, TMP_CMD_LINE
mov ecx, 256
rep movsb
@@:
mov eax, TMP_FILE_NAME
add eax, [tmp_task_data]
mov ebx, [tmp_task_data] ;cmd line
add ebx, TMP_CMD_LINE
 
stdcall fs_exec, eax, ebx, [flags], [ebp+8],\
[ebp+12], [ebp+16],[ebp+20]
mov [retval], eax
popad
mov [pg_data.tmp_task_mutex], 0
mov eax, [retval]
ret
 
endp
 
align 4
proc fs_exec stdcall file_name:dword, cmd_line:dword, flags:dword,\
fn_read:dword, file_size:dword,\
cluster:dword, some_data:dword
 
locals
slot dd ?
app_path_size dd ?
save_cr3 dd ?
img_size dd ?
endl
 
; check filename length - with terminating NULL must be no more than 1024 symbols
 
mov edi, [file_name]
mov ecx, 1024
xor eax, eax
repnz scasb
jz @f
mov eax, -ERROR_FILE_NOT_FOUND
ret
@@:
sub edi, [file_name]
mov [app_path_size], edi
 
mov esi, new_process_loading
call sys_msg_board_str ; write message to message board
 
pushfd
cli
 
.wait_lock:
cmp [application_table_status],0
je .get_lock
call change_task
jmp .wait_lock
 
.get_lock:
mov eax, 1
xchg eax, [application_table_status]
cmp eax, 0
jne .wait_lock
 
call set_application_table_status
 
call get_new_process_place
test eax, eax
mov ecx, -0x20 ; too many processes
jz .err
mov [slot], eax
 
mov edi,eax
shl edi,8
add edi,PROC_BASE
mov ecx,256/4
xor eax,eax
cld
rep stosd ;clean extended information about process
 
; write application name
 
mov edi, [file_name]
mov ecx, [app_path_size]
add edi, ecx
dec edi
std
mov al, '/'
repnz scasb
cld
jnz @f
inc edi
@@:
inc edi
; now edi points to name without path
 
mov esi, edi
mov ecx, 8 ; 8 chars for name
mov edi, [slot]
shl edi, cl
add edi, PROC_BASE
.copy_process_name_loop:
lodsb
cmp al, '.'
jz .copy_process_name_done
test al, al
jz .copy_process_name_done
stosb
loop .copy_process_name_loop
.copy_process_name_done:
mov al, ' '
rep stosb
pop eax
mov cl, 3 ; 3 chars for extension
dec esi
@@:
dec eax
cmp eax, esi
jbe .copy_process_ext_done
cmp byte [eax], '.'
jnz @b
lea esi, [eax+1]
.copy_process_ext_loop:
lodsb
test al, al
jz .copy_process_ext_done
stosb
loop .copy_process_ext_loop
.copy_process_ext_done:
mov al, ' '
rep stosb
 
; read header
lea eax, [file_size]
mov ebx, [eax]
mov [img_size], ebx
mov edi, TMP_BUFF
call [fn_read]
 
test eax, eax
jnz .err
 
; check menuet signature
 
mov ecx, -0x1F
;check MENUET signature
cmp [TMP_BUFF],dword 'MENU'
jnz .err
cmp [TMP_BUFF+4],word 'ET'
jnz .err
 
stdcall test_app_header, TMP_BUFF
test eax, eax
jz .err
 
mov eax, cr3
mov [save_cr3], eax
if GREEDY_KERNEL
stdcall create_app_space,[app_mem],[img_size]
else
stdcall create_app_space,[app_mem],[app_mem]
end if
test eax, eax
jz .failed
 
mov ebx,[slot]
shl ebx,8
mov [PROC_BASE+ebx+0xB8],eax
 
mov esi, TMP_BUFF
mov edi, new_app_base
mov ecx, 512/4
cld
rep movsd
 
;read file
@@:
lea eax, [file_size]
cmp dword [eax], 0
jz .done
push edi
call [fn_read]
pop edi
add edi, 512
test eax, eax
jz @b
cmp ebx, 6
jne .failed
.done:
stdcall add_app_parameters, [slot], new_app_base,\
[cmd_line],[file_name],[flags]
 
mov eax, [save_cr3]
call set_cr3
 
xor eax, eax
mov [application_table_status],eax ;unlock application_table_status mutex
popfd
mov eax,[process_number] ;set result
ret
 
.failed:
mov eax, [save_cr3]
call set_cr3
.err:
 
popfd
xor eax, eax
mov [application_table_status],eax
ret
endp
 
align 4
proc add_app_parameters stdcall,slot:dword,img_base:dword,\
cmd_line:dword, app_path:dword, flags:dword
 
mov eax,[slot]
bt [cpu_caps], CAPS_SSE
jnc .no_SSE
shl eax, 8
mov ebx, eax
add eax, eax
add eax, [fpu_data]
mov [ebx+PROC_BASE+APPDATA.fpu_state], eax
mov [ebx+PROC_BASE+APPDATA.fpu_handler], 0
mov [ebx+PROC_BASE+APPDATA.sse_handler], 0
jmp .m1
.no_SSE:
mov ecx, eax
mov ebx, eax
shl eax, 7
shl ebx, 4
sub eax, ebx ;eax*=112
add eax, [fpu_data]
shl ecx, 8
mov [ecx+PROC_BASE+APPDATA.fpu_state], eax
mov [ecx+PROC_BASE+APPDATA.fpu_handler], 0
mov [ecx+PROC_BASE+APPDATA.sse_handler], 0
.m1:
mov ebx,[slot]
cmp ebx,[TASK_COUNT]
jle .noinc
inc dword [TASK_COUNT] ;update number of processes
.noinc:
shl ebx,8
mov eax,[app_mem]
mov [PROC_BASE+0x8c+ebx],eax
 
shr ebx,3
mov eax, new_app_base
mov dword [CURRENT_TASK+ebx+0x10],eax
 
.add_command_line:
mov edx,[app_i_param]
test edx,edx
jz .no_command_line ;application don't need parameters
mov eax,[cmd_line]
test eax,eax
jz .no_command_line ;no parameters specified
;calculate parameter length
xor ecx,ecx
.command_line_len:
cmp byte [eax],0
jz .command_line_len_end
inc eax
inc ecx
cmp ecx,255
jl .command_line_len
 
.command_line_len_end:
;ecx - parameter length
;edx - address of parameters in new process address space
inc ecx
mov edi, [img_base]
add edi, edx
mov esi, [cmd_line]
rep movsb
 
.no_command_line:
 
mov edx,[app_i_icon]
test edx,edx
jz .no_command_line_1 ;application don't need path of file
mov esi,[app_path]
test esi, esi
jz .no_command_line_1 ;application don't need path of file
mov ecx, 64
mov edi, [img_base]
add edi, edx
rep movsb
 
.no_command_line_1:
mov ebx,[slot]
mov eax,ebx
shl ebx,5
; 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
 
mov ecx,ebx
add ecx,(draw_data-CURRENT_TASK) ;ecx - pointer to draw data
;set draw data to full screen
 
mov [ecx+0],dword 0
mov [ecx+4],dword 0
mov eax,[SCR_X_SIZE]
mov [ecx+8],eax
mov eax,[SCR_Y_SIZE]
mov [ecx+12],eax
;set cr3 register in TSS of application
 
mov ecx,[slot]
shl ecx,8
mov eax,[PROC_BASE+0xB8+ecx]
;or eax, PG_NOCACHE
mov [l.cr3],eax
 
mov eax,[app_start]
mov [l.eip],eax ;set eip in TSS
mov eax,[app_esp]
mov [l.esp],eax ;set stack in TSS
 
;gdt
mov ax,app_code ;ax - selector of code segment
mov [l.cs],ax
mov ax,app_data
mov [l.ss],ax
mov [l.ds],ax
mov [l.es],ax
mov [l.fs],ax
mov ax,graph_data ;ax - selector of graphic segment
mov [l.gs],ax
mov [l.io],word 128
mov [l.eflags],dword 0x1202
 
mov [l.ss0],os_data
mov ebx,[slot]
shl ebx,12
add ebx,sysint_stack_data+4096
mov [l.esp0],ebx
 
;copy tss to it place
mov eax,tss_sceleton
mov ebx,[slot]
imul ebx,tss_step
add ebx,tss_data ;ebx - address of application TSS
mov ecx,120
call memmove
 
;Add IO access table - bit array of permitted ports
or eax,-1
mov edi,[slot]
imul edi,tss_step
add edi,tss_data+128
mov ecx,2048
cld
rep stosd ;full access to 2048*8=16384 ports
 
mov ecx,ebx ;ecx - address of application TSS
mov edi,[slot]
shl edi,3
;set TSS descriptor
mov [edi+gdts+tss0+0],word tss_step ;limit (size)
mov [edi+gdts+tss0+2],cx ;part of offset
mov eax,ecx
shr eax,16
mov [edi+gdts+tss0+4],al ;part of offset
mov [edi+gdts+tss0+7],ah ;part of offset
mov [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
 
;flush keyboard and buttons queue
mov [KEY_COUNT],byte 0
mov [BTN_COUNT],byte 0
 
mov edi,[slot]
shl edi,5
add edi,window_data
mov ebx,[slot]
movzx esi,word [WIN_STACK+ebx*2]
lea esi,[WIN_POS+esi*2]
call windowactivate ;gui initialization
 
mov ebx,[slot]
shl ebx,5
mov [CURRENT_TASK+ebx+0xa],byte 0 ;set process state - running
; set if debuggee
mov eax, [flags]
test byte [flags], 1
jz .no_debug
mov [CURRENT_TASK+ebx+0xa],byte 1 ;set process state - suspended
mov eax,[CURRENT_TASK]
mov [PROC_BASE+ebx*8+0xac],eax ;set debugger PID - current
.no_debug:
 
mov esi,new_process_running
call sys_msg_board_str ;output information about succefull startup
 
ret
endp
 
pid_to_slot:
;Input:
; eax - pid of process
;Output:
; eax - slot of process or 0 if process don't exists
;Search process by PID.
push ebx
push ecx
mov ebx,[TASK_COUNT]
shl ebx,5
mov ecx,2*32
 
.loop:
;ecx=offset of current process info entry
;ebx=maximum permitted offset
cmp byte [CURRENT_TASK+ecx+0xa],9
jz .endloop ;skip empty slots
cmp [CURRENT_TASK+ecx+0x4],eax ;check PID
jz .pid_found
.endloop:
add ecx,32
cmp ecx,ebx
jle .loop
 
pop ecx
pop ebx
xor eax,eax
ret
 
.pid_found:
shr ecx,5
mov eax,ecx ;convert offset to index of slot
pop ecx
pop ebx
ret
 
check_region:
;input:
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
mov eax,[CURRENT_TASK]
jmp check_process_region
;-----------------------------------------------------------------------------
check_process_region:
;input:
; eax - slot
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
 
test ecx,ecx
jle .ok
shl eax,5
cmp word [CURRENT_TASK+eax+0xa],0
jnz .failed
shl eax,3
mov eax,[PROC_BASE+eax+0xb8]
test eax,eax
jz .failed
 
mov eax,1
ret
 
 
; call MEM_Get_Linear_Address
; push ebx
; push ecx
; push edx
; mov edx,ebx
; and edx,not (4096-1)
; sub ebx,edx
; add ecx,ebx
; mov ebx,edx
; add ecx,(4096-1)
; and ecx,not (4096-1)
;.loop:
;;eax - linear address of page directory
;;ebx - current page
;;ecx - current size
; mov edx,ebx
; shr edx,22
; mov edx,[eax+4*edx]
; and edx,not (4096-1)
; test edx,edx
; jz .failed1
; push eax
; mov eax,edx
; call MEM_Get_Linear_Address
; mov edx,ebx
; shr edx,12
; and edx,(1024-1)
; mov eax,[eax+4*edx]
; and eax,not (4096-1)
; test eax,eax
; pop eax
; jz .failed1
; add ebx,4096
; sub ecx,4096
; jg .loop
; pop edx
; pop ecx
; pop ebx
.ok:
mov eax,1
ret
;
;.failed1:
; pop edx
; pop ecx
; pop ebx
.failed:
xor eax,eax
ret
 
align 4
proc read_process_memory
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes read.
locals
slot dd ?
buff dd ?
r_count dd ?
offset dd ?
tmp_r_cnt dd ?
endl
 
mov [slot], eax
mov [buff], ebx
mov [r_count], ecx
mov [tmp_r_cnt], ecx
mov [offset], edx
 
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_r_cnt]
 
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov eax, [slot]
shl eax,8
mov ebx, [offset]
add ebx, new_app_base
push ecx
stdcall map_memEx, [proc_mem_map],\
[PROC_BASE+eax+0xB8],\
ebx, ecx
pop ecx
 
mov esi, [offset]
and esi, 0xfff
add esi, [proc_mem_map]
mov edi, [buff]
mov edx, ecx
rep movsb
 
add [offset], edx
sub [tmp_r_cnt], edx
jnz .read_mem
 
popad
mov eax, [r_count]
ret
 
endp
 
align 4
proc write_process_memory
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes written
 
locals
slot dd ?
buff dd ?
w_count dd ?
offset dd ?
tmp_w_cnt dd ?
endl
 
mov [slot], eax
mov [buff], ebx
mov [w_count], ecx
mov [tmp_w_cnt], ecx
mov [offset], edx
 
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_w_cnt]
 
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov eax, [slot]
shl eax,8
mov ebx, [offset]
add ebx, new_app_base
push ecx
stdcall map_memEx, [proc_mem_map],\
[PROC_BASE+eax+0xB8],\
ebx, ecx
pop ecx
 
mov edi, [offset]
and edi, 0xfff
add edi, [proc_mem_map]
mov esi, [buff]
mov edx, ecx
rep movsb
 
add [offset], edx
sub [tmp_w_cnt], edx
jnz .read_mem
 
popad
mov eax, [w_count]
ret
endp
 
 
align 4
proc new_sys_threads
locals
thread_start dd ?
thread_stack dd ?
params dd ?
slot dd ?
endl
 
mov [thread_start], ebx
mov [thread_stack], ecx
mov [params], 0
 
xor edx,edx ; flags=0
 
cmp eax,1
jnz .failed ;other subfunctions
mov esi,new_process_loading
call sys_msg_board_str
 
.wait_lock:
cmp [application_table_status],0
je .get_lock
call change_task
jmp .wait_lock
 
.get_lock:
mov eax, 1
xchg eax, [application_table_status]
cmp eax, 0
jne .wait_lock
 
call set_application_table_status
 
call get_new_process_place
test eax, eax
jz .failed
 
mov [slot], eax
 
xor eax,eax
mov [app_i_param],eax
mov [app_i_icon],eax
 
mov ebx, [thread_start]
mov ecx, [thread_stack]
 
mov [app_start],ebx
mov [app_esp],ecx
 
mov esi,[CURRENT_TASK]
shl esi,8
add esi,PROC_BASE
mov ebx,esi ;ebx=esi - pointer to extended information about current thread
 
mov edi,[slot]
shl edi,8
add edi,PROC_BASE
mov edx,edi ;edx=edi - pointer to extended infomation about new thread
mov ecx,256/4
rep stosd ;clean extended information about new thread
mov edi,edx
mov ecx,11
rep movsb ;copy process name
mov eax,[ebx+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 [app_mem],eax ;set memory size
mov eax,[ebx+0xb8]
mov [edx+0xb8],eax ;copy page directory
 
stdcall add_app_parameters, [slot], new_app_base,\
[params], dword 0,dword 0
 
mov esi,new_process_running
call sys_msg_board_str ;output information about succefull startup
 
mov [application_table_status],0 ;unlock application_table_status mutex
mov eax,[process_number] ;set result
ret
.failed:
mov [application_table_status],0
mov eax,-1
ret
endp
 
align 4
proc wait_mutex stdcall, mutex:dword
mov ebx, [mutex]
.wait_lock:
cmp dword [ebx],0
je .get_lock
push ebx
call change_task
pop ebx
jmp .wait_lock
 
.get_lock:
mov eax, 1
xchg eax, [ebx]
test eax, eax
jnz .wait_lock
ret
endp
 
 
include "debug.inc"
 
iglobal
new_process_loading db 'K : New Process - loading',13,10,0
new_process_running db 'K : New Process - done',13,10,0
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
endg
 
/kernel/tags/kolibri0.6.3.0/core/heap.inc
0,0 → 1,832
 
HEAP_BASE equ 0x01000000
;HEAP_SIZE equ 0x01000000
 
struc MEM_BLOCK
{ .next_block dd ?
.prev_block dd ? ;+4
.list_next dd ? ;+8
.list_prev dd ? ;+12
.base dd ? ;+16
.size dd ? ;+20
.flags dd ? ;+24
.handle dd ? ;+28
}
 
FREE_BLOCK equ 4
USED_BLOCK equ 8
 
virtual at 0
MEM_BLOCK MEM_BLOCK
end virtual
 
MEM_BLOCK_SIZE equ 8*4
 
block_next equ MEM_BLOCK.next_block
block_prev equ MEM_BLOCK.prev_block
list_next equ MEM_BLOCK.list_next
list_prev equ MEM_BLOCK.list_prev
block_base equ MEM_BLOCK.base
block_size equ MEM_BLOCK.size
block_flags equ MEM_BLOCK.flags
 
macro calc_index op
{ shr op, 12
dec op
cmp op, 63
jna @f
mov op, 63
@@:
}
 
macro remove_from_list op
{ mov edx, [op+list_next]
mov ecx, [op+list_prev]
test edx, edx
jz @f
mov [edx+list_prev], ecx
@@:
test ecx, ecx
jz @f
mov [ecx+list_next], edx
@@:
mov [op+list_next],0
mov [op+list_prev],0
}
 
macro remove_from_free op
{
remove_from_list op
 
mov eax, [op+block_size]
calc_index eax
cmp [mem_block_list+eax*4], op
jne @f
mov [mem_block_list+eax*4], edx
@@:
cmp [mem_block_list+eax*4], 0
jne @f
btr [mem_block_mask], eax
@@:
}
 
macro remove_from_used op
{
remove_from_list op
cmp [mem_used_list], op
jne @f
mov [mem_used_list], edx
@@:
}
 
align 4
proc init_kernel_heap
 
mov ecx, 64/4
mov edi, mem_block_list
xor eax, eax
cld
rep stosd
 
mov ecx, 512/4
mov edi, mem_block_map
not eax
rep stosd
 
mov [mem_block_start], mem_block_map
mov [mem_block_end], mem_block_map+512
mov [mem_block_arr], HEAP_BASE
 
stdcall alloc_pages, dword 32
mov ecx, 32
mov edx, eax
mov edi, HEAP_BASE
.l1:
stdcall map_page,edi,edx,PG_SW
add edi, 0x1000
add edx, 0x1000
dec ecx
jnz .l1
 
mov edi, HEAP_BASE
mov ebx, edi
add ebx, MEM_BLOCK_SIZE
xor eax, eax
mov [edi+block_next], ebx
mov [edi+block_prev], eax
mov [edi+list_next], eax
mov [edi+list_prev], eax
mov [edi+block_base], HEAP_BASE
mov [edi+block_size], 4096*MEM_BLOCK_SIZE
mov [edi+block_flags], USED_BLOCK
 
mov [ebx+block_next], eax
mov [ebx+block_prev], eax
mov [ebx+list_next], eax
mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE
 
mov ecx, [MEM_AMOUNT]
sub ecx, 0x01000000 + 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_used_list], eax
mov [mem_block_list+63*4], ebx
mov byte [mem_block_map], 0xFC
mov [heap_blocks], 4095
mov [free_blocks], 4095
ret
endp
 
align 4
proc get_block stdcall, index:dword
 
mov eax, 63
mov ecx, [index]
cmp ecx, eax
jna @f
;cmova ecx, eax
mov ecx, eax
@@:
xor esi, esi
xor ebx, ebx
xor edx, edx
not edx
 
cmp ecx, 32
jb .bit_test
 
sub ecx, 32
add ebx, 32
add esi, 4
 
.bit_test:
shl edx, cl
and edx, [mem_block_mask+esi]
jz .high_mask
bsf eax, edx
add ebx, eax
mov eax, [mem_block_list+ebx*4]
ret
 
.high_mask:
 
add esi, 4
add ebx, 32
test esi, 0xFFFFFFF8
jnz .big_error
mov edx, [mem_block_mask+esi]
and edx, edx
jz .high_mask
bsf eax, edx
add ebx, eax
mov eax, [mem_block_list+ebx*4]
ret
 
.big_error:
xor eax, eax
ret
endp
 
align 4
proc alloc_mem_block
 
pushfd
cli
mov ebx, [mem_block_start]
mov ecx, [mem_block_end]
.l1:
bsf eax,[ebx];
jnz found
add ebx,4
cmp ebx, ecx
jb .l1
popfd
xor eax,eax
ret
 
found:
btr [ebx], eax
mov [mem_block_start],ebx
sub ebx, mem_block_map
shl ebx, 3
add eax,ebx
shl eax, 5
add eax, [mem_block_arr]
dec [free_blocks]
popfd
ret
endp
 
proc free_mem_block
pushfd
cli
sub eax, [mem_block_arr]
shr eax, 5
 
mov ebx, mem_block_map
bts [ebx], eax
inc [free_blocks]
shr eax, 3
and eax, not 3
add eax, ebx
cmp [mem_block_start], eax
ja @f
popfd
ret
@@:
mov [mem_block_start], eax
popfd
ret
.err:
xor eax, eax
popfd
ret
endp
 
align 4
proc alloc_kernel_space stdcall, size:dword
local block_ind:DWORD
 
pushfd
cli
 
mov eax, [size]
add eax, 0xFFF
and eax, 0xFFFFF000;
mov [size], eax
cmp eax, [heap_free]
ja .error
 
shr eax, 12
sub eax, 1
 
mov [block_ind], eax
 
stdcall get_block, eax
and eax, eax
jz .error
 
mov edi, eax ;edi - pBlock
 
cmp [edi+block_flags], FREE_BLOCK
jne .error
 
mov [block_ind], ebx ;index of allocated block
 
mov eax, [edi+block_size]
cmp eax, [size]
je .m_eq_size
 
call alloc_mem_block
and eax, eax
jz .error
 
mov esi, eax ;esi - splitted block
 
mov [esi+block_next], edi
mov eax, [edi+block_prev]
mov [esi+block_prev], eax
mov [edi+block_prev], esi
mov [esi+list_next], 0
mov [esi+list_prev], 0
and eax, eax
jz @f
mov [eax+block_next], esi
@@:
mov ebx, [edi+block_base]
mov [esi+block_base], ebx
mov edx, [size]
mov [esi+block_size], edx
add [edi+block_base], edx
sub [edi+block_size], edx
 
mov eax, [edi+block_size]
shr eax, 12
sub eax, 1
cmp eax, 63
jna @f
mov eax, 63
@@:
cmp eax, [block_ind]
je .m_eq_ind
 
remove_from_list edi
 
mov ecx, [block_ind]
mov [mem_block_list+ecx*4], ebx
 
test ebx, ebx
jnz @f
btr [mem_block_mask], ecx
@@:
mov edx, [mem_block_list+eax*4]
mov [edi+list_next], edx
test edx, edx
jz @f
mov [edx+list_prev], edi
@@:
mov [mem_block_list+eax*4], edi
bts [mem_block_mask], eax
.m_eq_ind:
mov ebx, [mem_used_list]
mov [esi+list_next], ebx
test ebx, ebx
jz @f
mov [ebx+list_prev], esi
@@:
mov [esi+block_flags], USED_BLOCK
mov [mem_used_list], esi
mov eax, [esi+block_base]
mov ebx, [size]
sub [heap_free], ebx
popfd
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_list]
mov [edi+list_next], ecx
test ecx, ecx
jnz @f
mov [ecx+list_prev], edi
@@:
mov [mem_used_list], edi
mov [edi+block_flags], USED_BLOCK
mov eax, [edi+block_base]
mov ebx, [size]
sub [heap_free], ebx
popfd
ret
.error:
xor eax, eax
popfd
ret
endp
 
align 4
proc free_kernel_space stdcall, base:dword
 
mov eax, [base]
mov esi, [mem_used_list]
@@:
test esi, esi
jz .fail
 
cmp [esi+block_base], eax
je .found
mov esi, [esi+list_next]
jmp @b
.found:
cmp [esi+block_flags], USED_BLOCK
jne .fail
 
mov 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_next], esi
test esi, esi
jz @f
mov [esi+list_prev], edi
@@:
bts [mem_block_mask], eax
.m_eq:
xor eax, eax
not eax
ret
.insert:
remove_from_used esi
 
mov eax, [esi+block_size]
calc_index eax
 
mov edi, [mem_block_list+eax*4]
mov [mem_block_list+eax*4], esi
mov [esi+list_next], edi
test edi, edi
jz @f
mov [edi+list_prev], esi
@@:
bts [mem_block_mask], eax
mov [esi+block_flags],FREE_BLOCK
xor eax, eax
not eax
ret
.fail:
xor eax, eax
ret
endp
 
align 4
proc kernel_alloc stdcall, size:dword
locals
lin_addr dd ?
pages_count dd ?
endl
 
mov eax, [size]
add eax, 0xFFF
and eax, 0xFFFFF000;
mov [size], eax
and eax, eax
jz .error
mov ebx, eax
shr ebx, 12
mov [pages_count], ebx
 
stdcall alloc_kernel_space, eax
and eax, eax
jz .error
mov [lin_addr], eax
 
mov ecx, [pages_count]
mov edx, eax
mov ebx, ecx
 
shr ecx, 3
jz .next
 
and ebx, not 7
push ebx
stdcall alloc_pages, ebx
pop ecx ; yes ecx!!!
and eax, eax
jz .error
 
mov edi, eax
mov edx, [lin_addr]
@@:
stdcall map_page,edx,edi,dword PG_SW
add edx, 0x1000
add edi, 0x1000
dec ecx
jnz @B
.next:
mov ecx, [pages_count]
and ecx, 7
jz .end
 
@@: push ecx
call alloc_page
pop ecx
test eax, eax
jz .error
 
stdcall map_page,edx,eax,dword PG_SW
add edx, 0x1000
dec ecx
jnz @B
.end:
mov eax, [lin_addr]
ret
 
.error:
xor eax, eax
ret
endp
 
align 4
proc kernel_free stdcall, base:dword
locals
size dd ?
endl
 
mov eax, [base]
mov esi, [mem_used_list]
@@:
test esi, esi
jz .fail
 
cmp [esi+block_base], eax
je .found
mov esi, [esi+list_next]
jmp @b
.found:
cmp [esi+block_flags], USED_BLOCK
jne .fail
 
mov ecx, [esi+block_size];
mov [size], ecx
 
stdcall free_kernel_space, [base]
test eax, eax
jz .fail
 
mov ecx, [size]
mov edi, [base]
 
shr ecx, 12
mov esi, edi
shr edi, 10
add edi, pages_tab
xor edx, edx
.release:
mov eax, [edi]
test eax, 1
jz .next
 
call free_page
mov [edi],edx
.next:
invlpg [esi]
add esi, 0x1000
add edi, 4
dec ecx
jnz .release
.fail:
ret
endp
 
restore block_next
restore block_prev
restore block_list
restore block_base
restore block_size
restore block_flags
 
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;;
 
HEAP_TOP equ 0x5FC00000
 
align 4
proc init_heap
 
mov ebx,[CURRENT_TASK]
shl ebx,8
mov eax, [PROC_BASE+APPDATA.heap_top+ebx]
test eax, eax
jz @F
sub eax,[PROC_BASE+APPDATA.heap_base+ebx]
sub eax, 4096
ret
@@:
mov esi, [PROC_BASE+APPDATA.mem_size+ebx]
add esi, 4095
and esi, not 4095
mov eax, HEAP_TOP
mov [PROC_BASE+APPDATA.heap_base+ebx], esi
mov [PROC_BASE+APPDATA.heap_top+ebx], eax
 
sub eax, esi
add esi, new_app_base
shr esi, 10
mov ecx, eax
sub eax, 4096
or ecx, FREE_BLOCK
mov [pages_tab+esi], ecx
ret
.exit:
xor eax, eax
ret
endp
 
align 4
proc user_alloc stdcall, alloc_size:dword
 
mov ecx, [alloc_size]
add ecx, (4095+4096)
and ecx, not 4095
 
mov ebx, [CURRENT_TASK]
shl ebx, 8
mov esi, dword [ebx+PROC_BASE+APPDATA.heap_base]; heap_base
mov edi, dword [ebx+PROC_BASE+APPDATA.heap_top]; heap_top
add esi, new_app_base
add edi, new_app_base
 
l_0:
cmp esi, edi
jae m_exit
 
mov ebx, esi
shr ebx, 12
mov eax, [pages_tab+ebx*4]
test eax, FREE_BLOCK
jz test_used
and eax, 0xFFFFF000
cmp eax, ecx ;alloc_size
jb m_next
 
mov edx, esi
add edx, ecx
sub eax, ecx;
or eax, FREE_BLOCK
shr edx, 12
mov [pages_tab+edx*4], eax
 
or ecx, USED_BLOCK
mov [pages_tab+ebx*4], ecx
shr ecx, 12
dec ecx
inc ebx
@@:
mov dword [pages_tab+ebx*4], 2
inc ebx
dec ecx
jnz @B
 
mov eax, esi
add eax, 4096
sub eax, new_app_base
ret
m_next:
add esi, eax
jmp l_0
test_used:
test eax, USED_BLOCK
jz m_exit
 
and eax, 0xFFFFF000
add esi, eax
jmp l_0
m_exit:
xor eax, eax
ret
endp
 
align 4
proc user_free stdcall, base:dword
 
mov esi, [base]
test esi, esi
jz .exit
 
sub esi, 4096
shr esi, 12
mov eax, [pages_tab+esi*4]
test eax, USED_BLOCK
jz .not_used
 
and eax, not 4095
mov ecx, eax
or eax, FREE_BLOCK
mov [pages_tab+esi*4], eax
inc esi
sub ecx, 4096
shr ecx, 12
.release:
xor eax, eax
xchg eax, [pages_tab+esi*4]
test eax, 1
jz @F
call free_page
@@:
inc esi
dec ecx
jnz .release
.not_used:
mov ebx, [CURRENT_TASK]
shl ebx, 8
mov esi, dword [ebx+PROC_BASE+APPDATA.heap_base]; heap_base
mov edi, dword [ebx+PROC_BASE+APPDATA.heap_top]; heap_top
shr esi, 12
shr edi, 12
@@:
mov eax, [pages_tab+esi*4]
test eax, USED_BLOCK
jz .test_free
shr eax, 12
add esi, eax
jmp @B
.test_free:
test eax, FREE_BLOCK
jz .err
mov edx, eax
shr edx, 12
add edx, esi
cmp edx, edi
jae .exit
 
mov ebx, [pages_tab+edx*4]
test ebx, USED_BLOCK
jz .next_free
 
shr ebx, 12
add edx, ebx
mov esi, edx
jmp @B
.next_free:
test ebx, FREE_BLOCK
jz .err
and dword [pages_tab+edx*4], 0
add eax, ebx
and eax, not 4095
or eax, FREE_BLOCK
mov [pages_tab+esi*4], eax
jmp @B
.exit:
xor eax, eax
inc eax
ret
.err:
xor eax, eax
ret
endp
 
align 4
proc alloc_dll
pushf
cli
bsf eax, [dll_map]
jnz .find
popf
xor eax, eax
ret
.find:
btr [dll_map], eax
popf
shl eax, 5
add eax, dll_tab
ret
endp
 
align 4
proc alloc_service
pushf
cli
bsf eax, [srv_map]
jnz .find
popf
xor eax, eax
ret
 
.find: btr [srv_map], eax
popf
shl eax,5
add eax, srv_tab
ret
endp
/kernel/tags/kolibri0.6.3.0/core/exports.inc
0,0 → 1,45
 
iglobal
 
align 16
kernel_export:
dd szAttachIntHandler, attach_int_handler
dd szSysMsgBoardStr , sys_msg_board_str
dd szPciApi , pci_api
dd szPciRead32 , pci_read32
dd szPciRead8 , pci_read8
dd szPciWrite8 , pci_write8
dd szAllocKernelSpace, alloc_kernel_space
dd szMapPage , map_page
dd szRegService , reg_service
dd szKernelAlloc , kernel_alloc
dd szKernelFree , kernel_free
dd szGetPgAddr , get_pg_addr
dd szGetCurrentTask , get_curr_task
dd szGetService , get_service
dd szServiceHandler , srv_handler
dd szFpuSave , fpu_save
dd szFpuRestore , fpu_restore
dd 0
 
szKernel db 'KERNEL', 0
szAttachIntHandler db 'AttachIntHandler',0
szSysMsgBoardStr db 'SysMsgBoardStr', 0
szPciApi db 'PciApi', 0
szPciRead32 db 'PciRead32', 0
szPciRead8 db 'PciRead8', 0
szPciWrite8 db 'PciWrite8',0
szAllocKernelSpace db 'AllocKernelSpace',0
szMapPage db 'MapPage',0
szRegService db 'RegService',0
szKernelAlloc db 'KernelAlloc',0
szKernelFree db 'KernelFree',0
szGetPgAddr db 'GetPgAddr',0
szGetCurrentTask db 'GetCurrentTask',0
szGetService db 'GetService',0
szServiceHandler db 'ServiceHandler',0
szFpuSave db 'FpuSave',0
szFpuRestore db 'FpuRestore',0
 
endg
 
/kernel/tags/kolibri0.6.3.0/core/sched.inc
0,0 → 1,204
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; IRQ0 HANDLER (TIMER INTERRUPT) ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
align 32
irq0:
save_ring3_context
mov ax, os_data
mov ds, ax
mov es, ax
 
inc dword [timer_ticks]
 
mov eax, [timer_ticks]
call playNote ; <<<--- Speaker driver
 
cmp eax,[next_usage_update]
jb .nocounter
add eax,100
mov [next_usage_update],eax
call updatecputimes
.nocounter:
 
cmp [0xffff], byte 1
jne .change_task
 
mov al,0x20 ; send End Of Interrupt signal
mov dx,0x20
out dx,al
 
mov [0xffff], byte 0
 
restore_ring3_context
iret
 
.change_task:
call update_counters
 
call find_next_task
mov ecx, eax
 
mov al,0x20 ; send End Of Interrupt signal
mov dx,0x20
out dx,al
 
test ecx, ecx ; if there is only one running process
jnz .return
 
call do_change_task
.return:
restore_ring3_context
iret
 
 
align 4
change_task:
 
pushfd
cli
pushad
 
call update_counters
; \begin{Mario79}
cmp [dma_task_switched], 1
jne .find_next_task
mov [dma_task_switched], 0
mov ebx, [dma_process]
cmp [0x3000], ebx
je .return
mov edi, [dma_slot_ptr]
mov [0x3000], ebx
mov [0x3010], edi
jmp @f
.find_next_task:
; \end{Mario79}
call find_next_task
test eax, eax ; the same task -> skip switch
jnz .return
@@:
mov [0xffff],byte 1
call do_change_task
 
.return:
popad
popfd
 
ret
 
 
uglobal
align 4
far_jump:
.offs dd ?
.sel dw ?
context_counter dd ? ;noname & halyavin
next_usage_update dd ?
timer_ticks dd ?
prev_slot dd ?
event_sched dd ?
endg
 
 
update_counters:
mov edi, [0x3010]
mov ebx, [edi+TASKDATA.counter_add] ; time stamp counter add
call _rdtsc
sub eax, ebx
add eax, [edi+TASKDATA.counter_sum] ; counter sum
mov [edi+TASKDATA.counter_sum], eax
ret
 
 
; Find next task to execute
; result: ebx = number of the selected task
; eax = 1 if the task is the same
; edi = address of the data for the task in ebx
; [0x3000] = ebx and [0x3010] = edi
; corrupts other regs
find_next_task:
mov ebx, [0x3000]
mov edi, [0x3010]
mov [prev_slot], ebx
 
.waiting_for_termination:
.waiting_for_reuse:
.waiting_for_event:
.suspended:
cmp ebx, [0x3004]
jb @f
mov edi, 0x3000
xor ebx, ebx
@@:
 
add edi,0x20
inc ebx
 
mov al, byte [edi+TASKDATA.state]
test al, al
jz .found
cmp al, 1
jz .suspended
cmp al, 2
jz .suspended
cmp al, 3
je .waiting_for_termination
cmp al, 4
je .waiting_for_termination
cmp al, 9
je .waiting_for_reuse
 
mov [0x3000],ebx
mov [0x3010],edi
 
cmp al, 5
jne .noevents
call get_event_for_app
test eax, eax
jz .waiting_for_event
mov [event_sched], eax
mov [edi+TASKDATA.state], byte 0
.noevents:
.found:
mov [0x3000],ebx
mov [0x3010],edi
call _rdtsc
mov [edi+TASKDATA.counter_add],eax
 
xor eax, eax
cmp ebx, [prev_slot]
sete al
ret
 
; in: ebx = TSS selector index
do_change_task:
shl ebx, 3
xor eax, eax
add ebx, tss0
mov [far_jump.sel], bx ; selector
mov [far_jump.offs], eax ; offset
jmp pword [far_jump]
inc [context_counter] ;noname & halyavin
ret
 
 
 
align 4
updatecputimes:
 
mov eax,[idleuse]
mov [idleusesec],eax
mov [idleuse],dword 0
mov ecx, [0x3004]
mov edi, 0x3020
.newupdate:
mov ebx,[edi+TASKDATA.counter_sum]
mov [edi+TASKDATA.cpu_usage],ebx
mov [edi+TASKDATA.counter_sum],dword 0
add edi,0x20
dec ecx
jnz .newupdate
 
ret
/kernel/tags/kolibri0.6.3.0/core/except.inc
0,0 → 1,117
 
 
reg_eip equ ebp+4
reg_cs equ ebp+8
reg_eflags equ ebp+12
reg_esp equ ebp+16
reg_ss equ ebp+20
;fpu_ctrl equ ebp-28
 
align 4
except_16:
push ebp
mov ebp, esp
; sub esp, 28
 
push eax
push ebx
push ecx
push edx
 
mov ebx, [ss:CURRENT_TASK]
shl ebx, 8
 
mov eax, [ss:ebx+PROC_BASE+APPDATA.fpu_handler]
test eax, eax
jz .default
 
mov ecx, [reg_eip]
mov edx, [reg_esp]
sub edx, 4
mov [ss:edx+new_app_base], ecx
mov [reg_esp], edx
mov dword [reg_eip], eax
 
pop edx
pop ecx
pop ebx
pop eax
 
leave
iretd
 
.default:
pop edx
pop ecx
pop ebx
pop eax
leave
 
save_ring3_context ;debugger support
 
mov bl, 16
jmp exc_c
 
; fnstenv [fpu_ctrl]
; fnclex
; or word [fpu_ctrl], 0111111b
; fldenv [fpu_ctrl]
 
; pop edx
; pop ecx
; pop ebx
; pop eax
 
; leave
; iretd
 
align 16
except_19:
push ebp
mov ebp, esp
 
push eax
push ebx
push ecx
push edx
 
mov ebx, [ss:CURRENT_TASK]
shl ebx, 8
 
mov eax, [ss:ebx+PROC_BASE+APPDATA.sse_handler]
test eax, eax
jz .default
 
mov ecx, [reg_eip]
mov edx, [reg_esp]
sub edx, 4
mov [ss:edx+new_app_base], ecx
mov [reg_esp], edx
mov dword [reg_eip], eax
 
pop edx
pop ecx
pop ebx
pop eax
 
leave
iretd
 
.default:
pop edx
pop ecx
pop ebx
pop eax
leave
 
save_ring3_context ;debugger support
 
mov bl, 19
jmp exc_c
 
restore reg_eip
restore reg_cs
restore reg_eflags
restore reg_esp
restore reg_ss
;restore fpu_ctrl
/kernel/tags/kolibri0.6.3.0/core/newproce.inc
0,0 → 1,1076
if ~defined newprocess_inc
newprocess_inc_fix:
newprocess_inc fix newprocess_inc_fix
include "mem.inc"
include "memmanag.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Working with new types of processes.
;;Author: Khalyavin Andrey halyavin@land.ru
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
iglobal
new_process_loading db 'K : New Process - loading',13,10,0
new_process_running db 'K : New Process - done',13,10,0
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
endg
;-----------------------------------------------------------------------------
find_new_process_place:
;input:
; none
;result:
; eax=[new_process_place]<>0 - ok
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [0x3004]!
mov eax,0x3000+second_base_address
push ebx
mov ebx,[0x3004]
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+TASKDATA.state],9 ;check process state, 9 means that process slot is empty
jnz .newprocessplace
.endnewprocessplace:
mov ebx,eax
sub eax,0x3000+second_base_address
shr eax,5 ;calculate slot index
cmp eax,256
jge .failed ;it should be <256
mov word [ebx+TASKDATA.state],9 ;set process state to 9 (for slot after hight boundary)
mov [new_process_place],eax ;save process slot
pop ebx
ret
.failed:
xor eax,eax
pop ebx
ret
;-----------------------------------------------------------------------------
safe_sti:
cmp byte [0xe000], 1
jne @f
sti
@@:ret
;-----------------------------------------------------------------------------
new_sys_threads:
;eax=1 - create thread
; ebx=thread start
; ecx=thread stack value
;result:
; eax=pid
xor edx,edx ; flags=0
pushad
cmp eax,1
jnz .ret ;other subfunctions
mov esi,new_process_loading
call sys_msg_board_str
;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
;find free process slot
 
call find_new_process_place
test eax,eax
jz .failed
;set parameters for thread
xor eax,eax
mov [app_i_param],eax
mov [app_i_icon],eax
mov [app_start],ebx
mov [app_esp],ecx
 
mov esi,[0x3000]
shl esi,8
add esi,0x80000+APPDATA.app_name
mov ebx,esi ;ebx=esi - pointer to extended information about current thread
mov edi,[new_process_place]
shl edi,8
add edi,0x80000
lea edx, [edi+APPDATA.app_name] ;edx=edi - pointer to extended infomation about new thread
mov ecx,256/4
rep stosd ;clean extended information about new thread
mov edi,edx
mov ecx,11
rep movsb ;copy process name
mov eax,[ebx+APPDATA.mem_size]
mov [app_mem],eax ;set memory size
mov eax,[ebx+APPDATA.dir_table]
mov dword [edx-APPDATA.app_name+APPDATA.dir_table],eax ;copy page directory
; mov eax,[new_process_place]
; mov ebx,[0x3000]
; call addreference_app_cr3_table
 
push 0 ;no parameters
call fs_execute.add_app_parameters ;start thread
mov [esp+28],eax
popad
ret
.failed:
sti
popad
mov eax,-1
ret
.ret:
popad
ret
;-----------------------------------------------------------------------------
new_mem_resize:
;input:
; ebx - new size
;result:
; [esp+36]:=0 - normal
; [esp+36]:=1 - error
;This function set new application memory size.
mov esi,ebx ;save new size
add ebx,4095
and ebx,not (4096-1) ;round up size
mov ecx,[0x3000]
shl ecx,8
mov edx,[0x80000 + APPDATA.mem_size +ecx]
add edx,4095
and edx,not (4096-1) ;old size
mov eax,[0x80000 + APPDATA.dir_table+ecx]
call MEM_Get_Linear_Address
;eax - linear address of page directory
call MEM_Heap_Lock ;guarantee that two threads willn't
;change memory size simultaneously
cmp ebx,edx
; mov esi,ebx ;save new size
jg .expand
.free:
sub edx,ebx
jz .unlock ;do nothing
mov ecx,edx
shr ecx,12
add ebx,std_application_base_address
call mem_free_specified_region ;free unnecessary pages
jmp .unlock
 
.expand:
sub ebx,edx
mov ecx,ebx
shr ecx,12
mov ebx,edx
add ebx,std_application_base_address
call mem_alloc_specified_region ;alloc necessary pages
test eax,eax
jz .failed ;not enough memory
.unlock:
mov ebx,esi
mov eax,[0x3000]
shl eax,8
mov [eax+0x80000 + APPDATA.mem_size],ebx ;write new memory size
;search threads and update
;application memory size infomation
mov ecx,[eax+0x80000 + APPDATA.dir_table]
mov eax,2
.search_threads:
;eax = current slot
;ebx = new memory size
;ecx = page directory
cmp eax,[0x3004]
jg .search_threads_end
mov edx,eax
shl edx,5
cmp word [0x3000+edx+TASKDATA.state],9 ;if slot empty?
jz .search_threads_next
shl edx,3
cmp [edx+0x80000+APPDATA.dir_table],ecx ;if it is our thread?
jnz .search_threads_next
mov [edx+0x80000+APPDATA.mem_size],ebx ;update memory size
.search_threads_next:
inc eax
jmp .search_threads
.search_threads_end:
 
call MEM_Heap_UnLock
mov dword [esp+36],0
ret
.failed:
call MEM_Heap_UnLock
mov dword [esp+36],1
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,[0x3004]
shl ebx,5
mov ecx,2*32
.loop:
;ecx=offset of current process info entry
;ebx=maximum permitted offset
cmp byte [second_base_address+0x3000+ecx+TASKDATA.state],9
jz .endloop ;skip empty slots
cmp [second_base_address+0x3000+ecx+TASKDATA.pid],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
;-----------------------------------------------------------------------------
is_new_process:
;Input:
; eax - process slot
;Output:
; eax=1 - it is new process
; eax=0 - it is old process
; shl eax,5
; mov eax,[second_base_address+0x3000+eax+0x10]
; cmp eax,std_application_base_address ;check base address of application
; jz .new_process
; xor eax,eax
; ret
;.new_process:
mov eax,1
ret
;-----------------------------------------------------------------------------
write_process_memory:
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes written
pushad
shl eax,8
mov eax,[0x80000+eax+APPDATA.dir_table]
call MEM_Get_Linear_Address
mov ebp,eax
;ebp=linear address of page directory of other process.
add edx,std_application_base_address ;convert to linear address
test ecx,ecx
jle .ret
.write_loop:
;ebx = current buffer address
;ecx>0 = current size
;edx = current address in other process
;ebp = linear address of page directory
 
call MEM_Heap_Lock ;cli
mov esi,edx
shr esi,22
mov eax,[ebp+4*esi] ;find page directory entry
and eax,not (4096-1) ;clear flags
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address ;calculate linear address of page table
test eax,eax
jz .page_not_found
mov esi,edx
shr esi,12
and esi,1023
mov eax,[eax+4*esi] ;find page table entry
and eax,not (4096-1)
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address ;calculate linear address of page
test eax,eax
jz .page_not_found
mov edi,eax
call MEM_Add_Reference_Linear;guarantee that page willn't disappear
call MEM_Heap_UnLock ;sti
mov esi,edx
and esi,4095
add edi,esi ;add offset in page
;edi = linear address corresponding edx in other process
sub esi,4096
neg esi ;esi - number of remaining bytes in page
cmp esi,ecx
jl .min_ecx
mov esi,ecx
.min_ecx: ;esi=min(ecx,esi) - number of bytes to write
sub ecx,esi
push ecx
mov ecx,esi ;ecx - number of bytes to write
mov esi,ebx ;esi - source, edi - destination
add edx,ecx ;move pointer in address space of other process
push edi
;move ecx bytes
test ecx,3
jnz .not_aligned
shr ecx,2
rep movsd
jmp .next_iter
.not_aligned:
rep movsb
.next_iter:
 
pop eax
and eax,not (4096-1) ;eax - linear address of current page
call MEM_Free_Page_Linear ;free reference
mov ebx,esi ;new pointer to buffer - movsb automaticaly advance it.
pop ecx ;restore number of remaining bytes
test ecx,ecx
jnz .write_loop
.ret:
popad
mov eax,ecx
ret
.page_not_found:
call MEM_Heap_UnLock ;error has appeared in critical region
sub ecx,[esp+24] ;[esp+24]<-->ecx
neg ecx ;ecx=number_of_written_bytes
mov [esp+28],ecx ;[esp+28]<-->eax
popad
ret
;-----------------------------------------------------------------------------
syscall_test:
;for testing memory manager from applications.
mov edx,ecx
mov ecx,ebx
call trans_address
mov ebx,eax
mov eax,[0x3000]
call read_process_memory
ret
;-----------------------------------------------------------------------------
read_process_memory:
;Input:
; eax - process slot
; ebx - buffer address
; ecx - buffer size
; edx - start address in other process
;Output:
; eax - number of bytes read.
pushad
shl eax,8
mov eax,[0x80000+eax+APPDATA.dir_table]
call MEM_Get_Linear_Address
mov ebp,eax
add edx,std_application_base_address
.read_loop:
;ebx = current buffer address
;ecx>0 = current size
;edx = current address in other process
;ebp = linear address of page directory
 
call MEM_Heap_Lock ;cli
mov esi,edx
shr esi,22
mov eax,[ebp+4*esi] ;find page directory entry
and eax,not (4096-1)
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address
test eax,eax
jz .page_not_found
mov esi,edx
shr esi,12
and esi,1023
mov eax,[eax+4*esi] ;find page table entry
and eax,not (4096-1)
test eax,eax
jz .page_not_found
call MEM_Get_Linear_Address ;calculate linear address of page
test eax,eax
jz .page_not_found
mov esi,eax
call MEM_Add_Reference_Linear;guarantee that page willn't disappear
call MEM_Heap_UnLock ;sti
mov edi,edx
and edi,4095
add esi,edi ;add offset in page
;esi = linear address corresponding edx in other process
sub edi,4096
neg edi
;edi=min(edi,ecx) - number of bytes to copy
cmp edi,ecx
jl .min_ecx
mov edi,ecx
.min_ecx:
 
sub ecx,edi ;update size of remaining bytes
add edx,edi ;update current pointer in other address space.
push ecx
mov ecx,edi ;ecx - number of bytes to read
mov edi,ebx ;esi - source, edi - destination
push esi
;move ecx bytes
test ecx,3
jnz .not_aligned
shr ecx,2
rep movsd
jmp .next_iter
.not_aligned:
rep movsb
.next_iter:
pop eax
and eax,not (4096-1) ;eax - linear address of current page
call MEM_Free_Page_Linear ;free reference
mov ebx,edi ;new pointer to buffer - movsb automaticaly advance it.
pop ecx ;restore number of remaining bytes
test ecx,ecx
jnz .read_loop
popad
mov eax,ecx
ret
.page_not_found:
call MEM_Heap_UnLock ;error has appeared in critical region
sub ecx,[esp+24] ;[esp+24]<-->ecx
neg ecx ;ecx=number_of_read_bytes
mov [esp+28],ecx ;[esp+28]<-->eax
popad
ret
;-----------------------------------------------------------------------------
check_region:
;input:
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
mov eax,[0x3000]
jmp check_process_region
;-----------------------------------------------------------------------------
check_process_region:
;input:
; eax - slot
; ebx - start of buffer
; ecx - size of buffer
;result:
; eax = 1 region lays in app memory
; eax = 0 region don't lays in app memory
test ecx,ecx
jle .ok
shl eax,5
cmp word [0x3000+eax+TASKDATA.state],0
jnz .failed
shl eax,3
mov eax,[0x80000+eax+APPDATA.dir_table]
test eax,eax
jz .failed
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
;-----------------------------------------------------------------------------
new_sys_ipc:
;input:
; eax=1 - set ipc buffer area
; ebx=address of buffer
; ecx=size of buffer
; eax=2 - send message
; ebx=PID
; ecx=address of message
; edx=size of message
cmp eax,1
jnz .no_ipc_def
;set ipc buffer area
mov edi,[0x3000]
shl edi,8
add edi,0x80000
cli
mov [edi+APPDATA.ipc_start],ebx ;set fields in extended information area
mov [edi+APPDATA.ipc_size],ecx
sti
mov [esp+36],dword 0 ;success
ret
.no_ipc_def:
cmp eax,2
jnz .no_ipc_send
;send message
cli
;obtain slot from PID
mov eax,ebx
call pid_to_slot
test eax,eax
jz .no_pid
mov ebp,eax
;ebp = slot of other process
shl eax,8
mov edi,[eax+0x80000+APPDATA.ipc_start] ;is ipc area defined?
test edi,edi
jz .no_ipc_area
mov esi,[eax+0x80000+APPDATA.ipc_size] ;esi - size of buffer
push dword -1 ;temp variable for read_process_memory
mov ebx,esp
push ecx
push edx
mov ecx,4 ;read 4 bytes
mov eax,ebp
mov edx,edi ;from beginning of buffer.
call read_process_memory
mov eax,[esp+8]
test eax,eax
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now
add edx,4 ;move to next 4 bytes
mov eax,ebp
call read_process_memory ;read size of occupied space in buffer
sub esi,8
sub esi,[esp]
sub esi,[esp+8] ;esi=(buffer size)-(occupied size)-(message size)-(header of message size)
js .buffer_overflow ;esi<0 - not enough memory in buffer
mov esi,[esp+8] ;previous offset
add dword [esp+8],8
mov edi,[esp]
add [esp+8],edi ;add (size of message)+(size of header of message) to [buffer+4]
mov eax,ebp
call write_process_memory
add edx,esi
sub edx,4 ;move to beginning of place for our message
mov eax,[second_base_address+0x3010]
mov eax,[eax+TASKDATA.pid] ;eax - our PID
mov [esp+8],eax
mov eax,ebp
call write_process_memory ;write PID
mov ebx,esp ;address of size of message
mov eax,ebp
add edx,4
call write_process_memory ;write size of message
add edx,4
pop ecx ;ecx - size of message
pop eax
call trans_address
mov ebx,eax ;ebx - linear address of message
add esp,4 ;pop temporary variable
mov eax,ebp
call write_process_memory ;write message
sti
;awake other process
shl ebp,8
mov eax,ebp
or [eax+0x80000+APPDATA.event_mask],dword 0x40
cmp dword [check_idle_semaphore],20
jge .ipc_no_cis
mov dword [check_idle_semaphore],5
.ipc_no_cis:
mov dword [esp+36],0
ret
.no_ipc_send:
mov dword [esp+36],-1
ret
.no_pid:
sti
mov dword [esp+36],4
ret
.no_ipc_area:
sti
mov dword [esp+36],1
ret
.ipc_blocked:
sti
add esp,12
mov dword [esp+36],2
ret
.buffer_overflow:
sti
add esp,12
mov dword [esp+36],3
ret
;-----------------------------------------------------------------------------
trans_address:
;Input
; eax - application address
;Output
; eax - linear address for kernel
add eax,std_application_base_address
ret
;-----------------------------------------------------------------------------
 
; \begin{diamond}
include 'debug.inc'
 
fs_execute:
; ebx - cmdline
; edx - flags
; ebp - full filename
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it
pushad
; check filename length - with terminating NULL must be no more than 1024 symbols
mov edi, ebp
mov ecx, 1024
xor eax, eax
repnz scasb
jz @f
popad
mov eax, -ERROR_FILE_NOT_FOUND
ret
@@:
 
mov esi, new_process_loading
call sys_msg_board_str ; write message to message board
 
; lock application_table_status mutex
.table_status:
cli
cmp [application_table_status], 0
jz .stf
sti
call change_task
jmp .table_status
.stf:
call set_application_table_status
push ebx ; save command line pointer for add_app_parameters
 
call find_new_process_place ; find new process slot
call safe_sti
test eax, eax
mov ecx, -0x20 ; too many processes
jz .failed
 
; write application name
push edi
mov ecx, edi
sub ecx, ebp
mov [appl_path], ebp
mov [appl_path_size], ecx
dec edi
std
mov al, '/'
repnz scasb
cld
jnz @f
inc edi
@@:
inc edi
; now edi points to name without path
mov esi, edi
mov ecx, 8 ; 8 chars for name
mov edi, [new_process_place]
shl edi, cl
add edi, 0x80000+APPDATA.app_name
.copy_process_name_loop:
lodsb
cmp al, '.'
jz .copy_process_name_done
test al, al
jz .copy_process_name_done
stosb
loop .copy_process_name_loop
.copy_process_name_done:
mov al, ' '
rep stosb
pop eax
mov cl, 3 ; 3 chars for extension
dec esi
@@:
dec eax
cmp eax, esi
jbe .copy_process_ext_done
cmp byte [eax], '.'
jnz @b
lea esi, [eax+1]
.copy_process_ext_loop:
lodsb
test al, al
jz .copy_process_ext_done
stosb
loop .copy_process_ext_loop
.copy_process_ext_done:
mov al, ' '
rep stosb
 
; read header
lea eax, [esp+8+36]
mov edi, 0x90000
call dword [eax-4]
mov ecx, eax
neg ecx
jnz .cleanfailed
; check menuet signature
mov ecx, -0x1F
cmp dword [0x90000], 'MENU'
jnz .cleanfailed
cmp word [0x90004], 'ET'
jnz .cleanfailed
call get_app_params
mov ecx, -0x1F
jc .cleanfailed
; sanity check - because we will load all file,
; file size must be not greater than memory size
mov eax, [esp+8+36]
cmp [app_mem], eax
jb .cleanfailed
 
mov eax, [new_process_place]
inc ecx ; -0x1E = no memory
call create_app_cr3_table
test eax, eax
jz .cleanfailed_mem
 
call MEM_Get_Linear_Address
 
mov ebx, std_application_base_address
mov ecx, [app_mem]
add ecx, 4095
shr ecx, 12
mov edx, eax ; edx - linear address of page directory
call mem_alloc_specified_region
mov ecx, -0x1E ; no memory
test eax, eax
jz .cleanfailed_mem1
 
add edx, std_application_base_address shr 20
mov eax, [edx]
and eax, not 4095
call MEM_Get_Linear_Address
push edx ; save pointer to first page table
mov edx, eax
; read file
; first block is already read to 0x90000
mov eax, [edx]
and eax, not 0xFFF
call MEM_Get_Linear_Address
mov esi, 0x90000
mov edi, eax
mov ecx, 512/4
rep movsd
sub edi, eax
.loop1:
; [esp] = pointer to current page directory entry
; edx = pointer to current page table
; edi = offset in page
mov eax, [edx]
and eax, not 0xFFF
call MEM_Get_Linear_Address
push edi
add edi, eax
lea eax, [esp+8+36+8]
call dword [eax-4]
pop edi
test eax, eax
jnz .endloop1
add edi, 512 ; new offset
cmp edi, 4096
jb .loop1
xor edi, edi
add edx, 4 ; go to next page
test edx, 4096-1
jnz .loop1
pop eax
add eax, 4 ; go to next directory entry
push eax
mov eax, [eax]
and eax, not 0xFFF
call MEM_Get_Linear_Address
mov edx, eax
jmp .loop1
.endloop1:
pop edx
cmp eax, 6
jnz .cleanfailed_mem2
call .add_app_parameters
mov [esp+28], eax
popad
ret
 
.cleanfailed_mem2:
; file read error; free all allocated mem
mov ecx, eax
neg ecx
mov eax, [new_process_place]
call dispose_app_cr3_table
jmp .cleanfailed
.cleanfailed_mem1:
; there is mem for directory entry, but there is no mem for pages
; so free directory entry
mov eax, [new_process_place]
shl eax, 8
mov eax, [0x80000+eax+0xB8]
call MEM_Free_Page
.cleanfailed_mem:
; there is no mem for directory entry, display message
mov esi, start_not_enough_memory
call sys_msg_board_str
.cleanfailed:
push ecx
; clean process name, this avoid problems with @panel
mov edi, [new_process_place]
shl edi, 8
add edi, 0x80000+APPDATA.app_name
mov ecx, 11
mov al, ' '
rep stosb
pop eax
.failed:
pop ebx
mov [esp+28], eax
popad
mov [application_table_status], 0
call safe_sti
ret
; \end{diamond}
.add_app_parameters:
;input:
; [esp] - pointer to parameters
; [esp+4]-[esp+36] pushad registers.
;result
; eax - pid of new process
; or zero if failed
cli
mov ebx,[new_process_place]
cmp ebx,[0x3004]
jle .noinc
inc dword [0x3004] ;update number of processes
.noinc:
 
; mov ebx,[new_process_place]
;set 0x8c field of extended information about process
;(size of application memory)
shl ebx,8
mov eax,[app_mem]
mov [second_base_address+0x80000+APPDATA.mem_size+ebx],eax
;set 0x10 field of information about process
;(application base address)
; mov ebx,[new_process_place]
; shl ebx,5
shr ebx,3
mov dword [second_base_address+0x3000+ebx+TASKDATA.mem_start],std_application_base_address
 
;add command line parameters
.add_command_line:
mov edx,[app_i_param]
test edx,edx
jz .no_command_line ;application don't need parameters
mov eax,[esp+4]
test eax,eax
jz .no_command_line ;no parameters specified
;calculate parameter length
mov esi,eax
xor ecx,ecx
inc ecx ; include terminating null
.command_line_len:
cmp byte [esi],0
jz .command_line_len_end
inc esi
inc ecx
cmp ecx,256
jl .command_line_len
.command_line_len_end:
;ecx - parameter length
;edx - address of parameters in new process address space
mov ebx,eax ;ebx - address of parameters in our address space
mov eax,[new_process_place]
call write_process_memory ;copy parameters to new process address space
.no_command_line:
;******************************************************************
mov edx,[app_i_icon]
test edx,edx
jz .no_command_line_1 ;application don't need path of file
mov ebx,[appl_path]
mov ecx,[appl_path_size]
mov eax,[new_process_place]
call write_process_memory ;copy path of file to new process address space
.no_command_line_1:
;******************************************************************
mov ebx,[new_process_place]
mov eax,ebx
shl ebx,5
mov [ebx+window_data+WDATA.fl_wstate],WSTATE_NORMAL
mov [ebx+window_data+WDATA.fl_redraw],1
add ebx,0x3000 ;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+TASKDATA.pid],eax ;set PID
mov ecx,ebx
add ecx,draw_data-0x3000 ;ecx - pointer to draw data
;set draw data to full screen
mov [ecx+RECT.left],dword 0
mov [ecx+RECT.top],dword 0
mov eax,[0xfe00]
mov [ecx+RECT.right],eax
mov eax,[0xfe04]
mov [ecx+RECT.bottom],eax
;set cr3 register in TSS of application
mov ecx,[new_process_place]
shl ecx,8
mov eax,[0x80000+APPDATA.dir_table+ecx]
add eax,8+16 ;add flags
mov [l.cr3],eax
mov eax,[app_start]
mov [l.eip],eax ;set eip in TSS
mov eax,[app_esp]
mov [l.esp],eax ;set stack in TSS
;gdt
;mov ebx,[new_process_place]
;shl ebx,3
mov ax,app_code ;ax - selector of code segment
;add ax,bx
mov [l.cs],ax
mov ax,app_data
;add ax,bx ;ax - selector of data segment
mov [l.ss],ax
mov [l.ds],ax
mov [l.es],ax
mov [l.fs],ax
mov ax,graph_data ;ax - selector of graphic segment
mov [l.gs],ax
mov [l.io],word 128
mov [l.eflags],dword 0x11202
mov [l.ss0],os_data
mov ebx,[new_process_place]
shl ebx,12
add ebx,sysint_stack_data+4096
mov [l.esp0],ebx
 
;copy tss to it place
mov eax,tss_sceleton
mov ebx,[new_process_place]
imul ebx,tss_step
add ebx,tss_data ;ebx - address of application TSS
mov ecx,120
call memmove
;Add IO access table - bit array of permitted ports
or eax,-1
mov edi,[new_process_place]
imul edi,tss_step
add edi,tss_data+128
mov ecx,2048
cld
rep stosd ;full access to 2048*8=16384 ports
mov ecx,ebx ;ecx - address of application TSS
mov edi,[new_process_place]
shl edi,3
;set TSS descriptor
mov [edi+gdts+tss0+0],word tss_step ;limit (size)
mov [edi+gdts+tss0+2],cx ;part of offset
mov eax,ecx
shr eax,16
mov [edi+gdts+tss0+4],al ;part of offset
mov [edi+gdts+tss0+7],ah ;part of offset
mov [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
 
;flush keyboard and buttons queue
mov [0xf400],byte 0
mov [0xf500],byte 0
 
mov edi,[new_process_place]
shl edi,5
add edi,window_data
mov ebx,[new_process_place]
movzx esi,word [0xC000+ebx*2]
lea esi,[0xC400+esi*2]
call windowactivate ;gui initialization
 
mov ebx,[new_process_place]
shl ebx,5
; set if debuggee
test byte [esp+28], 1
jz .no_debug
mov [0x3000+ebx+TASKDATA.state], 1 ; set process state - suspended
mov eax, [0x3000]
mov [0x80000+ebx*8+APPDATA.debugger_slot], eax ;set debugger PID - current
jmp .debug
.no_debug:
mov [0x3000+ebx+TASKDATA.state], 0 ; set process state - running
.debug:
mov esi,new_process_running
call sys_msg_board_str ;output information about succefull startup
; add esp,4 ;pop pointer to parameters
; popad
mov eax,[process_number] ;set result
mov [application_table_status],0 ;unlock application_table_status mutex
call safe_sti
ret 4
 
end if
/kernel/tags/kolibri0.6.3.0/core/debug.inc
0,0 → 1,499
; diamond, 2006
sys_debug_services:
cmp eax, 9
ja @f
jmp dword [sys_debug_services_table+eax*4]
@@: ret
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
 
debug_set_event_data:
; in: ebx = pointer
; destroys eax
mov eax, [0x3000]
shl eax, 8
mov [eax+0x80000+APPDATA.dbg_event_mem], ebx
ret
 
get_debuggee_slot:
; in: ebx=PID
; out: CF=1 if error
; CF=0 and eax=slot*0x20 if ok
; out: interrupts disabled
cli
mov eax, ebx
call pid_to_slot
test eax, eax
jz .ret_bad
shl eax, 5
push ebx
mov ebx, [0x3000]
cmp [0x80000+eax*8+APPDATA.debugger_slot], ebx
pop ebx
jnz .ret_bad
; clc ; automatically
ret
.ret_bad:
stc
ret
 
debug_detach:
; in: ebx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
and dword [eax*8+0x80000+APPDATA.debugger_slot], 0
call do_resume
.ret:
sti
ret
 
debug_terminate:
; in: ebx=pid
call get_debuggee_slot
jc debug_detach.ret
mov ebx, eax
shr ebx, 5
push 2
pop eax
jmp sys_system
 
debug_suspend:
; in: ebx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
mov bl, [0x3000+eax+TASKDATA.state] ; process state
test bl, bl
jz .1
cmp bl, 5
jnz .ret
mov bl, 2
.2: mov [0x3000+eax+TASKDATA.state], bl
.ret:
sti
ret
.1:
inc ebx
jmp .2
 
do_resume:
mov bl, [0x3000+eax+TASKDATA.state]
cmp bl, 1
jz .1
cmp bl, 2
jnz .ret
mov bl, 5
.2: mov [0x3000+eax+TASKDATA.state], bl
.ret: ret
.1: dec ebx
jmp .2
 
debug_resume:
; in: ebx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
call do_resume
.ret: sti
ret
 
debug_getcontext:
; in:
; ebx=pid
; ecx=sizeof(CONTEXT)
; edx->CONTEXT
; destroys eax,ecx,edx,esi,edi
cmp ecx, 28h
jnz .ret
add edx, std_application_base_address
push ebx
mov ebx, edx
call check_region
pop ebx
dec eax
jnz .ret
call get_debuggee_slot
jc .ret
imul eax, tss_step/32
add eax, tss_data
mov edi, edx
cmp [l.cs - tss_sceleton + eax], app_code
jnz .ring0
lea esi, [l.eip - tss_sceleton + eax]
shr ecx, 2
rep movsd
jmp .ret
.ring0:
; note that following code assumes that all interrupt/exception handlers
; saves ring-3 context by push ds es, pushad in this order
mov esi, [l.esp0 - tss_sceleton + eax]
; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), ds, es, pushad
sub esi, 8+12+8+20h
lodsd
mov [edi+24h], eax
lodsd
mov [edi+20h], eax
lodsd
mov [edi+1Ch], eax
lodsd
lodsd
mov [edi+14h], eax
lodsd
mov [edi+10h], eax
lodsd
mov [edi+0Ch], eax
lodsd
mov [edi+8], eax
add esi, 8
lodsd
mov [edi], eax
lodsd
lodsd
mov [edi+4], eax
lodsd
mov [edi+18h], eax
.ret:
sti
ret
 
debug_setcontext:
; in:
; ebx=pid
; ecx=sizeof(CONTEXT)
; edx->CONTEXT
; destroys eax,ecx,edx,esi,edi
cmp ecx, 28h
jnz .ret
add edx, std_application_base_address
push ebx
mov ebx, edx
call check_region
pop ebx
dec eax
jnz .ret
call get_debuggee_slot
jc .stiret
imul eax, tss_step/32
add eax, tss_data
mov esi, edx
cmp [l.cs - tss_sceleton + eax], app_code
jnz .ring0
lea edi, [l.eip - tss_sceleton + eax]
shr ecx, 2
rep movsd
jmp .stiret
.ring0:
mov edi, [l.esp0 - tss_sceleton + eax]
sub edi, 8+12+8+20h
mov eax, [esi+24h]
stosd
mov eax, [esi+20h]
stosd
mov eax, [esi+1Ch]
stosd
scasd
mov eax, [esi+14h]
stosd
mov eax, [esi+10h]
stosd
mov eax, [esi+0Ch]
stosd
mov eax, [esi+8]
stosd
add edi, 8
mov eax, [esi]
stosd
scasd
mov eax, [esi+4]
stosd
mov eax, [esi+18h]
stosd
.stiret:
sti
.ret:
ret
 
debug_set_drx:
call get_debuggee_slot
jc .errret
mov ebp, eax
lea eax, [eax*8+0x80000+APPDATA.dbg_regs]
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3
; [eax+10]=dr7
add edx, std_application_base_address
jc .errret
cmp cl, 3
ja .errret
mov ebx, dr7
shr ebx, cl
shr ebx, cl
test ebx, 2 ; bit 1+2*index = G0..G3, global break enable
jnz .errret2
test ch, ch
jns .new
; clear breakpoint
movzx ecx, cl
add ecx, ecx
and dword [eax+ecx*2], 0 ; clear DR<i>
btr dword [eax+10h], ecx ; clear L<i> bit
test byte [eax+10h], 55h
jnz .okret
imul eax, ebp, tss_step/32
and byte [eax + tss_data + l.trap - tss_sceleton], not 1
.okret:
and dword [esp+36], 0
sti
ret
.errret:
sti
mov dword [esp+36], 1
ret
.errret2:
sti
mov dword [esp+36], 2
ret
.new:
; add new breakpoint
; cl=index; ch=flags; edx=address
test ch, 0xF0
jnz .errret
mov bl, ch
and bl, 3
cmp bl, 2
jz .errret
mov bl, ch
shr bl, 2
cmp bl, 2
jz .errret
test dl, bl
jnz .errret
or byte [eax+10h+1], 3 ; set GE and LE flags
movzx ebx, ch
movzx ecx, cl
add ecx, ecx
bts dword [eax+10h], ecx ; set L<i> flag
add ecx, ecx
mov [eax+ecx], edx ; set DR<i>
shl ebx, cl
mov edx, 0xF
shl edx, cl
not edx
and [eax+10h+2], dx
or [eax+10h+2], bx ; set R/W and LEN fields
imul eax, ebp, tss_step/32
or byte [eax + tss_data + l.trap - tss_sceleton], 1
jmp .okret
 
debug_read_process_memory:
; in:
; ebx=pid
; ecx=length
; esi->buffer in debugger
; edx=address in debuggee
; out: [esp+36]=sizeof(read)
; destroys all
add esi, std_application_base_address
push ebx
mov ebx, esi
call check_region
pop ebx
dec eax
jnz .err
call get_debuggee_slot
jc .err
shr eax, 5
mov ebx, esi
call read_process_memory
sti
mov dword [esp+36], eax
ret
.err:
or dword [esp+36], -1
ret
 
debug_write_process_memory:
; in:
; ebx=pid
; ecx=length
; esi->buffer in debugger
; edx=address in debuggee
; out: [esp+36]=sizeof(write)
; destroys all
add esi, std_application_base_address
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 ebx, esi
call write_process_memory
sti
mov [esp+36], 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 edx, [0x80000+eax+APPDATA.dbg_event_mem]
test edx, edx
jz .ret
; read buffer header
push ecx
push eax
push eax
mov eax, ebp
mov ebx, esp
mov ecx, 8
call read_process_memory
cmp eax, ecx
jz @f
add esp, 12
jmp .ret
@@:
cmp dword [ebx], 0
jg @f
.2:
pop ecx
pop ecx
pop ecx
cmp dword [0x3000], 1
jnz .notos
cmp [timer_ticks], edi
jae .ret
.notos:
sti
call change_task
cli
jmp .1
@@:
mov ecx, [ebx+8]
add ecx, [ebx+4]
cmp ecx, [ebx]
ja .2
; advance buffer position
push ecx
mov ecx, 4
sub ebx, ecx
mov eax, ebp
add edx, ecx
call write_process_memory
pop eax
; write message
mov eax, ebp
add edx, ecx
add edx, [ebx+8]
add ebx, 20
pop ecx
pop ecx
pop ecx
call write_process_memory
; new debug event
mov eax, ebp
shl eax, 8
or byte [0x80000+eax+APPDATA.event_mask+1], 1 ; set flag 100h
.ret:
ret
 
debug_exc:
; int 1 = #DB
save_ring3_context
cld
mov ax, os_data
mov ds, ax
mov es, ax
mov eax, dr6
test ax, ax
jns @f
; this is exception from task switch
; set DRx registers for task and continue
mov eax, [0x3000]
shl eax, 8
add eax, 0x80000+APPDATA.dbg_regs
mov ecx, [eax+0]
mov dr0, ecx
mov ecx, [eax+4]
mov dr1, ecx
mov ecx, [eax+8]
mov dr2, ecx
mov ecx, [eax+0Ch]
mov dr3, ecx
xor ecx, ecx
mov dr6, ecx
mov ecx, [eax+10h]
mov dr7, ecx
restore_ring3_context
iretd
@@:
push eax
xor eax, eax
mov dr6, eax
; test if debugging
cli
mov eax, [0x3000]
shl eax, 8
mov eax, [0x80000+eax+APPDATA.debugger_slot]
test eax, eax
jnz .debug
sti
; not debuggee => say error and terminate
add esp, 28h+4
mov [error_interrupt], 1
call show_error_parameters
mov edx, [0x3010]
mov byte [edx+TASKDATA.state], 4
jmp change_task
.debug:
; we are debugged process, notify debugger and suspend ourself
; eax=debugger PID
pop edx
mov ebx, dr7
mov cl, not 1
.l1:
test bl, 1
jnz @f
and dl, cl
@@:
shr ebx, 2
add cl, cl
inc ecx
cmp cl, not 10h
jnz .l1
push edx ; DR6 image
mov ecx, [0x3010]
push dword [ecx+TASKDATA.pid] ; PID
push 12
pop ecx
push 3 ; 3 = debug exception
call debugger_notify
pop ecx
pop ecx
pop ecx
mov edx, [0x3010]
mov byte [edx+TASKDATA.state], 1 ; suspended
call change_task
restore_ring3_context
iretd
/kernel/tags/kolibri0.6.3.0/core/mem.inc
0,0 → 1,469
if ~defined mem_inc
mem_inc_fix:
mem_inc fix mem_inc_fix
;include "memmanag.inc"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;High-level memory management in MenuetOS.
;;It uses memory manager in memmanager.inc
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
second_base_address=0xC0000000
std_application_base_address=0x10000000
general_page_table_ dd 0
general_page_table=general_page_table_+second_base_address
;-----------------------------------------------------------------------------
create_general_page_table:
;input
; none
;output
; none
;Procedure create general page directory and write
;it address to [general_page_table].
pushad
mov eax,1 ;alloc 1 page
mov ebx,general_page_table ;write address to [general_page_table]
call MEM_Alloc_Pages ;allocate page directory
mov eax,[general_page_table]
call MEM_Get_Linear_Address ;eax - linear address of page directory
mov edi,eax
mov ebx,eax ;copy address of page directory to safe place
xor eax,eax
mov ecx,4096/4
cld
rep stosd ;clear page directory
mov eax,4
mov edx,eax
call MEM_Alloc_Pages ;alloc page tables for 0x0-0x1000000 region
cmp eax,edx
jnz $ ;hang if not enough memory
;fill page tables
xor esi,esi
mov ebp,7
.loop:
;esi - number of page in page directory
;ebp - current page address
;ebx - linear address of page directory
mov eax,[ebx+4*esi]
add dword [ebx+4*esi],7 ;add flags to address of page table
call MEM_Get_Linear_Address
;eax - linear address of page table
mov ecx,4096/4
;ecx (counter) - number of pages in page table
;current address=4Mb*esi
.loop1:
mov [eax],ebp ;write page address (with flags) in page table
add eax,4
add ebp,4096 ;size of page=4096 bytes
loop .loop1
inc esi ;next page directory entry
cmp esi,edx
jnz .loop
;map region 0x80000000-0x807fffff to LFB
mov eax,2 ;size of the region is 4Mb so only 1 page table needed
mov edx,ebx ;ebx still contains linear address of the page directory
add ebx,0x800
call MEM_Alloc_Pages ;alloc page table for the region
mov eax,[ebx]
add dword [ebx],7 ;add flags
call MEM_Get_Linear_Address ;get linear address of the page table
mov ecx,4096/4 ;number of pages in page table
mov edi,[0xfe80]
add edi,7
.loop3:
;eax - linear address of page table
;edi - current linear address with flags
mov [eax],edi
add eax,4
add edi,4096
loop .loop3
mov eax,[ebx+4]
call MEM_Get_Linear_Address
add dword [ebx+4],7
mov ecx,4096/4
.loop31:
mov [eax],edi
add eax,4
add edi,4096
loop .loop31
;map region 0xC0000000-* to 0x0-*
mov esi,edx ;esi=linear address of the page directory
lea edi,[esi+(second_base_address shr 20)];add offset of entry (0xC00)
mov ecx,4
rep movsd ;first 16Mb of the region mapped as 0x0-0x1000000 block
mov eax,[0xfe8c] ;eax=memory size
add eax,0x3fffff
shr eax,22
mov esi,eax ;calculate number of entries in page directory
sub esi,4 ;subtract entries for first 16Mb.
mov ebp,0x1000000+7 ;start physical address with flags
;mapping memory higher than 16Mb
.loop4:
;esi (counter) - number of entries in page directory
;edi - address of entry
test esi,esi
jle .loop4end
call MEM_Alloc_Page ;alloc page table for entry in page directory
mov [edi],eax
add dword [edi],7 ;write physical address of page table in page directory
add edi,4 ;move entry pointer
call MEM_Get_Linear_Address
mov ecx,eax
xor edx,edx
.loop5:
;ecx - linear address of page table
;edx - index of page in page table
;ebp - current mapped physical address with flags
mov [ecx+4*edx],ebp ;write address of page in page table
add ebp,0x1000 ;move to next page
inc edx
cmp edx,4096/4
jl .loop5
dec esi
jmp .loop4
.loop4end:
.set_cr3:
;set value of cr3 register to the address of page directory
mov eax,[general_page_table]
add eax,8+16 ;add flags
mov cr3,eax ;now we have full access paging
popad
ret
;-----------------------------------------------------------------------------
simple_clone_cr3_table:
;Parameters:
; eax - physical address of cr3 table (page directory)
;result:
; eax - physical address of clone of cr3 table.
;Function copy only page directory.
push ecx
push edx
push esi
push edi
call MEM_Get_Linear_Address
;eax - linear address of cr3 table
mov esi,eax
call MEM_Alloc_Page
test eax,eax
jz .failed
;eax - physical address of new page diretory
mov edx,eax
call MEM_Get_Linear_Address
mov edi,eax
mov ecx,4096/4
cld
;esi - address of old page directory
;edi - address of new page directory
rep movsd ;copy page directory
mov eax,edx
.failed:
pop edi
pop esi
pop edx
pop ecx
ret
;-----------------------------------------------------------------------------
create_app_cr3_table:
;Parameters:
; eax - slot of process (index in 0x3000 table)
;result:
; eax - physical address of table.
;This function create page directory for new process and
;write it physical address to offset 0xB8 of extended
;process information.
push ebx
 
mov ebx,eax
mov eax,[general_page_table]
call simple_clone_cr3_table ;clone general page table
shl ebx,8
mov [second_base_address+0x80000+ebx+APPDATA.dir_table],eax ;save address of page directory
pop ebx
ret
;-----------------------------------------------------------------------------
get_cr3_table:
;Input:
; eax - slot of process
;result:
; eax - physical address of page directory
shl eax,8 ;size of process extended information=256 bytes
mov eax,[second_base_address+0x80000+eax+APPDATA.dir_table]
ret
;-----------------------------------------------------------------------------
dispose_app_cr3_table:
;Input:
; eax - slot of process
;result:
; none
;This procedure frees page directory,
;page tables and all memory of process.
pushad
mov ebp,eax
;ebp = process slot in the procedure.
shl eax,8
mov eax,[second_base_address+0x80000+eax+APPDATA.dir_table]
mov ebx,eax
;ebx = physical address of page directory
call MEM_Get_Linear_Address
mov edi,eax
;edi = linear address of page directory
mov eax,[edi+(std_application_base_address shr 20)]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov esi,eax
;esi = linear address of first page table
 
;search threads
; mov ecx,0x200
xor edx,edx
mov eax,0x2
.loop:
;eax = current slot of process
mov ecx,eax
shl ecx,5
cmp byte [second_base_address+0x3000+ecx+TASKDATA.state],9 ;if process running?
jz .next ;skip empty slots
shl ecx,3
cmp [second_base_address+0x80000+ecx+APPDATA.dir_table],ebx ;compare page directory addresses
jnz .next
inc edx ;thread found
.next:
inc eax
cmp eax,[0x3004] ;exit loop if we look through all processes
jle .loop
;edx = number of threads
;our process is zombi so it isn't counted
cmp edx,1
jg .threadsexists
;if there isn't threads then clear memory.
add edi,std_application_base_address shr 20
.loop1:
;edi = linear address of current directory entry
;esi = linear address of current page table
test esi,esi
jz .loop1end
xor ecx,ecx
.loop2:
;ecx = index of page
mov eax,[esi+4*ecx]
test eax,eax
jz .loopend ;skip empty entries
and eax,not (4096-1) ;clear flags
push ecx
call MEM_Free_Page ;free page
pop ecx
.loopend:
inc ecx
cmp ecx,1024 ;there are 1024 pages in page table
jl .loop2
mov eax,esi
call MEM_Free_Page_Linear ;free page table
.loop1end:
add edi,4 ;move to next directory entry
mov eax,[edi]
and eax,not (4096-1)
call MEM_Get_Linear_Address
mov esi,eax ;calculate linear address of new page table
test edi,0x800
jz .loop1 ;test if we at 0x80000000 address?
and edi,not (4096-1) ;clear offset of page directory entry
mov eax,edi
call MEM_Free_Page_Linear ;free page directory
popad
ret
.threadsexists: ;do nothing
popad ;last thread will free memory
ret
;-----------------------------------------------------------------------------
mem_alloc_specified_region:
;eax - linear directory address
;ebx - start address (aligned to 4096 bytes)
;ecx - size in pages
;result:
; eax=1 - ok
; eax=0 - failed
;Try to alloc and map ecx pages to [ebx;ebx+4096*ecx) interval.
pushad
mov ebp,ebx ;save start address for recoil
mov esi,eax
.gen_loop:
;esi = linear directory address
;ebx = current address
;ecx = remaining size in pages
mov edx,ebx
shr edx,22
mov edi,[esi+4*edx] ;find directory entry for current address
test edi,edi
jnz .table_exists ;check if page table allocated
call MEM_Alloc_Page ;alloc page table
test eax,eax
jz .failed
mov [esi+4*edx],eax
add dword [esi+4*edx],7 ;write it address with flags
call MEM_Get_Linear_Address
call mem_fill_page ;clear page table
jmp .table_linear
.table_exists:
;calculate linear address of page table
mov eax,edi
and eax,not (4096-1) ;clear flags
call MEM_Get_Linear_Address
.table_linear:
;eax = linear address of page table
mov edx,ebx
shr edx,12
and edx,(1024-1) ;calculate index in page table
mov edi,eax
.loop:
;edi = linear address of page table
;edx = current page table index
;ecx = remaining size in pages
;ebx = current address
test ecx,ecx
jle .endloop1 ;all requested pages allocated
call MEM_Alloc_Page ;alloc new page
test eax,eax
jz .failed
mov [edi+4*edx],eax
add dword [edi+4*edx],7 ;write it address with flags
call MEM_Get_Linear_Address
call mem_fill_page ;clear new page
;go to next page table entry
dec ecx
add ebx,4096
inc edx
test edx,(1024-1)
jnz .loop
jmp .gen_loop
.endloop1:
popad
mov eax,1 ;ok
ret
.failed:
;calculate data for recoil
sub ebx,ebp
shr ebx,12
mov ecx,ebx ;calculate number of allocated pages
mov eax,esi ;restore linear address of page directory
mov ebx,ebp ;restore initial address
call mem_free_specified_region ;free all allocated pages
popad
xor eax,eax ;fail
ret
;-----------------------------------------------------------------------------
mem_fill_page:
;Input:
; eax - address
;result:
; none
;set to zero 4096 bytes at eax address.
push ecx
push edi
mov edi,eax
mov ecx,4096/4
xor eax,eax
rep stosd
lea eax,[edi-4096]
pop edi
pop ecx
ret
;-----------------------------------------------------------------------------
mem_free_specified_region:
;eax - linear page directory address
;ebx - start address (aligned to 4096 bytes)
;ecx - size in pages
;result - none
;Free pages in [ebx;ebx+4096*ecx) region.
pushad
mov esi,eax
xor ebp,ebp
.gen_loop:
;esi = linear page directory address
;ebx = current address
;ecx = remaining pages
;ebp = 0 for first page table
; 1 otherwise
mov edx,ebx
shr edx,22
mov eax,[esi+4*edx] ;find directory entry for current address
and eax,not (4096-1)
test eax,eax
jnz .table_exists
;skip absent page tables
mov edx,ebx
shr edx,12
and edx,(1024-1) ;edx - index of current page
add ebx,1 shl 22
add ecx,edx
and ebx,not ((1 shl 22)-1)
mov ebp,1 ;set flag
sub ecx,1024 ;ecx=ecx-(1024-edx)
jg .gen_loop
popad
ret
.table_exists:
call MEM_Get_Linear_Address
;eax - linear address of table
mov edx,ebx
shr edx,12
and edx,(1024-1) ;edx - index of current page
mov edi,eax
.loop:
;edi = linear address of page table entry
;edx = index of page table entry
;ecx = remaining pages
test ecx,ecx
jle .endloop1
mov eax,[edi+4*edx]
and eax,not (4096-1)
call MEM_Free_Page ;free page
mov dword [edi+4*edx],0 ;and clear page table entry
dec ecx
inc edx
cmp edx,1024
jl .loop
test ebp,ebp
jz .first_page
mov eax,edi
call MEM_Free_Page_Linear ;free page table
mov edx,ebx
shr edx,22
mov dword [esi+4*edx],0 ;and clear page directory entry
.first_page:
add ebx,1 shl 22
and ebx,not ((1 shl 22)-1) ;calculate new current address
mov ebp,1 ;set flag
jmp .gen_loop
.endloop1:
popad
ret
end if
/kernel/tags/kolibri0.6.3.0/core/physmem.inc
0,0 → 1,220
virtual at 0
physical_mem_block:
.start rd 1
.size rd 1
.flags rd 1 ;0-free, pid-used.
.sizeof:
end virtual
max_physical_mem_blocks = 24
uglobal
num_physical_mem_blocks rd 1
physical_mem_blocks rd 3*max_physical_mem_blocks
endg
Init_Physical_Memory_Manager:
pushad
mov edi,physical_mem_blocks
mov ecx,3*max_physical_mem_blocks
xor eax,eax
cld
rep stosd
mov dword [num_physical_mem_blocks],2
mov [physical_mem_blocks+physical_mem_block.start],0x60000
mov [physical_mem_blocks+physical_mem_block.size],0x20000 ;128Kb
mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.start],0x780000
mov [physical_mem_blocks+physical_mem_block.sizeof+physical_mem_block.size],0x80000 ;512Kb
popad
ret
Insert_Block:
;input:
; eax - handle
;output:
; none
push eax ecx esi edi
sub eax,[num_physical_mem_blocks]
neg eax
mov edi,physical_mem_block.sizeof
imul eax,edi
shr eax,2
mov ecx,eax
mov esi,[num_physical_mem_blocks]
imul esi,edi
add esi,physical_mem_blocks
lea edi,[esi+physical_mem_block.sizeof]
std
rep movsd
pop edi esi ecx eax
ret
Delete_Block:
;input:
; eax - handle
;output:
; none
pushad
mov edi,eax
sub eax,[num_physical_mem_blocks]
neg eax
dec eax
mov esi,physical_mem_block.sizeof
imul eax,esi
imul edi,esi
add edi,physical_mem_blocks
lea esi,[edi+physical_mem_block.sizeof]
mov ecx,eax
shr ecx,2
cld
rep movsd
popad
ret
Allocate_Physical_Block:
;input:
; eax - size
;output:
; eax - address or 0 if not enough memory.
pushad
cmp [num_physical_mem_blocks],max_physical_mem_blocks
jge .error
mov ebx,eax
xor eax,eax
mov esi,physical_mem_blocks
.loop:
cmp dword [esi+physical_mem_block.flags],0
jnz .next
cmp [esi+physical_mem_block.size],ebx
jg .addblock
jz .noaddblock
.next:
inc eax
add esi,physical_mem_block.sizeof
cmp eax,[num_physical_mem_blocks]
jl .loop
.error:
popad
xor eax,eax
ret
.noaddblock:
mov eax,[esi+physical_mem_block.start]
mov [esp+28],eax
mov eax,[0x3010]
mov eax,[eax+TASKDATA.pid]
mov [esi+physical_mem_block.flags],eax
popad
ret
.addblock:
call Insert_Block
inc dword [num_physical_mem_blocks]
mov eax,[esi+physical_mem_block.start]
mov [esp+28],eax
mov ecx,[0x3010]
mov ecx,[ecx+TASKDATA.pid]
mov [esi+physical_mem_block.flags],ecx
mov ecx,[esi+physical_mem_block.size]
mov [esi+physical_mem_block.size],ebx
sub ecx,ebx
mov [esi+physical_mem_block.sizeof+physical_mem_block.size],ecx
add ebx,[esi+physical_mem_block.start]
mov [esi+physical_mem_block.sizeof+physical_mem_block.start],ebx
mov dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0
popad
ret
Free_Physical_Block:
;input:
; eax - address
;output:
; none
pushad
test eax,eax
jz .ret
mov ebx,eax
xor eax,eax
mov esi,physical_mem_blocks
.loop:
cmp ebx,[esi+physical_mem_block.start]
jz .endloop
inc eax
add esi,physical_mem_block.sizeof
cmp eax,[num_physical_mem_blocks]
jl .loop
jmp .ret
.endloop:
mov dword [esi+physical_mem_block.flags],0
test eax,eax
jz .no_union_previous
cmp dword [esi-physical_mem_block.sizeof+physical_mem_block.flags],0
jnz .no_union_previous
mov ebx,[esi-physical_mem_block.sizeof+physical_mem_block.start]
add ebx,[esi-physical_mem_block.sizeof+physical_mem_block.size]
cmp ebx,[esi+physical_mem_block.start]
jnz .no_union_previous
mov ebx,[esi+physical_mem_block.size]
add [esi-physical_mem_block.sizeof+physical_mem_block.size],ebx
call Delete_Block
dec eax
dec [num_physical_mem_blocks]
.no_union_previous:
inc eax
cmp eax,[num_physical_mem_blocks]
jge .no_union_next
cmp dword [esi+physical_mem_block.sizeof+physical_mem_block.flags],0
jnz .no_union_next
mov ebx,[esi+physical_mem_block.start]
add ebx,[esi+physical_mem_block.size]
cmp ebx,[esi+physical_mem_block.sizeof+physical_mem_block.start]
jnz .no_union_next
mov ebx,[esi+physical_mem_block.sizeof+physical_mem_block.size]
add [esi+physical_mem_block.size],ebx
call Delete_Block
dec [num_physical_mem_blocks]
.no_union_next:
.ret:
popad
ret
sys_allocate_physical_block:
;eax - subfunction number
mov eax,ebx
call Allocate_Physical_Block
mov [esp+36],eax
ret
sys_free_physical_block:
;eax - subfunction number
mov eax,ebx
call Free_Physical_Block
ret
sys_set_buffer:
add ecx,std_application_base_address
isys_set_buffer: ;for using in kernel
;eax - subfunction number
;ebx - physical address
;ecx - buffer start
;edx - buffer size
lea edi,[ebx+second_base_address]
mov esi,ecx
mov ecx,edx
cld
rep movsb
ret
sys_get_buffer:
add ecx,std_application_base_address
isys_get_buffer: ;for using in kernel
;eax - subfunction number
;ebx - physical address
;ecx - buffer start
;edx - buffer size
mov edi,ecx
lea esi,[ebx+second_base_address]
mov ecx,edx
cld
rep movsb
ret
sys_internal_services:
cmp eax,4
jle sys_sheduler
cmp eax,5
jz sys_allocate_physical_block
cmp eax,6
jz sys_free_physical_block
cmp eax,7
jz sys_set_buffer
cmp eax,8
jz sys_get_buffer
ret
/kernel/tags/kolibri0.6.3.0/core/sync.inc
0,0 → 1,111
if ~defined sync_inc
sync_inc_fix:
sync_inc fix sync_inc_fix
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Synhronization for MenuetOS. ;;
;;Author: Halyavin Andrey, halyavin@land.ru ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;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 [0x3010+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,[0x3010+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,[0x3000+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
 
/kernel/tags/kolibri0.6.3.0/core/memmanag.inc
0,0 → 1,833
if ~defined memmanager_inc
memmanager_inc_fix:
memmanager_inc fix memmanager_inc_fix
;for testing in applications
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Memory allocator for MenuetOS kernel
;; Andrey Halyavin, halyavin@land.ru 2005
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; heap block structure -
;; you can handle several ranges of
;; pages simultaneosly.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.heap_linear_address equ 0
.heap_block_size equ 4
.heap_physical_address equ 8
.heap_reserved equ 12
.heap_block_info equ 16
max_heaps equ 8
.range_info equ 36
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; memory manager data
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
uglobal
MEM_heap_block rd .heap_block_info*max_heaps/4
MEM_heap_count rd 1
MEM_cli_count rd 1
MEM_cli_prev rd 1
MEM_FreeSpace rd 1
; MEM_AllSpace rd 1
endg
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Init
;;Initialize memory manager structures.
;;Must be called first.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Init:
push eax
xor eax,eax
mov [MEM_cli_prev],eax ;init value = 0
dec eax
mov [MEM_cli_count],eax ;init value = -1
pop eax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Heap_Lock
;;Wait until all operations with heap will be finished.
;;Between MEM_Heap_Lock and MEM_Heap_UnLock operations
;;with heap are forbidden.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Heap_Lock:
pushfd
cli
inc dword [MEM_cli_count]
jz MEM_Heap_First_Lock
add esp,4
ret
MEM_Heap_First_Lock: ;save interrupt flag
shr dword [esp],9
and dword [esp],1
pop dword [MEM_cli_prev]
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Heap_UnLock
;;After this routine operations with heap are allowed.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Heap_UnLock:
dec dword [MEM_cli_count]
js MEM_Heap_UnLock_last
ret
MEM_Heap_UnLock_last:
cmp dword [MEM_cli_prev],0 ;restore saved interrupt flag
jz MEM_Heap_UnLock_No_sti
sti
MEM_Heap_UnLock_No_sti:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Heap
;;Add new range to memory manager.
;;eax - linear address
;;ebx - size in pages
;;ecx - physical address
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MEM_Add_Heap:
push edx
call MEM_Heap_Lock
mov edx,[MEM_heap_count]
cmp edx,max_heaps
jz MEM_Add_Heap_Error
inc dword [MEM_heap_count]
shl edx,4
mov [MEM_heap_block+edx+.heap_linear_address],eax
mov [MEM_heap_block+edx+.heap_block_size],ebx
shl dword [MEM_heap_block+edx+.heap_block_size],12
mov [MEM_heap_block+edx+.heap_physical_address],ecx
lea edx,[4*ebx+.range_info+4095] ;calculate space for page info table
and edx,0xFFFFF000
 
push edi
mov edi,edx
shr edi,12
sub edi,ebx ;edi=-free space
sub [MEM_FreeSpace],edi
; sub [MEM_AllSpace],edi
 
mov [eax],eax
add [eax],edx ;first 4 bytes - pointer to first free page
;clean page info area
lea edi,[eax+4]
mov ecx,edx
shr ecx,2
push eax
xor eax,eax
rep stosd
pop eax
pop edi
;create free pages list.
mov ecx,[eax]
shl ebx,12
add eax,ebx ;eax - address after block
MEM_Add_Heap_loop:
add ecx,4096
mov [ecx-4096],ecx ;set forward pointer
cmp ecx,eax
jnz MEM_Add_Heap_loop
mov dword [ecx-4096],0 ;set end of list
MEM_Add_Heap_ret:
call MEM_Heap_UnLock
pop edx
ret
MEM_Add_Heap_Error:
xor eax,eax
jmp MEM_Add_Heap_ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Physical_Address
;;Translate linear address to physical address
;;Parameters:
;; eax - linear address
;;Result:
;; eax - physical address
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Physical_Address
MEM_Get_Physical_Address:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Physical_Address_loop:
sub eax,[MEM_heap_block+ecx+.heap_linear_address]
jl MEM_Get_Physical_Address_next
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jge MEM_Get_Physical_Address_next
add eax,[MEM_heap_block+ecx+.heap_physical_address]
jmp MEM_Get_Physical_Address_loopend
MEM_Get_Physical_Address_next:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
sub ecx,16
jns MEM_Get_Physical_Address_loop
xor eax,eax ;address not found
MEM_Get_Physical_Address_loopend:
call MEM_Heap_UnLock
pop ecx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Linear_Address
;;Translate physical address to linear address.
;;Parameters:
;; eax - physical address
;;Result:
;; eax - linear address
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Linear_Address
MEM_Get_Linear_Address:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Linear_Address_loop:
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
jl MEM_Get_Linear_Address_Next
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jge MEM_Get_Linear_Address_Next
add eax,[MEM_heap_block+ecx+.heap_linear_address]
call MEM_Heap_UnLock
pop ecx
ret
MEM_Get_Linear_Address_Next:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
sub ecx,16
jns MEM_Get_Linear_Address_loop
call MEM_Heap_UnLock
pop ecx
xor eax,eax ;address not found
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Page
;;Allocate and add reference to page
;;Result:
;; eax<>0 - physical address of page
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Page
MEM_Alloc_Page:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Page_loop:
push ecx
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [ecx],0
jz MEM_Alloc_Page_loopend
mov eax,[ecx]
push dword [eax]
pop dword [ecx]
sub eax,ecx
push eax
shr eax,10
mov word [ecx+.range_info+eax],1
pop eax
pop ecx
add eax,[MEM_heap_block+ecx+.heap_physical_address]
dec [MEM_FreeSpace]
jmp MEM_Alloc_Page_ret
MEM_Alloc_Page_loopend:
pop ecx
sub ecx,16
jns MEM_Alloc_Page_loop
xor eax,eax
MEM_Alloc_Page_ret:
call MEM_Heap_UnLock
pop ecx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Page_Linear
;;Allocate and add reference to page
;;Result:
;; eax<>0 - linear address of page
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Page_Linear
MEM_Alloc_Page_Linear:
push ecx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Page_Linear_loop:
push ecx
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [ecx],0
jz MEM_Alloc_Page_Linear_loopend
mov eax,[ecx]
push dword [eax]
pop dword [ecx]
push eax
sub eax,ecx
shr eax,10
mov word [ecx+.range_info+eax],1
pop eax
pop ecx
dec [MEM_FreeSpace]
jmp MEM_Alloc_Page_Linear_ret
MEM_Alloc_Page_Linear_loopend:
pop ecx
sub ecx,16
jns MEM_Alloc_Page_Linear_loop
xor eax,eax
MEM_Alloc_Page_Linear_ret:
call MEM_Heap_UnLock
pop ecx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Page
;;Remove reference and free page if number of
;;references is equal to 0
;;Parameters:
;; eax - physical address of page
;;Result:
;; eax - 1 success
;; eax - 0 failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if (used MEM_Free_Page) | (used MEM_Free_Page_Linear)
MEM_Free_Page:
test eax,eax
jz MEM_Free_Page_Zero
test eax,0xFFF
jnz MEM_Free_Page_Not_Aligned
push ebx
push ecx
push edx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Free_Page_Heap_loop:
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
js MEM_Free_Page_Heap_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Free_Page_Heap_loopend
MEM_Free_Page_Heap_loopnext:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
sub ecx,16
jns MEM_Free_Page_Heap_loop
xor eax,eax
inc eax
jmp MEM_Free_Page_ret
MEM_Free_Page_Heap_loopend:
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
mov ebx,eax
add eax,ecx
shr ebx,10
mov edx,[ecx+.range_info+ebx]
test edx,0x80000000
jnz MEM_Free_Page_Bucket
test dx,dx
jz MEM_Free_Page_Error
dec word [ecx+.range_info+ebx]
jnz MEM_Free_Page_OK
MEM_Free_Page_Bucket:
push dword [ecx]
mov [ecx],eax
pop dword [eax]
mov dword [ecx+.range_info+ebx],0
inc [MEM_FreeSpace]
MEM_Free_Page_OK:
mov eax,1
MEM_Free_Page_ret:
call MEM_Heap_UnLock
pop edx
pop ecx
pop ebx
ret
MEM_Free_Page_Error:
xor eax,eax
jmp MEM_Free_Page_ret
MEM_Free_Page_Zero:
inc eax
ret
MEM_Free_Page_Not_Aligned:
xor eax,eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Page_Linear
;;Remove reference and free page if number of
;;references is equal to 0
;;Parameters:
;; eax - linear address of page
;;Result:
;; eax - 1 success
;; eax - 0 failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Page_Linear
MEM_Free_Page_Linear:
test eax,eax
jz MEM_Free_Page_Zero
test eax,0xFFF
jnz MEM_Free_Page_Not_Aligned
push ebx
push ecx
push edx
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Free_Page_Linear_Heap_loop:
sub eax,[MEM_heap_block+ecx+.heap_linear_address]
js MEM_Free_Page_Linear_Heap_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Free_Page_Heap_loopend
MEM_Free_Page_Linear_Heap_loopnext:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
sub ecx,16
jns MEM_Free_Page_Linear_Heap_loop
xor eax,eax
inc eax
jmp MEM_Free_Page_ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Pages
;;Allocates set of pages.
;;Parameters:
;; eax - number of pages
;; ebx - buffer for physical addresses
;;Result:
;; eax - number of allocated pages
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Pages
MEM_Alloc_Pages:
push eax
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Alloc_Pages_ret
MEM_Alloc_Pages_loop:
call MEM_Alloc_Page
test eax,eax
jz MEM_Alloc_Pages_ret
mov [ebx],eax
add ebx,4
dec ecx
jnz MEM_Alloc_Pages_loop
MEM_Alloc_Pages_ret:
sub [esp+8],ecx
pop ecx
pop ebx
pop eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc_Pages_Linear
;;Allocates set of pages.
;;Parameters:
;; eax - number of pages
;; ebx - buffer for linear addresses
;;Result:
;; eax - number of allocated pages
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc_Pages_Linear
MEM_Alloc_Pages_Linear:
push eax
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Alloc_Pages_Linear_ret
MEM_Alloc_Pages_Linear_loop:
call MEM_Alloc_Page_Linear
test eax,eax
jz MEM_Alloc_Pages_Linear_ret
mov [ebx],eax
add ebx,4
dec ecx
jnz MEM_Alloc_Pages_Linear_loop
MEM_Alloc_Pages_Linear_ret:
sub [esp+8],ecx
pop ecx
pop ebx
pop eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Pages
;;Parameters:
;; eax - number of pages
;; ebx - array of addresses
;;Result:
;; eax=1 - succcess
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Pages
MEM_Free_Pages:
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Free_Pages_ret
MEM_Free_Pages_loop:
mov eax,[ebx]
call MEM_Free_Page
add ebx,4
test eax,eax
jz MEM_Free_Pages_ret
dec ecx
jnz MEM_Free_Pages_loop
MEM_Free_Pages_ret:
pop ecx
pop ebx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free_Pages_Linear
;;Parameters:
;; eax - number of pages
;; ebx - array of addresses
;;Result:
;; eax=1 - succcess
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free_Pages_Linear
MEM_Free_Pages_Linear:
push ebx
push ecx
mov ecx,eax
test ecx,ecx
jz MEM_Free_Pages_Linear_ret
MEM_Free_Pages_Linear_loop:
mov eax,[ebx]
call MEM_Free_Page_Linear
add ebx,4
test eax,eax
jz MEM_Free_Pages_Linear_ret
dec ecx
jnz MEM_Free_Pages_Linear_loop
MEM_Free_Pages_Linear_ret:
pop ecx
pop ebx
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Heap_Number
;;Calculate number of heap which pointer belongs to.
;;Parameter:
;; eax - address
;;Result:
;; ecx - number of heap*16.
;; eax=0 if address not found.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Heap_Number
MEM_Get_Heap_Number:
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Heap_loop:
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
jl MEM_Get_Heap_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Get_Heap_loopend
MEM_Get_Heap_loopnext:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
sub ecx,16
jns MEM_Get_Heap_loop
call MEM_Heap_UnLock
xor eax,eax
ret
MEM_Get_Heap_loopend:
add eax,[MEM_heap_block+ecx+.heap_physical_address]
call MEM_Heap_UnLock
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Get_Heap_Number_Linear
;;Calculate number of heap which pointer belongs to.
;;Parameter:
;; eax - address
;;Result:
;; ecx - number of heap*16.
;; eax=0 if address not found.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Get_Heap_Number_Linear
MEM_Get_Heap_Number_Linear:
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Get_Heap_Linear_loop:
sub eax,[MEM_heap_block+ecx+.heap_linear_address]
jl MEM_Get_Heap_Linear_loopnext
cmp eax,[MEM_heap_block+ecx+.heap_block_size]
jl MEM_Get_Heap_Linear_loopend
MEM_Get_Heap_Linear_loopnext:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
sub ecx,16
jns MEM_Get_Heap_Linear_loop
call MEM_Heap_UnLock
xor eax,eax
ret
MEM_Get_Heap_Linear_loopend:
add eax,[MEM_heap_block+ecx+.heap_linear_address]
call MEM_Heap_UnLock
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Alloc
;;Allocate small region.
;;Parameters:
;; eax - size (0<eax<=4096)
;;Result:
;; eax - linear address
;; eax=0 - not enough memory
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Alloc
MEM_Alloc:
;find chain
test eax,eax
jng MEM_Alloc_Wrong_Size
cmp eax,4096
jg MEM_Alloc_Wrong_Size
push ebx
push ecx
push edx
push esi
dec eax
shr eax,4
xor edx,edx
MEM_Alloc_Find_Size:
add edx,4
shr eax,1
jnz MEM_Alloc_Find_Size
MEM_Alloc_Size_Found:
mov ecx,edx
shr ecx,2
add ecx,4
mov eax,1
shl eax,cl
mov esi,eax
;esi - block size
;edx - offset
call MEM_Heap_Lock
mov ecx,[MEM_heap_count]
dec ecx
shl ecx,4
MEM_Alloc_Find_Heap:
mov eax,[MEM_heap_block+ecx+.heap_linear_address]
cmp dword [eax+edx],0
jnz MEM_Alloc_Use_Existing
sub ecx,16
jns MEM_Alloc_Find_Heap
;create new bucket page
call MEM_Alloc_Page_Linear
call MEM_Get_Heap_Number_Linear
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
mov [ecx+edx],eax
lea ebx,[eax+4096]
MEM_Alloc_List_loop:
mov [eax],eax
mov [eax+4],eax
add [eax],esi
sub [eax+4],esi
add eax,esi
cmp eax,ebx
jnz MEM_Alloc_List_loop
sub ebx,esi
mov dword [ebx],0
sub eax,4096
mov dword [eax+4],0
mov eax,ecx
MEM_Alloc_Use_Existing:
mov ebx,eax
mov eax,[eax+edx]
mov ecx,[eax]
mov [ebx+edx],ecx
test ecx,ecx
jz MEM_Alloc_Became_Empty
mov dword [ecx+4],0
MEM_Alloc_Became_Empty:
mov ecx,eax
sub ecx,ebx
shr ecx,10
and ecx,0xFFFFFFFC
inc byte [ebx+.range_info+ecx+2]
shr edx,2
add edx,128
dec edx
mov [ebx+.range_info+ecx+3],dl
MEM_Alloc_ret:
call MEM_Heap_UnLock
pop esi
pop edx
pop ecx
pop ebx
ret
MEM_Alloc_Wrong_Size:
xor eax,eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Free
;;Parameters:
;; eax - linear address
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Free
MEM_Free:
test eax,eax
jz MEM_Free_Zero
push ebx
push ecx
push edx
push esi
push edi
push ebp
call MEM_Heap_Lock
call MEM_Get_Heap_Number_Linear
test eax,eax
jz MEM_Free_ret
mov edx,eax
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
sub edx,ecx
shr edx,10
and edx,0xFFFFFFFC
mov ebx,[ecx+.range_info+edx]
mov esi,ebx
shr esi,24
sub esi,128
mov edi,[ecx+4+4*esi]
mov [eax],edi
mov dword [eax+4],0
test edi,edi
jz MEM_Free_Empty_List
mov [edi+4],eax
MEM_Free_Empty_List:
mov [ecx+4+4*esi],eax
sub ebx,0x10000
mov [ecx+.range_info+edx],ebx
test ebx,0xFF0000
jnz MEM_Free_ret
;delete empty blocks on the page
lea edx,[esi+5]
and eax,0xFFFFF000
mov edi,eax
mov eax,1
xchg ecx,edx
shl eax,cl
mov ecx,edx
mov edx,eax
;edx - size of block
;edi - start of page
mov eax,edi
lea ebx,[eax+4096]
MEM_Free_Block_loop:
cmp dword [eax+4],0
jnz MEM_Free_Block_Not_First
mov ebp,dword [eax]
mov [ecx+4+4*esi],ebp
test ebp,ebp
jz MEM_Free_Block_Last
mov dword [ebp+4],0
MEM_Free_Block_Last:
jmp MEM_Free_Block_loop_end
MEM_Free_Block_Not_First:
mov ebp,dword [eax]
push ebp
mov ebp,dword [eax+4]
pop dword [ebp]
mov ebp,dword [eax]
test ebp,ebp
jz MEM_Free_Block_loop_end
push dword [eax+4]
pop dword [ebp+4]
; jmp MEM_Free_Block_loop_end
MEM_Free_Block_loop_end:
add eax,edx
cmp eax,ebx
jnz MEM_Free_Block_loop
mov eax,edi
call MEM_Free_Page_Linear
MEM_Free_ret:
call MEM_Heap_UnLock
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
ret
MEM_Free_Zero:
inc eax
ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Reference
;; eax - physical address of page
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Add_Reference
MEM_Add_Reference:
push ebx
push ecx
call MEM_Heap_Lock
call MEM_Get_Heap_Number
test eax,eax
jz MEM_Add_Reference_ret
sub eax,[MEM_heap_block+ecx+.heap_physical_address]
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
shr eax,10
and eax,0xFFFFFFFC
test dword [ecx+eax+.range_info],0x80000000
jnz MEM_Add_Reference_failed
inc dword [ecx+eax+.range_info]
MEM_Add_Reference_ret:
call MEM_Heap_UnLock
pop ecx
pop ebx
ret
MEM_Add_Reference_failed:
xor eax,eax
jmp MEM_Add_Reference_ret
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;MEM_Add_Reference_Linear
;; eax - linear address of page
;;Result:
;; eax=1 - success
;; eax=0 - failed
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
if used MEM_Add_Reference_Linear
MEM_Add_Reference_Linear:
push ebx
push ecx
call MEM_Heap_Lock
call MEM_Get_Heap_Number_Linear
test eax,eax
jz MEM_Add_Reference_Linear_ret
mov ecx,[MEM_heap_block+ecx+.heap_linear_address]
sub eax,ecx
shr eax,10
and eax,0xFFFFFFFC
test dword [ecx+eax+.range_info],0x80000000
jnz MEM_Add_Reference_Linear_failed
inc dword [ecx+eax+.range_info]
mov eax,1
MEM_Add_Reference_Linear_ret:
call MEM_Heap_UnLock
pop ecx
pop ebx
ret
MEM_Add_Reference_Linear_failed:
xor eax,eax
jmp MEM_Add_Reference_Linear_ret
end if
end if ;memmanager.inc
/kernel/tags/kolibri0.6.3.0/drivers/mixer.asm
0,0 → 1,1287
;
; This file is part of the Infinity sound library.
; (C) copyright Serge 2006
; email: infinity_sound@mail.ru
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
 
align 4
proc new_mix stdcall, output:dword
locals
mixCounter dd ?
mixIndex dd ?
streamIndex dd ?
inputCount dd ?
main_count dd ?
blockCount dd ?
mix_out dd ?
endl
 
call prepare_playlist
 
cmp [play_count], 0
je .exit
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
 
sub [main_count], 1
jnz .l00
 
call update_stream
emms
call FpuRestore
ret
.exit:
mov edi, [output]
mov ecx, 0x1000
xor eax, eax
cld
rep stosd
ret
endp
 
 
align 4
proc update_stream
locals
stream_index dd ?
endl
 
mov [stream_index], 0
.l1:
mov edx, [stream_index]
mov esi, [play_list+edx*4]
 
mov eax, [esi+STREAM.work_read]
cmp eax, [esi+STREAM.work_top]
jb @f
mov eax, [esi+STREAM.work_buff]
@@:
mov [esi+STREAM.work_read], eax
 
cmp [esi+STREAM.format], PCM_2_16_48
je .copy
 
sub [esi+STREAM.work_count], 16384
 
cmp [esi+STREAM.work_count], 32768
ja @f
 
stdcall refill, esi
@@:
inc [stream_index]
dec [play_count]
jnz .l1
 
ret
.copy:
mov ebx, esi
mov edi, [ebx+STREAM.work_write]
cmp edi, [ebx+STREAM.work_top]
jb @f
mov edi, [ebx+STREAM.work_buff]
mov [ebx+STREAM.work_write], edi
@@:
mov esi, [ebx+STREAM.curr_seg]
mov ecx, 16384/4
cld
rep movsd
 
mov [ebx+STREAM.work_write], edi
 
cmp esi, [ebx+STREAM.limit]
jb @f
 
mov esi, [ebx+STREAM.base]
@@:
mov [ebx+STREAM.curr_seg], esi
 
xor ecx, ecx
cmp esi, [ebx+STREAM.notify_off2]
je @f
 
mov ecx,0x8000
cmp esi, [ebx+STREAM.notify_off1]
je @f
 
inc [stream_index]
dec [play_count]
jnz .l1
 
ret
@@:
mov eax, [ebx+STREAM.notify_task]
call pid_to_slot
test eax, eax
jnz @f
not eax
mov [ebx+STREAM.notify_task], eax ;-1
jmp .l_end
@@:
shl eax, 8
mov [eax+PROC_BASE+32],ecx
or dword [eax+PROC_BASE+0xA8],EVENT_NOTIFY
.l_end:
inc [stream_index]
dec [play_count]
jnz .l1
ret
endp
 
align 4
proc refill stdcall, str:dword
 
; if DEBUG
; mov esi, msgUser
; call [SysMsgBoardStr]
; end if
 
mov ebx, [str]
 
mov ecx, [ebx+STREAM.work_write]
cmp ecx, [ebx+STREAM.work_top]
jbe .m2
mov esi, [ebx+STREAM.work_top]
sub ecx, esi
mov edi, [ebx+STREAM.work_buff]
shr ecx, 2
rep movsd ;call memcpy
 
mov [ebx+STREAM.work_write], edi
.m2:
mov esi, [ebx+STREAM.curr_seg]
mov edi, [ebx+STREAM.work_write]
mov edx, [ebx+STREAM.r_buff]
 
stdcall [ebx+STREAM.resample], edi, esi, edx,\
[ebx+STREAM.r_dt],[ebx+STREAM.r_size],[ebx+STREAM.r_end]
 
mov ebx, [str]
 
add [ebx+STREAM.work_count], eax;
add [ebx+STREAM.work_write], eax;
 
mov eax, [ebx+STREAM.curr_seg]
add eax, [ebx+STREAM.r_size]
cmp eax, [ebx+STREAM.limit]
jb @f
mov eax, [ebx+STREAM.base]
@@:
mov [ebx+STREAM.curr_seg], eax
 
xor ecx, ecx
cmp eax, [ebx+STREAM.notify_off2]
je @f
 
mov ecx,0x8000
cmp eax, [ebx+STREAM.notify_off1]
je @f
 
ret
@@:
mov eax, [ebx+STREAM.notify_task]
call pid_to_slot
test eax, eax
jnz @f
not eax
mov [ebx+STREAM.notify_task], eax ;-1
ret
@@:
shl eax, 8
mov [eax+PROC_BASE+32],ecx
or dword [eax+PROC_BASE+0xA8],EVENT_NOTIFY
ret
endp
 
align 4
proc resample_1 stdcall, dest:dword,src:dword,r_buff:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov edi, [r_buff]
add edi, 32*2
mov esi, [src]
mov ecx, [r_size]
shr ecx, 2
rep movsd
 
mov edi, [dest]
mov edx, [r_buff]
mov eax, 16
 
align 16
.l1:
mov ecx, eax
mov esi, eax
and ecx, 0x7FFF
shr esi, 15
lea esi, [edx+esi*2]
 
movsx ebp, word [esi]
movsx esi, word [esi+2]
mov ebx, 32768
imul esi, ecx
sub ebx, ecx
imul ebx, ebp
lea ecx, [ebx+esi+16384]
sar ecx, 15
cmp ecx, 32767 ; 00007fffH
jle @f
mov ecx, 32767 ; 00007fffH
jmp .write
@@:
cmp ecx, -32768 ; ffff8000H
jge .write
mov ecx, -32768 ; ffff8000H
.write:
mov ebx, ecx
shl ebx, 16
mov bx, cx
mov [edi], ebx
add edi, 4
 
add eax, [esp+20] ;rdt
cmp eax, [esp+28] ;r_end
jb .l1
 
mov ebp, esp
 
mov esi, [src]
add esi, [r_size]
sub esi, 32*2
mov edx, [r_buff]
mov ecx, 16
@@:
mov ebx, [esi]
mov [edx], ebx
add esi, 4
add edx, 4
dec ecx
jnz @B
 
sub edi, [dest]
mov eax, edi
ret
endp
 
align 4
proc resample_18 stdcall, dest:dword,src:dword,r_buff:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov edi, [r_buff]
add edi, 32
mov esi, [src]
mov ecx, [r_size]
shr ecx, 2
rep movsd
 
mov edi, [dest]
mov edx, [r_buff]
mov esi, 16
 
align 16
.l1:
mov ecx, esi
mov eax, esi
and ecx, 0x7FFF
shr eax, 15
lea eax, [edx+eax]
 
mov bx, word [eax]
sub bh, 0x80
sub bl, 0x80
movsx eax, bh
shl eax,8
movsx ebp, bl
shl ebp,8
mov ebx, 32768
imul eax, ecx
sub ebx, ecx
imul ebx, ebp
lea ecx, [ebx+eax+16384]
sar ecx, 15
cmp ecx, 32767 ; 00007fffH
jle @f
mov ecx, 32767 ; 00007fffH
jmp .write
@@:
cmp ecx, -32768 ; ffff8000H
jge .write
mov ecx, -32768 ; ffff8000H
.write:
mov ebx, ecx
shl ebx, 16
mov bx, cx
mov [edi], ebx
add edi, 4
 
add esi, [esp+20] ;rdt
cmp esi, [esp+28] ;r_end
jb .l1
 
mov ebp, esp
 
mov esi, [src]
add esi, [r_size]
sub esi, 32
mov edx, [r_buff]
mov ecx, 8
@@:
mov ebx, [esi]
mov [edx], ebx
add esi, 4
add edx, 4
dec ecx
jnz @B
 
sub edi, [dest]
mov eax, edi
ret
endp
 
align 4
proc copy_stream stdcall, dest:dword,src:dword,r_buff:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov ecx, [r_size]
mov eax, ecx
shr ecx, 2
mov esi, [src]
mov edi, [dest]
rep movsd
mov eax, 16384
ret
endp
 
align 4
proc resample_2 stdcall, dest:dword,src:dword,r_buff:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov edi, [r_buff]
add edi, 32*4
mov esi, [src]
mov ecx, [r_size]
shr ecx, 2
rep movsd ;call memcpy
 
mov edx, [r_buff]
mov edi, [dest]
mov ebx, [r_dt]
mov eax, 16
emms
 
align 16
.l1:
mov ecx, eax
mov esi, eax
and ecx, 0x7FFF
shr esi, 15
lea esi, [edx+esi*4]
 
movq mm0, [esi]
movq mm1, mm0
 
movd mm2, ecx
punpcklwd mm2, mm2
movq mm3, qword [m7] ; // 0x8000
 
psubw mm3, mm2 ; // 0x8000 - iconst
punpckldq mm3, mm2
 
pmulhw mm0, mm3
pmullw mm1, mm3
 
movq mm4, mm1
punpcklwd mm1, mm0
punpckhwd mm4, mm0
paddd mm1, mm4
psrad mm1, 15
packssdw mm1, mm1
movd [edi], mm1
add edi, 4
 
add eax, ebx
cmp eax, [r_end]
jb .l1
emms
 
mov esi, [src]
add esi, [r_size]
sub esi, 32*4
mov edx, [r_buff]
mov ecx, 32
@@:
mov ebx, [esi]
mov [edx], ebx
add esi, 4
add edx, 4
dec ecx
jnz @B
 
sub edi, [dest]
mov eax, edi
ret
endp
 
align 4
proc resample_28 stdcall, dest:dword,src:dword,r_buff:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov edi, [r_buff]
add edi, 32*2
mov esi, [src]
mov ecx, [r_size]
shr ecx, 2
rep movsd ;call memcpy
 
mov edx, [r_buff]
mov edi, [dest]
mov ebx, [r_dt]
mov eax, 16
emms
movq mm7,[mm80]
movq mm6,[mm_mask]
 
align 16
.l1:
mov ecx, eax
mov esi, eax
and ecx, 0x7FFF
shr esi, 15
lea esi, [edx+esi*2]
 
movq mm0, [esi]
psubb mm0,mm7
punpcklbw mm0,mm0
pand mm0,mm6
 
movq mm1, mm0
 
movd mm2, ecx
punpcklwd mm2, mm2
movq mm3, qword [m7] ; // 0x8000
 
psubw mm3, mm2 ; // 0x8000 - iconst
punpckldq mm3, mm2
 
pmulhw mm0, mm3
pmullw mm1, mm3
 
movq mm4, mm1
punpcklwd mm1, mm0
punpckhwd mm4, mm0
paddd mm1, mm4
psrad mm1, 15
packssdw mm1, mm1
movd [edi], mm1
add edi, 4
 
add eax, ebx
cmp eax, [r_end]
jb .l1
emms
 
mov esi, [src]
add esi, [r_size]
sub esi, 32*2
mov edx, [r_buff]
mov ecx, 16
@@:
mov ebx, [esi]
mov [edx], ebx
add esi, 4
add edx, 4
dec ecx
jnz @B
 
sub edi, [dest]
mov eax, edi
ret
endp
 
 
proc m16_stereo stdcall, dest:dword,src:dword,r_buff:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov esi, [src]
mov edi, [dest]
mov ecx, [r_size]
shr ecx,8
@@:
call m16_s_mmx
add edi, 128
add esi, 64
call m16_s_mmx
add edi, 128
add esi, 64
call m16_s_mmx
add edi, 128
add esi, 64
call m16_s_mmx
add edi, 128
add esi, 64
dec ecx
jnz @b
 
mov eax, [r_size]
add eax, eax
ret
endp
 
align 4
proc s8_stereo stdcall, dest:dword,src:dword,r_buff:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
 
mov esi, [src]
mov edi, [dest]
mov ecx, [r_size]
shr ecx, 7
 
movq mm7, [mm80]
movq mm6, [mm_mask]
@@:
call s8_s_mmx
add edi, 64
add esi, 32
call s8_s_mmx
add edi, 64
add esi, 32
call s8_s_mmx
add edi, 64
add esi, 32
call s8_s_mmx
add edi, 64
add esi, 32
dec ecx
jnz @b
 
mov eax, [r_size]
add eax, eax
ret
endp
 
proc m8_stereo stdcall, dest:dword,src:dword,r_buff:dword,\
r_dt:dword, r_size:dword,r_end:dword
 
mov esi, [src]
mov edi, [dest]
mov ecx, [r_size]
shr ecx, 6
 
movq mm7, [mm80]
movq mm6, [mm_mask]
@@:
call m8_s_mmx
add edi, 64
add esi, 16
call m8_s_mmx
add edi, 64
add esi, 16
call m8_s_mmx
add edi, 64
add esi, 16
call m8_s_mmx
add edi, 64
add esi, 16
dec ecx
jnz @b
 
mov eax, [r_size]
add eax, eax
add eax, eax
ret
endp
 
align 4
proc alloc_mix_buff
 
bsf eax, [mix_buff_map]
jnz .find
xor eax, eax
ret
.find:
btr [mix_buff_map], eax
shl eax, 9
add eax, [mix_buff]
ret
endp
 
proc m16_s_mmx
 
movq mm0, [esi]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi], mm0
movq [edi+8], mm1
 
movq mm0, [esi+8]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+16], mm0
movq [edi+24], mm1
 
movq mm0, [esi+16]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+32], mm0
movq [edi+40], mm1
 
movq mm0, [esi+24]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+48], mm0
movq [edi+56], mm1
 
movq mm0, [esi+32]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+64], mm0
movq [edi+72], mm1
 
movq mm0, [esi+40]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+80], mm0
movq [edi+88], mm1
 
 
movq mm0, [esi+48]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+96], mm0
movq [edi+104], mm1
 
movq mm0, [esi+56]
movq mm1, mm0
punpcklwd mm0, mm0
punpckhwd mm1, mm1
movq [edi+112], mm0
movq [edi+120], mm1
 
ret
endp
 
align 4
proc s8_s_mmx
 
movq mm0, [esi]
psubb mm0, mm7
movq mm1, mm0
punpcklbw mm0, mm0
pand mm0, mm6
punpckhbw mm1, mm1
pand mm1, mm6
movq [edi], mm0
movq [edi+8], mm1
 
movq mm0, [esi+8]
psubb mm0, mm7
movq mm1, mm0
punpcklbw mm0, mm0
pand mm0, mm6
punpckhbw mm1, mm1
pand mm1, mm6
movq [edi+16], mm0
movq [edi+24], mm1
 
movq mm0, [esi+16]
psubb mm0, mm7
movq mm1, mm0
punpcklbw mm0, mm0
pand mm0, mm6
punpckhbw mm1, mm1
pand mm1, mm6
movq [edi+32], mm0
movq [edi+40], mm1
 
movq mm0, [esi+24]
psubb mm0, mm7
movq mm1, mm0
punpcklbw mm0, mm0
pand mm0, mm6
punpckhbw mm1, mm1
pand mm1, mm6
movq [edi+48], mm0
movq [edi+56], mm1
 
ret
 
endp
 
align 4
proc m8_s_mmx
 
movq mm0, [esi]
psubb mm0, mm7
movq mm1, mm0
punpcklbw mm0, mm0
pand mm0, mm6
punpckhbw mm1, mm1
pand mm1, mm6
movq mm2, mm0
punpcklwd mm0, mm0
punpckhwd mm2, mm2
 
movq mm3, mm1
punpcklwd mm1, mm1
punpckhwd mm3, mm3
 
movq [edi], mm0
movq [edi+8], mm2
movq [edi+16], mm1
movq [edi+24], mm3
 
movq mm0, [esi+8]
psubb mm0, mm7
movq mm1, mm0
punpcklbw mm0, mm0
pand mm0, mm6
punpckhbw mm1, mm1
pand mm1, mm6
movq mm2, mm0
punpcklwd mm0, mm0
punpckhwd mm2, mm2
 
movq mm3, mm1
punpcklwd mm1, mm1
punpckhwd mm3, mm3
 
movq [edi+32], mm0
movq [edi+40], mm2
movq [edi+48], mm1
movq [edi+56], mm3
 
ret
endp
 
 
align 4
proc mix_2_1 stdcall, output:dword, str0:dword, str1:dword
 
mov edi, [output]
 
stdcall mix_2_1_mmx, edi, [str0],[str1]
add edi, 128
add [str0], 128
add [str1], 128
stdcall mix_2_1_mmx, edi, [str0],[str1]
add edi, 128
add [str0], 128
add [str1], 128
stdcall mix_2_1_mmx, edi, [str0],[str1]
add edi, 128
add [str0], 128
add [str1], 128
stdcall mix_2_1_mmx, edi, [str0],[str1]
 
ret
endp
 
 
align 4
proc mix_3_1 stdcall, output:dword, str0:dword, str1:dword, str2:dword
 
mov edi, [output]
 
stdcall mix_3_1_mmx, edi, [str0],[str1],[str2]
add edi, 128
add [str0], 128
add [str1], 128
add [str2], 128
stdcall mix_3_1_mmx, edi, [str0],[str1],[str2]
add edi, 128
add [str0], 128
add [str1], 128
add [str2], 128
stdcall mix_3_1_mmx, edi, [str0],[str1],[str2]
add edi, 128
add [str0], 128
add [str1], 128
add [str2], 128
stdcall mix_3_1_mmx, edi, [str0],[str1],[str2]
 
ret
endp
 
align 4
proc mix_4_1 stdcall, str0:dword, str1:dword,\
str2:dword, str3:dword
 
local output:DWORD
 
call alloc_mix_buff
and eax, eax
jz .err
mov [output], eax
 
mov edi, eax
 
stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3]
add edi, 128
add [str0], 128
add [str1], 128
add [str2], 128
add [str3], 128
stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3]
add edi, 128
add [str0], 128
add [str1], 128
add [str2], 128
add [str3], 128
stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3]
add edi, 128
add [str0], 128
add [str1], 128
add [str2], 128
add [str3], 128
stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3]
mov eax, [output]
ret
.err:
xor eax, eax
ret
endp
 
 
align 4
proc final_mix stdcall, output:dword, str0:dword, str1:dword,\
str2:dword, str3:dword
 
mov edi, [output]
 
stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3]
add edi, 128
add [str0], 128
add [str1], 128
add [str2], 128
add [str3], 128
stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3]
add edi, 128
add [str0], 128
add [str1], 128
add [str2], 128
add [str3], 128
stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3]
add edi, 128
add [str0], 128
add [str1], 128
add [str2], 128
add [str3], 128
stdcall mix_4_1_mmx, edi, [str0],[str1],[str2],[str3]
 
ret
endp
 
align 4
proc mix_2_1_mmx stdcall, output:dword, str0:dword, str1:dword
 
mov edx, [output]
mov eax, [str0]
mov ecx, [str1]
 
movq mm0, [eax]
paddsw mm0, [ecx]
; psraw mm0, 1
movq [edx], mm0
 
movq mm1, [eax+8]
paddsw mm1,[ecx+8]
; psraw mm1, 1
movq [edx+8], mm1
 
movq mm2, [eax+16]
paddsw mm2, [ecx+16]
; psraw mm2, 1
movq [edx+16], mm2
 
movq mm3, [eax+24]
paddsw mm3, [ecx+24]
; psraw mm3, 1
movq [edx+24], mm3
 
movq mm0, [eax+32]
paddsw mm0, [ecx+32]
; psraw mm0, 1
movq [edx+32], mm0
 
movq mm1, [eax+40]
paddsw mm1, [ecx+40]
; psraw mm1, 1
movq [edx+40], mm1
 
movq mm2, [eax+48]
paddsw mm2, [ecx+48]
; psraw mm2, 1
movq [edx+48], mm2
 
movq mm3, [eax+56]
paddsw mm3, [ecx+56]
; psraw mm3, 1
movq [edx+56], mm3
 
movq mm0, [eax+64]
paddsw mm0, [ecx+64]
; psraw mm0, 1
movq [edx+64], mm0
 
movq mm1, [eax+72]
paddsw mm1, [ecx+72]
; psraw mm1, 1
movq [edx+72], mm1
 
movq mm2, [eax+80]
paddsw mm2, [ecx+80]
; psraw mm2, 1
movq [edx+80], mm2
 
movq mm3, [eax+88]
paddsw mm3, [ecx+88]
; psraw mm3, 1
 
movq [edx+88], mm3
 
movq mm0, [eax+96]
paddsw mm0, [ecx+96]
; psraw mm0, 1
 
movq [edx+96], mm0
 
movq mm1, [eax+104]
paddsw mm1, [ecx+104]
; psraw mm1, 1
 
movq [edx+104], mm1
 
movq mm2, [eax+112]
paddsw mm2, [ecx+112]
; psraw mm2, 1
 
movq [edx+112], mm2
 
movq mm3, [eax+120]
paddsw mm3, [ecx+120]
; psraw mm3, 1
 
movq [edx+120], mm3
 
ret
endp
 
align 4
proc mix_3_1_mmx stdcall, output:dword, str0:dword, str1:dword, str2:dword
 
mov edx, [output]
mov eax, [str0]
mov ebx, [str1]
mov ecx, [str2]
 
movq mm0, [eax]
paddsw mm0, [ebx]
paddsw mm0, [ecx]
movq [edx], mm0
 
movq mm1, [eax+8]
paddsw mm1,[ebx+8]
paddsw mm1,[ecx+8]
movq [edx+8], mm1
 
movq mm2, [eax+16]
paddsw mm2, [ebx+16]
paddsw mm2, [ecx+16]
movq [edx+16], mm2
 
movq mm3, [eax+24]
paddsw mm3, [ebx+24]
paddsw mm3, [ecx+24]
movq [edx+24], mm3
 
movq mm0, [eax+32]
paddsw mm0, [ebx+32]
paddsw mm0, [ecx+32]
movq [edx+32], mm0
 
movq mm1, [eax+40]
paddsw mm1, [ebx+40]
paddsw mm1, [ecx+40]
movq [edx+40], mm1
 
movq mm2, [eax+48]
paddsw mm2, [ebx+48]
paddsw mm2, [ecx+48]
movq [edx+48], mm2
 
movq mm3, [eax+56]
paddsw mm3, [ebx+56]
paddsw mm3, [ecx+56]
movq [edx+56], mm3
 
movq mm0, [eax+64]
paddsw mm0, [ebx+64]
paddsw mm0, [ecx+64]
movq [edx+64], mm0
 
movq mm1, [eax+72]
paddsw mm1, [ebx+72]
paddsw mm1, [ecx+72]
movq [edx+72], mm1
 
movq mm2, [eax+80]
paddsw mm2, [ebx+80]
paddsw mm2, [ecx+80]
movq [edx+80], mm2
 
movq mm3, [eax+88]
paddsw mm3, [ebx+88]
paddsw mm3, [ecx+88]
movq [edx+88], mm3
 
movq mm0, [eax+96]
paddsw mm0, [ebx+96]
paddsw mm0, [ecx+96]
movq [edx+96], mm0
 
movq mm1, [eax+104]
paddsw mm1, [ebx+104]
paddsw mm1, [ecx+104]
movq [edx+104], mm1
 
movq mm2, [eax+112]
paddsw mm2, [ebx+112]
paddsw mm2, [ecx+112]
movq [edx+112], mm2
 
movq mm3, [eax+120]
paddsw mm3, [ebx+120]
paddsw mm3, [ecx+120]
movq [edx+120], mm3
 
ret
endp
 
align 4
proc mix_4_1_mmx stdcall, output:dword, str0:dword, str1:dword,\
str2:dword, str3:dword
 
mov edx, [output]
mov esi, [str0]
mov eax, [str1]
mov ebx, [str2]
mov ecx, [str3]
 
movq mm0, [esi]
movq mm1, [eax]
paddsw mm0, [ebx]
paddsw mm1, [ecx]
paddsw mm0, mm1
movq [edx], mm0
 
movq mm2, [esi+8]
movq mm3, [eax+8]
paddsw mm2, [ebx+8]
paddsw mm3, [ecx+8]
paddsw mm2, mm3
movq [edx+8], mm2
 
movq mm0, [esi+16]
movq mm1, [eax+16]
paddsw mm0, [ebx+16]
paddsw mm1, [ecx+16]
paddsw mm0, mm1
movq [edx+16], mm0
 
movq mm2, [esi+24]
movq mm3, [eax+24]
paddsw mm2, [ebx+24]
paddsw mm3, [ecx+24]
paddsw mm2, mm3
movq [edx+24], mm2
 
movq mm0, [esi+32]
movq mm1, [eax+32]
paddsw mm0, [ebx+32]
paddsw mm1, [ecx+32]
paddsw mm0, mm1
movq [edx+32], mm0
 
movq mm2, [esi+40]
movq mm3, [eax+40]
paddsw mm2, [ebx+40]
paddsw mm3, [ecx+40]
paddsw mm2, mm3
movq [edx+40], mm2
 
movq mm0, [esi+48]
movq mm1, [eax+48]
paddsw mm0, [ebx+48]
paddsw mm1, [ecx+48]
paddsw mm0, mm1
movq [edx+48], mm0
 
movq mm2, [esi+56]
movq mm3, [eax+56]
paddsw mm2, [ebx+56]
paddsw mm3, [ecx+56]
paddsw mm2, mm3
movq [edx+56], mm2
 
movq mm0, [esi+64]
movq mm1, [eax+64]
paddsw mm0, [ebx+64]
paddsw mm1, [ecx+64]
paddsw mm0, mm1
movq [edx+64], mm0
 
movq mm2, [esi+72]
movq mm3, [eax+72]
paddsw mm2, [ebx+72]
paddsw mm3, [ecx+72]
paddsw mm2, mm3
movq [edx+72], mm2
 
movq mm2, [esi+80]
movq mm3, [eax+80]
paddsw mm2, [ebx+80]
paddsw mm3, [ecx+80]
paddsw mm2, mm3
movq [edx+80], mm2
 
movq mm2, [esi+88]
movq mm3, [eax+88]
paddsw mm2, [ebx+88]
paddsw mm3, [ecx+88]
paddsw mm2, mm3
movq [edx+88], mm2
 
movq mm2, [esi+96]
movq mm3, [eax+96]
paddsw mm2, [ebx+96]
paddsw mm3, [ecx+96]
paddsw mm2, mm3
movq [edx+96], mm2
 
movq mm2, [esi+104]
movq mm3, [eax+104]
paddsw mm2, [ebx+104]
paddsw mm3, [ecx+104]
paddsw mm2, mm3
movq [edx+104], mm2
 
movq mm2, [esi+112]
movq mm3, [eax+112]
paddsw mm2, [ebx+112]
paddsw mm3, [ecx+112]
paddsw mm2, mm3
movq [edx+112], mm2
 
movq mm2, [esi+120]
movq mm3, [eax+120]
paddsw mm2, [ebx+120]
paddsw mm3, [ecx+120]
paddsw mm2, mm3
movq [edx+120], mm2
 
ret
endp
 
align 4
proc copy_mem stdcall, output:dword, input:dword
 
mov edi, [output]
mov esi, [input]
mov ecx, 0x80
.l1:
mov eax, [esi]
mov [edi], eax
add esi, 4
add edi, 4
loop .l1
 
ret
endp
 
proc memcpy
@@:
mov eax, [esi]
mov [edi], eax
add esi, 4
add edi, 4
dec ecx
jnz @B
ret
endp
 
 
 
/kernel/tags/kolibri0.6.3.0/drivers/infinity.asm
0,0 → 1,762
;
; This file is part of the Infinity sound library.
; (C) copyright Serge 2006
; email: infinity_sound@mail.ru
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
 
format MS COFF
 
include 'proc32.inc'
include 'main.inc'
 
DEBUG equ 1
 
EVENT_NOTIFY equ 0x00000200
 
OS_BASE equ 0; 0x80400000
new_app_base equ 0x60400000; 0x01000000
PROC_BASE equ OS_BASE+0x0080000
 
public START
public STOP
public service_proc
 
extrn AttachIntHandler
extrn SysMsgBoardStr
extrn PciApi
extrn PciRead32
extrn PciRead8
extrn PciWrite8
extrn AllocKernelSpace
extrn MapPage
extrn RegService
extrn KernelAlloc
extrn KernelFree
extrn GetPgAddr
extrn GetCurrentTask
extrn GetService
extrn ServiceHandler
extrn FpuSave
extrn FpuRestore
 
SND_CREATE_BUFF equ 2
SND_PLAY equ 3
SND_STOP equ 4
SND_SETBUFF equ 5
SND_DESTROY_BUFF equ 6
 
DEV_PLAY equ 1
DEV_STOP equ 2
DEV_CALLBACK equ 3
 
struc IOCTL
{ .handle dd ?
.io_code dd ?
.input dd ?
.inp_size dd ?
.output dd ?
.out_size dd ?
}
 
virtual at 0
IOCTL IOCTL
end virtual
 
section '.flat' code readable align 16
 
START:
stdcall GetService, szSound
test eax, eax
jz .fail
mov [hSound], eax
 
stdcall KernelAlloc, 16*512
test eax, eax
jz .out_of_mem
mov [mix_buff], eax
 
mov edi, stream_list
mov ecx, 17
xor eax, eax
cld
rep stosd
 
mov edi, stream
mov ecx, 4*STREAM_SIZE
rep stosd
mov [stream_count],0
 
stdcall set_handler, [hSound], new_mix
stdcall RegService, szInfinity, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
xor eax, eax
ret
 
.out_of_mem:
if DEBUG
mov esi, msgMem
call SysMsgBoardStr
end if
xor eax, eax
STOP:
ret
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edi, [ioctl]
mov eax, [edi+io_code]
 
cmp eax, SND_CREATE_BUFF
jne @F
mov ebx, [edi+input]
stdcall CreateBuffer,[ebx]
ret
@@:
cmp eax, SND_PLAY
jne @F
 
mov ebx, [edi+input]
stdcall play_buffer, [ebx]
ret
@@:
cmp eax, SND_STOP
jne @F
 
; if DEBUG
; mov esi, msgStop
; call [SysMsgBoardStr]
; end if
 
mov ebx, [edi+input]
stdcall stop_buffer, [ebx]
ret
@@:
cmp eax, SND_SETBUFF
jne @F
 
mov ebx, [edi+input]
mov eax, [ebx+4]
add eax, new_app_base
stdcall set_buffer, [ebx],eax,[ebx+8],[ebx+12]
ret
@@:
cmp eax, SND_DESTROY_BUFF
jne @F
 
mov ebx, [edi+input]
stdcall DestroyBuffer, [ebx]
ret
@@:
xor eax, eax
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
TASK_COUNT equ 0x0003004
CURRENT_TASK equ 0x0003000
 
align 8
proc CreateBuffer stdcall, format:dword
locals
str dd ?
endl
 
call alloc_stream
and eax, eax
jz .fail
mov [str], eax
mov edi, eax
 
mov edx, [stream_count]
mov [stream_list+edx*4], eax
inc [stream_count]
 
mov [edi+STREAM.magic], 'WAVE'
mov [edi+STREAM.size], STREAM_SIZE
 
stdcall KernelAlloc, 180*1024
 
mov edi, [str]
mov [edi+STREAM.base], eax
mov [edi+STREAM.curr_seg], eax
mov [edi+STREAM.notify_off1], eax
add eax, 0x8000
mov [edi+STREAM.notify_off2], eax
add eax, 0x7FFF
mov [edi+STREAM.limit], eax
 
inc eax
 
mov [edi+STREAM.work_buff], eax
mov [edi+STREAM.work_read], eax
mov [edi+STREAM.work_write], eax
mov [edi+STREAM.work_count], 0
add eax, 0x10000
mov [edi+STREAM.work_top], eax
add eax, 1024*32
mov [edi+STREAM.r_buff], eax
 
mov ebx, [CURRENT_TASK]
shl ebx, 5
mov eax, [0x3000+ebx+4]
 
mov [edi+STREAM.notify_task], eax
 
mov eax, [format]
mov [edi+STREAM.format], eax
mov [edi+STREAM.flags], SND_STOP
 
xor ebx, ebx
cmp eax, 19
jb @f
mov ebx, 0x80808080
@@:
mov [edi+STREAM.r_silence], ebx
 
shl eax, 4
mov ebx, [resampler_params+eax]
mov ecx, [resampler_params+eax+4]
mov edx, [resampler_params+eax+8]
 
mov [edi+STREAM.r_size],ebx
mov [edi+STREAM.r_end], ecx
mov [edi+STREAM.r_dt], edx
 
mov ebx, [resampler_params+eax+12]
mov [edi+STREAM.resample], ebx
 
mov edi, [edi+STREAM.base]
mov ecx, 180*1024/4
xor eax, eax
rep stosd
 
mov eax, [str]
ret
 
.fail:
xor eax, eax
ret
endp
 
align 4
pid_to_slot:
 
push ebx
push ecx
mov ebx,[TASK_COUNT]
shl ebx,5
mov ecx,2*32
.loop:
cmp byte [CURRENT_TASK+ecx+0xa],9
jz .endloop ;skip empty slots
cmp [CURRENT_TASK+ecx+0x4],eax ;check PID
jz .pid_found
.endloop:
add ecx,32
cmp ecx,ebx
jle .loop
pop ecx
pop ebx
xor eax,eax
ret
 
.pid_found:
shr ecx,5
mov eax,ecx
pop ecx
pop ebx
ret
 
align 4
proc DestroyBuffer stdcall, str:dword
 
mov esi, [str]
 
cmp [esi+STREAM.magic], 'WAVE'
jne .fail
 
cmp [esi+STREAM.size], STREAM_SIZE
jne .fail
 
stdcall KernelFree, [esi+STREAM.base]
 
mov eax, [str]
call free_stream
 
mov edi, [str]
mov ecx, STREAM_SIZE/4
xor eax, eax
cld
rep stosd
 
mov eax, [str]
mov esi, stream_list
mov ecx, 16
@@:
cmp [esi], eax
je .remove
add esi, 4
dec ecx
jnz @B
xor eax, eax
inc eax
ret
.remove:
mov edi, esi
add esi, 4
cld
rep movsd
dec [stream_count]
xor eax, eax
inc eax
ret
.fail:
xor eax, eax
ret
endp
 
align 4
proc play_buffer stdcall, str:dword
 
mov ebx, [str]
 
cmp [ebx+STREAM.magic], 'WAVE'
jne .fail
 
cmp [ebx+STREAM.size], STREAM_SIZE
jne .fail
 
mov [ebx+STREAM.flags], SND_PLAY
 
mov eax,[ebx+STREAM.work_buff]
mov [ebx+STREAM.work_read], eax
mov [ebx+STREAM.work_write], eax
mov [ebx+STREAM.work_count], 0
 
mov eax, [ebx+STREAM.base]
mov [ebx+STREAM.curr_seg], eax
 
mov esi, [ebx+STREAM.curr_seg]
mov edi, [ebx+STREAM.work_write]
mov edx, [ebx+STREAM.r_buff]
 
mov ecx, 32
mov eax, [ebx+STREAM.r_silence]
@@:
mov [edx], eax
add edx, 4
dec ecx
jnz @B
 
mov edx, [ebx+STREAM.r_buff]
 
stdcall [ebx+STREAM.resample], edi, esi, edx,\
[ebx+STREAM.r_dt],[ebx+STREAM.r_size],[ebx+STREAM.r_end]
 
mov ebx, [str]
 
add [ebx+STREAM.work_count], eax;
add [ebx+STREAM.work_write], eax;
 
mov eax, [ebx+STREAM.r_size]
add [ebx+STREAM.curr_seg], eax
 
; if DEBUG
; mov esi, msgPlay
; call [SysMsgBoardStr]
; end if
 
stdcall dev_play, [hSound]
 
xor eax, eax
inc eax
ret
 
.fail:
xor eax, eax
ret
 
endp
 
 
align 4
proc stop_buffer stdcall, str:dword
 
mov edi, [str]
 
cmp [edi+STREAM.magic], 'WAVE'
jne .fail
 
cmp [edi+STREAM.size], STREAM_SIZE
jne .fail
 
mov [edi+STREAM.flags], SND_STOP
 
; stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0
 
xor eax, eax
inc eax
ret
 
.fail:
xor eax, eax
ret
 
endp
 
align 4
proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword
 
mov edx, [str]
test edx, edx
jz .fail
 
cmp [edx+STREAM.magic], 'WAVE'
jne .fail
 
cmp [edx+STREAM.size], STREAM_SIZE
jne .fail
 
mov esi,[src]
test esi, esi
jz .fail
 
cmp esi, new_app_base
jb .fail
 
mov ecx, [size]
test ecx, ecx
jz .fail
 
mov eax, [edx+STREAM.base]
add eax, [offs]
 
cmp eax, [edx+STREAM.base]
jb .fail
 
mov edi, eax
add eax, ecx
sub eax, 1
 
cmp eax, [edx+STREAM.limit]
ja .fail
 
shr ecx, 2
cld
rep movsd
 
xor eax, eax
inc eax
ret
.fail:
xor eax, eax
ret
endp
 
align 4
proc alloc_stream
 
mov esi, stream_map
 
pushf
cli
 
bsf eax, [esi]
jnz .find
popf
xor eax, eax
ret
 
.find: btr [esi], eax
popf
mov ebx, STREAM_SIZE
mul ebx
add eax, stream
ret
endp
 
align 4
proc free_stream
sub eax, stream
mov ebx, STREAM_SIZE
xor edx, edx
div ebx
 
and edx, edx
jnz .err
 
bts [stream_map], eax
 
ret
.err:
xor eax, eax
ret
endp
 
align 4
proc check_stream
 
xor edx, edx
mov ecx, [play_count]
.l1:
mov esi, [play_list+edx]
 
mov eax, [esi+STR.curr_seg]
cmp eax, [esi+STR.limit]
jb .next
 
.m1: mov eax,[esi+STR.base]
mov [esi+STR.curr_seg], eax
.next:
add edx, 4
loop .l1
ret
endp
 
 
align 4
proc prepare_playlist
 
.restart:
xor ebx, ebx
xor edx, edx
mov [play_count], 0
mov ecx, [stream_count]
jcxz .exit
.l1:
mov esi, [stream_list+ebx]
test esi, esi
jz .next
 
cmp [esi+STREAM.magic], 'WAVE'
jne .next
 
cmp [esi+STREAM.size], STREAM_SIZE
jne .next
 
mov eax,[esi+STREAM.notify_task]
cmp eax, -1
je .fail
 
call pid_to_slot
test eax, eax
jz .fail
 
cmp [esi+STREAM.flags], SND_PLAY;
jne .next
cmp [esi+STREAM.work_count], 16384
jb .next
 
mov [play_list+edx], esi
inc [play_count]
add edx, 4
.next:
add ebx, 4
loop .l1
.exit:
ret
 
.fail:
stdcall DestroyBuffer, esi
jmp .restart
endp
 
align 4
proc prepare_updatelist
 
xor ebx, ebx
xor edx, edx
mov [play_count], 0
mov ecx, [stream_count]
jcxz .exit
.l1:
mov eax, [stream_list+ebx]
test eax, eax
jz .next
cmp [eax+STREAM.flags], SND_PLAY
jne .next
 
mov [play_list+edx], eax
inc [play_count]
add edx, 4
.next:
add ebx, 4
loop .l1
.exit:
ret
endp
 
align 4
proc set_handler stdcall, hsrv:dword, handler_proc:dword
locals
handler dd ?
io_code dd ?
input dd ?
inp_size dd ?
output dd ?
out_size dd ?
val dd ?
endl
 
mov eax, [hsrv]
lea ecx, [handler_proc]
xor ebx, ebx
 
mov [handler], eax
mov [io_code], DEV_CALLBACK
mov [input], ecx
mov [inp_size], 4
mov [output], ebx
mov [out_size], 0
 
lea eax, [handler]
stdcall ServiceHandler, eax
ret
endp
 
align 4
proc dev_play stdcall, hsrv:dword
locals
handle dd ?
io_code dd ?
input dd ?
inp_size dd ?
output dd ?
out_size dd ?
val dd ?
endl
 
mov eax, [hsrv]
xor ebx, ebx
 
mov [handle], eax
mov [io_code], DEV_PLAY
mov [input], ebx
mov [inp_size], ebx
mov [output], ebx
mov [out_size], ebx
 
lea eax, [handle]
stdcall ServiceHandler, eax
ret
endp
 
include 'mixer.asm'
 
align 16
resampler_params:
;r_size r_end r_dt resampler_func
dd 0,0,0,0 ; 0 PCM_ALL
dd 16384, 0, 0, copy_stream ; 1 PCM_2_16_48
dd 16384, 0, 0, m16_stereo ; 2 PCM_1_16_48
 
dd 16384, 0x08000000, 30109, resample_2 ; 3 PCM_2_16_44
dd 8192, 0x08000000, 30109, resample_1 ; 4 PCM_1_16_44
 
dd 16384, 0x08000000, 21846, resample_2 ; 5 PCM_2_16_32
dd 8192, 0x08000000, 21846, resample_1 ; 6 PCM_1_16_32
 
dd 16384, 0x08000000, 16384, resample_2 ; 7 PCM_2_16_24
dd 8192, 0x08000000, 16384, resample_1 ; 8 PCM_1_16_24
 
dd 8192, 0x04000000, 15052, resample_2 ; 9 PCM_2_16_22
dd 4096, 0x04000000, 15052, resample_1 ;10 PCM_1_16_22
 
dd 8192, 0x04000000, 10923, resample_2 ;11 PCM_2_16_16
dd 4096, 0x04000000, 10923, resample_1 ;12 PCM_1_16_16
 
dd 8192, 0x04000000, 8192, resample_2 ;13 PCM_2_16_12
dd 4096, 0x04000000, 8192, resample_1 ;14 PCM_1_16_12
 
dd 4096, 0x02000000, 7527, resample_2 ;15 PCM_2_16_11
dd 2048, 0x02000000, 7527, resample_1 ;16 PCM_1_16_11
 
dd 4096, 0x02000000, 5462, resample_2 ;17 PCM_2_16_8
dd 2048, 0x02000000, 5462, resample_1 ;18 PCM_1_16_8
 
dd 16384, 0, 0, s8_stereo ;19 PCM_2_8_48
dd 8192, 0, 0, m8_stereo ;20 PCM_1_8_48
 
dd 8192, 0x08000000, 30109, resample_28 ;21 PCM_2_8_44
dd 4096, 0x08000000, 30109, resample_18 ;22 PCM_1_8_44
 
dd 8192, 0x08000000, 21846, resample_28 ;23 PCM_2_8_32
dd 4096, 0x08000000, 21846, resample_18 ;24 PCM_1_8_32
 
dd 8192, 0x08000000, 16384, resample_28 ;25 PCM_2_8_24
dd 4096, 0x08000000, 16384, resample_18 ;26 PCM_1_8_24
 
dd 4096, 0x04000000, 15052, resample_28 ;27 PCM_2_8_22
dd 2048, 0x04000000, 15052, resample_18 ;28 PCM_1_8_22
 
dd 4096, 0x04000000, 10923, resample_28 ;29 PCM_2_8_16
dd 2048, 0x04000000, 10923, resample_18 ;30 PCM_1_8_16
 
dd 4096, 0x04000000, 8192, resample_28 ;31 PCM_2_8_12
dd 2048, 0x04000000, 8192, resample_18 ;32 PCM_1_8_12
 
dd 2048, 0x02000000, 7527, resample_28 ;33 PCM_2_8_11
dd 1024, 0x02000000, 7527, resample_18 ;34 PCM_1_8_11
 
dd 2048, 0x02000000, 5462, resample_28 ;35 PCM_2_8_8
dd 1024, 0x02000000, 5462, resample_18 ;36 PCM_1_8_8
 
m7 dw 0x8000,0x8000,0x8000,0x8000
mm80 dq 0x8080808080808080
mm_mask dq 0xFF00FF00FF00FF00
 
stream_map dd 0xFFFF ; 16
 
szInfinity db 'INFINITY',0
szSound db 'SOUND',0
 
if DEBUG
msgFail db 'Sound service not found',13,10,0
msgPlay db 'Play buffer',13,10,0
msgStop db 'Stop',13,10,0
msgUser db 'User callback',13,10,0
msgMem db 'Not enough memory',13,10,0
end if
 
section '.data' data readable writable align 16
 
stream rb STREAM_SIZE*16
 
play_list rd 16
mix_input rd 16
 
stream_list rd 17
play_count rd 1
stream_count rd 1
hSound rd 1
mix_buff rd 1
mix_buff_map rd 1
 
/kernel/tags/kolibri0.6.3.0/drivers/unisound.asm
0,0 → 1,1383
 
format MS COFF
 
 
include 'proc32.inc'
 
DEBUG equ 1
 
REMAP_IRQ equ 0
 
;irq 0,1,2,8,12,13 íåäîñòóïíû
; FEDCBA9876543210
VALID_IRQ equ 1100111011111000b
ATTCH_IRQ equ 0000111010101000b
 
IRQ_LINE equ 0
 
CPU_FREQ equ 2600d
 
BIT0 EQU 0x00000001
BIT1 EQU 0x00000002
BIT2 EQU 0x00000004
BIT3 EQU 0x00000008
BIT4 EQU 0x00000010
BIT5 EQU 0x00000020
BIT6 EQU 0x00000040
BIT7 EQU 0x00000080
BIT8 EQU 0x00000100
BIT9 EQU 0x00000200
BIT10 EQU 0x00000400
BIT11 EQU 0x00000800
BIT12 EQU 0x00001000
BIT13 EQU 0x00002000
BIT14 EQU 0x00004000
BIT15 EQU 0x00008000
BIT16 EQU 0x00010000
BIT17 EQU 0x00020000
BIT18 EQU 0x00040000
BIT19 EQU 0x00080000
BIT20 EQU 0x00100000
BIT21 EQU 0x00200000
BIT22 EQU 0x00400000
BIT23 EQU 0x00800000
BIT24 EQU 0x00100000
BIT25 EQU 0x02000000
BIT26 EQU 0x04000000
BIT27 EQU 0x08000000
BIT28 EQU 0x10000000
BIT29 EQU 0x20000000
BIT30 EQU 0x40000000
BIT31 EQU 0x80000000
 
VID_INTEL equ 0x8086
VID_NVIDIA equ 0x10DE
 
CTRL_ICH equ 0x2415
CTRL_ICH0 equ 0x2425
CTRL_ICH2 equ 0x2435
CTRL_ICH3 equ 0x2445
CTRL_ICH4 equ 0x24C5
CTRL_ICH5 equ 0x24D5
CTRL_ICH6 equ 0x266E
CTRL_ICH7 equ 0x27DE
 
CTRL_NFORCE equ 0x01B1
CTRL_NFORCE2 equ 0x006A
CTRL_NFORCE3 equ 0x00DA
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 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 0; 0x80400000
new_app_base equ 0x60400000; 0x01000000
PROC_BASE equ OS_BASE+0x0080000
 
public START
public STOP
public service_proc
 
extrn AttachIntHandler
extrn SysMsgBoardStr
extrn PciApi
extrn PciRead32
extrn PciRead8
extrn PciWrite8
extrn AllocKernelSpace
extrn MapPage
extrn RegService
extrn KernelAlloc
extrn GetPgAddr
extrn GetCurrentTask
 
section '.flat' code readable align 16
 
START:
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
call detect_controller
test eax, eax
jz .fail
 
if DEBUG
mov esi,[ctrl.vendor_ids]
call SysMsgBoardStr
mov esi, [ctrl.ctrl_ids]
call SysMsgBoardStr
 
end if
 
call init_controller
test eax, eax
jz .fail
 
if DEBUG
mov esi, msgInitCodec
call SysMsgBoardStr
end if
 
call init_codec
test eax, eax
jz .fail
 
if DEBUG
mov esi, [codec.ac_vendor_ids]
call SysMsgBoardStr
 
mov esi, [codec.chip_ids]
call SysMsgBoardStr
end if
 
call reset_controller
call setup_codec
 
mov esi, msgPrimBuff
call SysMsgBoardStr
 
call create_primary_buff
 
; if REMAP_IRQ
 
; call get_LPC_bus
; cmp eax, -1
; jz .fail
 
; mov [lpc_bus], 0 ;eax
; call remap_irq
; end if
 
mov eax, VALID_IRQ
mov ebx, [ctrl.int_line]
mov esi, msgInvIRQ
bt eax, ebx
jnc .fail
mov eax, ATTCH_IRQ
mov esi, msgAttchIRQ
bt eax, ebx
jnc .fail
 
stdcall AttachIntHandler, ebx, ac97_irq
stdcall RegService, sz_sound_srv, service_proc
ret
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
xor eax, eax
STOP:
ret
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edi, [ioctl]
mov eax, [edi+io_code]
cmp eax, DEV_PLAY
jne @F
if DEBUG
mov esi, msgPlay
call SysMsgBoardStr
end if
call play
ret
@@:
cmp eax, DEV_STOP
jne @F
if DEBUG
mov esi, msgStop
call SysMsgBoardStr
end if
call stop
ret
@@:
cmp eax, DEV_CALLBACK
jne @F
mov ebx, [edi+input]
stdcall set_callback, [ebx]
ret
@@:
cmp eax, DEV_SET_MASTERVOL
jne @F
mov ebx, [edi+input]
stdcall set_master_vol, [ebx]
ret
@@:
cmp eax, DEV_GET_MASTERVOL
jne @F
mov ebx, [edi+output]
test ebx, ebx
jz .fail
 
stdcall get_master_vol, ebx
ret
@@:
cmp eax, DEV_GET_INFO
jne @F
mov ebx, [edi+output]
stdcall get_dev_info, ebx
ret
@@:
.fail:
xor eax, eax
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
 
align 4
proc remap_irq ;for Intel chipsets ONLY !!!
mov eax, VALID_IRQ
bt eax, IRQ_LINE
jnc .exit
 
mov edx, 0x4D0
in ax,dx
bts ax, IRQ_LINE
out dx, aX
 
stdcall PciWrite8, dword 0, dword 0xF8, dword 0x61, dword IRQ_LINE
mov [ctrl.int_line], IRQ_LINE
 
.exit:
ret
endp
 
align 4
proc ac97_irq
 
; if DEBUG
; mov esi, msgIRQ
; call SysMsgBoardStr
; end if
 
mov edx, PCM_OUT_CR_REG
mov al, 0x14
call [ctrl.ctrl_write8]
 
mov ax, 0x1c
mov edx, PCM_OUT_SR_REG
call [ctrl.ctrl_write16]
 
mov edx, PCM_OUT_CIV_REG
call [ctrl.ctrl_read8]
 
and eax, 0x1F
cmp eax, [civ_val]
je .skip
 
mov [civ_val], eax
dec eax
and eax, 0x1F
mov [ctrl.lvi_reg], eax
 
mov edx, PCM_OUT_LVI_REG
call [ctrl.ctrl_write8]
 
mov edx, PCM_OUT_CR_REG
mov ax, 0x1D
call [ctrl.ctrl_write8]
 
mov eax, [civ_val]
add eax, 2
and eax, 31
mov ebx, dword [buff_list+eax*4]
 
cmp [ctrl.user_callback], 0
je @f
 
stdcall [ctrl.user_callback], ebx
@@:
ret
 
.skip:
mov edx, PCM_OUT_CR_REG
mov ax, 0x1D
call [ctrl.ctrl_write8]
ret
endp
 
align 4
proc create_primary_buff
 
stdcall KernelAlloc, 0x10000
mov [ctrl.buffer], eax
 
mov edi, eax
mov ecx, 0x10000/4
xor eax, eax
cld
rep stosd
 
stdcall GetPgAddr, [ctrl.buffer]
 
mov ebx, 0xC0002000
mov ecx, 4
mov edi, pcmout_bdl
@@:
mov [edi], eax
mov [edi+4], ebx
 
mov [edi+32], eax
mov [edi+4+32], ebx
 
mov [edi+64], eax
mov [edi+4+64], ebx
 
mov [edi+96], eax
mov [edi+4+96], ebx
 
mov [edi+128], eax
mov [edi+4+128], ebx
 
mov [edi+160], eax
mov [edi+4+160], ebx
 
mov [edi+192], eax
mov [edi+4+192], ebx
 
mov [edi+224], eax
mov [edi+4+224], ebx
 
add eax, 0x4000
add edi, 8
loop @B
 
mov edi, buff_list
mov eax, [ctrl.buffer]
mov ecx, 4
@@:
mov [edi], eax
mov [edi+16], eax
mov [edi+32], eax
mov [edi+48], eax
mov [edi+64], eax
mov [edi+80], eax
mov [edi+96], eax
mov [edi+112], eax
 
add eax, 0x4000
add edi, 4
loop @B
 
mov ecx, pcmout_bdl
stdcall GetPgAddr, ecx
and ecx, 0xFFF
add eax, ecx
 
mov edx, PCM_OUT_BDL
call [ctrl.ctrl_write32]
 
mov eax, 16
mov [ctrl.lvi_reg], eax
mov edx, PCM_OUT_LVI_REG
call [ctrl.ctrl_write8]
 
ret
endp
 
align 4
proc detect_controller
locals
last_bus dd ?
bus dd ?
devfn dd ?
endl
 
xor eax, eax
mov [bus], eax
inc eax
call PciApi
cmp eax, -1
je .err
 
mov [last_bus], eax
 
.next_bus:
and [devfn], 0
.next_dev:
stdcall PciRead32, [bus], [devfn], dword 0
test eax, eax
jz .next
cmp eax, -1
je .next
 
mov edi, devices
@@:
mov ebx, [edi]
test ebx, ebx
jz .next
 
cmp eax, ebx
je .found
add edi, 12
jmp @B
 
.next: inc [devfn]
cmp [devfn], 256
jb .next_dev
mov eax, [bus]
inc eax
mov [bus], eax
cmp eax, [last_bus]
jna .next_bus
xor eax, eax
ret
.found:
mov ebx, [bus]
mov [ctrl.bus], ebx
 
mov ecx, [devfn]
mov [ctrl.devfn], ecx
 
mov edx, eax
and edx, 0xFFFF
mov [ctrl.vendor], edx
shr eax, 16
mov [ctrl.dev_id], eax
 
mov ebx, [edi+4]
mov [ctrl.ctrl_ids], ebx
mov esi, [edi+8]
mov [ctrl.ctrl_setup], esi
 
cmp ebx, VID_INTEL
jne @F
mov [ctrl.vendor_ids], msg_Intel
ret
@@:
cmp ebx, VID_NVIDIA
jne @F
mov [ctrl.vendor_ids], msg_NVidia
@@:
mov [ctrl.vendor_ids], 0 ;something wrong ?
ret
.err:
xor eax, eax
ret
endp
 
align 4
proc get_LPC_bus ;for Intel chipsets ONLY !!!
locals
last_bus dd ?
bus dd ?
endl
 
xor eax, eax
mov [bus], eax
inc eax
call [PciApi]
cmp eax, -1
je .err
 
mov [last_bus], eax
.next_bus:
stdcall PciRead32, [bus], dword 0xF8, dword 0
test eax, eax
jz .next
cmp eax, -1
je .next
 
cmp eax, 0x24D08086
je .found
.next:
mov eax, [bus]
inc eax
cmp eax, [last_bus]
mov [bus], eax
jna .next_bus
.err:
xor eax, eax
dec eax
ret
.found:
mov eax, [bus]
ret
endp
 
align 4
proc init_controller
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
mov ebx, eax
and eax, 0xFFFF
mov [ctrl.pci_cmd], eax
shr ebx, 16
mov [ctrl.pci_stat], ebx
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
and eax,0xFFFE
mov [ctrl.codec_io_base], eax
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14
and eax, 0xFFC0
mov [ctrl.ctrl_io_base], eax
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18
mov [ctrl.codec_mem_base], eax
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C
mov [ctrl.ctrl_mem_base], eax
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
and eax, 0xFF
mov [ctrl.int_line], eax
 
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41
and eax, 0xFF
mov [ctrl.cfg_reg], eax
 
call [ctrl.ctrl_setup]
xor eax, eax
inc eax
ret
endp
 
align 4
proc set_ICH
mov [ctrl.codec_read16], codec_io_r16 ;virtual
mov [ctrl.codec_write16], codec_io_w16 ;virtual
 
mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual
mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual
mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual
 
mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual
mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual
mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual
ret
endp
 
PG_SW equ 0x003
PG_NOCACHE equ 0x018
 
align 4
proc set_ICH4
stdcall AllocKernelSpace, dword 0x2000
mov edi, eax
stdcall MapPage, edi,[ctrl.codec_mem_base],PG_SW+PG_NOCACHE
mov [ctrl.codec_mem_base], edi
add edi, 0x1000
stdcall MapPage, edi, [ctrl.ctrl_mem_base],PG_SW+PG_NOCACHE
mov [ctrl.ctrl_mem_base], edi
 
mov [ctrl.codec_read16], codec_mem_r16 ;virtual
mov [ctrl.codec_write16], codec_mem_w16 ;virtual
 
mov [ctrl.ctrl_read8 ], ctrl_mem_r8 ;virtual
mov [ctrl.ctrl_read16], ctrl_mem_r16 ;virtual
mov [ctrl.ctrl_read32], ctrl_mem_r32 ;virtual
 
mov [ctrl.ctrl_write8 ], ctrl_mem_w8 ;virtual
mov [ctrl.ctrl_write16], ctrl_mem_w16 ;virtual
mov [ctrl.ctrl_write32], ctrl_mem_w32 ;virtual
ret
endp
 
align 4
proc reset_controller
 
xor eax, eax
mov edx, PCM_IN_CR_REG
call [ctrl.ctrl_write8]
 
mov edx, PCM_OUT_CR_REG
call [ctrl.ctrl_write8]
 
mov edx, MC_IN_CR_REG
call [ctrl.ctrl_write8]
 
mov eax, RR
mov edx, PCM_IN_CR_REG
call [ctrl.ctrl_write8]
 
mov edx, PCM_OUT_CR_REG
call [ctrl.ctrl_write8]
 
mov edx, MC_IN_CR_REG
call [ctrl.ctrl_write8]
 
ret
endp
 
align 4
proc init_codec
locals
counter dd ?
endl
 
call reset_codec
and eax, eax
jz .err
 
xor edx, edx ;ac_reg_0
call [ctrl.codec_write16]
 
xor eax, eax
mov edx, CODEC_REG_POWERDOWN
call [ctrl.codec_write16]
 
mov [counter], 200 ; total 200*5 ms = 1s
.wait:
mov edx, CODEC_REG_POWERDOWN
call [ctrl.codec_read16]
and eax, 0x0F
cmp eax, 0x0F
jz .ready
 
mov eax, 5000 ; wait 5 ms
call StallExec
sub [counter] , 1
jnz .wait
.err:
xor eax, eax ; timeout error
ret
.ready:
call detect_codec
 
xor eax, eax
inc eax
ret
endp
 
align 4
proc reset_codec
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
 
test eax, 0x02
jz .cold
 
call warm_reset
jnc .ok
.cold:
call cold_reset
jnc .ok
 
if DEBUG
mov esi, msgCFail
call SysMsgBoardStr
end if
xor eax, eax ; timeout error
ret
.ok:
if DEBUG
mov esi, msgResetOk
call SysMsgBoardStr
end if
 
xor eax, eax
inc eax
ret
endp
 
align 4
proc warm_reset
locals
counter dd ?
endl
 
mov eax, 0x06
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
 
if DEBUG
mov esi, msgWarm
call SysMsgBoardStr
end if
 
mov [counter], 10 ; total 10*100 ms = 1s
.wait:
mov eax, 100000 ; wait 100 ms
call StallExec
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
test eax, 4
jz .ok
sub [counter], 1
jnz .wait
 
if DEBUG
mov esi, msgWRFail
call SysMsgBoardStr
end if
 
stc
ret
.ok:
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
and eax, CTRL_ST_CREADY
jz .fail
clc
ret
.fail:
stc
ret
endp
 
align 4
proc cold_reset
locals
counter dd ?
endl
 
xor eax, eax
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
 
if DEBUG
mov esi, msgCold
call SysMsgBoardStr
end if
 
mov eax, 1000000 ; wait 1 s
call StallExec
 
mov eax, 2
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
 
mov [counter], 10 ; total 10*100 ms = 1s
.wait:
mov eax, 100000 ; wait 100 ms
call StallExec
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
test eax, 4
jz .ok
sub [counter], 1
jnz .wait
 
if DEBUG
mov esi, msgCRFail
call SysMsgBoardStr
end if
stc
ret
.ok:
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
and eax, CTRL_ST_CREADY
jz .fail
clc
ret
.fail:
stc
ret
endp
 
align 4
proc play
 
mov eax, 16
mov [ctrl.lvi_reg], eax
mov edx, PCM_OUT_LVI_REG
call [ctrl.ctrl_write8]
 
mov edx, PCM_OUT_CR_REG
mov ax, 0x1D
call [ctrl.ctrl_write8]
ret
endp
 
align 4
proc stop
mov edx, PCM_OUT_CR_REG
mov ax, 0x14
call [ctrl.ctrl_write8]
 
mov eax, 16
mov [ctrl.lvi_reg], eax
mov edx, PCM_OUT_LVI_REG
call [ctrl.ctrl_write8]
 
ret
endp
 
align 4
proc get_dev_info stdcall, p_info:dword
virtual at esi
CTRL_INFO CTRL_INFO
end virtual
 
mov esi, [p_info]
mov eax, [ctrl.int_line]
mov ebx, [ctrl.codec_io_base]
mov ecx, [ctrl.ctrl_io_base]
mov edx, [ctrl.codec_mem_base]
mov edi, [ctrl.ctrl_mem_base]
 
mov [CTRL_INFO.irq], eax
mov [CTRL_INFO.codec_io_base], ebx
mov [CTRL_INFO.ctrl_io_base], ecx
mov [CTRL_INFO.codec_mem_base], edx
mov [CTRL_INFO.ctrl_mem_base], edi
 
mov eax, [codec.chip_id]
mov [CTRL_INFO.codec_id], eax
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
mov [CTRL_INFO.glob_cntrl], eax
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
mov [CTRL_INFO.glob_sta], eax
 
mov ebx, [ctrl.pci_cmd]
mov [CTRL_INFO.pci_cmd], ebx
 
ret
endp
 
align 4
proc set_callback stdcall, handler:dword
mov eax, [handler]
mov [ctrl.user_callback], eax
ret
endp
 
align 4
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax
 
mov edx, [ac_reg]
 
mov ebx, edx
shr ebx, 1
bt [codec.shadow_flag], ebx
jc .use_shadow
 
call [ctrl.codec_read16] ;change edx !!!
mov ecx, eax
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
test eax, CTRL_ST_RCS
jz .read_ok
 
mov edx, CTRL_STAT
call [ctrl.ctrl_write32]
xor eax,eax
not eax ;timeout
ret
.read_ok:
mov edx, [ac_reg]
mov [codec.regs+edx], cx
bts [codec.shadow_flag], ebx
mov eax, ecx
ret
.use_shadow:
movzx eax, word [codec.regs+edx]
ret
endp
 
align 4
proc codec_write stdcall, ac_reg:dword
push eax
call check_semafore
and eax, eax
jz .err
pop eax
 
mov esi, [ac_reg]
mov edx, esi
call [ctrl.codec_write16]
mov [codec.regs+esi], ax
shr esi, 1
bts [codec.shadow_flag], esi
ret
.err:
pop eax
ret
endp
 
align 4
proc codec_check_ready
 
mov edx, CTRL_ST
call [ctrl.ctrl_read32]
and eax, CTRL_ST_CREADY
jz .not_ready
 
xor eax, wax
inc eax
ret
 
align 4
.not_ready:
xor eax, eax
ret
endp
 
align 4
proc check_semafore
local counter:DWORD
 
mov [counter], 100
.l1:
mov edx, CTRL_CAS
call [ctrl.ctrl_read8]
and eax, CAS_FLAG
jz .ok
 
mov eax, 1
call StallExec
sub [counter], 1
jnz .l1
xor eax, eax
ret
align 4
.ok:
xor eax,eax
inc eax
ret
endp
 
align 4
proc StallExec
push ecx
push edx
push ebx
push eax
 
mov ecx, CPU_FREQ
mul ecx
mov ebx, eax ;low
mov ecx, edx ;high
rdtsc
add ebx, eax
adc ecx,edx
@@:
rdtsc
sub eax, ebx
sbb edx, ecx
jb @B
 
pop eax
pop ebx
pop edx
pop ecx
ret
endp
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONTROLLER IO functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
proc codec_io_r16
add edx, [ctrl.codec_io_base]
in ax, dx
ret
endp
 
align 4
proc codec_io_w16
add edx, [ctrl.codec_io_base]
out dx, ax
ret
endp
 
align 4
proc ctrl_io_r8
add edx, [ctrl.ctrl_io_base]
in al, dx
ret
endp
 
align 4
proc ctrl_io_r16
add edx, [ctrl.ctrl_io_base]
in ax, dx
ret
endp
 
align 4
proc ctrl_io_r32
add edx, [ctrl.ctrl_io_base]
in eax, dx
ret
endp
 
align 4
proc ctrl_io_w8
add edx, [ctrl.ctrl_io_base]
out dx, al
ret
endp
 
align 4
proc ctrl_io_w16
add edx, [ctrl.ctrl_io_base]
out dx, ax
ret
endp
 
align 4
proc ctrl_io_w32
add edx, [ctrl.ctrl_io_base]
out dx, eax
ret
endp
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; MEMORY MAPPED IO (os depended)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
proc codec_mem_r16
add edx, [ctrl.codec_mem_base]
mov ax, word [edx]
ret
endp
 
align 4
proc codec_mem_w16
add edx, [ctrl.codec_mem_base]
mov word [edx], ax
ret
endp
 
align 4
proc ctrl_mem_r8
add edx, [ctrl.ctrl_mem_base]
mov al, [edx]
ret
endp
 
align 4
proc ctrl_mem_r16
add edx, [ctrl.ctrl_mem_base]
mov ax, [edx]
ret
endp
 
align 4
proc ctrl_mem_r32
add edx, [ctrl.ctrl_mem_base]
mov eax, [edx]
ret
endp
 
align 4
proc ctrl_mem_w8
add edx, [ctrl.ctrl_mem_base]
mov [edx], al
 
ret
endp
 
align 4
proc ctrl_mem_w16
add edx, [ctrl.ctrl_mem_base]
mov [edx], ax
ret
endp
 
align 4
proc ctrl_mem_w32
add edx, [ctrl.ctrl_mem_base]
mov [edx], eax
ret
endp
 
 
include "codec.inc"
 
align 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
 
msg_ICH db 'Intel ICH', 13,10, 0
msg_ICH0 db 'Intel ICH0', 13,10, 0
msg_ICH2 db 'Intel ICH2', 13,10, 0
msg_ICH3 db 'Intel ICH3', 13,10, 0
msg_ICH4 db 'Intel ICH4', 13,10, 0
msg_ICH5 db 'Intel ICH5', 13,10, 0
msg_ICH6 db 'Intel ICH6', 13,10, 0
msg_ICH7 db 'Intel ICH7', 13,10, 0
msg_Intel db 'Intel Corp. ', 0
 
msg_NForce db 'NForce', 13,10, 0
msg_NForce2 db 'NForce 2', 13,10, 0
msg_NForce3 db 'NForce 3', 13,10, 0
msg_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',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
 
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/tags/kolibri0.6.3.0/drivers/sis.asm
0,0 → 1,1155
 
format MS COFF
 
 
include 'proc32.inc'
 
DEBUG equ 1
 
CPU_FREQ equ 2000d ;cpu freq in MHz
 
BIT0 EQU 0x00000001
BIT1 EQU 0x00000002
BIT2 EQU 0x00000004
BIT3 EQU 0x00000008
BIT4 EQU 0x00000010
BIT5 EQU 0x00000020
BIT6 EQU 0x00000040
BIT7 EQU 0x00000080
BIT8 EQU 0x00000100
BIT9 EQU 0x00000200
BIT10 EQU 0x00000400
BIT11 EQU 0x00000800
BIT12 EQU 0x00001000
BIT13 EQU 0x00002000
BIT14 EQU 0x00004000
BIT15 EQU 0x00008000
BIT16 EQU 0x00010000
BIT17 EQU 0x00020000
BIT18 EQU 0x00040000
BIT19 EQU 0x00080000
BIT20 EQU 0x00100000
BIT21 EQU 0x00200000
BIT22 EQU 0x00400000
BIT23 EQU 0x00800000
BIT24 EQU 0x00100000
BIT25 EQU 0x02000000
BIT26 EQU 0x04000000
BIT27 EQU 0x08000000
BIT28 EQU 0x10000000
BIT29 EQU 0x20000000
BIT30 EQU 0x40000000
BIT31 EQU 0x80000000
 
VID_SIS equ 0x1039
CTRL_SIS equ 0x7012
 
PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list
PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register
PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index
PCM_OUT_SR_REG equ 0x18 ; PCM out Status register
PCM_OUT_PIV_REG equ 0x1a ; PCM out prefetched index
PCM_OUT_CIV_REG equ 0x14 ; PCM out current index
 
PCM_IN_CR_REG equ 0x0b ; PCM in Control Register
MC_IN_CR_REG equ 0x2b ; MIC in Control Register
RR equ BIT1 ; reset registers. Nukes all regs
 
CODEC_MASTER_VOL_REG equ 0x02
CODEC_AUX_VOL equ 0x04 ;
CODEC_PCM_OUT_REG equ 18h ; PCM output volume
CODEC_EXT_AUDIO_REG equ 28h ; extended audio
CODEC_EXT_AUDIO_CTRL_REG equ 2ah ; extended audio control
CODEC_PCM_FRONT_DACRATE_REG equ 2ch ; PCM out sample rate
CODEC_PCM_SURND_DACRATE_REG equ 2eh ; surround sound sample rate
CODEC_PCM_LFE_DACRATE_REG equ 30h ; LFE sample rate
 
 
GLOB_CTRL equ 0x2C ; Global Control
CTRL_STAT equ 0x30 ; Global Status
CTRL_CAS equ 0x34 ; Codec Access Semiphore
 
CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit
 
CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready
 
CTRL_ST_RCS equ 0x00008000 ; Read Completion Status
 
CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable
CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off
CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset
CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset
CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable
 
CODEC_REG_POWERDOWN equ 0x26
CODEC_REG_ST equ 0x26
 
 
DEV_PLAY equ 1
DEV_STOP equ 2
DEV_CALLBACK equ 3
DEV_SET_BUFF equ 4
DEV_NOTIFY equ 5
DEV_SET_MASTERVOL equ 6
DEV_GET_MASTERVOL equ 7
DEV_GET_INFO equ 8
 
struc AC_CNTRL ;AC controller base class
{ .bus dd ?
.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 0; 0x80400000
new_app_base equ 0x60400000; 0x01000000
PROC_BASE equ OS_BASE+0x0080000
 
public START
public STOP
public service_proc
 
extrn AttachIntHandler
extrn SysMsgBoardStr
extrn PciApi
extrn PciRead32
extrn PciRead8
extrn PciWrite8
extrn AllocKernelSpace
extrn MapPage
extrn RegService
extrn KernelAlloc
extrn GetPgAddr
extrn GetCurrentTask
 
section '.flat' code readable align 16
 
START:
if DEBUG
mov esi, msgInit
call SysMsgBoardStr
end if
 
call detect_controller
test eax, eax
jz .fail
 
if DEBUG
mov esi,[ctrl.vendor_ids]
call SysMsgBoardStr
mov esi, [ctrl.ctrl_ids]
call SysMsgBoardStr
end if
 
call init_controller
test eax, eax
jz .fail
 
if DEBUG
mov esi, msgInitCodec
call SysMsgBoardStr
end if
 
call init_codec
test eax, eax
jz .fail
 
if DEBUG
mov esi, [codec.ac_vendor_ids]
call SysMsgBoardStr
 
mov esi, [codec.chip_ids]
call SysMsgBoardStr
end if
 
call reset_controller
call setup_codec
 
mov esi, msgPrimBuff
call SysMsgBoardStr
 
call create_primary_buff
 
stdcall AttachIntHandler, [ctrl.int_line], ac97_irq
 
stdcall RegService, sz_sound_srv, service_proc
 
mov esi, msgOk
call SysMsgBoardStr
 
ret
 
.fail:
if DEBUG
mov esi, msgFail
call SysMsgBoardStr
end if
STOP:
xor eax, eax
ret
 
handle equ IOCTL.handle
io_code equ IOCTL.io_code
input equ IOCTL.input
inp_size equ IOCTL.inp_size
output equ IOCTL.output
out_size equ IOCTL.out_size
 
align 4
proc service_proc stdcall, ioctl:dword
 
mov edi, [ioctl]
mov eax, [edi+io_code]
cmp eax, DEV_PLAY
jne @F
if DEBUG
mov esi, msgPlay
call SysMsgBoardStr
end if
call play
ret
@@:
cmp eax, DEV_STOP
jne @F
if DEBUG
mov esi, msgStop
call SysMsgBoardStr
end if
call stop
ret
@@:
cmp eax, DEV_CALLBACK
jne @F
mov ebx, [edi+input]
stdcall set_callback, [ebx]
ret
@@:
cmp eax, DEV_SET_MASTERVOL
jne @F
mov ebx, [edi+input]
stdcall set_master_vol, [ebx]
ret
@@:
cmp eax, DEV_GET_MASTERVOL
jne @F
mov ebx, [edi+output]
test ebx, ebx
jz .fail
 
stdcall get_master_vol, ebx
ret
@@:
cmp eax, DEV_GET_INFO
jne @F
mov ebx, [edi+output]
stdcall get_dev_info, ebx
ret
@@:
.fail:
xor eax, eax
ret
endp
 
restore handle
restore io_code
restore input
restore inp_size
restore output
restore out_size
 
align 4
proc ac97_irq
 
; if DEBUG
; mov esi, msgIRQ
; call SysMsgBoardStr
; end if
 
mov edx, PCM_OUT_CR_REG
mov al, 0x14
call [ctrl.ctrl_write8]
 
mov ax, 0x1c
mov edx, PCM_OUT_SR_REG
call [ctrl.ctrl_write16]
 
mov edx, PCM_OUT_CIV_REG
call [ctrl.ctrl_read8]
 
and eax, 0x1F
cmp eax, [civ_val]
je .skip
 
mov [civ_val], eax
dec eax
and eax, 0x1F
mov [ctrl.lvi_reg], eax
 
mov edx, PCM_OUT_LVI_REG
call [ctrl.ctrl_write8]
 
mov edx, PCM_OUT_CR_REG
mov ax, 0x1D
call [ctrl.ctrl_write8]
 
mov eax, [civ_val]
add eax, 2
and eax, 31
mov ebx, dword [buff_list+eax*4]
 
cmp [ctrl.user_callback], 0
je @f
 
stdcall [ctrl.user_callback], ebx
@@:
ret
 
.skip:
mov edx, PCM_OUT_CR_REG
mov ax, 0x1D
call [ctrl.ctrl_write8]
ret
endp
 
align 4
proc create_primary_buff
 
stdcall KernelAlloc, 0x10000
mov [ctrl.buffer], eax
 
mov edi, eax
mov ecx, 0x10000/4
xor eax, eax
rep stosd
 
stdcall GetPgAddr, [ctrl.buffer]
 
mov ebx, 0xC0004000
mov ecx, 4
mov edi, pcmout_bdl
@@:
mov [edi], eax
mov [edi+4], ebx
 
mov [edi+32], eax
mov [edi+4+32], ebx
 
mov [edi+64], eax
mov [edi+4+64], ebx
 
mov [edi+96], eax
mov [edi+4+96], ebx
 
mov [edi+128], eax
mov [edi+4+128], ebx
 
mov [edi+160], eax
mov [edi+4+160], ebx
 
mov [edi+192], eax
mov [edi+4+192], ebx
 
mov [edi+224], eax
mov [edi+4+224], ebx
 
add eax, 0x4000
add edi, 8
loop @B
 
mov edi, buff_list
mov eax, [ctrl.buffer]
mov ecx, 4
@@:
mov [edi], eax
mov [edi+16], eax
mov [edi+32], eax
mov [edi+48], eax
mov [edi+64], eax
mov [edi+80], eax
mov [edi+96], eax
mov [edi+112], eax
 
add eax, 0x4000
add edi, 4
loop @B
 
mov ecx, pcmout_bdl
stdcall GetPgAddr, ecx
and ecx, 0xFFF
add eax, ecx
 
mov edx, PCM_OUT_BDL
call [ctrl.ctrl_write32]
 
mov eax, 16
mov [ctrl.lvi_reg], eax
mov edx, PCM_OUT_LVI_REG
call [ctrl.ctrl_write8]
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
and eax, not 0x000000C0
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
 
 
ret
endp
 
align 4
proc detect_controller
locals
last_bus dd ?
bus dd ?
devfn dd ?
endl
 
xor eax, eax
mov [bus], eax
inc eax
call PciApi
cmp eax, -1
je .err
 
mov [last_bus], eax
 
.next_bus:
and [devfn], 0
.next_dev:
stdcall PciRead32, [bus], [devfn], dword 0
test eax, eax
jz .next
cmp eax, -1
je .next
 
mov edi, devices
@@:
mov ebx, [edi]
test ebx, ebx
jz .next
 
cmp eax, ebx
je .found
add edi, 12
jmp @B
 
.next: inc [devfn]
cmp [devfn], 256
jb .next_dev
mov eax, [bus]
inc eax
mov [bus], eax
cmp eax, [last_bus]
jna .next_bus
xor eax, eax
ret
.found:
mov ebx, [bus]
mov [ctrl.bus], ebx
 
mov ecx, [devfn]
mov [ctrl.devfn], ecx
 
mov edx, eax
and edx, 0xFFFF
mov [ctrl.vendor], edx
shr eax, 16
mov [ctrl.dev_id], eax
 
mov ebx, [edi+4]
mov [ctrl.ctrl_ids], ebx
mov [ctrl.vendor_ids], msg_SIS
 
mov esi, [edi+8]
mov [ctrl.ctrl_setup], esi
 
ret
.err:
xor eax, eax
ret
endp
 
align 4
proc init_controller
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4
mov ebx, eax
and eax, 0xFFFF
mov [ctrl.pci_cmd], eax
shr ebx, 16
mov [ctrl.pci_stat], ebx
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10
and eax,0xFFFE
mov [ctrl.codec_io_base], eax
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x14
and eax, 0xFFC0
mov [ctrl.ctrl_io_base], eax
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x18
mov [ctrl.codec_mem_base], eax
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x1C
mov [ctrl.ctrl_mem_base], eax
 
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C
and eax, 0xFF
mov [ctrl.int_line], eax
 
stdcall PciRead8, [ctrl.bus], [ctrl.devfn], dword 0x41
and eax, 0xFF
mov [ctrl.cfg_reg], eax
 
call [ctrl.ctrl_setup]
xor eax, eax
inc eax
ret
endp
 
align 4
proc set_SIS
mov [ctrl.codec_read16], codec_io_r16 ;virtual
mov [ctrl.codec_write16], codec_io_w16 ;virtual
 
mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual
mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual
mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual
 
mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual
mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual
mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual
ret
endp
 
align 4
proc reset_controller
 
xor eax, eax
mov edx, PCM_IN_CR_REG
call [ctrl.ctrl_write8]
 
mov edx, PCM_OUT_CR_REG
call [ctrl.ctrl_write8]
 
mov edx, MC_IN_CR_REG
call [ctrl.ctrl_write8]
 
mov eax, RR
mov edx, PCM_IN_CR_REG
call [ctrl.ctrl_write8]
 
mov edx, PCM_OUT_CR_REG
call [ctrl.ctrl_write8]
 
mov edx, MC_IN_CR_REG
call [ctrl.ctrl_write8]
 
 
ret
endp
 
align 4
proc init_codec
locals
counter dd ?
endl
 
call reset_codec
and eax, eax
jz .err
 
xor edx, edx ;ac_reg_0
call [ctrl.codec_write16]
 
xor eax, eax
mov edx, CODEC_REG_POWERDOWN
call [ctrl.codec_write16]
 
mov [counter], 200 ; total 200*5 ms = 1s
.wait:
mov edx, CODEC_REG_POWERDOWN
call [ctrl.codec_read16]
and eax, 0x0F
cmp eax, 0x0F
jz .ready
 
mov eax, 5000 ; wait 5 ms
call StallExec
sub [counter] , 1
jnz .wait
.err:
xor eax, eax ; timeout error
ret
.ready:
call detect_codec
 
xor eax, eax
inc eax
ret
endp
 
align 4
proc reset_codec
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
 
test eax, 0x02
jz .cold
 
call warm_reset
jnc .ok
.cold:
call cold_reset
jnc .ok
 
if DEBUG
mov esi, msgCFail
call SysMsgBoardStr
end if
xor eax, eax ; timeout error
ret
.ok:
xor eax, eax
inc eax
ret
endp
 
align 4
proc warm_reset
locals
counter dd ?
endl
 
mov eax, 0x06
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
 
if DEBUG
mov esi, msgWarm
call SysMsgBoardStr
end if
 
mov [counter], 10 ; total 10*100 ms = 1s
.wait:
mov eax, 100000 ; wait 100 ms
call StallExec
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
test eax, 4
jz .ok
sub [counter], 1
jnz .wait
 
if DEBUG
mov esi, msgWRFail
call SysMsgBoardStr
end if
 
stc
ret
.ok:
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
and eax, CTRL_ST_CREADY
jz .fail
clc
ret
.fail:
stc
ret
endp
 
align 4
proc cold_reset
locals
counter dd ?
endl
 
xor eax, eax
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
 
if DEBUG
mov esi, msgCold
call SysMsgBoardStr
end if
 
mov eax, 1000000 ; wait 1 s
call StallExec
 
mov eax, 2
mov edx, GLOB_CTRL
call [ctrl.ctrl_write32]
 
mov [counter], 10 ; total 10*100 ms = 1s
.wait:
mov eax, 100000 ; wait 100 ms
call StallExec
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
test eax, 4
jz .ok
sub [counter], 1
jnz .wait
 
if DEBUG
mov esi, msgCRFail
call SysMsgBoardStr
end if
stc
ret
.ok:
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
and eax, CTRL_ST_CREADY
jz .fail
clc
ret
.fail:
stc
ret
endp
 
align 4
proc play
xor eax, eax
mov [civ_val], eax
mov edx, PCM_OUT_CIV_REG
call [ctrl.ctrl_write8]
 
mov eax, 16
mov [ctrl.lvi_reg], eax
mov edx, PCM_OUT_LVI_REG
call [ctrl.ctrl_write8]
 
mov edx, PCM_OUT_CR_REG
mov ax, 0x1D
call [ctrl.ctrl_write8]
ret
endp
 
align 4
proc stop
mov edx, PCM_OUT_CR_REG
mov ax, 0x14
call [ctrl.ctrl_write8]
 
mov eax, 16
mov [ctrl.lvi_reg], eax
mov edx, PCM_OUT_LVI_REG
call [ctrl.ctrl_write8]
 
ret
endp
 
align 4
proc get_dev_info stdcall, p_info:dword
virtual at esi
CTRL_INFO CTRL_INFO
end virtual
 
mov esi, [p_info]
mov eax, [ctrl.int_line]
mov ebx, [ctrl.codec_io_base]
mov ecx, [ctrl.ctrl_io_base]
mov edx, [ctrl.codec_mem_base]
mov edi, [ctrl.ctrl_mem_base]
 
mov [CTRL_INFO.irq], eax
mov [CTRL_INFO.codec_io_base], ebx
mov [CTRL_INFO.ctrl_io_base], ecx
mov [CTRL_INFO.codec_mem_base], edx
mov [CTRL_INFO.ctrl_mem_base], edi
 
mov eax, [codec.chip_id]
mov [CTRL_INFO.codec_id], eax
 
mov edx, GLOB_CTRL
call [ctrl.ctrl_read32]
mov [CTRL_INFO.glob_cntrl], eax
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
mov [CTRL_INFO.glob_sta], eax
 
mov ebx, [ctrl.pci_cmd]
mov [CTRL_INFO.pci_cmd], ebx
 
ret
endp
 
align 4
proc set_callback stdcall, handler:dword
mov eax, [handler]
mov [ctrl.user_callback], eax
ret
endp
 
align 4
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax
 
mov edx, [ac_reg]
 
mov ebx, edx
shr ebx, 1
bt [codec.shadow_flag], ebx
jc .use_shadow
 
call [ctrl.codec_read16] ;change edx !!!
mov ecx, eax
 
mov edx, CTRL_STAT
call [ctrl.ctrl_read32]
test eax, CTRL_ST_RCS
jz .read_ok
 
mov edx, CTRL_STAT
call [ctrl.ctrl_write32]
xor eax,eax
not eax ;timeout
ret
.read_ok:
mov edx, [ac_reg]
mov [codec.regs+edx], cx
bts [codec.shadow_flag], ebx
mov eax, ecx
ret
.use_shadow:
movzx eax, word [codec.regs+edx]
ret
endp
 
align 4
proc codec_write stdcall, ac_reg:dword
push eax
call check_semafore
and eax, eax
jz .err
pop eax
 
mov esi, [ac_reg]
mov edx, esi
call [ctrl.codec_write16]
mov [codec.regs+esi], ax
shr esi, 1
bts [codec.shadow_flag], esi
ret
.err:
pop eax
ret
endp
 
 
align 4
proc codec_check_ready
 
mov edx, CTRL_ST
call [ctrl.ctrl_read32]
and eax, CTRL_ST_CREADY
jz .not_ready
 
xor eax, wax
inc eax
ret
 
align 4
.not_ready:
xor eax, eax
ret
endp
 
 
align 4
proc check_semafore
local counter:DWORD
 
mov [counter], 100
.l1:
mov edx, CTRL_CAS
call [ctrl.ctrl_read8]
and eax, CAS_FLAG
jz .ok
 
mov eax, 1
call StallExec
sub [counter], 1
jnz .l1
xor eax, eax
ret
align 4
.ok:
xor eax,eax
inc eax
ret
endp
 
align 4
proc StallExec
push ecx
push edx
push ebx
push eax
 
mov ecx, CPU_FREQ
mul ecx
mov ebx, eax ;low
mov ecx, edx ;high
rdtsc
add ebx, eax
adc ecx,edx
@@:
rdtsc
sub eax, ebx
sbb edx, ecx
jb @B
 
pop eax
pop ebx
pop edx
pop ecx
ret
endp
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONTROLLER IO functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
proc codec_io_r16
add edx, [ctrl.codec_io_base]
in ax, dx
ret
endp
 
align 4
proc codec_io_w16
add edx, [ctrl.codec_io_base]
out dx, ax
ret
endp
 
align 4
proc ctrl_io_r8
add edx, [ctrl.ctrl_io_base]
in al, dx
ret
endp
 
align 4
proc ctrl_io_r16
add edx, [ctrl.ctrl_io_base]
in ax, dx
ret
endp
 
align 4
proc ctrl_io_r32
add edx, [ctrl.ctrl_io_base]
in eax, dx
ret
endp
 
align 4
proc ctrl_io_w8
add edx, [ctrl.ctrl_io_base]
out dx, al
ret
endp
 
align 4
proc ctrl_io_w16
add edx, [ctrl.ctrl_io_base]
out dx, ax
ret
endp
 
align 4
proc ctrl_io_w32
add edx, [ctrl.ctrl_io_base]
out dx, eax
ret
endp
 
include "codec.inc"
 
align 4
devices dd (CTRL_SIS shl 16)+VID_SIS,msg_AC, set_SIS
dd 0
 
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
msgPlay db 'start play', 13,10,0
msgStop db 'stop play', 13,10,0
msgNotify db 'call notify',13,10,0
msgIRQ db 'AC97 IRQ', 13,10,0
msgInitCtrl db 'init controller',13,10,0
msgInitCodec db 'init codec',13,10,0
msgPrimBuff db 'create primary buffer',13,10,0
msgReg db 'set service handler',13,10,0
msgOk db 'service installed',13,10,0
msgCold db 'cold resret',13,10,0
msgWarm db 'warm reset',13,10,0
msgWRFail db 'warm reset failed',13,10,0
msgCRFail db 'cold reset failed',13,10,0
msgCFail db 'codec not ready',13,10,0
 
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/tags/kolibri0.6.3.0/drivers/codec.inc
0,0 → 1,223
 
align 4
proc detect_codec
locals
codec_id dd ?
endl
 
stdcall codec_read, dword 0x7C
shl eax, 16
mov [codec_id], eax
 
stdcall codec_read, dword 0x7E
or eax, [codec_id]
 
mov [codec.chip_id], eax
and eax, 0xFFFFFF00
 
mov edi, codecs
@@:
mov ebx, [edi]
test ebx, ebx
jz .unknown
 
cmp eax, ebx
jne .next
mov eax, [edi+4]
mov [codec.ac_vendor_ids], eax
stdcall detect_chip, [edi+8]
ret
.next:
add edi, 12
jmp @B
.unknown:
mov [codec.ac_vendor_ids], ac_unknown
mov [codec.chip_ids], chip_unknown
ret
endp
 
align 4
proc detect_chip stdcall, chip_tab:dword
 
mov eax, [codec.chip_id]
and eax, 0xFF
 
mov edi, [chip_tab]
@@:
mov ebx, [edi]
test ebx, ebx
jz .unknown
 
cmp eax,ebx
jne .next
mov eax, [edi+4]
mov [codec.chip_ids], eax
ret
.next:
add edi, 8
jmp @b
.unknown:
mov [codec.chip_ids], chip_unknown
ret
endp
 
align 4
proc setup_codec
 
xor eax, eax
stdcall codec_write, dword CODEC_AUX_VOL
 
mov eax, 0x1010
stdcall codec_write, dword CODEC_MASTER_VOL_REG
 
mov ax, 0x08
stdcall codec_write, dword 0x0C
 
mov ax, 0x0808
stdcall codec_write, dword CODEC_PCM_OUT_REG
 
mov ax, 0x0808
stdcall codec_write, dword 0x10
 
mov ax, 0x0808
stdcall codec_write, dword 0x12
 
mov ax, 0x0808
stdcall codec_write, dword 0x16
 
 
stdcall codec_read, dword CODEC_EXT_AUDIO_CTRL_REG
 
and eax, 0FFFFh - BIT1 ; clear DRA (BIT1)
or eax, BIT0 ; set VRA (BIT0)
stdcall codec_write, dword CODEC_EXT_AUDIO_CTRL_REG
 
stdcall set_sample_rate, dword 48000
 
.init_error:
 
xor eax, eax ; exit with error
ret
 
endp
 
align 4
proc set_master_vol stdcall, vol:dword
 
mov ebx, 63
mov ecx, 20644
mov eax, [vol]
cmp eax, 90
jna @f
mov eax, 90
@@:
mul ecx
shr eax, 15
sub ebx, eax
mov ah, bl
mov al, bl
stdcall codec_write, dword CODEC_MASTER_VOL_REG
ret
endp
 
align 4
proc get_master_vol stdcall, pvol:dword
 
stdcall codec_read, dword CODEC_MASTER_VOL_REG
and eax, 0x3F
mov ebx, 63
mov ecx, 20644
 
xchg eax, ebx
sub eax, ebx
shl eax, 15
xor edx, edx
div ecx
mov ebx, [pvol]
mov [ebx], eax
ret
endp
 
align 4
proc set_sample_rate stdcall, rate:dword
mov eax, [rate]
stdcall codec_write, dword CODEC_PCM_FRONT_DACRATE_REG
ret
endp
 
align 16
ac_unknown db 'unknown manufacturer',13,10,0
ac_Realtek db 'Realtek Semiconductor',13,10,0
ac_Analog db 'Analog Devices',13,10,0
ac_CMedia db 'C-Media Electronics',13,10,0
chip_unknown db 'unknown chip', 13,10,0
 
CHIP_ANALOG equ 0x41445300
CHIP_REALTEK equ 0x414C4700
CHIP_CMEDIA equ 0x434D4900
 
align 16
codecs dd CHIP_ANALOG, ac_Analog, chips_Analog
dd CHIP_CMEDIA, ac_CMedia, chips_CMedia
dd CHIP_REALTEK,ac_Realtek, chips_Realtek
dd 0
 
align 16
chips_Analog dd 0x03, chip_AD1819
dd 0x40, chip_AD1881
dd 0x48, chip_AD1881A
dd 0x60, chip_AD1884
dd 0x61, chip_AD1886
dd 0x62, chip_AD1887
dd 0x63, chip_AD1886A
dd 0x70, chip_AD1980
dd 0x75, chip_AD1985
dd 0
 
chips_Realtek dd 0x20, chip_ALC650
dd 0x21, chip_ALC650D
dd 0x22, chip_ALC650E
dd 0x23, chip_ALC650F
dd 0x60, chip_ALC655
dd 0x80, chip_ALC658
dd 0x81, chip_ALC658D
dd 0x90, chip_ALC850
dd 0
 
chips_CMedia dd 0x41, chip_CM9738
dd 0x61, chip_CM9739
dd 0x69, chip_CM9780
dd 0x78, chip_CM9761
dd 0x82, chip_CM9761
dd 0x83, chip_CM9761
dd 0
 
align 16
;Analog Devices
chip_AD1819 db 'AD1819 ',0dh,0ah,00h
chip_AD1881 db 'AD1881 ',0dh,0ah,00h
chip_AD1881A db 'AD1881A',0dh,0ah,00h
chip_AD1884 db 'AD1885 ',0dh,0ah,00h
chip_AD1885 db 'AD1885 ',0dh,0ah,00h
chip_AD1886 db 'AD1886 ',0dh,0ah,00h
chip_AD1886A db 'AD1886A',0dh,0ah,00h
chip_AD1887 db 'AD1887 ',0dh,0ah,00h
chip_AD1980 db 'AD1980 ',0dh,0ah,00h
chip_AD1985 db 'AD1985 ',0dh,0ah,00h
 
;Realtek
chip_ALC650 db 'ALC650 ',0dh,0ah,00h
chip_ALC650D db 'ALC650D',0dh,0ah,00h
chip_ALC650E db 'ALC650E',0dh,0ah,00h
chip_ALC650F db 'ALC650F',0dh,0ah,00h
chip_ALC655 db 'ALC655 ',0dh,0ah,00h
chip_ALC658 db 'ALC658 ',0dh,0ah,00h
chip_ALC658D db 'ALC658D',0dh,0ah,00h
chip_ALC850 db 'ALC850 ',0dh,0ah,00h
 
;CMedia
chip_CM9738 db 'CMI9738', 0dh,0ah,0
chip_CM9739 db 'CMI9739', 0dh,0ah,0
chip_CM9780 db 'CMI9780', 0dh,0ah,0
chip_CM9761 db 'CMI9761', 0dh,0ah,0
 
/kernel/tags/kolibri0.6.3.0/drivers/main.inc
0,0 → 1,133
;
; This file is part of the Infinity sound AC97 driver.
; (C) copyright Serge 2006
; email: infinity_sound@mail.ru
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
 
PCM_2_16_48 equ 1
PCM_1_16_48 equ 2
 
PCM_2_16_44 equ 3
PCM_1_16_44 equ 4
 
PCM_2_16_32 equ 5
PCM_1_16_32 equ 6
 
PCM_2_16_24 equ 7
PCM_1_16_24 equ 8
 
PCM_2_16_22 equ 9
PCM_1_16_22 equ 10
 
PCM_2_16_16 equ 11
PCM_1_16_16 equ 12
 
PCM_2_16_12 equ 13
PCM_1_16_12 equ 14
 
PCM_2_16_11 equ 15
PCM_1_16_11 equ 16
 
PCM_2_8_48 equ 17
PCM_1_8_48 equ 18
 
PCM_2_8_44 equ 19
PCM_1_8_44 equ 20
 
PCM_2_8_32 equ 21
PCM_1_8_32 equ 22
 
PCM_2_8_24 equ 23
PCM_1_8_24 equ 24
 
PCM_2_8_22 equ 25
PCM_1_8_22 equ 26
 
PCM_2_8_16 equ 27
PCM_1_8_16 equ 28
 
PCM_2_8_12 equ 29
PCM_1_8_12 equ 30
 
PCM_2_8_11 equ 31
PCM_1_8_11 equ 32
 
SND_PLAY equ 1
SND_STOP equ 2
 
; struc SND_DEV
;{ .magic dd 0
; .size dd 0
; .count dd 0
; dd 0
; .snd_buff dd 16 dup (0)
;}
 
;virtual at 0
; SND_DEV SND_DEV
;end virtual
 
;SND_DEV_SIZE equ 80
 
 
struc STREAM
{ .magic dd 0
.size dd 0
.device dd 0
.format dd 0
.flags dd 0
 
.work_buff dd 0
.work_read dd 0
.work_write dd 0
.work_count dd 0
.work_top dd 0
.r_buff dd 0
.r_size dd 0
.r_end dd 0
.r_dt dd 0
.r_silence dd 0
 
.base dd 0
.curr_seg dd 0
.limit dd 0
.buff_size dd 0
.notify_off1 dd 0
.notify_off2 dd 0
.notify_task dd 0
.resample dd 0
}
 
STREAM_SIZE equ 23*4
 
virtual at 0
STREAM STREAM
end virtual
 
struc WAVE_HEADER
{ .riff_id dd ?
.riff_size dd ?
.riff_format dd ?
 
.fmt_id dd ?
.fmt_size dd ?
.format_tag dw ?
.channels dw ?
.freq dd ?
.bytes_sec dd ?
.block_align dw ?
.bits_sample dw ?
 
.data_id dd ?
.data_size dd ?
}
 
/kernel/tags/kolibri0.6.3.0/drivers/proc32.inc
0,0 → 1,268
 
; Macroinstructions for defining and calling procedures
 
macro stdcall proc,[arg] ; directly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call proc }
 
macro invoke proc,[arg] ; indirectly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call [proc] }
 
macro ccall proc,[arg] ; directly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call proc
if size@ccall
add esp,size@ccall
end if }
 
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call [proc]
if size@ccall
add esp,size@ccall
end if }
 
macro proc [args] ; define procedure
{ common
match name params, args>
\{ define@proc name,<params \} }
 
prologue@proc equ prologuedef
 
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,localbytes
end if
end if
irps reg, reglist \{ push reg \} }
 
epilogue@proc equ epiloguedef
 
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if flag and 10000b
retn
else
retn parmbytes
end if }
 
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
virtual at ebp+8
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $ - (ebp+8)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
macro locals
\{ virtual at ebp-localbytes+current
macro label . \\{ deflocal@proc .,:, \\}
struc db [val] \\{ \common deflocal@proc .,db,val \\}
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
macro endl
\{ purge label
restruc db,dw,dp,dd,dt,dq
restruc rb,rw,rp,rd,rt,rq
restruc byte,word,dword,pword,tword,qword
current = $-(ebp-localbytes)
end virtual \}
macro ret operand
\{ match any, operand \\{ retn operand \\}
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs>
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2
end if \} }
 
macro defargs@proc [arg]
{ common
if ~ arg eq
forward
local ..arg,current@arg
match argname:type, arg
\{ current@arg equ argname
label ..arg type
argname equ ..arg
if dqword eq type
dd ?,?,?,?
else if tbyte eq type
dd ?,?,?
else if qword eq type | pword eq type
dd ?,?
else
dd ?
end if \}
match =current@arg,current@arg
\{ current@arg equ arg
arg equ ..arg
..arg dd ? \}
common
args@proc equ current@arg
forward
restore current@arg
common
end if }
 
macro deflocal@proc name,def,[val]
{ common
match vars, all@vars \{ all@vars equ all@vars, \}
all@vars equ all@vars name
forward
local ..var,..tmp
..var def val
match =?, val \{ ..tmp equ \}
match any =dup (=?), val \{ ..tmp equ \}
match tmp : value, ..tmp : val
\{ tmp: end virtual
initlocal@proc ..var,def value
virtual at tmp\}
common
match first rest, ..var, \{ name equ first \} }
 
macro initlocal@proc name,def
{ virtual at name
def
size@initlocal = $ - name
end virtual
position@initlocal = 0
while size@initlocal > position@initlocal
virtual at name
def
if size@initlocal - position@initlocal < 2
current@initlocal = 1
load byte@initlocal byte from name+position@initlocal
else if size@initlocal - position@initlocal < 4
current@initlocal = 2
load word@initlocal word from name+position@initlocal
else
current@initlocal = 4
load dword@initlocal dword from name+position@initlocal
end if
end virtual
if current@initlocal = 1
mov byte [name+position@initlocal],byte@initlocal
else if current@initlocal = 2
mov word [name+position@initlocal],word@initlocal
else
mov dword [name+position@initlocal],dword@initlocal
end if
position@initlocal = position@initlocal + current@initlocal
end while }
 
macro endp
{ purge ret,locals,endl
finish@proc
purge finish@proc
restore regs@proc
match all,args@proc \{ restore all \}
restore args@proc
match all,all@vars \{ restore all \} }
 
macro local [var]
{ common
locals
forward done@local equ
match varname[count]:vartype, var
\{ match =BYTE, vartype \\{ varname rb count
restore done@local \\}
match =WORD, vartype \\{ varname rw count
restore done@local \\}
match =DWORD, vartype \\{ varname rd count
restore done@local \\}
match =PWORD, vartype \\{ varname rp count
restore done@local \\}
match =QWORD, vartype \\{ varname rq count
restore done@local \\}
match =TBYTE, vartype \\{ varname rt count
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
rq count+count
restore done@local \\}
match , done@local \\{ virtual
varname vartype
end virtual
rb count*sizeof.\#vartype
restore done@local \\} \}
match :varname:vartype, done@local:var
\{ match =BYTE, vartype \\{ varname db ?
restore done@local \\}
match =WORD, vartype \\{ varname dw ?
restore done@local \\}
match =DWORD, vartype \\{ varname dd ?
restore done@local \\}
match =PWORD, vartype \\{ varname dp ?
restore done@local \\}
match =QWORD, vartype \\{ varname dq ?
restore done@local \\}
match =TBYTE, vartype \\{ varname dt ?
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
dq ?,?
restore done@local \\}
match , done@local \\{ varname vartype
restore done@local \\} \}
match ,done@local
\{ var
restore done@local \}
common
endl }
/kernel/tags/kolibri0.6.3.0/boot/booteng.inc
0,0 → 1,134
;======================================================================
;
; BOOT DATA
;
;======================================================================
 
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
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
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 "Display: EGA/CGA",13,10,0
vervesa db "Version of Vesa: Vesa x.x",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 Colors: [9] 320x200, "
db "VGA 16 Colors: [0] 640x480",13,10
db 186," Select mode: ",0
bt24 db "Bits Per Pixel: 24",13,10,0
bt32 db "Bits Per Pixel: 32",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
;askmouse db " Mouse at:"
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
; db " Select port [1-3]: ",0
;no_com1 db 13,10,186, " No COM1 mouse",0
;no_com2 db 13,10,186, " No COM2 mouse",0
gr_acc db "Vesa 2.0+ : MTRR graphics acceleration "
db "[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 "Load ramdisk from [1-floppy; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-use preloaded ram-image from kernel restart]: ",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
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
mode1 db "640x480",0
mode2 db "800x600",0
mode3 db "1024x768",0
mode4 db "1280x1024",0
modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000
modevesa20 db " with 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 mode)",0
probeok_msg db " (check nonstandard modes)",0
mtrr_msg db " [b] Use MTRR for graphics acceleration:",0
on_msg db " on",13,10,0
off_msg db " off",13,10,0
vrrm_msg db " [c] Use VRR:",0
preboot_device_msg db " [d] Floppy image: ",0
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000
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
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
/kernel/tags/kolibri0.6.3.0/boot/bootge.inc
0,0 → 1,139
;======================================================================
;
; BOOT DATA
;
;======================================================================
 
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
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
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
gr_acc db "Vesa 2.0+ : MTRR Grafikbeschleunigung "
db "[1-ja/2-nein] ? ",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]: ",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-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000
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
mtrr_msg db " [b] Nutze MTRR fuer Graphibeschleunigung:",0
on_msg db " an",13,10,0
off_msg db " aus",13,10,0
vrrm_msg db " [c] Nutze VRR:",0
preboot_device_msg db " [d] Diskettenimage: ",0
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000
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
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
/kernel/tags/kolibri0.6.3.0/boot/bootru.inc
0,0 → 1,134
;======================================================================
;
; BOOT DATA
;
;======================================================================
 
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
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
d80x25_bottom:
db 186,' Kolibri OS ®á­®¢ ­  ­  Menuet OS ¨ ­¥ ¯à¥¤®áâ ¢«ï¥â '
db '­¨ª ª¨å £ àa­â¨©. ',186
db 186,' ®¤à®¡­¥¥ ᬮâà¨â¥ ä ©« GNU.TXT '
db ' ',186
line_full_bottom
d80x25_bottom_num = 3
 
novesa db "‚¨¤¥®ª àâ : EGA/CGA",13,10,0
vervesa db "‚¥àá¨ï VESA: Vesa x.x",13,10,0
vervesa_off=19
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 –¢¥â®¢: [9] 320x200, "
db "VGA 16 –¢¥â®¢: [0] 640x480",13,10
db 186," ‚ë¡¥à¨â¥ ¢¨¤¥®à¥¦¨¬: ",0
bt24 db "ƒ«ã¡¨­  梥â : 24",13,10,0
bt32 db "ƒ«ã¡¨­  梥â : 32",13,10,0
vrrmprint db "ˆá¯®«ì§®¢ âì VRR? (ç áâ®â  ª ¤à®¢ ¢ëè¥ 60 ƒæ"
db " ⮫쪮 ¤«ï ¯¥à¥å®¤®¢:",13,10
db 186," 1024*768>800*600 ¨ 800*600>640*480) [1-¤ , 2-­¥â]: ",0
;askmouse db "Œëèì:" ; 186, " "
; db " [1] PS/2 (USB), [2] Com1, [3] Com2."
; db " ‚ë¡¥à¨â¥ ¯®àâ [1-3]: ",0
;no_com1 db 13,10,186," No COM1 mouse",0
;no_com2 db 13,10,186," No COM2 mouse",0
gr_acc db "Vesa 2.0+: ‚ª«îç¨âì MTRR ¤«ï ã᪮७¨ï £à ä¨ª¨? "
db "[1-¤ /2-­¥â]: ",0
;gr_direct db 186," ˆá¯®«ì§®¢ âì «¨­¥©­ë© ¢¨¤¥®¡ãä¥à? "
; db "[1-¤ /2-­¥â]: ",0
;mem_model db 13,10,186," Ž¡ê+¬ ¯ ¬ï⨠[1-16 Mb / 2-32 Mb / "
; db "3-64Mb / 4-128 Mb / 5-256 Mb]: ",0
;bootlog db 13,10,186," à®á¬®âà¥âì ¦ãà­ « § £à㧪¨? [1-­¥â/2-¤ ]: ",0
bdev db "‡ £à㧨âì ®¡à § ¨§ [1-¤¨áª¥â ; 2-C:\kolibri.img (FAT32);"
db 13,10,186," "
db "3-¨á¯®«ì§®¢ âì 㦥 § £à㦥­­ë© ®¡à §]: ",0
probetext db 13,10,13,10,186," ‘â ­¤ àâ­ë© ¢¨¤¥®à¥¦¨¬? [1-¤ , "
db "2-¯à®¢¥à¨âì ¤à㣨¥ (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 "Žè¨¡ª  - ‚¨¤¥®à¥¦¨¬ ­¥ ­ ©¤¥­.",0
;modena db "Žè¨¡ª  - ’ॡã¥âáï ¯®¤¤¥à¦ª  VBE 0x112+.",0
not386 db "Žè¨¡ª  - ’ॡã¥âáï ¯à®æ¥áá®à 386+.",0
btns db "Žè¨¡ª  - ¥ ¬®£ã ®¯à¥¤¥«¨âì £«ã¡¨­ã 梥â .",0
fatalsel 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
mode1 db "640x480",0
mode2 db "800x600",0
mode3 db "1024x768",0
mode4 db "1280x1024",0
modes_msg dw mode4-0x10000,mode1-0x10000,mode2-0x10000,mode3-0x10000
modevesa20 db " á LFB",0
modevesa12 db ", VESA 1.2 Bnk",0
mode9 db "320x200, EGA/CGA 256 梥⮢",0
mode10 db "640x480, VGA 16 梥⮢",0
probeno_msg db " (áâ ­¤ àâ­ë© ¢¨¤¥®à¥¦¨¬)",0
probeok_msg db " (¯à®¢¥à¨âì ­¥áâ ­¤ àâ­ë¥ ०¨¬ë)",0
mtrr_msg db " [b] ˆá¯®«ì§®¢ ­¨¥ MTRR ¤«ï ã᪮७¨ï £à ä¨ª¨:",0
on_msg db " ¢ª«",13,10,0
off_msg db " ¢ëª«",13,10,0
vrrm_msg db " [c] ˆá¯®«ì§®¢ ­¨¥ VRR:",0
preboot_device_msg db " [d] Ž¡à § ¤¨áª¥âë: ",0
preboot_device_msgs dw 0,pdm1-0x10000,pdm2-0x10000,pdm3-0x10000
pdm1 db "­ áâ®ïé ï ¤¨áª¥â ",13,10,0
pdm2 db "C:\kolibri.img (FAT32)",13,10,0
pdm3 db "¨á¯®«ì§®¢ âì 㦥 § £à㦥­­ë© ®¡à §",13,10,0
loading_msg db "ˆ¤ñâ § £à㧪  KolibriOS...",0
save_quest db "‡ ¯®¬­¨âì ⥪ã騥 ­ áâனª¨? [y/n]: ",0
loader_block_error db "Žè¨¡ª  ¢ ¤ ­­ëå ­ ç «ì­®£® § £àã§ç¨ª , ¯à®¤®«¦¥­¨¥ ­¥¢®§¬®¦­®.",0
/kernel/tags/kolibri0.6.3.0/boot/preboot.inc
0,0 → 1,23
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 db 0 ; graph mode
preboot_gprobe db 0 ; probe vesa3 videomodes (1-no, 2-yes)
preboot_vrrm db 0 ; use VRR_M (1-yes, 2- no)
preboot_mtrr db 0 ; mtrr acceleration (1-yes, 2-no)
preboot_device db 0 ; boot device
; (1-floppy 2-harddisk 3-kernel restart)
;!!!! 0 - autodetect !!!!
preboot_blogesc db 1 ; start immediately after bootlog
 
if $>10200h
ERROR: prebooting parameters must fit in first sector!!!
end if
hdsysimage db 'KOLIBRI IMG' ; load from
image_save db 'KOLIBRI IMG' ; save to
/kernel/tags/kolibri0.6.3.0/boot/bootcode.inc
0,0 → 1,1393
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; BOOTCODE.INC ;;
;; ;;
;; KolibriOS 16-bit loader, ;;
;; based on bootcode for MenuetOS ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
 
;==========================================================================
;
; 16 BIT FUNCTIONS
;
;==========================================================================
 
; 16-bit data
org $+0x10000
 
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
 
 
align 32
 
; GDT TABLE
 
gdts:
 
dw gdte-$-1
dd gdts
dw 0
 
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
 
; --------------- APM ---------------------
apm_code_32:
dw 0x10 ; limit 64kb
db 0, 0, 0
dw 11010000b *256 +10011010b
db 0x00
apm_code_16:
dw 0x10
db 0, 0, 0
dw 10010000b *256 +10011010b
db 0x00
apm_data_16:
dw 0x10
db 0, 0, 0
dw 10010000b *256 +10010010b
db 0x00
; -----------------------------------------
 
app_code_l:
dw 0xFFFF;((0x80000000-std_application_base_address) shr 12) and 0xffff
dw 0
db 0x40
db cpl3
dw G32+D32+0x6000+0x7;
 
app_data_l:
dw 0xFFFF;(0x80000000-std_application_base_address) shr 12 and 0xffff
dw 0
db 0x40
db drw3
dw G32+D32+0x6000+0x7;
 
graph_data_l:
 
dw 0x3ff
dw 0x0000
db 0x00
dw 11010000b *256 +11110010b
db 0x00
 
tss0_l:
; times (max_processes+10) dd 0,0
gdte = $ + (max_processes+10)*8
 
; videomodes table
gr_table:
dw 0x112+0100000000000000b , 640 , 480 ; 1
dw 0x115+0100000000000000b , 800 , 600 ; 2
dw 0x118+0100000000000000b , 1024 , 768 ; 3
dw 0x11B+0100000000000000b , 1280 , 1024 ; 4
dw 0x112 , 640 , 480 ; 5
dw 0x115 , 800 , 600 ; 6
dw 0x118 , 1024 , 768 ; 7
dw 0x11B , 1280 ,1024 ; 8
dw 0x13, 640, 480 ; 9
dw 0x12, 640, 480 ; 0
 
; table for move to extended memory (int 15h, ah=87h)
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
org $-0x10000
 
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
 
; Now int 16 is used for keyboard support.
; This is shorter, simpler and more reliable.
if 0
getkey: push ecx
push edx
add ebx,0x0101
xor eax,eax
 
gk1:
in al,0x60
mov cl,al
gk0:
in al,0x60
cmp al,cl
je gk0
cmp ax,11
jg gk0
gk0_1:
mov cl,al
 
; add al,47
; mov [ds:keyinbs-0x10000],al
; mov si,keyinbs-0x10000
; call printplain
 
gk12:
in al,0x60
cmp al,cl
je gk12
cmp ax,240
jne gk13
mov al,cl
jmp gk14
gk13:
add cl,128
cmp al,cl
jne gk1
sub al,128
gk14:
 
movzx edx,bl
cmp eax,edx
jb gk1
movzx edx,bh
cmp eax,edx
jg gk1
test ebx,0x010000
jnz gk3
mov cx,0x1000
mov dx,cx
add eax,47
mov cx,ax
cmp cx,58
jb gk_nozero
sub cx,10
gk_nozero:
mov [ds:keyin-0x10000],cl
mov si,keyin-0x10000
call printplain
gk3:
sub eax,48
pop edx
pop ecx
ret
end if
 
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
}
 
;pagetable_set:
;eax - physical address
;es:di - page table
;ecx - number of pages to map
; or al, 7
;@@:
; stosd
; add eax, 1000h
; loop @b
; ret
 
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-0x10000
sayerr_plain:
call printplain
jmp $
@@:
pop si
ret
 
;=========================================================================
;
; 16 BIT CODE
;
;=========================================================================
 
 
start_of_code:
cld
; \begin{diamond}[02.12.2005]
cmp ax, 'KL'
jnz @f
mov word [cs:cfgmanager.loader_block-0x10000], si
mov word [cs:cfgmanager.loader_block+2-0x10000], ds
@@:
; \end{diamond}[02.12.2005]
 
; 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-10000h ; 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-10000h ; 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
end if
 
; draw frames
push 0xb800
pop es
xor di, di
; mov si,d80x25-0x10000
; mov cx,80*25
; mov ah,1*16+15
; dfl1:
; lodsb
; stosw
; loop dfl1
mov ah, 1*16+15
; draw top
mov si, d80x25_top - 0x10000
mov cx, d80x25_top_num * 80
@@:
lodsb
stosw
loop @b
; draw spaces
mov si, space_msg - 0x10000
mov cx, 25 - d80x25_top_num - d80x25_bottom_num
dfl1:
push cx
push si
mov cx, 80
@@:
lodsb
stosw
loop @b
pop si
pop cx
loop dfl1
; draw bottom
mov si, d80x25_bottom - 0x10000
mov cx, d80x25_bottom_num * 80
@@:
lodsb
stosw
loop @b
 
mov byte [space_msg-0x10000+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-0x10000
sayerr:
call print
jmp $
cpugood:
 
; set up esp
movzx esp, sp
 
; FLUSH 8042 KEYBOARD CONTROLLER
 
;// mike.dld [
; mov al,0xED
; out 0x60,al
; or cx,-1
; @@:
; in al,0x64
; test al,2
; jz @f
; loop @b
; @@:
; mov al,0
; out 0x60,al
; or cx,-1
; @@:
; in al,0x64
; test al,2
; jz @f
; loop @b
; @@:
;// mike.dld ]
 
; mov ecx,10000
; fl1:
; in al,0x64
; loop fl1
; test al,1
; jz fl2
; in al,0x60
; jmp fl1
; fl2:
 
;****************************************************************
; The function is modified Mario79
;*****************************************************************
; wait_kbd: ; variant 1
; mov cx,2500h ;çàäåðæêà ïîðÿäêà 10 ìñåê
; test_kbd:
; in al,64h ;÷èòàåì ñîñòîÿíèå êëàâèàòóðû
; test al,2 ;ïðîâåðêà áèòà ãîòîâíîñòè
; loopnz test_kbd
 
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
mov si, 0 ; 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
mov si, 0 ; 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
mov si, 0
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
 
; --------------- APM ---------------------
push 0
pop es
mov 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 - 0x10000
mov [si + 5], ah
mov [si + 7], al
_setcursor 0, 3
call printplain
_setcursor d80x25_top_num,0
; ------------------
 
mov ax, 0x5304 ; Disconnect interface
xor bx, bx
int 0x15
mov ax, 0x5303 ; Connect 32 bit mode interface
xor bx, bx
int 0x15
; init selectors
movzx eax, ax ; real-mode segment base address of protected-mode 32-bit code segment
shl eax, 4
mov [apm_code_32 - 0x10000 + 2], ax
shr eax, 16
mov [apm_code_32 - 0x10000 + 4], al
movzx ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment
shl ecx, 4
mov [apm_code_16 - 0x10000 + 2], cx
shr ecx, 16
mov [apm_code_16 - 0x10000 + 4], cl
movzx edx, dx ; real-mode segment base address of protected-mode 16-bit data segment
shl edx, 4
mov [apm_data_16 - 0x10000 + 2], dx
shr edx, 16
mov [apm_data_16 - 0x10000 + 4], dl
mov [es : 0x9040], ebx ; offset of APM entry point
apm_end:
; -----------------------------------------
 
; DISPLAY VESA INFORMATION
 
push 0
pop es
mov ax,0x4f00
mov di,0xa000
int 0x10
cmp ax,0x004f
mov si, novesa-0x10000
jnz @f
mov bx, word [es:di+0x12]
shl ebx,16
mov [es:0x9050], ebx
mov ax,[es:di+4]
add ax,'0'*256+'0'
mov si,vervesa-0x10000
mov [si+vervesa_off], ah
mov [si+vervesa_off+2], al
@@: call print
 
; \begin{diamond}[30.11.2005]
cfgmanager:
; settings:
; a) preboot_graph = graphical mode
; preboot_gprobe = probe this mode?
; b) preboot_mtrr = use hardware acceleration?
; c) preboot_vrrm = use VRR?
; d) preboot_device = from what boot?
mov di, preboot_graph-0x10000
; check bootloader block
cmp [.loader_block-0x10000], -1
jz .noloaderblock
les bx, [.loader_block-0x10000]
cmp byte [es:bx], 1
mov si, loader_block_error-0x10000
jnz sayerr
test byte [es:bx+1], 1
jz @f
; image in memory present
cmp [di+preboot_device-preboot_graph], 0
jnz @f
mov [di+preboot_device-preboot_graph], 3
@@:
.noloaderblock:
; determine default settings
mov [.bSettingsChanged-0x10000], 0
cmp byte [di], 0
jnz .preboot_gr_end
mov [di+preboot_gprobe-preboot_graph], 0
mov al, [vervesa+vervesa_off-0x10000]
cmp al, 'x'
jz .novesa
cmp al, '1'
jz .vesa12
mov [di+preboot_gprobe-preboot_graph], 2
mov al, 3
jmp @f
.vesa12:
mov al, 7
jmp @f
.novesa:
mov al, 10
@@:
mov [di], al
.preboot_gr_end:
cmp [di+preboot_mtrr-preboot_graph], 1
adc [di+preboot_mtrr-preboot_graph], 0
cmp [di+preboot_vrrm-preboot_graph], 1
adc [di+preboot_vrrm-preboot_graph], 0
cmp [di+preboot_device-preboot_graph], 1
adc [di+preboot_device-preboot_graph], 0
; notify user
mov si, linef-0x10000
call print
mov si, start_msg-0x10000
call print
mov si, time_msg-0x10000
call print
; get start time
call .gettime
mov [.starttime-0x10000], eax
mov word [.timer-0x10000], .newtimer
mov word [.timer-0x10000+2], cs
.printcfg:
_setcursor 9,0
mov si, current_cfg_msg-0x10000
call print
mov si, curvideo_msg-0x10000
call print
mov al, [preboot_graph-0x10000]
cmp al, 8
ja .pnovesa
mov dl, al
and eax, 3
mov si, [modes_msg-0x10000+eax*2]
call printplain
mov si, modevesa20-0x10000
cmp dl, 4
jbe @f
mov si, modevesa12-0x10000
@@:
call printplain
cmp dl, 4
ja .x
mov si, probeno_msg-0x10000
cmp [preboot_gprobe-0x10000], 2
jnz @f
mov si, probeok_msg-0x10000
@@:
call printplain
.x:
jmp .c
.pnovesa:
cmp al, 9
mov si, mode9-0x10000
jz @b
mov si, mode10-0x10000
jmp @b
.c:
mov si, linef-0x10000
call printplain
mov si, mtrr_msg-0x10000
cmp [preboot_mtrr-0x10000], 1
call .say_on_off
mov si, vrrm_msg-0x10000
cmp [preboot_vrrm-0x10000], 1
call .say_on_off
mov si, preboot_device_msg-0x10000
call print
mov al, [preboot_device-0x10000]
and eax, 3
mov si, [preboot_device_msgs-0x10000+eax*2]
call printplain
.wait:
_setcursor 25,0 ; out of screen
; set timer interrupt handler
cli
push 0
pop es
mov eax, [es:8*4]
mov [.oldtimer-0x10000], eax
mov eax, [.timer-0x10000]
mov [es:8*4], eax
sti
; wait for keypressed
mov ah, 0
int 16h
push ax
; restore timer interrupt
push 0
pop es
mov eax, [.oldtimer-0x10000]
mov [es:8*4], eax
mov [.timer-0x10000], eax
_setcursor 7,0
mov si, space_msg-0x10000
call printplain
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 .wait
_setcursor 15,0
mov si,bdev-0x10000
call print
mov bx,'13'
call getkey
mov [preboot_device-0x10000], al
_setcursor 13,0
.d:
mov [.bSettingsChanged-0x10000], 1
mov si, space_msg-0x10000
call printplain
_setcursor 15,0
mov cx, 6
@@:
call printplain
loop @b
jmp .printcfg
.change_a:
_setcursor 15,0
mov si, gr_mode-0x10000
call printplain
mov bx, '09'
call getkey
mov [preboot_graph-0x10000], al
cmp al, 4
ja @f
mov si, probetext-0x10000
call printplain
mov bx, '12'
call getkey
mov [preboot_gprobe-0x10000], al
@@:
_setcursor 10,0
jmp .d
.change_b:
_setcursor 15,0
mov si, gr_acc-0x10000
call print
mov bx, '12'
call getkey
mov [preboot_mtrr-0x10000], al
_setcursor 11,0
jmp .d
.change_c:
_setcursor 15,0
mov si, vrrmprint-0x10000
call print
mov bx, '12'
call getkey
mov [preboot_vrrm-0x10000], al
_setcursor 12,0
jmp .d
.say_on_off:
pushf
call print
mov si, on_msg-0x10000
popf
jz @f
mov si, off_msg-0x10000
@@: call printplain
ret
; 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
org $+0x10000
.loader_block dd -1
org $-0x10000
.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-0x10000]
pushad
call .gettime
sub eax, [.starttime-0x10000]
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-0x10000], cl
else
; wait 5/4/3/2 seconds, 1 second
cmp al, 1
mov cl, 's'
ja @f
mov cl, ' '
@@: mov [time_str+9-0x10000], cl
end if
add al, '0'
mov [time_str+1-0x10000], al
mov si, time_msg-0x10000
_setcursor 7,0
call print
_setcursor 25,0
popad
pop ds
iret
.timergo:
push 0
pop es
mov eax, [.oldtimer-0x10000]
mov [es:8*4], eax
mov sp, 0EC00h
.continue:
sti
_setcursor 6,0
mov si, space_msg-0x10000
call printplain
call printplain
_setcursor 6,0
mov si, loading_msg-0x10000
call print
_setcursor 15,0
cmp [.bSettingsChanged-0x10000], 0
jz .load
cmp [.loader_block-0x10000], -1
jz .load
les bx, [.loader_block-0x10000]
mov eax, [es:bx+3]
push ds
pop es
test eax, eax
jz .load
push eax
mov si, save_quest-0x10000
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-0x10000+80], 186
pop eax
push cs
push .cont
push eax
retf
.loadc:
pop eax
.cont:
push cs
pop ds
mov si, space_msg-0x10000
mov byte [si+80], 0
_setcursor 15,0
call printplain
_setcursor 15,0
.load:
; \end{diamond}[02.12.2005]
 
; ASK GRAPHICS MODE
 
movzx ax, [preboot_graph-0x10000]
push 0
pop es
; address is gr_table+6*(ax-1)-0x10000
add ax, ax
lea si, [gr_table-0x10000 + eax + eax*2 - 6]
mov bx,[si+0]
mov cx,[si+2]
mov dx,[si+4]
cmp al, 9*2
mov al, 32 ; BPP
jb @f
mov [es:0x9000], al
mov dword [es:0x9018], 0xFFFFFFFF; 0x800000
@@:
mov [es:0x9008],bx
mov [es:0x900A],cx
mov [es:0x900C],dx
test bh, bh
jz nov
 
; USE DEFAULTS OR PROBE
 
; bx - mode : cx - x size : dx - y size
cmp [preboot_gprobe-0x10000], 1
jz noprobe
 
mov bx,0x100
newprobe:
inc bx
cmp bx,0x17f
mov si,prnotfnd-0x10000
jz sayerr
 
probemore:
push cx
mov ax,0x4f01
mov cx,bx
and cx,0xfff
mov di,0xa000
int 0x10
pop cx
 
test byte [es:di], 80h ; lfb?
jz newprobe
cmp [es:di+0x12], cx ; x size?
jnz newprobe
cmp [es:di+0x14], dx ; y size?
jnz newprobe
cmp byte [es:di+0x19], 32 ;24
jb newprobe
 
; add bx,0100000000000000b
or bh, 40h
mov [es:0x9008],bx
 
noprobe:
 
 
; FIND VESA 2.0 LFB & BPP
 
mov ax,0x4f01
mov cx,bx
and cx,0xfff
mov di,0xa000
int 0x10
; LFB
mov eax,[es:di+0x28]
mov [es:0x9018],eax
; ---- vbe voodoo
BytesPerScanLine equ 0x10
mov ax, [es:di+BytesPerScanLine]
mov [es:0x9001],ax
; BPP
mov al,byte [es:di+0x19]
mov [es:0x9000],al
nov:
cmp al,24
mov si,bt24-0x10000
jz bppl
cmp al,32
mov si,bt32-0x10000
jz bppl
mov si,btns-0x10000
jmp sayerr
bppl:
call print
 
 
; FIND VESA 1.2 PM BANK SWITCH ADDRESS
 
push es
mov ax,0x4f0A
xor bx, bx
int 0x10
xor eax,eax
mov ax,es
shl eax,4
movzx ebx,di
add eax,ebx
mov bx,[es:di]
add eax,ebx
pop es
mov [es:0x9014],eax
 
 
; GRAPHICS ACCELERATION
 
mov al, [preboot_mtrr-0x10000]
mov [es:0x901C],al
 
; VRR_M USE
 
mov al,[preboot_vrrm-0x10000]
mov [es:0x9030],al
 
 
; MEMORY MODEL
 
; movzx eax,byte [es:preboot_memory-0x10000]
; cmp eax,0
; jne pre_mem
;;;;;;;;;;;;;;;;;;;;;;;;;
; mario79 - memory size ;
;;;;;;;;;;;;;;;;;;;;;;;;;
; mov ax,0E801h
;;; xor bx,bx ; thanks to Alexei for bugfix [18.07.2004]
; xor cx, cx
; xor dx, dx
; int 0x15
; movzx ebx, dx ;bx
; movzx eax, cx ;ax
; shl ebx,6 ; ïåðåâîä â êèëîáàéòû (x64)
; add eax,ebx
; add eax, 1000h ;440h
; cmp eax,40000h ; 256?
; jge mem_256_z
; cmp eax,20000h ; 128?
; jge mem_128_z
; cmp eax,10000h ; 64?
; jge mem_64_z
; cmp eax,8000h ; 32?
; jge mem_32_z
; jmp mem_16_z
;
;mem_256_z: mov si,memokz256-0x10000
; call printplain
; mov eax,5
; jmp pre_mem
;mem_128_z: mov si,memokz128-0x10000
; call printplain
; mov eax,4
; jmp pre_mem
;mem_64_z: mov si,memokz64-0x10000
; call printplain
; mov eax,3
; jmp pre_mem
;mem_32_z: mov si,memokz32-0x10000
; call printplain
; mov eax,2
; jmp pre_mem
;mem_16_z: mov si,memokz16-0x10000
; call printplain
; mov eax,1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; pre_mem:
; push word 0x0000
; pop es
; mov [es:0x9030],al
; push word 0x1000
; pop es
; mov si,linef-0x10000
; call printplain
 
 
 
 
; DIRECT WRITE TO LFB, PAGING DISABLED
 
; movzx eax,byte [es:preboot_lfb-0x10000]
; mov eax,1 ; paging disabled
; cmp eax,0
; jne pre_lfb
; mov si,gr_direct-0x10000
; call printplain
; mov ebx,'12'
; call getkey
; pre_lfb:
; push word 0x0000
; pop es
; mov [es:0x901E],al
; mov ax,0x1000
; mov es,ax
; mov si,linef-0x10000
; call printplain
mov [es:0x901E],byte 1
 
 
 
; BOOT DEVICE
 
mov al, [preboot_device-0x10000]
dec al
mov [boot_dev-0x10000],al
 
; READ DISKETTE TO MEMORY
 
; cmp [boot_dev-0x10000],0
jne no_sys_on_floppy
mov si,diskload-0x10000
call print
xor ax, ax ; reset drive
xor dx, dx
int 0x13
; now load floppy image to memory
; at first load boot sector and first FAT table
mov cx, 0x0001 ; startcyl,startsector
xor dx, dx ; starthead,drive
mov al, 1+9 ; no of sectors to read
mov bx, 0xB000 ; es:bx -> data area
call boot_read_floppy
; and copy them to extended memory
mov si, movedesc-0x10000
mov [si+8*2+3], bh
push es
push ds
pop es
mov cx, 256*10
mov ah, 0x87
int 0x15
test ah, ah
jz @f
sayerr_floppy:
mov dx, 0x3f2
mov al, 0
out dx, al
mov si, memmovefailed-0x10000
jmp sayerr_plain
@@:
add dword [si+8*3+2], 512*10
; copy FAT to second copy
mov byte [si+8*2+3], 0xB2
mov cx, 256*9
mov ah, 0x87
int 0x15
pop es
test ah, ah
jnz sayerr_floppy
add dword [si+8*3+2], 512*9
; calculate total number of sectors to read
mov ax, 1+9+14 ; boot+FAT+root
mov di, 0xB203
.calc_loop:
test word [es:di], 0xFFF
jz @f
inc ax
@@:
test word [es:di+1], 0xFFF0
jz @f
inc ax
@@:
add di, 3
cmp di, 0xB200+1440*3
jb .calc_loop
push ax
mov bp, 1+9 ; already read sectors
; now read rest
mov byte [si+8*2+3], 0xA0
mov di, 2-14 ; absolute sector-31
mov cx, 0x0002 ; cylinder=0, sector=2
mov dx, 0x0100 ; head=1, disk=0
.read_loop:
; determine whether sector must be read
cmp di, 2
jl .read
mov bx, di
shr bx, 1
jnc .even
test word [es:bx+di+0xB200], 0xFFF0
jmp @f
.even:
test word [es:bx+di+0xB200], 0xFFF
@@:
jz .skip
.read:
mov bx, 0xA000
mov al, 1 ; 1 sector
call boot_read_floppy
inc bp
push es
push ds
pop es
pusha
mov cx, 256
mov ah, 0x87
int 0x15
test ah, ah
popa
pop es
jnz sayerr_floppy
.skip:
add dword [si+8*3+2], 512
inc cx
cmp cl, 19
jnz @f
mov cl, 1
inc dh
cmp dh, 2
jnz @f
mov dh, 0
inc ch
@@:
pop ax
push ax
pusha
; draw percentage
; total sectors: ax
; read sectors: bp
xchg ax, bp
mov cx, 100
mul cx
div bp
aam
xchg al, ah
add ax, '00'
mov si, pros-0x10000
cmp [si], ax
jz @f
mov [si], ax
call printplain
@@:
popa
inc di
cmp di, 2880-31
jnz .read_loop
 
; mov cx, 0x0001 ; startcyl,startsector
; xor dx, dx ; starthead,drive
; push word 80*2 ; read no of sect
; reads:
; pusha
; xor si,si
; newread:
; mov bx,0xa000 ; es:bx -> data area
; mov ax,0x0200+18 ; read, no of sectors to read
; int 0x13
; test ah, ah
; jz goodread
; inc si
; cmp si,10
; jnz newread
; mov si,badsect-0x10000
;sayerr_plain:
; call printplain
; jmp $
; goodread:
; ; move -> 1mb
; mov si,movedesc-0x10000
; push es
; push ds
; pop es
; mov cx,256*18
; mov ah,0x87
; int 0x15
; pop es
;
; test ah,ah ; was the move successfull ?
; je goodmove
; mov dx,0x3f2 ; floppy motor off
; mov al,0
; out dx,al
; mov si,memmovefailed-0x10000
; jmp sayerr_plain
; goodmove:
;
; add dword [movedesc-0x10000+0x18+2], 512*18
; popa
; inc dh
; cmp dh,2
; jnz bb2
; mov dh,0
; inc ch
; pusha ; print prosentage
; mov si,pros-0x10000
; shr ch, 2
; mov al, '5'
; test ch, 1
; jnz @f
; mov al, '0'
;@@:
; mov [si+1], al
; shr ch, 1
; add ch, '0'
; mov [si], ch
; call printplain
; popa
; bb2:
; pop ax
; dec ax
; push ax
; jnz reads
; readdone:
; pop ax
mov si,backspace2-0x10000
call printplain
mov si,okt-0x10000
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
 
push es
; PAGE TABLE
 
push dword [es:0x9018]
;
; mmap_mem equ 64 ; amount of memory to map
;
push 0x6000
pop es ; es:di = 6000:0
; xor di,di
; mov cx,256*mmap_mem ; Map (mapmem) M
;; initialize as identity mapping
; xor eax, eax
; call pagetable_set
;
;
; 4 KB PAGE DIRECTORY
;
push 0x7F00
pop es ; es:di = 7F00:0
; xor di, di
; mov cx, 64 / 4
; mov eax, 0x60007 ; for 0 M
; call pagetable_set
; xor si,si
; mov di,second_base_address shr 20
; mov cx,64/2
; rep movs word [es:di], [es:si]
 
; mov eax, 0x7F000 +8+16 ; Page directory and enable caches
; mov cr3, eax
 
; SET GRAPHICS
 
pop es
 
xor ax, ax
mov es, ax
 
mov ax,[es:0x9008] ; vga & 320x200
mov bx, ax
cmp ax,0x13
je setgr
cmp ax,0x12
je setgr
mov ax,0x4f02 ; Vesa
setgr:
int 0x10
test ah,ah
mov si, fatalsel-0x10000
jnz sayerr
; 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
/kernel/tags/kolibri0.6.3.0/boot/shutdown.inc
0,0 → 1,521
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Shutdown for Menuet
;;
;; Distributed under General Public License
;; See file COPYING for details.
;; Copyright 2003 Ville Turjanmaa
;;
 
 
system_shutdown: ; shut down the system
 
push 3 ; stop playing cd
pop eax
call sys_cd_audio
cld
 
mov al,[0x2f0000+0x9030]
cmp al,1
jl no_shutdown_parameter
cmp al,4
jle yes_shutdown_param
no_shutdown_parameter:
 
; movzx ecx,word [0x2f0000+0x900A]
; movzx esi,word [0x2f0000+0x900C]
; imul ecx,esi ;[0xfe04]
;; mov ecx,0x500000/4 ;3fff00/4 ; darken screen
; push ecx
; mov esi,[0xfe80]
; cmp esi,32*0x100000
; jbe no_darken_screen
; mov edi,16*0x100000
; push esi edi
; sdnewpix:
; lodsd
; shr eax,1
; and eax,0x7f7f7f7f
; stosd
; loop sdnewpix
; pop ecx
; pop esi edi
; rep movsd
; no_darken_screen:
 
; read shutdown code:
; 1) display shutdown "window"
 
mov eax,[0xfe00]
shr eax,1
lea esi,[eax+220] ; x end
sub eax,220 ; x start
 
mov ebx,[0xfe04]
shr ebx,1
mov [shutdownpos],ebx
lea ebp,[ebx+105] ; y end
sub ebx,120 ; y start
 
xor edi,edi
inc edi ; force putpixel & dtext
mov ecx,0x0000ff
 
; vertical loop begin
sdnewpix1:
push eax ; save x start
 
; horizontal loop begin
sdnewpix2:
 
call [putpixel]
 
inc eax
cmp eax,esi
jnz sdnewpix2
; horizontal loop end
 
dec ecx ; color
pop eax ; restore x start
 
inc ebx ; advance y pos
cmp ebx,ebp
jnz sdnewpix1
; vertical loop end
 
; 2) display text strings
; a) version
mov eax,[0xfe00]
shr eax,1
shl eax,16
mov ax,word [shutdownpos]
push eax
sub eax,(220-27)*10000h + 105
mov ebx,0xffff00
mov ecx,version
push 34
pop edx
call dtext
 
; b) variants
add eax,105+33
push 6
pop esi
; mov ebx,0xffffff
mov bl,0xFF
mov ecx,shutdowntext
mov dl,40
newsdt:
call dtext
add eax,10
add ecx,edx
dec esi
jnz newsdt
 
; 3) load & display rose.txt
mov eax,rosef ; load rose.txt
xor ebx,ebx
push 2
pop ecx
mov edx,0x90000
push edx
push 12
pop esi
push edi ; may be destroyed
call fileread
pop edi
 
pop ecx
inc ecx ; do not display stars from rose.txt
pop eax
add eax,20*10000h - 110
 
mov ebx,0x00ff00
push 27
pop edx
 
nrl:
call dtext
; sub ebx,0x050000
ror ebx, 16
sub bl, 0x05
ror ebx, 16
add eax,8
add ecx,31
cmp cx,word 0x0001+25*31
jnz nrl
 
call checkVga_N13
 
yes_shutdown_param:
cli
 
mov eax,kernel ; load kernel.mnt to 0x8000:0
push 12
pop esi
xor ebx,ebx
or ecx,-1
mov edx,0x80000
call fileread
 
mov esi,restart_kernel_4000+0x10000 ; move kernel re-starter to 0x4000:0
mov edi,0x40000
mov ecx,1000
rep movsb
 
mov eax,0x2F0000 ; restore 0x0 - 0xffff
xor ebx,ebx
mov ecx,0x10000
call memmove
 
call restorefatchain
 
mov word [0x467+0],pr_mode_exit-0x10000
mov word [0x467+2],0x1000
 
mov al,0x0F
out 0x70,al
mov al,0x05
out 0x71,al
 
mov al,0xFE
out 0x64,al
hlt
 
use16
 
pr_mode_exit:
org $-0x10000
 
; setup stack
mov ax, 3000h
mov ss, ax
mov esp, 0EC00h
; setup ds
push cs
pop ds
 
lidt [old_ints_h-0x10000]
;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,0
out 0x21,al
call rdelay
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
call pause_key
cmp al,6
jae nbw
mov bl,al
nbw2:
in al,0x60
call pause_key
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 ; 1 = write floppy
js nbw
jnz no_floppy_write
call floppy_write
jmp temp_3456 ;nbw
no_floppy_write:
 
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
 
pause_key:
mov cx,100
pause_key_1:
loop pause_key_1
ret
 
rdelay:
ret
 
iglobal
kernel db 'KERNEL MNT'
; shutdown_parameter db 0
endg
 
restart_kernel:
 
mov ax,0x0003 ; set text mode for screen
int 0x10
 
jmp 0x4000:0000
 
 
restart_kernel_4000:
cli
 
; mov di,0x1000 ; load kernel image from 0x8000:0 -> 0x1000:0
;
; new_kernel_block_move:
;
; mov ebx,0
;
; new_kernel_byte_move:
;
; mov ax,di
; add ax,0x7000
; mov es,ax
; mov dl,[es:bx]
; mov es,di
; mov [es:bx],dl
;
; inc ebx
; cmp ebx,65536
; jbe new_kernel_byte_move
;
; add di,0x1000
; cmp di,0x2000
; jbe new_kernel_block_move
push ds
pop es
mov cx, 0x8000
push cx
mov ds, cx
xor si, si
xor di, di
rep movsw
push 0x9000
pop ds
push 0x2000
pop es
pop cx
rep movsw
 
wbinvd ; write and invalidate cache
 
; mov ax,0x1000
; mov es,ax
; mov ax,0x3000
; mov ss,ax
; mov sp,0xec00
; restore timer
mov al, 00110100b
out 43h, al
jcxz $+2
mov al, 0xFF
out 40h, al
jcxz $+2
out 40h, al
jcxz $+2
sti
 
; bootloader interface
push 0x1000
pop ds
mov si, kernel_restart_bootblock-0x10000
mov ax, 'KL'
jmp 0x1000:0000
 
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
;!!!!!!!!!!!!!!!!!!!!!!!!
fwwritedone:
ret
org $+0x10000
flm db 0
org $-0x10000
 
floppy_write: ; write diskette image to physical floppy
 
cmp [flm-0x10000],byte 1
je fwwritedone
mov [flm-0x10000],byte 1
 
xor ax, ax ; reset drive
xor dx, dx
int 0x13
 
mov cx,0x0001 ; startcyl,startsector
; mov dx,0x0000 ; starthead,drive
xor dx, dx
mov ax, 80*2 ; read no of sect
 
fwwrites:
push ax
 
; move 1mb+ -> 0:a000
 
pusha
mov si,fwmovedesc -0x10000
mov cx,256*18
mov ah,0x87
push ds
pop es
int 0x15
add dword [fwmovedesc-0x10000+0x12], 512*18
popa
 
xor si,si
mov es,si
fwnewwrite:
mov bx,0xa000 ; es:bx -> data area
mov ax,0x0300+18 ; read, no of sectors to read
int 0x13
 
test ah, ah
jz fwgoodwrite
 
inc si
cmp si,10
jnz fwnewwrite
 
; can't access diskette - return
pop ax
ret
 
fwgoodwrite:
inc dh
cmp dh,2
jnz fwbb2
mov dh,0
inc ch
fwbb2:
pop ax
dec ax
jnz fwwrites
ret
org $+0x10000
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
org $-0x10000
use32
org $+0x10000
uglobal
shutdownpos dd 0x0
endg
 
iglobal
if lang eq en
shutdowntext:
db "IT'S SAFE TO POWER OFF COMPUTER OR "
db ' '
db '1) SAVE RAMDISK TO FLOPPY '
db '2) APM - POWEROFF '
db '3) REBOOT '
db '4) RESTART KERNEL '
else if lang eq ru
shutdowntext:
db "¥§®¯ á­®¥ ¢ëª«î祭¨¥ ª®¬¯ìîâ¥à  ¨«¨ "
db ' '
db '1) ‘®åà ­¨âì à ¬¤¨áª ­  ¤¨áª¥âã '
db '2) APM - ¢ëª«î祭¨¥ ¯¨â ­¨ï '
db '3) ¥à¥§ £à㧪  á¨á⥬ë '
db '4) ¥áâ àâ ï¤à  ¨§ Ž‡“ '
else
shutdowntext:
db "SIE KOENNEN DEN COMPUTER NUN AUSSCHALTEN"
db ' '
db '1) RAMDISK AUF DISK SPEICHERN '
db '2) APM - AUSSCHALTEN '
db '3) NEUSTARTEN '
db '4) KERNEL NEU STARTEN '
end if
rosef:
db 'ROSE TXT'
endg
/kernel/tags/kolibri0.6.3.0/boot/rdload.inc
0,0 → 1,95
; READ RAMDISK IMAGE FROM HD
 
cmp [boot_dev],1
jne no_sys_on_hd
 
test [0x40001],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 [0x40002]
cmp [fat32part],eax
jle position_1_1
position_2:
test [0x40001],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 [0x40003]
cmp eax,[fat32part]
jle position_2_1
position_3:
test [0x40001],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 [0x40004]
cmp eax,[fat32part]
jle position_3_1
position_4:
test [0x40001],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 [0x40005]
cmp eax,[fat32part]
jle position_4_1
jmp yes_sys_on_hd
 
search_and_read_image:
; mov [0xfe10],dword 0 ; entries in hd cache
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
mov ebx, 1474560/512
mov ecx, 0x100000
mov esi, 0
mov edi, 12
call file_read
ret
 
image_retrieved db 0
counter_of_partitions db 0
no_sys_on_hd:
yes_sys_on_hd:
/kernel/tags/kolibri0.6.3.0/boot/ru.inc
0,0 → 1,92
; 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/tags/kolibri0.6.3.0/kernel.asm
0,0 → 1,5053
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Kolibri OS - based on source code Menuet OS, but not 100% compatible.
;;
;; See file COPYING or GNU.TXT for details with these additional details:
;; - All code written in 32 bit x86 assembly language
;; - No external code (eg. bios) at process execution time
;;
;;
;; Compile with last version FASM
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
include "proc32.inc"
include "kglobals.inc"
include "lang.inc"
 
include "const.inc"
 
;WinMapAddress equ 0x460000
;display_data = 0x460000
 
max_processes equ 255
 
;window_data equ 0x0000
;tss_data equ 0xD20000
;tss_step equ (128+2048) ; tss & i/o - 16384 ports, * 256=557056
tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4
;draw_data equ 0xC00000
;sysint_stack_data equ 0xC03000
 
;twdw equ (0x3000-window_data)
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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
 
; mike.dld {
org $+0x10000
db 0
dd servetable-0x10000
draw_line dd __sys_draw_line
disable_mouse dd __sys_disable_mouse
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
 
version db 'Kolibri OS version 0.6.3.0 ',13,10,13,10,0
;dd endofcode-0x10000
 
;db 'Boot02'
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
include "boot/preboot.inc"
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
preboot_lfb db 0
preboot_bootlog db 0
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 16 BIT INCLUDED FILES ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
include "kernel16.inc"
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SWITCH TO 32 BIT PROTECTED MODE ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
os_data = os_data_l-gdts ; GDTs
os_code = os_code_l-gdts
int_code equ int_code_l-gdts
int_data equ int_data_l-gdts
tss0sys equ tss0sys_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
 
 
 
; CR0 Flags - Protected mode and Paging
 
mov ecx, CR0_PE
 
; Enabling 32 bit protected mode
 
sidt [cs:old_ints_h-0x10000]
 
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:gdts-0x10000] ; Load GDT
mov eax, cr0 ; Turn on paging // protected mode
or eax, ecx
and eax, 10011111b *65536*256 + 0xffffff ; caching enabled
mov cr0, eax
jmp $+2
org $+0x10000
mov ax,os_data ; Selector for os
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov esp,0x3ec00 ; Set stack
jmp pword os_code:B32 ; jmp to enable 32 bit mode
 
if gdte >= $
error 'GDT overlaps with used code!'
end if
 
use32
 
include 'unpacker.inc'
 
iglobal
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_pal_ega db 'Setting EGA/CGA 320x200 palette',0
boot_pal_vga db 'Setting VGA 640x480 palette',0
boot_mtrr db 'Setting MTRR',0
boot_tasking db 'All set - press ESC to start',0
endg
 
iglobal
boot_y dd 10
endg
 
boot_log:
pushad
 
mov eax,10*65536
mov ax,word [boot_y]
add [boot_y],dword 10
mov ebx,0x80ffffff ; ASCIIZ string with white color
mov ecx,esi
mov edi,1
call dtext
 
mov [novesachecksum],1000
call checkVga_N13
 
cmp [preboot_blogesc],byte 1
je .bll2
 
cmp esi,boot_tasking
jne .bll2
; begin ealex 04.08.05
; in al,0x61
; and al,01111111b
; out 0x61,al
; end ealex 04.08.05
.bll1: in al,0x60 ; wait for ESC key press
cmp al,129
jne .bll1
 
.bll2: popad
 
ret
 
iglobal
firstapp db '/rd/1/LAUNCHER',0
char db 'FONTS/CHAR.MT',0
char2 db 'FONTS/CHAR2.MT',0
bootpath db '/KOLIBRI '
bootpath2 db 0
vmode db 'VMODE MDR'
vrr_m db '/rd/1/VRR_M',0
endg
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 32 BIT ENTRY ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
align 4
 
B32:
; CLEAR 0x280000-0xF00000
 
xor eax,eax
mov edi,0x280000
mov ecx,(0x100000*0xF-0x280000) / 4
cld
rep stosd
; CLEAR 0x80000-0x90000
; xor eax,eax
mov edi,0x80000
mov ecx,(0x90000-0x80000)/4
; cld
rep stosd
 
; CLEAR KERNEL UNDEFINED GLOBALS
mov edi, endofcode
mov ecx, (uglobals_size/4)+4
rep stosd
 
; SAVE & CLEAR 0-0xffff
 
mov esi,0x0000
mov edi,0x2F0000
mov ecx,0x10000 / 4
cld
rep movsd
xor eax,eax
mov edi,0
mov ecx,0x10000 / 4
cld
rep stosd
 
; SAVE REAL MODE VARIABLES
mov ax, [0x2f0000 + 0x9031]
mov [IDEContrRegsBaseAddr], ax
; --------------- APM ---------------------
mov eax, [0x2f0000 + 0x9040] ; entry point
mov dword[apm_entry], eax
mov word [apm_entry + 4], apm_code_32 - gdts
 
mov eax, [0x2f0000 + 0x9044] ; version & flags
mov [apm_vf], eax
; -----------------------------------------
; movzx eax,byte [0x2f0000+0x9010] ; mouse port
; mov [0xF604],byte 1 ;al
mov al,[0x2f0000+0x9000] ; bpp
mov [0xFBF1],al
movzx eax,word [0x2f0000+0x900A] ; X max
dec eax
mov [0xfe00],eax
mov [screen_workarea.right],eax
movzx eax,word [0x2f0000+0x900C] ; Y max
dec eax
mov [0xfe04],eax
mov [screen_workarea.bottom],eax
movzx eax,word [0x2f0000+0x9008] ; screen mode
mov [0xFE0C],eax
mov eax,[0x2f0000+0x9014] ; Vesa 1.2 bnk sw add
mov [0xE030],eax
mov [0xfe08],word 640*4 ; Bytes PerScanLine
cmp [0xFE0C],word 0x13 ; 320x200
je @f
cmp [0xFE0C],word 0x12 ; VGA 640x480
je @f
mov ax,[0x2f0000+0x9001] ; for other modes
mov [0xfe08],ax
@@:
 
; GRAPHICS ADDRESSES
 
;mov eax,0x100000*8 ; LFB address
;cmp [0xfe0c],word 0x13
;je no_d_lfb
;cmp [0xfe0c],word 0x12
;je no_d_lfb
;cmp [0x2f0000+0x901e],byte 1
;jne no_d_lfb
mov byte [0x2f0000+0x901e],0x0
mov eax,[0x2f0000+0x9018]
;no_d_lfb:
mov [LFBAddress],eax
 
cmp [0xfe0c],word 0100000000000000b
jge setvesa20
cmp [0xfe0c],word 0x13
je v20ga32
mov [0xe020],dword Vesa12_putpixel24 ; Vesa 1.2
mov [0xe024],dword Vesa12_getpixel24
cmp [0xfbf1],byte 24
jz ga24
mov [0xe020],dword Vesa12_putpixel32
mov [0xe024],dword Vesa12_getpixel32
ga24:
jmp v20ga24
setvesa20:
mov [0xe020],dword Vesa20_putpixel24 ; Vesa 2.0
mov [0xe024],dword Vesa20_getpixel24
cmp [0xfbf1],byte 24
jz v20ga24
v20ga32:
mov [0xe020],dword Vesa20_putpixel32
mov [0xe024],dword Vesa20_getpixel32
v20ga24:
cmp [0xfe0c],word 0x12 ; 16 C VGA 640x480
jne no_mode_0x12
mov [0xe020],dword VGA_putpixel
mov [0xe024],dword Vesa20_getpixel32
no_mode_0x12:
 
; MEMORY MODEL
 
call mem_test
mov [MEM_AMOUNT], eax
 
mov [pg_data.mem_amount], eax
mov [pg_data.kernel_max], eax
 
shr eax, 12
mov edx, eax
mov [pg_data.pages_count], eax
mov [pg_data.kernel_pages], eax
 
shr eax, 3
mov [pg_data.pagemap_size], eax
 
shr edx, 10
cmp edx, 4
ja @f
inc edx ;at least 4Mb for kernel heap
@@:
mov [pg_data.kernel_tables], edx
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!
include 'detect/disks.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!!
 
; CHECK EXTRA REGION
; ENABLE PAGING
 
call test_cpu
; btr [cpu_caps], CAPS_SSE ;test: dont't use sse code
; btr [cpu_caps], CAPS_SSE2 ;test: don't use sse2
 
; btr [cpu_caps], CAPS_FXSR ;test: disable sse support
;all sse commands rise #UD exption
; btr [cpu_caps], CAPS_PSE ;test: don't use large pages
; btr [cpu_caps], CAPS_PGE ;test: don't use global pages
; btr [cpu_caps], CAPS_MTRR ;test: don't use MTRR
; btr [cpu_caps], CAPS_TSC ;test: don't use TSC
 
call init_memEx
call init_page_map
 
mov eax, sys_pgdir ;+PG_NOCACHE
mov cr3, eax
 
mov eax,cr0
or eax,CR0_PG
mov cr0,eax
 
call init_kernel_heap
call init_LFB
call init_mtrr
 
stdcall alloc_kernel_space, 0x4F000
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, 0x1000
mov [tmp_task_data], eax
 
mov [dll_map], 0xFFFFFFFF
mov [srv_map], 0xFFFFFFFF
 
call alloc_dll
mov edi, eax
mov esi, szKernel
mov ecx, 16
rep movsb
 
clts
fninit
 
bt [cpu_caps], CAPS_FXSR
jnc .no_FXSR
 
stdcall kernel_alloc, 512*256
mov [fpu_data], eax
 
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
 
jmp .set_cr
.no_FXSR:
stdcall kernel_alloc, 112*256
mov [fpu_data], eax
mov ebx, cr4
mov ecx, cr0
and ebx, not (CR4_OSFXSR+CR4_OSXMMEXPT)
and ecx, not CR0_EM
or ecx, CR0_MP+CR0_NE
mov cr0, ecx
mov cr4, ebx
.set_cr:
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
 
; 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'
;!!!!!!!!!!!!!!!!!!!!!!!
 
; LOAD FONTS I and II
 
mov [0x3000],dword 1
mov [0x3004],dword 1
mov [0x3010],dword 0x3020
 
mov esi,char
xor ebx,ebx
mov ecx,2560;26000
mov edx,0x3F600;0x37000
call fs_RamdiskRead
 
mov esi,char2
xor ebx,ebx
mov ecx,2560;26000
mov edx,0x3EC00;0x30000
call fs_RamdiskRead
 
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
mov edi, 1
mov eax, 0x00040000
call display_number_force
 
; REDIRECT ALL IRQ'S TO INT'S 0x20-0x2f
 
mov esi,boot_irqs
call boot_log
call rerouteirqs
 
mov esi,boot_tss
call boot_log
 
; BUILD SCHEDULER
 
call build_scheduler ; sys32.inc
 
; LOAD IDT
lidt [cs:idtreg]
 
;The CPU to this moment should be already in PM,
;and bit MP of the register cr0 should be installed in 1.
;finit ;reset of the FPU (finit, instead of fninit)
;fsetpm ;enable PM of the FPU
;finit ;reset the registers, contents which are still equal RM
;Now FPU too in PM
; DETECT DEVICES
 
mov esi,boot_devices
call boot_log
call detect_devices
 
; TIMER SET TO 1/100 S
 
mov esi,boot_timer
call boot_log
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
 
; SET MOUSE
 
mov esi,boot_setmouse
call boot_log
call setmouse
 
; SET PRELIMINARY WINDOW STACK AND POSITIONS
 
mov esi,boot_windefs
call boot_log
call setwindowdefaults
 
; SET BACKGROUND DEFAULTS
 
mov esi,boot_bgr
call boot_log
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
; name for OS/IDLE process
mov dword [0x80000+256+APPDATA.app_name], dword 'OS/I'
mov dword [0x80000+256+APPDATA.app_name+4], dword 'DLE '
mov eax, [fpu_data]
mov dword [0x80000+APPDATA.fpu_state], eax
mov dword [0x80000+APPDATA.fpu_handler], 0
mov dword [0x80000+APPDATA.sse_handler], 0
 
add eax, 112
bt [cpu_caps], CAPS_FXSR
jnc .no_sse
add eax, 512-112
.no_sse:
mov dword [0x80000+256+APPDATA.fpu_state], eax
mov dword [0x80000+256+APPDATA.fpu_handler], 0
mov dword [0x80000+256+APPDATA.sse_handler], 0
; task list
mov [0x3020+TASKDATA.wnd_number], 1 ; on screen number
mov [0x3020+TASKDATA.pid], 1 ; process id number
mov [0x3020+TASKDATA.mem_start], 0 ; process base address
 
; set default flags & stacks
mov [l.eflags],dword 0x11202 ; sti and resume
mov [l.ss0], os_data
; osloop - TSS
mov eax,cr3
mov [l.cr3],eax
mov [l.eip],osloop
mov [l.esp],sysint_stack_data + 4096*2 ; uses slot 1 stack
mov [l.cs],os_code
mov [l.ss],os_data
mov [l.ds],os_data
mov [l.es],os_data
mov [l.fs],os_data
mov [l.gs],os_data
; move tss to tss_data+tss_step
mov esi,tss_sceleton
mov edi,tss_data+tss_step
mov ecx,120/4
cld
rep movsd
 
mov ax,tss0
ltr ax
 
; READ TSC / SECOND
 
mov esi,boot_tsc
call boot_log
call _rdtsc
mov ecx,eax
mov esi,250 ; wait 1/4 a second
call delay_ms
call _rdtsc
sub eax,ecx
shl eax,2
mov [0xf600],eax ; save tsc / sec
mov ebx, 1000000
div ebx
mov [stall_mcs], eax
 
; SET VARIABLES
 
call set_variables
 
; STACK AND FDC
 
call stack_init
call fdc_init
 
; PALETTE FOR 320x200 and 640x480 16 col
 
cmp [0xfe0c],word 0x12
jne no_pal_vga
mov esi,boot_pal_vga
call boot_log
call paletteVGA
no_pal_vga:
 
cmp [0xfe0c],word 0x13
jne no_pal_ega
mov esi,boot_pal_ega
call boot_log
call palette320x200
no_pal_ega:
 
; LOAD DEFAULT SKIN
 
mov esi,_skin_file_default
mov edi,_skin_file
movsd
movsd
movsd
call load_skin
 
; LOAD FIRST APPLICATION
mov [0x3000],dword 1
mov [0x3004],dword 1
cli
cmp byte [0x2f0000+0x9030],1
jne no_load_vrr_m
mov ebp,vrr_m
lea esi,[ebp+6] ; skip '/rd/1/'
xor ebx,ebx ; no parameters
xor edx,edx ; no flags
call fs_RamdiskExecute.flags
cmp eax,2 ; if vrr_m app found (PID=2)
je first_app_found
 
no_load_vrr_m:
mov ebp,firstapp
lea esi,[ebp+6]
xor ebx,ebx ; no parameters
xor edx,edx ; no flags
call fs_RamdiskExecute.flags
 
cmp eax,2 ; continue if a process has been loaded
je first_app_found
mov eax, 0xDEADBEEF ; otherwise halt
hlt
first_app_found:
cli
 
;mov [0x3004],dword 2
mov [0x3000],dword 1 ; 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
call Wait8042BufferEmpty
 
; 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 ]
 
; START MULTITASKING
 
mov esi,boot_tasking
call boot_log
 
mov [0xe000],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, dword 1, irq1
 
; mov [dma_hdd],1
cmp [IDEContrRegsBaseAddr], 0
setnz [dma_hdd]
 
sti
jmp $ ; wait here for timer to take control
 
; Fly :)
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; MAIN OS LOOP START ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 32
osloop:
 
call [draw_pointer]
call checkbuttons
call checkwindows
; call check_window_move_request
call checkmisc
call checkVga_N13
call stack_handler
call checkidle
call check_fdd_motor_status
jmp osloop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; MAIN OS LOOP END ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
checkidle:
pushad
 
cmp [check_idle_semaphore],0
jne no_idle_state
 
call change_task
mov eax,[idlemem]
mov ebx,[timer_ticks] ;[0xfdf0]
cmp eax,ebx
jnz idle_exit
call _rdtsc
mov ecx,eax
idle_loop:
hlt
cmp [check_idle_semaphore],0
jne idle_loop_exit
mov eax,[timer_ticks] ;[0xfdf0]
cmp ebx,eax
jz idle_loop
idle_loop_exit:
mov [idlemem],eax
call _rdtsc
sub eax,ecx
mov ebx,[idleuse]
add ebx,eax
mov [idleuse],ebx
 
popad
ret
 
idle_exit:
 
mov ebx,[timer_ticks] ;[0xfdf0]
mov [idlemem],ebx
call change_task
 
popad
ret
 
no_idle_state:
 
dec [check_idle_semaphore]
 
mov ebx,[timer_ticks] ;[0xfdf0]
mov [idlemem],ebx
call change_task
 
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:
 
pushad
 
mov [irq_owner+4*0],byte 1 ; timer
mov [irq_owner+4*1],byte 1 ; keyboard
mov [irq_owner+4*5],byte 1 ; sound blaster
mov [irq_owner+4*6],byte 1 ; floppy diskette
mov [irq_owner+4*13],byte 1 ; math co-pros
mov [irq_owner+4*14],byte 1 ; ide I
mov [irq_owner+4*15],byte 1 ; ide II
; movzx eax,byte [0xf604] ; mouse irq
; dec eax
; add eax,mouseirqtable
; movzx eax,byte [eax]
; shl eax,2
; mov [irq_owner+eax],byte 1
 
 
; RESERVE PORTS
mov edi,1 ; 0x00-0xff
mov [0x2d0000],edi
shl edi,4
mov [0x2d0000+edi+0],dword 1
mov [0x2d0000+edi+4],dword 0x0
mov [0x2d0000+edi+8],dword 0xff
; cmp [0xf604],byte 2 ; com1 mouse -> 0x3f0-0x3ff
; jne ripl1
; inc dword [0x2d0000]
; mov edi,[0x2d0000]
; shl edi,4
; mov [0x2d0000+edi+0],dword 1
; mov [0x2d0000+edi+4],dword 0x3f0
; mov [0x2d0000+edi+8],dword 0x3ff
; ripl1:
; cmp [0xf604],byte 3 ; com2 mouse -> 0x2f0-0x2ff
; jne ripl2
; inc dword [0x2d0000]
; mov edi,[0x2d0000]
; shl edi,4
; mov [0x2d0000+edi+0],dword 1
; mov [0x2d0000+edi+4],dword 0x2f0
; mov [0x2d0000+edi+8],dword 0x2ff
; ripl2:
 
popad
ret
 
iglobal
mouseirqtable db 12 ; ps2
db 4 ; com1
db 3 ; com2
endg
 
setirqreadports:
 
mov [irq12read+0],dword 0x60 + 0x01000000 ; read port 0x60 , byte
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
mov [0xfcff],byte 0 ; mouse buffer
mov [0xf400],byte 0 ; keyboard buffer
mov [0xf500],byte 0 ; button buffer
; mov [0xfb0a],dword 100*65536+100 ; mouse x/y
 
push eax
mov ax,[0x2f0000+0x900c]
shr ax,1
shl eax,16
mov ax,[0x2f0000+0x900A]
shr ax,1
mov [0xfb0a],eax
pop eax
 
mov byte [SB16_Status],0 ; Minazzi Paolo
mov [display_data-12],dword 1 ; tiled background
mov [0xfe88],dword 0x2C0000 ; address of button list
 
;!! IP 04.02.2005:
mov [next_usage_update], 100
mov byte [0xFFFF], 0 ; change task if possible
 
ret
 
;* mouse centered - start code- Mario79
mouse_centered:
push eax
mov eax,[0xFE00]
shr eax,1
mov [0xFB0A],ax
mov eax,[0xFE04]
shr eax,1
mov [0xFB0C],ax
pop eax
ret
;* mouse centered - end code- Mario79
 
align 4
 
sys_outport:
 
mov edi,ebx ; separate flag for read / write
and ebx,65535
 
mov ecx,[0x2d0000]
test ecx,ecx
jne sopl8
mov [esp+36],dword 1
ret
 
sopl8:
mov edx,[0x3010]
mov edx,[edx+0x4]
and ebx,65535
cld
sopl1:
 
mov esi,ecx
shl esi,4
add esi,0x2d0000
cmp edx,[esi+0]
jne sopl2
cmp ebx,[esi+4]
jb sopl2
cmp ebx,[esi+8]
jg sopl2
jmp sopl3
 
sopl2:
 
dec ecx
jnz sopl1
mov [esp+36],dword 1
ret
 
sopl3:
 
test edi,0x80000000 ; read ?
jnz sopl4
 
mov dx,bx ; write
out dx,al
mov [esp+36],dword 0
ret
 
sopl4:
 
mov dx,bx ; read
in al,dx
and eax,0xff
mov [esp+36],dword 0
mov [esp+24],eax
ret
 
 
 
align 4
sys_sb16:
 
cmp word [sb16],word 0
jnz sb16l1
mov [esp+36],dword 1
ret
sb16l1:
mov [esp+36],dword 0
cmp eax,1 ; set volume - main
jnz sb16l2
mov dx,word [sb16]
add dx,4
mov al,0x22
out dx,al
mov esi,1
call delay_ms
mov eax,ebx
inc edx
out dx,al
ret
sb16l2:
 
cmp eax,2 ; set volume - cd
jnz sb16l3
mov dx,word [sb16]
add dx,4
mov al,0x28
out dx,al
mov esi,1
call delay_ms
mov eax,ebx
add edx,1
out dx,al
ret
sb16l3:
mov [esp+36],dword 2
ret
 
 
align 4
 
sys_sb16II:
 
cmp word [sb16],word 0
jnz IIsb16l1
mov [esp+36],dword 1
ret
IIsb16l1:
 
cmp eax,1 ; set volume - main
jnz IIsb16l2
; L
mov dx,word [sb16]
add dx,4
mov al,0x30
out dx,al
mov eax,ebx
inc edx
out dx,al
; R
mov dx,word [sb16]
add dx,4
mov al,0x31
out dx,al
mov eax,ebx
inc edx
out dx,al
mov [esp+36],dword 0
ret
IIsb16l2:
 
cmp eax,2 ; set volume - cd
jnz IIsb16l3
; L
mov dx,word [sb16]
add dx,4
mov al,0x36
out dx,al
mov eax,ebx
inc edx
out dx,al
; R
mov dx,word [sb16]
add dx,4
mov al,0x37
out dx,al
mov eax,ebx
inc edx
out dx,al
mov [esp+36],dword 0
ret
IIsb16l3:
 
mov [esp+36],dword 2
ret
 
 
align 4
 
sys_wss:
 
cmp word [wss],word 0
jnz wssl1
mov [esp+36],dword 1
ret
wssl1:
 
cmp eax,1 ; set volume - main
jnz wssl2
mov [esp+36],dword 0
ret
wssl2:
 
cmp eax,2 ; set volume - cd
jnz wssl3
; L
mov dx,word [wss]
add dx,4
mov al,0x2
out dx,al
mov esi,1
call delay_ms
mov eax,ebx
inc edx
out dx,al
; R
mov dx,word [wss]
add dx,4
mov al,0x3
out dx,al
mov esi,1
call delay_ms
mov eax,ebx
inc edx
out dx,al
mov [esp+36],dword 0
ret
wssl3:
mov [esp+36],dword 2
ret
 
display_number:
 
; 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:
 
cmp eax,0xffff ; length > 0 ?
jge cont_displ
ret
cont_displ:
 
cmp eax,61*0x10000 ; length <= 60 ?
jb cont_displ2
ret
cont_displ2:
 
pushad
 
cmp al,1 ; ecx is a pointer ?
jne displnl1
mov ebx,[ebx+std_application_base_address]
displnl1:
sub esp,64
 
cmp ah,0 ; DECIMAL
jne no_display_desnum
shr eax,16
and eax,0x3f
push eax
mov edi,esp
add edi,4+64-1
mov ecx,eax
mov eax,ebx
mov ebx,10
d_desnum:
xor edx,edx
div ebx
add dl,48
mov [edi],dl
dec edi
loop d_desnum
pop eax
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,0x3f
push eax
mov edi,esp
add edi,4+64-1
mov ecx,eax
mov eax,ebx
mov ebx,16
d_hexnum:
xor edx,edx
div ebx
add edx,hexletters
mov dl,[edx]
mov [edi],dl
dec edi
loop d_hexnum
pop eax
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,0x3f
push eax
mov edi,esp
add edi,4+64-1
mov ecx,eax
mov eax,ebx
mov ebx,2
d_binnum:
xor edx,edx
div ebx
add dl,48
mov [edi],dl
dec edi
loop d_binnum
pop eax
call draw_num_text
add esp,64
popad
ret
no_display_binnum:
 
add esp,64
popad
ret
 
 
draw_num_text:
 
; dtext
;
; eax x & y
; ebx color
; ecx start of text
; edx length
; edi 1 force
 
; mov edi,[0x3000]
; shl edi,8
; add ax,word[edi+0x80000+APPDATA.wnd_clientbox.top]
; rol eax,16
; add ax,word[edi+0x80000+APPDATA.wnd_clientbox.left]
; rol eax,16
 
mov edx,eax
mov ecx,64+4
sub ecx,eax
add ecx,esp
mov eax,[esp+64+32-8+4]
push edx ; add window start x & y
mov edx,[0x3010]
mov ebx,[edx-twdw+WDATA.box.left]
add ebx, [(edx-0x3000)*8+0x80000+APPDATA.wnd_clientbox.left]
shl ebx,16
add ebx,[edx-twdw+WDATA.box.top]
add ebx, [(edx-0x3000)*8+0x80000+APPDATA.wnd_clientbox.top]
add eax,ebx
pop edx
mov ebx,[esp+64+32-12+4]
and ebx, not 0x80000000 ; force counted string
mov esi, [esp+64+4+4]
mov edi, [esp+64+4]
jmp dtext
 
read_string:
 
; eax read_area
; ebx color of letter
; ecx color of background
; edx number of letters to read
; esi [x start]*65536 + [y_start]
 
ret
 
 
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
; 4=sb16 base , base io address
; 5=system language, 1eng 2fi 3ger 4rus
; 6=wss base , base io address
; 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
 
 
mov [esp+36],dword 0
cmp eax,1 ; MIDI
jnz nsyse1
cmp ebx,0x100
jb nsyse1
mov edx,65535
cmp edx,ebx
jb nsyse1
mov [midi_base],bx
mov word [mididp],bx
inc bx
mov word [midisp],bx
ret
 
midi_base dw 0
 
nsyse1:
 
cmp eax,2 ; KEYBOARD
jnz nsyse2
cmp ebx,1
jnz kbnobase
mov edi,[0x3010]
add ecx,[edi+TASKDATA.mem_start]
mov eax,ecx
mov ebx,keymap
mov ecx,128
call memmove
ret
kbnobase:
cmp ebx,2
jnz kbnoshift
mov edi,[0x3010]
add ecx,[edi+TASKDATA.mem_start]
mov eax,ecx
mov ebx,keymap_shift
mov ecx,128
call memmove
ret
kbnoshift:
cmp ebx,3
jne kbnoalt
mov edi,[0x3010]
add ecx,[edi+TASKDATA.mem_start]
mov eax,ecx
mov ebx,keymap_alt
mov ecx,128
call memmove
ret
kbnoalt:
cmp ebx,9
jnz kbnocountry
mov word [keyboard],cx
ret
kbnocountry:
mov [esp+36],dword 1
ret
nsyse2:
cmp eax,3 ; CD
jnz nsyse3
test ebx,ebx
jz nosesl
cmp ebx, 4
ja nosesl
mov [cd_base],bl
cmp ebx,1
jnz noprma
mov [cdbase],0x1f0
mov [cdid],0xa0
noprma:
cmp ebx,2
jnz noprsl
mov [cdbase],0x1f0
mov [cdid],0xb0
noprsl:
cmp ebx,3
jnz nosema
mov [cdbase],0x170
mov [cdid],0xa0
nosema:
cmp ebx,4
jnz nosesl
mov [cdbase],0x170
mov [cdid],0xb0
nosesl:
ret
 
cd_base db 0
 
nsyse3:
 
cmp eax,4 ; SB
jnz nsyse4
cmp ebx,0x100
jb nsyse4
mov edx,65535
cmp edx,ebx
jb nsyse4
mov word [sb16],bx
ret
nsyse4:
 
cmp eax,5 ; SYSTEM LANGUAGE
jnz nsyse5
mov [syslang],ebx
ret
nsyse5:
 
cmp eax,6 ; WSS
jnz nsyse6
cmp ebx,0x100
jb nsyse6
mov [wss],ebx
ret
 
wss_temp dd 0
 
nsyse6:
 
cmp eax,7 ; HD BASE
jne nsyse7
test ebx,ebx
jz nosethd
cmp ebx,4
ja nosethd
mov [hd_base],bl
cmp ebx,1
jnz noprmahd
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
; call set_FAT32_variables
noprmahd:
cmp ebx,2
jnz noprslhd
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
; call set_FAT32_variables
noprslhd:
cmp ebx,3
jnz nosemahd
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
; call set_FAT32_variables
nosemahd:
cmp ebx,4
jnz noseslhd
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
; call set_FAT32_variables
noseslhd:
mov [0xfe10],dword 0
call reserve_hd1
call clear_hd_cache
mov [hd1_status],0 ; free
nosethd:
ret
 
hd_base db 0
 
nsyse7:
 
cmp eax,8 ; HD PARTITION
jne nsyse8
mov [fat32part],ebx
; call set_FAT32_variables
call reserve_hd1
call clear_hd_cache
pusha
call choice_necessity_partition_1
popa
mov [hd1_status],0 ; free
ret
nsyse8:
 
cmp eax,10 ; SOUND DMA CHANNEL
jne no_set_sound_dma
cmp ebx,3
ja sys_setup_err
mov [sound_dma],ebx
ret
no_set_sound_dma:
 
cmp eax,11 ; ENABLE LBA READ
jne no_set_lba_read
and ebx,1
mov [lba_read_enabled],ebx
ret
no_set_lba_read:
 
cmp eax,12 ; ENABLE PCI ACCESS
jne no_set_pci_access
and ebx,1
mov [pci_access_enabled],ebx
ret
no_set_pci_access:
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
include 'vmodeint.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
sys_setup_err:
mov [esp+36],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
; 4=sb16 base , base io address
; 5=system language, 1eng 2fi 3ger 4rus
; 6=wss base
; 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
jne ngsyse1
movzx eax,[midi_base]
mov [esp+36],eax
ret
ngsyse1:
 
cmp eax,2
jne ngsyse2
cmp ebx,1
jnz kbnobaseret
mov edi,[0x3010]
add ecx,[edi+TASKDATA.mem_start]
mov ebx,ecx
mov eax,keymap
mov ecx,128
call memmove
ret
kbnobaseret:
cmp ebx,2
jnz kbnoshiftret
mov edi,[0x3010]
add ecx,[edi+TASKDATA.mem_start]
mov ebx,ecx
mov eax,keymap_shift
mov ecx,128
call memmove
ret
kbnoshiftret:
cmp ebx,3
jne kbnoaltret
mov edi,[0x3010]
add ecx,[edi+TASKDATA.mem_start]
mov ebx,ecx
mov eax,keymap_alt
mov ecx,128
call memmove
ret
kbnoaltret:
cmp ebx,9
jnz ngsyse2
movzx eax,word [keyboard]
mov [esp+36],eax
ret
ngsyse2:
 
cmp eax,3
jnz ngsyse3
movzx eax,[cd_base]
mov [esp+36],eax
ret
ngsyse3:
 
cmp eax,4
jne ngsyse4
mov eax,[sb16]
mov [esp+36],eax
ret
ngsyse4:
 
cmp eax,5
jnz ngsyse5
mov eax,[syslang]
mov [esp+36],eax
ret
ngsyse5:
cmp eax,6
jnz ngsyse6
mov eax,[wss]
mov [esp+36],eax
ret
ngsyse6:
cmp eax,7
jnz ngsyse7
movzx eax,[hd_base]
mov [esp+36],eax
ret
ngsyse7:
cmp eax,8
jnz ngsyse8
mov eax,[fat32part]
mov [esp+36],eax
ret
ngsyse8:
cmp eax,9
jne ngsyse9
mov eax,[timer_ticks] ;[0xfdf0]
mov [esp+36],eax
ret
ngsyse9:
cmp eax,10
jnz ngsyse10
mov eax,[sound_dma]
mov [esp+36],eax
ret
ngsyse10:
cmp eax,11
jnz ngsyse11
mov eax,[lba_read_enabled]
mov [esp+36],eax
ret
ngsyse11:
cmp eax,12
jnz ngsyse12
mov eax,[pci_access_enabled]
mov [esp+36],eax
ret
ngsyse12:
mov [esp+36],dword 1
ret
 
 
align 4
 
readmousepos:
 
; eax=0 screen relative
; eax=1 window relative
; eax=2 buttons pressed
 
test eax,eax
jnz nosr
mov eax,[0xfb0a]
shl eax,16
mov ax,[0xfb0c]
mov [esp+36],eax
ret
nosr:
 
cmp eax,1
jnz nowr
mov eax,[0xfb0a]
shl eax,16
mov ax,[0xfb0c]
mov esi,[0x3010]
mov bx, word [esi-twdw+WDATA.box.left]
shl ebx,16
mov bx, word [esi-twdw+WDATA.box.top]
sub eax,ebx
 
mov edi,[0x3000]
shl edi,8
sub ax,word[edi+0x80000+APPDATA.wnd_clientbox.top]
rol eax,16
sub ax,word[edi+0x80000+APPDATA.wnd_clientbox.left]
rol eax,16
 
mov [esp+36],eax
ret
nowr:
 
cmp eax,2
jnz nomb
movzx eax,byte [0xfb40]
nomb:
mov [esp+36],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
 
 
setuart:
 
su1:
call is_output
cmp al,0
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
cmp al,0
jnz su2
call get_mpu_in
cmp al,0xfe
jnz su2
su3:
call is_output
cmp al,0
jnz su3
mov dx,word [midisp]
mov al,0x3f
out dx,al
 
ret
 
 
align 4
 
sys_midi:
 
cmp [mididp],0
jnz sm0
mov [esp+36],dword 1
ret
sm0:
 
cmp eax,1
mov [esp+36],dword 0
jnz smn1
call setuart
ret
smn1:
 
cmp eax,2
jnz smn2
sm10:
call get_mpu_in
call is_output
test al,al
jnz sm10
mov al,bl
call put_mpu_out
ret
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 eax,[0x3010]
mov [eax+TASKDATA.state], 3 ; terminate this program
 
waitterm: ; wait here for termination
mov eax,5
call delay_hs
jmp waitterm
 
iglobal
align 4
sys_system_table:
dd sysfn_shutdown ; 1 = system shutdown
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_param ; 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
sysfn_num = ($ - sys_system_table)/4
endg
 
sys_system:
dec eax
cmp eax, sysfn_num
jae @f
jmp dword [sys_system_table + eax*4]
@@:
ret
 
sysfn_shutdown: ; 18.1 = BOOT
mov [0x2f0000+0x9030],byte 0
for_shutdown_parameter:
mov eax,[0x3004]
add eax,2
mov [shutdown_processes],eax
mov [0xFF00],al
and dword [esp+36], 0
ret
uglobal
shutdown_processes: dd 0x0
endg
 
sysfn_terminate: ; 18.2 = TERMINATE
cmp ebx,2
jb noprocessterminate
mov edx,[0x3004]
cmp ebx,edx
ja noprocessterminate
mov eax,[0x3004]
shl ebx,5
mov edx,[ebx+0x3000+TASKDATA.pid]
add ebx,0x3000+TASKDATA.state
cmp byte [ebx], 9
jz noprocessterminate
 
;call MEM_Heap_Lock ;guarantee that process isn't working with heap
mov [ebx],byte 3 ; clear possible i40's
;call MEM_Heap_UnLock
 
cmp edx,[application_table_status] ; clear app table stat
jne noatsc
mov [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,ebx
call pid_to_slot
test eax,eax
jz .not_found
mov ebx,eax
cli
call sysfn_terminate
mov [application_table_status],0
sti
and dword [esp+36],0
ret
.not_found:
mov [application_table_status],0
or dword [esp+36],-1
ret
 
sysfn_activate: ; 18.3 = ACTIVATE WINDOW
cmp ebx,2
jb .nowindowactivate
cmp ebx,[0x3004]
ja .nowindowactivate
 
mov [window_minimize], 2 ; restore window if minimized
 
movzx esi, word [0xC000 + ebx*2]
cmp esi, [0x3004]
je .nowindowactivate ; already active
 
mov edi, ebx
shl edi, 5
add edi, window_data
movzx esi, word [0xC000 + ebx * 2]
lea esi, [0xC400 + esi * 2]
call waredraw
.nowindowactivate:
ret
 
sysfn_getidletime: ; 18.4 = GET IDLETIME
mov eax,[idleusesec]
mov [esp+36], eax
ret
 
sysfn_getcpuclock: ; 18.5 = GET TSC/SEC
mov eax,[0xf600]
mov [esp+36], eax
ret
 
; SAVE ramdisk to /hd/1/menuet.img
;!!!!!!!!!!!!!!!!!!!!!!!!
include 'blkdev/rdsave.inc'
;!!!!!!!!!!!!!!!!!!!!!!!!
 
sysfn_getactive: ; 18.7 = get active window
mov eax, [0x3004]
movzx eax, word [0xC400 + eax*2]
mov [esp+36],eax
ret
 
sysfn_sound_flag: ; 18.8 = get/set sound_flag
cmp ebx,1
jne nogetsoundflag
movzx eax,byte [sound_flag] ; get sound_flag
mov [esp+36],eax
ret
nogetsoundflag:
cmp ebx,2
jnz nosoundflag
xor byte [sound_flag], 1
nosoundflag:
ret
 
sysfn_shutdown_param: ; 18.9 = system shutdown with param
cmp ebx,1
jl exit_for_anyone
cmp ebx,4
jg exit_for_anyone
mov [0x2f0000+0x9030],bl
jmp for_shutdown_parameter
 
sysfn_minimize: ; 18.10 = minimize window
mov [window_minimize],1
exit_for_anyone:
ret
 
sysfn_getdiskinfo: ; 18.11 = get disk info table
cmp ebx,1
jnz full_table
small_table:
call for_all_tables
mov ecx,10
cld
rep movsb
ret
for_all_tables:
mov edi,[0x3010]
mov edi,[edi+TASKDATA.mem_start]
add edi,ecx
mov esi,0x40000
ret
full_table:
cmp ebx,2
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+36], 0
ret
 
sysfn_getversion: ; 18.13 = get kernel ID and version
mov edi,[0x3010]
mov edi,[edi+TASKDATA.mem_start]
add edi,ebx
mov esi,version_inf
mov ecx,version_end-version_inf
cld
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
mov [esp+36],dword 0
ret
 
sysfn_centermouse: ; 18.15 = mouse centered
call mouse_centered
mov [esp+36],dword 0
ret
 
sysfn_mouse_acceleration: ; 18.19 = set/get mouse features
cmp ebx,0 ; get mouse speed factor
jnz .set_mouse_acceleration
xor eax,eax
mov ax,[mouse_speed_factor]
mov [esp+36],eax
ret
.set_mouse_acceleration:
cmp ebx,1 ; set mouse speed factor
jnz .get_mouse_delay
mov [mouse_speed_factor],cx
ret
.get_mouse_delay:
cmp ebx,2 ; get mouse delay
jnz .set_mouse_delay
mov eax,[mouse_delay]
mov [esp+36],eax
ret
.set_mouse_delay:
cmp ebx,3 ; set mouse delay
jnz .set_pointer_position
mov [mouse_delay],ecx
ret
.set_pointer_position:
cmp ebx,4 ; set mouse pointer position
jnz .end
mov [0xFB0C],cx ;y
ror ecx,16
mov [0xFB0A],cx ;x
rol ecx,16
.end:
ret
 
sysfn_getfreemem:
mov eax, [pg_data.pages_free]
shl eax, 2
mov [esp+36],eax
ret
 
sysfn_getallmem:
mov eax,[MEM_AMOUNT]
shr eax, 10
mov [esp+36],eax
ret
 
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,6,3,0 ; version 0.6.3.0
db UID_KOLIBRI
db 'Kolibri',0
version_end:
endg
 
UID_NONE=0
UID_MENUETOS=1 ;official
UID_KOLIBRI=2 ;russian
 
sys_cachetodiskette:
; pushad
; cmp eax,1
; jne no_write_all_of_ramdisk
; call fdc_writeramdisk
; popad
; ret
; no_write_all_of_ramdisk:
; cmp eax,2
; jne no_write_part_of_ramdisk
; call fdc_commitflush
; popad
; ret
; no_write_part_of_ramdisk:
; cmp eax,3
; jne no_set_fdc
; call fdc_set
; popad
; ret
; no_set_fdc:
; cmp eax,4
; jne no_get_fdc
; popad
; call fdc_get
; mov [esp+36],ecx
; ret
; no_get_fdc:
; popad
; ret
cmp eax,1
jne no_floppy_a_save
mov [flp_number],1
jmp save_image_on_floppy
no_floppy_a_save:
cmp eax,2
jne no_floppy_b_save
mov [flp_number],2
save_image_on_floppy:
call save_image
mov [esp+36],dword 0
cmp [FDC_Status],0
je yes_floppy_save
no_floppy_b_save:
mov [esp+36],dword 1
yes_floppy_save:
ret
 
uglobal
; bgrchanged dd 0x0
endg
 
sys_background:
 
cmp eax,1 ; BACKGROUND SIZE
jnz nosb1
cmp ebx,0
je sbgrr
cmp ecx,0
je sbgrr
mov [display_data-8],ebx
mov [display_data-4],ecx
; mov [bgrchanged],1
sbgrr:
ret
nosb1:
 
cmp eax,2 ; SET PIXEL
jnz nosb2
mov edx,0x160000-16
cmp edx,ebx
jbe nosb2
mov edx,[ebx]
and edx,0xFF000000 ;255*256*256*256
and ecx,0x00FFFFFF ;255*256*256+255*256+255
add edx,ecx
mov [ebx+0x300000],edx
; mov [bgrchanged],1
ret
nosb2:
 
cmp eax,3 ; DRAW BACKGROUND
jnz nosb3
draw_background_temp:
; cmp [bgrchanged],1 ;0
; je nosb31
;draw_background_temp:
; mov [bgrchanged],1 ;0
mov [0xfff0],byte 1
mov [background_defined], 1
nosb31:
ret
nosb3:
 
cmp eax,4 ; TILED / STRETCHED
jnz nosb4
cmp ebx,[display_data-12]
je nosb41
mov [display_data-12],ebx
; mov [bgrchanged],1
nosb41:
ret
nosb4:
 
cmp eax,5 ; BLOCK MOVE TO BGR
jnz nosb5
; bughere
mov edi, [0x3010]
add ebx, [edi+TASKDATA.mem_start]
; mov esi, ebx
; mov edi, ecx
mov eax, ebx
mov ebx, ecx
add ecx, edx
cmp ecx, 0x160000-16
ja .fin
; add edi, 0x300000
add ebx, 0x300000
mov ecx, edx
cmp ecx, 0x160000-16
ja .fin
; mov [bgrchanged],1
; cld
; rep movsb
call memmove
.fin:
ret
nosb5:
 
ret
 
 
align 4
 
sys_getbackground:
 
cmp eax,1 ; SIZE
jnz nogb1
mov eax,[display_data-8]
shl eax,16
mov ax,[display_data-4]
mov [esp+36],eax
ret
nogb1:
 
cmp eax,2 ; PIXEL
jnz nogb2
mov edx,0x160000-16
cmp edx,ebx
jbe nogb2
mov eax, [ebx+0x300000]
and eax, 0xFFFFFF
mov [esp+36],eax
ret
nogb2:
 
cmp eax,4 ; TILED / STRETCHED
jnz nogb4
mov eax,[display_data-12]
nogb4:
mov [esp+36],eax
ret
 
 
align 4
 
sys_getkey:
mov [esp+36],dword 1
; test main buffer
mov ebx, [0x3000] ; TOP OF WINDOW STACK
movzx ecx,word [0xC000 + ebx * 2]
mov edx,[0x3004]
cmp ecx,edx
jne .finish
cmp [0xf400],byte 0
je .finish
movzx eax,byte [0xf401]
shl eax,8
push eax
dec byte [0xf400]
and byte [0xf400],127
movzx ecx,byte [0xf400]
add ecx,2
; mov esi,0xf402
; mov edi,0xf401
; cld
; rep movsb
mov eax, 0xF402
mov ebx, 0xF401
call memmove
pop eax
.ret_eax:
mov [esp+36],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, [0x3000] ; TOP OF WINDOW STACK
mov [esp+36],dword 1
movzx ecx, word [0xC000 + ebx * 2]
mov edx, [0x3004] ; less than 256 processes
cmp ecx,edx
jne .exit
movzx eax,byte [0xf500]
test eax,eax
jz .exit
mov eax,[0xf501]
shl eax,8
mov [0xf500],byte 0
mov [esp+36],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
;
 
mov edi,[0x3010] ; eax = return area
add eax,[edi + TASKDATA.mem_start]
 
cmp ebx,-1 ; who am I ?
jne no_who_am_i
mov ebx,[0x3000]
no_who_am_i:
 
push eax ; return area
push ebx ; process number
 
push ebx
push ebx
push eax
 
; return memory usage
 
xor edx,edx
mov eax,0x20
mul ebx
add eax,0x3000+TASKDATA.cpu_usage
mov ebx,eax
pop eax
mov ecx,[ebx]
mov [eax],ecx
pop ebx
mov cx, [0xC000 + ebx * 2]
mov [eax+4],cx
mov cx, [0xC400 + ebx * 2]
mov [eax+6],cx
push eax
mov eax,ebx
shl eax,8
add eax,0x80000+APPDATA.app_name
pop ebx
add ebx,10
mov ecx,11
call memmove
 
; memory usage
 
xor eax,eax
mov edx,0x100000*16
pop ecx ; get gdt of tss
cmp ecx,1
je os_mem
shl ecx,8
mov edx,[0x80000+ecx+APPDATA.mem_size] ;0x8c
mov eax,std_application_base_address
; eax run base -> edx used memory
os_mem:
dec edx
mov [ebx+12],eax
mov [ebx+16],edx
 
; PID (+30)
 
mov eax,[esp]
shl eax,5
add eax,0x3000+TASKDATA.pid
mov eax,[eax]
mov [ebx+20],eax
 
; window position and size
 
mov esi,[esp]
shl esi,5
add esi,window_data + WDATA.box
mov edi,[esp+4]
add edi,34
mov ecx,4
cld
rep movsd
 
; Process state (+50)
 
mov eax,[esp]
shl eax,5
add eax,0x3000+TASKDATA.state
mov eax,[eax]
mov [ebx+40],ax
 
; Window client area box
 
mov esi,[esp]
shl esi,8
add esi,0x80000+APPDATA.wnd_clientbox
lea edi,[ebx+44]
mov ecx,4
rep movsd
 
; Window state
 
mov esi,[esp]
shl esi,5
add esi,window_data + WDATA.box
mov al,[esi+window_data+WDATA.fl_wstate]
mov [edi],al
 
pop ebx
pop eax
 
; return number of processes
 
mov eax,[0x3004]
mov [esp+36],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+36],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+36],ecx
ret
 
 
; redraw status
 
sys_redrawstat:
 
cmp eax,1
jne no_widgets_away
 
; buttons away
 
mov ecx,[0x3000]
 
sys_newba2:
 
mov edi,[0xfe88]
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 eax,2
jnz srl1
 
mov edx,[0x3010] ; return whole screen draw area for this app
add edx,draw_data-0x3000
mov [edx+RECT.left], 0
mov [edx+RECT.top], 0
mov eax,[0xfe00]
mov [edx+RECT.right],eax
mov eax,[0xfe04]
mov [edx+RECT.bottom],eax
 
mov edi,[0x3010]
or [edi-twdw+WDATA.fl_wdrawn], 1 ; no new position & buttons from app
 
call sys_window_mouse
 
ret
 
srl1:
 
ret
 
 
sys_drawwindow:
 
mov edi,ecx
shr edi,16+8
and edi,15
 
cmp edi,0 ; type I - original style
jne nosyswI
inc [mouse_pause]
call [disable_mouse]
call sys_set_window
call [disable_mouse]
call drawwindow_I
;dec [mouse_pause]
;call [draw_pointer]
;ret
jmp draw_window_caption.2
nosyswI:
 
cmp edi,1 ; type II - only reserve area, no draw
jne nosyswII
inc [mouse_pause]
call [disable_mouse]
call sys_set_window
call [disable_mouse]
call sys_window_mouse
dec [mouse_pause]
call [draw_pointer]
ret
nosyswII:
 
cmp edi,2 ; type III - new style
jne nosyswIII
inc [mouse_pause]
call [disable_mouse]
call sys_set_window
call [disable_mouse]
call drawwindow_III
;dec [mouse_pause]
;call [draw_pointer]
;ret
jmp draw_window_caption.2
nosyswIII:
 
cmp edi,3 ; type IV - skinned window
jne nosyswIV
 
; parameter for drawwindow_IV
push 0
mov edi, [0x3004]
movzx edi, word [0xC400 + edi*2]
cmp edi, [0x3000]
jne @f
inc dword [esp]
@@:
 
inc [mouse_pause]
call [disable_mouse]
call sys_set_window
call [disable_mouse]
call drawwindow_IV
;dec [mouse_pause]
;call [draw_pointer]
;ret
jmp draw_window_caption.2
nosyswIV:
 
ret
 
 
draw_window_caption:
inc [mouse_pause]
call [disable_mouse]
 
xor eax,eax
mov edx,[0x3004]
movzx edx,word[0xC400+edx*2]
cmp edx,[0x3000]
jne @f
inc eax
@@: mov edx,[0x3000]
shl edx,5
add edx,window_data
movzx ebx,[edx+WDATA.fl_wstyle]
and bl,0x0F
cmp bl,3
jne .not_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: ;jmp @f
mov edi,[0x3000]
shl edi,5
test [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION
jz @f
mov ecx,[edi*8+0x80000+APPDATA.wnd_caption]
or ecx,ecx
jz @f
add ecx,[edi+twdw+TASKDATA.mem_start]
 
movzx eax,[edi+window_data+WDATA.fl_wstyle]
and al,0x0F
cmp al,3
jne .not_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]
cwde
cdq
mov ebx,6
idiv ebx
or eax,eax
js @f
mov edx,eax
mov eax,dword[_skinmargins.left-2]
mov ax,word[_skinh]
sub ax,[_skinmargins.bottom]
sub ax,[_skinmargins.top]
sar ax,1
adc ax,0
add ax,[_skinmargins.top]
add ax,-3
add eax,ebp
jmp .dodraw
 
.not_skinned:
cmp al,1
je @f
 
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
cwde
cdq
mov ebx,6
idiv ebx
or eax,eax
js @f
mov edx,eax
mov eax,0x00080007
add eax,ebp
.dodraw:
mov ebx,[common_colours+16];0x00FFFFFF
or ebx, 0x80000000
xor edi,edi
call dtext
 
@@:
;--------------------------------------------------------------
dec [mouse_pause]
call [draw_pointer]
ret
 
iglobal
align 4
window_topleft dd \
1, 21,\
0, 0,\
5, 20,\
5, ?
endg
 
set_window_clientbox:
push eax ecx edi
 
mov eax,[_skinh]
mov [window_topleft+4*7],eax
 
mov ecx,edi
sub edi,window_data
shl edi,3
test [ecx+WDATA.fl_wstyle],WSTYLE_CLIENTRELATIVE
jz @f
 
movzx eax,[ecx+WDATA.fl_wstyle]
and eax,0x0F
mov eax,[eax*8+window_topleft+0]
mov [edi+0x80000+APPDATA.wnd_clientbox.left],eax
shl eax,1
neg eax
add eax,[ecx+WDATA.box.width]
mov [edi+0x80000+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+0x80000+APPDATA.wnd_clientbox.top],eax
neg eax
sub eax,[esp]
add eax,[ecx+WDATA.box.height]
mov [edi+0x80000+APPDATA.wnd_clientbox.height],eax
add esp,4
 
pop edi ecx eax
ret
@@:
xor eax,eax
mov [edi+0x80000+APPDATA.wnd_clientbox.left],eax
mov [edi+0x80000+APPDATA.wnd_clientbox.top],eax
mov eax,[ecx+WDATA.box.width]
mov [edi+0x80000+APPDATA.wnd_clientbox.width],eax
mov eax,[ecx+WDATA.box.height]
mov [edi+0x80000+APPDATA.wnd_clientbox.height],eax
 
pop edi ecx eax
ret
 
sys_set_window:
 
mov edi,[0x3000]
shl edi,5
add edi,window_data
 
; colors
mov [edi+WDATA.cl_workarea],ecx
mov [edi+WDATA.cl_titlebar],edx
mov [edi+WDATA.cl_frames],esi
 
; check flag (?)
test [edi+WDATA.fl_wdrawn],1
jnz newd
 
push eax
mov eax,[timer_ticks] ;[0xfdf0]
add eax,100
mov [new_window_starting],eax
pop eax
 
mov word[edi+WDATA.box.width],ax
mov word[edi+WDATA.box.height],bx
sar eax,16
sar ebx,16
mov word[edi+WDATA.box.left],ax
mov word[edi+WDATA.box.top],bx
 
call check_window_position
 
call set_window_clientbox
 
push ecx esi edi ; save for window fullscreen/resize
;mov esi,edi
 
mov cl,[edi+WDATA.fl_wstyle]
 
sub edi,window_data
shl edi,3
add edi,0x80000
 
and cl,0x0F
mov [edi+APPDATA.wnd_caption],0
cmp cl,3
jne @f
mov [edi+APPDATA.wnd_caption],esi
@@: mov esi,[esp+0]
 
add edi, APPDATA.saved_box
movsd
movsd
movsd
movsd
pop edi esi ecx
 
push eax ebx ecx edx
;;; mov eax, 1
;;; call delay_hs
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
pop edx ecx ebx eax
 
mov [0xf400],byte 0 ; empty keyboard buffer
mov [0xf500],byte 0 ; empty button buffer
 
newd:
mov [edi+WDATA.fl_redraw],byte 0 ; no redraw
mov edx,edi
 
ret
 
syscall_windowsettings:
 
.set_window_caption:
dec eax ; subfunction #1 - set window caption
jnz .get_window_caption
 
; NOTE: only window owner thread can set its caption,
; so there's no parameter for PID/TID
 
mov edi,[0x3000]
shl edi,5
 
; have to check if caption is within application memory limit
; check is trivial, and if application resizes its memory,
; caption still can become over bounds
; diamond, 31.10.2006: check removed because with new memory manager
; there can be valid data after APPDATA.mem_size bound
; mov ecx,[edi*8+0x80000+APPDATA.mem_size]
; add ecx,255 ; max caption length
; cmp ebx,ecx
; ja .exit_fail
 
mov [edi*8+0x80000+APPDATA.wnd_caption],ebx
or [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION
 
call 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
 
 
sys_window_move:
 
mov edi,[0x3000]
shl edi,5
add edi,window_data
 
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED
jnz .window_move_return
 
push dword [edi + WDATA.box.left] ; save old coordinates
push dword [edi + WDATA.box.top]
push dword [edi + WDATA.box.width]
push dword [edi + WDATA.box.height]
 
cmp eax,-1 ; set new position and size
je .no_x_reposition
mov [edi + WDATA.box.left], eax
.no_x_reposition:
cmp ebx,-1
je .no_y_reposition
mov [edi + WDATA.box.top], ebx
.no_y_reposition:
 
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP
jnz .no_y_resizing
 
cmp ecx,-1
je .no_x_resizing
mov [edi + WDATA.box.width], ecx
.no_x_resizing:
cmp edx,-1
je .no_y_resizing
mov [edi + WDATA.box.height], edx
.no_y_resizing:
 
call check_window_position
call set_window_clientbox
 
pushad ; save for window fullscreen/resize
mov esi,edi
sub edi,window_data
shr edi,5
shl edi,8
add edi, 0x80000 + APPDATA.saved_box
mov ecx,4
cld
rep movsd
popad
 
pushad ; calculcate screen at new position
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
popad
 
pop edx ; calculcate screen at old position
pop ecx
pop ebx
pop eax
add ecx,eax
add edx,ebx
mov [dlx],eax ; save for drawlimits
mov [dly],ebx
mov [dlxe],ecx
mov [dlye],edx
call calculatescreen
 
mov [edi + WDATA.fl_redraw], 1 ; flag the process as redraw
 
mov eax,edi ; redraw screen at old position
xor esi,esi
call redrawscreen
 
mov [0xfff5],byte 0 ; mouse pointer
mov [0xfff4],byte 0 ; no mouse under
mov [0xfb44],byte 0 ; react to mouse up/down
 
mov ecx,10 ; wait 1/10 second
.wmrl3:
call [draw_pointer]
mov eax,1
call delay_hs
loop .wmrl3
 
mov [window_move_pr],0
 
.window_move_return:
 
ret
 
;type_background_1:
; cmp [0xfff0],byte 0 ; background update ?
; jz temp_nobackgr
; mov [0xfff0],byte 2
; call change_task
; mov [draw_data+32+0],dword 0
; mov [draw_data+32+4],dword 0
; mov eax,[0xfe00]
; mov ebx,[0xfe04]
; mov [draw_data+32+8],eax
; mov [draw_data+32+12],ebx
; call drawbackground
; mov [0xfff0],byte 0
; mov [0xfff4],byte 0
;temp_nobackgr:
; ret
 
uglobal
window_move_pr dd 0x0
window_move_eax dd 0x0
window_move_ebx dd 0x0
window_move_ecx dd 0x0
window_move_edx dd 0x0
endg
 
;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.
;---------------------------------------------------------------------------------------------
sys_sheduler: ;noname & halyavin
cmp eax,0
je shed_counter
cmp eax,2
je perf_control
cmp eax,3
je rdmsr_instr
cmp eax,4
je wrmsr_instr
cmp eax,1
jne not_supported
call change_task ;delay,0
ret
shed_counter:
mov eax,[context_counter]
mov [esp+36],eax
not_supported:
ret
perf_control:
inc eax ;now eax=3
cmp ebx,eax
je cache_disable
dec eax
cmp ebx,eax
je cache_enable
dec eax
cmp ebx,eax
je is_cache_enabled
dec eax
cmp ebx,eax
je modify_pce
ret
 
rdmsr_instr:
;now counter in ecx
;(edx:eax) esi:edi => edx:esi
mov eax,esi
rdmsr
mov [esp+36],eax
mov [esp+24],edx ;ret in ebx?
ret
 
wrmsr_instr:
;now counter in ecx
;(edx:eax) esi:edi => edx:esi
mov eax,esi
wrmsr
mov [esp+36],eax
mov [esp+24],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+36],ebx
cache_disabled:
mov dword [esp+36],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+36],eax
ret
;---------------------------------------------------------------------------------------------
 
 
; check if pixel is allowed to be drawn
 
checkpixel:
push eax edx
 
mov edx,[0xfe00] ; screen x size
inc edx
imul edx, ebx
mov dl, [eax+edx+display_data] ; lea eax, [...]
 
xor ecx, ecx
mov eax, [0x3000]
cmp al, dl
setne cl
 
pop edx eax
ret
 
uglobal
mouse_active db 0
endg
iglobal
cpustring db '/RD/1/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
lea esi,[ebp+6]
xor ebx,ebx ; no parameters
xor edx,edx ; no flags
call fs_RamdiskExecute.flags
mov [ctrl_alt_del], 0
nocpustart:
cmp [mouse_active], 1
jne mouse_not_active
mov [mouse_active], 0
xor edi, edi
mov ecx, [0x3004]
set_mouse_event:
add edi, 256
or [edi+0x80000+APPDATA.event_mask], dword 00100000b
loop set_mouse_event
mouse_not_active:
 
 
cmp [0xfff0],byte 0 ; background update ?
jz nobackgr
cmp [background_defined], 0
jz nobackgr
mov [0xfff0],byte 2
call change_task
mov [draw_data+32 + RECT.left],dword 0
mov [draw_data+32 + RECT.top],dword 0
mov eax,[0xfe00]
mov ebx,[0xfe04]
mov [draw_data+32 + RECT.right],eax
mov [draw_data+32 + RECT.bottom],ebx
call drawbackground
mov [0xfff0],byte 0
mov [0xfff4],byte 0
 
nobackgr:
 
 
; system shutdown request
 
cmp [0xFF00],byte 0
je noshutdown
 
mov edx,[shutdown_processes]
sub dl,2
 
cmp [0xff00],dl
jne no_mark_system_shutdown
 
mov edx,0x3040
movzx ecx,byte [0xff00]
add ecx,5
markz:
mov [edx+TASKDATA.state],byte 3
add edx,0x20
loop markz
 
no_mark_system_shutdown:
 
call [disable_mouse]
 
dec byte [0xff00]
 
cmp [0xff00],byte 0
je system_shutdown
 
noshutdown:
 
 
mov eax,[0x3004] ; termination
mov ebx,0x3020+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 eax,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,[dlye] ; ecx = area y end ebx = window y start
cmp ecx,ebx
jb ricino
 
mov ecx,[dlxe] ; 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,[dly] ; eax = area y start edx = window y end
cmp edx,eax
jb ricino
 
mov eax,[dlx] ; eax = area x start ecx = window x end
cmp ecx,eax
jb ricino
 
bgli:
 
cmp edi,esi
jz ricino
 
mov eax,edi
add eax,draw_data-window_data
 
mov ebx,[dlx] ; set limits
mov [eax + RECT.left], ebx
mov ebx,[dly]
mov [eax + RECT.top], ebx
mov ebx,[dlxe]
mov [eax + RECT.right], ebx
mov ebx,[dlye]
mov [eax + RECT.bottom], ebx
 
sub eax,draw_data-window_data
 
cmp ecx,1
jne nobgrd
cmp esi,1
je newdw8
call drawbackground
 
newdw8:
nobgrd:
 
mov [eax + WDATA.fl_redraw],byte 1 ; mark as redraw
 
ricino:
 
not_this_task:
 
pop ecx
 
cmp ecx,[0x3004]
jle newdw2
 
pop eax
popad
 
ret
 
calculatebackground: ; background
 
; all black
 
mov [display_data-8],dword 4 ; size x
mov [display_data-4],dword 2 ; size y
 
mov edi, 0x300000 ; set background to black
xor eax, eax
mov ecx, 0x0fff00 / 4
cld
rep stosd
 
mov edi,display_data ; set os to use all pixels
mov eax,0x01010101
mov ecx,0x1fff00 / 4
rep stosd
 
mov byte [0xFFF0], 0 ; do not draw background!
 
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:
push edi
 
mov edi,[0x3010]
mov [edi+TASKDATA.event_mask],eax
 
pop edi
ret
 
 
 
delay_hs: ; delay in 1/100 secs
push eax
push ecx
push edx
 
mov edx,[timer_ticks]
add edx,eax
 
newtic:
mov ecx,[timer_ticks]
cmp edx,ecx
jbe zerodelay
 
call change_task
 
jmp newtic
 
zerodelay:
pop edx
pop ecx
pop eax
 
ret
 
 
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,[0x3010]
; 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 edi,[0x3010]
add eax,[edi+TASKDATA.mem_start]
 
cmp ebx,16
jae .not_owner
mov edi,[0x3010]
mov edi,[edi+TASKDATA.pid]
cmp edi,[irq_owner+ebx*4]
je spril1
.not_owner:
mov [esp+36],dword 1
ret
spril1:
 
mov esi,eax
shl ebx,6
add ebx,irq00read
mov edi,ebx
mov ecx,16
cld
rep movsd
mov [esp+36],dword 0
ret
 
 
align 4
 
get_irq_data:
cmp eax,16
jae .not_owner
mov edx,eax ; check for correct owner
shl edx,2
add edx,irq_owner
mov edx,[edx]
mov edi,[0x3010]
mov edi,[edi+TASKDATA.pid]
cmp edx,edi
je gidril1
.not_owner:
mov [esp+32],dword 2 ; ecx=2
ret
 
gidril1:
 
mov ebx,eax
shl ebx,12
add ebx,0x2e0000
mov eax,[ebx]
mov ecx,1
test eax,eax
jz gid1
 
dec eax
mov esi,ebx
mov [ebx],eax
movzx ebx,byte [ebx+0x10]
add esi,0x10
mov edi,esi
inc esi
mov ecx,4000 / 4
cld
rep movsd
; xor ecx,ecx ; as result of 'rep' ecx=0
gid1:
mov [esp+36],eax
mov [esp+32],ecx
mov [esp+24],ebx
ret
 
 
set_io_access_rights:
 
pushad
 
mov edi,[0x3000]
imul edi,tss_step
add edi,tss_data+128
; add edi,128
 
mov ecx,eax
and ecx,7 ; offset in byte
 
shr eax,3 ; number of byte
add edi,eax
 
mov ebx,1
shl ebx,cl
 
cmp ebp,0 ; enable access - ebp = 0
jne siar1
 
not ebx
and [edi],byte bl
 
popad
 
ret
 
siar1:
 
or [edi],byte bl ; disable access - ebp = 1
 
popad
 
ret
 
 
 
 
 
r_f_port_area:
 
test eax, eax
jnz free_port_area
; je r_port_area
; jmp free_port_area
 
; r_port_area:
 
pushad
 
cmp ebx,ecx ; beginning > end ?
ja rpal1
cmp ecx,65536
jae rpal1
mov esi,[0x2d0000]
test esi,esi ; no reserved areas ?
je rpal2
cmp esi,255 ; max reserved
jae rpal1
rpal3:
mov edi,esi
shl edi,4
add edi,0x2d0000
cmp ebx,[edi+8]
ja rpal4
cmp ecx,[edi+4]
jae rpal1
; jb rpal4
; jmp rpal1
rpal4:
 
dec esi
jnz rpal3
jmp rpal2
rpal1:
popad
mov eax,1
ret
 
rpal2:
popad
 
 
; enable port access at port IO map
cli
pushad ; start enable io map
 
cmp ecx,65536 ;16384
jae no_unmask_io ; jge
 
mov eax,ebx
 
new_port_access:
 
pushad
 
xor ebp,ebp ; enable - eax = port
call set_io_access_rights
 
popad
 
inc eax
cmp eax,ecx
jbe new_port_access
 
no_unmask_io:
 
popad ; end enable io map
sti
 
mov edi,[0x2d0000]
add edi,1
mov [0x2d0000],edi
shl edi,4
add edi,0x2d0000
mov esi,[0x3010]
mov esi,[esi+TASKDATA.pid]
mov [edi],esi
mov [edi+4],ebx
mov [edi+8],ecx
 
xor eax, eax
ret
 
 
 
 
free_port_area:
 
pushad
 
mov esi,[0x2d0000] ; no reserved areas ?
test esi,esi
je frpal2
mov edx,[0x3010]
mov edx,[edx+TASKDATA.pid]
frpal3:
mov edi,esi
shl edi,4
add edi,0x2d0000
cmp edx,[edi]
jne frpal4
cmp ebx,[edi+4]
jne frpal4
cmp ecx,[edi+8]
jne frpal4
jmp frpal1
frpal4:
dec esi
jnz frpal3
frpal2:
popad
mov eax,1
ret
frpal1:
mov ecx,256
sub ecx,esi
shl ecx,4
mov esi,edi
add esi,16
cld
rep movsb
 
dec dword [0x2d0000]
 
popad
 
 
; disable port access at port IO map
 
pushad ; start disable io map
 
cmp ecx,65536 ;16384
jge no_mask_io
 
mov eax,ebx
 
new_port_access_disable:
 
pushad
 
mov ebp,1 ; disable - eax = port
call set_io_access_rights
 
popad
 
inc eax
cmp eax,ecx
jbe new_port_access_disable
 
no_mask_io:
 
popad ; end disable io map
 
xor eax, eax
ret
 
 
reserve_free_irq:
 
mov ecx, 1
cmp ebx, 16
jae fril1
test eax,eax
jz reserve_irq
 
lea edi,[irq_owner+ebx*4]
mov edx,[edi]
mov eax,[0x3010]
cmp edx,[eax+TASKDATA.pid]
jne fril1
dec ecx
mov [edi],ecx
fril1:
mov [esp+36],ecx ; return in eax
ret
 
reserve_irq:
 
lea edi,[irq_owner+ebx*4]
cmp dword [edi], 0
jnz ril1
 
mov edx,[0x3010]
mov edx,[edx+TASKDATA.pid]
mov [edi],edx
dec ecx
ril1:
mov [esp+36],ecx ; return in eax
ret
 
 
 
drawbackground:
inc [mouse_pause]
cmp [0xfe0c],word 0x12
je dbrv20
dbrv12:
cmp [0xfe0c],word 0100000000000000b
jge dbrv20
cmp [0xfe0c],word 0x13
je dbrv20
call vesa12_drawbackground
dec [mouse_pause]
call [draw_pointer]
ret
dbrv20:
cmp [display_data-12],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
 
mov edx,ecx
mov ecx,ebx
lea ebx, [eax+std_application_base_address]
 
sys_putimage:
test ecx,0x80008000
jnz .exit
test ecx,0x0000FFFF
jz .exit
test ecx,0xFFFF0000
jnz @f
.exit:
ret
@@:
mov edi,[0x3000]
shl edi,8
add dx,word[edi+0x80000+APPDATA.wnd_clientbox.top]
rol edx,16
add dx,word[edi+0x80000+APPDATA.wnd_clientbox.left]
rol edx,16
.forced:
; mov eax, vga_putimage
cmp [0xfe0c], word 0x12
jz @f ;.doit
mov eax, vesa12_putimage
cmp [0xfe0c], word 0100000000000000b
jae @f
cmp [0xfe0c], word 0x13
jnz .doit
@@:
mov eax, vesa20_putimage
.doit:
inc [mouse_pause]
call eax
dec [mouse_pause]
jmp [draw_pointer]
 
; eax x beginning
; ebx y beginning
; ecx x end
; edx y end
; edi color
 
__sys_drawbar:
mov esi,[0x3000]
shl esi,8
add eax,[esi+0x80000+APPDATA.wnd_clientbox.left]
add ecx,[esi+0x80000+APPDATA.wnd_clientbox.left]
add ebx,[esi+0x80000+APPDATA.wnd_clientbox.top]
add edx,[esi+0x80000+APPDATA.wnd_clientbox.top]
.forced:
inc [mouse_pause]
cmp [0xfe0c],word 0x12
je dbv20
sdbv20:
cmp [0xfe0c],word 0100000000000000b
jge dbv20
cmp [0xfe0c],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 [0xf200],dword mousepointer
 
cli
; mov bl,0xa8 ; enable mouse cmd
; call kb_cmd
; call kb_read ; read status
; mov bl,0x20 ; get command byte
; call kb_cmd
; call kb_read
; or al,3 ; enable interrupt
; mov bl,0x60 ; write command
; push eax
; call kb_cmd
; pop eax
; call kb_write
; mov bl,0xd4 ; for mouse
; call kb_cmd
; mov al,0xf4 ; enable mouse device
; call kb_write
; call kb_read ; read status return
 
; com1 mouse enable
 
mov bx,0x3f8 ; combase
 
mov dx,bx
add dx,3
mov al,0x80
out dx,al
 
mov dx,bx
add dx,1
mov al,0
out dx,al
 
mov dx,bx
add dx,0
mov al,0x30*2 ; 0x30 / 4
out dx,al
 
mov dx,bx
add dx,3
mov al,2 ; 3
out dx,al
 
mov dx,bx
add dx,4
mov al,0xb
out dx,al
 
mov dx,bx
add dx,1
mov al,1
out dx,al
 
 
; com2 mouse enable
 
mov bx,0x2f8 ; combase
 
mov dx,bx
add dx,3
mov al,0x80
out dx,al
 
mov dx,bx
add dx,1
mov al,0
out dx,al
 
mov dx,bx
add dx,0
mov al,0x30*2
out dx,al
 
mov dx,bx
add dx,3
mov al,2
out dx,al
 
mov dx,bx
add dx,4
mov al,0xb
out dx,al
 
mov dx,bx
add dx,1
mov al,1
out dx,al
 
ret
 
 
_rdtsc:
bt [cpu_caps], CAPS_TSC
jnc ret_rdtsc
rdtsc
ret
ret_rdtsc:
mov edx,0xffffffff
mov eax,0xffffffff
ret
 
 
 
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
 
uglobal
msg_board_data: times 512 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
 
 
mov [msg_board_data+ecx],bl
inc ecx
and ecx, 511
mov [msg_board_count], ecx
mov [check_idle_semaphore], 5
ret
smbl1:
 
cmp eax, 2
jne smbl2
test ecx, ecx
jz smbl21
; mov edi, msg_board_data
; mov esi, msg_board_data+1
; movzx eax, byte [edi]
mov eax, msg_board_data+1
mov ebx, msg_board_data
movzx edx, byte [ebx]
call memmove
; push ecx
; shr ecx, 2
; cld
; rep movsd
; pop ecx
; and ecx, 3
; rep movsb
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
 
 
 
sys_trace:
 
test eax, eax ; get event data
jnz no_get_sys_events
 
mov esi,save_syscall_data ; data
mov edi,[0x3010]
mov edi,[edi+TASKDATA.mem_start]
add edi,ebx
cld
rep movsb
 
mov [esp+24],dword 0
mov eax,[save_syscall_count] ; count
mov [esp+36],eax
ret
 
no_get_sys_events:
 
ret
 
 
sys_process_def:
mov edi, [0x3000]
 
dec eax ; 1 = set keyboard mode
jne no_set_keyboard_setup
 
shl edi,8
mov [edi+0x80000 + APPDATA.keyboard_mode],bl
 
ret
 
no_set_keyboard_setup:
 
dec eax ; 2 = get keyboard mode
jne no_get_keyboard_setup
 
shl edi,8
movzx eax, byte [0x80000+edi + APPDATA.keyboard_mode]
 
mov [esp+36],eax
 
ret
 
no_get_keyboard_setup:
 
dec eax ; 3 = get keyboard ctrl, alt, shift
jne no_get_keyboard_cas
 
; 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
 
;// mike.dld [
mov eax, [kb_state]
;// mike.dld ]
 
mov [esp+36],eax
 
ret
 
no_get_keyboard_cas:
 
dec eax
jnz no_add_keyboard_hotkey
 
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+36], 1
ret
.found_free:
mov [eax+8], edi
mov [eax+4], ecx
movzx ebx, bl
lea ebx, [hotkey_scancodes+ebx*4]
mov ecx, [ebx]
mov [eax], ecx
mov [ebx], eax
mov [eax+12], ebx
jecxz @f
mov [ecx+12], eax
@@:
and dword [esp+36], 0
ret
 
no_add_keyboard_hotkey:
 
dec eax
jnz no_del_keyboard_hotkey
 
movzx ebx, bl
lea ebx, [hotkey_scancodes+ebx*4]
mov eax, [ebx]
.scan:
test eax, eax
jz .notfound
cmp [eax+8], edi
jnz .next
cmp [eax+4], ecx
jz .found
.next:
mov eax, [eax]
jmp .scan
.notfound:
mov dword [esp+36], 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+36], edx
ret
 
no_del_keyboard_hotkey:
ret
 
 
align 4
 
sys_gs: ; direct screen access
 
cmp eax,1 ; resolution
jne no_gs1
mov eax,[0xfe00]
shl eax,16
mov ax,[0xfe04]
add eax,0x00010001
mov [esp+36],eax
ret
no_gs1:
 
cmp eax,2 ; bits per pixel
jne no_gs2
movzx eax,byte [0xfbf1]
mov [esp+36],eax
ret
no_gs2:
 
cmp eax,3 ; bytes per scanline
jne no_gs3
mov eax,[0xfe08]
mov [esp+36],eax
ret
no_gs3:
 
mov [esp+36],dword -1
ret
 
 
align 4 ; PCI functions
 
sys_pci:
 
call pci_api
mov [esp+36],eax
ret
 
 
align 4 ; system functions
 
syscall_setpixel: ; SetPixel
 
 
mov edx,[0x3010]
add eax,[edx-twdw+WDATA.box.left]
add ebx,[edx-twdw+WDATA.box.top]
mov edi,[0x3000]
shl edi,8
add eax,[edi+0x80000+APPDATA.wnd_clientbox.left]
add ebx,[edi+0x80000+APPDATA.wnd_clientbox.top]
xor edi,edi ; no force
; mov edi,1
call [disable_mouse]
jmp [putpixel]
 
align 4
 
syscall_writetext: ; WriteText
 
mov edi,[0x3010]
mov ebp,[edi-twdw+WDATA.box.left]
push esi
mov esi,[0x3000]
shl esi,8
add ebp,[esi+0x80000+APPDATA.wnd_clientbox.left]
shl ebp,16
add ebp,[edi-twdw+WDATA.box.top]
add bp,word[esi+0x80000+APPDATA.wnd_clientbox.top]
pop esi
add ecx,[edi+TASKDATA.mem_start]
add eax,ebp
xor edi,edi
jmp dtext
 
align 4
 
syscall_openramdiskfile: ; OpenRamdiskFile
 
 
mov edi,[0x3010]
add edi,TASKDATA.mem_start
add eax,[edi]
add edx,[edi]
mov esi,12
call fileread
mov [esp+36],ebx
ret
 
align 4
 
syscall_drawrect: ; DrawRect
 
mov edi,ecx
and edi,0x80FFFFFF
test ax,ax
je drectr
test bx,bx
je drectr
movzx ecx,ax
shr eax,16
movzx edx,bx
shr ebx,16
mov esi,[0x3000]
shl esi,8
add eax,[esi+0x80000+APPDATA.wnd_clientbox.left]
add ebx,[esi+0x80000+APPDATA.wnd_clientbox.top]
add ecx,eax
add edx,ebx
jmp [drawbar]
drectr:
ret
 
align 4
 
syscall_getscreensize: ; GetScreenSize
 
movzx eax,word[0xfe00]
shl eax,16
mov ax,[0xfe04]
mov [esp+36],eax
ret
 
align 4
 
syscall_cdaudio: ; CD
 
call sys_cd_audio
mov [esp+36],eax
ret
 
align 4
 
syscall_delramdiskfile: ; DelRamdiskFile
 
mov edi,[0x3010]
add edi,TASKDATA.mem_start
add eax,[edi]
call filedelete
mov [esp+36],eax
ret
 
align 4
 
syscall_writeramdiskfile: ; WriteRamdiskFile
 
mov edi,[0x3010]
add edi,TASKDATA.mem_start
add eax,[edi]
add ebx,[edi]
call filesave
mov [esp+36],eax
ret
 
align 4
 
syscall_getpixel: ; GetPixel
mov ecx,[0xfe00]
inc ecx
xor edx,edx
div ecx
mov ebx,edx
xchg eax,ebx
call dword [0xe024]
mov [esp+36],ecx
ret
 
align 4
 
syscall_readstring: ; ReadString
 
mov edi,[0x3010]
add edi,TASKDATA.mem_start
add eax,[edi]
call read_string
mov [esp+36],eax
ret
 
align 4
 
syscall_drawline: ; DrawLine
 
mov edi,[0x3010]
movzx edx,word[edi-twdw+WDATA.box.left]
mov ebp,edx
mov esi,[0x3000]
shl esi,8
add ebp,[esi+0x80000+APPDATA.wnd_clientbox.left]
add dx,word[esi+0x80000+APPDATA.wnd_clientbox.left]
shl edx,16
add ebp,edx
movzx edx,word[edi-twdw+WDATA.box.top]
add eax,ebp
mov ebp,edx
add ebp,[esi+0x80000+APPDATA.wnd_clientbox.top]
add dx,word[esi+0x80000+APPDATA.wnd_clientbox.top]
shl edx,16
xor edi,edi
add edx,ebp
add ebx,edx
jmp [draw_line]
 
align 4
 
syscall_getirqowner: ; GetIrqOwner
cmp eax,16
jae .err
shl eax,2
add eax,irq_owner
mov eax,[eax]
mov [esp+36],eax
ret
.err:
or dword [esp+36], -1
ret
 
align 4
 
syscall_reserveportarea: ; ReservePortArea and FreePortArea
 
call r_f_port_area
mov [esp+36],eax
ret
 
align 4
 
syscall_threads: ; CreateThreads
 
call sys_threads
mov [esp+36],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+36],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
 
user_events: ; User event times
 
mov eax,0x12345678
mov [esp+36],eax
 
ret
 
align 4
 
read_from_hd: ; Read from hd - fn not in use
 
mov edi,[0x3010]
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
 
 
; --------------- APM ---------------------
apm_entry dp 0
apm_vf dd 0
align 4
sys_apm:
cmp word [apm_vf], 0 ; Check APM BIOS enable
jne @f
or [esp + 56], byte 1 ; error
mov [esp + 36], dword 8 ; 32-bit protected-mode interface not supported
ret
 
@@: xchg eax, ecx
xchg ebx, ecx
 
cmp al, 3
ja @f
and [esp + 56], byte 0xfe ; emulate func 0..3 as func 0
mov eax, [apm_vf]
mov [esp + 36], eax
shr eax, 16
mov [esp + 32], eax
ret
 
@@: call pword [apm_entry] ; call APM BIOS
mov [esp + 8 ], edi
mov [esp + 12], esi
mov [esp + 24], ebx
mov [esp + 28], edx
mov [esp + 32], ecx
mov [esp + 36], eax
setc al
and [esp + 56], byte 0xfe
or [esp + 56], al
ret
; -----------------------------------------
 
align 4
 
undefined_syscall: ; Undefined system call
 
mov [esp+36],dword -1
ret
 
 
;clear_busy_flag_at_caller:
 
; push edi
 
; mov edi,[0x3000] ; restore processes tss pointer in gdt, busyfl?
; imul edi,8
; mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b
 
; pop edi
 
; ret
 
 
 
 
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'
 
 
; device irq owners
uglobal
irq_owner: ; process id
 
dd 0x0
dd 0x0
dd 0x0
dd 0x0
dd 0x0
dd 0x0
dd 0x0
dd 0x0
dd 0x0
dd 0x0
dd 0x0
dd 0x0
dd 0x0
dd 0x0
dd 0x0
dd 0x0
endg
 
 
; on irq read ports
uglobal
irq00read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq01read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq02read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq03read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq04read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq05read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq06read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq07read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq08read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq09read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq10read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq11read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq12read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq13read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq14read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
irq15read dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
endg
 
; status
uglobal
hd1_status dd 0x0 ; 0 - free : other - pid
application_table_status dd 0x0 ; 0 - free : other - pid
endg
 
; device addresses
uglobal
mididp dd 0x0
midisp dd 0x0
 
cdbase dd 0x0
cdid dd 0x0
 
hdbase dd 0x0 ; for boot 0x1f0
hdid dd 0x0
hdpos dd 0x0 ; for boot 0x1
fat32part dd 0x0 ; for boot 0x1
 
;part2_ld dd 0x0
 
;* start code - Mario79
mouse_pause dd 0
MouseTickCounter dd 0
ps2_mouse_detected db 0
com1_mouse_detected db 0
com2_mouse_detected db 0
;* end code - Mario79
 
wraw_bacground_select db 0
lba_read_enabled dd 0x0 ; 0 = disabled , 1 = enabled
pci_access_enabled dd 0x0 ; 0 = disabled , 1 = enabled
 
sb16 dd 0x0
wss dd 0x0
 
buttontype dd 0x0
windowtypechanged dd 0x0
 
align 4
pg_data PG_DATA
heap_test dd ?
cpu_caps dd 4 dup(0)
endg
 
iglobal
keyboard dd 0x1
sound_dma dd 0x1
syslang dd 0x1
endg
 
IncludeIGlobals
endofcode:
IncludeUGlobals
uglobals_size = $ - endofcode
diff16 "end of kernel code",0,$
 
/kernel/tags/kolibri0.6.3.0/docs/sysfuncs.txt
0,0 → 1,4511
SYSTEM FUNCTIONS of OS Kolibri 0.6.0.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
* other possible values (from 4 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 style Y=3 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 is reserved (set to 0)
* 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 style Y=3 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.
* At current implementation there will be an immediate return from
the function, if the addition of ebx with current value of
time counter will call 32-bit overflow.
 
======================================================================
============== 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.
* The normal applications are placed in memory at the address
0x60400000 (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:
* There is no checks for correctness. The setting of too large
values will result that the background will contain data abroad
of buffer for the background image. Buffer size = 0x160000-0x10,
that corresponds to maximum size 800*600. (800*600*3=0x15F900)
* 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 0x160000-16 = 1.375 Mb - 16 bytes,
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:
* If the block gets out abroad 0x160000-16 = 1.375 Mb - 16 bytes,
the call is ignored.
* 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 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, function returns al=0,
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).
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".
 
======================================================================
============ Function 18, subfunction 1 - system shutdown. ===========
======================================================================
Parameters:
* eax = 18 - function number
* ebx = 1 - subfunction number
Returned value:
* function always return eax = 0 as tag of success
Remarks:
* On the last step menu of exit from the system appears and waits
response of the user.
* See also subfunction 9, system shutdown with
the parameter to force the choice in the exit menu.
 
======================================================================
= 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 defines path to the file:
* 1 = in the folder "/KOLIBRI"
* 2 = in the root folder
* 3 = edx points to the path (names of folders in the format 8+3,
divided by '/')
Returned value:
* eax = 0 - success
* else eax = error code of the file system
Çàìå÷àíèÿ:
* Filename is fixed, "menuet.img" (global kernel variable
'image_save' from 'preboot.inc')
* Drive and partition are defined by subfunction 7
and subfunction 8 of function 21.
* 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:
* 1 = on the last step of shutdown save ramdisk on a floppy and
then show the exit menu and request further operations
from the user
* 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.
* It is possible to use subfunction 1, that on the last step
the user makes choice himself.
* It is not recommended to use value ecx=1 (to not irritate the user
with excessive questions); to save ramdisk on a floppy use
function 16 (which admits specification, on which floppy to
write), and to shutdown with the exit menu use already mentioned
subfunction 1.
 
======================================================================
===== 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 and FAT32 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: dword: sectors per one copy of FAT
* +12 = +0xC: dword: number of copies of FAT
* +16 = +0x10: dword: number of sectors per cluster
* +20 = +0x14: dword: bytes per sector;
current implementation expects 0x200 = 512 in this field
* +24 = +0x18: dword: first root cluster in FAT32, 0 for FAT16
* +28 = +0x1C: dword: first physical sector of FAT
* +32 = +0x20: dword: first physical root sector for FAT16,
ignored for FAT32
* +36 = +0x24: dword: number of root sectors for FAT16,
0 for FAT32
* +40 = +0x28: dword: physical sector of the beginning of
the data area
* +44 = +0x2C: dword: maximum number of a cluster
* +48 = +0x30: dword: physical sector of the information
about the file system for FAT32, ignored for FAT16
* +52 = +0x34: dword: value used as boundary for special
values in FAT
* +56 = +0x38: dword: value used for bad clusters in FAT
* +60 = +0x3C: dword: value used as the end marker for FAT chain
* +64 = +0x40: dword: mask for FAT items
* +68 = +0x44: byte: file system type: 16 èëè 32
* +69 = +0x45: 31 db: reserved
Remarks:
* The short table can be used for obtaining the information about
available devices.
* First two fields in the information about partition
gives the parameters of partition, other - parameters of
FAT file system. For other file systems (when they will be
supported) specific for file system information will be, of
course, another, but first two fields will have the same sense.
 
======================================================================
========== 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
db 'name',0 - ASCIIZ-string with the name
For Kolibri 0.5.8.1 kernel:
db 0,5,8,1
db 2
db 'Kolibri',0
 
======================================================================
======= 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
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 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 4 - set Sound Blaster base port. =====
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 4 - subfunction number
* ecx = number of the base port
Returned value:
* eax = 0 - success
* eax = -1 - erratic port number
Remarks:
* Number of the port must satisfy to conditions 0x100<=ecx<=0xFFFF.
* The installation of the base is necessary for
functions 25, 28, 55.
* To get base port use subfunction 4 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 6 - set WSS base port. ==========
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 6 - subfunction number
* ecx = base port
Returned value:
* eax = 0 - success
* eax = -1 - erratic port number
Remarks:
* Port number must satisfy to condition 0x100<=ecx.
* WSS base is used by function 27.
* To get WSS base port use subfunction 6 of function 26.
 
======================================================================
============== Function 21, subfunction 7 - set HD base. =============
======================================================================
The HD base defines hard disk to write with usage of obsolete
file system functions and functions implicitly using the hard disk
(such as subfunction 6 of function 18);
at usage of function 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3
these function set base themselves.
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 file system functions and functions implicitly
using the hard disk (such as subfunction 6 of function 18);
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3
these functions set base and partition themselves.
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 10 - set sound DMA channel. ========
======================================================================
Parameters:
* eax = 21 - function number
* ebx = 10 - subfunction number
* ecx = number of channel (from 0 up to 3 inclusively)
Returned value:
* eax = 0 - success
* eax = -1 - incorrect channel number
Remarks:
* Number of DMA channel is used in subfunction 1 of function 55.
* To get sound DMA channel use subfunction 10 of function 26.
 
======================================================================
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
Çàìå÷àíèÿ:
* Previously CD base port must be defined by call to
subfunction 3 of function 21.
 
======================================================================
=================== Function 25 - set SBPro volume. ==================
======================================================================
Parameters:
* eax = 25 - function number
* ebx = what to set:
* 1 - set common volume
* 2 - set CD-audio volume
* cl = volume level: high 4 bits for the left column,
low 4 bits for the right one
Returned value:
* eax = 0 - success
* eax = 1 - SB base is not defined
* eax = 2 - incorrect subfunction
Remarks:
* Previously SB base port must be defined by
subfunction 4 of function 21.
* See also function 28 which sets
volume for the later standard SB16.
 
======================================================================
======== 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 4 - get Sound Blaster base port. =====
======================================================================
Parameters:
* eax = 26 - function number
* ebx = 4 - subfunction number
Returned value:
* eax = base port number
Remarks:
* Bae port is used by functions 25, 55.
* To set base port use subfunction 4 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 6 - get WSS base port. ==========
======================================================================
Parameters:
* eax = 26 - function number
* ebx = 6 - subfunction number
Returned value:
* eax = base port
Remarks:
* WSS base is used by function 27.
* To set WSS base port use subfunction 6 of function 21.
 
======================================================================
============== Function 26, subfunction 7 - get HD base. =============
======================================================================
The HD base defines hard disk to write with usage of obsolete
file system functions and functions implicitly using the hard disk
(such as subfunction 6 of function 18);
at usage of function 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3
these function set base themselves.
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 file system functions and functions implicitly
using the hard disk (such as subfunction 6 of function 18);
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3
these functions set base and partition themselves.
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 10 - get sound DMA channel. ========
======================================================================
Parameters:
* eax = 26 - function number
* ebx = 10 - subfunction number
Returned value:
* eax = number of the channel (from 0 to 3 inclusive)
Remarks:
* Number of the DMA channel is used by subfunction 1 of function 55.
* To set the sound DMA channel use subfunction 10 of function 21.
 
======================================================================
===================== 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 27 - set Windows Sound System (WSS) volume. ========
======================================================================
Parameters:
* eax = 27 - function number
* ebx = what to set:
* 1 - set common volume
* 2 - set Line In volume
* cl = volume level (0x0=highest, 0x1F=lowest,
if bit 0x80 is set=disable)
Returned value:
* eax = 0 - success
* eax = 1 - WSS base is not defined
* eax = 2 - incorrect subfunction
Remarks:
* Previously WSS base port must be defined by call to
subfunction 6 of function 21.
* Set of common volume is ignored (function simply returns eax=0).
* Old documentation and kernel sources erraticly name function 2
as CD-audio volume.
 
======================================================================
=================== Function 28 - set SB16 volume. ===================
======================================================================
Parameters:
* eax = 28 - function number
* ebx = what to install:
* 1 - install common volume
* 2 - install CD-audio volume
* cl = volume level (0=off, 0xFF=max)
Returned value:
* eax = 0 - success
* eax = 1 - SB base is not defined
* eax = 2 - incorrect subfunction
Remarks:
* Previously SB base port must be defined by
subfunction 4 of function 21.
* This function gives more variants for volume, that function 25.
 
======================================================================
=================== 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 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 37 - get coordinates/status of the 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
* other bits are cleared
 
======================================================================
====================== 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:
* function does not return value
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 - read 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
bytewise.
Parameters:
* eax = 42 - function number
* ebx = IRQ number, 0..15
Returned value: (use value of ecx to distinguish)
* if the thread is not IRQ owner (or IRQ number is incorrect):
* ecx = 2
* if there is no data:
* eax = 0
* ecx = 1
* ebx destroyed
* if all is ok:
* eax = byte size of data, not yet read from buffer
* ecx = 0
* ebx = current byte
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..0xff, and if
COM-mouse is detected - additionally range of COM-ports
0x3f0..0x3ff and/or 0x2f0..0x2ff.
* 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-number
* bh = 0 - display in decimal number system
* bh = 1 - display in hexadecimal system
* bh = 2 - display in binary system
* áèòû 16-21 = how many digits to display
* áèòû 22-31 reserved and must be set to 0
* 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 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)
* 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.
* The current implementation does no checks on correctness
(function returns error only if thread tries to close not opened
socket with correct handle).
 
======================================================================
============== 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
* ebx destroyed
Remarks:
* There is no checks for correctness.
 
======================================================================
========= 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: 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
Remarks:
* There is no checks for correctness.
 
======================================================================
========== 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 - invalid handle
* eax = 0xffff - not enough memory
* eax = 0 - success
* ebx destroyed
Remarks:
* Check on validity of handle is minimal - only not very incorrect
not opened handles are eliminated.
* 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)
* 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 = 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 destroys
Remarks:
* There is no checks for correctness.
 
======================================================================
========== 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
* eax = 0xffff - not enough memory
* eax = 0 - success
* ebx destroyed
Remarks:
* Check on validity of handle is minimal - only not very incorrect
not opened handles are eliminated.
* 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 - invalid handle
* eax = 0xffff - not enough memory for socket close packet
* eax = 0 - success
* in many cases eax is destroyed (the result of function 'queue'
is returned) - probably this is bug, which will be corrected
* 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.
* The current implementation does no checks on correctness
(function returns error only if thread tries to close not opened
socket with correct handle).
 
======================================================================
=== 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 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 0 - load data for SB16. ==========
======================================================================
Parameters:
* eax = 55 - function number
* ebx = 0 - subfunction number
* ecx = pointer to data (is copied 64 kilobytes, is used as much as
set by subfunction 2)
Returned value:
* function does not return value
Remarks:
* Format and size of data are set by subfunction 2.
 
======================================================================
======== Function 55, subfunction 1 - begin play data on SB16. =======
======================================================================
Parameters:
* eax = 55 - function number
* ebx = 1 - subfunction number
Returned value:
* function does not return value
Remarks:
* Previously data must be loaded by subfunction 0 and
their format must be defined by subfunction 2.
* Function returns control, when playing of data began; after that
play goes independently from application (and does not use
processor time at all).
* Previously must be defined SB16 base port
(by subfunction 4 of function 21) and DMA channel
(by subfunction 10 of function 21).
 
======================================================================
======== Function 55, subfunction 2 - set format of SB16 data. =======
======================================================================
Parameters:
* eax = 55 - function number
* ebx = 2 - subfunction number
* ecx = 0 - set digit capacity
* edx = 1 - 8bit mono
* edx = 2 - 8bit stereo
* ecx = 1 - set data size
* edx = size in bytes
* ecx = 2 - set play frequency
* edx = frequency
Returned value:
* function does not return value
Remarks:
* When the system boots, it sets following default parameters:
digit capacity - 8bit mono, size - 64 Kb, frequency - 44100 Hz.
Nevertheless it is recommended to set necessary values obviously
as they could be reset by some application.
 
======================================================================
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 56 - write file to hard disk. ===============
======================================================================
Parameters:
* eax = 56 - function number
* ebx = pointer to the file name
* ecx = size of data to write (in bytes)
* edx = pointer to data to write
* esi = pointer to path (ASCIIZ-string)
Returned value:
* eax = 0 - success, otherwise file system error code
Remarks:
* This function is obsolete; function 70 allows to fulfil the same
operations with the extended possibilities.
* This function assumes that during its call by one application
no other application works with hard disk.
* The path to file is ASCIIZ-string, which may be empty
(if the file is created in the root folder) or have the format
/d1/d2/.../dn, where all folder names must have the 8+3 format,
i.e. 8 characters of name and 3 characters of the extension
without separator, supplemented by blanks if necessary;
all letters must be capital.
* The file name must also have the format 8+3.
 
======================================================================
================ 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 1 - rewrite file
* subfunction 4 - make folder
* subfunction 5 - rename/move 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 1 - rewrite file. =============
======================================================================
If the file does not exist, it is created.
If the file exists, it is rewritten.
Parameters:
* eax = 58 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 1 = subfunction number
* +4: dword: ignored (set to 0)
* +8: dword: number of bytes to write
* +12 = +0xC: dword: pointer to data to write
* +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 destroyed
Remarks:
* This function is obsolete, use subfunction 2 of function 70.
 
======================================================================
============== Function 58, subfunction 4 - make folder. =============
======================================================================
Parameters:
* eax = 58 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 4 = subfunction number
* +4: dword: ignored
* +8: dword: ignored
* +12 = +0xC: dword: ignored
* +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 destroyed
Remarks:
* Ramdisk and floppies do not support this function, it is only
for hard disks.
 
======================================================================
======== Function 58, subfunction 5 - rename/move file/folder. =======
======================================================================
Parameters:
* eax = 58 - function number
* ebx = pointer to the information structure
Format of the information structure:
* +0: dword: 5 = subfunction number
* +4: dword: ignored
* +8: dword: ignored
* +12 = +0xC: dword: ignored
* +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
* +20+n: (at once after terminating null character) new
ASCIIZ-name, must start from /hd/1, that is interpreted as
the hard disk, indicated in the first name
(moving from one disk to another is not supported)
Returned value:
* eax = 0 - success, otherwise file system error code
* ebx destroyed
Remarks:
* Ramdisk and floppies do not support this function, it is only
for hard disks.
* If the new ASCIIZ-name is strongly incorrect, i.e. does not start
from /hd/1, /hd/first, /harddisk/1, /harddisk/first or after this
space or null character follows, function returns, strangely
enough, error code 4. It is the only function which returns
this code.
 
======================================================================
========= 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 59 - trace last system calls. ===============
======================================================================
Gets data on all system calls of all processes.
Parameters:
* eax = 59 - function number
* ebx = 0 - unique subfunction
* ecx = pointer to the buffer
* edx = size of the buffer
Returned value:
* eax = total number of system calls made from system boot
(modulo 2^32)
* ebx = 0
Format of information on one call: (size = 0x40 = 64 bytes)
* +0: dword: PID of process/thread
* +4: 7*dword: garbage
* +32 = +0x20: dword: value of edi at the call
* +36 = +0x24: dword: esi
* +40 = +0x28: dword: ebp
* +44 = +0x2C: dword: stack pointer of the kernel handler
* +48 = +0x30: dword: ebx
* +52 = +0x34: dword: edx
* +56 = +0x38: dword: ecx
* +60 = +0x3C: dword: eax (=number of system function)
Remarks:
* The function is used only in the application 'systrace'.
It is rather difficult to imagine a situation, in which
this application or this function are really useful;
and all system calls for support of this function are a little
decelerated (though not strongly)...
* So there is a proposition to delete from the kernel
support of this function, together with application 'systrace'.
* The information on system calls saves in the system
ring buffer with 0x10 entries.
This function simply copies the given size of data
from this buffer to the given address.
* One can determine, which entry in the buffer corresponds to
last system call, by value of eax, namely, it is the entry
(eax and 0xF) (at offset (eax and 0xF)*0x40).
* In the current implementation there can be the seldom
meeting problems of unsynchronization, when the information
on some calls becomes outdated.
* Under the system buffer one page, 4Kb, is allocated.
Size of an entry = 64 bytes. Why only 16 entries are used,
is not clearly.
* The value of esp at the moment of system call cannot
be determined by this function.
* The current implementation does not check edx for correctness.
 
======================================================================
========== 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 63 - work with the debug board. ==============
======================================================================
The debug board is the global system buffer (with the size
512 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 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.
 
-------------- 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:
* ebx:eax = copy of esi:edi
Çàìå÷àíèÿ:
* 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.
 
======================================================================
======== Function 68, subfunction 14 - wait for driver notify. =======
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 14 - subfunction number
* ecx = pointer to the buffer for information (8 bytes)
Returned value:
* buffer pointed to by ecx contains the following information:
* +0: dword: constant EV_INTR = 1
* +4: dword: driver data
Remarks:
* The current implementation at wait time uses "heavy" operations
of task switch.
 
======================================================================
====== Function 68, subfunction 15 - set FPU exception handler. ======
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 15 - subfunction number
* ecx = address of the new exception handler
Returned value:
* eax = address of the old exception handler (0, if it was not set)
 
======================================================================
============= 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.
* The function can load only drivers which are registered in the
system; the current implementation contains
exactly 2 such drivers:
* name SOUND, file /rd/1/unisound.obj
* name INFINITY, file /rd/1/infinity.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 = determined by driver
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. ======
======================================================================
Parameters:
* eax = 68 - function number
* ebx = 15 - subfunction number
* ecx = address of the new exception handler
Returned value:
* eax = address of the old exception handler (0, if it was not set)
 
======================================================================
====================== 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 58 or 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)
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
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
For CD-drives due to hardware limitations only subfunctions
0,1,5 and 7 are available, other subfunctions return error
with code 2.
 
======================================================================
=== 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
* äëÿ ôîðìàòà UNICODE: 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 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 -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 = is returned only from function 'rename' by transmission of
the strongly incorrect parameter and in any way does not
correspond to the description in the kernel sources
"partition not defined at hd"
* 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/tags/kolibri0.6.3.0/docs/sysfuncr.txt
0,0 → 1,4559
‘ˆ‘’…Œ›… ”“Š–ˆˆ Ž…€–ˆŽŽ‰ ‘ˆ‘’…Œ› Kolibri 0.6.0.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 - ®ª­® ᮠ᪨­®¬
* ®áâ «ì­ë¥ ¢®§¬®¦­ë¥ §­ ç¥­¨ï (®â 4 ¤® 15) § à¥§¥à¢¨à®¢ ­ë,
¢ë§®¢ ä㭪樨 á â ª¨¬¨ Y ¨£­®à¨àã¥âáï
* RR, GG, BB = ᮮ⢥âá⢥­­® ªà á­ ï, §¥«¥­ ï, ᨭïï
á®áâ ¢«ïî騥 æ¢¥â  à ¡®ç¥© ®¡« á⨠®ª­ 
(¨£­®à¨àã¥âáï ¤«ï á⨫ï Y=2)
* X = DCBA (¡¨âë)
* A = 1 - ã ®ª­  ¥áâì § £®«®¢®ª; ¤«ï á⨫ï Y=3  ¤à¥á áâப¨
§ £®«®¢ª  § ¤ ñâáï ¢ edi, ¤«ï ¯à®ç¨å á⨫¥©
¨á¯®«ì§ã¥âáï ¯®¤äã­ªæ¨ï 1 ä㭪樨 71
* B = 1 - ª®®à¤¨­ âë ¢á¥å £à ä¨ç¥áª¨å ¯à¨¬¨â¨¢®¢ § ¤ îâáï
®â­®á¨â¥«ì­® ª«¨¥­â᪮© ®¡« á⨠®ª­ 
* C § à¥§¥à¢¨à®¢ ­ (ãáâ ­ ¢«¨¢ ©â¥ ¢ 0)
* 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 á § £®«®¢ª®¬ (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.
* à¨ ⥪ã饩 ॠ«¨§ æ¨¨ ¯à®¨§®©¤¥â ­¥¬¥¤«¥­­ë© ¢®§¢à â ¨§ ä㭪樨,
¥á«¨ á«®¦¥­¨¥ ebx á ⥪ã騬 §­ ç¥­¨¥¬ áç¥â稪  ¢à¥¬¥­¨ ¢ë§®¢¥â
32-¡¨â­®¥ ¯¥à¥¯®«­¥­¨¥.
 
======================================================================
=============== ”ã­ªæ¨ï 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, à §¬¥é îâáï ®¡ëç­ë¥ ¯à¨«®¦¥­¨ï.
* Ž¡ëç­ë¥ ¯à¨«®¦¥­¨ï à §¬¥é îâáï ¢ ¯ ¬ï⨠¯®  ¤à¥áã 0x60400000
(ª®­áâ ­â  ï¤à  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 = ¢ëá®â  ¨§®¡à ¦¥­¨ï
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* à®¢¥à®ª ­  ª®à४⭮áâì ­¥ ¤¥« ¥âáï. “áâ ­®¢ª  ᫨誮¬ ¡®«ìè¨å
§­ ç¥­¨© ¯à¨¢¥¤ñâ ª ⮬ã, çâ® ¢ ä®­ ¢®©¤ãâ ¤ ­­ë¥ §  £à ­¨æ¥©
¡ãä¥à  ä®­®¢®£® ¨§®¡à ¦¥­¨ï.  §¬¥à ¡ãä¥à  = 0x160000-0x10, çâ®
ᮮ⢥âáâ¢ã¥â ¬ ªá¨¬ «ì­ë¬ à §¬¥à ¬ 800*600. (800*600*3=0x15F900)
* „«ï ®¡­®¢«¥­¨ï íªà ­  (¯®á«¥ § ¢¥à襭¨ï á¥à¨¨ ª®¬ ­¤, à ¡®â îé¨å á
ä®­®¬) ¢ë§ë¢ ©â¥ ¯®¤äã­ªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä®­ .
* …áâì ¯ à­ ï äã­ªæ¨ï ¯®«ã祭¨ï à §¬¥à®¢ ä®­®¢®£® ¨§®¡à ¦¥­¨ï -
¯®¤äã­ªæ¨ï 1 ä㭪樨 39.
 
======================================================================
= ”ã­ªæ¨ï 15, ¯®¤äã­ªæ¨ï 2 - ¯®áâ ¢¨âì â®çªã ­  ä®­®¢®¬ ¨§®¡à ¦¥­¨¨. =
======================================================================
 à ¬¥âàë:
* eax = 15 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ᬥ饭¨¥
* edx = 梥â â®çª¨ 0xRRGGBB
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ‘¬¥é¥­¨¥ ¤«ï â®çª¨ á ª®®à¤¨­ â ¬¨ (x,y) ¢ëç¨á«ï¥âáï ª ª
(x+y*xsize)*3.
* …᫨ 㪠§ ­­®¥ ᬥ饭¨¥ ¯à¥¢ëè ¥â 0x160000-16 =
1.375 Mb - 16 bytes, ¢ë§®¢ ¨£­®à¨àã¥âáï.
* „«ï ®¡­®¢«¥­¨ï íªà ­  (¯®á«¥ § ¢¥à襭¨ï á¥à¨¨ ª®¬ ­¤, à ¡®â îé¨å á
ä®­®¬) ¢ë§ë¢ ©â¥ ¯®¤äã­ªæ¨î 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 * ç¨á«® ¯¨ªá¥«¥©
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* …᫨ ¡«®ª ¢ë«¥§ ¥â §  £à ­¨æã 0x160000-16 = 1.375 Mb - 16 bytes,
â® ¢ë§®¢ ¨£­®à¨àã¥âáï.
* –¢¥â ª ¦¤®£® ¯¨ªá¥«ï åà ­¨âáï ª ª 3-¡ ©â­ ï ¢¥«¨ç¨­  BBGGRR.
* ¨ªá¥«¨ ä®­®¢®£® ¨§®¡à ¦¥­¨ï § ¯¨á뢠îâáï ¯®á«¥¤®¢ â¥«ì­®
á«¥¢  ­ ¯à ¢®, ᢥàåã ¢­¨§.
* ‘¬¥é¥­¨¥ ¯¨ªá¥«ï á ª®®à¤¨­ â ¬¨ (x,y) ¥áâì (x+y*xsize)*3.
* „«ï ®¡­®¢«¥­¨ï íªà ­  (¯®á«¥ § ¢¥à襭¨ï á¥à¨¨ ª®¬ ­¤, à ¡®â îé¨å á
ä®­®¬) ¢ë§ë¢ ©â¥ ¯®¤äã­ªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä®­ .
 
======================================================================
============= ”ã­ªæ¨ï 16 - á®åà ­¨âì à ¬¤¨áª ­  ¤¨áª¥âã. =============
======================================================================
 à ¬¥âàë:
* eax = 16 - ­®¬¥à ä㭪樨
* ebx = 1 ¨«¨ ebx = 2 - ­  ª ªãî ¤¨áª¥âã á®åà ­ïâì
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ®è¨¡ª 
 
======================================================================
============== ”ã­ªæ¨ï 17 - ¯®«ãç¨âì ª®¤ ­ ¦ â®© ª­®¯ª¨. =============
======================================================================
‡ ¡¨à ¥â ª®¤ ­ ¦ â®© ª­®¯ª¨ ¨§ ¡ãä¥à .
 à ¬¥âàë:
* eax = 17 - ­®¬¥à ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¥á«¨ ¡ãä¥à ¯ãáâ, ¢®§¢à é ¥âáï eax=1
* ¥á«¨ ¡ãä¥à ­¥¯ãáâ, â® ¢®§¢à é ¥âáï al=0, áâ à訥 24 ¡¨â  eax
ᮤ¥à¦ â ¨¤¥­â¨ä¨ª â®à ª­®¯ª¨ (¢ ç áâ­®áâ¨, ¢ ah ®ª §ë¢ ¥âáï
¬« ¤è¨© ¡ ©â ¨¤¥­â¨ä¨ª â®à ; ¥á«¨ ¢á¥ ª­®¯ª¨ ¨¬¥îâ ¨¤¥­â¨ä¨ª â®à,
¬¥­ì訩 256, â® ¤«ï à §«¨ç¥­¨ï ¤®áâ â®ç­® ah)
‡ ¬¥ç ­¨ï:
* "ãä¥à" åà ­¨â ⮫쪮 ®¤­ã ª­®¯ªã, ¯à¨ ­ ¦ â¨¨ ­®¢®© ª­®¯ª¨
¨­ä®à¬ æ¨ï ® áâ à®© â¥àï¥âáï.
* à¨ ¢ë§®¢¥ í⮩ ä㭪樨 ¯à¨«®¦¥­¨¥¬ á ­¥ ªâ¨¢­ë¬ ®ª­®¬
¢®§¢à é ¥âáï ®â¢¥â "¡ãä¥à ¯ãáâ".
 
======================================================================
======== ”ã­ªæ¨ï 18, ¯®¤äã­ªæ¨ï 1 - § ¢¥àè¨âì à ¡®âã á¨á⥬ë. ========
======================================================================
 à ¬¥âàë:
* eax = 18 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¢á¥£¤  ¢®§¢à é ¥âáï eax = 0 ª ª ¯à¨§­ ª ãᯥå 
‡ ¬¥ç ­¨ï:
*   ¯®á«¥¤­¥¬ è £¥ ¯®ï¢«ï¥âáï ¬¥­î ¢ë室  ¨§ á¨á⥬ë, ®¦¨¤ î饥
ॠªæ¨¨ ¯®«ì§®¢ â¥«ï.
* ‘¬®âਠ⠪¦¥ ¯®¤äã­ªæ¨î 9, § ¢¥à襭¨¥ à ¡®âë á¨á⥬ë á ¯ à ¬¥â஬,
ç⮡ë ä®àá¨à®¢ âì ¢ë¡®à ¢ ¬¥­î ¢ë室 .
 
======================================================================
==== ”ã­ªæ¨ï 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 ®¯à¥¤¥«ï¥â ¯ãâì ª ä ©«ã:
* 1 = ¢ ¯ ¯ª¥ "/KOLIBRI"
* 2 = ¢ ª®à­¥¢®¬ ª â «®£¥
* 3 = edx 㪠§ë¢ ¥â ­  ¯ãâì (¨¬¥­  ¯ ¯®ª ¢ ä®à¬ â¥ 8+3,
à §¤¥«ñ­­ë¥ '/')
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* ¨­ ç¥ eax = ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
‡ ¬¥ç ­¨ï:
* ˆ¬ï ä ©«  䨪á¨à®¢ ­®, "menuet.img" (£«®¡ «ì­ ï ¯¥à¥¬¥­­ ï ï¤à 
image_save ¨§ preboot.inc)
*   ª ª®¬ à §¤¥«¥ ª ª®£® ¤¨áª  ä ©« ¡ã¤¥â á®åà ­ñ­, ®¯à¥¤¥«ï¥âáï
¯®¤ä㭪樥© 7 ¨ ¯®¤ä㭪樥© 8 ä㭪樨 21.
* ‚ᥠ¯ ¯ª¨ ¢ 㪠§ ­­®¬ ¯ã⨠¤®«¦­ë áãé¥á⢮¢ âì, ¨­ ç¥ ¢¥à­ñâáï
§­ ç¥­¨¥ 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 = ¯ à ¬¥âà:
* 1 = ­  ¯®á«¥¤­¥¬ è £¥ § ¢¥à襭¨ï à ¡®âë á®åà ­¨âì à ¬¤¨áª ­ 
¤¨áª¥âã, ¯®á«¥ 祣® ¢ë¢¥á⨠¬¥­î ¢ë室  ¨ § ¯à®á¨âì ã
¯®«ì§®¢ â¥«ï ¤ «ì­¥©è¨¥ ¤¥©á⢨ï
* 2 = ¢ëª«îç¨âì ª®¬¯ìîâ¥à
* 3 = ¯¥à¥§ £à㧨âì ª®¬¯ìîâ¥à
* 4 = ¯¥à¥§ ¯ãáâ¨âì ï¤à® ¨§ ä ©«  kernel.mnt ­  à ¬¤¨áª¥
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¯à¨ ­¥¢¥à­®¬ ecx ॣ¨áâàë ­¥ ¬¥­ïîâáï (â.¥. eax=18)
* ¯à¨ ¯à ¢¨«ì­®¬ ¢ë§®¢¥ ¢á¥£¤  ¢®§¢à é ¥âáï ¯à¨§­ ª ãá¯¥å  eax=0
‡ ¬¥ç ­¨ï:
* ¥ á«¥¤ã¥â ¯®« £ âìáï ­  ¢®§¢à é ¥¬®¥ §­ ç¥­¨¥ ¯à¨ ­¥¢¥à­®¬
¢ë§®¢¥, ®­® ¬®¦¥â ¨§¬¥­¨âìáï ¢ ¯®á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à .
* Œ®¦­® ¨á¯®«ì§®¢ âì ¯®¤äã­ªæ¨î 1, çâ®¡ë ­  ¯®á«¥¤­¥¬ è £¥
§ ¢¥à襭¨ï à ¡®âë ¯®«ì§®¢ â¥«ì á ¬ à¥è «, çâ® ¥¬ã ­ã¦­®.
* ¥ ४®¬¥­¤ã¥âáï ¨á¯®«ì§®¢ âì §­ ç¥­¨¥ ecx=1 (çâ®¡ë ­¥ à §¤à ¦ âì
¯®«ì§®¢ â¥«ï ¨§«¨è­¨¬¨ ¢®¯à®á ¬¨); á®åà ­¨âì à ¬¤¨áª ­  ¤¨áª¥âã
¬®¦­® ä㭪樥© 16 (ª®â®à ï ¤®¯ã᪠¥â ãâ®ç­¥­¨¥, ­  ª ªãî ¨¬¥­­®
¤¨áª¥âã ¯¨á âì),   § ¢¥àè¨âì à ¡®âã á ¬¥­î ¢ë室  ¬®¦­® 㦥
㯮¬ï­ã⮩ ¯®¤ä㭪樥© 1.
 
======================================================================
======== ”ã­ªæ¨ï 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.
* +6: 4 db: § à¥§¥à¢¨à®¢ ­®
”®à¬ â â ¡«¨æë: ¯®«­ ï ¢¥àá¨ï:
* +0: 10 db: â ª¨¥ ¦¥, ª ª ¨ ¢ ª®à®âª®© ¢¥àᨨ
* +10: 100 db: ¤ ­­ë¥ ¤«ï ¯¥à¢®£® à §¤¥« 
* +110: 100 db: ¤ ­­ë¥ ¤«ï ¢â®à®£® à §¤¥« 
* ...
* +10+100*(n-1): 100 db: ¤ ­­ë¥ ¤«ï ¯®á«¥¤­¥£® à §¤¥« 
 §¤¥«ë à á¯®«®¦¥­ë ¢ á«¥¤ãî饬 ¯®à浪¥: á­ ç «  ¯®á«¥¤®¢ â¥«ì­® ¢á¥
à á¯®§­ ­­ë¥ à §¤¥«ë ­  HD ­  IDE0 (¥á«¨ ¥áâì),
§ â¥¬ ­  HD ­  IDE1 (¥á«¨ ¥áâì) ¨ â.¤. ¤® IDE3.
”®à¬ â ¨­ä®à¬ æ¨¨ ® à §¤¥«¥ (¯®ª  ¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 FAT):
* +0: dword: ­ ç «ì­ë© 䨧¨ç¥áª¨© ᥪâ®à à §¤¥« 
* +4: dword: ¯®á«¥¤­¨© 䨧¨ç¥áª¨© ᥪâ®à à §¤¥« 
(¯à¨­ ¤«¥¦¨â à §¤¥«ã)
* +8: dword: ᥪâ®à®¢ ¢ ®¤­®© ª®¯¨¨ FAT
* +12 = +0xC: dword: ç¨á«® ª®¯¨© FAT
* +16 = +0x10: dword: ç¨á«® ᥪâ®à®¢ ¢ ª« áâ¥à¥
* +20 = +0x14: dword: ¡ ©â ¢ ᥪâ®à¥; ⥪ãé ï ॠ«¨§ æ¨ï ®¦¨¤ ¥â,
çâ® §¤¥áì 0x200 = 512
* +24 = +0x18: dword: ¯¥à¢ë© ª« áâ¥à ª®à­¥¢®£® ª â «®£  ¢ FAT32,
0 ¤«ï FAT16
* +28 = +0x1C: dword: ­ ç «ì­ë© 䨧¨ç¥áª¨© ᥪâ®à FAT
* +32 = +0x20: dword: ¯¥à¢ë© 䨧¨ç¥áª¨© ᥪâ®à ª®à­¥¢®£® ª â «®£ 
¤«ï FAT16, ¨£­®à¨àã¥âáï ¤«ï FAT32
* +36 = +0x24: dword: ç¨á«® ᥪâ®à®¢ ¢ ª®à­¥¢®¬ ª â «®£¥ ¤«ï FAT16,
0 ¤«ï FAT32
* +40 = +0x28: dword: 䨧¨ç¥áª¨© ᥪâ®à ­ ç «  ®¡« á⨠¤ ­­ëå
* +44 = +0x2C: dword: ¬ ªá¨¬ «ì­ë© ­®¬¥à ª« áâ¥à 
* +48 = +0x30: dword: 䨧¨ç¥áª¨© ᥪâ®à ¨­ä®à¬ æ¨¨ ®
ä ©«®¢®© á¨á⥬¥ ¤«ï FAT32, ¨£­®à¨àã¥âáï ¤«ï FAT16
* +52 = +0x34: dword: §­ ç¥­¨¥, ¨á¯®«ì§ã¥¬®¥ ª ª £à ­¨æ 
ᯥ樠«ì­ëå §­ ç¥­¨© ¢ FAT
* +56 = +0x38: dword: §­ ç¥­¨¥, ¨á¯®«ì§ã¥¬®¥ ¤«ï ¯«®å¨å ª« áâ¥à®¢
¢ FAT
* +60 = +0x3C: dword: §­ ç¥­¨¥, ¨á¯®«ì§ã¥¬®¥ ª ª ¬ àª¥à ª®­æ 
¯à¨ § ¯¨á¨ 楯®çª¨ ¢ FAT
* +64 = +0x40: dword: ¬ áª , ­ ª« ¤ë¢ ¥¬ ï ­  í«¥¬¥­â FAT
* +68 = +0x44: byte: ⨯ ä ©«®¢®© á¨á⥬ë: 16 ¨«¨ 32
* +69 = +0x45: 31 db: § à¥§¥à¢¨à®¢ ­®
‡ ¬¥ç ­¨ï:
* Š®à®âª ï â ¡«¨æ  ¬®¦¥â ¡ëâì ¨á¯®«ì§®¢ ­  ¤«ï ¯®«ã祭¨ï ¨­ä®à¬ æ¨¨
®¡ ¨¬¥îé¨åáï ãáâனá⢠å.
* ¥à¢ë¥ ¤¢  ¯®«ï ¨­ä®à¬ æ¨¨ ® à §¤¥«¥ ¢ ¯®«­®© ¢¥àᨨ â ¡«¨æë
á®®¡é îâ ¯ à ¬¥âàë à §¤¥« , ®á⠢訥áï - ¯ à ¬¥âàë ä ©«®¢®©
á¨á⥬ë FAT. „«ï ¤à㣨å ä ©«®¢ëå á¨á⥬ (ª®£¤  ®­¨ ¡ã¤ãâ
¯®¤¤¥à¦¨¢ âìáï) ᯥæ¨ä¨ç¥áª ï ¤«ï ä ©«®¢®© á¨áâ¥¬ë ¨­ä®à¬ æ¨ï,
¥áâ¥á⢥­­®, ¡ã¤¥â ¤à㣮©, ­® ¯¥à¢ë¥ ¤¢  ¯®«ï
á®åà ­ïâáï ­¥¨§¬¥­­ë¬¨.
 
======================================================================
========== ”ã­ªæ¨ï 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
db 'name',0 - ASCIIZ-áâப  á ¨¬¥­¥¬
„«ï ï¤à  Kolibri 0.5.8.1:
db 0,5,8,1
db 2
db 'Kolibri',0
 
======================================================================
====================== ”ã­ªæ¨ï 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]
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ¥ª®¬¥­¤ã¥¬ ï ᪮à®áâì ¬ëè¨ (¢ ¯®¤¯®¤ä㭪樨 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: à §¬¥à ­ ¨¡®«ì襣® ¢ë¤¥«¥­­®£® ¡«®ª  ¢ ªãç¥ ï¤à 
(§ à¥§¥à¢¨à®¢ ­®)
 
======================================================================
==================== ”ã­ªæ¨ï 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, ¯®¤äã­ªæ¨ï 4 - ãáâ ­®¢¨âì ¡ §®¢ë© ¯®àâ Sound Blaster. =
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 4 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­®¬¥à ¡ §®¢®£® ¯®àâ 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = -1 - ®è¨¡®ç­ë© ­®¬¥à ¯®àâ 
‡ ¬¥ç ­¨ï:
* ®¬¥à ¯®àâ  ¤®«¦¥­ 㤮¢«¥â¢®àïâì ãá«®¢¨ï¬ 0x100<=ecx<=0xFFFF.
* “áâ ­®¢ª  ¡ §ë ­ã¦­  ¤«ï à ¡®âë ä㭪権 25, 28, 55.
* ®«ãç¨âì ãáâ ­®¢«¥­­ë© ¡ §®¢ë© ¯®àâ ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 4 ä㭪樨 26.
 
======================================================================
========= ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 5 - ãáâ ­®¢¨âì ï§ëª á¨á⥬ë. ========
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ï§ëª á¨á⥬ë (1=eng, 2=fi, 3=ger, 4=rus)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0
‡ ¬¥ç ­¨ï:
* Ÿ§ëª á¨á⥬ë - £«®¡ «ì­ ï á¨á⥬­ ï ¯¥à¥¬¥­­ ï, ­¨ª ª
­¥ ¨á¯®«ì§ã¥¬ ï á ¬¨¬ ï¤à®¬, ®¤­ ª® ¯à¨«®¦¥­¨¥ @panel à¨áã¥â
ᮮ⢥âáâ¢ãîéãî ¨ª®­ªã.
* à®¢¥à®ª ­  ª®à४⭮áâì ­¥ ¤¥« ¥âáï, ¯®áª®«ìªã ï¤à® íâã
¯¥à¥¬¥­­ãî ­¥ ¨á¯®«ì§ã¥â.
* ®«ãç¨âì ï§ëª á¨áâ¥¬ë ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 5 ä㭪樨 26.
 
======================================================================
======= ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 6 - ãáâ ­®¢¨âì ¡ §®¢ë© ¯®àâ WSS. ======
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 6 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ¡ §®¢ë© ¯®àâ
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = -1 - ®è¨¡®ç­ë© ­®¬¥à ¯®àâ 
‡ ¬¥ç ­¨ï:
* ®¬¥à ¯®àâ  ¤®«¦¥­ 㤮¢«¥â¢®àïâì ãá«®¢¨î 0x100<=ecx.
*  §  WSS ¨á¯®«ì§ã¥âáï ä㭪樥© 27.
* ®«ãç¨âì ãáâ ­®¢«¥­­ë© ¡ §®¢ë© ¯®àâ WSS ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 6 ä㭪樨 26.
 
======================================================================
=========== ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 7 - ãáâ ­®¢¨âì ¡ §ã HD. ===========
======================================================================
 §  HD ­ã¦­  ¤«ï ®¯à¥¤¥«¥­¨ï, ­  ª ª®© ¦ñá⪨© ¤¨áª ¯¨á âì, ¯à¨
¨á¯®«ì§®¢ ­¨¨ ãáâ à¥¢è¨å ä㭪権 à ¡®âë á ä ©«®¢®© á¨á⥬®© ¨ ä㭪権,
­¥ï¢­® ¨á¯®«ì§ãîé¨å ¦ñá⪨© ¤¨áª (⨯  ¯®¤ä㭪樨 6 ä㭪樨 18);
¯à¨ ¨á¯®«ì§®¢ ­¨¨ ä㭪権 58 ¨ 70 ¨ ᮢ६¥­­®£® ᨭ⠪á¨á 
/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 ­ã¦¥­ ¤«ï ®¯à¥¤¥«¥­¨ï, ­  ª ª®© à §¤¥« ¦ñá⪮£® ¤¨áª 
¯¨á âì, ¯à¨ ¨á¯®«ì§®¢ ­¨¨ ãáâ à¥¢è¨å ä㭪権 à ¡®âë á ä ©«®¢®©
á¨á⥬®© ¨ ä㭪権, ­¥ï¢­® ¨á¯®«ì§ãîé¨å ¦ñá⪨© ¤¨áª (⨯ 
¯®¤ä㭪樨 6 ä㭪樨 18); ¯à¨ ¨á¯®«ì§®¢ ­¨¨ ä㭪権 58 ¨ 70
¨ ᮢ६¥­­®£® ᨭ⠪á¨á  /HD0,/HD1,/HD2,/HD3 í⨠ä㭪樨 á ¬¨
ãáâ ­ ¢«¨¢ îâ ¡ §ã ¨ à §¤¥«.
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 8 - ­®¬¥à ¯®¤ä㭪樨
* ecx = à §¤¥« HD (áç¨â ï á 1)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0
‡ ¬¥ç ­¨ï:
* ‹î¡®¥ ¯à¨«®¦¥­¨¥ ¢ «î¡®© ¬®¬¥­â ¢à¥¬¥­¨ ¬®¦¥â ¨§¬¥­¨âì à §¤¥«.
* ¥ á«¥¤ã¥â ¨§¬¥­ïâì à §¤¥«, ª®£¤  ª ª®¥-­¨¡ã¤ì ¯à¨«®¦¥­¨¥ à ¡®â ¥â
á ¦ñá⪨¬ ¤¨áª®¬. …᫨ ­¥ å®â¨â¥ £«îª®¢ á¨á⥬ë.
* ®«ãç¨âì ãáâ ­®¢«¥­­ë© à §¤¥« ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 8
ä㭪樨 26.
* à®¢¥à®ª ­  ª®à४⭮áâì ­¥ ¤¥« ¥âáï.
* “§­ âì ç¨á«® à §¤¥«®¢ ­  ¦ñá⪮¬ ¤¨áª¥ ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 11 ä㭪樨 18.
* ‘«¥¤ã¥â â ª¦¥ ®¯à¥¤¥«¨âì ¨á¯®«ì§ã¥¬ãî ¡ §ã ¦ñá⪮£® ¤¨áª 
¯®¤ä㭪樥© 7.
 
======================================================================
===== ”ã­ªæ¨ï 21, ¯®¤äã­ªæ¨ï 10 - ãáâ ­®¢¨âì ª ­ « DMA ¤«ï §¢ãª . ====
======================================================================
 à ¬¥âàë:
* eax = 21 - ­®¬¥à ä㭪樨
* ebx = 10 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­®¬¥à ª ­ «  (®â 0 ¤® 3 ¢ª«îç¨â¥«ì­®)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = -1 - ­¥¢¥à­ë© ­®¬¥à ª ­ « 
‡ ¬¥ç ­¨ï:
* ®¬¥à ª ­ «  DMA ¨á¯®«ì§ã¥âáï ¢
¯®¤ä㭪樨 1 ä㭪樨 55.
* ®«ãç¨âì ª ­ « DMA ¤«ï §¢ãª  ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 10 ä㭪樨 26.
 
======================================================================
====================== ”ã­ªæ¨ï 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.
 
======================================================================
============== ”ã­ªæ¨ï 25 - ãáâ ­®¢¨âì £à®¬ª®áâì SBPro. ==============
======================================================================
 à ¬¥âàë:
* eax = 25 - ­®¬¥à ä㭪樨
* ebx = çâ® ãáâ ­ ¢«¨¢ âì:
* 1 - ãáâ ­®¢¨âì ®¡éãî £à®¬ª®áâì
* 2 - ãáâ ­®¢¨âì £à®¬ª®áâì CD-audio
* cl = ã஢¥­ì £à®¬ª®áâ¨: áâ à訥 4 ¡¨â  ¤«ï «¥¢®© ª®«®­ª¨,
¬« ¤è¨¥ 4 - ¤«ï ¯à ¢®©
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ­¥ ®¯à¥¤¥«¥­  ¡ §  SB
* eax = 2 - ­¥¢¥à­ ï ¯®¤äã­ªæ¨ï
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ­ã¦­® ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ SB ¢ë§®¢®¬
¯®¤ä㭪樨 4 ä㭪樨 21.
* ‘¬®âਠ⠪¦¥ äã­ªæ¨î 28
ãáâ ­®¢ª¨ §¢ãª  ¤«ï ¡®«¥¥ ¯®§¤­¥£® áâ ­¤ àâ  SB16.
 
======================================================================
===== ”ã­ªæ¨ï 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, ¯®¤äã­ªæ¨ï 4 - ¯®«ãç¨âì ¡ §®¢ë© ¯®àâ Sound Blaster. ==
======================================================================
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 4 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ­®¬¥à ¡ §®¢®£® ¯®àâ 
‡ ¬¥ç ­¨ï:
* “áâ ­®¢ª  ¡ §ë ­ã¦­  ¤«ï à ¡®âë ä㭪権 25, 55.
* “áâ ­®¢¨âì ¡ §®¢ë© ¯®àâ ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 4 ä㭪樨 21.
 
======================================================================
========== ”ã­ªæ¨ï 26, ¯®¤äã­ªæ¨ï 5 - ¯®«ãç¨âì ï§ëª á¨á⥬ë. =========
======================================================================
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ï§ëª á¨á⥬ë (1=eng, 2=fi, 3=ger, 4=rus)
‡ ¬¥ç ­¨ï:
* Ÿ§ëª á¨á⥬ë - £«®¡ «ì­ ï á¨á⥬­ ï ¯¥à¥¬¥­­ ï, ­¨ª ª
­¥ ¨á¯®«ì§ã¥¬ ï á ¬¨¬ ï¤à®¬, ®¤­ ª® ¯à¨«®¦¥­¨¥ @panel à¨áã¥â
ᮮ⢥âáâ¢ãîéãî ¨ª®­ªã (¨á¯®«ì§ãï ®¯¨á뢠¥¬ãî äã­ªæ¨î).
* “áâ ­®¢¨âì ï§ëª á¨áâ¥¬ë ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 5 ä㭪樨 21.
 
======================================================================
======== ”ã­ªæ¨ï 26, ¯®¤äã­ªæ¨ï 6 - ¯®«ãç¨âì ¡ §®¢ë© ¯®àâ WSS. =======
======================================================================
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 6 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ¡ §®¢ë© ¯®àâ
‡ ¬¥ç ­¨ï:
*  §  WSS ¨á¯®«ì§ã¥âáï ä㭪樥© 27.
* “áâ ­®¢¨âì ¡ §®¢ë© ¯®àâ WSS ¬®¦­® ¢ë§®¢®¬ ¯®¤ä㭪樨 6 ä㭪樨 21.
 
======================================================================
============ ”ã­ªæ¨ï 26, ¯®¤äã­ªæ¨ï 7 - ¯®«ãç¨âì ¡ §ã HD. ============
======================================================================
 §  HD ­ã¦­  ¤«ï ®¯à¥¤¥«¥­¨ï, ­  ª ª®© ¦ñá⪨© ¤¨áª ¯¨á âì, ¯à¨
¨á¯®«ì§®¢ ­¨¨ ãáâ à¥¢è¨å ä㭪権 à ¡®âë á ä ©«®¢®© á¨á⥬®© ¨ ä㭪権,
­¥ï¢­® ¨á¯®«ì§ãîé¨å ¦ñá⪨© ¤¨áª (⨯  ¯®¤ä㭪樨 6 ä㭪樨 18);
¯à¨ ¨á¯®«ì§®¢ ­¨¨ ä㭪権 58 ¨ 70 ¨ ᮢ६¥­­®£® ᨭ⠪á¨á 
/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 ­ã¦¥­ ¤«ï ®¯à¥¤¥«¥­¨ï, ­  ª ª®© à §¤¥« ¦ñá⪮£® ¤¨áª 
¯¨á âì, ¯à¨ ¨á¯®«ì§®¢ ­¨¨ ãáâ à¥¢è¨å ä㭪権 à ¡®âë á ä ©«®¢®©
á¨á⥬®© ¨ ä㭪権, ­¥ï¢­® ¨á¯®«ì§ãîé¨å ¦ñá⪨© ¤¨áª (⨯ 
¯®¤ä㭪樨 6 ä㭪樨 18); ¯à¨ ¨á¯®«ì§®¢ ­¨¨ ä㭪権 58 ¨ 70 ¨
ᮢ६¥­­®£® ᨭ⠪á¨á  /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, ¯®¤äã­ªæ¨ï 10 - ¯®«ãç¨âì ª ­ « DMA ¤«ï §¢ãª . =====
======================================================================
 à ¬¥âàë:
* eax = 26 - ­®¬¥à ä㭪樨
* ebx = 10 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ­®¬¥à ª ­ «  (®â 0 ¤® 3 ¢ª«îç¨â¥«ì­®)
‡ ¬¥ç ­¨ï:
* ®¬¥à ª ­ «  DMA ¨á¯®«ì§ã¥âáï ¢ ¯®¤ä㭪樨 1 ä㭪樨 55.
* “áâ ­®¢¨âì ª ­ « DMA ¤«ï §¢ãª  ¬®¦­® ¢ë§®¢®¬
¯®¤ä㭪樨 10 ä㭪樨 21.
 
======================================================================
====================== ”ã­ªæ¨ï 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.
 
======================================================================
==== ”ã­ªæ¨ï 27 - ãáâ ­®¢¨âì £à®¬ª®áâì Windows Sound System (WSS). ===
======================================================================
 à ¬¥âàë:
* eax = 27 - ­®¬¥à ä㭪樨
* ebx = çâ® ãáâ ­ ¢«¨¢ âì:
* 1 - ãáâ ­®¢¨âì ®¡éãî £à®¬ª®áâì
* 2 - ãáâ ­®¢¨âì £à®¬ª®áâì Line In
* cl = ã஢¥­ì £à®¬ª®á⨠(0x0=á ¬ë© ¢ë᮪¨©, 0x1F=á ¬ë© ­¨§ª¨©,
ãáâ ­®¢«¥­­ë© ¡¨â 0x80=®âª«îç¨âì)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ­¥ ®¯à¥¤¥«¥­  ¡ §  WSS
* eax = 2 - ­¥¢¥à­ ï ¯®¤äã­ªæ¨ï
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ­ã¦­® ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ WSS ¢ë§®¢®¬
¯®¤ä㭪樨 6 ä㭪樨 21.
* “áâ ­®¢ª  ®¡é¥© £à®¬ª®á⨠䠪â¨ç¥áª¨ ¨£­®à¨àã¥âáï
(¢®§¢à é ¥âáï eax=0).
* ‚ áâ à®© ¤®ªã¬¥­â æ¨¨ ¨ ¢ ¨á室­¨ª å ï¤à  ¯®¤äã­ªæ¨ï 2
®è¨¡®ç­® ­ §¢ ­  £à®¬ª®áâìî CD-audio.
 
======================================================================
=============== ”ã­ªæ¨ï 28 - ãáâ ­®¢¨âì £à®¬ª®áâì SB16. ==============
======================================================================
 à ¬¥âàë:
* eax = 28 - ­®¬¥à ä㭪樨
* ebx = çâ® ãáâ ­ ¢«¨¢ âì:
* 1 - ãáâ ­®¢¨âì ®¡éãî £à®¬ª®áâì
* 2 - ãáâ ­®¢¨âì £à®¬ª®áâì CD-audio
* cl = ã஢¥­ì £à®¬ª®á⨠(0=off, 0xFF=max)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* eax = 1 - ­¥ ®¯à¥¤¥«¥­  ¡ §  SB
* eax = 2 - ­¥¢¥à­ ï ¯®¤äã­ªæ¨ï
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ­ã¦­® ®¯à¥¤¥«¨âì ¡ §®¢ë© ¯®àâ SB ¢ë§®¢®¬
¯®¤ä㭪樨 4 ä㭪樨 21.
* â  äã­ªæ¨ï ¯à¥¤®áâ ¢«ï¥â ¡®«ìè¥ ¢ à¨ ­â®¢ ¤«ï £à®¬ª®áâ¨,
祬 äã­ªæ¨ï 25.
 
======================================================================
================ ”ã­ªæ¨ï 29 - ¯®«ãç¨âì á¨á⥬­ãî ¤ âã. ===============
======================================================================
 à ¬¥âàë:
* eax = 29 - ­®¬¥à ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0x00DDMMYY, £¤¥
(¨á¯®«ì§ã¥âáï ¤¢®¨ç­®-¤¥áïâ¨ç­®¥ ª®¤¨à®¢ ­¨¥, BCD)
* YY = ¤¢¥ ¬« ¤è¨¥ æ¨äàë £®¤  (00..99)
* MM = ¬¥áïæ (01..12)
* DD = ¤¥­ì (01..31)
‡ ¬¥ç ­¨ï:
* ‘¨á⥬­ãî ¤ âã ¬®¦­® ãáâ ­®¢¨âì ä㭪樥© 22.
 
======================================================================
================ ”ã­ªæ¨ï 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.
 
======================================================================
========== ”ã­ªæ¨ï 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 ãáâ ­®¢«¥­ = ¯à ¢ ï ª­®¯ª  ­ ¦ â 
* ¯à®ç¨¥ ¡¨âë á¡à®è¥­ë
 
======================================================================
================== ”ã­ªæ¨ï 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 (á¬. ᯨ᮪ ᮡë⨩)
(ãáâ ­®¢«¥­­ë© ¡¨â à §à¥è ¥â ¨§¢¥é¥­¨¥ ® ᮡë⨨)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* Œ áª  ¯® 㬮«ç ­¨î (7=111b) à §à¥è ¥â ¨§¢¥é¥­¨ï ® ¯¥à¥à¨á®¢ª¥
¨ ­ ¦ â¨ïå ª« ¢¨è ¨ ª­®¯®ª.
â®£® ¤®áâ â®ç­® ¤«ï ¡®«ì設á⢠ ¯à¨«®¦¥­¨©.
* ‘®¡ëâ¨ï, § ¯à¥éñ­­ë¥ ¢ ¬ áª¥, ¢áñ à ¢­® á®åà ­ïîâáï, ¥á«¨
¯à¨å®¤ïâ; ® ­¨å ¯à®áâ® ­¥ ¨§¢¥é îâ ä㭪樨 à ¡®âë á ᮡëâ¨ï¬¨.
* ”㭪樨 à ¡®âë á ᮡëâ¨ï¬¨ ãç¨â뢠îâ ¬ áªã ­  ¬®¬¥­â
¢ë§®¢  ä㭪樨,   ­¥ ­  ¬®¬¥­â ¯®áâ㯫¥­¨ï á®®¡é¥­¨ï.
 
======================================================================
================= ”ã­ªæ¨ï 41 - 㧭 âì ¢« ¤¥«ìæ  IRQ. =================
======================================================================
 à ¬¥âàë:
* eax = 41 - ­®¬¥à ä㭪樨
* ebx = ­®¬¥à IRQ, 0..15
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = PID ¢« ¤¥«ìæ 
* eax = 0, ¥á«¨ ¢« ¤¥«ìæ  ­¥â
* eax = -1 ¤«ï ­¥ª®à४⭮£® ebx
 
======================================================================
========== ”ã­ªæ¨ï 42 - ¯à®ç¨â âì ¤ ­­ë¥, ¯®«ã祭­ë¥ ¯® IRQ. =========
======================================================================
à¨ ¢®§­¨ª­®¢¥­¨¨ IRQ á¨á⥬  ¬®¦¥â áç¨â뢠âì ¤ ­­ë¥ ¨§ 㪠§ ­­ëå
à ­¥¥ ä㭪樥© 44 ¯®à⮢ ¨ § ¯¨á뢠âì í⨠¤ ­­ë¥ ¢ ¡ãä¥à.
Ž¯¨á뢠¥¬ ï äã­ªæ¨ï áç¨â뢠¥â ¯®¡ ©â­® ¤ ­­ë¥ ¨§ í⮣® ¡ãä¥à .
 à ¬¥âàë:
* eax = 42 - ­®¬¥à ä㭪樨
* ebx = ­®¬¥à IRQ, 0..15
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥: (á¨âã æ¨î ¬®¦­® à §«¨ç¨âì ¯® §­ ç¥­¨î ecx)
* ¥á«¨ ¯®â®ª ­¥ ï¥âáï ¢« ¤¥«ì楬 IRQ
(¨«¨ ­®¬¥à IRQ § ¤ ­ ­¥¢¥à­®):
* ecx = 2
* ¥á«¨ ¤ ­­ëå ­¥â:
* eax = 0
* ecx = 1
* ebx à §àãè ¥âáï
* ¥á«¨ ¢áñ ¢ ¯®à浪¥ ¨ ¤ ­­ë¥ ¡ë«¨:
* eax = à §¬¥à ¤ ­­ëå, ¥éñ ­¥ ¯à®ç¨â ­­ëå ¨§ ¡ãä¥à  (¢ ¡ ©â å)
* ecx = 0
* ebx = ®ç¥à¥¤­®© ¡ ©â
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¯®â®ª ¤®«¦¥­ § à¥§¥à¢¨à®¢ âì ¤«ï ᥡï 㪠§ ­­ë© 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..0xff,   ¯à¨
®¡­ à㦥­¨¨ COM-¬ëè¨ - ¤®¯®«­¨â¥«ì­® ¤¨ ¯ §®­ COM-¯®à⮢
0x3f0..0x3ff ¨/¨«¨ 0x2f0..0x2ff.
* à¨ § ¢¥à襭¨¨ ¯®â®ª   ¢â®¬ â¨ç¥áª¨ ®á¢®¡®¦¤ îâáï ¢á¥
§ à¥§¥à¢¨à®¢ ­­ë¥ ¨¬ ¯®àâë.
 
======================================================================
================= ”ã­ªæ¨ï 47 - ¢ë¢¥á⨠ç¨á«® ¢ ®ª­®. =================
======================================================================
 à ¬¥âàë:
* eax = 47 - ­®¬¥à ä㭪樨
* ebx = ¯ à ¬¥âàë ¯à¥®¡à §®¢ ­¨ï ç¨á«  ¢ ⥪áâ:
* bl = 0 - ecx ᮤ¥à¦¨â ç¨á«®
* bl = 1 - ecx ᮤ¥à¦¨â 㪠§ â¥«ì ­  dword-ç¨á«®
* bh = 0 - ®â®¡à ¦ âì ¢ ¤¥áïâ¨ç­®© á¨á⥬¥ áç¨á«¥­¨ï
* bh = 1 - ®â®¡à ¦ âì ¢ è¥áâ­ ¤æ â¥à¨ç­®© á¨á⥬¥
* bh = 2 - ®â®¡à ¦ âì ¢ ¤¢®¨ç­®© á¨á⥬¥
* ¡¨âë 16-21 = ᪮«ìª® æ¨äà ®â®¡à ¦ âì
* ¡¨âë 22-31 § à¥§¥à¢¨à®¢ ­ë ¨ ¤®«¦­ë ¡ëâì ãáâ ­®¢«¥­ë ¢ 0
* 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 = 㪠§ â¥«ì ­  ¡«®ª ¤«ï ä㭪樨 58, ¢ ª®â®à®¬ ãáâ ­®¢«¥­®
¯®«¥ ¯à®¬¥¦ãâ®ç­®£® ¡ãä¥à  ¨ 㪠§ ­® ¨¬ï ä ©« 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮
* ¨­ ç¥ eax = ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë; ¥á«¨ ä ©« ­¥ § ¤ ñâ ᪨­,
â® ¢®§¢à é ¥âáï ®è¨¡ª  3 (­¥¨§¢¥áâ­ ï ä ©«®¢ ï á¨á⥬ ).
‡ ¬¥ç ­¨ï:
* à¨ ãᯥ譮© § £à㧪¥ ᪨­  ¢á¥ ®ª­  ¨§¢¥é îâáï ® ­¥®¡å®¤¨¬®áâ¨
¯¥à¥à¨á®¢ª¨ (ᮡë⨥ 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, ­® íâ® ¬®¦¥â ¡ëâì ¨§¬¥­¥­®
¢ á«¥¤ãîé¨å ¢¥àá¨ïå
 
======================================================================
============ ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 0 - ®âªàëâì UDP-᮪¥â. ===========
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 0 - ­®¬¥à ¯®¤ä㭪樨
* ecx = «®ª «ì­ë© ¯®àâ (ãç¨â뢠¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®)
* 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 = ç¨á«® ¯®«ã祭­ëå ¡ ©â
* 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 = 0xffff - ­¥¤®áâ â®ç­® ¯ ¬ïâ¨
* eax = 0 - ãᯥ譮
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* à®¢¥àª  ­  ¯à ¢¨«ì­®áâì åí­¤«  ¬¨­¨¬ «ì­  - ¨áª«îç îâáï ⮫쪮
­¥ ®ç¥­ì ­¥¯à ¢¨«ì­ë¥ ­¥®âªàëâë¥ åí­¤«ë.
* —¨á«® ¡ ©â ¤«ï § ¯¨á¨ ­¥ ¬®¦¥â ¯à¥¢ëè âì 1500-28, å®âï
ᮮ⢥âáâ¢ãî饩 ¯à®¢¥àª¨ ­¥ ¤¥« ¥âáï.
 
======================================================================
============ ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 5 - ®âªàëâì TCP-᮪¥â. ===========
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 5 - ­®¬¥à ¯®¤ä㭪樨
* ecx = «®ª «ì­ë© ¯®àâ (ãç¨â뢠¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®)
* 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 = áâ âãá ᮪¥â : ®¤­® ¨§
* 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 = 0xffff - ­¥¤®áâ â®ç­® ¯ ¬ïâ¨
* eax = 0 - ãᯥ譮
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* à®¢¥àª  ­  ¯à ¢¨«ì­®áâì åí­¤«  ¬¨­¨¬ «ì­  - ¨áª«îç îâáï ⮫쪮
­¥ ®ç¥­ì ­¥¯à ¢¨«ì­ë¥ ­¥®âªàëâë¥ åí­¤«ë.
* —¨á«® ¡ ©â ¤«ï § ¯¨á¨ ­¥ ¬®¦¥â ¯à¥¢ëè âì 1500-40,
å®âï ᮮ⢥âáâ¢ãî饩 ¯à®¢¥àª¨ ­¥ ¤¥« ¥âáï.
 
======================================================================
============ ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 8 - § ªàëâì TCP-᮪¥â. ===========
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 8 - ­®¬¥à ¯®¤ä㭪樨
* ecx = åí­¤« ᮪¥â 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = -1 - ­¥¢¥à­ë© åí­¤«
* eax = 0xffff - ­¥¤®áâ â®ç­® ¯ ¬ï⨠¤«ï ¯ ª¥â  § ªàëâ¨ï ᮪¥â 
* eax = 0 - ãᯥ譮
* ¢® ¬­®£¨å á«ãç ïå eax à §àãè ¥âáï (¢®§¢à é ¥âáï १ã«ìâ â ä㭪樨
queue) - ¢¨¤¨¬®, íâ® ¡ £, ª®â®àë© ¡ã¤¥â ¨á¯à ¢«¥­
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* ’¥ªãé ï ॠ«¨§ æ¨ï ­¥ § ªà뢠¥â  ¢â®¬ â¨ç¥áª¨ ¢á¥ ᮪¥âë ¯®â®ª 
¯à¨ ¥£® § ¢¥à襭¨¨. ‚ ç áâ­®áâ¨, ­¥ á«¥¤ã¥â ¯à¨¡¨¢ âì ¯®â®ª
á ªã祩 ®âªàëâëå ᮪¥â®¢ - ¡ã¤¥â ãâ¥çª  à¥áãàᮢ.
* ’¥ªãé ï ॠ«¨§ æ¨ï ­¥ ¤¥« ¥â ¯à®¢¥à®ª ­  ª®à४⭮áâì
(¥¤¨­á⢥­­®¥, ­  çâ® ¢®§¢à é ¥âáï ®è¨¡ª , - ¯®¯ë⪠ § ªàëâì
­¥®âªàëâë© á®ª¥â á ª®à४â­ë¬ åí­¤«®¬).
 
======================================================================
== ”ã­ªæ¨ï 53, ¯®¤äã­ªæ¨ï 9 - ¯à®¢¥à¨âì, ᢮¡®¤¥­ «¨ «®ª «ì­ë© ¯®àâ. =
======================================================================
 à ¬¥âàë:
* eax = 53 - ­®¬¥à ä㭪樨
* ebx = 9 - ­®¬¥à ¯®¤ä㭪樨
* ecx = ­®¬¥à «®ª «ì­®£® ¯®àâ  (¨á¯®«ì§ãîâáï ⮫쪮 ¬« ¤è¨¥ 16 ¡¨â)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ¯®à⠨ᯮ«ì§ã¥âáï
* eax = 1 - ¯®àâ ᢮¡®¤¥­
* 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, ¯®¤äã­ªæ¨ï 0 - § £à㧨âì ¤ ­­ë¥ ¤«ï SB16. =======
======================================================================
 à ¬¥âàë:
* eax = 55 - ­®¬¥à ä㭪樨
* ebx = 0 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¤ ­­ë¥ (ª®¯¨àã¥âáï 64 ª¨«®¡ ©â , ¨á¯®«ì§ã¥âáï
á⮫쪮, ᪮«ìª® ãáâ ­®¢«¥­® ¯®¤ä㭪樥© 2)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ”®à¬ â ¨ à §¬¥à ¤ ­­ëå ãáâ ­ ¢«¨¢ îâáï ¯®¤ä㭪樥© 2.
 
======================================================================
==== ”ã­ªæ¨ï 55, ¯®¤äã­ªæ¨ï 1 - ­ ç âì ¯à®¨£à뢠âì ¤ ­­ë¥ ­  SB16. ===
======================================================================
 à ¬¥âàë:
* eax = 55 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® ¤ ­­ë¥ ¤®«¦­ë ¡ëâì § £à㦥­ë ¯®¤ä㭪樥© 0 ¨
®¯à¥¤¥«ñ­ ¨å ä®à¬ â ¯®¤ä㭪樥© 2.
* ”ã­ªæ¨ï ¢®§¢à é ¥â ã¯à ¢«¥­¨¥, ª®£¤  ­ ç «®áì ¯à®¨£à뢠­¨¥ ¤ ­­ëå;
¯®á«¥ í⮣® ¯à®¨£à뢠­¨¥ ¨¤ñâ ­¥§ ¢¨á¨¬® ®â ¯à¨«®¦¥­¨ï (¨ ¢®®¡é¥
­¥ âॡã¥â § £à㧪¨ ¯à®æ¥áá®à ).
* à¥¤¢ à¨â¥«ì­® ¤®«¦­ë ¡ëâì ®¯à¥¤¥«¥­ë ¡ §®¢ë© ¯®àâ SB16
(¯®¤ä㭪樥© 4 ä㭪樨 21) ¨ ª ­ « DMA
(¯®¤ä㭪樥© 10 ä㭪樨 21).
 
======================================================================
====== ”ã­ªæ¨ï 55, ¯®¤äã­ªæ¨ï 2 - ãáâ ­®¢¨âì ä®à¬ â ¤ ­­ëå SB16. =====
======================================================================
 à ¬¥âàë:
* eax = 55 - ­®¬¥à ä㭪樨
* ebx = 2 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 0 - ãáâ ­®¢¨âì à §à來®áâì
* edx = 1 - 8¡¨â ¬®­®
* edx = 2 - 8¡¨â áâ¥à¥®
* ecx = 1 - ãáâ ­®¢¨âì à §¬¥à ¤ ­­ëå
* edx = à §¬¥à ¢ ¡ ©â å
* ecx = 2 - ãáâ ­®¢¨âì ç áâ®â㠯ந£à뢠­¨ï
* edx = ç áâ®â 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* à¨ § £à㧪¥ á¨á⥬ë ãáâ ­ ¢«¨¢ îâáï á«¥¤ãî騥 ¯ à ¬¥âàë
¯® 㬮«ç ­¨î: à §à來®áâì - 8 ¡¨â ¬®­®, à §¬¥à - 64 Š¡,
ç áâ®â  44100 ƒæ. ’¥¬ ­¥ ¬¥­¥¥ ४®¬¥­¤ã¥âáï ® ãáâ ­ ¢«¨¢ âì
­¥®¡å®¤¨¬ë¥ §­ ç¥­¨ï, ¯®áª®«ìªã ®­¨ ¬®£«¨ ¡ëâì ¯¥à¥ãáâ ­®¢«¥­ë
ª ª®©-­¨¡ã¤ì ¯à®£à ¬¬®©.
 
======================================================================
====================== ”ã­ªæ¨ï 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.
* ”ã­ªæ¨ï ¢®§¢à é ¥â ã¯à ¢«¥­¨¥, á®®¡é¨¢ ªã¤  á«¥¤ã¥â ¨­ä®à¬ æ¨î
® § ¯à®á¥. ‘ ¬® ¯à®¨£à뢠­¨¥ ¨¤ñâ ­¥§ ¢¨á¨¬® ®â ¯à®£à ¬¬ë.
* „ ­­ë¥ ¤®«¦­ë á®åà ­ïâìáï ¢ ¯ ¬ï⨠¯® ªà ©­¥© ¬¥à¥
¤® ª®­æ  ¯à®¨£à뢠­¨ï.
 
======================================================================
============= ”ã­ªæ¨ï 56 - § ¯¨á âì ä ©« ­  ¦ñá⪨© ¤¨áª. ============
======================================================================
 à ¬¥âàë:
* eax = 56 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨¬ï ä ©« 
* ecx = à §¬¥à ¤ ­­ëå ¤«ï § ¯¨á¨ (¢ ¡ ©â å)
* edx = 㪠§ â¥«ì ­  ¤ ­­ë¥ ¤«ï § ¯¨á¨
* esi = 㪠§ â¥«ì ­  ¯ãâì (ASCIIZ-áâபã)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
‡ ¬¥ç ­¨ï:
* â  äã­ªæ¨ï ãáâ à¥« ; äã­ªæ¨ï 70 ¯®§¢®«ï¥â ¢ë¯®«­ïâì
⥠¦¥ ¤¥©á⢨ï á à áè¨à¥­­ë¬¨ ¢®§¬®¦­®áâﬨ.
* „ ­­ ï äã­ªæ¨ï ¯à¥¤¯®« £ ¥â, çâ® ¢® ¢à¥¬ï ¥ñ ¢ë§®¢  ®¤­¨¬
¯à¨«®¦¥­¨¥¬ ­¨ª ª®¥ ¤à㣮¥ ¯à¨«®¦¥­¨¥ ­¥ à ¡®â ¥â
á ¦ñá⪨¬ ¤¨áª®¬.
* ãâì ª ä ©«ã - ASCIIZ-áâப , ª®â®à ï ¬®¦¥â ¡ëâì ¯ãá⮩
(¥á«¨ ä ©« ᮧ¤ ñâáï ¢ ª®à­¥¢®¬ ª â «®£¥) ¨«¨ ¨¬¥âì ä®à¬ â
/d1/d2/.../dn, £¤¥ ¢á¥ ¨¬¥­  ¯ ¯®ª ¤®«¦­ë ¨¬¥âì ä®à¬ â 8+3, â.¥.
8 ᨬ¢®«®¢ ¨¬¥­¨ ¨ 3 ᨬ¢®«  à áè¨à¥­¨ï ¡¥§ à §¤¥«¨â¥«ï,
¯à¨ ­¥®¡å®¤¨¬®á⨠¤®¯®«­¥­­ë¥ ¯à®¡¥« ¬¨;
¢á¥ ¡ãª¢ë ¤®«¦­ë ¡ëâì § £« ¢­ë¥.
* ˆ¬ï ª ä ©«ã â ª¦¥ ¤®«¦­® ¨¬¥âì ä®à¬ â 8+3.
 
======================================================================
============== ”ã­ªæ¨ï 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 - ç⥭¨¥ ä ©« /¯ ¯ª¨
* ¯®¤äã­ªæ¨ï 1 - ¯¥à¥§ ¯¨áì ä ©« 
* ¯®¤äã­ªæ¨ï 4 - ᮧ¤ ­¨¥ ¯ ¯ª¨
* ¯®¤äã­ªæ¨ï 5 - ¯¥à¥¨¬¥­®¢ ­¨¥/¯¥à¥¬¥é¥­¨¥ ä ©« /¯ ¯ª¨
* ¯®¤äã­ªæ¨ï 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, ¯®¤äã­ªæ¨ï 1 - ¯¥à¥§ ¯¨á âì ä ©«. ===========
======================================================================
…᫨ ä ©« ­¥ áãé¥áâ¢ã¥â, ®­ ᮧ¤ ñâáï.
…᫨ ä ©« áãé¥áâ¢ã¥â, ®­ ¯¥à¥§ ¯¨á뢠¥âáï.
 à ¬¥âàë:
* eax = 58 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 1 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ¨£­®à¨àã¥âáï (ãáâ ­ ¢«¨¢ ©â¥ ¢ 0)
* +8: dword: ç¨á«® ¡ ©â ¤«ï § ¯¨á¨
* +12 = +0xC: dword: 㪠§ â¥«ì ­  ¤ ­­ë¥ ¤«ï § ¯¨á¨
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë
(4096 ¡ ©â)
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
* â  äã­ªæ¨ï ãáâ à¥« , ¨á¯®«ì§ã©â¥ ¯®¤äã­ªæ¨î 2 ä㭪樨 70.
 
======================================================================
============== ”ã­ªæ¨ï 58, ¯®¤äã­ªæ¨ï 4 - ᮧ¤ âì ¯ ¯ªã. =============
======================================================================
 à ¬¥âàë:
* eax = 58 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 4 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ¨£­®à¨àã¥âáï
* +8: dword: ¨£­®à¨àã¥âáï
* +12 = +0xC: dword: ¨£­®à¨àã¥âáï
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë
(4096 ¡ ©â)
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
*  ¬¤¨áª ¨ ¤¨áª¥âë ­¥ ¯®¤¤¥à¦¨¢ îâ íâã äã­ªæ¨î,
®­  ⮫쪮 ¤«ï ¦ñáâª¨å ¤¨áª®¢.
 
======================================================================
== ”ã­ªæ¨ï 58, ¯®¤äã­ªæ¨ï 5 - ¯¥à¥¨¬¥­®¢ âì/¯¥à¥¬¥áâ¨âì ä ©«/¯ ¯ªã. ==
======================================================================
 à ¬¥âàë:
* eax = 58 - ­®¬¥à ä㭪樨
* ebx = 㪠§ â¥«ì ­  ¨­ä®à¬ æ¨®­­ãî áâàãªâãàã
”®à¬ â ¨­ä®à¬ æ¨®­­®© áâàãªâãàë:
* +0: dword: 5 = ­®¬¥à ¯®¤ä㭪樨
* +4: dword: ¨£­®à¨àã¥âáï
* +8: dword: ¨£­®à¨àã¥âáï
* +12 = +0xC: dword: ¨£­®à¨àã¥âáï
* +16 = +0x10: dword: 㪠§ â¥«ì ­  ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë
(4096 ¡ ©â)
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨«  ä®à¬¨à®¢ ­¨ï ¨¬ñ­ 㪠§ ­ë ¢
®¡é¥¬ ®¯¨á ­¨¨
* +20+n: (áࠧ㠯®á«¥ § ¢¥àè î饣® ­ã«¥¢®£® ᨬ¢®« ) ­®¢®¥
ASCIIZ-¨¬ï, ¤®«¦­® ­ ç¨­ âìáï á /hd/1, çâ® ¨­â¥à¯à¥â¨àã¥âáï ª ª
¦ñá⪨© ¤¨áª, 㪠§ ­­ë© ¢ ¯¥à¢®¬ ¨¬¥­¨
(¯¥à¥¬¥é¥­¨¥ á ®¤­®£® ¤¨áª  ­  ¤à㣮© ­¥ ¯®¤¤¥à¦¨¢ ¥âáï)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ãᯥ譮, ¨­ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë
* ebx à §àãè ¥âáï
‡ ¬¥ç ­¨ï:
*  ¬¤¨áª ¨ ¤¨áª¥âë ­¥ ¯®¤¤¥à¦¨¢ îâ íâã äã­ªæ¨î,
®­  ⮫쪮 ¤«ï ¦ñáâª¨å ¤¨áª®¢.
* …᫨ ­®¢®¥ ASCIIZ-¨¬ï ᨫ쭮 ­¥¯à ¢¨«ì­®¥, â.¥. ­¥ ­ ç¨­ ¥âáï á
/hd/1, /hd/first, /harddisk/1, /harddisk/first ¨«¨ ¯®á«¥ í⮣®
­ ç «  ¨¤ñ⠯஡¥« ¨«¨ ᨬ¢®« á ª®¤®¬ 0, â® äã­ªæ¨ï ¢®§¢à é ¥â,
ª ª ­¨ áâà ­­®, ª®¤ ®è¨¡ª¨ 4. â® ¥¤¨­á⢥­­ ï äã­ªæ¨ï, ª®â®à ï
¢®®¡é¥ ¢®§¢à é ¥â íâ®â ª®¤.
 
======================================================================
========= ”ã­ªæ¨ï 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, ¢®§¢à é îé ï
¨­ä®à¬ æ¨î ® ä ©«®¢®© á¨á⥬¥. ® à áè¨à¥­­®© â ¡«¨æ¥ ¤¨áª®¢®©
¯®¤á¨áâ¥¬ë ¬®¦­® ®¯à¥¤¥«¨âì à §¬¥à ª« áâ¥à  (â ¬ ®­ åà ­¨âáï
¢ ᥪâ®à å) ¨ ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ ¤«ï ¦ñáâª¨å ¤¨áª®¢.
 
======================================================================
=== ”ã­ªæ¨ï 59 - ¯®«ãç¨âì ¨­ä®à¬ æ¨î ® ¯®á«¥¤­¨å á¨á⥬­ëå ¢ë§®¢ å. ==
======================================================================
®«ã砥⠤ ­­ë¥ ® ¢á¥å á¨á⥬­ëå ¢ë§®¢ å ¢á¥å ¯à®æ¥áᮢ.
 à ¬¥âàë:
* eax = 59 - ­®¬¥à ä㭪樨
* ebx = 0 - ¥¤¨­á⢥­­ ï ¯®¤äã­ªæ¨ï
* ecx = 㪠§ â¥«ì ­  ¡ãä¥à
* edx = à §¬¥à ¡ãä¥à 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = ®¡é¥¥ ç¨á«® á¨á⥬­ëå ¢ë§®¢®¢,
ᤥ« ­­ëå á ¬®¬¥­â  § £à㧪¨ á¨á⥬ë (¯® ¬®¤ã«î 2^32)
* ebx = 0
”®à¬ â ¨­ä®à¬ æ¨¨ ®¡ ®¤­®¬ ¢ë§®¢¥: (à §¬¥à = 0x40 = 64 ¡ ©â )
* +0: dword: PID ¯à®æ¥áá /¯®â®ª 
* +4: 7*dword: ¬ãá®à
* +32 = +0x20: dword: §­ ç¥­¨¥ edi ¯à¨ ¢ë§®¢¥
* +36 = +0x24: dword: esi
* +40 = +0x28: dword: ebp
* +44 = +0x2C: dword: 㪠§ â¥«ì áâíª  ®¡à ¡®â稪  ï¤à 
* +48 = +0x30: dword: ebx
* +52 = +0x34: dword: edx
* +56 = +0x38: dword: ecx
* +60 = +0x3C: dword: eax (=­®¬¥à á¨á⥬­®© ä㭪樨)
‡ ¬¥ç ­¨ï:
* ”ã­ªæ¨ï ¨á¯®«ì§ã¥âáï ⮫쪮 ¢ ¯à¨«®¦¥­¨¨ systrace.
„®¢®«ì­® âà㤭® ¯à¥¤áâ ¢¨âì á¨âã æ¨î, ¢ ª®â®à®© íâ® ¯à¨«®¦¥­¨¥
¨«¨ íâ  äã­ªæ¨ï ¤¥©á⢨⥫쭮 ¯®«¥§­ë,   ¢®â ¢á¥ á¨á⥬­ë¥ ¢ë§®¢ë
¤«ï ¯®¤¤¥à¦ª¨ í⮩ ä㭪樨 ­¥áª®«ìª® § ¬¥¤«ïîâáï
(å®âï ¨ ­¥­ ¬­®£®)...
* ‚ á¢ï§¨ á í⨬ ¥áâì ¯à¥¤«®¦¥­¨¥ ¯®¤¤¥à¦ªã í⮩ ä㭪樨
¨§ ï¤à  ã¡à âì ᮢᥬ, ¢¬¥áâ¥ á ¯à¨«®¦¥­¨¥¬ systrace.
* ˆ­ä®à¬ æ¨ï ® á¨á⥬­ëå ¢ë§®¢ å á®åà ­ï¥âáï ¢
á¨á⥬­®¬ ª®«ì楢®¬ ¡ãä¥à¥ ­  0x10 ¢å®¤®¢.
â  äã­ªæ¨ï ¯à®áâ® ª®¯¨àã¥â 㪠§ ­­ë© ®¡êñ¬ ¤ ­­ëå
¨§ 㯮¬ï­ã⮣® ¡ãä¥à  ¯® 㪠§ ­­®¬ã  ¤à¥áã.
* Š ª®© ¨§ ¢å®¤®¢ ¢ ¡ãä¥à¥ ᮮ⢥âáâ¢ã¥â ¯®á«¥¤­¥¬ã ¢ë§®¢ã,
¬®¦­® ®¯à¥¤¥«¨âì ¯® §­ ç¥­¨î eax,   ¨¬¥­­®,
¢å®¤ (eax and 0xF) (¯® ᬥ饭¨î (eax and 0xF)*0x40).
* ‚ ⥪ã饩 ॠ«¨§ æ¨¨ ¢®§¬®¦­ë ।ª® ¢áâà¥ç î騥áï
¯à®¡«¥¬ë à áᨭåà®­¨§ æ¨¨, ª®£¤  ® ­¥ª®â®àëå ¢ë§®¢ å
¨­ä®à¬ æ¨ï ãáâ à¥¢ ¥â.
* ®¤ á¨á⥬­ë© ¡ãä¥à ¢ë¤¥«¥­  áâà ­¨æ , 4Š¡.
 §¬¥à ¢å®¤  = 64 ¡ ©â .
®ç¥¬ã ¨á¯®«ì§ã¥âáï ⮫쪮 16 ¢å®¤®¢ - ­¥¯®­ïâ­®.
* ‡­ ç¥­¨¥ esp ¢ ¬®¬¥­â á¨á⥬­®£® ¢ë§®¢ 
í⮩ ä㭪樥© 㧭 âì ­¥«ì§ï.
* à®¢¥àª¨ ª®à४⭮á⨠edx ¢ ⥪ã饩 ॠ«¨§ æ¨¨ ­¥ ¤¥« ¥âáï.
 
======================================================================
=========== ”ã­ªæ¨ï 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;
ᯨ᮪ ¢â®àëå ¤®«¦¥­ ¡ëâì 㪠§ ­ ¢ ¤®ªã¬¥­â æ¨¨ ¯® ãáâனáâ¢ã.
 
======================================================================
================ ”ã­ªæ¨ï 63 - à ¡®â  á ¤®áª®© ®â« ¤ª¨. ===============
======================================================================
„®áª  ®â« ¤ª¨ ¯à¥¤áâ ¢«ï¥â ᮡ®© á¨á⥬­ë© ¡ãä¥à (­  512 ¡ ©â),
¢ ª®â®àë© «î¡ ï ¯à®£à ¬¬  ¬®¦¥â § ¯¨á âì (¢®®¡é¥ £®¢®àï, ¯à®¨§¢®«ì­ë¥)
¤ ­­ë¥ ¨ ¨§ ª®â®à®£® ¤àã£ ï ¯à®£à ¬¬  ¬®¦¥â í⨠¤ ­­ë¥ ¯à®ç¨â âì.
…áâì ᮣ« è¥­¨¥, ¢ ᮮ⢥âá⢨¨ á ª®â®àë¬ § ¯¨á뢠¥¬ë¥ ¤ ­­ë¥ -
⥪áâ®¢ë¥ áâப¨, ¨­â¥à¯à¥â¨àã¥¬ë¥ ª ª ®â« ¤®ç­ë¥ á®®¡é¥­¨ï ® 室¥
¢ë¯®«­¥­¨ï ¯à®£à ¬¬ë. Ÿ¤à® ¢ ®¯à¥¤¥«ñ­­ëå á¨âã æ¨ïå â ª¦¥ § ¯¨á뢠¥â
­  ¤®áªã ®â« ¤ª¨ ᢥ¤¥­¨ï ® ¢ë¯®«­¥­¨¨ ­¥ª®â®àëå ä㭪権;
¯® ᮣ« è¥­¨î á®®¡é¥­¨ï ï¤à  ­ ç¨­ îâáï á ¯à¥ä¨ªá  "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
 
======================================================================
================= ”ã­ªæ¨ï 66 - à ¡®â  á ª« ¢¨ âãன. =================
======================================================================
¥¦¨¬ ¢¢®¤  ¢«¨ï¥â ­  १ã«ìâ âë ç⥭¨ï ª« ¢¨è ä㭪樥© 2.
à¨ § £à㧪¥ ¯à®£à ¬¬ë ¤«ï ­¥ñ ãáâ ­ ¢«¨¢ ¥âáï ASCII-०¨¬ ¢¢®¤ .
 
-------- ®¤äã­ªæ¨ï 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
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ebx:eax = ª®¯¨ï esi:edi
‡ ¬¥ç ­¨ï:
* “ª § ­¨¥ ¢ ecx ­¥áãé¥áâ¢ãî饣® ¨«¨ ­¥à¥ «¨§®¢ ­­®£® ¤«ï ¤ ­­®£®
¯à®æ¥áá®à  MSR ¯®¢«¥çñ⠨᪫î祭¨¥ ¢ ï¤à¥, ª®â®à®¥ ¯à¨¡ìñâ ¯®â®ª.
* à¥¤¢ à¨â¥«ì­® á«¥¤ã¥â ®¯à¥¤¥«¨âì, ¯®¤¤¥à¦¨¢ îâáï «¨ MSR ¢ 楫®¬,
ª®¬ ­¤®© cpuid. ˆ­ ç¥ ¢®§­¨ª­¥â 㦥 ¤à㣮¥ ¨áª«î祭¨¥ ¢ ï¤à¥,
ª®â®à®¥ ¢áñ à ¢­® ¯à¨¡ìñâ ¯®â®ª.
 
======================================================================
===== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 11 - ¨­¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá . ====
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 11 - ­®¬¥à ¯®¤ä㭪樨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ­¥ãᯥå
* ¨­ ç¥ à §¬¥à ᮧ¤ ­­®© ªãç¨
‡ ¬¥ç ­¨ï:
* ‚맮¢ ä㭪樨 ¨­¨æ¨ «¨§¨àã¥â ªãçã, ¨§ ª®â®à®© ¢¯®á«¥¤á⢨¨ ¬®¦­®
¢ë¤¥«ïâì ¨ ®á¢®¡®¦¤ âì ¡«®ª¨ ¯ ¬ï⨠¯®¤äã­ªæ¨ï¬¨ 12 ¨ 13.
 §¬¥à ªãç¨ à ¢¥­ à §¬¥à㠢ᥩ ᢮¡®¤­®© ¯ ¬ï⨠¯à¨«®¦¥­¨ï.
* à¨ ¯®¢â®à­®¬ ¢ë§®¢¥ ä㭪樨 ⥬ ¦¥ ¯à®æ¥áᮬ äã­ªæ¨ï ¢¥à­ñâ à §¬¥à
áãé¥áâ¢ãî饩 ªãç¨.
* ®á«¥ ᮧ¤ ­¨ï ªãç¨ ¢ë§®¢ë ä㭪樨 64.1 ¨£­®à¨àãîâáï.
 
======================================================================
========== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 12 - ¢ë¤¥«¨âì ¡«®ª ¯ ¬ïâ¨. =========
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 12 - ­®¬¥à ¯®¤ä㭪樨
* ecx = âà¥¡ã¥¬ë© à §¬¥à ¢ ¡ ©â å
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 㪠§ â¥«ì ­  ¢ë¤¥«¥­­ë© ¡«®ª
‡ ¬¥ç ­¨ï:
* à¥¤¢ à¨â¥«ì­® á«¥¤ã¥â ¨­¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá  ¢ë§®¢®¬
¯®¤ä㭪樨 11.
* ”ã­ªæ¨ï ¢ë¤¥«ï¥â 楫®¥ ç¨á«® áâà ­¨æ (4 Š¡) â ª, çâ® ä ªâ¨ç¥áª¨©
à §¬¥à ¢ë¤¥«¥­­®£® ¡«®ª  ¡®«ìè¥ ¨«¨ à ¢¥­ § ¯à®è¥­­®¬ã.
 
======================================================================
========= ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 13 - ®á¢®¡®¤¨âì ¡«®ª ¯ ¬ïâ¨. ========
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 13 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¡«®ª ¯ ¬ïâ¨
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 1 - ãᯥ譮
* eax = 0 - ­¥ã¤ ç 
‡ ¬¥ç ­¨ï:
* «®ª ¯ ¬ï⨠¤®«¦¥­ ¡ëâì à ­¥¥ ¢ë¤¥«¥­ ¯®¤ä㭪樥© 12.
 
======================================================================
===== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 14 - ®¦¨¤ âì ¨§¢¥é¥­¨ï ®â ¤à ©¢¥à . =====
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 14 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ¡ãä¥à ¤«ï ¨­ä®à¬ æ¨¨ (8 ¡ ©â)
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* ¡ãä¥à, ­  ª®â®àë© ãª §ë¢ ¥â ecx, ᮤ¥à¦¨â á«¥¤ãîéãî ¨­ä®à¬ æ¨î:
* +0: dword: ª®­áâ ­â  EV_INTR = 1
* +4: dword: ¤ ­­ë¥ ¤à ©¢¥à 
‡ ¬¥ç ­¨ï:
* ’¥ªãé ï ॠ«¨§ æ¨ï ¢® ¢à¥¬ï ®¦¨¤ ­¨ï âॡã¥â ¤®¢®«ì­® "âï¦ñ«ëå"
®¯¥à æ¨© ¯¥à¥ª«î祭¨ï ª®­â¥ªáâ .
 
======================================================================
== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 15 - ãáâ ­®¢¨âì ®¡à ¡®â稪 ¨áª«î祭¨© FPU. =
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 15 - ­®¬¥à ¯®¤ä㭪樨
* ecx =  ¤à¥á ­®¢®£® ®¡à ¡®â稪  ¨áª«î祭¨©
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax =  ¤à¥á áâ à®£® ®¡à ¡®â稪  ¨áª«î祭¨©
(0, ¥á«¨ ®­ ­¥ ¡ë« ãáâ ­®¢«¥­)
 
======================================================================
=========== ”ã­ªæ¨ï 68, ¯®¤äã­ªæ¨ï 16 - § £à㧨âì ¤à ©¢¥à. ===========
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 16 - ­®¬¥à ¯®¤ä㭪樨
* ecx = 㪠§ â¥«ì ­  ASCIIZ áâபã á ¨¬¥­¥¬ ¤à ©¢¥à 
¬ ªá¨¬ «ì­ ï ¤«¨­  ¨¬¥­¨ 16 ᨬ¢®«®¢ ¢ª«îç ï ­®«ì
®áâ «ì­ë¥ ᨬ¢®«ë ¨£­®à¨àãîâáï
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax = 0 - ­¥ã¤ ç 
* ¨­ ç¥ eax = åí­¤« ¤à ©¢¥à 
‡ ¬¥ç ­¨ï:
* …᫨ ¤à ©¢¥à ¥éñ ­¥ § £à㦥­, ®­ § £à㦠¥âáï;
¥á«¨ ¤à ©¢¥à 㦥 § £à㦥­, ­¨ç¥£® ­¥ ¬¥­ï¥âáï.
* ˆ¬ï ¤à ©¢¥à  çã¢á⢨⥫쭮 ª ॣ¨áâàã ᨬ¢®«®¢.
* Œ®¦­® § £à㦠âì ⮫쪮 ¤à ©¢¥à , § à¥£¨áâà¨à®¢ ­­ë¥ ¢ á¨á⥬¥;
¢ ⥪ã饩 ॠ«¨§ æ¨¨ ¥áâì ஢­® 2 â ª¨å ¤à ©¢¥à :
* ¨¬ï SOUND, ä ©« /rd/1/unisound.obj
* ¨¬ï INFINITY, ä ©« /rd/1/infinity.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. =
======================================================================
 à ¬¥âàë:
* eax = 68 - ­®¬¥à ä㭪樨
* ebx = 18 - ­®¬¥à ¯®¤ä㭪樨
* ecx =  ¤à¥á ­®¢®£® ®¡à ¡®â稪  ¨áª«î祭¨©
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* eax =  ¤à¥á áâ à®£® ®¡à ¡®â稪  ¨áª«î祭¨©
(0, ¥á«¨ ®­ ­¥ ¡ë« ãáâ ­®¢«¥­)
 
======================================================================
======================== ”ã­ªæ¨ï 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.
 
‚ᥠ¯®¤ä㭪樨 ¯à¨¬¥­¨¬ë ⮫쪮 ª ¯à®æ¥áá ¬/¯®â®ª ¬, § ¯ã饭­ë¬
¨§ ⥪ã饣® ä㭪樥© 58 ¨«¨ 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)
à¨¬¥àë:
* '/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
„®áâã¯­ë¥ ¯®¤ä㭪樨:
* ¯®¤äã­ªæ¨ï 0 - ç⥭¨¥ ä ©« 
* ¯®¤äã­ªæ¨ï 1 - ç⥭¨¥ ¯ ¯ª¨
* ¯®¤äã­ªæ¨ï 2 - ᮧ¤ ­¨¥/¯¥à¥§ ¯¨áì ä ©« 
* ¯®¤äã­ªæ¨ï 3 - § ¯¨áì ¢ áãé¥áâ¢ãî騩 ä ©«
* ¯®¤äã­ªæ¨ï 4 - ãáâ ­®¢ª  à §¬¥à  ä ©« 
* ¯®¤äã­ªæ¨ï 5 - ¯®«ã祭¨¥  âਡã⮢ ä ©« /¯ ¯ª¨
* ¯®¤äã­ªæ¨ï 6 - ãáâ ­®¢ª   âਡã⮢ ä ©« /¯ ¯ª¨
* ¯®¤äã­ªæ¨ï 7 - § ¯ã᪠¯à®£à ¬¬ë
* ¯®¤äã­ªæ¨ï 8 - 㤠«¥­¨¥ ä ©« /¯ ¯ª¨
„«ï CD-¯à¨¢®¤®¢ ¢ á¢ï§¨ á  ¯¯ à â­ë¬¨ ®£à ­¨ç¥­¨ï¬¨ ¤®áâ㯭ë
⮫쪮 ¯®¤ä㭪樨 0,1,5 ¨ 7, ¢ë§®¢ ¤àã£¨å ¯®¤ä㭪権 § ¢¥àè¨âáï
®è¨¡ª®© á ª®¤®¬ 2.
 
======================================================================
= ”ã­ªæ¨ï 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, "¤®áâ㯠§ ¯à¥éñ­").
 
======================================================================
=== ”ã­ªæ¨ï 71, ¯®¤äã­ªæ¨ï 1 - ãáâ ­®¢¨âì § £®«®¢®ª ®ª­  ¯à®£à ¬¬ë. ==
======================================================================
 à ¬¥âàë:
* eax = 71 - ­®¬¥à ä㭪樨
* ebx = 1 - ­®¬¥à ¯®¤ä㭪樨
* ecx =  ¤à¥á áâப¨ § £®«®¢ª 
‚®§¢à é ¥¬®¥ §­ ç¥­¨¥:
* äã­ªæ¨ï ­¥ ¢®§¢à é ¥â §­ ç¥­¨ï
‡ ¬¥ç ­¨ï:
* ‘âப  § £®«®¢ª  ¤®«¦­  ¡ëâì ¢ ä®à¬ â¥ ASCIIZ. ‚ § £®«®¢ª¥
®â®¡à ¦ ¥âáï ­¥ ¡®«¥¥ 255 ᨬ¢®«®¢ ­¥§ ¢¨á¨¬® ®â ¯®«­®© ¤«¨­ë
áâப¨.
* —⮡ë ã¡à âì § £®«®¢®ª, ¯¥à¥¤ ©â¥ NULL ¢ ecx.
 
======================================================================
========== ”ã­ªæ¨ï -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 = ¢®§¢à é ¥âáï ⮫쪮 ä㭪樥© rename ¯à¨ ¯¥à¥¤ ç¥ ᨫ쭮
­¥¢¥à­®£® ¯ à ¬¥âà  ¨ ­¨ª ª ­¥ ᮮ⢥âáâ¢ã¥â ®¯¨á ­¨î
¢ ¨á室­¨ª å ï¤à  "partition not defined at hd"
* 5 = ä ©« ­¥ ­ ©¤¥­
* 6 = ä ©« § ª®­ç¨«áï
* 7 = 㪠§ â¥«ì ¢­¥ ¯ ¬ï⨠¯à¨«®¦¥­¨ï
* 8 = ¤¨áª § ¯®«­¥­
* 9 = â ¡«¨æ  FAT à §àã襭 
* 10 = ¤®áâ㯠§ ¯à¥éñ­
* 11 = ®è¨¡ª  ãáâனá⢠
à¨ § ¯ã᪥ ¯à®£à ¬¬ë ¢®§¬®¦­ë â ª¦¥ á«¥¤ãî騥 ª®¤ë ®è¨¡®ª:
* 30 = 0x1E = ­¥¤®áâ â®ç­® ¯ ¬ïâ¨
* 31 = 0x1F = ä ©« ­¥ ï¥âáï ¨á¯®«­¨¬ë¬
* 32 = 0x20 = ᫨誮¬ ¬­®£® ¯à®æ¥áᮢ
/kernel/tags/kolibri0.6.3.0/docs/apm/README.TXT
0,0 → 1,255
Advanced Power Management
 
SYSTEM CALL
 
eax = 70
dx = íîìåð ôóíêöèè APM BIOS (àíàëîãè÷åí ax â ðåàëüíîì ðåæèìå)
îñòàëüíûå (bx, cx) ðåãèñòðû ïî ñïåöèôèêàöèè (ñì. apm.txt)
ðåçóëüòàò : ïî ñïåöèôèêàöèè (âêëþ÷àÿ CF), ñòàðøàÿ ÷àñòü 32 áèòíûõ ðåãèñòðîâ íå îïðåäåëåíà
 
 
MEMORY MAP
 
Boot:
0x9040 - dword - entry point of APM BIOS
0x9044 - word - version (BCD)
0x9046 - word - flags
 
 
ÈÇÌÅÍÅÍÈß
 
sys32.inc
syscall.inc
kernel.asm
bootcode.inc
 
##############[core\sys32.inc]#####################
 
Òðè íîâûõ äåñêðèïòîðà
 
.............
.............
 
; GDT TABLE
 
gdts:
 
dw gdte-$-1
dd gdts
dw 0
 
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
; --------------- APM ---------------------
apm_code_32:
dw 0x10 ; limit 64kb
db 0, 0, 0
dw 11011111b *256 +10011010b
db 0x00
apm_code_16:
dw 0x10
db 0, 0, 0
dw 10011111b *256 +10011010b
db 0x00
apm_data_16:
dw 0x10
db 0, 0, 0
dw 10011111b *256 +10010010b
db 0x00
; -----------------------------------------
app_code_l:
dw ((0x80000000-std_application_base_address) shr 12) and 0xffff
dw 0
db 0
dw 11010000b*256+11111010b+256*((0x80000000-std_application_base_address) shr 28)
db std_application_base_address shr 24
 
app_data_l:
dw (0x80000000-std_application_base_address) shr 12 and 0xffff
dw 0
db 0
dw 11010000b*256+11110010b+256*((0x80000000-std_application_base_address) shr 28)
db std_application_base_address shr 24
 
graph_data_l:
 
dw 0x3ff
dw 0x0000
db 0x00
dw 11010000b *256 +11110010b
db 0x00
 
tss0_l:
times (max_processes+10) dd 0,0
 
.............
.............
 
##############[core\syscall.inc]###################
 
.............
.............
 
 
dd undefined_syscall ; 65-UTF
dd sys_process_def ; 66-Process definitions - keyboard
dd sys_window_move ; 67-Window move or resize
dd sys_internal_services ; 68-Some internal services
dd sys_debug_services ; 69-Debug
dd sys_apm ; 70-APM
 
 
.............
.............
 
##############[kernel.asm]#########################
 
 
×àñòü 1 (ïîñëå ìåòêè "; SAVE REAL MODE VARIABLES"):
 
.............
.............
 
; SAVE REAL MODE VARIABLES
 
; --------------- APM ---------------------
mov eax, [0x2f0000 + 0x9040] ; entry point
mov dword[apm_entry], eax
mov word [apm_entry + 4], apm_code_32 - gdts
 
mov eax, [0x2f0000 + 0x9044] ; version & flags
mov [apm_vf], eax
; -----------------------------------------
 
.............
.............
 
×àñòü 2 (ñèñòåìíûé âûçîâ, ðàñïîëîæåíèå íå êðèòè÷íî,
ÿ ðàñïîëîæèë ïåðåä ìåòêîé "undefined_syscall:")
 
.............
.............
 
; --------------- APM ---------------------
apm_entry dp 0
apm_vf dd 0
align 4
sys_apm:
cmp word [apm_vf], 0 ; Check APM BIOS enable
jne @f
or [esp + 40], byte 1 ; error
mov [esp + 36], dword 8 ; 32-bit protected-mode interface not supported
ret
@@: xchg eax, ecx
xchg ebx, ecx
cmp al, 3
ja @f
and [esp + 40], byte 0xfe ; emulate func 0..3 as func 0
mov eax, [apm_vf]
mov [esp + 36], eax
shr eax, 16
mov [esp + 32], eax
ret
@@: call pword [apm_entry] ; call APM BIOS
mov [esp + 8 ], edi
mov [esp + 12], esi
mov [esp + 24], ebx
mov [esp + 28], edx
mov [esp + 32], ecx
mov [esp + 36], eax
setc al
and [esp + 40], byte 0xfe
or [esp + 40], al
ret
; -----------------------------------------
 
align 4
 
undefined_syscall: ; Undefined system call
 
.............
.............
 
##############[boot\bootcode.inc]##################
 
Ïåðåä ìåòêîé "; DISPLAY VESA INFORMATION"
 
.............
.............
 
; --------------- APM ---------------------
push 0
pop es
mov 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 ----
jmp @f
msg_apm:db ' APM x.x ', 0
@@: and ax, 0xf0f
add ax, '00'
mov [msg_apm - 0x10000 + 5], ah
mov [msg_apm - 0x10000 + 7], al
_setcursor 0, 3
mov si, msg_apm - 0x10000
call printplain
_setcursor d80x25_top_num,0
; ------------------
mov ax, 0x5304 ; Disconnect interface
xor bx, bx
int 0x15
mov ax, 0x5303 ; Connect 32 bit mode interface
xor bx, bx
int 0x15
; init selectors
movzx eax, ax ; real-mode segment base address of protected-mode 32-bit code segment
shl eax, 4
mov [apm_code_32 - 0x10000 + 2], ax
shr eax, 16
mov [apm_code_32 - 0x10000 + 4], al
movzx ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment
shl ecx, 4
mov [apm_code_16 - 0x10000 + 2], cx
shr ecx, 16
mov [apm_code_16 - 0x10000 + 4], cl
movzx edx, dx ; real-mode segment base address of protected-mode 16-bit data segment
shl edx, 4
mov [apm_data_16 - 0x10000 + 2], dx
shr edx, 16
mov [apm_data_16 - 0x10000 + 4], dl
mov [es : 0x9040], ebx ; offset of APM entry point
apm_end:
; -----------------------------------------
 
 
; DISPLAY VESA INFORMATION
 
.............
.............
 
/kernel/tags/kolibri0.6.3.0/docs/apm/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/tags/kolibri0.6.3.0/const.inc
0,0 → 1,462
 
 
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 ;
 
 
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)
 
OS_BASE equ 0; 0x80400000
 
window_data equ OS_BASE+0x0000000
 
CURRENT_TASK equ OS_BASE+0x0003000
TASK_COUNT equ OS_BASE+0x0003004
TASK_BASE equ OS_BASE+0x0003010
TASK_DATA equ OS_BASE+0x0003020
TASK_EVENT equ OS_BASE+0x0003020
 
save_syscall_data equ OS_BASE+0x0005000
 
;mouseunder equ OS_BASE+0x0006900
FLOPPY_BUFF equ OS_BASE+0x0008000
ACTIVE_PROC_STACK equ OS_BASE+0x000A400
idts equ OS_BASE+0x000B100
WIN_STACK equ OS_BASE+0x000C000
WIN_POS equ OS_BASE+0x000C400
FDD_DATA equ OS_BASE+0x000D000
 
ENABLE_TASKSWITCH equ OS_BASE+0x000E000
PUTPIXEL equ OS_BASE+0x000E020
GETPIXEL equ OS_BASE+0x000E024
BANK_SWITCH equ OS_BASE+0x000E030
 
MOUSE_PICTURE equ OS_BASE+0x000F200
MOUSE_VISIBLE equ OS_BASE+0x000F204
XY_TEMP equ OS_BASE+0x000F300
KEY_COUNT equ OS_BASE+0x000F400
KEY_BUFF equ OS_BASE+0x000F401
 
BTN_COUNT equ OS_BASE+0x000F500
BTN_BUFF equ OS_BASE+0x000F501
 
CPU_FREQ equ OS_BASE+0x000F600
MOUSE_PORT equ OS_BASE+0x000F604
 
PS2_CHUNK equ OS_BASE+0x000FB00
MOUSE_X equ OS_BASE+0x000FB0A
MOUSE_Y equ OS_BASE+0x000FB0C
 
MOUSE_COLOR_MEM equ OS_BASE+0x000FB10
COLOR_TEMP equ OS_BASE+0x000FB30
BTN_DOWN equ OS_BASE+0x000FB40
MOUSE_DOWN equ OS_BASE+0x000FB44
X_UNDER equ OS_BASE+0x000FB4A
Y_UNDER equ OS_BASE+0x000FB4C
;ScreenBPP equ OS_BASE+0x000FBF1
MOUSE_BUFF_COUNT equ OS_BASE+0x000FCFF
HD_CACHE_ENT equ OS_BASE+0x000FE10
LFBAddress equ OS_BASE+0x000FE80
MEM_AMOUNT equ OS_BASE+0x000FE8C
LFBSize equ OS_BASE+0x02f9050
 
SCR_X_SIZE equ OS_BASE+0x000FE00
SCR_Y_SIZE equ OS_BASE+0x000FE04
SCR_BYTES_PER_LINE equ OS_BASE+0x000FE08
SCR_MODE equ OS_BASE+0x000FE0C
 
BTN_ADDR equ OS_BASE+0x000FE88
SYS_SHUTDOWN equ OS_BASE+0x000FF00
TASK_ACTIVATE equ OS_BASE+0x000FF01
 
REDRAW_BACKGROUND equ OS_BASE+0x000FFF0
BANK_RW equ OS_BASE+0x000FFF2
MOUSE_BACKGROUND equ OS_BASE+0x000FFF4
DONT_DRAW_MOUSE equ OS_BASE+0x000FFF5
DONT_SWITCH equ OS_BASE+0x000FFFF
 
STACK_TOP equ OS_BASE+0x003EC00
 
FONT_II equ OS_BASE+0x003EC00
FONT_I equ OS_BASE+0x003F600
DISK_DATA equ OS_BASE+0x0040000
PROC_BASE equ OS_BASE+0x0080000
TMP_BUFF equ OS_BASE+0x0090000
 
VGABasePtr equ OS_BASE+0x00A0000
 
RAMDISK equ OS_BASE+0x0100000
RAMDISK_FAT equ OS_BASE+0x0280000
FLOPPY_FAT equ OS_BASE+0x0282000
SB16_Status equ OS_BASE+0x02B0000
BUTTON_INFO equ OS_BASE+0x02C0000
RESERVED_PORTS equ OS_BASE+0x02D0000
IRQ_SAVE equ OS_BASE+0x02E0000
SYS_VAR equ OS_BASE+0x02f0000
IMG_BACKGROUND equ OS_BASE+0x0300000
WinMapAddress equ OS_BASE+0x0460000
display_data equ OS_BASE+0x0460000
HD_CACHE equ OS_BASE+0x0600000
stack_data_start equ OS_BASE+0x0700000
eth_data_start equ OS_BASE+0x0700000
stack_data equ OS_BASE+0x0704000
stack_data_end equ OS_BASE+0x071ffff
VMODE_BASE equ OS_BASE+0x0760000
resendQ equ OS_BASE+0x0770000
 
;skin_data equ OS_BASE+0x0778000
 
draw_data equ OS_BASE+0x0800000
sysint_stack_data equ OS_BASE+0x0803000
 
tss_data equ OS_BASE+0x0920000
 
pages_tab equ 0x60000000
master_tab equ 0x60180000
current_pgdir equ 0x60180000
 
sys_pgdir equ OS_BASE+0x00050000
sys_master_tab equ OS_BASE+0x00051000
sys_pgmap equ OS_BASE+0x00052000
 
;lfb_start equ 0x00800000
 
;new_app_pdir equ OS_BASE+0x01000000
;new_app_master_table equ OS_BASE+0x01001000
;new_app_ptable equ OS_BASE+0x01002000
 
new_app_base equ 0x60400000
 
twdw equ (CURRENT_TASK-window_data)
 
std_application_base_address equ new_app_base
 
PAGES_USED equ 4
 
PG_UNMAP equ 0x000
PG_MAP equ 0x001
PG_WRITE equ 0x002
PG_SW equ 0x003
PG_USER equ 0x005
PG_UW equ 0x007
PG_NOCACHE equ 0x018
PG_LARGE equ 0x080
PG_GLOBAL equ 0x100
 
;;;;;;;;;;;boot time variables
 
;BOOT_BPP equ 0x9000 ;byte bits per pixel
BOOT_SCANLINE equ 0x9001 ;word scanline length
BOOT_VESA_MODE equ 0x9008 ;word vesa video mode
;;BOOT_X_RES equ 0x900A ;word X res
;;BOOT_Y_RES equ 0x900C ;word Y res
;;BOOT_MOUSE_PORT equ 0x9010 ;byte mouse port - not used
BOOT_BANK_SW equ 0x9014 ;dword Vesa 1.2 pm bank switch
BOOT_LFB equ 0x9018 ;dword Vesa 2.0 LFB address
BOOT_MTRR equ 0x901C ;byte 0 or 1 : enable MTRR graphics acceleration
BOOT_LOG equ 0x901D ;byte not used anymore (0 or 1 : enable system log display)
BOOT_DIRECT_LFB equ 0x901E ;byte 0 or 1 : enable direct lfb write, paging disabled
BOOT_PCI_DATA equ 0x9020 ;8bytes pci data
BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no
BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr
BOOT_MEM_AMOUNT equ 0x9034 ;dword memory amount
 
TMP_FILE_NAME equ 0
TMP_CMD_LINE equ 1024
TMP_ICON_OFFS equ 1280
 
 
EVENT_REDRAW equ 0x00000001
EVENT_KEY equ 0x00000002
EVENT_BUTTON equ 0x00000004
EVENT_BACKGROUND equ 0x00000010
EVENT_MOUSE equ 0x00000020
EVENT_IPC equ 0x00000040
EVENT_NETWORK equ 0x00000080
EVENT_DEBUG equ 0x00000100
EVENT_NOTIFY equ 0x00000200
 
EV_INTR equ 1
 
struc SYS_VARS
{ .bpp dd ?
.scanline dd ?
.vesa_mode dd ?
.x_res dd ?
.y_res dd ?
.cpu_caps dd ?
dd ?
dd ?
dd ?
}
 
struc BOOT_DATA
{ .bpp dd ?
.scanline dd ?
.vesa_mode dd ?
.x_res dd ?
.y_res dd ?
.mouse_port dd ?
.bank_switch dd ?
.lfb dd ?
.vesa_mem dd ?
.log dd ?
.direct_lfb dd ?
.pci_data dd ?
; dd ?
.vrr dd ?
.ide_base dd ?
.mem_amount dd ?
.pages_count dd ?
.pagemap_size dd ?
.kernel_max dd ?
.kernel_pages dd ?
.kernel_tables dd ?
 
.cpu_vendor dd ?
dd ?
dd ?
.cpu_sign dd ?
.cpu_info dd ?
.cpu_caps dd ?
dd ?
dd ?
}
 
virtual at 0
BOOT_DATA BOOT_DATA
end virtual
 
struc PG_DATA
{ .mem_amount dd ?
.vesa_mem dd ?
.pages_count dd ?
.pages_free dd ?
.pages_faults dd ?
.pagemap_size dd ?
.kernel_max dd ?
.kernel_pages dd ?
.kernel_tables dd ?
.sys_page_dir dd ?
.pg_mutex dd ?
.tmp_task_mutex dd ?
}
 
struc LIB
{ .lib_name rb 16
.lib_base dd ?
.lib_start dd ?
.export dd ?
.import dd ?
}
 
struc SRV
{ .srv_name rb 16
.magic dd ?
.size dd ?
.base dd ?
.srv_proc dd ?
}
 
struc COFF_HEADER
{ .machine dw ?
.nSections dw ?
.DataTime dd ?
.pSymTable dd ?
.nSymbols dd ?
.optHeader dw ?
.flags dw ?
};
 
 
struc COFF_SECTION
{ .Name rb 8
.VirtualSize dd ?
.VirtualAddress dd ?
.SizeOfRawData dd ?
.PtrRawData dd ?
.PtrReloc dd ?
.PtrLinenumbers dd ?
.NumReloc dw ?
.NumLinenum dw ?
.Characteristics dd ?
}
 
struc COFF_RELOC
{ .VirtualAddress dd ?
.SymIndex dd ?
.Type dw ?
}
 
struc COFF_SYM
{ .Name rb 8
.Value dd ?
.SectionNumber dw ?
.Type dw ?
.StorageClass db ?
.NumAuxSymbols db ?
}
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
 
 
SRV_SIZE equ 32
 
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
 
/kernel/tags/kolibri0.6.3.0/gui/skincode.inc
0,0 → 1,444
include "skindata.inc"
 
skin_data = 0x00778000
 
load_skin_file:
; eax = filename
; edx = destination
mov ebx,1
or ecx,-1
mov esi,12
call fileread
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_skin:
pushad
mov [_skinh],22
mov eax,_skin_file
mov edx,skin_data
mov [edx+SKIN_HEADER.ident],'????'
call load_skin_file
cmp eax,ERROR_SUCCESS
je @f
cmp eax,ERROR_END_OF_FILE
jne .exit
@@: call parse_skin_data
.exit:
popad
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]
or [edi+WDATA.fl_wdrawn], 4
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]
call [drawbar]
_noinside2:
 
cmp dword[skin_data],'SKIN'
jne no_skin_add_button
 
;* close button
mov edi,[0xfe88]
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,[0x3000]
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,[0xfe88]
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,[0x3000]
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
and [edi+WDATA.fl_wdrawn], not 4
test [edi+WDATA.fl_wdrawn], 2
jz @f
call drawwindowframes2
@@:
 
popa
 
ret 4
 
/kernel/tags/kolibri0.6.3.0/gui/window.inc
0,0 → 1,1765
get_titlebar_height: ; edi = window draw_data pointer
mov al,[edi+WDATA.fl_wstyle]
and al,0x0F
cmp al,0x03
jne @f
mov eax,[_skinh]
ret
@@: mov eax,21
ret
 
get_rolledup_height: ; edi = window draw_data pointer
mov al,[edi+WDATA.fl_wstyle]
and al,0x0F
cmp al,0x03
jne @f
mov eax,[_skinh]
add eax,3
ret
@@: or al,al
jnz @f
mov eax,21
ret
@@: mov eax,21+2
ret
 
 
setwindowdefaults:
pushad
 
xor eax,eax
mov ecx,0xc000
@@:
inc eax
add ecx,2
mov [ecx+0x000],ax ; process no
mov [ecx+0x400],ax ; positions in stack
cmp ecx,0xc400-2 ; the more high, the more surface
jnz @b
 
popad
ret
 
 
 
; eax = cx
; ebx = cy
; ecx = ex
; edx = ey
; èäåÿ: ïåðåáðàòü âñå îêíà, íà÷èíàÿ ñ ñàìîãî íèæíåãî,
; è äëÿ ïîïàâøèõ â çàäàííóþ îáëàñòü
; ÷àñòåé îêîí âûçâàòü setscreen
align 4
calculatescreen:
pushad
pushfd
cli
 
push edx ecx ebx eax
 
mov esi, 1
call setscreen
 
mov ebp, [0x3004] ; number of processes
cmp ebp, 1
jbe .finish
align 4
.new_wnd:
movzx edi, word [0xC400 + esi * 2]
shl edi, 5
 
cmp [0x3000+edi+TASKDATA.state], byte 9
je .not_wnd
 
add edi, window_data
test [edi+WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .not_wnd
 
mov eax,[edi+WDATA.box.left]
cmp eax, [esp+RECT.right]
ja .out_of_bounds
mov ebx,[edi+WDATA.box.top]
cmp ebx, [esp+RECT.bottom]
ja .out_of_bounds
mov ecx,[edi+WDATA.box.width]
add ecx, eax
cmp ecx, [esp+RECT.left]
jb .out_of_bounds
mov edx,[edi+WDATA.box.height]
add edx, ebx
cmp edx, [esp+RECT.top]
jb .out_of_bounds
 
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 [0xC400 + esi * 2]
call setscreen
pop esi
 
.not_wnd:
.out_of_bounds:
inc esi
dec ebp
jnz .new_wnd
.finish:
 
pop eax ebx ecx edx
 
popfd
popad
ret
 
 
 
virtual at esp
ff_x dd ?
ff_y dd ?
ff_width dd ?
ff_xsz dd ?
ff_ysz dd ?
ff_scale dd ?
end virtual
 
align 4
; ðåçåðâèðóåò ìåñòî ïîä îêíî çàäàííîãî ïðîöåññà
setscreen:
; eax x start
; ebx y start
; ecx x end
; edx y end
; esi process number
pushad
; \begin{diamond}[29.08.2006]
cmp esi, 1
jz @f
mov edi, esi
shl edi, 5
cmp [edi+window_data+WDATA.box.width], 0
jnz @f
cmp [edi+window_data+WDATA.box.height], 0
jz .ret
@@:
; \end{diamond}[29.08.2006]
mov edi, esi ;;;word [esi*2+0xc400]
shl edi, 8
add edi, 0x80000 ; address of random shaped window area
cmp [edi+APPDATA.wnd_shape], dword 0
jne .free_form
 
; get x&y size
sub ecx, eax
sub edx, ebx
inc ecx
inc edx
 
; get WinMap start
mov edi, [0xFE00] ; screen_sx
inc edi
imul edi, ebx
add edi, eax
add edi, WinMapAddress
 
.new_y:
push ecx ; sx
push edx
 
mov edx, esi
align 4
.new_x:
mov byte [edi], dl
inc edi
dec ecx
jnz .new_x
 
pop edx
pop ecx
add edi, [0xFE00]
inc edi
sub edi, ecx
dec edx
jnz .new_y
.ret:
popad
ret
.read_byte:
;eax - address
;esi - slot
push eax
push ebx
push ecx
push edx
mov edx,eax
mov eax,esi
lea ebx,[esp+12]
mov ecx,1
call read_process_memory
pop edx
pop ecx
pop ebx
pop eax
ret
.free_form:
 
; 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 dword [edi+APPDATA.wnd_shape_scale] ; push scale first -> for loop
 
; get WinMap start -> ebp
push eax
mov eax, [0xFE00] ; 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, [0xFE00] ; screen.x
inc ebp
inc ebx
cmp ebx, [ff_ysz]
jb .ff_new_y
 
add esp, 24
popad
ret
 
 
display_settings:
 
; eax = 0 ; DISPLAY redraw
; ebx = 0 ; all
;
; eax = 1 ; BUTTON type
; ebx = 0 ; flat
; ebx = 1 ; 3D
; eax = 2 ; set WINDOW colours
; ebx = pointer to table
; ecx = number of bytes define
; eax = 3 ; get WINDOW colours
; ebx = pointer to table
; ecx = number of bytes wanted
; eax = 4 ; get skin height
; input : nothing
; output : eax = skin height in pixel
; eax = 5 ; get screen workarea
; input : nothing
; output : eax = [left]*65536+[right]
; ebx = [top]*65536+[bottom]
; eax = 6 ; set screen workarea
; input : ecx = [left]*65536+[right]
; edx = [top]*65536+[bottom]
; output : nothing
; eax = 7 ; get skin margins
; input : nothing
; output : eax = [left]*65536+[right]
; ebx = [top]*65536+[bottom]
; eax = 8 ; set window skin
; input : ecx = pointer to file info block
; output : eax = FS error code
 
 
pushad
 
test eax, eax ; redraw display
jnz dspl0
test ebx, ebx
jnz dspl0
cmp [windowtypechanged],dword 1
jne dspl00
mov [windowtypechanged],dword 0
redraw_screen_direct:
mov [dlx],dword 0
mov [dly],dword 0
mov eax,[0xfe00]
mov [dlxe],eax
mov eax,[0xfe04]
mov [dlye],eax
mov eax,window_data
call redrawscreen
dspl00:
popad
ret
dspl0:
 
cmp eax,1 ; button type
jne dspl1
and ebx,1
cmp ebx,[buttontype]
je dspl9
mov [buttontype],ebx
mov [windowtypechanged],dword 1
dspl9:
popad
ret
dspl1:
 
cmp eax,2 ; set common window colours
jne no_com_colours
mov [windowtypechanged],dword 1
mov esi,[0x3010]
add esi,TASKDATA.mem_start
add ebx,[esi]
mov esi,ebx
mov edi,common_colours
and ecx,127
cld
rep movsb
popad
ret
no_com_colours:
 
cmp eax,3 ; get common window colours
jne no_get_com
mov esi,[0x3010]
add esi,TASKDATA.mem_start
add ebx,[esi]
mov edi,ebx
mov esi,common_colours
and ecx,127
cld
rep movsb
popad
ret
no_get_com:
 
cmp eax,4 ; get skin height
jne no_skin_height
popad
mov eax,[_skinh]
mov [esp+36],eax
ret
no_skin_height:
 
cmp eax,5 ; get screen workarea
jne no_get_workarea
popad
mov eax,[screen_workarea.left-2]
mov ax,word[screen_workarea.right]
mov [esp+36],eax
mov eax,[screen_workarea.top-2]
mov ax,word[screen_workarea.bottom]
mov [esp+24],eax
ret
no_get_workarea:
 
cmp eax,6 ; set screen workarea
jne no_set_workarea
movsx eax,word[esp+16+2]
movsx ebx,word[esp+16]
cmp eax,ebx
jge .lp1
or eax,eax;[0xFE00]
jl @f
mov [screen_workarea.left],eax
@@: cmp ebx,[0xFE00]
jg .lp1
mov [screen_workarea.right],ebx
.lp1: movsx eax,word[esp+24+2]
movsx ebx,word[esp+24]
cmp eax,ebx
jge .lp2
or eax,eax;[0xFE04]
jl @f
mov [screen_workarea.top],eax
@@: cmp ebx,[0xFE04]
jg .lp2
mov [screen_workarea.bottom],ebx
.lp2: call repos_windows
mov eax, 0
mov ebx, 0
mov ecx, [0xfe00]
mov edx, [0xfe04]
call calculatescreen
; jmp redraw_screen_direct
.exit:
popad
ret
no_set_workarea:
 
cmp eax,7 ; get skin margins
jne no_get_skinmargins
popad
mov eax,dword[_skinmargins+0]
mov [esp+36],eax
mov eax,dword[_skinmargins+4]
mov [esp+24],eax
ret
no_get_skinmargins:
 
cmp eax,8 ; set window skin
jne no_set_skin
mov eax,ebx
mov edi,[0x3010]
add ebx,[edi+TASKDATA.mem_start] ; abs start of info block
pushd [ebx+0] [ebx+4] [ebx+8] [ebx+12]
mov dword[ebx+0],0 ; read
mov dword[ebx+4],0 ; from the beginning
mov dword[ebx+8],64 ; 32 KBytes maximum
mov ecx,skin_data+64*512
sub ecx,[edi+0x10]
mov dword[ebx+12],ecx ; destination
push eax
pushad
call file_system
popad
pop eax
popd [ebx+12] [ebx+8] [ebx+4] [ebx+0]
cmp eax,ERROR_SUCCESS
je @f
cmp eax,ERROR_END_OF_FILE
jne .exit
@@: cmp [skin_data+64*512+SKIN_HEADER.ident],'SKIN'
mov eax,ERROR_UNKNOWN_FS
jne .exit
mov esi,skin_data+64*512
mov edi,skin_data
mov ecx,(64*512)/4
rep movsd
call parse_skin_data
pushad
mov eax, 0
mov ebx, 0
mov ecx, [0xfe00]
mov edx, [0xfe04]
call calculatescreen
popad
mov dword[esp+32+36],0
jmp redraw_screen_direct
.exit:
mov [esp+32+36],eax
popad
ret
no_set_skin:
 
popad
ret
 
 
repos_windows:
mov ecx,[0x3004]
mov edi,0x20*2
mov byte[0x0000fff0],1
dec ecx
jge @f
ret
@@: mov [edi+WDATA.fl_redraw],1
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED
jz .lp2
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 .lp1
sub eax,[screen_workarea.bottom]
neg eax
mov [edi+WDATA.box.height],eax
.lp1:
call set_window_clientbox
add edi,0x20
loop @b
ret
.lp2: mov eax,[edi+WDATA.box.left]
add eax,[edi+WDATA.box.width]
mov ebx,[0x0000fe00]
; inc ebx
cmp eax,ebx
jle .lp4
mov eax,[edi+WDATA.box.width]
sub eax,ebx
jle .lp3
mov [edi+WDATA.box.width],ebx
.lp3: sub ebx,[edi+WDATA.box.width]
mov [esi+WDATA.box.left],ebx
.lp4: mov eax,[edi+WDATA.box.top]
add eax,[edi+WDATA.box.height]
mov ebx,[0x0000fe04]
; inc ebx
cmp eax,ebx
jle .lp6
mov eax,[edi+WDATA.box.height]
sub eax,ebx
jle .lp5
mov [edi+WDATA.box.height],ebx
.lp5: sub ebx,[edi+WDATA.box.height]
mov [edi+WDATA.box.top],ebx
.lp6: jmp .lp1
 
uglobal
common_colours:
times 128 db 0x0
endg
 
 
 
 
check_window_position:
 
pushad ; window inside screen ?
 
movzx eax,word [edi+WDATA.box.left]
movzx ebx,word [edi+WDATA.box.top]
movzx ecx,word [edi+WDATA.box.width]
movzx edx,word [edi+WDATA.box.height]
 
mov esi,ecx ; check x pos
add esi,eax
cmp esi,[0xfe00]
jbe x_pos_ok
mov [edi+WDATA.box.left],dword 0
xor eax, eax
x_pos_ok:
 
mov esi,edx ; check y pos
add esi,ebx
cmp esi,[0xfe04]
jbe y_pos_ok
mov [edi+WDATA.box.top],dword 0
mov ebx,0
y_pos_ok:
 
mov esi,ecx ; check x size
add esi,eax
cmp esi,[0xfe00]
jbe x_size_ok
mov ecx,[0xfe00]
mov [edi+WDATA.box.width],ecx
x_size_ok:
 
mov esi,edx ; check y size
add esi,ebx
cmp esi,[0xfe04]
jbe y_size_ok
mov edx,[0xfe04]
mov [edi+WDATA.box.height],edx
y_size_ok:
 
popad
 
ret
 
 
uglobal
new_window_starting dd 0
endg
 
 
sys_window_mouse:
 
push eax
 
mov eax,[timer_ticks]
cmp [new_window_starting],eax
jb swml1
 
mov [0xfff4],byte 0 ; no mouse background
mov [0xfff5],byte 0 ; draw mouse
 
mov [new_window_starting],eax
 
swml1:
 
pop eax
 
ret
 
 
 
 
drawwindow_I_caption:
 
mov ecx,[edx+WDATA.cl_titlebar] ; grab bar
push ecx
mov esi,edx
mov edx,[esi+WDATA.box.top]
add edx,1
mov ebx,[esi+WDATA.box.top]
add ebx,21
mov eax,[esi+WDATA.box.top]
add eax,[esi+WDATA.box.height]
cmp ebx,eax
jb .wdsizeok
mov ebx,eax
.wdsizeok:
push ebx
.drwi:
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]
sub eax,1
push edx
mov edx,0x80000000
mov ecx,[esi+WDATA.cl_titlebar]
and ecx,edx
cmp ecx,edx
jnz .nofa
mov ecx,[esi+WDATA.cl_titlebar]
sub ecx,0x00040404
mov [esi+WDATA.cl_titlebar],ecx
and ecx,0x00ffffff
jmp .faj
.nofa:
mov ecx,[esi+WDATA.cl_titlebar]
and ecx,0x00ffffff
.faj:
pop edx
mov edi,0
call [draw_line]
inc edx
cmp edx,[esp]
jb .drwi
add esp,4
pop ecx
mov [esi+WDATA.cl_titlebar],ecx
 
ret
 
 
drawwindow_I:
 
pushad
or [edx+WDATA.fl_wdrawn], 4
 
mov esi,[edx+WDATA.cl_frames] ; rectangle
mov eax,[edx+WDATA.box.left]
shl eax,16
add eax,[edx+WDATA.box.left]
add eax,[edx+WDATA.box.width]
mov ebx,[edx+WDATA.box.top]
shl ebx,16
add ebx,[edx+WDATA.box.top]
add ebx,[edx+WDATA.box.height]
call draw_rectangle
 
and [edx+WDATA.fl_wdrawn], not 4
test [edx+WDATA.fl_wdrawn], 2
jz @f
call drawwindowframes2
@@:
 
call drawwindow_I_caption
 
mov edx,[esi+WDATA.box.top] ; inside work area
add edx,21+5
mov ebx,[esi+WDATA.box.top]
add ebx,[esi+WDATA.box.height]
cmp edx,ebx
jg noinside
mov eax,1
mov ebx,21
mov ecx,[esi+WDATA.box.width]
mov edx,[esi+WDATA.box.height]
mov edi,[esi+WDATA.cl_workarea]
call [drawbar]
noinside:
 
popad
 
ret
 
 
draw_rectangle:
 
r_eax equ [esp+28] ; x start
r_ax equ [esp+30] ; x end
r_ebx equ [esp+16] ; y start
r_bx equ [esp+18] ; y end
;esi ; color
 
pushad
 
mov ecx,esi ; yb,xb -> yb,xe
mov eax, r_eax
rol eax, 16
mov ebx,r_ebx
shl ebx,16
mov bx,r_ebx
xor edi, edi
call [draw_line]
 
mov ebx,r_bx ; ye,xb -> ye,xe
shl ebx,16
mov bx,r_bx
call [draw_line]
 
mov ecx,esi ; ya,xa -> ye,xa
mov eax,r_eax
shl eax,16
mov ax,r_eax
mov ebx,r_ebx
shl ebx,16
mov bx,r_bx
mov edi,0
call [draw_line]
 
mov eax,r_ax ; ya,xe -> ye,xe
shl eax,16
mov ax,r_ax
call [draw_line]
 
popad
ret
 
 
drawwindow_III_caption:
 
mov ecx,[edx+WDATA.cl_titlebar] ; GRAB BAR
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 .wdsizeok
mov ebx,eax
.wdsizeok:
push ebx
.drwi:
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 .nofa
add ecx,0x040404
.nofa:
test ecx,0x80000000
jz .nofa2
sub ecx,0x040404
.nofa2:
mov [esi+WDATA.cl_titlebar],ecx
and ecx,0xffffff
xor edi, edi
call [draw_line]
inc edx
cmp edx,[esp]
jb .drwi
add esp,4
pop ecx
mov [esi+WDATA.cl_titlebar],ecx
 
ret
 
 
drawwindow_III:
 
pushad
 
mov edi,edx ; RECTANGLE
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+WDATA.cl_frames]
shr esi,1
and esi,0x007f7f7f
push esi
or [edi+WDATA.fl_wdrawn], 4
call draw_rectangle
and [edi+WDATA.fl_wdrawn], not 4
test [edi+WDATA.fl_wdrawn], 2
jz @f
call drawwindowframes2
@@:
mov ecx,3
dw3l:
add eax,1*65536-1
add ebx,1*65536-1
mov esi,[edi+WDATA.cl_frames]
call draw_rectangle
dec ecx
jnz dw3l
pop esi
add eax,1*65536-1
add ebx,1*65536-1
call draw_rectangle
 
call drawwindow_III_caption
 
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,20
mov ecx,[esi+WDATA.box.width]
mov edx,[esi+WDATA.box.height]
sub ecx,4
sub edx,4
mov edi,[esi+WDATA.cl_workarea]
call [drawbar]
noinside2:
 
popad
 
ret
 
 
 
; activate window
align 4
windowactivate:
 
; esi = abs mem position in stack 0xC400+
 
pushad
 
; if type of current active window is 3,
; it must be redrawn
mov eax, [0x3004]
movzx eax, word [0xC400 + eax*2]
shl eax, 5
add eax, window_data
mov ebx, [eax + WDATA.cl_workarea]
and ebx, 0x0f000000
cmp ebx, 0x03000000
jne @f
mov [eax + WDATA.fl_redraw], byte 1
@@:
 
push esi
movzx eax, word [esi] ; ax <- process no
movzx eax, word [0xC000+eax*2] ; ax <- position in window stack
 
xor esi, esi ; drop others
waloop:
cmp esi, dword [0x3004]
jae wacont
inc esi
lea edi, [0xC000 + esi*2]
mov bx, [edi] ; position of the current process
cmp bx, ax
jbe @f
dec bx ; upper? => drop!
mov [edi], bx
@@:
jmp waloop
wacont:
; set to no 1
pop esi ; esi = pointer at 0xC400
 
movzx eax, word [esi]
mov bx, [0x3004] ; number of processes
mov [0xC000+eax*2], bx ; this is the last (and the upper)
 
; update on screen -window stack
xor esi, esi
waloop2:
mov edi, [0x3004]
cmp esi, edi
jae wacont2
inc esi
movzx ebx, word [esi*2 + 0xC000]
mov [ebx*2 + 0xC400], si
jmp waloop2
wacont2:
mov [0xf400], byte 0 ; empty keyboard buffer
mov [0xf500], byte 0 ; empty button buffer
popad
ret
 
 
; check if window is necessary to draw
 
checkwindowdraw:
 
; edi = position in window_data+
 
mov eax, [edi + WDATA.cl_workarea]
and eax, 0x0f000000
cmp eax, 0x03000000
je .return_yes ; window type 3
 
mov esi, edi
sub esi, window_data
shr esi, 5
 
; esi = process number
 
movzx eax, word [0xC000 + esi * 2] ; get value of the curr process
lea esi, [0xC400 + eax * 2] ; get address of this process at 0xC400
 
push esi
 
.new_check:
 
pop esi
add esi, 2
push esi
 
mov eax, [0x3004]
lea eax, word [0xC400 + eax * 2] ; number of the upper window
 
cmp esi, eax
ja .all_wnds_to_top
 
movzx eax, word [esi]
shl eax, 5
cmp [0x3000 + eax + TASKDATA.state], byte 9
je .new_check ; skip dead windows
 
lea esi, [eax+window_data]
 
mov ebx, [edi+WDATA.box.top] ; y0
mov edx, [edi+WDATA.box.height]
add edx, ebx ; y0e
 
mov ecx, [esi+WDATA.box.top] ; y ; y check
cmp ecx, edx
jae .new_check ; y < y0e
mov eax, [esi+WDATA.box.height]
add ecx, eax ; ye
cmp ebx, ecx ; y0 >= ye
ja .new_check
 
mov eax, [edi+WDATA.box.left] ; x0
mov ecx, [edi+WDATA.box.width]
add ecx, eax ; x0e
 
mov edx, [esi+WDATA.box.left] ; x ; x check
cmp edx, ecx
jae .new_check ; x < x0e
mov ecx, [esi+WDATA.box.width]
add edx, ecx
cmp eax, edx
ja .new_check
 
pop esi
.return_yes:
mov ecx,1 ; overlap some window
ret
 
.all_wnds_to_top:
 
pop esi
 
xor ecx, ecx ; passed all windows to top
ret
 
 
 
 
waredraw: ; if redraw necessary at activate
 
pushad
 
call checkwindowdraw ; draw window on activation ?
test ecx, ecx
jz .do_not_draw
 
popad
mov [0xfb44], byte 1 ; do draw mouse
call windowactivate
 
; update screen info
pushad
mov edi, [0x3004] ; the last process (number)
movzx esi, word [0xC400 + edi * 2]
shl esi, 5
add esi, window_data
 
; coordinates of the upper window
mov eax, [esi + WDATA.box.left] ; cx
mov ebx, [esi + WDATA.box.top] ; cy
mov ecx, [esi + WDATA.box.width] ; sx
mov edx, [esi + WDATA.box.height] ; sy
 
add ecx, eax ; ecx = x_end
add edx, ebx ; edx = y_end
 
mov edi, [0x3004]
movzx esi, word [0xC400 + edi * 2]
call setscreen
popad
 
mov [edi + WDATA.fl_redraw], 1 ; redraw flag for app
mov [0xfb44],byte 0 ; mouse down checks
 
ret
 
.do_not_draw:
 
popad
 
call windowactivate
mov [0xfb44],byte 0 ; mouse down checks
mov [0xfff4],byte 0 ; no mouse background
mov [0xfff5],byte 0 ; draw mouse
ret
 
 
; eax = window number on screen
; corrupts registers and [dl*]
minimize_window:
movzx eax, word [0xC400+eax*2]
shl eax, 5
add eax, window_data
test [eax+WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .skip_redrawings
pushfd
cli
or [eax+WDATA.fl_wstate], WSTATE_MINIMIZED
mov edi, eax
;call calculatescreen
mov eax, [edi+WDATA.box.left]
mov [dlx], eax
mov ecx, eax
add ecx, [edi+WDATA.box.width]
mov [dlxe], ecx
mov ebx, [edi+WDATA.box.top]
mov [dly], ebx
mov edx, ebx
add edx, [edi+WDATA.box.height]
mov [dlye], edx
call calculatescreen
xor esi, esi
xor eax, eax
call redrawscreen
popfd
.skip_redrawings:
ret
 
; eax = window number on screen
; corrupts registers and [dl*]
restore_minimized_window:
pushfd
cli
movzx esi, word [0xC400+eax*2]
mov edi, esi
shl edi, 5
add edi, window_data
test [edi+WDATA.fl_wstate], WSTATE_MINIMIZED
jz .skip_redrawings
mov [edi+WDATA.fl_redraw], 1
and [edi+WDATA.fl_wstate], not WSTATE_MINIMIZED
cmp eax, [0x3004] ; the uppermost window
jnz .no_uppermost
mov eax, [edi+WDATA.box.left]
mov ebx, [edi+WDATA.box.top]
mov ecx, eax
mov edx, ebx
add ecx, [edi+WDATA.box.width]
add edx, [edi+WDATA.box.height]
call setscreen
jmp .done
.no_uppermost:
mov eax, [edi+WDATA.box.left]
mov ebx, [edi+WDATA.box.top]
mov ecx, eax
mov edx, ebx
add ecx, [edi+WDATA.box.width]
add edx, [edi+WDATA.box.height]
call calculatescreen
.done:
mov [0xfff4],byte 0 ; no mouse under
.skip_redrawings:
popfd
ret
 
 
iglobal
window_moving db 'K : Window - move/resize',13,10,0
window_moved db 'K : Window - done',13,10,0
endg
 
; check window touch
align 4
checkwindows:
pushad
 
cmp [window_minimize], 0
je .no_minimizing
mov eax, [0x3004] ; the uppermost window
mov bl, 0
xchg [window_minimize], bl
cmp bl, 1
jne .restore
call minimize_window
jmp .continue
.restore:
call restore_minimized_window
.continue:
.no_minimizing:
 
cmp [0xfb40],byte 0 ; mouse buttons pressed ?
jne .mouse_buttons_pressed
popad
ret
.mouse_buttons_pressed:
 
mov esi,[0x3004]
inc esi
 
cwloop:
cmp esi,2
jb .exit
 
dec esi
movzx edi, word [0xC400 + esi * 2] ; ebx
shl edi, 5
add edi, window_data
; mov edi, ebx
mov ecx, [edi + WDATA.box.left]
mov edx, [edi + WDATA.box.top]
 
mov eax,ecx
mov ebx,edx
test [edi+WDATA.fl_wstate],WSTATE_MINIMIZED
jnz cwloop
 
movzx eax, word [0xfb0a]
movzx ebx, word [0xfb0c]
cmp ecx, eax
jae cwloop
cmp edx, ebx
jae cwloop
add ecx, [edi + WDATA.box.width]
add edx, [edi + WDATA.box.height]
cmp eax, ecx
jae cwloop
cmp ebx, edx
jae cwloop
 
pushad
mov eax, esi
mov ebx, [0x3004]
cmp eax, ebx ; is this window active?
jz .move_resize_window
 
; eax = position in windowing stack
; redraw must ?
lea esi, [0xC400 + esi * 2]
call waredraw
add esp, 32
 
.exit:
popad
ret
 
.move_resize_window: ; MOVE OR RESIZE WINDOW
popad
 
; Check for user enabled fixed window
mov edx, [edi + WDATA.cl_titlebar]
and edx, 0x0f000000
cmp edx, 0x01000000
jne .window_move_enabled_for_user
popad
ret
.window_move_enabled_for_user:
 
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP
jnz .no_resize_2
 
mov [do_resize_from_corner],byte 0 ; resize for skinned window
mov edx, [edi + WDATA.cl_workarea]
and edx, 0x0f000000
cmp edx, 0x02000000
jb .no_resize_2 ; not type 2 wnd
 
mov edx, [edi + WDATA.box.top]
add edx, [edi + WDATA.box.height]
sub edx, 6 ; edx = y_end - 6
cmp ebx, edx ; ebx = mouse_y
jb .no_resize_2
mov [do_resize_from_corner],byte 1
jmp .continue
.no_resize_2:
 
push eax
call get_titlebar_height
add eax,[edi + WDATA.box.top]
cmp ebx,eax
pop eax
jae .exit
 
.continue:
 
push esi
mov esi, window_moving
call sys_msg_board_str
pop esi
 
mov ecx, [timer_ticks] ; double-click ?
mov edx, ecx
sub edx, [latest_window_touch]
mov [latest_window_touch], ecx
mov [latest_window_touch_delta], edx
 
mov cl, [0xfb40] ; save for shade check
mov [do_resize], cl
no_emulation_righ_button:
mov ecx, [edi + WDATA.box.left]
mov edx, [edi + WDATA.box.top]
 
push eax ecx edx
mov [dlx], ecx ; save for drawlimits
mov [dly], edx
mov eax, [edi + WDATA.box.width]
add ecx, eax
mov eax, [edi + WDATA.box.height]
add edx, eax
mov [dlxe], ecx
mov [dlye], edx
pop edx ecx eax
 
sub eax, ecx
sub ebx, edx
 
mov esi, [0xfb0a]
mov [0xf300], esi
 
pushad ; wait for putimages to finish
; mov eax,5
; call delay_hs
mov eax,[edi + WDATA.box.left]
mov [npx],eax
mov eax,[edi + WDATA.box.top]
mov [npy],eax
popad
 
push eax ; save old coordinates
mov ax, word [edi + WDATA.box.left]
mov word [oldc+BOX.left],ax
mov ax, word [edi + WDATA.box.top]
mov word [oldc+BOX.top],ax
mov ax, word [edi + WDATA.box.width]
mov word [oldc+BOX.width],ax
mov word [npxe],ax
mov ax, word [edi + WDATA.box.height]
mov word [oldc+BOX.height],ax
mov word [npye],ax
pop eax
 
call drawwindowframes
 
mov [reposition],0
mov [0xfb44],byte 1 ; no reaction to mouse up/down
 
; move window
 
newchm:
 
mov [0xfff5],byte 1
 
call checkidle
 
call checkVga_N13
 
mov [0xfff4],byte 0
 
call [draw_pointer]
 
pushad
call stack_handler
popad
 
mov esi,[0xf300]
cmp esi,[0xfb0a]
je cwb
 
mov cx,[0xfb0a]
mov dx,[0xfb0c]
sub cx,ax
sub dx,bx
 
push ax
push bx
 
call drawwindowframes
 
mov ax,[0xfe00]
mov bx,[0xfe04]
 
cmp [do_resize_from_corner],1
je no_new_position
 
mov word [npx],word 0 ; x repos ?
cmp ax,cx
jb noreposx
mov [reposition],1
sub ax,word [npxe]
mov word [npx],ax
cmp ax,cx
jb noreposx
mov word [npx],cx
noreposx:
 
mov word [npy],word 0 ; y repos ?
cmp bx,dx
jb noreposy
mov [reposition],1
sub bx,word [npye]
mov word [npy],bx
cmp bx,dx
jb noreposy
mov word [npy],dx
noreposy:
 
no_new_position:
 
cmp [do_resize_from_corner],0 ; resize from right corner
je norepos_size
pushad
 
mov edx,edi
sub edx,window_data
;shr edx,5
;shl edx,8
;add edx,0x80000 ; process base at 0x80000+
lea edx, [0x80000 + edx*8]
 
movzx eax,word [0xfb0a]
cmp eax,[edi + WDATA.box.left]
jb nnepx
sub eax,[edi + WDATA.box.left]
cmp eax,32 ; [edx+0x90+8]
jge nnepx2
mov eax,32 ; [edx+0x90+8]
nnepx2:
mov [npxe],eax
nnepx:
 
call get_rolledup_height
mov ebx,eax
movzx eax,word [0xfb0c]
cmp eax,[edi + WDATA.box.top]
jb nnepy
sub eax,[edi + WDATA.box.top]
cmp eax,ebx ; [edx+0x90+12]
jge nnepy2
mov eax,ebx ; [edx+0x90+12]
nnepy2:
mov [npye],eax
nnepy:
 
mov [reposition],1
 
popad
norepos_size:
 
pop bx
pop ax
call drawwindowframes
 
mov esi,[0xfb0a]
mov [0xf300],esi
 
cwb:
cmp [0xfb40],byte 0
jne newchm
; new position done
mov [0xfff5],byte 1
mov cl,0
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED
jnz @f
mov cl,[reposition]
call drawwindowframes
 
mov eax,[npx]
mov [edi + WDATA.box.left],eax
mov eax,[npy]
mov [edi + WDATA.box.top],eax
mov eax,[npxe]
mov [edi + WDATA.box.width],eax
mov eax,[npye]
mov [edi + WDATA.box.height],eax
call set_window_clientbox
 
@@: mov [reposition],cl
 
cmp [reposition],1 ; save new position and size
jne no_bounds_save
push esi edi ecx
mov esi,edi
mov ecx,2
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP or WSTATE_MAXIMIZED
jnz @f
add ecx,2
@@: sub edi,window_data
shr edi,5
shl edi,8
add edi,0x80000+APPDATA.saved_box
cld
rep movsd
pop ecx edi esi
no_bounds_save:
 
pushad ; WINDOW SHADE/FULLSCREEN
 
cmp [reposition],1
je no_window_sizing
mov edx,edi
sub edx,window_data
shr edx,5
shl edx,8
add edx,0x80000 ; process base at 0x80000+
 
cmp [do_resize],2 ; window shade ?
jne no_window_shade
mov [reposition],1
 
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP
jnz wnd_rolldown
wnd_rollup:
or [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP
call get_rolledup_height
jmp @f
wnd_rolldown:
and [edi+WDATA.fl_wstate],not WSTATE_ROLLEDUP
mov eax,[edx + APPDATA.saved_box.height] ; 0x90+BOX.height
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED
jz @f
mov eax,[screen_workarea.bottom]
sub eax,[screen_workarea.top]
@@: mov [edi+WDATA.box.height],eax
call set_window_clientbox
 
no_window_shade:
 
cmp [do_resize],1 ; fullscreen/restore ?
jne no_fullscreen_restore
cmp [latest_window_touch_delta],dword 50
jg no_fullscreen_restore
mov [reposition],1
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED
jnz restore_from_fullscreen
or [edi+WDATA.fl_wstate],WSTATE_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 @f
sub eax,[screen_workarea.bottom]
neg eax
mov [edi+WDATA.box.height],eax
@@:
jmp restore_from_fullscreen.clientbox
restore_from_fullscreen:
and [edi+WDATA.fl_wstate],not WSTATE_MAXIMIZED
push [edi+WDATA.box.height]
push edi ; restore
lea esi, [edx + APPDATA.saved_box]
mov ecx,4
cld
rep movsd
pop edi
pop eax
test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP
jz @f
mov [edi+WDATA.box.height],eax
@@:
.clientbox:
call set_window_clientbox
 
no_fullscreen_restore:
 
mov eax,[edi+WDATA.box.top] ; check Y inside screen
add eax,[edi+WDATA.box.height]
cmp eax,[0xfe04]
jbe no_window_sizing
mov eax,[edi+WDATA.box.left] ; check X inside screen
add eax,[edi+WDATA.box.width]
cmp eax,[0xfe00]
jbe no_window_sizing
mov eax,[0xfe00]
sub eax,[edi+WDATA.box.width]
mov [edi+WDATA.box.left],eax
mov eax,[0xfe04]
sub eax,[edi+WDATA.box.height]
mov [edi+WDATA.box.top],eax
call set_window_clientbox
no_window_sizing:
 
popad
 
cmp [reposition],0
je retwm
 
mov [0xfff5],byte 1 ; no mouse
 
 
push eax ebx ecx edx
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 eax,[oldc+BOX.left]
mov ebx,[oldc+BOX.top]
mov ecx,[oldc+BOX.width]
mov edx,[oldc+BOX.height]
add ecx,eax
add edx,ebx
call calculatescreen
pop edx ecx ebx eax
 
mov eax,edi
call redrawscreen
 
 
mov [edi+WDATA.fl_redraw],1
 
mov ecx,100 ; wait to avoid mouse residuals
waitre2:
mov [0xfff5],byte 1
call checkidle
cmp [edi+WDATA.fl_redraw],0
jz retwm
loop waitre2
 
retwm:
 
mov [0xfff5],byte 0 ; mouse pointer
mov [0xfff4],byte 0 ; no mouse under
mov [0xfb44],byte 0 ; react to mouse up/down
 
mov esi,window_moved
call sys_msg_board_str
 
popad
 
ret
 
 
uglobal
add_window_data dd 0
do_resize_from_corner db 0x0
reposition db 0x0
latest_window_touch dd 0x0
latest_window_touch_delta dd 0x0
 
do_resize db 0x0
 
oldc dd 0x0,0x0,0x0,0x0
 
dlx dd 0x0
dly dd 0x0
dlxe dd 0x0
dlye dd 0x0
 
npx dd 0x0
npy dd 0x0
npxe dd 0x0
npye dd 0x0
 
mpx dd 0x0
mpy dd 0x0
endg
 
 
; draw negative window frames
drawwindowframes2:
pushad
cli
jmp drawwindowframes.do
drawwindowframes:
pushad
cli
 
test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED
jnz .ret
mov eax, [npx]
cmp eax, [edi+WDATA.box.left]
jnz .nowndframe
mov eax, [npxe]
cmp eax, [edi+WDATA.box.width]
jnz .nowndframe
mov eax, [npy]
cmp eax, [edi+WDATA.box.top]
jnz .nowndframe
mov eax, [npye]
cmp eax, [edi+WDATA.box.height]
jnz .nowndframe
xor [edi+WDATA.fl_wdrawn], 2
test [edi+WDATA.fl_wdrawn], 4
jnz .ret
 
.nowndframe:
.do:
mov edi, 1
mov ecx, 0x01000000
mov eax,[npx]
shl eax,16
add eax,[npx]
add eax,[npxe]
add eax,65536*1-1
mov ebx,[npy]
shl ebx,16
add ebx,[npy]
call [draw_line]
 
mov eax,[npx]
shl eax,16
add eax,[npx]
add eax,[npxe]
add eax,65536*1-1
mov ebx,[npy]
add ebx,[npye]
shl ebx,16
add ebx,[npy]
add ebx,[npye]
call [draw_line]
 
mov eax,[npx]
shl eax,16
add eax,[npx]
mov ebx,[npy]
shl ebx,16
add ebx,[npy]
add ebx,[npye]
call [draw_line]
 
mov eax,[npx]
add eax,[npxe]
shl eax,16
add eax,[npx]
add eax,[npxe]
mov ebx,[npy]
shl ebx,16
add ebx,[npy]
add ebx,[npye]
call [draw_line]
 
.ret:
sti
popad
ret
 
 
 
random_shaped_window:
 
;
; eax = 0 giving address of data area
; ebx address
; eax = 1 shape area scale
; ebx 2^ebx scale
 
test eax, eax
jne rsw_no_address
mov eax,[0x3000]
shl eax,8
 
mov [eax+0x80000+APPDATA.wnd_shape],ebx
rsw_no_address:
 
cmp eax,1
jne rsw_no_scale
mov eax,[0x3000]
shl eax,8
mov byte [eax+0x80000+APPDATA.wnd_shape_scale], bl
rsw_no_scale:
 
ret
 
 
/kernel/tags/kolibri0.6.3.0/gui/font.inc
0,0 → 1,107
align 4
dtext: ; Text String Output (rw by Johnny_B[john@kolibrios.org])
; eax x & y
; ebx style ( 0xX0000000 ) & color ( 0x00RRGGBB )
; X = ABnnb:
; nn = font
; A = 0 <=> output edx characters; otherwise output ASCIIZ string
; B = 1 <=> fill background with color esi
; ecx start of text
; edi 1 force
 
pushad
call [disable_mouse]
 
mov ebp, ecx ; ebp=pointer to text
mov ecx, ebx ; ecx=color
movsx ebx, ax ; ebx=y
sar eax, 16 ; eax=x
cmp edx, 255
jb .loop
mov edx, 255
.loop:
test ecx, ecx
js .test_asciiz
dec edx
js .end
jmp @f
.test_asciiz:
cmp byte [ebp], 0
jz .end
@@:
push edx
movzx edx, byte [ebp]
inc ebp
test ecx, 0x10000000
jnz .font2
pushad
mov esi, 9
lea ebp, [0x3F600+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+4]
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
pop edx
jmp .loop
.font2:
pushad
add edx, edx
lea ebp, [0x3EC00+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+4]
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
pop edx
jmp .loop
.end:
popad
ret
/kernel/tags/kolibri0.6.3.0/gui/button.inc
0,0 → 1,648
max_buttons=4095
dececx:
push edx
push ecx
 
mov edx,2
.loop:
 
cmp byte [esp+edx],0x20
jae @f
mov [esp+edx],byte 0x20
@@:
sub [esp+edx],byte 0x20
 
dec edx
jns .loop
 
pop ecx
pop edx
ret
incecx:
push edx
push ecx
mov edx,2
.loop:
cmp byte [esp+edx],0xdf
jbe @f
mov [esp+edx],byte 0xdf
@@:
add [esp+edx],byte 0x20
dec edx
jns .loop
pop ecx
pop edx
ret
incecx2:
push edx
push ecx
mov edx,2
.loop:
cmp byte [esp+edx],0xeb
jbe @f
mov [esp+edx],byte 0xeb
@@:
add [esp+edx],byte 0x14
dec edx
jns .loop
pop ecx
pop edx
ret
 
drawbuttonframes:
 
push esi
push edi
push eax
push ebx
push ecx
push edx
 
shr eax,16
shr ebx,16
mov edx,[0x3010]
 
add eax,[edx-twdw + WDATA.box.left]
add ebx,[edx-twdw + WDATA.box.top]
mov cx,ax
mov dx,bx
shl eax,16
shl ebx,16
mov ax,cx
mov bx,dx
add ax,word [esp+12]
mov esi,ebx
mov edi,0
mov ecx,[esp+0]
call incecx
call [draw_line]
 
movzx edx,word [esp+8]
add ebx,edx
shl edx,16
add ebx,edx
mov ecx,[esp+0]
call dececx
call [draw_line]
 
mov ebx,esi
push edx
mov edx,eax
shr edx,16
mov ax,dx
mov edx,ebx
shr edx,16
mov bx,dx
mov dx,[esp+8+4]
add bx,dx
pop edx
mov edi,0
mov ecx,[esp+0]
call incecx
call [draw_line]
 
mov esi,edx
mov dx,[esp+12]
add ax,dx
shl edx,16
add eax,edx
add ebx,1*65536
mov edx,esi
mov ecx,[esp+0]
call dececx
call [draw_line]
 
pop edx
pop ecx
pop ebx
pop eax
pop edi
pop esi
 
ret
 
button_dececx:
 
cmp [buttontype],dword 1
jne .finish
; je bdece
; ret
; bdece:
push eax
mov eax,0x01
cmp edi,20
jg @f
mov eax,0x02
@@:
test ecx,0xff
jz @f
sub ecx,eax
@@:
shl eax,8
test ecx,0xff00
jz @f
sub ecx,eax
@@:
shl eax,8
test ecx,0xff0000
jz @f
sub ecx,eax
@@:
pop eax
.finish:
ret
 
 
sys_button:
 
push edi
mov edi,[0x3000]
shl edi,8
rol eax,16
add ax,word[edi+0x80000+APPDATA.wnd_clientbox.left]
rol eax,16
rol ebx,16
add bx,word[edi+0x80000+APPDATA.wnd_clientbox.top]
rol ebx,16
pop edi
.forced:
 
test ecx,0x80000000
jnz remove_button
 
push esi
push edi
push eax ; <x,xs>
push ebx ; <y,ys>
push ecx ; <id>
push edx
 
or ax,ax
jle noaddbutt
or bx,bx
jle noaddbutt
 
test ecx,0x40000000
jnz button_no_draw
 
pushad ; button body
push ebx
shr eax,16
shr ebx,16
mov edx,[0x3010]
mov esi,[edx-twdw + WDATA.box.left]
mov edi,[edx-twdw + WDATA.box.top]
add eax,esi
add ebx,edi
mov cx,ax
mov dx,bx
shl eax,16
shl ebx,16
mov ax,cx
mov bx,dx
movzx ecx,word [4+32+esp+12]
add eax,ecx
mov ecx,[4+32+esp+0]
cmp [buttontype],dword 0
je @f
call incecx2
@@:
movzx edi,word [esp]
 
pop edx
and edx, 0xFFFF
 
.newline:
call button_dececx
push edi
xor edi, edi
call [draw_line]
pop edi
add ebx,1*65536+1 ; [ y start | y end ]
dec edx
jnz .newline
popad
 
call drawbuttonframes
 
button_no_draw:
 
and ecx,0xffff
 
mov edi,[0xfe88]
movzx eax,word [edi]
cmp eax,max_buttons
jge noaddbutt
inc eax
mov [edi],ax
 
shl eax,4
add eax,edi
 
mov bx,[0x3000]
mov [eax],bx
 
add eax,2 ; save button id number
mov ebx,[esp+4]
mov [eax],bx ; bits 0-15
shr ebx,16
mov [eax-2+0xc],bx; bits 16-31
add eax,2 ; x start
mov bx,[esp+12+2]
mov [eax],bx
add eax,2 ; x size
mov bx,[esp+12+0]
mov [eax],bx
add eax,2 ; y start
mov bx,[esp+8+2]
mov [eax],bx
add eax,2 ; y size
mov bx,[esp+8+0]
mov [eax],bx
 
noaddbutt:
 
pop edx
pop ecx
pop ebx
pop eax
pop edi
pop esi
 
ret
 
 
remove_button:
 
and ecx,0x7fffffff
 
rnewba2:
 
mov edi,[0xfe88]
mov eax,edi
movzx ebx,word [edi]
inc bx
 
rnewba:
 
dec bx
jz rnmba
 
add eax,0x10
 
mov dx,[0x3000]
cmp dx,[eax]
jnz rnewba
 
cmp cx,[eax+2]
jnz rnewba
 
pushad
mov ecx,ebx
inc ecx
shl ecx,4
mov ebx,eax
add eax,0x10
call memmove
dec dword [edi]
popad
 
jmp rnewba2
 
rnmba:
 
ret
 
find_pressed_button_frames:
 
pushad
 
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
mov ecx, [ebx+ WDATA.box.left] ; window x start
movzx edx,word [eax+4] ; button x start
add ecx,edx
push ecx
 
mov dx,[eax+6] ; button x size
add cx,dx
mov esi,ecx
inc esi
mov ecx, [ebx+WDATA.box.top] ; window y start
mov dx,[eax+8] ; button y start
add ecx,edx
mov ebx,ecx
mov dx,[eax+10] ; button y size
add dx,cx
inc dx
 
pop eax
 
; eax x beginning
; ebx y beginning
; esi x end
; edx y end
; ecx color
 
mov [pressed_button_eax],eax
mov [pressed_button_ebx],ebx
mov [pressed_button_ecx],ecx
mov [pressed_button_edx],edx
mov [pressed_button_esi],esi
 
popad
ret
 
uglobal
pressed_button_eax dd 0
pressed_button_ebx dd 0
pressed_button_ecx dd 0
pressed_button_edx dd 0
pressed_button_esi dd 0
endg
 
; negative button image
 
negativebutton:
; If requested, do not display button
; boarder on press.
test ebx,0x20000000
jz draw_negative_button
ret
draw_negative_button:
 
pushad
 
mov eax,[pressed_button_eax]
mov ebx,[pressed_button_ebx]
mov ecx,[pressed_button_ecx]
mov edx,[pressed_button_edx]
mov esi,[pressed_button_esi]
mov ecx,0x01000000
 
dec edx
push edx
inc edx
dec esi
push esi
inc esi
 
push eax
push ebx
push ecx
push edx
push edi
 
call [disable_mouse]
 
bdbnewline:
mov edi,1 ; force
cmp eax,[esp+16]
jz bneg
cmp eax,[esp+20]
jz bneg
cmp ebx,[esp+12]
jz bneg
cmp ebx,[esp+24]
jnz nbneg
; jz bneg
; jmp nbneg
 
bneg:
 
;;;call [disable_mouse]
call [putpixel]
 
nbneg:
 
inc eax
cmp eax,esi
jnz bdbnewline
mov eax,[esp+16]
inc ebx
cmp ebx,edx
jnz bdbnewline
 
add esp,28
 
popad
 
ret
 
; check buttons
 
 
; 0000 word process number
; 0002 word button id number : bits 0-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
;
; button table in 0x10 increments
;
; first at 0x10
 
 
checkbuttons:
 
cmp [0xfb40],byte 0 ; mouse buttons pressed
jnz @f
ret
@@:
 
pushad
 
xor esi, esi
mov edi, [0xfe88]
movzx edx, word [edi]
test edx, edx
jne @f
popad
ret
 
@@:
 
push esi
inc edx
push edx
 
buttonnewcheck:
 
pop edx
pop esi
inc esi
cmp edx,esi
jge bch
 
popad ; no button pressed
ret
 
bch:
 
push esi
push edx
mov eax,esi
shl eax,4
add eax,edi
 
;......................start 1/2 : modified by vhanla .............................
mov [buttonid],eax
;......................end 1/2 : modified by vhanla .............................
 
; check that button is at top of windowing stack
 
movzx ebx,word [eax]
movzx ecx,word [0xC000 + ebx * 2]
cmp ecx,[0x3004]
jne buttonnewcheck
 
; check that button start is inside window x/y end
 
movzx ebx,word [eax+0]
shl ebx,5
 
test [ebx+window_data+WDATA.fl_wstate],WSTATE_MINIMIZED
jnz buttonnewcheck
 
; add ebx,window_data
; mov ecx,[window_data+ebx+8] ; window end X
movzx edx,word [eax+4] ; button start X
cmp edx, [window_data+ebx+WDATA.box.width] ;ecx
jge buttonnewcheck
 
; mov ecx,[window_data+ebx+12] ; window end Y
movzx edx, word [eax+8] ; button start Y
cmp edx, [window_data+ebx+WDATA.box.height] ;ecx
jge buttonnewcheck
 
; check coordinates
; mouse x >= button x ?
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
mov ecx, [ebx+WDATA.box.left] ; window x start
movzx edx,word [eax+4] ; button x start
add edx,ecx
mov cx,[0xfb0a]
cmp edx,ecx
jg buttonnewcheck
 
movzx ebx,word [eax+6] ; button x size
add edx,ebx
cmp ecx,edx
jg buttonnewcheck
 
; mouse y >= button y ?
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
mov ecx, [ebx+WDATA.box.top] ; window y start
movzx edx,word [eax+8] ; button y start
add edx,ecx
mov cx,[0xfb0c]
cmp edx,ecx
jg buttonnewcheck
 
movzx ebx,word [eax+10] ; button y size
add edx,ebx
cmp ecx,edx
jg buttonnewcheck
 
; mouse on button
 
pop edx
pop esi
 
mov bx,[eax+0xc] ; button id : bits 16-31
shl ebx,16
mov bx,[eax+2] ; button id : bits 00-16
push ebx
 
mov [0xfb44],byte 1 ; no mouse down checks
call find_pressed_button_frames
call negativebutton
 
pushad
cbwaitmouseup:
 
call checkidle
 
call [draw_pointer]
 
pushad
call stack_handler
popad
 
cmp [0xfb40],byte 0 ; mouse buttons pressed ?
jnz cbwaitmouseup
popad
 
call negativebutton
mov [0xfff4],byte 0 ; no mouse background
mov [0xfff5],byte 0 ; draw mouse
;..................................... start 2/2 : modified by vhanla .............................
; check coordinates
jmp afterbuttonid
buttonid dd 0x0 ;here a will backup the eax value
afterbuttonid:
 
pusha
; mouse x >= button x ?
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
mov ecx, [ebx+WDATA.box.left] ; window x start
movzx edx,word [eax+4] ; button x start
add edx,ecx
mov cx,[0xfb0a]
cmp edx,ecx
jg no_on_button ;if we release the pointer out of the button area
 
movzx ebx,word [eax+6] ; button x size
add edx,ebx
cmp ecx,edx
jg no_on_button
 
; mouse y >= button y ?
movzx ebx,word [eax+0]
shl ebx,5
add ebx,window_data
mov ecx, [ebx+WDATA.box.top] ; window y start
movzx edx,word [eax+8] ; button y start
add edx,ecx
mov cx,[0xfb0c]
cmp edx,ecx
jg no_on_button
 
movzx ebx,word [eax+10] ; button y size
add edx,ebx
cmp ecx,edx
jg no_on_button
popa
mov [0xf500],byte 1 ; no of buttons in buffer
pop ebx
mov [0xf501],ebx ; lets put the button id in buffer
push ebx
pusha
jmp yes_on_button
no_on_button:
mov [0xf500],byte 0 ; no of buttons in buffer
yes_on_button:
mov [0xfb44],byte 0 ; mouse down -> do not draw
popa
pop ebx
popa
ret
 
;..................................... end 2/2 : modified by vhanla ................................
/kernel/tags/kolibri0.6.3.0/gui/event.inc
0,0 → 1,215
sys_getevent:
 
call get_event_for_app
mov [esp+36],eax
ret
 
 
align 4
 
sys_wait_event_timeout:
 
mov ebx,[timer_ticks]
add ebx,eax
cmp ebx,[timer_ticks]
jna .swfet2
.swfet1:
call get_event_for_app
test eax,eax
jne .eventoccur_time
call change_task
cmp ebx,[timer_ticks]
jg .swfet1
.swfet2:
xor eax,eax
.eventoccur_time:
mov [esp+36],eax
ret
 
 
align 4
 
sys_waitforevent:
 
call get_event_for_app
test eax,eax
jne eventoccur
newwait:
 
mov eax, [0x3010]
mov [eax+TASKDATA.state], byte 5
call change_task
 
mov eax, [event_sched]
 
eventoccur:
mov [esp+36],eax
ret
 
 
get_event_for_app:
 
pushad
 
mov edi,[0x3010] ; WINDOW REDRAW
test [edi+TASKDATA.event_mask],dword 1
jz no_eventoccur1
;mov edi,[0x3010]
cmp [edi-twdw+WDATA.fl_redraw],byte 0
je no_eventoccur1
popad
mov eax,1
ret
no_eventoccur1:
 
;mov edi,[0x3010] ; KEY IN BUFFER
test [edi+TASKDATA.event_mask],dword 2
jz no_eventoccur2
mov ecx, [0x3000]
movzx edx,word [0xC000+ecx*2]
mov eax, [0x3004]
cmp eax,edx
jne no_eventoccur2x
cmp [0xf400],byte 0
je no_eventoccur2x
eventoccur2:
popad
mov eax,2
ret
no_eventoccur2x:
mov eax, hotkey_buffer
@@:
cmp [eax], ecx
jz eventoccur2
add eax, 8
cmp eax, hotkey_buffer+120*8
jb @b
no_eventoccur2:
 
;mov edi,[0x3010] ; BUTTON IN BUFFER
test [edi+TASKDATA.event_mask],dword 4
jz no_eventoccur3
cmp [0xf500],byte 0
je no_eventoccur3
mov ecx, [0x3000]
movzx edx, word [0xC000+ecx*2]
mov eax, [0x3004]
cmp eax,edx
jnz no_eventoccur3
popad
mov eax,[0xf501]
cmp eax,65535
je no_event_1
mov eax,3
ret
 
no_event_1:
mov [window_minimize],1
mov [0xf500],byte 0
xor eax, eax
ret
 
no_eventoccur3:
;mov edi,[0x3010] ; mouse event
test [edi+TASKDATA.event_mask],dword 00100000b
jz no_mouse_event
mov eax,[0x3000]
shl eax,8
test [eax+0x80000+APPDATA.event_mask],dword 00100000b
jz no_mouse_event
and [eax+0x80000+APPDATA.event_mask],dword 0xffffffff-00100000b
popad
mov eax,6
ret
no_mouse_event:
 
;mov edi,[0x3010] ; DESKTOP BACKGROUND REDRAW
test [edi+TASKDATA.event_mask],dword 16
jz no_eventoccur5
cmp [0xfff0],byte 2
jnz no_eventoccur5
popad
mov eax,5
ret
no_eventoccur5:
 
;mov edi,[0x3010] ; IPC
test [edi+TASKDATA.event_mask],dword 01000000b
jz no_ipc
mov eax,[0x3000]
shl eax,8
test [eax+0x80000+APPDATA.event_mask],dword 01000000b
jz no_ipc
and [eax+0x80000+APPDATA.event_mask],dword 0xffffffff-01000000b
popad
mov eax,7
ret
no_ipc:
 
 
;mov edi,[0x3010] ; STACK
test [edi+TASKDATA.event_mask],dword 10000000b
jz no_stack_event
mov eax,[0x3000]
shl eax,8
test [eax+0x80000+APPDATA.event_mask],dword 10000000b
jz no_stack_event
and [eax+0x80000+APPDATA.event_mask],dword 0xffffffff-10000000b
popad
mov eax,8
ret
no_stack_event:
 
test byte [edi+TASKDATA.event_mask+1], 1 ; DEBUG
jz no_debug_event
mov eax, [0x3000]
shl eax, 8
test byte [eax+0x80000+APPDATA.event_mask+1], byte 1
jz no_debug_event
and byte [eax+0x80000+APPDATA.event_mask+1], not 1
popad
mov eax, 9
ret
no_debug_event:
 
cmp dword [edi+TASKDATA.event_mask], 0xFFFF
jbe no_events
 
mov esi,0x2e0000 ; IRQ'S AND DATA
mov ebx,0x00010000
xor ecx, ecx
irq_event_test:
mov edi,[0x3010]
test [edi+TASKDATA.event_mask],ebx
jz no_irq_event
mov edi,ecx
shl edi,2
add edi,irq_owner
mov edx,[edi]
mov eax,[0x3010]
mov eax,[eax+TASKDATA.pid]
cmp edx,eax
jne no_irq_event
cmp [esi],dword 0
jz no_irq_event
mov eax,ecx
add eax,16
mov [esp+28],eax
popad
ret
no_irq_event:
add esi,0x1000
shl ebx,1
inc ecx
cmp ecx,16
jb irq_event_test
 
no_events:
popad
xor eax, eax
ret
 
 
/kernel/tags/kolibri0.6.3.0/gui/skindata.inc
0,0 → 1,56
;
; WINDOW SKIN DATA
;
 
iglobal
_skin_file_default db '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
 
_skin_file rb 256
 
align 4
 
skin_udata.end:
 
endg
/kernel/tags/kolibri0.6.3.0/gui/mouse.inc
0,0 → 1,243
;mouseunder:
; times 16*24 dd 0
label mouseunder dword at 0x6900
 
iglobal
 
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
/kernel/tags/kolibri0.6.3.0/unpacker.inc
0,0 → 1,504
; 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 eax
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, [.p + .IsMatch*4 + eax + edx*4]
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, .p+.Literal*4
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, [.p + .IsRep*4 + ebx*4]
call .RangeDecoderBitDecode
jnc .10
lea eax, [.p + .IsRepG0*4 + ebx*4]
call .RangeDecoderBitDecode
jc .111
mov eax, ebx
shl eax, .kNumPosBitsMax+2
lea eax, [.p + .IsRep0Long*4 + eax + edx*4]
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, [.p + .IsRepG1*4 + ebx*4]
call .RangeDecoderBitDecode
mov eax, [.rep1]
jnc .l3
.l1:
lea eax, [.p + .IsRepG2*4 + ebx*4]
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, .p + .RepLencoder*4
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, .p + .Lencoder*4
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, .p+.PosSlot*4
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, .p + (.SpecPos - 1)*4
call .RangeDecoderReverseBitTreeDecode
add [.rep0], ecx
jmp .l6
.l5:
sub ecx, .kNumAlignBits
call .RangeDecoderDecodeDirectBits
mov ecx, .kNumAlignBits
shl eax, cl
add [.rep0], eax
mov eax, .p+.Align_*4
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.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:executable
+*
\ No newline at end of property
/kernel/tags/kolibri0.6.3.0/kernel32.inc
0,0 → 1,296
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; 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 8
d = 48 + s shr ((8-%) shl 2) and $0F
if d > 57
d = d + 65-57-1
end if
display d
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]
 
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 RECT {
.left dd ?
.top dd ?
.right dd ?
.bottom dd ?
}
virtual at 0
RECT RECT
end virtual
 
struc BOX {
.left dd ?
.top dd ?
.width dd ?
.height dd ?
}
virtual at 0
BOX BOX
end virtual
 
; 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
 
; 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 ?
}
virtual at 0
WDATA WDATA
end virtual
label WDATA.fl_wstyle byte at 0x13
 
struc APPDATA
{
.app_name db 11 dup(?)
db 5 dup(?)
 
.fpu_state dd ? ;+16
.fpu_init dd ? ;+20
.fpu_handler dd ? ;+24
.sse_handler dd ? ;+28
.event dd ? ;+32
.heap_base dd ? ;+36
.heap_top dd ? ;+40
 
db 84 dup(?) ;+44
 
.wnd_shape dd ? ;+128
.wnd_shape_scale dd ?
dd ?
.mem_size dd ?
.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 ]
 
 
; 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/memory.inc"
include "core/heap.inc"
include "core/taskman.inc"
include "core/dll.inc"
include "core/exports.inc"
include "core/except.inc"
 
 
; GUI stuff
include "gui/window.inc"
include "gui/event.inc"
include "gui/font.inc"
include "gui/button.inc"
 
; shutdown
 
include "boot/shutdown.inc" ; shutdown or restart
 
; file system
 
include "fs/fs.inc" ; syscall
include "fs/fat32.inc" ; read / write for fat32 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
 
; sound
 
include "sound/sb16.inc" ; playback for Sound Blaster 16
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
 
; Network Interface & TCPIP Stack
 
include "network/stack.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"
 
; 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
/kernel/tags/kolibri0.6.3.0/blkdev/rd.inc
0,0 → 1,2404
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; RAMDISK functions ;;
;; (C) 2004 Ville Turjanmaa, License: GPL ;;
;; Addings by M.Lisovin ;;
;; LFN support by diamond ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; calculate fat chain
 
calculatefatchain:
 
pushad
 
mov esi,0x100000+512
mov edi,0x280000
 
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,0x280000+2856*2 ;2849 clusters
jnz fcnew
 
popad
ret
 
 
restorefatchain: ; restore fat chain
 
pushad
 
mov esi,0x280000
mov edi,0x100000+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,0x100000+512+4278 ;4274 bytes - all used FAT
jb fcnew2
 
mov esi,0x100000+512 ; duplicate fat chain
mov edi,0x100000+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,0x280000 ;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,0x100000+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,0x100000 ;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+0x280000] ; 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
 
filedelete:
;--------------------------------------------
;
; filedelete - sys floppy
; in:
; eax - pointer to filename 11 chars
;
; out:
; eax - 0 = successful, 5 = file not found
;
;--------------------------------------------
 
sub esp,32
call expand_filename
 
push eax ebx ecx edx esi edi
call rd_findfile
je fifoundd
pop edi esi edx ecx ebx eax ;file not found
add esp,32
mov eax,5
ret
 
fifoundd:
 
mov [edi-11],byte 0xE5 ;mark filename deleted
add edi,0xf
movzx eax,word [edi]
mov edi,eax ;edi = cluster
 
frnewd:
 
shl edi,1 ;find next cluster from FAT
add edi,0x280000
movzx eax,word [edi]
mov [edi],word 0x0 ;clear fat chain cluster
mov edi,eax
cmp edi,dword 0xff8 ;last cluster ?
jb frnewd
 
pop edi esi edx ecx ebx eax
add esp,32
xor eax,eax ; file found
ret
 
 
filesave:
;----------------------------------------------------------
;
; filesave - sys floppy
;
; eax points to filename 11 chars
;
; eax ; pointer to file name
; ebx ; buffer
; ecx ; count to write in bytes
; edx ; 0 create new , 1 append
;
;-----------------------------------------------------------
 
sub esp,32
call expand_filename
test edx,edx
jnz fsdel
pusha
call filedelete
popa
 
fsdel:
 
call ramdisk_free_space
cmp ecx,edi
jbe rd_do_save
add esp,32
mov eax,8 ;disk full
ret
 
rd_do_save:
 
push eax ebx ecx edx esi edi
 
mov edi,0x100000+512*18+512 ;Point at directory
mov edx,224 +1
; find an empty spot for filename in the root dir
l20ds:
dec edx
jz frnoreadds
l21ds:
cmp [edi],byte 0xE5
jz fifoundds
cmp [edi],byte 0x0
jz fifoundds
add edi,32 ; Advance to next entry
jmp l20ds
fifoundds:
 
push edi ; move the filename to root dir
mov esi,[esp+4+20]
mov ecx,11
cld
rep movsb
pop edi
mov edx,edi
add edx,11+0xf ; edx <- cluster save position
mov ebx,[esp+12] ; save file size
mov [edi+28],ebx
mov [edi+11],byte 0x20 ; attribute
; Ivan Poddubny 11/12/2003:
call get_date_for_file ; from FAT32.INC
mov [edi+24],ax ; date
call get_time_for_file ; from FAT32.INC
mov [edi+22],ax ; time
; End
mov edi,0x280000 ;pointer to first cluster
mov ecx,2849
cld
frnewds:
xor ax,ax
repne scasw
mov ebx,2848
sub ebx,ecx
mov [edx],bx ; save next cluster pos. to prev cl.
mov edx,edi ; next save pos abs mem add
dec edx
dec edx
call fdc_filesave
pusha ; move save to floppy cluster
add ebx,31
shl ebx,9
add ebx,0x100000
mov eax,[esp+32+16]
mov ecx,512
call memmove
popa
 
mov eax,[esp+12]
cmp eax,512
jbe flnsa
sub eax,512
mov [esp+12],eax
add dword [esp+16], 512
jmp frnewds
 
flnsa:
mov [edi-2],word 4095 ; mark end of file - last cluster
 
frnoreadds:
 
pop edi esi edx ecx ebx eax
add esp,32
 
; pusha
; cli
; call fdc_commitfile
; sti
; popa
 
xor eax,eax ;ok write
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,0x100000+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,0x100000+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, ' '
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
 
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
push ecx
mov ecx, 8
push edi ebp ecx
test byte [ebp-4], 1
jnz .unicode_short
@@:
mov al, [edi]
inc edi
mov [ebp], al
inc ebp
loop @b
pop ecx
@@:
cmp byte [ebp-1], ' '
jnz @f
dec ebp
loop @b
@@:
mov byte [ebp], '.'
inc ebp
mov ecx, 3
push ecx
@@:
mov al, [edi]
inc edi
mov [ebp], al
inc ebp
loop @b
pop ecx
@@:
cmp byte [ebp-1], ' '
jnz @f
dec ebp
loop @b
dec ebp
@@:
and byte [ebp], 0 ; CF=0
pop ebp edi ecx
ret
.unicode_short:
@@:
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, 0x100000+512*19
clc
ret
ramdisk_root_next:
add edi, 0x20
cmp edi, 0x100000+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+0x280000]
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)+0x100000]
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, 0x280000
mov ecx, 2849
repnz scasw
jnz .notfound
mov word [edi-2], 0xFFF
sub edi, 0x280000
shr edi, 1
dec edi
mov eax, [esp+28]
mov ecx, [eax]
mov [0x280000+ecx*2], di
mov [eax], edi
shl edi, 9
add edi, (31 shl 9)+0x100000
mov [esp], edi
xor eax, eax
mov ecx, 128
rep stosd
popa
clc
ret
.notfound:
popa
stc
ret
 
rd_find_lfn:
; in: esi->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
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
jmp .loop
.notfound:
add esp, 12
pop edi esi
stc
ret
.found:
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, 0x100000 ; 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+0x280000] ; 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, 0x100000
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+0x280000]
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, 0x100000
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+0x280000]
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 ; CF already cleared
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]
.succ:
pop edi
popad
clc
ret
.break:
jecxz .noplace
inc edi
mov al, '1'
@@:
xchg al, [edi]
inc edi
cmp al, ' '
mov al, '0'
jnz @b
jmp .succ
.noplace:
dec edi
cmp edi, [esp]
jz .err
add dword [esp], 8
mov word [edi], '~1'
inc edi
inc edi
@@:
mov byte [edi], '0'
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 edi, ecx
jbe .skip
@@:
dec edi
mov al, ' '
xchg al, [edi]
dec ebx
mov [ebx], al
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 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
 
fs_RamdiskRewrite:
cmp byte [esi], 0
jz @b
pushad
xor ebp, ebp
push esi
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
lea ebp, [esi-1]
jmp @b
@@:
pop esi
test ebp, ebp
jnz .noroot
push ramdisk_root_extend_dir
push ramdisk_root_next_write
push ebp
push ramdisk_root_first
push ramdisk_root_next
jmp .common1
.noroot:
; check existence
mov byte [ebp], 0
call rd_find_lfn
mov byte [ebp], '/'
lea esi, [ebp+1]
jnc @f
mov eax, ERROR_FILE_NOT_FOUND
.ret1:
mov [esp+28], eax
popad
xor ebx, ebx
ret
@@:
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; must not be directory
test byte [edi+11], 10h
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, [0x280000 + 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
.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, 0x280000
.write_loop:
; allocate new cluster
xor eax, eax
repnz scasw
jnz .disk_full2
dec edi
dec edi
lea eax, [edi-0x280000]
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
shl eax, 9
add eax, 0x100000+31*512
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
 
.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, 0x100000+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+0x280000]
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+0x280000]
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+0x280000]
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+0x100000+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, 0x280000+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, 0x280000
shr edi, 1
dec edi ; now edi=new cluster
test eax, eax
jz .first_cluster
mov [0x280000+eax*2], di
jmp @f
.first_cluster:
pop eax ; eax->direntry
push eax
mov [eax+26], di
@@:
push edi
shl edi, 9
add edi, 0x100000+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 [0x280000+ecx*2]
jmp @b
@@:
; zero data at the end of last sector
push ecx
mov edi, ecx
shl edi, 9
lea edi, [edi+0x100000+31*512+eax+0x200]
mov ecx, eax
neg ecx
xor eax, eax
rep stosb
pop ecx
; terminate FAT chain
lea ecx, [0x280000+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, [0x280000+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_RamdiskExecute - LFN variant for executing on sys floppy
;
; esi points to ramdisk filename (e.g. 'launcher')
; ebp points to full filename (e.g. '/rd/1/launcher')
; dword [ebx] = flags
; dword [ebx+4] = cmdline
;
; ret ebx,edx destroyed
; eax > 0 - PID, < 0 - error
;
;--------------------------------------------------------------
fs_RamdiskExecute:
mov edx, [ebx]
mov ebx, [ebx+4]
test ebx, ebx
jz @f
add ebx, std_application_base_address
@@:
 
;----------------------------------------------------------------
;
; fs_RamdiskExecute.flags - second entry
;
; esi points to ramdisk filename (kernel address)
; ebp points to full filename
; edx flags
; ebx cmdline (kernel address)
;
; ret eax > 0 - PID, < 0 - error
;
;--------------------------------------------------------------
 
.flags:
cmp byte [esi], 0
jnz @f
; cannot execute root!
mov eax, -ERROR_ACCESS_DENIED
ret
@@:
push edi
call rd_find_lfn
jnc .found
pop edi
mov eax, -ERROR_FILE_NOT_FOUND
ret
.found:
movzx eax, word [edi+26] ; cluster
push eax
push dword [edi+28] ; size
push .DoRead
call fs_execute
add esp, 12
pop edi
ret
 
.DoRead:
; read next block
; in: eax->parameters, edi->buffer
; out: eax = error code
pushad
cmp dword [eax], 0 ; file size
jz .eof
mov edx, [eax+4] ; cluster
lea esi, [edx+31]
shl esi, 9
add esi, 0x100000
mov ecx, 512/4
rep movsd
mov ecx, [eax]
sub ecx, 512
jae @f
add edi, ecx
neg ecx
push eax
xor eax, eax
rep stosb
pop eax
@@:
mov [eax], ecx
mov dx, [edx*2+0x280000]
mov [eax+4], dx ; high word is already zero
popad
xor eax, eax
ret
.eof:
popad
mov eax, 6
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}
/kernel/tags/kolibri0.6.3.0/blkdev/hd_drv.inc
0,0 → 1,858
; Low-level driver for HDD access
; DMA support by Mario79
 
;**************************************************************************
;
; 0x600008 - 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 )
;
; +65536 - cache entries
;
;**************************************************************************
 
align 4
hd_read:
;-----------------------------------------------------------
; input : eax = block to read
; ebx = destination
;-----------------------------------------------------------
push ecx esi edi ; scan cache
 
mov ecx,cache_max ; entries in cache
mov esi,0x600000+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
cmp [dma_hdd], 1
jnz .nodma
call hd_read_dma
jmp @f
.nodma:
call hd_read_pio
@@:
 
lea esi,[edi*8+0x600000]
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,0x600000+65536
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 disable_ide_int
 
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,0x600000+65536
mov ecx,256
mov edx,[hdbase]
cld
rep insw
pop edi
; sti
 
call enable_ide_int
 
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,0x600000+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+0x600000]
mov [esi],eax ; sector number
 
yes_in_cache_write:
 
mov dword [esi+4],2 ; write - differs from hd
 
shl edi,9
add edi,0x600000+65536
mov esi,ebx
mov ecx,512/4
cld
rep movsd ; move data
hd_write_access_denied:
pop edi esi ecx
ret
 
 
write_cache:
;-----------------------------------------------------------
; write all changed sectors to disk
;-----------------------------------------------------------
push eax ecx edx esi edi
 
; write difference ( 2 ) from cache to hd
 
mov ecx,cache_max
mov esi,0x600000+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 [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], 64
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
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,0x600000+65536 ; esi = from memory position
mov ecx,256
mov edx,[hdbase]
cld
rep outsw
; sti
 
call enable_ide_int
pop esi ecx
 
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:
 
mov ecx,cache_max*10/100
mov edi,[cache_search_start]
 
search_for_empty:
 
inc edi
cmp edi,cache_max
jbe inside_cache
mov edi,1
 
inside_cache:
 
cmp dword [edi*8+0x600000+4],2 ; get cache slot info
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:
 
mov [cache_search_start],edi
found_slot_access_denied:
ret
 
align 4
clear_hd_cache:
 
push eax ecx edi
mov edi,0x600000
mov ecx,16384
xor eax,eax
cld
rep stosd ; clear hd cache with 0
mov [cache_search_start],eax
mov [fat_in_cache],-1
mov [fat_change],0
pop edi ecx eax
ret
 
save_hd_wait_timeout:
 
push eax
mov eax,[timer_ticks];[0xfdf0]
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 ;[0xfdf0],eax
jg hd_timeout_error
pop eax
mov [hd_error],0
ret
 
iglobal
hd_timeout_str db 'K : FS - HD timeout',13,10,0
hd_read_str db 'K : FS - HD read error',13,10,0
hd_write_str db 'K : FS - HD write error',13,10,0
hd_lba_str db 'K : FS - HD LBA error',13,10,0
endg
 
hd_timeout_error:
 
call clear_hd_cache
call clear_application_table_status
mov esi,hd_timeout_str
call sys_msg_board_str
; jmp $
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
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
ret
 
hd_write_error_dma:
call clear_hd_cache
call clear_application_table_status
mov esi, hd_write_str
call sys_msg_board_str
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
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 284000h
dw 2000h
dw 8000h
 
dma_cur_sector dd not 40h
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
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 [0x3000], ebx
jz .noswitch
mov [dma_task_switched], 1
mov edi, [dma_slot_ptr]
mov eax, [0x3000]
mov [dma_process], eax
mov eax, [0x3010]
mov [dma_slot_ptr], eax
mov [0x3000], ebx
mov [0x3010], edi
mov byte [0xFFFF], 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 [0x3000], ebx
jz .noswitch
mov [dma_task_switched], 1
mov edi, [dma_slot_ptr]
mov eax, [0x3000]
mov [dma_process], eax
mov eax, [0x3010]
mov [dma_slot_ptr], eax
mov [0x3000], ebx
mov [0x3010], edi
mov byte [0xFFFF], 1
call do_change_task
.noswitch:
popad
popfd
ret
 
align 4
hd_read_dma:
push eax
push edx
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, 0x284000
push ecx esi edi
mov esi, eax
shl edi, 9
add edi, 0x610000
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], 0x284000
mov word [eax+4], 0x2000
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, [0x3000]
mov [dma_process], eax
mov eax, [0x3010]
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
pop edx
pop eax
mov [dma_cur_sector], eax
jmp hd_read_dma
 
align 4
write_cache_chain:
push esi
mov eax, IDE_descriptor_table
mov edx, [cache_chain_pos]
shl edx, 9
add edx, 0x610000
mov [eax], edx
movzx edx, [cache_chain_size]
shl edx, 9
mov [eax+4], dx
jmp do_write_dma
write_cache_sector:
push esi
mov eax, IDE_descriptor_table
mov edx, edi
shl edx, 9
add edx, 0x610000
mov [eax], edx
mov word [eax+4], 0x200
do_write_dma:
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, [0x3000]
mov [dma_process], eax
mov eax, [0x3010]
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}
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/kernel/tags/kolibri0.6.3.0/blkdev/cdrom.inc
0,0 → 1,261
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,[0x3010]
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
 
/kernel/tags/kolibri0.6.3.0/blkdev/flp_drv.inc
0,0 → 1,615
;**********************************************************
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ êîíòðîëëåðîì ãèáêîãî äèñêà
;**********************************************************
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
; Àäàïòàöèÿ è äîðàáîòêà Mario79
 
give_back_application_data: ; ïåðåñëàòü ïðèëîæåíèþ
mov edi,[0x3010]
mov edi,[edi+TASKDATA.mem_start]
add edi,ecx
give_back_application_data_1:
mov esi,0xD000 ;FDD_DataBuffer ;0x40000
xor ecx,ecx
mov cx,128
cld
rep movsd
ret
 
take_data_from_application: ; âçÿòü èç ïðèëîæåíèÿ
mov esi,[0x3010]
mov esi,[esi+TASKDATA.mem_start]
add esi,ecx
take_data_from_application_1:
mov edi,0xD000 ;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
 
;*****************************************
;* ÏÐÎÂÅÐÊÀ ÇÀÄÅÐÆÊÈ ÂÛÊËÞ×ÅÍÈß ÌÎÒÎÐÀ *
;*****************************************
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
 
/kernel/tags/kolibri0.6.3.0/blkdev/rdsave.inc
0,0 → 1,25
sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only)
cmp ebx,1
jnz img_save_hd_1
mov edx,bootpath ; path = '/KOLIBRI '
jmp img_save_hd_3
img_save_hd_1:
cmp ebx,2
jnz img_save_hd_2
mov edx,bootpath2 ; path = 0 (root dir)
jmp img_save_hd_3
img_save_hd_2:
cmp ebx,3
jnz exit_for_anyone
mov edx,[0x3010]
mov edx,[edx+TASKDATA.mem_start]
add edx,ecx
img_save_hd_3:
call reserve_hd1
call restorefatchain ; restore FAT !!!
mov eax,image_save
mov ebx,1440*1024 ; size 1440 Kb
mov ecx,0x100000 ; address of image
call file_write
mov [esp+36],eax
ret
/kernel/tags/kolibri0.6.3.0/blkdev/cd_drv.inc
0,0 → 1,546
;**********************************************************
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ óñòðîéñòâîì ÑD (ATAPI)
;**********************************************************
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
; Àäàïòàöèÿ è äîðàáîòêà Mario79
 
; Ïðîöåäóðà äëÿ ïîëíîãî ñ÷èòûâàíèÿ âñåõ
; äàííûõ èç ñåêòîðà êîìïàêò-äèñêà
; Àâòîð òåêñòà ïðîãðàììû Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
 
 
; Ìàêñèìàëüíîå êîëè÷åñòâî ïîâòîðåíèé îïåðàöèè ÷òåíèÿ
MaxRetr equ 3
; Ïðåäåëüíîå âðåìÿ îæèäàíèÿ ãîòîâíîñòè ê ïðèåìó êîìàíäû
; (â òèêàõ)
BSYWaitTime equ 1000 ;2
 
;*************************************************
;* ÏÎËÍÎÅ ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÊÎÌÏÀÊÒ-ÄÈÑÊÀ *
;* Ñ÷èòûâàþòñÿ äàííûå ïîëüçîâàòåëÿ, èíôîðìàöèÿ *
;* ñóáêàíàëà è êîíòðîëüíàÿ èíôîðìàöèÿ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
;* CDSectorAddress - àäðåñ ñ÷èòûâàåìîãî ñåêòîðà. *
;* Äàííûå ñ÷èòûâàåòñÿ â ìàññèâ CDDataBuf. *
;*************************************************
ReadCD:
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
; call test_mario79
popa
ret
 
;********************************************
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ Ñ ÏÎÂÒÎÐÀÌÈ *
;* Ìíîãîêðàòíîå ïîâòîðåíèå ÷òåíèÿ ïðè ñáîÿõ *
;********************************************
ReadCDWRetr:
pusha
; Öèêë, ïîêà êîìàíäà íå âûïîëíåíà óñïåøíî èëè íå
; èñ÷åðïàíî êîëè÷åñòâî ïîïûòîê
mov ECX,MaxRetr
@@NextRetr:
; Ïîäàòü êîìàíäó
call ReadCD
cmp [DevErrorCode],0
je @@End_4
; Çàäåðæêà íà 2,5 ñåêóíäû
mov EAX,[timer_ticks]
add EAX,250 ;50
@@Wait:
call change_task
cmp EAX,[timer_ticks]
ja @@Wait
loop @@NextRetr
; call test_mario79
; Ñîîáùåíèå îá îøèáêå
; mov SI,offset ErrS
; call FatalError
@@End_4:
popa
ret
 
 
; Óíèâåðñàëüíûå ïðîöåäóðû, îáåñïå÷èâàþùèå âûïîëíåíèå
; ïàêåòíûõ êîìàíä â ðåæèìå PIO
;
; Àâòîð òåêñòà ïðîãðàììû Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
 
; Ìàêñèìàëüíî äîïóñòèìîå âðåìÿ îæèäàíèÿ ðåàêöèè
; óñòðîéñòâà íà ïàêåòíóþ êîìàíäó (â òèêàõ)
MaxCDWaitTime equ 1000 ;200 ;10 ñåêóíä
 
; Îáëàñòü ïàìÿòè äëÿ ôîðìèðîâàíèÿ ïàêåòíîé êîìàíäû
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
 
;****************************************************
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, *
;* ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×Ó ÎÄÍÎÃÎ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ *
;* ÐÀÇÌÅÐÎÌ 2048 ÁÀÉÒ ÎÒ ÓÑÒÐÎÉÑÒÂÀ Ê ÕÎÑÒÓ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò; *
;* CDBlockSize - ðàçìåð ïðèíèìàåìîãî áëîêà äàííûõ. *
;****************************************************
SendPacketDatCommand:
pushad
; Çàäàòü ðåæèì CHS
mov [ATAAddressMode],0
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
mov [ATAFeatures],0
mov [ATASectorCount],0
mov [ATASectorNumber],0
; Çàãðóçèòü ðàçìåð ïåðåäàâàåìîãî áëîêà
mov AX,[CDBlockSize]
mov [ATACylinder],AX
mov [ATAHead],0
mov [ATACommand],0A0h
call SendCommandToHDD_1
; call test_mario79
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
jne @@End_8 ;çàêîí÷èòü, ñîõðàíèâ êîä îøèáêè
 
; Îæèäàíèå ãîòîâíîñòè äèñêîâîäà ê ïðèåìó
; ïàêåòíîé êîìàíäû
mov DX,[ATABasePortAddr]
add DX,7 ;ïîðò 1õ7h
@@WaitDevice0:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,BSYWaitTime
ja @@Err1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitDevice0
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Err6
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitDevice0
; Ïîñëàòü ïàêåòíóþ êîìàíäó
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
@@WaitDevice1:
call change_task
; Ïðîâåðèòü âðåìÿ âûïîëíåíèÿ êîìàíäû
mov EAX,[timer_ticks]
sub EAX,[TickCounter_1]
cmp EAX,MaxCDWaitTime
ja @@Err1_1 ;îøèáêà òàéì-àóòà
; Ïðîâåðèòü ãîòîâíîñòü
in AL,DX
test AL,80h ;ñîñòîÿíèå ñèãíàëà BSY
jnz @@WaitDevice1
test AL,1 ;ñîñòîÿíèå ñèãíàëà ERR
jnz @@Err6_temp
test AL,08h ;ñîñòîÿíèå ñèãíàëà DRQ
jz @@WaitDevice1
cli
; Ïðèíÿòü áëîê äàííûõ îò êîíòðîëëåðà
mov EDI,[CDDataBuf_pointer] ;0x7000 ;CDDataBuf
; Çàãðóçèòü àäðåñ ðåãèñòðà äàííûõ êîíòðîëëåðà
mov DX,[ATABasePortAddr] ;ïîðò 1x0h
; Çàãðóçèòü â ñ÷åò÷èê ðàçìåð áëîêà â áàéòàõ
mov CX,[CDBlockSize]
; Âû÷èñëèòü ðàçìåð áëîêà â 16-ðàçðÿäíûõ ñëîâàõ
shr CX,1 ;ðàçäåëèòü ðàçìåð áëîêà íà 2
; Ïðèíÿòü áëîê äàííûõ
cld
rep insw
sti
; Óñïåøíîå çàâåðøåíèå ïðèåìà äàííûõ
jmp @@End_8
 
; Çàïèñàòü êîä îøèáêè
@@Err1_1:
mov [DevErrorCode],1
jmp @@End_8
@@Err6_temp:
mov [DevErrorCode],7
jmp @@End_8
@@Err6:
mov [DevErrorCode],6
 
@@End_8:
popad
ret
 
 
 
;***********************************************
;* ÏÎÑËÀÒÜ ÓÑÒÐÎÉÑÒÂÓ ATAPI ÏÀÊÅÒÍÓÞ ÊÎÌÀÍÄÓ, *
;* ÍÅ ÏÐÅÄÓÑÌÀÒÐÈÂÀÞÙÓÞ ÏÅÐÅÄÀ×È ÄÀÍÍÛÕ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç *
;* ãëîáàëüíûå ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå; *
;* PacketCommand - 12-áàéòíûé êîìàíäíûé ïàêåò. *
;***********************************************
SendPacketNoDatCommand:
pushad
; Çàäàòü ðåæèì CHS
mov [ATAAddressMode],0
; Ïîñëàòü ATA-êîìàíäó ïåðåäà÷è ïàêåòíîé êîìàíäû
mov [ATAFeatures],0
mov [ATASectorCount],0
mov [ATASectorNumber],0
mov [ATACylinder],0
mov [ATAHead],0
mov [ATACommand],0A0h
call SendCommandToHDD_1
cmp [DevErrorCode],0 ;ïðîâåðèòü êîä îøèáêè
jne @@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
; Îæèäàíèå ïîäòâåðæäåíèÿ ïðèåìà êîìàíäû
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
jmp @@End_9
 
; Çàïèñàòü êîä îøèáêè
@@Err1_3:
mov [DevErrorCode],1
jmp @@End_9
@@Err6_1:
mov [DevErrorCode],6
@@End_9:
popad
ret
 
;****************************************************
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* ChannelNumber - íîìåð êàíàëà (1 èëè 2); *
;* DiskNumber - íîìåð äèñêà (0 èëè 1); *
;* ATAFeatures - "îñîáåííîñòè"; *
;* ATASectorCount - êîëè÷åñòâî ñåêòîðîâ; *
;* ATASectorNumber - íîìåð íà÷àëüíîãî ñåêòîðà; *
;* ATACylinder - íîìåð íà÷àëüíîãî öèëèíäðà; *
;* ATAHead - íîìåð íà÷àëüíîé ãîëîâêè; *
;* ATAAddressMode - ðåæèì àäðåñàöèè (0-CHS, 1-LBA); *
;* ATACommand - êîä êîìàíäû. *
;* Ïîñëå óñïåøíîãî âûïîëíåíèÿ ôóíêöèè: *
;* â ATABasePortAddr - áàçîâûé àäðåñ HDD; *
;* â DevErrorCode - íîëü. *
;* Ïðè âîçíèêíîâåíèè îøèáêè â DevErrorCode áóäåò *
;* âîçâðàùåí êîä îøèáêè. *
;****************************************************
SendCommandToHDD_1:
pushad
; Ïðîâåðèòü çíà÷åíèå êîäà ðåæèìà
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 ecx,0xfff
mov eax,[timer_ticks]
mov [TickCounter_1],eax
@@WaitHDReady_2:
call change_task
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ
; dec ecx
; cmp ecx,0
; je @@Err1
mov eax,[timer_ticks]
sub eax,[TickCounter_1]
cmp eax,BSYWaitTime ;300 ;îæèäàòü 3 ñåê.
ja @@Err1_4 ;îøèáêà òàéì-àóòà
; Ïðî÷èòàòü ðåãèñòð ñîñòîÿíèÿ
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
jmp @@End_10
; Çàïèñàòü êîä îøèáêè
@@Err1_4:
mov [DevErrorCode],1
jmp @@End_10
@@Err2_4:
mov [DevErrorCode],2
jmp @@End_10
@@Err3_4:
mov [DevErrorCode],3
jmp @@End_10
@@Err4_4:
mov [DevErrorCode],4
jmp @@End_10
@@Err5_4:
mov [DevErrorCode],5
; Çàâåðøåíèå ðàáîòû ïðîãðàììû
@@End_10:
sti
popad
ret
;*************************************************
;* ÎÆÈÄÀÍÈÅ ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ Ê ÐÀÁÎÒÅ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðìåííûå: *
;* ChannelNumber - íîìåð êàíàëà; *
;* DiskNumber - íîìåð äèñêà íà êàíàëå. *
;*************************************************
WaitUnitReady:
pusha
; Çàïîìíèòü âðåìÿ íà÷àëà îïåðàöèè
mov EAX,[timer_ticks]
mov [WURStartTime],EAX
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó TEST UNIT READY
mov [PacketCommand],word 00h
; ÖÈÊË ÎÆÈÄÀÍÈß ÃÎÒÎÂÍÎÑÒÈ ÓÑÒÐÎÉÑÒÂÀ
@@SendCommand:
; Ïîäàòü êîìàíäó ïðîâåðêè ãîòîâíîñòè
call SendPacketNoDatCommand
call change_task
; Ïðîâåðèòü êîä îøèáêè
cmp [DevErrorCode],0
je @@End_11
; Ïðîâåðèòü âðåìÿ îæèäàíèÿ ãîòîâíîñòè
mov EAX,[timer_ticks]
sub EAX,[WURStartTime]
cmp EAX,MaxCDWaitTime
jb @@SendCommand
; Îøèáêà òàéì-àóòà
mov [DevErrorCode],1
@@End_11:
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 - íîìåð äèñêà íà êàíàëå. *
;*************************************************
UnloadMedium:
pusha
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
call clear_packet_buffer
; Ñôîðìèðîâàòü êîìàíäó START/STOP UNIT
; Çàäàòü êîä êîìàíäû
mov [PacketCommand],word 1Bh
; Çàäàòü îïåðàöèþ èçâëå÷åíèÿ íîñèòåëÿ
mov [PacketCommand+4],word 00000010b
; Ïîäàòü êîìàíäó
call SendPacketNoDatCommand
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:
; Î÷èñòèòü áóôåð ïàêåòíîé êîìàíäû
mov [PacketCommand],dword 0
mov [PacketCommand+4],dword 0
mov [PacketCommand+8],dword 0
ret
 
/kernel/tags/kolibri0.6.3.0/blkdev/fdc.inc
0,0 → 1,73
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,0xD201
mov al,0
mov ecx,160
rep stosb
ret
 
fdc_filesave: ;ebx: cluster to be saved.
pusha ;returns immediately. does not trigger a write.
mov eax,ebx
add eax,31
mov bl,18
div bl
mov ah,0
add eax,0xD201
mov [eax],byte 1 ;This track is now dirty.
popa
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,0x100000
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
 
/kernel/tags/kolibri0.6.3.0/fs/fat12.inc
0,0 → 1,2722
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; FAT12.INC ;;
;; (C) 2005 Mario79, License: GPL ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
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,[0x3000]
shl eax,5
mov eax,[eax+0x3000+TASKDATA.pid]
mov [flp_status],eax
pop eax
sti
ret
 
floppy_free_space:
;---------------------------------------------
;
; returns free space in edi
;
;---------------------------------------------
push eax ebx ecx
call read_flp_fat
cmp [FDC_Status],0
jne fdc_status_error_2
mov eax,0x282004
xor edi,edi
mov ecx,2847 ;1448000/512
rdfs1_1:
mov ebx,[eax]
and ebx,4095
jne rdfs2_1
add edi,512
rdfs2_1:
add eax,2
loop rdfs1_1
fdc_status_error_2:
pop ecx ebx eax
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
cmp esi,0 ; return ramdisk root
jne fr_noroot_1
cmp ebx,224/16
jbe fr_do_1
mov eax,5
mov ebx,0
mov [flp_status],0
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,0x8000
add esi,ebx
shl ecx,9
cld
rep movsb
mov eax,0 ; ok read
mov ebx,0
mov [flp_status],0
ret
fdc_status_error_1:
mov [flp_status],0
mov eax,10
mov ebx,-1
ret
 
fr_noroot_1:
sub esp,32
call expand_filename
frfloppy_1:
cmp ebx,0
jne frfl5_1
mov ebx,1
frfl5_1:
cmp ecx,0
jne 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,0xD000
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
cmp dl,0
jne l.21_1
dec dh
cmp dh,0
jne l.20_1
fdc_status_error_3:
mov eax,5 ; file not found ?
mov 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,0x282000
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
mov eax,0
mov [flp_status],0
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,0x8000
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,0x8000
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,0x8000
mov edi,0x282000
 
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,0x282000+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,0xD000+39
mov ecx,15
cld
rep cmpsb
je same_label
mov [root_read],0
mov [flp_fat],0
same_label:
mov esi,0xD000+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,0x8000
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,0x8000
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,0x282000
mov edi,0x8000
 
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,0x8000+0x1200 ;4274 bytes - all used FAT
jb fcnew2_1
 
mov esi,0x8000 ; duplicate fat chain
mov edi,0x8000+0x1200
mov ecx,0x1200/4
cld
rep movsd
 
popad
ret
 
 
floppy_filedelete:
;--------------------------------------------
;
; filedelete - sys floppy
; in:
; eax - filename 11 chars - for root directory
; edi pointer to path /fd/1/...... - for all files in nested directories
;
; out:
; eax - 0 = successful, 1 = file not found, 10 = access denied
;
;--------------------------------------------
mov [path_pointer_flp],edi
mov [save_flag],0
mov ebp,1 ; file not found as default
filedelete_newtry_1:
sub esp,32
call expand_filename
push eax ebx ecx edx esi edi
call read_flp_fat
cmp [FDC_Status],0
jne frnoreadd_1
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
call SeekTrack
mov dh,14
l.20_2:
call ReadSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error_4
mov dl,16
mov edi,0xD000
inc [FDD_Sector]
l.21_2:
mov esi,eax ;Name of file we want
mov ecx,11
cld
rep cmpsb ;Found the file?
je fifoundd_1 ;Yes
add ecx,21
add edi, ecx ;Advance to next entry
dec dl
jne l.21_2
dec dh
jne l.20_2
jmp frnoreadd_1
 
fdc_status_error_4:
pop edi esi edx ecx ebx eax
add esp,32
jmp fdc_status_error_1
 
fifoundd_1:
mov eax,[path_pointer_flp]
cmp [eax+36],byte 0
je fifoundd_2
movzx eax, word [edi+0xf]
mov ebx,[path_pointer_flp]
add ebx,36
call get_cluster_of_a_path_flp
jc frnoreadd_1_1
mov edi,ebx
add edi,11
jmp fifoundd_2_1
fifoundd_2:
dec [FDD_Sector]
fifoundd_2_1:
mov [edi-11],byte 0xE5 ;mark filename deleted
movzx edi, word [edi+0xf] ;edi = cluster
frnewd_1:
shl edi,1 ;find next cluster from FAT
add edi,0x282000
mov eax,[edi]
mov [edi],word 0x0 ;clear fat chain cluster
and eax,4095
mov edi,eax
cmp edi,dword 4095 ;last cluster ?
jz frnoreadd2_1
jmp frnewd_1
 
frnoreadd2_1:
call WriteSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error_4
call save_flp_fat
cmp [FDC_Status],0
jne fdc_status_error_4
; pop edi esi edx ecx ebx eax
; add esp,32
mov ebp,0 ; file found
; jmp filedelete_newtry_1
jmp frnoreadd_1
 
frnoreadd_1_1:
cmp [FDC_Status],0
jne fdc_status_error_4
frnoreadd_1:
pop edi esi edx ecx ebx eax
add esp,32
mov eax,ebp
ret
 
floppy_filesave:
;----------------------------------------------------------
;
; filesave - sys floppy
;
; eax ; pointer to file name 11 chars - for root directory
; ebx ; buffer
; ecx ; count to write in bytes
; edx ; 0 create new , 1 append
; edi pointer to path /fd/1/...... - for all files in nested directories
;
; output : eax = 0 - ok
; 5 - file not found / directory not found
; 8 - disk full
; 10 - access denied
;-----------------------------------------------------------
mov [path_pointer_flp],edi
sub esp,32
call expand_filename
cmp edx,0
jnz fsdel_1
pusha
call floppy_filedelete
cmp [FDC_Status],0
jne fdc_status_error_6
popa
mov [save_flag],1
fsdel_1:
call floppy_free_space
cmp [FDC_Status],0
jne fdc_status_error_6
cmp ecx,edi
jb rd_do_save_1
add esp,32
mov eax,8 ; not enough free space
mov [flp_status],0
ret
 
fdc_status_error_6:
popa
add esp,32
jmp fdc_status_error_1
 
rd_do_save_1:
push eax ebx ecx edx esi edi
call read_flp_fat
cmp [FDC_Status],0
jne fdc_status_error_7
push eax
mov eax,[path_pointer_flp]
cmp [eax+36],byte 0
jne fifoundds_2
pop eax
mov [save_root_flag],1
call read_flp_root
cmp [FDC_Status],0
jne fdc_status_error_7
mov edi,0x8000 ;Point at directory
mov edx,224 +1
; find an empty spot for filename in the root dir
l20ds_1:
sub edx,1
jz frnoreadds_1
l21ds_1:
cmp [edi],byte 0xE5
jz fifoundds_1
cmp [edi],byte 0x0
jz fifoundds_1
add edi,32 ; Advance to next entry
jmp l20ds_1
 
fifoundds_2:
pop eax
mov [save_root_flag],0
mov [FDD_Track],0 ; Öèëèíäð
mov [FDD_Head],1 ; Ñòîðîíà
mov [FDD_Sector],2 ; Ñåêòîð
call SeekTrack
mov dh,14
l.20_3:
call ReadSectWithRetr
cmp [FDC_Status],0
jne fdc_status_error_7
mov dl,16
mov edi,0xD000
inc [FDD_Sector]
l.21_3:
mov esi,eax ;Name of file we want
mov ecx,11
cld
rep cmpsb ;Found the file?
je fifoundds_3 ;Yes
add ecx,21
add edi, ecx ;Advance to next entry
dec dl
jne l.21_3
dec dh
jne l.20_3
fdc_status_error_8:
pop edi esi edx ecx ebx eax
mov eax,5 ; file not found ?
mov ebx,-1
add esp,32
mov [flp_status],0
ret
 
fifoundds_3:
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_7_1
found_directory_for_writing_flp:
call analyze_directory_to_write_flp
jc fdc_status_error_7_1
mov edi,ebx
fifoundds_1:
push edi ; move the filename to root dir
mov esi,[esp+4+20]
cmp [save_root_flag],0
jne fifoundds_4
mov esi,[pointer_file_name_flp]
fifoundds_4:
mov ecx,11
cld
rep movsb
pop edi
mov edx,edi
add edx,11+0xf ; edx <- cluster save position
mov ebx,[esp+12] ; save file size
mov [edi+28],ebx
mov [edi+11],byte 0x20 ; attribute
call get_date_for_file ; from FAT32.INC
mov [edi+24],ax ; date
mov [edi+18],ax ; date
call get_time_for_file ; from FAT32.INC
mov [edi+22],ax ; time
xor ax,ax
mov [edi+20],ax
mov ebx,1 ; first cluster
cmp [save_root_flag],0
jne frnewds_1
call frnewds_2
pusha
call WriteSectWithRetr
popa
cmp [FDC_Status],0
jne fdc_status_error_7
jmp frnewds_3
 
frnewds_1:
call frnewds_2
frnewds_3:
pusha ; move save to floppy cluster
add ebx,31
mov eax,ebx
mov esi,[esp+32+16]
call take_data_from_application_1
call save_chs_sector
cmp [FDC_Status],0
jne fdc_status_error_7
popa
mov eax,[esp+12]
cmp eax,512
jb flnsa_1
sub eax,512
mov [esp+12],eax
mov eax,[esp+16]
add eax,512
mov [esp+16],eax
jmp frnewds_1
 
frnewds_2:
add ebx,1
mov edi,ebx ; find free cluster in FAT
shl edi,1
add edi,0x282000
mov eax,[edi]
and eax,4095
jnz frnewds_2
mov [edx],bx ; save next cluster pos. to prev cl.
mov edx,edi ; next save pos abs mem add
ret
 
flnsa_1:
mov [edi],word 4095 ; mark end of file - last cluster
cmp [save_root_flag],1
jne flnsa_2
call save_flp_root
cmp [FDC_Status],0
jne fdc_status_error_7
flnsa_2:
call save_flp_fat
cmp [FDC_Status],0
jne fdc_status_error_7
frnoreadds_1:
pop edi esi edx ecx ebx eax
add esp,32
mov eax,0
mov [flp_status],0
ret
 
fdc_status_error_7_1:
cmp [FDC_Status],0
je fdc_status_error_8
fdc_status_error_7:
pop edi esi edx ecx ebx eax
add esp,32
jmp fdc_status_error_1
 
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
cmp edx,0
je 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,0xD000
 
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,0x282000
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
 
 
analyze_directory_to_write_flp:
;--------------------------------
; input : EAX = first cluster of the directory
; output : IF CARRY=0 EAX = sector where the file is found
; EBX = pointer in buffer
; [buffer .. buffer+511]
; ECX,EDX,EDI,EDI not changed
; IF CARRY=1
;--------------------------------
 
push ecx
push edx
push esi
 
adr561:
mov [clust_tmp_flp],eax
add eax,31
pusha
call read_chs_sector
popa
cmp [FDC_Status],0
jne error_found_file_analyze1
 
mov ecx,512/32
mov ebx,0xD000
 
adr1_analyze1:
cmp byte [ebx],0x00
je found_file_analyze1
cmp byte [ebx],0xe5
je found_file_analyze1
 
avanti:
add ebx,32
loop adr1_analyze1
 
mov eax,[clust_tmp_flp]
shl eax,1 ;find next cluster from FAT
add eax,0x282000
mov eax,[eax]
and eax,4095
cmp eax,0x0ff8
jb adr561
 
call get_free_FAT ;this block of code add a new cluster
;for the directory because the directory
;is full
 
mov [edi],word 0x0fff
 
mov eax,[clust_tmp_flp]
shl eax,1 ;find next cluster from FAT
add eax,0x282000
sub edi,0x282000
mov [eax],di
 
pusha
mov ecx,512/4
xor eax,eax
mov edi,0xD000
cld
rep stosd
popa
 
mov eax,edi
add eax,31
pusha
call save_chs_sector
popa
cmp [FDC_Status],0
jne error_found_file_analyze1
mov ebx,0xD000
 
found_file_analyze1:
 
pop esi
pop edx
pop ecx
clc ;file found
ret
 
error_found_file_analyze1:
pop esi
pop edx
pop ecx
stc
ret
 
get_free_FAT_flp:
;------------------------------------------
; input : EAX = # cluster for start the searching
; output : EAX = # first cluster found free
;-------------------------------------------
push ebx
 
mov ebx,1
check_new_flp:
add ebx,1
mov edi,ebx ; find free cluster in FAT
shl edi,1
add edi,0x282000
mov eax,[edi]
and eax,4095
cmp eax,0x0
jnz check_new_flp
 
pop ebx
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, 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, 0xD000
ret ; CF=0
.readerr:
stc
ret
 
flp_rootmem_first:
mov edi, 0x8000
clc
ret
flp_rootmem_next:
add edi, 0x20
cmp edi, 0x8000+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, 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+0x282000]
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, 0xD000
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, 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, 0x282000
mov ecx, 2849
repnz scasw
jnz .notfound
mov word [edi-2], 0xFFF ; mark as last cluster
sub edi, 0x282000
shr edi, 1
dec edi
mov eax, [esp+28]
mov ecx, [eax]
mov [0x282000+ecx*2], di
mov [eax], edi
xor eax, eax
mov edi, 0xD000
mov ecx, 128
rep stosd
popa
call flp_notroot_end_write
mov edi, 0xD000
clc
ret
.notfound:
popa
stc
ret
 
fd_find_lfn:
; in: esi->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
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:
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, [0xD000+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+0x282000]
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, 0xD000
push eax
.l1:
call fat_get_name
jc .l2
cmp byte [edi+11], 0xF
jnz .do_bdfe
add edi, 0x20
cmp edi, 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+0x282000]
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, 0xD000
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, 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+0x282000]
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_FloppyRewrite:
cmp byte [esi], 0
jz @b
call read_flp_fat
cmp [FDC_Status], 0
jnz fsfrfe
pushad
xor ebp, ebp
push esi
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
lea ebp, [esi-1]
jmp @b
@@:
pop esi
test ebp, ebp
jnz .noroot
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
.noroot:
; check existence
mov byte [ebp], 0
call fd_find_lfn
mov byte [ebp], '/'
lea esi, [ebp+1]
jnc @f
mov eax, ERROR_FILE_NOT_FOUND
.ret1:
mov [esp+28], eax
popad
xor ebx, ebx
ret
@@:
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; must not be directory
test byte [edi+11], 10h
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, [0x282000 + 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
.doit:
lea eax, [esp+8]
call dword [eax+12] ; flush directory
push ecx
push edi
push 0
mov esi, edx
jecxz .done
mov ecx, 2849
mov edi, 0x282000
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
lea eax, [edi-0x282000]
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]
@@:
push ecx
mov edi, 0xD000
rep movsb
pop ecx
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
 
;----------------------------------------------------------------
;
; 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:
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, 0xD000
add edi, [esp+4+12]
rep stosb
@@:
; zero uninitialized data in the last sector
mov ecx, 0x200
sub ecx, esi
jbe @f
mov edi, 0xD000
add edi, esi
rep stosb
@@:
pop edi ecx eax
; copy new data
push eax
mov eax, edx
neg ebx
jecxz @f
add ebx, 0xD000+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
.next_cluster:
movzx edi, word [edi*2+0x282000]
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+0x282000]
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+0x282000]
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, 0x282000+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, 0x282000
shr edi, 1
dec edi ; now edi=new cluster
test eax, eax
jz .first_cluster
mov [0x282000+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, 0xD000+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 [0x282000+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 [0x282000+ecx*2]
jmp @b
@@:
; we will zero data at the end of last sector - remember it
push ecx
; terminate FAT chain
lea ecx, [0x282000+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, [0x282000+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, 0xD000
mov ecx, 0xD000+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], 0
jz @f
mov al, 11
@@:
ret
 
;----------------------------------------------------------------
;
; fs_FloppyExecute - LFN variant for executing from floppy
;
; esi points to floppy filename (e.g. 'dir1/name')
; ebp points to full filename (e.g. '/fd/1/dir1/name')
; dword [ebx] = flags
; dword [ebx+4] = cmdline
;
; ret ebx,edx destroyed
; eax > 0 - PID, < 0 - error
;
;--------------------------------------------------------------
fs_FloppyExecute:
mov edx, [ebx]
mov ebx, [ebx+4]
test ebx, ebx
jz @f
add ebx, std_application_base_address
@@:
 
;----------------------------------------------------------------
;
; fs_FloppyExecute.flags - second entry
;
; esi points to floppy filename (kernel address)
; ebp points to full filename
; edx flags
; ebx cmdline (kernel address)
;
; ret eax > 0 - PID, < 0 - error
;
;--------------------------------------------------------------
 
.flags:
call read_flp_fat
cmp byte [esi], 0
jnz @f
; cannot execute root!
mov eax, -ERROR_ACCESS_DENIED
ret
@@:
push edi
call fd_find_lfn
jnc .found
pop edi
mov eax, -ERROR_FILE_NOT_FOUND
ret
.found:
movzx eax, word [edi+26] ; cluster
push eax
push dword [edi+28] ; size
push .DoRead
call fs_execute
add esp, 12
pop edi
ret
 
.DoRead:
; read next block
; in: eax->parameters, edi->buffer
; out: eax = error code
pushad
cmp dword [eax], 0 ; file size
jz .eof
mov eax, [eax+4] ; cluster
add eax, 31
call read_chs_sector
cmp [FDC_Status], 0
jnz .err
pop edi
mov esi, 0xD000
push edi
mov ecx, 512/4
rep movsd
mov eax, [esp+28]
mov ecx, [eax]
sub ecx, 512
jae @f
add edi, ecx
neg ecx
push eax
xor eax, eax
rep stosb
pop eax
@@:
mov [eax], ecx
mov edx, [eax+4]
mov dx, [edx*2+0x282000]
mov [eax+4], dx ; high word is already zero
popad
xor eax, eax
ret
.eof:
popad
mov eax, 6
ret
.err:
popad
mov eax, 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_DATA + 2*0x20
.checkempty:
cmp byte [ebx], 0
jz .empty
cmp byte [ebx], 0xE5
jnz .notempty
add ebx, 0x20
cmp ebx, FDD_DATA + 0x200
jb .checkempty
movzx eax, word [FLOPPY_FAT + eax*2]
pusha
add eax, 31
call read_chs_sector
popa
mov ebx, FDD_DATA
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_DATA
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_DATA+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}
/kernel/tags/kolibri0.6.3.0/fs/fat32.inc
0,0 → 1,3862
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; FAT32.INC ;;
;; ;;
;; FAT16/32 functions for KolibriOS ;;
;; ;;
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;;
;; ;;
;; See file COPYING for details ;;
;; 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
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
cluster dd 0 ; used by file_write,makedir,append
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
 
sector_tmp dd 0 ; used by rename,append,file_write
entry_pos dd 0 ; used by rename,append,file_write
 
old_filesize dd 0 ; used by append
new_filepos dd 0 ; used by append
bytes2write dd 0 ; used by append
 
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
deltree_buffer: times 512 db 0
fsinfo_buffer: times 512 db 0
endg
 
iglobal
NewDirEntry1 db ". ",0x10
times 20 db 0
NewDirEntry2 db ".. ",0x10
times 20 db 0
endg
 
uglobal
dir_entry: times 32 db 0
 
startpath: times 255 db 0
 
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,[0x3000]
shl eax,5
mov eax,[eax+0x3000+TASKDATA.pid]
mov [hd1_status],eax
pop eax
sti
ret
;********************************************
reserve_hd_channel:
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_1
.reserve_ok_1:
mov [IDE_Channel_1],1
ret
.reserve_ok_2:
mov [IDE_Channel_2],1
ret
free_hd_channel:
cmp [hdbase], 0x1F0
jne .IDE_Channel_2
.IDE_Channel_1:
mov [IDE_Channel_1],0
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 [fat_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 [fat_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 [fat_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:
;-----------------------------------------------------------
; input : EAX = # cluster for start the searching
; 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
 
gff_test:
cmp eax,[LAST_CLUSTER] ; if above last cluster start at cluster 2
jbe gff_in_range
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:
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 [fat_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
 
 
analyze_directory_to_write:
;-----------------------------------------------------------
; input : EAX = first cluster of the directory
; output : IF CARRY=0 EAX = sector where the empty pos is found
; EBX = pointer in buffer
; [buffer .. buffer+511]
; ECX,EDX,ESI,EDI not changed
; IF CARRY=1 disk full or fat corrupted
; Note : if cluster=0 it's changed to read rootdir
;-----------------------------------------------------------
push ecx edx edi
 
adw_new_cluster:
mov [cluster_tmp],eax
mov [fat16_root],0
cmp eax,[LAST_CLUSTER]
ja adw_not_found ; too big cluster number, something is wrong
cmp eax,2
jnb adw_data_cluster
 
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir
cmp [fat_type],16
jne adw_data_cluster
mov eax,[ROOT_START]
mov edx,[ROOT_SECTORS]
mov [fat16_root],1 ; flag for fat16 rootdir
jmp adw_new_sector
 
adw_data_cluster:
sub eax,2
mov edx,[SECTORS_PER_CLUSTER]
imul eax,edx
add eax,[DATA_START]
 
adw_new_sector:
mov ebx,buffer
call hd_read
cmp [hd_error],0
jne adw_not_found
 
mov ecx,512/32 ; count of dir entrys per sector = 16
 
adw_analyze:
cmp byte [ebx],0x00 ; is free entry?
je adw_found ; yes
cmp byte [ebx],0xe5 ; is deleted entry?
je adw_found ; yes
add ebx,32 ; position of next dir entry
dec ecx
jnz adw_analyze
 
inc eax ; next sector
dec edx
jne adw_new_sector
cmp [fat16_root],1 ; end of fat16 rootdir
je adw_not_found
 
mov eax,[cluster_tmp]
call get_FAT ; get next cluster
cmp [hd_error],0
jne adw_not_found
 
cmp eax,2 ; incorrect fat chain?
jb adw_not_found ; yes
cmp eax,[fatRESERVED] ; is it end of directory?
jb adw_new_cluster ; no. analyse it
 
mov eax,2 ; this block of code add a new cluster
call get_free_FAT ; for the directory because the directory
jc adw_not_found ; is full
 
mov edx,[fatEND] ; new end for directory
call set_FAT
cmp [hd_error],0
jne adw_not_found
 
push eax ; save new cluster
mov edx,eax
mov eax,[cluster_tmp] ; change last cluster to point new cluster
call set_FAT
cmp [hd_error],0
jne adw_not_found_1
 
mov ecx,-1 ; remove 1 cluster from free disk space
call add_disk_free_space
cmp [hd_error],0
jne adw_not_found_1
 
mov ecx,512/4
xor eax,eax
mov edi,buffer
cld
rep stosd ; clear new directory cluster
pop eax
 
sub eax,2
mov ecx,[SECTORS_PER_CLUSTER]
imul eax,ecx
add eax,[DATA_START]
mov ebx,buffer
push eax ; save sector number
 
adw_set_empty_directory:
call hd_write
cmp [hd_error],0
jne adw_not_found_1
 
inc eax ; next sector
dec ecx
jnz adw_set_empty_directory
 
pop eax
 
adw_found:
pop edi edx ecx
clc ; free space found
ret
adw_not_found_1:
add esp,4
adw_not_found:
pop edi edx ecx
stc ; free space not 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 [fat_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
 
 
set_data_cluster:
;-----------------------------------------------------------
; input : EAX = cluster
; EBX = pointer to buffer
; output : if CARRY=0 ok
; if CARRY=1 cluster out of range
;-----------------------------------------------------------
push eax ebx edx
 
cmp eax,[LAST_CLUSTER]
ja sdc_error ; too big cluster number, something is wrong
sub eax,2
jb sdc_error ; don't allow rootdir write
 
mov edx,[SECTORS_PER_CLUSTER]
imul eax,edx
add eax,[DATA_START]
 
sdc_write:
call hd_write
cmp [hd_error],0
jne sdc_error
 
add ebx,512 ; update pointer
inc eax
dec edx
jnz sdc_write
pop edx ebx eax
clc
ret
 
sdc_error:
pop edx ebx 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
 
 
makedir:
;-----------------------------------------------------
; input : eax = directory name
; edx = path
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 8 - disk full
; 10 - access denied
; Note : can only make one directory at time
;-----------------------------------------------------
cmp [fat_type],0
jnz make_dir_fat_ok
mov eax,ERROR_UNKNOWN_FS
ret
 
make_dir_fat_ok:
; call reserve_hd1
 
pushad
 
mov ebx,edx
call get_cluster_of_a_path
jnc make_dir_found_path
cmp [hd_error],0
jne make_dir_error_1
 
make_dir_path_not_found:
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne make_dir_error_2
 
mov [hd1_status],0
mov eax,ERROR_FILE_NOT_FOUND
ret
 
make_dir_disk_full:
cmp [hd_error],0
jne make_dir_error_1
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne make_dir_error_2
 
mov [hd1_status],0
mov eax,ERROR_DISK_FULL
ret
 
make_dir_already_exist:
cmp [hd_error],0
jne make_dir_error_1
mov eax,[cluster] ; directory cluster
xor edx,edx ; free
call set_FAT
cmp [hd_error],0
jne make_dir_error_1
 
popad
call update_disk ; write all of cache and fat to hd
make_dir_error_2:
mov [hd1_status],0
mov eax,ERROR_ACCESS_DENIED
ret
 
make_dir_error_1:
popad
jmp make_dir_error_2
 
make_dir_error_3:
add esp,4
jmp make_dir_error_1
 
make_dir_found_path:
cmp eax,[ROOT_CLUSTER]
jnz make_dir_not_root
xor eax,eax
 
make_dir_not_root:
mov ecx,eax ; directorys start cluster
mov word [NewDirEntry2+26],cx ; 16 bits low of cluster
shr ecx,16
mov word [NewDirEntry2+20],cx ; 16 bits high of cluster (=0 fat16)
 
push eax ; save parent directory cluster
mov eax,2
call get_free_FAT
mov [cluster],eax ; first free cluster
pop eax
jc make_dir_disk_full
 
push eax
mov eax,[cluster] ; directory cluster
mov edx,[fatEND] ; end for directory
call set_FAT
cmp [hd_error],0
jne make_dir_error_3
pop eax
 
mov ebx,PUSHAD_EAX ; dir name
push eax
call analyze_directory ; check if directory already exist
cmp [hd_error],0
jne make_dir_error_1
 
pop eax
jnc make_dir_already_exist ; need to free allocated cluster!
 
call analyze_directory_to_write
jc make_dir_already_exist ; need to free allocated cluster!
 
mov esi,PUSHAD_EAX ; dir name
mov edi,ebx ; pointer in buffer
mov ecx,11
cld
rep movsb
 
mov dword [ebx+28],0 ; dir size is always 0
mov ecx,[cluster]
mov [ebx+26],cx ; 16 bits low of cluster
mov word [NewDirEntry1+26],cx
shr ecx,16
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16)
mov word [NewDirEntry1+20],cx
mov byte [ebx+11],0x10 ; attribute = directory
 
call set_current_time_for_entry
mov ecx,[ebx+22]
mov dword [NewDirEntry1+22],ecx
mov dword [NewDirEntry2+22],ecx
 
mov ebx,buffer ; save the directory name,length,cluster
call hd_write
cmp [hd_error],0
jne make_dir_error_1
 
mov ecx,512/4
xor eax,eax
mov edi,buffer
cld
rep stosd ; clear new directory cluster
 
mov eax,[cluster] ; new directory cluster
sub eax,2
mov edx,[SECTORS_PER_CLUSTER]
imul eax,edx
add eax,[DATA_START]
mov ebx,buffer
add eax,edx ; start from last sector
 
dir_set_empty_directory:
dec eax ; next sector
cmp edx,1 ; is first directory sector?
jnz not_first_sector ; no. write empty sector
mov esi,NewDirEntry1
mov edi,buffer
mov ecx,64/4
cld
rep movsd ; copy 2 first directory entrys "." and ".."
 
not_first_sector:
call hd_write
cmp [hd_error],0
jne make_dir_error_1
dec edx
jnz dir_set_empty_directory
 
mov ecx,-1 ; remove 1 cluster from free disk space
call add_disk_free_space
cmp [hd_error],0
jne make_dir_error_1
 
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne make_dir_error_2
mov [hd1_status],0
xor eax,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 [fat_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
call hd_write
; cmp [hd_error],0
; jne add_not_fs
 
add_not_fs:
pop ebx eax
 
add_dfs_no:
ret
 
 
file_write:
;--------------------------------------------------------------------------
; INPUT : user-reg register-in-this meaning symbol-in-this-routine
;
; EAX EDI system call to write /
; EBX EAX (PAR0) pointer to file-name PAR0
; EDX ECX (PAR1) pointer to buffer PAR1
; ECX EBX (PAR2) file size PAR2
; ESI EDX (PAR3) pointer to path PAR3
;
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 8 - disk full
; 10 - access denied
;--------------------------------------------------------------------------
cmp [fat_type],0
jnz fat_ok_for_writing
mov eax,ERROR_UNKNOWN_FS
ret
 
fat_ok_for_writing:
; call reserve_hd1
 
pushad
 
xor edi,edi ; don't allow directory remove
call file_delete ; try to delete the file first
cmp [hd_error],0
jne exit_write_access_1
 
test eax,eax
jz old_deleted ; deleted ok
cmp eax,ERROR_FILE_NOT_FOUND
jnz exit_write_access ; it exist but can't delete
 
old_deleted:
mov ebx,PUSHAD_EDX
call get_cluster_of_a_path
jnc found_directory_for_writing
cmp [hd_error],0
jne exit_write_access
 
exit_writing_with_error:
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne exit_write_access_2
 
mov [hd1_status],0
mov eax,ERROR_FILE_NOT_FOUND
ret
 
exit_writing_disk_full_clear:
cmp [hd_error],0
jne exit_write_access_1
mov eax,[sector_tmp]
mov ebx,buffer
call hd_read ; read directory sector
cmp [hd_error],0
jne exit_write_access_1
 
mov edx,[entry_pos]
mov byte [edx],0xe5 ; mark as deleted
call hd_write
cmp [hd_error],0
jne exit_write_access_1
 
mov eax,[edx+20-2] ; FAT entry
mov ax,[edx+26]
and eax,[fatMASK]
call clear_cluster_chain
 
exit_writing_disk_full:
cmp [hd_error],0
jne exit_write_access_1
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne exit_write_access_2
mov [hd1_status],0
mov eax,ERROR_DISK_FULL
ret
 
exit_write_access:
popad
call update_disk ; write all of cache and fat to hd
mov [hd1_status],0
mov eax,ERROR_ACCESS_DENIED
ret
 
exit_write_access_1:
popad
exit_write_access_2:
mov [hd1_status],0
mov eax,ERROR_ACCESS_DENIED
ret
 
found_directory_for_writing:
call analyze_directory_to_write
jc exit_writing_disk_full
 
mov [sector_tmp],eax
mov [entry_pos],ebx
push eax ; save directory sector
mov eax,2
call get_free_FAT
mov [cluster],eax ; first free cluster
pop eax
jc exit_writing_disk_full
 
mov esi,PUSHAD_EAX ; file name
mov edi,ebx ; pointer in buffer
mov ecx,11
cld
rep movsb
 
mov esi,PUSHAD_EBX ; file size (bytes left)
mov [ebx+28],esi ; file size
mov ecx,[cluster]
mov [ebx+26],cx ; 16 bits low of cluster
shr ecx,16
mov [ebx+20],cx ; 16 bits high of cluster (=0 fat16)
mov byte [ebx+11],0x20 ; attribute = archive
 
call set_current_time_for_entry
 
mov ebx,buffer ; save the directory name,length,cluster
call hd_write
cmp [hd_error],0
jne exit_write_access_1
 
imul edi,[SECTORS_PER_CLUSTER],512 ; edi = cluster size in bytes
xor ecx,ecx ; cluster count
mov ebx,PUSHAD_ECX ; ebx = buffer
 
hd_new_block_write:
 
mov eax,[cluster] ; eax = block
call set_data_cluster
cmp [hd_error],0
jne exit_write_access_1
 
sub esi,edi ; sub wrote bytes
jbe file_saved_OK ; end if all done
add ebx,edi ; update buffer position
 
inc eax
call get_free_FAT ; next free in FAT
jc exit_writing_disk_full_clear
 
mov edx,eax
xchg eax,[cluster] ; get old cluster and save new cluster
call set_FAT ; add it in cluster chain
cmp [hd_error],0
jne exit_write_access_1
 
dec ecx ; update cluster count
jmp hd_new_block_write
 
file_saved_OK:
 
mov edx,[fatEND] ; new end for cluster chain
call set_FAT
cmp [hd_error],0
jne exit_write_access_1
 
dec ecx ; update cluster count
 
call add_disk_free_space ; remove clusters from free disk space
cmp [hd_error],0
jne exit_write_access_1
 
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne exit_write_access_2
mov [hd1_status],0
xor eax,eax
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 [fat_type],0
jnz 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 [fat_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
 
 
file_delete:
;-----------------------------------------------------
; input : eax = file/directory name
; edx = path
; edi = 1 - allow directory remove else don't remove directory
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 10 - access denied
;-----------------------------------------------------
cmp [fat_type],0
jnz file_del_fat_ok
mov eax,ERROR_UNKNOWN_FS
ret
 
file_del_fat_ok:
pushad
 
mov ebx,edx
call get_cluster_of_a_path
jc file_to_delete_not_found
 
mov ebx,PUSHAD_EAX ; file/directory name
call analyze_directory
jc file_to_delete_not_found
 
test byte [ebx+11],0x10 ; is it directory?
jz delete_notdir ; no. it's file
cmp edi,1 ; allow directory remove
jnz delete_no_access ; no
 
push eax ; save directory sector
mov eax,[ebx+20-2] ; first cluster of file
mov ax,[ebx+26] ; 0 length files start cluster = 0
and eax,[fatMASK]
xor ebp,ebp ; counter for directory deepnes
call clear_directory
pop eax
jc delete_no_access
 
push ebx ; save directory pointer in buffer
mov ebx,buffer
call hd_read ; read directory sector
cmp [hd_error],0
jne delete_no_access_1
pop ebx
 
delete_notdir:
call delete_entry_name
cmp [hd_error],0
jne delete_no_access
 
mov eax,ecx ; first cluster of file
call clear_cluster_chain
cmp [hd_error],0
jne delete_no_access
 
popad
xor eax,eax
ret
 
delete_no_access_1:
add esp,4
delete_no_access:
popad
mov eax,ERROR_ACCESS_DENIED
ret
 
file_to_delete_not_found:
cmp [hd_error],0
jne delete_no_access
popad
mov eax,ERROR_FILE_NOT_FOUND
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
 
 
clear_directory:
;-----------------------------------------------------
; input : eax = directory cluster
; ebp = directory deepnes
; Note : use recursive call
;-----------------------------------------------------
pushad
inc ebp
cmp ebp,64 ; if over 63 directory deep
jnb clear_error ; something must be wrong
 
clear_new_cluster:
cmp eax,[LAST_CLUSTER]
ja clear_end
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster
jz clear_end
mov esi,eax ; esi = current directory cluster
sub eax,2
jb clear_end
mov ecx,[SECTORS_PER_CLUSTER]
imul eax,ecx
add eax,[DATA_START]
 
clear_new_sector:
mov edi,eax ; edi = current directory sector
mov ebx,deltree_buffer
call hd_read
cmp [hd_error],0
jne clear_error
 
mov edx,512/32 ; count of dir entrys per sector = 16
 
clear_analyze:
mov al,[ebx+11] ; file attribute
and al,0xf
cmp al,0xf
je clear_long_filename
 
cmp byte [ebx],'.' ; parent or current directory
je clear_next_entry
cmp byte [ebx],0xe5 ; deleted
je clear_next_entry
cmp byte [ebx],0 ; empty
je clear_write_last
;je clear_next_entry
 
mov eax,[ebx+20-2] ; first cluster of entry
mov ax,[ebx+26]
and eax,[fatMASK]
 
test byte [ebx+11],0x10 ; is it directory?
jz clear_file ; no
 
push eax ebx
mov eax,edi
mov ebx,deltree_buffer ; save buffer over recursive call
call hd_write ; write directory sector to disk
cmp [hd_error],0
jne clear_error
 
pop ebx eax
 
call clear_directory ; recursive call !!!
jc clear_error ; exit if error found
 
push eax ebx
mov eax,edi
mov ebx,deltree_buffer
call hd_read ; read directory sector again
cmp [hd_error],0
jne clear_error_1
 
pop ebx eax
 
clear_file:
call clear_cluster_chain
cmp [hd_error],0
jne clear_error
 
clear_long_filename:
mov byte [ebx],0xe5
 
clear_next_entry:
add ebx,32 ; position of next dir entry
dec edx
jnz clear_analyze
 
mov eax,edi
mov ebx,deltree_buffer
call hd_write ; write directory sector to disk
cmp [hd_error],0
jne clear_error
 
inc eax ; next sector
dec ecx
jnz clear_new_sector
 
mov eax,esi
call get_FAT ; get next cluster
cmp [hd_error],0
jne clear_error
 
jmp clear_new_cluster ; clear it
 
clear_write_last:
mov eax,edi
mov ebx,deltree_buffer
call hd_write ; write directory sector to disk
cmp [hd_error],0
jne clear_error
 
clear_end:
popad
clc
ret
clear_error_1:
add esp,8
clear_error:
popad
stc
ret
 
 
delete_entry_name:
;-----------------------------------------------------
; input : eax = directory sector
; ebx = directory pointer in buffer
; longname_sec = 2 previous directory sectors
; output : ecx = first cluster
; change : eax,ebx,edx
;-----------------------------------------------------
mov byte [ebx],0xe5
mov ecx,[ebx+20-2] ; first cluster of file
mov cx,[ebx+26] ; 0 length files start cluster = 0
and ecx,[fatMASK]
 
delete_empty:
sub ebx,32
cmp ebx,buffer
jnb delete_test_long
 
mov ebx,buffer
call hd_write ; write directory sector back
cmp [hd_error],0
jne delete_name_end
 
xor eax,eax
xchg eax,[longname_sec2]
xchg eax,[longname_sec1]
test eax,eax ; is there previous directory sector?
jz delete_name_end ; no
 
mov ebx,buffer
call hd_read ; read previous sector
cmp [hd_error],0
jne delete_name_end
 
mov ebx,buffer+0x1e0 ; start from last entry
 
delete_test_long:
mov dh,[ebx+11] ; file attribute
and dh,0xf
cmp dh,0xf
jne delete_write_buffer
 
cmp byte [ebx],0x40 ; end of long dir entry?
mov byte [ebx],0xe5
jb delete_empty
 
delete_write_buffer:
mov ebx,buffer
call hd_write ; write directory sector back
 
delete_name_end:
ret
 
 
rename:
;-----------------------------------------------------------
; input : eax = source directory name
; edx = source path
; ebx = dest directory name
; edi = dest path
; output : eax = 0 - ok
; 3 - unknown FS
; 5 - file not found
; 8 - disk full
; 10 - access denied
;-----------------------------------------------------------
cmp [fat_type],0
jnz fat_ok_for_rename
mov eax,ERROR_UNKNOWN_FS
ret
 
fat_ok_for_rename:
; call reserve_hd1
 
pushad
 
mov ebx,edx ; source path
call get_cluster_of_a_path
jc rename_entry_not_found
 
mov ebx,PUSHAD_EAX ; source directory name
call analyze_directory
jc rename_entry_not_found
 
mov [sector_tmp],eax ; save source sector
mov [entry_pos],ebx
mov esi,ebx
mov edi,dir_entry
mov ecx,32/4
cld
rep movsd ; save entry
 
mov ebx,PUSHAD_EDI ; dest path
call get_cluster_of_a_path
jc rename_entry_not_found
 
mov edx,eax ; save dest directory cluster
mov ebx,PUSHAD_EBX ; dest directory name
push [longname_sec1]
push [longname_sec2]
call analyze_directory ; check if entry already exist
cmp [hd_error],0
jne rename_entry_already_exist_1
 
pop [longname_sec2]
pop [longname_sec1]
jnc rename_entry_already_exist
 
mov eax,edx
call analyze_directory_to_write
jc rename_disk_full
 
mov esi,dir_entry
mov edi,ebx
mov ecx,32/4
cld
rep movsd ; copy entry
mov esi,PUSHAD_EBX ; dest directory name
mov edi,ebx
mov ecx,11
rep movsb ; copy name
 
mov ebx,buffer ; save the directory name,length,cluster
call hd_write
 
test byte [dir_entry+11],0x10 ; is it directory?
jz rename_not_dir ; no
mov eax,[dir_entry+20-2] ; FAT entry
mov ax,[dir_entry+26]
and eax,[fatMASK]
call change_2dot_cluster
cmp [hd_error],0
jne rename_entry_already_exist
 
rename_not_dir:
cmp [hd_error],0
jne rename_entry_already_exist
mov eax,[sector_tmp]
mov ebx,buffer
call hd_read ; read source directory sector
cmp [hd_error],0
jne rename_entry_already_exist
 
mov ebx,[entry_pos]
call delete_entry_name
cmp [hd_error],0
jne rename_entry_already_exist
 
popad
call update_disk ; write all of cache and fat to hd
cmp [hd_error],0
jne rename_entry_already_exist_2
mov [hd1_status],0
xor eax,eax
ret
 
rename_entry_not_found:
cmp [hd_error],0
jne rename_entry_already_exist
popad
mov [hd1_status],0
mov eax,ERROR_FILE_NOT_FOUND
ret
 
rename_entry_already_exist_1:
add esp,8
rename_entry_already_exist:
popad
rename_entry_already_exist_2:
mov [hd1_status],0
mov eax,ERROR_ACCESS_DENIED
ret
 
rename_disk_full:
cmp [hd_error],0
jne rename_entry_already_exist
popad
mov [hd1_status],0
mov eax,ERROR_DISK_FULL
ret
 
 
change_2dot_cluster:
;-----------------------------------------------------------
; input : eax = directory cluster
; edx = value to save
; change : eax,ebx,edx
;-----------------------------------------------------------
cmp eax,[LAST_CLUSTER]
ja not_2dot ; too big cluster number, something is wrong
sub eax,2
jb not_2dot
 
imul eax,[SECTORS_PER_CLUSTER]
add eax,[DATA_START]
mov ebx,buffer
call hd_read
cmp [hd_error],0
jne not_2dot
 
cmp dword [ebx+32],'.. '
jnz not_2dot
 
cmp edx,[ROOT_CLUSTER] ; is rootdir cluster?
jne not_2dot_root
xor edx,edx ; yes. set it zero
 
not_2dot_root:
mov [ebx+32+26],dx ; 16 bits low of cluster
shr edx,16
mov [ebx+32+20],dx ; 16 bits high of cluster (=0 fat16)
call hd_write
 
not_2dot:
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 [fat_type],0
jnz 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
 
read_hd_file:
;-----------------------------------------------------------------
;
; Converting old reading function for hd-application start.
;
; IN:
;
; eax - pointer to file (0 = read only first sector of drive: eg 'label')
; 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)
;
; For new read function
;
; EAX (PAR0) pointer to file-name
; ECX (PAR1) pointer to buffer
; EBX (PAR2) vt file blocks to read
; EDX (PAR3) pointer to path
; ESI vt first 512 block to read
; EDI if 0 - return root
;--------------------------------------------------------------------------
 
push ecx esi edi
mov esi,eax
mov edi,startpath
mov ecx,250
cld
rep movsb
pop edi esi ecx
 
mov eax,startpath
mov [eax+ebx-12],byte 0
 
push eax ebx ecx edx esi
 
pop ecx ; pointer to buffer
add ecx,1024
pop ebx ; number of blocks to read
pop esi ; first block to read
dec esi
pop eax ; file length
pop edx ; pointer to path
 
mov edi,12
lea eax,[eax+edx-12+1]
call file_read
 
ret
 
; \begin{diamond}
hd_find_lfn:
; in: esi->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 [fat_type], 32
jz .fat32
.loop:
call fat_find_lfn
jc .notfound
cmp byte [esi], 0
jz .found
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:
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 [fat_type], 0
jnz @f
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
.noaccess_3:
add esp,4
.noaccess_1:
add esp,4
.noaccess_4:
add esp,4*5
jmp .noaccess_2
 
@@:
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
cmp [hd_error],0
jne .noaccess_1
pop ebx
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
cmp [hd_error],0
jne .noaccess_3
 
mov eax, ebx
pop ebx
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_4
 
jmp .new_cluster
.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:
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 [fat_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
mov eax, [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_HdRewrite:
cmp [fat_type], 0
jz fshrfs
cmp byte [esi], 0
jz fshrad
pushad
xor ebp, ebp
push esi
@@:
lodsb
test al, al
jz @f
cmp al, '/'
jnz @b
lea ebp, [esi-1]
jmp @b
@@:
pop esi
test ebp, ebp
jnz .noroot
mov ebp, [ROOT_CLUSTER]
cmp [fat_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
.noroot:
; check existence
mov byte [ebp], 0
call hd_find_lfn
mov byte [ebp], '/'
lea esi, [ebp+1]
jnc @f
mov eax, ERROR_FILE_NOT_FOUND
.ret1:
mov [esp+28], eax
popad
xor ebx, ebx
ret
@@:
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; must not be directory
test byte [edi+11], 10h
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
.doit:
lea eax, [esp+8]
call dword [eax+16] ; flush directory
push ecx
mov ecx, [esp+4+32+24]
push ecx
push edi
mov esi, edx
test ecx, ecx
jz .done
mov eax, 2
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:
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
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
 
;----------------------------------------------------------------
;
; fs_HdWrite - 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
;
;--------------------------------------------------------------
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 [fat_type], 0
jnz @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:
; 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 eax
; copy new data
push eax
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
; 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
mov eax, edx
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 [fat_type], 0
jnz @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 [fat_type], 0
jnz @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 [fat_type], 0
jnz @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_HdExecute - LFN variant for executing from harddisk
;
; esi points to hd filename (e.g. 'dir1/name')
; ebp points to full filename (e.g. '/hd0/1/dir1/name')
; dword [ebx] = flags
; dword [ebx+4] = cmdline
;
; ret ebx,edx destroyed
; eax > 0 - PID, < 0 - error
;
;--------------------------------------------------------------
fs_HdExecute:
mov edx, [ebx]
mov ebx, [ebx+4]
test ebx, ebx
jz @f
add ebx, std_application_base_address
@@:
 
;----------------------------------------------------------------
;
; fs_HdExecute.flags - second entry
;
; esi points to floppy filename (kernel address)
; ebp points to full filename
; edx flags
; ebx cmdline (kernel address)
;
; ret eax > 0 - PID, < 0 - error
;
;--------------------------------------------------------------
 
.flags:
cmp [fat_type], 0
jnz @f
mov eax, -ERROR_UNKNOWN_FS
ret
@@:
cmp byte [esi], 0
jnz @f
; cannot execute root!
mov eax, -ERROR_ACCESS_DENIED
ret
@@:
push edi
call hd_find_lfn
jnc .found
pop edi
mov eax, -ERROR_FILE_NOT_FOUND
cmp [hd_error], 0
jz @f
mov al, -11
@@:
ret
.found:
mov eax, [edi+20-2]
mov ax, [edi+26]
push 0
push eax
push dword [edi+28] ; size
push .DoRead
call fs_execute
add esp, 16
pop edi
ret
 
.DoRead:
; read next block
; in: eax->parameters, edi->buffer
; out: eax = error code
pushad
cmp dword [eax], 0 ; file size
jz .eof
add eax, 4
call fat_get_sector
mov ebx, edi
call hd_read
cmp [hd_error], 0
jnz .err
mov eax, [esp+28]
mov ecx, [eax]
sub ecx, 512
jae @f
lea edi, [edi+ecx+512]
neg ecx
push eax
xor eax, eax
rep stosb
pop eax
@@:
mov [eax], ecx
mov edx, [eax+8]
inc edx
cmp edx, [SECTORS_PER_CLUSTER]
jb @f
push eax
mov eax, [eax+4]
call get_FAT
cmp [hd_error], 0
jnz .err
mov ecx, eax
pop eax
mov [eax+4], ecx
xor edx, edx
@@:
mov [eax+8], edx
popad
xor eax, eax
ret
.eof:
popad
mov eax, 6
ret
.err:
popad
mov eax, 11
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 [fat_type], 0
jnz @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}
/kernel/tags/kolibri0.6.3.0/fs/fs.inc
0,0 → 1,898
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 ;;
;; xx.04.2006 LFN support - diamond ;;
;; 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
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 = 1 ; write file /RamDisk/First 33 /HardDisk/First 56
; eax = 4 ; makedir
; eax = 5 ; rename file/directory
; 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 [eax+0],5 ; RENAME - dont care about read&write blocks
je fs_read
cmp dword [eax+0],4 ; MAKEDIR - dont care about read&write blocks
je fs_read
 
cmp dword [0x3000],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:
 
cmp dword [esp+20],1 ; WRITE
jne fs_noramdisk_write
 
mov eax,[esp+4] ; fname
add eax,2*12+1
mov ebx,[esp+8] ; buffer
mov ecx,[esp+12] ; count to write
mov edx,0 ; create new
call filesave
 
; eax=0 ok - eax=1 not enough free space
 
jmp file_system_return
 
fs_noramdisk_write:
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:
 
cmp dword [esp+20],1 ; WRITE
jne fs_noflpdisk_write
 
mov eax,[esp+4] ; fname
add eax,2*12+1
mov ebx,[esp+8] ; buffer
mov ecx,[esp+12] ; count to write
mov edx,0 ; create new
call floppy_filesave
 
; eax=0 ok - eax=1 not enough free space
 
jmp file_system_return
 
fs_noflpdisk_write:
 
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 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 [0xfe10], eax ; entries in hd cache
mov edx,0x40002
search_partition_array:
mov bl,[edx]
movzx ebx,bl
add eax,ebx
inc edx
loop search_partition_array
sub eax,ebx
add eax,[fat32part]
dec eax
xor edx,edx
imul eax,100
add eax,0x4000a
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:
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],'/'
 
jmp file_system_return
 
fs_noharddisk_read:
 
 
cmp dword [esp+20],1 ; WRITE
jne fs_noharddisk_write
 
mov eax,[esp+0] ; /fname
mov byte [eax],0 ; path to asciiz
inc eax ; filename start
 
mov ebx,[esp+12] ; count to write
mov ecx,[esp+8] ; buffer
mov edx,[esp+4]
add edx,12*2 ; path start
 
call file_write
 
mov edi,[esp+0]
mov byte [edi],'/'
 
; eax=0 ok - eax=1 not enough free space
 
jmp file_system_return
 
 
fs_noharddisk_write:
 
cmp dword [esp+20],4 ; MAKEDIR
jne fs_noharddisk_makedir
 
mov eax,[esp+0] ; /dirname
mov byte [eax],0 ; path to asciiz
inc eax ; filename start
mov edx,[esp+4]
add edx,12*2 ; path start
 
call makedir
 
mov edi,[esp+0]
mov byte [edi],'/'
 
jmp file_system_return
 
fs_noharddisk_makedir:
 
cmp dword [esp+20],5 ; RENAME
jne fs_noharddisk_rename
 
mov edi,[esp+0] ; start of source file name
add edi,12+1 ; continue after name
call expand_pathz ; convert destination name
 
mov eax,[edi+1]
cmp eax,'HD '
je fs_rename_test1
cmp eax,'HARD'
jne fs_rename_error
 
fs_rename_test1:
mov eax,[edi+1+12]
cmp eax,'1 '
je fs_rename_start
cmp eax,'FIRS'
jne fs_rename_error
 
fs_rename_start:
mov byte [ebx],0 ; path to asciiz
inc ebx ; filename start
add edi,12*2 ; path start
cmp byte [ebx],0
je fs_rename_error
cmp byte [ebx],32
je fs_rename_error
 
mov eax,[esp+0] ; /filename
mov byte [eax],0 ; path to asciiz
inc eax ; filename start
mov edx,[esp+4]
add edx,12*2 ; path start
 
call rename
 
mov edi,[esp+0]
mov byte [edi],'/'
 
jmp file_system_return
 
fs_rename_error:
mov eax,4 ; partition not defined at hd
jmp file_system_return
 
fs_noharddisk_rename:
 
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,0x100000
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 err
mov bx,cx
shl cx,1
jc err
shl cx,1
jc err
add cx,bx
jc err
cbw
add cx,ax
jc err
i3:
inc edi
jmp i1
i_exit:
mov ax,cx
clc
i4:
movzx eax,ax
pop edi
pop dx
pop cx
pop bx
ret
 
err:
stc
jmp i4
 
partition_string: dd 0
db 32
/kernel/tags/kolibri0.6.3.0/fs/fs_lfn.inc
0,0 → 1,663
; 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
endg
 
file_system_lfn:
; in: eax->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 - not implemented yet
 
add eax, std_application_base_address
; parse file name
xchg ebx, eax
lea esi, [ebx+20]
mov ebp, esi ; for 'start app' function full path must be known
lodsb
test al, al
jnz @f
mov esi, [esi]
add esi, std_application_base_address
mov ebp, esi
lodsb
@@:
cmp al, '/'
jz @f
.notfound:
mov dword [esp+36], 5 ; file not found
ret
@@:
cmp byte [esi], 0
jz .rootdir
mov edi, rootdirs-8
xor ecx, ecx
push esi
.scan1:
pop esi
add edi, ecx
scasd
scasd
mov cl, byte [edi]
jecxz .notfound
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:
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
mov esi, [edi+4]
; ebx=flags, [esp]=first block, ebp=number of blocks, edx=return area, esi='Next' handler
mov edi, edx
mov ecx, 32/4
rep stosd
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
mov ecx, 40/4-2
rep stosd
pop eax
push eax edx
; convert number in eax to decimal UNICODE string
push edi
push -'0'
mov cl, 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 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 [esp+36], eax
mov [esp+24], ebx
ret
; directory /
.rootdir:
cmp dword [ebx], 1 ; read folder?
jz .readroot
.access_denied:
mov dword [esp+36], 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
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], 1 ; 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:
pop eax
mov ebx, [edx+4]
xor eax, eax
dec ebp
js @f
mov al, ERROR_END_OF_FILE
@@:
mov [esp+36], eax
mov [esp+24], ebx
ret
 
.found1:
pop eax
cmp byte [esi], 0
jz .maindir
; 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 .notfound
imul ecx, 10
add ecx, eax
jmp @b
.done1:
test ecx, ecx
jz .notfound
test al, al
jnz @f
dec esi
@@:
; 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
; out: [esp+36]=image of eax, [esp+24]=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 [esp+36], eax
mov [esp+24], ebx
ret
.not_impl:
mov dword [esp+36], 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 fs_RamdiskExecute
dd fs_RamdiskDelete
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 [esp+36], eax
mov [esp+24], 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 fs_FloppyExecute
dd fs_FloppyDelete
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 .nf
cmp cl, [0x40001+eax]
jbe @f
.nf:
call free_hd_channel
and [hd1_status], 0
mov dword [esp+36], 5 ; not found
ret
@@:
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 [esp+36], eax
mov [esp+24], ebx
ret
.not_impl:
call free_hd_channel
and [hd1_status], 0
mov dword [esp+36], 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 fs_HdExecute
dd fs_HdDelete
fs_NumHdServices = ($ - fs_HdServices)/4
 
;*******************************************************
fs_OnCd0:
call reserve_cd
mov [ChannelNumber],1
mov [DiskNumber],0
push 6
jmp fs_OnCd
fs_OnCd1:
call reserve_cd
mov [ChannelNumber],1
mov [DiskNumber],1
push 4
jmp fs_OnCd
fs_OnCd2:
call reserve_cd
mov [ChannelNumber],2
mov [DiskNumber],0
push 2
jmp fs_OnCd
fs_OnCd3:
call reserve_cd
mov [ChannelNumber],2
mov [DiskNumber],1
push 0
fs_OnCd:
call reserve_cd_channel
pop eax
mov [hdpos], eax
cmp ecx, 0x100
jae .nf
push ecx ebx
mov cl,al
mov bl,[0x40001]
shr bl,cl
test bl,2
pop ebx ecx
 
jnz @f
.nf:
call free_cd_channel
and [cd_status], 0
mov dword [esp+36], 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 [esp+36], eax
mov [esp+24], ebx
ret
.not_impl:
call free_cd_channel
and [cd_status], 0
mov dword [esp+36], 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 fs_CdExecute
fs_NumCdServices = ($ - fs_CdServices)/4
 
;*******************************************************
 
fs_HasRamdisk:
mov al, 1 ; we always have ramdisk
ret
 
fs_HasFloppy:
cmp byte [0x40000], 0
setnz al
ret
 
fs_HasHd0:
mov al, [0x40001]
and al, 11000000b
cmp al, 01000000b
setz al
ret
fs_HasHd1:
mov al, [0x40001]
and al, 00110000b
cmp al, 00010000b
setz al
ret
fs_HasHd2:
mov al, [0x40001]
and al, 00001100b
cmp al, 00000100b
setz al
ret
fs_HasHd3:
mov al, [0x40001]
and al, 00000011b
cmp al, 00000001b
setz al
ret
 
;*******************************************************
fs_HasCd0:
mov al, [0x40001]
and al, 11000000b
cmp al, 10000000b
setz al
ret
fs_HasCd1:
mov al, [0x40001]
and al, 00110000b
cmp al, 00100000b
setz al
ret
fs_HasCd2:
mov al, [0x40001]
and al, 00001100b
cmp al, 00001000b
setz al
ret
fs_HasCd3:
mov al, [0x40001]
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 (([0x40000] and 0xF0) != 0) and /fd/2 iff (([0x40000] and 0x0F) != 0)
test byte [0x40000], 0xF0
jz .no1
test eax, eax
jnz .no1
inc eax
ret ; CF cleared
.no1:
test byte [0x40000], 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 [0x40002+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
;*******************************************************
 
/kernel/tags/kolibri0.6.3.0/fs/iso9660.inc
0,0 → 1,823
 
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
 
CDDataBuf equ 0x7000
 
reserve_cd:
 
cli
cmp [cd_status],0
je reserve_ok2
 
sti
call change_task
jmp reserve_cd
 
reserve_ok2:
 
push eax
mov eax,[0x3000]
shl eax,5
mov eax,[eax+0x3000+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
cd_status dd 0
 
;----------------------------------------------------------------
;
; 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
; äèðåêòîðèÿ çàêîí÷èëàñü?
cmp eax,0
ja .read_to_buffer
mov edi,[cd_counter_block]
mov [edx+8],edi
mov edi,[ebx]
sub [edx+4],edi
pop ecx edi
mov ebx, [edx+4]
mov eax,ERROR_SUCCESS
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 al
shl eax,1
; ýòî êàòàëîã?
test [ebp-8],byte 2
jz .file
inc al
.file:
; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò
; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì
shl eax,3
; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå)
test [ebp-8],byte 1
jz .hidden
inc al
.hidden:
shl eax,1
; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD
inc al
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 ebp
call cd_find_lfn
pushfd
cmp [DevErrorCode], 0
jz @f
popfd
pop ebp edi
mov eax, 11
ret
@@:
popfd
jnc @f
pop ebp edi
mov eax, ERROR_FILE_NOT_FOUND
ret
@@:
 
mov edi, edx
call cd_get_parameters_of_file_1
and dword [edi+4], 0
pop ebp edi
xor eax, eax
ret
 
;----------------------------------------------------------------
;
; fs_CdExecute - LFN variant for executing from CD
;
; esi points to hd filename (e.g. 'dir1/name')
; ebp points to full filename (e.g. '/hd0/1/dir1/name')
; dword [ebx] = flags
; dword [ebx+4] = cmdline
;
; ret ebx,edx destroyed
; eax > 0 - PID, < 0 - error
;
;--------------------------------------------------------------
fs_CdExecute:
mov edx, [ebx]
mov ebx, [ebx+4]
test ebx, ebx
jz @f
add ebx, std_application_base_address
@@:
 
;----------------------------------------------------------------
;
; fs_CdExecute.flags - second entry
;
; esi points to floppy filename (kernel address)
; ebp points to full filename
; edx flags
; ebx cmdline (kernel address)
;
; ret eax > 0 - PID, < 0 - error
;
;--------------------------------------------------------------
 
.flags:
cmp byte [esi], 0
jnz @f
; cannot execute root!
mov eax, -ERROR_ACCESS_DENIED
ret
@@:
push edi
call cd_find_lfn
jnc .found
pop edi
mov eax, -ERROR_FILE_NOT_FOUND
cmp [DevErrorCode], 0
jz @f
mov al, -11
@@:
ret
.found:
mov edi,[cd_current_pointer_of_input]
mov eax,[edi+2]
push 0
push eax
push dword [edi+10] ; size
push .DoRead
call fs_execute
add esp, 16
pop edi
ret
 
.DoRead:
; read next block
; in: eax->parameters, edi->buffer
; out: eax = error code
pushad
cmp dword [eax], 0 ; file size
jz .eof
cmp [eax+8],dword 0
jne @f
mov ecx,[eax+4]
inc dword [eax+4]
mov [CDSectorAddress],ecx
mov [CDDataBuf_pointer],CDDataBuf ;edi
call ReadCDWRetr
cmp [DevErrorCode], 0
jnz .err
@@:
push esi edi ecx
mov esi,512
imul esi,[eax+8]
add esi,CDDataBuf
mov ecx,512/4
cld
rep movsd
pop ecx edi esi
 
mov eax, [esp+28]
mov ecx, [eax]
sub ecx, 512
jae @f
lea edi, [edi+ecx+512]
neg ecx
push eax
xor eax, eax
rep stosb
pop eax
@@:
mov [eax], ecx
mov edx, [eax+8]
inc edx
cmp edx, 4 ; 2048/512=4
jb @f
xor edx, edx
@@:
mov [eax+8], edx
popad
xor eax, eax
ret
.eof:
popad
mov eax, 6
ret
.err:
popad
mov eax, 11
ret
 
cd_find_lfn:
; in: esi->name
; out: CF=1 - file not found
; else CF=0 and [cd_current_pointer_of_input] direntry
push eax esi
; 16 ñåêòîð íà÷àëî íàáîðà äåñêðèïòîðîâ òîìîâ
mov [CDSectorAddress],dword 15
.start:
inc dword [CDSectorAddress]
mov [CDDataBuf_pointer],CDDataBuf
call ReadCDWRetr
cmp [DevErrorCode],0
jne .access_denied
; ïðîâåðêà íà âøèâîñòü
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
call cd_find_name_in_buffer
jnc .found
sub eax,2048
; äèðåêòîðèÿ çàêîí÷èëàñü?
cmp eax,0
ja .read_to_buffer
; íåò èñêîìîãî ýëåìåíòà öåïî÷êè
.access_denied:
pop esi eax
stc
ret
; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí
.found:
; êîíåö ïóòè ôàéëà
cmp byte [esi-1], 0
jz .done
mov eax,[cd_current_pointer_of_input]
add eax,2
mov eax,[eax]
mov [CDSectorAddress],eax ; íà÷àëî äèðåêòîðèè
add eax,8
mov eax,[eax] ; ðàçìåð äèðåêòîðèè
jmp .mainloop
; óêàçàòåëü ôàéëà íàéäåí
.done:
pop esi eax
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]
cmp eax,0 ; âõîäû çàêîí÷èëèñü?
je .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 ax
call char_todown
call ansi2uni_char
xchg ah,al
cld
scasw
pop ax
je .coincides
call char_toupper
call ansi2uni_char
xchg ah,al
cld
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
/kernel/tags/kolibri0.6.3.0/fs/part_set.inc
0,0 → 1,351
;*************************************************************
;* 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 *
;*************************************************************
 
align 4
;******************************************************
; Please do not change this place - variables in text
; Mario79
; START place
;******************************************************
PARTITION_START dd 0x3f
PARTITION_END dd 0
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
 
fat_type db 0 ; 0=none, 16=fat16, 32=fat32
;***************************************************************************
; End place
; Mario79
;***************************************************************************
 
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
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 ; PARTITION2 ; PARTITION3 ; PARTITION4
;==========================================================
; fat16/32 +-- fat16/32 +-- fat16/32 +-- fat16/32 +--
; extended --+ extended --+ extended --+ extended --+
; 0 0 0 0
; 0 0 0 0
; Notes:
; - extended partition need to be in second entry on table
; - it will skip over removed partitions
 
set_FAT32_variables:
mov [0xfe10],dword 0 ; entries in hd cache
mov [problem_partition],0
call reserve_hd1
call clear_hd_cache
 
cmp dword [hdpos],0
je problem_hd
 
pushad
xor ecx,ecx ; partition count
mov edx,-1 ; flag for partition
xor eax,eax ; read MBR
xor ebp,ebp ; extended partition start
 
new_partition:
test ebp,ebp ; is there extended partition?
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
cmp dword [ebx+0x1be+0xc],0 ; skip over empty partition
jz next_partition
 
push eax
mov al,[ebx+0x1be+4] ; get primary partition type
call scan_partition_types
pop eax
jnz next_primary_partition ; no. skip over
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition ; no
 
mov edx,eax ; start sector
add edx,[ebx+0x1be+8] ; add relative start
next_primary_partition:
push eax
mov al,[ebx+0x1be+4+16] ; get primary partition type
call scan_partition_types
pop eax
jnz next_primary_partition_1 ; no. skip over
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition_1 ; no
 
mov edx,eax ; start sector
add edx,[ebx+0x1be+8+16] ; add relative start
 
next_primary_partition_1:
push eax
mov al,[ebx+0x1be+4+16+16] ; get primary partition type
call scan_partition_types
pop eax
jnz next_primary_partition_2 ; no. skip over
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_primary_partition_2 ; no
 
mov edx,eax ; start sector
add edx,[ebx+0x1be+8+16+16] ; add relative start
 
next_primary_partition_2:
push eax
mov al,[ebx+0x1be+4+16+16+16] ; get primary partition type
call scan_partition_types
pop eax
jnz next_partition ; no. skip over
 
inc ecx
cmp ecx,[fat32part] ; is it wanted partition?
jnz next_partition ; no
 
mov edx,eax ; start sector
add edx,[ebx+0x1be+8+16+16+16] ; add relative start
 
next_partition:
push eax
mov al,[ebx+0x1be+4] ; get extended partition type
call scan_extended_types
pop eax
jnz next_partition_1
 
mov eax,[ebx+0x1be+8] ; add relative start
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
 
next_partition_1:
push eax
mov al,[ebx+0x1be+4+16] ; get extended partition type
call scan_extended_types
pop eax
jnz next_partition_2
 
mov eax,[ebx+0x1be+8+16] ; add relative start
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
 
next_partition_2:
push eax
mov al,[ebx+0x1be+4+16+16] ; get extended partition type
call scan_extended_types
pop eax
jnz next_partition_3
 
mov eax,[ebx+0x1be+8+16+16] ; add relative start
test eax,eax ; is there extended partition?
jnz new_partition ; yes. read it
next_partition_3:
push eax
mov al,[ebx+0x1be+4+16+16+16] ; get extended partition type
call scan_extended_types
pop eax
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_partition ; 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
 
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:
popad
 
problem_hd:
mov [fat_type],0
mov [hd1_status],0 ; free
mov [problem_partition],1
ret
 
hd_and_partition_ok:
mov eax,edx
mov [PARTITION_START],eax
 
mov [hd_setup],1
mov ebx,buffer
call hd_read ; read boot sector of partition
cmp [hd_error],0
jne problem_fat_dec_count
 
mov [hd_setup],0
 
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
mov [SECTORS_PER_CLUSTER],eax
 
movzx ecx,word [ebx+0xb] ; bytes per sector
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
 
; 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
 
popad
 
mov [fatRESERVED],0x0FFFFFF6
mov [fatBAD],0x0FFFFFF7
mov [fatEND],0x0FFFFFF8
mov [fatMASK],0x0FFFFFFF
mov [fat_type],32 ; Fat32
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 [fat_type],16 ; Fat16
mov [hd1_status],0 ; free
ret
/kernel/tags/kolibri0.6.3.0/fs/fs_phys.inc
0,0 → 1,111
hd_phys_read:
;eax - sector number
;ebx - destination
pushad
call wait_for_hd_idle
popad
push edx
push eax
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al
inc edx
inc eax
out dx,al
inc edx
;write sector number.
mov eax,[esp]
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] ;+0 or +16
or al,32+64+128
out dx,al
inc edx
mov al,0x20
out dx,al
sti
call wait_for_sector_buffer
cmp [hd_error],0
jnz hd_read_error
cli
push edi
mov edi,ebx
mov ecx,256
mov edx,[hdbase]
cld
rep insw
pop edi
sti
pop edx
pop eax
ret
hd_phys_write:
;eax - sector number
;ebx - destination
cmp eax,[partition_start]
jb .ret
cmp eax,[partition_end]
ja .ret
pushad
call wait_for_hd_idle
popad
push edx
push eax
cli
xor eax,eax
mov edx,[hdbase]
inc edx
out dx,al
inc edx
inc eax
out dx,al
;write sector number
inc edx
mov eax,[esp]
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] ;+0 or +16
or al,32+64+128
out dx,al
inc edx
mov al,0x30
out dx,al
sti
call wait_for_sector_buffer
cmp [hd_error],0
jnz hd_write_error
cli
push esi
mov esi,ebx
mov ecx,256
mov edx,[hdbase]
cld
rep outsw
pop esi
sti
pop edx
pop eax
.ret:
ret
/kernel/tags/kolibri0.6.3.0/proc32.inc
0,0 → 1,268
 
; Macroinstructions for defining and calling procedures
 
macro stdcall proc,[arg] ; directly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call proc }
 
macro invoke proc,[arg] ; indirectly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call [proc] }
 
macro ccall proc,[arg] ; directly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call proc
if size@ccall
add esp,size@ccall
end if }
 
macro cinvoke proc,[arg] ; indirectly call CDECL procedure
{ common
size@ccall = 0
if ~ arg eq
reverse
pushd arg
size@ccall = size@ccall+4
common
end if
call [proc]
if size@ccall
add esp,size@ccall
end if }
 
macro proc [args] ; define procedure
{ common
match name params, args>
\{ define@proc name,<params \} }
 
prologue@proc equ prologuedef
 
macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,localbytes
end if
end if
irps reg, reglist \{ push reg \} }
 
epilogue@proc equ epiloguedef
 
macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if flag and 10000b
retn
else
retn parmbytes
end if }
 
macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
virtual at ebp+8
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $ - (ebp+8)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
macro locals
\{ virtual at ebp-localbytes+current
macro label . \\{ deflocal@proc .,:, \\}
struc db [val] \\{ \common deflocal@proc .,db,val \\}
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
macro endl
\{ purge label
restruc db,dw,dp,dd,dt,dq
restruc rb,rw,rp,rd,rt,rq
restruc byte,word,dword,pword,tword,qword
current = $-(ebp-localbytes)
end virtual \}
macro ret operand
\{ match any, operand \\{ retn operand \\}
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs>
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2
end if \} }
 
macro defargs@proc [arg]
{ common
if ~ arg eq
forward
local ..arg,current@arg
match argname:type, arg
\{ current@arg equ argname
label ..arg type
argname equ ..arg
if dqword eq type
dd ?,?,?,?
else if tbyte eq type
dd ?,?,?
else if qword eq type | pword eq type
dd ?,?
else
dd ?
end if \}
match =current@arg,current@arg
\{ current@arg equ arg
arg equ ..arg
..arg dd ? \}
common
args@proc equ current@arg
forward
restore current@arg
common
end if }
 
macro deflocal@proc name,def,[val]
{ common
match vars, all@vars \{ all@vars equ all@vars, \}
all@vars equ all@vars name
forward
local ..var,..tmp
..var def val
match =?, val \{ ..tmp equ \}
match any =dup (=?), val \{ ..tmp equ \}
match tmp : value, ..tmp : val
\{ tmp: end virtual
initlocal@proc ..var,def value
virtual at tmp\}
common
match first rest, ..var, \{ name equ first \} }
 
macro initlocal@proc name,def
{ virtual at name
def
size@initlocal = $ - name
end virtual
position@initlocal = 0
while size@initlocal > position@initlocal
virtual at name
def
if size@initlocal - position@initlocal < 2
current@initlocal = 1
load byte@initlocal byte from name+position@initlocal
else if size@initlocal - position@initlocal < 4
current@initlocal = 2
load word@initlocal word from name+position@initlocal
else
current@initlocal = 4
load dword@initlocal dword from name+position@initlocal
end if
end virtual
if current@initlocal = 1
mov byte [name+position@initlocal],byte@initlocal
else if current@initlocal = 2
mov word [name+position@initlocal],word@initlocal
else
mov dword [name+position@initlocal],dword@initlocal
end if
position@initlocal = position@initlocal + current@initlocal
end while }
 
macro endp
{ purge ret,locals,endl
finish@proc
purge finish@proc
restore regs@proc
match all,args@proc \{ restore all \}
restore args@proc
match all,all@vars \{ restore all \} }
 
macro local [var]
{ common
locals
forward done@local equ
match varname[count]:vartype, var
\{ match =BYTE, vartype \\{ varname rb count
restore done@local \\}
match =WORD, vartype \\{ varname rw count
restore done@local \\}
match =DWORD, vartype \\{ varname rd count
restore done@local \\}
match =PWORD, vartype \\{ varname rp count
restore done@local \\}
match =QWORD, vartype \\{ varname rq count
restore done@local \\}
match =TBYTE, vartype \\{ varname rt count
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
rq count+count
restore done@local \\}
match , done@local \\{ virtual
varname vartype
end virtual
rb count*sizeof.\#vartype
restore done@local \\} \}
match :varname:vartype, done@local:var
\{ match =BYTE, vartype \\{ varname db ?
restore done@local \\}
match =WORD, vartype \\{ varname dw ?
restore done@local \\}
match =DWORD, vartype \\{ varname dd ?
restore done@local \\}
match =PWORD, vartype \\{ varname dp ?
restore done@local \\}
match =QWORD, vartype \\{ varname dq ?
restore done@local \\}
match =TBYTE, vartype \\{ varname dt ?
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
dq ?,?
restore done@local \\}
match , done@local \\{ varname vartype
restore done@local \\} \}
match ,done@local
\{ var
restore done@local \}
common
endl }
/kernel/tags/kolibri0.6.3.0/hid/keyboard.inc
0,0 → 1,294
;// 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[0x3004] ; top window process
movzx eax,word[0xC400+eax*2]
shl eax,8
mov al,[0x80000+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
@@:
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]
@@:
mov bh, 0
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
jmp .dowrite
.scancode:
mov bl, ch
.dowrite:
movzx eax,byte[0xF400]
cmp al,120
jae .exit.irq1
inc eax
mov [0xF400],al
mov [0xF400+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 ]
/kernel/tags/kolibri0.6.3.0/hid/m_com1.inc
0,0 → 1,130
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà
MouseByteNumber DB 0
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ
FirstByte DB 0
SecondByte DB 0
ThirdByte DB 0
timer_ticks_com dd 0
;***************************************
;* ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÌÛØÈ *
;***************************************
check_mouse_data_com1:
; cmp [com1_mouse_detected],0
; je @@EndMouseInterrupt
; Ïðîâåðèòü íàëè÷èå äàííûõ
mov DX,3F8h ;[COMPortBaseAddr]
add DX,5 ;xFDh
in AL,DX
test AL,1 ;Äàííûå ãîòîâû?
jz @@Error
; Ââåñòè äàííûå
mov DX,3F8h ;[COMPortBaseAddr] ;xF8h
in AL,DX
; Ñáðîñèòü ñòàðøèé íåçíà÷àùèé áèò
and AL,01111111b
 
; Îïðåäåëèòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà
cmp [MouseByteNumber],0
je @@FirstByte
cmp [MouseByteNumber],1
je @@SecondByte
cmp [MouseByteNumber],2
je @@ThirdByte
jmp @@Error
 
; Ñîõðàíèòü ïåðâûé áàéò äàííûõ
@@FirstByte:
test AL,1000000b ;Ïåðâûé áàéò ïîñûëêè?
jz @@Error
mov [FirstByte],AL
inc [MouseByteNumber] ;óâåëè÷èòü ñ÷åò÷èê
jmp @@EndMouseInterrupt
; Ñîõðàíèòü âòîðîé áàéò äàííûõ
@@SecondByte:
test AL,1000000b
jnz @@Error
mov [SecondByte],AL
inc [MouseByteNumber] ;óâåëè÷èòü ñ÷åò÷èê
jmp @@EndMouseInterrupt
; Ñîõðàíèòü òðåòèé áàéò äàííûõ
@@ThirdByte:
test AL,1000000b
jnz @@Error
mov [ThirdByte],AL ;óâåëè÷èòü ñ÷åò÷èê
mov [MouseByteNumber],0
; (Ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ).
; Çàïèñàòü íîâîå çíà÷åíèå ñîñòîÿíèÿ êíîïîê ìûøè
mov al,[FirstByte] ;[0xfb01]
mov ah,al
shr al,3
and al,2
shr ah,5
and ah,1
add al,ah
mov [0xfb40],al
mov [mouse_active],1
; Ïðèáàâèòü ïåðåìåùåíèå ïî X ê êîîðäèíàòå X
mov AL,[FirstByte]
shl AL,6
or AL,[SecondByte]
cbw
call mouse_acceleration_com1
add AX,[0xFB0A] ;[XCoordinate]
; Êóðñîð íå äîëæåí âûõîäèòü çà ëåâóþ èëè
; ïðàâóþ ãðàíèöó ýêðàíà
js @@X1
cmp AX,[0xFE00] ;ScreenLength
jb @@X2
; Óñòàíîâèòü êîîðäèíàòó X ïî ïðàâîé ãðàíèöå
mov AX,[0xFE00] ;ScreenLength-1
dec ax
jmp @@X2
@@X1:
; Óñòàíîâèòü êîîðäèíàòó X ïî ëåâîé ãðàíèöå
xor AX,AX
@@X2:
mov [0xFB0A],AX ;[XCoordinate]
; Ïðèáàâèòü ïåðåìåùåíèå ïî Y ê êîîðäèíàòå Y
mov AL,[FirstByte]
and AL,00001100b
shl AL,4
or AL,[ThirdByte]
cbw
call mouse_acceleration_com1
add AX,[0xFB0C] ;[YCoordinate]
; Êóðñîð íå äîëæåí âûõîäèòü çà âåðõíþþ èëè
; íèæíþþ ãðàíèöó ýêðàíà
js @@Y1
cmp AX,[0xFE04] ;ScreenHeigth
jb @@Y2
; Óñòàíîâèòü êîîðäèíàòó X ïî íèæíåé ãðàíèöå
mov AX,[0xFE04] ;ScreenHeigth-1
dec ax
jmp @@Y2
@@Y1:
; Óñòàíîâèòü êîîðäèíàòó X ïî âåðõíåé ãðàíèöå
xor AX,AX
@@Y2:
mov [0xFB0C],AX ;[YCoordinate]
mov eax,[timer_ticks]
mov [timer_ticks_com],eax
jmp @@EndMouseInterrupt
 
@@Error:
; Ïðîèçîøåë ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò
; ìûøè, îáíóëèòü ñ÷åò÷èê áàéòîâ ïàêåòà äàííûõ
mov [MouseByteNumber],0
@@EndMouseInterrupt:
call ready_for_next_irq
ret
 
mouse_acceleration_com1:
push eax
mov eax,[timer_ticks]
sub eax,[timer_ticks_com]
cmp eax,[mouse_delay]
pop eax
ja @f
imul ax,[mouse_speed_factor]
@@:
ret
/kernel/tags/kolibri0.6.3.0/hid/m_com2.inc
0,0 → 1,130
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà
MouseByteNumber_1 DB 0
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ
FirstByte_1 DB 0
SecondByte_1 DB 0
ThirdByte_1 DB 0
timer_ticks_com_1 dd 0
;***************************************
;* ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÌÛØÈ *
;***************************************
check_mouse_data_com2:
; cmp [com2_mouse_detected],0
; je @@EndMouseInterrupt_1
; Ïðîâåðèòü íàëè÷èå äàííûõ
mov DX,2F8h ;[COMPortBaseAddr]
add DX,5 ;xFDh
in AL,DX
test AL,1 ;Äàííûå ãîòîâû?
jz @@Error_1
; Ââåñòè äàííûå
mov DX,2F8h ;[COMPortBaseAddr] ;xF8h
in AL,DX
; Ñáðîñèòü ñòàðøèé íåçíà÷àùèé áèò
and AL,01111111b
 
; Îïðåäåëèòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà
cmp [MouseByteNumber_1],0
je @@FirstByte_1
cmp [MouseByteNumber_1],1
je @@SecondByte_1
cmp [MouseByteNumber_1],2
je @@ThirdByte_1
jmp @@Error_1
 
; Ñîõðàíèòü ïåðâûé áàéò äàííûõ
@@FirstByte_1:
test AL,1000000b ;Ïåðâûé áàéò ïîñûëêè?
jz @@Error_1
mov [FirstByte_1],AL
inc [MouseByteNumber_1] ;óâåëè÷èòü ñ÷åò÷èê
jmp @@EndMouseInterrupt_1
; Ñîõðàíèòü âòîðîé áàéò äàííûõ
@@SecondByte_1:
test AL,1000000b
jnz @@Error_1
mov [SecondByte_1],AL
inc [MouseByteNumber_1] ;óâåëè÷èòü ñ÷åò÷èê
jmp @@EndMouseInterrupt_1
; Ñîõðàíèòü òðåòèé áàéò äàííûõ
@@ThirdByte_1:
test AL,1000000b
jnz @@Error_1
mov [ThirdByte_1],AL ;óâåëè÷èòü ñ÷åò÷èê
mov [MouseByteNumber_1],0
; (Ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ).
; Çàïèñàòü íîâîå çíà÷åíèå ñîñòîÿíèÿ êíîïîê ìûøè
mov al,[FirstByte_1] ;[0xfb01]
mov ah,al
shr al,3
and al,2
shr ah,5
and ah,1
add al,ah
mov [0xfb40],al
mov [mouse_active],1
; Ïðèáàâèòü ïåðåìåùåíèå ïî X ê êîîðäèíàòå X
mov AL,[FirstByte_1]
shl AL,6
or AL,[SecondByte_1]
cbw
call mouse_acceleration_com2
add AX,[0xFB0A] ;[XCoordinate]
; Êóðñîð íå äîëæåí âûõîäèòü çà ëåâóþ èëè
; ïðàâóþ ãðàíèöó ýêðàíà
js @@X1_1
cmp AX,[0xFE00] ;ScreenLength
jb @@X2_1
; Óñòàíîâèòü êîîðäèíàòó X ïî ïðàâîé ãðàíèöå
mov AX,[0xFE00] ;ScreenLength-1
dec ax
jmp @@X2_1
@@X1_1:
; Óñòàíîâèòü êîîðäèíàòó X ïî ëåâîé ãðàíèöå
xor AX,AX
@@X2_1:
mov [0xFB0A],AX ;[XCoordinate]
; Ïðèáàâèòü ïåðåìåùåíèå ïî Y ê êîîðäèíàòå Y
mov AL,[FirstByte_1]
and AL,00001100b
shl AL,4
or AL,[ThirdByte_1]
cbw
call mouse_acceleration_com2
add AX,[0xFB0C] ;[YCoordinate]
; Êóðñîð íå äîëæåí âûõîäèòü çà âåðõíþþ èëè
; íèæíþþ ãðàíèöó ýêðàíà
js @@Y1_1
cmp AX,[0xFE04] ;ScreenHeigth
jb @@Y2_1
; Óñòàíîâèòü êîîðäèíàòó X ïî íèæíåé ãðàíèöå
mov AX,[0xFE04] ;ScreenHeigth-1
dec ax
jmp @@Y2_1
@@Y1_1:
; Óñòàíîâèòü êîîðäèíàòó X ïî âåðõíåé ãðàíèöå
xor AX,AX
@@Y2_1:
mov [0xFB0C],AX ;[YCoordinate]
mov eax,[timer_ticks]
mov [timer_ticks_com_1],eax
jmp @@EndMouseInterrupt_1
 
@@Error_1:
; Ïðîèçîøåë ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò
; ìûøè, îáíóëèòü ñ÷åò÷èê áàéòîâ ïàêåòà äàííûõ
mov [MouseByteNumber_1],0
@@EndMouseInterrupt_1:
call ready_for_next_irq
ret
 
mouse_acceleration_com2:
push eax
mov eax,[timer_ticks]
sub eax,[timer_ticks_com_1]
cmp eax,[mouse_delay]
pop eax
ja @f
imul ax,[mouse_speed_factor]
@@:
ret
/kernel/tags/kolibri0.6.3.0/hid/m_ps2.inc
0,0 → 1,170
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà
MouseByteNumber_2 DB 0
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ
FirstByte_2 DB 0
SecondByte_2 DB 0
ThirdByte_2 DB 0
timer_ticks_ps2 dd 0
 
;**************************************
;* ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÌÛØÈ PS/2 *
;**************************************
check_mouse_data_ps2:
cmp [ps2_mouse_detected],0
je @@EndMouseInterrupt_2
call Wait8042BufferEmpty ;î÷èñòêà áóôåðà
in AL,0x60 ;ïîëó÷èòü ñêýí-êîä
; Âûáèðàòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà
cmp [MouseByteNumber_2],0
je @@SaveFirstByte
cmp [MouseByteNumber_2],1
je @@SaveSecondByte
cmp [MouseByteNumber_2],2
je @@SaveThirdByte
jmp @@Error_2
; Çàïèñàòü ïåðâûé áàéò ïîñûëêè
@@SaveFirstByte:
test AL,1000b ;ïåðâûé áàéò ïîñûëêè?
jz @@Error_2 ;ñáîé ñèíõðîíèçàöèè
mov [FirstByte_2],AL
inc [MouseByteNumber_2]
jmp @@EndMouseInterrupt_2
; Çàïèñàòü âòîðîé áàéò ïîñûëêè
@@SaveSecondByte:
mov [SecondByte_2],AL
inc [MouseByteNumber_2]
jmp @@EndMouseInterrupt_2
; Çàïèñàòü òðåòèé áàéò ïîñûëêè
@@SaveThirdByte:
mov [ThirdByte_2],AL
mov [MouseByteNumber_2],0
; (ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ)
; Çàïèñàòü íîâîå çíà÷åíèå áàéòà ñîñòîÿíèÿ êíîïîê
mov al,[FirstByte_2] ;[0xfb01]
and eax,3
mov [0xfb40],al
mov [mouse_active],1
; Âû÷èñëèòü íîâóþ X-êîîðäèíàòó êóðñîðà
; Çàíåñòè â AX ïåðåìåùåíèå ïî X
mov AH,0 ;äóáëèðóåì çíàê âî âñå ðàçðÿäû AH
mov AL,[FirstByte_2]
test AL,10000b
jz @@M0
mov AH,0FFh
; Çàíåñòè â AL ìëàäøèé áàéò
@@M0:
mov AL,[SecondByte_2]
call mouse_acceleration_ps2
; Âû÷èñëèòü íîâîå çíà÷åíèå êîîðäèíàòû
; êóðñîðà ïî X
add AX,[0xFB0A] ;[XCoordinate]
cmp AX,0
jge @@M1
mov AX,0
jmp @@M2
@@M1:
cmp AX,[0xFE00] ;ScreenLength
jl @@M2
mov AX,[0xFE00] ;ScreenLength-1
dec ax
@@M2:
mov [0xFB0A],AX ;[XCoordinate]
 
; Âû÷èñëÿåì íîâóþ Y-êîîðäèíàòó êóðñîðà
; Çàíåñòè â AX ïåðåìåùåíèå ïî Y
mov AH,0 ;äóáëèðóåì çíàê âî âñå ðàçðÿäû AH
mov AL,[FirstByte_2]
test AL,100000b
jz @@M3
mov AH,0FFh
; Çàíåñòè â AL ìëàäøèé áàéò
@@M3:
mov AL,[ThirdByte_2]
call mouse_acceleration_ps2
; Âû÷èñëèòü íîâîå çíà÷åíèå êîîðäèíàòû êóðñîðà
; ïî Y (Y-êîîðäèíàòà ìûøè PS/2 íàïðàâëåíà
; ïðîòèâîïîëîæíî ýêðàííîé)
neg AX
add AX,[0xFB0C] ;[YCoordinate]
cmp AX,0
jge @@M4
mov AX,0
jmp @@M5
@@M4:
cmp AX,[0xFE04] ;ScreenHeigth
jl @@M5
mov AX,[0xFE04] ;ScreenHeigth-1
dec ax
@@M5:
mov [0xFB0C],AX ;[YCoordinate]
 
; Ïîêàçàòü êóðñîð â íîâîé ïîçèöèè
mov eax,[timer_ticks]
mov [timer_ticks_ps2],eax
jmp @@EndMouseInterrupt_2
 
; Îáíàðóæåí ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò ìûøè
@@Error_2:
mov [MouseByteNumber_2],0
; Íîðìàëüíîå çàâåðøåíèå ïðåðûâàíèÿ
@@EndMouseInterrupt_2:
call ready_for_next_irq_1
ret
 
mouse_acceleration_ps2:
push eax
mov eax,[timer_ticks]
sub eax,[timer_ticks_ps2]
cmp eax,[mouse_delay]
pop eax
ja @f
imul ax,[mouse_speed_factor]
@@:
ret
;***********************************************
;* ÎÆÈÄÀÍÈÅ Î×ÈÑÒÊÈ ÂÕÎÄÍÎÃÎ ÁÓÔÅÐÀ I8042 *
;* Ïðè âûõîäå èç ïðîöåäóðû: *
;* ôëàã ZF óñòàíîâëåí - íîðìàëüíîå çàâåðøåíèå, *
;* ôëàã ZF ñáðîøåí - îøèáêà òàéì-àóòà. *
;***********************************************
Wait8042BufferEmpty:
; push CX
; mov CX,0FFFFh ;çàäàòü ÷èñëî öèêëîâ îæèäàíèÿ
;@@kb:
; in AL,64h ;ïîëó÷èòü ñòàòóñ
; test AL,10b ;áóôåð i8042 ñâîáîäåí?
; loopnz @@kb ;åñëè íåò, òî öèêë
; pop CX
push ecx
xor ecx,ecx
@@:
in al,64h
test al,00000010b
loopnz @b
pop ecx
;Åñëè ïðè âûõîäå èç ïîäïðîãðàììû ñáðîøåí
;ôëàã ZF - îøèáêà
ret ;âîçâðàò â ïîäïðîãðàììó
 
;***************************************
;* ÎÆÈÄÀÍÈÅ ÏÎÑÒÓÏËÅÍÈß ÄÀÍÍÛÕ ÎÒ ÌÛØÈ *
;***************************************
WaitMouseData:
; push CX
; mov CX,0FFFFh ;çàäàòü ÷èñëî öèêëîâ îæèäàíèÿ
;@@mouse:
; in AL,64h ;îïðîñèòü ðåãèñòð ñòàòóñà
; test AL,100000b ;äàííûå ïîñòóïèëè?
; loopz @@mouse ;åñëè íåò, òî öèêë
; pop CX
push ecx
mov ECX,0FFFFh
@@:
in al,64h
test al,100000b
loopz @b
pop ecx
;Åñëè ïðè âûõîäå èç ïîäïðîãðàììû óñòàíîâëåí
;ôëàã ZF - îøèáêà
ret
 
/kernel/tags/kolibri0.6.3.0/hid/mousedrv.inc
0,0 → 1,331
; 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
 
mouse_delay dd 10
mouse_speed_factor dw 3
 
include 'm_ps2.inc'
include 'm_com1.inc'
include 'm_com2.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
pushad
xor ecx,ecx
xor edx,edx
align 4
mres:
movzx eax,word [0xfb4a]
movzx ebx,word [0xfb4c]
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:
pushad
; save & draw
mov [0xfb4a],ax
mov [0xfb4c],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 [0xfb30],ecx
pop ecx
mov eax,edx
shl eax,6
shl ecx,2
add eax,ecx
add eax,mouseunder
mov ebx,[0xfb30]
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,[0xf200] ; we have our str address
mov esi, edi
add esi, 16*24*3
push ecx
mov ecx, [0xfb30]
call combine_colors
mov [0xfb10], 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, [0xfb10]
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 [0xf204],dword 0
je @f
ret
@@:
pushad
cmp [0x3000],dword 1
je disable_m
mov edx,[0x3000]
shl edx,5
add edx,window_data
movzx eax, word [0xfb0a]
movzx ebx, word [0xfb0c]
mov ecx,[0xfe00]
inc ecx
imul ecx,ebx
add ecx,eax
add ecx, display_data
mov eax, [0x3000]
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,[0xfe00]
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,[0x3000]
shl edx,5
add edx,window_data
movzx eax, word [0xfb0a]
movzx ebx, word [0xfb0c]
mov ecx,[edx+0] ; mouse inside the area ?
add eax,14
cmp eax,ecx
jb no_mouse_disable
sub eax,14
add ecx,[edx+8]
cmp eax,ecx
jg no_mouse_disable
mov ecx,[edx+4]
add ebx,20
cmp ebx,ecx
jb no_mouse_disable
sub ebx,20
add ecx,[edx+12]
cmp ebx,ecx
jg no_mouse_disable
disable_m:
cmp dword [0xf204],dword 0
jne no_mouse_disable
cli
call draw_mouse_under
sti
mov [0xf204],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 [0xf204],dword 0 ; mouse visible ?
je chms00
mov [0xf204], dword 0
movzx ebx,word [0xfb0c]
movzx eax,word [0xfb0a]
cli
call save_draw_mouse
sti
nodmu2:
popad
ret
chms00:
movzx ecx,word [0xfb4a]
movzx edx,word [0xfb4c]
movzx ebx,word [0xfb0c]
movzx eax,word [0xfb0a]
cmp eax,ecx
jne redrawmouse
cmp ebx,edx
jne redrawmouse
jmp nodmp
redrawmouse:
cli
call draw_mouse_under
call save_draw_mouse
sti
nodmp:
popad
ret
 
/kernel/tags/kolibri0.6.3.0/hid/set_dtc.inc
0,0 → 1,191
;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:
mov ecx,eax
cli
mov al,0x0d
out 0x70,al
in al,0x71
bt ax,7
jnc bat_low
cmp ecx,2 ;day of week
jne nosetweek
test ebx,ebx ;test day of week
je wrongtime
cmp ebx,7
ja wrongtime
mov dx,0x70
call startstopclk
dec edx
mov al,6
out dx,al
inc edx
mov al,bl
out dx,al
jmp endsettime
nosetweek: ;set date
cmp ecx,1
jne nosetdate
cmp bl,0x99 ;test year
ja wrongtime
shl ebx,4
cmp bl,0x90
ja wrongtime
cmp bh,0x99 ;test month
ja wrongtime
shr ebx,4
test bh,bh
je wrongtime
cmp bh,0x12
ja wrongtime
shl ebx,8
bswap ebx ;ebx=00YYMMDD
test bl,bl ;test day
je wrongtime
shl ebx,4
cmp bl,0x90
ja wrongtime
shr ebx,4
cmp bh,2 ;February
jne testday
cmp bl,0x29
ja wrongtime
jmp setdate
testday:
cmp bh,8
jb testday1 ;Aug-Dec
bt bx,8
jnc days31
jmp days30
testday1:
bt bx,8 ;Jan-Jul ex.Feb
jnc days30
days31:
cmp bl,0x31
ja wrongtime
jmp setdate
days30:
cmp bl,0x30
ja wrongtime
setdate:
mov dx,0x70
call startstopclk
dec edx
mov al,7 ;set days
out dx,al
inc edx
mov al,bl
out dx,al
dec edx
mov al,8 ;set months
out dx,al
inc edx
mov al,bh
out dx,al
dec edx
mov al,9 ;set years
out dx,al
inc edx
shr ebx,8
mov al,bh
out dx,al
jmp endsettime
nosetdate: ;set time or alarm-clock
cmp ecx,3
ja wrongtime
cmp bl,0x23
ja wrongtime
cmp bh,0x59
ja wrongtime
shl ebx,4
cmp bl,0x90
ja wrongtime
cmp bh,0x92
ja wrongtime
shl ebx,4
bswap ebx ;00HHMMSS
cmp bl,0x59
ja wrongtime
shl ebx,4
cmp bl,0x90
ja wrongtime
shr ebx,4
mov dx,0x70
call startstopclk
dec edx
cmp ecx,3
je setalarm
xor eax,eax ;al=0-set seconds
out dx,al
inc edx
mov al,bl
out dx,al
dec edx
mov al,2 ;set minutes
out dx,al
inc edx
mov al,bh
out dx,al
dec edx
mov al,4 ;set hours
out dx,al
inc edx
shr ebx,8
mov al,bh
out dx,al
jmp endsettime
setalarm:
mov al,1 ;set seconds for al.
out dx,al
inc edx
mov al,bl
out dx,al
dec edx
mov al,3 ;set minutes for al.
out dx,al
inc edx
mov al,bh
out dx,al
dec edx
mov al,5 ;set hours for al.
out dx,al
inc edx
shr ebx,8
mov al,bh
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
mov [esp+36],dword 0
ret
bat_low:
sti
mov [esp+36],dword 2
ret
wrongtime:
sti
mov [esp+36],dword 1
ret
startstopclk:
mov al,0x0b
out dx,al
inc dx
in al,dx
btc ax,7
out dx,al
ret
/kernel/tags/kolibri0.6.3.0/kglobals.inc
0,0 → 1,59
;------------------------------------------------------------------
; 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
/kernel/tags/kolibri0.6.3.0/build_en.bat
0,0 → 1,5
@erase lang.inc
@echo lang fix en >lang.inc
@fasm kernel.asm kernel.mnt
@erase lang.inc
@pause
/kernel/tags/kolibri0.6.3.0/build_ge.bat
0,0 → 1,5
@erase lang.inc
@echo lang fix ge >lang.inc
@fasm kernel.asm kernel.mnt
@erase lang.inc
@pause
/kernel/tags/kolibri0.6.3.0/build_ru.bat
0,0 → 1,5
@erase lang.inc
@echo lang fix ru >lang.inc
@fasm kernel.asm kernel.mnt
@erase lang.inc
@pause
/kernel/tags/kolibri0.6.3.0/detect/dev_hdcd.inc
0,0 → 1,357
;******************************************************
; ïîèñê ïðèâîäîâ HDD è CD
; àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
; àäàïòàöèÿ è äîðàáîòêà Mario79
;******************************************************
 
;****************************************************
;* ÏÎÈÑÊ HDD è CD *
;****************************************************
FindHDD:
mov [ChannelNumber],1
mov [DiskNumber],0
call FindHDD_3
mov [DiskNumber],1
call FindHDD_3
inc [ChannelNumber]
mov [DiskNumber],0
call FindHDD_3
mov [DiskNumber],1
call FindHDD_1
jmp EndFindHDD
 
FindHDD_1:
call DeviceReset
cmp [DevErrorCode],0
jne FindHDD_2_2
call ReadHDD_ID
cmp [DevErrorCode],0
jne FindHDD_2
inc byte [0x40001]
ret
FindHDD_2:
call ReadCD_ID
cmp [DevErrorCode],0
jne FindHDD_2_2
inc byte [0x40001]
inc byte [0x40001]
FindHDD_2_2:
ret
 
FindHDD_3:
call FindHDD_1
shl byte [0x40001],2
ret
 
 
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà â ðåæèìå LBA
SectorAddress DD ?
 
;*************************************************
;* ×ÒÅÍÈÅ ÈÄÅÍÒÈÔÈÊÀÒÎÐÀ ÆÅÑÒÊÎÃÎ ÄÈÑÊÀ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* 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
je @@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 ;ïðèíÿòü áëîê äàííûõ
jmp @@End
; Çàïèñàòü êîä îøèáêè
@@Error1:
mov [DevErrorCode],1
jmp @@End
@@Error6:
mov [DevErrorCode],6
@@End: ret
 
 
 
; Ñòàíäàðòíûå áàçîâûå àäðåñà êàíàëîâ 1 è 2
StandardATABases DW 1F0h, 170h
; Íîìåð êàíàëà
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 DB ?
 
;****************************************************
;* ÏÎÑËÀÒÜ ÊÎÌÀÍÄÓ ÇÀÄÀÍÍÎÌÓ ÄÈÑÊÓ *
;* Âõîäíûå ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå *
;* ïåðåìåííûå: *
;* 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
je @@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
jmp @@End_2
; Çàïèñàòü êîä îøèáêè
@@Err1: mov [DevErrorCode],1
jmp @@End_2
@@Err2: mov [DevErrorCode],2
jmp @@End_2
@@Err3: mov [DevErrorCode],3
jmp @@End_2
@@Err4: mov [DevErrorCode],4
jmp @@End_2
@@Err5: mov [DevErrorCode],5
; Çàâåðøåíèå ðàáîòû ïðîãðàììû
@@End_2:
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
je @@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
jmp @@End_1
; Çàïèñàòü êîä îøèáêè
@@Error1_1:
mov [DevErrorCode],1
jmp @@End_1
@@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
jmp @@End_3
; Îáðàáîòêà îøèáîê
@@Err1_2: mov [DevErrorCode],1
jmp @@End_3
@@Err3_2: mov [DevErrorCode],3
jmp @@End_3
@@Err4_2: mov [DevErrorCode],4
; Çàïèñàòü êîä îøèáêè
@@End_3:
ret
 
EndFindHDD:
 
/kernel/tags/kolibri0.6.3.0/detect/ps2mouse.inc
0,0 → 1,131
MouseSearch_PS2:
jmp MouseSearch_PS2_begin
 
mouse_error equ MouseSearch_PS2_begin.error
 
kb_cmd_c:
call kb_cmd
jmp check_kbd
 
kb_write_c:
call kb_write
jmp check_kbd
 
kb_read_c:
call kb_read
;jmp check_kbd
 
check_kbd:
cmp ah, 1
je mouse_error
ret
 
uglobal
mouse_cmd_byte db 0
mouse_nr_tries db 0
mouse_nr_resends db 0
 
mouse_error_esp dd 0
endg
 
 
mouse_cmd:
mov [mouse_cmd_byte], al
mov [mouse_nr_resends], 5
.resend:
mov bl, 0xd4
call kb_cmd_c
mov al, [mouse_cmd_byte]
call kb_write_c
 
call mouse_read
 
cmp al, 0xFA ; ack
jne .noack
ret
.noack:
cmp al, 0xFE ; resend
jne .noresend
dec [mouse_nr_resends]
jnz .resend
.noresend:
jmp mouse_error
 
 
mouse_read:
mov [mouse_nr_tries], 100
.repeat:
call kb_read
cmp ah, 1
jne .fin
mov esi, 10
call delay_ms
dec [mouse_nr_tries]
jnz .repeat
jmp mouse_error
.fin:
ret
 
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MouseSearch_PS2_begin:
pushad
 
mov [mouse_error_esp], esp
 
mov bl, 0xAD ; disable keyboard interface
call kb_cmd_c
mov bl, 0xA8 ; enable mouse interface
call kb_cmd_c
 
mov al, 0xFF ; reset
call mouse_cmd
 
; now the mouse is in Reset Mode
; get the Basic Assurance Test completion code
call mouse_read
cmp al, 0xAA
jne .error ; dead mouse
 
; get device ID
call mouse_read
cmp al, 0x00
jne .error ; unknown device
 
; reset completed successfully
 
; enable mouse interrupt - IRQ12
mov bl, 0x20 ; read command byte
call kb_cmd_c
call kb_read_c
or al, 10b
push eax
mov bl, 0x60 ; write command byte
call kb_cmd_c
pop eax
call kb_write_c
 
mov al, 0xF4 ; enable data reporting
call mouse_cmd
 
mov [ps2_mouse_detected], 1
mov bl, 0xAE ; enable keyboard interface
call kb_cmd
 
mov esi, boot_setmouse_type
call boot_log
 
jmp .finish
 
 
.error:
mov esp, [mouse_error_esp] ; clear stack frame
mov [ps2_mouse_detected], 0
mov bl, 0xA7 ; disable mouse interface
call kb_cmd
mov bl, 0xAE ; enable keyboard interface
call kb_cmd
 
.finish:
popad
/kernel/tags/kolibri0.6.3.0/detect/commouse.inc
0,0 → 1,135
;**************************************************
;* ÏÎÈÑÊ ÌÛØÈ ÏÎ ÏÎÑËÅÄÎÂÀÒÅËÜÍÛÌ ÏÎÐÒÀÌ *
;* Ïðîöåäóðà ïîäãîòàâëèâàåò ãëîáàëüíûå ïåðåìåííûå *
;* COMPortNum è COMPortBaseAddr äëÿ ïîäïðîãðàììû *
;* óñòàíîâêè îáðàáîò÷èêà ïðåðûâàíèÿ *
;**************************************************
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷.
; Àäàïòàöèÿ è äîðàáîòêà Mario79
 
Detect_COM_Mouse:
pusha
call MSMouseSearch
cmp AL,'M'
jne @f
mov [com1_mouse_detected],1
pusha
 
mov eax,4
shl eax,2
mov [irq_owner+eax],byte 1
 
inc dword [0x2d0000]
mov edi,[0x2d0000]
shl edi,4
mov [0x2d0000+edi+0],dword 1
mov [0x2d0000+edi+4],dword 0x3f0
mov [0x2d0000+edi+8],dword 0x3ff
 
popa
mov esi,boot_setmouse_type+22
call boot_log
@@:
sub [COMPortBaseAddr],100h
call MSMouseSearch
cmp AL,'M'
jne @f
mov [com2_mouse_detected],1
pusha
 
mov eax,3
shl eax,2
mov [irq_owner+eax],byte 1
inc dword [0x2d0000]
mov edi,[0x2d0000]
shl edi,4
mov [0x2d0000+edi+0],dword 1
mov [0x2d0000+edi+4],dword 0x2f0
mov [0x2d0000+edi+8],dword 0x2ff
 
popa
mov esi,boot_setmouse_type+44
call boot_log
@@:
popa
jmp end_detecting_mouse
 
MSMouseSearch:
; ÏÎÈÑÊ ÌÛØÈ ×ÅÐÅÇ COM-ÏÎÐÒÛ
MouseSearch:
; Óñòàíàâëèâàåì ñêîðîñòü
; ïðèåìà/ïåðåäà÷è 1200 áîä
mov DX,[COMPortBaseAddr]
add DX,3
in AL,DX
or AL,80h ;óñòàíîâèòü áèò DLAB
out DX,AL
mov DX,[COMPortBaseAddr]
mov AL,60h ;1200 áîä
out DX,AL
inc DX
mov AL,0
out DX,AL
; Óñòàíîâèòü äëèíó ñëîâà 7 áèò, 1 ñòîïîâûé áèò,
; ÷åòíîñòü íå êîíòðîëèðîâàòü
mov DX,[COMPortBaseAddr]
add DX,3
mov AL,00000010b
out DX,AL
; Çàïðåòèòü âñå ïðåðûâàíèÿ
mov DX,[COMPortBaseAddr]
inc DX
mov AL,0
out DX,AL
; Ïðîâåðèòü, ÷òî óñòðîéñòâî ïîäêëþ÷åíî è ÿâëÿåòñÿ
; ìûøüþ òèïà MSMouse
; Îòêëþ÷èòü ïèòàíèå ìûøè è ïðåðûâàíèÿ
mov DX,[COMPortBaseAddr]
add DX,4 ;ðåãèñòð óïðàâëåíèÿ ìîäåìîì
mov AL,0 ;ñáðîñèòü DTR, RTS è OUT2
out DX,AL
; Îæèäàòü 5 "òèêîâ" (0,2 ñ)
mov ecx,0xffff
dT_1:
dec ecx
cmp ecx,0
jne dT_1
mov ecx,0xffff
; Âêëþ÷èòü ïèòàíèå ìûøè
mov AL,11b ;óñòàíîâèòü DTR è RTS
out DX,AL
; Î÷èñòèòü ðåãèñòð äàííûõ
mov DX,[COMPortBaseAddr]
in AL,DX
; Öèêë îïðîñà ïîðòà
WaitData:
; Îæèäàòü åùå 10 "òèêîâ"
dec ecx
cmp ecx,0
je NoMouse
; Ïðîâåðèòü íàëè÷èå èäåíòèôèêàöèîííîãî áàéòà
mov DX,[COMPortBaseAddr]
add DX,5
in AL,DX
test AL,1 ;Äàííûå ãîòîâû?
jz WaitData
; Ââåñòè äàííûå
mov DX,[COMPortBaseAddr]
in AL,DX
NoMouse:
ret
 
iglobal
COMPortBaseAddr dw 3F8h
;COMPortNum dw 0
endg
 
iglobal
boot_setmouse_type db 'Detected - PS2 mouse',0
db 'Detected - COM1 mouse',0
db 'Detected - COM2 mouse',0
endg
 
end_detecting_mouse:
 
/kernel/tags/kolibri0.6.3.0/detect/sear_par.inc
0,0 → 1,118
;****************************************************
; ïîèñê ëîãè÷åñêèõ äèñêîâ íà îáíàðóæåííûõ HDD
; è çàíåñåíèå äàííûõ â îáëàñòü òàáëèöû
; àâòîð Mario79
;****************************************************
mov [transfer_adress],0x4000a
search_partitions_ide0:
test [0x40001],byte 0x40
jz search_partitions_ide1
mov [hdbase],0x1f0
mov [hdid],0x0
mov [hdpos],1
mov [fat32part],1
search_partitions_ide0_1:
call set_FAT32_variables
cmp [problem_partition],0
jne search_partitions_ide1
inc byte [0x40002]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide0_1
 
search_partitions_ide1:
test [0x40001],byte 0x10
jz search_partitions_ide2
mov [hdbase],0x1f0
mov [hdid],0x10
mov [hdpos],2
mov [fat32part],1
search_partitions_ide1_1:
call set_FAT32_variables
cmp [problem_partition],0
jne search_partitions_ide2
inc byte [0x40003]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide1_1
 
search_partitions_ide2:
test [0x40001],byte 0x4
jz search_partitions_ide3
mov [hdbase],0x170
mov [hdid],0x0
mov [hdpos],3
mov [fat32part],1
search_partitions_ide2_1:
call set_FAT32_variables
cmp [problem_partition],0
jne search_partitions_ide3
inc byte [0x40004]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide2_1
 
search_partitions_ide3:
test [0x40001],byte 0x1
jz end_search_partitions_ide
mov [hdbase],0x170
mov [hdid],0x10
mov [hdpos],4
mov [fat32part],1
search_partitions_ide3_1:
call set_FAT32_variables
cmp [problem_partition],0
jne end_search_partitions_ide
inc byte [0x40005]
call partition_data_transfer
add [transfer_adress],100
inc [fat32part]
jmp search_partitions_ide3_1
 
partition_data_transfer:
mov edi,[transfer_adress]
mov esi,PARTITION_START
xor ecx,ecx
mov cx,69 ;100
rep movsb
ret
transfer_adress dd 0
partition_data_transfer_1:
cli
push edi
mov edi,PARTITION_START
mov esi,[transfer_adress]
xor ecx,ecx
mov cx,69 ;100
rep movsb
pop edi
sti
ret
 
end_search_partitions_ide:
 
;PARTITION_START dd 0x3f
;PARTITION_END dd 0
;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
;
;fat_type db 0 ; 0=none, 16=fat16, 32=fat32
 
/kernel/tags/kolibri0.6.3.0/detect/dev_fd.inc
0,0 → 1,20
;***************************************************
; ïðåäâàðèòåëüíàÿ î÷èñòêà îáëàñòè òàáëèöû
; ïîèñê è çàíåñåíèå â òàáëèöó ïðèâîäîâ FDD
; àâòîð Mario79
;***************************************************
xor eax,eax
mov edi,0x40000
mov ecx,16384
cld
rep stosd
 
mov al,0x10
out 0x70,al
mov cx,0xff
wait_cmos:
dec cx
cmp cx,0
jne wait_cmos
in al,0x71
mov [0x40000],al
/kernel/tags/kolibri0.6.3.0/detect/disks.inc
0,0 → 1,4
include 'dev_fd.inc'
include 'dev_hdcd.inc'
include 'sear_par.inc'
 
/kernel/tags/kolibri0.6.3.0/makefile
0,0 → 1,16
FASM=fasm
KSRC=kernel.asm
KOUT=kernel.mnt
 
en: kernel.asm
rm -f lang.inc
echo lang fix en > lang.inc
$(FASM) $(KSRC) $(KOUT)
ru: kernel.asm
rm -f lang.inc
echo lang fix ru > lang.inc
$(FASM) $(KSRC) $(KOUT)
 
clean:
rm -f $(KOUT)
rm -f lang.inc
/kernel/tags/kolibri0.6.3.0/kernel16.inc
0,0 → 1,34
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; KERNEL16.INC ;;
;; ;;
;; Included 16 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. ;;
;; ;;
;; Copyright Ville Turjanmaa, see file COPYING for details. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
;% +include
 
;!!!
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
else
include "boot/bootge.inc" ; german system boot messages
;!!!
end if
include "boot/ru.inc" ; Russian font
org $-0x10000
 
include "boot/bootcode.inc" ; 16 bit system boot code
 
include "bus/pci/pci16.inc"
 
;% -include
/kernel/tags/kolibri0.6.3.0/video/vesa20.inc
0,0 → 1,1122
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
; If you're planning to write your own video driver I suggest
; you replace the VESA12.INC file and see those instructions.
 
ScreenWidth equ 0xfe00
ScreenHeight equ 0xfe04
BytesPerScanLine equ 0xfe08
LFBAddress equ 0xfe80
ScreenBPP equ 0xfbf1
WinMapAddress equ 0x460000
 
 
 
;*************************************************
; getpixel
;
; in:
; eax = x coordinate
; ebx = y coordinate
;
; ret:
; ecx = 00 RR GG BB
 
getpixel:
push eax ebx edx edi
call dword [0xe024]
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)
add edi, [LFBAddress] ; ebx = where pixel is in memory
mov ecx, [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)
add edi, [LFBAddress] ; ebx = where pixel is in memory
mov ecx, [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 ?
.source_bpp dd ?
.winmap_newline dd ?
.screen_newline dd ?
.stack_data = 4*13
end virtual
 
align 4
; ebx = pointer
; ecx = size [x|y]
; edx = coordinates [x|y]
vesa20_putimage:
pushad
call [disable_mouse]
 
sub esp, putimg.stack_data
 
mov [putimg.source_bpp], 3
; test ebx, 0x80000000
; jz @f
; inc [putimg.source_bpp]
; @@:
; and ebx, 0x7FFFFFFF
 
; 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, [0x3010]
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]
sub eax, [putimg.real_sx]
;; imul eax, [putimg.source_bpp]
lea eax, [eax + eax * 2]
mov [putimg.line_increment], eax
 
; winmap new line increment
mov eax, [ScreenWidth]
inc eax
sub eax, [putimg.real_sx]
mov [putimg.winmap_newline], eax
 
; screen new line increment
mov eax, [BytesPerScanLine]
mov ecx, [putimg.real_sx]
movzx ebx, byte [ScreenBPP]
shr ebx, 3
imul ecx, ebx
sub eax, ecx
mov [putimg.screen_newline], eax
 
; pointer to image
mov ecx, [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
add edx, [LFBAddress]
 
; pointer to pixel map
mov eax, [putimg.abs_cy]
imul eax, [ScreenWidth]
add eax, [putimg.abs_cy]
add eax, [putimg.abs_cx]
add eax, WinMapAddress
xchg eax, ebp
 
; get process number
mov ebx, [0x3000]
 
cmp byte [ScreenBPP], 32
je put_image_end_32
 
;put_image_end_24:
mov edi, [putimg.real_sy]
align 4
.new_line:
mov esi, [putimg.real_sx]
 
; push ebp edx
align 4
.new_x:
 
cmp [ebp], bl
jne .skip
mov eax, [ecx] ; ecx = RRBBGGRR
mov [edx], ax
shr eax, 16
mov [edx+2], al
.skip:
 
add ecx, 3 ;[putimg.source_bpp]
add edx, 3
inc ebp
 
dec esi
jnz .new_x
; pop edx ebp
 
add ecx, [putimg.line_increment]
add edx, [putimg.screen_newline] ;[BytesPerScanLine]
add ebp, [putimg.winmap_newline] ;[ScreenWidth]
;inc ebp
 
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 esi, [putimg.real_sx]
 
; push ebp edx
align 4
.new_x:
 
cmp [ebp], bl
jne .skip
mov eax, [ecx] ; ecx = RRBBGGRR
mov [edx], eax
.skip:
 
add ecx, [putimg.source_bpp]
add edx, 4
inc ebp
 
dec esi
jnz .new_x
; pop edx ebp
 
add ecx, [putimg.line_increment]
add edx, [putimg.screen_newline] ;[BytesPerScanLine]
add ebp, [putimg.winmap_newline] ;[ScreenWidth]
;inc ebp
 
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
test edi,1 ; force ?
jnz .forced
; not forced:
push ecx ; save 24th bit in case negative pixel wanted
call checkpixel
test ecx,ecx
pop ecx
jnz .exit
.forced:
cmp [ScreenWidth], eax
jb .exit
cmp [ScreenHeight], ebx
jb .exit
.ok:
; check if negation
test ecx,0x01000000
jz .noneg
call getpixel
not ecx
mov [esp+32-8],ecx
.noneg:
; OK to set pixel
call dword [0xe020] ; 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]
add edi, [LFBAddress]
add edi, ebx ; ebx = where to put pixel in memory
mov [edi], ax
shr eax, 16
mov [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
add edi, [LFBAddress] ; ebx = where to put pixel in memory
mov [edi], eax
 
ret
 
 
;*************************************************
 
;align 4
calculate_edi:
mov edi, ebx
imul edi, [ScreenWidth]
add edi, ebx
add edi, eax
ret
 
;*************************************************
 
; DRAWLINE
 
align 4
__sys_draw_line:
; inc [mouse_pause]
call [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 [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, [0x3010]
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, [ScreenWidth]
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
add edx, [LFBAddress]
 
; pointer to pixel map
mov eax, [drbar.abs_cy]
imul eax, [ScreenWidth]
add eax, [drbar.abs_cy]
add eax, [drbar.abs_cx]
add eax, WinMapAddress
xchg eax, ebp
 
; get process number
mov ebx, [0x3000]
 
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 [edx], bh
mov [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 [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
 
 
;voodoodbcplimit:
 
; ebp:=(y+Ywin)*(ScreenXSize+1)+(x+Xwin)+AddrBuffer
 
 
; pusha
 
; xor edx,edx
; mov eax,ebp
; mov ebx,[ScreenWidth] ; Screen_X_size
; inc ebx ; +1
; sub eax,WinMapAddress ; -AddrBuffer
; div ebx ;
; mov ebx,eax ; ebx:=Y
; mov eax,edx ; eax:=X
; call cplimit
 
; test ecx,ecx
; jne dbcpl12
; popa
; clc
; ret
; dbcpl12:
; popa
; stc
; ret
 
 
 
 
;dbcplimit:
 
; pusha
 
; xor edx,edx
; mov ebx,[ScreenWidth]
; inc ebx
; sub eax,WinMapAddress
; div ebx
; mov ebx,eax
; mov eax,edx
; call cplimit
 
; test ecx,ecx
; jne dbcpl1
; popa
; clc
; ret
; dbcpl1:
; popa
; stc
; ret
 
 
 
 
 
 
;--------------vbe voodoo ------------------------------------------------
vesa20_drawbackground_tiled:
 
call [disable_mouse]
 
push ebp
push eax
push ebx
push ecx
push edx
 
mov edx,dword [WinMapAddress-8] ; B
add edx,dword [WinMapAddress-8] ; +B
add edx,dword [WinMapAddress-8] ; +B
push edx
 
mov ebp,[draw_data+32+RECT.left] ; x start:=(x+Xwin)
mov ebx,[draw_data+32+RECT.top] ; y start:=(y+Ywin)
 
mov eax,[BytesPerScanLine]
mul ebx
xchg ebp, eax ; BytesPerScanLine*(Ywin+y)
add ebp, eax ; +X
add ebp, eax ; +X
add ebp, eax ; +X
 
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
add ebp,eax ; +X
@@:
add ebp,[LFBAddress] ; +LFB
 
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
 
call calculate_edi
 
 
dp3: ; MAIN LOOP
 
cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1)
; je ybgp
;
; jmp nbgp
;
; ybgp:
jne nbgp
 
push eax
push ebx
 
mov ecx,dword [WinMapAddress-8] ; B
xor edx,edx ; edx:=0
div ecx ; Xstart/B
 
; eax=Int(qn) edx:=Rem
 
lea esi,[edx+edx*2] ; esi:=edx*3
 
mov ecx,dword [WinMapAddress-4] ; ecx:=H
mov eax,[esp+0] ; eax:=Ystart
xor edx,edx ;
div ecx ; Ystart/H
 
mov eax,edx ; eax:=Rem
xor edx,edx ;
mov ebx,[esp+8] ; ebx:=B*3
mul ebx ;
add esi,eax ;
mov eax,[esi+0x300000]
and eax,0xffffff
 
xchg edi, ebp
stosw
shr eax,16
stosb
xchg ebp, edi ; ebp+=3
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
inc ebp ; +1
@@:
 
pop ebx
pop eax
 
jmp hook1
 
nbgp:
add ebp,3 ; +3
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
inc ebp ; +1
@@:
 
hook1:
 
inc edi ; ptrBuffer++
add esi,3 ; ptrImage+=3
inc eax
cmp eax,[draw_data+32+RECT.right] ; X > xend?
; jg nodp3
; jmp dp3
;
; nodp3:
jle dp3
 
mov ebp,[draw_data+32+RECT.left]
 
inc ebx
 
mov eax,[BytesPerScanLine]
mul ebx
xchg ebp, eax ; BytesPerScanLine*(Ywin+y)
add ebp, eax ; +X
add ebp, eax ; +X=X*2
add ebp, eax ; +X=X*3
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
add ebp,eax ; +X=X*4
@@:
add ebp,[LFBAddress] ; +LFB
 
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
 
call calculate_edi
 
cmp ebx,[draw_data+32+RECT.bottom]
; jg dp4
;
; jmp dp3
;
; dp4:
jle dp3
 
add esp,4
 
pop edx
pop ecx
pop ebx
pop eax
pop ebp
mov [EGA_counter],1
call VGA_drawbackground
ret
 
; ----------
 
 
vesa20_drawbackground_stretch:
 
call [disable_mouse]
 
push ebp
push eax
push ebx
push ecx
push edx
 
mov edx,dword [WinMapAddress-8] ; B
add edx,dword [WinMapAddress-8] ; +B
add edx,dword [WinMapAddress-8] ; +B
push edx
 
mov ebp,[draw_data+32+RECT.left] ; x start:=(x+Xwin)
mov ebx,[draw_data+32+RECT.top] ; y start:=(y+Ywin)
 
mov eax,[BytesPerScanLine]
mul ebx
xchg ebp, eax ; BytesPerScanLine*(Ywin+y)
add ebp, eax ; +X
add ebp, eax ; +X
add ebp, eax ; +X
 
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
add ebp,eax ; +X
@@:
add ebp,[LFBAddress] ; +LFB
 
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
 
call calculate_edi
 
 
sdp3: ; MAIN LOOP
 
cmp [edi+WinMapAddress],byte 1 ; ptrBuffer^<>byte(1)
jne snbgp
 
push eax
push ebx
 
mov eax,dword [WinMapAddress-8]
imul eax, [esp+4] ;4
xor edx,edx
mov ebx,[ScreenWidth]
div ebx
lea esi,[eax+eax*2]
mov eax,dword [WinMapAddress-4]
imul eax, [esp+0] ;0
xor edx,edx
mov ebx,[ScreenHeight]
div ebx
imul eax, [esp+8] ;8
add esi,eax
 
mov eax,[esi+0x300000]
and eax,0xffffff
 
xchg edi, ebp
stosw
shr eax,16
stosb
xchg ebp, edi ; ebp+=3
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
inc ebp ; +1
@@:
 
pop ebx
pop eax
 
jmp shook1
 
snbgp:
add ebp,3 ; +3
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
inc ebp ; +1
@@:
 
shook1:
 
inc edi ; ptrBuffer++
add esi,3 ; ptrImage+=3
inc eax
cmp eax,[draw_data+32+RECT.right] ; X > xend?
jle sdp3
 
mov ebp,[draw_data+32+RECT.left]
 
inc ebx
 
mov eax,[BytesPerScanLine]
mul ebx
xchg ebp, eax ; BytesPerScanLine*(Ywin+y)
add ebp, eax ; +X
add ebp, eax ; +X=X*2
add ebp, eax ; +X=X*3
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size
jz @f
add ebp,eax ; +X=X*4
@@:
add ebp,[LFBAddress] ; +LFB
 
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
 
call calculate_edi
 
cmp ebx,[draw_data+32+RECT.bottom]
jle sdp3
 
add esp,4
 
pop edx
pop ecx
pop ebx
pop eax
pop ebp
mov [EGA_counter],1
call VGA_drawbackground
ret
/kernel/tags/kolibri0.6.3.0/video/vga.inc
0,0 → 1,446
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; VGA.INC ;;
;; ;;
;; 640x480 mode 0x12 VGA functions for MenuetOS ;;
;; ;;
;; Paul Butcher, paul.butcher@asa.co.uk ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
 
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
 
uglobal
novesachecksum dd 0x0
EGA_counter db 0
VGA_drawing_screen db 0
VGA_8_pixels:
rb 16
temp:
.cx dd 0
endg
 
checkVga_N13:
 
cmp [0xfe0c],dword 0x13
jne @f
 
; cnvl:
pushad
cmp [EGA_counter],1
je novesal
mov ecx,[0xfb0a]
cmp ecx,[novesachecksum]
jne novesal
popad
@@:
ret
 
novesal:
mov [novesachecksum],ecx
mov ecx,0
movzx eax,word [0xfb0c]
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 [0xfb0a]
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,[0xfe80]
add esi,ecx
mov edi,0xa0000
mov edx,200
mov ecx,320
cld
m13pix:
lodsd
cmp eax,0
je .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 [0xfe0c],dword 0x12
jne .end
pushad
mov esi,[0xfe80]
mov edi,0xa0000
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
cmp eax,0
je .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, [0xfe80] ; + LFB address
mov [edi], eax ; write to LFB for Vesa2.0
shr edx,5 ; change BytesPerPixel to 1/8
mov edi,edx
add edi, 0x0a0000 ; 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
cmp eax,0
je .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 [0xfe0c],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 [0xfe0c],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, [0x3010]
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, [0xfe80] ; + LFB address
shr ebx,5 ; change BytesPerPixel to 1/8
mov edi,ebx
add edi, 0x0a0000 ; 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
 
 
/kernel/tags/kolibri0.6.3.0/video/vesa12.inc
0,0 → 1,987
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; VESA12.INC ;;
;; ;;
;; Vesa 1.2 functions for MenuetOS ;;
;; ;;
;; Copyright 2002 Ville Turjanmaa ;;
;; ;;
;; quickcode@mail.ru - bankswitch for S3 cards ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
; 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
;set_bank:
;cli
;cmp al,[0xfff2]
;je retsb
;mov [0xfff2],al
;push dx
;mov dx,3D8h
;out dx,al
;pop dx
;retsb:
;sti
;ret
 
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
; set_bank for S3 videocards, work on S3 ViRGE PCI (325)
; modified by kmeaw
set_bank:
pushfd
cli
cmp al,[0xfff2]
je retsb
mov [0xfff2],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
 
;Set bank function for Intel 810/815 chipsets
; *****Modified by Protopopius, Russia.*****
; ********* http://menuetos.hut.ru **************
; ************************************************
;
;set_bank:
;cli
;cmp al,[0xfff2]
;je retsb
;mov [0xfff2],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:
;sti
;ret
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!}
 
;set_bank:
; cli
; cmp al,[0xfff2]
; je retsb
; mov [0xfff2],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:
; ret
 
 
vesa12_drawbackground:
 
call [disable_mouse]
 
push eax
push ebx
push ecx
push edx
 
xor edx,edx
mov eax,dword[WinMapAddress-8]
mov ebx,dword[WinMapAddress-4]
mul ebx
mov ebx,3
mul ebx
mov [imax],eax
mov eax,[draw_data+32+RECT.left]
mov ebx,[draw_data+32+RECT.top]
mov edi,0 ;no force
 
v12dp3:
 
push eax
push ebx
mov esi,0x300000
 
cmp [WinMapAddress-12],dword 1 ; tiled background
jne no_vesa12_tiled_bgr
 
push edx
 
xor edx,edx
mov ecx,[WinMapAddress-8]
div ecx
mov eax,edx
 
push eax
mov eax,ebx
xor edx,edx
mov ecx,[WinMapAddress-4]
div ecx
mov ebx,edx
pop eax
 
pop edx
 
no_vesa12_tiled_bgr:
 
cmp [WinMapAddress-12],dword 2 ; stretched background
jne no_vesa12_stretched_bgr
 
push edx
 
imul eax,dword [WinMapAddress-8]
xor edx,edx
mov ecx,[0xfe00]
inc ecx
div ecx
 
push eax
mov eax,ebx
imul eax,dword [WinMapAddress-4]
xor edx,edx
mov ecx,[0xfe04]
inc ecx
div ecx
mov ebx,eax
pop eax
 
pop edx
 
no_vesa12_stretched_bgr:
 
 
push eax
mov eax,ebx
xor edx,edx
mov ebx,[WinMapAddress-8]
add ebx,[WinMapAddress-8]
add ebx,[WinMapAddress-8]
mul ebx
mov esi,eax
pop eax
add esi,eax
add esi,eax
add esi,eax
add esi,0x300000
pop ebx
pop eax
 
v12di4:
 
mov ecx,[esi]
pusha
mov esi,eax
mov edi,ebx
mov eax,[0xfe00]
add eax,1
mul ebx
add eax,esi
add eax,WinMapAddress
cmp [eax],byte 1
jnz v12nbgp
mov eax,[0xfe08]
mov ebx,edi
mul ebx
add eax,esi
add eax,esi
add eax,esi
cmp [0xFBF1],byte 24
jz v12bgl3
add eax,esi
 
v12bgl3:
 
push ebx
push eax
 
sub eax,[0xfe80]
 
shr eax,16
call set_bank
pop eax
and eax,65535
add eax,0xa0000
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 [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,[0x3010]
add eax,[ecx-twdw+WDATA.box.left]
add ebx,[ecx-twdw+WDATA.box.top]
push eax
mov eax,ebx ; y
mov ebx,[0xfe08]
mul ebx
pop ecx
add eax,ecx ; x
add eax,ecx
add eax,ecx
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x start
jz dbpi2412
add eax,ecx
 
dbpi2412:
 
add eax,[0xfe80]
mov edi,eax
 
; x size
 
mov eax,[esp+4] ; [esp+6]
mov ecx,eax
add ecx,eax
add ecx,eax
cmp [0xfbf1],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,[0x3010]
mov ecx,[eax+draw_data-0x3000+RECT.left]
cmp ecx,0
jnz dbcblimitlset12
mov ecx,[eax+draw_data-0x3000+RECT.top]
cmp ecx,0
jnz dbcblimitlset12
mov ecx,[eax+draw_data-0x3000+RECT.right]
cmp ecx,[0xfe00]
jnz dbcblimitlset12
mov ecx,[eax+draw_data-0x3000+RECT.bottom]
cmp ecx,[0xfe04]
jnz dbcblimitlset12
pop ecx
pop eax
push dword 0
jmp dbcblimitlno12
 
dbcblimitlset12:
 
pop ecx
pop eax
push dword 1
 
dbcblimitlno12:
 
cmp [0xfbf1],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,[0xfe80]
mov ebx,3
div ebx
add eax,WinMapAddress
mov ebx,[0x3000]
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,[0xfe80]
shr eax,16
call set_bank
and edi,0xffff
add edi,0xa0000
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,[0xfe08]
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,[0xfe80]
shr eax,2
add eax,WinMapAddress
mov ebx,[0x3000]
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,[0xfe80]
shr eax,16
call set_bank
and edi,0xffff
add edi,0xa0000
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,[0xfe08]
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,[0xfe08]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
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,[0xfe08]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
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,[0xfe08]
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
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,[0xfe08]
xor edx,edx
mul ebx
add edi,eax
mov eax,edi
shr eax,16
call set_bank
and edi,65535
add edi,0xa0000
mov ecx,[edi]
and ecx,255*256*256+255*256+255
sti
 
ret
 
 
 
vesa12_putimage:
 
; mov ebx,image
; mov ecx,320*65536+240
; mov edx,20*65536+20
 
call [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,[0x3010]
add eax,[ecx-twdw+WDATA.box.left]
add ebx,[ecx-twdw+WDATA.box.top]
push eax
mov eax,ebx ; y
mov ebx,[0xfe08]
mul ebx
pop ecx
add eax,ecx ; x
add eax,ecx
add eax,ecx
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x start
jz pi2412
add eax,ecx
 
pi2412:
 
add eax,[0xfe80]
mov edi,eax
 
; x size
 
movzx eax,word [esp+6]
mov ecx,eax
add ecx,eax
add ecx,eax
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ? - x size
jz pi24312
add ecx,eax
 
pi24312:
 
mov esi,[esp+8]
movzx ebx,word [esp+4]
 
; check limits while draw ?
 
push eax
push ecx
mov eax,[0x3010]
mov ecx,[eax+draw_data-0x3000+RECT.left]
cmp ecx,0
jnz dbcblimitlset212
mov ecx,[eax+draw_data-0x3000+RECT.top]
cmp ecx,0
jnz dbcblimitlset212
mov ecx,[eax+draw_data-0x3000+RECT.right]
cmp ecx,[0xfe00]
jnz dbcblimitlset212
mov ecx,[eax+draw_data-0x3000+RECT.bottom]
cmp ecx,[0xfe04]
jnz dbcblimitlset212
pop ecx
pop eax
push dword 0
jmp dbcblimitlno212
 
dbcblimitlset212:
 
pop ecx
pop eax
push dword 1
 
dbcblimitlno212:
 
cmp [0xfbf1],byte 24 ; 24 or 32 bpp ?
jz pi24bit12
jmp pi32bit12
 
pi24bit12:
 
cld
push eax
push ebx
push edx
xor edx,edx
mov eax,ecx
mov ebx,3
div ebx
mov ecx,eax
pop edx
pop ebx
pop eax
 
newpi12:
 
push edi
push esi
push ecx
push ebx
 
xor edx,edx
mov eax,edi
sub eax,[0xfe80]
mov ebx,3
div ebx
add eax,WinMapAddress
mov ebx,[0x3000]
mov bh,[esp+4*4]
 
np2412:
 
cmp bl,[eax]
jnz imp24no12
mov edx,[esi]
cmp bh,0
jz imp24yes12
; call dbcplimit
; jnz imp24no12
 
imp24yes12:
 
push eax
push edi
mov eax,edi
sub eax,[0xfe80]
shr eax,16
call set_bank
and edi,0xffff
add edi,0xa0000
mov [edi],edx
shr edx,2
mov [edi+2],dl
sti
pop edi
pop eax
 
imp24no12:
 
inc eax
add esi,3
add edi,3
dec ecx
jnz np2412
 
np24d12:
 
pop ebx
pop ecx
pop esi
pop edi
 
add edi,[0xfe08]
xor eax,eax
mov ax,[esp+4+2+4]
lea eax,[eax+eax*2]
add esi,eax
dec ebx
jz nonewpi12
jmp newpi12
 
nonewpi12:
 
add esp,7*4
mov eax,0
ret
 
 
pi32bit12:
 
cld
shr ecx,2
 
newpi3212:
 
push edi
push esi
push ecx
push ebx
 
mov eax,edi
sub eax,[0xfe80]
shr eax,2
add eax,WinMapAddress
mov ebx,[0x3000]
mov bh,[esp+4*4]
 
np3212:
 
cmp bl,[eax]
jnz imp32no12
mov edx,[esi]
cmp bh,0
jz imp32yes12
; call dbcplimit
; jnz imp32no12
 
imp32yes12:
 
push eax
push edi
mov eax,edi
sub eax,[0xfe80]
shr eax,16
call set_bank
and edi,0xffff
add edi,0xa0000
mov [edi],edx
sti
pop edi
pop eax
 
imp32no12:
 
inc eax
add esi,3
add edi,4
dec ecx
jnz np3212
 
np32d12:
 
pop ebx
pop ecx
pop esi
pop edi
 
add edi,[0xfe08]
movzx eax,word [esp+4+2+4]
lea eax,[eax+eax*2]
add esi,eax
dec ebx
jz nonewpi3212
jmp newpi3212
 
nonewpi3212:
 
add esp,7*4
mov eax,0
ret
 
 
vesa12_read_screen_pixel:
 
and eax,0x3FFFFF
cmp [0xfbf1],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,0xa0000
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,0xa0000
mov eax,[edi]
and eax,0x00ffffff
ret
 
 
/kernel/tags/kolibri0.6.3.0/memmap.inc
0,0 → 1,233
;
; 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: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
;
; Runtime:
;
; 0000 -> 1FFF 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
;
; 2000 -> 2FFF free
;
; 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 -> 5FFF save_syscall_data - syscall trace
; 6000 -> 68FF free
; 6900 -> 6EFF saved picture under mouse pointer
;
; 6F00 -> 6FFF free
;
; 7000 -> 7FFF used CD driver
;
; 8000 -> A3FF used FLOPPY driver
;
; A400 -> B0FF free
 
; B100 -> B2FF IDT
 
; B300 -> BFFF free
 
; 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
; E000 byte multitasking started
; E020 dword putpixel address
; E024 dword getpixel address
; E030 dword Vesa 1.2 pm bank switch address
; F200 dword mousepicture -pointer
; F204 dword mouse appearance counter
; F300 dword x & y temp for windowmove
; 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 mouse port: 1 ps2, 2 com1, 3 com2
; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y
; 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
; FE00 dword screen x size
; FE04 dword screen y size
; FE08 dword screen y multiplier
; FE0C dword screen mode
; FE10 dword entries in hd cache
; 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
; FF00 byte 1 = system shutdown request
; FF01 dword free
; FFF0 byte 1 = redraw background request from app
; FFF1 byte 1 = diskette int occur
; 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.
;
; 10000 -> 3DBFF kernel, 32-bit run-time code (up to 183 Kb)
; 3DC00 -> 3EBFF stack at boot time (4Kb)
; 3EC00 -> 3F5FF basic text font II
; 3F600 -> 3FFFF basic text font I
; 40000 -> 4FFFF data of retrieved disks and partitions (Mario79)
 
; 50000 -> 5FFFF free (64 Kb)
 
; 60000 -> 7FFFF reserved to physical memory manager
; 80000 -> 8FFFF additional app info, in 256 byte steps - 256 entries
;
; 00 11db name of app running
; 10 108db floating point unit save area
; 7f byte 0= no fpu saved , 1= fpu saved to 0x10 -> restore
; 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
;
; 90000 -> 9FFFF tmp
; A0000 -> AFFFF screen access area
; B0000 -> FFFFF bios rest in peace -area
; 100000 -> 27FFFF diskette image
; 280000 -> 281FFF ramdisk fat
; 282000 -> 283FFF floppy fat
;
; 284000 -> 29FFFF free (112 Kb)
;
; 2A0000 -> 2B00ff wav device data
; 2C0000 -> 2C3fff button info
;
; 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
;
; 2C4000 -> 2CFFFF free (48Kb)
;
; 2D0000 -> 2DFFFF reserved port area
;
; 0000 dword no of port areas reserved
; 0010 dword process id
; dword start port
; dword end port
; dword 0
;
; 2E0000 -> 2EFFFF irq data area
; 2F0000 -> 2FFFFF low memory save
;
; 300000 -> 45FFFF background image, max 1,375 M
;
; 460000 -> 5FFFFF display info
;
; 600000 -> 6FFFFF hd cache
;
; 700000 -> 71ffff tcp memory (128 kb)
; 720000 -> 75ffff free (256 kb)
;
; 760000 -> 76ffff !vrr driver
; 770000 -> 777fff tcp memory ( 32 kb)
;
; 778000 -> 77ffff window skinning ( 32 kb)
; 780000 -> 7fffff reserved to physical memory manager
;
; 800000 -> BFFFFF mapped to LFB
;
;
; C00000 -> C01FFF draw_data - 256 entries
;
; 00 dword draw limit - x start
; 04 dword draw limit - y start
; 08 dword draw limit - x end
; 0C dword draw limit - y end
;
; C02000 -> C02fff free (4 Kb)
;
; C03000 -> D02fff sysint_stack_data
; - ring0 stacks for ring3 processes
; - used for interrupt handling
; - 256 entries * 4096 step
;
; D03000 -> D1ffff free (116 Kb)
;
; D20000 -> F28000 TSS and IO map for (8192*8)=65536 ports
; (128+8192)*256 = 557956 = 0x88000
;
; 1000000 -> 3FFFFFF for applications
;
 
 
 
 
 
/kernel/tags/kolibri0.6.3.0/network/stack.inc
0,0 → 1,1784
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; STACK.INC ;;
;; ;;
;; TCP/IP stack for Menuet OS ;;
;; ;;
;; Version 0.7 4th July 2004 ;;
;; ;;
;; 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 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
;*******************************************************************
; Interface
; The interfaces defined in ETHERNET.INC plus:
; stack_init
; stack_handler
; app_stack_handler
; app_socket_handler
; checksum
;
;*******************************************************************
 
 
 
;
; IP Packet after reception - Normal IP packet format
;
; 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
;
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
;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 |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Data |
; +-+-+-.......... -+
 
 
; 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
 
 
;
; 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 |
; +-+-+-.......... -+
;
 
 
;
; Socket Descriptor + Buffer
;
; 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
;
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Status ( of this buffer ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Application Process ID |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Local IP Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Local IP Port | Unused ( set to 0 ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Remote IP Address |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; | Remote IP Port | Unused ( set to 0 ) |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 24| Rx Data Count INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 28| TCB STATE INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 32| TCB Timer (seconds) INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 36| ISS (Inital Sequence # used by this connection ) INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 40| IRS ( Inital Receive Sequence # ) INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 44| SND.UNA Seq # of unack'ed sent packets INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 48| SND.NXT Next send seq # to use INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 52| SND.WND Send window INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 56| RCV.NXT Next expected receive sequence # INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 60| RCV.WND Receive window INET format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 64| SEG.LEN Segment length INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 68| SEG.WND Segment window INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 72| Retransmit queue # NOW WINDOW SIZE TIMER INTEL format|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
; 76| RX Data |
; +-+-+-.......... -+
 
 
 
; IP protocol numbers
PROTOCOL_ICMP equ 1
PROTOCOL_TCP equ 6
PROTOCOL_UDP equ 17
 
 
; TIPBUFF 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
 
SOCK_EMPTY equ 0 ; socket not in use
SOCK_OPEN equ 1 ; open issued, but no data sent
 
; TCP opening modes
SOCKET_PASSIVE equ 0
SOCKET_ACTIVE equ 1
 
; 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_TIME_WAIT equ 10
TCB_CLOSED equ 11
 
TWOMSL equ 10 ; # of secs to wait before closing socket
 
; socket buffers
SOCKETBUFFSIZE equ 4096 ; state + config + buffer.
SOCKETHEADERSIZE equ 76 ; thus 4096 - SOCKETHEADERSIZE bytes data
 
NUM_SOCKETS equ 16 ; Number of open sockets supported. Was 20
 
 
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
TCP_RETRIES equ 5 ; Number of times to resend a packet
TCP_TIMEOUT equ 10 ; resend if not replied to in x hs
 
; 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
slip_active equ stack_data + 8 ; no longer used
; 1 byte. 0 == inactive, 1 = active
ethernet_active equ stack_data + 9
unused equ stack_data + 10
; word. Buffer number, -1 if none
rx_buff_ptr equ stack_data + 12
; dword. Buffer number, -1 if none
tx_buff_ptr equ stack_data + 16
; byte.
slip_rx_state equ stack_data + 20 ; no longer used
; byte
slip_tx_state equ stack_data + 21 ; no longer used
; dword. Index into data
rx_data_ptr equ stack_data + 22
; dword. Index into data
tx_data_ptr equ stack_data + 26
; word. Count of bytes to send
tx_msg_len equ stack_data + 30
; 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 sockets + (SOCKETBUFFSIZE * NUM_SOCKETS)
; 1560 byte buffer for rx / tx ethernet packets
Ether_buffer equ Next_free2
Next_free3 equ Ether_buffer + 1560
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
 
 
;***************************************************************************
; 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:
xor eax,eax
mov edi,stack_data_start
mov ecx,0x20000 / 4 ; Assume that we have 128KB of data
cld
rep stosd
 
; Initialise TCP resend queue data structures
mov eax, 0xFFFFFFFF
mov edi, resendQ
mov ecx, NUMRESENDENTRIES ; 1 dword per entry
cld
rep stosd
 
 
mov eax, 0xFFFFFFFF
mov [rx_buff_ptr], eax
mov [tx_buff_ptr], eax
 
; Put in some defaults : slip, 0x3f8, 4, ip=192.168.1.22
; Saves me entering them each boot up when debugging
mov eax, 0x03f80401
mov [stack_config], eax
mov eax, 0xc801a8c0
mov [stack_ip], eax
 
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
;
;***************************************************************************
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
 
call arp_timer
call tcp_tcb_handler
 
sh_exit:
ret
 
 
 
 
;***************************************************************************
; Function
; is_localport_unused
;
; Description
; scans through all the active sockets , looking to see if the
; port number specified in bx is in use as a localport number.
; This is useful when you want a to generate a unique local port
; number.
; On return, eax = 1 for free, 0 for in use
;
;***************************************************************************
is_localport_unused:
mov al, bh
mov ah, bl
mov bx, ax
 
mov edx, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
mov eax, 0 ; Assume the return value is 'in use'
 
ilu1:
sub edx, SOCKETBUFFSIZE
cmp [edx + sockets + 12], bx
loopnz ilu1 ; Return back if the socket is occupied
 
jz ilu_exit
inc eax ; return port not in use
 
ilu_exit:
ret
 
 
 
;***************************************************************************
; Function
; get_free_socket
;
; Description
;
;***************************************************************************
get_free_socket:
push ecx
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
 
gfs1:
sub eax, SOCKETBUFFSIZE
cmp [eax + sockets], dword SOCK_EMPTY
loopnz gfs1 ; Return back if the socket is occupied
mov eax, ecx
pop ecx
jz gfs_exit
mov eax, 0xFFFFFFFF
 
gfs_exit:
ret
 
 
 
;***************************************************************************
; 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
 
xor edx, edx ; edx is the accumulative checksum
xor ebx, ebx
mov cx, [checkSize1]
shr cx, 1
jz cs1_1
 
mov eax, [checkAdd1]
 
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
 
shr cx, 1
jz cs2_1
 
mov eax, [checkAdd2]
 
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 fn 52
; It provides application access to the network interface layer
;
;***************************************************************************
app_stack_handler:
cmp eax, 0
jnz not0
; Read the configuartion word
mov eax, [stack_config]
ret
 
not0:
cmp eax, 1
jnz not1
; read the IP address
 
mov eax, [stack_ip]
ret
 
not1:
cmp eax, 2
jnz not2
 
; write the configuration word
mov [stack_config], ebx
 
; <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 bl, 0x7f
cmp bl, 3
 
je ash_eth_enable
; Ethernet isn't enabled, so make sure that the card is disabled
mov [ethernet_active], byte 0
 
ret
 
ash_eth_enable:
; Probe for the card. This will reset it and enable the interface
; if found
call eth_probe
cmp eax, 0
je ash_eth_done ; Abort if no hardware found
 
mov [ethernet_active], byte 1
 
ash_eth_done:
ret
 
not2:
cmp eax, 3
jnz not3
; write the IP Address
mov [stack_ip], ebx
ret
 
not3:
cmp eax, 4
jnz not4
; Enabled the slip driver on the comm port
; slip removed
ret
 
not4:
cmp eax, 5
jnz not5
; Disable the slip driver on the comm port
; slip removed
 
not5:
cmp eax, 6
jnz not6
 
; Insert an IP packet into the stacks received packet queue
call stack_insert_packet
ret
 
not6:
cmp eax, 7
jnz not7
 
; Test for any packets queued for transmission over the network
 
not7:
cmp eax, 8
jnz not8
 
call stack_get_packet
; Extract a packet queued for transmission by the network
ret
 
not8:
cmp eax, 9
jnz not9
 
; read the gateway IP address
 
mov eax, [gateway_ip]
ret
 
not9:
cmp eax, 10
jnz not10
 
; read the subnet mask
 
mov eax, [subnet_mask]
ret
 
not10:
cmp eax, 11
jnz not11
 
; write the gateway IP Address
mov [gateway_ip], ebx
 
ret
 
not11:
cmp eax, 12
jnz not12
 
; write the subnet mask
mov [subnet_mask], ebx
 
 
not12:
cmp eax, 13
jnz not13
 
; read the dns
 
mov eax, [dns_ip]
ret
 
not13:
cmp eax, 14
jnz stack_driver_end
 
; write the dns IP Address
mov [dns_ip], ebx
 
ret
 
stack_driver_end:
ret
 
 
 
;***************************************************************************
; Function
; app_socket_handler
;
; Description
; This is an application service, called by int 0x40
; It provides application access to stack socket services
; such as opening sockets
;
;***************************************************************************
app_socket_handler:
cmp eax, 0
jnz nots0
 
call socket_open
ret
 
nots0:
cmp eax, 1
jnz nots1
 
call socket_close
ret
 
nots1:
cmp eax, 2
jnz nots2
 
call socket_poll
ret
 
nots2:
cmp eax, 3
jnz nots3
 
call socket_read
ret
 
nots3:
cmp eax, 4
jnz nots4
 
call socket_write
ret
 
nots4:
cmp eax, 5
jnz nots5
 
call socket_open_tcp
ret
 
nots5:
cmp eax, 6
jnz nots6
 
call socket_status
ret
 
nots6:
cmp eax, 7
jnz nots7
 
call socket_write_tcp
ret
 
nots7:
cmp eax, 8
jnz nots8
 
call socket_close_tcp
ret
 
nots8:
cmp eax, 9
jnz nots9
 
call is_localport_unused
ret
 
nots9:
cmp eax, 254
jnz notdump
 
ret
 
notdump:
cmp eax, 255
jnz notsdebug
 
; This sub function allows access to debugging information on the stack
; ebx 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 )
 
call stack_internal_status
ret
 
notsdebug:
; Invalid Option
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
;
;***************************************************************************
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,[0x3010]
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,[0x3010]
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
 
 
 
;***************************************************************************
; Function
; socket_open
;
; Description
; find a free socket
; local port in ebx
; remote port in ecx
; remote ip in edx
; return socket # in eax, -1 if none available
;
;***************************************************************************
socket_open:
call get_free_socket
 
cmp eax, 0xFFFFFFFF
jz so_exit
 
; ax holds the socket number that is free. Get real address
push eax
shl eax, 12
add eax, sockets
 
mov [eax], dword SOCK_OPEN
 
mov [eax + 12], byte bh ; Local port ( LS 16 bits )
mov [eax + 13], byte bl ; Local port ( LS 16 bits )
mov ebx, [stack_ip]
mov [eax + 8], ebx ; Local IP
mov [eax + 20], ch ; Remote Port ( LS 16 bits )
mov [eax + 21], cl ; Remote Port ( LS 16 bits )
mov [eax + 16], edx ; Remote IP ( in Internet order )
mov [eax + 24], dword 0 ; recieved data count
 
mov esi, [0x3010]
mov ebx, [esi+TASKDATA.pid]
mov [eax + 4], ebx ; save the process ID
pop eax ; Get the socket number back, so we can return it
 
so_exit:
ret
 
 
 
;***************************************************************************
; Function
; socket_open_tcp
;
; Description
; Opens a TCP socket in PASSIVE or ACTIVE mode
; find a free socket
; local port in ebx ( intel format )
; remote port in ecx ( intel format )
; remote ip in edx ( in Internet byte order )
; Socket open mode in esi ( SOCKET_PASSIVE or SOCKET_ACTIVE )
; return socket # in eax, -1 if none available
;
;***************************************************************************
socket_open_tcp:
call get_free_socket
 
cmp eax, 0xFFFFFFFF
jz so_exit
 
; ax holds the socket number that is free. Get real address
push eax
shl eax, 12
add eax, sockets
 
mov [sktAddr], eax
mov [eax], dword SOCK_OPEN
 
; TODO - check this works!
mov [eax + 72], dword 0 ; Reset the window timer.
 
mov [eax + 12], byte bh ; Local port ( LS 16 bits )
mov [eax + 13], byte bl ; Local port ( LS 16 bits )
mov ebx, [stack_ip]
mov [eax + 8], ebx ; Local IP
mov [eax + 20], ch ; Remote Port ( LS 16 bits )
mov [eax + 21], cl ; Remote Port ( LS 16 bits )
mov [eax + 16], edx ; Remote IP ( in Internet order )
mov [eax + 24], dword 0 ; recieved data count
 
; Now fill in TCB state
mov ebx, TCB_LISTEN
cmp esi, SOCKET_PASSIVE
jz sot_001
mov ebx, TCB_SYN_SENT
 
sot_001:
mov [eax + 28], ebx ; Indicate the state of the TCB
 
mov esi, [0x3010]
mov ecx, [esi+TASKDATA.pid]
mov [eax + 4], ecx ; save the process ID
 
cmp ebx, TCB_LISTEN
je sot_done
 
; 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 sot_done
 
push eax
 
mov bl, 0x02 ; SYN
mov ecx, 0
 
call buildTCPPacket
 
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne sot_notlocal
mov eax, IPIN_QUEUE
 
sot_notlocal:
; Send it.
pop ebx
call queue
 
mov esi, [sktAddr]
 
; increment SND.NXT in socket
add esi, 48
call inc_inet_esi
 
sot_done:
pop eax ; Get the socket number back, so we can return it
 
sot_exit:
ret
 
 
 
;***************************************************************************
; Function
; socket_close
;
; Description
; socket # in ebx
; returns 0 for ok, -1 for socket not open (fail)
;
;***************************************************************************
socket_close:
shl ebx, 12
add ebx, sockets
mov eax, 0xFFFFFFFF ; assume this operation will fail..
cmp [ebx], dword SOCK_EMPTY
jz sc_exit
 
; Clear the socket varaibles
xor eax, eax
mov edi,ebx
mov ecx,SOCKETHEADERSIZE
cld
rep stosb
 
sc_exit:
ret
 
 
 
;***************************************************************************
; Function
; socket_close_tcp
;
; Description
; socket # in ebx
; returns 0 for ok, -1 for socket not open (fail)
;
;***************************************************************************
socket_close_tcp:
; first, remove any resend entries
pusha
 
mov esi, resendQ
mov ecx, 0
 
sct001:
cmp ecx, NUMRESENDENTRIES
je sct003 ; None left
cmp [esi], bl
je sct002 ; found one
inc ecx
add esi, 4
jmp sct001
 
sct002:
dec dword [arp_rx_count] ; ************ TEST ONLY!
 
mov [esi], byte 0xFF
jmp sct001
 
sct003:
popa
 
shl ebx, 12
add ebx, sockets
mov [sktAddr], ebx
mov eax, 0xFFFFFFFF ; assume this operation will fail..
cmp [ebx], dword SOCK_EMPTY
jz sct_exit
 
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je stl_exit
 
push eax
 
mov bl, 0x11 ; FIN + ACK
mov ecx, 0
mov esi, 0
 
call buildTCPPacket
 
mov ebx, [sktAddr]
 
; increament SND.NXT in socket
mov esi, 48
add esi, ebx
call inc_inet_esi
 
 
; Get the socket state
mov eax, [ebx + 28]
cmp eax, TCB_LISTEN
je destroyTCB
cmp eax, TCB_SYN_SENT
je destroyTCB
cmp eax, TCB_SYN_RECEIVED
je sct_finwait1
cmp eax, TCB_ESTABLISHED
je sct_finwait1
 
; assume CLOSE WAIT
; Send a fin, then enter last-ack state
mov eax, TCB_LAST_ACK
mov [ebx + 28], eax
xor eax, eax
jmp sct_send
 
sct_finwait1:
; Send a fin, then enter finwait2 state
mov eax, TCB_FIN_WAIT_1
mov [ebx + 28], eax
xor eax, eax
 
sct_send:
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne sct_notlocal
mov eax, IPIN_QUEUE
 
sct_notlocal:
; Send it.
pop ebx
call queue
jmp sct_exit
 
destroyTCB:
pop eax
; Clear the socket varaibles
xor eax, eax
mov edi,ebx
mov ecx,SOCKETHEADERSIZE
cld
rep stosb
 
sct_exit:
ret
 
 
 
;***************************************************************************
; Function
; socket_poll
;
; Description
; socket # in ebx
; returns count in eax.
;
;***************************************************************************
socket_poll:
shl ebx, 12
add ebx, sockets
mov eax, [ebx + 24]
 
ret
 
 
 
;***************************************************************************
; Function
; socket_status
;
; Description
; socket # in ebx
; returns TCB state in eax.
;
;***************************************************************************
socket_status:
shl ebx, 12
add ebx, sockets
mov eax, [ebx + 28]
 
ret
 
 
 
;***************************************************************************
; Function
; socket_read
;
; Description
; socket # in ebx
; returns # of bytes remaining in eax, data in bl
;
;***************************************************************************
socket_read:
shl ebx, 12
add ebx, sockets
mov eax, [ebx + 24] ; get count of bytes
mov ecx,1
test eax, eax
jz sr2
 
dec eax
mov esi, ebx ; esi is address of socket
mov [ebx + 24], eax ; store new count
movzx ebx, byte [ebx + SOCKETHEADERSIZE] ; get the byte
add esi, SOCKETHEADERSIZE
mov edi, esi
inc esi
 
mov ecx, (SOCKETBUFFSIZE - SOCKETHEADERSIZE) / 4
cld
rep movsd
xor ecx, ecx
 
sr1:
jmp sor_exit
 
sr2:
xor bl, bl
 
sor_exit:
ret
 
 
 
;***************************************************************************
; Function
; socket_write
;
; Description
; socket in ebx
; # of bytes to write in ecx
; pointer to data in edx
; returns 0 in eax ok, -1 == failed ( invalid socket, or
; could not queue IP packet )
;
;***************************************************************************
socket_write:
; First, find the address of the socket descriptor
shl ebx, 12
add ebx, sockets ; ebx = address of actual socket
 
mov eax, 0xFFFFFFFF
; If the socket is invalid, return with an error code
cmp [ebx], dword SOCK_EMPTY
je sw_exit
 
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je sw_exit
 
; 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 + 8]
mov [edx + 12], eax ; source IP
mov eax, [ebx + 16]
mov [edx + 16], eax ; Destination IP
 
mov al, 0x45
mov [edx], al ; Version, IHL
xor al, al
mov [edx + 1], al ; Type of service
 
pop eax ; Get the UDP data length
push eax
 
add eax, 20 + 8 ; add IP header and UDP header lengths
mov [edx + 2], ah
mov [edx + 3], al
xor al, al
mov [edx + 4], al
mov [edx + 5], al
mov al, 0x40
mov [edx + 6], al
xor al, al
mov [edx + 7], al
mov al, 0x20
mov [edx + 8], al
mov al, 17
mov [edx + 9], al
 
; Checksum left unfilled
xor ax, ax
mov [edx + 10], ax
 
; Fill in the UDP header ( some data is in the socket descriptor)
mov ax, [ebx + 12]
mov [edx + 20], ax
 
mov ax, [ebx + 20]
mov [edx + 20 + 2], ax
 
pop eax
push eax
 
add eax, 8
mov [edx + 20 + 4], ah
mov [edx + 20 + 5], al
 
; Checksum left unfilled
xor ax, ax
mov [edx + 20 + 6], 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,[0x3010]
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 + 12]
mov [pseudoHeader], eax
mov eax, [edx + 16]
mov [pseudoHeader+4], eax
mov ax, 0x1100 ; 0 + protocol
mov [pseudoHeader+8], ax
add ebx, 8
mov eax, ebx
mov [pseudoHeader+10], ah
mov [pseudoHeader+11], al
 
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')
cmp ax, 0
jne sw_001
mov ax, 0xffff
 
sw_001:
mov [edx + 20 + 6], ah
mov [edx + 20 + 7], al
 
; Fill in the IP header checksum
mov eax, edx
mov [checkAdd1], eax
mov [checkSize1], word 20
mov [checkAdd2], dword 0
mov [checkSize2], word 0
 
call checksum
 
mov ax, [checkResult]
mov [edx + 10], ah
mov [edx + 11], al
 
; 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 + 16]
mov edx, [stack_ip]
cmp edx, ecx
jne sw_notlocal
mov eax, IPIN_QUEUE
 
sw_notlocal:
; Send it.
call queue
 
xor eax, eax
 
sw_exit:
ret
 
 
 
;***************************************************************************
; Function
; socket_write_tcp
;
; Description
; socket in ebx
; # of bytes to write in ecx
; pointer to data in edx
; returns 0 in eax ok, -1 == failed ( invalid socket, or
; could not queue IP packet )
;
;***************************************************************************
socket_write_tcp:
; First, find the address of the socket descriptor
shl ebx, 12
add ebx, sockets ; ebx = address of actual socket
 
mov [sktAddr], ebx
 
mov eax, 0xFFFFFFFF
; If the socket is invalid, return with an error code
cmp [ebx], dword SOCK_EMPTY
je swt_exit
 
; If the sockets window timer is nonzero, do not queue packet
; TODO - done
cmp [ebx + 72], dword 0
jne swt_exit
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je swt_exit
 
push eax
 
mov bl, 0x10 ; ACK
 
; Get the address of the callers data
mov edi,[0x3010]
add edi,TASKDATA.mem_start
add edx,[edi]
mov esi, edx
 
pop eax
push eax
 
push ecx
call buildTCPPacket
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, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne swt_notlocal
mov eax, IPIN_QUEUE
 
swt_notlocal:
pop ecx
 
push ebx ; save ipbuffer number
 
call queue
 
mov esi, [sktAddr]
 
; increament SND.NXT in socket
; Amount to increment by is in ecx
add esi, 48
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
 
swt003:
cmp ecx, NUMRESENDENTRIES
je swt001 ; None found
cmp [esi], byte 0xFF
je swt002 ; found one
inc ecx
add esi, 4
jmp swt003
 
swt002:
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
 
mov eax, [sktAddr]
sub eax, sockets
shr eax, 12 ; get skt #
mov [esi], al
mov [esi + 1], byte TCP_RETRIES
mov [esi + 2], word TCP_TIMEOUT
 
inc ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
mov edi, resendBuffer - IPBUFFSIZE
swt002a:
add edi, IPBUFFSIZE
loop swt002a
 
; 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
 
inc dword [arp_rx_count] ; ************ TEST ONLY!
 
swt001:
xor eax, eax
 
swt_exit:
ret
 
 
 
; Below, the main network layer source code is included
;
 
include "queue.inc"
include "ip.inc"
include "tcp.inc"
include "udp.inc"
include "eth_drv/ethernet.inc"
/kernel/tags/kolibri0.6.3.0/network/tcp.inc
0,0 → 1,1243
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; TCP.INC ;;
;; ;;
;; TCP Processes for Menuet OS TCP/IP stack ;;
;; ;;
;; Version 0.6 4th July 2004 ;;
;; ;;
;; 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 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
;*******************************************************************
; 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
;
;*******************************************************************
 
 
 
;***************************************************************************
; Function
; tcp_tcb_handler
;
; Description
; Handles sockets in the timewait state, closing them
; when the TCB timer expires
;
;***************************************************************************
tcp_tcb_handler:
; scan through all the sockets, decrementing active timers
 
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
 
tth1:
sub eax, SOCKETBUFFSIZE
cmp [eax + sockets + 32], dword 0
jne tth2
 
tth1a:
cmp [eax + sockets + 72], dword 0
jne tth4
 
loop tth1
ret
 
tth2:
; decrement it, delete socket if TCB timer = 0 & socket in timewait state
pusha
dec dword [eax + sockets + 32]
cmp [eax + sockets + 32], dword 0
jne tth3
 
cmp [eax + sockets + 28], dword TCB_TIME_WAIT
jne tth3
 
; OK, delete socket
mov edi, eax
add edi, sockets
 
xor eax, eax
mov ecx, SOCKETHEADERSIZE
cld
rep stosb
 
tth3:
popa
 
jmp tth1a
 
loop tth1
ret
 
; TODO - prove it works!
tth4:
dec dword [eax + sockets + 72]
loop tth1
ret
 
 
 
 
tth_exit:
ret
 
 
;***************************************************************************
; Function
; tcp_tx_handler
;
; Description
; Handles queued TCP data
; This is a kernel function, called by stack_handler
;
;***************************************************************************
tcp_tx_handler:
; 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
 
tth001:
cmp ecx, NUMRESENDENTRIES
je tth003 ; None left
cmp [esi], byte 0xFF
jne tth002 ; found one
inc ecx
add esi, 4
jmp tth001
 
tth002:
; we have one. decrement it's timer by 1
dec word [esi+2]
mov ax, [esi+2]
cmp ax, 0
je tth002a
inc ecx
add esi, 4
jmp tth001 ; Timer not zero, so move on
 
tth002a:
mov bl, 0xff
; 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]
mov al, [esi+1]
cmp al, 0
jne tth004
 
; retries now 0, so delete from queue
xchg [esi], bl
tth004:
 
; resend packet
pusha
 
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
jne tth004z
 
; TODO - try again in 10ms.
cmp bl, 0xff
jne tth004za
mov [esi], bl
 
tth004za:
; Mark it to expire in 10ms - 1 tick
mov [esi+1], byte 1
mov [esi+2], word 1
jmp tth005
 
tth004z:
; we have a buffer # in ax
 
push eax
push ecx
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
 
; we have the buffer address in eax
mov edi, eax
pop ecx
; get resend data address
inc ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
mov esi, resendBuffer - IPBUFFSIZE
tth004a:
add esi, IPBUFFSIZE
loop tth004a
 
; we have resend buffer location in esi
mov ecx, IPBUFFSIZE
 
; copy data across
cld
rep movsb
 
; queue packet
 
 
 
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [ edi + 16 ]
cmp edx, ecx
jne tth004b
mov eax, IPIN_QUEUE
 
tth004b:
pop ebx
 
call queue
 
 
tth005:
popa
 
inc ecx
add esi, 4
jmp tth001
 
tth003:
ret
 
 
 
 
;***************************************************************************
; 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
;
;***************************************************************************
tcp_rx:
; 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 eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
ss1:
sub eax, SOCKETBUFFSIZE
movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr
cmp [eax + sockets + 12], bx ; compare with socket's local port
jnz nxttst1 ; different - try next socket
 
movzx ebx, word [edx + 20] ; get the source port from the TCP hdr
cmp [eax + sockets + 20], bx ; compare with socket's remote port
jnz nxttst1 ; different - try next socket
 
 
mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr
cmp [eax + sockets + 16], ebx ; compare with socket's remote IP
jnz nxttst1 ; different - try next socket
 
; We have a complete match - use this socket
jmp tcprx_001
 
nxttst1:
loop ss1 ; Return back if no match
 
; 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 eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
 
ss2:
sub eax, SOCKETBUFFSIZE
 
movzx ebx, word [edx + 22] ; get the dest. port from the TCP hdr
cmp [eax + sockets + 12], bx ; compare with socket's local port
jnz nxttst2 ; different - try next socket
 
mov ebx, [edx + 12] ; get the source IP Addr from the IP hdr
cmp [eax + sockets + 16], ebx ; compare with socket's remote IP
jnz nxttst2 ; different - try next socket
 
mov ebx, 0
cmp [eax + sockets + 20], bx ; only match a remote socket of 0
jnz nxttst2 ; different - try next socket
 
; We have a complete match - use this socket
jmp tcprx_001
 
nxttst2:
loop ss2 ; Return back if no match
 
; 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 eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
 
ss3:
sub eax, SOCKETBUFFSIZE
 
movzx ebx, word [edx + 22] ; get destination port from the TCP hdr
cmp [eax + sockets + 12], bx ; compare with socket's local port
jnz nxttst3 ; different - try next socket
 
mov ebx, 0
cmp [eax + sockets + 20], bx ; only match a remote socket of 0
jnz nxttst3 ; different - try next socket
 
mov ebx, 0
cmp [eax + sockets + 16], ebx ; only match a socket remote IP of 0
jnz nxttst3 ; different - try next socket
 
; We have a complete match - use this socket
jmp tcprx_001
 
nxttst3:
loop ss3 ; Return back if no match
 
; If we got here, we need to reject the packet
inc dword [dumped_rx_count]
jmp tcprx_exit
 
tcprx_001:
; We have a valid socket/TCB, so call the TCB State Machine for that skt.
; socket is pointed to by [eax + sockets]
; IP packet is pointed to by [edx]
; IP buffer number is on stack ( it will be popped at the end)
call tcpStateMachine
 
tcprx_exit:
pop eax
call freeBuff
 
ret
 
 
 
;***************************************************************************
; 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
;
;***************************************************************************
buildTCPPacket:
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 + 33], bl ; TCP flags
 
mov ebx, [sktAddr]
 
; 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 + 8]
mov [edx + 12], eax ; source IP
mov eax, [ebx + 16]
mov [edx + 16], eax ; Destination IP
 
mov al, 0x45
mov [edx], al ; Version, IHL
xor al, al
mov [edx + 1], al ; Type of service
 
pop eax ; Get the TCP data length
push eax
 
add eax, 20 + 20 ; add IP header and TCP header lengths
mov [edx + 2], ah
mov [edx + 3], al
xor al, al
mov [edx + 4], al
mov [edx + 5], al
mov al, 0x40
mov [edx + 6], al
xor al, al
mov [edx + 7], al
mov al, 0x20
mov [edx + 8], al
mov al, 6 ; TCP protocol
mov [edx + 9], al
 
; Checksum left unfilled
xor ax, ax
mov [edx + 10], ax
 
; Fill in the TCP header ( some data is in the socket descriptor)
mov ax, [ebx + 12]
mov [edx + 20], ax ; Local Port
 
mov ax, [ebx + 20]
mov [edx + 20 + 2], ax ; desitination Port
 
; Checksum left unfilled
xor ax, ax
mov [edx + 20 + 16], ax
 
; sequence number
mov eax, [ebx + 48]
mov [edx + 20 + 4], eax
 
; ack number
mov eax, [ebx + 56]
mov [edx + 20 + 8], eax
 
; window ( 0x2000 is default ).I could accept 4KB, fa0, ( skt buffer size)
; 768 bytes seems better
mov ax, 0x0003
mov [edx + 20 + 14], ax
 
; Urgent pointer (0)
mov ax, 0
mov [edx + 20 + 18], ax
 
; data offset ( 0x50 )
mov al, 0x50
mov [edx + 20 + 12], al
 
pop ecx ; count of bytes to send
mov ebx, ecx ; need the length later
 
cmp ebx, 0
jz btp_001
 
mov edi, edx
add edi, 40
cld
rep movsb ; copy the data across
 
btp_001:
; we have edx as IPbuffer ptr.
; Fill in the TCP checksum
; First, fill in pseudoheader
mov eax, [edx + 12]
mov [pseudoHeader], eax
mov eax, [edx + 16]
mov [pseudoHeader+4], eax
mov ax, 0x0600 ; 0 + protocol
mov [pseudoHeader+8], ax
add ebx, 20
mov eax, ebx
mov [pseudoHeader+10], ah
mov [pseudoHeader+11], al
 
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
 
call checksum
 
; store it in the TCP checksum ( in the correct order! )
mov ax, [checkResult]
 
mov [edx + 20 + 16], ah
mov [edx + 20 + 17], al
 
; Fill in the IP header checksum
mov eax, edx
mov [checkAdd1], eax
mov [checkSize1], word 20
mov [checkAdd2], dword 0
mov [checkSize2], word 0
 
call checksum
 
mov ax, [checkResult]
mov [edx + 10], ah
mov [edx + 11], al
 
ret
 
 
; Increments the 32 bit value pointed to by esi in internet order
inc_inet_esi:
push eax
add esi, 3
mov al, byte[esi]
inc al
mov byte[esi], al
cmp al, 0
jnz iie_exit
dec esi
mov al, byte[esi]
inc al
mov byte[esi], al
cmp al, 0
jnz iie_exit
dec esi
mov al, byte[esi]
inc al
mov byte[esi], al
cmp al, 0
jnz iie_exit
dec esi
mov al, byte[esi]
inc al
mov byte[esi], al
 
iie_exit:
pop eax
ret
 
 
; Increments the 32 bit value pointed to by esi in internet order
; by the value in ecx
add_inet_esi:
push eax
 
mov al, [esi]
shl eax, 8
inc esi
mov al, [esi]
shl eax, 8
inc esi
mov al, [esi]
shl eax, 8
inc esi
mov al, [esi]
add eax, ecx
mov [esi], al
dec esi
shr eax, 8
mov [esi], al
dec esi
shr eax, 8
mov [esi], al
dec esi
shr eax, 8
mov [esi], al
pop eax
ret
 
 
iglobal
TCBStateHandler:
dd stateTCB_LISTEN
dd stateTCB_SYN_SENT
dd stateTCB_SYN_RECEIVED
dd stateTCB_ESTABLISHED
dd stateTCB_FIN_WAIT_1
dd stateTCB_FIN_WAIT_2
dd stateTCB_CLOSE_WAIT
dd stateTCB_CLOSING
dd stateTCB_LAST_ACK
dd stateTCB_TIME_WAIT
dd 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 [eax + sockets]
;
; The IP buffer will be released by the caller
;***************************************************************************
tcpStateMachine:
mov ebx, sockets
add ebx, eax
mov [sktAddr], ebx
 
; as a packet has been received, update the TCB timer
mov ecx, TWOMSL
mov [ebx + 32], ecx
 
; If the received packet has an ACK bit set,
; remove any packets in the resend queue that this
; received packet acknowledges
pusha
mov cl, [edx + 33]
and cl, 0x10
cmp cl, 0x10
jne tsm001 ; No ACK, so no data yet
 
 
; get skt number in al
shr eax, 12
 
; The ack number is in [edx + 28], inet format
; skt in al
 
mov esi, resendQ
mov ecx, 0
 
t001:
cmp ecx, NUMRESENDENTRIES
je t003 ; None left
cmp [esi], al
je t002 ; found one
inc ecx
add esi, 4
jmp t001
 
t002: ; Can we delete this buffer?
 
; If yes, goto t004. No, goto t001
; Get packet data address
 
push ecx
inc ecx
; Now get buffer location, and copy buffer across. argh! more copying,,
mov edi, resendBuffer - IPBUFFSIZE
t002a:
add edi, IPBUFFSIZE
loop t002a
 
; we have dest buffer location in edi. incoming packet in edx.
; Get this packets sequence number
; preserve al, ecx, esi, edx
 
mov cl, [edi + 24]
shl ecx, 8
mov cl, [edi + 25]
shl ecx, 8
mov cl, [edi + 26]
shl ecx, 8
mov cl, [edi + 27]
movzx ebx, byte [edi + 3]
mov bh, [edi + 2]
sub ebx, 40
add ecx, ebx ; ecx is now seq# of last byte +1, intel format
 
; get recievd ack #, in intel format
mov bl, [edx + 28]
shl ebx, 8
mov bl, [edx + 29]
shl ebx, 8
mov bl, [edx + 30]
shl ebx, 8
mov bl, [edx + 31]
 
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 t004 ; if rx > old, delete old
inc ecx
add esi, 4
jmp t001
 
 
t004:
dec dword [arp_rx_count] ; ************ TEST ONLY!
 
mov [esi], byte 0xFF
inc ecx
add esi, 4
jmp t001
 
t003:
 
tsm001:
popa
 
; Call handler for given TCB state
mov ebx, [eax + sockets+28]
cmp ebx, TCB_LISTEN
jb tsm_exit
cmp ebx, TCB_CLOSED
ja tsm_exit
 
dec ebx
call dword [TCBStateHandler+ebx*4]
 
tsm_exit:
ret
 
 
 
stateTCB_LISTEN:
; 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
mov bl, [edx + 33]
and bl, 0x02
cmp bl, 0x02
jnz stl_exit
 
; We have a SYN. update the socket with this IP packets details,
; And send a response
 
mov ebx, [edx + 12] ; IP source address
mov [eax + sockets + 16], ebx
mov bx, [edx + 20] ; IP source port
mov [eax + sockets + 20], bx
mov ebx, [edx + 24] ; IRS
mov [eax + sockets + 40], ebx
mov [eax + sockets + 56], ebx
mov esi, sockets
add esi, eax
add esi, 56
call inc_inet_esi ; RCV.NXT
mov ebx, [eax + sockets + 36] ; ISS
mov [eax + sockets + 48], ebx ; SND.NXT
 
; Now construct the response, and queue for sending by IP
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je stl_exit
 
push eax
mov bl, 0x12 ; SYN + ACK
mov ecx, 0
mov esi, 0
 
call buildTCPPacket
 
mov eax, NET1OUT_QUEUE
mov edx, [stack_ip]
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne stl_notlocal
mov eax, IPIN_QUEUE
 
stl_notlocal:
; Send it.
pop ebx
call queue
 
 
mov ebx, TCB_SYN_RECEIVED
mov esi, [sktAddr]
mov [esi + 28], ebx
 
; increament SND.NXT in socket
add esi, 48
call inc_inet_esi
 
stl_exit:
ret
 
 
 
stateTCB_SYN_SENT:
; We are awaiting an ACK to our SYN, with a SYM
; Look at control flags - expecting an ACK
mov bl, [edx + 33]
and bl, 0x12
cmp bl, 0x12
jnz stss_exit
 
mov ebx, TCB_ESTABLISHED
mov esi, [sktAddr]
mov [esi + 28], ebx
 
; Store the recv.nxt field
mov eax, [edx + 24]
 
; Update our recv.nxt field
mov esi, [sktAddr]
add esi, 56
mov [esi], eax
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
je stss_exit
 
push eax
 
mov bl, 0x10 ; ACK
mov ecx, 0
mov esi, 0
 
call buildTCPPacket
 
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne stss_notlocal
mov eax, IPIN_QUEUE
 
stss_notlocal:
; Send it.
pop ebx
call queue
 
stss_exit:
ret
 
 
 
stateTCB_SYN_RECEIVED:
; In this case, we are expecting an ACK packet
; For now, if the packet is an ACK, process it,
; If not, ignore it
 
; Look at control flags - expecting an ACK
mov bl, [edx + 33]
and bl, 0x10
cmp bl, 0x10
jnz stsr_exit
 
mov ebx, TCB_ESTABLISHED
mov esi, [sktAddr]
mov [esi + 28], ebx
 
stsr_exit:
ret
 
 
 
stateTCB_ESTABLISHED:
; Here we are expecting data, or a request to close
; OR both...
 
; Did we receive a FIN or RST?
mov bl, [edx + 33]
and bl, 0x05
cmp bl, 0
je ste_chkack
 
; It was a fin or reset.
 
; Remove resend entries from the queue - I dont want to send any more data
pusha
 
mov ebx, [sktAddr]
sub ebx, sockets
shr ebx, 12 ; get skt #
 
mov esi, resendQ
mov ecx, 0
 
ste001:
cmp ecx, NUMRESENDENTRIES
je ste003 ; None left
cmp [esi], bl
je ste002 ; found one
inc ecx
add esi, 4
jmp ste001
 
ste002:
dec dword [arp_rx_count] ; ************ TEST ONLY!
 
mov [esi], byte 0xFF
jmp ste001
 
ste003:
popa
 
; was it a reset?
mov bl, [edx + 33]
and bl, 0x04
cmp bl, 0x04
jne ste003a
 
mov esi, [sktAddr]
mov ebx, TCB_CLOSED
mov [esi + 28], ebx
jmp ste_exit
 
ste003a:
; Send an ACK to that fin, and enter closewait state
 
mov esi, [sktAddr]
mov ebx, TCB_CLOSE_WAIT
mov [esi + 28], ebx
add esi, 56
mov eax, [esi] ; save original
call inc_inet_esi
;; jmp ste_ack - NO, there may be data
 
ste_chkack:
; Check that we received an ACK
mov bl, [edx + 33]
and bl, 0x10
cmp bl, 0x10
jnz ste_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 ch, [edx + 34]
mov cl, [edx + 35]
cmp cx, 1024
ja ste004
 
mov ecx, [sktAddr]
mov [ecx+72], dword 1
 
ste004:
 
; OK, here is the deal
; My recv.nct field holds the seq of the expected next rec byte
; if the recevied sequence number is not equal to this, do not
; increment the recv.nxt field, do not copy data - just send a
; repeat ack.
 
; recv.nxt is in dword [edx+24], in inext format
; recv seq is in [sktAddr]+56, in inet format
; just do a comparision
mov ecx, [sktAddr]
add ecx, 56
 
cmp [ecx - 56 + 28], dword TCB_CLOSE_WAIT
mov ecx, [ecx]
jne stenofin
mov ecx, eax
 
stenofin:
cmp ecx, [edx+24]
jne ste_ack
 
 
; Read the data bytes, store in socket buffer
xor ecx, ecx
mov ch, [edx + 2]
mov cl, [edx + 3]
sub ecx, 40 ; Discard 40 bytes of header
 
cmp ecx, 0
jnz ste_data ; Read data, if any
 
; If we had received a fin, we need to ACK it.
mov esi, [sktAddr]
mov ebx, [esi + 28]
cmp ebx, TCB_CLOSE_WAIT
jz ste_ack
jnz ste_exit
 
ste_data:
push ecx
mov esi, [sktAddr]
 
add [esi + 24], ecx ; increment the count of bytes in buffer
 
mov eax, [esi + 4] ; get socket owner PID
push eax
 
mov eax, [esi + 24] ; get # of bytes already in buffer
 
; point to the location to store the data
add esi, eax
sub esi, ecx
add esi, SOCKETHEADERSIZE
 
add edx, 40 ; edx now points to the data
mov edi, esi
mov esi, edx
 
cld
rep movsb ; copy the data across
 
; flag an event to the application
pop eax
mov ecx,1
mov esi,0x3020+TASKDATA.pid
 
news:
cmp [esi],eax
je foundPID1
inc ecx
add esi,0x20
cmp ecx,[0x3004]
jbe news
 
foundPID1:
shl ecx,8
or dword [ecx+0x80000+APPDATA.event_mask],dword 10000000b ; stack event
 
pop ecx
 
; Update our recv.nxt field
mov esi, [sktAddr]
add esi, 56
call add_inet_esi
 
ste_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 ste_exit
 
push eax
 
mov bl, 0x10 ; ACK
mov ecx, 0
mov esi, 0
 
call buildTCPPacket
 
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne ste_notlocal
mov eax, IPIN_QUEUE
ste_notlocal:
 
; Send it.
pop ebx
call queue
 
ste_exit:
ret
 
 
 
stateTCB_FIN_WAIT_1:
; We can either receive an ACK of a fin, or a fin
mov bl, [edx + 33]
and bl, 0x10
cmp bl, 0x10
jnz stfw1_001
 
; It was an ACK
mov esi, [sktAddr]
mov ebx, TCB_FIN_WAIT_2
mov [esi + 28], ebx
jmp stfw1_exit
 
stfw1_001:
; It must be a fin then
mov esi, [sktAddr]
mov ebx, TCB_CLOSING
mov [esi + 28], ebx
add esi, 56
call inc_inet_esi
 
; Send an ACK
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je stfw1_exit
 
push eax
 
mov bl, 0x10 ; ACK
mov ecx, 0
mov esi, 0
 
call buildTCPPacket
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne stfw1_notlocal
mov eax, IPIN_QUEUE
 
stfw1_notlocal:
; Send it.
pop ebx
call queue
 
stfw1_exit:
ret
 
 
 
stateTCB_FIN_WAIT_2:
mov esi, [sktAddr]
 
; Get data length
xor ecx, ecx
mov ch, [edx+2]
mov cl, [edx+3]
sub ecx, 40
 
mov bl, [edx + 33]
and bl, 0x01
cmp bl, 0x01
jne stfw2001
 
; Change state, as we have a fin
mov ebx, TCB_TIME_WAIT
mov [esi + 28], ebx
 
inc ecx ; FIN is part of the sequence space
 
stfw2001:
add esi, 56
call add_inet_esi
 
; Send an ACK
mov eax, EMPTY_QUEUE
call dequeue
cmp ax, NO_BUFFER
je stfw2_exit
 
push eax
 
mov bl, 0x10 ; ACK
mov ecx, 0
mov esi, 0
 
call buildTCPPacket
 
mov eax, NET1OUT_QUEUE
 
mov edx, [stack_ip]
mov ecx, [ sktAddr ]
mov ecx, [ ecx + 16 ]
cmp edx, ecx
jne stfw2_notlocal
mov eax, IPIN_QUEUE
 
stfw2_notlocal:
; Send it.
pop ebx
call queue
 
; Only delete the socket if we received the FIN
 
mov bl, [edx + 33]
and bl, 0x01
cmp bl, 0x01
jne stfw2_exit
 
; mov edi, [sktAddr]
 
; delete the socket. Should really wait for 2MSL
; xor eax, eax
; mov ecx,SOCKETHEADERSIZE
; cld
; rep stosb
 
stfw2_exit:
ret
 
 
 
stateTCB_CLOSE_WAIT:
; Intentionally left empty
; socket_close_tcp handles this
ret
 
 
 
stateTCB_CLOSING:
; We can either receive an ACK of a fin, or a fin
mov bl, [edx + 33]
and bl, 0x10
cmp bl, 0x10
jnz stc_exit
 
; It was an ACK
 
mov edi, [sktAddr]
 
; delete the socket
xor eax, eax
mov ecx,SOCKETHEADERSIZE
cld
rep stosb
 
stc_exit:
ret
 
 
 
stateTCB_LAST_ACK:
; Look at control flags - expecting an ACK
mov bl, [edx + 33]
and bl, 0x10
cmp bl, 0x10
jnz stla_exit
 
mov edi, [sktAddr]
 
; delete the socket
xor eax, eax
mov ecx,SOCKETHEADERSIZE
cld
rep stosb
 
stla_exit:
ret
 
 
 
stateTCB_TIME_WAIT:
ret
 
 
 
stateTCB_CLOSED:
ret
/kernel/tags/kolibri0.6.3.0/network/udp.inc
0,0 → 1,137
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; UDP.INC ;;
;; ;;
;; UDP 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;*******************************************************************
; Interface
;
; udp_rx Handles received IP packets with the UDP protocol
;
;*******************************************************************
;***************************************************************************
; Function
; udp_rx
;
; Description
; UDP protocol handler
; This is a kernel function, called by ip_rx
; IP buffer address given in edx
; Free up (or re-use) IP buffer when finished
;
;***************************************************************************
udp_rx:
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
movzx ebx, word [edx + 22] ; get the local port from
; the IP packet's UDP header
mov eax, SOCKETBUFFSIZE * NUM_SOCKETS
mov ecx, NUM_SOCKETS
fs1:
sub eax, SOCKETBUFFSIZE
cmp [eax + sockets + 12], bx ; bx will hold the 'wrong' value,
; but the comparision is correct
loopnz fs1 ; Return back if no match
jz fs_done
; No match, so exit
jmp udprx_001
fs_done:
; 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
mov ebx, [eax + sockets + 16]
cmp ebx, 0xffffffff
je udprx_002
mov ebx, [edx + 12] ; get the Source address from the IP packet
cmp [eax + sockets + 16], ebx
jne udprx_001 ; Quit if the source IP is not valid
 
udprx_002:
; 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
movzx ebx, word [edx + 20] ; get the UDP source port
; ( was 69, now new )
mov [eax + sockets + 20], bx
; 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, byte [edx + 3] ; total length of IP packet. Subtract
mov ch, byte [edx + 2] ; 20 + 8 gives data length
sub ecx, 28
mov ebx, eax
add ebx, sockets ; ebx = address of actual socket
mov eax, [ebx+ 4] ; get socket owner PID
push eax
mov eax, [ebx + 24] ; get # of bytes already in buffer
add [ebx + 24], ecx ; increment the count of bytes in buffer
; point to the location to store the data
add ebx, eax
add ebx, SOCKETHEADERSIZE
 
; ebx = location for first byte, ecx has count,
; edx points to data
add edx, 28 ; edx now points to the data
mov edi, ebx
mov esi, edx
cld
rep movsb ; copy the data across
; flag an event to the application
pop eax
mov ecx,1
mov esi,0x3020+TASKDATA.pid
newsearch:
cmp [esi],eax
je foundPID
inc ecx
add esi,0x20
cmp ecx,[0x3004]
jbe newsearch
foundPID:
shl ecx,8
or dword [ecx+0x80000+APPDATA.event_mask],dword 10000000b ; stack event
 
mov [check_idle_semaphore],200
 
udprx_001:
pop eax
call freeBuff ; Discard the packet
ret
/kernel/tags/kolibri0.6.3.0/network/eth_drv/ethernet.inc
0,0 → 1,1701
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; ETHERNET.INC ;;
;; ;;
;; Ethernet network layer for Menuet OS ;;
;; ;;
;; Version 0.4 22 September 2003 ;;
;; ;;
;; 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
;********************************************************************
; Interface
; ethernet_driver called by stack_handler in stack.inc
; eth_probe called by app_stack_handler in stack.inc
;
;********************************************************************
 
; 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 "rtl8029.inc"
include "i8255x.inc"
include "rtl8139.inc"
include "3c59x.inc"
include "sis900.inc"
include "pcnet32.inc"
 
; DEBUGGING_STATE enables or disables output of received and transmitted
; data over the serial port
DEBUGGING_ENABLED equ 1
DEBUGGING_DISABLED equ 0
DEBUGGING_STATE equ DEBUGGING_DISABLED
 
; 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 20 ; Size of each PCICARDS entry
 
iglobal
PCICards:
dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
dd 0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
dd 0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
dd 0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
dd 0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit
dd 0x12111113, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit
dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
; /+/ Íîâûå âåíäîðû ñåòåâûõ êàðò íà áàçå rtl8139
dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
; /-/
dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit
dd 0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit
dd 0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit
dd 0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit
; following card is untested
dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit
dd 0,0,0,0,0 ; end of list marker, do not remove
endg
 
; 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
 
ETHER_IP equ 0x0008 ; Reversed from 0800 for intel
ETHER_ARP equ 0x0608 ; Reversed from 0806 for intel
ETHER_RARP equ 0x3580
ARP_REQ_OPCODE equ 0x0100
ARP_REP_OPCODE equ 0x0200
 
uglobal
arp_rx_count: dd 0
ip_rx_count: dd 0
dumped_rx_count: dd 0
ip_tx_count: dd 0
node_addr: db 0,0,0,0,0,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
 
; These hold the destination Host identity for ARP responses
remote_ip_add: dd 0
remote_hw_add: db 0, 0, 0, 0, 0, 0
endg
 
iglobal
broadcast_add: db 0xff,0xff,0xff,0xff,0xff,0xff
subnet_mask: dd 0x00ffffff
endg
 
uglobal
; This is used by getMACfromIP
MACAddress: db 0,0,0,0,0,0
gateway_ip: db 0, 0, 0, 0
dns_ip: dd 0
endg
 
; The follow is the ARP Table.
; This table must be manually updated and the kernel recompilied if
; changes are made to it.
; ARP_TABLE_SIZE defines the size of the table
; ARP_TABLE_ENTRIES defines the number of entries in the table
; Each entry is 10 bytes: 4 Byte IP address, 6 byte MAC Address,
; 2 bytes status, 2 bytes TTL ( in seconds )
; Empty entries are filled with zeros
; 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 permanent 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
 
ARP_NO_ENTRY equ 0
ARP_VALID_MAPPING equ 1
ARP_AWAITING_RESPONSE equ 2
ARP_RESPONSE_TIMEOUT equ 3
 
ARP_ENTRY_SIZE equ 14 ; Number of bytes per entry
ARP_TABLE_SIZE equ 20 ; Size of table
ARP_TABLE_ENTRIES equ 0 ; Inital, hardcoded entries
 
uglobal
ARPTable:
times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE db 0
endg
 
iglobal
NumARP: db ARP_TABLE_ENTRIES
endg
 
;***************************************************************************
; 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 erx_exit
 
if DEBUGGING_STATE = DEBUGGING_ENABLED
pusha
mov eax, 0 ;Indicate that this is a received packet
mov cx, [eth_rx_data_len]
mov esi, Ether_buffer
cmp word [esi + 12], ETHER_IP
jnz erxd_done
; cmp byte [esi + 14 + 9], 0x06 ; TCP
; jnz erxd_done
call eth_dump
erxd_done:
popa
end if
 
; Check the protocol. Call appropriate handler
mov eax, Ether_buffer
add eax, 12 ; The address of the protocol word
 
mov ax, [eax]
 
cmp ax, ETHER_ARP
je erx_001 ; It is ARP
 
cmp ax, ETHER_IP
je erx_002 ; It's IP
 
; inc dword [dumped_rx_count]
 
jmp erx_exit ; If not IP or ARP, ignore
 
erx_001:
mov eax, [arp_rx_count]
inc eax
mov [arp_rx_count], eax
 
; At this point, the packet is still in the Ether_buffer
call arp_handler
 
jmp erx_exit
 
erx_002:
mov eax, [ip_rx_count]
inc eax
mov [ip_rx_count], eax
 
; Check to see if the MAC address is in our arp table
; refresh the arp ttl if so
 
mov esi, Ether_buffer
add esi, 6
 
call refreshARP
 
call ether_IP_handler
 
jmp erx_exit
 
erx_exit:
ret
 
;***************************************************************************
; 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
;
;***************************************************************************
eth_tx:
; Look for a buffer to tx
mov eax, NET1OUT_QUEUE
call dequeue
cmp ax, NO_BUFFER
je eth_exit ; Exit if no buffer available
 
push eax
 
; convert buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
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 )
mov [MACAddress], dword 0xffffffff
mov [MACAddress + 4], word 0xffff
cmp edx, 0xffffffff
je etx_send ; If it is broadcast, just send
 
call getMACfromIP ; Get the MAC address.
 
cmp eax, ARP_VALID_MAPPING
jz etx_send
 
; No valid entry. Are we waiting for a response?
cmp eax, ARP_AWAITING_RESPONSE
jne etx_001
 
; Re-queue the packet, and exit
pop ebx
mov eax, NET1OUT_QUEUE
call queue
jmp etx_exit
 
etx_001:
; HAs the request been sent, but timed out?
cmp eax, ARP_RESPONSE_TIMEOUT
jne etx_002
 
pop eax
call freeBuff
jmp etx_exit
 
etx_002:
; There is no entry. Re queue the request, and ask ARP to send a request
 
; IP address is in edx
push edx
call arp_request
pop ebx
 
; Add an entry in the ARP table, awaiting response
 
cmp byte [NumARP], ARP_TABLE_SIZE
je etx_003 ; We cannot add a new entry in the table
 
inc byte [NumARP]
 
movzx eax, byte [NumARP]
mov ecx, ARP_ENTRY_SIZE
mul ecx
sub eax, ARP_ENTRY_SIZE
 
mov [eax + ARPTable], ebx
xor ebx, ebx
mov [eax + ARPTable + 4], ebx
mov [eax + ARPTable + 8], bx
 
; set the status field up - awaiting response
mov cl, 0x00
mov [eax + ARPTable + 10], cl
mov cl, 0x02
mov [eax + ARPTable + 11], cl
 
; Initialise the time to live field - 10s
mov cx, 0x000A
mov [eax + ARPTable + 12], cx
 
etx_003:
pop ebx ; Get the buffer back
mov eax, NET1OUT_QUEUE
call queue
jmp etx_exit
 
etx_send:
xor ecx, ecx
mov ch, [ebx+2]
mov cl, [ebx+3] ; ; Size of IP packet to send
 
mov esi, ebx
 
mov edi, MACAddress
 
if DEBUGGING_STATE = DEBUGGING_ENABLED
pusha
mov cx, 42
mov eax, 1 ; Indicate that this is a tx packet
call eth_dump
popa
end if
 
mov bx, ETHER_IP
call dword [drvr_transmit] ; Call the drivers transmit function
 
; OK, we have sent a packet, so increment the count
inc dword [ip_tx_count]
 
; And finally, return the buffer to the free queue
pop eax
call freeBuff
 
etx_exit:
ret
 
;***************************************************************************
; 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
;
;***************************************************************************
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, Ether_buffer + 14
 
; Now store it all away
mov ecx, IPBUFFSIZE / 4 ; Copy all of the available
; data across - worse case
cld
rep movsd
 
; And finally, place the buffer in the IPRX queue
pop ebx
mov eax, IPIN_QUEUE
call queue
 
eiph00x:
ret
 
;***************************************************************************
;
; ARP CODE FOLLOWS
;
; The ARP code is used by ethernet drivers to translate an destination
; IP address into an ethernet hardware address. Functions to broadcast
; requests and handle response are (or will be) here.
; The IP layer has no knowledge of ARP, as this is a network interface
; issue
;
;***************************************************************************
 
;***************************************************************************
; Function
; arp_timer
;
; Description
; Called every 1s
; It is responsible for removing expired routes
; All registers may be destroyed
;
;***************************************************************************
arp_timer:
; loop through all the ARP entries, decrementing each one
; that doesn't have a TTL of 0xFFFF
movzx eax, byte [NumARP]
 
arp_001:
cmp eax, 0
je arp_003
 
push eax
dec eax
mov ecx, ARP_ENTRY_SIZE
mul ecx
cmp word [ eax + ARPTable + 12], 0xFFFF
je arp_002
 
cmp word [ eax + ARPTable + 12], 0
je arp_002
 
dec word [eax + ARPTable + 12]
 
arp_002:
pop eax
dec eax
jmp arp_001
 
; Now, look for entries with a TTL of 0
; Valid entries and response timeout entries get removed
; awaiting response gets converted into a response timeout, with a
; short life time - this allows queued packets to be flushed
arp_003:
movzx edx, byte [NumARP]
cmp edx, 0
je arp_exit
 
; EDX holds the # of entries to search through
mov eax, 0
 
arp_005:
cmp word [ eax + ARPTable + 12], 0
jne arp_004
 
; If it's status code is 0001 or 0003, delete the entry
cmp word [eax + ARPTable + 10], 0x0100
je arp_007
cmp word [eax + ARPTable + 10], 0x0300
je arp_007
 
; The only other valid code is 0002 - indicating a
; timeout while waiting for a response. Change the
; entry to response timed out
 
mov [eax + ARPTable + 10], word 0x0300
mov [eax + ARPTable + 12], word 0x000A
jmp arp_004
 
arp_007:
; Delete this entry
mov edi, ARPTable
add edi, eax
mov esi, edi
add esi, ARP_ENTRY_SIZE
 
mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE
sub ecx, eax
 
rep movsb
 
dec byte [NumARP]
jmp arp_006
 
arp_004:
add eax, ARP_ENTRY_SIZE
arp_006:
dec edx
cmp edx, 0
jne arp_005
 
arp_exit:
ret
 
;***************************************************************************
; Function
; arp_request
;
; Description
; Sends an ARP request on the ethernet
; The requested IP address is in edx
; All registers may be destroyed
;
;***************************************************************************
arp_request:
mov ebx, Ether_buffer
mov ax, 0x0100
mov [ebx], ax
add ebx, 2
 
mov ax, 0x0008
mov [ebx], ax
add ebx, 2
 
mov ax, 0x0406
mov [ebx], ax
add ebx, 2
 
mov ax, 0x0100
mov [ebx], ax
add ebx, 2
 
mov ecx, node_addr
mov eax, [ecx]
mov [ebx], eax
add ecx, 4
add ebx, 4
mov ax, [ecx]
mov [ebx], ax
add ebx, 2
mov eax, [stack_ip]
mov [ebx], eax
add ebx, 4
 
xor eax, eax
mov [ebx], eax
add ebx, 4
mov [ebx], ax
 
add ebx, 2
mov [ebx], edx
 
; Now, send it!
 
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
mov edi, broadcast_add
 
;if DEBUGGING_STATE = DEBUGGING_ENABLED
; pusha
; mov eax, 1 ; Indicate that this is a tx packet
; mov ecx, 28
; mov esi, Ether_buffer
; call eth_dump
; popa
;end if
 
mov bx, ETHER_ARP
mov ecx, 28
mov esi, Ether_buffer
call dword [drvr_transmit] ; Call the drivers transmit function
ret
 
;***************************************************************************
; 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
 
mov ebx, Ether_buffer
 
mov edx, ebx
add edx, 20
mov ax, [edx]
cmp ax, ARP_REQ_OPCODE ; Is this a request packet?
jne arph_resp ; No - so test for response
 
mov edx, ebx
add edx, 38
mov eax, [edx]
 
cmp eax, [stack_ip] ; Is it looking for my IP address?
jne arph_exit ; No - so quit now
 
; OK, it is a request for my MAC address. Build the frame and send it
 
; Save the important data from the original packet
; remote MAC address first
mov ecx, remote_hw_add
mov edx, ebx
add edx, 22 ; edx points to Source h/w address
mov eax, [edx]
mov [ecx], eax
add edx, 4
add ecx, 4
mov ax, [edx]
mov [ecx],ax
 
; and also the remote IP address
add edx, 2
mov eax,[edx]
mov [remote_ip_add], eax
 
; So now we can reuse the packet. ebx still holds the address of
; the header + packet
; We dont need the header ( first 14 bytes )
 
mov edx, ebx
add edx, 20
mov ax, ARP_REP_OPCODE
mov [edx], ax
add edx, 2
 
mov ecx, node_addr
mov eax, [ecx]
mov [edx], eax
add ecx, 4
add edx, 4
mov ax, [ecx]
mov [edx], ax
add edx, 2
mov eax, [stack_ip]
mov [edx], eax
add edx, 4
mov ecx, remote_hw_add
mov eax, [ecx]
mov [edx], eax
add ecx, 4
add edx, 4
mov ax, [ecx]
mov [edx], ax
 
add edx, 2
mov eax, [remote_ip_add]
mov [edx], eax
 
; Now, send it!
 
; Pointer to 48 bit destination address in edi
; Type of packet in bx
; size of packet in ecx
; pointer to packet data in esi
mov edi, remote_hw_add
 
;if DEBUGGING_STATE = DEBUGGING_ENABLED
; pusha
; mov eax, 1 ; Indicate that this is a tx packet
; mov ecx, 28
; mov esi, Ether_buffer + 14
; call eth_dump
; popa
;end if
 
mov bx, ETHER_ARP
mov ecx, 28
mov esi, Ether_buffer + 14
call dword [drvr_transmit] ; Call the drivers transmit function
jmp arph_exit
 
arph_resp:
cmp ax, ARP_REP_OPCODE ; Is this a replypacket?
jne arph_resp ; No - so quit
 
; This was a reply, probably directed at me.
; save the remotes MAC & IP
mov ecx, remote_hw_add
mov edx, ebx
add edx, 22 ; edx points to Source h/w address
mov eax, [edx]
mov [ecx], eax
add edx, 4
add ecx, 4
mov ax, [edx]
mov [ecx],ax
 
; and also the remote IP address
add edx, 2
mov eax,[edx]
mov [remote_ip_add], eax
 
; Now, add an entry in the table for this IP address if it doesn't exist
 
push eax
movzx eax, byte [NumARP]
mov ecx, ARP_ENTRY_SIZE
mul ecx
pop edx
movzx ecx, byte [NumARP]
cmp ecx, 0
je arph_002
 
arph_001:
sub eax, ARP_ENTRY_SIZE
cmp [eax + ARPTable], edx
loopnz arph_001 ; Return back if non match
 
jnz arph_002 ; None found, add to end
 
mov ecx, [remote_hw_add]
mov [eax + ARPTable + 4], ecx
mov cx, [remote_hw_add+4]
mov [eax + ARPTable + 8], cx
 
; specify the type - a valid entry
mov cl, 0x00
mov [eax + ARPTable + 10], cl
mov cl, 0x01
mov [eax + ARPTable + 11], cl
 
; Initialise the time to live field - 1 hour
mov cx, 0x0E10
mov [eax + ARPTable + 12], cx
jmp arph_exit
 
arph_002:
 
cmp byte [NumARP], ARP_TABLE_SIZE
je arph_exit
 
inc byte [NumARP]
 
movzx eax, byte [NumARP]
mov ecx, ARP_ENTRY_SIZE
mul ecx
sub eax, ARP_ENTRY_SIZE
 
mov ecx, [remote_ip_add]
mov [eax + ARPTable], ecx
mov ecx, [remote_hw_add]
mov [eax + ARPTable + 4], ecx
mov cx, [remote_hw_add+4]
mov [eax + ARPTable + 8], cx
 
mov cl, 0x00
mov [eax + ARPTable + 10], cl
mov cl, 0x01
mov [eax + ARPTable + 11], cl
 
; Initialise the time to live field - 1 hour
mov cx, 0x0E10
mov [eax + ARPTable + 12], cx
 
arph_exit:
ret
 
; pointer to MAC in esi
refreshARP:
mov ebx, [esi]
mov dx, [esi+4]
push edx
movzx eax, byte [NumARP]
mov ecx, ARP_ENTRY_SIZE
mul ecx
pop edx
movzx ecx, byte [NumARP]
cmp ecx, 0
je rf_exit
 
rf_001:
sub eax, ARP_ENTRY_SIZE
cmp [eax + ARPTable+4], ebx
 
je rf_002
loop rf_001
jmp rf_exit
 
rf_002:
cmp [eax + ARPTable+8], dx
je rf_gotone
loop rf_001
jmp rf_exit
 
rf_gotone:
; Initialise the time to live field - 1 hour
mov cx, 0x0E10
mov [eax + ARPTable + 12], cx
 
rf_exit:
ret
 
;***************************************************************************
; Function
; getMACfromIP
;
; Description
; Takes an IP address in edx and scans the ARP table for
; a matching entry
; If a match is found, it's MAC address is stored in MACAddress.
; Otherwise the value 0 is writen to MACAddress
; eax holds ARP table entry status code ( ARP_ )
; ebx unchanged
;
;***************************************************************************
getMACfromIP:
; first, check destination IP to see if it is on 'this' network.
; The test is:
; if ( destIP & subnet_mask == stack_ip & subnet_mask )
; desitnation is local
; else
; destination is remote, so pass to gateway
 
mov eax, edx
and eax, [subnet_mask]
mov ecx, [stack_ip]
and ecx, [subnet_mask]
cmp eax, ecx
je gm0
 
mov edx, [gateway_ip]
gm0:
push edx
xor eax, eax
mov [MACAddress], eax
mov [MACAddress + 4], ax
 
movzx eax, byte [NumARP]
mov ecx, ARP_ENTRY_SIZE
mul ecx
 
pop edx
 
movzx ecx, byte [NumARP]
cmp ecx, 0
je gm_none
gm1:
sub eax, ARP_ENTRY_SIZE
cmp [eax + ARPTable], edx
loopnz gm1 ; Return back if non match
jnz gm_none ; Quit if none found
 
; eax holds index
mov ecx, [eax + ARPTable + 4]
mov [MACAddress], ecx
mov cx, [eax + ARPTable + 8]
mov [MACAddress+4], cx
 
; Return the entry status in eax
mov ch, [eax + ARPTable + 10]
mov cl, [eax + ARPTable + 11]
movzx eax, cx
jmp gm_exit
 
gm_none:
mov eax, ARP_NO_ENTRY
 
gm_exit:
ret
 
;***************************************************************************
;
; PCI CODE FOLLOWS
;
; the following functions provide access to the PCI interface.
; These functions are used by scan_bus, and also some ethernet drivers
;
;***************************************************************************
 
;***************************************************************************
; 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
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
 
;***************************************************************************
;
; DEBUGGING CODE FOLLOWS
;
; If debugging data output is not required, ALL code & data below may
; be removed.
;
;***************************************************************************
 
if DEBUGGING_STATE = DEBUGGING_ENABLED
 
;***************************************************************************
; Function
; eth_dump
;
; Description
; Dumps a tx or rx ethernet packet over the rs232 link
; This is a debugging routine that seriously slows down the stack.
; Use with caution.
;
; Baud rate is 57600, 8n1 com1
; eax : type (0 == rx, 1 == tx )
; cx : # of bytes in buffer
; esi : address of buffer start
; edi : pointer to MACAddress ( tx only )
;
;***************************************************************************
eth_dump:
pusha
 
; Set the port to the desired speed
mov ebx, 0x3f8 ; combase
 
mov edx, ebx
add edx, 3 ; data format register
mov al, 0x80 ; enable access to divisor latch
out dx, al
 
mov edx, ebx
add edx, 1 ; interrupt enable register
mov al, 0x00 ; No interruts enabled
out dx, al
 
mov edx, ebx
mov al, 0x20 / 16 ; set baud rate to 57600 0x10 =115200
out dx, al
 
mov edx, ebx
add edx, 3 ; data format register
mov al, 0x03 ; 8 data bits
out dx, al
 
mov edx, ebx
add edx, 4 ; Modem control register
mov al, 0x08 ; out2 enabled. No handshaking.
out dx, al
 
mov edx, ebx
add edx, 1 ; interrupt enable register
mov al, 0x01 ; Receive data interrupt enabled,
out dx, al
 
popa
 
; First, display the type of the buffer.
; If it is a tx buffer, display the macaddress
 
pusha
 
cmp eax, 0
jne dd001
 
mov bl, 0x0a
call tx_byted
mov bl, 0x0d
call tx_byted
 
; Output "RX:"
mov bl, 'R'
call tx_byted
mov bl, 'X'
call tx_byted
mov bl, ':'
call tx_byted
jmp dump_data
 
dd001:
mov bl, 0x0a
call tx_byted
mov bl, 0x0d
call tx_byted
 
; Output TX: xxxxxxxxxxxx
mov bl, 'T'
call tx_byted
mov bl, 'X'
call tx_byted
mov bl, ':'
call tx_byted
mov bl, ' '
call tx_byted
 
; Display MAC address
xor eax, eax
mov al, [edi]
shr al, 4
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
xor eax, eax
mov al, [edi]
and al, 0x0f
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
inc edi
xor eax, eax
mov al, [edi]
shr al, 4
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
xor eax, eax
mov al, [edi]
and al, 0x0f
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
inc edi
xor eax, eax
mov al, [edi]
shr al, 4
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
xor eax, eax
mov al, [edi]
and al, 0x0f
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
inc edi
xor eax, eax
mov al, [edi]
shr al, 4
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
xor eax, eax
mov al, [edi]
and al, 0x0f
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
inc edi
xor eax, eax
mov al, [edi]
shr al, 4
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
xor eax, eax
mov al, [edi]
and al, 0x0f
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
inc edi
xor eax, eax
mov al, [edi]
shr al, 4
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
xor eax, eax
mov al, [edi]
and al, 0x0f
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
dump_data:
popa
 
; OK, we come in here with
; cx == number of byte to send
; esi == buffer start
;
dd_000:
mov bl, 0x0a
call tx_byted
mov bl, 0x0d
call tx_byted
 
mov eax, 16 ; Number of characters on the line
mov edi, esi ; Save first byte position for later
 
push ecx
 
dd_001:
push eax
 
; Print a byte, and a space
xor eax, eax
mov al, [esi]
shr al, 4
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
xor eax, eax
mov al, [esi]
and al, 0x0f
mov bl, [eax + hexchars]
call tx_byted ; byte in bl eax ebx edx destroyed
 
mov bl, ' '
call tx_byted
 
pop eax
 
inc esi
dec ecx
cmp ecx, 0
je dd_0011 ; Print the ASCII format
 
dec eax
 
cmp eax, 0
je dd_002 ; Print the ASCII format
jmp dd_001 ; Print rest of line
 
dd_0011:
; First, complete the 16 bytes of data, by printing spaces
dec eax
cmp eax, 0
je dd_002
 
push eax
mov bl, ' '
call tx_byted
mov bl, ' '
call tx_byted
mov bl, ' '
call tx_byted
pop eax
jmp dd_0011
 
dd_002:
pop ecx
mov esi, edi ; Go back to the start of the line data
 
mov eax, 16
 
outLineAscii:
push eax
 
xor eax, eax
mov al, [esi]
mov bl, '.'
 
cmp al, 0x1F
jle outAscii
cmp al, 0x7e
jge outAscii
 
mov bl, al
 
outAscii:
call tx_byted ; byte in bl eax ebx edx destroyed
 
pop eax
dec ecx
inc esi
cmp ecx, 0
je dd_003
 
dec eax
cmp eax, 0
je dd_003
jmp outLineAscii
 
dd_003:
cmp ecx, 0
je dd_004
jmp dd_000
 
dd_004:
ret
 
;***************************************************************************
; Function
; tx_byte
;
; Description
; Send a byte in bl out of the com port 1
; destroys eax, edx
;
;***************************************************************************
tx_byted:
push ebx ; Save the byte
 
mov ebx, 0x3f8 ; get the com port address
 
; Wait for transmit buffer to empty. This could take 1ms @ 9600baud
 
mov edx, ebx
add edx, 5
 
wait_txd:
in al, dx ; read uart serialisation status
and al, 0x40
cmp al, 0
jz wait_txd ; loop until free
 
mov edx, ebx
pop eax ; restore the byte to send
out dx, al
ret
 
iglobal
; This is used for translating hex to ASCII for display or output
hexchars db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
endg
end if
 
/kernel/tags/kolibri0.6.3.0/network/eth_drv/3c59x.inc
0,0 → 1,2380
;; 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
{
if defined E3C59X_LINUX
sub reg, [virt_addr]
add reg, [dma_addr]
end if
}
 
macro dma_to_virt reg
{
if defined E3C59X_LINUX
sub reg, [dma_addr]
add reg, [virt_addr]
end if
}
 
macro zero_to_virt reg
{
if defined E3C59X_LINUX
add reg, [virt_addr]
end if
}
 
macro virt_to_zero reg
{
if defined E3C59X_LINUX
sub reg, [virt_addr]
end if
}
 
macro zero_to_dma reg
{
if defined E3C59X_LINUX
add reg, [dma_addr]
end if
}
 
macro dma_to_zero reg
{
if defined E3C59X_LINUX
sub reg, [dma_addr]
end if
}
 
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, 2000
.tx_reset_loop:
in ax, dx
test ah, 10000b ; check CmdInProgress
jz .tx_enable
dec ecx
jns .tx_reset_loop
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
/kernel/tags/kolibri0.6.3.0/network/eth_drv/i8255x.inc
0,0 → 1,739
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 ;;
;; ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
;********************************************************************
; 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_reset
; Description
; Place the chip (ie, the ethernet card) into a virgin state
; No inputs
; All registers destroyed
;
;***************************************************************************
I8255x_reset:
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:
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
mov [rxfd_link], eax
 
mov eax, Ether_buffer
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
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
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
mov [confcmd_link], eax
 
mov ax, 1
mov [txfd_command], ax ; CmdIASetup
 
mov ax, 0
mov [txfd_status], ax
 
mov eax, confcmd
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
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_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
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
mov [txfd_tx_desc_addr], eax
mov eax, hdr
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
mov [txfd_tx_buf_addr1], eax
mov eax, ecx
mov [txfd_tx_buf_size1], eax
 
mov eax, txfd
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
/kernel/tags/kolibri0.6.3.0/network/eth_drv/pcnet32.inc
0,0 → 1,814
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; PCNET32.INC ;;
;; ;;
;; Ethernet driver for Menuet OS ;;
;; ;;
;; Version 1.0 31 July 2004 ;;
;; ;;
;; 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;macro PutStr X
;{
; local .__xyz1
; local .__xyz2
; push esi
; mov esi,.__xyz1
; call sys_msg_board_str
; push eax
; mov eax,1
; call delay_hs
; pop eax
; jmp .__xyz2
;.__xyz1:
; db X
; db 13,10,0
;.__xyz2:
; pop esi
;}
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
.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 dword [pcnet32_private.rx_ring],pcnet32_rx_ring
mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
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
; PutStr "ASEL, enable auto-negotiation"
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
and eax,0xffff
call dword [pcnet32_access.write_csr]
mov eax,pcnet32_private
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:
; PutStr "hardware reset"
xor ebx,ebx
mov eax,0x0002
call dword [pcnet32_access.write_csr]
xor ebx,ebx
call dword [pcnet32_access.read_csr]
; PutStr "PCNET reset complete"
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
; PutStr "Using WIO"
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
; PutStr "Using DWIO"
mov esi,pcnet32_dwio
jmp .L1
.no_dev:
; PutStr "PCNET32 not found"
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
; PutStr "PCNET32 chip version OK"
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
; PutStr "Invalid chip rev"
jmp .no_dev
.L2:
; PutStr "PCnet/PCI 79C970"
jmp .L10
.L3:
; PutStr "PCnet/PCI 79C970"
jmp .L10
.L4:
; PutStr "PCnet/PCI II 79C970A"
mov [pcnet32_private.fdx],1
jmp .L10
.L5:
; PutStr "PCnet/FAST 79C971"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
mov [pcnet32_private.fset],1
mov [pcnet32_private.ltint],1
jmp .L10
.L6:
; PutStr "PCnet/FAST+ 79C972"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
mov [pcnet32_private.fset],1
jmp .L10
.L7:
; PutStr "PCnet/FAST III 79C973"
mov [pcnet32_private.fdx],1
mov [pcnet32_private.mii],1
jmp .L10
.L8:
; PutStr "PCnet/Home 79C978"
mov [pcnet32_private.fdx],1
mov ebx,49
call dword [pcnet32_access.read_bcr]
call dword [pcnet32_access.write_bcr]
jmp .L10
.L9:
; PutStr "PCnet/FAST III 79C975"
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
; PutStr "MAC read"
call pcnet32_adjust_pci_device
; PutStr "PCI done"
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 dword [pcnet32_private.rx_ring],pcnet32_rx_ring
mov dword [pcnet32_private.tx_ring],pcnet32_tx_ring
; PutStr "Switching to 32"
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 eax,eax
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
; PutStr "PCNETRX"
mov ecx,[ebx+pcnet32_rx_head.msg_length]
and ecx,0xfff
sub ecx,4
mov [eth_rx_data_len],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
; PutStr "PCNETTX"
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
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:
; PutStr "PCNET: Send timeout"
.L3:
mov dword [edi+pcnet32_tx_head.base],0
pop ecx
pop ebx
pop esi
pop edi
ret
/kernel/tags/kolibri0.6.3.0/network/eth_drv/rtl8029.inc
0,0 → 1,955
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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! ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
 
;********************************************************************
; 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
/kernel/tags/kolibri0.6.3.0/network/eth_drv/rtl8139.inc
0,0 → 1,595
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 ;;
;; ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
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
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
test ax, 0x1fff ; or no size given
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
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
/kernel/tags/kolibri0.6.3.0/network/eth_drv/sis900.inc
0,0 → 1,1148
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;********************************************************************
; 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 ;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 ; 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 ;
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 ;
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
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], ebx
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
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
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
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
/kernel/tags/kolibri0.6.3.0/network/ip.inc
0,0 → 1,202
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
;*******************************************************************
; Interface
;
; ip_rx processes all packets received by the network layer
; It calls the appropriate protocol handler
;
;
;
;*******************************************************************
 
 
;***************************************************************************
; Function
; ip_rx
;
; Description
; Handles received IP packets
; This is a kernel function, called by stack_handler
;
;***************************************************************************
ip_rx:
; Look for a buffer to tx
mov eax, IPIN_QUEUE
call dequeue
cmp ax, NO_BUFFER
je ipr_exit ; Exit if no buffer available
 
push eax
 
; convert buffer pointer eax to the absolute address
mov ecx, IPBUFFSIZE
mul ecx
add eax, IPbuffs
 
mov edx, eax ; Save the address in edx for use by future processes
 
; Validate the IP checksum
mov ebx, edx
mov ah, [ebx + 10]
mov al, [ebx + 11] ; Get the checksum in intel format
mov [ebx + 10], word 0 ; clear checksum field - need to when
; recalculating checksum
 
; this needs two data pointers and two size #.
; 2nd pointer can be of length 0
mov ebx, edx
mov [checkAdd1], ebx
mov [checkSize1], word 20
mov [checkAdd2], dword 0
mov [checkSize2], word 0
 
call checksum ; Recalculate IP checksum
cmp ax, [checkResult]
jnz ipr_dump
 
; If the IP address is 255.255.255.255, accept it
; - it is a broadcast packet, which we need for dhcp
mov eax, [edx + 16]
cmp eax, 0xffffffff
je ipr_p0
 
; Validate the IP address, if it isn't broadcast
cmp eax, [stack_ip]
jnz ipr_dump
 
ipr_p0:
mov al, [edx]
and al, 0x0f
cmp al, 0x05
jnz ipr_dump
 
cmp [edx+8], byte 0
jz ipr_dump
 
mov ax, [edx + 6]
and ax, 0xFFBF
cmp ax, 0
jnz ipr_dump
 
; Check the protocol, and call the appropriate handler
; Each handler will re-use or free the queue buffer as appropriate
mov al, [edx + 9]
cmp al , PROTOCOL_ICMP
jnz ipr_p1
pop eax
call icmp_rx
jmp ipr_exit
 
ipr_p1:
cmp al , PROTOCOL_TCP
jnz ipr_p2
pop eax
call tcp_rx
jmp ipr_exit
 
ipr_p2:
cmp al , PROTOCOL_UDP
jnz ipr_dump
pop eax
call udp_rx
jmp ipr_exit
 
ipr_dump:
; No protocol handler available, so
; silently dump the packet, freeing up the queue buffer
 
; inc dword [dumped_rx_count]
 
pop eax
call freeBuff
 
ipr_exit:
ret
 
 
 
;***************************************************************************
; Function
; icmp_rx
;
; Description
; ICMP protocol handler
; This is a kernel function, called by ip_rx
; edx contains the address of the buffer in use.
; This buffer must be reused or marked as empty afterwards
;
;***************************************************************************
icmp_rx:
cmp [edx + 20], byte 8 ; Is this an echo request? discard if not
jz icmp_echo
 
call freeBuff
jmp icmp_exit
 
icmp_echo:
push eax
mov [edx + 10], word 0 ; I think this was already done by IP rx
 
; swap the source and destination addresses
mov ecx, [edx + 16]
mov eax, [edx + 12]
mov [edx + 16], eax
mov [edx + 12], ecx
 
; recaluculate the IP header checksum
 
mov ebx, edx
mov [checkAdd1], ebx
mov [checkSize1], word 20
mov [checkAdd2], dword 0
mov [checkSize2], word 0
 
call checksum
mov ax, [checkResult]
mov [edx + 10], ah
mov [edx + 11], al ; ?? correct byte order?
 
mov [edx + 20], byte 0 ; change the request to a response
mov [edx + 22], word 0 ; clear ICMP checksum prior to re-calc
 
; Calculate the length of the ICMP data ( IP payload)
mov ah, [edx + 2]
mov al, [edx + 3]
sub ax, 20
 
mov [checkSize1], ax
mov ebx, edx
add ebx, 20
 
mov [checkAdd1], ebx
mov [checkAdd2], dword 0
mov [checkSize2], word 0
 
call checksum
 
mov ax, [checkResult]
mov [edx + 22], ah
mov [edx + 23], al
 
; Queue packet for transmission
 
pop ebx
mov eax, NET1OUT_QUEUE
call queue
 
icmp_exit:
ret
/kernel/tags/kolibri0.6.3.0/network/queue.inc
0,0 → 1,214
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; QUEUE.INC ;;
;; ;;
;; Buffer queue management for Menuet OS TCP/IP Stack ;;
;; ;;
;; Version 0.3 29 August 2002 ;;
;; ;;
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
;*******************************************************************
; 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
;***************************************************************************
freeBuff:
push ebx
push ecx
mov ebx, EMPTY_QUEUE
shl ebx, 1
add ebx, queues
cli ; Ensure that another process does not interfer
movzx ecx, word [ebx]
mov [ebx], ax
shl eax, 1
add eax, queueList
mov [eax], 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
;***************************************************************************
queue:
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
;
;***************************************************************************
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
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
/kernel/tags/kolibri0.6.3.0/sound/sb16.inc
0,0 → 1,350
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; SB16.INC ;;
;; ;;
;; Sound Blaster 16 functions for MenuetOS ;;
;; ;;
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;; - 11.07.2002 8 bit stereo mode - Ville Turjanmaa ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
SB16_load_music equ 0xc0000000
SB16_play_music equ 0xc0000001
DMAPage equ 0x2A
Rate equ 44100
SB16Buffer equ 0x2A0000
SB16_Status equ SB16Buffer+65536
 
iglobal
sound_data_format dd 0x1
sound_data_length dd 65536
sound_data_freq dd 44100
endg
 
sound_interface:
 
cmp eax,0 ; Load data
jne no_SB16_load_music
mov edi,[0x3010]
add edi,TASKDATA.mem_start
add ebx,[edi]
call code_SB16_load_music
ret
no_SB16_load_music:
 
cmp eax,1 ; Play data
jne no_SB16_play_music
call code_SB16_play_music
ret
no_SB16_play_music:
 
cmp eax,2 ; Set data formats
jne no_SB16_data_format
cmp ebx,0 ; ebx=0 play format
jne no_sound_format
mov [sound_data_format],ecx ; 1=8b mono, 2=8b stereo
ret
no_sound_format:
cmp ebx,1 ; ebx=1 data length
jne no_sound_length
mov [sound_data_length],ecx ;
ret
no_sound_length:
cmp ebx,2 ; ebx=2 sound data frequency
jne no_sound_freq
mov [sound_data_freq],ecx
ret
no_sound_freq:
ret
 
no_SB16_data_format:
 
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
cmp eax, edi ; 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 eax, [0x3010]
; mov eax, [eax+0x10] ; address application im memory
; add eax, edx ; add offset Delay-Note string
; mov [memAdrNote], eax
mov [memAdrNote],edx
mov eax,[0x3010]
mov eax,[eax+TASKDATA.pid]
mov [pidProcessNote],eax
xor eax, eax ; Ok! EAX = 0
retFunc55:
mov [esp+36], eax ; return value EAX for application
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
ret
 
 
 
 
code_SB16_play_music:
 
cmp [sound_data_format],1
jne no_sound_8bm
call sb_play_8b_mono
ret
no_sound_8bm:
 
cmp [sound_data_format],2
jne no_sound_8bs
call sb_play_8b_stereo
ret
no_sound_8bs:
 
ret
 
 
 
 
 
Blaster_command:
 
push eax
push ecx
push edx
 
mov dx,word [sb16]
add dx,0xc
mov cx,1000
bcl1:
in al,dx
and al,128
jz bcl2
loop bcl1
bcl2:
mov al,[esp+8]
mov dx,[esp+0]
add dx,word [sb16]
out dx,al
 
pop edx
pop ecx
pop eax
 
ret
 
 
sb_play_8b_stereo:
 
pusha
 
call sb_set_dma
 
call sb_set_stereo
 
mov dx,0xc
mov al,0xa8
call Blaster_command
 
mov al,0x40
call Blaster_command
 
mov al,245
call Blaster_command
 
mov al,0x48
call Blaster_command
 
mov al,0xff
call Blaster_command
call Blaster_command
 
mov al,0x91
call Blaster_command
 
popa
ret
 
 
 
sb_set_stereo:
 
push eax
push edx
 
call sb_wait
 
mov dx,word [sb16]
add dx,0x4
mov al,0xe
out dx,al
inc dx
in al,dx
and al,253
or al,2 ; stereo
out dx,al
 
pop edx
pop eax
ret
 
 
 
code_SB16_load_music:
 
cmp byte [SB16_Status],1
je nol
mov edi,SB16Buffer
mov esi,ebx
mov ecx,65536/4
cld
rep movsd
nol: ret
 
 
iglobal
dma_table db 0x87,0x83,0x81,0x82
endg
 
 
 
;--------------------------------
; program dma
;--------------------------------
 
sb_set_dma:
 
pusha
 
mov eax,[sound_dma]
add eax,4
out 0xa,al
 
mov al,0
out 0xc,al
 
mov eax,[sound_dma]
add eax,0x48
out 0xb,al
 
mov edx,[sound_dma]
shl edx,1
mov al,0
out dx,al
 
mov al,0
out dx,al
 
mov edx,[sound_dma]
add edx,dma_table
movzx edx,byte [edx]
mov al,DMAPage
out dx,al
 
mov edx,[sound_dma]
shl edx,1
inc edx
mov eax,[sound_data_length]
dec eax
and eax,0xff
; mov al,(DataLength-1) and 0xff
out dx,al
 
mov eax,[sound_data_length]
dec eax
shr eax,8
; mov al,(DataLength-1) shr 8
out dx,al
 
mov eax,[sound_dma] ; DMA
out 0xa,al
 
popa
ret
 
 
 
sb_play_8b_mono:
 
 
call sb_set_dma
 
cmp byte [SB16_Status],1
jne contsb16
jmp retserve
contsb16:
 
mov dx,word [sb16]
add dx,4
mov ecx,[sound_dma]
mov ax,0x01
shl ax,cl
shl ax,8
add ax,0x81
out dx,ax
 
mov ax,0f280h ;enable irq5
out dx,ax
 
 
adr1_SB: mov dx,word [sb16]
add dx,0ch
in al,dx
and al,080h
jnz adr1_SB
 
call sb_set_stereo
 
mov al,0d1h
out dx,al
 
 
mov dx,word [sb16]
add dx,0ch
 
call sb_wait
 
mov al,40h ; Rate
out dx,al
call sb_wait
mov al,256-1000000/Rate
out dx,al
 
call sb_wait
 
mov al,14h ; Datalength
out dx,al
call sb_wait
 
mov eax,[sound_data_length]
dec eax
and eax,0xff
;mov al,(DataLength-1) and 0xff
out dx,al
call sb_wait
mov eax,[sound_data_length]
dec eax
shr eax,8
;mov al,(DataLength-1) shr 8
out dx,al
 
retserve:
 
ret
 
 
sb_wait: in al,dx ;wait
and al,080h
jnz sb_wait
 
ret
 
 
 
 
;****************************************
; END CODE SB16 by Minazzi Paolo
;***************************************
/kernel/tags/kolibri0.6.3.0/sound/playnote.inc
0,0 → 1,135
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; 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 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
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
 
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 ebx
push ecx
push edx
mov eax,[pidProcessNote]
call pid_to_slot
test eax,eax
jz .failed
lea ebx,[esp+12]
mov ecx,1
mov edx,[memAdrNote]
inc [memAdrNote]
call read_process_memory
.failed:
pop edx
pop ecx
pop ebx
pop eax
ret
;------------------- END CODE -------------------
/kernel/tags/kolibri0.6.3.0/vmodeint.inc
0,0 → 1,47
;
; 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
jne .no_vmode_drv_access
pushd [0x0000fe00] [0x0000fe04]
popd [old_screen_height] [old_screen_width]
or eax,-1 ; If driver is absent then eax does not change
call 0x760100 ; Entry point of video driver
mov [esp+36],eax
mov [esp+24],ebx
mov [esp+32],ecx
; mov [esp+28],edx
mov eax,[old_screen_width]
mov ebx,[old_screen_height]
sub eax,[0x0000fe00]
jnz @f
sub ebx,[0x0000fe04]
jz .resolution_wasnt_changed
jmp .lp1
@@: sub ebx,[0x0000fe04]
.lp1: sub [screen_workarea.right],eax
sub [screen_workarea.bottom],ebx
 
call repos_windows
mov eax, 0
mov ebx, 0
mov ecx, [0xfe00]
mov edx, [0xfe04]
call calculatescreen
 
.resolution_wasnt_changed:
ret
.no_vmode_drv_access:
/kernel/tags/kolibri0.6.3.0/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/tags/kolibri0.6.3.0/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/tags/kolibri0.6.3.0/skin/default.asm
0,0 → 1,31
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'
/kernel/tags/kolibri0.6.3.0/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/tags/kolibri0.6.3.0/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/tags/kolibri0.6.3.0/skin/me_skin.inc
0,0 → 1,235
;============================================================================
; 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
}
/kernel/tags/kolibri0.6.3.0/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/tags/kolibri0.6.3.0/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/tags/kolibri0.6.3.0/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/tags/kolibri0.6.3.0/bus/pci/pci16.inc
0,0 → 1,46
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; PCI16.INC ;;
;; ;;
;; 16 bit PCI driver code ;;
;; ;;
;; Version 0.2 December 21st, 2002 ;;
;; ;;
;; Author: Victor Prodan, victorprodan@yahoo.com ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
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
/kernel/tags/kolibri0.6.3.0/bus/pci/pci32.inc
0,0 → 1,358
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; PCI32.INC ;;
;; ;;
;; 32 bit PCI driver code ;;
;; ;;
;; Version 0.2 December 21st, 2002 ;;
;; ;;
;; Author: Victor Prodan, victorprodan@yahoo.com ;;
;; Credits: ;;
;; Ralf Brown ;;
;; Mike Hibbett, mikeh@oceanfree.net ;;
;; ;;
;; See file COPYING for details ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 
;***************************************************************************
; Function
; pci_api:
;
; Description
; entry point for system PCI calls
;***************************************************************************
 
align 4
 
pci_api:
 
cmp [pci_access_enabled],1
jne no_pci_access_for_applications
 
or al,al
jnz pci_fn_1
; PCI function 0: get pci version (AH.AL)
movzx eax,word [0x2F0000+0x9022]
ret
 
pci_fn_1:
cmp al,1
jnz pci_fn_2
 
; PCI function 1: get last bus in AL
mov al,[0x2F0000+0x9021]
ret
 
pci_fn_2:
cmp al,2
jne pci_fn_3
; PCI function 2: get pci access mechanism
mov al,[0x2F0000+0x9020]
ret
pci_fn_3:
 
cmp al,4
jz pci_read_reg ;byte
cmp al,5
jz pci_read_reg ;word
cmp al,6
jz pci_read_reg ;dword
 
cmp al,8
jz pci_write_reg ;byte
cmp al,9
jz pci_write_reg ;word
cmp al,10
jz pci_write_reg ;dword
 
no_pci_access_for_applications:
 
mov eax,-1
 
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
;***************************************************************************
 
align 4
 
pci_read_reg:
cmp byte [0x2F0000+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
;***************************************************************************
 
align 4
 
pci_write_reg:
cmp byte [0x2F0000+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
/kernel/tags/kolibri0.6.3.0/vmodeld.inc
0,0 → 1,27
;
; Load of videomode driver in memory
;
; (driver is located at 0x760000-0x768000 - 32kb) // if this area not occuped anything
;
; Author: Trans
; Date: 19.07.2003
;
; Include in MeOS kernel and compile with FASM
;
 
 
;vmode db 'VMODE MDR' ; MDR - Menuet Driver
; must be located after fonts filenames in kernel.asm
 
; LOAD VIDEOMODE DRIVER
; If vmode.mdr file not found
or eax,-1 ; Driver ID = -1 (not present in system)
mov [0x760000],eax ;
mov [0x760100],byte 0xC3 ; Instruction RETN - driver loop
 
mov eax,vmode ; File name of driver
mov esi,12
mov ebx,0
mov ecx,26000
mov edx,0x760000 ; Memory position of driver
call fileread
/kernel/tags/kolibri0.6.3.0
Property changes:
Added: svn:ignore
+*.mnt
+lang.inc
+*.bat
+out.txt
+scin*
Added: tsvn:logminsize
+5
\ No newline at end of property