merge trunk

git-svn-id: svn://kolibrios.org@2130 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2011-08-27 11:24:26 +00:00
parent 246c135659
commit 836a2f71bd
26 changed files with 3535 additions and 180 deletions

View File

@ -645,7 +645,7 @@ virtual at 0
end virtual
struc MEM_STATE
{ .mutex rd 1
{ .mutex MUTEX
.smallmap rd 1
.treemap rd 1
.topsize rd 1
@ -664,7 +664,7 @@ struc PG_DATA
.kernel_pages dd ?
.kernel_tables dd ?
.sys_page_dir dd ?
.pg_mutex dd ?
.mutex MUTEX
}
;struc LIB

View File

@ -5,7 +5,7 @@
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IRQ_RESERVE = 24 ; 16 or 24
IRQ_RESERVED = 24 ; 16 or 24
iglobal
IRQ_COUNT dd 24
@ -62,10 +62,11 @@ APIC_init:
shr eax, 16
inc al
movzx eax, al
cmp al, IRQ_RESERVE
cmp al, IRQ_RESERVED
jbe @f
mov al, IRQ_RESERVE
@@: mov [IRQ_COUNT], eax
mov al, IRQ_RESERVED
@@:
mov [IRQ_COUNT], eax
; Reroute IOAPIC & mask all interrupts
xor ecx, ecx
@ -106,7 +107,7 @@ APIC_init:
;init handlers table
mov ecx, IRQ_RESERVE
mov ecx, IRQ_RESERVED
mov edi, irqh_tab
@@:
mov eax, edi

View File

@ -85,6 +85,13 @@ iglobal
szStrchr db 'strchr',0
szStrrchr db 'strrchr',0
szDiskAdd db 'DiskAdd',0
szDiskDel db 'DiskDel',0
szDiskMediaChanged db 'DiskMediaChanged',0
szTimerHS db 'TimerHS',0
szCancelTimerHS db 'CancelTimerHS',0
align 16
kernel_export:

View File

@ -151,7 +151,8 @@ proc init_kernel_heap
mov [mem_block_list+63*4], ebx
mov byte [mem_block_map], 0xFC
and [heap_mutex], 0
mov ecx, heap_mutex
call mutex_init
mov [heap_blocks], 4095
mov [free_blocks], 4094
ret
@ -272,14 +273,14 @@ proc alloc_kernel_space stdcall, size:dword
push esi
push edi
mov ecx, heap_mutex
call mutex_lock
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
@ -355,10 +356,11 @@ proc alloc_kernel_space stdcall, size:dword
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
mov ecx, heap_mutex
call mutex_unlock
mov eax, [esi+block_base]
pop edi
pop esi
pop ebx
@ -378,17 +380,19 @@ proc alloc_kernel_space stdcall, size:dword
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
mov ecx, heap_mutex
call mutex_unlock
mov eax, [edi+block_base]
pop edi
pop esi
pop ebx
ret
.error:
mov ecx, heap_mutex
call mutex_unlock
xor eax, eax
mov [heap_mutex], eax
pop edi
pop esi
pop ebx
@ -400,8 +404,9 @@ proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
push ebx
push esi
push edi
mov ebx, heap_mutex
call wait_mutex ;ebx
mov ecx, heap_mutex
call mutex_lock
mov eax, [base]
mov esi, [mem_used.fd]
@ -491,9 +496,10 @@ proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
@@:
bts [mem_block_mask], eax
.m_eq:
mov ecx, heap_mutex
call mutex_unlock
xor eax, eax
mov [heap_mutex], eax
dec eax
not eax
pop edi
pop esi
pop ebx
@ -513,16 +519,18 @@ proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
@@:
bts [mem_block_mask], eax
mov [esi+block_flags],FREE_BLOCK
mov ecx, heap_mutex
call mutex_unlock
xor eax, eax
mov [heap_mutex], eax
dec eax
not eax
pop edi
pop esi
pop ebx
ret
.fail:
mov ecx, heap_mutex
call mutex_unlock
xor eax, eax
mov [heap_mutex], eax
pop edi
pop esi
pop ebx
@ -607,8 +615,8 @@ align 4
proc kernel_free stdcall, base:dword
push ebx esi
mov ebx, heap_mutex
call wait_mutex ;ebx
mov ecx, heap_mutex
call mutex_lock
mov eax, [base]
mov esi, [mem_used.fd]
@ -624,19 +632,17 @@ proc kernel_free stdcall, base:dword
cmp [esi+block_flags], USED_BLOCK
jne .fail
and [heap_mutex], 0
call mutex_unlock
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:
call mutex_unlock
xor eax, eax
mov [heap_mutex], eax
pop esi ebx
ret
endp

View File

@ -5,6 +5,10 @@
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IRQ_POOL_SIZE equ 48
macro __list_add new, prev, next
{
mov [next+LHEAD.prev], new
@ -28,13 +32,13 @@ macro list_add_tail new, head
uglobal
align 16
irqh_tab rd LHEAD.sizeof * IRQ_RESERVE / 4
irqh_tab rd LHEAD.sizeof * IRQ_RESERVED / 4
irqh_pool rd IRQH.sizeof *48 /4
irqh_pool rd IRQH.sizeof * IRQ_POOL_SIZE /4
next_irqh rd 1
irq_active_set rd 1
irq_failed rd IRQ_RESERVE
irq_failed rd IRQ_RESERVED
endg
@ -44,8 +48,6 @@ proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword
.irqh dd ?
endl
xchg bx, bx
and [.irqh], 0
push ebx
@ -54,7 +56,7 @@ proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword
test ebx, ebx
jz .err
cmp ebx, IRQ_RESERVE
cmp ebx, IRQ_RESERVED
jae .err
mov edx, [handler]
@ -72,17 +74,17 @@ proc attach_int_handler stdcall, irq:dword, handler:dword, user_data:dword
mov eax, [ecx]
mov [next_irqh], eax
mov [.irqh], ecx
mov [irq_failed+ebx*4], 0 ;clear counter
mov eax, [user_data]
mov [ecx+IRQH.handler], edx
mov [ecx+IRQH.data], eax
lea edx, [irqh_tab+ebx*8]
list_add_tail ecx, edx ;clobber eax
stdcall enable_irq, [irq]
stdcall enable_irq, ebx
.fail:
popfd
@ -116,7 +118,6 @@ proc detach_int_handler
endp
macro irq_serv_h [num] {
forward
align 4
@ -142,8 +143,6 @@ align 16
.main:
save_ring3_context
xchg bx, bx
mov ebp, [esp + 32]
mov bx, app_data ;os_data
mov ds, bx
@ -212,4 +211,15 @@ align 16
add esp, 4
iret
align 4
irqD:
push eax
push ecx
xor eax,eax
out 0xf0,al
mov eax, 13
call IRQ_EOI
pop ecx
pop eax
iret

View File

@ -20,7 +20,7 @@ $Revision$
; esi= nb
; ebx= idx
;
align 16
align 4
malloc:
push esi
@ -31,8 +31,8 @@ malloc:
and esi, -8
add esi, 8
mov ebx, mst.mutex
call wait_mutex ;ebx
mov ecx, mst.mutex
call mutex_lock
cmp esi, 256
jae .large
@ -92,9 +92,13 @@ malloc:
pop edi
pop ebp
.done:
mov esi, eax
mov ecx, mst.mutex
call mutex_unlock
mov eax, esi
pop esi
mov [mst.mutex], 0
ret
.split:
lea ebx, [edx+8] ;ebx=mem
@ -133,10 +137,10 @@ malloc:
mov [edx+12], eax ; F->bk = r;
mov [eax+8], edx ; r->fd = F;
mov [eax+12], ecx ; r->bk = B;
mov eax, ebx
pop esi
mov [mst.mutex], 0
ret
jmp .done
.small:
; if (ms.treemap != 0 && (mem = malloc_small(nb)) != 0)
@ -150,9 +154,8 @@ malloc:
call malloc_small
test eax, eax
jz .from_top
pop esi
and [mst.mutex], 0
ret
jmp .done
.large:
; if (ms.treemap != 0 && (mem = malloc_large(nb)) != 0)
@ -189,18 +192,15 @@ malloc:
mov [edx+4], eax
mov [ecx+4], esi
lea eax, [ecx+8]
pop esi
and [mst.mutex], 0
ret
jmp .done
.fail:
xor eax, eax
pop esi
and [mst.mutex], 0
ret
jmp .done
; param
; eax= mem
align 4
free:
push edi
mov edi, eax
@ -211,8 +211,8 @@ free:
test byte [edi+4], 2
je .fail
mov ebx, mst.mutex
call wait_mutex ;ebx
mov ecx, mst.mutex
call mutex_lock
; psize = p->head & (~3);
@ -289,7 +289,10 @@ free:
mov [mst.top], edi
mov [edi+4], eax
.fail2:
and [mst.mutex], 0
mov esi, eax
mov ecx, mst.mutex
call mutex_unlock
mov eax, esi
pop esi
.fail:
pop edi
@ -410,13 +413,15 @@ insert_chunk:
mov [esi+8], edx ;P->fd = F
mov [esi+12], eax ;P->bk = B
pop esi
and [mst.mutex], 0
mov ecx, mst.mutex
call mutex_unlock
ret
.large:
mov ebx, eax
call insert_large_chunk
pop esi
and [mst.mutex], 0
mov ecx, mst.mutex
call mutex_unlock
ret
@ -1025,5 +1030,8 @@ init_malloc:
cmp eax, mst.smallbins+512
jb @B
mov ecx, mst.mutex
call mutex_init
ret

View File

@ -214,30 +214,32 @@ endp
align 4
commit_pages:
push edi
test ecx, ecx
jz .fail
mov edi, ebx
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
push edi
push eax
push ecx
mov ecx, pg_data.mutex
call mutex_lock
pop ecx
pop eax
mov edx, 0x1000
mov ebx, edi
shr ebx, 12
mov edi, ebx
shr edi, 12
lea edi, [page_tabs+edi*4]
@@:
mov [page_tabs+ebx*4], eax
; push eax
invlpg [edi]
; pop eax
add edi, edx
add eax, edx
inc ebx
dec ecx
jnz @B
mov [pg_data.pg_mutex],ecx
.fail:
stosd
invlpg [ebx]
add eax, 0x1000
add ebx, 0x1000
loop @B
pop edi
mov ecx, pg_data.mutex
call mutex_unlock
.fail:
ret
@ -248,15 +250,21 @@ commit_pages:
align 4
release_pages:
pushad
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
push ebp
push esi
push edi
push ebx
mov esi, eax
mov edi, eax
shr esi, 10
add esi, page_tabs
shr esi, 12
lea esi, [page_tabs+esi*4]
push ecx
mov ecx, pg_data.mutex
call mutex_lock
pop ecx
mov ebp, [pg_data.pages_free]
mov ebx, [page_start]
@ -264,9 +272,7 @@ release_pages:
@@:
xor eax, eax
xchg eax, [esi]
push eax
invlpg [edi]
pop eax
test eax, 1
jz .next
@ -285,11 +291,16 @@ release_pages:
.next:
add edi, 0x1000
add esi, 4
dec ecx
jnz @B
loop @B
mov [pg_data.pages_free], ebp
and [pg_data.pg_mutex],0
popad
mov ecx, pg_data.mutex
call mutex_unlock
pop ebx
pop edi
pop esi
pop ebp
ret
; param
@ -423,8 +434,8 @@ endp
align 4
proc new_mem_resize stdcall, new_size:dword
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
mov ecx, pg_data.mutex
call mutex_lock
mov edi, [new_size]
add edi,4095
@ -464,8 +475,10 @@ proc new_mem_resize stdcall, new_size:dword
mov ebx, [new_size]
call update_mem_size
mov ecx, pg_data.mutex
call mutex_unlock
xor eax, eax
dec [pg_data.pg_mutex]
ret
.expand:
@ -539,9 +552,11 @@ proc new_mem_resize stdcall, new_size:dword
pop edi
pop esi
.exit:
mov ecx, pg_data.mutex
call mutex_unlock
xor eax, eax
inc eax
dec [pg_data.pg_mutex]
ret
endp

View File

@ -54,7 +54,7 @@ iglobal
dd irq_serv.irq_22
dd irq_serv.irq_23
times 32 - IRQ_RESERVE dd unknown_interrupt
times 32 - IRQ_RESERVED dd unknown_interrupt
;int_0x40 gate trap (for directly copied)
dw i40 and 0xFFFF, os_code, 11101111b shl 8, i40 shr 16
@ -245,18 +245,6 @@ show_error_parameters:
restore reg_edi
align 4
irqD:
push eax
xor eax,eax
out 0xf0,al
mov al,0x20
out 0xa0,al
out 0x20,al
pop eax
iret
align 4
set_application_table_status:
push eax
@ -682,8 +670,13 @@ term9:
restore .slot
iglobal
if lang eq ru
boot_sched_1 db '‘®§¤ ­¨¥ GDT TSS 㪠§ â¥«ï',0
boot_sched_2 db '‘®§¤ ­¨¥ IDT â ¡«¨æë',0
else
boot_sched_1 db 'Building gdt tss pointer',0
boot_sched_2 db 'Building IDT table',0
end if
endg

View File

@ -360,8 +360,8 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
app_tabs dd ?
endl
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
mov ecx, pg_data.mutex
call mutex_lock
xor eax, eax
mov [dir_addr], eax
@ -387,11 +387,11 @@ proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
shr ecx, 12
mov [img_pages], ecx
if GREEDY_KERNEL
if GREEDY_KERNEL
lea eax, [ecx+ebx+2] ;only image size
else
else
lea eax, [eax+ebx+2] ;all requested memory
end if
end if
cmp eax, [pg_data.pages_free]
ja .fail
@ -480,11 +480,13 @@ end if
.done:
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
dec [pg_data.pg_mutex]
mov ecx, pg_data.mutex
call mutex_unlock
mov eax, [dir_addr]
ret
.fail:
dec [pg_data.pg_mutex]
mov ecx, pg_data.mutex
call mutex_unlock
cmp [dir_addr], 0
je @f
stdcall destroy_app_space, [dir_addr], 0
@ -554,10 +556,10 @@ proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
jg .ret
;if there isn't threads then clear memory.
mov esi, [dlls_list]
call destroy_all_hdlls
call destroy_all_hdlls ;ecx=APPDATA
mov ebx, pg_data.pg_mutex
call wait_mutex ;ebx
mov ecx, pg_data.mutex
call mutex_lock
mov eax, [pg_dir]
and eax, not 0xFFF
@ -583,7 +585,8 @@ proc destroy_app_space stdcall, pg_dir:dword, dlls_list:dword
.exit:
stdcall map_page,[tmp_task_ptab],0,PG_UNMAP
stdcall map_page,[tmp_task_pdir],0,PG_UNMAP
dec [pg_data.pg_mutex]
mov ecx, pg_data.mutex
call mutex_unlock
.ret:
ret
endp
@ -956,24 +959,6 @@ proc new_sys_threads
ret
endp
; param
; ebx=mutex
align 4
wait_mutex:
;;Maxis use atomic bts for mutex 4.4.2009
push eax
push ebx
.do_wait:
bts dword [ebx],0
jnc .locked
call change_task
jmp .do_wait
.locked:
pop ebx
pop eax
ret
align 4
tls_app_entry:

View File

@ -0,0 +1,205 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2011. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 2122 $
; Simple implementation of timers. All timers are organized in a double-linked
; list, and the OS loop after every timer tick processes the list.
; This structure describes a timer for the kernel.
struct TIMER
.Next dd ?
.Prev dd ?
; These fields organize a double-linked list of all timers.
.TimerFunc dd ?
; Function to be called when the timer is activated.
.UserData dd ?
; The value that is passed as is to .TimerFunc.
.Time dd ?
; Time at which the timer should be activated.
.Interval dd ?
; Interval between activations of the timer, in 0.01s.
ends
iglobal
align 4
; The head of timer list.
timer_list:
dd timer_list
dd timer_list
endg
uglobal
; These two variables are used to synchronize access to the global list.
; Logically, they form an recursive mutex. Physically, the first variable holds
; the slot number of the current owner or 0, the second variable holds the
; recursion count.
; The mutex should be recursive to allow a timer function to add/delete other
; timers or itself.
timer_list_owner dd 0
timer_list_numlocks dd 0
; A timer function can delete any timer, including itself and the next timer in
; the chain. To handle such situation correctly, we keep the next timer in a
; global variable, so the removing operation can update it.
timer_next dd 0
endg
; This internal function acquires the lock for the global list.
lock_timer_list:
mov edx, [CURRENT_TASK]
@@:
xor eax, eax
lock cmpxchg [timer_list_owner], edx
jz @f
cmp eax, edx
jz @f
call change_task
jmp @b
@@:
inc [timer_list_numlocks]
ret
; This internal function releases the lock for the global list.
unlock_timer_list:
dec [timer_list_numlocks]
jnz .nothing
mov [timer_list_owner], 0
.nothing:
ret
; This function adds a timer.
; If deltaStart is nonzero, the timer is activated after deltaStart hundredths
; of seconds starting from the current time. If interval is nonzero, the timer
; is activated every deltaWork hundredths of seconds starting from the first
; activation. The activated timer calls timerFunc as stdcall function with one
; argument userData.
; Return value is NULL if something has failed or some value which is opaque
; for the caller. Later this value can be used for cancel_timer_hs.
proc timer_hs stdcall uses ebx, deltaStart:dword, interval:dword, \
timerFunc:dword, userData:dword
; 1. Allocate memory for the TIMER structure.
; 1a. Call the allocator.
push sizeof.TIMER
pop eax
call malloc
; 1b. If allocation failed, return (go to 5) with eax = 0.
test eax, eax
jz .nothing
; 2. Setup the TIMER structure.
xchg ebx, eax
; 2a. Copy values from the arguments.
mov ecx, [interval]
mov [ebx+TIMER.Interval], ecx
mov ecx, [timerFunc]
mov [ebx+TIMER.TimerFunc], ecx
mov ecx, [userData]
mov [ebx+TIMER.UserData], ecx
; 2b. Get time of the next activation.
mov ecx, [deltaStart]
test ecx, ecx
jnz @f
mov ecx, [interval]
@@:
add ecx, [timer_ticks]
mov [ebx+TIMER.Time], ecx
; 3. Insert the TIMER structure to the global list.
; 3a. Acquire the lock.
call lock_timer_list
; 3b. Insert an item at ebx to the tail of the timer_list.
mov eax, timer_list
mov ecx, [eax+TIMER.Prev]
mov [ebx+TIMER.Next], eax
mov [ebx+TIMER.Prev], ecx
mov [eax+TIMER.Prev], ebx
mov [ecx+TIMER.Next], ebx
; 3c. Release the lock.
call unlock_timer_list
; 4. Return with eax = pointer to TIMER structure.
xchg ebx, eax
.nothing:
; 5. Returning.
ret
endp
; This function removes a timer.
; The only argument is [esp+4] = the value which was returned from timer_hs.
cancel_timer_hs:
push ebx ; save used register to be stdcall
; 1. Remove the TIMER structure from the global list.
; 1a. Acquire the lock.
call lock_timer_list
mov ebx, [esp+4+4]
; 1b. Delete an item at ebx from the double-linked list.
mov eax, [ebx+TIMER.Next]
mov ecx, [ebx+TIMER.Prev]
mov [eax+TIMER.Prev], ecx
mov [ecx+TIMER.Next], eax
; 1c. If we are removing the next timer in currently processing chain,
; the next timer for this timer becomes new next timer.
cmp ebx, [timer_next]
jnz @f
mov [timer_next], eax
@@:
; 1d. Release the lock.
call unlock_timer_list
; 2. Free the TIMER structure.
xchg eax, ebx
call free
; 3. Return.
pop ebx ; restore used register to be stdcall
ret 4 ; purge one dword argument to be stdcall
; This function is regularly called from osloop. It processes the global list
; and activates the corresponding timers.
check_timers:
; 1. Acquire the lock.
call lock_timer_list
; 2. Loop over all registered timers, checking time.
; 2a. Get the first item.
mov eax, [timer_list+TIMER.Next]
mov [timer_next], eax
.loop:
; 2b. Check for end of list.
cmp eax, timer_list
jz .done
; 2c. Get and store the next timer.
mov edx, [eax+TIMER.Next]
mov [timer_next], edx
; 2d. Check time for timer activation.
; We can't just compare [timer_ticks] and [TIMER.Time], since overflows are
; possible: if the current time is 0FFFFFFFFh ticks and timer should be
; activated in 3 ticks, the simple comparison will produce incorrect result.
; So we calculate the difference [timer_ticks] - [TIMER.Time]; if it is
; non-negative, the time is over; if it is negative, then either the time is
; not over or we have not processed this timer for 2^31 ticks, what is very
; unlikely.
mov edx, [timer_ticks]
sub edx, [eax+TIMER.Time]
js .next
; The timer should be activated now.
; 2e. Store the timer data in the stack. This is required since 2f can delete
; the timer, invalidating the content.
push [eax+TIMER.UserData] ; parameter for TimerFunc
push [eax+TIMER.TimerFunc] ; to be restored in 2g
; 2f. Calculate time of next activation or delete the timer if it is one-shot.
mov ecx, [eax+TIMER.Interval]
add [eax+TIMER.Time], ecx
test ecx, ecx
jnz .nodelete
stdcall cancel_timer_hs, eax
.nodelete:
; 2g. Activate timer, using data from the stack.
pop eax
call eax
.next:
; 2h. Advance to the next timer and continue the loop.
mov eax, [timer_next]
jmp .loop
.done:
; 3. Release the lock.
call unlock_timer_list
; 4. Return.
ret

View File

@ -328,7 +328,7 @@ v86_start:
cmp edx, -1
jz .noirqhook
uglobal
v86_irqhooks rd IRQ_RESERVE * 2
v86_irqhooks rd IRQ_RESERVED * 2
endg
cmp [v86_irqhooks+edx*8], 0
jz @f
@ -839,6 +839,7 @@ end if
; mov byte [BOOT_VAR + 48Eh], 0FFh
; ret
align 4
v86_irq:
; push irq/pushad/jmp v86_irq
; eax = irq

View File

@ -47,8 +47,34 @@ keymap_alt:
db 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
boot_memdetect db 'Determining amount of memory',0
if lang eq ru
boot_fonts db '˜à¨äâë § £à㦥­ë',0
boot_memdetect db 'Š®«¨ç¥á⢮ ®¯¥à â¨¢­®© ¯ ¬ïâ¨',' ',' Œ¡',0
boot_tss db '“áâ ­®¢ª  TSSs',0
boot_cpuid db '—⥭¨¥ CPUIDs',0
boot_devices db '<27>®¨áª ãáâனáâ¢',0
boot_timer db '“áâ ­®¢ª  â ©¬¥à ',0
boot_irqs db '<27>¥à¥®¯à¥¤¥«¥­¨¥ IRQ',0
boot_setmouse db '“áâ ­®¢ª  ¬ëè¨',0
boot_windefs db '“áâ ­®¢ª  ­ áâ஥ª ®ª®­ ¯® 㬮«ç ­¨î',0
boot_bgr db '“áâ ­®¢ª  ä®­ ',0
boot_resirqports db '<27>¥§¥à¢¨à®¢ ­¨¥ IRQ ¨ ¯®à⮢',0
boot_setrports db '“áâ ­®¢ª   ¤à¥á®¢ IRQ',0
boot_setostask db '‘®§¤ ­¨¥ ¯à®æ¥áá  ï¤à ',0
boot_allirqs db 'Žâªàë⨥ ¢á¥å IRQ',0
boot_tsc db '—⥭¨¥ TSC',0
boot_cpufreq db '— áâ®â  ¯à®æ¥áá®à  ',' ',' Œƒæ',0
boot_pal_ega db '“áâ ­®¢ª  EGA/CGA 320x200 ¯ «¨âàë',0
boot_pal_vga db '“áâ ­®¢ª  VGA 640x480 ¯ «¨âàë',0
boot_failed db '‡ £à㧪  ¯¥à¢®£® ¯à¨«®¦¥­¨ï ­¥ 㤠« áì',0
boot_mtrr db '“áâ ­®¢ª  MTRR',0
if preboot_blogesc
boot_tasking db '‚ᥠ£®â®¢® ¤«ï § ¯ã᪠, ­ ¦¬¨âॠESC ¤«ï áâ àâ ',0
end if
else
boot_fonts db 'Fonts loaded',0
boot_memdetect db 'Determining amount of memory',0
boot_tss db 'Setting TSSs',0
boot_cpuid db 'Reading CPUIDs',0
boot_devices db 'Detecting devices',0
@ -63,12 +89,14 @@ keymap_alt:
boot_pal_ega db 'Setting EGA/CGA 320x200 palette',0
boot_pal_vga db 'Setting VGA 640x480 palette',0
boot_failed db 'Failed to start first app',0
boot_APIC_found db 'APIC enabled', 0
boot_APIC_nfound db 'APIC not found', 0
boot_mtrr db 'Setting MTRR',0
if preboot_blogesc
boot_tasking db 'All set - press ESC to start',0
end if
end if
boot_APIC_found db 'APIC enabled', 0
boot_APIC_nfound db 'APIC not found', 0
;new_process_loading db 'K : New Process - loading',13,10,0
;new_process_running db 'K : New Process - done',13,10,0
@ -280,7 +308,7 @@ mem_block_arr rd 1
mem_block_start rd 1
mem_block_end rd 1
heap_mutex rd 1
heap_mutex MUTEX
heap_size rd 1
heap_free rd 1
heap_blocks rd 1

View File

@ -0,0 +1,94 @@
All functions are stdcall unless mentioned otherwise.
=== Disk ===
The kernel exports the functions 'DiskAdd', 'DiskMediaChanged', 'DiskDel' for
drivers. They must be called in the following order: DiskAdd, then zero or
more DiskMediaChanged, then optionally DiskDel. The driver must not call
two functions in parallel, including two calls to DiskMediaChanged.
void* DiskAdd(DISKFUNC* functions, const char* name, void* userdata, int flags);
; The pointer 'functions' must be valid at least until the disk will be deleted
; (until DISKFUNC.close is called).
; The pointer 'name' can be invalid after this function returns.
; It should point to ASCIIZ-string without leading '/' in latin lowercase and
; digits, like 'usbhd0'.
; The value 'userdata' is any pointer-sized data, passed as is to all
; callbacks.
DISK_NO_INSERT_NOTIFICATION = 1
; The bitfield 'flags' has currently only one bit defined. If it is set, the
; driver will never call DiskMediaChanged(hDisk, true), so the kernel must scan
; for media insertion when the operation is requested.
struc DISKFUNC
{
.strucsize dd ?
.close dd ?
; void close(void* userdata);
; Optional.
; The last function that is called for the given disk. The kernel calls it when
; the kernel has finished all operations with the disk and it is safe to free
; all driver-specific data identified by 'userdata'.
.closemedia dd ?
; void closemedia(void* userdata);
; Optional.
; The kernel calls this function when it finished all processing with the
; current media. If media is removed, the driver should decline all requests
; to that media with DISK_STATUS_NO_MEDIA, even if new media is inserted,
; until this function is called. If media is removed, a new call to
; DiskMediaChanged(hDisk, true) is not allowed until this function is called.
.querymedia dd ?
; int querymedia(void* userdata, DISKMEDIAINFO* info);
; return value: 0 = success, otherwise = error
.read dd ?
; int read(void* userdata, void* buffer, __int64 startsector,
; int* numsectors);
; return value: 0 = success, otherwise = error
.write dd ?
; int write(void* userdata, const void* buffer, __int64 startsector,
; int* numsectors);
; Optional.
; return value: 0 = success, otherwise = error
.flush dd ?
; int flush(void* userdata);
; Optional.
; Flushes the hardware cache, if it exists. Note that a driver should not
; implement a software cache for read/write, since they are called from the
; kernel cache manager.
}
struc DISKMEDIAINFO
{
.flags dd ?
DISK_MEDIA_READONLY = 1
.sectorsize dd ?
.capacity dq ?
}
void DiskDel(void* hDisk);
; This function informs the kernel that the disk should be deleted from the
; system. This function removes the disk from the global file system; however,
; it is possible that active operations with the disk are still running. When
; the disk is actually removed, the kernel calls the 'close' function, which
; can free all device-related resources.
void DiskMediaChanged(void* hDisk, int newstate);
; This function informs the kernel that a media has been inserted, removed or
; changed. 'newstate' should be zero if currently there is no media inserted
; and nonzero in the other case. This function must not be called with nonzero
; 'newstate' from any of callbacks. This function must not be called if another
; call to this function is active.
=== Timers ===
Timers allow to schedule a function call to some time in the future, once
or periodically. A timer function can do anything, including adding/removing
other timers and itself, but it should not run time-consuming tasks, since that
would block the processing thread for a long time; for such tasks it is
recommended to create new thread.
void* TimerHS(unsigned int deltaStart, unsigned int interval,
void* timerFunc, void* userData);
; Registers a timer which is activated in (deltaStart == 0 ? deltaStart :
; interval) 1/100ths of second starting from the current time. If interval
; is zero, this timer is automatically deleted when activated. Otherwise,
; this timer will be activated every (interval) 1/100ths of second from the
; first activation. Activated timer calls timerFunc(userData) as stdcall.
; Returned value: NULL = failed, otherwise = timer handle which can be passed
; to CancelTimerHS.
void CancelTimerHS(void* hTimer);
; Cancels previously registered timer.

View File

@ -332,7 +332,7 @@ irq_handler:
mov [esi+COM_MOUSE_DATA.MouseByteNumber],0
.EndMouseInterrupt:
mov al, 1
ret
;all initialized data place here

View File

@ -239,7 +239,8 @@ else if sb_buffer_size eq full_buffer
stdcall [callback],SB16Buffer0 ;for 64k buffer
stdcall [callback],SB16Buffer1 ;for 64k buffer
end if
xor eax,eax
xor eax, eax
not eax
ret
.fill_second_half:
@ -249,7 +250,8 @@ else if sb_buffer_size eq full_buffer
stdcall [callback],SB16Buffer2 ;for 64k buffer
stdcall [callback],SB16Buffer3 ;for 64k buffer
end if
xor eax,eax
xor eax, eax
not eax
ret
endp
;-------------------------------------------------------------------------------

View File

@ -0,0 +1,465 @@
; Stub of videodriver for Intel videocards.
; (c) CleverMouse
; When the start procedure gots control,
; it tries to detect preferred resolution,
; sets the detected resolution assuming 32-bpp VESA mode and exits
; (without registering a service).
; Detection can be overloaded with compile-time settings
; use_predefined_mode/predefined_width/predefined_height.
; set predefined resolution here
use_predefined_mode = 0;1
predefined_width = 0;1366
predefined_height = 0;768
; standard driver stuff
format MS COFF
DEBUG = 1
include 'proc32.inc'
include 'imports.inc'
public START
public version
section '.flat' code readable align 16
; the start procedure (see the description above)
START:
; 1. Detect device. Abort if not found.
push esi
call DetectDevice
test esi, esi
jz .return0
; 2. Detect optimal mode unless the mode is given explicitly. Abort if failed.
if use_predefined_mode = 0
call DetectMode
end if
cmp [width], 0
jz .return0_cleanup
; 3. Set the detected mode.
call SetMode
; 4. Cleanup and return.
.return0_cleanup:
stdcall FreeKernelSpace, esi
.return0:
pop esi
xor eax, eax
ret 4
; check that there is Intel videocard
; if so, map MMIO registers and set internal variables
; esi points to MMIO block; NULL means no device
DetectDevice:
; 1. Sanity check: check that we are dealing with Intel videocard.
; Integrated video device for Intel is always at PCI:0:2:0.
xor esi, esi ; initialize return value to NULL
; 1a. Get PCI VendorID and DeviceID.
push esi
push 10h
push esi
call PciRead32
; 1b. loword(eax) = ax = VendorID, hiword(eax) = DeviceID.
; Test whether we have Intel chipset.
cmp ax, 8086h
jnz .return
; 1c. Say hi including DeviceID.
shr eax, 10h
push edi
pusha
mov edi, pciid_text
call WriteWord
mov esi, hellomsg
call SysMsgBoardStr
popa
; 1d. Test whether we know this DeviceID.
; If this is the case, remember the position of the device in line of Intel cards;
; this knowledge will be useful later.
; Tested on devices with id: 8086:0046, partially 8086:2A02.
mov ecx, pciids_num
mov edi, pciids
repnz scasw
pop edi
jnz .return_unknown_pciid
sub ecx, pciids_num - 1
neg ecx
mov [deviceType], ecx
; 1e. Continue saying hi with positive intonation.
pusha
mov esi, knownmsg
call SysMsgBoardStr
popa
; 2. Prepare MMIO region to control the card.
; 2a. Read MMIO physical address from PCI config space.
push 10h
cmp ecx, i9xx_start
jae @f
mov byte [esp], 14h
@@:
push 10h
push esi
call PciRead32
; 2b. Mask out PCI region type, lower 4 bits.
and al, not 0xF
; 2c. Create virtual mapping of the physical memory.
push 1Bh
push 100000h
push eax
call MapIoMem
; 3. Return.
xchg esi, eax
.return:
ret
; 1f. If we do not know DeviceID, continue saying hi with negative intonation.
.return_unknown_pciid:
pusha
mov esi, unknownmsg
call SysMsgBoardStr
popa
ret
; Convert word in ax to hexadecimal text in edi, advance edi.
WriteWord:
; 1. Convert high byte.
push eax
mov al, ah
call WriteByte
pop eax
; 2. Convert low byte.
; Fall through to WriteByte; ret from WriteByte is ret from WriteWord too.
; Convert byte in al to hexadecimal text in edi, advance edi.
WriteByte:
; 1. Convert high nibble.
push eax
shr al, 4
call WriteNibble
pop eax
; 2. Convert low nibble.
and al, 0xF
; Fall through to WriteNibble; ret from WriteNibble is ret from WriteByte too.
; Convert nibble in al to hexadecimal text in edi, advance edi.
WriteNibble:
; Obvious, isn't it?
cmp al, 10
sbb al, 69h
das
stosb
ret
if use_predefined_mode = 0
; detect resolution of the flat panel
DetectMode:
push esi edi
; 1. Get the location of block of GMBUS* registers.
; Starting with Ironlake, GMBUS* registers were moved.
add esi, 5100h
cmp [deviceType], ironlake_start
jb @f
add esi, 0xC0000
@@:
; 2. Initialize GMBUS engine.
mov edi, edid
mov ecx, 0x10000
@@:
test byte [esi+8+1], 80h
loopnz @b
jnz .fail
mov dword [esi], 3
test byte [esi+8+1], 4
jz .noreset
call ResetGMBus
jnz .fail
.noreset:
; 3. Send read command.
and dword [esi+20h], 0
mov dword [esi+4], 4E8000A1h
; 4. Wait for data, writing to the buffer as data arrive.
.getdata:
mov ecx, 0x10000
@@:
test byte [esi+8+1], 8
loopz @b
test byte [esi+8+1], 4
jz .dataok
call ResetGMBus
jmp .fail
.dataok:
mov eax, [esi+0Ch]
stosd
cmp edi, edid+80h
jb .getdata
; 5. Wait for bus idle.
mov ecx, 0x10000
@@:
test byte [esi+8+1], 2
loopnz @b
; 6. We got EDID; dump it if DEBUG.
if DEBUG
pusha
xor ecx, ecx
mov esi, edid
mov edi, edid_text
.dumploop:
lodsb
call WriteByte
mov al, ' '
stosb
inc cl
test cl, 15
jnz @f
mov byte [edi-1], 13
mov al, 10
stosb
@@:
test cl, cl
jns .dumploop
mov esi, edidmsg
call SysMsgBoardStr
popa
end if
; 7. Test whether EDID is good.
; 7a. Signature: 00 FF FF FF FF FF FF 00.
mov esi, edid
cmp dword [esi], 0xFFFFFF00
jnz .fail
cmp dword [esi+4], 0x00FFFFFF
jnz .fail
; 7b. Checksum must be zero.
xor edx, edx
mov ecx, 80h
@@:
lodsb
add dl, al
loop @b
jnz .fail
; 8. Get width and height from EDID.
xor eax, eax
mov ah, [esi-80h+3Ah]
shr ah, 4
mov al, [esi-80h+38h]
mov [width], eax
mov ah, [esi-80h+3Dh]
shr ah, 4
mov al, [esi-80h+3Bh]
mov [height], eax
; 9. Return.
.fail:
pop edi esi
ret
; reset bus, clear all errors
ResetGMBus:
; look into the PRM
mov dword [esi+4], 80000000h
mov dword [esi+4], 0
mov ecx, 0x10000
@@:
test byte [esi+8+1], 2
loopnz @b
ret
end if
; set resolution [width]*[height]
SetMode:
; 1. Program the registers of videocard.
; look into the PRM
cli
; or byte [esi+7000Ah], 0Ch ; PIPEACONF: disable Display+Cursor Planes
; or byte [esi+7100Ah], 0Ch ; PIPEBCONF: disable Display+Cursor Planes
xor eax, eax
xor edx, edx
cmp [deviceType], i965_start
jb @f
mov dl, 9Ch - 84h
@@:
; or byte [esi+71403h], 80h ; VGACNTRL: VGA Display Disable
and byte [esi+70080h], not 27h ; CURACNTR: disable cursor A
mov dword [esi+70084h], eax ; CURABASE: force write to CURA* regs
and byte [esi+700C0h], not 27h ; CURBCNTR: disable cursor B
mov dword [esi+700C4h], eax ; CURBBASE: force write to CURB* regs
and byte [esi+70183h], not 80h ; DSPACNTR: disable Primary A Plane
mov dword [esi+edx+70184h], eax ; DSPALINOFF/DSPASURF: force write to DSPA* regs
and byte [esi+71183h], not 80h ; DSPBCNTR: disable Primary B Plane
mov dword [esi+edx+71184h], eax ; DSPBLINOFF/DSPBSURF: force write to DSPB* regs
if 1
cmp [deviceType], ironlake_start
jae .disable_pipes
mov edx, 10000h
or byte [esi+70024h], 2 ; PIPEASTAT: clear VBLANK status
or byte [esi+71024h], 2 ; PIPEBSTAT: clear VBLANK status
.wait_vblank_preironlake1:
mov ecx, 1000h
loop $
test byte [esi+7000Bh], 80h ; PIPEACONF: pipe A active?
jz @f
test byte [esi+70024h], 2 ; PIPEASTAT: got VBLANK?
jz .wait_vblank_preironlake2
@@:
test byte [esi+7100Bh], 80h ; PIPEBCONF: pipe B active?
jz .disable_pipes
test byte [esi+71024h], 2 ; PIPEBSTAT: got VBLANK?
jnz .disable_pipes
.wait_vblank_preironlake2:
dec edx
jnz .wait_vblank_preironlake1
jmp .not_disabled
.disable_pipes:
end if
and byte [esi+7000Bh], not 80h ; PIPEACONF: disable pipe
and byte [esi+7100Bh], not 80h ; PIPEBCONF: disable pipe
if 1
mov edx, 10000h
@@:
mov ecx, 1000h
loop $
test byte [esi+7000Bh], 40h ; PIPEACONF: wait until pipe disabled
jz @f
dec edx
jnz @b
.not_disabled:
sti
jmp .return
@@:
test byte [esi+7100Bh], 40h ; PIPEBCONF: wait until pipe disabled
jz @f
mov ecx, 1000h
loop $
dec edx
jnz @b
jmp .not_disabled
@@:
else
; alternative way of waiting for pipe stop, works too
mov edx, 1000h
.dis1:
push dword [esi+71000h]
push dword [esi+70000h]
mov ecx, 10000h
loop $
pop eax
xor eax, [esi+70000h]
and eax, 1FFFh
pop eax
jnz .notdis1
xor eax, [esi+71000h]
and eax, 1FFFh
jz .disabled
.notdis1:
dec edx
jnz .dis1
.not_disabled:
sti
jmp .return
.disabled:
end if
lea eax, [esi+61183h]
cmp [deviceType], ironlake_start
jb @f
add eax, 0xE0000 - 0x60000
@@:
lea edx, [esi+60000h]
test byte [eax], 40h
jz @f
add edx, 1000h
@@:
mov eax, [width]
dec eax
shl eax, 16
mov ax, word [height]
dec eax
mov dword [edx+1Ch], eax ; PIPEASRC: set source image size
ror eax, 16
mov dword [edx+10190h], eax ; for old cards
mov ecx, [width]
add ecx, 15
and ecx, not 15
shl ecx, 2
mov dword [edx+10188h], ecx ; DSPASTRIDE: set scanline length
and byte [esi+61233h], not 80h ; PFIT_CONTROL: disable panel fitting
or byte [edx+1000Bh], 80h ; PIPEACONF: enable pipe
; and byte [edx+1000Ah], not 0Ch ; PIPEACONF: enable Display+Cursor Planes
or byte [edx+10183h], 80h ; DSPACNTR: enable Display Plane A
sti
; 2. Notify the kernel that resolution has changed.
call GetDisplay
mov edx, [width]
mov dword [eax+8], edx
mov edx, [height]
mov dword [eax+0Ch], edx
mov [eax+18h], ecx
mov eax, [width]
dec eax
dec edx
call SetScreen
.return:
ret
align 4
hellomsg db 'Intel videocard detected, PciId=8086:'
pciid_text db '0000'
db ', which is ', 0
knownmsg db 'known',13,10,0
unknownmsg db 'unknown',13,10,0
if DEBUG
edidmsg db 'EDID successfully read:',13,10
edid_text rb 8*(16*3+1)
db 0
end if
version:
dd 0x50005
width dd predefined_width
height dd predefined_height
pciids:
dw 0x3577 ; i830m
dw 0x2562 ; 845g
dw 0x3582 ; i855gm
i865_start = ($ - pciids) / 2
dw 0x2572 ; i865g
i9xx_start = ($ - pciids) / 2
dw 0x2582 ; i915g
dw 0x258a ; e7221g (i915g)
dw 0x2592 ; i915gm
dw 0x2772 ; i945g
dw 0x27a2 ; i945gm
dw 0x27ae ; i945gme
i965_start = ($ - pciids) / 2
dw 0x2972 ; i946qz (i965g)
dw 0x2982 ; g35g (i965g)
dw 0x2992 ; i965q (i965g)
dw 0x29a2 ; i965g
dw 0x29b2 ; q35g
dw 0x29c2 ; g33g
dw 0x29d2 ; q33g
dw 0x2a02 ; i965gm
dw 0x2a12 ; i965gm
dw 0x2a42 ; gm45
dw 0x2e02 ; g45
dw 0x2e12 ; g45
dw 0x2e22 ; g45
dw 0x2e32 ; g45
dw 0x2e42 ; g45
dw 0x2e92 ; g45
dw 0xa001 ; pineview
dw 0xa011 ; pineview
ironlake_start = ($ - pciids) / 2
dw 0x0042 ; ironlake_d
dw 0x0046 ; ironlake_m
dw 0x0102 ; sandybridge_d
dw 0x0112 ; sandybridge_d
dw 0x0122 ; sandybridge_d
dw 0x0106 ; sandybridge_m
dw 0x0116 ; sandybridge_m
dw 0x0126 ; sandybridge_m
dw 0x010A ; sandybridge_d
pciids_num = ($ - pciids) / 2
align 4
deviceType dd ?
edid rb 0x80

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -60,6 +60,7 @@ ERROR_MEMORY_POINTER = 7
ERROR_DISK_FULL = 8
ERROR_FAT_TABLE = 9
ERROR_ACCESS_DENIED = 10
ERROR_DEVICE = 11
PUSHAD_EAX equ [esp+28]
PUSHAD_ECX equ [esp+24]

View File

@ -85,6 +85,7 @@ virtual_root_query:
fs_additional_handlers:
dd biosdisk_handler, biosdisk_enum_root
dd dyndisk_handler, dyndisk_enum_root
; add new handlers here
dd 0
@ -383,7 +384,8 @@ file_system_lfn:
.notfounda:
cmp edi, esp
jnz .notfound
add esp, 8
call dword [edi+4]
add esp, 16
jmp .notfound
.found1:
@ -850,6 +852,8 @@ biosdisk_handler:
jmp file_system_lfn.maindir_noesi
@@:
push ecx
push ecx
push biosdisk_cleanup
push fs_OnBd
mov edi, esp
jmp file_system_lfn.found2
@ -858,10 +862,11 @@ fs_BdNext:
cmp eax, [BiosDiskPartitions+ecx*4]
inc eax
cmc
biosdisk_cleanup:
ret
fs_OnBd:
pop edx edx
pop edx edx edx edx
; edx = disk number, ecx = partition number
; esi+ebp = name
call reserve_hd1

View File

@ -266,7 +266,6 @@ proc init_page_map
add ebx, [pg_data.pagemap_size-OS_BASE]
mov [page_end-OS_BASE], ebx
mov [pg_data.pg_mutex-OS_BASE], 0
ret
endp

View File

@ -321,6 +321,12 @@ high_code:
mov eax, cr3
mov cr3, eax ; flush TLB
mov ecx, pg_data.mutex
call mutex_init
mov ecx, disk_list_mutex
call mutex_init
; SAVE REAL MODE VARIABLES
mov ax, [BOOT_VAR + 0x9031]
mov [IDEContrRegsBaseAddr], ax
@ -713,7 +719,11 @@ end if
call boot_log
movzx ecx, word [boot_y]
or ecx, (10+29*6) shl 16 ; "Determining amount of memory"
if lang eq ru
or ecx, (10+30*6) shl 16
else
or ecx, (10+29*6) shl 16
end if
sub ecx, 10
mov edx, 0xFFFFFF
mov ebx, [MEM_AMOUNT]
@ -832,7 +842,11 @@ end if
mov ebx, edx
movzx ecx, word [boot_y]
add ecx, (10+17*6) shl 16 - 10 ; 'CPU frequency is '
if lang eq ru
add ecx, (10+19*6) shl 16 - 10; 'Determining amount of memory'
else
add ecx, (10+17*6) shl 16 - 10; 'Determining amount of memory'
end if
mov edx, 0xFFFFFF
xor edi,edi
mov eax, 0x00040000
@ -2270,18 +2284,18 @@ window_minimize db 0
sound_flag db 0
endg
iglobal
version_inf:
db 0,7,7,0 ; version 0.7.7.0
db UID_KOLIBRI
dd __REV__
version_end:
endg
UID_NONE=0
UID_MENUETOS=1 ;official
UID_KOLIBRI=2 ;russian
iglobal
version_inf:
db 0,7,7,0 ; version 0.7.7.0
db 0
dd __REV__
version_end:
endg
sys_cachetodiskette:
cmp ebx, 1
jne .no_floppy_a_save

View File

@ -223,6 +223,7 @@ include "core/string.inc"
include "core/v86.inc" ; virtual-8086 manager
include "core/apic.inc" ; Interrupt Controller functions
include "core/irq.inc" ; irq handling functions
include "core/timers.inc"
; GUI stuff
include "gui/window.inc"
@ -234,6 +235,7 @@ include "gui/button.inc"
; file system
include "fs/disk.inc" ; support for plug-n-play disks
include "fs/fs.inc" ; syscall
include "fs/fat32.inc" ; read / write for fat32 filesystem
include "fs/ntfs.inc" ; read / write for ntfs filesystem

View File

@ -20,13 +20,16 @@ macro struct name, [arg]
struc name arg {
}
macro declare_sizeof xname,value
{ sizeof.#xname = value }
macro struct_helper name
{
match xname,name
\{
virtual at 0
xname xname
sizeof.#xname = $ - xname
declare_sizeof xname, $ - xname
name equ sizeof.#xname
end virtual
\}

View File

@ -54,7 +54,7 @@ struct SOCKET
.SEG_LEN dd ? ; segment length
.SEG_WND dd ? ; segment window
.wndsizeTimer dd ? ; window size timer
.lock dd ? ; lock mutex
.lock MUTEX ; lock mutex
.rxData dd ? ; receive data buffer here
ends
@ -99,6 +99,11 @@ proc net_socket_alloc stdcall uses ebx ecx edx edi
rep stosd
pop eax
mov ebx, eax
lea ecx, [eax+SOCKET.lock]
call mutex_init
mov eax, ebx
; add socket to the list by changing pointers
mov ebx, net_sockets
push [ebx + SOCKET.NextPtr]
@ -703,10 +708,10 @@ proc socket_read stdcall
or eax, eax
jz .error
lea ebx, [eax + SOCKET.lock]
call wait_mutex
mov ebx, eax
lea ecx, [eax + SOCKET.lock]
call mutex_lock
mov ebx, eax
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes
test eax, eax
jz .error_release
@ -727,15 +732,18 @@ proc socket_read stdcall
and ecx, 3
rep movsb
mov [ebx + SOCKET.lock], 0
lea ecx, [ebx + SOCKET.lock]
mov ebx, eax
call mutex_unlock
mov eax, ebx
ret
.error_release:
mov [ebx + SOCKET.lock], 0
lea ecx, [ebx + SOCKET.lock]
call mutex_unlock
.error:
xor ebx, ebx
xor eax, eax
ret
endp
@ -756,10 +764,11 @@ proc socket_read_packet stdcall
or eax, eax
jz .error
lea ebx, [eax + SOCKET.lock]
call wait_mutex
mov ebx, eax
lea ecx, [eax + SOCKET.lock]
call mutex_lock
mov ebx, eax
mov eax, [ebx + SOCKET.rxDataCount] ; get count of bytes
test eax, eax ; if count of bytes is zero..
jz .exit ; exit function (eax will be zero)
@ -789,7 +798,9 @@ proc socket_read_packet stdcall
rep movsb ; copy remaining bytes
.exit:
mov [ebx + SOCKET.lock], 0
lea ecx, [ebx + SOCKET.lock]
call mutex_unlock
mov eax, edx
ret ; at last, exit
.error:
@ -800,7 +811,9 @@ proc socket_read_packet stdcall
xor esi, esi
mov [ebx + SOCKET.rxDataCount], esi ; store new count (zero)
call .start_copy
mov [ebx + SOCKET.lock], 0
lea ecx, [ebx + SOCKET.lock]
call mutex_unlock
mov eax, edx
ret
.start_copy:

View File

@ -963,12 +963,10 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
jmp .exit
.data:
push ebx
add ebx, SOCKET.lock
call wait_mutex
pop ebx
push ecx
lea ecx, [ebx+SOCKET.lock]
call mutex_lock
push ecx
push ebx
mov eax, [ebx + SOCKET.rxDataCount]
add eax, ecx
@ -986,7 +984,9 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
cld
rep movsb ; copy the data across
mov [ebx + SOCKET.lock], 0 ; release mutex
lea ecx,[ebx + SOCKET.lock]
call mutex_unlock
; flag an event to the application
pop ebx
@ -1031,8 +1031,9 @@ proc stateTCB_ESTABLISHED stdcall, sockAddr:DWORD
.overflow:
; no place in buffer
; so simply restore stack and exit
lea ecx, [ebx + SOCKET.lock]
call mutex_unlock
pop eax ecx
mov [ebx + SOCKET.lock], 0
ret
endp