/kernel/tags/kolibri0.7.0.0/core/conf_lib.inc |
---|
0,0 → 1,312 |
$Revision$ |
;------------------------------------------------------------------------- |
;Loading configuration from ini file |
; {SPraid.simba} |
;------------------------------------------------------------------------- |
conf_path_sect: db 'path',0 |
conf_fname db '/sys/sys.conf',0 |
; set soke kernel configuration |
proc set_kernel_conf |
locals |
par db 30 dup(?) |
endl |
pushad |
;[gui] |
;mouse_speed |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, ugui, ugui_mouse_speed, eax,30, ugui_mouse_speed_def |
pop eax |
stdcall strtoint,eax |
mov [mouse_speed_factor], ax |
;mouse_delay |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, ugui, ugui_mouse_delay, eax,30, ugui_mouse_delay_def |
pop eax |
stdcall strtoint,eax |
mov [mouse_delay], eax |
;[dev] |
;sb16 |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, udev, udev_sb16, eax,30, udev_sb16_def |
pop eax |
stdcall strtoint,eax |
cmp eax, 0x100 |
jb @f |
cmp eax, 0x10000 |
jae @f |
mov [sb16], eax |
@@: |
;sound_dma |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, udev, udev_sound_dma, eax,30, udev_sound_dma_def |
pop eax |
stdcall strtoint,eax |
cmp eax, 3 |
ja @f |
mov [sound_dma], eax |
@@: |
;midibase |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, udev, udev_midibase, eax,30, udev_midibase_def |
pop eax |
stdcall strtoint,eax |
cmp eax, 0x100 |
jb @f |
cmp eax, 0x10000 |
jae @f |
mov [midi_base], ax |
mov [mididp], eax |
inc eax |
mov [midisp], eax |
@@: |
popad |
ret |
endp |
ugui db 'gui',0 |
ugui_mouse_speed db 'mouse_speed',0 |
ugui_mouse_speed_def db '2',0 |
ugui_mouse_delay db 'mouse_delay',0 |
ugui_mouse_delay_def db '0x00A',0 |
udev db 'dev',0 |
udev_sb16 db 'sb16',0 |
udev_sb16_def db '0x220',0 |
udev_sound_dma db 'sound_dma',0 |
udev_sound_dma_def db '1',0 |
udev_midibase db 'midibase',0 |
udev_midibase_def db '0x320',0 |
;set up netvork configuration |
proc set_network_conf |
locals |
par db 30 dup(?) |
endl |
pushad |
;[net] |
;active |
lea eax,[par] |
invoke ini.get_int,conf_fname, unet, unet_active, 0 |
or eax,eax |
jz .do_not_set_net |
mov eax, [stack_config] |
and eax, 0xFFFFFF80 |
add eax, 3 |
mov [stack_config], eax |
call ash_eth_enable |
;addr |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, unet, unet_addr, eax,30, unet_def |
pop eax |
stdcall do_inet_adr,eax |
mov [stack_ip], eax |
;mask |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, unet, unet_mask, eax,30, unet_def |
pop eax |
stdcall do_inet_adr,eax |
mov [subnet_mask], eax |
;gate |
lea eax,[par] |
push eax |
invoke ini.get_str,conf_fname, unet, unet_gate, eax,30, unet_def |
pop eax |
stdcall do_inet_adr,eax |
mov [gateway_ip], eax |
.do_not_set_net: |
popad |
ret |
endp |
unet db 'net',0 |
unet_active db 'active',0 |
unet_addr db 'addr',0 |
unet_mask db 'mask',0 |
unet_gate db 'gate',0 |
unet_def db 0 |
; convert string to DWord |
proc strtoint stdcall,strs |
pushad |
mov eax,[strs] |
inc eax |
mov bl,[eax] |
cmp bl,'x' |
je .hex |
cmp bl,'X' |
je .hex |
jmp .dec |
.hex: |
inc eax |
stdcall strtoint_hex,eax |
jmp .exit |
.dec: |
dec eax |
stdcall strtoint_dec,eax |
.exit: |
mov [esp+28],eax |
popad |
ret |
endp |
; convert string to DWord for decimal value |
proc strtoint_dec stdcall,strs |
pushad |
xor edx,edx |
; ¯®¨áª ª®æ |
mov esi,[strs] |
@@: |
lodsb |
or al,al |
jnz @b |
mov ebx,esi |
mov esi,[strs] |
dec ebx |
sub ebx,esi |
mov ecx,1 |
@@: |
dec ebx |
or ebx,ebx |
jz @f |
imul ecx,ecx,10 ; ¯®à冷ª |
jmp @b |
@@: |
xchg ebx,ecx |
xor ecx,ecx |
@@: |
xor eax,eax |
lodsb |
cmp al,0 |
je .eend |
sub al,30h |
imul ebx |
add ecx,eax |
push ecx |
xchg eax,ebx |
mov ecx,10 |
div ecx |
xchg eax,ebx |
pop ecx |
jmp @b |
.eend: |
mov [esp+28],ecx |
popad |
ret |
endp |
;convert string to DWord for hex value |
proc strtoint_hex stdcall,strs |
pushad |
xor edx,edx |
mov esi,[strs] |
mov ebx,1 |
add esi,1 |
@@: |
lodsb |
or al,al |
jz @f |
shl ebx,4 |
jmp @b |
@@: |
xor ecx,ecx |
mov esi,[strs] |
@@: |
xor eax,eax |
lodsb |
cmp al,0 |
je .eend |
cmp al,'a' |
jae .bm |
cmp al,'A' |
jae .bb |
jmp .cc |
.bm: ; 57h |
sub al,57h |
jmp .do |
.bb: ; 37h |
sub al,37h |
jmp .do |
.cc: ; 30h |
sub al,30h |
.do: |
imul ebx |
add ecx,eax |
shr ebx,4 |
jmp @b |
.eend: |
mov [esp+28],ecx |
popad |
ret |
endp |
; convert string to DWord for IP addres |
proc do_inet_adr stdcall,strs |
pushad |
mov esi,[strs] |
mov ebx,0 |
.next: |
push esi |
@@: |
lodsb |
or al,al |
jz @f |
cmp al,'.' |
jz @f |
jmp @b |
@@: |
mov cl, al |
mov [esi-1],byte 0 |
;pop eax |
call strtoint_dec |
rol eax,24 |
ror ebx,8 |
add ebx,eax |
or cl,cl |
jz @f |
jmp .next |
@@: |
mov [esp+28],ebx |
popad |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/memory.inc |
---|
0,0 → 1,1173 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
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 |
lea eax, [eax+ebx*8] |
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 |
push ebx |
mov eax, [phis_addr] |
and eax, not 0xFFF |
or eax, [flags] |
mov ebx, [lin_addr] |
shr ebx, 12 |
mov [page_tabs+ebx*4], eax |
mov eax, [lin_addr] |
invlpg [eax] |
pop ebx |
ret |
endp |
align 4 |
map_space: ;not implemented |
ret |
align 4 |
proc free_page |
;arg: eax page address |
pushfd |
cli |
shr eax, 12 ;page index |
bts dword [sys_pgmap], eax ;that's all! |
cmc |
adc [pg_data.pages_free], 0 |
shr eax, 3 |
and eax, not 3 ;dword offset from page_map |
add eax, sys_pgmap |
cmp [page_start], eax |
ja @f |
popfd |
ret |
@@: |
mov [page_start], eax |
popfd |
ret |
endp |
; param |
; eax= page base + page flags |
; ebx= liear address |
; ecx= count |
align 4 |
commit_pages: |
test ecx, ecx |
jz .fail |
mov edi, ebx |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov edx, 0x1000 |
mov ebx, edi |
shr ebx, 12 |
@@: |
mov [page_tabs+ebx*4], eax |
invlpg [edi] |
add edi, edx |
add eax, edx |
inc ebx |
dec ecx |
jnz @B |
mov [pg_data.pg_mutex],ecx |
.fail: |
ret |
; param |
; eax= base |
; ecx= count |
align 4 |
release_pages: |
pushad |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov esi, eax |
mov edi, eax |
shr esi, 10 |
add esi, page_tabs |
mov ebp, [pg_data.pages_free] |
mov ebx, [page_start] |
mov edx, sys_pgmap |
@@: |
xor eax, eax |
xchg eax, [esi] |
invlpg [edi] |
test eax, 1 |
jz .next |
shr eax, 12 |
bts [edx], eax |
cmc |
adc ebp, 0 |
shr eax, 3 |
and eax, -4 |
add eax, edx |
cmp eax, ebx |
jae .next |
mov ebx, eax |
.next: |
add edi, 0x1000 |
add esi, 4 |
dec ecx |
jnz @B |
mov [pg_data.pages_free], ebp |
and [pg_data.pg_mutex],0 |
popad |
ret |
align 4 |
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword |
push ebx |
mov ebx, [lin_addr] |
shr ebx, 22 |
mov eax, [phis_addr] |
and eax, not 0xFFF |
or eax, PG_UW ;+PG_NOCACHE |
mov dword [master_tab+ebx*4], eax |
mov eax, [lin_addr] |
shr eax, 10 |
add eax, page_tabs |
invlpg [eax] |
pop ebx |
ret |
endp |
align 4 |
proc init_LFB |
locals |
pg_count dd ? |
endl |
cmp dword [LFBAddress], -1 |
jne @f |
mov [BOOT_VAR+0x901c],byte 2 |
stdcall kernel_alloc, 0x280000 |
mov [LFBAddress], eax |
ret |
@@: |
test [SCR_MODE],word 0100000000000000b |
jnz @f |
mov [BOOT_VAR+0x901c],byte 2 |
ret |
@@: |
call init_mtrr |
mov edx, LFB_BASE |
mov esi, [LFBAddress] |
mov edi, 0x00800000 |
mov dword [exp_lfb+4], edx |
shr edi, 12 |
mov [pg_count], edi |
shr edi, 10 |
bt [cpu_caps], CAPS_PSE |
jnc .map_page_tables |
or esi, PG_LARGE+PG_UW |
mov edx, sys_pgdir+(LFB_BASE shr 20) |
@@: |
mov [edx], esi |
add edx, 4 |
add esi, 0x00400000 |
dec edi |
jnz @B |
bt [cpu_caps], CAPS_PGE |
jnc @F |
or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL |
@@: |
mov dword [LFBAddress], LFB_BASE |
mov eax, cr3 ;flush TLB |
mov cr3, eax |
ret |
.map_page_tables: |
@@: |
call alloc_page |
stdcall map_page_table, edx, eax |
add edx, 0x00400000 |
dec edi |
jnz @B |
mov eax, [LFBAddress] |
mov edi, page_tabs + (LFB_BASE shr 10) |
or eax, PG_UW |
mov ecx, [pg_count] |
cld |
@@: |
stosd |
add eax, 0x1000 |
dec ecx |
jnz @B |
mov dword [LFBAddress], LFB_BASE |
mov eax, cr3 ;flush TLB |
mov cr3, eax |
ret |
endp |
align 4 |
proc new_mem_resize stdcall, new_size:dword |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
mov edi, [new_size] |
add edi,4095 |
and edi,not 4095 |
mov [new_size], edi |
mov edx,[current_slot] |
cmp [edx+APPDATA.heap_base],0 |
jne .exit |
mov esi, [edx+APPDATA.mem_size] |
add esi, 4095 |
and esi, not 4095 |
cmp edi, esi |
jae .expand |
shr edi, 12 |
shr esi, 12 |
@@: |
mov eax, [app_page_tabs+edi*4] |
test eax, 1 |
jz .next |
mov dword [app_page_tabs+edi*4], 2 |
mov ebx, edi |
shl ebx, 12 |
invlpg [ebx+std_application_base_address] |
call free_page |
.next: add edi, 1 |
cmp edi, esi |
jb @B |
.update_size: |
mov ebx, [new_size] |
call update_mem_size |
xor eax, eax |
dec [pg_data.pg_mutex] |
ret |
.expand: |
push esi |
push edi |
add edi, 0x3FFFFF |
and edi, not(0x3FFFFF) |
add esi, 0x3FFFFF |
and esi, not(0x3FFFFF) |
cmp esi, edi |
jae .grow |
xchg esi, edi |
@@: |
call alloc_page |
test eax, eax |
jz .exit |
stdcall map_page_table, edi, eax |
push edi |
shr edi, 10 |
add edi, page_tabs |
mov ecx, 1024 |
xor eax, eax |
cld |
rep stosd |
pop edi |
add edi, 0x00400000 |
cmp edi, esi |
jb @B |
.grow: |
pop edi |
pop esi |
@@: |
call alloc_page |
test eax, eax |
jz .exit |
stdcall map_page,esi,eax,dword PG_UW |
push edi |
mov edi, esi |
xor eax, eax |
mov ecx, 1024 |
cld |
rep stosd |
pop edi |
add esi, 0x1000 |
cmp esi, edi |
jb @B |
jmp .update_size |
.exit: |
xor eax, eax |
inc eax |
dec [pg_data.pg_mutex] |
ret |
endp |
update_mem_size: |
; in: edx = slot base |
; ebx = new memory size |
; destroys eax,ecx,edx |
mov [APPDATA.mem_size+edx],ebx |
;search threads and update |
;application memory size infomation |
mov ecx,[APPDATA.dir_table+edx] |
mov eax,2 |
.search_threads: |
;eax = current slot |
;ebx = new memory size |
;ecx = page directory |
cmp eax,[TASK_COUNT] |
jg .search_threads_end |
mov edx,eax |
shl edx,5 |
cmp word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty? |
jz .search_threads_next |
shl edx,3 |
cmp [SLOT_BASE+edx+APPDATA.dir_table],ecx ;if it is our thread? |
jnz .search_threads_next |
mov [SLOT_BASE+edx+APPDATA.mem_size],ebx ;update memory size |
.search_threads_next: |
inc eax |
jmp .search_threads |
.search_threads_end: |
ret |
; param |
; eax= linear address |
; |
; retval |
; eax= phisical page address |
align 4 |
get_pg_addr: |
shr eax, 12 |
mov eax, [page_tabs+eax*4] |
and eax, 0xFFFFF000 |
ret |
align 4 |
proc page_fault_handler |
.err_code equ ebp+32 |
.err_addr equ ebp-4 |
pushad |
mov ebp, esp |
mov eax, cr2 |
push eax |
mov ax, app_data |
mov ds, ax |
mov es, ax |
inc [pg_data.pages_faults] |
; push eax |
; push edx |
; mov edx, 0x400 ;bochs |
; mov al,0xff ;bochs |
; out dx, al ;bochs |
; pop edx |
; pop eax |
mov ebx, [.err_addr] |
mov eax, [.err_code] |
cmp ebx, OS_BASE |
jb .user_space ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ; |
cmp ebx, page_tabs |
jb .kernel_space ;ñòðàíèöà â ïàìÿòè ÿäðà |
cmp ebx, kernel_tabs |
jb .alloc;.app_tabs ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ; |
;ïðîñòî ñîçäàäèì îäíó |
cmp ebx, LFB_BASE |
jb .core_tabs ;òàáëèöû ñòðàíèö ÿäðà |
;Îøèáêà |
.lfb: |
;îáëàñòü LFB |
;Îøèáêà |
jmp .fail |
align 4 |
.user_space: |
test eax, PG_MAP |
jnz .err_access ;Ñòðàíèöà ïðèñóòñòâóåò |
;Îøèáêà äîñòóïà ? |
shr ebx, 12 |
mov ecx, ebx |
shr ecx, 10 |
mov edx, [master_tab+ecx*4] |
test edx, PG_MAP |
jz .fail ;òàáëèöà ñòðàíèö íå ñîçäàíà |
;íåâåðíûé àäðåñ â ïðîãðàììå |
mov eax, [page_tabs+ebx*4] |
test eax, 2 |
jz .fail ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ; |
;èñïîëüçîâàíèÿ. Îøèáêà |
.alloc: |
call alloc_page |
and eax, eax |
jz .fail |
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: |
mov esp, ebp |
popad |
add esp, 4 |
iretd |
.err_access: |
;íèêîãäà íå ïðîèñõîäèò |
jmp .fail |
.kernel_space: |
test eax, PG_MAP |
jz .fail ;ñòðàíèöà íå ïðèñóòñòâóåò |
test eax, 4 ;U/S |
jnz .fail ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè |
;ÿäðà |
test eax, 8 |
jnz .fail ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò |
;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon |
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà |
cmp ebx, tss._io_map_0 |
jb .fail |
cmp ebx, tss._io_map_0+8192 |
jae .fail |
; io permission map |
; copy-on-write protection |
call alloc_page |
and eax, eax |
jz .fail |
push eax |
stdcall map_page,[ebp-4],eax,dword PG_SW |
pop eax |
mov edi, [.err_addr] |
and edi, -4096 |
lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0 |
mov ebx, esi |
shr ebx, 12 |
mov edx, [current_slot] |
or eax, PG_SW |
mov [edx+APPDATA.io_map+ebx*4], eax |
add esi, [default_io_map] |
mov ecx, 4096/4 |
cld |
rep movsd |
jmp .exit |
;íå îáðàáàòûâàåì. Îøèáêà |
.core_tabs: |
.fail: |
mov esp, ebp |
popad |
add esp, 4 |
; iretd |
save_ring3_context ;debugger support |
mov bl, 14 |
jmp exc_c |
iretd |
endp |
align 4 |
proc map_mem stdcall, lin_addr:dword,pdir:dword,\ |
ofs:dword,buf_size:dword |
mov eax, [buf_size] |
test eax, eax |
jz .exit |
mov eax, [pdir] |
and eax, 0xFFFFF000 |
stdcall map_page,[ipc_pdir],eax,PG_UW |
mov ebx, [ofs] |
shr ebx, 22 |
mov esi, [ipc_pdir] |
mov edi, [ipc_ptab] |
mov eax, [esi+ebx*4] |
and eax, 0xFFFFF000 |
jz .exit |
stdcall map_page,edi,eax,PG_UW |
; inc ebx |
; add edi, 0x1000 |
; mov eax, [esi+ebx*4] |
; test eax, eax |
; jz @f |
; and eax, 0xFFFFF000 |
; stdcall map_page, edi, eax |
@@: mov edi, [lin_addr] |
and edi, 0xFFFFF000 |
mov ecx, [buf_size] |
add ecx, 4095 |
shr ecx, 12 |
inc ecx |
mov edx, [ofs] |
shr edx, 12 |
and edx, 0x3FF |
mov esi, [ipc_ptab] |
.map: mov eax, [esi+edx*4] |
and eax, 0xFFFFF000 |
jz .exit |
stdcall map_page,edi,eax,PG_UW |
dec ecx |
jz .exit |
add edi, 0x1000 |
inc edx |
cmp edx, 0x400 |
jnz .map |
inc ebx |
mov eax, [ipc_pdir] |
mov eax, [eax+ebx*4] |
and eax, 0xFFFFF000 |
jz .exit |
stdcall map_page,esi,eax,PG_UW |
xor edx, edx |
jmp .map |
.exit: |
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_slot] |
pushf |
cli |
mov [eax+APPDATA.ipc_start],ebx ;set fields in extended information area |
mov [eax+APPDATA.ipc_size],ecx |
add ecx, ebx |
add ecx, 4095 |
and ecx, not 4095 |
.touch: mov eax, [ebx] |
add ebx, 0x1000 |
cmp ebx, ecx |
jb .touch |
popf |
xor eax, eax |
ret |
endp |
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword |
locals |
dst_slot dd ? |
dst_offset dd ? |
buf_size dd ? |
used_buf dd ? |
endl |
pushf |
cli |
mov eax, [PID] |
call pid_to_slot |
test eax,eax |
jz .no_pid |
mov [dst_slot], eax |
shl eax,8 |
mov edi,[eax+SLOT_BASE+0xa0] ;is ipc area defined? |
test edi,edi |
jz .no_ipc_area |
mov ebx, edi |
; add edi, new_app_base |
and ebx, 0xFFF |
mov [dst_offset], ebx |
mov esi, [eax+SLOT_BASE+0xa4] |
mov [buf_size], esi |
mov ecx, [ipc_tmp] |
cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page |
jbe @f |
push eax esi edi |
add esi,0x1000 |
stdcall alloc_kernel_space,esi |
mov ecx, eax |
pop edi esi eax |
@@: |
mov [used_buf], ecx |
stdcall map_mem, ecx, [SLOT_BASE+eax+0xB8],\ |
edi, esi |
mov edi, [dst_offset] |
add edi, [used_buf] |
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 |
add edi, edx |
mov [edi], eax |
mov ecx, [msg_size] |
mov [edi+4], ecx |
add edi, 8 |
mov esi, [msg_addr] |
; add esi, new_app_base |
cld |
rep movsb |
mov ebx, [ipc_tmp] |
mov edx, ebx |
shr ebx, 12 |
xor eax, eax |
mov [page_tabs+ebx*4], eax |
invlpg [edx] |
mov ebx, [ipc_pdir] |
mov edx, ebx |
shr ebx, 12 |
xor eax, eax |
mov [page_tabs+ebx*4], eax |
invlpg [edx] |
mov ebx, [ipc_ptab] |
mov edx, ebx |
shr ebx, 12 |
xor eax, eax |
mov [page_tabs+ebx*4], eax |
invlpg [edx] |
mov eax, [dst_slot] |
shl eax, 8 |
or [eax+SLOT_BASE+0xA8],dword 0x40 |
cmp dword [check_idle_semaphore],20 |
jge .ipc_no_cis |
mov dword [check_idle_semaphore],5 |
.ipc_no_cis: |
push 0 |
jmp .ret |
.no_pid: |
popf |
mov eax, 4 |
ret |
.no_ipc_area: |
popf |
xor eax, eax |
inc eax |
ret |
.ipc_blocked: |
push 2 |
jmp .ret |
.buffer_overflow: |
push 3 |
.ret: |
mov eax, [used_buf] |
cmp eax, [ipc_tmp] |
jz @f |
stdcall free_kernel_space,eax |
@@: |
pop eax |
popf |
ret |
endp |
align 4 |
sysfn_meminfo: |
; add ebx, new_app_base |
cmp ebx, OS_BASE |
jae .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 |
stdcall user_free, ebx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 14 |
ja @f |
cmp ebx, OS_BASE |
jae .fail |
stdcall get_event_ex, ebx, ecx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 15 |
ja @f |
mov ecx, [current_slot] |
mov eax, [ecx+APPDATA.fpu_handler] |
mov [ecx+APPDATA.fpu_handler], ebx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 16 |
ja @f |
test ebx, ebx |
jz .fail |
cmp ebx, OS_BASE |
jae .fail |
stdcall get_service, ebx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 17 |
ja @f |
call srv_handlerEx ;ebx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 18 |
ja @f |
mov ecx, [current_slot] |
mov eax, [ecx+APPDATA.sse_handler] |
mov [ecx+APPDATA.sse_handler], ebx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 19 |
ja @f |
cmp ebx, OS_BASE |
jae .fail |
stdcall load_library, ebx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 20 |
ja .fail |
mov eax, ecx |
call user_realloc |
mov [esp+36], eax |
ret |
.fail: |
xor eax, eax |
mov [esp+36], eax |
ret |
align 4 |
proc init_mtrr |
cmp [BOOT_VAR+0x901c],byte 2 |
je .exit |
bt [cpu_caps], CAPS_MTRR |
jnc .exit |
mov eax, cr0 |
or eax, 0x60000000 ;disable caching |
mov cr0, eax |
wbinvd ;invalidate cache |
mov ecx, 0x2FF |
rdmsr ; |
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 |
align 4 |
proc create_ring_buffer stdcall, size:dword, flags:dword |
locals |
buf_ptr dd ? |
endl |
mov eax, [size] |
test eax, eax |
jz .fail |
add eax, eax |
stdcall alloc_kernel_space, eax |
test eax, eax |
jz .fail |
mov [buf_ptr], eax |
mov ebx, [size] |
shr ebx, 12 |
push ebx |
stdcall alloc_pages, ebx |
pop ecx |
test eax, eax |
jz .mm_fail |
or eax, [flags] |
mov edi, [buf_ptr] |
mov ebx, [buf_ptr] |
mov edx, ecx |
shl edx, 2 |
shr edi, 10 |
@@: |
mov [page_tabs+edi], eax |
mov [page_tabs+edi+edx], eax |
invlpg [ebx] |
invlpg [ebx+esi] |
add eax, 0x1000 |
add ebx, 0x1000 |
add edi, 4 |
dec ecx |
jnz @B |
mov eax, [buf_ptr] |
ret |
.mm_fail: |
stdcall free_kernel_space, [buf_ptr] |
xor eax, eax |
.fail: |
ret |
endp |
if 0 |
push eax |
push edx |
mov edx, 0x400 ;bochs |
mov al,0xff ;bochs |
out dx, al ;bochs |
pop edx |
pop eax |
end if |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/ext_lib.inc |
---|
0,0 → 1,307 |
$Revision$ |
;============================================================================ |
; |
; External kernel dependencies (libraries) loading |
; |
;============================================================================ |
macro library [name,fname] |
{ |
forward |
dd __#name#_library_table__,__#name#_library_name__ |
common |
dd 0 |
forward |
__#name#_library_name__ db fname,0 |
} |
macro import lname,[name,sname] |
{ |
common |
align 4 |
__#lname#_library_table__: |
forward |
name dd __#name#_import_name__ |
common |
dd 0 |
forward |
__#name#_import_name__ db sname,0 |
} |
macro export [name,sname] |
{ |
align 4 |
forward |
dd __#name#_export_name__,name |
common |
dd 0 |
forward |
__#name#_export_name__ db sname,0 |
} |
align 4 ; loading library (use kernel functions) |
proc load_k_library stdcall, file_name:dword |
locals |
coff dd ? |
sym dd ? |
strings dd ? |
img_size dd ? |
img_base dd ? |
exports dd ? |
endl |
cli |
stdcall load_file, [file_name] |
test eax, eax |
jz .fail |
mov [coff], eax |
movzx ecx, [eax+CFH.nSections] |
xor ebx, ebx |
lea edx, [eax+20] |
@@: |
add ebx, [edx+CFS.SizeOfRawData] |
add ebx, 15 |
and ebx, not 15 |
add edx, COFF_SECTION_SIZE |
dec ecx |
jnz @B |
mov [img_size], ebx |
stdcall kernel_alloc, [img_size] |
test eax, eax |
jz .fail |
mov [img_base], eax |
mov edx, [coff] |
movzx ebx, [edx+CFH.nSections] |
mov edi, [img_base] |
lea eax, [edx+20] |
@@: |
mov [eax+CFS.VirtualAddress], edi |
mov esi, [eax+CFS.PtrRawData] |
test esi, esi |
jnz .copy |
add edi, [eax+CFS.SizeOfRawData] |
jmp .next |
.copy: |
add esi, edx |
mov ecx, [eax+CFS.SizeOfRawData] |
cld |
rep movsb |
.next: |
add edi, 15 |
and edi, not 15 |
add eax, COFF_SECTION_SIZE |
dec ebx |
jnz @B |
mov ebx, [edx+CFH.pSymTable] |
add ebx, edx |
mov [sym], ebx |
mov ecx, [edx+CFH.nSymbols] |
add ecx,ecx |
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE |
add ecx, [sym] |
mov [strings], ecx |
lea eax, [edx+20] |
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\ |
[strings], dword 0 |
test eax, eax |
jnz @F |
@@: |
mov edx, [coff] |
movzx ebx, [edx+CFH.nSections] |
mov edi, 0 |
lea eax, [edx+20] |
@@: |
add [eax+CFS.VirtualAddress], edi ;patch user space offset |
add eax, COFF_SECTION_SIZE |
dec ebx |
jnz @B |
add edx, 20 |
stdcall fix_coff_relocs, [coff], edx, [sym] |
mov ebx, [coff] |
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS |
mov [exports], eax |
stdcall kernel_free, [coff] |
mov eax, [exports] |
ret |
.fail: |
xor eax, eax |
ret |
endp |
proc dll.Load, import_table:dword |
mov esi,[import_table] |
.next_lib: mov edx,[esi] |
or edx,edx |
jz .exit |
push esi |
mov edi,s_libname |
mov al, '/' |
stosb |
mov esi,sysdir_path |
@@: lodsb |
stosb |
or al,al |
jnz @b |
dec edi |
mov [edi], dword '/lib' |
mov [edi+4],byte '/' |
add edi,5 |
pop esi |
push esi |
mov esi,[esi+4] |
@@: lodsb |
stosb |
or al,al |
jnz @b |
pushad |
stdcall load_k_library,s_libname |
mov [esp+28],eax |
popad |
or eax,eax |
jz .fail |
stdcall dll.Link,eax,edx |
stdcall dll.Init,[eax+4] |
pop esi |
add esi,8 |
jmp .next_lib |
.exit: xor eax,eax |
ret |
.fail: add esp,4 |
xor eax,eax |
inc eax |
ret |
endp |
proc dll.Link, exp:dword,imp:dword |
push eax |
mov esi,[imp] |
test esi,esi |
jz .done |
.next: lodsd |
test eax,eax |
jz .done |
stdcall dll.GetProcAddress,[exp],eax |
or eax,eax |
jz @f |
mov [esi-4],eax |
jmp .next |
@@: mov dword[esp],0 |
.done: pop eax |
ret |
endp |
proc dll.Init, dllentry:dword |
pushad |
mov eax,mem.Alloc |
mov ebx,mem.Free |
mov ecx,mem.ReAlloc |
mov edx,dll.Load |
stdcall [dllentry] |
popad |
ret |
endp |
proc dll.GetProcAddress, exp:dword,sz_name:dword |
mov edx,[exp] |
.next: test edx,edx |
jz .end |
stdcall strncmp,[edx],[sz_name], dword -1 |
test eax,eax |
jz .ok |
add edx,8 |
jmp .next |
.ok: mov eax,[edx+4] |
.end: ret |
endp |
;----------------------------------------------------------------------------- |
proc mem.Alloc size ;///////////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
push ebx ecx |
; mov eax,[size] |
; lea ecx,[eax+4+4095] |
; and ecx,not 4095 |
; stdcall kernel_alloc, ecx |
; add ecx,-4 |
; mov [eax],ecx |
; add eax,4 |
stdcall kernel_alloc, [size] |
pop ecx ebx |
ret |
endp |
;----------------------------------------------------------------------------- |
proc mem.ReAlloc mptr,size;/////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
push ebx ecx esi edi eax |
mov eax,[mptr] |
mov ebx,[size] |
or eax,eax |
jz @f |
lea ecx,[ebx+4+4095] |
and ecx,not 4095 |
add ecx,-4 |
cmp ecx,[eax-4] |
je .exit |
@@: mov eax,ebx |
call mem.Alloc |
xchg eax,[esp] |
or eax,eax |
jz .exit |
mov esi,eax |
xchg eax,[esp] |
mov edi,eax |
mov ecx,[esi-4] |
cmp ecx,[edi-4] |
jbe @f |
mov ecx,[edi-4] |
@@: add ecx,3 |
shr ecx,2 |
cld |
rep movsd |
xchg eax,[esp] |
call mem.Free |
.exit: |
pop eax edi esi ecx ebx |
ret |
endp |
;----------------------------------------------------------------------------- |
proc mem.Free mptr ;////////////////////////////////////////////////////////// |
;----------------------------------------------------------------------------- |
; mov eax,[mptr] |
; or eax,eax |
; jz @f |
; push ebx ecx |
; lea ecx,[eax-4] |
; stdcall kernel_free, ecx |
; pop ecx ebx |
; @@: ret |
stdcall kernel_free, [mptr] |
ret |
endp |
uglobal |
s_libname db 64 dup (0) |
endg |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/sched.inc |
---|
0,0 → 1,372 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; IRQ0 HANDLER (TIMER INTERRUPT) ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 32 |
irq0: |
; pushfd |
pushad |
mov ax, app_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 [DONT_SWITCH], byte 1 |
jne .change_task |
mov al,0x20 ; send End Of Interrupt signal |
mov dx,0x20 |
out dx,al |
mov [DONT_SWITCH], byte 0 |
popad |
; popfd |
iretd |
.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: |
popad |
; popfd |
iretd |
align 4 |
change_task: |
pushfd |
cli |
pushad |
call update_counters |
if 0 |
; \begin{Mario79} |
cmp [dma_task_switched], 1 |
jne .find_next_task |
mov [dma_task_switched], 0 |
mov ebx, [dma_process] |
cmp [CURRENT_TASK], ebx |
je .return |
mov edi, [dma_slot_ptr] |
mov [CURRENT_TASK], ebx |
mov [TASK_BASE], edi |
jmp @f |
.find_next_task: |
; \end{Mario79} |
end if |
call find_next_task |
test eax, eax ; the same task -> skip switch |
jnz .return |
@@: |
mov [DONT_SWITCH],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, [TASK_BASE] |
mov ebx, [edi+TASKDATA.counter_add] ; time stamp counter add |
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, [CURRENT_TASK] |
mov edi, [TASK_BASE] |
mov [prev_slot], ebx |
.waiting_for_termination: |
.waiting_for_reuse: |
.waiting_for_event: |
.suspended: |
cmp ebx, [TASK_COUNT] |
jb @f |
mov edi, CURRENT_TASK |
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 [CURRENT_TASK],ebx |
mov [TASK_BASE],edi |
cmp al, 5 |
jne .noevents |
call get_event_for_app |
test eax, eax |
jnz @f |
mov eax, ebx |
shl eax, 8 |
mov eax, [SLOT_BASE + APPDATA.wait_timeout + eax] |
cmp eax, [timer_ticks] |
jae .waiting_for_event |
xor eax, eax |
@@: |
mov [event_sched], eax |
mov [edi+TASKDATA.state], byte 0 |
.noevents: |
.found: |
mov [CURRENT_TASK],ebx |
mov [TASK_BASE],edi |
rdtsc ;call _rdtsc |
mov [edi+TASKDATA.counter_add],eax |
mov esi, [prev_slot] |
xor eax, eax |
cmp ebx, esi |
sete al |
ret |
; param |
; ebx = incoming task |
; esi = outcomig task |
do_change_task: |
shl ebx, 8 |
add ebx, SLOT_BASE |
mov [current_slot], ebx |
shl esi, 8 |
add esi, SLOT_BASE |
mov [esi+APPDATA.saved_esp], esp |
mov esp, [ebx+APPDATA.saved_esp] |
; set thread io map |
mov ecx, [ebx+APPDATA.io_map] |
mov edx, [ebx+APPDATA.io_map+4] |
mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)], ecx |
mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)], edx |
mov eax, [ebx+APPDATA.dir_table] |
mov cr3, eax |
mov ebx, [ebx+APPDATA.pl0_stack] |
add ebx, RING0_STACK_SIZE |
mov [tss._esp0], ebx |
push graph_data |
pop gs |
mov ecx, cr0 |
or ecx, CR0_TS ;set task switch flag |
mov cr0, ecx |
inc [context_counter] ;noname & halyavin |
test [ebx+APPDATA.dbg_state], 1 |
jnz @F |
ret |
@@: |
mov eax, [ebx+APPDATA.dbg_regs.dr0] |
mov dr0, eax |
mov eax, [ebx+APPDATA.dbg_regs.dr1] |
mov dr1, eax |
mov eax, [ebx+APPDATA.dbg_regs.dr2] |
mov dr2, eax |
mov eax, [ebx+APPDATA.dbg_regs.dr3] |
mov dr3, eax |
xor eax, eax |
mov dr6, eax |
mov eax, [ebx+APPDATA.dbg_regs.dr7] |
mov dr7, eax |
ret |
align 4 |
updatecputimes: |
mov eax,[idleuse] |
mov [idleusesec],eax |
mov [idleuse],dword 0 |
mov ecx, [TASK_COUNT] |
mov edi, TASK_DATA |
.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 |
if 0 |
struc TIMER |
{ |
.next dd ? |
.exp_time dd ? |
.func dd ? |
.arg dd ? |
} |
MAX_PROIRITY 0 ; highest, used for kernel tasks |
MAX_USER_PRIORITY 0 ; highest priority for user processes |
USER_PRIORITY 7 ; default (should correspond to nice 0) |
MIN_USER_PRIORITY 14 ; minimum priority for user processes |
IDLE_PRIORITY 15 ; lowest, only IDLE process goes here |
NR_SCHED_QUEUES 16 ; MUST equal IDLE_PRIORYTY + 1 |
rdy_head rd 16 |
align 4 |
pick_task: |
xor eax, eax |
.pick: |
mov ebx, [rdy_head+eax*4] |
test ebx, ebx |
jz .next |
mov [next_task], ebx |
test [ebx+flags.billable] |
jz @F |
mov [bill_task], ebx |
@@: |
ret |
.next: |
inc eax |
jmp .pick |
; param |
; eax= task |
; |
; retval |
; eax= task |
; ebx= queue |
; ecx= front if 1 or back if 0 |
align 4 |
shed: |
cmp [eax+.tics_left], 0 ;signed compare |
mov ebx, [eax+.priority] |
setg ecx |
jg @F |
mov edx, [eax+.tics_quantum] |
mov [eax+.ticks_left], edx |
cmp ebx, (IDLE_PRIORITY-1) |
je @F |
inc ebx |
@@: |
ret |
; param |
; eax= task |
align 4 |
enqueue: |
call shed ;eax |
cmp [rdy_head+ebx*4],0 |
jnz @F |
mov [rdy_head+ebx*4], eax |
mov [rdy_tail+ebx*4], eax |
mov [eax+.next_ready], 0 |
jmp .pick |
@@: |
test ecx, ecx |
jz .back |
mov ecx, [rdy_head+ebx*4] |
mov [eax+.next_ready], ecx |
mov [rdy_head+ebx*4], eax |
jmp .pick |
.back: |
mov ecx, [rdy_tail+ebx*4] |
mov [ecx+.next_ready], eax |
mov [rdy_tail+ebx*4], eax |
mov [eax+.next_ready], 0 |
.pick: |
call pick_proc ;select next task |
ret |
end if |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/dll.inc |
---|
0,0 → 1,1107 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
DRV_COMPAT equ 5 ;minimal required drivers version |
DRV_CURRENT equ 5 ;current drivers model version |
DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT |
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, app_data ;os_data |
mov ds, bx |
mov es, bx |
mov ebx, [irq_tab+eax*4] |
test ebx, ebx |
jz .exit |
call ebx |
mov [check_idle_semaphore],5 |
.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_slot] |
test dword [ebx+APPDATA.event_mask],EVENT_NOTIFY |
jz @f |
and dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY |
mov edi, [p_ev] |
mov dword [edi], EV_INTR |
mov eax, [ebx+APPDATA.event] |
mov dword [edi+4], eax |
ret |
@@: |
call change_task |
jmp .wait |
endp |
align 4 |
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword |
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 |
; param |
; ebx= io_control |
; |
; retval |
; eax= error code |
align 4 |
srv_handlerEx: |
cmp ebx, OS_BASE |
jae .fail |
mov eax, [ebx+handle] |
cmp [eax+SRV.magic], ' SRV' |
jne .fail |
cmp [eax+SRV.size], SRV_SIZE |
jne .fail |
stdcall [eax+SRV.srv_proc], ebx |
ret |
.fail: |
or eax, -1 |
ret |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc get_service stdcall, sz_name:dword |
mov eax, [sz_name] |
test eax, eax |
jnz @F |
ret |
@@: |
mov edx, [srv.fd] |
@@: |
cmp edx, srv.fd-SRV_FD_OFFSET |
je .not_load |
stdcall strncmp, edx, [sz_name], 16 |
test eax, eax |
je .ok |
mov edx, [edx+SRV.fd] |
jmp @B |
.not_load: |
pop ebp |
jmp load_driver |
.ok: |
mov eax, edx |
ret |
endp |
align 4 |
reg_service: |
.sz_name equ esp+4 |
.handler equ esp+8 |
mov eax, [.sz_name] |
test eax, eax |
jz .fail |
mov ebx, [.handler] |
test ebx, ebx |
jz .fail |
mov eax, SRV_SIZE |
call malloc ;call alloc_service |
test eax, eax |
jz .fail |
mov edi, eax |
mov esi, [.sz_name] |
mov ecx, 16/4 |
rep movsd |
mov [eax+SRV.magic], ' SRV' |
mov [eax+SRV.size], SRV_SIZE |
mov ebx, srv.fd-SRV_FD_OFFSET |
mov edx, [ebx+SRV.fd] |
mov [eax+SRV.fd], edx |
mov [eax+SRV.bk], ebx |
mov [ebx+SRV.fd], eax |
mov [edx+SRV.bk], eax |
mov ecx, [.handler] |
mov [eax+SRV.srv_proc], ecx |
ret 8 |
.fail: |
xor eax, eax |
ret 8 |
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] |
mov [cmd], eax |
mov [offset], ecx |
mov [offset+4], eax |
mov [count], edx |
mov [buff], esi |
mov byte [buff+4], al |
mov [name], ebx |
pushad |
push eax |
lea eax, [cmd] |
call file_system_lfn |
pop eax |
popad |
ret |
endp |
; description |
; allocate kernel memory and loads the specified file |
; |
; param |
; file_name= full path to file |
; |
; retval |
; eax= file image in kernel memory |
; ebx= size of file |
; |
; warging |
; You mast call kernel_free() to delete each file |
; loaded by the load_file() function |
align 4 |
proc load_file stdcall, file_name:dword |
locals |
attr dd ? |
flags dd ? |
cr_time dd ? |
cr_date dd ? |
acc_time dd ? |
acc_date dd ? |
mod_time dd ? |
mod_date dd ? |
file_size dd ? |
file dd ? |
file2 dd ? |
endl |
lea eax, [attr] |
stdcall get_fileinfo, [file_name], eax |
test eax, eax |
jnz .fail |
mov eax, [file_size] |
cmp eax, 1024*1024*16 |
ja .fail |
stdcall kernel_alloc, [file_size] |
mov [file], eax |
stdcall read_file, [file_name], eax, dword 0, [file_size] |
cmp ebx, [file_size] |
jne .cleanup |
mov eax, [file] |
cmp dword [eax], 0x4B43504B |
jne .exit |
mov ebx, [eax+4] |
mov [file_size], ebx |
stdcall kernel_alloc, ebx |
test eax, eax |
jz .cleanup |
mov [file2], eax |
stdcall unpack, [file], eax |
stdcall kernel_free, [file] |
mov eax, [file2] |
mov ebx, [file_size] |
.exit: |
push eax |
lea edi, [eax+ebx] ;cleanup remain space |
mov ecx, 4096 ;from file end |
and ebx, 4095 |
jz @f |
sub ecx, ebx |
xor eax, eax |
cld |
rep stosb |
@@: |
mov ebx, [file_size] |
pop eax |
ret |
.cleanup: |
stdcall kernel_free, [file] |
.fail: |
xor eax, eax |
xor ebx, ebx |
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], COFF_SECTION_SIZE |
dec [n_sec] |
jnz .fix_sec |
.exit: |
ret |
endp |
align 4 |
proc load_driver stdcall, driver_name:dword |
locals |
coff dd ? |
sym dd ? |
strings dd ? |
img_size dd ? |
img_base dd ? |
start dd ? |
exports dd ? ;fake exports table |
dd ? |
file_name rb 13+16+4+1 ; '/sys/drivers/<up-to-16-chars>.obj' |
endl |
lea edx, [file_name] |
mov dword [edx], '/sys' |
mov dword [edx+4], '/dri' |
mov dword [edx+8], 'vers' |
mov byte [edx+12], '/' |
mov esi, [driver_name] |
lea edi, [edx+13] |
mov ecx, 16 |
@@: |
lodsb |
test al, al |
jz @f |
stosb |
loop @b |
@@: |
mov dword [edi], '.obj' |
mov byte [edi+4], 0 |
stdcall load_file, edx |
test eax, eax |
jz .exit |
mov [coff], eax |
movzx ecx, [eax+CFH.nSections] |
xor ebx, ebx |
lea edx, [eax+20] |
@@: |
add ebx, [edx+CFS.SizeOfRawData] |
add ebx, 15 |
and ebx, not 15 |
add edx, COFF_SECTION_SIZE |
dec ecx |
jnz @B |
mov [img_size], ebx |
stdcall kernel_alloc, ebx |
test eax, eax |
jz .fail |
mov [img_base], eax |
mov edi, eax |
xor eax, eax |
mov ecx, [img_size] |
add ecx, 4095 |
and ecx, not 4095 |
shr ecx, 2 |
cld |
rep stosd |
mov edx, [coff] |
movzx ebx, [edx+CFH.nSections] |
mov edi, [img_base] |
lea eax, [edx+20] |
@@: |
mov [eax+CFS.VirtualAddress], edi |
mov esi, [eax+CFS.PtrRawData] |
test esi, esi |
jnz .copy |
add edi, [eax+CFS.SizeOfRawData] |
jmp .next |
.copy: |
add esi, edx |
mov ecx, [eax+CFS.SizeOfRawData] |
cld |
rep movsb |
.next: |
add edi, 15 |
and edi, not 15 |
add eax, COFF_SECTION_SIZE |
dec ebx |
jnz @B |
mov ebx, [edx+CFH.pSymTable] |
add ebx, edx |
mov [sym], ebx |
mov ecx, [edx+CFH.nSymbols] |
add ecx,ecx |
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE |
add ecx, [sym] |
mov [strings], ecx |
lea ebx, [exports] |
mov dword [ebx], kernel_export |
mov dword [ebx+4], 0 |
lea eax, [edx+20] |
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\ |
[strings], ebx |
test eax, eax |
jz .link_fail |
mov ebx, [coff] |
add ebx, 20 |
stdcall fix_coff_relocs, [coff], ebx, [sym] |
mov ebx, [coff] |
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szVersion |
test eax, eax |
jz .link_fail |
mov eax, [eax] |
shr eax, 16 |
cmp eax, DRV_COMPAT |
jb .ver_fail |
cmp eax, DRV_CURRENT |
ja .ver_fail |
mov ebx, [coff] |
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART |
mov [start], eax |
stdcall kernel_free, [coff] |
mov ebx, [start] |
stdcall ebx, DRV_ENTRY |
test eax, eax |
jnz .ok |
stdcall kernel_free, [img_base] |
xor eax, eax |
ret |
.ok: |
mov ebx, [img_base] |
mov [eax+SRV.base], ebx |
mov ecx, [start] |
mov [eax+SRV.entry], ecx |
ret |
.ver_fail: |
mov esi, msg_CR |
call sys_msg_board_str |
mov esi, [driver_name] |
call sys_msg_board_str |
mov esi, msg_CR |
call sys_msg_board_str |
mov esi, msg_version |
call sys_msg_board_str |
mov esi, msg_www |
call sys_msg_board_str |
jmp .cleanup |
.link_fail: |
mov esi, msg_module |
call sys_msg_board_str |
mov esi, [driver_name] |
call sys_msg_board_str |
mov esi, msg_CR |
call sys_msg_board_str |
.cleanup: |
stdcall kernel_free,[img_base] |
.fail: |
stdcall kernel_free, [coff] |
.exit: |
xor eax, eax |
ret |
endp |
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, COFF_SECTION_SIZE |
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, -16 |
add eax, COFF_SECTION_SIZE |
dec ebx |
jnz @B |
mov ebx, [edx+CFH.pSymTable] |
add ebx, edx |
mov [sym], ebx |
mov ecx, [edx+CFH.nSymbols] |
add ecx,ecx |
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE |
add ecx, [sym] |
mov [strings], ecx |
lea eax, [edx+20] |
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\ |
[strings], dword 0 |
test eax, eax |
jnz @F |
@@: |
mov edx, [coff] |
movzx ebx, [edx+CFH.nSections] |
mov edi, new_app_base |
lea eax, [edx+20] |
@@: |
add [eax+CFS.VirtualAddress], edi ;patch user space offset |
add eax, COFF_SECTION_SIZE |
dec ebx |
jnz @B |
add edx, 20 |
stdcall fix_coff_relocs, [coff], edx, [sym] |
mov ebx, [coff] |
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS |
mov [exports], eax |
stdcall kernel_free, [coff] |
mov eax, [exports] |
ret |
.fail: |
xor eax, eax |
ret |
endp |
align 4 |
proc stop_all_services |
mov edx, [srv.fd] |
.next: |
cmp edx, srv.fd-SRV_FD_OFFSET |
je .done |
cmp [edx+SRV.magic], ' SRV' |
jne .next |
cmp [edx+SRV.size], SRV_SIZE |
jne .next |
mov ebx, [edx+SRV.entry] |
mov edx, [edx+SRV.fd] |
push edx |
stdcall ebx, dword -1 |
pop edx |
jmp .next |
.done: |
ret |
endp |
; param |
; eax= size |
; ebx= pid |
align 4 |
create_kernel_object: |
push ebx |
call malloc |
pop ebx |
test eax, eax |
jz .fail |
mov ecx,[current_slot] |
add ecx, APP_OBJ_OFFSET |
pushfd |
cli |
mov edx, [ecx+APPOBJ.fd] |
mov [eax+APPOBJ.fd], edx |
mov [eax+APPOBJ.bk], ecx |
mov [eax+APPOBJ.pid], ebx |
mov [ecx+APPOBJ.fd], eax |
mov [edx+APPOBJ.bk], eax |
popfd |
.fail: |
ret |
; param |
; eax= object |
align 4 |
destroy_kernel_object: |
pushfd |
cli |
mov ebx, [eax+APPOBJ.fd] |
mov ecx, [eax+APPOBJ.bk] |
mov [ebx+APPOBJ.bk], ecx |
mov [ecx+APPOBJ.fd], ebx |
popfd |
xor edx, edx ;clear common header |
mov [eax], edx |
mov [eax+4], edx |
mov [eax+8], edx |
mov [eax+12], edx |
mov [eax+16], edx |
call free ;release object memory |
ret |
if 0 |
irq: |
.irq0: |
pusfd |
pushad |
push IRQ_0 |
jmp .master |
.irq_1: |
pusfd |
pushad |
push IRQ_1 |
jmp .master |
.master: |
mov ax, app_data |
mov ds, eax |
mov es, eax |
mov ebx, [esp+4] ;IRQ_xx |
mov eax, [irq_handlers+ebx+4] |
call intr_handler |
mov ecx, [esp+4] |
cmp [irq_actids+ecx*4], 0 |
je @F |
in al, 0x21 |
bts eax, ecx |
out 0x21, al |
mov al, 0x20 |
out 0x20, al |
jmp .restart |
.slave: |
mov ax, app_data |
mov ds, eax |
mov es, eax |
mov ebx, [esp+4] ;IRQ_xx |
mov eax, [irq_handlers+ebx+4] |
call intr_handler |
mov ecx, [esp+4] |
sub ecx, 8 |
cmp [irq_actids+ecx*4], 0 |
je @F |
in al, 0xA1 |
bts eax, ecx |
out 0xA1, al |
mov al, 0x20 |
out 0xA0, al |
out 0x20, al |
.restart: |
mov ebx, [next_slot] |
test ebx, ebx |
jz @F |
mov [next_task],0 |
mov esi, [prev_slot] |
call do_change_task |
add esp, 4 |
iretd |
end if |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/taskman.inc |
---|
0,0 → 1,1126 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
GREEDY_KERNEL equ 0 |
struc APP_HEADER_00 |
{ .banner dq ? |
.version dd ? ;+8 |
.start dd ? ;+12 |
.i_end dd ? ;+16 |
.mem_size dd ? ;+20 |
.i_param dd ? ;+24 |
} |
struc APP_HEADER_01 |
{ .banner dq ? |
.version dd ? ;+8 |
.start dd ? ;+12 |
.i_end dd ? ;+16 |
.mem_size dd ? ;+20 |
.stack_top dd ? ;+24 |
.i_param dd ? ;+28 |
.i_icon dd ? ;+32 |
} |
struc APP_PARAMS |
{ .app_cmdline ;0x00 |
.app_path ;0x04 |
.app_eip ;0x08 |
.app_esp ;0x0C |
.app_mem ;0x10 |
} |
macro _clear_ op |
{ mov ecx, op/4 |
xor eax, eax |
cld |
rep stosd |
} |
fs_execute_from_sysdir: |
xor ebx, ebx |
xor edx, edx |
mov esi, sysdir_path |
align 4 |
proc fs_execute |
;fn_read:dword, file_size:dword, cluster:dword |
; ebx - cmdline |
; edx - flags |
; ebp - full filename |
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it |
locals |
cmdline rd 64 ;256/4 |
filename rd 256 ;1024/4 |
flags dd ? |
save_cr3 dd ? |
slot dd ? |
slot_base dd ? |
file_base dd ? |
file_size dd ? |
;app header data |
hdr_cmdline dd ? ;0x00 |
hdr_path dd ? ;0x04 |
hdr_eip dd ? ;0x08 |
hdr_esp dd ? ;0x0C |
hdr_mem dd ? ;0x10 |
hdr_i_end dd ? ;0x14 |
endl |
pushad |
mov [flags], edx |
; [ebp] pointer to filename |
lea edi, [filename] |
lea ecx, [edi+1024] |
mov al, '/' |
stosb |
@@: |
cmp edi, ecx |
jae .bigfilename |
lodsb |
stosb |
test al, al |
jnz @b |
mov esi, [ebp] |
test esi, esi |
jz .namecopied |
mov byte [edi-1], '/' |
@@: |
cmp edi, ecx |
jae .bigfilename |
lodsb |
stosb |
test al, al |
jnz @b |
jmp .namecopied |
.bigfilename: |
popad |
mov eax, -ERROR_FILE_NOT_FOUND |
ret |
.namecopied: |
mov [cmdline], ebx |
test ebx, ebx |
jz @F |
lea eax, [cmdline] |
mov dword [eax+252], 0 |
stdcall strncpy, eax, ebx, 255 |
@@: |
lea eax, [filename] |
stdcall load_file, eax |
mov ecx, -ERROR_FILE_NOT_FOUND |
test eax, eax |
jz .err_file |
mov [file_base], eax |
mov [file_size], ebx |
lea ebx, [hdr_cmdline] |
call test_app_header |
mov ecx, -0x1F |
test eax, eax |
jz .err_hdr |
;mov esi, new_process_loading |
;call sys_msg_board_str ; write message to message board |
DEBUGF 1,"%s",new_process_loading |
.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 |
shl eax, 8 |
add eax, SLOT_BASE |
mov [slot_base], eax |
mov edi, eax |
_clear_ 256 ;clean extended information about process |
; write application name |
lea eax, [filename] |
stdcall strrchr, eax, '/' ; now eax points to name without path |
lea esi, [eax+1] |
test eax, eax |
jnz @F |
lea esi, [filename] |
@@: |
mov ecx, 8 ; 8 chars for name |
mov edi, [slot_base] |
.copy_process_name_loop: |
lodsb |
cmp al, '.' |
jz .copy_process_name_done |
test al, al |
jz .copy_process_name_done |
stosb |
loop .copy_process_name_loop |
.copy_process_name_done: |
mov ebx, cr3 |
mov [save_cr3], ebx |
stdcall create_app_space,[hdr_mem],[file_base],[file_size] |
mov ecx, -30 ; no memory |
test eax, eax |
jz .failed |
mov ebx,[slot_base] |
mov [ebx+APPDATA.dir_table],eax |
mov eax,[hdr_mem] |
mov [ebx+APPDATA.mem_size],eax |
if GREEDY_KERNEL |
else |
mov ecx, [hdr_mem] |
mov edi, [file_size] |
add edi, 4095 |
and edi, not 4095 |
sub ecx, edi |
jna @F |
xor eax, eax |
; add edi, new_app_base |
cld |
rep stosb |
@@: |
end if |
; release only virtual space, not phisical memory |
stdcall free_kernel_space, [file_base] |
lea eax, [hdr_cmdline] |
lea ebx, [cmdline] |
lea ecx, [filename] |
stdcall set_app_params ,[slot],eax,ebx,ecx,[flags] |
mov eax, [save_cr3] |
call set_cr3 |
xor ebx, ebx |
mov [application_table_status],ebx ;unlock application_table_status mutex |
mov eax,[process_number] ;set result |
ret |
.failed: |
mov eax, [save_cr3] |
call set_cr3 |
.err: |
.err_hdr: |
stdcall kernel_free,[file_base] |
.err_file: |
xor eax, eax |
mov [application_table_status],eax |
mov eax, ecx |
ret |
endp |
align 4 |
test_app_header: |
virtual at eax |
APP_HEADER_00 APP_HEADER_00 |
end virtual |
virtual at eax |
APP_HEADER_01 APP_HEADER_01 |
end virtual |
cmp dword [eax], 'MENU' |
jne .fail |
cmp word [eax+4],'ET' |
jne .fail |
cmp [eax+6], word '00' |
jne .check_01_header |
mov ecx,[APP_HEADER_00.start] |
mov [ebx+0x08], ecx ;app_eip |
mov edx,[APP_HEADER_00.mem_size] |
mov [ebx+0x10], edx ;app_mem |
shr edx,1 |
sub edx,0x10 |
mov [ebx+0x0C], edx ;app_esp |
mov ecx,[APP_HEADER_00.i_param] |
mov [ebx], ecx ;app_cmdline |
mov [ebx+4], dword 0 ;app_path |
mov edx, [APP_HEADER_00.i_end] |
mov [ebx+0x14], edx |
ret |
.check_01_header: |
cmp [eax+6],word '01' |
jne .fail |
mov ecx,[APP_HEADER_01.start] |
mov [ebx+0x08], ecx ;app_eip |
mov edx,[APP_HEADER_01.mem_size] |
; \begin{diamond}[20.08.2006] |
; sanity check (functions 19,58 load app_i_end bytes and that must |
; fit in allocated memory to prevent kernel faults) |
cmp edx,[APP_HEADER_01.i_end] |
jb .fail |
; \end{diamond}[20.08.2006] |
mov [ebx+0x10], edx ;app_mem |
mov ecx,[APP_HEADER_01.stack_top] |
mov [ebx+0x0C], ecx ;app_esp |
mov edx,[APP_HEADER_01.i_param] |
mov [ebx], edx ;app_cmdline |
mov ecx,[APP_HEADER_01.i_icon] |
mov [ebx+4], ecx ;app_path |
mov edx, [APP_HEADER_01.i_end] |
mov [ebx+0x14], edx |
ret |
.fail: |
xor eax, eax |
ret |
align 4 |
proc get_new_process_place |
;input: |
; none |
;result: |
; eax=[new_process_place]<>0 - ok |
; 0 - failed. |
;This function find least empty slot. |
;It doesn't increase [TASK_COUNT]! |
mov eax,CURRENT_TASK |
mov ebx,[TASK_COUNT] |
inc ebx |
shl ebx,5 |
add ebx,eax ;ebx - address of process information for (last+1) slot |
.newprocessplace: |
;eax = address of process information for current slot |
cmp eax,ebx |
jz .endnewprocessplace ;empty slot after high boundary |
add eax,0x20 |
cmp word [eax+0xa],9 ;check process state, 9 means that process slot is empty |
jnz .newprocessplace |
.endnewprocessplace: |
mov ebx,eax |
sub eax,CURRENT_TASK |
shr eax,5 ;calculate slot index |
cmp eax,256 |
jge .failed ;it should be <256 |
mov word [ebx+0xa],9 ;set process state to 9 (for slot after hight boundary) |
ret |
.failed: |
xor eax,eax |
ret |
endp |
align 4 |
proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword |
locals |
app_pages dd ? |
img_pages dd ? |
dir_addr dd ? |
app_tabs dd ? |
endl |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
xor eax, eax |
mov [dir_addr], eax |
mov eax, [app_size] |
add eax, 4095 |
and eax, NOT(4095) |
mov [app_size], eax |
mov ebx, eax |
shr eax, 12 |
mov [app_pages], eax |
add ebx, 0x3FFFFF |
and ebx, NOT(0x3FFFFF) |
shr ebx, 22 |
mov [app_tabs], ebx |
mov ecx, [img_size] |
add ecx, 4095 |
and ecx, NOT(4095) |
mov [img_size], ecx |
shr ecx, 12 |
mov [img_pages], ecx |
if GREEDY_KERNEL |
lea eax, [ecx+ebx+2] ;only image size |
else |
lea eax, [eax+ebx+2] ;all requested memory |
end if |
cmp eax, [pg_data.pages_free] |
ja .fail |
call alloc_page |
test eax, eax |
jz .fail |
mov [dir_addr], eax |
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW |
mov edi, [tmp_task_pdir] |
mov ecx, (OS_BASE shr 20)/4 |
xor eax, eax |
cld |
rep stosd |
mov ecx, (OS_BASE shr 20)/4 |
mov esi, sys_pgdir+(OS_BASE shr 20) |
rep movsd |
mov eax, [dir_addr] |
or eax, PG_SW |
mov [edi-4096+(page_tabs shr 20)], eax |
and eax, -4096 |
call set_cr3 |
mov edx, [app_tabs] |
mov edi, new_app_base |
@@: |
call alloc_page |
test eax, eax |
jz .fail |
stdcall map_page_table, edi, eax |
add edi, 0x00400000 |
dec edx |
jnz @B |
mov edi, new_app_base |
shr edi, 10 |
add edi, page_tabs |
mov ecx, [app_tabs] |
shl ecx, 10 |
xor eax, eax |
rep stosd |
mov ecx, [img_pages] |
mov ebx, PG_UW |
mov edx, new_app_base |
mov esi, [img_base] |
mov edi, new_app_base |
shr esi, 10 |
shr edi, 10 |
add esi, page_tabs |
add edi, page_tabs |
.remap: |
lodsd |
or eax, ebx ; force user level r/w access |
stosd |
add edx, 0x1000 |
dec [app_pages] |
dec ecx |
jnz .remap |
mov ecx, [app_pages] |
test ecx, ecx |
jz .done |
if GREEDY_KERNEL |
mov eax, 0x02 |
.reserve: |
stosd |
invlpg [edx] |
add edx, 4096 |
dec ecx |
jnz .reserve |
else |
.alloc: |
call alloc_page |
test eax, eax |
jz .fail |
stdcall map_page,edx,eax,dword PG_UW |
add edx, 0x1000 |
dec [app_pages] |
jnz .alloc |
end if |
.done: |
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP |
dec [pg_data.pg_mutex] |
mov eax, [dir_addr] |
ret |
.fail: |
dec [pg_data.pg_mutex] |
cmp [dir_addr], 0 |
je @f |
stdcall destroy_app_space, [dir_addr] |
@@: |
xor eax, eax |
ret |
endp |
align 4 |
set_cr3: |
mov ebx, [current_slot] |
mov [ebx+APPDATA.dir_table], eax |
mov cr3, eax |
ret |
align 4 |
proc destroy_page_table stdcall, pg_tab:dword |
push esi |
mov esi, [pg_tab] |
mov ecx, 1024 |
.free: |
mov eax, [esi] |
test eax, 1 |
jz .next |
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 |
mov ebx, pg_data.pg_mutex |
call wait_mutex ;ebx |
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 [SLOT_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] |
mov edi, (OS_BASE shr 20)/4 |
.destroy: |
mov eax, [esi] |
test eax, 1 |
jz .next |
and eax, not 0xFFF |
stdcall map_page,[tmp_task_ptab],eax,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 |
get_pid: |
mov eax, [TASK_DATA] |
mov eax, [eax+4] |
ret |
pid_to_slot: |
;Input: |
; eax - pid of process |
;Output: |
; eax - slot of process or 0 if process don't exists |
;Search process by PID. |
push ebx |
push ecx |
mov ebx,[TASK_COUNT] |
shl ebx,5 |
mov ecx,2*32 |
.loop: |
;ecx=offset of current process info entry |
;ebx=maximum permitted offset |
cmp byte [CURRENT_TASK+ecx+0xa],9 |
jz .endloop ;skip empty slots |
cmp [CURRENT_TASK+ecx+0x4],eax ;check PID |
jz .pid_found |
.endloop: |
add ecx,32 |
cmp ecx,ebx |
jle .loop |
pop ecx |
pop ebx |
xor eax,eax |
ret |
.pid_found: |
shr ecx,5 |
mov eax,ecx ;convert offset to index of slot |
pop ecx |
pop ebx |
ret |
check_region: |
;input: |
; 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,[SLOT_BASE+eax+0xb8] |
test eax,eax |
jz .failed |
mov eax,1 |
ret |
; call MEM_Get_Linear_Address |
; push ebx |
; push ecx |
; push edx |
; mov edx,ebx |
; and edx,not (4096-1) |
; sub ebx,edx |
; add ecx,ebx |
; mov ebx,edx |
; add ecx,(4096-1) |
; and ecx,not (4096-1) |
;.loop: |
;;eax - linear address of page directory |
;;ebx - current page |
;;ecx - current size |
; mov edx,ebx |
; shr edx,22 |
; mov edx,[eax+4*edx] |
; and edx,not (4096-1) |
; test edx,edx |
; jz .failed1 |
; push eax |
; mov eax,edx |
; call MEM_Get_Linear_Address |
; mov edx,ebx |
; shr edx,12 |
; and edx,(1024-1) |
; mov eax,[eax+4*edx] |
; and eax,not (4096-1) |
; test eax,eax |
; pop eax |
; jz .failed1 |
; add ebx,4096 |
; sub ecx,4096 |
; jg .loop |
; pop edx |
; pop ecx |
; pop ebx |
.ok: |
mov eax,1 |
ret |
; |
;.failed1: |
; pop edx |
; pop ecx |
; pop ebx |
.failed: |
xor eax,eax |
ret |
align 4 |
proc read_process_memory |
;Input: |
; eax - process slot |
; 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 |
and [r_count], 0 |
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],\ |
[SLOT_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 [r_count], edx |
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 |
and [w_count], 0 |
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],\ |
[SLOT_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 [w_count], edx |
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 |
slot dd ? |
app_cmdline dd ? ;0x00 |
app_path dd ? ;0x04 |
app_eip dd ? ;0x08 |
app_esp dd ? ;0x0C |
app_mem dd ? ;0x10 |
endl |
cmp eax,1 |
jne .failed ;other subfunctions |
xor eax,eax |
mov [app_cmdline], eax |
mov [app_path], eax |
mov [app_eip], ebx |
mov [app_esp], ecx |
;mov esi,new_process_loading |
;call sys_msg_board_str |
DEBUGF 1,"%s",new_process_loading |
.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 |
mov esi,[current_slot] |
mov ebx,esi ;ebx=esi - pointer to extended information about current thread |
mov edi, eax |
shl edi,8 |
add edi,SLOT_BASE |
mov edx,edi ;edx=edi - pointer to extended infomation about new thread |
mov ecx,256/4 |
xor eax, eax |
cld |
rep stosd ;clean extended information about new thread |
mov esi,ebx |
mov edi,edx |
mov ecx,11 |
rep movsb ;copy process name |
mov eax,[ebx+APPDATA.heap_base] |
mov [edx+APPDATA.heap_base], eax |
mov ecx,[ebx+APPDATA.heap_top] |
mov [edx+APPDATA.heap_top], ecx |
mov eax,[ebx+APPDATA.mem_size] |
mov [edx+APPDATA.mem_size], eax |
mov ecx,[ebx+APPDATA.dir_table] |
mov [edx+APPDATA.dir_table],ecx ;copy page directory |
lea eax, [app_cmdline] |
stdcall set_app_params ,[slot],eax,dword 0,\ |
dword 0,dword 0 |
;mov esi,new_process_running |
;call sys_msg_board_str ;output information about succefull startup |
DEBUGF 1,"%s",new_process_running |
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 |
; param |
; ebx=mutex |
align 4 |
wait_mutex: |
push eax |
push ebx |
.do_wait: |
cmp dword [ebx],0 |
je .get_lock |
call change_task |
jmp .do_wait |
.get_lock: |
mov eax, 1 |
xchg eax, [ebx] |
test eax, eax |
jnz .do_wait |
pop ebx |
pop eax |
ret |
EFL_IF equ 0x0200 |
EFL_IOPL1 equ 0x1000 |
EFL_IOPL2 equ 0x2000 |
EFL_IOPL3 equ 0x3000 |
align 4 |
proc set_app_params stdcall,slot:dword, params:dword,\ |
cmd_line:dword, app_path:dword, flags:dword |
locals |
pl0_stack dd ? |
endl |
stdcall kernel_alloc, RING0_STACK_SIZE+512 |
mov [pl0_stack], eax |
lea edi, [eax+RING0_STACK_SIZE] |
mov eax, [slot] |
mov ebx, eax |
shl eax, 8 |
mov [eax+SLOT_BASE+APPDATA.fpu_state], edi |
mov [eax+SLOT_BASE+APPDATA.fpu_handler], 0 |
mov [eax+SLOT_BASE+APPDATA.sse_handler], 0 |
;set default io permission map |
mov [eax+SLOT_BASE+APPDATA.io_map],\ |
(tss._io_map_0-OS_BASE+PG_MAP) |
mov [eax+SLOT_BASE+APPDATA.io_map+4],\ |
(tss._io_map_1-OS_BASE+PG_MAP) |
mov esi, fpu_data |
mov ecx, 512/4 |
rep movsd |
cmp ebx,[TASK_COUNT] |
jle .noinc |
inc dword [TASK_COUNT] ;update number of processes |
.noinc: |
shl ebx,8 |
lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET] |
mov [SLOT_BASE+APPDATA.fd_ev+ebx],edx |
mov [SLOT_BASE+APPDATA.bk_ev+ebx],edx |
add edx, APP_OBJ_OFFSET-APP_EV_OFFSET |
mov [SLOT_BASE+APPDATA.fd_obj+ebx],edx |
mov [SLOT_BASE+APPDATA.bk_obj+ebx],edx |
mov ecx, [def_cursor] |
mov [SLOT_BASE+APPDATA.cursor+ebx],ecx |
mov eax, [pl0_stack] |
mov [SLOT_BASE+APPDATA.pl0_stack+ebx],eax |
push ebx |
stdcall kernel_alloc, 0x1000 |
pop ebx |
mov esi,[current_slot] |
mov esi,[esi+APPDATA.cur_dir] |
mov ecx,0x1000/4 |
mov edi,eax |
mov [ebx+SLOT_BASE+APPDATA.cur_dir],eax |
rep movsd |
shr ebx,3 |
mov eax, new_app_base |
mov dword [CURRENT_TASK+ebx+0x10],eax |
.add_command_line: |
mov edx,[params] |
mov edx,[edx] ;app_cmdline |
test edx,edx |
jz @f ;application doesn't need parameters |
mov eax, edx |
add eax, 256 |
jc @f |
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] |
ja @f |
mov byte [edx], 0 ;force empty string if no cmdline given |
mov eax, [cmd_line] |
test eax, eax |
jz @f |
stdcall strncpy, edx, eax, 256 |
@@: |
mov edx,[params] |
mov edx, [edx+4] ;app_path |
test edx,edx |
jz @F ;application don't need path of file |
mov eax, edx |
add eax, 1024 |
jc @f |
cmp eax, [SLOT_BASE+APPDATA.mem_size+ebx*8] |
ja @f |
stdcall strncpy, edx, [app_path], 1024 |
@@: |
mov ebx,[slot] |
mov eax,ebx |
shl ebx,5 |
lea ecx,[draw_data+ebx] ;ecx - pointer to draw data |
; set window state to 'normal' (non-minimized/maximized/rolled-up) state |
mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL |
mov [ebx+window_data+WDATA.fl_redraw], 1 |
add ebx,CURRENT_TASK ;ebx - pointer to information about process |
mov [ebx+TASKDATA.wnd_number],al;set window number on screen = process slot |
mov [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function) |
inc dword [process_number] |
mov eax,[process_number] |
mov [ebx+4],eax ;set PID |
;set draw data to full screen |
mov [ecx+0],dword 0 |
mov [ecx+4],dword 0 |
mov eax,[ScreenWidth] |
mov [ecx+8],eax |
mov eax,[ScreenHeight] |
mov [ecx+12],eax |
mov ebx, [pl0_stack] |
mov esi,[params] |
lea ecx, [ebx+REG_EIP] |
xor eax, eax |
mov [ebx+REG_RET], dword irq0.return |
mov [ebx+REG_EDI], eax |
mov [ebx+REG_ESI], eax |
mov [ebx+REG_EBP], eax |
mov [ebx+REG_ESP], ecx ;ebx+REG_EIP |
mov [ebx+REG_EBX], eax |
mov [ebx+REG_EDX], eax |
mov [ebx+REG_ECX], eax |
mov [ebx+REG_EAX], eax |
mov eax, [esi+0x08] ;app_eip |
mov [ebx+REG_EIP], eax ;app_entry |
mov [ebx+REG_CS], dword app_code |
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF |
mov eax, [esi+0x0C] ;app_esp |
mov [ebx+REG_APP_ESP], eax ;app_stack |
mov [ebx+REG_SS], dword app_data |
lea ecx, [ebx+REG_RET] |
mov ebx, [slot] |
shl ebx, 8 |
mov [ebx+SLOT_BASE+APPDATA.saved_esp], ecx |
;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 [SLOT_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 |
DEBUGF 1,"%s",new_process_running |
ret |
endp |
include "debug.inc" |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/sys32.inc |
---|
0,0 → 1,844 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; MenuetOS process management, protected ring3 ;; |
;; ;; |
;; Distributed under GPL. See file COPYING for details. ;; |
;; Copyright 2003 Ville Turjanmaa ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
idtreg: |
dw 8*0x41-1 |
dd idts+8 |
build_interrupt_table: |
mov edi, idts+8 |
mov esi, sys_int |
mov ecx, 0x40 |
@@: |
lodsd |
mov [edi], ax ; lower part of offset |
mov [edi+2], word os_code ; segment selector |
mov ax, word 10001110b shl 8 ; type: interrupt gate |
mov [edi+4], eax |
add edi, 8 |
loop @b |
;mov edi,8*0x40+idts+8 |
mov dword [edi], (i40 and 0xFFFF) or (os_code shl 16) |
mov dword [edi+4], (11101111b shl 8) or (i40 and 0xFFFF0000) |
; type: trap gate |
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 , p_irq3 ;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,irq_serv.irq_12,irqD ,p_irq14,p_irq15 |
times 16 dd unknown_interrupt |
dd i40 |
endg |
macro save_ring3_context |
{ |
pushad |
} |
macro restore_ring3_context |
{ |
popad |
} |
; 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, app_data ;èñêëþ÷åíèå |
mov ds, ax ;çàãðóçèì ïðàâèëüíûå çíà÷åíè |
mov es, ax ;â ðåãèñòðû |
; test if debugging |
cli |
mov eax, [current_slot] |
mov eax, [eax+APPDATA.debugger_slot] |
test eax, eax |
jnz .debug |
sti |
; not debuggee => say error and terminate |
add esp, 0x20 ;28h |
movzx eax, bl |
mov [error_interrupt], eax |
call show_error_parameters |
mov edx, [TASK_BASE] |
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, [TASK_BASE] |
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, [TASK_BASE] |
mov byte [edx+TASKDATA.state], 1 ; suspended |
call change_task |
restore_ring3_context |
iretd |
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,[CURRENT_TASK] |
shl eax, 5 |
mov eax,[CURRENT_TASK+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 |
DEBUGF 1,"%s",system_error |
@@: |
mov eax, [esp+4] ; EIP |
mov [write_error_to],process_eip+43 |
call writehex |
;mov esi,process_error |
;call sys_msg_board_str |
DEBUGF 1,"%s",process_error |
;mov esi,process_pid |
;call sys_msg_board_str |
DEBUGF 1,"%s",process_pid |
;mov esi,process_eip |
;call sys_msg_board_str |
DEBUGF 1,"%s",process_eip |
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, app_data ;os_data |
mov ds, ax |
mov es, ax |
call irqhandler |
restore_ring3_context |
iret |
p_irq6: |
save_ring3_context |
mov ax, app_data ;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, app_data ;os_data |
mov ds, ax |
mov es, ax |
cmp [com2_mouse_detected],0 |
je old_irq3_handler |
mov esi, com2_mouse |
mov dx, 2F8h ;[COMPortBaseAddr] |
call check_mouse_data_com |
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, app_data ;os_data |
mov ds, ax |
mov es, ax |
cmp [com1_mouse_detected],0 |
je old_irq4_handler |
mov esi, com1_mouse |
mov dx, 3F8h ;[COMPortBaseAddr] |
call check_mouse_data_com |
jmp p_irq4_1 |
old_irq4_handler: |
mov edi,4 |
call irqhandler |
p_irq4_1: |
restore_ring3_context |
iret |
p_irq14: |
save_ring3_context |
mov ax, app_data ;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, app_data ;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, app_data ;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,IRQ_SAVE |
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,[CURRENT_TASK] |
shl eax, 5 |
add eax,CURRENT_TASK+TASKDATA.pid |
mov eax,[eax] |
mov [application_table_status],eax |
pop eax |
ret |
clear_application_table_status: |
push eax |
mov eax,[CURRENT_TASK] |
shl eax, 5 |
add eax,CURRENT_TASK+TASKDATA.pid |
mov eax,[eax] |
cmp eax,[application_table_status] |
jne apptsl1 |
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 |
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 |
msg_obj_destroy db 'K : destroy app object',13,10,0 |
endg |
; param |
; esi= slot |
terminate: ; terminate application |
.slot equ esp ;locals |
push esi ;save .slot |
shl esi, 8 |
cmp [SLOT_BASE+esi+APPDATA.dir_table], 0 |
jne @F |
add esp, 4 |
ret |
@@: |
;mov esi,process_terminating |
;call sys_msg_board_str |
DEBUGF 1,"%s",process_terminating |
@@: |
cli |
cmp [application_table_status],0 |
je term9 |
sti |
call change_task |
jmp @b |
term9: |
call set_application_table_status |
mov esi, [.slot] |
shl esi,8 |
add esi, SLOT_BASE+APP_OBJ_OFFSET |
@@: |
mov eax, [esi+APPOBJ.fd] |
test eax, eax |
jz @F |
cmp eax, esi |
je @F |
push esi |
call [eax+APPOBJ.destroy] |
;mov esi, msg_obj_destroy |
;call sys_msg_board_str |
DEBUGF 1,"%s",msg_obj_destroy |
pop esi |
jmp @B |
@@: |
mov eax, [.slot] |
shl eax, 8 |
mov eax,[SLOT_BASE+eax+APPDATA.dir_table] |
stdcall destroy_app_space, eax |
mov esi, [.slot] |
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1 |
jne @F |
mov [fpu_owner],1 |
mov eax, [256+SLOT_BASE+APPDATA.fpu_state] |
clts |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
fxrstor [eax] |
jmp @F |
.no_SSE: |
fnclex |
frstor [eax] |
@@: |
mov [KEY_COUNT],byte 0 ; empty keyboard buffer |
mov [BTN_COUNT],byte 0 ; empty button buffer |
; remove defined hotkeys |
mov eax, hotkey_list |
.loop: |
cmp [eax+8], esi |
jnz .cont |
mov ecx, [eax] |
jecxz @f |
push dword [eax+12] |
pop dword [ecx+12] |
@@: |
mov ecx, [eax+12] |
push dword [eax] |
pop dword [ecx] |
xor ecx, ecx |
mov [eax], ecx |
mov [eax+4], ecx |
mov [eax+8], ecx |
mov [eax+12], ecx |
.cont: |
add eax, 16 |
cmp eax, hotkey_list+256*16 |
jb .loop |
; remove hotkeys in buffer |
mov eax, hotkey_buffer |
.loop2: |
cmp [eax], esi |
jnz .cont2 |
and dword [eax+4], 0 |
and dword [eax], 0 |
.cont2: |
add eax, 8 |
cmp eax, hotkey_buffer+120*8 |
jb .loop2 |
mov ecx,esi ; remove buttons |
bnewba2: |
mov edi,[BTN_ADDR] |
mov eax,edi |
cld |
movzx ebx,word [edi] |
inc bx |
bnewba: |
dec bx |
jz bnmba |
add eax,0x10 |
cmp cx,[eax] |
jnz bnewba |
pusha |
mov ecx,ebx |
inc ecx |
shl ecx,4 |
mov ebx,eax |
add eax,0x10 |
call memmove |
dec dword [edi] |
popa |
jmp bnewba2 |
bnmba: |
pusha ; save window coordinates for window restoring |
cld |
shl esi,5 |
add esi,window_data |
mov eax,[esi+WDATA.box.left] |
mov [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, [SLOT_BASE+edi*8+APPDATA.debugger_slot] |
test eax, eax |
jz .nodebug |
push 8 |
pop ecx |
push dword [CURRENT_TASK+edi+TASKDATA.pid] ; PID |
push 2 |
call debugger_notify |
pop ecx |
pop ecx |
.nodebug: |
popad |
mov ebx, [.slot] |
shl ebx, 8 |
push ebx |
mov ebx,[SLOT_BASE+ebx+APPDATA.pl0_stack] |
stdcall kernel_free, ebx |
pop ebx |
mov ebx,[SLOT_BASE+ebx+APPDATA.cur_dir] |
stdcall kernel_free, ebx |
mov edi, [.slot] |
shl edi,8 |
add edi,SLOT_BASE |
mov eax, [edi+APPDATA.io_map] |
cmp eax, (tss._io_map_0-OS_BASE+PG_MAP) |
je @F |
call free_page |
@@: |
mov eax, [edi+APPDATA.io_map+4] |
cmp eax, (tss._io_map_1-OS_BASE+PG_MAP) |
je @F |
call free_page |
@@: |
mov eax, 0x20202020 |
stosd |
stosd |
stosd |
mov ecx,244/4 |
xor eax, eax |
rep stosd |
; activate window |
movzx eax, word [WIN_STACK + esi*2] |
cmp eax, [TASK_COUNT] |
jne .dont_activate |
pushad |
.check_next_window: |
dec eax |
cmp eax, 1 |
jbe .nothing_to_activate |
lea esi, [WIN_POS+eax*2] |
movzx edi, word [esi] ; edi = process |
shl edi, 5 |
cmp [CURRENT_TASK + edi + TASKDATA.state], byte 9 ; skip dead slots |
je .check_next_window |
add edi, window_data |
; \begin{diamond}[19.09.2006] |
; skip minimized windows |
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED |
jnz .check_next_window |
; \end{diamond} |
call waredraw |
.nothing_to_activate: |
popad |
.dont_activate: |
push esi ; remove hd1 & cd & flp reservation |
shl esi, 5 |
mov esi, [esi+CURRENT_TASK+TASKDATA.pid] |
cmp [hd1_status], esi |
jnz @f |
call free_hd_channel |
mov [hd1_status], 0 |
@@: |
cmp [cd_status], esi |
jnz @f |
call free_cd_channel |
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+CURRENT_TASK+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,CURRENT_TASK |
mov edx,[edx+TASKDATA.pid] |
rmpr0: |
mov esi,[RESERVED_PORTS] |
cmp esi,0 |
je rmpr9 |
rmpr3: |
mov edi,esi |
shl edi,4 |
add edi,RESERVED_PORTS |
cmp edx,[edi] |
je rmpr4 |
dec esi |
jnz rmpr3 |
jmp rmpr9 |
rmpr4: |
mov ecx,256 |
sub ecx,esi |
shl ecx,4 |
mov esi,edi |
add esi,16 |
cld |
rep movsb |
dec dword [RESERVED_PORTS] |
jmp rmpr0 |
rmpr9: |
popa |
mov edi,esi ; do not run this process slot |
shl edi, 5 |
mov [edi+CURRENT_TASK + TASKDATA.state],byte 9 |
; debugger test - terminate all debuggees |
mov eax, 2 |
mov ecx, SLOT_BASE+2*0x100+APPDATA.debugger_slot |
.xd0: |
cmp eax, [TASK_COUNT] |
ja .xd1 |
cmp dword [ecx], esi |
jnz @f |
and dword [ecx], 0 |
pushad |
xchg eax, 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 [MOUSE_BACKGROUND],byte 0 ; no mouse background |
mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse |
mov [application_table_status],0 |
;mov esi,process_terminated |
;call sys_msg_board_str |
DEBUGF 1,"%s",process_terminated |
add esp, 4 |
ret |
restore .slot |
iglobal |
boot_sched_1 db 'Building gdt tss pointer',0 |
boot_sched_2 db 'Building IDT table',0 |
endg |
build_scheduler: |
mov esi,boot_sched_1 |
call boot_log |
; call build_process_gdt_tss_pointer |
; mov esi,boot_sched_2 |
; call boot_log |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/syscall.inc |
---|
0,0 → 1,218 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SYSTEM CALL ENTRY ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 16 |
i40: |
; diamond, 27.03.2007: handler does not require disabled interrupts |
; so interrupts remain enabled when calling int 0x40 |
pushad |
cld |
; mov ax, word app_data |
; mov ds, ax |
; mov es, ax |
; load all registers in crossed order |
mov eax, ebx |
mov ebx, ecx |
mov ecx, edx |
mov edx, esi |
mov esi, edi |
mov edi, [esp+28] |
; 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 |
popad |
iretd |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SYSENTER ENTRY ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 32 |
sysenter_entry: |
; Íàñòðàèâàåì ñòåê |
mov esp, [ss:tss._esp0] |
sti |
push ebp ; save app esp + 4 |
mov ebp, [ebp] ; ebp - original ebp |
;------------------ |
pushad |
cld |
mov eax, ebx |
mov ebx, ecx |
mov ecx, edx |
mov edx, esi |
mov esi, edi |
mov edi, [esp + 28] |
push eax |
and edi, 0xff |
call dword [servetable + edi * 4] |
pop eax |
popad |
;------------------ |
xchg ecx, [ss:esp] ; â âåðøèí ñòåêà - app ecx, ecx - app esp + 4 |
sub ecx, 4 |
xchg edx, [ecx] ; edx - return point, & save original edx |
push edx |
mov edx, [ss:esp + 4] |
mov [ecx + 4], edx ; save original ecx |
pop edx |
sysexit |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SYSCALL ENTRY ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 32 |
syscall_entry: |
; cli syscall clear IF |
xchg esp, [ss:tss._esp0] |
push ecx |
lea ecx, [esp+4] |
xchg ecx, [ss:tss._esp0] |
sti |
push ecx |
mov ecx, [ecx] |
; mov [ss:sysenter_stack - 4], eax |
; mov eax, [ss:CURRENT_TASK] |
; shl eax, 8 |
; mov eax, [ss:SLOT_BASE + eax + APPDATA.pl0_stack] |
; lea esp, [eax + RING0_STACK_SIZE] ; configure ESP |
; mov eax, [ss:sysenter_stack - 4] ; eax - original eax, from app |
;------------------ |
pushad |
cld |
; mov ax, word app_data |
; mov ds, ax |
; mov es, ax |
mov eax, ebx |
mov ebx, ecx |
mov ecx, edx |
mov edx, esi |
mov esi, edi |
mov edi, [esp + 28] |
push eax |
and edi, 0xff |
call dword [servetable + edi * 4] |
pop eax |
popad |
;------------------ |
mov ecx, [ss:esp+4] |
pop esp |
sysret |
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 paleholder;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 undefined_syscall ; 27-reserved |
dd sys_sb16II ; 28-SetSb16 |
dd sys_date ; 29-GetDate |
dd sys_current_directory ; 30-Get/SetCurrentDirectory |
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 undefined_syscall ; 59-reserved |
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 syscall_putimage_palette; 65-PutImagePalette |
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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/exports.inc |
---|
0,0 → 1,143 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
szKernel db 'KERNEL', 0 |
szVersion db 'version',0 |
szRegService db 'RegService',0 |
szGetService db 'GetService',0 |
szServiceHandler db 'ServiceHandler',0 |
szAttachIntHandler db 'AttachIntHandler',0 |
szFpuSave db 'FpuSave',0 |
szFpuRestore db 'FpuRestore',0 |
szPciApi db 'PciApi', 0 |
szPciRead32 db 'PciRead32', 0 |
szPciRead8 db 'PciRead8', 0 |
szPciWrite8 db 'PciWrite8',0 |
szAllocPage db 'AllocPage',0 |
szAllocPages db 'AllocPages',0 |
szFreePage db 'FreePage',0 |
szGetPgAddr db 'GetPgAddr',0 |
szMapPage db 'MapPage',0 |
szMapSpace db 'MapSpace',0 |
szCommitPages db 'CommitPages',0 |
szReleasePages db 'ReleasePages',0 |
szAllocKernelSpace db 'AllocKernelSpace',0 |
szFreeKernelSpace db 'FreeKernelSpace',0 |
szKernelAlloc db 'KernelAlloc',0 |
szKernelFree db 'KernelFree',0 |
szUserAlloc db 'UserAlloc',0 |
szUserFree db 'UserFree',0 |
szKmalloc db 'Kmalloc',0 |
szKfree db 'Kfree',0 |
szCreateRingBuffer db 'CreateRingBuffer',0 |
szGetPid db 'GetPid',0 |
szCreateObject db 'CreateObject',0 |
szDestroyObject db 'DestroyObject',0 |
szCreateEvent db 'CreateEvent',0 |
szRaiseEvent db 'RaiseEvent',0 |
szWaitEvent db 'WaitEvent',0 |
szDestroyEvent db 'DestroyEvent',0 |
szClearEvent db 'ClearEvent',0 |
szLoadCursor db 'LoadCursor',0 |
szSetHwCursor db 'SetHwCursor',0 |
szHwCursorRestore db 'HwCursorRestore', 0 |
szHwCursorCreate db 'HwCursorCreate', 0 |
szSysMsgBoardStr db 'SysMsgBoardStr', 0 |
szGetCurrentTask db 'GetCurrentTask',0 |
szLFBAddress db 'LFBAddress',0 |
szLoadFile db 'LoadFile',0 |
szSendEvent db 'SendEvent',0 |
szSetMouseData db 'SetMouseData',0 |
szSleep db 'Sleep',0 |
szGetTimerTicks db 'GetTimerTicks',0 |
szStrncat db 'strncat',0 |
szStrncpy db 'strncpy',0 |
szstrncmp db 'strncmp',0 |
szStrnlen db 'strnlen',0 |
szStrchr db 'strchr',0 |
szStrrchr db 'strrchr',0 |
align 16 |
kernel_export: |
dd szRegService , reg_service |
dd szGetService , get_service |
dd szServiceHandler , srv_handler |
dd szAttachIntHandler, attach_int_handler |
dd szFpuSave , fpu_save |
dd szFpuRestore , fpu_restore |
dd szPciApi , pci_api |
dd szPciRead32 , pci_read32 |
dd szPciRead8 , pci_read8 |
dd szPciWrite8 , pci_write8 |
dd szAllocPage , alloc_page |
dd szAllocPages , alloc_pages |
dd szFreePage , free_page |
dd szMapPage , map_page |
dd szMapSpace , map_space |
dd szGetPgAddr , get_pg_addr |
dd szCommitPages , commit_pages ;not implemented |
dd szReleasePages , release_pages |
dd szAllocKernelSpace, alloc_kernel_space |
dd szFreeKernelSpace , free_kernel_space |
dd szKernelAlloc , kernel_alloc |
dd szKernelFree , kernel_free |
dd szUserAlloc , user_alloc |
dd szUserFree , user_free |
dd szKmalloc , malloc |
dd szKfree , free |
dd szCreateRingBuffer, create_ring_buffer |
dd szGetPid , get_pid |
dd szCreateObject , create_kernel_object |
dd szDestroyObject , destroy_kernel_object |
dd szCreateEvent , create_event |
dd szRaiseEvent , raise_event |
dd szWaitEvent , wait_event |
dd szDestroyEvent , destroy_event |
dd szClearEvent , clear_event |
dd szLoadCursor , load_cursor |
dd szSetHwCursor , set_hw_cursor |
dd szHwCursorRestore , hw_restore |
dd szHwCursorCreate , create_cursor |
dd szSysMsgBoardStr , sys_msg_board_str |
dd szGetCurrentTask , get_curr_task |
dd szLoadFile , load_file |
dd szSendEvent , send_event |
dd szSetMouseData , set_mouse_data |
dd szSleep , delay_ms |
dd szGetTimerTicks , get_timer_ticks |
dd szStrncat , strncat |
dd szStrncpy , strncpy |
dd szstrncmp , strncmp |
dd szStrnlen , strnlen |
dd szStrchr , strchr |
dd szStrrchr , strrchr |
exp_lfb: |
dd szLFBAddress , 0 |
dd 0 ;terminator, must be zero |
endg |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/string.inc |
---|
0,0 → 1,187 |
$Revision: 431 $ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; Author: Kees J. Bot 1 Jan 1994 ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; size_t strncat(char *s1, const char *s2, size_t n) |
; Append string s2 to s1. |
; char *strchr(const char *s, int c) |
; int strncmp(const char *s1, const char *s2, size_t n) |
; Compare two strings. |
; char *strncpy(char *s1, const char *s2, size_t n) |
; Copy string s2 to s1. |
; size_t strnlen(const char *s, size_t n) |
; Return the length of a string. |
; proc strrchr stdcall, s:dword, c:dword |
; Look for the last occurrence a character in a string. |
proc strncat stdcall, s1:dword, s2:dword, n:dword |
push esi |
push edi |
mov edi, [s1] ; String s1 |
mov edx, [n] ; Maximum length |
mov ecx, -1 |
xor al, al ; Null byte |
cld |
repne scasb ; Look for the zero byte in s1 |
dec edi ; Back one up (and clear 'Z' flag) |
push edi ; Save end of s1 |
mov edi, [s2] ; edi = string s2 |
mov ecx, edx ; Maximum count |
repne scasb ; Look for the end of s2 |
jne @F |
inc ecx ; Exclude null byte |
@@: |
sub edx, ecx ; Number of bytes in s2 |
mov ecx, edx |
mov esi, [s2] ; esi = string s2 |
pop edi ; edi = end of string s1 |
rep movsb ; Copy bytes |
stosb ; Add a terminating null |
mov eax, [s1] ; Return s1 |
pop edi |
pop esi |
ret |
endp |
align 4 |
proc strncmp stdcall, s1:dword, s2:dword, n:dword |
push esi |
push edi |
mov ecx, [n] |
test ecx, ecx ; Max length is zero? |
je .done |
mov esi, [s1] ; esi = string s1 |
mov edi, [s2] ; edi = string s2 |
cld |
.compare: |
cmpsb ; Compare two bytes |
jne .done |
cmp byte [esi-1], 0 ; End of string? |
je .done |
dec ecx ; Length limit reached? |
jne .compare |
.done: |
seta al ; al = (s1 > s2) |
setb ah ; ah = (s1 < s2) |
sub al, ah |
movsx eax, al ; eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 |
pop edi |
pop esi |
ret |
endp |
align 4 |
proc strncpy stdcall, s1:dword, s2:dword, n:dword |
push esi |
push edi |
mov ecx, [n] ; Maximum length |
mov edi, [s2] ; edi = string s2 |
xor al, al ; Look for a zero byte |
mov edx, ecx ; Save maximum count |
cld |
repne scasb ; Look for end of s2 |
sub edx, ecx ; Number of bytes in s2 including null |
xchg ecx, edx |
mov esi, [s2] ; esi = string s2 |
mov edi, [s1] ; edi = string s1 |
rep movsb ; Copy bytes |
mov ecx, edx ; Number of bytes not copied |
rep stosb ; strncpy always copies n bytes by null padding |
mov eax, [s1] ; Return s1 |
pop edi |
pop esi |
ret |
endp |
align 4 |
proc strnlen stdcall, s:dword, n:dword |
push edi |
mov edi, [s] ; edi = string |
xor al, al ; Look for a zero byte |
mov edx, ecx ; Save maximum count |
cmp cl, 1 ; 'Z' bit must be clear if ecx = 0 |
cld |
repne scasb ; Look for zero |
jne @F |
inc ecx ; Don't count zero byte |
@@: |
mov eax, edx |
sub eax, ecx ; Compute bytes scanned |
pop edi |
ret |
endp |
align 4 |
proc strchr stdcall, s:dword, c:dword |
push edi |
cld |
mov edi, [s] ; edi = string |
mov edx, 16 ; Look at small chunks of the string |
.next: |
shl edx, 1 ; Chunks become bigger each time |
mov ecx, edx |
xor al, al ; Look for the zero at the end |
repne scasb |
pushf ; Remember the flags |
sub ecx, edx |
neg ecx ; Some or all of the chunk |
sub edi, ecx ; Step back |
mov eax, [c] ; The character to look for |
repne scasb |
je .found |
popf ; Did we find the end of string earlier? |
jne .next ; No, try again |
xor eax, eax ; Return NULL |
pop edi |
ret |
.found: |
pop eax ; Get rid of those flags |
lea eax, [edi-1] ; Address of byte found |
pop edi |
ret |
endp |
proc strrchr stdcall, s:dword, c:dword |
push edi |
mov edi, [s] ; edi = string |
mov ecx, -1 |
xor al, al |
cld |
repne scasb ; Look for the end of the string |
not ecx ; -1 - ecx = Length of the string + null |
dec edi ; Put edi back on the zero byte |
mov eax, [c] ; The character to look for |
std ; Downwards search |
repne scasb |
cld ; Direction bit back to default |
jne .fail |
lea eax, [edi+1] ; Found it |
pop edi |
ret |
.fail: |
xor eax, eax ; Not there |
pop edi |
ret |
endp |
/kernel/tags/kolibri0.7.0.0/core/debug.inc |
---|
0,0 → 1,465 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; 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, [current_slot] |
mov [eax+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, [CURRENT_TASK] |
cmp [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx |
pop ebx |
jnz .ret_bad |
; clc ; automatically |
ret |
.ret_bad: |
stc |
ret |
debug_detach: |
; in: ebx=pid |
; destroys eax,ebx |
call get_debuggee_slot |
jc .ret |
and dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0 |
call do_resume |
.ret: |
sti |
ret |
debug_terminate: |
; in: 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, [CURRENT_TASK+eax+TASKDATA.state] ; process state |
test bl, bl |
jz .1 |
cmp bl, 5 |
jnz .ret |
mov bl, 2 |
.2: mov [CURRENT_TASK+eax+TASKDATA.state], bl |
.ret: |
sti |
ret |
.1: |
inc ebx |
jmp .2 |
do_resume: |
mov bl, [CURRENT_TASK+eax+TASKDATA.state] |
cmp bl, 1 |
jz .1 |
cmp bl, 2 |
jnz .ret |
mov bl, 5 |
.2: mov [CURRENT_TASK+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 |
push ebx |
mov ebx, edx |
call check_region |
pop ebx |
dec eax |
jnz .ret |
call get_debuggee_slot |
jc .ret |
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack] |
lea esi, [eax+RING0_STACK_SIZE] |
mov edi, edx |
.ring0: |
; note that following code assumes that all interrupt/exception handlers |
; saves ring-3 context by pushad in this order |
; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), pushad |
sub esi, 8+12+20h |
lodsd ;edi |
mov [edi+24h], eax |
lodsd ;esi |
mov [edi+20h], eax |
lodsd ; ebp |
mov [edi+1Ch], eax |
lodsd ;esp |
lodsd ;ebx |
mov [edi+14h], eax |
lodsd ;edx |
mov [edi+10h], eax |
lodsd ;ecx |
mov [edi+0Ch], eax |
lodsd ;eax |
mov [edi+8], eax |
lodsd ;eip |
mov [edi], eax |
lodsd ;cs |
lodsd ;eflags |
mov [edi+4], eax |
lodsd ;esp |
mov [edi+18h], eax |
.ret: |
sti |
ret |
debug_setcontext: |
; in: |
; ebx=pid |
; ecx=sizeof(CONTEXT) |
; edx->CONTEXT |
; destroys eax,ecx,edx,esi,edi |
cmp ecx, 28h |
jnz .ret |
push ebx |
mov ebx, edx |
call check_region |
pop ebx |
dec eax |
jnz .ret |
call get_debuggee_slot |
jc .stiret |
mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack] |
lea edi, [eax+RING0_STACK_SIZE] |
mov esi, edx |
.ring0: |
sub edi, 8+12+20h |
mov eax, [esi+24h] ;edi |
stosd |
mov eax, [esi+20h] ;esi |
stosd |
mov eax, [esi+1Ch] ;ebp |
stosd |
scasd |
mov eax, [esi+14h] ;ebx |
stosd |
mov eax, [esi+10h] ;edx |
stosd |
mov eax, [esi+0Ch] ;ecx |
stosd |
mov eax, [esi+8] ;eax |
stosd |
mov eax, [esi] ;eip |
stosd |
scasd |
mov eax, [esi+4] ;eflags |
stosd |
mov eax, [esi+18h] ;esp |
stosd |
.stiret: |
sti |
.ret: |
ret |
debug_set_drx: |
call get_debuggee_slot |
jc .errret |
mov ebp, eax |
lea eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs] |
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3 |
; [eax+10]=dr7 |
cmp edx, OS_BASE |
jae .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 + TSS._trap], not 1 |
and [ebp*8 + SLOT_BASE+APPDATA.dbg_state], 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 + TSS._trap], 1 |
or [ebp*8 + SLOT_BASE+APPDATA.dbg_state], 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 |
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 |
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, [SLOT_BASE+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 [CURRENT_TASK], 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 [SLOT_BASE+eax+APPDATA.event_mask+1], 1 ; set flag 100h |
.ret: |
ret |
debug_exc: |
; int 1 = #DB |
save_ring3_context |
cld |
mov ax, app_data ;os_data |
mov ds, ax |
mov es, ax |
mov eax, dr6 |
push eax |
xor eax, eax |
mov dr6, eax |
; test if debugging |
cli |
mov eax, [current_slot] |
mov eax, [eax+APPDATA.debugger_slot] |
test eax, eax |
jnz .debug |
sti |
; not debuggee => say error and terminate |
add esp, 0x20+4 |
mov [error_interrupt], 1 |
call show_error_parameters |
mov edx, [TASK_BASE] |
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, [TASK_BASE] |
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, [TASK_BASE] |
mov byte [edx+TASKDATA.state], 1 ; suspended |
call change_task |
restore_ring3_context |
iretd |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/fpu.inc |
---|
0,0 → 1,282 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
init_fpu: |
clts |
fninit |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
mov ebx, cr4 |
mov ecx, cr0 |
or ebx, CR4_OSFXSR+CR4_OSXMMEXPT |
mov cr4, ebx |
and ecx, not (CR0_MP+CR0_EM) |
or ecx, CR0_NE |
mov cr0, ecx |
mov dword [esp-4], SSE_INIT |
ldmxcsr [esp-4] |
xorps xmm0, xmm0 |
xorps xmm1, xmm1 |
xorps xmm2, xmm2 |
xorps xmm3, xmm3 |
xorps xmm4, xmm4 |
xorps xmm5, xmm5 |
xorps xmm6, xmm6 |
xorps xmm7, xmm7 |
fxsave [fpu_data] ;[eax] |
ret |
.no_SSE: |
mov ecx, cr0 |
and ecx, not CR0_EM |
or ecx, CR0_MP+CR0_NE |
mov cr0, ecx |
fnsave [fpu_data] |
ret |
; param |
; eax= 512 bytes memory area |
align 4 |
fpu_save: |
push ecx |
push esi |
push edi |
pushfd |
cli |
clts |
mov edi, eax |
mov ecx, [fpu_owner] |
mov esi, [CURRENT_TASK] |
cmp ecx, esi |
jne .save |
call save_context |
jmp .exit |
.save: |
mov [fpu_owner], esi |
shl ecx, 8 |
mov eax, [ecx+SLOT_BASE+APPDATA.fpu_state] |
call save_context |
shl esi, 8 |
mov esi, [esi+SLOT_BASE+APPDATA.fpu_state] |
mov ecx, 512/4 |
cld |
rep movsd |
fninit |
.exit: |
popfd |
pop edi |
pop esi |
pop ecx |
ret |
align 4 |
save_context: |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
fxsave [eax] |
ret |
.no_SSE: |
fnsave [eax] |
ret |
align 4 |
fpu_restore: |
push ecx |
push esi |
mov esi, eax |
pushfd |
cli |
mov ecx, [fpu_owner] |
mov eax, [CURRENT_TASK] |
cmp ecx, eax |
jne .copy |
clts |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
fxrstor [esi] |
popfd |
pop esi |
pop ecx |
ret |
.no_SSE: |
fnclex ;fix possible problems |
frstor [esi] |
popfd |
pop esi |
pop ecx |
ret |
.copy: |
shl eax, 8 |
mov edi, [eax+SLOT_BASE+APPDATA.fpu_state] |
mov ecx, 512/4 |
cld |
rep movsd |
popfd |
pop esi |
pop ecx |
ret |
align 4 |
e7: ;#NM exception handler |
save_ring3_context |
clts |
mov ax, app_data ; |
mov ds, ax |
mov es, ax |
mov ebx, [fpu_owner] |
cmp ebx, [CURRENT_TASK] |
je .exit |
shl ebx, 8 |
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
fxsave [eax] |
mov ebx, [CURRENT_TASK] |
mov [fpu_owner], ebx |
shl ebx, 8 |
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] |
fxrstor [eax] |
.exit: |
restore_ring3_context |
iret |
.no_SSE: |
fnsave [eax] |
mov ebx, [CURRENT_TASK] |
mov [fpu_owner], ebx |
shl ebx, 8 |
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_state] |
frstor [eax] |
restore_ring3_context |
iret |
iglobal |
fpu_owner dd 1 |
endg |
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 |
align 4 |
except_16: ;fpu native exceptions handler |
push ebp |
mov ebp, esp |
push eax |
push ebx |
push ecx |
push edx |
mov ebx, [CURRENT_TASK] |
shl ebx, 8 |
mov eax, [ebx+SLOT_BASE+APPDATA.fpu_handler] |
test eax, eax |
jz .default |
mov ecx, [reg_eip] |
mov edx, [reg_esp] |
sub edx, 4 |
mov [edx], 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 |
align 4 |
except_19: ;sse exceptions handler |
push ebp |
mov ebp, esp |
push eax |
push ebx |
push ecx |
push edx |
mov ebx, [current_slot] |
mov eax, [ebx+APPDATA.sse_handler] |
test eax, eax |
jz .default |
mov ecx, [reg_eip] |
mov edx, [reg_esp] |
sub edx, 4 |
mov [edx], 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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/heap.inc |
---|
0,0 → 1,1074 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
struc MEM_BLOCK |
{ .next_block dd ? |
.prev_block dd ? ;+4 |
.list_fd dd ? ;+8 |
.list_bk dd ? ;+12 |
.base dd ? ;+16 |
.size dd ? ;+20 |
.flags dd ? ;+24 |
.handle dd ? ;+28 |
} |
MEM_LIST_OFFSET equ 8 |
FREE_BLOCK equ 4 |
USED_BLOCK equ 8 |
virtual at 0 |
MEM_BLOCK MEM_BLOCK |
end virtual |
MEM_BLOCK_SIZE equ 8*4 |
block_next equ MEM_BLOCK.next_block |
block_prev equ MEM_BLOCK.prev_block |
list_fd equ MEM_BLOCK.list_fd |
list_bk equ MEM_BLOCK.list_bk |
block_base equ MEM_BLOCK.base |
block_size equ MEM_BLOCK.size |
block_flags equ MEM_BLOCK.flags |
macro calc_index op |
{ shr op, 12 |
dec op |
cmp op, 63 |
jna @f |
mov op, 63 |
@@: |
} |
macro remove_from_list op |
{ mov edx, [op+list_fd] |
mov ecx, [op+list_bk] |
test edx, edx |
jz @f |
mov [edx+list_bk], ecx |
@@: |
test ecx, ecx |
jz @f |
mov [ecx+list_fd], edx |
@@: |
mov [op+list_fd],0 |
mov [op+list_bk],0 |
} |
macro remove_from_free op |
{ |
remove_from_list op |
mov eax, [op+block_size] |
calc_index eax |
cmp [mem_block_list+eax*4], op |
jne @f |
mov [mem_block_list+eax*4], edx |
@@: |
cmp [mem_block_list+eax*4], 0 |
jne @f |
btr [mem_block_mask], eax |
@@: |
} |
macro remove_from_used op |
{ |
mov edx, [op+list_fd] |
mov ecx, [op+list_bk] |
mov [edx+list_bk], ecx |
mov [ecx+list_fd], edx |
mov [op+list_fd], 0 |
mov [op+list_bk], 0 |
} |
align 4 |
proc init_kernel_heap |
mov ecx, 64/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 |
mov eax, mem_used.fd-MEM_LIST_OFFSET |
mov [mem_used.fd], eax |
mov [mem_used.bk], eax |
stdcall alloc_pages, dword 32 |
mov ecx, 32 |
mov edx, eax |
mov edi, HEAP_BASE |
.l1: |
stdcall map_page,edi,edx,PG_SW |
add edi, 0x1000 |
add edx, 0x1000 |
dec ecx |
jnz .l1 |
mov edi, HEAP_BASE |
mov ebx, HEAP_BASE+MEM_BLOCK_SIZE |
xor eax, eax |
mov [edi+block_next], ebx |
mov [edi+block_prev], eax |
mov [edi+list_fd], eax |
mov [edi+list_bk], eax |
mov [edi+block_base], HEAP_BASE |
mov [edi+block_size], 4096*MEM_BLOCK_SIZE |
mov [edi+block_flags], USED_BLOCK |
mov [ebx+block_next], eax |
mov [ebx+block_prev], eax |
mov [ebx+list_fd], eax |
mov [ebx+list_bk], eax |
mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE |
mov ecx, [MEM_AMOUNT] |
sub ecx, HEAP_BASE + 4096*MEM_BLOCK_SIZE |
mov [heap_size], ecx |
mov [heap_free], ecx |
mov [ebx+block_size], ecx |
mov [ebx+block_flags], FREE_BLOCK |
mov [mem_block_mask], eax |
mov [mem_block_mask+4],0x80000000 |
mov [mem_block_list+63*4], ebx |
mov byte [mem_block_map], 0xFC |
and [heap_mutex], 0 |
mov [heap_blocks], 4095 |
mov [free_blocks], 4095 |
ret |
endp |
; param |
; eax= required size |
; |
; retval |
; edi= memory block descriptor |
; ebx= descriptor index |
align 4 |
get_block: |
mov ecx, eax |
shr ecx, 12 |
dec ecx |
cmp ecx, 63 |
jle .get_index |
mov ecx, 63 |
.get_index: |
lea esi, [mem_block_mask] |
xor ebx, ebx |
or edx, -1 |
cmp ecx, 32 |
jb .bit_test |
sub ecx, 32 |
add ebx, 32 |
add esi, 4 |
.bit_test: |
shl edx, cl |
and edx, [esi] |
.find: |
bsf edi, edx |
jz .high_mask |
add ebx, edi |
mov edi, [mem_block_list+ebx*4] |
.check_size: |
cmp eax, [edi+block_size] |
ja .next |
ret |
.high_mask: |
add esi, 4 |
cmp esi, mem_block_mask+8 |
jae .err |
add ebx, 32 |
mov edx, [esi] |
jmp .find |
.next: |
mov edi, [edi+list_fd] |
test edi, edi |
jnz .check_size |
.err: |
xor edi, edi |
ret |
align 4 |
proc alloc_mem_block |
mov ebx, [mem_block_start] |
mov ecx, [mem_block_end] |
.l1: |
bsf eax,[ebx]; |
jnz found |
add ebx,4 |
cmp ebx, ecx |
jb .l1 |
xor eax,eax |
ret |
found: |
btr [ebx], eax |
mov [mem_block_start],ebx |
sub ebx, mem_block_map |
lea eax,[eax+ebx*8] |
shl eax, 5 |
add eax, [mem_block_arr] |
dec [free_blocks] |
ret |
endp |
proc free_mem_block |
mov dword [eax], 0 |
mov dword [eax+4], 0 |
mov dword [eax+8], 0 |
mov dword [eax+12], 0 |
mov dword [eax+16], 0 |
; mov dword [eax+20], 0 |
mov dword [eax+24], 0 |
mov dword [eax+28], 0 |
sub eax, [mem_block_arr] |
shr eax, 5 |
mov ebx, mem_block_map |
bts [ebx], eax |
inc [free_blocks] |
shr eax, 3 |
and eax, not 3 |
add eax, ebx |
cmp [mem_block_start], eax |
ja @f |
ret |
@@: |
mov [mem_block_start], eax |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc alloc_kernel_space stdcall, size:dword |
local block_ind:DWORD |
mov eax, [size] |
add eax, 4095 |
and eax, not 4095 |
mov [size], eax |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
cmp eax, [heap_free] |
ja .error |
call get_block ; eax |
test edi, edi |
jz .error |
cmp [edi+block_flags], FREE_BLOCK |
jne .error |
mov [block_ind], ebx ;index of allocated block |
mov eax, [edi+block_size] |
cmp eax, [size] |
je .m_eq_size |
call alloc_mem_block |
and eax, eax |
jz .error |
mov esi, eax ;esi - splitted block |
mov [esi+block_next], edi |
mov eax, [edi+block_prev] |
mov [esi+block_prev], eax |
mov [edi+block_prev], esi |
mov [esi+list_fd], 0 |
mov [esi+list_bk], 0 |
and eax, eax |
jz @f |
mov [eax+block_next], esi |
@@: |
mov ebx, [edi+block_base] |
mov [esi+block_base], ebx |
mov edx, [size] |
mov [esi+block_size], edx |
add [edi+block_base], edx |
sub [edi+block_size], edx |
mov eax, [edi+block_size] |
shr eax, 12 |
sub eax, 1 |
cmp eax, 63 |
jna @f |
mov eax, 63 |
@@: |
cmp eax, [block_ind] |
je .m_eq_ind |
remove_from_list edi |
mov ecx, [block_ind] |
mov [mem_block_list+ecx*4], edx |
test edx, edx |
jnz @f |
btr [mem_block_mask], ecx |
@@: |
mov edx, [mem_block_list+eax*4] |
mov [edi+list_fd], edx |
test edx, edx |
jz @f |
mov [edx+list_bk], edi |
@@: |
mov [mem_block_list+eax*4], edi |
bts [mem_block_mask], eax |
.m_eq_ind: |
mov ecx, mem_used.fd-MEM_LIST_OFFSET |
mov edx, [ecx+list_fd] |
mov [esi+list_fd], edx |
mov [esi+list_bk], ecx |
mov [ecx+list_fd], esi |
mov [edx+list_bk], esi |
mov [esi+block_flags], USED_BLOCK |
mov eax, [esi+block_base] |
mov ebx, [size] |
sub [heap_free], ebx |
and [heap_mutex], 0 |
ret |
.m_eq_size: |
remove_from_list edi |
mov [mem_block_list+ebx*4], edx |
and edx, edx |
jnz @f |
btr [mem_block_mask], ebx |
@@: |
mov ecx, mem_used.fd-MEM_LIST_OFFSET |
mov edx, [ecx+list_fd] |
mov [edi+list_fd], edx |
mov [edi+list_bk], ecx |
mov [ecx+list_fd], edi |
mov [edx+list_bk], edi |
mov [edi+block_flags], USED_BLOCK |
mov eax, [edi+block_base] |
mov ebx, [size] |
sub [heap_free], ebx |
and [heap_mutex], 0 |
ret |
.error: |
xor eax, eax |
mov [heap_mutex], eax |
ret |
endp |
align 4 |
proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
mov eax, [base] |
mov esi, [mem_used.fd] |
@@: |
cmp esi, mem_used.fd-MEM_LIST_OFFSET |
je .fail |
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_fd] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
mov eax, [esi+block_size] |
add [heap_free], eax |
mov edi, [esi+block_next] |
test edi, edi |
jz .prev |
cmp [edi+block_flags], FREE_BLOCK |
jne .prev |
remove_from_free edi |
mov edx, [edi+block_next] |
mov [esi+block_next], edx |
test edx, edx |
jz @f |
mov [edx+block_prev], esi |
@@: |
mov ecx, [edi+block_size] |
add [esi+block_size], ecx |
mov eax, edi |
call free_mem_block |
.prev: |
mov edi, [esi+block_prev] |
test edi, edi |
jz .insert |
cmp [edi+block_flags], FREE_BLOCK |
jne .insert |
remove_from_used esi |
mov edx, [esi+block_next] |
mov [edi+block_next], edx |
test edx, edx |
jz @f |
mov [edx+block_prev], edi |
@@: |
mov eax, esi |
call free_mem_block |
mov ecx, [edi+block_size] |
mov eax, [esi+block_size] |
add eax, ecx |
mov [edi+block_size], eax |
calc_index eax |
calc_index ecx |
cmp eax, ecx |
je .m_eq |
push ecx |
remove_from_list edi |
pop ecx |
cmp [mem_block_list+ecx*4], edi |
jne @f |
mov [mem_block_list+ecx*4], edx |
@@: |
cmp [mem_block_list+ecx*4], 0 |
jne @f |
btr [mem_block_mask], ecx |
@@: |
mov esi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], edi |
mov [edi+list_fd], esi |
test esi, esi |
jz @f |
mov [esi+list_bk], edi |
@@: |
bts [mem_block_mask], eax |
.m_eq: |
xor eax, eax |
mov [heap_mutex], eax |
dec eax |
ret |
.insert: |
remove_from_used esi |
mov eax, [esi+block_size] |
calc_index eax |
mov edi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], esi |
mov [esi+list_fd], edi |
test edi, edi |
jz @f |
mov [edi+list_bk], esi |
@@: |
bts [mem_block_mask], eax |
mov [esi+block_flags],FREE_BLOCK |
xor eax, eax |
mov [heap_mutex], eax |
dec eax |
ret |
.fail: |
xor eax, eax |
mov [heap_mutex], eax |
ret |
endp |
align 4 |
proc kernel_alloc stdcall, size:dword |
locals |
lin_addr dd ? |
pages_count dd ? |
endl |
mov eax, [size] |
add eax, 4095 |
and eax, not 4095; |
mov [size], eax |
and eax, eax |
jz .err |
mov ebx, eax |
shr ebx, 12 |
mov [pages_count], ebx |
stdcall alloc_kernel_space, eax |
test eax, eax |
jz .err |
mov [lin_addr], eax |
mov ecx, [pages_count] |
mov edx, eax |
mov ebx, ecx |
shr ecx, 3 |
jz .next |
and ebx, not 7 |
push ebx |
stdcall alloc_pages, ebx |
pop ecx ; yes ecx!!! |
and eax, eax |
jz .err |
mov edi, eax |
mov edx, [lin_addr] |
@@: |
stdcall map_page,edx,edi,dword PG_SW |
add edx, 0x1000 |
add edi, 0x1000 |
dec ecx |
jnz @B |
.next: |
mov ecx, [pages_count] |
and ecx, 7 |
jz .end |
@@: |
push ecx |
call alloc_page |
pop ecx |
test eax, eax |
jz .err |
stdcall map_page,edx,eax,dword PG_SW |
add edx, 0x1000 |
dec ecx |
jnz @B |
.end: |
mov eax, [lin_addr] |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc kernel_free stdcall, base:dword |
push ebx esi |
mov ebx, heap_mutex |
call wait_mutex ;ebx |
mov eax, [base] |
mov esi, [mem_used.fd] |
@@: |
cmp esi, mem_used.fd-MEM_LIST_OFFSET |
je .fail |
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_fd] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
and [heap_mutex], 0 |
push ecx |
mov ecx, [esi+block_size]; |
shr ecx, 12 |
call release_pages ;eax, ecx |
pop ecx |
stdcall free_kernel_space, [base] |
pop esi ebx |
ret |
.fail: |
and [heap_mutex], 0 |
pop esi ebx |
ret |
endp |
restore block_next |
restore block_prev |
restore block_list |
restore block_base |
restore block_size |
restore block_flags |
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; |
HEAP_TOP equ 0x5FC00000 |
align 4 |
proc init_heap |
mov ebx,[current_slot] |
mov eax, [ebx+APPDATA.heap_top] |
test eax, eax |
jz @F |
sub eax,[ebx+APPDATA.heap_base] |
sub eax, 4096 |
ret |
@@: |
mov esi, [ebx+APPDATA.mem_size] |
add esi, 4095 |
and esi, not 4095 |
mov [ebx+APPDATA.mem_size], esi |
mov eax, HEAP_TOP |
mov [ebx+APPDATA.heap_base], esi |
mov [ebx+APPDATA.heap_top], eax |
sub eax, esi |
; add esi, new_app_base |
shr esi, 10 |
mov ecx, eax |
sub eax, 4096 |
or ecx, FREE_BLOCK |
mov [page_tabs+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_slot] |
mov esi, dword [ebx+APPDATA.heap_base] ; heap_base |
mov edi, dword [ebx+APPDATA.heap_top] ; heap_top |
l_0: |
cmp esi, edi |
jae m_exit |
mov ebx, esi |
shr ebx, 12 |
mov eax, [page_tabs+ebx*4] |
test eax, FREE_BLOCK |
jz test_used |
and eax, 0xFFFFF000 |
cmp eax, ecx ;alloc_size |
jb m_next |
jz @f |
mov edx, esi |
add edx, ecx |
sub eax, ecx; |
or eax, FREE_BLOCK |
shr edx, 12 |
mov [page_tabs+edx*4], eax |
@@: |
or ecx, USED_BLOCK |
mov [page_tabs+ebx*4], ecx |
shr ecx, 12 |
dec ecx |
inc ebx |
@@: |
mov dword [page_tabs+ebx*4], 2 |
inc ebx |
dec ecx |
jnz @B |
mov edx, [current_slot] |
mov ebx, [alloc_size] |
add ebx, 0xFFF |
and ebx, not 0xFFF |
add ebx, [edx+APPDATA.mem_size] |
call update_mem_size |
mov eax, esi |
add eax, 4096 |
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 |
xor ebx, ebx |
sub esi, 4096 |
shr esi, 12 |
mov eax, [page_tabs+esi*4] |
test eax, USED_BLOCK |
jz .not_used |
and eax, not 4095 |
mov ecx, eax |
or eax, FREE_BLOCK |
mov [page_tabs+esi*4], eax |
inc esi |
sub ecx, 4096 |
shr ecx, 12 |
mov ebx, ecx |
.release: |
xor eax, eax |
xchg eax, [page_tabs+esi*4] |
test eax, 1 |
jz @F |
call free_page |
mov eax, esi |
shl eax, 12 |
invlpg [eax] |
@@: |
inc esi |
dec ecx |
jnz .release |
.not_used: |
mov edx, [current_slot] |
mov esi, dword [edx+APPDATA.heap_base] |
mov edi, dword [edx+APPDATA.heap_top] |
sub ebx, [edx+APPDATA.mem_size] |
neg ebx |
call update_mem_size |
call user_normalize |
ret |
.exit: |
xor eax, eax |
inc eax |
ret |
endp |
user_normalize: |
; in: esi=heap_base, edi=heap_top |
; out: eax=0 <=> OK |
; destroys: ebx,edx,esi,edi |
shr esi, 12 |
shr edi, 12 |
@@: |
mov eax, [page_tabs+esi*4] |
test 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, [page_tabs+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 [page_tabs+edx*4], 0 |
add eax, ebx |
and eax, not 4095 |
or eax, FREE_BLOCK |
mov [page_tabs+esi*4], eax |
jmp @B |
.exit: |
xor eax, eax |
inc eax |
ret |
.err: |
xor eax, eax |
ret |
user_realloc: |
; in: eax = pointer, ebx = new size |
; out: eax = new pointer or NULL |
test eax, eax |
jnz @f |
; realloc(NULL,sz) - same as malloc(sz) |
push ebx |
call user_alloc |
ret |
@@: |
push ecx edx |
lea ecx, [eax - 0x1000] |
shr ecx, 12 |
mov edx, [page_tabs+ecx*4] |
test edx, USED_BLOCK |
jnz @f |
; attempt to realloc invalid pointer |
.ret0: |
pop edx ecx |
xor eax, eax |
ret |
@@: |
add ebx, 0x1FFF |
shr edx, 12 |
shr ebx, 12 |
; edx = allocated size, ebx = new size |
add edx, ecx |
add ebx, ecx |
cmp edx, ebx |
jb .realloc_add |
; release part of allocated memory |
.loop: |
cmp edx, ebx |
jz .release_done |
dec edx |
xor eax, eax |
xchg eax, [page_tabs+edx*4] |
test al, 1 |
jz .loop |
call free_page |
mov eax, edx |
shl eax, 12 |
invlpg [eax] |
jmp .loop |
.release_done: |
sub ebx, ecx |
cmp ebx, 1 |
jnz .nofreeall |
mov eax, [page_tabs+ecx*4] |
and eax, not 0xFFF |
mov edx, [current_slot] |
mov ebx, [APPDATA.mem_size+edx] |
sub ebx, eax |
add ebx, 0x1000 |
or al, FREE_BLOCK |
mov [page_tabs+ecx*4], eax |
push esi edi |
mov esi, [APPDATA.heap_base+edx] |
mov edi, [APPDATA.heap_top+edx] |
call update_mem_size |
call user_normalize |
pop edi esi |
jmp .ret0 ; all freed |
.nofreeall: |
sub edx, ecx |
shl ebx, 12 |
or ebx, USED_BLOCK |
xchg [page_tabs+ecx*4], ebx |
shr ebx, 12 |
sub ebx, edx |
push ebx ecx edx |
mov edx, [current_slot] |
shl ebx, 12 |
sub ebx, [APPDATA.mem_size+edx] |
neg ebx |
call update_mem_size |
pop edx ecx ebx |
lea eax, [ecx+1] |
shl eax, 12 |
push eax |
add ecx, ebx |
add edx, ecx |
shl ebx, 12 |
jz .ret |
push esi |
mov esi, [current_slot] |
mov esi, [APPDATA.heap_top+esi] |
shr esi, 12 |
@@: |
cmp edx, esi |
jae .merge_done |
mov eax, [page_tabs+edx*4] |
test al, USED_BLOCK |
jz .merge_done |
and dword [page_tabs+edx*4], 0 |
and eax, not 0xFFF |
add ebx, eax |
add edx, eax |
jmp @b |
.merge_done: |
pop esi |
or ebx, FREE_BLOCK |
mov [page_tabs+ecx*4], ebx |
.ret: |
pop eax edx ecx |
ret |
.realloc_add: |
; get some additional memory |
mov eax, [current_slot] |
mov eax, [APPDATA.heap_top+eax] |
shr eax, 12 |
cmp edx, eax |
jae .cant_inplace |
mov eax, [page_tabs+edx*4] |
shr eax, 12 |
add eax, edx |
cmp eax, ebx |
jb .cant_inplace |
sub eax, ebx |
jz @f |
shl eax, 12 |
or al, FREE_BLOCK |
mov [page_tabs+ebx*4], eax |
@@: |
mov eax, ebx |
sub eax, ecx |
shl eax, 12 |
or al, USED_BLOCK |
mov [page_tabs+ecx*4], eax |
lea eax, [ecx+1] |
shl eax, 12 |
push eax |
push edi |
lea edi, [page_tabs+edx*4] |
mov eax, 2 |
sub ebx, edx |
mov ecx, ebx |
cld |
rep stosd |
pop edi |
mov edx, [current_slot] |
shl ebx, 12 |
add ebx, [APPDATA.mem_size+edx] |
call update_mem_size |
pop eax edx ecx |
ret |
.cant_inplace: |
push esi edi |
mov eax, [current_slot] |
mov esi, [APPDATA.heap_base+eax] |
mov edi, [APPDATA.heap_top+eax] |
shr esi, 12 |
shr edi, 12 |
sub ebx, ecx |
.find_place: |
cmp esi, edi |
jae .place_not_found |
mov eax, [page_tabs+esi*4] |
test al, FREE_BLOCK |
jz .next_place |
shr eax, 12 |
cmp eax, ebx |
jae .place_found |
add esi, eax |
jmp .find_place |
.next_place: |
shr eax, 12 |
add esi, eax |
jmp .find_place |
.place_not_found: |
pop edi esi |
jmp .ret0 |
.place_found: |
sub eax, ebx |
jz @f |
push esi |
add esi, eax |
shl eax, 12 |
or al, FREE_BLOCK |
mov [page_tabs+esi*4], eax |
pop esi |
@@: |
mov eax, ebx |
shl eax, 12 |
or al, USED_BLOCK |
mov [page_tabs+esi*4], eax |
inc esi |
mov eax, esi |
shl eax, 12 |
push eax |
mov eax, [page_tabs+ecx*4] |
and eax, not 0xFFF |
or al, FREE_BLOCK |
sub edx, ecx |
mov [page_tabs+ecx*4], eax |
inc ecx |
@@: |
xor eax, eax |
xchg eax, [page_tabs+ecx*4] |
mov [page_tabs+esi*4], eax |
mov eax, ecx |
shl eax, 12 |
invlpg [eax] |
inc ecx |
inc esi |
dec ebx |
dec edx |
jnz @b |
push ebx |
mov edx, [current_slot] |
shl ebx, 12 |
add ebx, [APPDATA.mem_size+edx] |
call update_mem_size |
pop ebx |
@@: |
mov dword [page_tabs+esi*4], 2 |
inc esi |
dec ebx |
jnz @b |
pop eax edi esi edx ecx |
ret |
if 0 |
align 4 |
proc alloc_dll |
pushf |
cli |
bsf eax, [dll_map] |
jnz .find |
popf |
xor eax, eax |
ret |
.find: |
btr [dll_map], eax |
popf |
shl eax, 5 |
add eax, dll_tab |
ret |
endp |
align 4 |
proc alloc_service |
pushf |
cli |
bsf eax, [srv_map] |
jnz .find |
popf |
xor eax, eax |
ret |
.find: |
btr [srv_map], eax |
popf |
shl eax,0x02 |
lea eax,[srv_tab+eax+eax*8] ;srv_tab+eax*36 |
ret |
endp |
end if |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/malloc.inc |
---|
0,0 → 1,1001 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; Small heap based on malloc/free/realloc written by Doug Lea |
; Version 2.8.3 Thu Sep 22 11:16:15 2005 Doug Lea (dl at gee) |
; Source ftp://gee.cs.oswego.edu/pub/misc/malloc.c |
; License http://creativecommons.org/licenses/publicdomain. |
; eax= size |
; temp |
; esi= nb |
; ebx= idx |
; |
malloc: |
push esi |
; nb = ((size+7)&~7)+8; |
mov esi, eax ;size |
add esi, 7 |
and esi, -8 |
add esi, 8 |
mov ebx, mst.mutex |
call wait_mutex ;ebx |
cmp esi, 256 |
jae .large |
mov ecx, esi |
shr ecx, 3 |
or eax, -1 |
shl eax, cl |
and eax, [mst.smallmap] |
jz .small |
push ebp |
push edi |
bsf eax, eax |
mov ebx, eax |
; psize= idx<<3; |
; B = &ms.smallbins[idx]; |
; p = B->fd; |
; F = p->fd; |
; rsize= psize-nb; |
lea ebp, [eax*8] ;ebp= psize |
shl eax, 4 |
lea edi, [mst.smallbins+eax] ;edi= B |
mov edx, [edi+8] ;edx= p |
mov eax, [edx+8] ;eax= F |
mov ecx, ebp |
sub ecx, esi ;ecx= rsize |
; if (B == F) |
cmp edi, eax |
jne @F |
btr [mst.smallmap], ebx |
@@: |
; B->fd = F; |
; F->bk = B; |
; if(rsize<16) |
cmp ecx, 16 |
mov [edi+8], eax |
mov [eax+12], edi |
jae .split |
; p->head = psize|PINUSE_BIT|CINUSE_BIT; |
; (p + psize)->head |= PINUSE_BIT; |
lea eax, [edx+8] |
or dword [edx+ebp+4], 1 |
or ebp, 3 |
mov [edx+4], ebp |
pop edi |
pop ebp |
.done: |
pop esi |
mov [mst.mutex], 0 |
ret |
.split: |
lea ebx, [edx+8] ;ebx=mem |
; r = chunk_plus_offset(p, nb); |
; p->head = nb|PINUSE_BIT|CINUSE_BIT; |
; r->head = rsize|PINUSE_BIT; |
lea eax, [edx+esi] ;eax= r |
or esi, 3 |
mov [edx+4], esi |
mov edx, ecx |
or edx, 1 |
mov [eax+4], edx |
; (r + rsize)->prev_foot = rsize; |
mov [eax+ecx], ecx |
; I = rsize>>3; |
shr ecx, 3 |
; ms.smallmap |= 1<< I; |
bts [mst.smallmap], ecx |
; B = &ms.smallbins[I]; |
shl ecx, 4 |
pop edi |
pop ebp |
add ecx, mst.smallbins ;ecx= B |
mov edx, [ecx+8] ; F = B->fd; |
mov [ecx+8], eax ; B->fd = r; |
mov [edx+12], eax ; F->bk = r; |
mov [eax+8], edx ; r->fd = F; |
mov [eax+12], ecx ; r->bk = B; |
mov eax, ebx |
pop esi |
ret |
.small: |
; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0) |
cmp [mst.treemap], 0 |
je .from_top |
mov eax, esi |
call malloc_small |
test eax, eax |
jz .from_top |
pop esi |
and [mst.mutex], 0 |
ret |
.large: |
; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0) |
cmp [mst.treemap], 0 |
je .from_top |
call malloc_large ;esi= nb |
test eax, eax |
jne .done |
.from_top: |
; if (nb < ms.topsize) |
mov eax, [mst.topsize] |
cmp esi, eax |
jae .fail |
; rsize = ms.topsize -= nb; |
; p = ms.top; |
mov ecx, [mst.top] |
sub eax, esi |
mov [mst.topsize], eax |
; r = ms.top = chunk_plus_offset(p, nb); |
; r->head = rsize | PINUSE_BIT; |
; p->head = nb |PINUSE_BIT|CINUSE_BIT; |
lea edx, [ecx+esi] |
or eax, 1 |
mov [mst.top], edx |
or esi, 3 |
mov [edx+4], eax |
mov [ecx+4], esi |
lea eax, [ecx+8] |
pop esi |
and [mst.mutex], 0 |
ret |
.fail: |
xor eax, eax |
pop esi |
and [mst.mutex], 0 |
ret |
; param |
; eax= mem |
align 4 |
free: |
push edi |
mov edi, eax |
add edi, -8 |
; if(p->head & CINUSE_BIT) |
test byte [edi+4], 2 |
je .fail |
mov ebx, mst.mutex |
call wait_mutex ;ebx |
; psize = p->head & (~3); |
mov eax, [edi+4] |
push esi |
mov esi, eax |
and esi, -4 |
; next = chunk_plus_offset(p, psize); |
; if(!(p->head & PINUSE_BIT)) |
test al, 1 |
lea ebx, [esi+edi] |
jne .next |
; prevsize = p->prev_foot; |
; prev=p - prevsize; |
; psize += prevsize; |
; p = prev; |
mov ecx, [edi] ;ecx= prevsize |
add esi, ecx ;esi= psize |
sub edi, ecx ;edi= p |
; if (prevsize < 256) |
cmp ecx, 256 |
jae .unlink_large |
mov eax, [edi+8] ;F = p->fd; |
mov edx, [edi+12] ;B = p->bk; |
; if (F == B) |
; ms.smallmap &= ~(1<< I); |
shr ecx, 3 |
cmp eax, edx |
jne @F |
and [mst.smallmap], ecx |
@@: |
mov [eax+12], edx ;F->bk = B; |
mov [edx+8], eax ;B->fd = F |
jmp .next |
.unlink_large: |
mov edx, edi |
call unlink_large_chunk |
.next: |
; if(next->head & PINUSE_BIT) |
mov eax, [ebx+4] |
test al, 1 |
jz .fail2 |
; if (! (next->head & CINUSE_BIT)) |
test al, 2 |
jnz .fix_next |
; if (next == ms.top) |
cmp ebx, [mst.top] |
jne @F |
; tsize = ms.topsize += psize; |
mov eax, [mst.topsize] |
add eax, esi |
mov [mst.topsize], eax |
; ms.top = p; |
; p->head = tsize | PINUSE_BIT; |
or eax, 1 |
mov [mst.top], edi |
mov [edi+4], eax |
.fail2: |
and [mst.mutex], 0 |
pop esi |
.fail: |
pop edi |
ret |
@@: |
; nsize = next->head & ~INUSE_BITS; |
and eax, -4 |
add esi, eax ;psize += nsize; |
; if (nsize < 256) |
cmp eax, 256 |
jae .unl_large |
mov edx, [ebx+8] ;F = next->fd |
mov ebx, [ebx+12] ;B = next->bk |
; if (F == B) |
cmp edx, ebx |
jne @F |
mov ecx, eax |
shr ecx, 3 |
btr [mst.smallmap], ecx |
@@: |
mov [edx+12], ebx ;F->bk = B |
; p->head = psize|PINUSE_BIT; |
mov ecx, esi |
mov [ebx+8], edx |
or ecx, 1 |
mov [edi+4], ecx |
; (p+psize)->prev_foot = psize; |
mov [esi+edi], esi |
; insert_chunk(p,psize); |
mov eax, esi |
pop esi |
mov ecx, edi |
pop edi |
jmp insert_chunk |
.unl_large: |
; unlink_large_chunk((tchunkptr)next); |
mov edx, ebx |
call unlink_large_chunk |
; p->head = psize|PINUSE_BIT; |
mov ecx, esi |
or ecx, 1 |
mov [edi+4], ecx |
; (p+psize)->prev_foot = psize; |
mov [esi+edi], esi |
; insert_chunk(p,psize); |
mov eax, esi |
pop esi |
mov ecx, edi |
pop edi |
jmp insert_chunk |
.fix_next: |
; (p+psize)->prev_foot = psize; |
; next->head &= ~PINUSE_BIT; |
; p->head = psize|PINUSE_BIT; |
and eax, -2 |
mov edx, esi |
mov [ebx+4], eax |
or edx, 1 |
mov [edi+4], edx |
; (p+psize)->prev_foot = psize; |
mov [esi+edi], esi |
; insert_chunk(p,psize); |
mov eax, esi |
pop esi |
mov ecx, edi |
pop edi |
jmp insert_chunk |
; param |
; ecx = chunk |
; eax = size |
align 4 |
insert_chunk: |
cmp eax, 256 |
push esi |
mov esi, ecx |
jae .large |
; I = S>>3; |
; ms.smallmap |= 1<< I; |
shr eax, 3 |
bts [mst.smallmap], eax |
; B = &ms.smallbins[I]; |
shl eax, 4 |
add eax, mst.smallbins |
mov edx, [eax+8] ;F = B->fd |
mov [eax+8], esi ;B->fd = P |
mov [edx+12], esi ;F->bk = P |
mov [esi+8], edx ;P->fd = F |
mov [esi+12], eax ;P->bk = B |
pop esi |
and [mst.mutex], 0 |
ret |
.large: |
mov ebx, eax |
call insert_large_chunk |
pop esi |
and [mst.mutex], 0 |
ret |
align 4 |
; param |
; esi= chunk |
; ebx= size |
align 4 |
insert_large_chunk: |
; I = compute_tree_index(S); |
mov edx, ebx |
shr edx, 8 |
bsr eax, edx |
lea ecx, [eax+7] |
mov edx, ebx |
shr edx, cl |
and edx, 1 |
lea ecx, [edx+eax*2] |
; X->index = I; |
mov dword [esi+28], ecx |
; X->child[0] = X->child[1] = 0; |
and dword [esi+20], 0 |
and dword [esi+16], 0 |
; H = &ms.treebins[I]; |
mov eax, ecx |
lea edx, [mst.treebins+eax*4] |
; if (!(ms.treemap & 1<<I)) |
bt [mst.treemap], ecx |
jc .tree |
; ms.treemap |= 1<<I; |
bts [mst.treemap], ecx |
; *H = X; |
mov dword [edx], esi |
jmp .done |
.tree: |
; T = *H; |
mov edx, [edx] |
; K = S << leftshift_for_tree_index(I); |
mov eax, ecx |
shr eax, 1 |
sub ecx, 31 |
mov edi, 37 |
sub edi, eax |
neg ecx |
sbb ecx, ecx |
and ecx, edi |
mov eax, ebx |
shl eax, cl ;eax= K |
jmp .loop |
.not_eq_size: |
; C = &(T->child[(K >> 31) & 1]); |
mov ecx, eax |
shr ecx, 31 |
lea ecx, [edx+ecx*4+16] |
; K <<= 1; |
; if (*C != 0) |
mov edi, [ecx] |
add eax, eax |
test edi, edi |
jz .insert_child |
; T = *C; |
mov edx, edi |
.loop: |
; for (;;) |
; if ((T->head & ~INUSE_BITS) != S) |
mov ecx, [edx+4] |
and ecx, not 3 |
cmp ecx, ebx |
jne .not_eq_size |
; F = T->fd; |
mov eax, [edx+8] |
; T->fd = F->bk = X; |
mov [eax+12], esi |
mov [edx+8], esi |
; X->fd = F; |
; X->bk = T; |
; X->parent = 0; |
and dword [esi+24], 0 |
mov [esi+8], eax |
mov [esi+12], edx |
ret |
.insert_child: |
; *C = X; |
mov [ecx], esi |
.done: |
; X->parent = T; |
mov [esi+24], edx |
; X->fd = X->bk = X; |
mov [esi+12], esi |
mov [esi+8], esi |
ret |
; param |
; edx= chunk |
align 4 |
unlink_large_chunk: |
mov eax, [edx+12] |
cmp eax, edx |
push edi |
mov edi, [edx+24] |
je @F |
mov ecx, [edx+8] ;F = X->fd |
mov [ecx+12], eax ;F->bk = R; |
mov [eax+8], ecx ;R->fd = F |
jmp .parent |
@@: |
mov eax, [edx+20] |
test eax, eax |
push esi |
lea esi, [edx+20] |
jne .loop |
mov eax, [edx+16] |
test eax, eax |
lea esi, [edx+16] |
je .l2 |
.loop: |
cmp dword [eax+20], 0 |
lea ecx, [eax+20] |
jne @F |
cmp dword [eax+16], 0 |
lea ecx, [eax+16] |
je .l1 |
@@: |
mov eax, [ecx] |
mov esi, ecx |
jmp .loop |
.l1: |
mov dword [esi], 0 |
.l2: |
pop esi |
.parent: |
test edi, edi |
je .done |
mov ecx, [edx+28] |
cmp edx, [mst.treebins+ecx*4] |
lea ecx, [mst.treebins+ecx*4] |
jne .l3 |
test eax, eax |
mov [ecx], eax |
jne .l5 |
mov ecx, [edx+28] |
btr [mst.treemap], ecx |
pop edi |
ret |
.l3: |
cmp [edi+16], edx |
jne @F |
mov [edi+16], eax |
jmp .l4 |
@@: |
mov [edi+20], eax |
.l4: |
test eax, eax |
je .done |
.l5: |
mov [eax+24], edi |
mov ecx, [edx+16] |
test ecx, ecx |
je .l6 |
mov [eax+16], ecx |
mov [ecx+24], eax |
.l6: |
mov edx, [edx+20] |
test edx, edx |
je .done |
mov [eax+20], edx |
mov [edx+24], eax |
.done: |
pop edi |
ret |
; param |
; esi= nb |
align 4 |
malloc_small: |
push ebp |
mov ebp, esi |
push edi |
bsf eax,[mst.treemap] |
mov ecx, [mst.treebins+eax*4] |
; rsize = (t->head & ~INUSE_BITS) - nb; |
mov edi, [ecx+4] |
and edi, -4 |
sub edi, esi |
.loop: |
mov ebx, ecx |
.loop_1: |
; while ((t = leftmost_child(t)) != 0) |
mov eax, [ecx+16] |
test eax, eax |
jz @F |
mov ecx, eax |
jmp .l1 |
@@: |
mov ecx, [ecx+20] |
.l1: |
test ecx, ecx |
jz .unlink |
; trem = (t->head & ~INUSE_BITS) - nb; |
mov eax, [ecx+4] |
and eax, -4 |
sub eax, ebp |
; if (trem < rsize) |
cmp eax, edi |
jae .loop_1 |
; rsize = trem; |
mov edi, eax |
jmp .loop |
.unlink: |
; r = chunk_plus_offset((mchunkptr)v, nb); |
; unlink_large_chunk(v); |
mov edx, ebx |
lea esi, [ebx+ebp] |
call unlink_large_chunk |
; if (rsize < 16) |
cmp edi, 16 |
jae .split |
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT; |
lea ecx, [edi+ebp] |
; (v+rsize + nb)->head |= PINUSE_BIT; |
add edi, ebx |
lea eax, [edi+ebp+4] |
pop edi |
or ecx, 3 |
mov [ebx+4], ecx |
or dword [eax], 1 |
pop ebp |
lea eax, [ebx+8] |
ret |
.split: |
; v->head = nb|PINUSE_BIT|CINUSE_BIT; |
; r->head = rsize|PINUSE_BIT; |
; (r+rsize)->prev_foot = rsize; |
or ebp, 3 |
mov edx, edi |
or edx, 1 |
cmp edi, 256 |
mov [ebx+4], ebp |
mov [esi+4], edx |
mov [esi+edi], edi |
jae .large |
shr edi, 3 |
bts [mst.smallmap], edi |
mov eax, edi |
shl eax, 4 |
add eax, mst.smallbins |
mov edx, [eax+8] |
mov [eax+8], esi |
mov [edx+12], esi |
pop edi |
mov [esi+12], eax |
mov [esi+8], edx |
pop ebp |
lea eax, [ebx+8] |
ret |
.large: |
lea eax, [ebx+8] |
push eax |
mov ebx, edi |
call insert_large_chunk |
pop eax |
pop edi |
pop ebp |
ret |
; param |
; esi= nb |
align 4 |
malloc_large: |
.idx equ esp+4 |
.rst equ esp |
push ebp |
push edi |
sub esp, 8 |
; v = 0; |
; rsize = -nb; |
mov edi, esi |
mov ebx, esi |
xor ebp, ebp |
neg edi |
; idx = compute_tree_index(nb); |
mov edx, esi |
shr edx, 8 |
bsr eax, edx |
lea ecx, [eax+7] |
shr esi, cl |
and esi, 1 |
lea ecx, [esi+eax*2] |
mov [.idx], ecx |
; if ((t = ms.treebins[idx]) != 0) |
mov eax, [mst.treebins+ecx*4] |
test eax, eax |
jz .l3 |
; sizebits = nb << leftshift_for_tree_index(idx); |
cmp ecx, 31 |
jne @F |
xor ecx, ecx |
jmp .l1 |
@@: |
mov edx, ecx |
shr edx, 1 |
mov ecx, 37 |
sub ecx, edx |
.l1: |
mov edx, ebx |
shl edx, cl |
; rst = 0; |
mov [.rst], ebp |
.loop: |
; trem = (t->head & ~INUSE_BITS) - nb; |
mov ecx, [eax+4] |
and ecx, -4 |
sub ecx, ebx |
; if (trem < rsize) |
cmp ecx, edi |
jae @F |
; v = t; |
; if ((rsize = trem) == 0) |
test ecx, ecx |
mov ebp, eax |
mov edi, ecx |
je .l2 |
@@: |
; rt = t->child[1]; |
mov ecx, [eax+20] |
; t = t->child[(sizebits >> 31) & 1]; |
mov esi, edx |
shr esi, 31 |
; if (rt != 0 && rt != t) |
test ecx, ecx |
mov eax, [eax+esi*4+16] |
jz @F |
cmp ecx, eax |
jz @F |
; rst = rt; |
mov [.rst], ecx |
@@: |
; if (t == 0) |
test eax, eax |
jz @F |
; sizebits <<= 1; |
add edx, edx |
jmp .loop |
@@: |
; t = rst; |
mov eax, [.rst] |
.l2: |
; if (t == 0 && v == 0) |
test eax, eax |
jne .l4 |
test ebp, ebp |
jne .l7 |
mov ecx, [.idx] |
.l3: |
; leftbits = (-1<<idx) & ms.treemap; |
; if (leftbits != 0) |
or edx, -1 |
shl edx, cl |
and edx, [mst.treemap] |
jz @F |
bsf eax, edx |
; t = ms.treebins[i]; |
mov eax, [mst.treebins+eax*4] |
@@: |
; while (t != 0) |
test eax, eax |
jz .l5 |
.l4: |
; trem = (t->head & ~INUSE_BITS) - nb; |
mov ecx, [eax+4] |
and ecx, -4 |
sub ecx, ebx |
; if (trem < rsize) |
cmp ecx, edi |
jae @F |
; rsize = trem; |
mov edi, ecx |
; v = t; |
mov ebp, eax |
@@: |
; t = leftmost_child(t); |
mov ecx, [eax+16] |
test ecx, ecx |
je @F |
mov eax, ecx |
jmp .l6 |
@@: |
mov eax, [eax+20] |
.l6: |
; while (t != 0) |
test eax, eax |
jne .l4 |
.l5: |
; if (v != 0) |
test ebp, ebp |
jz .done |
.l7: |
; r = chunk_plus_offset((mchunkptr)v, nb); |
; unlink_large_chunk(v); |
mov edx, ebp |
lea esi, [ebx+ebp] |
call unlink_large_chunk |
; if (rsize < 16) |
cmp edi, 16 |
jae .large |
; v->head = (rsize + nb)|PINUSE_BIT|CINUSE_BIT; |
lea ecx, [edi+ebx] |
; (v+rsize + nb)->head |= PINUSE_BIT; |
add edi, ebp |
lea eax, [edi+ebx+4] |
or ecx, 3 |
mov [ebp+4], ecx |
or dword [eax], 1 |
lea eax, [ebp+8] |
add esp, 8 |
pop edi |
pop ebp |
ret |
.large: |
; v->head = nb|PINUSE_BIT|CINUSE_BIT; |
; r->head = rsize|PINUSE_BIT; |
mov edx, edi |
or ebx, 3 |
mov [ebp+4], ebx |
or edx, 1 |
mov [esi+4], edx |
; (r+rsize)->prev_foot = rsize; |
; insert_large_chunk((tchunkptr)r, rsize); |
mov [esi+edi], edi |
mov eax, edi |
mov ecx, esi |
call insert_chunk |
lea eax, [ebp+8] |
add esp, 8 |
pop edi |
pop ebp |
ret |
.done: |
add esp, 8 |
pop edi |
pop ebp |
xor eax, eax |
ret |
align 4 |
init_malloc: |
stdcall kernel_alloc, 0x20000 |
mov [mst.top], eax |
mov [mst.topsize], 128*1024 |
mov dword [eax+4], (128*1024) or 1 |
mov eax, mst.smallbins |
@@: |
mov [eax+8], eax |
mov [eax+12], eax |
add eax, 16 |
cmp eax, mst.smallbins+512 |
jb @B |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/core/sync.inc |
---|
0,0 → 1,117 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; Synhronization for MenuetOS. ;; |
;; Author: Halyavin Andrey, halyavin@land.ru ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if ~defined sync_inc |
sync_inc_fix: |
sync_inc fix sync_inc_fix |
;simplest mutex. |
macro SimpleMutex name |
{ |
; iglobal |
name dd 0 |
name#.type = 1 |
; endg |
} |
macro WaitSimpleMutex name |
{ |
local start_wait,ok |
start_wait=$ |
cli |
cmp [name],dword 0 |
jz ok |
sti |
call change_task |
jmp start_wait |
ok=$ |
push eax |
mov eax,dword [TASK_BASE+second_base_address] |
mov eax,[eax+TASKDATA.pid] |
mov [name],eax |
pop eax |
sti |
} |
macro ReleaseSimpleMutex name |
{ |
mov [name],dword 0 |
} |
macro TryWaitSimpleMutex name ;result in eax and in flags |
{ |
local ok,try_end |
cmp [name],dword 0 |
jz ok |
xor eax,eax |
jmp try_end |
ok=$ |
xor eax,eax |
inc eax |
try_end=$ |
} |
macro SimpleCriticalSection name |
{ |
; iglobal |
name dd 0 |
dd 0 |
name#.type=2 |
; endg |
} |
macro WaitSimpleCriticalSection name |
{ |
local start_wait,first_wait,inc_counter,end_wait |
push eax |
mov eax,[TASK_BASE+second_base_address] |
mov eax,[eax+TASKDATA.pid] |
start_wait=$ |
cli |
cmp [name],dword 0 |
jz first_wait |
cmp [name],eax |
jz inc_counter |
sti |
call change_task |
jmp start_wait |
first_wait=$ |
mov [name],eax |
mov [name+4],dword 1 |
jmp end_wait |
inc_counter=$ |
inc dword [name+4] |
end_wait=$ |
sti |
pop eax |
} |
macro ReleaseSimpleCriticalSection name |
{ |
local release_end |
dec dword [name+4] |
jnz release_end |
mov [name],dword 0 |
release_end=$ |
} |
macro TryWaitSimpleCriticalSection name ;result in eax and in flags |
{ |
local ok,try_end |
mov eax,[CURRENT_TASK+second_base_address] |
mov eax,[eax+TASKDATA.pid] |
cmp [name],eax |
jz ok |
cmp [name],0 |
jz ok |
xor eax,eax |
jmp try_end |
ok=$ |
xor eax,eax |
inc eax |
try_end=$ |
} |
_cli equ call MEM_HeapLock |
_sti equ call MEM_HeapUnLock |
end if |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/fs/iso9660.inc |
---|
0,0 → 1,722 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
uglobal |
cd_current_pointer_of_input dd 0 |
cd_current_pointer_of_input_2 dd 0 |
cd_mem_location dd 0 |
cd_counter_block dd 0 |
IDE_Channel_1 db 0 |
IDE_Channel_2 db 0 |
endg |
reserve_cd: |
cli |
cmp [cd_status],0 |
je reserve_ok2 |
sti |
call change_task |
jmp reserve_cd |
reserve_ok2: |
push eax |
mov eax,[CURRENT_TASK] |
shl eax,5 |
mov eax,[eax+CURRENT_TASK+TASKDATA.pid] |
mov [cd_status],eax |
pop eax |
sti |
ret |
reserve_cd_channel: |
cmp [ChannelNumber],1 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
cli |
cmp [IDE_Channel_1],0 |
je .reserve_ok_1 |
sti |
call change_task |
jmp .IDE_Channel_1 |
.IDE_Channel_2: |
cli |
cmp [IDE_Channel_2],0 |
je .reserve_ok_2 |
sti |
call change_task |
jmp .IDE_Channel_1 |
.reserve_ok_1: |
mov [IDE_Channel_1],1 |
ret |
.reserve_ok_2: |
mov [IDE_Channel_2],1 |
ret |
free_cd_channel: |
cmp [ChannelNumber],1 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
mov [IDE_Channel_1],0 |
ret |
.IDE_Channel_2: |
mov [IDE_Channel_2],0 |
ret |
uglobal |
cd_status dd 0 |
endg |
;---------------------------------------------------------------- |
; |
; fs_CdRead - LFN variant for reading CD disk |
; |
; esi points to filename /dir1/dir2/.../dirn/file,0 |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_CdRead: |
push edi |
cmp byte [esi], 0 |
jnz @f |
.noaccess: |
pop edi |
.noaccess_2: |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.noaccess_3: |
pop eax edx ecx edi |
jmp .noaccess_2 |
@@: |
call cd_find_lfn |
jnc .found |
pop edi |
cmp [DevErrorCode],0 |
jne .noaccess_2 |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
mov edi,[cd_current_pointer_of_input] |
test byte [edi+25],10b ; do not allow read directories |
jnz .noaccess |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 ; end of file |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+10] ; ðåàëüíûé ðàçìåð ôàéëîâîé ñåêöèè |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 |
@@: |
mov eax,[edi+2] |
mov [CDSectorAddress],eax |
; now eax=cluster, ebx=position, ecx=count, edx=buffer for data |
.new_sector: |
test ecx, ecx |
jz .done |
sub ebx, 2048 |
jae .next |
add ebx, 2048 |
jnz .incomplete_sector |
cmp ecx, 2048 |
jb .incomplete_sector |
; we may read and memmove complete sector |
mov [CDDataBuf_pointer],edx |
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà |
cmp [DevErrorCode],0 |
jne .noaccess_3 |
add edx, 2048 |
sub ecx, 2048 |
.next: |
inc dword [CDSectorAddress] |
jmp .new_sector |
.incomplete_sector: |
; we must read and memmove incomplete sector |
mov [CDDataBuf_pointer],CDDataBuf |
call ReadCDWRetr ; ÷èòàåì ñåêòîð ôàéëà |
cmp [DevErrorCode],0 |
jne .noaccess_3 |
push ecx |
add ecx, ebx |
cmp ecx, 2048 |
jbe @f |
mov ecx, 2048 |
@@: |
sub ecx, ebx |
push edi esi ecx |
mov edi,edx |
lea esi, [CDDataBuf + ebx] |
cld |
rep movsb |
pop ecx esi edi |
add edx, ecx |
sub [esp], ecx |
pop ecx |
xor ebx, ebx |
jmp .next |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
.eof: |
mov ebx, edx |
pop eax edx ecx |
sub ebx, edx |
jmp .reteof |
;---------------------------------------------------------------- |
; |
; fs_CdReadFolder - LFN variant for reading CD disk folder |
; |
; esi points to filename /dir1/dir2/.../dirn/file,0 |
; ebx pointer to structure 32-bit number = first wanted block, 0+ |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = blocks read or 0xffffffff folder not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_CdReadFolder: |
push edi |
call cd_find_lfn |
jnc .found |
pop edi |
cmp [DevErrorCode], 0 |
jne .noaccess_1 |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
mov edi, [cd_current_pointer_of_input] |
test byte [edi+25], 10b ; do not allow read directories |
jnz .found_dir |
pop edi |
.noaccess_1: |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
mov eax, [edi+2] ; eax=cluster |
mov [CDSectorAddress], eax |
mov eax, [edi+10] ; ðàçìåð äèðåêòðîðèè |
.doit: |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
pop ecx eax |
mov byte [edx], 1 ; version |
mov [cd_mem_location], edx |
add [cd_mem_location], 32 |
; íà÷èíàåì ïåðåáðîñêó ÁÄÂÊ â ÓÑÂÊ |
;.mainloop: |
mov [cd_counter_block], dword 0 |
dec dword [CDSectorAddress] |
push ecx |
.read_to_buffer: |
inc dword [CDSectorAddress] |
mov [CDDataBuf_pointer], CDDataBuf |
call ReadCDWRetr ; ÷èòàåì ñåêòîð äèðåêòîðèè |
cmp [DevErrorCode], 0 |
jne .noaccess_1 |
call .get_names_from_buffer |
sub eax,2048 |
; äèðåêòîðèÿ çàêîí÷èëàñü? |
ja .read_to_buffer |
mov edi, [cd_counter_block] |
mov [edx+8], edi |
mov edi, [ebx] |
sub [edx+4], edi |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx edi |
mov ebx, [edx+4] |
ret |
.get_names_from_buffer: |
mov [cd_current_pointer_of_input_2],CDDataBuf |
push eax esi edi edx |
.get_names_from_buffer_1: |
call cd_get_name |
jc .end_buffer |
inc dword [cd_counter_block] |
mov eax,[cd_counter_block] |
cmp [ebx],eax |
jae .get_names_from_buffer_1 |
test ecx, ecx |
jz .get_names_from_buffer_1 |
mov edi,[cd_counter_block] |
mov [edx+4],edi |
dec ecx |
mov esi,ebp |
mov edi,[cd_mem_location] |
add edi,40 |
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE |
jnz .unicode |
; jmp .unicode |
.ansi: |
cmp [cd_counter_block],2 |
jbe .ansi_parent_directory |
cld |
lodsw |
xchg ah,al |
call uni2ansi_char |
cld |
stosb |
; ïðîâåðêà êîíöà ôàéëà |
mov ax,[esi] |
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';' |
je .cd_get_parameters_of_file_1 |
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì |
movzx eax,byte [ebp-33] |
add eax,ebp |
sub eax,34 |
cmp esi,eax |
je .cd_get_parameters_of_file_1 |
; ïðîâåðêà êîíöà ïàïêè |
movzx eax,byte [ebp-1] |
add eax,ebp |
cmp esi,eax |
jb .ansi |
.cd_get_parameters_of_file_1: |
mov [edi],byte 0 |
call cd_get_parameters_of_file |
add [cd_mem_location],304 |
jmp .get_names_from_buffer_1 |
.ansi_parent_directory: |
cmp [cd_counter_block],2 |
je @f |
mov [edi],byte '.' |
inc edi |
jmp .cd_get_parameters_of_file_1 |
@@: |
mov [edi],word '..' |
add edi,2 |
jmp .cd_get_parameters_of_file_1 |
.unicode: |
cmp [cd_counter_block],2 |
jbe .unicode_parent_directory |
cld |
movsw |
; ïðîâåðêà êîíöà ôàéëà |
mov ax,[esi] |
cmp ax,word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';' |
je .cd_get_parameters_of_file_2 |
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì |
movzx eax,byte [ebp-33] |
add eax,ebp |
sub eax,34 |
cmp esi,eax |
je .cd_get_parameters_of_file_2 |
; ïðîâåðêà êîíöà ïàïêè |
movzx eax,byte [ebp-1] |
add eax,ebp |
cmp esi,eax |
jb .unicode |
.cd_get_parameters_of_file_2: |
mov [edi],word 0 |
call cd_get_parameters_of_file |
add [cd_mem_location],560 |
jmp .get_names_from_buffer_1 |
.unicode_parent_directory: |
cmp [cd_counter_block],2 |
je @f |
mov [edi],word 2E00h ; '.' |
add edi,2 |
jmp .cd_get_parameters_of_file_2 |
@@: |
mov [edi],dword 2E002E00h ; '..' |
add edi,4 |
jmp .cd_get_parameters_of_file_2 |
.end_buffer: |
pop edx edi esi eax |
ret |
cd_get_parameters_of_file: |
mov edi,[cd_mem_location] |
cd_get_parameters_of_file_1: |
; ïîëó÷àåì àòðèáóòû ôàéëà |
xor eax,eax |
; ôàéë íå àðõèâèðîâàëñÿ |
inc eax |
shl eax,1 |
; ýòî êàòàëîã? |
test [ebp-8],byte 2 |
jz .file |
inc eax |
.file: |
; ìåòêà òîìà íå êàê â FAT, â ýòîì âèäå îòñóòñâóåò |
; ôàéë íå ÿâëÿåòñÿ ñèñòåìíûì |
shl eax,3 |
; ôàéë ÿâëÿåòñÿ ñêðûòûì? (àòðèáóò ñóùåñòâîâàíèå) |
test [ebp-8],byte 1 |
jz .hidden |
inc eax |
.hidden: |
shl eax,1 |
; ôàéë âñåãäà òîëüêî äëÿ ÷òåíèÿ, òàê êàê ýòî CD |
inc eax |
mov [edi],eax |
; ïîëó÷àåì âðåìÿ äëÿ ôàéëà |
;÷àñ |
movzx eax,byte [ebp-12] |
shl eax,8 |
;ìèíóòà |
mov al,[ebp-11] |
shl eax,8 |
;ñåêóíäà |
mov al,[ebp-10] |
;âðåìÿ ñîçäàíèÿ ôàéëà |
mov [edi+8],eax |
;âðåìÿ ïîñëåäíåãî äîñòóïà |
mov [edi+16],eax |
;âðåìÿ ïîñëåäíåé çàïèñè |
mov [edi+24],eax |
; ïîëó÷àåì äàòó äëÿ ôàéëà |
;ãîä |
movzx eax,byte [ebp-15] |
add eax,1900 |
shl eax,8 |
;ìåñÿö |
mov al,[ebp-14] |
shl eax,8 |
;äåíü |
mov al,[ebp-13] |
;äàòà ñîçäàíèÿ ôàéëà |
mov [edi+12],eax |
;âðåìÿ ïîñëåäíåãî äîñòóïà |
mov [edi+20],eax |
;âðåìÿ ïîñëåäíåé çàïèñè |
mov [edi+28],eax |
; ïîëó÷àåì òèï äàííûõ èìåíè |
xor eax,eax |
test dword [ebx+4], 1 ; 0=ANSI, 1=UNICODE |
jnz .unicode_1 |
mov [edi+4],eax |
jmp @f |
.unicode_1: |
inc eax |
mov [edi+4],eax |
@@: |
; ïîëó÷àåì ðàçìåð ôàéëà â áàéòàõ |
xor eax,eax |
mov [edi+32+4],eax |
mov eax,[ebp-23] |
mov [edi+32],eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_CdGetFileInfo - LFN variant for CD |
; get file/directory attributes structure |
; |
;---------------------------------------------------------------- |
fs_CdGetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 |
ret |
@@: |
push edi |
call cd_find_lfn |
pushfd |
cmp [DevErrorCode], 0 |
jz @f |
popfd |
pop edi |
mov eax, 11 |
ret |
@@: |
popfd |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
mov edi, edx |
push ebp |
mov ebp, [cd_current_pointer_of_input] |
add ebp, 33 |
call cd_get_parameters_of_file_1 |
pop ebp |
and dword [edi+4], 0 |
pop edi |
xor eax, eax |
ret |
cd_find_lfn: |
; in: esi+ebp -> 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 |
push ebp |
call cd_find_name_in_buffer |
pop ebp |
jnc .found |
sub eax,2048 |
; äèðåêòîðèÿ çàêîí÷èëàñü? |
cmp eax,0 |
ja .read_to_buffer |
; íåò èñêîìîãî ýëåìåíòà öåïî÷êè |
.access_denied: |
pop esi eax |
stc |
ret |
; èñêîìûé ýëåìåíò öåïî÷êè íàéäåí |
.found: |
; êîíåö ïóòè ôàéëà |
cmp byte [esi-1], 0 |
jz .done |
.nested: |
mov eax,[cd_current_pointer_of_input] |
push dword [eax+2] |
pop dword [CDSectorAddress] ; íà÷àëî äèðåêòîðèè |
mov eax,[eax+2+8] ; ðàçìåð äèðåêòîðèè |
jmp .mainloop |
; óêàçàòåëü ôàéëà íàéäåí |
.done: |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
jmp .nested |
@@: |
pop esi eax |
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 eax |
call char_todown |
call ansi2uni_char |
xchg ah,al |
scasw |
pop eax |
je .coincides |
call char_toupper |
call ansi2uni_char |
xchg ah,al |
sub edi,2 |
scasw |
jne .name_not_coincide |
.coincides: |
cmp [esi],byte '/' ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà |
je .done |
cmp [esi],byte 0 ; ðàçäåëèòåëü ïóòè, êîíåö èìåíè òåêóùåãî ýëåìåíòà |
je .done |
jmp .loop |
.name_not_coincide: |
pop edi eax esi |
stc |
ret |
.done: |
; ïðîâåðêà êîíöà ôàéëà |
cmp [edi],word 3B00h ; ñåïàðàòîð êîíöà ôàéëà ';' |
je .done_1 |
; ïðîâåðêà äëÿ ôàéëîâ íå çàêàí÷èâàþùèõñÿ ñåïàðàòîðîì |
movzx eax,byte [ebp-33] |
add eax,ebp |
sub eax,34 |
cmp edi,eax |
je .done_1 |
; ïðîâåðêà êîíöà ïàïêè |
movzx eax,byte [ebp-1] |
add eax,ebp |
cmp edi,eax |
jne .name_not_coincide |
.done_1: |
pop edi eax |
add esp,4 |
inc esi |
clc |
ret |
char_todown: |
; convert character to uppercase, using cp866 encoding |
; in: al=symbol |
; out: al=converted symbol |
cmp al, 'A' |
jb .ret |
cmp al, 'Z' |
jbe .az |
cmp al, '' |
jb .ret |
cmp al, '' |
jb .rus1 |
cmp al, '' |
ja .ret |
; 0x90-0x9F -> 0xE0-0xEF |
add al, 'à'-'' |
.ret: |
ret |
.rus1: |
; 0x80-0x8F -> 0xA0-0xAF |
.az: |
add al, 0x20 |
ret |
uni2ansi_char: |
; convert UNICODE character in al to ANSI character in ax, using cp866 encoding |
; in: ax=UNICODE character |
; out: al=converted ANSI character |
cmp ax, 0x80 |
jb .ascii |
cmp ax, 0x401 |
jz .yo1 |
cmp ax, 0x451 |
jz .yo2 |
cmp ax, 0x410 |
jb .unk |
cmp ax, 0x440 |
jb .rus1 |
cmp ax, 0x450 |
jb .rus2 |
.unk: |
mov al, '_' |
jmp .doit |
.yo1: |
mov al, 'ð' |
jmp .doit |
.yo2: |
mov al, 'ñ' |
jmp .doit |
.rus1: |
; 0x410-0x43F -> 0x80-0xAF |
add al, 0x70 |
jmp .doit |
.rus2: |
; 0x440-0x44F -> 0xE0-0xEF |
add al, 0xA0 |
.ascii: |
.doit: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/fs/parse_fn.inc |
---|
0,0 → 1,200 |
$Revision$ |
;------------------------------------------------------------------------- |
; |
; File path partial substitution (according to configuration) |
; |
; |
; SPraid |
; |
;------------------------------------------------------------------------- |
iglobal |
; pointer to memory for path replace table, |
; size of one record is 128 bytes: 64 bytes for search pattern + 64 bytes for replace string |
; start with one entry: sys -> <sysdir> |
full_file_name_table dd sysdir_name |
.size dd 1 |
tmp_file_name_size dd 1 |
endg |
uglobal |
; Parser_params will initialize: sysdir_name = "sys", sysdir_path = <sysdir> |
sysdir_name rb 64 |
sysdir_path rb 64 |
tmp_file_name_table dd ? |
endg |
; use bx_from_load and init system directory /sys |
Parser_params: |
mov eax,[OS_BASE+0x10000+bx_from_load] |
mov ecx,sysdir_path |
mov [ecx-64],dword 'sys' |
cmp al,'r' ; if ram disk |
jnz @f |
mov [ecx],dword 'RD/?' |
mov [ecx+3],byte ah |
mov [ecx+4],byte 0 |
ret |
@@: |
sub al,49 |
mov [ecx],dword 'HD?/' ; if hard disk |
mov [ecx+2],byte al |
mov [ecx+4],byte ah |
mov [ecx+5],dword '/KOL' |
mov [ecx+9],dword 'IBRI' |
mov [ecx+13],byte 0 |
ret |
proc load_file_parse_table |
stdcall kernel_alloc,0x1000 |
mov [tmp_file_name_table],eax |
mov edi,eax |
mov esi,sysdir_name |
mov ecx,128/4 |
rep movsd |
invoke ini.enum_keys,conf_fname,conf_path_sect,get_every_key |
mov eax,[tmp_file_name_table] |
mov [full_file_name_table],eax |
mov eax,[tmp_file_name_size] |
mov [full_file_name_table.size],eax |
ret |
endp |
uglobal |
def_val_1 db 0 |
endg |
proc get_every_key stdcall, f_name, sec_name, key_name |
mov esi, [key_name] |
mov ecx, esi |
cmp byte [esi], '/' |
jnz @f |
inc esi |
@@: |
mov edi, [tmp_file_name_size] |
shl edi, 7 |
cmp edi, 0x1000 |
jae .stop_parse |
add edi, [tmp_file_name_table] |
lea ebx, [edi+64] |
@@: |
cmp edi, ebx |
jae .skip_this_key |
lodsb |
test al, al |
jz @f |
or al, 20h |
stosb |
jmp @b |
@@: |
stosb |
invoke ini.get_str, [f_name],[sec_name],ecx,ebx,64,def_val_1 |
cmp byte [ebx], '/' |
jnz @f |
lea esi, [ebx+1] |
mov edi, ebx |
mov ecx, 63 |
rep movsb |
@@: |
push ebp |
mov ebp, [tmp_file_name_table] |
mov ecx, [tmp_file_name_size] |
jecxz .noreplace |
mov eax, ecx |
dec eax |
shl eax, 7 |
add ebp, eax |
.replace_loop: |
mov edi, ebx |
mov esi, ebp |
@@: |
lodsb |
test al, al |
jz .doreplace |
mov dl, [edi] |
inc edi |
test dl, dl |
jz .replace_loop_cont |
or dl, 20h |
cmp al, dl |
jz @b |
jmp .replace_loop_cont |
.doreplace: |
cmp byte [edi], 0 |
jz @f |
cmp byte [edi], '/' |
jnz .replace_loop_cont |
@@: |
lea esi, [ebp+64] |
call .replace |
jc .skip_this_key2 |
.replace_loop_cont: |
sub ebp, 128 |
loop .replace_loop |
.noreplace: |
pop ebp |
inc [tmp_file_name_size] |
.skip_this_key: |
xor eax, eax |
inc eax |
ret |
.skip_this_key2: |
pop ebp |
jmp .skip_this_key |
.stop_parse: |
xor eax, eax |
ret |
endp |
proc get_every_key.replace |
; in: ebx->destination, esi->first part of name, edi->second part of name |
; maximum length is 64 bytes |
; out: CF=1 <=> overflow |
; 1) allocate temporary buffer in stack |
sub esp, 64 |
; 2) save second part of name to temporary buffer |
push esi |
lea esi, [esp+4] ; esi->tmp buffer |
xchg esi, edi ; edi->tmp buffer, esi->source |
@@: |
lodsb |
stosb |
test al, al |
jnz @b |
; 3) copy first part of name to destination |
pop esi |
mov edi, ebx |
@@: |
lodsb |
test al, al |
jz @f |
stosb |
jmp @b |
@@: |
; 4) restore second part of name from temporary buffer to destination |
; (may cause overflow) |
lea edx, [ebx+64] ; limit of destination |
mov esi, esp |
@@: |
cmp edi, edx |
jae .overflow |
lodsb |
stosb |
test al, al |
jnz @b |
; all is OK |
add esp, 64 ; CF is cleared |
ret |
.overflow: |
; name is too long |
add esp, 64 |
stc |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/fs/fat12.inc |
---|
0,0 → 1,2267 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; FAT12.INC ;; |
;; (C) 2005 Mario79, License: GPL ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
n_sector dd 0 ; temporary save for sector value |
flp_status dd 0 |
clust_tmp_flp dd 0 ; used by analyze_directory and analyze_directory_to_write |
path_pointer_flp dd 0 |
pointer_file_name_flp dd 0 |
save_root_flag db 0 |
save_flag db 0 |
root_read db 0 ; 0-necessary to load root, 1-not to load root |
flp_fat db 0 ; 0-necessary to load fat, 1-not to load fat |
flp_number db 0 ; 1- Floppy A, 2-Floppy B |
old_track db 0 ; old value track |
flp_label rb 15 ; Label and ID of inserted floppy disk |
reserve_flp: |
cli |
cmp [flp_status],0 |
je reserve_flp_ok |
sti |
call change_task |
jmp reserve_flp |
reserve_flp_ok: |
push eax |
mov eax,[CURRENT_TASK] |
shl eax,5 |
mov eax,[eax+CURRENT_TASK+TASKDATA.pid] |
mov [flp_status],eax |
pop eax |
sti |
ret |
floppy_fileread: |
;---------------------------------------------------------------- |
; |
; fileread - sys floppy |
; |
; eax points to filename 11 chars - for root directory |
; ebx first wanted block ; 1+ ; if 0 then set to 1 |
; ecx number of blocks to read ; 1+ ; if 0 then set to 1 |
; edx mem location to return data |
; esi length of filename 12*X |
; edi pointer to path /fd/1/...... - for all files in nested directories |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; 10 = access denied |
;-------------------------------------------------------------- |
mov [save_flag],0 |
mov [path_pointer_flp],edi |
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,FLOPPY_BUFF |
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,FDD_BUFF |
inc [FDD_Sector] |
l.21_1: |
mov esi,eax ;Name of file we want |
mov ecx,11 |
cld |
rep cmpsb ;Found the file? |
je fifound_1 ;Yes |
add ecx,21 |
add edi, ecx ;Advance to next entry |
dec dl |
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,FLOPPY_FAT |
mov eax,[edi] |
and eax,4095 |
mov edi,eax |
mov [n_sector],edi |
cmp edi,4095 ;eof - cluster |
jz frnoread2_1 |
cmp [esp+24],dword 512 ;eof - size |
jb frnoread_1 |
sub [esp+24],dword 512 |
jmp frnew_1 |
read_chs_sector: |
call calculate_chs |
call ReadSectWithRetr |
ret |
frnoread2_1: |
cmp [esp+16],dword 0 ; eof without read ? |
je frnoread_1 |
mov [fdc_irq_func],fdc_null |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
mov eax,6 ; end of file |
mov [flp_status],0 |
ret |
frnoread_1: |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
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,FLOPPY_BUFF |
call SeekTrack |
read_flp_root_1: |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_root_read |
push edi |
call give_back_application_data_1 |
pop edi |
add edi,512 |
inc [FDD_Sector] |
cmp [FDD_Sector],16 |
jne read_flp_root_1 |
mov [root_read],1 |
unnecessary_root_read: |
popa |
ret |
read_flp_fat: |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat |
cmp [flp_fat],1 |
je unnecessary_flp_fat |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
mov edi,FLOPPY_BUFF |
call SeekTrack |
read_flp_fat_1: |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat |
push edi |
call give_back_application_data_1 |
pop edi |
add edi,512 |
inc [FDD_Sector] |
cmp [FDD_Sector],19 |
jne read_flp_fat_1 |
mov [FDD_Sector],1 |
mov [FDD_Head],1 |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat |
call give_back_application_data_1 |
call calculatefatchain_flp |
mov [root_read],0 |
mov [flp_fat],1 |
unnecessary_flp_fat: |
popa |
ret |
calculatefatchain_flp: |
pushad |
mov esi,FLOPPY_BUFF |
mov edi,FLOPPY_FAT |
fcnew_1: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
mov ecx,dword [esi+8] |
mov edx,ecx |
shr edx,4 ;8 ok |
shr dx,4 ;7 ok |
xor ch,ch |
shld ecx,ebx,20 ;6 ok |
shr cx,4 ;5 ok |
shld ebx,eax,12 |
and ebx,0x0fffffff ;4 ok |
shr bx,4 ;3 ok |
shl eax,4 |
and eax,0x0fffffff ;2 ok |
shr ax,4 ;1 ok |
mov dword [edi],eax |
add edi,4 |
mov dword [edi],ebx |
add edi,4 |
mov dword [edi],ecx |
add edi,4 |
mov dword [edi],edx |
add edi,4 |
add esi,12 |
cmp edi,FLOPPY_FAT+2856*2 ;2849 clusters |
jnz fcnew_1 |
popad |
ret |
check_label: |
pushad |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],1 ; Ñåêòîð |
call SetUserInterrupts |
call FDDMotorON |
call RecalibrateFDD |
cmp [FDC_Status],0 |
jne fdc_status_error |
call SeekTrack |
cmp [FDC_Status],0 |
jne fdc_status_error |
call ReadSectWithRetr |
cmp [FDC_Status],0 |
jne fdc_status_error |
mov esi,flp_label |
mov edi,FDD_BUFF+39 |
mov ecx,15 |
cld |
rep cmpsb |
je same_label |
mov [root_read],0 |
mov [flp_fat],0 |
same_label: |
mov esi,FDD_BUFF+39 |
mov edi,flp_label |
mov ecx,15 |
cld |
rep movsb |
popad |
ret |
fdc_status_error: |
popad |
ret |
save_flp_root: |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_root_save |
cmp [root_read],0 |
je unnecessary_root_save |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],1 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
mov esi,FLOPPY_BUFF |
call SeekTrack |
save_flp_root_1: |
push esi |
call take_data_from_application_1 |
pop esi |
add esi,512 |
call WriteSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_root_save |
inc [FDD_Sector] |
cmp [FDD_Sector],16 |
jne save_flp_root_1 |
unnecessary_root_save: |
mov [fdc_irq_func],fdc_null |
popa |
ret |
save_flp_fat: |
pusha |
call check_label |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat_save |
cmp [flp_fat],0 |
je unnecessary_flp_fat_save |
call restorefatchain_flp |
mov [FDD_Track],0 ; Öèëèíäð |
mov [FDD_Head],0 ; Ñòîðîíà |
mov [FDD_Sector],2 ; Ñåêòîð |
mov esi,FLOPPY_BUFF |
call SeekTrack |
save_flp_fat_1: |
push esi |
call take_data_from_application_1 |
pop esi |
add esi,512 |
call WriteSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat_save |
inc [FDD_Sector] |
cmp [FDD_Sector],19 |
jne save_flp_fat_1 |
mov [FDD_Sector],1 |
mov [FDD_Head],1 |
call take_data_from_application_1 |
call WriteSectWithRetr |
cmp [FDC_Status],0 |
jne unnecessary_flp_fat_save |
mov [root_read],0 |
unnecessary_flp_fat_save: |
mov [fdc_irq_func],fdc_null |
popa |
ret |
restorefatchain_flp: ; restore fat chain |
pushad |
mov esi,FLOPPY_FAT |
mov edi,FLOPPY_BUFF |
fcnew2_1: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
shl ax,4 |
shl eax,4 |
shl bx,4 |
shr ebx,4 |
shrd eax,ebx,8 |
shr ebx,8 |
mov dword [edi],eax |
add edi,4 |
mov word [edi],bx |
add edi,2 |
add esi,8 |
cmp edi,FLOPPY_BUFF+0x1200 ;4274 bytes - all used FAT |
jb fcnew2_1 |
mov esi,FLOPPY_BUFF ; duplicate fat chain |
mov edi,FLOPPY_BUFF+0x1200 |
mov ecx,0x1200/4 |
cld |
rep movsd |
popad |
ret |
save_chs_sector: |
call calculate_chs |
call WriteSectWithRetr |
ret |
calculate_chs: |
mov bl,[FDD_Track] |
mov [old_track],bl |
mov ebx,18 |
xor edx,edx |
div ebx |
inc edx |
mov [FDD_Sector],dl |
xor edx,edx |
mov ebx,2 |
div ebx |
mov [FDD_Track],al |
mov [FDD_Head],0 |
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,FDD_BUFF |
adr1_analyze_flp: |
mov esi,edx ;[esp+16] |
mov edi,ebx |
cld |
push ecx |
mov ecx,11 |
rep cmpsb |
pop ecx |
je found_file_analyze_flp |
add ebx,32 |
loop adr1_analyze_flp |
mov eax,[clust_tmp_flp] |
shl eax,1 ;find next cluster from FAT |
add eax,FLOPPY_FAT |
mov eax,[eax] |
and eax,4095 |
cmp eax,0x0ff8 |
jb adr56_flp |
not_found_file_analyze_flp: |
pop edi |
pop esi |
pop edx |
pop ecx |
add esp,4 |
stc ;file not found |
ret |
found_file_analyze_flp: |
pop edi |
pop esi |
pop edx |
pop ecx |
add esp,4 |
clc ;file found |
ret |
; \begin{diamond} |
fat_find_lfn: |
; in: esi->name |
; [esp+4] = next |
; [esp+8] = first |
; [esp+C]... - possibly parameters for first and next |
; out: CF=1 - file not found |
; else CF=0, esi->next name component, edi->direntry |
pusha |
lea eax, [esp+0Ch+20h] |
call dword [eax-4] |
jc .reterr |
sub esp, 262*2 ; reserve place for LFN |
mov ebp, esp |
push 0 ; for fat_get_name: read ASCII name |
.l1: |
call fat_get_name |
jc .l2 |
call fat_compare_name |
jz .found |
.l2: |
lea eax, [esp+0Ch+20h+262*2+4] |
call dword [eax-8] |
jnc .l1 |
add esp, 262*2+4 |
.reterr: |
stc |
popa |
ret |
.found: |
add esp, 262*2+4 |
; if this is LFN entry, advance to true entry |
cmp byte [edi+11], 0xF |
jnz @f |
lea eax, [esp+0Ch+20h] |
call dword [eax-8] |
jc .reterr |
@@: |
add esp, 8 ; CF=0 |
push esi |
push edi |
popa |
ret |
uglobal |
; this is for delete support |
fd_prev_sector dd ? |
fd_prev_prev_sector dd ? |
endg |
flp_root_next: |
cmp edi, OS_BASE+0xD200-0x20 |
jae @f |
add edi, 0x20 |
ret ; CF=0 |
@@: |
; read next sector |
inc dword [eax] |
cmp dword [eax], 14 |
jae flp_root_first.readerr |
push [fd_prev_sector] |
pop [fd_prev_prev_sector] |
push eax |
mov eax, [eax] |
add eax, 19-1 |
mov [fd_prev_sector], eax |
pop eax |
flp_root_first: |
mov eax, [eax] |
pusha |
add eax, 19 |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .readerr |
mov edi, FDD_BUFF |
ret ; CF=0 |
.readerr: |
stc |
ret |
flp_rootmem_first: |
mov edi, FLOPPY_BUFF |
clc |
ret |
flp_rootmem_next: |
add edi, 0x20 |
cmp edi, FLOPPY_BUFF+14*0x200 |
cmc |
flp_rootmem_next_write: |
flp_rootmem_begin_write: |
flp_rootmem_end_write: |
ret |
flp_rootmem_extend_dir: |
stc |
ret |
flp_notroot_next: |
cmp edi, OS_BASE+0xD200-0x20 |
jae flp_notroot_next_sector |
add edi, 0x20 |
ret ; CF=0 |
flp_notroot_next_sector: |
push ecx |
mov ecx, [eax] |
push [fd_prev_sector] |
pop [fd_prev_prev_sector] |
add ecx, 31 |
mov [fd_prev_sector], ecx |
mov ecx, [(ecx-31)*2+FLOPPY_FAT] |
and ecx, 0xFFF |
cmp ecx, 2849 |
jae flp_notroot_first.err2 |
mov [eax], ecx |
pop ecx |
flp_notroot_first: |
mov eax, [eax] |
cmp eax, 2 |
jb .err |
cmp eax, 2849 |
jae .err |
pusha |
add eax, 31 |
call read_chs_sector |
popa |
mov edi, FDD_BUFF |
cmp [FDC_Status], 0 |
jnz .err |
ret ; CF=0 |
.err2: |
pop ecx |
.err: |
stc |
ret |
flp_notroot_begin_write: |
pusha |
mov eax, [eax] |
add eax, 31 |
call read_chs_sector |
popa |
ret |
flp_notroot_end_write: |
pusha |
mov eax, [eax] |
add eax, 31 |
call save_chs_sector |
popa |
ret |
flp_notroot_next_write: |
cmp edi, OS_BASE+0xD200 |
jae @f |
ret |
@@: |
call flp_notroot_end_write |
jmp flp_notroot_next_sector |
flp_notroot_extend_dir: |
; find free cluster in FAT |
pusha |
xor eax, eax |
mov edi, FLOPPY_FAT |
mov ecx, 2849 |
repnz scasw |
jnz .notfound |
mov word [edi-2], 0xFFF ; mark as last cluster |
sub edi, FLOPPY_FAT |
shr edi, 1 |
dec edi |
mov eax, [esp+28] |
mov ecx, [eax] |
mov [FLOPPY_FAT+ecx*2], di |
mov [eax], edi |
xor eax, eax |
mov edi, FDD_BUFF |
mov ecx, 128 |
rep stosd |
popa |
call flp_notroot_end_write |
mov edi, FDD_BUFF |
clc |
ret |
.notfound: |
popa |
stc |
ret |
fd_find_lfn: |
; in: esi+ebp -> name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry, eax=directory cluster (0 for root) |
push esi edi |
push 0 |
push flp_root_first |
push flp_root_next |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
.continue: |
test byte [edi+11], 10h |
jz .notfound |
movzx eax, word [edi+26] ; cluster |
mov [esp+8], eax |
mov dword [esp+4], flp_notroot_first |
mov dword [esp], flp_notroot_next |
jmp .loop |
.notfound: |
add esp, 12 |
pop edi esi |
stc |
ret |
.found: |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
jmp .continue |
@@: |
mov eax, [esp+8] |
add eax, 31 |
cmp dword [esp], flp_root_next |
jnz @f |
add eax, -31+19 |
@@: |
add esp, 16 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyRead - LFN variant for reading floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_FloppyRead: |
call read_flp_fat |
cmp byte [esi], 0 |
jnz @f |
or ebx, -1 |
mov eax, 10 ; access denied |
ret |
@@: |
push edi |
call fd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, 5 ; file not found |
ret |
.found: |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 ; EOF |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+28] |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 ; EOF |
@@: |
movzx edi, word [edi+26] |
.new: |
jecxz .done |
test edi, edi |
jz .eof |
cmp edi, 0xFF8 |
jae .eof |
sub ebx, 512 |
jae .skip |
lea eax, [edi+31] |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .err |
lea eax, [FDD_BUFF+ebx+512] |
neg ebx |
push ecx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
mov ebx, edx |
call memmove |
add edx, ecx |
sub [esp], ecx |
pop ecx |
xor ebx, ebx |
.skip: |
movzx edi, word [edi*2+FLOPPY_FAT] |
jmp .new |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
.eof: |
mov ebx, edx |
pop eax edx ecx |
jmp .reteof |
.err: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
mov al, 11 |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyReadFolder - LFN variant for reading floppy folders |
; |
; esi points to filename |
; ebx pointer to structure: 32-bit number = first wanted block, 0+ |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = blocks read or 0xffffffff folder not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_FloppyReadFolder: |
call read_flp_fat |
push edi |
cmp byte [esi], 0 |
jz .root |
call fd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 ; do not allow read files |
jnz .found_dir |
pop edi |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
movzx eax, word [edi+26] |
add eax, 31 |
push 0 |
jmp .doit |
.root: |
mov eax, 19 |
push 14 |
.doit: |
push ecx ebp |
sub esp, 262*2 ; reserve space for LFN |
mov ebp, esp |
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names |
mov ebx, [ebx] |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
pop ecx eax |
mov byte [edx], 1 ; version |
mov esi, edi ; esi points to BDFE |
.main_loop: |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .error |
mov edi, FDD_BUFF |
push eax |
.l1: |
call fat_get_name |
jc .l2 |
cmp byte [edi+11], 0xF |
jnz .do_bdfe |
add edi, 0x20 |
cmp edi, OS_BASE+0xD200 |
jb .do_bdfe |
pop eax |
inc eax |
dec byte [esp+262*2+12] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+FLOPPY_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+12], 0 |
@@: |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .error |
mov edi, FDD_BUFF |
push eax |
.do_bdfe: |
inc dword [edx+8] ; new file found |
dec ebx |
jns .l2 |
dec ecx |
js .l2 |
inc dword [edx+4] ; new file block copied |
call fat_entry_to_bdfe |
.l2: |
add edi, 0x20 |
cmp edi, OS_BASE+0xD200 |
jb .l1 |
pop eax |
inc eax |
dec byte [esp+262*2+12] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+FLOPPY_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+12], 0 |
@@: |
jmp .main_loop |
.error: |
add esp, 262*2+4 |
pop ebp ecx edi edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.done: |
add esp, 262*2+4 |
pop ebp |
mov ebx, [edx+4] |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx edi edi |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyRewrite - LFN variant for writing sys floppy |
; |
; esi points to filename |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fsfrfe2: |
popad |
fsfrfe: |
mov eax, 11 |
xor ebx, ebx |
ret |
fs_FloppyCreateFolder: |
mov al, 1 |
jmp fs_FloppyRewrite.common |
fs_FloppyRewrite: |
xor eax, eax |
.common: |
cmp byte [esi], 0 |
jz @b |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz fsfrfe |
pushad |
xor edi, edi |
push esi |
test ebp, ebp |
jz @f |
mov esi, ebp |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea edi, [esi-1] |
jmp @b |
@@: |
pop esi |
test edi, edi |
jnz .noroot |
test ebp, ebp |
jnz .hasebp |
call read_flp_root |
cmp [FDC_Status], 0 |
jnz fsfrfe2 |
push flp_rootmem_extend_dir |
push flp_rootmem_end_write |
push flp_rootmem_next_write |
push flp_rootmem_begin_write |
xor ebp, ebp |
push ebp |
push flp_rootmem_first |
push flp_rootmem_next |
jmp .common1 |
.hasebp: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [ebp], 0 |
jz .ret1 |
push ebp |
xor ebp, ebp |
call fd_find_lfn |
pop esi |
jc .notfound0 |
jmp .common0 |
.noroot: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [edi+1], 0 |
jz .ret1 |
; check existence |
mov byte [edi], 0 |
push edi |
call fd_find_lfn |
pop esi |
mov byte [esi], '/' |
jnc @f |
.notfound0: |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
inc esi |
.common0: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
movzx ebp, word [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
cmp ebp, 2849 |
jae .ret1 |
push flp_notroot_extend_dir |
push flp_notroot_end_write |
push flp_notroot_next_write |
push flp_notroot_begin_write |
push ebp |
push flp_notroot_first |
push flp_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found |
test byte [edi+11], 10h |
jz .exists_file |
; found directory; if we are creating directory, return OK, |
; if we are creating file, say "access denied" |
add esp, 28 |
popad |
test al, al |
mov eax, ERROR_ACCESS_DENIED |
jz @f |
mov al, 0 |
@@: |
xor ebx, ebx |
ret |
.exists_file: |
; found file; if we are creating directory, return "access denied", |
; if we are creating file, delete existing file and continue |
cmp byte [esp+28+28], 0 |
jz @f |
add esp, 28 |
popad |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
@@: |
; delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xchg ax, word [edi+26] ; start cluster |
test eax, eax |
jz .done1 |
@@: |
cmp eax, 0xFF8 |
jae .done1 |
lea edi, [FLOPPY_FAT + eax*2] ; position in FAT |
xor eax, eax |
xchg ax, [edi] |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 28 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+28 |
popa |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
; find <eax> successive entries in directory |
xor ecx, ecx |
push eax |
lea eax, [esp+12+8+12+8] |
mov [eax], ebp |
call dword [eax-4] |
pop eax |
jnc .scan_dir |
.fsfrfe3: |
add esp, 8+8+12+28 |
popad |
mov eax, 11 |
xor ebx, ebx |
ret |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax-8] |
pop eax |
jnc .scan_dir |
cmp [FDC_Status], 0 |
jnz .fsfrfe3 |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax+16] ; extend directory |
pop eax |
jnc .scan_dir |
add esp, 8+8+12+28 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.free: |
test ecx, ecx |
jnz @f |
mov [esp], edi |
mov ecx, [esp+8+8+12+8] |
mov [esp+4], ecx |
xor ecx, ecx |
@@: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8+8] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop dword [esp+8+12+8] |
; edi points to first entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
lea eax, [esp+8+8+12+8] |
call dword [eax+4] ; begin write |
mov al, 40h |
.writelfn: |
or al, cl |
mov esi, [esp+4] |
push ecx |
dec ecx |
imul ecx, 13 |
add esi, ecx |
stosb |
mov cl, 5 |
call fs_RamdiskRewrite.read_symbols |
mov ax, 0xF |
stosw |
mov al, [esp+4] |
stosb |
mov cl, 6 |
call fs_RamdiskRewrite.read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call fs_RamdiskRewrite.read_symbols |
pop ecx |
lea eax, [esp+8+8+12+8] |
call dword [eax+8] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
; lea eax, [esp+8+12+8] |
; call dword [eax+12] ; end write |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
and word [edi+20], 0 ; high word of cluster |
and word [edi+26], 0 ; low word of cluster - to be filled |
and dword [edi+28], 0 ; file size - to be filled |
cmp byte [esp+28+28], 0 |
jz .doit |
; create directory |
mov byte [edi+11], 10h ; attributes: folder |
mov ecx, 32*2 |
mov edx, edi |
.doit: |
lea eax, [esp+8] |
call dword [eax+12] ; flush directory |
push ecx |
push edi |
push 0 |
mov esi, edx |
test ecx, ecx |
jz .done |
mov ecx, 2849 |
mov edi, FLOPPY_FAT |
push 0 ; first cluster |
.write_loop: |
; allocate new cluster |
xor eax, eax |
repnz scasw |
mov al, ERROR_DISK_FULL |
jnz .ret |
dec edi |
dec edi |
mov eax, edi |
sub eax, FLOPPY_FAT |
shr eax, 1 ; eax = cluster |
mov word [edi], 0xFFF ; mark as last cluster |
xchg edi, [esp+4] |
cmp dword [esp], 0 |
jz .first |
stosw |
jmp @f |
.first: |
mov [esp], eax |
@@: |
mov edi, [esp+4] |
inc ecx |
; write data |
push ecx edi |
mov ecx, 512 |
cmp dword [esp+20], ecx |
jae @f |
mov ecx, [esp+20] |
@@: |
mov edi, FDD_BUFF |
cmp byte [esp+24+28+28], 0 |
jnz .writedir |
push ecx |
rep movsb |
pop ecx |
.writedircont: |
push ecx |
sub ecx, 512 |
neg ecx |
push eax |
xor eax, eax |
rep stosb |
pop eax |
add eax, 31 |
pusha |
call save_chs_sector |
popa |
pop ecx |
cmp [FDC_Status], 0 |
jnz .diskerr |
sub [esp+20], ecx |
pop edi ecx |
jnz .write_loop |
.done: |
xor eax, eax |
.ret: |
pop ebx edi edi ecx |
mov [esp+28+28], eax |
lea eax, [esp+8] |
call dword [eax+4] |
mov [edi+26], bx |
mov ebx, esi |
sub ebx, edx |
mov [edi+28], ebx |
call dword [eax+12] |
mov [esp+28+16], ebx |
test ebp, ebp |
jnz @f |
call save_flp_root |
@@: |
add esp, 28 |
cmp [FDC_Status], 0 |
jnz .err3 |
call save_flp_fat |
cmp [FDC_Status], 0 |
jnz .err3 |
popa |
ret |
.err3: |
popa |
mov al, 11 |
xor ebx, ebx |
ret |
.diskerr: |
sub esi, ecx |
mov eax, 11 |
pop edi ecx |
jmp .ret |
.writedir: |
push ecx |
mov ecx, 32/4 |
push ecx esi |
rep movsd |
pop esi ecx |
mov dword [edi-32], '. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
mov word [edi-32+26], ax |
push esi |
rep movsd |
pop esi |
mov dword [edi-32], '.. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
mov ecx, [esp+28+8] |
mov word [edi-32+26], cx |
pop ecx |
jmp .writedircont |
;---------------------------------------------------------------- |
; |
; fs_FloppyWrite - LFN variant for writing to floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = bytes written (maybe 0) |
; eax = 0 ok write or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
push ERROR_ACCESS_DENIED |
fs_FloppyWrite.ret0: |
pop eax |
xor ebx, ebx |
ret |
fs_FloppyWrite.ret11: |
push 11 |
jmp fs_FloppyWrite.ret0 |
fs_FloppyWrite: |
cmp byte [esi], 0 |
jz @b |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz .ret11 |
pushad |
call fd_find_lfn |
jnc .found |
popad |
push ERROR_FILE_NOT_FOUND |
jmp .ret0 |
.found: |
; FAT does not support files larger than 4GB |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
.eof: |
popad |
push ERROR_END_OF_FILE |
jmp .ret0 |
@@: |
mov ebx, [ebx] |
.l1: |
; now edi points to direntry, ebx=start byte to write, |
; ecx=number of bytes to write, edx=data pointer |
; extend file if needed |
add ecx, ebx |
jc .eof ; FAT does not support files larger than 4GB |
push eax ; save directory cluster |
push 0 ; return value=0 |
call get_time_for_file |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
push dword [edi+28] ; save current file size |
cmp ecx, [edi+28] |
jbe .length_ok |
cmp ecx, ebx |
jz .length_ok |
call floppy_extend_file |
jnc .length_ok |
mov [esp+4], eax |
; floppy_extend_file can return two error codes: FAT table error or disk full. |
; First case is fatal error, in second case we may write some data |
cmp al, ERROR_DISK_FULL |
jz .disk_full |
pop eax |
pop eax |
mov [esp+4+28], eax |
pop eax |
popad |
xor ebx, ebx |
ret |
.disk_full: |
; correct number of bytes to write |
mov ecx, [edi+28] |
cmp ecx, ebx |
ja .length_ok |
.ret: |
pop eax |
pop eax |
mov [esp+4+28], eax ; eax=return value |
pop eax |
sub edx, [esp+20] |
mov [esp+16], edx ; ebx=number of written bytes |
popad |
ret |
.length_ok: |
; save FAT & directory |
; note that directory must be saved first because save_flp_fat uses buffer at 0xD000 |
mov esi, [edi+28] |
movzx edi, word [edi+26] ; starting cluster |
mov eax, [esp+8] |
pusha |
call save_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .device_err |
call save_flp_fat |
cmp [FDC_Status], 0 |
jz @f |
.device_err: |
mov byte [esp+4], 11 |
jmp .ret |
@@: |
; now ebx=start pos, ecx=end pos, both lie inside file |
sub ecx, ebx |
jz .ret |
call SetUserInterrupts |
.write_loop: |
; skip unmodified sectors |
cmp dword [esp], 0x200 |
jb .modify |
sub ebx, 0x200 |
jae .skip |
add ebx, 0x200 |
.modify: |
lea eax, [edi+31] ; current sector |
; get length of data in current sector |
push ecx |
sub ebx, 0x200 |
jb .hasdata |
neg ebx |
xor ecx, ecx |
jmp @f |
.hasdata: |
neg ebx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
; load sector if needed |
cmp dword [esp+4], 0 ; we don't need to read uninitialized data |
jz .noread |
cmp ecx, 0x200 ; we don't need to read sector if it is fully rewritten |
jz .noread |
cmp ecx, esi ; (same for the last sector) |
jz .noread |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jz @f |
.device_err2: |
pop ecx |
jmp .device_err |
@@: |
.noread: |
; zero uninitialized data if file was extended (because floppy_extend_file does not this) |
push eax ecx edi |
xor eax, eax |
mov ecx, 0x200 |
sub ecx, [esp+4+12] |
jbe @f |
mov edi, FDD_BUFF |
add edi, [esp+4+12] |
rep stosb |
@@: |
; zero uninitialized data in the last sector |
mov ecx, 0x200 |
sub ecx, esi |
jbe @f |
mov edi, FDD_BUFF |
add edi, esi |
rep stosb |
@@: |
pop edi ecx eax |
; copy new data |
push eax |
mov eax, edx |
neg ebx |
jecxz @f |
add ebx, FDD_BUFF+0x200 |
call memmove |
xor ebx, ebx |
@@: |
pop eax |
; save sector |
pusha |
call save_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .device_err2 |
add edx, ecx |
sub [esp], ecx |
pop ecx |
jz .done |
.skip: |
.next_cluster: |
movzx edi, word [edi*2+FLOPPY_FAT] |
sub esi, 0x200 |
jae @f |
xor esi, esi |
@@: |
sub dword [esp], 0x200 |
jae .write_loop |
and dword [esp], 0 |
jmp .write_loop |
.done: |
mov [fdc_irq_func], fdc_null |
jmp .ret |
floppy_extend_file.zero_size: |
xor eax, eax |
jmp floppy_extend_file.start_extend |
; extends file on floppy to given size (new data area is undefined) |
; in: edi->direntry, ecx=new size |
; out: CF=0 => OK, eax=0 |
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) |
floppy_extend_file: |
push ecx |
; find the last cluster of file |
movzx eax, word [edi+26] ; first cluster |
mov ecx, [edi+28] |
jecxz .zero_size |
@@: |
sub ecx, 0x200 |
jbe @f |
mov eax, [eax*2+FLOPPY_FAT] |
and eax, 0xFFF |
jz .fat_err |
cmp eax, 0xFF8 |
jb @b |
.fat_err: |
pop ecx |
push ERROR_FAT_TABLE |
pop eax |
stc |
ret |
@@: |
push eax |
mov eax, [eax*2+FLOPPY_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
pop eax |
jb .fat_err |
; set length to full number of sectors |
sub [edi+28], ecx |
.start_extend: |
pop ecx |
; now do extend |
push edx esi |
mov esi, FLOPPY_FAT+2*2 ; start scan from cluster 2 |
mov edx, 2847 ; number of clusters to scan |
.extend_loop: |
cmp [edi+28], ecx |
jae .extend_done |
; add new sector |
push ecx |
push edi |
.scan: |
mov ecx, edx |
mov edi, esi |
jecxz .disk_full |
push eax |
xor eax, eax |
repnz scasw |
pop eax |
jnz .disk_full |
mov word [edi-2], 0xFFF |
mov esi, edi |
mov edx, ecx |
sub edi, FLOPPY_FAT |
shr edi, 1 |
dec edi ; now edi=new cluster |
test eax, eax |
jz .first_cluster |
mov [FLOPPY_FAT+eax*2], di |
jmp @f |
.first_cluster: |
pop eax ; eax->direntry |
push eax |
mov [eax+26], di |
@@: |
mov eax, edi ; eax=new cluster |
pop edi ; edi->direntry |
pop ecx ; ecx=required size |
add dword [edi+28], 0x200 |
jmp .extend_loop |
.extend_done: |
mov [edi+28], ecx |
pop esi edx |
xor eax, eax ; CF=0 |
ret |
.disk_full: |
pop edi ecx |
pop esi edx |
stc |
push ERROR_DISK_FULL |
pop eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppySetFileEnd - set end of file on floppy |
; |
; esi points to filename |
; ebx points to 64-bit number = new file size |
; ecx ignored (reserved) |
; edx ignored (reserved) |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_FloppySetFileEnd: |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz ret11 |
cmp byte [esi], 0 |
jnz @f |
.access_denied: |
push ERROR_ACCESS_DENIED |
jmp .ret |
@@: |
push edi |
call fd_find_lfn |
jnc @f |
pop edi |
push ERROR_FILE_NOT_FOUND |
.ret: |
pop eax |
jmp .doret |
@@: |
; must not be directory |
test byte [edi+11], 10h |
jz @f |
pop edi |
jmp .access_denied |
@@: |
; file size must not exceed 4 Gb |
cmp dword [ebx+4], 0 |
jz @f |
pop edi |
push ERROR_END_OF_FILE |
jmp .ret |
@@: |
push eax |
; set file modification date/time to current |
call fat_update_datetime |
mov eax, [ebx] |
cmp eax, [edi+28] |
jb .truncate |
ja .expand |
pop eax |
pushad |
call save_chs_sector |
popad |
pop edi |
xor eax, eax |
cmp [FDC_Status], 0 |
jz @f |
mov al, 11 |
@@: |
.doret: |
mov [fdc_irq_func], fdc_null |
ret |
.expand: |
push ecx |
push dword [edi+28] ; save old size |
mov ecx, eax |
call floppy_extend_file |
push eax ; return code |
jnc .expand_ok |
cmp al, ERROR_DISK_FULL |
jz .disk_full |
pop eax ecx ecx edi edi |
jmp .doret |
.device_err: |
pop eax |
.device_err2: |
pop ecx ecx eax edi |
push 11 |
jmp .ret |
.disk_full: |
.expand_ok: |
; save directory & FAT |
mov eax, [edi+28] |
xchg eax, [esp+12] |
movzx edi, word [edi+26] |
pusha |
call save_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .device_err |
call save_flp_fat |
cmp [FDC_Status], 0 |
jnz .device_err |
call SetUserInterrupts |
; now zero new data |
; edi = current cluster, [esp+12]=new size, [esp+4]=old size, [esp]=return code |
.zero_loop: |
sub dword [esp+4], 0x200 |
jae .next_cluster |
cmp dword [esp+4], -0x200 |
jz .noread |
lea eax, [edi+31] |
pusha |
call read_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .err_next |
.noread: |
mov ecx, [esp+4] |
neg ecx |
push edi |
mov edi, FDD_BUFF+0x200 |
add edi, [esp+8] |
xor eax, eax |
mov [esp+8], eax |
rep stosb |
pop edi |
lea eax, [edi+31] |
pusha |
call save_chs_sector |
popa |
cmp [FDC_Status], 0 |
jz .next_cluster |
.err_next: |
mov byte [esp], 11 |
.next_cluster: |
sub dword [esp+12], 0x200 |
jbe .expand_done |
movzx edi, word [FLOPPY_FAT+edi*2] |
jmp .zero_loop |
.expand_done: |
pop eax ecx ecx edi edi |
jmp .doret |
.truncate: |
mov [edi+28], eax |
push ecx |
movzx ecx, word [edi+26] |
test eax, eax |
jz .zero_size |
; find new last sector |
@@: |
sub eax, 0x200 |
jbe @f |
movzx ecx, word [FLOPPY_FAT+ecx*2] |
jmp @b |
@@: |
; we will zero data at the end of last sector - remember it |
push ecx |
; terminate FAT chain |
lea ecx, [FLOPPY_FAT+ecx+ecx] |
push dword [ecx] |
mov word [ecx], 0xFFF |
pop ecx |
and ecx, 0xFFF |
jmp .delete |
.zero_size: |
and word [edi+26], 0 |
push 0 |
.delete: |
; delete FAT chain starting with ecx |
; mark all clusters as free |
cmp ecx, 0xFF8 |
jae .deleted |
lea ecx, [FLOPPY_FAT+ecx+ecx] |
push dword [ecx] |
and word [ecx], 0 |
pop ecx |
and ecx, 0xFFF |
jmp .delete |
.deleted: |
mov edi, [edi+28] |
; save directory & FAT |
mov eax, [esp+8] |
pusha |
call save_chs_sector |
popa |
cmp [FDC_Status], 0 |
jnz .device_err2 |
call save_flp_fat |
cmp [FDC_Status], 0 |
jnz .device_err2 |
; zero last sector, ignore errors |
pop eax |
add eax, 31 |
and edi, 0x1FF |
jz .truncate_done |
call SetUserInterrupts |
pusha |
call read_chs_sector |
popa |
add edi, FDD_BUFF |
mov ecx, FDD_BUFF+0x200 |
sub ecx, edi |
push eax |
xor eax, eax |
rep stosb |
pop eax |
pusha |
call save_chs_sector |
popa |
.truncate_done: |
pop ecx eax edi |
xor eax, eax |
jmp .doret |
fs_FloppyGetFileInfo: |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz ret11 |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call fd_find_lfn |
jmp fs_GetFileInfo_finish |
ret11: |
mov eax, 11 |
ret |
fs_FloppySetFileInfo: |
call read_flp_fat |
cmp [FDC_Status], 0 |
jnz ret11 |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call fd_find_lfn |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
push eax |
call bdfe_to_fat_entry |
pop eax |
pusha |
call save_chs_sector |
popa |
pop edi |
xor eax, eax |
cmp [FDC_Status], 0 |
jz @f |
mov al, 11 |
@@: |
ret |
;---------------------------------------------------------------- |
; |
; fs_FloppyDelete - delete file or empty folder from floppy |
; |
; esi points to filename |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_FloppyDelete: |
call read_flp_fat |
cmp [FDC_Status], 0 |
jz @f |
push 11 |
jmp .pop_ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
; cannot delete root! |
.access_denied: |
push ERROR_ACCESS_DENIED |
.pop_ret: |
pop eax |
ret |
@@: |
and [fd_prev_sector], 0 |
and [fd_prev_prev_sector], 0 |
push edi |
call fd_find_lfn |
jnc .found |
pop edi |
push ERROR_FILE_NOT_FOUND |
jmp .pop_ret |
.found: |
cmp dword [edi], '. ' |
jz .access_denied2 |
cmp dword [edi], '.. ' |
jz .access_denied2 |
test byte [edi+11], 10h |
jz .dodel |
; we can delete only empty folders! |
push eax |
movzx eax, word [edi+26] |
push ebx |
pusha |
add eax, 31 |
call read_chs_sector |
popa |
mov ebx, FDD_BUFF + 2*0x20 |
.checkempty: |
cmp byte [ebx], 0 |
jz .empty |
cmp byte [ebx], 0xE5 |
jnz .notempty |
add ebx, 0x20 |
cmp ebx, FDD_BUFF + 0x200 |
jb .checkempty |
movzx eax, word [FLOPPY_FAT + eax*2] |
pusha |
add eax, 31 |
call read_chs_sector |
popa |
mov ebx, FDD_BUFF |
jmp .checkempty |
.notempty: |
pop ebx |
pop eax |
.access_denied2: |
pop edi |
jmp .access_denied |
.empty: |
pop ebx |
pop eax |
pusha |
call read_chs_sector |
popa |
.dodel: |
push eax |
movzx eax, word [edi+26] |
xchg eax, [esp] |
; delete folder entry |
mov byte [edi], 0xE5 |
; delete LFN (if present) |
.lfndel: |
cmp edi, FDD_BUFF |
ja @f |
cmp [fd_prev_sector], 0 |
jz .lfndone |
push [fd_prev_sector] |
push [fd_prev_prev_sector] |
pop [fd_prev_sector] |
and [fd_prev_prev_sector], 0 |
pusha |
call save_chs_sector |
popa |
pop eax |
pusha |
call read_chs_sector |
popa |
mov edi, FDD_BUFF+0x200 |
@@: |
sub edi, 0x20 |
cmp byte [edi], 0xE5 |
jz .lfndone |
cmp byte [edi+11], 0xF |
jnz .lfndone |
mov byte [edi], 0xE5 |
jmp .lfndel |
.lfndone: |
pusha |
call save_chs_sector |
popa |
; delete FAT chain |
pop eax |
test eax, eax |
jz .done |
@@: |
lea eax, [FLOPPY_FAT + eax*2] |
push dword [eax] |
and word [eax], 0 |
pop eax |
and eax, 0xFFF |
jnz @b |
.done: |
call save_flp_fat |
pop edi |
xor eax, eax |
ret |
; \end{diamond} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/fs/fat32.inc |
---|
0,0 → 1,2906 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; FAT32.INC ;; |
;; ;; |
;; FAT16/32 functions for KolibriOS ;; |
;; ;; |
;; Copyright 2002 Paolo Minazzi, paolo.minazzi@inwind.it ;; |
;; ;; |
;; See file COPYING for details ;; |
;; 04.02.2007 LFN create folder - diamond ;; |
;; 08.10.2006 LFN delete file/folder - diamond ;; |
;; 20.08.2006 LFN set file size (truncate/extend) - diamond ;; |
;; 17.08.2006 LFN write/append to file - diamond ;; |
;; 23.06.2006 LFN start application - diamond ;; |
;; 15.06.2006 LFN get/set file/folder info - diamond ;; |
;; 27.05.2006 LFN create/rewrite file - diamond ;; |
;; 04.05.2006 LFN read folder - diamond ;; |
;; 29.04.2006 Elimination of hangup after the ;; |
;; expiration hd_wait_timeout - Mario79 ;; |
;; 23.04.2006 LFN read file - diamond ;; |
;; 28.01.2006 find all Fat16/32 partition in all input point ;; |
;; to MBR, see file part_set.inc - Mario79 ;; |
;; 15.01.2005 get file size/attr/date, file_append - ATV ;; |
;; 04.12.2004 skip volume label, file delete bug fixed - ATV ;; |
;; 29.11.2004 get_free_FAT changed, append dir bug fixed - ATV ;; |
;; 23.11.2004 don't allow overwrite dir with file - ATV ;; |
;; 18.11.2004 get_disk_info and more error codes - ATV ;; |
;; 17.11.2004 set_FAT/get_FAT and disk cache rewritten - ATV ;; |
;; 10.11.2004 removedir clear whole directory structure - ATV ;; |
;; 08.11.2004 rename - ATV ;; |
;; 30.10.2004 file_read return also dirsize in bytes - ATV ;; |
;; 20.10.2004 Makedir/Removedir - ATV ;; |
;; 14.10.2004 Partition chain/Fat16 - ATV (thanks drh3xx) ;; |
;; 06.9.2004 Fix free space by Mario79 added - MH ;; |
;; 24.5.2004 Write back buffer for File_write -VT ;; |
;; 20.5.2004 File_read function to work with syscall 58 - VT ;; |
;; 30.3.2004 Error parameters at function return - VT ;; |
;; 01.5.2002 Bugfix in device write - VT ;; |
;; 20.5.2002 Hd status check - VT ;; |
;; 29.6.2002 Improved fat32 verification - VT ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
cache_max equ 1919 ; max. is 1919*512+0x610000=0x6ffe00 |
ERROR_SUCCESS = 0 |
ERROR_DISK_BASE = 1 |
ERROR_UNSUPPORTED_FS = 2 |
ERROR_UNKNOWN_FS = 3 |
ERROR_PARTITION = 4 |
ERROR_FILE_NOT_FOUND = 5 |
ERROR_END_OF_FILE = 6 |
ERROR_MEMORY_POINTER = 7 |
ERROR_DISK_FULL = 8 |
ERROR_FAT_TABLE = 9 |
ERROR_ACCESS_DENIED = 10 |
PUSHAD_EAX equ [esp+28] |
PUSHAD_ECX equ [esp+24] |
PUSHAD_EDX equ [esp+20] |
PUSHAD_EBX equ [esp+16] |
PUSHAD_EBP equ [esp+8] |
PUSHAD_ESI equ [esp+4] |
PUSHAD_EDI equ [esp+0] |
uglobal |
align 4 |
partition_count dd 0 ; partitions found by set_FAT32_variables |
longname_sec1 dd 0 ; used by analyze_directory to save 2 previous |
longname_sec2 dd 0 ; directory sectors for delete long filename |
hd_error dd 0 ; set by wait_for_sector_buffer |
hd_setup dd 0 |
hd_wait_timeout dd 0 |
cluster_tmp dd 0 ; used by analyze_directory |
; and analyze_directory_to_write |
file_size dd 0 ; used by file_read |
cache_search_start dd 0 ; used by find_empty_slot |
endg |
iglobal |
fat_in_cache dd -1 |
endg |
uglobal |
align 4 |
fat_cache: times 512 db 0 |
Sector512: ; label for dev_hdcd.inc |
buffer: times 512 db 0 |
fsinfo_buffer: times 512 db 0 |
endg |
uglobal |
fat16_root db 0 ; flag for fat16 rootdir |
fat_change db 0 ; 1=fat has changed |
endg |
reserve_hd1: |
cli |
cmp [hd1_status],0 |
je reserve_ok1 |
sti |
call change_task |
jmp reserve_hd1 |
reserve_ok1: |
push eax |
mov eax,[CURRENT_TASK] |
shl eax,5 |
mov eax,[eax+CURRENT_TASK+TASKDATA.pid] |
mov [hd1_status],eax |
pop eax |
sti |
ret |
;******************************************** |
uglobal |
hd_in_cache db ? |
endg |
reserve_hd_channel: |
cmp [hdbase], 0x1F0 |
jne .IDE_Channel_2 |
.IDE_Channel_1: |
cli |
cmp [IDE_Channel_1],0 |
je .reserve_ok_1 |
sti |
call change_task |
jmp .IDE_Channel_1 |
.IDE_Channel_2: |
cli |
cmp [IDE_Channel_2],0 |
je .reserve_ok_2 |
sti |
call change_task |
jmp .IDE_Channel_2 |
.reserve_ok_1: |
mov [IDE_Channel_1], 1 |
push eax |
mov al, 1 |
jmp @f |
.reserve_ok_2: |
mov [IDE_Channel_2], 1 |
push eax |
mov al, 3 |
@@: |
cmp [hdid], 1 |
sbb al, -1 |
cmp al, [hd_in_cache] |
jz @f |
mov [hd_in_cache], al |
call clear_hd_cache |
@@: |
pop eax |
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 [fs_type],16 |
je sfc_1 |
add eax,eax |
sfc_1: |
add eax,eax |
mov esi,511 |
and esi,eax ; esi = position in fat sector |
shr eax,9 ; eax = fat sector |
add eax,[FAT_START] |
mov ebx,fat_cache |
cmp eax,[fat_in_cache] ; is fat sector already in memory? |
je sfc_in_cache ; yes |
cmp [fat_change],0 ; is fat changed? |
je sfc_no_change ; no |
call write_fat_sector ; yes. write it into disk |
cmp [hd_error],0 |
jne sfc_error |
sfc_no_change: |
mov [fat_in_cache],eax ; save fat sector |
call hd_read |
cmp [hd_error],0 |
jne sfc_error |
sfc_in_cache: |
cmp [fs_type],16 |
jne sfc_test32 |
sfc_set16: |
xchg [ebx+esi],dx ; save new value and get old value |
jmp sfc_write |
sfc_test32: |
mov eax,[fatMASK] |
sfc_set32: |
and edx,eax |
xor eax,-1 ; mask for high bits |
and eax,[ebx+esi] ; get high 4 bits |
or eax,edx |
mov edx,[ebx+esi] ; get old value |
mov [ebx+esi],eax ; save new value |
sfc_write: |
mov [fat_change],1 ; fat has changed |
sfc_nonzero: |
and edx,[fatMASK] |
sfc_error: |
pop esi ebx eax |
ret |
get_FAT: |
;-------------------------------- |
; input : EAX = cluster |
; output : EAX = next cluster |
;-------------------------------- |
push ebx esi |
cmp [fs_type],16 |
je gfc_1 |
add eax,eax |
gfc_1: |
add eax,eax |
mov esi,511 |
and esi,eax ; esi = position in fat sector |
shr eax,9 ; eax = fat sector |
add eax,[FAT_START] |
mov ebx,fat_cache |
cmp eax,[fat_in_cache] ; is fat sector already in memory? |
je gfc_in_cache |
cmp [fat_change],0 ; is fat changed? |
je gfc_no_change ; no |
call write_fat_sector ; yes. write it into disk |
cmp [hd_error],0 |
jne hd_error_01 |
gfc_no_change: |
mov [fat_in_cache],eax |
call hd_read |
cmp [hd_error],0 |
jne hd_error_01 |
gfc_in_cache: |
mov eax,[ebx+esi] |
and eax,[fatMASK] |
hd_error_01: |
pop esi ebx |
ret |
get_free_FAT: |
;----------------------------------------------------------- |
; 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 [fs_type],16 |
jne adr_data_cluster |
mov eax,[ROOT_START] |
mov edx,[ROOT_SECTORS] |
mov [fat16_root],1 ; flag for fat16 rootdir |
jmp adr_new_sector |
adr_data_cluster: |
sub eax,2 |
mov edx,[SECTORS_PER_CLUSTER] |
imul eax,edx |
add eax,[DATA_START] |
adr_new_sector: |
mov ebx,buffer |
call hd_read |
cmp [hd_error],0 |
jne adr_not_found |
mov ecx,512/32 ; count of dir entrys per sector = 16 |
adr_analyze: |
mov edi,[ebx+11] ; file attribute |
and edi,0xf |
cmp edi,0xf |
je adr_long_filename |
test edi,0x8 ; skip over volume label |
jne adr_long_filename ; Note: label can be same name as file/dir |
mov esi,[esp+0] ; filename need to be uppercase |
mov edi,ebx |
push ecx |
mov ecx,11 |
cld |
rep cmpsb ; compare 8+3 filename |
pop ecx |
je adr_found |
adr_long_filename: |
add ebx,32 ; position of next dir entry |
dec ecx |
jnz adr_analyze |
mov ecx,[longname_sec1] ; save 2 previous directory sectors |
mov [longname_sec1],eax ; for delete long filename |
mov [longname_sec2],ecx |
inc eax ; next sector |
dec edx |
jne adr_new_sector |
cmp [fat16_root],1 ; end of fat16 rootdir |
je adr_not_found |
adr_next_cluster: |
mov eax,[cluster_tmp] |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne adr_not_found |
cmp eax,2 ; incorrect fat chain? |
jb adr_not_found ; yes |
cmp eax,[fatRESERVED] ; is it end of directory? |
jb adr_new_cluster ; no. analyse it |
adr_not_found: |
pop edi edi esi edx ecx ; first edi will remove ebx |
stc ; file not found |
ret |
adr_found: |
pop edi edi esi edx ecx ; first edi will remove ebx |
clc ; file found |
ret |
get_data_cluster: |
;----------------------------------------------------------- |
; input : EAX = cluster |
; EBX = pointer to buffer |
; EDX = # blocks to read in buffer |
; ESI = # blocks to skip over |
; output : if CARRY=0 ok EBX/EDX/ESI updated |
; if CARRY=1 cluster out of range |
; Note : if cluster=0 it's changed to read rootdir |
;----------------------------------------------------------- |
push eax ecx |
mov [fat16_root],0 |
cmp eax,[LAST_CLUSTER] |
ja gdc_error ; too big cluster number, something is wrong |
cmp eax,2 |
jnb gdc_cluster |
mov eax,[ROOT_CLUSTER] ; if cluster < 2 then read rootdir |
cmp [fs_type],16 |
jne gdc_cluster |
mov eax,[ROOT_START] |
mov ecx,[ROOT_SECTORS] ; Note: not cluster size |
mov [fat16_root],1 ; flag for fat16 rootdir |
jmp gdc_read |
gdc_cluster: |
sub eax,2 |
mov ecx,[SECTORS_PER_CLUSTER] |
imul eax,ecx |
add eax,[DATA_START] |
gdc_read: |
test esi,esi ; first wanted block |
je gdcl1 ; yes, skip count is 0 |
dec esi |
jmp gdcl2 |
gdcl1: |
call hd_read |
cmp [hd_error],0 |
jne gdc_error |
add ebx,512 ; update pointer |
dec edx |
gdcl2: |
test edx,edx ; is all read? |
je out_of_read |
inc eax ; next sector |
dec ecx |
jnz gdc_read |
out_of_read: |
pop ecx eax |
clc |
ret |
gdc_error: |
pop ecx eax |
stc |
ret |
get_cluster_of_a_path: |
;--------------------------------------------------------- |
; input : EBX = pointer to a path string |
; (example: the path "/files/data/document" become |
; "files......data.......document...0" |
; '.' = space char |
; '0' = char(0) (ASCII=0) !!! ) |
; output : if (CARRY=1) -> ERROR in the PATH |
; if (CARRY=0) -> EAX=cluster |
;--------------------------------------------------------- |
push ebx edx |
mov eax,[ROOT_CLUSTER] |
mov edx,ebx |
search_end_of_path: |
cmp byte [edx],0 |
je found_end_of_path |
inc edx ; '/' |
mov ebx,edx |
call analyze_directory |
jc directory_not_found |
mov eax,[ebx+20-2] ; read the HIGH 16bit cluster field |
mov ax,[ebx+26] ; read the LOW 16bit cluster field |
and eax,[fatMASK] |
add edx,11 ; 8+3 (name+extension) |
jmp search_end_of_path |
found_end_of_path: |
pop edx ebx |
clc ; no errors |
ret |
directory_not_found: |
pop edx ebx |
stc ; errors occour |
ret |
bcd2bin: |
;---------------------------------- |
; input : AL=BCD number (eg. 0x11) |
; output : AH=0 |
; AL=decimal number (eg. 11) |
;---------------------------------- |
xor ah,ah |
shl ax,4 |
shr al,4 |
aad |
ret |
get_date_for_file: |
;----------------------------------------------------- |
; Get date from CMOS and pack day,month,year in AX |
; DATE bits 0..4 : day of month 0..31 |
; 5..8 : month of year 1..12 |
; 9..15 : count of years from 1980 |
;----------------------------------------------------- |
mov al,0x7 ;day |
out 0x70,al |
in al,0x71 |
call bcd2bin |
ror eax,5 |
mov al,0x8 ;month |
out 0x70,al |
in al,0x71 |
call bcd2bin |
ror eax,4 |
mov al,0x9 ;year |
out 0x70,al |
in al,0x71 |
call bcd2bin |
add ax,20 ;because CMOS return only the two last |
;digit (eg. 2000 -> 00 , 2001 -> 01) and we |
rol eax,9 ;need the difference with 1980 (eg. 2001-1980) |
ret |
get_time_for_file: |
;----------------------------------------------------- |
; Get time from CMOS and pack hour,minute,second in AX |
; TIME bits 0..4 : second (the low bit is lost) |
; 5..10 : minute 0..59 |
; 11..15 : hour 0..23 |
;----------------------------------------------------- |
mov al,0x0 ;second |
out 0x70,al |
in al,0x71 |
call bcd2bin |
ror eax,6 |
mov al,0x2 ;minute |
out 0x70,al |
in al,0x71 |
call bcd2bin |
ror eax,6 |
mov al,0x4 ;hour |
out 0x70,al |
in al,0x71 |
call bcd2bin |
rol eax,11 |
ret |
set_current_time_for_entry: |
;----------------------------------------------------- |
; Set current time/date for file entry |
; input : ebx = file entry pointer |
;----------------------------------------------------- |
push eax |
call get_time_for_file ; update files date/time |
mov [ebx+22],ax |
call get_date_for_file |
mov [ebx+24],ax |
pop eax |
ret |
add_disk_free_space: |
;----------------------------------------------------- |
; input : ecx = cluster count |
; Note : negative = remove clusters from free space |
; positive = add clusters to free space |
;----------------------------------------------------- |
test ecx,ecx ; no change |
je add_dfs_no |
cmp [fs_type],32 ; free disk space only used by fat32 |
jne add_dfs_no |
push eax ebx |
mov eax,[ADR_FSINFO] |
mov ebx,fsinfo_buffer |
call hd_read |
cmp [hd_error],0 |
jne add_not_fs |
cmp dword [ebx+0x1fc],0xaa550000 ; check sector id |
jne add_not_fs |
add [ebx+0x1e8],ecx |
call hd_write |
; cmp [hd_error],0 |
; jne add_not_fs |
add_not_fs: |
pop ebx eax |
add_dfs_no: |
ret |
file_read: |
;-------------------------------------------------------------------------- |
; INPUT : user-register register-in-this meaning symbol-in-this |
; |
; EAX EDI system call to write / |
; EBX EAX (PAR0) pointer to file-name PAR0 |
; EDX ECX (PAR1) pointer to buffer PAR1 |
; ECX EBX (PAR2) vt file blocks to read PAR2 |
; ESI EDX (PAR3) pointer to path PAR3 |
; EDI ESI vt first 512 block to read |
; EDI if 0 - read root |
; |
; output : eax = 0 - ok |
; 3 - unknown FS |
; 5 - file not found |
; 6 - end of file |
; 9 - fat table corrupted |
; 10 - access denied |
; ebx = size of file/directory |
;-------------------------------------------------------------------------- |
cmp [fs_type], 16 |
jz fat_ok_for_reading |
cmp [fs_type], 32 |
jz fat_ok_for_reading |
xor ebx,ebx |
mov eax,ERROR_UNKNOWN_FS |
mov [hd1_status], ebx |
ret |
fat_ok_for_reading: |
; call reserve_hd1 |
pushad |
mov ebx,edx |
call get_cluster_of_a_path |
jc file_to_read_not_found |
test edi,edi ; read rootdir |
jne no_read_root |
xor eax,eax |
call get_dir_size ; return rootdir size |
cmp [hd_error],0 |
jne file_access_denied |
mov [file_size],eax |
mov eax,[ROOT_CLUSTER] |
jmp file_read_start |
no_read_root: |
mov ebx,PUSHAD_EAX ; file name |
call analyze_directory |
jc file_to_read_not_found |
mov eax,[ebx+28] ; file size |
test byte [ebx+11],0x10 ; is it directory? |
jz read_set_size ; no |
mov eax,[ebx+20-2] ; FAT entry |
mov ax,[ebx+26] |
and eax,[fatMASK] |
call get_dir_size |
cmp [hd_error],0 |
jne file_access_denied |
read_set_size: |
mov [file_size],eax |
mov eax,[ebx+20-2] ; FAT entry |
mov ax,[ebx+26] |
and eax,[fatMASK] |
file_read_start: |
mov ebx,PUSHAD_ECX ; pointer to buffer |
mov edx,PUSHAD_EBX ; file blocks to read |
mov esi,PUSHAD_ESI ; first 512 block to read |
file_read_new_cluster: |
call get_data_cluster |
jc file_read_eof ; end of file or cluster out of range |
test edx,edx ; is all read? |
je file_read_OK ; yes |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne file_access_denied |
cmp eax,[fatRESERVED] ; end of file |
jnb file_read_eof |
cmp eax,2 ; incorrect fat chain |
jnb file_read_new_cluster |
popad |
mov [hd1_status],0 |
mov ebx,[file_size] |
mov eax,ERROR_FAT_TABLE |
ret |
file_read_eof: |
cmp [hd_error],0 |
jne file_access_denied |
popad |
mov [hd1_status],0 |
mov ebx,[file_size] |
mov eax,ERROR_END_OF_FILE |
ret |
file_read_OK: |
popad |
mov [hd1_status],0 |
mov ebx,[file_size] |
xor eax,eax |
ret |
file_to_read_not_found: |
cmp [hd_error],0 |
jne file_access_denied |
popad |
mov [hd1_status],0 |
xor ebx,ebx |
mov eax,ERROR_FILE_NOT_FOUND |
ret |
file_access_denied: |
popad |
mov [hd1_status],0 |
xor ebx,ebx |
mov eax,ERROR_ACCESS_DENIED |
ret |
get_dir_size: |
;----------------------------------------------------- |
; input : eax = first cluster (0=rootdir) |
; output : eax = directory size in bytes |
;----------------------------------------------------- |
push edx |
xor edx,edx ; count of directory clusters |
test eax,eax |
jnz dir_size_next |
mov eax,[ROOT_SECTORS] |
shl eax,9 ; fat16 rootdir size in bytes |
cmp [fs_type],16 |
je dir_size_ret |
mov eax,[ROOT_CLUSTER] |
dir_size_next: |
cmp eax,2 ; incorrect fat chain |
jb dir_size_end |
cmp eax,[fatRESERVED] ; end of directory |
ja dir_size_end |
call get_FAT ; get next cluster |
cmp [hd_error],0 |
jne dir_size_ret |
inc edx |
jmp dir_size_next |
dir_size_end: |
imul eax,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes |
imul eax,edx |
dir_size_ret: |
pop edx |
ret |
clear_cluster_chain: |
;----------------------------------------------------- |
; input : eax = first cluster |
;----------------------------------------------------- |
push eax ecx edx |
xor ecx,ecx ; cluster count |
clean_new_chain: |
cmp eax,[LAST_CLUSTER] ; end of file |
ja delete_OK |
cmp eax,2 ; unfinished fat chain or zero length file |
jb delete_OK |
cmp eax,[ROOT_CLUSTER] ; don't remove root cluster |
jz delete_OK |
xor edx,edx |
call set_FAT ; clear fat entry |
cmp [hd_error],0 |
jne access_denied_01 |
inc ecx ; update cluster count |
mov eax,edx ; old cluster |
jmp clean_new_chain |
delete_OK: |
call add_disk_free_space ; add clusters to free disk space |
access_denied_01: |
pop edx ecx eax |
ret |
get_hd_info: |
;----------------------------------------------------------- |
; output : eax = 0 - ok |
; 3 - unknown FS |
; 10 - access denied |
; edx = cluster size in bytes |
; ebx = total clusters on disk |
; ecx = free clusters on disk |
;----------------------------------------------------------- |
cmp [fs_type], 16 |
jz info_fat_ok |
cmp [fs_type], 32 |
jz info_fat_ok |
xor edx,edx |
xor ebx,ebx |
xor ecx,ecx |
mov eax,ERROR_UNKNOWN_FS |
ret |
info_fat_ok: |
; call reserve_hd1 |
xor ecx,ecx ; count of free clusters |
mov eax,2 |
mov ebx,[LAST_CLUSTER] |
info_cluster: |
push eax |
call get_FAT ; get cluster info |
cmp [hd_error],0 |
jne info_access_denied |
test eax,eax ; is it free? |
jnz info_used ; no |
inc ecx |
info_used: |
pop eax |
inc eax |
cmp eax,ebx ; is above last cluster? |
jbe info_cluster ; no. test next cluster |
dec ebx ; cluster count |
imul edx,[SECTORS_PER_CLUSTER],512 ; cluster size in bytes |
mov [hd1_status],0 |
xor eax,eax |
ret |
info_access_denied: |
add esp,4 |
xor edx,edx |
xor ebx,ebx |
xor ecx,ecx |
mov eax,ERROR_ACCESS_DENIED |
ret |
update_disk: |
;----------------------------------------------------------- |
; write changed fat and cache to disk |
;----------------------------------------------------------- |
cmp [fat_change],0 ; is fat changed? |
je upd_no_change |
call write_fat_sector |
cmp [hd_error],0 |
jne update_disk_acces_denied |
upd_no_change: |
call write_cache |
update_disk_acces_denied: |
ret |
; \begin{diamond} |
hd_find_lfn: |
; in: esi+ebp -> name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry, eax=sector |
; destroys eax |
push esi edi |
push 0 |
push 0 |
push fat16_root_first |
push fat16_root_next |
mov eax, [ROOT_CLUSTER] |
cmp [fs_type], 32 |
jz .fat32 |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
.continue: |
test byte [edi+11], 10h |
jz .notfound |
and dword [esp+12], 0 |
mov eax, [edi+20-2] |
mov ax, [edi+26] ; cluster |
.fat32: |
mov [esp+8], eax |
mov dword [esp+4], fat_notroot_first |
mov dword [esp], fat_notroot_next |
jmp .loop |
.notfound: |
add esp, 16 |
pop edi esi |
stc |
ret |
.found: |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
jmp .continue |
@@: |
lea eax, [esp+8] |
cmp dword [eax], 0 |
jz .root |
call fat_get_sector |
jmp .cmn |
.root: |
mov eax, [eax+4] |
add eax, [ROOT_START] |
.cmn: |
add esp, 20 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
; |
; fs_HdRead - LFN variant for reading hard disk |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_HdRead: |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
cmp [fs_type], 1 |
jz ntfs_HdRead |
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: |
cmp [fs_type], 1 |
jz ntfs_HdReadFolder |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
push ERROR_UNSUPPORTED_FS |
pop eax |
or ebx, -1 |
ret |
@@: |
mov eax, [ROOT_CLUSTER] |
push edi |
cmp byte [esi], 0 |
jz .doit |
call hd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 ; do not allow read files |
jnz .found_dir |
pop edi |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
mov eax, [edi+20-2] |
mov ax, [edi+26] ; eax=cluster |
.doit: |
push esi ecx |
push ebp |
sub esp, 262*2 ; reserve space for LFN |
mov ebp, esp |
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE name |
mov ebx, [ebx] |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
pop ecx eax |
mov byte [edx], 1 ; version |
mov esi, edi ; esi points to BDFE |
.new_cluster: |
mov [cluster_tmp], eax |
test eax, eax |
jnz @f |
cmp [fs_type], 32 |
jz .notfound |
mov eax, [ROOT_START] |
push [ROOT_SECTORS] |
push ebx |
jmp .new_sector |
@@: |
dec eax |
dec eax |
imul eax, [SECTORS_PER_CLUSTER] |
push [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
push ebx |
.new_sector: |
mov ebx, buffer |
mov edi, ebx |
call hd_read |
cmp [hd_error], 0 |
jnz .notfound2 |
add ebx, 512 |
push eax |
.l1: |
call fat_get_name |
jc .l2 |
cmp byte [edi+11], 0xF |
jnz .do_bdfe |
add edi, 0x20 |
cmp edi, ebx |
jb .do_bdfe |
pop eax |
inc eax |
dec dword [esp+4] |
jnz @f |
mov eax, [cluster_tmp] |
test eax, eax |
jz .done |
call get_FAT |
cmp [hd_error], 0 |
jnz .notfound2 |
cmp eax, 2 |
jb .done |
cmp eax, [fatRESERVED] |
jae .done |
push eax |
mov eax, [SECTORS_PER_CLUSTER] |
mov [esp+8], eax |
pop eax |
mov [cluster_tmp], eax |
dec eax |
dec eax |
imul eax, [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
@@: |
mov ebx, buffer |
mov edi, ebx |
call hd_read |
cmp [hd_error], 0 |
jnz .notfound2 |
add ebx, 512 |
push eax |
.do_bdfe: |
inc dword [edx+8] ; new file found |
dec dword [esp+4] |
jns .l2 |
dec ecx |
js .l2 |
inc dword [edx+4] ; new file block copied |
call fat_entry_to_bdfe |
.l2: |
add edi, 0x20 |
cmp edi, ebx |
jb .l1 |
pop eax |
inc eax |
dec dword [esp+4] |
jnz .new_sector |
mov eax, [cluster_tmp] |
test eax, eax |
jz .done |
call get_FAT |
cmp [hd_error], 0 |
jnz .notfound2 |
cmp eax, 2 |
jb .done |
cmp eax, [fatRESERVED] |
jae .done |
push eax |
mov eax, [SECTORS_PER_CLUSTER] |
mov [esp+8], eax |
pop eax |
pop ebx |
add esp, 4 |
jmp .new_cluster |
.notfound2: |
add esp, 8 |
.notfound: |
add esp, 262*2+4 |
pop ebp ecx esi edi |
mov eax, ERROR_FILE_NOT_FOUND |
or ebx, -1 |
ret |
.done: |
add esp, 262*2+4+8 |
pop ebp |
mov ebx, [edx+4] |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx esi edi |
ret |
fat16_root_next: |
cmp edi, buffer+0x200-0x20 |
jae fat16_root_next_sector |
add edi, 0x20 |
ret ; CF=0 |
fat16_root_next_sector: |
; read next sector |
push [longname_sec2] |
pop [longname_sec1] |
push ecx |
mov ecx, [eax+4] |
push ecx |
add ecx, [ROOT_START] |
mov [longname_sec2], ecx |
pop ecx |
inc ecx |
mov [eax+4], ecx |
cmp ecx, [ROOT_SECTORS] |
pop ecx |
jae fat16_root_first.readerr |
fat16_root_first: |
mov eax, [eax+4] |
add eax, [ROOT_START] |
push ebx |
mov edi, buffer |
mov ebx, edi |
call hd_read |
pop ebx |
cmp [hd_error], 0 |
jnz .readerr |
ret ; CF=0 |
.readerr: |
stc |
ret |
fat16_root_begin_write: |
push edi eax |
call fat16_root_first |
pop eax edi |
ret |
fat16_root_end_write: |
pusha |
mov eax, [eax+4] |
add eax, [ROOT_START] |
mov ebx, buffer |
call hd_write |
popa |
ret |
fat16_root_next_write: |
cmp edi, buffer+0x200 |
jae @f |
ret |
@@: |
call fat16_root_end_write |
jmp fat16_root_next_sector |
fat16_root_extend_dir: |
stc |
ret |
fat_notroot_next: |
cmp edi, buffer+0x200-0x20 |
jae fat_notroot_next_sector |
add edi, 0x20 |
ret ; CF=0 |
fat_notroot_next_sector: |
push [longname_sec2] |
pop [longname_sec1] |
push eax |
call fat_get_sector |
mov [longname_sec2], eax |
pop eax |
push ecx |
mov ecx, [eax+4] |
inc ecx |
cmp ecx, [SECTORS_PER_CLUSTER] |
jae fat_notroot_next_cluster |
mov [eax+4], ecx |
jmp @f |
fat_notroot_next_cluster: |
push eax |
mov eax, [eax] |
call get_FAT |
mov ecx, eax |
pop eax |
cmp [hd_error], 0 |
jnz fat_notroot_next_err |
cmp ecx, [fatRESERVED] |
jae fat_notroot_next_err |
mov [eax], ecx |
and dword [eax+4], 0 |
@@: |
pop ecx |
fat_notroot_first: |
call fat_get_sector |
push ebx |
mov edi, buffer |
mov ebx, edi |
call hd_read |
pop ebx |
cmp [hd_error], 0 |
jnz @f |
ret ; CF=0 |
fat_notroot_next_err: |
pop ecx |
@@: |
stc |
ret |
fat_notroot_begin_write: |
push eax edi |
call fat_notroot_first |
pop edi eax |
ret |
fat_notroot_end_write: |
call fat_get_sector |
push ebx |
mov ebx, buffer |
call hd_write |
pop ebx |
ret |
fat_notroot_next_write: |
cmp edi, buffer+0x200 |
jae @f |
ret |
@@: |
push eax |
call fat_notroot_end_write |
pop eax |
jmp fat_notroot_next_sector |
fat_notroot_extend_dir: |
push eax |
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_HdCreateFolder: |
mov al, 1 |
jmp fs_HdRewrite.common |
fs_HdRewrite: |
xor eax, eax |
.common: |
cmp [fs_type], 1 |
jz ntfs_HdRewrite |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jnz fshrfs |
@@: |
cmp byte [esi], 0 |
jz fshrad |
pushad |
xor edi, edi |
push esi |
test ebp, ebp |
jz @f |
mov esi, ebp |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea edi, [esi-1] |
jmp @b |
@@: |
pop esi |
test edi, edi |
jnz .noroot |
test ebp, ebp |
jnz .hasebp |
mov ebp, [ROOT_CLUSTER] |
cmp [fs_type], 32 |
jz .pushnotroot |
push fat16_root_extend_dir |
push fat16_root_end_write |
push fat16_root_next_write |
push fat16_root_begin_write |
xor ebp, ebp |
push ebp |
push ebp |
push fat16_root_first |
push fat16_root_next |
jmp .common1 |
.hasebp: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [ebp], 0 |
jz .ret1 |
push ebp |
xor ebp, ebp |
call hd_find_lfn |
pop esi |
jc .notfound0 |
jmp .common0 |
.noroot: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [edi+1], 0 |
jz .ret1 |
; check existence |
mov byte [edi], 0 |
push edi |
call hd_find_lfn |
pop esi |
mov byte [esi], '/' |
jnc @f |
.notfound0: |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
inc esi |
.common0: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
mov ebp, [edi+20-2] |
mov bp, [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
.pushnotroot: |
push fat_notroot_extend_dir |
push fat_notroot_end_write |
push fat_notroot_next_write |
push fat_notroot_begin_write |
push 0 |
push ebp |
push fat_notroot_first |
push fat_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found |
test byte [edi+11], 10h |
jz .exists_file |
; found directory; if we are creating directory, return OK, |
; if we are creating file, say "access denied" |
add esp, 32 |
popad |
test al, al |
mov eax, ERROR_ACCESS_DENIED |
jz @f |
mov al, 0 |
@@: |
xor ebx, ebx |
ret |
.exists_file: |
; found file; if we are creating directory, return "access denied", |
; if we are creating file, delete existing file and continue |
cmp byte [esp+32+28], 0 |
jz @f |
add esp, 32 |
popad |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
@@: |
; delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xor ecx, ecx |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
mov word [edi+20], cx |
mov word [edi+26], cx |
test eax, eax |
jz .done1 |
@@: |
cmp eax, [fatRESERVED] |
jae .done1 |
push edx |
xor edx, edx |
call set_FAT |
mov eax, edx |
pop edx |
inc ecx |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 32 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
and dword [eax+4], 0 |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+32 |
popa |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
push -1 |
; find <eax> successive entries in directory |
xor ecx, ecx |
push eax |
lea eax, [esp+16+8+12+8] |
mov [eax], ebp |
and dword [eax+4], 0 |
call dword [eax-4] |
pop eax |
jnc .scan_dir |
.fsfrfe3: |
add esp, 12+8+12+32 |
popad |
mov eax, 11 |
xor ebx, ebx |
ret |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
push eax |
lea eax, [esp+16+8+12+8] |
call dword [eax-8] |
pop eax |
jnc .scan_dir |
cmp [hd_error], 0 |
jnz .fsfrfe3 |
push eax |
lea eax, [esp+16+8+12+8] |
call dword [eax+20] ; extend directory |
pop eax |
jnc .scan_dir |
add esp, 12+8+12+32 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.free: |
test ecx, ecx |
jnz @f |
mov [esp], edi |
mov ecx, [esp+12+8+12+8] |
mov [esp+4], ecx |
mov ecx, [esp+12+8+12+12] |
mov [esp+8], ecx |
xor ecx, ecx |
@@: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8+12] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop dword [esp+8+12+12] |
pop dword [esp+8+12+12] |
; edi points to first entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
lea eax, [esp+8+8+12+8] |
call dword [eax+8] ; begin write |
mov al, 40h |
.writelfn: |
or al, cl |
mov esi, [esp+4] |
push ecx |
dec ecx |
imul ecx, 13 |
add esi, ecx |
stosb |
mov cl, 5 |
call fs_RamdiskRewrite.read_symbols |
mov ax, 0xF |
stosw |
mov al, [esp+4] |
stosb |
mov cl, 6 |
call fs_RamdiskRewrite.read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call fs_RamdiskRewrite.read_symbols |
pop ecx |
lea eax, [esp+8+8+12+8] |
call dword [eax+12] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
; lea eax, [esp+8+12+8] |
; call dword [eax+16] ; end write |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
xor ecx, ecx |
mov word [edi+20], cx ; high word of cluster |
mov word [edi+26], cx ; low word of cluster - to be filled |
mov dword [edi+28], ecx ; file size - to be filled |
cmp byte [esp+32+28], cl |
jz .doit |
; create directory |
mov byte [edi+11], 10h ; attributes: folder |
mov edx, edi |
lea eax, [esp+8] |
call dword [eax+16] ; flush directory |
push ecx |
mov ecx, [SECTORS_PER_CLUSTER] |
shl ecx, 9 |
jmp .doit2 |
.doit: |
lea eax, [esp+8] |
call dword [eax+16] ; flush directory |
push ecx |
mov ecx, [esp+4+32+24] |
.doit2: |
push ecx |
push edi |
mov esi, edx |
test ecx, ecx |
jz .done |
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: |
cmp byte [esp+16+32+28], 0 |
jnz .writedir |
mov ecx, 512 |
cmp dword [esp+8], ecx |
jb .writeshort |
; we can write directly from given buffer |
mov ebx, esi |
add esi, ecx |
jmp .writecommon |
.writeshort: |
mov ecx, [esp+8] |
push ecx |
mov edi, buffer |
mov ebx, edi |
rep movsb |
.writedircont: |
mov ecx, buffer+0x200 |
sub ecx, edi |
push eax |
xor eax, eax |
rep stosb |
pop eax |
pop ecx |
.writecommon: |
call hd_write |
cmp [hd_error], 0 |
jnz .writeerr |
inc eax |
sub dword [esp+8], ecx |
jz .writedone |
dec ebp |
jnz .write_sector |
; allocate new cluster |
pop eax |
mov ecx, eax |
call get_free_FAT |
jc .diskfull |
push edx |
mov edx, [fatEND] |
call set_FAT |
xchg eax, ecx |
mov edx, ecx |
call set_FAT |
pop edx |
xchg eax, ecx |
jmp .write_cluster |
.diskfull: |
mov eax, ERROR_DISK_FULL |
jmp .ret |
.writeerr: |
pop eax |
sub esi, ecx |
mov eax, 11 |
jmp .ret |
.writedone: |
pop eax |
.done: |
xor eax, eax |
.ret: |
pop edi ecx |
mov ebx, esi |
sub ebx, edx |
pop ebp |
mov [esp+32+28], eax |
lea eax, [esp+8] |
call dword [eax+8] |
mov [edi+28], ebx |
call dword [eax+16] |
mov [esp+32+16], ebx |
lea eax, [ebx+511] |
shr eax, 9 |
mov ecx, [SECTORS_PER_CLUSTER] |
lea eax, [eax+ecx-1] |
xor edx, edx |
div ecx |
mov ecx, ebp |
sub ecx, eax |
call add_disk_free_space |
add esp, 32 |
call update_disk |
popad |
ret |
.writedir: |
push 512 |
mov edi, buffer |
mov ebx, edi |
mov ecx, [SECTORS_PER_CLUSTER] |
shl ecx, 9 |
cmp ecx, [esp+12] |
jnz .writedircont |
dec dword [esp+16] |
push esi |
mov ecx, 32/4 |
rep movsd |
pop esi |
mov dword [edi-32], '. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
push esi |
mov ecx, 32/4 |
rep movsd |
pop esi |
mov dword [edi-32], '.. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
mov ecx, [esp+20+8] |
cmp ecx, [ROOT_CLUSTER] |
jnz @f |
xor ecx, ecx |
@@: |
mov word [edi-32+26], cx |
shr ecx, 16 |
mov [edi-32+20], cx |
jmp .writedircont |
;---------------------------------------------------------------- |
; |
; fs_HdWrite - LFN variant for writing to hard disk |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = bytes written (maybe 0) |
; eax = 0 ok write or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_HdWrite.access_denied: |
push ERROR_ACCESS_DENIED |
fs_HdWrite.ret0: |
pop eax |
xor ebx, ebx |
ret |
fs_HdWrite.ret11: |
push 11 |
jmp fs_HdWrite.ret0 |
fs_HdWrite: |
cmp [fs_type], 1 |
jz ntfs_HdWrite |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
push ERROR_UNKNOWN_FS |
jmp .ret0 |
@@: |
cmp byte [esi], 0 |
jz .access_denied |
pushad |
call hd_find_lfn |
pushfd |
cmp [hd_error], 0 |
jz @f |
popfd |
popad |
push 11 |
jmp .ret0 |
@@: |
popfd |
jnc .found |
popad |
push ERROR_FILE_NOT_FOUND |
jmp .ret0 |
.found: |
; FAT does not support files larger than 4GB |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
.eof: |
popad |
push ERROR_END_OF_FILE |
jmp .ret0 |
@@: |
mov ebx, [ebx] |
.l1: |
; now edi points to direntry, ebx=start byte to write, |
; ecx=number of bytes to write, edx=data pointer |
; extend file if needed |
add ecx, ebx |
jc .eof ; FAT does not support files larger than 4GB |
push eax ; save directory sector |
push 0 ; return value=0 |
call get_time_for_file |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
push dword [edi+28] ; save current file size |
cmp ecx, [edi+28] |
jbe .length_ok |
cmp ecx, ebx |
jz .length_ok |
call hd_extend_file |
jnc .length_ok |
mov [esp+4], eax |
; hd_extend_file can return three error codes: FAT table error, device error or disk full. |
; First two cases are fatal errors, in third case we may write some data |
cmp al, ERROR_DISK_FULL |
jz .disk_full |
pop eax |
pop eax |
mov [esp+4+28], eax |
pop eax |
popad |
xor ebx, ebx |
ret |
.disk_full: |
; correct number of bytes to write |
mov ecx, [edi+28] |
cmp ecx, ebx |
ja .length_ok |
.ret: |
call update_disk |
cmp [hd_error], 0 |
jz @f |
mov byte [esp+4], 11 |
@@: |
pop eax |
pop eax |
mov [esp+4+28], eax ; eax=return value |
pop eax |
sub edx, [esp+20] |
mov [esp+16], edx ; ebx=number of written bytes |
popad |
ret |
.length_ok: |
mov esi, [edi+28] |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
mov edi, eax ; edi=current cluster |
xor ebp, ebp ; ebp=current sector in cluster |
; save directory |
mov eax, [esp+8] |
push ebx |
mov ebx, buffer |
call hd_write |
pop ebx |
cmp [hd_error], 0 |
jz @f |
.device_err: |
mov byte [esp+4], 11 |
jmp .ret |
@@: |
; now ebx=start pos, ecx=end pos, both lie inside file |
sub ecx, ebx |
jz .ret |
.write_loop: |
; skip unmodified sectors |
cmp dword [esp], 0x200 |
jb .modify |
sub ebx, 0x200 |
jae .skip |
add ebx, 0x200 |
.modify: |
; get length of data in current sector |
push ecx |
sub ebx, 0x200 |
jb .hasdata |
neg ebx |
xor ecx, ecx |
jmp @f |
.hasdata: |
neg ebx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
; get current sector number |
mov eax, edi |
dec eax |
dec eax |
imul eax, [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
add eax, ebp |
; load sector if needed |
cmp dword [esp+4], 0 ; we don't need to read uninitialized data |
jz .noread |
cmp ecx, 0x200 ; we don't need to read sector if it is fully rewritten |
jz .noread |
cmp ecx, esi ; (same for the last sector) |
jz .noread |
push ebx |
mov ebx, buffer |
call hd_read |
pop ebx |
cmp [hd_error], 0 |
jz @f |
.device_err2: |
pop ecx |
jmp .device_err |
@@: |
.noread: |
; zero uninitialized data if file was extended (because hd_extend_file does not this) |
push eax ecx edi |
xor eax, eax |
mov ecx, 0x200 |
sub ecx, [esp+4+12] |
jbe @f |
mov edi, buffer |
add edi, [esp+4+12] |
rep stosb |
@@: |
; zero uninitialized data in the last sector |
mov ecx, 0x200 |
sub ecx, esi |
jbe @f |
mov edi, buffer |
add edi, esi |
rep stosb |
@@: |
pop edi ecx |
; copy new data |
mov eax, edx |
neg ebx |
jecxz @f |
add ebx, buffer+0x200 |
call memmove |
xor ebx, ebx |
@@: |
pop eax |
; save sector |
push ebx |
mov ebx, buffer |
call hd_write |
pop ebx |
cmp [hd_error], 0 |
jnz .device_err2 |
add edx, ecx |
sub [esp], ecx |
pop ecx |
jz .ret |
.skip: |
; next sector |
inc ebp |
cmp ebp, [SECTORS_PER_CLUSTER] |
jb @f |
xor ebp, ebp |
mov eax, edi |
call get_FAT |
mov edi, eax |
cmp [hd_error], 0 |
jnz .device_err |
@@: |
sub esi, 0x200 |
jae @f |
xor esi, esi |
@@: |
sub dword [esp], 0x200 |
jae @f |
and dword [esp], 0 |
@@: jmp .write_loop |
hd_extend_file.zero_size: |
xor eax, eax |
jmp hd_extend_file.start_extend |
; extends file on hd to given size (new data area is undefined) |
; in: edi->direntry, ecx=new size |
; out: CF=0 => OK, eax=0 |
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL or 11) |
hd_extend_file: |
push ebp |
mov ebp, [SECTORS_PER_CLUSTER] |
imul ebp, [BYTES_PER_SECTOR] |
push ecx |
; find the last cluster of file |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
mov ecx, [edi+28] |
jecxz .zero_size |
.last_loop: |
sub ecx, ebp |
jbe .last_found |
call get_FAT |
cmp [hd_error], 0 |
jz @f |
.device_err: |
pop ecx |
.device_err2: |
pop ebp |
push 11 |
.ret_err: |
pop eax |
stc |
ret |
@@: |
cmp eax, 2 |
jb .fat_err |
cmp eax, [fatRESERVED] |
jb .last_loop |
.fat_err: |
pop ecx ebp |
push ERROR_FAT_TABLE |
jmp .ret_err |
.last_found: |
push eax |
call get_FAT |
cmp [hd_error], 0 |
jz @f |
pop eax |
jmp .device_err |
@@: |
cmp eax, [fatRESERVED] |
pop eax |
jb .fat_err |
; set length to full number of clusters |
sub [edi+28], ecx |
.start_extend: |
pop ecx |
; now do extend |
push edx |
mov edx, 2 ; start scan from cluster 2 |
.extend_loop: |
cmp [edi+28], ecx |
jae .extend_done |
; add new cluster |
push eax |
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 [fs_type], 1 |
jz ntfs_HdSetFileEnd |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
push ERROR_UNKNOWN_FS |
.ret: |
pop eax |
ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
.access_denied: |
push ERROR_ACCESS_DENIED |
jmp .ret |
@@: |
push edi |
call hd_find_lfn |
pushfd |
cmp [hd_error], 0 |
jz @f |
popfd |
push 11 |
jmp .ret |
@@: |
popfd |
jnc @f |
pop edi |
push ERROR_FILE_NOT_FOUND |
jmp .ret |
@@: |
; must not be directory |
test byte [edi+11], 10h |
jz @f |
pop edi |
jmp .access_denied |
@@: |
; file size must not exceed 4 Gb |
cmp dword [ebx+4], 0 |
jz @f |
pop edi |
push ERROR_END_OF_FILE |
jmp .ret |
@@: |
push eax ; save directory sector |
; set file modification date/time to current |
call fat_update_datetime |
mov eax, [ebx] |
cmp eax, [edi+28] |
jb .truncate |
ja .expand |
pop eax |
mov ebx, buffer |
call hd_write |
pop edi |
xor eax, eax |
cmp [hd_error], 0 |
jz @f |
mov al, 11 |
@@: |
ret |
.expand: |
push ebx ebp ecx |
push dword [edi+28] ; save old size |
mov ecx, eax |
call hd_extend_file |
push eax ; return code |
jnc .expand_ok |
cmp al, ERROR_DISK_FULL |
jz .disk_full |
.pop_ret: |
call update_disk |
pop eax ecx ebp ebx ecx edi edi |
ret |
.expand_ok: |
.disk_full: |
; save directory |
mov eax, [edi+28] |
xchg eax, [esp+20] |
mov ebx, buffer |
call hd_write |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
mov edi, eax |
cmp [hd_error], 0 |
jz @f |
.pop_ret11: |
mov byte [esp], 11 |
jmp .pop_ret |
@@: |
; now zero new data |
xor ebp, ebp |
; edi=current cluster, ebp=sector in cluster |
; [esp+20]=new size, [esp+4]=old size, [esp]=return code |
.zero_loop: |
sub dword [esp+4], 0x200 |
jae .next_cluster |
lea eax, [edi-2] |
imul eax, [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
add eax, ebp |
cmp dword [esp+4], -0x200 |
jz .noread |
mov ebx, buffer |
call hd_read |
cmp [hd_error], 0 |
jnz .err_next |
.noread: |
mov ecx, [esp+4] |
neg ecx |
push edi |
mov edi, buffer+0x200 |
add edi, [esp+8] |
push eax |
xor eax, eax |
mov [esp+12], eax |
rep stosb |
pop eax |
pop edi |
call hd_write |
cmp [hd_error], 0 |
jz .next_cluster |
.err_next: |
mov byte [esp], 11 |
.next_cluster: |
sub dword [esp+20], 0x200 |
jbe .pop_ret |
inc ebp |
cmp ebp, [SECTORS_PER_CLUSTER] |
jb .zero_loop |
xor ebp, ebp |
mov eax, edi |
call get_FAT |
mov edi, eax |
cmp [hd_error], 0 |
jnz .pop_ret11 |
jmp .zero_loop |
.truncate: |
mov [edi+28], eax |
push ecx |
mov ecx, [edi+20-2] |
mov cx, [edi+26] |
push eax |
test eax, eax |
jz .zero_size |
; find new last cluster |
@@: |
mov eax, [SECTORS_PER_CLUSTER] |
shl eax, 9 |
sub [esp], eax |
jbe @f |
mov eax, ecx |
call get_FAT |
mov ecx, eax |
cmp [hd_error], 0 |
jz @b |
.device_err3: |
pop eax ecx eax edi |
push 11 |
pop eax |
ret |
@@: |
; we will zero data at the end of last sector - remember it |
push ecx |
; terminate FAT chain |
push edx |
mov eax, ecx |
mov edx, [fatEND] |
call set_FAT |
mov eax, edx |
pop edx |
cmp [hd_error], 0 |
jz @f |
.device_err4: |
pop ecx |
jmp .device_err3 |
.zero_size: |
and word [edi+20], 0 |
and word [edi+26], 0 |
push 0 |
mov eax, ecx |
@@: |
; delete FAT chain |
call clear_cluster_chain |
cmp [hd_error], 0 |
jnz .device_err4 |
; save directory |
mov eax, [esp+12] |
push ebx |
mov ebx, buffer |
call hd_write |
pop ebx |
cmp [hd_error], 0 |
jnz .device_err4 |
; zero last sector, ignore errors |
pop ecx |
pop eax |
dec ecx |
imul ecx, [SECTORS_PER_CLUSTER] |
add ecx, [DATA_START] |
push eax |
sar eax, 9 |
add ecx, eax |
pop eax |
and eax, 0x1FF |
jz .truncate_done |
push ebx eax |
mov eax, ecx |
mov ebx, buffer |
call hd_read |
pop eax |
lea edi, [buffer+eax] |
push ecx |
mov ecx, 0x200 |
sub ecx, eax |
xor eax, eax |
rep stosb |
pop eax |
call hd_write |
pop ebx |
.truncate_done: |
pop ecx eax edi |
call update_disk |
xor eax, eax |
cmp [hd_error], 0 |
jz @f |
mov al, 11 |
@@: |
ret |
fs_HdGetFileInfo: |
cmp [fs_type], 1 |
jz ntfs_HdGetFileInfo |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
mov eax, ERROR_UNKNOWN_FS |
ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 |
ret |
@@: |
push edi |
call hd_find_lfn |
pushfd |
cmp [hd_error], 0 |
jz @f |
popfd |
pop edi |
mov eax, 11 |
ret |
@@: |
popfd |
jmp fs_GetFileInfo_finish |
fs_HdSetFileInfo: |
cmp [fs_type], 1 |
jz ntfs_HdSetFileInfo |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
mov eax, ERROR_UNKNOWN_FS |
ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 |
ret |
@@: |
push edi |
call hd_find_lfn |
pushfd |
cmp [hd_error], 0 |
jz @f |
popfd |
pop edi |
mov eax, 11 |
ret |
@@: |
popfd |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
push eax |
call bdfe_to_fat_entry |
pop eax |
mov ebx, buffer |
call hd_write |
call update_disk |
pop edi |
xor eax, eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_HdDelete - delete file or empty folder from hard disk |
; |
; esi points to filename |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_HdDelete: |
cmp [fs_type], 1 |
jz ntfs_HdDelete |
cmp [fs_type], 16 |
jz @f |
cmp [fs_type], 32 |
jz @f |
push ERROR_UNKNOWN_FS |
.pop_ret: |
pop eax |
ret |
@@: |
cmp byte [esi], 0 |
jnz @f |
; cannot delete root! |
.access_denied: |
push ERROR_ACCESS_DENIED |
jmp .pop_ret |
@@: |
and [longname_sec1], 0 |
and [longname_sec2], 0 |
push edi |
call hd_find_lfn |
jnc .found |
pop edi |
push ERROR_FILE_NOT_FOUND |
jmp .pop_ret |
.found: |
cmp dword [edi], '. ' |
jz .access_denied2 |
cmp dword [edi], '.. ' |
jz .access_denied2 |
test byte [edi+11], 10h |
jz .dodel |
; we can delete only empty folders! |
pushad |
mov ebp, [edi+20-2] |
mov bp, [edi+26] |
xor ecx, ecx |
lea eax, [ebp-2] |
imul eax, [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
mov ebx, buffer |
call hd_read |
cmp [hd_error], 0 |
jnz .err1 |
add ebx, 2*0x20 |
.checkempty: |
cmp byte [ebx], 0 |
jz .empty |
cmp byte [ebx], 0xE5 |
jnz .notempty |
add ebx, 0x20 |
cmp ebx, buffer+0x200 |
jb .checkempty |
inc ecx |
cmp ecx, [SECTORS_PER_CLUSTER] |
jb @f |
mov eax, ebp |
call get_FAT |
cmp [hd_error], 0 |
jnz .err1 |
mov ebp, eax |
xor ecx, ecx |
@@: |
lea eax, [ebp-2] |
imul eax, [SECTORS_PER_CLUSTER] |
add eax, [DATA_START] |
add eax, ecx |
mov ebx, buffer |
call hd_read |
cmp [hd_error], 0 |
jz .checkempty |
.err1: |
popad |
.err2: |
pop edi |
push 11 |
pop eax |
ret |
.notempty: |
popad |
.access_denied2: |
pop edi |
push ERROR_ACCESS_DENIED |
pop eax |
ret |
.empty: |
popad |
push ebx |
mov ebx, buffer |
call hd_read |
pop ebx |
cmp [hd_error], 0 |
jnz .err2 |
.dodel: |
push eax |
mov eax, [edi+20-2] |
mov ax, [edi+26] |
xchg eax, [esp] |
; delete folder entry |
mov byte [edi], 0xE5 |
; delete LFN (if present) |
.lfndel: |
cmp edi, buffer |
ja @f |
cmp [longname_sec2], 0 |
jz .lfndone |
push [longname_sec2] |
push [longname_sec1] |
pop [longname_sec2] |
and [longname_sec1], 0 |
push ebx |
mov ebx, buffer |
call hd_write |
mov eax, [esp+4] |
call hd_read |
pop ebx |
pop eax |
mov edi, buffer+0x200 |
@@: |
sub edi, 0x20 |
cmp byte [edi], 0xE5 |
jz .lfndone |
cmp byte [edi+11], 0xF |
jnz .lfndone |
mov byte [edi], 0xE5 |
jmp .lfndel |
.lfndone: |
push ebx |
mov ebx, buffer |
call hd_write |
pop ebx |
; delete FAT chain |
pop eax |
call clear_cluster_chain |
call update_disk |
pop edi |
xor eax, eax |
cmp [hd_error], 0 |
jz @f |
mov al, 11 |
@@: |
ret |
; \end{diamond} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/fs/fs_lfn.inc |
---|
0,0 → 1,854 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
image_of_eax EQU esp+36 |
image_of_ebx EQU esp+24 |
; 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 |
; parse file name |
xchg ebx, eax |
lea esi, [ebx+20] |
lodsb |
test al, al |
jnz @f |
mov esi, [esi] |
lodsb |
@@: |
cmp al, '/' |
jz .notcurdir |
dec esi |
mov ebp, esi |
test al, al |
jnz @f |
xor ebp, ebp |
@@: |
mov esi, [current_slot] |
mov esi, [esi+APPDATA.cur_dir] |
jmp .parse_normal |
.notcurdir: |
cmp byte [esi], 0 |
jz .rootdir |
call process_replace_file_name |
.parse_normal: |
cmp dword [ebx], 7 |
jne @F |
mov edx, [ebx+4] |
mov ebx, [ebx+8] |
call fs_execute ; esi+ebp, ebx, edx |
mov [image_of_eax], eax |
ret |
@@: |
mov edi, rootdirs-8 |
xor ecx, ecx |
push esi |
.scan1: |
pop esi |
add edi, ecx |
scasd |
scasd |
mov cl, byte [edi] |
test cl, cl |
jz .notfound |
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 [image_of_eax], eax |
mov [image_of_ebx], ebx |
ret |
; directory / |
.rootdir: |
cmp dword [ebx], 1 ; read folder? |
jz .readroot |
.access_denied: |
mov dword [image_of_eax], 10 ; access denied |
ret |
.readroot: |
; virtual root folder - special handler |
mov esi, virtual_root_query |
mov ebp, [ebx+12] |
mov edx, [ebx+16] |
; add edx, std_application_base_address |
push dword [ebx+4] ; first block |
mov ebx, [ebx+8] ; flags |
xor eax, eax |
; eax=0, [esp]=first block, ebx=flags, ebp=number of blocks, edx=return area |
mov edi, edx |
mov ecx, 32/4 |
rep stosd |
mov byte [edx], 1 ; version |
.readroot_loop: |
cmp dword [esi], eax |
jz .readroot_done |
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 [image_of_eax], eax |
mov [image_of_ebx], ebx |
ret |
.notfound: |
mov dword [image_of_eax], ERROR_FILE_NOT_FOUND |
and dword [image_of_ebx], 0 |
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 |
lea ecx, [ecx*5] |
lea ecx, [ecx*2+eax] |
jmp @b |
.done1: |
jecxz .notfound |
test al, al |
jnz @f |
dec esi |
@@: |
cmp byte [esi], 0 |
jnz @f |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
@@: |
; now [edi] contains handler address, ecx - partition number, |
; esi points to ASCIIZ string - rest of name |
jmp dword [edi] |
; handlers for devices |
; in: ecx = 0 => query virtual directory /xxx |
; in: ecx = partition number |
; esi -> relative (for device) name |
; ebx -> fileinfo |
; ebp = 0 or pointer to rest of name from folder addressed by esi |
; out: [image_of_eax]=image of eax, [image_of_ebx]=image of ebx |
fs_OnRamdisk: |
cmp ecx, 1 |
jnz file_system_lfn.notfound |
mov eax, [ebx] |
cmp eax, fs_NumRamdiskServices |
jae .not_impl |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
; add edx, std_application_base_address |
add ebx, 4 |
call dword [fs_RamdiskServices + eax*4] |
mov [image_of_eax], eax |
mov [image_of_ebx], ebx |
ret |
.not_impl: |
mov dword [image_of_eax], 2 ; not implemented |
ret |
fs_NotImplemented: |
mov eax, 2 |
ret |
fs_RamdiskServices: |
dd fs_RamdiskRead |
dd fs_RamdiskReadFolder |
dd fs_RamdiskRewrite |
dd fs_RamdiskWrite |
dd fs_RamdiskSetFileEnd |
dd fs_RamdiskGetFileInfo |
dd fs_RamdiskSetFileInfo |
dd 0 |
dd fs_RamdiskDelete |
dd fs_RamdiskCreateFolder |
fs_NumRamdiskServices = ($ - fs_RamdiskServices)/4 |
fs_OnFloppy: |
cmp ecx, 2 |
ja file_system_lfn.notfound |
mov eax, [ebx] |
cmp eax, fs_NumFloppyServices |
jae fs_OnRamdisk.not_impl |
call reserve_flp |
mov [flp_number], cl |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
; add edx, std_application_base_address |
add ebx, 4 |
call dword [fs_FloppyServices + eax*4] |
and [flp_status], 0 |
mov [image_of_eax], eax |
mov [image_of_ebx], ebx |
ret |
fs_FloppyServices: |
dd fs_FloppyRead |
dd fs_FloppyReadFolder |
dd fs_FloppyRewrite |
dd fs_FloppyWrite |
dd fs_FloppySetFileEnd |
dd fs_FloppyGetFileInfo |
dd fs_FloppySetFileInfo |
dd 0 |
dd fs_FloppyDelete |
dd fs_FloppyCreateFolder |
fs_NumFloppyServices = ($ - fs_FloppyServices)/4 |
fs_OnHd0: |
call reserve_hd1 |
mov [hdbase], 0x1F0 |
mov [hdid], 0 |
push 1 |
jmp fs_OnHd |
fs_OnHd1: |
call reserve_hd1 |
mov [hdbase], 0x1F0 |
mov [hdid], 0x10 |
push 2 |
jmp fs_OnHd |
fs_OnHd2: |
call reserve_hd1 |
mov [hdbase], 0x170 |
mov [hdid], 0 |
push 3 |
jmp fs_OnHd |
fs_OnHd3: |
call reserve_hd1 |
mov [hdbase], 0x170 |
mov [hdid], 0x10 |
push 4 |
fs_OnHd: |
call reserve_hd_channel |
pop eax |
mov [hdpos], eax |
cmp ecx, 0x100 |
jae .nf |
cmp cl, [DRIVE_DATA+1+eax] |
jbe @f |
.nf: |
call free_hd_channel |
and [hd1_status], 0 |
mov dword [image_of_eax], 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 [image_of_eax], eax |
mov [image_of_ebx], ebx |
ret |
.not_impl: |
call free_hd_channel |
and [hd1_status], 0 |
mov dword [image_of_eax], 2 ; not implemented |
ret |
fs_HdServices: |
dd fs_HdRead |
dd fs_HdReadFolder |
dd fs_HdRewrite |
dd fs_HdWrite |
dd fs_HdSetFileEnd |
dd fs_HdGetFileInfo |
dd fs_HdSetFileInfo |
dd 0 |
dd fs_HdDelete |
dd fs_HdCreateFolder |
fs_NumHdServices = ($ - fs_HdServices)/4 |
;******************************************************* |
fs_OnCd0: |
call reserve_cd |
mov [ChannelNumber],1 |
mov [DiskNumber],0 |
push 6 |
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,[DRIVE_DATA+1] |
shr bl,cl |
test bl,2 |
pop ebx ecx |
jnz @f |
.nf: |
call free_cd_channel |
and [cd_status], 0 |
mov dword [image_of_eax], 5 ; not found |
ret |
@@: |
mov ecx, [ebx+12] |
mov edx, [ebx+16] |
; add edx, std_application_base_address |
mov eax, [ebx] |
cmp eax,fs_NumCdServices |
jae .not_impl |
add ebx, 4 |
call dword [fs_CdServices + eax*4] |
call free_cd_channel |
and [cd_status], 0 |
mov [image_of_eax], eax |
mov [image_of_ebx], ebx |
ret |
.not_impl: |
call free_cd_channel |
and [cd_status], 0 |
mov dword [image_of_eax], 2 ; not implemented |
ret |
fs_CdServices: |
dd fs_CdRead |
dd fs_CdReadFolder |
dd fs_NotImplemented |
dd fs_NotImplemented |
dd fs_NotImplemented |
dd fs_CdGetFileInfo |
dd fs_NotImplemented |
dd 0 |
fs_NumCdServices = ($ - fs_CdServices)/4 |
;******************************************************* |
fs_HasRamdisk: |
mov al, 1 ; we always have ramdisk |
ret |
fs_HasFloppy: |
cmp byte [DRIVE_DATA], 0 |
setnz al |
ret |
fs_HasHd0: |
mov al, [DRIVE_DATA+1] |
and al, 11000000b |
cmp al, 01000000b |
setz al |
ret |
fs_HasHd1: |
mov al, [DRIVE_DATA+1] |
and al, 00110000b |
cmp al, 00010000b |
setz al |
ret |
fs_HasHd2: |
mov al, [DRIVE_DATA+1] |
and al, 00001100b |
cmp al, 00000100b |
setz al |
ret |
fs_HasHd3: |
mov al, [DRIVE_DATA+1] |
and al, 00000011b |
cmp al, 00000001b |
setz al |
ret |
;******************************************************* |
fs_HasCd0: |
mov al, [DRIVE_DATA+1] |
and al, 11000000b |
cmp al, 10000000b |
setz al |
ret |
fs_HasCd1: |
mov al, [DRIVE_DATA+1] |
and al, 00110000b |
cmp al, 00100000b |
setz al |
ret |
fs_HasCd2: |
mov al, [DRIVE_DATA+1] |
and al, 00001100b |
cmp al, 00001000b |
setz al |
ret |
fs_HasCd3: |
mov al, [DRIVE_DATA+1] |
and al, 00000011b |
cmp al, 00000010b |
setz al |
ret |
;******************************************************* |
; fs_NextXXX functions: |
; in: eax = partition number, from which start to scan |
; out: CF=1 => no more partitions |
; CF=0 => eax=next partition number |
fs_NextRamdisk: |
; we always have /rd/1 |
test eax, eax |
stc |
jnz @f |
mov al, 1 |
clc |
@@: |
ret |
fs_NextFloppy: |
; we have /fd/1 iff (([DRIVE_DATA] and 0xF0) != 0) and /fd/2 iff (([DRIVE_DATA] and 0x0F) != 0) |
test byte [DRIVE_DATA], 0xF0 |
jz .no1 |
test eax, eax |
jnz .no1 |
inc eax |
ret ; CF cleared |
.no1: |
test byte [DRIVE_DATA], 0x0F |
jz .no2 |
cmp al, 2 |
jae .no2 |
mov al, 2 |
clc |
ret |
.no2: |
stc |
ret |
; on hdx, we have partitions from 1 to [0x40002+x] |
fs_NextHd0: |
push 0 |
jmp fs_NextHd |
fs_NextHd1: |
push 1 |
jmp fs_NextHd |
fs_NextHd2: |
push 2 |
jmp fs_NextHd |
fs_NextHd3: |
push 3 |
fs_NextHd: |
pop ecx |
movzx ecx, byte [DRIVE_DATA+2+ecx] |
cmp eax, ecx |
jae fs_NextFloppy.no2 |
inc eax |
clc |
ret |
;******************************************************* |
fs_NextCd: |
; we always have /cdX/1 |
test eax, eax |
stc |
jnz @f |
mov al, 1 |
clc |
@@: |
ret |
;******************************************************* |
process_replace_file_name: |
mov ebp, [full_file_name_table] |
mov edi, [full_file_name_table.size] |
dec edi |
shl edi, 7 |
add edi, ebp |
.loop: |
cmp edi, ebp |
jb .notfound |
push esi edi |
@@: |
cmp byte [edi], 0 |
jz .dest_done |
lodsb |
test al, al |
jz .cont |
or al, 20h |
scasb |
jz @b |
jmp .cont |
.dest_done: |
cmp byte [esi], 0 |
jz .found |
cmp byte [esi], '/' |
jnz .cont |
inc esi |
jmp .found |
.cont: |
pop edi esi |
sub edi, 128 |
jmp .loop |
.found: |
pop edi eax |
mov ebp, esi |
cmp byte [esi], 0 |
lea esi, [edi+64] |
jnz .ret |
.notfound: |
xor ebp, ebp |
.ret: |
ret |
sys_current_directory: |
mov esi, [current_slot] |
mov esi, [esi+APPDATA.cur_dir] |
mov edx, esi |
dec eax |
jz .set |
dec eax |
jz .get |
ret |
.get: |
; sysfunction 30.2: [for app] eax=30,ebx=2,ecx->buffer,edx=len |
; for our code: ebx->buffer,ecx=len |
@@: |
lodsb |
test al, al |
jnz @b |
sub esi, edx |
inc esi |
mov [esp+36], esi |
cmp ecx, esi |
jbe @f |
mov ecx, esi |
@@: |
cmp ecx, 1 |
jbe .ret |
mov esi, edx |
mov edi, ebx |
mov al, '/' |
stosb |
dec ecx |
dec ecx |
rep movsb |
mov byte [edi], 0 |
.ret: |
ret |
.set: |
; sysfunction 30.1: [for app] eax=30,ebx=1,ecx->string |
; for our code: ebx->string to set |
@@: |
inc esi |
cmp byte [esi-1], 0 |
jnz @b |
dec esi |
cmp byte [ebx], '/' |
jz .set_absolute |
; string gives relative path |
.relative: |
cmp byte [ebx], 0 |
jz .set_ok |
cmp word [ebx], '.' |
jz .set_ok |
cmp word [ebx], './' |
jnz @f |
add ebx, 2 |
jmp .relative |
@@: |
cmp word [ebx], '..' |
jnz .doset_relative |
cmp byte [ebx+2], 0 |
jz @f |
cmp byte [ebx+2], '/' |
jnz .doset_relative |
@@: |
dec esi |
cmp byte [esi], '/' |
jnz @b |
mov byte [esi], 0 |
add ebx, 3 |
jmp .relative |
.doset_relative: |
add edx, 0x1000 |
mov byte [esi], '/' |
inc esi |
cmp esi, edx |
jae .overflow_esi |
@@: |
mov al, [ebx] |
inc ebx |
mov [esi], al |
inc esi |
test al, al |
jz .set_ok |
cmp esi, edx |
jb @b |
.overflow_esi: |
mov byte [esi-1], 0 ; force null-terminated string |
.set_ok: |
ret |
.set_absolute: |
lea esi, [ebx+1] |
call process_replace_file_name |
mov edi, edx |
add edx, 0x1000 |
.set_copy: |
lodsb |
stosb |
test al, al |
jz .set_part2 |
.set_copy_cont: |
cmp edi, edx |
jb .set_copy |
.overflow_edi: |
mov byte [edi-1], 0 |
ret |
.set_part2: |
mov esi, ebp |
xor ebp, ebp |
test esi, esi |
jz .set_ok |
mov byte [edi-1], '/' |
jmp .set_copy_cont |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/fs/ntfs.inc |
---|
0,0 → 1,1804 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
ntfs_test_bootsec: |
; in: ebx->buffer, edx=size of partition |
; out: CF set <=> invalid |
; 1. Name=='NTFS ' |
cmp dword [ebx+3], 'NTFS' |
jnz .no |
cmp dword [ebx+7], ' ' |
jnz .no |
; 2. Number of bytes per sector is the same as for physical device |
; (that is, 0x200 for hard disk) |
cmp word [ebx+11], 0x200 |
jnz .no |
; 3. Number of sectors per cluster must be power of 2 |
movzx eax, byte [ebx+13] |
dec eax |
js .no |
test al, [ebx+13] |
jnz .no |
; 4. FAT parameters must be zero |
cmp word [ebx+14], 0 |
jnz .no |
cmp dword [ebx+16], 0 |
jnz .no |
cmp byte [ebx+20], 0 |
jnz .no |
cmp word [ebx+22], 0 |
jnz .no |
cmp dword [ebx+32], 0 |
jnz .no |
; 5. Number of sectors <= partition size |
cmp dword [ebx+0x2C], 0 |
ja .no |
cmp [ebx+0x28], edx |
ja .no |
; 6. $MFT and $MFTMirr clusters must be within partition |
cmp dword [ebx+0x34], 0 |
ja .no |
push edx |
movzx eax, byte [ebx+13] |
mul dword [ebx+0x30] |
test edx, edx |
pop edx |
jnz .no |
cmp eax, edx |
ja .no |
cmp dword [ebx+0x3C], 0 |
ja .no |
push edx |
movzx eax, byte [ebx+13] |
mul dword [ebx+0x38] |
test edx, edx |
pop edx |
jnz .no |
cmp eax, edx |
ja .no |
; 7. Clusters per FRS must be either negative and in [-31,-9] or positive and power of 2 |
movsx eax, byte [ebx+0x40] |
cmp al, -31 |
jl .no |
cmp al, -9 |
jle @f |
dec eax |
js .no |
test [ebx+0x40], al |
jnz .no |
@@: |
; 8. Same for clusters per IndexAllocationBuffer |
movsx eax, byte [ebx+0x44] |
cmp al, -31 |
jl .no |
cmp al, -9 |
jle @f |
dec eax |
js .no |
test [ebx+0x44], al |
jnz .no |
@@: |
; OK, this is correct NTFS bootsector |
clc |
ret |
.no: |
; No, this bootsector isn't NTFS |
stc |
ret |
ntfs_setup: ; CODE XREF: part_set.inc |
; By given bootsector, initialize some NTFS variables |
call ntfs_test_bootsec |
jc problem_fat_dec_count |
movzx eax, byte [ebx+13] |
mov [ntfs_data.sectors_per_cluster], eax |
mov eax, [ebx+0x28] |
add eax, [PARTITION_START] |
dec eax |
mov [PARTITION_END], eax |
mov [fs_type], 1 |
mov eax, [ebx+0x30] |
mov [ntfs_data.mft_cluster], eax |
mov eax, [ebx+0x38] |
mov [ntfs_data.mftmirr_cluster], eax |
movsx eax, byte [ebx+0x40] |
test eax, eax |
js .1 |
mul [ntfs_data.sectors_per_cluster] |
shl eax, 9 |
jmp .2 |
.1: |
neg eax |
mov ecx, eax |
mov eax, 1 |
shl eax, cl |
.2: |
mov [ntfs_data.frs_size], eax |
movsx eax, byte [ebx+0x44] |
test eax, eax |
js .3 |
mul [ntfs_data.sectors_per_cluster] |
shl eax, 9 |
jmp .4 |
.3: |
neg eax |
mov ecx, eax |
mov eax, 1 |
shl eax, cl |
.4: |
mov [ntfs_data.iab_size], eax |
; allocate space for buffers |
add eax, [ntfs_data.frs_size] |
push eax |
call kernel_alloc |
test eax, eax |
jz problem_fat_dec_count |
mov [ntfs_data.frs_buffer], eax |
add eax, [ntfs_data.frs_size] |
mov [ntfs_data.iab_buffer], eax |
; read $MFT disposition |
mov eax, [ntfs_data.mft_cluster] |
mul [ntfs_data.sectors_per_cluster] |
call ntfs_read_frs_sector |
cmp [hd_error], 0 |
jnz .usemirr |
cmp dword [ebx], 'FILE' |
jnz .usemirr |
call ntfs_restore_usa_frs |
jnc .mftok |
.usemirr: |
and [hd_error], 0 |
mov eax, [ntfs_data.mftmirr_cluster] |
mul [ntfs_data.sectors_per_cluster] |
call ntfs_read_frs_sector |
cmp [hd_error], 0 |
jnz @f |
cmp dword [ebx], 'FILE' |
jnz @f |
call ntfs_restore_usa_frs |
jnc .mftok |
@@: |
; $MFT and $MFTMirr invalid! |
.fail_free_frs: |
push [ntfs_data.frs_buffer] |
call kernel_free |
jmp problem_fat_dec_count |
.fail_free_mft: |
push [ntfs_data.mft_retrieval] |
call kernel_free |
jmp .fail_free_frs |
.mftok: |
; read $MFT table retrieval information |
; start with one page, increase if not enough (when MFT too fragmented) |
push ebx |
push 0x1000 |
call kernel_alloc |
pop ebx |
test eax, eax |
jz .fail_free_frs |
mov [ntfs_data.mft_retrieval], eax |
and [ntfs_data.mft_retrieval_size], 0 |
mov [ntfs_data.mft_retrieval_alloc], 0x1000/8 |
; $MFT base record must contain unnamed non-resident $DATA attribute |
movzx eax, word [ebx+14h] |
add eax, ebx |
.scandata: |
cmp dword [eax], -1 |
jz .fail_free_mft |
cmp dword [eax], 0x80 |
jnz @f |
cmp byte [eax+9], 0 |
jz .founddata |
@@: |
add eax, [eax+4] |
jmp .scandata |
.founddata: |
cmp byte [eax+8], 0 |
jz .fail_free_mft |
; load first portion of $DATA attribute retrieval information |
mov edx, [eax+0x18] |
mov [ntfs_data.mft_retrieval_end], edx |
mov esi, eax |
movzx eax, word [eax+0x20] |
add esi, eax |
sub esp, 10h |
.scanmcb: |
call ntfs_decode_mcb_entry |
jnc .scanmcbend |
call .get_mft_retrieval_ptr |
mov edx, [esp] ; block length |
mov [eax], edx |
mov edx, [esp+8] ; block addr (relative) |
mov [eax+4], edx |
inc [ntfs_data.mft_retrieval_size] |
jmp .scanmcb |
.scanmcbend: |
add esp, 10h |
; there may be other portions of $DATA attribute in auxiliary records; |
; if they will be needed, they will be loaded later |
mov [ntfs_data.cur_index_size], 0x1000/0x200 |
push 0x1000 |
call kernel_alloc |
test eax, eax |
jz .fail_free_mft |
mov [ntfs_data.cur_index_buf], eax |
popad |
call free_hd_channel |
and [hd1_status], 0 |
ret |
.get_mft_retrieval_ptr: |
pushad |
mov eax, [ntfs_data.mft_retrieval_size] |
cmp eax, [ntfs_data.mft_retrieval_alloc] |
jnz .ok |
add eax, 0x1000/8 |
mov [ntfs_data.mft_retrieval_alloc], eax |
shl eax, 3 |
push eax |
call kernel_alloc |
test eax, eax |
jnz @f |
popad |
add esp, 14h |
jmp .fail_free_mft |
@@: |
mov esi, [ntfs_data.mft_retrieval] |
mov edi, eax |
mov ecx, [ntfs_data.mft_retrieval_size] |
add ecx, ecx |
rep movsd |
push [ntfs_data.mft_retrieval] |
mov [ntfs_data.mft_retrieval], eax |
call kernel_free |
mov eax, [ntfs_data.mft_retrieval_size] |
.ok: |
shl eax, 3 |
add eax, [ntfs_data.mft_retrieval] |
mov [esp+28], eax |
popad |
ret |
ntfs_read_frs_sector: |
push eax ecx |
add eax, [PARTITION_START] |
mov ecx, [ntfs_data.frs_size] |
shr ecx, 9 |
mov ebx, [ntfs_data.frs_buffer] |
push ebx |
@@: |
call hd_read |
cmp [hd_error], 0 |
jnz .fail |
add ebx, 0x200 |
inc eax |
loop @b |
.fail: |
pop ebx |
pop ecx eax |
ret |
uglobal |
align 4 |
ntfs_cur_attr dd ? |
ntfs_cur_iRecord dd ? |
ntfs_cur_offs dd ? ; in sectors |
ntfs_cur_size dd ? ; in sectors |
ntfs_cur_buf dd ? |
ntfs_cur_read dd ? ; [output] |
ntfs_bCanContinue db ? |
rb 3 |
ntfs_attrlist_buf rb 0x400 |
ntfs_attrlist_mft_buf rb 0x400 |
ntfs_bitmap_buf rb 0x400 |
ntfs_attr_iRecord dd ? |
ntfs_attr_iBaseRecord dd ? |
ntfs_attr_offs dd ? |
ntfs_attr_list dd ? |
ntfs_attr_size dq ? |
ntfs_cur_tail dd ? |
endg |
ntfs_read_attr: |
; in: global variables |
; out: [ntfs_cur_read] |
pushad |
and [ntfs_cur_read], 0 |
cmp [ntfs_cur_iRecord], 0 |
jnz .nomft |
cmp [ntfs_cur_attr], 0x80 |
jnz .nomft |
mov eax, [ntfs_data.mft_retrieval_end] |
inc eax |
mul [ntfs_data.sectors_per_cluster] |
cmp eax, [ntfs_cur_offs] |
jbe .nomft |
; precalculated part of $Mft $DATA |
mov esi, [ntfs_data.mft_retrieval] |
mov eax, [ntfs_cur_offs] |
xor edx, edx |
div [ntfs_data.sectors_per_cluster] |
; eax = VCN, edx = offset in sectors from beginning of cluster |
xor ecx, ecx ; ecx will contain LCN |
.mftscan: |
add ecx, [esi+4] |
sub eax, [esi] |
jb @f |
add esi, 8 |
push eax |
mov eax, [ntfs_data.mft_retrieval_end] |
shl eax, 3 |
add eax, [ntfs_data.mft_retrieval] |
cmp eax, esi |
pop eax |
jnz .mftscan |
jmp .nomft |
@@: |
push ecx |
add ecx, eax |
add ecx, [esi] |
push eax |
push edx |
mov eax, [ntfs_data.sectors_per_cluster] |
mul ecx |
; eax = sector on partition |
add eax, [PARTITION_START] |
pop edx |
add eax, edx |
mov ebx, [ntfs_cur_buf] |
pop ecx |
neg ecx |
imul ecx, [ntfs_data.sectors_per_cluster] |
sub ecx, edx |
cmp ecx, [ntfs_cur_size] |
jb @f |
mov ecx, [ntfs_cur_size] |
@@: |
; ecx = number of sequential sectors to read |
call hd_read |
cmp [hd_error], 0 |
jnz .errread |
add [ntfs_cur_read], 0x200 |
dec [ntfs_cur_size] |
inc [ntfs_cur_offs] |
add ebx, 0x200 |
mov [ntfs_cur_buf], ebx |
inc eax |
loop @b |
pop ecx |
xor eax, eax |
xor edx, edx |
cmp [ntfs_cur_size], eax |
jz @f |
add esi, 8 |
push eax |
mov eax, [ntfs_data.mft_retrieval_end] |
shl eax, 3 |
add eax, [ntfs_data.mft_retrieval] |
cmp eax, esi |
pop eax |
jz .nomft |
jmp .mftscan |
@@: |
popad |
ret |
.errread: |
pop ecx |
.errret: |
stc |
popad |
ret |
.nomft: |
; 1. Read file record. |
; N.B. This will do recursive call of read_attr for $MFT::$Data. |
mov eax, [ntfs_cur_iRecord] |
mov [ntfs_attr_iRecord], eax |
and [ntfs_attr_list], 0 |
or dword [ntfs_attr_size], -1 |
or dword [ntfs_attr_size+4], -1 |
or [ntfs_attr_iBaseRecord], -1 |
call ntfs_read_file_record |
test eax, eax |
jz .errret |
; 2. Find required attribute. |
mov eax, [ntfs_data.frs_buffer] |
; a) For auxiliary records, read base record |
; N.B. If base record is present, |
; base iRecord may be 0 (for $Mft), but SequenceNumber is nonzero |
cmp dword [eax+24h], 0 |
jz @f |
mov eax, [eax+20h] |
; test eax, eax |
; jz @f |
.beginfindattr: |
mov [ntfs_attr_iRecord], eax |
call ntfs_read_file_record |
test eax, eax |
jz .errret |
@@: |
; b) Scan for required attribute and for $ATTR_LIST |
mov eax, [ntfs_data.frs_buffer] |
movzx ecx, word [eax+14h] |
add eax, ecx |
mov ecx, [ntfs_cur_attr] |
and [ntfs_attr_offs], 0 |
.scanattr: |
cmp dword [eax], -1 |
jz .scandone |
cmp dword [eax], ecx |
jz .okattr |
cmp [ntfs_attr_iBaseRecord], -1 |
jnz .scancont |
cmp dword [eax], 0x20 ; $ATTR_LIST |
jnz .scancont |
mov [ntfs_attr_list], eax |
jmp .scancont |
.okattr: |
; ignore named $DATA attributes (aka NTFS streams) |
cmp ecx, 0x80 |
jnz @f |
cmp byte [eax+9], 0 |
jnz .scancont |
@@: |
mov [ntfs_attr_offs], eax |
.scancont: |
add eax, [eax+4] |
jmp .scanattr |
.continue: |
pushad |
and [ntfs_cur_read], 0 |
.scandone: |
; c) Check for required offset and length |
mov ecx, [ntfs_attr_offs] |
jecxz .noattr |
push [ntfs_cur_size] |
push [ntfs_cur_read] |
call .doreadattr |
pop edx |
pop eax |
jc @f |
cmp [ntfs_bCanContinue], 0 |
jz @f |
sub edx, [ntfs_cur_read] |
neg edx |
shr edx, 9 |
sub eax, edx |
mov [ntfs_cur_size], eax |
jnz .not_in_cur |
@@: |
popad |
ret |
.noattr: |
.not_in_cur: |
cmp [ntfs_cur_attr], 0x20 |
jz @f |
mov ecx, [ntfs_attr_list] |
test ecx, ecx |
jnz .lookattr |
.ret_is_attr: |
cmp [ntfs_attr_offs], 1 ; CF set <=> ntfs_attr_offs == 0 |
popad |
ret |
.lookattr: |
; required attribute or required offset was not found in base record; |
; it may be present in auxiliary records; |
; scan $ATTR_LIST |
mov eax, [ntfs_attr_iBaseRecord] |
cmp eax, -1 |
jz @f |
call ntfs_read_file_record |
test eax, eax |
jz .errret |
or [ntfs_attr_iBaseRecord], -1 |
@@: |
push [ntfs_cur_offs] |
push [ntfs_cur_size] |
push [ntfs_cur_read] |
push [ntfs_cur_buf] |
push dword [ntfs_attr_size] |
push dword [ntfs_attr_size+4] |
or dword [ntfs_attr_size], -1 |
or dword [ntfs_attr_size+4], -1 |
and [ntfs_cur_offs], 0 |
mov [ntfs_cur_size], 2 |
and [ntfs_cur_read], 0 |
mov eax, ntfs_attrlist_buf |
cmp [ntfs_cur_iRecord], 0 |
jnz @f |
mov eax, ntfs_attrlist_mft_buf |
@@: |
mov [ntfs_cur_buf], eax |
push eax |
call .doreadattr |
pop esi |
mov edx, 1 |
pop dword [ntfs_attr_size+4] |
pop dword [ntfs_attr_size] |
mov ebp, [ntfs_cur_read] |
pop [ntfs_cur_buf] |
pop [ntfs_cur_read] |
pop [ntfs_cur_size] |
pop [ntfs_cur_offs] |
jc .errret |
or edi, -1 |
lea ebp, [ebp+esi-1Ah] |
.scanliststart: |
mov eax, [ntfs_cur_attr] |
.scanlist: |
cmp esi, ebp |
jae .scanlistdone |
cmp eax, [esi] |
jz @f |
.scanlistcont: |
movzx ecx, word [esi+4] |
add esi, ecx |
jmp .scanlist |
@@: |
; ignore named $DATA attributes (aka NTFS streams) |
cmp eax, 0x80 |
jnz @f |
cmp byte [esi+6], 0 |
jnz .scanlistcont |
@@: |
push eax |
mov eax, [esi+8] |
test eax, eax |
jnz .testf |
mov eax, dword [ntfs_attr_size] |
and eax, dword [ntfs_attr_size+4] |
cmp eax, -1 |
jnz .testfz |
; if attribute is in auxiliary records, its size is defined only in first |
mov eax, [esi+10h] |
call ntfs_read_file_record |
test eax, eax |
jnz @f |
.errret_pop: |
pop eax |
jmp .errret |
@@: |
mov eax, [ntfs_data.frs_buffer] |
movzx ecx, word [eax+14h] |
add eax, ecx |
mov ecx, [ntfs_cur_attr] |
@@: |
cmp dword [eax], -1 |
jz .errret_pop |
cmp dword [eax], ecx |
jz @f |
.l1: |
add eax, [eax+4] |
jmp @b |
@@: |
cmp eax, 0x80 |
jnz @f |
cmp byte [eax+9], 0 |
jnz .l1 |
@@: |
cmp byte [eax+8], 0 |
jnz .sdnores |
mov eax, [eax+10h] |
mov dword [ntfs_attr_size], eax |
and dword [ntfs_attr_size+4], 0 |
jmp .testfz |
.sdnores: |
mov ecx, [eax+30h] |
mov dword [ntfs_attr_size], ecx |
mov ecx, [eax+34h] |
mov dword [ntfs_attr_size+4], ecx |
.testfz: |
xor eax, eax |
.testf: |
imul eax, [ntfs_data.sectors_per_cluster] |
cmp eax, [ntfs_cur_offs] |
pop eax |
ja @f |
mov edi, [esi+10h] ; keep previous iRecord |
jmp .scanlistcont |
@@: |
.scanlistfound: |
cmp edi, -1 |
jnz @f |
popad |
ret |
@@: |
mov eax, [ntfs_cur_iRecord] |
mov [ntfs_attr_iBaseRecord], eax |
mov eax, edi |
jmp .beginfindattr |
.sde: |
popad |
stc |
ret |
.scanlistdone: |
sub ebp, ntfs_attrlist_buf-1Ah |
cmp [ntfs_cur_iRecord], 0 |
jnz @f |
sub ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf |
@@: |
cmp ebp, 0x400 |
jnz .scanlistfound |
inc edx |
push esi edi |
mov esi, ntfs_attrlist_buf+0x200 |
mov edi, ntfs_attrlist_buf |
cmp [ntfs_cur_iRecord], 0 |
jnz @f |
mov esi, ntfs_attrlist_mft_buf+0x200 |
mov edi, ntfs_attrlist_mft_buf |
@@: |
mov ecx, 0x200/4 |
rep movsd |
mov eax, edi |
pop edi esi |
sub esi, 0x200 |
push [ntfs_cur_offs] |
push [ntfs_cur_size] |
push [ntfs_cur_read] |
push [ntfs_cur_buf] |
push dword [ntfs_attr_size] |
push dword [ntfs_attr_size+4] |
or dword [ntfs_attr_size], -1 |
or dword [ntfs_attr_size+4], -1 |
mov [ntfs_cur_offs], edx |
mov [ntfs_cur_size], 1 |
and [ntfs_cur_read], 0 |
mov [ntfs_cur_buf], eax |
mov ecx, [ntfs_attr_list] |
push esi edx |
call .doreadattr |
pop edx esi |
mov ebp, [ntfs_cur_read] |
pop dword [ntfs_attr_size+4] |
pop dword [ntfs_attr_size] |
pop [ntfs_cur_buf] |
pop [ntfs_cur_read] |
pop [ntfs_cur_size] |
pop [ntfs_cur_offs] |
jc .errret |
add ebp, ntfs_attrlist_buf+0x200-0x1A |
cmp [ntfs_cur_iRecord], 0 |
jnz .scanliststart |
add ebp, ntfs_attrlist_mft_buf-ntfs_attrlist_buf |
jmp .scanliststart |
.doreadattr: |
mov [ntfs_bCanContinue], 0 |
cmp byte [ecx+8], 0 |
jnz .nonresident |
mov eax, [ecx+10h] ; length |
mov esi, eax |
mov edx, [ntfs_cur_offs] |
shr eax, 9 |
cmp eax, edx |
jb .okret |
shl edx, 9 |
sub esi, edx |
movzx eax, word [ecx+14h] |
add edx, eax |
add edx, ecx ; edx -> data |
mov eax, [ntfs_cur_size] |
cmp eax, (0xFFFFFFFF shr 9)+1 |
jbe @f |
mov eax, (0xFFFFFFFF shr 9)+1 |
@@: |
shl eax, 9 |
cmp eax, esi |
jbe @f |
mov eax, esi |
@@: |
; eax = length, edx -> data |
mov [ntfs_cur_read], eax |
mov ecx, eax |
mov eax, edx |
mov ebx, [ntfs_cur_buf] |
call memmove |
and [ntfs_cur_size], 0 ; CF=0 |
ret |
.nonresident: |
; Not all auxiliary records contain correct FileSize info |
mov eax, dword [ntfs_attr_size] |
mov edx, dword [ntfs_attr_size+4] |
push eax |
and eax, edx |
cmp eax, -1 |
pop eax |
jnz @f |
mov eax, [ecx+30h] ; FileSize |
mov edx, [ecx+34h] |
mov dword [ntfs_attr_size], eax |
mov dword [ntfs_attr_size+4], edx |
@@: |
add eax, 0x1FF |
adc edx, 0 |
shrd eax, edx, 9 |
sub eax, [ntfs_cur_offs] |
ja @f |
; return with nothing read |
and [ntfs_cur_size], 0 |
.okret: |
clc |
ret |
@@: |
; reduce read length |
and [ntfs_cur_tail], 0 |
cmp [ntfs_cur_size], eax |
jb @f |
mov [ntfs_cur_size], eax |
mov eax, dword [ntfs_attr_size] |
and eax, 0x1FF |
mov [ntfs_cur_tail], eax |
@@: |
cmp [ntfs_cur_size], 0 |
jz .okret |
mov eax, [ntfs_cur_offs] |
xor edx, edx |
div [ntfs_data.sectors_per_cluster] |
sub eax, [ecx+10h] ; first_vbo |
jb .okret |
; eax = cluster, edx = starting sector |
sub esp, 10h |
movzx esi, word [ecx+20h] ; mcb_info_ofs |
add esi, ecx |
xor ebp, ebp |
.readloop: |
call ntfs_decode_mcb_entry |
jnc .break |
add ebp, [esp+8] |
sub eax, [esp] |
jae .readloop |
push ecx |
push eax |
add eax, [esp+8] |
add eax, ebp |
imul eax, [ntfs_data.sectors_per_cluster] |
add eax, edx |
add eax, [PARTITION_START] |
pop ecx |
neg ecx |
imul ecx, [ntfs_data.sectors_per_cluster] |
sub ecx, edx |
cmp ecx, [ntfs_cur_size] |
jb @f |
mov ecx, [ntfs_cur_size] |
@@: |
mov ebx, [ntfs_cur_buf] |
@@: |
call hd_read |
cmp [hd_error], 0 |
jnz .errread2 |
add ebx, 0x200 |
mov [ntfs_cur_buf], ebx |
inc eax |
add [ntfs_cur_read], 0x200 |
dec [ntfs_cur_size] |
inc [ntfs_cur_offs] |
loop @b |
pop ecx |
xor eax, eax |
xor edx, edx |
cmp [ntfs_cur_size], 0 |
jnz .readloop |
add esp, 10h |
mov eax, [ntfs_cur_tail] |
test eax, eax |
jz .okret |
sub eax, 0x200 |
add [ntfs_cur_read], eax |
jmp .okret |
.errread2: |
pop ecx |
add esp, 10h |
jmp .errret |
.break: |
add esp, 10h ; CF=0 |
mov [ntfs_bCanContinue], 1 |
ret |
ntfs_read_file_record: |
; in: eax=iRecord |
; out: [ntfs_data.frs_buffer] contains information |
; eax=0 - failed, eax=1 - success |
; Read attr $DATA of $Mft, starting from eax*[ntfs_data.frs_size] |
push ecx edx |
mov ecx, [ntfs_data.frs_size] |
mul ecx |
shrd eax, edx, 9 |
shr edx, 9 |
jnz .err |
push [ntfs_attr_iRecord] |
push [ntfs_attr_iBaseRecord] |
push [ntfs_attr_offs] |
push [ntfs_attr_list] |
push dword [ntfs_attr_size+4] |
push dword [ntfs_attr_size] |
push [ntfs_cur_iRecord] |
push [ntfs_cur_attr] |
push [ntfs_cur_offs] |
push [ntfs_cur_size] |
push [ntfs_cur_buf] |
push [ntfs_cur_read] |
mov [ntfs_cur_attr], 0x80 ; $DATA |
and [ntfs_cur_iRecord], 0 ; $Mft |
mov [ntfs_cur_offs], eax |
shr ecx, 9 |
mov [ntfs_cur_size], ecx |
mov eax, [ntfs_data.frs_buffer] |
mov [ntfs_cur_buf], eax |
call ntfs_read_attr |
mov eax, [ntfs_cur_read] |
pop [ntfs_cur_read] |
pop [ntfs_cur_buf] |
pop [ntfs_cur_size] |
pop [ntfs_cur_offs] |
pop [ntfs_cur_attr] |
pop [ntfs_cur_iRecord] |
pop dword [ntfs_attr_size] |
pop dword [ntfs_attr_size+4] |
pop [ntfs_attr_list] |
pop [ntfs_attr_offs] |
pop [ntfs_attr_iBaseRecord] |
pop [ntfs_attr_iRecord] |
pop edx ecx |
jc .errret |
cmp eax, [ntfs_data.frs_size] |
jnz .errret |
mov eax, [ntfs_data.frs_buffer] |
cmp dword [eax], 'FILE' |
jnz .errret |
push ebx |
mov ebx, eax |
call ntfs_restore_usa_frs |
pop ebx |
setnc al |
movzx eax, al |
.ret: |
ret |
.err: |
pop edx ecx |
.errret: |
xor eax, eax |
ret |
ntfs_restore_usa_frs: |
mov eax, [ntfs_data.frs_size] |
ntfs_restore_usa: |
pushad |
shr eax, 9 |
mov ecx, eax |
inc eax |
cmp [ebx+6], ax |
jnz .err |
movzx eax, word [ebx+4] |
lea esi, [eax+ebx] |
lodsw |
mov edx, eax |
lea edi, [ebx+0x1FE] |
@@: |
cmp [edi], dx |
jnz .err |
lodsw |
stosw |
add edi, 0x1FE |
loop @b |
popad |
clc |
ret |
.err: |
popad |
stc |
ret |
ntfs_decode_mcb_entry: |
push eax ecx edi |
lea edi, [esp+16] |
xor eax, eax |
lodsb |
test al, al |
jz .end |
mov ecx, eax |
and ecx, 0xF |
cmp ecx, 8 |
ja .end |
push ecx |
rep movsb |
pop ecx |
sub ecx, 8 |
neg ecx |
cmp byte [esi-1], 80h |
jae .end |
push eax |
xor eax, eax |
rep stosb |
pop ecx |
shr ecx, 4 |
cmp ecx, 8 |
ja .end |
push ecx |
rep movsb |
pop ecx |
sub ecx, 8 |
neg ecx |
cmp byte [esi-1], 80h |
cmc |
sbb eax, eax |
rep stosb |
stc |
.end: |
pop edi ecx eax |
ret |
ntfs_find_lfn: |
; in: esi+ebp -> name |
; out: CF=1 - file not found |
; else CF=0, [ntfs_cur_iRecord] valid, eax->record in parent directory |
mov [ntfs_cur_iRecord], 5 ; start parse from root cluster |
.doit2: |
mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT |
and [ntfs_cur_offs], 0 |
mov eax, [ntfs_data.cur_index_size] |
mov [ntfs_cur_size], eax |
mov eax, [ntfs_data.cur_index_buf] |
mov [ntfs_cur_buf], eax |
call ntfs_read_attr |
jnc @f |
.ret: |
ret |
@@: |
cmp [ntfs_cur_read], 0x20 |
jc .ret |
pushad |
mov esi, [ntfs_data.cur_index_buf] |
mov eax, [esi+14h] |
add eax, 10h |
cmp [ntfs_cur_read], eax |
jae .readok1 |
add eax, 1FFh |
shr eax, 9 |
cmp eax, [ntfs_data.cur_index_size] |
ja @f |
.stc_ret: |
popad |
stc |
ret |
@@: |
; reallocate |
push eax |
push [ntfs_data.cur_index_buf] |
call kernel_free |
pop eax |
mov [ntfs_data.cur_index_size], eax |
push eax |
call kernel_alloc |
test eax, eax |
jnz @f |
and [ntfs_data.cur_index_size], 0 |
and [ntfs_data.cur_index_buf], 0 |
jmp .stc_ret |
@@: |
mov [ntfs_data.cur_index_buf], eax |
popad |
jmp .doit2 |
.readok1: |
mov ebp, [esi+8] ; subnode_size |
shr ebp, 9 |
cmp ebp, [ntfs_data.cur_index_size] |
jbe .ok2 |
push esi ebp |
push ebp |
call kernel_alloc |
pop ebp esi |
test eax, eax |
jz .stc_ret |
mov edi, eax |
mov ecx, [ntfs_data.cur_index_size] |
shl ecx, 9-2 |
rep movsd |
mov esi, eax |
mov [ntfs_data.cur_index_size], ebp |
push esi ebp |
push [ntfs_data.cur_index_buf] |
call kernel_free |
pop ebp esi |
mov [ntfs_data.cur_index_buf], esi |
.ok2: |
add esi, 10h |
mov edi, [esp+4] |
; edi -> name, esi -> current index data, ebp = subnode size |
.scanloop: |
add esi, [esi] |
.scanloopint: |
test byte [esi+0Ch], 2 |
jnz .subnode |
push esi |
add esi, 0x52 |
movzx ecx, byte [esi-2] |
push edi |
@@: |
lodsw |
call uni2ansi_char |
call char_toupper |
push eax |
mov al, [edi] |
inc edi |
call char_toupper |
cmp al, [esp] |
pop eax |
loopz @b |
jz .found |
pop edi |
pop esi |
jb .subnode |
.scanloopcont: |
movzx eax, word [esi+8] |
add esi, eax |
jmp .scanloopint |
.subnode: |
test byte [esi+0Ch], 1 |
jz .notfound |
movzx eax, word [esi+8] |
mov eax, [esi+eax-8] |
mul [ntfs_data.sectors_per_cluster] |
mov [ntfs_cur_offs], eax |
mov [ntfs_cur_attr], 0xA0 ; $INDEX_ALLOCATION |
mov [ntfs_cur_size], ebp |
mov eax, [ntfs_data.cur_index_buf] |
mov esi, eax |
mov [ntfs_cur_buf], eax |
call ntfs_read_attr |
mov eax, ebp |
shl eax, 9 |
cmp [ntfs_cur_read], eax |
jnz .notfound |
cmp dword [esi], 'INDX' |
jnz .notfound |
mov ebx, esi |
call ntfs_restore_usa |
jc .notfound |
add esi, 0x18 |
jmp .scanloop |
.notfound: |
popad |
stc |
ret |
.found: |
cmp byte [edi], 0 |
jz .done |
cmp byte [edi], '/' |
jz .next |
pop edi |
pop esi |
jmp .scanloopcont |
.done: |
.next: |
pop esi |
pop esi |
mov eax, [esi] |
mov [ntfs_cur_iRecord], eax |
mov [esp+1Ch], esi |
mov [esp+4], edi |
popad |
inc esi |
cmp byte [esi-1], 0 |
jnz .doit2 |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
jmp .doit2 |
@@: |
ret |
;---------------------------------------------------------------- |
; |
; ntfs_HdRead - read NTFS hard disk |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
ntfs_HdRead: |
cmp byte [esi], 0 |
jnz @f |
or ebx, -1 |
push ERROR_ACCESS_DENIED |
pop eax |
ret |
@@: |
call ntfs_find_lfn |
jnc .found |
or ebx, -1 |
push ERROR_FILE_NOT_FOUND |
pop eax |
ret |
.found: |
mov [ntfs_cur_attr], 0x80 ; $DATA |
and [ntfs_cur_offs], 0 |
and [ntfs_cur_size], 0 |
call ntfs_read_attr |
jnc @f |
or ebx, -1 |
push ERROR_ACCESS_DENIED |
pop eax |
ret |
@@: |
pushad |
and dword [esp+10h], 0 |
xor eax, eax |
test ebx, ebx |
jz .zero1 |
cmp dword [ebx+4], 0x200 |
jb @f |
.eof0: |
popad |
xor ebx, ebx |
.eof: |
push ERROR_END_OF_FILE |
pop eax |
ret |
@@: |
mov eax, [ebx] |
test eax, 0x1FF |
jz .alignedstart |
push edx |
mov edx, [ebx+4] |
shrd eax, edx, 9 |
pop edx |
mov [ntfs_cur_offs], eax |
mov [ntfs_cur_size], 1 |
mov [ntfs_cur_buf], ntfs_bitmap_buf |
call ntfs_read_attr.continue |
mov eax, [ebx] |
and eax, 0x1FF |
lea esi, [ntfs_bitmap_buf+eax] |
sub eax, [ntfs_cur_read] |
jae .eof0 |
neg eax |
push ecx |
cmp ecx, eax |
jb @f |
mov ecx, eax |
@@: |
mov [esp+10h+4], ecx |
mov edi, edx |
rep movsb |
mov edx, edi |
pop ecx |
sub ecx, [esp+10h] |
jnz @f |
.retok: |
popad |
xor eax, eax |
ret |
@@: |
cmp [ntfs_cur_read], 0x200 |
jz .alignedstart |
.eof_ebx: |
popad |
jmp .eof |
.alignedstart: |
mov eax, [ebx] |
push edx |
mov edx, [ebx+4] |
add eax, 511 |
adc edx, 0 |
shrd eax, edx, 9 |
pop edx |
.zero1: |
mov [ntfs_cur_offs], eax |
mov [ntfs_cur_buf], edx |
mov eax, ecx |
shr eax, 9 |
mov [ntfs_cur_size], eax |
add eax, [ntfs_cur_offs] |
push eax |
call ntfs_read_attr.continue |
pop [ntfs_cur_offs] |
mov eax, [ntfs_cur_read] |
add [esp+10h], eax |
mov eax, ecx |
and eax, not 0x1FF |
cmp [ntfs_cur_read], eax |
jnz .eof_ebx |
and ecx, 0x1FF |
jz .retok |
add edx, [ntfs_cur_read] |
mov [ntfs_cur_size], 1 |
mov [ntfs_cur_buf], ntfs_bitmap_buf |
call ntfs_read_attr.continue |
cmp [ntfs_cur_read], ecx |
jb @f |
mov [ntfs_cur_read], ecx |
@@: |
xchg ecx, [ntfs_cur_read] |
push ecx |
mov edi, edx |
mov esi, ntfs_bitmap_buf |
add [esp+10h+4], ecx |
rep movsb |
pop ecx |
xor eax, eax |
cmp ecx, [ntfs_cur_read] |
jz @f |
mov al, ERROR_END_OF_FILE |
@@: |
mov [esp+1Ch], eax |
popad |
ret |
;---------------------------------------------------------------- |
; |
; ntfs_HdReadFolder - read NTFS hard disk folder |
; |
; esi points to filename |
; ebx pointer to structure 32-bit number = first wanted block, 0+ |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = blocks read or 0xffffffff folder not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
ntfs_HdReadFolder: |
mov eax, 5 ; root cluster |
cmp byte [esi], 0 |
jz .doit |
call ntfs_find_lfn |
jnc .doit2 |
.notfound: |
or ebx, -1 |
push ERROR_FILE_NOT_FOUND |
.pop_ret: |
pop eax |
ret |
.doit: |
mov [ntfs_cur_iRecord], eax |
.doit2: |
mov [ntfs_cur_attr], 0x10 ; $STANDARD_INFORMATION |
and [ntfs_cur_offs], 0 |
mov [ntfs_cur_size], 1 |
mov [ntfs_cur_buf], ntfs_bitmap_buf |
call ntfs_read_attr |
jc .notfound |
mov [ntfs_cur_attr], 0x90 ; $INDEX_ROOT |
and [ntfs_cur_offs], 0 |
mov eax, [ntfs_data.cur_index_size] |
mov [ntfs_cur_size], eax |
mov eax, [ntfs_data.cur_index_buf] |
mov [ntfs_cur_buf], eax |
call ntfs_read_attr |
jnc .ok |
cmp [hd_error], 0 |
jz .notfound |
or ebx, -1 |
push 11 |
jmp .pop_ret |
.ok: |
cmp [ntfs_cur_read], 0x20 |
jae @f |
or ebx, -1 |
.fserr: |
push ERROR_FAT_TABLE |
jmp .pop_ret |
@@: |
pushad |
mov esi, [ntfs_data.cur_index_buf] |
mov eax, [esi+14h] |
add eax, 10h |
cmp [ntfs_cur_read], eax |
jae .readok1 |
add eax, 1FFh |
shr eax, 9 |
cmp eax, [ntfs_data.cur_index_size] |
ja @f |
popad |
jmp .fserr |
@@: |
; reallocate |
push eax |
push [ntfs_data.cur_index_buf] |
call kernel_free |
pop eax |
mov [ntfs_data.cur_index_size], eax |
push eax |
call kernel_alloc |
test eax, eax |
jnz @f |
and [ntfs_data.cur_index_size], 0 |
and [ntfs_data.cur_index_buf], 0 |
.nomem: |
popad |
or ebx, -1 |
push 12 |
pop eax |
ret |
@@: |
mov [ntfs_data.cur_index_buf], eax |
popad |
jmp .doit2 |
.readok1: |
mov ebp, [esi+8] ; subnode_size |
shr ebp, 9 |
cmp ebp, [ntfs_data.cur_index_size] |
jbe .ok2 |
push esi ebp |
push ebp |
call kernel_alloc |
pop ebp esi |
test eax, eax |
jz .nomem |
mov edi, eax |
mov ecx, [ntfs_data.cur_index_size] |
shl ecx, 9-2 |
rep movsd |
mov esi, eax |
mov [ntfs_data.cur_index_size], ebp |
push esi ebp |
push [ntfs_data.cur_index_buf] |
call kernel_free |
pop ebp esi |
mov [ntfs_data.cur_index_buf], esi |
.ok2: |
add esi, 10h |
mov ebx, [esp+10h] |
mov edx, [esp+14h] |
push dword [ebx+4] ; read ANSI/UNICODE name |
mov ebx, [ebx] |
; init header |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
mov byte [edx], 1 ; version |
mov ecx, [esp+4+18h] |
push edx |
mov edx, esp |
; edi -> BDFE, esi -> current index data, ebp = subnode size, ebx = first wanted block, |
; ecx = number of blocks to read |
; edx -> parameters block: dd <output>, dd <flags> |
cmp [ntfs_cur_iRecord], 5 |
jz .skip_specials |
; dot and dotdot entries |
push esi |
xor esi, esi |
call .add_special_entry |
inc esi |
call .add_special_entry |
pop esi |
.skip_specials: |
; at first, dump index root |
add esi, [esi] |
.dump_root: |
test byte [esi+0Ch], 2 |
jnz .dump_root_done |
call .add_entry |
movzx eax, word [esi+8] |
add esi, eax |
jmp .dump_root |
.dump_root_done: |
; now dump all subnodes |
push ecx edi |
mov edi, ntfs_bitmap_buf |
mov [ntfs_cur_buf], edi |
mov ecx, 0x400/4 |
xor eax, eax |
rep stosd |
mov [ntfs_cur_attr], 0xB0 ; $BITMAP |
and [ntfs_cur_offs], 0 |
mov [ntfs_cur_size], 2 |
call ntfs_read_attr |
pop edi ecx |
push 0 ; save offset in $BITMAP attribute |
and [ntfs_cur_offs], 0 |
.dumploop: |
mov [ntfs_cur_attr], 0xA0 |
mov [ntfs_cur_size], ebp |
mov eax, [ntfs_data.cur_index_buf] |
mov esi, eax |
mov [ntfs_cur_buf], eax |
push [ntfs_cur_offs] |
mov eax, [ntfs_cur_offs] |
imul eax, ebp |
mov [ntfs_cur_offs], eax |
call ntfs_read_attr |
pop [ntfs_cur_offs] |
mov eax, ebp |
shl eax, 9 |
cmp [ntfs_cur_read], eax |
jnz .done |
push eax |
mov eax, [ntfs_cur_offs] |
and eax, 0x400*8-1 |
bt dword [ntfs_bitmap_buf], eax |
pop eax |
jnc .dump_subnode_done |
cmp dword [esi], 'INDX' |
jnz .dump_subnode_done |
push ebx |
mov ebx, esi |
call ntfs_restore_usa |
pop ebx |
jc .dump_subnode_done |
add esi, 0x18 |
add esi, [esi] |
.dump_subnode: |
test byte [esi+0Ch], 2 |
jnz .dump_subnode_done |
call .add_entry |
movzx eax, word [esi+8] |
add esi, eax |
jmp .dump_subnode |
.dump_subnode_done: |
inc [ntfs_cur_offs] |
test [ntfs_cur_offs], 0x400*8-1 |
jnz .dumploop |
mov [ntfs_cur_attr], 0xB0 |
push ecx edi |
mov edi, ntfs_bitmap_buf |
mov [ntfs_cur_buf], edi |
mov ecx, 0x400/4 |
xor eax, eax |
rep stosd |
pop edi ecx |
pop eax |
push [ntfs_cur_offs] |
inc eax |
mov [ntfs_cur_offs], eax |
mov [ntfs_cur_size], 2 |
push eax |
call ntfs_read_attr |
pop eax |
pop [ntfs_cur_offs] |
push eax |
jmp .dumploop |
.done: |
pop eax |
pop edx |
mov ebx, [edx+4] |
pop edx |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
mov [esp+1Ch], eax |
mov [esp+10h], ebx |
popad |
ret |
.add_special_entry: |
mov eax, [edx] |
inc dword [eax+8] ; new file found |
dec ebx |
jns .ret |
dec ecx |
js .ret |
inc dword [eax+4] ; new file block copied |
mov eax, [edx+4] |
mov [edi+4], eax |
; mov eax, dword [ntfs_bitmap_buf+0x20] |
; or al, 0x10 |
mov eax, 0x10 |
stosd |
scasd |
push edx |
mov eax, dword [ntfs_bitmap_buf] |
mov edx, dword [ntfs_bitmap_buf+4] |
call ntfs_datetime_to_bdfe |
mov eax, dword [ntfs_bitmap_buf+0x18] |
mov edx, dword [ntfs_bitmap_buf+0x1C] |
call ntfs_datetime_to_bdfe |
mov eax, dword [ntfs_bitmap_buf+8] |
mov edx, dword [ntfs_bitmap_buf+0xC] |
call ntfs_datetime_to_bdfe |
pop edx |
xor eax, eax |
stosd |
stosd |
mov al, '.' |
push edi ecx |
lea ecx, [esi+1] |
test byte [edi-0x24], 1 |
jz @f |
rep stosw |
pop ecx |
xor eax, eax |
stosw |
pop edi |
add edi, 520 |
ret |
@@: |
rep stosb |
pop ecx |
xor eax, eax |
stosb |
pop edi |
add edi, 264 |
.ret: |
ret |
.add_entry: |
; do not return DOS 8.3 names |
cmp byte [esi+0x51], 2 |
jz .ret |
; do not return system files |
; ... note that there will be no bad effects if system files also were reported ... |
cmp dword [esi], 0x10 |
jb .ret |
mov eax, [edx] |
inc dword [eax+8] ; new file found |
dec ebx |
jns .ret |
dec ecx |
js .ret |
inc dword [eax+4] ; new file block copied |
mov eax, [edx+4] ; flags |
call ntfs_direntry_to_bdfe |
push ecx esi edi |
movzx ecx, byte [esi+0x50] |
add esi, 0x52 |
test byte [edi-0x24], 1 |
jz .ansi |
shr ecx, 1 |
rep movsd |
adc ecx, ecx |
rep movsw |
and word [edi], 0 |
pop edi |
add edi, 520 |
pop esi ecx |
ret |
.ansi: |
jecxz .skip |
@@: |
lodsw |
call uni2ansi_char |
stosb |
loop @b |
.skip: |
xor al, al |
stosb |
pop edi |
add edi, 264 |
pop esi ecx |
ret |
ntfs_direntry_to_bdfe: |
mov [edi+4], eax ; ANSI/UNICODE name |
mov eax, [esi+48h] |
test eax, 0x10000000 |
jz @f |
and eax, not 0x10000000 |
or al, 0x10 |
@@: |
stosd |
scasd |
push edx |
mov eax, [esi+0x18] |
mov edx, [esi+0x1C] |
call ntfs_datetime_to_bdfe |
mov eax, [esi+0x30] |
mov edx, [esi+0x34] |
call ntfs_datetime_to_bdfe |
mov eax, [esi+0x20] |
mov edx, [esi+0x24] |
call ntfs_datetime_to_bdfe |
pop edx |
mov eax, [esi+0x40] |
stosd |
mov eax, [esi+0x44] |
stosd |
ret |
iglobal |
_24 dd 24 |
_60 dd 60 |
_10000000 dd 10000000 |
days400year dd 365*400+100-4+1 |
days100year dd 365*100+25-1 |
days4year dd 365*4+1 |
days1year dd 365 |
months dd 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 |
months2 dd 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 |
_400 dd 400 |
_100 dd 100 |
endg |
ntfs_datetime_to_bdfe: |
; edx:eax = number of 100-nanosecond intervals since January 1, 1601, in UTC |
push eax |
mov eax, edx |
xor edx, edx |
div [_10000000] |
xchg eax, [esp] |
div [_10000000] |
pop edx |
; edx:eax = number of seconds since January 1, 1601 |
push eax |
mov eax, edx |
xor edx, edx |
div [_60] |
xchg eax, [esp] |
div [_60] |
mov [edi], dl |
pop edx |
; edx:eax = number of minutes |
div [_60] |
mov [edi+1], dl |
; eax = number of hours (note that 2^64/(10^7*60*60) < 2^32) |
xor edx, edx |
div [_24] |
mov [edi+2], dl |
mov [edi+3], byte 0 |
; eax = number of days since January 1, 1601 |
xor edx, edx |
div [days400year] |
imul eax, 400 |
add eax, 1601 |
mov [edi+6], ax |
mov eax, edx |
xor edx, edx |
div [days100year] |
cmp al, 4 |
jnz @f |
dec eax |
add edx, [days100year] |
@@: |
imul eax, 100 |
add [edi+6], ax |
mov eax, edx |
xor edx, edx |
div [days4year] |
shl eax, 2 |
add [edi+6], ax |
mov eax, edx |
xor edx, edx |
div [days1year] |
cmp al, 4 |
jnz @f |
dec eax |
add edx, [days1year] |
@@: |
add [edi+6], ax |
push esi edx |
mov esi, months |
movzx eax, word [edi+6] |
test al, 3 |
jnz .noleap |
xor edx, edx |
push eax |
div [_400] |
pop eax |
test edx, edx |
jz .leap |
xor edx, edx |
div [_100] |
test edx, edx |
jz .noleap |
.leap: |
mov esi, months2 |
.noleap: |
pop edx |
xor eax, eax |
inc eax |
@@: |
sub edx, [esi] |
jb @f |
add esi, 4 |
inc eax |
jmp @b |
@@: |
add edx, [esi] |
pop esi |
inc edx |
mov [edi+4], dl |
mov [edi+5], al |
add edi, 8 |
ret |
;---------------------------------------------------------------- |
; |
; ntfs_HdRewrite - write to NTFS hard disk |
; |
; esi points to filename |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
ntfs_HdRewrite: |
xor ebx, ebx |
mov eax, ERROR_UNSUPPORTED_FS |
ret |
;---------------------------------------------------------------- |
; |
; ntfs_HdWrite - write to NTFS hard disk |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = bytes written (maybe 0) |
; eax = 0 ok write or other = errormsg |
; |
;-------------------------------------------------------------- |
ntfs_HdWrite: |
xor ebx, ebx |
mov eax, ERROR_UNSUPPORTED_FS |
ret |
;---------------------------------------------------------------- |
; |
; ntfs_HdSetFileEnd - set end of file on NTFS hard disk |
; |
; esi points to filename |
; ebx points to 64-bit number = new file size |
; ecx ignored (reserved) |
; edx ignored (reserved) |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
ntfs_HdSetFileEnd: |
ntfs_HdSetFileInfo: |
;---------------------------------------------------------------- |
; |
; ntfs_HdDelete - delete file or empty folder from NTFS hard disk |
; |
; esi points to filename |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
ntfs_HdDelete: |
mov eax, ERROR_UNSUPPORTED_FS |
ret |
ntfs_HdGetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
push 2 |
pop eax |
ret |
@@: |
call ntfs_find_lfn |
jnc .doit |
push ERROR_FILE_NOT_FOUND |
pop eax |
cmp [hd_error], 0 |
jz @f |
mov al, 11 |
@@: |
ret |
.doit: |
push esi edi |
mov esi, eax |
mov edi, edx |
xor eax, eax |
call ntfs_direntry_to_bdfe |
pop edi esi |
xor eax, eax |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/fs/fs.inc |
---|
0,0 → 1,779 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; System service for filesystem call ;; |
;; (C) 2004 Ville Turjanmaa, License: GPL ;; |
;; 29.04.2006 Elimination of hangup after the ;; |
;; expiration hd_wait_timeout (for LBA) - Mario79 ;; |
;; 15.01.2005 get file size/attr/date, ;; |
;; file_append (only for hd) - ATV ;; |
;; 23.11.2004 test if hd/partition is set - ATV ;; |
;; 18.11.2004 get_disk_info and more error codes - ATV ;; |
;; 08.11.2004 expand_pathz and rename (only for hd) - ATV ;; |
;; 20.10.2004 Makedir/Removedir (only for hd) - ATV ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
dir0: db 'HARDDISK ' |
db 'RAMDISK ' |
db 'FLOPPYDISK ' |
db 0 |
dir1: db 'FIRST ' |
db 'SECOND ' |
db 'THIRD ' |
db 'FOURTH ' |
db 0 |
not_select_IDE db 0 |
hd_address_table: dd 0x1f0,0x00,0x1f0,0x10 |
dd 0x170,0x00,0x170,0x10 |
endg |
file_system: |
; IN: |
; |
; eax = 0 ; read file /RamDisk/First 6 |
; eax = 8 ; lba read |
; eax = 15 ; get_disk_info |
; |
; OUT: |
; |
; eax = 0 : read ok |
; eax = 1 : no hd base and/or partition defined |
; eax = 2 : function is unsupported for this FS |
; eax = 3 : unknown FS |
; eax = 4 : partition not defined at hd |
; eax = 5 : file not found |
; eax = 6 : end of file |
; eax = 7 : memory pointer not in application area |
; eax = 8 : disk full |
; eax = 9 : fat table corrupted |
; eax = 10 : access denied |
; eax = 11 : disk error |
; |
; ebx = size |
; \begin{diamond}[18.03.2006] |
; for subfunction 16 (start application) error codes must be negative |
; because positive values are valid PIDs |
; so possible return values are: |
; eax > 0 : process created, eax=PID |
; -0x10 <= eax < 0 : -eax is filesystem error code: |
; eax = -1 = 0xFFFFFFFF : no hd base and/or partition defined |
; eax = -3 = 0xFFFFFFFD : unknown FS |
; eax = -5 = 0xFFFFFFFB : file not found |
; eax = -6 = 0xFFFFFFFA : unexpected end of file (probably not executable file) |
; eax = -9 = 0xFFFFFFF7 : fat table corrupted |
; eax = -10 = 0xFFFFFFF6 : access denied |
; -0x20 <= eax < -0x10: eax is process creation error code: |
; eax = -0x20 = 0xFFFFFFE0 : too many processes |
; eax = -0x1F = 0xFFFFFFE1 : not Menuet/Kolibri executable |
; eax = -0x1E = 0xFFFFFFE2 : no memory |
; ebx is not changed |
; \end{diamond}[18.03.2006] |
; Extract parameters |
; add eax, std_application_base_address ; abs start of info block |
cmp dword [eax+0],15 ; GET_DISK_INFO |
je fs_info |
cmp dword [CURRENT_TASK],1 ; no memory checks for kernel requests |
jz no_checks_for_kernel |
mov edx,eax |
cmp dword [eax+0],1 |
jnz .usual_check |
mov ebx,[eax+12] |
; add ebx,std_application_base_address |
mov ecx,[eax+8] |
call check_region |
test eax,eax |
jnz area_in_app_mem |
.error_output: |
mov esi,buffer_failed |
call sys_msg_board_str |
; mov eax,7 |
mov dword [esp+36],7 |
ret |
iglobal |
buffer_failed db 'K : Buffer check failed',13,10,0 |
endg |
.usual_check: |
cmp dword [eax+0],0 |
mov ecx,512 |
jnz .small_size |
mov ecx,[eax+8] |
shl ecx,9 |
.small_size: |
mov ebx,[eax+12] |
; add ebx,std_application_base_address |
call check_region |
test eax,eax |
jz .error_output |
area_in_app_mem: |
mov eax,edx |
no_checks_for_kernel: |
fs_read: |
mov ebx,[eax+20] ; program wants root directory ? |
test bl,bl |
je fs_getroot |
test bh,bh |
jne fs_noroot |
fs_getroot: |
; \begin{diamond}[18.03.2006] |
; root - only read is allowed |
; other operations return "access denied", eax=10 |
; (execute operation returns eax=-10) |
cmp dword [eax], 0 |
jz .read_root |
mov dword [esp+36], 10 |
ret |
.read_root: |
; \end{diamond}[18.03.2006] |
mov esi,dir0 |
mov edi,[eax+12] |
; add edi,std_application_base_address |
mov ecx,11 |
push ecx |
; cld ; already is |
rep movsb |
mov al,0x10 |
stosb |
add edi,32-11-1 |
pop ecx |
rep movsb |
stosb |
and dword [esp+36],0 ; ok read |
mov dword [esp+24],32*2 ; size of root |
ret |
fs_info: ;start of code - Mihasik |
push eax |
cmp [eax+21],byte 'h' |
je fs_info_h |
cmp [eax+21],byte 'H' |
je fs_info_h |
cmp [eax+21],byte 'r' |
je fs_info_r |
cmp [eax+21],byte 'R' |
je fs_info_r |
mov eax,3 ;if unknown disk |
xor ebx,ebx |
xor ecx,ecx |
xor edx,edx |
jmp fs_info1 |
fs_info_r: |
call ramdisk_free_space ;if ramdisk |
mov ecx,edi ;free space in ecx |
shr ecx,9 ;free clusters |
mov ebx,2847 ;total clusters |
mov edx,512 ;cluster size |
xor eax,eax ;always 0 |
jmp fs_info1 |
fs_info_h: ;if harddisk |
call get_hd_info |
fs_info1: |
pop edi |
mov [esp+36],eax |
mov [esp+24],ebx ; total clusters on disk |
mov [esp+32],ecx ; free clusters on disk |
mov [edi],edx ; cluster size in bytes |
ret ;end of code - Mihasik |
fs_noroot: |
push dword [eax+0] ; read/write/delete/.../makedir/rename/lba/run |
push dword [eax+4] ; 512 block number to read |
push dword [eax+8] ; bytes to write/append or 512 blocks to read |
mov ebx,[eax+12] |
; add ebx,std_application_base_address |
push ebx ; abs start of return/save area |
lea esi,[eax+20] ; abs start of dir + filename |
mov edi,[eax+16] |
; add edi,std_application_base_address ; abs start of work area |
call expand_pathz |
push edi ; dir start |
push ebx ; name of file start |
mov eax,[edi+1] |
cmp eax,'RD ' |
je fs_yesramdisk |
cmp eax,'RAMD' |
jne fs_noramdisk |
fs_yesramdisk: |
cmp byte [edi+1+11],0 |
je fs_give_dir1 |
mov eax,[edi+1+12] |
cmp eax,'1 ' |
je fs_yesramdisk_first |
cmp eax,'FIRS' |
jne fs_noramdisk |
fs_yesramdisk_first: |
cmp dword [esp+20],8 ; LBA read ramdisk |
jne fs_no_LBA_read_ramdisk |
mov eax,[esp+16] ; LBA block to read |
mov ecx,[esp+8] ; abs pointer to return area |
call LBA_read_ramdisk |
jmp file_system_return |
fs_no_LBA_read_ramdisk: |
cmp dword [esp+20],0 ; READ |
jne fs_noramdisk_read |
mov eax,[esp+4] ; fname |
add eax,2*12+1 |
mov ebx,[esp+16] ; block start |
inc ebx |
mov ecx,[esp+12] ; block count |
mov edx,[esp+8] ; return |
mov esi,[esp+0] |
sub esi,eax |
add esi,12+1 ; file name length |
call fileread |
jmp file_system_return |
fs_noramdisk_read: |
fs_noramdisk: |
;******************************************************************** |
mov eax,[edi+1] |
cmp eax,'FD ' |
je fs_yesflpdisk |
cmp eax,'FLOP' |
jne fs_noflpdisk |
fs_yesflpdisk: |
call reserve_flp |
cmp byte [edi+1+11],0 |
je fs_give_dir1 |
mov eax,[edi+1+12] |
cmp eax,'1 ' |
je fs_yesflpdisk_first |
cmp eax,'FIRS' |
je fs_yesflpdisk_first |
cmp eax,'2 ' |
je fs_yesflpdisk_second |
cmp eax,'SECO' |
jne fs_noflpdisk |
jmp fs_yesflpdisk_second |
fs_yesflpdisk_first: |
mov [flp_number],1 |
jmp fs_yesflpdisk_start |
fs_yesflpdisk_second: |
mov [flp_number],2 |
fs_yesflpdisk_start: |
cmp dword [esp+20],0 ; READ |
jne fs_noflpdisk_read |
mov eax,[esp+4] ; fname |
add eax,2*12+1 |
mov ebx,[esp+16] ; block start |
inc ebx |
mov ecx,[esp+12] ; block count |
mov edx,[esp+8] ; return |
mov esi,[esp+0] |
sub esi,eax |
add esi,12+1 ; file name length |
call floppy_fileread |
jmp file_system_return |
fs_noflpdisk_read: |
fs_noflpdisk: |
;***************************************************************** |
mov eax,[edi+1] |
cmp eax,'HD0 ' |
je fs_yesharddisk_IDE0 |
cmp eax,'HD1 ' |
je fs_yesharddisk_IDE1 |
cmp eax,'HD2 ' |
je fs_yesharddisk_IDE2 |
cmp eax,'HD3 ' |
je fs_yesharddisk_IDE3 |
jmp old_path_harddisk |
fs_yesharddisk_IDE0: |
call reserve_hd1 |
mov [hdbase],0x1f0 |
mov [hdid],0x0 |
mov [hdpos],1 |
jmp fs_yesharddisk_partition |
fs_yesharddisk_IDE1: |
call reserve_hd1 |
mov [hdbase],0x1f0 |
mov [hdid],0x10 |
mov [hdpos],2 |
jmp fs_yesharddisk_partition |
fs_yesharddisk_IDE2: |
call reserve_hd1 |
mov [hdbase],0x170 |
mov [hdid],0x0 |
mov [hdpos],3 |
jmp fs_yesharddisk_partition |
fs_yesharddisk_IDE3: |
call reserve_hd1 |
mov [hdbase],0x170 |
mov [hdid],0x10 |
mov [hdpos],4 |
fs_yesharddisk_partition: |
call reserve_hd_channel |
; call choice_necessity_partition |
; jmp fs_yesharddisk_all |
jmp fs_for_new_semantic |
choice_necessity_partition: |
mov eax,[edi+1+12] |
call StringToNumber |
mov [fat32part],eax |
choice_necessity_partition_1: |
mov ecx,[hdpos] |
xor eax,eax |
mov [hd_entries], eax ; entries in hd cache |
mov edx,DRIVE_DATA+2 |
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,DRIVE_DATA+0xa |
mov [transfer_adress],eax |
call partition_data_transfer_1 |
ret |
old_path_harddisk: |
mov eax,[edi+1] |
cmp eax,'HD ' |
je fs_yesharddisk |
cmp eax,'HARD' |
jne fs_noharddisk |
fs_yesharddisk: |
cmp dword [esp+20],8 ; LBA read |
jne fs_no_LBA_read |
mov eax,[esp+16] ; LBA block to read |
lea ebx,[edi+1+12] ; pointer to FIRST/SECOND/THIRD/FOURTH |
mov ecx,[esp+8] ; abs pointer to return area |
call LBA_read |
jmp file_system_return |
fs_no_LBA_read: |
cmp byte [edi+1+11],0 ; directory read |
je fs_give_dir1 |
call reserve_hd1 |
fs_for_new_semantic: |
call choice_necessity_partition |
fs_yesharddisk_all: |
mov eax,1 |
mov ebx, [esp+24+24] |
cmp [hdpos],0 ; is hd base set? |
jz hd_err_return |
cmp [fat32part],0 ; is partition set? |
jnz @f |
hd_err_return: |
call free_hd_channel |
and [hd1_status], 0 |
jmp file_system_return |
@@: |
cmp dword [esp+20],0 ; READ |
jne fs_noharddisk_read |
mov eax,[esp+0] ; /fname |
lea edi,[eax+12] |
mov byte [eax],0 ; path to asciiz |
inc eax ; filename start |
mov ebx,[esp+12] ; count to read |
mov ecx,[esp+8] ; buffer |
mov edx,[esp+4] |
add edx,12*2 ; dir start |
sub edi,edx ; path length |
mov esi,[esp+16] ; blocks to read |
call file_read |
mov edi,[esp+0] |
mov byte [edi],'/' |
call free_hd_channel |
and [hd1_status], 0 |
jmp file_system_return |
fs_noharddisk_read: |
call free_hd_channel |
and [hd1_status], 0 |
fs_noharddisk: |
; \begin{diamond}[18.03.2006] |
mov eax, 5 ; file not found |
; à ìîæåò áûòü, âîçâðàùàòü äðóãîé êîä îøèáêè? |
mov ebx, [esp+24+24] ; do not change ebx in application |
; \end{diamond}[18.03.2006] |
file_system_return: |
add esp,24 |
mov [esp+36],eax |
mov [esp+24],ebx |
ret |
fs_give_dir1: |
; \begin{diamond}[18.03.2006] |
; /RD,/FD,/HD - only read is allowed |
; other operations return "access denied", eax=10 |
; (execute operation returns eax=-10) |
cmp dword [esp+20], 0 |
jz .read |
add esp, 20 |
pop ecx |
mov dword [esp+36], 10 |
ret |
.read: |
; \end{diamond}[18.03.2006] |
mov al,0x10 |
mov ebx,1 |
mov edi,[esp+8] |
mov esi,dir1 |
fs_d1_new: |
mov ecx,11 |
; cld |
rep movsb |
stosb |
add edi,32-11-1 |
dec ebx |
jne fs_d1_new |
add esp,24 |
and dword [esp+36],0 ; ok read |
mov dword [esp+24],32*1 ; dir/data size |
ret |
LBA_read_ramdisk: |
cmp [lba_read_enabled],1 |
je lbarrl1 |
xor ebx,ebx |
mov eax,2 |
ret |
lbarrl1: |
cmp eax,18*2*80 |
jb lbarrl2 |
xor ebx,ebx |
mov eax,3 |
ret |
lbarrl2: |
pushad |
call restorefatchain |
mov edi,ecx |
mov esi,eax |
shl esi,9 |
add esi,RAMDISK |
mov ecx,512/4 |
; cld |
rep movsd |
popad |
xor ebx,ebx |
xor eax,eax |
ret |
LBA_read: |
; IN: |
; |
; eax = LBA block to read |
; ebx = pointer to FIRST/SECOND/THIRD/FOURTH |
; ecx = abs pointer to return area |
cmp [lba_read_enabled],1 |
je lbarl1 |
mov eax,2 |
ret |
lbarl1: |
call reserve_hd1 |
push eax |
push ecx |
mov edi,hd_address_table |
mov esi,dir1 |
mov eax,[ebx] |
mov edx,'1 ' |
mov ecx,4 |
blar0: |
cmp eax,[esi] |
je blar2 |
cmp eax,edx |
je blar2 |
inc edx |
add edi,8 |
add esi,11 |
dec ecx |
jnz blar0 |
mov eax,1 |
mov ebx,1 |
jmp LBA_read_ret |
blar2: |
mov eax,[edi+0] |
mov ebx,[edi+4] |
mov [hdbase],eax |
mov [hdid],ebx |
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_lba_error |
; eax = hd port |
; ebx = set for primary (0x00) or slave (0x10) |
cli |
mov edx,eax |
inc edx |
xor eax,eax |
out dx,al |
inc edx |
inc eax |
out dx,al |
inc edx |
mov eax,[esp+4] |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
out dx,al |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,bl |
add al,128+64+32 |
out dx,al |
inc edx |
mov al,20h |
out dx,al |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jne hd_lba_error |
cli |
mov edi,[esp+0] |
mov ecx,256 |
sub edx,7 |
cld |
rep insw |
sti |
xor eax,eax |
xor ebx,ebx |
LBA_read_ret: |
mov [hd_error],0 |
mov [hd1_status],0 |
add esp,2*4 |
ret |
expand_pathz: |
; IN: |
; esi = asciiz path & file |
; edi = buffer for path & file name |
; OUT: |
; edi = directory & file : / 11 + / 11 + / 11 - zero terminated |
; ebx = /file name - zero terminated |
; esi = pointer after source |
push eax |
push ecx |
push edi ;[esp+0] |
pathz_start: |
mov byte [edi],'/' |
inc edi |
mov al,32 |
mov ecx,11 |
cld |
rep stosb ; clear filename area |
sub edi,11 |
mov ebx,edi ; start of dir/file name |
pathz_new_char: |
mov al,[esi] |
inc esi |
cmp al,0 |
je pathz_end |
cmp al,'/' |
jne pathz_not_path |
cmp edi,ebx ; skip first '/' |
jz pathz_new_char |
lea edi,[ebx+11] ; start of next directory |
jmp pathz_start |
pathz_not_path: |
cmp al,'.' |
jne pathz_not_ext |
lea edi,[ebx+8] ; start of extension |
jmp pathz_new_char |
pathz_not_ext: |
cmp al,'a' |
jb pathz_not_low |
cmp al,'z' |
ja pathz_not_low |
sub al,0x20 ; char to uppercase |
pathz_not_low: |
mov [edi],al |
inc edi |
mov eax,[esp+0] ; start_of_dest_path |
add eax,512 ; keep maximum path under 512 bytes |
cmp edi,eax |
jb pathz_new_char |
pathz_end: |
cmp ebx,edi ; if path end with '/' |
jnz pathz_put_zero ; go back 1 level |
sub ebx,12 |
pathz_put_zero: |
mov byte [ebx+11],0 |
dec ebx ; include '/' char into file name |
pop edi |
pop ecx |
pop eax |
ret |
;******************************************* |
;* string to number |
;* input eax - 4 byte string |
;* output eax - number |
;******************************************* |
StringToNumber: |
; ÏÅÐÅÂÎÄ ÑÒÐÎÊÎÂÎÃÎ ×ÈÑËÀ  ×ÈÑËÎÂÎÉ ÂÈÄ |
; Âõîä: |
; EDI - àäðåñ ñòðîêè ñ ÷èñëîì. Êîíåö ÷èñëà îòìå÷åí êîäîì 0Dh |
; Âûõîä: |
; CF - èíäèêàòîð îøèáîê: |
; 0 - îøèáîê íåò; |
; 1 - îøèáêà |
; Åñëè CF=0, òî AX - ÷èñëî. |
push bx |
push cx |
push dx |
push edi |
mov [partition_string],eax |
mov edi,partition_string |
xor cx,cx |
i1: |
mov al,[edi] |
cmp al,32 ;13 |
je i_exit |
; cmp al,'0' |
; jb err |
; cmp al,'9' |
; ja err |
sub al,48 |
shl cx,1 |
jc 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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/fs/part_set.inc |
---|
0,0 → 1,452 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;************************************************************* |
;* 29.04.2006 Elimination of hangup after the * |
;* expiration hd_wait_timeout - Mario79 * |
;* 28.01.2006 find all Fat16/32 partition in all input point * |
;* to MBR - Mario79 * |
;************************************************************* |
uglobal |
align 4 |
;****************************************************** |
; Please do not change this place - variables in text |
; Mario79 |
; START place |
;****************************************************** |
PARTITION_START dd 0x3f |
PARTITION_END dd 0 |
fs_type db 0 ; 0=none, 1=NTFS, 16=FAT16, 32=FAT32 |
align 4 |
fs_dependent_data_start: |
; FATxx data |
SECTORS_PER_FAT dd 0x1f3a |
NUMBER_OF_FATS dd 0x2 |
SECTORS_PER_CLUSTER dd 0x8 |
BYTES_PER_SECTOR dd 0x200 ; Note: if BPS <> 512 need lots of changes |
ROOT_CLUSTER dd 2 ; first rootdir cluster |
FAT_START dd 0 ; start of fat table |
ROOT_START dd 0 ; start of rootdir (only fat16) |
ROOT_SECTORS dd 0 ; count of rootdir sectors (only fat16) |
DATA_START dd 0 ; start of data area (=first cluster 2) |
LAST_CLUSTER dd 0 ; last availabe cluster |
ADR_FSINFO dd 0 ; used only by fat32 |
fatRESERVED dd 0x0FFFFFF6 |
fatBAD dd 0x0FFFFFF7 |
fatEND dd 0x0FFFFFF8 |
fatMASK dd 0x0FFFFFFF |
fs_dependent_data_end: |
file_system_data_size = $ - PARTITION_START |
if file_system_data_size > 96 |
ERROR: sizeof(file system data) too big! |
end if |
virtual at fs_dependent_data_start |
; NTFS data |
ntfs_data: |
.sectors_per_cluster dd ? |
.mft_cluster dd ? |
.mftmirr_cluster dd ? |
.frs_size dd ? ; FRS size in bytes |
.iab_size dd ? ; IndexAllocationBuffer size in bytes |
.frs_buffer dd ? |
.iab_buffer dd ? |
.mft_retrieval dd ? |
.mft_retrieval_size dd ? |
.mft_retrieval_alloc dd ? |
.mft_retrieval_end dd ? |
.cur_index_size dd ? |
.cur_index_buf dd ? |
if $ > fs_dependent_data_end |
ERROR: increase sizeof(fs_dependent_data)! |
end if |
end virtual |
;*************************************************************************** |
; End place |
; Mario79 |
;*************************************************************************** |
endg |
iglobal |
partition_types: ; list of fat16/32 partitions |
db 0x04 ; DOS: fat16 <32M |
db 0x06 ; DOS: fat16 >32M |
db 0x0b ; WIN95: fat32 |
db 0x0c ; WIN95: fat32, LBA-mapped |
db 0x0e ; WIN95: fat16, LBA-mapped |
db 0x14 ; Hidden DOS: fat16 <32M |
db 0x16 ; Hidden DOS: fat16 >32M |
db 0x1b ; Hidden WIN95: fat32 |
db 0x1c ; Hidden WIN95: fat32, LBA-mapped |
db 0x1e ; Hidden WIN95: fat16, LBA-mapped |
db 0xc4 ; DRDOS/secured: fat16 <32M |
db 0xc6 ; DRDOS/secured: fat16 >32M |
db 0xcb ; DRDOS/secured: fat32 |
db 0xcc ; DRDOS/secured: fat32, LBA-mapped |
db 0xce ; DRDOS/secured: fat16, LBA-mapped |
db 0xd4 ; Old Multiuser DOS secured: fat16 <32M |
db 0xd6 ; Old Multiuser DOS secured: fat16 >32M |
db 0x07 ; NTFS |
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 [problem_partition],0 |
call reserve_hd1 |
call reserve_hd_channel |
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 |
push edx |
add edx, [ebx+0x1be+12] ; add length |
dec edx ; PARTITION_END is inclusive |
mov [PARTITION_END], edx ; note that this can be changed |
; when file system data will be available |
mov dl, [ebx+0x1be+4] |
mov [fs_type], dl ; save for FS recognizer (separate FAT vs NTFS) |
pop edx |
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 |
add edx, [ebx+0x1be+8+16] |
push edx |
add edx, [ebx+0x1be+12+16] |
dec edx |
mov [PARTITION_END], edx |
mov dl, [ebx+0x1be+4+16] |
mov [fs_type], dl |
pop edx |
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 |
add edx, [ebx+0x1be+8+16+16] |
push edx |
add edx, [ebx+0x1be+12+16+16] |
dec edx |
mov [PARTITION_END], edx |
mov dl, [ebx+0x1be+4+16+16] |
mov [fs_type], dl |
pop edx |
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 |
add edx, [ebx+0x1be+8+16+16+16] |
push edx |
add edx, [ebx+0x1be+12+16+16+16] |
dec edx |
mov [PARTITION_END], edx |
mov dl, [ebx+0x1be+4+16+16+16] |
mov [fs_type], dl |
pop edx |
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 [fs_type],0 |
call free_hd_channel |
mov [hd1_status],0 ; free |
mov [problem_partition],1 |
ret |
hd_and_partition_ok: |
mov eax,edx |
mov [PARTITION_START],eax |
mov edx, [PARTITION_END] |
sub edx, eax |
inc edx ; edx = length of partition |
; mov [hd_setup],1 |
mov ebx,buffer |
call hd_read ; read boot sector of partition |
cmp [hd_error], 0 |
jz boot_read_ok |
cmp [fs_type], 7 |
jnz problem_fat_dec_count |
; NTFS duplicates bootsector: |
; NT4/2k/XP+ saves bootsector copy in the end of disk |
; NT 3.51 saves bootsector copy in the middle of disk |
and [hd_error], 0 |
mov eax, [PARTITION_END] |
call hd_read |
cmp [hd_error], 0 |
jnz @f |
call ntfs_test_bootsec |
jnc boot_read_ok |
@@: |
and [hd_error], 0 |
mov eax, edx |
shr eax, 1 |
add eax, [PARTITION_START] |
call hd_read |
cmp [hd_error], 0 |
jnz problem_fat_dec_count ; ¥ áã¤ì¡ ... |
boot_read_ok: |
; mov [hd_setup], 0 |
; if we are running on NTFS, check bootsector |
cmp [fs_type], 7 |
jz ntfs_setup |
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 [fs_type],32 ; Fat32 |
call free_hd_channel |
mov [hd1_status],0 ; free |
ret |
fat16_partition: |
xor eax,eax |
mov [ROOT_CLUSTER],eax |
popad |
mov [fatRESERVED],0x0000FFF6 |
mov [fatBAD],0x0000FFF7 |
mov [fatEND],0x0000FFF8 |
mov [fatMASK],0x0000FFFF |
mov [fs_type],16 ; Fat16 |
call free_hd_channel |
mov [hd1_status],0 ; free |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/kernel.asm |
---|
0,0 → 1,5114 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. |
;; PROGRAMMING: |
;; Ivan Poddubny |
;; Marat Zakiyanov (Mario79) |
;; VaStaNi |
;; Trans |
;; Mihail Semenyako (mike.dld) |
;; Sergey Kuzmin (Wildwest) |
;; Andrey Halyavin (halyavin) |
;; Mihail Lisovin (Mihasik) |
;; Andrey Ignatiev (andrew_programmer) |
;; NoName |
;; Evgeny Grechnikov (Diamond) |
;; Iliya Mihailov (Ghost) |
;; Sergey Semyonov (Serge) |
;; Johnny_B |
;; |
;; Data in this file was originally part of MenuetOS project which is |
;; distributed under the terms of GNU GPL. It is modified and redistributed as |
;; part of KolibriOS project under the terms of GNU GPL. |
;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa |
;; PROGRAMMING: |
;; |
;; Ville Mikael Turjanmaa, villemt@itu.jyu.fi |
;; - main os coding/design |
;; Jan-Michael Brummer, BUZZ2@gmx.de |
;; Felix Kaiser, info@felix-kaiser.de |
;; Paolo Minazzi, paolo.minazzi@inwind.it |
;; quickcode@mail.ru |
;; Alexey, kgaz@crosswinds.net |
;; Juan M. Caravaca, bitrider@wanadoo.es |
;; kristol@nic.fi |
;; Mike Hibbett, mikeh@oceanfree.net |
;; Lasse Kuusijarvi, kuusijar@lut.fi |
;; Jarek Pelczar, jarekp3@wp.pl |
;; |
;; KolibriOS is distributed in the hope that it will be useful, but WITHOUT ANY |
;; WARRANTY. No author or distributor accepts responsibility to anyone for the |
;; consequences of using it or for whether it serves any particular purpose or |
;; works at all, unless he says so in writing. Refer to the GNU General Public |
;; License (the "GPL") for full details. |
; |
;; Everyone is granted permission to copy, modify and redistribute KolibriOS, |
;; but only under the conditions described in the GPL. A copy of this license |
;; is supposed to have been given to you along with KolibriOS so you can know |
;; your rights and responsibilities. It should be in a file named COPYING. |
;; Among other things, the copyright notice and this notice must be preserved |
;; on all copies. |
;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
include 'macros.inc' |
$Revision$ |
include "proc32.inc" |
include "kglobals.inc" |
include "lang.inc" |
include "const.inc" |
max_processes equ 255 |
tss_step equ (128+8192) ; tss & i/o - 65535 ports, * 256=557056*4 |
os_stack equ (os_data_l-gdts) ; GDTs |
os_code equ (os_code_l-gdts) |
graph_data equ (3+graph_data_l-gdts) |
tss0 equ (tss0_l-gdts) |
app_code equ (3+app_code_l-gdts) |
app_data equ (3+app_data_l-gdts) |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; |
;; Included files: |
;; |
;; Kernel16.inc |
;; - Booteng.inc English text for bootup |
;; - Bootcode.inc Hardware setup |
;; - Pci16.inc PCI functions |
;; |
;; Kernel32.inc |
;; - Sys32.inc Process management |
;; - Shutdown.inc Shutdown and restart |
;; - Fat32.inc Read / write hd |
;; - Vesa12.inc Vesa 1.2 driver |
;; - Vesa20.inc Vesa 2.0 driver |
;; - Vga.inc VGA driver |
;; - Stack.inc Network interface |
;; - Mouse.inc Mouse pointer |
;; - Scincode.inc Window skinning |
;; - Pci32.inc PCI functions |
;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 16 BIT ENTRY FROM BOOTSECTOR ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
use16 |
org 0x0 |
jmp start_of_code |
version db 'Kolibri OS version 0.7.0.0 ',13,10,13,10,0 |
include "boot/bootstr.inc" ; language-independent boot messages |
include "boot/preboot.inc" |
if lang eq en |
include "boot/booteng.inc" ; english system boot messages |
else if lang eq ru |
include "boot/bootru.inc" ; russian system boot messages |
include "boot/ru.inc" ; Russian font |
else if lang eq et |
include "boot/bootet.inc" ; estonian system boot messages |
include "boot/et.inc" ; Estonian font |
else |
include "boot/bootge.inc" ; german system boot messages |
end if |
include "boot/bootcode.inc" ; 16 bit system boot code |
include "bus/pci/pci16.inc" |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; SWITCH TO 32 BIT PROTECTED MODE ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; CR0 Flags - Protected mode and Paging |
mov ecx, CR0_PE |
; Enabling 32 bit protected mode |
sidt [cs:old_ints_h] |
cli ; disable all irqs |
cld |
mov al,255 ; mask all irqs |
out 0xa1,al |
out 0x21,al |
l.5: in al, 0x64 ; Enable A20 |
test al, 2 |
jnz l.5 |
mov al, 0xD1 |
out 0x64, al |
l.6: in al, 0x64 |
test al, 2 |
jnz l.6 |
mov al, 0xDF |
out 0x60, al |
l.7: in al, 0x64 |
test al, 2 |
jnz l.7 |
mov al, 0xFF |
out 0x64, al |
lgdt [cs:tmp_gdt] ; Load GDT |
mov eax, cr0 ; protected mode |
or eax, ecx |
and eax, 10011111b *65536*256 + 0xffffff ; caching enabled |
mov cr0, eax |
jmp pword os_code:B32 ; jmp to enable 32 bit mode |
align 8 |
tmp_gdt: |
dw 23 |
dd tmp_gdt+0x10000 |
dw 0 |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10011010b |
db 0x00 |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10010010b |
db 0x00 |
include "data16.inc" |
use32 |
org $+0x10000 |
align 4 |
B32: |
mov ax,os_stack ; Selector for os |
mov ds,ax |
mov es,ax |
mov fs,ax |
mov gs,ax |
mov ss,ax |
mov esp,0x3ec00 ; Set stack |
; CLEAR 0x280000 - HEAP_BASE |
xor eax,eax |
mov edi,0x280000 |
mov ecx,(HEAP_BASE-OS_BASE-0x280000) / 4 |
cld |
rep stosd |
mov edi,0x40000 |
mov ecx,(0x90000-0x40000)/4 |
rep stosd |
; CLEAR KERNEL UNDEFINED GLOBALS |
mov edi, endofcode-OS_BASE |
mov ecx, (uglobals_size/4)+4 |
rep stosd |
; SAVE & CLEAR 0-0xffff |
xor esi, esi |
mov edi,0x2F0000 |
mov ecx,0x10000 / 4 |
rep movsd |
xor edi, edi |
mov ecx,0x10000 / 4 |
rep stosd |
call test_cpu |
bts [cpu_caps-OS_BASE], CAPS_TSC ;force use rdtsc |
; MEMORY MODEL |
call mem_test |
call init_mem |
call init_page_map |
; ENABLE PAGING |
mov eax, sys_pgdir-OS_BASE |
mov cr3, eax |
mov eax,cr0 |
or eax,CR0_PG+CR0_WP |
mov cr0,eax |
lgdt [gdts] |
jmp pword os_code:high_code |
align 4 |
tmp_page_tabs dd ? |
use16 |
org $-0x10000 |
include "boot/shutdown.inc" ; shutdown or restart |
org $+0x10000 |
use32 |
__DEBUG__ fix 1 |
__DEBUG_LEVEL__ fix 1 |
include 'init.inc' |
org OS_BASE+$ |
align 4 |
high_code: |
mov ax,os_stack |
mov bx,app_data |
mov ss,ax |
add esp, OS_BASE |
mov ds,bx |
mov es,bx |
mov fs,bx |
mov gs,bx |
bt [cpu_caps], CAPS_PGE |
jnc @F |
or dword [sys_pgdir+(OS_BASE shr 20)], PG_GLOBAL |
mov ebx, cr4 |
or ebx, CR4_PGE |
mov cr4, ebx |
@@: |
xor eax, eax |
mov dword [sys_pgdir], eax |
mov dword [sys_pgdir+4], eax |
mov eax, cr3 |
mov cr3, eax ; flush TLB |
; SAVE REAL MODE VARIABLES |
mov ax, [BOOT_VAR + 0x9031] |
mov [IDEContrRegsBaseAddr], ax |
; --------------- APM --------------------- |
; init selectors |
mov ebx, [BOOT_VAR+0x9040] ; offset of APM entry point |
movzx eax, word [BOOT_VAR+0x9050] ; real-mode segment base address of |
; protected-mode 32-bit code segment |
movzx ecx, word [BOOT_VAR+0x9052] ; real-mode segment base address of |
; protected-mode 16-bit code segment |
movzx edx, word [BOOT_VAR+0x9054] ; real-mode segment base address of |
; protected-mode 16-bit data segment |
shl eax, 4 |
mov [dword apm_code_32 + 2], ax |
shr eax, 16 |
mov [dword apm_code_32 + 4], al |
shl ecx, 4 |
mov [dword apm_code_16 + 2], cx |
shr ecx, 16 |
mov [dword apm_code_16 + 4], cl |
shl edx, 4 |
mov [dword apm_data_16 + 2], dx |
shr edx, 16 |
mov [dword apm_data_16 + 4], dl |
mov dword[apm_entry], ebx |
mov word [apm_entry + 4], apm_code_32 - gdts |
mov eax, [BOOT_VAR + 0x9044] ; version & flags |
mov [apm_vf], eax |
; ----------------------------------------- |
; movzx eax,byte [BOOT_VAR+0x9010] ; mouse port |
; mov [0xF604],byte 1 ;al |
mov al, [BOOT_VAR+0x901F] ; DMA access |
mov [allow_dma_access], al |
mov al,[BOOT_VAR+0x9000] ; bpp |
mov [ScreenBPP],al |
movzx eax,word [BOOT_VAR+0x900A] ; X max |
dec eax |
mov [ScreenWidth],eax |
mov [screen_workarea.right],eax |
movzx eax,word [BOOT_VAR+0x900C] ; Y max |
dec eax |
mov [ScreenHeight],eax |
mov [screen_workarea.bottom],eax |
movzx eax,word [BOOT_VAR+0x9008] ; screen mode |
mov [SCR_MODE],eax |
mov eax,[BOOT_VAR+0x9014] ; Vesa 1.2 bnk sw add |
mov [BANK_SWITCH],eax |
mov [BytesPerScanLine],word 640*4 ; Bytes PerScanLine |
cmp [SCR_MODE],word 0x13 ; 320x200 |
je @f |
cmp [SCR_MODE],word 0x12 ; VGA 640x480 |
je @f |
mov ax,[BOOT_VAR+0x9001] ; for other modes |
mov [BytesPerScanLine],ax |
@@: |
; GRAPHICS ADDRESSES |
mov byte [BOOT_VAR+0x901e],0x0 |
mov eax,[BOOT_VAR+0x9018] |
mov [LFBAddress],eax |
cmp [SCR_MODE],word 0100000000000000b |
jge setvesa20 |
cmp [SCR_MODE],word 0x13 |
je v20ga32 |
mov [PUTPIXEL],dword Vesa12_putpixel24 ; Vesa 1.2 |
mov [GETPIXEL],dword Vesa12_getpixel24 |
cmp [ScreenBPP],byte 24 |
jz ga24 |
mov [PUTPIXEL],dword Vesa12_putpixel32 |
mov [GETPIXEL],dword Vesa12_getpixel32 |
ga24: |
jmp v20ga24 |
setvesa20: |
mov [PUTPIXEL],dword Vesa20_putpixel24 ; Vesa 2.0 |
mov [GETPIXEL],dword Vesa20_getpixel24 |
cmp [ScreenBPP],byte 24 |
jz v20ga24 |
v20ga32: |
mov [PUTPIXEL],dword Vesa20_putpixel32 |
mov [GETPIXEL],dword Vesa20_getpixel32 |
v20ga24: |
cmp [SCR_MODE],word 0x12 ; 16 C VGA 640x480 |
jne no_mode_0x12 |
mov [PUTPIXEL],dword VGA_putpixel |
mov [GETPIXEL],dword Vesa20_getpixel32 |
no_mode_0x12: |
; -------- Fast System Call init ---------- |
; Intel SYSENTER/SYSEXIT (AMD CPU support it too) |
bt [cpu_caps], CAPS_SEP |
jnc .SEnP ; SysEnter not Present |
xor edx, edx |
mov ecx, MSR_SYSENTER_CS |
mov eax, os_code |
wrmsr |
mov ecx, MSR_SYSENTER_ESP |
; mov eax, sysenter_stack ; Check it |
xor eax, eax |
wrmsr |
mov ecx, MSR_SYSENTER_EIP |
mov eax, sysenter_entry |
wrmsr |
.SEnP: |
; AMD SYSCALL/SYSRET |
cmp byte[cpu_vendor], 'A' |
jne .noSYSCALL |
mov eax, 0x80000001 |
cpuid |
test edx, 0x800 ; bit_11 - SYSCALL/SYSRET support |
jz .noSYSCALL |
mov ecx, MSR_AMD_EFER |
rdmsr |
or eax, 1 ; bit_0 - System Call Extension (SCE) |
wrmsr |
; !!!! It`s dirty hack, fix it !!! |
; Bits of EDX : |
; Bit 3116 During the SYSRET instruction, this field is copied into the CS register |
; and the contents of this field, plus 8, are copied into the SS register. |
; Bit 150 During the SYSCALL instruction, this field is copied into the CS register |
; and the contents of this field, plus 8, are copied into the SS register. |
; mov edx, (os_code + 16) * 65536 + os_code |
mov edx, 0x1B0008 |
mov eax, syscall_entry |
mov ecx, MSR_AMD_STAR |
wrmsr |
.noSYSCALL: |
; ----------------------------------------- |
; LOAD IDT |
call build_interrupt_table |
lidt [idtreg] |
call init_kernel_heap |
stdcall kernel_alloc, RING0_STACK_SIZE+512 |
mov [os_stack_seg], eax |
lea esp, [eax+RING0_STACK_SIZE] |
mov [tss._ss0], os_stack |
mov [tss._esp0], esp |
mov [tss._esp], esp |
mov [tss._cs],os_code |
mov [tss._ss],os_stack |
mov [tss._ds],app_data |
mov [tss._es],app_data |
mov [tss._fs],app_data |
mov [tss._gs],app_data |
mov [tss._io],128 |
;Add IO access table - bit array of permitted ports |
mov edi, tss._io_map_0 |
xor eax, eax |
not eax |
mov ecx, 8192/4 |
rep stosd ; access to 4096*8=65536 ports |
mov ax,tss0 |
ltr ax |
mov [LFBSize], 0x800000 |
call init_LFB |
call init_fpu |
call init_malloc |
stdcall alloc_kernel_space, 0x51000 |
mov [default_io_map], eax |
add eax, 0x2000 |
mov [ipc_tmp], eax |
mov ebx, 0x1000 |
add eax, 0x40000 |
mov [proc_mem_map], eax |
add eax, 0x8000 |
mov [proc_mem_pdir], eax |
add eax, ebx |
mov [proc_mem_tab], eax |
add eax, ebx |
mov [tmp_task_pdir], eax |
add eax, ebx |
mov [tmp_task_ptab], eax |
add eax, ebx |
mov [ipc_pdir], eax |
add eax, ebx |
mov [ipc_ptab], eax |
call init_events |
mov eax, srv.fd-SRV_FD_OFFSET |
mov [srv.fd], eax |
mov [srv.bk], eax |
mov edi, irq_tab |
xor eax, eax |
mov ecx, 16 |
rep stosd |
;Set base of graphic segment to linear address of LFB |
mov eax,[LFBAddress] ; set for gs |
mov [graph_data_l+2],ax |
shr eax,16 |
mov [graph_data_l+4],al |
mov [graph_data_l+7],ah |
mov [CURRENT_TASK],dword 1 |
mov [TASK_COUNT],dword 1 |
mov [TASK_BASE],dword TASK_DATA |
mov [current_slot], SLOT_BASE+256 |
; set background |
xor eax,eax |
inc eax |
mov [BgrDrawMode],eax |
mov [BgrDataWidth],eax |
mov [BgrDataHeight],eax |
mov [mem_BACKGROUND],4095 |
stdcall kernel_alloc, [mem_BACKGROUND] |
mov [img_background], eax |
;!!!!!!!!!!!!!!!!!!!!!!!!!! |
include 'detect/disks.inc' |
;!!!!!!!!!!!!!!!!!!!!!!!!!! |
call Parser_params |
; READ RAMDISK IMAGE FROM HD |
;!!!!!!!!!!!!!!!!!!!!!!! |
include 'boot/rdload.inc' |
;!!!!!!!!!!!!!!!!!!!!!!! |
; mov [dma_hdd],1 |
; CALCULATE FAT CHAIN FOR RAMDISK |
call calculatefatchain |
; LOAD VMODE DRIVER |
;!!!!!!!!!!!!!!!!!!!!!!! |
include 'vmodeld.inc' |
;!!!!!!!!!!!!!!!!!!!!!!! |
mov ax,[OS_BASE+0x10000+bx_from_load] |
cmp ax,'r1' ; if using not ram disk, then load librares and parameters {SPraid.simba} |
je no_lib_load |
; LOADING LIBRARES |
stdcall dll.Load,@IMPORT ; loading librares for kernel (.obj files) |
call load_file_parse_table ; prepare file parse table |
call set_kernel_conf ; configure devices and gui |
no_lib_load: |
; LOAD FONTS I and II |
; pushad |
; push eax |
; mov eax,char |
; call file_system_lfn |
; mov eax,char2 |
; call file_system_lfn |
; pop eax |
; popad |
stdcall read_file, char, FONT_I, 0, 2560 |
stdcall read_file, char2, FONT_II, 0, 2560 |
mov esi,boot_fonts |
call boot_log |
; PRINT AMOUNT OF MEMORY |
mov esi, boot_memdetect |
call boot_log |
movzx ecx, word [boot_y] |
or ecx, (10+29*6) shl 16 ; "Determining amount of memory" |
sub ecx, 10 |
mov edx, 0xFFFFFF |
mov ebx, [MEM_AMOUNT] |
shr ebx, 20 |
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 |
mov esi,boot_devices |
call boot_log |
call detect_devices |
stdcall load_driver, szPS2MDriver |
; 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 |
mov [pci_access_enabled],1 |
; 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 |
xor eax, eax |
mov dword [SLOT_BASE+APPDATA.fpu_state], fpu_data |
mov dword [SLOT_BASE+APPDATA.fpu_handler], eax |
mov dword [SLOT_BASE+APPDATA.sse_handler], eax |
; name for OS/IDLE process |
mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I' |
mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE ' |
mov edi, [os_stack_seg] |
mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi |
add edi, 0x2000-512 |
mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi |
mov dword [SLOT_BASE+256+APPDATA.io_map],\ |
(tss._io_map_0-OS_BASE+PG_MAP) |
mov dword [SLOT_BASE+256+APPDATA.io_map+4],\ |
(tss._io_map_1-OS_BASE+PG_MAP) |
mov esi, fpu_data |
mov ecx, 512/4 |
cld |
rep movsd |
mov dword [SLOT_BASE+256+APPDATA.fpu_handler], eax |
mov dword [SLOT_BASE+256+APPDATA.sse_handler], eax |
mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET |
mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx |
mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx |
mov dword [SLOT_BASE+256+APPDATA.cur_dir], sysdir_path |
; task list |
mov [CURRENT_TASK],dword 1 |
mov [TASK_COUNT],dword 1 |
mov [current_slot], SLOT_BASE+256 |
mov [TASK_BASE],dword TASK_DATA |
mov [TASK_DATA+TASKDATA.wnd_number], 1 ; on screen number |
mov [TASK_DATA+TASKDATA.pid], 1 ; process id number |
mov [TASK_DATA+TASKDATA.mem_start], 0 ; process base address |
call init_cursors |
mov eax, [def_cursor] |
mov [SLOT_BASE+APPDATA.cursor],eax |
mov [SLOT_BASE+APPDATA.cursor+256],eax |
; READ TSC / SECOND |
mov esi,boot_tsc |
call boot_log |
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 [CPU_FREQ],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 [SCR_MODE],word 0x12 |
jne no_pal_vga |
mov esi,boot_pal_vga |
call boot_log |
call paletteVGA |
no_pal_vga: |
cmp [SCR_MODE],word 0x13 |
jne no_pal_ega |
mov esi,boot_pal_ega |
call boot_log |
call palette320x200 |
no_pal_ega: |
; LOAD DEFAULT SKIN |
call load_default_skin |
;protect io permission map |
mov esi, [default_io_map] |
stdcall map_page,esi,(tss._io_map_0-OS_BASE), PG_MAP |
add esi, 0x1000 |
stdcall map_page,esi,(tss._io_map_1-OS_BASE), PG_MAP |
stdcall map_page,tss._io_map_0,\ |
(tss._io_map_0-OS_BASE), PG_MAP |
stdcall map_page,tss._io_map_1,\ |
(tss._io_map_1-OS_BASE), PG_MAP |
mov ax,[OS_BASE+0x10000+bx_from_load] |
cmp ax,'r1' ; if not rused ram disk - load network configuration from files {SPraid.simba} |
je no_st_network |
call set_network_conf |
no_st_network: |
; LOAD FIRST APPLICATION |
cli |
cmp byte [BOOT_VAR+0x9030],1 |
jne no_load_vrr_m |
mov ebp, vrr_m |
call fs_execute_from_sysdir |
cmp eax,2 ; if vrr_m app found (PID=2) |
je first_app_found |
no_load_vrr_m: |
mov ebp, firstapp |
call fs_execute_from_sysdir |
cmp eax,2 ; continue if a process has been loaded |
je first_app_found |
mov eax, 0xDEADBEEF ; otherwise halt |
hlt |
first_app_found: |
cli |
;mov [TASK_COUNT],dword 2 |
mov [CURRENT_TASK],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 |
; 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 [ENABLE_TASKSWITCH],byte 1 ; multitasking enabled |
; UNMASK ALL IRQ'S |
mov esi,boot_allirqs |
call boot_log |
cli ;guarantee forbidance of interrupts. |
mov al,0 ; unmask all irq's |
out 0xA1,al |
out 0x21,al |
mov ecx,32 |
ready_for_irqs: |
mov al,0x20 ; ready for irqs |
out 0x20,al |
out 0xa0,al |
loop ready_for_irqs ; flush the queue |
stdcall attach_int_handler, dword 1, irq1 |
; mov [dma_hdd],1 |
cmp [IDEContrRegsBaseAddr], 0 |
setnz [dma_hdd] |
; stdcall init_uart_service, DRV_ENTRY |
sti |
call change_task |
jmp osloop |
jmp $ ; wait here for timer to take control |
; Fly :) |
include 'unpacker.inc' |
include 'fdo.inc' |
align 4 |
boot_log: |
pushad |
mov 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+OS_BASE+0x10000],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 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; ; |
; 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], 1 ; timer |
mov [irq_owner+4*1], 1 ; keyboard |
mov [irq_owner+4*5], 1 ; sound blaster |
mov [irq_owner+4*6], 1 ; floppy diskette |
mov [irq_owner+4*13], 1 ; math co-pros |
mov [irq_owner+4*14], 1 ; ide I |
mov [irq_owner+4*15], 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-0x2d |
mov [RESERVED_PORTS],edi |
shl edi,4 |
mov [RESERVED_PORTS+edi+0],dword 1 |
mov [RESERVED_PORTS+edi+4],dword 0x0 |
mov [RESERVED_PORTS+edi+8],dword 0x2d |
inc dword [RESERVED_PORTS] ; 0x30-0x4d |
mov edi,[RESERVED_PORTS] |
shl edi,4 |
mov [RESERVED_PORTS+edi+0],dword 1 |
mov [RESERVED_PORTS+edi+4],dword 0x30 |
mov [RESERVED_PORTS+edi+8],dword 0x4d |
inc dword [RESERVED_PORTS] ; 0x50-0xdf |
mov edi,[RESERVED_PORTS] |
shl edi,4 |
mov [RESERVED_PORTS+edi+0],dword 1 |
mov [RESERVED_PORTS+edi+4],dword 0x50 |
mov [RESERVED_PORTS+edi+8],dword 0xdf |
inc dword [RESERVED_PORTS] ; 0xe5-0xff |
mov edi,[RESERVED_PORTS] |
shl edi,4 |
mov [RESERVED_PORTS+edi+0],dword 1 |
mov [RESERVED_PORTS+edi+4],dword 0xe5 |
mov [RESERVED_PORTS+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 [MOUSE_BUFF_COUNT],byte 0 ; mouse buffer |
mov [KEY_COUNT],byte 0 ; keyboard buffer |
mov [BTN_COUNT],byte 0 ; button buffer |
; mov [MOUSE_X],dword 100*65536+100 ; mouse x/y |
push eax |
mov ax,[BOOT_VAR+0x900c] |
shr ax,1 |
shl eax,16 |
mov ax,[BOOT_VAR+0x900A] |
shr ax,1 |
mov [MOUSE_X],eax |
pop eax |
mov byte [SB16_Status],0 ; Minazzi Paolo |
mov [BTN_ADDR],dword BUTTON_INFO ; address of button list |
;!! IP 04.02.2005: |
mov [next_usage_update], 100 |
mov byte [DONT_SWITCH], 0 ; change task if possible |
ret |
;* mouse centered - start code- Mario79 |
mouse_centered: |
push eax |
mov eax,[ScreenWidth] |
shr eax,1 |
mov [MOUSE_X],ax |
mov eax,[ScreenHeight] |
shr eax,1 |
mov [MOUSE_Y],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,[RESERVED_PORTS] |
test ecx,ecx |
jne sopl8 |
mov [esp+36],dword 1 |
ret |
sopl8: |
mov edx,[TASK_BASE] |
mov edx,[edx+0x4] |
and ebx,65535 |
cld |
sopl1: |
mov esi,ecx |
shl esi,4 |
add esi,RESERVED_PORTS |
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 |
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,[CURRENT_TASK] |
; shl edi,8 |
; add ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] |
; rol eax,16 |
; add ax,word[edi+SLOT_BASE+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,[TASK_BASE] |
mov edi,[CURRENT_TASK] |
shl edi,8 |
mov ebx,[edx-twdw+WDATA.box.left] |
add ebx,[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] |
shl ebx,16 |
add ebx,[edx-twdw+WDATA.box.top] |
add ebx,[edi+SLOT_BASE+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 |
; 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 |
iglobal |
midi_base dw 0 |
endg |
nsyse1: |
cmp eax,2 ; KEYBOARD |
jnz nsyse2 |
cmp ebx,1 |
jnz kbnobase |
mov edi,[TASK_BASE] |
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,[TASK_BASE] |
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,[TASK_BASE] |
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,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: |
call reserve_hd1 |
call reserve_hd_channel |
call free_hd_channel |
mov [hd1_status],0 ; free |
nosethd: |
ret |
iglobal |
hd_base db 0 |
endg |
nsyse7: |
cmp eax,8 ; HD PARTITION |
jne nsyse8 |
mov [fat32part],ebx |
; call set_FAT32_variables |
call reserve_hd1 |
call reserve_hd_channel |
call free_hd_channel |
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 |
; 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,[TASK_BASE] |
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,[TASK_BASE] |
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,[TASK_BASE] |
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,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 |
get_timer_ticks: |
mov eax,[timer_ticks] |
ret |
iglobal |
align 4 |
mousefn dd msscreen, mswin, msbutton, msset |
dd app_load_cursor |
dd app_set_cursor |
dd app_delete_cursor |
dd msz |
endg |
readmousepos: |
; eax=0 screen relative |
; eax=1 window relative |
; eax=2 buttons pressed |
; eax=3 set mouse pos ; reserved |
; eax=4 load cursor |
; eax=5 set cursor |
; eax=6 delete cursor ; reserved |
; eax=7 get mouse_z |
cmp eax, 7 |
ja msset |
jmp [mousefn+eax*4] |
msscreen: |
mov eax,[MOUSE_X] |
shl eax,16 |
mov ax,[MOUSE_Y] |
mov [esp+36],eax |
ret |
mswin: |
mov eax,[MOUSE_X] |
shl eax,16 |
mov ax,[MOUSE_Y] |
mov esi,[TASK_BASE] |
mov bx, word [esi-twdw+WDATA.box.left] |
shl ebx,16 |
mov bx, word [esi-twdw+WDATA.box.top] |
sub eax,ebx |
mov edi,[CURRENT_TASK] |
shl edi,8 |
sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.top] |
rol eax,16 |
sub ax,word[edi+SLOT_BASE+APPDATA.wnd_clientbox.left] |
rol eax,16 |
mov [esp+36],eax |
ret |
msbutton: |
movzx eax,byte [BTN_DOWN] |
mov [esp+36],eax |
ret |
msz: |
mov edi, [TASK_COUNT] |
movzx edi, word [WIN_POS + edi*2] |
cmp edi, [CURRENT_TASK] |
jne @f |
mov ax,[MOUSE_SCROLL_H] |
shl eax,16 |
mov ax,[MOUSE_SCROLL_V] |
mov [esp+36],eax |
mov [MOUSE_SCROLL_H],word 0 |
mov [MOUSE_SCROLL_V],word 0 |
ret |
@@: |
mov [esp+36],dword 0 |
ret |
msset: |
ret |
app_load_cursor: |
; add ebx, new_app_base |
cmp ebx, OS_BASE |
jae msset |
stdcall load_cursor, ebx, ecx |
mov [esp+36], eax |
ret |
app_set_cursor: |
stdcall set_cursor, ebx |
mov [esp+36], eax |
ret |
app_delete_cursor: |
stdcall delete_cursor, ebx |
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,[TASK_BASE] |
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 [BOOT_VAR+0x9030],byte 0 |
for_shutdown_parameter: |
mov eax,[TASK_COUNT] |
add eax,2 |
mov [shutdown_processes],eax |
mov [SYS_SHUTDOWN],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,[TASK_COUNT] |
cmp ebx,edx |
ja noprocessterminate |
mov eax,[TASK_COUNT] |
shl ebx,5 |
mov edx,[ebx+CURRENT_TASK+TASKDATA.pid] |
add ebx,CURRENT_TASK+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,[TASK_COUNT] |
ja .nowindowactivate |
mov [window_minimize], 2 ; restore window if minimized |
movzx esi, word [WIN_STACK + ebx*2] |
cmp esi, [TASK_COUNT] |
je .nowindowactivate ; already active |
mov edi, ebx |
shl edi, 5 |
add edi, window_data |
movzx esi, word [WIN_STACK + ebx * 2] |
lea esi, [WIN_POS + 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,[CPU_FREQ] |
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, [TASK_COUNT] |
movzx eax, word [WIN_POS + 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 [BOOT_VAR+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,[TASK_BASE] |
mov edi,[edi+TASKDATA.mem_start] |
add edi,ecx |
mov esi,DRIVE_DATA |
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,[TASK_BASE] |
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 [MOUSE_Y],cx ;y |
ror ecx,16 |
mov [MOUSE_X],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,7,0,0 ; version 0.7.0.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 [BgrDataWidth],ebx |
mov [BgrDataHeight],ecx |
; mov [bgrchanged],1 |
pushad |
; return memory for old background |
stdcall kernel_free, [img_background] |
; calculate RAW size |
xor eax,eax |
inc eax |
cmp [BgrDataWidth],eax |
jae @f |
mov [BgrDataWidth],eax |
@@: |
cmp [BgrDataHeight],eax |
jae @f |
mov [BgrDataHeight],eax |
@@: |
mov eax,[BgrDataWidth] |
imul eax,[BgrDataHeight] |
lea eax,[eax*3] |
mov [mem_BACKGROUND],eax |
; get memory for new background |
stdcall kernel_alloc, [mem_BACKGROUND] |
test eax, eax |
jz .exit_mem |
mov [img_background], eax |
.exit_mem: |
popad |
sbgrr: |
ret |
nosb1: |
cmp eax,2 ; SET PIXEL |
jnz nosb2 |
mov edx,[mem_BACKGROUND] |
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+IMG_BACKGROUND],edx |
push eax |
mov eax,[img_background] |
mov [ebx+eax],edx |
pop eax |
; 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 [REDRAW_BACKGROUND],byte 1 |
mov [background_defined], 1 |
nosb31: |
ret |
nosb3: |
cmp eax,4 ; TILED / STRETCHED |
jnz nosb4 |
cmp ebx,[BgrDrawMode] |
je nosb41 |
mov [BgrDrawMode],ebx |
; mov [bgrchanged],1 |
nosb41: |
ret |
nosb4: |
cmp eax,5 ; BLOCK MOVE TO BGR |
jnz nosb5 |
; bughere |
mov eax, ebx |
mov ebx, ecx |
add ebx, [img_background] ;IMG_BACKGROUND |
mov ecx, edx |
call memmove |
.fin: |
ret |
nosb5: |
ret |
align 4 |
sys_getbackground: |
cmp eax,1 ; SIZE |
jnz nogb1 |
mov eax,[BgrDataWidth] |
shl eax,16 |
mov ax,[BgrDataHeight] |
mov [esp+36],eax |
ret |
nogb1: |
cmp eax,2 ; PIXEL |
jnz nogb2 |
; mov edx,0x160000-16 |
; cmp edx,ebx |
; jbe nogb2 |
; mov eax, [ebx+IMG_BACKGROUND] |
mov eax,[img_background] |
mov eax,[ebx+eax] |
and eax, 0xFFFFFF |
mov [esp+36],eax |
ret |
nogb2: |
cmp eax,4 ; TILED / STRETCHED |
jnz nogb4 |
mov eax,[BgrDrawMode] |
nogb4: |
mov [esp+36],eax |
ret |
align 4 |
sys_getkey: |
mov [esp+36],dword 1 |
; test main buffer |
mov ebx, [CURRENT_TASK] ; TOP OF WINDOW STACK |
movzx ecx,word [WIN_STACK + ebx * 2] |
mov edx,[TASK_COUNT] |
cmp ecx,edx |
jne .finish |
cmp [KEY_COUNT],byte 0 |
je .finish |
movzx eax,byte [KEY_BUFF] |
shl eax,8 |
push eax |
dec byte [KEY_COUNT] |
and byte [KEY_COUNT],127 |
movzx ecx,byte [KEY_COUNT] |
add ecx,2 |
; mov esi,0xf402 |
; mov edi,0xf401 |
; cld |
; rep movsb |
mov eax, KEY_BUFF+1 |
mov ebx, KEY_BUFF |
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, [CURRENT_TASK] ; TOP OF WINDOW STACK |
mov [esp+36],dword 1 |
movzx ecx, word [WIN_STACK + ebx * 2] |
mov edx, [TASK_COUNT] ; less than 256 processes |
cmp ecx,edx |
jne .exit |
movzx eax,byte [BTN_COUNT] |
test eax,eax |
jz .exit |
mov eax,[BTN_BUFF] |
shl eax,8 |
mov [BTN_COUNT],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,[TASK_BASE] ; eax = return area |
add eax,[edi + TASKDATA.mem_start] |
cmp ebx,-1 ; who am I ? |
jne no_who_am_i |
mov ebx,[CURRENT_TASK] |
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,CURRENT_TASK+TASKDATA.cpu_usage |
mov ebx,eax |
pop eax |
mov ecx,[ebx] |
mov [eax],ecx |
pop ebx |
mov cx, [WIN_STACK + ebx * 2] |
mov [eax+4],cx |
mov cx, [WIN_POS + ebx * 2] |
mov [eax+6],cx |
push eax |
mov eax,ebx |
shl eax,8 |
add eax,SLOT_BASE+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,[SLOT_BASE+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,CURRENT_TASK+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,CURRENT_TASK+TASKDATA.state |
mov eax,[eax] |
mov [ebx+40],ax |
; Window client area box |
mov esi,[esp] |
shl esi,8 |
add esi,SLOT_BASE+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+WDATA.fl_wstate] |
mov [edi],al |
pop ebx |
pop eax |
; return number of processes |
mov eax,[TASK_COUNT] |
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,[CURRENT_TASK] |
sys_newba2: |
mov edi,[BTN_ADDR] |
cmp [edi],dword 0 ; empty button list ? |
je end_of_buttons_away |
movzx ebx,word [edi] |
inc ebx |
mov eax,edi |
sys_newba: |
dec ebx |
jz end_of_buttons_away |
add eax,0x10 |
cmp cx,[eax] |
jnz sys_newba |
push eax ebx ecx |
mov ecx,ebx |
inc ecx |
shl ecx,4 |
mov ebx,eax |
add eax,0x10 |
call memmove |
dec dword [edi] |
pop ecx ebx eax |
jmp sys_newba2 |
end_of_buttons_away: |
ret |
no_widgets_away: |
cmp eax,2 |
jnz srl1 |
mov edx,[TASK_BASE] ; return whole screen draw area for this app |
add edx,draw_data-CURRENT_TASK |
mov [edx+RECT.left], 0 |
mov [edx+RECT.top], 0 |
mov eax,[ScreenWidth] |
mov [edx+RECT.right],eax |
mov eax,[ScreenHeight] |
mov [edx+RECT.bottom],eax |
mov edi,[TASK_BASE] |
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, [TASK_COUNT] |
movzx edi, word [WIN_POS + edi*2] |
cmp edi, [CURRENT_TASK] |
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,[TASK_COUNT] |
movzx edx,word[WIN_POS+edx*2] |
cmp edx,[CURRENT_TASK] |
jne @f |
inc eax |
@@: mov edx,[CURRENT_TASK] |
shl edx,5 |
add edx,window_data |
movzx ebx,[edx+WDATA.fl_wstyle] |
and bl,0x0F |
cmp bl,3 |
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,[CURRENT_TASK] |
shl edi,5 |
test [edi+window_data+WDATA.fl_wstyle],WSTYLE_HASCAPTION |
jz @f |
mov ecx,[edi*8+SLOT_BASE+APPDATA.wnd_caption] |
or ecx,ecx |
jz @f |
add ecx,[edi+CURRENT_TASK+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+SLOT_BASE+APPDATA.wnd_clientbox.left],eax |
shl eax,1 |
neg eax |
add eax,[ecx+WDATA.box.width] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax |
movzx eax,[ecx+WDATA.fl_wstyle] |
and eax,0x0F |
push [eax*8+window_topleft+0] |
mov eax,[eax*8+window_topleft+4] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax |
neg eax |
sub eax,[esp] |
add eax,[ecx+WDATA.box.height] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax |
add esp,4 |
pop edi ecx eax |
ret |
@@: |
xor eax,eax |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.left],eax |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.top],eax |
mov eax,[ecx+WDATA.box.width] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.width],eax |
mov eax,[ecx+WDATA.box.height] |
mov [edi+SLOT_BASE+APPDATA.wnd_clientbox.height],eax |
pop edi ecx eax |
ret |
sys_set_window: |
mov edi,[CURRENT_TASK] |
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,SLOT_BASE |
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 [KEY_COUNT],byte 0 ; empty keyboard buffer |
mov [BTN_COUNT],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,[CURRENT_TASK] |
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+SLOT_BASE+APPDATA.mem_size] |
; add ecx,255 ; max caption length |
; cmp ebx,ecx |
; ja .exit_fail |
mov [edi*8+SLOT_BASE+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,[CURRENT_TASK] |
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, SLOT_BASE + 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 [DONT_DRAW_MOUSE],byte 0 ; mouse pointer |
mov [MOUSE_BACKGROUND],byte 0 ; no mouse under |
mov [MOUSE_DOWN],byte 0 ; react to mouse up/down |
call [draw_pointer] |
mov [window_move_pr],0 |
.window_move_return: |
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 |
; Fast Call MSR can't be destroy |
; Íî MSR_AMD_EFER ìîæíî èçìåíÿòü, ò.ê. â ýòîì ðåãèñòðå ëèø |
; âêëþ÷àþòñÿ/âûêëþ÷àþòñÿ ðàñøèðåííûå âîçìîæíîñòè |
cmp ecx, MSR_SYSENTER_CS |
je @f |
cmp ecx, MSR_SYSENTER_ESP |
je @f |
cmp ecx, MSR_SYSENTER_EIP |
je @f |
cmp ecx, MSR_AMD_STAR |
je @f |
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,[ScreenWidth] ; screen x size |
inc edx |
imul edx, ebx |
mov dl, [eax+edx+display_data] ; lea eax, [...] |
xor ecx, ecx |
mov eax, [CURRENT_TASK] |
cmp al, dl |
setne cl |
pop edx eax |
ret |
iglobal |
cpustring db 'CPU',0 |
endg |
uglobal |
background_defined db 0 ; diamond, 11.04.2006 |
endg |
align 4 |
; check misc |
checkmisc: |
cmp [ctrl_alt_del], 1 |
jne nocpustart |
mov ebp, cpustring |
call fs_execute_from_sysdir |
mov [ctrl_alt_del], 0 |
nocpustart: |
cmp [mouse_active], 1 |
jne mouse_not_active |
mov [mouse_active], 0 |
xor edi, edi |
mov ecx, [TASK_COUNT] |
set_mouse_event: |
add edi, 256 |
or [edi+SLOT_BASE+APPDATA.event_mask], dword 100000b |
loop set_mouse_event |
mouse_not_active: |
cmp [REDRAW_BACKGROUND],byte 0 ; background update ? |
jz nobackgr |
cmp [background_defined], 0 |
jz nobackgr |
; mov [REDRAW_BACKGROUND],byte 2 |
; call change_task |
xor edi, edi |
mov ecx, [TASK_COUNT] |
set_bgr_event: |
add edi, 256 |
or [edi+SLOT_BASE+APPDATA.event_mask], 16 |
loop set_bgr_event |
mov [draw_data+32 + RECT.left],dword 0 |
mov [draw_data+32 + RECT.top],dword 0 |
mov eax,[ScreenWidth] |
mov ebx,[ScreenHeight] |
mov [draw_data+32 + RECT.right],eax |
mov [draw_data+32 + RECT.bottom],ebx |
call drawbackground |
mov [REDRAW_BACKGROUND],byte 0 |
mov [MOUSE_BACKGROUND],byte 0 |
nobackgr: |
; system shutdown request |
cmp [SYS_SHUTDOWN],byte 0 |
je noshutdown |
mov edx,[shutdown_processes] |
sub dl,2 |
cmp [SYS_SHUTDOWN],dl |
jne no_mark_system_shutdown |
mov edx,OS_BASE+0x3040 |
movzx ecx,byte [SYS_SHUTDOWN] |
add ecx,5 |
markz: |
mov [edx+TASKDATA.state],byte 3 |
add edx,0x20 |
loop markz |
no_mark_system_shutdown: |
call [disable_mouse] |
dec byte [SYS_SHUTDOWN] |
cmp [SYS_SHUTDOWN],byte 0 |
je system_shutdown |
noshutdown: |
mov eax,[TASK_COUNT] ; termination |
mov ebx,TASK_DATA+TASKDATA.state |
mov esi,1 |
newct: |
mov cl,[ebx] |
cmp cl,byte 3 |
jz terminate |
cmp cl,byte 4 |
jz terminate |
add ebx,0x20 |
inc esi |
dec eax |
jnz newct |
ret |
; redraw screen |
redrawscreen: |
; eax , if process window_data base is eax, do not set flag/limits |
pushad |
push eax |
;;; mov 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,[TASK_COUNT] |
jle newdw2 |
pop eax |
popad |
ret |
calculatebackground: ; background |
; all black |
mov edi, [img_background] ;IMG_BACKGROUND ; set background to black |
xor eax, eax |
mov ecx, 1023 ;0x0fff00 / 4 |
cld |
rep stosd |
mov edi,display_data ; set os to use all pixels |
mov eax,0x01010101 |
mov ecx,1280*1024 / 4 |
rep stosd |
mov byte [REDRAW_BACKGROUND], 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,[TASK_BASE] |
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,[TASK_BASE] |
; add edi,0x10 |
; add esi,[edi] |
; add eax,[edi] |
; |
; pushad |
; mov edi,esi |
; add edi,1024 |
; mov esi,0x100000+19*512 |
; sub ecx,1 |
; shl ecx,9 |
; add esi,ecx |
; shl edx,9 |
; mov ecx,edx |
; cld |
; rep movsb |
; popad |
; |
; mov [esp+36],eax |
; mov [esp+24],ebx |
; ret |
align 4 |
sys_programirq: |
mov edi,[TASK_BASE] |
add eax,[edi+TASKDATA.mem_start] |
cmp ebx,16 |
jae .not_owner |
mov edi,[TASK_BASE] |
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,[TASK_BASE] |
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,IRQ_SAVE |
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, tss._io_map_0 |
; mov ecx,eax |
; and ecx,7 ; offset in byte |
; shr eax,3 ; number of byte |
; add edi,eax |
; mov ebx,1 |
; shl ebx,cl |
cmp ebp,0 ; enable access - ebp = 0 |
jne siar1 |
; not ebx |
; and [edi],byte bl |
btr [edi], eax |
popad |
ret |
siar1: |
bts [edi], eax |
; 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,[RESERVED_PORTS] |
test esi,esi ; no reserved areas ? |
je rpal2 |
cmp esi,255 ; max reserved |
jae rpal1 |
rpal3: |
mov edi,esi |
shl edi,4 |
add edi,RESERVED_PORTS |
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,[RESERVED_PORTS] |
add edi,1 |
mov [RESERVED_PORTS],edi |
shl edi,4 |
add edi,RESERVED_PORTS |
mov esi,[TASK_BASE] |
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,[RESERVED_PORTS] ; no reserved areas ? |
test esi,esi |
je frpal2 |
mov edx,[TASK_BASE] |
mov edx,[edx+TASKDATA.pid] |
frpal3: |
mov edi,esi |
shl edi,4 |
add edi,RESERVED_PORTS |
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 [RESERVED_PORTS] |
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,[TASK_BASE] |
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,[TASK_BASE] |
mov edx,[edx+TASKDATA.pid] |
mov [edi],edx |
dec ecx |
ril1: |
mov [esp+36],ecx ; return in eax |
ret |
drawbackground: |
inc [mouse_pause] |
cmp [SCR_MODE],word 0x12 |
je dbrv20 |
dbrv12: |
cmp [SCR_MODE],word 0100000000000000b |
jge dbrv20 |
cmp [SCR_MODE],word 0x13 |
je dbrv20 |
call vesa12_drawbackground |
dec [mouse_pause] |
call [draw_pointer] |
ret |
dbrv20: |
cmp [BgrDrawMode],dword 1 |
jne bgrstr |
call vesa20_drawbackground_tiled |
dec [mouse_pause] |
call [draw_pointer] |
ret |
bgrstr: |
call vesa20_drawbackground_stretch |
dec [mouse_pause] |
call [draw_pointer] |
ret |
align 4 |
syscall_putimage: ; PutImage |
mov edx,ecx |
mov ecx,ebx |
mov ebx, eax |
sys_putimage: |
test ecx,0x80008000 |
jnz .exit |
test ecx,0x0000FFFF |
jz .exit |
test ecx,0xFFFF0000 |
jnz @f |
.exit: |
ret |
@@: |
mov edi,[current_slot] |
add dx,word[edi+APPDATA.wnd_clientbox.top] |
rol edx,16 |
add dx,word[edi+APPDATA.wnd_clientbox.left] |
rol edx,16 |
.forced: |
push ebp esi 0 |
mov ebp, putimage_get24bpp |
mov esi, putimage_init24bpp |
sys_putimage_bpp: |
; call [disable_mouse] ; this will be done in xxx_putimage |
; mov eax, vga_putimage |
cmp [SCR_MODE], word 0x12 |
jz @f ;.doit |
mov eax, vesa12_putimage |
cmp [SCR_MODE], word 0100000000000000b |
jae @f |
cmp [SCR_MODE], word 0x13 |
jnz .doit |
@@: |
mov eax, vesa20_putimage |
.doit: |
inc [mouse_pause] |
call eax |
dec [mouse_pause] |
pop ebp esi ebp |
jmp [draw_pointer] |
syscall_putimage_palette: |
mov edi, esi |
mov esi, edx |
mov edx, ecx |
mov ecx, ebx |
mov ebx, eax |
sys_putimage_palette: |
; ebx = pointer to image |
; ecx = [xsize]*65536 + [ysize] |
; edx = [xstart]*65536 + [ystart] |
; esi = number of bits per pixel, must be 8, 24 or 32 |
; edi = pointer to palette |
; ebp = row delta |
mov eax, [CURRENT_TASK] |
shl eax, 8 |
add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.top] |
rol edx, 16 |
add dx, word [eax+SLOT_BASE+APPDATA.wnd_clientbox.left] |
rol edx, 16 |
.forced: |
push ebp esi ebp |
cmp esi, 8 |
jnz @f |
mov ebp, putimage_get8bpp |
mov esi, putimage_init8bpp |
jmp sys_putimage_bpp |
@@: |
cmp esi, 24 |
jnz @f |
mov ebp, putimage_get24bpp |
mov esi, putimage_init24bpp |
jmp sys_putimage_bpp |
@@: |
cmp esi, 32 |
jnz @f |
mov ebp, putimage_get32bpp |
mov esi, putimage_init32bpp |
jmp sys_putimage_bpp |
@@: |
pop ebp esi |
ret |
putimage_init24bpp: |
lea eax, [eax*3] |
putimage_init8bpp: |
ret |
putimage_get24bpp: |
mov eax, [esi] |
add esi, 3 |
ret 4 |
putimage_get8bpp: |
movzx eax, byte [esi] |
push edx |
mov edx, [esp+8] |
mov eax, [edx+eax*4] |
pop edx |
inc esi |
ret 4 |
putimage_init32bpp: |
shl eax, 2 |
ret |
putimage_get32bpp: |
lodsd |
ret 4 |
; eax x beginning |
; ebx y beginning |
; ecx x end |
; edx y end |
; edi color |
__sys_drawbar: |
mov esi,[current_slot] |
add eax,[esi+APPDATA.wnd_clientbox.left] |
add ecx,[esi+APPDATA.wnd_clientbox.left] |
add ebx,[esi+APPDATA.wnd_clientbox.top] |
add edx,[esi+APPDATA.wnd_clientbox.top] |
.forced: |
inc [mouse_pause] |
; call [disable_mouse] |
cmp [SCR_MODE],word 0x12 |
je dbv20 |
sdbv20: |
cmp [SCR_MODE],word 0100000000000000b |
jge dbv20 |
cmp [SCR_MODE],word 0x13 |
je dbv20 |
call vesa12_drawbar |
dec [mouse_pause] |
call [draw_pointer] |
ret |
dbv20: |
call vesa20_drawbar |
dec [mouse_pause] |
call [draw_pointer] |
ret |
kb_read: |
push ecx edx |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kr_loop: |
in al,0x64 |
test al,1 |
jnz kr_ready |
loop kr_loop |
mov ah,1 |
jmp kr_exit |
kr_ready: |
push ecx |
mov ecx,32 |
kr_delay: |
loop kr_delay |
pop ecx |
in al,0x60 |
xor ah,ah |
kr_exit: |
pop edx ecx |
ret |
kb_write: |
push ecx edx |
mov dl,al |
; mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
; kw_loop1: |
; in al,0x64 |
; test al,0x20 |
; jz kw_ok1 |
; loop kw_loop1 |
; mov ah,1 |
; jmp kw_exit |
; kw_ok1: |
in al,0x60 |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop: |
in al,0x64 |
test al,2 |
jz kw_ok |
loop kw_loop |
mov ah,1 |
jmp kw_exit |
kw_ok: |
mov al,dl |
out 0x60,al |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop3: |
in al,0x64 |
test al,2 |
jz kw_ok3 |
loop kw_loop3 |
mov ah,1 |
jmp kw_exit |
kw_ok3: |
mov ah,8 |
kw_loop4: |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
kw_loop5: |
in al,0x64 |
test al,1 |
jnz kw_ok4 |
loop kw_loop5 |
dec ah |
jnz kw_loop4 |
kw_ok4: |
xor ah,ah |
kw_exit: |
pop edx ecx |
ret |
kb_cmd: |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
c_wait: |
in al,0x64 |
test al,2 |
jz c_send |
loop c_wait |
jmp c_error |
c_send: |
mov al,bl |
out 0x64,al |
mov ecx,0x1ffff ; last 0xffff, new value in view of fast CPU's |
c_accept: |
in al,0x64 |
test al,2 |
jz c_ok |
loop c_accept |
c_error: |
mov ah,1 |
jmp c_exit |
c_ok: |
xor ah,ah |
c_exit: |
ret |
setmouse: ; set mousepicture -pointer |
; ps2 mouse enable |
mov [MOUSE_PICTURE],dword mousepointer |
cli |
; 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 4096 db 0 |
msg_board_count dd 0x0 |
endg |
sys_msg_board: |
; eax=1 : write : bl byte to write |
; eax=2 : read : ebx=0 -> no data, ebx=1 -> data in al |
mov ecx,[msg_board_count] |
cmp eax, 1 |
jne smbl1 |
mov [msg_board_data+ecx],bl |
inc ecx |
and ecx, 4095 |
mov [msg_board_count], ecx |
mov [check_idle_semaphore], 5 |
ret |
smbl1: |
cmp eax, 2 |
jne smbl2 |
test ecx, ecx |
jz smbl21 |
; mov 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_process_def: |
mov edi, [CURRENT_TASK] |
dec eax ; 1 = set keyboard mode |
jne no_set_keyboard_setup |
shl edi,8 |
mov [edi+SLOT_BASE + 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 [SLOT_BASE+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,[ScreenWidth] |
shl eax,16 |
mov ax,[ScreenHeight] |
add eax,0x00010001 |
mov [esp+36],eax |
ret |
no_gs1: |
cmp eax,2 ; bits per pixel |
jne no_gs2 |
movzx eax,byte [ScreenBPP] |
mov [esp+36],eax |
ret |
no_gs2: |
cmp eax,3 ; bytes per scanline |
jne no_gs3 |
mov eax,[BytesPerScanLine] |
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,[TASK_BASE] |
add eax,[edx-twdw+WDATA.box.left] |
add ebx,[edx-twdw+WDATA.box.top] |
mov edi,[current_slot] |
add eax,[edi+APPDATA.wnd_clientbox.left] |
add ebx,[edi+APPDATA.wnd_clientbox.top] |
xor edi,edi ; no force |
; mov edi,1 |
call [disable_mouse] |
jmp [putpixel] |
align 4 |
syscall_writetext: ; WriteText |
mov edi,[TASK_BASE] |
mov ebp,[edi-twdw+WDATA.box.left] |
push esi |
mov esi,[current_slot] |
add ebp,[esi+APPDATA.wnd_clientbox.left] |
shl ebp,16 |
add ebp,[edi-twdw+WDATA.box.top] |
add bp,word[esi+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,[TASK_BASE] |
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,[current_slot] |
add eax,[esi+APPDATA.wnd_clientbox.left] |
add ebx,[esi+APPDATA.wnd_clientbox.top] |
add ecx,eax |
add edx,ebx |
jmp [drawbar] |
drectr: |
ret |
align 4 |
syscall_getscreensize: ; GetScreenSize |
movzx eax,word[ScreenWidth] |
shl eax,16 |
mov ax,[ScreenHeight] |
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,[TASK_BASE] |
add edi,TASKDATA.mem_start |
add eax,[edi] |
call filedelete |
mov [esp+36],eax |
ret |
align 4 |
syscall_writeramdiskfile: ; WriteRamdiskFile |
mov edi,[TASK_BASE] |
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,[ScreenWidth] |
inc ecx |
xor edx,edx |
div ecx |
mov ebx,edx |
xchg eax,ebx |
call dword [GETPIXEL] |
mov [esp+36],ecx |
ret |
align 4 |
syscall_readstring: ; ReadString |
mov edi,[TASK_BASE] |
add edi,TASKDATA.mem_start |
add eax,[edi] |
call read_string |
mov [esp+36],eax |
ret |
align 4 |
syscall_drawline: ; DrawLine |
mov edi,[TASK_BASE] |
movzx edx,word[edi-twdw+WDATA.box.left] |
mov ebp,edx |
mov esi,[current_slot] |
add ebp,[esi+APPDATA.wnd_clientbox.left] |
add dx,word[esi+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+APPDATA.wnd_clientbox.top] |
add dx,word[esi+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,[TASK_BASE] |
add edi,TASKDATA.mem_start |
add eax,[edi] |
add ecx,[edi] |
add edx,[edi] |
call file_read |
mov [esp+36],eax |
mov [esp+24],ebx |
ret |
align 4 |
paleholder: |
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 |
@@: |
mov esi, [master_tab+(OS_BASE shr 20)] |
xchg [master_tab], esi |
push esi |
mov edi, cr3 |
mov cr3, edi ;flush TLB |
call pword [apm_entry] ; call APM BIOS |
xchg eax, [esp] |
mov [master_tab], eax |
mov eax, cr3 |
mov cr3, eax |
pop eax |
mov [esp + 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 |
align 4 |
system_shutdown: ; shut down the system |
cmp byte [BOOT_VAR+0x9030], 1 |
jne @F |
ret |
@@: |
call stop_all_services |
push 3 ; stop playing cd |
pop eax |
call sys_cd_audio |
yes_shutdown_param: |
cli |
mov eax, kernel_file ; load kernel.mnt to 0x8000:0 |
push 12 |
pop esi |
xor ebx,ebx |
or ecx,-1 |
mov edx, OS_BASE+0x80000 |
call fileread |
mov esi, restart_kernel_4000+OS_BASE+0x10000 ; move kernel re-starter to 0x4000:0 |
mov edi,OS_BASE+0x40000 |
mov ecx,1000 |
rep movsb |
mov esi,OS_BASE+0x2F0000 ; restore 0x0 - 0xffff |
mov edi, OS_BASE |
mov ecx,0x10000/4 |
cld |
rep movsd |
call restorefatchain |
mov al, 0xFF |
out 0x21, al |
out 0xA1, al |
mov word [OS_BASE+0x467+0],pr_mode_exit |
mov word [OS_BASE+0x467+2],0x1000 |
mov al,0x0F |
out 0x70,al |
mov al,0x05 |
out 0x71,al |
mov al,0xFE |
out 0x64,al |
hlt |
include "data32.inc" |
__REV__ = __REV |
uglobals_size = $ - endofcode |
diff16 "end of kernel code",0,$ |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/video/vesa20.inc |
---|
0,0 → 1,1074 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; VESA20.INC ;; |
;; ;; |
;; Vesa 2.0 functions for MenuetOS ;; |
;; ;; |
;; Copyright 2002 Ville Turjanmaa ;; |
;; Alexey, kgaz@crosswindws.net ;; |
;; - Voodoo compatible graphics ;; |
;; Juan M. Caravaca ;; |
;; - Graphics optimimizations eg. drawline ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; 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 [GETPIXEL] |
pop edi edx ebx eax |
ret |
Vesa20_getpixel24: |
; eax = x |
; ebx = y |
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier |
lea edi, [eax+eax*2] ; edi = x*3 |
add edi, ebx ; edi = x*3+(y*y multiplier) |
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 ? |
.winmap_newline dd ? |
.screen_newline dd ? |
.stack_data = 4*12 |
.edi dd ? |
.esi dd ? |
.ebp dd ? |
.esp dd ? |
.ebx dd ? |
.edx dd ? |
.ecx dd ? |
.eax dd ? |
.ret_addr dd ? |
.arg_0 dd ? |
end virtual |
align 16 |
; ebx = pointer |
; ecx = size [x|y] |
; edx = coordinates [x|y] |
; ebp = pointer to 'get' function |
; esi = pointer to 'init' function |
; edi = parameter for 'get' function |
vesa20_putimage: |
pushad |
call [disable_mouse] |
sub esp, putimg.stack_data |
; save pointer to image |
mov [putimg.pti], ebx |
; unpack the size |
mov eax, ecx |
and ecx, 0xFFFF |
shr eax, 16 |
mov [putimg.image_sx], eax |
mov [putimg.image_sy], ecx |
; unpack the coordinates |
mov eax, edx |
and edx, 0xFFFF |
shr eax, 16 |
mov [putimg.image_cx], eax |
mov [putimg.image_cy], edx |
; calculate absolute (i.e. screen) coordinates |
mov eax, [TASK_BASE] |
mov ebx, [eax-twdw + WDATA.box.left] |
add ebx, [putimg.image_cx] |
mov [putimg.abs_cx], ebx |
mov ebx, [eax-twdw + WDATA.box.top] |
add ebx, [putimg.image_cy] |
mov [putimg.abs_cy], ebx |
; real_sx = MIN(wnd_sx-image_cx, image_sx); |
mov ebx, [eax-twdw + WDATA.box.width] ; ebx = wnd_sx |
; \begin{diamond}[20.08.2006] |
; note that WDATA.box.width is one pixel less than real window x-size |
inc ebx |
; \end{diamond}[20.08.2006] |
sub ebx, [putimg.image_cx] |
ja @f |
add esp, putimg.stack_data |
popad |
ret |
@@: |
cmp ebx, [putimg.image_sx] |
jbe .end_x |
mov ebx, [putimg.image_sx] |
.end_x: |
mov [putimg.real_sx], ebx |
; init real_sy |
mov ebx, [eax-twdw + WDATA.box.height] ; ebx = wnd_sy |
; \begin{diamond}[20.08.2006] |
inc ebx |
; \end{diamond}[20.08.2006] |
sub ebx, [putimg.image_cy] |
ja @f |
add esp, putimg.stack_data |
popad |
ret |
@@: |
cmp ebx, [putimg.image_sy] |
jbe .end_y |
mov ebx, [putimg.image_sy] |
.end_y: |
mov [putimg.real_sy], ebx |
; line increment |
mov eax, [putimg.image_sx] |
sub eax, [putimg.real_sx] |
;; imul eax, [putimg.source_bpp] |
; lea eax, [eax + eax * 2] |
call esi |
add eax, [putimg.arg_0] |
mov [putimg.line_increment], eax |
; winmap new line increment |
mov eax, [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 esi, [putimg.pti] |
; pointer to screen |
mov edx, [putimg.abs_cy] |
imul edx, [BytesPerScanLine] |
mov eax, [putimg.abs_cx] |
movzx ebx, byte [ScreenBPP] |
shr ebx, 3 |
imul eax, ebx |
add edx, eax |
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, [CURRENT_TASK] |
cmp byte [ScreenBPP], 32 |
je put_image_end_32 |
;put_image_end_24: |
mov edi, [putimg.real_sy] |
align 4 |
.new_line: |
mov ecx, [putimg.real_sx] |
; push ebp edx |
align 4 |
.new_x: |
push [putimg.edi] |
mov eax, [putimg.ebp+4] |
call eax |
cmp [ebp], bl |
jne .skip |
; mov eax, [esi] ; eax = RRBBGGRR |
mov [edx], ax |
shr eax, 16 |
mov [edx+2], al |
.skip: |
; add esi, 3 ;[putimg.source_bpp] |
add edx, 3 |
inc ebp |
dec ecx |
jnz .new_x |
; pop edx ebp |
add esi, [putimg.line_increment] |
add edx, [putimg.screen_newline] ;[BytesPerScanLine] |
add ebp, [putimg.winmap_newline] ;[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 ecx, [putimg.real_sx] |
; push ebp edx |
align 4 |
.new_x: |
push [putimg.edi] |
mov eax, [putimg.ebp+4] |
call eax |
cmp [ebp], bl |
jne .skip |
; mov eax, [esi] ; ecx = RRBBGGRR |
mov [edx], eax |
.skip: |
; add esi, [putimg.source_bpp] |
add edx, 4 |
inc ebp |
dec ecx |
jnz .new_x |
; pop edx ebp |
add esi, [putimg.line_increment] |
add edx, [putimg.screen_newline] ;[BytesPerScanLine] |
add ebp, [putimg.winmap_newline] ;[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 [PUTPIXEL] ; call the real put_pixel function |
.exit: |
popad |
ret |
align 4 |
Vesa20_putpixel24: |
; eax = x |
; ebx = y |
imul ebx, [BytesPerScanLine] ; ebx = y * y multiplier |
lea edi, [eax+eax*2] ; edi = x*3 |
mov eax, [esp+32-8+4] |
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, [TASK_BASE] |
add eax, [edi-twdw + WDATA.box.left] ; win_cx |
add ebx, [edi-twdw + WDATA.box.top] ; win_cy |
mov [drbar.abs_cx], eax |
mov [drbar.abs_cy], ebx |
; real_sx = MIN(wnd_sx-bar_cx, bar_sx); |
mov ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx |
; \begin{diamond}[20.08.2006] |
; note that WDATA.box.width is one pixel less than real window x-size |
inc ebx |
; \end{diamond}[20.08.2006] |
sub ebx, [drbar.bar_cx] |
ja @f |
.exit: ;// mike.dld, 2005-01-29 |
add esp, drbar.stack_data |
popad |
xor eax, eax |
inc eax |
ret |
@@: |
cmp ebx, [drbar.bar_sx] |
jbe .end_x |
mov ebx, [drbar.bar_sx] |
.end_x: |
mov [drbar.real_sx], ebx |
; real_sy = MIN(wnd_sy-bar_cy, bar_sy); |
mov ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy |
; \begin{diamond}[20.08.2006] |
inc ebx |
; \end{diamond} |
sub ebx, [drbar.bar_cy] |
ja @f |
add esp, drbar.stack_data |
popad |
xor eax, eax |
inc eax |
ret |
@@: |
cmp ebx, [drbar.bar_sy] |
jbe .end_y |
mov ebx, [drbar.bar_sy] |
.end_y: |
mov [drbar.real_sy], ebx |
; line_inc_map |
mov eax, [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, [CURRENT_TASK] |
cmp byte [ScreenBPP], 24 |
jne draw_bar_end_32 |
draw_bar_end_24: |
mov eax, [drbar.color] ;; BBGGRR00 |
mov bh, al ;; bh = BB |
shr eax, 8 ;; eax = RRGG |
; eax - color high RRGG |
; bl - process num |
; bh - color low BB |
; ecx - temp |
; edx - pointer to screen |
; esi - counter |
; edi - counter |
mov esi, [drbar.real_sy] |
align 4 |
.new_y: |
mov edi, [drbar.real_sx] |
align 4 |
.new_x: |
cmp byte [ebp], bl |
jne .skip |
mov [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 |
vesa20_drawbackground_tiled: |
call [disable_mouse] |
pushad |
; External loop for all y from start to end |
mov ebx, [draw_data+32+RECT.top] ; y start |
dp2: |
mov ebp, [draw_data+32+RECT.left] ; x start |
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp] |
; and LFB data (output for our function) [edi] |
mov eax, [BytesPerScanLine] |
mul ebx |
xchg ebp, eax |
add ebp, eax |
add ebp, eax |
add ebp, eax |
cmp [ScreenBPP], byte 24 ; 24 or 32 bpp ? - x size |
jz @f |
add ebp, eax |
@@: |
add ebp, [LFBAddress] |
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB |
call calculate_edi |
xchg edi, ebp |
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress |
; 2) Calculate offset in background memory block |
push eax |
xor edx, edx |
mov eax, ebx |
mov ecx, [BgrDataHeight] |
div ecx ; edx := y mod BgrDataHeight |
sub ecx, edx ; ecx := BgrDataHeight - (y mod BgrDataHeight) |
pop eax |
push eax |
mov esi, edx |
imul esi, [BgrDataWidth] ; esi := (y mod BgrDataHeight) * BgrDataWidth |
xor edx, edx |
div dword [BgrDataWidth] ; edx := x mod BgrDataWidth |
add esi, edx ; esi := (y mod BgrDataHeight)*BgrDataWidth + (x mod BgrDataWidth) |
pop eax |
lea esi, [esi*3] |
add esi, [img_background] |
xor edx, edx |
inc edx |
; 3) Loop through redraw rectangle and copy background data |
; Registers meaning: |
; eax = x, ebx = y (screen coordinates) |
; ecx = deltax - number of pixels left in current tile block |
; edx = 1 |
; esi -> bgr memory, edi -> output |
; ebp = offset in WinMapAddress |
dp3: |
cmp [ebp+WinMapAddress], dl |
jnz nbgp |
movsb |
movsb |
movsb |
jmp @f |
nbgp: |
add esi, 3 |
add edi, 3 |
@@: |
cmp [ScreenBPP], byte 25 ; 24 or 32 bpp? |
sbb edi, -1 ; +1 for 32 bpp |
; I do not use 'inc eax' because this is slightly slower then 'add eax,1' |
add ebp, edx |
add eax, edx |
cmp eax, [draw_data+32+RECT.right] |
ja dp4 |
sub ecx, edx |
jnz dp3 |
; next tile block on x-axis |
mov ecx, [BgrDataWidth] |
sub esi, ecx |
sub esi, ecx |
sub esi, ecx |
jmp dp3 |
dp4: |
; next scan line |
inc ebx |
cmp ebx, [draw_data+32+RECT.bottom] |
jbe dp2 |
popad |
mov [EGA_counter], 1 |
call VGA_drawbackground |
ret |
; ---------- |
vesa20_drawbackground_stretch: |
call [disable_mouse] |
pushad |
; Helper variables |
mov eax, [BgrDataWidth] |
xor edx, edx |
mov ecx, [ScreenWidth] |
inc ecx |
div ecx |
push eax ; quo |
push edx ; rem |
mov eax, [BgrDataHeight] |
xor edx, edx |
mov ecx, [ScreenHeight] |
inc ecx |
div ecx |
push eax |
push edx |
; External loop for all y from start to end |
mov ebx, [draw_data+32+RECT.top] ; y start |
mov ebp, [draw_data+32+RECT.left] ; x start |
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp] |
; and LFB data (output for our function) [edi] |
mov eax, [BytesPerScanLine] |
mul ebx |
xchg ebp, eax |
add ebp, eax |
add ebp, eax |
add ebp, eax |
cmp [ScreenBPP], byte 24 ; 24 or 32 bpp ? - x size |
jz @f |
add ebp, eax |
@@: |
add ebp, [LFBAddress] |
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB |
call calculate_edi |
xchg edi, ebp |
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress |
push ebx |
; 2) Calculate offset in background memory block |
push eax |
mov eax, ebx |
mul dword [BgrDataHeight] |
mov ecx, [ScreenHeight] |
inc ecx |
div ecx ; eax := y * BgrDataHeight / ScreenHeight |
; edx := (y * BgrDataHeight) mod ScreenHeight |
mov esi, eax |
pop eax |
push edx ; dword [esp] = (y * BgrDataHeight) mod ScreenHeight |
; dword [esp+4] = y * BgrDataHeight / ScreenHeight |
push eax |
mov ecx, [BgrDataWidth] |
lea edx, [ecx*3] |
imul edx, [BgrDataHeight] |
add edx, [img_background] |
push edx |
mul ecx |
imul esi, ecx |
dec ecx |
push ecx |
mov ecx, [ScreenWidth] |
inc ecx |
div ecx ; eax := x * BgrDataWidth / ScreenWidth |
; edx := (x * BgrDataWidth) mod ScreenWidth |
add esi, eax |
lea esi, [esi*3] |
add esi, [img_background] |
push ecx edx esi |
; 3) Loop through redraw rectangle and copy background data |
; Registers meaning: |
; ecx = (x * BgrDataWidth) / ScreenWidth |
; edx = (x * BgrDataWidth) mod ScreenWidth (used to fast recalculating of ecx,esi) |
; esi -> bgr memory, edi -> output |
; ebp = offset in WinMapAddress |
; dword [esp] = saved esi |
; dword [esp+4] = saved edx |
; dword [esp+8] = saved ecx |
; dword [esp+12] = BgrDataWidth-1, x-limit for overlapping of points |
; dword [esp+16] = end of bgr memory (defines y-limit for overlapping of points) |
; dword [esp+20] = x |
; dword [esp+24] = (y * BgrDataHeight) mod ScreenHeight (used to fast recalculating of esi) |
; dword [esp+28] = y |
; precalculated constants: |
; dword [esp+32] = BgrDataHeight mod ScreenHeight |
; dword [esp+36] = BgrDataHeight div ScreenHeight |
; dword [esp+40] = BgrDataWidth mod ScreenWidth |
; dword [esp+44] = BgrDataWidth div ScreenWidth |
sdp3: |
add edx, [esp+40] |
cmp [ebp+WinMapAddress], byte 1 |
jnz snbgp |
mov al, [esi+2] |
shl eax, 16 |
mov ax, [esi] |
cmp ecx, [esp+12] |
jae @f |
cmp edx, [ScreenWidth] |
jb @f |
mov ebx, [esi+2] |
shr ebx, 8 |
call overlapping_of_points |
@@: |
mov ebx, [esp+24] |
add ebx, [esp+32] |
cmp ebx, [ScreenHeight] |
jbe @f |
mov ebx, [BgrDataWidth] |
lea ebx, [ebx*3] |
add ebx, esi |
cmp ebx, [esp+16] |
jae @f |
mov ebx, [ebx-1] |
shr ebx, 8 |
call overlapping_of_points |
@@: |
mov [edi], ax |
shr eax, 16 |
mov [edi+2], al |
snbgp: |
cmp [ScreenBPP], byte 25 |
sbb edi, -4 |
add ebp, 1 |
mov eax, [esp+20] |
add eax, 1 |
mov [esp+20], eax |
cmp eax, [draw_data+32+RECT.right] |
ja sdp4 |
mov eax, [esp+44] |
add ecx, eax |
lea eax, [eax*3] |
add esi, eax |
; add edx, [esp+40] |
cmp edx, [ScreenWidth] |
jbe sdp3 |
sub edx, [ScreenWidth] |
add ecx, 1 |
add esi, 3 |
sub edx, 1 |
jmp sdp3 |
sdp4: |
; next y |
mov ebx, [esp+28] |
add ebx, 1 |
mov [esp+28], ebx |
cmp ebx, [draw_data+32+RECT.bottom] |
ja sdpdone |
; advance edi, ebp to next scan line |
sub eax, [draw_data+32+RECT.left] |
sub ebp, eax |
add ebp, [ScreenWidth] |
add ebp, 1 |
sub edi, eax |
sub edi, eax |
sub edi, eax |
cmp [ScreenBPP], byte 24 |
jz @f |
sub edi, eax |
@@: |
add edi, [BytesPerScanLine] |
; restore ecx,edx; advance esi to next background line |
pop esi edx ecx |
push ecx edx |
xor ebx, ebx |
mov eax, [esp+24-4] |
add eax, [esp+32-4] |
cmp eax, [ScreenHeight] |
jbe @f |
sub eax, [ScreenHeight] |
mov ebx, 1 |
sub eax, ebx |
@@: |
mov [esp+24-4], eax |
add ebx, [esp+36-4] |
lea ebx, [ebx*3] |
imul ebx, [BgrDataWidth] |
add esi, ebx |
push esi |
mov eax, [draw_data+32+RECT.left] |
mov [esp+20], eax |
jmp sdp3 |
sdpdone: |
add esp, 48 |
popad |
mov [EGA_counter],1 |
call VGA_drawbackground |
ret |
overlapping_of_points: |
push ecx edx edi |
mov ecx, eax |
mov edx, ebx |
movzx eax, cl |
movzx ebx, dl |
add eax, ebx |
rcr eax, 1 |
movzx edi, ax |
movzx eax, ch |
movzx ebx, dh |
add eax, ebx |
rcr eax, 1 |
ror edi, 8 |
add edi, eax |
shr ecx, 8 |
shr edx, 8 |
movzx eax, ch |
movzx ebx, dh |
add eax, ebx |
rcr eax, 1 |
ror edi, 8 |
add eax, edi |
ror eax, 16 |
pop edi edx ecx |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/video/vesa12.inc |
---|
0,0 → 1,940 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; VESA12.INC ;; |
;; ;; |
;; Vesa 1.2 functions for MenuetOS ;; |
;; ;; |
;; Copyright 2002 Ville Turjanmaa ;; |
;; ;; |
;; quickcode@mail.ru - bankswitch for S3 cards ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; 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,[BANK_RW] |
;je retsb |
;mov [BANK_RW],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,[BANK_RW] |
je retsb |
mov [BANK_RW],al |
push ax |
push dx |
push cx |
mov cl, al |
mov dx, 0x3D4 |
mov al, 0x38 |
out dx, al ;CR38 Register Lock 1 ;Note: Traditionally 48h is used to |
;unlock and 00h to lock |
inc dx |
mov al, 0x48 |
out dx, al ;3d5 -? |
dec dx |
mov al, 0x31 |
out dx, al ;CR31 Memory Configuration Register |
;0 Enable Base Address Offset (CPUA BASE). Enables bank operation if set, ;disables if clear. |
;4-5 Bit 16-17 of the Display Start Address. For the 801/5,928 see index 51h, |
;for the 864/964 see index 69h. |
inc dx |
in al, dx |
dec dx |
mov ah, al |
mov al, 0x31 |
out dx, ax |
mov al, ah |
or al, 9 |
inc dx |
out dx, al |
dec dx |
mov al, 0x35 |
out dx, al ;CR35 CRT Register Lock |
inc dx |
in al, dx |
dec dx |
and al, 0xF0 |
mov ch, cl |
and ch, 0x0F |
or ch, al |
mov al, 0x35 |
out dx, al |
inc dx |
mov al, ch |
out dx, ax |
dec dx |
mov al, 0x51 ;Extended System Control 2 Register |
out dx, al |
inc dx |
in al, dx |
dec dx |
and al, 0xF3 |
shr cl, 2 |
and cl, 0x0C |
or cl, al |
mov al, 0x51 |
out dx, al |
inc dx |
mov al, cl |
out dx, al |
dec dx |
mov al, 0x38 |
out dx, al |
inc dx |
xor al, al |
out dx, al |
dec dx |
pop cx |
pop dx |
pop ax |
retsb: |
popfd |
ret |
;Set bank function for Intel 810/815 chipsets |
; *****Modified by Protopopius, Russia.***** |
; ********* http://menuetos.hut.ru ************** |
; ************************************************ |
; |
;set_bank: |
;cli |
;cmp al,[BANK_RW] |
;je retsb |
;mov [BANK_RW],al |
;push ax |
;push dx |
;mov dx,3CEh |
;mov ah,al ; Save value for later use |
;mov al,10h ; Index GR10 (Address Mapping) |
;out dx,al ; Select GR10 |
;inc dl |
;mov al,3 ; Set bits 0 and 1 (Enable linear page mapping) |
;out dx,al ; Write value |
;dec dl |
;mov al,11h ; Index GR11 (Page Selector) |
;out dx,al ; Select GR11 |
;inc dl |
;mov al,ah ; Write address |
;out dx,al ; Write the value |
;pop dx |
;pop ax |
;retsb: |
;sti |
;ret |
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!} |
;set_bank: |
; cli |
; cmp al,[BANK_RW] |
; je retsb |
; mov [BANK_RW],al |
; push ax |
; push dx |
; mov ah,al |
; mov dx,0x03D4 |
; mov al,0x39 |
; out dx,al |
; inc dl |
; mov al,0xA5 |
; out dx,al |
; dec dl |
; mov al,6Ah |
; out dx,al |
; inc dl |
; mov al,ah |
; out dx,al |
; dec dl |
; mov al,0x39 |
; out dx,al |
; inc dl |
; mov al,0x5A |
; out dx,al |
; dec dl |
; pop dx |
; pop ax |
; |
; retsb: |
; ret |
vesa12_drawbackground: |
call [disable_mouse] |
push eax |
push ebx |
push ecx |
push edx |
xor edx,edx |
mov eax,dword[BgrDataWidth] |
mov ebx,dword[BgrDataHeight] |
mul ebx |
mov ebx,3 |
mul ebx |
mov [imax],eax |
mov eax,[draw_data+32+RECT.left] |
mov ebx,[draw_data+32+RECT.top] |
mov edi,0 ;no force |
v12dp3: |
push eax |
push ebx |
cmp [BgrDrawMode],dword 1 ; tiled background |
jne no_vesa12_tiled_bgr |
push edx |
xor edx,edx |
div dword [BgrDataWidth] |
push edx |
mov eax,ebx |
xor edx,edx |
div dword [BgrDataHeight] |
mov ebx,edx |
pop eax |
pop edx |
no_vesa12_tiled_bgr: |
cmp [BgrDrawMode],dword 2 ; stretched background |
jne no_vesa12_stretched_bgr |
push edx |
mul dword [BgrDataWidth] |
mov ecx,[ScreenWidth] |
inc ecx |
div ecx |
push eax |
mov eax,ebx |
mul dword [BgrDataHeight] |
mov ecx,[ScreenHeight] |
inc ecx |
div ecx |
mov ebx,eax |
pop eax |
pop edx |
no_vesa12_stretched_bgr: |
mov esi,ebx |
imul esi, dword [BgrDataWidth] |
add esi,eax |
lea esi,[esi*3] |
add esi,[img_background] ;IMG_BACKGROUND |
pop ebx |
pop eax |
v12di4: |
mov cl,[esi+2] |
shl ecx,16 |
mov cx,[esi] |
pusha |
mov esi,eax |
mov edi,ebx |
mov eax,[ScreenWidth] |
add eax,1 |
mul ebx |
cmp [eax+esi+WinMapAddress],byte 1 |
jnz v12nbgp |
mov eax,[BytesPerScanLine] |
mov ebx,edi |
mul ebx |
add eax,esi |
add eax,esi |
add eax,esi |
cmp [ScreenBPP],byte 24 |
jz v12bgl3 |
add eax,esi |
v12bgl3: |
push ebx |
push eax |
sub eax,[LFBAddress] |
shr eax,16 |
call set_bank |
pop eax |
and eax,65535 |
add eax,VGABasePtr |
pop ebx |
mov [eax],cx |
add eax,2 |
shr ecx,16 |
mov [eax],cl |
sti |
v12nbgp: |
popa |
add esi,3 |
inc eax |
cmp eax,[draw_data+32+RECT.right] |
jg v12nodp31 |
jmp v12dp3 |
v12nodp31: |
mov eax,[draw_data+32+RECT.left] |
inc ebx |
cmp ebx,[draw_data+32+RECT.bottom] |
jg v12dp4 |
jmp v12dp3 |
v12dp4: |
pop edx |
pop ecx |
pop ebx |
pop eax |
ret |
vesa12_drawbar: |
call [disable_mouse] |
;; mov [novesachecksum],dword 0 |
sub edx,ebx |
sub ecx,eax |
push esi |
push edi |
push eax |
push ebx |
push ecx |
push edx |
mov ecx,[TASK_BASE] |
add eax,[ecx-twdw+WDATA.box.left] |
add ebx,[ecx-twdw+WDATA.box.top] |
push eax |
mov eax,ebx ; y |
mov ebx,[BytesPerScanLine] |
mul ebx |
pop ecx |
add eax,ecx ; x |
add eax,ecx |
add eax,ecx |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x start |
jz dbpi2412 |
add eax,ecx |
dbpi2412: |
add eax,[LFBAddress] |
mov edi,eax |
; x size |
mov eax,[esp+4] ; [esp+6] |
mov ecx,eax |
add ecx,eax |
add ecx,eax |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x size |
jz dbpi24312 |
add ecx,eax |
dbpi24312: |
mov ebx,[esp+0] |
; check limits ? |
push eax |
push ecx |
mov eax,[TASK_BASE] |
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.left] |
cmp ecx,0 |
jnz dbcblimitlset12 |
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.top] |
cmp ecx,0 |
jnz dbcblimitlset12 |
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.right] |
cmp ecx,[ScreenWidth] |
jnz dbcblimitlset12 |
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.bottom] |
cmp ecx,[ScreenHeight] |
jnz dbcblimitlset12 |
pop ecx |
pop eax |
push dword 0 |
jmp dbcblimitlno12 |
dbcblimitlset12: |
pop ecx |
pop eax |
push dword 1 |
dbcblimitlno12: |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? |
jz dbpi24bit12 |
jmp dbpi32bit12 |
; DRAWBAR 24 BBP |
dbpi24bit12: |
push eax |
push ebx |
push edx |
mov eax,ecx |
mov ebx,3 |
div ebx |
mov ecx,eax |
pop edx |
pop ebx |
pop eax |
cld |
dbnewpi12: |
push ebx |
push edi |
push ecx |
xor edx,edx |
mov eax,edi |
sub eax,[LFBAddress] |
mov ebx,3 |
div ebx |
add eax,WinMapAddress |
mov ebx,[CURRENT_TASK] |
cld |
dbnp2412: |
mov dl,[eax] |
push eax |
push ecx |
cmp dl,bl |
jnz dbimp24no12 |
cmp [esp+5*4],dword 0 |
jz dbimp24yes12 |
; call dbcplimit |
; jnz dbimp24no12 |
dbimp24yes12: |
push edi |
mov eax,edi |
sub eax,[LFBAddress] |
shr eax,16 |
call set_bank |
and edi,0xffff |
add edi,VGABasePtr |
mov eax,[esp+8+3*4+16+4+4] |
stosw |
shr eax,16 |
stosb |
sti |
pop edi |
add edi,3 |
pop ecx |
pop eax |
inc eax |
loop dbnp2412 |
jmp dbnp24d12 |
dbimp24no12: |
pop ecx |
pop eax |
cld |
add edi,3 |
inc eax |
loop dbnp2412 |
dbnp24d12: |
mov eax,[esp+3*4+16+4] |
test eax,0x80000000 |
jz nodbgl2412 |
cmp al,0 |
jz nodbgl2412 |
dec eax |
mov [esp+3*4+16+4],eax |
nodbgl2412: |
pop ecx |
pop edi |
pop ebx |
add edi,[BytesPerScanLine] |
dec ebx |
jz dbnonewpi12 |
jmp dbnewpi12 |
dbnonewpi12: |
add esp,7*4 |
ret |
; DRAWBAR 32 BBP |
dbpi32bit12: |
cld |
shr ecx,2 |
dbnewpi3212: |
push ebx |
push edi |
push ecx |
mov eax,edi |
sub eax,[LFBAddress] |
shr eax,2 |
add eax,WinMapAddress |
mov ebx,[CURRENT_TASK] |
cld |
dbnp3212: |
mov dl,[eax] |
push eax |
push ecx |
cmp dl,bl |
jnz dbimp32no12 |
cmp [esp+5*4],dword 0 |
jz dbimp32yes12 |
; call dbcplimit |
; jnz dbimp32no12 |
dbimp32yes12: |
push edi |
mov eax,edi |
sub eax,[LFBAddress] |
shr eax,16 |
call set_bank |
and edi,0xffff |
add edi,VGABasePtr |
mov eax,[esp+8+3*4+16+4+4] |
stosw |
shr eax,16 |
stosb |
sti |
pop edi |
add edi,4 |
inc ebp |
pop ecx |
pop eax |
inc eax |
loop dbnp3212 |
jmp dbnp32d12 |
dbimp32no12: |
pop ecx |
pop eax |
inc eax |
add edi,4 |
inc ebp |
loop dbnp3212 |
dbnp32d12: |
mov eax,[esp+12+16+4] |
test eax,0x80000000 |
jz nodbgl3212 |
cmp al,0 |
jz nodbgl3212 |
dec eax |
mov [esp+12+16+4],eax |
nodbgl3212: |
pop ecx |
pop edi |
pop ebx |
add edi,[BytesPerScanLine] |
dec ebx |
jz nodbnewpi3212 |
jmp dbnewpi3212 |
nodbnewpi3212: |
add esp,7*4 |
ret |
Vesa12_putpixel24: |
mov edi,eax ; x |
mov eax,ebx ; y |
lea edi,[edi+edi*2] |
mov ebx,[BytesPerScanLine] |
mul ebx |
add edi,eax |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,VGABasePtr |
mov eax,[esp+28] |
stosw |
shr eax,16 |
mov [edi],al |
sti |
ret |
Vesa12_putpixel32: |
mov edi,eax ; x |
mov eax,ebx ; y |
shl edi,2 |
mov ebx,[BytesPerScanLine] |
mul ebx |
add edi,eax |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,VGABasePtr |
mov ecx,[esp+28] |
mov [edi],ecx |
sti |
ret |
Vesa12_getpixel24: |
mov edi,eax ; x |
mov eax,ebx ; y |
lea edi,[edi+edi*2] |
mov ebx,[BytesPerScanLine] |
mul ebx |
add edi,eax |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,VGABasePtr |
mov ecx,[edi] |
and ecx,255*256*256+255*256+255 |
sti |
ret |
Vesa12_getpixel32: |
mov edi,eax ; x |
mov eax,ebx ; y |
shl edi,2 |
mov ebx,[BytesPerScanLine] |
xor edx,edx |
mul ebx |
add edi,eax |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,VGABasePtr |
mov ecx,[edi] |
and ecx,255*256*256+255*256+255 |
sti |
ret |
vesa12_putimage: |
; ebx = pointer to image |
; ecx = size [x|y] |
; edx = coordinates [x|y] |
; ebp = pointer to 'get' function |
; esi = pointer to 'init' function |
; edi = parameter for 'get' function |
; mov ebx,image |
; mov ecx,320*65536+240 |
; mov edx,20*65536+20 |
call [disable_mouse] |
mov [novesachecksum],dword 0 |
push esi |
push edi |
push eax |
push ebx |
push ecx |
push edx |
movzx eax,word [esp+2] |
movzx ebx,word [esp+0] |
mov ecx,[TASK_BASE] |
add eax,[ecx-twdw+WDATA.box.left] |
add ebx,[ecx-twdw+WDATA.box.top] |
push eax |
mov eax,ebx ; y |
mul dword [BytesPerScanLine] |
pop ecx |
add eax,ecx ; x |
add eax,ecx |
add eax,ecx |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? - x start |
jz pi2412 |
add eax,ecx |
pi2412: |
add eax,[LFBAddress] |
mov edi,eax |
; x size |
movzx ecx,word [esp+6] |
mov esi,[esp+8] |
movzx ebx,word [esp+4] |
; check limits while draw ? |
push ecx |
mov eax,[TASK_BASE] |
cmp dword [eax+draw_data-CURRENT_TASK+RECT.left], 0 |
jnz dbcblimitlset212 |
cmp dword [eax+draw_data-CURRENT_TASK+RECT.top], 0 |
jnz dbcblimitlset212 |
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.right] |
cmp ecx,[ScreenWidth] |
jnz dbcblimitlset212 |
mov ecx,[eax+draw_data-CURRENT_TASK+RECT.bottom] |
cmp ecx,[ScreenHeight] |
jnz dbcblimitlset212 |
pop ecx |
push 0 |
jmp dbcblimitlno212 |
dbcblimitlset212: |
pop ecx |
push 1 |
dbcblimitlno212: |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? |
jnz pi32bit12 |
pi24bit12: |
newpi12: |
push edi |
push ecx |
push ebx |
mov edx,edi |
sub edx,[LFBAddress] |
mov ebx,3 |
div ebx |
add edx,WinMapAddress |
mov ebx,[CURRENT_TASK] |
mov bh,[esp+4*3] |
np2412: |
cmp bl,[edx] |
jnz imp24no12 |
; mov eax,[esi] |
push dword [esp+4*3+20] |
call ebp |
; cmp bh,0 |
; jz imp24yes12 |
; call dbcplimit |
; jnz imp24no12 |
imp24yes12: |
push edi |
push eax |
mov eax,edi |
sub eax,[LFBAddress] |
shr eax,16 |
call set_bank |
pop eax |
and edi,0xffff |
add edi,VGABasePtr |
mov [edi],ax |
shr eax,16 |
mov [edi+2],al |
pop edi |
imp24no12: |
inc edx |
; add esi,3 |
add edi,3 |
dec ecx |
jnz np2412 |
np24d12: |
pop ebx |
pop ecx |
pop edi |
add edi,[BytesPerScanLine] |
add esi,[esp+32] |
dec ebx |
jnz newpi12 |
nonewpi12: |
pop eax edx ecx ebx eax edi esi |
xor eax, eax |
ret |
pi32bit12: |
newpi3212: |
push edi |
push ecx |
push ebx |
mov edx,edi |
sub edx,[LFBAddress] |
shr edx,2 |
add edx,WinMapAddress |
mov ebx,[CURRENT_TASK] |
mov bh,[esp+4*3] |
np3212: |
cmp bl,[edx] |
jnz imp32no12 |
; mov eax,[esi] |
push dword [esp+4*3+20] |
call ebp |
; cmp bh,0 |
; jz imp32yes12 |
; call dbcplimit |
; jnz imp32no12 |
imp32yes12: |
push edi |
push eax |
mov eax,edi |
sub eax,[LFBAddress] |
shr eax,16 |
call set_bank |
pop eax |
and edi,0xffff |
mov [edi+VGABasePtr],eax |
pop edi |
imp32no12: |
inc edx |
; add esi,3 |
add edi,4 |
dec ecx |
jnz np3212 |
np32d12: |
pop ebx |
pop ecx |
pop edi |
add edi,[BytesPerScanLine] |
dec ebx |
jnz newpi3212 |
nonewpi3212: |
pop eax edx ecx ebx eax edi esi |
xor eax, eax |
ret |
vesa12_read_screen_pixel: |
and eax,0x3FFFFF |
cmp [ScreenBPP],byte 24 ; 24 or 32 bpp ? |
jz v12rsp24 |
mov edi,eax |
shl edi,2 |
mov eax,edi |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,VGABasePtr |
mov eax,[edi] |
and eax,0x00ffffff |
ret |
v12rsp24: |
imul eax,3 |
mov edi,eax |
shr eax,16 |
call set_bank |
and edi,65535 |
add edi,VGABasePtr |
mov eax,[edi] |
and eax,0x00ffffff |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/video/vga.inc |
---|
0,0 → 1,450 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; VGA.INC ;; |
;; ;; |
;; 640x480 mode 0x12 VGA functions for MenuetOS ;; |
;; ;; |
;; Paul Butcher, paul.butcher@asa.co.uk ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
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 [SCR_MODE],dword 0x13 |
jne @f |
; cnvl: |
pushad |
cmp [EGA_counter],1 |
je novesal |
mov ecx,[MOUSE_X] |
cmp ecx,[novesachecksum] |
jne novesal |
popad |
@@: |
ret |
novesal: |
mov [novesachecksum],ecx |
mov ecx,0 |
movzx eax,word [MOUSE_Y] |
cmp eax,100 |
jge m13l3 |
mov eax,100 |
m13l3: |
cmp eax,480-100 |
jbe m13l4 |
mov eax,480-100 |
m13l4: |
sub eax,100 |
imul eax,640*4 |
add ecx,eax |
movzx eax,word [MOUSE_X] |
cmp eax,160 |
jge m13l1 |
mov eax,160 |
m13l1: |
cmp eax,640-160 |
jbe m13l2 |
mov eax,640-160 |
m13l2: |
sub eax,160 |
shl eax,2 |
add ecx,eax |
mov esi,[LFBAddress] |
add esi,ecx |
mov edi,VGABasePtr |
mov edx,200 |
mov ecx,320 |
cld |
m13pix: |
lodsd |
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 [SCR_MODE],dword 0x12 |
jne .end |
pushad |
mov esi,[LFBAddress] |
mov edi,VGABasePtr |
mov ebx,640/32 ; 640*480/(8*4) |
mov edx,480 |
@@: |
push ebx edx esi edi |
shl edx,9 |
lea edx,[edx+edx*4] |
add esi,edx |
shr edx,5 |
add edi,edx |
call VGA_draw_long_line |
pop edi esi edx ebx |
dec edx |
jnz @r |
call VGA_draw_long_line_1 |
popad |
.end: |
ret |
VGA_draw_long_line: |
mov dx,3ceh |
mov ax,0ff08h |
cli |
out dx, ax |
mov ax,0005h |
out dx, ax |
m12pix: |
call VGA_draw_32_pixels |
dec ebx |
jnz m12pix |
mov dx,3c4h |
mov ax,0ff02h |
out dx,ax |
mov dx,3ceh |
mov ax,0205h |
out dx,ax |
mov dx,3ceh |
mov al,08h |
out dx,al |
sti |
ret |
VGA_draw_32_pixels: |
xor eax,eax |
mov ebp,VGA_8_pixels |
mov [ebp],eax |
mov [ebp+4],eax |
mov [ebp+8],eax |
mov [ebp+12],eax |
mov ch,4 |
.main_loop: |
mov cl,8 |
.convert_pixels_to_VGA: |
lodsd ; eax = 24bit colour |
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, [LFBAddress] ; + LFB address |
mov [edi], eax ; write to LFB for Vesa2.0 |
shr edx,5 ; change BytesPerPixel to 1/8 |
mov edi,edx |
add edi, VGABasePtr ; address of pixel in VGA area |
and ecx,0x07 ; bit no. (modulo 8) |
pushfd |
; edi = address, eax = 24bit colour, ecx = bit no. (modulo 8) |
xor edx,edx |
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 [SCR_MODE],dword 0x12 |
jne @f |
pushad |
rol edx,16 |
movzx eax,dx |
rol edx,16 |
movzx ebx,dx |
movzx edx,cx |
rol ecx,16 |
movzx ecx,cx |
call VGA_draw_bar_1 |
popad |
@@: |
ret |
VGA_draw_bar: |
; eax cx |
; ebx cy |
; ecx xe |
; edx ye |
cmp [SCR_MODE],dword 0x12 |
jne @f |
pushad |
sub ecx,eax |
sub edx,ebx |
and eax,0xffff |
and ebx,0xffff |
and ecx,0xffff |
and edx,0xffff |
call VGA_draw_bar_1 |
popad |
@@: |
ret |
VGA_draw_bar_1: |
mov [temp.cx],eax |
mov eax, [TASK_BASE] |
add ebx, [eax-twdw + 4] |
mov eax, [eax-twdw + 0] |
add eax, [temp.cx] |
and eax,0xfff8 |
shl ebx,9 |
lea ebx,[ebx+ebx*4] ; óìíîæåíèå íà 5 |
lea ebx, [ebx+eax*4] ; + x*BytesPerPixel (Vesa2.0 32) |
mov esi,ebx |
add esi, [LFBAddress] ; + LFB address |
shr ebx,5 ; change BytesPerPixel to 1/8 |
mov edi,ebx |
add edi, VGABasePtr ; address of pixel in VGA area |
mov ebx,ecx |
shr ebx,5 |
inc ebx |
.main_loop: |
call VGA_draw_long_line_1 |
dec edx |
jnz .main_loop |
call VGA_draw_long_line_1 |
ret |
VGA_draw_long_line_1: |
push ebx edx esi edi |
shl edx,9 |
lea edx,[edx+edx*4] |
add esi,edx |
shr edx,5 |
add edi,edx |
call VGA_draw_long_line |
pop edi esi edx ebx |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/video/cursors.inc |
---|
0,0 → 1,749 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
LOAD_FROM_FILE equ 0 |
LOAD_FROM_MEM equ 1 |
LOAD_INDIRECT equ 2 |
LOAD_SYSTEM equ 3 |
struc BITMAPINFOHEADER { |
.biSize dd ? ; DWORD |
.biWidth dd ? ; LONG |
.biHeight dd ? ; LONG |
.biPlanes dw ? ; WORD |
.biBitCount dw ? ; WORD |
.biCompression dd ? ; DWORD |
.biSizeImage dd ? ; DWORD |
.biXPelsPerMeter dd ? ; LONG |
.biYPelsPerMeter dd ? ; LONG |
.biClrUsed dd ? ; DWORD |
.biClrImportant dd ? ; DWORD |
} |
virtual at 0 |
BI BITMAPINFOHEADER |
end virtual |
align 4 |
proc vesa_init_cursor stdcall, dst:dword, src:dword |
locals |
rBase dd ? |
pQuad dd ? |
pBits dd ? |
pAnd dd ? |
width dd ? |
height dd ? |
counter dd ? |
endl |
mov esi, [src] |
add esi,[esi+18] |
mov eax,esi |
cmp [esi+BI.biBitCount], 24 |
je .img_24 |
cmp [esi+BI.biBitCount], 8 |
je .img_8 |
cmp [esi+BI.biBitCount], 4 |
je .img_4 |
.img_2: |
add eax, [esi] |
mov [pQuad],eax |
add eax,8 |
mov [pBits],eax |
add eax, 128 |
mov [pAnd],eax |
mov eax,[esi+4] |
mov [width],eax |
mov ebx,[esi+8] |
shr ebx,1 |
mov [height],ebx |
mov edi, [dst] |
add edi, 32*31*4 |
mov [rBase],edi |
mov esi,[pQuad] |
.l21: |
mov ebx, [pBits] |
mov ebx, [ebx] |
bswap ebx |
mov eax, [pAnd] |
mov eax, [eax] |
bswap eax |
mov [counter], 32 |
@@: |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
xor ecx, ecx |
shl ebx,1 |
setc cl |
mov ecx, [esi+ecx*4] |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi], edx |
add edi, 4 |
dec [counter] |
jnz @B |
add [pBits], 4 |
add [pAnd], 4 |
mov edi,[rBase] |
sub edi,128 |
mov [rBase],edi |
sub [height],1 |
jnz .l21 |
ret |
.img_4: |
add eax, [esi] |
mov [pQuad],eax |
add eax,64 |
mov [pBits],eax |
add eax, 0x200 |
mov [pAnd],eax |
mov eax,[esi+4] |
mov [width],eax |
mov ebx,[esi+8] |
shr ebx,1 |
mov [height],ebx |
mov edi, [dst] |
add edi, 32*31*4 |
mov [rBase],edi |
mov esi,[pQuad] |
mov ebx, [pBits] |
.l4: |
mov eax, [pAnd] |
mov eax, [eax] |
bswap eax |
mov [counter], 16 |
@@: |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
movzx ecx, byte [ebx] |
and cl, 0xF0 |
shr ecx, 2 |
mov ecx, [esi+ecx] |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi], edx |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
movzx ecx, byte [ebx] |
and cl, 0x0F |
mov ecx, [esi+ecx*4] |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi+4], edx |
inc ebx |
add edi, 8 |
dec [counter] |
jnz @B |
add [pAnd], 4 |
mov edi,[rBase] |
sub edi,128 |
mov [rBase],edi |
sub [height],1 |
jnz .l4 |
ret |
.img_8: |
add eax, [esi] |
mov [pQuad],eax |
add eax,1024 |
mov [pBits],eax |
add eax, 1024 |
mov [pAnd],eax |
mov eax,[esi+4] |
mov [width],eax |
mov ebx,[esi+8] |
shr ebx,1 |
mov [height],ebx |
mov edi, [dst] |
add edi, 32*31*4 |
mov [rBase],edi |
mov esi,[pQuad] |
mov ebx, [pBits] |
.l81: |
mov eax, [pAnd] |
mov eax, [eax] |
bswap eax |
mov [counter], 32 |
@@: |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
movzx ecx, byte [ebx] |
mov ecx, [esi+ecx*4] |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi], edx |
inc ebx |
add edi, 4 |
dec [counter] |
jnz @B |
add [pAnd], 4 |
mov edi,[rBase] |
sub edi,128 |
mov [rBase],edi |
sub [height],1 |
jnz .l81 |
ret |
.img_24: |
add eax, [esi] |
mov [pQuad],eax |
add eax, 0xC00 |
mov [pAnd],eax |
mov eax,[esi+BI.biWidth] |
mov [width],eax |
mov ebx,[esi+BI.biHeight] |
shr ebx,1 |
mov [height],ebx |
mov edi, [dst] |
add edi, 32*31*4 |
mov [rBase],edi |
mov esi,[pAnd] |
mov ebx, [pQuad] |
.row_24: |
mov eax, [esi] |
bswap eax |
mov [counter], 32 |
@@: |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
mov ecx, [ebx] |
and ecx, 0x00FFFFFF |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi], edx |
add ebx, 3 |
add edi, 4 |
dec [counter] |
jnz @B |
add esi, 4 |
mov edi,[rBase] |
sub edi,128 |
mov [rBase],edi |
sub [height],1 |
jnz .row_24 |
ret |
endp |
align 4 |
proc set_cursor stdcall, hcursor:dword |
mov eax, [hcursor] |
cmp [eax+CURSOR.magic], 'CURS' |
jne .fail |
; cmp [eax+CURSOR.size], CURSOR_SIZE |
; jne .fail |
mov ebx, [current_slot] |
xchg eax, [ebx+APPDATA.cursor] |
ret |
.fail: |
mov eax, [def_cursor] |
mov ebx, [current_slot] |
xchg eax, [ebx+APPDATA.cursor] |
ret |
endp |
; param |
; eax= pid |
; ebx= src |
; ecx= flags |
vesa_cursor: |
.src equ esp |
.flags equ esp+4 |
.hcursor equ esp+8 |
sub esp, 4 ;space for .hcursor |
push ecx |
push ebx |
mov ebx, eax |
mov eax, CURSOR_SIZE |
call create_kernel_object |
test eax, eax |
jz .fail |
mov [.hcursor],eax |
xor ebx, ebx |
mov [eax+CURSOR.magic], 'CURS' |
mov [eax+CURSOR.destroy], destroy_cursor |
mov [eax+CURSOR.hot_x], ebx |
mov [eax+CURSOR.hot_y], ebx |
stdcall kernel_alloc, 0x1000 |
test eax, eax |
jz .fail |
mov edi, [.hcursor] |
mov [edi+CURSOR.base], eax |
mov esi, [.src] |
mov ebx, [.flags] |
cmp bx, LOAD_INDIRECT |
je .indirect |
movzx ecx, word [esi+10] |
movzx edx, word [esi+12] |
mov [edi+CURSOR.hot_x], ecx |
mov [edi+CURSOR.hot_y], edx |
stdcall vesa_init_cursor, eax, esi |
mov eax, [.hcursor] |
.fail: |
add esp, 12 |
ret |
.indirect: |
shr ebx, 16 |
movzx ecx, bh |
movzx edx, bl |
mov [eax+CURSOR.hot_x], ecx |
mov [eax+CURSOR.hot_y], edx |
xchg edi, eax |
mov ecx, 1024 |
cld |
rep movsd |
add esp, 12 |
ret |
align 4 |
proc load_cursor stdcall, src:dword, flags:dword |
locals |
handle dd ? |
endl |
xor eax, eax |
mov [handle], eax |
cmp word [flags], LOAD_FROM_FILE |
jne @F |
stdcall load_file, [src] |
test eax, eax |
jz .exit |
mov [src], eax |
@@: |
mov eax, [CURRENT_TASK] |
shl eax, 5 |
mov eax, [CURRENT_TASK+eax+4] |
mov ebx, [src] |
mov ecx, [flags] |
call [create_cursor] ;eax, ebx, ecx |
mov [handle], eax |
.fail: |
cmp word [flags], LOAD_FROM_FILE |
jne .exit |
stdcall kernel_free, [src] |
.exit: |
mov eax, [handle] |
ret |
endp |
align 4 |
proc delete_cursor stdcall, hcursor:dword |
locals |
hsrv dd ? |
io_code dd ? |
input dd ? |
inp_size dd ? |
output dd ? |
out_size dd ? |
endl |
mov esi, [hcursor] |
cmp [esi+CURSOR.magic], 'CURS' |
jne .fail |
; cmp [esi+CURSOR.size], CURSOR_SIZE |
; jne .fail |
mov ebx, [CURRENT_TASK] |
shl ebx, 5 |
mov ebx, [CURRENT_TASK+ebx+4] |
cmp ebx, [esi+CURSOR.pid] |
jne .fail |
mov ebx, [current_slot] |
cmp esi, [ebx+APPDATA.cursor] |
jne @F |
mov eax, [def_cursor] |
mov [ebx+APPDATA.cursor], eax |
@@: |
mov eax, [hcursor] |
call [eax+APPOBJ.destroy] |
.fail: |
ret |
endp |
; param |
; eax= cursor |
align 4 |
destroy_cursor: |
push eax |
stdcall kernel_free, [eax+CURSOR.base] |
pop eax |
call destroy_kernel_object |
ret |
align 4 |
proc init_cursors |
cmp [SCR_MODE],word 0x13 |
jbe .fail |
movzx eax, byte [ScreenBPP] |
mov ebx, [BytesPerScanLine] |
cmp eax, 32 |
jne @F |
sub ebx, 128 |
jmp .init |
@@: |
cmp eax, 24 |
jne .fail |
sub ebx, 96 |
.init: |
mov [cur_def_interl], ebx |
stdcall load_driver, szHwMouse |
mov [hw_cursor], eax |
test eax, eax |
jz .sw_mouse |
stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM |
mov [def_cursor], eax |
ret |
.sw_mouse: |
mov [create_cursor], vesa_cursor |
stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM |
mov [def_cursor], eax |
mov ecx, [ScreenWidth] |
mov edx, [ScreenHeight] |
inc ecx |
inc edx |
mov [scr_width], ecx |
mov [scr_height], edx |
movzx ebx, byte [ScreenBPP] |
cmp ebx, 32 |
jne @F |
mov dword [set_hw_cursor], cursor_32 |
mov dword [hw_restore], restore_32 |
ret |
@@: |
mov dword [set_hw_cursor], cursor_24 |
mov dword [hw_restore], restore_24 |
ret |
.fail: |
xor eax, eax |
mov dword [set_hw_cursor], eax |
mov dword [hw_restore], eax |
ret |
endp |
align 4 |
proc restore_24 stdcall, x:dword, y:dword |
locals |
w dd ? |
endl |
mov edi, [cur_saved_base] |
mov edx, [cur_saved_h] |
mov ebx, [cur_saved_interl] |
mov esi, cur_saved_data |
@@: |
mov ecx, [cur_saved_w] |
lea ecx, [ecx+ecx*2] |
rep movsb |
add edi, ebx |
dec edx |
jnz @B |
ret |
endp |
align 4 |
proc restore_32 stdcall, x:dword, y:dword |
locals |
w dd ? |
endl |
mov edi, [cur_saved_base] |
mov edx, [cur_saved_h] |
mov ebx, [cur_saved_interl] |
mov esi, cur_saved_data |
@@: |
mov ecx, [cur_saved_w] |
rep movsd |
add edi, ebx |
dec edx |
jnz @B |
ret |
endp |
align 4 |
proc cursor_24 stdcall, hcursor:dword, x:dword, y:dword |
locals |
w dd ? |
h dd ? |
st dd ? |
_dx dd ? |
_dy dd ? |
endl |
mov esi, [hcursor] |
mov ecx, [x] |
mov eax, [y] |
mov ebx, [BytesPerScanLine] |
xor edx, edx |
sub ecx, [esi+CURSOR.hot_x] |
mov [x], ecx |
sets dl |
dec edx |
and ecx, edx ;clip x to 0<=x |
mov edi, ecx |
sub edi, [x] |
mov [_dx], edi |
xor edx, edx |
sub eax, [esi+CURSOR.hot_y] |
mov [y], eax |
sets dl |
dec edx |
and eax, edx ;clip y to 0<=y |
mov edi, eax |
sub edi, [y] |
mov [_dy], edi |
mul ebx |
lea esi, [ecx+ecx*2] |
add esi, [LFBAddress] |
add esi, eax |
mov [cur_saved_base],esi |
mov edi, [scr_width] |
mov edx, [scr_height] |
mov eax, 32 |
sub edi, ecx |
cmp edi, eax |
jng @F |
mov edi, eax |
@@: |
sub edi, [_dx] |
sub edx, [y] |
cmp edx, eax |
jng @F |
mov edx, eax |
@@: |
sub edx, [_dy] |
mov [w], edi |
mov [h], edx |
mov [cur_saved_w], edi |
mov [cur_saved_h], edx |
sub eax, edi |
shl eax, 2 ;lea eax, [eax+eax*2] |
lea edi, [edi+edi*2] |
sub ebx, edi |
mov [cur_saved_interl], ebx |
mov edi, cur_saved_data |
@@: |
mov ecx, [w] |
lea ecx, [ecx+ecx*2] |
rep movsb |
add esi, ebx |
dec edx |
jnz @B |
;draw cursor |
mov edx, eax |
mov edi, [cur_saved_base] |
mov eax, [_dy] |
shl eax, 5 |
add eax, [_dx] |
shl eax, 2 |
mov esi, [hcursor] |
mov esi, [esi+CURSOR.base] |
add esi, eax |
.row: |
mov ecx, [w] |
.pix: |
lodsd |
test eax, 0xFF000000 |
jz @F |
mov word [edi], ax |
shr eax, 16 |
mov [edi+2],al |
@@: |
add edi, 3 |
dec ecx |
jnz .pix |
add esi, edx |
add edi, ebx |
dec [h] |
jnz .row |
ret |
endp |
align 4 |
proc cursor_32 stdcall, hcursor:dword, x:dword, y:dword |
locals |
w dd ? |
h dd ? |
st dd ? |
_dx dd ? |
_dy dd ? |
endl |
mov esi, [hcursor] |
mov ecx, [x] |
mov eax, [y] |
mov ebx, [BytesPerScanLine] |
xor edx, edx |
sub ecx, [esi+CURSOR.hot_x] |
mov [x], ecx |
sets dl |
dec edx |
and ecx, edx ;clip x to 0<=x |
mov edi, ecx |
sub edi, [x] |
mov [_dx], edi |
xor edx, edx |
sub eax, [esi+CURSOR.hot_y] |
mov [y], eax |
sets dl |
dec edx |
and eax, edx ;clip y to 0<=y |
mov edi, eax |
sub edi, [y] |
mov [_dy], edi |
mul ebx |
lea esi, [eax+ecx*4] |
add esi, [LFBAddress] |
mov [cur_saved_base],esi |
mov edi, [scr_width] |
mov edx, [scr_height] |
mov eax, 32 |
sub edi, ecx |
cmp edi, eax |
jng @F |
mov edi, eax |
@@: |
sub edi, [_dx] |
sub edx, [y] |
cmp edx, eax |
jng @F |
mov edx, eax |
@@: |
sub edx, [_dy] |
mov [w], edi |
mov [h], edx |
mov [cur_saved_w], edi |
mov [cur_saved_h], edx |
sub eax, edi |
shl eax, 2 |
shl edi, 2 |
sub ebx, edi |
mov [cur_saved_interl], ebx |
mov edi, cur_saved_data |
@@: |
mov ecx, [w] |
rep movsd |
add esi, ebx |
dec edx |
jnz @B |
;draw cursor |
mov edx, eax |
mov edi, [cur_saved_base] |
mov eax, [_dy] |
shl eax, 5 |
add eax, [_dx] |
shl eax, 2 |
mov esi, [hcursor] |
mov esi, [esi+CURSOR.base] |
add esi, eax |
.row: |
mov ecx, [w] |
.pix: |
lodsd |
test eax, 0xFF000000 |
jz @F |
mov [edi], eax |
@@: |
add edi, 4 |
dec ecx |
jnz .pix |
add esi, edx |
add edi, ebx |
dec [h] |
jnz .row |
ret |
endp |
align 4 |
def_arrow: |
file 'arrow.cur' |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/video/arrow.cur |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/data32.inc |
---|
0,0 → 1,342 |
$Revision$ |
keymap: |
db '6',27 |
db '1234567890-=',8,9 |
db 'qwertyuiop[]',13 |
db '~asdfghjkl;',39,96,0,'\zxcvbnm,./',0,'45 ' |
db '@234567890123',180,178,184,'6',176,'7' |
db 179,'8',181,177,183,185,182 |
db 'AB<D',255,'FGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
keymap_shift: |
db '6',27 |
db '!@#$%^&*()_+',8,9 |
db 'QWERTYUIOP{}',13 |
db '~ASDFGHJKL:"~',0,'|ZXCVBNM<>?',0,'45 ' |
db '@234567890123',180,178,184,'6',176,'7' |
db 179,'8',181,177,183,185,182 |
db 'AB>D',255,'FGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
keymap_alt: |
db ' ',27 |
db ' @ $ {[]}\ ',8,9 |
db ' ',13 |
db ' ',0,' ',0,'4',0,' ' |
db ' ',180,178,184,'6',176,'7' |
db 179,'8',181,177,183,185,182 |
db 'ABCD',255,'FGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
boot_memdetect db 'Determining amount of memory',0 |
boot_fonts db 'Fonts loaded',0 |
boot_tss db 'Setting TSSs',0 |
boot_cpuid db 'Reading CPUIDs',0 |
boot_devices db 'Detecting devices',0 |
boot_timer db 'Setting timer',0 |
boot_irqs db 'Reprogramming IRQs',0 |
boot_setmouse db 'Setting mouse',0 |
boot_windefs db 'Setting window defaults',0 |
boot_bgr db 'Calculating background',0 |
boot_resirqports db 'Reserving IRQs & ports',0 |
boot_setrports db 'Setting addresses for IRQs',0 |
boot_setostask db 'Setting OS task',0 |
boot_allirqs db 'Unmasking all IRQs',0 |
boot_tsc db 'Reading TSC',0 |
boot_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 |
new_process_loading db 'K : New Process - loading',13,10,0 |
new_process_running db 'K : New Process - done',13,10,0 |
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0 |
msg_unresolved db 'unresolved ',0 |
msg_module db 'in module ',0 |
msg_version db 'incompatible driver version',13,10,0 |
msg_www db 'please visit www.kolibrios.org',13,10,0 |
msg_CR db 13,10,0 |
intel_str db "GenuineIntel",0 |
AMD_str db "AuthenticAMD",0 |
;szSound db 'SOUND',0 |
;szInfinity db 'INFINITY',0 |
szHwMouse db 'ATI2D',0 |
szPS2MDriver db 'PS2MOUSE',0 |
szSTART db 'START',0 |
szEXPORTS db 'EXPORTS',0 |
szIMPORTS db 'IMPORTS',0 |
firstapp db 'LAUNCHER',0 |
char db '/sys/FONTS/CHAR.MT',0 |
char2 db '/sys/FONTS/CHAR2.MT',0 |
bootpath db '/KOLIBRI ' |
bootpath2 db 0 |
vmode db 'drivers/VMODE.MDR',0 |
vrr_m db 'VRR_M',0 |
kernel_file db 'KERNEL MNT' |
; mike.dld { |
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 |
align 4 |
keyboard dd 1 |
sound_dma dd 1 |
syslang dd 1 |
boot_y dd 10 |
if __DEBUG__ eq 1 |
include_debug_strings |
end if |
IncludeIGlobals |
align 16 |
gdts: |
dw gdte-$-1 |
dd gdts |
dw 0 |
; Attention! Do not change the order of the first four selectors. They are used in Fast System Call |
; must be : os_code, os_data, app_code, app_data, .... |
int_code_l: |
os_code_l: |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10011010b |
db 0x00 |
int_data_l: |
os_data_l: |
dw 0xffff |
dw 0x0000 |
db 0x00 |
dw 11011111b *256 +10010010b |
db 0x00 |
app_code_l: |
dw 0xFFFF |
dw 0 |
db 0 |
db cpl3 |
dw G32+D32+(new_app_base shr 16)+0xF; |
app_data_l: |
dw 0xFFFF |
dw 0 |
db 0 |
db drw3 |
dw G32+D32+(new_app_base shr 16)+0xF; |
; --------------- APM --------------------- |
apm_code_32: |
dw 0x0f ; limit 64kb |
db 0, 0, 0 |
dw 11010000b *256 +10011010b |
db 0x00 |
apm_code_16: |
dw 0x0f |
db 0, 0, 0 |
dw 10010000b *256 +10011010b |
db 0x00 |
apm_data_16: |
dw 0x0f |
db 0, 0, 0 |
dw 10010000b *256 +10010010b |
db 0x00 |
; ----------------------------------------- |
graph_data_l: |
dw 0x7ff |
dw 0x0000 |
db 0x00 |
dw 11010000b *256 +11110010b |
db 0x00 |
tss0_l: |
dw TSS_SIZE-1 |
dw tss and 0xFFFF |
db (tss shr 16) and 0xFF |
db 10001001b |
dw (tss shr 16) and 0xFF00 |
endofcode: |
gdte: |
align 16 |
cur_saved_data rb 4096 |
fpu_data: rb 512 |
; device irq owners |
irq_owner rd 16 ; process id |
; on irq read ports |
irq00read rd 16 |
irq01read rd 16 |
irq02read rd 16 |
irq03read rd 16 |
irq04read rd 16 |
irq05read rd 16 |
irq06read rd 16 |
irq07read rd 16 |
irq08read rd 16 |
irq09read rd 16 |
irq10read rd 16 |
irq11read rd 16 |
irq12read rd 16 |
irq13read rd 16 |
irq14read rd 16 |
irq15read rd 16 |
irq_tab rd 16 |
mem_block_map rb 512 |
event_map rb 64 |
mem_block_list rd 64 |
mem_block_mask rd 2 |
mem_used.fd rd 1 |
mem_used.bk rd 1 |
mem_block_arr rd 1 |
mem_block_start rd 1 |
mem_block_end rd 1 |
heap_mutex rd 1 |
heap_size rd 1 |
heap_free rd 1 |
heap_blocks rd 1 |
free_blocks rd 1 |
mst MEM_STATE |
page_start rd 1 |
page_end rd 1 |
events rd 1 |
event_start rd 1 |
event_end rd 1 |
event_uid rd 1 |
sys_page_map rd 1 |
os_stack_seg rd 1 |
srv.fd rd 1 |
srv.bk rd 1 |
scr_width rd 1 |
scr_height rd 1 |
create_cursor rd 1 |
set_hw_cursor rd 1 |
hw_restore rd 1 |
def_cursor rd 1 |
hw_cursor rd 1 |
cur_def_interl rd 1 |
cur_saved_base rd 1 |
cur_saved_interl rd 1 |
cur_saved_w rd 1 |
cur_saved_h rd 1 |
ipc_tmp rd 1 |
ipc_pdir rd 1 |
ipc_ptab rd 1 |
proc_mem_map rd 1 |
proc_mem_pdir rd 1 |
proc_mem_tab rd 1 |
tmp_task_pdir rd 1 |
tmp_task_ptab rd 1 |
default_io_map rd 1 |
LFBSize rd 1 |
stall_mcs rd 1 |
current_slot rd 1 |
; status |
hd1_status rd 1 ; 0 - free : other - pid |
application_table_status rd 1 ; 0 - free : other - pid |
; device addresses |
mididp rd 1 |
midisp rd 1 |
cdbase rd 1 |
cdid rd 1 |
hdbase rd 1 ; for boot 0x1f0 |
hdid rd 1 |
hdpos rd 1 ; for boot 0x1 |
fat32part rd 1 ; for boot 0x1 |
sb16 rd 1 |
;CPUID information |
cpu_vendor rd 3 |
cpu_sign rd 1 |
cpu_info rd 1 |
cpu_caps rd 4 |
pg_data PG_DATA |
heap_test rd 1 |
buttontype rd 1 |
windowtypechanged rd 1 |
hd_entries rd 1 ;unused ? 0xfe10 |
;* start code - Mario79 |
mouse_active rd 1 |
mouse_pause rd 1 |
MouseTickCounter rd 1 |
com1_mouse_detected rb 1 |
com2_mouse_detected rb 1 |
;* end code - Mario79 |
img_background rd 1 |
mem_BACKGROUND rd 1 |
wraw_bacground_select rb 1 |
lba_read_enabled rd 1 ; 0 = disabled , 1 = enabled |
pci_access_enabled rd 1 ; 0 = disabled , 1 = enabled |
IncludeUGlobals |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/const.inc |
---|
0,0 → 1,670 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
drw0 equ 10010010b ; data read/write dpl0 |
drw3 equ 11110010b ; data read/write dpl3 |
cpl0 equ 10011010b ; code read dpl0 |
cpl3 equ 11111010b ; code read dpl3 |
D32 equ 01000000b ; 32bit segment |
G32 equ 10000000b ; page gran |
;;;;;;;;;;;;cpu_caps flags;;;;;;;;;;;;;;;; |
CPU_386 equ 3 |
CPU_486 equ 4 |
CPU_PENTIUM equ 5 |
CPU_P6 equ 6 |
CPU_PENTIUM4 equ 0x0F |
CAPS_FPU equ 00 ;on-chip x87 floating point unit |
CAPS_VME equ 01 ;virtual-mode enhancements |
CAPS_DE equ 02 ;debugging extensions |
CAPS_PSE equ 03 ;page-size extensions |
CAPS_TSC equ 04 ;time stamp counter |
CAPS_MSR equ 05 ;model-specific registers |
CAPS_PAE equ 06 ;physical-address extensions |
CAPS_MCE equ 07 ;machine check exception |
CAPS_CX8 equ 08 ;CMPXCHG8B instruction |
CAPS_APIC equ 09 ;on-chip advanced programmable |
; interrupt controller |
; 10 ;unused |
CAPS_SEP equ 11 ;SYSENTER and SYSEXIT instructions |
CAPS_MTRR equ 12 ;memory-type range registers |
CAPS_PGE equ 13 ;page global extension |
CAPS_MCA equ 14 ;machine check architecture |
CAPS_CMOV equ 15 ;conditional move instructions |
CAPS_PAT equ 16 ;page attribute table |
CAPS_PSE36 equ 17 ;page-size extensions |
CAPS_PSN equ 18 ;processor serial number |
CAPS_CLFLUSH equ 19 ;CLFUSH instruction |
CAPS_DS equ 21 ;debug store |
CAPS_ACPI equ 22 ;thermal monitor and software |
;controlled clock supported |
CAPS_MMX equ 23 ;MMX instructions |
CAPS_FXSR equ 24 ;FXSAVE and FXRSTOR instructions |
CAPS_SSE equ 25 ;SSE instructions |
CAPS_SSE2 equ 26 ;SSE2 instructions |
CAPS_SS equ 27 ;self-snoop |
CAPS_HTT equ 28 ;hyper-threading technology |
CAPS_TM equ 29 ;thermal monitor supported |
CAPS_IA64 equ 30 ;IA64 capabilities |
CAPS_PBE equ 31 ;pending break enable |
;ecx |
CAPS_SSE3 equ 32 ;SSE3 instructions |
; 33 |
; 34 |
CAPS_MONITOR equ 35 ;MONITOR/MWAIT instructions |
CAPS_DS_CPL equ 36 ; |
CAPS_VMX equ 37 ;virtual mode extensions |
; 38 ; |
CAPS_EST equ 39 ;enhansed speed step |
CAPS_TM2 equ 40 ;thermal monitor2 supported |
; 41 |
CAPS_CID equ 42 ; |
; 43 |
; 44 |
CAPS_CX16 equ 45 ;CMPXCHG16B instruction |
CAPS_xTPR equ 46 ; |
; |
;reserved |
; |
;ext edx /ecx |
CAPS_SYSCAL equ 64 ; |
CAPS_XD equ 65 ;execution disable |
CAPS_FFXSR equ 66 ; |
CAPS_RDTSCP equ 67 ; |
CAPS_X64 equ 68 ; |
CAPS_3DNOW equ 69 ; |
CAPS_3DNOWEXT equ 70 ; |
CAPS_LAHF equ 71 ; |
CAPS_CMP_LEG equ 72 ; |
CAPS_SVM equ 73 ;secure virual machine |
CAPS_ALTMOVCR8 equ 74 ; |
; CPU MSR names |
MSR_SYSENTER_CS equ 0x174 |
MSR_SYSENTER_ESP equ 0x175 |
MSR_SYSENTER_EIP equ 0x176 |
MSR_AMD_EFER equ 0xC0000080 ; Extended Feature Enable Register |
MSR_AMD_STAR equ 0xC0000081 ; SYSCALL/SYSRET Target Address Register |
CR0_PE equ 0x00000001 ;protected mode |
CR0_MP equ 0x00000002 ;monitor fpu |
CR0_EM equ 0x00000004 ;fpu emulation |
CR0_TS equ 0x00000008 ;task switch |
CR0_ET equ 0x00000010 ;extension type hardcoded to 1 |
CR0_NE equ 0x00000020 ;numeric error |
CR0_WP equ 0x00010000 ;write protect |
CR0_AM equ 0x00040000 ;alignment check |
CR0_NW equ 0x20000000 ;not write-through |
CR0_CD equ 0x40000000 ;cache disable |
CR0_PG equ 0x80000000 ;paging |
CR4_VME equ 0x0001 |
CR4_PVI equ 0x0002 |
CR4_TSD equ 0x0004 |
CR4_DE equ 0x0008 |
CR4_PSE equ 0x0010 |
CR4_PAE equ 0x0020 |
CR4_MCE equ 0x0040 |
CR4_PGE equ 0x0080 |
CR4_PCE equ 0x0100 |
CR4_OSFXSR equ 0x0200 |
CR4_OSXMMEXPT equ 0x0400 |
SSE_IE equ 0x0001 |
SSE_DE equ 0x0002 |
SSE_ZE equ 0x0004 |
SSE_OE equ 0x0008 |
SSE_UE equ 0x0010 |
SSE_PE equ 0x0020 |
SSE_DAZ equ 0x0040 |
SSE_IM equ 0x0080 |
SSE_DM equ 0x0100 |
SSE_ZM equ 0x0200 |
SSE_OM equ 0x0400 |
SSE_UM equ 0x0800 |
SSE_PM equ 0x1000 |
SSE_FZ equ 0x8000 |
SSE_INIT equ (SSE_IM+SSE_DM+SSE_ZM+SSE_OM+SSE_UM+SSE_PM) |
struc TSS |
{ |
._back rw 2 |
._esp0 rd 1 |
._ss0 rw 2 |
._esp1 rd 1 |
._ss1 rw 2 |
._esp2 rd 1 |
._ss2 rw 2 |
._cr3 rd 1 |
._eip rd 1 |
._eflags rd 1 |
._eax rd 1 |
._ecx rd 1 |
._edx rd 1 |
._ebx rd 1 |
._esp rd 1 |
._ebp rd 1 |
._esi rd 1 |
._edi rd 1 |
._es rw 2 |
._cs rw 2 |
._ss rw 2 |
._ds rw 2 |
._fs rw 2 |
._gs rw 2 |
._ldt rw 2 |
._trap rw 1 |
._io rw 1 |
rb 24 |
._io_map_0 rb 4096 |
._io_map_1 rb 4096 |
} |
virtual at 0 |
TSS TSS |
end virtual |
TSS_SIZE equ (128+8192) |
OS_BASE equ 0x80000000 |
window_data equ OS_BASE |
CURRENT_TASK equ (OS_BASE+0x0003000) |
TASK_COUNT equ (OS_BASE+0x0003004) |
TASK_BASE equ (OS_BASE+0x0003010) |
TASK_DATA equ (OS_BASE+0x0003020) |
TASK_EVENT equ (OS_BASE+0x0003020) |
mouseunder equ (OS_BASE+0x0006900) |
CDDataBuf equ (OS_BASE+0x0007000) |
FLOPPY_BUFF equ (OS_BASE+0x0008000) |
ACTIVE_PROC_STACK equ (OS_BASE+0x000A400) ;unused |
idts equ (OS_BASE+0x000B100) |
WIN_STACK equ (OS_BASE+0x000C000) |
WIN_POS equ (OS_BASE+0x000C400) |
FDD_BUFF equ (OS_BASE+0x000D000) |
;unused ? only one reference |
ENABLE_TASKSWITCH equ (OS_BASE+0x000E000) |
PUTPIXEL equ (OS_BASE+0x000E020) |
GETPIXEL equ (OS_BASE+0x000E024) |
;unused ? only one reference |
BANK_SWITCH equ (OS_BASE+0x000E030) |
;unused ? store mousepointer |
MOUSE_PICTURE equ (OS_BASE+0x000F200) |
MOUSE_VISIBLE equ (OS_BASE+0x000F204) |
WIN_TEMP_XY equ (OS_BASE+0x000F300) |
KEY_COUNT equ (OS_BASE+0x000F400) |
KEY_BUFF equ (OS_BASE+0x000F401) |
BTN_COUNT equ (OS_BASE+0x000F500) |
BTN_BUFF equ (OS_BASE+0x000F501) |
CPU_FREQ equ (OS_BASE+0x000F600) |
;unused ? no active references |
MOUSE_PORT equ (OS_BASE+0x000F604) |
;unused |
PS2_CHUNK equ (OS_BASE+0x000FB00) |
MOUSE_SCROLL_H equ (OS_BASE+0x000FB08) |
MOUSE_X equ (OS_BASE+0x000FB0A) |
MOUSE_Y equ (OS_BASE+0x000FB0C) |
MOUSE_SCROLL_V equ (OS_BASE+0x000FB0E) |
MOUSE_COLOR_MEM equ (OS_BASE+0x000FB10) |
COLOR_TEMP equ (OS_BASE+0x000FB30) |
BTN_DOWN equ (OS_BASE+0x000FB40) |
MOUSE_DOWN equ (OS_BASE+0x000FB44) |
X_UNDER equ (OS_BASE+0x000FB4A) |
Y_UNDER equ (OS_BASE+0x000FB4C) |
ScreenBPP equ (OS_BASE+0x000FBF1) |
;unused ? only one reference |
MOUSE_BUFF_COUNT equ (OS_BASE+0x000FCFF) |
LFBAddress equ (OS_BASE+0x000FE80) |
MEM_AMOUNT equ (OS_BASE+0x000FE8C) |
ScreenWidth equ (OS_BASE+0x000FE00) |
ScreenHeight equ (OS_BASE+0x000FE04) |
BytesPerScanLine 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) |
TMP_STACK_TOP equ 0x006CC00 |
FONT_II equ (OS_BASE+0x006DC00) |
FONT_I equ (OS_BASE+0x006E600) |
sys_pgdir equ (OS_BASE+0x006F000) |
DRIVE_DATA equ (OS_BASE+0x0070000) |
SLOT_BASE equ (OS_BASE+0x0080000) |
;unused |
TMP_BUFF equ (OS_BASE+0x0090000) |
VGABasePtr equ (OS_BASE+0x00A0000) |
RAMDISK equ (OS_BASE+0x0100000) |
RAMDISK_FAT equ (OS_BASE+0x0280000) |
FLOPPY_FAT equ (OS_BASE+0x0282000) |
; unused? |
SB16_Status equ (OS_BASE+0x02B0000) |
BUTTON_INFO equ (OS_BASE+0x02C0000) |
RESERVED_PORTS equ (OS_BASE+0x02D0000) |
IRQ_SAVE equ (OS_BASE+0x02E0000) |
BOOT_VAR equ (OS_BASE+0x02f0000) |
DMA_HD_MEM equ 0x0300000 |
HD_CACHE equ (OS_BASE+DMA_HD_MEM) |
stack_data_start equ (OS_BASE+0x0400000) |
eth_data_start equ (OS_BASE+0x0400000) |
stack_data equ (OS_BASE+0x0404000) |
stack_data_end equ (OS_BASE+0x041ffff) |
resendQ equ (OS_BASE+0x0420000) |
VMODE_BASE equ (OS_BASE+0x0428000) |
skin_data equ (OS_BASE+0x0430000) |
draw_data equ (OS_BASE+0x0438000); |
virtual at (OS_BASE+0x043BF80) |
tss TSS |
end virtual |
BgrDrawMode equ (OS_BASE+0x043EFF4) |
BgrDataWidth equ (OS_BASE+0x043EFF8) |
BgrDataHeight equ (OS_BASE+0x043EFFC) |
WinMapAddress equ (OS_BASE+0x043F000) |
display_data equ (OS_BASE+0x043F000) |
sys_pgmap equ (OS_BASE+0x057F000) |
HEAP_BASE equ (OS_BASE+0x0800000) |
HEAP_MIN_SIZE equ 0x01000000 |
page_tabs equ 0xFDC00000 |
app_page_tabs equ 0xFDC00000 |
kernel_tabs equ (page_tabs+ (OS_BASE shr 10)) ;0xFDE00000 |
master_tab equ (page_tabs+ (page_tabs shr 10)) ;0xFDFF70000 |
LFB_BASE equ 0xFE000000 |
new_app_base equ 0; |
twdw equ 0x3000 ;(CURRENT_TASK-window_data) |
std_application_base_address equ new_app_base |
RING0_STACK_SIZE equ (0x2000 - 512) ;512 áàéò äëÿ êîíòåêñòà FPU |
if 0 |
REG_SS equ (RING0_STACK_SIZE-4) |
REG_APP_ESP equ (RING0_STACK_SIZE-8) |
REG_EFLAGS equ (RING0_STACK_SIZE-12) |
REG_CS equ (RING0_STACK_SIZE-16) |
REG_EIP equ (RING0_STACK_SIZE-20) |
REG_EFL_2 equ (RING0_STACK_SIZE-24) |
REG_EAX equ (RING0_STACK_SIZE-28) |
REG_ECX equ (RING0_STACK_SIZE-32) |
REG_EDX equ (RING0_STACK_SIZE-36) |
REG_EBX equ (RING0_STACK_SIZE-40) |
REG_ESP equ (RING0_STACK_SIZE-44) ;RING0_STACK_SIZE-20 |
REG_EBP equ (RING0_STACK_SIZE-48) |
REG_ESI equ (RING0_STACK_SIZE-52) |
REG_EDI equ (RING0_STACK_SIZE-56) |
REG_RET equ (RING0_STACK_SIZE-60) ;irq0.return |
end if |
REG_SS equ (RING0_STACK_SIZE-4) |
REG_APP_ESP equ (RING0_STACK_SIZE-8) |
REG_EFLAGS equ (RING0_STACK_SIZE-12) |
REG_CS equ (RING0_STACK_SIZE-16) |
REG_EIP equ (RING0_STACK_SIZE-20) |
REG_EAX equ (RING0_STACK_SIZE-24) |
REG_ECX equ (RING0_STACK_SIZE-28) |
REG_EDX equ (RING0_STACK_SIZE-32) |
REG_EBX equ (RING0_STACK_SIZE-36) |
REG_ESP equ (RING0_STACK_SIZE-40) ;RING0_STACK_SIZE-20 |
REG_EBP equ (RING0_STACK_SIZE-44) |
REG_ESI equ (RING0_STACK_SIZE-48) |
REG_EDI equ (RING0_STACK_SIZE-52) |
REG_RET equ (RING0_STACK_SIZE-56) ;irq0.return |
PG_UNMAP equ 0x000 |
PG_MAP equ 0x001 |
PG_WRITE equ 0x002 |
PG_SW equ 0x003 |
PG_USER equ 0x005 |
PG_UW equ 0x007 |
PG_NOCACHE equ 0x018 |
PG_LARGE equ 0x080 |
PG_GLOBAL equ 0x100 |
;;;;;;;;;;;boot time variables |
;BOOT_BPP equ 0x9000 ;byte bits per pixel |
BOOT_SCANLINE equ 0x9001 ;word scanline length |
BOOT_VESA_MODE equ 0x9008 ;word vesa video mode |
;;BOOT_X_RES equ 0x900A ;word X res |
;;BOOT_Y_RES equ 0x900C ;word Y res |
;;BOOT_MOUSE_PORT equ 0x9010 ;byte mouse port - not used |
BOOT_BANK_SW equ 0x9014 ;dword Vesa 1.2 pm bank switch |
BOOT_LFB equ 0x9018 ;dword Vesa 2.0 LFB address |
BOOT_MTRR equ 0x901C ;byte 0 or 1 : enable MTRR graphics acceleration |
BOOT_LOG equ 0x901D ;byte not used anymore (0 or 1 : enable system log display) |
BOOT_DIRECT_LFB equ 0x901E ;byte 0 or 1 : enable direct lfb write, paging disabled |
BOOT_PCI_DATA equ 0x9020 ;8bytes pci data |
BOOT_VRR equ 0x9030 ;byte VRR start enabled 1, 2-no |
BOOT_IDE_BASE_ADDR equ 0x9031 ;word IDEContrRegsBaseAddr |
BOOT_MEM_AMOUNT equ 0x9034 ;dword memory amount |
TMP_FILE_NAME equ 0 |
TMP_CMD_LINE equ 1024 |
TMP_ICON_OFFS equ 1280 |
EVENT_REDRAW equ 0x00000001 |
EVENT_KEY equ 0x00000002 |
EVENT_BUTTON equ 0x00000004 |
EVENT_BACKGROUND equ 0x00000010 |
EVENT_MOUSE equ 0x00000020 |
EVENT_IPC equ 0x00000040 |
EVENT_NETWORK equ 0x00000080 |
EVENT_DEBUG equ 0x00000100 |
EVENT_EXTENDED equ 0x00000200 |
EV_INTR equ 1 |
struc THR_DATA |
{ |
rb (8192-512) |
.pl0_stack: |
.fpu_state rb 512 |
.tls_page rb 4096 |
.pdbr rb 4096 |
} |
THR_DATA_SIZE equ 4096*4 |
virtual at (OS_BASE-THR_DATA_SIZE) |
thr_data THR_DATA |
end virtual |
struc SYS_VARS |
{ .bpp dd ? |
.scanline dd ? |
.vesa_mode dd ? |
.x_res dd ? |
.y_res dd ? |
} |
struc APPOBJ ;common object header |
{ |
.magic dd ? ; |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
}; |
virtual at 0 |
APPOBJ APPOBJ |
end virtual |
APP_OBJ_OFFSET equ 48 |
APP_EV_OFFSET equ 40 |
struc CURSOR |
{;common object header |
.magic dd ? ;'CURS' |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
;cursor data |
.base dd ? ;allocated memory |
.hot_x dd ? ;hotspot coords |
.hot_y dd ? |
} |
virtual at 0 |
CURSOR CURSOR |
end virtual |
CURSOR_SIZE equ 32 |
struc EVENT |
{ |
.magic dd ? ;'EVNT' |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
.id dd ? ;event uid |
.state dd ? ;internal flags |
.code dd ? |
rd 5 |
} |
EVENT_SIZE equ 52 |
virtual at 0 |
EVENT EVENT |
end virtual |
struc HEAP_DATA |
{ |
.mutex rd 1 |
.refcount rd 1 |
.heap_base rd 1 |
.heap_top rd 1 |
.app_mem rd 1 |
} |
HEAP_DATA_SIZE equ 20 |
virtual at 0 |
HEAP_DATA HEAP_DATA |
end virtual |
struc BOOT_DATA |
{ .bpp dd ? |
.scanline dd ? |
.vesa_mode dd ? |
.x_res dd ? |
.y_res dd ? |
.mouse_port dd ? |
.bank_switch dd ? |
.lfb dd ? |
.vesa_mem dd ? |
.log dd ? |
.direct_lfb dd ? |
.pci_data dd ? |
; dd ? |
.vrr dd ? |
.ide_base dd ? |
.mem_amount dd ? |
.pages_count dd ? |
.pagemap_size dd ? |
.kernel_max dd ? |
.kernel_pages dd ? |
.kernel_tables dd ? |
.cpu_vendor dd ? |
dd ? |
dd ? |
.cpu_sign dd ? |
.cpu_info dd ? |
.cpu_caps dd ? |
dd ? |
dd ? |
} |
virtual at 0 |
BOOT_DATA BOOT_DATA |
end virtual |
struc MEM_STATE |
{ .mutex rd 1 |
.smallmap rd 1 |
.treemap rd 1 |
.topsize rd 1 |
.top rd 1 |
.smallbins rd 4*32 |
.treebins rd 32 |
} |
struc PG_DATA |
{ .mem_amount dd ? |
.vesa_mem dd ? |
.pages_count dd ? |
.pages_free dd ? |
.pages_faults dd ? |
.pagemap_size dd ? |
.kernel_pages dd ? |
.kernel_tables dd ? |
.sys_page_dir dd ? |
.pg_mutex dd ? |
} |
;struc LIB |
;{ .lib_name rb 16 |
; .lib_base dd ? |
; .lib_start dd ? |
; .export dd ? |
; .import dd ? |
;} |
struc SRV |
{ .srv_name rb 16 ;ASCIIZ string |
.magic dd ? ;+0x10 ;'SRV ' |
.size dd ? ;+0x14 ;size of structure SRV |
.fd dd ? ;+0x18 ;next SRV descriptor |
.bk dd ? ;+0x1C ;prev SRV descriptor |
.base dd ? ;+0x20 ;service base address |
.entry dd ? ;+0x24 ;service START function |
.srv_proc dd ? ;+0x28 ;main service handler |
} |
SRV_FD_OFFSET equ 0x18 |
SRV_SIZE equ 44 |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
struc COFF_HEADER |
{ .machine dw ? |
.nSections dw ? |
.DataTime dd ? |
.pSymTable dd ? |
.nSymbols dd ? |
.optHeader dw ? |
.flags dw ? |
}; |
struc COFF_SECTION |
{ .Name rb 8 |
.VirtualSize dd ? |
.VirtualAddress dd ? |
.SizeOfRawData dd ? |
.PtrRawData dd ? |
.PtrReloc dd ? |
.PtrLinenumbers dd ? |
.NumReloc dw ? |
.NumLinenum dw ? |
.Characteristics dd ? |
} |
COFF_SECTION_SIZE equ 40 |
struc COFF_RELOC |
{ .VirtualAddress dd ? |
.SymIndex dd ? |
.Type dw ? |
} |
struc COFF_SYM |
{ .Name rb 8 |
.Value dd ? |
.SectionNumber dw ? |
.Type dw ? |
.StorageClass db ? |
.NumAuxSymbols db ? |
} |
CSYM_SIZE equ 18 |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
;virtual at 0 |
; LIB LIB |
;end virtual |
virtual at 0 |
SRV SRV |
end virtual |
virtual at 0 |
CFH COFF_HEADER |
end virtual |
virtual at 0 |
CFS COFF_SECTION |
end virtual |
virtual at 0 |
CRELOC COFF_RELOC |
end virtual |
virtual at 0 |
CSYM COFF_SYM |
end virtual |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/gui/event.inc |
---|
0,0 → 1,665 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
init_events: |
stdcall kernel_alloc, 512*EVENT_SIZE |
mov [events], eax |
xor eax, eax |
mov [event_uid], eax |
not eax |
mov edi, event_map |
mov [event_start], edi |
mov ecx, 64/4 |
cld |
rep stosd |
mov [event_end], edi |
ret |
align 4 |
proc alloc_event |
pushfd |
cli |
mov ebx, [event_start] |
mov ecx, [event_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 [event_start],ebx |
inc [event_uid] |
sub ebx, event_map |
lea eax,[eax+ebx*8] |
lea ebx, [eax+eax*4] |
shl eax,5 |
lea eax,[eax+ebx*4] ;eax*=52 (EVENT_SIZE) |
add eax, [events] |
mov ebx, [event_uid] |
popfd |
ret |
endp |
align 4 |
free_event: |
sub eax, [events] |
mov ecx, EVENT_SIZE |
mov ebx, event_map |
cdq |
div ecx |
pushfd |
cli |
bts [ebx], eax |
shr eax, 3 |
and eax, not 3 |
add eax, ebx |
cmp [event_start], eax |
ja @f |
popfd |
ret |
@@: |
mov [event_start], eax |
popfd |
ret |
EVENT_WATCHED equ 0x10000000 |
EVENT_SIGNALED equ 0x20000000 |
MANUAL_RESET equ 0x40000000 |
MANUAL_DESTROY equ 0x80000000 |
; param |
; eax= event data |
; ebx= flags |
; |
; retval |
; eax= event |
; edx= id |
create_event: |
.flags equ esp+4 |
.data equ esp |
push ebx |
push eax |
call alloc_event |
test eax, eax |
jz .fail |
mov [eax+APPOBJ.magic], 'EVNT' |
mov [eax+APPOBJ.destroy], destroy_event.internal |
mov [eax+EVENT.id], ebx |
mov ebx, [CURRENT_TASK] |
shl ebx, 5 |
mov ebx, [CURRENT_TASK+ebx+4] |
mov [eax+APPOBJ.pid], ebx |
mov edx, [.flags] |
mov [eax+EVENT.state], edx |
mov esi, [.data] |
test esi, esi |
jz @F |
lea edi, [eax+EVENT.code] |
mov ecx, 6 |
cld |
rep movsd |
@@: |
mov ecx, [current_slot] |
add ecx, APP_OBJ_OFFSET |
pushfd |
cli |
mov edx, [ecx+APPOBJ.fd] |
mov [eax+APPOBJ.fd], edx |
mov [eax+APPOBJ.bk], ecx |
mov [ecx+APPOBJ.fd], eax |
mov [edx+APPOBJ.bk], eax |
popfd |
mov edx, [eax+EVENT.id] |
.fail: |
add esp, 8 |
ret |
restore .flags |
restore .data |
; param |
; eax= event |
; ebx= id |
destroy_event: |
cmp [eax+APPOBJ.magic], 'EVNT' |
jne .fail |
cmp [eax+EVENT.id], ebx |
jne .fail |
.internal: |
mov ebx, [eax+APPOBJ.fd] |
mov ecx, [eax+APPOBJ.bk] |
mov [ebx+APPOBJ.bk], ecx |
mov [ecx+APPOBJ.fd], ebx |
.force: |
xor edx, edx ;clear common header |
mov [eax], edx |
mov [eax+4], edx |
mov [eax+8], edx |
mov [eax+12], edx |
mov [eax+16], edx |
call free_event ;release object memory |
.fail: |
ret |
align 4 |
proc send_event stdcall pid:dword, event:dword |
locals |
slot dd ? |
endl |
mov eax, [pid] |
call pid_to_slot |
test eax, eax |
jz .fail |
shl eax, 8 |
cmp [SLOT_BASE+eax+APPDATA.ev_count], 32 |
ja .fail |
mov [slot], eax |
call alloc_event |
test eax, eax |
jz .fail |
lea edi, [eax+EVENT.code] |
mov ecx, 6 |
mov esi, [event] |
cld |
rep movsd |
mov ecx, [slot] |
add ecx, SLOT_BASE+APP_EV_OFFSET |
mov [eax+APPOBJ.magic], 'EVNT' |
mov [eax+APPOBJ.destroy], destroy_event |
mov ebx, [pid] |
mov [eax+APPOBJ.pid], ebx |
mov [eax+EVENT.state], EVENT_SIGNALED |
pushfd |
cli ;insert event into |
mov edx, [ecx+APPOBJ.fd] ;events list |
mov [eax+APPOBJ.fd], edx ;and set events flag |
mov [eax+APPOBJ.bk], ecx |
mov [ecx+APPOBJ.fd], eax |
mov [edx+APPOBJ.bk], eax |
inc [ecx+APPDATA.ev_count-APP_EV_OFFSET] |
or [ecx+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED |
popfd |
.fail: |
ret |
endp |
; timeout ignored |
align 4 |
proc get_event_ex stdcall, p_ev:dword, timeout:dword |
.wait: |
mov edx,[current_slot] |
; cmp [SLOT_BASE+edx+APPDATA.ev_count], 0 |
; je .switch |
add edx, APP_EV_OFFSET |
mov eax, [edx+APPOBJ.fd] |
cmp eax, edx |
je .switch |
lea esi, [eax+EVENT.code] |
mov edi, [p_ev] ;copy event data |
mov ecx, 6 |
cld |
rep movsd |
and dword [edi-24], 0xFF00FFFF ;clear priority field |
; |
test [eax+EVENT.state], MANUAL_RESET |
jnz .done |
pushfd |
cli ;remove event from events |
mov ebx, [eax+APPOBJ.fd] ;list (reset event) |
mov ecx, [eax+APPOBJ.bk] ;and clear events flag |
mov [ebx+APPOBJ.bk], ecx ;if no active events |
mov [ecx+APPOBJ.fd], ebx |
and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED) |
dec [edx+APPDATA.ev_count-APP_EV_OFFSET] |
jnz @F |
and [edx+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED |
@@: |
popfd |
test [eax+EVENT.state], MANUAL_DESTROY |
jz .destroy |
add edx, (APP_OBJ_OFFSET-APP_EV_OFFSET) |
pushfd |
cli |
mov ebx, [edx+APPOBJ.fd] ;insert event into |
mov [eax+APPOBJ.fd], ebx ;objects list |
mov [eax+APPOBJ.bk], edx |
mov [edx+APPOBJ.fd], eax |
mov [ebx+APPOBJ.bk], eax |
popfd |
.done: |
ret |
.destroy: |
call destroy_event.force |
ret |
.switch: |
mov eax, [TASK_BASE] |
mov [eax+TASKDATA.state], byte 5 |
call change_task |
jmp .wait |
endp |
; param |
; eax= event |
; ebx= id |
align 4 |
wait_event: |
.event equ esp |
push eax |
.wait: |
cmp [eax+APPOBJ.magic], 'EVNT' |
jne .done |
cmp [eax+EVENT.id], ebx |
jne .done |
test [eax+EVENT.state], EVENT_SIGNALED |
jz .switch |
test [eax+EVENT.state], MANUAL_RESET |
jnz .done |
mov edx,[current_slot] |
pushfd |
cli ;remove event from events |
mov ebx, [eax+APPOBJ.fd] ;list (reset event) |
mov ecx, [eax+APPOBJ.bk] ;and clear events flag |
mov [ebx+APPOBJ.bk], ecx ;if no active events |
mov [ecx+APPOBJ.fd], ebx |
dec [edx+APPDATA.ev_count] |
jnz @F |
and [edx+APPDATA.event_mask], not EVENT_EXTENDED |
@@: |
and [eax+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED) |
popfd |
test [eax+EVENT.state], MANUAL_DESTROY |
jz .destroy |
add edx, APP_OBJ_OFFSET |
pushfd |
cli |
mov ecx, [edx+APPOBJ.fd] ;insert event into |
mov [eax+APPOBJ.fd], ecx ;objects list |
mov [eax+APPOBJ.bk], edx |
mov [edx+APPOBJ.fd], eax |
mov [ecx+APPOBJ.bk], eax |
popfd |
.done: |
add esp, 4 |
ret |
.destroy: |
call destroy_event.force |
add esp, 4 |
ret |
.switch: |
or [eax+EVENT.state], EVENT_WATCHED |
mov eax, [TASK_BASE] |
mov [eax+TASKDATA.state], byte 5 |
call change_task |
mov eax, [.event] |
jmp .wait |
restore .event |
; param |
; eax= event |
; ebx= id |
; ecx= flags |
; edx= event data |
raise_event: |
.event equ esp |
push eax |
cmp [eax+APPOBJ.magic], 'EVNT' |
jne .fail |
cmp [eax+EVENT.id], ebx |
jne .fail |
mov eax, [eax+APPOBJ.pid] |
call pid_to_slot |
test eax, eax |
jz .fail |
mov esi, edx |
test esi, esi |
mov edx, [.event] |
jz @F |
push ecx |
lea edi, [edx+EVENT.code] |
mov ecx, 6 |
cld |
rep movsd |
pop ecx |
@@: |
test [edx+EVENT.state], EVENT_SIGNALED |
jnz .done |
test ecx, EVENT_WATCHED |
jz @F |
test [edx+EVENT.state], EVENT_WATCHED |
jz .done |
@@: |
shl eax, 8 |
add eax, SLOT_BASE+APP_EV_OFFSET |
pushfd |
cli |
mov ebx, [edx+APPOBJ.fd] |
mov ecx, [edx+APPOBJ.bk] |
mov [ebx+APPOBJ.bk], ecx |
mov [ecx+APPOBJ.fd], ebx |
mov ecx, [eax+APPOBJ.fd] |
mov [edx+APPOBJ.fd], ecx |
mov [edx+APPOBJ.bk], eax |
mov [eax+APPOBJ.fd], edx |
mov [ecx+APPOBJ.bk], edx |
or [edx+EVENT.state], EVENT_SIGNALED |
inc [eax+APPDATA.ev_count-APP_EV_OFFSET] |
or [eax+APPDATA.event_mask-APP_EV_OFFSET], EVENT_EXTENDED |
popfd |
.fail: |
.done: |
add esp, 4 |
ret |
restore .event |
; param |
; eax= event |
; ebx= id |
align 4 |
clear_event: |
.event equ esp |
push eax |
cmp [eax+APPOBJ.magic], 'EVNT' |
jne .fail |
cmp [eax+EVENT.id], ebx |
jne .fail |
mov eax, [eax+APPOBJ.pid] |
call pid_to_slot |
test eax, eax |
jz .fail |
shl eax, 8 |
add eax, SLOT_BASE+APP_EV_OFFSET |
mov edx, [.event] |
pushfd |
cli ;remove event from events |
mov ebx, [edx+APPOBJ.fd] ;list (reset event) |
mov ecx, [edx+APPOBJ.bk] ;and clear events flag |
mov [ebx+APPOBJ.bk], ecx ;if no active events |
mov [ecx+APPOBJ.fd], ebx |
and [edx+EVENT.state], not (EVENT_SIGNALED+EVENT_WATCHED) |
dec [eax+APPDATA.ev_count-APP_EV_OFFSET] |
jnz @F |
and [eax+APPDATA.event_mask-APP_EV_OFFSET], not EVENT_EXTENDED |
@@: |
add eax, (APP_OBJ_OFFSET-APP_EV_OFFSET) |
mov ecx, [eax+APPOBJ.fd] ;insert event into |
mov [edx+APPOBJ.fd], ecx ;objects list |
mov [edx+APPOBJ.bk], eax |
mov [eax+APPOBJ.fd], edx |
mov [ecx+APPOBJ.bk], edx |
popfd |
.fail: |
.done: |
add esp, 4 |
ret |
restore .event |
sys_getevent: |
call get_event_for_app |
mov [esp+36],eax |
ret |
sys_waitforevent: |
or eax, 0xFFFFFFFF ; infinite timeout |
jmp @f |
sys_wait_event_timeout: |
add eax, [timer_ticks] |
@@: |
mov ebx, [current_slot] |
mov [ebx + APPDATA.wait_timeout], eax |
call get_event_for_app |
test eax, eax |
jnz eventoccur |
mov eax, [TASK_BASE] |
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,[TASK_BASE] ; WINDOW REDRAW |
test [edi+TASKDATA.event_mask], 1 |
jz no_eventoccur1 |
;mov edi,[TASK_BASE] |
cmp [edi-twdw+WDATA.fl_redraw],byte 0 |
je no_eventoccur1 |
popad |
mov eax,1 |
ret |
no_eventoccur1: |
;mov edi,[TASK_BASE] ; KEY IN BUFFER |
test [edi+TASKDATA.event_mask],dword 2 |
jz no_eventoccur2 |
mov ecx, [CURRENT_TASK] |
movzx edx,word [WIN_STACK+ecx*2] |
mov eax, [TASK_COUNT] |
cmp eax,edx |
jne no_eventoccur2x |
cmp [KEY_COUNT],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,[TASK_BASE] ; BUTTON IN BUFFER |
test [edi+TASKDATA.event_mask],dword 4 |
jz no_eventoccur3 |
cmp [BTN_COUNT],byte 0 |
je no_eventoccur3 |
mov ecx, [CURRENT_TASK] |
movzx edx, word [WIN_STACK+ecx*2] |
mov eax, [TASK_COUNT] |
cmp eax,edx |
jnz no_eventoccur3 |
popad |
mov eax,[BTN_BUFF] |
cmp eax,65535 |
je no_event_1 |
mov eax,3 |
ret |
no_event_1: |
mov [window_minimize],1 |
mov [BTN_COUNT],byte 0 |
xor eax, eax |
ret |
no_eventoccur3: |
;mov edi,[TASK_BASE] ; mouse event |
mov eax, [CURRENT_TASK] |
shl eax, 8 |
add eax, SLOT_BASE |
test [edi+TASKDATA.event_mask],dword 00100000b |
jz no_mouse_event |
test [eax+APPDATA.event_mask],dword 00100000b |
jz no_mouse_event |
and [eax+APPDATA.event_mask],dword (not 00100000b) |
popad |
mov eax,6 |
ret |
no_mouse_event: |
;mov edi,[TASK_BASE] ; DESKTOP BACKGROUND REDRAW |
test [edi+TASKDATA.event_mask], 16 |
jz no_eventoccur5 |
; cmp [REDRAW_BACKGROUND],byte 2 |
; jnz no_eventoccur5 |
test [eax+APPDATA.event_mask], 16 |
jz no_eventoccur5 |
and [eax+APPDATA.event_mask], not 16 |
popad |
mov eax,5 |
ret |
no_eventoccur5: |
;mov edi,[TASK_BASE] ; IPC |
test [edi+TASKDATA.event_mask],dword 01000000b |
jz no_ipc |
test [eax+APPDATA.event_mask],dword 01000000b |
jz no_ipc |
and [eax+APPDATA.event_mask],dword 0xffffffff-01000000b |
popad |
mov eax,7 |
ret |
no_ipc: |
;mov edi,[TASK_BASE] ; STACK |
test [edi+TASKDATA.event_mask],dword 10000000b |
jz no_stack_event |
test [eax+APPDATA.event_mask],dword 10000000b |
jz no_stack_event |
and [eax+APPDATA.event_mask],dword 0xffffffff-10000000b |
popad |
mov eax,8 |
ret |
no_stack_event: |
test byte [edi+TASKDATA.event_mask+1], 1 ; DEBUG |
jz .test_IRQ |
test byte [eax+APPDATA.event_mask+1], byte 1 |
jz .test_IRQ |
and byte [eax+APPDATA.event_mask+1], not 1 |
popad |
mov eax, 9 |
ret |
;.test_ext: |
; mov eax, [CURRENT_TASK] |
; shl eax, 8 |
; test dword [eax+SLOT_BASE+APPDATA.event_mask], EVENT_EXTENDED |
; jz .test_IRQ |
; popad |
; mov eax, 10 |
; ret |
.test_IRQ: |
cmp dword [edi+TASKDATA.event_mask], 0xFFFF |
jbe no_events |
mov esi,IRQ_SAVE ; IRQ'S AND DATA |
mov ebx,0x00010000 |
xor ecx, ecx |
irq_event_test: |
mov edi,[TASK_BASE] |
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,[TASK_BASE] |
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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/gui/skindata.inc |
---|
0,0 → 1,62 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; |
; WINDOW SKIN DATA |
; |
iglobal |
_skin_file_default db '/sys/DEFAULT.SKN',0 |
endg |
struct SKIN_DATA |
.colors.inner dd ? |
.colors.outer dd ? |
.colors.frame dd ? |
.left.data dd ? |
.left.left dd ? |
.left.width dd ? |
.oper.data dd ? |
.oper.left dd ? |
.oper.width dd ? |
.base.data dd ? |
.base.left dd ? |
.base.width dd ? |
ends |
struct SKIN_BUTTON |
.left dd ? |
.top dd ? |
.width dd ? |
.height dd ? |
ends |
uglobal |
align 4 |
skin_udata: |
_skinh dd ? |
_skinmargins: ; rw 4 |
.right dw ? |
.left dw ? |
.bottom dw ? |
.top dw ? |
skin_btn_close SKIN_BUTTON |
skin_btn_minimize SKIN_BUTTON |
skin_active SKIN_DATA |
skin_inactive SKIN_DATA |
align 4 |
skin_udata.end: |
endg |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/gui/skincode.inc |
---|
0,0 → 1,465 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
include "skindata.inc" |
;skin_data = 0x00778000 |
read_skin_file: |
stdcall load_file, ebx |
test eax, eax |
jz .notfound |
cmp dword [eax], 'SKIN' |
jnz .noskin |
cmp ebx, 32*1024 |
jb @f |
mov ebx, 32*1024 |
@@: |
lea ecx, [ebx+3] |
shr ecx, 2 |
mov esi, eax |
mov edi, skin_data |
rep movsd |
stdcall kernel_free, eax |
call parse_skin_data |
xor eax, eax |
ret |
.notfound: |
xor eax, eax |
inc eax |
ret |
.noskin: |
stdcall kernel_free, eax |
push 2 |
pop eax |
ret |
struct SKIN_HEADER |
.ident dd ? |
.version dd ? |
.params dd ? |
.buttons dd ? |
.bitmaps dd ? |
ends |
struct SKIN_PARAMS |
.skin_height dd ? |
.margin.right dw ? |
.margin.left dw ? |
.margin.bottom dw ? |
.margin.top dw ? |
.colors.inner dd ? |
.colors.outer dd ? |
.colors.frame dd ? |
.colors_1.inner dd ? |
.colors_1.outer dd ? |
.colors_1.frame dd ? |
.dtp.size dd ? |
.dtp.data db 40 dup (?) |
ends |
struct SKIN_BUTTONS |
.type dd ? |
.pos: |
.left dw ? |
.top dw ? |
.size: |
.width dw ? |
.height dw ? |
ends |
struct SKIN_BITMAPS |
.kind dw ? |
.type dw ? |
.data dd ? |
ends |
load_default_skin: |
mov [_skinh],22 |
mov ebx,_skin_file_default |
call read_skin_file |
ret |
parse_skin_data: |
mov ebp,skin_data |
cmp [ebp+SKIN_HEADER.ident],'SKIN' |
jne .exit |
mov edi,skin_udata |
mov ecx,(skin_udata.end-skin_udata)/4 |
xor eax,eax |
cld |
rep stosd |
mov ebx,[ebp+SKIN_HEADER.params] |
add ebx,skin_data |
mov eax,[ebx+SKIN_PARAMS.skin_height] |
mov [_skinh],eax |
mov eax,[ebx+SKIN_PARAMS.colors.inner] |
mov [skin_active.colors.inner],eax |
mov eax,[ebx+SKIN_PARAMS.colors.outer] |
mov [skin_active.colors.outer],eax |
mov eax,[ebx+SKIN_PARAMS.colors.frame] |
mov [skin_active.colors.frame],eax |
mov eax,[ebx+SKIN_PARAMS.colors_1.inner] |
mov [skin_inactive.colors.inner],eax |
mov eax,[ebx+SKIN_PARAMS.colors_1.outer] |
mov [skin_inactive.colors.outer],eax |
mov eax,[ebx+SKIN_PARAMS.colors_1.frame] |
mov [skin_inactive.colors.frame],eax |
lea esi,[ebx+SKIN_PARAMS.dtp.data] |
mov edi,common_colours |
mov ecx,[ebx+SKIN_PARAMS.dtp.size] |
and ecx,127 |
rep movsb |
mov eax,dword[ebx+SKIN_PARAMS.margin.right] |
mov dword[_skinmargins+0],eax |
mov eax,dword[ebx+SKIN_PARAMS.margin.bottom] |
mov dword[_skinmargins+4],eax |
mov ebx,[ebp+SKIN_HEADER.bitmaps] |
add ebx,skin_data |
.lp1: cmp dword[ebx],0 |
je .end_bitmaps |
movzx eax,[ebx+SKIN_BITMAPS.kind] |
movzx ecx,[ebx+SKIN_BITMAPS.type] |
dec eax |
jnz .not_left |
xor eax,eax |
mov edx,skin_active.left.data |
or ecx,ecx |
jnz @f |
mov edx,skin_inactive.left.data |
@@: jmp .next_bitmap |
.not_left: |
dec eax |
jnz .not_oper |
mov esi,[ebx+SKIN_BITMAPS.data] |
add esi,skin_data |
mov eax,[esi+0] |
neg eax |
mov edx,skin_active.oper.data |
or ecx,ecx |
jnz @f |
mov edx,skin_inactive.oper.data |
@@: jmp .next_bitmap |
.not_oper: |
dec eax |
jnz .not_base |
mov eax,[skin_active.left.width] |
mov edx,skin_active.base.data |
or ecx,ecx |
jnz @f |
mov eax,[skin_inactive.left.width] |
mov edx,skin_inactive.base.data |
@@: jmp .next_bitmap |
.not_base: |
add ebx,8 |
jmp .lp1 |
.next_bitmap: |
mov ecx,[ebx+SKIN_BITMAPS.data] |
add ecx,skin_data |
mov [edx+4],eax |
mov eax,[ecx+0] |
mov [edx+8],eax |
add ecx,8 |
mov [edx+0],ecx |
add ebx,8 |
jmp .lp1 |
.end_bitmaps: |
mov ebx,[ebp+SKIN_HEADER.buttons] |
add ebx,skin_data |
.lp2: cmp dword[ebx],0 |
je .end_buttons |
mov eax,[ebx+SKIN_BUTTONS.type] |
dec eax |
jnz .not_close |
mov edx,skin_btn_close |
jmp .next_button |
.not_close: |
dec eax |
jnz .not_minimize |
mov edx,skin_btn_minimize |
jmp .next_button |
.not_minimize: |
add ebx,12 |
jmp .lp2 |
.next_button: |
movsx eax,[ebx+SKIN_BUTTONS.left] |
mov [edx+SKIN_BUTTON.left],eax |
movsx eax,[ebx+SKIN_BUTTONS.top] |
mov [edx+SKIN_BUTTON.top],eax |
movsx eax,[ebx+SKIN_BUTTONS.width] |
mov [edx+SKIN_BUTTON.width],eax |
movsx eax,[ebx+SKIN_BUTTONS.height] |
mov [edx+SKIN_BUTTON.height],eax |
add ebx,12 |
jmp .lp2 |
.end_buttons: |
.exit: |
ret |
sys_putimage_with_check: |
or ebx,ebx |
jz @f |
call sys_putimage.forced |
@@: ret |
drawwindow_IV_caption: |
mov ebp,skin_active |
or al,al |
jnz @f |
mov ebp,skin_inactive |
@@: |
mov esi,[esp+4] |
mov eax,[esi+WDATA.box.width] ; window width |
mov edx,[ebp+SKIN_DATA.left.left] |
shl edx,16 |
mov ecx,[ebp+SKIN_DATA.left.width] |
shl ecx,16 |
add ecx,[_skinh] |
mov ebx, [ebp+SKIN_DATA.left.data] |
call sys_putimage_with_check |
mov esi,[esp+4] |
mov eax,[esi+WDATA.box.width] |
sub eax,[ebp+SKIN_DATA.left.width] |
sub eax,[ebp+SKIN_DATA.oper.width] |
cmp eax,[ebp+SKIN_DATA.base.left] |
jng .non_base |
xor edx,edx |
mov ecx,[ebp+SKIN_DATA.base.width] |
jecxz .non_base |
div ecx |
inc eax |
mov ebx,[ebp+SKIN_DATA.base.data] |
mov ecx,[ebp+SKIN_DATA.base.width] |
shl ecx,16 |
add ecx,[_skinh] |
mov edx,[ebp+SKIN_DATA.base.left] |
sub edx,[ebp+SKIN_DATA.base.width] |
shl edx,16 |
.baseskinloop: |
shr edx,16 |
add edx,[ebp+SKIN_DATA.base.width] |
shl edx,16 |
push eax ebx ecx edx |
call sys_putimage_with_check |
pop edx ecx ebx eax |
dec eax |
jnz .baseskinloop |
.non_base: |
mov esi,[esp+4] |
mov edx,[esi+WDATA.box.width] |
sub edx,[ebp+SKIN_DATA.oper.width] |
inc edx |
shl edx,16 |
mov ebx,[ebp+SKIN_DATA.oper.data] |
mov ecx,[ebp+SKIN_DATA.oper.width] |
shl ecx,16 |
add ecx,[_skinh] |
call sys_putimage_with_check |
ret |
;//mike.dld, 2006-08-02 ] |
drawwindow_IV: |
;param1 - aw_yes |
pusha |
push edx |
mov edi,edx |
mov ebp,skin_active |
cmp byte [esp+32+4+4],0 |
jne @f |
mov ebp,skin_inactive |
@@: |
mov eax,[edi+WDATA.box.left] |
shl eax,16 |
mov ax,word [edi+WDATA.box.left] |
add ax,word [edi+WDATA.box.width] |
mov ebx,[edi+WDATA.box.top] |
shl ebx,16 |
mov bx,word [edi+WDATA.box.top] |
add bx,word [edi+WDATA.box.height] |
; mov esi,[edi+24] |
; shr esi,1 |
; and esi,0x007f7f7f |
mov esi,[ebp+SKIN_DATA.colors.outer] |
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] |
test edi,0x40000000 |
jnz _noinside2 |
call [drawbar] |
_noinside2: |
cmp dword[skin_data],'SKIN' |
jne no_skin_add_button |
;* close button |
mov edi,[BTN_ADDR] |
movzx eax,word [edi] |
cmp eax,1000 |
jge no_skin_add_button |
inc eax |
mov [edi],ax |
shl eax,4 |
add eax,edi |
mov bx,[CURRENT_TASK] |
mov [eax],bx |
add eax,2 ; save button id number |
mov bx,1 |
mov [eax],bx |
add eax,2 ; x start |
xor ebx,ebx |
cmp [skin_btn_close.left],0 |
jge _bCx_at_right |
mov ebx,[esp] |
mov ebx,[ebx+WDATA.box.width] |
inc ebx |
_bCx_at_right: |
add ebx,[skin_btn_close.left] |
mov [eax],bx |
add eax,2 ; x size |
mov ebx,[skin_btn_close.width] |
dec ebx |
mov [eax],bx |
add eax,2 ; y start |
mov ebx,[skin_btn_close.top] |
mov [eax],bx |
add eax,2 ; y size |
mov ebx,[skin_btn_close.height] |
dec ebx |
mov [eax],bx |
;* minimize button |
mov edi,[BTN_ADDR] |
movzx eax,word [edi] |
cmp eax,1000 |
jge no_skin_add_button |
inc eax |
mov [edi],ax |
shl eax,4 |
add eax,edi |
mov bx,[CURRENT_TASK] |
mov [eax],bx |
add eax,2 ; save button id number |
mov bx,65535 ;999 |
mov [eax],bx |
add eax,2 ; x start |
xor ebx,ebx |
cmp [skin_btn_minimize.left],0 |
jge _bMx_at_right |
mov ebx,[esp] |
mov ebx,[ebx+WDATA.box.width] |
inc ebx |
_bMx_at_right: |
add ebx,[skin_btn_minimize.left] |
mov [eax],bx |
add eax,2 ; x size |
mov ebx,[skin_btn_minimize.width] |
dec ebx |
mov [eax],bx |
add eax,2 ; y start |
mov ebx,[skin_btn_minimize.top] |
mov [eax],bx |
add eax,2 ; y size |
mov ebx,[skin_btn_minimize.height] |
dec ebx |
mov [eax],bx |
no_skin_add_button: |
pop edi |
and [edi+WDATA.fl_wdrawn], not 4 |
test [edi+WDATA.fl_wdrawn], 2 |
jz @f |
call drawwindowframes2 |
@@: |
popa |
ret 4 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/gui/window.inc |
---|
0,0 → 1,1770 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
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,WIN_STACK |
@@: |
inc eax |
add ecx,2 |
mov [ecx+0x000],ax ; process no |
mov [ecx+0x400],ax ; positions in stack |
cmp ecx,WIN_POS-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, [TASK_COUNT] ; number of processes |
cmp ebp, 1 |
jbe .finish |
align 4 |
.new_wnd: |
movzx edi, word [WIN_POS + esi * 2] |
shl edi, 5 |
cmp [CURRENT_TASK+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 [WIN_POS + 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+WIN_POS] |
shl edi, 8 |
add edi, SLOT_BASE ; 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, [ScreenWidth] ; 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, [ScreenWidth] |
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, [ScreenWidth] ; 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, [ScreenWidth] ; 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,[ScreenWidth] |
mov [dlxe],eax |
mov eax,[ScreenHeight] |
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,[TASK_BASE] |
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,[TASK_BASE] |
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;[ScreenWidth] |
jl @f |
mov [screen_workarea.left],eax |
@@: cmp ebx,[ScreenWidth] |
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,[ScreenHeight] |
jg .lp2 |
mov [screen_workarea.bottom],ebx |
.lp2: call repos_windows |
mov eax, 0 |
mov ebx, 0 |
mov ecx, [ScreenWidth] |
mov edx, [ScreenHeight] |
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 |
call read_skin_file |
mov [esp+32+36], eax |
test eax, eax |
jnz .ret |
xor eax, eax |
xor ebx, ebx |
mov ecx, [ScreenWidth] |
mov edx, [ScreenHeight] |
call calculatescreen |
jmp redraw_screen_direct |
.ret: |
popad |
ret |
no_set_skin: |
popad |
ret |
repos_windows: |
mov ecx,[TASK_COUNT] |
mov edi, OS_BASE+0x20*2 |
mov byte[REDRAW_BACKGROUND],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,[ScreenWidth] |
; 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 [edi+WDATA.box.left],ebx |
.lp4: mov eax,[edi+WDATA.box.top] |
add eax,[edi+WDATA.box.height] |
mov ebx,[ScreenHeight] |
; 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,[ScreenWidth] |
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,[ScreenHeight] |
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,[ScreenWidth] |
jbe x_size_ok |
mov ecx,[ScreenWidth] |
mov [edi+WDATA.box.width],ecx |
x_size_ok: |
mov esi,edx ; check y size |
add esi,ebx |
cmp esi,[ScreenHeight] |
jbe y_size_ok |
mov edx,[ScreenHeight] |
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 [MOUSE_BACKGROUND],byte 0 ; no mouse background |
mov [DONT_DRAW_MOUSE],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] |
test edi,0x40000000 |
jnz noinside |
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] |
test edi,0x40000000 |
jnz noinside2 |
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, [TASK_COUNT] |
movzx eax, word [WIN_POS + 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 [WIN_STACK+eax*2] ; ax <- position in window stack |
xor esi, esi ; drop others |
waloop: |
cmp esi, dword [TASK_COUNT] |
jae wacont |
inc esi |
lea edi, [WIN_STACK + 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, [TASK_COUNT] ; number of processes |
mov [WIN_STACK+eax*2], bx ; this is the last (and the upper) |
; update on screen -window stack |
xor esi, esi |
waloop2: |
mov edi, [TASK_COUNT] |
cmp esi, edi |
jae wacont2 |
inc esi |
movzx ebx, word [esi*2 + WIN_STACK] |
mov [ebx*2 + WIN_POS], si |
jmp waloop2 |
wacont2: |
mov [KEY_COUNT], byte 0 ; empty keyboard buffer |
mov [BTN_COUNT], byte 0 ; empty button buffer |
mov [MOUSE_SCROLL_H], word 0 ; zero mouse z-index |
mov [MOUSE_SCROLL_V], word 0 ; zero mouse z-index |
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 [WIN_STACK + esi * 2] ; get value of the curr process |
lea esi, [WIN_POS + eax * 2] ; get address of this process at 0xC400 |
push esi |
.new_check: |
pop esi |
add esi, 2 |
push esi |
mov eax, [TASK_COUNT] |
lea eax, word [WIN_POS + eax * 2] ; number of the upper window |
cmp esi, eax |
ja .all_wnds_to_top |
movzx eax, word [esi] |
shl eax, 5 |
cmp [CURRENT_TASK + 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 [MOUSE_DOWN], byte 1 ; do draw mouse |
call windowactivate |
; update screen info |
pushad |
mov edi, [TASK_COUNT] ; the last process (number) |
movzx esi, word [WIN_POS + 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, [TASK_COUNT] |
movzx esi, word [WIN_POS + edi * 2] |
call setscreen |
popad |
mov [edi + WDATA.fl_redraw], 1 ; redraw flag for app |
mov [MOUSE_DOWN],byte 0 ; mouse down checks |
ret |
.do_not_draw: |
popad |
call windowactivate |
mov [MOUSE_DOWN],byte 0 ; mouse down checks |
mov [MOUSE_BACKGROUND],byte 0 ; no mouse background |
mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse |
ret |
; eax = window number on screen |
; corrupts registers and [dl*] |
minimize_window: |
movzx eax, word [WIN_POS+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 [WIN_POS+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, [TASK_COUNT] ; 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 [MOUSE_BACKGROUND],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, [TASK_COUNT] ; 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 [BTN_DOWN],byte 0 ; mouse buttons pressed ? |
jne .mouse_buttons_pressed |
;..................................... start 1/4 : modified by vhanla ................. |
mov [bPressedMouseXY_W],0 |
;..................................... end 1/4 : modified by vhanla ................... |
popad |
ret |
.mouse_buttons_pressed: |
;..................................... start 2/4 : modified by vhanla ................. |
jmp @f |
bPressedMouseXY_W db 0x0 |
@@: |
;..................................... end 2/4 : modified by vhanla ................... |
mov esi,[TASK_COUNT] |
inc esi |
;..................................... start 3/4 : modified by vhanla ................. |
push ax |
cmp [bPressedMouseXY_W],0 |
jnz @f |
mov [bPressedMouseXY_W],1 |
mov ax,[MOUSE_X] |
mov [mx],ax |
mov ax,[MOUSE_Y] |
mov [my],ax |
@@: |
pop ax |
;..................................... end 3/4 : modified by vhanla ................... |
cwloop: |
cmp esi,2 |
jb .exit |
dec esi |
movzx edi, word [WIN_POS + 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 |
;..................................... start 4/4 : modified by vhanla ................. |
movzx eax, word [mx]; movzx eax,word[MOUSE_X] |
movzx ebx, word [my]; movzx ebx,word[MOUSE_Y] |
;..................................... endt 4/4 : modified by vhanla .................. |
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, [TASK_COUNT] |
cmp eax, ebx ; is this window active? |
jz .move_resize_window |
; eax = position in windowing stack |
; redraw must ? |
lea esi, [WIN_POS + 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, [BTN_DOWN] ; 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, [MOUSE_X] |
mov [WIN_TEMP_XY], 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 [MOUSE_DOWN],byte 1 ; no reaction to mouse up/down |
; move window |
newchm: |
mov [DONT_DRAW_MOUSE],byte 1 |
call checkidle |
call checkVga_N13 |
mov [MOUSE_BACKGROUND],byte 0 |
call [draw_pointer] |
pushad |
call stack_handler |
popad |
mov esi,[WIN_TEMP_XY] |
cmp esi,[MOUSE_X] |
je cwb |
mov cx,[MOUSE_X] |
mov dx,[MOUSE_Y] |
sub cx,ax |
sub dx,bx |
push ax |
push bx |
call drawwindowframes |
mov ax,[ScreenWidth] |
mov bx,[ScreenHeight] |
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, [SLOT_BASE + edx*8] |
movzx eax,word [MOUSE_X] |
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 [MOUSE_Y] |
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,[MOUSE_X] |
mov [WIN_TEMP_XY],esi |
cwb: |
cmp [BTN_DOWN],byte 0 |
jne newchm |
; new position done |
mov [DONT_DRAW_MOUSE],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,SLOT_BASE+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,SLOT_BASE ; 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,[ScreenHeight] |
jbe no_window_sizing |
mov eax,[edi+WDATA.box.left] ; check X inside screen |
add eax,[edi+WDATA.box.width] |
cmp eax,[ScreenWidth] |
jbe no_window_sizing |
mov eax,[ScreenWidth] |
sub eax,[edi+WDATA.box.width] |
mov [edi+WDATA.box.left],eax |
mov eax,[ScreenHeight] |
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 [DONT_DRAW_MOUSE],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 [DONT_DRAW_MOUSE],byte 1 |
call checkidle |
cmp [edi+WDATA.fl_redraw],0 |
jz retwm |
loop waitre2 |
retwm: |
mov [DONT_DRAW_MOUSE],byte 0 ; mouse pointer |
mov [MOUSE_BACKGROUND],byte 0 ; no mouse under |
mov [MOUSE_DOWN],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,[current_slot] |
mov [eax+APPDATA.wnd_shape],ebx |
rsw_no_address: |
cmp eax,1 |
jne rsw_no_scale |
mov eax,[current_slot] |
mov byte [eax+APPDATA.wnd_shape_scale], bl |
rsw_no_scale: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/gui/button.inc |
---|
0,0 → 1,673 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
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,[TASK_BASE] |
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,[current_slot] |
rol eax,16 |
add ax,word[edi+APPDATA.wnd_clientbox.left] |
rol eax,16 |
rol ebx,16 |
add bx,word[edi+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,[TASK_BASE] |
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,[BTN_ADDR] |
movzx eax,word [edi] |
cmp eax,max_buttons |
jge noaddbutt |
inc eax |
mov [edi],ax |
shl eax,4 |
add eax,edi |
mov bx,[CURRENT_TASK] |
mov [eax],bx |
add eax,2 ; save button id number |
mov 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,[BTN_ADDR] |
mov eax,edi |
movzx ebx,word [edi] |
inc bx |
rnewba: |
dec bx |
jz rnmba |
add eax,0x10 |
mov dx,[CURRENT_TASK] |
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 [BTN_DOWN],byte 0 ; mouse buttons pressed |
jnz @f |
;..................................... start 1/5 : modified by vhanla ............................. |
mov [bPressedMouseXY_B],0 |
;..................................... end 1/5 : modified by vhanla ............................. |
ret |
@@: |
pushad |
xor esi, esi |
mov edi, [BTN_ADDR] |
movzx edx, word [edi] |
test edx, edx |
jne @f |
popad |
ret |
@@: |
;..................................... start 2/5 : modified by vhanla ............................. |
;here i catch the coordinates when the mouse's button is clicked |
push ax |
cmp [bPressedMouseXY_B],0;FALSE |
jnz @f |
mov [bPressedMouseXY_B],1;TRUE - it was already clicked |
mov ax,[MOUSE_X] |
mov [mx],ax |
mov ax,[MOUSE_Y] |
mov [my],ax |
@@: |
pop ax |
;and it is only refreshed after the mouse's button release |
;..................................... end 2/5 : modified by vhanla ............................. |
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 |
; check that button is at top of windowing stack |
movzx ebx,word [eax] |
movzx ecx,word [WIN_STACK + ebx * 2] |
cmp ecx,[TASK_COUNT] |
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 |
;..................................... start 3/5 : modified by vhanla ............................. |
mov cx,[mx] ;mov cx,[MOUSE_X] |
;..................................... end 3/5 : modified by vhanla ............................. |
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 |
;..................................... start 4/5 : modified by vhanla ............................. |
mov cx,[my] ;mov cx,[MOUSE_Y] |
;..................................... start 4/5 : modified by vhanla ............................. |
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 [MOUSE_DOWN],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 [BTN_DOWN],byte 0 ; mouse buttons pressed ? |
jnz cbwaitmouseup |
popad |
call negativebutton |
mov [MOUSE_BACKGROUND],byte 0 ; no mouse background |
mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse |
;..................................... start 5/5 : modified by vhanla ............................. |
; check coordinates |
jmp @f |
mx dw 0x0 ; keeps the x mouse's position when it was clicked |
my dw 0x0 ; keeps the y mouse's position when it was clicked |
bPressedMouseXY_B db 0x0 |
@@: |
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,[MOUSE_X] |
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,[MOUSE_Y] |
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 [BTN_COUNT],byte 1 ; no of buttons in buffer |
pop ebx |
mov [BTN_BUFF],ebx ; lets put the button id in buffer |
push ebx |
pusha |
jmp yes_on_button |
no_on_button: |
mov [BTN_COUNT],byte 0 ; no of buttons in buffer |
yes_on_button: |
mov [MOUSE_DOWN],byte 0 ; mouse down -> do not draw |
popa |
pop ebx |
popa |
ret |
;..................................... end 5/5 : modified by vhanla ................................ |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/gui/font.inc |
---|
0,0 → 1,115 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
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, [FONT_I+8*edx+edx] |
.symloop1: |
mov dl, byte [ebp] |
or dl, 1 shl 6 |
.pixloop1: |
shr dl, 1 |
jz .pixloop1end |
jnc .nopix |
call [putpixel] |
jmp .pixloop1cont |
.nopix: |
test ecx, 0x40000000 |
jz .pixloop1cont |
push ecx |
mov ecx, [esp+4+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, [FONT_II+4*edx+edx+1] |
push 9 |
movzx esi, byte [ebp-1] |
.symloop2: |
mov dl, byte [ebp] |
push esi |
.pixloop2: |
shr dl, 1 |
jnc .nopix2 |
call [putpixel] |
jmp .pixloop2cont |
.nopix2: |
test ecx, 0x40000000 |
jz .pixloop2cont |
push ecx |
mov ecx, [esp+12+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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/gui/mouse.inc |
---|
0,0 → 1,248 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
align 4 |
mousepointer: |
db 0x00,0x00,0x00,0x74,0x74,0x74,0x6e,0x6e,0x6e,0x6f |
db 0x6f,0x6f,0x71,0x71,0x71,0x75,0x75,0x75,0x79,0x79 |
db 0x79,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63 |
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78 |
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0 |
db 0xc0,0xc0,0x00,0x00,0x00,0x54,0x54,0x54,0x57,0x57 |
db 0x57,0x5f,0x5f,0x5f,0x68,0x68,0x68,0x71,0x71,0x71 |
db 0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x47,0x47,0x47,0x50 |
db 0x50,0x50,0x5b,0x5b,0x5b,0x67,0x67,0x67,0x70,0x70 |
db 0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3f,0x3f,0x3f |
db 0x4b,0x4b,0x4b,0x59,0x59,0x59,0x66,0x66,0x66,0x70 |
db 0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e,0x7e |
db 0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x3a,0x3a |
db 0x3a,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66,0x66 |
db 0x70,0x70,0x70,0x77,0x77,0x77,0x7c,0x7c,0x7c,0x7e |
db 0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x39 |
db 0x39,0x39,0x49,0x49,0x49,0x59,0x59,0x59,0x66,0x66 |
db 0x66,0x71,0x71,0x71,0x78,0x78,0x78,0x7c,0x7c,0x7c |
db 0x7e,0x7e,0x7e,0x80,0x80,0x80,0x80,0x80,0x80,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00 |
db 0x39,0x39,0x39,0x4a,0x4a,0x4a,0x5a,0x5a,0x5a,0x68 |
db 0x68,0x68,0x72,0x72,0x72,0x79,0x79,0x79,0x7d,0x7d |
db 0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00 |
db 0x00,0x3c,0x3c,0x3c,0x4e,0x4e,0x4e,0x5e,0x5e,0x5e |
db 0x6b,0x6b,0x6b,0x75,0x75,0x75,0x7a,0x7a,0x7a,0x7e |
db 0x7e,0x7e,0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00 |
db 0x00,0x00,0x43,0x43,0x43,0x55,0x55,0x55,0x64,0x64 |
db 0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d |
db 0x80,0x80,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xc0 |
db 0xc0,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x4e,0x4e,0x4e,0x5f,0x5f,0x5f,0x6d |
db 0x6d,0x6d,0x76,0x76,0x76,0x7c,0x7c,0x7c,0x80,0x80 |
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x14 |
db 0x14,0x14,0x1b,0x1b,0x1b,0x29,0x29,0x29,0x3a,0x3a |
db 0x3a,0x4c,0x4c,0x4c,0x5d,0x5d,0x5d,0x6c,0x6c,0x6c |
db 0x75,0x75,0x75,0x7b,0x7b,0x7b,0x80,0x80,0x80,0xc0 |
db 0xc0,0xc0,0x00,0x00,0x00,0x2f,0x2f,0x2f,0x80,0x80 |
db 0x80,0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00 |
db 0x21,0x21,0x21,0x2e,0x2e,0x2e,0x40,0x40,0x40,0x52 |
db 0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f,0x77,0x77 |
db 0x77,0x7c,0x7c,0x7c,0x80,0x80,0x80,0x00,0x00,0x00 |
db 0x47,0x47,0x47,0x3b,0x3b,0x3b,0x80,0x80,0x80,0xff |
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x25,0x25 |
db 0x25,0x30,0x30,0x30,0x42,0x42,0x42,0x54,0x54,0x54 |
db 0x64,0x64,0x64,0x70,0x70,0x70,0x78,0x78,0x78,0x7d |
db 0x7d,0x7d,0x00,0x00,0x00,0x62,0x62,0x62,0x52,0x52 |
db 0x52,0x4a,0x4a,0x4a,0x43,0x43,0x43,0x80,0x80,0x80 |
db 0xff,0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x33 |
db 0x33,0x33,0x42,0x42,0x42,0x54,0x54,0x54,0x64,0x64 |
db 0x64,0x71,0x71,0x71,0x79,0x79,0x79,0x7d,0x7d,0x7d |
db 0x72,0x72,0x72,0x6b,0x6b,0x6b,0x5f,0x5f,0x5f,0x5a |
db 0x5a,0x5a,0x54,0x54,0x54,0x80,0x80,0x80,0xff,0xff |
db 0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x35,0x35,0x35 |
db 0x41,0x41,0x41,0x53,0x53,0x53,0x63,0x63,0x63,0x70 |
db 0x70,0x70,0x78,0x78,0x78,0x7d,0x7d,0x7d,0x77,0x77 |
db 0x77,0x73,0x73,0x73,0x6c,0x6c,0x6c,0x68,0x68,0x68 |
db 0x62,0x62,0x62,0x5a,0x5a,0x5a,0x80,0x80,0x80,0xff |
db 0xff,0xff,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x41,0x41 |
db 0x41,0x52,0x52,0x52,0x62,0x62,0x62,0x6f,0x6f,0x6f |
db 0x78,0x78,0x78,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x79 |
db 0x79,0x79,0x74,0x74,0x74,0x72,0x72,0x72,0x6e,0x6e |
db 0x6e,0x66,0x66,0x66,0x80,0x80,0x80,0xc0,0xc0,0xc0 |
db 0xc0,0xc0,0xc0,0x00,0x00,0x00,0x44,0x44,0x44,0x52 |
db 0x52,0x52,0x62,0x62,0x62,0x6e,0x6e,0x6e,0x77,0x77 |
db 0x77,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7c,0x7c,0x7c |
db 0x7a,0x7a,0x7a,0x79,0x79,0x79,0x75,0x75,0x75,0x6f |
db 0x6f,0x6f,0x65,0x65,0x65,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x48,0x48,0x48,0x4b,0x4b,0x4b,0x56,0x56,0x56 |
db 0x65,0x65,0x65,0x70,0x70,0x70,0x78,0x78,0x78,0x7d |
db 0x7d,0x7d,0x80,0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e |
db 0x7e,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76,0x76 |
db 0x6f,0x6f,0x6f,0x65,0x65,0x65,0x5c,0x5c,0x5c,0x56 |
db 0x56,0x56,0x58,0x58,0x58,0x60,0x60,0x60,0x6b,0x6b |
db 0x6b,0x73,0x73,0x73,0x7a,0x7a,0x7a,0x7d,0x7d,0x7d |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7f |
db 0x7f,0x7f,0x7d,0x7d,0x7d,0x7a,0x7a,0x7a,0x76,0x76 |
db 0x76,0x70,0x70,0x70,0x6a,0x6a,0x6a,0x66,0x66,0x66 |
db 0x66,0x66,0x66,0x6c,0x6c,0x6c,0x72,0x72,0x72,0x78 |
db 0x78,0x78,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7b,0x7b,0x7b,0x77 |
db 0x77,0x77,0x73,0x73,0x73,0x71,0x71,0x71,0x71,0x71 |
db 0x71,0x74,0x74,0x74,0x78,0x78,0x78,0x7b,0x7b,0x7b |
db 0x7d,0x7d,0x7d,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x7f,0x7f,0x7f,0x7d,0x7d,0x7d,0x7c,0x7c,0x7c |
db 0x7a,0x7a,0x7a,0x78,0x78,0x78,0x78,0x78,0x78,0x7a |
db 0x7a,0x7a,0x7c,0x7c,0x7c,0x7e,0x7e,0x7e,0x7f,0x7f |
db 0x7f,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 |
db 0x80,0x80,0x7f,0x7f,0x7f,0x7e,0x7e,0x7e,0x7e,0x7e |
db 0x7e,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e |
db 0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,0x80 |
db 0x80,0x80 |
mousepointer1: |
db 0xff,0xff,0xff,0x06,0x06,0x06,0x0a,0x0a |
db 0x0a,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xff,0xff,0xff,0x19,0x19,0x19,0x16 |
db 0x16,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2e,0x2e,0x2e |
db 0x23,0x23,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x3f |
db 0x3f,0x29,0x29,0x29,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47 |
db 0x47,0x47,0x2c,0x2c,0x2c,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x16,0x16,0x16 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0x48,0x48,0x48,0x2c,0x2c,0x2c,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0x47,0x47,0x47,0x29,0x29,0x29 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0x40,0x40,0x40,0x23,0x23 |
db 0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xaa,0xaa,0xaa,0x9f,0x9f,0x9f,0x8c,0x8c,0x8c |
db 0x70,0x70,0x70,0x4f,0x4f,0x4f,0x30,0x30,0x30,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8f,0x8f,0x8f |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0xff,0x9c,0x9c,0x9c,0x87,0x87,0x87,0x6c,0x6c |
db 0x6c,0x4f,0x4f,0x4f,0x32,0x32,0x32,0x19,0x19,0x19 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff |
db 0xff,0xff,0x69,0x69,0x69,0x84,0x84,0x84,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0x92,0x92,0x92,0x79,0x79,0x79,0x59,0x59,0x59,0x3c |
db 0x3c,0x3c,0x24,0x24,0x24,0x11,0x11,0x11,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x37,0x37,0x37 |
db 0x5d,0x5d,0x5d,0x70,0x70,0x70,0x76,0x76,0x76,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0xff,0x75,0x75,0x75,0x51,0x51,0x51,0x31,0x31,0x31 |
db 0x19,0x19,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x16,0x16,0x16,0x2d,0x2d,0x2d,0x49,0x49 |
db 0x49,0x53,0x53,0x53,0x54,0x54,0x54,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x78 |
db 0x78,0x78,0x54,0x54,0x54,0x30,0x30,0x30,0x16,0x16 |
db 0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x0f,0x0f,0x0f,0x1f,0x1f,0x1f,0x30,0x30,0x30,0x33 |
db 0x33,0x33,0x33,0x33,0x33,0x3b,0x3b,0x3b,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff |
db 0x62,0x62,0x62,0x3b,0x3b,0x3b,0x1c,0x1c,0x1c,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08 |
db 0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x24,0x24,0x24,0xff,0xff,0xff,0xff |
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6e,0x6e |
db 0x6e,0x48,0x48,0x48,0x25,0x25,0x25,0x0e,0x0e,0x0e |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00 |
db 0x00,0x00,0x0a,0x0a,0x0a,0x09,0x09,0x09,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x29,0x29,0x29,0xff,0xff,0xff |
db 0xff,0xff,0xff,0x7c,0x7c,0x7c,0x71,0x71,0x71,0x50 |
db 0x50,0x50,0x2b,0x2b,0x2b,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x02,0x02,0x02,0x04,0x04,0x04,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x36,0x36,0x36,0x56,0x56 |
db 0x56,0x69,0x69,0x69,0x64,0x64,0x64,0x4a,0x4a,0x4a |
db 0x28,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x05,0x05,0x05 |
db 0x00,0x00,0x00,0x21,0x21,0x21,0x39,0x39,0x39,0x49 |
db 0x49,0x49,0x48,0x48,0x48,0x35,0x35,0x35,0x1d,0x1d |
db 0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x1d,0x1d,0x1d,0x27,0x27,0x27 |
db 0x27,0x27,0x27,0x1d,0x1d,0x1d,0x0f,0x0f,0x0f,0x06 |
db 0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 |
db 0x00,0x00,0x00,0x00 |
endg |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/kernel32.inc |
---|
0,0 → 1,261 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; KERNEL32.INC ;; |
;; ;; |
;; Included 32 bit kernel files for MenuetOS ;; |
;; ;; |
;; This file is kept separate as it will be easier to ;; |
;; maintain and compile with an automated SETUP program ;; |
;; in the future. ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;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 |
.ev_count dd ? ;+20 |
.fpu_handler dd ? ;+24 |
.sse_handler dd ? ;+28 |
.pl0_stack dd ? ;unused ;+32 |
.heap_base dd ? ;+36 |
.heap_top dd ? ;+40 |
.cursor dd ? ;+44 |
.fd_ev dd ? ;+48 |
.bk_ev dd ? ;+52 |
.fd_obj dd ? ;+56 |
.bk_obj dd ? ;+60 |
.saved_esp dd ? ;+64 |
.io_map rd 2 ;+68 |
.dbg_state dd ? ;+76 |
.cur_dir dd ? ;+80 |
.wait_timeout dd ? ;+84 |
db 40 dup(?) ;+88 |
.wnd_shape dd ? ;+128 |
.wnd_shape_scale dd ? ;+132 |
dd ? ;+136 |
.mem_size dd ? ;+140 |
.saved_box BOX |
.ipc_start dd ? |
.ipc_size dd ? |
.event_mask dd ? |
.debugger_slot dd ? |
dd ? |
.keyboard_mode db ? |
db 3 dup(?) |
.dir_table dd ? |
.dbg_event_mem dd ? |
.dbg_regs: |
.dbg_regs.dr0 dd ? |
.dbg_regs.dr1 dd ? |
.dbg_regs.dr2 dd ? |
.dbg_regs.dr3 dd ? |
.dbg_regs.dr7 dd ? |
.wnd_caption dd ? |
.wnd_clientbox BOX |
} |
virtual at 0 |
APPDATA APPDATA |
end virtual |
;// mike.dld, 2006-29-01 ] |
; Core functions |
include "core/sync.inc" ; macros for synhronization objects |
include "core/sys32.inc" ; process management |
include "core/sched.inc" ; process scheduling |
include "core/syscall.inc" ; system call |
include "core/fpu.inc" ; all fpu/sse support |
include "core/memory.inc" |
include "core/heap.inc" ; kernel and app heap |
include "core/malloc.inc" ; small kernel heap |
include "core/taskman.inc" |
include "core/dll.inc" |
include "core/exports.inc" |
include "core/string.inc" |
; GUI stuff |
include "gui/window.inc" |
include "gui/event.inc" |
include "gui/font.inc" |
include "gui/button.inc" |
; shutdown |
; file system |
include "fs/fs.inc" ; syscall |
include "fs/fat32.inc" ; read / write for fat32 filesystem |
include "fs/ntfs.inc" ; read / write for ntfs filesystem |
include "fs/fat12.inc" ; read / write for fat12 filesystem |
include "blkdev/rd.inc" ; ramdisk read /write |
include "fs/fs_lfn.inc" ; syscall, version 2 |
include "fs/iso9660.inc" ; read for iso9660 filesystem CD |
; 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 |
include "video/cursors.inc" ; cursors functions |
; Network Interface & TCPIP Stack |
include "network/stack.inc" |
;include "drivers/uart.inc" |
; Mouse pointer |
include "gui/mouse.inc" |
; Window skinning |
include "gui/skincode.inc" |
; Pci functions |
include "bus/pci/pci32.inc" |
; Floppy drive controller |
include "blkdev/fdc.inc" |
include "blkdev/flp_drv.inc" |
; HD drive controller |
include "blkdev/hd_drv.inc" |
; CD drive controller |
include "blkdev/cdrom.inc" |
include "blkdev/cd_drv.inc" |
; Character devices |
include "hid/keyboard.inc" |
include "hid/mousedrv.inc" |
; setting date,time,clock and alarm-clock |
include "hid/set_dtc.inc" |
;% -include |
;parser file names |
include "fs/parse_fn.inc" |
; work with conf lib |
include "core/conf_lib.inc" |
; load external lib |
include "core/ext_lib.inc" |
; list of external functions |
include "imports.inc" |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/imports.inc |
---|
0,0 → 1,18 |
$Revision$ |
;============================================================================ |
; |
; External kernel dependencies |
; |
;============================================================================ |
align 4 |
@IMPORT: |
library \ |
libini,'libini.obj' |
import libini, \ |
lib_init,'lib_init',\ |
ini.get_str,'ini.get_str',\ |
ini.enum_keys,'ini.enum_keys',\ |
ini.get_int,'ini.get_int' |
Property changes: |
Added: svn:keywords |
+Revision |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/build.bat |
---|
0,0 → 1,105 |
@echo off |
set languages=en ru ge et |
set drivers=sound sis infinity ati2d vmode ps2mouse |
set targets=all kernel drivers skins clean |
call :Check_Target %1 |
for %%a in (all kernel) do if %%a==%target% call :Check_Lang %2 |
call :Target_%target% |
if ERRORLEVEL 0 goto Exit_OK |
echo There was an error executing script. |
echo For any help, please send a report. |
pause |
goto :eof |
:Check_Lang |
set res=%1 |
:Check_Lang_loop |
for %%a in (%languages%) do if %%a==%res% set lang=%res% |
if defined lang goto :eof |
echo Language '%res%' is incorrect |
echo Enter valid language [ %languages% ]: |
set /P res="> |
goto Check_Lang_loop |
goto :eof |
:Check_Target |
set res=%1 |
:Check_Target_loop |
for %%a in (%targets%) do if %%a==%res% set target=%res% |
if defined target goto :eof |
echo Target '%res%' is incorrect |
echo Enter valid target [ %targets% ]: |
set /P res="> |
goto Check_Target_loop |
goto :eof |
:Target_kernel |
echo *** building kernel with language '%lang%' ... |
if not exist bin mkdir bin |
echo lang fix %lang% > lang.inc |
fasm -m 65536 kernel.asm bin\kernel.mnt |
if not %errorlevel%==0 goto :Error_FasmFailed |
erase lang.inc |
goto :eof |
:Target_all |
call :Target_kernel |
call :Target_drivers |
call :Target_skins |
goto :eof |
:Target_drivers |
echo *** building drivers ... |
if not exist bin\drivers mkdir bin\drivers |
cd drivers |
for %%a in (%drivers%) do ( |
fasm -m 65536 %%a.asm ..\bin\drivers\%%a.obj |
if not %errorlevel%==0 goto :Error_FasmFailed |
) |
cd .. |
move bin\drivers\vmode.obj bin\drivers\vmode.mdr |
goto :eof |
:Target_skins |
echo *** building skins ... |
if not exist bin\skins mkdir bin\skins |
cd skin |
fasm -m 65536 default.asm ..\bin\skins\default.skn |
if not %errorlevel%==0 goto :Error_FasmFailed |
cd .. |
goto :eof |
:Target_clean |
echo *** cleaning ... |
rmdir /S /Q bin |
goto :Exit_OK |
:Error_FasmFailed |
echo error: fasm execution failed |
erase lang.inc |
pause |
exit 1 |
:Exit_OK |
echo all operations has been done |
pause |
exit 0 |
/kernel/tags/kolibri0.7.0.0/blkdev/rd.inc |
---|
0,0 → 1,2420 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; RAMDISK functions ;; |
;; (C) 2004 Ville Turjanmaa, License: GPL ;; |
;; Addings by M.Lisovin ;; |
;; LFN support by diamond ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; calculate fat chain |
calculatefatchain: |
pushad |
mov esi,RAMDISK+512 |
mov edi,RAMDISK_FAT |
fcnew: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
mov ecx,dword [esi+8] |
mov edx,ecx |
shr edx,4 ;8 ok |
shr dx,4 ;7 ok |
xor ch,ch |
shld ecx,ebx,20 ;6 ok |
shr cx,4 ;5 ok |
shld ebx,eax,12 |
and ebx,0x0fffffff ;4 ok |
shr bx,4 ;3 ok |
shl eax,4 |
and eax,0x0fffffff ;2 ok |
shr ax,4 ;1 ok |
mov dword [edi],eax |
mov dword [edi+4],ebx |
mov dword [edi+8],ecx |
mov dword [edi+12],edx |
add edi,16 |
add esi,12 |
cmp edi,RAMDISK_FAT+2856*2 ;2849 clusters |
jnz fcnew |
popad |
ret |
restorefatchain: ; restore fat chain |
pushad |
mov esi,RAMDISK_FAT |
mov edi,RAMDISK+512 |
fcnew2: |
mov eax,dword [esi] |
mov ebx,dword [esi+4] |
shl ax,4 |
shl eax,4 |
shl bx,4 |
shr ebx,4 |
shrd eax,ebx,8 |
shr ebx,8 |
mov dword [edi],eax |
mov word [edi+4],bx |
add edi,6 |
add esi,8 |
cmp edi,RAMDISK+512+4278 ;4274 bytes - all used FAT |
jb fcnew2 |
mov esi,RAMDISK+512 ; duplicate fat chain |
mov edi,RAMDISK+512+0x1200 |
mov ecx,1069 ;4274/4 |
cld |
rep movsd |
popad |
ret |
ramdisk_free_space: |
;--------------------------------------------- |
; |
; returns free space in edi |
; rewr.by Mihasik |
;--------------------------------------------- |
push eax ebx ecx |
mov edi,RAMDISK_FAT ;start of FAT |
xor ax,ax ;Free cluster=0x0000 in FAT |
xor ebx,ebx ;counter |
mov ecx,2849 ;2849 clusters |
cld |
rdfs1: |
repne scasw |
jnz rdfs2 ;if last cluster not 0 |
inc ebx |
test ecx, ecx |
jnz rdfs1 |
rdfs2: |
shl ebx,9 ;free clusters*512 |
mov edi,ebx |
pop ecx ebx eax |
ret |
expand_filename: |
;--------------------------------------------- |
; |
; exapand filename with '.' to 11 character |
; eax - pointer to filename |
;--------------------------------------------- |
push esi edi ebx |
mov edi,esp ; check for '.' in the name |
add edi,12+8 |
mov esi,eax |
mov eax,edi |
mov [eax+0],dword ' ' |
mov [eax+4],dword ' ' |
mov [eax+8],dword ' ' |
flr1: |
cmp [esi],byte '.' |
jne flr2 |
mov edi,eax |
add edi,7 |
jmp flr3 |
flr2: |
mov bl,[esi] |
mov [edi],bl |
flr3: |
inc esi |
inc edi |
mov ebx,eax |
add ebx,11 |
cmp edi,ebx |
jbe flr1 |
pop ebx edi esi |
ret |
fileread: |
;---------------------------------------------------------------- |
; |
; fileread - sys floppy |
; |
; eax points to filename 11 chars |
; ebx first wanted block ; 1+ ; if 0 then set to 1 |
; ecx number of blocks to read ; 1+ ; if 0 then set to 1 |
; edx mem location to return data |
; esi length of filename 12*X 0=root |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
test ebx,ebx ;if ebx=0 - set to 1 |
jnz frfl5 |
inc ebx |
frfl5: |
test ecx,ecx ;if ecx=0 - set to 1 |
jnz frfl6 |
inc ecx |
frfl6: |
test esi,esi ; return ramdisk root |
jnz fr_noroot ;if not root |
cmp ebx,14 ;14 clusters=root dir |
ja oorr |
cmp ecx,14 |
ja oorr |
jmp fr_do |
oorr: |
mov eax,5 ;out of root range (fnf) |
xor ebx,ebx |
dec ebx ;0xffffffff |
ret |
fr_do: ;reading rootdir |
mov edi,edx |
dec ebx |
push edx |
mov edx,ecx |
add edx,ebx |
cmp edx,15 ;ebx+ecx=14+1 |
pushf |
jbe fr_do1 |
sub edx,14 |
sub ecx,edx |
fr_do1: |
shl ebx,9 |
mov esi,RAMDISK+512*19 |
add esi,ebx |
shl ecx,7 |
cld |
rep movsd |
popf |
pop edx |
jae fr_do2 |
xor eax,eax ; ok read |
xor ebx,ebx |
ret |
fr_do2: ;if last cluster |
mov eax,6 ;end of file |
xor ebx,ebx |
ret |
fr_noroot: |
sub esp,32 |
call expand_filename |
dec ebx |
push eax |
push eax ebx ecx edx esi edi |
call rd_findfile |
je fifound |
add esp,32+28 ;if file not found |
ret |
fifound: |
mov ebx,[edi-11+28] ;file size |
mov [esp+20],ebx |
mov [esp+24],ebx |
add edi,0xf |
movzx eax,word [edi] |
mov edi,eax ;edi=cluster |
frnew: |
add eax,31 ;bootsector+2*fat+filenames |
shl eax,9 ;*512 |
add eax,RAMDISK ;image base |
mov ebx,[esp+8] |
mov ecx,512 ;[esp+4] |
cmp [esp+16],dword 0 ; wanted cluster ? |
jne frfl7 |
call memmove |
add [esp+8],dword 512 |
dec dword [esp+12] ; last wanted cluster ? |
je frnoread |
jmp frfl8 |
frfl7: |
dec dword [esp+16] |
frfl8: |
movzx eax,word [edi*2+RAMDISK_FAT] ; find next cluster from FAT |
mov edi,eax |
cmp edi,4095 ;eof - cluster |
jz frnoread2 |
cmp [esp+24],dword 512 ;eof - size |
jb frnoread |
sub [esp+24],dword 512 |
jmp frnew |
frnoread2: |
cmp [esp+16],dword 0 ; eof without read ? |
je frnoread |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
mov eax,6 ; end of file |
ret |
frnoread: |
pop edi esi edx ecx |
add esp,4 |
pop ebx ; ebx <- eax : size of file |
add esp,36 |
xor eax,eax ;read ok |
ret |
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,RAMDISK_FAT |
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,RAMDISK+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,RAMDISK_FAT ;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,RAMDISK |
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,RAMDISK+512*18+512 ;Point at directory |
cld |
rd_newsearch: |
mov esi,eax |
mov ecx,11 |
rep cmpsb |
je rd_ff |
add cl,21 |
add edi,ecx |
cmp edi,RAMDISK+512*33 |
jb rd_newsearch |
mov eax,5 ;if file not found - eax=5 |
xor ebx,ebx |
dec ebx ;ebx=0xffffffff and zf=0 |
rd_ff: |
ret |
; \begin{diamond} |
uni2ansi_str: |
; convert UNICODE zero-terminated string to ASCII-string (codepage 866) |
; in: esi->source, edi->buffer (may be esi=edi) |
; destroys: eax,esi,edi |
lodsw |
test ax, ax |
jz .done |
cmp ax, 0x80 |
jb .ascii |
cmp ax, 0x401 |
jz .yo1 |
cmp ax, 0x451 |
jz .yo2 |
cmp ax, 0x410 |
jb .unk |
cmp ax, 0x440 |
jb .rus1 |
cmp ax, 0x450 |
jb .rus2 |
.unk: |
mov al, '_' |
jmp .doit |
.yo1: |
mov al, 'ð' |
jmp .doit |
.yo2: |
mov al, 'ñ' |
jmp .doit |
.rus1: |
; 0x410-0x43F -> 0x80-0xAF |
add al, 0x70 |
jmp .doit |
.rus2: |
; 0x440-0x44F -> 0xE0-0xEF |
add al, 0xA0 |
.ascii: |
.doit: |
stosb |
jmp uni2ansi_str |
.done: |
mov byte [edi], 0 |
ret |
ansi2uni_char: |
; convert ANSI character in al to UNICODE character in ax, using cp866 encoding |
mov ah, 0 |
; 0x00-0x7F - trivial map |
cmp al, 0x80 |
jb .ret |
; 0x80-0xAF -> 0x410-0x43F |
cmp al, 0xB0 |
jae @f |
add ax, 0x410-0x80 |
.ret: |
ret |
@@: |
; 0xE0-0xEF -> 0x440-0x44F |
cmp al, 0xE0 |
jb .unk |
cmp al, 0xF0 |
jae @f |
add ax, 0x440-0xE0 |
ret |
; 0xF0 -> 0x401 |
; 0xF1 -> 0x451 |
@@: |
cmp al, 'ð' |
jz .yo1 |
cmp al, 'ñ' |
jz .yo2 |
.unk: |
mov al, '_' ; ah=0 |
ret |
.yo1: |
mov ax, 0x401 |
ret |
.yo2: |
mov ax, 0x451 |
ret |
char_toupper: |
; convert character to uppercase, using cp866 encoding |
; in: al=symbol |
; out: al=converted symbol |
cmp al, 'a' |
jb .ret |
cmp al, 'z' |
jbe .az |
cmp al, ' ' |
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 |
test byte [edi+11], 8 |
jnz .no |
push ecx |
push edi ebp |
test byte [ebp-4], 1 |
jnz .unicode_short |
mov eax, [edi] |
mov ecx, [edi+4] |
mov [ebp], eax |
mov [ebp+4], ecx |
mov ecx, 8 |
@@: |
cmp byte [ebp+ecx-1], ' ' |
loope @b |
mov eax, [edi+8] |
cmp al, ' ' |
je .done |
shl eax, 8 |
mov al, '.' |
lea ebp, [ebp+ecx+1] |
mov [ebp], eax |
mov ecx, 3 |
@@: |
rol eax, 8 |
cmp al, ' ' |
jne .done |
loop @b |
dec ebp |
.done: |
and byte [ebp+ecx+1], 0 ; CF=0 |
pop ebp edi ecx |
ret |
.unicode_short: |
mov ecx, 8 |
push ecx |
@@: |
mov al, [edi] |
inc edi |
call ansi2uni_char |
mov [ebp], ax |
inc ebp |
inc ebp |
loop @b |
pop ecx |
@@: |
cmp word [ebp-2], ' ' |
jnz @f |
dec ebp |
dec ebp |
loop @b |
@@: |
mov word [ebp], '.' |
inc ebp |
inc ebp |
mov ecx, 3 |
push ecx |
@@: |
mov al, [edi] |
inc edi |
call ansi2uni_char |
mov [ebp], ax |
inc ebp |
inc ebp |
loop @b |
pop ecx |
@@: |
cmp word [ebp-2], ' ' |
jnz @f |
dec ebp |
dec ebp |
loop @b |
dec ebp |
dec ebp |
@@: |
and word [ebp], 0 ; CF=0 |
pop ebp edi ecx |
ret |
.longname: |
; LFN |
mov al, byte [edi] |
and eax, 0x3F |
dec eax |
cmp al, 20 |
jae .no ; ignore invalid entries |
mov word [ebp+260*2], 0 ; force null-terminating for orphans |
imul eax, 13*2 |
add ebp, eax |
test byte [edi], 0x40 |
jz @f |
mov word [ebp+13*2], 0 |
@@: |
push eax |
; now copy name from edi to ebp ... |
mov eax, [edi+1] |
mov [ebp], eax ; symbols 1,2 |
mov eax, [edi+5] |
mov [ebp+4], eax ; 3,4 |
mov eax, [edi+9] |
mov [ebp+8], ax ; 5 |
mov eax, [edi+14] |
mov [ebp+10], eax ; 6,7 |
mov eax, [edi+18] |
mov [ebp+14], eax ; 8,9 |
mov eax, [edi+22] |
mov [ebp+18], eax ; 10,11 |
mov eax, [edi+28] |
mov [ebp+22], eax ; 12,13 |
; ... done |
pop eax |
sub ebp, eax |
test eax, eax |
jz @f |
; if this is not first entry, more processing required |
stc |
ret |
@@: |
; if this is first entry: |
test byte [ebp-4], 1 |
jnz .ret |
; buffer at ebp contains UNICODE name, convert it to ANSI |
push esi edi |
mov esi, ebp |
mov edi, ebp |
call uni2ansi_str |
pop edi esi |
.ret: |
clc |
ret |
fat_compare_name: |
; compares ASCIIZ-names, case-insensitive (cp866 encoding) |
; in: esi->name, ebp->name |
; out: if names match: ZF=1 and esi->next component of name |
; else: ZF=0, esi is not changed |
; destroys eax |
push ebp esi |
.loop: |
mov al, [ebp] |
inc ebp |
call char_toupper |
push eax |
lodsb |
call char_toupper |
cmp al, [esp] |
jnz .done |
pop eax |
test al, al |
jnz .loop |
dec esi |
pop eax |
pop ebp |
xor eax, eax ; set ZF flag |
ret |
.done: |
cmp al, '/' |
jnz @f |
cmp byte [esp], 0 |
jnz @f |
mov [esp+4], esi |
@@: |
pop eax |
pop esi ebp |
ret |
fat_time_to_bdfe: |
; in: eax=FAT time |
; out: eax=BDFE time |
push ecx edx |
mov ecx, eax |
mov edx, eax |
shr eax, 11 |
shl eax, 16 ; hours |
and edx, 0x1F |
add edx, edx |
mov al, dl ; seconds |
shr ecx, 5 |
and ecx, 0x3F |
mov ah, cl ; minutes |
pop edx ecx |
ret |
fat_date_to_bdfe: |
push ecx edx |
mov ecx, eax |
mov edx, eax |
shr eax, 9 |
add ax, 1980 |
shl eax, 16 ; year |
and edx, 0x1F |
mov al, dl ; day |
shr ecx, 5 |
and ecx, 0xF |
mov ah, cl ; month |
pop edx ecx |
ret |
bdfe_to_fat_time: |
push edx |
mov edx, eax |
shr eax, 16 |
and dh, 0x3F |
shl eax, 6 |
or al, dh |
shr dl, 1 |
and dl, 0x1F |
shl eax, 5 |
or al, dl |
pop edx |
ret |
bdfe_to_fat_date: |
push edx |
mov edx, eax |
shr eax, 16 |
sub ax, 1980 |
and dh, 0xF |
shl eax, 4 |
or al, dh |
and dl, 0x1F |
shl eax, 5 |
or al, dl |
pop edx |
ret |
fat_entry_to_bdfe: |
; convert FAT entry at edi to BDFE (block of data of folder entry) at esi, advance esi |
; destroys eax |
mov eax, [ebp-4] |
mov [esi+4], eax ; ASCII/UNICODE name |
fat_entry_to_bdfe2: |
movzx eax, byte [edi+11] |
mov [esi], eax ; attributes |
movzx eax, word [edi+14] |
call fat_time_to_bdfe |
mov [esi+8], eax ; creation time |
movzx eax, word [edi+16] |
call fat_date_to_bdfe |
mov [esi+12], eax ; creation date |
and dword [esi+16], 0 ; last access time is not supported on FAT |
movzx eax, word [edi+18] |
call fat_date_to_bdfe |
mov [esi+20], eax ; last access date |
movzx eax, word [edi+22] |
call fat_time_to_bdfe |
mov [esi+24], eax ; last write time |
movzx eax, word [edi+24] |
call fat_date_to_bdfe |
mov [esi+28], eax ; last write date |
mov eax, [edi+28] |
mov [esi+32], eax ; file size (low dword) |
xor eax, eax |
mov [esi+36], eax ; file size (high dword) |
test ebp, ebp |
jz .ret |
push ecx edi |
lea edi, [esi+40] |
mov esi, ebp |
test byte [esi-4], 1 |
jz .ansi |
mov ecx, 260/2 |
rep movsd |
mov [edi-2], ax |
@@: |
mov esi, edi |
pop edi ecx |
.ret: |
ret |
.ansi: |
mov ecx, 264/4 |
rep movsd |
mov [edi-1], al |
jmp @b |
bdfe_to_fat_entry: |
; convert BDFE at edx to FAT entry at edi |
; destroys eax |
; attributes byte |
test byte [edi+11], 8 ; volume label? |
jnz @f |
mov al, [edx] |
and al, 0x27 |
and byte [edi+11], 0x10 |
or byte [edi+11], al |
@@: |
mov eax, [edx+8] |
call bdfe_to_fat_time |
mov [edi+14], ax ; creation time |
mov eax, [edx+12] |
call bdfe_to_fat_date |
mov [edi+16], ax ; creation date |
mov eax, [edx+20] |
call bdfe_to_fat_date |
mov [edi+18], ax ; last access date |
mov eax, [edx+24] |
call bdfe_to_fat_time |
mov [edi+22], ax ; last write time |
mov eax, [edx+28] |
call bdfe_to_fat_date |
mov [edi+24], ax ; last write date |
ret |
ramdisk_root_first: |
mov edi, RAMDISK+512*19 |
clc |
ret |
ramdisk_root_next: |
add edi, 0x20 |
cmp edi, RAMDISK+512*33 |
cmc |
ret |
ramdisk_root_extend_dir: |
stc |
ret |
uglobal |
; this is for delete support |
rd_prev_sector dd ? |
rd_prev_prev_sector dd ? |
endg |
ramdisk_notroot_next: |
add edi, 0x20 |
test edi, 0x1FF |
jz ramdisk_notroot_next_sector |
ret ; CF=0 |
ramdisk_notroot_next_sector: |
push ecx |
mov ecx, [eax] |
push [rd_prev_sector] |
pop [rd_prev_prev_sector] |
mov [rd_prev_sector], ecx |
mov ecx, [ecx*2+RAMDISK_FAT] |
and ecx, 0xFFF |
cmp ecx, 2849 |
jae ramdisk_notroot_first.err2 |
mov [eax], ecx |
pop ecx |
ramdisk_notroot_first: |
mov eax, [eax] |
cmp eax, 2 |
jb .err |
cmp eax, 2849 |
jae .err |
shl eax, 9 |
lea edi, [eax+(31 shl 9)+RAMDISK] |
clc |
ret |
.err2: |
pop ecx |
.err: |
stc |
ret |
ramdisk_notroot_next_write: |
test edi, 0x1FF |
jz ramdisk_notroot_next_sector |
ramdisk_root_next_write: |
ret |
ramdisk_notroot_extend_dir: |
pusha |
xor eax, eax |
mov edi, RAMDISK_FAT |
mov ecx, 2849 |
repnz scasw |
jnz .notfound |
mov word [edi-2], 0xFFF |
sub edi, RAMDISK_FAT |
shr edi, 1 |
dec edi |
mov eax, [esp+28] |
mov ecx, [eax] |
mov [RAMDISK_FAT+ecx*2], di |
mov [eax], edi |
shl edi, 9 |
add edi, (31 shl 9)+RAMDISK |
mov [esp], edi |
xor eax, eax |
mov ecx, 128 |
rep stosd |
popa |
clc |
ret |
.notfound: |
popa |
stc |
ret |
rd_find_lfn: |
; in: esi+ebp -> name |
; out: CF=1 - file not found |
; else CF=0 and edi->direntry |
push esi edi |
push 0 |
push ramdisk_root_first |
push ramdisk_root_next |
.loop: |
call fat_find_lfn |
jc .notfound |
cmp byte [esi], 0 |
jz .found |
.continue: |
test byte [edi+11], 10h |
jz .notfound |
movzx eax, word [edi+26] |
mov [esp+8], eax |
mov dword [esp+4], ramdisk_notroot_first |
mov dword [esp], ramdisk_notroot_next |
jmp .loop |
.notfound: |
add esp, 12 |
pop edi esi |
stc |
ret |
.found: |
test ebp, ebp |
jz @f |
mov esi, ebp |
xor ebp, ebp |
jmp .continue |
@@: |
mov eax, [esp+8] |
add esp, 16 ; CF=0 |
pop esi |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskRead - LFN variant for reading sys floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = bytes read or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskRead: |
cmp byte [esi], 0 |
jnz @f |
or ebx, -1 |
mov eax, 10 ; access denied |
ret |
@@: |
push edi |
call rd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, 5 ; file not found |
ret |
.found: |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
xor ebx, ebx |
.reteof: |
mov eax, 6 ; EOF |
pop edi |
ret |
@@: |
mov ebx, [ebx] |
.l1: |
push ecx edx |
push 0 |
mov eax, [edi+28] |
sub eax, ebx |
jb .eof |
cmp eax, ecx |
jae @f |
mov ecx, eax |
mov byte [esp], 6 ; EOF |
@@: |
movzx edi, word [edi+26] ; cluster |
.new: |
jecxz .done |
test edi, edi |
jz .eof |
cmp edi, 0xFF8 |
jae .eof |
lea eax, [edi+31] ; bootsector+2*fat+filenames |
shl eax, 9 ; *512 |
add eax, RAMDISK ; image base |
; now eax points to data of cluster |
sub ebx, 512 |
jae .skip |
lea eax, [eax+ebx+512] |
neg ebx |
push ecx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
mov ebx, edx |
call memmove |
add edx, ecx |
sub [esp], ecx |
pop ecx |
xor ebx, ebx |
.skip: |
movzx edi, word [edi*2+RAMDISK_FAT] ; find next cluster from FAT |
jmp .new |
.eof: |
mov ebx, edx |
pop eax edx ecx |
sub ebx, edx |
jmp .reteof |
.done: |
mov ebx, edx |
pop eax edx ecx edi |
sub ebx, edx |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskReadFolder - LFN variant for reading sys floppy folder |
; |
; esi points to filename; only root is folder on ramdisk |
; ebx pointer to structure 32-bit number = first wanted block |
; & flags (bitfields) |
; flags: bit 0: 0=ANSI names, 1=UNICODE names |
; ecx number of blocks to read, 0+ |
; edx mem location to return data |
; |
; ret ebx = size or 0xffffffff file not found |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskReadFolder: |
push edi |
cmp byte [esi], 0 |
jz .root |
call rd_find_lfn |
jnc .found |
pop edi |
or ebx, -1 |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
.found: |
test byte [edi+11], 0x10 |
jnz .found_dir |
pop edi |
or ebx, -1 |
mov eax, ERROR_ACCESS_DENIED |
ret |
.found_dir: |
movzx eax, word [edi+26] |
add eax, 31 |
push 0 |
jmp .doit |
.root: |
mov eax, 19 |
push 14 |
.doit: |
push esi ecx ebp |
sub esp, 262*2 ; reserve space for LFN |
mov ebp, esp |
push dword [ebx+4] ; for fat_get_name: read ANSI/UNICODE names |
mov ebx, [ebx] |
; init header |
push eax ecx |
mov edi, edx |
mov ecx, 32/4 |
xor eax, eax |
rep stosd |
mov byte [edx], 1 ; version |
pop ecx eax |
mov esi, edi ; esi points to block of data of folder entry (BDFE) |
.main_loop: |
mov edi, eax |
shl edi, 9 |
add edi, RAMDISK |
push eax |
.l1: |
call fat_get_name |
jc .l2 |
cmp byte [edi+11], 0xF |
jnz .do_bdfe |
add edi, 0x20 |
test edi, 0x1FF |
jnz .do_bdfe |
pop eax |
inc eax |
dec byte [esp+262*2+16] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+RAMDISK_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+16], 0 |
@@: |
mov edi, eax |
shl edi, 9 |
add edi, RAMDISK |
push eax |
.do_bdfe: |
inc dword [edx+8] ; new file found |
dec ebx |
jns .l2 |
dec ecx |
js .l2 |
inc dword [edx+4] ; new file block copied |
call fat_entry_to_bdfe |
.l2: |
add edi, 0x20 |
test edi, 0x1FF |
jnz .l1 |
pop eax |
inc eax |
dec byte [esp+262*2+16] |
jz .done |
jns @f |
; read next sector from FAT |
mov eax, [(eax-31-1)*2+RAMDISK_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
jae .done |
add eax, 31 |
mov byte [esp+262*2+16], 0 |
@@: |
jmp .main_loop |
.done: |
add esp, 262*2+4 |
pop ebp |
mov ebx, [edx+4] |
xor eax, eax |
dec ecx |
js @f |
mov al, ERROR_END_OF_FILE |
@@: |
pop ecx esi edi edi |
ret |
iglobal |
label fat_legal_chars byte |
; 0 = not allowed |
; 1 = allowed only in long names |
; 3 = allowed |
times 32 db 0 |
; ! " # $ % & ' ( ) * + , - . / |
db 1,3,0,3,3,3,3,3,3,3,0,1,1,3,3,0 |
; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
db 3,3,3,3,3,3,3,3,3,3,0,1,0,1,0,0 |
; @ A B C D E F G H I J K L M N O |
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 |
; P Q R S T U V W X Y Z [ \ ] ^ _ |
db 3,3,3,3,3,3,3,3,3,3,3,1,0,1,3,3 |
; ` a b c d e f g h i j k l m n o |
db 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 |
; p q r s t u v w x y z { | } ~ |
db 3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,0 |
endg |
fat_name_is_legal: |
; in: esi->(long) name |
; out: CF set <=> legal |
; destroys eax |
push esi |
xor eax, eax |
@@: |
lodsb |
test al, al |
jz .done |
cmp al, 80h |
jae .big |
test [fat_legal_chars+eax], 1 |
jnz @b |
.err: |
pop esi |
clc |
ret |
.big: |
; 0x80-0xAF, 0xE0-0xEF |
cmp al, 0xB0 |
jb @b |
cmp al, 0xE0 |
jb .err |
cmp al, 0xF0 |
jb @b |
jmp .err |
.done: |
sub esi, [esp] |
cmp esi, 257 |
pop esi |
ret |
fat_next_short_name: |
; in: edi->8+3 name |
; out: name corrected |
; CF=1 <=> error |
pushad |
mov ecx, 8 |
mov al, '~' |
std |
push edi |
add edi, 7 |
repnz scasb |
pop edi |
cld |
jz .tilde |
; tilde is not found, insert "~1" at end |
add edi, 6 |
cmp word [edi], ' ' |
jnz .insert_tilde |
@@: dec edi |
cmp byte [edi], ' ' |
jz @b |
inc edi |
.insert_tilde: |
mov word [edi], '~1' |
popad |
clc |
ret |
.tilde: |
push edi |
add edi, 7 |
xor ecx, ecx |
@@: |
; after tilde may be only digits and trailing spaces |
cmp byte [edi], '~' |
jz .break |
cmp byte [edi], ' ' |
jz .space |
cmp byte [edi], '9' |
jnz .found |
dec edi |
jmp @b |
.space: |
dec edi |
inc ecx |
jmp @b |
.found: |
inc byte [edi] |
add dword [esp], 8 |
jmp .zerorest |
.break: |
jecxz .noplace |
inc edi |
mov al, '1' |
@@: |
xchg al, [edi] |
inc edi |
cmp al, ' ' |
mov al, '0' |
jnz @b |
.succ: |
pop edi |
popad |
clc |
ret |
.noplace: |
dec edi |
cmp edi, [esp] |
jz .err |
add dword [esp], 8 |
mov word [edi], '~1' |
inc edi |
inc edi |
@@: |
mov byte [edi], '0' |
.zerorest: |
inc edi |
cmp edi, [esp] |
jb @b |
pop edi |
popad |
;clc ; automatically |
ret |
.err: |
pop edi |
popad |
stc |
ret |
fat_gen_short_name: |
; in: esi->long name |
; edi->buffer (8+3=11 chars) |
; out: buffer filled |
pushad |
mov eax, ' ' |
push edi |
stosd |
stosd |
stosd |
pop edi |
xor eax, eax |
push 8 |
pop ebx |
lea ecx, [edi+8] |
.loop: |
lodsb |
test al, al |
jz .done |
call char_toupper |
cmp al, ' ' |
jz .space |
cmp al, 80h |
ja .big |
test [fat_legal_chars+eax], 2 |
jnz .symbol |
.inv_symbol: |
mov al, '_' |
or bh, 1 |
.symbol: |
cmp al, '.' |
jz .dot |
.normal_symbol: |
dec bl |
jns .store |
mov bl, 0 |
.space: |
or bh, 1 |
jmp .loop |
.store: |
stosb |
jmp .loop |
.big: |
cmp al, 0xB0 |
jb .normal_symbol |
cmp al, 0xE0 |
jb .inv_symbol |
cmp al, 0xF0 |
jb .normal_symbol |
jmp .inv_symbol |
.dot: |
test bh, 2 |
jz .firstdot |
pop ebx |
add ebx, edi |
sub ebx, ecx |
push ebx |
cmp ebx, ecx |
jb @f |
pop ebx |
push ecx |
@@: |
cmp edi, ecx |
jbe .skip |
@@: |
dec edi |
mov al, [edi] |
dec ebx |
mov [ebx], al |
mov byte [edi], ' ' |
cmp edi, ecx |
ja @b |
.skip: |
mov bh, 3 |
jmp @f |
.firstdot: |
cmp bl, 8 |
jz .space |
push edi |
or bh, 2 |
@@: |
mov edi, ecx |
mov bl, 3 |
jmp .loop |
.done: |
test bh, 2 |
jz @f |
pop edi |
@@: |
lea edi, [ecx-8] |
test bh, 1 |
jz @f |
call fat_next_short_name |
@@: |
popad |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskRewrite - LFN variant for writing ramdisk |
; fs_RamdiskCreateFolder - create folder on ramdisk |
; |
; esi points to file/folder name |
; ebx ignored (reserved) |
; ecx number of bytes to write, 0+ (ignored for folders) |
; edx mem location to data (ignored for folders) |
; |
; ret ebx = number of written bytes |
; eax = 0 ok read or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
fs_RamdiskCreateFolder: |
mov al, 1 ; create folder |
jmp fs_RamdiskRewrite.common |
fs_RamdiskRewrite: |
xor eax, eax ; create file |
.common: |
cmp byte [esi], 0 |
jz @b |
pushad |
xor edi, edi |
push esi |
test ebp, ebp |
jz @f |
mov esi, ebp |
@@: |
lodsb |
test al, al |
jz @f |
cmp al, '/' |
jnz @b |
lea edi, [esi-1] |
jmp @b |
@@: |
pop esi |
test edi, edi |
jnz .noroot |
test ebp, ebp |
jnz .hasebp |
push ramdisk_root_extend_dir |
push ramdisk_root_next_write |
push edi |
push ramdisk_root_first |
push ramdisk_root_next |
jmp .common1 |
.hasebp: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [ebp], 0 |
jz .ret1 |
push ebp |
xor ebp, ebp |
call rd_find_lfn |
pop esi |
jc .notfound0 |
jmp .common0 |
.noroot: |
mov eax, ERROR_ACCESS_DENIED |
cmp byte [edi+1], 0 |
jz .ret1 |
; check existence |
mov byte [edi], 0 |
push edi |
call rd_find_lfn |
pop esi |
mov byte [esi], '/' |
jnc @f |
.notfound0: |
mov eax, ERROR_FILE_NOT_FOUND |
.ret1: |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
@@: |
inc esi |
.common0: |
test byte [edi+11], 0x10 ; must be directory |
mov eax, ERROR_ACCESS_DENIED |
jz .ret1 |
movzx ebp, word [edi+26] ; ebp=cluster |
mov eax, ERROR_FAT_TABLE |
cmp ebp, 2 |
jb .ret1 |
cmp ebp, 2849 |
jae .ret1 |
push ramdisk_notroot_extend_dir |
push ramdisk_notroot_next_write |
push ebp |
push ramdisk_notroot_first |
push ramdisk_notroot_next |
.common1: |
call fat_find_lfn |
jc .notfound |
; found |
test byte [edi+11], 10h |
jz .exists_file |
; found directory; if we are creating directory, return OK, |
; if we are creating file, say "access denied" |
add esp, 20 |
popad |
test al, al |
mov eax, ERROR_ACCESS_DENIED |
jz @f |
mov al, 0 |
@@: |
xor ebx, ebx |
ret |
.exists_file: |
; found file; if we are creating directory, return "access denied", |
; if we are creating file, delete existing file and continue |
cmp byte [esp+20+28], 0 |
jz @f |
add esp, 20 |
popad |
mov eax, ERROR_ACCESS_DENIED |
xor ebx, ebx |
ret |
@@: |
; delete FAT chain |
push edi |
xor eax, eax |
mov dword [edi+28], eax ; zero size |
xchg ax, word [edi+26] ; start cluster |
test eax, eax |
jz .done1 |
@@: |
cmp eax, 0xFF8 |
jae .done1 |
lea edi, [RAMDISK_FAT + eax*2] ; position in FAT |
xor eax, eax |
xchg ax, [edi] |
jmp @b |
.done1: |
pop edi |
call get_time_for_file |
mov [edi+22], ax |
call get_date_for_file |
mov [edi+24], ax |
mov [edi+18], ax |
or byte [edi+11], 20h ; set 'archive' attribute |
jmp .doit |
.notfound: |
; file is not found; generate short name |
call fat_name_is_legal |
jc @f |
add esp, 20 |
popad |
mov eax, ERROR_FILE_NOT_FOUND |
xor ebx, ebx |
ret |
@@: |
sub esp, 12 |
mov edi, esp |
call fat_gen_short_name |
.test_short_name_loop: |
push esi edi ecx |
mov esi, edi |
lea eax, [esp+12+12+8] |
mov [eax], ebp |
call dword [eax-4] |
jc .found |
.test_short_name_entry: |
cmp byte [edi+11], 0xF |
jz .test_short_name_cont |
mov ecx, 11 |
push esi edi |
repz cmpsb |
pop edi esi |
jz .short_name_found |
.test_short_name_cont: |
lea eax, [esp+12+12+8] |
call dword [eax-8] |
jnc .test_short_name_entry |
jmp .found |
.short_name_found: |
pop ecx edi esi |
call fat_next_short_name |
jnc .test_short_name_loop |
.disk_full: |
add esp, 12+20 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.found: |
pop ecx edi esi |
; now find space in directory |
; we need to save LFN <=> LFN is not equal to short name <=> generated name contains '~' |
mov al, '~' |
push ecx edi |
mov ecx, 8 |
repnz scasb |
push 1 |
pop eax ; 1 entry |
jnz .notilde |
; we need ceil(strlen(esi)/13) additional entries = floor((strlen(esi)+12+13)/13) total |
xor eax, eax |
@@: |
cmp byte [esi], 0 |
jz @f |
inc esi |
inc eax |
jmp @b |
@@: |
sub esi, eax |
add eax, 12+13 |
mov ecx, 13 |
push edx |
cdq |
div ecx |
pop edx |
.notilde: |
push -1 |
push -1 |
; find <eax> successive entries in directory |
xor ecx, ecx |
push eax |
lea eax, [esp+12+8+12+8] |
mov [eax], ebp |
call dword [eax-4] |
pop eax |
.scan_dir: |
cmp byte [edi], 0 |
jz .free |
cmp byte [edi], 0xE5 |
jz .free |
xor ecx, ecx |
.scan_cont: |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax-8] |
pop eax |
jnc .scan_dir |
push eax |
lea eax, [esp+12+8+12+8] |
call dword [eax+8] ; extend directory |
pop eax |
jnc .scan_dir |
add esp, 8+8+12+20 |
popad |
mov eax, ERROR_DISK_FULL |
xor ebx, ebx |
ret |
.free: |
test ecx, ecx |
jnz @f |
mov [esp], edi |
mov ecx, [esp+8+8+12+8] |
mov [esp+4], ecx |
xor ecx, ecx |
@@: |
inc ecx |
cmp ecx, eax |
jb .scan_cont |
; found! |
; calculate name checksum |
push esi ecx |
mov esi, [esp+8+8] |
mov ecx, 11 |
xor eax, eax |
@@: |
ror al, 1 |
add al, [esi] |
inc esi |
loop @b |
pop ecx esi |
pop edi |
pop dword [esp+8+12+8] |
; edi points to last entry in free chunk |
dec ecx |
jz .nolfn |
push esi |
push eax |
mov al, 40h |
.writelfn: |
or al, cl |
mov esi, [esp+4] |
push ecx |
dec ecx |
imul ecx, 13 |
add esi, ecx |
stosb |
mov cl, 5 |
call .read_symbols |
mov ax, 0xF |
stosw |
mov al, [esp+4] |
stosb |
mov cl, 6 |
call .read_symbols |
xor eax, eax |
stosw |
mov cl, 2 |
call .read_symbols |
pop ecx |
lea eax, [esp+8+8+12+8] |
call dword [eax+4] ; next write |
xor eax, eax |
loop .writelfn |
pop eax |
pop esi |
.nolfn: |
xchg esi, [esp] |
mov ecx, 11 |
rep movsb |
mov word [edi], 20h ; attributes |
sub edi, 11 |
pop esi ecx |
add esp, 12 |
mov byte [edi+13], 0 ; tenths of a second at file creation time |
call get_time_for_file |
mov [edi+14], ax ; creation time |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+16], ax ; creation date |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
and word [edi+20], 0 ; high word of cluster |
and word [edi+26], 0 ; low word of cluster - to be filled |
and dword [edi+28], 0 ; file size - to be filled |
cmp byte [esp+20+28], 0 |
jz .doit |
; create directory |
mov byte [edi+11], 10h ; attributes: folder |
mov ecx, 32*2 |
mov edx, edi |
.doit: |
push edx |
push ecx |
push edi |
add edi, 26 ; edi points to low word of cluster |
push edi |
jecxz .done |
mov ecx, 2849 |
mov edi, RAMDISK_FAT |
.write_loop: |
; allocate new cluster |
xor eax, eax |
repnz scasw |
jnz .disk_full2 |
dec edi |
dec edi |
; lea eax, [edi-(RAMDISK_FAT)] |
mov eax, edi |
sub eax, RAMDISK_FAT |
shr eax, 1 ; eax = cluster |
mov word [edi], 0xFFF ; mark as last cluster |
xchg edi, [esp] |
stosw |
pop edi |
push edi |
inc ecx |
; write data |
cmp byte [esp+16+20+28], 0 |
jnz .writedir |
shl eax, 9 |
add eax, RAMDISK+31*512 |
.writefile: |
mov ebx, edx |
xchg eax, ebx |
push ecx |
mov ecx, 512 |
cmp dword [esp+12], ecx |
jae @f |
mov ecx, [esp+12] |
@@: |
call memmove |
add edx, ecx |
sub [esp+12], ecx |
pop ecx |
jnz .write_loop |
.done: |
mov ebx, edx |
pop edi edi ecx edx |
sub ebx, edx |
mov [edi+28], ebx |
add esp, 20 |
mov [esp+16], ebx |
popad |
xor eax, eax |
ret |
.disk_full2: |
mov ebx, edx |
pop edi edi ecx edx |
sub ebx, edx |
mov [edi+28], ebx |
add esp, 20 |
mov [esp+16], ebx |
popad |
push ERROR_DISK_FULL |
pop eax |
ret |
.writedir: |
mov edi, eax |
shl edi, 9 |
add edi, RAMDISK+31*512 |
mov esi, edx |
mov ecx, 32/4 |
push ecx |
rep movsd |
mov dword [edi-32], '. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
mov word [edi-32+26], ax |
mov esi, edx |
pop ecx |
rep movsd |
mov dword [edi-32], '.. ' |
mov dword [edi-32+4], ' ' |
mov dword [edi-32+8], ' ' |
mov byte [edi-32+11], 10h |
mov eax, [esp+16+8] |
mov word [edi-32+26], ax |
xor eax, eax |
mov ecx, (512-32*2)/4 |
rep stosd |
pop edi edi ecx edx |
add esp, 20 |
popad |
xor eax, eax |
xor ebx, ebx |
ret |
.read_symbol: |
or ax, -1 |
test esi, esi |
jz .retFFFF |
lodsb |
test al, al |
jnz ansi2uni_char |
xor eax, eax |
xor esi, esi |
.retFFFF: |
ret |
.read_symbols: |
call .read_symbol |
stosw |
loop .read_symbols |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskWrite - LFN variant for writing to sys floppy |
; |
; esi points to filename |
; ebx pointer to 64-bit number = first wanted byte, 0+ |
; may be ebx=0 - start from first byte |
; ecx number of bytes to write, 0+ |
; edx mem location to data |
; |
; ret ebx = bytes written (maybe 0) |
; eax = 0 ok write or other = errormsg |
; |
;-------------------------------------------------------------- |
@@: |
push ERROR_ACCESS_DENIED |
fs_RamdiskWrite.ret0: |
pop eax |
xor ebx, ebx |
ret |
fs_RamdiskWrite: |
cmp byte [esi], 0 |
jz @b |
pushad |
call rd_find_lfn |
jnc .found |
popad |
push ERROR_FILE_NOT_FOUND |
jmp .ret0 |
.found: |
; must not be directory |
test byte [edi+11], 10h |
jz @f |
popad |
push ERROR_ACCESS_DENIED |
jmp .ret0 |
@@: |
; FAT does not support files larger than 4GB |
test ebx, ebx |
jz .l1 |
cmp dword [ebx+4], 0 |
jz @f |
.eof: |
popad |
push ERROR_END_OF_FILE |
jmp .ret0 |
@@: |
mov ebx, [ebx] |
.l1: |
; now edi points to direntry, ebx=start byte to write, |
; ecx=number of bytes to write, edx=data pointer |
call fat_update_datetime |
; extend file if needed |
add ecx, ebx |
jc .eof ; FAT does not support files larger than 4GB |
push 0 ; return value=0 |
cmp ecx, [edi+28] |
jbe .length_ok |
cmp ecx, ebx |
jz .length_ok |
call ramdisk_extend_file |
jnc .length_ok |
; ramdisk_extend_file can return two error codes: FAT table error or disk full. |
; First case is fatal error, in second case we may write some data |
mov [esp], eax |
cmp al, ERROR_DISK_FULL |
jz .disk_full |
pop eax |
mov [esp+28], eax |
popad |
xor ebx, ebx |
ret |
.disk_full: |
; correct number of bytes to write |
mov ecx, [edi+28] |
cmp ecx, ebx |
ja .length_ok |
.ret: |
pop eax |
mov [esp+28], eax ; eax=return value |
sub edx, [esp+20] |
mov [esp+16], edx ; ebx=number of written bytes |
popad |
ret |
.length_ok: |
; now ebx=start pos, ecx=end pos, both lie inside file |
sub ecx, ebx |
jz .ret |
movzx edi, word [edi+26] ; starting cluster |
.write_loop: |
sub ebx, 0x200 |
jae .next_cluster |
push ecx |
neg ebx |
cmp ecx, ebx |
jbe @f |
mov ecx, ebx |
@@: |
mov eax, edi |
shl eax, 9 |
add eax, RAMDISK+31*512+0x200 |
sub eax, ebx |
mov ebx, eax |
mov eax, edx |
call memmove |
xor ebx, ebx |
add edx, ecx |
sub [esp], ecx |
pop ecx |
jz .ret |
.next_cluster: |
movzx edi, word [edi*2+RAMDISK_FAT] |
jmp .write_loop |
ramdisk_extend_file.zero_size: |
xor eax, eax |
jmp ramdisk_extend_file.start_extend |
; extends file on ramdisk to given size, new data area is filled by 0 |
; in: edi->direntry, ecx=new size |
; out: CF=0 => OK, eax=0 |
; CF=1 => error, eax=code (ERROR_FAT_TABLE or ERROR_DISK_FULL) |
ramdisk_extend_file: |
push ecx |
; find the last cluster of file |
movzx eax, word [edi+26] ; first cluster |
mov ecx, [edi+28] |
jecxz .zero_size |
@@: |
sub ecx, 0x200 |
jbe @f |
mov eax, [eax*2+RAMDISK_FAT] |
and eax, 0xFFF |
jz .fat_err |
cmp eax, 0xFF8 |
jb @b |
.fat_err: |
pop ecx |
push ERROR_FAT_TABLE |
pop eax |
stc |
ret |
@@: |
push eax |
mov eax, [eax*2+RAMDISK_FAT] |
and eax, 0xFFF |
cmp eax, 0xFF8 |
pop eax |
jb .fat_err |
; set length to full number of sectors and make sure that last sector is zero-padded |
sub [edi+28], ecx |
push eax edi |
mov edi, eax |
shl edi, 9 |
lea edi, [edi+RAMDISK+31*512+0x200+ecx] |
neg ecx |
xor eax, eax |
rep stosb |
pop edi eax |
.start_extend: |
pop ecx |
; now do extend |
push edx esi |
mov esi, RAMDISK_FAT+2*2 ; start scan from cluster 2 |
mov edx, 2847 ; number of clusters to scan |
.extend_loop: |
cmp [edi+28], ecx |
jae .extend_done |
; add new sector |
push ecx |
mov ecx, edx |
push edi |
mov edi, esi |
jecxz .disk_full |
push eax |
xor eax, eax |
repnz scasw |
pop eax |
jnz .disk_full |
mov word [edi-2], 0xFFF |
mov esi, edi |
mov edx, ecx |
sub edi, RAMDISK_FAT |
shr edi, 1 |
dec edi ; now edi=new cluster |
test eax, eax |
jz .first_cluster |
mov [RAMDISK_FAT+eax*2], di |
jmp @f |
.first_cluster: |
pop eax ; eax->direntry |
push eax |
mov [eax+26], di |
@@: |
push edi |
shl edi, 9 |
add edi, RAMDISK+31*512 |
xor eax, eax |
mov ecx, 512/4 |
rep stosd |
pop eax ; eax=new cluster |
pop edi ; edi->direntry |
pop ecx ; ecx=required size |
add dword [edi+28], 0x200 |
jmp .extend_loop |
.extend_done: |
mov [edi+28], ecx |
pop esi edx |
xor eax, eax ; CF=0 |
ret |
.disk_full: |
pop edi ecx |
pop esi edx |
stc |
push ERROR_DISK_FULL |
pop eax |
ret |
fat_update_datetime: |
call get_time_for_file |
mov [edi+22], ax ; last write time |
call get_date_for_file |
mov [edi+24], ax ; last write date |
mov [edi+18], ax ; last access date |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskSetFileEnd - set end of file on ramdisk |
; |
; esi points to filename |
; ebx points to 64-bit number = new file size |
; ecx ignored (reserved) |
; edx ignored (reserved) |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskSetFileEnd: |
cmp byte [esi], 0 |
jnz @f |
.access_denied: |
push ERROR_ACCESS_DENIED |
jmp .ret |
@@: |
push edi |
call rd_find_lfn |
jnc @f |
pop edi |
push ERROR_FILE_NOT_FOUND |
.ret: |
pop eax |
ret |
@@: |
; must not be directory |
test byte [edi+11], 10h |
jz @f |
pop edi |
jmp .access_denied |
@@: |
; file size must not exceed 4Gb |
cmp dword [ebx+4], 0 |
jz @f |
pop edi |
push ERROR_END_OF_FILE |
jmp .ret |
@@: |
; set file modification date/time to current |
call fat_update_datetime |
mov eax, [ebx] |
cmp eax, [edi+28] |
jb .truncate |
ja .expand |
pop edi |
xor eax, eax |
ret |
.expand: |
push ecx |
mov ecx, eax |
call ramdisk_extend_file |
pop ecx |
pop edi |
ret |
.truncate: |
mov [edi+28], eax |
push ecx |
movzx ecx, word [edi+26] |
test eax, eax |
jz .zero_size |
; find new last sector |
@@: |
sub eax, 0x200 |
jbe @f |
movzx ecx, word [RAMDISK_FAT+ecx*2] |
jmp @b |
@@: |
; zero data at the end of last sector |
push ecx |
mov edi, ecx |
shl edi, 9 |
lea edi, [edi+RAMDISK+31*512+eax+0x200] |
mov ecx, eax |
neg ecx |
xor eax, eax |
rep stosb |
pop ecx |
; terminate FAT chain |
lea ecx, [RAMDISK_FAT+ecx+ecx] |
push dword [ecx] |
mov word [ecx], 0xFFF |
pop ecx |
and ecx, 0xFFF |
jmp .delete |
.zero_size: |
and word [edi+26], 0 |
.delete: |
; delete FAT chain starting with ecx |
; mark all clusters as free |
cmp ecx, 0xFF8 |
jae .deleted |
lea ecx, [RAMDISK_FAT+ecx+ecx] |
push dword [ecx] |
and word [ecx], 0 |
pop ecx |
and ecx, 0xFFF |
jmp .delete |
.deleted: |
pop ecx |
pop edi |
xor eax, eax |
ret |
fs_RamdiskGetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call rd_find_lfn |
fs_GetFileInfo_finish: |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
push esi ebp |
xor ebp, ebp |
mov esi, edx |
and dword [esi+4], 0 |
call fat_entry_to_bdfe2 |
pop ebp esi |
pop edi |
xor eax, eax |
ret |
fs_RamdiskSetFileInfo: |
cmp byte [esi], 0 |
jnz @f |
mov eax, 2 ; unsupported |
ret |
@@: |
push edi |
call rd_find_lfn |
jnc @f |
pop edi |
mov eax, ERROR_FILE_NOT_FOUND |
ret |
@@: |
call bdfe_to_fat_entry |
pop edi |
xor eax, eax |
ret |
;---------------------------------------------------------------- |
; |
; fs_RamdiskDelete - delete file or empty folder from ramdisk |
; |
; esi points to filename |
; |
; ret eax = 0 ok or other = errormsg |
; |
;-------------------------------------------------------------- |
fs_RamdiskDelete: |
cmp byte [esi], 0 |
jnz @f |
; cannot delete root! |
.access_denied: |
push ERROR_ACCESS_DENIED |
.pop_ret: |
pop eax |
ret |
@@: |
and [rd_prev_sector], 0 |
and [rd_prev_prev_sector], 0 |
push edi |
call rd_find_lfn |
jnc .found |
pop edi |
push ERROR_FILE_NOT_FOUND |
jmp .pop_ret |
.found: |
cmp dword [edi], '. ' |
jz .access_denied2 |
cmp dword [edi], '.. ' |
jz .access_denied2 |
test byte [edi+11], 10h |
jz .dodel |
; we can delete only empty folders! |
movzx eax, word [edi+26] |
push ebx |
mov ebx, eax |
shl ebx, 9 |
add ebx, RAMDISK + 31*0x200 + 2*0x20 |
.checkempty: |
cmp byte [ebx], 0 |
jz .empty |
cmp byte [ebx], 0xE5 |
jnz .notempty |
add ebx, 0x20 |
test ebx, 0x1FF |
jnz .checkempty |
movzx eax, word [RAMDISK_FAT + eax*2] |
test eax, eax |
jz .empty |
mov ebx, eax |
shl ebx, 9 |
add ebx, RAMDISK + 31*0x200 |
jmp .checkempty |
.notempty: |
pop ebx |
.access_denied2: |
pop edi |
jmp .access_denied |
.empty: |
pop ebx |
.dodel: |
movzx eax, word [edi+26] |
; delete folder entry |
mov byte [edi], 0xE5 |
; delete LFN (if present) |
.lfndel: |
test edi, 0x1FF |
jnz @f |
cmp [rd_prev_sector], 0 |
jz @f |
cmp [rd_prev_sector], -1 |
jz .lfndone |
mov edi, [rd_prev_sector] |
push [rd_prev_prev_sector] |
pop [rd_prev_sector] |
or [rd_prev_prev_sector], -1 |
shl edi, 9 |
add edi, RAMDISK + 31*0x200 + 0x200 |
@@: |
sub edi, 0x20 |
cmp byte [edi], 0xE5 |
jz .lfndone |
cmp byte [edi+11], 0xF |
jnz .lfndone |
mov byte [edi], 0xE5 |
jmp .lfndel |
.lfndone: |
; delete FAT chain |
test eax, eax |
jz .done |
lea eax, [RAMDISK_FAT + eax*2] |
push dword [eax] |
and word [eax], 0 |
pop eax |
and eax, 0xFFF |
jmp .lfndone |
.done: |
pop edi |
xor eax, eax |
ret |
; \end{diamond} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/blkdev/hd_drv.inc |
---|
0,0 → 1,877 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; 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 |
;----------------------------------------------------------- |
and [hd_error], 0 |
push ecx esi edi ; scan cache |
mov ecx,cache_max ; entries in cache |
mov esi,HD_CACHE+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 |
; DMA read is permitted if [allow_dma_access]=1 or 2 |
cmp [allow_dma_access], 2 |
ja .nodma |
cmp [dma_hdd], 1 |
jnz .nodma |
call hd_read_dma |
jmp @f |
.nodma: |
call hd_read_pio |
@@: |
lea esi,[edi*8+HD_CACHE] |
mov [esi],eax ; sector number |
mov dword [esi+4],1 ; hd read - mark as same as in hd |
yeshdcache: |
mov esi,edi |
shl esi,9 |
add esi,HD_CACHE+65536 |
mov edi,ebx |
mov ecx,512/4 |
cld |
rep movsd ; move data |
return_01: |
pop edi esi ecx |
ret |
align 4 |
hd_read_pio: |
push eax edx |
call wait_for_hd_idle |
cmp [hd_error],0 |
jne hd_read_error |
cli |
xor eax,eax |
mov edx,[hdbase] |
inc edx |
out dx,al ; ATAFeatures ॣ¨áâà "®á®¡¥®á⥩" |
inc edx |
inc eax |
out dx,al ; ATASectorCount áçñâ稪 ᥪâ®à®¢ |
inc edx |
mov eax,[esp+4] |
out dx,al ; ATASectorNumber ॣ¨áâà ®¬¥à ᥪâ®à |
shr eax,8 |
inc edx |
out dx,al ; ATACylinder ®¬¥à 樫¨¤à (¬« ¤è¨© ¡ ©â) |
shr eax,8 |
inc edx |
out dx,al ; ®¬¥à 樫¨¤à (áâ à訩 ¡ ©â) |
shr eax,8 |
inc edx |
and al,1+2+4+8 |
add al,byte [hdid] |
add al,128+64+32 |
out dx,al ; ®¬¥à £®«®¢ª¨/®¬¥à ¤¨áª |
inc edx |
mov al,20h |
out dx,al ; ATACommand ॣ¨áâà ª®¬ ¤ |
sti |
call wait_for_sector_buffer |
cmp [hd_error],0 |
jne hd_read_error |
cli |
push edi |
shl edi,9 |
add edi,HD_CACHE+65536 |
mov ecx,256 |
mov edx,[hdbase] |
cld |
rep insw |
pop edi |
sti |
pop edx eax |
ret |
disable_ide_int: |
; mov edx,[hdbase] |
; add edx,0x206 |
; mov al,2 |
; out dx,al |
cli |
ret |
enable_ide_int: |
; mov edx,[hdbase] |
; add edx,0x206 |
; mov al,0 |
; out dx,al |
sti |
ret |
align 4 |
hd_write: |
;----------------------------------------------------------- |
; input : eax = block |
; ebx = pointer to memory |
;----------------------------------------------------------- |
push ecx esi edi |
; check if the cache already has the sector and overwrite it |
mov ecx,cache_max |
mov esi,HD_CACHE+8 |
mov edi,1 |
hdwritecache: |
cmp dword [esi+4],0 ; if cache slot is empty |
je not_in_cache_write |
cmp [esi],eax ; if the slot has the sector |
je yes_in_cache_write |
not_in_cache_write: |
add esi,8 |
inc edi |
dec ecx |
jnz hdwritecache |
; sector not found in cache |
; write the block to a new location |
call find_empty_slot ; ret in edi |
cmp [hd_error],0 |
jne hd_write_access_denied |
lea esi,[edi*8+HD_CACHE] |
mov [esi],eax ; sector number |
yes_in_cache_write: |
mov dword [esi+4],2 ; write - differs from hd |
shl edi,9 |
add edi,HD_CACHE+65536 |
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,HD_CACHE+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 |
; DMA write is permitted only if [allow_dma_access]=1 |
cmp [allow_dma_access], 2 |
jae .nodma |
cmp [dma_hdd], 1 |
jnz .nodma |
; ¡ê¥¤¨ï¥¬ § ¯¨áì 楯®çª¨ ¯®á«¥¤®¢ ⥫ìëå ᥪâ®à®¢ ¢ ®¤® ®¡à 饨¥ ª ¤¨áªã |
cmp ecx, 1 |
jz .nonext |
cmp dword [esi+8+4], 2 |
jnz .nonext |
push eax |
inc eax |
cmp eax, [esi+8] |
pop eax |
jnz .nonext |
cmp [cache_chain_started], 1 |
jz @f |
mov [cache_chain_started], 1 |
mov [cache_chain_size], 0 |
mov [cache_chain_pos], edi |
mov [cache_chain_ptr], esi |
@@: |
inc [cache_chain_size] |
cmp [cache_chain_size], 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,HD_CACHE+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+HD_CACHE+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, HD_CACHE |
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] |
add eax,300 ; 3 sec timeout |
mov [hd_wait_timeout],eax |
pop eax |
ret |
align 4 |
check_hd_wait_timeout: |
push eax |
mov eax,[hd_wait_timeout] |
cmp [timer_ticks], eax |
jg hd_timeout_error |
pop eax |
mov [hd_error],0 |
ret |
;iglobal |
; hd_timeout_str db 'K : FS - HD timeout',0 |
; hd_read_str db 'K : FS - HD read error',0 |
; hd_write_str db 'K : FS - HD write error',0 |
; hd_lba_str db 'K : FS - HD LBA error',0 |
;endg |
hd_timeout_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_timeout_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD timeout\n" |
mov [hd_error],1 |
pop eax |
ret |
hd_read_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_read_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD read error\n" |
pop edx eax |
ret |
hd_write_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_write_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD write error\n" |
ret |
hd_write_error_dma: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi, hd_write_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD read error\n" |
pop esi |
ret |
hd_lba_error: |
; call clear_hd_cache |
; call clear_application_table_status |
; mov esi,hd_lba_str |
; call sys_msg_board_str |
DEBUGF 1,"K : FS - HD LBA error\n" |
jmp LBA_read_ret |
align 4 |
wait_for_hd_idle: |
push eax edx |
call save_hd_wait_timeout |
mov edx,[hdbase] |
add edx,0x7 |
wfhil1: |
call check_hd_wait_timeout |
cmp [hd_error],0 |
jne @f |
in al,dx |
test al,128 |
jnz wfhil1 |
@@: |
pop edx eax |
ret |
align 4 |
wait_for_sector_buffer: |
push eax edx |
mov edx,[hdbase] |
add edx,0x7 |
call save_hd_wait_timeout |
hdwait_sbuf: ; wait for sector buffer to be ready |
call check_hd_wait_timeout |
cmp [hd_error],0 |
jne @f |
in al,dx |
test al,8 |
jz hdwait_sbuf |
mov [hd_error],0 |
cmp [hd_setup],1 ; do not mark error for setup request |
je buf_wait_ok |
test al,1 ; previous command ended up with an error |
jz buf_wait_ok |
@@: |
mov [hd_error],1 |
buf_wait_ok: |
pop edx eax |
ret |
; \begin{Mario79} |
align 4 |
wait_for_sector_dma_ide0: |
push eax |
push edx |
call save_hd_wait_timeout |
.wait: |
call change_task |
cmp [irq14_func], hdd_irq14 |
jnz .done |
call check_hd_wait_timeout |
cmp [hd_error], 0 |
jz .wait |
mov [irq14_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
mov al, 0 |
out dx, al |
.done: |
pop edx |
pop eax |
ret |
align 4 |
wait_for_sector_dma_ide1: |
push eax |
push edx |
call save_hd_wait_timeout |
.wait: |
call change_task |
cmp [irq15_func], hdd_irq15 |
jnz .done |
call check_hd_wait_timeout |
cmp [hd_error], 0 |
jz .wait |
mov [irq15_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
add dx, 8 |
mov al, 0 |
out dx, al |
.done: |
pop edx |
pop eax |
ret |
iglobal |
align 4 |
; note that IDE descriptor table must be 4-byte aligned and do not cross 4K boundary |
IDE_descriptor_table: |
dd 0x284000 |
dw 0x2000 |
dw 0x8000 |
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 |
allow_dma_access db 0 |
endg |
align 4 |
hdd_irq14: |
pushfd |
cli |
pushad |
mov [irq14_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
mov al, 0 |
out dx, al |
; call update_counters |
; mov ebx, [dma_process] |
; cmp [CURRENT_TASK], ebx |
; jz .noswitch |
; mov [dma_task_switched], 1 |
; mov edi, [dma_slot_ptr] |
; mov eax, [CURRENT_TASK] |
; mov [dma_process], eax |
; mov eax, [TASK_BASE] |
; mov [dma_slot_ptr], eax |
; mov [CURRENT_TASK], ebx |
; mov [TASK_BASE], edi |
; mov byte [DONT_SWITCH], 1 |
; call do_change_task |
.noswitch: |
popad |
popfd |
align 4 |
hdd_irq_null: |
ret |
align 4 |
hdd_irq15: |
pushfd |
cli |
pushad |
mov [irq15_func], hdd_irq_null |
mov dx, [IDEContrRegsBaseAddr] |
add dx, 8 |
mov al, 0 |
out dx, al |
; call update_counters |
; mov ebx, [dma_process] |
; cmp [CURRENT_TASK], ebx |
; jz .noswitch |
; mov [dma_task_switched], 1 |
; mov edi, [dma_slot_ptr] |
; mov eax, [CURRENT_TASK] |
; mov [dma_process], eax |
; mov eax, [TASK_BASE] |
; mov [dma_slot_ptr], eax |
; mov [CURRENT_TASK], ebx |
; mov [TASK_BASE], edi |
; mov byte [DONT_SWITCH], 1 |
; call do_change_task |
.noswitch: |
popad |
popfd |
ret |
align 4 |
hd_read_dma: |
push eax |
push edx |
mov edx, [dma_cur_sector] |
cmp eax, edx |
jb .notread |
add edx, 15 |
cmp [esp+4], edx |
ja .notread |
mov eax, [esp+4] |
sub eax, [dma_cur_sector] |
shl eax, 9 |
add eax, OS_BASE+0x284000 |
push ecx esi edi |
mov esi, eax |
shl edi, 9 |
add edi, HD_CACHE+0x10000 |
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 |
sub eax, OS_BASE |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add edx, 8 |
@@: |
push edx |
add edx, 4 |
out dx, eax |
pop edx |
mov al, 0 |
out dx, al |
add edx, 2 |
mov al, 6 |
out dx, al |
call wait_for_hd_idle |
cmp [hd_error], 0 |
jnz hd_read_error |
call disable_ide_int |
xor eax, eax |
mov edx, [hdbase] |
inc edx |
out dx, al |
inc edx |
mov eax, 10h |
out dx, al |
inc edx |
mov eax, [esp+4] |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
and al, 0xF |
add al, byte [hdid] |
add al, 11100000b |
out dx, al |
inc edx |
mov al, 0xC8 |
out dx, al |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add dx, 8 |
@@: |
mov al, 9 |
out dx, al |
mov eax, [CURRENT_TASK] |
mov [dma_process], eax |
mov eax, [TASK_BASE] |
mov [dma_slot_ptr], eax |
cmp [hdbase], 0x1F0 |
jnz .ide1 |
mov [irq14_func], hdd_irq14 |
jmp @f |
.ide1: |
mov [irq15_func], hdd_irq15 |
@@: |
call enable_ide_int |
cmp [hdbase], 0x1F0 |
jnz .wait_ide1 |
call wait_for_sector_dma_ide0 |
jmp @f |
.wait_ide1: |
call wait_for_sector_dma_ide1 |
@@: |
cmp [hd_error], 0 |
jnz hd_read_error |
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, DMA_HD_MEM+0x10000 |
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, DMA_HD_MEM+0x10000 |
mov [eax], edx |
mov word [eax+4], 0x200 |
do_write_dma: |
sub eax, OS_BASE |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add edx, 8 |
@@: |
push edx |
add edx, 4 |
out dx, eax |
pop edx |
mov al, 0 |
out dx, al |
add edx, 2 |
mov al, 6 |
out dx, al |
call wait_for_hd_idle |
cmp [hd_error], 0 |
jnz hd_write_error_dma |
call disable_ide_int |
xor eax, eax |
mov edx, [hdbase] |
inc edx |
out dx, al |
inc edx |
mov al, [cache_chain_size] |
out dx, al |
inc edx |
mov esi, [cache_chain_ptr] |
mov eax, [esi] |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
out dx, al |
shr eax, 8 |
inc edx |
and al, 0xF |
add al, byte [hdid] |
add al, 11100000b |
out dx, al |
inc edx |
mov al, 0xCA |
out dx, al |
mov dx, [IDEContrRegsBaseAddr] |
cmp [hdbase], 0x1F0 |
jz @f |
add dx, 8 |
@@: |
mov al, 1 |
out dx, al |
mov eax, [CURRENT_TASK] |
mov [dma_process], eax |
mov eax, [TASK_BASE] |
mov [dma_slot_ptr], eax |
cmp [hdbase], 0x1F0 |
jnz .ide1 |
mov [irq14_func], hdd_irq14 |
jmp @f |
.ide1: |
mov [irq15_func], hdd_irq15 |
@@: |
call enable_ide_int |
mov [dma_cur_sector], not 0x40 |
cmp [hdbase], 0x1F0 |
jnz .wait_ide1 |
call wait_for_sector_dma_ide0 |
jmp @f |
.wait_ide1: |
call wait_for_sector_dma_ide1 |
@@: |
cmp [hd_error], 0 |
jnz hd_write_error_dma |
pop esi |
ret |
uglobal |
IDEContrRegsBaseAddr dw ? |
endg |
; \end{Mario79} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/blkdev/rdsave.inc |
---|
0,0 → 1,30 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
saverd_fileinfo: |
dd 2 ; subfunction: write |
dd 0 ; (reserved) |
dd 0 ; (reserved) |
dd 1440*1024 ; size 1440 Kb |
dd RAMDISK |
db 0 |
.name: |
dd ? |
endg |
sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only) |
call restorefatchain |
mov eax, saverd_fileinfo |
mov [saverd_fileinfo.name], ebx |
pushad |
push eax |
call file_system_lfn |
pop eax |
popad |
mov [esp+36], eax |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/blkdev/flp_drv.inc |
---|
0,0 → 1,623 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;********************************************************** |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ êîíòðîëëåðîì ãèáêîãî äèñêà |
;********************************************************** |
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Àäàïòàöèÿ è äîðàáîòêà Mario79 |
;give_back_application_data: ; ïåðåñëàòü ïðèëîæåíèþ |
; mov edi,[TASK_BASE] |
; mov edi,[edi+TASKDATA.mem_start] |
; add edi,ecx |
give_back_application_data_1: |
mov esi,FDD_BUFF ;FDD_DataBuffer ;0x40000 |
xor ecx,ecx |
mov cx,128 |
cld |
rep movsd |
ret |
;take_data_from_application: ; âçÿòü èç ïðèëîæåíè |
; mov esi,[TASK_BASE] |
; mov esi,[esi+TASKDATA.mem_start] |
; add esi,ecx |
take_data_from_application_1: |
mov edi,FDD_BUFF ;FDD_DataBuffer ;0x40000 |
xor ecx,ecx |
mov cx,128 |
cld |
rep movsd |
ret |
; Êîäû çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì (FDC_Status) |
FDC_Normal equ 0 ;íîðìàëüíîå çàâåðøåíèå |
FDC_TimeOut equ 1 ;îøèáêà òàéì-àóòà |
FDC_DiskNotFound equ 2 ;â äèñêîâîäå íåò äèñêà |
FDC_TrackNotFound equ 3 ;äîðîæêà íå íàéäåíà |
FDC_SectorNotFound equ 4 ;ñåêòîð íå íàéäåí |
; Ìàêñèìàëüíûå çíà÷åíèÿ êîîðäèíàò ñåêòîðà (çàäàííûå |
; çíà÷åíèÿ ñîîòâåòñòâóþò ïàðàìåòðàì ñòàíäàðòíîãî |
; òðåõäþéìîâîãî ãèáêîãî äèñêà îáúåìîì 1,44 Ìá) |
MAX_Track equ 79 |
MAX_Head equ 1 |
MAX_Sector equ 18 |
uglobal |
; Ñ÷åò÷èê òèêîâ òàéìåðà |
TickCounter dd ? |
; Êîä çàâåðøåíèÿ îïåðàöèè ñ êîíòðîëëåðîì ÍÃÌÄ |
FDC_Status DB ? |
; Ôëàã ïðåðûâàíèÿ îò ÍÃÌÄ |
FDD_IntFlag DB ? |
; Ìîìåíò íà÷àëà ïîñëåäíåé îïåðàöèè ñ ÍÃÌÄ |
FDD_Time DD ? |
; Íîìåð äèñêîâîäà |
FDD_Type db 0 |
; Êîîðäèíàòû ñåêòîðà |
FDD_Track DB ? |
FDD_Head DB ? |
FDD_Sector DB ? |
; Áëîê ðåçóëüòàòà îïåðàöèè |
FDC_ST0 DB ? |
FDC_ST1 DB ? |
FDC_ST2 DB ? |
FDC_C DB ? |
FDC_H DB ? |
FDC_R DB ? |
FDC_N DB ? |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
ReadRepCounter DB ? |
; Ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
RecalRepCounter DB ? |
endg |
; Îáëàñòü ïàìÿòè äëÿ õðàíåíèÿ ïðî÷èòàííîãî ñåêòîðà |
;FDD_DataBuffer: times 512 db 0 ;DB 512 DUP (?) |
fdd_motor_status db 0 |
timer_fdd_motor dd 0 |
;************************************* |
;* ÈÍÈÖÈÀËÈÇÀÖÈß ÐÅÆÈÌÀ ÏÄÏ ÄËß ÍÃÌÄ * |
;************************************* |
Init_FDC_DMA: |
pushad |
mov al,0 |
out 0x0c,al ; reset the flip-flop to a known state. |
mov al,6 ; mask channel 2 so we can reprogram it. |
out 0x0a,al |
mov al,[dmamode] ; 0x46 -> Read from floppy - 0x4A Write to floppy |
out 0x0b,al |
mov al,0 |
out 0x0c,al ; reset the flip-flop to a known state. |
mov eax,0xD000 |
out 0x04,al ; set the channel 2 starting address to 0 |
shr eax,8 |
out 0x04,al |
shr eax,8 |
out 0x81,al |
mov al,0 |
out 0x0c, al ; reset flip-flop |
mov al, 0xff ;set count (actual size -1) |
out 0x5, al |
mov al,0x1 ;[dmasize] ;(0x1ff = 511 / 0x23ff =9215) |
out 0x5,al |
mov al,2 |
out 0xa,al |
popad |
ret |
;*********************************** |
;* ÇÀÏÈÑÀÒÜ ÁÀÉÒ Â ÏÎÐÒ ÄÀÍÍÛÕ FDC * |
;* Ïàðàìåòðû: * |
;* AL - âûâîäèìûé áàéò. * |
;*********************************** |
FDCDataOutput: |
; pusha |
push eax ecx edx |
mov AH,AL ;çàïîìíèòü áàéò â AH |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov [FDC_Status],FDC_Normal |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïðèåìó äàííûõ |
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
mov ecx, 0x10000 ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
@@TestRS: |
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL,0C0h ;âûäåëèòü ðàçðÿäû 6 è 7 |
cmp AL,80h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
je @@OutByteToFDC |
loop @@TestRS |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
jmp @@End_5 |
; Âûâåñòè áàéò â ïîðò äàííûõ |
@@OutByteToFDC: |
inc DX |
mov AL,AH |
out DX,AL |
@@End_5: |
; popa |
pop edx ecx eax |
ret |
;****************************************** |
;* ÏÐÎ×ÈÒÀÒÜ ÁÀÉÒ ÈÇ ÏÎÐÒÀ ÄÀÍÍÛÕ FDC * |
;* Ïðîöåäóðà íå èìååò âõîäíûõ ïàðàìåòðîâ. * |
;* Âûõîäíûå äàííûå: * |
;* AL - ñ÷èòàííûé áàéò. * |
;****************************************** |
FDCDataInput: |
push ECX |
push DX |
; Ñáðîñèòü ïåðåìåííóþ ñîñòîÿíèÿ êîíòðîëëåðà |
mov [FDC_Status],FDC_Normal |
; Ïðîâåðèòü ãîòîâíîñòü êîíòðîëëåðà ê ïåðåäà÷å äàííûõ |
mov DX,3F4h ;(ïîðò ñîñòîÿíèÿ FDC) |
xor CX,CX ;óñòàíîâèòü ñ÷åò÷èê òàéì-àóòà |
@@TestRS_1: |
in AL,DX ;ïðî÷èòàòü ðåãèñòð RS |
and AL,0C0h ;âûäëèòü ðàçðÿäû 6 è 7 |
cmp AL,0C0h ;ïðîâåðèòü ðàçðÿäû 6 è 7 |
je @@GetByteFromFDC |
loop @@TestRS_1 |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
jmp @@End_6 |
; Ââåñòè áàéò èç ïîðòà äàííûõ |
@@GetByteFromFDC: |
inc DX |
in AL,DX |
@@End_6: pop DX |
pop ECX |
ret |
;********************************************* |
;* ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;********************************************* |
FDCInterrupt: |
; Óñòàíîâèòü ôëàã ïðåðûâàíè |
mov [FDD_IntFlag],1 |
ret |
;****************************************** |
;* ÓÑÒÀÍÎÂÈÒÜ ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈÉ * |
;* ÍÃÌÄ * |
;****************************************** |
SetUserInterrupts: |
mov [fdc_irq_func],FDCInterrupt |
ret |
;******************************************* |
;* ÎÆÈÄÀÍÈÅ ÏÐÅÐÛÂÀÍÈß ÎÒ ÊÎÍÒÐÎËËÅÐÀ ÍÃÌÄ * |
;******************************************* |
WaitFDCInterrupt: |
pusha |
; Ñáðîñèòü áàéò ñîñòîÿíèÿ îïåðàöèè |
mov [FDC_Status],FDC_Normal |
; Ñáðîñèòü ôëàã ïðåðûâàíè |
mov [FDD_IntFlag],0 |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
mov eax,[timer_ticks] |
mov [TickCounter],eax |
; Îæèäàòü óñòàíîâêè ôëàãà ïðåðûâàíèÿ ÍÃÌÄ |
@@TestRS_2: |
cmp [FDD_IntFlag],0 |
jnz @@End_7 ;ïðåðûâàíèå ïðîèçîøëî |
call change_task |
mov eax,[timer_ticks] |
sub eax,[TickCounter] |
cmp eax,50 ;25 ;5 ;îæèäàòü 5 òèêîâ |
jb @@TestRS_2 |
; jl @@TestRS_2 |
; Îøèáêà òàéì-àóòà |
mov [FDC_Status],FDC_TimeOut |
; mov [flp_status],0 |
@@End_7: popa |
ret |
;********************************* |
;* ÂÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ "A:" * |
;********************************* |
FDDMotorON: |
pusha |
; cmp [fdd_motor_status],1 |
; je fdd_motor_on |
mov al,[flp_number] |
cmp [fdd_motor_status],al |
je fdd_motor_on |
; Ïðîèçâåñòè ñáðîñ êîíòðîëëåðà ÍÃÌÄ |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,0 |
out DX,AL |
; Âûáðàòü è âêëþ÷èòü ìîòîð äèñêîâîäà |
cmp [flp_number],1 |
jne FDDMotorON_B |
; call FDDMotorOFF_B |
mov AL,1Ch ; Floppy A |
jmp FDDMotorON_1 |
FDDMotorON_B: |
; call FDDMotorOFF_A |
mov AL,2Dh ; Floppy B |
FDDMotorON_1: |
out DX,AL |
; Îáíóëèòü ñ÷åò÷èê òèêîâ |
mov eax,[timer_ticks] |
mov [TickCounter],eax |
; Îæèäàòü 0,5 ñ |
@@dT: |
call change_task |
mov eax,[timer_ticks] |
sub eax,[TickCounter] |
cmp eax,50 ;10 |
jb @@dT |
cmp [flp_number],1 |
jne fdd_motor_on_B |
mov [fdd_motor_status],1 |
jmp fdd_motor_on |
fdd_motor_on_B: |
mov [fdd_motor_status],2 |
fdd_motor_on: |
call save_timer_fdd_motor |
popa |
ret |
;***************************************** |
;* ÑÎÕÐÀÍÅÍÈÅ ÓÊÀÇÀÒÅËß ÂÐÅÌÅÍÈ * |
;***************************************** |
save_timer_fdd_motor: |
mov eax,[timer_ticks] |
mov [timer_fdd_motor],eax |
ret |
;***************************************** |
;* ÏÐÎÂÅÐÊÀ ÇÀÄÅÐÆÊÈ ÂÛÊËÞ×ÅÍÈß ÌÎÒÎÐÀ * |
;***************************************** |
check_fdd_motor_status: |
cmp [fdd_motor_status],0 |
je end_check_fdd_motor_status_1 |
mov eax,[timer_ticks] |
sub eax,[timer_fdd_motor] |
cmp eax,500 |
jb end_check_fdd_motor_status |
call FDDMotorOFF |
mov [fdd_motor_status],0 |
end_check_fdd_motor_status_1: |
mov [flp_status],0 |
end_check_fdd_motor_status: |
ret |
;********************************** |
;* ÂÛÊËÞ×ÈÒÜ ÌÎÒÎÐ ÄÈÑÊÎÂÎÄÀ * |
;********************************** |
FDDMotorOFF: |
push AX |
push DX |
cmp [flp_number],1 |
jne FDDMotorOFF_1 |
call FDDMotorOFF_A |
jmp FDDMotorOFF_2 |
FDDMotorOFF_1: |
call FDDMotorOFF_B |
FDDMotorOFF_2: |
pop DX |
pop AX |
; ñáðîñ ôëàãîâ êåøèðîâàíèÿ â ñâÿçè ñ óñòàðåâàíèåì èíôîðìàöèè |
mov [root_read],0 |
mov [flp_fat],0 |
ret |
FDDMotorOFF_A: |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,0Ch ; Floppy A |
out DX,AL |
ret |
FDDMotorOFF_B: |
mov DX,3F2h ;ïîðò óïðàâëåíèÿ äâèãàòåëÿìè |
mov AL,5h ; Floppy B |
out DX,AL |
ret |
;******************************* |
;* ÐÅÊÀËÈÁÐÎÂÊÀ ÄÈÑÊÎÂÎÄÀ "A:" * |
;******************************* |
RecalibrateFDD: |
pusha |
call save_timer_fdd_motor |
; Ïîäàòü êîìàíäó "Ðåêàëèáðîâêà" |
mov AL,07h |
call FDCDataOutput |
mov AL,00h |
call FDCDataOutput |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
call WaitFDCInterrupt |
; cmp [FDC_Status],0 |
; je no_fdc_status_error |
; mov [flp_status],0 |
;no_fdc_status_error: |
call save_timer_fdd_motor |
popa |
ret |
;***************************************************** |
;* ÏÎÈÑÊ ÄÎÐÎÆÊÈ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;***************************************************** |
SeekTrack: |
pusha |
call save_timer_fdd_motor |
; Ïîäàòü êîìàíäó "Ïîèñê" |
mov AL,0Fh |
call FDCDataOutput |
; Ïåðåäàòü áàéò íîìåðà ãîëîâêè/íàêîïèòåë |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
; Ïåðåäàòü áàéò íîìåðà äîðîæêè |
mov AL,[FDD_Track] |
call FDCDataOutput |
; Îæèäàòü çàâåðøåíèÿ îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit |
; Ñîõðàíèòü ðåçóëüòàò ïîèñêà |
mov AL,08h |
call FDCDataOutput |
call FDCDataInput |
mov [FDC_ST0],AL |
call FDCDataInput |
mov [FDC_C],AL |
; Ïðîâåðèòü ðåçóëüòàò ïîèñêà |
; Ïîèñê çàâåðøåí? |
test [FDC_ST0],100000b |
je @@Err |
; Çàäàííûé òðåê íàéäåí? |
mov AL,[FDC_C] |
cmp AL,[FDD_Track] |
jne @@Err |
; Íîìåð ãîëîâêè ñîâïàäàåò ñ çàäàííûì? |
mov AL,[FDC_ST0] |
and AL,100b |
shr AL,2 |
cmp AL,[FDD_Head] |
jne @@Err |
; Îïåðàöèÿ çàâåðøåíà óñïåøíî |
mov [FDC_Status],FDC_Normal |
jmp @@Exit |
@@Err: ; Òðåê íå íàéäåí |
mov [FDC_Status],FDC_TrackNotFound |
; mov [flp_status],0 |
@@Exit: |
call save_timer_fdd_motor |
popa |
ret |
;******************************************************* |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;******************************************************* |
ReadSector: |
pushad |
call save_timer_fdd_motor |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
mov AX,0 |
mov DX,03F7h |
out DX,AL |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
mov [dmamode],0x46 |
call Init_FDC_DMA |
; Ïîäàòü êîìàíäó "×òåíèå äàííûõ" |
mov AL,0E6h ;÷òåíèå â ìóëüòèòðåêîâîì ðåæèìå |
call FDCDataOutput |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
mov AL,[FDD_Track] |
call FDCDataOutput |
mov AL,[FDD_Head] |
call FDCDataOutput |
mov AL,[FDD_Sector] |
call FDCDataOutput |
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
call FDCDataOutput |
mov AL,18 ;+1; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
call FDCDataOutput |
mov AL,1Bh ;çíà÷åíèå GPL |
call FDCDataOutput |
mov AL,0FFh ;çíà÷åíèå DTL |
call FDCDataOutput |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit_1 |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
call GetStatusInfo |
test [FDC_ST0],11011000b |
jnz @@Err_1 |
mov [FDC_Status],FDC_Normal |
jmp @@Exit_1 |
@@Err_1: mov [FDC_Status],FDC_SectorNotFound |
; mov [flp_status],0 |
@@Exit_1: |
call save_timer_fdd_motor |
popad |
ret |
;******************************************************* |
;* ×ÒÅÍÈÅ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè ÷òåíèÿ * |
;* ñîäåðæèìîå ñåêòîðà áóäåò çàíåñåíî â FDD_DataBuffer. * |
;******************************************************* |
ReadSectWithRetr: |
pusha |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
mov [RecalRepCounter],0 |
@@TryAgain: |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
mov [ReadRepCounter],0 |
@@ReadSector_1: |
call ReadSector |
cmp [FDC_Status],0 |
je @@Exit_2 |
cmp [FDC_Status],1 |
je @@Err_3 |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè |
inc [ReadRepCounter] |
cmp [ReadRepCounter],3 |
jb @@ReadSector_1 |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
cmp [RecalRepCounter],3 |
jb @@TryAgain |
; mov [flp_status],0 |
@@Exit_2: |
popa |
ret |
@@Err_3: |
mov [flp_status],0 |
popa |
ret |
;******************************************************* |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ ÄÀÍÍÛÕ * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;******************************************************* |
WriteSector: |
pushad |
call save_timer_fdd_motor |
; Óñòàíîâèòü ñêîðîñòü ïåðåäà÷è 500 Êáàéò/ñ |
mov AX,0 |
mov DX,03F7h |
out DX,AL |
; Èíèöèàëèçèðîâàòü êàíàë ïðÿìîãî äîñòóïà ê ïàìÿòè |
mov [dmamode],0x4A |
call Init_FDC_DMA |
; Ïîäàòü êîìàíäó "Çàïèñü äàííûõ" |
mov AL,0xC5 ;0x45 ;çàïèñü â ìóëüòèòðåêîâîì ðåæèìå |
call FDCDataOutput |
mov AL,[FDD_Head] |
shl AL,2 |
call FDCDataOutput |
mov AL,[FDD_Track] |
call FDCDataOutput |
mov AL,[FDD_Head] |
call FDCDataOutput |
mov AL,[FDD_Sector] |
call FDCDataOutput |
mov AL,2 ;êîä ðàçìåðà ñåêòîðà (512 áàéò) |
call FDCDataOutput |
mov AL,18; 3Fh ;÷èñëî ñåêòîðîâ íà äîðîæêå |
call FDCDataOutput |
mov AL,1Bh ;çíà÷åíèå GPL |
call FDCDataOutput |
mov AL,0FFh ;çíà÷åíèå DTL |
call FDCDataOutput |
; Îæèäàåì ïðåðûâàíèå ïî çàâåðøåíèè îïåðàöèè |
call WaitFDCInterrupt |
cmp [FDC_Status],FDC_Normal |
jne @@Exit_3 |
; Ñ÷èòûâàåì ñòàòóñ çàâåðøåíèÿ îïåðàöèè |
call GetStatusInfo |
test [FDC_ST0],11000000b ;11011000b |
jnz @@Err_2 |
mov [FDC_Status],FDC_Normal |
jmp @@Exit_3 |
@@Err_2: mov [FDC_Status],FDC_SectorNotFound |
@@Exit_3: |
call save_timer_fdd_motor |
popad |
ret |
;******************************************************* |
;* ÇÀÏÈÑÜ ÑÅÊÒÎÐÀ (Ñ ÏÎÂÒÎÐÅÍÈÅÌ ÎÏÅÐÀÖÈÈ ÏÐÈ ÑÁÎÅ) * |
;* Ïàðàìåòðû ïåðåäàþòñÿ ÷åðåç ãëîáàëüíûå ïåðåìåííûå: * |
;* FDD_Track - íîìåð äîðîæêè (0-79); * |
;* FDD_Head - íîìåð ãîëîâêè (0-1); * |
;* FDD_Sector - íîìåð ñåêòîðà (1-18). * |
;* Ðåçóëüòàò îïåðàöèè çàíîñèòñÿ â FDC_Status. * |
;*  ñëó÷àå óñïåøíîãî âûïîëíåíèÿ îïåðàöèè çàïèñè * |
;* ñîäåðæèìîå FDD_DataBuffer áóäåò çàíåñåíî â ñåêòîð. * |
;******************************************************* |
WriteSectWithRetr: |
pusha |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ðåêàëèáðîâêè |
mov [RecalRepCounter],0 |
@@TryAgain_1: |
; Îáíóëèòü ñ÷åò÷èê ïîâòîðåíèÿ îïåðàöèè ÷òåíè |
mov [ReadRepCounter],0 |
@@WriteSector_1: |
call WriteSector |
cmp [FDC_Status],0 |
je @@Exit_4 |
cmp [FDC_Status],1 |
je @@Err_4 |
; Òðîåêðàòíîå ïîâòîðåíèå ÷òåíè |
inc [ReadRepCounter] |
cmp [ReadRepCounter],3 |
jb @@WriteSector_1 |
; Òðîåêðàòíîå ïîâòîðåíèå ðåêàëèáðîâêè |
call RecalibrateFDD |
call SeekTrack |
inc [RecalRepCounter] |
cmp [RecalRepCounter],3 |
jb @@TryAgain_1 |
@@Exit_4: |
popa |
ret |
@@Err_4: |
mov [flp_status],0 |
popa |
ret |
;********************************************* |
;* ÏÎËÓ×ÈÒÜ ÈÍÔÎÐÌÀÖÈÞ Î ÐÅÇÓËÜÒÀÒÅ ÎÏÅÐÀÖÈÈ * |
;********************************************* |
GetStatusInfo: |
push AX |
call FDCDataInput |
mov [FDC_ST0],AL |
call FDCDataInput |
mov [FDC_ST1],AL |
call FDCDataInput |
mov [FDC_ST2],AL |
call FDCDataInput |
mov [FDC_C],AL |
call FDCDataInput |
mov [FDC_H],AL |
call FDCDataInput |
mov [FDC_R],AL |
call FDCDataInput |
mov [FDC_N],AL |
pop AX |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/blkdev/cd_drv.inc |
---|
0,0 → 1,554 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;********************************************************** |
; Íåïîñðåäñòâåííàÿ ðàáîòà ñ óñòðîéñòâîì Ñ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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/blkdev/cdrom.inc |
---|
0,0 → 1,269 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
sys_cd_audio: |
cmp word [cdbase],word 0 |
jnz @f |
mov eax,1 |
ret |
@@: |
; eax=1 cdplay at ebx 0x00FFSSMM |
; eax=2 get tracklist size of ecx to [ebx] |
; eax=3 stop/pause playing |
cmp eax,1 |
jnz nocdp |
call sys_cdplay |
ret |
nocdp: |
cmp eax,2 |
jnz nocdtl |
mov edi,[TASK_BASE] |
add edi,TASKDATA.mem_start |
add ebx,[edi] |
call sys_cdtracklist |
ret |
nocdtl: |
cmp eax,3 |
jnz nocdpause |
call sys_cdpause |
ret |
nocdpause: |
mov eax,0xffffff01 |
ret |
sys_cd_atapi_command: |
pushad |
mov dx,word [cdbase] |
add dx,6 |
mov ax,word [cdid] |
out dx,al |
mov esi,10 |
call delay_ms |
mov dx,word [cdbase] |
add dx,7 |
in al,dx |
and al,0x80 |
cmp al,0 |
jnz res |
jmp cdl6 |
res: |
mov dx,word [cdbase] |
add dx,7 |
mov al,0x8 |
out dx,al |
mov dx,word [cdbase] |
add dx,0x206 |
mov al,0xe |
out dx,al |
mov esi,1 |
call delay_ms |
mov dx,word [cdbase] |
add dx,0x206 |
mov al,0x8 |
out dx,al |
mov esi,30 |
call delay_ms |
xor cx,cx |
cdl5: |
inc cx |
cmp cx,10 |
jz cdl6 |
mov dx,word [cdbase] |
add dx,7 |
in al,dx |
and al,0x88 |
cmp al,0x00 |
jz cdl5 |
mov esi,100 |
call delay_ms |
jmp cdl5 |
cdl6: |
mov dx,word [cdbase] |
add dx,4 |
mov al,0 |
out dx,al |
mov dx,word [cdbase] |
add dx,5 |
mov al,0 |
out dx,al |
mov dx,word [cdbase] |
add dx,7 |
mov al,0xec |
out dx,al |
mov esi,5 |
call delay_ms |
mov dx,word [cdbase] |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,0 |
out dx,al |
add dx,1 |
mov al,128 |
out dx,al |
add dx,2 |
mov al,0xa0 |
out dx,al |
xor cx,cx |
mov dx,word [cdbase] |
add dx,7 |
cdl1: |
inc cx |
cmp cx,100 |
jz cdl2 |
in al,dx |
and ax,0x88 |
cmp al,0x8 |
jz cdl2 |
mov esi,2 |
call delay_ms |
jmp cdl1 |
cdl2: |
popad |
ret |
sys_cdplay: |
mov ax,5 |
push ax |
push ebx |
cdplay: |
call sys_cd_atapi_command |
cli |
mov dx,word [cdbase] |
mov ax,0x0047 |
out dx,ax |
mov al,1 |
mov ah,[esp+0] ; min xx |
out dx,ax |
mov ax,[esp+1] ; fr sec |
out dx,ax |
mov ax,256+99 |
out dx,ax |
mov ax,0x0001 |
out dx,ax |
mov ax,0x0000 |
out dx,ax |
mov esi,10 |
call delay_ms |
sti |
add dx,7 |
in al,dx |
test al,1 |
jz cdplayok |
mov ax,[esp+4] |
dec ax |
mov [esp+4],ax |
cmp ax,0 |
jz cdplayfail |
jmp cdplay |
cdplayfail: |
cdplayok: |
pop ebx |
pop ax |
xor eax, eax |
ret |
sys_cdtracklist: |
push ebx |
tcdplay: |
call sys_cd_atapi_command |
mov dx,word [cdbase] |
mov ax,0x43+2*256 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
mov ax,200 |
out dx,ax |
mov ax,0x0 |
out dx,ax |
in al,dx |
mov cx,1000 |
mov dx,word [cdbase] |
add dx,7 |
cld |
cdtrnwewait: |
mov esi,10 |
call delay_ms |
in al,dx |
and al,128 |
cmp al,0 |
jz cdtrl1 |
loop cdtrnwewait |
cdtrl1: |
; read the result |
mov ecx,[esp+0] |
mov dx,word [cdbase] |
cdtrread: |
add dx,7 |
in al,dx |
and al,8 |
cmp al,8 |
jnz cdtrdone |
sub dx,7 |
in ax,dx |
mov [ecx],ax |
add ecx,2 |
jmp cdtrread |
cdtrdone: |
pop ecx |
xor eax, eax |
ret |
sys_cdpause: |
call sys_cd_atapi_command |
mov dx,word [cdbase] |
mov ax,0x004B |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov ax,0 |
out dx,ax |
mov esi,10 |
call delay_ms |
add dx,7 |
in al,dx |
xor eax, eax |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/blkdev/fdc.inc |
---|
0,0 → 1,82 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
iglobal |
;function pointers. |
fdc_irq_func dd fdc_null |
endg |
uglobal |
dmasize db 0x0 |
dmamode db 0x0 |
endg |
fdc_init: ;start with clean tracks. |
mov edi,OS_BASE+0xD201 |
mov al,0 |
mov ecx,160 |
rep stosb |
ret |
fdc_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,OS_BASE+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,RAMDISK |
call SeekTrack |
save_image_1: |
push esi |
call take_data_from_application_1 |
pop esi |
add esi,512 |
call WriteSectWithRetr |
; call WriteSector |
cmp [FDC_Status],0 |
jne unnecessary_save_image |
inc [FDD_Sector] |
cmp [FDD_Sector],19 |
jne save_image_1 |
mov [FDD_Sector],1 |
inc [FDD_Head] |
cmp [FDD_Head],2 |
jne save_image_1 |
mov [FDD_Head],0 |
inc [FDD_Track] |
call SeekTrack |
cmp [FDD_Track],80 |
jne save_image_1 |
unnecessary_save_image: |
mov [fdc_irq_func],fdc_null |
popa |
mov [flp_status],0 |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/sys.conf |
---|
0,0 → 1,18 |
[path] |
/rd/1=/sys |
/rd/1/dll=/sys/lib |
[net] |
active=1 |
addr=192.168.1.2 |
mask=255.255.255.0 |
gate=192.168.1.1 |
[gui] |
mouse_speed=1 |
mouse_delay=0x00A |
[dev] |
sb16=0x220 |
sound_dma=1 |
midibase=0x320 |
/kernel/tags/kolibri0.7.0.0/boot/bootcode.inc |
---|
0,0 → 1,1067 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; BOOTCODE.INC ;; |
;; ;; |
;; KolibriOS 16-bit loader, ;; |
;; based on bootcode for MenuetOS ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;========================================================================== |
; |
; 16 BIT FUNCTIONS |
; |
;========================================================================== |
putchar: |
; in: al=character |
mov ah, 0Eh |
mov bh, 0 |
int 10h |
ret |
print: |
; in: si->string |
mov al, 186 |
call putchar |
mov al, ' ' |
call putchar |
printplain: |
; in: si->string |
pusha |
lodsb |
@@: |
call putchar |
lodsb |
cmp al, 0 |
jnz @b |
popa |
ret |
getkey: |
; get number in range [bl,bh] (bl,bh in ['0'..'9']) |
; in: bx=range |
; out: ax=digit (1..9, 10 for 0) |
mov ah, 0 |
int 16h |
cmp al, bl |
jb getkey |
cmp al, bh |
ja getkey |
push ax |
call putchar |
pop ax |
and ax, 0Fh |
jnz @f |
mov al, 10 |
@@: |
ret |
setcursor: |
; in: dl=column, dh=row |
mov ah, 2 |
mov bh, 0 |
int 10h |
ret |
macro _setcursor row,column |
{ |
mov dx, row*256 + column |
call setcursor |
} |
boot_read_floppy: |
push si |
xor si, si |
mov ah, 2 ; read |
@@: |
push ax |
int 0x13 |
pop ax |
jnc @f |
inc si |
cmp si, 10 |
jb @b |
mov si, badsect |
sayerr_plain: |
call printplain |
jmp $ |
@@: |
pop si |
ret |
;========================================================================= |
; |
; 16 BIT CODE |
; |
;========================================================================= |
start_of_code: |
cld |
; \begin{diamond}[02.12.2005] |
; if bootloader sets ax = 'KL', then ds:si points to loader block |
cmp ax, 'KL' |
jnz @f |
mov word [cs:cfgmanager.loader_block], si |
mov word [cs:cfgmanager.loader_block+2], ds |
@@: |
; \end{diamond}[02.12.2005] |
; if bootloader sets cx = 'HA' and dx = 'RD', then bx contains identifier of source hard disk |
; (see comment to bx_from_load) |
cmp cx, 'HA' |
jnz no_hd_load |
cmp dx,'RD' |
jnz no_hd_load |
mov word [cs:bx_from_load], bx ; {SPraid}[13.03.2007] |
no_hd_load: |
; set up stack |
mov ax, 3000h |
mov ss, ax |
mov sp, 0EC00h |
; set up segment registers |
push cs |
pop ds |
push cs |
pop es |
; set videomode |
mov ax, 3 |
int 0x10 |
if lang eq ru |
; Load & set russian VGA font (RU.INC) |
mov bp, RU_FNT1 ; RU_FNT1 - First part |
mov bx, 1000h ; 768 bytes |
mov cx, 30h ; 48 symbols |
mov dx, 80h ; 128 - position of first symbol |
mov ax, 1100h |
int 10h |
mov bp, RU_FNT2 ; RU_FNT2 -Second part |
mov bx, 1000h ; 512 bytes |
mov cx, 20h ; 32 symbols |
mov dx, 0E0h ; 224 - position of first symbol |
mov ax, 1100h |
int 10h |
; End set VGA russian font |
else if lang eq et |
mov bp, ET_FNT ; ET_FNT1 |
mov bx, 1000h ; |
mov cx, 255 ; 256 symbols |
xor dx, dx ; 0 - position of first symbol |
mov ax, 1100h |
int 10h |
end if |
; draw frames |
push 0xb800 |
pop es |
xor di, di |
mov ah, 1*16+15 |
; draw top |
mov si, d80x25_top |
mov cx, d80x25_top_num * 80 |
@@: |
lodsb |
stosw |
loop @b |
; draw spaces |
mov si, space_msg |
mov dx, 25 - d80x25_top_num - d80x25_bottom_num |
dfl1: |
push si |
mov cx, 80 |
@@: |
lodsb |
stosw |
loop @b |
pop si |
dec dx |
jnz dfl1 |
; draw bottom |
mov si, d80x25_bottom |
mov cx, d80x25_bottom_num * 80 |
@@: |
lodsb |
stosw |
loop @b |
mov byte [space_msg+80], 0 ; now space_msg is null terminated |
_setcursor d80x25_top_num,0 |
; TEST FOR 386+ |
mov bx, 0x4000 |
pushf |
pop ax |
mov dx, ax |
xor ax, bx |
push ax |
popf |
pushf |
pop ax |
and ax, bx |
and dx, bx |
cmp ax, dx |
jnz cpugood |
mov si, not386 |
sayerr: |
call print |
jmp $ |
cpugood: |
push 0 |
popf |
sti |
; set up esp |
movzx esp, sp |
push 0 |
pop es |
and word [es:0x9031], 0 |
; \begin{Mario79} |
; find HDD IDE DMA PCI device |
; check for PCI BIOS |
mov ax, 0xB101 |
int 0x1A |
jc .nopci |
cmp edx, 'PCI ' |
jnz .nopci |
; find PCI class code |
; class 1 = mass storage |
; subclass 1 = IDE controller |
; a) class 1, subclass 1, programming interface 0x80 |
mov ax, 0xB103 |
mov ecx, 1*10000h + 1*100h + 0x80 |
xor si, si ; device index = 0 |
int 0x1A |
jnc .found |
; b) class 1, subclass 1, programming interface 0x8A |
mov ax, 0xB103 |
mov ecx, 1*10000h + 1*100h + 0x8A |
xor si, si ; device index = 0 |
int 0x1A |
jnc .found |
; c) class 1, subclass 1, programming interface 0x85 |
mov ax, 0xB103 |
mov ecx, 1*10000h + 1*100h + 0x85 |
xor si, si |
int 0x1A |
jc .nopci |
.found: |
; get memory base |
mov ax, 0xB10A |
mov di, 0x20 ; memory base is config register at 0x20 |
int 0x1A |
jc .nopci |
and cx, 0xFFF0 ; clear address decode type |
mov [es:0x9031], cx |
.nopci: |
; \end{Mario79} |
mov al, 0xf6 ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå |
out 0x60, al |
xor cx, cx |
wait_loop: ; variant 2 |
; reading state of port of 8042 controller |
in al, 64h |
and al, 00000010b ; ready flag |
; wait until 8042 controller is ready |
loopnz wait_loop |
; --------------- APM --------------------- |
and word [es:0x9044], 0 ; ver = 0.0 (APM not found) |
mov ax, 0x5300 |
xor bx, bx |
int 0x15 |
jc apm_end ; APM not found |
test cx, 2 |
jz apm_end ; APM 32-bit protected-mode interface not supported |
mov [es:0x9044], ax ; Save APM Version |
mov [es:0x9046], cx ; Save APM flags |
; Write APM ver ---- |
and ax, 0xf0f |
add ax, '00' |
mov si, msg_apm |
mov [si + 5], ah |
mov [si + 7], al |
_setcursor 0, 3 |
call printplain |
; ------------------ |
mov ax, 0x5304 ; Disconnect interface |
xor bx, bx |
int 0x15 |
mov ax, 0x5303 ; Connect 32 bit mode interface |
xor bx, bx |
int 0x15 |
mov [es:0x9040], ebx |
mov [es:0x9050], ax |
mov [es:0x9052], cx |
mov [es:0x9054], dx |
apm_end: |
_setcursor d80x25_top_num, 0 |
; DISPLAY VESA INFORMATION |
mov ax, 0x4f00 |
mov di, 0xa000 |
int 0x10 |
cmp ax, 0x004f |
mov si, novesa |
jnz @f |
mov ax, [es:di+4] |
add ax, '0'*256+'0' |
mov si, vervesa |
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_dma = use DMA access? |
; c) preboot_vrrm = use VRR? |
; d) preboot_device = from what boot? |
mov di, preboot_graph |
; check bootloader block |
cmp [.loader_block], -1 |
jz .noloaderblock |
les bx, [.loader_block] |
cmp byte [es:bx], 1 |
mov si, loader_block_error |
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], 0 |
cmp byte [di], 0 |
jnz .preboot_gr_end |
mov [di+preboot_gprobe-preboot_graph], 0 |
mov al, [vervesa+vervesa_off] |
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_dma-preboot_graph], 0 |
jnz @f |
mov [di+preboot_dma-preboot_graph], 3 ; DMA: defaults to none |
@@: |
; following 4 lines set variables to 1 if its current value is 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 |
call print |
mov si, start_msg |
call print |
mov si, time_msg |
call print |
; get start time |
call .gettime |
mov [.starttime], eax |
mov word [.timer], .newtimer |
mov word [.timer+2], cs |
.printcfg: |
_setcursor 9,0 |
mov si, current_cfg_msg |
call print |
mov si, curvideo_msg |
call print |
mov al, [preboot_graph] |
cmp al, 8 |
ja .pnovesa |
mov dl, al |
and eax, 3 |
mov si, [modes_msg+eax*2] |
call printplain |
mov si, modevesa20 |
cmp dl, 4 |
jbe @f |
mov si, modevesa12 |
@@: |
call printplain |
cmp dl, 4 |
ja .x |
mov si, probeno_msg |
cmp [preboot_gprobe], 2 |
jnz @f |
mov si, probeok_msg |
@@: |
call printplain |
.x: |
jmp .c |
.pnovesa: |
cmp al, 9 |
mov si, mode9 |
jz @b |
mov si, mode10 |
jmp @b |
.c: |
mov si, linef |
call printplain |
mov si, dma_msg |
call print |
cmp [preboot_dma], 2 |
mov si, on_msg |
jb @f |
mov si, off_msg |
ja @f |
mov si, readonly_msg |
@@: |
call printplain |
mov si, vrrm_msg |
cmp [preboot_vrrm], 1 |
call .say_on_off |
mov si, preboot_device_msg |
call print |
mov al, [preboot_device] |
and eax, 3 |
mov si, [preboot_device_msgs+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], eax |
mov eax, [.timer] |
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] |
mov [es:8*4], eax |
mov [.timer], eax |
_setcursor 7,0 |
mov si, space_msg |
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 |
call print |
mov bx, '13' |
call getkey |
mov [preboot_device], al |
_setcursor 13,0 |
.d: |
mov [.bSettingsChanged], 1 |
mov si, space_msg |
call printplain |
_setcursor 15,0 |
mov cx, 6 |
@@: |
call printplain |
loop @b |
jmp .printcfg |
.change_a: |
_setcursor 15,0 |
mov si, gr_mode |
call printplain |
mov bx, '09' |
call getkey |
mov [preboot_graph], al |
cmp al, 4 |
ja @f |
mov si, probetext |
call printplain |
mov bx, '12' |
call getkey |
mov [preboot_gprobe], al |
@@: |
_setcursor 10,0 |
jmp .d |
.change_b: |
_setcursor 15,0 |
mov si, ask_dma |
call print |
mov bx, '13' |
call getkey |
mov [preboot_dma], al |
_setcursor 11,0 |
jmp .d |
.change_c: |
_setcursor 15,0 |
mov si, vrrmprint |
call print |
mov bx, '12' |
call getkey |
mov [preboot_vrrm], al |
_setcursor 12,0 |
jmp .d |
.say_on_off: |
pushf |
call print |
mov si, on_msg |
popf |
jz @f |
mov si, off_msg |
@@: jmp printplain |
; novesa and vervesa strings are not used at the moment of executing this code |
virtual at novesa |
.oldtimer dd ? |
.starttime dd ? |
.bSettingsChanged db ? |
.timer dd ? |
end virtual |
.loader_block dd -1 |
.gettime: |
mov ah, 0 |
int 1Ah |
xchg ax, cx |
shl eax, 10h |
xchg ax, dx |
ret |
.newtimer: |
push ds |
push cs |
pop ds |
pushf |
call [.oldtimer] |
pushad |
call .gettime |
sub eax, [.starttime] |
sub ax, 18*5 |
jae .timergo |
neg ax |
add ax, 18-1 |
mov bx, 18 |
xor dx, dx |
div bx |
if lang eq ru |
; ¯®¤®¦¤¨â¥ 5 ᥪã¤, 4/3/2 ᥪã¤ë, 1 ᥪã¤ã |
cmp al, 5 |
mov cl, ' ' |
jae @f |
cmp al, 1 |
mov cl, 'ã' |
jz @f |
mov cl, 'ë' |
@@: mov [time_str+9], cl |
else if lang eq et |
cmp al, 1 |
ja @f |
mov [time_str+9], ' ' |
mov [time_str+10],' ' |
@@: |
else |
; wait 5/4/3/2 seconds, 1 second |
cmp al, 1 |
mov cl, 's' |
ja @f |
mov cl, ' ' |
@@: mov [time_str+9], cl |
end if |
add al, '0' |
mov [time_str+1], al |
mov si, time_msg |
_setcursor 7,0 |
call print |
_setcursor 25,0 |
popad |
pop ds |
iret |
.timergo: |
push 0 |
pop es |
mov eax, [.oldtimer] |
mov [es:8*4], eax |
mov sp, 0EC00h |
.continue: |
sti |
_setcursor 6,0 |
mov si, space_msg |
call printplain |
call printplain |
_setcursor 6,0 |
mov si, loading_msg |
call print |
_setcursor 15,0 |
cmp [.bSettingsChanged], 0 |
jz .load |
cmp [.loader_block], -1 |
jz .load |
les bx, [.loader_block] |
mov eax, [es:bx+3] |
push ds |
pop es |
test eax, eax |
jz .load |
push eax |
mov si, save_quest |
call print |
.waityn: |
mov ah, 0 |
int 16h |
or al, 20h |
cmp al, 'n' |
jz .loadc |
cmp al, 'y' |
jnz .waityn |
call putchar |
mov byte [space_msg+80], 186 |
pop eax |
push cs |
push .cont |
push eax |
retf |
.loadc: |
pop eax |
.cont: |
push cs |
pop ds |
mov si, space_msg |
mov byte [si+80], 0 |
_setcursor 15,0 |
call printplain |
_setcursor 15,0 |
.load: |
; \end{diamond}[02.12.2005] |
; ASK GRAPHICS MODE |
movzx ax, [preboot_graph] |
push 0 |
pop es |
; address is gr_table+6*(ax-1) |
add ax, ax |
lea si, [gr_table + 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 |
or 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], 1 |
jz noprobe |
mov bx, 0x100 |
newprobe: |
inc bx |
cmp bx, 0x17f |
mov si, prnotfnd |
jz invalid_video_mode |
probemore: |
push cx |
mov ax, 0x4f01 |
mov cx, bx |
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 |
BytesPerLine equ 0x10 |
mov ax, [es:di+BytesPerLine] |
mov [es:0x9001], ax |
; BPP |
mov al, byte [es:di+0x19] |
mov [es:0x9000], al |
nov: |
cmp al, 24 |
mov si, bt24 |
jz bppl |
cmp al, 32 |
mov si, bt32 |
jz bppl |
mov si, btns |
invalid_video_mode: |
call print |
_setcursor (d80x25_top_num+2), 0 |
mov si, start_msg |
call print |
jmp cfgmanager.printcfg |
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 |
; force yes |
mov [es:0x901C], byte 1 |
; DMA ACCESS TO HD |
mov al, [preboot_dma] |
mov [es:0x901F], al |
; VRR_M USE |
mov al,[preboot_vrrm] |
mov [es:0x9030], al |
mov [es:0x901E], byte 1 |
; BOOT DEVICE |
mov al, [preboot_device] |
dec al |
mov [boot_dev], al |
; READ DISKETTE TO MEMORY |
; cmp [boot_dev],0 |
jne no_sys_on_floppy |
mov si,diskload |
call print |
xor ax, ax ; reset drive |
xor dx, dx |
int 0x13 |
; 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 |
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 |
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 |
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 |
call printplain |
mov si, okt |
call printplain |
no_sys_on_floppy: |
xor ax, ax ; reset drive |
xor dx, dx |
int 0x13 |
mov dx, 0x3f2 ; floppy motor off |
mov al, 0 |
out dx, al |
; SET GRAPHICS |
xor ax, ax |
mov es, ax |
mov ax, [es:0x9008] ; vga & 320x200 |
mov bx, ax |
cmp ax, 0x13 |
je setgr |
cmp ax, 0x12 |
je setgr |
mov ax, 0x4f02 ; Vesa |
setgr: |
int 0x10 |
test ah, ah |
mov si, fatalsel |
jnz 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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/boot/booteng.inc |
---|
0,0 → 1,95 |
$Revision$ |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
d80x25_bottom: |
db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' |
db 'NO WARRANTY ',186 |
db 186,' See file COPYING for details ' |
db ' ',186 |
line_full_bottom |
d80x25_bottom_num = 3 |
novesa db "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 |
ask_dma db "Use DMA for HDD access? [1-yes, 2-only for reading, 3-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,mode1,mode2,mode3 |
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 |
dma_msg db " [b] Use DMA for HDD access:",0 |
on_msg db " on",13,10,0 |
off_msg db " off",13,10,0 |
readonly_msg db " only for reading",13,10,0 |
vrrm_msg db " [c] Use VRR:",0 |
preboot_device_msg db " [d] Floppy image: ",0 |
preboot_device_msgs dw 0,pdm1,pdm2,pdm3 |
pdm1 db "real floppy",13,10,0 |
pdm2 db "C:\kolibri.img (FAT32)",13,10,0 |
pdm3 db "use already loaded image",13,10,0 |
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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/boot/bootet.inc |
---|
0,0 → 1,95 |
$Revision$ |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
d80x25_bottom: |
db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' |
db 'NO WARRANTY ',186 |
db 186,' See file COPYING for details ' |
db ' ',186 |
line_full_bottom |
d80x25_bottom_num = 3 |
novesa db "Ekraan: EGA/CGA",13,10,0 |
vervesa db "Vesa versioon: Vesa x.x",13,10,0 |
vervesa_off=20 |
msg_apm db " APM x.x ", 0 |
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " |
db "[3] 1024x768, [4] 1280x1024",13,10 |
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " |
db "[7] 1024x768, [8] 1280x1024",13,10 |
db 186," EGA/CGA 256 värvi: [9] 320x200, " |
db "VGA 16 värvi: [0] 640x480",13,10 |
db 186," Vali reziim: ",0 |
bt24 db "Bitti pikseli kohta: 24",13,10,0 |
bt32 db "Bitti pikseli kohta: 32",13,10,0 |
vrrmprint db "Kinnita VRR? (ekraani sagedus suurem kui 60Hz" |
db " ainult:",13,10 |
db 186," 1024*768->800*600 ja 800*600->640*480) [1-jah,2-ei]:",0 |
;askmouse db " Hiir:" |
; db " [1] PS/2 (USB), [2] Com1, [3] Com2." |
; db " Vali port [1-3]: ",0 |
;no_com1 db 13,10,186, " No COM1 mouse",0 |
;no_com2 db 13,10,186, " No COM2 mouse",0 |
ask_dma db "Use DMA for HDD access? [1-yes, 2-only for reading, 3-no]: ",0 |
;gr_direct db 186," Use direct LFB writing? " |
; db "[1-yes/2-no] ? ",0 |
;mem_model db 13,10,186," Motherboard memory [1-16 Mb / 2-32 Mb / " |
; db "3-64Mb / 4-128 Mb / 5-256 Mb] ? ",0 |
;bootlog db 13,10,186," After bootlog display [1-continue/2-pause] ? ",0 |
bdev db "Paigalda mäluketas [1-diskett; 2-C:\kolibri.img (FAT32);" |
db 13,10,186," " |
db "3-kasuta eellaaditud mäluketast kerneli restardist]: ",0 |
probetext db 13,10,13,10,186," Kasuta standartset graafika reziimi? [1-jah, " |
db "2-leia biosist (Vesa 3.0)]: ",0 |
;memokz256 db 13,10,186," RAM 256 Mb",0 |
;memokz128 db 13,10,186," RAM 128 Mb",0 |
;memokz64 db 13,10,186," RAM 64 Mb",0 |
;memokz32 db 13,10,186," RAM 32 Mb",0 |
;memokz16 db 13,10,186," RAM 16 Mb",0 |
prnotfnd db "Fataalne - Videoreziimi ei leitud.",0 |
;modena db "Fataalne - VBE 0x112+ on vajalik.",0 |
not386 db "Fataalne - CPU 386+ on vajalik.",0 |
btns db "Fataalne - Ei suuda värvisügavust määratleda.",0 |
fatalsel db "Fataalne - Graafilist reziimi riistvara ei toeta.",0 |
badsect db 13,10,186," Fataalne - Vigane sektor. Asenda diskett.",0 |
memmovefailed db 13,10,186," Fataalne - Int 0x15 liigutamine ebaõnnestus.",0 |
okt db " ... OK" |
linef db 13,10,0 |
diskload db "Loen disketti: 00 %",8,8,8,8,0 |
pros db "00" |
backspace2 db 8,8,0 |
boot_dev db 0 ; 0=floppy, 1=hd |
start_msg db "Vajuta [abcd] seadete muutmiseks, vajuta [Enter] laadimise jätkamiseks",13,10,0 |
time_msg db " või oota " |
time_str db " 5 sekundit" |
db " automaatseks jätkamiseks",13,10,0 |
current_cfg_msg db "Praegused seaded:",13,10,0 |
curvideo_msg db " [a] Videoreziim: ",0 |
mode1 db "640x480",0 |
mode2 db "800x600",0 |
mode3 db "1024x768",0 |
mode4 db "1280x1024",0 |
modes_msg dw mode4,mode1,mode2,mode3 |
modevesa20 db " koos LFB",0 |
modevesa12 db ", VESA 1.2 Bnk",0 |
mode9 db "320x200, EGA/CGA 256 värvi",0 |
mode10 db "640x480, VGA 16 värvi",0 |
probeno_msg db " (standard reziim)",0 |
probeok_msg db " (kontrolli ebastandardseid reziime)",0 |
dma_msg db " [b] Use DMA for HDD access:",0 |
on_msg db " sees",13,10,0 |
off_msg db " väljas",13,10,0 |
readonly_msg db " only for reading",13,10,0 |
vrrm_msg db " [c] Kasuta VRR:",0 |
preboot_device_msg db " [d] Disketi kujutis: ",0 |
preboot_device_msgs dw 0,pdm1,pdm2,pdm3 |
pdm1 db "reaalne diskett",13,10,0 |
pdm2 db "C:\kolibri.img (FAT32)",13,10,0 |
pdm3 db "kasuta juba laaditud kujutist",13,10,0 |
loading_msg db "Laadin KolibriOS...",0 |
save_quest db "Jäta meelde praegused seaded? [y/n]: ",0 |
loader_block_error db "Alglaaduri andmed vigased, ei saa jätkata. Peatatud.",0 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/boot/bootge.inc |
---|
0,0 → 1,100 |
$Revision$ |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
d80x25_bottom: |
; db 186,' KolibriOS based on MenuetOS and comes with ABSOLUTELY ' |
; db 'NO WARRANTY ',186 |
; db 186,' See file COPYING for details ' |
; db ' ',186 |
db 186,' KolibriOS basiert auf MenuetOS und wird ohne jegliche ' |
db ' Garantie vertrieben ',186 |
db 186,' Details stehen in der Datei COPYING ' |
db ' ',186 |
line_full_bottom |
d80x25_bottom_num = 3 |
novesa db "Anzeige: EGA/CGA ",13,10,0 |
vervesa db "Vesa-Version: Vesa ",13,10,0 |
vervesa_off=22 |
msg_apm db " APM x.x ", 0 |
gr_mode db 186," Vesa 2.0+ 16 M LFB: [1] 640x480, [2] 800x600, " |
db "[3] 1024x768, [4] 1280x1024",13,10 |
db 186," Vesa 1.2 16 M Bnk: [5] 640x480, [6] 800x600, " |
db "[7] 1024x768, [8] 1280x1024",13,10 |
db 186," EGA/CGA 256 Farben: [9] 320x200, " |
db "VGA 16 Farben: [0] 640x480",13,10 |
db 186," Waehle Modus: ",0 |
bt24 db "Bits Per Pixel: 24",13,10,0 |
bt32 db "Bits Per Pixel: 32",13,10,0 |
vrrmprint db "VRR verwenden? (Monitorfrequenz groesser als 60Hz" |
db " only for transfers:",13,10 |
db 186," 1024*768->800*600 und 800*600->640*480) [1-ja,2-nein]:",0 |
;askmouse db " Maus angeschlossen an:" |
; db " [1] PS/2 (USB), [2] Com1, [3] Com2." |
; db " Waehle Port [1-3]: ",0 |
;no_com1 db 13,10,186, " Keine COM1 Maus",0 |
;no_com2 db 13,10,186, " Keine COM2 Maus",0 |
ask_dma db "Nutze DMA zum HDD Zugriff? [1-ja, 2-allein fur Lesen, 3-nein]: ",0 |
;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,mode1,mode2,mode3 |
modevesa20 db " mit LFB",0 |
modevesa12 db ", VESA 1.2 Bnk",0 |
mode9 db "320x200, EGA/CGA 256 colors",0 |
mode10 db "640x480, VGA 16 colors",0 |
probeno_msg db " (Standard Modus)",0 |
probeok_msg db " (teste nicht-standard Modi)",0 |
dma_msg db " [b] Nutze DMA zum HDD Aufschreiben:",0 |
on_msg db " an",13,10,0 |
off_msg db " aus",13,10,0 |
readonly_msg db " fur Lesen",13,10,0 |
vrrm_msg db " [c] Nutze VRR:",0 |
preboot_device_msg db " [d] Diskettenimage: ",0 |
preboot_device_msgs dw 0,pdm1,pdm2,pdm3 |
pdm1 db "Echte Diskette",13,10,0 |
pdm2 db "C:\kolibri.img (FAT32)",13,10,0 |
pdm3 db "Nutze bereits geladenes Image",13,10,0 |
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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/boot/bootru.inc |
---|
0,0 → 1,95 |
$Revision$ |
;====================================================================== |
; |
; BOOT DATA |
; |
;====================================================================== |
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 |
ask_dma db "ᯮ«ì§®¢ âì DMA ¤«ï ¤®áâ㯠ª HDD? [1-¤ , 2-⮫쪮 ç⥨¥, 3-¥â]: ",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,mode1,mode2,mode3 |
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 |
dma_msg db " [b] ᯮ«ì§®¢ ¨¥ DMA ¤«ï ¤®áâ㯠ª HDD:",0 |
on_msg db " ¢ª«",13,10,0 |
off_msg db " ¢ëª«",13,10,0 |
readonly_msg db " ⮫쪮 ç⥨¥",13,10,0 |
vrrm_msg db " [c] ᯮ«ì§®¢ ¨¥ VRR:",0 |
preboot_device_msg db " [d] ¡à § ¤¨áª¥âë: ",0 |
preboot_device_msgs dw 0,pdm1,pdm2,pdm3 |
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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/boot/preboot.inc |
---|
0,0 → 1,31 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
display_modechg db 0 ; display mode change for text, yes/no (0 or 2) |
; |
; !! Important note !! |
; |
; Must be set to 2, to avoid two screenmode |
; changes within a very short period of time. |
display_atboot db 0 ; show boot screen messages ( 2-no ) |
preboot_graph 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_dma db 0 ; use DMA for access to HDD (1-always, 2-only for read, 3-never) |
preboot_device db 0 ; boot device |
; (1-floppy 2-harddisk 3-kernel restart) |
;!!!! 0 - autodetect !!!! |
preboot_blogesc db 1 ; start immediately after bootlog |
if $>0x200 |
ERROR: prebooting parameters must fit in first sector!!! |
end if |
hdsysimage db 'KOLIBRI IMG' ; load from |
image_save db 'KOLIBRI IMG' ; save to |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/boot/rdload.inc |
---|
0,0 → 1,102 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; READ RAMDISK IMAGE FROM HD |
cmp [boot_dev+OS_BASE+0x10000],1 |
jne no_sys_on_hd |
test [DRIVE_DATA+1],byte 0x40 |
jz position_2 |
mov [hdbase],0x1f0 |
mov [hdid],0x0 |
mov [hdpos],1 |
mov [fat32part],0 |
position_1_1: |
inc [fat32part] |
call search_and_read_image |
cmp [image_retrieved],1 |
je yes_sys_on_hd |
movzx eax,byte [DRIVE_DATA+2] |
cmp [fat32part],eax |
jle position_1_1 |
position_2: |
test [DRIVE_DATA+1],byte 0x10 |
jz position_3 |
mov [hdbase],0x1f0 |
mov [hdid],0x10 |
mov [hdpos],2 |
mov [fat32part],0 |
position_2_1: |
inc [fat32part] |
call search_and_read_image |
cmp [image_retrieved],1 |
je yes_sys_on_hd |
movzx eax,byte [DRIVE_DATA+3] |
cmp eax,[fat32part] |
jle position_2_1 |
position_3: |
test [DRIVE_DATA+1],byte 0x4 |
jz position_4 |
mov [hdbase],0x170 |
mov [hdid],0x0 |
mov [hdpos],3 |
mov [fat32part],0 |
position_3_1: |
inc [fat32part] |
call search_and_read_image |
cmp [image_retrieved],1 |
je yes_sys_on_hd |
movzx eax,byte [DRIVE_DATA+4] |
cmp eax,[fat32part] |
jle position_3_1 |
position_4: |
test [DRIVE_DATA+1],byte 0x1 |
jz no_sys_on_hd |
mov [hdbase],0x170 |
mov [hdid],0x10 |
mov [hdpos],4 |
mov [fat32part],0 |
position_4_1: |
inc [fat32part] |
call search_and_read_image |
cmp [image_retrieved],1 |
je yes_sys_on_hd |
movzx eax,byte [DRIVE_DATA+5] |
cmp eax,[fat32part] |
jle position_4_1 |
jmp yes_sys_on_hd |
search_and_read_image: |
call set_FAT32_variables |
mov edx, bootpath |
call read_image |
test eax, eax |
jz image_present |
mov edx, bootpath2 |
call read_image |
test eax, eax |
jz image_present |
ret |
image_present: |
mov [image_retrieved],1 |
ret |
read_image: |
mov eax, hdsysimage+OS_BASE+0x10000 |
mov ebx, 1474560/512 |
mov ecx, RAMDISK |
mov esi, 0 |
mov edi, 12 |
call file_read |
ret |
image_retrieved db 0 |
counter_of_partitions db 0 |
no_sys_on_hd: |
yes_sys_on_hd: |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/boot/ru.inc |
---|
0,0 → 1,93 |
$Revision$ |
; Generated by RUFNT.EXE |
; By BadBugsKiller (C) |
; Modifyed by BadBugsKiller 12.01.2004 17:45 |
; Øðèôò óìåíüøåí â ðàçìåðå è òåïåðü ñîñòîèò èç 2-óõ ÷àñòåé, |
; ñîäåðæàùèõ òîëüêî ñèìâîëû ðóññêîãî àëôàâèòà. |
; ñèìâîëû â êîäèðîâêå ASCII (ÄÎÑ'îâñêàÿ), êîäîâàÿ ñòàíèöà 866. |
RU_FNT1: |
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0x62, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0x81, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x7E, 0x7E, 0x5A, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCF, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x7C, 0x38, 0x38, 0x7C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 |
db 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFF, 0x03, 0x03, 0x00, 0x00 |
db 0x00, 0x00, 0xF8, 0xF0, 0xB0, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xF3, 0xDB, 0xDB, 0xDB, 0xDB, 0xF3, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x26, 0x3E, 0x26, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x3F, 0x66, 0x66, 0x66, 0x3E, 0x3E, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x02, 0x06, 0x7C, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x62, 0x62, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xFF, 0xC3, 0xC3, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0x54, 0x7C, 0x54, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xCE, 0xD6, 0xE6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x36, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00 |
RU_FNT2: |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 |
db 0x00, 0x00, 0x00, 0x3C, 0x18, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x18, 0x18, 0x3C, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xFF, 0x03, 0x03, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xFE, 0x03, 0x03, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB0, 0xB0, 0x3E, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xF6, 0xDE, 0xDE, 0xF6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x3E, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0xDB, 0xDB, 0xFB, 0xDB, 0xDB, 0xCE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC6, 0xC6, 0x7E, 0x36, 0x66, 0xE7, 0x00, 0x00, 0x00, 0x00 |
db 0x6C, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x7C, 0xC6, 0xC6, 0xFC, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC8, 0xF8, 0xC8, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xF8, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x66, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x6C, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00 |
db 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x6C, 0x38, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0xC6, 0x7C, 0x00 |
db 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0xCF, 0xCD, 0xEF, 0xEC, 0xFF, 0xDC, 0xDC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00 |
db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/boot/shutdown.inc |
---|
0,0 → 1,274 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; Shutdown for Menuet ;; |
;; ;; |
;; Distributed under General Public License ;; |
;; See file COPYING for details. ;; |
;; Copyright 2003 Ville Turjanmaa ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
pr_mode_exit: |
; setup stack |
mov ax, 0x3000 |
mov ss, ax |
mov esp, 0x0EC00 |
; setup ds |
push cs |
pop ds |
lidt [old_ints_h] |
;remap IRQs |
mov al,0x11 |
out 0x20,al |
call rdelay |
out 0xA0,al |
call rdelay |
mov al,0x08 |
out 0x21,al |
call rdelay |
mov al,0x70 |
out 0xA1,al |
call rdelay |
mov al,0x04 |
out 0x21,al |
call rdelay |
mov al,0x02 |
out 0xA1,al |
call rdelay |
mov al,0x01 |
out 0x21,al |
call rdelay |
out 0xA1,al |
call rdelay |
mov al,0xB8 |
out 0x21,al |
call rdelay |
mov al,0xBD |
out 0xA1,al |
sti |
temp_3456: |
xor ax,ax |
mov es,ax |
mov al,byte [es:0x9030] |
cmp al,1 |
jl nbw |
cmp al,4 |
jle nbw32 |
nbw: |
in al,0x60 |
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 |
floppy_write: ; write diskette image to physical floppy |
cmp [flm],byte 1 |
je fwwritedone |
mov [flm],byte 1 |
xor ax, ax ; reset drive |
xor dx, dx |
int 0x13 |
mov cx,0x0001 ; startcyl,startsector |
xor dx, dx ; starthead,drive |
mov ax, 80*2 ; read no of sect |
fwwrites: |
push ax |
; move 1mb+ -> 0:a000 |
pusha |
mov si, fwmovedesc |
mov cx,256*18 |
mov ah,0x87 |
push ds |
pop es |
int 0x15 |
add dword [fwmovedesc+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 |
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 |
restart_kernel: |
mov ax,0x0003 ; set text mode for screen |
int 0x10 |
jmp 0x4000:0000 |
restart_kernel_4000: |
cli |
push ds |
pop es |
mov cx, 0x8000 |
push cx |
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 al, 00110100b |
out 43h, al |
jcxz $+2 |
mov al, 0xFF |
out 40h, al |
jcxz $+2 |
out 40h, al |
jcxz $+2 |
sti |
; (hint by Black_mirror) |
; We must read data from keyboard port, |
; because there may be situation when previous keyboard interrupt is lost |
; (due to return to real mode and IRQ reprogramming) |
; and next interrupt will not be generated (as keyboard waits for handling) |
in al, 0x60 |
; bootloader interface |
push 0x1000 |
pop ds |
mov si, kernel_restart_bootblock |
mov ax, 'KL' |
jmp 0x1000:0000 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/boot/bootstr.inc |
---|
0,0 → 1,52 |
; boot data: common strings (for all languages) |
macro line_full_top { |
db 201 |
times 78 db 205 |
db 187 |
} |
macro line_full_bottom { |
db 200 |
times 78 db 205 |
db 188 |
} |
macro line_half { |
db 186,' ' |
times 76 db 0xc4 |
db ' ',186 |
} |
macro line_space { |
db 186 |
times 78 db 32 |
db 186 |
} |
d80x25_top: |
line_full_top |
cur_line_pos = 75 |
store byte ' ' at d80x25_top+cur_line_pos+1 |
rev_var = __REV__ |
while rev_var > 0 |
store byte rev_var mod 10 + '0' at d80x25_top+cur_line_pos |
cur_line_pos = cur_line_pos - 1 |
rev_var = rev_var / 10 |
end while |
store byte ' ' at d80x25_top+cur_line_pos |
store dword ' SVN' at d80x25_top+cur_line_pos-4 |
space_msg: line_space |
verstr: |
; line_space |
; version string |
db 186,32 |
repeat 78 |
load a byte from version+%-1 |
if a = 13 |
break |
end if |
db a |
end repeat |
repeat 78 - ($-verstr) |
db ' ' |
end repeat |
db 32,186 |
line_half |
d80x25_top_num = 4 |
/kernel/tags/kolibri0.7.0.0/boot/et.inc |
---|
0,0 → 1,7 |
$Revision$ |
; Full ASCII code font |
; only õ and ä added |
; Kaitz |
ET_FNT: |
fontfile file "ETFONT.FNT" |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/boot/ETFONT.FNT |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/eth_drv/ethernet.inc |
---|
0,0 → 1,475 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; 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 |
; |
;******************************************************************** |
ETHER_IP equ 0x0008 ; Reversed from 0800 for intel |
ETHER_ARP equ 0x0608 ; Reversed from 0806 for intel |
ETHER_RARP equ 0x3580 |
struc ETH_FRAME |
{ .DstMAC dp ? ;destination MAC-address [6 bytes] |
.SrcMAC dp ? ;source MAC-address [6 bytes] |
.Type dw ? ;type of the upper-layer protocol [2 bytes] |
.Data db ? ;data [46-1500 bytes] |
} |
virtual at Ether_buffer |
ETH_FRAME ETH_FRAME |
end virtual |
; Some useful information on data structures |
; Ethernet Packet - ARP Request example |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
; |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Dest H/W Address | |
; | ( 14 byte header ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | Source H/W Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Protocol - ARP 08 06 | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | H/W Type 00 01 | Protocol Type 08 00 | |
; | ( ARP Request packet ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | HLen 0x06 | PLen 0x04 | OpCode 00 01 | |
; | ( 0001 for request, 0002 for reply ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Source Hardware Address ( MAC Address ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | Source IP Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | Destination Hardware Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Destination IP Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; Include individual drivers source files at this point. |
; If you create a new driver, include it below. |
include "drivers/rtl8029.inc" |
include "drivers/i8255x.inc" |
include "drivers/rtl8139.inc" |
include "drivers/3c59x.inc" |
include "drivers/sis900.inc" |
include "drivers/pcnet32.inc" |
include "drivers/rtl8169.inc" |
; PCICards |
; ======== |
; PCI vendor and hardware types for hardware supported by the above drivers |
; If you add a driver, ensure you update this datastructure, otherwise the |
; card will not be probed. |
; Each driver is defined by 4 double words. These are |
; PCIVendorDevice probeFunction ResetFunction PollFunction transmitFunction |
; The last entry must be kept at all zeros, to indicate the end of the list |
; As a PCI driver may support more than one hardware implementation, there may |
; be several lines which refer to the same functions. |
; The first driver found on the PCI bus will be the one used. |
PCICARDS_ENTRY_SIZE equ 24 ; Size of each PCICARDS entry |
iglobal |
PCICards: |
dd 0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 |
dd 0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 |
dd 0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 |
dd 0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 |
dd 0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit, 0 |
dd 0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit, 0 |
dd 0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable ; tested by hidnplayr: works ok |
dd 0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable ; tested by hidnplayr: works ok |
dd 0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit, rtl8139_cable |
dd 0x816810ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 |
dd 0x816910ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 |
dd 0x011616ec, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 |
dd 0x43001186, rtl8169_probe, rtl8169_reset, rtl8169_poll, rtl8169_transmit, 0 |
dd 0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit, 0 |
dd 0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0 |
dd 0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 |
dd 0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 |
dd 0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit, 0 |
;dd 0x08031516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable |
; following cards are untested |
dd 0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit, 0 |
;dd 0x08001516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable |
;dd 0x08911516, mtd80x_probe, mtd80x_reset, mtd80x_poll, mtd80x_transmit, mtd80x_cable |
rb PCICARDS_ENTRY_SIZE ; end of list marker, do not remove |
endg |
uglobal |
;Net-stack's interface's settings |
node_addr: db 0,0,0,0,0,0 |
gateway_ip: dd 0 |
dns_ip: dd 0 |
eth_rx_data_len: dw 0 |
eth_status: dd 0 |
io_addr: dd 0 |
hdrtype: db 0 |
vendor_device: dd 0 |
pci_data: dd 0 |
pci_dev: dd 0 |
pci_bus: dd 0 |
; These will hold pointers to the selected driver functions |
drvr_probe: dd 0 |
drvr_reset: dd 0 |
drvr_poll: dd 0 |
drvr_transmit: dd 0 |
drvr_cable: dd 0 |
endg |
iglobal |
broadcast_add: db 0xff,0xff,0xff,0xff,0xff,0xff |
subnet_mask: dd 0x00ffffff ; 255.255.255.0 |
endg |
include "arp.inc" ;arp-protocol functions |
include "pci.inc" ;PCI bus access functions |
;*************************************************************************** |
; Function |
; eth_tx |
; |
; Description |
; Looks at the NET1OUT_QUEUE for data to send. |
; Stores that destination IP in a location used by the tx routine |
; Looks up the MAC address in the ARP table; stores that where |
; the tx routine can get it |
; Get the length of the data. Store that where the tx routine wants it |
; Call tx |
; Places buffer on empty queue when the tx routine finished |
; |
;*************************************************************************** |
proc eth_tx stdcall uses ebx esi edi |
local MACAddress dp ? ;allocate 6 bytes in the stack |
; Look for a buffer to tx |
mov eax, NET1OUT_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je .exit ; Exit if no buffer available |
push eax ;save buffer number |
; convert buffer pointer eax to the absolute address |
imul eax, IPBUFFSIZE |
add eax, IPbuffs |
; Extract the destination IP |
; find the destination IP in the ARP table, get MAC |
; store this MAC in 'MACAddress' |
mov ebx, eax ; Save buffer address |
mov edx, [ebx + 16] ; get destination address |
; If the destination address is 255.255.255.255, |
; set the MACAddress to all ones ( broadcast ) |
cld |
mov esi, broadcast_add |
lea edi, [MACAddress] |
movsd |
movsw |
cmp edx, 0xffffffff |
je .send ; If it is broadcast, just send |
; first, check destination IP to see if it is on 'this' network. |
; The test is: |
; if ( destIP & subnet_mask == stack_ip & subnet_mask ) |
; destination is local |
; else |
; destination is remote, so pass to gateway |
mov eax, edx |
and eax, [subnet_mask] |
mov ecx, [stack_ip] |
and ecx, [subnet_mask] |
cmp eax, ecx |
je .local |
mov edx, [gateway_ip] |
.local: |
lea eax, [MACAddress] ;cause this is local variable |
stdcall arp_table_manager, ARP_TABLE_IP_TO_MAC, edx, eax ;opcode,IP,MAC_ptr - Get the MAC address. |
cmp eax, ARP_VALID_MAPPING |
je .send |
; No valid entry. Has the request been sent, but timed out? |
cmp eax, ARP_RESPONSE_TIMEOUT |
je .freebuf |
.wait_response: ;we wait arp-response |
; Re-queue the packet, and exit |
pop ebx |
mov eax, NET1OUT_QUEUE |
call queue ; Get the buffer back |
jmp .exit |
.send: ;if ARP_VALID_MAPPING then send the packet |
lea edi, [MACAddress] ; Pointer to 48 bit destination address |
movzx ecx, word[ebx+2] ; Size of IP packet to send |
xchg ch, cl ; because mirror byte-order |
mov esi, ebx ; Pointer to packet data |
mov bx, ETHER_IP ; Type of packet |
push ebp |
call dword [drvr_transmit] ; Call the drivers transmit function |
pop ebp |
; OK, we have sent a packet, so increment the count |
inc dword [ip_tx_count] |
; And finally, return the buffer to the free queue |
.freebuf: |
pop eax |
call freeBuff |
.exit: |
ret |
endp |
;*************************************************************************** |
; Function |
; ether_IP_handler |
; |
; Description |
; Called when an IP ethernet packet is received on the ethernet |
; Header + Data is in Ether_buffer[] |
; We just need to get a buffer from the 'free' queue, and |
; store the packet in it, then insert the packet number into the |
; IPRX queue. |
; If no queue entry is available, the packet is silently discarded |
; All registers may be destroyed |
; |
;*************************************************************************** |
ether_IP_handler: |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je eiph00x |
; convert buffer pointer eax to the absolute address |
push eax |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov edi, eax |
; get a pointer to the start of the DATA |
mov esi, ETH_FRAME.Data |
; Now store it all away |
mov ecx, IPBUFFSIZE / 4 ; Copy all of the available |
; data across - worse case |
cld |
rep movsd |
; And finally, place the buffer in the IPRX queue |
pop ebx |
mov eax, IPIN_QUEUE |
call queue |
eiph00x: |
ret |
;*************************************************************************** |
; Function |
; eth_probe |
; Description |
; Searches for an ethernet card. If found, the card is enabled and |
; the ethernet -> IP link established |
; |
; This function scans the PCI bus looking for a supported device. |
; ISA bus is currently not supported. |
; |
; eax is 0 if no hardware found |
;*************************************************************************** |
eth_probe: |
; Find a card on the PCI bus, and get it's address |
call scan_bus ; Find the ethernet cards PIC address |
xor eax, eax |
cmp [io_addr], eax |
je ep_00x ; Return 0 in eax if no cards found |
call dword [drvr_probe] ; Call the drivers probe function |
mov eax, [io_addr] ; return a non zero value |
ep_00x: |
ret |
;*************************************************************************** |
; Function |
; ethernet_driver |
; |
; Description |
; The ethernet RX and TX handler |
; This is a kernel function, called by stack_handler |
; |
;*************************************************************************** |
ethernet_driver: |
; Do nothing if the driver is inactive |
cmp [ethernet_active], byte 0 |
je eth_exit |
call eth_rx |
call eth_tx |
eth_exit: |
ret |
;*************************************************************************** |
; Function |
; eth_rx |
; |
; Description |
; Polls the ethernet card for received data. Extracts if present |
; Depending on the Protocol within the packet: |
; ARP : Pass to ARP_handler. This may result in an ARP reply |
; being tx'ed |
; IP : Store in an IP buffer |
; |
;*************************************************************************** |
eth_rx: |
xor ax, ax |
mov [eth_rx_data_len], ax |
call dword [drvr_poll] ; Call the drivers poll function |
mov ax, [eth_rx_data_len] |
cmp ax, 0 |
je .exit |
; Check the protocol. Call appropriate handler |
mov ax, [ETH_FRAME.Type] ; The address of the protocol word |
cmp ax, ETHER_IP |
je .is_ip ; It's IP |
cmp ax, ETHER_ARP |
je .is_arp ; It is ARP |
jmp .exit ; If not IP or ARP, ignore |
.is_ip: |
DEBUGF 1,"K : eth_rx - IP packet\n" |
inc dword [ip_rx_count] |
call ether_IP_handler |
jmp .exit |
.is_arp: |
DEBUGF 1,"K : eth_rx - ARP packet\n" |
; At this point, the packet is still in the Ether_buffer |
call arp_handler |
.exit: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/eth_drv/arp.inc |
---|
0,0 → 1,534 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ARP.INC ;; |
;; ;; |
;; Address Resolution Protocol ;; |
;; ;; |
;; Last revision: 10.11.2006 ;; |
;; ;; |
;; This file contains the following: ;; |
;; arp_table_manager - Manages an ARPTable ;; |
;; arp_request - Sends an ARP request on the ethernet ;; |
;; arp_handler - Called when an ARP packet is received ;; |
;; ;; |
;; Changes history: ;; |
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; |
;; 11.11.2006 - [Johnny_B] and [smb] ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
ARP_NO_ENTRY equ 0 |
ARP_VALID_MAPPING equ 1 |
ARP_AWAITING_RESPONSE equ 2 |
ARP_RESPONSE_TIMEOUT equ 3 |
struc ARP_ENTRY ;=14 bytes |
{ .IP dd ? ;+00 |
.MAC dp ? ;+04 |
.Status dw ? ;+10 |
.TTL dw ? ;+12 : ( in seconds ) |
} |
virtual at 0 |
ARP_ENTRY ARP_ENTRY |
end virtual |
; The TTL field is decremented every second, and is deleted when it |
; reaches 0. It is refreshed every time a packet is received |
; If the TTL field is 0xFFFF it is a static entry and is never deleted |
; The status field can be the following values: |
; 0x0000 entry not used |
; 0x0001 entry holds a valid mapping |
; 0x0002 entry contains an IP address, awaiting ARP response |
; 0x0003 No response received to ARP request. |
; The last status value is provided to allow the network layer to delete |
; a packet that is queued awaiting an ARP response |
; The follow is the ARP Table. |
; This table must be manually updated and the kernel recompilied if |
; changes are made to it. |
; Empty entries are filled with zeros |
ARP_ENTRY_SIZE equ 14 ; Number of bytes per entry |
ARP_TABLE_SIZE equ 20 ; Size of table |
ARP_TABLE_ENTRIES equ 0 ; Number of static entries in the table |
;TO ADD A STATIC ENTRY, DONT FORGET, PUT "ARPTable" from "uglobal" to "iglobal"!!! |
;AND ALSO - IP and MAC have net byte-order, BUT STATUS AND TTL HAVE A MIRROR BYTE-ORDER!!! |
uglobal |
ARPTable: |
;example, static entry -> db 11,22,33,44, 0x11,0x22,0x33,0x44,0x55,0x66, 0x01,0x00, 0xFF,0xFF |
times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE db 0 |
endg |
iglobal |
NumARP: dd ARP_TABLE_ENTRIES |
ARPTable_ptr dd ARPTable ;pointer to ARPTable |
endg |
ARP_REQ_OPCODE equ 0x0100 ;request |
ARP_REP_OPCODE equ 0x0200 ;reply |
struc ARP_PACKET |
{ .HardwareType dw ? ;+00 |
.ProtocolType dw ? ;+02 |
.HardwareSize db ? ;+04 |
.ProtocolSize db ? ;+05 |
.Opcode dw ? ;+06 |
.SenderMAC dp ? ;+08 |
.SenderIP dd ? ;+14 |
.TargetMAC dp ? ;+18 |
.TargetIP dd ? ;+24 |
} |
virtual at 0 |
ARP_PACKET ARP_PACKET |
end virtual |
;*************************************************************************** |
; Function |
; arp_table_manager [by Johnny_B] |
; |
; Description |
; Does a most required operations with ARP-table |
; IN: |
; Operation: see Opcode's constants below |
; Index: Index of entry in the ARP-table |
; Extra: Extra parameter for some Opcodes |
; OUT: |
; EAX = Returned value depends on opcodes, more detailed see below |
; |
;*************************************************************************** |
;Opcode's constants |
ARP_TABLE_ADD equ 1 |
ARP_TABLE_DEL equ 2 |
ARP_TABLE_GET equ 3 |
ARP_TABLE_GET_ENTRIES_NUMBER equ 4 |
ARP_TABLE_IP_TO_MAC equ 5 |
ARP_TABLE_TIMER equ 6 |
;Index's constants |
EXTRA_IS_ARP_PACKET_PTR equ 0 ;if Extra contain pointer to ARP_PACKET |
EXTRA_IS_ARP_ENTRY_PTR equ -1 ;if Extra contain pointer to ARP_ENTRY |
align 4 |
proc arp_table_manager stdcall uses ebx esi edi ecx edx,\ |
Opcode:DWORD,Index:DWORD,Extra:DWORD |
mov ebx, dword[ARPTable_ptr] ;ARPTable base |
mov ecx, dword[NumARP] ;ARP-entries counter |
mov eax, dword[Opcode] |
cmp eax, ARP_TABLE_TIMER |
je .timer |
cmp eax, ARP_TABLE_ADD |
je .add |
cmp eax, ARP_TABLE_DEL |
je .del |
cmp eax, ARP_TABLE_GET |
je .get |
cmp eax, ARP_TABLE_IP_TO_MAC |
je .ip_to_mac |
cmp eax, ARP_TABLE_GET_ENTRIES_NUMBER |
je .get_entries_number |
jmp .exit ;if unknown opcode |
;;BEGIN TIMER |
;;Description: it must be callback every second. It is responsible for removing expired routes. |
;;IN: Operation: ARP_TABLE_TIMER |
;; Index: must be zero |
;; Extra: must be zero |
;;OUT: |
;; EAX=not defined |
;; |
.timer: |
test ecx, ecx |
jz .exit ;if NumARP=0 nothing to do |
sub ecx, ARP_TABLE_ENTRIES ;ecx=dynamic entries number |
jz .exit ;if NumARP=number of static entries then exit |
add ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE ;ebx=dynamic entries base |
.timer_loop: |
movsx esi, word [ebx + ARP_ENTRY.TTL] |
cmp esi, 0xFFFFFFFF |
je .timer_loop_end ;if TTL==0xFFFF then it's static entry |
test esi, esi |
jnz .timer_loop_end_with_dec ;if TTL!=0 |
; Ok, TTL is 0 |
;if Status==AWAITING_RESPONSE and TTL==0 |
;then we have to change it to ARP_RESPONSE_TIMEOUT |
cmp word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
jne @f |
mov word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT |
mov word [ebx + ARP_ENTRY.TTL], word 0x000A ;10 sec |
jmp .timer_loop_end |
@@: |
;if TTL==0 and Status==VALID_MAPPING, we have to delete it |
;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too |
mov esi, dword[NumARP] |
sub esi, ecx ;esi=index of entry, will be deleted |
stdcall arp_table_manager,ARP_TABLE_DEL,esi,0 ;opcode,index,extra |
jmp .timer_loop_end |
.timer_loop_end_with_dec: |
dec word [ebx + ARP_ENTRY.TTL] ;decrease TTL |
.timer_loop_end: |
add ebx, ARP_ENTRY_SIZE |
loop .timer_loop |
jmp .exit |
;;END TIMER |
;;BEGIN ADD |
;;Description: it adds an entry in the table. If ARP-table already |
;; contains same IP, it will be updated. |
;;IN: Operation: ARP_TABLE_ADD |
;; Index: specifies what contains Extra-parameter |
;; Extra: if Index==EXTRA_IS_ARP_PACKET_PTR, |
;; then Extra contains pointer to ARP_PACKET, |
;; otherwise Extra contains pointer to ARP_ENTRY |
;;OUT: |
;; EAX=index of entry, that has been added |
;; |
.add: |
sub esp, ARP_ENTRY_SIZE ;Allocate ARP_ENTRY_SIZE byte in stack |
mov esi, [Extra] ;pointer |
mov edi, [Index] ;opcode |
cmp edi, EXTRA_IS_ARP_PACKET_PTR |
je .arp_packet_to_entry ;if Extra contain ptr to ARP_PACKET and we have to form arp-entry |
;else it contain ptr to arp-entry |
cld |
; esi already has been loaded |
mov edi, esp ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add) |
mov ecx,ARP_ENTRY_SIZE/2 ;ARP_ENTRY_SIZE must be even number!!! |
rep movsw ;copy |
jmp .search |
.arp_packet_to_entry: |
mov edx, dword[esi + ARP_PACKET.SenderIP] ;esi=base of ARP_PACKET |
mov [esp + ARP_ENTRY.IP], edx |
cld |
lea esi, [esi + ARP_PACKET.SenderMAC] |
lea edi, [esp + ARP_ENTRY.MAC] |
movsd |
movsw |
mov word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING ; specify the type - a valid entry |
mov word[esp + ARP_ENTRY.TTL], 0x0E10 ; = 1 hour |
.search: |
mov edx, dword[esp + ARP_ENTRY.IP] ;edx=IP-address, which we'll search |
mov ecx, dword[NumARP] ;ecx=ARP-entries counter |
jecxz .add_to_end ;if ARP-entries number == 0 |
imul eax, ecx, ARP_ENTRY_SIZE ;eax=current table size(in bytes) |
@@: |
sub eax, ARP_ENTRY_SIZE |
cmp dword[ebx + eax + ARP_ENTRY.IP], edx |
loopnz @b |
jz .replace ; found, replace existing entry, ptr to it is in eax |
.add_to_end: |
;else add to end |
or eax,-1 ;set eax=0xFFFFFFFF if adding is impossible |
mov ecx, dword[NumARP] |
cmp ecx, ARP_TABLE_SIZE |
je .add_exit ;if arp-entries number is equal to arp-table maxsize |
imul eax, dword[NumARP], ARP_ENTRY_SIZE ;eax=ptr to end of ARPTable |
inc dword [NumARP] ;increase ARP-entries counter |
.replace: |
cld |
mov esi, esp ;esp=base of ARP-entry, that will be added |
lea edi, [ebx + eax] ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add) |
mov ecx,ARP_ENTRY_SIZE/2 ;ARP_ENTRY_SIZE must be even number!!! |
rep movsw |
mov ecx, ARP_ENTRY_SIZE |
xor edx, edx ;"div" takes operand from EDX:EAX |
div ecx ;eax=index of entry, which has been added |
.add_exit: |
add esp, ARP_ENTRY_SIZE ;free stack |
jmp .exit |
;;END ADD |
;;BEGIN DEL |
;;Description: it deletes an entry in the table. |
;;IN: Operation: ARP_TABLE_DEL |
;; Index: index of entry, that should be deleted |
;; Extra: must be zero |
;;OUT: |
;; EAX=not defined |
;; |
.del: |
mov esi, [Index] |
imul esi, ARP_ENTRY_SIZE |
mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE |
sub ecx, esi |
lea edi, [ebx + esi] ;edi=ptr to entry that should be deleted |
lea esi, [edi + ARP_ENTRY_SIZE] ;esi=ptr to next entry |
shr ecx,1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER! |
cld |
rep movsw |
dec dword[NumARP] ;decrease arp-entries counter |
jmp .exit |
;;END DEL |
;;BEGIN GET |
;;Description: it reads an entry of table into buffer. |
;;IN: Operation: ARP_TABLE_GET |
;; Index: index of entry, that should be read |
;; Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE) |
;;OUT: |
;; EAX=not defined |
;; |
.get: |
mov esi, [Index] |
imul esi, ARP_ENTRY_SIZE ;esi=ptr to required ARP_ENTRY |
mov edi, [Extra] ;edi=buffer for reading |
mov ecx, ARP_ENTRY_SIZE/2 ; must be even number!!! |
cld |
rep movsw |
jmp .exit |
;;END GET |
;;BEGIN IP_TO_MAC |
;;Description: it gets an IP from Index, scans each entry in the table and writes |
;; MAC, that relates to specified IP, into buffer specified in Extra. |
;; And if it cannot find an IP-address in the table, it does an ARP-request of that. |
;;IN: Operation: ARP_TABLE_IP_TO_MAC |
;; Index: IP that should be transformed into MAC |
;; Extra: pointer to buffer where will be written the MAC-address. |
;;OUT: |
;; EAX=ARP table entry status code. |
;; If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request. |
;; If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system. |
;; If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long. |
;; If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC. |
;; |
;; If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet |
;; resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this |
;; function with 1sec delay. sure, only if it not return a valid MAC after a first call. |
;; |
.ip_to_mac: |
xor eax, eax |
mov edi, dword[Extra] |
cld |
stosd |
stosw |
cmp dword[NumARP], 0 |
je .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP. |
;EAX will be containing a zero, it's equal to ARP_NO_ENTRY |
mov eax, [Index] ;eax=required IP |
mov ecx, dword[NumARP] |
imul esi, ecx, ARP_ENTRY_SIZE ;esi=current ARP-table size |
@@: |
sub esi, ARP_ENTRY_SIZE |
cmp [ebx + esi], eax ; ebx=ARPTable base |
loopnz @b ; Return back if non match |
jnz .ip_to_mac_send_request ; and request IP->MAC if none found in the table |
; Return the entry status in eax |
movzx eax, word[ebx + esi + ARP_ENTRY.Status] |
; esi holds index |
cld |
lea esi, [ebx + esi + ARP_ENTRY.MAC] |
mov edi, [Extra] ;edi=ptr to buffer for write MAC |
movsd |
movsw |
jmp .exit |
.ip_to_mac_send_request: |
stdcall arp_request,[Index],stack_ip,node_addr ;TargetIP,SenderIP_ptr,SenderMAC_ptr |
mov eax, ARP_NO_ENTRY |
jmp .exit |
;;END IP_TO_MAC |
;;BEGIN GET_ENTRIES_NUMBER |
;;Description: returns an ARP-entries number in the ARPTable |
;;IN: Operation: ARP_TABLE_GET_ENTRIES_NUMBER |
;; Index: must be zero |
;; Extra: must be zero |
;;OUT: |
;; EAX=ARP-entries number in the ARPTable |
.get_entries_number: |
mov eax, dword[NumARP] |
jmp .exit |
;;END GET_ENTRIES_NUMBER |
.exit: |
ret |
endp |
;*************************************************************************** |
; Function |
; arp_handler |
; |
; Description |
; Called when an ARP packet is received on the ethernet |
; Header + Data is in Ether_buffer[] |
; It looks to see if the packet is a request to resolve this Hosts |
; IP address. If it is, send the ARP reply packet. |
; This Hosts IP address is in dword [stack_ip] ( in network format ) |
; This Hosts MAC address is in node_addr[6] |
; All registers may be destroyed |
; |
;*************************************************************************** |
arp_handler: |
; Is this a REQUEST? |
; Is this a request for My Host IP |
; Yes - So construct a response message. |
; Send this message to the ethernet card for transmission |
stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_PACKET_PTR,ETH_FRAME.Data + ARP_PACKET |
inc dword[arp_rx_count] ;increase ARP-packets counter |
cmp word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REQ_OPCODE ; Is this a request packet? |
jne .exit ; No - so exit |
mov eax, [stack_ip] |
cmp eax, dword[ETH_FRAME.Data + ARP_PACKET.TargetIP] ; Is it looking for my IP address? |
jne .exit ; No - so quit now |
; OK, it is a request for my MAC address. Build the frame and send it |
; We can reuse the packet. |
mov word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REP_OPCODE |
cld |
mov esi, ETH_FRAME.Data + ARP_PACKET.SenderMAC |
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC |
movsd |
movsw |
mov esi, ETH_FRAME.Data + ARP_PACKET.SenderIP |
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetIP |
movsd |
mov esi, node_addr |
mov edi, ETH_FRAME.Data + ARP_PACKET.SenderMAC |
movsd |
movsw |
mov esi, stack_ip |
mov edi, ETH_FRAME.Data + ARP_PACKET.SenderIP |
movsd |
; Now, send it! |
mov edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC ;ptr to destination MAC address |
mov bx, ETHER_ARP ;type of protocol |
mov ecx, 28 ;data size |
mov esi, ETH_FRAME.Data + ARP_PACKET ;ptr to data |
call dword [drvr_transmit] ;transmit packet |
.exit: |
ret |
;*************************************************************************** |
; Function |
; arp_request [by Johnny_B] |
; |
; Description |
; Sends an ARP request on the ethernet |
; IN: |
; TargetIP : requested IP address |
; SenderIP_ptr : POINTER to sender's IP address(our system's address) |
; SenderMAC_ptr : POINTER to sender's MAC address(our system's address) |
; OUT: |
; EAX=0 (if all is ok), otherwise EAX is not defined |
; |
; EBX,ESI,EDI will be saved |
; |
;*************************************************************************** |
proc arp_request stdcall uses ebx esi edi,\ |
TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD |
inc dword[arp_tx_count] ; increase counter |
sub esp, 28 ; allocate memory for ARP_PACKET |
mov word[esp + ARP_PACKET.HardwareType],0x0100 ;Ethernet |
mov word[esp + ARP_PACKET.ProtocolType],0x0008 ;IP |
mov byte[esp + ARP_PACKET.HardwareSize],0x06 ;MAC-addr length |
mov byte[esp + ARP_PACKET.ProtocolSize],0x04 ;IP-addr length |
mov word[esp + ARP_PACKET.Opcode],0x0100 ;Request |
cld |
mov esi,[SenderMAC_ptr] |
lea edi,[esp + ARP_PACKET.SenderMAC] ;Our MAC-addr |
movsd |
movsw |
mov esi,[SenderIP_ptr] |
lea edi,[esp + ARP_PACKET.SenderIP] ;Our IP-addr |
movsd |
xor eax, eax |
lea edi, [esp + ARP_PACKET.TargetMAC] ;Required MAC-addr(zeroed) |
stosd |
stosw |
mov esi, dword[TargetIP] |
mov dword[esp + ARP_PACKET.TargetIP],esi ;Required IP-addr(we get it as function parameter) |
; Now, send it! |
mov edi, broadcast_add ; Pointer to 48 bit destination address |
mov bx, ETHER_ARP ; Type of packet |
mov ecx, 28 ; size of packet |
lea esi, [esp + ARP_PACKET]; pointer to packet data |
call dword [drvr_transmit] ; Call the drivers transmit function |
add esp, 28 ; free memory, allocated before for ARP_PACKET |
; Add an entry in the ARP table, awaiting response |
sub esp, ARP_ENTRY_SIZE ;allocate memory for ARP-entry |
mov esi, dword[TargetIP] |
mov dword[esp + ARP_ENTRY.IP],esi |
lea edi, [esp + ARP_ENTRY.MAC] |
xor eax, eax |
stosd |
stosw |
mov word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
mov word[esp + ARP_ENTRY.TTL], 0x000A ; 10 seconds |
stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp |
add esp, ARP_ENTRY_SIZE ; free memory |
.exit: |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/eth_drv/drivers/rtl8139.inc |
---|
0,0 → 1,618 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; RTL8139.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.2 11 August 2003 ;; |
;; ;; |
;; Driver for chips of RealTek 8139 family ;; |
;; References: ;; |
;; www.realtek.com.hw - data sheets ;; |
;; rtl8139.c - linux driver ;; |
;; 8139too.c - linux driver ;; |
;; ethernet driver template by Mike Hibbett ;; |
;; ;; |
;; The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; Copyright 2003 Endre Kozma, ;; |
;; endre.kozma@axelero.hu ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; 10.01.2007 Bugfix for l8139_transmit from Paolo Franchetti ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
ETH_ALEN equ 6 |
ETH_HLEN equ (2 * ETH_ALEN + 2) |
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for |
; mininmum 64bytes frame length |
PCI_REG_COMMAND equ 0x04 ; command register |
PCI_BIT_PIO equ 0 ; bit0: io space control |
PCI_BIT_MMIO equ 1 ; bit1: memory space control |
PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master |
RTL8139_REG_MAR0 equ 0x08 ; multicast filter register 0 |
RTL8139_REG_MAR4 equ 0x0c ; multicast filter register 4 |
RTL8139_REG_TSD0 equ 0x10 ; transmit status of descriptor |
RTL8139_REG_TSAD0 equ 0x20 ; transmit start address of descriptor |
RTL8139_REG_RBSTART equ 0x30 ; RxBuffer start address |
RTL8139_REG_COMMAND equ 0x37 ; command register |
RTL8139_REG_CAPR equ 0x38 ; current address of packet read |
RTL8139_REG_IMR equ 0x3c ; interrupt mask register |
RTL8139_REG_ISR equ 0x3e ; interrupt status register |
RTL8139_REG_TXCONFIG equ 0x40 ; transmit configuration register |
RTL8139_REG_TXCONFIG_0 equ 0x40 ; transmit configuration register 0 |
RTL8139_REG_TXCONFIG_1 equ 0x41 ; transmit configuration register 1 |
RTL8139_REG_TXCONFIG_2 equ 0x42 ; transmit configuration register 2 |
RTL8139_REG_TXCONFIG_3 equ 0x43 ; transmit configuration register 3 |
RTL8139_REG_RXCONFIG equ 0x44 ; receive configuration register 0 |
RTL8139_REG_RXCONFIG_0 equ 0x44 ; receive configuration register 0 |
RTL8139_REG_RXCONFIG_1 equ 0x45 ; receive configuration register 1 |
RTL8139_REG_RXCONFIG_2 equ 0x46 ; receive configuration register 2 |
RTL8139_REG_RXCONFIG_3 equ 0x47 ; receive configuration register 3 |
RTL8139_REG_MPC equ 0x4c ; missed packet counter |
RTL8139_REG_9346CR equ 0x50 ; serial eeprom 93C46 command register |
RTL8139_REG_CONFIG1 equ 0x52 ; configuration register 1 |
RTL8139_REG_CONFIG4 equ 0x5a ; configuration register 4 |
RTL8139_REG_HLTCLK equ 0x5b ; undocumented halt clock register |
RTL8139_REG_BMCR equ 0x62 ; basic mode control register |
RTL8139_REG_ANAR equ 0x66 ; auto negotiation advertisement register |
; 5.1 packet header |
RTL8139_BIT_RUNT equ 4 ; total packet length < 64 bytes |
RTL8139_BIT_LONG equ 3 ; total packet length > 4k |
RTL8139_BIT_CRC equ 2 ; crc error occured |
RTL8139_BIT_FAE equ 1 ; frame alignment error occured |
RTL8139_BIT_ROK equ 0 ; received packet is ok |
; 5.4 command register |
RTL8139_BIT_RST equ 4 ; reset bit |
RTL8139_BIT_RE equ 3 ; receiver enabled |
RTL8139_BIT_TE equ 2 ; transmitter enabled |
RTL8139_BIT_BUFE equ 0 ; rx buffer is empty, no packet stored |
; 5.6 interrupt status register |
RTL8139_BIT_ISR_TOK equ 2 ; transmit ok |
RTL8139_BIT_ISR_RER equ 1 ; receive error interrupt |
RTL8139_BIT_ISR_ROK equ 0 ; receive ok |
; 5.7 transmit configyration register |
RTL8139_BIT_TX_MXDMA equ 8 ; Max DMA burst size per Tx DMA burst |
RTL8139_BIT_TXRR equ 4 ; Tx Retry count 16+(TXRR*16) |
; 5.8 receive configuration register |
RTL8139_BIT_RXFTH equ 13 ; Rx fifo threshold |
RTL8139_BIT_RBLEN equ 11 ; Ring buffer length indicator |
RTL8139_BIT_RX_MXDMA equ 8 ; Max DMA burst size per Rx DMA burst |
RTL8139_BIT_NOWRAP equ 7 ; transfered data wrapping |
RTL8139_BIT_9356SEL equ 6 ; eeprom selector 9346/9356 |
RTL8139_BIT_AER equ 5 ; accept error packets |
RTL8139_BIT_AR equ 4 ; accept runt packets |
RTL8139_BIT_AB equ 3 ; accept broadcast packets |
RTL8139_BIT_AM equ 2 ; accept multicast packets |
RTL8139_BIT_APM equ 1 ; accept physical match packets |
RTL8139_BIT_AAP equ 0 ; accept all packets |
; 5.9 93C46/93C56 command register |
RTL8139_BIT_93C46_EEM1 equ 7 ; RTL8139 eeprom operating mode1 |
RTL8139_BIT_93C46_EEM0 equ 6 ; RTL8139 eeprom operating mode0 |
RTL8139_BIT_93C46_EECS equ 3 ; chip select |
RTL8139_BIT_93C46_EESK equ 2 ; serial data clock |
RTL8139_BIT_93C46_EEDI equ 1 ; serial data input |
RTL8139_BIT_93C46_EEDO equ 0 ; serial data output |
; 5.11 configuration register 1 |
RTL8139_BIT_LWACT equ 4 ; see RTL8139_REG_CONFIG1 |
RTL8139_BIT_SLEEP equ 1 ; sleep bit at older chips |
RTL8139_BIT_PWRDWN equ 0 ; power down bit at older chips |
RTL8139_BIT_PMEn equ 0 ; power management enabled |
; 5.14 configuration register 4 |
RTL8139_BIT_LWPTN equ 2 ; see RTL8139_REG_CONFIG4 |
; 6.2 transmit status register |
RTL8139_BIT_ERTXTH equ 16 ; early TX threshold |
RTL8139_BIT_TOK equ 15 ; transmit ok |
RTL8139_BIT_OWN equ 13 ; tx DMA operation is completed |
; 6.18 basic mode control register |
RTL8139_BIT_ANE equ 12 ; auto negotiation enable |
; 6.20 auto negotiation advertisement register |
RTL8139_BIT_TXFD equ 8 ; 100base-T full duplex |
RTL8139_BIT_TX equ 7 ; 100base-T |
RTL8139_BIT_10FD equ 6 ; 10base-T full duplex |
RTL8139_BIT_10 equ 5 ; 10base-T |
RTL8139_BIT_SELECTOR equ 0 ; binary encoded selector CSMA/CD=00001 |
; RX/TX buffer size |
RTL8139_RBLEN equ 0 ; 0==8K 1==16k 2==32k 3==64k |
RTL8139_RX_BUFFER_SIZE equ (8192 shl RTL8139_RBLEN) |
MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC |
RTL8139_NUM_TX_DESC equ 4 |
RTL8139_TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE * RTL8139_NUM_TX_DESC) |
RTL8139_TXRR equ 8 ; total retries = 16+(TXRR*16) |
RTL8139_TX_MXDMA equ 6 ; 0==16 1==32 2==64 3==128 |
; 4==256 5==512 6==1024 7==2048 |
RTL8139_ERTXTH equ 8 ; in unit of 32 bytes e.g:(8*32)=256 |
RTL8139_RX_MXDMA equ 7 ; 0==16 1==32 2==64 3==128 |
; 4==256 5==512 6==1024 7==unlimited |
RTL8139_RXFTH equ 7 ; 0==16 1==32 2==64 3==128 |
; 4==256 5==512 6==1024 7==no threshold |
RTL8139_RX_CONFIG equ ((RTL8139_RBLEN shl RTL8139_BIT_RBLEN) \ |
or (RTL8139_RX_MXDMA shl RTL8139_BIT_RX_MXDMA) \ |
or (1 shl RTL8139_BIT_NOWRAP) \ |
or (RTL8139_RXFTH shl RTL8139_BIT_RXFTH) \ |
or (1 shl RTL8139_BIT_AB) or (1 shl RTL8139_BIT_APM) \ |
or (1 shl RTL8139_BIT_AER) or (1 shl RTL8139_BIT_AR) \ |
or (1 shl RTL8139_BIT_AM)) |
RTL8139_TX_TIMEOUT equ 30 ; 300 milliseconds timeout |
EE_93C46_REG_ETH_ID equ 7 ; MAC offset |
EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address |
EE_93C56_READ_CMD equ (6 shl 8) ; 110b + 8bit address |
EE_93C46_CMD_LENGTH equ 9 ; start bit + cmd + 6bit address |
EE_93C56_CMD_LENGTH equ 11 ; start bit + cmd + 8bit ddress |
VER_RTL8139 equ 1100000b |
VER_RTL8139A equ 1110000b |
; VER_RTL8139AG equ 1110100b |
VER_RTL8139B equ 1111000b |
VER_RTL8130 equ VER_RTL8139B |
VER_RTL8139C equ 1110100b |
VER_RTL8100 equ 1111010b |
VER_RTL8100B equ 1110101b |
VER_RTL8139D equ VER_RTL8100B |
VER_RTL8139CP equ 1110110b |
VER_RTL8101 equ 1110111b |
IDX_RTL8139 equ 0 |
IDX_RTL8139A equ 1 |
IDX_RTL8139B equ 2 |
IDX_RTL8139C equ 3 |
IDX_RTL8100 equ 4 |
IDX_RTL8139D equ 5 |
IDX_RTL8139D equ 6 |
IDX_RTL8101 equ 7 |
; These two must be 4 byte aligned ( which they are ) |
rtl8139_rx_buff equ eth_data_start |
rtl8139_tx_buff equ rtl8139_rx_buff + (RTL8139_RX_BUFFER_SIZE + MAX_ETH_FRAME_SIZE) |
uglobal |
align 4 |
rtl8139_rx_buff_offset: dd 0 |
curr_tx_desc dd 0 |
endg |
iglobal |
hw_ver_array: db VER_RTL8139, VER_RTL8139A, VER_RTL8139B, VER_RTL8139C |
db VER_RTL8100, VER_RTL8139D, VER_RTL8139CP, VER_RTL8101 |
HW_VER_ARRAY_SIZE = $-hw_ver_array |
endg |
uglobal |
hw_ver_id: db 0 |
endg |
;*************************************************************************** |
; Function |
; rtl8139_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; Destroyed registers |
; eax, ebx, ecx, edx |
; |
;*************************************************************************** |
rtl8139_probe: |
; enable the device |
mov al, 2 |
mov ah, [pci_bus] |
mov bh, [pci_dev] |
mov bl, PCI_REG_COMMAND |
call pci_read_reg |
mov cx, ax |
or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) |
and cl, not (1 shl PCI_BIT_MMIO) |
mov al, 2 |
mov ah, [pci_bus] |
mov bh, [pci_dev] |
mov bl, PCI_REG_COMMAND |
call pci_write_reg |
; get chip version |
mov edx, [io_addr] |
add edx, RTL8139_REG_TXCONFIG_2 |
in ax, dx |
shr ah, 2 |
shr ax, 6 |
and al, 01111111b |
mov ecx, HW_VER_ARRAY_SIZE-1 |
.chip_ver_loop: |
cmp al, [hw_ver_array+ecx] |
je .chip_ver_found |
dec ecx |
jns .chip_ver_loop |
xor cl, cl ; default RTL8139 |
.chip_ver_found: |
mov [hw_ver_id], cl |
; wake up the chip |
mov edx, [io_addr] |
add edx, RTL8139_REG_HLTCLK |
mov al, 'R' ; run the clock |
out dx, al |
; unlock config and BMCR registers |
add edx, RTL8139_REG_9346CR - RTL8139_REG_HLTCLK |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) |
out dx, al |
; enable power management |
add edx, RTL8139_REG_CONFIG1 - RTL8139_REG_9346CR |
in al, dx |
cmp byte [hw_ver_id], IDX_RTL8139B |
jl .old_chip |
; set LWAKE pin to active high (default value). |
; it is for Wake-On-LAN functionality of some motherboards. |
; this signal is used to inform the motherboard to execute a wake-up process. |
; only at newer chips. |
or al, (1 shl RTL8139_BIT_PMEn) |
and al, not (1 shl RTL8139_BIT_LWACT) |
out dx, al |
add edx, RTL8139_REG_CONFIG4 - RTL8139_REG_CONFIG1 |
in al, dx |
and al, not (1 shl RTL8139_BIT_LWPTN) |
out dx, al |
jmp .finish_wake_up |
.old_chip: |
; wake up older chips |
and al, not ((1 shl RTL8139_BIT_SLEEP) or (1 shl RTL8139_BIT_PWRDWN)) |
out dx, al |
.finish_wake_up: |
; lock config and BMCR registers |
xor al, al |
mov edx, [io_addr] |
add edx, RTL8139_REG_9346CR |
out dx, al |
;*************************************************************************** |
; Function |
; rt8139_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; Destroyed registers |
; eax, ebx, ecx, edx |
; |
;*************************************************************************** |
rtl8139_reset: |
mov edx, [io_addr] |
add edx, RTL8139_REG_COMMAND |
mov al, 1 shl RTL8139_BIT_RST |
out dx, al |
mov cx, 1000 ; wait no longer for the reset |
.wait_for_reset: |
in al, dx |
test al, 1 shl RTL8139_BIT_RST |
jz .reset_completed ; RST remains 1 during reset |
dec cx |
jns .wait_for_reset |
.reset_completed: |
; get MAC (hardware address) |
mov ecx, 2 |
.mac_read_loop: |
lea eax, [EE_93C46_REG_ETH_ID+ecx] |
push ecx |
call rtl8139_read_eeprom |
pop ecx |
mov [node_addr+ecx*2], ax |
dec ecx |
jns .mac_read_loop |
; unlock config and BMCR registers |
mov edx, [io_addr] |
add edx, RTL8139_REG_9346CR |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) |
out dx, al |
; initialize multicast registers (no filtering) |
mov eax, 0xffffffff |
add edx, RTL8139_REG_MAR0 - RTL8139_REG_9346CR |
out dx, eax |
add edx, RTL8139_REG_MAR4 - RTL8139_REG_MAR0 |
out dx, eax |
; enable Rx/Tx |
mov al, (1 shl RTL8139_BIT_RE) or (1 shl RTL8139_BIT_TE) |
add edx, RTL8139_REG_COMMAND - RTL8139_REG_MAR4 |
out dx, al |
; 32k Rxbuffer, unlimited dma burst, no wrapping, no rx threshold |
; accept broadcast packets, accept physical match packets |
mov ax, RTL8139_RX_CONFIG |
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND |
out dx, ax |
; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144 |
mov ax, (RTL8139_TX_MXDMA shl RTL8139_BIT_TX_MXDMA) \ |
or (RTL8139_TXRR shl RTL8139_BIT_TXRR) |
add edx, RTL8139_REG_TXCONFIG - RTL8139_REG_RXCONFIG |
out dx, ax |
; enable auto negotiation |
add edx, RTL8139_REG_BMCR - RTL8139_REG_TXCONFIG |
in ax, dx |
or ax, (1 shl RTL8139_BIT_ANE) |
out dx, ax |
; set auto negotiation advertisement |
add edx, RTL8139_REG_ANAR - RTL8139_REG_BMCR |
in ax, dx |
or ax, (1 shl RTL8139_BIT_SELECTOR) or (1 shl RTL8139_BIT_10) \ |
or (1 shl RTL8139_BIT_10FD) or (1 shl RTL8139_BIT_TX) \ |
or (1 shl RTL8139_BIT_TXFD) |
out dx, ax |
; lock config and BMCR registers |
xor eax, eax |
add edx, RTL8139_REG_9346CR - RTL8139_REG_ANAR |
out dx, al |
; init RX/TX pointers |
mov [rtl8139_rx_buff_offset], eax |
mov [curr_tx_desc], eax |
; clear missing packet counter |
add edx, RTL8139_REG_MPC - RTL8139_REG_9346CR |
out dx, eax |
; disable all interrupts |
add edx, RTL8139_REG_IMR - RTL8139_REG_MPC |
out dx, ax |
; set RxBuffer address, init RX buffer offset, init TX ring |
mov eax, rtl8139_rx_buff ; simba |
sub eax,OS_BASE |
add edx, RTL8139_REG_RBSTART - RTL8139_REG_IMR |
out dx, eax |
; Indicate that we have successfully reset the card |
mov eax, [pci_data] |
mov [eth_status], eax |
ret |
;*************************************************************************** |
; Function |
; rtl8139_read_eeprom |
; Description |
; reads eeprom type 93c46 and 93c56 |
; Parameters |
; al - word to be read (6bit in case of 93c46 and 8bit otherwise) |
; Return value |
; ax - word read in |
; Destroyed register(s) |
; eax, cx, ebx, edx |
; |
;*************************************************************************** |
rtl8139_read_eeprom: |
movzx ebx, al |
mov edx, [io_addr] |
add edx, RTL8139_REG_RXCONFIG |
in al, dx |
test al, (1 shl RTL8139_BIT_9356SEL) |
jz .type_93c46 |
; and bl, 01111111b ; don't care first bit |
or bx, EE_93C56_READ_CMD ; it contains start bit |
mov cx, EE_93C56_CMD_LENGTH-1 ; cmd_loop counter |
jmp .read_eeprom |
.type_93c46: |
and bl, 00111111b |
or bx, EE_93C46_READ_CMD ; it contains start bit |
mov cx, EE_93C46_CMD_LENGTH-1 ; cmd_loop counter |
.read_eeprom: |
add edx, RTL8139_REG_9346CR - RTL8139_REG_RXCONFIG_0 |
; mov al, (1 shl RTL8139_BIT_93C46_EEM1) |
; out dx, al |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ |
or (1 shl RTL8139_BIT_93C46_EECS) ; wake up the eeprom |
out dx, al |
.cmd_loop: |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) |
bt bx, cx |
jnc .zero_bit |
or al, (1 shl RTL8139_BIT_93C46_EEDI) |
.zero_bit: |
out dx, al |
; push eax |
; in eax, dx ; eeprom delay |
; pop eax |
or al, (1 shl RTL8139_BIT_93C46_EESK) |
out dx, al |
; in eax, dx ; eeprom delay |
dec cx |
jns .cmd_loop |
; in eax, dx ; eeprom delay |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) |
out dx, al |
mov cl, 0xf |
.read_loop: |
shl ebx, 1 |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ |
or (1 shl RTL8139_BIT_93C46_EECS) \ |
or (1 shl RTL8139_BIT_93C46_EESK) |
out dx, al |
; in eax, dx ; eeprom delay |
in al, dx |
and al, (1 shl RTL8139_BIT_93C46_EEDO) |
jz .dont_set |
inc ebx |
.dont_set: |
mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ |
or (1 shl RTL8139_BIT_93C46_EECS) |
out dx, al |
; in eax, dx ; eeprom delay |
dec cl |
jns .read_loop |
xor al, al |
out dx, al |
mov ax, bx |
ret |
;*************************************************************************** |
; Function |
; rtl8139_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; Size of packet in ecx |
; Pointer to packet data in esi |
; Destroyed registers |
; eax, edx, esi, edi |
; ToDo |
; for waiting of timeout the rtl8139 internal timer |
; should be used |
; |
;*************************************************************************** |
rtl8139_transmit: |
cmp ecx, MAX_ETH_FRAME_SIZE |
jg .finish ; packet is too long |
push ecx |
; check descriptor |
mov ecx, [curr_tx_desc] |
mov edx, [io_addr] |
lea edx, [edx+ecx*4+RTL8139_REG_TSD0] |
push edx ebx |
in ax, dx |
test ax, 0x1fff ; or no size given |
jz .send_packet |
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
jz .send_packet |
; wait for timeout |
mov ebx, RTL8139_TX_TIMEOUT |
mov eax, 0x5 ; delay x/100 secs |
int 0x40 |
in ax, dx |
and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
jz .send_packet |
; chip hung, reset it |
call rtl8139_reset |
; reset the card |
.send_packet: |
; calculate tx_buffer address |
pop ebx |
push esi |
mov eax, MAX_ETH_FRAME_SIZE |
mul dword [curr_tx_desc] |
mov esi, edi |
lea edi, [rtl8139_tx_buff+eax] |
mov eax, edi |
cld |
; copy destination address |
movsd |
movsw |
; copy source address |
mov esi, node_addr |
movsd |
movsw |
; copy packet type |
mov [edi], bx |
add edi, 2 |
; copy the packet data |
pop esi edx ecx |
push ecx |
shr ecx, 2 |
rep movsd |
pop ecx |
push ecx |
and ecx, 3 |
rep movsb |
; set address |
sub eax,OS_BASE |
add edx, RTL8139_REG_TSAD0 - RTL8139_REG_TSD0 |
out dx, eax |
; set size and early threshold |
pop eax ; pick up the size |
add eax, ETH_HLEN |
cmp eax, ETH_ZLEN |
jnc .no_pad |
mov eax, ETH_ZLEN |
.no_pad: |
or eax, (RTL8139_ERTXTH shl RTL8139_BIT_ERTXTH) |
add edx, RTL8139_REG_TSD0 - RTL8139_REG_TSAD0 |
out dx, eax |
; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ... |
inc dword [curr_tx_desc] |
and dword [curr_tx_desc], 3 |
.finish: |
ret |
;*************************************************************************** |
; Function |
; rtl8139_poll |
; |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; Destroyed register(s) |
; eax, edx, ecx |
; |
;*************************************************************************** |
rtl8139_poll: |
mov word [eth_rx_data_len], 0 |
mov edx, [io_addr] |
add edx, RTL8139_REG_COMMAND |
in al, dx |
test al, (1 shl RTL8139_BIT_BUFE) |
jnz .finish |
; new packet received copy it from rx_buffer into Ether_buffer |
mov eax, rtl8139_rx_buff |
add eax, [rtl8139_rx_buff_offset] |
; check if packet is ok |
test byte [eax], (1 shl RTL8139_BIT_ROK) |
jz .reset_rx |
; packet is ok copy it into the Ether_buffer |
movzx ecx, word [eax+2] ; packet length |
sub ecx, 4 ; don't copy CRC |
mov word [eth_rx_data_len], cx |
push ecx |
shr ecx, 2 ; first copy dword-wise |
lea esi, [eax+4] ; don't copy the packet header |
mov edi, Ether_buffer |
cld |
rep movsd ; copy the dwords |
pop ecx |
and ecx, 3 |
rep movsb ; copy the rest bytes |
; update rtl8139_rx_buff_offset |
movzx eax, word [eax+2] ; packet length |
add eax, [rtl8139_rx_buff_offset] |
add eax, 4+3 ; packet header is 4 bytes long + dword alignment |
and eax, not 3 ; dword alignment |
cmp eax, RTL8139_RX_BUFFER_SIZE |
jl .no_wrap |
sub eax, RTL8139_RX_BUFFER_SIZE |
.no_wrap: |
mov [rtl8139_rx_buff_offset], eax |
; update CAPR register |
sub eax, 0x10 ; value 0x10 is a constant for CAPR |
add edx, RTL8139_REG_CAPR - RTL8139_REG_COMMAND |
out dx, ax |
.finish: |
; clear active interrupt sources |
mov edx, [io_addr] |
add edx, RTL8139_REG_ISR |
in ax, dx |
out dx, ax |
ret |
.reset_rx: |
in al, dx ; read command register |
push eax |
and al, not (1 shl RTL8139_BIT_RE) |
out dx, al |
pop eax |
out dx, al |
add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND |
mov ax, RTL8139_RX_CONFIG |
out dx, ax |
ret |
rtl8139_cable: |
pusha |
mov edx, [io_addr] |
add edx, 0x58 |
in al,dx |
test al,1 SHL 2 |
jnz .notconnected |
popa |
xor al,al |
inc al |
ret |
.notconnected: |
popa |
xor al,al |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/eth_drv/drivers/3c59x.inc |
---|
0,0 → 1,2388 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; 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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/eth_drv/drivers/i8255x.inc |
---|
0,0 → 1,744 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; I8255X.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.3 11 August 2003 ;; |
;; ;; |
;; This driver is based on the eepro100 driver from ;; |
;; the etherboot 5.0.6 project. The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2002 Mike Hibbett, ;; |
;; mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************** |
; 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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/eth_drv/drivers/pcnet32.inc |
---|
0,0 → 1,818 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; PCNET32.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 1.0 31 July 2004 ;; |
;; ;; |
;; 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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/eth_drv/drivers/rtl8029.inc |
---|
0,0 → 1,959 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; RTL8029.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.2 31 July 2002 ;; |
;; ;; |
;; This driver is based on the ns8390 driver from ;; |
;; the etherboot 5.0.6 project. The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2002 Mike Hibbett, ;; |
;; mikeh@oceanfree.net ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; While this implementation handles only PCI bus RTL8029 ;; |
;; hardware, it can be easily adapted to other NE2000 clone ;; |
;; products. I just dont have any to try! ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************** |
; Interface |
; rtl8029_reset |
; rtl8029_probe |
; rtl8029_poll |
; rtl8029_transmit |
; |
;******************************************************************** |
;************************************************************************** |
; 8390 Register Definitions |
;************************************************************************** |
D8390_P0_COMMAND equ 0x00 |
D8390_P0_PSTART equ 0x01 |
D8390_P0_PSTOP equ 0x02 |
D8390_P0_BOUND equ 0x03 |
D8390_P0_TSR equ 0x04 |
D8390_P0_TPSR equ 0x04 |
D8390_P0_TBCR0 equ 0x05 |
D8390_P0_TBCR1 equ 0x06 |
D8390_P0_ISR equ 0x07 |
D8390_P0_RSAR0 equ 0x08 |
D8390_P0_RSAR1 equ 0x09 |
D8390_P0_RBCR0 equ 0x0A |
D8390_P0_RBCR1 equ 0x0B |
D8390_P0_RSR equ 0x0C |
D8390_P0_RCR equ 0x0C |
D8390_P0_TCR equ 0x0D |
D8390_P0_DCR equ 0x0E |
D8390_P0_IMR equ 0x0F |
D8390_P1_COMMAND equ 0x00 |
D8390_P1_PAR0 equ 0x01 |
D8390_P1_PAR1 equ 0x02 |
D8390_P1_PAR2 equ 0x03 |
D8390_P1_PAR3 equ 0x04 |
D8390_P1_PAR4 equ 0x05 |
D8390_P1_PAR5 equ 0x06 |
D8390_P1_CURR equ 0x07 |
D8390_P1_MAR0 equ 0x08 |
D8390_COMMAND_PS0 equ 0x0 ; Page 0 select |
D8390_COMMAND_PS1 equ 0x40 ; Page 1 select |
D8390_COMMAND_PS2 equ 0x80 ; Page 2 select |
D8390_COMMAND_RD2 equ 0x20 ; Remote DMA control |
D8390_COMMAND_RD1 equ 0x10 |
D8390_COMMAND_RD0 equ 0x08 |
D8390_COMMAND_TXP equ 0x04 ; transmit packet |
D8390_COMMAND_STA equ 0x02 ; start |
D8390_COMMAND_STP equ 0x01 ; stop |
D8390_COMMAND_RD2_STA equ 0x22 |
D8390_COMMAND_RD2_STP equ 0x21 |
D8390_COMMAND_RD1_STA equ 0x12 |
D8390_COMMAND_RD0_STA equ 0x0A |
D8390_COMMAND_PS0_RD2_STP equ 0x21 |
D8390_COMMAND_PS1_RD2_STP equ 0x61 |
D8390_COMMAND_PS0_RD2_STA equ 0x22 |
D8390_COMMAND_PS0_TXP_RD2_STA equ 0x26 |
D8390_RCR_MON equ 0x20 ; monitor mode |
D8390_DCR_FT1 equ 0x40 |
D8390_DCR_LS equ 0x08 ; Loopback select |
D8390_DCR_WTS equ 0x01 ; Word transfer select |
D8390_DCR_FT1_LS equ 0x48 |
D8390_DCR_WTS_FT1_LS equ 0x49 |
D8390_ISR_PRX equ 0x01 ; successful recv |
D8390_ISR_PTX equ 0x02 ; successful xmit |
D8390_ISR_RXE equ 0x04 ; receive error |
D8390_ISR_TXE equ 0x08 ; transmit error |
D8390_ISR_OVW equ 0x10 ; Overflow |
D8390_ISR_CNT equ 0x20 ; Counter overflow |
D8390_ISR_RDC equ 0x40 ; Remote DMA complete |
D8390_ISR_RST equ 0x80 ; reset |
D8390_RSTAT_PRX equ 0x01 ; successful recv |
D8390_RSTAT_CRC equ 0x02 ; CRC error |
D8390_RSTAT_FAE equ 0x04 ; Frame alignment error |
D8390_RSTAT_OVER equ 0x08 ; FIFO overrun |
D8390_TXBUF_SIZE equ 6 |
D8390_RXBUF_END equ 32 |
D8390_PAGE_SIZE equ 256 |
ETH_ALEN equ 6 |
ETH_HLEN equ 14 |
ETH_ZLEN equ 60 |
ETH_FRAME_LEN equ 1514 |
FLAG_PIO equ 0x01 |
FLAG_16BIT equ 0x02 |
ASIC_PIO equ 0 |
VENDOR_NONE equ 0 |
VENDOR_WD equ 1 |
VENDOR_NOVELL equ 2 |
VENDOR_3COM equ 3 |
NE_ASIC_OFFSET equ 0x10 |
NE_RESET equ 0x0F ; Used to reset card |
NE_DATA equ 0x00 ; Used to read/write NIC mem |
MEM_8192 equ 32 |
MEM_16384 equ 64 |
MEM_32768 equ 128 |
ISA_MAX_ADDR equ 0x400 |
uglobal |
eth_flags: db 0 |
eth_vendor: db 0 |
eth_nic_base: dw 0 |
eth_asic_base: dw 0 |
eth_memsize: db 0 |
eth_rx_start: db 0 |
eth_tx_start: db 0 |
eth_bmem: dd 0 |
eth_rmem: dd 0 |
romdata: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
endg |
iglobal |
test_data: db 'NE*000 memory',0 |
test_buffer: db ' ',0 |
endg |
uglobal |
eth_type: dw 0 |
pkthdr: db 0,0,0,0 ; status, next, (short) len |
pktoff: dw 0 |
eth_rx_data_ptr: dd 0 |
eth_tmp_len: dw 0 |
endg |
;*************************************************************************** |
; Function |
; eth_pio_read |
; |
; Description |
; Read a frame from the ethernet card via Programmed I/O |
; src in ebx |
; cnt in ecx |
; dst in edi |
;*************************************************************************** |
eth_pio_read: |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, 0 |
je epr_001 |
inc ecx |
and ecx, 0xFFFFFFFE |
epr_001: |
mov al, D8390_COMMAND_RD2_STA |
mov dx, [eth_nic_base] |
add dx, D8390_P0_COMMAND |
out dx, al |
mov al, cl |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RBCR0 |
out dx, al |
mov al, ch |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RBCR1 |
out dx, al |
mov al, bl |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RSAR0 |
out dx, al |
mov al, bh |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RSAR1 |
out dx, al |
mov al, D8390_COMMAND_RD0_STA |
mov dx, [eth_nic_base] |
add dx, D8390_P0_COMMAND |
out dx, al |
mov dx, [eth_asic_base] |
add dx, ASIC_PIO |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, 0 |
je epr_003 |
shr ecx, 1 |
epr_002: |
; 2 bytes at a time |
in ax, dx |
mov [edi], ax |
add edi, 2 |
loop epr_002 |
ret |
epr_003: |
; 1 byte at a time |
in al, dx |
mov [edi], al |
inc edi |
loop epr_003 |
ret |
;*************************************************************************** |
; Function |
; eth_pio_write |
; |
; Description |
; writes a frame to the ethernet card via Programmed I/O |
; dst in ebx |
; cnt in ecx |
; src in esi |
;*************************************************************************** |
eth_pio_write: |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, 0 |
je epw_001 |
inc ecx |
and ecx, 0xFFFFFFFE |
epw_001: |
mov al, D8390_COMMAND_RD2_STA |
mov dx, [eth_nic_base] |
add dx, D8390_P0_COMMAND |
out dx, al |
mov al, D8390_ISR_RDC |
mov dx, [eth_nic_base] |
add dx, D8390_P0_ISR |
out dx, al |
mov al, cl |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RBCR0 |
out dx, al |
mov al, ch |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RBCR1 |
out dx, al |
mov al, bl |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RSAR0 |
out dx, al |
mov al, bh |
mov dx, [eth_nic_base] |
add dx, D8390_P0_RSAR1 |
out dx, al |
mov al, D8390_COMMAND_RD1_STA |
mov dx, [eth_nic_base] |
add dx, D8390_P0_COMMAND |
out dx, al |
mov dx, [eth_asic_base] |
add dx, ASIC_PIO |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, 0 |
je epw_003 |
shr ecx, 1 |
epw_002: |
; 2 bytes at a time |
mov ax, [esi] |
add esi, 2 |
out dx, ax |
loop epw_002 |
jmp epw_004 |
epw_003: |
; 1 byte at a time |
mov al, [esi] |
inc esi |
out dx, al |
loop epw_003 |
epw_004: |
mov dx, [eth_nic_base] |
add dx, D8390_P0_ISR |
epw_005: |
in al, dx |
and al, D8390_ISR_RDC |
cmp al, D8390_ISR_RDC |
jne epw_005 |
ret |
;*************************************************************************** |
; Function |
; rtl8029_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; No inputs |
; All registers destroyed |
; |
;*************************************************************************** |
rtl8029_reset: |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0_RD2_STP |
out dx, al |
mov dx, bx |
add dx, D8390_P0_DCR |
mov al, [eth_flags] |
and al, FLAG_16BIT |
cmp al, FLAG_16BIT |
jne nsr_001 |
mov al, 0x49 |
jmp nsr_002 |
nsr_001: |
mov al, 0x48 |
nsr_002: |
out dx, al |
xor al, al |
mov dx, bx |
add dx, D8390_P0_RBCR0 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_RBCR1 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_RCR |
mov al, 0x20 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TCR |
mov al, 2 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TPSR |
mov al, [eth_tx_start] |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTART |
mov al, [eth_rx_start] |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTOP |
mov al, [eth_memsize] |
out dx, al |
mov dx, bx |
add dx, D8390_P0_BOUND |
mov al, [eth_memsize] |
dec al |
out dx, al |
mov dx, bx |
add dx, D8390_P0_ISR |
mov al, 0xff |
out dx, al |
mov dx, bx |
add dx, D8390_P0_IMR |
xor al, al |
out dx, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS1_RD2_STP |
out dx, al |
mov dx, bx |
add dx, D8390_P1_PAR0 |
mov esi, node_addr |
mov ecx, ETH_ALEN |
nsr_003: |
mov al, [esi] |
out dx, al |
inc esi |
inc dx |
loop nsr_003 |
mov dx, bx |
add dx, D8390_P1_MAR0 |
mov ecx, ETH_ALEN |
mov al, 0xff |
nsr_004: |
out dx, al |
inc dx |
loop nsr_004 |
mov dx, bx |
add dx, D8390_P1_CURR |
mov al, [eth_rx_start] |
out dx, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0_RD2_STA |
out dx, al |
mov dx, bx |
add dx, D8390_P0_ISR |
mov al, 0xff |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TCR |
mov al, 0 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_RCR |
mov al, 4 |
out dx, al |
ret |
;*************************************************************************** |
; Function |
; rtl8029_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; |
;*************************************************************************** |
rtl8029_probe: |
mov eax, [io_addr] |
mov [eth_nic_base], ax ; The IO address space is 16 bit only |
mov al, VENDOR_NONE |
mov [eth_vendor], al |
mov al, [eth_vendor] |
cmp al, VENDOR_NONE |
jne ep_check_have_vendor |
xor eax, eax |
mov [eth_bmem], eax |
mov al, FLAG_PIO |
mov [eth_flags], al |
mov ax, [eth_nic_base] |
add ax, NE_ASIC_OFFSET |
mov [eth_asic_base], ax |
mov al, MEM_16384 |
mov [eth_memsize], al |
mov al, 32 |
mov [eth_tx_start], al |
add al, D8390_TXBUF_SIZE |
mov [eth_rx_start], al |
mov dx, [eth_asic_base] |
add dx, NE_RESET |
in al, dx |
out dx, al |
in al, 0x84 |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_RD2_STP |
out dx, al |
mov dx, bx |
add dx, D8390_P0_RCR |
mov al, D8390_RCR_MON |
out dx, al |
mov dx, bx |
add dx, D8390_P0_DCR |
mov al, D8390_DCR_FT1_LS |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTART |
mov al, MEM_8192 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTOP |
mov al, MEM_16384 |
out dx, al |
mov esi, test_data |
mov ebx, 8192 |
mov ecx, 14 |
call eth_pio_write |
mov ebx, 8192 |
mov ecx, 14 |
mov edi, test_buffer |
call eth_pio_read |
mov esi, test_buffer |
mov edi, test_data |
mov ecx, 13 |
cld |
rep cmpsb |
je ep_set_vendor |
mov al, [eth_flags] |
or al, FLAG_16BIT |
mov [eth_flags], al |
mov al, MEM_32768 |
mov [eth_memsize], al |
mov al, 64 |
mov [eth_tx_start], al |
add al, D8390_TXBUF_SIZE |
mov [eth_rx_start], al |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_DCR |
mov al, D8390_DCR_WTS_FT1_LS |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTART |
mov al, MEM_16384 |
out dx, al |
mov dx, bx |
add dx, D8390_P0_PSTOP |
mov al, MEM_32768 |
out dx, al |
mov esi, test_data |
mov ebx, 16384 |
mov ecx, 14 |
call eth_pio_write |
mov ebx, 16384 |
mov ecx, 14 |
mov edi, test_buffer |
call eth_pio_read |
mov esi, test_buffer |
mov edi, test_data |
mov ecx, 13 |
cld |
rep cmpsb |
ep_set_vendor: |
; this bit is odd - probably left over from my hacking |
mov ax, [eth_nic_base] |
cmp ax, 0 |
je rtl8029_exit |
cmp ax, ISA_MAX_ADDR |
jbe ep_001 |
mov al, [eth_flags] |
or al, FLAG_16BIT |
mov [eth_flags], al |
ep_001: |
mov al, VENDOR_NOVELL |
mov [eth_vendor], al |
mov ebx, 0 |
mov ecx, 16 |
mov edi, romdata |
call eth_pio_read |
mov ecx, ETH_ALEN |
mov esi, romdata |
mov edi, node_addr |
mov bl, [eth_flags] |
and bl, FLAG_16BIT |
ep_002: |
mov al, [esi] |
mov [edi], al |
inc edi |
inc esi |
cmp bl, FLAG_16BIT |
jne ep_003 |
inc esi |
ep_003: |
loop ep_002 |
ep_check_have_vendor: |
mov al, [eth_vendor] |
cmp al, VENDOR_NONE |
je rtl8029_exit |
cmp al, VENDOR_3COM |
je ep_reset_card |
mov eax, [eth_bmem] |
mov [eth_rmem], eax |
ep_reset_card: |
; Reset the card |
call rtl8029_reset |
; Indicate that we have successfully reset the card |
mov eax, [pci_data] |
mov [eth_status], eax |
rtl8029_exit: |
ret |
;*************************************************************************** |
; Function |
; rtl8029_poll |
; |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; |
;*************************************************************************** |
rtl8029_poll: |
mov eax, Ether_buffer |
mov [eth_rx_data_ptr], eax |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_RSR |
in al, dx |
and al, D8390_RSTAT_PRX |
cmp al, D8390_RSTAT_PRX |
jne nsp_exit |
mov dx, bx |
add dx, D8390_P0_BOUND |
in al, dx |
inc al |
cmp al, [eth_memsize] |
jb nsp_001 |
mov al, [eth_rx_start] |
nsp_001: |
mov ch, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS1 |
out dx, al |
mov dx, bx |
add dx, D8390_P1_CURR |
in al, dx ; get current page |
mov cl, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0 |
out dx, al |
cmp cl, [eth_memsize] |
jb nsp_002 |
mov cl, [eth_rx_start] |
nsp_002: |
cmp cl, ch |
je nsp_exit |
xor ax, ax |
mov ah, ch |
mov [pktoff], ax |
mov al, [eth_flags] |
and al, FLAG_PIO |
cmp al, FLAG_PIO |
jne nsp_003 |
movzx ebx, word [pktoff] |
mov edi, pkthdr |
mov ecx, 4 |
call eth_pio_read |
jmp nsp_004 |
nsp_003: |
mov edi, [eth_rmem] |
movzx eax, word [pktoff] |
add edi, eax |
mov eax, [edi] |
mov [pkthdr], eax |
nsp_004: |
mov ax, [pktoff] |
add ax, 4 |
mov [pktoff], ax |
mov ax, [pkthdr + 2] |
sub ax, 4 |
mov [eth_tmp_len], ax |
cmp ax, ETH_ZLEN |
jb nsp_exit |
cmp ax, ETH_FRAME_LEN |
ja nsp_exit |
mov al, [pkthdr] |
and al, D8390_RSTAT_PRX |
cmp al, D8390_RSTAT_PRX |
jne nsp_exit |
; Right, we can now get the data |
mov ax, [eth_tmp_len] |
mov [eth_rx_data_len], ax |
xor ebx, ebx |
mov bh, [eth_memsize] |
sub bx, [pktoff] |
cmp [eth_tmp_len], bx |
jbe nsp_005 |
mov al, [eth_flags] |
and al, FLAG_PIO |
cmp al, FLAG_PIO |
jne nsp_006 |
push ebx |
mov ecx, ebx |
xor ebx, ebx |
mov bx, [pktoff] |
mov edi, [eth_rx_data_ptr] |
call eth_pio_read |
pop ebx |
jmp nsp_007 |
nsp_006: |
; Not implemented, as we are using PIO mode on this card |
nsp_007: |
xor ax, ax |
mov ah, [eth_rx_start] |
mov [pktoff], ax |
mov eax, [eth_rx_data_ptr] |
add eax, ebx |
mov [eth_rx_data_ptr], eax |
mov ax, [eth_tmp_len] |
sub ax, bx |
mov [eth_tmp_len], ax |
nsp_005: |
mov al, [eth_flags] |
and al, FLAG_PIO |
cmp al, FLAG_PIO |
jne nsp_008 |
xor ebx, ebx |
mov bx, [pktoff] |
xor ecx, ecx |
mov cx, [eth_tmp_len] |
mov edi, [eth_rx_data_ptr] |
call eth_pio_read |
jmp nsp_009 |
nsp_008: |
; Not implemented, as we are using PIO mode on this card |
nsp_009: |
mov al, [pkthdr+1] |
cmp al, [eth_rx_start] |
jne nsp_010 |
mov al, [eth_memsize] |
nsp_010: |
mov dx, [eth_nic_base] |
add dx, D8390_P0_BOUND |
dec al |
out dx, al |
nsp_exit: |
ret |
;*************************************************************************** |
; Function |
; rtl8029_transmit |
; |
; Description |
; Transmits a packet of data via the ethernet card |
; Pointer to 48 bit destination address in edi |
; Type of packet in bx |
; size of packet in ecx |
; pointer to packet data in esi |
; |
;*************************************************************************** |
rtl8029_transmit: |
mov [eth_type], bx |
pusha |
mov esi, edi |
xor bx, bx |
mov bh, [eth_tx_start] |
mov ecx, ETH_ALEN |
call eth_pio_write |
mov esi, node_addr |
xor bx, bx |
mov bh, [eth_tx_start] |
add bx, ETH_ALEN |
mov ecx, ETH_ALEN |
call eth_pio_write |
mov esi, eth_type |
xor bx, bx |
mov bh, [eth_tx_start] |
add bx, ETH_ALEN |
add bx, ETH_ALEN |
mov ecx, 2 |
call eth_pio_write |
popa |
xor bx, bx |
mov bh, [eth_tx_start] |
add bx, ETH_HLEN |
push ecx |
call eth_pio_write |
pop ecx |
add ecx, ETH_HLEN |
cmp ecx, ETH_ZLEN |
jae nst_001 |
mov ecx, ETH_ZLEN |
nst_001: |
push ecx |
mov bx, [eth_nic_base] |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0_RD2_STA |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TPSR |
mov al, [eth_tx_start] |
out dx, al |
pop ecx |
mov dx, bx |
add dx, D8390_P0_TBCR0 |
mov al, cl |
out dx, al |
mov dx, bx |
add dx, D8390_P0_TBCR1 |
mov al, ch |
out dx, al |
mov dx, bx |
add dx, D8390_P0_COMMAND |
mov al, D8390_COMMAND_PS0_TXP_RD2_STA |
out dx, al |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/eth_drv/drivers/rtl8169.inc |
---|
0,0 → 1,1208 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; RTL8169.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.1 11 February 2007 ;; |
;; ;; |
;; Driver for chips of RealTek 8169 family ;; |
;; References: ;; |
;; r8169.c - linux driver (etherboot project) ;; |
;; ethernet driver template by Mike Hibbett ;; |
;; ;; |
;; The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; Copyright 2007 mike.dld, ;; |
;; mike.dld@gmail.com ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
ETH_ALEN equ 6 |
ETH_HLEN equ (2 * ETH_ALEN + 2) |
ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for |
; mininmum 64bytes frame length |
RTL8169_REG_MAC0 equ 0x0 ; Ethernet hardware address |
RTL8169_REG_MAR0 equ 0x8 ; Multicast filter |
RTL8169_REG_TxDescStartAddr equ 0x20 |
RTL8169_REG_TxHDescStartAddr equ 0x28 |
RTL8169_REG_FLASH equ 0x30 |
RTL8169_REG_ERSR equ 0x36 |
RTL8169_REG_ChipCmd equ 0x37 |
RTL8169_REG_TxPoll equ 0x38 |
RTL8169_REG_IntrMask equ 0x3C |
RTL8169_REG_IntrStatus equ 0x3E |
RTL8169_REG_TxConfig equ 0x40 |
RTL8169_REG_RxConfig equ 0x44 |
RTL8169_REG_RxMissed equ 0x4C |
RTL8169_REG_Cfg9346 equ 0x50 |
RTL8169_REG_Config0 equ 0x51 |
RTL8169_REG_Config1 equ 0x52 |
RTL8169_REG_Config2 equ 0x53 |
RTL8169_REG_Config3 equ 0x54 |
RTL8169_REG_Config4 equ 0x55 |
RTL8169_REG_Config5 equ 0x56 |
RTL8169_REG_MultiIntr equ 0x5C |
RTL8169_REG_PHYAR equ 0x60 |
RTL8169_REG_TBICSR equ 0x64 |
RTL8169_REG_TBI_ANAR equ 0x68 |
RTL8169_REG_TBI_LPAR equ 0x6A |
RTL8169_REG_PHYstatus equ 0x6C |
RTL8169_REG_RxMaxSize equ 0xDA |
RTL8169_REG_CPlusCmd equ 0xE0 |
RTL8169_REG_RxDescStartAddr equ 0xE4 |
RTL8169_REG_ETThReg equ 0xEC |
RTL8169_REG_FuncEvent equ 0xF0 |
RTL8169_REG_FuncEventMask equ 0xF4 |
RTL8169_REG_FuncPresetState equ 0xF8 |
RTL8169_REG_FuncForceEvent equ 0xFC |
; InterruptStatusBits |
RTL8169_ISB_SYSErr equ 0x8000 |
RTL8169_ISB_PCSTimeout equ 0x4000 |
RTL8169_ISB_SWInt equ 0x0100 |
RTL8169_ISB_TxDescUnavail equ 0x80 |
RTL8169_ISB_RxFIFOOver equ 0x40 |
RTL8169_ISB_LinkChg equ 0x20 |
RTL8169_ISB_RxOverflow equ 0x10 |
RTL8169_ISB_TxErr equ 0x08 |
RTL8169_ISB_TxOK equ 0x04 |
RTL8169_ISB_RxErr equ 0x02 |
RTL8169_ISB_RxOK equ 0x01 |
; RxStatusDesc |
RTL8169_SD_RxRES equ 0x00200000 |
RTL8169_SD_RxCRC equ 0x00080000 |
RTL8169_SD_RxRUNT equ 0x00100000 |
RTL8169_SD_RxRWT equ 0x00400000 |
; ChipCmdBits |
RTL8169_CMD_Reset equ 0x10 |
RTL8169_CMD_RxEnb equ 0x08 |
RTL8169_CMD_TxEnb equ 0x04 |
RTL8169_CMD_RxBufEmpty equ 0x01 |
; Cfg9346Bits |
RTL8169_CFG_9346_Lock equ 0x00 |
RTL8169_CFG_9346_Unlock equ 0xC0 |
; rx_mode_bits |
RTL8169_RXM_AcceptErr equ 0x20 |
RTL8169_RXM_AcceptRunt equ 0x10 |
RTL8169_RXM_AcceptBroadcast equ 0x08 |
RTL8169_RXM_AcceptMulticast equ 0x04 |
RTL8169_RXM_AcceptMyPhys equ 0x02 |
RTL8169_RXM_AcceptAllPhys equ 0x01 |
; RxConfigBits |
RTL8169_RXC_FIFOShift equ 13 |
RTL8169_RXC_DMAShift equ 8 |
; TxConfigBits |
RTL8169_TXC_InterFrameGapShift equ 24 |
RTL8169_TXC_DMAShift equ 8 ; DMA burst value (0-7) is shift this many bits |
; rtl8169_PHYstatus |
RTL8169_PHYS_TBI_Enable equ 0x80 |
RTL8169_PHYS_TxFlowCtrl equ 0x40 |
RTL8169_PHYS_RxFlowCtrl equ 0x20 |
RTL8169_PHYS_1000bpsF equ 0x10 |
RTL8169_PHYS_100bps equ 0x08 |
RTL8169_PHYS_10bps equ 0x04 |
RTL8169_PHYS_LinkStatus equ 0x02 |
RTL8169_PHYS_FullDup equ 0x01 |
; GIGABIT_PHY_registers |
RTL8169_PHY_CTRL_REG equ 0 |
RTL8169_PHY_STAT_REG equ 1 |
RTL8169_PHY_AUTO_NEGO_REG equ 4 |
RTL8169_PHY_1000_CTRL_REG equ 9 |
; GIGABIT_PHY_REG_BIT |
RTL8169_PHY_Restart_Auto_Nego equ 0x0200 |
RTL8169_PHY_Enable_Auto_Nego equ 0x1000 |
; PHY_STAT_REG = 1; |
RTL8169_PHY_Auto_Neco_Comp equ 0x0020 |
; PHY_AUTO_NEGO_REG = 4; |
RTL8169_PHY_Cap_10_Half equ 0x0020 |
RTL8169_PHY_Cap_10_Full equ 0x0040 |
RTL8169_PHY_Cap_100_Half equ 0x0080 |
RTL8169_PHY_Cap_100_Full equ 0x0100 |
; PHY_1000_CTRL_REG = 9; |
RTL8169_PHY_Cap_1000_Full equ 0x0200 |
RTL8169_PHY_Cap_1000_Half equ 0x0100 |
RTL8169_PHY_Cap_PAUSE equ 0x0400 |
RTL8169_PHY_Cap_ASYM_PAUSE equ 0x0800 |
RTL8169_PHY_Cap_Null equ 0x0 |
; _MediaType |
RTL8169_MT_10_Half equ 0x01 |
RTL8169_MT_10_Full equ 0x02 |
RTL8169_MT_100_Half equ 0x04 |
RTL8169_MT_100_Full equ 0x08 |
RTL8169_MT_1000_Full equ 0x10 |
; _TBICSRBit |
RTL8169_TBI_LinkOK equ 0x02000000 |
; _DescStatusBit |
RTL8169_DSB_OWNbit equ 0x80000000 |
RTL8169_DSB_EORbit equ 0x40000000 |
RTL8169_DSB_FSbit equ 0x20000000 |
RTL8169_DSB_LSbit equ 0x10000000 |
; MAC address length |
MAC_ADDR_LEN equ 6 |
; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4) |
MAX_ETH_FRAME_SIZE equ 1536 |
TX_FIFO_THRESH equ 256 ; In bytes |
RX_FIFO_THRESH equ 7 ; 7 means NO threshold, Rx buffer level before first PCI xfer |
RX_DMA_BURST equ 7 ; Maximum PCI burst, '6' is 1024 |
TX_DMA_BURST equ 7 ; Maximum PCI burst, '6' is 1024 |
ETTh equ 0x3F ; 0x3F means NO threshold |
EarlyTxThld equ 0x3F ; 0x3F means NO early transmit |
RxPacketMaxSize equ 0x0800 ; Maximum size supported is 16K-1 |
InterFrameGap equ 0x03 ; 3 means InterFrameGap = the shortest one |
NUM_TX_DESC equ 1 ; Number of Tx descriptor registers |
NUM_RX_DESC equ 4 ; Number of Rx descriptor registers |
RX_BUF_SIZE equ 1536 ; Rx Buffer size |
HZ equ 1000 |
RTL_MIN_IO_SIZE equ 0x80 |
TX_TIMEOUT equ (6*HZ) |
RTL8169_TIMER_EXPIRE_TIME equ 100 |
ETH_HDR_LEN equ 14 |
DEFAULT_MTU equ 1500 |
DEFAULT_RX_BUF_LEN equ 1536 |
;#ifdef RTL8169_JUMBO_FRAME_SUPPORT |
;#define MAX_JUMBO_FRAME_MTU ( 10000 ) |
;#define MAX_RX_SKBDATA_SIZE ( MAX_JUMBO_FRAME_MTU + ETH_HDR_LEN ) |
;#else |
MAX_RX_SKBDATA_SIZE equ 1600 |
;#endif //end #ifdef RTL8169_JUMBO_FRAME_SUPPORT |
;#ifdef RTL8169_USE_IO |
;!!!#define RTL_W8(reg, val8) outb ((val8), ioaddr + (reg)) |
macro RTL_W8 reg,val8 { |
if ~reg eq dx |
mov dx,word[rtl8169_tpc.mmio_addr] |
add dx,reg |
end if |
if ~val8 eq al |
mov al,val8 |
end if |
out dx,al |
} |
;!!!#define RTL_W16(reg, val16) outw ((val16), ioaddr + (reg)) |
macro RTL_W16 reg,val16 { |
if ~reg eq dx |
mov dx,word[rtl8169_tpc.mmio_addr] |
add dx,reg |
end if |
if ~val16 eq ax |
mov ax,val16 |
end if |
out dx,ax |
} |
;!!!#define RTL_W32(reg, val32) outl ((val32), ioaddr + (reg)) |
macro RTL_W32 reg,val32 { |
if ~reg eq dx |
mov dx,word[rtl8169_tpc.mmio_addr] |
add dx,reg |
end if |
if ~val32 eq eax |
mov eax,val32 |
end if |
out dx,eax |
} |
;!!!#define RTL_R8(reg) inb (ioaddr + (reg)) |
macro RTL_R8 reg { |
if ~reg eq dx |
mov dx,word[rtl8169_tpc.mmio_addr] |
add dx,reg |
end if |
in al,dx |
} |
;!!!#define RTL_R16(reg) inw (ioaddr + (reg)) |
macro RTL_R16 reg { |
if ~reg eq dx |
mov dx,word[rtl8169_tpc.mmio_addr] |
add dx,reg |
end if |
in ax,dx |
} |
;!!!#define RTL_R32(reg) ((unsigned long) inl (ioaddr + (reg))) |
macro RTL_R32 reg { |
if ~reg eq dx |
mov dx,word[rtl8169_tpc.mmio_addr] |
add dx,reg |
end if |
in eax,dx |
} |
;#else |
; write/read MMIO register |
;#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) |
;#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg)) |
;#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg)) |
;#define RTL_R8(reg) readb (ioaddr + (reg)) |
;#define RTL_R16(reg) readw (ioaddr + (reg)) |
;#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg))) |
;#endif |
MCFG_METHOD_01 equ 0x01 |
MCFG_METHOD_02 equ 0x02 |
MCFG_METHOD_03 equ 0x03 |
MCFG_METHOD_04 equ 0x04 |
MCFG_METHOD_05 equ 0x05 |
MCFG_METHOD_11 equ 0x0b |
MCFG_METHOD_12 equ 0x0c |
MCFG_METHOD_13 equ 0x0d |
MCFG_METHOD_14 equ 0x0e |
MCFG_METHOD_15 equ 0x0f |
PCFG_METHOD_1 equ 0x01 ; PHY Reg 0x03 bit0-3 == 0x0000 |
PCFG_METHOD_2 equ 0x02 ; PHY Reg 0x03 bit0-3 == 0x0001 |
PCFG_METHOD_3 equ 0x03 ; PHY Reg 0x03 bit0-3 == 0x0002 |
PCI_COMMAND_IO equ 0x1 ; Enable response in I/O space |
PCI_COMMAND_MEM equ 0x2 ; Enable response in mem space |
PCI_COMMAND_MASTER equ 0x4 ; Enable bus mastering |
PCI_LATENCY_TIMER equ 0x0d ; 8 bits |
PCI_COMMAND_SPECIAL equ 0x8 ; Enable response to special cycles |
PCI_COMMAND_INVALIDATE equ 0x10 ; Use memory write and invalidate |
PCI_COMMAND_VGA_PALETTE equ 0x20 ; Enable palette snooping |
PCI_COMMAND_PARITY equ 0x40 ; Enable parity checking |
PCI_COMMAND_WAIT equ 0x80 ; Enable address/data stepping |
PCI_COMMAND_SERR equ 0x100 ; Enable SERR |
PCI_COMMAND_FAST_BACK equ 0x200 ; Enable back-to-back writes |
struc rtl8169_TxDesc { |
.status dd ? |
.vlan_tag dd ? |
.buf_addr dd ? |
.buf_Haddr dd ? |
} |
virtual at 0 |
rtl8169_TxDesc rtl8169_TxDesc |
sizeof.rtl8169_TxDesc = $ - rtl8169_TxDesc |
end virtual |
struc rtl8169_RxDesc { |
.status dd ? |
.vlan_tag dd ? |
.buf_addr dd ? |
.buf_Haddr dd ? |
} |
virtual at 0 |
rtl8169_RxDesc rtl8169_RxDesc |
sizeof.rtl8169_RxDesc = $ - rtl8169_RxDesc |
end virtual |
virtual at eth_data_start |
; Define the TX Descriptor |
align 256 |
rtl8169_tx_ring rb NUM_TX_DESC * sizeof.rtl8169_TxDesc |
; Create a static buffer of size RX_BUF_SZ for each |
; TX Descriptor. All descriptors point to a |
; part of this buffer |
align 256 |
rtl8169_txb rb NUM_TX_DESC * RX_BUF_SIZE |
; Define the RX Descriptor |
align 256 |
rtl8169_rx_ring rb NUM_RX_DESC * sizeof.rtl8169_TxDesc |
; Create a static buffer of size RX_BUF_SZ for each |
; RX Descriptor All descriptors point to a |
; part of this buffer |
align 256 |
rtl8169_rxb rb NUM_RX_DESC * RX_BUF_SIZE |
rtl8169_tpc: |
.mmio_addr dd ? ; memory map physical address |
.chipset dd ? |
.pcfg dd ? |
.mcfg dd ? |
.cur_rx dd ? ; Index into the Rx descriptor buffer of next Rx pkt |
.cur_tx dd ? ; Index into the Tx descriptor buffer of next Rx pkt |
.TxDescArrays dd ? ; Index of Tx Descriptor buffer |
.RxDescArrays dd ? ; Index of Rx Descriptor buffer |
.TxDescArray dd ? ; Index of 256-alignment Tx Descriptor buffer |
.RxDescArray dd ? ; Index of 256-alignment Rx Descriptor buffer |
.RxBufferRing rd NUM_RX_DESC ; Index of Rx Buffer array |
.Tx_skbuff rd NUM_TX_DESC |
end virtual |
rtl8169_intr_mask = RTL8169_ISB_LinkChg or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxFIFOOver or RTL8169_ISB_TxErr or RTL8169_ISB_TxOK or RTL8169_ISB_RxErr or RTL8169_ISB_RxOK |
rtl8169_rx_config = (RX_FIFO_THRESH shl RTL8169_RXC_FIFOShift) or (RX_DMA_BURST shl RTL8169_RXC_DMAShift) or 0x0000000E |
iglobal |
;static struct { |
; const char *name; |
; u8 mcfg; /* depend on RTL8169 docs */ |
; u32 RxConfigMask; /* should clear the bits supported by this chip */ |
;} |
rtl_chip_info dd \ |
MCFG_METHOD_01, 0xff7e1880, \ ; RTL8169 |
MCFG_METHOD_02, 0xff7e1880, \ ; RTL8169s/8110s |
MCFG_METHOD_03, 0xff7e1880, \ ; RTL8169s/8110s |
MCFG_METHOD_04, 0xff7e1880, \ ; RTL8169sb/8110sb |
MCFG_METHOD_05, 0xff7e1880, \ ; RTL8169sc/8110sc |
MCFG_METHOD_11, 0xff7e1880, \ ; RTL8168b/8111b // PCI-E |
MCFG_METHOD_12, 0xff7e1880, \ ; RTL8168b/8111b // PCI-E |
MCFG_METHOD_13, 0xff7e1880, \ ; RTL8101e // PCI-E 8139 |
MCFG_METHOD_14, 0xff7e1880, \ ; RTL8100e // PCI-E 8139 |
MCFG_METHOD_15, 0xff7e1880 ; RTL8100e // PCI-E 8139 |
mac_info dd \ |
0x38800000, MCFG_METHOD_15, \ |
0x38000000, MCFG_METHOD_12, \ |
0x34000000, MCFG_METHOD_13, \ |
0x30800000, MCFG_METHOD_14, \ |
0x30000000, MCFG_METHOD_11, \ |
0x18000000, MCFG_METHOD_05, \ |
0x10000000, MCFG_METHOD_04, \ |
0x04000000, MCFG_METHOD_03, \ |
0x00800000, MCFG_METHOD_02, \ |
0x00000000, MCFG_METHOD_01 ; catch-all |
endg |
PCI_COMMAND_IO equ 0x1 ; Enable response in I/O space |
PCI_COMMAND_MEM equ 0x2 ; Enable response in mem space |
PCI_COMMAND_MASTER equ 0x4 ; Enable bus mastering |
PCI_LATENCY_TIMER equ 0x0d ; 8 bits |
PCI_COMMAND_SPECIAL equ 0x8 ; Enable response to special cycles |
PCI_COMMAND_INVALIDATE equ 0x10 ; Use memory write and invalidate |
PCI_COMMAND_VGA_PALETTE equ 0x20 ; Enable palette snooping |
PCI_COMMAND_PARITY equ 0x40 ; Enable parity checking |
PCI_COMMAND_WAIT equ 0x80 ; Enable address/data stepping |
PCI_COMMAND_SERR equ 0x100 ; Enable SERR |
PCI_COMMAND_FAST_BACK equ 0x200 ; Enable back-to-back writes |
PCI_VENDOR_ID equ 0x00 ; 16 bits |
PCI_DEVICE_ID equ 0x02 ; 16 bits |
PCI_COMMAND equ 0x04 ; 16 bits |
PCI_BASE_ADDRESS_0 equ 0x10 ; 32 bits |
PCI_BASE_ADDRESS_1 equ 0x14 ; 32 bits |
PCI_BASE_ADDRESS_2 equ 0x18 ; 32 bits |
PCI_BASE_ADDRESS_3 equ 0x1c ; 32 bits |
PCI_BASE_ADDRESS_4 equ 0x20 ; 32 bits |
PCI_BASE_ADDRESS_5 equ 0x24 ; 32 bits |
PCI_BASE_ADDRESS_MEM_TYPE_MASK equ 0x06 |
PCI_BASE_ADDRESS_MEM_TYPE_32 equ 0x00 ; 32 bit address |
PCI_BASE_ADDRESS_MEM_TYPE_1M equ 0x02 ; Below 1M [obsolete] |
PCI_BASE_ADDRESS_MEM_TYPE_64 equ 0x04 ; 64 bit address |
PCI_BASE_ADDRESS_IO_MASK equ (not 0x03) |
PCI_BASE_ADDRESS_MEM_MASK equ (not 0x0f) |
PCI_BASE_ADDRESS_SPACE_IO equ 0x01 |
PCI_ROM_ADDRESS equ 0x30 ; 32 bits |
proc CONFIG_CMD,where:byte |
movzx eax,byte[pci_bus] |
shl eax,8 |
mov al,[pci_dev] |
shl eax,8 |
mov al,[where] |
and al,not 3 |
or eax,0x80000000 |
ret |
endp |
proc pci_read_config_byte,where:dword |
push edx |
stdcall CONFIG_CMD,[where] |
mov dx,0xCF8 |
out dx,eax |
mov edx,[where] |
and edx,3 |
add edx,0xCFC |
in al,dx |
pop edx |
ret |
endp |
proc pci_read_config_word,where:dword |
push edx |
stdcall CONFIG_CMD,[where] |
mov dx,0xCF8 |
out dx,eax |
mov edx,[where] |
and edx,2 |
add edx,0xCFC |
in ax,dx |
pop edx |
ret |
endp |
proc pci_read_config_dword,where:dword |
push edx |
stdcall CONFIG_CMD,[where] |
mov edx,0xCF8 |
out dx,eax |
mov edx,0xCFC |
in eax,dx |
pop edx |
ret |
endp |
proc pci_write_config_byte,where:dword,value:byte |
push edx |
stdcall CONFIG_CMD,[where] |
mov dx,0xCF8 |
out dx,eax |
mov edx,[where] |
and edx,3 |
add edx,0xCFC |
mov al,[value] |
out dx,al |
pop edx |
ret |
endp |
proc pci_write_config_word,where:dword,value:word |
push edx |
stdcall CONFIG_CMD,[where] |
mov dx,0xCF8 |
out dx,eax |
mov edx,[where] |
and edx,2 |
add edx,0xCFC |
mov ax,[value] |
out dx,ax |
pop edx |
ret |
endp |
proc pci_write_config_dword,where:dword,value:dword |
push edx |
stdcall CONFIG_CMD,[where] |
mov edx,0xCF8 |
out dx,eax |
mov edx,0xCFC |
mov eax,[value] |
out dx,eax |
pop edx |
ret |
endp |
; Set device to be a busmaster in case BIOS neglected to do so. |
; Also adjust PCI latency timer to a reasonable value, 32. |
proc adjust_pci_device |
DEBUGF 1,"K : adjust_pci_device\n" |
stdcall pci_read_config_word,PCI_COMMAND |
mov bx,ax |
or bx,PCI_COMMAND_MASTER or PCI_COMMAND_IO |
cmp ax,bx |
je @f |
DEBUGF 1,"K : adjust_pci_device: The PCI BIOS has not enabled this device!\nK : Updating PCI command %x->%x. pci_bus %x pci_device_fn %x\n",ax,bx,[pci_bus]:2,[pci_dev]:2 |
stdcall pci_write_config_word,PCI_COMMAND,ebx |
@@: |
stdcall pci_read_config_byte,PCI_LATENCY_TIMER |
cmp al,32 |
jae @f |
DEBUGF 1,"K : adjust_pci_device: PCI latency timer (CFLT) is unreasonably low at %d.\nK : Setting to 32 clocks.\n",al |
stdcall pci_write_config_byte,PCI_LATENCY_TIMER,32 |
@@: |
ret |
endp |
; Find the start of a pci resource |
proc pci_bar_start,index:dword |
stdcall pci_read_config_dword,[index] |
test eax,PCI_BASE_ADDRESS_SPACE_IO |
jz @f |
and eax,PCI_BASE_ADDRESS_IO_MASK |
jmp .exit |
@@: push eax |
and eax,PCI_BASE_ADDRESS_MEM_TYPE_MASK |
cmp eax,PCI_BASE_ADDRESS_MEM_TYPE_64 |
jne .not64 |
mov eax,[index] |
add eax,4 |
stdcall pci_read_config_dword,eax |
or eax,eax |
jz .not64 |
DEBUGF 1,"K : pci_bar_start: Unhandled 64bit BAR\n" |
add esp,4 |
or eax,-1 |
ret |
.not64: |
pop eax |
and eax,PCI_BASE_ADDRESS_MEM_MASK |
.exit: |
ret |
endp |
proc rtl8169_init_board |
DEBUGF 1,"K : rtl8169_init_board\n" |
call adjust_pci_device |
stdcall pci_bar_start,PCI_BASE_ADDRESS_0 |
mov [rtl8169_tpc.mmio_addr],eax |
; Soft reset the chip |
RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset |
; Check that the chip has finished the reset |
mov ecx,1000 |
@@: RTL_R8 RTL8169_REG_ChipCmd |
test al,RTL8169_CMD_Reset |
jz @f |
stdcall udelay,10 |
loop @b |
@@: |
; identify config method |
RTL_R32 RTL8169_REG_TxConfig |
and eax,0x7c800000 |
DEBUGF 1,"K : rtl8169_init_board: TxConfig & 0x7c800000 = 0x%x\n",eax |
mov esi,mac_info-8 |
@@: add esi,8 |
mov ecx,eax |
and ecx,[esi] |
cmp ecx,[esi] |
jne @b |
mov eax,[esi+4] |
mov [rtl8169_tpc.mcfg],eax |
mov [rtl8169_tpc.pcfg],PCFG_METHOD_3 |
stdcall RTL8169_READ_GMII_REG,3 |
and al,0x0f |
or al,al |
jnz @f |
mov [rtl8169_tpc.pcfg],PCFG_METHOD_1 |
jmp .pconf |
@@: dec al |
jnz .pconf |
mov [rtl8169_tpc.pcfg],PCFG_METHOD_2 |
.pconf: |
; identify chip attached to board |
mov ecx,10 |
mov eax,[rtl8169_tpc.mcfg] |
@@: dec ecx |
js @f |
cmp eax,[rtl_chip_info+ecx*8] |
jne @b |
mov [rtl8169_tpc.chipset],ecx |
jmp .match |
@@: |
; if unknown chip, assume array element #0, original RTL-8169 in this case |
DEBUGF 1,"K : rtl8169_init_board: PCI device: unknown chip version, assuming RTL-8169\n" |
RTL_R32 RTL8169_REG_TxConfig |
DEBUGF 1,"K : rtl8169_init_board: PCI device: TxConfig = 0x%x\n",eax |
mov [rtl8169_tpc.chipset],0 |
xor eax,eax |
inc eax |
ret |
.match: |
xor eax,eax |
ret |
endp |
proc rtl8169_hw_PHY_config |
DEBUGF 1,"K : rtl8169_hw_PHY_config: priv.mcfg=%d, priv.pcfg=%d\n",[rtl8169_tpc.mcfg],[rtl8169_tpc.pcfg] |
; DBG_PRINT("priv->mcfg=%d, priv->pcfg=%d\n", tpc->mcfg, tpc->pcfg); |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_04 |
jne .not_4 |
; stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001 |
; stdcall RTL8169_WRITE_GMII_REG,0x1b,0x841e |
; stdcall RTL8169_WRITE_GMII_REG,0x0e,0x7bfb |
; stdcall RTL8169_WRITE_GMII_REG,0x09,0x273a |
stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0002 |
stdcall RTL8169_WRITE_GMII_REG,0x01,0x90D0 |
stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000 |
jmp .exit |
.not_4: |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 |
je @f |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 |
jne .not_2_or_3 |
@@: stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0001 |
stdcall RTL8169_WRITE_GMII_REG,0x15,0x1000 |
stdcall RTL8169_WRITE_GMII_REG,0x18,0x65C7 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 |
stdcall RTL8169_WRITE_GMII_REG,0x03,0x00A1 |
stdcall RTL8169_WRITE_GMII_REG,0x02,0x0008 |
stdcall RTL8169_WRITE_GMII_REG,0x01,0x1020 |
stdcall RTL8169_WRITE_GMII_REG,0x00,0x1000 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x0800 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000 |
stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41 |
stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE60 |
stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140 |
stdcall RTL8169_WRITE_GMII_REG,0x00,0x0077 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x7800 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x7000 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000 |
stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01 |
stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20 |
stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95 |
stdcall RTL8169_WRITE_GMII_REG,0x00,0xFA00 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xA800 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xA000 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000 |
stdcall RTL8169_WRITE_GMII_REG,0x03,0xFF41 |
stdcall RTL8169_WRITE_GMII_REG,0x02,0xDE20 |
stdcall RTL8169_WRITE_GMII_REG,0x01,0x0140 |
stdcall RTL8169_WRITE_GMII_REG,0x00,0x00BB |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xB800 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xB000 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000 |
stdcall RTL8169_WRITE_GMII_REG,0x03,0xDF01 |
stdcall RTL8169_WRITE_GMII_REG,0x02,0xDF20 |
stdcall RTL8169_WRITE_GMII_REG,0x01,0xFF95 |
stdcall RTL8169_WRITE_GMII_REG,0x00,0xBF00 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xF800 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0xF000 |
stdcall RTL8169_WRITE_GMII_REG,0x04,0x0000 |
stdcall RTL8169_WRITE_GMII_REG,0x1F,0x0000 |
stdcall RTL8169_WRITE_GMII_REG,0x0B,0x0000 |
jmp .exit |
.not_2_or_3: |
; DBG_PRINT("tpc->mcfg=%d. Discard hw PHY config.\n", tpc->mcfg); |
DEBUGF 1,"K : tpc.mcfg=%d, discard hw PHY config\n",[rtl8169_tpc.mcfg] |
.exit: |
ret |
endp |
;proc pci_write_config_byte |
; ret |
;endp |
proc RTL8169_WRITE_GMII_REG,RegAddr:byte,value:dword |
DEBUGF 1,"K : RTL8169_WRITE_GMII_REG: 0x%x 0x%x\n",[RegAddr]:2,[value] |
movzx eax,[RegAddr] |
shl eax,16 |
or eax,[value] |
or eax,0x80000000 |
RTL_W32 RTL8169_REG_PHYAR,eax |
stdcall udelay,1000 |
mov ecx,2000 |
; Check if the RTL8169 has completed writing to the specified MII register |
@@: RTL_R32 RTL8169_REG_PHYAR |
test eax,0x80000000 |
jz .exit |
stdcall udelay,100 |
loop @b |
.exit: |
ret |
endp |
proc RTL8169_READ_GMII_REG,RegAddr:byte |
DEBUGF 1,"K : RTL8169_READ_GMII_REG: 0x%x\n",[RegAddr]:2 |
push ecx |
movzx eax,[RegAddr] |
shl eax,16 |
; or eax,0x0 |
RTL_W32 RTL8169_REG_PHYAR,eax |
stdcall udelay,1000 |
mov ecx,2000 |
; Check if the RTL8169 has completed retrieving data from the specified MII register |
@@: RTL_R32 RTL8169_REG_PHYAR |
test eax,0x80000000 |
jnz .exit |
stdcall udelay,100 |
loop @b |
or eax,-1 |
pop ecx |
ret |
.exit: |
RTL_R32 RTL8169_REG_PHYAR |
and eax,0xFFFF |
pop ecx |
ret |
endp |
proc rtl8169_set_rx_mode |
DEBUGF 1,"K : rtl8169_set_rx_mode\n" |
; IFF_ALLMULTI |
; Too many to filter perfectly -- accept all multicasts |
RTL_R32 RTL8169_REG_RxConfig |
mov ecx,[rtl8169_tpc.chipset] |
and eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask |
or eax,rtl8169_rx_config or (RTL8169_RXM_AcceptBroadcast or RTL8169_RXM_AcceptMulticast or RTL8169_RXM_AcceptMyPhys) |
RTL_W32 RTL8169_REG_RxConfig,eax |
; Multicast hash filter |
RTL_W32 RTL8169_REG_MAR0 + 0,0xffffffff |
RTL_W32 RTL8169_REG_MAR0 + 4,0xffffffff |
ret |
endp |
proc rtl8169_init_ring |
DEBUGF 1,"K : rtl8169_init_ring\n" |
xor eax,eax |
mov [rtl8169_tpc.cur_rx],eax |
mov [rtl8169_tpc.cur_tx],eax |
mov edi,[rtl8169_tpc.TxDescArray] |
mov ecx,(NUM_TX_DESC * sizeof.rtl8169_TxDesc) / 4 |
cld |
rep stosd |
mov edi,[rtl8169_tpc.RxDescArray] |
mov ecx,(NUM_RX_DESC * sizeof.rtl8169_RxDesc) / 4 |
rep stosd |
mov edi,rtl8169_tpc.Tx_skbuff |
mov eax,rtl8169_txb |
mov ecx,NUM_TX_DESC |
@@: stosd |
inc eax ; add eax,RX_BUF_SIZE ??? |
loop @b |
;!!! for (i = 0; i < NUM_RX_DESC; i++) { |
;!!! if (i == (NUM_RX_DESC - 1)) |
;!!! tpc->RxDescArray[i].status = (OWNbit | EORbit) | RX_BUF_SIZE; |
;!!! else |
;!!! tpc->RxDescArray[i].status = OWNbit | RX_BUF_SIZE; |
;!!! tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE]; |
;!!! tpc->RxDescArray[i].buf_addr = virt_to_bus(tpc->RxBufferRing[i]); |
;!!! } |
mov esi,rtl8169_tpc.RxBufferRing |
mov edi,[rtl8169_tpc.RxDescArray] |
mov eax,rtl8169_rxb |
mov ecx,NUM_RX_DESC |
@@: mov [esi],eax |
mov [edi+rtl8169_RxDesc.buf_addr],eax |
mov [edi+rtl8169_RxDesc.status],RTL8169_DSB_OWNbit or RX_BUF_SIZE |
add esi,4 |
add edi,sizeof.rtl8169_RxDesc |
add eax,RX_BUF_SIZE |
loop @b |
or [edi - sizeof.rtl8169_RxDesc + rtl8169_RxDesc.status],RTL8169_DSB_EORbit |
ret |
endp |
proc rtl8169_hw_start |
DEBUGF 1,"K : rtl8169_hw_start\n" |
; Soft reset the chip |
RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_Reset |
; Check that the chip has finished the reset |
mov ecx,1000 |
@@: RTL_R8 RTL8169_REG_ChipCmd |
and al,RTL8169_CMD_Reset |
jz @f |
stdcall udelay,10 |
loop @b |
@@: |
RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Unlock |
RTL_W8 RTL8169_REG_ChipCmd,RTL8169_CMD_TxEnb or RTL8169_CMD_RxEnb |
RTL_W8 RTL8169_REG_ETThReg,ETTh |
; For gigabit rtl8169 |
RTL_W16 RTL8169_REG_RxMaxSize,RxPacketMaxSize |
; Set Rx Config register |
RTL_R32 RTL8169_REG_RxConfig |
mov ecx,[rtl8169_tpc.chipset] |
and eax,[rtl_chip_info + ecx * 8 + 4] ; RxConfigMask |
or eax,rtl8169_rx_config |
RTL_W32 RTL8169_REG_RxConfig,eax |
; Set DMA burst size and Interframe Gap Time |
RTL_W32 RTL8169_REG_TxConfig,(TX_DMA_BURST shl RTL8169_TXC_DMAShift) or (InterFrameGap shl RTL8169_TXC_InterFrameGapShift) |
RTL_R16 RTL8169_REG_CPlusCmd |
RTL_W16 RTL8169_REG_CPlusCmd,ax |
RTL_R16 RTL8169_REG_CPlusCmd |
or ax,1 shl 3 |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 |
jne @f |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 |
jne @f |
or ax,1 shl 14 |
; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0xE0: bit-3 and bit-14\n" |
jmp .set |
@@:;DEBUGF 1,"K : Set MAC Reg C+CR Offset 0xE0: bit-3\n" |
.set: RTL_W16 RTL8169_REG_CPlusCmd,ax |
; RTL_W16 0xE2,0x1517 |
; RTL_W16 0xE2,0x152a |
; RTL_W16 0xE2,0x282a |
RTL_W16 0xE2,0x0000 |
MOV [rtl8169_tpc.cur_rx],0 |
RTL_W32 RTL8169_REG_TxDescStartAddr,[rtl8169_tpc.TxDescArray] |
RTL_W32 RTL8169_REG_RxDescStartAddr,[rtl8169_tpc.RxDescArray] |
RTL_W8 RTL8169_REG_Cfg9346,RTL8169_CFG_9346_Lock |
stdcall udelay,10 |
RTL_W32 RTL8169_REG_RxMissed,0 |
call rtl8169_set_rx_mode |
; no early-rx interrupts |
RTL_R16 RTL8169_REG_MultiIntr |
and ax,0xF000 |
RTL_W16 RTL8169_REG_MultiIntr,ax |
RTL_W16 RTL8169_REG_IntrMask,0 ; rtl8169_intr_mask |
ret |
endp |
proc udelay,msec:dword |
push esi |
mov esi,[msec] |
call delay_ms |
pop esi |
ret |
endp |
;*************************************************************************** |
; Function |
; rtl8169_probe |
; Description |
; Searches for an ethernet card, enables it and clears the rx buffer |
; If a card was found, it enables the ethernet -> TCPIP link |
; Destroyed registers |
; eax, ebx, ecx, edx |
; |
;*************************************************************************** |
proc rtl8169_probe |
DEBUGF 1,"K : rtl8169_probe: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2 |
call rtl8169_init_board |
mov ecx,MAC_ADDR_LEN |
mov edx,[rtl8169_tpc.mmio_addr] |
add edx,RTL8169_REG_MAC0 |
xor ebx,ebx |
; Get MAC address. FIXME: read EEPROM |
@@: RTL_R8 dx |
mov [node_addr+ebx],al |
inc edx |
inc ebx |
loop @b |
DEBUGF 1,"K : rtl8169_probe: MAC = %x-%x-%x-%x-%x-%x\n",[node_addr+0]:2,[node_addr+1]:2,[node_addr+2]:2,[node_addr+3]:2,[node_addr+4]:2,[node_addr+5]:2 |
; Config PHY |
stdcall rtl8169_hw_PHY_config |
; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0x82h = 0x01h\n" |
RTL_W8 0x82,0x01 |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_03 |
jae @f |
; DEBUGF 1,"K : Set PCI Latency=0x40\n" |
; stdcall pci_write_config_byte,PCI_LATENCY_TIMER,0x40 |
@@: |
cmp [rtl8169_tpc.mcfg],MCFG_METHOD_02 |
jne @f |
; DEBUGF 1,"K : Set MAC Reg C+CR Offset 0x82h = 0x01h\n" |
RTL_W8 0x82,0x01 |
; DEBUGF 1,"K : Set PHY Reg 0x0bh = 0x00h\n" |
stdcall RTL8169_WRITE_GMII_REG,0x0b,0x0000 ; w 0x0b 15 0 0 |
@@: |
; if TBI is not enabled |
RTL_R8 RTL8169_REG_PHYstatus |
test al,RTL8169_PHYS_TBI_Enable |
jz .tbi_dis |
stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG |
; enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged |
and eax,0x0C1F |
or eax,RTL8169_PHY_Cap_10_Half or RTL8169_PHY_Cap_10_Full or RTL8169_PHY_Cap_100_Half or RTL8169_PHY_Cap_100_Full |
stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_AUTO_NEGO_REG,eax |
; enable 1000 Full Mode |
stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_1000_CTRL_REG,RTL8169_PHY_Cap_1000_Full or RTL8169_PHY_Cap_1000_Half ; rtl8168 |
; Enable auto-negotiation and restart auto-nigotiation |
stdcall RTL8169_WRITE_GMII_REG,RTL8169_PHY_CTRL_REG,RTL8169_PHY_Enable_Auto_Nego or RTL8169_PHY_Restart_Auto_Nego |
stdcall udelay,100 |
mov ecx,10000 |
; wait for auto-negotiation process |
@@: dec ecx |
jz @f |
stdcall RTL8169_READ_GMII_REG,RTL8169_PHY_STAT_REG |
stdcall udelay,100 |
test eax,RTL8169_PHY_Auto_Neco_Comp |
jz @b |
RTL_R8 RTL8169_REG_PHYstatus |
jmp @f |
.tbi_dis: |
stdcall udelay,100 |
@@: |
call rtl8169_reset |
ret |
endp |
;*************************************************************************** |
; Function |
; rt8169_reset |
; Description |
; Place the chip (ie, the ethernet card) into a virgin state |
; Destroyed registers |
; eax, ebx, ecx, edx |
; |
;*************************************************************************** |
proc rtl8169_reset |
DEBUGF 1,"K : rtl8169_reset: 0x%x : 0x%x 0x%x\n",[io_addr]:8,[pci_bus]:2,[pci_dev]:2 |
mov [rtl8169_tpc.TxDescArrays],rtl8169_tx_ring |
; Tx Desscriptor needs 256 bytes alignment |
mov [rtl8169_tpc.TxDescArray],rtl8169_tx_ring |
mov [rtl8169_tpc.RxDescArrays],rtl8169_rx_ring |
; Rx Desscriptor needs 256 bytes alignment |
mov [rtl8169_tpc.RxDescArray],rtl8169_rx_ring |
call rtl8169_init_ring |
call rtl8169_hw_start |
; Construct a perfect filter frame with the mac address as first match |
; and broadcast for all others |
mov edi,rtl8169_txb |
or al,-1 |
mov ecx,192 |
cld |
rep stosb |
mov esi,node_addr |
mov edi,rtl8169_txb |
movsd |
movsw |
mov eax,[pci_data] |
mov [eth_status],eax |
ret |
endp |
;*************************************************************************** |
; Function |
; rtl8169_transmit |
; Description |
; Transmits a packet of data via the ethernet card |
; d - edi - Pointer to 48 bit destination address |
; t - bx - Type of packet |
; s - ecx - size of packet |
; p - esi - pointer to packet data |
; Destroyed registers |
; eax, edx, esi, edi |
; |
;*************************************************************************** |
proc rtl8169_transmit |
DEBUGF 1,"K : rtl8169_transmit\n" ;: 0x%x : 0x%x 0x%x 0x%x 0x%x\n",[io_addr]:8,edi,bx,ecx,esi |
push ecx edx esi |
mov eax,MAX_ETH_FRAME_SIZE |
mul [rtl8169_tpc.cur_tx] |
mov esi,edi |
; point to the current txb incase multiple tx_rings are used |
mov edi,[rtl8169_tpc.Tx_skbuff + eax * 4] |
mov eax,edi |
cld |
; copy destination address |
movsd |
movsw |
; copy source address |
mov esi,node_addr |
movsd |
movsw |
; copy packet type |
mov [edi],bx |
add edi,2 |
; copy the packet data |
pop esi edx ecx |
push ecx |
shr ecx,2 |
rep movsd |
pop ecx |
push ecx |
and ecx,3 |
rep movsb |
;!!! s += ETH_HLEN; |
;!!! s &= 0x0FFF; |
;!!! while (s < ETH_ZLEN) |
;!!! ptxb[s++] = '\0'; |
mov edi,eax |
pop ecx |
push eax |
add ecx,ETH_HLEN |
and ecx,0x0FFF |
xor al,al |
add edi,ecx |
@@: cmp ecx,ETH_ZLEN |
jae @f |
stosb |
inc ecx |
jmp @b |
@@: pop eax |
mov ebx,eax |
mov eax,sizeof.rtl8169_TxDesc |
mul [rtl8169_tpc.cur_tx] |
add eax,[rtl8169_tpc.TxDescArray] |
xchg eax,ebx |
mov [ebx + rtl8169_TxDesc.buf_addr],eax |
mov eax,ecx |
cmp eax,ETH_ZLEN |
jae @f |
mov eax,ETH_ZLEN |
@@: or eax,RTL8169_DSB_OWNbit or RTL8169_DSB_FSbit or RTL8169_DSB_LSbit |
cmp [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1 |
jne @f |
or eax,RTL8169_DSB_EORbit |
@@: mov [ebx + rtl8169_TxDesc.status],eax |
RTL_W8 RTL8169_REG_TxPoll,0x40 ; set polling bit |
inc [rtl8169_tpc.cur_tx] |
and [rtl8169_tpc.cur_tx],NUM_TX_DESC - 1 |
;!!! to = currticks() + TX_TIMEOUT; |
;!!! while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to)); /* wait */ |
mov ecx,TX_TIMEOUT / 10 |
@@: test [ebx + rtl8169_TxDesc.status],RTL8169_DSB_OWNbit |
jnz @f |
stdcall udelay,10 |
loop @b |
DEBUGF 1,"K : rtl8169_transmit: TX Time Out\n" |
@@: |
ret |
endp |
;*************************************************************************** |
; Function |
; rtl8169_poll |
; |
; Description |
; Polls the ethernet card for a received packet |
; Received data, if any, ends up in Ether_buffer |
; Destroyed register(s) |
; eax, edx, ecx |
; |
;*************************************************************************** |
proc rtl8169_poll |
; DEBUGF 1,"K : rtl8169_poll\n" ;: 0x%x : none\n",[io_addr]:8 |
mov word[eth_rx_data_len],0 |
mov eax,sizeof.rtl8169_RxDesc |
mul [rtl8169_tpc.cur_rx] |
add eax,[rtl8169_tpc.RxDescArray] |
mov ebx,eax |
; DEBUGF 1,"K : rtl8169_RxDesc.status = 0x%x\n",[ebx + rtl8169_RxDesc.status] |
test [ebx + rtl8169_RxDesc.status],RTL8169_DSB_OWNbit ; 0x80000600 |
jnz .exit |
; DEBUGF 1,"K : rtl8169_tpc.cur_rx = %u\n",[rtl8169_tpc.cur_rx] |
; h/w no longer present (hotplug?) or major error, bail |
RTL_R16 RTL8169_REG_IntrStatus |
; DEBUGF 1,"K : IntrStatus = 0x%x\n",ax |
cmp ax,0xFFFF |
je .exit |
push eax |
and ax,not (RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK) |
RTL_W16 RTL8169_REG_IntrStatus,ax |
mov eax,[ebx + rtl8169_RxDesc.status] |
; DEBUGF 1,"K : RxDesc.status = 0x%x\n",eax |
test eax,RTL8169_SD_RxRES |
jnz .else |
and eax,0x00001FFF |
; jz .exit.pop |
add eax,-4 |
mov [eth_rx_data_len],ax |
DEBUGF 1,"K : rtl8169_poll: data length = %u\n",ax |
push eax |
mov ecx,eax |
shr ecx,2 |
mov eax,[rtl8169_tpc.cur_rx] |
mov edx,[rtl8169_tpc.RxBufferRing + eax * 4] |
mov esi,edx |
mov edi,Ether_buffer |
cld |
rep movsd |
pop ecx |
and ecx,3 |
rep movsb |
mov eax,RTL8169_DSB_OWNbit or RX_BUF_SIZE |
cmp [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1 |
jne @f |
or eax,RTL8169_DSB_EORbit |
@@: mov [ebx + rtl8169_RxDesc.status],eax |
mov [ebx + rtl8169_RxDesc.buf_addr],edx |
jmp @f |
.else: |
DEBUGF 1,"K : rtl8169_poll: Rx Error\n" |
; FIXME: shouldn't I reset the status on an error |
@@: |
inc [rtl8169_tpc.cur_rx] |
and [rtl8169_tpc.cur_rx],NUM_RX_DESC - 1 |
.exit.pop: |
pop eax |
and ax,RTL8169_ISB_RxFIFOOver or RTL8169_ISB_RxOverflow or RTL8169_ISB_RxOK |
RTL_W16 RTL8169_REG_IntrStatus,ax |
.exit: |
ret |
endp |
proc rtl8169_cable |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/eth_drv/drivers/sis900.inc |
---|
0,0 → 1,1152 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; SIS900.INC ;; |
;; ;; |
;; Ethernet driver for Menuet OS ;; |
;; ;; |
;; Version 0.4 26 April 2004 ;; |
;; ;; |
;; This driver is based on the SIS900 driver from ;; |
;; the etherboot 5.0.6 project. The copyright statement is ;; |
;; ;; |
;; GNU GENERAL PUBLIC LICENSE ;; |
;; Version 2, June 1991 ;; |
;; ;; |
;; remaining parts Copyright 2004 Jason Delozier, ;; |
;; cordata51@hotmail.com ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;; Updates: ;; |
;; Revision Look up table and SIS635 Mac Address by Jarek Pelczar ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************** |
; 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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/eth_drv/pci.inc |
---|
0,0 → 1,349 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;*************************************************************************** |
; |
; PCI CODE FOLLOWS |
; |
; the following functions provide access to the PCI interface. |
; These functions are used by scan_bus, and also some ethernet drivers |
; |
;*************************************************************************** |
; PCI Bus defines |
PCI_HEADER_TYPE equ 0x0e ;8 bit |
PCI_BASE_ADDRESS_0 equ 0x10 ;32 bit |
PCI_BASE_ADDRESS_5 equ 0x24 ;32 bits |
PCI_BASE_ADDRESS_SPACE_IO equ 0x01 |
PCI_VENDOR_ID equ 0x00 ;16 bit |
PCI_BASE_ADDRESS_IO_MASK equ 0xFFFFFFFC |
;*************************************************************************** |
; Function |
; config_cmd |
; |
; Description |
; creates a command dword for use with the PCI bus |
; bus # in ebx |
; devfn in ecx |
; where in edx |
; |
; command dword returned in eax |
; Only eax destroyed |
;*************************************************************************** |
config_cmd: |
push ecx |
mov eax, ebx |
shl eax, 16 |
or eax, 0x80000000 |
shl ecx, 8 |
or eax, ecx |
pop ecx |
or eax, edx |
and eax, 0xFFFFFFFC |
ret |
;*************************************************************************** |
; Function |
; pcibios_read_config_byte |
; |
; Description |
; reads a byte from the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; byte returned in al ( rest of eax zero ) |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_read_config_byte: |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
xor eax, eax |
and dx, 0x03 |
add dx, 0xCFC |
; and dx, 0xFFC |
in al, dx |
ret |
;*************************************************************************** |
; Function |
; pcibios_read_config_word |
; |
; Description |
; reads a word from the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; word returned in ax ( rest of eax zero ) |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_read_config_word: |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
xor eax, eax |
and dx, 0x02 |
add dx, 0xCFC |
; and dx, 0xFFC |
in ax, dx |
ret |
;*************************************************************************** |
; Function |
; pcibios_read_config_dword |
; |
; Description |
; reads a dword from the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; dword returned in eax |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_read_config_dword: |
push edx |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
xor eax, eax |
mov dx, 0xCFC |
in eax, dx |
pop edx |
ret |
;*************************************************************************** |
; Function |
; pcibios_write_config_byte |
; |
; Description |
; write a byte in al to the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_write_config_byte: |
push ax |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
pop ax |
and dx, 0x03 |
add dx, 0xCFC |
out dx, al |
ret |
;*************************************************************************** |
; Function |
; pcibios_write_config_word |
; |
; Description |
; write a word in ax to the PCI config space |
; bus # in ebx |
; devfn in ecx |
; where in edx ( ls 16 bits significant ) |
; |
; Only eax/edx destroyed |
;*************************************************************************** |
pcibios_write_config_word: |
push ax |
call config_cmd |
push dx |
mov dx, 0xCF8 |
out dx, eax |
pop dx |
pop ax |
and dx, 0x02 |
add dx, 0xCFC |
out dx, ax |
ret |
;*************************************************************************** |
; Function |
; delay_us |
; |
; Description |
; delays for 30 to 60 us |
; |
; I would prefer this routine to be able to delay for |
; a selectable number of microseconds, but this works for now. |
; |
; If you know a better way to do 2us delay, pleae tell me! |
;*************************************************************************** |
delay_us: |
push eax |
push ecx |
mov ecx,2 |
in al,0x61 |
and al,0x10 |
mov ah,al |
cld |
dcnt1: |
in al,0x61 |
and al,0x10 |
cmp al,ah |
jz dcnt1 |
mov ah,al |
loop dcnt1 |
pop ecx |
pop eax |
ret |
;*************************************************************************** |
; Function |
; scan_bus |
; |
; Description |
; Scans the PCI bus for a supported device |
; If a supported device is found, the drvr_ variables are initialised |
; to that drivers functions ( as defined in the PCICards table) |
; |
; io_addr holds card I/O space. 32 bit, but only LS 16 bits valid |
; pci_data holds the PCI vendor + device code |
; pci_dev holds PCI bus dev # |
; pci_bus holds PCI bus # |
; |
; io_addr will be zero if no card found |
; |
;*************************************************************************** |
scan_bus: |
xor eax, eax |
mov [hdrtype], al |
mov [pci_data], eax |
xor ebx, ebx ; ebx = bus# 0 .. 255 |
sb_bus_loop: |
xor ecx, ecx ; ecx = devfn# 0 .. 254 ( not 255? ) |
sb_devf_loop: |
mov eax, ecx |
and eax, 0x07 |
cmp eax, 0 |
jne sb_001 |
mov edx, PCI_HEADER_TYPE |
call pcibios_read_config_byte |
mov [hdrtype], al |
jmp sb_002 |
sb_001: |
mov al, [hdrtype] |
and al, 0x80 |
cmp al, 0x80 |
jne sb_inc_devf |
sb_002: |
mov edx, PCI_VENDOR_ID |
call pcibios_read_config_dword |
mov [vendor_device], eax |
cmp eax, 0xffffffff |
je sb_empty |
cmp eax, 0 |
jne sb_check_vendor |
sb_empty: |
mov [hdrtype], byte 0 |
jmp sb_inc_devf |
sb_check_vendor: |
; iterate though PCICards until end or match found |
mov esi, PCICards |
sb_check: |
cmp [esi], dword 0 |
je sb_inc_devf ; Quit if at last entry |
cmp eax, [esi] |
je sb_got_card |
add esi, PCICARDS_ENTRY_SIZE |
jmp sb_check |
sb_got_card: |
; indicate that we have found the card |
mov [pci_data], eax |
mov [pci_dev], ecx |
mov [pci_bus], ebx |
; Define the driver functions |
push eax |
mov eax, [esi+4] |
mov [drvr_probe], eax |
mov eax, [esi+8] |
mov [drvr_reset], eax |
mov eax, [esi+12] |
mov [drvr_poll], eax |
mov eax, [esi+16] |
mov [drvr_transmit], eax |
mov eax, [esi+20] |
mov [drvr_cable], eax |
pop eax |
mov edx, PCI_BASE_ADDRESS_0 |
sb_reg_check: |
call pcibios_read_config_dword |
mov [io_addr], eax |
and eax, PCI_BASE_ADDRESS_IO_MASK |
cmp eax, 0 |
je sb_inc_reg |
mov eax, [io_addr] |
and eax, PCI_BASE_ADDRESS_SPACE_IO |
cmp eax, 0 |
je sb_inc_reg |
mov eax, [io_addr] |
and eax, PCI_BASE_ADDRESS_IO_MASK |
mov [io_addr], eax |
sb_exit1: |
ret |
sb_inc_reg: |
add edx, 4 |
cmp edx, PCI_BASE_ADDRESS_5 |
jbe sb_reg_check |
sb_inc_devf: |
inc ecx |
cmp ecx, 255 |
jb sb_devf_loop |
inc ebx |
cmp ebx, 256 |
jb sb_bus_loop |
; We get here if we didn't find our card |
; set io_addr to 0 as an indication |
xor eax, eax |
mov [io_addr], eax |
sb_exit2: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/socket.inc |
---|
0,0 → 1,930 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; SOCKET.INC ;; |
;; ;; |
;; Sockets constants, structures and functions ;; |
;; ;; |
;; Last revision: 11.11.2006 ;; |
;; ;; |
;; This file contains the following: ;; |
;; is_localport_unused ;; |
;; get_free_socket ;; |
;; socket_open ;; |
;; socket_open_tcp ;; |
;; socket_close ;; |
;; socket_close_tcp ;; |
;; socket_poll ;; |
;; socket_status ;; |
;; socket_read ;; |
;; socket_write ;; |
;; socket_write_tcp ;; |
;; ;; |
;; ;; |
;; Changes history: ;; |
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; |
;; 11.11.2006 - [Johnny_B] and [smb] ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; |
; 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 |
; |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 0| Status ( of this buffer ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 4| Application Process ID | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 8| Local IP Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 12| Local IP Port | Unused ( set to 0 ) | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 16| Remote IP Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; 20| 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 offset from |
; 76| RX Data | |
; +-+-+-.......... -+ |
; so, define struct |
struc SOCKET |
{ .Status dd ? ;+00 - Status ( of this buffer ) |
.PID dd ? ;+04 - Application Process ID |
.LocalIP dd ? ;+08 - Local IP Address |
.LocalPort dw ? ;+12 - Local Port |
.UnusedL dw ? ;+14 - may be removed in future |
.RemoteIP dd ? ;+16 - Remote IP Address |
.RemotePort dw ? ;+20 - Remote Port |
.UnusedR dw ? ;+22 - may be removed in future |
.rxDataCount dd ? ;+24 - Rx Data Count |
.TCBState dd ? ;+28 - TCB STATE |
.TCBTimer dd ? ;+32 - TCB Timer (seconds) |
.ISS dd ? ;+36 - Initial Send Sequence |
.IRS dd ? ;+40 - Initial Receive Sequence |
.SND_UNA dd ? ;+44 - Sequence number of unack'ed sent packets |
.SND_NXT dd ? ;+48 - Next send sequence number to use |
.SND_WND dd ? ;+52 - Send window |
.RCV_NXT dd ? ;+56 - Next receive sequence number to use |
.RCV_WND dd ? ;+60 - Receive window |
.SEG_LEN dd ? ;+64 - Segment length |
.SEG_WND dd ? ;+68 - Segment window |
.wndsizeTimer dd ? ;+72 - Retransmit queue # NOW WINDOW SIZE TIMER |
.rxData dd ? ;+76 - receive data buffer here |
} |
virtual at 0 |
SOCKET SOCKET |
end virtual |
; simple macro calcing real memory address of SOCKET struct by socket's |
macro Index2RealAddr reg |
{ |
shl reg, 12 |
add reg, sockets |
} |
;Constants |
; current socket statuses |
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 |
;*************************************************************************** |
; 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 + SOCKET.LocalPort], 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 + SOCKET.Status], 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 |
; 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 |
Index2RealAddr eax |
mov [eax + SOCKET.Status], dword SOCK_OPEN |
xchg bh, bl |
mov [eax + SOCKET.LocalPort], bx |
xchg ch, cl |
mov [eax + SOCKET.RemotePort], cx |
mov ebx, [stack_ip] |
mov [eax + SOCKET.LocalIP], ebx |
mov [eax + SOCKET.RemoteIP], edx |
mov [eax + SOCKET.rxDataCount], dword 0 ; recieved data count |
mov esi, [TASK_BASE] |
mov ebx, [esi+TASKDATA.pid] |
mov [eax + SOCKET.PID], 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 |
Index2RealAddr eax |
mov [sktAddr], eax |
mov [eax], dword SOCK_OPEN |
; TODO - check this works! |
mov [eax + SOCKET.wndsizeTimer], dword 0 ; Reset the window timer. |
xchg bh, bl |
mov [eax + SOCKET.LocalPort], bx |
; mov [eax + 12], byte bh ; Local port ( LS 16 bits ) |
; mov [eax + 13], byte bl ; Local port ( LS 16 bits ) |
xchg ch, cl |
mov [eax + SOCKET.RemotePort], cx |
; mov [eax + 20], ch ; Remote Port ( LS 16 bits ) |
; mov [eax + 21], cl ; Remote Port ( LS 16 bits ) |
mov ebx, [stack_ip] |
mov [eax + SOCKET.LocalIP], ebx |
mov [eax + SOCKET.RemoteIP], edx |
mov [eax + SOCKET.rxDataCount], dword 0 |
; 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 + SOCKET.TCBState], ebx ; Indicate the state of the TCB |
mov esi, [TASK_BASE] |
mov ecx, [esi+TASKDATA.pid] |
mov [eax + SOCKET.PID], 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: |
Index2RealAddr ebx |
mov eax, 0xFFFFFFFF ; assume this operation will fail.. |
cmp [ebx + SOCKET.Status], 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: |
mov [esi], byte 0xFF |
jmp sct001 |
sct003: |
popa |
Index2RealAddr ebx |
mov [sktAddr], ebx |
mov eax, 0xFFFFFFFF ; assume this operation will fail.. |
cmp [ebx + SOCKET.Status], 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 + SOCKET.TCBState] |
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 + SOCKET.TCBState], eax |
xor eax, eax |
jmp sct_send |
sct_finwait1: |
; Send a fin, then enter finwait2 state |
mov eax, TCB_FIN_WAIT_1 |
mov [ebx + SOCKET.TCBState], 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: |
Index2RealAddr ebx |
mov eax, [ebx + SOCKET.rxDataCount] |
ret |
;*************************************************************************** |
; Function |
; socket_status |
; |
; Description |
; socket # in ebx |
; returns TCB state in eax. |
; |
;*************************************************************************** |
socket_status: |
Index2RealAddr ebx |
mov eax, [ebx + SOCKET.TCBState] |
ret |
;*************************************************************************** |
; Function |
; socket_read |
; |
; Description |
; socket # in ebx |
; returns # of bytes remaining in eax, data in bl |
; |
;*************************************************************************** |
socket_read: |
Index2RealAddr ebx |
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes |
mov ecx, 1 |
test eax, eax |
jz sr2 |
dec eax |
mov esi, ebx ; esi is address of socket |
mov [ebx + SOCKET.rxDataCount], eax ; store new count |
;movzx ebx, byte [ebx + SOCKET.rxData] ; get the byte |
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_read_packet |
; |
; Description |
; socket # in ebx |
; datapointer # in ecx |
; buffer size in edx |
; returns # of bytes copied in eax |
; |
;*************************************************************************** |
socket_read_packet: |
Index2RealAddr ebx ; get real socket address |
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes |
test eax, eax ; if count of bytes is zero.. |
jz .exit ; exit function (eax will be zero) |
test edx, edx ; if buffer size is zero, copy all data |
jz .copyallbytes |
cmp edx, eax ; if buffer size is larger then the bytes of data, copy all data |
jge .copyallbytes |
sub eax, edx ; store new count (data bytes in buffer - bytes we're about to copy) |
mov [ebx + SOCKET.rxDataCount], eax ; |
push eax |
mov eax, edx ; number of bytes we want to copy must be in eax |
call .startcopy ; copy to the application |
mov esi, ebx ; now we're going to copy the remaining bytes to the beginning |
add esi, SOCKETHEADERSIZE ; we dont need to copy the header |
mov edi, esi ; edi is where we're going to copy to |
add esi, edx ; esi is from where we copy |
pop ecx ; count of bytes we have left |
push ecx ; push it again so we can re-use it later |
shr ecx, 2 ; divide eax by 4 |
cld |
rep movsd ; copy all full dwords |
pop ecx |
and ecx, 3 |
rep movsb ; copy remaining bytes |
ret ; at last, exit |
.copyallbytes: |
xor esi, esi |
mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero) |
.startcopy: |
mov edi, ecx ; |
; add edi, std_application_base_address ; get data pointer to buffer in application |
mov esi, ebx ; |
add esi, SOCKETHEADERSIZE ; we dont need to copy the header |
mov ecx, eax ; eax is count of bytes |
push ecx |
shr ecx, 2 ; divide eax by 4 |
cld ; copy all full dwords |
rep movsd ; |
pop ecx |
and ecx, 3 |
rep movsb ; copy the rest bytes |
.exit: |
ret ; exit, or go back to shift remaining bytes if any |
;*************************************************************************** |
; 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: |
Index2RealAddr ebx |
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, [TASK_BASE] |
add edi, TASKDATA.mem_start |
add eax, [edi] |
mov esi, eax |
mov edi, edx |
add edi, 28 |
cld |
rep movsb ; copy the data across |
; we have edx as IPbuffer ptr. |
; Fill in the UDP checksum |
; First, fill in pseudoheader |
mov eax, [edx + 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 |
GET_IHL ecx,edx ; get IP-Header length |
stdcall checksum_jb,edx,ecx ; buf_ptr, buf_size |
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: |
Index2RealAddr ebx |
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 + SOCKET.wndsizeTimer], 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, [TASK_BASE] |
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 |
swt001: |
xor eax, eax |
swt_exit: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/icmp.inc |
---|
0,0 → 1,192 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ICMP.INC ;; |
;; ;; |
;; Internet Control Message Protocol ( RFC 792 ) ;; |
;; ;; |
;; Last revision: 11.11.2006 ;; |
;; ;; |
;; This file contains the following: ;; |
;; icmp_rx - processes ICMP-packets received by the IP layer ;; |
;; ;; |
;; Changes history: ;; |
;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; |
;; 11.11.2006 - [Johnny_B] and [smb] ;; |
;; ;; |
;; Current status: ;; |
;; This implemetation of ICMP proto supports message of ECHO type. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
struc ICMP_PACKET |
{ .Type db ? ;+00 |
.Code db ? ;+01 |
.Checksum dw ? ;+02 |
.Identifier dw ? ;+04 |
.SequenceNumber dw ? ;+06 |
.Data db ? ;+08 |
} |
virtual at 0 |
ICMP_PACKET ICMP_PACKET |
end virtual |
; Example: |
; ECHO message format |
; |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Type | Code | Checksum | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Identifier | Sequence Number | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Data ... |
; +-+-+-+-+- |
; |
; |
; ICMP types & codes, RFC 792 and FreeBSD's ICMP sources |
; |
ICMP_ECHOREPLY equ 0 ; echo reply message |
ICMP_UNREACH equ 3 |
ICMP_UNREACH_NET equ 0 ; bad net |
ICMP_UNREACH_HOST equ 1 ; bad host |
ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol |
ICMP_UNREACH_PORT equ 3 ; bad port |
ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop |
ICMP_UNREACH_SRCFAIL equ 5 ; src route failed |
ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net |
ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host |
ICMP_UNREACH_ISOLATED equ 8 ; src host isolated |
ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access |
ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto |
ICMP_UNREACH_TOSNET equ 11 ; bad tos for net |
ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host |
ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib |
ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio. |
ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff |
ICMP_SOURCEQUENCH equ 4 ; packet lost, slow down |
ICMP_REDIRECT equ 5 ; shorter route, codes: |
ICMP_REDIRECT_NET equ 0 ; for network |
ICMP_REDIRECT_HOST equ 1 ; for host |
ICMP_REDIRECT_TOSNET equ 2 ; for tos and net |
ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host |
ICMP_ALTHOSTADDR equ 6 ; alternate host address |
ICMP_ECHO equ 8 ; echo service |
ICMP_ROUTERADVERT equ 9 ; router advertisement |
ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement |
ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing |
ICMP_ROUTERSOLICIT equ 10 ; router solicitation |
ICMP_TIMXCEED equ 11 ; time exceeded, code: |
ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit |
ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass |
ICMP_PARAMPROB equ 12 ; ip header bad |
ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr |
ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent |
ICMP_PARAMPROB_LENGTH equ 2 ; bad length |
ICMP_TSTAMP equ 13 ; timestamp request |
ICMP_TSTAMPREPLY equ 14 ; timestamp reply |
ICMP_IREQ equ 15 ; information request |
ICMP_IREQREPLY equ 16 ; information reply |
ICMP_MASKREQ equ 17 ; address mask request |
ICMP_MASKREPLY equ 18 ; address mask reply |
ICMP_TRACEROUTE equ 30 ; traceroute |
ICMP_DATACONVERR equ 31 ; data conversion error |
ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect |
ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you |
ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here |
ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req |
ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply |
ICMP_SKIP equ 39 ; SKIP |
ICMP_PHOTURIS equ 40 ; Photuris |
ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index |
ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed |
ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed |
;*************************************************************************** |
; Function |
; icmp_rx [by Johnny_B] |
; |
; Description |
; ICMP protocol handler |
; This is a kernel function, called by ip_rx |
; |
; IN: |
; buffer_number - # of IP-buffer. This buffer must be reused or marked as empty afterwards |
; IPPacketBase - IP_PACKET base address |
; IPHeaderLength - Header length of IP_PACKET |
; |
; OUT: |
; EAX=not defined |
; |
; All used registers will be saved |
; |
;*************************************************************************** |
proc icmp_rx stdcall uses ebx esi edi,\ |
buffer_number:DWORD,IPPacketBase:DWORD,IPHeaderLength:DWORD |
mov esi,[IPPacketBase] ;esi=IP_PACKET base address |
mov edi, esi |
add edi,[IPHeaderLength] ;edi=ICMP_PACKET base address |
cmp byte[edi + ICMP_PACKET.Type], ICMP_ECHO ; Is this an echo request? discard if not |
jz .icmp_echo |
mov eax, [buffer_number] |
call freeBuff |
jmp .exit |
.icmp_echo: |
; swap the source and destination addresses |
mov ecx, [esi + IP_PACKET.DestinationAddress] |
mov ebx, [esi + IP_PACKET.SourceAddress] |
mov [esi + IP_PACKET.DestinationAddress], ebx |
mov [esi + IP_PACKET.SourceAddress], ecx |
; recalculate the IP header checksum |
mov eax,[IPHeaderLength] |
stdcall checksum_jb,esi,eax ;buf_ptr,buf_size |
mov byte[esi + IP_PACKET.HeaderChecksum], ah |
mov byte[esi + IP_PACKET.HeaderChecksum + 1], al ; ?? correct byte order? |
mov byte[edi + ICMP_PACKET.Type], ICMP_ECHOREPLY ; change the request to a response |
mov word[edi + ICMP_PACKET.Checksum], 0 ; clear ICMP checksum prior to re-calc |
; Calculate the length of the ICMP data ( IP payload) |
xor eax, eax |
mov ah, byte[esi + IP_PACKET.TotalLength] |
mov al, byte[esi + IP_PACKET.TotalLength + 1] |
sub ax, word[IPHeaderLength] ;ax=ICMP-packet length |
stdcall checksum_jb,edi,eax ;buf_ptr,buf_size |
mov byte[edi + ICMP_PACKET.Checksum], ah |
mov byte[edi + ICMP_PACKET.Checksum + 1], al |
; Queue packet for transmission |
mov ebx, [buffer_number] |
mov eax, NET1OUT_QUEUE |
call queue |
.exit: |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/queue.inc |
---|
0,0 → 1,219 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; 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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/stack.inc |
---|
0,0 → 1,1021 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; 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 ;; |
;; ;; |
;;10.01.2007 Bugfix for checksum function from Paolo Franchetti ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;******************************************************************* |
; Interface |
; The interfaces defined in ETHERNET.INC plus: |
; stack_init |
; stack_handler |
; app_stack_handler |
; app_socket_handler |
; checksum |
; |
;******************************************************************* |
uglobal |
StackCounters: |
dumped_rx_count: dd 0 |
arp_tx_count: dd 0 |
arp_rx_count: dd 0 |
ip_rx_count: dd 0 |
ip_tx_count: dd 0 |
endg |
; socket buffers |
SOCKETBUFFSIZE equ 4096 ; state + config + buffer. |
SOCKETHEADERSIZE equ 76 ; thus 4096 - SOCKETHEADERSIZE bytes data |
NUM_SOCKETS equ 16 ; Number of open sockets supported. Was 20 |
; IPBUFF status values |
BUFF_EMPTY equ 0 |
BUFF_RX_FULL equ 1 |
BUFF_ALLOCATED equ 2 |
BUFF_TX_FULL equ 3 |
NUM_IPBUFFERS equ 20 ; buffers allocated for TX/RX |
NUMQUEUES equ 4 |
EMPTY_QUEUE equ 0 |
IPIN_QUEUE equ 1 |
IPOUT_QUEUE equ 2 |
NET1OUT_QUEUE equ 3 |
NO_BUFFER equ 0xFFFF |
IPBUFFSIZE equ 1500 ; MTU of an ethernet packet |
NUMQUEUEENTRIES equ NUM_IPBUFFERS |
NUMRESENDENTRIES equ 18 ; Buffers for TCP resend packets |
; These are the 0x40 function codes for application access to the stack |
STACK_DRIVER_STATUS equ 52 |
SOCKET_INTERFACE equ 53 |
; 128KB allocated for the stack and network driver buffers and other |
; data requirements |
;stack_data_start equ 0x700000 |
;eth_data_start equ 0x700000 |
;stack_data equ 0x704000 |
;stack_data_end equ 0x71ffff |
; 32 bit word |
stack_config equ stack_data |
; 32 bit word - IP Address in network format |
stack_ip equ stack_data + 4 |
; 1 byte. 0 == inactive, 1 = active |
ethernet_active equ stack_data + 9 |
; TODO :: empty memory area |
; Address of selected socket |
sktAddr equ stack_data + 32 |
; Parameter to checksum routine - data ptr |
checkAdd1 equ stack_data + 36 |
; Parameter to checksum routine - 2nd data ptr |
checkAdd2 equ stack_data + 40 |
; Parameter to checksum routine - data size |
checkSize1 equ stack_data + 44 |
; Parameter to checksum routine - 2nd data size |
checkSize2 equ stack_data + 46 |
; result of checksum routine |
checkResult equ stack_data + 48 |
; holds the TCP/UDP pseudo header. SA|DA|0|prot|UDP len| |
pseudoHeader equ stack_data + 50 |
; receive and transmit IP buffer allocation |
sockets equ stack_data + 62 |
Next_free2 equ sockets + (SOCKETBUFFSIZE * NUM_SOCKETS) |
; 1560 byte buffer for rx / tx ethernet packets |
Ether_buffer equ Next_free2 |
Next_free3 equ Ether_buffer + 1518 |
last_1sTick equ Next_free3 |
IPbuffs equ Next_free3 + 1 |
queues equ IPbuffs + ( NUM_IPBUFFERS * IPBUFFSIZE ) |
queueList equ queues + (2 * NUMQUEUES) |
last_1hsTick equ queueList + ( 2 * NUMQUEUEENTRIES ) |
;resendQ equ queueList + ( 2 * NUMQUEUEENTRIES ) |
;resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP |
; equ resendBuffer + ( IPBUFFSIZE * NUMRESENDENTRIES ) |
;resendQ equ 0x770000 |
resendBuffer equ resendQ + ( 4 * NUMRESENDENTRIES ) ; for TCP |
; simple macro for memory set operation |
macro _memset_dw adr,value,amount |
{ |
mov edi, adr |
mov ecx, amount |
if value = 0 |
xor eax, eax |
else |
mov eax, value |
end if |
cld |
rep stosd |
} |
; Below, the main network layer source code is included |
; |
include "queue.inc" |
include "eth_drv/ethernet.inc" |
include "ip.inc" |
include "icmp.inc" |
include "tcp.inc" |
include "udp.inc" |
include "socket.inc" |
;*************************************************************************** |
; Function |
; stack_init |
; |
; Description |
; Clear all allocated memory to zero. This ensures that |
; on startup, the stack is inactive, and consumes no resources |
; This is a kernel function, called prior to the OS main loop |
; in set_variables |
; |
;*************************************************************************** |
stack_init: |
; Init two address spaces with default values |
_memset_dw stack_data_start, 0, 0x20000/4 |
_memset_dw resendQ, 0xFFFFFFFF, NUMRESENDENTRIES |
; Queries initialization |
call queueInit |
; The following block sets up the 1s timer |
mov al, 0x0 |
out 0x70, al |
in al, 0x71 |
mov [last_1sTick], al |
ret |
;*************************************************************************** |
; Function |
; stack_handler |
; |
; Description |
; The kernel loop routine for the stack |
; This is a kernel function, called in the main loop |
; |
;*************************************************************************** |
stack_handler: |
call ethernet_driver |
call ip_rx |
; Test for 10ms tick, call tcp timer |
mov eax, [timer_ticks] ;[0xfdf0] |
cmp eax, [last_1hsTick] |
je sh_001 |
mov [last_1hsTick], eax |
call tcp_tx_handler |
sh_001: |
; Test for 1 second event, call 1s timer functions |
mov al, 0x0 ;second |
out 0x70, al |
in al, 0x71 |
cmp al, [last_1sTick] |
je sh_exit |
mov [last_1sTick], al |
stdcall arp_table_manager, ARP_TABLE_TIMER, 0, 0 |
call tcp_tcb_handler |
sh_exit: |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; Checksum [by Johnny_B] |
;; IN: |
;; buf_ptr=POINTER to buffer |
;; buf_size=SIZE of buffer |
;; OUT: |
;; AX=16-bit checksum |
;; Saves all used registers |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc checksum_jb stdcall uses ebx esi ecx,\ |
buf_ptr:DWORD, buf_size:DWORD |
xor eax, eax |
xor ebx, ebx ;accumulator |
mov esi, dword[buf_ptr] |
mov ecx, dword[buf_size] |
shr ecx, 1 ; ecx=ecx/2 |
jnc @f ; if CF==0 then size is even number |
mov bh, byte[esi + ecx*2] |
@@: |
cld |
.loop: |
lodsw ;eax=word[esi],esi=esi+2 |
xchg ah,al ;cause must be a net byte-order |
add ebx, eax |
loop .loop |
mov eax, ebx |
shr eax, 16 |
add ax, bx |
not ax |
ret |
endp |
;*************************************************************************** |
; Function |
; checksum |
; |
; Description |
; checkAdd1,checkAdd2, checkSize1, checkSize2, checkResult |
; Dont break anything; Most registers are used by the caller |
; This code is derived from the 'C' source, cksum.c, in the book |
; Internetworking with TCP/IP Volume II by D.E. Comer |
; |
;*************************************************************************** |
checksum: |
pusha |
mov eax, [checkAdd1] |
xor edx, edx ; edx is the accumulative checksum |
xor ebx, ebx |
mov cx, [checkSize1] |
shr cx, 1 |
jz cs1_1 |
cs1: |
mov bh, [eax] |
mov bl, [eax + 1] |
add eax, 2 |
add edx, ebx |
loopw cs1 |
cs1_1: |
and word [checkSize1], 0x01 |
jz cs_test2 |
mov bh, [eax] |
xor bl, bl |
add edx, ebx |
cs_test2: |
mov cx, [checkSize2] |
cmp cx, 0 |
jz cs_exit ; Finished if no 2nd buffer |
mov eax, [checkAdd2] |
shr cx, 1 |
jz cs2_1 |
cs2: |
mov bh, [eax] |
mov bl, [eax + 1] |
add eax, 2 |
add edx, ebx |
loopw cs2 |
cs2_1: |
and word [checkSize2], 0x01 |
jz cs_exit |
mov bh, [eax] |
xor bl, bl |
add edx, ebx |
cs_exit: |
mov ebx, edx |
shr ebx, 16 |
and edx, 0xffff |
add edx, ebx |
mov eax, edx |
shr eax, 16 |
add edx, eax |
not dx |
mov [checkResult], dx |
popa |
ret |
;*************************************************************************** |
; Function |
; app_stack_handler |
; |
; Description |
; This is an application service, called by int 0x40, function 52 |
; It provides application access to the network interface layer |
; |
;*************************************************************************** |
app_stack_handler: |
cmp eax, 0 |
jnz not0 |
; Read the configuration 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 |
;old functions was deleted |
not3: |
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 not14 |
; write the dns IP Address |
mov [dns_ip], ebx |
ret |
;<added by Frank Sommer> |
not14: |
cmp eax, 15 |
jnz not15 |
; in ebx we need 4 to read the last 2 bytes |
cmp ebx, dword 4 |
je read |
; or we need 0 to read the first 4 bytes |
cmp ebx, dword 0 |
jnz param_error |
; read MAC, returned (in mirrored byte order) in eax |
read: |
mov eax, [node_addr + ebx] |
jmp @f |
param_error: |
mov eax, -1 ; params not accepted |
@@: |
ret |
; 0 -> arp_probe |
; 1 -> arp_announce |
; 2 -> arp_responce (not supported yet) |
not15: ; ARP stuff |
cmp eax, 16 |
jnz not16 |
cmp ebx, 0 |
je a_probe |
cmp ebx, 1 |
je a_ann ; arp announce |
; cmp ebx,2 |
; jne a_resp ; arp response |
jmp param15_error |
; arp probe, sender IP must be set to 0.0.0.0, target IP is set to address being probed |
; ecx: pointer to target MAC, MAC should set to 0 by application |
; edx: target IP |
a_probe: |
push dword [stack_ip] |
mov edx, [stack_ip] |
mov [stack_ip], dword 0 |
mov esi, ecx ; pointer to target MAC address |
call arp_request |
pop dword [stack_ip] |
jmp @f |
; arp announce, sender IP must be set to target IP |
; ecx: pointer to target MAC |
a_ann: |
mov edx, [stack_ip] |
mov esi, ecx ; pointer to target MAC address |
call arp_request |
jmp @f |
param15_error: |
mov eax, -1 |
@@: |
ret |
;</added by Frank Sommer> |
; modified by [smb] |
;<added by Johnny_B> |
; ARPTable manager interface |
not16: |
cmp eax, 17 |
jnz stack_driver_end |
;see "proc arp_table_manager" for more details |
stdcall arp_table_manager,ebx,ecx,edx ;Opcode,Index,Extra |
ret |
;</added by Johnny_B> |
stack_driver_end: |
ret |
;*************************************************************************** |
; Function |
; app_socket_handler |
; |
; Description |
; This is an application service, called by int 0x40, function 53 |
; It provides application access to stack socket services |
; such as opening sockets |
; |
;*************************************************************************** |
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, 10 |
jnz nots10 |
mov eax,dword[drvr_cable] |
test eax,eax |
jnz @f ; if function is not implented, return -1 |
mov al,-1 |
ret |
@@: |
call dword[drvr_cable] |
ret |
nots10: |
cmp eax, 11 |
jnz nots11 |
call socket_read_packet |
ret |
nots11: |
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,[TASK_BASE] |
add edi,TASKDATA.mem_start |
add edx,[edi] |
mov edi, edx |
pop eax |
mov ecx, 1500 ; should get the actual number of bytes to write |
mov esi, eax |
cld |
rep movsb ; copy the data across |
; And finally, return the buffer to the free queue |
pop eax |
call freeBuff |
mov eax, 1500 |
ret |
sgp_non_exit: |
xor eax, eax |
ret |
;*************************************************************************** |
; Function |
; stack_insert_packet |
; |
; Description |
; writes an IP packet into the stacks receive queue |
; # of bytes to write in ecx |
; pointer to data in edx |
; returns 0 in eax ok, -1 == failed |
; |
;*************************************************************************** |
stack_insert_packet: |
mov eax, EMPTY_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je sip_err_exit |
push eax |
; save the pointers to the data buffer & size |
push edx |
push ecx |
; convert buffer pointer eax to the absolute address |
mov ecx, IPBUFFSIZE |
mul ecx |
add eax, IPbuffs |
mov edx, eax |
; So, edx holds the IPbuffer ptr |
pop ecx ; count of bytes to send |
mov ebx, ecx ; need the length later |
pop eax ; get callers ptr to data to send |
; Get the address of the callers data |
mov edi,[TASK_BASE] |
add edi,TASKDATA.mem_start |
add eax,[edi] |
mov esi, eax |
mov edi, edx |
cld |
rep movsb ; copy the data across |
pop ebx |
mov eax, IPIN_QUEUE |
call queue |
inc dword [ip_rx_count] |
mov eax, 0 |
ret |
sip_err_exit: |
mov eax, 0xFFFFFFFF |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/tcp.inc |
---|
0,0 → 1,1300 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; 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 ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; 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 |
TCP_RETRIES equ 5 ; Number of times to resend a packet |
TCP_TIMEOUT equ 10 ; resend if not replied to in x hs |
;******************************************************************* |
; Interface |
; |
; tcp_tx_handler Handles the TCP transmit queue |
; tcp_rx The protocol handler for received data |
; buildTCPPacket fills in the packet headers and data |
; tcpStateMachine Main state machine for received TCP packets |
; tcp_tcb_handler 1s timer, to erase tcb's in TIME_WAIT state |
; |
;******************************************************************* |
; TCP Payload ( Data field in IP datagram ) |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;20 | Source Port | Destination Port | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;24 | Sequence Number | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;28 | Acknowledgment Number | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;32 | Data | |U|A|P|R|S|F| | |
; | Offset| Reserved |R|C|S|S|Y|I| Window | |
; | | |G|K|H|T|N|N| | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;36 | Checksum | Urgent Pointer | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;40 | Options | Padding | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | data |
struc TCP_PACKET |
{ .SourcePort dw ? ;+00 |
.DestinationPort dw ? ;+02 |
.SequenceNumber dd ? ;+04 |
.AckNumber dd ? ;+08 |
.DataOffset db ? ;+12 - DataOffset[0-3 bits] and Reserved[4-7] |
.Flags db ? ;+13 - Reserved[0-1 bits]|URG|ACK|PSH|RST|SYN|FIN |
.Window dw ? ;+14 |
.Checksum dw ? ;+16 |
.UrgentPointer dw ? ;+18 |
.Options rb 3 ;+20 |
.Padding db ? ;+23 |
.Data db ? ;+24 |
} |
virtual at 0 |
TCP_PACKET TCP_PACKET |
end virtual |
;*************************************************************************** |
; Function |
; tcp_tcb_handler |
; |
; Description |
; Handles sockets in the timewait state, closing them |
; when the TCB timer expires |
; |
;*************************************************************************** |
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 |
GET_IHL eax,edx ; get IP-Header length |
stdcall checksum_jb,edx,eax ; buf_ptr, buf_size |
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,TASK_DATA+TASKDATA.pid |
news: |
cmp [esi],eax |
je foundPID1 |
inc ecx |
add esi,0x20 |
cmp ecx,[TASK_COUNT] |
jbe news |
foundPID1: |
shl ecx,8 |
or dword [ecx+SLOT_BASE+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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/udp.inc |
---|
0,0 → 1,172 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; 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 |
; |
;******************************************************************* |
; |
; UDP Payload ( Data field in IP datagram ) |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
; |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Source Port | Destination Port | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | Length ( UDP Header + Data ) | Checksum | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
; | UDP Data | |
; +-+-+-.......... -+ |
; |
struc UDP_PACKET |
{ .SourcePort dw ? ;+00 |
.DestinationPort dw ? ;+02 |
.Length dw ? ;+04 - Length of (UDP Header + Data) |
.Checksum dw ? ;+06 |
.Data db ? ;+08 |
} |
virtual at 0 |
UDP_PACKET UDP_PACKET |
end virtual |
;*************************************************************************** |
; Function |
; udp_rx [by Johnny_B] |
; |
; Description |
; UDP protocol handler |
; This is a kernel function, called by ip_rx |
; IP buffer address given in edx |
; IP buffer number in eax |
; Free up (or re-use) IP buffer when finished |
; |
;*************************************************************************** |
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,TASK_DATA+TASKDATA.pid |
newsearch: |
cmp [esi],eax |
je foundPID |
inc ecx |
add esi,0x20 |
cmp ecx,[TASK_COUNT] |
jbe newsearch |
foundPID: |
shl ecx,8 |
or dword [ecx+SLOT_BASE+APPDATA.event_mask],dword 10000000b ; stack event |
mov [check_idle_semaphore],200 |
udprx_001: |
pop eax |
call freeBuff ; Discard the packet |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/network/ip.inc |
---|
0,0 → 1,198 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; 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 ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; IP underlying protocols numbers |
PROTOCOL_ICMP equ 1 |
PROTOCOL_TCP equ 6 |
PROTOCOL_UDP equ 17 |
struc IP_PACKET |
{ .VersionAndIHL db ? ;+00 - Version[0-3 bits] and IHL(header length)[4-7 bits] |
.TypeOfService db ? ;+01 |
.TotalLength dw ? ;+02 |
.Identification dw ? ;+04 |
.FlagsAndFragmentOffset dw ? ;+06 - Flags[0-2] and FragmentOffset[3-15] |
.TimeToLive db ? ;+08 |
.Protocol db ? ;+09 |
.HeaderChecksum dw ? ;+10 |
.SourceAddress dd ? ;+12 |
.DestinationAddress dd ? ;+16 |
.DataOrOptional dd ? ;+20 |
} |
virtual at 0 |
IP_PACKET IP_PACKET |
end virtual |
;******************************************************************* |
; Interface |
; |
; ip_rx processes all packets received by the network layer |
; It calls the appropriate protocol handler |
; |
; |
; |
;******************************************************************* |
; |
; IP Packet after reception - Normal IP packet format |
; |
; 0 1 2 3 |
; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 |
; |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;0 |Version| IHL |Type of Service| Total Length | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;4 | Identification |Flags| Fragment Offset | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;8 | Time to Live | Protocol | Header Checksum | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;12 | Source Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;16 | Destination Address | |
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
;20 | Data | |
; +-+-+-.......... -+ |
; |
; |
; [smb] attention! according to RFC 791 IP packet may have 'options' sections, |
; so we can't simply think, that data have offset 20. We must calculate offset from |
; IHL field |
; |
macro GET_IHL reg, header_addr |
{ |
movzx reg, byte [header_addr] |
; we need 4-7 bits, so.... |
and reg, 0x0000000F |
; IHL keeps number of octets, so we need to << 2 'reg' |
shl reg, 2 |
} |
;*************************************************************************** |
; Function |
; ip_rx |
; |
; Description |
; This is a kernel function, called by stack_handler |
; Processes all IP-packets received by the network layer |
; It calls the appropriate protocol handler |
; |
;*************************************************************************** |
proc ip_rx stdcall |
local buffer_number dd ? |
; Look for a buffer to tx |
mov eax, IPIN_QUEUE |
call dequeue |
cmp ax, NO_BUFFER |
je .exit ; Exit if no buffer available |
mov [buffer_number], eax ;save buffer number |
; convert buffer pointer eax to the absolute address |
imul eax, IPBUFFSIZE |
add eax, IPbuffs |
mov ebx, eax ; ebx=pointer to IP_PACKET |
; Validate the IP checksum |
mov dx, word[ebx + IP_PACKET.HeaderChecksum] |
xchg dh,dl ; Get the checksum in intel format |
mov [ebx + IP_PACKET.HeaderChecksum], 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 |
GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx |
stdcall checksum_jb, ebx, ecx ;buf_ptr, buf_size |
cmp dx, ax |
mov edx, ebx ; EDX (IP-BUFFER POINTER) WILL BE USED FOR *_rx HANDLERS BELOW!!! |
jnz .dump ;if CHECKSUM isn't valid then dump packet |
; Validate the IP address, if it isn't broadcast |
mov eax, [stack_ip] |
cmp dword[ebx + IP_PACKET.DestinationAddress], eax |
je @f |
; If the IP address is 255.255.255.255, accept it |
; - it is a broadcast packet, which we need for dhcp |
cmp dword[ebx + IP_PACKET.DestinationAddress], 0xffffffff |
jne .dump |
@@: |
mov al, [ebx + IP_PACKET.VersionAndIHL] |
and al, 0x0f ;get IHL(header length) |
cmp al, 0x05 ;if IHL!= 5*4(20 bytes) |
jnz .dump ;then dump it |
cmp byte[ebx + IP_PACKET.TimeToLive], byte 0 |
je .dump ;if TTL==0 then dump it |
mov ax, word[ebx + IP_PACKET.FlagsAndFragmentOffset] |
and ax, 0xFFBF ;get flags |
cmp ax, 0 ;if some flags was set then we dump this packet |
jnz .dump ;the flags should be used for fragmented packets |
; Check the protocol, and call the appropriate handler |
; Each handler will re-use or free the queue buffer as appropriate |
mov al, [ebx + IP_PACKET.Protocol] |
cmp al , PROTOCOL_TCP |
jne .not_tcp |
DEBUGF 1,"K : ip_rx - TCP packet\n" |
mov eax, dword[buffer_number] |
call tcp_rx |
jmp .exit |
.not_tcp: |
cmp al, PROTOCOL_UDP |
jne .not_udp |
DEBUGF 1,"K : ip_rx - UDP packet\n" |
mov eax, dword[buffer_number] |
call udp_rx |
jmp .exit |
.not_udp: |
cmp al , PROTOCOL_ICMP |
jne .dump ;protocol ain't supported |
DEBUGF 1,"K : ip_rx - ICMP packet\n" |
;GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx |
mov eax, dword[buffer_number] |
stdcall icmp_rx,eax,ebx,ecx ;buffer_number,IPPacketBase,IPHeaderLength |
jmp .exit |
.dump: |
; No protocol handler available, so |
; silently dump the packet, freeing up the queue buffer |
inc dword [dumped_rx_count] |
mov eax, dword[buffer_number] |
call freeBuff |
.exit: |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/docs/sysfuncr.txt |
---|
0,0 → 1,4530 |
Kolibri 0.6.5.0 |
®¬¥à äãªæ¨¨ ¯®¬¥é ¥âáï ¢ ॣ¨áâà eax. |
맮¢ á¨á⥬®© äãªæ¨¨ ®áãé¥á⢫ï¥âáï ª®¬ ¤®© "int 0x40". |
ᥠॣ¨áâàë, ªà®¬¥  㪠§ ëå ¢ ¢®§¢à é ¥¬®¬ § 票¨, |
¢ª«îç ï ॣ¨áâà ä« £®¢ eflags, á®åà ïîâáï. |
====================================================================== |
============== ãªæ¨ï 0 - ®¯à¥¤¥«¨âì ¨ à¨á®¢ âì ®ª®. ============= |
====================================================================== |
¯à¥¤¥«ï¥â ®ª® ¯à¨«®¦¥¨ï. ¨áã¥â à ¬ªã ®ª , § £®«®¢®ª ¨ à ¡®çãî |
®¡« áâì. «ï ®ª® ᮠ᪨®¬ ®¯à¥¤¥«ï¥â áâ ¤ àâë¥ ª®¯ª¨ § ªàëâ¨ï ¨ |
¬¨¨¬¨§ 樨. |
à ¬¥âàë: |
* eax = 0 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ¯® ®á¨ y]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = 0xXYRRGGBB, £¤¥: |
* Y = áâ¨«ì ®ª : |
* Y=0 - ⨯ I - ®ª® 䨪á¨à®¢ ëå à §¬¥à®¢ |
* Y=1 - ⮫쪮 ®¯à¥¤¥«¨âì ®¡« áâì ®ª , ¨ç¥£® ¥ à¨á®¢ âì |
* Y=2 - ⨯ II - ®ª® ¨§¬¥ï¥¬ëå à §¬¥à®¢ |
* Y=3 - ®ª® ᮠ᪨®¬ |
* ®áâ «ìë¥ ¢®§¬®¦ë¥ § 票ï (®â 4 ¤® 15) § १¥à¢¨à®¢ ë, |
¢ë§®¢ äãªæ¨¨ á â ª¨¬¨ Y ¨£®à¨àã¥âáï |
* RR, GG, BB = ᮮ⢥âá⢥® ªà á ï, §¥«¥ ï, á¨ïï |
á®áâ ¢«ïî騥 梥â à ¡®ç¥© ®¡« á⨠®ª |
(¨£®à¨àã¥âáï ¤«ï á⨫ï Y=2) |
* X = DCBA (¡¨âë) |
* A = 1 - ã ®ª ¥áâì § £®«®¢®ª; ¤«ï á⨫ï Y=3 ¤à¥á áâப¨ |
§ £®«®¢ª § ¤ ñâáï ¢ edi, ¤«ï ¯à®ç¨å á⨫¥© |
¨á¯®«ì§ã¥âáï ¯®¤äãªæ¨ï 1 äãªæ¨¨ 71 |
* B = 1 - ª®®à¤¨ âë ¢á¥å £à ä¨ç¥áª¨å ¯à¨¬¨â¨¢®¢ § ¤ îâáï |
®â®á¨â¥«ì® ª«¨¥â᪮© ®¡« á⨠®ª |
* C = 1 - ¥ § ªà 訢 âì à ¡®çãî ®¡« áâì ¯à¨ ®âà¨á®¢ª¥ ®ª |
* D = 0 - ®à¬ «ì ï § «¨¢ª à ¡®ç¥© ®¡« áâ¨, 1 - £à ¤¨¥â ï |
«¥¤ãî騥 ¯ à ¬¥âàë ¯à¥¤ § ç¥ë ¤«ï ®ª® ⨯ I ¨ II ¨ |
¨£®à¨àãîâáï ¤«ï á⨫¥© Y=1,3: |
* esi = 0xXYRRGGBB - 梥⠧ £®«®¢ª |
* RR, GG, BB ®¯à¥¤¥«ïîâ á ¬ 梥â |
* Y=0 - ®¡ë箥 ®ª®, Y=1 - ¥¯¥à¥¬¥é ¥¬®¥ ®ª® |
* X ®¯à¥¤¥«ï¥â £à ¤¨¥â § £®«®¢ª : X=0 - ¥â £à ¤¨¥â , |
X=8 - ®¡ëçë© £à ¤¨¥â, |
¤«ï ®ª® ⨯ II X=4 - ¥£ â¨¢ë© £à ¤¨¥â |
* ¯à®ç¨¥ § 票ï X ¨ Y § १¥à¢¨à®¢ ë |
* edi = 0x00RRGGBB - 梥â à ¬ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®«®¦¥¨¥ ¨ à §¬¥àë ®ª ãáâ ¢«¨¢ îâáï ¯à¨ ¯¥à¢®¬ ¢ë§®¢¥ |
í⮩ äãªæ¨¨ ¨ ¨£®à¨àãîâáï ¯à¨ ¯®á«¥¤ãîé¨å; ¤«ï ¨§¬¥¥¨ï |
¯®«®¦¥¨ï ¨/¨«¨ à §¬¥à®¢ 㦥 ᮧ¤ ®£® ®ª ¨á¯®«ì§ã©â¥ |
67-î äãªæ¨î. |
* «ï ®ª® á⨫ï Y=3 á § £®«®¢ª®¬ (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 = ¢ëá®â ¨§®¡à ¦¥¨ï |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* 맮¢ äãªæ¨¨ ®¡ï§ ⥫¥ ¯¥à¥¤ ¢ë§®¢®¬ ¯®¤äãªæ¨© 2 ¨ 5. |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
* áâì ¯ à ï äãªæ¨ï ¯®«ã票ï à §¬¥à®¢ ä®®¢®£® ¨§®¡à ¦¥¨ï - |
¯®¤äãªæ¨ï 1 äãªæ¨¨ 39. |
====================================================================== |
= ãªæ¨ï 15, ¯®¤äãªæ¨ï 2 - ¯®áâ ¢¨âì â®çªã ä®®¢®¬ ¨§®¡à ¦¥¨¨. = |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ᬥ饨¥ |
* edx = 梥â â®çª¨ 0xRRGGBB |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ¬¥é¥¨¥ ¤«ï â®çª¨ á ª®®à¤¨ â ¬¨ (x,y) ¢ëç¨á«ï¥âáï ª ª |
(x+y*xsize)*3. |
* ᫨ 㪠§ ®¥ ᬥ饨¥ ¯à¥¢ëè ¥â ãáâ ®¢«¥ë© ¯®¤äãªæ¨¥© 1 |
à §¬¥à, ¢ë§®¢ ¨£®à¨àã¥âáï. |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
* áâì ¯ à ï äãªæ¨ï ¯®«ã票ï â®çª¨ á ä®®¢®£® ¨§®¡à ¦¥¨ï - |
¯®¤äãªæ¨ï 2 äãªæ¨¨ 39. |
====================================================================== |
============ ãªæ¨ï 15, ¯®¤äãªæ¨ï 3 - ¯¥à¥à¨á®¢ âì ä®. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
===== ãªæ¨ï 15, ¯®¤äãªæ¨ï 4 - ãáâ ®¢¨âì ०¨¬ ®âà¨á®¢ª¨ ä® . ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ०¨¬ ®âà¨á®¢ª¨: |
* 1 = § ¬®áâ¨âì |
* 2 = à áâïãâì |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
* áâì ¯ à ï ª®¬ ¤ ¯®«ã票ï ०¨¬ ®âà¨á®¢ª¨ ä® - |
¯®¤äãªæ¨ï 4 äãªæ¨¨ 39. |
====================================================================== |
===== ãªæ¨ï 15, ¯®¤äãªæ¨ï 5 - ¯®¬¥áâ¨âì ¡«®ª ¯¨ªá¥«¥© ä®. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 15 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¤ ë¥ ¢ ä®à¬ ⥠BBGGRRBBGGRR... |
* edx = ᬥ饨¥ ¢ ¤ ëå ä®®¢®£® ¨§®¡à ¦¥¨ï |
* esi = à §¬¥à ¤ ëå ¢ ¡ ©â å = 3 * ç¨á«® ¯¨ªá¥«¥© |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ஢¥àª¨ ª®à४â®áâ¨ á¬¥é¥¨ï ¨ à §¬¥à ¥ ¯à®¨§¢®¤¨âáï. |
* ¢¥â ª ¦¤®£® ¯¨ªá¥«ï åà ¨âáï ª ª 3-¡ ©â ï ¢¥«¨ç¨ BBGGRR. |
* ¨ªá¥«¨ ä®®¢®£® ¨§®¡à ¦¥¨ï § ¯¨áë¢ îâáï ¯®á«¥¤®¢ â¥«ì® |
á«¥¢ ¯à ¢®, ᢥàåã ¢¨§. |
* ¬¥é¥¨¥ ¯¨ªá¥«ï á ª®®à¤¨ â ¬¨ (x,y) ¥áâì (x+y*xsize)*3. |
* «ï ®¡®¢«¥¨ï íªà (¯®á«¥ § ¢¥à襨ï á¥à¨¨ ª®¬ ¤, à ¡®â îé¨å á |
ä®®¬) ¢ë§ë¢ ©â¥ ¯®¤äãªæ¨î 3 ¯¥à¥à¨á®¢ª¨ ä® . |
====================================================================== |
============= ãªæ¨ï 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 = 㪠§ ⥫ì áâபã á ¯®«ë¬ ¨¬¥¥¬ ä ©« |
( ¯à¨¬¥à, "/hd0/1/kolibri/kolibri.img") |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* ¨ ç¥ eax = ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* ᥠ¯ ¯ª¨ ¢ 㪠§ ®¬ ¯ã⨠¤®«¦ë áãé¥á⢮¢ âì, ¨ ç¥ ¢¥àñâáï |
§ 票¥ 5, "ä ©« ¥ ©¤¥". |
====================================================================== |
====== ãªæ¨ï 18, ¯®¤äãªæ¨ï 7 - ¯®«ãç¨âì ®¬¥à ªâ¨¢®£® ®ª . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¬¥à ªâ¨¢®£® ®ª (®¬¥à ᫮⠯®â®ª , ®ª® ª®â®à®£® |
ªâ¨¢®) |
¬¥ç ¨ï: |
* ªâ¨¢®¥ ®ª® 室¨âáï ¢¢¥àåã ®ª®®£® áâíª ¨ ¯®«ãç ¥â |
á®®¡é¥¨ï ®¡® ¢áñ¬ ¢¢®¤¥ á ª« ¢¨ âãàë. |
* ¤¥« âì ®ª® ªâ¨¢ë¬ ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 3. |
====================================================================== |
==== ãªæ¨ï 18, ¯®¤äãªæ¨ï 8 - ®âª«îç¨âì/à §à¥è¨âì §¢ãª ᯨª¥à . ==== |
====================================================================== |
ਠ®âª«îçñ®¬ §¢ãª¥ ¢ë§®¢ë ¯®¤äãªæ¨¨ 55 äãªæ¨¨ 55 ¨£®à¨àãîâáï. |
ਠ¢ª«îçñ®¬ - ¯à ¢«ïîâáï ¢áâà®¥ë© á¯¨ª¥à. |
--------------- ®¤¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì á®áâ®ï¨¥. ---------------- |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 1 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - §¢ãª ᯨª¥à à §à¥èñ; 1 - § ¯à¥éñ |
-------------- ®¤¯®¤äãªæ¨ï 2 - ¯¥à¥ª«îç¨âì á®áâ®ï¨¥. -------------- |
¥à¥ª«îç ¥â á®áâ®ï¨ï à §à¥è¥¨ï/§ ¯à¥é¥¨ï. |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 2 - ®¬¥à ¯®¤¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
====================================================================== |
= ãªæ¨ï 18, ¯®¤äãªæ¨ï 9 - § ¢¥à襨¥ à ¡®âë á¨á⥬ë á ¯ à ¬¥â஬. = |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¯ à ¬¥âà: |
* 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 ¨ NTFS. |
* +6: 4 db: § १¥à¢¨à®¢ ® |
®à¬ â â ¡«¨æë: ¯®« ï ¢¥àá¨ï: |
* +0: 10 db: â ª¨¥ ¦¥, ª ª ¨ ¢ ª®à®âª®© ¢¥àᨨ |
* +10: 100 db: ¤ ë¥ ¤«ï ¯¥à¢®£® à §¤¥« |
* +110: 100 db: ¤ ë¥ ¤«ï ¢â®à®£® à §¤¥« |
* ... |
* +10+100*(n-1): 100 db: ¤ ë¥ ¤«ï ¯®á«¥¤¥£® à §¤¥« |
§¤¥«ë à ᯮ«®¦¥ë ¢ á«¥¤ãî饬 ¯®à浪¥: á ç « ¯®á«¥¤®¢ â¥«ì® ¢á¥ |
à ᯮ§ ë¥ à §¤¥«ë HD IDE0 (¥á«¨ ¥áâì), |
§ ⥬ HD IDE1 (¥á«¨ ¥áâì) ¨ â.¤. ¤® IDE3. |
®à¬ â ¨ä®à¬ 樨 ® à §¤¥«¥: |
* +0: dword: ç «ìë© ä¨§¨ç¥áª¨© ᥪâ®à à §¤¥« |
* +4: dword: ¯®á«¥¤¨© 䨧¨ç¥áª¨© ᥪâ®à à §¤¥« |
(¯à¨ ¤«¥¦¨â à §¤¥«ã) |
* +8: byte: ⨯ ä ©«®¢®© á¨á⥬ë: |
16=FAT16, 32=FAT32, 1=NTFS |
* ä®à¬ â ¤ «ì¥©è¨å ¤ ëå § ¢¨á¨â ®â ä ©«®¢®© á¨á⥬ë, |
¬®¦¥â ¬¥ïâìáï á ¨§¬¥¥¨ï¬¨ ¢ ï¤à¥ ¨ ¯®í⮬㠥 ®¯¨áë¢ ¥âáï |
¬¥ç ¨ï: |
* ®à®âª ï â ¡«¨æ ¬®¦¥â ¡ëâì ¨á¯®«ì§®¢ ¤«ï ¯®«ãç¥¨ï ¨ä®à¬ 樨 |
®¡ ¨¬¥îé¨åáï ãáâனá⢠å. |
====================================================================== |
========== ãªæ¨ï 18, ¯®¤äãªæ¨ï 13 - ¯®«ãç¨âì ¢¥àá¨î ï¤à . ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 18 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à (¥ ¬¥¥¥ 16 ¡ ©â), ªã¤ ¡ã¤¥â ¯®¬¥é¥ |
¨ä®à¬ æ¨ï |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
âàãªâãà ¡ãä¥à : |
db a,b,c,d ¤«ï ¢¥àᨨ a.b.c.d |
db UID_xxx: ®¤® ¨§ UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2 |
db 'name',0 - ASCIIZ-áâப á ¨¬¥¥¬ |
«ï ï¤à Kolibri 0.6.5.0: |
db 0,6,5,0 |
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, ¯®¤äãªæ¨ï 7 - ãáâ ®¢¨âì ¡ §ã HD. =========== |
====================================================================== |
§ HD 㦠¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© ¦ñá⪨© ¤¨áª ¯¨á âì, ¯à¨ |
¨á¯®«ì§®¢ ¨¨ ãáâ ॢ襣® á¨â ªá¨á /HD ¢ ãáâ ॢ襩 äãªæ¨¨ 58; |
¯à¨ ¨á¯®«ì§®¢ ¨¨ ᮢ६¥®£® á¨â ªá¨á /HD0,/HD1,/HD2,/HD3 |
¡ § ãáâ ¢«¨¢ ¥âáï ¢â®¬ â¨ç¥áª¨. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¡ § HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì ¡ §ã. |
* ¥ á«¥¤ã¥â ¨§¬¥ïâì ¡ §ã, ª®£¤ ª ª®¥-¨¡ã¤ì ¯à¨«®¦¥¨¥ à ¡®â ¥â |
á ¦ñá⪨¬ ¤¨áª®¬. ᫨ ¥ å®â¨â¥ £«îª®¢ á¨á⥬ë. |
* ®«ãç¨âì ãáâ ®¢«¥ãî ¡ §ã ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 7 äãªæ¨¨ 26. |
* «¥¤ã¥â â ª¦¥ ®¯à¥¤¥«¨âì ¨á¯®«ì§ã¥¬ë© à §¤¥« ¦ñá⪮£® ¤¨áª |
¯®¤äãªæ¨¥© 8. |
====================================================================== |
========== ãªæ¨ï 21, ¯®¤äãªæ¨ï 8 - ãáâ ®¢¨âì à §¤¥« HD. ========== |
====================================================================== |
§¤¥« HD 㦥 ¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© à §¤¥« ¦ñá⪮£® ¤¨áª |
¯¨á âì, ¯à¨ ¨á¯®«ì§®¢ ¨¨ ãáâ ॢ襣® á¨â ªá¨á /HD ¢ ãáâ ॢ襩 |
äãªæ¨¨ 58; ¯à¨ ¨á¯®«ì§®¢ ¨¨ ᮢ६¥®£® á¨â ªá¨á |
/HD0,/HD1,/HD2,/HD3 ¡ § ¨ à §¤¥« ãáâ ¢«¨¢ îâáï ¢â®¬ â¨ç¥áª¨. |
à ¬¥âàë: |
* eax = 21 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = à §¤¥« HD (áç¨â ï á 1) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì à §¤¥«. |
* ¥ á«¥¤ã¥â ¨§¬¥ïâì à §¤¥«, ª®£¤ ª ª®¥-¨¡ã¤ì ¯à¨«®¦¥¨¥ à ¡®â ¥â |
á ¦ñá⪨¬ ¤¨áª®¬. ᫨ ¥ å®â¨â¥ £«îª®¢ á¨á⥬ë. |
* ®«ãç¨âì ãáâ ®¢«¥ë© à §¤¥« ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 8 |
äãªæ¨¨ 26. |
* ஢¥à®ª ª®à४â®áâì ¥ ¤¥« ¥âáï. |
* § âì ç¨á«® à §¤¥«®¢ ¦ñá⪮¬ ¤¨áª¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11 äãªæ¨¨ 18. |
* «¥¤ã¥â â ª¦¥ ®¯à¥¤¥«¨âì ¨á¯®«ì§ã¥¬ãî ¡ §ã ¦ñá⪮£® ¤¨áª |
¯®¤äãªæ¨¥© 7. |
====================================================================== |
===== ãªæ¨ï 21, ¯®¤äãªæ¨ï 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, ¯®¤äãªæ¨ï 7 - ¯®«ãç¨âì ¡ §ã HD. ============ |
====================================================================== |
§ HD 㦠¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© ¦ñá⪨© ¤¨áª ¯¨á âì, ¯à¨ |
¨á¯®«ì§®¢ ¨¨ ãáâ ॢ襣® á¨â ªá¨á /HD ¢ ãáâ ॢ襩 äãªæ¨¨ 58; |
¯à¨ ¨á¯®«ì§®¢ ¨¨ ᮢ६¥®£® á¨â ªá¨á /HD0,/HD1,/HD2,/HD3 |
¡ § ãáâ ¢«¨¢ ¥âáï ¢â®¬ â¨ç¥áª¨. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¡ § HD: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì ¡ §ã. |
* áâ ®¢¨âì ¡ §ã ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 7 äãªæ¨¨ 21. |
* ®«ãç¨âì ¨á¯®«ì§ã¥¬ë© à §¤¥« ¦ñá⪮£® ¤¨áª ¬®¦® ¯®¤äãªæ¨¥© 8. |
====================================================================== |
=========== ãªæ¨ï 26, ¯®¤äãªæ¨ï 8 - ¯®«ãç¨âì à §¤¥« HD. =========== |
====================================================================== |
§¤¥« HD 㦥 ¤«ï ®¯à¥¤¥«¥¨ï, ª ª®© à §¤¥« ¦ñá⪮£® ¤¨áª |
¯¨á âì, ¯à¨ ¨á¯®«ì§®¢ ¨¨ ãáâ ॢ襣® á¨â ªá¨á /HD ¢ ãáâ ॢ襩 |
äãªæ¨¨ 58; ¯à¨ ¨á¯®«ì§®¢ ¨¨ ᮢ६¥®£® á¨â ªá¨á |
/HD0,/HD1,/HD2,/HD3 ¡ § ¨ à §¤¥« ãáâ ¢«¨¢ îâáï ¢â®¬ â¨ç¥áª¨. |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = à §¤¥« HD (áç¨â ï á 1) |
¬¥ç ¨ï: |
* î¡®¥ ¯à¨«®¦¥¨¥ ¢ «î¡®© ¬®¬¥â ¢à¥¬¥¨ ¬®¦¥â ¨§¬¥¨âì à §¤¥«. |
* áâ ®¢¨âì à §¤¥« ¬®¦® ¢ë§®¢®¬ ¯®¤äãªæ¨¨ 8 äãªæ¨¨ 21. |
* § âì ç¨á«® à §¤¥«®¢ ¦ñá⪮¬ ¤¨áª¥ ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11 äãªæ¨¨ 18. |
* ®«ãç¨âì ¨á¯®«ì§ã¥¬ãî ¡ §ã ¦ñá⪮£® ¤¨áª ¬®¦® ¯®¤äãªæ¨¥© 7. |
====================================================================== |
=== ãªæ¨ï 26, ¯®¤äãªæ¨ï 9 - ¯®«ãç¨âì § 票¥ áçñâ稪 ¢à¥¬¥¨. === |
====================================================================== |
à ¬¥âàë: |
* eax = 26 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® á®âëå ¤®«¥© ᥪã¤ë, ¯à®è¥¤è¨å á ¬®¬¥â |
§ ¯ã᪠á¨á⥬ë |
¬¥ç ¨ï: |
* çñâ稪 ¡¥àñâáï ¯® ¬®¤ã«î 2^32, ç⮠ᮮ⢥âáâ¢ã¥â ¥¬®£¨¬ ¡®«¥¥ |
497 áã⮪. |
* ¨á⥬®¥ ¢à¥¬ï ¬®¦® ¯®«ãç¨âì äãªæ¨¥© 3. |
====================================================================== |
====== ãªæ¨ï 26, ¯®¤äãªæ¨ï 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. |
====================================================================== |
=============== ãªæ¨ï 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. |
====================================================================== |
================ ãªæ¨ï 30 - à ¡®â á ⥪ã饩 ¯ ¯ª®©. =============== |
====================================================================== |
-------- ®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ⥪ãéãî ¯ ¯ªã ¤«ï ¯®â®ª . --------- |
à ¬¥âàë: |
* eax = 30 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì ASCIIZ-áâபã á ¯ãâñ¬ ª ®¢®© ⥪ã饩 ¯ ¯ª¥ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
--------- ®¤äãªæ¨ï 2 - ¯®«ãç¨âì ⥪ãéãî ¯ ¯ªã ¤«ï ¯®â®ª . ---------- |
à ¬¥âàë: |
* eax = 30 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à |
* edx = à §¬¥à ¡ãä¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¤«¨ ¨¬¥¨ ⥪ã饩 ¯ ¯ª¨ (¢ª«îç ï § ¢¥àè î騩 0) |
¬¥ç ¨ï: |
* ᫨ à §¬¥à ¡ãä¥à ¥¤®áâ â®ç® ¤«ï ª®¯¨à®¢ ¨ï ¢á¥£® ¨¬¥¨, |
ª®¯¨àãîâáï ⮫쪮 ¯¥à¢ë¥ (edx-1) ¡ ©â |
¨ ¢ ª®æ¥ áâ ¢¨âáï § ¢¥àè î騩 0. |
====================================================================== |
================ ãªæ¨ï 32 - 㤠«¨âì ä ©« á à ¬¤¨áª . =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 32 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨¬ï ä ©« |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®; ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* â äãªæ¨ï ãáâ ५ ; äãªæ¨ï 58 ¯®§¢®«ï¥â ¢ë¯®«ïâì |
⥠¦¥ ¤¥©á⢨ï á à áè¨à¥ë¬¨ ¢®§¬®¦®áâﬨ. |
* ¥ªãé ï ॠ«¨§ æ¨ï ¢®§¢à é ¥â ⮫쪮 § 票ï 0(ãᯥå) ¨ |
5(ä ©« ¥ ©¤¥). |
* ¬ï ä ©« ¤®«¦® ¡ëâì «¨¡® ¢ ä®à¬ ⥠8+3 ᨬ¢®«®¢ (¯¥à¢ë¥ |
8 ᨬ¢®«®¢ - ᮡá⢥® ¨¬ï, ¯®á«¥¤¨¥ 3 - à áè¨à¥¨¥, |
ª®à®âª¨¥ ¨¬¥ ¨ à áè¨à¥¨ï ¤®¯®«ïîâáï ¯à®¡¥« ¬¨), |
«¨¡® ¢ ä®à¬ ⥠8.3 ᨬ¢®«®¢ "FILE.EXT"/"FILE.EX " |
(¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ 3 ᨬ¢®« , |
¤®¯®«¥®¥ ¯à¨ ¥®¡å®¤¨¬®á⨠¯à®¡¥« ¬¨). |
¬ï ä ©« ¤®«¦® ¡ëâì § ¯¨á ® § £« ¢ë¬¨ ¡ãª¢ ¬¨. |
¢¥àè î騩 ᨬ¢®« á ª®¤®¬ 0 ¥ 㦥 (¥ ASCIIZ-áâப ). |
* â äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª à ¬¤¨áª¥. |
====================================================================== |
=============== ãªæ¨ï 33 - § ¯¨á âì ä ©« à ¬¤¨áª. =============== |
====================================================================== |
à ¬¥âàë: |
* eax = 33 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨¬ï ä ©« |
* ecx = 㪠§ â¥«ì ¤ ë¥ ¤«ï § ¯¨á¨ |
* edx = ç¨á«® ¡ ©â ¤«ï § ¯¨á¨ |
* á«¥¤ã¥â ãáâ ¢«¨¢ âì esi=0 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
¬¥ç ¨ï: |
* â äãªæ¨ï ãáâ ५ ; äãªæ¨ï 70 ¯®§¢®«ï¥â ¢ë¯®«ïâì |
⥠¦¥ ¤¥©á⢨ï á à áè¨à¥ë¬¨ ¢®§¬®¦®áâﬨ. |
* ᫨ 㪠§ âì ¥ã«¥¢®¥ § 票¥ ¢ esi ¨ à ¬¤¨áª¥ 㦥 ¥áâì |
㪠§ ë© ä ©«, â® ¡ã¤¥â ᮧ¤ ¥éñ ®¤¨ ä ©« á ⥬ ¦¥ ¨¬¥¥¬. |
* ¯à®â¨¢®¬ á«ãç ¥ ä ©« ¯¥à¥§ ¯¨áë¢ ¥âáï. |
* ¬ï ä ©« ¤®«¦® ¡ëâì «¨¡® ¢ ä®à¬ ⥠8+3 ᨬ¢®«®¢ |
(¯¥à¢ë¥ 8 ᨬ¢®«®¢ - ᮡá⢥® ¨¬ï, ¯®á«¥¤¨¥ 3 - à áè¨à¥¨¥, |
ª®à®âª¨¥ ¨¬¥ ¨ à áè¨à¥¨ï ¤®¯®«ïîâáï ¯à®¡¥« ¬¨), |
«¨¡® ¢ ä®à¬ ⥠8.3 ᨬ¢®«®¢ "FILE.EXT"/"FILE.EX " |
(¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ 3 ᨬ¢®« , |
¤®¯®«¥®¥ ¯à¨ ¥®¡å®¤¨¬®á⨠¯à®¡¥« ¬¨). |
¬ï ä ©« ¤®«¦® ¡ëâì § ¯¨á ® § £« ¢ë¬¨ ¡ãª¢ ¬¨. |
¢¥àè î騩 ᨬ¢®« á ª®¤®¬ 0 ¥ 㦥 (¥ ASCIIZ-áâப ). |
* â äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª à ¬¤¨áª¥. |
====================================================================== |
============ ãªæ¨ï 35 - ¯à®ç¨â âì 梥â â®çª¨ íªà ¥. ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 35 |
* ebx = y*xsize+x, £¤¥ |
* (x,y) = ª®®à¤¨ âë â®çª¨ (áç¨â ï ®â 0) |
* xsize = à §¬¥à íªà ¯® £®à¨§®â «¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 梥â 0x00RRGGBB |
¬¥ç ¨ï: |
* § âì à §¬¥àë íªà ¬®¦® ¢ë§®¢®¬ äãªæ¨¨ 14. ¡à â¨â¥ ¢¨¬ ¨¥, |
çâ® ® ¢ëç¨â ¥â 1 ¨§ ®¡®¨å à §¬¥à®¢. |
* ¢¨¤¥®¯ ¬ï⨠¥áâì â ª¦¥ ¯àאַ© ¤®áâ㯠(¡¥§ ¢ë§®¢®¢ á¨á⥬ëå |
äãªæ¨©) ç¥à¥§ ᥫ¥ªâ®à gs. à ¬¥âàë ⥪ã饣® ¢¨¤¥®à¥¦¨¬ |
¬®¦® ¯®«ãç¨âì äãªæ¨¥© 61. |
====================================================================== |
==================== ãªæ¨ï 37 - à ¡®â á ¬ëèìî. ==================== |
====================================================================== |
-------------- ®¤äãªæ¨ï 0 - íªà ë¥ ª®®à¤¨ âë ¬ëè¨ --------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = x*65536 + y, (x,y)=ª®®à¤¨ âë ªãàá®à ¬ëè¨ (áç¨â ï ®â 0) |
---------- ®¤äãªæ¨ï 1 - ª®®à¤¨ âë ¬ëè¨ ®â®á¨â¥«ì® ®ª ---------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = x*65536 + y, (x,y)=ª®®à¤¨ âë ªãàá®à ¬ëè¨ ®â®á¨â¥«ì® |
®ª ¯à¨«®¦¥¨ï (áç¨â ï ®â 0) |
¬¥ç ¨ï: |
* 票¥ ¢ëç¨á«ï¥âáï ¯® ä®à¬ã«¥ (x-xwnd)*65536 + (y-ywnd). |
᫨ y>=ywnd, â® ¬« ¤è¥¥ á«®¢® ¥®âà¨æ â¥«ì® ¨ ᮤ¥à¦¨â |
®â®á¨â¥«ìãî y-ª®®à¤¨ âã, áâ à襥 - ®â®á¨â¥«ìãî x-ª®®à¤¨ âã |
(¯à ¢¨«ì®£® § ª ). ¯à®â¨¢®¬ á«ãç ¥ ¬« ¤è¥¥ á«®¢® ®âà¨æ â¥«ì® |
¨ ¢áñ à ¢® ᮤ¥à¦¨â ®â®á¨â¥«ìãî y-ª®®à¤¨ âã, |
ª áâ à襬ã á«®¢ã á«¥¤ã¥â ¯à¨¡ ¢¨âì 1. |
----------------- ®¤äãªæ¨ï 2 - ¦ âë¥ ª®¯ª¨ ¬ëè¨ ----------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax ᮤ¥à¦¨â ¨ä®à¬ æ¨î ® ¦ âëå ª®¯ª å ¬ëè¨: |
* ¡¨â 0 ãáâ ®¢«¥ = «¥¢ ï ª®¯ª ¦ â |
* ¡¨â 1 ãáâ ®¢«¥ = ¯à ¢ ï ª®¯ª ¦ â |
* ¡¨â 2 ãáâ ®¢«¥ = á।ïï ª®¯ª ¦ â |
* ¡¨â 3 ãáâ ®¢«¥ = 4-ï ª®¯ª ¦ â |
* ¡¨â 4 ãáâ ®¢«¥ = 5-ï ª®¯ª ¦ â |
* ¯à®ç¨¥ ¡¨âë á¡à®è¥ë |
------------------ ®¤äãªæ¨ï 4 - § £à㧨âì ªãàá®à ------------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* dx = ¨áâ®ç¨ª ¤ ëå: |
* dx = LOAD_FROM_FILE = 0 - ¤ ë¥ ¢ ä ©«¥ |
* ecx = 㪠§ â¥«ì ¯®«ë© ¯ãâì ª ä ©«ã ªãàá®à |
* ä ©« ªãàá®à ¤®«¦¥ ¡ëâì ¢ ä®à¬ ⥠.cur, áâ ¤ à⮬ ¤«ï |
MS Windows, ¯à¨çñ¬ à §¬¥à®¬ 32*32 ¯¨ªá¥«ï |
* dx = LOAD_FROM_MEM = 1 - ¤ ë¥ ä ©« 㦥 § £àã¦¥ë ¢ ¯ ¬ïâì |
* ecx = 㪠§ â¥«ì ¤ ë¥ ä ©« ªãàá®à |
* ä®à¬ â ¤ ëå â ª®© ¦¥, ª ª ¨ ¢ ¯à¥¤ë¤ã饬 á«ãç ¥ |
* dx = LOAD_INDIRECT = 2 - ¤ ë¥ ¢ ¯ ¬ï⨠|
* ecx = 㪠§ â¥«ì ®¡à § ªãàá®à ¢ ä®à¬ ⥠ARGB 32*32 ¯¨ªá¥«ï |
* edx = 0xXXYY0002, £¤¥ |
* XX = x-ª®®à¤¨ â "£®àï祩 â®çª¨" ªãàá®à |
* YY = y-ª®®à¤¨ â |
* 0 <= XX, YY <= 31 |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ã¤ ç |
* ¨ ç¥ eax = åí¤« ªãàá®à |
------------------ ®¤äãªæ¨ï 5 - ãáâ ®¢¨âì ªãàá®à ------------------ |
áâ ¢«¨¢ ¥â ®¢ë© ªãàá®à ¤«ï ®ª ⥪ã饣® ¯®â®ª . |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ªãàá®à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = åí¤« ¯à¥¤ë¤ã饣® ãáâ ®¢«¥®£® ªãàá®à |
¬¥ç ¨ï: |
* ᫨ ¯¥à¥¤ ¥ª®à४âë© åí¤«, â® äãªæ¨ï ¢®ááâ ®¢¨â ªãàá®à |
¯® 㬮«ç ¨î (áâ ¤ àâãî áâ५ªã). ç áâ®áâ¨, ª ¢®ááâ ®¢«¥¨î |
ªãàá®à ¯® 㬮«ç ¨î ¯à¨¢®¤¨â ¯¥à¥¤ ç ecx=0. |
------------------- ®¤äãªæ¨ï 6 - 㤠«¨âì ªãàá®à -------------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ªãàá®à |
®§¢à é ¥¬®¥ § 票¥: |
* eax à §àãè ¥âáï |
¬¥ç ¨ï: |
* ãàá®à ¤®«¦¥ ¡ë« ¡ëâì à ¥¥ § £à㦥 ⥪ã騬 ¯®â®ª®¬ |
(¢ë§®¢®¬ ¯®¤äãªæ¨¨ 4). ãªæ¨ï ¥ 㤠«ï¥â á¨áâ¥¬ë¥ ªãàá®àë ¨ |
ªãàá®àë, § £àã¦¥ë¥ ¤à㣨¬¨ ¯à¨«®¦¥¨ï¬¨. |
* ᫨ 㤠«ï¥âáï ªâ¨¢ë© (ãáâ ®¢«¥ë© ¯®¤äãªæ¨¥© 5) ªãàá®à, â® |
¢®ááâ ¢«¨¢ ¥âáï ªãàá®à ¯® 㬮«ç ¨î (áâ ¤ àâ ï áâ५ª ). |
------------------ ®¤äãªæ¨ï 7 - ¤ ë¥ ¯à®ªàã⪨ ------------------- |
à ¬¥âàë: |
* eax = 37 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [horizontal offset]*65536 + [vertical offset] |
¬¥ç ¨ï: |
* ë¥ ¤®áâã¯ë ⮫쪮 ªâ¨¢®¬ã ®ªã. |
* ®á«¥ ¯à®çâ¥¨ï § ç¥¨ï ®¡ã«ïîâáï. |
* ë¥ ¨¬¥îâ § ª®¢ë¥ § 票ï. |
====================================================================== |
================== ãªæ¨ï 38 - à¨á®¢ âì ®â१®ª. ================== |
====================================================================== |
à ¬¥âàë: |
* eax = 38 - ®¬¥à äãªæ¨¨ |
* ebx = [ª®®à¤¨ â ç « ¯® ®á¨ x]*65536 + |
[ª®®à¤¨ â ª®æ ¯® ®á¨ x] |
* ecx = [ª®®à¤¨ â ç « ¯® ®á¨ y]*65536 + |
[ª®®à¤¨ â ª®æ ¯® ®á¨ y] |
* edx = 0x00RRGGBB - 梥â |
edx = 0x01xxxxxx - à¨á®¢ âì ¨¢¥àáë© ®â१®ª |
(¬« ¤è¨¥ 24 ¡¨â ¨£®à¨àãîâáï) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ¡¥àãâáï ®â®á¨â¥«ì® ®ª . |
* ®¥ç ï â®çª â ª¦¥ à¨áã¥âáï. |
====================================================================== |
== ãªæ¨ï 39, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì à §¬¥à ä®®¢®£® ¨§®¡à ¦¥¨ï. == |
====================================================================== |
à ¬¥âàë: |
* eax = 39 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [è¨à¨ ]*65536 + [¢ëá®â ] |
¬¥ç ¨ï: |
* áâì ¯ à ï ª®¬ ¤ ãáâ ®¢ª¨ à §¬¥à®¢ ä®®¢®£® ¨§®¡à ¦¥¨ï - |
¯®¤äãªæ¨ï 1 äãªæ¨¨ 15. ®á«¥ ª®â®à®©, à §ã¬¥¥âáï, á«¥¤ã¥â |
§ ®¢® ®¯à¥¤¥«¨âì á ¬® ¨§®¡à ¦¥¨¥. |
====================================================================== |
= ãªæ¨ï 39, ¯®¤äãªæ¨ï 2 - ¯à®ç¨â âì â®çªã á ä®®¢®£® ¨§®¡à ¦¥¨ï. = |
====================================================================== |
à ¬¥âàë: |
* eax = 39 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ᬥ饨¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0x00RRGGBB - 梥â â®çª¨, ¥á«¨ ᬥ饨¥ ¤®¯ãá⨬® |
(¬¥ìè¥ 0x160000-16) |
* eax = 2 - ¨ ç¥ |
¬¥ç ¨ï: |
* ¥ á«¥¤ã¥â ¯®« £ âìáï ¢®§¢à é ¥¬®¥ § 票¥ ¢ á«ãç ¥ ¥¢¥à®£® |
ᬥ饨ï, ®® ¬®¦¥â ¨§¬¥¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à . |
* ¬¥é¥¨¥ â®çª¨ á ª®®à¤¨ â ¬¨ (x,y) ¢ëç¨á«ï¥âáï ª ª (x+y*xsize)*3. |
* áâì ¯ à ï äãªæ¨ï ãáâ ®¢ª¨ â®çª¨ ä®®¢®¬ ¨§®¡à ¦¥¨¨ - |
¯®¤äãªæ¨ï 2 äãªæ¨¨ 15. |
====================================================================== |
====== ãªæ¨ï 39, ¯®¤äãªæ¨ï 4 - ¯®«ãç¨âì ०¨¬ ®âà¨á®¢ª¨ ä® . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 39 - ®¬¥à äãªæ¨¨ |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 1 - § ¬®áâ¨âì |
* eax = 2 - à áâïãâì |
¬¥ç ¨ï: |
* áâì ¯ à ï äãªæ¨ï ãáâ ®¢ª¨ ०¨¬ ®âà¨á®¢ª¨ ä® - |
¯®¤äãªæ¨ï 4 äãªæ¨¨ 15. |
====================================================================== |
======== ãªæ¨ï 40 - ãáâ ®¢¨âì ¬ áªã ¤«ï ®¦¨¤ ¥¬ëå ᮡë⨩. ======== |
====================================================================== |
᪠¤«ï ®¦¨¤ ¥¬ëå ᮡë⨩ ¢«¨ï¥â äãªæ¨¨ à ¡®âë á ᮡëâ¨ï¬¨ 10, |
11, 23 - ®¨ á®®¡é îâ ⮫쪮 ® ᮡëâ¨ïå, à §à¥èñëå í⮩ ¬ ᪮©. |
à ¬¥âàë: |
* eax = 40 - ®¬¥à äãªæ¨¨ |
* ebx = ¬ ᪠: ¡¨â i ᮮ⢥âáâ¢ã¥â ᮡëâ¨î i+1 (á¬. ᯨ᮪ ᮡë⨩) |
(ãáâ ®¢«¥ë© ¡¨â à §à¥è ¥â ¨§¢¥é¥¨¥ ® ᮡë⨨) |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ᪠¯® 㬮«ç ¨î (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..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (¢ª«îç¨â¥«ì®). |
* ਠ§ ¢¥à襨¨ ¯®â®ª ¢â®¬ â¨ç¥áª¨ ®á¢®¡®¦¤ îâáï ¢á¥ |
§ १¥à¢¨à®¢ ë¥ ¨¬ ¯®àâë. |
====================================================================== |
================= ãªæ¨ï 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, ® íâ® ¬®¦¥â ¡ëâì ¨§¬¥¥® |
¢ á«¥¤ãîé¨å ¢¥àá¨ïå |
====================================================================== |
====== ãªæ¨ï 52, ¯®¤äãªæ¨ï 15 - ¯®«ãç¨âì «®ª «ìë© MAC- ¤à¥á. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 52 - ®¬¥à äãªæ¨¨ |
* ebx = 15 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 0 - ç¨â âì ¯¥à¢ë¥ 4 ¡ ©â , |
ecx = 4 - ç¨â âì ¯®á«¥¤¨¥ 2 ¡ ©â |
®§¢à é ¥¬®¥ § 票¥: |
* ¤«ï ecx=0: eax = ¯¥à¢ë¥ 4 ¡ ©â MAC- ¤à¥á |
* ¤«ï ecx=4: ax = ¯®á«¥¤¨¥ 2 ¡ ©â MAC- ¤à¥á , |
áâ àè ï ¯®«®¢¨ eax à §àãè ¥âáï |
* ¤«ï ¤à㣨å ecx: eax = -1 ª ª ¯à¨§ ª ®è¨¡ª¨ |
====================================================================== |
============ ãªæ¨ï 53, ¯®¤äãªæ¨ï 0 - ®âªàëâì UDP-᮪¥â. =========== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = «®ª «ìë© ¯®àâ (ãç¨âë¢ ¥âáï ⮫쪮 ¬« ¤è¥¥ á«®¢®) |
* 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, ¯®¤äãªæ¨ï 10 - ¯®«ãç¨âì áâ âãá ª ¡¥«ï Ethernet. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 10 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* al = -1 - ¤à ©¢¥à á¥â¥¢®© ª àâë ¥ § £à㦥 ¨«¨ |
¥ ¯®¤¤¥à¦¨¢ ¥â íâã äãªæ¨î |
* al = 0 - ª ¡¥«ì ¥ ¯®¤ª«îçñ |
* al = 1 - ª ¡¥«ì ¯®¤ª«îçñ |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ¥ªãé ï ॠ«¨§ æ¨ï ï¤à ¯®¤¤¥à¦¨¢ ¥â íâã äãªæ¨î |
⮫쪮 ¤«ï á¥â¥¢ëå ª àâ RTL8139. |
====================================================================== |
==== ãªæ¨ï 53, ¯®¤äãªæ¨ï 11 - ¯à®ç¨â âì ¤ ë¥ á¥â¥¢®£® á⥪ . ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 53 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = åí¤« ᮪¥â |
* edx = 㪠§ â¥«ì ¡ãä¥à |
* esi = ç¨á«® ¡ ©â ¤«ï ç⥨ï; |
* esi = 0 - ç¨â âì ¢á¥ ¤ ë¥ (¬ ªá¨¬ã¬ 4096 ¡ ©â) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¯à®ç¨â ëå ¡ ©â |
* 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. |
* ãªæ¨ï ¢®§¢à é ¥â ã¯à ¢«¥¨¥, á®®¡é¨¢ ªã¤ á«¥¤ã¥â ¨ä®à¬ æ¨î |
® § ¯à®á¥. ¬® ¯à®¨£àë¢ ¨¥ ¨¤ñâ ¥§ ¢¨á¨¬® ®â ¯à®£à ¬¬ë. |
* ë¥ ¤®«¦ë á®åà ïâìáï ¢ ¯ ¬ï⨠¯® ªà ©¥© ¬¥à¥ |
¤® ª®æ ¯à®¨£àë¢ ¨ï. |
====================================================================== |
============== ãªæ¨ï 58 - à ¡®â á ä ©«®¢®© á¨á⥬®©. ============== |
====================================================================== |
à ¬¥âàë: |
* eax = 58 |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®; ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ¢ § ¢¨á¨¬®á⨠®â ¯®¤äãªæ¨¨ ¬®¦¥â ¢®§¢à é âìáï § 票¥ ¨ |
¢ ¤à㣨å ॣ¨áâà å |
¡é¨© ä®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ®¬¥à ¡«®ª |
* +8: dword: à §¬¥à |
* +12 = +0xC: dword: 㪠§ â¥«ì ¤ ë¥ |
* +16 = +0x10: dword: 㪠§ â¥«ì ¯ ¬ïâì ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: n db: ASCIIZ-áâப á ¨¬¥¥¬ ä ©« |
â®ç¥¨ï - ¢ ¤®ªã¬¥â 樨 ᮮ⢥âáâ¢ãîéãî ¯®¤äãªæ¨î. |
¬ï ä ©« ¥çã¢áâ¢¨â¥«ì® ª ॣ¨áâàã « â¨áª¨å ¡ãª¢, |
àãá᪨¥ ¡ãª¢ë ¤®«¦ë ¡ëâì § £« ¢ë¬¨. |
®à¬ â ¨¬¥¨ ä ©« : |
/base/number/dir1/dir2/.../dirn/file, |
£¤¥ /base/number ¨¤¥â¨ä¨æ¨àã¥â ãáâனá⢮, ª®â®à®¬ ¨é¥âáï ä ©«: |
®¤® ¨§ |
* /RD/1 = /RAMDISK/1 ¤«ï ¤®áâ㯠ª à ¬¤¨áªã |
* /FD/1 = /FLOPPYDISK/1 ¤«ï ¤®áâ㯠ª ¯¥à¢®¬ã ä«®¯¯¨-¤¨áª®¢®¤ã, |
/FD/2 = /FLOPPYDISK/2 ¤«ï ¢â®à®£® ä«®¯¯¨-¤¨áª®¢®¤ |
* /HD/x = /HARDDISK/x - ãáâ ॢ訩 ¢ ਠ⠤®áâ㯠ª ¦ñá⪮¬ã ¤¨áªã |
(¢ í⮬ á«ãç ¥ ¡ § ®¯à¥¤¥«ï¥âáï ¯®¤äãªæ¨¥© 7 äãªæ¨¨ 21), |
x - ®¬¥à à §¤¥« (áç¨â ï á 1) |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x ¤«ï ¤®áâ㯠ᮮ⢥âá⢥® |
ª ãáâனá⢠¬ IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - ®¬¥à à §¤¥« ¢ë¡à ®¬ ¢¨ç¥áâ¥à¥, ¨§¬¥ï¥âáï ®â 1 ¤® 255 |
( ª ¦¤®¬ ¨§ ¢¨ç¥áâ¥à®¢ 㬥à æ¨ï ç¨ ¥âáï á 1) |
¬¥ç ¨ï: |
* ¯¥à¢ëå ¤¢ãå á«ãç ïå ¤®¯ã᪠¥âáï ¨á¯®«ì§®¢ ¨¥ FIRST ¢¬¥áâ® 1, |
SECOND ¢¬¥áâ® 2, ® ¨á¯®«ì§®¢ âì íâã ¢®§¬®¦®áâì |
¥ ४®¬¥¤ã¥âáï ¤«ï 㤮¡á⢠¯¥à¥å®¤ ¡ã¤ã騥 à áè¨à¥¨ï. |
* ª« ¤ë¢ ¥âáï ®£à ¨ç¥¨¥ n<=39. |
* ¬¥ ¯ ¯®ª ¨ ä ©« dir1,...,dirn,file ¤®«¦ë ¡ëâì ¢ ä®à¬ ⥠8.3: |
¨¬ï ¥ ¡®«¥¥ 8 ᨬ¢®«®¢, â®çª , à áè¨à¥¨¥ ¥ ¡®«¥¥ 3 ᨬ¢®«®¢. |
¢®áâ®¢ë¥ ¯à®¡¥«ë ¨£®à¨àãîâáï. àã£¨å ¯à®¡¥«®¢ ¡ëâì ¥ ¤®«¦®. |
᫨ ¨¬ï § ¨¬ ¥â ஢® 8 ᨬ¢®«®¢, â®çªã ¬®¦® ®¯ãáâ¨âì |
(å®âï ¯®«ì§®¢ âìáï í⨬ ¥ ४®¬¥¤ã¥âáï ¤«ï 㤮¡á⢠¯¥à¥å®¤ |
¡ã¤ã騥 à áè¨à¥¨ï). |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥â ¯ ¯®ª à ¬¤¨áª¥. |
ਬ¥àë: |
* '/RAMDISK/FIRST/KERNEL.ASM',0 |
'/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/1/menuet/pics/tanzania.bmp',0 |
®áâã¯ë¥ ¯®¤äãªæ¨¨: |
* ¯®¤äãªæ¨ï 0 - ç⥨¥ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 8 - LBA-ç⥨¥ á ãáâனá⢠|
* ¯®¤äãªæ¨ï 15 - ¯®«ã票¥ ¨ä®à¬ 樨 ® ä ©«®¢®© á¨á⥬¥ |
====================================================================== |
========== ãªæ¨ï 58, ¯®¤äãªæ¨ï 0 - ¯à®ç¨â âì ä ©«/¯ ¯ªã. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 58 |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 0 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ®¬¥à ¡«®ª ¤«ï ç⥨ï (áç¨â ï á 0) |
* +8: dword: ç¨á«® ¡«®ª®¢ ¤«ï ç⥨ï |
* +12 = +0xC: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ä ©« , ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx = à §¬¥à ä ©« (¢ ¡ ©â å) ¨«¨ |
-1=0xffffffff, ¥á«¨ ä ©« ¥ ©¤¥ |
¬¥ç ¨ï: |
* §¬¥à ¡«®ª - 512 ¡ ©â. |
* â äãªæ¨ï ãáâ ५ , ¤«ï ç⥨ï ä ©«®¢ ¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 0 |
äãªæ¨¨ 70, ¤«ï çâ¥¨ï ¯ ¯®ª - ¯®¤äãªæ¨î 1 äãªæ¨¨ 70. |
* ãªæ¨ï ¯®§¢®«ï¥â ç¨â âì ᮤ¥à¦¨¬®¥ ¯ ¯ª¨. § ä ©«®¢ëå á¨á⥬ |
¯®¤¤¥à¦¨¢ ¥âáï ⮫쪮 FAT. ®à¬ â FAT-¯ ¯ª¨ ®¯¨á ¢ «î¡®© |
¤®ªã¬¥â 樨 ¯® FAT. |
* §¬¥à ¯ ¯ª¨ ®¯à¥¤¥«ï¥âáï ¯® à §¬¥àã 楯®çª¨ ª« áâ¥à®¢ ¢ FAT. |
* ᫨ ä ©« ª®ç¨«áï à ìè¥, 祬 ¡ë« ¯à®ç¨â ¯®á«¥¤¨© § ¯à®è¥ë© |
¡«®ª, â® äãªæ¨ï ¯à®ç¨â ¥â, ᪮«ìª® ᬮ¦¥â, ¯®á«¥ 祣® ¢¥àñâ |
eax=6 (EOF). |
* ãªæ¨ï ¯®§¢®«ï¥â ç¨â âì ª®à¥¢ë¥ ¯ ¯ª¨ /rd/1,/fd/x,/hd[n]/x, ® |
¢ ¯¥à¢ëå ¤¢ãå á«ãç ïå ⥪ãé ï ॠ«¨§ æ¨ï ¥ á«¥¤ã¥â |
ãáâ ®¢«¥ë¬ ¯à ¢¨« ¬: |
¤«ï /rd/1: |
* ¥á«¨ 㪠§ ® 0 ¡«®ª®¢ ¤«ï ç⥨ï, áç¨â ¥âáï, |
çâ® § ¯à 訢 ¥âáï 1; |
* ¥á«¨ § ¯à 訢 ¥âáï ¡®«ìè¥ 14 ¡«®ª®¢ ¨«¨ ç «ìë© ¡«®ª |
¥ ¬¥ìè¥ 14-£®, â® ¢®§¢à é ¥âáï eax=5 (not found) ¨ ebx=-1; |
* à §¬¥à ª®à¥¢®£® ª â «®£ à ¬¤¨áª = 14 ¡«®ª®¢, |
0x1C00=7168 ¡ ©â; ® ¢®§¢à é ¥âáï ebx=0 |
(§ ¨áª«î票¥¬ á«ãç ï ¯à¥¤ë¤ã饣® ¯ãªâ ); |
* ª ª ¨ áâà ®, ¬®¦® ¯à®ç¨â âì 14-© ¡«®ª (â ¬, ¢®®¡é¥ £®¢®àï, |
¬ãá®à - ¯®¬¨ î, áçñâ ¢¥¤ñâáï á 0); |
* ¥á«¨ ¡ë« § ¯à®è¥ å®âï ¡ë ®¤¨ ¡«®ª á ®¬¥à®¬, ¥ ¬¥ì訬 14, |
â® ¢®§¢à é ¥âáï eax=6(EOF); ¨ ç¥ eax=0. |
«ï /fd/x: |
* ¥á«¨ ç «ìë© ¡«®ª ¥ ¬¥ìè¥ 14-£®, â® ¢®§¢à é ¥âáï |
eax=5 (not found) ¨ ebx=0; |
* ªáâ ⨠£®¢®àï, ä®à¬ â FAT12 ¤®¯ã᪠¥â ¤¨áª¥âë á à §¬¥à®¬ |
ª®à¥¢®£® ª â «®£ ¬¥ìè¥ ¨«¨ ¡®«ìè¥ 14 ¡«®ª®¢; |
* ¯à®¢¥àª¨ ¤«¨ë ¥ ¤¥« ¥âáï; |
* ¥á«¨ 㤠«®áì ¯à®ç¨â âì ¤ ë¥ á ¤¨áª¥âë, ¢®§¢à é ¥âáï |
eax=0,ebx=0; ¢ ¯à®â¨¢®¬ á«ãç ¥ eax=10 (access denied), ebx=-1. |
* ãªæ¨ï ®¡à ¡ âë¢ ¥â ç⥨¥ á¯¥æ¨ «ìëå ¯ ¯®ª /,/rd,/fd,/hd[n]; |
® १ã«ìâ â ¥ ᮮ⢥âáâ¢ã¥â ®¦¨¤ ¥¬®¬ã |
(¯® à ¡®â¥ á ®¡ëç묨 ä ©« ¬¨/¯ ¯ª ¬¨), ¥ á«¥¤ã¥â ãáâ ®¢«¥ë¬ |
¯à ¢¨« ¬, ¬®¦¥â ¨§¬¥¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå ï¤à ¨ ¯®â®¬ã |
¥ ®¯¨áë¢ ¥âáï. «ï ¯®«ãç¥¨ï ¨ä®à¬ 樨 ®¡ ®¡®à㤮¢ ¨¨ |
¨á¯®«ì§ã©â¥ ¯®¤äãªæ¨î 11 äãªæ¨¨ 18 ¨«¨ |
ç¨â ©â¥ ᮮ⢥âáâ¢ãî騥 ¯ ¯ª¨ ¯®¤äãªæ¨¥© 1 äãªæ¨¨ 70. |
====================================================================== |
========= ãªæ¨ï 58, ¯®¤äãªæ¨ï 8 - LBA-ç⥨¥ á ãáâனá⢠. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 8 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ®¬¥à ¡«®ª ¤«ï ç⥨ï (áç¨â ï á 0) |
* +8: dword: ¨£®à¨àã¥âáï (ãáâ ¢«¨¢ ©â¥ ¢ 1) |
* +12 = +0xC: dword: 㪠§ â¥«ì ¡ãä¥à, ªã¤ ¡ã¤ãâ § ¯¨á ë ¤ ë¥ |
(512 ¡ ©â) |
* +16 = +0x10: dword: 㪠§ â¥«ì ¡ãä¥à ¤«ï à ¡®âë á¨á⥬ë |
(4096 ¡ ©â) |
* +20 = +0x14: ASCIIZ-¨¬ï ãáâனá⢠: ¥çã¢áâ¢¨â¥«ì® ª ॣ¨áâàã, |
®¤® ¨§ /rd/1 = /RamDisk/1, /hd/n = /HardDisk/n, |
1<=n<=4 - ®¬¥à ãáâனá⢠: 1=IDE0, ..., 4=IDE3. |
¬¥áâ® æ¨äà ¤®¯ã᪠¥âáï, å®âï ¨ ¥ ४®¬¥¤ã¥âáï ¤«ï 㤮¡á⢠|
¯¥à¥å®¤ ¡ã¤ã騥 à áè¨à¥¨ï, |
¨á¯®«ì§®¢ ¨¥ 'first','second','third','fourth'. |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ 㪠§ ® ¨¬ï ãáâனá⢠/hd/xxx, £¤¥ xxx ¥ 室¨âáï |
¢ ᯨ᪥ ¢ëè¥: |
* eax = ebx = 1 |
* ¥á«¨ 㪠§ ® ¥¯à ¢¨«ì®¥ ¨¬ï ãáâனá⢠|
(§ ¨áª«î票¥¬ ¯à¥¤ë¤ã饣® á«ãç ï): |
* eax = 5 |
* ebx ¥ ¬¥ï¥âáï |
* ¥á«¨ LBA-¤®áâ㯠§ ¯à¥éñ ¯®¤äãªæ¨¥© 11 äãªæ¨¨ 21: |
* eax = 2 |
* ebx à §àãè ¥âáï |
* ¤«ï à ¬¤¨áª : ¯®¯ë⪠çâ¥¨ï ¡«®ª § ¯à¥¤¥« ¬¨ à ¬¤¨áª |
(18*2*80 ¡«®ª®¢) ¯à¨¢®¤¨â ª |
* eax = 3 |
* ebx = 0 |
* ¯à¨ ãᯥ讬 ç⥨¨: |
* eax = ebx = 0 |
¬¥ç ¨ï: |
* §¬¥à ¡«®ª - 512 ¡ ©â; ç¨â ¥âáï ®¤¨ ¡«®ª. |
* ¥ á«¥¤ã¥â ¯®« £ âìáï ¢®§¢à é ¥¬®¥ § 票¥, |
®® ¬®¦¥â ¨§¬¥¨âìáï ¢ á«¥¤ãîé¨å ¢¥àá¨ïå. |
* ॡã¥âáï, çâ®¡ë ¡ë« à §à¥èñ LBA-¤®áâ㯠ª ãáâனá⢠¬ |
¯®¤äãªæ¨¥© 11 äãªæ¨¨ 21. § âì íâ® ¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¥© 11 äãªæ¨¨ 26. |
* LBA-ç⥨¥ ¤¨áª¥âë ¥ ¯®¤¤¥à¦¨¢ ¥âáï. |
* ãªæ¨ï áç¨âë¢ ¥â ¤ ë¥ ä¨§¨ç¥áª®£® ¦ñá⪮£® ¤¨áª ; |
¥á«¨ ¯® ª ª¨¬-â® ¯à¨ç¨ ¬ ã¦ë ¤ ë¥ ª®ªà¥â®£® à §¤¥« , |
¯à¨¤ñâáï ®¯à¥¤¥«ïâì ç «ìë© á¥ªâ®à í⮣® à §¤¥« |
(«¨¡® ¯àï¬ãî ç¥à¥§ MBR, «¨¡® ¨§ à áè¨à¥®© áâàãªâãàë, |
¢®§¢à é ¥¬®© ⮩ ¦¥ ¯®¤äãªæ¨¥© 11 äãªæ¨¨ 18). |
* ãªæ¨ï ¥ ¯à®¢¥àï¥â ª®¤ ®è¨¡ª¨ ¦ñá⪮£® ¤¨áª , â ª çâ® § ¯à®á |
¥áãé¥áâ¢ãî饣® ᥪâ®à ¢áñ à ¢® çâ®-â® ¯à®ç¨â ¥â |
(¢¥à®ï⥥ ¢á¥£®, 㫨, ® íâ® ®¯à¥¤¥«ï¥âáï ãáâனá⢮¬) ¨ |
íâ® ¡ã¤¥â áç¨â âìáï ãᯥ宬 (eax=0). |
====================================================================== |
= ãªæ¨ï 58, ¯®¤äãªæ¨ï 15 - ¯®«ãç¨âì ¨ä®à¬ æ¨î ® ä ©«®¢®© á¨á⥬¥. |
====================================================================== |
à ¬¥âàë: |
* eax = 58 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 15 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ¨£®à¨àã¥âáï |
* +8: dword: ¨£®à¨àã¥âáï |
* +12 = +0xC: dword: ¨£®à¨àã¥âáï |
* +16 = +0x10: dword: ¨£®à¨àã¥âáï |
* +20 = +0x14: (¯à®¢¥àï¥âáï ⮫쪮 ¢â®à®© ᨬ¢®«, áà §ã ¯®á«¥ á«íè ) |
/rd=/RAMDISK ¨«¨ /hd=/HARDDISK |
®§¢à é ¥¬®¥ § 票¥: |
* ¥á«¨ ¢â®à®© ᨬ¢®« ¥ ¯à¨ ¤«¥¦¨â ¬®¦¥áâ¢ã {'r','R','h','H'}: |
* eax = 3 |
* ebx = ecx = dword [fileinfo] = 0 |
* ¤«ï à ¬¤¨áª : |
* eax = 0 (ãᯥå) |
* ebx = ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ = 2847 |
* ecx = ç¨á«® ᢮¡®¤ëå ª« áâ¥à®¢ |
* dword [fileinfo] = à §¬¥à ª« áâ¥à = 512 |
* ¤«ï ¦ñá⪮£® ¤¨áª : ¡ § ¨ à §¤¥« ®¯à¥¤¥«ïîâáï ¯®¤äãªæ¨ï¬¨ 7 ¨ 8 |
äãªæ¨¨ 21: |
* eax = 0 (ãᯥå) |
* ebx = ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ |
* ecx = ç¨á«® ᢮¡®¤ëå ª« áâ¥à®¢ |
* dword [fileinfo] = à §¬¥à ª« áâ¥à (¢ ¡ ©â å) |
¬¥ç ¨ï: |
* ¥ 㤨¢«ï©â¥áì áâà ®¬ã à ᯮ«®¦¥¨î 4-£® ¢®§¢à é ¥¬®£® |
¯ à ¬¥âà - ª®£¤ ¯¨á «áï íâ®â ª®¤, ¯à¨ á¨á⥬ëå ¢ë§®¢ å |
¯à¨«®¦¥¨î ¢®§¢à é «¨áì ⮫쪮 ॣ¨áâàë eax,ebx,ecx (¨§ |
pushad-áâàãªâãàë, ¯¥à¥¤ î饩áï ª ª à£ã¬¥â á¨á⥬®© äãªæ¨¨). |
¥¯¥àì íâ® ¨á¯à ¢«¥®, â ª çâ®, ¢®§¬®¦®, ¨¬¥¥â á¬ëá« ¢®§¢à é âì |
à §¬¥à ª« áâ¥à ¢ edx, ¯®ª íâã äãªæ¨î ¥ ç «¨ ¨á¯®«ì§®¢ âì. |
* ®®¡é¥-â® ¥éñ áãé¥áâ¢ã¥â ¯®¤äãªæ¨ï 11 äãªæ¨¨ 18, ¢®§¢à é îé ï |
¨ä®à¬ æ¨î ® ä ©«®¢®© á¨á⥬¥. ® à áè¨à¥®© â ¡«¨æ¥ ¤¨áª®¢®© |
¯®¤á¨áâ¥¬ë ¬®¦® ®¯à¥¤¥«¨âì à §¬¥à ª« áâ¥à (â ¬ ® åà ¨âáï |
¢ ᥪâ®à å) ¨ ®¡é¥¥ ç¨á«® ª« áâ¥à®¢ ¤«ï ¦ñáâª¨å ¤¨áª®¢. |
====================================================================== |
=========== ãªæ¨ï 60 - Inter Process Communication (IPC). ========== |
====================================================================== |
IPC ¯à¨¬¥ï¥âáï ¤«ï ¯®áë«®ª á®®¡é¥¨© ®â ®¤®£® ¯à®æ¥áá /¯®â®ª |
¤à㣮¬ã. ਠí⮬ á«¥¤ã¥â ¯à¥¤¢ à¨â¥«ì® ¤®£®¢®à¨âìáï ® ⮬, ª ª |
¨â¥à¯à¥â¨à®¢ âì ª®ªà¥â®¥ á®®¡é¥¨¥. |
-------- ®¤äãªæ¨ï 1 - ãáâ ®¢¨âì ®¡« áâì ¤«ï ¯®«ã票ï IPC --------- |
ë§ë¢ ¥âáï ¯à®æ¥áᮬ-¯à¨ñ¬¨ª®¬. |
à ¬¥âàë: |
* eax = 60 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à |
* edx = à §¬¥à ¡ãä¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¢á¥£¤ ãá¯¥è® |
®à¬ â IPC-¡ãä¥à : |
* +0: dword: ¥á«¨ §¤¥áì ¥ 0, â® ¡ãä¥à áç¨â ¥âáï § ¡«®ª¨à®¢ ë¬; |
¡«®ª¨àã©â¥/à §¡«®ª¨àã©â¥ ¡ãä¥à, ª®£¤ ¢ë á ¨¬ ªâ¨¢® à ¡®â ¥â¥ |
¨ ¢ ¬ ¤®, çâ®¡ë ¨§¢¥ ¥ ¨§¬¥ï«¨áì ¤ ë¥ ¡ãä¥à |
(¥ ¯®áâ㯠«¨ ®¢ë¥ á®®¡é¥¨ï) |
* +4: dword: § ïâ® ¬¥áâ ¢ ¡ãä¥à¥ (¢ ¡ ©â å) |
* +8: ¯¥à¢®¥ á®®¡é¥¨¥ |
* +8+n: ¢â®à®¥ á®®¡é¥¨¥ |
* ... |
®à¬ â á®®¡é¥¨ï: |
* +0: dword: PID ¯à®æ¥áá /¯®â®ª , ¯®á« ¢è¥£® á®®¡é¥¨¥ |
* +4: dword: ¤«¨ á®®¡é¥¨ï (¥ áç¨â ï íâ®â § £®«®¢®ª) |
* +8: n*byte: ¤ ë¥ á®®¡é¥¨ï |
--------------- ®¤äãªæ¨ï 2 - ¯®á« âì á®®¡é¥¨¥ IPC. ---------------- |
ë§ë¢ ¥âáï ¯à®æ¥áᮬ-¨¨æ¨ â®à®¬. |
à ¬¥âàë: |
* eax = 60 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = PID ¯à¨ñ¬¨ª |
* edx = 㪠§ â¥«ì ¤ ë¥ á®®¡é¥¨ï |
* esi = ¤«¨ á®®¡é¥¨ï (¢ ¡ ©â å) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¯à¨ñ¬¨ª ¥ ®¯à¥¤¥«¨« ¡ãä¥à ¤«ï IPC-á®®¡é¥¨© |
(¬®¦¥â ¡ëâì, ¥éñ ¥ ãᯥ«, ¬®¦¥â ¡ëâì, íâ® ¥ â®â ¯®â®ª, |
ª®â®àë© ã¦¥) |
* eax = 2 - ¯à¨ñ¬¨ª § ¡«®ª¨à®¢ « IPC-¡ãä¥à; |
¯®¯à®¡ã©â¥ ¥¬®£® ¯®¤®¦¤ âì |
* eax = 3 - ¯¥à¥¯®«¥¨¥ IPC-¡ãä¥à ¯à¨ñ¬¨ª |
* eax = 4 - ¯à®æ¥áá /¯®â®ª á â ª¨¬ PID ¥ áãé¥áâ¢ã¥â |
¬¥ç ¨ï: |
* ¨á⥬ áà §ã ¯®á«¥ § ¯¨á¨ IPC-á®®¡é¥¨ï ¢ ¡ãä¥à ¯®áë« ¥â |
¯®â®ªã-¯à¨ñ¬¨ªã ᮡë⨥ á ª®¤®¬ 7 (á¬. ª®¤ë ᮡë⨩). |
====================================================================== |
=== ãªæ¨ï 61 - ¯®«ãç¨âì ¯ à ¬¥âàë ¤«ï ¯àאַ£® ¤®áâ㯠ª £à 䨪¥. === |
====================================================================== |
à®£à ¬¬¥ ¤®áâã¯ë ¤ ë¥ £à ä¨ç¥áª®£® íªà (®¡« áâì ¯ ¬ïâ¨, ª®â®à ï |
ᮡá⢥® ¨ ®â®¡à ¦ ¥â ᮤ¥à¦¨¬®¥ íªà ) ¯àï¬ãî ¡¥§ ¢ë§®¢®¢ |
á¨á⥬ëå äãªæ¨© ç¥à¥§ ᥫ¥ªâ®à gs: |
mov eax, [gs:0] |
¯®¬¥áâ¨â ¢ eax ¯¥à¢ë© dword ¡ãä¥à , ᮤ¥à¦ 騩 ¨ä®à¬ æ¨î ® 梥⥠|
«¥¢®© ¢¥à奩 â®çª¨ (¨, ¢®§¬®¦®, 梥⠥᪮«ìª¨å á«¥¤ãîé¨å). |
mov [gs:0], eax |
¯à¨ à ¡®â¥ ¢ ०¨¬ å VESA c LFB |
ãáâ ®¢¨â 梥⠫¥¢®© ¢¥à奩 â®çª¨ |
(¨ ¢®§¬®¦®, 梥⠥᪮«ìª¨å á«¥¤ãîé¨å). |
«ï ¨â¥à¯à¥â 樨 ¤ ëå £à ä¨ç¥áª®£® íªà âॡã¥âáï § ¨¥ |
¥ª®â®àëå ¯ à ¬¥â஢, ª®â®àë¥ ¢®§¢à é îâáï í⮩ äãªæ¨¥©. |
¬¥ç ¨ï: |
* à ¬¥âàë £à 䨪¨ ®ç¥ì ।ª® ¬¥ïîâáï ¯à¨ à ¡®â¥ á¨á⥬ë, |
¨¬¥®, ⮫쪮 ¢ á«ãç ïå, ª®£¤ ¯®«ì§®¢ ⥫ì à ¡®â ¥â |
á ¯à®£à ¬¬®© VRR. |
* ਠ¨§¬¥¥¨¨ ¢¨¤¥®à¥¦¨¬ á¨á⥬ ¯¥à¥à¨á®¢ë¢ ¥â ¢á¥ ®ª |
(ᮡë⨥ á ª®¤®¬ 1) ¨ ¯¥à¥à¨á®¢ë¢ ¥â ä® (ᮡë⨥ 5). |
⨠¦¥ ᮡëâ¨ï ¯à®¨á室ïâ ¨ ¢ ¤à㣨å á«ãç ïå, |
ª®â®àë¥ ¢áâà¥ç îâáï § ç¨â¥«ì® ç é¥, 祬 ¨§¬¥¥¨¥ ¢¨¤¥®à¥¦¨¬ . |
* à¨ à ¡®â¥ ¢ ¢¨¤¥®à¥¦¨¬ å á LFB ᥫ¥ªâ®à gs 㪠§ë¢ ¥â |
ᮡá⢥® LFB, â ª çâ® ç⥨¥/§ ¯¨áì ¯® gs ¯à¨¢®¤ïâ |
¥¯®á।á⢥® ª ¨§¬¥¥¨î ᮤ¥à¦¨¬®£® íªà . à¨ à ¡®â¥ ¢ |
¢¨¤¥®à¥¦¨¬ å ¡¥§ LFB gs 㪠§ë¢ ¥â ¥ª®â®àãî ®¡« áâì ¤ ëå |
ï¤à , ¯à¨çñ¬ ¢á¥ äãªæ¨¨ ¢ë¢®¤ íªà ¤®¡à®á®¢¥áâ® ¢ë¯®«ïîâ |
¤¢®©ãî à ¡®âã ¯® § ¯¨á¨ ¥¯®á।á⢥® íªà ¨ ¯® § ¯¨á¨ |
¢ íâ®â ¡ãä¥à. १ã«ìâ ⥠¯à¨ ç⥨¨ ᮤ¥à¦¨¬®£® í⮣® ¡ãä¥à |
१ã«ìâ âë ᮮ⢥âáâ¢ãîâ ᮤ¥à¦¨¬®¬ã íªà |
(á, ¢®®¡é¥ £®¢®àï, ¡®«ì訬 æ¢¥â®¢ë¬ à §à¥è¥¨¥¬), |
§ ¯¨áì ¨£®à¨àã¥âáï. |
᪫î票¥¬ ï¥âáï ०¨¬ 320*200, ¤«ï ª®â®à®£® ¢ £« ¢®¬ 横«¥ |
á¨á⥬®£® ¯®â®ª ¢ë¯®«ï¥âáï ®¡®¢«¥¨¥ íªà ¢ ᮮ⢥âá⢨¨ |
á ¤¢¨¦¥¨ï¬¨ ªãàá®à ¬ëè¨. |
------------------------- §à¥è¥¨¥ íªà -------------------------- |
à ¬¥âàë: |
* eax = 61 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = [à §à¥è¥¨¥ ¯® ®á¨ x]*65536 + [à §à¥è¥¨¥ ¯® ®á¨ y] |
¬¥ç ¨ï: |
* ®¦® ¨á¯®«ì§®¢ âì äãªæ¨î 14 á ãçñ⮬ ⮣®, çâ® ® ¢®§¢à é ¥â |
à §¬¥àë 1 ¬¥ìè¥. â® ¯®«®áâìî íª¢¨¢ «¥âë© á¯®á®¡. |
------------------------ ¨á«® ¡¨â ¯¨ªá¥«ì ------------------------ |
à ¬¥âàë: |
* eax = 61 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¡¨â ¯¨ªá¥«ì (24 ¨«¨ 32) |
------------------------ ¨á«® ¡ ©â áâபã ------------------------ |
à ¬¥âàë: |
* eax = 61 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ç¨á«® ¡ ©â, ª®â®à®¥ § ¨¬ ¥â ®¤ áâப à §¢ñà⪨ |
(£®à¨§®â «ì ï «¨¨ï íªà ¥) |
====================================================================== |
===== ãªæ¨ï 62, ¯®¤äãªæ¨ï 0 - ¯®«ãç¨âì ¢¥àá¨î PCI-¨â¥à䥩á . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ; ¨ ç¥ |
* ah.al = ¢¥àá¨ï PCI-¨â¥à䥩á (ah=¢¥àá¨ï, al=¯®¤¢¥àá¨ï) |
* áâ à襥 á«®¢® eax ®¡ã«¥® |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ᫨ PCI BIOS ¥ ¯®¤¤¥à¦¨¢ ¥âáï, â® § 票¥ ax ¥®¯à¥¤¥«¥®. |
====================================================================== |
==== ãªæ¨ï 62, ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì ®¬¥à ¯®á«¥¤¥© PCI-è¨ë. === |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ; ¨ ç¥ |
* al = ®¬¥à ¯®á«¥¤¥© PCI-è¨ë; ®á⠢訥áï ¡ ©âë eax à §àãè îâáï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ᫨ PCI BIOS ¥ ¯®¤¤¥à¦¨¢ ¥âáï, â® § 票¥ al ¥®¯à¥¤¥«¥®. |
====================================================================== |
====================== ãªæ¨ï 62, ¯®¤äãªæ¨ï 2 ====================== |
== ®«ãç¨âì ¬¥å ¨§¬ ®¡à é¥¨ï ª ª®ä¨£ãà 樮®¬ã ¯à®áâà áâ¢ã PCI. = |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ¤®áâ㯠ª PCI § ¯à¥éñ; ¨ ç¥ |
* al = ¬¥å ¨§¬ (1 ¨«¨ 2); ¯à®ç¨¥ ¡ ©âë eax à §àãè îâáï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ¥å ¨§¬ ®¡à é¥¨ï ¢ë¡¨à ¥âáï ¢ ᮮ⢥âá⢨¨ |
á å à ªâ¥à¨á⨪ ¬¨ ®¡®à㤮¢ ¨ï. |
* ®¤äãªæ¨¨ çâ¥¨ï ¨ § ¯¨á¨ ¢â®¬ â¨ç¥áª¨ à ¡®â îâ |
á ¢ë¡à ë¬ ¬¥å ¨§¬®¬. |
====================================================================== |
======== ãªæ¨ï 62, ¯®¤äãªæ¨¨ 4,5,6 - ¯à®ç¨â âì PCI-ॣ¨áâà. ======= |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 4 - ç¨â âì ¡ ©â |
* bl = 5 - ç¨â âì á«®¢® |
* bl = 6 - ç¨â âì ¤¢®©®¥ á«®¢® |
* bh = ®¬¥à PCI-è¨ë |
* ch = dddddfff, £¤¥ ddddd = ®¬¥à ãáâனá⢠訥, |
fff = ®¬¥à äãªæ¨¨ ãáâனá⢠|
* cl = ®¬¥à ॣ¨áâà (¤®«¦¥ ¡ëâì çñâë¬ ¤«ï bl=5, |
¤¥«¨âìáï 4 ¤«ï bl=6) |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (§ ¯à¥éñ ¤®áâ㯠ª PCI ¨«¨ |
¥¯®¤¤¥à¦¨¢ ¥¬ë¥ ¯ à ¬¥âàë); ¨ ç¥ |
* al/ax/eax (¢ § ¢¨á¨¬®á⨠®â § ¯à®è¥®£® à §¬¥à ) ᮤ¥à¦¨â ¤ ë¥; |
®áâ ¢è ïáï ç áâì ॣ¨áâà eax à §àãè ¥âáï |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ¥å ¨§¬ ¤®áâ㯠2 ¯®¤¤¥à¦¨¢ ¥â ⮫쪮 16 ãáâனá⢠訥 ¨ |
¨£®à¨àã¥â ®¬¥à äãªæ¨¨. ®«ãç¨âì ¬¥å ¨§¬ ¤®áâ㯠¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 2. |
* ¥ª®â®àë¥ à¥£¨áâàë áâ ¤ àâë ¨ áãé¥áâ¢ãîâ ¤«ï ¢á¥å ãáâனáâ¢, |
¥ª®â®àë¥ ®¯à¥¤¥«ïîâáï ª®ªà¥âë¬ ãáâனá⢮¬. ¯¨á®ª ¯¥à¢ëå |
¢å®¤¨â, ¯à¨¬¥à, ¢ ¨§¢¥áâë© Interrupt List by Ralf Brown |
(http://www.pobox.com/~ralf/files.html, |
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/); |
ᯨ᮪ ¢â®àëå ¤®«¦¥ ¡ëâì 㪠§ ¢ ¤®ªã¬¥â 樨 ¯® ãáâனáâ¢ã. |
====================================================================== |
======= ãªæ¨ï 62, ¯®¤äãªæ¨¨ 8,9,10 - § ¯¨á âì ¢ PCI-ॣ¨áâà. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 62 - ®¬¥à äãªæ¨¨ |
* bl = 8 - ¯¨á âì ¡ ©â |
* bl = 9 - ¯¨á âì á«®¢® |
* bl = 10 - ¯¨á âì ¤¢®©®¥ á«®¢® |
* bh = ®¬¥à PCI-è¨ë |
* ch = dddddfff, £¤¥ ddddd = ®¬¥à ãáâனá⢠訥, |
fff = ®¬¥à äãªæ¨¨ ãáâனá⢠|
* cl = ®¬¥à ॣ¨áâà (¤®«¦¥ ¡ëâì çñâë¬ ¤«ï bl=9, |
¤¥«¨âìáï 4 ¤«ï bl=10) |
* dl/dx/edx (¢ § ¢¨á¨¬®á⨠®â § ¯à®è¥®£® à §¬¥à ) ᮤ¥à¦¨â |
¤ ë¥ ¤«ï § ¯¨á¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 - ®è¨¡ª (§ ¯à¥éñ ¤®áâ㯠ª PCI ¨«¨ |
¥¯®¤¤¥à¦¨¢ ¥¬ë¥ ¯ à ¬¥âàë) |
* eax = 0 - ãá¯¥è® |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì à §à¥èñ ¨§ª®ã஢¥¢ë© ¤®áâ㯠ª PCI |
¤«ï ¯à¨«®¦¥¨© ¯®¤äãªæ¨¥© 12 äãªæ¨¨ 21. |
* ¥å ¨§¬ ¤®áâ㯠2 ¯®¤¤¥à¦¨¢ ¥â ⮫쪮 16 ãáâனá⢠訥 ¨ |
¨£®à¨àã¥â ®¬¥à äãªæ¨¨. ®«ãç¨âì ¬¥å ¨§¬ ¤®áâ㯠¬®¦® ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 2. |
* ¥ª®â®àë¥ à¥£¨áâàë áâ ¤ àâë ¨ áãé¥áâ¢ãîâ ¤«ï ¢á¥å ãáâனáâ¢, |
¥ª®â®àë¥ ®¯à¥¤¥«ïîâáï ª®ªà¥âë¬ ãáâனá⢮¬. ¯¨á®ª ¯¥à¢ëå |
¢å®¤¨â, ¯à¨¬¥à, ¢ ¨§¢¥áâë© Interrupt List by Ralf Brown; |
ᯨ᮪ ¢â®àëå ¤®«¦¥ ¡ëâì 㪠§ ¢ ¤®ªã¬¥â 樨 ¯® ãáâனáâ¢ã. |
====================================================================== |
================ ãªæ¨ï 63 - à ¡®â á ¤®áª®© ®â« ¤ª¨. =============== |
====================================================================== |
®áª ®â« ¤ª¨ ¯à¥¤áâ ¢«ï¥â ᮡ®© á¨áâ¥¬ë© ¡ãä¥à ( 4096 ¡ ©â), |
¢ ª®â®àë© «î¡ ï ¯à®£à ¬¬ ¬®¦¥â § ¯¨á âì (¢®®¡é¥ £®¢®àï, ¯à®¨§¢®«ìë¥) |
¤ ë¥ ¨ ¨§ ª®â®à®£® ¤àã£ ï ¯à®£à ¬¬ ¬®¦¥â í⨠¤ ë¥ ¯à®ç¨â âì. |
áâì ᮣ« 襨¥, ¢ ᮮ⢥âá⢨¨ á ª®â®àë¬ § ¯¨áë¢ ¥¬ë¥ ¤ ë¥ - |
⥪áâ®¢ë¥ áâப¨, ¨â¥à¯à¥â¨àã¥¬ë¥ ª ª ®â« ¤®çë¥ á®®¡é¥¨ï ® 室¥ |
¢ë¯®«¥¨ï ¯à®£à ¬¬ë. ¤à® ¢ ®¯à¥¤¥«ñëå á¨âã æ¨ïå â ª¦¥ § ¯¨áë¢ ¥â |
¤®áªã ®â« ¤ª¨ ᢥ¤¥¨ï ® ¢ë¯®«¥¨¨ ¥ª®â®àëå äãªæ¨©; |
¯® ᮣ« 襨î á®®¡é¥¨ï ï¤à ç¨ îâáï á ¯à¥ä¨ªá "K : ". |
«ï ¯à®á¬®âà ¤®áª¨ ®â« ¤ª¨ ᮧ¤ ® ¯à¨«®¦¥¨¥ board, |
ª®â®à®¥ áç¨âë¢ ¥â ¤ ë¥ ¨§ ¡ãä¥à ¨ ®â®¡à ¦ ¥â ¨å ¢ ᢮ñ¬ ®ª¥. board |
¯®¨¬ ¥â ¯®á«¥¤®¢ ⥫ì®áâì ª®¤®¢ 13,10 ª ª ¯¥à¥å®¤ ®¢ãî áâபã. |
¨¬¢®« á ã«¥¢ë¬ ª®¤®¬ ¢ ª®æ¥ áâப¨ ¥ ®¡ï§ ⥫¥, ® ¨ ¥ ¬¥è ¥â. |
á¢ï§¨ á ¯®ï¢«¥¨¥¬ ®â« ¤ç¨ª 楮áâì ¤®áª¨ ®â« ¤ª¨ ¥áª®«ìª® |
ᨧ¨« áì, ¯®áª®«ìªã ®â« ¤ç¨ª ¯®§¢®«ï¥â ¯®«®áâìî ª®â஫¨à®¢ âì 室 |
¢ë¯®«¥¨ï ¯à®£à ¬¬ë, ¯à¨çñ¬ ¤«ï í⮣® ¥ âॡã¥âáï ¨ª ª¨å ãᨫ¨© |
á® áâ®à®ë á ¬®© ¯à®£à ¬¬ë. ¥¬ ¥ ¬¥¥¥ ¢® ¬®£¨å á«ãç ïå |
¤®áª ®â« ¤ª¨ ¯à®¤®«¦ ¥â ®áâ ¢ âìáï ¯®«¥§®©. |
---------------------------- ¯¨áì ¡ ©â ---------------------------- |
à ¬¥âàë: |
* eax = 63 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* cl = ¡ ©â ¤ ëå |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ©â § ¯¨áë¢ ¥âáï ¢ ¡ãä¥à. «¨ ¡ãä¥à - 512 ¡ ©â. |
ਠ¯¥à¥¯®«¥¨¨ ¡ãä¥à ¢á¥ ¯®«ãç¥ë¥ ¤ ë¥ â¥àïîâáï |
¨ § ¯®«¥¨¥ ç¨ ¥âáï ᮢ á ã«ï. |
* «ï ¢ë¢®¤ ¤®áªã ®â« ¤ª¨ ¡®«¥¥ á«®¦ëå ®¡ê¥ªâ®¢ (áâப, ç¨á¥«) |
¤®áâ â®ç® í⮩ äãªæ¨¨, ¢ë§ë¢ ¥¬®© ¢ 横«¥. ®¦® ¥ ¯¨á âì |
¢àãçãî ᮮ⢥âáâ¢ãî騩 ª®¤, ¢®á¯®«ì§®¢ âìáï ä ©«®¬ debug.inc, |
¢å®¤ï騬 ¢ ¤¨áâਡã⨢. |
---------------------------- ⥨¥ ¡ ©â ---------------------------- |
¡¨à ¥â ¡ ©â ¨§ ¡ãä¥à . |
à ¬¥âàë: |
* eax = 63 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ebx = 0 - ¡ãä¥à ¯ãáâ |
* eax = ¡ ©â, ebx = 1 - ¡ ©â ãá¯¥è® ¯à®ç¨â |
====================================================================== |
========== ãªæ¨ï 64 - ¯¥à¥à á¯à¥¤¥«¨âì ¯ ¬ïâì ¯à¨«®¦¥¨ï. ========== |
====================================================================== |
à ¬¥âàë: |
* eax = 64 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ¥¤¨á⢥ ï ¯®¤äãªæ¨ï |
* ecx = ®¢ë© à §¬¥à ¯ ¬ï⨠|
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ¥¤®áâ â®ç® ¯ ¬ï⨠|
¬¥ç ¨ï: |
* áâì ¤à㣮© ᯮᮡ ¢ë¤¥«¥¨ï/®á¢®¡®¦¤¥¨ï ¤¨ ¬¨ç¥áª®© ¯ ¬ï⨠- |
¯®¤äãªæ¨¨ 11, 12, 13 äãªæ¨¨ 68. |
* ãªæ¨ï ¥ ¬®¦¥â ¨á¯®«ì§®¢ âìáï ᮢ¬¥áâ® á 68.11, 68.12, 68.13. |
맮¢ äãªæ¨¨ ¡ã¤¥â ¨£®à¨à®¢ âìáï, ¥á«¨ ¯à¨«®¦¥¨¥ ᮧ¤ áâ |
«®ª «ìãî ªãç㠢맮¢®¬ 68.11. |
====================================================================== |
========= ãªæ¨ï 65 - ¢ë¢¥á⨠¨§®¡à ¦¥¨¥ á ¯ «¨âன ¢ ®ª®. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 65 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨§®¡à ¦¥¨¥ |
* ecx = [à §¬¥à ¯® ®á¨ x]*65536 + [à §¬¥à ¯® ®á¨ y] |
* edx = [ª®®à¤¨ â ¯® ®á¨ x]*65536 + [ª®®à¤¨ â ¯® ®á¨ y] |
* esi = ç¨á«® ¡¨â ¯¨ªá¥«ì, ¤®«¦® ¡ëâì 8, 24 ¨«¨ 32 |
* edi = 㪠§ â¥«ì ¯ «¨âàã (256 梥⮢ 0x00RRGGBB); |
¨£®à¨àã¥âáï ¯à¨ esi = 24 ¨ 32 |
* ebp = ᬥ饨¥ ¤ ëå ª ¦¤®© á«¥¤ãî饩 áâப¨ ¨§®¡à ¦¥¨ï |
®â®á¨â¥«ì® ¯à¥¤ë¤ã饩 |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ®®à¤¨ âë ¨§®¡à ¦¥¨ï - íâ® ª®®à¤¨ âë ¢¥à奣® «¥¢®£® 㣫 |
¨§®¡à ¦¥¨ï ®â®á¨â¥«ì® ®ª . |
* §¬¥à ¨§®¡à ¦¥¨ï ¢ ¡ ©â å ¥áâì xsize*ysize. |
* ¦¤ë© ¡ ©â ¨§®¡à ¦¥¨ï à áᬠâਢ ¥âáï ª ª ¨¤¥ªá ¢ ¯ «¨âà¥. |
* ᫨ ¨§®¡à ¦¥¨¥ ¨á¯®«ì§ã¥â ¥ ¢á¥ 256 梥⮢, ¬¥ìè¥, |
à §¬¥à ¯ «¨âàë ¬®¦¥â ¡ëâì ¬¥ìè¥ 256. |
* 맮¢ äãªæ¨¨ 7 íª¢¨¢ «¥â¥ ¢ë§®¢ã í⮩ äãªæ¨¨ á ¯ à ¬¥âà ¬¨ |
esi=24, ebp=0. |
====================================================================== |
================= ãªæ¨ï 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 |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ª § ¨¥ ¢ ecx ¥áãé¥áâ¢ãî饣® ¨«¨ ¥à¥ «¨§®¢ ®£® ¤«ï ¤ ®£® |
¯à®æ¥áá®à MSR ¯®¢«¥çñ⠨᪫î票¥ ¢ ï¤à¥, ª®â®à®¥ ¯à¨¡ìñâ ¯®â®ª. |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ®¯à¥¤¥«¨âì, ¯®¤¤¥à¦¨¢ îâáï «¨ MSR ¢ 楫®¬, |
ª®¬ ¤®© cpuid. ç¥ ¢®§¨ª¥â 㦥 ¤à㣮¥ ¨áª«î票¥ ¢ ï¤à¥, |
ª®â®à®¥ ¢áñ à ¢® ¯à¨¡ìñâ ¯®â®ª. |
====================================================================== |
===== ãªæ¨ï 68, ¯®¤äãªæ¨ï 11 - ¨¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá . ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 11 - ®¬¥à ¯®¤äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ãᯥå |
* ¨ ç¥ à §¬¥à ᮧ¤ ®© ªãç¨ |
¬¥ç ¨ï: |
* 맮¢ äãªæ¨¨ ¨¨æ¨ «¨§¨àã¥â ªãçã, ¨§ ª®â®à®© ¢¯®á«¥¤á⢨¨ ¬®¦® |
¢ë¤¥«ïâì ¨ ®á¢®¡®¦¤ âì ¡«®ª¨ ¯ ¬ï⨠¯®¤äãªæ¨ï¬¨ 12 ¨ 13. |
§¬¥à ªãç¨ à ¢¥ à §¬¥à㠢ᥩ ᢮¡®¤®© ¯ ¬ï⨠¯à¨«®¦¥¨ï. |
* ਠ¯®¢â®à®¬ ¢ë§®¢¥ äãªæ¨¨ ⥬ ¦¥ ¯à®æ¥áᮬ äãªæ¨ï ¢¥àñâ |
à §¬¥à áãé¥áâ¢ãî饩 ªãç¨. |
* ®á«¥ ᮧ¤ ¨ï ªãç¨ ¢ë§®¢ë äãªæ¨¨ 64 ¨£®à¨àãîâáï. |
====================================================================== |
========== ãªæ¨ï 68, ¯®¤äãªæ¨ï 12 - ¢ë¤¥«¨âì ¡«®ª ¯ ¬ïâ¨. ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 12 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = âà¥¡ã¥¬ë© à §¬¥à ¢ ¡ ©â å |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 㪠§ â¥«ì ¢ë¤¥«¥ë© ¡«®ª |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ¨¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11. |
* ãªæ¨ï ¢ë¤¥«ï¥â 楫®¥ ç¨á«® áâà ¨æ (4 ¡) â ª, çâ® ä ªâ¨ç¥áª¨© |
à §¬¥à ¢ë¤¥«¥®£® ¡«®ª ¡®«ìè¥ ¨«¨ à ¢¥ § ¯à®è¥®¬ã. |
====================================================================== |
========= ãªæ¨ï 68, ¯®¤äãªæ¨ï 13 - ®á¢®¡®¤¨âì ¡«®ª ¯ ¬ïâ¨. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 13 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡«®ª ¯ ¬ï⨠|
®§¢à é ¥¬®¥ § 票¥: |
* eax = 1 - ãá¯¥è® |
* eax = 0 - ¥ã¤ ç |
¬¥ç ¨ï: |
* «®ª ¯ ¬ï⨠¤®«¦¥ ¡ëâì à ¥¥ ¢ë¤¥«¥ ¯®¤äãªæ¨¥© 12 |
¨«¨ ¯®¤äãªæ¨¥© 20. |
====================================================================== |
===== ãªæ¨ï 68, ¯®¤äãªæ¨ï 14 - ®¦¨¤ âì ¨§¢¥é¥¨ï ®â ¤à ©¢¥à . ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 14 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ â¥«ì ¡ãä¥à ¤«ï ¨ä®à¬ 樨 (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-áâபã á ¨¬¥¥¬ ¤à ©¢¥à |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ã¤ ç |
* ¨ ç¥ eax = åí¤« ¤à ©¢¥à |
¬¥ç ¨ï: |
* ᫨ ¤à ©¢¥à ¥éñ ¥ § £à㦥, ® § £à㦠¥âáï; |
¥á«¨ ¤à ©¢¥à 㦥 § £à㦥, ¨ç¥£® ¥ ¬¥ï¥âáï. |
* ¬ï ¤à ©¢¥à çã¢áâ¢¨â¥«ì® ª ॣ¨áâàã ᨬ¢®«®¢. |
ªá¨¬ «ì ï ¤«¨ ¨¬¥¨ - 16 ᨬ¢®«®¢, ¢ª«îç ï § ¢¥àè î騩 |
ã«¥¢®© ᨬ¢®«, ®áâ «ìë¥ á¨¬¢®«ë ¨£®à¨àãîâáï. |
* à ©¢¥à á ¨¬¥¥¬ ABC § £à㦠¥âáï ¨§ ä ©« /rd/1/drivers/ABC.obj. |
====================================================================== |
========== ãªæ¨ï 68, ¯®¤äãªæ¨ï 17 - ã¯à ¢«¥¨¥ ¤à ©¢¥à®¬. ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 17 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì ã¯à ¢«ïîéãî áâàãªâãàã: |
* +0: dword: åí¤« ¤à ©¢¥à |
* +4: dword: ª®¤ äãªæ¨¨ ¤à ©¢¥à |
* +8: dword: 㪠§ â¥«ì ¢å®¤ë¥ ¤ ë¥ |
* +12 = +0xC: dword: à §¬¥à ¢å®¤ëå ¤ ëå |
* +16 = +0x10: dword: 㪠§ â¥«ì ¢ëå®¤ë¥ ¤ ë¥ |
* +20 = +0x14: dword: à §¬¥à ¢ë室ëå ¤ ëå |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ®¯à¥¤¥«ï¥âáï ¤à ©¢¥à®¬ |
¬¥ç ¨ï: |
* ®¤ë äãªæ¨© ¨ áâàãªâãà ¢å®¤ëå/¢ë室ëå ¤ ëå |
®¯à¥¤¥«ïîâáï ¤à ©¢¥à®¬. |
* ।¢ à¨â¥«ì® ¤®«¦¥ ¡ëâì ¯®«ãç¥ åí¤« ¤à ©¢¥à ¯®¤äãªæ¨¥© 16. |
====================================================================== |
== ãªæ¨ï 68, ¯®¤äãªæ¨ï 18 - ãáâ ®¢¨âì ®¡à ¡®â稪 ¨áª«î票© SSE. = |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 18 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¤à¥á ®¢®£® ®¡à ¡®â稪 ¨áª«î票© |
®§¢à é ¥¬®¥ § 票¥: |
* eax = ¤à¥á áâ ண® ®¡à ¡®â稪 ¨áª«î票© |
(0, ¥á«¨ ® ¥ ¡ë« ãáâ ®¢«¥) |
====================================================================== |
============= ãªæ¨ï 68, ¯®¤äãªæ¨ï 19 - § £à㧨âì DLL. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 19 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì ASCIIZ-áâபã á ¯®«ë¬ ¯ãâñ¬ ª DLL |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ¥ã¤ ç |
* ¨ ç¥ eax = 㪠§ ⥫ì â ¡«¨æã íªá¯®àâ DLL |
¬¥ç ¨ï: |
* ¡«¨æ íªá¯®à⠯।áâ ¢«ï¥â ᮡ®© ¬ áᨢ áâàãªâãà ¯® 2 dword' , |
§ ª 稢 î騩áï ã«ñ¬. ¥à¢ë© dword ¢ áâàãªâãॠï¥âáï |
㪠§ ⥫¥¬ ¨¬ï äãªæ¨¨, ¢â®à®© ᮤ¥à¦¨â ¤à¥á äãªæ¨¨. |
====================================================================== |
====== ãªæ¨ï 68, ¯®¤äãªæ¨ï 20 - ¯¥à¥à á¯à¥¤¥«¨âì ¡«®ª ¯ ¬ïâ¨. ===== |
====================================================================== |
à ¬¥âàë: |
* eax = 68 - ®¬¥à äãªæ¨¨ |
* ebx = 20 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ®¢ë© à §¬¥à ¢ ¡ ©â å |
* edx = 㪠§ ⥫ì 㦥 ¢ë¤¥«¥ë© ¡«®ª ¯ ¬ï⨠|
®§¢à é ¥¬®¥ § 票¥: |
* eax = 㪠§ â¥«ì ¯¥à¥à á¯à¥¤¥«ñë© ¡«®ª, 0 ¯à¨ ®è¨¡ª¥ |
¬¥ç ¨ï: |
* ।¢ à¨â¥«ì® á«¥¤ã¥â ¨¨æ¨ «¨§¨à®¢ âì ªãçã ¯à®æ¥áá ¢ë§®¢®¬ |
¯®¤äãªæ¨¨ 11. |
* ãªæ¨ï ¢ë¤¥«ï¥â 楫®¥ ç¨á«® áâà ¨æ (4 ¡) â ª, çâ® ä ªâ¨ç¥áª¨© |
à §¬¥à ¢ë¤¥«¥®£® ¡«®ª ¡®«ìè¥ ¨«¨ à ¢¥ § ¯à®è¥®¬ã. |
* ᫨ edx=0, â® ¢ë§®¢ äãªæ¨¨ íª¢¨¢ «¥â¥ ¢ë¤¥«¥¨î ¯ ¬ï⨠|
¯®¤äãªæ¨¥© 12. ¯à®â¨¢®¬ á«ãç ¥ ¡«®ª ¯ ¬ï⨠¯® ¤à¥áã edx |
¤®«¦¥ ¡ëâì à ¥¥ ¢ë¤¥«¥ ¯®¤äãªæ¨¥© 12 ¨«¨ |
®¯¨áë¢ ¥¬®© ¯®¤äãªæ¨¥©. |
* ᫨ ecx=0, â® äãªæ¨ï ®á¢®¡®¦¤ ¥â ¡«®ª ¯ ¬ï⨠¯® ¤à¥áã edx ¨ |
¢®§¢à é ¥â 0. |
* ®¤¥à¦¨¬®¥ ¯ ¬ï⨠¢¯«®âì ¤® ¨¬¥ì襣® ¨§ áâ ண® ¨ ®¢®£® |
à §¬¥à®¢ á®åà ï¥âáï. |
====================================================================== |
======================== ãªæ¨ï 69 - ®â« ¤ª . ======================= |
====================================================================== |
à®æ¥áá ¬®¦¥â § £à㧨âì ¤à㣮© ¯à®æ¥áá ª ª ®â« ¦¨¢ ¥¬ë© ãáâ ®¢ª®© |
ᮮ⢥âáâ¢ãî饣® ¡¨â ¯à¨ ¢ë§®¢¥ ¯®¤äãªæ¨¨ 7 äãªæ¨¨ 70. |
¯à®æ¥áá ¬®¦¥â ¡ëâì ⮫쪮 ®¤¨ ®â« ¤ç¨ª; ®¤¨ ¯à®æ¥áá ¬®¦¥â |
®â« ¦¨¢ âì ¥áª®«ìª® à §ëå. ¨á⥬ 㢥¤®¬«ï¥â ®â« ¤ç¨ª ® ᮡëâ¨ïå, |
¯à®¨á室ïé¨å á ®â« ¦¨¢ ¥¬ë¬ ¯à®æ¥áᮬ. ®®¡é¥¨ï § ¯¨áë¢ îâáï ¢ ¡ãä¥à, |
®¯à¥¤¥«ñë© ¯®¤äãªæ¨¥© 0. |
®à¬ â á®®¡é¥¨ï: |
* +0: dword: ª®¤ á®®¡é¥¨ï |
* +4: dword: PID ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* +8: ¬®£ãâ ¯à¨áãâá⢮¢ âì ¤®¯®«¨â¥«ìë¥ ¤ ë¥, |
®¯à¥¤¥«ï¥¬ë¥ ª®¤®¬ á®®¡é¥¨ï |
®¤ë á®®¡é¥¨©: |
* 1 = ¨áª«î票¥ |
* ¤®¯®«¨â¥«ì® ¯¥à¥¤ ñâáï dword-®¬¥à ¨áª«î票ï |
* ¯à®æ¥áá ¯à¨®áâ ®¢«¥ |
* 2 = ¯à®æ¥áá § ¢¥à訫áï |
* ¯à¨å®¤¨â ¯à¨ «î¡®¬ § ¢¥à襨¨: ª ª ç¥à¥§ á¨á⥬ãî äãªæ¨î -1, |
â ª ¨ ¯à¨ "㡨©á⢥" «î¡ë¬ ¤à㣨¬ ¯à®æ¥áᮬ |
(¢ ⮬ ç¨á«¥ á ¬¨¬ ®â« ¤ç¨ª®¬) |
* 3 = ®â« ¤®ç®¥ ¨áª«î票¥ int 1 = #DB |
* ¤®¯®«¨â¥«ì® ¯¥à¥¤ ñâáï dword-®¡à § ॣ¨áâà DR6: |
* ¡¨âë 0-3: ¢ë¯®«¥® ãá«®¢¨¥ ᮮ⢥âáâ¢ãî饩 â®çª¨ ®áâ ®¢ |
(ãáâ ®¢«¥®© ¯®¤äãªæ¨¥© 9) |
* ¡¨â 14: ¨áª«î票¥ ¯à®¨§®è«® ¨§-§ ०¨¬ |
¯®è £®¢®© âà áá¨à®¢ª¨ (ãáâ ®¢«¥ ä« £ TF) |
* ¯à®æ¥áá ¯à¨®áâ ®¢«¥ |
ਠ§ ¢¥à襨¨ ®â« ¤ç¨ª ¯à¨¡¨¢ îâáï ¢á¥ ®â« ¦¨¢ ¥¬ë¥ ¯à®æ¥ááë. |
᫨ ®â« ¤ç¨ª í⮣® ¥ å®ç¥â, ® ¤®«¦¥ ¯à¥¤¢ à¨â¥«ì® ®âª«îç¨âìáï |
¯®¤äãªæ¨¥© 3. |
ᥠ¯®¤äãªæ¨¨ ¯à¨¬¥¨¬ë ⮫쪮 ª ¯à®æ¥áá ¬/¯®â®ª ¬, § ¯ãé¥ë¬ |
¨§ ⥪ã饣® äãªæ¨¥© 70 á ãáâ ®¢«¥ë¬ ä« £®¬ ®â« ¤ª¨. |
â« ¤ª ¬®£®¯®â®çëå ¯à®£à ¬¬ ¯®ª ¥ ¯®¤¤¥à¦¨¢ ¥âáï. |
®«ë© ᯨ᮪ ¯®¤äãªæ¨©: |
* ¯®¤äãªæ¨ï 0 - ®¯à¥¤¥«¨âì ®¡« áâì ¤ ëå ¤«ï ®â« ¤®çëå á®®¡é¥¨© |
* ¯®¤äãªæ¨ï 1 - ¯®«ãç¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª |
* ¯®¤äãªæ¨ï 2 - ãáâ ®¢¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª |
* ¯®¤äãªæ¨ï 3 - ®âª«îç¨âìáï ®â ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* ¯®¤äãªæ¨ï 4 - ¯à¨®áâ ®¢¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª |
* ¯®¤äãªæ¨ï 5 - ¢®§®¡®¢¨âì ¢ë¯®«¥¨¥ ®â« ¦¨¢ ¥¬®£® ¯®â®ª |
* ¯®¤äãªæ¨ï 6 - ¯à®ç¨â âì ¨§ ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* ¯®¤äãªæ¨ï 7 - § ¯¨á âì ¢ ¯ ¬ïâì ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* ¯®¤äãªæ¨ï 8 - § ¢¥àè¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª |
* ¯®¤äãªæ¨ï 9 - ãáâ ®¢¨âì/áïâì ¯¯ à âãî â®çªã ®áâ ®¢ |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 0 ====================== |
========= ¯à¥¤¥«¨âì ®¡« áâì ¤ ëå ¤«ï ®â« ¤®çëå á®®¡é¥¨©. ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 0 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = 㪠§ ⥫ì |
®à¬ â ®¡« á⨠¤ ëå: |
* +0: dword: N = à §¬¥à ¡ãä¥à (¥ áç¨â ï í⮣® § £®«®¢ª ) |
* +4: dword: § ïâ® ¢ ¡ãä¥à¥ |
* +8: N*byte: ¡ãä¥à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ᫨ ¯®«¥ à §¬¥à ®âà¨æ ⥫ì®, ¡ãä¥à áç¨â ¥âáï § ¡«®ª¨à®¢ ë¬ |
¨ ¯à¨ ¯®áâ㯫¥¨¨ ®¢®£® á®®¡é¥¨ï á¨á⥬ ¡ã¤¥â ¦¤ âì. |
«ï á¨åந§ 樨 ®¡à ¬«ï©â¥ ¢áî à ¡®âã á ¡ãä¥à®¬ ®¯¥à æ¨ï¬¨ |
¡«®ª¨à®¢ª¨/à §¡«®ª¨à®¢ª¨ |
neg [bufsize] |
* ë¥ ¢ ¡ãä¥à¥ âà ªâãîâáï ª ª ¬ áᨢ í«¥¬¥â®¢ ¯¥à¥¬¥®© ¤«¨ë - |
á®®¡é¥¨©. ®à¬ â á®®¡é¥¨ï 㪠§ ¢ ®¡é¥¬ ®¯¨á ¨¨. |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 1 ====================== |
========= ®«ãç¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ========= |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯®â®ª |
* edx = ¤«¨ áâàãªâãàë ª®â¥ªáâ , ¤®«¦® ¡ëâì 0x28=40 ¡ ©â |
* esi = 㪠§ ⥫ì áâàãªâãàã ª®â¥ªáâ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â áâàãªâãàë ª®â¥ªáâ : (FPU ¯®ª ¥ ¯®¤¤¥à¦¨¢ ¥âáï) |
* +0: dword: eip |
* +4: dword: eflags |
* +8: dword: eax |
* +12 = +0xC: dword: ecx |
* +16 = +0x10: dword: edx |
* +20 = +0x14: dword: ebx |
* +24 = +0x18: dword: esp |
* +28 = +0x1C: dword: ebp |
* +32 = +0x20: dword: esi |
* +36 = +0x24: dword: edi |
¬¥ç ¨ï: |
* ᫨ ¯®â®ª ¢ë¯®«ï¥â ª®¤ 0-ª®«ìæ , ¢®§¢à é ¥âáï |
á®áâ®ï¨¥ ॣ¨áâ஢ 3-ª®«ìæ . |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 2 ====================== |
======== áâ ®¢¨âì á®áâ®ï¨¥ ॣ¨áâ஢ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ======== |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 2 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯®â®ª |
* edx = ¤«¨ áâàãªâãàë ª®â¥ªáâ , ¤®«¦® ¡ëâì 0x28=40 ¡ ©â |
* esi = 㪠§ ⥫ì áâàãªâãàã ª®â¥ªáâ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
®à¬ â áâàãªâãàë ª®â¥ªáâ 㪠§ ¢ ®¯¨á ¨¨ ¯®¤äãªæ¨¨ 1. |
¬¥ç ¨ï: |
* ᫨ ¯®â®ª ¢ë¯®«ï¥â ª®¤ 0-ª®«ìæ , ãáâ ¢«¨¢ ¥âáï |
á®áâ®ï¨¥ ॣ¨áâ஢ 3-ª®«ìæ . |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
== ãªæ¨ï 69, ¯®¤äãªæ¨ï 3 - ®âª«îç¨âìáï ®â ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . = |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 3 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* ᫨ ¯à®æ¥áá ¡ë« ¯à¨®áâ ®¢«¥, ® ¢®§®¡®¢«ï¥â ¢ë¯®«¥¨¥. |
====================================================================== |
==== ãªæ¨ï 69, ¯®¤äãªæ¨ï 4 - ¯à¨®áâ ®¢¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª. ==== |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à ¯à®æ¥áá |
* ebx = 4 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 5 ====================== |
============ ®§®¡®¢¨âì ¢ë¯®«¥¨¥ ®â« ¦¨¢ ¥¬®£® ¯®â®ª . ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 5 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 6 ====================== |
============= à®ç¨â âì ¨§ ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 6 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
* edx = ᪮«ìª® ¡ ©â ç¨â âì |
* esi = ¤à¥á ¯ ¬ï⨠®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá |
* edi = 㪠§ â¥«ì ¡ãä¥à ¤«ï ¤ ëå |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 ¯à¨ ®è¨¡ª¥ (¥¢¥àë© PID ¨«¨ ¡ãä¥à) |
* ¨ ç¥ eax = ç¨á«® ¯à®ç¨â ëå ¡ ©â (¢®§¬®¦®, 0, |
¥á«¨ ¢ esi ᫨誮¬ ¡®«ì讥 § 票¥) |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
ãªæ¨ï 69, ¯®¤äãªæ¨ï 7 - § ¯¨á âì ¢ ¯ ¬ïâì ®â« ¦¨¢ ¥¬®£® ¯à®æ¥áá . |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 7 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
* edx = ᪮«ìª® ¡ ©â ¯¨á âì |
* esi = ¤à¥á ¯ ¬ï⨠¢ ®â« ¦¨¢ ¥¬®¬ ¯à®æ¥áᥠ|
* edi = 㪠§ â¥«ì ¤ ë¥ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = -1 ¯à¨ ®è¨¡ª¥ (¥¢¥àë© PID ¨«¨ ¡ãä¥à) |
* ¨ ç¥ eax = ç¨á«® § ¯¨á ëå ¡ ©â (¢®§¬®¦®, 0, |
¥á«¨ ¢ esi ᫨誮¬ ¡®«ì讥 § 票¥) |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
====================================================================== |
====== ãªæ¨ï 69, ¯®¤äãªæ¨ï 8 - § ¢¥àè¨âì ®â« ¦¨¢ ¥¬ë© ¯®â®ª. ====== |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 8 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
* ãªæ¨ï «®£¨ç ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 18 á ¤¢ã¬ï ®â«¨ç¨ï¬¨: |
âॡã¥âáï ¢ë¯®«¥¨¥ ¯¥à¢®£® § ¬¥ç ¨ï ¨ ¯à¨¨¬ ¥âáï PID, |
¥ ®¬¥à á«®â . |
====================================================================== |
====================== ãªæ¨ï 69, ¯®¤äãªæ¨ï 9 ====================== |
============= áâ ®¢¨âì/áïâì ¯¯ à âãî â®çªã ®áâ ®¢ . ============ |
====================================================================== |
à ¬¥âàë: |
* eax = 69 - ®¬¥à äãªæ¨¨ |
* ebx = 9 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¨¤¥â¨ä¨ª â®à ¯®â®ª |
* dl = ¨¤¥ªá â®çª¨ ®áâ ®¢ , ®â 0 ¤® 3 ¢ª«îç¨â¥«ì® |
* dh = ä« £¨: |
* ¥á«¨ áâ à訩 ¡¨â á¡à®è¥ - ãáâ ®¢¨âì â®çªã ®áâ ®¢ : |
* ¡¨âë 0-1 - ãá«®¢¨¥: |
* 00 = â®çª ®áâ ®¢ ¢ë¯®«¥¨¥ |
* 01 = â®çª ®áâ ®¢ § ¯¨áì |
* 11 = â®çª ®áâ ®¢ ç⥨¥/§ ¯¨áì |
* ¡¨âë 2-3 - ¤«¨ ; ¤«ï â®ç¥ª ®áâ ®¢ ¨á¯®«¥¨¥ ¤®«¦® ¡ëâì |
00, ¢ ¯à®â¨¢®¬ á«ãç ¥ ®¤® ¨§ |
* 00 = ¡ ©â |
* 01 = á«®¢® |
* 11 = ¤¢®©®¥ á«®¢® |
* esi = ¤à¥á â®çª¨ ®áâ ®¢ ; ¤®«¦¥ ¡ëâì ¢ë஢¥ |
ᮮ⢥âá⢥® ¤«¨¥ (â.¥. ¤®«¦¥ ¡ëâì çñâë¬ ¤«ï |
â®ç¥ª ®áâ ®¢ á«®¢®, ªà ⥠4 ¤«ï ¤¢®©®£® á«®¢ ) |
* ¥á«¨ áâ à訩 ¡¨â ãáâ ®¢«¥ - á¡à®á¨âì â®çªã ®áâ ®¢ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãá¯¥è® |
* eax = 1 - ®è¨¡ª ¢® ¢å®¤ëå ¤ ëå |
* eax = 2 - (§ १¥à¢¨à®¢ ®, ¨ª®£¤ ¥ ¢®§¢à é ¥âáï |
¢ ⥪ã饩 ॠ«¨§ 樨) á í⨬ ¨¤¥ªá®¬ 㦥 ãáâ ®¢«¥ |
£«®¡ «ì ï â®çª ®áâ ®¢ |
¬¥ç ¨ï: |
* à®æ¥áá ¤®«¦¥ ¡ëâì § £à㦥 ¤«ï ®â« ¤ª¨ (ª ª 㪠§ ® ¢ |
®¡é¥¬ ®¯¨á ¨¨). |
* ¯¯ à âë¥ â®çª¨ ®áâ ®¢ ॠ«¨§ãîâáï ç¥à¥§ DRx-ॣ¨áâàë |
¯à®æ¥áá®à , ®âáî¤ ¢á¥ ®£à ¨ç¥¨ï. |
* ãªæ¨ï ¬®¦¥â ¯¥à¥ãáâ ®¢¨âì à ¥¥ ãáâ ®¢«¥ãî ¥© ¦¥ |
â®çªã ®áâ ®¢ (¨ª ª ¥ á®®¡é ï ®¡ í⮬). |
¥¤¨â¥ ᯨ᮪ ãáâ ®¢«¥ëå â®ç¥ª ®áâ ®¢ ¢ ®â« ¤ç¨ª¥. |
* à ¡ âë¢ ¨¥ â®çª¨ ®áâ ®¢ § ª«îç ¥âáï ¢ £¥¥à¨à®¢ ¨¨ |
®â« ¤®ç®£® ¨áª«î票ï #DB, ® ª®â®à®¬ á¨á⥬ á®®¡é ¥â ®â« ¤ç¨ªã. |
* ®çª ®áâ ®¢ § ¯¨áì ¨ ç⥨¥/§ ¯¨áì áà ¡ âë¢ ¥â ¯®á«¥ |
¢ë¯®«¥¨ï ¢ë§¢ ¢è¥© ¥ñ ¨áâàãªæ¨¨. |
====================================================================== |
= ãªæ¨ï 70 - à ¡®â á ä ©«®¢®© á¨á⥬®© á ¯®¤¤¥à¦ª®© ¤«¨ëå ¨¬ñ. = |
====================================================================== |
à ¬¥âàë: |
* eax = 70 |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®; ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ¢ § ¢¨á¨¬®á⨠®â ¯®¤äãªæ¨¨ ¬®¦¥â ¢®§¢à é âìáï § 票¥ ¨ |
¢ ¤à㣨å ॣ¨áâà å |
¡é¨© ä®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: ᬥ饨¥ ¢ ä ©«¥ |
* +8: dword: áâ à訩 dword ᬥ饨ï (¤®«¦¥ ¡ëâì 0) ¨«¨ ¯®«¥ ä« £®¢ |
* +12 = +0xC: dword: à §¬¥à |
* +16 = +0x10: dword: 㪠§ â¥«ì ¤ ë¥ |
* +20 = +0x14: n db: ASCIIZ-áâப á ¨¬¥¥¬ ä ©« |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ä ©« |
â®ç¥¨ï - ¢ ¤®ªã¬¥â 樨 ᮮ⢥âáâ¢ãîéãî ¯®¤äãªæ¨î. |
¬ï ä ©« ¥çã¢áâ¢¨â¥«ì® ª ॣ¨áâà㠡㪢. ãá᪨¥ ¡ãª¢ë ¤®«¦ë ¡ëâì |
§ ¯¨á ë ¢ ª®¤¨à®¢ª¥ cp866 (DOS). |
®à¬ â ¨¬¥¨ ä ©« : |
/base/number/dir1/dir2/.../dirn/file, |
£¤¥ /base/number ¨¤¥â¨ä¨æ¨àã¥â ãáâனá⢮, ª®â®à®¬ ¨é¥âáï ä ©«: |
®¤® ¨§ |
* /RD/1 = /RAMDISK/1 ¤«ï ¤®áâ㯠ª à ¬¤¨áªã |
* /FD/1 = /FLOPPYDISK/1 ¤«ï ¤®áâ㯠ª ¯¥à¢®¬ã ä«®¯¯¨-¤¨áª®¢®¤ã, |
/FD/2 = /FLOPPYDISK/2 ¤«ï ¢â®à®£® ä«®¯¯¨-¤¨áª®¢®¤ |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x ¤«ï ¤®áâ㯠ᮮ⢥âá⢥® |
ª ¦ñá⪨¬ ¤¨áª ¬ IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - ®¬¥à à §¤¥« ¢ë¡à ®¬ ¢¨ç¥áâ¥à¥, ¨§¬¥ï¥âáï ®â 1 ¤® 255 |
( ª ¦¤®¬ ¨§ ¢¨ç¥áâ¥à®¢ 㬥à æ¨ï ç¨ ¥âáï á 1) |
* /CD0/1, /CD1/1, /CD2/1, /CD3/1 ¤«ï ¤®áâ㯠ᮮ⢥âá⢥® |
ª CD IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave) |
ਬ¥àë: |
* '/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 - 㤠«¥¨¥ ä ©« /¯ ¯ª¨ |
* ¯®¤äãªæ¨ï 9 - ᮧ¤ ¨¥ ¯ ¯ª¨ |
«ï 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, "¤®áâ㯠§ ¯à¥éñ"). |
====================================================================== |
============= ãªæ¨ï 70, ¯®¤äãªæ¨ï 9 - ᮧ¤ ¨¥ ¯ ¯ª¨. ============= |
====================================================================== |
à ¬¥âàë: |
* eax = 70 - ®¬¥à äãªæ¨¨ |
* ebx = 㪠§ â¥«ì ¨ä®à¬ 樮ãî áâàãªâãàã |
®à¬ â ¨ä®à¬ 樮®© áâàãªâãàë: |
* +0: dword: 9 = ®¬¥à ¯®¤äãªæ¨¨ |
* +4: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +8: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +12 = +0xC: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +16 = +0x10: dword: 0 (§ १¥à¢¨à®¢ ®) |
* +20 = +0x14: ASCIIZ-¨¬ï ¯ ¯ª¨, ¯à ¢¨« ä®à¬¨à®¢ ¨ï ¨¬ñ 㪠§ ë ¢ |
®¡é¥¬ ®¯¨á ¨¨ |
¨«¨ |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd 㪠§ ⥫ì ASCIIZ-áâபã á ¨¬¥¥¬ ¯ ¯ª¨ |
®§¢à é ¥¬®¥ § 票¥: |
* eax = 0 - ãᯥè®, ¨ ç¥ ª®¤ ®è¨¡ª¨ ä ©«®¢®© á¨á⥬ë |
* ebx à §àãè ¥âáï |
¬¥ç ¨ï: |
* ãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï CD (¢¥àñâáï ª®¤ ®è¨¡ª¨ 2). |
* ®¤¨â¥«ìáª ï ¯ ¯ª ¤®«¦ 㦥 áãé¥á⢮¢ âì. |
* ᫨ ¯ ¯ª 㦥 áãé¥áâ¢ã¥â, äãªæ¨ï § ¢¥àè¨âáï ãá¯¥è® (eax=0). |
====================================================================== |
=== ãªæ¨ï 71, ¯®¤äãªæ¨ï 1 - ãáâ ®¢¨âì § £®«®¢®ª ®ª ¯à®£à ¬¬ë. == |
====================================================================== |
à ¬¥âàë: |
* eax = 71 - ®¬¥à äãªæ¨¨ |
* ebx = 1 - ®¬¥à ¯®¤äãªæ¨¨ |
* ecx = ¤à¥á áâப¨ § £®«®¢ª |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â § 票ï |
¬¥ç ¨ï: |
* âப § £®«®¢ª ¤®«¦ ¡ëâì ¢ ä®à¬ ⥠ASCIIZ. § £®«®¢ª¥ |
®â®¡à ¦ ¥âáï ¥ ¡®«¥¥ 255 ᨬ¢®«®¢ ¥§ ¢¨á¨¬® ®â ¯®«®© ¤«¨ë |
áâப¨. |
* ⮡ë ã¡à âì § £®«®¢®ª, ¯¥à¥¤ ©â¥ NULL ¢ ecx. |
====================================================================== |
========== ãªæ¨ï -1 - § ¢¥àè¨âì ¢ë¯®«¥¨¥ ¯®â®ª /¯à®æ¥áá ========= |
====================================================================== |
à ¬¥âàë: |
* eax = -1 - ®¬¥à äãªæ¨¨ |
®§¢à é ¥¬®¥ § 票¥: |
* äãªæ¨ï ¥ ¢®§¢à é ¥â ¨ § 票ï, ¨ ã¯à ¢«¥¨ï |
¬¥ç ¨ï: |
* ᫨ ¯à®æ¥áá  ¥ ᮧ¤ ¢ « ¯®â®ª®¢, â® ã ¥£® ¥áâì ⮫쪮 |
®¤¨ ¯®â®ª, § ¢¥à襨¥ ª®â®à®£® ¯à¨¢®¤¨â ª § ¢¥àè¥¨î ¯à®æ¥áá . |
* ᫨ ⥪ã騩 ¯®â®ª - ¯®á«¥¤¨© ¢ ¯à®æ¥áá¥, â® ¥£® § ¢¥à襨¥ |
â ª¦¥ ¯à¨¢®¤¨â ª § ¢¥àè¥¨î ¯à®æ¥áá . |
* â äãªæ¨ï § ¢¥àè ¥â ⥪ã騩 ¯®â®ª. à㣮© ¯®â®ª ¬®¦® ¯à¨¡¨âì |
¢ë§®¢®¬ ¯®¤äãªæ¨¨ 2 äãªæ¨¨ 18. |
====================================================================== |
=========================== ¯¨á®ª ᮡë⨩ =========================== |
====================================================================== |
ç¥à¥¤®¥ ᮡë⨥ ¬®¦® ¯®«ãç¨âì ¢ë§®¢®¬ ®¤®© ¨§ äãªæ¨© 10 |
(®¦¨¤ âì ᮡëâ¨ï), 11 (¯à®¢¥à¨âì ¡¥§ ®¦¨¤ ¨ï), 23 |
(®¦¨¤ âì ¢ â¥ç¥¨¥ § ¤ ®£® ¢à¥¬¥¨). |
⨠äãªæ¨¨ ¢®§¢à é îâ ⮫쪮 ⥠ᮡëâ¨ï, ª®â®àë¥ ¢å®¤ïâ ¢ ¬ áªã, |
ãáâ ¢«¨¢ ¥¬ãî äãªæ¨¥© 40. ® 㬮«ç ¨î íâ® ¯¥à¢ë¥ âà¨, 祣® |
¢¯®«¥ ¤®áâ â®ç® ¤«ï ¬®£¨å ¯à¨«®¦¥¨©. |
®¤ë ᮡë⨩: |
* 1 = á®®¡é¥¨¥ ® ¯¥à¥à¨á®¢ª¥ (á¡à áë¢ ¥âáï ¯à¨ ¢ë§®¢¥ äãªæ¨¨ 0) |
* 2 = ¦ â ª« ¢¨è ª« ¢¨ âãॠ(¯®áâ㯠¥â, ⮫쪮 ª®£¤ ®ª® |
ªâ¨¢®) ¨«¨ ¦ â "£®àïç ï ª« ¢¨è "; |
á¡à áë¢ ¥âáï, ª®£¤ ¢á¥ ª« ¢¨è¨ ¨§ ¡ãä¥à áç¨â ë äãªæ¨¥© 2 |
* 3 = ¦ â ª®¯ª , ®¯à¥¤¥«ñ ï à ¥¥ äãªæ¨¥© 8 (¨«¨ ª®¯ª |
§ ªàëâ¨ï, ᮧ¤ ï ¥ï¢® äãªæ¨¥© 0; ª®¯ª ¬¨¨¬¨§ 樨 |
®¡à ¡ âë¢ ¥âáï á¨á⥬®© ¨ ® ¥© á®®¡é¥¨ï ¥ ¯à¨å®¤¨â; |
¯®áâ㯠¥â, ⮫쪮 ª®£¤ ®ª® ªâ¨¢®; á¡à áë¢ ¥âáï, ª®£¤ ¢á¥ |
ª®¯ª¨ ¨§ ¡ãä¥à áç¨â ë äãªæ¨¥© 17) |
* 4 = § १¥à¢¨à®¢ ® (¢ ⥪ã饩 ॠ«¨§ 樨 ¨ª®£¤ ¥ ¯à¨å®¤¨â ¤ ¦¥ |
¯à¨ à §¬ ᪨஢ª¥ äãªæ¨¥© 40) |
* 5 = ¯¥à¥à¨á®¢ë¢ ¥âáï ä® à ¡®ç¥£® á⮫ (á¡à áë¢ ¥âáï |
¢â®¬ â¨ç¥áª¨ ¯®á«¥ ¯¥à¥à¨á®¢ª¨, â ª çâ® ¥á«¨ ¢® ¢à¥¬ï ¯¥à¥à¨á®¢ª¨ |
ä® ¯à®£à ¬¬ ¥ ¦¤ñâ ¨ ¥ ¯à®¢¥àï¥â ᮡëâ¨ï, â® í⮣® ᮡëâ¨ï |
® ¥ § ¬¥â¨â) |
* 6 = ᮡë⨥ ®â ¬ëè¨ (çâ®-â® á«ã稫®áì - ¦ ⨥ ª®¯ªã ¬ëè¨ |
¨«¨ ¯¥à¥¬¥é¥¨¥; á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨) |
* 7 = ¯à®¨§®è«® ᮡë⨥ IPC (ᬮâਠäãªæ¨î 60 - Inter Process |
Communication; á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨) |
* 8 = ¯à®¨§®è«® á¥â¥¢®¥ ᮡë⨥ (á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨; |
ᬮâà¨ à ¡®âã á á¥âìî) |
* 9 = ¯à®¨§®è«® ®â« ¤®ç®¥ ᮡë⨥ (á¡à áë¢ ¥âáï ¯à¨ ¯à®ç⥨¨; |
ᬮâਠ®â« ¤®çãî ¯®¤á¨á⥬ã) |
* 16..31 = ¯à®¨§®è«® ᮡë⨥ á ᮮ⢥âáâ¢ãî騬 IRQ |
(16=IRQ0, 31=IRQ15) (á¡à áë¢ ¥âáï ¯à¨ áç¨âë¢ ¨¨ ¢á¥å ¤ ëå IRQ) |
====================================================================== |
==================== ®¤ë ®è¨¡®ª ä ©«®¢®© á¨á⥬ë ==================== |
====================================================================== |
* 0 = ãá¯¥è® |
* 1 = ¥ ®¯à¥¤¥«¥ ¡ § ¨/¨«¨ à §¤¥« ¦ñá⪮£® ¤¨áª (¯®¤äãªæ¨ï¬¨ |
7, 8 äãªæ¨¨ 21) |
* 2 = äãªæ¨ï ¥ ¯®¤¤¥à¦¨¢ ¥âáï ¤«ï ¤ ®© ä ©«®¢®© á¨á⥬ë |
* 3 = ¥¨§¢¥áâ ï ä ©«®¢ ï á¨á⥬ |
* 4 = § १¥à¢¨à®¢ ®, ¨ª®£¤ ¥ ¢®§¢à é ¥âáï ¢ ⥪ã饩 ॠ«¨§ 樨 |
* 5 = ä ©« ¥ ©¤¥ |
* 6 = ä ©« § ª®ç¨«áï |
* 7 = 㪠§ â¥«ì ¢¥ ¯ ¬ï⨠¯à¨«®¦¥¨ï |
* 8 = ¤¨áª § ¯®«¥ |
* 9 = â ¡«¨æ FAT à §àãè¥ |
* 10 = ¤®áâ㯠§ ¯à¥éñ |
* 11 = ®è¨¡ª ãáâனá⢠|
ਠ§ ¯ã᪥ ¯à®£à ¬¬ë ¢®§¬®¦ë â ª¦¥ á«¥¤ãî騥 ª®¤ë ®è¨¡®ª: |
* 30 = 0x1E = ¥¤®áâ â®ç® ¯ ¬ï⨠|
* 31 = 0x1F = ä ©« ¥ ï¥âáï ¨á¯®«¨¬ë¬ |
* 32 = 0x20 = ᫨誮¬ ¬®£® ¯à®æ¥áᮢ |
/kernel/tags/kolibri0.7.0.0/docs/sysfuncs.txt |
---|
0,0 → 1,4484 |
SYSTEM FUNCTIONS of OS Kolibri 0.6.5.0 |
Number of the function is located in the register eax. |
The call of the system function is executed by "int 0x40" command. |
All registers except explicitly declared in the returned value, |
including eflags, are preserved. |
====================================================================== |
============== Function 0 - define and draw the window. ============== |
====================================================================== |
Defines an application window. Draws a frame of the window, header and |
working area. For skinned windows defines standard close and minimize |
buttons. |
Parameters: |
* eax = 0 - function number |
* ebx = [coordinate on axis x]*65536 + [size on axis x] |
* ecx = [coordinate on axis y]*65536 + [size on axis y] |
* edx = 0xXYRRGGBB, where: |
* Y = style of the window: |
* Y=0 - type I - fixed-size window |
* Y=1 - only define window area, draw nothing |
* Y=2 - type II - variable-size window |
* Y=3 - skinned window |
* 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 = 1 - don't fill working area on window draw |
* D = 0 - normal filling of the working area, 1 - gradient |
The following parameters are intended for windows |
of a type I and II, and ignored for styles Y=1,3: |
* esi = 0xXYRRGGBB - color of the header |
* RR, GG, BB define color |
* Y=0 - usual window, Y=1 - unmovable window |
* X defines a gradient of header: X=0 - no gradient, |
X=8 - usual gradient, |
for windows of a type II X=4 - negative gradient |
* other values of X and Y are reserved |
* edi = 0x00RRGGBB - color of the frame |
Returned value: |
* function does not return value |
Remarks: |
* Position and sizes of the window are installed by the first |
call of this function and are ignored at subsequent; to change |
position and/or sizes of already created window use function 67. |
* For windows with 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: |
* Before calling subfunctions 2 and 5 you should call this function |
to set image size! |
* For update of the screen (after completion of a series of commands |
working with a background) call subfunction 3. |
* There is a pair function for get size of the background image - |
subfunction 1 of function 39. |
====================================================================== |
=== Function 15, subfunction 2 - put pixel on the background image. == |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 2 - subfunction number |
* ecx = offset |
* edx = color of a pixel 0xRRGGBB |
Returned value: |
* function does not return value |
Remarks: |
* Offset for a pixel with coordinates (x,y) is calculated as |
(x+y*xsize)*3. |
* If the given offset exceeds size set by subfunction 1, |
the call is ignored. |
* For update of the screen (after completion of a series of commands |
working with a background) call subfunction 3. |
* There is a pair function for get pixel on the background image - |
subfunction 2 of function 39. |
====================================================================== |
=========== Function 15, subfunction 3 - redraw background. ========== |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 3 - subfunction number |
Returned value: |
* function does not return value |
====================================================================== |
== Function 15, subfunction 4 - set drawing mode for the background. = |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 4 - subfunction number |
* ecx = drawing mode: |
* 1 = tile |
* 2 = stretch |
Returned value: |
* function does not return value |
Remarks: |
* For update of the screen (after completion of a series of commands |
working with a background) call subfunction 3. |
* There is a pair function for get drawing mode of the background - |
subfunction 4 of function 39. |
====================================================================== |
===================== Function 15, subfunction 5 ===================== |
============ Put block of pixels on the background image. ============ |
====================================================================== |
Parameters: |
* eax = 15 - function number |
* ebx = 5 - subfunction number |
* ecx = pointer to the data in the format BBGGRRBBGGRR... |
* edx = offset in data of the background image |
* esi = size of data in bytes = 3 * number of pixels |
Returned value: |
* function does not return value |
Remarks: |
* Offset and size are not checked for correctness. |
* Color of each pixel is stored as 3-bytes value BBGGRR. |
* Pixels of the background image are written sequentially |
from left to right, from up to down. |
* Offset of pixel with coordinates (x,y) is (x+y*xsize)*3. |
* For update of the screen (after completion of a series of commands |
working with a background) call subfunction 3. |
====================================================================== |
=============== Function 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 = pointer to the full path to file |
(for example, "/hd0/1/kolibri/kolibri.img") |
Returned value: |
* eax = 0 - success |
* else eax = error code of the file system |
Remarks: |
* All folders in the given path must exist, otherwise function |
returns value 5, "file not found". |
====================================================================== |
=========== Function 18, subfunction 7 - get active window. ========== |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 7 - subfunction number |
Returned value: |
* eax = number of the active window |
(number of the slot of the thread with active window) |
Remarks: |
* Active window is at the top of the window stack and receives |
messages on all keyboard input. |
* To make a window active, use subfunction 3. |
====================================================================== |
== Function 18, subfunction 8 - disable/enable the internal speaker. = |
====================================================================== |
If speaker sound is disabled, all calls to subfunction 55 of |
function 55 are ignored. If speaker sound is enabled, |
they are routed on builtin speaker. |
------------------- Subsubfunction 1 - get status. ------------------- |
Parameters: |
* eax = 18 - function number |
* ebx = 8 - subfunction number |
* ecx = 1 - number of the subsubfunction |
Returned value: |
* eax = 0 - speaker sound is enabled; 1 - disabled |
----------------- Subsubfunction 2 - toggle status. ------------------ |
Toggles states of disable/enable. |
Parameters: |
* eax = 18 - function number |
* ebx = 8 - subfunction number |
* ecx = 2 - number of the subsubfunction |
Returned value: |
* function does not return value |
====================================================================== |
== Function 18, subfunction 9 - system shutdown with the parameter. == |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 9 - subfunction number |
* ecx = parameter: |
* 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, FAT32 and NTFS for hard disks. |
* +6: 4 db: reserved |
Format of the table: full version: |
* +0: 10 db: same as for the short version |
* +10: 100 db: data for the first partition |
* +110: 100 db: data for the second partition |
* ... |
* +10+100*(n-1): 100 db: data for the last partition |
The partitions are located as follows: at first sequentially all |
recoginzed partitions on HD on IDE0 (if present), |
then on HD on IDE1 (if present) and so on up to IDE3. |
Format of the information about partition |
(at moment only FAT is supported): |
* +0: dword: first physical sector of the partition |
* +4: dword: last physical sector of the partition |
(belongs to the partition) |
* +8: byte: file system type: |
16=FAT16, 32=FAT32, 1=NTFS |
* other data are dependent on file system, are modified with |
kernel modifications and therefore are not described |
Remarks: |
* The short table can be used for obtaining the information about |
available devices. |
====================================================================== |
========== Function 18, subfunction 13 - get kernel version. ========= |
====================================================================== |
Parameters: |
* eax = 18 - function number |
* ebx = 13 - subfunction number |
* ecx = pointer to the buffer (not less than 16 bytes), where |
the information will be placed |
Returned value: |
* function does not return value |
Structure of the buffer: |
db a,b,c,d for version a.b.c.d |
db UID_xxx: one of UID_NONE=0, UID_MENUET=1, UID_KOLIBRI=2 |
db 'name',0 - ASCIIZ-string with the name |
For Kolibri 0.6.5.0 kernel: |
db 0,6,5,0 |
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 7 - set HD base. ============= |
====================================================================== |
The HD base defines hard disk to write with usage of obsolete |
syntax /HD in obsolete function 58; at usage of modern syntax |
/HD0,/HD1,/HD2,/HD3 base is set automatically. |
Parameters: |
* eax = 21 - function number |
* ebx = 7 - subfunction number |
* ecx = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Returned value: |
* eax = 0 |
Remarks: |
* Any application at any time can change the base. |
* Do not change base, when any application works with hard disk. |
If you do not want system bugs. |
* To get HD base use subfunction 7 of function 26. |
* It is also necessary to define used partition of hard disk by |
subfunction 8. |
====================================================================== |
========= Function 21, subfunction 8 - set used HD partition. ======== |
====================================================================== |
The HD partition defines partition of the hard disk to write with |
usage of obsolete syntax /HD and obsolete function 58; |
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 |
base and partition are set automatically. |
Parameters: |
* eax = 21 - function number |
* ebx = 8 - subfunction number |
* ecx = HD partition (beginning from 1) |
Return value: |
* eax = 0 |
Remarks: |
* Any application at any time can change partition. |
* Do not change partition when any application works with hard disk. |
If you do not want system bugs. |
* To get used partition use subfunction 8 of function 26. |
* There is no correctness checks. |
* To get the number of partitions of a hard disk use |
subfunction 11 of function 18. |
* It is also necessary to define used HD base by subfunction 7. |
====================================================================== |
======== Function 21, subfunction 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 |
Remarks: |
* 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 7 - get HD base. ============= |
====================================================================== |
The HD base defines hard disk to write with usage of obsolete |
syntax /HD in obsolete function 58; at usage of modern syntax |
/HD0,/HD1,/HD2,/HD3 base is set automatically. |
Parameters: |
* eax = 26 - function number |
* ebx = 7 - subfunction number |
Returned value: |
* eax = HD base: 1=IDE0, 2=IDE1, 3=IDE2, 4=IDE3 |
Remarks: |
* Any application in any time can change HD base. |
* To set base use subfunction 7 of function 21. |
* To get used partition of hard disk use subfunction 8. |
====================================================================== |
========= Function 26, subfunction 8 - get used HD partition. ======== |
====================================================================== |
The HD partition defines partition of the hard disk to write with |
usage of obsolete syntax /HD in obsolete function 58; |
at usage of functions 58 and 70 and modern syntax /HD0,/HD1,/HD2,/HD3 |
base and partition are set automatically. |
Parameters: |
* eax = 26 - function number |
* ebx = 8 - subfunction number |
Returned value: |
* eax = HD partition (beginning from 1) |
Remarks: |
* Any application in any time can change partition. |
* To set partition use subfunction 8 of function 21. |
* To get number of partitions on a hard disk use |
subfunction 11 of function 18. |
* To get base of used hard disk, use subfunction 7. |
====================================================================== |
=== Function 26, subfunction 9 - get the value of the time counter. == |
====================================================================== |
Parameters: |
* eax = 26 - function number |
* ebx = 9 - subfunction number |
Returned value: |
* eax = number of 1/100s of second, past from the system boot time |
Remarks: |
* Counter takes modulo 2^32, that correspond to a little more |
than 497 days. |
* To get system time use function 3. |
====================================================================== |
======== Function 26, subfunction 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 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 30 - work with the current folder. ============ |
====================================================================== |
--------- Subfunction 1 - set current folder for the thread. --------- |
Parameters: |
* eax = 30 - function number |
* ebx = 1 - subfunction number |
* ecx = pointer to ASCIIZ-string with the path to new current folder |
Returned value: |
* function does not return value |
--------- Subfunction 2 - get current folder for the thread. --------- |
Parameters: |
* eax = 30 - function number |
* ebx = 2 - subfunction number |
* ecx = pointer to buffer |
* edx = size of buffer |
Returned value: |
* eax = size of the current folder's name (including terminating 0) |
Remarks: |
* If the buffer is too small to hold all data, only first (edx-1) |
bytes are copied and than terminating 0 is inserted. |
====================================================================== |
=============== Function 32 - delete file from ramdisk. ============== |
====================================================================== |
Parameters: |
* eax = 32 - function number |
* ebx = pointer to the filename |
Returned value: |
* eax = 0 - success; otherwise file system error code |
Remarks: |
* This function is obsolete; function 58 allows to fulfill |
the same operations with the extended possibilities. |
* The current implementation returns only values 0(success) and |
5(file not found). |
* The filename must be either in the format 8+3 characters |
(first 8 characters - name itself, last 3 - extension, |
the short names and extensions are supplemented with spaces), |
or in the format 8.3 characters "FILE.EXT"/"FILE.EX " |
(name no more than 8 characters, dot, extension 3 characters |
supplemented if necessary by spaces). |
The filename must be written with capital letters. The terminating |
character with code 0 is not necessary (not ASCIIZ-string). |
* This function does not support folders on the ramdisk. |
====================================================================== |
================ Function 33 - write file to ramdisk. ================ |
====================================================================== |
Parameters: |
* eax = 33 - function number |
* ebx = pointer to the filename |
* ecx = pointer to data for writing |
* edx = number of bytes for writing |
* should be set esi=0 |
Returned value: |
* eax = 0 - success, otherwise file system error code |
Remarks: |
* This function is obsolete; function 70 allows to fulfil |
the same operations with extended possibilities. |
* If esi contains non-zero value and selected file already exists, |
one more file with the same name will be created. |
* Otherwise file will be overwritten. |
* The filename must be either in the format 8+3 characters |
(first 8 characters - name itself, last 3 - extension, |
the short names and extensions are supplemented with spaces), |
or in the format 8.3 characters "FILE.EXT"/"FILE.EX " |
(name no more than 8 characters, dot, extension 3 characters |
supplemented if necessary by spaces). |
The filename must be written with capital letters. The terminating |
character with code 0 is not necessary (not ASCIIZ-string). |
* This function does not support folders on the ramdisk. |
====================================================================== |
======= Function 35 - read the color of a pixel on the screen. ======= |
====================================================================== |
Parameters: |
* eax = 35 |
* ebx = y*xsize+x, where |
* (x,y) = coordinates of a pixel (beginning from 0) |
* xsize = horizontal screen size |
Returned value: |
* eax = color 0x00RRGGBB |
Remarks: |
* To get screen sizes use function 14. Pay attention, |
that it subtracts 1 from both sizes. |
* There is also direct access (without any system calls) |
to videomemory through the selector gs. To get parameters of |
the current videomode, use function 61. |
====================================================================== |
=================== Function 37 - work with mouse. =================== |
====================================================================== |
---------- Subfunction 0 - screen coordinates of the mouse ----------- |
Parameters: |
* eax = 37 - function number |
* ebx = 0 - subfunction number |
Returned value: |
* eax = x*65536 + y, (x,y)=coordinates of the mouse pointer |
(beginning from 0) |
-- Subfunction 1 - coordinates of the mouse relative to the window --- |
Parameters: |
* eax = 37 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = x*65536 + y, (x,y)=coordinates of the mouse pointer |
relative to the application window (beginning from 0) |
Remarks: |
* The value is calculated by formula (x-xwnd)*65536 + (y-ywnd). |
If y>=ywnd, the low word is non-negative and contains |
relative y-coordinate, and the high word - relative x-coordinate |
(with correct sign). Otherwise the low word is negative and still |
contains relative y-coordinate, and to the high word |
1 should be added. |
------------ Subfunction 2 - pressed buttons of the mouse ------------ |
Parameters: |
* eax = 37 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* eax contains information on the pressed mouse buttons: |
* bit 0 is set = left button is pressed |
* bit 1 is set = right button is pressed |
* bit 2 is set = middle button is pressed |
* bit 3 is set = 4th button is pressed |
* bit 4 is set = 5th button is pressed |
* other bits are cleared |
-------------------- Subfunction 4 - load cursor --------------------- |
Parameters: |
* eax = 37 - function number |
* ebx = 4 - subfunction number |
* dx = data source: |
* dx = LOAD_FROM_FILE = 0 - data in a file |
* ecx = pointer to full path to the cursor file |
* the file must be in the format .cur, which is standard for |
MS Windows, at that of the size 32*32 pixels |
* dx = LOAD_FROM_MEM = 1 - data of file are already loaded in memory |
* ecx = pointer to data of the cursor file |
* the data format is the same as in the previous case |
* dx = LOAD_INDIRECT = 2 - data in memory |
* ecx = pointer to cursor image in the format ARGB 32*32 pixels |
* edx = 0xXXYY0002, where |
* XX = x-coordinate of cursor hotspot |
* YY = y-coordinate |
* 0 <= XX, YY <= 31 |
Returned value: |
* eax = 0 - failed |
* otherwise eax = cursor handle |
--------------------- Subfunction 5 - set cursor --------------------- |
Sets new cursor for the window of the current thread. |
Parameters: |
* eax = 37 - function number |
* ebx = 5 - subfunction number |
* ecx = cursor handle |
Returned value: |
* eax = handle of previous cursor |
Remarks: |
* If the handle is incorrect, the function restores the default |
cursor (standard arrow). In particular, ecx=0 restores it. |
------------------- Subfunction 6 - delete cursor -------------------- |
Parameters: |
* eax = 37 - function number |
* ebx = 6 - subfunction number |
* ecx = cursor handle |
Returned value: |
* eax destroyed |
Remarks: |
* The cursor must be loaded previously by the current thread |
(with the call to subfunction 4). The function does not delete |
system cursors and cursors, loaded by another applications. |
* If the active cursor (set by subfunction 5) is deleted, |
the system restores the default cursor (standard arrow). |
------------------ Subfunction 7 - get scroll data ------------------- |
Parameters: |
* eax = 37 - function number |
* ebx = 7 - subfunction number |
Returned value: |
* eax = [horizontal offset]*65536 + [vertical offset] |
Remarks: |
* Scroll data is available for active window only. |
* Values are zeroed after reading. |
* Values are signed. |
====================================================================== |
====================== Function 38 - draw line. ====================== |
====================================================================== |
Parameters: |
* eax = 38 - function number |
* ebx = [start coordinate on axis x]*65536 + |
[end coordinate on axis x] |
* ecx = [start coordinate on axis y]*65536 + |
[end coordinate on axis y] |
* edx = 0x00RRGGBB - color |
edx = 0x01xxxxxx - draw inversed line |
(low 24 bits are ignored) |
Returned value: |
* function does not return value |
Remarks: |
* Coordinates are relative to the window. |
* End point is also drawn. |
====================================================================== |
== Function 39, subfunction 1 - get a size of the background image. == |
====================================================================== |
Parameters: |
* eax = 39 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = [width]*65536 + [height] |
Remarks: |
* There is a pair function to set sizes of background image - |
subfunction 1 of function 15. After which it is necessary, |
of course, anew to define image. |
====================================================================== |
== Function 39, subfunction 2 - get pixel from the background image. = |
====================================================================== |
Parameters: |
* eax = 39 - function number |
* ebx = 2 - subfunction number |
* ecx = offset |
Returned value: |
* eax = 0x00RRGGBB - pixel color, if offset is valid |
(less than 0x160000-16) |
* eax = 2 otherwise |
Remarks: |
* Do not rely on returned value for invalid offsets, it may be |
changed in future kernel versions. |
* Offset for pixel with coordinates (x,y) |
is calculated as (x+y*xsize)*3. |
* There is a pair function to set pixel on the background image - |
subfunction 2 of function 15. |
====================================================================== |
== Function 39, subfunction 4 - get drawing mode for the background. = |
====================================================================== |
Parameters: |
* eax = 39 - function number |
* ebx = 4 - subfunction number |
Returned value: |
* eax = 1 - tile |
* eax = 2 - stretch |
Remarks: |
* There is a pair function to set drawing mode - |
subfunction 4 of function 15. |
====================================================================== |
=========== Function 40 - set the mask for expected events. ========== |
====================================================================== |
The mask for expected events affects function working with events |
10, 11, 23 - they notify only about events allowed by this mask. |
Parameters: |
* eax = 40 - function number |
* ebx = mask: bit i corresponds to event i+1 (see list of events) |
(set bit permits notice on event) |
Returned value: |
* 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..0x2d, 0x30..0x4d, 0x50..0xdf, 0xe5..0xff (inclusively). |
* When a thread terminates, all reserved by it ports |
are freed automatically. |
====================================================================== |
============= Function 47 - draw a number in the window. ============= |
====================================================================== |
Parameters: |
* eax = 47 - function number |
* ebx = parameters of conversion number to text: |
* bl = 0 - ecx contains number |
* bl = 1 - ecx contains pointer to dword-number |
* bh = 0 - display in decimal number system |
* bh = 1 - display in hexadecimal system |
* bh = 2 - display in binary system |
* bits 16-21 = how many digits to display |
* bits 22-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 52, subfunction 15 - get local MAC address. ======== |
====================================================================== |
Parameters: |
* eax = 52 - function number |
* ebx = 15 - subfunction number |
* ecx = 0 - read first 4 bytes, |
ecx = 4 - read last 2 bytes |
Returned value: |
* for ecx=0: eax = first 4 bytes of MAC address |
* for ecx=4: ax = last 2 bytes of MAC address, |
high half of eax is destroyed |
* for other ecx: eax = -1 indicates an error |
====================================================================== |
============ Function 53, subfunction 0 - open UDP-socket. =========== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 0 - subfunction number |
* ecx = local port (only low word is taken into account) |
* 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 10 - query Ethernet cable status. ===== |
====================================================================== |
Parameters: |
* eax = 53 - function number |
* ebx = 10 - subfunction number |
Returned value: |
* al = -1 - a network driver is not loaded or |
does not support this function |
* al = 0 - Ethernet cable is unplugged |
* al = 1 - Ethernet cable is plugged |
* ebx destroyed |
Remarks: |
* The current kernel implementation supports this function |
only for RTL8139 network cards. |
====================================================================== |
======= Function 53, subfunction 11 - read network stack data. ======= |
====================================================================== |
Paramters: |
* eax = 53 - function number |
* ebx = 11 - subfunction number |
* ecx = socket handle |
* edx = pointer to buffer |
* esi = number of bytes to read; |
* esi = 0 - read all data (maximum 4096 bytes) |
Returned value: |
* eax = number of bytes read |
* ebx destroyed |
Remakrs: |
* There is no check on handle correctness. |
====================================================================== |
= 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 58 - work with file system. ================ |
====================================================================== |
Parameters: |
* eax = 58 |
* ebx = pointer to the information structure |
Returned value: |
* eax = 0 - success; otherwise file system error code |
* some subfunctions return value in other registers too |
General format of the information structure: |
* +0: dword: subfunction number |
* +4: dword: number of block |
* +8: dword: size |
* +12 = +0xC: dword: pointer to data |
* +16 = +0x10: dword: pointer to a memory for system operations |
(4096 bytes) |
* +20 = +0x14: n db: ASCIIZ-string with the file name |
Specifications - in documentation on the appropriate subfunction. |
Filename is case-insensitive for latin letters, russian letters |
must be capital. |
Format of filename: |
/base/number/dir1/dir2/.../dirn/file, |
where /base/number identifies device, on which file is located: |
one of |
* /RD/1 = /RAMDISK/1 to access ramdisk |
* /FD/1 = /FLOPPYDISK/1 to access first floppy drive, |
/FD/2 = /FLOPPYDISK/2 to access second one |
* /HD/x = /HARDDISK/x - obsolete variant of access to hard disk |
(in this case base is defined by subfunction 7 of function 21), |
x - partition number (beginning from 1) |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices |
IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - partition number on the selected hard drive, varies from 1 |
to 255 (on each hard drive the indexing starts from 1) |
Remarks: |
* In the first two cases it is also possible to use FIRST |
instead of 1, SECOND instead of 2, but it is not recommended |
for convenience of transition to the future extensions. |
* Limitation n<=39 is imposed. |
* Names of folders and file dir1,...,dirn,file must have the |
format 8.3: name no more than 8 characters, dot, extension no |
more than 3 characters. Trailing spaces are ignored, no other |
spaces is allowed. If name occupies equally 8 characters, |
dot may be omitted (though it is not recommended to use this |
feature for convenience of transition to the future extensions). |
* This function does not support folders on ramdisk. |
Examples: |
* '/RAMDISK/FIRST/KERNEL.ASM',0 |
'/rd/1/kernel.asm',0 |
* '/HD0/1/kernel.asm',0 |
* '/hd0/1/menuet/pics/tanzania.bmp',0 |
Existing subfunctions: |
* subfunction 0 - read file/folder |
* subfunction 8 - LBA-read from device |
* subfunction 15 - get file system information |
====================================================================== |
=========== Function 58, subfunction 0 - read file/folder. =========== |
====================================================================== |
Parameters: |
* eax = 58 |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 0 = subfunction number |
* +4: dword: first block to read (beginning from 0) |
* +8: dword: amount of blocks to read |
* +12 = +0xC: dword: pointer to buffer for data |
* +16 = +0x10: dword: pointer to buffer for system operations |
(4096 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = file size (in bytes) or -1=0xffffffff, if file was not found |
Remarks: |
* Block size is 512 bytes. |
* This function is obsolete, for reading files use subfunction 0 |
of function 70, for reading folders - subfunction 1 of |
function 70. |
* Function can read contents of a folder. Only FAT file system is |
supported. The format of FAT-folder is described |
in any FAT documentation. |
* Size of a folder is determined by size of FAT clusters chain. |
* If file was ended before last requested block was read, |
the function will read as many as it can, and after that return |
eax=6 (EOF). |
* Function can read root folders /rd/1,/fd/x,/hd[n]/x, but |
in the first two cases the current implementation does not follow |
to the declared rules: |
for /rd/1: |
* if one want to read 0 blocks, function considers, |
that he requested 1; |
* if one requests more than 14 blocks or starting block is |
not less than 14, function returns eax=5 (not found) è ebx=-1; |
* size of ramdisk root folder is 14 blocks, |
0x1C00=7168 áàéò; but function returns ebx=0 |
(except of the case of previous item); |
* strangely enough, it is possible to read 14th block (which |
generally contains a garbage - I remind, the indexing begins |
from 0); |
* if some block with the number not less than 14 was requested, |
function returns eax=6(EOF); otherwise eax=0. |
For /fd/x: |
* if the start block is not less than 14, function returns |
eax=5 (not found) and ebx=0; |
* note that format of FAT12 allows floppies with the root size |
more or less than 14 blocks; |
* check for length is not performed; |
* if data was successful read, function returns |
eax=0,ebx=0; otherwise eax=10 (access denied), ebx=-1. |
* The function handles reading of special folders /,/rd,/fd,/hd[n]; |
but the result does not correspond to expected (on operations with |
normal files/folders), does not follow the declared rules, |
may be changed in future versions of the kernel and consequently |
is not described. To obtain the information about the equipment |
use subfunction 11 of function 18 or |
read corresponding folder with subfunction 1 of function 70. |
====================================================================== |
========= Function 58, subfunction 8 - LBA-read from device. ========= |
====================================================================== |
Parameters: |
* eax = 58 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 8 = subfunction number |
* +4: dword: number of block to read (beginning from 0) |
* +8: dword: ignored (set to 1) |
* +12 = +0xC: dword: pointer to buffer for data (512 bytes) |
* +16 = +0x10: dword: pointer to buffer for system operations |
(4096 bytes) |
* +20 = +0x14: ASCIIZ-name of device: case-insensitive, one of |
/rd/1 = /RamDisk/1, /hd/n = /HardDisk/n, |
1<=n<=4 - number of device: 1=IDE0, ..., 4=IDE3. |
Instead of digits it is allowed, though not recommended for |
convenience of transition to future extensions, to use |
'first','second','third','fourth'. |
Returned value: |
* for device name /hd/xxx, where xxx is not in the list above: |
* eax = ebx = 1 |
* for invalid device name (except for the previous case): |
* eax = 5 |
* ebx does not change |
* if LBA-access is disabled by subfunction 11 of function 21: |
* eax = 2 |
* ebx destroyed |
* for ramdisk: attempt to read block outside ramdisk |
(18*2*80 blocks) results in |
* eax = 3 |
* ebx = 0 |
* for successful read: |
* eax = ebx = 0 |
Remarks: |
* Block size is 512 bytes; function reads one block. |
* Do not depend on returned value, it can be changed |
in future versions. |
* Function requires that LBA-access to devices is enabled by |
subfunction 11 of function 21. To check this one can use |
subfunction 11 of function 26. |
* LBA-read of floppy is not supported. |
* Function reads data on physical hard drive; if for any reason |
data of the concrete partition are required, application must |
define starting sector of this partition (either directly |
through MBR, or from the full structure returned by |
ïîäôóíêöèåé 11 ôóíêöèè 18). |
* Function does not check error code of hard disk, so request of |
nonexisting sector reads something (most probably it will be |
zeroes, but this is defined by device) and this is considered |
as success (eax=0). |
====================================================================== |
==== Function 58, subfunction 15 - get information on file system. === |
====================================================================== |
Parameters: |
* eax = 58 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 15 = subfunction number |
* +4: dword: ignored |
* +8: dword: ignored |
* +12 = +0xC: dword: ignored |
* +16 = +0x10: dword: ignored |
* +20 = +0x14: (only second character is checked) |
/rd=/RAMDISK or /hd=/HARDDISK |
Returned value: |
* if the second character does not belong to set {'r','R','h','H'}: |
* eax = 3 |
* ebx = ecx = dword [fileinfo] = 0 |
* for ramdisk: |
* eax = 0 (success) |
* ebx = total number of clusters = 2847 |
* ecx = number of free clusters |
* dword [fileinfo] = cluster size = 512 |
* for hard disk: base and partition are defined by subfunctions |
7 and 8 of function 21: |
* eax = 0 (success) |
* ebx = total number of clusters |
* ecx = number of free clusters |
* dword [fileinfo] = cluster size (in bytes) |
Remarks: |
* Be not surprised to strange layout of 4th returned parameter |
- when this code was writing, at system calls application got |
only registers eax,ebx,ecx (from pushad-structure transmitted |
as argument to the system function). Now it is corrected, so, |
probably, it is meaningful to return cluster size in edx, while |
this function is not used yet. |
* There exists also subfunction 11 of function 18, |
which returns information on file system. From the full table |
of disk subsystem it is possible to deduce cluster size (there |
it is stored in sectors) and total number of clusters |
for hard disks. |
====================================================================== |
========== Function 60 - Inter Process Communication (IPC). ========== |
====================================================================== |
IPC is used for message dispatching from one process/thread to |
another. Previously it is necessary to agree how to interpret |
the concrete message. |
----------- Subfunction 1 - set the area for IPC receiving ----------- |
Is called by process-receiver. |
Parameters: |
* eax = 60 - function number |
* ebx = 1 - subfunction number |
* ecx = pointer to the buffer |
* edx = size of the buffer |
Returned value: |
* eax = 0 - always success |
Format of IPC-buffer: |
* +0: dword: if nonzero, buffer is considered locked; |
lock/unlock the buffer, when you work with it and need that |
buffer data are not changed from outside (no new messages) |
* +4: dword: occupied place in the buffer (in bytes) |
* +8: first message |
* +8+n: second message |
* ... |
Format of a message: |
* +0: dword: PID of sender |
* +4: dword: message length (not including this header) |
* +8: n*byte: message data |
------------------ Subfunction 2 - send IPC message ------------------ |
Is called by process-sender. |
Parameters: |
* eax = 60 - function number |
* ebx = 2 - subfunction number |
* ecx = PID of receiver |
* edx = pointer to the message data |
* esi = message length (in bytes) |
Returned value: |
* eax = 0 - success |
* eax = 1 - the receiver has not defined buffer for IPC messages |
(can be, still have no time, |
and can be, this is not right process) |
* eax = 2 - the receiver has blocked IPC-buffer; try to wait a bit |
* eax = 3 - overflow of IPC-buffer of the receiver |
* eax = 4 - process/thread with such PID does not exist |
Remarks: |
* Immediately after writing of IPC-message to the buffer the system |
sends to the receiver the event with code 7 (see event codes). |
====================================================================== |
==== Function 61 - get parameters for the direct graphics access. ==== |
====================================================================== |
The data of the graphics screen (the memory area which displays |
screen contents) are accessible to a program directly, without |
any system calls, through the selector gs: |
mov eax, [gs:0] |
places in eax the first dword of the buffer, which contains |
information on color of the left upper point (and, possibly, colors |
of several following). |
mov [gs:0], eax |
by work in VESA modes with LFB sets color of the left upper point |
(and, possibly, colors of several following). |
To interpret the data of graphics screen program needs to know |
some parameters, returning by this function. |
Remarks: |
* Graphics parameters changes very seldom at work, |
namely, only in cases, when user works with the application VRR. |
* At videomode change the system redraws all windows (event |
with code 1) and redraws the background (event 5). |
Same events occur in other cases too, which meet much more often, |
than videomode change. |
* By operation in videomodes with LFB the selector gs points to |
LFB itself, so reading/writing on gs result directly in |
change of screen contents. By operation in videomodes without |
LFB gs points to some data area in the kernel, and all functions |
of screen output fulfil honesty double operation on writing |
directly to the screen and writing to this buffer. In result |
at reading contents of this buffer the results correspond to |
screen contents (with, generally speaking, large color |
resolution), and writing is ignored. |
One exception is the mode 320*200, for which main loop of the |
system thread updates the screen according to mouse movements. |
------------------------- Screen resolution -------------------------- |
Parameters: |
* eax = 61 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* eax = [resolution on x axis]*65536 + [resolution on y axis] |
Remarks: |
* One can use function 14 paying attention that |
it returns sizes on 1 pixel less. It is fully equivalent way. |
---------------------- Number of bits per pixel ---------------------- |
Parameters: |
* eax = 61 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* eax = number of bits per pixel (24 or 32) |
-------------------- Number of bytes per scanline -------------------- |
Parameters: |
* eax = 61 - function number |
* ebx = 3 - subfunction number |
Returned value: |
* eax = number of bytes occupied by one scanline |
(horizontal line on the screen) |
====================================================================== |
===== Function 62, subfunction 0 - get version of PCI-interface. ===== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 0 - subfunction number |
Returned value: |
* eax = -1 - PCI access is disabled; otherwise |
* ah.al = version of PCI-interface (ah=version, al=subversion) |
* high word of eax is zeroed |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* If PCI BIOS is not supported, the value of ax is undefined. |
====================================================================== |
==== Function 62, subfunction 1 - get number of the last PCI-bus. ==== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 1 - subfunction number |
Returned value: |
* eax = -1 - access to PCI is disabled; otherwise |
* al = number of the last PCI-bus; other bytes of eax are destroyed |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* If PCI BIOS is not supported, the value of ax is undefined. |
====================================================================== |
===================== Function 62, subfunction 2 ===================== |
===== Get mechanism of addressing to the PCI configuration space. ==== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 2 - subfunction number |
Returned value: |
* eax = -1 - access to PCI is disabled; otherwise |
* al = mechanism (1 or 2); other bytes of eax are destroyed |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* Addressing mechanism is selected depending on |
equipment characteristics. |
* Subfunctions of read and write work automatically |
with the selected mechanism. |
====================================================================== |
======== Function 62, subfunctions 4,5,6 - read PCI-register. ======== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 4 - read byte |
* bl = 5 - read word |
* bl = 6 - read dword |
* bh = number of PCI-bus |
* ch = dddddfff, where ddddd = number of the device on the bus, |
fff = function number of device |
* cl = number of register (must be even for bl=5, |
divisible by 4 for bl=6) |
Returned value: |
* eax = -1 - error (access to PCI is disabled or parameters |
are not supported); otherwise |
* al/ax/eax (depending on requested size) contains the data; |
the other part of register eax is destroyed |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* Access mechanism 2 supports only 16 devices on a bus and ignores |
function number. To get access mechanism use subfunction 2. |
* Some registers are standard and exist for all devices, some are |
defined by the concrete device. The list of registers of the |
first type can be found e.g. in famous |
Interrupt List by Ralf Brown |
(http://www.pobox.com/~ralf/files.html, |
ftp://ftp.cs.cmu.edu/afs/cs/user/ralf/pub/); |
registers of the second type must be listed |
in the device documentation. |
====================================================================== |
====== Function 62, subfunctions 8,9,10 - write to PCI-register. ===== |
====================================================================== |
Parameters: |
* eax = 62 - function number |
* bl = 8 - write byte |
* bl = 9 - write word |
* bl = 10 - write dword |
* bh = number of PCI-bus |
* ch = dddddfff, where ddddd = number of the device on the bus, |
fff = function number of device |
* cl = number of register (must be even for bl=9, |
divisible by 4 for bl=10) |
* dl/dx/edx (depending on requested size) contatins |
the data to write |
Returned value: |
* eax = -1 - error (access to PCI is disabled or parameters |
are not supported) |
* eax = 0 - success |
Remarks: |
* Previously low-level access to PCI for applications must be |
enabled by subfunction 12 of function 21. |
* Access mechanism 2 supports only 16 devices on a bus and ignores |
function number. To get access mechanism use subfunction 2. |
* Some registers are standard and exist for all devices, some are |
defined by the concrete device. The list of registers of the |
first type can be found e.g. in famous Interrupt List by |
Ralf Brown; registers of the second type must be listed |
in the device documentation. |
====================================================================== |
============== Function 63 - work with the debug board. ============== |
====================================================================== |
The debug board is the global system buffer (with the size |
1024 bytes), to which any program can write (generally speaking, |
arbitrary) data and from which other program can read these data. |
By the agreement written data are text strings interpreted as |
debug messages on a course of program execution. The kernel in |
some situations also writes to the debug board information on |
execution of some functions; by the agreement kernel messages |
begins from the prefix "K : ". |
For view of the debug board the application 'board' was created, |
which reads data from the buffer and displays them in its window. |
'board' interpretes the sequence of codes 13,10 as newline. |
A character with null code in an end of line is not necessary, |
but also does not prevent. |
Because debugger has been written, the value of the debug board |
has decreased, as debugger allows to inspect completely a course of |
program execution without any efforts from the direction of program |
itself. Nevertheless in some cases the debug board is still useful. |
----------------------------- Write byte ----------------------------- |
Parameters: |
* eax = 63 - function number |
* ebx = 1 - subfunction number |
* cl = data byte |
Returned value: |
* function does not return value |
Remarks: |
* Byte is written to the buffer. Buffer size is 512 bytes. |
At buffer overflow all obtained data are lost. |
* For output to the debug board of more complicated objects |
(strings, numbers) it is enough to call this function in cycle. |
It is possible not to write the appropriate code manually and use |
file 'debug.inc', which is included into the distributive. |
----------------------------- Read byte ------------------------------ |
Takes away byte from the buffer. |
Parameters: |
* eax = 63 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* eax = ebx = 0 - the buffer is empty |
* eax = byte, ebx = 1 - byte was successfully read |
====================================================================== |
============== Function 64 - resize application memory. ============== |
====================================================================== |
Parameters: |
* eax = 64 - function number |
* ebx = 1 - unique subfunction |
* ecx = new memory size |
Returned value: |
* eax = 0 - success |
* eax = 1 - not enough memory |
Remarks: |
* There is another way to dynamically allocate/free memory - |
subfunctions 11, 12, 13 of function 68. |
* The function cannot be used together with 68.11, 68.12, 68.13. |
The function call will be ignored after creation of process heap |
with function 68.11. |
====================================================================== |
======== Function 65 - draw image with palette in the window. ======== |
====================================================================== |
Parameters: |
* eax = 65 - function number |
* ebx = pointer to the image |
* ecx = [size on axis x]*65536 + [size on axis y] |
* edx = [coordinate on axis x]*65536 + [coordinate on axis y] |
* esi = number of bits per pixel, must be 8, 24 or 32 |
* edi = pointer to palette (256 colors 0x00RRGGBB); |
ignored when esi = 24 and 32 |
* ebp = offset of next row data relative to previous row data |
Returned value: |
* function does not return value |
Remarks: |
* Coordinates of the image are coordinates of the upper left corner |
of the image relative to the window. |
* Size of the image in bytes is xsize*ysize. |
* Each byte of image is index in the palette. |
* If the image uses less than 256 colors, palette size may be |
less than 256 too. |
* The call to function 7 is equivalent to call to this function |
with esi=24, ebp=0. |
====================================================================== |
================== Function 66 - work with keyboard. ================= |
====================================================================== |
The input mode influences results of reading keys by function 2. |
When a program loads, ASCII input mode is set for it. |
-------------- Subfunction 1 - set keyboard input mode. -------------- |
Parameters: |
* eax = 66 - function number |
* ebx = 1 - subfunction number |
* ecx = mode: |
* 0 = normal (ASCII-characters) |
* 1 = scancodes |
Returned value: |
* function does not return value |
-------------- Subfunction 2 - get keyboard input mode. -------------- |
Parameters: |
* eax = 66 - function number |
* ebx = 2 - subfunction number |
Returned value: |
* eax = current mode |
------------ Subfunction 3 - get status of control keys. ------------- |
Parameters: |
* eax = 66 - function number |
* ebx = 3 - subfunction number |
Returned value: |
* eax = bit mask: |
* bit 0 (mask 1): left Shift is pressed |
* bit 1 (mask 2): right Shift is pressed |
* bit 2 (mask 4): left Ctrl is pressed |
* bit 3 (mask 8): right Ctrl is pressed |
* bit 4 (mask 0x10): left Alt is pressed |
* bit 5 (mask 0x20): right Alt is pressed |
* bit 6 (mask 0x40): CapsLock is on |
* bit 7 (mask 0x80): NumLock is on |
* bit 8 (mask 0x100): ScrollLock is on |
* other bits are cleared |
-------------- Subfunction 4 - set system-wide hotkey. --------------- |
When hotkey is pressed, the system notifies only those applications, |
which have installed it; the active application (which receives |
all normal input) does not receive such keys. |
The notification consists in sending event with the code 2. |
Reading hotkey is the same as reading normal key - by function 2. |
Parameters: |
* eax = 66 - function number |
* ebx = 4 - subfunction number |
* cl determines key scancode; |
use cl=0 to give combinations such as Ctrl+Shift |
* edx = 0xXYZ determines possible states of control keys: |
* Z (low 4 bits) determines state of LShift and RShift: |
* 0 = no key must be pressed; |
* 1 = exactly one key must be pressed; |
* 2 = both keys must be pressed; |
* 3 = must be pressed LShift, but not RShift; |
* 4 = must be pressed RShift, but not LShift |
* Y - similar for LCtrl and RCtrl; |
* X - similar for LAlt and RAlt |
Returned value: |
* eax=0 - success |
* eax=1 - too mant hotkeys (maximum 256 are allowed) |
Remarks: |
* Hotkey can work either at pressing or at release. Release |
scancode of a key is more on 128 than pressing scancode |
(i.e. high bit is set). |
* Several applications can set the same combination; |
all such applications will be informed on pressing |
such combination. |
-------------- Subfunction 5 - delete installed hotkey. -------------- |
Parameters: |
* eax = 66 - function number |
* ebx = 5 - subfunction number |
* cl = scancode of key and edx = 0xXYZ the same as in subfunction 4 |
Returned value: |
* eax = 0 - success |
* eax = 1 - there is no such hotkey |
Remarks: |
* When a process/thread terminates, all hotkey installed by it are |
deleted. |
* The call to this subfunction does not affect other applications. |
If other application has defined the same combination, it will |
still receive notices. |
====================================================================== |
========= Function 67 - change position/sizes of the window. ========= |
====================================================================== |
Parameters: |
* eax = 67 - function number |
* ebx = new x-coordinate of the window |
* ecx = new y-coordinate of the window |
* edx = new x-size of the window |
* esi = new y-size of the window |
Returned value: |
* function does not return value |
Remarks: |
* The value -1 for a parameter means "do not change"; e.g. to move |
the window without resizing it is possible to specify edx=esi=-1. |
* Previously the window must be defined by function 0. |
It sets initial coordinates and sizes of the window. |
* Sizes of the window are understood in sense of function 0, |
that is one pixel less than real sizes. |
* The function call for maximized windows is simply ignored. |
* For windows of appropriate styles position and/or sizes can be |
changed by user; current position and sizes can be obtained by |
call to function 9. |
* The function sends to the window redraw event (with the code 1). |
====================================================================== |
====== Function 68, subfunction 0 - get the task switch counter. ===== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 0 - subfunction number |
Returned value: |
* eax = number of task switches from the system booting |
(modulo 2^32) |
====================================================================== |
======= Function 68, subfunction 1 - switch to the next thread. ====== |
====================================================================== |
The function completes the current time slice allocated to the |
thread and switches to the next. (Which thread in which process |
will be next, is unpredictable). Later, when execution queue |
will reach the current thread, execution will be continued. |
Parameters: |
* eax = 68 - function number |
* ebx = 1 - subfunction number |
Returned value: |
* function does not return value |
====================================================================== |
============= Function 68, subfunction 2 - cache + rdpmc. ============ |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 2 - subfunction number |
* ecx = required action: |
* ecx = 0 - enable instruction 'rdpmc' |
(ReaD Performance-Monitoring Counters) for applications |
* ecx = 1 - find out whether cache is disabled/enabled |
* ecx = 2 - enable cache |
* ecx = 3 - disable cache |
Returned value: |
* for ecx=0: |
* eax = the value of cr4 |
* for ecx=1: |
* eax = (cr0 and 0x60000000): |
* eax = 0 - cache is on |
* eax <> 0 - cache is off |
* for ecx=2 and ecx=3: |
* function does not return value |
====================================================================== |
=========== Function 68, subfunction 3 - read MSR-register. ========== |
====================================================================== |
MSR = Model Specific Register; the complete list of MSR-registers |
of a processor is included to the documentation on it (for example, |
IA-32 Intel Architecture Software Developer's Manual, |
Volume 3, Appendix B); each processor family has its own subset |
of the MSR-registers. |
Parameters: |
* eax = 68 - function number |
* ebx = 3 - subfunction number |
* ecx is ignored |
* edx = MSR address |
Returned value: |
* ebx:eax = high:low dword of the result |
Remarks: |
* If ecx contains nonexistent or not implemented for this processor |
MSR, processor will generate an exception in the kernel, which |
will kill the thread. |
* Previously it is necessary to check, whether MSRs are supported |
as a whole, with the instruction 'cpuid'. Otherwise processor |
will generate other exception in the kernel, which will anyway |
kill the thread. |
====================================================================== |
========= Function 68, subfunction 4 - write to MSR-register. ======== |
====================================================================== |
MSR = Model Specific Register; the complete list of MSR-registers |
of a processor is included to the documentation on it (for example, |
IA-32 Intel Architecture Software Developer's Manual, |
Volume 3, Appendix B); each processor family has its own subset |
of the MSR-registers. |
Parameters: |
* eax = 68 - function number |
* ebx = 4 - subfunction number |
* ecx is ignored |
* edx = MSR address |
* esi:edi = high:low dword |
Returned value: |
* function does not return value |
Remarks: |
* If ecx contains nonexistent or not implemented for this processor |
MSR, processor will generate an exception in the kernel, which |
will kill the thread. |
* Previously it is necessary to check, whether MSRs are supported |
as a whole, with the instruction 'cpuid'. Otherwise processor |
will generate other exception in the kernel, which will anyway |
kill the thread. |
====================================================================== |
======= Function 68, subfunction 11 - initialize process heap. ======= |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 11 - subfunction number |
Returned value: |
* eax = 0 - failed |
* otherwise size of created heap |
Remarks: |
* The function call initializes heap, from which one can in future |
allocate and free memory blocks with subfunctions 12 and 13. |
Heap size is equal to total amount of free application memory. |
* The second function call from the same process results in |
returning the size of the existing heap. |
* After creation of the heap calls to function 64 will be ignored. |
====================================================================== |
======== Function 68, subfunction 12 - allocate memory block. ======== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 12 - subfunction number |
* ecx = required size in bytes |
Returned value: |
* eax = pointer to the allocated block |
Remarks: |
* Before this call one must initialize process heap by call to |
subfunction 11. |
* The function allocates an integer number of pages (4 Kb) in such |
way that the real size of allocated block is more than or equal to |
requested size. |
====================================================================== |
========== Function 68, subfunction 13 - free memory block. ========== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 13 - subfunction number |
* ecx = pointer to the memory block |
Returned value: |
* eax = 1 - success |
* eax = 0 - failed |
Remarks: |
* The memory block must have been allocated by subfunction 12 |
or subfunction 20. |
====================================================================== |
======== Function 68, subfunction 14 - 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. |
* Driver ABC is loaded from file /rd/1/drivers/ABC.obj. |
====================================================================== |
============ Function 68, subfunction 17 - driver control. =========== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 17 - subfunction number |
* ecx = pointer to the control structure: |
* +0: dword: handle of driver |
* +4: dword: code of driver function |
* +8: dword: pointer to input data |
* +12 = +0xC: dword: size of input data |
* +16 = +0x10: dword: pointer to output data |
* +20 = +0x14: dword: size of output data |
Returned value: |
* eax = 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) |
====================================================================== |
=============== Function 68, subfunction 19 - load DLL. ============== |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 19 - subfunction number |
* ecx = pointer to ASCIIZ-string with the full path to DLL |
Returned value: |
* eax = 0 - failed |
* otherwise eax = pointer to DLL export table |
Remarks: |
* Export table is an array of structures of 2 dword's, terminated |
by zero. The first dword in structure points to function name, |
the second dword contains address of function. |
====================================================================== |
======= Function 68, subfunction 20 - reallocate memory block. ======= |
====================================================================== |
Parameters: |
* eax = 68 - function number |
* ebx = 20 - subfunction number |
* ecx = new size in bytes |
* edx = pointer to already allocated block |
Returned value: |
* eax = pointer to the reallocated block, 0 = error |
Remarks: |
* Before this call one must initialize process heap by call to |
subfunction 11. |
* The function allocates an integer number of pages (4 Kb) in such |
way that the real size of allocated block is more than or equal to |
requested size. |
* If edx=0, the function call is equivalent to memory allocation |
with subfunction 12. Otherwise the block at edx |
must be allocated earlier with subfunction 12 or this subfunction. |
* If ecx=0, the function frees memory block at edx and returns 0. |
* The contents of the block are unchanged up to the shorter of |
the new and old sizes. |
====================================================================== |
====================== Fucntion 69 - debugging. ====================== |
====================================================================== |
A process can load other process as debugged by set of corresponding |
bit by call to subfunction 7 of function 70. |
A process can have only one debugger; one process can debug some |
others. The system notifies debugger on events occuring with |
debugged process. Messages are written to the buffer defined by |
subfunction 0. |
Format of a message: |
* +0: dword: message code |
* +4: dword: PID of debugged process |
* +8: there can be additional data depending on message code |
Message codes: |
* 1 = exception |
* in addition dword-number of the exception is given |
* process is suspended |
* 2 = process has terminated |
* comes at any termination: both through the system function -1, |
and at "murder" by any other process (including debugger itself) |
* 3 = debug exception int 1 = #DB |
* in addition dword-image of the register DR6 is given: |
* bits 0-3: condition of the corresponding breakpoint (set by |
subfunction 9) is satisfied |
* áèò 14: exception has occured because of the trace mode |
(flag TF is set TF) |
* process is suspended |
When debugger terminates, all debugged processes are killed. |
If debugger does not want this, it must previously detach by |
subfunction 3. |
All subfunctions are applicable only to processes/threads started |
from the current by function 70 with set debugging flag. |
Debugging of multithreaded programs is not supported yet. |
The full list of subfunctions: |
* subfunction 0 - define data area for debug messages |
* subfunction 1 - get contents of registers of debugged thread |
* subfunction 2 - set contents of registers of debugged thread |
* subfunction 3 - detach from debugged process |
* subfunction 4 - suspend debugged thread |
* subfunction 5 - resume debugged thread |
* subfunction 6 - read from the memory of debugged process |
* subfunction 7 - write to the memory of debugged process |
* subfunction 8 - terminate debugged thread |
* subfunction 9 - set/clear hardware breakpoint |
====================================================================== |
= Function 69, subfunction 0 - define data area fror debug messages. = |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 0 - subfunction number |
* ecx = pointer |
Format of data area: |
* +0: dword: N = buffer size (not including this header) |
* +4: dword: occupied place |
* +8: N*byte: buffer |
Returned value: |
* function does not return value |
Remarks: |
* If the size field is negative, the buffer is considered locked |
and at arrival of new message the system will wait. |
For synchronization frame all work with the buffer by operations |
lock/unlock |
neg [bufsize] |
* Data in the buffer are considered as array of items with variable |
length - messages. Format of a message is explained in |
general description. |
====================================================================== |
===================== Function 69, subfunction 1 ===================== |
============ Get contents of registers of debugged thread. =========== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 1 - subfunction number |
* ecx = thread identifier |
* edx = size of context structure, must be 0x28=40 bytes |
* esi = pointer to context structure |
Returned value: |
* function does not return value |
Format of context structure: (FPU is not supported yet) |
* +0: dword: eip |
* +4: dword: eflags |
* +8: dword: eax |
* +12 = +0xC: dword: ecx |
* +16 = +0x10: dword: edx |
* +20 = +0x14: dword: ebx |
* +24 = +0x18: dword: esp |
* +28 = +0x1C: dword: ebp |
* +32 = +0x20: dword: esi |
* +36 = +0x24: dword: edi |
Remarks: |
* If the thread executes code of ring-0, the function returns |
contents of registers of ring-3. |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
===================== Function 69, subfunction 2 ===================== |
============ Set contents of registers of debugged thread. =========== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 2 - subfunction number |
* ecx = thread identifier |
* edx = size of context structure, must be 0x28=40 bytes |
Returned value: |
* function does not return value |
Format of context structure is shown in the description of |
subfunction 1. |
Remarks: |
* If the thread executes code of ring-0, the function returns |
contents of registers of ring-3. |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
===== Function 69, subfunction 3 - detach from debugged process. ===== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 3 - subfunction number |
* ecx = identifier |
Returned value: |
* function does not return value |
Remarks: |
* If the process was suspended, it resumes execution. |
====================================================================== |
======== Function 69, subfunction 4 - suspend debugged thread. ======= |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 4 - subfunction number |
* ecx = thread identifier |
Returned value: |
* function does not return value |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
======== Function 69, subfunction 5 - resume debugged thread. ======== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 5 - subfunction number |
* ecx = thread identifier |
Returned value: |
* function does not return value |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
= Fucntion 69, subfunction 6 - read from memory of debugged process. = |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 6 - subfunction number |
* ecx = identifier |
* edx = number of bytes to read |
* esi = address in the memory of debugged process |
* edi = pointer to buffer for data |
Returned value: |
* eax = -1 at an error (invalid PID or buffer) |
* otherwise eax = number of read bytes (possibly, 0, |
if esi is too large) |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
== Function 69, subfunction 7 - write to memory of debugged process. = |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 7 - subfunction number |
* ecx = identifier |
* edx = number of bytes to write |
* esi = address of memory in debugged process |
* edi = pointer to data |
Returned value: |
* eax = -1 at an error (invalid PID or buffer) |
* otherwise eax = number of written bytes (possibly, 0, |
if esi is too large) |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
====================================================================== |
======= Function 69, subfunction 8 - terminate debugged thread. ====== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 8 - subfunction number |
* ecx = identifier |
Returned value: |
* function does not return value |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
* The function is similar to subfunction 2 of function 18 |
with two differences: it requires first remark and |
accepts PID rather than slot number. |
====================================================================== |
===== Function 69, subfunction 9 - set/clear hardware breakpoint. ==== |
====================================================================== |
Parameters: |
* eax = 69 - function number |
* ebx = 9 - subfunction number |
* ecx = thread identifier |
* dl = index of breakpoint, from 0 to 3 inclusively |
* dh = flags: |
* if high bit is cleared - set breakpoint: |
* bits 0-1 - condition: |
* 00 = breakpoint on execution |
* 01 = breakpoint on read |
* 11 = breakpoint on read/write |
* bits 2-3 - length; for breakpoints on exception it must be |
00, otherwise one of |
* 00 = byte |
* 01 = word |
* 11 = dword |
* esi = breakpoint address; must be aligned according to |
the length (i.e. must be even for word breakpoints, |
divisible by 4 for dword) |
* if high bit is set - clear breakpoint |
Returned value: |
* eax = 0 - success |
* eax = 1 - error in the input data |
* eax = 2 - (reserved, is never returned in the current |
implementation) a global breakpoint with that index is already set |
Remarks: |
* Process must be loaded for debugging (as is shown in |
general description). |
* Hardware breakpoints are implemented through DRx-registers of |
the processor, all limitations results from this. |
* The function can reinstall the breakpoint, previously set |
by it (and it does not inform on this). |
Carry on the list of set breakpoints in the debugger. |
* Breakpoints generate debug exception #DB, on which the system |
notifies debugger. |
* Breakpoints on write and read/write act after |
execution of the caused it instruction. |
====================================================================== |
==== Function 70 - work with file system with long names support. ==== |
====================================================================== |
Parameters: |
* eax = 70 |
* ebx = pointer to the information structure |
Returned value: |
* eax = 0 - success; otherwise file system error code |
* some subfunctions return value in other registers too |
General format of the information structure: |
* +0: dword: subfunction number |
* +4: dword: file offset |
* +8: dword: high dword of offset (must be 0) or flags field |
* +12 = +0xC: dword: size |
* +16 = +0x10: dword: pointer to data |
* +20 = +0x14: n db: ASCIIZ-string with the filename |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with the filename |
Specifications - in documentation on the appropriate subfunction. |
Filename is case-insensitive. Russian letters must be written in |
the encoding cp866 (DOS). |
Format of filename: |
/base/number/dir1/dir2/.../dirn/file, |
where /base/number identifies device, on which file is located: |
one of |
* /RD/1 = /RAMDISK/1 to access ramdisk |
* /FD/1 = /FLOPPYDISK/1 to access first floppy drive, |
/FD/2 = /FLOPPYDISK/2 to access second one |
* /HD0/x, /HD1/x, /HD2/x, /HD3/x to access accordingly to devices |
IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave); |
x - partition number on the selected hard drive, varies from 1 |
to 255 (on each hard drive the indexing starts from 1) |
* /CD0/1, /CD1/1, /CD2/1, /CD3/1 to access accordingly to |
CD on IDE0 (Primary Master), IDE1 (Primary Slave), |
IDE2 (Secondary Master), IDE3 (Secondary Slave) |
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 |
* subfunction 9 - create folder |
For CD-drives due to hardware limitations only subfunctions |
0,1,5 and 7 are available, other subfunctions return error |
with code 2. |
====================================================================== |
=== Function 70, subfunction 0 - read file with long names support. == |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 0 = subfunction number |
* +4: dword: file offset (in bytes) |
* +8: dword: 0 (reserved for high dword of offset) |
* +12 = +0xC: dword: number of bytes to read |
* +16 = +0x10: dword: pointer to buffer for data |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = number of read bytes or -1=0xffffffff if file was not found |
Remarks: |
* If file was ended before last requested block was read, |
the function will read as many as it can, and after that return |
eax=6 (EOF). |
* The function does not allow to read folder (returns eax=10, |
access denied). |
====================================================================== |
== Function 70, subfunction 1 - read folder with long names support. = |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 1 = subfunction number |
* +4: dword: index of starting block (beginning from 0) |
* +8: dword: flags field: |
* bit 0 (mask 1): in what format to return names, |
0=ANSI, 1=UNICODE |
* other bits are reserved and must be set to 0 for the future |
compatibility |
* +12 = +0xC: dword: number of blocks to read |
* +16 = +0x10: dword: pointer to buffer for data, buffer size |
must be not less than 32 + [+12]*560 bytes |
* +20 = +0x14: ASCIIZ-name of folder, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = number of files, information on which was written to |
the buffer, or -1=0xffffffff, if folder was not found |
Structure of the buffer: |
* +0: 32*byte: header |
* +32 = +0x20: n1*byte: block with information on file 1 |
* +32+n1: n2*byte: block with information on file 2 |
* ... |
Structure of header: |
* +0: dword: version of structure (current is 1) |
* +4: dword: number of placed blocks; is not greater than requested |
in the field +12 of information structure; can be less, if |
there are no more files in folder (the same as in ebx) |
* +8: dword: total number of files in folder |
* +12 = +0xC: 20*byte: reserved (zeroed) |
Structure of block of data for folder entry (BDFE): |
* +0: dword: attributes of file: |
* bit 0 (mask 1): file is read-only |
* bit 1 (mask 2): file is hidden |
* bit 2 (mask 4): file is system |
* bit 3 (mask 8): this is not a file but volume label |
(for one partition meets no more than once and |
only in root folder) |
* bit 4 (mask 0x10): this is a folder |
* bit 5 (mask 0x20): file was not archived - many archivation |
programs have an option to archive only files with this bit set, |
and after archiving this bit is cleared - it can be useful |
for automatically creating of backup-archives as at writing |
this bit is usually set |
* +4: byte: type of name data: |
(coincides with bit 0 of flags in the information structure) |
* 0 = ASCII = 1-byte representation of each character |
* 1 = UNICODE = 2-byte representation of each character |
* +5: 3*byte: reserved (zero) |
* +8: 4*byte: time of file creation |
* +12 = +0xC: 4*byte: date of file creation |
* +16 = +0x10: 4*byte: time of last access (read or write) |
* +20 = +0x14: 4*byte: date of last access |
* +24 = +0x18: 4*byte: time of last modification |
* +28 = +0x1C: 4*byte: date of last modification |
* +32 = +0x20: qword: file size in bytes (up to 16777216 Tb) |
* +40 = +0x28: name |
* for ASCII format: maximum length is 263 characters |
(263 bytes), byte after the name has value 0 |
* for UNICODE format: maximum length is 259 characters |
(518 bytes), 2 bytes after the name have value 0 |
Time format: |
* +0: byte: seconds |
* +1: byte: minutes |
* +2: byte: hours |
* +3: byte: reserved (0) |
* for example, 23.59.59 is written as (in hex) 3B 3B 17 00 |
Date format: |
* +0: byte: day |
* +1: byte: month |
* +2: word: year |
* for example, 25.11.1979 is written as (in hex) 19 0B BB 07 |
Remarks: |
* If BDFE contains ASCII name, the length of BDFE is 304 bytes, |
if UNICODE name - 560 bytes. Value of length is aligned |
on 16-byte bound (to accelerate processing in CPU cache). |
* First character after a name is zero (ASCIIZ-string). The further |
data contain garbage. |
* If files in folder were ended before requested number was read, |
the function will read as many as it can, and after that return |
eax=6 (EOF). |
* Any folder on the disk, except for root, contains two special |
entries "." and "..", identifying accordingly the folder itself |
and the parent folder. |
* The function allows also to read virtual folders "/", "/rd", |
"/fd", "/hd[n]", thus attributes of subfolders are set to 0x10, |
and times and dates are zeroed. An alternative way to get the |
equipment information - subfunction 11 of function 18. |
====================================================================== |
===================== Function 70, subfunction 2 ===================== |
============ Create/rewrite file with long names support. ============ |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 2 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: number of bytes to read |
* +16 = +0x10: dword: pointer to data |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = number of written bytes (possibly 0) |
Remarks: |
* If a file with given name did not exist, it is created; |
if it existed, it is rewritten. |
* If there is not enough free space on disk, the function will |
write as many as can and then return error code 8. |
* The function is not supported for CD (returns error code 2). |
====================================================================== |
===================== Function 70, subfunction 3 ===================== |
=========== Write to existing file with long names support. ========== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 3 = subfunction number |
* +4: dword: file offset (in bytes) |
* +8: dword: high dword of offset (must be 0 for FAT) |
* +12 = +0xC: dword: number of bytes to write |
* +16 = +0x10: dword: pointer to data |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx = number of written bytes (possibly 0) |
Remarks: |
* The file must already exist, otherwise function returns eax=5. |
* The only result of write 0 bytes is update in the file attributes |
date/time of modification and access to the current date/time. |
* If beginning and/or ending position is greater than file size |
(except for the previous case), the file is expanded to needed |
size with zero characters. |
* The function is not supported for CD (returns error code 2). |
====================================================================== |
============ Function 70, subfunction 4 - set end of file. =========== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 4 = subfunction number |
* +4: dword: low dword of new file size |
* +8: dword: high dword of new file size (must be 0 for FAT) |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: 0 (reserved) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Remarks: |
* If the new file size is less than old one, file is truncated. |
If the new size is greater than old one, file is expanded with |
characters with code 0. If the new size is equal to old one, |
the only result of call is set date/time of modification and |
access to the current date/time. |
* If there is not enough free space on disk for expansion, the |
function will expand to maximum possible size and then return |
error code 8. |
* The function is not supported for CD (returns error code 2). |
====================================================================== |
==== Function 70, subfunction 5 - get information on file/folder. ==== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 5 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: pointer to buffer for data (40 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Information on file is returned in the BDFE format (block of data |
for folder entry), explained in the description of |
subfunction 1, but without filename |
(i.e. only first 40 = 0x28 bytes). |
Remarks: |
* The function does not support virtual folders such as /, /rd and |
root folders like /rd/1. |
====================================================================== |
===== Function 70, subfunction 6 - set attributes of file/folder. ==== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 6 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: pointer to buffer with attributes (32 bytes) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
File attributes are first 32 bytes in BDFE (block of data |
for folder entry), explained in the description of subfunction 1 |
(that is, without name and size of file). Attribute |
file/folder/volume label (bits 3,4 in dword +0) is not changed. |
Byte +4 (name format) is ignored. |
Remarks: |
* The function does not support virtual folders such as /, /rd and |
root folders like /rd/1. |
* The function is not supported for CD (returns error code 2). |
====================================================================== |
=========== Function 70, subfunction 7 - start application. ========== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 7 = subfunction number |
* +4: dword: flags field: |
* áèò 0: start process as debugged |
* other bits are reserved and must be set to 0 |
* +8: dword: 0 or pointer to ASCIIZ-string with parameters |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: 0 (reserved) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax > 0 - program is loaded, eax contains PID |
* eax < 0 - an error has occured, -eax contains |
file system error code |
* ebx destroyed |
Remarks: |
* Command line must be terminated by the character with the code 0 |
(ASCIIZ-string); function takes into account either all characters |
up to terminating zero inclusively or first 256 character |
regarding what is less. |
* If the process is started as debugged, it is created in |
the suspended state; to run use subfunction 5 of function 69. |
====================================================================== |
========== Function 70, subfunction 8 - delete file/folder. ========== |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 8 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: 0 (reserved) |
* +20 = +0x14: ASCIIZ-name of file, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with file name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Remarks: |
* The function is not supported for CD (returns error code 2). |
* The function can delete only empty folders (attempt to delete |
nonempty folder results in error with code 10, "access denied"). |
====================================================================== |
============= Function 70, subfunction 9 - create folder. ============ |
====================================================================== |
Parameters: |
* eax = 70 - function number |
* ebx = pointer to the information structure |
Format of the information structure: |
* +0: dword: 9 = subfunction number |
* +4: dword: 0 (reserved) |
* +8: dword: 0 (reserved) |
* +12 = +0xC: dword: 0 (reserved) |
* +16 = +0x10: dword: 0 (reserved) |
* +20 = +0x14: ASCIIZ-name of folder, the rules of names forming are |
given in the general description |
or |
* +20 = +0x14: db 0 |
* +21 = +0x15: dd pointer to ASCIIZ-string with folder name |
Returned value: |
* eax = 0 - success, otherwise file system error code |
* ebx destroyed |
Remarks: |
* The function is not supported for CD (returns error code 2). |
* The parent folder must already exist. |
* If target folder already exists, function returns success (eax=0). |
====================================================================== |
========== Function 71, subfunction 1 - set window caption. ========== |
====================================================================== |
Parameters: |
* eax = 71 - function number |
* ebx = 1 - subfunction number |
* ecx = pointer to caption string |
Returned value: |
* function does not return value |
Remarks: |
* String must be in the ASCIIZ-format. Disregarding real string |
length, no more than 255 characters are drawn. |
* Pass NULL in ecx to remove caption. |
====================================================================== |
=============== Function -1 - terminate thread/process =============== |
====================================================================== |
Parameters: |
* eax = -1 - function number |
Returned value: |
* function does not return neither value nor control |
Remarks: |
* If the process did not create threads obviously, it has only |
one thread, which termination results in process termination. |
* If the current thread is last in the process, its termination |
also results in process terminates. |
* This function terminates the current thread. Other thread can be |
killed by call to subfunction 2 of function 18. |
====================================================================== |
=========================== List of events =========================== |
====================================================================== |
Next event can be retrieved by the call of one from functions 10 |
(to wait for event), 11 (to check without waiting), 23 |
(to wait during the given time). |
These functions return only those events, which enter into a mask set |
by function 40. By default it is first three, |
there is enough for most applications. |
Codes of events: |
* 1 = redraw event (is reset by call to function 0) |
* 2 = key on keyboard is pressed (acts, only when the window is |
active) or hotkey is pressed; is reset, when all keys from |
the buffer are read out by function 2 |
* 3 = button is pressed, defined earlier by function 8 |
(or close button, created implicitly by function 0; |
minimize button is handled by the system and sends no message; |
acts, only when the window is active; |
is reset when all buttons from the buffer |
are read out by function 17) |
* 4 = reserved (in current implementation never comes even after |
unmasking by function 40) |
* 5 = the desktop background is redrawed (is reset automatically |
after redraw, so if in redraw time program does not wait and |
does not check events, it will not remark this event) |
* 6 = mouse event (something happened - button pressing or moving; |
is reset at reading) |
* 7 = IPC event (see function 60 - |
Inter Process Communication; is reset at reading) |
* 8 = network event (is reset at reading) |
* 9 = debug event (is reset at reading; see |
debug subsystem) |
* 16..31 = event with appropriate IRQ |
(16=IRQ0, 31=IRQ15) (is reset after reading all IRQ data) |
====================================================================== |
=================== Error codes of the file system =================== |
====================================================================== |
* 0 = success |
* 1 = base and/or partition of a hard disk is not defined |
(by subfunctions 7, 8 of function 21) |
* 2 = function is not supported for the given file system |
* 3 = unknown file system |
* 4 = reserved, is never returned in the current implementation |
* 5 = file not found |
* 6 = end of file, EOF |
* 7 = pointer lies outside of application memory |
* 8 = disk is full |
* 9 = FAT table is destroyed |
* 10 = access denied |
* 11 = device error |
Application start functions can return also following errors: |
* 30 = 0x1E = not enough memory |
* 31 = 0x1F = file is not executable |
* 32 = 0x20 = too many processes |
/kernel/tags/kolibri0.7.0.0/docs/apm.txt |
---|
0,0 → 1,518 |
--------p-155300----------------------------- |
INT 15 - Advanced Power Management v1.0+ - INSTALLATION CHECK |
AX = 5300h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
AH = major version (BCD) |
AL = minor version (BCD) |
BX = 504Dh ("PM") |
CX = flags (see #00472) |
CF set on error |
AH = error code (06h,09h,86h) (see #00473) |
BUG: early versions of the Award Modular BIOS with built-in APM support |
reportedly do not set BX on return |
Bitfields for APM flags: |
Bit(s) Description (Table 00472) |
0 16-bit protected mode interface supported |
1 32-bit protected mode interface supported |
2 CPU idle call reduces processor speed |
3 BIOS power management disabled |
4 BIOS power management disengaged (APM v1.1) |
5-7 reserved |
(Table 00473) |
Values for APM error code: |
01h power management functionality disabled |
02h interface connection already in effect |
03h interface not connected |
04h real-mode interface not connected |
05h 16-bit protected-mode interface already connected |
06h 16-bit protected-mode interface not supported |
07h 32-bit protected-mode interface already connected |
08h 32-bit protected-mode interface not supported |
09h unrecognized device ID |
0Ah invalid parameter value in CX |
0Bh (APM v1.1) interface not engaged |
0Ch (APM v1.2) function not supported |
0Dh (APM v1.2) Resume Timer disabled |
0Eh-1Fh reserved for other interface and general errors |
20h-3Fh reserved for CPU errors |
40h-5Fh reserved for device errors |
60h can't enter requested state |
61h-7Fh reserved for other system errors |
80h no power management events pending |
81h-85h reserved for other power management event errors |
86h APM not present |
87h-9Fh reserved for other power management event errors |
A0h-FEh reserved |
FFh undefined |
--------p-155301----------------------------- |
INT 15 - Advanced Power Management v1.0+ - CONNECT REAL-MODE INTERFACE |
AX = 5301h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
CF set on error |
AH = error code (02h,05h,07h,09h) (see #00473) |
Note: on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 |
compatibility mode until it is informed that the user supports a |
newer version of APM (see AX=530Eh) |
SeeAlso: AX=5302h,AX=5303h,AX=5304h |
--------p-155302----------------------------- |
INT 15 R - Advanced Power Management v1.0+ - CONNECT 16-BIT PROTMODE INTERFACE |
AX = 5302h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
AX = real-mode segment base address of protected-mode 16-bit code |
segment |
BX = offset of entry point |
CX = real-mode segment base address of protected-mode 16-bit data |
segment |
---APM v1.1--- |
SI = APM BIOS code segment length |
DI = APM BIOS data segment length |
CF set on error |
AH = error code (02h,05h,06h,07h,09h) (see #00473) |
Notes: the caller must initialize two consecutive descriptors with the |
returned segment base addresses; these descriptors must be valid |
whenever the protected-mode interface is called, and will have |
their limits arbitrarily set to 64K. |
the protected mode interface is invoked by making a far call with the |
same register values as for INT 15; it must be invoked while CPL=0, |
the code segment descriptor must have a DPL of 0, the stack must be |
in a 16-bit segment and have enough room for BIOS use and possible |
interrupts, and the current I/O permission bit map must allow access |
to the I/O ports used for power management. |
functions 00h-03h are not available from protected mode |
on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 |
compatibility mode until it is informed that the user supports a |
newer version of APM (see AX=530Eh) |
SeeAlso: AX=5301h,AX=5303h,AX=5304h |
--------p-155303----------------------------- |
INT 15 - Advanced Power Management v1.0+ - CONNECT 32-BIT PROTMODE INTERFACE |
AX = 5303h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
AX = real-mode segment base address of protected-mode 32-bit code |
segment |
EBX = offset of entry point |
CX = real-mode segment base address of protected-mode 16-bit code |
segment |
DX = real-mode segment base address of protected-mode 16-bit data |
segment |
---APM v1.1--- |
SI = APM BIOS code segment length |
DI = APM BIOS data segment length |
CF set on error |
AH = error code (02h,05h,07h,08h,09h) (see #00473) |
Notes: the caller must initialize three consecutive descriptors with the |
returned segment base addresses for 32-bit code, 16-bit code, and |
16-bit data, respectively; these descriptors must be valid whenever |
the protected-mode interface is called, and will have their limits |
arbitrarily set to 64K. |
the protected mode interface is invoked by making a far call to the |
32-bit code segment with the same register values as for INT 15; it |
must be invoked while CPL=0, the code segment descriptor must have a |
DPL of 0, the stack must be in a 32-bit segment and have enough room |
for BIOS use and possible interrupts, and the current I/O permission |
bit map must allow access to the I/O ports used for power management. |
functions 00h-03h are not available from protected mode |
on connection, an APM v1.1 or v1.2 BIOS switches to APM v1.0 |
compatibility mode until it is informed that the user supports a |
newer version of APM (see AX=530Eh) |
SeeAlso: AX=5301h,AX=5302h,AX=5304h |
--------p-155304----------------------------- |
INT 15 - Advanced Power Management v1.0+ - DISCONNECT INTERFACE |
AX = 5304h |
BX = device ID of system BIOS (0000h) |
Return: CF clear if successful |
CF set on error |
AH = error code (03h,09h) (see #00473) |
SeeAlso: AX=5301h,AX=5302h,AX=5303h |
--------p-155305----------------------------- |
INT 15 - Advanced Power Management v1.0+ - CPU IDLE |
AX = 5305h |
Return: CF clear if successful (after system leaves idle state) |
CF set on error |
AH = error code (03h,0Bh) (see #00473) |
Notes: call when the system is idle and should be suspended until the next |
system event or interrupt |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
if an interrupt causes the system to resume normal processing, the |
interrupt may or may not have been handled when the BIOS returns |
from this call; thus, the caller should allow interrupts on return |
interrupt handlers may not retain control if the BIOS allows |
interrupts while in idle mode even if they are able to determine |
that they were called from idle mode |
the caller should issue this call continuously in a loop until it needs |
to perform some processing of its own |
SeeAlso: AX=1000h,AX=5306h,INT 2F/AX=1680h |
--------p-155306----------------------------- |
INT 15 - Advanced Power Management v1.0+ - CPU BUSY |
AX = 5306h |
Return: CF clear if successful |
CF set on error |
AH = error code (03h,0Bh) (see #00473) |
Notes: called to ensure that the system runs at full speed even on systems |
where the BIOS is unable to recognize increased activity (especially |
if interrupts are hooked by other programs and not chained to the |
BIOS) |
this call may be made even when the system is already running at full |
speed, but it will create unnecessary overhead |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
SeeAlso: AX=5305h |
--------p-155307----------------------------- |
INT 15 - Advanced Power Management v1.0+ - SET POWER STATE |
AX = 5307h |
BX = device ID (see #00474) |
CX = system state ID (see #00475) |
Return: CF clear if successful |
CF set on error |
AH = error code (01h,03h,09h,0Ah,0Bh,60h) (see #00473) |
Note: should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
SeeAlso: AX=530Ch |
(Table 00474) |
Values for APM device IDs: |
0000h system BIOS |
0001h all devices for which the system BIOS manages power |
01xxh display (01FFh for all attached display devices) |
02xxh secondary storage (02FFh for all attached secondary storage devices) |
03xxh parallel ports (03FFh for all attached parallel ports) |
04xxh serial ports (04FFh for all attached serial ports) |
---APM v1.1+ --- |
05xxh network adapters (05FFh for all attached network adapters) |
06xxh PCMCIA sockets (06FFh for all) |
0700h-7FFFh reserved |
80xxh system battery devices (APM v1.2) |
8100h-DFFFh reserved |
Exxxh OEM-defined power device IDs |
F000h-FFFFh reserved |
(Table 00475) |
Values for system state ID: |
0000h ready (not supported for device ID 0001h) |
0001h stand-by |
0002h suspend |
0003h off (not supported for device ID 0001h in APM v1.0) |
---APM v1.1--- |
0004h last request processing notification (only for device ID 0001h) |
0005h last request rejected (only for device ID 0001h) |
0006h-001Fh reserved system states |
0020h-003Fh OEM-defined system states |
0040h-007Fh OEM-defined device states |
0080h-FFFFh reserved device states |
--------p-155307CX0001----------------------- |
INT 15 - Advanced Power Management v1.0+ - SYSTEM STAND-BY |
AX = 5307h |
CX = 0001h |
BX = 0001h (device ID for all power-managed devices) |
Return: CF clear |
Notes: puts the entire system into stand-by mode; normally called in response |
to a System Stand-by Request notification after any necessary |
processing, but may also be invoked at the caller's discretion |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
the stand-by state is typically exited on an interrupt |
SeeAlso: AX=4280h,AX=5307h/CX=0002h"SUSPEND",AX=5307h/CX=0003h,AX=530Bh |
--------p-155307CX0002----------------------- |
INT 15 - Advanced Power Management v1.0+ - SUSPEND SYSTEM |
AX = 5307h |
CX = 0002h |
BX = 0001h (device ID for all power-managed devices) |
Return: after system is resumed |
CF clear |
Notes: puts the entire system into a low-power suspended state; normally |
called in response to a Suspend System Request notification after |
any necessary processing, but may also be invoked at the caller's |
discretion |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
the caller may need to update its date and time values because the |
system could have been suspended for a long period of time |
SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh |
--------p-155307CX0003----------------------- |
INT 15 - Advanced Power Management v1.2 - TURN OFF SYSTEM |
AX = 5307h |
CX = 0003h |
BX = 0001h (device ID for all power-managed devices) |
Return: after system is resumed |
CF clear |
Notes: if supported by the system's power supply, turns off the system power |
SeeAlso: AX=5307h/CX=0001h"STAND-BY",AX=530Bh |
--------p-155308----------------------------- |
INT 15 - Advanced Power Management v1.0+ - ENABLE/DISABLE POWER MANAGEMENT |
AX = 5308h |
BX = device ID for all devices power-managed by APM |
0001h (APM v1.1+) |
FFFFh (APM v1.0) |
CX = new state |
0000h disabled |
0001h enabled |
Return: CF clear if successful |
CF set on error |
AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473) |
Notes: when power management is disabled, the system BIOS will not |
automatically power down devices, enter stand-by or suspended mode, |
or perform any power-saving actions in response to AX=5305h calls |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
the APM BIOS should never be both disabled and disengaged at the same |
time |
SeeAlso: AX=5309h,AX=530Dh,AX=530Fh |
--------p-155309----------------------------- |
INT 15 - Advanced Power Management v1.0+ - RESTORE POWER-ON DEFAULTS |
AX = 5309h |
BX = device ID for all devices power-managed by APM |
0001h (APM v1.1) |
FFFFh (APM v1.0) |
Return: CF clear if successful |
CF set on error |
AH = error code (03h,09h,0Bh) (see #00473) |
Note: should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
SeeAlso: AX=5308h |
--------p-15530A----------------------------- |
INT 15 - Advanced Power Management v1.0+ - GET POWER STATUS |
AX = 530Ah |
BX = device ID |
0001h all devices power-managed by APM |
80xxh specific battery unit number XXh (01h-FFh) (APM v1.2) |
Return: CF clear if successful |
BH = AC line status |
00h off-line |
01h on-line |
02h on backup power (APM v1.1) |
FFh unknown |
other reserved |
BL = battery status (see #00476) |
CH = battery flag (APM v1.1+) (see #00477) |
CL = remaining battery life, percentage |
00h-64h (0-100) percentage of full charge |
FFh unknown |
DX = remaining battery life, time (APM v1.1) (see #00478) |
---if specific battery unit specified--- |
SI = number of battery units currently installed |
CF set on error |
AH = error code (09h,0Ah) (see #00473) |
Notes: should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
supported in real mode (INT 15) and both 16-bit and 32-bit protected |
mode |
(Table 00476) |
Values for APM v1.0+ battery status: |
00h high |
01h low |
02h critical |
03h charging |
FFh unknown |
other reserved |
SeeAlso: #00477,#00478 |
Bitfields for APM v1.1+ battery flag: |
Bit(s) Description (Table 00477) |
0 high |
1 low |
2 critical |
3 charging |
4 selected battery not present (APM v1.2) |
5-6 reserved (0) |
7 no system battery |
Note: all bits set (FFh) if unknown |
SeeAlso: #00476,#00478 |
Bitfields for APM v1.1+ remaining battery life: |
Bit(s) Description (Table 00478) |
15 time units: 0=seconds, 1=minutes |
14-0 battery life in minutes or seconds |
Note: all bits set (FFFFh) if unknown |
SeeAlso: #00476,#00477 |
--------p-15530B----------------------------- |
INT 15 - Advanced Power Management v1.0+ - GET POWER MANAGEMENT EVENT |
AX = 530Bh |
Return: CF clear if successful |
BX = event code (see #00479) |
CX = event information (APM v1.2) if BX=0003h or BX=0004h |
bit 0: PCMCIA socket was powered down in suspend state |
CF set on error |
AH = error code (03h,0Bh,80h) (see #00473) |
Notes: although power management events are often asynchronous, notification |
will not be made until polled via this call to permit software to |
only receive event notification when it is prepared to process |
power management events; since these events are not very time- |
critical, it should be sufficient to poll once or twice per second |
the critical resume notification is made after the system resumes |
from an emergency suspension; normally, the system BIOS only notifies |
its partner that it wishes to suspend and relies on the partner to |
actually request the suspension, but no notification is made on an |
emergency suspension |
should not be called from within a hardware interrupt handler to avoid |
reentrance problems |
SeeAlso: AX=5307h,AX=5307h/CX=0001h"STAND-BY",AX=5307h/CX=0002h"SUSPEND" |
(Table 00479) |
Values for APM event code: |
0001h system stand-by request |
0002h system suspend request |
0003h normal resume system notification |
0004h critical resume system notification |
0005h battery low notification |
---APM v1.1--- |
0006h power status change notification |
0007h update time notification |
0008h critical system suspend notification |
0009h user system standby request notification |
000Ah user system suspend request notification |
000Bh system standby resume notification |
---APM v1.2--- |
000Ch capabilities change notification (see AX=5310h) |
------ |
000Dh-00FFh reserved system events |
01xxh reserved device events |
02xxh OEM-defined APM events |
0300h-FFFFh reserved |
--------p-15530C----------------------------- |
INT 15 - Advanced Power Management v1.1+ - GET POWER STATE |
AX = 530Ch |
BX = device ID (see #00474) |
Return: CF clear if successful |
CX = system state ID (see #00475) |
CF set on error |
AH = error code (01h,09h) (see #00473) |
SeeAlso: AX=5307h |
--------p-15530D----------------------------- |
INT 15 - Advanced Power Management v1.1+ - EN/DISABLE DEVICE POWER MANAGEMENT |
AX = 530Dh |
BX = device ID (see #00474) |
CX = function |
0000h disable power management |
0001h enable power management |
Return: CF clear if successful |
CF set on error |
AH = error code (01h,03h,09h,0Ah,0Bh) (see #00473) |
Desc: specify whether automatic power management should be active for a |
given device |
SeeAlso: AX=5308h,AX=530Fh |
--------p-15530E----------------------------- |
INT 15 - Advanced Power Management v1.1+ - DRIVER VERSION |
AX = 530Eh |
BX = device ID of system BIOS (0000h) |
CH = APM driver major version (BCD) |
CL = APM driver minor version (BCD) (02h for APM v1.2) |
Return: CF clear if successful |
AH = APM connection major version (BCD) |
AL = APM connection minor version (BCD) |
CF set on error |
AH = error code (03h,09h,0Bh) (see #00473) |
SeeAlso: AX=5300h,AX=5303h |
--------p-15530F----------------------------- |
INT 15 - Advanced Power Management v1.1+ - ENGAGE/DISENGAGE POWER MANAGEMENT |
AX = 530Fh |
BX = device ID (see #00474) |
CX = function |
0000h disengage power management |
0001h engage power management |
Return: CF clear if successful |
CF set on error |
AH = error code (01h,09h) (see #00473) |
Notes: unlike AX=5308h, this call does not affect the functioning of the APM |
BIOS |
when cooperative power management is disengaged, the APM BIOS performs |
automatic power management of the system or device |
SeeAlso: AX=5308h,AX=530Dh |
--------p-155310----------------------------- |
INT 15 - Advanced Power Management v1.2 - GET CAPABILITIES |
AX = 5310h |
BX = device ID (see #00474) |
0000h (APM BIOS) |
other reserved |
Return: CF clear if successful |
BL = number of battery units supported (00h if no system batteries) |
CX = capabilities flags (see #00480) |
CF set on error |
AH = error code (01h,09h,86h) (see #00473) |
Notes: this function is supported via the INT 15, 16-bit protected mode, and |
32-bit protected mode interfaces; it does not require that a |
connection be established prior to use |
this function will return the capabilities currently in effect, not |
any new settings which have been made but do not take effect until |
a system restart |
SeeAlso: AX=5300h,AX=530Fh,AX=5311h,AX=5312h,AX=5313h |
Bitfields for APM v1.2 capabilities flags: |
Bit(s) Description (Table 00480) |
15-8 reserved |
7 PCMCIA Ring Indicator will wake up system from suspend mode |
6 PCMCIA Ring Indicator will wake up system from standby mode |
5 Resume on Ring Indicator will wake up system from suspend mode |
4 Resume on Ring Indicator will wake up system from standby mode |
3 resume timer will wake up system from suspend mode |
2 resume timer will wake up system from standby mode |
1 can enter global suspend state |
0 can enter global standby state |
--------p-155311----------------------------- |
INT 15 - Advanced Power Management v1.2 - GET/SET/DISABLE RESUME TIMER |
AX = 5311h |
BX = device ID (see #00474) |
0000h (APM BIOS) |
other reserved |
CL = function |
00h disable Resume Timer |
01h get Resume Timer |
02h set Resume Timer |
CH = resume time, seconds (BCD) |
DL = resume time, minutes (BCD) |
DH = resume time, hours (BCD) |
SI = resume date (BCD), high byte = month, low byte = day |
DI = resume date, year (BCD) |
Return: CF clear if successful |
---if getting timer--- |
CH = resume time, seconds (BCD) |
DL = resume time, minutes (BCD) |
DH = resume time, hours (BCD) |
SI = resume date (BCD), high byte = month, low byte = day |
DI = resume date, year (BCD) |
CF set on error |
AH = error code (03h,09h,0Ah,0Bh,0Ch,0Dh,86h) (see #00473) |
Notes: this function is supported via the INT 15, 16-bit protected mode, and |
32-bit protected mode interfaces |
SeeAlso: AX=5300h,AX=5310h,AX=5312h,AX=5313h |
--------p-155312----------------------------- |
INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE RESUME ON RING |
AX = 5312h |
BX = device ID (see #00474) |
0000h (APM BIOS) |
other reserved |
CL = function |
00h disable Resume on Ring Indicator |
01h enable Resume on Ring Indicator |
02h get Resume on Ring Indicator status |
Return: CF clear if successful |
CX = resume status (0000h disabled, 0001h enabled) |
CF set on error |
AH = error code (03h,09h,0Ah,0Bh,0Ch,86h) (see #00473) |
Notes: this function is supported via the INT 15, 16-bit protected mode, and |
32-bit protected mode interfaces |
SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5313h |
--------p-155313----------------------------- |
INT 15 - Advanced Power Management v1.2 - ENABLE/DISABLE TIMER-BASED REQUESTS |
AX = 5313h |
BX = device ID (see #00474) |
0000h (APM BIOS) |
other reserved |
CL = function |
00h disable timer-based requests |
01h enable timer-based requests |
02h get timer-based requests status |
Return: CF clear if successful |
CX = timer-based requests status (0000h disabled, 0001h enabled) |
CF set on error |
AH = error code (03h,09h,0Ah,0Bh,86h) (see #00473) |
Notes: this function is supported via the INT 15, 16-bit protected mode, and |
32-bit protected mode interfaces |
some BIOSes set AH on return even when successful |
SeeAlso: AX=5300h,AX=5310h,AX=5311h,AX=5312h |
/kernel/tags/kolibri0.7.0.0/macros.inc |
---|
0,0 → 1,99 |
__REV = 0 |
macro $Revision a { |
match =: Num =$,a \{ |
if __REV < Num |
__REV = Num |
end if |
\} |
} |
$Revision$ |
; structure definition helper |
macro struct name, [arg] |
{ |
common |
name@struct equ name |
struc name arg { |
} |
macro struct_helper name |
{ |
match xname,name |
\{ |
virtual at 0 |
xname xname |
sizeof.#xname = $ - xname |
name equ sizeof.#xname |
end virtual |
\} |
} |
ends fix } struct_helper name@struct |
;// mike.dld, 2006-29-01 [ |
; macros definition |
macro diff16 title,l1,l2 |
{ |
local s,d |
s = l2-l1 |
display title,': 0x' |
repeat 16 |
d = 48 + s shr ((16-%) shl 2) and $0F |
if d > 57 |
d = d + 65-57-1 |
end if |
display d |
end repeat |
display 13,10 |
} |
macro diff10 title,l1,l2 |
{ |
local s,d,z,m |
s = l2-l1 |
z = 0 |
m = 1000000000 |
display title,': ' |
repeat 10 |
d = '0' + s / m |
s = s - (s/m)*m |
m = m / 10 |
if d <> '0' |
z = 1 |
end if |
if z <> 0 |
display d |
end if |
end repeat |
display 13,10 |
} |
include 'kglobals.inc' |
; \begin{diamond}[29.09.2006] |
; may be useful for kernel debugging |
; example 1: |
; dbgstr 'Hello, World!' |
; example 2: |
; dbgstr 'Hello, World!', save_flags |
macro dbgstr string*, f |
{ |
local a |
iglobal_nested |
a db 'K : ',string,13,10,0 |
endg_nested |
if ~ f eq |
pushfd |
end if |
push esi |
mov esi, a |
call sys_msg_board_str |
pop esi |
if ~ f eq |
popfd |
end if |
} |
; \end{diamond}[29.09.2006] |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/vmodeld.inc |
---|
0,0 → 1,32 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; |
; Load of videomode driver in memory |
; |
; (driver is located at VMODE_BASE - 32kb) // if this area not occuped anything |
; |
; Author: Trans |
; Date: 19.07.2003 |
; |
; Include in MeOS kernel and compile with FASM |
; |
; LOAD VIDEOMODE DRIVER |
; If vmode.mdr file not found |
or eax,-1 ; Driver ID = -1 (not present in system) |
mov [VMODE_BASE],eax ; |
mov [VMODE_BASE+0x100],byte 0xC3 ; Instruction RETN - driver loop |
mov esi, vmode |
xor ebx, ebx |
mov ecx, 0x8000 ; size of memory area for driver |
mov edx, VMODE_BASE ; Memory position of driver |
xor ebp, ebp |
call fs_RamdiskRead |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/drivers/imports.inc |
---|
0,0 → 1,177 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; all exported kernel functions and data |
if used RegService |
extrn RegService |
end if |
if used GetService |
extrn GetService |
end if |
if used ServiceHandler |
extrn ServiceHandler |
end if |
if used AttachIntHandler |
extrn AttachIntHandler |
end if |
if used FpuSave |
extrn FpuSave |
end if |
if used FpuRestore |
extrn FpuRestore |
end if |
if used PciApi |
extrn PciApi |
end if |
if used PciRead32 |
extrn PciRead32 |
end if |
if used PciRead8 |
extrn PciRead8 |
end if |
if used PciWrite8 |
extrn PciWrite8 |
end if |
if used AllocPage |
extrn AllocPage |
end if |
if used AllocPages |
extrn AllocPages |
end if |
if used FreePage |
extrn FreePage |
end if |
if used MapPage |
extrn MapPage |
end if |
if used MapSpace |
extrn MapSpace |
end if |
if used GetPgAddr |
extrn GetPgAddr |
end if |
if used CommitPages |
extrn CommitPages |
end if |
if used ReleasePages |
extrn ReleasePages |
end if |
if used AllocKernelSpace |
extrn AllocKernelSpace |
end if |
if used FreeKernelSpace |
extrn FreeKernelSpace |
end if |
if used KernelAlloc |
extrn KernelAlloc |
end if |
if used KernelFree |
extrn KernelFree |
end if |
if used UserAlloc |
extrn UserAlloc |
end if |
if used UserFree |
extrn UserFree |
end if |
if used Kmalloc |
extrn Kmalloc |
end if |
if used Kfree |
extrn Kfree |
end if |
if used CreateRingBuffer |
extrn CreateRingBuffer |
end if |
if used GetPid |
extrn GetPid |
end if |
if used CreateObject |
extrn CreateObject |
end if |
if used DestroyObject |
extrn DestroyObject |
end if |
if used CreateEvent |
extrn CreateEvent |
end if |
if used RaiseEvent |
extrn RaiseEvent |
end if |
if used WaitEvent |
extrn WaitEvent |
end if |
if used DestroyEvent |
extrn DestroyEvent |
end if |
if used ClearEvent |
extrn ClearEvent |
end if |
if used LoadCursor |
extrn LoadCursor |
end if |
if used SetHwCursor |
extrn SetHwCursor |
end if |
if used HwCursorRestore |
extrn HwCursorRestore |
end if |
if used HwCursorCreate |
extrn HwCursorCreate |
end if |
if used SysMsgBoardStr |
extrn SysMsgBoardStr |
end if |
if used GetCurrentTask |
extrn GetCurrentTask |
end if |
if used LoadFile |
extrn LoadFile |
end if |
if used SendEvent |
extrn SendEvent |
end if |
if used SetMouseData |
extrn SetMouseData |
end if |
if used Sleep |
extrn Sleep |
end if |
if used GetTimerTicks |
extrn GetTimerTicks |
end if |
if used strncat |
extrn strncat |
end if |
if used strncpy |
extrn strncpy |
end if |
if used strncmp |
extrn strncmp |
end if |
if used strnlen |
extrn strnlen |
end if |
if used strchr |
extrn strchr |
end if |
if used strrchr |
extrn strrchr |
end if |
if used LFBAddress |
extrn LFBAddress |
end if |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/drivers/infinity.asm |
---|
0,0 → 1,1293 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; (C) copyright Serge 2006 |
; email: infinity_sound@mail.ru |
format MS COFF |
API_VERSION equ 0x01000100 |
SOUND_VERSION equ API_VERSION |
include 'proc32.inc' |
;include 'system.inc' |
include 'main.inc' |
include 'imports.inc' |
FORCE_MMX equ 0 ;set to 1 to force use mmx or |
FORCE_MMX_128 equ 0 ;integer sse2 extensions |
;and reduce driver size |
;USE_SSE equ 0 |
DEBUG equ 1 |
OS_BASE equ 0x80000000 |
CAPS_SSE2 equ 26 |
PG_SW equ 0x003 |
public START |
public service_proc |
public version |
RT_INP_EMPTY equ 0xFF000001 |
RT_OUT_EMPTY equ 0xFF000002 |
RT_INP_FULL equ 0xFF000003 |
RT_OUT_FULL equ 0xFF000004 |
EVENT_WATCHED equ 0x10000000 |
EVENT_SIGNALED equ 0x20000000 |
MANUAL_RESET equ 0x40000000 |
MANUAL_DESTROY equ 0x80000000 |
DEV_PLAY equ 1 |
DEV_STOP equ 2 |
DEV_CALLBACK equ 3 |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .exit |
stdcall GetService, szSound |
test eax, eax |
jz .fail |
mov [hSound], eax |
stdcall KernelAlloc, 16*512 |
test eax, eax |
jz .out_of_mem |
mov [mix_buff], eax |
mov eax, str.fd-FD_OFFSET |
mov [str.fd], eax |
mov [str.bk], eax |
if FORCE_MMX |
if FORCE_MMX_128 |
display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10 |
stop |
end if |
mov [mix_2_core], mmx_mix_2 |
mov [mix_3_core], mmx_mix_3 |
mov [mix_4_core], mmx_mix_4 |
end if |
if FORCE_MMX_128 |
if FORCE_MMX |
display 'Use only FORCE_MMX or FORCE_MMX_128 not both together',13,10 |
stop |
end if |
mov [mix_2_core], mmx128_mix_2 |
mov [mix_3_core], mmx128_mix_3 |
mov [mix_4_core], mmx128_mix_4 |
end if |
if 0 |
if ~(FORCE_MMX or FORCE_MMX_128) ;autodetect |
mov eax, 1 |
cpuid |
bt edx, CAPS_SSE2 |
jc .mmx128 |
;old 64-bit mmx |
mov [mix_2_core], mmx_mix_2 |
mov [mix_3_core], mmx_mix_3 |
mov [mix_4_core], mmx_mix_4 |
jmp @F |
.mmx128: ;128-bit integer sse2 extensions |
mov [mix_2_core], mmx128_mix_2 |
mov [mix_3_core], mmx128_mix_3 |
mov [mix_4_core], mmx128_mix_4 |
@@: |
end if |
end if |
stdcall set_handler, [hSound], new_mix |
mov [eng_state], SND_STOP |
stdcall RegService, szInfinity, service_proc |
ret |
.fail: |
if DEBUG |
mov esi, msgFail |
call SysMsgBoardStr |
end if |
.exit: |
xor eax, eax |
ret |
.out_of_mem: |
if DEBUG |
mov esi, msgMem |
call SysMsgBoardStr |
end if |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [edi+output] |
cmp [edi+out_size], 4 |
jne .fail |
mov eax, [eax] |
mov [eax], dword SOUND_VERSION |
xor eax, eax |
ret |
@@: |
cmp eax, SND_CREATE_BUFF |
jne @F |
mov ebx, [edi+input] |
push edi |
stdcall CreateBuffer,[ebx],[ebx+4] |
pop edi |
mov ecx, [edi+output] |
mov ecx, [ecx] |
mov [ecx], ebx |
ret |
@@: |
mov ebx, [edi+input] |
mov edx, [ebx] |
cmp [edx+STREAM.magic], 'WAVE' |
jne .fail |
cmp [edx+STREAM.size], STREAM_SIZE |
jne .fail |
cmp eax, SND_DESTROY_BUFF |
jne @F |
mov eax, edx |
call DestroyBuffer ;edx= stream |
ret |
@@: |
cmp eax, SND_SETFORMAT |
jne @F |
stdcall SetFormat,[ebx],[ebx+4] |
ret |
@@: |
cmp eax, SND_GETFORMAT |
jne @F |
movzx eax, word [edx+STREAM.format] |
mov ecx, [edi+output] |
mov ecx, [ecx] |
mov [ecx], eax |
xor eax, eax |
ret |
@@: |
cmp eax, SND_RESET |
jne @F |
stdcall ResetBuffer,[ebx],[ebx+4] |
ret |
@@: |
cmp eax, SND_SETPOS |
jne @F |
stdcall SetBufferPos,[ebx],[ebx+4] |
ret |
@@: |
cmp eax, SND_GETPOS |
jne @F |
push edi |
stdcall GetBufferPos, [ebx] |
pop edi |
mov ecx, [edi+output] |
mov ecx, [ecx] |
mov [ecx], ebx |
ret |
@@: |
cmp eax, SND_SETBUFF |
jne @F |
mov eax, [ebx+4] |
stdcall set_buffer, [ebx],eax,[ebx+8],[ebx+12] |
ret |
@@: |
cmp eax, SND_SETVOLUME |
jne @F |
stdcall SetBufferVol,[ebx],[ebx+4],[ebx+8] |
ret |
@@: |
cmp eax, SND_GETVOLUME |
jne @F |
mov eax, [edi+output] |
mov ecx, [eax] |
mov eax, [eax+4] |
stdcall GetBufferVol,[ebx],ecx,eax |
ret |
@@: |
cmp eax, SND_SETPAN |
jne @F |
stdcall SetBufferPan,[ebx],[ebx+4] |
ret |
@@: |
cmp eax, SND_GETPAN |
jne @F |
mov eax, [edx+STREAM.pan] |
mov ebx, [edi+output] |
mov ebx, [ebx] |
mov [ebx], eax |
xor eax, eax |
ret |
@@: |
cmp eax, SND_OUT |
jne @F |
mov eax, [ebx+4] |
stdcall wave_out, [ebx],eax,[ebx+8] |
ret |
@@: |
cmp eax, SND_PLAY |
jne @F |
stdcall play_buffer, [ebx],[ebx+4] |
ret |
@@: |
cmp eax, SND_STOP |
jne @F |
stdcall stop_buffer, [ebx] |
ret |
@@: |
cmp eax, SND_GETBUFFSIZE |
jne @F |
mov eax, [edx+STREAM.in_size] |
mov ecx, [edi+output] |
mov ecx, [ecx] |
mov [ecx], eax |
xor eax, eax |
ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc CreateBuffer stdcall, format:dword, size:dword |
locals |
str dd ? |
ring_size dd ? |
ring_pages dd ? |
endl |
mov eax, [format] |
cmp ax, PCM_1_8_8 |
ja .fail |
test eax, PCM_OUT |
jnz .test_out |
test eax, PCM_RING |
jnz .test_ring |
;staic |
test eax, PCM_OUT+PCM_RING |
jnz .fail |
jmp .test_ok |
.test_out: |
test eax, PCM_RING+PCM_STATIC |
jnz .fail |
jmp .test_ok |
.test_ring: |
test eax, PCM_OUT+PCM_STATIC |
jnz .fail |
.test_ok: |
call GetPid |
mov ebx, eax |
mov eax, STREAM_SIZE |
call CreateObject |
test eax, eax |
jz .fail |
mov [str], eax |
mov ebx, [format] |
mov [eax+STREAM.format], ebx |
xor ecx, ecx |
movzx ebx, bx |
cmp ebx, 19 |
jb @f |
mov ecx, 0x80808080 |
@@: |
mov [eax+STREAM.r_silence], ecx |
shl ebx, 2 |
lea ebx, [ebx+ebx*2] ;ebx*=12 |
mov ecx, [resampler_params+ebx] |
mov edx, [resampler_params+ebx+4] |
mov esi, [resampler_params+ebx+8] |
mov [eax+STREAM.r_size],ecx |
mov [eax+STREAM.r_dt], edx |
mov [eax+STREAM.resample], esi |
xor ecx, ecx |
mov [eax+STREAM.l_vol], ecx |
mov [eax+STREAM.r_vol], ecx |
mov dword [eax+STREAM.l_amp], 0x7FFF7FFF |
mov [eax+STREAM.pan], ecx |
test [format], PCM_STATIC |
jnz .static |
; ring and waveout |
mov ebx, 0x10000 |
test [format], PCM_RING |
jz .waveout |
mov ebx, [eax+STREAM.r_size] |
add ebx, 4095 |
and ebx, -4096 |
add ebx, ebx |
.waveout: |
mov [ring_size], ebx |
mov eax, ebx |
shr ebx, 12 |
mov [ring_pages], ebx |
stdcall CreateRingBuffer, eax, PG_SW |
if 0 |
stdcall AllocKernelSpace, eax |
end if |
mov edi, [str] |
mov ecx, [ring_size] |
mov [edi+STREAM.in_base], eax |
mov [edi+STREAM.in_size], ecx |
add eax, 128 |
sub ecx, 128 |
mov [edi+STREAM.in_wp], eax |
mov [edi+STREAM.in_rp], eax |
mov [edi+STREAM.in_count], 0 |
mov [edi+STREAM.in_free], ecx |
add eax, ecx |
mov [edi+STREAM.in_top], eax |
if 0 |
mov ebx, [ring_pages] |
stdcall AllocPages, ebx |
mov edi, [str] |
mov ebx, [edi+STREAM.in_base] |
mov ecx, [ring_pages] |
or eax, PG_SW |
push eax |
push ebx |
call CommitPages ;eax, ebx, ecx |
mov ecx, [ring_pages] |
pop ebx |
pop eax |
add ebx, [ring_size] |
call CommitPages ;double mapped |
end if |
jmp .out_buff |
.static: |
mov ecx, [size] |
add ecx, 128 ;resampler required |
mov [eax+STREAM.in_size], ecx |
stdcall KernelAlloc, ecx |
mov edi, [str] |
mov [edi+STREAM.in_base], eax |
add eax, 128 |
mov [edi+STREAM.in_wp], eax |
mov [edi+STREAM.in_rp], eax |
mov ebx, [size] |
mov [edi+STREAM.in_count], ebx |
mov [edi+STREAM.in_free], ebx |
add eax, ebx |
mov [edi+STREAM.in_top], eax |
.out_buff: |
stdcall AllocKernelSpace, dword 128*1024 |
mov edi, [str] |
mov [edi+STREAM.out_base], eax |
mov [edi+STREAM.out_wp], eax |
mov [edi+STREAM.out_rp], eax |
mov [edi+STREAM.out_count], 0 |
add eax, 64*1024 |
mov [edi+STREAM.out_top], eax |
stdcall AllocPages, dword 64/4 |
mov edi, [str] |
mov ebx, [edi+STREAM.out_base] |
mov ecx, 16 |
or eax, PG_SW |
push eax |
push ebx |
call CommitPages ;eax, ebx, ecx |
mov ecx, 16 |
pop ebx |
pop eax |
add ebx, 64*1024 |
call CommitPages ;double mapped |
mov edi, [str] |
mov ecx, [edi+STREAM.in_top] |
mov edi, [edi+STREAM.in_base] |
sub ecx, edi |
xor eax, eax |
shr ecx, 2 |
cld |
rep stosd |
mov edi, [str] |
mov edi, [edi+STREAM.out_base] |
mov ecx, (64*1024)/4 |
rep stosd |
xor edx, edx |
mov ebx, MANUAL_DESTROY |
call CreateEvent |
mov ebx, [str] |
mov [ebx+STREAM.notify_event], eax |
mov [ebx+STREAM.notify_id], edx |
mov [ebx+STREAM.magic], 'WAVE' |
mov [ebx+STREAM.destroy], DestroyBuffer.destroy |
mov [ebx+STREAM.size], STREAM_SIZE |
mov [ebx+STREAM.flags], SND_STOP |
pushf |
cli |
mov eax, str.fd-FD_OFFSET |
mov edx, [eax+STREAM.str_fd] |
mov [ebx+STREAM.str_fd], edx |
mov [ebx+STREAM.str_bk], eax |
mov [eax+STREAM.str_fd], ebx |
mov [edx+STREAM.str_bk], ebx |
popf |
xor eax, eax |
ret |
.fail: |
xor ebx, ebx |
or eax, -1 |
ret |
endp |
;param |
; eax= buffer handle |
align 4 |
DestroyBuffer: |
.handle equ esp ;local |
mov [eax+STREAM.flags], SND_STOP |
.destroy: |
push eax |
pushfd |
cli |
mov ebx, [eax+STREAM.str_fd] |
mov ecx, [eax+STREAM.str_bk] |
mov [ebx+STREAM.str_bk], ecx |
mov [ecx+STREAM.str_fd], ebx |
popf |
stdcall KernelFree, [eax+STREAM.in_base] |
mov eax, [.handle] |
stdcall KernelFree, [eax+STREAM.out_base] |
pop eax ;restore stack |
call DestroyObject ;eax= stream |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
restore .handle |
align 4 |
proc SetFormat stdcall, str:dword, format:dword |
cmp word [format], PCM_1_8_8 |
ja .fail |
mov edx, [str] |
mov [edx+STREAM.flags], SND_STOP |
test [edx+STREAM.format], PCM_RING |
jnz .fail |
; mov eax,[edx+STREAM.out_base] |
; mov [edx+STREAM.out_wp], eax |
; mov [edx+STREAM.out_rp], eax |
; mov [edx+STREAM.out_count], 0 |
movzx eax, word [format] |
mov word [edx+STREAM.format], ax |
xor ebx, ebx |
cmp eax, 19 |
jb @f |
mov ebx, 0x80808080 |
@@: |
mov [edx+STREAM.r_silence], ebx |
shl eax, 2 |
lea eax, [eax+eax*2] ;eax*=12 |
mov edi, [resampler_params+eax] |
mov ecx, [resampler_params+eax+4] |
mov ebx, [resampler_params+eax+8] |
mov [edx+STREAM.r_size],edi |
mov [edx+STREAM.r_dt], ecx |
mov [edx+STREAM.resample], ebx |
mov edi, [edx+STREAM.in_base] |
mov ecx, 128/4 |
mov eax, [edx+STREAM.r_silence] |
cld |
rep stosd |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; for static buffers only |
; use waveout for streams |
align 4 |
proc set_buffer stdcall, str:dword,src:dword,offs:dword,size:dword |
mov edx, [str] |
test [edx+STREAM.format], PCM_OUT |
jnz .fail |
mov esi, [src] |
mov edi, [offs] |
add edi, [edx+STREAM.in_base] |
add edi, 128 |
cmp edi, [edx+STREAM.in_top] |
jae .fail |
mov ecx, [size] |
lea ebx, [ecx+edi] |
sub ebx, [edx+STREAM.in_top] |
jb @F |
sub ecx, ebx |
@@: |
shr ecx, 2 |
cld |
rep movsd |
xor eax,eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; for stream buffers only |
align 4 |
proc wave_out stdcall, str:dword,src:dword,size:dword |
locals |
state_saved dd ? |
fpu_state rb 528 |
endl |
mov edx, [str] |
mov eax, [edx+STREAM.format] |
test eax, PCM_STATIC+PCM_RING |
jnz .fail |
cmp ax, PCM_ALL |
je .fail |
mov esi,[src] |
test esi, esi |
jz .fail |
cmp esi, OS_BASE |
ja .fail |
mov [state_saved], 0 |
.main_loop: |
mov edx, [str] |
mov ebx, [size] |
test ebx, ebx |
jz .done |
cmp [edx+STREAM.flags], SND_STOP |
jne .fill |
mov edi, [edx+STREAM.in_base] |
mov ecx, 128/4 |
mov eax, [edx+STREAM.r_silence] |
cld |
rep stosd |
mov ecx, [edx+STREAM.in_size] |
sub ecx, 128 |
mov [edx+STREAM.in_wp], edi |
mov [edx+STREAM.in_rp], edi |
mov [edx+STREAM.in_count], 0 |
mov [edx+STREAM.in_free], ecx |
mov eax,[edx+STREAM.out_base] |
mov [edx+STREAM.out_wp], eax |
mov [edx+STREAM.out_rp], eax |
mov [edx+STREAM.out_count], 0 |
.fill: |
mov ecx, [edx+STREAM.in_free] |
test ecx, ecx |
jz .wait |
cmp ecx, ebx |
jbe @F |
mov ecx, ebx |
@@: |
sub [size], ecx |
add [edx+STREAM.in_count], ecx |
sub [edx+STREAM.in_free], ecx |
shr ecx, 2 |
mov edi, [edx+STREAM.in_wp] |
mov esi, [src] |
cld |
rep movsd |
mov [src], esi |
cmp edi, [edx+STREAM.in_top] |
jb @F |
sub edi, [edx+STREAM.in_size] |
@@: |
mov [edx+STREAM.in_wp], edi |
cmp [edx+STREAM.out_count], 32768 |
jae .skip |
cmp [state_saved], 0 |
jne @F |
lea eax, [fpu_state+15] |
and eax, -16 |
call FpuSave |
mov [state_saved], 1 |
@@: |
stdcall refill, edx |
.skip: |
mov ebx, [str] |
mov [ebx+STREAM.flags], SND_PLAY |
cmp [eng_state], SND_PLAY |
je .main_loop |
stdcall dev_play, [hSound] |
mov [eng_state], SND_PLAY |
jmp .main_loop |
.wait: |
mov edx, [str] |
mov eax, [edx+STREAM.notify_event] |
mov ebx, [edx+STREAM.notify_id] |
call WaitEvent ;eax ebx |
jmp .main_loop |
.done: |
cmp [state_saved], 1 |
jne @F |
lea eax, [fpu_state+15] |
and eax, -16 |
call FpuRestore |
@@: |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; both static and stream |
; reset all but not clear buffers |
; flags reserved |
; RESET_INPUT equ 1 ;reserved reset and clear input buffer |
; RESET_OUTPUT equ 2 ;reserved reset and clear output buffer |
; RESET_ALL equ 3 |
align 4 |
proc ResetBuffer stdcall, str:dword, flags:dword |
mov edx, [str] |
mov [edx+STREAM.flags], SND_STOP |
mov edi, [edx+STREAM.in_base] |
mov ecx, 128/4 |
mov eax, [edx+STREAM.r_silence] |
cld |
rep stosd |
mov [edx+STREAM.in_wp], edi |
mov [edx+STREAM.in_rp], edi |
mov [edx+STREAM.in_count], 0 |
mov eax, [edx+STREAM.in_size] |
sub eax, 128 |
mov [edx+STREAM.in_free], eax |
xor eax, eax |
mov ebx,[edx+STREAM.out_base] |
mov [edx+STREAM.out_wp], ebx |
mov [edx+STREAM.out_rp], ebx |
mov [edx+STREAM.out_count], eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; for static buffers only |
align 4 |
proc SetBufferPos stdcall, str:dword, pos:dword |
mov edx, [str] |
test [edx+STREAM.format], PCM_OUT+PCM_RING |
jnz .fail |
mov [edx+STREAM.flags], SND_STOP |
mov eax, [pos] |
add eax, [edx+STREAM.in_base] |
mov ebx, [edx+STREAM.in_top] |
add eax, 128 |
cmp eax, ebx |
jae .fail |
mov [edx+STREAM.in_rp], eax |
sub ebx, eax |
mov [edx+STREAM.in_count], ebx |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
align 4 |
proc GetBufferPos stdcall, str:dword |
mov edx, [str] |
test [edx+STREAM.format], PCM_OUT+PCM_RING |
jnz .fail |
mov ebx, [edx+STREAM.in_rp] |
xor eax, eax |
ret |
.fail: |
xor ebx,ebx |
or eax, -1 |
ret |
endp |
; both |
align 4 |
proc SetBufferVol stdcall, str:dword,l_vol:dword,r_vol:dword |
mov edx, [str] |
stdcall set_vol_param,[l_vol],[r_vol],[edx+STREAM.pan] |
ret |
endp |
proc set_vol_param stdcall, l_vol:dword,r_vol:dword,pan:dword |
locals |
_600 dd ? |
_32767 dd ? |
state rb 108 |
endl |
mov [_600], 0x44160000 ;600.0 |
mov [_32767], 32767 |
lea ebx, [state] |
fnsave [ebx] |
movq mm0, qword [l_vol] |
pminsw mm0, qword [vol_max] |
pmaxsw mm0, qword [vol_min] |
movq qword [l_vol], mm0 |
movq qword [edx+STREAM.l_vol], mm0 |
movd mm1,[pan] |
pminsw mm1, qword [pan_max] |
pmaxsw mm1, qword [vol_min] |
movd [edx+STREAM.pan], mm1 |
cmp word [edx+STREAM.pan], 0 |
jl @F |
psubsw mm0,mm1 |
pminsw mm0, qword [vol_max] |
pmaxsw mm0, qword [vol_min] |
movd [l_vol],mm0 |
jmp .calc_amp |
@@: |
punpckhdq mm0,mm0 |
paddsw mm0,mm1 |
pminsw mm0, qword [vol_max] |
pmaxsw mm0, qword [vol_min] |
movd [r_vol], mm0 |
.calc_amp: |
emms |
fild word [l_vol] |
call .calc |
fistp word [edx+STREAM.l_amp] |
fstp st0 |
fild word [r_vol] |
call .calc |
fistp word [edx+STREAM.r_amp] |
fstp st0 |
fnclex |
lea ebx, [state] |
frstor [ebx] |
xor eax, eax |
inc eax |
ret |
.calc: |
fdiv dword [_600] |
fld st0 |
frndint |
fxch st1 |
fsub st, st1 |
f2xm1 |
fld1 |
faddp st1, st0 |
fscale |
fimul dword [_32767] |
ret 0 |
endp |
align 4 |
proc GetBufferVol stdcall, str:dword,p_lvol:dword,p_rvol:dword |
mov edx, [str] |
mov eax, [p_lvol] |
movsx ecx, word [edx+STREAM.l_vol] |
mov [eax], ecx |
mov eax, [p_rvol] |
movsx ecx, word [edx+STREAM.r_vol] |
mov [eax], ecx |
xor eax, eax |
ret |
endp |
align 4 |
proc SetBufferPan stdcall, str:dword,pan:dword |
mov edx, [str] |
stdcall set_vol_param,[edx+STREAM.l_vol],\ |
[edx+STREAM.r_vol],[pan] |
ret |
endp |
; for static and ring buffers only |
align 4 |
proc play_buffer stdcall, str:dword, flags:dword |
locals |
fpu_state rb 528 |
endl |
mov ebx, [str] |
mov eax, [ebx+STREAM.format] |
test eax, PCM_OUT |
jnz .fail |
cmp ax, PCM_ALL |
je .fail |
mov [ebx+STREAM.flags], SND_PLAY |
cmp [eng_state], SND_PLAY |
je .done |
stdcall dev_play, [hSound] |
mov [eng_state], SND_PLAY |
.done: |
test [flags], PLAY_SYNC |
jz @F |
mov edx, [str] |
.wait: |
mov eax, [edx+STREAM.notify_event] |
mov ebx, [edx+STREAM.notify_id] |
call WaitEvent ;eax ebx |
mov edx, [str] |
cmp [edx+STREAM.flags], SND_STOP |
jne .wait |
@@: |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; for static buffers only |
align 4 |
proc stop_buffer stdcall, str:dword |
mov edx, [str] |
test [edx+STREAM.format], PCM_STATIC+PCM_RING |
jz .fail |
mov [edx+STREAM.flags], SND_STOP |
; stdcall [ServiceHandler], [hSound], dword DEV_STOP, 0 |
mov eax, [edx+STREAM.notify_event] |
mov ebx, [edx+STREAM.notify_id] |
call ClearEvent ;eax ebx |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
; parm |
; eax= mix_list |
align 4 |
do_mix_list: |
xor edx, edx |
mov esi, str.fd-FD_OFFSET |
mov ebx, [esi+STREAM.str_fd] |
@@: |
cmp ebx, esi |
je .done |
cmp [ebx+STREAM.magic], 'WAVE' |
jne .next |
cmp [ebx+STREAM.size], STREAM_SIZE |
jne .next |
cmp [ebx+STREAM.flags], SND_PLAY; |
jne .next |
mov ecx, [ebx+STREAM.out_count] |
test ecx, ecx |
jnz .l1 |
test [ebx+STREAM.format], PCM_RING |
jnz .next |
mov [ebx+STREAM.flags], SND_STOP |
jmp .next |
.l1: |
cmp ecx, 512 |
jae .add_buff |
mov edi, [ebx+STREAM.out_rp] |
add edi, ecx |
sub ecx, 512 |
neg ecx |
push eax |
xor eax, eax |
cld |
rep stosb |
pop eax |
mov [ebx+STREAM.out_count], 512 |
.add_buff: |
mov ecx, [ebx+STREAM.out_rp] |
mov [eax],ecx |
mov edi, dword [ebx+STREAM.l_amp] |
mov [eax+4], edi |
add [ebx+STREAM.out_rp], 512 |
sub [ebx+STREAM.out_count], 512 |
add eax, 8 |
inc edx |
.next: |
mov ebx, [ebx+STREAM.str_fd] |
jmp @B |
.done: |
mov eax, edx |
ret |
align 4 |
prepare_playlist: |
xor edx, edx |
mov [play_count], edx |
mov esi, str.fd-FD_OFFSET |
mov edi, [esi+STREAM.str_fd] |
@@: |
cmp edi, esi |
je .done |
cmp [edi+STREAM.magic], 'WAVE' |
jne .next |
cmp [edi+STREAM.size], STREAM_SIZE |
jne .next |
cmp [edi+STREAM.flags], SND_PLAY; |
jne .next |
mov [play_list+edx], edi |
inc [play_count] |
add edx, 4 |
.next: |
mov edi, [edi+STREAM.str_fd] |
jmp @B |
.done: |
ret |
align 4 |
proc set_handler stdcall, hsrv:dword, handler_proc:dword |
locals |
handler dd ? |
io_code dd ? |
input dd ? |
inp_size dd ? |
output dd ? |
out_size dd ? |
val dd ? |
endl |
mov eax, [hsrv] |
lea ecx, [handler_proc] |
xor ebx, ebx |
mov [handler], eax |
mov [io_code], DEV_CALLBACK |
mov [input], ecx |
mov [inp_size], 4 |
mov [output], ebx |
mov [out_size], 0 |
lea eax, [handler] |
stdcall ServiceHandler, eax |
ret |
endp |
align 4 |
proc dev_play stdcall, hsrv:dword |
locals |
handle dd ? |
io_code dd ? |
input dd ? |
inp_size dd ? |
output dd ? |
out_size dd ? |
val dd ? |
endl |
mov eax, [hsrv] |
xor ebx, ebx |
mov [handle], eax |
mov [io_code], DEV_PLAY |
mov [input], ebx |
mov [inp_size], ebx |
mov [output], ebx |
mov [out_size], ebx |
lea eax, [handle] |
stdcall ServiceHandler, eax |
ret |
endp |
if 0 |
align 4 |
dword2str: |
mov esi, hex_buff |
mov ecx, -8 |
@@: |
rol eax, 4 |
mov ebx, eax |
and ebx, 0x0F |
mov bl, [ebx+hexletters] |
mov [8+esi+ecx], bl |
inc ecx |
jnz @B |
ret |
hexletters db '0123456789ABCDEF' |
hex_buff db 8 dup(0),13,10,0 |
end if |
include 'mixer.asm' |
include 'mix_mmx.inc' |
include 'mix_sse2.inc' |
;if USE_SSE |
; include 'mix_sse.inc' |
;end if |
align 16 |
resampler_params: |
;r_size r_dt resampler_func |
dd 0,0,0 ; 0 PCM_ALL |
dd 16384, 0, copy_stream ; 1 PCM_2_16_48 |
dd 16384, 0, m16_stereo ; 2 PCM_1_16_48 |
dd 16384, 30109, resample_2 ; 3 PCM_2_16_44 |
dd 8192, 30109, resample_1 ; 4 PCM_1_16_44 |
dd 16384, 21846, resample_2 ; 5 PCM_2_16_32 |
dd 8192, 21846, resample_1 ; 6 PCM_1_16_32 |
dd 16384, 16384, resample_2 ; 7 PCM_2_16_24 |
dd 8192, 16384, resample_1 ; 8 PCM_1_16_24 |
dd 8192, 15052, resample_2 ; 9 PCM_2_16_22 |
dd 4096, 15052, resample_1 ;10 PCM_1_16_22 |
dd 8192, 10923, resample_2 ;11 PCM_2_16_16 |
dd 4096, 10923, resample_1 ;12 PCM_1_16_16 |
dd 8192, 8192, resample_2 ;13 PCM_2_16_12 |
dd 4096, 8192, resample_1 ;14 PCM_1_16_12 |
dd 4096, 7527, resample_2 ;15 PCM_2_16_11 |
dd 2048, 7527, resample_1 ;16 PCM_1_16_11 |
dd 4096, 5462, resample_2 ;17 PCM_2_16_8 |
dd 2048, 5462, resample_1 ;18 PCM_1_16_8 |
dd 16384, 0, s8_stereo ;19 PCM_2_8_48 |
dd 8192, 0, m8_stereo ;20 PCM_1_8_48 |
dd 8192, 30109, resample_28 ;21 PCM_2_8_44 |
dd 4096, 30109, resample_18 ;22 PCM_1_8_44 |
dd 8192, 21846, resample_28 ;23 PCM_2_8_32 |
dd 4096, 21846, resample_18 ;24 PCM_1_8_32 |
dd 8192, 16384, resample_28 ;25 PCM_2_8_24 |
dd 4096, 16384, resample_18 ;26 PCM_1_8_24 |
dd 4096, 15052, resample_28 ;27 PCM_2_8_22 |
dd 2048, 15052, resample_18 ;28 PCM_1_8_22 |
dd 4096, 10923, resample_28 ;29 PCM_2_8_16 |
dd 2048, 10923, resample_18 ;30 PCM_1_8_16 |
dd 4096, 8192, resample_28 ;31 PCM_2_8_12 |
dd 2048, 8192, resample_18 ;32 PCM_1_8_12 |
dd 2048, 7527, resample_28 ;33 PCM_2_8_11 |
dd 1024, 7527, resample_18 ;34 PCM_1_8_11 |
dd 2048, 5462, resample_28 ;35 PCM_2_8_8 |
dd 1024, 5462, resample_18 ;36 PCM_1_8_8 |
m7 dw 0x8000,0x8000,0x8000,0x8000 |
mm80 dq 0x8080808080808080 |
mm_mask dq 0xFF00FF00FF00FF00 |
vol_max dd 0x00000000,0x00000000 |
vol_min dd 0x0000D8F0,0x0000D8F0 |
pan_max dd 0x00002710,0x00002710 |
;stream_map dd 0xFFFF ; 16 |
version dd (5 shl 16) or (SOUND_VERSION and 0xFFFF) |
szInfinity db 'INFINITY',0 |
szSound db 'SOUND',0 |
if DEBUG |
msgFail db 'Sound service not loaded',13,10,0 |
msgPlay db 'Play buffer',13,10,0 |
msgStop db 'Stop',13,10,0 |
msgUser db 'User callback',13,10,0 |
msgMem db 'Not enough memory',13,10,0 |
msgDestroy db 'Destroy sound buffer', 13,10,0 |
msgWaveout db 'Play waveout', 13,10,0 |
msgSetVolume db 'Set volume',13,10,0 |
end if |
section '.data' data readable writable align 16 |
play_list rd 16 |
mix_input rd 16 |
play_count rd 1 |
hSound rd 1 |
eng_state rd 1 |
mix_buff rd 1 |
mix_buff_map rd 1 |
str.fd rd 1 |
str.bk rd 1 |
mix_2_core rd 1 |
mix_3_core rd 1 |
mix_4_core rd 1 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/drivers/ps2m_irqh.inc |
---|
0,0 → 1,120 |
;************************************** |
;* IRQ HANDLER FOR PS/2 MOUSE * |
;************************************** |
proc irq_handler |
call Wait8042BufferEmpty ;clear buffer |
in al,0x60 ;get scan-code |
cmp [mouse_byte],0 |
je .byte1 |
cmp [mouse_byte],1 |
je .byte2 |
cmp [mouse_byte],2 |
je .byte3 |
cmp [mouse_byte],3 |
je .byte4 |
jmp .error |
.byte1: |
test al,1000b ;first byte? |
jz .error |
mov [first_byte],al |
inc [mouse_byte] |
jmp .exit |
.byte2: |
mov [second_byte],al |
inc [mouse_byte] |
jmp .exit |
.byte3: |
mov [third_byte],al |
cmp [MouseType],MT_3B |
je .full_packet |
inc [mouse_byte] |
jmp .exit |
.byte4: |
mov [fourth_byte],al |
.full_packet: |
mov [mouse_byte],0 |
mov al,byte [first_byte] |
and eax,7 |
mov byte [ButtonState],al |
cmp [MouseType],MT_3B |
je .xy_moving |
mov al,[fourth_byte] |
cmp [MouseType],MT_3BScroll |
je .z_moving |
mov ah,al |
and ah,00110000b |
shr ah,1 |
or byte [ButtonState],ah |
and al,00001111b |
bt eax,3 |
jnc .z_moving |
or al,11110000b |
.z_moving: |
movsx eax,al |
mov [ZMoving],eax |
.xy_moving: |
mov ah,0 |
mov al,[first_byte] |
test al,10000b |
jz @f |
mov ah,0FFh |
@@: |
mov al,[second_byte] |
cwd |
mov [XMoving],eax |
mov ah,0 |
mov al,[first_byte] |
test al,100000b |
jz @f |
mov ah,0FFh |
@@: |
mov al,[third_byte] |
cwd |
@@: |
mov [YMoving],eax |
stdcall SetMouseData, [ButtonState], [XMoving], [YMoving], [ZMoving], 0 |
jmp .exit |
.error: |
mov [mouse_byte],0 |
.exit: |
ret |
endp |
;*********************************************** |
;* Waiting for clearing I8042 buffer * |
;* Retutned state: * |
;* ZF is set - good ending, * |
;* ZF is cleared - time-out error. * |
;*********************************************** |
Wait8042BufferEmpty: |
push ecx |
xor ecx,ecx |
@@: |
in al,64h |
test al,00000010b |
loopnz @b |
pop ecx |
ret |
/kernel/tags/kolibri0.7.0.0/drivers/ps2mouse.asm |
---|
0,0 → 1,268 |
format MS COFF |
include 'proc32.inc' |
include 'imports.inc' |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
public START |
public version |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
MT_3B equ 0 |
MT_3BScroll equ 1 |
MT_5BScroll equ 2 |
PS2_DRV_VER equ 1 |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], DRV_ENTRY |
jne .fin |
.init: |
call detect_mouse |
test eax,eax |
jnz .exit |
mov [MouseType],MT_3B |
call try_mode_ID3 |
test eax,eax |
jnz .stop_try |
mov [MouseType],MT_3BScroll |
call try_mode_ID4 |
test eax,eax |
jnz .stop_try |
mov [MouseType],MT_5BScroll |
.stop_try: |
mov bl, 0x20 ; read command byte |
call kbd_cmd |
cmp ah,1 |
je .exit |
call kbd_read |
cmp ah,1 |
je .exit |
or al, 10b |
push eax |
mov bl, 0x60 ; write command byte |
call kbd_cmd |
cmp ah,1 |
je .exit |
pop eax |
call kbd_write |
cmp ah,1 |
je .exit |
mov al, 0xF4 ; enable data reporting |
call mouse_cmd |
mov bl, 0xAE ; enable keyboard interface |
call kbd_cmd |
stdcall AttachIntHandler, 12, irq_handler |
stdcall RegService, my_service, service_proc |
ret |
.fin: |
;stdcall DetachIntHandler, 12, irq_handler |
mov bl, 0xA7 ; disable mouse interface |
call kbd_cmd |
xor eax, eax |
ret |
.exit: |
mov bl, 0xA7 ; disable mouse interface |
call kbd_cmd |
mov bl, 0xAE ; enable keyboard interface |
call kbd_cmd |
xor eax, eax |
ret |
endp |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+IOCTL.io_code] |
test eax, eax |
jz .getversion |
cmp eax,1 |
jz .gettype |
.err: |
or eax, -1 |
ret |
.ok: |
xor eax, eax |
ret |
.getversion: |
cmp [edi+IOCTL.out_size], 4 |
jb .err |
mov edi, [edi+IOCTL.output] |
mov dword [edi], PS2_DRV_VER ; version of driver |
jmp .ok |
.gettype: |
cmp [edi+IOCTL.out_size], 4 |
jb .err |
mov edi, [edi+IOCTL.output] |
mov eax,[MouseType] |
mov dword [edi], eax ; mouse type |
jmp .ok |
endp |
detect_mouse: |
mov bl, 0xAD ; disable keyboard interface |
call kbd_cmd |
cmp ah,1 |
je .fail |
mov bl, 0xA8 ; enable mouse interface |
call kbd_cmd |
cmp ah,1 |
je .fail |
mov al, 0xFF ; reset |
call mouse_cmd |
jc .fail |
call mouse_read |
jc .fail |
cmp al, 0xAA |
jne .fail ; dead mouse |
; get device ID |
call mouse_read |
jc .fail |
cmp al, 0x00 |
jne .fail ; unknown device |
xor eax,eax |
ret |
.fail: |
or eax,-1 |
ret |
try_mode_ID3: |
mov al, 0xF3 ;Set Sample Rate |
call mouse_cmd |
jc .fail |
mov al, 0xC8 ;200d |
call mouse_cmd |
jc .fail |
mov al, 0xF3 ;Set Sample Rate |
call mouse_cmd |
jc .fail |
mov al, 0x64 ;100d |
call mouse_cmd |
jc .fail |
mov al, 0xF3 ;Set Sample Rate |
call mouse_cmd |
jc .fail |
mov al, 0x50 ;80d |
call mouse_cmd |
jc .fail |
mov al, 0xF2 ;Get device id |
call mouse_cmd |
jc .fail |
call mouse_read |
jc .fail |
cmp al, 0x03 |
jne .fail |
xor eax,eax |
ret |
.fail: |
or eax,-1 |
ret |
try_mode_ID4: |
mov al, 0xF3 ;Set Sample Rate |
call mouse_cmd |
jc .fail |
mov al, 0xC8 ;200d |
call mouse_cmd |
jc .fail |
mov al, 0xF3 ;Set Sample Rate |
call mouse_cmd |
jc .fail |
mov al, 0xC8 ;100d |
call mouse_cmd |
jc .fail |
mov al, 0xF3 ;Set Sample Rate |
call mouse_cmd |
jc .fail |
mov al, 0x50 ;80d |
call mouse_cmd |
jc .fail |
mov al, 0xF2 ;Get device id |
call mouse_cmd |
jc .fail |
call mouse_read |
jc .fail |
cmp al, 0x04 |
jne .fail |
xor eax,eax |
ret |
.fail: |
or eax,-1 |
ret |
include 'ps2m_iofuncs.inc' |
include 'ps2m_irqh.inc' |
section '.data' data readable writable align 16 |
version dd 0x00050005 |
my_service db 'ps2mouse',0 |
;iofuncs data |
mouse_cmd_byte db 0 |
mouse_nr_tries db 0 |
mouse_nr_resends db 0 |
;hid data |
mouse_byte dd 0 |
first_byte db 0 |
second_byte db 0 |
third_byte db 0 |
fourth_byte db 0 |
;main data |
MouseType dd 0 |
XMoving dd 0 |
YMoving dd 0 |
ZMoving dd 0 |
ButtonState dd 0 |
;timerTicks dd 0 |
/kernel/tags/kolibri0.7.0.0/drivers/ps2m_iofuncs.inc |
---|
0,0 → 1,141 |
kbd_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 |
kbd_write: |
push ecx edx |
mov dl,al |
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 |
kbd_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 |
mouse_cmd: |
mov [mouse_cmd_byte], al |
mov [mouse_nr_resends], 5 |
.resend: |
mov bl, 0xd4 |
call kbd_cmd |
cmp ah,1 |
je .fail |
mov al, [mouse_cmd_byte] |
call kbd_write |
cmp ah, 1 |
je .fail |
call mouse_read |
cmp al, 0xFA |
jne .noack |
clc |
ret |
.noack: |
cmp al, 0xFE ; resend |
jne .noresend |
dec [mouse_nr_resends] |
jnz .resend |
.noresend: |
.fail: |
stc |
ret |
mouse_read: |
mov [mouse_nr_tries], 100 |
.repeat: |
call kbd_read |
cmp ah, 1 |
jne .fin |
mov esi, 10 |
call Sleep |
dec [mouse_nr_tries] |
jnz .repeat |
stc |
ret |
.fin: |
clc |
ret |
/kernel/tags/kolibri0.7.0.0/drivers/vmode.asm |
---|
0,0 → 1,736 |
; |
; MenuetOS Driver (vmode.mdr) |
; Target: Vertical Refresh Rate programming and videomode changing |
; |
; Author: Trans <<<<<13>>>>> |
; Date: 20.07.2003 |
; |
; Version: 1.0 |
; OS: MenuetOS |
; Compiler: FASM |
; |
OS_BASE equ 0x80000000 |
use32 |
macro align value { rb (value-1) - ($ + value-1) mod value } |
org OS_BASE+0x0428000 |
headerstart=$ |
mdid db 'MDAZ' ; 4 byte id |
mdhver dd 0x00 ; header version |
mdcode dd MDSTART ; start of code |
mdver dd 0x00000001 ; driver version (subversion*65536+version) |
mdname db 'Trans VideoDriver' ; 32 bytes of full driver name |
times (32-($-mdname)) db ' ' ; |
headerlen=$-headerstart |
times (256-headerlen) db 0 ; reserved area for future |
MDSTART: ; start of driver code ( base_adr+256 bytes) |
; ebx(=ecx in program): |
; 1 - Get DriverInfo and Driver Initial Set |
; 2 - Get Current Video Mode With Vertical Refresh Rate |
; 3 - Change Video Mode |
; 4 - Return at Start System Video Mode |
; 5 - Change vertical and horizontal size of visible screen area |
; 6 - Change Vert/Hor position visible area on screen (not complete yet) |
; |
; MAXF - ... |
MAXF=5 |
;-------Main Manager------------- |
pushad |
cmp ebx,1 |
jb mdvm_00 |
cmp ebx,MAXF |
ja mdvm_00 |
shl ebx,2 |
add ebx,mdvm_func_table |
call dword [ebx] |
mov [esp+28],eax |
mov [esp+24],ecx |
mov [esp+20],edx |
mov [esp+16],ebx |
popad |
retn |
mdvm_00: |
popad |
xor eax,eax |
dec eax |
retn |
; ------Drivers Functions---------- |
align 4 |
; EBX=1 (in applications ECX=1)- Get DriverInfo and Driver Initial Set |
; |
; IN: ecx (in app. edx) - pointer to 512-bytes info area in application |
; OUT: |
; |
vm_info_init: |
push ecx |
cmp [mdrvm],dword 0 |
jnz .vmii_00 |
call vm_safe_reg |
call vm_get_initial_videomode |
mov eax,[initvm] |
mov [currvm],eax |
call vm_search_sys_func_table |
call vm_get_cur_vert_rate |
mov [initrr],eax |
call vm_calc_pixelclock |
call vm_calc_refrate |
inc [mdrvm] |
.vmii_00: |
pop ecx |
call vm_transfer_drv_info |
mov ebx,dword [refrate] |
mov eax,dword [mdid] ;dword [systlb] |
retn |
align 4 |
; EBX=2 (in applications ECX=2)- Get Current Video Mode |
; |
; OUT: eax = X_screen*65536+Y_screen |
; ebx = current vertical rate |
; ecx = current video mode (number) |
vm_get_cur_mode: |
cmp [mdrvm],dword 0 |
jz .vmgcm_00 |
call vm_get_cur_vert_rate |
mov eax,[OS_BASE+0FE00h] |
mov ebx,[OS_BASE+0FE04h] |
shl eax,16 |
add eax,ebx |
add eax,00010001h |
mov ebx,[refrate] |
mov ecx,[currvm] |
retn |
.vmgcm_00: |
xor eax,eax |
dec eax |
retn |
align 4 |
; EBX=3 (in applications ECX=3)- Change Video Mode |
; |
; IN: ecx = VertRate*65536+VideoMode |
; OUT: eax = 0 if no error |
; |
vm_set_video_mode: |
cmp [mdrvm],dword 0 |
jz .vmsvm_00 |
call vm_set_selected_mode |
; xor eax,eax |
retn |
.vmsvm_00: |
xor eax,eax |
dec eax |
retn |
align 4 |
; EBX=4 (in applications ECX=4)- Return at Start System Video Mode |
; |
; IN: |
; OUT: eax = = 0 if no error |
; |
vm_restore_init_video_mode: |
cmp [mdrvm],dword 0 |
jz .vmrivm_00 |
call vm_restore_reg |
xor eax,eax |
retn |
.vmrivm_00: |
xor eax,eax |
dec eax |
retn |
align 4 |
; EBX=5 (in applications ECX=5)- Change vertical and horizontal size |
; of visible screen area |
; IN: ecx (in app. edx) = 0/1 - -/+ horizontal size on 1 position |
; = 2/3 - -/+ vertical size on 1 position (8 pixels) |
; ^-^----- not complete yet |
; OUT: eax = = 0 if no error |
; |
vm_change_screen_size: |
cmp [mdrvm],dword 0 |
jz .vmcss_00 |
cmp cl,1 |
ja .vmcss_01 |
mov eax,ecx |
call vm_inc_dec_width |
xor eax,eax |
retn |
.vmcss_01: |
and ecx,01h |
mov eax,ecx |
; call vm_inc_dec_high ; not complete yet |
xor eax,eax |
retn |
.vmcss_00: |
xor eax,eax |
dec eax |
retn |
align 4 |
; EBX=6 (in applications ECX=6)- Change Vert/Hor position visible area on screen |
; |
; IN: ecx (in app. edx) = 0/1 - -/+ horizontal position on 1 point |
; = 2/3 - -/+ vertical position on 1 pixel |
; ^-^----- not complete yet |
; OUT: eax = 0 if no error |
; |
vm_change_position_screen: |
cmp [mdrvm],dword 0 |
jz .vmcps_00 |
; ... |
xor eax,eax |
retn |
.vmcps_00: |
xor eax,eax |
dec eax |
retn |
;-----Drivers Subfunctions--------- |
; |
; Searching i40 system functions pointer table in kernel area location |
; |
vm_search_sys_func_table: |
push eax ; eax - current value |
push ecx ; ecx - will be counter of equevalent value |
push edx ; edx - last value |
push esi ; esi - current address |
xor ecx,ecx |
mov esi,OS_BASE+010000h ; Start address of kernel location |
lodsd |
mov edx,eax |
cld |
.vmssft_00: |
cmp esi,OS_BASE+30000h |
ja .vmssft_03 |
inc ecx |
lodsd |
cmp edx,eax |
mov edx,eax |
je .vmssft_00 |
cmp ecx,128 |
ja .vmssft_02 |
.vmssft_01: |
xor ecx,ecx |
jmp .vmssft_00 |
.vmssft_02: |
cmp edx,0 |
je .vmssft_01 |
sub esi,256*4-1 |
mov [systlb],esi |
xor ecx,ecx |
.vmssft_03_0: |
inc ecx |
lodsd |
cmp edx,eax |
mov edx,eax |
jne .vmssft_03_0 |
mov esi,dword [systlb] |
cmp cx,60 |
jae .vmssft_03 |
add esi,256*4-4 |
lodsb |
mov edx,eax |
jmp .vmssft_01 |
.vmssft_03: |
mov [systlb],esi |
pop esi |
pop edx |
pop ecx |
pop eax |
retn |
; IN: |
; OUT: eax= vertical rate in Hz |
vm_get_cur_vert_rate: |
push edx |
push ebx |
xor eax,eax |
mov edx,eax |
mov ebx,eax |
mov dx,03DAh |
.vmgcvt_00: |
in al,dx |
test al,8 |
jz .vmgcvt_00 |
.vmgcvt_01: |
in al,dx |
test al,8 |
jnz .vmgcvt_01 |
mov ebx,edx |
rdtsc |
mov edx,ebx |
mov ebx,eax |
.vmgcvt_02: |
in al,dx |
test al,8 |
jz .vmgcvt_02 |
.vmgcvt_03: |
in al,dx |
test al,8 |
jnz .vmgcvt_03 |
rdtsc |
sub eax,ebx |
mov ebx,eax |
mov eax,[OS_BASE+0F600h] |
xor edx,edx |
div ebx |
inc eax |
mov [refrate],eax |
pop ebx |
pop edx |
retn |
vm_calc_pixelclock: |
push ebx |
push edx |
xor eax,eax |
mov al,[_00] |
add ax,5 |
shl eax,3 |
xor ebx,ebx |
mov bl,[_06] |
mov bh,[_07] |
and bh,00100001b |
btr bx,13 |
jnc .vmcpc_00 |
or bh,2 |
.vmcpc_00: |
xor edx,edx |
mul ebx |
xor edx,edx |
mul [initrr] |
mov [pclock],eax |
pop edx |
pop ebx |
retn |
; |
; Safe of initial CRTC state |
; |
vm_safe_reg: |
push edx |
push ebx |
push ecx |
push edi |
cli |
mov dx,3d4h ; CRTC |
mov al,11h |
out dx,al |
inc dx |
in al,dx |
and al,7fh |
out dx,al ; Clear protection bit |
dec dx |
xor ecx,ecx |
mov cl,19h |
xor bl,bl |
mov edi,CRTCreg |
.vmsr_00: |
mov al,bl |
out dx,al |
inc dx |
in al,dx |
dec dx |
stosb |
inc bl |
loop .vmsr_00 |
sti |
pop edi |
pop ecx |
pop ebx |
pop edx |
retn |
; |
; Restore of initial CRTC state |
; |
vm_restore_reg: |
push eax |
push ebx |
push edx |
push esi |
mov eax,[oldX] |
mov [OS_BASE+0FE00h],eax |
mov eax,[oldY] |
mov [OS_BASE+0FE04h],eax |
mov dx,03dah |
.vmrr_00: |
in al,dx |
test al,8 |
jnz .vmrr_00 |
.vmrr_01: |
in al,dx |
test al,8 |
jnz .vmrr_01 |
cli |
mov dx,03c4h |
mov ax,0101h |
out dx,ax |
mov dx,3d4h ; CRTC |
mov al,11h |
out dx,al |
inc dx |
in al,dx |
and al,7fh ; Clear Protection bit |
out dx,al |
dec dx |
xor ecx,ecx |
mov cl,19h |
mov esi,CRTCreg |
xor bl,bl |
.vmrr_02: |
lodsb |
mov ah,al |
mov al,bl |
out dx,ax |
inc bl |
loop .vmrr_02 |
sti |
; call ref_screen |
pop esi |
pop edx |
pop ecx |
pop eax |
retn |
; Calculate of possible vertical refrash rate |
; (light version of function) |
vm_calc_refrate: |
push ebx |
push ecx |
push edx |
push edi |
push esi |
mov eax,[pclock] |
xor edx,edx |
mov edi,_m1 |
mov ebx,eax |
mov ecx,(1696*1065) |
div ecx |
xor edx,edx |
stosw |
add edi,8 |
mov eax,ebx |
mov ecx,(1344*804) |
div ecx |
xor edx,edx |
stosw |
add edi,8 |
mov eax,ebx |
mov ecx,(1056*636) |
div ecx |
xor edx,edx |
stosw |
add edi,8 |
mov eax,ebx |
mov ecx,(800*524) |
div ecx |
xor edx,edx |
stosw |
mov edi,_m1 |
mov esi,edi |
mov ecx,5*4 |
.vmcrr_00: |
lodsw |
cmp ax,55 |
jb .vmcrr_01 |
stosw |
loop .vmcrr_00 |
pop esi |
pop edi |
pop edx |
pop ecx |
pop ebx |
retn |
.vmcrr_01: |
xor ax,ax |
stosw |
loop .vmcrr_00 |
pop esi |
pop edi |
pop edx |
pop ecx |
pop ebx |
retn |
vm_get_initial_videomode: |
push eax |
mov eax,dword [OS_BASE+0FE00h] |
mov [oldX],eax |
mov eax,dword [OS_BASE+0FE04h] |
mov [oldY],eax |
mov eax,dword [OS_BASE+0FE0Ch] ; initial video mode |
and ax,01FFh |
mov dword [initvm],eax |
pop eax |
retn |
; IN: eax = 0/1 - -/+ 1 position of width |
vm_inc_dec_width: |
push ebx |
push edx |
mov ebx,eax |
mov dx,3d4h ; CRTC |
mov al,11h |
out dx,al |
inc dx |
in al,dx |
and al,7fh ; Clear Protection bit |
out dx,al |
dec dx |
xor al,al |
out dx,al |
inc dx |
in al,dx |
dec al |
cmp bl,0 |
jnz .vmidr_00 |
inc al |
inc al |
.vmidr_00: |
out dx,al |
pop edx |
pop ebx |
retn |
; |
; Copy driver info to application area |
; |
; IN: ecx (in app. edx) - pointer to 512-bytes info area in application |
; OUT: |
vm_transfer_drv_info: |
push ecx |
push edi |
push esi |
mov eax,ecx |
xor ecx,ecx |
mov cl,32/4 |
mov esi,mdname |
mov edi,drvname |
rep movsd |
mov ecx,eax |
mov eax,[mdver] |
mov [drvver],eax |
mov edi,[OS_BASE+3010h] |
mov edi,[edi+10h] |
add edi,ecx |
mov esi,drvinfo |
xor ecx,ecx |
mov cx,512 |
rep movsb |
pop esi |
pop edi |
pop ecx |
retn |
; |
; Set selected video mode |
; (light version) |
; |
; IN: ecx = VertRate*65536+VideoMode |
; |
vm_set_selected_mode: |
push edx |
push ecx |
push esi |
ror ecx,16 |
cmp cx,00h |
je .vmssm_03 |
rol ecx,16 |
mov eax,ecx |
shl eax,16 |
shr eax,16 |
mov [currvm],eax |
cmp cx,112h |
jne .vmssm_00 |
mov esi,mode0 |
mov ecx,639 |
mov edx,479 |
jmp .vmssm_st00 |
.vmssm_00: |
cmp cx,115h |
jne .vmssm_01 |
mov esi,mode1 |
mov ecx,799 |
mov edx,599 |
jmp .vmssm_st00 |
.vmssm_01: |
cmp cx,118h |
jne .vmssm_02 |
mov esi,mode2 |
mov ecx,1023 |
mov edx,767 |
jmp .vmssm_st00 |
.vmssm_02: |
cmp cx,11Bh |
jne .vmssm_03 |
mov esi,mode2 |
mov ecx,1279 |
mov edx,1023 |
jmp .vmssm_st00 |
.vmssm_03: |
xor eax,eax |
dec eax |
pop esi |
pop ecx |
pop edx |
retn |
.vmssm_st00: |
mov [OS_BASE+0FE00h],ecx |
mov [OS_BASE+0FE04h],edx |
cli |
mov dx,03c4h |
lodsw |
out dx,ax |
mov dx,03d4h |
mov al,11h |
out dx,al |
inc dx |
in al,dx |
and al,7fh |
out dx,al |
dec dx |
mov ecx,13 |
.vmssm_st01: |
lodsw |
out dx,ax |
loop .vmssm_st01 |
sti |
xor eax,eax |
pop esi |
pop ecx |
pop edx |
retn |
;------------DATA AREA--------------- |
align 4 |
mdvm_func_table: |
dd MDSTART |
dd vm_info_init, vm_get_cur_mode |
dd vm_set_video_mode, vm_restore_init_video_mode |
dd vm_change_screen_size, vm_change_position_screen |
CRTCreg: |
_00 db ? |
_01 db ? |
_02 db ? |
_03 db ? |
_04 db ? |
_05 db ? |
_06 db ? |
_07 db ? |
_08 db ? |
_09 db ? |
_0a db ? |
_0b db ? |
_0c db ? |
_0d db ? |
_0e db ? |
_0f db ? |
_10 db ? |
_11 db ? |
_12 db ? |
_13 db ? |
_14 db ? |
_15 db ? |
_16 db ? |
_17 db ? |
_18 db ? |
_19 db ? |
align 4 |
oldX dd ? |
oldY dd ? |
initvm dd ? |
currvm dd 0 |
refrate dd 0 |
initrr dd 0 |
systlb dd 0 |
pclock dd ? |
mdrvm dd 0 ; 0 - not drv init yet, 1 - already drv init |
drvinfo: |
drvname: times 32 db ' ' |
drvver dd 0 |
times (32-($-drvver))/4 dd 0 |
drvmode dw 011Bh,0118h,0115h,0112h |
times (64-($-drvmode))/2 dw 00h |
_m1 dw 0,0,0,0,0 |
_m2 dw 0,0,0,0,0 |
_m3 dw 0,0,0,0,0 |
_m4 dw 0,0,0,0,0 |
_m5 dw 0,0,0,0,0 |
times (512-($-drvinfo)) db 0 |
drvinfoend: |
;1280x1024 - 11Bh |
mode3: |
dw 0101h |
dw 0d000h,9f01h,9f02h,9303h,0a904h,1905h,2806h,5a07h |
dw 0110h,8411h,0ff12h,0ff15h,2916h |
;1024x768 - 118h |
mode2: |
dw 0101h |
dw 0a400h,7f01h,7f02h,8703h,8404h,9505h,2406h,0f507h |
dw 0310h,8911h,0ff12h,0ff15h,2516h |
;800x600 - 115h |
mode1: |
dw 0101h |
dw 8000h,6301h,6302h,8303h,6a04h,1a05h,7206h,0f007h |
dw 5910h,8d11h,5712h,5715h,7316h |
;640x480 - 112h, 12h |
mode0: |
dw 0101h |
dw 6000h,4f01h,4f02h,8303h,5304h,9f05h,00b06h,3e07h |
dw 0ea10h,8c11h,0df12h,0df15h,0c16h |
; 640x400 |
;mymode0: |
; dw 0101h |
;_0_7 dw 5f00h,4f01h,4f02h,8303h,5304h,9f05h,0BF06h,1f07h |
; dw 9c10h,8e11h,8f12h,9615h,0B916h ;,4013h |
; 640x800 |
;mymode1: |
; dw 0101h |
; dw 5f00h,4f01h,4f02h,8003h,5004h,9f05h,06006h,0FF07h |
; dw 2d10h,8f11h,2012h,2615h,05716h ;,4013h |
DRVM_END: |
/kernel/tags/kolibri0.7.0.0/drivers/ati2d.asm |
---|
0,0 → 1,1018 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
format MS COFF |
include 'proc32.inc' |
include 'imports.inc' |
API_VERSION equ 0x01000100 |
DEBUG equ 1 |
VID_ATI equ 0x1002 |
LOAD_FROM_FILE equ 0 |
LOAD_FROM_MEM equ 1 |
LOAD_INDIRECT equ 2 |
LOAD_SYSTEM equ 3 |
SRV_GETVERSION equ 0 |
struc BITMAPINFOHEADER { |
.biSize dd ? ; DWORD |
.biWidth dd ? ; LONG |
.biHeight dd ? ; LONG |
.biPlanes dw ? ; WORD |
.biBitCount dw ? ; WORD |
.biCompression dd ? ; DWORD |
.biSizeImage dd ? ; DWORD |
.biXPelsPerMeter dd ? ; LONG |
.biYPelsPerMeter dd ? ; LONG |
.biClrUsed dd ? ; DWORD |
.biClrImportant dd ? ; DWORD |
} |
virtual at 0 |
BI BITMAPINFOHEADER |
end virtual |
struc CURSOR |
{;common object header |
.magic dd ? ;'CURS' |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
;cursor data |
.base dd ? ;allocated memory |
.hot_x dd ? ;hotspot coords |
.hot_y dd ? |
} |
virtual at 0 |
CURSOR CURSOR |
end virtual |
CURSOR_SIZE equ 32 |
R8500 equ 0x514C ;R200 |
R9000 equ 0x4966 ;RV250 |
R9200 equ 0x5961 ;RV280 |
R9500 equ 0x4144 ;R300 |
R9500P equ 0x4E45 ;R300 |
R9550 equ 0x4153 ;RV350 |
R9600 equ 0x4150 ;RV350 |
R9600XT equ 0x4152 ;RV360 |
R9700P equ 0x4E44 ;R300 |
R9800 equ 0x4E49 ;R350 |
R9800P equ 0x4E48 ;R350 |
R9800XT equ 0x4E4A ;R360 |
OS_BASE equ 0x80000000 |
SLOT_BASE equ (OS_BASE+0x0080000) |
PG_SW equ 0x003 |
PG_NOCACHE equ 0x018 |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
;MMIO equ 0F9000000h |
RD_RB3D_CNTL equ 1c3ch |
RD_MEM_CNTL equ 0140h |
RD_CRTC_GEN_CNTL equ 0050h |
RD_CRTC_CUR_EN equ 10000h |
RD_DISPLAY_BASE_ADDR equ 023ch |
RD_DEFAULT_OFFSET equ 16e0h |
CUR_HORZ_VERT_OFF equ 0268h |
CUR_HORZ_VERT_POSN equ 0264h |
CUR_OFFSET equ 0260h |
RD_RB3D_CNTL equ 1c3ch |
RD_RBBM_STATUS equ 0e40h |
RD_RBBM_FIFOCNT_MASK equ 007fh |
RD_RBBM_ACTIVE equ 80000000h |
RD_TIMEOUT equ 2000000 |
RD_DP_GUI_MASTER_CNTL equ 0146ch |
RD_DP_BRUSH_BKGD_CLR equ 01478h |
RD_DP_BRUSH_FRGD_CLR equ 0147ch |
RD_DP_SRC_BKGD_CLR equ 015dch |
RD_DP_SRC_FRGD_CLR equ 015d8h |
RD_DP_CNTL equ 016c0h |
RD_DP_DATATYPE equ 016c4h |
RD_DP_WRITE_MASK equ 016cch |
RD_DP_SRC_SOURCE_MEMORY equ (2 shl 24) |
RD_DP_SRC_SOURCE_HOST_DATA equ (3 shl 24) |
RD_DEFAULT_SC_BOTTOM_RIGHT equ 16e8h |
RD_GMC_BRUSH_SOLID_COLOR equ (13 shl 4) |
RD_DEFAULT_SC_RIGHT_MAX equ 1fffh |
RD_DEFAULT_SC_BOTTOM_MAX equ 1fff0000h |
RD_GMC_DST_DATATYPE_SHIFT equ 8 |
RD_ROP3_S equ 00cc0000h |
RD_ROP3_P equ 00f00000h |
RD_RB2D_DSTCACHE_MODE equ 03428h |
RD_RB2D_DSTCACHE_CTLSTAT equ 0342ch |
RD_RB2D_DC_FLUSH_ALL equ 000fh |
RD_RB2D_DC_BUSY equ 80000000h |
RD_GMC_BRUSH_SOLID_COLOR equ 000000D0h |
RD_GMC_SRC_DATATYPE_COLOR equ (3 shl 12) |
RD_GMC_CLR_CMP_CNTL_DIS equ (1 shl 28) |
RD_GMC_WR_MSK_DIS equ (1 shl 30) |
cmdSolidFill equ 73f036d0h |
RD_DST_PITCH_OFFSET equ 142ch |
RD_SRC_PITCH_OFFSET equ 1428h |
RD_DST_X_LEFT_TO_RIGHT equ 1 |
RD_DST_Y_TOP_TO_BOTTOM equ 2 |
RD_DST_Y_X equ 1438h |
RD_DST_WIDTH_HEIGHT equ 1598h |
RD_DST_LINE_START equ 1600h |
RD_DST_LINE_END equ 1604h |
R300_MEM_NUM_CHANNELS_MASK equ 0003h |
macro rdr op1, op2 |
{ |
mov edi, [ati_io] |
mov op1, [edi+op2] |
} |
macro wrr dest, src |
{ |
mov edi, [ati_io] |
mov dword [edi+dest], src |
} |
public START |
public service_proc |
public version |
CURSOR_IMAGE_OFFSET equ 0x00500000 |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .exit |
if DEBUG |
mov esi, msgInit |
call SysMsgBoardStr |
end if |
call detect_ati |
test eax, eax |
jz .fail |
call init_ati |
test eax, eax |
jz .fail |
or eax, -1 |
mov [cursor_map], eax |
mov [cursor_map+4], eax |
mov edx, cursor_map |
mov [cursor_start], edx |
add edx, 8 |
mov [cursor_end], edx |
stdcall RegService, sz_ati_srv, service_proc |
test eax, eax |
jz .fail |
mov dword [SetHwCursor], drvCursorPos ;enable hardware cursor |
mov dword [HwCursorRestore], drv_restore |
mov dword [HwCursorCreate], ati_cursor |
ret |
.fail: |
if DEBUG |
mov esi, msgFail |
call SysMsgBoardStr |
end if |
.exit: |
xor eax, eax |
; mov ebx, SetHwCursor |
; mov dword [ebx], eax ;force disable hardware cursor |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov ebx, [ioctl] |
cmp [ebx+io_code], SRV_GETVERSION |
jne .fail |
mov eax, [ebx+output] |
cmp [ebx+out_size], 4 |
jne .fail |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc detect_ati |
locals |
last_bus dd ? |
endl |
xor eax, eax |
mov [bus], eax |
inc eax |
call PciApi |
cmp eax, -1 |
je .err |
mov [last_bus], eax |
.next_bus: |
and [devfn], 0 |
.next_dev: |
stdcall PciRead32, [bus], [devfn], dword 0 |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
mov edi, devices |
@@: |
mov ebx, [edi] |
test ebx, ebx |
jz .next |
cmp eax, ebx |
je .found |
add edi, 4 |
jmp @B |
.next: |
inc [devfn] |
cmp [devfn], 256 |
jb .next_dev |
mov eax, [bus] |
inc eax |
mov [bus], eax |
cmp eax, [last_bus] |
jna .next_bus |
xor eax, eax |
ret |
.found: |
xor eax, eax |
inc eax |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc init_ati |
stdcall AllocKernelSpace, dword 0x10000 |
test eax, eax |
jz .fail |
mov [ati_io], eax |
stdcall PciRead32, [bus], [devfn], dword 0x18 |
and eax, 0xFFFF0000 |
mov esi, eax |
mov edi, [ati_io] |
mov edx, 16 |
@@: |
stdcall MapPage,edi,esi,PG_SW+PG_NOCACHE |
add edi, 0x1000 |
add esi, 0x1000 |
dec edx |
jnz @B |
mov edi, [ati_io] |
mov dword [edi+RD_RB3D_CNTL], 0 |
call engRestore |
mov edi, [ati_io] |
mov eax, [edi+0x50] |
mov ebx,3 |
shl ebx,20 |
not ebx |
and eax,ebx |
mov ebx, 2 |
shl ebx,20 |
or eax, ebx |
mov [edi+0x50], eax |
call drvShowCursor |
xor eax, eax |
inc eax |
.fail: |
ret |
endp |
align 4 |
drv_restore: |
ret 8 |
align 4 |
drvShowCursor: |
mov edi, [ati_io] |
mov eax, [edi+RD_CRTC_GEN_CNTL] |
bts eax,16 |
mov [edi+RD_CRTC_GEN_CNTL], eax |
ret |
align 4 |
proc drvCursorPos stdcall, hcursor:dword, x:dword, y:dword |
pushfd |
cli |
xor eax, eax |
xor edx, edx |
mov esi, [hcursor] |
mov ebx, [x] |
mov ecx, [y] |
sub ebx, [esi+CURSOR.hot_x] |
jnc @F |
neg ebx |
mov eax, ebx |
shl eax, 16 |
xor ebx, ebx |
@@: |
sub ecx, [esi+CURSOR.hot_y] |
jnc @F |
neg ecx |
mov ax, cx |
mov edx, ecx |
xor ecx, ecx |
@@: |
or eax, 0x80000000 |
wrr CUR_HORZ_VERT_OFF, eax |
shl ebx, 16 |
mov bx, cx |
or ebx, 0x80000000 |
wrr CUR_HORZ_VERT_POSN, ebx |
shl edx, 8 |
add edx, [esi+CURSOR.base] |
sub edx, LFBAddress |
wrr CUR_OFFSET, edx |
popfd |
ret |
endp |
align 4 |
proc video_alloc |
pushfd |
cli |
mov ebx, [cursor_start] |
mov ecx, [cursor_end] |
.l1: |
bsf eax,[ebx]; |
jnz .found |
add ebx,4 |
cmp ebx, ecx |
jb .l1 |
popfd |
xor eax,eax |
ret |
.found: |
btr [ebx], eax |
popfd |
mov [cursor_start],ebx |
sub ebx, cursor_map |
lea eax,[eax+ebx*8] |
shl eax,14 |
add eax, LFBAddress+CURSOR_IMAGE_OFFSET |
ret |
endp |
align 4 |
video_free: |
pushfd |
cli |
sub eax, LFBAddress+CURSOR_IMAGE_OFFSET |
shr eax, 14 |
mov ebx, cursor_map |
bts [ebx], eax |
shr eax, 3 |
and eax, not 3 |
add eax, ebx |
cmp [cursor_start], eax |
ja @f |
popfd |
ret |
@@: |
mov [cursor_start], eax |
popfd |
ret |
; param |
; eax= pid |
; ebx= src |
; ecx= flags |
align 4 |
ati_cursor: |
.src equ esp |
.flags equ esp+4 |
.hcursor equ esp+8 |
sub esp, 4 ;space for .hcursor |
push ecx |
push ebx |
mov ebx, eax |
mov eax, CURSOR_SIZE |
call CreateObject |
test eax, eax |
jz .fail |
mov [.hcursor],eax |
xor ebx, ebx |
mov [eax+CURSOR.magic], 'CURS' |
mov [eax+CURSOR.destroy], destroy_cursor |
mov [eax+CURSOR.hot_x], ebx |
mov [eax+CURSOR.hot_y], ebx |
call video_alloc |
mov edi, [.hcursor] |
mov [edi+CURSOR.base], eax |
mov esi, [.src] |
mov ebx, [.flags] |
cmp bx, LOAD_INDIRECT |
je .indirect |
movzx ecx, word [esi+10] |
movzx edx, word [esi+12] |
mov [edi+CURSOR.hot_x], ecx |
mov [edi+CURSOR.hot_y], edx |
stdcall ati_init_cursor, eax, esi |
mov eax, [.hcursor] |
.fail: |
add esp, 12 |
ret |
.indirect: |
shr ebx, 16 |
movzx ecx, bh |
movzx edx, bl |
mov [edi+CURSOR.hot_x], ecx |
mov [edi+CURSOR.hot_y], edx |
mov edi, eax |
mov ebx, eax |
mov ecx, 64*64 |
xor eax,eax |
cld |
rep stosd |
mov edi, ebx |
mov esi, [.src] |
mov ebx, 32 |
cld |
@@: |
mov ecx, 32 |
rep movsd |
add edi, 128 |
dec ebx |
jnz @B |
mov eax, [.hcursor] |
add esp, 12 |
ret |
align 4 |
destroy_cursor: |
push eax |
mov eax, [eax+CURSOR.base] |
call video_free |
pop eax |
call DestroyObject |
ret |
align 4 |
proc ati_init_cursor stdcall, dst:dword, src:dword |
locals |
rBase dd ? |
pQuad dd ? |
pBits dd ? |
pAnd dd ? |
width dd ? |
height dd ? |
counter dd ? |
endl |
mov esi, [src] |
add esi,[esi+18] |
mov eax,esi |
cmp [esi+BI.biBitCount], 24 |
je .img_24 |
cmp [esi+BI.biBitCount], 8 |
je .img_8 |
cmp [esi+BI.biBitCount], 4 |
je .img_4 |
.img_2: |
add eax, [esi] |
mov [pQuad],eax |
add eax,8 |
mov [pBits],eax |
add eax, 128 |
mov [pAnd],eax |
mov eax,[esi+4] |
mov [width],eax |
mov ebx,[esi+8] |
shr ebx,1 |
mov [height],ebx |
mov edi, pCursor |
add edi, 32*31*4 |
mov [rBase],edi |
mov esi,[pQuad] |
.l21: |
mov ebx, [pBits] |
mov ebx, [ebx] |
bswap ebx |
mov eax, [pAnd] |
mov eax, [eax] |
bswap eax |
mov [counter], 32 |
@@: |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
xor ecx, ecx |
shl ebx,1 |
setc cl |
mov ecx, [esi+ecx*4] |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi], edx |
add edi, 4 |
dec [counter] |
jnz @B |
add [pBits], 4 |
add [pAnd], 4 |
mov edi,[rBase] |
sub edi,128 |
mov [rBase],edi |
sub [height],1 |
jnz .l21 |
jmp .copy |
.img_4: |
add eax, [esi] |
mov [pQuad],eax |
add eax,64 |
mov [pBits],eax |
add eax, 0x200 |
mov [pAnd],eax |
mov eax,[esi+4] |
mov [width],eax |
mov ebx,[esi+8] |
shr ebx,1 |
mov [height],ebx |
mov edi, pCursor |
add edi, 32*31*4 |
mov [rBase],edi |
mov esi,[pQuad] |
mov ebx, [pBits] |
.l4: |
mov eax, [pAnd] |
mov eax, [eax] |
bswap eax |
mov [counter], 16 |
@@: |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
movzx ecx, byte [ebx] |
and cl, 0xF0 |
shr ecx, 2 |
mov ecx, [esi+ecx] |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi], edx |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
movzx ecx, byte [ebx] |
and cl, 0x0F |
mov ecx, [esi+ecx*4] |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi+4], edx |
inc ebx |
add edi, 8 |
dec [counter] |
jnz @B |
add [pAnd], 4 |
mov edi,[rBase] |
sub edi,128 |
mov [rBase],edi |
sub [height],1 |
jnz .l4 |
jmp .copy |
.img_8: |
add eax, [esi] |
mov [pQuad],eax |
add eax,1024 |
mov [pBits],eax |
add eax, 1024 |
mov [pAnd],eax |
mov eax,[esi+4] |
mov [width],eax |
mov ebx,[esi+8] |
shr ebx,1 |
mov [height],ebx |
mov edi, pCursor |
add edi, 32*31*4 |
mov [rBase],edi |
mov esi,[pQuad] |
mov ebx, [pBits] |
.l81: |
mov eax, [pAnd] |
mov eax, [eax] |
bswap eax |
mov [counter], 32 |
@@: |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
movzx ecx, byte [ebx] |
mov ecx, [esi+ecx*4] |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi], edx |
inc ebx |
add edi, 4 |
dec [counter] |
jnz @B |
add [pAnd], 4 |
mov edi,[rBase] |
sub edi,128 |
mov [rBase],edi |
sub [height],1 |
jnz .l81 |
jmp .copy |
.img_24: |
add eax, [esi] |
mov [pQuad],eax |
add eax, 0xC00 |
mov [pAnd],eax |
mov eax,[esi+BI.biWidth] |
mov [width],eax |
mov ebx,[esi+BI.biHeight] |
shr ebx,1 |
mov [height],ebx |
mov edi, pCursor |
add edi, 32*31*4 |
mov [rBase],edi |
mov esi,[pAnd] |
mov ebx, [pQuad] |
.row_24: |
mov eax, [esi] |
bswap eax |
mov [counter], 32 |
@@: |
xor edx, edx |
shl eax,1 |
setc dl |
dec edx |
mov ecx, [ebx] |
and ecx, 0x00FFFFFF |
and ecx, edx |
and edx, 0xFF000000 |
or edx, ecx |
mov [edi], edx |
add ebx, 3 |
add edi, 4 |
dec [counter] |
jnz @B |
add esi, 4 |
mov edi,[rBase] |
sub edi,128 |
mov [rBase],edi |
sub [height],1 |
jnz .row_24 |
.copy: |
mov edi, [dst] |
mov ecx, 64*64 |
xor eax,eax |
rep stosd |
mov esi, pCursor |
mov edi, [dst] |
mov ebx, 32 |
cld |
@@: |
mov ecx, 32 |
rep movsd |
add edi, 128 |
dec ebx |
jnz @B |
ret |
endp |
align 4 |
proc engFlush |
mov edi, [ati_io] |
mov eax, [edi+RD_RB2D_DSTCACHE_CTLSTAT] |
or eax,RD_RB2D_DC_FLUSH_ALL |
mov [edi+RD_RB2D_DSTCACHE_CTLSTAT],eax |
mov ecx, RD_TIMEOUT |
@@: |
mov eax,[edi+RD_RB2D_DSTCACHE_CTLSTAT] |
and eax, RD_RB2D_DC_BUSY |
jz .exit |
sub ecx,1 |
jnz @B |
.exit: |
ret |
endp |
align 4 |
engWaitForFifo: |
cnt equ bp+8 |
push ebp |
mov ebp, esp |
mov edi, [ati_io] |
mov ecx, RD_TIMEOUT |
@@: |
mov eax, [edi+RD_RBBM_STATUS] |
and eax, RD_RBBM_FIFOCNT_MASK |
cmp eax, [ebp+8] |
jae .exit |
sub ecx,1 |
jmp @B |
.exit: |
leave |
ret 4 |
align 4 |
proc engWaitForIdle |
push dword 64 |
call engWaitForFifo |
mov edi, [ati_io] |
mov ecx ,RD_TIMEOUT |
@@: |
mov eax, [edi+RD_RBBM_STATUS] |
and eax,RD_RBBM_ACTIVE |
jz .exit |
sub ecx,1 |
jnz @B |
.exit: |
call engFlush |
ret |
endp |
align 4 |
proc engRestore |
; push dword 1 |
; call engWaitForFifo |
; mov dword [MMIO+RD_RB2D_DSTCACHE_MODE], 0 |
push dword 3 |
call engWaitForFifo |
mov edi, [ati_io] |
mov eax, [edi+RD_DISPLAY_BASE_ADDR] |
shr eax, 10d |
or eax,(64d shl 22d) |
mov [edi+RD_DEFAULT_OFFSET],eax |
mov [edi+RD_SRC_PITCH_OFFSET],eax |
mov [edi+RD_DST_PITCH_OFFSET],eax |
push dword 1 |
call engWaitForFifo |
mov edi, [ati_io] |
mov eax, [edi+RD_DP_DATATYPE] |
btr eax, 29d |
mov [edi+RD_DP_DATATYPE],eax |
push dword 1 |
call engWaitForFifo |
mov edi, [ati_io] |
mov dword [edi+RD_DEFAULT_SC_BOTTOM_RIGHT],\ |
(RD_DEFAULT_SC_RIGHT_MAX or RD_DEFAULT_SC_BOTTOM_MAX) |
push dword 1 |
call engWaitForFifo |
mov edi, [ati_io] |
mov dword [edi+RD_DP_GUI_MASTER_CNTL],\ |
(RD_GMC_BRUSH_SOLID_COLOR or \ |
RD_GMC_SRC_DATATYPE_COLOR or \ |
(6 shl RD_GMC_DST_DATATYPE_SHIFT) or \ |
RD_GMC_CLR_CMP_CNTL_DIS or \ |
RD_ROP3_P or \ |
RD_GMC_WR_MSK_DIS) |
push dword 7 |
call engWaitForFifo |
mov edi, [ati_io] |
mov dword [edi+RD_DST_LINE_START],0 |
mov dword [edi+RD_DST_LINE_END], 0 |
mov dword [edi+RD_DP_BRUSH_FRGD_CLR], 808000ffh |
mov dword [edi+RD_DP_BRUSH_BKGD_CLR], 002020ffh |
mov dword [edi+RD_DP_SRC_FRGD_CLR], 808000ffh |
mov dword [edi+RD_DP_SRC_BKGD_CLR], 004000ffh |
mov dword [edi+RD_DP_WRITE_MASK],0ffffffffh |
call engWaitForIdle |
ret |
endp |
align 4 |
engSetupSolidFill: |
push ebp |
mov ebp, esp |
push dword 3 |
call engWaitForFifo |
wrr RD_DP_GUI_MASTER_CNTL, cmdSolidFill |
mov eax, [ebp+8] |
wrr RD_DP_BRUSH_FRGD_CLR,eax |
mov edi, [ati_io] |
mov dword [edi+RD_DP_CNTL],(RD_DST_X_LEFT_TO_RIGHT or RD_DST_Y_TOP_TO_BOTTOM) |
leave |
ret 4 |
align 4 |
drvSolidFill: |
;x:word,y:word,w:word,h:word,color:dword |
push ebp |
mov ebp, esp |
x equ ebp+8 |
y equ ebp+12 |
w equ ebp+16 |
h equ ebp+20 |
color equ ebp+24 |
push dword [ebp+24] |
call engSetupSolidFill |
push dword 2 |
call engWaitForFifo |
mov edi, [ati_io] |
mov eax, [y] |
mov ebx, [x] |
shl eax,16 |
or eax, ebx |
mov ecx, [w] |
mov edx, [h] |
shl ecx,16 |
or ecx, edx |
mov [edi+RD_DST_Y_X], eax |
mov [edi+RD_DST_WIDTH_HEIGHT], ecx |
call engFlush |
leave |
ret 20 |
align 4 |
devices dd (R8500 shl 16)+VID_ATI |
dd (R9000 shl 16)+VID_ATI |
dd (R9200 shl 16)+VID_ATI |
dd (R9500 shl 16)+VID_ATI |
dd (R9500P shl 16)+VID_ATI |
dd (R9550 shl 16)+VID_ATI |
dd (R9600 shl 16)+VID_ATI |
dd (R9600XT shl 16)+VID_ATI |
dd (R9700P shl 16)+VID_ATI |
dd (R9800 shl 16)+VID_ATI |
dd (R9800P shl 16)+VID_ATI |
dd (R9800XT shl 16)+VID_ATI |
dd 0 ;terminator |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
sz_ati_srv db 'HWCURSOR',0 |
msgInit db 'detect hardware...',13,10,0 |
msgPCI db 'PCI accsess not supported',13,10,0 |
msgFail db 'device not found',13,10,0 |
msg_neg db 'neg ecx',13,10,0 |
buff db 8 dup(0) |
db 13,10, 0 |
section '.data' data readable writable align 16 |
pCursor db 4096 dup(?) |
cursor_map rd 2 |
cursor_start rd 1 |
cursor_end rd 1 |
bus dd ? |
devfn dd ? |
ati_io dd ? |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/drivers/ensoniq.asm |
---|
0,0 → 1,1177 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;alpha version |
format MS COFF |
include 'proc32.inc' |
include 'imports.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 |
PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list |
PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register |
PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index |
PCM_OUT_SR_REG equ 0x16 ; PCM out Status register |
PCM_OUT_PIV_REG equ 0x1a |
PCM_OUT_CIV_REG equ 0x14 ; PCM out current index |
PCM_IN_CR_REG equ 0x0b ; PCM in Control Register |
MC_IN_CR_REG equ 0x2b ; MIC in Control Register |
RR equ BIT1 ; reset registers. Nukes all regs |
CODEC_MASTER_VOL_REG equ 0x02 |
CODEC_AUX_VOL equ 0x04 ; |
CODEC_PCM_OUT_REG equ 18h ; PCM output volume |
CODEC_EXT_AUDIO_REG equ 28h ; extended audio |
CODEC_EXT_AUDIO_CTRL_REG equ 2ah ; extended audio control |
CODEC_PCM_FRONT_DACRATE_REG equ 2ch ; PCM out sample rate |
CODEC_PCM_SURND_DACRATE_REG equ 2eh ; surround sound sample rate |
CODEC_PCM_LFE_DACRATE_REG equ 30h ; LFE sample rate |
GLOB_CTRL equ 0x2C ; Global Control |
CTRL_STAT equ 0x30 ; Global Status |
CTRL_CAS equ 0x34 ; Codec Access Semiphore |
CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit |
CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready |
CTRL_ST_RCS equ 0x00008000 ; Read Completion Status |
CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable |
CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off |
CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset |
CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset |
CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable |
CODEC_REG_POWERDOWN equ 0x26 |
CODEC_REG_ST equ 0x26 |
DEV_PLAY equ 1 |
DEV_STOP equ 2 |
DEV_CALLBACK equ 3 |
DEV_SET_BUFF equ 4 |
DEV_NOTIFY equ 5 |
DEV_SET_MASTERVOL equ 6 |
DEV_GET_MASTERVOL equ 7 |
DEV_GET_INFO equ 8 |
struc AC_CNTRL ;AC controller base class |
{ .bus dd ? |
.devfn dd ? |
.vendor dd ? |
.dev_id dd ? |
.pci_cmd dd ? |
.pci_stat dd ? |
.codec_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_io_base dd ? |
.ctrl_mem_base dd ? |
.cfg_reg dd ? |
.int_line dd ? |
.vendor_ids dd ? ;vendor id string |
.ctrl_ids dd ? ;hub id string |
.buffer dd ? |
.notify_pos dd ? |
.notify_task dd ? |
.lvi_reg dd ? |
.ctrl_setup dd ? |
.user_callback dd ? |
.codec_read16 dd ? |
.codec_write16 dd ? |
.ctrl_read8 dd ? |
.ctrl_read16 dd ? |
.ctrl_read32 dd ? |
.ctrl_write8 dd ? |
.ctrl_write16 dd ? |
.ctrl_write32 dd ? |
} |
struc CODEC ;Audio Chip base class |
{ |
.chip_id dd ? |
.flags dd ? |
.status dd ? |
.ac_vendor_ids dd ? ;ac vendor id string |
.chip_ids dd ? ;chip model string |
.shadow_flag dd ? |
dd ? |
.regs dw ? ; codec registers |
.reg_master_vol dw ? ;0x02 |
.reg_aux_out_vol dw ? ;0x04 |
.reg_mone_vol dw ? ;0x06 |
.reg_master_tone dw ? ;0x08 |
.reg_beep_vol dw ? ;0x0A |
.reg_phone_vol dw ? ;0x0C |
.reg_mic_vol dw ? ;0x0E |
.reg_line_in_vol dw ? ;0x10 |
.reg_cd_vol dw ? ;0x12 |
.reg_video_vol dw ? ;0x14 |
.reg_aux_in_vol dw ? ;0x16 |
.reg_pcm_out_vol dw ? ;0x18 |
.reg_rec_select dw ? ;0x1A |
.reg_rec_gain dw ? ;0x1C |
.reg_rec_gain_mic dw ? ;0x1E |
.reg_gen dw ? ;0x20 |
.reg_3d_ctrl dw ? ;0X22 |
.reg_page dw ? ;0X24 |
.reg_powerdown dw ? ;0x26 |
.reg_ext_audio dw ? ;0x28 |
.reg_ext_st dw ? ;0x2a |
.reg_pcm_front_rate dw ? ;0x2c |
.reg_pcm_surr_rate dw ? ;0x2e |
.reg_lfe_rate dw ? ;0x30 |
.reg_pcm_in_rate dw ? ;0x32 |
dw ? ;0x34 |
.reg_cent_lfe_vol dw ? ;0x36 |
.reg_surr_vol dw ? ;0x38 |
.reg_spdif_ctrl dw ? ;0x3A |
dw ? ;0x3C |
dw ? ;0x3E |
dw ? ;0x40 |
dw ? ;0x42 |
dw ? ;0x44 |
dw ? ;0x46 |
dw ? ;0x48 |
dw ? ;0x4A |
dw ? ;0x4C |
dw ? ;0x4E |
dw ? ;0x50 |
dw ? ;0x52 |
dw ? ;0x54 |
dw ? ;0x56 |
dw ? ;0x58 |
dw ? ;0x5A |
dw ? ;0x5C |
dw ? ;0x5E |
.reg_page_0 dw ? ;0x60 |
.reg_page_1 dw ? ;0x62 |
.reg_page_2 dw ? ;0x64 |
.reg_page_3 dw ? ;0x66 |
.reg_page_4 dw ? ;0x68 |
.reg_page_5 dw ? ;0x6A |
.reg_page_6 dw ? ;0x6C |
.reg_page_7 dw ? ;0x6E |
dw ? ;0x70 |
dw ? ;0x72 |
dw ? ;0x74 |
dw ? ;0x76 |
dw ? ;0x78 |
dw ? ;0x7A |
.reg_vendor_id_1 dw ? ;0x7C |
.reg_vendor_id_2 dw ? ;0x7E |
.reset dd ? ;virual |
.set_master_vol dd ? |
} |
struc CTRL_INFO |
{ .pci_cmd dd ? |
.irq dd ? |
.glob_cntrl dd ? |
.glob_sta dd ? |
.codec_io_base dd ? |
.ctrl_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_mem_base dd ? |
.codec_id dd ? |
} |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
EVENT_NOTIFY equ 0x00000200 |
OS_BASE equ 0x80000000 |
SLOT_BASE equ OS_BASE+0x0080000 |
new_app_base equ 0 |
public START |
public service_proc |
public version |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .stop |
if DEBUG |
mov esi, msgDetect |
call SysMsgBoardStr |
end if |
call detect_controller |
test eax, eax |
jz .fail |
if DEBUG |
mov esi,[ctrl.vendor_ids] |
call SysMsgBoardStr |
mov esi, [ctrl.ctrl_ids] |
call SysMsgBoardStr |
end if |
call init_controller |
test eax, eax |
jz .fail |
jmp .fail ;force fail |
if DEBUG |
mov esi, msgInitCodec |
call SysMsgBoardStr |
end if |
call init_codec |
test eax, eax |
jz .fail |
if DEBUG |
mov esi, [codec.ac_vendor_ids] |
call SysMsgBoardStr |
mov esi, [codec.chip_ids] |
call SysMsgBoardStr |
end if |
call reset_controller |
call setup_codec |
mov esi, msgPrimBuff |
call SysMsgBoardStr |
call create_primary_buff |
mov eax, VALID_IRQ |
mov ebx, [ctrl.int_line] |
mov esi, msgInvIRQ |
bt eax, ebx |
jnc .fail |
mov eax, ATTCH_IRQ |
mov esi, msgAttchIRQ |
bt eax, ebx |
jnc .fail |
stdcall AttachIntHandler, ebx, ac97_irq |
stdcall RegService, sz_sound_srv, service_proc |
ret |
.fail: |
if DEBUG |
mov esi, msgFail |
call SysMsgBoardStr |
end if |
xor eax, eax |
ret |
.stop: |
call stop |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+io_code] |
cmp eax, DEV_PLAY |
jne @F |
if DEBUG |
mov esi, msgPlay |
call SysMsgBoardStr |
end if |
call play |
ret |
@@: |
cmp eax, DEV_STOP |
jne @F |
if DEBUG |
mov esi, msgStop |
call SysMsgBoardStr |
end if |
call stop |
ret |
@@: |
cmp eax, DEV_CALLBACK |
jne @F |
mov ebx, [edi+input] |
stdcall set_callback, [ebx] |
ret |
@@: |
cmp eax, DEV_SET_MASTERVOL |
jne @F |
mov eax, [edi+input] |
mov eax, [eax] |
call set_master_vol ;eax= vol |
ret |
@@: |
cmp eax, DEV_GET_MASTERVOL |
jne @F |
mov ebx, [edi+output] |
stdcall get_master_vol, ebx |
ret |
;@@: |
; cmp eax, DEV_GET_INFO |
; jne @F |
; mov ebx, [edi+output] |
; stdcall get_dev_info, ebx |
; ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc ac97_irq |
; if DEBUG |
; mov esi, msgIRQ |
; call SysMsgBoardStr |
; end if |
cmp [ctrl.user_callback], 0 |
je @f |
stdcall [ctrl.user_callback], ebx |
@@: |
ret |
.skip: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 ;0x1D |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc create_primary_buff |
stdcall KernelAlloc, 0x10000 |
mov [ctrl.buffer], eax |
mov edi, eax |
mov ecx, 0x10000/4 |
xor eax, eax |
cld |
rep stosd |
mov eax, [ctrl.buffer] |
call GetPgAddr |
mov ebx, 0xC0002000 |
mov ecx, 4 |
mov edi, pcmout_bdl |
@@: |
mov [edi], eax |
mov [edi+4], ebx |
mov [edi+32], eax |
mov [edi+4+32], ebx |
mov [edi+64], eax |
mov [edi+4+64], ebx |
mov [edi+96], eax |
mov [edi+4+96], ebx |
mov [edi+128], eax |
mov [edi+4+128], ebx |
mov [edi+160], eax |
mov [edi+4+160], ebx |
mov [edi+192], eax |
mov [edi+4+192], ebx |
mov [edi+224], eax |
mov [edi+4+224], ebx |
add eax, 0x4000 |
add edi, 8 |
loop @B |
mov edi, buff_list |
mov eax, [ctrl.buffer] |
mov ecx, 4 |
@@: |
mov [edi], eax |
mov [edi+16], eax |
mov [edi+32], eax |
mov [edi+48], eax |
mov [edi+64], eax |
mov [edi+80], eax |
mov [edi+96], eax |
mov [edi+112], eax |
add eax, 0x4000 |
add edi, 4 |
loop @B |
mov eax, pcmout_bdl |
mov ebx, eax |
call GetPgAddr ;eax |
and ebx, 0xFFF |
add eax, ebx |
mov edx, PCM_OUT_BDL |
call [ctrl.ctrl_write32] |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc detect_controller |
locals |
last_bus dd ? |
bus dd ? |
devfn dd ? |
endl |
xor eax, eax |
mov [bus], eax |
inc eax |
call PciApi |
cmp eax, -1 |
je .err |
mov [last_bus], eax |
.next_bus: |
and [devfn], 0 |
.next_dev: |
stdcall PciRead32, [bus], [devfn], dword 0 |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
mov edi, devices |
@@: |
mov ebx, [edi] |
test ebx, ebx |
jz .next |
cmp eax, ebx |
je .found |
add edi, 12 |
jmp @B |
.next: |
inc [devfn] |
cmp [devfn], 256 |
jb .next_dev |
mov eax, [bus] |
inc eax |
mov [bus], eax |
cmp eax, [last_bus] |
jna .next_bus |
xor eax, eax |
ret |
.found: |
mov ebx, [bus] |
mov [ctrl.bus], ebx |
mov ecx, [devfn] |
mov [ctrl.devfn], ecx |
mov edx, eax |
and edx, 0xFFFF |
mov [ctrl.vendor], edx |
shr eax, 16 |
mov [ctrl.dev_id], eax |
mov ebx, [edi+4] |
mov [ctrl.ctrl_ids], ebx |
mov esi, [edi+8] |
mov [ctrl.ctrl_setup], esi |
cmp ebx, 0x1274 |
jne @F |
mov [ctrl.vendor_ids], msgEnsoniq |
ret |
@@: |
mov [ctrl.vendor_ids], 0 ;something wrong ? |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc init_controller |
mov esi, msgPCIcmd |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 |
mov ebx, eax |
and eax, 0xFFFF |
mov [ctrl.pci_cmd], eax |
shr ebx, 16 |
mov [ctrl.pci_stat], ebx |
call dword2str |
call SysMsgBoardStr |
mov esi, msgIObase |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x10 |
; and eax, -16 |
mov [ctrl.ctrl_io_base], eax |
call dword2str |
call SysMsgBoardStr |
mov esi, msgIRQline |
call SysMsgBoardStr |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 0x3C |
and eax, 0xFF |
mov [ctrl.int_line], eax |
call dword2str |
call SysMsgBoardStr |
call [ctrl.ctrl_setup] |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc set_ICH |
mov [ctrl.codec_read16], codec_io_r16 ;virtual |
mov [ctrl.codec_write16], codec_io_w16 ;virtual |
mov [ctrl.ctrl_read8 ], ctrl_io_r8 ;virtual |
mov [ctrl.ctrl_read16], ctrl_io_r16 ;virtual |
mov [ctrl.ctrl_read32], ctrl_io_r32 ;virtual |
mov [ctrl.ctrl_write8 ], ctrl_io_w8 ;virtual |
mov [ctrl.ctrl_write16], ctrl_io_w16 ;virtual |
mov [ctrl.ctrl_write32], ctrl_io_w32 ;virtual |
ret |
endp |
align 4 |
proc reset_controller |
xor eax, eax |
mov edx, PCM_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, MC_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov eax, RR |
mov edx, PCM_IN_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
call [ctrl.ctrl_write8] |
mov edx, MC_IN_CR_REG |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc init_codec |
locals |
counter dd ? |
endl |
mov esi, msgControl |
call SysMsgBoardStr |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgStatus |
call SysMsgBoardStr |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
test eax, CTRL_ST_CREADY |
jnz .ready |
call reset_codec |
and eax, eax |
jz .err |
xor edx, edx ;ac_reg_0 |
call [ctrl.codec_write16] |
xor eax, eax |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_write16] |
mov [counter], 200 ; total 200*5 ms = 1s |
.wait: |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_read16] |
and eax, 0x0F |
cmp eax, 0x0F |
jz .ready |
mov eax, 5000 ; wait 5 ms |
call StallExec |
sub [counter] , 1 |
jnz .wait |
.err: |
xor eax, eax ; timeout error |
ret |
.ready: |
call detect_codec |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc reset_codec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 0x02 |
jz .cold |
call warm_reset |
jnc .ok |
.cold: |
call cold_reset |
jnc .ok |
if DEBUG |
mov esi, msgCFail |
call SysMsgBoardStr |
end if |
xor eax, eax ; timeout error |
ret |
.ok: |
if DEBUG |
mov esi, msgResetOk |
call SysMsgBoardStr |
end if |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc warm_reset |
locals |
counter dd ? |
endl |
mov eax, 0x06 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgWarm |
call SysMsgBoardStr |
end if |
mov [counter], 10 ; total 10*100 ms = 1s |
.wait: |
mov eax, 100000 ; wait 100 ms |
call StallExec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 4 |
jz .ok |
sub [counter], 1 |
jnz .wait |
if DEBUG |
mov esi, msgWRFail |
call SysMsgBoardStr |
end if |
stc |
ret |
.ok: |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .fail |
clc |
ret |
.fail: |
stc |
ret |
endp |
align 4 |
proc cold_reset |
locals |
counter dd ? |
endl |
xor eax, eax |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgCold |
call SysMsgBoardStr |
end if |
mov eax, 1000000 ; wait 1 s |
call StallExec |
mov eax, 2 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
mov [counter], 10 ; total 10*100 ms = 1s |
.wait: |
mov eax, 100000 ; wait 100 ms |
call StallExec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 4 |
jz .ok |
sub [counter], 1 |
jnz .wait |
if DEBUG |
mov esi, msgCRFail |
call SysMsgBoardStr |
end if |
stc |
ret |
.ok: |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .fail |
clc |
ret |
.fail: |
stc |
ret |
endp |
align 4 |
play: |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x1D |
call [ctrl.ctrl_write8] |
xor eax, eax |
ret |
align 4 |
stop: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x0 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
xor eax, eax |
ret |
align 4 |
proc get_dev_info stdcall, p_info:dword |
virtual at esi |
CTRL_INFO CTRL_INFO |
end virtual |
mov esi, [p_info] |
mov eax, [ctrl.int_line] |
mov ebx, [ctrl.codec_io_base] |
mov ecx, [ctrl.ctrl_io_base] |
mov edx, [ctrl.codec_mem_base] |
mov edi, [ctrl.ctrl_mem_base] |
mov [CTRL_INFO.irq], eax |
mov [CTRL_INFO.codec_io_base], ebx |
mov [CTRL_INFO.ctrl_io_base], ecx |
mov [CTRL_INFO.codec_mem_base], edx |
mov [CTRL_INFO.ctrl_mem_base], edi |
mov eax, [codec.chip_id] |
mov [CTRL_INFO.codec_id], eax |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_cntrl], eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_sta], eax |
mov ebx, [ctrl.pci_cmd] |
mov [CTRL_INFO.pci_cmd], ebx |
ret |
endp |
align 4 |
proc set_callback stdcall, handler:dword |
mov eax, [handler] |
mov [ctrl.user_callback], eax |
ret |
endp |
align 4 |
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax |
mov edx, [ac_reg] |
mov ebx, edx |
shr ebx, 1 |
bt [codec.shadow_flag], ebx |
jc .use_shadow |
call [ctrl.codec_read16] ;change edx !!! |
mov ecx, eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_RCS |
jz .read_ok |
mov edx, CTRL_STAT |
call [ctrl.ctrl_write32] |
xor eax,eax |
not eax ;timeout |
ret |
.read_ok: |
mov edx, [ac_reg] |
mov [codec.regs+edx], cx |
bts [codec.shadow_flag], ebx |
mov eax, ecx |
ret |
.use_shadow: |
movzx eax, word [codec.regs+edx] |
ret |
endp |
align 4 |
proc codec_write stdcall, ac_reg:dword |
push eax |
call check_semafore |
and eax, eax |
jz .err |
pop eax |
mov esi, [ac_reg] |
mov edx, esi |
call [ctrl.codec_write16] |
mov [codec.regs+esi], ax |
shr esi, 1 |
bts [codec.shadow_flag], esi |
ret |
.err: |
pop eax |
ret |
endp |
align 4 |
proc codec_check_ready |
mov edx, CTRL_ST |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .not_ready |
xor eax, wax |
inc eax |
ret |
.not_ready: |
xor eax, eax |
ret |
endp |
align 4 |
proc check_semafore |
local counter:DWORD |
mov [counter], 100 |
.l1: |
mov edx, CTRL_CAS |
call [ctrl.ctrl_read8] |
and eax, CAS_FLAG |
jz .ok |
mov eax, 1 |
call StallExec |
sub [counter], 1 |
jnz .l1 |
xor eax, eax |
ret |
align 4 |
.ok: |
xor eax,eax |
inc eax |
ret |
endp |
align 4 |
proc StallExec |
push ecx |
push edx |
push ebx |
push eax |
mov ecx, CPU_FREQ |
mul ecx |
mov ebx, eax ;low |
mov ecx, edx ;high |
rdtsc |
add ebx, eax |
adc ecx,edx |
@@: |
rdtsc |
sub eax, ebx |
sbb edx, ecx |
js @B |
pop eax |
pop ebx |
pop edx |
pop ecx |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; CONTROLLER IO functions |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
codec_io_r16: |
add edx, [ctrl.codec_io_base] |
in ax, dx |
ret |
align 4 |
codec_io_w16: |
add edx, [ctrl.codec_io_base] |
out dx, ax |
ret |
align 4 |
ctrl_io_r8: |
add edx, [ctrl.ctrl_io_base] |
in al, dx |
ret |
align 4 |
ctrl_io_r16: |
add edx, [ctrl.ctrl_io_base] |
in ax, dx |
ret |
align 4 |
ctrl_io_r32: |
add edx, [ctrl.ctrl_io_base] |
in eax, dx |
ret |
align 4 |
ctrl_io_w8: |
add edx, [ctrl.ctrl_io_base] |
out dx, al |
ret |
align 4 |
ctrl_io_w16: |
add edx, [ctrl.ctrl_io_base] |
out dx, ax |
ret |
align 4 |
ctrl_io_w32: |
add edx, [ctrl.ctrl_io_base] |
out dx, eax |
ret |
align 4 |
dword2str: |
mov esi, hex_buff |
mov ecx, -8 |
@@: |
rol eax, 4 |
mov ebx, eax |
and ebx, 0x0F |
mov bl, [ebx+hexletters] |
mov [8+esi+ecx], bl |
inc ecx |
jnz @B |
ret |
hexletters db '0123456789ABCDEF' |
hex_buff db 8 dup(0),13,10,0 |
include "codec.inc" |
align 4 |
devices dd (0x5000 shl 16)+0x1274,msgEnsoniq,set_ICH |
dd (0x5880 shl 16)+0x1274,msgVibra128,set_ICH |
dd 0 ;terminator |
version dd 0x00040004 |
msgEnsoniq db 'Ensonic 1371',13,10,0 |
msgVibra128 db 'Sound Blaster AudioPCI Vibra 128',13,10,0 |
sz_sound_srv db 'SOUND',0 |
msgDetect db 'detect hardware...',13,10,0 |
msgFail db 'device not found',13,10,0 |
msgAttchIRQ db 'IRQ line not supported', 13,10, 0 |
msgInvIRQ db 'IRQ line not assigned or invalid', 13,10, 0 |
msgPlay db 'start play', 13,10,0 |
msgStop db 'stop play', 13,10,0 |
msgNotify db 'call notify',13,10,0 |
msgIRQ db 'AC97 IRQ', 13,10,0 |
msgInitCtrl db 'init controller',13,10,0 |
msgInitCodec db 'init codec',13,10,0 |
msgPrimBuff db 'create primary buffer',13,10,0 |
msgReg db 'set service handler',13,10,0 |
msgOk db 'service installed',13,10,0 |
msgCold db 'cold reset',13,10,0 |
msgWarm db 'warm reset',13,10,0 |
msgWRFail db 'warm reset failed',13,10,0 |
msgCRFail db 'cold reset failed',13,10,0 |
msgCFail db 'codec not ready',13,10,0 |
msgResetOk db 'reset complete',13,10,0 |
msgStatus db 'global status ',0 |
msgControl db 'global control ',0 |
msgPCIcmd db 'PCI command ',0 |
msgIObase db 'IO base ',0 |
msgIRQline db 'IRQ line ',0 |
section '.data' data readable writable align 16 |
pcmout_bdl rq 32 |
buff_list rd 32 |
codec CODEC |
ctrl AC_CNTRL |
lpc_bus rd 1 |
civ_val rd 1 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/drivers/main.inc |
---|
0,0 → 1,161 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; (C) copyright Serge 2006-2007 |
; email: infinity_sound@mail.ru |
PLAY_SYNC equ 0x80000000 |
PCM_ALL equ 0 |
PCM_OUT equ 0x08000000 |
PCM_RING equ 0x10000000 |
PCM_STATIC equ 0x20000000 |
PCM_FLOAT equ 0x40000000 ;reserved |
PCM_FILTER equ 0x80000000 ;reserved |
PCM_2_16_48 equ 1 |
PCM_1_16_48 equ 2 |
PCM_2_16_44 equ 3 |
PCM_1_16_44 equ 4 |
PCM_2_16_32 equ 5 |
PCM_1_16_32 equ 6 |
PCM_2_16_24 equ 7 |
PCM_1_16_24 equ 8 |
PCM_2_16_22 equ 9 |
PCM_1_16_22 equ 10 |
PCM_2_16_16 equ 11 |
PCM_1_16_16 equ 12 |
PCM_2_16_12 equ 13 |
PCM_1_16_12 equ 14 |
PCM_2_16_11 equ 15 |
PCM_1_16_11 equ 16 |
PCM_2_16_8 equ 17 |
PCM_1_16_8 equ 18 |
PCM_2_8_48 equ 19 |
PCM_1_8_48 equ 20 |
PCM_2_8_44 equ 21 |
PCM_1_8_44 equ 22 |
PCM_2_8_32 equ 23 |
PCM_1_8_32 equ 24 |
PCM_2_8_24 equ 25 |
PCM_1_8_24 equ 26 |
PCM_2_8_22 equ 27 |
PCM_1_8_22 equ 28 |
PCM_2_8_16 equ 29 |
PCM_1_8_16 equ 30 |
PCM_2_8_12 equ 31 |
PCM_1_8_12 equ 32 |
PCM_2_8_11 equ 33 |
PCM_1_8_11 equ 34 |
PCM_2_8_8 equ 35 |
PCM_1_8_8 equ 36 |
SRV_GETVERSION equ 0 |
SND_CREATE_BUFF equ 1 |
SND_DESTROY_BUFF equ 2 |
SND_SETFORMAT equ 3 |
SND_GETFORMAT equ 4 |
SND_RESET equ 5 |
SND_SETPOS equ 6 |
SND_GETPOS equ 7 |
SND_SETBUFF equ 8 |
SND_OUT equ 9 |
SND_PLAY equ 10 |
SND_STOP equ 11 |
SND_SETVOLUME equ 12 |
SND_GETVOLUME equ 13 |
SND_SETPAN equ 14 |
SND_GETPAN equ 15 |
SND_GETBUFFSIZE equ 16 |
struc STREAM |
{ |
.magic dd ? ;'WAVE' |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
.size dd ? |
.str_fd dd ? |
.str_bk dd ? |
.device dd ? |
.format dd ? |
.flags dd ? |
.out_base dd ? |
.out_wp dd ? |
.out_rp dd ? |
.out_count dd ? |
.out_top dd ? |
.r_size dd ? |
.r_dt dd ? |
.r_silence dd ? |
.resample dd ? |
.l_vol dd ? |
.r_vol dd ? |
.l_amp dw ? |
.r_amp dw ? |
.pan dd ? |
.in_base dd ? |
.in_size dd ? |
.in_wp dd ? |
.in_rp dd ? |
.in_count dd ? |
.in_free dd ? |
.in_top dd ? |
.notify_event dd ? |
.notify_id dd ? |
} |
STREAM_SIZE equ 34*4 |
FD_OFFSET equ 24 |
virtual at 0 |
STREAM STREAM |
end virtual |
struc WAVE_HEADER |
{ .riff_id dd ? |
.riff_size dd ? |
.riff_format dd ? |
.fmt_id dd ? |
.fmt_size dd ? |
.format_tag dw ? |
.channels dw ? |
.freq dd ? |
.bytes_sec dd ? |
.block_align dw ? |
.bits_sample dw ? |
.data_id dd ? |
.data_size dd ? |
} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/drivers/sceletone.asm |
---|
0,0 → 1,177 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;driver sceletone |
format MS COFF |
API_VERSION equ 0 ;debug |
include 'proc32.inc' |
include 'imports.inc' |
OS_BASE equ 0; |
new_app_base equ 0x60400000 |
PROC_BASE equ OS_BASE+0x0080000 |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
public START |
public service_proc |
public version |
DEBUG equ 1 |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
STRIDE equ 4 ;size of row in devices table |
SRV_GETVERSION equ 0 |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .exit |
.entry: |
if DEBUG |
mov esi, msgInit |
call SysMsgBoardStr |
end if |
stdcall RegService, my_service, service_proc |
ret |
.fail: |
.exit: |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov ebx, [ioctl] |
mov eax, [ebx+io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [ebx+output] |
cmp [ebx+out_size], 4 |
jne .fail |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc detect |
locals |
last_bus dd ? |
endl |
xor eax, eax |
mov [bus], eax |
inc eax |
call PciApi |
cmp eax, -1 |
je .err |
mov [last_bus], eax |
.next_bus: |
and [devfn], 0 |
.next_dev: |
stdcall PciRead32, [bus], [devfn], dword 0 |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
mov edi, devices |
@@: |
mov ebx, [edi] |
test ebx, ebx |
jz .next |
cmp eax, ebx |
je .found |
add edi, STRIDE |
jmp @B |
.next: |
inc [devfn] |
cmp [devfn], 256 |
jb .next_dev |
mov eax, [bus] |
inc eax |
mov [bus], eax |
cmp eax, [last_bus] |
jna .next_bus |
xor eax, eax |
ret |
.found: |
xor eax, eax |
inc eax |
ret |
.err: |
xor eax, eax |
ret |
endp |
DEVICE_ID equ 1234; pci device id |
VENDOR_ID equ 5678; device vendor id |
;all initialized data place here |
align 4 |
devices dd (DEVICE_ID shl 16)+VENDOR_ID |
dd 0 ;terminator |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
my_service db 'MY_SERVICE',0 ;max 16 chars include zero |
msgInit db 'detect hardware...',13,10,0 |
msgPCI db 'PCI accsess not supported',13,10,0 |
msgFail db 'device not found',13,10,0 |
section '.data' data readable writable align 16 |
;all uninitialized data place here |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/drivers/sis.asm |
---|
0,0 → 1,1192 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
format MS COFF |
include 'proc32.inc' |
include 'imports.inc' |
API_VERSION equ 0x01000100 |
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 |
SRV_GETVERSION equ 0 |
DEV_PLAY equ 1 |
DEV_STOP equ 2 |
DEV_CALLBACK equ 3 |
DEV_SET_BUFF equ 4 |
DEV_NOTIFY equ 5 |
DEV_SET_MASTERVOL equ 6 |
DEV_GET_MASTERVOL equ 7 |
DEV_GET_INFO equ 8 |
struc AC_CNTRL ;AC controller base class |
{ .bus dd ? |
.devfn dd ? |
.vendor dd ? |
.dev_id dd ? |
.pci_cmd dd ? |
.pci_stat dd ? |
.codec_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_io_base dd ? |
.ctrl_mem_base dd ? |
.cfg_reg dd ? |
.int_line dd ? |
.vendor_ids dd ? ;vendor id string |
.ctrl_ids dd ? ;hub id string |
.buffer dd ? |
.notify_pos dd ? |
.notify_task dd ? |
.lvi_reg dd ? |
.ctrl_setup dd ? |
.user_callback dd ? |
.codec_read16 dd ? |
.codec_write16 dd ? |
.ctrl_read8 dd ? |
.ctrl_read16 dd ? |
.ctrl_read32 dd ? |
.ctrl_write8 dd ? |
.ctrl_write16 dd ? |
.ctrl_write32 dd ? |
} |
struc CODEC ;Audio Chip base class |
{ |
.chip_id dd ? |
.flags dd ? |
.status dd ? |
.ac_vendor_ids dd ? ;ac vendor id string |
.chip_ids dd ? ;chip model string |
.shadow_flag dd ? |
dd ? |
.regs dw ? ; codec registers |
.reg_master_vol dw ? ;0x02 |
.reg_aux_out_vol dw ? ;0x04 |
.reg_mone_vol dw ? ;0x06 |
.reg_master_tone dw ? ;0x08 |
.reg_beep_vol dw ? ;0x0A |
.reg_phone_vol dw ? ;0x0C |
.reg_mic_vol dw ? ;0x0E |
.reg_line_in_vol dw ? ;0x10 |
.reg_cd_vol dw ? ;0x12 |
.reg_video_vol dw ? ;0x14 |
.reg_aux_in_vol dw ? ;0x16 |
.reg_pcm_out_vol dw ? ;0x18 |
.reg_rec_select dw ? ;0x1A |
.reg_rec_gain dw ? ;0x1C |
.reg_rec_gain_mic dw ? ;0x1E |
.reg_gen dw ? ;0x20 |
.reg_3d_ctrl dw ? ;0X22 |
.reg_page dw ? ;0X24 |
.reg_powerdown dw ? ;0x26 |
.reg_ext_audio dw ? ;0x28 |
.reg_ext_st dw ? ;0x2a |
.reg_pcm_front_rate dw ? ;0x2c |
.reg_pcm_surr_rate dw ? ;0x2e |
.reg_lfe_rate dw ? ;0x30 |
.reg_pcm_in_rate dw ? ;0x32 |
dw ? ;0x34 |
.reg_cent_lfe_vol dw ? ;0x36 |
.reg_surr_vol dw ? ;0x38 |
.reg_spdif_ctrl dw ? ;0x3A |
dw ? ;0x3C |
dw ? ;0x3E |
dw ? ;0x40 |
dw ? ;0x42 |
dw ? ;0x44 |
dw ? ;0x46 |
dw ? ;0x48 |
dw ? ;0x4A |
dw ? ;0x4C |
dw ? ;0x4E |
dw ? ;0x50 |
dw ? ;0x52 |
dw ? ;0x54 |
dw ? ;0x56 |
dw ? ;0x58 |
dw ? ;0x5A |
dw ? ;0x5C |
dw ? ;0x5E |
.reg_page_0 dw ? ;0x60 |
.reg_page_1 dw ? ;0x62 |
.reg_page_2 dw ? ;0x64 |
.reg_page_3 dw ? ;0x66 |
.reg_page_4 dw ? ;0x68 |
.reg_page_5 dw ? ;0x6A |
.reg_page_6 dw ? ;0x6C |
.reg_page_7 dw ? ;0x6E |
dw ? ;0x70 |
dw ? ;0x72 |
dw ? ;0x74 |
dw ? ;0x76 |
dw ? ;0x78 |
dw ? ;0x7A |
.reg_vendor_id_1 dw ? ;0x7C |
.reg_vendor_id_2 dw ? ;0x7E |
.reset dd ? ;virual |
.set_master_vol dd ? |
} |
struc CTRL_INFO |
{ .pci_cmd dd ? |
.irq dd ? |
.glob_cntrl dd ? |
.glob_sta dd ? |
.codec_io_base dd ? |
.ctrl_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_mem_base dd ? |
.codec_id dd ? |
} |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
EVENT_NOTIFY equ 0x00000200 |
OS_BASE equ 0x80000000 |
SLOT_BASE equ OS_BASE+0x0080000 |
public START |
public service_proc |
public version |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .stop |
if DEBUG |
mov esi, msgInit |
call SysMsgBoardStr |
end if |
call detect_controller |
test eax, eax |
jz .fail |
if DEBUG |
mov esi,[ctrl.vendor_ids] |
call SysMsgBoardStr |
mov esi, [ctrl.ctrl_ids] |
call SysMsgBoardStr |
end if |
call init_controller |
test eax, eax |
jz .fail |
if DEBUG |
mov esi, msgInitCodec |
call SysMsgBoardStr |
end if |
call init_codec |
test eax, eax |
jz .fail |
if DEBUG |
mov esi, [codec.ac_vendor_ids] |
call SysMsgBoardStr |
mov esi, [codec.chip_ids] |
call SysMsgBoardStr |
end if |
call reset_controller |
call setup_codec |
mov esi, msgPrimBuff |
call SysMsgBoardStr |
call create_primary_buff |
stdcall AttachIntHandler, [ctrl.int_line], ac97_irq |
stdcall RegService, sz_sound_srv, service_proc |
mov esi, msgOk |
call SysMsgBoardStr |
ret |
.fail: |
if DEBUG |
mov esi, msgFail |
call SysMsgBoardStr |
end if |
xor eax, eax |
ret |
.stop: |
call stop |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [edi+output] |
cmp [edi+out_size], 4 |
jne .fail |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
@@: |
cmp eax, DEV_PLAY |
jne @F |
if DEBUG |
mov esi, msgPlay |
call SysMsgBoardStr |
end if |
call play |
ret |
@@: |
cmp eax, DEV_STOP |
jne @F |
if DEBUG |
mov esi, msgStop |
call SysMsgBoardStr |
end if |
call stop |
ret |
@@: |
cmp eax, DEV_CALLBACK |
jne @F |
mov ebx, [edi+input] |
stdcall set_callback, [ebx] |
ret |
@@: |
cmp eax, DEV_SET_MASTERVOL |
jne @F |
mov eax, [edi+input] |
mov eax, [eax] |
call set_master_vol ;eax= vol |
ret |
@@: |
cmp eax, DEV_GET_MASTERVOL |
jne @F |
mov ebx, [edi+output] |
stdcall get_master_vol, ebx |
ret |
;@@: |
; cmp eax, DEV_GET_INFO |
; jne @F |
; mov ebx, [edi+output] |
; stdcall get_dev_info, ebx |
; ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc ac97_irq |
; if DEBUG |
; mov esi, msgIRQ |
; call SysMsgBoardStr |
; end if |
mov edx, PCM_OUT_CR_REG |
mov al, 0x10 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
mov edx, PCM_OUT_CIV_REG |
call [ctrl.ctrl_read8] |
and eax, 0x1F |
cmp eax, [civ_val] |
je .skip |
mov [civ_val], eax |
dec eax |
and eax, 0x1F |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 |
call [ctrl.ctrl_write8] |
mov eax, [civ_val] |
add eax, 1 |
and eax, 31 |
mov ebx, dword [buff_list+eax*4] |
cmp [ctrl.user_callback], 0 |
je @f |
stdcall [ctrl.user_callback], ebx |
@@: |
ret |
.skip: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc create_primary_buff |
stdcall KernelAlloc, 0x10000 |
mov [ctrl.buffer], eax |
mov edi, eax |
mov ecx, 0x10000/4 |
xor eax, eax |
cld |
rep stosd |
mov eax, [ctrl.buffer] |
call GetPgAddr |
mov ebx, 0xC0004000 |
mov ecx, 4 |
mov edi, pcmout_bdl |
@@: |
mov [edi], eax |
mov [edi+4], ebx |
mov [edi+32], eax |
mov [edi+4+32], ebx |
mov [edi+64], eax |
mov [edi+4+64], ebx |
mov [edi+96], eax |
mov [edi+4+96], ebx |
mov [edi+128], eax |
mov [edi+4+128], ebx |
mov [edi+160], eax |
mov [edi+4+160], ebx |
mov [edi+192], eax |
mov [edi+4+192], ebx |
mov [edi+224], eax |
mov [edi+4+224], ebx |
add eax, 0x4000 |
add edi, 8 |
loop @B |
mov edi, buff_list |
mov eax, [ctrl.buffer] |
mov ecx, 4 |
@@: |
mov [edi], eax |
mov [edi+16], eax |
mov [edi+32], eax |
mov [edi+48], eax |
mov [edi+64], eax |
mov [edi+80], eax |
mov [edi+96], eax |
mov [edi+112], eax |
add eax, 0x4000 |
add edi, 4 |
loop @B |
mov eax, pcmout_bdl |
mov ebx, eax |
call GetPgAddr ;eax |
and ebx, 0xFFF |
add eax, ebx |
mov edx, PCM_OUT_BDL |
call [ctrl.ctrl_write32] |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
and eax, not 0x000000C0 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
ret |
endp |
align 4 |
proc detect_controller |
locals |
last_bus dd ? |
bus dd ? |
devfn dd ? |
endl |
xor eax, eax |
mov [bus], eax |
inc eax |
call PciApi |
cmp eax, -1 |
je .err |
mov [last_bus], eax |
.next_bus: |
and [devfn], 0 |
.next_dev: |
stdcall PciRead32, [bus], [devfn], dword 0 |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
mov edi, devices |
@@: |
mov ebx, [edi] |
test ebx, ebx |
jz .next |
cmp eax, ebx |
je .found |
add edi, 12 |
jmp @B |
.next: |
inc [devfn] |
cmp [devfn], 256 |
jb .next_dev |
mov eax, [bus] |
inc eax |
mov [bus], eax |
cmp eax, [last_bus] |
jna .next_bus |
xor eax, eax |
ret |
.found: |
mov ebx, [bus] |
mov [ctrl.bus], ebx |
mov ecx, [devfn] |
mov [ctrl.devfn], ecx |
mov edx, eax |
and edx, 0xFFFF |
mov [ctrl.vendor], edx |
shr eax, 16 |
mov [ctrl.dev_id], eax |
mov ebx, [edi+4] |
mov [ctrl.ctrl_ids], ebx |
mov [ctrl.vendor_ids], msg_SIS |
mov esi, [edi+8] |
mov [ctrl.ctrl_setup], esi |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc init_controller |
stdcall PciRead32, [ctrl.bus], [ctrl.devfn], dword 4 |
mov ebx, eax |
and eax, 0xFFFF |
mov [ctrl.pci_cmd], eax |
shr ebx, 16 |
mov [ctrl.pci_stat], ebx |
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 |
mov esi, msgControl |
call SysMsgBoardStr |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgStatus |
call SysMsgBoardStr |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
test eax, CTRL_ST_CREADY |
jnz .ready |
call reset_codec |
and eax, eax |
jz .err |
xor edx, edx ;ac_reg_0 |
call [ctrl.codec_write16] |
xor eax, eax |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_write16] |
mov [counter], 200 ; total 200*5 ms = 1s |
.wait: |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_read16] |
and eax, 0x0F |
cmp eax, 0x0F |
je .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 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
and eax, not 0x08 |
or eax, 0x02 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgCold |
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, msgCRFail |
call SysMsgBoardStr |
end if |
.fail: |
stc |
ret |
.ok: |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .fail |
clc |
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, 0x0 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
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 |
js @B |
pop eax |
pop ebx |
pop edx |
pop ecx |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; CONTROLLER IO functions |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
proc codec_io_r16 |
add edx, [ctrl.codec_io_base] |
in ax, dx |
ret |
endp |
align 4 |
proc codec_io_w16 |
add edx, [ctrl.codec_io_base] |
out dx, ax |
ret |
endp |
align 4 |
proc ctrl_io_r8 |
add edx, [ctrl.ctrl_io_base] |
in al, dx |
ret |
endp |
align 4 |
proc ctrl_io_r16 |
add edx, [ctrl.ctrl_io_base] |
in ax, dx |
ret |
endp |
align 4 |
proc ctrl_io_r32 |
add edx, [ctrl.ctrl_io_base] |
in eax, dx |
ret |
endp |
align 4 |
proc ctrl_io_w8 |
add edx, [ctrl.ctrl_io_base] |
out dx, al |
ret |
endp |
align 4 |
proc ctrl_io_w16 |
add edx, [ctrl.ctrl_io_base] |
out dx, ax |
ret |
endp |
align 4 |
proc ctrl_io_w32 |
add edx, [ctrl.ctrl_io_base] |
out dx, eax |
ret |
endp |
align 4 |
dword2str: |
mov esi, hex_buff |
mov ecx, -8 |
@@: |
rol eax, 4 |
mov ebx, eax |
and ebx, 0x0F |
mov bl, [ebx+hexletters] |
mov [8+esi+ecx], bl |
inc ecx |
jnz @B |
ret |
include "codec.inc" |
align 4 |
devices dd (CTRL_SIS shl 16)+VID_SIS,msg_AC, set_SIS |
dd 0 |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
msg_AC db '7012 AC97 controller',13,10, 0 |
msg_SIS db 'Silicon Integrated Systems',13,10, 0 |
sz_sound_srv db 'SOUND',0 |
msgInit db 'detect hardware...',13,10,0 |
msgFail db 'device not found',13,10,0 |
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 |
msgStatus db 'global status ',0 |
msgControl db 'global control ',0 |
hexletters db '0123456789ABCDEF' |
hex_buff db 8 dup(0),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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/drivers/sound.asm |
---|
0,0 → 1,1441 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
format MS COFF |
include 'proc32.inc' |
include 'imports.inc' |
API_VERSION equ 0x01000100 |
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 |
PCM_4 equ BIT20 |
PCM_6 equ BIT21 |
VID_INTEL equ 0x8086 |
VID_NVIDIA equ 0x10DE |
CTRL_ICH equ 0x2415 |
CTRL_ICH0 equ 0x2425 |
CTRL_ICH2 equ 0x2435 |
CTRL_ICH3 equ 0x2445 |
CTRL_ICH4 equ 0x24C5 |
CTRL_ICH5 equ 0x24D5 |
CTRL_ICH6 equ 0x266E |
CTRL_ICH7 equ 0x27DE |
CTRL_NFORCE equ 0x01B1 |
CTRL_NFORCE2 equ 0x006A |
CTRL_NFORCE3 equ 0x00DA |
CTRL_MCP04 equ 0x003A |
CTRL_CK804 equ 0x0059 |
CTRL_CK8 equ 0x008A |
CTRL_CK8S equ 0x00EA |
CTRL_MCP51 equ 0x026B |
PCM_OUT_BDL equ 0x10 ; PCM out buffer descriptors list |
PCM_OUT_CR_REG equ 0x1b ; PCM out Control Register |
PCM_OUT_LVI_REG equ 0x15 ; PCM last valid index |
PCM_OUT_SR_REG equ 0x16 ; PCM out Status register |
PCM_OUT_PIV_REG equ 0x1a |
PCM_OUT_CIV_REG equ 0x14 ; PCM out current index |
PCM_IN_CR_REG equ 0x0b ; PCM in Control Register |
MC_IN_CR_REG equ 0x2b ; MIC in Control Register |
RR equ BIT1 ; reset registers. Nukes all regs |
CODEC_MASTER_VOL_REG equ 0x02 |
CODEC_AUX_VOL equ 0x04 ; |
CODEC_PCM_OUT_REG equ 0x18 ; PCM output volume |
CODEC_EXT_AUDIO_REG equ 0x28 ; extended audio |
CODEC_EXT_AUDIO_CTRL_REG equ 0x2a ; extended audio control |
CODEC_PCM_FRONT_DACRATE_REG equ 0x2c ; PCM out sample rate |
CODEC_PCM_SURND_DACRATE_REG equ 0x2e ; surround sound sample rate |
CODEC_PCM_LFE_DACRATE_REG equ 0x30 ; LFE sample rate |
GLOB_CTRL equ 0x2C ; Global Control |
CTRL_STAT equ 0x30 ; Global Status |
CTRL_CAS equ 0x34 ; Codec Access Semiphore |
CAS_FLAG equ 0x01 ; Codec Access Semiphore Bit |
CTRL_ST_CREADY equ BIT8+BIT9+BIT28 ; Primary Codec Ready |
CTRL_ST_RCS equ 0x00008000 ; Read Completion Status |
CTRL_CNT_CRIE equ BIT4+BIT5+BIT6 ; Codecs Resume Interrupt Enable |
CTRL_CNT_AC_OFF equ 0x00000008 ; ACLINK Off |
CTRL_CNT_WARM equ 0x00000004 ; AC97 Warm Reset |
CTRL_CNT_COLD equ 0x00000002 ; AC97 Cold Reset |
CTRL_CNT_GIE equ 0x00000001 ; GPI Interrupt Enable |
CODEC_REG_POWERDOWN equ 0x26 |
CODEC_REG_ST equ 0x26 |
SRV_GETVERSION equ 0 |
DEV_PLAY equ 1 |
DEV_STOP equ 2 |
DEV_CALLBACK equ 3 |
DEV_SET_BUFF equ 4 |
DEV_NOTIFY equ 5 |
DEV_SET_MASTERVOL equ 6 |
DEV_GET_MASTERVOL equ 7 |
DEV_GET_INFO equ 8 |
struc AC_CNTRL ;AC controller base class |
{ .bus dd ? |
.devfn dd ? |
.vendor dd ? |
.dev_id dd ? |
.pci_cmd dd ? |
.pci_stat dd ? |
.codec_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_io_base dd ? |
.ctrl_mem_base dd ? |
.cfg_reg dd ? |
.int_line dd ? |
.vendor_ids dd ? ;vendor id string |
.ctrl_ids dd ? ;hub id string |
.buffer dd ? |
.notify_pos dd ? |
.notify_task dd ? |
.lvi_reg dd ? |
.ctrl_setup dd ? |
.user_callback dd ? |
.codec_read16 dd ? |
.codec_write16 dd ? |
.ctrl_read8 dd ? |
.ctrl_read16 dd ? |
.ctrl_read32 dd ? |
.ctrl_write8 dd ? |
.ctrl_write16 dd ? |
.ctrl_write32 dd ? |
} |
struc CODEC ;Audio Chip base class |
{ |
.chip_id dd ? |
.flags dd ? |
.status dd ? |
.ac_vendor_ids dd ? ;ac vendor id string |
.chip_ids dd ? ;chip model string |
.shadow_flag dd ? |
dd ? |
.regs dw ? ; codec registers |
.reg_master_vol dw ? ;0x02 |
.reg_aux_out_vol dw ? ;0x04 |
.reg_mone_vol dw ? ;0x06 |
.reg_master_tone dw ? ;0x08 |
.reg_beep_vol dw ? ;0x0A |
.reg_phone_vol dw ? ;0x0C |
.reg_mic_vol dw ? ;0x0E |
.reg_line_in_vol dw ? ;0x10 |
.reg_cd_vol dw ? ;0x12 |
.reg_video_vol dw ? ;0x14 |
.reg_aux_in_vol dw ? ;0x16 |
.reg_pcm_out_vol dw ? ;0x18 |
.reg_rec_select dw ? ;0x1A |
.reg_rec_gain dw ? ;0x1C |
.reg_rec_gain_mic dw ? ;0x1E |
.reg_gen dw ? ;0x20 |
.reg_3d_ctrl dw ? ;0X22 |
.reg_page dw ? ;0X24 |
.reg_powerdown dw ? ;0x26 |
.reg_ext_audio dw ? ;0x28 |
.reg_ext_st dw ? ;0x2a |
.reg_pcm_front_rate dw ? ;0x2c |
.reg_pcm_surr_rate dw ? ;0x2e |
.reg_lfe_rate dw ? ;0x30 |
.reg_pcm_in_rate dw ? ;0x32 |
dw ? ;0x34 |
.reg_cent_lfe_vol dw ? ;0x36 |
.reg_surr_vol dw ? ;0x38 |
.reg_spdif_ctrl dw ? ;0x3A |
dw ? ;0x3C |
dw ? ;0x3E |
dw ? ;0x40 |
dw ? ;0x42 |
dw ? ;0x44 |
dw ? ;0x46 |
dw ? ;0x48 |
dw ? ;0x4A |
dw ? ;0x4C |
dw ? ;0x4E |
dw ? ;0x50 |
dw ? ;0x52 |
dw ? ;0x54 |
dw ? ;0x56 |
dw ? ;0x58 |
dw ? ;0x5A |
dw ? ;0x5C |
dw ? ;0x5E |
.reg_page_0 dw ? ;0x60 |
.reg_page_1 dw ? ;0x62 |
.reg_page_2 dw ? ;0x64 |
.reg_page_3 dw ? ;0x66 |
.reg_page_4 dw ? ;0x68 |
.reg_page_5 dw ? ;0x6A |
.reg_page_6 dw ? ;0x6C |
.reg_page_7 dw ? ;0x6E |
dw ? ;0x70 |
dw ? ;0x72 |
dw ? ;0x74 |
dw ? ;0x76 |
dw ? ;0x78 |
dw ? ;0x7A |
.reg_vendor_id_1 dw ? ;0x7C |
.reg_vendor_id_2 dw ? ;0x7E |
.reset dd ? ;virual |
.set_master_vol dd ? |
} |
struc CTRL_INFO |
{ .pci_cmd dd ? |
.irq dd ? |
.glob_cntrl dd ? |
.glob_sta dd ? |
.codec_io_base dd ? |
.ctrl_io_base dd ? |
.codec_mem_base dd ? |
.ctrl_mem_base dd ? |
.codec_id dd ? |
} |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
EVENT_NOTIFY equ 0x00000200 |
OS_BASE equ 0x80000000 |
SLOT_BASE equ OS_BASE+0x0080000 |
public START |
public service_proc |
public version |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .stop |
if DEBUG |
mov esi, msgInit |
call SysMsgBoardStr |
end if |
call detect_controller |
test eax, eax |
jz .fail |
if DEBUG |
mov esi,[ctrl.vendor_ids] |
call SysMsgBoardStr |
mov esi, [ctrl.ctrl_ids] |
call SysMsgBoardStr |
end if |
call init_controller |
test eax, eax |
jz .fail |
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 |
.reg: |
stdcall RegService, sz_sound_srv, service_proc |
ret |
.fail: |
if DEBUG |
mov esi, msgFail |
call SysMsgBoardStr |
end if |
xor eax, eax |
ret |
.stop: |
call stop |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov edi, [ioctl] |
mov eax, [edi+io_code] |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [edi+output] |
cmp [edi+out_size], 4 |
jne .fail |
mov [eax], dword API_VERSION |
xor eax, eax |
ret |
@@: |
cmp eax, DEV_PLAY |
jne @F |
if DEBUG |
mov esi, msgPlay |
call SysMsgBoardStr |
end if |
call play |
ret |
@@: |
cmp eax, DEV_STOP |
jne @F |
if DEBUG |
mov esi, msgStop |
call SysMsgBoardStr |
end if |
call stop |
ret |
@@: |
cmp eax, DEV_CALLBACK |
jne @F |
mov ebx, [edi+input] |
stdcall set_callback, [ebx] |
ret |
@@: |
cmp eax, DEV_SET_MASTERVOL |
jne @F |
mov eax, [edi+input] |
mov eax, [eax] |
call set_master_vol ;eax= vol |
ret |
@@: |
cmp eax, DEV_GET_MASTERVOL |
jne @F |
mov ebx, [edi+output] |
stdcall get_master_vol, ebx |
ret |
;@@: |
; cmp eax, DEV_GET_INFO |
; jne @F |
; mov ebx, [edi+output] |
; stdcall get_dev_info, ebx |
; ret |
@@: |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc 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, 0x10; 0x10 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
mov edx, PCM_OUT_CIV_REG |
call [ctrl.ctrl_read8] |
and eax, 0x1F |
cmp eax, [civ_val] |
je .skip |
mov [civ_val], eax |
dec eax |
and eax, 0x1F |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 ;0x1D |
call [ctrl.ctrl_write8] |
mov eax, [civ_val] |
add eax, 1 |
and eax, 31 |
mov ebx, dword [buff_list+eax*4] |
cmp [ctrl.user_callback], 0 |
je @f |
stdcall [ctrl.user_callback], ebx |
@@: |
ret |
.skip: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x11 ;0x1D |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc create_primary_buff |
stdcall KernelAlloc, 0x10000 |
mov [ctrl.buffer], eax |
mov edi, eax |
mov ecx, 0x10000/4 |
xor eax, eax |
cld |
rep stosd |
mov eax, [ctrl.buffer] |
call GetPgAddr |
mov ebx, 0xC0002000 |
mov ecx, 4 |
mov edi, pcmout_bdl |
@@: |
mov [edi], eax |
mov [edi+4], ebx |
mov [edi+32], eax |
mov [edi+4+32], ebx |
mov [edi+64], eax |
mov [edi+4+64], ebx |
mov [edi+96], eax |
mov [edi+4+96], ebx |
mov [edi+128], eax |
mov [edi+4+128], ebx |
mov [edi+160], eax |
mov [edi+4+160], ebx |
mov [edi+192], eax |
mov [edi+4+192], ebx |
mov [edi+224], eax |
mov [edi+4+224], ebx |
add eax, 0x4000 |
add edi, 8 |
loop @B |
mov edi, buff_list |
mov eax, [ctrl.buffer] |
mov ecx, 4 |
@@: |
mov [edi], eax |
mov [edi+16], eax |
mov [edi+32], eax |
mov [edi+48], eax |
mov [edi+64], eax |
mov [edi+80], eax |
mov [edi+96], eax |
mov [edi+112], eax |
add eax, 0x4000 |
add edi, 4 |
loop @B |
mov eax, pcmout_bdl |
mov ebx, eax |
call GetPgAddr ;eax |
and ebx, 0xFFF |
add eax, ebx |
mov edx, PCM_OUT_BDL |
call [ctrl.ctrl_write32] |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
ret |
endp |
align 4 |
proc detect_controller |
locals |
last_bus dd ? |
bus dd ? |
devfn dd ? |
endl |
xor eax, eax |
mov [bus], eax |
inc eax |
call PciApi |
cmp eax, -1 |
je .err |
mov [last_bus], eax |
.next_bus: |
and [devfn], 0 |
.next_dev: |
stdcall PciRead32, [bus], [devfn], dword 0 |
test eax, eax |
jz .next |
cmp eax, -1 |
je .next |
mov edi, devices |
@@: |
mov ebx, [edi] |
test ebx, ebx |
jz .next |
cmp eax, ebx |
je .found |
add edi, 12 |
jmp @B |
.next: |
inc [devfn] |
cmp [devfn], 256 |
jb .next_dev |
mov eax, [bus] |
inc eax |
mov [bus], eax |
cmp eax, [last_bus] |
jna .next_bus |
xor eax, eax |
ret |
.found: |
mov ebx, [bus] |
mov [ctrl.bus], ebx |
mov ecx, [devfn] |
mov [ctrl.devfn], ecx |
mov edx, eax |
and edx, 0xFFFF |
mov [ctrl.vendor], edx |
shr eax, 16 |
mov [ctrl.dev_id], eax |
mov ebx, [edi+4] |
mov [ctrl.ctrl_ids], ebx |
mov esi, [edi+8] |
mov [ctrl.ctrl_setup], esi |
cmp 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 |
mov esi, msgControl |
call SysMsgBoardStr |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
mov esi, msgStatus |
call SysMsgBoardStr |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
call dword2str |
call SysMsgBoardStr |
test eax, CTRL_ST_CREADY |
jnz .ready |
call reset_codec |
and eax, eax |
jz .err |
xor edx, edx ;ac_reg_0 |
call [ctrl.codec_write16] |
xor eax, eax |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_write16] |
mov [counter], 200 ; total 200*5 ms = 1s |
.wait: |
mov edx, CODEC_REG_POWERDOWN |
call [ctrl.codec_read16] |
and eax, 0x0F |
cmp eax, 0x0F |
jz .ready |
mov eax, 5000 ; wait 5 ms |
call StallExec |
sub [counter] , 1 |
jnz .wait |
.err: |
xor eax, eax ; timeout error |
ret |
.ready: |
mov eax, 2 ;force set 16-bit 2-channel PCM |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
mov eax, 5000 ; wait 5 ms |
call StallExec |
call detect_codec |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc reset_codec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 0x02 |
jz .cold |
call warm_reset |
jnc .ok |
.cold: |
call cold_reset |
jnc .ok |
if DEBUG |
mov esi, msgCFail |
call SysMsgBoardStr |
end if |
xor eax, eax ; timeout error |
ret |
.ok: |
if DEBUG |
mov esi, msgResetOk |
call SysMsgBoardStr |
end if |
xor eax, eax |
inc eax |
ret |
endp |
align 4 |
proc warm_reset |
locals |
counter dd ? |
endl |
mov eax, 0x06 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgWarm |
call SysMsgBoardStr |
end if |
mov [counter], 10 ; total 10*100 ms = 1s |
.wait: |
mov eax, 100000 ; wait 100 ms |
call StallExec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 4 |
jz .ok |
sub [counter], 1 |
jnz .wait |
if DEBUG |
mov esi, msgWRFail |
call SysMsgBoardStr |
end if |
stc |
ret |
.ok: |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .fail |
clc |
ret |
.fail: |
stc |
ret |
endp |
align 4 |
proc cold_reset |
locals |
counter dd ? |
endl |
xor eax, eax |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
if DEBUG |
mov esi, msgCold |
call SysMsgBoardStr |
end if |
mov eax, 1000000 ; wait 1 s |
call StallExec |
mov eax, 2 |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_write32] |
mov [counter], 10 ; total 10*100 ms = 1s |
.wait: |
mov eax, 100000 ; wait 100 ms |
call StallExec |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
test eax, 4 |
jz .ok |
sub [counter], 1 |
jnz .wait |
if DEBUG |
mov esi, msgCRFail |
call SysMsgBoardStr |
end if |
stc |
ret |
.ok: |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .fail |
clc |
ret |
.fail: |
stc |
ret |
endp |
align 4 |
play: |
mov eax, 16 |
mov [ctrl.lvi_reg], eax |
mov edx, PCM_OUT_LVI_REG |
call [ctrl.ctrl_write8] |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x1D |
call [ctrl.ctrl_write8] |
xor eax, eax |
ret |
align 4 |
stop: |
mov edx, PCM_OUT_CR_REG |
mov ax, 0x0 |
call [ctrl.ctrl_write8] |
mov ax, 0x1c |
mov edx, PCM_OUT_SR_REG |
call [ctrl.ctrl_write16] |
xor eax, eax |
ret |
align 4 |
proc get_dev_info stdcall, p_info:dword |
virtual at esi |
CTRL_INFO CTRL_INFO |
end virtual |
mov esi, [p_info] |
mov eax, [ctrl.int_line] |
mov ebx, [ctrl.codec_io_base] |
mov ecx, [ctrl.ctrl_io_base] |
mov edx, [ctrl.codec_mem_base] |
mov edi, [ctrl.ctrl_mem_base] |
mov [CTRL_INFO.irq], eax |
mov [CTRL_INFO.codec_io_base], ebx |
mov [CTRL_INFO.ctrl_io_base], ecx |
mov [CTRL_INFO.codec_mem_base], edx |
mov [CTRL_INFO.ctrl_mem_base], edi |
mov eax, [codec.chip_id] |
mov [CTRL_INFO.codec_id], eax |
mov edx, GLOB_CTRL |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_cntrl], eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
mov [CTRL_INFO.glob_sta], eax |
mov ebx, [ctrl.pci_cmd] |
mov [CTRL_INFO.pci_cmd], ebx |
ret |
endp |
align 4 |
proc set_callback stdcall, handler:dword |
mov eax, [handler] |
mov [ctrl.user_callback], eax |
ret |
endp |
align 4 |
proc codec_read stdcall, ac_reg:dword ; reg = edx, reval = eax |
mov edx, [ac_reg] |
mov ebx, edx |
shr ebx, 1 |
bt [codec.shadow_flag], ebx |
jc .use_shadow |
call [ctrl.codec_read16] ;change edx !!! |
mov ecx, eax |
mov edx, CTRL_STAT |
call [ctrl.ctrl_read32] |
test eax, CTRL_ST_RCS |
jz .read_ok |
mov edx, CTRL_STAT |
call [ctrl.ctrl_write32] |
xor eax,eax |
not eax ;timeout |
ret |
.read_ok: |
mov edx, [ac_reg] |
mov [codec.regs+edx], cx |
bts [codec.shadow_flag], ebx |
mov eax, ecx |
ret |
.use_shadow: |
movzx eax, word [codec.regs+edx] |
ret |
endp |
align 4 |
proc codec_write stdcall, ac_reg:dword |
push eax |
call check_semafore |
and eax, eax |
jz .err |
pop eax |
mov esi, [ac_reg] |
mov edx, esi |
call [ctrl.codec_write16] |
mov [codec.regs+esi], ax |
shr esi, 1 |
bts [codec.shadow_flag], esi |
ret |
.err: |
pop eax |
ret |
endp |
align 4 |
proc codec_check_ready |
mov edx, CTRL_ST |
call [ctrl.ctrl_read32] |
and eax, CTRL_ST_CREADY |
jz .not_ready |
xor eax, wax |
inc eax |
ret |
.not_ready: |
xor eax, eax |
ret |
endp |
align 4 |
proc check_semafore |
local counter:DWORD |
mov [counter], 100 |
.l1: |
mov edx, CTRL_CAS |
call [ctrl.ctrl_read8] |
and eax, CAS_FLAG |
jz .ok |
mov eax, 1 |
call StallExec |
sub [counter], 1 |
jnz .l1 |
xor eax, eax |
ret |
align 4 |
.ok: |
xor eax,eax |
inc eax |
ret |
endp |
align 4 |
proc StallExec |
push ecx |
push edx |
push ebx |
push eax |
mov ecx, CPU_FREQ |
mul ecx |
mov ebx, eax ;low |
mov ecx, edx ;high |
rdtsc |
add ebx, eax |
adc ecx,edx |
@@: |
rdtsc |
sub eax, ebx |
sbb edx, ecx |
js @B |
pop eax |
pop ebx |
pop edx |
pop ecx |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; CONTROLLER IO functions |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
proc codec_io_r16 |
add edx, [ctrl.codec_io_base] |
in ax, dx |
ret |
endp |
align 4 |
proc codec_io_w16 |
add edx, [ctrl.codec_io_base] |
out dx, ax |
ret |
endp |
align 4 |
proc ctrl_io_r8 |
add edx, [ctrl.ctrl_io_base] |
in al, dx |
ret |
endp |
align 4 |
proc ctrl_io_r16 |
add edx, [ctrl.ctrl_io_base] |
in ax, dx |
ret |
endp |
align 4 |
proc ctrl_io_r32 |
add edx, [ctrl.ctrl_io_base] |
in eax, dx |
ret |
endp |
align 4 |
proc ctrl_io_w8 |
add edx, [ctrl.ctrl_io_base] |
out dx, al |
ret |
endp |
align 4 |
proc ctrl_io_w16 |
add edx, [ctrl.ctrl_io_base] |
out dx, ax |
ret |
endp |
align 4 |
proc ctrl_io_w32 |
add edx, [ctrl.ctrl_io_base] |
out dx, eax |
ret |
endp |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; MEMORY MAPPED IO (os depended) |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
proc codec_mem_r16 |
add edx, [ctrl.codec_mem_base] |
mov ax, word [edx] |
ret |
endp |
align 4 |
proc codec_mem_w16 |
add edx, [ctrl.codec_mem_base] |
mov word [edx], ax |
ret |
endp |
align 4 |
proc ctrl_mem_r8 |
add edx, [ctrl.ctrl_mem_base] |
mov al, [edx] |
ret |
endp |
align 4 |
proc ctrl_mem_r16 |
add edx, [ctrl.ctrl_mem_base] |
mov ax, [edx] |
ret |
endp |
align 4 |
proc ctrl_mem_r32 |
add edx, [ctrl.ctrl_mem_base] |
mov eax, [edx] |
ret |
endp |
align 4 |
proc ctrl_mem_w8 |
add edx, [ctrl.ctrl_mem_base] |
mov [edx], al |
ret |
endp |
align 4 |
proc ctrl_mem_w16 |
add edx, [ctrl.ctrl_mem_base] |
mov [edx], ax |
ret |
endp |
align 4 |
proc ctrl_mem_w32 |
add edx, [ctrl.ctrl_mem_base] |
mov [edx], eax |
ret |
endp |
align 4 |
dword2str: |
mov esi, hex_buff |
mov ecx, -8 |
@@: |
rol eax, 4 |
mov ebx, eax |
and ebx, 0x0F |
mov bl, [ebx+hexletters] |
mov [8+esi+ecx], bl |
inc ecx |
jnz @B |
ret |
hexletters db '0123456789ABCDEF' |
hex_buff db 8 dup(0),13,10,0 |
include "codec.inc" |
align 4 |
devices dd (CTRL_ICH shl 16)+VID_INTEL,msg_ICH, set_ICH |
dd (CTRL_ICH0 shl 16)+VID_INTEL,msg_ICH0,set_ICH |
dd (CTRL_ICH2 shl 16)+VID_INTEL,msg_ICH2,set_ICH |
dd (CTRL_ICH3 shl 16)+VID_INTEL,msg_ICH3,set_ICH |
dd (CTRL_ICH4 shl 16)+VID_INTEL,msg_ICH4,set_ICH4 |
dd (CTRL_ICH5 shl 16)+VID_INTEL,msg_ICH5,set_ICH4 |
dd (CTRL_ICH6 shl 16)+VID_INTEL,msg_ICH6,set_ICH4 |
dd (CTRL_ICH7 shl 16)+VID_INTEL,msg_ICH7,set_ICH4 |
dd (CTRL_NFORCE shl 16)+VID_NVIDIA,msg_NForce, set_ICH |
dd (CTRL_NFORCE2 shl 16)+VID_NVIDIA,msg_NForce2,set_ICH |
dd (CTRL_NFORCE3 shl 16)+VID_NVIDIA,msg_NForce3,set_ICH |
dd (CTRL_MCP04 shl 16)+VID_NVIDIA,msg_MCP04,set_ICH |
dd (CTRL_CK804 shl 16)+VID_NVIDIA,msg_CK804,set_ICH |
dd (CTRL_CK8 shl 16)+VID_NVIDIA,msg_CK8,set_ICH |
dd (CTRL_CK8S shl 16)+VID_NVIDIA,msg_CK8S,set_ICH |
dd (CTRL_MCP51 shl 16)+VID_NVIDIA,msg_MCP51,set_ICH |
dd 0 ;terminator |
version dd (5 shl 16) or (API_VERSION and 0xFFFF) |
msg_ICH db '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 |
msgStatus db 'global status ',0 |
msgControl db 'global control ',0 |
section '.data' data readable writable align 16 |
pcmout_bdl rq 32 |
buff_list rd 32 |
codec CODEC |
ctrl AC_CNTRL |
lpc_bus rd 1 |
civ_val rd 1 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/drivers/uart.asm |
---|
0,0 → 1,972 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
format MS COFF |
include 'proc32.inc' |
include 'imports.inc' |
API_VERSION equ 0 |
UART_VERSION equ API_VERSION |
PG_SW equ 0x003 |
page_tabs equ 0xFDC00000 ;hack |
OS_BASE equ 0x80000000 |
SLOT_BASE equ (OS_BASE+0x0080000) |
TASK_COUNT equ (OS_BASE+0x0003004) |
CURRENT_TASK equ (OS_BASE+0x0003000) |
struc APPOBJ ;common object header |
{ |
.magic dd ? ; |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
}; |
virtual at 0 |
APPOBJ APPOBJ |
end virtual |
struc IOCTL |
{ .handle dd ? |
.io_code dd ? |
.input dd ? |
.inp_size dd ? |
.output dd ? |
.out_size dd ? |
} |
virtual at 0 |
IOCTL IOCTL |
end virtual |
DEBUG equ 1 |
DRV_ENTRY equ 1 |
DRV_EXIT equ -1 |
THR_REG equ 0; x3f8 ;transtitter/reciever |
IER_REG equ 1; x3f9 ;interrupt enable |
IIR_REG equ 2; x3fA ;interrupt info |
LCR_REG equ 3; x3FB ;line control |
MCR_REG equ 4; x3FC ;modem control |
LSR_REG equ 5; x3FD ;line status |
MSR_REG equ 6; x3FE ;modem status |
LCR_5BIT equ 0x00 |
LCR_6BIT equ 0x01 |
LCR_7BIT equ 0x02 |
LCR_8BIT equ 0x03 |
LCR_STOP_1 equ 0x00 |
LCR_STOP_2 equ 0x04 |
LCR_PARITY equ 0x08 |
LCR_EVEN equ 0x10 |
LCR_STICK equ 0x20 |
LCR_BREAK equ 0x40 |
LCR_DLAB equ 0x80 |
LSR_DR equ 0x01 ;data ready |
LSR_OE equ 0x02 ;overrun error |
LSR_PE equ 0x04 ;parity error |
LSR_FE equ 0x08 ;framing error |
LSR_BI equ 0x10 ;break interrupt |
LSR_THRE equ 0x20 ;transmitter holding empty |
LSR_TEMT equ 0x40 ;transmitter empty |
LSR_FER equ 0x80 ;FIFO error |
FCR_EFIFO equ 0x01 ;enable FIFO |
FCR_CRB equ 0x02 ;clear reciever FIFO |
FCR_CXMIT equ 0x04 ;clear transmitter FIFO |
FCR_RDY equ 0x08 ;set RXRDY and TXRDY pins |
FCR_FIFO_1 equ 0x00 ;1 byte trigger |
FCR_FIFO_4 equ 0x40 ;4 bytes trigger |
FCR_FIFO_8 equ 0x80 ;8 bytes trigger |
FCR_FIFO_14 equ 0xC0 ;14 bytes trigger |
IIR_INTR equ 0x01 ;1= no interrupts |
IER_RDAI equ 0x01 ;reciever data interrupt |
IER_THRI equ 0x02 ;transmitter empty interrupt |
IER_LSI equ 0x04 ;line status interrupt |
IER_MSI equ 0x08 ;modem status interrupt |
MCR_DTR equ 0x01 ;0-> DTR=1, 1-> DTR=0 |
MCR_RTS equ 0x02 ;0-> RTS=1, 1-> RTS=0 |
MCR_OUT_1 equ 0x04 ;0-> OUT1=1, 1-> OUT1=0 |
MCR_OUT_2 equ 0x08 ;0-> OUT2=1, 1-> OUT2=0; enable intr |
MCR_LOOP equ 0x10 ;lopback mode |
MSR_DCTS equ 0x01 ;delta clear to send |
MSR_DDSR equ 0x02 ;delta data set redy |
MSR_TERI equ 0x04 ;trailinh edge of ring |
MSR_DDCD equ 0x08 ;delta carrier detect |
RATE_50 equ 0 |
RATE_75 equ 1 |
RATE_110 equ 2 |
RATE_134 equ 3 |
RATE_150 equ 4 |
RATE_300 equ 5 |
RATE_600 equ 6 |
RATE_1200 equ 7 |
RATE_1800 equ 8 |
RATE_2000 equ 9 |
RATE_2400 equ 10 |
RATE_3600 equ 11 |
RATE_4800 equ 12 |
RATE_7200 equ 13 |
RATE_9600 equ 14 |
RATE_19200 equ 15 |
RATE_38400 equ 16 |
RATE_57600 equ 17 |
RATE_115200 equ 18 |
COM_1 equ 1 |
COM_2 equ 2 |
COM_3 equ 3 |
COM_4 equ 4 |
COM_MAX equ 2 ;only two port supported |
COM_1_BASE equ 0x3F8 |
COM_2_BASE equ 0x2F8 |
COM_1_IRQ equ 4 |
COM_2_IRQ equ 3 |
UART_CLOSED equ 0 |
UART_TRANSMIT equ 1 |
UART_STOP equ 2 |
struc UART |
{ |
.lock dd ? |
.base dd ? |
.lcr_reg dd ? |
.mcr_reg dd ? |
.rate dd ? |
.mode dd ? |
.state dd ? |
.rcvr_buff dd ? |
.rcvr_rp dd ? |
.rcvr_wp dd ? |
.rcvr_count dd ? |
.rcvr_top dd ? |
.xmit_buff dd ? |
.xmit_rp dd ? |
.xmit_wp dd ? |
.xmit_count dd ? |
.xmit_free dd ? |
.xmit_top dd ? |
} |
virtual at 0 |
UART UART |
end virtual |
UART_SIZE equ 18*4 |
struc CONNECTION |
{ |
.magic dd ? ;'CNCT' |
.destroy dd ? ;internal destructor |
.fd dd ? ;next object in list |
.bk dd ? ;prev object in list |
.pid dd ? ;owner id |
.id dd ? ;reserved |
.uart dd ? ;uart pointer |
} |
virtual at 0 |
CONNECTION CONNECTION |
end virtual |
CONNECTION_SIZE equ 7*4 |
public START |
public service_proc |
public version |
section '.flat' code readable align 16 |
proc START stdcall, state:dword |
cmp [state], 1 |
jne .stop |
mov eax, UART_SIZE |
call Kmalloc |
test eax, eax |
jz .fail |
mov [com1], eax |
mov edi, eax |
mov ecx, UART_SIZE/4 |
xor eax, eax |
cld |
rep stosd |
mov eax, [com1] |
mov [eax+UART.base], COM_1_BASE |
stdcall AllocKernelSpace, 32768 |
mov edi, [com1] |
mov edx, eax |
mov [edi+UART.rcvr_buff], eax |
add eax, 8192 |
mov [edi+UART.rcvr_top], eax |
add eax, 8192 |
mov [edi+UART.xmit_buff], eax |
add eax, 8192 |
mov [edi+UART.xmit_top], eax |
call AllocPage |
test eax, eax |
jz .fail |
shr edx, 12 |
or eax, PG_SW |
mov [page_tabs+edx*4], eax |
mov [page_tabs+edx*4+8], eax |
call AllocPage |
test eax, eax |
jz .fail |
or eax, PG_SW |
mov [page_tabs+edx*4+4], eax |
mov [page_tabs+edx*4+12], eax |
call AllocPage |
test eax, eax |
jz .fail |
or eax, PG_SW |
mov [page_tabs+edx*4+16], eax |
mov [page_tabs+edx*4+24], eax |
call AllocPage |
test eax, eax |
jz .fail |
or eax, PG_SW |
mov [page_tabs+edx*4+20], eax |
mov [page_tabs+edx*4+28], eax |
mov eax, [edi+UART.rcvr_buff] |
invlpg [eax] |
invlpg [eax+0x1000] |
invlpg [eax+0x2000] |
invlpg [eax+0x3000] |
invlpg [eax+0x4000] |
invlpg [eax+0x5000] |
invlpg [eax+0x6000] |
invlpg [eax+0x7000] |
mov eax, edi |
call uart_reset.internal ;eax= uart |
stdcall AttachIntHandler, COM_1_IRQ, com_1_isr |
stdcall RegService, sz_uart_srv, service_proc |
ret |
.fail: |
.stop: |
xor eax, eax |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
SRV_GETVERSION equ 0 |
PORT_OPEN equ 1 |
PORT_CLOSE equ 2 |
PORT_RESET equ 3 |
PORT_SETMODE equ 4 |
PORT_GETMODE equ 5 |
PORT_SETMCR equ 6 |
PORT_GETMCR equ 7 |
PORT_READ equ 8 |
PORT_WRITE equ 9 |
align 4 |
proc service_proc stdcall, ioctl:dword |
mov ebx, [ioctl] |
mov eax, [ebx+io_code] |
cmp eax, PORT_WRITE |
ja .fail |
cmp eax, SRV_GETVERSION |
jne @F |
mov eax, [ebx+output] |
cmp [ebx+out_size], 4 |
jne .fail |
mov [eax], dword UART_VERSION |
xor eax, eax |
ret |
@@: |
cmp eax, PORT_OPEN |
jne @F |
cmp [ebx+out_size], 4 |
jne .fail |
mov ebx, [ebx+input] |
mov eax, [ebx] |
call uart_open |
mov ebx, [ioctl] |
mov ebx, [ebx+output] |
mov [ebx], ecx |
ret |
@@: |
mov esi, [ebx+input] ;input buffer |
mov edi, [ebx+output] |
call [uart_func+eax*4] |
ret |
.fail: |
or eax, -1 |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
; param |
; esi= input buffer |
; +0 connection |
; |
; retval |
; eax= error code |
align 4 |
uart_reset: |
mov eax, [esi] |
cmp [eax+APPOBJ.magic], 'CNCT' |
jne .fail |
cmp [eax+APPOBJ.destroy], uart_close.destroy |
jne .fail |
mov eax, [eax+CONNECTION.uart] |
test eax, eax |
jz .fail |
; set mode 2400 bod 8-bit |
; disable DTR & RTS |
; clear FIFO |
; clear pending interrupts |
; |
; param |
; eax= uart |
align 4 |
.internal: |
mov esi, eax |
mov [eax+UART.state], UART_CLOSED |
mov edx, [eax+UART.base] |
add edx, MCR_REG |
xor eax, eax |
out dx, al ;clear DTR & RTS |
mov eax, esi |
mov ebx, RATE_2400 |
mov ecx, LCR_8BIT+LCR_STOP_1 |
call uart_set_mode.internal |
mov edx, [esi+UART.base] |
add edx, IIR_REG |
mov eax,FCR_EFIFO+FCR_CRB+FCR_CXMIT+FCR_FIFO_14 |
out dx, al |
.clear_RB: |
mov edx, [esi+UART.base] |
add edx, LSR_REG |
in al, dx |
test eax, LSR_DR |
jz @F |
mov edx, [esi+UART.base] |
in al, dx |
jmp .clear_RB |
@@: |
mov edx, [esi+UART.base] |
add edx, IER_REG |
mov eax,IER_RDAI+IER_THRI+IER_LSI |
out dx, al |
.clear_IIR: |
mov edx, [esi+UART.base] |
add edx, IIR_REG |
in al, dx |
test al, IIR_INTR |
jnz .done |
shr eax, 1 |
and eax, 3 |
jnz @F |
mov edx, [esi+UART.base] |
add edx, MSR_REG |
in al, dx |
jmp .clear_IIR |
@@: |
cmp eax, 1 |
je .clear_IIR |
cmp eax, 2 |
jne @F |
mov edx, [esi+UART.base] |
in al, dx |
jmp .clear_IIR |
@@: |
mov edx, [esi+UART.base] |
add edx, LSR_REG |
in al, dx |
jmp .clear_IIR |
.done: |
mov edi, [esi+UART.rcvr_buff] |
mov ecx, 8192/4 |
xor eax, eax |
mov [esi+UART.rcvr_rp], edi |
mov [esi+UART.rcvr_wp], edi |
mov [esi+UART.rcvr_count], eax |
cld |
rep stosd |
mov edi, [esi+UART.xmit_buff] |
mov ecx, 8192/4 |
mov [esi+UART.xmit_rp], edi |
mov [esi+UART.xmit_wp], edi |
mov [esi+UART.xmit_count], eax |
mov [esi+UART.xmit_free], 8192 |
rep stosd |
ret ;eax= 0 |
.fail: |
or eax, -1 |
ret |
; param |
; esi= input buffer |
; +0 connection |
; +4 rate |
; +8 mode |
; |
; retval |
; eax= error code |
align 4 |
uart_set_mode: |
mov eax, [esi] |
cmp [eax+APPOBJ.magic], 'CNCT' |
jne .fail |
cmp [eax+APPOBJ.destroy], uart_close.destroy |
jne .fail |
mov eax, [eax+CONNECTION.uart] |
test eax, eax |
jz .fail |
mov ebx, [esi+4] |
mov ecx, [esi+8] |
; param |
; eax= uart |
; ebx= baud rate |
; ecx= mode |
align 4 |
.internal: |
cmp ebx, RATE_115200 |
ja .fail |
cmp ecx, LCR_BREAK |
jae .fail |
mov [eax+UART.rate], ebx |
mov [eax+UART.mode], ecx |
mov esi, eax |
mov bx, [divisor+ebx*2] |
mov edx, [esi+UART.base] |
push edx |
add edx, LCR_REG |
in al, dx |
or al, 0x80 |
out dx, al |
pop edx |
mov al, bl |
out dx, al |
inc dx |
mov al, bh |
out dx, al |
add edx, LCR_REG-1 |
mov eax, ecx |
out dx, al |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
; param |
; esi= input buffer |
; +0 connection |
; +4 modem control reg valie |
; |
; retval |
; eax= error code |
align 4 |
uart_set_mcr: |
mov eax, [esi] |
cmp [eax+APPOBJ.magic], 'CNCT' |
jne .fail |
cmp [eax+APPOBJ.destroy], uart_close.destroy |
jne .fail |
mov eax, [eax+CONNECTION.uart] |
test eax, eax |
jz .fail |
mov ebx, [esi+4] |
mov [eax+UART.mcr_reg], ebx |
mov edx, [eax+UART.base] |
add edx, MCR_REG |
mov al, bl |
out dx, al |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
; param |
; eax= port |
; |
; retval |
; ecx= connection |
; eax= error code |
align 4 |
uart_open: |
dec eax |
cmp eax, COM_MAX |
jae .fail |
mov esi, [com1+eax*4] ;uart |
push esi |
.do_wait: |
cmp dword [esi+UART.lock],0 |
je .get_lock |
; call change_task |
jmp .do_wait |
.get_lock: |
mov eax, 1 |
xchg eax, [esi+UART.lock] |
test eax, eax |
jnz .do_wait |
mov eax, esi ;uart |
call uart_reset.internal |
mov ebx, [CURRENT_TASK] |
shl ebx, 5 |
mov ebx, [CURRENT_TASK+ebx+4] |
mov eax, CONNECTION_SIZE |
call CreateObject |
pop esi ;uart |
test eax, eax |
jz .fail |
mov [eax+APPOBJ.magic], 'CNCT' |
mov [eax+APPOBJ.destroy], uart_close.destroy |
mov [eax+CONNECTION.uart], esi |
mov ecx, eax |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
restore .uart |
; param |
; esi= input buffer |
align 4 |
uart_close: |
mov eax, [esi] |
cmp [eax+APPOBJ.magic], 'CNCT' |
jne .fail |
cmp [eax+APPOBJ.destroy], uart_close.destroy |
jne .fail |
.destroy: |
push [eax+CONNECTION.uart] |
call DestroyObject ;eax= object |
pop eax ;eax= uart |
test eax, eax |
jz .fail |
mov [eax+UART.state], UART_CLOSED |
mov [eax+UART.lock], 0 ;release port |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
; param |
; eax= uart |
; ebx= baud rate |
align 4 |
set_rate: |
cmp ebx, RATE_115200 |
ja .fail |
mov [eax+UART.rate], ebx |
mov bx, [divisor+ebx*2] |
mov edx, [eax+UART.base] |
add edx, LCR_REG |
in al, dx |
push eax |
or al, 0x80 |
out dx, al |
sub edx, LCR_REG |
mov al, bl |
out dx, al |
inc edx |
mov al, bh |
out dx, al |
pop eax |
add edx, LCR_REG-1 |
out dx, al |
.fail: |
ret |
; param |
; ebx= uart |
align 4 |
transmit: |
push esi |
push edi |
mov edx, [ebx+UART.base] |
pushfd |
cli |
mov esi, [ebx+UART.xmit_rp] |
mov ecx, [ebx+UART.xmit_count] |
test ecx, ecx |
je .stop |
cmp ecx, 16 |
jbe @F |
mov ecx, 16 |
@@: |
sub [ebx+UART.xmit_count], ecx |
add [ebx+UART.xmit_free], ecx |
cld |
@@: |
lodsb |
out dx, al |
dec ecx |
jnz @B |
cmp esi,[ebx+UART.xmit_top] |
jb @F |
sub esi, 8192 |
@@: |
mov [ebx+UART.xmit_rp], esi |
cmp [ebx+UART.xmit_count], 0 |
je .stop |
mov [ebx+UART.state], UART_TRANSMIT |
jmp @F |
.stop: |
mov [ebx+UART.state], UART_STOP |
@@: |
popfd |
pop edi |
pop esi |
ret |
; param |
; esi= input buffer |
; +0 connection |
; +4 dst buffer |
; +8 dst size |
; edi= output buffer |
; +0 bytes read |
; retval |
; eax= error code |
align 4 |
uart_read: |
mov eax, [esi] |
cmp [eax+APPOBJ.magic], 'CNCT' |
jne .fail |
cmp [eax+APPOBJ.destroy], uart_close.destroy |
jne .fail |
mov eax, [eax+CONNECTION.uart] |
test eax, eax |
jz .fail |
mov ebx, [esi+8] ;dst size |
mov ecx, [eax+UART.rcvr_count] |
cmp ecx, ebx |
jbe @F |
mov ecx, ebx |
@@: |
mov [edi], ecx ;bytes read |
test ecx, ecx |
jz .done |
push ecx |
mov edi, [esi+4] ;dst |
mov esi, [eax+UART.rcvr_rp] |
cld |
rep movsb |
pop ecx |
cmp esi, [eax+UART.rcvr_top] |
jb @F |
sub esi, 8192 |
@@: |
mov [eax+UART.rcvr_rp], esi |
sub [eax+UART.rcvr_count], ecx |
.done: |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
; param |
; esi= input buffer |
; +0 connection |
; +4 src buffer |
; +8 src size |
; |
; retval |
; eax= error code |
align 4 |
uart_write: |
mov eax, [esi] |
cmp [eax+APPOBJ.magic], 'CNCT' |
jne .fail |
cmp [eax+APPOBJ.destroy], uart_close.destroy |
jne .fail |
mov eax, [eax+CONNECTION.uart] |
test eax, eax |
jz .fail |
mov ebx, [esi+4] |
mov edx, [esi+8] |
; param |
; eax= uart |
; ebx= src |
; edx= count |
align 4 |
.internal: |
mov esi, ebx |
mov edi, [eax+UART.xmit_wp] |
.write: |
test edx, edx |
jz .fail |
.wait: |
cmp [eax+UART.xmit_free], 0 |
jne .fill |
cmp [eax+UART.state], UART_TRANSMIT |
je .wait |
mov ebx, eax |
push edx |
call transmit |
pop edx |
mov eax, ebx |
jmp .write |
.fill: |
mov ecx, [eax+UART.xmit_free] |
cmp ecx, edx |
jbe @F |
mov ecx, edx |
@@: |
push ecx |
cld |
rep movsb |
pop ecx |
sub [eax+UART.xmit_free], ecx |
add [eax+UART.xmit_count], ecx |
sub edx, ecx |
jnz .wait |
.done: |
cmp edi, [eax+UART.xmit_top] |
jb @F |
sub edi, 8192 |
@@: |
mov [eax+UART.xmit_wp], edi |
cmp [eax+UART.state], UART_TRANSMIT |
je @F |
mov ebx, eax |
call transmit |
@@: |
xor eax, eax |
ret |
.fail: |
or eax, -1 |
ret |
align 4 |
com_2_isr: |
mov ebx, [com2] |
jmp com_1_isr.get_info |
align 4 |
com_1_isr: |
mov ebx, [com1] |
.get_info: |
mov edx, [ebx+UART.base] |
add edx, IIR_REG |
in al, dx |
test al, IIR_INTR |
jnz .done |
shr eax, 1 |
and eax, 3 |
call [isr_action+eax*4] |
jmp .get_info |
.done: |
ret |
align 4 |
isr_line: |
mov edx, [ebx+UART.base] |
add edx, LSR_REG |
in al, dx |
ret |
align 4 |
isr_recieve: |
mov esi, [ebx+UART.base] |
add esi, LSR_REG |
mov edi, [ebx+UART.rcvr_wp] |
xor ecx, ecx |
cld |
.read: |
mov edx, esi |
in al, dx |
test eax, LSR_DR |
jz .done |
mov edx, [ebx+UART.base] |
in al, dx |
stosb |
inc ecx |
jmp .read |
.done: |
cmp edi, [ebx+UART.rcvr_top] |
jb @F |
sub edi, 8192 |
@@: |
mov [ebx+UART.rcvr_wp], edi |
add [ebx+UART.rcvr_count], ecx |
ret |
align 4 |
isr_modem: |
mov edx, [ebx+UART.base] |
add edx, MSR_REG |
in al, dx |
ret |
align 4 |
divisor dw 2304, 1536, 1047, 857, 768, 384 |
dw 192, 96, 64, 58, 48, 32 |
dw 24, 16, 12, 6, 3, 2, 1 |
align 4 |
uart_func dd 0 ;SRV_GETVERSION |
dd 0 ;PORT_OPEN |
dd uart_close ;PORT_CLOSE |
dd uart_reset ;PORT_RESET |
dd uart_set_mode ;PORT_SETMODE |
dd 0 ;PORT_GETMODE |
dd uart_set_mcr ;PORT_SETMODEM |
dd 0 ;PORT_GETMODEM |
dd uart_read ;PORT_READ |
dd uart_write ;PORT_WRITE |
isr_action dd isr_modem |
dd transmit |
dd isr_recieve |
dd isr_line |
version dd (5 shl 16) or (UART_VERSION and 0xFFFF) |
sz_uart_srv db 'UART',0 |
align 4 |
com1 rd 1 |
com2 rd 1 |
/kernel/tags/kolibri0.7.0.0/drivers/codec.inc |
---|
0,0 → 1,226 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
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, 0x0B0B |
stdcall codec_write, dword CODEC_MASTER_VOL_REG |
mov ax, 0x08 |
stdcall codec_write, dword 0x0C |
mov ax, 0x0808 |
stdcall codec_write, dword CODEC_PCM_OUT_REG |
mov ax, 0x0808 |
stdcall codec_write, dword 0x10 |
mov ax, 0x0808 |
stdcall codec_write, dword 0x12 |
mov ax, 0x0808 |
stdcall codec_write, dword 0x16 |
stdcall codec_read, dword CODEC_EXT_AUDIO_CTRL_REG |
and eax, 0FFFFh - BIT1 ; clear DRA (BIT1) |
or eax, BIT0 ; set VRA (BIT0) |
stdcall codec_write, dword CODEC_EXT_AUDIO_CTRL_REG |
stdcall set_sample_rate, dword 48000 |
.init_error: |
xor eax, eax ; exit with error |
ret |
endp |
; param |
; eax= volume -10000 - 0 for both channels |
align 4 |
set_master_vol: |
cmp eax, 0 |
jl @F |
xor eax, eax |
jmp .set |
@@: |
cmp eax, -9450 |
jg .set |
mov eax, -9450 ;clamp into 6 bits |
.set: |
cdq |
mov ebx, -150 |
idiv ebx |
mov ah, al |
stdcall codec_write, dword CODEC_MASTER_VOL_REG |
xor eax, eax |
ret |
align 4 |
proc get_master_vol stdcall, pvol:dword |
stdcall codec_read, dword CODEC_MASTER_VOL_REG |
and eax, 0x3F |
imul eax, -150 |
mov ebx, [pvol] |
mov [ebx], eax |
xor eax, eax |
ret |
endp |
align 4 |
proc set_sample_rate stdcall, rate:dword |
mov eax, [rate] |
stdcall codec_write, dword CODEC_PCM_FRONT_DACRATE_REG |
ret |
endp |
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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/drivers/mix_mmx.inc |
---|
0,0 → 1,247 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; params |
; edi= output |
; eax= input stream 1 |
; ebx= input stream 2 |
if used mmx_mix_2 |
align 4 |
mmx_mix_2: |
movq mm0, [eax] |
movq mm1, [eax+8] |
movq mm2, [eax+16] |
movq mm3, [eax+24] |
movq mm4, [eax+32] |
movq mm5, [eax+40] |
movq mm6, [eax+48] |
movq mm7, [eax+56] |
paddsw mm0, [ebx] |
movq [edi], mm0 |
paddsw mm1,[ebx+8] |
movq [edi+8], mm1 |
paddsw mm2, [ebx+16] |
movq [edi+16], mm2 |
paddsw mm3, [ebx+24] |
movq [edi+24], mm3 |
paddsw mm4, [ebx+32] |
movq [edi+32], mm4 |
paddsw mm5, [ebx+40] |
movq [edi+40], mm5 |
paddsw mm6, [ebx+48] |
movq [edi+48], mm6 |
paddsw mm7, [ebx+56] |
movq [edi+56], mm7 |
movq mm0, [eax+64] |
movq mm1, [eax+72] |
movq mm2, [eax+80] |
movq mm3, [eax+88] |
movq mm4, [eax+96] |
movq mm5, [eax+104] |
movq mm6, [eax+112] |
movq mm7, [eax+120] |
paddsw mm0, [ebx+64] |
movq [edi+64], mm0 |
paddsw mm1, [ebx+72] |
movq [edi+72], mm1 |
paddsw mm2, [ebx+80] |
movq [edi+80], mm2 |
paddsw mm3, [ebx+88] |
movq [edi+88], mm3 |
paddsw mm4, [ebx+96] |
movq [edi+96], mm4 |
paddsw mm5, [ecx+104] |
movq [edx+104], mm5 |
paddsw mm6, [ebx+112] |
movq [edi+112], mm6 |
paddsw mm7, [ebx+120] |
movq [edi+120], mm7 |
ret |
align 4 |
mmx_mix_3: |
movq mm0, [eax] |
movq mm1, [eax+8] |
movq mm2, [eax+16] |
movq mm3, [eax+24] |
movq mm4, [eax+32] |
movq mm5, [eax+40] |
movq mm6, [eax+48] |
movq mm7, [eax+56] |
paddsw mm0, [ebx] |
paddsw mm1, [ebx+8] |
paddsw mm2, [ebx+16] |
paddsw mm3, [ebx+24] |
paddsw mm4, [ebx+32] |
paddsw mm5, [ebx+40] |
paddsw mm6, [ebx+48] |
paddsw mm7, [ebx+56] |
paddsw mm0, [ecx] |
movq [edi], mm0 |
paddsw mm1,[ecx+8] |
movq [edi+8], mm1 |
paddsw mm2, [ecx+16] |
movq [edi+16], mm2 |
paddsw mm3, [ecx+24] |
movq [edi+24], mm3 |
paddsw mm4, [ecx+32] |
movq [edi+32], mm4 |
paddsw mm5, [ecx+40] |
movq [edi+40], mm5 |
paddsw mm6, [ecx+48] |
movq [edi+48], mm6 |
paddsw mm7, [ecx+56] |
movq [edi+56], mm7 |
movq mm0, [eax+64] |
movq mm1, [eax+72] |
movq mm2, [eax+80] |
movq mm3, [eax+88] |
movq mm4, [eax+96] |
movq mm5, [eax+104] |
movq mm6, [eax+112] |
movq mm7, [eax+120] |
paddsw mm0, [ebx+64] |
paddsw mm1, [ebx+72] |
paddsw mm2, [ebx+80] |
paddsw mm3, [ebx+88] |
paddsw mm4, [ebx+96] |
paddsw mm5, [ebx+104] |
paddsw mm6, [ebx+112] |
paddsw mm7, [ebx+120] |
paddsw mm0, [ecx+64] |
movq [edi+64], mm0 |
paddsw mm1, [ecx+72] |
movq [edi+72], mm1 |
paddsw mm2, [ecx+80] |
movq [edi+80], mm2 |
paddsw mm3, [ecx+88] |
movq [edi+88], mm3 |
paddsw mm4, [ecx+96] |
movq [edi+96], mm4 |
paddsw mm5, [ecx+104] |
movq [edi+104], mm5 |
paddsw mm6, [ecx+112] |
movq [edi+112], mm6 |
paddsw mm7, [ecx+120] |
movq [edi+120], mm7 |
ret |
align 4 |
mmx_mix_4: |
movq mm0, [eax] |
movq mm2, [eax+8] |
movq mm4, [eax+16] |
movq mm6, [eax+24] |
movq mm1, [ebx] |
movq mm3, [ebx+8] |
movq mm5, [ebx+16] |
movq mm7, [ebx+24] |
paddsw mm0, [ecx] |
paddsw mm2, [ecx+8] |
paddsw mm4, [ecx+16] |
paddsw mm6, [ecx+24] |
paddsw mm1, [edx] |
paddsw mm3, [edx+8] |
paddsw mm5, [edx+16] |
paddsw mm7, [edx+24] |
paddsw mm0, mm1 |
movq [edi], mm0 |
paddsw mm2, mm3 |
movq [edi+8], mm2 |
paddsw mm4, mm5 |
movq [edi+16], mm4 |
paddsw mm5, mm6 |
movq [edi+24], mm6 |
movq mm0, [eax+32] |
movq mm2, [eax+40] |
movq mm4, [eax+48] |
movq mm6, [eax+56] |
movq mm1, [ebx+32] |
movq mm3, [ebx+40] |
movq mm5, [ebx+48] |
movq mm7, [ebx+56] |
paddsw mm0, [ecx+32] |
paddsw mm2, [ecx+40] |
paddsw mm4, [ecx+48] |
paddsw mm6, [ecx+56] |
paddsw mm1, [edx+32] |
paddsw mm3, [edx+40] |
paddsw mm5, [edx+48] |
paddsw mm7, [edx+56] |
paddsw mm0, mm1 |
movq [edi+32], mm0 |
paddsw mm2, mm2 |
movq [edi+40], mm2 |
paddsw mm4, mm5 |
movq [edi+48], mm4 |
paddsw mm6, mm7 |
movq [edi+56], mm6 |
movq mm0, [eax+64] |
movq mm2, [eax+72] |
movq mm4, [eax+80] |
movq mm6, [eax+88] |
movq mm1, [ebx+64] |
movq mm3, [ebx+72] |
movq mm5, [ebx+80] |
movq mm7, [ebx+88] |
paddsw mm0, [ecx+64] |
paddsw mm2, [ecx+72] |
paddsw mm4, [ecx+80] |
paddsw mm6, [ecx+88] |
paddsw mm1, [edx+64] |
paddsw mm3, [edx+72] |
paddsw mm5, [edx+80] |
paddsw mm7, [edx+88] |
paddsw mm0, mm1 |
movq [edi+64], mm0 |
paddsw mm2, mm3 |
movq [edi+72], mm2 |
paddsw mm4, mm5 |
movq [edi+80], mm4 |
paddsw mm6, mm5 |
movq [edi+88], mm7 |
movq mm0, [eax+96] |
movq mm2, [eax+104] |
movq mm4, [eax+112] |
movq mm6, [eax+120] |
movq mm1, [ebx+96] |
movq mm3, [ebx+104] |
movq mm5, [ebx+112] |
movq mm7, [ebx+120] |
paddsw mm0, [ecx+96] |
paddsw mm2, [ecx+104] |
paddsw mm4, [ecx+112] |
paddsw mm6, [ecx+120] |
paddsw mm1, [edx+96] |
paddsw mm3, [edx+104] |
paddsw mm5, [edx+112] |
paddsw mm7, [edx+120] |
paddsw mm0, mm1 |
movq [eax+96], mm0 |
paddsw mm2, mm3 |
movq [edi+104], mm2 |
paddsw mm4, mm5 |
movq [edi+112], mm4 |
paddsw mm6, mm7 |
movq [edi+120], mm6 |
ret |
end if |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/drivers/mix_sse2.inc |
---|
0,0 → 1,145 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used mmx128_mix_2 |
align 4 |
mmx128_mix_2: |
prefetcht1 [eax+128] |
prefetcht1 [ebx+128] |
movaps xmm0, [eax] |
movaps xmm1, [eax+16] |
movaps xmm2, [eax+32] |
movaps xmm3, [eax+48] |
movaps xmm4, [eax+64] |
movaps xmm5, [eax+80] |
movaps xmm6, [eax+96] |
movaps xmm7, [eax+112] |
paddsw xmm0, [ebx] |
movaps [edi], xmm0 |
paddsw xmm1,[ebx+16] |
movaps [edi+16], xmm1 |
paddsw xmm2, [ebx+32] |
movaps [edi+32], xmm2 |
paddsw xmm3, [ebx+48] |
movaps [edi+48], xmm3 |
paddsw xmm4, [ebx+64] |
movaps [edi+64], xmm4 |
paddsw xmm5, [ebx+80] |
movaps [edi+80], xmm5 |
paddsw xmm6, [ebx+96] |
movaps [edi+96], xmm6 |
paddsw xmm7, [ebx+112] |
movaps [edi+112], xmm7 |
ret |
align 4 |
mmx128_mix_3: |
prefetcht1 [eax+128] |
prefetcht1 [ebx+128] |
prefetcht1 [ecx+128] |
movaps xmm0, [eax] |
movaps xmm1, [eax+16] |
movaps xmm2, [eax+32] |
movaps xmm3, [eax+48] |
movaps xmm4, [eax+64] |
movaps xmm5, [eax+80] |
movaps xmm6, [eax+96] |
movaps xmm7, [eax+112] |
paddsw xmm0, [ebx] |
paddsw xmm1, [ebx+16] |
paddsw xmm2, [ebx+32] |
paddsw xmm3, [ebx+48] |
paddsw xmm4, [ebx+64] |
paddsw xmm5, [ebx+80] |
paddsw xmm6, [ebx+96] |
paddsw xmm7, [ebx+112] |
paddsw xmm0, [ecx] |
movaps [edi], xmm0 |
paddsw xmm1, [ecx+16] |
movaps [edi+16], xmm1 |
paddsw xmm2, [ecx+32] |
movaps [edi+32], xmm2 |
paddsw xmm3, [ecx+48] |
movaps [edi+48], xmm3 |
paddsw xmm4, [ecx+64] |
movaps [edi+64], xmm4 |
paddsw xmm5, [ecx+80] |
movaps [edi+80], xmm5 |
paddsw xmm6, [ecx+96] |
movaps [edi+96], xmm6 |
paddsw xmm7, [ecx+112] |
movaps [edi+112], xmm7 |
ret |
align 4 |
mmx128_mix_4: |
prefetcht1 [eax+128] |
prefetcht1 [ebx+128] |
prefetcht1 [ecx+128] |
prefetcht1 [edx+128] |
movaps xmm0, [eax] |
movaps xmm2, [eax+16] |
movaps xmm4, [eax+32] |
movaps xmm6, [eax+48] |
movaps xmm1, [ebx] |
movaps xmm3, [ebx+16] |
movaps xmm5, [ebx+32] |
movaps xmm7, [ebx+48] |
paddsw xmm0, [ecx] |
paddsw xmm2, [ecx+16] |
paddsw xmm4, [ecx+32] |
paddsw xmm6, [ecx+48] |
paddsw xmm1, [edx] |
paddsw xmm3, [edx+16] |
paddsw xmm5, [edx+32] |
paddsw xmm7, [edx+48] |
paddsw xmm0, xmm1 |
movaps [edi], xmm0 |
paddsw xmm2, xmm3 |
movaps [edi+16], xmm2 |
paddsw xmm4, xmm5 |
movaps [edi+32], xmm4 |
paddsw xmm6, xmm7 |
movaps [edi+48], xmm6 |
movaps xmm0, [eax+64] |
movaps xmm2, [eax+80] |
movaps xmm4, [eax+96] |
movaps xmm6, [eax+112] |
movaps xmm1, [ebx+64] |
movaps xmm3, [ebx+80] |
movaps xmm5, [ebx+96] |
movaps xmm7, [ebx+112] |
paddsw xmm0, [ecx+64] |
paddsw xmm2, [ecx+80] |
paddsw xmm4, [ecx+96] |
paddsw xmm6, [ecx+112] |
paddsw xmm1, [edx+64] |
paddsw xmm3, [edx+80] |
paddsw xmm5, [edx+96] |
paddsw xmm7, [edx+112] |
paddsw xmm0, xmm1 |
movaps [edi+64], xmm0 |
paddsw xmm2, xmm3 |
movaps [edi+80], xmm2 |
paddsw xmm4, xmm5 |
movaps [edi+96], xmm4 |
paddsw xmm6, xmm7 |
movaps [edi+112], xmm6 |
ret |
end if |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/drivers/mixer.asm |
---|
0,0 → 1,1102 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; (C) copyright Serge 2006 |
; email: infinity_sound@mail.ru |
align 4 |
mix_list rq 32 |
align 4 |
proc new_mix stdcall, output:dword |
locals |
main_count rd 1 |
fpu_state rb 528 ;512+16 |
endl |
mov [main_count], 32 |
call prepare_playlist |
cmp [play_count], 0 |
je .clear |
lea eax, [fpu_state+16] |
and eax, -16 ;must be 16b aligned |
call FpuSave |
call update_stream |
.mix: |
lea eax, [mix_list] |
call do_mix_list |
test eax, eax |
je .done |
; cmp eax, 1 |
; je .copy |
lea ebx, [mix_list] |
stdcall mix_all, [output], ebx, eax |
@@: |
add [output], 512 |
dec [main_count] |
jnz .mix |
.exit: |
lea eax, [fpu_state+16] |
and eax, -16 |
call FpuRestore |
ret |
.copy: |
lea eax, [mix_list] |
stdcall copy_mem, [output], [eax] |
jmp @B |
.done: |
mov ecx, [main_count] |
shl ecx, 7 ;ecx*= 512/4 |
mov edi, [output] |
xor eax, eax |
cld |
rep stosd |
jmp .exit |
.clear: |
mov edi, [output] |
mov ecx, 4096 |
xor eax, eax |
cld |
rep stosd |
ret |
endp |
align 4 |
proc update_stream |
locals |
stream_index dd ? |
ev_code dd ? ;EVENT |
ev_offs dd ? |
rd 4 |
endl |
mov [stream_index], 0 |
.l1: |
mov edx, [stream_index] |
mov esi, [play_list+edx*4] |
mov eax, [esi+STREAM.out_rp] |
cmp eax, [esi+STREAM.out_top] |
jb @f |
sub eax, 64*1024 |
@@: |
mov [esi+STREAM.out_rp], eax |
cmp word [esi+STREAM.format], PCM_2_16_48 |
je .copy |
cmp [esi+STREAM.out_count], 16384 |
ja .skip |
test [esi+STREAM.format], PCM_RING |
jnz .ring |
stdcall refill, esi |
.skip: |
inc [stream_index] |
dec [play_count] |
jnz .l1 |
ret |
.ring: |
stdcall refill_ring, esi |
jmp .skip |
.copy: |
mov ebx, esi |
mov edi, [ebx+STREAM.out_wp] |
cmp edi, [ebx+STREAM.out_top] |
jb @f |
sub edi, 64*1024 |
mov [ebx+STREAM.out_wp], edi |
@@: |
mov esi, [ebx+STREAM.in_rp] |
mov ecx, 16384/4 |
cld |
rep movsd |
mov [ebx+STREAM.out_wp], edi |
cmp esi, [ebx+STREAM.in_top] |
jb @f |
sub esi, 0x10000 |
@@: |
mov [ebx+STREAM.in_rp], esi |
test eax, eax |
jz .l_end |
mov eax, [ebx+STREAM.notify_event] |
mov ebx, [ebx+STREAM.notify_id] |
mov ecx, EVENT_WATCHED |
xor edx, edx |
call RaiseEvent ;eax, ebx, ecx, edx |
.l_end: |
inc [stream_index] |
dec [play_count] |
jnz .l1 |
ret |
endp |
align 4 |
proc refill stdcall, str:dword |
locals |
r_size rd 1 |
event rd 6 |
endl |
mov ebx, [str] |
mov edi, [ebx+STREAM.out_wp] |
cmp edi, [ebx+STREAM.out_top] |
jb @F |
sub edi, 0x10000 |
mov [ebx+STREAM.out_wp], edi |
@@: |
mov eax, [ebx+STREAM.in_count] |
test eax, eax |
jz .done |
mov ecx, [ebx+STREAM.r_size] |
cmp eax, ecx |
jle @F |
mov eax, ecx |
@@: |
mov ecx, eax |
cmp word [ebx+STREAM.format], PCM_1_16_8 |
ja @F |
shr eax, 1 ;two channles |
@@: |
test [ebx+STREAM.format], 1 ;even formats mono |
jz @F |
shr eax, 1 ;eax= samples |
@@: |
shl eax, 15 ;eax*=32768 =r_end |
mov [r_size], ecx |
mov esi, [ebx+STREAM.in_rp] |
mov edi, [ebx+STREAM.out_wp] |
stdcall [ebx+STREAM.resample], edi, esi, \ |
[ebx+STREAM.r_dt], ecx, eax |
mov ebx, [str] |
add [ebx+STREAM.out_count], eax; |
add [ebx+STREAM.out_wp], eax; |
mov eax, [ebx+STREAM.in_rp] |
mov ecx, [r_size] |
add eax, ecx |
add [ebx+STREAM.in_free], ecx |
sub [ebx+STREAM.in_count], ecx |
cmp eax, [ebx+STREAM.in_top] |
jb @f |
sub eax, [ebx+STREAM.in_size] |
@@: |
mov [ebx+STREAM.in_rp], eax |
.done: |
mov eax, [ebx+STREAM.notify_event] |
test eax, eax |
jz .exit |
mov ebx, [ebx+STREAM.notify_id] |
mov ecx, EVENT_WATCHED |
xor edx, edx |
call RaiseEvent ;eax, ebx, ecx, edx |
.exit: |
ret |
endp |
align 4 |
proc refill_ring stdcall, str:dword |
locals |
event rd 6 |
endl |
mov ebx, [str] |
mov edi, [ebx+STREAM.out_wp] |
cmp edi, [ebx+STREAM.out_top] |
jb @F |
sub edi, 0x10000 |
mov [ebx+STREAM.out_wp], edi |
@@: |
mov ecx, [ebx+STREAM.r_size] |
mov eax, ecx |
cmp word [ebx+STREAM.format], PCM_1_16_8 |
ja @F |
shr eax, 1 ;two channles |
@@: |
test [ebx+STREAM.format], 1 ;even formats mono |
jz @F |
shr eax, 1 ;eax= samples |
@@: |
shl eax, 15 ;eax*=32768 =r_end |
mov esi, [ebx+STREAM.in_rp] |
mov edi, [ebx+STREAM.out_wp] |
stdcall [ebx+STREAM.resample], edi, esi, \ |
[ebx+STREAM.r_dt], ecx, eax |
mov ebx, [str] |
add [ebx+STREAM.out_count], eax; |
add [ebx+STREAM.out_wp], eax; |
mov eax, [ebx+STREAM.in_rp] |
mov ecx, [ebx+STREAM.r_size] |
add eax, ecx |
add [ebx+STREAM.in_free], ecx |
sub [ebx+STREAM.in_count], ecx |
cmp eax, [ebx+STREAM.in_top] |
jb @f |
sub eax, [ebx+STREAM.in_size] |
@@: |
mov [ebx+STREAM.in_rp], eax |
sub eax, [ebx+STREAM.in_base] |
sub eax, 128 |
lea edx, [event] |
mov dword [edx], RT_INP_EMPTY |
mov dword [edx+4], 0 |
mov dword [edx+8], ebx |
mov dword [edx+12], eax |
mov eax, [ebx+STREAM.notify_event] |
test eax, eax |
jz .exit |
mov ebx, [ebx+STREAM.notify_id] |
xor ecx, ecx |
call RaiseEvent ;eax, ebx, ecx, edx |
.exit: |
ret |
endp |
align 4 |
proc mix_all stdcall, dest:dword, list:dword, count:dword |
mov edi, [dest] |
mov ebx, 64 |
.mix: |
mov edx, [list] |
mov ecx, [count] |
mov eax, [edx] |
movq mm0, [eax] |
movd mm1, [edx+4] |
punpckldq mm1,mm1 |
pmulhw mm0, mm1 |
psllw mm0, 1 |
.mix_loop: |
add dword [edx], 8 |
add edx, 8 |
dec ecx |
jz @F |
mov eax, [edx] |
movq mm1, [eax] |
movd mm2, [edx+4] |
punpckldq mm2,mm2 |
pmulhw mm1, mm2 |
psllw mm1, 1 |
paddsw mm0, mm1 |
jmp .mix_loop |
@@: |
movq [edi], mm0 |
add edi, 8 |
dec ebx |
jnz .mix |
ret |
endp |
align 4 |
proc resample_1 stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
; dest equ esp+8 |
; src equ esp+12 |
; r_dt equ esp+16 |
; r_size equ esp+20 |
; r_end equ esp+24 |
mov edi, [dest] |
mov edx, [src] |
sub edx, 32*2 |
mov eax, 16 |
align 4 |
.l1: |
mov ecx, eax |
mov esi, eax |
and ecx, 0x7FFF |
shr esi, 15 |
lea esi, [edx+esi*2] |
movsx ebp, word [esi] |
movsx esi, word [esi+2] |
mov ebx, 32768 |
imul esi, ecx |
sub ebx, ecx |
imul ebx, ebp |
lea ecx, [ebx+esi+16384] |
sar ecx, 15 |
cmp ecx, 32767 ; 00007fffH |
jle @f |
mov ecx, 32767 ; 00007fffH |
jmp .write |
@@: |
cmp ecx, -32768 ; ffff8000H |
jge .write |
mov ecx, -32768 ; ffff8000H |
.write: |
mov ebx, ecx |
shl ebx, 16 |
mov bx, cx |
mov [edi], ebx |
add edi, 4 |
add eax, [esp+16] |
cmp eax, [esp+24] |
jb .l1 |
mov ebp, esp |
sub edi, [dest] |
mov eax, edi |
ret |
endp |
align 4 |
proc resample_18 stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov edi, [dest] |
mov edx, [src] |
sub edx, 32 |
mov esi, 16 |
align 4 |
.l1: |
mov ecx, esi |
mov eax, esi |
and ecx, 0x7FFF |
shr eax, 15 |
lea eax, [edx+eax] |
mov bx, word [eax] |
sub bh, 0x80 |
sub bl, 0x80 |
movsx eax, bh |
shl eax,8 |
movsx ebp, bl |
shl ebp,8 |
mov ebx, 32768 |
imul eax, ecx |
sub ebx, ecx |
imul ebx, ebp |
lea ecx, [ebx+eax+16384] |
sar ecx, 15 |
cmp ecx, 32767 ; 00007fffH |
jle @f |
mov ecx, 32767 ; 00007fffH |
jmp .write |
@@: |
cmp ecx, -32768 ; ffff8000H |
jge .write |
mov ecx, -32768 ; ffff8000H |
.write: |
mov ebx, ecx |
shl ebx, 16 |
mov bx, cx |
mov [edi], ebx |
add edi, 4 |
add esi, [esp+16] |
cmp esi, [esp+24] |
jb .l1 |
mov ebp, esp |
sub edi, [dest] |
mov eax, edi |
ret |
endp |
align 4 |
proc copy_stream stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov ecx, [r_size] |
mov eax, ecx |
shr ecx, 2 |
mov esi, [src] |
mov edi, [dest] |
rep movsd |
mov eax, 16384 |
ret |
endp |
align 4 |
proc resample_2 stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov edx, [src] |
sub edx, 32*4 |
mov edi, [dest] |
mov ebx, [r_dt] |
mov eax, 16 |
emms |
align 4 |
.l1: |
mov ecx, eax |
mov esi, eax |
and ecx, 0x7FFF |
shr esi, 15 |
lea esi, [edx+esi*4] |
movq mm0, [esi] |
movq mm1, mm0 |
movd mm2, ecx |
punpcklwd mm2, mm2 |
movq mm3, qword [m7] ;0x8000 |
psubw mm3, mm2 ; ;0x8000 - iconst |
punpckldq mm3, mm2 |
pmulhw mm0, mm3 |
pmullw mm1, mm3 |
movq mm4, mm1 |
punpcklwd mm1, mm0 |
punpckhwd mm4, mm0 |
paddd mm1, mm4 |
psrad mm1, 15 |
packssdw mm1, mm1 |
movd [edi], mm1 |
add edi, 4 |
add eax, ebx |
cmp eax, [r_end] |
jb .l1 |
emms |
sub edi, [dest] |
mov eax, edi |
ret |
endp |
align 4 |
proc resample_28 stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov edx, [src] |
sub edx, 32*2 |
mov edi, [dest] |
mov ebx, [r_dt] |
mov eax, 16 |
emms |
movq mm7,[mm80] |
movq mm6,[mm_mask] |
align 4 |
.l1: |
mov ecx, eax |
mov esi, eax |
and ecx, 0x7FFF |
shr esi, 15 |
lea esi, [edx+esi*2] |
movq mm0, [esi] |
psubb mm0,mm7 |
punpcklbw mm0,mm0 |
pand mm0,mm6 |
movq mm1, mm0 |
movd mm2, ecx |
punpcklwd mm2, mm2 |
movq mm3, qword [m7] ; // 0x8000 |
psubw mm3, mm2 ; // 0x8000 - iconst |
punpckldq mm3, mm2 |
pmulhw mm0, mm3 |
pmullw mm1, mm3 |
movq mm4, mm1 |
punpcklwd mm1, mm0 |
punpckhwd mm4, mm0 |
paddd mm1, mm4 |
psrad mm1, 15 |
packssdw mm1, mm1 |
movd [edi], mm1 |
add edi, 4 |
add eax, ebx |
cmp eax, [r_end] |
jb .l1 |
emms |
sub edi, [dest] |
mov eax, edi |
ret |
endp |
proc m16_stereo stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov esi, [src] |
mov edi, [dest] |
mov ecx, [r_size] |
shr ecx,8 |
@@: |
call m16_s_mmx |
add edi, 128 |
add esi, 64 |
call m16_s_mmx |
add edi, 128 |
add esi, 64 |
call m16_s_mmx |
add edi, 128 |
add esi, 64 |
call m16_s_mmx |
add edi, 128 |
add esi, 64 |
dec ecx |
jnz @b |
mov eax, [r_size] |
add eax, eax |
ret |
endp |
align 4 |
proc s8_stereo stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov esi, [src] |
mov edi, [dest] |
mov ecx, [r_size] |
shr ecx, 7 |
movq mm7, [mm80] |
movq mm6, [mm_mask] |
@@: |
call s8_s_mmx |
add edi, 64 |
add esi, 32 |
call s8_s_mmx |
add edi, 64 |
add esi, 32 |
call s8_s_mmx |
add edi, 64 |
add esi, 32 |
call s8_s_mmx |
add edi, 64 |
add esi, 32 |
dec ecx |
jnz @b |
mov eax, [r_size] |
add eax, eax |
ret |
endp |
proc m8_stereo stdcall, dest:dword,src:dword,\ |
r_dt:dword, r_size:dword,r_end:dword |
mov esi, [src] |
mov edi, [dest] |
mov ecx, [r_size] |
shr ecx, 6 |
movq mm7, [mm80] |
movq mm6, [mm_mask] |
@@: |
call m8_s_mmx |
add edi, 64 |
add esi, 16 |
call m8_s_mmx |
add edi, 64 |
add esi, 16 |
call m8_s_mmx |
add edi, 64 |
add esi, 16 |
call m8_s_mmx |
add edi, 64 |
add esi, 16 |
dec ecx |
jnz @b |
mov eax, [r_size] |
add eax, eax |
add eax, eax |
ret |
endp |
align 4 |
proc alloc_mix_buff |
bsf eax, [mix_buff_map] |
jnz .find |
xor eax, eax |
ret |
.find: |
btr [mix_buff_map], eax |
shl eax, 9 |
add eax, [mix_buff] |
ret |
endp |
align 4 |
proc m16_s_mmx |
movq mm0, [esi] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi], mm0 |
movq [edi+8], mm1 |
movq mm0, [esi+8] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+16], mm0 |
movq [edi+24], mm1 |
movq mm0, [esi+16] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+32], mm0 |
movq [edi+40], mm1 |
movq mm0, [esi+24] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+48], mm0 |
movq [edi+56], mm1 |
movq mm0, [esi+32] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+64], mm0 |
movq [edi+72], mm1 |
movq mm0, [esi+40] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+80], mm0 |
movq [edi+88], mm1 |
movq mm0, [esi+48] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+96], mm0 |
movq [edi+104], mm1 |
movq mm0, [esi+56] |
movq mm1, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm1, mm1 |
movq [edi+112], mm0 |
movq [edi+120], mm1 |
ret |
endp |
align 4 |
proc s8_s_mmx |
movq mm0, [esi] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq [edi], mm0 |
movq [edi+8], mm1 |
movq mm0, [esi+8] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq [edi+16], mm0 |
movq [edi+24], mm1 |
movq mm0, [esi+16] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq [edi+32], mm0 |
movq [edi+40], mm1 |
movq mm0, [esi+24] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq [edi+48], mm0 |
movq [edi+56], mm1 |
ret |
endp |
align 4 |
proc m8_s_mmx |
movq mm0, [esi] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq mm2, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm2, mm2 |
movq mm3, mm1 |
punpcklwd mm1, mm1 |
punpckhwd mm3, mm3 |
movq [edi], mm0 |
movq [edi+8], mm2 |
movq [edi+16], mm1 |
movq [edi+24], mm3 |
movq mm0, [esi+8] |
psubb mm0, mm7 |
movq mm1, mm0 |
punpcklbw mm0, mm0 |
pand mm0, mm6 |
punpckhbw mm1, mm1 |
pand mm1, mm6 |
movq mm2, mm0 |
punpcklwd mm0, mm0 |
punpckhwd mm2, mm2 |
movq mm3, mm1 |
punpcklwd mm1, mm1 |
punpckhwd mm3, mm3 |
movq [edi+32], mm0 |
movq [edi+40], mm2 |
movq [edi+48], mm1 |
movq [edi+56], mm3 |
ret |
endp |
align 4 |
proc mix_2_1 stdcall, output:dword, str0:dword, str1:dword |
mov edi, [output] |
mov eax, [str0] |
mov ebx, [str1] |
mov esi, 128 |
call [mix_2_core] ;edi, eax, ebx |
add edi, esi |
add eax, esi |
add ebx, esi |
call [mix_2_core] ;edi, eax, ebx |
add edi, esi |
add eax, esi |
add ebx, esi |
call [mix_2_core] ;edi, eax, ebx |
add edi, esi |
add eax, esi |
add ebx, esi |
call [mix_2_core] ;edi, eax, ebx |
ret |
endp |
align 4 |
proc mix_3_1 stdcall, output:dword, str0:dword, str1:dword, str2:dword |
mov edi, [output] |
mov eax, [str0] |
mov ebx, [str1] |
mov ecx, [str2] |
mov esi, 128 |
call [mix_3_core] |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
call [mix_3_core] |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
call [mix_3_core] |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
call [mix_3_core] |
ret |
endp |
align 4 |
proc mix_4_1 stdcall, str0:dword, str1:dword,\ |
str2:dword, str3:dword |
local output:DWORD |
call alloc_mix_buff |
and eax, eax |
jz .err |
mov [output], eax |
mov edi, eax |
mov eax, [str0] |
mov ebx, [str1] |
mov ecx, [str2] |
mov edx, [str3] |
mov esi, 128 |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
mov eax, [output] |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc final_mix stdcall, output:dword, str0:dword, str1:dword,\ |
str2:dword, str3:dword |
mov edi, [output] |
mov eax, [str0] |
mov ebx, [str1] |
mov ecx, [str2] |
mov edx, [str3] |
mov esi, 128 |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
add edi, esi |
add eax, esi |
add ebx, esi |
add ecx, esi |
add edx, esi |
call [mix_4_core] ;edi, eax, ebx, ecx, edx |
ret |
endp |
align 4 |
proc copy_mem stdcall, output:dword, input:dword |
mov edi, [output] |
mov esi, [input] |
mov ecx, 0x80 |
.l1: |
mov eax, [esi] |
mov [edi], eax |
add esi, 4 |
add edi, 4 |
loop .l1 |
ret |
endp |
proc memcpy |
@@: |
mov eax, [esi] |
mov [edi], eax |
add esi, 4 |
add edi, 4 |
dec ecx |
jnz @B |
ret |
endp |
if 0 |
align 4 |
proc new_mix stdcall, output:dword |
locals |
mixCounter dd ? |
mixIndex dd ? |
streamIndex dd ? |
inputCount dd ? |
main_count dd ? |
blockCount dd ? |
mix_out dd ? |
endl |
call prepare_playlist |
cmp [play_count], 0 |
je .exit |
call FpuSave |
mov [main_count], 32; |
.l00: |
mov [mix_buff_map], 0x0000FFFF; |
xor eax, eax |
mov [mixCounter], eax |
mov [mixIndex],eax |
mov [streamIndex], eax; |
mov ebx, [play_count] |
mov [inputCount], ebx |
.l0: |
mov ecx, 4 |
.l1: |
mov ebx, [streamIndex] |
mov esi, [play_list+ebx*4] |
mov eax, [esi+STREAM.work_read] |
add [esi+STREAM.work_read], 512 |
mov ebx, [mixIndex] |
mov [mix_input+ebx*4], eax |
inc [mixCounter] |
inc [mixIndex] |
inc [streamIndex] |
dec [inputCount] |
jz .m2 |
dec ecx |
jnz .l1 |
cmp [mixCounter], 4 |
jnz .m2 |
stdcall mix_4_1, [mix_input],[mix_input+4],[mix_input+8],[mix_input+12] |
sub [mixIndex],4 |
mov ebx, [mixIndex] |
mov [mix_input+ebx*4], eax |
inc [mixIndex] |
mov [mixCounter], 0 |
cmp [inputCount], 0 |
jnz .l0 |
.m2: |
cmp [mixIndex], 1 |
jne @f |
stdcall copy_mem, [output], [mix_input] |
jmp .m3 |
@@: |
cmp [mixIndex], 2 |
jne @f |
stdcall mix_2_1, [output], [mix_input], [mix_input+4] |
jmp .m3 |
@@: |
cmp [mixIndex], 3 |
jne @f |
stdcall mix_3_1, [output],[mix_input],[mix_input+4],[mix_input+8] |
jmp .m3 |
@@: |
stdcall final_mix, [output],[mix_input],[mix_input+4],[mix_input+8], [mix_input+12] |
.m3: |
add [output],512 |
dec [main_count] |
jnz .l00 |
call update_stream |
emms |
call FpuRestore |
ret |
.exit: |
mov edi, [output] |
mov ecx, 0x1000 |
xor eax, eax |
cld |
rep stosd |
ret |
endp |
end if |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.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) | (parmbytes=0) |
retn |
else |
retn parmbytes |
end if } |
macro define@proc name,statement |
{ local params,flag,regs,parmbytes,localbytes,current |
if used name |
name: |
match =stdcall args, statement \{ params equ args |
flag = 11b \} |
match =stdcall, statement \{ params equ |
flag = 11b \} |
match =c args, statement \{ params equ args |
flag = 10001b \} |
match =c, statement \{ params equ |
flag = 10001b \} |
match =params, params \{ params equ statement |
flag = 0 \} |
virtual at ebp+8 |
match =uses reglist=,args, params \{ regs equ reglist |
params equ args \} |
match =regs =uses reglist, regs params \{ regs equ reglist |
params equ \} |
match =regs, regs \{ regs equ \} |
match =,args, params \{ defargs@proc args \} |
match =args@proc args, args@proc params \{ defargs@proc args \} |
parmbytes = $ - (ebp+8) |
end virtual |
name # % = parmbytes/4 |
all@vars equ |
current = 0 |
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \} |
macro locals |
\{ virtual at ebp-localbytes+current |
macro label . \\{ deflocal@proc .,:, \\} |
struc db [val] \\{ \common deflocal@proc .,db,val \\} |
struc dw [val] \\{ \common deflocal@proc .,dw,val \\} |
struc dp [val] \\{ \common deflocal@proc .,dp,val \\} |
struc dd [val] \\{ \common deflocal@proc .,dd,val \\} |
struc dt [val] \\{ \common deflocal@proc .,dt,val \\} |
struc dq [val] \\{ \common deflocal@proc .,dq,val \\} |
struc rb cnt \\{ deflocal@proc .,rb cnt, \\} |
struc rw cnt \\{ deflocal@proc .,rw cnt, \\} |
struc rp cnt \\{ deflocal@proc .,rp cnt, \\} |
struc rd cnt \\{ deflocal@proc .,rd cnt, \\} |
struc rt cnt \\{ deflocal@proc .,rt cnt, \\} |
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} |
macro endl |
\{ purge label |
restruc db,dw,dp,dd,dt,dq |
restruc rb,rw,rp,rd,rt,rq |
restruc byte,word,dword,pword,tword,qword |
current = $-(ebp-localbytes) |
end virtual \} |
macro ret operand |
\{ match any, operand \\{ retn operand \\} |
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> |
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} |
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 |
end if \} } |
macro defargs@proc [arg] |
{ common |
if ~ arg eq |
forward |
local ..arg,current@arg |
match argname:type, arg |
\{ current@arg equ argname |
label ..arg type |
argname equ ..arg |
if dqword eq type |
dd ?,?,?,? |
else if tbyte eq type |
dd ?,?,? |
else if qword eq type | pword eq type |
dd ?,? |
else |
dd ? |
end if \} |
match =current@arg,current@arg |
\{ current@arg equ arg |
arg equ ..arg |
..arg dd ? \} |
common |
args@proc equ current@arg |
forward |
restore current@arg |
common |
end if } |
macro deflocal@proc name,def,[val] |
{ common |
match vars, all@vars \{ all@vars equ all@vars, \} |
all@vars equ all@vars name |
forward |
local ..var,..tmp |
..var def val |
match =?, val \{ ..tmp equ \} |
match any =dup (=?), val \{ ..tmp equ \} |
match tmp : value, ..tmp : val |
\{ tmp: end virtual |
initlocal@proc ..var,def value |
virtual at tmp\} |
common |
match first rest, ..var, \{ name equ first \} } |
macro initlocal@proc name,def |
{ virtual at name |
def |
size@initlocal = $ - name |
end virtual |
position@initlocal = 0 |
while size@initlocal > position@initlocal |
virtual at name |
def |
if size@initlocal - position@initlocal < 2 |
current@initlocal = 1 |
load byte@initlocal byte from name+position@initlocal |
else if size@initlocal - position@initlocal < 4 |
current@initlocal = 2 |
load word@initlocal word from name+position@initlocal |
else |
current@initlocal = 4 |
load dword@initlocal dword from name+position@initlocal |
end if |
end virtual |
if current@initlocal = 1 |
mov byte [name+position@initlocal],byte@initlocal |
else if current@initlocal = 2 |
mov word [name+position@initlocal],word@initlocal |
else |
mov dword [name+position@initlocal],dword@initlocal |
end if |
position@initlocal = position@initlocal + current@initlocal |
end while } |
macro endp |
{ purge ret,locals,endl |
finish@proc |
purge finish@proc |
restore regs@proc |
match all,args@proc \{ restore all \} |
restore args@proc |
match all,all@vars \{ restore all \} } |
macro local [var] |
{ common |
locals |
forward done@local equ |
match varname[count]:vartype, var |
\{ match =BYTE, vartype \\{ varname rb count |
restore done@local \\} |
match =WORD, vartype \\{ varname rw count |
restore done@local \\} |
match =DWORD, vartype \\{ varname rd count |
restore done@local \\} |
match =PWORD, vartype \\{ varname rp count |
restore done@local \\} |
match =QWORD, vartype \\{ varname rq count |
restore done@local \\} |
match =TBYTE, vartype \\{ varname rt count |
restore done@local \\} |
match =DQWORD, vartype \\{ label varname dqword |
rq count+count |
restore done@local \\} |
match , done@local \\{ virtual |
varname vartype |
end virtual |
rb count*sizeof.\#vartype |
restore done@local \\} \} |
match :varname:vartype, done@local:var |
\{ match =BYTE, vartype \\{ varname db ? |
restore done@local \\} |
match =WORD, vartype \\{ varname dw ? |
restore done@local \\} |
match =DWORD, vartype \\{ varname dd ? |
restore done@local \\} |
match =PWORD, vartype \\{ varname dp ? |
restore done@local \\} |
match =QWORD, vartype \\{ varname dq ? |
restore done@local \\} |
match =TBYTE, vartype \\{ varname dt ? |
restore done@local \\} |
match =DQWORD, vartype \\{ label varname dqword |
dq ?,? |
restore done@local \\} |
match , done@local \\{ varname vartype |
restore done@local \\} \} |
match ,done@local |
\{ var |
restore done@local \} |
common |
endl } |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/init.inc |
---|
0,0 → 1,268 |
$Revision$ |
MEM_WB equ 6 ;write-back memory |
MEM_WC equ 1 ;write combined memory |
MEM_UC equ 0 ;uncached memory |
align 4 |
proc mem_test |
mov eax, cr0 |
and eax, not (CR0_CD+CR0_NW) |
or eax, CR0_CD ;disable caching |
mov cr0, eax |
wbinvd ;invalidate cache |
xor edi, edi |
mov ebx, 'TEST' |
@@: |
add edi, 0x100000 |
xchg ebx, dword [edi] |
cmp dword [edi], 'TEST' |
xchg ebx, dword [edi] |
je @b |
mov [MEM_AMOUNT-OS_BASE], edi |
and eax, not (CR0_CD+CR0_NW) ;enable caching |
mov cr0, eax |
mov eax, edi |
ret |
endp |
align 4 |
proc init_mem |
mov eax, [MEM_AMOUNT-OS_BASE] |
mov [pg_data.mem_amount-OS_BASE], eax |
shr eax, 12 |
mov edx, eax |
mov [pg_data.pages_count-OS_BASE], eax |
shr eax, 3 |
mov [pg_data.pagemap_size-OS_BASE], eax |
add eax, (sys_pgmap-OS_BASE)+4095 |
and eax, not 4095 |
mov [tmp_page_tabs], eax |
cmp edx, (OS_BASE/4096) |
jbe @F |
mov edx, (OS_BASE/4096) |
jmp .set |
@@: |
cmp edx, (HEAP_MIN_SIZE/4096) |
jae .set |
mov edx, (HEAP_MIN_SIZE/4096) |
.set: |
mov [pg_data.kernel_pages-OS_BASE], edx |
shr edx, 10 |
mov [pg_data.kernel_tables-OS_BASE], edx |
xor eax, eax |
mov edi, sys_pgdir-OS_BASE |
mov ecx, 4096/4 |
cld |
rep stosd |
mov edx, (sys_pgdir-OS_BASE)+ 0x800; (OS_BASE shr 20) |
bt [cpu_caps-OS_BASE], CAPS_PSE |
jnc .no_PSE |
mov ebx, cr4 |
or ebx, CR4_PSE |
mov eax, PG_LARGE+PG_SW |
; bt [cpu_caps-OS_BASE], CAPS_PGE |
; jnc @F |
; or eax, PG_GLOBAL |
; or ebx, CR4_PGE |
; |
;@@: |
mov cr4, ebx |
dec [pg_data.kernel_tables-OS_BASE] |
mov [edx], eax |
add eax, 0x00400000 |
add edx, 4 |
mov eax, 0x400000+PG_SW |
mov ecx, [tmp_page_tabs] |
sub ecx, 0x400000 |
shr ecx, 12 ;ecx/=4096 |
jmp .map_low |
.no_PSE: |
mov eax, PG_SW |
mov ecx, [tmp_page_tabs] |
shr ecx, 12 |
.map_low: |
mov edi, [tmp_page_tabs] |
@@: ; |
stosd |
add eax, 0x1000 |
dec ecx |
jnz @B |
mov ecx, [pg_data.kernel_tables-OS_BASE] |
shl ecx, 10 |
xor eax, eax |
rep stosd |
mov ecx, [pg_data.kernel_tables-OS_BASE] |
mov eax, [tmp_page_tabs] |
or eax, PG_SW |
mov edi, edx |
.map_kernel_tabs: |
stosd |
add eax, 0x1000 |
dec ecx |
jnz .map_kernel_tabs |
mov dword [sys_pgdir-OS_BASE+(page_tabs shr 20)], sys_pgdir+PG_SW-OS_BASE |
mov edi, (sys_pgdir-OS_BASE) |
lea esi, [edi+(OS_BASE shr 20)] |
movsd |
movsd |
ret |
endp |
align 4 |
proc init_page_map |
mov edi, sys_pgmap-OS_BASE |
mov ecx, [pg_data.pagemap_size-OS_BASE] |
shr ecx, 2 |
or eax, -1 |
cld |
rep stosd |
mov ecx, [tmp_page_tabs] |
mov edx, [pg_data.pages_count-OS_BASE] |
shr ecx, 12 |
add ecx, [pg_data.kernel_tables-OS_BASE] |
sub edx, ecx |
mov [pg_data.pages_free-OS_BASE], edx |
mov edi, sys_pgmap-OS_BASE |
mov ebx, ecx |
shr ecx, 5 |
xor eax, eax |
rep stosd |
not eax |
mov ecx, ebx |
and ecx, 31 |
shl eax, cl |
mov [edi], eax |
add edi, OS_BASE |
mov [page_start-OS_BASE], edi; |
mov ebx, sys_pgmap |
add ebx, [pg_data.pagemap_size-OS_BASE] |
mov [page_end-OS_BASE], ebx |
mov [pg_data.pg_mutex-OS_BASE], 0 |
ret |
endp |
align 4 |
proc test_cpu |
locals |
cpu_type dd ? |
cpu_id dd ? |
cpu_Intel dd ? |
cpu_AMD dd ? |
endl |
mov [cpu_type], 0 |
xor eax, eax |
mov [cpu_caps-OS_BASE], eax |
mov [cpu_caps+4-OS_BASE], eax |
pushfd |
pop eax |
mov ecx, eax |
xor eax, 0x40000 |
push eax |
popfd |
pushfd |
pop eax |
xor eax, ecx |
mov [cpu_type], CPU_386 |
jz .end_cpuid |
push ecx |
popfd |
mov [cpu_type], CPU_486 |
mov eax, ecx |
xor eax, 0x200000 |
push eax |
popfd |
pushfd |
pop eax |
xor eax, ecx |
je .end_cpuid |
mov [cpu_id], 1 |
xor eax, eax |
cpuid |
mov [cpu_vendor-OS_BASE], ebx |
mov [cpu_vendor+4-OS_BASE], edx |
mov [cpu_vendor+8-OS_BASE], ecx |
cmp ebx, dword [intel_str-OS_BASE] |
jne .check_AMD |
cmp edx, dword [intel_str+4-OS_BASE] |
jne .check_AMD |
cmp ecx, dword [intel_str+8-OS_BASE] |
jne .check_AMD |
mov [cpu_Intel], 1 |
cmp eax, 1 |
jl .end_cpuid |
mov eax, 1 |
cpuid |
mov [cpu_sign-OS_BASE], eax |
mov [cpu_info-OS_BASE], ebx |
mov [cpu_caps-OS_BASE], edx |
mov [cpu_caps+4-OS_BASE],ecx |
shr eax, 8 |
and eax, 0x0f |
ret |
.end_cpuid: |
mov eax, [cpu_type] |
ret |
.check_AMD: |
cmp ebx, dword [AMD_str-OS_BASE] |
jne .unknown |
cmp edx, dword [AMD_str+4-OS_BASE] |
jne .unknown |
cmp ecx, dword [AMD_str+8-OS_BASE] |
jne .unknown |
mov [cpu_AMD], 1 |
cmp eax, 1 |
jl .unknown |
mov eax, 1 |
cpuid |
mov [cpu_sign-OS_BASE], eax |
mov [cpu_info-OS_BASE], ebx |
mov [cpu_caps-OS_BASE], edx |
mov [cpu_caps+4-OS_BASE],ecx |
shr eax, 8 |
and eax, 0x0f |
ret |
.unknown: |
mov eax, 1 |
cpuid |
mov [cpu_sign-OS_BASE], eax |
mov [cpu_info-OS_BASE], ebx |
mov [cpu_caps-OS_BASE], edx |
mov [cpu_caps+4-OS_BASE],ecx |
shr eax, 8 |
and eax, 0x0f |
ret |
endp |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/memmap.inc |
---|
0,0 → 1,237 |
; |
; MEMORY MAP |
; |
; Boot: |
; |
; 0:9000 byte bits per pixel |
; 0:9001 word scanline length |
; 0:9008 word vesa video mode |
; 0:900A word X res |
; 0:900C word Y res |
; 0:9010 byte mouse port - not used |
; 0:9014 dword Vesa 1.2 pm bank switch |
; 0:9018 dword Vesa 2.0 LFB address |
; 0:901C byte 0 or 1 : enable MTRR graphics acceleration |
; 0:901D byte not used anymore (0 or 1 : enable system log display) |
; 0:901E byte 0 or 1 : enable direct lfb write, paging disabled |
; 0:901F byte DMA write : 1=yes, 2=no |
; 0:9020 8bytes pci data |
; 0:9030 byte VRR start enabled 1, 2-no |
; 0:9031 word IDEContrRegsBaseAddr |
; 0x9040 - dword - entry point of APM BIOS |
; 0x9044 - word - version (BCD) |
; 0x9046 - word - flags |
; |
; Runtime: |
; |
; 0x00000000 -> 0x7FFFFFFF application 2Gb |
; 0x80000000 -> 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 -> 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 |
; 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. |
; |
; 0x80010000 -> 6CBFF kernel, 32-bit run-time code (up to 371 Kb) |
; 0x8006CC00 -> 6DBFF stack at boot time (4Kb) |
; |
; 0x8006DC00 -> 6E5FF basic text font II |
; 0x8006E600 -> 6Efff basic text font I |
; 0x8006F000 -> 6FFFF main page directory |
; 0x80070000 -> 7FFFF data of retrieved disks and partitions (Mario79) |
; 0x80080000 -> 8FFFF additional app info, in 256 byte steps - 256 entries |
; |
; 00 11db name of app running |
; 0x10 dword pointer to fpu save area |
; 0x14 dword event count |
; 0x18 dword user fpu exceptoins handler |
; 0x1c dword user sse exceptions handler |
; 20 dword PL0 stack base |
; 24 dword user heap base |
; 28 dword user heap top |
; 2c dword window cursor handle |
; 30 dword first event in list |
; 34 dword last event in list |
; 38 dword first kernel object in list |
; 3c dword last kernel object in list |
; 40 dword thread esp |
; 44 dword io permission map page 0 |
; 48 dword io permission map page 1 |
4c dword debug state: 1= load debug registers |
; 50-7F unused |
; |
; 80 dword address of random shaped window area |
; 84 byte shape area scale |
; 88 dword free |
; 8C dword application memory size |
; 90 dword window X position save |
; 94 dword window Y position save |
; 98 dword window X size save |
; 9C dword window Y size save |
; A0 dword IPC memory start |
; A4 dword IPC memory size |
; A8 dword event bits: mouse, stack,.. |
; AC dword 0 or debugger slot |
; B0 dword free |
; B4 byte keyboard mode: 0 = keymap, 1 = scancodes |
; B8 dword physical address of directory table |
; BC dword address of debug event memory |
; C0 5 dd thread debug registers: DR0,DR1,DR2,DR3,DR7 |
; |
; 0x80090000 -> 9FFFF tmp |
; 0x800A0000 -> AFFFF screen access area |
; 0x800B0000 -> FFFFF bios rest in peace -area |
; 0x80100000 -> 27FFFF diskette image |
; 0x80280000 -> 281FFF ramdisk fat |
; 0x80282000 -> 283FFF floppy fat |
; |
; 0x80284000 -> 29FFFF free (112 Kb) |
; |
; 0x802A0000 -> 2B00ff wav device data |
; 0x802C0000 -> 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 |
; |
; 0x802C4000 -> 2CFFFF free (48Kb) |
; |
; 0x802D0000 -> 2DFFFF reserved port area |
; |
; 0000 dword no of port areas reserved |
; 0010 dword process id |
; dword start port |
; dword end port |
; dword 0 |
; |
; 0x802E0000 -> 2EFFFF irq data area |
; 0x802F0000 -> 2FFFFF low memory save |
; |
; 0x80300000 -> 400000 hd cache |
; 0x80400000 -> 41FFFF tcp memory 128 Kb |
; 0x80420000 -> 427FFF tcp memory 32 Kb |
; |
; 0x80428000 -> 42FFFF !vrr driver 32 Kb |
; 0x80430000 -> 477FFF skin data |
; 0x80438000 -> 43AFFF 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 |
; 0x8043BF80 -> 43BFFF TSS 128 bytes |
; 0x8043C000 -> 43DFFF IO map for (8192*8)=65536 ports |
; 0x8043F000 -> 57EFFF display info |
; 0x8057F000 -> 58FFFF page map max 128 Kb |
; |
; 0x80800000 -> kernel heap |
; 0x81FFFFFF heap min limit |
; 0xFDBFFFFF heap max limit |
; 0xFDC00000 -> 0xFDFFFFFF page tables 4Mb |
; 0xFE000000 -> 0xFFFFFFFF LFB 32Mb |
; 0xFE000000 -> 0xFE7FFFFF application available LFB 8Mb |
; 0xFE800000 -> 0xFFFFFFFF kernel LFB part 24 Mb |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/unpacker.inc |
---|
0,0 → 1,512 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; 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:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/data16.inc |
---|
0,0 → 1,62 |
$Revision$ |
flm db 0 |
preboot_lfb db 0 |
preboot_bootlog db 0 |
bx_from_load: dw 'r1' ; ñòðóêòóðà äëÿ õðàíåíèÿ ïàðàìåòðîâ- îòêóäà ãàøðóçèëèñü, áåðåòñÿ íèæå èç bx ; {SPraid}[13.03.2007] |
; a,b,c,d - âèí÷åñòåðû, r - ðàì äèñê |
; # äèñêà... ñèìâîë, à íå áàéò. '1', à íå 1 |
align 4 |
old_ints_h: |
dw 0x400 |
dd 0 |
dw 0 |
kernel_restart_bootblock: |
db 1 ; version |
dw 1 ; floppy image is in memory |
dd 0 ; cannot save parameters |
align 4 |
; 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) |
align 8 |
movedesc: |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 |
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
fwmovedesc: |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0 |
db 0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
db 0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/fdo.inc |
---|
0,0 → 1,430 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; |
; Formatted Debug Output (FDO) |
; Copyright (c) 2005-2006, mike.dld |
; Created: 2005-01-29, Changed: 2006-11-10 |
; |
; For questions and bug reports, mail to mike.dld@gmail.com |
; |
; Available format specifiers are: %s, %d, %u, %x (with partial width support) |
; |
; to be defined: |
; __DEBUG__ equ 1 |
; __DEBUG_LEVEL__ equ 5 |
macro debug_func name { |
if used name |
name@of@func equ name |
} |
macro debug_beginf { |
align 4 |
name@of@func: |
} |
debug_endf fix end if |
macro DEBUGS _sign,[_str] { |
common |
local tp |
tp equ 0 |
match _arg:_num,_str \{ |
DEBUGS_N _sign,_num,_arg |
tp equ 1 |
\} |
match =0 _arg,tp _str \{ |
DEBUGS_N _sign,,_arg |
\} |
} |
macro DEBUGS_N _sign,_num,[_str] { |
common |
pushf |
pushad |
local ..str,..label,is_str |
is_str = 0 |
forward |
if _str eqtype '' |
is_str = 1 |
end if |
common |
if is_str = 1 |
jmp ..label |
..str db _str,0 |
..label: |
add esp,4*8+4 |
mov edx,..str |
sub esp,4*8+4 |
else |
mov edx,_str |
end if |
if ~_num eq |
if _num eqtype eax |
if _num in <eax,ebx,ecx,edx,edi,ebp,esp> |
mov esi,_num |
else if ~_num eq esi |
movzx esi,_num |
end if |
else if _num eqtype 0 |
mov esi,_num |
else |
local tp |
tp equ 0 |
match [_arg],_num \{ |
mov esi,dword[_arg] |
tp equ 1 |
\} |
match =0 =dword[_arg],tp _num \{ |
mov esi,dword[_arg] |
tp equ 1 |
\} |
match =0 =word[_arg],tp _num \{ |
movzx esi,word[_arg] |
tp equ 1 |
\} |
match =0 =byte[_arg],tp _num \{ |
movzx esi,byte[_arg] |
tp equ 1 |
\} |
match =0,tp \{ |
'Error: specified string width is incorrect' |
\} |
end if |
else |
mov esi,0x7FFFFFFF |
end if |
call fdo_debug_outstr |
popad |
popf |
} |
macro DEBUGD _sign,_dec { |
local tp |
tp equ 0 |
match _arg:_num,_dec \{ |
DEBUGD_N _sign,_num,_arg |
tp equ 1 |
\} |
match =0 _arg,tp _dec \{ |
DEBUGD_N _sign,,_arg |
\} |
} |
macro DEBUGD_N _sign,_num,_dec { |
pushf |
pushad |
if (~_num eq) |
if (_dec eqtype eax | _dec eqtype 0) |
'Error: precision allowed only for in-memory variables' |
end if |
if (~_num in <1,2,4>) |
if _sign |
'Error: 1, 2 and 4 are only allowed for precision in %d' |
else |
'Error: 1, 2 and 4 are only allowed for precision in %u' |
end if |
end if |
end if |
if _dec eqtype eax |
if _dec in <ebx,ecx,edx,esi,edi,ebp,esp> |
mov eax,_dec |
else if ~_dec eq eax |
if _sign = 1 |
movsx eax,_dec |
else |
movzx eax,_dec |
end if |
end if |
else if _dec eqtype 0 |
mov eax,_dec |
else |
add esp,4*8+4 |
if _num eq |
mov eax,dword _dec |
else if _num = 1 |
if _sign = 1 |
movsx eax,byte _dec |
else |
movzx eax,byte _dec |
end if |
else if _num = 2 |
if _sign = 1 |
movsx eax,word _dec |
else |
movzx eax,word _dec |
end if |
else |
mov eax,dword _dec |
end if |
sub esp,4*8+4 |
end if |
mov cl,_sign |
call fdo_debug_outdec |
popad |
popf |
} |
macro DEBUGH _sign,_hex { |
local tp |
tp equ 0 |
match _arg:_num,_hex \{ |
DEBUGH_N _sign,_num,_arg |
tp equ 1 |
\} |
match =0 _arg,tp _hex \{ |
DEBUGH_N _sign,,_arg |
\} |
} |
macro DEBUGH_N _sign,_num,_hex { |
pushf |
pushad |
if (~_num eq) & (~_num in <1,2,3,4,5,6,7,8>) |
'Error: 1..8 are only allowed for precision in %x' |
end if |
if _hex eqtype eax |
if _hex in <eax,ebx,ecx,edx,esi,edi,ebp,esp> |
if ~_hex eq eax |
mov eax,_hex |
end if |
else if _hex in <ax,bx,cx,dx,si,di,bp,sp> |
if ~_hex eq ax |
movzx eax,_hex |
end if |
shl eax,16 |
if (_num eq) |
mov edx,4 |
end if |
else if _hex in <al,ah,bl,bh,cl,ch,dl,dh> |
if ~_hex eq al |
movzx eax,_hex |
end if |
shl eax,24 |
if (_num eq) |
mov edx,2 |
end if |
end if |
else if _hex eqtype 0 |
mov eax,_hex |
else |
add esp,4*8+4 |
mov eax,dword _hex |
sub esp,4*8+4 |
end if |
if ~_num eq |
mov edx,_num |
else |
if ~_hex eqtype eax |
mov edx,8 |
end if |
end if |
call fdo_debug_outhex |
popad |
popf |
} |
;----------------------------------------------------------------------------- |
debug_func fdo_debug_outchar |
debug_beginf |
pushad |
movzx ebx,al |
mov eax,1 |
mov ecx,sys_msg_board |
call ecx ; sys_msg_board |
popad |
ret |
debug_endf |
debug_func fdo_debug_outstr |
debug_beginf |
mov eax,1 |
.l1: dec esi |
js .l2 |
movzx ebx,byte[edx] |
or bl,bl |
jz .l2 |
mov ecx,sys_msg_board |
call ecx ; sys_msg_board |
inc edx |
jmp .l1 |
.l2: ret |
debug_endf |
debug_func fdo_debug_outdec |
debug_beginf |
or cl,cl |
jz @f |
or eax,eax |
jns @f |
neg eax |
push eax |
mov al,'-' |
call fdo_debug_outchar |
pop eax |
@@: push 10 |
pop ecx |
push -'0' |
.l1: xor edx,edx |
div ecx |
push edx |
test eax,eax |
jnz .l1 |
.l2: pop eax |
add al,'0' |
jz .l3 |
call fdo_debug_outchar |
jmp .l2 |
.l3: ret |
debug_endf |
debug_func fdo_debug_outhex |
__fdo_hexdigits db '0123456789ABCDEF' |
debug_beginf |
mov cl,dl |
neg cl |
add cl,8 |
shl cl,2 |
rol eax,cl |
.l1: rol eax,4 |
push eax |
and eax,0x0000000F |
mov al,[__fdo_hexdigits+eax] |
call fdo_debug_outchar |
pop eax |
dec edx |
jnz .l1 |
ret |
debug_endf |
;----------------------------------------------------------------------------- |
macro DEBUGF _level,_format,[_arg] { |
common |
if __DEBUG__ = 1 & _level >= __DEBUG_LEVEL__ |
local ..f1,f2,a1,a2,c1,c2,c3,..lbl |
_debug_str_ equ __debug_str_ # a1 |
a1 = 0 |
c2 = 0 |
c3 = 0 |
f2 = 0 |
repeat ..lbl-..f1 |
virtual at 0 |
db _format,0,0 |
load c1 word from %-1 |
end virtual |
if c1 = '%s' |
virtual at 0 |
db _format,0,0 |
store word 0 at %-1 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS 0,_debug_str_+f2-c2 |
end if |
c2 = c2 + 1 |
f2 = %+1 |
DEBUGF_HELPER S,a1,0,_arg |
else if c1 = '%x' |
virtual at 0 |
db _format,0,0 |
store word 0 at %-1 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS 0,_debug_str_+f2-c2 |
end if |
c2 = c2 + 1 |
f2 = %+1 |
DEBUGF_HELPER H,a1,0,_arg |
else if c1 = '%d' | c1 = '%u' |
local c4 |
if c1 = '%d' |
c4 = 1 |
else |
c4 = 0 |
end if |
virtual at 0 |
db _format,0,0 |
store word 0 at %-1 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS 0,_debug_str_+f2-c2 |
end if |
c2 = c2 + 1 |
f2 = %+1 |
DEBUGF_HELPER D,a1,c4,_arg |
else if c1 = '\n' |
c3 = c3 + 1 |
end if |
end repeat |
virtual at 0 |
db _format,0,0 |
load c1 from f2-c2 |
end virtual |
if (c1<>0)&(f2<>..lbl-..f1-1) |
DEBUGS 0,_debug_str_+f2-c2 |
end if |
virtual at 0 |
..f1 db _format,0 |
..lbl: |
__debug_strings equ __debug_strings,_debug_str_,<_format>,..lbl-..f1-1-c2-c3 |
end virtual |
end if |
} |
macro __include_debug_strings dummy,[_id,_fmt,_len] { |
common |
local c1,a1,a2 |
forward |
if defined _len & ~_len eq |
_id: |
a1 = 0 |
a2 = 0 |
repeat _len |
virtual at 0 |
db _fmt,0,0 |
load c1 word from %+a2-1 |
end virtual |
if (c1='%s')|(c1='%x')|(c1='%d')|(c1='%u') |
db 0 |
a2 = a2 + 1 |
else if (c1='\n') |
dw $0A0D |
a1 = a1 + 1 |
a2 = a2 + 1 |
else |
db c1 and 0x0FF |
end if |
end repeat |
db 0 |
end if |
} |
macro DEBUGF_HELPER _letter,_num,_sign,[_arg] { |
common |
local num |
num = 0 |
forward |
if num = _num |
DEBUG#_letter _sign,_arg |
end if |
num = num+1 |
common |
_num = _num+1 |
} |
macro include_debug_strings { |
if __DEBUG__ = 1 |
match dbg_str,__debug_strings \{ |
__include_debug_strings dbg_str |
\} |
end if |
} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/hid/m_ps2.inc |
---|
0,0 → 1,174 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà |
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 [BTN_DOWN],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,[MOUSE_X] ;[XCoordinate] |
jns @@M1 |
xor eax, eax |
jmp @@M2 |
@@M1: |
cmp AX,[ScreenWidth] ;ScreenLength |
jl @@M2 |
mov AX,[ScreenWidth] ;ScreenLength-1 |
@@M2: |
mov [MOUSE_X],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,[MOUSE_Y] ;[YCoordinate] |
jns @@M4 |
xor eax, eax |
jmp @@M5 |
@@M4: |
cmp AX,[ScreenHeight] ;ScreenHeigth |
jl @@M5 |
mov AX,[ScreenHeight] ;ScreenHeigth-1 |
@@M5: |
mov [MOUSE_Y],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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/hid/mousedrv.inc |
---|
0,0 → 1,452 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; check mouse |
; |
; |
; FB00 -> FB0F mouse memory 00 chunk count - FB0A-B x - FB0C-D y |
; FB10 -> FB17 mouse color mem |
; FB21 x move |
; FB22 y move |
; FB30 color temp |
; FB28 high bits temp |
; FB4A -> FB4D FB4A-B x-under - FB4C-D y-under |
; FC00 -> FCFE com1/ps2 buffer |
; FCFF com1/ps2 buffer count starting from FC00 |
uglobal |
mousecount dd 0x0 |
mousedata dd 0x0 |
endg |
iglobal |
mouse_delay dd 10 |
mouse_speed_factor: dd 3 |
mouse_timer_ticks dd 0 |
endg |
include 'm_com.inc' |
;test_mario79: |
; push esi |
; push eax |
; mov [write_error_to],process_test_m79+43 |
; movzx eax,al ;[DevErrorCode] |
; call writehex |
; mov esi,process_test_m79 |
; call sys_msg_board_str |
; pop eax |
; pop esi |
; ret |
;process_test_m79 db 'K : Process - test Mario79 error 00000000',13,10,0 |
draw_mouse_under: |
; return old picture |
cmp [set_hw_cursor], 0 |
jz @F |
pushad |
movzx eax,word [X_UNDER] |
movzx ebx,word [Y_UNDER] |
stdcall [hw_restore], eax, ebx |
popad |
ret |
@@: |
pushad |
xor ecx,ecx |
xor edx,edx |
align 4 |
mres: |
movzx eax,word [X_UNDER] |
movzx ebx,word [Y_UNDER] |
add eax,ecx |
add ebx,edx |
push ecx |
push edx |
push eax |
push ebx |
mov eax,edx |
shl eax,6 |
shl ecx,2 |
add eax,ecx |
add eax,mouseunder |
mov ecx,[eax] |
pop ebx |
pop eax |
mov edi, 1 ;force |
call [putpixel] |
pop edx |
pop ecx |
inc ecx |
cmp ecx, 16 |
jnz mres |
xor ecx, ecx |
inc edx |
cmp edx, 24 |
jnz mres |
popad |
ret |
save_draw_mouse: |
cmp [set_hw_cursor], 0 |
jz @F |
pushad |
mov [X_UNDER],ax |
mov [Y_UNDER],bx |
movzx eax,word [MOUSE_Y] |
movzx ebx,word [MOUSE_X] |
push eax |
push ebx |
mov ecx, [ScreenWidth] |
inc ecx |
mul ecx |
movzx edx, byte [display_data+ebx+eax] |
shl edx, 8 |
mov ecx, [edx+SLOT_BASE+APPDATA.cursor] |
cmp [ecx+CURSOR.magic], 'CURS' |
jne .fail |
; cmp [ecx+CURSOR.size], CURSOR_SIZE |
; jne .fail |
push ecx |
call [set_hw_cursor] |
popad |
ret |
.fail: |
mov ecx, [def_cursor] |
mov [edx+SLOT_BASE+APPDATA.cursor], ecx |
push ecx |
call [set_hw_cursor] |
popad |
ret |
@@: |
pushad |
; save & draw |
mov [X_UNDER],ax |
mov [Y_UNDER],bx |
push eax |
push ebx |
mov ecx,0 |
mov edx,0 |
align 4 |
drm: |
push eax |
push ebx |
push ecx |
push edx |
; helloworld |
push ecx |
add eax,ecx ; save picture under mouse |
add ebx,edx |
push ecx |
call getpixel |
mov [COLOR_TEMP],ecx |
pop ecx |
mov eax,edx |
shl eax,6 |
shl ecx,2 |
add eax,ecx |
add eax,mouseunder |
mov ebx,[COLOR_TEMP] |
mov [eax],ebx |
pop ecx |
mov edi,edx ; y cycle |
shl edi,4 ; *16 bytes per row |
add edi,ecx ; x cycle |
mov esi, edi |
add edi, esi |
add edi, esi ; *3 |
add edi,[MOUSE_PICTURE] ; we have our str address |
mov esi, edi |
add esi, 16*24*3 |
push ecx |
mov ecx, [COLOR_TEMP] |
call combine_colors |
mov [MOUSE_COLOR_MEM], ecx |
pop ecx |
pop edx |
pop ecx |
pop ebx |
pop eax |
add eax,ecx ; we have x coord+cycle |
add ebx,edx ; and y coord+cycle |
push ecx |
mov ecx, [MOUSE_COLOR_MEM] |
mov edi, 1 |
call [putpixel] |
pop ecx |
mov ebx,[esp+0] ; pure y coord again |
mov eax,[esp+4] ; and x |
inc ecx ; +1 cycle |
cmp ecx,16 ; if more than 16 |
jnz drm |
xor ecx, ecx |
inc edx |
cmp edx,24 |
jnz drm |
add esp,8 |
popad |
ret |
combine_colors: |
; in |
; ecx - color ( 00 RR GG BB ) |
; edi - ref to new color byte |
; esi - ref to alpha byte |
; |
; out |
; ecx - new color ( roughly (ecx*[esi]>>8)+([edi]*[esi]>>8) ) |
push eax |
push ebx |
push edx |
push ecx |
xor ecx, ecx |
; byte 2 |
mov eax, 0xff |
sub al, [esi+0] |
mov ebx, [esp] |
shr ebx, 16 |
and ebx, 0xff |
mul ebx |
shr eax, 8 |
add ecx, eax |
xor eax, eax |
xor ebx, ebx |
mov al, [edi+0] |
mov bl, [esi+0] |
mul ebx |
shr eax, 8 |
add ecx, eax |
shl ecx, 8 |
; byte 1 |
mov eax, 0xff |
sub al, [esi+1] |
mov ebx, [esp] |
shr ebx, 8 |
and ebx, 0xff |
mul ebx |
shr eax, 8 |
add ecx, eax |
xor eax, eax |
xor ebx, ebx |
mov al, [edi+1] |
mov bl, [esi+1] |
mul ebx |
shr eax, 8 |
add ecx, eax |
shl ecx, 8 |
; byte 2 |
mov eax, 0xff |
sub al, [esi+2] |
mov ebx, [esp] |
and ebx, 0xff |
mul ebx |
shr eax, 8 |
add ecx, eax |
xor eax, eax |
xor ebx, ebx |
mov al, [edi+2] |
mov bl, [esi+2] |
mul ebx |
shr eax, 8 |
add ecx, eax |
pop eax |
pop edx |
pop ebx |
pop eax |
ret |
__sys_disable_mouse: |
cmp dword [MOUSE_VISIBLE],dword 0 |
je @f |
ret |
@@: |
pushad |
cmp [CURRENT_TASK],dword 1 |
je disable_m |
mov edx,[CURRENT_TASK] |
shl edx,5 |
add edx,window_data |
movzx eax, word [MOUSE_X] |
movzx ebx, word [MOUSE_Y] |
mov ecx,[ScreenWidth] |
inc ecx |
imul ecx,ebx |
add ecx,eax |
add ecx, display_data |
mov eax, [CURRENT_TASK] |
movzx ebx, byte [ecx] |
cmp eax,ebx |
je yes_mouse_disable |
movzx ebx, byte [ecx+16] |
cmp eax,ebx |
je yes_mouse_disable |
mov ebx,[ScreenWidth] |
inc ebx |
imul ebx,10 |
add ecx,ebx |
movzx ebx, byte [ecx] |
cmp eax,ebx |
je yes_mouse_disable |
movzx ebx, byte [ecx+16] |
cmp eax,ebx |
je yes_mouse_disable |
jmp no_mouse_disable |
yes_mouse_disable: |
mov edx,[CURRENT_TASK] |
shl edx,5 |
add edx,window_data |
movzx eax, word [MOUSE_X] |
movzx ebx, word [MOUSE_Y] |
mov ecx,[edx+0] ; mouse inside the area ? |
add eax,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 [MOUSE_VISIBLE],dword 0 |
jne no_mouse_disable |
pushf |
cli |
call draw_mouse_under |
popf |
mov [MOUSE_VISIBLE],dword 1 |
no_mouse_disable: |
popad |
ret |
__sys_draw_pointer: |
cmp [mouse_pause],0 |
je @f |
ret |
@@: |
push eax |
mov eax,[timer_ticks] |
sub eax,[MouseTickCounter] |
cmp eax,1 |
ja @f |
pop eax |
ret |
@@: |
mov eax,[timer_ticks] |
mov [MouseTickCounter],eax |
pop eax |
pushad |
cmp dword [MOUSE_VISIBLE],dword 0 ; mouse visible ? |
je chms00 |
mov [MOUSE_VISIBLE], dword 0 |
movzx ebx,word [MOUSE_Y] |
movzx eax,word [MOUSE_X] |
pushfd |
cli |
call save_draw_mouse |
popfd |
nodmu2: |
popad |
ret |
chms00: |
movzx ecx,word [X_UNDER] |
movzx edx,word [Y_UNDER] |
movzx ebx,word [MOUSE_Y] |
movzx eax,word [MOUSE_X] |
cmp eax,ecx |
jne redrawmouse |
cmp ebx,edx |
jne redrawmouse |
jmp nodmp |
redrawmouse: |
pushfd |
cli |
call draw_mouse_under |
call save_draw_mouse |
popfd |
nodmp: |
popad |
ret |
proc set_mouse_data stdcall, BtnState:dword, XMoving:dword, YMoving:dword, VScroll:dword, HScroll:dword |
mov eax,[BtnState] |
mov [BTN_DOWN],eax |
mov eax,[XMoving] |
call mouse_acceleration |
add ax,[MOUSE_X] ;[XCoordinate] |
cmp ax,0 |
jge @@M1 |
mov eax,0 |
jmp @@M2 |
@@M1: |
cmp ax,[ScreenWidth] ;ScreenLength |
jl @@M2 |
mov ax,[ScreenWidth] ;ScreenLength-1 |
@@M2: |
mov [MOUSE_X],ax ;[XCoordinate] |
mov eax,[YMoving] |
neg eax |
call mouse_acceleration |
add ax,[MOUSE_Y] ;[YCoordinate] |
cmp ax,0 |
jge @@M3 |
mov ax,0 |
jmp @@M4 |
@@M3: |
cmp ax,[ScreenHeight] ;ScreenHeigth |
jl @@M4 |
mov ax,[ScreenHeight] ;ScreenHeigth-1 |
@@M4: |
mov [MOUSE_Y],ax ;[YCoordinate] |
mov eax,[VScroll] |
add [MOUSE_SCROLL_V],ax |
mov eax,[HScroll] |
add [MOUSE_SCROLL_H],ax |
mov [mouse_active],1 |
mov eax,[timer_ticks] |
mov [mouse_timer_ticks],eax |
ret |
endp |
mouse_acceleration: |
push eax |
mov eax,[timer_ticks] |
sub eax,[mouse_timer_ticks] |
cmp eax,[mouse_delay] |
pop eax |
ja @f |
;push edx |
imul eax,[mouse_speed_factor] |
;pop edx |
@@: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/hid/m_com.inc |
---|
0,0 → 1,141 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
struc COM_MOUSE_DATA { |
; Íîìåð ïðèíèìàåìîãî îò ìûøè áàéòà |
.MouseByteNumber db ? |
; Òðåõáàéòîâàÿ ñòðóêòóðà äàííûõ, ïåðåäàâàåìàÿ ìûøüþ |
.FirstByte db ? |
.SecondByte db ? |
.ThirdByte db ? |
.timer_ticks_com dd ? |
} |
virtual at 0 |
COM_MOUSE_DATA COM_MOUSE_DATA |
end virtual |
uglobal |
com1_mouse COM_MOUSE_DATA |
com2_mouse COM_MOUSE_DATA |
endg |
;*************************************** |
;* ÍÎÂÛÉ ÎÁÐÀÁÎÒ×ÈÊ ÏÐÅÐÛÂÀÍÈß ÎÒ ÌÛØÈ * |
;*************************************** |
check_mouse_data_com: |
; in: esi -> COM_MOUSE_DATA struc, dx = base port (xF8h) |
add edx, 5 ; xFDh |
in al, dx |
test al, 1 ; Äàííûå ãîòîâû? |
jz .Error |
; Ââåñòè äàííûå |
sub edx, 5 |
in al, dx |
; Ñáðîñèòü ñòàðøèé íåçíà÷àùèé áèò |
and al, 01111111b |
; Îïðåäåëèòü ïîðÿäêîâûé íîìåð ïðèíèìàåìîãî áàéòà |
cmp [esi+COM_MOUSE_DATA.MouseByteNumber], 2 |
ja .Error |
jz .ThirdByte |
jp .SecondByte |
; Ñîõðàíèòü ïåðâûé áàéò äàííûõ |
.FirstByte: |
test al, 1000000b ; Ïåðâûé áàéò ïîñûëêè? |
jz .Error |
mov [esi+COM_MOUSE_DATA.FirstByte], al |
inc [esi+COM_MOUSE_DATA.MouseByteNumber] |
jmp .EndMouseInterrupt |
; Ñîõðàíèòü âòîðîé áàéò äàííûõ |
.SecondByte: |
test al, 1000000b |
jnz .Error |
mov [esi+COM_MOUSE_DATA.SecondByte], al |
inc [esi+COM_MOUSE_DATA.MouseByteNumber] |
jmp .EndMouseInterrupt |
; Ñîõðàíèòü òðåòèé áàéò äàííûõ |
.ThirdByte: |
test al, 1000000b |
jnz .Error |
mov [esi+COM_MOUSE_DATA.ThirdByte], al |
mov [esi+COM_MOUSE_DATA.MouseByteNumber], 0 |
; (Ïàêåò äàííûõ îò ìûøè ïðèíÿò ïîëíîñòüþ). |
; Çàïèñàòü íîâîå çíà÷åíèå ñîñòîÿíèÿ êíîïîê ìûøè |
mov al, [esi+COM_MOUSE_DATA.FirstByte] |
mov ah, al |
shr al, 3 |
and al, 2 |
shr ah, 5 |
and ah, 1 |
add al, ah |
mov [BTN_DOWN], al |
mov [mouse_active], 1 |
; Ïðèáàâèòü ïåðåìåùåíèå ïî X ê êîîðäèíàòå X |
mov al, [esi+COM_MOUSE_DATA.FirstByte] |
shl al, 6 |
or al, [esi+COM_MOUSE_DATA.SecondByte] |
call mouse_acceleration_com |
; mouse acceleration |
mov ecx, [timer_ticks] |
sub ecx, [esi+COM_MOUSE_DATA.timer_ticks_com] |
cmp ecx, [mouse_delay] |
ja @f |
imul ax, [mouse_speed_factor] |
@@: |
add ax, [MOUSE_X] |
; Êóðñîð íå äîëæåí âûõîäèòü çà ëåâóþ èëè ïðàâóþ ãðàíèöó ýêðàíà |
js .x1 |
cmp ax, [ScreenWidth] |
jb .x2 |
; Óñòàíîâèòü êîîðäèíàòó X ïî ïðàâîé ãðàíèöå |
mov ax, [ScreenWidth] |
jmp .x2 |
.x1: |
; Óñòàíîâèòü êîîðäèíàòó X ïî ëåâîé ãðàíèöå |
xor eax, eax |
.x2: |
mov [MOUSE_X], ax |
; Ïðèáàâèòü ïåðåìåùåíèå ïî Y ê êîîðäèíàòå Y |
mov al, [esi+COM_MOUSE_DATA.FirstByte] |
and al, 00001100b |
shl al, 4 |
or al, [esi+COM_MOUSE_DATA.ThirdByte] |
call mouse_acceleration_com |
add ax, [MOUSE_Y] |
; Êóðñîð íå äîëæåí âûõîäèòü çà âåðõíþþ èëè íèæíþþ ãðàíèöó ýêðàíà |
js .y1 |
cmp ax, [ScreenHeight] |
jb .y2 |
; Óñòàíîâèòü êîîðäèíàòó Y ïî íèæíåé ãðàíèöå |
mov ax, [ScreenHeight] |
jmp .y2 |
.y1: |
; Óñòàíîâèòü êîîðäèíàòó Y ïî âåðõíåé ãðàíèöå |
xor eax, eax |
.y2: |
mov [MOUSE_Y], ax |
mov eax, [timer_ticks] |
mov [esi+COM_MOUSE_DATA.timer_ticks_com], eax |
jmp .EndMouseInterrupt |
.Error: |
; Ïðîèçîøåë ñáîé â ïîðÿäêå ïåðåäà÷è èíôîðìàöèè îò |
; ìûøè, îáíóëèòü ñ÷åò÷èê áàéòîâ ïàêåòà äàííûõ |
mov [esi+COM_MOUSE_DATA.MouseByteNumber],0 |
.EndMouseInterrupt: |
jmp ready_for_next_irq |
mouse_acceleration_com: |
cbw |
mov ecx, [timer_ticks] |
sub ecx, [esi+COM_MOUSE_DATA.timer_ticks_com] |
cmp ecx, [mouse_delay] |
ja @f |
imul ax, [mouse_speed_factor] |
@@: |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/hid/keyboard.inc |
---|
0,0 → 1,302 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
;; Distributed under terms of the GNU General Public License ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;// mike.dld [ |
VKEY_LSHIFT = 0000000000000001b |
VKEY_RSHIFT = 0000000000000010b |
VKEY_LCONTROL = 0000000000000100b |
VKEY_RCONTROL = 0000000000001000b |
VKEY_LALT = 0000000000010000b |
VKEY_RALT = 0000000000100000b |
VKEY_CAPSLOCK = 0000000001000000b |
VKEY_NUMLOCK = 0000000010000000b |
VKEY_SCRLOCK = 0000000100000000b |
VKEY_SHIFT = 0000000000000011b |
VKEY_CONTROL = 0000000000001100b |
VKEY_ALT = 0000000000110000b |
uglobal |
align 4 |
kb_state dd 0 |
ext_code db 0 |
keyboard_mode db 0 |
keyboard_data db 0 |
altmouseb db 0 |
ctrl_alt_del db 0 |
kb_lights db 0 |
align 4 |
hotkey_scancodes rd 256 ; we have 256 scancodes |
hotkey_list rd 256*4 ; max 256 defined hotkeys |
hotkey_buffer rd 120*2 ; buffer for 120 hotkeys |
endg |
iglobal |
hotkey_tests dd hotkey_test0 |
dd hotkey_test1 |
dd hotkey_test2 |
dd hotkey_test3 |
dd hotkey_test4 |
hotkey_tests_num = 5 |
endg |
hotkey_test0: |
test al, al |
setz al |
ret |
hotkey_test1: |
test al, al |
setnp al |
ret |
hotkey_test2: |
cmp al, 3 |
setz al |
ret |
hotkey_test3: |
cmp al, 1 |
setz al |
ret |
hotkey_test4: |
cmp al, 2 |
setz al |
ret |
hotkey_do_test: |
push eax |
mov edx, [kb_state] |
shr edx, cl |
add cl, cl |
mov eax, [eax+4] |
shr eax, cl |
and eax, 15 |
cmp al, hotkey_tests_num |
jae .fail |
xchg eax, edx |
and al, 3 |
call [hotkey_tests + edx*4] |
cmp al, 1 |
pop eax |
ret |
.fail: |
stc |
pop eax |
ret |
align 4 |
irq1: |
; save_ring3_context |
; mov ax, os_data |
; mov ds, ax |
; mov es, ax |
movzx eax,word[TASK_COUNT] ; top window process |
movzx eax,word[WIN_POS+eax*2] |
shl eax,8 |
mov al,[SLOT_BASE+eax+APPDATA.keyboard_mode] |
mov [keyboard_mode],al |
in al,0x60 |
mov [keyboard_data],al |
; ch = scancode |
; cl = ext_code |
; bh = 0 - normal key |
; bh = 1 - modifier (Shift/Ctrl/Alt) |
; bh = 2 - extended code |
mov ch,al |
cmp al,0xE0 |
je @f |
cmp al,0xE1 |
jne .normal_code |
@@: |
mov bh, 2 |
mov [ext_code], al |
jmp .writekey |
.normal_code: |
mov cl, 0 |
xchg cl, [ext_code] |
and al,0x7F |
mov bh, 1 |
@@: cmp al,0x2A |
jne @f |
cmp cl,0xE0 |
je .writekey |
mov eax,VKEY_LSHIFT |
jmp .modifier |
@@: cmp al,0x36 |
jne @f |
cmp cl,0xE0 |
je .writekey |
mov eax,VKEY_RSHIFT |
jmp .modifier |
@@: cmp al,0x38 |
jne @f |
mov eax, VKEY_LALT |
test cl, cl |
jz .modifier |
mov al, VKEY_RALT |
jmp .modifier |
@@: cmp al,0x1D |
jne @f |
mov eax, VKEY_LCONTROL |
test cl, cl |
jz .modifier |
mov al, VKEY_RCONTROL |
cmp cl, 0xE0 |
jz .modifier |
mov [ext_code], cl |
jmp .writekey |
@@: cmp al,0x3A |
jne @f |
mov bl,4 |
mov eax,VKEY_CAPSLOCK |
jmp .no_key.xor |
@@: cmp al,0x45 |
jne @f |
test cl, cl |
jnz .writekey |
mov bl,2 |
mov eax,VKEY_NUMLOCK |
jmp .no_key.xor |
@@: cmp al,0x46 |
jne @f |
mov bl,1 |
mov eax,VKEY_SCRLOCK |
jmp .no_key.xor |
@@: |
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[KEY_COUNT] |
cmp al,120 |
jae .exit.irq1 |
inc eax |
mov [KEY_COUNT],al |
mov [KEY_COUNT+eax],bl |
.exit.irq1: |
mov [check_idle_semaphore],5 |
; mov al,0x20 ; ready for next irq |
; out 0x20,al |
; restore_ring3_context |
; iret |
ret |
set_lights: |
mov al,0xED |
call kb_write |
mov al,[kb_lights] |
call kb_write |
ret |
;// mike.dld ] |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/hid/set_dtc.inc |
---|
0,0 → 1,199 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/detect/commouse.inc |
---|
0,0 → 1,133 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;************************************************** |
;* ÏÎÈÑÊ ÌÛØÈ ÏÎ ÏÎÑËÅÄÎÂÀÒÅËÜÍÛÌ ÏÎÐÒÀÌ * |
;* Ïðîöåäóðà ïîäãîòàâëèâàåò ãëîáàëüíûå ïåðåìåííûå * |
;* COMPortNum è COMPortBaseAddr äëÿ ïîäïðîãðàììû * |
;* óñòàíîâêè îáðàáîò÷èêà ïðåðûâàíèÿ * |
;************************************************** |
; Àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; Àäàïòàöèÿ è äîðàáîòêà Mario79 |
Detect_COM_Mouse: |
pusha |
call MSMouseSearch |
cmp AL,'M' |
jne @f |
mov [com1_mouse_detected],1 |
mov [irq_owner+4*4], 1 ; IRQ4 owner is System |
mov eax, [RESERVED_PORTS] |
inc eax |
mov [RESERVED_PORTS], eax |
shl eax, 4 |
mov [RESERVED_PORTS+eax+0], dword 1 |
mov [RESERVED_PORTS+eax+4], dword 0x3F8 |
mov [RESERVED_PORTS+eax+8], dword 0x3FF |
mov esi,boot_setmouse_type+22 |
call boot_log |
@@: |
sub [COMPortBaseAddr],100h |
call MSMouseSearch |
cmp AL,'M' |
jne @f |
mov [com2_mouse_detected],1 |
mov [irq_owner+3*4], 1 ; IRQ3 owner is System |
mov eax, [RESERVED_PORTS] |
inc eax |
mov [RESERVED_PORTS], eax |
shl eax, 4 |
mov [RESERVED_PORTS+eax+0], dword 1 |
mov [RESERVED_PORTS+eax+4], dword 0x2F8 |
mov [RESERVED_PORTS+eax+8], dword 0x2FF |
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 EDX,4 ;ðåãèñòð óïðàâëåíèÿ ìîäåìîì |
mov AL,0 ;ñáðîñèòü DTR, RTS è OUT2 |
out DX,AL |
; Îæèäàòü 5 "òèêîâ" (0,2 ñ) |
mov ecx, 0xFFFF |
loop $ |
; Âêëþ÷èòü ïèòàíèå ìûøè |
mov al, 1 |
out dx, al |
mov ecx, 0xFFFF |
loop $ |
; Î÷èñòèòü ðåãèñòð äàííûõ |
sub edx, 4 |
in AL,DX |
add edx, 4 |
mov AL,11b ;óñòàíîâèòü DTR è RTS |
out DX,AL |
mov ecx, 0x1FFFF |
; Öèêë îïðîñà ïîðòà |
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: |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/detect/dev_fd.inc |
---|
0,0 → 1,28 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;*************************************************** |
; ïðåäâàðèòåëüíàÿ î÷èñòêà îáëàñòè òàáëèöû |
; ïîèñê è çàíåñåíèå â òàáëèöó ïðèâîäîâ FDD |
; àâòîð Mario79 |
;*************************************************** |
xor eax,eax |
mov edi,DRIVE_DATA |
mov ecx,16384 |
cld |
rep stosd |
mov al,0x10 |
out 0x70,al |
mov cx,0xff |
wait_cmos: |
dec cx |
cmp cx,0 |
jne wait_cmos |
in al,0x71 |
mov [DRIVE_DATA],al |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/detect/dev_hdcd.inc |
---|
0,0 → 1,382 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;****************************************************** |
; ïîèñê ïðèâîäîâ HDD è CD |
; àâòîð èñõîäíîãî òåêñòà Êóëàêîâ Âëàäèìèð Ãåííàäüåâè÷. |
; àäàïòàöèÿ è äîðàáîòêà Mario79 |
;****************************************************** |
;**************************************************** |
;* ÏÎÈÑÊ HDD è CD * |
;**************************************************** |
FindHDD: |
mov [ChannelNumber],1 |
mov [DiskNumber],0 |
call FindHDD_3 |
; mov ax,[Sector512+176] |
; mov [DRIVE_DATA+6],ax |
; mov ax,[Sector512+126] |
; mov [DRIVE_DATA+8],ax |
; mov ax,[Sector512+128] |
; mov [DRIVE_DATA+8],ax |
mov [DiskNumber],1 |
call FindHDD_3 |
; mov al,[Sector512+176] |
; mov [DRIVE_DATA+7],al |
inc [ChannelNumber] |
mov [DiskNumber],0 |
call FindHDD_3 |
; mov al,[Sector512+176] |
; mov [DRIVE_DATA+8],al |
mov [DiskNumber],1 |
call FindHDD_1 |
; mov al,[Sector512+176] |
; mov [DRIVE_DATA+9],al |
jmp EndFindHDD |
FindHDD_1: |
call ReadHDD_ID |
cmp [DevErrorCode],0 |
jne FindHDD_2 |
cmp [Sector512+6],word 16 |
ja FindHDD_2 |
cmp [Sector512+12],word 255 |
ja FindHDD_2 |
inc byte [DRIVE_DATA+1] |
jmp FindHDD_2_2 |
FindHDD_2: |
call DeviceReset |
cmp [DevErrorCode],0 |
jne FindHDD_2_2 |
call ReadCD_ID |
cmp [DevErrorCode],0 |
jne FindHDD_2_2 |
inc byte [DRIVE_DATA+1] |
inc byte [DRIVE_DATA+1] |
FindHDD_2_2: |
ret |
FindHDD_3: |
call FindHDD_1 |
shl byte [DRIVE_DATA+1],2 |
ret |
; Àäðåñ ñ÷èòûâàåìîãî ñåêòîðà â ðåæèìå LBA |
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: |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/detect/ps2mouse.inc |
---|
0,0 → 1,139 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/detect/sear_par.inc |
---|
0,0 → 1,125 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;**************************************************** |
; ïîèñê ëîãè÷åñêèõ äèñêîâ íà îáíàðóæåííûõ HDD |
; è çàíåñåíèå äàííûõ â îáëàñòü òàáëèöû |
; àâòîð Mario79 |
;**************************************************** |
mov [transfer_adress],DRIVE_DATA+0xa |
search_partitions_ide0: |
test [DRIVE_DATA+1],byte 0x40 |
jz search_partitions_ide1 |
mov [hdbase],0x1f0 |
mov [hdid],0x0 |
mov [hdpos],1 |
mov [fat32part],1 |
search_partitions_ide0_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne search_partitions_ide1 |
inc byte [DRIVE_DATA+2] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
jmp search_partitions_ide0_1 |
search_partitions_ide1: |
test [DRIVE_DATA+1],byte 0x10 |
jz search_partitions_ide2 |
mov [hdbase],0x1f0 |
mov [hdid],0x10 |
mov [hdpos],2 |
mov [fat32part],1 |
search_partitions_ide1_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne search_partitions_ide2 |
inc byte [DRIVE_DATA+3] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
jmp search_partitions_ide1_1 |
search_partitions_ide2: |
test [DRIVE_DATA+1],byte 0x4 |
jz search_partitions_ide3 |
mov [hdbase],0x170 |
mov [hdid],0x0 |
mov [hdpos],3 |
mov [fat32part],1 |
search_partitions_ide2_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne search_partitions_ide3 |
inc byte [DRIVE_DATA+4] |
call partition_data_transfer |
add [transfer_adress],100 |
inc [fat32part] |
jmp search_partitions_ide2_1 |
search_partitions_ide3: |
test [DRIVE_DATA+1],byte 0x1 |
jz end_search_partitions_ide |
mov [hdbase],0x170 |
mov [hdid],0x10 |
mov [hdpos],4 |
mov [fat32part],1 |
search_partitions_ide3_1: |
call set_FAT32_variables |
cmp [problem_partition],0 |
jne end_search_partitions_ide |
inc byte [DRIVE_DATA+5] |
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 |
mov ecx,(file_system_data_size+3)/4 |
rep movsd |
ret |
uglobal |
transfer_adress dd 0 |
endg |
partition_data_transfer_1: |
; cli |
push edi |
mov edi,PARTITION_START |
mov esi,[transfer_adress] |
mov ecx,(file_system_data_size+3)/4 |
rep movsd |
pop edi |
; sti |
ret |
end_search_partitions_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 |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/detect/disks.inc |
---|
0,0 → 1,5 |
$Revision$ |
include 'dev_fd.inc' |
include 'dev_hdcd.inc' |
include 'sear_par.inc' |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/vmodeint.inc |
---|
0,0 → 1,55 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; |
; 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 [ScreenWidth] [ScreenHeight] |
popd [old_screen_height] [old_screen_width] |
or eax,-1 ; If driver is absent then eax does not change |
call (VMODE_BASE+0x100) ; Entry point of video driver |
mov [esp+36],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,[ScreenWidth] |
jnz @f |
sub ebx,[ScreenHeight] |
jz .resolution_wasnt_changed |
jmp .lp1 |
@@: sub ebx,[ScreenHeight] |
.lp1: sub [screen_workarea.right],eax |
sub [screen_workarea.bottom],ebx |
call repos_windows |
mov eax, 0 |
mov ebx, 0 |
mov ecx, [ScreenWidth] |
mov edx, [ScreenHeight] |
call calculatescreen |
.resolution_wasnt_changed: |
ret |
.no_vmode_drv_access: |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/makefile |
---|
0,0 → 1,48 |
FASM=fasm |
FLAGS=-m 65536 |
languages=en|ru|ge|et |
drivers_src=sound sis infinity ati2d vmode |
skins_src=default |
.PHONY: all kernel drivers skins clean |
all: kernel drivers skins |
kernel: check_lang |
@echo "*** building kernel with language '$(lang)' ..." |
@mkdir -p bin |
@echo "lang fix $(lang)" > lang.inc |
@echo "--- building 'bin/kernel.mnt' ..." |
@$(FASM) $(FLAGS) kernel.asm bin/kernel.mnt |
@rm -f lang.inc |
drivers: |
@echo "*** building drivers ..." |
@mkdir -p bin/drivers |
@cd drivers; for f in $(drivers_src); do \ |
echo "--- building 'bin/drivers/$${f}.obj' ..."; \ |
$(FASM) $(FLAGS) $${f}.asm ../bin/drivers/$${f}.obj; \ |
done |
@mv bin/drivers/vmode.obj bin/drivers/vmode.mdr |
skins: |
@echo "*** building skins ..." |
@mkdir -p bin/skins |
@cd skin; for f in $(skins_src); do \ |
echo "--- building 'bin/skins/$${f}.skn' ..."; \ |
$(FASM) $(FLAGS) $${f}.asm ../bin/skins/$${f}.skn; \ |
done |
check_lang: |
@case "$(lang)" in \ |
$(languages)) \ |
;; \ |
*) \ |
echo "*** error: language is incorrect or not specified"; \ |
exit 1; \ |
;; \ |
esac |
clean: |
rm -rf bin |
rm -f lang.inc |
/kernel/tags/kolibri0.7.0.0/bus/pci/pci16.inc |
---|
0,0 → 1,50 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; PCI16.INC ;; |
;; ;; |
;; 16 bit PCI driver code ;; |
;; ;; |
;; Version 0.2 December 21st, 2002 ;; |
;; ;; |
;; Author: Victor Prodan, victorprodan@yahoo.com ;; |
;; ;; |
;; See file COPYING for details ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
init_pci_16: |
pushad |
xor ax,ax |
mov es,ax |
mov byte [es:0x9020],1 ;default mechanism:1 |
mov ax,0xb101 |
int 0x1a |
or ah,ah |
jnz pci16skip |
mov [es:0x9021],cl ;last PCI bus in system |
mov [es:0x9022],bx |
mov [es:0x9024],edi |
; we have a PCI BIOS, so check which configuration mechanism(s) |
; it supports |
; AL = PCI hardware characteristics (bit0 => mechanism1, bit1 => mechanism2) |
test al,1 |
jnz pci16skip |
test al,2 |
jz pci16skip |
mov byte [es:0x9020],2 ; if (al&3)==2 => mechanism 2 |
pci16skip: |
mov ax,0x1000 |
mov es,ax |
popad |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/bus/pci/pci32.inc |
---|
0,0 → 1,363 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; ;; |
;; PCI32.INC ;; |
;; ;; |
;; 32 bit PCI driver code ;; |
;; ;; |
;; Version 0.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 [BOOT_VAR+0x9022] |
ret |
pci_fn_1: |
cmp al,1 |
jnz pci_fn_2 |
; PCI function 1: get last bus in AL |
mov al,[BOOT_VAR+0x9021] |
ret |
pci_fn_2: |
cmp al,2 |
jne pci_fn_3 |
; PCI function 2: get pci access mechanism |
mov al,[BOOT_VAR+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 [BOOT_VAR+0x9020],2 ;what mechanism will we use? |
je pci_read_reg_2 |
; mechanism 1 |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
call pci_make_config_cmd |
mov ebx,eax |
; get current state |
mov dx,0xcf8 |
in eax, dx |
push eax |
; set up addressing to config data |
mov eax,ebx |
and al,0xfc ; make address dword-aligned |
out dx,eax |
; get requested DWORD of config data |
mov dl,0xfc |
and bl,3 |
or dl,bl ; add to port address first 2 bits of register address |
or esi,esi |
jz pci_read_byte1 |
cmp esi,1 |
jz pci_read_word1 |
cmp esi,2 |
jz pci_read_dword1 |
jmp pci_fin_read1 |
pci_read_byte1: |
in al,dx |
jmp pci_fin_read1 |
pci_read_word1: |
in ax,dx |
jmp pci_fin_read1 |
pci_read_dword1: |
in eax,dx |
jmp pci_fin_read1 |
pci_fin_read1: |
; restore configuration control |
xchg eax,[esp] |
mov dx,0xcf8 |
out dx,eax |
pop eax |
pop esi |
ret |
pci_read_reg_2: |
test bh,128 ;mech#2 only supports 16 devices per bus |
jnz pci_read_reg_err |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
push eax |
;store current state of config space |
mov dx,0xcf8 |
in al,dx |
mov ah,al |
mov dl,0xfa |
in al,dx |
xchg eax,[esp] |
; out 0xcfa,bus |
mov al,ah |
out dx,al |
; out 0xcf8,0x80 |
mov dl,0xf8 |
mov al,0x80 |
out dx,al |
; compute addr |
shr bh,3 ; func is ignored in mechanism 2 |
or bh,0xc0 |
mov dx,bx |
or esi,esi |
jz pci_read_byte2 |
cmp esi,1 |
jz pci_read_word2 |
cmp esi,2 |
jz pci_read_dword2 |
jmp pci_fin_read2 |
pci_read_byte2: |
in al,dx |
jmp pci_fin_read2 |
pci_read_word2: |
in ax,dx |
jmp pci_fin_read2 |
pci_read_dword2: |
in eax,dx |
; jmp pci_fin_read2 |
pci_fin_read2: |
; restore configuration space |
xchg eax,[esp] |
mov dx,0xcfa |
out dx,al |
mov dl,0xf8 |
mov al,ah |
out dx,al |
pop eax |
pop esi |
ret |
pci_read_reg_err: |
xor eax,eax |
dec eax |
ret |
;*************************************************************************** |
; Function |
; pci_write_reg: |
; |
; Description |
; write a register from ECX/CX/CL into the PCI config space |
; IN: ah=bus,device+func=bh,register address (dword aligned)=bl, |
; value to write in ecx |
; number of bytes to write (1,2,4) coded into AL, bits 0-1 |
;*************************************************************************** |
align 4 |
pci_write_reg: |
cmp byte [BOOT_VAR+0x9020],2 ;what mechanism will we use? |
je pci_write_reg_2 |
; mechanism 1 |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
call pci_make_config_cmd |
mov ebx,eax |
; get current state into ecx |
mov dx,0xcf8 |
in eax, dx |
push eax |
; set up addressing to config data |
mov eax,ebx |
and al,0xfc ; make address dword-aligned |
out dx,eax |
; write DWORD of config data |
mov dl,0xfc |
and bl,3 |
or dl,bl |
mov eax,ecx |
or esi,esi |
jz pci_write_byte1 |
cmp esi,1 |
jz pci_write_word1 |
cmp esi,2 |
jz pci_write_dword1 |
jmp pci_fin_write1 |
pci_write_byte1: |
out dx,al |
jmp pci_fin_write1 |
pci_write_word1: |
out dx,ax |
jmp pci_fin_write1 |
pci_write_dword1: |
out dx,eax |
jmp pci_fin_write1 |
pci_fin_write1: |
; restore configuration control |
pop eax |
mov dl,0xf8 |
out dx,eax |
xor eax,eax |
pop esi |
ret |
pci_write_reg_2: |
test bh,128 ;mech#2 only supports 16 devices per bus |
jnz pci_write_reg_err |
push esi ; save register size into ESI |
mov esi,eax |
and esi,3 |
push eax |
;store current state of config space |
mov dx,0xcf8 |
in al,dx |
mov ah,al |
mov dl,0xfa |
in al,dx |
xchg eax,[esp] |
; out 0xcfa,bus |
mov al,ah |
out dx,al |
; out 0xcf8,0x80 |
mov dl,0xf8 |
mov al,0x80 |
out dx,al |
; compute addr |
shr bh,3 ; func is ignored in mechanism 2 |
or bh,0xc0 |
mov dx,bx |
; write register |
mov eax,ecx |
or esi,esi |
jz pci_write_byte2 |
cmp esi,1 |
jz pci_write_word2 |
cmp esi,2 |
jz pci_write_dword2 |
jmp pci_fin_write2 |
pci_write_byte2: |
out dx,al |
jmp pci_fin_write2 |
pci_write_word2: |
out dx,ax |
jmp pci_fin_write2 |
pci_write_dword2: |
out dx,eax |
jmp pci_fin_write2 |
pci_fin_write2: |
; restore configuration space |
pop eax |
mov dx,0xcfa |
out dx,al |
mov dl,0xf8 |
mov al,ah |
out dx,al |
xor eax,eax |
pop esi |
ret |
pci_write_reg_err: |
xor eax,eax |
dec eax |
ret |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/kglobals.inc |
---|
0,0 → 1,67 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;------------------------------------------------------------------ |
; use "iglobal" for inserting initialized global data definitions. |
;------------------------------------------------------------------ |
macro iglobal { |
IGlobals equ IGlobals, |
macro __IGlobalBlock { } |
macro iglobal_nested { |
IGlobals equ IGlobals, |
macro __IGlobalBlock \{ } |
;------------------------------------------------------------- |
; use 'uglobal' for inserting uninitialized global definitions. |
; even when you define some data values, these variables |
; will be stored as uninitialized data. |
;------------------------------------------------------------- |
macro uglobal { |
UGlobals equ UGlobals, |
macro __UGlobalBlock { } |
macro uglobal_nested { |
UGlobals equ UGlobals, |
macro __UGlobalBlock \{ } |
endg fix } ; Use endg for ending iglobal and uglobal blocks. |
endg_nested fix \} |
macro IncludeIGlobals{ |
macro IGlobals dummy,[n] \{ __IGlobalBlock |
purge __IGlobalBlock \} |
match I, IGlobals \{ I \} } |
macro IncludeUGlobals{ |
macro UGlobals dummy,[n] \{ |
\common |
\local begin, size |
begin = $ |
virtual at $ |
\forward |
__UGlobalBlock |
purge __UGlobalBlock |
\common |
size = $ - begin |
end virtual |
rb size |
\} |
match U, UGlobals \{ U \} } |
macro IncludeAllGlobals { |
IncludeIGlobals |
IncludeUGlobals |
} |
iglobal |
endg |
uglobal |
endg |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.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) | (parmbytes=0) |
retn |
else |
retn parmbytes |
end if } |
macro define@proc name,statement |
{ local params,flag,regs,parmbytes,localbytes,current |
if used name |
name: |
match =stdcall args, statement \{ params equ args |
flag = 11b \} |
match =stdcall, statement \{ params equ |
flag = 11b \} |
match =c args, statement \{ params equ args |
flag = 10001b \} |
match =c, statement \{ params equ |
flag = 10001b \} |
match =params, params \{ params equ statement |
flag = 0 \} |
virtual at ebp+8 |
match =uses reglist=,args, params \{ regs equ reglist |
params equ args \} |
match =regs =uses reglist, regs params \{ regs equ reglist |
params equ \} |
match =regs, regs \{ regs equ \} |
match =,args, params \{ defargs@proc args \} |
match =args@proc args, args@proc params \{ defargs@proc args \} |
parmbytes = $ - (ebp+8) |
end virtual |
name # % = parmbytes/4 |
all@vars equ |
current = 0 |
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \} |
macro locals |
\{ virtual at ebp-localbytes+current |
macro label . \\{ deflocal@proc .,:, \\} |
struc db [val] \\{ \common deflocal@proc .,db,val \\} |
struc dw [val] \\{ \common deflocal@proc .,dw,val \\} |
struc dp [val] \\{ \common deflocal@proc .,dp,val \\} |
struc dd [val] \\{ \common deflocal@proc .,dd,val \\} |
struc dt [val] \\{ \common deflocal@proc .,dt,val \\} |
struc dq [val] \\{ \common deflocal@proc .,dq,val \\} |
struc rb cnt \\{ deflocal@proc .,rb cnt, \\} |
struc rw cnt \\{ deflocal@proc .,rw cnt, \\} |
struc rp cnt \\{ deflocal@proc .,rp cnt, \\} |
struc rd cnt \\{ deflocal@proc .,rd cnt, \\} |
struc rt cnt \\{ deflocal@proc .,rt cnt, \\} |
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \} |
macro endl |
\{ purge label |
restruc db,dw,dp,dd,dt,dq |
restruc rb,rw,rp,rd,rt,rq |
restruc byte,word,dword,pword,tword,qword |
current = $-(ebp-localbytes) |
end virtual \} |
macro ret operand |
\{ match any, operand \\{ retn operand \\} |
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs> |
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} |
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2 |
end if \} } |
macro defargs@proc [arg] |
{ common |
if ~ arg eq |
forward |
local ..arg,current@arg |
match argname:type, arg |
\{ current@arg equ argname |
label ..arg type |
argname equ ..arg |
if dqword eq type |
dd ?,?,?,? |
else if tbyte eq type |
dd ?,?,? |
else if qword eq type | pword eq type |
dd ?,? |
else |
dd ? |
end if \} |
match =current@arg,current@arg |
\{ current@arg equ arg |
arg equ ..arg |
..arg dd ? \} |
common |
args@proc equ current@arg |
forward |
restore current@arg |
common |
end if } |
macro deflocal@proc name,def,[val] |
{ common |
match vars, all@vars \{ all@vars equ all@vars, \} |
all@vars equ all@vars name |
forward |
local ..var,..tmp |
..var def val |
match =?, val \{ ..tmp equ \} |
match any =dup (=?), val \{ ..tmp equ \} |
match tmp : value, ..tmp : val |
\{ tmp: end virtual |
initlocal@proc ..var,def value |
virtual at tmp\} |
common |
match first rest, ..var, \{ name equ first \} } |
macro initlocal@proc name,def |
{ virtual at name |
def |
size@initlocal = $ - name |
end virtual |
position@initlocal = 0 |
while size@initlocal > position@initlocal |
virtual at name |
def |
if size@initlocal - position@initlocal < 2 |
current@initlocal = 1 |
load byte@initlocal byte from name+position@initlocal |
else if size@initlocal - position@initlocal < 4 |
current@initlocal = 2 |
load word@initlocal word from name+position@initlocal |
else |
current@initlocal = 4 |
load dword@initlocal dword from name+position@initlocal |
end if |
end virtual |
if current@initlocal = 1 |
mov byte [name+position@initlocal],byte@initlocal |
else if current@initlocal = 2 |
mov word [name+position@initlocal],word@initlocal |
else |
mov dword [name+position@initlocal],dword@initlocal |
end if |
position@initlocal = position@initlocal + current@initlocal |
end while } |
macro endp |
{ purge ret,locals,endl |
finish@proc |
purge finish@proc |
restore regs@proc |
match all,args@proc \{ restore all \} |
restore args@proc |
match all,all@vars \{ restore all \} } |
macro local [var] |
{ common |
locals |
forward done@local equ |
match varname[count]:vartype, var |
\{ match =BYTE, vartype \\{ varname rb count |
restore done@local \\} |
match =WORD, vartype \\{ varname rw count |
restore done@local \\} |
match =DWORD, vartype \\{ varname rd count |
restore done@local \\} |
match =PWORD, vartype \\{ varname rp count |
restore done@local \\} |
match =QWORD, vartype \\{ varname rq count |
restore done@local \\} |
match =TBYTE, vartype \\{ varname rt count |
restore done@local \\} |
match =DQWORD, vartype \\{ label varname dqword |
rq count+count |
restore done@local \\} |
match , done@local \\{ virtual |
varname vartype |
end virtual |
rb count*sizeof.\#vartype |
restore done@local \\} \} |
match :varname:vartype, done@local:var |
\{ match =BYTE, vartype \\{ varname db ? |
restore done@local \\} |
match =WORD, vartype \\{ varname dw ? |
restore done@local \\} |
match =DWORD, vartype \\{ varname dd ? |
restore done@local \\} |
match =PWORD, vartype \\{ varname dp ? |
restore done@local \\} |
match =QWORD, vartype \\{ varname dq ? |
restore done@local \\} |
match =TBYTE, vartype \\{ varname dt ? |
restore done@local \\} |
match =DQWORD, vartype \\{ label varname dqword |
dq ?,? |
restore done@local \\} |
match , done@local \\{ varname vartype |
restore done@local \\} \} |
match ,done@local |
\{ var |
restore done@local \} |
common |
endl } |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/COPYING.TXT |
---|
0,0 → 1,347 |
GNU GENERAL PUBLIC LICENSE |
Version 2, June 1991 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
675 Mass Ave, Cambridge, MA 02139, USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
Preamble |
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
License is intended to guarantee your freedom to share and change free |
software--to make sure the software is free for all its users. This |
General Public License applies to most of the Free Software |
Foundation's software and to any other program whose authors commit to |
using it. (Some other Free Software Foundation software is covered by |
the GNU Library General Public License instead.) You can apply it to |
your programs, too. |
When we speak of free software, we are referring to freedom, not |
price. Our General Public Licenses are designed to make sure that you |
have the freedom to distribute copies of free software (and charge for |
this service if you wish), that you receive source code or can get it |
if you want it, that you can change the software or use pieces of it |
in new free programs; and that you know you can do these things. |
To protect your rights, we need to make restrictions that forbid |
anyone to deny you these rights or to ask you to surrender the rights. |
These restrictions translate to certain responsibilities for you if you |
distribute copies of the software, or if you modify it. |
For example, if you distribute copies of such a program, whether |
gratis or for a fee, you must give the recipients all the rights that |
you have. You must make sure that they, too, receive or can get the |
source code. And you must show them these terms so they know their |
rights. |
We protect your rights with two steps: (1) copyright the software, and |
(2) offer you this license which gives you legal permission to copy, |
distribute and/or modify the software. |
Also, for each author's protection and ours, we want to make certain |
that everyone understands that there is no warranty for this free |
software. If the software is modified by someone else and passed on, we |
want its recipients to know that what they have is not the original, so |
that any problems introduced by others will not reflect on the original |
authors' reputations. |
Finally, any free program is threatened constantly by software |
patents. We wish to avoid the danger that redistributors of a free |
program will individually obtain patent licenses, in effect making the |
program proprietary. To prevent this, we have made it clear that any |
patent must be licensed for everyone's free use or not licensed at all. |
The precise terms and conditions for copying, distribution and |
modification follow. |
GNU GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
0. This License applies to any program or other work which contains |
a notice placed by the copyright holder saying it may be distributed |
under the terms of this General Public License. The "Program", below, |
refers to any such program or work, and a "work based on the Program" |
means either the Program or any derivative work under copyright law: |
that is to say, a work containing the Program or a portion of it, |
either verbatim or with modifications and/or translated into another |
language. (Hereinafter, translation is included without limitation in |
the term "modification".) Each licensee is addressed as "you". |
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running the Program is not restricted, and the output from the Program |
is covered only if its contents constitute a work based on the |
Program (independent of having been made by running the Program). |
Whether that is true depends on what the Program does. |
1. You may copy and distribute verbatim copies of the Program's |
source code as you receive it, in any medium, provided that you |
conspicuously and appropriately publish on each copy an appropriate |
copyright notice and disclaimer of warranty; keep intact all the |
notices that refer to this License and to the absence of any warranty; |
and give any other recipients of the Program a copy of this License |
along with the Program. |
You may charge a fee for the physical act of transferring a copy, and |
you may at your option offer warranty protection in exchange for a fee. |
2. You may modify your copy or copies of the Program or any portion |
of it, thus forming a work based on the Program, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
a) You must cause the modified files to carry prominent notices |
stating that you changed the files and the date of any change. |
b) You must cause any work that you distribute or publish, that in |
whole or in part contains or is derived from the Program or any |
part thereof, to be licensed as a whole at no charge to all third |
parties under the terms of this License. |
c) If the modified program normally reads commands interactively |
when run, you must cause it, when started running for such |
interactive use in the most ordinary way, to print or display an |
announcement including an appropriate copyright notice and a |
notice that there is no warranty (or else, saying that you provide |
a warranty) and that users may redistribute the program under |
these conditions, and telling the user how to view a copy of this |
License. (Exception: if the Program itself is interactive but |
does not normally print such an announcement, your work based on |
the Program is not required to print an announcement.) |
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Program, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Program, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote it. |
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Program. |
In addition, mere aggregation of another work not based on the Program |
with the Program (or with a work based on the Program) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
3. You may copy and distribute the Program (or a work based on it, |
under Section 2) in object code or executable form under the terms of |
Sections 1 and 2 above provided that you also do one of the following: |
a) Accompany it with the complete corresponding machine-readable |
source code, which must be distributed under the terms of Sections |
1 and 2 above on a medium customarily used for software interchange; or, |
b) Accompany it with a written offer, valid for at least three |
years, to give any third party, for a charge no more than your |
cost of physically performing source distribution, a complete |
machine-readable copy of the corresponding source code, to be |
distributed under the terms of Sections 1 and 2 above on a medium |
customarily used for software interchange; or, |
c) Accompany it with the information you received as to the offer |
to distribute corresponding source code. (This alternative is |
allowed only for noncommercial distribution and only if you |
received the program in object code or executable form with such |
an offer, in accord with Subsection b above.) |
The source code for a work means the preferred form of the work for |
making modifications to it. For an executable work, complete source |
code means all the source code for all modules it contains, plus any |
associated interface definition files, plus the scripts used to |
control compilation and installation of the executable. However, as a |
special exception, the source code distributed need not include |
anything that is normally distributed (in either source or binary |
form) with the major components (compiler, kernel, and so on) of the |
operating system on which the executable runs, unless that component |
itself accompanies the executable. |
If distribution of executable or object code is made by offering |
access to copy from a designated place, then offering equivalent |
access to copy the source code from the same place counts as |
distribution of the source code, even though third parties are not |
compelled to copy the source along with the object code. |
4. You may not copy, modify, sublicense, or distribute the Program |
except as expressly provided under this License. Any attempt |
otherwise to copy, modify, sublicense or distribute the Program is |
void, and will automatically terminate your rights under this License. |
However, parties who have received copies, or rights, from you under |
this License will not have their licenses terminated so long as such |
parties remain in full compliance. |
5. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Program or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Program (or any work based on the |
Program), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Program or works based on it. |
6. Each time you redistribute the Program (or any work based on the |
Program), the recipient automatically receives a license from the |
original licensor to copy, distribute or modify the Program subject to |
these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties to |
this License. |
7. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Program at all. For example, if a patent |
license would not permit royalty-free redistribution of the Program by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Program. |
If any portion of this section is held invalid or unenforceable under |
any particular circumstance, the balance of the section is intended to |
apply and the section as a whole is intended to apply in other |
circumstances. |
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system, which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
8. If the distribution and/or use of the Program is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Program under this License |
may add an explicit geographical distribution limitation excluding |
those countries, so that distribution is permitted only in or among |
countries not thus excluded. In such case, this License incorporates |
the limitation as if written in the body of this License. |
9. The Free Software Foundation may publish revised and/or new versions |
of the General Public License from time to time. Such new versions will |
be similar in spirit to the present version, but may differ in detail to |
address new problems or concerns. |
Each version is given a distinguishing version number. If the Program |
specifies a version number of this License which applies to it and "any |
later version", you have the option of following the terms and conditions |
either of that version or of any later version published by the Free |
Software Foundation. If the Program does not specify a version number of |
this License, you may choose any version ever published by the Free Software |
Foundation. |
10. If you wish to incorporate parts of the Program into other free |
programs whose distribution conditions are different, write to the author |
to ask for permission. For software which is copyrighted by the Free |
Software Foundation, write to the Free Software Foundation; we sometimes |
make exceptions for this. Our decision will be guided by the two goals |
of preserving the free status of all derivatives of our free software and |
of promoting the sharing and reuse of software generally. |
NO WARRANTY |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
REPAIR OR CORRECTION. |
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGES. |
END OF TERMS AND CONDITIONS |
Appendix: How to Apply These Terms to Your New Programs |
If you develop a new program, and you want it to be of the greatest |
possible use to the public, the best way to achieve this is to make it |
free software which everyone can redistribute and change under these terms. |
To do so, attach the following notices to the program. It is safest |
to attach them to the start of each source file to most effectively |
convey the exclusion of warranty; and each file should have at least |
the "copyright" line and a pointer to where the full notice is found. |
<one line to give the program's name and a brief idea of what it does.> |
Copyright (C) 19yy <name of author> |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
Also add information on how to contact you by electronic and paper mail. |
If the program is interactive, make it output a short notice like this |
when it starts in an interactive mode: |
Gnomovision version 69, Copyright (C) 19yy name of author |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
This is free software, and you are welcome to redistribute it |
under certain conditions; type `show c' for details. |
The hypothetical commands `show w' and `show c' should show the appropriate |
parts of the General Public License. Of course, the commands you use may |
be called something other than `show w' and `show c'; they could even be |
mouse-clicks or menu items--whatever suits your program. |
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the program, if |
necessary. Here is a sample; alter the names: |
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
<signature of Ty Coon>, 1 April 1989 |
Ty Coon, President of Vice |
This General Public License does not permit incorporating your program into |
proprietary programs. If your program is a subroutine library, you may |
consider it more useful to permit linking proprietary applications with the |
library. If this is what you want to do, use the GNU Library General |
Public License instead of this License. |
/kernel/tags/kolibri0.7.0.0/skin/default.asm |
---|
0,0 → 1,38 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
include 'me_skin.inc' |
SKIN_PARAMS \ |
height = bmp_base.height,\ ; skin height |
margins = [5:1:43:1],\ ; margins [left:top:right:bottom] |
colors active = [binner=0x00081d:\ ; border inner color |
bouter=0x00081d:\ ; border outer color |
bframe=0x0054e7],\ ; border frame color |
colors inactive = [binner=0x00081d:\ ; border inner color |
bouter=0x00081d:\ ; border outer color |
bframe=0x1a8acc],\ ; border frame color |
dtp = 'myblue.dtp' ; dtp colors |
SKIN_BUTTONS \ |
close = [-21:3][16:16],\ ; buttons coordinates |
minimize = [-39:3][16:16] ; [left:top][width:height] |
SKIN_BITMAPS \ |
left active = bmp_left,\ ; skin bitmaps pointers |
left inactive = bmp_left1,\ |
oper active = bmp_oper,\ |
oper inactive = bmp_oper1,\ |
base active = bmp_base,\ |
base inactive = bmp_base1 |
BITMAP bmp_left ,'left.bmp' ; skin bitmaps |
BITMAP bmp_oper ,'oper.bmp' |
BITMAP bmp_base ,'base.bmp' |
BITMAP bmp_left1,'left_1.bmp' |
BITMAP bmp_oper1,'oper_1.bmp' |
BITMAP bmp_base1,'base_1.bmp' |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/skin/me_skin.inc |
---|
0,0 → 1,242 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;============================================================================ |
; This file should be used to generate skins of new standard |
;============================================================================ |
; skin file structure: |
;---------------------------------------------------------------------------- |
; header: |
; dd 'SKIN' |
; dd = version (1 for now) |
; dd @ params |
; dd @ buttons |
; dd @ bitmaps |
; ... |
;---------------------------------------------------------------------------- |
; NOTE: order of sections listed below is insignificant |
; since they're identified by pointer in above header |
;---------------------------------------------------------------------------- |
; ... |
; params: |
; dd = skin height |
; dw = right margin |
; dw = left margin |
; dw = bottom margin |
; dw = top margin |
; dd = inner line color |
; dd = outer line color |
; dd = frame color |
; dd = dtp file size |
; ?? = dtp file itself |
; ... |
;---------------------------------------------------------------------------- |
; ... |
; buttons: |
; dd = button type (1 = close, 2 = minimize) |
; dw = left button coord (could be negative) |
; dw = top button coord (could be negative) |
; dw = button width |
; dw = button height |
; ... etc for all buttons |
; dd = 0 (end of buttons list) |
; ... |
;---------------------------------------------------------------------------- |
; ... |
; bitmaps: |
; dw = bitmap kind (1 = left, 2 = oper, 3 = base) |
; dw = bitmap type (1 = active, 0 = inactive) |
; dd @ bitmap |
; ... etc for all bitmaps |
; dd 0 (end of bitmaps list) |
; ... |
;---------------------------------------------------------------------------- |
; ... |
; bitmap: |
; dd = bitmap width |
; dd = bitmap height |
; ?? = raw bitmap data |
; ... etc for all bitmaps |
; ... |
;============================================================================ |
dd 'SKIN',1,__params__,__buttons__,__bitmaps__ |
struc BITMAPFILEHEADER { |
.bfType dw ? ; WORD |
.bfSize dd ? ; DWORD |
.bfReserved1 dw ? ; WORD |
.bfReserved2 dw ? ; WORD |
.bfOffBits dd ? ; DWORD |
} |
struc BITMAPINFOHEADER { |
.biSize dd ? ; DWORD |
.biWidth dd ? ; LONG |
.biHeight dd ? ; LONG |
.biPlanes dw ? ; WORD |
.biBitCount dw ? ; WORD |
.biCompression dd ? ; DWORD |
.biSizeImage dd ? ; DWORD |
.biXPelsPerMeter dd ? ; LONG |
.biYPelsPerMeter dd ? ; LONG |
.biClrUsed dd ? ; DWORD |
.biClrImportant dd ? ; DWORD |
} |
struc _bmp { |
.h BITMAPFILEHEADER |
.i BITMAPINFOHEADER |
} |
virtual at 0 |
_bmp _bmp |
end virtual |
macro BITMAP _name*,_fname* |
{ |
local w,h,a,r,g,b |
virtual at 0 |
file _fname |
load w dword from _bmp.i.biWidth |
load h dword from _bmp.i.biHeight |
end virtual |
align 4 |
label _name |
.width = w |
.height = h |
dd w,h |
a=54+(w*3+(w mod 4))*(h-1) |
size = $ |
repeat h |
repeat w |
virtual at 0 |
file _fname |
load r from a+0 |
load g from a+1 |
load b from a+2 |
end virtual |
db r,g,b |
a=a+3 |
end repeat |
a=a-w*3*2-(w mod 4) |
end repeat |
} |
macro define_colors name,[col,val] |
{ |
common |
local a,b,c |
forward |
match =binner,col \{ a = val \} |
match =bouter,col \{ b = val \} |
match =bframe,col \{ c = val \} |
common |
name equ a,b,c |
} |
macro SKIN_PARAMS [a] |
{ |
common |
local _height,_margins,_colors,_colors_1,_dtp,_dtp_sz |
__params__: |
forward |
match qq == ww,a |
\{ |
match =height,qq \\{ _height = ww \\} |
match =margins,qq \\{ |
match [q1:q2:q3:q4],ww |
\\\{ |
_margins equ q3,q1,q4,q2 |
\\\} |
\\} |
match =colors =active,qq |
\\{ |
match [q10==q11:q20==q21:q30==q31],ww |
\\\{ |
define_colors _colors,q10,q11,q20,q21,q30,q31 |
\\\} |
\\} |
match =colors =inactive,qq |
\\{ |
match [q10==q11:q20==q21:q30==q31],ww |
\\\{ |
define_colors _colors_1,q10,q11,q20,q21,q30,q31 |
\\\} |
\\} |
match =dtp,qq \\{ _dtp equ ww \\} |
\} |
common |
dd _height |
dw _margins |
dd _colors,_colors_1 |
virtual at 0 |
file _dtp |
_dtp_sz = $ |
end virtual |
dd _dtp_sz |
file _dtp |
} |
macro SKIN_BUTTONS [a] |
{ |
common |
local btn |
__buttons__: |
forward |
match qq == ww,a |
\{ |
btn = 0 |
match =close,qq \\{ btn = 1 \\} |
match =minimize,qq \\{ btn = 2 \\} |
match [q1:q2][q3:q4],ww |
\\{ |
if btn <> 0 |
dd btn |
dw q1,q2,q3,q4 |
end if |
\\} |
\} |
common |
dd 0 |
} |
macro SKIN_BITMAPS [a] |
{ |
common |
local bmp |
__bitmaps__: |
forward |
match qq == ww,a |
\{ |
bmp=-1 |
match qqq =active,qq \\{ bmp = 1 \\} |
match qqq =inactive,qq \\{ bmp = 0 \\} |
match =left qqq,qq |
\\{ |
if bmp >= 0 |
dw 1,bmp |
dd ww |
end if |
\\} |
match =oper qqq,qq |
\\{ |
if bmp >= 0 |
dw 2,bmp |
dd ww |
end if |
\\} |
match =base qqq,qq |
\\{ |
if bmp >= 0 |
dw 3,bmp |
dd ww |
end if |
\\} |
\} |
common |
dd 0 |
} |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.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.7.0.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.7.0.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.7.0.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.7.0.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.7.0.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.7.0.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.7.0.0/sound/playnote.inc |
---|
0,0 → 1,139 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; PLAYNOTE.INC version 1.1 22 November 2003 ;; |
;; ;; |
;; Player Notes for Speaker PC ;; |
;; subfunction #55 from function #55 Menuet OS ;; |
;; ;; |
;; Copyright 2003 VaStaNi ;; |
;; vastani@ukr.net ;; |
;; >>>- SIMPLY - QUICKLY - SHORTLY -<<< ;; |
;; ;; |
;; Note: playnote.txt ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
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 ------------------- |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0/sound/sb16.inc |
---|
0,0 → 1,354 |
$Revision$ |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
;; Distributed under terms of the GNU General Public License ;; |
;; ;; |
;; 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,[TASK_BASE] |
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, [TASK_BASE] |
; mov eax, [eax+0x10] ; address application im memory |
; add eax, edx ; add offset Delay-Note string |
; mov [memAdrNote], eax |
mov [memAdrNote],edx |
mov eax,[TASK_BASE] |
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 |
;*************************************** |
Property changes: |
Added: svn:keywords |
+Rev |
\ No newline at end of property |
/kernel/tags/kolibri0.7.0.0 |
---|
Property changes: |
Added: svn:ignore |
+*.mnt |
+lang.inc |
+*.bat |
+out.txt |
+scin* |
Added: tsvn:logminsize |
+5 |
\ No newline at end of property |